Coverage Report

Created: 2023-05-31 04:38

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/AST/ODRDiagsEmitter.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- ODRDiagsEmitter.cpp - Diagnostics for ODR mismatches ----*- C++ -*-===//
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
#include "clang/AST/ODRDiagsEmitter.h"
10
#include "clang/AST/DeclFriend.h"
11
#include "clang/AST/DeclTemplate.h"
12
#include "clang/AST/ODRHash.h"
13
#include "clang/Basic/DiagnosticAST.h"
14
#include "clang/Basic/Module.h"
15
16
using namespace clang;
17
18
316
static unsigned computeODRHash(QualType Ty) {
19
316
  ODRHash Hasher;
20
316
  Hasher.AddQualType(Ty);
21
316
  return Hasher.CalculateHash();
22
316
}
23
24
40
static unsigned computeODRHash(const Stmt *S) {
25
40
  ODRHash Hasher;
26
40
  Hasher.AddStmt(S);
27
40
  return Hasher.CalculateHash();
28
40
}
29
30
923
static unsigned computeODRHash(const Decl *D) {
31
923
  assert(D);
32
923
  ODRHash Hasher;
33
923
  Hasher.AddSubDecl(D);
34
923
  return Hasher.CalculateHash();
35
923
}
36
37
16
static unsigned computeODRHash(const TemplateArgument &TA) {
38
16
  ODRHash Hasher;
39
16
  Hasher.AddTemplateArgument(TA);
40
16
  return Hasher.CalculateHash();
41
16
}
42
43
922
std::string ODRDiagsEmitter::getOwningModuleNameForDiagnostic(const Decl *D) {
44
  // If we know the owning module, use it.
45
922
  if (Module *M = D->getImportedOwningModule())
46
865
    return M->getFullModuleName();
47
48
  // Not from a module.
49
57
  return {};
50
922
}
51
52
template <typename MethodT>
53
static bool diagnoseSubMismatchMethodParameters(DiagnosticsEngine &Diags,
54
                                                const NamedDecl *FirstContainer,
55
                                                StringRef FirstModule,
56
                                                StringRef SecondModule,
57
                                                const MethodT *FirstMethod,
58
46
                                                const MethodT *SecondMethod) {
59
46
  enum DiagMethodType {
60
46
    DiagMethod,
61
46
    DiagConstructor,
62
46
    DiagDestructor,
63
46
  };
64
46
  auto GetDiagMethodType = [](const NamedDecl *D) {
65
36
    if (isa<CXXConstructorDecl>(D))
66
2
      return DiagConstructor;
67
34
    if (isa<CXXDestructorDecl>(D))
68
0
      return DiagDestructor;
69
34
    return DiagMethod;
70
34
  };
ODRDiagsEmitter.cpp:bool diagnoseSubMismatchMethodParameters<clang::ObjCMethodDecl>(clang::DiagnosticsEngine&, clang::NamedDecl const*, llvm::StringRef, llvm::StringRef, clang::ObjCMethodDecl const*, clang::ObjCMethodDecl const*)::'lambda'(clang::NamedDecl const*)::operator()(clang::NamedDecl const*) const
Line
Count
Source
64
24
  auto GetDiagMethodType = [](const NamedDecl *D) {
65
24
    if (isa<CXXConstructorDecl>(D))
66
0
      return DiagConstructor;
67
24
    if (isa<CXXDestructorDecl>(D))
68
0
      return DiagDestructor;
69
24
    return DiagMethod;
70
24
  };
ODRDiagsEmitter.cpp:bool diagnoseSubMismatchMethodParameters<clang::CXXMethodDecl>(clang::DiagnosticsEngine&, clang::NamedDecl const*, llvm::StringRef, llvm::StringRef, clang::CXXMethodDecl const*, clang::CXXMethodDecl const*)::'lambda'(clang::NamedDecl const*)::operator()(clang::NamedDecl const*) const
Line
Count
Source
64
12
  auto GetDiagMethodType = [](const NamedDecl *D) {
65
12
    if (isa<CXXConstructorDecl>(D))
66
2
      return DiagConstructor;
67
10
    if (isa<CXXDestructorDecl>(D))
68
0
      return DiagDestructor;
69
10
    return DiagMethod;
70
10
  };
71
72
46
  enum ODRMethodParametersDifference {
73
46
    NumberParameters,
74
46
    ParameterType,
75
46
    ParameterName,
76
46
  };
77
46
  auto DiagError = [&Diags, &GetDiagMethodType, FirstContainer, FirstModule,
78
46
                    FirstMethod](ODRMethodParametersDifference DiffType) {
79
18
    DeclarationName FirstName = FirstMethod->getDeclName();
80
18
    DiagMethodType FirstMethodType = GetDiagMethodType(FirstMethod);
81
18
    return Diags.Report(FirstMethod->getLocation(),
82
18
                        diag::err_module_odr_violation_method_params)
83
18
           << FirstContainer << FirstModule.empty() << FirstModule
84
18
           << FirstMethod->getSourceRange() << DiffType << FirstMethodType
85
18
           << FirstName;
86
18
  };
ODRDiagsEmitter.cpp:bool diagnoseSubMismatchMethodParameters<clang::ObjCMethodDecl>(clang::DiagnosticsEngine&, clang::NamedDecl const*, llvm::StringRef, llvm::StringRef, clang::ObjCMethodDecl const*, clang::ObjCMethodDecl const*)::'lambda'(bool diagnoseSubMismatchMethodParameters<clang::ObjCMethodDecl>(clang::DiagnosticsEngine&, clang::NamedDecl const*, llvm::StringRef, llvm::StringRef, clang::ObjCMethodDecl const*, clang::ObjCMethodDecl const*)::ODRMethodParametersDifference)::operator()(bool diagnoseSubMismatchMethodParameters<clang::ObjCMethodDecl>(clang::DiagnosticsEngine&, clang::NamedDecl const*, llvm::StringRef, llvm::StringRef, clang::ObjCMethodDecl const*, clang::ObjCMethodDecl const*)::ODRMethodParametersDifference) const
Line
Count
Source
78
12
                    FirstMethod](ODRMethodParametersDifference DiffType) {
79
12
    DeclarationName FirstName = FirstMethod->getDeclName();
80
12
    DiagMethodType FirstMethodType = GetDiagMethodType(FirstMethod);
81
12
    return Diags.Report(FirstMethod->getLocation(),
82
12
                        diag::err_module_odr_violation_method_params)
83
12
           << FirstContainer << FirstModule.empty() << FirstModule
84
12
           << FirstMethod->getSourceRange() << DiffType << FirstMethodType
85
12
           << FirstName;
86
12
  };
ODRDiagsEmitter.cpp:bool diagnoseSubMismatchMethodParameters<clang::CXXMethodDecl>(clang::DiagnosticsEngine&, clang::NamedDecl const*, llvm::StringRef, llvm::StringRef, clang::CXXMethodDecl const*, clang::CXXMethodDecl const*)::'lambda'(bool diagnoseSubMismatchMethodParameters<clang::CXXMethodDecl>(clang::DiagnosticsEngine&, clang::NamedDecl const*, llvm::StringRef, llvm::StringRef, clang::CXXMethodDecl const*, clang::CXXMethodDecl const*)::ODRMethodParametersDifference)::operator()(bool diagnoseSubMismatchMethodParameters<clang::CXXMethodDecl>(clang::DiagnosticsEngine&, clang::NamedDecl const*, llvm::StringRef, llvm::StringRef, clang::CXXMethodDecl const*, clang::CXXMethodDecl const*)::ODRMethodParametersDifference) const
Line
Count
Source
78
6
                    FirstMethod](ODRMethodParametersDifference DiffType) {
79
6
    DeclarationName FirstName = FirstMethod->getDeclName();
80
6
    DiagMethodType FirstMethodType = GetDiagMethodType(FirstMethod);
81
6
    return Diags.Report(FirstMethod->getLocation(),
82
6
                        diag::err_module_odr_violation_method_params)
83
6
           << FirstContainer << FirstModule.empty() << FirstModule
84
6
           << FirstMethod->getSourceRange() << DiffType << FirstMethodType
85
6
           << FirstName;
86
6
  };
87
46
  auto DiagNote = [&Diags, &GetDiagMethodType, SecondModule,
88
46
                   SecondMethod](ODRMethodParametersDifference DiffType) {
89
18
    DeclarationName SecondName = SecondMethod->getDeclName();
90
18
    DiagMethodType SecondMethodType = GetDiagMethodType(SecondMethod);
91
18
    return Diags.Report(SecondMethod->getLocation(),
92
18
                        diag::note_module_odr_violation_method_params)
93
18
           << SecondModule.empty() << SecondModule
94
18
           << SecondMethod->getSourceRange() << DiffType << SecondMethodType
95
18
           << SecondName;
96
18
  };
ODRDiagsEmitter.cpp:bool diagnoseSubMismatchMethodParameters<clang::ObjCMethodDecl>(clang::DiagnosticsEngine&, clang::NamedDecl const*, llvm::StringRef, llvm::StringRef, clang::ObjCMethodDecl const*, clang::ObjCMethodDecl const*)::'lambda0'(bool diagnoseSubMismatchMethodParameters<clang::ObjCMethodDecl>(clang::DiagnosticsEngine&, clang::NamedDecl const*, llvm::StringRef, llvm::StringRef, clang::ObjCMethodDecl const*, clang::ObjCMethodDecl const*)::ODRMethodParametersDifference)::operator()(bool diagnoseSubMismatchMethodParameters<clang::ObjCMethodDecl>(clang::DiagnosticsEngine&, clang::NamedDecl const*, llvm::StringRef, llvm::StringRef, clang::ObjCMethodDecl const*, clang::ObjCMethodDecl const*)::ODRMethodParametersDifference) const
Line
Count
Source
88
12
                   SecondMethod](ODRMethodParametersDifference DiffType) {
89
12
    DeclarationName SecondName = SecondMethod->getDeclName();
90
12
    DiagMethodType SecondMethodType = GetDiagMethodType(SecondMethod);
91
12
    return Diags.Report(SecondMethod->getLocation(),
92
12
                        diag::note_module_odr_violation_method_params)
93
12
           << SecondModule.empty() << SecondModule
94
12
           << SecondMethod->getSourceRange() << DiffType << SecondMethodType
95
12
           << SecondName;
96
12
  };
ODRDiagsEmitter.cpp:bool diagnoseSubMismatchMethodParameters<clang::CXXMethodDecl>(clang::DiagnosticsEngine&, clang::NamedDecl const*, llvm::StringRef, llvm::StringRef, clang::CXXMethodDecl const*, clang::CXXMethodDecl const*)::'lambda0'(bool diagnoseSubMismatchMethodParameters<clang::CXXMethodDecl>(clang::DiagnosticsEngine&, clang::NamedDecl const*, llvm::StringRef, llvm::StringRef, clang::CXXMethodDecl const*, clang::CXXMethodDecl const*)::ODRMethodParametersDifference)::operator()(bool diagnoseSubMismatchMethodParameters<clang::CXXMethodDecl>(clang::DiagnosticsEngine&, clang::NamedDecl const*, llvm::StringRef, llvm::StringRef, clang::CXXMethodDecl const*, clang::CXXMethodDecl const*)::ODRMethodParametersDifference) const
Line
Count
Source
88
6
                   SecondMethod](ODRMethodParametersDifference DiffType) {
89
6
    DeclarationName SecondName = SecondMethod->getDeclName();
90
6
    DiagMethodType SecondMethodType = GetDiagMethodType(SecondMethod);
91
6
    return Diags.Report(SecondMethod->getLocation(),
92
6
                        diag::note_module_odr_violation_method_params)
93
6
           << SecondModule.empty() << SecondModule
94
6
           << SecondMethod->getSourceRange() << DiffType << SecondMethodType
95
6
           << SecondName;
96
6
  };
97
98
46
  const unsigned FirstNumParameters = FirstMethod->param_size();
99
46
  const unsigned SecondNumParameters = SecondMethod->param_size();
100
46
  if (FirstNumParameters != SecondNumParameters) {
101
6
    DiagError(NumberParameters) << FirstNumParameters;
102
6
    DiagNote(NumberParameters) << SecondNumParameters;
103
6
    return true;
104
6
  }
105
106
44
  
for (unsigned I = 0; 40
I < FirstNumParameters;
++I4
) {
107
16
    const ParmVarDecl *FirstParam = FirstMethod->getParamDecl(I);
108
16
    const ParmVarDecl *SecondParam = SecondMethod->getParamDecl(I);
109
110
16
    QualType FirstParamType = FirstParam->getType();
111
16
    QualType SecondParamType = SecondParam->getType();
112
16
    if (FirstParamType != SecondParamType &&
113
16
        
computeODRHash(FirstParamType) != computeODRHash(SecondParamType)8
) {
114
7
      if (const DecayedType *ParamDecayedType =
115
7
              FirstParamType->getAs<DecayedType>()) {
116
1
        DiagError(ParameterType) << (I + 1) << FirstParamType << true
117
1
                                 << ParamDecayedType->getOriginalType();
118
6
      } else {
119
6
        DiagError(ParameterType) << (I + 1) << FirstParamType << false;
120
6
      }
121
122
7
      if (const DecayedType *ParamDecayedType =
123
7
              SecondParamType->getAs<DecayedType>()) {
124
1
        DiagNote(ParameterType) << (I + 1) << SecondParamType << true
125
1
                                << ParamDecayedType->getOriginalType();
126
6
      } else {
127
6
        DiagNote(ParameterType) << (I + 1) << SecondParamType << false;
128
6
      }
129
7
      return true;
130
7
    }
131
132
9
    DeclarationName FirstParamName = FirstParam->getDeclName();
133
9
    DeclarationName SecondParamName = SecondParam->getDeclName();
134
9
    if (FirstParamName != SecondParamName) {
135
5
      DiagError(ParameterName) << (I + 1) << FirstParamName;
136
5
      DiagNote(ParameterName) << (I + 1) << SecondParamName;
137
5
      return true;
138
5
    }
139
9
  }
140
141
28
  return false;
142
40
}
ODRDiagsEmitter.cpp:bool diagnoseSubMismatchMethodParameters<clang::ObjCMethodDecl>(clang::DiagnosticsEngine&, clang::NamedDecl const*, llvm::StringRef, llvm::StringRef, clang::ObjCMethodDecl const*, clang::ObjCMethodDecl const*)
Line
Count
Source
58
20
                                                const MethodT *SecondMethod) {
59
20
  enum DiagMethodType {
60
20
    DiagMethod,
61
20
    DiagConstructor,
62
20
    DiagDestructor,
63
20
  };
64
20
  auto GetDiagMethodType = [](const NamedDecl *D) {
65
20
    if (isa<CXXConstructorDecl>(D))
66
20
      return DiagConstructor;
67
20
    if (isa<CXXDestructorDecl>(D))
68
20
      return DiagDestructor;
69
20
    return DiagMethod;
70
20
  };
71
72
20
  enum ODRMethodParametersDifference {
73
20
    NumberParameters,
74
20
    ParameterType,
75
20
    ParameterName,
76
20
  };
77
20
  auto DiagError = [&Diags, &GetDiagMethodType, FirstContainer, FirstModule,
78
20
                    FirstMethod](ODRMethodParametersDifference DiffType) {
79
20
    DeclarationName FirstName = FirstMethod->getDeclName();
80
20
    DiagMethodType FirstMethodType = GetDiagMethodType(FirstMethod);
81
20
    return Diags.Report(FirstMethod->getLocation(),
82
20
                        diag::err_module_odr_violation_method_params)
83
20
           << FirstContainer << FirstModule.empty() << FirstModule
84
20
           << FirstMethod->getSourceRange() << DiffType << FirstMethodType
85
20
           << FirstName;
86
20
  };
87
20
  auto DiagNote = [&Diags, &GetDiagMethodType, SecondModule,
88
20
                   SecondMethod](ODRMethodParametersDifference DiffType) {
89
20
    DeclarationName SecondName = SecondMethod->getDeclName();
90
20
    DiagMethodType SecondMethodType = GetDiagMethodType(SecondMethod);
91
20
    return Diags.Report(SecondMethod->getLocation(),
92
20
                        diag::note_module_odr_violation_method_params)
93
20
           << SecondModule.empty() << SecondModule
94
20
           << SecondMethod->getSourceRange() << DiffType << SecondMethodType
95
20
           << SecondName;
96
20
  };
97
98
20
  const unsigned FirstNumParameters = FirstMethod->param_size();
99
20
  const unsigned SecondNumParameters = SecondMethod->param_size();
100
20
  if (FirstNumParameters != SecondNumParameters) {
101
4
    DiagError(NumberParameters) << FirstNumParameters;
102
4
    DiagNote(NumberParameters) << SecondNumParameters;
103
4
    return true;
104
4
  }
105
106
16
  for (unsigned I = 0; I < FirstNumParameters; 
++I0
) {
107
8
    const ParmVarDecl *FirstParam = FirstMethod->getParamDecl(I);
108
8
    const ParmVarDecl *SecondParam = SecondMethod->getParamDecl(I);
109
110
8
    QualType FirstParamType = FirstParam->getType();
111
8
    QualType SecondParamType = SecondParam->getType();
112
8
    if (FirstParamType != SecondParamType &&
113
8
        
computeODRHash(FirstParamType) != computeODRHash(SecondParamType)4
) {
114
4
      if (const DecayedType *ParamDecayedType =
115
4
              FirstParamType->getAs<DecayedType>()) {
116
0
        DiagError(ParameterType) << (I + 1) << FirstParamType << true
117
0
                                 << ParamDecayedType->getOriginalType();
118
4
      } else {
119
4
        DiagError(ParameterType) << (I + 1) << FirstParamType << false;
120
4
      }
121
122
4
      if (const DecayedType *ParamDecayedType =
123
4
              SecondParamType->getAs<DecayedType>()) {
124
0
        DiagNote(ParameterType) << (I + 1) << SecondParamType << true
125
0
                                << ParamDecayedType->getOriginalType();
126
4
      } else {
127
4
        DiagNote(ParameterType) << (I + 1) << SecondParamType << false;
128
4
      }
129
4
      return true;
130
4
    }
131
132
4
    DeclarationName FirstParamName = FirstParam->getDeclName();
133
4
    DeclarationName SecondParamName = SecondParam->getDeclName();
134
4
    if (FirstParamName != SecondParamName) {
135
4
      DiagError(ParameterName) << (I + 1) << FirstParamName;
136
4
      DiagNote(ParameterName) << (I + 1) << SecondParamName;
137
4
      return true;
138
4
    }
139
4
  }
140
141
8
  return false;
142
16
}
ODRDiagsEmitter.cpp:bool diagnoseSubMismatchMethodParameters<clang::CXXMethodDecl>(clang::DiagnosticsEngine&, clang::NamedDecl const*, llvm::StringRef, llvm::StringRef, clang::CXXMethodDecl const*, clang::CXXMethodDecl const*)
Line
Count
Source
58
26
                                                const MethodT *SecondMethod) {
59
26
  enum DiagMethodType {
60
26
    DiagMethod,
61
26
    DiagConstructor,
62
26
    DiagDestructor,
63
26
  };
64
26
  auto GetDiagMethodType = [](const NamedDecl *D) {
65
26
    if (isa<CXXConstructorDecl>(D))
66
26
      return DiagConstructor;
67
26
    if (isa<CXXDestructorDecl>(D))
68
26
      return DiagDestructor;
69
26
    return DiagMethod;
70
26
  };
71
72
26
  enum ODRMethodParametersDifference {
73
26
    NumberParameters,
74
26
    ParameterType,
75
26
    ParameterName,
76
26
  };
77
26
  auto DiagError = [&Diags, &GetDiagMethodType, FirstContainer, FirstModule,
78
26
                    FirstMethod](ODRMethodParametersDifference DiffType) {
79
26
    DeclarationName FirstName = FirstMethod->getDeclName();
80
26
    DiagMethodType FirstMethodType = GetDiagMethodType(FirstMethod);
81
26
    return Diags.Report(FirstMethod->getLocation(),
82
26
                        diag::err_module_odr_violation_method_params)
83
26
           << FirstContainer << FirstModule.empty() << FirstModule
84
26
           << FirstMethod->getSourceRange() << DiffType << FirstMethodType
85
26
           << FirstName;
86
26
  };
87
26
  auto DiagNote = [&Diags, &GetDiagMethodType, SecondModule,
88
26
                   SecondMethod](ODRMethodParametersDifference DiffType) {
89
26
    DeclarationName SecondName = SecondMethod->getDeclName();
90
26
    DiagMethodType SecondMethodType = GetDiagMethodType(SecondMethod);
91
26
    return Diags.Report(SecondMethod->getLocation(),
92
26
                        diag::note_module_odr_violation_method_params)
93
26
           << SecondModule.empty() << SecondModule
94
26
           << SecondMethod->getSourceRange() << DiffType << SecondMethodType
95
26
           << SecondName;
96
26
  };
97
98
26
  const unsigned FirstNumParameters = FirstMethod->param_size();
99
26
  const unsigned SecondNumParameters = SecondMethod->param_size();
100
26
  if (FirstNumParameters != SecondNumParameters) {
101
2
    DiagError(NumberParameters) << FirstNumParameters;
102
2
    DiagNote(NumberParameters) << SecondNumParameters;
103
2
    return true;
104
2
  }
105
106
28
  
for (unsigned I = 0; 24
I < FirstNumParameters;
++I4
) {
107
8
    const ParmVarDecl *FirstParam = FirstMethod->getParamDecl(I);
108
8
    const ParmVarDecl *SecondParam = SecondMethod->getParamDecl(I);
109
110
8
    QualType FirstParamType = FirstParam->getType();
111
8
    QualType SecondParamType = SecondParam->getType();
112
8
    if (FirstParamType != SecondParamType &&
113
8
        
computeODRHash(FirstParamType) != computeODRHash(SecondParamType)4
) {
114
3
      if (const DecayedType *ParamDecayedType =
115
3
              FirstParamType->getAs<DecayedType>()) {
116
1
        DiagError(ParameterType) << (I + 1) << FirstParamType << true
117
1
                                 << ParamDecayedType->getOriginalType();
118
2
      } else {
119
2
        DiagError(ParameterType) << (I + 1) << FirstParamType << false;
120
2
      }
121
122
3
      if (const DecayedType *ParamDecayedType =
123
3
              SecondParamType->getAs<DecayedType>()) {
124
1
        DiagNote(ParameterType) << (I + 1) << SecondParamType << true
125
1
                                << ParamDecayedType->getOriginalType();
126
2
      } else {
127
2
        DiagNote(ParameterType) << (I + 1) << SecondParamType << false;
128
2
      }
129
3
      return true;
130
3
    }
131
132
5
    DeclarationName FirstParamName = FirstParam->getDeclName();
133
5
    DeclarationName SecondParamName = SecondParam->getDeclName();
134
5
    if (FirstParamName != SecondParamName) {
135
1
      DiagError(ParameterName) << (I + 1) << FirstParamName;
136
1
      DiagNote(ParameterName) << (I + 1) << SecondParamName;
137
1
      return true;
138
1
    }
139
5
  }
140
141
20
  return false;
142
24
}
143
144
bool ODRDiagsEmitter::diagnoseSubMismatchField(
145
    const NamedDecl *FirstRecord, StringRef FirstModule, StringRef SecondModule,
146
40
    const FieldDecl *FirstField, const FieldDecl *SecondField) const {
147
40
  enum ODRFieldDifference {
148
40
    FieldName,
149
40
    FieldTypeName,
150
40
    FieldSingleBitField,
151
40
    FieldDifferentWidthBitField,
152
40
    FieldSingleMutable,
153
40
    FieldSingleInitializer,
154
40
    FieldDifferentInitializers,
155
40
  };
156
157
40
  auto DiagError = [FirstRecord, FirstField, FirstModule,
158
40
                    this](ODRFieldDifference DiffType) {
159
36
    return Diag(FirstField->getLocation(), diag::err_module_odr_violation_field)
160
36
           << FirstRecord << FirstModule.empty() << FirstModule
161
36
           << FirstField->getSourceRange() << DiffType;
162
36
  };
163
40
  auto DiagNote = [SecondField, SecondModule,
164
40
                   this](ODRFieldDifference DiffType) {
165
36
    return Diag(SecondField->getLocation(),
166
36
                diag::note_module_odr_violation_field)
167
36
           << SecondModule.empty() << SecondModule << SecondField->getSourceRange() << DiffType;
168
36
  };
169
170
40
  IdentifierInfo *FirstII = FirstField->getIdentifier();
171
40
  IdentifierInfo *SecondII = SecondField->getIdentifier();
172
40
  if (FirstII->getName() != SecondII->getName()) {
173
7
    DiagError(FieldName) << FirstII;
174
7
    DiagNote(FieldName) << SecondII;
175
7
    return true;
176
7
  }
177
178
33
  QualType FirstType = FirstField->getType();
179
33
  QualType SecondType = SecondField->getType();
180
33
  if (computeODRHash(FirstType) != computeODRHash(SecondType)) {
181
16
    DiagError(FieldTypeName) << FirstII << FirstType;
182
16
    DiagNote(FieldTypeName) << SecondII << SecondType;
183
16
    return true;
184
16
  }
185
186
17
  assert(Context.hasSameType(FirstField->getType(), SecondField->getType()));
187
17
  (void)Context;
188
189
17
  const bool IsFirstBitField = FirstField->isBitField();
190
17
  const bool IsSecondBitField = SecondField->isBitField();
191
17
  if (IsFirstBitField != IsSecondBitField) {
192
3
    DiagError(FieldSingleBitField) << FirstII << IsFirstBitField;
193
3
    DiagNote(FieldSingleBitField) << SecondII << IsSecondBitField;
194
3
    return true;
195
3
  }
196
197
14
  if (IsFirstBitField && 
IsSecondBitField5
) {
198
5
    unsigned FirstBitWidthHash = computeODRHash(FirstField->getBitWidth());
199
5
    unsigned SecondBitWidthHash = computeODRHash(SecondField->getBitWidth());
200
5
    if (FirstBitWidthHash != SecondBitWidthHash) {
201
4
      DiagError(FieldDifferentWidthBitField)
202
4
          << FirstII << FirstField->getBitWidth()->getSourceRange();
203
4
      DiagNote(FieldDifferentWidthBitField)
204
4
          << SecondII << SecondField->getBitWidth()->getSourceRange();
205
4
      return true;
206
4
    }
207
5
  }
208
209
10
  if (!LangOpts.CPlusPlus)
210
4
    return false;
211
212
6
  const bool IsFirstMutable = FirstField->isMutable();
213
6
  const bool IsSecondMutable = SecondField->isMutable();
214
6
  if (IsFirstMutable != IsSecondMutable) {
215
2
    DiagError(FieldSingleMutable) << FirstII << IsFirstMutable;
216
2
    DiagNote(FieldSingleMutable) << SecondII << IsSecondMutable;
217
2
    return true;
218
2
  }
219
220
4
  const Expr *FirstInitializer = FirstField->getInClassInitializer();
221
4
  const Expr *SecondInitializer = SecondField->getInClassInitializer();
222
4
  if ((!FirstInitializer && 
SecondInitializer1
) ||
223
4
      
(3
FirstInitializer3
&&
!SecondInitializer3
)) {
224
1
    DiagError(FieldSingleInitializer)
225
1
        << FirstII << (FirstInitializer != nullptr);
226
1
    DiagNote(FieldSingleInitializer)
227
1
        << SecondII << (SecondInitializer != nullptr);
228
1
    return true;
229
1
  }
230
231
3
  if (FirstInitializer && SecondInitializer) {
232
3
    unsigned FirstInitHash = computeODRHash(FirstInitializer);
233
3
    unsigned SecondInitHash = computeODRHash(SecondInitializer);
234
3
    if (FirstInitHash != SecondInitHash) {
235
3
      DiagError(FieldDifferentInitializers)
236
3
          << FirstII << FirstInitializer->getSourceRange();
237
3
      DiagNote(FieldDifferentInitializers)
238
3
          << SecondII << SecondInitializer->getSourceRange();
239
3
      return true;
240
3
    }
241
3
  }
242
243
0
  return false;
244
3
}
245
246
bool ODRDiagsEmitter::diagnoseSubMismatchTypedef(
247
    const NamedDecl *FirstRecord, StringRef FirstModule, StringRef SecondModule,
248
    const TypedefNameDecl *FirstTD, const TypedefNameDecl *SecondTD,
249
7
    bool IsTypeAlias) const {
250
7
  enum ODRTypedefDifference {
251
7
    TypedefName,
252
7
    TypedefType,
253
7
  };
254
255
7
  auto DiagError = [FirstRecord, FirstTD, FirstModule,
256
7
                    this](ODRTypedefDifference DiffType) {
257
7
    return Diag(FirstTD->getLocation(), diag::err_module_odr_violation_typedef)
258
7
           << FirstRecord << FirstModule.empty() << FirstModule
259
7
           << FirstTD->getSourceRange() << DiffType;
260
7
  };
261
7
  auto DiagNote = [SecondTD, SecondModule,
262
7
                   this](ODRTypedefDifference DiffType) {
263
7
    return Diag(SecondTD->getLocation(),
264
7
                diag::note_module_odr_violation_typedef)
265
7
           << SecondModule << SecondTD->getSourceRange() << DiffType;
266
7
  };
267
268
7
  DeclarationName FirstName = FirstTD->getDeclName();
269
7
  DeclarationName SecondName = SecondTD->getDeclName();
270
7
  if (FirstName != SecondName) {
271
2
    DiagError(TypedefName) << IsTypeAlias << FirstName;
272
2
    DiagNote(TypedefName) << IsTypeAlias << SecondName;
273
2
    return true;
274
2
  }
275
276
5
  QualType FirstType = FirstTD->getUnderlyingType();
277
5
  QualType SecondType = SecondTD->getUnderlyingType();
278
5
  if (computeODRHash(FirstType) != computeODRHash(SecondType)) {
279
5
    DiagError(TypedefType) << IsTypeAlias << FirstName << FirstType;
280
5
    DiagNote(TypedefType) << IsTypeAlias << SecondName << SecondType;
281
5
    return true;
282
5
  }
283
0
  return false;
284
5
}
285
286
bool ODRDiagsEmitter::diagnoseSubMismatchVar(const NamedDecl *FirstRecord,
287
                                             StringRef FirstModule,
288
                                             StringRef SecondModule,
289
                                             const VarDecl *FirstVD,
290
6
                                             const VarDecl *SecondVD) const {
291
6
  enum ODRVarDifference {
292
6
    VarName,
293
6
    VarType,
294
6
    VarSingleInitializer,
295
6
    VarDifferentInitializer,
296
6
    VarConstexpr,
297
6
  };
298
299
6
  auto DiagError = [FirstRecord, FirstVD, FirstModule,
300
6
                    this](ODRVarDifference DiffType) {
301
6
    return Diag(FirstVD->getLocation(), diag::err_module_odr_violation_variable)
302
6
           << FirstRecord << FirstModule.empty() << FirstModule
303
6
           << FirstVD->getSourceRange() << DiffType;
304
6
  };
305
6
  auto DiagNote = [SecondVD, SecondModule, this](ODRVarDifference DiffType) {
306
6
    return Diag(SecondVD->getLocation(),
307
6
                diag::note_module_odr_violation_variable)
308
6
           << SecondModule << SecondVD->getSourceRange() << DiffType;
309
6
  };
310
311
6
  DeclarationName FirstName = FirstVD->getDeclName();
312
6
  DeclarationName SecondName = SecondVD->getDeclName();
313
6
  if (FirstName != SecondName) {
314
1
    DiagError(VarName) << FirstName;
315
1
    DiagNote(VarName) << SecondName;
316
1
    return true;
317
1
  }
318
319
5
  QualType FirstType = FirstVD->getType();
320
5
  QualType SecondType = SecondVD->getType();
321
5
  if (computeODRHash(FirstType) != computeODRHash(SecondType)) {
322
1
    DiagError(VarType) << FirstName << FirstType;
323
1
    DiagNote(VarType) << SecondName << SecondType;
324
1
    return true;
325
1
  }
326
327
4
  if (!LangOpts.CPlusPlus)
328
0
    return false;
329
330
4
  const Expr *FirstInit = FirstVD->getInit();
331
4
  const Expr *SecondInit = SecondVD->getInit();
332
4
  if ((FirstInit == nullptr) != (SecondInit == nullptr)) {
333
1
    DiagError(VarSingleInitializer)
334
1
        << FirstName << (FirstInit == nullptr)
335
1
        << (FirstInit ? 
FirstInit->getSourceRange()0
: SourceRange());
336
1
    DiagNote(VarSingleInitializer)
337
1
        << SecondName << (SecondInit == nullptr)
338
1
        << (SecondInit ? SecondInit->getSourceRange() : 
SourceRange()0
);
339
1
    return true;
340
1
  }
341
342
3
  if (FirstInit && SecondInit &&
343
3
      computeODRHash(FirstInit) != computeODRHash(SecondInit)) {
344
2
    DiagError(VarDifferentInitializer)
345
2
        << FirstName << FirstInit->getSourceRange();
346
2
    DiagNote(VarDifferentInitializer)
347
2
        << SecondName << SecondInit->getSourceRange();
348
2
    return true;
349
2
  }
350
351
1
  const bool FirstIsConstexpr = FirstVD->isConstexpr();
352
1
  const bool SecondIsConstexpr = SecondVD->isConstexpr();
353
1
  if (FirstIsConstexpr != SecondIsConstexpr) {
354
1
    DiagError(VarConstexpr) << FirstName << FirstIsConstexpr;
355
1
    DiagNote(VarConstexpr) << SecondName << SecondIsConstexpr;
356
1
    return true;
357
1
  }
358
0
  return false;
359
1
}
360
361
bool ODRDiagsEmitter::diagnoseSubMismatchProtocols(
362
    const ObjCProtocolList &FirstProtocols,
363
    const ObjCContainerDecl *FirstContainer, StringRef FirstModule,
364
    const ObjCProtocolList &SecondProtocols,
365
97
    const ObjCContainerDecl *SecondContainer, StringRef SecondModule) const {
366
  // Keep in sync with err_module_odr_violation_referenced_protocols.
367
97
  enum ODRReferencedProtocolDifference {
368
97
    NumProtocols,
369
97
    ProtocolType,
370
97
  };
371
97
  auto DiagRefProtocolError = [FirstContainer, FirstModule,
372
97
                               this](SourceLocation Loc, SourceRange Range,
373
97
                                     ODRReferencedProtocolDifference DiffType) {
374
16
    return Diag(Loc, diag::err_module_odr_violation_referenced_protocols)
375
16
           << FirstContainer << FirstModule.empty() << FirstModule << Range
376
16
           << DiffType;
377
16
  };
378
97
  auto DiagRefProtocolNote = [SecondModule,
379
97
                              this](SourceLocation Loc, SourceRange Range,
380
97
                                    ODRReferencedProtocolDifference DiffType) {
381
16
    return Diag(Loc, diag::note_module_odr_violation_referenced_protocols)
382
16
           << SecondModule.empty() << SecondModule << Range << DiffType;
383
16
  };
384
97
  auto GetProtoListSourceRange = [](const ObjCProtocolList &PL) {
385
16
    if (PL.empty())
386
8
      return SourceRange();
387
8
    return SourceRange(*PL.loc_begin(), *std::prev(PL.loc_end()));
388
16
  };
389
390
97
  if (FirstProtocols.size() != SecondProtocols.size()) {
391
8
    DiagRefProtocolError(FirstContainer->getLocation(),
392
8
                         GetProtoListSourceRange(FirstProtocols), NumProtocols)
393
8
        << FirstProtocols.size();
394
8
    DiagRefProtocolNote(SecondContainer->getLocation(),
395
8
                        GetProtoListSourceRange(SecondProtocols), NumProtocols)
396
8
        << SecondProtocols.size();
397
8
    return true;
398
8
  }
399
400
89
  for (unsigned I = 0, E = FirstProtocols.size(); I != E; 
++I0
) {
401
8
    const ObjCProtocolDecl *FirstProtocol = FirstProtocols[I];
402
8
    const ObjCProtocolDecl *SecondProtocol = SecondProtocols[I];
403
8
    DeclarationName FirstProtocolName = FirstProtocol->getDeclName();
404
8
    DeclarationName SecondProtocolName = SecondProtocol->getDeclName();
405
8
    if (FirstProtocolName != SecondProtocolName) {
406
8
      SourceLocation FirstLoc = *(FirstProtocols.loc_begin() + I);
407
8
      SourceLocation SecondLoc = *(SecondProtocols.loc_begin() + I);
408
8
      SourceRange EmptyRange;
409
8
      DiagRefProtocolError(FirstLoc, EmptyRange, ProtocolType)
410
8
          << (I + 1) << FirstProtocolName;
411
8
      DiagRefProtocolNote(SecondLoc, EmptyRange, ProtocolType)
412
8
          << (I + 1) << SecondProtocolName;
413
8
      return true;
414
8
    }
415
8
  }
416
417
81
  return false;
418
89
}
419
420
bool ODRDiagsEmitter::diagnoseSubMismatchObjCMethod(
421
    const NamedDecl *FirstObjCContainer, StringRef FirstModule,
422
    StringRef SecondModule, const ObjCMethodDecl *FirstMethod,
423
30
    const ObjCMethodDecl *SecondMethod) const {
424
30
  enum ODRMethodDifference {
425
30
    ReturnType,
426
30
    InstanceOrClass,
427
30
    ControlLevel, // optional/required
428
30
    DesignatedInitializer,
429
30
    Directness,
430
30
    Name,
431
30
  };
432
433
30
  auto DiagError = [FirstObjCContainer, FirstModule, FirstMethod,
434
30
                    this](ODRMethodDifference DiffType) {
435
18
    return Diag(FirstMethod->getLocation(),
436
18
                diag::err_module_odr_violation_objc_method)
437
18
           << FirstObjCContainer << FirstModule.empty() << FirstModule
438
18
           << FirstMethod->getSourceRange() << DiffType;
439
18
  };
440
30
  auto DiagNote = [SecondModule, SecondMethod,
441
30
                   this](ODRMethodDifference DiffType) {
442
18
    return Diag(SecondMethod->getLocation(),
443
18
                diag::note_module_odr_violation_objc_method)
444
18
           << SecondModule.empty() << SecondModule
445
18
           << SecondMethod->getSourceRange() << DiffType;
446
18
  };
447
448
30
  if (computeODRHash(FirstMethod->getReturnType()) !=
449
30
      computeODRHash(SecondMethod->getReturnType())) {
450
4
    DiagError(ReturnType) << FirstMethod << FirstMethod->getReturnType();
451
4
    DiagNote(ReturnType) << SecondMethod << SecondMethod->getReturnType();
452
4
    return true;
453
4
  }
454
455
26
  if (FirstMethod->isInstanceMethod() != SecondMethod->isInstanceMethod()) {
456
4
    DiagError(InstanceOrClass)
457
4
        << FirstMethod << FirstMethod->isInstanceMethod();
458
4
    DiagNote(InstanceOrClass)
459
4
        << SecondMethod << SecondMethod->isInstanceMethod();
460
4
    return true;
461
4
  }
462
22
  if (FirstMethod->getImplementationControl() !=
463
22
      SecondMethod->getImplementationControl()) {
464
2
    DiagError(ControlLevel) << FirstMethod->getImplementationControl();
465
2
    DiagNote(ControlLevel) << SecondMethod->getImplementationControl();
466
2
    return true;
467
2
  }
468
20
  if (FirstMethod->isThisDeclarationADesignatedInitializer() !=
469
20
      SecondMethod->isThisDeclarationADesignatedInitializer()) {
470
0
    DiagError(DesignatedInitializer)
471
0
        << FirstMethod
472
0
        << FirstMethod->isThisDeclarationADesignatedInitializer();
473
0
    DiagNote(DesignatedInitializer)
474
0
        << SecondMethod
475
0
        << SecondMethod->isThisDeclarationADesignatedInitializer();
476
0
    return true;
477
0
  }
478
20
  if (FirstMethod->isDirectMethod() != SecondMethod->isDirectMethod()) {
479
0
    DiagError(Directness) << FirstMethod << FirstMethod->isDirectMethod();
480
0
    DiagNote(Directness) << SecondMethod << SecondMethod->isDirectMethod();
481
0
    return true;
482
0
  }
483
20
  if (diagnoseSubMismatchMethodParameters(Diags, FirstObjCContainer,
484
20
                                          FirstModule, SecondModule,
485
20
                                          FirstMethod, SecondMethod))
486
12
    return true;
487
488
  // Check method name *after* looking at the parameters otherwise we get a
489
  // less ideal diagnostics: a ObjCMethodName mismatch given that selectors
490
  // for different parameters are likely to be different.
491
8
  DeclarationName FirstName = FirstMethod->getDeclName();
492
8
  DeclarationName SecondName = SecondMethod->getDeclName();
493
8
  if (FirstName != SecondName) {
494
8
    DiagError(Name) << FirstName;
495
8
    DiagNote(Name) << SecondName;
496
8
    return true;
497
8
  }
498
499
0
  return false;
500
8
}
501
502
bool ODRDiagsEmitter::diagnoseSubMismatchObjCProperty(
503
    const NamedDecl *FirstObjCContainer, StringRef FirstModule,
504
    StringRef SecondModule, const ObjCPropertyDecl *FirstProp,
505
24
    const ObjCPropertyDecl *SecondProp) const {
506
24
  enum ODRPropertyDifference {
507
24
    Name,
508
24
    Type,
509
24
    ControlLevel, // optional/required
510
24
    Attribute,
511
24
  };
512
513
24
  auto DiagError = [FirstObjCContainer, FirstModule, FirstProp,
514
24
                    this](SourceLocation Loc, ODRPropertyDifference DiffType) {
515
24
    return Diag(Loc, diag::err_module_odr_violation_objc_property)
516
24
           << FirstObjCContainer << FirstModule.empty() << FirstModule
517
24
           << FirstProp->getSourceRange() << DiffType;
518
24
  };
519
24
  auto DiagNote = [SecondModule, SecondProp,
520
24
                   this](SourceLocation Loc, ODRPropertyDifference DiffType) {
521
24
    return Diag(Loc, diag::note_module_odr_violation_objc_property)
522
24
           << SecondModule.empty() << SecondModule
523
24
           << SecondProp->getSourceRange() << DiffType;
524
24
  };
525
526
24
  IdentifierInfo *FirstII = FirstProp->getIdentifier();
527
24
  IdentifierInfo *SecondII = SecondProp->getIdentifier();
528
24
  if (FirstII->getName() != SecondII->getName()) {
529
8
    DiagError(FirstProp->getLocation(), Name) << FirstII;
530
8
    DiagNote(SecondProp->getLocation(), Name) << SecondII;
531
8
    return true;
532
8
  }
533
16
  if (computeODRHash(FirstProp->getType()) !=
534
16
      computeODRHash(SecondProp->getType())) {
535
4
    DiagError(FirstProp->getLocation(), Type)
536
4
        << FirstII << FirstProp->getType();
537
4
    DiagNote(SecondProp->getLocation(), Type)
538
4
        << SecondII << SecondProp->getType();
539
4
    return true;
540
4
  }
541
12
  if (FirstProp->getPropertyImplementation() !=
542
12
      SecondProp->getPropertyImplementation()) {
543
0
    DiagError(FirstProp->getLocation(), ControlLevel)
544
0
        << FirstProp->getPropertyImplementation();
545
0
    DiagNote(SecondProp->getLocation(), ControlLevel)
546
0
        << SecondProp->getPropertyImplementation();
547
0
    return true;
548
0
  }
549
550
  // Go over the property attributes and stop at the first mismatch.
551
12
  unsigned FirstAttrs = (unsigned)FirstProp->getPropertyAttributes();
552
12
  unsigned SecondAttrs = (unsigned)SecondProp->getPropertyAttributes();
553
12
  if (FirstAttrs != SecondAttrs) {
554
82
    for (unsigned I = 0; I < NumObjCPropertyAttrsBits; 
++I70
) {
555
82
      unsigned CheckedAttr = (1 << I);
556
82
      if ((FirstAttrs & CheckedAttr) == (SecondAttrs & CheckedAttr))
557
70
        continue;
558
559
12
      bool IsFirstWritten =
560
12
          (unsigned)FirstProp->getPropertyAttributesAsWritten() & CheckedAttr;
561
12
      bool IsSecondWritten =
562
12
          (unsigned)SecondProp->getPropertyAttributesAsWritten() & CheckedAttr;
563
12
      DiagError(IsFirstWritten ? 
FirstProp->getLParenLoc()8
564
12
                               : 
FirstProp->getLocation()4
,
565
12
                Attribute)
566
12
          << FirstII << (I + 1) << IsFirstWritten;
567
12
      DiagNote(IsSecondWritten ? 
SecondProp->getLParenLoc()4
568
12
                               : 
SecondProp->getLocation()8
,
569
12
               Attribute)
570
12
          << SecondII << (I + 1);
571
12
      return true;
572
82
    }
573
12
  }
574
575
0
  return false;
576
12
}
577
578
ODRDiagsEmitter::DiffResult
579
ODRDiagsEmitter::FindTypeDiffs(DeclHashes &FirstHashes,
580
236
                               DeclHashes &SecondHashes) {
581
451
  auto DifferenceSelector = [](const Decl *D) {
582
451
    assert(D && "valid Decl required");
583
451
    switch (D->getKind()) {
584
0
    default:
585
0
      return Other;
586
77
    case Decl::AccessSpec:
587
77
      switch (D->getAccess()) {
588
39
      case AS_public:
589
39
        return PublicSpecifer;
590
37
      case AS_private:
591
37
        return PrivateSpecifer;
592
1
      case AS_protected:
593
1
        return ProtectedSpecifer;
594
0
      case AS_none:
595
0
        break;
596
77
      }
597
0
      llvm_unreachable("Invalid access specifier");
598
7
    case Decl::StaticAssert:
599
7
      return StaticAssert;
600
68
    case Decl::Field:
601
68
      return Field;
602
66
    case Decl::CXXMethod:
603
74
    case Decl::CXXConstructor:
604
77
    case Decl::CXXDestructor:
605
77
      return CXXMethod;
606
11
    case Decl::TypeAlias:
607
11
      return TypeAlias;
608
5
    case Decl::Typedef:
609
5
      return TypeDef;
610
13
    case Decl::Var:
611
13
      return Var;
612
8
    case Decl::Friend:
613
8
      return Friend;
614
42
    case Decl::FunctionTemplate:
615
42
      return FunctionTemplate;
616
68
    case Decl::ObjCMethod:
617
68
      return ObjCMethod;
618
19
    case Decl::ObjCIvar:
619
19
      return ObjCIvar;
620
56
    case Decl::ObjCProperty:
621
56
      return ObjCProperty;
622
451
    }
623
451
  };
624
625
236
  DiffResult DR;
626
236
  auto FirstIt = FirstHashes.begin();
627
236
  auto SecondIt = SecondHashes.begin();
628
382
  while (FirstIt != FirstHashes.end() || 
SecondIt != SecondHashes.end()9
) {
629
382
    if (FirstIt != FirstHashes.end() && 
SecondIt != SecondHashes.end()373
&&
630
382
        
FirstIt->second == SecondIt->second361
) {
631
146
      ++FirstIt;
632
146
      ++SecondIt;
633
146
      continue;
634
146
    }
635
636
236
    DR.FirstDecl = FirstIt == FirstHashes.end() ? 
nullptr9
:
FirstIt->first227
;
637
236
    DR.SecondDecl = SecondIt == SecondHashes.end() ? 
nullptr12
:
SecondIt->first224
;
638
639
236
    DR.FirstDiffType =
640
236
        DR.FirstDecl ? 
DifferenceSelector(DR.FirstDecl)227
:
EndOfClass9
;
641
236
    DR.SecondDiffType =
642
236
        DR.SecondDecl ? 
DifferenceSelector(DR.SecondDecl)224
:
EndOfClass12
;
643
236
    return DR;
644
382
  }
645
0
  return DR;
646
236
}
647
648
void ODRDiagsEmitter::diagnoseSubMismatchUnexpected(
649
    DiffResult &DR, const NamedDecl *FirstRecord, StringRef FirstModule,
650
0
    const NamedDecl *SecondRecord, StringRef SecondModule) const {
651
0
  Diag(FirstRecord->getLocation(),
652
0
       diag::err_module_odr_violation_different_definitions)
653
0
      << FirstRecord << FirstModule.empty() << FirstModule;
654
655
0
  if (DR.FirstDecl) {
656
0
    Diag(DR.FirstDecl->getLocation(), diag::note_first_module_difference)
657
0
        << FirstRecord << DR.FirstDecl->getSourceRange();
658
0
  }
659
660
0
  Diag(SecondRecord->getLocation(),
661
0
       diag::note_module_odr_violation_different_definitions)
662
0
      << SecondModule;
663
664
0
  if (DR.SecondDecl) {
665
0
    Diag(DR.SecondDecl->getLocation(), diag::note_second_module_difference)
666
0
        << DR.SecondDecl->getSourceRange();
667
0
  }
668
0
}
669
670
void ODRDiagsEmitter::diagnoseSubMismatchDifferentDeclKinds(
671
    DiffResult &DR, const NamedDecl *FirstRecord, StringRef FirstModule,
672
64
    const NamedDecl *SecondRecord, StringRef SecondModule) const {
673
64
  auto GetMismatchedDeclLoc = [](const NamedDecl *Container,
674
128
                                 ODRMismatchDecl DiffType, const Decl *D) {
675
128
    SourceLocation Loc;
676
128
    SourceRange Range;
677
128
    if (DiffType == EndOfClass) {
678
21
      if (auto *Tag = dyn_cast<TagDecl>(Container))
679
2
        Loc = Tag->getBraceRange().getEnd();
680
19
      else if (auto *IF = dyn_cast<ObjCInterfaceDecl>(Container))
681
11
        Loc = IF->getAtEndRange().getBegin();
682
8
      else
683
8
        Loc = Container->getEndLoc();
684
107
    } else {
685
107
      Loc = D->getLocation();
686
107
      Range = D->getSourceRange();
687
107
    }
688
128
    return std::make_pair(Loc, Range);
689
128
  };
690
691
64
  auto FirstDiagInfo =
692
64
      GetMismatchedDeclLoc(FirstRecord, DR.FirstDiffType, DR.FirstDecl);
693
64
  Diag(FirstDiagInfo.first, diag::err_module_odr_violation_mismatch_decl)
694
64
      << FirstRecord << FirstModule.empty() << FirstModule
695
64
      << FirstDiagInfo.second << DR.FirstDiffType;
696
697
64
  auto SecondDiagInfo =
698
64
      GetMismatchedDeclLoc(SecondRecord, DR.SecondDiffType, DR.SecondDecl);
699
64
  Diag(SecondDiagInfo.first, diag::note_module_odr_violation_mismatch_decl)
700
64
      << SecondModule.empty() << SecondModule << SecondDiagInfo.second
701
64
      << DR.SecondDiffType;
702
64
}
703
704
bool ODRDiagsEmitter::diagnoseMismatch(
705
    const CXXRecordDecl *FirstRecord, const CXXRecordDecl *SecondRecord,
706
164
    const struct CXXRecordDecl::DefinitionData *SecondDD) const {
707
  // Multiple different declarations got merged together; tell the user
708
  // where they came from.
709
164
  if (FirstRecord == SecondRecord)
710
0
    return false;
711
712
164
  std::string FirstModule = getOwningModuleNameForDiagnostic(FirstRecord);
713
164
  std::string SecondModule = getOwningModuleNameForDiagnostic(SecondRecord);
714
715
164
  const struct CXXRecordDecl::DefinitionData *FirstDD =
716
164
      FirstRecord->DefinitionData;
717
164
  assert(FirstDD && SecondDD && "Definitions without DefinitionData");
718
719
  // Diagnostics from DefinitionData are emitted here.
720
164
  if (FirstDD != SecondDD) {
721
    // Keep in sync with err_module_odr_violation_definition_data.
722
164
    enum ODRDefinitionDataDifference {
723
164
      NumBases,
724
164
      NumVBases,
725
164
      BaseType,
726
164
      BaseVirtual,
727
164
      BaseAccess,
728
164
    };
729
164
    auto DiagBaseError = [FirstRecord, &FirstModule,
730
164
                          this](SourceLocation Loc, SourceRange Range,
731
164
                                ODRDefinitionDataDifference DiffType) {
732
10
      return Diag(Loc, diag::err_module_odr_violation_definition_data)
733
10
             << FirstRecord << FirstModule.empty() << FirstModule << Range
734
10
             << DiffType;
735
10
    };
736
164
    auto DiagBaseNote = [&SecondModule,
737
164
                         this](SourceLocation Loc, SourceRange Range,
738
164
                               ODRDefinitionDataDifference DiffType) {
739
10
      return Diag(Loc, diag::note_module_odr_violation_definition_data)
740
10
             << SecondModule << Range << DiffType;
741
10
    };
742
164
    auto GetSourceRange = [](const struct CXXRecordDecl::DefinitionData *DD) {
743
10
      unsigned NumBases = DD->NumBases;
744
10
      if (NumBases == 0)
745
2
        return SourceRange();
746
8
      ArrayRef<CXXBaseSpecifier> bases = DD->bases();
747
8
      return SourceRange(bases[0].getBeginLoc(),
748
8
                         bases[NumBases - 1].getEndLoc());
749
10
    };
750
751
164
    unsigned FirstNumBases = FirstDD->NumBases;
752
164
    unsigned FirstNumVBases = FirstDD->NumVBases;
753
164
    unsigned SecondNumBases = SecondDD->NumBases;
754
164
    unsigned SecondNumVBases = SecondDD->NumVBases;
755
164
    if (FirstNumBases != SecondNumBases) {
756
2
      DiagBaseError(FirstRecord->getLocation(), GetSourceRange(FirstDD),
757
2
                    NumBases)
758
2
          << FirstNumBases;
759
2
      DiagBaseNote(SecondRecord->getLocation(), GetSourceRange(SecondDD),
760
2
                   NumBases)
761
2
          << SecondNumBases;
762
2
      return true;
763
2
    }
764
765
162
    if (FirstNumVBases != SecondNumVBases) {
766
3
      DiagBaseError(FirstRecord->getLocation(), GetSourceRange(FirstDD),
767
3
                    NumVBases)
768
3
          << FirstNumVBases;
769
3
      DiagBaseNote(SecondRecord->getLocation(), GetSourceRange(SecondDD),
770
3
                   NumVBases)
771
3
          << SecondNumVBases;
772
3
      return true;
773
3
    }
774
775
159
    ArrayRef<CXXBaseSpecifier> FirstBases = FirstDD->bases();
776
159
    ArrayRef<CXXBaseSpecifier> SecondBases = SecondDD->bases();
777
164
    for (unsigned I = 0; I < FirstNumBases; 
++I5
) {
778
10
      const CXXBaseSpecifier FirstBase = FirstBases[I];
779
10
      const CXXBaseSpecifier SecondBase = SecondBases[I];
780
10
      if (computeODRHash(FirstBase.getType()) !=
781
10
          computeODRHash(SecondBase.getType())) {
782
1
        DiagBaseError(FirstRecord->getLocation(), FirstBase.getSourceRange(),
783
1
                      BaseType)
784
1
            << (I + 1) << FirstBase.getType();
785
1
        DiagBaseNote(SecondRecord->getLocation(), SecondBase.getSourceRange(),
786
1
                     BaseType)
787
1
            << (I + 1) << SecondBase.getType();
788
1
        return true;
789
1
      }
790
791
9
      if (FirstBase.isVirtual() != SecondBase.isVirtual()) {
792
0
        DiagBaseError(FirstRecord->getLocation(), FirstBase.getSourceRange(),
793
0
                      BaseVirtual)
794
0
            << (I + 1) << FirstBase.isVirtual() << FirstBase.getType();
795
0
        DiagBaseNote(SecondRecord->getLocation(), SecondBase.getSourceRange(),
796
0
                     BaseVirtual)
797
0
            << (I + 1) << SecondBase.isVirtual() << SecondBase.getType();
798
0
        return true;
799
0
      }
800
801
9
      if (FirstBase.getAccessSpecifierAsWritten() !=
802
9
          SecondBase.getAccessSpecifierAsWritten()) {
803
4
        DiagBaseError(FirstRecord->getLocation(), FirstBase.getSourceRange(),
804
4
                      BaseAccess)
805
4
            << (I + 1) << FirstBase.getType()
806
4
            << (int)FirstBase.getAccessSpecifierAsWritten();
807
4
        DiagBaseNote(SecondRecord->getLocation(), SecondBase.getSourceRange(),
808
4
                     BaseAccess)
809
4
            << (I + 1) << SecondBase.getType()
810
4
            << (int)SecondBase.getAccessSpecifierAsWritten();
811
4
        return true;
812
4
      }
813
9
    }
814
159
  }
815
816
154
  const ClassTemplateDecl *FirstTemplate =
817
154
      FirstRecord->getDescribedClassTemplate();
818
154
  const ClassTemplateDecl *SecondTemplate =
819
154
      SecondRecord->getDescribedClassTemplate();
820
821
154
  assert(!FirstTemplate == !SecondTemplate &&
822
154
         "Both pointers should be null or non-null");
823
824
154
  if (FirstTemplate && 
SecondTemplate20
) {
825
20
    ArrayRef<const NamedDecl *> FirstTemplateParams =
826
20
        FirstTemplate->getTemplateParameters()->asArray();
827
20
    ArrayRef<const NamedDecl *> SecondTemplateParams =
828
20
        SecondTemplate->getTemplateParameters()->asArray();
829
20
    assert(FirstTemplateParams.size() == SecondTemplateParams.size() &&
830
20
           "Number of template parameters should be equal.");
831
31
    
for (auto Pair : llvm::zip(FirstTemplateParams, SecondTemplateParams))20
{
832
31
      const NamedDecl *FirstDecl = std::get<0>(Pair);
833
31
      const NamedDecl *SecondDecl = std::get<1>(Pair);
834
31
      if (computeODRHash(FirstDecl) == computeODRHash(SecondDecl))
835
23
        continue;
836
837
8
      assert(FirstDecl->getKind() == SecondDecl->getKind() &&
838
8
             "Parameter Decl's should be the same kind.");
839
840
8
      enum ODRTemplateDifference {
841
8
        ParamEmptyName,
842
8
        ParamName,
843
8
        ParamSingleDefaultArgument,
844
8
        ParamDifferentDefaultArgument,
845
8
      };
846
847
16
      auto hasDefaultArg = [](const NamedDecl *D) {
848
16
        if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(D))
849
8
          return TTP->hasDefaultArgument() &&
850
8
                 
!TTP->defaultArgumentWasInherited()3
;
851
8
        if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D))
852
6
          return NTTP->hasDefaultArgument() &&
853
6
                 !NTTP->defaultArgumentWasInherited();
854
2
        auto *TTP = cast<TemplateTemplateParmDecl>(D);
855
2
        return TTP->hasDefaultArgument() && !TTP->defaultArgumentWasInherited();
856
8
      };
857
8
      bool hasFirstArg = hasDefaultArg(FirstDecl);
858
8
      bool hasSecondArg = hasDefaultArg(SecondDecl);
859
860
8
      ODRTemplateDifference ErrDiffType;
861
8
      ODRTemplateDifference NoteDiffType;
862
863
8
      DeclarationName FirstName = FirstDecl->getDeclName();
864
8
      DeclarationName SecondName = SecondDecl->getDeclName();
865
866
8
      if (FirstName != SecondName) {
867
2
        bool FirstNameEmpty =
868
2
            FirstName.isIdentifier() && !FirstName.getAsIdentifierInfo();
869
2
        bool SecondNameEmpty =
870
2
            SecondName.isIdentifier() && !SecondName.getAsIdentifierInfo();
871
2
        ErrDiffType = FirstNameEmpty ? 
ParamEmptyName1
:
ParamName1
;
872
2
        NoteDiffType = SecondNameEmpty ? 
ParamEmptyName0
: ParamName;
873
6
      } else if (hasFirstArg == hasSecondArg)
874
4
        ErrDiffType = NoteDiffType = ParamDifferentDefaultArgument;
875
2
      else
876
2
        ErrDiffType = NoteDiffType = ParamSingleDefaultArgument;
877
878
8
      Diag(FirstDecl->getLocation(),
879
8
           diag::err_module_odr_violation_template_parameter)
880
8
          << FirstRecord << FirstModule.empty() << FirstModule
881
8
          << FirstDecl->getSourceRange() << ErrDiffType << hasFirstArg
882
8
          << FirstName;
883
8
      Diag(SecondDecl->getLocation(),
884
8
           diag::note_module_odr_violation_template_parameter)
885
8
          << SecondModule << SecondDecl->getSourceRange() << NoteDiffType
886
8
          << hasSecondArg << SecondName;
887
8
      return true;
888
8
    }
889
20
  }
890
891
146
  auto PopulateHashes = [](DeclHashes &Hashes, const RecordDecl *Record,
892
292
                           const DeclContext *DC) {
893
984
    for (const Decl *D : Record->decls()) {
894
984
      if (!ODRHash::isSubDeclToBeProcessed(D, DC))
895
327
        continue;
896
657
      Hashes.emplace_back(D, computeODRHash(D));
897
657
    }
898
292
  };
899
900
146
  DeclHashes FirstHashes;
901
146
  DeclHashes SecondHashes;
902
146
  const DeclContext *DC = FirstRecord;
903
146
  PopulateHashes(FirstHashes, FirstRecord, DC);
904
146
  PopulateHashes(SecondHashes, SecondRecord, DC);
905
906
146
  DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);
907
146
  ODRMismatchDecl FirstDiffType = DR.FirstDiffType;
908
146
  ODRMismatchDecl SecondDiffType = DR.SecondDiffType;
909
146
  const Decl *FirstDecl = DR.FirstDecl;
910
146
  const Decl *SecondDecl = DR.SecondDecl;
911
912
146
  if (FirstDiffType == Other || SecondDiffType == Other) {
913
0
    diagnoseSubMismatchUnexpected(DR, FirstRecord, FirstModule, SecondRecord,
914
0
                                  SecondModule);
915
0
    return true;
916
0
  }
917
918
146
  if (FirstDiffType != SecondDiffType) {
919
44
    diagnoseSubMismatchDifferentDeclKinds(DR, FirstRecord, FirstModule,
920
44
                                          SecondRecord, SecondModule);
921
44
    return true;
922
44
  }
923
924
  // Used with err_module_odr_violation_record and
925
  // note_module_odr_violation_record
926
102
  enum ODRCXXRecordDifference {
927
102
    StaticAssertCondition,
928
102
    StaticAssertMessage,
929
102
    StaticAssertOnlyMessage,
930
102
    MethodName,
931
102
    MethodDeleted,
932
102
    MethodDefaulted,
933
102
    MethodVirtual,
934
102
    MethodStatic,
935
102
    MethodVolatile,
936
102
    MethodConst,
937
102
    MethodInline,
938
102
    MethodParameterSingleDefaultArgument,
939
102
    MethodParameterDifferentDefaultArgument,
940
102
    MethodNoTemplateArguments,
941
102
    MethodDifferentNumberTemplateArguments,
942
102
    MethodDifferentTemplateArgument,
943
102
    MethodSingleBody,
944
102
    MethodDifferentBody,
945
102
    FriendTypeFunction,
946
102
    FriendType,
947
102
    FriendFunction,
948
102
    FunctionTemplateDifferentNumberParameters,
949
102
    FunctionTemplateParameterDifferentKind,
950
102
    FunctionTemplateParameterName,
951
102
    FunctionTemplateParameterSingleDefaultArgument,
952
102
    FunctionTemplateParameterDifferentDefaultArgument,
953
102
    FunctionTemplateParameterDifferentType,
954
102
    FunctionTemplatePackParameter,
955
102
  };
956
102
  auto DiagError = [FirstRecord, &FirstModule,
957
102
                    this](SourceLocation Loc, SourceRange Range,
958
102
                          ODRCXXRecordDifference DiffType) {
959
59
    return Diag(Loc, diag::err_module_odr_violation_record)
960
59
           << FirstRecord << FirstModule.empty() << FirstModule << Range
961
59
           << DiffType;
962
59
  };
963
102
  auto DiagNote = [&SecondModule, this](SourceLocation Loc, SourceRange Range,
964
102
                                        ODRCXXRecordDifference DiffType) {
965
59
    return Diag(Loc, diag::note_module_odr_violation_record)
966
59
           << SecondModule << Range << DiffType;
967
59
  };
968
969
102
  assert(FirstDiffType == SecondDiffType);
970
102
  switch (FirstDiffType) {
971
0
  case Other:
972
0
  case EndOfClass:
973
0
  case PublicSpecifer:
974
0
  case PrivateSpecifer:
975
0
  case ProtectedSpecifer:
976
0
  case ObjCMethod:
977
0
  case ObjCIvar:
978
0
  case ObjCProperty:
979
0
    llvm_unreachable("Invalid diff type");
980
981
3
  case StaticAssert: {
982
3
    const StaticAssertDecl *FirstSA = cast<StaticAssertDecl>(FirstDecl);
983
3
    const StaticAssertDecl *SecondSA = cast<StaticAssertDecl>(SecondDecl);
984
985
3
    const Expr *FirstExpr = FirstSA->getAssertExpr();
986
3
    const Expr *SecondExpr = SecondSA->getAssertExpr();
987
3
    unsigned FirstODRHash = computeODRHash(FirstExpr);
988
3
    unsigned SecondODRHash = computeODRHash(SecondExpr);
989
3
    if (FirstODRHash != SecondODRHash) {
990
1
      DiagError(FirstExpr->getBeginLoc(), FirstExpr->getSourceRange(),
991
1
                StaticAssertCondition);
992
1
      DiagNote(SecondExpr->getBeginLoc(), SecondExpr->getSourceRange(),
993
1
               StaticAssertCondition);
994
1
      return true;
995
1
    }
996
997
2
    const StringLiteral *FirstStr = FirstSA->getMessage();
998
2
    const StringLiteral *SecondStr = SecondSA->getMessage();
999
2
    assert((FirstStr || SecondStr) && "Both messages cannot be empty");
1000
2
    if ((FirstStr && 
!SecondStr1
) || (!FirstStr &&
SecondStr1
)) {
1001
1
      SourceLocation FirstLoc, SecondLoc;
1002
1
      SourceRange FirstRange, SecondRange;
1003
1
      if (FirstStr) {
1004
0
        FirstLoc = FirstStr->getBeginLoc();
1005
0
        FirstRange = FirstStr->getSourceRange();
1006
1
      } else {
1007
1
        FirstLoc = FirstSA->getBeginLoc();
1008
1
        FirstRange = FirstSA->getSourceRange();
1009
1
      }
1010
1
      if (SecondStr) {
1011
1
        SecondLoc = SecondStr->getBeginLoc();
1012
1
        SecondRange = SecondStr->getSourceRange();
1013
1
      } else {
1014
0
        SecondLoc = SecondSA->getBeginLoc();
1015
0
        SecondRange = SecondSA->getSourceRange();
1016
0
      }
1017
1
      DiagError(FirstLoc, FirstRange, StaticAssertOnlyMessage)
1018
1
          << (FirstStr == nullptr);
1019
1
      DiagNote(SecondLoc, SecondRange, StaticAssertOnlyMessage)
1020
1
          << (SecondStr == nullptr);
1021
1
      return true;
1022
1
    }
1023
1024
1
    if (FirstStr && SecondStr &&
1025
1
        FirstStr->getString() != SecondStr->getString()) {
1026
1
      DiagError(FirstStr->getBeginLoc(), FirstStr->getSourceRange(),
1027
1
                StaticAssertMessage);
1028
1
      DiagNote(SecondStr->getBeginLoc(), SecondStr->getSourceRange(),
1029
1
               StaticAssertMessage);
1030
1
      return true;
1031
1
    }
1032
0
    break;
1033
1
  }
1034
1035
24
  case Field: {
1036
24
    if (diagnoseSubMismatchField(FirstRecord, FirstModule, SecondModule,
1037
24
                                 cast<FieldDecl>(FirstDecl),
1038
24
                                 cast<FieldDecl>(SecondDecl)))
1039
24
      return true;
1040
0
    break;
1041
24
  }
1042
1043
38
  case CXXMethod: {
1044
38
    enum {
1045
38
      DiagMethod,
1046
38
      DiagConstructor,
1047
38
      DiagDestructor,
1048
38
    } FirstMethodType,
1049
38
        SecondMethodType;
1050
76
    auto GetMethodTypeForDiagnostics = [](const CXXMethodDecl *D) {
1051
76
      if (isa<CXXConstructorDecl>(D))
1052
8
        return DiagConstructor;
1053
68
      if (isa<CXXDestructorDecl>(D))
1054
3
        return DiagDestructor;
1055
65
      return DiagMethod;
1056
68
    };
1057
38
    const CXXMethodDecl *FirstMethod = cast<CXXMethodDecl>(FirstDecl);
1058
38
    const CXXMethodDecl *SecondMethod = cast<CXXMethodDecl>(SecondDecl);
1059
38
    FirstMethodType = GetMethodTypeForDiagnostics(FirstMethod);
1060
38
    SecondMethodType = GetMethodTypeForDiagnostics(SecondMethod);
1061
38
    DeclarationName FirstName = FirstMethod->getDeclName();
1062
38
    DeclarationName SecondName = SecondMethod->getDeclName();
1063
38
    auto DiagMethodError = [&DiagError, FirstMethod, FirstMethodType,
1064
38
                            FirstName](ODRCXXRecordDifference DiffType) {
1065
32
      return DiagError(FirstMethod->getLocation(),
1066
32
                       FirstMethod->getSourceRange(), DiffType)
1067
32
             << FirstMethodType << FirstName;
1068
32
    };
1069
38
    auto DiagMethodNote = [&DiagNote, SecondMethod, SecondMethodType,
1070
38
                           SecondName](ODRCXXRecordDifference DiffType) {
1071
32
      return DiagNote(SecondMethod->getLocation(),
1072
32
                      SecondMethod->getSourceRange(), DiffType)
1073
32
             << SecondMethodType << SecondName;
1074
32
    };
1075
1076
38
    if (FirstMethodType != SecondMethodType || 
FirstName != SecondName36
) {
1077
3
      DiagMethodError(MethodName);
1078
3
      DiagMethodNote(MethodName);
1079
3
      return true;
1080
3
    }
1081
1082
35
    const bool FirstDeleted = FirstMethod->isDeletedAsWritten();
1083
35
    const bool SecondDeleted = SecondMethod->isDeletedAsWritten();
1084
35
    if (FirstDeleted != SecondDeleted) {
1085
1
      DiagMethodError(MethodDeleted) << FirstDeleted;
1086
1
      DiagMethodNote(MethodDeleted) << SecondDeleted;
1087
1
      return true;
1088
1
    }
1089
1090
34
    const bool FirstDefaulted = FirstMethod->isExplicitlyDefaulted();
1091
34
    const bool SecondDefaulted = SecondMethod->isExplicitlyDefaulted();
1092
34
    if (FirstDefaulted != SecondDefaulted) {
1093
1
      DiagMethodError(MethodDefaulted) << FirstDefaulted;
1094
1
      DiagMethodNote(MethodDefaulted) << SecondDefaulted;
1095
1
      return true;
1096
1
    }
1097
1098
33
    const bool FirstVirtual = FirstMethod->isVirtualAsWritten();
1099
33
    const bool SecondVirtual = SecondMethod->isVirtualAsWritten();
1100
33
    const bool FirstPure = FirstMethod->isPure();
1101
33
    const bool SecondPure = SecondMethod->isPure();
1102
33
    if ((FirstVirtual || 
SecondVirtual32
) &&
1103
33
        
(3
FirstVirtual != SecondVirtual3
||
FirstPure != SecondPure1
)) {
1104
3
      DiagMethodError(MethodVirtual) << FirstPure << FirstVirtual;
1105
3
      DiagMethodNote(MethodVirtual) << SecondPure << SecondVirtual;
1106
3
      return true;
1107
3
    }
1108
1109
    // CXXMethodDecl::isStatic uses the canonical Decl.  With Decl merging,
1110
    // FirstDecl is the canonical Decl of SecondDecl, so the storage
1111
    // class needs to be checked instead.
1112
30
    StorageClass FirstStorage = FirstMethod->getStorageClass();
1113
30
    StorageClass SecondStorage = SecondMethod->getStorageClass();
1114
30
    const bool FirstStatic = FirstStorage == SC_Static;
1115
30
    const bool SecondStatic = SecondStorage == SC_Static;
1116
30
    if (FirstStatic != SecondStatic) {
1117
1
      DiagMethodError(MethodStatic) << FirstStatic;
1118
1
      DiagMethodNote(MethodStatic) << SecondStatic;
1119
1
      return true;
1120
1
    }
1121
1122
29
    const bool FirstVolatile = FirstMethod->isVolatile();
1123
29
    const bool SecondVolatile = SecondMethod->isVolatile();
1124
29
    if (FirstVolatile != SecondVolatile) {
1125
1
      DiagMethodError(MethodVolatile) << FirstVolatile;
1126
1
      DiagMethodNote(MethodVolatile) << SecondVolatile;
1127
1
      return true;
1128
1
    }
1129
1130
28
    const bool FirstConst = FirstMethod->isConst();
1131
28
    const bool SecondConst = SecondMethod->isConst();
1132
28
    if (FirstConst != SecondConst) {
1133
1
      DiagMethodError(MethodConst) << FirstConst;
1134
1
      DiagMethodNote(MethodConst) << SecondConst;
1135
1
      return true;
1136
1
    }
1137
1138
27
    const bool FirstInline = FirstMethod->isInlineSpecified();
1139
27
    const bool SecondInline = SecondMethod->isInlineSpecified();
1140
27
    if (FirstInline != SecondInline) {
1141
1
      DiagMethodError(MethodInline) << FirstInline;
1142
1
      DiagMethodNote(MethodInline) << SecondInline;
1143
1
      return true;
1144
1
    }
1145
1146
26
    if (diagnoseSubMismatchMethodParameters(Diags, FirstRecord,
1147
26
                                            FirstModule, SecondModule,
1148
26
                                            FirstMethod, SecondMethod))
1149
6
      return true;
1150
1151
20
    for (unsigned I = 0, N = FirstMethod->param_size(); I < N; 
++I0
) {
1152
4
      const ParmVarDecl *FirstParam = FirstMethod->getParamDecl(I);
1153
4
      const ParmVarDecl *SecondParam = SecondMethod->getParamDecl(I);
1154
1155
4
      const Expr *FirstInit = FirstParam->getInit();
1156
4
      const Expr *SecondInit = SecondParam->getInit();
1157
4
      if ((FirstInit == nullptr) != (SecondInit == nullptr)) {
1158
1
        DiagMethodError(MethodParameterSingleDefaultArgument)
1159
1
            << (I + 1) << (FirstInit == nullptr)
1160
1
            << (FirstInit ? FirstInit->getSourceRange() : 
SourceRange()0
);
1161
1
        DiagMethodNote(MethodParameterSingleDefaultArgument)
1162
1
            << (I + 1) << (SecondInit == nullptr)
1163
1
            << (SecondInit ? 
SecondInit->getSourceRange()0
: SourceRange());
1164
1
        return true;
1165
1
      }
1166
1167
3
      if (FirstInit && SecondInit &&
1168
3
          computeODRHash(FirstInit) != computeODRHash(SecondInit)) {
1169
3
        DiagMethodError(MethodParameterDifferentDefaultArgument)
1170
3
            << (I + 1) << FirstInit->getSourceRange();
1171
3
        DiagMethodNote(MethodParameterDifferentDefaultArgument)
1172
3
            << (I + 1) << SecondInit->getSourceRange();
1173
3
        return true;
1174
3
      }
1175
3
    }
1176
1177
16
    const TemplateArgumentList *FirstTemplateArgs =
1178
16
        FirstMethod->getTemplateSpecializationArgs();
1179
16
    const TemplateArgumentList *SecondTemplateArgs =
1180
16
        SecondMethod->getTemplateSpecializationArgs();
1181
1182
16
    if ((FirstTemplateArgs && 
!SecondTemplateArgs8
) ||
1183
16
        (!FirstTemplateArgs && 
SecondTemplateArgs8
)) {
1184
1
      DiagMethodError(MethodNoTemplateArguments)
1185
1
          << (FirstTemplateArgs != nullptr);
1186
1
      DiagMethodNote(MethodNoTemplateArguments)
1187
1
          << (SecondTemplateArgs != nullptr);
1188
1
      return true;
1189
1
    }
1190
1191
15
    if (FirstTemplateArgs && 
SecondTemplateArgs8
) {
1192
      // Remove pack expansions from argument list.
1193
16
      auto ExpandTemplateArgumentList = [](const TemplateArgumentList *TAL) {
1194
16
        llvm::SmallVector<const TemplateArgument *, 8> ExpandedList;
1195
23
        for (const TemplateArgument &TA : TAL->asArray()) {
1196
23
          if (TA.getKind() != TemplateArgument::Pack) {
1197
19
            ExpandedList.push_back(&TA);
1198
19
            continue;
1199
19
          }
1200
4
          llvm::append_range(ExpandedList,
1201
4
                             llvm::make_pointer_range(TA.getPackAsArray()));
1202
4
        }
1203
16
        return ExpandedList;
1204
16
      };
1205
8
      llvm::SmallVector<const TemplateArgument *, 8> FirstExpandedList =
1206
8
          ExpandTemplateArgumentList(FirstTemplateArgs);
1207
8
      llvm::SmallVector<const TemplateArgument *, 8> SecondExpandedList =
1208
8
          ExpandTemplateArgumentList(SecondTemplateArgs);
1209
1210
8
      if (FirstExpandedList.size() != SecondExpandedList.size()) {
1211
2
        DiagMethodError(MethodDifferentNumberTemplateArguments)
1212
2
            << (unsigned)FirstExpandedList.size();
1213
2
        DiagMethodNote(MethodDifferentNumberTemplateArguments)
1214
2
            << (unsigned)SecondExpandedList.size();
1215
2
        return true;
1216
2
      }
1217
1218
7
      
for (unsigned i = 0, e = FirstExpandedList.size(); 6
i != e;
++i1
) {
1219
7
        const TemplateArgument &FirstTA = *FirstExpandedList[i],
1220
7
                               &SecondTA = *SecondExpandedList[i];
1221
7
        if (computeODRHash(FirstTA) == computeODRHash(SecondTA))
1222
1
          continue;
1223
1224
6
        DiagMethodError(MethodDifferentTemplateArgument) << FirstTA << i + 1;
1225
6
        DiagMethodNote(MethodDifferentTemplateArgument) << SecondTA << i + 1;
1226
6
        return true;
1227
7
      }
1228
6
    }
1229
1230
    // Compute the hash of the method as if it has no body.
1231
14
    
auto ComputeCXXMethodODRHash = [](const CXXMethodDecl *D) 7
{
1232
14
      ODRHash Hasher;
1233
14
      Hasher.AddFunctionDecl(D, true /*SkipBody*/);
1234
14
      return Hasher.CalculateHash();
1235
14
    };
1236
1237
    // Compare the hash generated to the hash stored.  A difference means
1238
    // that a body was present in the original source.  Due to merging,
1239
    // the standard way of detecting a body will not work.
1240
7
    const bool HasFirstBody =
1241
7
        ComputeCXXMethodODRHash(FirstMethod) != FirstMethod->getODRHash();
1242
7
    const bool HasSecondBody =
1243
7
        ComputeCXXMethodODRHash(SecondMethod) != SecondMethod->getODRHash();
1244
1245
7
    if (HasFirstBody != HasSecondBody) {
1246
6
      DiagMethodError(MethodSingleBody) << HasFirstBody;
1247
6
      DiagMethodNote(MethodSingleBody) << HasSecondBody;
1248
6
      return true;
1249
6
    }
1250
1251
1
    if (HasFirstBody && HasSecondBody) {
1252
1
      DiagMethodError(MethodDifferentBody);
1253
1
      DiagMethodNote(MethodDifferentBody);
1254
1
      return true;
1255
1
    }
1256
1257
0
    break;
1258
1
  }
1259
1260
5
  case TypeAlias:
1261
7
  case TypeDef: {
1262
7
    if (diagnoseSubMismatchTypedef(FirstRecord, FirstModule, SecondModule,
1263
7
                                   cast<TypedefNameDecl>(FirstDecl),
1264
7
                                   cast<TypedefNameDecl>(SecondDecl),
1265
7
                                   FirstDiffType == TypeAlias))
1266
7
      return true;
1267
0
    break;
1268
7
  }
1269
6
  case Var: {
1270
6
    if (diagnoseSubMismatchVar(FirstRecord, FirstModule, SecondModule,
1271
6
                               cast<VarDecl>(FirstDecl),
1272
6
                               cast<VarDecl>(SecondDecl)))
1273
6
      return true;
1274
0
    break;
1275
6
  }
1276
4
  case Friend: {
1277
4
    const FriendDecl *FirstFriend = cast<FriendDecl>(FirstDecl);
1278
4
    const FriendDecl *SecondFriend = cast<FriendDecl>(SecondDecl);
1279
1280
4
    const NamedDecl *FirstND = FirstFriend->getFriendDecl();
1281
4
    const NamedDecl *SecondND = SecondFriend->getFriendDecl();
1282
1283
4
    TypeSourceInfo *FirstTSI = FirstFriend->getFriendType();
1284
4
    TypeSourceInfo *SecondTSI = SecondFriend->getFriendType();
1285
1286
4
    if (FirstND && 
SecondND2
) {
1287
1
      DiagError(FirstFriend->getFriendLoc(), FirstFriend->getSourceRange(),
1288
1
                FriendFunction)
1289
1
          << FirstND;
1290
1
      DiagNote(SecondFriend->getFriendLoc(), SecondFriend->getSourceRange(),
1291
1
               FriendFunction)
1292
1
          << SecondND;
1293
1
      return true;
1294
1
    }
1295
1296
3
    if (FirstTSI && 
SecondTSI2
) {
1297
2
      QualType FirstFriendType = FirstTSI->getType();
1298
2
      QualType SecondFriendType = SecondTSI->getType();
1299
2
      assert(computeODRHash(FirstFriendType) !=
1300
2
             computeODRHash(SecondFriendType));
1301
2
      DiagError(FirstFriend->getFriendLoc(), FirstFriend->getSourceRange(),
1302
2
                FriendType)
1303
2
          << FirstFriendType;
1304
2
      DiagNote(SecondFriend->getFriendLoc(), SecondFriend->getSourceRange(),
1305
2
               FriendType)
1306
2
          << SecondFriendType;
1307
2
      return true;
1308
2
    }
1309
1310
1
    DiagError(FirstFriend->getFriendLoc(), FirstFriend->getSourceRange(),
1311
1
              FriendTypeFunction)
1312
1
        << (FirstTSI == nullptr);
1313
1
    DiagNote(SecondFriend->getFriendLoc(), SecondFriend->getSourceRange(),
1314
1
             FriendTypeFunction)
1315
1
        << (SecondTSI == nullptr);
1316
1
    return true;
1317
3
  }
1318
20
  case FunctionTemplate: {
1319
20
    const FunctionTemplateDecl *FirstTemplate =
1320
20
        cast<FunctionTemplateDecl>(FirstDecl);
1321
20
    const FunctionTemplateDecl *SecondTemplate =
1322
20
        cast<FunctionTemplateDecl>(SecondDecl);
1323
1324
20
    TemplateParameterList *FirstTPL = FirstTemplate->getTemplateParameters();
1325
20
    TemplateParameterList *SecondTPL = SecondTemplate->getTemplateParameters();
1326
1327
20
    auto DiagTemplateError = [&DiagError,
1328
20
                              FirstTemplate](ODRCXXRecordDifference DiffType) {
1329
20
      return DiagError(FirstTemplate->getLocation(),
1330
20
                       FirstTemplate->getSourceRange(), DiffType)
1331
20
             << FirstTemplate;
1332
20
    };
1333
20
    auto DiagTemplateNote = [&DiagNote,
1334
20
                             SecondTemplate](ODRCXXRecordDifference DiffType) {
1335
20
      return DiagNote(SecondTemplate->getLocation(),
1336
20
                      SecondTemplate->getSourceRange(), DiffType)
1337
20
             << SecondTemplate;
1338
20
    };
1339
1340
20
    if (FirstTPL->size() != SecondTPL->size()) {
1341
1
      DiagTemplateError(FunctionTemplateDifferentNumberParameters)
1342
1
          << FirstTPL->size();
1343
1
      DiagTemplateNote(FunctionTemplateDifferentNumberParameters)
1344
1
          << SecondTPL->size();
1345
1
      return true;
1346
1
    }
1347
1348
19
    for (unsigned i = 0, e = FirstTPL->size(); i != e; 
++i0
) {
1349
19
      NamedDecl *FirstParam = FirstTPL->getParam(i);
1350
19
      NamedDecl *SecondParam = SecondTPL->getParam(i);
1351
1352
19
      if (FirstParam->getKind() != SecondParam->getKind()) {
1353
3
        enum {
1354
3
          TemplateTypeParameter,
1355
3
          NonTypeTemplateParameter,
1356
3
          TemplateTemplateParameter,
1357
3
        };
1358
6
        auto GetParamType = [](NamedDecl *D) {
1359
6
          switch (D->getKind()) {
1360
0
          default:
1361
0
            llvm_unreachable("Unexpected template parameter type");
1362
2
          case Decl::TemplateTypeParm:
1363
2
            return TemplateTypeParameter;
1364
2
          case Decl::NonTypeTemplateParm:
1365
2
            return NonTypeTemplateParameter;
1366
2
          case Decl::TemplateTemplateParm:
1367
2
            return TemplateTemplateParameter;
1368
6
          }
1369
6
        };
1370
1371
3
        DiagTemplateError(FunctionTemplateParameterDifferentKind)
1372
3
            << (i + 1) << GetParamType(FirstParam);
1373
3
        DiagTemplateNote(FunctionTemplateParameterDifferentKind)
1374
3
            << (i + 1) << GetParamType(SecondParam);
1375
3
        return true;
1376
3
      }
1377
1378
16
      if (FirstParam->getName() != SecondParam->getName()) {
1379
2
        DiagTemplateError(FunctionTemplateParameterName)
1380
2
            << (i + 1) << (bool)FirstParam->getIdentifier() << FirstParam;
1381
2
        DiagTemplateNote(FunctionTemplateParameterName)
1382
2
            << (i + 1) << (bool)SecondParam->getIdentifier() << SecondParam;
1383
2
        return true;
1384
2
      }
1385
1386
14
      if (isa<TemplateTypeParmDecl>(FirstParam) &&
1387
14
          
isa<TemplateTypeParmDecl>(SecondParam)6
) {
1388
6
        TemplateTypeParmDecl *FirstTTPD =
1389
6
            cast<TemplateTypeParmDecl>(FirstParam);
1390
6
        TemplateTypeParmDecl *SecondTTPD =
1391
6
            cast<TemplateTypeParmDecl>(SecondParam);
1392
6
        bool HasFirstDefaultArgument =
1393
6
            FirstTTPD->hasDefaultArgument() &&
1394
6
            
!FirstTTPD->defaultArgumentWasInherited()3
;
1395
6
        bool HasSecondDefaultArgument =
1396
6
            SecondTTPD->hasDefaultArgument() &&
1397
6
            
!SecondTTPD->defaultArgumentWasInherited()5
;
1398
6
        if (HasFirstDefaultArgument != HasSecondDefaultArgument) {
1399
3
          DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument)
1400
3
              << (i + 1) << HasFirstDefaultArgument;
1401
3
          DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument)
1402
3
              << (i + 1) << HasSecondDefaultArgument;
1403
3
          return true;
1404
3
        }
1405
1406
3
        if (HasFirstDefaultArgument && 
HasSecondDefaultArgument2
) {
1407
2
          QualType FirstType = FirstTTPD->getDefaultArgument();
1408
2
          QualType SecondType = SecondTTPD->getDefaultArgument();
1409
2
          if (computeODRHash(FirstType) != computeODRHash(SecondType)) {
1410
2
            DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument)
1411
2
                << (i + 1) << FirstType;
1412
2
            DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument)
1413
2
                << (i + 1) << SecondType;
1414
2
            return true;
1415
2
          }
1416
2
        }
1417
1418
1
        if (FirstTTPD->isParameterPack() != SecondTTPD->isParameterPack()) {
1419
1
          DiagTemplateError(FunctionTemplatePackParameter)
1420
1
              << (i + 1) << FirstTTPD->isParameterPack();
1421
1
          DiagTemplateNote(FunctionTemplatePackParameter)
1422
1
              << (i + 1) << SecondTTPD->isParameterPack();
1423
1
          return true;
1424
1
        }
1425
1
      }
1426
1427
8
      if (isa<TemplateTemplateParmDecl>(FirstParam) &&
1428
8
          
isa<TemplateTemplateParmDecl>(SecondParam)4
) {
1429
4
        TemplateTemplateParmDecl *FirstTTPD =
1430
4
            cast<TemplateTemplateParmDecl>(FirstParam);
1431
4
        TemplateTemplateParmDecl *SecondTTPD =
1432
4
            cast<TemplateTemplateParmDecl>(SecondParam);
1433
1434
4
        TemplateParameterList *FirstTPL = FirstTTPD->getTemplateParameters();
1435
4
        TemplateParameterList *SecondTPL = SecondTTPD->getTemplateParameters();
1436
1437
4
        auto ComputeTemplateParameterListODRHash =
1438
8
            [](const TemplateParameterList *TPL) {
1439
8
              assert(TPL);
1440
8
              ODRHash Hasher;
1441
8
              Hasher.AddTemplateParameterList(TPL);
1442
8
              return Hasher.CalculateHash();
1443
8
            };
1444
1445
4
        if (ComputeTemplateParameterListODRHash(FirstTPL) !=
1446
4
            ComputeTemplateParameterListODRHash(SecondTPL)) {
1447
1
          DiagTemplateError(FunctionTemplateParameterDifferentType) << (i + 1);
1448
1
          DiagTemplateNote(FunctionTemplateParameterDifferentType) << (i + 1);
1449
1
          return true;
1450
1
        }
1451
1452
3
        bool HasFirstDefaultArgument =
1453
3
            FirstTTPD->hasDefaultArgument() &&
1454
3
            
!FirstTTPD->defaultArgumentWasInherited()1
;
1455
3
        bool HasSecondDefaultArgument =
1456
3
            SecondTTPD->hasDefaultArgument() &&
1457
3
            
!SecondTTPD->defaultArgumentWasInherited()2
;
1458
3
        if (HasFirstDefaultArgument != HasSecondDefaultArgument) {
1459
1
          DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument)
1460
1
              << (i + 1) << HasFirstDefaultArgument;
1461
1
          DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument)
1462
1
              << (i + 1) << HasSecondDefaultArgument;
1463
1
          return true;
1464
1
        }
1465
1466
2
        if (HasFirstDefaultArgument && 
HasSecondDefaultArgument1
) {
1467
1
          TemplateArgument FirstTA =
1468
1
              FirstTTPD->getDefaultArgument().getArgument();
1469
1
          TemplateArgument SecondTA =
1470
1
              SecondTTPD->getDefaultArgument().getArgument();
1471
1
          if (computeODRHash(FirstTA) != computeODRHash(SecondTA)) {
1472
1
            DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument)
1473
1
                << (i + 1) << FirstTA;
1474
1
            DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument)
1475
1
                << (i + 1) << SecondTA;
1476
1
            return true;
1477
1
          }
1478
1
        }
1479
1480
1
        if (FirstTTPD->isParameterPack() != SecondTTPD->isParameterPack()) {
1481
1
          DiagTemplateError(FunctionTemplatePackParameter)
1482
1
              << (i + 1) << FirstTTPD->isParameterPack();
1483
1
          DiagTemplateNote(FunctionTemplatePackParameter)
1484
1
              << (i + 1) << SecondTTPD->isParameterPack();
1485
1
          return true;
1486
1
        }
1487
1
      }
1488
1489
4
      if (isa<NonTypeTemplateParmDecl>(FirstParam) &&
1490
4
          isa<NonTypeTemplateParmDecl>(SecondParam)) {
1491
4
        NonTypeTemplateParmDecl *FirstNTTPD =
1492
4
            cast<NonTypeTemplateParmDecl>(FirstParam);
1493
4
        NonTypeTemplateParmDecl *SecondNTTPD =
1494
4
            cast<NonTypeTemplateParmDecl>(SecondParam);
1495
1496
4
        QualType FirstType = FirstNTTPD->getType();
1497
4
        QualType SecondType = SecondNTTPD->getType();
1498
4
        if (computeODRHash(FirstType) != computeODRHash(SecondType)) {
1499
1
          DiagTemplateError(FunctionTemplateParameterDifferentType) << (i + 1);
1500
1
          DiagTemplateNote(FunctionTemplateParameterDifferentType) << (i + 1);
1501
1
          return true;
1502
1
        }
1503
1504
3
        bool HasFirstDefaultArgument =
1505
3
            FirstNTTPD->hasDefaultArgument() &&
1506
3
            
!FirstNTTPD->defaultArgumentWasInherited()2
;
1507
3
        bool HasSecondDefaultArgument =
1508
3
            SecondNTTPD->hasDefaultArgument() &&
1509
3
            
!SecondNTTPD->defaultArgumentWasInherited()2
;
1510
3
        if (HasFirstDefaultArgument != HasSecondDefaultArgument) {
1511
1
          DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument)
1512
1
              << (i + 1) << HasFirstDefaultArgument;
1513
1
          DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument)
1514
1
              << (i + 1) << HasSecondDefaultArgument;
1515
1
          return true;
1516
1
        }
1517
1518
2
        if (HasFirstDefaultArgument && 
HasSecondDefaultArgument1
) {
1519
1
          Expr *FirstDefaultArgument = FirstNTTPD->getDefaultArgument();
1520
1
          Expr *SecondDefaultArgument = SecondNTTPD->getDefaultArgument();
1521
1
          if (computeODRHash(FirstDefaultArgument) !=
1522
1
              computeODRHash(SecondDefaultArgument)) {
1523
1
            DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument)
1524
1
                << (i + 1) << FirstDefaultArgument;
1525
1
            DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument)
1526
1
                << (i + 1) << SecondDefaultArgument;
1527
1
            return true;
1528
1
          }
1529
1
        }
1530
1531
1
        if (FirstNTTPD->isParameterPack() != SecondNTTPD->isParameterPack()) {
1532
1
          DiagTemplateError(FunctionTemplatePackParameter)
1533
1
              << (i + 1) << FirstNTTPD->isParameterPack();
1534
1
          DiagTemplateNote(FunctionTemplatePackParameter)
1535
1
              << (i + 1) << SecondNTTPD->isParameterPack();
1536
1
          return true;
1537
1
        }
1538
1
      }
1539
4
    }
1540
0
    break;
1541
19
  }
1542
102
  }
1543
1544
0
  Diag(FirstDecl->getLocation(),
1545
0
       diag::err_module_odr_violation_mismatch_decl_unknown)
1546
0
      << FirstRecord << FirstModule.empty() << FirstModule << FirstDiffType
1547
0
      << FirstDecl->getSourceRange();
1548
0
  Diag(SecondDecl->getLocation(),
1549
0
       diag::note_module_odr_violation_mismatch_decl_unknown)
1550
0
      << SecondModule.empty() << SecondModule << FirstDiffType
1551
0
      << SecondDecl->getSourceRange();
1552
0
  return true;
1553
102
}
1554
1555
bool ODRDiagsEmitter::diagnoseMismatch(const RecordDecl *FirstRecord,
1556
9
                                       const RecordDecl *SecondRecord) const {
1557
9
  if (FirstRecord == SecondRecord)
1558
0
    return false;
1559
1560
9
  std::string FirstModule = getOwningModuleNameForDiagnostic(FirstRecord);
1561
9
  std::string SecondModule = getOwningModuleNameForDiagnostic(SecondRecord);
1562
1563
9
  auto PopulateHashes = [](DeclHashes &Hashes, const RecordDecl *Record,
1564
18
                           const DeclContext *DC) {
1565
21
    for (const Decl *D : Record->decls()) {
1566
21
      if (!ODRHash::isSubDeclToBeProcessed(D, DC))
1567
0
        continue;
1568
21
      Hashes.emplace_back(D, computeODRHash(D));
1569
21
    }
1570
18
  };
1571
1572
9
  DeclHashes FirstHashes;
1573
9
  DeclHashes SecondHashes;
1574
9
  const DeclContext *DC = FirstRecord;
1575
9
  PopulateHashes(FirstHashes, FirstRecord, DC);
1576
9
  PopulateHashes(SecondHashes, SecondRecord, DC);
1577
1578
9
  DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);
1579
9
  ODRMismatchDecl FirstDiffType = DR.FirstDiffType;
1580
9
  ODRMismatchDecl SecondDiffType = DR.SecondDiffType;
1581
9
  const Decl *FirstDecl = DR.FirstDecl;
1582
9
  const Decl *SecondDecl = DR.SecondDecl;
1583
1584
9
  if (FirstDiffType == Other || SecondDiffType == Other) {
1585
0
    diagnoseSubMismatchUnexpected(DR, FirstRecord, FirstModule, SecondRecord,
1586
0
                                  SecondModule);
1587
0
    return true;
1588
0
  }
1589
1590
9
  if (FirstDiffType != SecondDiffType) {
1591
1
    diagnoseSubMismatchDifferentDeclKinds(DR, FirstRecord, FirstModule,
1592
1
                                          SecondRecord, SecondModule);
1593
1
    return true;
1594
1
  }
1595
1596
8
  assert(FirstDiffType == SecondDiffType);
1597
8
  switch (FirstDiffType) {
1598
  // Already handled.
1599
0
  case EndOfClass:
1600
0
  case Other:
1601
  // C++ only, invalid in this context.
1602
0
  case PublicSpecifer:
1603
0
  case PrivateSpecifer:
1604
0
  case ProtectedSpecifer:
1605
0
  case StaticAssert:
1606
0
  case CXXMethod:
1607
0
  case TypeAlias:
1608
0
  case Friend:
1609
0
  case FunctionTemplate:
1610
  // Cannot be contained by RecordDecl, invalid in this context.
1611
0
  case ObjCMethod:
1612
0
  case ObjCIvar:
1613
0
  case ObjCProperty:
1614
0
    llvm_unreachable("Invalid diff type");
1615
1616
8
  case Field: {
1617
8
    if (diagnoseSubMismatchField(FirstRecord, FirstModule, SecondModule,
1618
8
                                 cast<FieldDecl>(FirstDecl),
1619
8
                                 cast<FieldDecl>(SecondDecl)))
1620
8
      return true;
1621
0
    break;
1622
8
  }
1623
0
  case TypeDef: {
1624
0
    if (diagnoseSubMismatchTypedef(FirstRecord, FirstModule, SecondModule,
1625
0
                                   cast<TypedefNameDecl>(FirstDecl),
1626
0
                                   cast<TypedefNameDecl>(SecondDecl),
1627
0
                                   /*IsTypeAlias=*/false))
1628
0
      return true;
1629
0
    break;
1630
0
  }
1631
0
  case Var: {
1632
0
    if (diagnoseSubMismatchVar(FirstRecord, FirstModule, SecondModule,
1633
0
                               cast<VarDecl>(FirstDecl),
1634
0
                               cast<VarDecl>(SecondDecl)))
1635
0
      return true;
1636
0
    break;
1637
0
  }
1638
8
  }
1639
1640
0
  Diag(FirstDecl->getLocation(),
1641
0
       diag::err_module_odr_violation_mismatch_decl_unknown)
1642
0
      << FirstRecord << FirstModule.empty() << FirstModule << FirstDiffType
1643
0
      << FirstDecl->getSourceRange();
1644
0
  Diag(SecondDecl->getLocation(),
1645
0
       diag::note_module_odr_violation_mismatch_decl_unknown)
1646
0
      << SecondModule.empty() << SecondModule << FirstDiffType
1647
0
      << SecondDecl->getSourceRange();
1648
0
  return true;
1649
8
}
1650
1651
bool ODRDiagsEmitter::diagnoseMismatch(
1652
    const FunctionDecl *FirstFunction,
1653
40
    const FunctionDecl *SecondFunction) const {
1654
40
  if (FirstFunction == SecondFunction)
1655
0
    return false;
1656
1657
  // Keep in sync with select options in err_module_odr_violation_function.
1658
40
  enum ODRFunctionDifference {
1659
40
    ReturnType,
1660
40
    ParameterName,
1661
40
    ParameterType,
1662
40
    ParameterSingleDefaultArgument,
1663
40
    ParameterDifferentDefaultArgument,
1664
40
    FunctionBody,
1665
40
  };
1666
1667
40
  std::string FirstModule = getOwningModuleNameForDiagnostic(FirstFunction);
1668
40
  std::string SecondModule = getOwningModuleNameForDiagnostic(SecondFunction);
1669
1670
40
  auto DiagError = [FirstFunction, &FirstModule,
1671
40
                    this](SourceLocation Loc, SourceRange Range,
1672
40
                          ODRFunctionDifference DiffType) {
1673
40
    return Diag(Loc, diag::err_module_odr_violation_function)
1674
40
           << FirstFunction << FirstModule.empty() << FirstModule << Range
1675
40
           << DiffType;
1676
40
  };
1677
40
  auto DiagNote = [&SecondModule, this](SourceLocation Loc, SourceRange Range,
1678
40
                                        ODRFunctionDifference DiffType) {
1679
40
    return Diag(Loc, diag::note_module_odr_violation_function)
1680
40
           << SecondModule << Range << DiffType;
1681
40
  };
1682
1683
40
  if (computeODRHash(FirstFunction->getReturnType()) !=
1684
40
      computeODRHash(SecondFunction->getReturnType())) {
1685
1
    DiagError(FirstFunction->getReturnTypeSourceRange().getBegin(),
1686
1
              FirstFunction->getReturnTypeSourceRange(), ReturnType)
1687
1
        << FirstFunction->getReturnType();
1688
1
    DiagNote(SecondFunction->getReturnTypeSourceRange().getBegin(),
1689
1
             SecondFunction->getReturnTypeSourceRange(), ReturnType)
1690
1
        << SecondFunction->getReturnType();
1691
1
    return true;
1692
1
  }
1693
1694
39
  assert(FirstFunction->param_size() == SecondFunction->param_size() &&
1695
39
         "Merged functions with different number of parameters");
1696
1697
39
  size_t ParamSize = FirstFunction->param_size();
1698
41
  for (unsigned I = 0; I < ParamSize; 
++I2
) {
1699
8
    const ParmVarDecl *FirstParam = FirstFunction->getParamDecl(I);
1700
8
    const ParmVarDecl *SecondParam = SecondFunction->getParamDecl(I);
1701
1702
8
    assert(Context.hasSameType(FirstParam->getType(), SecondParam->getType()) &&
1703
8
           "Merged function has different parameter types.");
1704
1705
8
    if (FirstParam->getDeclName() != SecondParam->getDeclName()) {
1706
2
      DiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),
1707
2
                ParameterName)
1708
2
          << I + 1 << FirstParam->getDeclName();
1709
2
      DiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(),
1710
2
               ParameterName)
1711
2
          << I + 1 << SecondParam->getDeclName();
1712
2
      return true;
1713
6
    };
1714
1715
6
    QualType FirstParamType = FirstParam->getType();
1716
6
    QualType SecondParamType = SecondParam->getType();
1717
6
    if (FirstParamType != SecondParamType &&
1718
6
        
computeODRHash(FirstParamType) != computeODRHash(SecondParamType)2
) {
1719
2
      if (const DecayedType *ParamDecayedType =
1720
2
              FirstParamType->getAs<DecayedType>()) {
1721
1
        DiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),
1722
1
                  ParameterType)
1723
1
            << (I + 1) << FirstParamType << true
1724
1
            << ParamDecayedType->getOriginalType();
1725
1
      } else {
1726
1
        DiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),
1727
1
                  ParameterType)
1728
1
            << (I + 1) << FirstParamType << false;
1729
1
      }
1730
1731
2
      if (const DecayedType *ParamDecayedType =
1732
2
              SecondParamType->getAs<DecayedType>()) {
1733
1
        DiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(),
1734
1
                 ParameterType)
1735
1
            << (I + 1) << SecondParamType << true
1736
1
            << ParamDecayedType->getOriginalType();
1737
1
      } else {
1738
1
        DiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(),
1739
1
                 ParameterType)
1740
1
            << (I + 1) << SecondParamType << false;
1741
1
      }
1742
2
      return true;
1743
2
    }
1744
1745
    // Note, these calls can trigger deserialization.
1746
4
    const Expr *FirstInit = FirstParam->getInit();
1747
4
    const Expr *SecondInit = SecondParam->getInit();
1748
4
    if ((FirstInit == nullptr) != (SecondInit == nullptr)) {
1749
1
      DiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),
1750
1
                ParameterSingleDefaultArgument)
1751
1
          << (I + 1) << (FirstInit == nullptr)
1752
1
          << (FirstInit ? FirstInit->getSourceRange() : 
SourceRange()0
);
1753
1
      DiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(),
1754
1
               ParameterSingleDefaultArgument)
1755
1
          << (I + 1) << (SecondInit == nullptr)
1756
1
          << (SecondInit ? 
SecondInit->getSourceRange()0
: SourceRange());
1757
1
      return true;
1758
1
    }
1759
1760
3
    if (FirstInit && 
SecondInit1
&&
1761
3
        
computeODRHash(FirstInit) != computeODRHash(SecondInit)1
) {
1762
1
      DiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),
1763
1
                ParameterDifferentDefaultArgument)
1764
1
          << (I + 1) << FirstInit->getSourceRange();
1765
1
      DiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(),
1766
1
               ParameterDifferentDefaultArgument)
1767
1
          << (I + 1) << SecondInit->getSourceRange();
1768
1
      return true;
1769
1
    }
1770
1771
2
    assert(computeODRHash(FirstParam) == computeODRHash(SecondParam) &&
1772
2
           "Undiagnosed parameter difference.");
1773
2
  }
1774
1775
  // If no error has been generated before now, assume the problem is in
1776
  // the body and generate a message.
1777
33
  DiagError(FirstFunction->getLocation(), FirstFunction->getSourceRange(),
1778
33
            FunctionBody);
1779
33
  DiagNote(SecondFunction->getLocation(), SecondFunction->getSourceRange(),
1780
33
           FunctionBody);
1781
33
  return true;
1782
39
}
1783
1784
bool ODRDiagsEmitter::diagnoseMismatch(const EnumDecl *FirstEnum,
1785
13
                                       const EnumDecl *SecondEnum) const {
1786
13
  if (FirstEnum == SecondEnum)
1787
0
    return false;
1788
1789
  // Keep in sync with select options in err_module_odr_violation_enum.
1790
13
  enum ODREnumDifference {
1791
13
    SingleScopedEnum,
1792
13
    EnumTagKeywordMismatch,
1793
13
    SingleSpecifiedType,
1794
13
    DifferentSpecifiedTypes,
1795
13
    DifferentNumberEnumConstants,
1796
13
    EnumConstantName,
1797
13
    EnumConstantSingleInitializer,
1798
13
    EnumConstantDifferentInitializer,
1799
13
  };
1800
1801
13
  std::string FirstModule = getOwningModuleNameForDiagnostic(FirstEnum);
1802
13
  std::string SecondModule = getOwningModuleNameForDiagnostic(SecondEnum);
1803
1804
13
  auto DiagError = [FirstEnum, &FirstModule, this](const auto *DiagAnchor,
1805
13
                                                   ODREnumDifference DiffType) {
1806
13
    return Diag(DiagAnchor->getLocation(), diag::err_module_odr_violation_enum)
1807
13
           << FirstEnum << FirstModule.empty() << FirstModule
1808
13
           << DiagAnchor->getSourceRange() << DiffType;
1809
13
  };
ODRDiagsEmitter.cpp:auto clang::ODRDiagsEmitter::diagnoseMismatch(clang::EnumDecl const*, clang::EnumDecl const*) const::$_0::operator()<clang::EnumDecl>(clang::EnumDecl const*, clang::ODRDiagsEmitter::diagnoseMismatch(clang::EnumDecl const*, clang::EnumDecl const*) const::ODREnumDifference) const
Line
Count
Source
1805
9
                                                   ODREnumDifference DiffType) {
1806
9
    return Diag(DiagAnchor->getLocation(), diag::err_module_odr_violation_enum)
1807
9
           << FirstEnum << FirstModule.empty() << FirstModule
1808
9
           << DiagAnchor->getSourceRange() << DiffType;
1809
9
  };
ODRDiagsEmitter.cpp:auto clang::ODRDiagsEmitter::diagnoseMismatch(clang::EnumDecl const*, clang::EnumDecl const*) const::$_0::operator()<clang::EnumConstantDecl>(clang::EnumConstantDecl const*, clang::ODRDiagsEmitter::diagnoseMismatch(clang::EnumDecl const*, clang::EnumDecl const*) const::ODREnumDifference) const
Line
Count
Source
1805
4
                                                   ODREnumDifference DiffType) {
1806
4
    return Diag(DiagAnchor->getLocation(), diag::err_module_odr_violation_enum)
1807
4
           << FirstEnum << FirstModule.empty() << FirstModule
1808
4
           << DiagAnchor->getSourceRange() << DiffType;
1809
4
  };
1810
13
  auto DiagNote = [&SecondModule, this](const auto *DiagAnchor,
1811
13
                                        ODREnumDifference DiffType) {
1812
13
    return Diag(DiagAnchor->getLocation(), diag::note_module_odr_violation_enum)
1813
13
           << SecondModule << DiagAnchor->getSourceRange() << DiffType;
1814
13
  };
ODRDiagsEmitter.cpp:auto clang::ODRDiagsEmitter::diagnoseMismatch(clang::EnumDecl const*, clang::EnumDecl const*) const::$_1::operator()<clang::EnumDecl>(clang::EnumDecl const*, clang::ODRDiagsEmitter::diagnoseMismatch(clang::EnumDecl const*, clang::EnumDecl const*) const::ODREnumDifference) const
Line
Count
Source
1811
9
                                        ODREnumDifference DiffType) {
1812
9
    return Diag(DiagAnchor->getLocation(), diag::note_module_odr_violation_enum)
1813
9
           << SecondModule << DiagAnchor->getSourceRange() << DiffType;
1814
9
  };
ODRDiagsEmitter.cpp:auto clang::ODRDiagsEmitter::diagnoseMismatch(clang::EnumDecl const*, clang::EnumDecl const*) const::$_1::operator()<clang::EnumConstantDecl>(clang::EnumConstantDecl const*, clang::ODRDiagsEmitter::diagnoseMismatch(clang::EnumDecl const*, clang::EnumDecl const*) const::ODREnumDifference) const
Line
Count
Source
1811
4
                                        ODREnumDifference DiffType) {
1812
4
    return Diag(DiagAnchor->getLocation(), diag::note_module_odr_violation_enum)
1813
4
           << SecondModule << DiagAnchor->getSourceRange() << DiffType;
1814
4
  };
1815
1816
13
  if (FirstEnum->isScoped() != SecondEnum->isScoped()) {
1817
2
    DiagError(FirstEnum, SingleScopedEnum) << FirstEnum->isScoped();
1818
2
    DiagNote(SecondEnum, SingleScopedEnum) << SecondEnum->isScoped();
1819
2
    return true;
1820
2
  }
1821
1822
11
  if (FirstEnum->isScoped() && 
SecondEnum->isScoped()4
) {
1823
4
    if (FirstEnum->isScopedUsingClassTag() !=
1824
4
        SecondEnum->isScopedUsingClassTag()) {
1825
2
      DiagError(FirstEnum, EnumTagKeywordMismatch)
1826
2
          << FirstEnum->isScopedUsingClassTag();
1827
2
      DiagNote(SecondEnum, EnumTagKeywordMismatch)
1828
2
          << SecondEnum->isScopedUsingClassTag();
1829
2
      return true;
1830
2
    }
1831
4
  }
1832
1833
9
  QualType FirstUnderlyingType =
1834
9
      FirstEnum->getIntegerTypeSourceInfo()
1835
9
          ? 
FirstEnum->getIntegerTypeSourceInfo()->getType()2
1836
9
          : 
QualType()7
;
1837
9
  QualType SecondUnderlyingType =
1838
9
      SecondEnum->getIntegerTypeSourceInfo()
1839
9
          ? 
SecondEnum->getIntegerTypeSourceInfo()->getType()2
1840
9
          : 
QualType()7
;
1841
9
  if (FirstUnderlyingType.isNull() != SecondUnderlyingType.isNull()) {
1842
2
    DiagError(FirstEnum, SingleSpecifiedType) << !FirstUnderlyingType.isNull();
1843
2
    DiagNote(SecondEnum, SingleSpecifiedType) << !SecondUnderlyingType.isNull();
1844
2
    return true;
1845
2
  }
1846
1847
7
  if (!FirstUnderlyingType.isNull() && 
!SecondUnderlyingType.isNull()1
) {
1848
1
    if (computeODRHash(FirstUnderlyingType) !=
1849
1
        computeODRHash(SecondUnderlyingType)) {
1850
1
      DiagError(FirstEnum, DifferentSpecifiedTypes) << FirstUnderlyingType;
1851
1
      DiagNote(SecondEnum, DifferentSpecifiedTypes) << SecondUnderlyingType;
1852
1
      return true;
1853
1
    }
1854
1
  }
1855
1856
  // Compare enum constants.
1857
6
  using DeclHashes =
1858
6
      llvm::SmallVector<std::pair<const EnumConstantDecl *, unsigned>, 4>;
1859
12
  auto PopulateHashes = [FirstEnum](DeclHashes &Hashes, const EnumDecl *Enum) {
1860
16
    for (const Decl *D : Enum->decls()) {
1861
      // Due to decl merging, the first EnumDecl is the parent of
1862
      // Decls in both records.
1863
16
      if (!ODRHash::isSubDeclToBeProcessed(D, FirstEnum))
1864
0
        continue;
1865
16
      assert(isa<EnumConstantDecl>(D) && "Unexpected Decl kind");
1866
16
      Hashes.emplace_back(cast<EnumConstantDecl>(D), computeODRHash(D));
1867
16
    }
1868
12
  };
1869
6
  DeclHashes FirstHashes;
1870
6
  PopulateHashes(FirstHashes, FirstEnum);
1871
6
  DeclHashes SecondHashes;
1872
6
  PopulateHashes(SecondHashes, SecondEnum);
1873
1874
6
  if (FirstHashes.size() != SecondHashes.size()) {
1875
2
    DiagError(FirstEnum, DifferentNumberEnumConstants)
1876
2
        << (int)FirstHashes.size();
1877
2
    DiagNote(SecondEnum, DifferentNumberEnumConstants)
1878
2
        << (int)SecondHashes.size();
1879
2
    return true;
1880
2
  }
1881
1882
5
  
for (unsigned I = 0, N = FirstHashes.size(); 4
I < N;
++I1
) {
1883
5
    if (FirstHashes[I].second == SecondHashes[I].second)
1884
1
      continue;
1885
4
    const EnumConstantDecl *FirstConstant = FirstHashes[I].first;
1886
4
    const EnumConstantDecl *SecondConstant = SecondHashes[I].first;
1887
1888
4
    if (FirstConstant->getDeclName() != SecondConstant->getDeclName()) {
1889
1
      DiagError(FirstConstant, EnumConstantName) << I + 1 << FirstConstant;
1890
1
      DiagNote(SecondConstant, EnumConstantName) << I + 1 << SecondConstant;
1891
1
      return true;
1892
1
    }
1893
1894
3
    const Expr *FirstInit = FirstConstant->getInitExpr();
1895
3
    const Expr *SecondInit = SecondConstant->getInitExpr();
1896
3
    if (!FirstInit && 
!SecondInit1
)
1897
0
      continue;
1898
1899
3
    if (!FirstInit || 
!SecondInit2
) {
1900
2
      DiagError(FirstConstant, EnumConstantSingleInitializer)
1901
2
          << I + 1 << FirstConstant << (FirstInit != nullptr);
1902
2
      DiagNote(SecondConstant, EnumConstantSingleInitializer)
1903
2
          << I + 1 << SecondConstant << (SecondInit != nullptr);
1904
2
      return true;
1905
2
    }
1906
1907
1
    if (computeODRHash(FirstInit) != computeODRHash(SecondInit)) {
1908
1
      DiagError(FirstConstant, EnumConstantDifferentInitializer)
1909
1
          << I + 1 << FirstConstant;
1910
1
      DiagNote(SecondConstant, EnumConstantDifferentInitializer)
1911
1
          << I + 1 << SecondConstant;
1912
1
      return true;
1913
1
    }
1914
1
  }
1915
0
  return false;
1916
4
}
1917
1918
bool ODRDiagsEmitter::diagnoseMismatch(
1919
    const ObjCInterfaceDecl *FirstID, const ObjCInterfaceDecl *SecondID,
1920
60
    const struct ObjCInterfaceDecl::DefinitionData *SecondDD) const {
1921
  // Multiple different declarations got merged together; tell the user
1922
  // where they came from.
1923
60
  if (FirstID == SecondID)
1924
0
    return false;
1925
1926
60
  std::string FirstModule = getOwningModuleNameForDiagnostic(FirstID);
1927
60
  std::string SecondModule = getOwningModuleNameForDiagnostic(SecondID);
1928
1929
  // Keep in sync with err_module_odr_violation_objc_interface.
1930
60
  enum ODRInterfaceDifference {
1931
60
    SuperClassType,
1932
60
    IVarAccess,
1933
60
  };
1934
1935
60
  auto DiagError = [FirstID, &FirstModule,
1936
60
                    this](SourceLocation Loc, SourceRange Range,
1937
60
                          ODRInterfaceDifference DiffType) {
1938
11
    return Diag(Loc, diag::err_module_odr_violation_objc_interface)
1939
11
           << FirstID << FirstModule.empty() << FirstModule << Range
1940
11
           << DiffType;
1941
11
  };
1942
60
  auto DiagNote = [&SecondModule, this](SourceLocation Loc, SourceRange Range,
1943
60
                                        ODRInterfaceDifference DiffType) {
1944
11
    return Diag(Loc, diag::note_module_odr_violation_objc_interface)
1945
11
           << SecondModule.empty() << SecondModule << Range << DiffType;
1946
11
  };
1947
1948
60
  const struct ObjCInterfaceDecl::DefinitionData *FirstDD = &FirstID->data();
1949
60
  assert(FirstDD && SecondDD && "Definitions without DefinitionData");
1950
60
  if (FirstDD != SecondDD) {
1951
    // Check for matching super class.
1952
60
    auto GetSuperClassSourceRange = [](const TypeSourceInfo *SuperInfo,
1953
60
                                       const ObjCInterfaceDecl *ID) {
1954
14
      if (!SuperInfo)
1955
5
        return ID->getSourceRange();
1956
9
      TypeLoc Loc = SuperInfo->getTypeLoc();
1957
9
      return SourceRange(Loc.getBeginLoc(), Loc.getEndLoc());
1958
14
    };
1959
1960
60
    ObjCInterfaceDecl *FirstSuperClass = FirstID->getSuperClass();
1961
60
    ObjCInterfaceDecl *SecondSuperClass = nullptr;
1962
60
    const TypeSourceInfo *FirstSuperInfo = FirstID->getSuperClassTInfo();
1963
60
    const TypeSourceInfo *SecondSuperInfo = SecondDD->SuperClassTInfo;
1964
60
    if (SecondSuperInfo)
1965
58
      SecondSuperClass =
1966
58
          SecondSuperInfo->getType()->castAs<ObjCObjectType>()->getInterface();
1967
1968
60
    if ((FirstSuperClass && 
SecondSuperClass57
&&
1969
60
         
FirstSuperClass->getODRHash() != SecondSuperClass->getODRHash()55
) ||
1970
60
        
(58
FirstSuperClass58
&&
!SecondSuperClass55
) ||
1971
60
        
(56
!FirstSuperClass56
&&
SecondSuperClass3
)) {
1972
7
      QualType FirstType;
1973
7
      if (FirstSuperInfo)
1974
4
        FirstType = FirstSuperInfo->getType();
1975
1976
7
      DiagError(FirstID->getLocation(),
1977
7
                GetSuperClassSourceRange(FirstSuperInfo, FirstID),
1978
7
                SuperClassType)
1979
7
          << (bool)FirstSuperInfo << FirstType;
1980
1981
7
      QualType SecondType;
1982
7
      if (SecondSuperInfo)
1983
5
        SecondType = SecondSuperInfo->getType();
1984
1985
7
      DiagNote(SecondID->getLocation(),
1986
7
               GetSuperClassSourceRange(SecondSuperInfo, SecondID),
1987
7
               SuperClassType)
1988
7
          << (bool)SecondSuperInfo << SecondType;
1989
7
      return true;
1990
7
    }
1991
1992
    // Check both interfaces reference the same protocols.
1993
53
    auto &FirstProtos = FirstID->getReferencedProtocols();
1994
53
    auto &SecondProtos = SecondDD->ReferencedProtocols;
1995
53
    if (diagnoseSubMismatchProtocols(FirstProtos, FirstID, FirstModule,
1996
53
                                     SecondProtos, SecondID, SecondModule))
1997
8
      return true;
1998
53
  }
1999
2000
45
  auto PopulateHashes = [](DeclHashes &Hashes, const ObjCInterfaceDecl *ID,
2001
90
                           const DeclContext *DC) {
2002
151
    for (auto *D : ID->decls()) {
2003
151
      if (!ODRHash::isSubDeclToBeProcessed(D, DC))
2004
60
        continue;
2005
91
      Hashes.emplace_back(D, computeODRHash(D));
2006
91
    }
2007
90
  };
2008
2009
45
  DeclHashes FirstHashes;
2010
45
  DeclHashes SecondHashes;
2011
  // Use definition as DeclContext because definitions are merged when
2012
  // DeclContexts are merged and separate when DeclContexts are separate.
2013
45
  PopulateHashes(FirstHashes, FirstID, FirstID->getDefinition());
2014
45
  PopulateHashes(SecondHashes, SecondID, SecondID->getDefinition());
2015
2016
45
  DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);
2017
45
  ODRMismatchDecl FirstDiffType = DR.FirstDiffType;
2018
45
  ODRMismatchDecl SecondDiffType = DR.SecondDiffType;
2019
45
  const Decl *FirstDecl = DR.FirstDecl;
2020
45
  const Decl *SecondDecl = DR.SecondDecl;
2021
2022
45
  if (FirstDiffType == Other || SecondDiffType == Other) {
2023
0
    diagnoseSubMismatchUnexpected(DR, FirstID, FirstModule, SecondID,
2024
0
                                  SecondModule);
2025
0
    return true;
2026
0
  }
2027
2028
45
  if (FirstDiffType != SecondDiffType) {
2029
11
    diagnoseSubMismatchDifferentDeclKinds(DR, FirstID, FirstModule, SecondID,
2030
11
                                          SecondModule);
2031
11
    return true;
2032
11
  }
2033
2034
34
  assert(FirstDiffType == SecondDiffType);
2035
34
  switch (FirstDiffType) {
2036
  // Already handled.
2037
0
  case EndOfClass:
2038
0
  case Other:
2039
  // Cannot be contained by ObjCInterfaceDecl, invalid in this context.
2040
0
  case Field:
2041
0
  case TypeDef:
2042
0
  case Var:
2043
  // C++ only, invalid in this context.
2044
0
  case PublicSpecifer:
2045
0
  case PrivateSpecifer:
2046
0
  case ProtectedSpecifer:
2047
0
  case StaticAssert:
2048
0
  case CXXMethod:
2049
0
  case TypeAlias:
2050
0
  case Friend:
2051
0
  case FunctionTemplate:
2052
0
    llvm_unreachable("Invalid diff type");
2053
2054
14
  case ObjCMethod: {
2055
14
    if (diagnoseSubMismatchObjCMethod(FirstID, FirstModule, SecondModule,
2056
14
                                      cast<ObjCMethodDecl>(FirstDecl),
2057
14
                                      cast<ObjCMethodDecl>(SecondDecl)))
2058
14
      return true;
2059
0
    break;
2060
14
  }
2061
8
  case ObjCIvar: {
2062
8
    if (diagnoseSubMismatchField(FirstID, FirstModule, SecondModule,
2063
8
                                 cast<FieldDecl>(FirstDecl),
2064
8
                                 cast<FieldDecl>(SecondDecl)))
2065
4
      return true;
2066
2067
    // Check if the access match.
2068
4
    const ObjCIvarDecl *FirstIvar = cast<ObjCIvarDecl>(FirstDecl);
2069
4
    const ObjCIvarDecl *SecondIvar = cast<ObjCIvarDecl>(SecondDecl);
2070
4
    if (FirstIvar->getCanonicalAccessControl() !=
2071
4
        SecondIvar->getCanonicalAccessControl()) {
2072
4
      DiagError(FirstIvar->getLocation(), FirstIvar->getSourceRange(),
2073
4
                IVarAccess)
2074
4
          << FirstIvar->getName()
2075
4
          << (int)FirstIvar->getCanonicalAccessControl();
2076
4
      DiagNote(SecondIvar->getLocation(), SecondIvar->getSourceRange(),
2077
4
               IVarAccess)
2078
4
          << SecondIvar->getName()
2079
4
          << (int)SecondIvar->getCanonicalAccessControl();
2080
4
      return true;
2081
4
    }
2082
0
    break;
2083
4
  }
2084
12
  case ObjCProperty: {
2085
12
    if (diagnoseSubMismatchObjCProperty(FirstID, FirstModule, SecondModule,
2086
12
                                        cast<ObjCPropertyDecl>(FirstDecl),
2087
12
                                        cast<ObjCPropertyDecl>(SecondDecl)))
2088
12
      return true;
2089
0
    break;
2090
12
  }
2091
34
  }
2092
2093
0
  Diag(FirstDecl->getLocation(),
2094
0
       diag::err_module_odr_violation_mismatch_decl_unknown)
2095
0
      << FirstID << FirstModule.empty() << FirstModule << FirstDiffType
2096
0
      << FirstDecl->getSourceRange();
2097
0
  Diag(SecondDecl->getLocation(),
2098
0
       diag::note_module_odr_violation_mismatch_decl_unknown)
2099
0
      << SecondModule << FirstDiffType << SecondDecl->getSourceRange();
2100
0
  return true;
2101
34
}
2102
2103
bool ODRDiagsEmitter::diagnoseMismatch(
2104
    const ObjCProtocolDecl *FirstProtocol,
2105
    const ObjCProtocolDecl *SecondProtocol,
2106
44
    const struct ObjCProtocolDecl::DefinitionData *SecondDD) const {
2107
44
  if (FirstProtocol == SecondProtocol)
2108
0
    return false;
2109
2110
44
  std::string FirstModule = getOwningModuleNameForDiagnostic(FirstProtocol);
2111
44
  std::string SecondModule = getOwningModuleNameForDiagnostic(SecondProtocol);
2112
2113
44
  const ObjCProtocolDecl::DefinitionData *FirstDD = &FirstProtocol->data();
2114
44
  assert(FirstDD && SecondDD && "Definitions without DefinitionData");
2115
  // Diagnostics from ObjCProtocol DefinitionData are emitted here.
2116
44
  if (FirstDD != SecondDD) {
2117
    // Check both protocols reference the same protocols.
2118
44
    const ObjCProtocolList &FirstProtocols =
2119
44
        FirstProtocol->getReferencedProtocols();
2120
44
    const ObjCProtocolList &SecondProtocols = SecondDD->ReferencedProtocols;
2121
44
    if (diagnoseSubMismatchProtocols(FirstProtocols, FirstProtocol, FirstModule,
2122
44
                                     SecondProtocols, SecondProtocol,
2123
44
                                     SecondModule))
2124
8
      return true;
2125
44
  }
2126
2127
36
  auto PopulateHashes = [](DeclHashes &Hashes, const ObjCProtocolDecl *ID,
2128
72
                           const DeclContext *DC) {
2129
134
    for (const Decl *D : ID->decls()) {
2130
134
      if (!ODRHash::isSubDeclToBeProcessed(D, DC))
2131
62
        continue;
2132
72
      Hashes.emplace_back(D, computeODRHash(D));
2133
72
    }
2134
72
  };
2135
2136
36
  DeclHashes FirstHashes;
2137
36
  DeclHashes SecondHashes;
2138
  // Use definition as DeclContext because definitions are merged when
2139
  // DeclContexts are merged and separate when DeclContexts are separate.
2140
36
  PopulateHashes(FirstHashes, FirstProtocol, FirstProtocol->getDefinition());
2141
36
  PopulateHashes(SecondHashes, SecondProtocol, SecondProtocol->getDefinition());
2142
2143
36
  DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);
2144
36
  ODRMismatchDecl FirstDiffType = DR.FirstDiffType;
2145
36
  ODRMismatchDecl SecondDiffType = DR.SecondDiffType;
2146
36
  const Decl *FirstDecl = DR.FirstDecl;
2147
36
  const Decl *SecondDecl = DR.SecondDecl;
2148
2149
36
  if (FirstDiffType == Other || SecondDiffType == Other) {
2150
0
    diagnoseSubMismatchUnexpected(DR, FirstProtocol, FirstModule,
2151
0
                                  SecondProtocol, SecondModule);
2152
0
    return true;
2153
0
  }
2154
2155
36
  if (FirstDiffType != SecondDiffType) {
2156
8
    diagnoseSubMismatchDifferentDeclKinds(DR, FirstProtocol, FirstModule,
2157
8
                                          SecondProtocol, SecondModule);
2158
8
    return true;
2159
8
  }
2160
2161
28
  assert(FirstDiffType == SecondDiffType);
2162
28
  switch (FirstDiffType) {
2163
  // Already handled.
2164
0
  case EndOfClass:
2165
0
  case Other:
2166
  // Cannot be contained by ObjCProtocolDecl, invalid in this context.
2167
0
  case Field:
2168
0
  case TypeDef:
2169
0
  case Var:
2170
0
  case ObjCIvar:
2171
  // C++ only, invalid in this context.
2172
0
  case PublicSpecifer:
2173
0
  case PrivateSpecifer:
2174
0
  case ProtectedSpecifer:
2175
0
  case StaticAssert:
2176
0
  case CXXMethod:
2177
0
  case TypeAlias:
2178
0
  case Friend:
2179
0
  case FunctionTemplate:
2180
0
    llvm_unreachable("Invalid diff type");
2181
16
  case ObjCMethod: {
2182
16
    if (diagnoseSubMismatchObjCMethod(FirstProtocol, FirstModule, SecondModule,
2183
16
                                      cast<ObjCMethodDecl>(FirstDecl),
2184
16
                                      cast<ObjCMethodDecl>(SecondDecl)))
2185
16
      return true;
2186
0
    break;
2187
16
  }
2188
12
  case ObjCProperty: {
2189
12
    if (diagnoseSubMismatchObjCProperty(FirstProtocol, FirstModule,
2190
12
                                        SecondModule,
2191
12
                                        cast<ObjCPropertyDecl>(FirstDecl),
2192
12
                                        cast<ObjCPropertyDecl>(SecondDecl)))
2193
12
      return true;
2194
0
    break;
2195
12
  }
2196
28
  }
2197
2198
0
  Diag(FirstDecl->getLocation(),
2199
0
       diag::err_module_odr_violation_mismatch_decl_unknown)
2200
0
      << FirstProtocol << FirstModule.empty() << FirstModule << FirstDiffType
2201
0
      << FirstDecl->getSourceRange();
2202
0
  Diag(SecondDecl->getLocation(),
2203
0
       diag::note_module_odr_violation_mismatch_decl_unknown)
2204
0
      << SecondModule.empty() << SecondModule << FirstDiffType
2205
0
      << SecondDecl->getSourceRange();
2206
0
  return true;
2207
28
}