Coverage Report

Created: 2024-01-17 10:31

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