clang  16.0.0git
ASTStructuralEquivalence.cpp
Go to the documentation of this file.
1 //===- ASTStructuralEquivalence.cpp ---------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implement StructuralEquivalenceContext class and helper functions
10 // for layout matching.
11 //
12 // The structural equivalence check could have been implemented as a parallel
13 // BFS on a pair of graphs. That must have been the original approach at the
14 // beginning.
15 // Let's consider this simple BFS algorithm from the `s` source:
16 // ```
17 // void bfs(Graph G, int s)
18 // {
19 // Queue<Integer> queue = new Queue<Integer>();
20 // marked[s] = true; // Mark the source
21 // queue.enqueue(s); // and put it on the queue.
22 // while (!q.isEmpty()) {
23 // int v = queue.dequeue(); // Remove next vertex from the queue.
24 // for (int w : G.adj(v))
25 // if (!marked[w]) // For every unmarked adjacent vertex,
26 // {
27 // marked[w] = true;
28 // queue.enqueue(w);
29 // }
30 // }
31 // }
32 // ```
33 // Indeed, it has it's queue, which holds pairs of nodes, one from each graph,
34 // this is the `DeclsToCheck` member. `VisitedDecls` plays the role of the
35 // marking (`marked`) functionality above, we use it to check whether we've
36 // already seen a pair of nodes.
37 //
38 // We put in the elements into the queue only in the toplevel decl check
39 // function:
40 // ```
41 // static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
42 // Decl *D1, Decl *D2);
43 // ```
44 // The `while` loop where we iterate over the children is implemented in
45 // `Finish()`. And `Finish` is called only from the two **member** functions
46 // which check the equivalency of two Decls or two Types. ASTImporter (and
47 // other clients) call only these functions.
48 //
49 // The `static` implementation functions are called from `Finish`, these push
50 // the children nodes to the queue via `static bool
51 // IsStructurallyEquivalent(StructuralEquivalenceContext &Context, Decl *D1,
52 // Decl *D2)`. So far so good, this is almost like the BFS. However, if we
53 // let a static implementation function to call `Finish` via another **member**
54 // function that means we end up with two nested while loops each of them
55 // working on the same queue. This is wrong and nobody can reason about it's
56 // doing. Thus, static implementation functions must not call the **member**
57 // functions.
58 //
59 //===----------------------------------------------------------------------===//
60 
62 #include "clang/AST/ASTContext.h"
64 #include "clang/AST/Decl.h"
65 #include "clang/AST/DeclBase.h"
66 #include "clang/AST/DeclCXX.h"
67 #include "clang/AST/DeclFriend.h"
68 #include "clang/AST/DeclObjC.h"
69 #include "clang/AST/DeclOpenMP.h"
70 #include "clang/AST/DeclTemplate.h"
71 #include "clang/AST/ExprCXX.h"
72 #include "clang/AST/ExprConcepts.h"
73 #include "clang/AST/ExprObjC.h"
74 #include "clang/AST/ExprOpenMP.h"
76 #include "clang/AST/StmtObjC.h"
77 #include "clang/AST/StmtOpenMP.h"
78 #include "clang/AST/TemplateBase.h"
79 #include "clang/AST/TemplateName.h"
80 #include "clang/AST/Type.h"
83 #include "clang/Basic/LLVM.h"
85 #include "llvm/ADT/APInt.h"
86 #include "llvm/ADT/APSInt.h"
87 #include "llvm/ADT/None.h"
88 #include "llvm/ADT/Optional.h"
89 #include "llvm/ADT/StringExtras.h"
90 #include "llvm/Support/Casting.h"
91 #include "llvm/Support/Compiler.h"
92 #include "llvm/Support/ErrorHandling.h"
93 #include <cassert>
94 #include <utility>
95 
96 using namespace clang;
97 
99  QualType T1, QualType T2);
101  Decl *D1, Decl *D2);
103  const TemplateArgument &Arg1,
104  const TemplateArgument &Arg2);
106  NestedNameSpecifier *NNS1,
107  NestedNameSpecifier *NNS2);
108 static bool IsStructurallyEquivalent(const IdentifierInfo *Name1,
109  const IdentifierInfo *Name2);
110 
112  const DeclarationName Name1,
113  const DeclarationName Name2) {
114  if (Name1.getNameKind() != Name2.getNameKind())
115  return false;
116 
117  switch (Name1.getNameKind()) {
118 
121  Name2.getAsIdentifierInfo());
122 
126  return IsStructurallyEquivalent(Context, Name1.getCXXNameType(),
127  Name2.getCXXNameType());
128 
131  Context, Name1.getCXXDeductionGuideTemplate()->getDeclName(),
133  return false;
134  return IsStructurallyEquivalent(Context,
137  }
138 
140  return Name1.getCXXOverloadedOperator() == Name2.getCXXOverloadedOperator();
141 
144  Name2.getCXXLiteralIdentifier());
145 
147  return true; // FIXME When do we consider two using directives equal?
148 
152  return true; // FIXME
153  }
154 
155  llvm_unreachable("Unhandled kind of DeclarationName");
156  return true;
157 }
158 
159 namespace {
160 /// Encapsulates Stmt comparison logic.
161 class StmtComparer {
163 
164  // IsStmtEquivalent overloads. Each overload compares a specific statement
165  // and only has to compare the data that is specific to the specific statement
166  // class. Should only be called from TraverseStmt.
167 
168  bool IsStmtEquivalent(const AddrLabelExpr *E1, const AddrLabelExpr *E2) {
169  return IsStructurallyEquivalent(Context, E1->getLabel(), E2->getLabel());
170  }
171 
172  bool IsStmtEquivalent(const AtomicExpr *E1, const AtomicExpr *E2) {
173  return E1->getOp() == E2->getOp();
174  }
175 
176  bool IsStmtEquivalent(const BinaryOperator *E1, const BinaryOperator *E2) {
177  return E1->getOpcode() == E2->getOpcode();
178  }
179 
180  bool IsStmtEquivalent(const CallExpr *E1, const CallExpr *E2) {
181  // FIXME: IsStructurallyEquivalent requires non-const Decls.
182  Decl *Callee1 = const_cast<Decl *>(E1->getCalleeDecl());
183  Decl *Callee2 = const_cast<Decl *>(E2->getCalleeDecl());
184 
185  // Compare whether both calls know their callee.
186  if (static_cast<bool>(Callee1) != static_cast<bool>(Callee2))
187  return false;
188 
189  // Both calls have no callee, so nothing to do.
190  if (!static_cast<bool>(Callee1))
191  return true;
192 
193  assert(Callee2);
194  return IsStructurallyEquivalent(Context, Callee1, Callee2);
195  }
196 
197  bool IsStmtEquivalent(const CharacterLiteral *E1,
198  const CharacterLiteral *E2) {
199  return E1->getValue() == E2->getValue() && E1->getKind() == E2->getKind();
200  }
201 
202  bool IsStmtEquivalent(const ChooseExpr *E1, const ChooseExpr *E2) {
203  return true; // Semantics only depend on children.
204  }
205 
206  bool IsStmtEquivalent(const CompoundStmt *E1, const CompoundStmt *E2) {
207  // Number of children is actually checked by the generic children comparison
208  // code, but a CompoundStmt is one of the few statements where the number of
209  // children frequently differs and the number of statements is also always
210  // precomputed. Directly comparing the number of children here is thus
211  // just an optimization.
212  return E1->size() == E2->size();
213  }
214 
215  bool IsStmtEquivalent(const DependentScopeDeclRefExpr *DE1,
216  const DependentScopeDeclRefExpr *DE2) {
217  if (!IsStructurallyEquivalent(Context, DE1->getDeclName(),
218  DE2->getDeclName()))
219  return false;
220  return IsStructurallyEquivalent(Context, DE1->getQualifier(),
221  DE2->getQualifier());
222  }
223 
224  bool IsStmtEquivalent(const Expr *E1, const Expr *E2) {
225  return IsStructurallyEquivalent(Context, E1->getType(), E2->getType());
226  }
227 
228  bool IsStmtEquivalent(const ExpressionTraitExpr *E1,
229  const ExpressionTraitExpr *E2) {
230  return E1->getTrait() == E2->getTrait() && E1->getValue() == E2->getValue();
231  }
232 
233  bool IsStmtEquivalent(const FloatingLiteral *E1, const FloatingLiteral *E2) {
234  return E1->isExact() == E2->isExact() && E1->getValue() == E2->getValue();
235  }
236 
237  bool IsStmtEquivalent(const GenericSelectionExpr *E1,
238  const GenericSelectionExpr *E2) {
239  for (auto Pair : zip_longest(E1->getAssocTypeSourceInfos(),
240  E2->getAssocTypeSourceInfos())) {
241  Optional<TypeSourceInfo *> Child1 = std::get<0>(Pair);
242  Optional<TypeSourceInfo *> Child2 = std::get<1>(Pair);
243  // Skip this case if there are a different number of associated types.
244  if (!Child1 || !Child2)
245  return false;
246 
247  if (!IsStructurallyEquivalent(Context, (*Child1)->getType(),
248  (*Child2)->getType()))
249  return false;
250  }
251 
252  return true;
253  }
254 
255  bool IsStmtEquivalent(const ImplicitCastExpr *CastE1,
256  const ImplicitCastExpr *CastE2) {
257  return IsStructurallyEquivalent(Context, CastE1->getType(),
258  CastE2->getType());
259  }
260 
261  bool IsStmtEquivalent(const IntegerLiteral *E1, const IntegerLiteral *E2) {
262  return E1->getValue() == E2->getValue();
263  }
264 
265  bool IsStmtEquivalent(const MemberExpr *E1, const MemberExpr *E2) {
266  return IsStructurallyEquivalent(Context, E1->getFoundDecl(),
267  E2->getFoundDecl());
268  }
269 
270  bool IsStmtEquivalent(const ObjCStringLiteral *E1,
271  const ObjCStringLiteral *E2) {
272  // Just wraps a StringLiteral child.
273  return true;
274  }
275 
276  bool IsStmtEquivalent(const Stmt *S1, const Stmt *S2) { return true; }
277 
278  bool IsStmtEquivalent(const SourceLocExpr *E1, const SourceLocExpr *E2) {
279  return E1->getIdentKind() == E2->getIdentKind();
280  }
281 
282  bool IsStmtEquivalent(const StmtExpr *E1, const StmtExpr *E2) {
283  return E1->getTemplateDepth() == E2->getTemplateDepth();
284  }
285 
286  bool IsStmtEquivalent(const StringLiteral *E1, const StringLiteral *E2) {
287  return E1->getBytes() == E2->getBytes();
288  }
289 
290  bool IsStmtEquivalent(const SubstNonTypeTemplateParmExpr *E1,
291  const SubstNonTypeTemplateParmExpr *E2) {
292  if (!IsStructurallyEquivalent(Context, E1->getAssociatedDecl(),
293  E2->getAssociatedDecl()))
294  return false;
295  if (E1->getIndex() != E2->getIndex())
296  return false;
297  if (E1->getPackIndex() != E2->getPackIndex())
298  return false;
299  return true;
300  }
301 
302  bool IsStmtEquivalent(const SubstNonTypeTemplateParmPackExpr *E1,
304  return IsStructurallyEquivalent(Context, E1->getArgumentPack(),
305  E2->getArgumentPack());
306  }
307 
308  bool IsStmtEquivalent(const TypeTraitExpr *E1, const TypeTraitExpr *E2) {
309  if (E1->getTrait() != E2->getTrait())
310  return false;
311 
312  for (auto Pair : zip_longest(E1->getArgs(), E2->getArgs())) {
313  Optional<TypeSourceInfo *> Child1 = std::get<0>(Pair);
314  Optional<TypeSourceInfo *> Child2 = std::get<1>(Pair);
315  // Different number of args.
316  if (!Child1 || !Child2)
317  return false;
318 
319  if (!IsStructurallyEquivalent(Context, (*Child1)->getType(),
320  (*Child2)->getType()))
321  return false;
322  }
323  return true;
324  }
325 
326  bool IsStmtEquivalent(const UnaryExprOrTypeTraitExpr *E1,
327  const UnaryExprOrTypeTraitExpr *E2) {
328  if (E1->getKind() != E2->getKind())
329  return false;
330  return IsStructurallyEquivalent(Context, E1->getTypeOfArgument(),
331  E2->getTypeOfArgument());
332  }
333 
334  bool IsStmtEquivalent(const UnaryOperator *E1, const UnaryOperator *E2) {
335  return E1->getOpcode() == E2->getOpcode();
336  }
337 
338  bool IsStmtEquivalent(const VAArgExpr *E1, const VAArgExpr *E2) {
339  // Semantics only depend on children.
340  return true;
341  }
342 
343  /// End point of the traversal chain.
344  bool TraverseStmt(const Stmt *S1, const Stmt *S2) { return true; }
345 
346  // Create traversal methods that traverse the class hierarchy and return
347  // the accumulated result of the comparison. Each TraverseStmt overload
348  // calls the TraverseStmt overload of the parent class. For example,
349  // the TraverseStmt overload for 'BinaryOperator' calls the TraverseStmt
350  // overload of 'Expr' which then calls the overload for 'Stmt'.
351 #define STMT(CLASS, PARENT) \
352  bool TraverseStmt(const CLASS *S1, const CLASS *S2) { \
353  if (!TraverseStmt(static_cast<const PARENT *>(S1), \
354  static_cast<const PARENT *>(S2))) \
355  return false; \
356  return IsStmtEquivalent(S1, S2); \
357  }
358 #include "clang/AST/StmtNodes.inc"
359 
360 public:
361  StmtComparer(StructuralEquivalenceContext &C) : Context(C) {}
362 
363  /// Determine whether two statements are equivalent. The statements have to
364  /// be of the same kind. The children of the statements and their properties
365  /// are not compared by this function.
366  bool IsEquivalent(const Stmt *S1, const Stmt *S2) {
367  if (S1->getStmtClass() != S2->getStmtClass())
368  return false;
369 
370  // Each TraverseStmt walks the class hierarchy from the leaf class to
371  // the root class 'Stmt' (e.g. 'BinaryOperator' -> 'Expr' -> 'Stmt'). Cast
372  // the Stmt we have here to its specific subclass so that we call the
373  // overload that walks the whole class hierarchy from leaf to root (e.g.,
374  // cast to 'BinaryOperator' so that 'Expr' and 'Stmt' is traversed).
375  switch (S1->getStmtClass()) {
376  case Stmt::NoStmtClass:
377  llvm_unreachable("Can't traverse NoStmtClass");
378 #define STMT(CLASS, PARENT) \
379  case Stmt::StmtClass::CLASS##Class: \
380  return TraverseStmt(static_cast<const CLASS *>(S1), \
381  static_cast<const CLASS *>(S2));
382 #define ABSTRACT_STMT(S)
383 #include "clang/AST/StmtNodes.inc"
384  }
385  llvm_unreachable("Invalid statement kind");
386  }
387 };
388 } // namespace
389 
390 /// Determine structural equivalence of two statements.
392  const Stmt *S1, const Stmt *S2) {
393  if (!S1 || !S2)
394  return S1 == S2;
395 
396  // Compare the statements itself.
397  StmtComparer Comparer(Context);
398  if (!Comparer.IsEquivalent(S1, S2))
399  return false;
400 
401  // Iterate over the children of both statements and also compare them.
402  for (auto Pair : zip_longest(S1->children(), S2->children())) {
403  Optional<const Stmt *> Child1 = std::get<0>(Pair);
404  Optional<const Stmt *> Child2 = std::get<1>(Pair);
405  // One of the statements has a different amount of children than the other,
406  // so the statements can't be equivalent.
407  if (!Child1 || !Child2)
408  return false;
409  if (!IsStructurallyEquivalent(Context, *Child1, *Child2))
410  return false;
411  }
412  return true;
413 }
414 
415 /// Determine whether two identifiers are equivalent.
416 static bool IsStructurallyEquivalent(const IdentifierInfo *Name1,
417  const IdentifierInfo *Name2) {
418  if (!Name1 || !Name2)
419  return Name1 == Name2;
420 
421  return Name1->getName() == Name2->getName();
422 }
423 
424 /// Determine whether two nested-name-specifiers are equivalent.
426  NestedNameSpecifier *NNS1,
427  NestedNameSpecifier *NNS2) {
428  if (NNS1->getKind() != NNS2->getKind())
429  return false;
430 
431  NestedNameSpecifier *Prefix1 = NNS1->getPrefix(),
432  *Prefix2 = NNS2->getPrefix();
433  if ((bool)Prefix1 != (bool)Prefix2)
434  return false;
435 
436  if (Prefix1)
437  if (!IsStructurallyEquivalent(Context, Prefix1, Prefix2))
438  return false;
439 
440  switch (NNS1->getKind()) {
443  NNS2->getAsIdentifier());
445  return IsStructurallyEquivalent(Context, NNS1->getAsNamespace(),
446  NNS2->getAsNamespace());
448  return IsStructurallyEquivalent(Context, NNS1->getAsNamespaceAlias(),
449  NNS2->getAsNamespaceAlias());
452  return IsStructurallyEquivalent(Context, QualType(NNS1->getAsType(), 0),
453  QualType(NNS2->getAsType(), 0));
455  return true;
457  return IsStructurallyEquivalent(Context, NNS1->getAsRecordDecl(),
458  NNS2->getAsRecordDecl());
459  }
460  return false;
461 }
462 
464  const TemplateName &N1,
465  const TemplateName &N2) {
466  TemplateDecl *TemplateDeclN1 = N1.getAsTemplateDecl();
467  TemplateDecl *TemplateDeclN2 = N2.getAsTemplateDecl();
468  if (TemplateDeclN1 && TemplateDeclN2) {
469  if (!IsStructurallyEquivalent(Context, TemplateDeclN1, TemplateDeclN2))
470  return false;
471  // If the kind is different we compare only the template decl.
472  if (N1.getKind() != N2.getKind())
473  return true;
474  } else if (TemplateDeclN1 || TemplateDeclN2)
475  return false;
476  else if (N1.getKind() != N2.getKind())
477  return false;
478 
479  // Check for special case incompatibilities.
480  switch (N1.getKind()) {
481 
484  *OS2 = N2.getAsOverloadedTemplate();
485  OverloadedTemplateStorage::iterator I1 = OS1->begin(), I2 = OS2->begin(),
486  E1 = OS1->end(), E2 = OS2->end();
487  for (; I1 != E1 && I2 != E2; ++I1, ++I2)
488  if (!IsStructurallyEquivalent(Context, *I1, *I2))
489  return false;
490  return I1 == E1 && I2 == E2;
491  }
492 
495  *TN2 = N1.getAsAssumedTemplateName();
496  return TN1->getDeclName() == TN2->getDeclName();
497  }
498 
501  *DN2 = N2.getAsDependentTemplateName();
502  if (!IsStructurallyEquivalent(Context, DN1->getQualifier(),
503  DN2->getQualifier()))
504  return false;
505  if (DN1->isIdentifier() && DN2->isIdentifier())
507  DN2->getIdentifier());
508  else if (DN1->isOverloadedOperator() && DN2->isOverloadedOperator())
509  return DN1->getOperator() == DN2->getOperator();
510  return false;
511  }
512 
517  return IsStructurallyEquivalent(Context, P1->getArgumentPack(),
518  P2->getArgumentPack()) &&
520  P2->getAssociatedDecl()) &&
521  P1->getIndex() == P2->getIndex();
522  }
523 
528  // It is sufficient to check value of getAsTemplateDecl.
529  break;
530 
531  }
532 
533  return true;
534 }
535 
539 
540 /// Determine whether two template arguments are equivalent.
542  const TemplateArgument &Arg1,
543  const TemplateArgument &Arg2) {
544  if (Arg1.getKind() != Arg2.getKind())
545  return false;
546 
547  switch (Arg1.getKind()) {
549  return true;
550 
552  return IsStructurallyEquivalent(Context, Arg1.getAsType(), Arg2.getAsType());
553 
555  if (!IsStructurallyEquivalent(Context, Arg1.getIntegralType(),
556  Arg2.getIntegralType()))
557  return false;
558 
559  return llvm::APSInt::isSameValue(Arg1.getAsIntegral(),
560  Arg2.getAsIntegral());
561 
563  return IsStructurallyEquivalent(Context, Arg1.getAsDecl(), Arg2.getAsDecl());
564 
566  return true; // FIXME: Is this correct?
567 
569  return IsStructurallyEquivalent(Context, Arg1.getAsTemplate(),
570  Arg2.getAsTemplate());
571 
573  return IsStructurallyEquivalent(Context,
576 
578  return IsStructurallyEquivalent(Context, Arg1.getAsExpr(),
579  Arg2.getAsExpr());
580 
582  return IsStructurallyEquivalent(Context, Arg1.pack_elements(),
583  Arg2.pack_elements());
584  }
585 
586  llvm_unreachable("Invalid template argument kind");
587 }
588 
589 /// Determine structural equivalence of two template argument lists.
593  if (Args1.size() != Args2.size())
594  return false;
595  for (unsigned I = 0, N = Args1.size(); I != N; ++I) {
596  if (!IsStructurallyEquivalent(Context, Args1[I], Args2[I]))
597  return false;
598  }
599  return true;
600 }
601 
602 /// Determine structural equivalence for the common part of array
603 /// types.
605  const ArrayType *Array1,
606  const ArrayType *Array2) {
607  if (!IsStructurallyEquivalent(Context, Array1->getElementType(),
608  Array2->getElementType()))
609  return false;
610  if (Array1->getSizeModifier() != Array2->getSizeModifier())
611  return false;
612  if (Array1->getIndexTypeQualifiers() != Array2->getIndexTypeQualifiers())
613  return false;
614 
615  return true;
616 }
617 
618 /// Determine structural equivalence based on the ExtInfo of functions. This
619 /// is inspired by ASTContext::mergeFunctionTypes(), we compare calling
620 /// conventions bits but must not compare some other bits.
623  FunctionType::ExtInfo EI2) {
624  // Compatible functions must have compatible calling conventions.
625  if (EI1.getCC() != EI2.getCC())
626  return false;
627 
628  // Regparm is part of the calling convention.
629  if (EI1.getHasRegParm() != EI2.getHasRegParm())
630  return false;
631  if (EI1.getRegParm() != EI2.getRegParm())
632  return false;
633 
634  if (EI1.getProducesResult() != EI2.getProducesResult())
635  return false;
636  if (EI1.getNoCallerSavedRegs() != EI2.getNoCallerSavedRegs())
637  return false;
638  if (EI1.getNoCfCheck() != EI2.getNoCfCheck())
639  return false;
640 
641  return true;
642 }
643 
644 /// Check the equivalence of exception specifications.
646  const FunctionProtoType *Proto1,
647  const FunctionProtoType *Proto2) {
648 
649  auto Spec1 = Proto1->getExceptionSpecType();
650  auto Spec2 = Proto2->getExceptionSpecType();
651 
653  return true;
654 
655  if (Spec1 != Spec2)
656  return false;
657  if (Spec1 == EST_Dynamic) {
658  if (Proto1->getNumExceptions() != Proto2->getNumExceptions())
659  return false;
660  for (unsigned I = 0, N = Proto1->getNumExceptions(); I != N; ++I) {
661  if (!IsStructurallyEquivalent(Context, Proto1->getExceptionType(I),
662  Proto2->getExceptionType(I)))
663  return false;
664  }
665  } else if (isComputedNoexcept(Spec1)) {
666  if (!IsStructurallyEquivalent(Context, Proto1->getNoexceptExpr(),
667  Proto2->getNoexceptExpr()))
668  return false;
669  }
670 
671  return true;
672 }
673 
674 /// Determine structural equivalence of two types.
676  QualType T1, QualType T2) {
677  if (T1.isNull() || T2.isNull())
678  return T1.isNull() && T2.isNull();
679 
680  QualType OrigT1 = T1;
681  QualType OrigT2 = T2;
682 
683  if (!Context.StrictTypeSpelling) {
684  // We aren't being strict about token-to-token equivalence of types,
685  // so map down to the canonical type.
686  T1 = Context.FromCtx.getCanonicalType(T1);
687  T2 = Context.ToCtx.getCanonicalType(T2);
688  }
689 
690  if (T1.getQualifiers() != T2.getQualifiers())
691  return false;
692 
693  Type::TypeClass TC = T1->getTypeClass();
694 
695  if (T1->getTypeClass() != T2->getTypeClass()) {
696  // Compare function types with prototypes vs. without prototypes as if
697  // both did not have prototypes.
698  if (T1->getTypeClass() == Type::FunctionProto &&
699  T2->getTypeClass() == Type::FunctionNoProto)
700  TC = Type::FunctionNoProto;
701  else if (T1->getTypeClass() == Type::FunctionNoProto &&
702  T2->getTypeClass() == Type::FunctionProto)
703  TC = Type::FunctionNoProto;
704  else
705  return false;
706  }
707 
708  switch (TC) {
709  case Type::Builtin:
710  // FIXME: Deal with Char_S/Char_U.
711  if (cast<BuiltinType>(T1)->getKind() != cast<BuiltinType>(T2)->getKind())
712  return false;
713  break;
714 
715  case Type::Complex:
716  if (!IsStructurallyEquivalent(Context,
717  cast<ComplexType>(T1)->getElementType(),
718  cast<ComplexType>(T2)->getElementType()))
719  return false;
720  break;
721 
722  case Type::Adjusted:
723  case Type::Decayed:
724  if (!IsStructurallyEquivalent(Context,
725  cast<AdjustedType>(T1)->getOriginalType(),
726  cast<AdjustedType>(T2)->getOriginalType()))
727  return false;
728  break;
729 
730  case Type::Pointer:
731  if (!IsStructurallyEquivalent(Context,
732  cast<PointerType>(T1)->getPointeeType(),
733  cast<PointerType>(T2)->getPointeeType()))
734  return false;
735  break;
736 
737  case Type::BlockPointer:
738  if (!IsStructurallyEquivalent(Context,
739  cast<BlockPointerType>(T1)->getPointeeType(),
740  cast<BlockPointerType>(T2)->getPointeeType()))
741  return false;
742  break;
743 
744  case Type::LValueReference:
745  case Type::RValueReference: {
746  const auto *Ref1 = cast<ReferenceType>(T1);
747  const auto *Ref2 = cast<ReferenceType>(T2);
748  if (Ref1->isSpelledAsLValue() != Ref2->isSpelledAsLValue())
749  return false;
750  if (Ref1->isInnerRef() != Ref2->isInnerRef())
751  return false;
752  if (!IsStructurallyEquivalent(Context, Ref1->getPointeeTypeAsWritten(),
753  Ref2->getPointeeTypeAsWritten()))
754  return false;
755  break;
756  }
757 
758  case Type::MemberPointer: {
759  const auto *MemPtr1 = cast<MemberPointerType>(T1);
760  const auto *MemPtr2 = cast<MemberPointerType>(T2);
761  if (!IsStructurallyEquivalent(Context, MemPtr1->getPointeeType(),
762  MemPtr2->getPointeeType()))
763  return false;
764  if (!IsStructurallyEquivalent(Context, QualType(MemPtr1->getClass(), 0),
765  QualType(MemPtr2->getClass(), 0)))
766  return false;
767  break;
768  }
769 
770  case Type::ConstantArray: {
771  const auto *Array1 = cast<ConstantArrayType>(T1);
772  const auto *Array2 = cast<ConstantArrayType>(T2);
773  if (!llvm::APInt::isSameValue(Array1->getSize(), Array2->getSize()))
774  return false;
775 
776  if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
777  return false;
778  break;
779  }
780 
781  case Type::IncompleteArray:
782  if (!IsArrayStructurallyEquivalent(Context, cast<ArrayType>(T1),
783  cast<ArrayType>(T2)))
784  return false;
785  break;
786 
787  case Type::VariableArray: {
788  const auto *Array1 = cast<VariableArrayType>(T1);
789  const auto *Array2 = cast<VariableArrayType>(T2);
790  if (!IsStructurallyEquivalent(Context, Array1->getSizeExpr(),
791  Array2->getSizeExpr()))
792  return false;
793 
794  if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
795  return false;
796 
797  break;
798  }
799 
800  case Type::DependentSizedArray: {
801  const auto *Array1 = cast<DependentSizedArrayType>(T1);
802  const auto *Array2 = cast<DependentSizedArrayType>(T2);
803  if (!IsStructurallyEquivalent(Context, Array1->getSizeExpr(),
804  Array2->getSizeExpr()))
805  return false;
806 
807  if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
808  return false;
809 
810  break;
811  }
812 
813  case Type::DependentAddressSpace: {
814  const auto *DepAddressSpace1 = cast<DependentAddressSpaceType>(T1);
815  const auto *DepAddressSpace2 = cast<DependentAddressSpaceType>(T2);
816  if (!IsStructurallyEquivalent(Context, DepAddressSpace1->getAddrSpaceExpr(),
817  DepAddressSpace2->getAddrSpaceExpr()))
818  return false;
819  if (!IsStructurallyEquivalent(Context, DepAddressSpace1->getPointeeType(),
820  DepAddressSpace2->getPointeeType()))
821  return false;
822 
823  break;
824  }
825 
826  case Type::DependentSizedExtVector: {
827  const auto *Vec1 = cast<DependentSizedExtVectorType>(T1);
828  const auto *Vec2 = cast<DependentSizedExtVectorType>(T2);
829  if (!IsStructurallyEquivalent(Context, Vec1->getSizeExpr(),
830  Vec2->getSizeExpr()))
831  return false;
832  if (!IsStructurallyEquivalent(Context, Vec1->getElementType(),
833  Vec2->getElementType()))
834  return false;
835  break;
836  }
837 
838  case Type::DependentVector: {
839  const auto *Vec1 = cast<DependentVectorType>(T1);
840  const auto *Vec2 = cast<DependentVectorType>(T2);
841  if (Vec1->getVectorKind() != Vec2->getVectorKind())
842  return false;
843  if (!IsStructurallyEquivalent(Context, Vec1->getSizeExpr(),
844  Vec2->getSizeExpr()))
845  return false;
846  if (!IsStructurallyEquivalent(Context, Vec1->getElementType(),
847  Vec2->getElementType()))
848  return false;
849  break;
850  }
851 
852  case Type::Vector:
853  case Type::ExtVector: {
854  const auto *Vec1 = cast<VectorType>(T1);
855  const auto *Vec2 = cast<VectorType>(T2);
856  if (!IsStructurallyEquivalent(Context, Vec1->getElementType(),
857  Vec2->getElementType()))
858  return false;
859  if (Vec1->getNumElements() != Vec2->getNumElements())
860  return false;
861  if (Vec1->getVectorKind() != Vec2->getVectorKind())
862  return false;
863  break;
864  }
865 
866  case Type::DependentSizedMatrix: {
867  const DependentSizedMatrixType *Mat1 = cast<DependentSizedMatrixType>(T1);
868  const DependentSizedMatrixType *Mat2 = cast<DependentSizedMatrixType>(T2);
869  // The element types, row and column expressions must be structurally
870  // equivalent.
871  if (!IsStructurallyEquivalent(Context, Mat1->getRowExpr(),
872  Mat2->getRowExpr()) ||
873  !IsStructurallyEquivalent(Context, Mat1->getColumnExpr(),
874  Mat2->getColumnExpr()) ||
875  !IsStructurallyEquivalent(Context, Mat1->getElementType(),
876  Mat2->getElementType()))
877  return false;
878  break;
879  }
880 
881  case Type::ConstantMatrix: {
882  const ConstantMatrixType *Mat1 = cast<ConstantMatrixType>(T1);
883  const ConstantMatrixType *Mat2 = cast<ConstantMatrixType>(T2);
884  // The element types must be structurally equivalent and the number of rows
885  // and columns must match.
886  if (!IsStructurallyEquivalent(Context, Mat1->getElementType(),
887  Mat2->getElementType()) ||
888  Mat1->getNumRows() != Mat2->getNumRows() ||
889  Mat1->getNumColumns() != Mat2->getNumColumns())
890  return false;
891  break;
892  }
893 
894  case Type::FunctionProto: {
895  const auto *Proto1 = cast<FunctionProtoType>(T1);
896  const auto *Proto2 = cast<FunctionProtoType>(T2);
897 
898  if (Proto1->getNumParams() != Proto2->getNumParams())
899  return false;
900  for (unsigned I = 0, N = Proto1->getNumParams(); I != N; ++I) {
901  if (!IsStructurallyEquivalent(Context, Proto1->getParamType(I),
902  Proto2->getParamType(I)))
903  return false;
904  }
905  if (Proto1->isVariadic() != Proto2->isVariadic())
906  return false;
907 
908  if (Proto1->getMethodQuals() != Proto2->getMethodQuals())
909  return false;
910 
911  // Check exceptions, this information is lost in canonical type.
912  const auto *OrigProto1 =
913  cast<FunctionProtoType>(OrigT1.getDesugaredType(Context.FromCtx));
914  const auto *OrigProto2 =
915  cast<FunctionProtoType>(OrigT2.getDesugaredType(Context.ToCtx));
916  if (!IsEquivalentExceptionSpec(Context, OrigProto1, OrigProto2))
917  return false;
918 
919  // Fall through to check the bits common with FunctionNoProtoType.
920  [[fallthrough]];
921  }
922 
923  case Type::FunctionNoProto: {
924  const auto *Function1 = cast<FunctionType>(T1);
925  const auto *Function2 = cast<FunctionType>(T2);
926  if (!IsStructurallyEquivalent(Context, Function1->getReturnType(),
927  Function2->getReturnType()))
928  return false;
929  if (!IsStructurallyEquivalent(Context, Function1->getExtInfo(),
930  Function2->getExtInfo()))
931  return false;
932  break;
933  }
934 
935  case Type::UnresolvedUsing:
936  if (!IsStructurallyEquivalent(Context,
937  cast<UnresolvedUsingType>(T1)->getDecl(),
938  cast<UnresolvedUsingType>(T2)->getDecl()))
939  return false;
940  break;
941 
942  case Type::Attributed:
943  if (!IsStructurallyEquivalent(Context,
944  cast<AttributedType>(T1)->getModifiedType(),
945  cast<AttributedType>(T2)->getModifiedType()))
946  return false;
948  Context, cast<AttributedType>(T1)->getEquivalentType(),
949  cast<AttributedType>(T2)->getEquivalentType()))
950  return false;
951  break;
952 
953  case Type::BTFTagAttributed:
955  Context, cast<BTFTagAttributedType>(T1)->getWrappedType(),
956  cast<BTFTagAttributedType>(T2)->getWrappedType()))
957  return false;
958  break;
959 
960  case Type::Paren:
961  if (!IsStructurallyEquivalent(Context, cast<ParenType>(T1)->getInnerType(),
962  cast<ParenType>(T2)->getInnerType()))
963  return false;
964  break;
965 
966  case Type::MacroQualified:
968  Context, cast<MacroQualifiedType>(T1)->getUnderlyingType(),
969  cast<MacroQualifiedType>(T2)->getUnderlyingType()))
970  return false;
971  break;
972 
973  case Type::Using:
974  if (!IsStructurallyEquivalent(Context, cast<UsingType>(T1)->getFoundDecl(),
975  cast<UsingType>(T2)->getFoundDecl()))
976  return false;
977  if (!IsStructurallyEquivalent(Context,
978  cast<UsingType>(T1)->getUnderlyingType(),
979  cast<UsingType>(T2)->getUnderlyingType()))
980  return false;
981  break;
982 
983  case Type::Typedef:
984  if (!IsStructurallyEquivalent(Context, cast<TypedefType>(T1)->getDecl(),
985  cast<TypedefType>(T2)->getDecl()) ||
986  !IsStructurallyEquivalent(Context, cast<TypedefType>(T1)->desugar(),
987  cast<TypedefType>(T2)->desugar()))
988  return false;
989  break;
990 
991  case Type::TypeOfExpr:
993  Context, cast<TypeOfExprType>(T1)->getUnderlyingExpr(),
994  cast<TypeOfExprType>(T2)->getUnderlyingExpr()))
995  return false;
996  break;
997 
998  case Type::TypeOf:
999  if (!IsStructurallyEquivalent(Context,
1000  cast<TypeOfType>(T1)->getUnmodifiedType(),
1001  cast<TypeOfType>(T2)->getUnmodifiedType()))
1002  return false;
1003  break;
1004 
1005  case Type::UnaryTransform:
1007  Context, cast<UnaryTransformType>(T1)->getUnderlyingType(),
1008  cast<UnaryTransformType>(T2)->getUnderlyingType()))
1009  return false;
1010  break;
1011 
1012  case Type::Decltype:
1013  if (!IsStructurallyEquivalent(Context,
1014  cast<DecltypeType>(T1)->getUnderlyingExpr(),
1015  cast<DecltypeType>(T2)->getUnderlyingExpr()))
1016  return false;
1017  break;
1018 
1019  case Type::Auto: {
1020  auto *Auto1 = cast<AutoType>(T1);
1021  auto *Auto2 = cast<AutoType>(T2);
1022  if (!IsStructurallyEquivalent(Context, Auto1->getDeducedType(),
1023  Auto2->getDeducedType()))
1024  return false;
1025  if (Auto1->isConstrained() != Auto2->isConstrained())
1026  return false;
1027  if (Auto1->isConstrained()) {
1028  if (Auto1->getTypeConstraintConcept() !=
1029  Auto2->getTypeConstraintConcept())
1030  return false;
1031  if (!IsStructurallyEquivalent(Context,
1032  Auto1->getTypeConstraintArguments(),
1033  Auto2->getTypeConstraintArguments()))
1034  return false;
1035  }
1036  break;
1037  }
1038 
1039  case Type::DeducedTemplateSpecialization: {
1040  const auto *DT1 = cast<DeducedTemplateSpecializationType>(T1);
1041  const auto *DT2 = cast<DeducedTemplateSpecializationType>(T2);
1042  if (!IsStructurallyEquivalent(Context, DT1->getTemplateName(),
1043  DT2->getTemplateName()))
1044  return false;
1045  if (!IsStructurallyEquivalent(Context, DT1->getDeducedType(),
1046  DT2->getDeducedType()))
1047  return false;
1048  break;
1049  }
1050 
1051  case Type::Record:
1052  case Type::Enum:
1053  if (!IsStructurallyEquivalent(Context, cast<TagType>(T1)->getDecl(),
1054  cast<TagType>(T2)->getDecl()))
1055  return false;
1056  break;
1057 
1058  case Type::TemplateTypeParm: {
1059  const auto *Parm1 = cast<TemplateTypeParmType>(T1);
1060  const auto *Parm2 = cast<TemplateTypeParmType>(T2);
1061  if (Parm1->getDepth() != Parm2->getDepth())
1062  return false;
1063  if (Parm1->getIndex() != Parm2->getIndex())
1064  return false;
1065  if (Parm1->isParameterPack() != Parm2->isParameterPack())
1066  return false;
1067 
1068  // Names of template type parameters are never significant.
1069  break;
1070  }
1071 
1072  case Type::SubstTemplateTypeParm: {
1073  const auto *Subst1 = cast<SubstTemplateTypeParmType>(T1);
1074  const auto *Subst2 = cast<SubstTemplateTypeParmType>(T2);
1075  if (!IsStructurallyEquivalent(Context, Subst1->getReplacementType(),
1076  Subst2->getReplacementType()))
1077  return false;
1078  if (!IsStructurallyEquivalent(Context, Subst1->getAssociatedDecl(),
1079  Subst2->getAssociatedDecl()))
1080  return false;
1081  if (Subst1->getIndex() != Subst2->getIndex())
1082  return false;
1083  if (Subst1->getPackIndex() != Subst2->getPackIndex())
1084  return false;
1085  break;
1086  }
1087 
1088  case Type::SubstTemplateTypeParmPack: {
1089  const auto *Subst1 = cast<SubstTemplateTypeParmPackType>(T1);
1090  const auto *Subst2 = cast<SubstTemplateTypeParmPackType>(T2);
1091  if (!IsStructurallyEquivalent(Context, Subst1->getAssociatedDecl(),
1092  Subst2->getAssociatedDecl()))
1093  return false;
1094  if (Subst1->getIndex() != Subst2->getIndex())
1095  return false;
1096  if (!IsStructurallyEquivalent(Context, Subst1->getArgumentPack(),
1097  Subst2->getArgumentPack()))
1098  return false;
1099  break;
1100  }
1101 
1102  case Type::TemplateSpecialization: {
1103  const auto *Spec1 = cast<TemplateSpecializationType>(T1);
1104  const auto *Spec2 = cast<TemplateSpecializationType>(T2);
1105  if (!IsStructurallyEquivalent(Context, Spec1->getTemplateName(),
1106  Spec2->getTemplateName()))
1107  return false;
1108  if (!IsStructurallyEquivalent(Context, Spec1->template_arguments(),
1109  Spec2->template_arguments()))
1110  return false;
1111  break;
1112  }
1113 
1114  case Type::Elaborated: {
1115  const auto *Elab1 = cast<ElaboratedType>(T1);
1116  const auto *Elab2 = cast<ElaboratedType>(T2);
1117  // CHECKME: what if a keyword is ETK_None or ETK_typename ?
1118  if (Elab1->getKeyword() != Elab2->getKeyword())
1119  return false;
1120  if (!IsStructurallyEquivalent(Context, Elab1->getQualifier(),
1121  Elab2->getQualifier()))
1122  return false;
1123  if (!IsStructurallyEquivalent(Context, Elab1->getNamedType(),
1124  Elab2->getNamedType()))
1125  return false;
1126  break;
1127  }
1128 
1129  case Type::InjectedClassName: {
1130  const auto *Inj1 = cast<InjectedClassNameType>(T1);
1131  const auto *Inj2 = cast<InjectedClassNameType>(T2);
1132  if (!IsStructurallyEquivalent(Context,
1133  Inj1->getInjectedSpecializationType(),
1134  Inj2->getInjectedSpecializationType()))
1135  return false;
1136  break;
1137  }
1138 
1139  case Type::DependentName: {
1140  const auto *Typename1 = cast<DependentNameType>(T1);
1141  const auto *Typename2 = cast<DependentNameType>(T2);
1142  if (!IsStructurallyEquivalent(Context, Typename1->getQualifier(),
1143  Typename2->getQualifier()))
1144  return false;
1145  if (!IsStructurallyEquivalent(Typename1->getIdentifier(),
1146  Typename2->getIdentifier()))
1147  return false;
1148 
1149  break;
1150  }
1151 
1152  case Type::DependentTemplateSpecialization: {
1153  const auto *Spec1 = cast<DependentTemplateSpecializationType>(T1);
1154  const auto *Spec2 = cast<DependentTemplateSpecializationType>(T2);
1155  if (!IsStructurallyEquivalent(Context, Spec1->getQualifier(),
1156  Spec2->getQualifier()))
1157  return false;
1158  if (!IsStructurallyEquivalent(Spec1->getIdentifier(),
1159  Spec2->getIdentifier()))
1160  return false;
1161  if (!IsStructurallyEquivalent(Context, Spec1->template_arguments(),
1162  Spec2->template_arguments()))
1163  return false;
1164  break;
1165  }
1166 
1167  case Type::PackExpansion:
1168  if (!IsStructurallyEquivalent(Context,
1169  cast<PackExpansionType>(T1)->getPattern(),
1170  cast<PackExpansionType>(T2)->getPattern()))
1171  return false;
1172  break;
1173 
1174  case Type::ObjCInterface: {
1175  const auto *Iface1 = cast<ObjCInterfaceType>(T1);
1176  const auto *Iface2 = cast<ObjCInterfaceType>(T2);
1177  if (!IsStructurallyEquivalent(Context, Iface1->getDecl(),
1178  Iface2->getDecl()))
1179  return false;
1180  break;
1181  }
1182 
1183  case Type::ObjCTypeParam: {
1184  const auto *Obj1 = cast<ObjCTypeParamType>(T1);
1185  const auto *Obj2 = cast<ObjCTypeParamType>(T2);
1186  if (!IsStructurallyEquivalent(Context, Obj1->getDecl(), Obj2->getDecl()))
1187  return false;
1188 
1189  if (Obj1->getNumProtocols() != Obj2->getNumProtocols())
1190  return false;
1191  for (unsigned I = 0, N = Obj1->getNumProtocols(); I != N; ++I) {
1192  if (!IsStructurallyEquivalent(Context, Obj1->getProtocol(I),
1193  Obj2->getProtocol(I)))
1194  return false;
1195  }
1196  break;
1197  }
1198 
1199  case Type::ObjCObject: {
1200  const auto *Obj1 = cast<ObjCObjectType>(T1);
1201  const auto *Obj2 = cast<ObjCObjectType>(T2);
1202  if (!IsStructurallyEquivalent(Context, Obj1->getBaseType(),
1203  Obj2->getBaseType()))
1204  return false;
1205  if (Obj1->getNumProtocols() != Obj2->getNumProtocols())
1206  return false;
1207  for (unsigned I = 0, N = Obj1->getNumProtocols(); I != N; ++I) {
1208  if (!IsStructurallyEquivalent(Context, Obj1->getProtocol(I),
1209  Obj2->getProtocol(I)))
1210  return false;
1211  }
1212  break;
1213  }
1214 
1215  case Type::ObjCObjectPointer: {
1216  const auto *Ptr1 = cast<ObjCObjectPointerType>(T1);
1217  const auto *Ptr2 = cast<ObjCObjectPointerType>(T2);
1218  if (!IsStructurallyEquivalent(Context, Ptr1->getPointeeType(),
1219  Ptr2->getPointeeType()))
1220  return false;
1221  break;
1222  }
1223 
1224  case Type::Atomic:
1225  if (!IsStructurallyEquivalent(Context, cast<AtomicType>(T1)->getValueType(),
1226  cast<AtomicType>(T2)->getValueType()))
1227  return false;
1228  break;
1229 
1230  case Type::Pipe:
1231  if (!IsStructurallyEquivalent(Context, cast<PipeType>(T1)->getElementType(),
1232  cast<PipeType>(T2)->getElementType()))
1233  return false;
1234  break;
1235  case Type::BitInt: {
1236  const auto *Int1 = cast<BitIntType>(T1);
1237  const auto *Int2 = cast<BitIntType>(T2);
1238 
1239  if (Int1->isUnsigned() != Int2->isUnsigned() ||
1240  Int1->getNumBits() != Int2->getNumBits())
1241  return false;
1242  break;
1243  }
1244  case Type::DependentBitInt: {
1245  const auto *Int1 = cast<DependentBitIntType>(T1);
1246  const auto *Int2 = cast<DependentBitIntType>(T2);
1247 
1248  if (Int1->isUnsigned() != Int2->isUnsigned() ||
1249  !IsStructurallyEquivalent(Context, Int1->getNumBitsExpr(),
1250  Int2->getNumBitsExpr()))
1251  return false;
1252  break;
1253  }
1254  } // end switch
1255 
1256  return true;
1257 }
1258 
1260  FieldDecl *Field1, FieldDecl *Field2,
1261  QualType Owner2Type) {
1262  const auto *Owner2 = cast<Decl>(Field2->getDeclContext());
1263 
1264  // For anonymous structs/unions, match up the anonymous struct/union type
1265  // declarations directly, so that we don't go off searching for anonymous
1266  // types
1267  if (Field1->isAnonymousStructOrUnion() &&
1268  Field2->isAnonymousStructOrUnion()) {
1269  RecordDecl *D1 = Field1->getType()->castAs<RecordType>()->getDecl();
1270  RecordDecl *D2 = Field2->getType()->castAs<RecordType>()->getDecl();
1271  return IsStructurallyEquivalent(Context, D1, D2);
1272  }
1273 
1274  // Check for equivalent field names.
1275  IdentifierInfo *Name1 = Field1->getIdentifier();
1276  IdentifierInfo *Name2 = Field2->getIdentifier();
1277  if (!::IsStructurallyEquivalent(Name1, Name2)) {
1278  if (Context.Complain) {
1279  Context.Diag2(
1280  Owner2->getLocation(),
1281  Context.getApplicableDiagnostic(diag::err_odr_tag_type_inconsistent))
1282  << Owner2Type;
1283  Context.Diag2(Field2->getLocation(), diag::note_odr_field_name)
1284  << Field2->getDeclName();
1285  Context.Diag1(Field1->getLocation(), diag::note_odr_field_name)
1286  << Field1->getDeclName();
1287  }
1288  return false;
1289  }
1290 
1291  if (!IsStructurallyEquivalent(Context, Field1->getType(),
1292  Field2->getType())) {
1293  if (Context.Complain) {
1294  Context.Diag2(
1295  Owner2->getLocation(),
1296  Context.getApplicableDiagnostic(diag::err_odr_tag_type_inconsistent))
1297  << Owner2Type;
1298  Context.Diag2(Field2->getLocation(), diag::note_odr_field)
1299  << Field2->getDeclName() << Field2->getType();
1300  Context.Diag1(Field1->getLocation(), diag::note_odr_field)
1301  << Field1->getDeclName() << Field1->getType();
1302  }
1303  return false;
1304  }
1305 
1306  if (Field1->isBitField())
1307  return IsStructurallyEquivalent(Context, Field1->getBitWidth(),
1308  Field2->getBitWidth());
1309 
1310  return true;
1311 }
1312 
1313 /// Determine structural equivalence of two fields.
1315  FieldDecl *Field1, FieldDecl *Field2) {
1316  const auto *Owner2 = cast<RecordDecl>(Field2->getDeclContext());
1317  return IsStructurallyEquivalent(Context, Field1, Field2,
1318  Context.ToCtx.getTypeDeclType(Owner2));
1319 }
1320 
1321 /// Determine structural equivalence of two methods.
1323  CXXMethodDecl *Method1,
1324  CXXMethodDecl *Method2) {
1325  bool PropertiesEqual =
1326  Method1->getDeclKind() == Method2->getDeclKind() &&
1327  Method1->getRefQualifier() == Method2->getRefQualifier() &&
1328  Method1->getAccess() == Method2->getAccess() &&
1329  Method1->getOverloadedOperator() == Method2->getOverloadedOperator() &&
1330  Method1->isStatic() == Method2->isStatic() &&
1331  Method1->isConst() == Method2->isConst() &&
1332  Method1->isVolatile() == Method2->isVolatile() &&
1333  Method1->isVirtual() == Method2->isVirtual() &&
1334  Method1->isPure() == Method2->isPure() &&
1335  Method1->isDefaulted() == Method2->isDefaulted() &&
1336  Method1->isDeleted() == Method2->isDeleted();
1337  if (!PropertiesEqual)
1338  return false;
1339  // FIXME: Check for 'final'.
1340 
1341  if (auto *Constructor1 = dyn_cast<CXXConstructorDecl>(Method1)) {
1342  auto *Constructor2 = cast<CXXConstructorDecl>(Method2);
1343  if (!Constructor1->getExplicitSpecifier().isEquivalent(
1344  Constructor2->getExplicitSpecifier()))
1345  return false;
1346  }
1347 
1348  if (auto *Conversion1 = dyn_cast<CXXConversionDecl>(Method1)) {
1349  auto *Conversion2 = cast<CXXConversionDecl>(Method2);
1350  if (!Conversion1->getExplicitSpecifier().isEquivalent(
1351  Conversion2->getExplicitSpecifier()))
1352  return false;
1353  if (!IsStructurallyEquivalent(Context, Conversion1->getConversionType(),
1354  Conversion2->getConversionType()))
1355  return false;
1356  }
1357 
1358  const IdentifierInfo *Name1 = Method1->getIdentifier();
1359  const IdentifierInfo *Name2 = Method2->getIdentifier();
1360  if (!::IsStructurallyEquivalent(Name1, Name2)) {
1361  return false;
1362  // TODO: Names do not match, add warning like at check for FieldDecl.
1363  }
1364 
1365  // Check the prototypes.
1366  if (!::IsStructurallyEquivalent(Context,
1367  Method1->getType(), Method2->getType()))
1368  return false;
1369 
1370  return true;
1371 }
1372 
1373 /// Determine structural equivalence of two lambda classes.
1374 static bool
1376  CXXRecordDecl *D1, CXXRecordDecl *D2) {
1377  assert(D1->isLambda() && D2->isLambda() &&
1378  "Must be called on lambda classes");
1379  if (!IsStructurallyEquivalent(Context, D1->getLambdaCallOperator(),
1380  D2->getLambdaCallOperator()))
1381  return false;
1382 
1383  return true;
1384 }
1385 
1386 /// Determine if context of a class is equivalent.
1388  RecordDecl *D2) {
1389  // The context should be completely equal, including anonymous and inline
1390  // namespaces.
1391  // We compare objects as part of full translation units, not subtrees of
1392  // translation units.
1395  while (true) {
1396  // Special case: We allow a struct defined in a function to be equivalent
1397  // with a similar struct defined outside of a function.
1398  if ((DC1->isFunctionOrMethod() && DC2->isTranslationUnit()) ||
1399  (DC2->isFunctionOrMethod() && DC1->isTranslationUnit()))
1400  return true;
1401 
1402  if (DC1->getDeclKind() != DC2->getDeclKind())
1403  return false;
1404  if (DC1->isTranslationUnit())
1405  break;
1406  if (DC1->isInlineNamespace() != DC2->isInlineNamespace())
1407  return false;
1408  if (const auto *ND1 = dyn_cast<NamedDecl>(DC1)) {
1409  const auto *ND2 = cast<NamedDecl>(DC2);
1410  if (!DC1->isInlineNamespace() &&
1411  !IsStructurallyEquivalent(ND1->getIdentifier(), ND2->getIdentifier()))
1412  return false;
1413  }
1414 
1415  DC1 = DC1->getParent()->getNonTransparentContext();
1416  DC2 = DC2->getParent()->getNonTransparentContext();
1417  }
1418 
1419  return true;
1420 }
1421 
1422 /// Determine structural equivalence of two records.
1424  RecordDecl *D1, RecordDecl *D2) {
1425 
1426  // Check for equivalent structure names.
1427  IdentifierInfo *Name1 = D1->getIdentifier();
1428  if (!Name1 && D1->getTypedefNameForAnonDecl())
1429  Name1 = D1->getTypedefNameForAnonDecl()->getIdentifier();
1430  IdentifierInfo *Name2 = D2->getIdentifier();
1431  if (!Name2 && D2->getTypedefNameForAnonDecl())
1432  Name2 = D2->getTypedefNameForAnonDecl()->getIdentifier();
1433  if (!IsStructurallyEquivalent(Name1, Name2))
1434  return false;
1435 
1436  if (D1->isUnion() != D2->isUnion()) {
1437  if (Context.Complain) {
1438  Context.Diag2(D2->getLocation(), Context.getApplicableDiagnostic(
1439  diag::err_odr_tag_type_inconsistent))
1440  << Context.ToCtx.getTypeDeclType(D2);
1441  Context.Diag1(D1->getLocation(), diag::note_odr_tag_kind_here)
1442  << D1->getDeclName() << (unsigned)D1->getTagKind();
1443  }
1444  return false;
1445  }
1446 
1447  if (!D1->getDeclName() && !D2->getDeclName()) {
1448  // If both anonymous structs/unions are in a record context, make sure
1449  // they occur in the same location in the context records.
1450  if (Optional<unsigned> Index1 =
1452  if (Optional<unsigned> Index2 =
1454  D2)) {
1455  if (*Index1 != *Index2)
1456  return false;
1457  }
1458  }
1459  }
1460 
1461  // If the records occur in different context (namespace), these should be
1462  // different. This is specially important if the definition of one or both
1463  // records is missing.
1465  return false;
1466 
1467  // If both declarations are class template specializations, we know
1468  // the ODR applies, so check the template and template arguments.
1469  const auto *Spec1 = dyn_cast<ClassTemplateSpecializationDecl>(D1);
1470  const auto *Spec2 = dyn_cast<ClassTemplateSpecializationDecl>(D2);
1471  if (Spec1 && Spec2) {
1472  // Check that the specialized templates are the same.
1473  if (!IsStructurallyEquivalent(Context, Spec1->getSpecializedTemplate(),
1474  Spec2->getSpecializedTemplate()))
1475  return false;
1476 
1477  // Check that the template arguments are the same.
1478  if (Spec1->getTemplateArgs().size() != Spec2->getTemplateArgs().size())
1479  return false;
1480 
1481  for (unsigned I = 0, N = Spec1->getTemplateArgs().size(); I != N; ++I)
1482  if (!IsStructurallyEquivalent(Context, Spec1->getTemplateArgs().get(I),
1483  Spec2->getTemplateArgs().get(I)))
1484  return false;
1485  }
1486  // If one is a class template specialization and the other is not, these
1487  // structures are different.
1488  else if (Spec1 || Spec2)
1489  return false;
1490 
1491  // Compare the definitions of these two records. If either or both are
1492  // incomplete (i.e. it is a forward decl), we assume that they are
1493  // equivalent.
1494  D1 = D1->getDefinition();
1495  D2 = D2->getDefinition();
1496  if (!D1 || !D2)
1497  return true;
1498 
1499  // If any of the records has external storage and we do a minimal check (or
1500  // AST import) we assume they are equivalent. (If we didn't have this
1501  // assumption then `RecordDecl::LoadFieldsFromExternalStorage` could trigger
1502  // another AST import which in turn would call the structural equivalency
1503  // check again and finally we'd have an improper result.)
1504  if (Context.EqKind == StructuralEquivalenceKind::Minimal)
1506  return true;
1507 
1508  // If one definition is currently being defined, we do not compare for
1509  // equality and we assume that the decls are equal.
1510  if (D1->isBeingDefined() || D2->isBeingDefined())
1511  return true;
1512 
1513  if (auto *D1CXX = dyn_cast<CXXRecordDecl>(D1)) {
1514  if (auto *D2CXX = dyn_cast<CXXRecordDecl>(D2)) {
1515  if (D1CXX->hasExternalLexicalStorage() &&
1516  !D1CXX->isCompleteDefinition()) {
1517  D1CXX->getASTContext().getExternalSource()->CompleteType(D1CXX);
1518  }
1519 
1520  if (D1CXX->isLambda() != D2CXX->isLambda())
1521  return false;
1522  if (D1CXX->isLambda()) {
1523  if (!IsStructurallyEquivalentLambdas(Context, D1CXX, D2CXX))
1524  return false;
1525  }
1526 
1527  if (D1CXX->getNumBases() != D2CXX->getNumBases()) {
1528  if (Context.Complain) {
1529  Context.Diag2(D2->getLocation(),
1530  Context.getApplicableDiagnostic(
1531  diag::err_odr_tag_type_inconsistent))
1532  << Context.ToCtx.getTypeDeclType(D2);
1533  Context.Diag2(D2->getLocation(), diag::note_odr_number_of_bases)
1534  << D2CXX->getNumBases();
1535  Context.Diag1(D1->getLocation(), diag::note_odr_number_of_bases)
1536  << D1CXX->getNumBases();
1537  }
1538  return false;
1539  }
1540 
1541  // Check the base classes.
1542  for (CXXRecordDecl::base_class_iterator Base1 = D1CXX->bases_begin(),
1543  BaseEnd1 = D1CXX->bases_end(),
1544  Base2 = D2CXX->bases_begin();
1545  Base1 != BaseEnd1; ++Base1, ++Base2) {
1546  if (!IsStructurallyEquivalent(Context, Base1->getType(),
1547  Base2->getType())) {
1548  if (Context.Complain) {
1549  Context.Diag2(D2->getLocation(),
1550  Context.getApplicableDiagnostic(
1551  diag::err_odr_tag_type_inconsistent))
1552  << Context.ToCtx.getTypeDeclType(D2);
1553  Context.Diag2(Base2->getBeginLoc(), diag::note_odr_base)
1554  << Base2->getType() << Base2->getSourceRange();
1555  Context.Diag1(Base1->getBeginLoc(), diag::note_odr_base)
1556  << Base1->getType() << Base1->getSourceRange();
1557  }
1558  return false;
1559  }
1560 
1561  // Check virtual vs. non-virtual inheritance mismatch.
1562  if (Base1->isVirtual() != Base2->isVirtual()) {
1563  if (Context.Complain) {
1564  Context.Diag2(D2->getLocation(),
1565  Context.getApplicableDiagnostic(
1566  diag::err_odr_tag_type_inconsistent))
1567  << Context.ToCtx.getTypeDeclType(D2);
1568  Context.Diag2(Base2->getBeginLoc(), diag::note_odr_virtual_base)
1569  << Base2->isVirtual() << Base2->getSourceRange();
1570  Context.Diag1(Base1->getBeginLoc(), diag::note_odr_base)
1571  << Base1->isVirtual() << Base1->getSourceRange();
1572  }
1573  return false;
1574  }
1575  }
1576 
1577  // Check the friends for consistency.
1578  CXXRecordDecl::friend_iterator Friend2 = D2CXX->friend_begin(),
1579  Friend2End = D2CXX->friend_end();
1580  for (CXXRecordDecl::friend_iterator Friend1 = D1CXX->friend_begin(),
1581  Friend1End = D1CXX->friend_end();
1582  Friend1 != Friend1End; ++Friend1, ++Friend2) {
1583  if (Friend2 == Friend2End) {
1584  if (Context.Complain) {
1585  Context.Diag2(D2->getLocation(),
1586  Context.getApplicableDiagnostic(
1587  diag::err_odr_tag_type_inconsistent))
1588  << Context.ToCtx.getTypeDeclType(D2CXX);
1589  Context.Diag1((*Friend1)->getFriendLoc(), diag::note_odr_friend);
1590  Context.Diag2(D2->getLocation(), diag::note_odr_missing_friend);
1591  }
1592  return false;
1593  }
1594 
1595  if (!IsStructurallyEquivalent(Context, *Friend1, *Friend2)) {
1596  if (Context.Complain) {
1597  Context.Diag2(D2->getLocation(),
1598  Context.getApplicableDiagnostic(
1599  diag::err_odr_tag_type_inconsistent))
1600  << Context.ToCtx.getTypeDeclType(D2CXX);
1601  Context.Diag1((*Friend1)->getFriendLoc(), diag::note_odr_friend);
1602  Context.Diag2((*Friend2)->getFriendLoc(), diag::note_odr_friend);
1603  }
1604  return false;
1605  }
1606  }
1607 
1608  if (Friend2 != Friend2End) {
1609  if (Context.Complain) {
1610  Context.Diag2(D2->getLocation(),
1611  Context.getApplicableDiagnostic(
1612  diag::err_odr_tag_type_inconsistent))
1613  << Context.ToCtx.getTypeDeclType(D2);
1614  Context.Diag2((*Friend2)->getFriendLoc(), diag::note_odr_friend);
1615  Context.Diag1(D1->getLocation(), diag::note_odr_missing_friend);
1616  }
1617  return false;
1618  }
1619  } else if (D1CXX->getNumBases() > 0) {
1620  if (Context.Complain) {
1621  Context.Diag2(D2->getLocation(),
1622  Context.getApplicableDiagnostic(
1623  diag::err_odr_tag_type_inconsistent))
1624  << Context.ToCtx.getTypeDeclType(D2);
1625  const CXXBaseSpecifier *Base1 = D1CXX->bases_begin();
1626  Context.Diag1(Base1->getBeginLoc(), diag::note_odr_base)
1627  << Base1->getType() << Base1->getSourceRange();
1628  Context.Diag2(D2->getLocation(), diag::note_odr_missing_base);
1629  }
1630  return false;
1631  }
1632  }
1633 
1634  // Check the fields for consistency.
1635  QualType D2Type = Context.ToCtx.getTypeDeclType(D2);
1636  RecordDecl::field_iterator Field2 = D2->field_begin(),
1637  Field2End = D2->field_end();
1638  for (RecordDecl::field_iterator Field1 = D1->field_begin(),
1639  Field1End = D1->field_end();
1640  Field1 != Field1End; ++Field1, ++Field2) {
1641  if (Field2 == Field2End) {
1642  if (Context.Complain) {
1643  Context.Diag2(D2->getLocation(),
1644  Context.getApplicableDiagnostic(
1645  diag::err_odr_tag_type_inconsistent))
1646  << Context.ToCtx.getTypeDeclType(D2);
1647  Context.Diag1(Field1->getLocation(), diag::note_odr_field)
1648  << Field1->getDeclName() << Field1->getType();
1649  Context.Diag2(D2->getLocation(), diag::note_odr_missing_field);
1650  }
1651  return false;
1652  }
1653 
1654  if (!IsStructurallyEquivalent(Context, *Field1, *Field2, D2Type))
1655  return false;
1656  }
1657 
1658  if (Field2 != Field2End) {
1659  if (Context.Complain) {
1660  Context.Diag2(D2->getLocation(), Context.getApplicableDiagnostic(
1661  diag::err_odr_tag_type_inconsistent))
1662  << Context.ToCtx.getTypeDeclType(D2);
1663  Context.Diag2(Field2->getLocation(), diag::note_odr_field)
1664  << Field2->getDeclName() << Field2->getType();
1665  Context.Diag1(D1->getLocation(), diag::note_odr_missing_field);
1666  }
1667  return false;
1668  }
1669 
1670  return true;
1671 }
1672 
1674  EnumConstantDecl *D1,
1675  EnumConstantDecl *D2) {
1676  const llvm::APSInt &FromVal = D1->getInitVal();
1677  const llvm::APSInt &ToVal = D2->getInitVal();
1678  if (FromVal.isSigned() != ToVal.isSigned())
1679  return false;
1680  if (FromVal.getBitWidth() != ToVal.getBitWidth())
1681  return false;
1682  if (FromVal != ToVal)
1683  return false;
1684 
1686  return false;
1687 
1688  // Init expressions are the most expensive check, so do them last.
1689  return IsStructurallyEquivalent(Context, D1->getInitExpr(),
1690  D2->getInitExpr());
1691 }
1692 
1693 /// Determine structural equivalence of two enums.
1695  EnumDecl *D1, EnumDecl *D2) {
1696 
1697  // Check for equivalent enum names.
1698  IdentifierInfo *Name1 = D1->getIdentifier();
1699  if (!Name1 && D1->getTypedefNameForAnonDecl())
1700  Name1 = D1->getTypedefNameForAnonDecl()->getIdentifier();
1701  IdentifierInfo *Name2 = D2->getIdentifier();
1702  if (!Name2 && D2->getTypedefNameForAnonDecl())
1703  Name2 = D2->getTypedefNameForAnonDecl()->getIdentifier();
1704  if (!IsStructurallyEquivalent(Name1, Name2))
1705  return false;
1706 
1707  // Compare the definitions of these two enums. If either or both are
1708  // incomplete (i.e. forward declared), we assume that they are equivalent.
1709  D1 = D1->getDefinition();
1710  D2 = D2->getDefinition();
1711  if (!D1 || !D2)
1712  return true;
1713 
1715  EC2End = D2->enumerator_end();
1717  EC1End = D1->enumerator_end();
1718  EC1 != EC1End; ++EC1, ++EC2) {
1719  if (EC2 == EC2End) {
1720  if (Context.Complain) {
1721  Context.Diag2(D2->getLocation(),
1722  Context.getApplicableDiagnostic(
1723  diag::err_odr_tag_type_inconsistent))
1724  << Context.ToCtx.getTypeDeclType(D2);
1725  Context.Diag1(EC1->getLocation(), diag::note_odr_enumerator)
1726  << EC1->getDeclName() << toString(EC1->getInitVal(), 10);
1727  Context.Diag2(D2->getLocation(), diag::note_odr_missing_enumerator);
1728  }
1729  return false;
1730  }
1731 
1732  llvm::APSInt Val1 = EC1->getInitVal();
1733  llvm::APSInt Val2 = EC2->getInitVal();
1734  if (!llvm::APSInt::isSameValue(Val1, Val2) ||
1735  !IsStructurallyEquivalent(EC1->getIdentifier(), EC2->getIdentifier())) {
1736  if (Context.Complain) {
1737  Context.Diag2(D2->getLocation(),
1738  Context.getApplicableDiagnostic(
1739  diag::err_odr_tag_type_inconsistent))
1740  << Context.ToCtx.getTypeDeclType(D2);
1741  Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
1742  << EC2->getDeclName() << toString(EC2->getInitVal(), 10);
1743  Context.Diag1(EC1->getLocation(), diag::note_odr_enumerator)
1744  << EC1->getDeclName() << toString(EC1->getInitVal(), 10);
1745  }
1746  return false;
1747  }
1748  }
1749 
1750  if (EC2 != EC2End) {
1751  if (Context.Complain) {
1752  Context.Diag2(D2->getLocation(), Context.getApplicableDiagnostic(
1753  diag::err_odr_tag_type_inconsistent))
1754  << Context.ToCtx.getTypeDeclType(D2);
1755  Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
1756  << EC2->getDeclName() << toString(EC2->getInitVal(), 10);
1757  Context.Diag1(D1->getLocation(), diag::note_odr_missing_enumerator);
1758  }
1759  return false;
1760  }
1761 
1762  return true;
1763 }
1764 
1766  TemplateParameterList *Params1,
1767  TemplateParameterList *Params2) {
1768  if (Params1->size() != Params2->size()) {
1769  if (Context.Complain) {
1770  Context.Diag2(Params2->getTemplateLoc(),
1771  Context.getApplicableDiagnostic(
1772  diag::err_odr_different_num_template_parameters))
1773  << Params1->size() << Params2->size();
1774  Context.Diag1(Params1->getTemplateLoc(),
1775  diag::note_odr_template_parameter_list);
1776  }
1777  return false;
1778  }
1779 
1780  for (unsigned I = 0, N = Params1->size(); I != N; ++I) {
1781  if (Params1->getParam(I)->getKind() != Params2->getParam(I)->getKind()) {
1782  if (Context.Complain) {
1783  Context.Diag2(Params2->getParam(I)->getLocation(),
1784  Context.getApplicableDiagnostic(
1785  diag::err_odr_different_template_parameter_kind));
1786  Context.Diag1(Params1->getParam(I)->getLocation(),
1787  diag::note_odr_template_parameter_here);
1788  }
1789  return false;
1790  }
1791 
1792  if (!IsStructurallyEquivalent(Context, Params1->getParam(I),
1793  Params2->getParam(I)))
1794  return false;
1795  }
1796 
1797  return true;
1798 }
1799 
1802  TemplateTypeParmDecl *D2) {
1803  if (D1->isParameterPack() != D2->isParameterPack()) {
1804  if (Context.Complain) {
1805  Context.Diag2(D2->getLocation(),
1806  Context.getApplicableDiagnostic(
1807  diag::err_odr_parameter_pack_non_pack))
1808  << D2->isParameterPack();
1809  Context.Diag1(D1->getLocation(), diag::note_odr_parameter_pack_non_pack)
1810  << D1->isParameterPack();
1811  }
1812  return false;
1813  }
1814 
1815  return true;
1816 }
1817 
1821  if (D1->isParameterPack() != D2->isParameterPack()) {
1822  if (Context.Complain) {
1823  Context.Diag2(D2->getLocation(),
1824  Context.getApplicableDiagnostic(
1825  diag::err_odr_parameter_pack_non_pack))
1826  << D2->isParameterPack();
1827  Context.Diag1(D1->getLocation(), diag::note_odr_parameter_pack_non_pack)
1828  << D1->isParameterPack();
1829  }
1830  return false;
1831  }
1832 
1833  // Check types.
1834  if (!IsStructurallyEquivalent(Context, D1->getType(), D2->getType())) {
1835  if (Context.Complain) {
1836  Context.Diag2(D2->getLocation(),
1837  Context.getApplicableDiagnostic(
1838  diag::err_odr_non_type_parameter_type_inconsistent))
1839  << D2->getType() << D1->getType();
1840  Context.Diag1(D1->getLocation(), diag::note_odr_value_here)
1841  << D1->getType();
1842  }
1843  return false;
1844  }
1845 
1846  return true;
1847 }
1848 
1852  if (D1->isParameterPack() != D2->isParameterPack()) {
1853  if (Context.Complain) {
1854  Context.Diag2(D2->getLocation(),
1855  Context.getApplicableDiagnostic(
1856  diag::err_odr_parameter_pack_non_pack))
1857  << D2->isParameterPack();
1858  Context.Diag1(D1->getLocation(), diag::note_odr_parameter_pack_non_pack)
1859  << D1->isParameterPack();
1860  }
1861  return false;
1862  }
1863 
1864  // Check template parameter lists.
1865  return IsStructurallyEquivalent(Context, D1->getTemplateParameters(),
1866  D2->getTemplateParameters());
1867 }
1868 
1872  return false;
1873  if (!D1->getIdentifier()) // Special name
1874  if (D1->getNameAsString() != D2->getNameAsString())
1875  return false;
1877  D2->getTemplateParameters());
1878 }
1879 
1881  ClassTemplateDecl *D1,
1882  ClassTemplateDecl *D2) {
1883  // Check template parameters.
1884  if (!IsTemplateDeclCommonStructurallyEquivalent(Context, D1, D2))
1885  return false;
1886 
1887  // Check the templated declaration.
1888  return IsStructurallyEquivalent(Context, D1->getTemplatedDecl(),
1889  D2->getTemplatedDecl());
1890 }
1891 
1894  FunctionTemplateDecl *D2) {
1895  // Check template parameters.
1896  if (!IsTemplateDeclCommonStructurallyEquivalent(Context, D1, D2))
1897  return false;
1898 
1899  // Check the templated declaration.
1900  return IsStructurallyEquivalent(Context, D1->getTemplatedDecl()->getType(),
1901  D2->getTemplatedDecl()->getType());
1902 }
1903 
1905  ConceptDecl *D1,
1906  ConceptDecl *D2) {
1907  // Check template parameters.
1908  if (!IsTemplateDeclCommonStructurallyEquivalent(Context, D1, D2))
1909  return false;
1910 
1911  // Check the constraint expression.
1912  return IsStructurallyEquivalent(Context, D1->getConstraintExpr(),
1913  D2->getConstraintExpr());
1914 }
1915 
1917  FriendDecl *D1, FriendDecl *D2) {
1918  if ((D1->getFriendType() && D2->getFriendDecl()) ||
1919  (D1->getFriendDecl() && D2->getFriendType())) {
1920  return false;
1921  }
1922  if (D1->getFriendType() && D2->getFriendType())
1923  return IsStructurallyEquivalent(Context,
1924  D1->getFriendType()->getType(),
1925  D2->getFriendType()->getType());
1926  if (D1->getFriendDecl() && D2->getFriendDecl())
1927  return IsStructurallyEquivalent(Context, D1->getFriendDecl(),
1928  D2->getFriendDecl());
1929  return false;
1930 }
1931 
1933  TypedefNameDecl *D1, TypedefNameDecl *D2) {
1935  return false;
1936 
1937  return IsStructurallyEquivalent(Context, D1->getUnderlyingType(),
1938  D2->getUnderlyingType());
1939 }
1940 
1942  FunctionDecl *D1, FunctionDecl *D2) {
1944  return false;
1945 
1946  if (D1->isOverloadedOperator()) {
1947  if (!D2->isOverloadedOperator())
1948  return false;
1949  if (D1->getOverloadedOperator() != D2->getOverloadedOperator())
1950  return false;
1951  }
1952 
1953  // FIXME: Consider checking for function attributes as well.
1954  if (!IsStructurallyEquivalent(Context, D1->getType(), D2->getType()))
1955  return false;
1956 
1957  return true;
1958 }
1959 
1961  ObjCIvarDecl *D1, ObjCIvarDecl *D2,
1962  QualType Owner2Type) {
1963  if (D1->getAccessControl() != D2->getAccessControl())
1964  return false;
1965 
1966  return IsStructurallyEquivalent(Context, cast<FieldDecl>(D1),
1967  cast<FieldDecl>(D2), Owner2Type);
1968 }
1969 
1971  ObjCIvarDecl *D1, ObjCIvarDecl *D2) {
1972  QualType Owner2Type =
1973  Context.ToCtx.getObjCInterfaceType(D2->getContainingInterface());
1974  return IsStructurallyEquivalent(Context, D1, D2, Owner2Type);
1975 }
1976 
1978  ObjCMethodDecl *Method1,
1979  ObjCMethodDecl *Method2) {
1980  bool PropertiesEqual =
1981  Method1->isInstanceMethod() == Method2->isInstanceMethod() &&
1982  Method1->isVariadic() == Method2->isVariadic() &&
1983  Method1->isDirectMethod() == Method2->isDirectMethod();
1984  if (!PropertiesEqual)
1985  return false;
1986 
1987  // Compare selector slot names.
1988  Selector Selector1 = Method1->getSelector(),
1989  Selector2 = Method2->getSelector();
1990  unsigned NumArgs = Selector1.getNumArgs();
1991  if (NumArgs != Selector2.getNumArgs())
1992  return false;
1993  // Compare all selector slots. For selectors with arguments it means all arg
1994  // slots. And if there are no arguments, compare the first-and-only slot.
1995  unsigned SlotsToCheck = NumArgs > 0 ? NumArgs : 1;
1996  for (unsigned I = 0; I < SlotsToCheck; ++I) {
1998  Selector2.getIdentifierInfoForSlot(I)))
1999  return false;
2000  }
2001 
2002  // Compare types.
2003  if (!IsStructurallyEquivalent(Context, Method1->getReturnType(),
2004  Method2->getReturnType()))
2005  return false;
2006  assert(
2007  Method1->param_size() == Method2->param_size() &&
2008  "Same number of arguments should be already enforced in Selector checks");
2010  ParamT1 = Method1->param_type_begin(),
2011  ParamT1End = Method1->param_type_end(),
2012  ParamT2 = Method2->param_type_begin(),
2013  ParamT2End = Method2->param_type_end();
2014  (ParamT1 != ParamT1End) && (ParamT2 != ParamT2End);
2015  ++ParamT1, ++ParamT2) {
2016  if (!IsStructurallyEquivalent(Context, *ParamT1, *ParamT2))
2017  return false;
2018  }
2019 
2020  return true;
2021 }
2022 
2024  ObjCCategoryDecl *D1,
2025  ObjCCategoryDecl *D2) {
2027  return false;
2028 
2030  D2->getClassInterface()->getIdentifier()))
2031  return false;
2032 
2033  // Compare protocols.
2035  Protocol2End = D2->protocol_end();
2036  for (ObjCCategoryDecl::protocol_iterator Protocol1 = D1->protocol_begin(),
2037  Protocol1End = D1->protocol_end();
2038  Protocol1 != Protocol1End; ++Protocol1, ++Protocol2) {
2039  if (Protocol2 == Protocol2End)
2040  return false;
2041  if (!IsStructurallyEquivalent((*Protocol1)->getIdentifier(),
2042  (*Protocol2)->getIdentifier()))
2043  return false;
2044  }
2045  if (Protocol2 != Protocol2End)
2046  return false;
2047 
2048  // Compare ivars.
2049  QualType D2Type = Context.ToCtx.getObjCInterfaceType(D2->getClassInterface());
2051  Ivar2End = D2->ivar_end();
2052  for (ObjCCategoryDecl::ivar_iterator Ivar1 = D1->ivar_begin(),
2053  Ivar1End = D1->ivar_end();
2054  Ivar1 != Ivar1End; ++Ivar1, ++Ivar2) {
2055  if (Ivar2 == Ivar2End)
2056  return false;
2057  if (!IsStructurallyEquivalent(Context, *Ivar1, *Ivar2, D2Type))
2058  return false;
2059  }
2060  if (Ivar2 != Ivar2End)
2061  return false;
2062 
2063  // Compare methods.
2065  Method2End = D2->meth_end();
2066  for (ObjCCategoryDecl::method_iterator Method1 = D1->meth_begin(),
2067  Method1End = D1->meth_end();
2068  Method1 != Method1End; ++Method1, ++Method2) {
2069  if (Method2 == Method2End)
2070  return false;
2071  if (!IsStructurallyEquivalent(Context, *Method1, *Method2))
2072  return false;
2073  }
2074  if (Method2 != Method2End)
2075  return false;
2076 
2077  return true;
2078 }
2079 
2080 /// Determine structural equivalence of two declarations.
2082  Decl *D1, Decl *D2) {
2083  // FIXME: Check for known structural equivalences via a callback of some sort.
2084 
2085  D1 = D1->getCanonicalDecl();
2086  D2 = D2->getCanonicalDecl();
2087  std::pair<Decl *, Decl *> P{D1, D2};
2088 
2089  // Check whether we already know that these two declarations are not
2090  // structurally equivalent.
2091  if (Context.NonEquivalentDecls.count(P))
2092  return false;
2093 
2094  // Check if a check for these declarations is already pending.
2095  // If yes D1 and D2 will be checked later (from DeclsToCheck),
2096  // or these are already checked (and equivalent).
2097  bool Inserted = Context.VisitedDecls.insert(P).second;
2098  if (!Inserted)
2099  return true;
2100 
2101  Context.DeclsToCheck.push(P);
2102 
2103  return true;
2104 }
2105 
2107  unsigned DiagID) {
2108  assert(Complain && "Not allowed to complain");
2109  if (LastDiagFromC2)
2111  LastDiagFromC2 = false;
2112  return FromCtx.getDiagnostics().Report(Loc, DiagID);
2113 }
2114 
2116  unsigned DiagID) {
2117  assert(Complain && "Not allowed to complain");
2118  if (!LastDiagFromC2)
2120  LastDiagFromC2 = true;
2121  return ToCtx.getDiagnostics().Report(Loc, DiagID);
2122 }
2123 
2126  ASTContext &Context = Anon->getASTContext();
2127  QualType AnonTy = Context.getRecordType(Anon);
2128 
2129  const auto *Owner = dyn_cast<RecordDecl>(Anon->getDeclContext());
2130  if (!Owner)
2131  return None;
2132 
2133  unsigned Index = 0;
2134  for (const auto *D : Owner->noload_decls()) {
2135  const auto *F = dyn_cast<FieldDecl>(D);
2136  if (!F)
2137  continue;
2138 
2139  if (F->isAnonymousStructOrUnion()) {
2140  if (Context.hasSameType(F->getType(), AnonTy))
2141  break;
2142  ++Index;
2143  continue;
2144  }
2145 
2146  // If the field looks like this:
2147  // struct { ... } A;
2148  QualType FieldType = F->getType();
2149  // In case of nested structs.
2150  while (const auto *ElabType = dyn_cast<ElaboratedType>(FieldType))
2151  FieldType = ElabType->getNamedType();
2152 
2153  if (const auto *RecType = dyn_cast<RecordType>(FieldType)) {
2154  const RecordDecl *RecDecl = RecType->getDecl();
2155  if (RecDecl->getDeclContext() == Owner && !RecDecl->getIdentifier()) {
2156  if (Context.hasSameType(FieldType, AnonTy))
2157  break;
2158  ++Index;
2159  continue;
2160  }
2161  }
2162  }
2163 
2164  return Index;
2165 }
2166 
2168  unsigned ErrorDiagnostic) {
2170  return ErrorDiagnostic;
2171 
2172  switch (ErrorDiagnostic) {
2173  case diag::err_odr_variable_type_inconsistent:
2174  return diag::warn_odr_variable_type_inconsistent;
2175  case diag::err_odr_variable_multiple_def:
2176  return diag::warn_odr_variable_multiple_def;
2177  case diag::err_odr_function_type_inconsistent:
2178  return diag::warn_odr_function_type_inconsistent;
2179  case diag::err_odr_tag_type_inconsistent:
2180  return diag::warn_odr_tag_type_inconsistent;
2181  case diag::err_odr_field_type_inconsistent:
2182  return diag::warn_odr_field_type_inconsistent;
2183  case diag::err_odr_ivar_type_inconsistent:
2184  return diag::warn_odr_ivar_type_inconsistent;
2185  case diag::err_odr_objc_superclass_inconsistent:
2186  return diag::warn_odr_objc_superclass_inconsistent;
2187  case diag::err_odr_objc_method_result_type_inconsistent:
2188  return diag::warn_odr_objc_method_result_type_inconsistent;
2189  case diag::err_odr_objc_method_num_params_inconsistent:
2190  return diag::warn_odr_objc_method_num_params_inconsistent;
2191  case diag::err_odr_objc_method_param_type_inconsistent:
2192  return diag::warn_odr_objc_method_param_type_inconsistent;
2193  case diag::err_odr_objc_method_variadic_inconsistent:
2194  return diag::warn_odr_objc_method_variadic_inconsistent;
2195  case diag::err_odr_objc_property_type_inconsistent:
2196  return diag::warn_odr_objc_property_type_inconsistent;
2197  case diag::err_odr_objc_property_impl_kind_inconsistent:
2198  return diag::warn_odr_objc_property_impl_kind_inconsistent;
2199  case diag::err_odr_objc_synthesize_ivar_inconsistent:
2200  return diag::warn_odr_objc_synthesize_ivar_inconsistent;
2201  case diag::err_odr_different_num_template_parameters:
2202  return diag::warn_odr_different_num_template_parameters;
2203  case diag::err_odr_different_template_parameter_kind:
2204  return diag::warn_odr_different_template_parameter_kind;
2205  case diag::err_odr_parameter_pack_non_pack:
2206  return diag::warn_odr_parameter_pack_non_pack;
2207  case diag::err_odr_non_type_parameter_type_inconsistent:
2208  return diag::warn_odr_non_type_parameter_type_inconsistent;
2209  }
2210  llvm_unreachable("Diagnostic kind not handled in preceding switch");
2211 }
2212 
2214 
2215  // Ensure that the implementation functions (all static functions in this TU)
2216  // never call the public ASTStructuralEquivalence::IsEquivalent() functions,
2217  // because that will wreak havoc the internal state (DeclsToCheck and
2218  // VisitedDecls members) and can cause faulty behaviour.
2219  // In other words: Do not start a graph search from a new node with the
2220  // internal data of another search in progress.
2221  // FIXME: Better encapsulation and separation of internal and public
2222  // functionality.
2223  assert(DeclsToCheck.empty());
2224  assert(VisitedDecls.empty());
2225 
2226  if (!::IsStructurallyEquivalent(*this, D1, D2))
2227  return false;
2228 
2229  return !Finish();
2230 }
2231 
2233  assert(DeclsToCheck.empty());
2234  assert(VisitedDecls.empty());
2235  if (!::IsStructurallyEquivalent(*this, T1, T2))
2236  return false;
2237 
2238  return !Finish();
2239 }
2240 
2242  assert(DeclsToCheck.empty());
2243  assert(VisitedDecls.empty());
2244  if (!::IsStructurallyEquivalent(*this, S1, S2))
2245  return false;
2246 
2247  return !Finish();
2248 }
2249 
2250 bool StructuralEquivalenceContext::CheckCommonEquivalence(Decl *D1, Decl *D2) {
2251  // Check for equivalent described template.
2252  TemplateDecl *Template1 = D1->getDescribedTemplate();
2253  TemplateDecl *Template2 = D2->getDescribedTemplate();
2254  if ((Template1 != nullptr) != (Template2 != nullptr))
2255  return false;
2256  if (Template1 && !IsStructurallyEquivalent(*this, Template1, Template2))
2257  return false;
2258 
2259  // FIXME: Move check for identifier names into this function.
2260 
2261  return true;
2262 }
2263 
2264 bool StructuralEquivalenceContext::CheckKindSpecificEquivalence(
2265  Decl *D1, Decl *D2) {
2266 
2267  // Kind mismatch.
2268  if (D1->getKind() != D2->getKind())
2269  return false;
2270 
2271  // Cast the Decls to their actual subclass so that the right overload of
2272  // IsStructurallyEquivalent is called.
2273  switch (D1->getKind()) {
2274 #define ABSTRACT_DECL(DECL)
2275 #define DECL(DERIVED, BASE) \
2276  case Decl::Kind::DERIVED: \
2277  return ::IsStructurallyEquivalent(*this, static_cast<DERIVED##Decl *>(D1), \
2278  static_cast<DERIVED##Decl *>(D2));
2279 #include "clang/AST/DeclNodes.inc"
2280  }
2281  return true;
2282 }
2283 
2284 bool StructuralEquivalenceContext::Finish() {
2285  while (!DeclsToCheck.empty()) {
2286  // Check the next declaration.
2287  std::pair<Decl *, Decl *> P = DeclsToCheck.front();
2288  DeclsToCheck.pop();
2289 
2290  Decl *D1 = P.first;
2291  Decl *D2 = P.second;
2292 
2293  bool Equivalent =
2294  CheckCommonEquivalence(D1, D2) && CheckKindSpecificEquivalence(D1, D2);
2295 
2296  if (!Equivalent) {
2297  // Note that these two declarations are not equivalent (and we already
2298  // know about it).
2299  NonEquivalentDecls.insert(P);
2300 
2301  return true;
2302  }
2303  }
2304 
2305  return false;
2306 }
clang::DependentTemplateName::isOverloadedOperator
bool isOverloadedOperator() const
Determine whether this template name refers to an overloaded operator.
Definition: TemplateName.h:558
clang::ExpressionTraitExpr
An expression trait intrinsic.
Definition: ExprCXX.h:2847
clang::StructuralEquivalenceContext::IsEquivalent
bool IsEquivalent(Decl *D1, Decl *D2)
Determine whether the two declarations are structurally equivalent.
Definition: ASTStructuralEquivalence.cpp:2213
clang::SubstNonTypeTemplateParmExpr
Represents a reference to a non-type template parameter that has been substituted with a template arg...
Definition: ExprCXX.h:4269
clang::AtomicExpr
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
Definition: Expr.h:6239
clang::ConceptDecl::getConstraintExpr
Expr * getConstraintExpr() const
Definition: DeclTemplate.h:3277
clang::Decl::getASTContext
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:428
clang::FunctionDecl::isDefaulted
bool isDefaulted() const
Whether this function is defaulted.
Definition: Decl.h:2269
clang::SubstTemplateTemplateParmPackStorage::getArgumentPack
TemplateArgument getArgumentPack() const
Retrieve the template template argument pack with which this parameter was substituted.
Definition: TemplateName.cpp:37
clang::ExpressionTraitExpr::getValue
bool getValue() const
Definition: ExprCXX.h:2886
clang::RecordDecl::field_begin
field_iterator field_begin() const
Definition: Decl.cpp:4754
clang::NestedNameSpecifier::Identifier
@ Identifier
An identifier, stored as an IdentifierInfo*.
Definition: NestedNameSpecifier.h:81
clang::CXXBaseSpecifier::getType
QualType getType() const
Retrieves the type of the base class.
Definition: DeclCXX.h:245
clang::NestedNameSpecifier::getAsRecordDecl
CXXRecordDecl * getAsRecordDecl() const
Retrieve the record declaration stored in this nested name specifier.
Definition: NestedNameSpecifier.cpp:185
clang::ASTContext::getTypeDeclType
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
Definition: ASTContext.h:1583
clang::EnumDecl::enumerator_end
enumerator_iterator enumerator_end() const
Definition: Decl.h:3849
clang::NestedNameSpecifier::Super
@ Super
Microsoft's '__super' specifier, stored as a CXXRecordDecl* of the class it appeared in.
Definition: NestedNameSpecifier.h:101
clang::FunctionProtoType::getExceptionSpecType
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
Definition: Type.h:4252
clang::DiagnosticBuilder
A little helper class used to produce diagnostics.
Definition: Diagnostic.h:1266
clang::DeclContext::specific_decl_iterator
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext,...
Definition: DeclBase.h:2198
clang::TypeSourceInfo::getType
QualType getType() const
Return the type wrapped by this type source info.
Definition: Type.h:6604
clang::CXXMethodDecl::isStatic
bool isStatic() const
Definition: DeclCXX.cpp:2128
clang::DeclContext::hasExternalLexicalStorage
bool hasExternalLexicalStorage() const
Whether this DeclContext has external storage containing additional declarations that are lexically i...
Definition: DeclBase.h:2493
clang::DeclarationName::Identifier
@ Identifier
Definition: DeclarationName.h:209
clang::DeclarationName::CXXLiteralOperatorName
@ CXXLiteralOperatorName
Definition: DeclarationName.h:219
clang::SubstTemplateTemplateParmPackStorage::getAssociatedDecl
Decl * getAssociatedDecl() const
A template-like entity which owns the whole pattern being substituted.
Definition: TemplateName.cpp:85
clang::DeclContext
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1389
clang::TemplateArgument::getAsTemplateOrTemplatePattern
TemplateName getAsTemplateOrTemplatePattern() const
Retrieve the template argument as a template name; if the argument is a pack expansion,...
Definition: TemplateBase.h:299
clang::TemplateArgument::pack_elements
ArrayRef< TemplateArgument > pack_elements() const
Iterator range referencing all of the elements of a template argument pack.
Definition: TemplateBase.h:365
clang::ObjCMethodDecl::param_type_end
param_type_iterator param_type_end() const
Definition: DeclObjC.h:408
clang::TemplateArgument::Null
@ Null
Represents an empty template argument, e.g., one that has not been deduced.
Definition: TemplateBase.h:67
clang::FloatingLiteral::getValue
llvm::APFloat getValue() const
Definition: Expr.h:1662
clang::FunctionDecl::isDeleted
bool isDeleted() const
Whether this function has been deleted.
Definition: Decl.h:2409
clang::SubstNonTypeTemplateParmPackExpr
Represents a reference to a non-type template parameter pack that has been substituted with a non-tem...
Definition: ExprCXX.h:4354
clang::DeclarationName::CXXConstructorName
@ CXXConstructorName
Definition: DeclarationName.h:212
clang::NestedNameSpecifier::NamespaceAlias
@ NamespaceAlias
A namespace alias, stored as a NamespaceAliasDecl*.
Definition: NestedNameSpecifier.h:87
clang::SourceLocation
Encodes a location in the source.
Definition: SourceLocation.h:86
clang::QualType::getQualifiers
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Definition: Type.h:6662
clang::AtomicExpr::getOp
AtomicOp getOp() const
Definition: Expr.h:6303
clang::StructuralEquivalenceContext::DeclsToCheck
std::queue< std::pair< Decl *, Decl * > > DeclsToCheck
Definition: ASTStructuralEquivalence.h:47
clang::CharacterLiteral::getValue
unsigned getValue() const
Definition: Expr.h:1627
clang::TemplateArgument::getIntegralType
QualType getIntegralType() const
Retrieve the type of the integral value.
Definition: TemplateBase.h:326
clang::QualType
A (possibly-)qualified type.
Definition: Type.h:737
clang::NonTypeTemplateParmDecl
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
Definition: DeclTemplate.h:1410
clang::TemplateName::getAsTemplateDecl
TemplateDecl * getAsTemplateDecl() const
Retrieve the underlying template declaration that this template name refers to, if known.
Definition: TemplateName.cpp:146
clang::NestedNameSpecifier
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
Definition: NestedNameSpecifier.h:50
clang::ObjCCategoryDecl::protocol_begin
protocol_iterator protocol_begin() const
Definition: DeclObjC.h:2374
clang::ObjCIvarDecl::getAccessControl
AccessControl getAccessControl() const
Definition: DeclObjC.h:1970
clang::TypeTraitExpr
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
Definition: ExprCXX.h:2689
clang::FieldDecl
Represents a member of a struct/union/class.
Definition: Decl.h:2930
clang::EST_Dynamic
@ EST_Dynamic
throw(T1, T2)
Definition: ExceptionSpecificationType.h:23
clang::FunctionType::ExtInfo::getNoCallerSavedRegs
bool getNoCallerSavedRegs() const
Definition: Type.h:3837
clang::isUnresolvedExceptionSpec
bool isUnresolvedExceptionSpec(ExceptionSpecificationType ESpecType)
Definition: ExceptionSpecificationType.h:49
clang::OverloadedTemplateStorage
A structure for storing the information associated with an overloaded template name.
Definition: TemplateName.h:107
DeclCXX.h
clang::ObjCCategoryDecl::getClassInterface
ObjCInterfaceDecl * getClassInterface()
Definition: DeclObjC.h:2339
ASTStructuralEquivalence.h
clang::TemplateArgument::Declaration
@ Declaration
The template argument is a declaration that was provided for a pointer, reference,...
Definition: TemplateBase.h:74
clang::EnumConstantDecl::getInitExpr
const Expr * getInitExpr() const
Definition: Decl.h:3164
clang::DeclarationName::CXXDeductionGuideName
@ CXXDeductionGuideName
Definition: DeclarationName.h:216
clang::FunctionDecl::isOverloadedOperator
bool isOverloadedOperator() const
Whether this function declaration represents an C++ overloaded operator, e.g., "operator+".
Definition: Decl.h:2713
DeclOpenMP.h
llvm::Optional
Definition: LLVM.h:40
clang::ExpressionTraitExpr::getTrait
ExpressionTrait getTrait() const
Definition: ExprCXX.h:2882
clang::RecordDecl::getDefinition
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
Definition: Decl.h:4194
clang::UnaryOperator
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition: Expr.h:2172
clang::TemplateName::getAsOverloadedTemplate
OverloadedTemplateStorage * getAsOverloadedTemplate() const
Retrieve the underlying, overloaded function template declarations that this template name refers to,...
Definition: TemplateName.cpp:167
clang::TagDecl::getTypedefNameForAnonDecl
TypedefNameDecl * getTypedefNameForAnonDecl() const
Definition: Decl.h:3651
clang::StructuralEquivalenceContext::findUntaggedStructOrUnionIndex
static llvm::Optional< unsigned > findUntaggedStructOrUnionIndex(RecordDecl *Anon)
Find the index of the given anonymous struct/union within its context.
Definition: ASTStructuralEquivalence.cpp:2125
clang::isComputedNoexcept
bool isComputedNoexcept(ExceptionSpecificationType ESpecType)
Definition: ExceptionSpecificationType.h:39
clang::CallExpr::getCalleeDecl
Decl * getCalleeDecl()
Definition: Expr.h:2974
ExprOpenMP.h
clang::BinaryOperator::getOpcode
Opcode getOpcode() const
Definition: Expr.h:3856
clang::DeclarationName::getAsIdentifierInfo
IdentifierInfo * getAsIdentifierInfo() const
Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...
Definition: DeclarationName.h:419
clang::DeclContext::isInlineNamespace
bool isInlineNamespace() const
Definition: DeclBase.cpp:1152
clang::DependentScopeDeclRefExpr::getQualifier
NestedNameSpecifier * getQualifier() const
Retrieve the nested-name-specifier that qualifies this declaration.
Definition: ExprCXX.h:3271
clang::TemplateArgument::getAsExpr
Expr * getAsExpr() const
Retrieve the template argument as an expression.
Definition: TemplateBase.h:341
TemplateName.h
clang::DeclarationName::getCXXDeductionGuideTemplate
TemplateDecl * getCXXDeductionGuideTemplate() const
If this name is the name of a C++ deduction guide, return the template associated with that name.
Definition: DeclarationName.h:460
clang::DeclarationName
The name of a declaration.
Definition: DeclarationName.h:144
clang::DependentScopeDeclRefExpr::getDeclName
DeclarationName getDeclName() const
Retrieve the name that this expression refers to.
Definition: ExprCXX.h:3258
clang::TemplateArgument::Expression
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
Definition: TemplateBase.h:96
clang::CompoundStmt::size
unsigned size() const
Definition: Stmt.h:1455
clang::TemplateArgument::getAsIntegral
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
Definition: TemplateBase.h:312
Paren
@ Paren
Definition: PPMacroExpansion.cpp:638
clang::DependentSizedMatrixType
Represents a matrix type where the type and the number of rows and columns is dependent on a template...
Definition: Type.h:3643
clang::CXXRecordDecl::getLambdaCallOperator
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
Definition: DeclCXX.cpp:1540
clang::EnumDecl
Represents an enum.
Definition: Decl.h:3705
clang::DeclContext::getNonTransparentContext
DeclContext * getNonTransparentContext()
Definition: DeclBase.cpp:1254
Decl.h
clang::Stmt::NoStmtClass
@ NoStmtClass
Definition: Stmt.h:74
DeclObjC.h
clang::ObjCIvarDecl::getContainingInterface
ObjCInterfaceDecl * getContainingInterface()
Return the class interface that this ivar is logically contained in; this is either the interface whe...
Definition: DeclObjC.cpp:1844
clang::TemplateArgument::Integral
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
Definition: TemplateBase.h:82
ExprConcepts.h
APSInt
llvm::APSInt APSInt
Definition: ByteCodeEmitter.cpp:19
clang::TemplateArgument::NullPtr
@ NullPtr
The template argument is a null pointer or null pointer to member that was provided for a non-type te...
Definition: TemplateBase.h:78
clang::FunctionTemplateDecl
Declaration of a template function.
Definition: DeclTemplate.h:1006
TemplateBase.h
clang::IntegerLiteral
Definition: Expr.h:1503
clang::ASTContext::getExternalSource
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any.
Definition: ASTContext.h:1194
IsStructurallyEquivalent
static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, QualType T1, QualType T2)
Determine structural equivalence of two types.
Definition: ASTStructuralEquivalence.cpp:675
clang::NestedNameSpecifier::Namespace
@ Namespace
A namespace, stored as a NamespaceDecl*.
Definition: NestedNameSpecifier.h:84
clang::UnaryExprOrTypeTraitExpr
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
Definition: Expr.h:2558
clang::FloatingLiteral
Definition: Expr.h:1648
clang::RecordType
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:4816
clang::TemplateArgument::getKind
ArgKind getKind() const
Return the kind of stored template argument.
Definition: TemplateBase.h:244
clang::NestedNameSpecifier::getAsIdentifier
IdentifierInfo * getAsIdentifier() const
Retrieve the identifier stored in this nested name specifier.
Definition: NestedNameSpecifier.h:176
clang::CompoundStmt
CompoundStmt - This represents a group of statements like { stmt stmt }.
Definition: Stmt.h:1410
clang::TemplateParameterList::getParam
NamedDecl * getParam(unsigned Idx)
Definition: DeclTemplate.h:139
DeclTemplate.h
clang::DeclarationName::getCXXOverloadedOperator
OverloadedOperatorKind getCXXOverloadedOperator() const
If this name is the name of an overloadable operator in C++ (e.g., operator+), retrieve the kind of o...
Definition: DeclarationName.h:471
clang::Decl::getAccess
AccessSpecifier getAccess() const
Definition: DeclBase.h:491
StmtOpenMP.h
clang::ObjCCategoryDecl::ivar_end
ivar_iterator ivar_end() const
Definition: DeclObjC.h:2415
clang::StructuralEquivalenceContext::FromCtx
ASTContext & FromCtx
AST contexts for which we are checking structural equivalence.
Definition: ASTStructuralEquivalence.h:43
IsStructurallyEquivalentLambdas
static bool IsStructurallyEquivalentLambdas(StructuralEquivalenceContext &Context, CXXRecordDecl *D1, CXXRecordDecl *D2)
Determine structural equivalence of two lambda classes.
Definition: ASTStructuralEquivalence.cpp:1375
DeclFriend.h
clang::Decl::getKind
Kind getKind() const
Definition: DeclBase.h:435
clang::BinaryOperator
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:3812
ExceptionSpecificationType.h
DeclBase.h
clang::DeclContext::getDeclKind
Decl::Kind getDeclKind() const
Definition: DeclBase.h:1916
clang::ConceptDecl
Declaration of a C++20 concept.
Definition: DeclTemplate.h:3262
clang::DeclarationName::CXXDestructorName
@ CXXDestructorName
Definition: DeclarationName.h:213
clang::GenericSelectionExpr::getAssocTypeSourceInfos
ArrayRef< TypeSourceInfo * > getAssocTypeSourceInfos() const
Definition: Expr.h:5837
clang::ObjCStringLiteral
ObjCStringLiteral, used for Objective-C string literals i.e.
Definition: ExprObjC.h:52
clang::threadSafety::sx::toString
std::string toString(const til::SExpr *E)
Definition: ThreadSafetyCommon.h:91
clang::FieldDecl::getBitWidth
Expr * getBitWidth() const
Definition: Decl.h:3019
clang::StringLiteral::getBytes
StringRef getBytes() const
Allow access to clients that need the byte representation, such as ASTWriterStmt::VisitStringLiteral(...
Definition: Expr.h:1867
IsRecordContextStructurallyEquivalent
static bool IsRecordContextStructurallyEquivalent(RecordDecl *D1, RecordDecl *D2)
Determine if context of a class is equivalent.
Definition: ASTStructuralEquivalence.cpp:1387
clang::ASTContext
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:209
clang::OverloadedTemplateStorage::begin
iterator begin() const
Definition: TemplateName.h:125
clang::OverloadedTemplateStorage::end
iterator end() const
Definition: TemplateName.h:126
clang::StructuralEquivalenceContext::Complain
bool Complain
Whether to complain about failures.
Definition: ASTStructuralEquivalence.h:67
clang::SubstNonTypeTemplateParmExpr::getIndex
unsigned getIndex() const
Returns the index of the replaced parameter in the associated declaration.
Definition: ExprCXX.h:4315
clang::FriendDecl::getFriendDecl
NamedDecl * getFriendDecl() const
If this friend declaration doesn't name a type, return the inner declaration.
Definition: DeclFriend.h:138
clang::ArrayType
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition: Type.h:3012
NestedNameSpecifier.h
clang::ConstantMatrixType
Represents a concrete matrix type with constant number of rows and columns.
Definition: Type.h:3584
clang::DependentTemplateName::isIdentifier
bool isIdentifier() const
Determine whether this template name refers to an identifier.
Definition: TemplateName.h:548
clang::Selector::getNumArgs
unsigned getNumArgs() const
Definition: IdentifierTable.cpp:563
clang::CXXBaseSpecifier::getBeginLoc
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: DeclCXX.h:190
clang::EnumDecl::getDefinition
EnumDecl * getDefinition() const
Definition: Decl.h:3808
clang::StructuralEquivalenceContext
Definition: ASTStructuralEquivalence.h:41
clang::TemplateArgument
Represents a template argument.
Definition: TemplateBase.h:61
clang::ObjCMethodDecl::getSelector
Selector getSelector() const
Definition: DeclObjC.h:330
clang::DeclarationName::CXXOperatorName
@ CXXOperatorName
Definition: DeclarationName.h:215
clang::ObjCMethodDecl::isDirectMethod
bool isDirectMethod() const
True if the method is tagged as objc_direct.
Definition: DeclObjC.cpp:834
clang::ASTContext::getObjCInterfaceType
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl.
Definition: ASTContext.cpp:5628
clang::Decl::getCanonicalDecl
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclBase.h:943
clang::Stmt::children
child_range children()
Definition: Stmt.cpp:285
clang::EnumConstantDecl::getInitVal
const llvm::APSInt & getInitVal() const
Definition: Decl.h:3166
clang::TypedefNameDecl::getUnderlyingType
QualType getUnderlyingType() const
Definition: Decl.h:3330
IdentifierTable.h
clang::DeclContext::isTranslationUnit
bool isTranslationUnit() const
Definition: DeclBase.h:1998
clang::AssumedTemplateStorage::getDeclName
DeclarationName getDeclName() const
Get the name of the template.
Definition: DeclarationName.h:949
clang::ConstantMatrixType::getNumColumns
unsigned getNumColumns() const
Returns the number of columns in the matrix.
Definition: Type.h:3605
Type.h
IsTemplateDeclCommonStructurallyEquivalent
static bool IsTemplateDeclCommonStructurallyEquivalent(StructuralEquivalenceContext &Ctx, TemplateDecl *D1, TemplateDecl *D2)
Definition: ASTStructuralEquivalence.cpp:1869
clang::TemplateName::getAsAssumedTemplateName
AssumedTemplateStorage * getAsAssumedTemplateName() const
Retrieve information on a name that has been assumed to be a template-name in order to permit a call ...
Definition: TemplateName.cpp:175
clang::FriendDecl
FriendDecl - Represents the declaration of a friend entity, which can be a function,...
Definition: DeclFriend.h:53
clang::TemplateTemplateParmDecl
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
Definition: DeclTemplate.h:1627
ASTContext.h
clang::ASTContext::getRecordType
QualType getRecordType(const RecordDecl *Decl) const
Definition: ASTContext.cpp:4759
clang::ObjCMethodDecl::getReturnType
QualType getReturnType() const
Definition: DeclObjC.h:332
clang::SourceLocExpr::getIdentKind
IdentKind getIdentKind() const
Definition: Expr.h:4709
clang::TemplateName::Template
@ Template
A single template declaration.
Definition: TemplateName.h:218
clang::CXXBaseSpecifier::getSourceRange
SourceRange getSourceRange() const LLVM_READONLY
Retrieves the source range that contains the entire base specifier.
Definition: DeclCXX.h:189
clang::FunctionType::ExtInfo::getNoCfCheck
bool getNoCfCheck() const
Definition: Type.h:3838
clang::EnumDecl::enumerator_begin
enumerator_iterator enumerator_begin() const
Definition: Decl.h:3842
clang::TemplateParameterList
Stores a list of template parameters for a TemplateDecl and its derived classes.
Definition: DeclTemplate.h:70
clang::StringLiteral
StringLiteral - This represents a string literal expression, e.g.
Definition: Expr.h:1776
clang::ASTContext::getCanonicalType
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
Definition: ASTContext.h:2528
clang::NestedNameSpecifier::Global
@ Global
The global specifier '::'. There is no stored value.
Definition: NestedNameSpecifier.h:97
clang::TagDecl::isUnion
bool isUnion() const
Definition: Decl.h:3629
clang::TemplateName::SubstTemplateTemplateParmPack
@ SubstTemplateTemplateParmPack
A template template parameter pack that has been substituted for a template template argument pack,...
Definition: TemplateName.h:242
clang::EnumConstantDecl
An instance of this object exists for each enum constant that is defined.
Definition: Decl.h:3145
clang::DeclarationName::CXXUsingDirective
@ CXXUsingDirective
Definition: DeclarationName.h:222
clang::TypeTraitExpr::getArgs
ArrayRef< TypeSourceInfo * > getArgs() const
Retrieve the argument types.
Definition: ExprCXX.h:2747
ExprObjC.h
ExprCXX.h
clang::StructuralEquivalenceContext::VisitedDecls
llvm::DenseSet< std::pair< Decl *, Decl * > > VisitedDecls
Definition: ASTStructuralEquivalence.h:51
clang::FunctionDecl::getOverloadedOperator
OverloadedOperatorKind getOverloadedOperator() const
getOverloadedOperator - Which C++ overloaded operator this function represents, if any.
Definition: Decl.cpp:3739
clang::SubstTemplateTemplateParmPackStorage
A structure for storing an already-substituted template template parameter pack.
Definition: TemplateName.h:139
clang::MatrixType::getElementType
QualType getElementType() const
Returns type of the elements being stored in the matrix.
Definition: Type.h:3562
clang::StmtExpr::getTemplateDepth
unsigned getTemplateDepth() const
Definition: Expr.h:4383
ASTDiagnostic.h
clang::Type::TypeClass
TypeClass
Definition: Type.h:1567
getKind
static Decl::Kind getKind(const Decl *D)
Definition: DeclBase.cpp:1024
clang::TemplateTypeParmDecl
Declaration of a template type parameter.
Definition: DeclTemplate.h:1205
clang::FunctionProtoType::getExceptionType
QualType getExceptionType(unsigned i) const
Return the ith exception type, where 0 <= i < getNumExceptions().
Definition: Type.h:4303
clang::Type::getTypeClass
TypeClass getTypeClass() const
Definition: Type.h:1984
clang::NestedNameSpecifier::TypeSpecWithTemplate
@ TypeSpecWithTemplate
A type that was preceded by the 'template' keyword, stored as a Type*.
Definition: NestedNameSpecifier.h:94
clang::TemplateParameterList::getTemplateLoc
SourceLocation getTemplateLoc() const
Definition: DeclTemplate.h:194
StmtObjC.h
clang::ChooseExpr
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
Definition: Expr.h:4529
clang::StructuralEquivalenceContext::NonEquivalentDecls
llvm::DenseSet< std::pair< Decl *, Decl * > > & NonEquivalentDecls
Declaration (from, to) pairs that are known not to be equivalent (which we have already complained ab...
Definition: ASTStructuralEquivalence.h:55
clang::TemplateDecl::getTemplateParameters
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Definition: DeclTemplate.h:427
clang::APIntStorage::getValue
llvm::APInt getValue() const
Definition: Expr.h:1487
clang::StructuralEquivalenceContext::Diag1
DiagnosticBuilder Diag1(SourceLocation Loc, unsigned DiagID)
Definition: ASTStructuralEquivalence.cpp:2106
clang::StructuralEquivalenceContext::LastDiagFromC2
bool LastDiagFromC2
true if the last diagnostic came from ToCtx.
Definition: ASTStructuralEquivalence.h:70
clang::ObjCCategoryDecl
ObjCCategoryDecl - Represents a category declaration.
Definition: DeclObjC.h:2294
clang::DeclarationName::CXXConversionFunctionName
@ CXXConversionFunctionName
Definition: DeclarationName.h:214
clang::CharacterLiteral
Definition: Expr.h:1593
clang::ArrayType::getIndexTypeQualifiers
Qualifiers getIndexTypeQualifiers() const
Definition: Type.h:3039
clang::DependentTemplateName
Represents a dependent template name that cannot be resolved prior to template instantiation.
Definition: TemplateName.h:489
clang::TemplateArgument::TemplateExpansion
@ TemplateExpansion
The template argument is a pack expansion of a template name that was provided for a template templat...
Definition: TemplateBase.h:90
clang::CXXMethodDecl::getRefQualifier
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this method.
Definition: DeclCXX.h:2143
clang::Type::castAs
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:7453
clang::ArrayType::getSizeModifier
ArraySizeModifier getSizeModifier() const
Definition: Type.h:3035
clang::QualType::getDesugaredType
QualType getDesugaredType(const ASTContext &Context) const
Return the specified type with any "sugar" removed from the type.
Definition: Type.h:1052
clang::TemplateName::getKind
NameKind getKind() const
Definition: TemplateName.cpp:122
clang::CXXRecordDecl
Represents a C++ struct/union/class.
Definition: DeclCXX.h:254
clang::FunctionType::ExtInfo::getHasRegParm
bool getHasRegParm() const
Definition: Type.h:3839
SourceLocation.h
clang::NestedNameSpecifier::getAsNamespaceAlias
NamespaceAliasDecl * getAsNamespaceAlias() const
Retrieve the namespace alias stored in this nested name specifier.
Definition: NestedNameSpecifier.cpp:177
P
StringRef P
Definition: ASTMatchersInternal.cpp:563
clang::ObjCCategoryDecl::ivar_begin
ivar_iterator ivar_begin() const
Definition: DeclObjC.h:2411
clang::FieldDecl::isBitField
bool isBitField() const
Determines whether this field is a bitfield.
Definition: Decl.h:3008
clang::NestedNameSpecifier::getAsNamespace
NamespaceDecl * getAsNamespace() const
Retrieve the namespace stored in this nested name specifier.
Definition: NestedNameSpecifier.cpp:169
clang::Stmt::getStmtClass
StmtClass getStmtClass() const
Definition: Stmt.h:1169
clang::ObjCContainerDecl::meth_begin
method_iterator meth_begin() const
Definition: DeclObjC.h:1016
clang::TemplateName::QualifiedTemplate
@ QualifiedTemplate
A qualified template name, where the qualification is kept to describe the source code as written.
Definition: TemplateName.h:229
clang::ExternalASTSource::CompleteType
virtual void CompleteType(TagDecl *Tag)
Gives the external AST source an opportunity to complete an incomplete type.
Definition: ExternalASTSource.cpp:49
clang::DiagnosticsEngine::notePriorDiagnosticFrom
void notePriorDiagnosticFrom(const DiagnosticsEngine &Other)
Note that the prior diagnostic was emitted by some other DiagnosticsEngine, and we may be attaching a...
Definition: Diagnostic.h:891
clang::TagDecl::isBeingDefined
bool isBeingDefined() const
Return true if this decl is currently being defined.
Definition: Decl.h:3548
clang::FunctionType::ExtInfo::getCC
CallingConv getCC() const
Definition: Type.h:3848
clang::NamedDecl::getIdentifier
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition: Decl.h:268
clang::ClassTemplateDecl
Declaration of a class template.
Definition: DeclTemplate.h:2273
clang::DependentSizedMatrixType::getRowExpr
Expr * getRowExpr() const
Definition: Type.h:3657
clang::TemplateName
Represents a C++ template name within the type system.
Definition: TemplateName.h:201
IsEquivalentExceptionSpec
static bool IsEquivalentExceptionSpec(StructuralEquivalenceContext &Context, const FunctionProtoType *Proto1, const FunctionProtoType *Proto2)
Check the equivalence of exception specifications.
Definition: ASTStructuralEquivalence.cpp:645
clang::FunctionProtoType
Represents a prototype with parameter type info, e.g.
Definition: Type.h:4016
clang::Decl::getDescribedTemplate
TemplateDecl * getDescribedTemplate() const
If this is a declaration that describes some template, this method returns that template declaration.
Definition: DeclBase.cpp:239
clang::DeclContext::getParent
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:1923
clang::TemplateDecl
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:408
clang::QualType::isNull
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:802
llvm::ArrayRef< TemplateArgument >
clang::StmtExpr
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
Definition: Expr.h:4354
clang::FunctionProtoType::getNoexceptExpr
Expr * getNoexceptExpr() const
Return the expression inside noexcept(expression), or a null pointer if there is none (because the ex...
Definition: Type.h:4310
clang::Decl
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:83
clang::StructuralEquivalenceContext::ToCtx
ASTContext & ToCtx
Definition: ASTStructuralEquivalence.h:43
clang::DependentSizedMatrixType::getColumnExpr
Expr * getColumnExpr() const
Definition: Type.h:3658
clang::FunctionDecl::isPure
bool isPure() const
Whether this virtual function is pure, i.e.
Definition: Decl.h:2244
clang::AddrLabelExpr
AddrLabelExpr - The GNU address of label extension, representing &&label.
Definition: Expr.h:4309
clang::DependentTemplateName::getIdentifier
const IdentifierInfo * getIdentifier() const
Returns the identifier to which this template name refers.
Definition: TemplateName.h:551
clang::ObjCMethodDecl::isInstanceMethod
bool isInstanceMethod() const
Definition: DeclObjC.h:431
clang::DeclarationName::ObjCZeroArgSelector
@ ObjCZeroArgSelector
Definition: DeclarationName.h:210
clang::DependentScopeDeclRefExpr
A qualified reference to a name whose declaration cannot yet be resolved.
Definition: ExprCXX.h:3215
getUnderlyingType
static QualType getUnderlyingType(const SubRegion *R)
Definition: RegionStore.cpp:1521
clang::UnaryExprOrTypeTraitExpr::getTypeOfArgument
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
Definition: Expr.h:2627
clang::DeclarationName::ObjCOneArgSelector
@ ObjCOneArgSelector
Definition: DeclarationName.h:211
LLVM.h
clang::ComparisonCategoryResult::Equivalent
@ Equivalent
clang::ClassTemplateDecl::getTemplatedDecl
CXXRecordDecl * getTemplatedDecl() const
Get the underlying class declarations of the template.
Definition: DeclTemplate.h:2321
clang::Selector::getIdentifierInfoForSlot
IdentifierInfo * getIdentifierInfoForSlot(unsigned argIndex) const
Retrieve the identifier at a given position in the selector.
Definition: IdentifierTable.cpp:574
clang::StructuralEquivalenceContext::Diag2
DiagnosticBuilder Diag2(SourceLocation Loc, unsigned DiagID)
Definition: ASTStructuralEquivalence.cpp:2115
clang::TemplateParameterList::size
unsigned size() const
Definition: DeclTemplate.h:130
clang::FunctionType::ExtInfo
A class which abstracts out some details necessary for making a call.
Definition: Type.h:3786
clang::IdentifierInfo
One of these records is kept for each identifier that is lexed.
Definition: IdentifierTable.h:85
clang::RecordDecl::field_end
field_iterator field_end() const
Definition: Decl.h:4212
clang::OverloadedTemplateStorage::iterator
NamedDecl *const * iterator
Definition: TemplateName.h:123
clang::NamedDecl::getNameAsString
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
Definition: Decl.h:290
clang::FloatingLiteral::isExact
bool isExact() const
Definition: Expr.h:1695
clang::TemplateTypeParmDecl::isParameterPack
bool isParameterPack() const
Returns whether this is a parameter pack.
Definition: DeclTemplate.cpp:699
clang::TemplateName::SubstTemplateTemplateParm
@ SubstTemplateTemplateParm
A template template parameter that has been substituted for some other template name.
Definition: TemplateName.h:237
clang::FunctionTemplateDecl::getTemplatedDecl
FunctionDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
Definition: DeclTemplate.h:1052
clang::TemplateArgument::getAsDecl
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template argument.
Definition: TemplateBase.h:275
clang::ObjCMethodDecl
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:139
clang::ObjCMethodDecl::param_type_begin
param_type_iterator param_type_begin() const
Definition: DeclObjC.h:404
clang::UnaryExprOrTypeTraitExpr::getKind
UnaryExprOrTypeTrait getKind() const
Definition: Expr.h:2590
clang::FunctionType::ExtInfo::getRegParm
unsigned getRegParm() const
Definition: Type.h:3841
clang::DeclarationName::getNameKind
NameKind getNameKind() const
Determine what kind of name this is.
Definition: DeclarationName.h:393
clang::IdentifierInfo::getName
StringRef getName() const
Return the actual identifier string.
Definition: IdentifierTable.h:196
clang::TemplateArgument::Type
@ Type
The template argument is a type.
Definition: TemplateBase.h:70
clang::CXXMethodDecl::isConst
bool isConst() const
Definition: DeclCXX.h:2024
clang
Definition: CalledOnceCheck.h:17
clang::Selector
Smart pointer class that efficiently represents Objective-C method names.
Definition: IdentifierTable.h:759
clang::NestedNameSpecifier::getAsType
const Type * getAsType() const
Retrieve the type stored in this nested name specifier.
Definition: NestedNameSpecifier.h:196
clang::TemplateArgument::Template
@ Template
The template argument is a template name that was provided for a template template parameter.
Definition: TemplateBase.h:86
clang::NonTypeTemplateParmDecl::isParameterPack
bool isParameterPack() const
Whether this parameter is a non-type template parameter pack.
Definition: DeclTemplate.h:1524
clang::Stmt
Stmt - This represents one statement.
Definition: Stmt.h:71
clang::TemplateArgument::getAsTemplate
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
Definition: TemplateBase.h:292
clang::ObjCIvarDecl
ObjCIvarDecl - Represents an ObjC instance variable.
Definition: DeclObjC.h:1921
clang::UnaryOperator::getOpcode
Opcode getOpcode() const
Definition: Expr.h:2214
clang::StructuralEquivalenceContext::ErrorOnTagTypeMismatch
bool ErrorOnTagTypeMismatch
Whether warn or error on tag type mismatches.
Definition: ASTStructuralEquivalence.h:64
clang::GenericSelectionExpr
Represents a C11 generic selection.
Definition: Expr.h:5633
clang::Expr::getType
QualType getType() const
Definition: Expr.h:141
clang::CXXBaseSpecifier
Represents a base class of a C++ class.
Definition: DeclCXX.h:146
clang::NamedDecl::getDeclName
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:313
clang::StructuralEquivalenceContext::getApplicableDiagnostic
unsigned getApplicableDiagnostic(unsigned ErrorDiagnostic)
Definition: ASTStructuralEquivalence.cpp:2167
clang::NestedNameSpecifier::getPrefix
NestedNameSpecifier * getPrefix() const
Return the prefix of this nested name specifier.
Definition: NestedNameSpecifier.h:169
clang::TemplateName::AssumedTemplate
@ AssumedTemplate
An unqualified-id that has been assumed to name a function template that will be found by ADL.
Definition: TemplateName.h:225
unsigned
clang::DeclarationName::getCXXLiteralIdentifier
IdentifierInfo * getCXXLiteralIdentifier() const
If this name is the name of a literal operator, retrieve the identifier associated with it.
Definition: DeclarationName.h:481
clang::SubstNonTypeTemplateParmExpr::getPackIndex
Optional< unsigned > getPackIndex() const
Definition: ExprCXX.h:4317
clang::ObjCCategoryDecl::protocol_end
protocol_iterator protocol_end() const
Definition: DeclObjC.h:2378
clang::TemplateName::getAsDependentTemplateName
DependentTemplateName * getAsDependentTemplateName() const
Retrieve the underlying dependent template name structure, if any.
Definition: TemplateName.cpp:205
clang::TagDecl::getTagKind
TagKind getTagKind() const
Definition: Decl.h:3620
clang::TypedefNameDecl
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3275
clang::TemplateName::OverloadedTemplate
@ OverloadedTemplate
A set of overloaded template declarations.
Definition: TemplateName.h:221
clang::ImplicitCastExpr
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Definition: Expr.h:3624
clang::VAArgExpr
Represents a call to the builtin function __builtin_va_arg.
Definition: Expr.h:4638
clang::SourceLocExpr
Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), __builtin_FUNCTION(),...
Definition: Expr.h:4687
clang::MemberExpr
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition: Expr.h:3169
IsArrayStructurallyEquivalent
static bool IsArrayStructurallyEquivalent(StructuralEquivalenceContext &Context, const ArrayType *Array1, const ArrayType *Array2)
Determine structural equivalence for the common part of array types.
Definition: ASTStructuralEquivalence.cpp:604
clang::NestedNameSpecifier::TypeSpec
@ TypeSpec
A type, stored as a Type*.
Definition: NestedNameSpecifier.h:90
clang::TemplateName::getAsSubstTemplateTemplateParmPack
SubstTemplateTemplateParmPackStorage * getAsSubstTemplateTemplateParmPack() const
Retrieve the substituted template template parameter pack, if known.
Definition: TemplateName.cpp:193
clang::CXXRecordDecl::isLambda
bool isLambda() const
Determine whether this class describes a lambda function object.
Definition: DeclCXX.h:1000
clang::ASTContext::hasSameType
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
Definition: ASTContext.h:2544
clang::AssumedTemplateStorage
A structure for storing the information associated with a name that has been assumed to be a template...
Definition: DeclarationName.h:940
clang::CXXMethodDecl::isVolatile
bool isVolatile() const
Definition: DeclCXX.h:2025
clang::SubstNonTypeTemplateParmPackExpr::getArgumentPack
TemplateArgument getArgumentPack() const
Retrieve the template argument pack containing the substituted template arguments.
Definition: ExprCXX.cpp:1608
clang::StructuralEquivalenceKind::Minimal
@ Minimal
clang::DeclarationName::ObjCMultiArgSelector
@ ObjCMultiArgSelector
Definition: DeclarationName.h:225
clang::ValueDecl::getType
QualType getType() const
Definition: Decl.h:712
clang::SubstTemplateTemplateParmPackStorage::getIndex
unsigned getIndex() const
Returns the index of the replaced parameter in the associated declaration.
Definition: TemplateName.h:155
clang::ArrayType::getElementType
QualType getElementType() const
Definition: Type.h:3033
clang::Expr
This represents one expression.
Definition: Expr.h:109
clang::DeclarationName::getCXXNameType
QualType getCXXNameType() const
If this name is one of the C++ names (of a constructor, destructor, or conversion function),...
Definition: DeclarationName.h:448
clang::CXXRecordDecl::friend_iterator
An iterator over the friend declarations of a class.
Definition: DeclFriend.h:187
clang::DependentTemplateName::getOperator
OverloadedOperatorKind getOperator() const
Return the overloaded operator to which this template name refers.
Definition: TemplateName.h:561
clang::DependentTemplateName::getQualifier
NestedNameSpecifier * getQualifier() const
Return the nested name specifier that qualifies this name.
Definition: TemplateName.h:545
clang::NestedNameSpecifier::getKind
SpecifierKind getKind() const
Determine what kind of nested name specifier is stored.
Definition: NestedNameSpecifier.cpp:143
clang::ObjCContainerDecl::meth_end
method_iterator meth_end() const
Definition: DeclObjC.h:1020
clang::SubstNonTypeTemplateParmExpr::getAssociatedDecl
Decl * getAssociatedDecl() const
A template-like entity which owns the whole pattern being substituted.
Definition: ExprCXX.h:4311
clang::DeclContext::isFunctionOrMethod
bool isFunctionOrMethod() const
Definition: DeclBase.h:1975
clang::MemberExpr::getFoundDecl
DeclAccessPair getFoundDecl() const
Retrieves the declaration found by lookup.
Definition: Expr.h:3256
clang::Decl::getLocation
SourceLocation getLocation() const
Definition: DeclBase.h:432
clang::FieldDecl::isAnonymousStructOrUnion
bool isAnonymousStructOrUnion() const
Determines whether this field is a representative for an anonymous struct or union.
Definition: Decl.cpp:4290
clang::ConstantMatrixType::getNumRows
unsigned getNumRows() const
Returns the number of rows in the matrix.
Definition: Type.h:3602
clang::AddrLabelExpr::getLabel
LabelDecl * getLabel() const
Definition: Expr.h:4332
clang::FunctionDecl
Represents a function declaration or definition.
Definition: Decl.h:1904
clang::RecordDecl
Represents a struct/union/class.
Definition: Decl.h:3983
clang::CallExpr
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2810
clang::FunctionType::ExtInfo::getProducesResult
bool getProducesResult() const
Definition: Type.h:3835
clang::TypeTraitExpr::getTrait
TypeTrait getTrait() const
Determine which type trait this expression uses.
Definition: ExprCXX.h:2728
clang::ObjCCategoryDecl::protocol_iterator
ObjCProtocolList::iterator protocol_iterator
Definition: DeclObjC.h:2367
clang::ObjCMethodDecl::isVariadic
bool isVariadic() const
Definition: DeclObjC.h:436
clang::ASTContext::getDiagnostics
DiagnosticsEngine & getDiagnostics() const
Definition: ASTContext.cpp:1505
clang::CXXMethodDecl::isVirtual
bool isVirtual() const
Definition: DeclCXX.h:2027
clang::ObjCContainerDecl::method_iterator
specific_decl_iterator< ObjCMethodDecl > method_iterator
Definition: DeclObjC.h:1008
clang::ObjCMethodDecl::param_type_iterator
llvm::mapped_iterator< param_const_iterator, GetTypeFn > param_type_iterator
Definition: DeclObjC.h:402
clang::FriendDecl::getFriendType
TypeSourceInfo * getFriendType() const
If this friend declaration names an (untemplated but possibly dependent) type, return the type; other...
Definition: DeclFriend.h:123
clang::CharacterLiteral::getKind
CharacterKind getKind() const
Definition: Expr.h:1620
clang::ObjCMethodDecl::param_size
unsigned param_size() const
Definition: DeclObjC.h:350
clang::TemplateArgument::getAsType
QualType getAsType() const
Retrieve the type for a type template argument.
Definition: TemplateBase.h:268
clang::DiagnosticsEngine::Report
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Definition: Diagnostic.h:1537
clang::TemplateTemplateParmDecl::isParameterPack
bool isParameterPack() const
Whether this template template parameter is a template parameter pack.
Definition: DeclTemplate.h:1696
clang::TemplateArgument::Pack
@ Pack
The template argument is actually a parameter pack.
Definition: TemplateBase.h:100
clang::FunctionProtoType::getNumExceptions
unsigned getNumExceptions() const
Return the number of types in the exception specification.
Definition: Type.h:4295
clang::CXXMethodDecl
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:1983
clang::Decl::getDeclContext
DeclContext * getDeclContext()
Definition: DeclBase.h:441
clang::TemplateName::DependentTemplate
@ DependentTemplate
A dependent template name that has not been resolved to a template (or set of templates).
Definition: TemplateName.h:233
clang::TemplateName::UsingTemplate
@ UsingTemplate
A template name that refers to a template declaration found through a specific using shadow declarati...
Definition: TemplateName.h:246