1f4a2713aSLionel Sambuc //===--- ASTImporter.cpp - Importing ASTs from other Contexts ---*- C++ -*-===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc //  This file defines the ASTImporter class which imports AST nodes from one
11f4a2713aSLionel Sambuc //  context into another context.
12f4a2713aSLionel Sambuc //
13f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
14f4a2713aSLionel Sambuc #include "clang/AST/ASTImporter.h"
15f4a2713aSLionel Sambuc #include "clang/AST/ASTContext.h"
16f4a2713aSLionel Sambuc #include "clang/AST/ASTDiagnostic.h"
17f4a2713aSLionel Sambuc #include "clang/AST/DeclCXX.h"
18f4a2713aSLionel Sambuc #include "clang/AST/DeclObjC.h"
19f4a2713aSLionel Sambuc #include "clang/AST/DeclVisitor.h"
20f4a2713aSLionel Sambuc #include "clang/AST/StmtVisitor.h"
21f4a2713aSLionel Sambuc #include "clang/AST/TypeVisitor.h"
22f4a2713aSLionel Sambuc #include "clang/Basic/FileManager.h"
23f4a2713aSLionel Sambuc #include "clang/Basic/SourceManager.h"
24f4a2713aSLionel Sambuc #include "llvm/Support/MemoryBuffer.h"
25f4a2713aSLionel Sambuc #include <deque>
26f4a2713aSLionel Sambuc 
27f4a2713aSLionel Sambuc namespace clang {
28f4a2713aSLionel Sambuc   class ASTNodeImporter : public TypeVisitor<ASTNodeImporter, QualType>,
29f4a2713aSLionel Sambuc                           public DeclVisitor<ASTNodeImporter, Decl *>,
30f4a2713aSLionel Sambuc                           public StmtVisitor<ASTNodeImporter, Stmt *> {
31f4a2713aSLionel Sambuc     ASTImporter &Importer;
32f4a2713aSLionel Sambuc 
33f4a2713aSLionel Sambuc   public:
ASTNodeImporter(ASTImporter & Importer)34f4a2713aSLionel Sambuc     explicit ASTNodeImporter(ASTImporter &Importer) : Importer(Importer) { }
35f4a2713aSLionel Sambuc 
36f4a2713aSLionel Sambuc     using TypeVisitor<ASTNodeImporter, QualType>::Visit;
37f4a2713aSLionel Sambuc     using DeclVisitor<ASTNodeImporter, Decl *>::Visit;
38f4a2713aSLionel Sambuc     using StmtVisitor<ASTNodeImporter, Stmt *>::Visit;
39f4a2713aSLionel Sambuc 
40f4a2713aSLionel Sambuc     // Importing types
41f4a2713aSLionel Sambuc     QualType VisitType(const Type *T);
42f4a2713aSLionel Sambuc     QualType VisitBuiltinType(const BuiltinType *T);
43f4a2713aSLionel Sambuc     QualType VisitComplexType(const ComplexType *T);
44f4a2713aSLionel Sambuc     QualType VisitPointerType(const PointerType *T);
45f4a2713aSLionel Sambuc     QualType VisitBlockPointerType(const BlockPointerType *T);
46f4a2713aSLionel Sambuc     QualType VisitLValueReferenceType(const LValueReferenceType *T);
47f4a2713aSLionel Sambuc     QualType VisitRValueReferenceType(const RValueReferenceType *T);
48f4a2713aSLionel Sambuc     QualType VisitMemberPointerType(const MemberPointerType *T);
49f4a2713aSLionel Sambuc     QualType VisitConstantArrayType(const ConstantArrayType *T);
50f4a2713aSLionel Sambuc     QualType VisitIncompleteArrayType(const IncompleteArrayType *T);
51f4a2713aSLionel Sambuc     QualType VisitVariableArrayType(const VariableArrayType *T);
52f4a2713aSLionel Sambuc     // FIXME: DependentSizedArrayType
53f4a2713aSLionel Sambuc     // FIXME: DependentSizedExtVectorType
54f4a2713aSLionel Sambuc     QualType VisitVectorType(const VectorType *T);
55f4a2713aSLionel Sambuc     QualType VisitExtVectorType(const ExtVectorType *T);
56f4a2713aSLionel Sambuc     QualType VisitFunctionNoProtoType(const FunctionNoProtoType *T);
57f4a2713aSLionel Sambuc     QualType VisitFunctionProtoType(const FunctionProtoType *T);
58f4a2713aSLionel Sambuc     // FIXME: UnresolvedUsingType
59f4a2713aSLionel Sambuc     QualType VisitParenType(const ParenType *T);
60f4a2713aSLionel Sambuc     QualType VisitTypedefType(const TypedefType *T);
61f4a2713aSLionel Sambuc     QualType VisitTypeOfExprType(const TypeOfExprType *T);
62f4a2713aSLionel Sambuc     // FIXME: DependentTypeOfExprType
63f4a2713aSLionel Sambuc     QualType VisitTypeOfType(const TypeOfType *T);
64f4a2713aSLionel Sambuc     QualType VisitDecltypeType(const DecltypeType *T);
65f4a2713aSLionel Sambuc     QualType VisitUnaryTransformType(const UnaryTransformType *T);
66f4a2713aSLionel Sambuc     QualType VisitAutoType(const AutoType *T);
67f4a2713aSLionel Sambuc     // FIXME: DependentDecltypeType
68f4a2713aSLionel Sambuc     QualType VisitRecordType(const RecordType *T);
69f4a2713aSLionel Sambuc     QualType VisitEnumType(const EnumType *T);
70f4a2713aSLionel Sambuc     // FIXME: TemplateTypeParmType
71f4a2713aSLionel Sambuc     // FIXME: SubstTemplateTypeParmType
72f4a2713aSLionel Sambuc     QualType VisitTemplateSpecializationType(const TemplateSpecializationType *T);
73f4a2713aSLionel Sambuc     QualType VisitElaboratedType(const ElaboratedType *T);
74f4a2713aSLionel Sambuc     // FIXME: DependentNameType
75f4a2713aSLionel Sambuc     // FIXME: DependentTemplateSpecializationType
76f4a2713aSLionel Sambuc     QualType VisitObjCInterfaceType(const ObjCInterfaceType *T);
77f4a2713aSLionel Sambuc     QualType VisitObjCObjectType(const ObjCObjectType *T);
78f4a2713aSLionel Sambuc     QualType VisitObjCObjectPointerType(const ObjCObjectPointerType *T);
79f4a2713aSLionel Sambuc 
80f4a2713aSLionel Sambuc     // Importing declarations
81f4a2713aSLionel Sambuc     bool ImportDeclParts(NamedDecl *D, DeclContext *&DC,
82f4a2713aSLionel Sambuc                          DeclContext *&LexicalDC, DeclarationName &Name,
83f4a2713aSLionel Sambuc                          SourceLocation &Loc);
84*0a6a1f1dSLionel Sambuc     void ImportDefinitionIfNeeded(Decl *FromD, Decl *ToD = nullptr);
85f4a2713aSLionel Sambuc     void ImportDeclarationNameLoc(const DeclarationNameInfo &From,
86f4a2713aSLionel Sambuc                                   DeclarationNameInfo& To);
87f4a2713aSLionel Sambuc     void ImportDeclContext(DeclContext *FromDC, bool ForceImport = false);
88f4a2713aSLionel Sambuc 
89f4a2713aSLionel Sambuc     /// \brief What we should import from the definition.
90f4a2713aSLionel Sambuc     enum ImportDefinitionKind {
91f4a2713aSLionel Sambuc       /// \brief Import the default subset of the definition, which might be
92f4a2713aSLionel Sambuc       /// nothing (if minimal import is set) or might be everything (if minimal
93f4a2713aSLionel Sambuc       /// import is not set).
94f4a2713aSLionel Sambuc       IDK_Default,
95f4a2713aSLionel Sambuc       /// \brief Import everything.
96f4a2713aSLionel Sambuc       IDK_Everything,
97f4a2713aSLionel Sambuc       /// \brief Import only the bare bones needed to establish a valid
98f4a2713aSLionel Sambuc       /// DeclContext.
99f4a2713aSLionel Sambuc       IDK_Basic
100f4a2713aSLionel Sambuc     };
101f4a2713aSLionel Sambuc 
shouldForceImportDeclContext(ImportDefinitionKind IDK)102f4a2713aSLionel Sambuc     bool shouldForceImportDeclContext(ImportDefinitionKind IDK) {
103f4a2713aSLionel Sambuc       return IDK == IDK_Everything ||
104f4a2713aSLionel Sambuc              (IDK == IDK_Default && !Importer.isMinimalImport());
105f4a2713aSLionel Sambuc     }
106f4a2713aSLionel Sambuc 
107f4a2713aSLionel Sambuc     bool ImportDefinition(RecordDecl *From, RecordDecl *To,
108f4a2713aSLionel Sambuc                           ImportDefinitionKind Kind = IDK_Default);
109f4a2713aSLionel Sambuc     bool ImportDefinition(VarDecl *From, VarDecl *To,
110f4a2713aSLionel Sambuc                           ImportDefinitionKind Kind = IDK_Default);
111f4a2713aSLionel Sambuc     bool ImportDefinition(EnumDecl *From, EnumDecl *To,
112f4a2713aSLionel Sambuc                           ImportDefinitionKind Kind = IDK_Default);
113f4a2713aSLionel Sambuc     bool ImportDefinition(ObjCInterfaceDecl *From, ObjCInterfaceDecl *To,
114f4a2713aSLionel Sambuc                           ImportDefinitionKind Kind = IDK_Default);
115f4a2713aSLionel Sambuc     bool ImportDefinition(ObjCProtocolDecl *From, ObjCProtocolDecl *To,
116f4a2713aSLionel Sambuc                           ImportDefinitionKind Kind = IDK_Default);
117f4a2713aSLionel Sambuc     TemplateParameterList *ImportTemplateParameterList(
118f4a2713aSLionel Sambuc                                                  TemplateParameterList *Params);
119f4a2713aSLionel Sambuc     TemplateArgument ImportTemplateArgument(const TemplateArgument &From);
120f4a2713aSLionel Sambuc     bool ImportTemplateArguments(const TemplateArgument *FromArgs,
121f4a2713aSLionel Sambuc                                  unsigned NumFromArgs,
122f4a2713aSLionel Sambuc                                SmallVectorImpl<TemplateArgument> &ToArgs);
123f4a2713aSLionel Sambuc     bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord,
124f4a2713aSLionel Sambuc                            bool Complain = true);
125f4a2713aSLionel Sambuc     bool IsStructuralMatch(VarDecl *FromVar, VarDecl *ToVar,
126f4a2713aSLionel Sambuc                            bool Complain = true);
127f4a2713aSLionel Sambuc     bool IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToRecord);
128f4a2713aSLionel Sambuc     bool IsStructuralMatch(EnumConstantDecl *FromEC, EnumConstantDecl *ToEC);
129f4a2713aSLionel Sambuc     bool IsStructuralMatch(ClassTemplateDecl *From, ClassTemplateDecl *To);
130f4a2713aSLionel Sambuc     bool IsStructuralMatch(VarTemplateDecl *From, VarTemplateDecl *To);
131f4a2713aSLionel Sambuc     Decl *VisitDecl(Decl *D);
132f4a2713aSLionel Sambuc     Decl *VisitTranslationUnitDecl(TranslationUnitDecl *D);
133f4a2713aSLionel Sambuc     Decl *VisitNamespaceDecl(NamespaceDecl *D);
134f4a2713aSLionel Sambuc     Decl *VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias);
135f4a2713aSLionel Sambuc     Decl *VisitTypedefDecl(TypedefDecl *D);
136f4a2713aSLionel Sambuc     Decl *VisitTypeAliasDecl(TypeAliasDecl *D);
137f4a2713aSLionel Sambuc     Decl *VisitEnumDecl(EnumDecl *D);
138f4a2713aSLionel Sambuc     Decl *VisitRecordDecl(RecordDecl *D);
139f4a2713aSLionel Sambuc     Decl *VisitEnumConstantDecl(EnumConstantDecl *D);
140f4a2713aSLionel Sambuc     Decl *VisitFunctionDecl(FunctionDecl *D);
141f4a2713aSLionel Sambuc     Decl *VisitCXXMethodDecl(CXXMethodDecl *D);
142f4a2713aSLionel Sambuc     Decl *VisitCXXConstructorDecl(CXXConstructorDecl *D);
143f4a2713aSLionel Sambuc     Decl *VisitCXXDestructorDecl(CXXDestructorDecl *D);
144f4a2713aSLionel Sambuc     Decl *VisitCXXConversionDecl(CXXConversionDecl *D);
145f4a2713aSLionel Sambuc     Decl *VisitFieldDecl(FieldDecl *D);
146f4a2713aSLionel Sambuc     Decl *VisitIndirectFieldDecl(IndirectFieldDecl *D);
147f4a2713aSLionel Sambuc     Decl *VisitObjCIvarDecl(ObjCIvarDecl *D);
148f4a2713aSLionel Sambuc     Decl *VisitVarDecl(VarDecl *D);
149f4a2713aSLionel Sambuc     Decl *VisitImplicitParamDecl(ImplicitParamDecl *D);
150f4a2713aSLionel Sambuc     Decl *VisitParmVarDecl(ParmVarDecl *D);
151f4a2713aSLionel Sambuc     Decl *VisitObjCMethodDecl(ObjCMethodDecl *D);
152f4a2713aSLionel Sambuc     Decl *VisitObjCCategoryDecl(ObjCCategoryDecl *D);
153f4a2713aSLionel Sambuc     Decl *VisitObjCProtocolDecl(ObjCProtocolDecl *D);
154*0a6a1f1dSLionel Sambuc     Decl *VisitLinkageSpecDecl(LinkageSpecDecl *D);
155f4a2713aSLionel Sambuc     Decl *VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
156f4a2713aSLionel Sambuc     Decl *VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
157f4a2713aSLionel Sambuc     Decl *VisitObjCImplementationDecl(ObjCImplementationDecl *D);
158f4a2713aSLionel Sambuc     Decl *VisitObjCPropertyDecl(ObjCPropertyDecl *D);
159f4a2713aSLionel Sambuc     Decl *VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
160f4a2713aSLionel Sambuc     Decl *VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
161f4a2713aSLionel Sambuc     Decl *VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
162f4a2713aSLionel Sambuc     Decl *VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
163f4a2713aSLionel Sambuc     Decl *VisitClassTemplateDecl(ClassTemplateDecl *D);
164f4a2713aSLionel Sambuc     Decl *VisitClassTemplateSpecializationDecl(
165f4a2713aSLionel Sambuc                                             ClassTemplateSpecializationDecl *D);
166f4a2713aSLionel Sambuc     Decl *VisitVarTemplateDecl(VarTemplateDecl *D);
167f4a2713aSLionel Sambuc     Decl *VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *D);
168f4a2713aSLionel Sambuc 
169f4a2713aSLionel Sambuc     // Importing statements
170f4a2713aSLionel Sambuc     Stmt *VisitStmt(Stmt *S);
171f4a2713aSLionel Sambuc 
172f4a2713aSLionel Sambuc     // Importing expressions
173f4a2713aSLionel Sambuc     Expr *VisitExpr(Expr *E);
174f4a2713aSLionel Sambuc     Expr *VisitDeclRefExpr(DeclRefExpr *E);
175f4a2713aSLionel Sambuc     Expr *VisitIntegerLiteral(IntegerLiteral *E);
176f4a2713aSLionel Sambuc     Expr *VisitCharacterLiteral(CharacterLiteral *E);
177f4a2713aSLionel Sambuc     Expr *VisitParenExpr(ParenExpr *E);
178f4a2713aSLionel Sambuc     Expr *VisitUnaryOperator(UnaryOperator *E);
179f4a2713aSLionel Sambuc     Expr *VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E);
180f4a2713aSLionel Sambuc     Expr *VisitBinaryOperator(BinaryOperator *E);
181f4a2713aSLionel Sambuc     Expr *VisitCompoundAssignOperator(CompoundAssignOperator *E);
182f4a2713aSLionel Sambuc     Expr *VisitImplicitCastExpr(ImplicitCastExpr *E);
183f4a2713aSLionel Sambuc     Expr *VisitCStyleCastExpr(CStyleCastExpr *E);
184f4a2713aSLionel Sambuc   };
185f4a2713aSLionel Sambuc }
186f4a2713aSLionel Sambuc using namespace clang;
187f4a2713aSLionel Sambuc 
188f4a2713aSLionel Sambuc //----------------------------------------------------------------------------
189f4a2713aSLionel Sambuc // Structural Equivalence
190f4a2713aSLionel Sambuc //----------------------------------------------------------------------------
191f4a2713aSLionel Sambuc 
192f4a2713aSLionel Sambuc namespace {
193f4a2713aSLionel Sambuc   struct StructuralEquivalenceContext {
194f4a2713aSLionel Sambuc     /// \brief AST contexts for which we are checking structural equivalence.
195f4a2713aSLionel Sambuc     ASTContext &C1, &C2;
196f4a2713aSLionel Sambuc 
197f4a2713aSLionel Sambuc     /// \brief The set of "tentative" equivalences between two canonical
198f4a2713aSLionel Sambuc     /// declarations, mapping from a declaration in the first context to the
199f4a2713aSLionel Sambuc     /// declaration in the second context that we believe to be equivalent.
200f4a2713aSLionel Sambuc     llvm::DenseMap<Decl *, Decl *> TentativeEquivalences;
201f4a2713aSLionel Sambuc 
202f4a2713aSLionel Sambuc     /// \brief Queue of declarations in the first context whose equivalence
203f4a2713aSLionel Sambuc     /// with a declaration in the second context still needs to be verified.
204f4a2713aSLionel Sambuc     std::deque<Decl *> DeclsToCheck;
205f4a2713aSLionel Sambuc 
206f4a2713aSLionel Sambuc     /// \brief Declaration (from, to) pairs that are known not to be equivalent
207f4a2713aSLionel Sambuc     /// (which we have already complained about).
208f4a2713aSLionel Sambuc     llvm::DenseSet<std::pair<Decl *, Decl *> > &NonEquivalentDecls;
209f4a2713aSLionel Sambuc 
210f4a2713aSLionel Sambuc     /// \brief Whether we're being strict about the spelling of types when
211f4a2713aSLionel Sambuc     /// unifying two types.
212f4a2713aSLionel Sambuc     bool StrictTypeSpelling;
213f4a2713aSLionel Sambuc 
214f4a2713aSLionel Sambuc     /// \brief Whether to complain about failures.
215f4a2713aSLionel Sambuc     bool Complain;
216f4a2713aSLionel Sambuc 
217f4a2713aSLionel Sambuc     /// \brief \c true if the last diagnostic came from C2.
218f4a2713aSLionel Sambuc     bool LastDiagFromC2;
219f4a2713aSLionel Sambuc 
StructuralEquivalenceContext__anon6f8cf8560111::StructuralEquivalenceContext220f4a2713aSLionel Sambuc     StructuralEquivalenceContext(ASTContext &C1, ASTContext &C2,
221f4a2713aSLionel Sambuc                llvm::DenseSet<std::pair<Decl *, Decl *> > &NonEquivalentDecls,
222f4a2713aSLionel Sambuc                                  bool StrictTypeSpelling = false,
223f4a2713aSLionel Sambuc                                  bool Complain = true)
224f4a2713aSLionel Sambuc       : C1(C1), C2(C2), NonEquivalentDecls(NonEquivalentDecls),
225f4a2713aSLionel Sambuc         StrictTypeSpelling(StrictTypeSpelling), Complain(Complain),
226f4a2713aSLionel Sambuc         LastDiagFromC2(false) {}
227f4a2713aSLionel Sambuc 
228f4a2713aSLionel Sambuc     /// \brief Determine whether the two declarations are structurally
229f4a2713aSLionel Sambuc     /// equivalent.
230f4a2713aSLionel Sambuc     bool IsStructurallyEquivalent(Decl *D1, Decl *D2);
231f4a2713aSLionel Sambuc 
232f4a2713aSLionel Sambuc     /// \brief Determine whether the two types are structurally equivalent.
233f4a2713aSLionel Sambuc     bool IsStructurallyEquivalent(QualType T1, QualType T2);
234f4a2713aSLionel Sambuc 
235f4a2713aSLionel Sambuc   private:
236f4a2713aSLionel Sambuc     /// \brief Finish checking all of the structural equivalences.
237f4a2713aSLionel Sambuc     ///
238f4a2713aSLionel Sambuc     /// \returns true if an error occurred, false otherwise.
239f4a2713aSLionel Sambuc     bool Finish();
240f4a2713aSLionel Sambuc 
241f4a2713aSLionel Sambuc   public:
Diag1__anon6f8cf8560111::StructuralEquivalenceContext242f4a2713aSLionel Sambuc     DiagnosticBuilder Diag1(SourceLocation Loc, unsigned DiagID) {
243f4a2713aSLionel Sambuc       assert(Complain && "Not allowed to complain");
244f4a2713aSLionel Sambuc       if (LastDiagFromC2)
245f4a2713aSLionel Sambuc         C1.getDiagnostics().notePriorDiagnosticFrom(C2.getDiagnostics());
246f4a2713aSLionel Sambuc       LastDiagFromC2 = false;
247f4a2713aSLionel Sambuc       return C1.getDiagnostics().Report(Loc, DiagID);
248f4a2713aSLionel Sambuc     }
249f4a2713aSLionel Sambuc 
Diag2__anon6f8cf8560111::StructuralEquivalenceContext250f4a2713aSLionel Sambuc     DiagnosticBuilder Diag2(SourceLocation Loc, unsigned DiagID) {
251f4a2713aSLionel Sambuc       assert(Complain && "Not allowed to complain");
252f4a2713aSLionel Sambuc       if (!LastDiagFromC2)
253f4a2713aSLionel Sambuc         C2.getDiagnostics().notePriorDiagnosticFrom(C1.getDiagnostics());
254f4a2713aSLionel Sambuc       LastDiagFromC2 = true;
255f4a2713aSLionel Sambuc       return C2.getDiagnostics().Report(Loc, DiagID);
256f4a2713aSLionel Sambuc     }
257f4a2713aSLionel Sambuc   };
258f4a2713aSLionel Sambuc }
259f4a2713aSLionel Sambuc 
260f4a2713aSLionel Sambuc static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
261f4a2713aSLionel Sambuc                                      QualType T1, QualType T2);
262f4a2713aSLionel Sambuc static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
263f4a2713aSLionel Sambuc                                      Decl *D1, Decl *D2);
264f4a2713aSLionel Sambuc 
265f4a2713aSLionel Sambuc /// \brief Determine structural equivalence of two expressions.
IsStructurallyEquivalent(StructuralEquivalenceContext & Context,Expr * E1,Expr * E2)266f4a2713aSLionel Sambuc static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
267f4a2713aSLionel Sambuc                                      Expr *E1, Expr *E2) {
268f4a2713aSLionel Sambuc   if (!E1 || !E2)
269f4a2713aSLionel Sambuc     return E1 == E2;
270f4a2713aSLionel Sambuc 
271f4a2713aSLionel Sambuc   // FIXME: Actually perform a structural comparison!
272f4a2713aSLionel Sambuc   return true;
273f4a2713aSLionel Sambuc }
274f4a2713aSLionel Sambuc 
275f4a2713aSLionel Sambuc /// \brief Determine whether two identifiers are equivalent.
IsStructurallyEquivalent(const IdentifierInfo * Name1,const IdentifierInfo * Name2)276f4a2713aSLionel Sambuc static bool IsStructurallyEquivalent(const IdentifierInfo *Name1,
277f4a2713aSLionel Sambuc                                      const IdentifierInfo *Name2) {
278f4a2713aSLionel Sambuc   if (!Name1 || !Name2)
279f4a2713aSLionel Sambuc     return Name1 == Name2;
280f4a2713aSLionel Sambuc 
281f4a2713aSLionel Sambuc   return Name1->getName() == Name2->getName();
282f4a2713aSLionel Sambuc }
283f4a2713aSLionel Sambuc 
284f4a2713aSLionel Sambuc /// \brief Determine whether two nested-name-specifiers are equivalent.
IsStructurallyEquivalent(StructuralEquivalenceContext & Context,NestedNameSpecifier * NNS1,NestedNameSpecifier * NNS2)285f4a2713aSLionel Sambuc static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
286f4a2713aSLionel Sambuc                                      NestedNameSpecifier *NNS1,
287f4a2713aSLionel Sambuc                                      NestedNameSpecifier *NNS2) {
288f4a2713aSLionel Sambuc   // FIXME: Implement!
289f4a2713aSLionel Sambuc   return true;
290f4a2713aSLionel Sambuc }
291f4a2713aSLionel Sambuc 
292f4a2713aSLionel Sambuc /// \brief Determine whether two template arguments are equivalent.
IsStructurallyEquivalent(StructuralEquivalenceContext & Context,const TemplateArgument & Arg1,const TemplateArgument & Arg2)293f4a2713aSLionel Sambuc static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
294f4a2713aSLionel Sambuc                                      const TemplateArgument &Arg1,
295f4a2713aSLionel Sambuc                                      const TemplateArgument &Arg2) {
296f4a2713aSLionel Sambuc   if (Arg1.getKind() != Arg2.getKind())
297f4a2713aSLionel Sambuc     return false;
298f4a2713aSLionel Sambuc 
299f4a2713aSLionel Sambuc   switch (Arg1.getKind()) {
300f4a2713aSLionel Sambuc   case TemplateArgument::Null:
301f4a2713aSLionel Sambuc     return true;
302f4a2713aSLionel Sambuc 
303f4a2713aSLionel Sambuc   case TemplateArgument::Type:
304f4a2713aSLionel Sambuc     return Context.IsStructurallyEquivalent(Arg1.getAsType(), Arg2.getAsType());
305f4a2713aSLionel Sambuc 
306f4a2713aSLionel Sambuc   case TemplateArgument::Integral:
307f4a2713aSLionel Sambuc     if (!Context.IsStructurallyEquivalent(Arg1.getIntegralType(),
308f4a2713aSLionel Sambuc                                           Arg2.getIntegralType()))
309f4a2713aSLionel Sambuc       return false;
310f4a2713aSLionel Sambuc 
311f4a2713aSLionel Sambuc     return llvm::APSInt::isSameValue(Arg1.getAsIntegral(), Arg2.getAsIntegral());
312f4a2713aSLionel Sambuc 
313f4a2713aSLionel Sambuc   case TemplateArgument::Declaration:
314f4a2713aSLionel Sambuc     return Context.IsStructurallyEquivalent(Arg1.getAsDecl(), Arg2.getAsDecl());
315f4a2713aSLionel Sambuc 
316f4a2713aSLionel Sambuc   case TemplateArgument::NullPtr:
317f4a2713aSLionel Sambuc     return true; // FIXME: Is this correct?
318f4a2713aSLionel Sambuc 
319f4a2713aSLionel Sambuc   case TemplateArgument::Template:
320f4a2713aSLionel Sambuc     return IsStructurallyEquivalent(Context,
321f4a2713aSLionel Sambuc                                     Arg1.getAsTemplate(),
322f4a2713aSLionel Sambuc                                     Arg2.getAsTemplate());
323f4a2713aSLionel Sambuc 
324f4a2713aSLionel Sambuc   case TemplateArgument::TemplateExpansion:
325f4a2713aSLionel Sambuc     return IsStructurallyEquivalent(Context,
326f4a2713aSLionel Sambuc                                     Arg1.getAsTemplateOrTemplatePattern(),
327f4a2713aSLionel Sambuc                                     Arg2.getAsTemplateOrTemplatePattern());
328f4a2713aSLionel Sambuc 
329f4a2713aSLionel Sambuc   case TemplateArgument::Expression:
330f4a2713aSLionel Sambuc     return IsStructurallyEquivalent(Context,
331f4a2713aSLionel Sambuc                                     Arg1.getAsExpr(), Arg2.getAsExpr());
332f4a2713aSLionel Sambuc 
333f4a2713aSLionel Sambuc   case TemplateArgument::Pack:
334f4a2713aSLionel Sambuc     if (Arg1.pack_size() != Arg2.pack_size())
335f4a2713aSLionel Sambuc       return false;
336f4a2713aSLionel Sambuc 
337f4a2713aSLionel Sambuc     for (unsigned I = 0, N = Arg1.pack_size(); I != N; ++I)
338f4a2713aSLionel Sambuc       if (!IsStructurallyEquivalent(Context,
339f4a2713aSLionel Sambuc                                     Arg1.pack_begin()[I],
340f4a2713aSLionel Sambuc                                     Arg2.pack_begin()[I]))
341f4a2713aSLionel Sambuc         return false;
342f4a2713aSLionel Sambuc 
343f4a2713aSLionel Sambuc     return true;
344f4a2713aSLionel Sambuc   }
345f4a2713aSLionel Sambuc 
346f4a2713aSLionel Sambuc   llvm_unreachable("Invalid template argument kind");
347f4a2713aSLionel Sambuc }
348f4a2713aSLionel Sambuc 
349f4a2713aSLionel Sambuc /// \brief Determine structural equivalence for the common part of array
350f4a2713aSLionel Sambuc /// types.
IsArrayStructurallyEquivalent(StructuralEquivalenceContext & Context,const ArrayType * Array1,const ArrayType * Array2)351f4a2713aSLionel Sambuc static bool IsArrayStructurallyEquivalent(StructuralEquivalenceContext &Context,
352f4a2713aSLionel Sambuc                                           const ArrayType *Array1,
353f4a2713aSLionel Sambuc                                           const ArrayType *Array2) {
354f4a2713aSLionel Sambuc   if (!IsStructurallyEquivalent(Context,
355f4a2713aSLionel Sambuc                                 Array1->getElementType(),
356f4a2713aSLionel Sambuc                                 Array2->getElementType()))
357f4a2713aSLionel Sambuc     return false;
358f4a2713aSLionel Sambuc   if (Array1->getSizeModifier() != Array2->getSizeModifier())
359f4a2713aSLionel Sambuc     return false;
360f4a2713aSLionel Sambuc   if (Array1->getIndexTypeQualifiers() != Array2->getIndexTypeQualifiers())
361f4a2713aSLionel Sambuc     return false;
362f4a2713aSLionel Sambuc 
363f4a2713aSLionel Sambuc   return true;
364f4a2713aSLionel Sambuc }
365f4a2713aSLionel Sambuc 
366f4a2713aSLionel Sambuc /// \brief Determine structural equivalence of two types.
IsStructurallyEquivalent(StructuralEquivalenceContext & Context,QualType T1,QualType T2)367f4a2713aSLionel Sambuc static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
368f4a2713aSLionel Sambuc                                      QualType T1, QualType T2) {
369f4a2713aSLionel Sambuc   if (T1.isNull() || T2.isNull())
370f4a2713aSLionel Sambuc     return T1.isNull() && T2.isNull();
371f4a2713aSLionel Sambuc 
372f4a2713aSLionel Sambuc   if (!Context.StrictTypeSpelling) {
373f4a2713aSLionel Sambuc     // We aren't being strict about token-to-token equivalence of types,
374f4a2713aSLionel Sambuc     // so map down to the canonical type.
375f4a2713aSLionel Sambuc     T1 = Context.C1.getCanonicalType(T1);
376f4a2713aSLionel Sambuc     T2 = Context.C2.getCanonicalType(T2);
377f4a2713aSLionel Sambuc   }
378f4a2713aSLionel Sambuc 
379f4a2713aSLionel Sambuc   if (T1.getQualifiers() != T2.getQualifiers())
380f4a2713aSLionel Sambuc     return false;
381f4a2713aSLionel Sambuc 
382f4a2713aSLionel Sambuc   Type::TypeClass TC = T1->getTypeClass();
383f4a2713aSLionel Sambuc 
384f4a2713aSLionel Sambuc   if (T1->getTypeClass() != T2->getTypeClass()) {
385f4a2713aSLionel Sambuc     // Compare function types with prototypes vs. without prototypes as if
386f4a2713aSLionel Sambuc     // both did not have prototypes.
387f4a2713aSLionel Sambuc     if (T1->getTypeClass() == Type::FunctionProto &&
388f4a2713aSLionel Sambuc         T2->getTypeClass() == Type::FunctionNoProto)
389f4a2713aSLionel Sambuc       TC = Type::FunctionNoProto;
390f4a2713aSLionel Sambuc     else if (T1->getTypeClass() == Type::FunctionNoProto &&
391f4a2713aSLionel Sambuc              T2->getTypeClass() == Type::FunctionProto)
392f4a2713aSLionel Sambuc       TC = Type::FunctionNoProto;
393f4a2713aSLionel Sambuc     else
394f4a2713aSLionel Sambuc       return false;
395f4a2713aSLionel Sambuc   }
396f4a2713aSLionel Sambuc 
397f4a2713aSLionel Sambuc   switch (TC) {
398f4a2713aSLionel Sambuc   case Type::Builtin:
399f4a2713aSLionel Sambuc     // FIXME: Deal with Char_S/Char_U.
400f4a2713aSLionel Sambuc     if (cast<BuiltinType>(T1)->getKind() != cast<BuiltinType>(T2)->getKind())
401f4a2713aSLionel Sambuc       return false;
402f4a2713aSLionel Sambuc     break;
403f4a2713aSLionel Sambuc 
404f4a2713aSLionel Sambuc   case Type::Complex:
405f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context,
406f4a2713aSLionel Sambuc                                   cast<ComplexType>(T1)->getElementType(),
407f4a2713aSLionel Sambuc                                   cast<ComplexType>(T2)->getElementType()))
408f4a2713aSLionel Sambuc       return false;
409f4a2713aSLionel Sambuc     break;
410f4a2713aSLionel Sambuc 
411*0a6a1f1dSLionel Sambuc   case Type::Adjusted:
412f4a2713aSLionel Sambuc   case Type::Decayed:
413f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context,
414*0a6a1f1dSLionel Sambuc                                   cast<AdjustedType>(T1)->getOriginalType(),
415*0a6a1f1dSLionel Sambuc                                   cast<AdjustedType>(T2)->getOriginalType()))
416f4a2713aSLionel Sambuc       return false;
417f4a2713aSLionel Sambuc     break;
418f4a2713aSLionel Sambuc 
419f4a2713aSLionel Sambuc   case Type::Pointer:
420f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context,
421f4a2713aSLionel Sambuc                                   cast<PointerType>(T1)->getPointeeType(),
422f4a2713aSLionel Sambuc                                   cast<PointerType>(T2)->getPointeeType()))
423f4a2713aSLionel Sambuc       return false;
424f4a2713aSLionel Sambuc     break;
425f4a2713aSLionel Sambuc 
426f4a2713aSLionel Sambuc   case Type::BlockPointer:
427f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context,
428f4a2713aSLionel Sambuc                                   cast<BlockPointerType>(T1)->getPointeeType(),
429f4a2713aSLionel Sambuc                                   cast<BlockPointerType>(T2)->getPointeeType()))
430f4a2713aSLionel Sambuc       return false;
431f4a2713aSLionel Sambuc     break;
432f4a2713aSLionel Sambuc 
433f4a2713aSLionel Sambuc   case Type::LValueReference:
434f4a2713aSLionel Sambuc   case Type::RValueReference: {
435f4a2713aSLionel Sambuc     const ReferenceType *Ref1 = cast<ReferenceType>(T1);
436f4a2713aSLionel Sambuc     const ReferenceType *Ref2 = cast<ReferenceType>(T2);
437f4a2713aSLionel Sambuc     if (Ref1->isSpelledAsLValue() != Ref2->isSpelledAsLValue())
438f4a2713aSLionel Sambuc       return false;
439f4a2713aSLionel Sambuc     if (Ref1->isInnerRef() != Ref2->isInnerRef())
440f4a2713aSLionel Sambuc       return false;
441f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context,
442f4a2713aSLionel Sambuc                                   Ref1->getPointeeTypeAsWritten(),
443f4a2713aSLionel Sambuc                                   Ref2->getPointeeTypeAsWritten()))
444f4a2713aSLionel Sambuc       return false;
445f4a2713aSLionel Sambuc     break;
446f4a2713aSLionel Sambuc   }
447f4a2713aSLionel Sambuc 
448f4a2713aSLionel Sambuc   case Type::MemberPointer: {
449f4a2713aSLionel Sambuc     const MemberPointerType *MemPtr1 = cast<MemberPointerType>(T1);
450f4a2713aSLionel Sambuc     const MemberPointerType *MemPtr2 = cast<MemberPointerType>(T2);
451f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context,
452f4a2713aSLionel Sambuc                                   MemPtr1->getPointeeType(),
453f4a2713aSLionel Sambuc                                   MemPtr2->getPointeeType()))
454f4a2713aSLionel Sambuc       return false;
455f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context,
456f4a2713aSLionel Sambuc                                   QualType(MemPtr1->getClass(), 0),
457f4a2713aSLionel Sambuc                                   QualType(MemPtr2->getClass(), 0)))
458f4a2713aSLionel Sambuc       return false;
459f4a2713aSLionel Sambuc     break;
460f4a2713aSLionel Sambuc   }
461f4a2713aSLionel Sambuc 
462f4a2713aSLionel Sambuc   case Type::ConstantArray: {
463f4a2713aSLionel Sambuc     const ConstantArrayType *Array1 = cast<ConstantArrayType>(T1);
464f4a2713aSLionel Sambuc     const ConstantArrayType *Array2 = cast<ConstantArrayType>(T2);
465f4a2713aSLionel Sambuc     if (!llvm::APInt::isSameValue(Array1->getSize(), Array2->getSize()))
466f4a2713aSLionel Sambuc       return false;
467f4a2713aSLionel Sambuc 
468f4a2713aSLionel Sambuc     if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
469f4a2713aSLionel Sambuc       return false;
470f4a2713aSLionel Sambuc     break;
471f4a2713aSLionel Sambuc   }
472f4a2713aSLionel Sambuc 
473f4a2713aSLionel Sambuc   case Type::IncompleteArray:
474f4a2713aSLionel Sambuc     if (!IsArrayStructurallyEquivalent(Context,
475f4a2713aSLionel Sambuc                                        cast<ArrayType>(T1),
476f4a2713aSLionel Sambuc                                        cast<ArrayType>(T2)))
477f4a2713aSLionel Sambuc       return false;
478f4a2713aSLionel Sambuc     break;
479f4a2713aSLionel Sambuc 
480f4a2713aSLionel Sambuc   case Type::VariableArray: {
481f4a2713aSLionel Sambuc     const VariableArrayType *Array1 = cast<VariableArrayType>(T1);
482f4a2713aSLionel Sambuc     const VariableArrayType *Array2 = cast<VariableArrayType>(T2);
483f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context,
484f4a2713aSLionel Sambuc                                   Array1->getSizeExpr(), Array2->getSizeExpr()))
485f4a2713aSLionel Sambuc       return false;
486f4a2713aSLionel Sambuc 
487f4a2713aSLionel Sambuc     if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
488f4a2713aSLionel Sambuc       return false;
489f4a2713aSLionel Sambuc 
490f4a2713aSLionel Sambuc     break;
491f4a2713aSLionel Sambuc   }
492f4a2713aSLionel Sambuc 
493f4a2713aSLionel Sambuc   case Type::DependentSizedArray: {
494f4a2713aSLionel Sambuc     const DependentSizedArrayType *Array1 = cast<DependentSizedArrayType>(T1);
495f4a2713aSLionel Sambuc     const DependentSizedArrayType *Array2 = cast<DependentSizedArrayType>(T2);
496f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context,
497f4a2713aSLionel Sambuc                                   Array1->getSizeExpr(), Array2->getSizeExpr()))
498f4a2713aSLionel Sambuc       return false;
499f4a2713aSLionel Sambuc 
500f4a2713aSLionel Sambuc     if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
501f4a2713aSLionel Sambuc       return false;
502f4a2713aSLionel Sambuc 
503f4a2713aSLionel Sambuc     break;
504f4a2713aSLionel Sambuc   }
505f4a2713aSLionel Sambuc 
506f4a2713aSLionel Sambuc   case Type::DependentSizedExtVector: {
507f4a2713aSLionel Sambuc     const DependentSizedExtVectorType *Vec1
508f4a2713aSLionel Sambuc       = cast<DependentSizedExtVectorType>(T1);
509f4a2713aSLionel Sambuc     const DependentSizedExtVectorType *Vec2
510f4a2713aSLionel Sambuc       = cast<DependentSizedExtVectorType>(T2);
511f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context,
512f4a2713aSLionel Sambuc                                   Vec1->getSizeExpr(), Vec2->getSizeExpr()))
513f4a2713aSLionel Sambuc       return false;
514f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context,
515f4a2713aSLionel Sambuc                                   Vec1->getElementType(),
516f4a2713aSLionel Sambuc                                   Vec2->getElementType()))
517f4a2713aSLionel Sambuc       return false;
518f4a2713aSLionel Sambuc     break;
519f4a2713aSLionel Sambuc   }
520f4a2713aSLionel Sambuc 
521f4a2713aSLionel Sambuc   case Type::Vector:
522f4a2713aSLionel Sambuc   case Type::ExtVector: {
523f4a2713aSLionel Sambuc     const VectorType *Vec1 = cast<VectorType>(T1);
524f4a2713aSLionel Sambuc     const VectorType *Vec2 = cast<VectorType>(T2);
525f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context,
526f4a2713aSLionel Sambuc                                   Vec1->getElementType(),
527f4a2713aSLionel Sambuc                                   Vec2->getElementType()))
528f4a2713aSLionel Sambuc       return false;
529f4a2713aSLionel Sambuc     if (Vec1->getNumElements() != Vec2->getNumElements())
530f4a2713aSLionel Sambuc       return false;
531f4a2713aSLionel Sambuc     if (Vec1->getVectorKind() != Vec2->getVectorKind())
532f4a2713aSLionel Sambuc       return false;
533f4a2713aSLionel Sambuc     break;
534f4a2713aSLionel Sambuc   }
535f4a2713aSLionel Sambuc 
536f4a2713aSLionel Sambuc   case Type::FunctionProto: {
537f4a2713aSLionel Sambuc     const FunctionProtoType *Proto1 = cast<FunctionProtoType>(T1);
538f4a2713aSLionel Sambuc     const FunctionProtoType *Proto2 = cast<FunctionProtoType>(T2);
539*0a6a1f1dSLionel Sambuc     if (Proto1->getNumParams() != Proto2->getNumParams())
540f4a2713aSLionel Sambuc       return false;
541*0a6a1f1dSLionel Sambuc     for (unsigned I = 0, N = Proto1->getNumParams(); I != N; ++I) {
542*0a6a1f1dSLionel Sambuc       if (!IsStructurallyEquivalent(Context, Proto1->getParamType(I),
543*0a6a1f1dSLionel Sambuc                                     Proto2->getParamType(I)))
544f4a2713aSLionel Sambuc         return false;
545f4a2713aSLionel Sambuc     }
546f4a2713aSLionel Sambuc     if (Proto1->isVariadic() != Proto2->isVariadic())
547f4a2713aSLionel Sambuc       return false;
548f4a2713aSLionel Sambuc     if (Proto1->getExceptionSpecType() != Proto2->getExceptionSpecType())
549f4a2713aSLionel Sambuc       return false;
550f4a2713aSLionel Sambuc     if (Proto1->getExceptionSpecType() == EST_Dynamic) {
551f4a2713aSLionel Sambuc       if (Proto1->getNumExceptions() != Proto2->getNumExceptions())
552f4a2713aSLionel Sambuc         return false;
553f4a2713aSLionel Sambuc       for (unsigned I = 0, N = Proto1->getNumExceptions(); I != N; ++I) {
554f4a2713aSLionel Sambuc         if (!IsStructurallyEquivalent(Context,
555f4a2713aSLionel Sambuc                                       Proto1->getExceptionType(I),
556f4a2713aSLionel Sambuc                                       Proto2->getExceptionType(I)))
557f4a2713aSLionel Sambuc           return false;
558f4a2713aSLionel Sambuc       }
559f4a2713aSLionel Sambuc     } else if (Proto1->getExceptionSpecType() == EST_ComputedNoexcept) {
560f4a2713aSLionel Sambuc       if (!IsStructurallyEquivalent(Context,
561f4a2713aSLionel Sambuc                                     Proto1->getNoexceptExpr(),
562f4a2713aSLionel Sambuc                                     Proto2->getNoexceptExpr()))
563f4a2713aSLionel Sambuc         return false;
564f4a2713aSLionel Sambuc     }
565f4a2713aSLionel Sambuc     if (Proto1->getTypeQuals() != Proto2->getTypeQuals())
566f4a2713aSLionel Sambuc       return false;
567f4a2713aSLionel Sambuc 
568f4a2713aSLionel Sambuc     // Fall through to check the bits common with FunctionNoProtoType.
569f4a2713aSLionel Sambuc   }
570f4a2713aSLionel Sambuc 
571f4a2713aSLionel Sambuc   case Type::FunctionNoProto: {
572f4a2713aSLionel Sambuc     const FunctionType *Function1 = cast<FunctionType>(T1);
573f4a2713aSLionel Sambuc     const FunctionType *Function2 = cast<FunctionType>(T2);
574*0a6a1f1dSLionel Sambuc     if (!IsStructurallyEquivalent(Context, Function1->getReturnType(),
575*0a6a1f1dSLionel Sambuc                                   Function2->getReturnType()))
576f4a2713aSLionel Sambuc       return false;
577f4a2713aSLionel Sambuc       if (Function1->getExtInfo() != Function2->getExtInfo())
578f4a2713aSLionel Sambuc         return false;
579f4a2713aSLionel Sambuc     break;
580f4a2713aSLionel Sambuc   }
581f4a2713aSLionel Sambuc 
582f4a2713aSLionel Sambuc   case Type::UnresolvedUsing:
583f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context,
584f4a2713aSLionel Sambuc                                   cast<UnresolvedUsingType>(T1)->getDecl(),
585f4a2713aSLionel Sambuc                                   cast<UnresolvedUsingType>(T2)->getDecl()))
586f4a2713aSLionel Sambuc       return false;
587f4a2713aSLionel Sambuc 
588f4a2713aSLionel Sambuc     break;
589f4a2713aSLionel Sambuc 
590f4a2713aSLionel Sambuc   case Type::Attributed:
591f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context,
592f4a2713aSLionel Sambuc                                   cast<AttributedType>(T1)->getModifiedType(),
593f4a2713aSLionel Sambuc                                   cast<AttributedType>(T2)->getModifiedType()))
594f4a2713aSLionel Sambuc       return false;
595f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context,
596f4a2713aSLionel Sambuc                                 cast<AttributedType>(T1)->getEquivalentType(),
597f4a2713aSLionel Sambuc                                 cast<AttributedType>(T2)->getEquivalentType()))
598f4a2713aSLionel Sambuc       return false;
599f4a2713aSLionel Sambuc     break;
600f4a2713aSLionel Sambuc 
601f4a2713aSLionel Sambuc   case Type::Paren:
602f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context,
603f4a2713aSLionel Sambuc                                   cast<ParenType>(T1)->getInnerType(),
604f4a2713aSLionel Sambuc                                   cast<ParenType>(T2)->getInnerType()))
605f4a2713aSLionel Sambuc       return false;
606f4a2713aSLionel Sambuc     break;
607f4a2713aSLionel Sambuc 
608f4a2713aSLionel Sambuc   case Type::Typedef:
609f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context,
610f4a2713aSLionel Sambuc                                   cast<TypedefType>(T1)->getDecl(),
611f4a2713aSLionel Sambuc                                   cast<TypedefType>(T2)->getDecl()))
612f4a2713aSLionel Sambuc       return false;
613f4a2713aSLionel Sambuc     break;
614f4a2713aSLionel Sambuc 
615f4a2713aSLionel Sambuc   case Type::TypeOfExpr:
616f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context,
617f4a2713aSLionel Sambuc                                 cast<TypeOfExprType>(T1)->getUnderlyingExpr(),
618f4a2713aSLionel Sambuc                                 cast<TypeOfExprType>(T2)->getUnderlyingExpr()))
619f4a2713aSLionel Sambuc       return false;
620f4a2713aSLionel Sambuc     break;
621f4a2713aSLionel Sambuc 
622f4a2713aSLionel Sambuc   case Type::TypeOf:
623f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context,
624f4a2713aSLionel Sambuc                                   cast<TypeOfType>(T1)->getUnderlyingType(),
625f4a2713aSLionel Sambuc                                   cast<TypeOfType>(T2)->getUnderlyingType()))
626f4a2713aSLionel Sambuc       return false;
627f4a2713aSLionel Sambuc     break;
628f4a2713aSLionel Sambuc 
629f4a2713aSLionel Sambuc   case Type::UnaryTransform:
630f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context,
631f4a2713aSLionel Sambuc                              cast<UnaryTransformType>(T1)->getUnderlyingType(),
632f4a2713aSLionel Sambuc                              cast<UnaryTransformType>(T1)->getUnderlyingType()))
633f4a2713aSLionel Sambuc       return false;
634f4a2713aSLionel Sambuc     break;
635f4a2713aSLionel Sambuc 
636f4a2713aSLionel Sambuc   case Type::Decltype:
637f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context,
638f4a2713aSLionel Sambuc                                   cast<DecltypeType>(T1)->getUnderlyingExpr(),
639f4a2713aSLionel Sambuc                                   cast<DecltypeType>(T2)->getUnderlyingExpr()))
640f4a2713aSLionel Sambuc       return false;
641f4a2713aSLionel Sambuc     break;
642f4a2713aSLionel Sambuc 
643f4a2713aSLionel Sambuc   case Type::Auto:
644f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context,
645f4a2713aSLionel Sambuc                                   cast<AutoType>(T1)->getDeducedType(),
646f4a2713aSLionel Sambuc                                   cast<AutoType>(T2)->getDeducedType()))
647f4a2713aSLionel Sambuc       return false;
648f4a2713aSLionel Sambuc     break;
649f4a2713aSLionel Sambuc 
650f4a2713aSLionel Sambuc   case Type::Record:
651f4a2713aSLionel Sambuc   case Type::Enum:
652f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context,
653f4a2713aSLionel Sambuc                                   cast<TagType>(T1)->getDecl(),
654f4a2713aSLionel Sambuc                                   cast<TagType>(T2)->getDecl()))
655f4a2713aSLionel Sambuc       return false;
656f4a2713aSLionel Sambuc     break;
657f4a2713aSLionel Sambuc 
658f4a2713aSLionel Sambuc   case Type::TemplateTypeParm: {
659f4a2713aSLionel Sambuc     const TemplateTypeParmType *Parm1 = cast<TemplateTypeParmType>(T1);
660f4a2713aSLionel Sambuc     const TemplateTypeParmType *Parm2 = cast<TemplateTypeParmType>(T2);
661f4a2713aSLionel Sambuc     if (Parm1->getDepth() != Parm2->getDepth())
662f4a2713aSLionel Sambuc       return false;
663f4a2713aSLionel Sambuc     if (Parm1->getIndex() != Parm2->getIndex())
664f4a2713aSLionel Sambuc       return false;
665f4a2713aSLionel Sambuc     if (Parm1->isParameterPack() != Parm2->isParameterPack())
666f4a2713aSLionel Sambuc       return false;
667f4a2713aSLionel Sambuc 
668f4a2713aSLionel Sambuc     // Names of template type parameters are never significant.
669f4a2713aSLionel Sambuc     break;
670f4a2713aSLionel Sambuc   }
671f4a2713aSLionel Sambuc 
672f4a2713aSLionel Sambuc   case Type::SubstTemplateTypeParm: {
673f4a2713aSLionel Sambuc     const SubstTemplateTypeParmType *Subst1
674f4a2713aSLionel Sambuc       = cast<SubstTemplateTypeParmType>(T1);
675f4a2713aSLionel Sambuc     const SubstTemplateTypeParmType *Subst2
676f4a2713aSLionel Sambuc       = cast<SubstTemplateTypeParmType>(T2);
677f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context,
678f4a2713aSLionel Sambuc                                   QualType(Subst1->getReplacedParameter(), 0),
679f4a2713aSLionel Sambuc                                   QualType(Subst2->getReplacedParameter(), 0)))
680f4a2713aSLionel Sambuc       return false;
681f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context,
682f4a2713aSLionel Sambuc                                   Subst1->getReplacementType(),
683f4a2713aSLionel Sambuc                                   Subst2->getReplacementType()))
684f4a2713aSLionel Sambuc       return false;
685f4a2713aSLionel Sambuc     break;
686f4a2713aSLionel Sambuc   }
687f4a2713aSLionel Sambuc 
688f4a2713aSLionel Sambuc   case Type::SubstTemplateTypeParmPack: {
689f4a2713aSLionel Sambuc     const SubstTemplateTypeParmPackType *Subst1
690f4a2713aSLionel Sambuc       = cast<SubstTemplateTypeParmPackType>(T1);
691f4a2713aSLionel Sambuc     const SubstTemplateTypeParmPackType *Subst2
692f4a2713aSLionel Sambuc       = cast<SubstTemplateTypeParmPackType>(T2);
693f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context,
694f4a2713aSLionel Sambuc                                   QualType(Subst1->getReplacedParameter(), 0),
695f4a2713aSLionel Sambuc                                   QualType(Subst2->getReplacedParameter(), 0)))
696f4a2713aSLionel Sambuc       return false;
697f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context,
698f4a2713aSLionel Sambuc                                   Subst1->getArgumentPack(),
699f4a2713aSLionel Sambuc                                   Subst2->getArgumentPack()))
700f4a2713aSLionel Sambuc       return false;
701f4a2713aSLionel Sambuc     break;
702f4a2713aSLionel Sambuc   }
703f4a2713aSLionel Sambuc   case Type::TemplateSpecialization: {
704f4a2713aSLionel Sambuc     const TemplateSpecializationType *Spec1
705f4a2713aSLionel Sambuc       = cast<TemplateSpecializationType>(T1);
706f4a2713aSLionel Sambuc     const TemplateSpecializationType *Spec2
707f4a2713aSLionel Sambuc       = cast<TemplateSpecializationType>(T2);
708f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context,
709f4a2713aSLionel Sambuc                                   Spec1->getTemplateName(),
710f4a2713aSLionel Sambuc                                   Spec2->getTemplateName()))
711f4a2713aSLionel Sambuc       return false;
712f4a2713aSLionel Sambuc     if (Spec1->getNumArgs() != Spec2->getNumArgs())
713f4a2713aSLionel Sambuc       return false;
714f4a2713aSLionel Sambuc     for (unsigned I = 0, N = Spec1->getNumArgs(); I != N; ++I) {
715f4a2713aSLionel Sambuc       if (!IsStructurallyEquivalent(Context,
716f4a2713aSLionel Sambuc                                     Spec1->getArg(I), Spec2->getArg(I)))
717f4a2713aSLionel Sambuc         return false;
718f4a2713aSLionel Sambuc     }
719f4a2713aSLionel Sambuc     break;
720f4a2713aSLionel Sambuc   }
721f4a2713aSLionel Sambuc 
722f4a2713aSLionel Sambuc   case Type::Elaborated: {
723f4a2713aSLionel Sambuc     const ElaboratedType *Elab1 = cast<ElaboratedType>(T1);
724f4a2713aSLionel Sambuc     const ElaboratedType *Elab2 = cast<ElaboratedType>(T2);
725f4a2713aSLionel Sambuc     // CHECKME: what if a keyword is ETK_None or ETK_typename ?
726f4a2713aSLionel Sambuc     if (Elab1->getKeyword() != Elab2->getKeyword())
727f4a2713aSLionel Sambuc       return false;
728f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context,
729f4a2713aSLionel Sambuc                                   Elab1->getQualifier(),
730f4a2713aSLionel Sambuc                                   Elab2->getQualifier()))
731f4a2713aSLionel Sambuc       return false;
732f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context,
733f4a2713aSLionel Sambuc                                   Elab1->getNamedType(),
734f4a2713aSLionel Sambuc                                   Elab2->getNamedType()))
735f4a2713aSLionel Sambuc       return false;
736f4a2713aSLionel Sambuc     break;
737f4a2713aSLionel Sambuc   }
738f4a2713aSLionel Sambuc 
739f4a2713aSLionel Sambuc   case Type::InjectedClassName: {
740f4a2713aSLionel Sambuc     const InjectedClassNameType *Inj1 = cast<InjectedClassNameType>(T1);
741f4a2713aSLionel Sambuc     const InjectedClassNameType *Inj2 = cast<InjectedClassNameType>(T2);
742f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context,
743f4a2713aSLionel Sambuc                                   Inj1->getInjectedSpecializationType(),
744f4a2713aSLionel Sambuc                                   Inj2->getInjectedSpecializationType()))
745f4a2713aSLionel Sambuc       return false;
746f4a2713aSLionel Sambuc     break;
747f4a2713aSLionel Sambuc   }
748f4a2713aSLionel Sambuc 
749f4a2713aSLionel Sambuc   case Type::DependentName: {
750f4a2713aSLionel Sambuc     const DependentNameType *Typename1 = cast<DependentNameType>(T1);
751f4a2713aSLionel Sambuc     const DependentNameType *Typename2 = cast<DependentNameType>(T2);
752f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context,
753f4a2713aSLionel Sambuc                                   Typename1->getQualifier(),
754f4a2713aSLionel Sambuc                                   Typename2->getQualifier()))
755f4a2713aSLionel Sambuc       return false;
756f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Typename1->getIdentifier(),
757f4a2713aSLionel Sambuc                                   Typename2->getIdentifier()))
758f4a2713aSLionel Sambuc       return false;
759f4a2713aSLionel Sambuc 
760f4a2713aSLionel Sambuc     break;
761f4a2713aSLionel Sambuc   }
762f4a2713aSLionel Sambuc 
763f4a2713aSLionel Sambuc   case Type::DependentTemplateSpecialization: {
764f4a2713aSLionel Sambuc     const DependentTemplateSpecializationType *Spec1 =
765f4a2713aSLionel Sambuc       cast<DependentTemplateSpecializationType>(T1);
766f4a2713aSLionel Sambuc     const DependentTemplateSpecializationType *Spec2 =
767f4a2713aSLionel Sambuc       cast<DependentTemplateSpecializationType>(T2);
768f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context,
769f4a2713aSLionel Sambuc                                   Spec1->getQualifier(),
770f4a2713aSLionel Sambuc                                   Spec2->getQualifier()))
771f4a2713aSLionel Sambuc       return false;
772f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Spec1->getIdentifier(),
773f4a2713aSLionel Sambuc                                   Spec2->getIdentifier()))
774f4a2713aSLionel Sambuc       return false;
775f4a2713aSLionel Sambuc     if (Spec1->getNumArgs() != Spec2->getNumArgs())
776f4a2713aSLionel Sambuc       return false;
777f4a2713aSLionel Sambuc     for (unsigned I = 0, N = Spec1->getNumArgs(); I != N; ++I) {
778f4a2713aSLionel Sambuc       if (!IsStructurallyEquivalent(Context,
779f4a2713aSLionel Sambuc                                     Spec1->getArg(I), Spec2->getArg(I)))
780f4a2713aSLionel Sambuc         return false;
781f4a2713aSLionel Sambuc     }
782f4a2713aSLionel Sambuc     break;
783f4a2713aSLionel Sambuc   }
784f4a2713aSLionel Sambuc 
785f4a2713aSLionel Sambuc   case Type::PackExpansion:
786f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context,
787f4a2713aSLionel Sambuc                                   cast<PackExpansionType>(T1)->getPattern(),
788f4a2713aSLionel Sambuc                                   cast<PackExpansionType>(T2)->getPattern()))
789f4a2713aSLionel Sambuc       return false;
790f4a2713aSLionel Sambuc     break;
791f4a2713aSLionel Sambuc 
792f4a2713aSLionel Sambuc   case Type::ObjCInterface: {
793f4a2713aSLionel Sambuc     const ObjCInterfaceType *Iface1 = cast<ObjCInterfaceType>(T1);
794f4a2713aSLionel Sambuc     const ObjCInterfaceType *Iface2 = cast<ObjCInterfaceType>(T2);
795f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context,
796f4a2713aSLionel Sambuc                                   Iface1->getDecl(), Iface2->getDecl()))
797f4a2713aSLionel Sambuc       return false;
798f4a2713aSLionel Sambuc     break;
799f4a2713aSLionel Sambuc   }
800f4a2713aSLionel Sambuc 
801f4a2713aSLionel Sambuc   case Type::ObjCObject: {
802f4a2713aSLionel Sambuc     const ObjCObjectType *Obj1 = cast<ObjCObjectType>(T1);
803f4a2713aSLionel Sambuc     const ObjCObjectType *Obj2 = cast<ObjCObjectType>(T2);
804f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context,
805f4a2713aSLionel Sambuc                                   Obj1->getBaseType(),
806f4a2713aSLionel Sambuc                                   Obj2->getBaseType()))
807f4a2713aSLionel Sambuc       return false;
808f4a2713aSLionel Sambuc     if (Obj1->getNumProtocols() != Obj2->getNumProtocols())
809f4a2713aSLionel Sambuc       return false;
810f4a2713aSLionel Sambuc     for (unsigned I = 0, N = Obj1->getNumProtocols(); I != N; ++I) {
811f4a2713aSLionel Sambuc       if (!IsStructurallyEquivalent(Context,
812f4a2713aSLionel Sambuc                                     Obj1->getProtocol(I),
813f4a2713aSLionel Sambuc                                     Obj2->getProtocol(I)))
814f4a2713aSLionel Sambuc         return false;
815f4a2713aSLionel Sambuc     }
816f4a2713aSLionel Sambuc     break;
817f4a2713aSLionel Sambuc   }
818f4a2713aSLionel Sambuc 
819f4a2713aSLionel Sambuc   case Type::ObjCObjectPointer: {
820f4a2713aSLionel Sambuc     const ObjCObjectPointerType *Ptr1 = cast<ObjCObjectPointerType>(T1);
821f4a2713aSLionel Sambuc     const ObjCObjectPointerType *Ptr2 = cast<ObjCObjectPointerType>(T2);
822f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context,
823f4a2713aSLionel Sambuc                                   Ptr1->getPointeeType(),
824f4a2713aSLionel Sambuc                                   Ptr2->getPointeeType()))
825f4a2713aSLionel Sambuc       return false;
826f4a2713aSLionel Sambuc     break;
827f4a2713aSLionel Sambuc   }
828f4a2713aSLionel Sambuc 
829f4a2713aSLionel Sambuc   case Type::Atomic: {
830f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context,
831f4a2713aSLionel Sambuc                                   cast<AtomicType>(T1)->getValueType(),
832f4a2713aSLionel Sambuc                                   cast<AtomicType>(T2)->getValueType()))
833f4a2713aSLionel Sambuc       return false;
834f4a2713aSLionel Sambuc     break;
835f4a2713aSLionel Sambuc   }
836f4a2713aSLionel Sambuc 
837f4a2713aSLionel Sambuc   } // end switch
838f4a2713aSLionel Sambuc 
839f4a2713aSLionel Sambuc   return true;
840f4a2713aSLionel Sambuc }
841f4a2713aSLionel Sambuc 
842f4a2713aSLionel Sambuc /// \brief Determine structural equivalence of two fields.
IsStructurallyEquivalent(StructuralEquivalenceContext & Context,FieldDecl * Field1,FieldDecl * Field2)843f4a2713aSLionel Sambuc static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
844f4a2713aSLionel Sambuc                                      FieldDecl *Field1, FieldDecl *Field2) {
845f4a2713aSLionel Sambuc   RecordDecl *Owner2 = cast<RecordDecl>(Field2->getDeclContext());
846f4a2713aSLionel Sambuc 
847f4a2713aSLionel Sambuc   // For anonymous structs/unions, match up the anonymous struct/union type
848f4a2713aSLionel Sambuc   // declarations directly, so that we don't go off searching for anonymous
849f4a2713aSLionel Sambuc   // types
850f4a2713aSLionel Sambuc   if (Field1->isAnonymousStructOrUnion() &&
851f4a2713aSLionel Sambuc       Field2->isAnonymousStructOrUnion()) {
852f4a2713aSLionel Sambuc     RecordDecl *D1 = Field1->getType()->castAs<RecordType>()->getDecl();
853f4a2713aSLionel Sambuc     RecordDecl *D2 = Field2->getType()->castAs<RecordType>()->getDecl();
854f4a2713aSLionel Sambuc     return IsStructurallyEquivalent(Context, D1, D2);
855f4a2713aSLionel Sambuc   }
856f4a2713aSLionel Sambuc 
857f4a2713aSLionel Sambuc   // Check for equivalent field names.
858f4a2713aSLionel Sambuc   IdentifierInfo *Name1 = Field1->getIdentifier();
859f4a2713aSLionel Sambuc   IdentifierInfo *Name2 = Field2->getIdentifier();
860f4a2713aSLionel Sambuc   if (!::IsStructurallyEquivalent(Name1, Name2))
861f4a2713aSLionel Sambuc     return false;
862f4a2713aSLionel Sambuc 
863f4a2713aSLionel Sambuc   if (!IsStructurallyEquivalent(Context,
864f4a2713aSLionel Sambuc                                 Field1->getType(), Field2->getType())) {
865f4a2713aSLionel Sambuc     if (Context.Complain) {
866f4a2713aSLionel Sambuc       Context.Diag2(Owner2->getLocation(), diag::warn_odr_tag_type_inconsistent)
867f4a2713aSLionel Sambuc         << Context.C2.getTypeDeclType(Owner2);
868f4a2713aSLionel Sambuc       Context.Diag2(Field2->getLocation(), diag::note_odr_field)
869f4a2713aSLionel Sambuc         << Field2->getDeclName() << Field2->getType();
870f4a2713aSLionel Sambuc       Context.Diag1(Field1->getLocation(), diag::note_odr_field)
871f4a2713aSLionel Sambuc         << Field1->getDeclName() << Field1->getType();
872f4a2713aSLionel Sambuc     }
873f4a2713aSLionel Sambuc     return false;
874f4a2713aSLionel Sambuc   }
875f4a2713aSLionel Sambuc 
876f4a2713aSLionel Sambuc   if (Field1->isBitField() != Field2->isBitField()) {
877f4a2713aSLionel Sambuc     if (Context.Complain) {
878f4a2713aSLionel Sambuc       Context.Diag2(Owner2->getLocation(), diag::warn_odr_tag_type_inconsistent)
879f4a2713aSLionel Sambuc         << Context.C2.getTypeDeclType(Owner2);
880f4a2713aSLionel Sambuc       if (Field1->isBitField()) {
881f4a2713aSLionel Sambuc         Context.Diag1(Field1->getLocation(), diag::note_odr_bit_field)
882f4a2713aSLionel Sambuc         << Field1->getDeclName() << Field1->getType()
883f4a2713aSLionel Sambuc         << Field1->getBitWidthValue(Context.C1);
884f4a2713aSLionel Sambuc         Context.Diag2(Field2->getLocation(), diag::note_odr_not_bit_field)
885f4a2713aSLionel Sambuc         << Field2->getDeclName();
886f4a2713aSLionel Sambuc       } else {
887f4a2713aSLionel Sambuc         Context.Diag2(Field2->getLocation(), diag::note_odr_bit_field)
888f4a2713aSLionel Sambuc         << Field2->getDeclName() << Field2->getType()
889f4a2713aSLionel Sambuc         << Field2->getBitWidthValue(Context.C2);
890f4a2713aSLionel Sambuc         Context.Diag1(Field1->getLocation(), diag::note_odr_not_bit_field)
891f4a2713aSLionel Sambuc         << Field1->getDeclName();
892f4a2713aSLionel Sambuc       }
893f4a2713aSLionel Sambuc     }
894f4a2713aSLionel Sambuc     return false;
895f4a2713aSLionel Sambuc   }
896f4a2713aSLionel Sambuc 
897f4a2713aSLionel Sambuc   if (Field1->isBitField()) {
898f4a2713aSLionel Sambuc     // Make sure that the bit-fields are the same length.
899f4a2713aSLionel Sambuc     unsigned Bits1 = Field1->getBitWidthValue(Context.C1);
900f4a2713aSLionel Sambuc     unsigned Bits2 = Field2->getBitWidthValue(Context.C2);
901f4a2713aSLionel Sambuc 
902f4a2713aSLionel Sambuc     if (Bits1 != Bits2) {
903f4a2713aSLionel Sambuc       if (Context.Complain) {
904f4a2713aSLionel Sambuc         Context.Diag2(Owner2->getLocation(), diag::warn_odr_tag_type_inconsistent)
905f4a2713aSLionel Sambuc           << Context.C2.getTypeDeclType(Owner2);
906f4a2713aSLionel Sambuc         Context.Diag2(Field2->getLocation(), diag::note_odr_bit_field)
907f4a2713aSLionel Sambuc           << Field2->getDeclName() << Field2->getType() << Bits2;
908f4a2713aSLionel Sambuc         Context.Diag1(Field1->getLocation(), diag::note_odr_bit_field)
909f4a2713aSLionel Sambuc           << Field1->getDeclName() << Field1->getType() << Bits1;
910f4a2713aSLionel Sambuc       }
911f4a2713aSLionel Sambuc       return false;
912f4a2713aSLionel Sambuc     }
913f4a2713aSLionel Sambuc   }
914f4a2713aSLionel Sambuc 
915f4a2713aSLionel Sambuc   return true;
916f4a2713aSLionel Sambuc }
917f4a2713aSLionel Sambuc 
918f4a2713aSLionel Sambuc /// \brief Find the index of the given anonymous struct/union within its
919f4a2713aSLionel Sambuc /// context.
920f4a2713aSLionel Sambuc ///
921f4a2713aSLionel Sambuc /// \returns Returns the index of this anonymous struct/union in its context,
922f4a2713aSLionel Sambuc /// including the next assigned index (if none of them match). Returns an
923f4a2713aSLionel Sambuc /// empty option if the context is not a record, i.e.. if the anonymous
924f4a2713aSLionel Sambuc /// struct/union is at namespace or block scope.
findAnonymousStructOrUnionIndex(RecordDecl * Anon)925f4a2713aSLionel Sambuc static Optional<unsigned> findAnonymousStructOrUnionIndex(RecordDecl *Anon) {
926f4a2713aSLionel Sambuc   ASTContext &Context = Anon->getASTContext();
927f4a2713aSLionel Sambuc   QualType AnonTy = Context.getRecordType(Anon);
928f4a2713aSLionel Sambuc 
929f4a2713aSLionel Sambuc   RecordDecl *Owner = dyn_cast<RecordDecl>(Anon->getDeclContext());
930f4a2713aSLionel Sambuc   if (!Owner)
931f4a2713aSLionel Sambuc     return None;
932f4a2713aSLionel Sambuc 
933f4a2713aSLionel Sambuc   unsigned Index = 0;
934*0a6a1f1dSLionel Sambuc   for (const auto *D : Owner->noload_decls()) {
935*0a6a1f1dSLionel Sambuc     const auto *F = dyn_cast<FieldDecl>(D);
936f4a2713aSLionel Sambuc     if (!F || !F->isAnonymousStructOrUnion())
937f4a2713aSLionel Sambuc       continue;
938f4a2713aSLionel Sambuc 
939f4a2713aSLionel Sambuc     if (Context.hasSameType(F->getType(), AnonTy))
940f4a2713aSLionel Sambuc       break;
941f4a2713aSLionel Sambuc 
942f4a2713aSLionel Sambuc     ++Index;
943f4a2713aSLionel Sambuc   }
944f4a2713aSLionel Sambuc 
945f4a2713aSLionel Sambuc   return Index;
946f4a2713aSLionel Sambuc }
947f4a2713aSLionel Sambuc 
948f4a2713aSLionel Sambuc /// \brief Determine structural equivalence of two records.
IsStructurallyEquivalent(StructuralEquivalenceContext & Context,RecordDecl * D1,RecordDecl * D2)949f4a2713aSLionel Sambuc static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
950f4a2713aSLionel Sambuc                                      RecordDecl *D1, RecordDecl *D2) {
951f4a2713aSLionel Sambuc   if (D1->isUnion() != D2->isUnion()) {
952f4a2713aSLionel Sambuc     if (Context.Complain) {
953f4a2713aSLionel Sambuc       Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
954f4a2713aSLionel Sambuc         << Context.C2.getTypeDeclType(D2);
955f4a2713aSLionel Sambuc       Context.Diag1(D1->getLocation(), diag::note_odr_tag_kind_here)
956f4a2713aSLionel Sambuc         << D1->getDeclName() << (unsigned)D1->getTagKind();
957f4a2713aSLionel Sambuc     }
958f4a2713aSLionel Sambuc     return false;
959f4a2713aSLionel Sambuc   }
960f4a2713aSLionel Sambuc 
961f4a2713aSLionel Sambuc   if (D1->isAnonymousStructOrUnion() && D2->isAnonymousStructOrUnion()) {
962f4a2713aSLionel Sambuc     // If both anonymous structs/unions are in a record context, make sure
963f4a2713aSLionel Sambuc     // they occur in the same location in the context records.
964f4a2713aSLionel Sambuc     if (Optional<unsigned> Index1 = findAnonymousStructOrUnionIndex(D1)) {
965f4a2713aSLionel Sambuc       if (Optional<unsigned> Index2 = findAnonymousStructOrUnionIndex(D2)) {
966f4a2713aSLionel Sambuc         if (*Index1 != *Index2)
967f4a2713aSLionel Sambuc           return false;
968f4a2713aSLionel Sambuc       }
969f4a2713aSLionel Sambuc     }
970f4a2713aSLionel Sambuc   }
971f4a2713aSLionel Sambuc 
972f4a2713aSLionel Sambuc   // If both declarations are class template specializations, we know
973f4a2713aSLionel Sambuc   // the ODR applies, so check the template and template arguments.
974f4a2713aSLionel Sambuc   ClassTemplateSpecializationDecl *Spec1
975f4a2713aSLionel Sambuc     = dyn_cast<ClassTemplateSpecializationDecl>(D1);
976f4a2713aSLionel Sambuc   ClassTemplateSpecializationDecl *Spec2
977f4a2713aSLionel Sambuc     = dyn_cast<ClassTemplateSpecializationDecl>(D2);
978f4a2713aSLionel Sambuc   if (Spec1 && Spec2) {
979f4a2713aSLionel Sambuc     // Check that the specialized templates are the same.
980f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context, Spec1->getSpecializedTemplate(),
981f4a2713aSLionel Sambuc                                   Spec2->getSpecializedTemplate()))
982f4a2713aSLionel Sambuc       return false;
983f4a2713aSLionel Sambuc 
984f4a2713aSLionel Sambuc     // Check that the template arguments are the same.
985f4a2713aSLionel Sambuc     if (Spec1->getTemplateArgs().size() != Spec2->getTemplateArgs().size())
986f4a2713aSLionel Sambuc       return false;
987f4a2713aSLionel Sambuc 
988f4a2713aSLionel Sambuc     for (unsigned I = 0, N = Spec1->getTemplateArgs().size(); I != N; ++I)
989f4a2713aSLionel Sambuc       if (!IsStructurallyEquivalent(Context,
990f4a2713aSLionel Sambuc                                     Spec1->getTemplateArgs().get(I),
991f4a2713aSLionel Sambuc                                     Spec2->getTemplateArgs().get(I)))
992f4a2713aSLionel Sambuc         return false;
993f4a2713aSLionel Sambuc   }
994f4a2713aSLionel Sambuc   // If one is a class template specialization and the other is not, these
995f4a2713aSLionel Sambuc   // structures are different.
996f4a2713aSLionel Sambuc   else if (Spec1 || Spec2)
997f4a2713aSLionel Sambuc     return false;
998f4a2713aSLionel Sambuc 
999f4a2713aSLionel Sambuc   // Compare the definitions of these two records. If either or both are
1000f4a2713aSLionel Sambuc   // incomplete, we assume that they are equivalent.
1001f4a2713aSLionel Sambuc   D1 = D1->getDefinition();
1002f4a2713aSLionel Sambuc   D2 = D2->getDefinition();
1003f4a2713aSLionel Sambuc   if (!D1 || !D2)
1004f4a2713aSLionel Sambuc     return true;
1005f4a2713aSLionel Sambuc 
1006f4a2713aSLionel Sambuc   if (CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(D1)) {
1007f4a2713aSLionel Sambuc     if (CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(D2)) {
1008f4a2713aSLionel Sambuc       if (D1CXX->getNumBases() != D2CXX->getNumBases()) {
1009f4a2713aSLionel Sambuc         if (Context.Complain) {
1010f4a2713aSLionel Sambuc           Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
1011f4a2713aSLionel Sambuc             << Context.C2.getTypeDeclType(D2);
1012f4a2713aSLionel Sambuc           Context.Diag2(D2->getLocation(), diag::note_odr_number_of_bases)
1013f4a2713aSLionel Sambuc             << D2CXX->getNumBases();
1014f4a2713aSLionel Sambuc           Context.Diag1(D1->getLocation(), diag::note_odr_number_of_bases)
1015f4a2713aSLionel Sambuc             << D1CXX->getNumBases();
1016f4a2713aSLionel Sambuc         }
1017f4a2713aSLionel Sambuc         return false;
1018f4a2713aSLionel Sambuc       }
1019f4a2713aSLionel Sambuc 
1020f4a2713aSLionel Sambuc       // Check the base classes.
1021f4a2713aSLionel Sambuc       for (CXXRecordDecl::base_class_iterator Base1 = D1CXX->bases_begin(),
1022f4a2713aSLionel Sambuc                                            BaseEnd1 = D1CXX->bases_end(),
1023f4a2713aSLionel Sambuc                                                 Base2 = D2CXX->bases_begin();
1024f4a2713aSLionel Sambuc            Base1 != BaseEnd1;
1025f4a2713aSLionel Sambuc            ++Base1, ++Base2) {
1026f4a2713aSLionel Sambuc         if (!IsStructurallyEquivalent(Context,
1027f4a2713aSLionel Sambuc                                       Base1->getType(), Base2->getType())) {
1028f4a2713aSLionel Sambuc           if (Context.Complain) {
1029f4a2713aSLionel Sambuc             Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
1030f4a2713aSLionel Sambuc               << Context.C2.getTypeDeclType(D2);
1031f4a2713aSLionel Sambuc             Context.Diag2(Base2->getLocStart(), diag::note_odr_base)
1032f4a2713aSLionel Sambuc               << Base2->getType()
1033f4a2713aSLionel Sambuc               << Base2->getSourceRange();
1034f4a2713aSLionel Sambuc             Context.Diag1(Base1->getLocStart(), diag::note_odr_base)
1035f4a2713aSLionel Sambuc               << Base1->getType()
1036f4a2713aSLionel Sambuc               << Base1->getSourceRange();
1037f4a2713aSLionel Sambuc           }
1038f4a2713aSLionel Sambuc           return false;
1039f4a2713aSLionel Sambuc         }
1040f4a2713aSLionel Sambuc 
1041f4a2713aSLionel Sambuc         // Check virtual vs. non-virtual inheritance mismatch.
1042f4a2713aSLionel Sambuc         if (Base1->isVirtual() != Base2->isVirtual()) {
1043f4a2713aSLionel Sambuc           if (Context.Complain) {
1044f4a2713aSLionel Sambuc             Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
1045f4a2713aSLionel Sambuc               << Context.C2.getTypeDeclType(D2);
1046f4a2713aSLionel Sambuc             Context.Diag2(Base2->getLocStart(),
1047f4a2713aSLionel Sambuc                           diag::note_odr_virtual_base)
1048f4a2713aSLionel Sambuc               << Base2->isVirtual() << Base2->getSourceRange();
1049f4a2713aSLionel Sambuc             Context.Diag1(Base1->getLocStart(), diag::note_odr_base)
1050f4a2713aSLionel Sambuc               << Base1->isVirtual()
1051f4a2713aSLionel Sambuc               << Base1->getSourceRange();
1052f4a2713aSLionel Sambuc           }
1053f4a2713aSLionel Sambuc           return false;
1054f4a2713aSLionel Sambuc         }
1055f4a2713aSLionel Sambuc       }
1056f4a2713aSLionel Sambuc     } else if (D1CXX->getNumBases() > 0) {
1057f4a2713aSLionel Sambuc       if (Context.Complain) {
1058f4a2713aSLionel Sambuc         Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
1059f4a2713aSLionel Sambuc           << Context.C2.getTypeDeclType(D2);
1060f4a2713aSLionel Sambuc         const CXXBaseSpecifier *Base1 = D1CXX->bases_begin();
1061f4a2713aSLionel Sambuc         Context.Diag1(Base1->getLocStart(), diag::note_odr_base)
1062f4a2713aSLionel Sambuc           << Base1->getType()
1063f4a2713aSLionel Sambuc           << Base1->getSourceRange();
1064f4a2713aSLionel Sambuc         Context.Diag2(D2->getLocation(), diag::note_odr_missing_base);
1065f4a2713aSLionel Sambuc       }
1066f4a2713aSLionel Sambuc       return false;
1067f4a2713aSLionel Sambuc     }
1068f4a2713aSLionel Sambuc   }
1069f4a2713aSLionel Sambuc 
1070f4a2713aSLionel Sambuc   // Check the fields for consistency.
1071f4a2713aSLionel Sambuc   RecordDecl::field_iterator Field2 = D2->field_begin(),
1072f4a2713aSLionel Sambuc                              Field2End = D2->field_end();
1073f4a2713aSLionel Sambuc   for (RecordDecl::field_iterator Field1 = D1->field_begin(),
1074f4a2713aSLionel Sambuc                                   Field1End = D1->field_end();
1075f4a2713aSLionel Sambuc        Field1 != Field1End;
1076f4a2713aSLionel Sambuc        ++Field1, ++Field2) {
1077f4a2713aSLionel Sambuc     if (Field2 == Field2End) {
1078f4a2713aSLionel Sambuc       if (Context.Complain) {
1079f4a2713aSLionel Sambuc         Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
1080f4a2713aSLionel Sambuc           << Context.C2.getTypeDeclType(D2);
1081f4a2713aSLionel Sambuc         Context.Diag1(Field1->getLocation(), diag::note_odr_field)
1082f4a2713aSLionel Sambuc           << Field1->getDeclName() << Field1->getType();
1083f4a2713aSLionel Sambuc         Context.Diag2(D2->getLocation(), diag::note_odr_missing_field);
1084f4a2713aSLionel Sambuc       }
1085f4a2713aSLionel Sambuc       return false;
1086f4a2713aSLionel Sambuc     }
1087f4a2713aSLionel Sambuc 
1088f4a2713aSLionel Sambuc     if (!IsStructurallyEquivalent(Context, *Field1, *Field2))
1089f4a2713aSLionel Sambuc       return false;
1090f4a2713aSLionel Sambuc   }
1091f4a2713aSLionel Sambuc 
1092f4a2713aSLionel Sambuc   if (Field2 != Field2End) {
1093f4a2713aSLionel Sambuc     if (Context.Complain) {
1094f4a2713aSLionel Sambuc       Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
1095f4a2713aSLionel Sambuc         << Context.C2.getTypeDeclType(D2);
1096f4a2713aSLionel Sambuc       Context.Diag2(Field2->getLocation(), diag::note_odr_field)
1097f4a2713aSLionel Sambuc         << Field2->getDeclName() << Field2->getType();
1098f4a2713aSLionel Sambuc       Context.Diag1(D1->getLocation(), diag::note_odr_missing_field);
1099f4a2713aSLionel Sambuc     }
1100f4a2713aSLionel Sambuc     return false;
1101f4a2713aSLionel Sambuc   }
1102f4a2713aSLionel Sambuc 
1103f4a2713aSLionel Sambuc   return true;
1104f4a2713aSLionel Sambuc }
1105f4a2713aSLionel Sambuc 
1106f4a2713aSLionel Sambuc /// \brief Determine structural equivalence of two enums.
IsStructurallyEquivalent(StructuralEquivalenceContext & Context,EnumDecl * D1,EnumDecl * D2)1107f4a2713aSLionel Sambuc static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
1108f4a2713aSLionel Sambuc                                      EnumDecl *D1, EnumDecl *D2) {
1109f4a2713aSLionel Sambuc   EnumDecl::enumerator_iterator EC2 = D2->enumerator_begin(),
1110f4a2713aSLionel Sambuc                              EC2End = D2->enumerator_end();
1111f4a2713aSLionel Sambuc   for (EnumDecl::enumerator_iterator EC1 = D1->enumerator_begin(),
1112f4a2713aSLionel Sambuc                                   EC1End = D1->enumerator_end();
1113f4a2713aSLionel Sambuc        EC1 != EC1End; ++EC1, ++EC2) {
1114f4a2713aSLionel Sambuc     if (EC2 == EC2End) {
1115f4a2713aSLionel Sambuc       if (Context.Complain) {
1116f4a2713aSLionel Sambuc         Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
1117f4a2713aSLionel Sambuc           << Context.C2.getTypeDeclType(D2);
1118f4a2713aSLionel Sambuc         Context.Diag1(EC1->getLocation(), diag::note_odr_enumerator)
1119f4a2713aSLionel Sambuc           << EC1->getDeclName()
1120f4a2713aSLionel Sambuc           << EC1->getInitVal().toString(10);
1121f4a2713aSLionel Sambuc         Context.Diag2(D2->getLocation(), diag::note_odr_missing_enumerator);
1122f4a2713aSLionel Sambuc       }
1123f4a2713aSLionel Sambuc       return false;
1124f4a2713aSLionel Sambuc     }
1125f4a2713aSLionel Sambuc 
1126f4a2713aSLionel Sambuc     llvm::APSInt Val1 = EC1->getInitVal();
1127f4a2713aSLionel Sambuc     llvm::APSInt Val2 = EC2->getInitVal();
1128f4a2713aSLionel Sambuc     if (!llvm::APSInt::isSameValue(Val1, Val2) ||
1129f4a2713aSLionel Sambuc         !IsStructurallyEquivalent(EC1->getIdentifier(), EC2->getIdentifier())) {
1130f4a2713aSLionel Sambuc       if (Context.Complain) {
1131f4a2713aSLionel Sambuc         Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
1132f4a2713aSLionel Sambuc           << Context.C2.getTypeDeclType(D2);
1133f4a2713aSLionel Sambuc         Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
1134f4a2713aSLionel Sambuc           << EC2->getDeclName()
1135f4a2713aSLionel Sambuc           << EC2->getInitVal().toString(10);
1136f4a2713aSLionel Sambuc         Context.Diag1(EC1->getLocation(), diag::note_odr_enumerator)
1137f4a2713aSLionel Sambuc           << EC1->getDeclName()
1138f4a2713aSLionel Sambuc           << EC1->getInitVal().toString(10);
1139f4a2713aSLionel Sambuc       }
1140f4a2713aSLionel Sambuc       return false;
1141f4a2713aSLionel Sambuc     }
1142f4a2713aSLionel Sambuc   }
1143f4a2713aSLionel Sambuc 
1144f4a2713aSLionel Sambuc   if (EC2 != EC2End) {
1145f4a2713aSLionel Sambuc     if (Context.Complain) {
1146f4a2713aSLionel Sambuc       Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
1147f4a2713aSLionel Sambuc         << Context.C2.getTypeDeclType(D2);
1148f4a2713aSLionel Sambuc       Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
1149f4a2713aSLionel Sambuc         << EC2->getDeclName()
1150f4a2713aSLionel Sambuc         << EC2->getInitVal().toString(10);
1151f4a2713aSLionel Sambuc       Context.Diag1(D1->getLocation(), diag::note_odr_missing_enumerator);
1152f4a2713aSLionel Sambuc     }
1153f4a2713aSLionel Sambuc     return false;
1154f4a2713aSLionel Sambuc   }
1155f4a2713aSLionel Sambuc 
1156f4a2713aSLionel Sambuc   return true;
1157f4a2713aSLionel Sambuc }
1158f4a2713aSLionel Sambuc 
IsStructurallyEquivalent(StructuralEquivalenceContext & Context,TemplateParameterList * Params1,TemplateParameterList * Params2)1159f4a2713aSLionel Sambuc static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
1160f4a2713aSLionel Sambuc                                      TemplateParameterList *Params1,
1161f4a2713aSLionel Sambuc                                      TemplateParameterList *Params2) {
1162f4a2713aSLionel Sambuc   if (Params1->size() != Params2->size()) {
1163f4a2713aSLionel Sambuc     if (Context.Complain) {
1164f4a2713aSLionel Sambuc       Context.Diag2(Params2->getTemplateLoc(),
1165f4a2713aSLionel Sambuc                     diag::err_odr_different_num_template_parameters)
1166f4a2713aSLionel Sambuc         << Params1->size() << Params2->size();
1167f4a2713aSLionel Sambuc       Context.Diag1(Params1->getTemplateLoc(),
1168f4a2713aSLionel Sambuc                     diag::note_odr_template_parameter_list);
1169f4a2713aSLionel Sambuc     }
1170f4a2713aSLionel Sambuc     return false;
1171f4a2713aSLionel Sambuc   }
1172f4a2713aSLionel Sambuc 
1173f4a2713aSLionel Sambuc   for (unsigned I = 0, N = Params1->size(); I != N; ++I) {
1174f4a2713aSLionel Sambuc     if (Params1->getParam(I)->getKind() != Params2->getParam(I)->getKind()) {
1175f4a2713aSLionel Sambuc       if (Context.Complain) {
1176f4a2713aSLionel Sambuc         Context.Diag2(Params2->getParam(I)->getLocation(),
1177f4a2713aSLionel Sambuc                       diag::err_odr_different_template_parameter_kind);
1178f4a2713aSLionel Sambuc         Context.Diag1(Params1->getParam(I)->getLocation(),
1179f4a2713aSLionel Sambuc                       diag::note_odr_template_parameter_here);
1180f4a2713aSLionel Sambuc       }
1181f4a2713aSLionel Sambuc       return false;
1182f4a2713aSLionel Sambuc     }
1183f4a2713aSLionel Sambuc 
1184f4a2713aSLionel Sambuc     if (!Context.IsStructurallyEquivalent(Params1->getParam(I),
1185f4a2713aSLionel Sambuc                                           Params2->getParam(I))) {
1186f4a2713aSLionel Sambuc 
1187f4a2713aSLionel Sambuc       return false;
1188f4a2713aSLionel Sambuc     }
1189f4a2713aSLionel Sambuc   }
1190f4a2713aSLionel Sambuc 
1191f4a2713aSLionel Sambuc   return true;
1192f4a2713aSLionel Sambuc }
1193f4a2713aSLionel Sambuc 
IsStructurallyEquivalent(StructuralEquivalenceContext & Context,TemplateTypeParmDecl * D1,TemplateTypeParmDecl * D2)1194f4a2713aSLionel Sambuc static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
1195f4a2713aSLionel Sambuc                                      TemplateTypeParmDecl *D1,
1196f4a2713aSLionel Sambuc                                      TemplateTypeParmDecl *D2) {
1197f4a2713aSLionel Sambuc   if (D1->isParameterPack() != D2->isParameterPack()) {
1198f4a2713aSLionel Sambuc     if (Context.Complain) {
1199f4a2713aSLionel Sambuc       Context.Diag2(D2->getLocation(), diag::err_odr_parameter_pack_non_pack)
1200f4a2713aSLionel Sambuc         << D2->isParameterPack();
1201f4a2713aSLionel Sambuc       Context.Diag1(D1->getLocation(), diag::note_odr_parameter_pack_non_pack)
1202f4a2713aSLionel Sambuc         << D1->isParameterPack();
1203f4a2713aSLionel Sambuc     }
1204f4a2713aSLionel Sambuc     return false;
1205f4a2713aSLionel Sambuc   }
1206f4a2713aSLionel Sambuc 
1207f4a2713aSLionel Sambuc   return true;
1208f4a2713aSLionel Sambuc }
1209f4a2713aSLionel Sambuc 
IsStructurallyEquivalent(StructuralEquivalenceContext & Context,NonTypeTemplateParmDecl * D1,NonTypeTemplateParmDecl * D2)1210f4a2713aSLionel Sambuc static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
1211f4a2713aSLionel Sambuc                                      NonTypeTemplateParmDecl *D1,
1212f4a2713aSLionel Sambuc                                      NonTypeTemplateParmDecl *D2) {
1213f4a2713aSLionel Sambuc   if (D1->isParameterPack() != D2->isParameterPack()) {
1214f4a2713aSLionel Sambuc     if (Context.Complain) {
1215f4a2713aSLionel Sambuc       Context.Diag2(D2->getLocation(), diag::err_odr_parameter_pack_non_pack)
1216f4a2713aSLionel Sambuc         << D2->isParameterPack();
1217f4a2713aSLionel Sambuc       Context.Diag1(D1->getLocation(), diag::note_odr_parameter_pack_non_pack)
1218f4a2713aSLionel Sambuc         << D1->isParameterPack();
1219f4a2713aSLionel Sambuc     }
1220f4a2713aSLionel Sambuc     return false;
1221f4a2713aSLionel Sambuc   }
1222f4a2713aSLionel Sambuc 
1223f4a2713aSLionel Sambuc   // Check types.
1224f4a2713aSLionel Sambuc   if (!Context.IsStructurallyEquivalent(D1->getType(), D2->getType())) {
1225f4a2713aSLionel Sambuc     if (Context.Complain) {
1226f4a2713aSLionel Sambuc       Context.Diag2(D2->getLocation(),
1227f4a2713aSLionel Sambuc                     diag::err_odr_non_type_parameter_type_inconsistent)
1228f4a2713aSLionel Sambuc         << D2->getType() << D1->getType();
1229f4a2713aSLionel Sambuc       Context.Diag1(D1->getLocation(), diag::note_odr_value_here)
1230f4a2713aSLionel Sambuc         << D1->getType();
1231f4a2713aSLionel Sambuc     }
1232f4a2713aSLionel Sambuc     return false;
1233f4a2713aSLionel Sambuc   }
1234f4a2713aSLionel Sambuc 
1235f4a2713aSLionel Sambuc   return true;
1236f4a2713aSLionel Sambuc }
1237f4a2713aSLionel Sambuc 
IsStructurallyEquivalent(StructuralEquivalenceContext & Context,TemplateTemplateParmDecl * D1,TemplateTemplateParmDecl * D2)1238f4a2713aSLionel Sambuc static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
1239f4a2713aSLionel Sambuc                                      TemplateTemplateParmDecl *D1,
1240f4a2713aSLionel Sambuc                                      TemplateTemplateParmDecl *D2) {
1241f4a2713aSLionel Sambuc   if (D1->isParameterPack() != D2->isParameterPack()) {
1242f4a2713aSLionel Sambuc     if (Context.Complain) {
1243f4a2713aSLionel Sambuc       Context.Diag2(D2->getLocation(), diag::err_odr_parameter_pack_non_pack)
1244f4a2713aSLionel Sambuc         << D2->isParameterPack();
1245f4a2713aSLionel Sambuc       Context.Diag1(D1->getLocation(), diag::note_odr_parameter_pack_non_pack)
1246f4a2713aSLionel Sambuc         << D1->isParameterPack();
1247f4a2713aSLionel Sambuc     }
1248f4a2713aSLionel Sambuc     return false;
1249f4a2713aSLionel Sambuc   }
1250f4a2713aSLionel Sambuc 
1251f4a2713aSLionel Sambuc   // Check template parameter lists.
1252f4a2713aSLionel Sambuc   return IsStructurallyEquivalent(Context, D1->getTemplateParameters(),
1253f4a2713aSLionel Sambuc                                   D2->getTemplateParameters());
1254f4a2713aSLionel Sambuc }
1255f4a2713aSLionel Sambuc 
IsStructurallyEquivalent(StructuralEquivalenceContext & Context,ClassTemplateDecl * D1,ClassTemplateDecl * D2)1256f4a2713aSLionel Sambuc static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
1257f4a2713aSLionel Sambuc                                      ClassTemplateDecl *D1,
1258f4a2713aSLionel Sambuc                                      ClassTemplateDecl *D2) {
1259f4a2713aSLionel Sambuc   // Check template parameters.
1260f4a2713aSLionel Sambuc   if (!IsStructurallyEquivalent(Context,
1261f4a2713aSLionel Sambuc                                 D1->getTemplateParameters(),
1262f4a2713aSLionel Sambuc                                 D2->getTemplateParameters()))
1263f4a2713aSLionel Sambuc     return false;
1264f4a2713aSLionel Sambuc 
1265f4a2713aSLionel Sambuc   // Check the templated declaration.
1266f4a2713aSLionel Sambuc   return Context.IsStructurallyEquivalent(D1->getTemplatedDecl(),
1267f4a2713aSLionel Sambuc                                           D2->getTemplatedDecl());
1268f4a2713aSLionel Sambuc }
1269f4a2713aSLionel Sambuc 
1270f4a2713aSLionel Sambuc /// \brief Determine structural equivalence of two declarations.
IsStructurallyEquivalent(StructuralEquivalenceContext & Context,Decl * D1,Decl * D2)1271f4a2713aSLionel Sambuc static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
1272f4a2713aSLionel Sambuc                                      Decl *D1, Decl *D2) {
1273f4a2713aSLionel Sambuc   // FIXME: Check for known structural equivalences via a callback of some sort.
1274f4a2713aSLionel Sambuc 
1275f4a2713aSLionel Sambuc   // Check whether we already know that these two declarations are not
1276f4a2713aSLionel Sambuc   // structurally equivalent.
1277f4a2713aSLionel Sambuc   if (Context.NonEquivalentDecls.count(std::make_pair(D1->getCanonicalDecl(),
1278f4a2713aSLionel Sambuc                                                       D2->getCanonicalDecl())))
1279f4a2713aSLionel Sambuc     return false;
1280f4a2713aSLionel Sambuc 
1281f4a2713aSLionel Sambuc   // Determine whether we've already produced a tentative equivalence for D1.
1282f4a2713aSLionel Sambuc   Decl *&EquivToD1 = Context.TentativeEquivalences[D1->getCanonicalDecl()];
1283f4a2713aSLionel Sambuc   if (EquivToD1)
1284f4a2713aSLionel Sambuc     return EquivToD1 == D2->getCanonicalDecl();
1285f4a2713aSLionel Sambuc 
1286f4a2713aSLionel Sambuc   // Produce a tentative equivalence D1 <-> D2, which will be checked later.
1287f4a2713aSLionel Sambuc   EquivToD1 = D2->getCanonicalDecl();
1288f4a2713aSLionel Sambuc   Context.DeclsToCheck.push_back(D1->getCanonicalDecl());
1289f4a2713aSLionel Sambuc   return true;
1290f4a2713aSLionel Sambuc }
1291f4a2713aSLionel Sambuc 
IsStructurallyEquivalent(Decl * D1,Decl * D2)1292f4a2713aSLionel Sambuc bool StructuralEquivalenceContext::IsStructurallyEquivalent(Decl *D1,
1293f4a2713aSLionel Sambuc                                                             Decl *D2) {
1294f4a2713aSLionel Sambuc   if (!::IsStructurallyEquivalent(*this, D1, D2))
1295f4a2713aSLionel Sambuc     return false;
1296f4a2713aSLionel Sambuc 
1297f4a2713aSLionel Sambuc   return !Finish();
1298f4a2713aSLionel Sambuc }
1299f4a2713aSLionel Sambuc 
IsStructurallyEquivalent(QualType T1,QualType T2)1300f4a2713aSLionel Sambuc bool StructuralEquivalenceContext::IsStructurallyEquivalent(QualType T1,
1301f4a2713aSLionel Sambuc                                                             QualType T2) {
1302f4a2713aSLionel Sambuc   if (!::IsStructurallyEquivalent(*this, T1, T2))
1303f4a2713aSLionel Sambuc     return false;
1304f4a2713aSLionel Sambuc 
1305f4a2713aSLionel Sambuc   return !Finish();
1306f4a2713aSLionel Sambuc }
1307f4a2713aSLionel Sambuc 
Finish()1308f4a2713aSLionel Sambuc bool StructuralEquivalenceContext::Finish() {
1309f4a2713aSLionel Sambuc   while (!DeclsToCheck.empty()) {
1310f4a2713aSLionel Sambuc     // Check the next declaration.
1311f4a2713aSLionel Sambuc     Decl *D1 = DeclsToCheck.front();
1312f4a2713aSLionel Sambuc     DeclsToCheck.pop_front();
1313f4a2713aSLionel Sambuc 
1314f4a2713aSLionel Sambuc     Decl *D2 = TentativeEquivalences[D1];
1315f4a2713aSLionel Sambuc     assert(D2 && "Unrecorded tentative equivalence?");
1316f4a2713aSLionel Sambuc 
1317f4a2713aSLionel Sambuc     bool Equivalent = true;
1318f4a2713aSLionel Sambuc 
1319f4a2713aSLionel Sambuc     // FIXME: Switch on all declaration kinds. For now, we're just going to
1320f4a2713aSLionel Sambuc     // check the obvious ones.
1321f4a2713aSLionel Sambuc     if (RecordDecl *Record1 = dyn_cast<RecordDecl>(D1)) {
1322f4a2713aSLionel Sambuc       if (RecordDecl *Record2 = dyn_cast<RecordDecl>(D2)) {
1323f4a2713aSLionel Sambuc         // Check for equivalent structure names.
1324f4a2713aSLionel Sambuc         IdentifierInfo *Name1 = Record1->getIdentifier();
1325f4a2713aSLionel Sambuc         if (!Name1 && Record1->getTypedefNameForAnonDecl())
1326f4a2713aSLionel Sambuc           Name1 = Record1->getTypedefNameForAnonDecl()->getIdentifier();
1327f4a2713aSLionel Sambuc         IdentifierInfo *Name2 = Record2->getIdentifier();
1328f4a2713aSLionel Sambuc         if (!Name2 && Record2->getTypedefNameForAnonDecl())
1329f4a2713aSLionel Sambuc           Name2 = Record2->getTypedefNameForAnonDecl()->getIdentifier();
1330f4a2713aSLionel Sambuc         if (!::IsStructurallyEquivalent(Name1, Name2) ||
1331f4a2713aSLionel Sambuc             !::IsStructurallyEquivalent(*this, Record1, Record2))
1332f4a2713aSLionel Sambuc           Equivalent = false;
1333f4a2713aSLionel Sambuc       } else {
1334f4a2713aSLionel Sambuc         // Record/non-record mismatch.
1335f4a2713aSLionel Sambuc         Equivalent = false;
1336f4a2713aSLionel Sambuc       }
1337f4a2713aSLionel Sambuc     } else if (EnumDecl *Enum1 = dyn_cast<EnumDecl>(D1)) {
1338f4a2713aSLionel Sambuc       if (EnumDecl *Enum2 = dyn_cast<EnumDecl>(D2)) {
1339f4a2713aSLionel Sambuc         // Check for equivalent enum names.
1340f4a2713aSLionel Sambuc         IdentifierInfo *Name1 = Enum1->getIdentifier();
1341f4a2713aSLionel Sambuc         if (!Name1 && Enum1->getTypedefNameForAnonDecl())
1342f4a2713aSLionel Sambuc           Name1 = Enum1->getTypedefNameForAnonDecl()->getIdentifier();
1343f4a2713aSLionel Sambuc         IdentifierInfo *Name2 = Enum2->getIdentifier();
1344f4a2713aSLionel Sambuc         if (!Name2 && Enum2->getTypedefNameForAnonDecl())
1345f4a2713aSLionel Sambuc           Name2 = Enum2->getTypedefNameForAnonDecl()->getIdentifier();
1346f4a2713aSLionel Sambuc         if (!::IsStructurallyEquivalent(Name1, Name2) ||
1347f4a2713aSLionel Sambuc             !::IsStructurallyEquivalent(*this, Enum1, Enum2))
1348f4a2713aSLionel Sambuc           Equivalent = false;
1349f4a2713aSLionel Sambuc       } else {
1350f4a2713aSLionel Sambuc         // Enum/non-enum mismatch
1351f4a2713aSLionel Sambuc         Equivalent = false;
1352f4a2713aSLionel Sambuc       }
1353f4a2713aSLionel Sambuc     } else if (TypedefNameDecl *Typedef1 = dyn_cast<TypedefNameDecl>(D1)) {
1354f4a2713aSLionel Sambuc       if (TypedefNameDecl *Typedef2 = dyn_cast<TypedefNameDecl>(D2)) {
1355f4a2713aSLionel Sambuc         if (!::IsStructurallyEquivalent(Typedef1->getIdentifier(),
1356f4a2713aSLionel Sambuc                                         Typedef2->getIdentifier()) ||
1357f4a2713aSLionel Sambuc             !::IsStructurallyEquivalent(*this,
1358f4a2713aSLionel Sambuc                                         Typedef1->getUnderlyingType(),
1359f4a2713aSLionel Sambuc                                         Typedef2->getUnderlyingType()))
1360f4a2713aSLionel Sambuc           Equivalent = false;
1361f4a2713aSLionel Sambuc       } else {
1362f4a2713aSLionel Sambuc         // Typedef/non-typedef mismatch.
1363f4a2713aSLionel Sambuc         Equivalent = false;
1364f4a2713aSLionel Sambuc       }
1365f4a2713aSLionel Sambuc     } else if (ClassTemplateDecl *ClassTemplate1
1366f4a2713aSLionel Sambuc                                            = dyn_cast<ClassTemplateDecl>(D1)) {
1367f4a2713aSLionel Sambuc       if (ClassTemplateDecl *ClassTemplate2 = dyn_cast<ClassTemplateDecl>(D2)) {
1368f4a2713aSLionel Sambuc         if (!::IsStructurallyEquivalent(ClassTemplate1->getIdentifier(),
1369f4a2713aSLionel Sambuc                                         ClassTemplate2->getIdentifier()) ||
1370f4a2713aSLionel Sambuc             !::IsStructurallyEquivalent(*this, ClassTemplate1, ClassTemplate2))
1371f4a2713aSLionel Sambuc           Equivalent = false;
1372f4a2713aSLionel Sambuc       } else {
1373f4a2713aSLionel Sambuc         // Class template/non-class-template mismatch.
1374f4a2713aSLionel Sambuc         Equivalent = false;
1375f4a2713aSLionel Sambuc       }
1376f4a2713aSLionel Sambuc     } else if (TemplateTypeParmDecl *TTP1= dyn_cast<TemplateTypeParmDecl>(D1)) {
1377f4a2713aSLionel Sambuc       if (TemplateTypeParmDecl *TTP2 = dyn_cast<TemplateTypeParmDecl>(D2)) {
1378f4a2713aSLionel Sambuc         if (!::IsStructurallyEquivalent(*this, TTP1, TTP2))
1379f4a2713aSLionel Sambuc           Equivalent = false;
1380f4a2713aSLionel Sambuc       } else {
1381f4a2713aSLionel Sambuc         // Kind mismatch.
1382f4a2713aSLionel Sambuc         Equivalent = false;
1383f4a2713aSLionel Sambuc       }
1384f4a2713aSLionel Sambuc     } else if (NonTypeTemplateParmDecl *NTTP1
1385f4a2713aSLionel Sambuc                                      = dyn_cast<NonTypeTemplateParmDecl>(D1)) {
1386f4a2713aSLionel Sambuc       if (NonTypeTemplateParmDecl *NTTP2
1387f4a2713aSLionel Sambuc                                       = dyn_cast<NonTypeTemplateParmDecl>(D2)) {
1388f4a2713aSLionel Sambuc         if (!::IsStructurallyEquivalent(*this, NTTP1, NTTP2))
1389f4a2713aSLionel Sambuc           Equivalent = false;
1390f4a2713aSLionel Sambuc       } else {
1391f4a2713aSLionel Sambuc         // Kind mismatch.
1392f4a2713aSLionel Sambuc         Equivalent = false;
1393f4a2713aSLionel Sambuc       }
1394f4a2713aSLionel Sambuc     } else if (TemplateTemplateParmDecl *TTP1
1395f4a2713aSLionel Sambuc                                   = dyn_cast<TemplateTemplateParmDecl>(D1)) {
1396f4a2713aSLionel Sambuc       if (TemplateTemplateParmDecl *TTP2
1397f4a2713aSLionel Sambuc                                     = dyn_cast<TemplateTemplateParmDecl>(D2)) {
1398f4a2713aSLionel Sambuc         if (!::IsStructurallyEquivalent(*this, TTP1, TTP2))
1399f4a2713aSLionel Sambuc           Equivalent = false;
1400f4a2713aSLionel Sambuc       } else {
1401f4a2713aSLionel Sambuc         // Kind mismatch.
1402f4a2713aSLionel Sambuc         Equivalent = false;
1403f4a2713aSLionel Sambuc       }
1404f4a2713aSLionel Sambuc     }
1405f4a2713aSLionel Sambuc 
1406f4a2713aSLionel Sambuc     if (!Equivalent) {
1407f4a2713aSLionel Sambuc       // Note that these two declarations are not equivalent (and we already
1408f4a2713aSLionel Sambuc       // know about it).
1409f4a2713aSLionel Sambuc       NonEquivalentDecls.insert(std::make_pair(D1->getCanonicalDecl(),
1410f4a2713aSLionel Sambuc                                                D2->getCanonicalDecl()));
1411f4a2713aSLionel Sambuc       return true;
1412f4a2713aSLionel Sambuc     }
1413f4a2713aSLionel Sambuc     // FIXME: Check other declaration kinds!
1414f4a2713aSLionel Sambuc   }
1415f4a2713aSLionel Sambuc 
1416f4a2713aSLionel Sambuc   return false;
1417f4a2713aSLionel Sambuc }
1418f4a2713aSLionel Sambuc 
1419f4a2713aSLionel Sambuc //----------------------------------------------------------------------------
1420f4a2713aSLionel Sambuc // Import Types
1421f4a2713aSLionel Sambuc //----------------------------------------------------------------------------
1422f4a2713aSLionel Sambuc 
VisitType(const Type * T)1423f4a2713aSLionel Sambuc QualType ASTNodeImporter::VisitType(const Type *T) {
1424f4a2713aSLionel Sambuc   Importer.FromDiag(SourceLocation(), diag::err_unsupported_ast_node)
1425f4a2713aSLionel Sambuc     << T->getTypeClassName();
1426f4a2713aSLionel Sambuc   return QualType();
1427f4a2713aSLionel Sambuc }
1428f4a2713aSLionel Sambuc 
VisitBuiltinType(const BuiltinType * T)1429f4a2713aSLionel Sambuc QualType ASTNodeImporter::VisitBuiltinType(const BuiltinType *T) {
1430f4a2713aSLionel Sambuc   switch (T->getKind()) {
1431f4a2713aSLionel Sambuc #define SHARED_SINGLETON_TYPE(Expansion)
1432f4a2713aSLionel Sambuc #define BUILTIN_TYPE(Id, SingletonId) \
1433f4a2713aSLionel Sambuc   case BuiltinType::Id: return Importer.getToContext().SingletonId;
1434f4a2713aSLionel Sambuc #include "clang/AST/BuiltinTypes.def"
1435f4a2713aSLionel Sambuc 
1436f4a2713aSLionel Sambuc   // FIXME: for Char16, Char32, and NullPtr, make sure that the "to"
1437f4a2713aSLionel Sambuc   // context supports C++.
1438f4a2713aSLionel Sambuc 
1439f4a2713aSLionel Sambuc   // FIXME: for ObjCId, ObjCClass, and ObjCSel, make sure that the "to"
1440f4a2713aSLionel Sambuc   // context supports ObjC.
1441f4a2713aSLionel Sambuc 
1442f4a2713aSLionel Sambuc   case BuiltinType::Char_U:
1443f4a2713aSLionel Sambuc     // The context we're importing from has an unsigned 'char'. If we're
1444f4a2713aSLionel Sambuc     // importing into a context with a signed 'char', translate to
1445f4a2713aSLionel Sambuc     // 'unsigned char' instead.
1446f4a2713aSLionel Sambuc     if (Importer.getToContext().getLangOpts().CharIsSigned)
1447f4a2713aSLionel Sambuc       return Importer.getToContext().UnsignedCharTy;
1448f4a2713aSLionel Sambuc 
1449f4a2713aSLionel Sambuc     return Importer.getToContext().CharTy;
1450f4a2713aSLionel Sambuc 
1451f4a2713aSLionel Sambuc   case BuiltinType::Char_S:
1452f4a2713aSLionel Sambuc     // The context we're importing from has an unsigned 'char'. If we're
1453f4a2713aSLionel Sambuc     // importing into a context with a signed 'char', translate to
1454f4a2713aSLionel Sambuc     // 'unsigned char' instead.
1455f4a2713aSLionel Sambuc     if (!Importer.getToContext().getLangOpts().CharIsSigned)
1456f4a2713aSLionel Sambuc       return Importer.getToContext().SignedCharTy;
1457f4a2713aSLionel Sambuc 
1458f4a2713aSLionel Sambuc     return Importer.getToContext().CharTy;
1459f4a2713aSLionel Sambuc 
1460f4a2713aSLionel Sambuc   case BuiltinType::WChar_S:
1461f4a2713aSLionel Sambuc   case BuiltinType::WChar_U:
1462f4a2713aSLionel Sambuc     // FIXME: If not in C++, shall we translate to the C equivalent of
1463f4a2713aSLionel Sambuc     // wchar_t?
1464f4a2713aSLionel Sambuc     return Importer.getToContext().WCharTy;
1465f4a2713aSLionel Sambuc   }
1466f4a2713aSLionel Sambuc 
1467f4a2713aSLionel Sambuc   llvm_unreachable("Invalid BuiltinType Kind!");
1468f4a2713aSLionel Sambuc }
1469f4a2713aSLionel Sambuc 
VisitComplexType(const ComplexType * T)1470f4a2713aSLionel Sambuc QualType ASTNodeImporter::VisitComplexType(const ComplexType *T) {
1471f4a2713aSLionel Sambuc   QualType ToElementType = Importer.Import(T->getElementType());
1472f4a2713aSLionel Sambuc   if (ToElementType.isNull())
1473f4a2713aSLionel Sambuc     return QualType();
1474f4a2713aSLionel Sambuc 
1475f4a2713aSLionel Sambuc   return Importer.getToContext().getComplexType(ToElementType);
1476f4a2713aSLionel Sambuc }
1477f4a2713aSLionel Sambuc 
VisitPointerType(const PointerType * T)1478f4a2713aSLionel Sambuc QualType ASTNodeImporter::VisitPointerType(const PointerType *T) {
1479f4a2713aSLionel Sambuc   QualType ToPointeeType = Importer.Import(T->getPointeeType());
1480f4a2713aSLionel Sambuc   if (ToPointeeType.isNull())
1481f4a2713aSLionel Sambuc     return QualType();
1482f4a2713aSLionel Sambuc 
1483f4a2713aSLionel Sambuc   return Importer.getToContext().getPointerType(ToPointeeType);
1484f4a2713aSLionel Sambuc }
1485f4a2713aSLionel Sambuc 
VisitBlockPointerType(const BlockPointerType * T)1486f4a2713aSLionel Sambuc QualType ASTNodeImporter::VisitBlockPointerType(const BlockPointerType *T) {
1487f4a2713aSLionel Sambuc   // FIXME: Check for blocks support in "to" context.
1488f4a2713aSLionel Sambuc   QualType ToPointeeType = Importer.Import(T->getPointeeType());
1489f4a2713aSLionel Sambuc   if (ToPointeeType.isNull())
1490f4a2713aSLionel Sambuc     return QualType();
1491f4a2713aSLionel Sambuc 
1492f4a2713aSLionel Sambuc   return Importer.getToContext().getBlockPointerType(ToPointeeType);
1493f4a2713aSLionel Sambuc }
1494f4a2713aSLionel Sambuc 
1495f4a2713aSLionel Sambuc QualType
VisitLValueReferenceType(const LValueReferenceType * T)1496f4a2713aSLionel Sambuc ASTNodeImporter::VisitLValueReferenceType(const LValueReferenceType *T) {
1497f4a2713aSLionel Sambuc   // FIXME: Check for C++ support in "to" context.
1498f4a2713aSLionel Sambuc   QualType ToPointeeType = Importer.Import(T->getPointeeTypeAsWritten());
1499f4a2713aSLionel Sambuc   if (ToPointeeType.isNull())
1500f4a2713aSLionel Sambuc     return QualType();
1501f4a2713aSLionel Sambuc 
1502f4a2713aSLionel Sambuc   return Importer.getToContext().getLValueReferenceType(ToPointeeType);
1503f4a2713aSLionel Sambuc }
1504f4a2713aSLionel Sambuc 
1505f4a2713aSLionel Sambuc QualType
VisitRValueReferenceType(const RValueReferenceType * T)1506f4a2713aSLionel Sambuc ASTNodeImporter::VisitRValueReferenceType(const RValueReferenceType *T) {
1507f4a2713aSLionel Sambuc   // FIXME: Check for C++0x support in "to" context.
1508f4a2713aSLionel Sambuc   QualType ToPointeeType = Importer.Import(T->getPointeeTypeAsWritten());
1509f4a2713aSLionel Sambuc   if (ToPointeeType.isNull())
1510f4a2713aSLionel Sambuc     return QualType();
1511f4a2713aSLionel Sambuc 
1512f4a2713aSLionel Sambuc   return Importer.getToContext().getRValueReferenceType(ToPointeeType);
1513f4a2713aSLionel Sambuc }
1514f4a2713aSLionel Sambuc 
VisitMemberPointerType(const MemberPointerType * T)1515f4a2713aSLionel Sambuc QualType ASTNodeImporter::VisitMemberPointerType(const MemberPointerType *T) {
1516f4a2713aSLionel Sambuc   // FIXME: Check for C++ support in "to" context.
1517f4a2713aSLionel Sambuc   QualType ToPointeeType = Importer.Import(T->getPointeeType());
1518f4a2713aSLionel Sambuc   if (ToPointeeType.isNull())
1519f4a2713aSLionel Sambuc     return QualType();
1520f4a2713aSLionel Sambuc 
1521f4a2713aSLionel Sambuc   QualType ClassType = Importer.Import(QualType(T->getClass(), 0));
1522f4a2713aSLionel Sambuc   return Importer.getToContext().getMemberPointerType(ToPointeeType,
1523f4a2713aSLionel Sambuc                                                       ClassType.getTypePtr());
1524f4a2713aSLionel Sambuc }
1525f4a2713aSLionel Sambuc 
VisitConstantArrayType(const ConstantArrayType * T)1526f4a2713aSLionel Sambuc QualType ASTNodeImporter::VisitConstantArrayType(const ConstantArrayType *T) {
1527f4a2713aSLionel Sambuc   QualType ToElementType = Importer.Import(T->getElementType());
1528f4a2713aSLionel Sambuc   if (ToElementType.isNull())
1529f4a2713aSLionel Sambuc     return QualType();
1530f4a2713aSLionel Sambuc 
1531f4a2713aSLionel Sambuc   return Importer.getToContext().getConstantArrayType(ToElementType,
1532f4a2713aSLionel Sambuc                                                       T->getSize(),
1533f4a2713aSLionel Sambuc                                                       T->getSizeModifier(),
1534f4a2713aSLionel Sambuc                                                T->getIndexTypeCVRQualifiers());
1535f4a2713aSLionel Sambuc }
1536f4a2713aSLionel Sambuc 
1537f4a2713aSLionel Sambuc QualType
VisitIncompleteArrayType(const IncompleteArrayType * T)1538f4a2713aSLionel Sambuc ASTNodeImporter::VisitIncompleteArrayType(const IncompleteArrayType *T) {
1539f4a2713aSLionel Sambuc   QualType ToElementType = Importer.Import(T->getElementType());
1540f4a2713aSLionel Sambuc   if (ToElementType.isNull())
1541f4a2713aSLionel Sambuc     return QualType();
1542f4a2713aSLionel Sambuc 
1543f4a2713aSLionel Sambuc   return Importer.getToContext().getIncompleteArrayType(ToElementType,
1544f4a2713aSLionel Sambuc                                                         T->getSizeModifier(),
1545f4a2713aSLionel Sambuc                                                 T->getIndexTypeCVRQualifiers());
1546f4a2713aSLionel Sambuc }
1547f4a2713aSLionel Sambuc 
VisitVariableArrayType(const VariableArrayType * T)1548f4a2713aSLionel Sambuc QualType ASTNodeImporter::VisitVariableArrayType(const VariableArrayType *T) {
1549f4a2713aSLionel Sambuc   QualType ToElementType = Importer.Import(T->getElementType());
1550f4a2713aSLionel Sambuc   if (ToElementType.isNull())
1551f4a2713aSLionel Sambuc     return QualType();
1552f4a2713aSLionel Sambuc 
1553f4a2713aSLionel Sambuc   Expr *Size = Importer.Import(T->getSizeExpr());
1554f4a2713aSLionel Sambuc   if (!Size)
1555f4a2713aSLionel Sambuc     return QualType();
1556f4a2713aSLionel Sambuc 
1557f4a2713aSLionel Sambuc   SourceRange Brackets = Importer.Import(T->getBracketsRange());
1558f4a2713aSLionel Sambuc   return Importer.getToContext().getVariableArrayType(ToElementType, Size,
1559f4a2713aSLionel Sambuc                                                       T->getSizeModifier(),
1560f4a2713aSLionel Sambuc                                                 T->getIndexTypeCVRQualifiers(),
1561f4a2713aSLionel Sambuc                                                       Brackets);
1562f4a2713aSLionel Sambuc }
1563f4a2713aSLionel Sambuc 
VisitVectorType(const VectorType * T)1564f4a2713aSLionel Sambuc QualType ASTNodeImporter::VisitVectorType(const VectorType *T) {
1565f4a2713aSLionel Sambuc   QualType ToElementType = Importer.Import(T->getElementType());
1566f4a2713aSLionel Sambuc   if (ToElementType.isNull())
1567f4a2713aSLionel Sambuc     return QualType();
1568f4a2713aSLionel Sambuc 
1569f4a2713aSLionel Sambuc   return Importer.getToContext().getVectorType(ToElementType,
1570f4a2713aSLionel Sambuc                                                T->getNumElements(),
1571f4a2713aSLionel Sambuc                                                T->getVectorKind());
1572f4a2713aSLionel Sambuc }
1573f4a2713aSLionel Sambuc 
VisitExtVectorType(const ExtVectorType * T)1574f4a2713aSLionel Sambuc QualType ASTNodeImporter::VisitExtVectorType(const ExtVectorType *T) {
1575f4a2713aSLionel Sambuc   QualType ToElementType = Importer.Import(T->getElementType());
1576f4a2713aSLionel Sambuc   if (ToElementType.isNull())
1577f4a2713aSLionel Sambuc     return QualType();
1578f4a2713aSLionel Sambuc 
1579f4a2713aSLionel Sambuc   return Importer.getToContext().getExtVectorType(ToElementType,
1580f4a2713aSLionel Sambuc                                                   T->getNumElements());
1581f4a2713aSLionel Sambuc }
1582f4a2713aSLionel Sambuc 
1583f4a2713aSLionel Sambuc QualType
VisitFunctionNoProtoType(const FunctionNoProtoType * T)1584f4a2713aSLionel Sambuc ASTNodeImporter::VisitFunctionNoProtoType(const FunctionNoProtoType *T) {
1585f4a2713aSLionel Sambuc   // FIXME: What happens if we're importing a function without a prototype
1586f4a2713aSLionel Sambuc   // into C++? Should we make it variadic?
1587*0a6a1f1dSLionel Sambuc   QualType ToResultType = Importer.Import(T->getReturnType());
1588f4a2713aSLionel Sambuc   if (ToResultType.isNull())
1589f4a2713aSLionel Sambuc     return QualType();
1590f4a2713aSLionel Sambuc 
1591f4a2713aSLionel Sambuc   return Importer.getToContext().getFunctionNoProtoType(ToResultType,
1592f4a2713aSLionel Sambuc                                                         T->getExtInfo());
1593f4a2713aSLionel Sambuc }
1594f4a2713aSLionel Sambuc 
VisitFunctionProtoType(const FunctionProtoType * T)1595f4a2713aSLionel Sambuc QualType ASTNodeImporter::VisitFunctionProtoType(const FunctionProtoType *T) {
1596*0a6a1f1dSLionel Sambuc   QualType ToResultType = Importer.Import(T->getReturnType());
1597f4a2713aSLionel Sambuc   if (ToResultType.isNull())
1598f4a2713aSLionel Sambuc     return QualType();
1599f4a2713aSLionel Sambuc 
1600f4a2713aSLionel Sambuc   // Import argument types
1601f4a2713aSLionel Sambuc   SmallVector<QualType, 4> ArgTypes;
1602*0a6a1f1dSLionel Sambuc   for (const auto &A : T->param_types()) {
1603*0a6a1f1dSLionel Sambuc     QualType ArgType = Importer.Import(A);
1604f4a2713aSLionel Sambuc     if (ArgType.isNull())
1605f4a2713aSLionel Sambuc       return QualType();
1606f4a2713aSLionel Sambuc     ArgTypes.push_back(ArgType);
1607f4a2713aSLionel Sambuc   }
1608f4a2713aSLionel Sambuc 
1609f4a2713aSLionel Sambuc   // Import exception types
1610f4a2713aSLionel Sambuc   SmallVector<QualType, 4> ExceptionTypes;
1611*0a6a1f1dSLionel Sambuc   for (const auto &E : T->exceptions()) {
1612*0a6a1f1dSLionel Sambuc     QualType ExceptionType = Importer.Import(E);
1613f4a2713aSLionel Sambuc     if (ExceptionType.isNull())
1614f4a2713aSLionel Sambuc       return QualType();
1615f4a2713aSLionel Sambuc     ExceptionTypes.push_back(ExceptionType);
1616f4a2713aSLionel Sambuc   }
1617f4a2713aSLionel Sambuc 
1618f4a2713aSLionel Sambuc   FunctionProtoType::ExtProtoInfo FromEPI = T->getExtProtoInfo();
1619f4a2713aSLionel Sambuc   FunctionProtoType::ExtProtoInfo ToEPI;
1620f4a2713aSLionel Sambuc 
1621f4a2713aSLionel Sambuc   ToEPI.ExtInfo = FromEPI.ExtInfo;
1622f4a2713aSLionel Sambuc   ToEPI.Variadic = FromEPI.Variadic;
1623f4a2713aSLionel Sambuc   ToEPI.HasTrailingReturn = FromEPI.HasTrailingReturn;
1624f4a2713aSLionel Sambuc   ToEPI.TypeQuals = FromEPI.TypeQuals;
1625f4a2713aSLionel Sambuc   ToEPI.RefQualifier = FromEPI.RefQualifier;
1626*0a6a1f1dSLionel Sambuc   ToEPI.ExceptionSpec.Type = FromEPI.ExceptionSpec.Type;
1627*0a6a1f1dSLionel Sambuc   ToEPI.ExceptionSpec.Exceptions = ExceptionTypes;
1628*0a6a1f1dSLionel Sambuc   ToEPI.ExceptionSpec.NoexceptExpr =
1629*0a6a1f1dSLionel Sambuc       Importer.Import(FromEPI.ExceptionSpec.NoexceptExpr);
1630*0a6a1f1dSLionel Sambuc   ToEPI.ExceptionSpec.SourceDecl = cast_or_null<FunctionDecl>(
1631*0a6a1f1dSLionel Sambuc       Importer.Import(FromEPI.ExceptionSpec.SourceDecl));
1632*0a6a1f1dSLionel Sambuc   ToEPI.ExceptionSpec.SourceTemplate = cast_or_null<FunctionDecl>(
1633*0a6a1f1dSLionel Sambuc       Importer.Import(FromEPI.ExceptionSpec.SourceTemplate));
1634f4a2713aSLionel Sambuc 
1635f4a2713aSLionel Sambuc   return Importer.getToContext().getFunctionType(ToResultType, ArgTypes, ToEPI);
1636f4a2713aSLionel Sambuc }
1637f4a2713aSLionel Sambuc 
VisitParenType(const ParenType * T)1638f4a2713aSLionel Sambuc QualType ASTNodeImporter::VisitParenType(const ParenType *T) {
1639f4a2713aSLionel Sambuc   QualType ToInnerType = Importer.Import(T->getInnerType());
1640f4a2713aSLionel Sambuc   if (ToInnerType.isNull())
1641f4a2713aSLionel Sambuc     return QualType();
1642f4a2713aSLionel Sambuc 
1643f4a2713aSLionel Sambuc   return Importer.getToContext().getParenType(ToInnerType);
1644f4a2713aSLionel Sambuc }
1645f4a2713aSLionel Sambuc 
VisitTypedefType(const TypedefType * T)1646f4a2713aSLionel Sambuc QualType ASTNodeImporter::VisitTypedefType(const TypedefType *T) {
1647f4a2713aSLionel Sambuc   TypedefNameDecl *ToDecl
1648f4a2713aSLionel Sambuc              = dyn_cast_or_null<TypedefNameDecl>(Importer.Import(T->getDecl()));
1649f4a2713aSLionel Sambuc   if (!ToDecl)
1650f4a2713aSLionel Sambuc     return QualType();
1651f4a2713aSLionel Sambuc 
1652f4a2713aSLionel Sambuc   return Importer.getToContext().getTypeDeclType(ToDecl);
1653f4a2713aSLionel Sambuc }
1654f4a2713aSLionel Sambuc 
VisitTypeOfExprType(const TypeOfExprType * T)1655f4a2713aSLionel Sambuc QualType ASTNodeImporter::VisitTypeOfExprType(const TypeOfExprType *T) {
1656f4a2713aSLionel Sambuc   Expr *ToExpr = Importer.Import(T->getUnderlyingExpr());
1657f4a2713aSLionel Sambuc   if (!ToExpr)
1658f4a2713aSLionel Sambuc     return QualType();
1659f4a2713aSLionel Sambuc 
1660f4a2713aSLionel Sambuc   return Importer.getToContext().getTypeOfExprType(ToExpr);
1661f4a2713aSLionel Sambuc }
1662f4a2713aSLionel Sambuc 
VisitTypeOfType(const TypeOfType * T)1663f4a2713aSLionel Sambuc QualType ASTNodeImporter::VisitTypeOfType(const TypeOfType *T) {
1664f4a2713aSLionel Sambuc   QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType());
1665f4a2713aSLionel Sambuc   if (ToUnderlyingType.isNull())
1666f4a2713aSLionel Sambuc     return QualType();
1667f4a2713aSLionel Sambuc 
1668f4a2713aSLionel Sambuc   return Importer.getToContext().getTypeOfType(ToUnderlyingType);
1669f4a2713aSLionel Sambuc }
1670f4a2713aSLionel Sambuc 
VisitDecltypeType(const DecltypeType * T)1671f4a2713aSLionel Sambuc QualType ASTNodeImporter::VisitDecltypeType(const DecltypeType *T) {
1672f4a2713aSLionel Sambuc   // FIXME: Make sure that the "to" context supports C++0x!
1673f4a2713aSLionel Sambuc   Expr *ToExpr = Importer.Import(T->getUnderlyingExpr());
1674f4a2713aSLionel Sambuc   if (!ToExpr)
1675f4a2713aSLionel Sambuc     return QualType();
1676f4a2713aSLionel Sambuc 
1677f4a2713aSLionel Sambuc   QualType UnderlyingType = Importer.Import(T->getUnderlyingType());
1678f4a2713aSLionel Sambuc   if (UnderlyingType.isNull())
1679f4a2713aSLionel Sambuc     return QualType();
1680f4a2713aSLionel Sambuc 
1681f4a2713aSLionel Sambuc   return Importer.getToContext().getDecltypeType(ToExpr, UnderlyingType);
1682f4a2713aSLionel Sambuc }
1683f4a2713aSLionel Sambuc 
VisitUnaryTransformType(const UnaryTransformType * T)1684f4a2713aSLionel Sambuc QualType ASTNodeImporter::VisitUnaryTransformType(const UnaryTransformType *T) {
1685f4a2713aSLionel Sambuc   QualType ToBaseType = Importer.Import(T->getBaseType());
1686f4a2713aSLionel Sambuc   QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType());
1687f4a2713aSLionel Sambuc   if (ToBaseType.isNull() || ToUnderlyingType.isNull())
1688f4a2713aSLionel Sambuc     return QualType();
1689f4a2713aSLionel Sambuc 
1690f4a2713aSLionel Sambuc   return Importer.getToContext().getUnaryTransformType(ToBaseType,
1691f4a2713aSLionel Sambuc                                                        ToUnderlyingType,
1692f4a2713aSLionel Sambuc                                                        T->getUTTKind());
1693f4a2713aSLionel Sambuc }
1694f4a2713aSLionel Sambuc 
VisitAutoType(const AutoType * T)1695f4a2713aSLionel Sambuc QualType ASTNodeImporter::VisitAutoType(const AutoType *T) {
1696f4a2713aSLionel Sambuc   // FIXME: Make sure that the "to" context supports C++11!
1697f4a2713aSLionel Sambuc   QualType FromDeduced = T->getDeducedType();
1698f4a2713aSLionel Sambuc   QualType ToDeduced;
1699f4a2713aSLionel Sambuc   if (!FromDeduced.isNull()) {
1700f4a2713aSLionel Sambuc     ToDeduced = Importer.Import(FromDeduced);
1701f4a2713aSLionel Sambuc     if (ToDeduced.isNull())
1702f4a2713aSLionel Sambuc       return QualType();
1703f4a2713aSLionel Sambuc   }
1704f4a2713aSLionel Sambuc 
1705f4a2713aSLionel Sambuc   return Importer.getToContext().getAutoType(ToDeduced, T->isDecltypeAuto(),
1706f4a2713aSLionel Sambuc                                              /*IsDependent*/false);
1707f4a2713aSLionel Sambuc }
1708f4a2713aSLionel Sambuc 
VisitRecordType(const RecordType * T)1709f4a2713aSLionel Sambuc QualType ASTNodeImporter::VisitRecordType(const RecordType *T) {
1710f4a2713aSLionel Sambuc   RecordDecl *ToDecl
1711f4a2713aSLionel Sambuc     = dyn_cast_or_null<RecordDecl>(Importer.Import(T->getDecl()));
1712f4a2713aSLionel Sambuc   if (!ToDecl)
1713f4a2713aSLionel Sambuc     return QualType();
1714f4a2713aSLionel Sambuc 
1715f4a2713aSLionel Sambuc   return Importer.getToContext().getTagDeclType(ToDecl);
1716f4a2713aSLionel Sambuc }
1717f4a2713aSLionel Sambuc 
VisitEnumType(const EnumType * T)1718f4a2713aSLionel Sambuc QualType ASTNodeImporter::VisitEnumType(const EnumType *T) {
1719f4a2713aSLionel Sambuc   EnumDecl *ToDecl
1720f4a2713aSLionel Sambuc     = dyn_cast_or_null<EnumDecl>(Importer.Import(T->getDecl()));
1721f4a2713aSLionel Sambuc   if (!ToDecl)
1722f4a2713aSLionel Sambuc     return QualType();
1723f4a2713aSLionel Sambuc 
1724f4a2713aSLionel Sambuc   return Importer.getToContext().getTagDeclType(ToDecl);
1725f4a2713aSLionel Sambuc }
1726f4a2713aSLionel Sambuc 
VisitTemplateSpecializationType(const TemplateSpecializationType * T)1727f4a2713aSLionel Sambuc QualType ASTNodeImporter::VisitTemplateSpecializationType(
1728f4a2713aSLionel Sambuc                                        const TemplateSpecializationType *T) {
1729f4a2713aSLionel Sambuc   TemplateName ToTemplate = Importer.Import(T->getTemplateName());
1730f4a2713aSLionel Sambuc   if (ToTemplate.isNull())
1731f4a2713aSLionel Sambuc     return QualType();
1732f4a2713aSLionel Sambuc 
1733f4a2713aSLionel Sambuc   SmallVector<TemplateArgument, 2> ToTemplateArgs;
1734f4a2713aSLionel Sambuc   if (ImportTemplateArguments(T->getArgs(), T->getNumArgs(), ToTemplateArgs))
1735f4a2713aSLionel Sambuc     return QualType();
1736f4a2713aSLionel Sambuc 
1737f4a2713aSLionel Sambuc   QualType ToCanonType;
1738f4a2713aSLionel Sambuc   if (!QualType(T, 0).isCanonical()) {
1739f4a2713aSLionel Sambuc     QualType FromCanonType
1740f4a2713aSLionel Sambuc       = Importer.getFromContext().getCanonicalType(QualType(T, 0));
1741f4a2713aSLionel Sambuc     ToCanonType =Importer.Import(FromCanonType);
1742f4a2713aSLionel Sambuc     if (ToCanonType.isNull())
1743f4a2713aSLionel Sambuc       return QualType();
1744f4a2713aSLionel Sambuc   }
1745f4a2713aSLionel Sambuc   return Importer.getToContext().getTemplateSpecializationType(ToTemplate,
1746f4a2713aSLionel Sambuc                                                          ToTemplateArgs.data(),
1747f4a2713aSLionel Sambuc                                                          ToTemplateArgs.size(),
1748f4a2713aSLionel Sambuc                                                                ToCanonType);
1749f4a2713aSLionel Sambuc }
1750f4a2713aSLionel Sambuc 
VisitElaboratedType(const ElaboratedType * T)1751f4a2713aSLionel Sambuc QualType ASTNodeImporter::VisitElaboratedType(const ElaboratedType *T) {
1752*0a6a1f1dSLionel Sambuc   NestedNameSpecifier *ToQualifier = nullptr;
1753f4a2713aSLionel Sambuc   // Note: the qualifier in an ElaboratedType is optional.
1754f4a2713aSLionel Sambuc   if (T->getQualifier()) {
1755f4a2713aSLionel Sambuc     ToQualifier = Importer.Import(T->getQualifier());
1756f4a2713aSLionel Sambuc     if (!ToQualifier)
1757f4a2713aSLionel Sambuc       return QualType();
1758f4a2713aSLionel Sambuc   }
1759f4a2713aSLionel Sambuc 
1760f4a2713aSLionel Sambuc   QualType ToNamedType = Importer.Import(T->getNamedType());
1761f4a2713aSLionel Sambuc   if (ToNamedType.isNull())
1762f4a2713aSLionel Sambuc     return QualType();
1763f4a2713aSLionel Sambuc 
1764f4a2713aSLionel Sambuc   return Importer.getToContext().getElaboratedType(T->getKeyword(),
1765f4a2713aSLionel Sambuc                                                    ToQualifier, ToNamedType);
1766f4a2713aSLionel Sambuc }
1767f4a2713aSLionel Sambuc 
VisitObjCInterfaceType(const ObjCInterfaceType * T)1768f4a2713aSLionel Sambuc QualType ASTNodeImporter::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
1769f4a2713aSLionel Sambuc   ObjCInterfaceDecl *Class
1770f4a2713aSLionel Sambuc     = dyn_cast_or_null<ObjCInterfaceDecl>(Importer.Import(T->getDecl()));
1771f4a2713aSLionel Sambuc   if (!Class)
1772f4a2713aSLionel Sambuc     return QualType();
1773f4a2713aSLionel Sambuc 
1774f4a2713aSLionel Sambuc   return Importer.getToContext().getObjCInterfaceType(Class);
1775f4a2713aSLionel Sambuc }
1776f4a2713aSLionel Sambuc 
VisitObjCObjectType(const ObjCObjectType * T)1777f4a2713aSLionel Sambuc QualType ASTNodeImporter::VisitObjCObjectType(const ObjCObjectType *T) {
1778f4a2713aSLionel Sambuc   QualType ToBaseType = Importer.Import(T->getBaseType());
1779f4a2713aSLionel Sambuc   if (ToBaseType.isNull())
1780f4a2713aSLionel Sambuc     return QualType();
1781f4a2713aSLionel Sambuc 
1782f4a2713aSLionel Sambuc   SmallVector<ObjCProtocolDecl *, 4> Protocols;
1783*0a6a1f1dSLionel Sambuc   for (auto *P : T->quals()) {
1784f4a2713aSLionel Sambuc     ObjCProtocolDecl *Protocol
1785*0a6a1f1dSLionel Sambuc       = dyn_cast_or_null<ObjCProtocolDecl>(Importer.Import(P));
1786f4a2713aSLionel Sambuc     if (!Protocol)
1787f4a2713aSLionel Sambuc       return QualType();
1788f4a2713aSLionel Sambuc     Protocols.push_back(Protocol);
1789f4a2713aSLionel Sambuc   }
1790f4a2713aSLionel Sambuc 
1791f4a2713aSLionel Sambuc   return Importer.getToContext().getObjCObjectType(ToBaseType,
1792f4a2713aSLionel Sambuc                                                    Protocols.data(),
1793f4a2713aSLionel Sambuc                                                    Protocols.size());
1794f4a2713aSLionel Sambuc }
1795f4a2713aSLionel Sambuc 
1796f4a2713aSLionel Sambuc QualType
VisitObjCObjectPointerType(const ObjCObjectPointerType * T)1797f4a2713aSLionel Sambuc ASTNodeImporter::VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
1798f4a2713aSLionel Sambuc   QualType ToPointeeType = Importer.Import(T->getPointeeType());
1799f4a2713aSLionel Sambuc   if (ToPointeeType.isNull())
1800f4a2713aSLionel Sambuc     return QualType();
1801f4a2713aSLionel Sambuc 
1802f4a2713aSLionel Sambuc   return Importer.getToContext().getObjCObjectPointerType(ToPointeeType);
1803f4a2713aSLionel Sambuc }
1804f4a2713aSLionel Sambuc 
1805f4a2713aSLionel Sambuc //----------------------------------------------------------------------------
1806f4a2713aSLionel Sambuc // Import Declarations
1807f4a2713aSLionel Sambuc //----------------------------------------------------------------------------
ImportDeclParts(NamedDecl * D,DeclContext * & DC,DeclContext * & LexicalDC,DeclarationName & Name,SourceLocation & Loc)1808f4a2713aSLionel Sambuc bool ASTNodeImporter::ImportDeclParts(NamedDecl *D, DeclContext *&DC,
1809f4a2713aSLionel Sambuc                                       DeclContext *&LexicalDC,
1810f4a2713aSLionel Sambuc                                       DeclarationName &Name,
1811f4a2713aSLionel Sambuc                                       SourceLocation &Loc) {
1812f4a2713aSLionel Sambuc   // Import the context of this declaration.
1813f4a2713aSLionel Sambuc   DC = Importer.ImportContext(D->getDeclContext());
1814f4a2713aSLionel Sambuc   if (!DC)
1815f4a2713aSLionel Sambuc     return true;
1816f4a2713aSLionel Sambuc 
1817f4a2713aSLionel Sambuc   LexicalDC = DC;
1818f4a2713aSLionel Sambuc   if (D->getDeclContext() != D->getLexicalDeclContext()) {
1819f4a2713aSLionel Sambuc     LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
1820f4a2713aSLionel Sambuc     if (!LexicalDC)
1821f4a2713aSLionel Sambuc       return true;
1822f4a2713aSLionel Sambuc   }
1823f4a2713aSLionel Sambuc 
1824f4a2713aSLionel Sambuc   // Import the name of this declaration.
1825f4a2713aSLionel Sambuc   Name = Importer.Import(D->getDeclName());
1826f4a2713aSLionel Sambuc   if (D->getDeclName() && !Name)
1827f4a2713aSLionel Sambuc     return true;
1828f4a2713aSLionel Sambuc 
1829f4a2713aSLionel Sambuc   // Import the location of this declaration.
1830f4a2713aSLionel Sambuc   Loc = Importer.Import(D->getLocation());
1831f4a2713aSLionel Sambuc   return false;
1832f4a2713aSLionel Sambuc }
1833f4a2713aSLionel Sambuc 
ImportDefinitionIfNeeded(Decl * FromD,Decl * ToD)1834f4a2713aSLionel Sambuc void ASTNodeImporter::ImportDefinitionIfNeeded(Decl *FromD, Decl *ToD) {
1835f4a2713aSLionel Sambuc   if (!FromD)
1836f4a2713aSLionel Sambuc     return;
1837f4a2713aSLionel Sambuc 
1838f4a2713aSLionel Sambuc   if (!ToD) {
1839f4a2713aSLionel Sambuc     ToD = Importer.Import(FromD);
1840f4a2713aSLionel Sambuc     if (!ToD)
1841f4a2713aSLionel Sambuc       return;
1842f4a2713aSLionel Sambuc   }
1843f4a2713aSLionel Sambuc 
1844f4a2713aSLionel Sambuc   if (RecordDecl *FromRecord = dyn_cast<RecordDecl>(FromD)) {
1845f4a2713aSLionel Sambuc     if (RecordDecl *ToRecord = cast_or_null<RecordDecl>(ToD)) {
1846f4a2713aSLionel Sambuc       if (FromRecord->getDefinition() && FromRecord->isCompleteDefinition() && !ToRecord->getDefinition()) {
1847f4a2713aSLionel Sambuc         ImportDefinition(FromRecord, ToRecord);
1848f4a2713aSLionel Sambuc       }
1849f4a2713aSLionel Sambuc     }
1850f4a2713aSLionel Sambuc     return;
1851f4a2713aSLionel Sambuc   }
1852f4a2713aSLionel Sambuc 
1853f4a2713aSLionel Sambuc   if (EnumDecl *FromEnum = dyn_cast<EnumDecl>(FromD)) {
1854f4a2713aSLionel Sambuc     if (EnumDecl *ToEnum = cast_or_null<EnumDecl>(ToD)) {
1855f4a2713aSLionel Sambuc       if (FromEnum->getDefinition() && !ToEnum->getDefinition()) {
1856f4a2713aSLionel Sambuc         ImportDefinition(FromEnum, ToEnum);
1857f4a2713aSLionel Sambuc       }
1858f4a2713aSLionel Sambuc     }
1859f4a2713aSLionel Sambuc     return;
1860f4a2713aSLionel Sambuc   }
1861f4a2713aSLionel Sambuc }
1862f4a2713aSLionel Sambuc 
1863f4a2713aSLionel Sambuc void
ImportDeclarationNameLoc(const DeclarationNameInfo & From,DeclarationNameInfo & To)1864f4a2713aSLionel Sambuc ASTNodeImporter::ImportDeclarationNameLoc(const DeclarationNameInfo &From,
1865f4a2713aSLionel Sambuc                                           DeclarationNameInfo& To) {
1866f4a2713aSLionel Sambuc   // NOTE: To.Name and To.Loc are already imported.
1867f4a2713aSLionel Sambuc   // We only have to import To.LocInfo.
1868f4a2713aSLionel Sambuc   switch (To.getName().getNameKind()) {
1869f4a2713aSLionel Sambuc   case DeclarationName::Identifier:
1870f4a2713aSLionel Sambuc   case DeclarationName::ObjCZeroArgSelector:
1871f4a2713aSLionel Sambuc   case DeclarationName::ObjCOneArgSelector:
1872f4a2713aSLionel Sambuc   case DeclarationName::ObjCMultiArgSelector:
1873f4a2713aSLionel Sambuc   case DeclarationName::CXXUsingDirective:
1874f4a2713aSLionel Sambuc     return;
1875f4a2713aSLionel Sambuc 
1876f4a2713aSLionel Sambuc   case DeclarationName::CXXOperatorName: {
1877f4a2713aSLionel Sambuc     SourceRange Range = From.getCXXOperatorNameRange();
1878f4a2713aSLionel Sambuc     To.setCXXOperatorNameRange(Importer.Import(Range));
1879f4a2713aSLionel Sambuc     return;
1880f4a2713aSLionel Sambuc   }
1881f4a2713aSLionel Sambuc   case DeclarationName::CXXLiteralOperatorName: {
1882f4a2713aSLionel Sambuc     SourceLocation Loc = From.getCXXLiteralOperatorNameLoc();
1883f4a2713aSLionel Sambuc     To.setCXXLiteralOperatorNameLoc(Importer.Import(Loc));
1884f4a2713aSLionel Sambuc     return;
1885f4a2713aSLionel Sambuc   }
1886f4a2713aSLionel Sambuc   case DeclarationName::CXXConstructorName:
1887f4a2713aSLionel Sambuc   case DeclarationName::CXXDestructorName:
1888f4a2713aSLionel Sambuc   case DeclarationName::CXXConversionFunctionName: {
1889f4a2713aSLionel Sambuc     TypeSourceInfo *FromTInfo = From.getNamedTypeInfo();
1890f4a2713aSLionel Sambuc     To.setNamedTypeInfo(Importer.Import(FromTInfo));
1891f4a2713aSLionel Sambuc     return;
1892f4a2713aSLionel Sambuc   }
1893f4a2713aSLionel Sambuc   }
1894f4a2713aSLionel Sambuc   llvm_unreachable("Unknown name kind.");
1895f4a2713aSLionel Sambuc }
1896f4a2713aSLionel Sambuc 
ImportDeclContext(DeclContext * FromDC,bool ForceImport)1897f4a2713aSLionel Sambuc void ASTNodeImporter::ImportDeclContext(DeclContext *FromDC, bool ForceImport) {
1898f4a2713aSLionel Sambuc   if (Importer.isMinimalImport() && !ForceImport) {
1899f4a2713aSLionel Sambuc     Importer.ImportContext(FromDC);
1900f4a2713aSLionel Sambuc     return;
1901f4a2713aSLionel Sambuc   }
1902f4a2713aSLionel Sambuc 
1903*0a6a1f1dSLionel Sambuc   for (auto *From : FromDC->decls())
1904*0a6a1f1dSLionel Sambuc     Importer.Import(From);
1905f4a2713aSLionel Sambuc }
1906f4a2713aSLionel Sambuc 
ImportDefinition(RecordDecl * From,RecordDecl * To,ImportDefinitionKind Kind)1907f4a2713aSLionel Sambuc bool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To,
1908f4a2713aSLionel Sambuc                                        ImportDefinitionKind Kind) {
1909f4a2713aSLionel Sambuc   if (To->getDefinition() || To->isBeingDefined()) {
1910f4a2713aSLionel Sambuc     if (Kind == IDK_Everything)
1911f4a2713aSLionel Sambuc       ImportDeclContext(From, /*ForceImport=*/true);
1912f4a2713aSLionel Sambuc 
1913f4a2713aSLionel Sambuc     return false;
1914f4a2713aSLionel Sambuc   }
1915f4a2713aSLionel Sambuc 
1916f4a2713aSLionel Sambuc   To->startDefinition();
1917f4a2713aSLionel Sambuc 
1918f4a2713aSLionel Sambuc   // Add base classes.
1919f4a2713aSLionel Sambuc   if (CXXRecordDecl *ToCXX = dyn_cast<CXXRecordDecl>(To)) {
1920f4a2713aSLionel Sambuc     CXXRecordDecl *FromCXX = cast<CXXRecordDecl>(From);
1921f4a2713aSLionel Sambuc 
1922f4a2713aSLionel Sambuc     struct CXXRecordDecl::DefinitionData &ToData = ToCXX->data();
1923f4a2713aSLionel Sambuc     struct CXXRecordDecl::DefinitionData &FromData = FromCXX->data();
1924f4a2713aSLionel Sambuc     ToData.UserDeclaredConstructor = FromData.UserDeclaredConstructor;
1925f4a2713aSLionel Sambuc     ToData.UserDeclaredSpecialMembers = FromData.UserDeclaredSpecialMembers;
1926f4a2713aSLionel Sambuc     ToData.Aggregate = FromData.Aggregate;
1927f4a2713aSLionel Sambuc     ToData.PlainOldData = FromData.PlainOldData;
1928f4a2713aSLionel Sambuc     ToData.Empty = FromData.Empty;
1929f4a2713aSLionel Sambuc     ToData.Polymorphic = FromData.Polymorphic;
1930f4a2713aSLionel Sambuc     ToData.Abstract = FromData.Abstract;
1931f4a2713aSLionel Sambuc     ToData.IsStandardLayout = FromData.IsStandardLayout;
1932f4a2713aSLionel Sambuc     ToData.HasNoNonEmptyBases = FromData.HasNoNonEmptyBases;
1933f4a2713aSLionel Sambuc     ToData.HasPrivateFields = FromData.HasPrivateFields;
1934f4a2713aSLionel Sambuc     ToData.HasProtectedFields = FromData.HasProtectedFields;
1935f4a2713aSLionel Sambuc     ToData.HasPublicFields = FromData.HasPublicFields;
1936f4a2713aSLionel Sambuc     ToData.HasMutableFields = FromData.HasMutableFields;
1937*0a6a1f1dSLionel Sambuc     ToData.HasVariantMembers = FromData.HasVariantMembers;
1938f4a2713aSLionel Sambuc     ToData.HasOnlyCMembers = FromData.HasOnlyCMembers;
1939f4a2713aSLionel Sambuc     ToData.HasInClassInitializer = FromData.HasInClassInitializer;
1940f4a2713aSLionel Sambuc     ToData.HasUninitializedReferenceMember
1941f4a2713aSLionel Sambuc       = FromData.HasUninitializedReferenceMember;
1942f4a2713aSLionel Sambuc     ToData.NeedOverloadResolutionForMoveConstructor
1943f4a2713aSLionel Sambuc       = FromData.NeedOverloadResolutionForMoveConstructor;
1944f4a2713aSLionel Sambuc     ToData.NeedOverloadResolutionForMoveAssignment
1945f4a2713aSLionel Sambuc       = FromData.NeedOverloadResolutionForMoveAssignment;
1946f4a2713aSLionel Sambuc     ToData.NeedOverloadResolutionForDestructor
1947f4a2713aSLionel Sambuc       = FromData.NeedOverloadResolutionForDestructor;
1948f4a2713aSLionel Sambuc     ToData.DefaultedMoveConstructorIsDeleted
1949f4a2713aSLionel Sambuc       = FromData.DefaultedMoveConstructorIsDeleted;
1950f4a2713aSLionel Sambuc     ToData.DefaultedMoveAssignmentIsDeleted
1951f4a2713aSLionel Sambuc       = FromData.DefaultedMoveAssignmentIsDeleted;
1952f4a2713aSLionel Sambuc     ToData.DefaultedDestructorIsDeleted = FromData.DefaultedDestructorIsDeleted;
1953f4a2713aSLionel Sambuc     ToData.HasTrivialSpecialMembers = FromData.HasTrivialSpecialMembers;
1954f4a2713aSLionel Sambuc     ToData.HasIrrelevantDestructor = FromData.HasIrrelevantDestructor;
1955f4a2713aSLionel Sambuc     ToData.HasConstexprNonCopyMoveConstructor
1956f4a2713aSLionel Sambuc       = FromData.HasConstexprNonCopyMoveConstructor;
1957f4a2713aSLionel Sambuc     ToData.DefaultedDefaultConstructorIsConstexpr
1958f4a2713aSLionel Sambuc       = FromData.DefaultedDefaultConstructorIsConstexpr;
1959f4a2713aSLionel Sambuc     ToData.HasConstexprDefaultConstructor
1960f4a2713aSLionel Sambuc       = FromData.HasConstexprDefaultConstructor;
1961f4a2713aSLionel Sambuc     ToData.HasNonLiteralTypeFieldsOrBases
1962f4a2713aSLionel Sambuc       = FromData.HasNonLiteralTypeFieldsOrBases;
1963f4a2713aSLionel Sambuc     // ComputedVisibleConversions not imported.
1964f4a2713aSLionel Sambuc     ToData.UserProvidedDefaultConstructor
1965f4a2713aSLionel Sambuc       = FromData.UserProvidedDefaultConstructor;
1966f4a2713aSLionel Sambuc     ToData.DeclaredSpecialMembers = FromData.DeclaredSpecialMembers;
1967f4a2713aSLionel Sambuc     ToData.ImplicitCopyConstructorHasConstParam
1968f4a2713aSLionel Sambuc       = FromData.ImplicitCopyConstructorHasConstParam;
1969f4a2713aSLionel Sambuc     ToData.ImplicitCopyAssignmentHasConstParam
1970f4a2713aSLionel Sambuc       = FromData.ImplicitCopyAssignmentHasConstParam;
1971f4a2713aSLionel Sambuc     ToData.HasDeclaredCopyConstructorWithConstParam
1972f4a2713aSLionel Sambuc       = FromData.HasDeclaredCopyConstructorWithConstParam;
1973f4a2713aSLionel Sambuc     ToData.HasDeclaredCopyAssignmentWithConstParam
1974f4a2713aSLionel Sambuc       = FromData.HasDeclaredCopyAssignmentWithConstParam;
1975f4a2713aSLionel Sambuc     ToData.IsLambda = FromData.IsLambda;
1976f4a2713aSLionel Sambuc 
1977f4a2713aSLionel Sambuc     SmallVector<CXXBaseSpecifier *, 4> Bases;
1978*0a6a1f1dSLionel Sambuc     for (const auto &Base1 : FromCXX->bases()) {
1979*0a6a1f1dSLionel Sambuc       QualType T = Importer.Import(Base1.getType());
1980f4a2713aSLionel Sambuc       if (T.isNull())
1981f4a2713aSLionel Sambuc         return true;
1982f4a2713aSLionel Sambuc 
1983f4a2713aSLionel Sambuc       SourceLocation EllipsisLoc;
1984*0a6a1f1dSLionel Sambuc       if (Base1.isPackExpansion())
1985*0a6a1f1dSLionel Sambuc         EllipsisLoc = Importer.Import(Base1.getEllipsisLoc());
1986f4a2713aSLionel Sambuc 
1987f4a2713aSLionel Sambuc       // Ensure that we have a definition for the base.
1988*0a6a1f1dSLionel Sambuc       ImportDefinitionIfNeeded(Base1.getType()->getAsCXXRecordDecl());
1989f4a2713aSLionel Sambuc 
1990f4a2713aSLionel Sambuc       Bases.push_back(
1991f4a2713aSLionel Sambuc                     new (Importer.getToContext())
1992*0a6a1f1dSLionel Sambuc                       CXXBaseSpecifier(Importer.Import(Base1.getSourceRange()),
1993*0a6a1f1dSLionel Sambuc                                        Base1.isVirtual(),
1994*0a6a1f1dSLionel Sambuc                                        Base1.isBaseOfClass(),
1995*0a6a1f1dSLionel Sambuc                                        Base1.getAccessSpecifierAsWritten(),
1996*0a6a1f1dSLionel Sambuc                                    Importer.Import(Base1.getTypeSourceInfo()),
1997f4a2713aSLionel Sambuc                                        EllipsisLoc));
1998f4a2713aSLionel Sambuc     }
1999f4a2713aSLionel Sambuc     if (!Bases.empty())
2000f4a2713aSLionel Sambuc       ToCXX->setBases(Bases.data(), Bases.size());
2001f4a2713aSLionel Sambuc   }
2002f4a2713aSLionel Sambuc 
2003f4a2713aSLionel Sambuc   if (shouldForceImportDeclContext(Kind))
2004f4a2713aSLionel Sambuc     ImportDeclContext(From, /*ForceImport=*/true);
2005f4a2713aSLionel Sambuc 
2006f4a2713aSLionel Sambuc   To->completeDefinition();
2007f4a2713aSLionel Sambuc   return false;
2008f4a2713aSLionel Sambuc }
2009f4a2713aSLionel Sambuc 
ImportDefinition(VarDecl * From,VarDecl * To,ImportDefinitionKind Kind)2010f4a2713aSLionel Sambuc bool ASTNodeImporter::ImportDefinition(VarDecl *From, VarDecl *To,
2011f4a2713aSLionel Sambuc                                        ImportDefinitionKind Kind) {
2012f4a2713aSLionel Sambuc   if (To->getDefinition())
2013f4a2713aSLionel Sambuc     return false;
2014f4a2713aSLionel Sambuc 
2015f4a2713aSLionel Sambuc   // FIXME: Can we really import any initializer? Alternatively, we could force
2016f4a2713aSLionel Sambuc   // ourselves to import every declaration of a variable and then only use
2017f4a2713aSLionel Sambuc   // getInit() here.
2018f4a2713aSLionel Sambuc   To->setInit(Importer.Import(const_cast<Expr *>(From->getAnyInitializer())));
2019f4a2713aSLionel Sambuc 
2020f4a2713aSLionel Sambuc   // FIXME: Other bits to merge?
2021f4a2713aSLionel Sambuc 
2022f4a2713aSLionel Sambuc   return false;
2023f4a2713aSLionel Sambuc }
2024f4a2713aSLionel Sambuc 
ImportDefinition(EnumDecl * From,EnumDecl * To,ImportDefinitionKind Kind)2025f4a2713aSLionel Sambuc bool ASTNodeImporter::ImportDefinition(EnumDecl *From, EnumDecl *To,
2026f4a2713aSLionel Sambuc                                        ImportDefinitionKind Kind) {
2027f4a2713aSLionel Sambuc   if (To->getDefinition() || To->isBeingDefined()) {
2028f4a2713aSLionel Sambuc     if (Kind == IDK_Everything)
2029f4a2713aSLionel Sambuc       ImportDeclContext(From, /*ForceImport=*/true);
2030f4a2713aSLionel Sambuc     return false;
2031f4a2713aSLionel Sambuc   }
2032f4a2713aSLionel Sambuc 
2033f4a2713aSLionel Sambuc   To->startDefinition();
2034f4a2713aSLionel Sambuc 
2035f4a2713aSLionel Sambuc   QualType T = Importer.Import(Importer.getFromContext().getTypeDeclType(From));
2036f4a2713aSLionel Sambuc   if (T.isNull())
2037f4a2713aSLionel Sambuc     return true;
2038f4a2713aSLionel Sambuc 
2039f4a2713aSLionel Sambuc   QualType ToPromotionType = Importer.Import(From->getPromotionType());
2040f4a2713aSLionel Sambuc   if (ToPromotionType.isNull())
2041f4a2713aSLionel Sambuc     return true;
2042f4a2713aSLionel Sambuc 
2043f4a2713aSLionel Sambuc   if (shouldForceImportDeclContext(Kind))
2044f4a2713aSLionel Sambuc     ImportDeclContext(From, /*ForceImport=*/true);
2045f4a2713aSLionel Sambuc 
2046f4a2713aSLionel Sambuc   // FIXME: we might need to merge the number of positive or negative bits
2047f4a2713aSLionel Sambuc   // if the enumerator lists don't match.
2048f4a2713aSLionel Sambuc   To->completeDefinition(T, ToPromotionType,
2049f4a2713aSLionel Sambuc                          From->getNumPositiveBits(),
2050f4a2713aSLionel Sambuc                          From->getNumNegativeBits());
2051f4a2713aSLionel Sambuc   return false;
2052f4a2713aSLionel Sambuc }
2053f4a2713aSLionel Sambuc 
ImportTemplateParameterList(TemplateParameterList * Params)2054f4a2713aSLionel Sambuc TemplateParameterList *ASTNodeImporter::ImportTemplateParameterList(
2055f4a2713aSLionel Sambuc                                                 TemplateParameterList *Params) {
2056f4a2713aSLionel Sambuc   SmallVector<NamedDecl *, 4> ToParams;
2057f4a2713aSLionel Sambuc   ToParams.reserve(Params->size());
2058f4a2713aSLionel Sambuc   for (TemplateParameterList::iterator P = Params->begin(),
2059f4a2713aSLionel Sambuc                                     PEnd = Params->end();
2060f4a2713aSLionel Sambuc        P != PEnd; ++P) {
2061f4a2713aSLionel Sambuc     Decl *To = Importer.Import(*P);
2062f4a2713aSLionel Sambuc     if (!To)
2063*0a6a1f1dSLionel Sambuc       return nullptr;
2064f4a2713aSLionel Sambuc 
2065f4a2713aSLionel Sambuc     ToParams.push_back(cast<NamedDecl>(To));
2066f4a2713aSLionel Sambuc   }
2067f4a2713aSLionel Sambuc 
2068f4a2713aSLionel Sambuc   return TemplateParameterList::Create(Importer.getToContext(),
2069f4a2713aSLionel Sambuc                                        Importer.Import(Params->getTemplateLoc()),
2070f4a2713aSLionel Sambuc                                        Importer.Import(Params->getLAngleLoc()),
2071f4a2713aSLionel Sambuc                                        ToParams.data(), ToParams.size(),
2072f4a2713aSLionel Sambuc                                        Importer.Import(Params->getRAngleLoc()));
2073f4a2713aSLionel Sambuc }
2074f4a2713aSLionel Sambuc 
2075f4a2713aSLionel Sambuc TemplateArgument
ImportTemplateArgument(const TemplateArgument & From)2076f4a2713aSLionel Sambuc ASTNodeImporter::ImportTemplateArgument(const TemplateArgument &From) {
2077f4a2713aSLionel Sambuc   switch (From.getKind()) {
2078f4a2713aSLionel Sambuc   case TemplateArgument::Null:
2079f4a2713aSLionel Sambuc     return TemplateArgument();
2080f4a2713aSLionel Sambuc 
2081f4a2713aSLionel Sambuc   case TemplateArgument::Type: {
2082f4a2713aSLionel Sambuc     QualType ToType = Importer.Import(From.getAsType());
2083f4a2713aSLionel Sambuc     if (ToType.isNull())
2084f4a2713aSLionel Sambuc       return TemplateArgument();
2085f4a2713aSLionel Sambuc     return TemplateArgument(ToType);
2086f4a2713aSLionel Sambuc   }
2087f4a2713aSLionel Sambuc 
2088f4a2713aSLionel Sambuc   case TemplateArgument::Integral: {
2089f4a2713aSLionel Sambuc     QualType ToType = Importer.Import(From.getIntegralType());
2090f4a2713aSLionel Sambuc     if (ToType.isNull())
2091f4a2713aSLionel Sambuc       return TemplateArgument();
2092f4a2713aSLionel Sambuc     return TemplateArgument(From, ToType);
2093f4a2713aSLionel Sambuc   }
2094f4a2713aSLionel Sambuc 
2095f4a2713aSLionel Sambuc   case TemplateArgument::Declaration: {
2096*0a6a1f1dSLionel Sambuc     ValueDecl *To = cast_or_null<ValueDecl>(Importer.Import(From.getAsDecl()));
2097*0a6a1f1dSLionel Sambuc     QualType ToType = Importer.Import(From.getParamTypeForDecl());
2098*0a6a1f1dSLionel Sambuc     if (!To || ToType.isNull())
2099f4a2713aSLionel Sambuc       return TemplateArgument();
2100*0a6a1f1dSLionel Sambuc     return TemplateArgument(To, ToType);
2101f4a2713aSLionel Sambuc   }
2102f4a2713aSLionel Sambuc 
2103f4a2713aSLionel Sambuc   case TemplateArgument::NullPtr: {
2104f4a2713aSLionel Sambuc     QualType ToType = Importer.Import(From.getNullPtrType());
2105f4a2713aSLionel Sambuc     if (ToType.isNull())
2106f4a2713aSLionel Sambuc       return TemplateArgument();
2107f4a2713aSLionel Sambuc     return TemplateArgument(ToType, /*isNullPtr*/true);
2108f4a2713aSLionel Sambuc   }
2109f4a2713aSLionel Sambuc 
2110f4a2713aSLionel Sambuc   case TemplateArgument::Template: {
2111f4a2713aSLionel Sambuc     TemplateName ToTemplate = Importer.Import(From.getAsTemplate());
2112f4a2713aSLionel Sambuc     if (ToTemplate.isNull())
2113f4a2713aSLionel Sambuc       return TemplateArgument();
2114f4a2713aSLionel Sambuc 
2115f4a2713aSLionel Sambuc     return TemplateArgument(ToTemplate);
2116f4a2713aSLionel Sambuc   }
2117f4a2713aSLionel Sambuc 
2118f4a2713aSLionel Sambuc   case TemplateArgument::TemplateExpansion: {
2119f4a2713aSLionel Sambuc     TemplateName ToTemplate
2120f4a2713aSLionel Sambuc       = Importer.Import(From.getAsTemplateOrTemplatePattern());
2121f4a2713aSLionel Sambuc     if (ToTemplate.isNull())
2122f4a2713aSLionel Sambuc       return TemplateArgument();
2123f4a2713aSLionel Sambuc 
2124f4a2713aSLionel Sambuc     return TemplateArgument(ToTemplate, From.getNumTemplateExpansions());
2125f4a2713aSLionel Sambuc   }
2126f4a2713aSLionel Sambuc 
2127f4a2713aSLionel Sambuc   case TemplateArgument::Expression:
2128f4a2713aSLionel Sambuc     if (Expr *ToExpr = Importer.Import(From.getAsExpr()))
2129f4a2713aSLionel Sambuc       return TemplateArgument(ToExpr);
2130f4a2713aSLionel Sambuc     return TemplateArgument();
2131f4a2713aSLionel Sambuc 
2132f4a2713aSLionel Sambuc   case TemplateArgument::Pack: {
2133f4a2713aSLionel Sambuc     SmallVector<TemplateArgument, 2> ToPack;
2134f4a2713aSLionel Sambuc     ToPack.reserve(From.pack_size());
2135f4a2713aSLionel Sambuc     if (ImportTemplateArguments(From.pack_begin(), From.pack_size(), ToPack))
2136f4a2713aSLionel Sambuc       return TemplateArgument();
2137f4a2713aSLionel Sambuc 
2138f4a2713aSLionel Sambuc     TemplateArgument *ToArgs
2139f4a2713aSLionel Sambuc       = new (Importer.getToContext()) TemplateArgument[ToPack.size()];
2140f4a2713aSLionel Sambuc     std::copy(ToPack.begin(), ToPack.end(), ToArgs);
2141f4a2713aSLionel Sambuc     return TemplateArgument(ToArgs, ToPack.size());
2142f4a2713aSLionel Sambuc   }
2143f4a2713aSLionel Sambuc   }
2144f4a2713aSLionel Sambuc 
2145f4a2713aSLionel Sambuc   llvm_unreachable("Invalid template argument kind");
2146f4a2713aSLionel Sambuc }
2147f4a2713aSLionel Sambuc 
ImportTemplateArguments(const TemplateArgument * FromArgs,unsigned NumFromArgs,SmallVectorImpl<TemplateArgument> & ToArgs)2148f4a2713aSLionel Sambuc bool ASTNodeImporter::ImportTemplateArguments(const TemplateArgument *FromArgs,
2149f4a2713aSLionel Sambuc                                               unsigned NumFromArgs,
2150f4a2713aSLionel Sambuc                               SmallVectorImpl<TemplateArgument> &ToArgs) {
2151f4a2713aSLionel Sambuc   for (unsigned I = 0; I != NumFromArgs; ++I) {
2152f4a2713aSLionel Sambuc     TemplateArgument To = ImportTemplateArgument(FromArgs[I]);
2153f4a2713aSLionel Sambuc     if (To.isNull() && !FromArgs[I].isNull())
2154f4a2713aSLionel Sambuc       return true;
2155f4a2713aSLionel Sambuc 
2156f4a2713aSLionel Sambuc     ToArgs.push_back(To);
2157f4a2713aSLionel Sambuc   }
2158f4a2713aSLionel Sambuc 
2159f4a2713aSLionel Sambuc   return false;
2160f4a2713aSLionel Sambuc }
2161f4a2713aSLionel Sambuc 
IsStructuralMatch(RecordDecl * FromRecord,RecordDecl * ToRecord,bool Complain)2162f4a2713aSLionel Sambuc bool ASTNodeImporter::IsStructuralMatch(RecordDecl *FromRecord,
2163f4a2713aSLionel Sambuc                                         RecordDecl *ToRecord, bool Complain) {
2164f4a2713aSLionel Sambuc   // Eliminate a potential failure point where we attempt to re-import
2165f4a2713aSLionel Sambuc   // something we're trying to import while completing ToRecord.
2166f4a2713aSLionel Sambuc   Decl *ToOrigin = Importer.GetOriginalDecl(ToRecord);
2167f4a2713aSLionel Sambuc   if (ToOrigin) {
2168f4a2713aSLionel Sambuc     RecordDecl *ToOriginRecord = dyn_cast<RecordDecl>(ToOrigin);
2169f4a2713aSLionel Sambuc     if (ToOriginRecord)
2170f4a2713aSLionel Sambuc       ToRecord = ToOriginRecord;
2171f4a2713aSLionel Sambuc   }
2172f4a2713aSLionel Sambuc 
2173f4a2713aSLionel Sambuc   StructuralEquivalenceContext Ctx(Importer.getFromContext(),
2174f4a2713aSLionel Sambuc                                    ToRecord->getASTContext(),
2175f4a2713aSLionel Sambuc                                    Importer.getNonEquivalentDecls(),
2176f4a2713aSLionel Sambuc                                    false, Complain);
2177f4a2713aSLionel Sambuc   return Ctx.IsStructurallyEquivalent(FromRecord, ToRecord);
2178f4a2713aSLionel Sambuc }
2179f4a2713aSLionel Sambuc 
IsStructuralMatch(VarDecl * FromVar,VarDecl * ToVar,bool Complain)2180f4a2713aSLionel Sambuc bool ASTNodeImporter::IsStructuralMatch(VarDecl *FromVar, VarDecl *ToVar,
2181f4a2713aSLionel Sambuc                                         bool Complain) {
2182f4a2713aSLionel Sambuc   StructuralEquivalenceContext Ctx(
2183f4a2713aSLionel Sambuc       Importer.getFromContext(), Importer.getToContext(),
2184f4a2713aSLionel Sambuc       Importer.getNonEquivalentDecls(), false, Complain);
2185f4a2713aSLionel Sambuc   return Ctx.IsStructurallyEquivalent(FromVar, ToVar);
2186f4a2713aSLionel Sambuc }
2187f4a2713aSLionel Sambuc 
IsStructuralMatch(EnumDecl * FromEnum,EnumDecl * ToEnum)2188f4a2713aSLionel Sambuc bool ASTNodeImporter::IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToEnum) {
2189f4a2713aSLionel Sambuc   StructuralEquivalenceContext Ctx(Importer.getFromContext(),
2190f4a2713aSLionel Sambuc                                    Importer.getToContext(),
2191f4a2713aSLionel Sambuc                                    Importer.getNonEquivalentDecls());
2192f4a2713aSLionel Sambuc   return Ctx.IsStructurallyEquivalent(FromEnum, ToEnum);
2193f4a2713aSLionel Sambuc }
2194f4a2713aSLionel Sambuc 
IsStructuralMatch(EnumConstantDecl * FromEC,EnumConstantDecl * ToEC)2195f4a2713aSLionel Sambuc bool ASTNodeImporter::IsStructuralMatch(EnumConstantDecl *FromEC,
2196f4a2713aSLionel Sambuc                                         EnumConstantDecl *ToEC)
2197f4a2713aSLionel Sambuc {
2198f4a2713aSLionel Sambuc   const llvm::APSInt &FromVal = FromEC->getInitVal();
2199f4a2713aSLionel Sambuc   const llvm::APSInt &ToVal = ToEC->getInitVal();
2200f4a2713aSLionel Sambuc 
2201f4a2713aSLionel Sambuc   return FromVal.isSigned() == ToVal.isSigned() &&
2202f4a2713aSLionel Sambuc          FromVal.getBitWidth() == ToVal.getBitWidth() &&
2203f4a2713aSLionel Sambuc          FromVal == ToVal;
2204f4a2713aSLionel Sambuc }
2205f4a2713aSLionel Sambuc 
IsStructuralMatch(ClassTemplateDecl * From,ClassTemplateDecl * To)2206f4a2713aSLionel Sambuc bool ASTNodeImporter::IsStructuralMatch(ClassTemplateDecl *From,
2207f4a2713aSLionel Sambuc                                         ClassTemplateDecl *To) {
2208f4a2713aSLionel Sambuc   StructuralEquivalenceContext Ctx(Importer.getFromContext(),
2209f4a2713aSLionel Sambuc                                    Importer.getToContext(),
2210f4a2713aSLionel Sambuc                                    Importer.getNonEquivalentDecls());
2211f4a2713aSLionel Sambuc   return Ctx.IsStructurallyEquivalent(From, To);
2212f4a2713aSLionel Sambuc }
2213f4a2713aSLionel Sambuc 
IsStructuralMatch(VarTemplateDecl * From,VarTemplateDecl * To)2214f4a2713aSLionel Sambuc bool ASTNodeImporter::IsStructuralMatch(VarTemplateDecl *From,
2215f4a2713aSLionel Sambuc                                         VarTemplateDecl *To) {
2216f4a2713aSLionel Sambuc   StructuralEquivalenceContext Ctx(Importer.getFromContext(),
2217f4a2713aSLionel Sambuc                                    Importer.getToContext(),
2218f4a2713aSLionel Sambuc                                    Importer.getNonEquivalentDecls());
2219f4a2713aSLionel Sambuc   return Ctx.IsStructurallyEquivalent(From, To);
2220f4a2713aSLionel Sambuc }
2221f4a2713aSLionel Sambuc 
VisitDecl(Decl * D)2222f4a2713aSLionel Sambuc Decl *ASTNodeImporter::VisitDecl(Decl *D) {
2223f4a2713aSLionel Sambuc   Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node)
2224f4a2713aSLionel Sambuc     << D->getDeclKindName();
2225*0a6a1f1dSLionel Sambuc   return nullptr;
2226f4a2713aSLionel Sambuc }
2227f4a2713aSLionel Sambuc 
VisitTranslationUnitDecl(TranslationUnitDecl * D)2228f4a2713aSLionel Sambuc Decl *ASTNodeImporter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
2229f4a2713aSLionel Sambuc   TranslationUnitDecl *ToD =
2230f4a2713aSLionel Sambuc     Importer.getToContext().getTranslationUnitDecl();
2231f4a2713aSLionel Sambuc 
2232f4a2713aSLionel Sambuc   Importer.Imported(D, ToD);
2233f4a2713aSLionel Sambuc 
2234f4a2713aSLionel Sambuc   return ToD;
2235f4a2713aSLionel Sambuc }
2236f4a2713aSLionel Sambuc 
VisitNamespaceDecl(NamespaceDecl * D)2237f4a2713aSLionel Sambuc Decl *ASTNodeImporter::VisitNamespaceDecl(NamespaceDecl *D) {
2238f4a2713aSLionel Sambuc   // Import the major distinguishing characteristics of this namespace.
2239f4a2713aSLionel Sambuc   DeclContext *DC, *LexicalDC;
2240f4a2713aSLionel Sambuc   DeclarationName Name;
2241f4a2713aSLionel Sambuc   SourceLocation Loc;
2242f4a2713aSLionel Sambuc   if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2243*0a6a1f1dSLionel Sambuc     return nullptr;
2244f4a2713aSLionel Sambuc 
2245*0a6a1f1dSLionel Sambuc   NamespaceDecl *MergeWithNamespace = nullptr;
2246f4a2713aSLionel Sambuc   if (!Name) {
2247f4a2713aSLionel Sambuc     // This is an anonymous namespace. Adopt an existing anonymous
2248f4a2713aSLionel Sambuc     // namespace if we can.
2249f4a2713aSLionel Sambuc     // FIXME: Not testable.
2250f4a2713aSLionel Sambuc     if (TranslationUnitDecl *TU = dyn_cast<TranslationUnitDecl>(DC))
2251f4a2713aSLionel Sambuc       MergeWithNamespace = TU->getAnonymousNamespace();
2252f4a2713aSLionel Sambuc     else
2253f4a2713aSLionel Sambuc       MergeWithNamespace = cast<NamespaceDecl>(DC)->getAnonymousNamespace();
2254f4a2713aSLionel Sambuc   } else {
2255f4a2713aSLionel Sambuc     SmallVector<NamedDecl *, 4> ConflictingDecls;
2256f4a2713aSLionel Sambuc     SmallVector<NamedDecl *, 2> FoundDecls;
2257*0a6a1f1dSLionel Sambuc     DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
2258f4a2713aSLionel Sambuc     for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
2259f4a2713aSLionel Sambuc       if (!FoundDecls[I]->isInIdentifierNamespace(Decl::IDNS_Namespace))
2260f4a2713aSLionel Sambuc         continue;
2261f4a2713aSLionel Sambuc 
2262f4a2713aSLionel Sambuc       if (NamespaceDecl *FoundNS = dyn_cast<NamespaceDecl>(FoundDecls[I])) {
2263f4a2713aSLionel Sambuc         MergeWithNamespace = FoundNS;
2264f4a2713aSLionel Sambuc         ConflictingDecls.clear();
2265f4a2713aSLionel Sambuc         break;
2266f4a2713aSLionel Sambuc       }
2267f4a2713aSLionel Sambuc 
2268f4a2713aSLionel Sambuc       ConflictingDecls.push_back(FoundDecls[I]);
2269f4a2713aSLionel Sambuc     }
2270f4a2713aSLionel Sambuc 
2271f4a2713aSLionel Sambuc     if (!ConflictingDecls.empty()) {
2272f4a2713aSLionel Sambuc       Name = Importer.HandleNameConflict(Name, DC, Decl::IDNS_Namespace,
2273f4a2713aSLionel Sambuc                                          ConflictingDecls.data(),
2274f4a2713aSLionel Sambuc                                          ConflictingDecls.size());
2275f4a2713aSLionel Sambuc     }
2276f4a2713aSLionel Sambuc   }
2277f4a2713aSLionel Sambuc 
2278f4a2713aSLionel Sambuc   // Create the "to" namespace, if needed.
2279f4a2713aSLionel Sambuc   NamespaceDecl *ToNamespace = MergeWithNamespace;
2280f4a2713aSLionel Sambuc   if (!ToNamespace) {
2281f4a2713aSLionel Sambuc     ToNamespace = NamespaceDecl::Create(Importer.getToContext(), DC,
2282f4a2713aSLionel Sambuc                                         D->isInline(),
2283f4a2713aSLionel Sambuc                                         Importer.Import(D->getLocStart()),
2284f4a2713aSLionel Sambuc                                         Loc, Name.getAsIdentifierInfo(),
2285*0a6a1f1dSLionel Sambuc                                         /*PrevDecl=*/nullptr);
2286f4a2713aSLionel Sambuc     ToNamespace->setLexicalDeclContext(LexicalDC);
2287f4a2713aSLionel Sambuc     LexicalDC->addDeclInternal(ToNamespace);
2288f4a2713aSLionel Sambuc 
2289f4a2713aSLionel Sambuc     // If this is an anonymous namespace, register it as the anonymous
2290f4a2713aSLionel Sambuc     // namespace within its context.
2291f4a2713aSLionel Sambuc     if (!Name) {
2292f4a2713aSLionel Sambuc       if (TranslationUnitDecl *TU = dyn_cast<TranslationUnitDecl>(DC))
2293f4a2713aSLionel Sambuc         TU->setAnonymousNamespace(ToNamespace);
2294f4a2713aSLionel Sambuc       else
2295f4a2713aSLionel Sambuc         cast<NamespaceDecl>(DC)->setAnonymousNamespace(ToNamespace);
2296f4a2713aSLionel Sambuc     }
2297f4a2713aSLionel Sambuc   }
2298f4a2713aSLionel Sambuc   Importer.Imported(D, ToNamespace);
2299f4a2713aSLionel Sambuc 
2300f4a2713aSLionel Sambuc   ImportDeclContext(D);
2301f4a2713aSLionel Sambuc 
2302f4a2713aSLionel Sambuc   return ToNamespace;
2303f4a2713aSLionel Sambuc }
2304f4a2713aSLionel Sambuc 
VisitTypedefNameDecl(TypedefNameDecl * D,bool IsAlias)2305f4a2713aSLionel Sambuc Decl *ASTNodeImporter::VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias) {
2306f4a2713aSLionel Sambuc   // Import the major distinguishing characteristics of this typedef.
2307f4a2713aSLionel Sambuc   DeclContext *DC, *LexicalDC;
2308f4a2713aSLionel Sambuc   DeclarationName Name;
2309f4a2713aSLionel Sambuc   SourceLocation Loc;
2310f4a2713aSLionel Sambuc   if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2311*0a6a1f1dSLionel Sambuc     return nullptr;
2312f4a2713aSLionel Sambuc 
2313f4a2713aSLionel Sambuc   // If this typedef is not in block scope, determine whether we've
2314f4a2713aSLionel Sambuc   // seen a typedef with the same name (that we can merge with) or any
2315f4a2713aSLionel Sambuc   // other entity by that name (which name lookup could conflict with).
2316f4a2713aSLionel Sambuc   if (!DC->isFunctionOrMethod()) {
2317f4a2713aSLionel Sambuc     SmallVector<NamedDecl *, 4> ConflictingDecls;
2318f4a2713aSLionel Sambuc     unsigned IDNS = Decl::IDNS_Ordinary;
2319f4a2713aSLionel Sambuc     SmallVector<NamedDecl *, 2> FoundDecls;
2320*0a6a1f1dSLionel Sambuc     DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
2321f4a2713aSLionel Sambuc     for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
2322f4a2713aSLionel Sambuc       if (!FoundDecls[I]->isInIdentifierNamespace(IDNS))
2323f4a2713aSLionel Sambuc         continue;
2324f4a2713aSLionel Sambuc       if (TypedefNameDecl *FoundTypedef =
2325f4a2713aSLionel Sambuc             dyn_cast<TypedefNameDecl>(FoundDecls[I])) {
2326f4a2713aSLionel Sambuc         if (Importer.IsStructurallyEquivalent(D->getUnderlyingType(),
2327f4a2713aSLionel Sambuc                                             FoundTypedef->getUnderlyingType()))
2328f4a2713aSLionel Sambuc           return Importer.Imported(D, FoundTypedef);
2329f4a2713aSLionel Sambuc       }
2330f4a2713aSLionel Sambuc 
2331f4a2713aSLionel Sambuc       ConflictingDecls.push_back(FoundDecls[I]);
2332f4a2713aSLionel Sambuc     }
2333f4a2713aSLionel Sambuc 
2334f4a2713aSLionel Sambuc     if (!ConflictingDecls.empty()) {
2335f4a2713aSLionel Sambuc       Name = Importer.HandleNameConflict(Name, DC, IDNS,
2336f4a2713aSLionel Sambuc                                          ConflictingDecls.data(),
2337f4a2713aSLionel Sambuc                                          ConflictingDecls.size());
2338f4a2713aSLionel Sambuc       if (!Name)
2339*0a6a1f1dSLionel Sambuc         return nullptr;
2340f4a2713aSLionel Sambuc     }
2341f4a2713aSLionel Sambuc   }
2342f4a2713aSLionel Sambuc 
2343f4a2713aSLionel Sambuc   // Import the underlying type of this typedef;
2344f4a2713aSLionel Sambuc   QualType T = Importer.Import(D->getUnderlyingType());
2345f4a2713aSLionel Sambuc   if (T.isNull())
2346*0a6a1f1dSLionel Sambuc     return nullptr;
2347f4a2713aSLionel Sambuc 
2348f4a2713aSLionel Sambuc   // Create the new typedef node.
2349f4a2713aSLionel Sambuc   TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
2350f4a2713aSLionel Sambuc   SourceLocation StartL = Importer.Import(D->getLocStart());
2351f4a2713aSLionel Sambuc   TypedefNameDecl *ToTypedef;
2352f4a2713aSLionel Sambuc   if (IsAlias)
2353f4a2713aSLionel Sambuc     ToTypedef = TypeAliasDecl::Create(Importer.getToContext(), DC,
2354f4a2713aSLionel Sambuc                                       StartL, Loc,
2355f4a2713aSLionel Sambuc                                       Name.getAsIdentifierInfo(),
2356f4a2713aSLionel Sambuc                                       TInfo);
2357f4a2713aSLionel Sambuc   else
2358f4a2713aSLionel Sambuc     ToTypedef = TypedefDecl::Create(Importer.getToContext(), DC,
2359f4a2713aSLionel Sambuc                                     StartL, Loc,
2360f4a2713aSLionel Sambuc                                     Name.getAsIdentifierInfo(),
2361f4a2713aSLionel Sambuc                                     TInfo);
2362f4a2713aSLionel Sambuc 
2363f4a2713aSLionel Sambuc   ToTypedef->setAccess(D->getAccess());
2364f4a2713aSLionel Sambuc   ToTypedef->setLexicalDeclContext(LexicalDC);
2365f4a2713aSLionel Sambuc   Importer.Imported(D, ToTypedef);
2366f4a2713aSLionel Sambuc   LexicalDC->addDeclInternal(ToTypedef);
2367f4a2713aSLionel Sambuc 
2368f4a2713aSLionel Sambuc   return ToTypedef;
2369f4a2713aSLionel Sambuc }
2370f4a2713aSLionel Sambuc 
VisitTypedefDecl(TypedefDecl * D)2371f4a2713aSLionel Sambuc Decl *ASTNodeImporter::VisitTypedefDecl(TypedefDecl *D) {
2372f4a2713aSLionel Sambuc   return VisitTypedefNameDecl(D, /*IsAlias=*/false);
2373f4a2713aSLionel Sambuc }
2374f4a2713aSLionel Sambuc 
VisitTypeAliasDecl(TypeAliasDecl * D)2375f4a2713aSLionel Sambuc Decl *ASTNodeImporter::VisitTypeAliasDecl(TypeAliasDecl *D) {
2376f4a2713aSLionel Sambuc   return VisitTypedefNameDecl(D, /*IsAlias=*/true);
2377f4a2713aSLionel Sambuc }
2378f4a2713aSLionel Sambuc 
VisitEnumDecl(EnumDecl * D)2379f4a2713aSLionel Sambuc Decl *ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
2380f4a2713aSLionel Sambuc   // Import the major distinguishing characteristics of this enum.
2381f4a2713aSLionel Sambuc   DeclContext *DC, *LexicalDC;
2382f4a2713aSLionel Sambuc   DeclarationName Name;
2383f4a2713aSLionel Sambuc   SourceLocation Loc;
2384f4a2713aSLionel Sambuc   if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2385*0a6a1f1dSLionel Sambuc     return nullptr;
2386f4a2713aSLionel Sambuc 
2387f4a2713aSLionel Sambuc   // Figure out what enum name we're looking for.
2388f4a2713aSLionel Sambuc   unsigned IDNS = Decl::IDNS_Tag;
2389f4a2713aSLionel Sambuc   DeclarationName SearchName = Name;
2390f4a2713aSLionel Sambuc   if (!SearchName && D->getTypedefNameForAnonDecl()) {
2391f4a2713aSLionel Sambuc     SearchName = Importer.Import(D->getTypedefNameForAnonDecl()->getDeclName());
2392f4a2713aSLionel Sambuc     IDNS = Decl::IDNS_Ordinary;
2393f4a2713aSLionel Sambuc   } else if (Importer.getToContext().getLangOpts().CPlusPlus)
2394f4a2713aSLionel Sambuc     IDNS |= Decl::IDNS_Ordinary;
2395f4a2713aSLionel Sambuc 
2396f4a2713aSLionel Sambuc   // We may already have an enum of the same name; try to find and match it.
2397f4a2713aSLionel Sambuc   if (!DC->isFunctionOrMethod() && SearchName) {
2398f4a2713aSLionel Sambuc     SmallVector<NamedDecl *, 4> ConflictingDecls;
2399f4a2713aSLionel Sambuc     SmallVector<NamedDecl *, 2> FoundDecls;
2400*0a6a1f1dSLionel Sambuc     DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
2401f4a2713aSLionel Sambuc     for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
2402f4a2713aSLionel Sambuc       if (!FoundDecls[I]->isInIdentifierNamespace(IDNS))
2403f4a2713aSLionel Sambuc         continue;
2404f4a2713aSLionel Sambuc 
2405f4a2713aSLionel Sambuc       Decl *Found = FoundDecls[I];
2406f4a2713aSLionel Sambuc       if (TypedefNameDecl *Typedef = dyn_cast<TypedefNameDecl>(Found)) {
2407f4a2713aSLionel Sambuc         if (const TagType *Tag = Typedef->getUnderlyingType()->getAs<TagType>())
2408f4a2713aSLionel Sambuc           Found = Tag->getDecl();
2409f4a2713aSLionel Sambuc       }
2410f4a2713aSLionel Sambuc 
2411f4a2713aSLionel Sambuc       if (EnumDecl *FoundEnum = dyn_cast<EnumDecl>(Found)) {
2412f4a2713aSLionel Sambuc         if (IsStructuralMatch(D, FoundEnum))
2413f4a2713aSLionel Sambuc           return Importer.Imported(D, FoundEnum);
2414f4a2713aSLionel Sambuc       }
2415f4a2713aSLionel Sambuc 
2416f4a2713aSLionel Sambuc       ConflictingDecls.push_back(FoundDecls[I]);
2417f4a2713aSLionel Sambuc     }
2418f4a2713aSLionel Sambuc 
2419f4a2713aSLionel Sambuc     if (!ConflictingDecls.empty()) {
2420f4a2713aSLionel Sambuc       Name = Importer.HandleNameConflict(Name, DC, IDNS,
2421f4a2713aSLionel Sambuc                                          ConflictingDecls.data(),
2422f4a2713aSLionel Sambuc                                          ConflictingDecls.size());
2423f4a2713aSLionel Sambuc     }
2424f4a2713aSLionel Sambuc   }
2425f4a2713aSLionel Sambuc 
2426f4a2713aSLionel Sambuc   // Create the enum declaration.
2427f4a2713aSLionel Sambuc   EnumDecl *D2 = EnumDecl::Create(Importer.getToContext(), DC,
2428f4a2713aSLionel Sambuc                                   Importer.Import(D->getLocStart()),
2429*0a6a1f1dSLionel Sambuc                                   Loc, Name.getAsIdentifierInfo(), nullptr,
2430f4a2713aSLionel Sambuc                                   D->isScoped(), D->isScopedUsingClassTag(),
2431f4a2713aSLionel Sambuc                                   D->isFixed());
2432f4a2713aSLionel Sambuc   // Import the qualifier, if any.
2433f4a2713aSLionel Sambuc   D2->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
2434f4a2713aSLionel Sambuc   D2->setAccess(D->getAccess());
2435f4a2713aSLionel Sambuc   D2->setLexicalDeclContext(LexicalDC);
2436f4a2713aSLionel Sambuc   Importer.Imported(D, D2);
2437f4a2713aSLionel Sambuc   LexicalDC->addDeclInternal(D2);
2438f4a2713aSLionel Sambuc 
2439f4a2713aSLionel Sambuc   // Import the integer type.
2440f4a2713aSLionel Sambuc   QualType ToIntegerType = Importer.Import(D->getIntegerType());
2441f4a2713aSLionel Sambuc   if (ToIntegerType.isNull())
2442*0a6a1f1dSLionel Sambuc     return nullptr;
2443f4a2713aSLionel Sambuc   D2->setIntegerType(ToIntegerType);
2444f4a2713aSLionel Sambuc 
2445f4a2713aSLionel Sambuc   // Import the definition
2446f4a2713aSLionel Sambuc   if (D->isCompleteDefinition() && ImportDefinition(D, D2))
2447*0a6a1f1dSLionel Sambuc     return nullptr;
2448f4a2713aSLionel Sambuc 
2449f4a2713aSLionel Sambuc   return D2;
2450f4a2713aSLionel Sambuc }
2451f4a2713aSLionel Sambuc 
VisitRecordDecl(RecordDecl * D)2452f4a2713aSLionel Sambuc Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
2453f4a2713aSLionel Sambuc   // If this record has a definition in the translation unit we're coming from,
2454f4a2713aSLionel Sambuc   // but this particular declaration is not that definition, import the
2455f4a2713aSLionel Sambuc   // definition and map to that.
2456f4a2713aSLionel Sambuc   TagDecl *Definition = D->getDefinition();
2457f4a2713aSLionel Sambuc   if (Definition && Definition != D) {
2458f4a2713aSLionel Sambuc     Decl *ImportedDef = Importer.Import(Definition);
2459f4a2713aSLionel Sambuc     if (!ImportedDef)
2460*0a6a1f1dSLionel Sambuc       return nullptr;
2461f4a2713aSLionel Sambuc 
2462f4a2713aSLionel Sambuc     return Importer.Imported(D, ImportedDef);
2463f4a2713aSLionel Sambuc   }
2464f4a2713aSLionel Sambuc 
2465f4a2713aSLionel Sambuc   // Import the major distinguishing characteristics of this record.
2466f4a2713aSLionel Sambuc   DeclContext *DC, *LexicalDC;
2467f4a2713aSLionel Sambuc   DeclarationName Name;
2468f4a2713aSLionel Sambuc   SourceLocation Loc;
2469f4a2713aSLionel Sambuc   if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2470*0a6a1f1dSLionel Sambuc     return nullptr;
2471f4a2713aSLionel Sambuc 
2472f4a2713aSLionel Sambuc   // Figure out what structure name we're looking for.
2473f4a2713aSLionel Sambuc   unsigned IDNS = Decl::IDNS_Tag;
2474f4a2713aSLionel Sambuc   DeclarationName SearchName = Name;
2475f4a2713aSLionel Sambuc   if (!SearchName && D->getTypedefNameForAnonDecl()) {
2476f4a2713aSLionel Sambuc     SearchName = Importer.Import(D->getTypedefNameForAnonDecl()->getDeclName());
2477f4a2713aSLionel Sambuc     IDNS = Decl::IDNS_Ordinary;
2478f4a2713aSLionel Sambuc   } else if (Importer.getToContext().getLangOpts().CPlusPlus)
2479f4a2713aSLionel Sambuc     IDNS |= Decl::IDNS_Ordinary;
2480f4a2713aSLionel Sambuc 
2481f4a2713aSLionel Sambuc   // We may already have a record of the same name; try to find and match it.
2482*0a6a1f1dSLionel Sambuc   RecordDecl *AdoptDecl = nullptr;
2483f4a2713aSLionel Sambuc   if (!DC->isFunctionOrMethod()) {
2484f4a2713aSLionel Sambuc     SmallVector<NamedDecl *, 4> ConflictingDecls;
2485f4a2713aSLionel Sambuc     SmallVector<NamedDecl *, 2> FoundDecls;
2486*0a6a1f1dSLionel Sambuc     DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
2487f4a2713aSLionel Sambuc     for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
2488f4a2713aSLionel Sambuc       if (!FoundDecls[I]->isInIdentifierNamespace(IDNS))
2489f4a2713aSLionel Sambuc         continue;
2490f4a2713aSLionel Sambuc 
2491f4a2713aSLionel Sambuc       Decl *Found = FoundDecls[I];
2492f4a2713aSLionel Sambuc       if (TypedefNameDecl *Typedef = dyn_cast<TypedefNameDecl>(Found)) {
2493f4a2713aSLionel Sambuc         if (const TagType *Tag = Typedef->getUnderlyingType()->getAs<TagType>())
2494f4a2713aSLionel Sambuc           Found = Tag->getDecl();
2495f4a2713aSLionel Sambuc       }
2496f4a2713aSLionel Sambuc 
2497f4a2713aSLionel Sambuc       if (RecordDecl *FoundRecord = dyn_cast<RecordDecl>(Found)) {
2498f4a2713aSLionel Sambuc         if (D->isAnonymousStructOrUnion() &&
2499f4a2713aSLionel Sambuc             FoundRecord->isAnonymousStructOrUnion()) {
2500f4a2713aSLionel Sambuc           // If both anonymous structs/unions are in a record context, make sure
2501f4a2713aSLionel Sambuc           // they occur in the same location in the context records.
2502f4a2713aSLionel Sambuc           if (Optional<unsigned> Index1
2503f4a2713aSLionel Sambuc               = findAnonymousStructOrUnionIndex(D)) {
2504f4a2713aSLionel Sambuc             if (Optional<unsigned> Index2 =
2505f4a2713aSLionel Sambuc                     findAnonymousStructOrUnionIndex(FoundRecord)) {
2506f4a2713aSLionel Sambuc               if (*Index1 != *Index2)
2507f4a2713aSLionel Sambuc                 continue;
2508f4a2713aSLionel Sambuc             }
2509f4a2713aSLionel Sambuc           }
2510f4a2713aSLionel Sambuc         }
2511f4a2713aSLionel Sambuc 
2512f4a2713aSLionel Sambuc         if (RecordDecl *FoundDef = FoundRecord->getDefinition()) {
2513f4a2713aSLionel Sambuc           if ((SearchName && !D->isCompleteDefinition())
2514f4a2713aSLionel Sambuc               || (D->isCompleteDefinition() &&
2515f4a2713aSLionel Sambuc                   D->isAnonymousStructOrUnion()
2516f4a2713aSLionel Sambuc                     == FoundDef->isAnonymousStructOrUnion() &&
2517f4a2713aSLionel Sambuc                   IsStructuralMatch(D, FoundDef))) {
2518f4a2713aSLionel Sambuc             // The record types structurally match, or the "from" translation
2519f4a2713aSLionel Sambuc             // unit only had a forward declaration anyway; call it the same
2520f4a2713aSLionel Sambuc             // function.
2521f4a2713aSLionel Sambuc             // FIXME: For C++, we should also merge methods here.
2522f4a2713aSLionel Sambuc             return Importer.Imported(D, FoundDef);
2523f4a2713aSLionel Sambuc           }
2524f4a2713aSLionel Sambuc         } else if (!D->isCompleteDefinition()) {
2525f4a2713aSLionel Sambuc           // We have a forward declaration of this type, so adopt that forward
2526f4a2713aSLionel Sambuc           // declaration rather than building a new one.
2527*0a6a1f1dSLionel Sambuc 
2528*0a6a1f1dSLionel Sambuc           // If one or both can be completed from external storage then try one
2529*0a6a1f1dSLionel Sambuc           // last time to complete and compare them before doing this.
2530*0a6a1f1dSLionel Sambuc 
2531*0a6a1f1dSLionel Sambuc           if (FoundRecord->hasExternalLexicalStorage() &&
2532*0a6a1f1dSLionel Sambuc               !FoundRecord->isCompleteDefinition())
2533*0a6a1f1dSLionel Sambuc             FoundRecord->getASTContext().getExternalSource()->CompleteType(FoundRecord);
2534*0a6a1f1dSLionel Sambuc           if (D->hasExternalLexicalStorage())
2535*0a6a1f1dSLionel Sambuc             D->getASTContext().getExternalSource()->CompleteType(D);
2536*0a6a1f1dSLionel Sambuc 
2537*0a6a1f1dSLionel Sambuc           if (FoundRecord->isCompleteDefinition() &&
2538*0a6a1f1dSLionel Sambuc               D->isCompleteDefinition() &&
2539*0a6a1f1dSLionel Sambuc               !IsStructuralMatch(D, FoundRecord))
2540*0a6a1f1dSLionel Sambuc             continue;
2541*0a6a1f1dSLionel Sambuc 
2542f4a2713aSLionel Sambuc           AdoptDecl = FoundRecord;
2543f4a2713aSLionel Sambuc           continue;
2544f4a2713aSLionel Sambuc         } else if (!SearchName) {
2545f4a2713aSLionel Sambuc           continue;
2546f4a2713aSLionel Sambuc         }
2547f4a2713aSLionel Sambuc       }
2548f4a2713aSLionel Sambuc 
2549f4a2713aSLionel Sambuc       ConflictingDecls.push_back(FoundDecls[I]);
2550f4a2713aSLionel Sambuc     }
2551f4a2713aSLionel Sambuc 
2552f4a2713aSLionel Sambuc     if (!ConflictingDecls.empty() && SearchName) {
2553f4a2713aSLionel Sambuc       Name = Importer.HandleNameConflict(Name, DC, IDNS,
2554f4a2713aSLionel Sambuc                                          ConflictingDecls.data(),
2555f4a2713aSLionel Sambuc                                          ConflictingDecls.size());
2556f4a2713aSLionel Sambuc     }
2557f4a2713aSLionel Sambuc   }
2558f4a2713aSLionel Sambuc 
2559f4a2713aSLionel Sambuc   // Create the record declaration.
2560f4a2713aSLionel Sambuc   RecordDecl *D2 = AdoptDecl;
2561f4a2713aSLionel Sambuc   SourceLocation StartLoc = Importer.Import(D->getLocStart());
2562f4a2713aSLionel Sambuc   if (!D2) {
2563f4a2713aSLionel Sambuc     if (isa<CXXRecordDecl>(D)) {
2564f4a2713aSLionel Sambuc       CXXRecordDecl *D2CXX = CXXRecordDecl::Create(Importer.getToContext(),
2565f4a2713aSLionel Sambuc                                                    D->getTagKind(),
2566f4a2713aSLionel Sambuc                                                    DC, StartLoc, Loc,
2567f4a2713aSLionel Sambuc                                                    Name.getAsIdentifierInfo());
2568f4a2713aSLionel Sambuc       D2 = D2CXX;
2569f4a2713aSLionel Sambuc       D2->setAccess(D->getAccess());
2570f4a2713aSLionel Sambuc     } else {
2571f4a2713aSLionel Sambuc       D2 = RecordDecl::Create(Importer.getToContext(), D->getTagKind(),
2572f4a2713aSLionel Sambuc                               DC, StartLoc, Loc, Name.getAsIdentifierInfo());
2573f4a2713aSLionel Sambuc     }
2574f4a2713aSLionel Sambuc 
2575f4a2713aSLionel Sambuc     D2->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
2576f4a2713aSLionel Sambuc     D2->setLexicalDeclContext(LexicalDC);
2577f4a2713aSLionel Sambuc     LexicalDC->addDeclInternal(D2);
2578f4a2713aSLionel Sambuc     if (D->isAnonymousStructOrUnion())
2579f4a2713aSLionel Sambuc       D2->setAnonymousStructOrUnion(true);
2580f4a2713aSLionel Sambuc   }
2581f4a2713aSLionel Sambuc 
2582f4a2713aSLionel Sambuc   Importer.Imported(D, D2);
2583f4a2713aSLionel Sambuc 
2584f4a2713aSLionel Sambuc   if (D->isCompleteDefinition() && ImportDefinition(D, D2, IDK_Default))
2585*0a6a1f1dSLionel Sambuc     return nullptr;
2586f4a2713aSLionel Sambuc 
2587f4a2713aSLionel Sambuc   return D2;
2588f4a2713aSLionel Sambuc }
2589f4a2713aSLionel Sambuc 
VisitEnumConstantDecl(EnumConstantDecl * D)2590f4a2713aSLionel Sambuc Decl *ASTNodeImporter::VisitEnumConstantDecl(EnumConstantDecl *D) {
2591f4a2713aSLionel Sambuc   // Import the major distinguishing characteristics of this enumerator.
2592f4a2713aSLionel Sambuc   DeclContext *DC, *LexicalDC;
2593f4a2713aSLionel Sambuc   DeclarationName Name;
2594f4a2713aSLionel Sambuc   SourceLocation Loc;
2595f4a2713aSLionel Sambuc   if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2596*0a6a1f1dSLionel Sambuc     return nullptr;
2597f4a2713aSLionel Sambuc 
2598f4a2713aSLionel Sambuc   QualType T = Importer.Import(D->getType());
2599f4a2713aSLionel Sambuc   if (T.isNull())
2600*0a6a1f1dSLionel Sambuc     return nullptr;
2601f4a2713aSLionel Sambuc 
2602f4a2713aSLionel Sambuc   // Determine whether there are any other declarations with the same name and
2603f4a2713aSLionel Sambuc   // in the same context.
2604f4a2713aSLionel Sambuc   if (!LexicalDC->isFunctionOrMethod()) {
2605f4a2713aSLionel Sambuc     SmallVector<NamedDecl *, 4> ConflictingDecls;
2606f4a2713aSLionel Sambuc     unsigned IDNS = Decl::IDNS_Ordinary;
2607f4a2713aSLionel Sambuc     SmallVector<NamedDecl *, 2> FoundDecls;
2608*0a6a1f1dSLionel Sambuc     DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
2609f4a2713aSLionel Sambuc     for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
2610f4a2713aSLionel Sambuc       if (!FoundDecls[I]->isInIdentifierNamespace(IDNS))
2611f4a2713aSLionel Sambuc         continue;
2612f4a2713aSLionel Sambuc 
2613f4a2713aSLionel Sambuc       if (EnumConstantDecl *FoundEnumConstant
2614f4a2713aSLionel Sambuc             = dyn_cast<EnumConstantDecl>(FoundDecls[I])) {
2615f4a2713aSLionel Sambuc         if (IsStructuralMatch(D, FoundEnumConstant))
2616f4a2713aSLionel Sambuc           return Importer.Imported(D, FoundEnumConstant);
2617f4a2713aSLionel Sambuc       }
2618f4a2713aSLionel Sambuc 
2619f4a2713aSLionel Sambuc       ConflictingDecls.push_back(FoundDecls[I]);
2620f4a2713aSLionel Sambuc     }
2621f4a2713aSLionel Sambuc 
2622f4a2713aSLionel Sambuc     if (!ConflictingDecls.empty()) {
2623f4a2713aSLionel Sambuc       Name = Importer.HandleNameConflict(Name, DC, IDNS,
2624f4a2713aSLionel Sambuc                                          ConflictingDecls.data(),
2625f4a2713aSLionel Sambuc                                          ConflictingDecls.size());
2626f4a2713aSLionel Sambuc       if (!Name)
2627*0a6a1f1dSLionel Sambuc         return nullptr;
2628f4a2713aSLionel Sambuc     }
2629f4a2713aSLionel Sambuc   }
2630f4a2713aSLionel Sambuc 
2631f4a2713aSLionel Sambuc   Expr *Init = Importer.Import(D->getInitExpr());
2632f4a2713aSLionel Sambuc   if (D->getInitExpr() && !Init)
2633*0a6a1f1dSLionel Sambuc     return nullptr;
2634f4a2713aSLionel Sambuc 
2635f4a2713aSLionel Sambuc   EnumConstantDecl *ToEnumerator
2636f4a2713aSLionel Sambuc     = EnumConstantDecl::Create(Importer.getToContext(), cast<EnumDecl>(DC), Loc,
2637f4a2713aSLionel Sambuc                                Name.getAsIdentifierInfo(), T,
2638f4a2713aSLionel Sambuc                                Init, D->getInitVal());
2639f4a2713aSLionel Sambuc   ToEnumerator->setAccess(D->getAccess());
2640f4a2713aSLionel Sambuc   ToEnumerator->setLexicalDeclContext(LexicalDC);
2641f4a2713aSLionel Sambuc   Importer.Imported(D, ToEnumerator);
2642f4a2713aSLionel Sambuc   LexicalDC->addDeclInternal(ToEnumerator);
2643f4a2713aSLionel Sambuc   return ToEnumerator;
2644f4a2713aSLionel Sambuc }
2645f4a2713aSLionel Sambuc 
VisitFunctionDecl(FunctionDecl * D)2646f4a2713aSLionel Sambuc Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
2647f4a2713aSLionel Sambuc   // Import the major distinguishing characteristics of this function.
2648f4a2713aSLionel Sambuc   DeclContext *DC, *LexicalDC;
2649f4a2713aSLionel Sambuc   DeclarationName Name;
2650f4a2713aSLionel Sambuc   SourceLocation Loc;
2651f4a2713aSLionel Sambuc   if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2652*0a6a1f1dSLionel Sambuc     return nullptr;
2653f4a2713aSLionel Sambuc 
2654f4a2713aSLionel Sambuc   // Try to find a function in our own ("to") context with the same name, same
2655f4a2713aSLionel Sambuc   // type, and in the same context as the function we're importing.
2656f4a2713aSLionel Sambuc   if (!LexicalDC->isFunctionOrMethod()) {
2657f4a2713aSLionel Sambuc     SmallVector<NamedDecl *, 4> ConflictingDecls;
2658f4a2713aSLionel Sambuc     unsigned IDNS = Decl::IDNS_Ordinary;
2659f4a2713aSLionel Sambuc     SmallVector<NamedDecl *, 2> FoundDecls;
2660*0a6a1f1dSLionel Sambuc     DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
2661f4a2713aSLionel Sambuc     for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
2662f4a2713aSLionel Sambuc       if (!FoundDecls[I]->isInIdentifierNamespace(IDNS))
2663f4a2713aSLionel Sambuc         continue;
2664f4a2713aSLionel Sambuc 
2665f4a2713aSLionel Sambuc       if (FunctionDecl *FoundFunction = dyn_cast<FunctionDecl>(FoundDecls[I])) {
2666f4a2713aSLionel Sambuc         if (FoundFunction->hasExternalFormalLinkage() &&
2667f4a2713aSLionel Sambuc             D->hasExternalFormalLinkage()) {
2668f4a2713aSLionel Sambuc           if (Importer.IsStructurallyEquivalent(D->getType(),
2669f4a2713aSLionel Sambuc                                                 FoundFunction->getType())) {
2670f4a2713aSLionel Sambuc             // FIXME: Actually try to merge the body and other attributes.
2671f4a2713aSLionel Sambuc             return Importer.Imported(D, FoundFunction);
2672f4a2713aSLionel Sambuc           }
2673f4a2713aSLionel Sambuc 
2674f4a2713aSLionel Sambuc           // FIXME: Check for overloading more carefully, e.g., by boosting
2675f4a2713aSLionel Sambuc           // Sema::IsOverload out to the AST library.
2676f4a2713aSLionel Sambuc 
2677f4a2713aSLionel Sambuc           // Function overloading is okay in C++.
2678f4a2713aSLionel Sambuc           if (Importer.getToContext().getLangOpts().CPlusPlus)
2679f4a2713aSLionel Sambuc             continue;
2680f4a2713aSLionel Sambuc 
2681f4a2713aSLionel Sambuc           // Complain about inconsistent function types.
2682f4a2713aSLionel Sambuc           Importer.ToDiag(Loc, diag::err_odr_function_type_inconsistent)
2683f4a2713aSLionel Sambuc             << Name << D->getType() << FoundFunction->getType();
2684f4a2713aSLionel Sambuc           Importer.ToDiag(FoundFunction->getLocation(),
2685f4a2713aSLionel Sambuc                           diag::note_odr_value_here)
2686f4a2713aSLionel Sambuc             << FoundFunction->getType();
2687f4a2713aSLionel Sambuc         }
2688f4a2713aSLionel Sambuc       }
2689f4a2713aSLionel Sambuc 
2690f4a2713aSLionel Sambuc       ConflictingDecls.push_back(FoundDecls[I]);
2691f4a2713aSLionel Sambuc     }
2692f4a2713aSLionel Sambuc 
2693f4a2713aSLionel Sambuc     if (!ConflictingDecls.empty()) {
2694f4a2713aSLionel Sambuc       Name = Importer.HandleNameConflict(Name, DC, IDNS,
2695f4a2713aSLionel Sambuc                                          ConflictingDecls.data(),
2696f4a2713aSLionel Sambuc                                          ConflictingDecls.size());
2697f4a2713aSLionel Sambuc       if (!Name)
2698*0a6a1f1dSLionel Sambuc         return nullptr;
2699f4a2713aSLionel Sambuc     }
2700f4a2713aSLionel Sambuc   }
2701f4a2713aSLionel Sambuc 
2702f4a2713aSLionel Sambuc   DeclarationNameInfo NameInfo(Name, Loc);
2703f4a2713aSLionel Sambuc   // Import additional name location/type info.
2704f4a2713aSLionel Sambuc   ImportDeclarationNameLoc(D->getNameInfo(), NameInfo);
2705f4a2713aSLionel Sambuc 
2706f4a2713aSLionel Sambuc   QualType FromTy = D->getType();
2707f4a2713aSLionel Sambuc   bool usedDifferentExceptionSpec = false;
2708f4a2713aSLionel Sambuc 
2709f4a2713aSLionel Sambuc   if (const FunctionProtoType *
2710f4a2713aSLionel Sambuc         FromFPT = D->getType()->getAs<FunctionProtoType>()) {
2711f4a2713aSLionel Sambuc     FunctionProtoType::ExtProtoInfo FromEPI = FromFPT->getExtProtoInfo();
2712f4a2713aSLionel Sambuc     // FunctionProtoType::ExtProtoInfo's ExceptionSpecDecl can point to the
2713f4a2713aSLionel Sambuc     // FunctionDecl that we are importing the FunctionProtoType for.
2714f4a2713aSLionel Sambuc     // To avoid an infinite recursion when importing, create the FunctionDecl
2715f4a2713aSLionel Sambuc     // with a simplified function type and update it afterwards.
2716*0a6a1f1dSLionel Sambuc     if (FromEPI.ExceptionSpec.SourceDecl ||
2717*0a6a1f1dSLionel Sambuc         FromEPI.ExceptionSpec.SourceTemplate ||
2718*0a6a1f1dSLionel Sambuc         FromEPI.ExceptionSpec.NoexceptExpr) {
2719f4a2713aSLionel Sambuc       FunctionProtoType::ExtProtoInfo DefaultEPI;
2720f4a2713aSLionel Sambuc       FromTy = Importer.getFromContext().getFunctionType(
2721*0a6a1f1dSLionel Sambuc           FromFPT->getReturnType(), FromFPT->getParamTypes(), DefaultEPI);
2722f4a2713aSLionel Sambuc       usedDifferentExceptionSpec = true;
2723f4a2713aSLionel Sambuc     }
2724f4a2713aSLionel Sambuc   }
2725f4a2713aSLionel Sambuc 
2726f4a2713aSLionel Sambuc   // Import the type.
2727f4a2713aSLionel Sambuc   QualType T = Importer.Import(FromTy);
2728f4a2713aSLionel Sambuc   if (T.isNull())
2729*0a6a1f1dSLionel Sambuc     return nullptr;
2730f4a2713aSLionel Sambuc 
2731f4a2713aSLionel Sambuc   // Import the function parameters.
2732f4a2713aSLionel Sambuc   SmallVector<ParmVarDecl *, 8> Parameters;
2733*0a6a1f1dSLionel Sambuc   for (auto P : D->params()) {
2734*0a6a1f1dSLionel Sambuc     ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(P));
2735f4a2713aSLionel Sambuc     if (!ToP)
2736*0a6a1f1dSLionel Sambuc       return nullptr;
2737f4a2713aSLionel Sambuc 
2738f4a2713aSLionel Sambuc     Parameters.push_back(ToP);
2739f4a2713aSLionel Sambuc   }
2740f4a2713aSLionel Sambuc 
2741f4a2713aSLionel Sambuc   // Create the imported function.
2742f4a2713aSLionel Sambuc   TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
2743*0a6a1f1dSLionel Sambuc   FunctionDecl *ToFunction = nullptr;
2744f4a2713aSLionel Sambuc   if (CXXConstructorDecl *FromConstructor = dyn_cast<CXXConstructorDecl>(D)) {
2745f4a2713aSLionel Sambuc     ToFunction = CXXConstructorDecl::Create(Importer.getToContext(),
2746f4a2713aSLionel Sambuc                                             cast<CXXRecordDecl>(DC),
2747f4a2713aSLionel Sambuc                                             D->getInnerLocStart(),
2748f4a2713aSLionel Sambuc                                             NameInfo, T, TInfo,
2749f4a2713aSLionel Sambuc                                             FromConstructor->isExplicit(),
2750f4a2713aSLionel Sambuc                                             D->isInlineSpecified(),
2751f4a2713aSLionel Sambuc                                             D->isImplicit(),
2752f4a2713aSLionel Sambuc                                             D->isConstexpr());
2753f4a2713aSLionel Sambuc   } else if (isa<CXXDestructorDecl>(D)) {
2754f4a2713aSLionel Sambuc     ToFunction = CXXDestructorDecl::Create(Importer.getToContext(),
2755f4a2713aSLionel Sambuc                                            cast<CXXRecordDecl>(DC),
2756f4a2713aSLionel Sambuc                                            D->getInnerLocStart(),
2757f4a2713aSLionel Sambuc                                            NameInfo, T, TInfo,
2758f4a2713aSLionel Sambuc                                            D->isInlineSpecified(),
2759f4a2713aSLionel Sambuc                                            D->isImplicit());
2760f4a2713aSLionel Sambuc   } else if (CXXConversionDecl *FromConversion
2761f4a2713aSLionel Sambuc                                            = dyn_cast<CXXConversionDecl>(D)) {
2762f4a2713aSLionel Sambuc     ToFunction = CXXConversionDecl::Create(Importer.getToContext(),
2763f4a2713aSLionel Sambuc                                            cast<CXXRecordDecl>(DC),
2764f4a2713aSLionel Sambuc                                            D->getInnerLocStart(),
2765f4a2713aSLionel Sambuc                                            NameInfo, T, TInfo,
2766f4a2713aSLionel Sambuc                                            D->isInlineSpecified(),
2767f4a2713aSLionel Sambuc                                            FromConversion->isExplicit(),
2768f4a2713aSLionel Sambuc                                            D->isConstexpr(),
2769f4a2713aSLionel Sambuc                                            Importer.Import(D->getLocEnd()));
2770f4a2713aSLionel Sambuc   } else if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
2771f4a2713aSLionel Sambuc     ToFunction = CXXMethodDecl::Create(Importer.getToContext(),
2772f4a2713aSLionel Sambuc                                        cast<CXXRecordDecl>(DC),
2773f4a2713aSLionel Sambuc                                        D->getInnerLocStart(),
2774f4a2713aSLionel Sambuc                                        NameInfo, T, TInfo,
2775f4a2713aSLionel Sambuc                                        Method->getStorageClass(),
2776f4a2713aSLionel Sambuc                                        Method->isInlineSpecified(),
2777f4a2713aSLionel Sambuc                                        D->isConstexpr(),
2778f4a2713aSLionel Sambuc                                        Importer.Import(D->getLocEnd()));
2779f4a2713aSLionel Sambuc   } else {
2780f4a2713aSLionel Sambuc     ToFunction = FunctionDecl::Create(Importer.getToContext(), DC,
2781f4a2713aSLionel Sambuc                                       D->getInnerLocStart(),
2782f4a2713aSLionel Sambuc                                       NameInfo, T, TInfo, D->getStorageClass(),
2783f4a2713aSLionel Sambuc                                       D->isInlineSpecified(),
2784f4a2713aSLionel Sambuc                                       D->hasWrittenPrototype(),
2785f4a2713aSLionel Sambuc                                       D->isConstexpr());
2786f4a2713aSLionel Sambuc   }
2787f4a2713aSLionel Sambuc 
2788f4a2713aSLionel Sambuc   // Import the qualifier, if any.
2789f4a2713aSLionel Sambuc   ToFunction->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
2790f4a2713aSLionel Sambuc   ToFunction->setAccess(D->getAccess());
2791f4a2713aSLionel Sambuc   ToFunction->setLexicalDeclContext(LexicalDC);
2792f4a2713aSLionel Sambuc   ToFunction->setVirtualAsWritten(D->isVirtualAsWritten());
2793f4a2713aSLionel Sambuc   ToFunction->setTrivial(D->isTrivial());
2794f4a2713aSLionel Sambuc   ToFunction->setPure(D->isPure());
2795f4a2713aSLionel Sambuc   Importer.Imported(D, ToFunction);
2796f4a2713aSLionel Sambuc 
2797f4a2713aSLionel Sambuc   // Set the parameters.
2798f4a2713aSLionel Sambuc   for (unsigned I = 0, N = Parameters.size(); I != N; ++I) {
2799f4a2713aSLionel Sambuc     Parameters[I]->setOwningFunction(ToFunction);
2800f4a2713aSLionel Sambuc     ToFunction->addDeclInternal(Parameters[I]);
2801f4a2713aSLionel Sambuc   }
2802f4a2713aSLionel Sambuc   ToFunction->setParams(Parameters);
2803f4a2713aSLionel Sambuc 
2804f4a2713aSLionel Sambuc   if (usedDifferentExceptionSpec) {
2805f4a2713aSLionel Sambuc     // Update FunctionProtoType::ExtProtoInfo.
2806f4a2713aSLionel Sambuc     QualType T = Importer.Import(D->getType());
2807f4a2713aSLionel Sambuc     if (T.isNull())
2808*0a6a1f1dSLionel Sambuc       return nullptr;
2809f4a2713aSLionel Sambuc     ToFunction->setType(T);
2810f4a2713aSLionel Sambuc   }
2811f4a2713aSLionel Sambuc 
2812f4a2713aSLionel Sambuc   // FIXME: Other bits to merge?
2813f4a2713aSLionel Sambuc 
2814f4a2713aSLionel Sambuc   // Add this function to the lexical context.
2815f4a2713aSLionel Sambuc   LexicalDC->addDeclInternal(ToFunction);
2816f4a2713aSLionel Sambuc 
2817f4a2713aSLionel Sambuc   return ToFunction;
2818f4a2713aSLionel Sambuc }
2819f4a2713aSLionel Sambuc 
VisitCXXMethodDecl(CXXMethodDecl * D)2820f4a2713aSLionel Sambuc Decl *ASTNodeImporter::VisitCXXMethodDecl(CXXMethodDecl *D) {
2821f4a2713aSLionel Sambuc   return VisitFunctionDecl(D);
2822f4a2713aSLionel Sambuc }
2823f4a2713aSLionel Sambuc 
VisitCXXConstructorDecl(CXXConstructorDecl * D)2824f4a2713aSLionel Sambuc Decl *ASTNodeImporter::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
2825f4a2713aSLionel Sambuc   return VisitCXXMethodDecl(D);
2826f4a2713aSLionel Sambuc }
2827f4a2713aSLionel Sambuc 
VisitCXXDestructorDecl(CXXDestructorDecl * D)2828f4a2713aSLionel Sambuc Decl *ASTNodeImporter::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
2829f4a2713aSLionel Sambuc   return VisitCXXMethodDecl(D);
2830f4a2713aSLionel Sambuc }
2831f4a2713aSLionel Sambuc 
VisitCXXConversionDecl(CXXConversionDecl * D)2832f4a2713aSLionel Sambuc Decl *ASTNodeImporter::VisitCXXConversionDecl(CXXConversionDecl *D) {
2833f4a2713aSLionel Sambuc   return VisitCXXMethodDecl(D);
2834f4a2713aSLionel Sambuc }
2835f4a2713aSLionel Sambuc 
getFieldIndex(Decl * F)2836f4a2713aSLionel Sambuc static unsigned getFieldIndex(Decl *F) {
2837f4a2713aSLionel Sambuc   RecordDecl *Owner = dyn_cast<RecordDecl>(F->getDeclContext());
2838f4a2713aSLionel Sambuc   if (!Owner)
2839f4a2713aSLionel Sambuc     return 0;
2840f4a2713aSLionel Sambuc 
2841f4a2713aSLionel Sambuc   unsigned Index = 1;
2842*0a6a1f1dSLionel Sambuc   for (const auto *D : Owner->noload_decls()) {
2843*0a6a1f1dSLionel Sambuc     if (D == F)
2844f4a2713aSLionel Sambuc       return Index;
2845f4a2713aSLionel Sambuc 
2846f4a2713aSLionel Sambuc     if (isa<FieldDecl>(*D) || isa<IndirectFieldDecl>(*D))
2847f4a2713aSLionel Sambuc       ++Index;
2848f4a2713aSLionel Sambuc   }
2849f4a2713aSLionel Sambuc 
2850f4a2713aSLionel Sambuc   return Index;
2851f4a2713aSLionel Sambuc }
2852f4a2713aSLionel Sambuc 
VisitFieldDecl(FieldDecl * D)2853f4a2713aSLionel Sambuc Decl *ASTNodeImporter::VisitFieldDecl(FieldDecl *D) {
2854f4a2713aSLionel Sambuc   // Import the major distinguishing characteristics of a variable.
2855f4a2713aSLionel Sambuc   DeclContext *DC, *LexicalDC;
2856f4a2713aSLionel Sambuc   DeclarationName Name;
2857f4a2713aSLionel Sambuc   SourceLocation Loc;
2858f4a2713aSLionel Sambuc   if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2859*0a6a1f1dSLionel Sambuc     return nullptr;
2860f4a2713aSLionel Sambuc 
2861f4a2713aSLionel Sambuc   // Determine whether we've already imported this field.
2862f4a2713aSLionel Sambuc   SmallVector<NamedDecl *, 2> FoundDecls;
2863*0a6a1f1dSLionel Sambuc   DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
2864f4a2713aSLionel Sambuc   for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
2865f4a2713aSLionel Sambuc     if (FieldDecl *FoundField = dyn_cast<FieldDecl>(FoundDecls[I])) {
2866f4a2713aSLionel Sambuc       // For anonymous fields, match up by index.
2867f4a2713aSLionel Sambuc       if (!Name && getFieldIndex(D) != getFieldIndex(FoundField))
2868f4a2713aSLionel Sambuc         continue;
2869f4a2713aSLionel Sambuc 
2870f4a2713aSLionel Sambuc       if (Importer.IsStructurallyEquivalent(D->getType(),
2871f4a2713aSLionel Sambuc                                             FoundField->getType())) {
2872f4a2713aSLionel Sambuc         Importer.Imported(D, FoundField);
2873f4a2713aSLionel Sambuc         return FoundField;
2874f4a2713aSLionel Sambuc       }
2875f4a2713aSLionel Sambuc 
2876f4a2713aSLionel Sambuc       Importer.ToDiag(Loc, diag::err_odr_field_type_inconsistent)
2877f4a2713aSLionel Sambuc         << Name << D->getType() << FoundField->getType();
2878f4a2713aSLionel Sambuc       Importer.ToDiag(FoundField->getLocation(), diag::note_odr_value_here)
2879f4a2713aSLionel Sambuc         << FoundField->getType();
2880*0a6a1f1dSLionel Sambuc       return nullptr;
2881f4a2713aSLionel Sambuc     }
2882f4a2713aSLionel Sambuc   }
2883f4a2713aSLionel Sambuc 
2884f4a2713aSLionel Sambuc   // Import the type.
2885f4a2713aSLionel Sambuc   QualType T = Importer.Import(D->getType());
2886f4a2713aSLionel Sambuc   if (T.isNull())
2887*0a6a1f1dSLionel Sambuc     return nullptr;
2888f4a2713aSLionel Sambuc 
2889f4a2713aSLionel Sambuc   TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
2890f4a2713aSLionel Sambuc   Expr *BitWidth = Importer.Import(D->getBitWidth());
2891f4a2713aSLionel Sambuc   if (!BitWidth && D->getBitWidth())
2892*0a6a1f1dSLionel Sambuc     return nullptr;
2893f4a2713aSLionel Sambuc 
2894f4a2713aSLionel Sambuc   FieldDecl *ToField = FieldDecl::Create(Importer.getToContext(), DC,
2895f4a2713aSLionel Sambuc                                          Importer.Import(D->getInnerLocStart()),
2896f4a2713aSLionel Sambuc                                          Loc, Name.getAsIdentifierInfo(),
2897f4a2713aSLionel Sambuc                                          T, TInfo, BitWidth, D->isMutable(),
2898f4a2713aSLionel Sambuc                                          D->getInClassInitStyle());
2899f4a2713aSLionel Sambuc   ToField->setAccess(D->getAccess());
2900f4a2713aSLionel Sambuc   ToField->setLexicalDeclContext(LexicalDC);
2901f4a2713aSLionel Sambuc   if (ToField->hasInClassInitializer())
2902f4a2713aSLionel Sambuc     ToField->setInClassInitializer(D->getInClassInitializer());
2903f4a2713aSLionel Sambuc   ToField->setImplicit(D->isImplicit());
2904f4a2713aSLionel Sambuc   Importer.Imported(D, ToField);
2905f4a2713aSLionel Sambuc   LexicalDC->addDeclInternal(ToField);
2906f4a2713aSLionel Sambuc   return ToField;
2907f4a2713aSLionel Sambuc }
2908f4a2713aSLionel Sambuc 
VisitIndirectFieldDecl(IndirectFieldDecl * D)2909f4a2713aSLionel Sambuc Decl *ASTNodeImporter::VisitIndirectFieldDecl(IndirectFieldDecl *D) {
2910f4a2713aSLionel Sambuc   // Import the major distinguishing characteristics of a variable.
2911f4a2713aSLionel Sambuc   DeclContext *DC, *LexicalDC;
2912f4a2713aSLionel Sambuc   DeclarationName Name;
2913f4a2713aSLionel Sambuc   SourceLocation Loc;
2914f4a2713aSLionel Sambuc   if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2915*0a6a1f1dSLionel Sambuc     return nullptr;
2916f4a2713aSLionel Sambuc 
2917f4a2713aSLionel Sambuc   // Determine whether we've already imported this field.
2918f4a2713aSLionel Sambuc   SmallVector<NamedDecl *, 2> FoundDecls;
2919*0a6a1f1dSLionel Sambuc   DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
2920f4a2713aSLionel Sambuc   for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
2921f4a2713aSLionel Sambuc     if (IndirectFieldDecl *FoundField
2922f4a2713aSLionel Sambuc                                 = dyn_cast<IndirectFieldDecl>(FoundDecls[I])) {
2923f4a2713aSLionel Sambuc       // For anonymous indirect fields, match up by index.
2924f4a2713aSLionel Sambuc       if (!Name && getFieldIndex(D) != getFieldIndex(FoundField))
2925f4a2713aSLionel Sambuc         continue;
2926f4a2713aSLionel Sambuc 
2927f4a2713aSLionel Sambuc       if (Importer.IsStructurallyEquivalent(D->getType(),
2928f4a2713aSLionel Sambuc                                             FoundField->getType(),
2929f4a2713aSLionel Sambuc                                             !Name.isEmpty())) {
2930f4a2713aSLionel Sambuc         Importer.Imported(D, FoundField);
2931f4a2713aSLionel Sambuc         return FoundField;
2932f4a2713aSLionel Sambuc       }
2933f4a2713aSLionel Sambuc 
2934f4a2713aSLionel Sambuc       // If there are more anonymous fields to check, continue.
2935f4a2713aSLionel Sambuc       if (!Name && I < N-1)
2936f4a2713aSLionel Sambuc         continue;
2937f4a2713aSLionel Sambuc 
2938f4a2713aSLionel Sambuc       Importer.ToDiag(Loc, diag::err_odr_field_type_inconsistent)
2939f4a2713aSLionel Sambuc         << Name << D->getType() << FoundField->getType();
2940f4a2713aSLionel Sambuc       Importer.ToDiag(FoundField->getLocation(), diag::note_odr_value_here)
2941f4a2713aSLionel Sambuc         << FoundField->getType();
2942*0a6a1f1dSLionel Sambuc       return nullptr;
2943f4a2713aSLionel Sambuc     }
2944f4a2713aSLionel Sambuc   }
2945f4a2713aSLionel Sambuc 
2946f4a2713aSLionel Sambuc   // Import the type.
2947f4a2713aSLionel Sambuc   QualType T = Importer.Import(D->getType());
2948f4a2713aSLionel Sambuc   if (T.isNull())
2949*0a6a1f1dSLionel Sambuc     return nullptr;
2950f4a2713aSLionel Sambuc 
2951f4a2713aSLionel Sambuc   NamedDecl **NamedChain =
2952f4a2713aSLionel Sambuc     new (Importer.getToContext())NamedDecl*[D->getChainingSize()];
2953f4a2713aSLionel Sambuc 
2954f4a2713aSLionel Sambuc   unsigned i = 0;
2955*0a6a1f1dSLionel Sambuc   for (auto *PI : D->chain()) {
2956*0a6a1f1dSLionel Sambuc     Decl *D = Importer.Import(PI);
2957f4a2713aSLionel Sambuc     if (!D)
2958*0a6a1f1dSLionel Sambuc       return nullptr;
2959f4a2713aSLionel Sambuc     NamedChain[i++] = cast<NamedDecl>(D);
2960f4a2713aSLionel Sambuc   }
2961f4a2713aSLionel Sambuc 
2962f4a2713aSLionel Sambuc   IndirectFieldDecl *ToIndirectField = IndirectFieldDecl::Create(
2963*0a6a1f1dSLionel Sambuc       Importer.getToContext(), DC, Loc, Name.getAsIdentifierInfo(), T,
2964f4a2713aSLionel Sambuc       NamedChain, D->getChainingSize());
2965*0a6a1f1dSLionel Sambuc 
2966*0a6a1f1dSLionel Sambuc   for (const auto *Attr : D->attrs())
2967*0a6a1f1dSLionel Sambuc     ToIndirectField->addAttr(Attr->clone(Importer.getToContext()));
2968*0a6a1f1dSLionel Sambuc 
2969f4a2713aSLionel Sambuc   ToIndirectField->setAccess(D->getAccess());
2970f4a2713aSLionel Sambuc   ToIndirectField->setLexicalDeclContext(LexicalDC);
2971f4a2713aSLionel Sambuc   Importer.Imported(D, ToIndirectField);
2972f4a2713aSLionel Sambuc   LexicalDC->addDeclInternal(ToIndirectField);
2973f4a2713aSLionel Sambuc   return ToIndirectField;
2974f4a2713aSLionel Sambuc }
2975f4a2713aSLionel Sambuc 
VisitObjCIvarDecl(ObjCIvarDecl * D)2976f4a2713aSLionel Sambuc Decl *ASTNodeImporter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
2977f4a2713aSLionel Sambuc   // Import the major distinguishing characteristics of an ivar.
2978f4a2713aSLionel Sambuc   DeclContext *DC, *LexicalDC;
2979f4a2713aSLionel Sambuc   DeclarationName Name;
2980f4a2713aSLionel Sambuc   SourceLocation Loc;
2981f4a2713aSLionel Sambuc   if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2982*0a6a1f1dSLionel Sambuc     return nullptr;
2983f4a2713aSLionel Sambuc 
2984f4a2713aSLionel Sambuc   // Determine whether we've already imported this ivar
2985f4a2713aSLionel Sambuc   SmallVector<NamedDecl *, 2> FoundDecls;
2986*0a6a1f1dSLionel Sambuc   DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
2987f4a2713aSLionel Sambuc   for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
2988f4a2713aSLionel Sambuc     if (ObjCIvarDecl *FoundIvar = dyn_cast<ObjCIvarDecl>(FoundDecls[I])) {
2989f4a2713aSLionel Sambuc       if (Importer.IsStructurallyEquivalent(D->getType(),
2990f4a2713aSLionel Sambuc                                             FoundIvar->getType())) {
2991f4a2713aSLionel Sambuc         Importer.Imported(D, FoundIvar);
2992f4a2713aSLionel Sambuc         return FoundIvar;
2993f4a2713aSLionel Sambuc       }
2994f4a2713aSLionel Sambuc 
2995f4a2713aSLionel Sambuc       Importer.ToDiag(Loc, diag::err_odr_ivar_type_inconsistent)
2996f4a2713aSLionel Sambuc         << Name << D->getType() << FoundIvar->getType();
2997f4a2713aSLionel Sambuc       Importer.ToDiag(FoundIvar->getLocation(), diag::note_odr_value_here)
2998f4a2713aSLionel Sambuc         << FoundIvar->getType();
2999*0a6a1f1dSLionel Sambuc       return nullptr;
3000f4a2713aSLionel Sambuc     }
3001f4a2713aSLionel Sambuc   }
3002f4a2713aSLionel Sambuc 
3003f4a2713aSLionel Sambuc   // Import the type.
3004f4a2713aSLionel Sambuc   QualType T = Importer.Import(D->getType());
3005f4a2713aSLionel Sambuc   if (T.isNull())
3006*0a6a1f1dSLionel Sambuc     return nullptr;
3007f4a2713aSLionel Sambuc 
3008f4a2713aSLionel Sambuc   TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
3009f4a2713aSLionel Sambuc   Expr *BitWidth = Importer.Import(D->getBitWidth());
3010f4a2713aSLionel Sambuc   if (!BitWidth && D->getBitWidth())
3011*0a6a1f1dSLionel Sambuc     return nullptr;
3012f4a2713aSLionel Sambuc 
3013f4a2713aSLionel Sambuc   ObjCIvarDecl *ToIvar = ObjCIvarDecl::Create(Importer.getToContext(),
3014f4a2713aSLionel Sambuc                                               cast<ObjCContainerDecl>(DC),
3015f4a2713aSLionel Sambuc                                        Importer.Import(D->getInnerLocStart()),
3016f4a2713aSLionel Sambuc                                               Loc, Name.getAsIdentifierInfo(),
3017f4a2713aSLionel Sambuc                                               T, TInfo, D->getAccessControl(),
3018*0a6a1f1dSLionel Sambuc                                               BitWidth, D->getSynthesize());
3019f4a2713aSLionel Sambuc   ToIvar->setLexicalDeclContext(LexicalDC);
3020f4a2713aSLionel Sambuc   Importer.Imported(D, ToIvar);
3021f4a2713aSLionel Sambuc   LexicalDC->addDeclInternal(ToIvar);
3022f4a2713aSLionel Sambuc   return ToIvar;
3023f4a2713aSLionel Sambuc 
3024f4a2713aSLionel Sambuc }
3025f4a2713aSLionel Sambuc 
VisitVarDecl(VarDecl * D)3026f4a2713aSLionel Sambuc Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
3027f4a2713aSLionel Sambuc   // Import the major distinguishing characteristics of a variable.
3028f4a2713aSLionel Sambuc   DeclContext *DC, *LexicalDC;
3029f4a2713aSLionel Sambuc   DeclarationName Name;
3030f4a2713aSLionel Sambuc   SourceLocation Loc;
3031f4a2713aSLionel Sambuc   if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
3032*0a6a1f1dSLionel Sambuc     return nullptr;
3033f4a2713aSLionel Sambuc 
3034f4a2713aSLionel Sambuc   // Try to find a variable in our own ("to") context with the same name and
3035f4a2713aSLionel Sambuc   // in the same context as the variable we're importing.
3036f4a2713aSLionel Sambuc   if (D->isFileVarDecl()) {
3037*0a6a1f1dSLionel Sambuc     VarDecl *MergeWithVar = nullptr;
3038f4a2713aSLionel Sambuc     SmallVector<NamedDecl *, 4> ConflictingDecls;
3039f4a2713aSLionel Sambuc     unsigned IDNS = Decl::IDNS_Ordinary;
3040f4a2713aSLionel Sambuc     SmallVector<NamedDecl *, 2> FoundDecls;
3041*0a6a1f1dSLionel Sambuc     DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
3042f4a2713aSLionel Sambuc     for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
3043f4a2713aSLionel Sambuc       if (!FoundDecls[I]->isInIdentifierNamespace(IDNS))
3044f4a2713aSLionel Sambuc         continue;
3045f4a2713aSLionel Sambuc 
3046f4a2713aSLionel Sambuc       if (VarDecl *FoundVar = dyn_cast<VarDecl>(FoundDecls[I])) {
3047f4a2713aSLionel Sambuc         // We have found a variable that we may need to merge with. Check it.
3048f4a2713aSLionel Sambuc         if (FoundVar->hasExternalFormalLinkage() &&
3049f4a2713aSLionel Sambuc             D->hasExternalFormalLinkage()) {
3050f4a2713aSLionel Sambuc           if (Importer.IsStructurallyEquivalent(D->getType(),
3051f4a2713aSLionel Sambuc                                                 FoundVar->getType())) {
3052f4a2713aSLionel Sambuc             MergeWithVar = FoundVar;
3053f4a2713aSLionel Sambuc             break;
3054f4a2713aSLionel Sambuc           }
3055f4a2713aSLionel Sambuc 
3056f4a2713aSLionel Sambuc           const ArrayType *FoundArray
3057f4a2713aSLionel Sambuc             = Importer.getToContext().getAsArrayType(FoundVar->getType());
3058f4a2713aSLionel Sambuc           const ArrayType *TArray
3059f4a2713aSLionel Sambuc             = Importer.getToContext().getAsArrayType(D->getType());
3060f4a2713aSLionel Sambuc           if (FoundArray && TArray) {
3061f4a2713aSLionel Sambuc             if (isa<IncompleteArrayType>(FoundArray) &&
3062f4a2713aSLionel Sambuc                 isa<ConstantArrayType>(TArray)) {
3063f4a2713aSLionel Sambuc               // Import the type.
3064f4a2713aSLionel Sambuc               QualType T = Importer.Import(D->getType());
3065f4a2713aSLionel Sambuc               if (T.isNull())
3066*0a6a1f1dSLionel Sambuc                 return nullptr;
3067f4a2713aSLionel Sambuc 
3068f4a2713aSLionel Sambuc               FoundVar->setType(T);
3069f4a2713aSLionel Sambuc               MergeWithVar = FoundVar;
3070f4a2713aSLionel Sambuc               break;
3071f4a2713aSLionel Sambuc             } else if (isa<IncompleteArrayType>(TArray) &&
3072f4a2713aSLionel Sambuc                        isa<ConstantArrayType>(FoundArray)) {
3073f4a2713aSLionel Sambuc               MergeWithVar = FoundVar;
3074f4a2713aSLionel Sambuc               break;
3075f4a2713aSLionel Sambuc             }
3076f4a2713aSLionel Sambuc           }
3077f4a2713aSLionel Sambuc 
3078f4a2713aSLionel Sambuc           Importer.ToDiag(Loc, diag::err_odr_variable_type_inconsistent)
3079f4a2713aSLionel Sambuc             << Name << D->getType() << FoundVar->getType();
3080f4a2713aSLionel Sambuc           Importer.ToDiag(FoundVar->getLocation(), diag::note_odr_value_here)
3081f4a2713aSLionel Sambuc             << FoundVar->getType();
3082f4a2713aSLionel Sambuc         }
3083f4a2713aSLionel Sambuc       }
3084f4a2713aSLionel Sambuc 
3085f4a2713aSLionel Sambuc       ConflictingDecls.push_back(FoundDecls[I]);
3086f4a2713aSLionel Sambuc     }
3087f4a2713aSLionel Sambuc 
3088f4a2713aSLionel Sambuc     if (MergeWithVar) {
3089f4a2713aSLionel Sambuc       // An equivalent variable with external linkage has been found. Link
3090f4a2713aSLionel Sambuc       // the two declarations, then merge them.
3091f4a2713aSLionel Sambuc       Importer.Imported(D, MergeWithVar);
3092f4a2713aSLionel Sambuc 
3093f4a2713aSLionel Sambuc       if (VarDecl *DDef = D->getDefinition()) {
3094f4a2713aSLionel Sambuc         if (VarDecl *ExistingDef = MergeWithVar->getDefinition()) {
3095f4a2713aSLionel Sambuc           Importer.ToDiag(ExistingDef->getLocation(),
3096f4a2713aSLionel Sambuc                           diag::err_odr_variable_multiple_def)
3097f4a2713aSLionel Sambuc             << Name;
3098f4a2713aSLionel Sambuc           Importer.FromDiag(DDef->getLocation(), diag::note_odr_defined_here);
3099f4a2713aSLionel Sambuc         } else {
3100f4a2713aSLionel Sambuc           Expr *Init = Importer.Import(DDef->getInit());
3101f4a2713aSLionel Sambuc           MergeWithVar->setInit(Init);
3102f4a2713aSLionel Sambuc           if (DDef->isInitKnownICE()) {
3103f4a2713aSLionel Sambuc             EvaluatedStmt *Eval = MergeWithVar->ensureEvaluatedStmt();
3104f4a2713aSLionel Sambuc             Eval->CheckedICE = true;
3105f4a2713aSLionel Sambuc             Eval->IsICE = DDef->isInitICE();
3106f4a2713aSLionel Sambuc           }
3107f4a2713aSLionel Sambuc         }
3108f4a2713aSLionel Sambuc       }
3109f4a2713aSLionel Sambuc 
3110f4a2713aSLionel Sambuc       return MergeWithVar;
3111f4a2713aSLionel Sambuc     }
3112f4a2713aSLionel Sambuc 
3113f4a2713aSLionel Sambuc     if (!ConflictingDecls.empty()) {
3114f4a2713aSLionel Sambuc       Name = Importer.HandleNameConflict(Name, DC, IDNS,
3115f4a2713aSLionel Sambuc                                          ConflictingDecls.data(),
3116f4a2713aSLionel Sambuc                                          ConflictingDecls.size());
3117f4a2713aSLionel Sambuc       if (!Name)
3118*0a6a1f1dSLionel Sambuc         return nullptr;
3119f4a2713aSLionel Sambuc     }
3120f4a2713aSLionel Sambuc   }
3121f4a2713aSLionel Sambuc 
3122f4a2713aSLionel Sambuc   // Import the type.
3123f4a2713aSLionel Sambuc   QualType T = Importer.Import(D->getType());
3124f4a2713aSLionel Sambuc   if (T.isNull())
3125*0a6a1f1dSLionel Sambuc     return nullptr;
3126f4a2713aSLionel Sambuc 
3127f4a2713aSLionel Sambuc   // Create the imported variable.
3128f4a2713aSLionel Sambuc   TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
3129f4a2713aSLionel Sambuc   VarDecl *ToVar = VarDecl::Create(Importer.getToContext(), DC,
3130f4a2713aSLionel Sambuc                                    Importer.Import(D->getInnerLocStart()),
3131f4a2713aSLionel Sambuc                                    Loc, Name.getAsIdentifierInfo(),
3132f4a2713aSLionel Sambuc                                    T, TInfo,
3133f4a2713aSLionel Sambuc                                    D->getStorageClass());
3134f4a2713aSLionel Sambuc   ToVar->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
3135f4a2713aSLionel Sambuc   ToVar->setAccess(D->getAccess());
3136f4a2713aSLionel Sambuc   ToVar->setLexicalDeclContext(LexicalDC);
3137f4a2713aSLionel Sambuc   Importer.Imported(D, ToVar);
3138f4a2713aSLionel Sambuc   LexicalDC->addDeclInternal(ToVar);
3139f4a2713aSLionel Sambuc 
3140f4a2713aSLionel Sambuc   // Merge the initializer.
3141f4a2713aSLionel Sambuc   if (ImportDefinition(D, ToVar))
3142*0a6a1f1dSLionel Sambuc     return nullptr;
3143f4a2713aSLionel Sambuc 
3144f4a2713aSLionel Sambuc   return ToVar;
3145f4a2713aSLionel Sambuc }
3146f4a2713aSLionel Sambuc 
VisitImplicitParamDecl(ImplicitParamDecl * D)3147f4a2713aSLionel Sambuc Decl *ASTNodeImporter::VisitImplicitParamDecl(ImplicitParamDecl *D) {
3148f4a2713aSLionel Sambuc   // Parameters are created in the translation unit's context, then moved
3149f4a2713aSLionel Sambuc   // into the function declaration's context afterward.
3150f4a2713aSLionel Sambuc   DeclContext *DC = Importer.getToContext().getTranslationUnitDecl();
3151f4a2713aSLionel Sambuc 
3152f4a2713aSLionel Sambuc   // Import the name of this declaration.
3153f4a2713aSLionel Sambuc   DeclarationName Name = Importer.Import(D->getDeclName());
3154f4a2713aSLionel Sambuc   if (D->getDeclName() && !Name)
3155*0a6a1f1dSLionel Sambuc     return nullptr;
3156f4a2713aSLionel Sambuc 
3157f4a2713aSLionel Sambuc   // Import the location of this declaration.
3158f4a2713aSLionel Sambuc   SourceLocation Loc = Importer.Import(D->getLocation());
3159f4a2713aSLionel Sambuc 
3160f4a2713aSLionel Sambuc   // Import the parameter's type.
3161f4a2713aSLionel Sambuc   QualType T = Importer.Import(D->getType());
3162f4a2713aSLionel Sambuc   if (T.isNull())
3163*0a6a1f1dSLionel Sambuc     return nullptr;
3164f4a2713aSLionel Sambuc 
3165f4a2713aSLionel Sambuc   // Create the imported parameter.
3166f4a2713aSLionel Sambuc   ImplicitParamDecl *ToParm
3167f4a2713aSLionel Sambuc     = ImplicitParamDecl::Create(Importer.getToContext(), DC,
3168f4a2713aSLionel Sambuc                                 Loc, Name.getAsIdentifierInfo(),
3169f4a2713aSLionel Sambuc                                 T);
3170f4a2713aSLionel Sambuc   return Importer.Imported(D, ToParm);
3171f4a2713aSLionel Sambuc }
3172f4a2713aSLionel Sambuc 
VisitParmVarDecl(ParmVarDecl * D)3173f4a2713aSLionel Sambuc Decl *ASTNodeImporter::VisitParmVarDecl(ParmVarDecl *D) {
3174f4a2713aSLionel Sambuc   // Parameters are created in the translation unit's context, then moved
3175f4a2713aSLionel Sambuc   // into the function declaration's context afterward.
3176f4a2713aSLionel Sambuc   DeclContext *DC = Importer.getToContext().getTranslationUnitDecl();
3177f4a2713aSLionel Sambuc 
3178f4a2713aSLionel Sambuc   // Import the name of this declaration.
3179f4a2713aSLionel Sambuc   DeclarationName Name = Importer.Import(D->getDeclName());
3180f4a2713aSLionel Sambuc   if (D->getDeclName() && !Name)
3181*0a6a1f1dSLionel Sambuc     return nullptr;
3182f4a2713aSLionel Sambuc 
3183f4a2713aSLionel Sambuc   // Import the location of this declaration.
3184f4a2713aSLionel Sambuc   SourceLocation Loc = Importer.Import(D->getLocation());
3185f4a2713aSLionel Sambuc 
3186f4a2713aSLionel Sambuc   // Import the parameter's type.
3187f4a2713aSLionel Sambuc   QualType T = Importer.Import(D->getType());
3188f4a2713aSLionel Sambuc   if (T.isNull())
3189*0a6a1f1dSLionel Sambuc     return nullptr;
3190f4a2713aSLionel Sambuc 
3191f4a2713aSLionel Sambuc   // Create the imported parameter.
3192f4a2713aSLionel Sambuc   TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
3193f4a2713aSLionel Sambuc   ParmVarDecl *ToParm = ParmVarDecl::Create(Importer.getToContext(), DC,
3194f4a2713aSLionel Sambuc                                      Importer.Import(D->getInnerLocStart()),
3195f4a2713aSLionel Sambuc                                             Loc, Name.getAsIdentifierInfo(),
3196f4a2713aSLionel Sambuc                                             T, TInfo, D->getStorageClass(),
3197*0a6a1f1dSLionel Sambuc                                             /*FIXME: Default argument*/nullptr);
3198f4a2713aSLionel Sambuc   ToParm->setHasInheritedDefaultArg(D->hasInheritedDefaultArg());
3199f4a2713aSLionel Sambuc   return Importer.Imported(D, ToParm);
3200f4a2713aSLionel Sambuc }
3201f4a2713aSLionel Sambuc 
VisitObjCMethodDecl(ObjCMethodDecl * D)3202f4a2713aSLionel Sambuc Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
3203f4a2713aSLionel Sambuc   // Import the major distinguishing characteristics of a method.
3204f4a2713aSLionel Sambuc   DeclContext *DC, *LexicalDC;
3205f4a2713aSLionel Sambuc   DeclarationName Name;
3206f4a2713aSLionel Sambuc   SourceLocation Loc;
3207f4a2713aSLionel Sambuc   if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
3208*0a6a1f1dSLionel Sambuc     return nullptr;
3209f4a2713aSLionel Sambuc 
3210f4a2713aSLionel Sambuc   SmallVector<NamedDecl *, 2> FoundDecls;
3211*0a6a1f1dSLionel Sambuc   DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
3212f4a2713aSLionel Sambuc   for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
3213f4a2713aSLionel Sambuc     if (ObjCMethodDecl *FoundMethod = dyn_cast<ObjCMethodDecl>(FoundDecls[I])) {
3214f4a2713aSLionel Sambuc       if (FoundMethod->isInstanceMethod() != D->isInstanceMethod())
3215f4a2713aSLionel Sambuc         continue;
3216f4a2713aSLionel Sambuc 
3217f4a2713aSLionel Sambuc       // Check return types.
3218*0a6a1f1dSLionel Sambuc       if (!Importer.IsStructurallyEquivalent(D->getReturnType(),
3219*0a6a1f1dSLionel Sambuc                                              FoundMethod->getReturnType())) {
3220f4a2713aSLionel Sambuc         Importer.ToDiag(Loc, diag::err_odr_objc_method_result_type_inconsistent)
3221*0a6a1f1dSLionel Sambuc             << D->isInstanceMethod() << Name << D->getReturnType()
3222*0a6a1f1dSLionel Sambuc             << FoundMethod->getReturnType();
3223f4a2713aSLionel Sambuc         Importer.ToDiag(FoundMethod->getLocation(),
3224f4a2713aSLionel Sambuc                         diag::note_odr_objc_method_here)
3225f4a2713aSLionel Sambuc           << D->isInstanceMethod() << Name;
3226*0a6a1f1dSLionel Sambuc         return nullptr;
3227f4a2713aSLionel Sambuc       }
3228f4a2713aSLionel Sambuc 
3229f4a2713aSLionel Sambuc       // Check the number of parameters.
3230f4a2713aSLionel Sambuc       if (D->param_size() != FoundMethod->param_size()) {
3231f4a2713aSLionel Sambuc         Importer.ToDiag(Loc, diag::err_odr_objc_method_num_params_inconsistent)
3232f4a2713aSLionel Sambuc           << D->isInstanceMethod() << Name
3233f4a2713aSLionel Sambuc           << D->param_size() << FoundMethod->param_size();
3234f4a2713aSLionel Sambuc         Importer.ToDiag(FoundMethod->getLocation(),
3235f4a2713aSLionel Sambuc                         diag::note_odr_objc_method_here)
3236f4a2713aSLionel Sambuc           << D->isInstanceMethod() << Name;
3237*0a6a1f1dSLionel Sambuc         return nullptr;
3238f4a2713aSLionel Sambuc       }
3239f4a2713aSLionel Sambuc 
3240f4a2713aSLionel Sambuc       // Check parameter types.
3241f4a2713aSLionel Sambuc       for (ObjCMethodDecl::param_iterator P = D->param_begin(),
3242f4a2713aSLionel Sambuc              PEnd = D->param_end(), FoundP = FoundMethod->param_begin();
3243f4a2713aSLionel Sambuc            P != PEnd; ++P, ++FoundP) {
3244f4a2713aSLionel Sambuc         if (!Importer.IsStructurallyEquivalent((*P)->getType(),
3245f4a2713aSLionel Sambuc                                                (*FoundP)->getType())) {
3246f4a2713aSLionel Sambuc           Importer.FromDiag((*P)->getLocation(),
3247f4a2713aSLionel Sambuc                             diag::err_odr_objc_method_param_type_inconsistent)
3248f4a2713aSLionel Sambuc             << D->isInstanceMethod() << Name
3249f4a2713aSLionel Sambuc             << (*P)->getType() << (*FoundP)->getType();
3250f4a2713aSLionel Sambuc           Importer.ToDiag((*FoundP)->getLocation(), diag::note_odr_value_here)
3251f4a2713aSLionel Sambuc             << (*FoundP)->getType();
3252*0a6a1f1dSLionel Sambuc           return nullptr;
3253f4a2713aSLionel Sambuc         }
3254f4a2713aSLionel Sambuc       }
3255f4a2713aSLionel Sambuc 
3256f4a2713aSLionel Sambuc       // Check variadic/non-variadic.
3257f4a2713aSLionel Sambuc       // Check the number of parameters.
3258f4a2713aSLionel Sambuc       if (D->isVariadic() != FoundMethod->isVariadic()) {
3259f4a2713aSLionel Sambuc         Importer.ToDiag(Loc, diag::err_odr_objc_method_variadic_inconsistent)
3260f4a2713aSLionel Sambuc           << D->isInstanceMethod() << Name;
3261f4a2713aSLionel Sambuc         Importer.ToDiag(FoundMethod->getLocation(),
3262f4a2713aSLionel Sambuc                         diag::note_odr_objc_method_here)
3263f4a2713aSLionel Sambuc           << D->isInstanceMethod() << Name;
3264*0a6a1f1dSLionel Sambuc         return nullptr;
3265f4a2713aSLionel Sambuc       }
3266f4a2713aSLionel Sambuc 
3267f4a2713aSLionel Sambuc       // FIXME: Any other bits we need to merge?
3268f4a2713aSLionel Sambuc       return Importer.Imported(D, FoundMethod);
3269f4a2713aSLionel Sambuc     }
3270f4a2713aSLionel Sambuc   }
3271f4a2713aSLionel Sambuc 
3272f4a2713aSLionel Sambuc   // Import the result type.
3273*0a6a1f1dSLionel Sambuc   QualType ResultTy = Importer.Import(D->getReturnType());
3274f4a2713aSLionel Sambuc   if (ResultTy.isNull())
3275*0a6a1f1dSLionel Sambuc     return nullptr;
3276f4a2713aSLionel Sambuc 
3277*0a6a1f1dSLionel Sambuc   TypeSourceInfo *ReturnTInfo = Importer.Import(D->getReturnTypeSourceInfo());
3278f4a2713aSLionel Sambuc 
3279*0a6a1f1dSLionel Sambuc   ObjCMethodDecl *ToMethod = ObjCMethodDecl::Create(
3280*0a6a1f1dSLionel Sambuc       Importer.getToContext(), Loc, Importer.Import(D->getLocEnd()),
3281*0a6a1f1dSLionel Sambuc       Name.getObjCSelector(), ResultTy, ReturnTInfo, DC, D->isInstanceMethod(),
3282*0a6a1f1dSLionel Sambuc       D->isVariadic(), D->isPropertyAccessor(), D->isImplicit(), D->isDefined(),
3283*0a6a1f1dSLionel Sambuc       D->getImplementationControl(), D->hasRelatedResultType());
3284f4a2713aSLionel Sambuc 
3285f4a2713aSLionel Sambuc   // FIXME: When we decide to merge method definitions, we'll need to
3286f4a2713aSLionel Sambuc   // deal with implicit parameters.
3287f4a2713aSLionel Sambuc 
3288f4a2713aSLionel Sambuc   // Import the parameters
3289f4a2713aSLionel Sambuc   SmallVector<ParmVarDecl *, 5> ToParams;
3290*0a6a1f1dSLionel Sambuc   for (auto *FromP : D->params()) {
3291*0a6a1f1dSLionel Sambuc     ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(FromP));
3292f4a2713aSLionel Sambuc     if (!ToP)
3293*0a6a1f1dSLionel Sambuc       return nullptr;
3294f4a2713aSLionel Sambuc 
3295f4a2713aSLionel Sambuc     ToParams.push_back(ToP);
3296f4a2713aSLionel Sambuc   }
3297f4a2713aSLionel Sambuc 
3298f4a2713aSLionel Sambuc   // Set the parameters.
3299f4a2713aSLionel Sambuc   for (unsigned I = 0, N = ToParams.size(); I != N; ++I) {
3300f4a2713aSLionel Sambuc     ToParams[I]->setOwningFunction(ToMethod);
3301f4a2713aSLionel Sambuc     ToMethod->addDeclInternal(ToParams[I]);
3302f4a2713aSLionel Sambuc   }
3303f4a2713aSLionel Sambuc   SmallVector<SourceLocation, 12> SelLocs;
3304f4a2713aSLionel Sambuc   D->getSelectorLocs(SelLocs);
3305f4a2713aSLionel Sambuc   ToMethod->setMethodParams(Importer.getToContext(), ToParams, SelLocs);
3306f4a2713aSLionel Sambuc 
3307f4a2713aSLionel Sambuc   ToMethod->setLexicalDeclContext(LexicalDC);
3308f4a2713aSLionel Sambuc   Importer.Imported(D, ToMethod);
3309f4a2713aSLionel Sambuc   LexicalDC->addDeclInternal(ToMethod);
3310f4a2713aSLionel Sambuc   return ToMethod;
3311f4a2713aSLionel Sambuc }
3312f4a2713aSLionel Sambuc 
VisitObjCCategoryDecl(ObjCCategoryDecl * D)3313f4a2713aSLionel Sambuc Decl *ASTNodeImporter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
3314f4a2713aSLionel Sambuc   // Import the major distinguishing characteristics of a category.
3315f4a2713aSLionel Sambuc   DeclContext *DC, *LexicalDC;
3316f4a2713aSLionel Sambuc   DeclarationName Name;
3317f4a2713aSLionel Sambuc   SourceLocation Loc;
3318f4a2713aSLionel Sambuc   if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
3319*0a6a1f1dSLionel Sambuc     return nullptr;
3320f4a2713aSLionel Sambuc 
3321f4a2713aSLionel Sambuc   ObjCInterfaceDecl *ToInterface
3322f4a2713aSLionel Sambuc     = cast_or_null<ObjCInterfaceDecl>(Importer.Import(D->getClassInterface()));
3323f4a2713aSLionel Sambuc   if (!ToInterface)
3324*0a6a1f1dSLionel Sambuc     return nullptr;
3325f4a2713aSLionel Sambuc 
3326f4a2713aSLionel Sambuc   // Determine if we've already encountered this category.
3327f4a2713aSLionel Sambuc   ObjCCategoryDecl *MergeWithCategory
3328f4a2713aSLionel Sambuc     = ToInterface->FindCategoryDeclaration(Name.getAsIdentifierInfo());
3329f4a2713aSLionel Sambuc   ObjCCategoryDecl *ToCategory = MergeWithCategory;
3330f4a2713aSLionel Sambuc   if (!ToCategory) {
3331f4a2713aSLionel Sambuc     ToCategory = ObjCCategoryDecl::Create(Importer.getToContext(), DC,
3332f4a2713aSLionel Sambuc                                           Importer.Import(D->getAtStartLoc()),
3333f4a2713aSLionel Sambuc                                           Loc,
3334f4a2713aSLionel Sambuc                                        Importer.Import(D->getCategoryNameLoc()),
3335f4a2713aSLionel Sambuc                                           Name.getAsIdentifierInfo(),
3336f4a2713aSLionel Sambuc                                           ToInterface,
3337f4a2713aSLionel Sambuc                                        Importer.Import(D->getIvarLBraceLoc()),
3338f4a2713aSLionel Sambuc                                        Importer.Import(D->getIvarRBraceLoc()));
3339f4a2713aSLionel Sambuc     ToCategory->setLexicalDeclContext(LexicalDC);
3340f4a2713aSLionel Sambuc     LexicalDC->addDeclInternal(ToCategory);
3341f4a2713aSLionel Sambuc     Importer.Imported(D, ToCategory);
3342f4a2713aSLionel Sambuc 
3343f4a2713aSLionel Sambuc     // Import protocols
3344f4a2713aSLionel Sambuc     SmallVector<ObjCProtocolDecl *, 4> Protocols;
3345f4a2713aSLionel Sambuc     SmallVector<SourceLocation, 4> ProtocolLocs;
3346f4a2713aSLionel Sambuc     ObjCCategoryDecl::protocol_loc_iterator FromProtoLoc
3347f4a2713aSLionel Sambuc       = D->protocol_loc_begin();
3348f4a2713aSLionel Sambuc     for (ObjCCategoryDecl::protocol_iterator FromProto = D->protocol_begin(),
3349f4a2713aSLionel Sambuc                                           FromProtoEnd = D->protocol_end();
3350f4a2713aSLionel Sambuc          FromProto != FromProtoEnd;
3351f4a2713aSLionel Sambuc          ++FromProto, ++FromProtoLoc) {
3352f4a2713aSLionel Sambuc       ObjCProtocolDecl *ToProto
3353f4a2713aSLionel Sambuc         = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
3354f4a2713aSLionel Sambuc       if (!ToProto)
3355*0a6a1f1dSLionel Sambuc         return nullptr;
3356f4a2713aSLionel Sambuc       Protocols.push_back(ToProto);
3357f4a2713aSLionel Sambuc       ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
3358f4a2713aSLionel Sambuc     }
3359f4a2713aSLionel Sambuc 
3360f4a2713aSLionel Sambuc     // FIXME: If we're merging, make sure that the protocol list is the same.
3361f4a2713aSLionel Sambuc     ToCategory->setProtocolList(Protocols.data(), Protocols.size(),
3362f4a2713aSLionel Sambuc                                 ProtocolLocs.data(), Importer.getToContext());
3363f4a2713aSLionel Sambuc 
3364f4a2713aSLionel Sambuc   } else {
3365f4a2713aSLionel Sambuc     Importer.Imported(D, ToCategory);
3366f4a2713aSLionel Sambuc   }
3367f4a2713aSLionel Sambuc 
3368f4a2713aSLionel Sambuc   // Import all of the members of this category.
3369f4a2713aSLionel Sambuc   ImportDeclContext(D);
3370f4a2713aSLionel Sambuc 
3371f4a2713aSLionel Sambuc   // If we have an implementation, import it as well.
3372f4a2713aSLionel Sambuc   if (D->getImplementation()) {
3373f4a2713aSLionel Sambuc     ObjCCategoryImplDecl *Impl
3374f4a2713aSLionel Sambuc       = cast_or_null<ObjCCategoryImplDecl>(
3375f4a2713aSLionel Sambuc                                        Importer.Import(D->getImplementation()));
3376f4a2713aSLionel Sambuc     if (!Impl)
3377*0a6a1f1dSLionel Sambuc       return nullptr;
3378f4a2713aSLionel Sambuc 
3379f4a2713aSLionel Sambuc     ToCategory->setImplementation(Impl);
3380f4a2713aSLionel Sambuc   }
3381f4a2713aSLionel Sambuc 
3382f4a2713aSLionel Sambuc   return ToCategory;
3383f4a2713aSLionel Sambuc }
3384f4a2713aSLionel Sambuc 
ImportDefinition(ObjCProtocolDecl * From,ObjCProtocolDecl * To,ImportDefinitionKind Kind)3385f4a2713aSLionel Sambuc bool ASTNodeImporter::ImportDefinition(ObjCProtocolDecl *From,
3386f4a2713aSLionel Sambuc                                        ObjCProtocolDecl *To,
3387f4a2713aSLionel Sambuc                                        ImportDefinitionKind Kind) {
3388f4a2713aSLionel Sambuc   if (To->getDefinition()) {
3389f4a2713aSLionel Sambuc     if (shouldForceImportDeclContext(Kind))
3390f4a2713aSLionel Sambuc       ImportDeclContext(From);
3391f4a2713aSLionel Sambuc     return false;
3392f4a2713aSLionel Sambuc   }
3393f4a2713aSLionel Sambuc 
3394f4a2713aSLionel Sambuc   // Start the protocol definition
3395f4a2713aSLionel Sambuc   To->startDefinition();
3396f4a2713aSLionel Sambuc 
3397f4a2713aSLionel Sambuc   // Import protocols
3398f4a2713aSLionel Sambuc   SmallVector<ObjCProtocolDecl *, 4> Protocols;
3399f4a2713aSLionel Sambuc   SmallVector<SourceLocation, 4> ProtocolLocs;
3400f4a2713aSLionel Sambuc   ObjCProtocolDecl::protocol_loc_iterator
3401f4a2713aSLionel Sambuc   FromProtoLoc = From->protocol_loc_begin();
3402f4a2713aSLionel Sambuc   for (ObjCProtocolDecl::protocol_iterator FromProto = From->protocol_begin(),
3403f4a2713aSLionel Sambuc                                         FromProtoEnd = From->protocol_end();
3404f4a2713aSLionel Sambuc        FromProto != FromProtoEnd;
3405f4a2713aSLionel Sambuc        ++FromProto, ++FromProtoLoc) {
3406f4a2713aSLionel Sambuc     ObjCProtocolDecl *ToProto
3407f4a2713aSLionel Sambuc       = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
3408f4a2713aSLionel Sambuc     if (!ToProto)
3409f4a2713aSLionel Sambuc       return true;
3410f4a2713aSLionel Sambuc     Protocols.push_back(ToProto);
3411f4a2713aSLionel Sambuc     ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
3412f4a2713aSLionel Sambuc   }
3413f4a2713aSLionel Sambuc 
3414f4a2713aSLionel Sambuc   // FIXME: If we're merging, make sure that the protocol list is the same.
3415f4a2713aSLionel Sambuc   To->setProtocolList(Protocols.data(), Protocols.size(),
3416f4a2713aSLionel Sambuc                       ProtocolLocs.data(), Importer.getToContext());
3417f4a2713aSLionel Sambuc 
3418f4a2713aSLionel Sambuc   if (shouldForceImportDeclContext(Kind)) {
3419f4a2713aSLionel Sambuc     // Import all of the members of this protocol.
3420f4a2713aSLionel Sambuc     ImportDeclContext(From, /*ForceImport=*/true);
3421f4a2713aSLionel Sambuc   }
3422f4a2713aSLionel Sambuc   return false;
3423f4a2713aSLionel Sambuc }
3424f4a2713aSLionel Sambuc 
VisitObjCProtocolDecl(ObjCProtocolDecl * D)3425f4a2713aSLionel Sambuc Decl *ASTNodeImporter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
3426f4a2713aSLionel Sambuc   // If this protocol has a definition in the translation unit we're coming
3427f4a2713aSLionel Sambuc   // from, but this particular declaration is not that definition, import the
3428f4a2713aSLionel Sambuc   // definition and map to that.
3429f4a2713aSLionel Sambuc   ObjCProtocolDecl *Definition = D->getDefinition();
3430f4a2713aSLionel Sambuc   if (Definition && Definition != D) {
3431f4a2713aSLionel Sambuc     Decl *ImportedDef = Importer.Import(Definition);
3432f4a2713aSLionel Sambuc     if (!ImportedDef)
3433*0a6a1f1dSLionel Sambuc       return nullptr;
3434f4a2713aSLionel Sambuc 
3435f4a2713aSLionel Sambuc     return Importer.Imported(D, ImportedDef);
3436f4a2713aSLionel Sambuc   }
3437f4a2713aSLionel Sambuc 
3438f4a2713aSLionel Sambuc   // Import the major distinguishing characteristics of a protocol.
3439f4a2713aSLionel Sambuc   DeclContext *DC, *LexicalDC;
3440f4a2713aSLionel Sambuc   DeclarationName Name;
3441f4a2713aSLionel Sambuc   SourceLocation Loc;
3442f4a2713aSLionel Sambuc   if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
3443*0a6a1f1dSLionel Sambuc     return nullptr;
3444f4a2713aSLionel Sambuc 
3445*0a6a1f1dSLionel Sambuc   ObjCProtocolDecl *MergeWithProtocol = nullptr;
3446f4a2713aSLionel Sambuc   SmallVector<NamedDecl *, 2> FoundDecls;
3447*0a6a1f1dSLionel Sambuc   DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
3448f4a2713aSLionel Sambuc   for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
3449f4a2713aSLionel Sambuc     if (!FoundDecls[I]->isInIdentifierNamespace(Decl::IDNS_ObjCProtocol))
3450f4a2713aSLionel Sambuc       continue;
3451f4a2713aSLionel Sambuc 
3452f4a2713aSLionel Sambuc     if ((MergeWithProtocol = dyn_cast<ObjCProtocolDecl>(FoundDecls[I])))
3453f4a2713aSLionel Sambuc       break;
3454f4a2713aSLionel Sambuc   }
3455f4a2713aSLionel Sambuc 
3456f4a2713aSLionel Sambuc   ObjCProtocolDecl *ToProto = MergeWithProtocol;
3457f4a2713aSLionel Sambuc   if (!ToProto) {
3458f4a2713aSLionel Sambuc     ToProto = ObjCProtocolDecl::Create(Importer.getToContext(), DC,
3459f4a2713aSLionel Sambuc                                        Name.getAsIdentifierInfo(), Loc,
3460f4a2713aSLionel Sambuc                                        Importer.Import(D->getAtStartLoc()),
3461*0a6a1f1dSLionel Sambuc                                        /*PrevDecl=*/nullptr);
3462f4a2713aSLionel Sambuc     ToProto->setLexicalDeclContext(LexicalDC);
3463f4a2713aSLionel Sambuc     LexicalDC->addDeclInternal(ToProto);
3464f4a2713aSLionel Sambuc   }
3465f4a2713aSLionel Sambuc 
3466f4a2713aSLionel Sambuc   Importer.Imported(D, ToProto);
3467f4a2713aSLionel Sambuc 
3468f4a2713aSLionel Sambuc   if (D->isThisDeclarationADefinition() && ImportDefinition(D, ToProto))
3469*0a6a1f1dSLionel Sambuc     return nullptr;
3470f4a2713aSLionel Sambuc 
3471f4a2713aSLionel Sambuc   return ToProto;
3472f4a2713aSLionel Sambuc }
3473f4a2713aSLionel Sambuc 
VisitLinkageSpecDecl(LinkageSpecDecl * D)3474*0a6a1f1dSLionel Sambuc Decl *ASTNodeImporter::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
3475*0a6a1f1dSLionel Sambuc   DeclContext *DC = Importer.ImportContext(D->getDeclContext());
3476*0a6a1f1dSLionel Sambuc   DeclContext *LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
3477*0a6a1f1dSLionel Sambuc 
3478*0a6a1f1dSLionel Sambuc   SourceLocation ExternLoc = Importer.Import(D->getExternLoc());
3479*0a6a1f1dSLionel Sambuc   SourceLocation LangLoc = Importer.Import(D->getLocation());
3480*0a6a1f1dSLionel Sambuc 
3481*0a6a1f1dSLionel Sambuc   bool HasBraces = D->hasBraces();
3482*0a6a1f1dSLionel Sambuc 
3483*0a6a1f1dSLionel Sambuc   LinkageSpecDecl *ToLinkageSpec =
3484*0a6a1f1dSLionel Sambuc     LinkageSpecDecl::Create(Importer.getToContext(),
3485*0a6a1f1dSLionel Sambuc                             DC,
3486*0a6a1f1dSLionel Sambuc                             ExternLoc,
3487*0a6a1f1dSLionel Sambuc                             LangLoc,
3488*0a6a1f1dSLionel Sambuc                             D->getLanguage(),
3489*0a6a1f1dSLionel Sambuc                             HasBraces);
3490*0a6a1f1dSLionel Sambuc 
3491*0a6a1f1dSLionel Sambuc   if (HasBraces) {
3492*0a6a1f1dSLionel Sambuc     SourceLocation RBraceLoc = Importer.Import(D->getRBraceLoc());
3493*0a6a1f1dSLionel Sambuc     ToLinkageSpec->setRBraceLoc(RBraceLoc);
3494*0a6a1f1dSLionel Sambuc   }
3495*0a6a1f1dSLionel Sambuc 
3496*0a6a1f1dSLionel Sambuc   ToLinkageSpec->setLexicalDeclContext(LexicalDC);
3497*0a6a1f1dSLionel Sambuc   LexicalDC->addDeclInternal(ToLinkageSpec);
3498*0a6a1f1dSLionel Sambuc 
3499*0a6a1f1dSLionel Sambuc   Importer.Imported(D, ToLinkageSpec);
3500*0a6a1f1dSLionel Sambuc 
3501*0a6a1f1dSLionel Sambuc   return ToLinkageSpec;
3502*0a6a1f1dSLionel Sambuc }
3503*0a6a1f1dSLionel Sambuc 
ImportDefinition(ObjCInterfaceDecl * From,ObjCInterfaceDecl * To,ImportDefinitionKind Kind)3504f4a2713aSLionel Sambuc bool ASTNodeImporter::ImportDefinition(ObjCInterfaceDecl *From,
3505f4a2713aSLionel Sambuc                                        ObjCInterfaceDecl *To,
3506f4a2713aSLionel Sambuc                                        ImportDefinitionKind Kind) {
3507f4a2713aSLionel Sambuc   if (To->getDefinition()) {
3508f4a2713aSLionel Sambuc     // Check consistency of superclass.
3509f4a2713aSLionel Sambuc     ObjCInterfaceDecl *FromSuper = From->getSuperClass();
3510f4a2713aSLionel Sambuc     if (FromSuper) {
3511f4a2713aSLionel Sambuc       FromSuper = cast_or_null<ObjCInterfaceDecl>(Importer.Import(FromSuper));
3512f4a2713aSLionel Sambuc       if (!FromSuper)
3513f4a2713aSLionel Sambuc         return true;
3514f4a2713aSLionel Sambuc     }
3515f4a2713aSLionel Sambuc 
3516f4a2713aSLionel Sambuc     ObjCInterfaceDecl *ToSuper = To->getSuperClass();
3517f4a2713aSLionel Sambuc     if ((bool)FromSuper != (bool)ToSuper ||
3518f4a2713aSLionel Sambuc         (FromSuper && !declaresSameEntity(FromSuper, ToSuper))) {
3519f4a2713aSLionel Sambuc       Importer.ToDiag(To->getLocation(),
3520f4a2713aSLionel Sambuc                       diag::err_odr_objc_superclass_inconsistent)
3521f4a2713aSLionel Sambuc         << To->getDeclName();
3522f4a2713aSLionel Sambuc       if (ToSuper)
3523f4a2713aSLionel Sambuc         Importer.ToDiag(To->getSuperClassLoc(), diag::note_odr_objc_superclass)
3524f4a2713aSLionel Sambuc           << To->getSuperClass()->getDeclName();
3525f4a2713aSLionel Sambuc       else
3526f4a2713aSLionel Sambuc         Importer.ToDiag(To->getLocation(),
3527f4a2713aSLionel Sambuc                         diag::note_odr_objc_missing_superclass);
3528f4a2713aSLionel Sambuc       if (From->getSuperClass())
3529f4a2713aSLionel Sambuc         Importer.FromDiag(From->getSuperClassLoc(),
3530f4a2713aSLionel Sambuc                           diag::note_odr_objc_superclass)
3531f4a2713aSLionel Sambuc         << From->getSuperClass()->getDeclName();
3532f4a2713aSLionel Sambuc       else
3533f4a2713aSLionel Sambuc         Importer.FromDiag(From->getLocation(),
3534f4a2713aSLionel Sambuc                           diag::note_odr_objc_missing_superclass);
3535f4a2713aSLionel Sambuc     }
3536f4a2713aSLionel Sambuc 
3537f4a2713aSLionel Sambuc     if (shouldForceImportDeclContext(Kind))
3538f4a2713aSLionel Sambuc       ImportDeclContext(From);
3539f4a2713aSLionel Sambuc     return false;
3540f4a2713aSLionel Sambuc   }
3541f4a2713aSLionel Sambuc 
3542f4a2713aSLionel Sambuc   // Start the definition.
3543f4a2713aSLionel Sambuc   To->startDefinition();
3544f4a2713aSLionel Sambuc 
3545f4a2713aSLionel Sambuc   // If this class has a superclass, import it.
3546f4a2713aSLionel Sambuc   if (From->getSuperClass()) {
3547f4a2713aSLionel Sambuc     ObjCInterfaceDecl *Super = cast_or_null<ObjCInterfaceDecl>(
3548f4a2713aSLionel Sambuc                                  Importer.Import(From->getSuperClass()));
3549f4a2713aSLionel Sambuc     if (!Super)
3550f4a2713aSLionel Sambuc       return true;
3551f4a2713aSLionel Sambuc 
3552f4a2713aSLionel Sambuc     To->setSuperClass(Super);
3553f4a2713aSLionel Sambuc     To->setSuperClassLoc(Importer.Import(From->getSuperClassLoc()));
3554f4a2713aSLionel Sambuc   }
3555f4a2713aSLionel Sambuc 
3556f4a2713aSLionel Sambuc   // Import protocols
3557f4a2713aSLionel Sambuc   SmallVector<ObjCProtocolDecl *, 4> Protocols;
3558f4a2713aSLionel Sambuc   SmallVector<SourceLocation, 4> ProtocolLocs;
3559f4a2713aSLionel Sambuc   ObjCInterfaceDecl::protocol_loc_iterator
3560f4a2713aSLionel Sambuc   FromProtoLoc = From->protocol_loc_begin();
3561f4a2713aSLionel Sambuc 
3562f4a2713aSLionel Sambuc   for (ObjCInterfaceDecl::protocol_iterator FromProto = From->protocol_begin(),
3563f4a2713aSLionel Sambuc                                          FromProtoEnd = From->protocol_end();
3564f4a2713aSLionel Sambuc        FromProto != FromProtoEnd;
3565f4a2713aSLionel Sambuc        ++FromProto, ++FromProtoLoc) {
3566f4a2713aSLionel Sambuc     ObjCProtocolDecl *ToProto
3567f4a2713aSLionel Sambuc       = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
3568f4a2713aSLionel Sambuc     if (!ToProto)
3569f4a2713aSLionel Sambuc       return true;
3570f4a2713aSLionel Sambuc     Protocols.push_back(ToProto);
3571f4a2713aSLionel Sambuc     ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
3572f4a2713aSLionel Sambuc   }
3573f4a2713aSLionel Sambuc 
3574f4a2713aSLionel Sambuc   // FIXME: If we're merging, make sure that the protocol list is the same.
3575f4a2713aSLionel Sambuc   To->setProtocolList(Protocols.data(), Protocols.size(),
3576f4a2713aSLionel Sambuc                       ProtocolLocs.data(), Importer.getToContext());
3577f4a2713aSLionel Sambuc 
3578f4a2713aSLionel Sambuc   // Import categories. When the categories themselves are imported, they'll
3579f4a2713aSLionel Sambuc   // hook themselves into this interface.
3580*0a6a1f1dSLionel Sambuc   for (auto *Cat : From->known_categories())
3581*0a6a1f1dSLionel Sambuc     Importer.Import(Cat);
3582f4a2713aSLionel Sambuc 
3583f4a2713aSLionel Sambuc   // If we have an @implementation, import it as well.
3584f4a2713aSLionel Sambuc   if (From->getImplementation()) {
3585f4a2713aSLionel Sambuc     ObjCImplementationDecl *Impl = cast_or_null<ObjCImplementationDecl>(
3586f4a2713aSLionel Sambuc                                      Importer.Import(From->getImplementation()));
3587f4a2713aSLionel Sambuc     if (!Impl)
3588f4a2713aSLionel Sambuc       return true;
3589f4a2713aSLionel Sambuc 
3590f4a2713aSLionel Sambuc     To->setImplementation(Impl);
3591f4a2713aSLionel Sambuc   }
3592f4a2713aSLionel Sambuc 
3593f4a2713aSLionel Sambuc   if (shouldForceImportDeclContext(Kind)) {
3594f4a2713aSLionel Sambuc     // Import all of the members of this class.
3595f4a2713aSLionel Sambuc     ImportDeclContext(From, /*ForceImport=*/true);
3596f4a2713aSLionel Sambuc   }
3597f4a2713aSLionel Sambuc   return false;
3598f4a2713aSLionel Sambuc }
3599f4a2713aSLionel Sambuc 
VisitObjCInterfaceDecl(ObjCInterfaceDecl * D)3600f4a2713aSLionel Sambuc Decl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
3601f4a2713aSLionel Sambuc   // If this class has a definition in the translation unit we're coming from,
3602f4a2713aSLionel Sambuc   // but this particular declaration is not that definition, import the
3603f4a2713aSLionel Sambuc   // definition and map to that.
3604f4a2713aSLionel Sambuc   ObjCInterfaceDecl *Definition = D->getDefinition();
3605f4a2713aSLionel Sambuc   if (Definition && Definition != D) {
3606f4a2713aSLionel Sambuc     Decl *ImportedDef = Importer.Import(Definition);
3607f4a2713aSLionel Sambuc     if (!ImportedDef)
3608*0a6a1f1dSLionel Sambuc       return nullptr;
3609f4a2713aSLionel Sambuc 
3610f4a2713aSLionel Sambuc     return Importer.Imported(D, ImportedDef);
3611f4a2713aSLionel Sambuc   }
3612f4a2713aSLionel Sambuc 
3613f4a2713aSLionel Sambuc   // Import the major distinguishing characteristics of an @interface.
3614f4a2713aSLionel Sambuc   DeclContext *DC, *LexicalDC;
3615f4a2713aSLionel Sambuc   DeclarationName Name;
3616f4a2713aSLionel Sambuc   SourceLocation Loc;
3617f4a2713aSLionel Sambuc   if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
3618*0a6a1f1dSLionel Sambuc     return nullptr;
3619f4a2713aSLionel Sambuc 
3620f4a2713aSLionel Sambuc   // Look for an existing interface with the same name.
3621*0a6a1f1dSLionel Sambuc   ObjCInterfaceDecl *MergeWithIface = nullptr;
3622f4a2713aSLionel Sambuc   SmallVector<NamedDecl *, 2> FoundDecls;
3623*0a6a1f1dSLionel Sambuc   DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
3624f4a2713aSLionel Sambuc   for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
3625f4a2713aSLionel Sambuc     if (!FoundDecls[I]->isInIdentifierNamespace(Decl::IDNS_Ordinary))
3626f4a2713aSLionel Sambuc       continue;
3627f4a2713aSLionel Sambuc 
3628f4a2713aSLionel Sambuc     if ((MergeWithIface = dyn_cast<ObjCInterfaceDecl>(FoundDecls[I])))
3629f4a2713aSLionel Sambuc       break;
3630f4a2713aSLionel Sambuc   }
3631f4a2713aSLionel Sambuc 
3632f4a2713aSLionel Sambuc   // Create an interface declaration, if one does not already exist.
3633f4a2713aSLionel Sambuc   ObjCInterfaceDecl *ToIface = MergeWithIface;
3634f4a2713aSLionel Sambuc   if (!ToIface) {
3635f4a2713aSLionel Sambuc     ToIface = ObjCInterfaceDecl::Create(Importer.getToContext(), DC,
3636f4a2713aSLionel Sambuc                                         Importer.Import(D->getAtStartLoc()),
3637f4a2713aSLionel Sambuc                                         Name.getAsIdentifierInfo(),
3638*0a6a1f1dSLionel Sambuc                                         /*PrevDecl=*/nullptr, Loc,
3639f4a2713aSLionel Sambuc                                         D->isImplicitInterfaceDecl());
3640f4a2713aSLionel Sambuc     ToIface->setLexicalDeclContext(LexicalDC);
3641f4a2713aSLionel Sambuc     LexicalDC->addDeclInternal(ToIface);
3642f4a2713aSLionel Sambuc   }
3643f4a2713aSLionel Sambuc   Importer.Imported(D, ToIface);
3644f4a2713aSLionel Sambuc 
3645f4a2713aSLionel Sambuc   if (D->isThisDeclarationADefinition() && ImportDefinition(D, ToIface))
3646*0a6a1f1dSLionel Sambuc     return nullptr;
3647f4a2713aSLionel Sambuc 
3648f4a2713aSLionel Sambuc   return ToIface;
3649f4a2713aSLionel Sambuc }
3650f4a2713aSLionel Sambuc 
VisitObjCCategoryImplDecl(ObjCCategoryImplDecl * D)3651f4a2713aSLionel Sambuc Decl *ASTNodeImporter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
3652f4a2713aSLionel Sambuc   ObjCCategoryDecl *Category = cast_or_null<ObjCCategoryDecl>(
3653f4a2713aSLionel Sambuc                                         Importer.Import(D->getCategoryDecl()));
3654f4a2713aSLionel Sambuc   if (!Category)
3655*0a6a1f1dSLionel Sambuc     return nullptr;
3656f4a2713aSLionel Sambuc 
3657f4a2713aSLionel Sambuc   ObjCCategoryImplDecl *ToImpl = Category->getImplementation();
3658f4a2713aSLionel Sambuc   if (!ToImpl) {
3659f4a2713aSLionel Sambuc     DeclContext *DC = Importer.ImportContext(D->getDeclContext());
3660f4a2713aSLionel Sambuc     if (!DC)
3661*0a6a1f1dSLionel Sambuc       return nullptr;
3662f4a2713aSLionel Sambuc 
3663f4a2713aSLionel Sambuc     SourceLocation CategoryNameLoc = Importer.Import(D->getCategoryNameLoc());
3664f4a2713aSLionel Sambuc     ToImpl = ObjCCategoryImplDecl::Create(Importer.getToContext(), DC,
3665f4a2713aSLionel Sambuc                                           Importer.Import(D->getIdentifier()),
3666f4a2713aSLionel Sambuc                                           Category->getClassInterface(),
3667f4a2713aSLionel Sambuc                                           Importer.Import(D->getLocation()),
3668f4a2713aSLionel Sambuc                                           Importer.Import(D->getAtStartLoc()),
3669f4a2713aSLionel Sambuc                                           CategoryNameLoc);
3670f4a2713aSLionel Sambuc 
3671f4a2713aSLionel Sambuc     DeclContext *LexicalDC = DC;
3672f4a2713aSLionel Sambuc     if (D->getDeclContext() != D->getLexicalDeclContext()) {
3673f4a2713aSLionel Sambuc       LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
3674f4a2713aSLionel Sambuc       if (!LexicalDC)
3675*0a6a1f1dSLionel Sambuc         return nullptr;
3676f4a2713aSLionel Sambuc 
3677f4a2713aSLionel Sambuc       ToImpl->setLexicalDeclContext(LexicalDC);
3678f4a2713aSLionel Sambuc     }
3679f4a2713aSLionel Sambuc 
3680f4a2713aSLionel Sambuc     LexicalDC->addDeclInternal(ToImpl);
3681f4a2713aSLionel Sambuc     Category->setImplementation(ToImpl);
3682f4a2713aSLionel Sambuc   }
3683f4a2713aSLionel Sambuc 
3684f4a2713aSLionel Sambuc   Importer.Imported(D, ToImpl);
3685f4a2713aSLionel Sambuc   ImportDeclContext(D);
3686f4a2713aSLionel Sambuc   return ToImpl;
3687f4a2713aSLionel Sambuc }
3688f4a2713aSLionel Sambuc 
VisitObjCImplementationDecl(ObjCImplementationDecl * D)3689f4a2713aSLionel Sambuc Decl *ASTNodeImporter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
3690f4a2713aSLionel Sambuc   // Find the corresponding interface.
3691f4a2713aSLionel Sambuc   ObjCInterfaceDecl *Iface = cast_or_null<ObjCInterfaceDecl>(
3692f4a2713aSLionel Sambuc                                        Importer.Import(D->getClassInterface()));
3693f4a2713aSLionel Sambuc   if (!Iface)
3694*0a6a1f1dSLionel Sambuc     return nullptr;
3695f4a2713aSLionel Sambuc 
3696f4a2713aSLionel Sambuc   // Import the superclass, if any.
3697*0a6a1f1dSLionel Sambuc   ObjCInterfaceDecl *Super = nullptr;
3698f4a2713aSLionel Sambuc   if (D->getSuperClass()) {
3699f4a2713aSLionel Sambuc     Super = cast_or_null<ObjCInterfaceDecl>(
3700f4a2713aSLionel Sambuc                                           Importer.Import(D->getSuperClass()));
3701f4a2713aSLionel Sambuc     if (!Super)
3702*0a6a1f1dSLionel Sambuc       return nullptr;
3703f4a2713aSLionel Sambuc   }
3704f4a2713aSLionel Sambuc 
3705f4a2713aSLionel Sambuc   ObjCImplementationDecl *Impl = Iface->getImplementation();
3706f4a2713aSLionel Sambuc   if (!Impl) {
3707f4a2713aSLionel Sambuc     // We haven't imported an implementation yet. Create a new @implementation
3708f4a2713aSLionel Sambuc     // now.
3709f4a2713aSLionel Sambuc     Impl = ObjCImplementationDecl::Create(Importer.getToContext(),
3710f4a2713aSLionel Sambuc                                   Importer.ImportContext(D->getDeclContext()),
3711f4a2713aSLionel Sambuc                                           Iface, Super,
3712f4a2713aSLionel Sambuc                                           Importer.Import(D->getLocation()),
3713f4a2713aSLionel Sambuc                                           Importer.Import(D->getAtStartLoc()),
3714f4a2713aSLionel Sambuc                                           Importer.Import(D->getSuperClassLoc()),
3715f4a2713aSLionel Sambuc                                           Importer.Import(D->getIvarLBraceLoc()),
3716f4a2713aSLionel Sambuc                                           Importer.Import(D->getIvarRBraceLoc()));
3717f4a2713aSLionel Sambuc 
3718f4a2713aSLionel Sambuc     if (D->getDeclContext() != D->getLexicalDeclContext()) {
3719f4a2713aSLionel Sambuc       DeclContext *LexicalDC
3720f4a2713aSLionel Sambuc         = Importer.ImportContext(D->getLexicalDeclContext());
3721f4a2713aSLionel Sambuc       if (!LexicalDC)
3722*0a6a1f1dSLionel Sambuc         return nullptr;
3723f4a2713aSLionel Sambuc       Impl->setLexicalDeclContext(LexicalDC);
3724f4a2713aSLionel Sambuc     }
3725f4a2713aSLionel Sambuc 
3726f4a2713aSLionel Sambuc     // Associate the implementation with the class it implements.
3727f4a2713aSLionel Sambuc     Iface->setImplementation(Impl);
3728f4a2713aSLionel Sambuc     Importer.Imported(D, Iface->getImplementation());
3729f4a2713aSLionel Sambuc   } else {
3730f4a2713aSLionel Sambuc     Importer.Imported(D, Iface->getImplementation());
3731f4a2713aSLionel Sambuc 
3732f4a2713aSLionel Sambuc     // Verify that the existing @implementation has the same superclass.
3733f4a2713aSLionel Sambuc     if ((Super && !Impl->getSuperClass()) ||
3734f4a2713aSLionel Sambuc         (!Super && Impl->getSuperClass()) ||
3735f4a2713aSLionel Sambuc         (Super && Impl->getSuperClass() &&
3736*0a6a1f1dSLionel Sambuc          !declaresSameEntity(Super->getCanonicalDecl(),
3737*0a6a1f1dSLionel Sambuc                              Impl->getSuperClass()))) {
3738f4a2713aSLionel Sambuc       Importer.ToDiag(Impl->getLocation(),
3739f4a2713aSLionel Sambuc                       diag::err_odr_objc_superclass_inconsistent)
3740f4a2713aSLionel Sambuc         << Iface->getDeclName();
3741f4a2713aSLionel Sambuc       // FIXME: It would be nice to have the location of the superclass
3742f4a2713aSLionel Sambuc       // below.
3743f4a2713aSLionel Sambuc       if (Impl->getSuperClass())
3744f4a2713aSLionel Sambuc         Importer.ToDiag(Impl->getLocation(),
3745f4a2713aSLionel Sambuc                         diag::note_odr_objc_superclass)
3746f4a2713aSLionel Sambuc         << Impl->getSuperClass()->getDeclName();
3747f4a2713aSLionel Sambuc       else
3748f4a2713aSLionel Sambuc         Importer.ToDiag(Impl->getLocation(),
3749f4a2713aSLionel Sambuc                         diag::note_odr_objc_missing_superclass);
3750f4a2713aSLionel Sambuc       if (D->getSuperClass())
3751f4a2713aSLionel Sambuc         Importer.FromDiag(D->getLocation(),
3752f4a2713aSLionel Sambuc                           diag::note_odr_objc_superclass)
3753f4a2713aSLionel Sambuc         << D->getSuperClass()->getDeclName();
3754f4a2713aSLionel Sambuc       else
3755f4a2713aSLionel Sambuc         Importer.FromDiag(D->getLocation(),
3756f4a2713aSLionel Sambuc                           diag::note_odr_objc_missing_superclass);
3757*0a6a1f1dSLionel Sambuc       return nullptr;
3758f4a2713aSLionel Sambuc     }
3759f4a2713aSLionel Sambuc   }
3760f4a2713aSLionel Sambuc 
3761f4a2713aSLionel Sambuc   // Import all of the members of this @implementation.
3762f4a2713aSLionel Sambuc   ImportDeclContext(D);
3763f4a2713aSLionel Sambuc 
3764f4a2713aSLionel Sambuc   return Impl;
3765f4a2713aSLionel Sambuc }
3766f4a2713aSLionel Sambuc 
VisitObjCPropertyDecl(ObjCPropertyDecl * D)3767f4a2713aSLionel Sambuc Decl *ASTNodeImporter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
3768f4a2713aSLionel Sambuc   // Import the major distinguishing characteristics of an @property.
3769f4a2713aSLionel Sambuc   DeclContext *DC, *LexicalDC;
3770f4a2713aSLionel Sambuc   DeclarationName Name;
3771f4a2713aSLionel Sambuc   SourceLocation Loc;
3772f4a2713aSLionel Sambuc   if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
3773*0a6a1f1dSLionel Sambuc     return nullptr;
3774f4a2713aSLionel Sambuc 
3775f4a2713aSLionel Sambuc   // Check whether we have already imported this property.
3776f4a2713aSLionel Sambuc   SmallVector<NamedDecl *, 2> FoundDecls;
3777*0a6a1f1dSLionel Sambuc   DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
3778f4a2713aSLionel Sambuc   for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
3779f4a2713aSLionel Sambuc     if (ObjCPropertyDecl *FoundProp
3780f4a2713aSLionel Sambuc                                 = dyn_cast<ObjCPropertyDecl>(FoundDecls[I])) {
3781f4a2713aSLionel Sambuc       // Check property types.
3782f4a2713aSLionel Sambuc       if (!Importer.IsStructurallyEquivalent(D->getType(),
3783f4a2713aSLionel Sambuc                                              FoundProp->getType())) {
3784f4a2713aSLionel Sambuc         Importer.ToDiag(Loc, diag::err_odr_objc_property_type_inconsistent)
3785f4a2713aSLionel Sambuc           << Name << D->getType() << FoundProp->getType();
3786f4a2713aSLionel Sambuc         Importer.ToDiag(FoundProp->getLocation(), diag::note_odr_value_here)
3787f4a2713aSLionel Sambuc           << FoundProp->getType();
3788*0a6a1f1dSLionel Sambuc         return nullptr;
3789f4a2713aSLionel Sambuc       }
3790f4a2713aSLionel Sambuc 
3791f4a2713aSLionel Sambuc       // FIXME: Check property attributes, getters, setters, etc.?
3792f4a2713aSLionel Sambuc 
3793f4a2713aSLionel Sambuc       // Consider these properties to be equivalent.
3794f4a2713aSLionel Sambuc       Importer.Imported(D, FoundProp);
3795f4a2713aSLionel Sambuc       return FoundProp;
3796f4a2713aSLionel Sambuc     }
3797f4a2713aSLionel Sambuc   }
3798f4a2713aSLionel Sambuc 
3799f4a2713aSLionel Sambuc   // Import the type.
3800f4a2713aSLionel Sambuc   TypeSourceInfo *T = Importer.Import(D->getTypeSourceInfo());
3801f4a2713aSLionel Sambuc   if (!T)
3802*0a6a1f1dSLionel Sambuc     return nullptr;
3803f4a2713aSLionel Sambuc 
3804f4a2713aSLionel Sambuc   // Create the new property.
3805f4a2713aSLionel Sambuc   ObjCPropertyDecl *ToProperty
3806f4a2713aSLionel Sambuc     = ObjCPropertyDecl::Create(Importer.getToContext(), DC, Loc,
3807f4a2713aSLionel Sambuc                                Name.getAsIdentifierInfo(),
3808f4a2713aSLionel Sambuc                                Importer.Import(D->getAtLoc()),
3809f4a2713aSLionel Sambuc                                Importer.Import(D->getLParenLoc()),
3810f4a2713aSLionel Sambuc                                T,
3811f4a2713aSLionel Sambuc                                D->getPropertyImplementation());
3812f4a2713aSLionel Sambuc   Importer.Imported(D, ToProperty);
3813f4a2713aSLionel Sambuc   ToProperty->setLexicalDeclContext(LexicalDC);
3814f4a2713aSLionel Sambuc   LexicalDC->addDeclInternal(ToProperty);
3815f4a2713aSLionel Sambuc 
3816f4a2713aSLionel Sambuc   ToProperty->setPropertyAttributes(D->getPropertyAttributes());
3817f4a2713aSLionel Sambuc   ToProperty->setPropertyAttributesAsWritten(
3818f4a2713aSLionel Sambuc                                       D->getPropertyAttributesAsWritten());
3819f4a2713aSLionel Sambuc   ToProperty->setGetterName(Importer.Import(D->getGetterName()));
3820f4a2713aSLionel Sambuc   ToProperty->setSetterName(Importer.Import(D->getSetterName()));
3821f4a2713aSLionel Sambuc   ToProperty->setGetterMethodDecl(
3822f4a2713aSLionel Sambuc      cast_or_null<ObjCMethodDecl>(Importer.Import(D->getGetterMethodDecl())));
3823f4a2713aSLionel Sambuc   ToProperty->setSetterMethodDecl(
3824f4a2713aSLionel Sambuc      cast_or_null<ObjCMethodDecl>(Importer.Import(D->getSetterMethodDecl())));
3825f4a2713aSLionel Sambuc   ToProperty->setPropertyIvarDecl(
3826f4a2713aSLionel Sambuc        cast_or_null<ObjCIvarDecl>(Importer.Import(D->getPropertyIvarDecl())));
3827f4a2713aSLionel Sambuc   return ToProperty;
3828f4a2713aSLionel Sambuc }
3829f4a2713aSLionel Sambuc 
VisitObjCPropertyImplDecl(ObjCPropertyImplDecl * D)3830f4a2713aSLionel Sambuc Decl *ASTNodeImporter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
3831f4a2713aSLionel Sambuc   ObjCPropertyDecl *Property = cast_or_null<ObjCPropertyDecl>(
3832f4a2713aSLionel Sambuc                                         Importer.Import(D->getPropertyDecl()));
3833f4a2713aSLionel Sambuc   if (!Property)
3834*0a6a1f1dSLionel Sambuc     return nullptr;
3835f4a2713aSLionel Sambuc 
3836f4a2713aSLionel Sambuc   DeclContext *DC = Importer.ImportContext(D->getDeclContext());
3837f4a2713aSLionel Sambuc   if (!DC)
3838*0a6a1f1dSLionel Sambuc     return nullptr;
3839f4a2713aSLionel Sambuc 
3840f4a2713aSLionel Sambuc   // Import the lexical declaration context.
3841f4a2713aSLionel Sambuc   DeclContext *LexicalDC = DC;
3842f4a2713aSLionel Sambuc   if (D->getDeclContext() != D->getLexicalDeclContext()) {
3843f4a2713aSLionel Sambuc     LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
3844f4a2713aSLionel Sambuc     if (!LexicalDC)
3845*0a6a1f1dSLionel Sambuc       return nullptr;
3846f4a2713aSLionel Sambuc   }
3847f4a2713aSLionel Sambuc 
3848f4a2713aSLionel Sambuc   ObjCImplDecl *InImpl = dyn_cast<ObjCImplDecl>(LexicalDC);
3849f4a2713aSLionel Sambuc   if (!InImpl)
3850*0a6a1f1dSLionel Sambuc     return nullptr;
3851f4a2713aSLionel Sambuc 
3852f4a2713aSLionel Sambuc   // Import the ivar (for an @synthesize).
3853*0a6a1f1dSLionel Sambuc   ObjCIvarDecl *Ivar = nullptr;
3854f4a2713aSLionel Sambuc   if (D->getPropertyIvarDecl()) {
3855f4a2713aSLionel Sambuc     Ivar = cast_or_null<ObjCIvarDecl>(
3856f4a2713aSLionel Sambuc                                     Importer.Import(D->getPropertyIvarDecl()));
3857f4a2713aSLionel Sambuc     if (!Ivar)
3858*0a6a1f1dSLionel Sambuc       return nullptr;
3859f4a2713aSLionel Sambuc   }
3860f4a2713aSLionel Sambuc 
3861f4a2713aSLionel Sambuc   ObjCPropertyImplDecl *ToImpl
3862f4a2713aSLionel Sambuc     = InImpl->FindPropertyImplDecl(Property->getIdentifier());
3863f4a2713aSLionel Sambuc   if (!ToImpl) {
3864f4a2713aSLionel Sambuc     ToImpl = ObjCPropertyImplDecl::Create(Importer.getToContext(), DC,
3865f4a2713aSLionel Sambuc                                           Importer.Import(D->getLocStart()),
3866f4a2713aSLionel Sambuc                                           Importer.Import(D->getLocation()),
3867f4a2713aSLionel Sambuc                                           Property,
3868f4a2713aSLionel Sambuc                                           D->getPropertyImplementation(),
3869f4a2713aSLionel Sambuc                                           Ivar,
3870f4a2713aSLionel Sambuc                                   Importer.Import(D->getPropertyIvarDeclLoc()));
3871f4a2713aSLionel Sambuc     ToImpl->setLexicalDeclContext(LexicalDC);
3872f4a2713aSLionel Sambuc     Importer.Imported(D, ToImpl);
3873f4a2713aSLionel Sambuc     LexicalDC->addDeclInternal(ToImpl);
3874f4a2713aSLionel Sambuc   } else {
3875f4a2713aSLionel Sambuc     // Check that we have the same kind of property implementation (@synthesize
3876f4a2713aSLionel Sambuc     // vs. @dynamic).
3877f4a2713aSLionel Sambuc     if (D->getPropertyImplementation() != ToImpl->getPropertyImplementation()) {
3878f4a2713aSLionel Sambuc       Importer.ToDiag(ToImpl->getLocation(),
3879f4a2713aSLionel Sambuc                       diag::err_odr_objc_property_impl_kind_inconsistent)
3880f4a2713aSLionel Sambuc         << Property->getDeclName()
3881f4a2713aSLionel Sambuc         << (ToImpl->getPropertyImplementation()
3882f4a2713aSLionel Sambuc                                               == ObjCPropertyImplDecl::Dynamic);
3883f4a2713aSLionel Sambuc       Importer.FromDiag(D->getLocation(),
3884f4a2713aSLionel Sambuc                         diag::note_odr_objc_property_impl_kind)
3885f4a2713aSLionel Sambuc         << D->getPropertyDecl()->getDeclName()
3886f4a2713aSLionel Sambuc         << (D->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic);
3887*0a6a1f1dSLionel Sambuc       return nullptr;
3888f4a2713aSLionel Sambuc     }
3889f4a2713aSLionel Sambuc 
3890f4a2713aSLionel Sambuc     // For @synthesize, check that we have the same
3891f4a2713aSLionel Sambuc     if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize &&
3892f4a2713aSLionel Sambuc         Ivar != ToImpl->getPropertyIvarDecl()) {
3893f4a2713aSLionel Sambuc       Importer.ToDiag(ToImpl->getPropertyIvarDeclLoc(),
3894f4a2713aSLionel Sambuc                       diag::err_odr_objc_synthesize_ivar_inconsistent)
3895f4a2713aSLionel Sambuc         << Property->getDeclName()
3896f4a2713aSLionel Sambuc         << ToImpl->getPropertyIvarDecl()->getDeclName()
3897f4a2713aSLionel Sambuc         << Ivar->getDeclName();
3898f4a2713aSLionel Sambuc       Importer.FromDiag(D->getPropertyIvarDeclLoc(),
3899f4a2713aSLionel Sambuc                         diag::note_odr_objc_synthesize_ivar_here)
3900f4a2713aSLionel Sambuc         << D->getPropertyIvarDecl()->getDeclName();
3901*0a6a1f1dSLionel Sambuc       return nullptr;
3902f4a2713aSLionel Sambuc     }
3903f4a2713aSLionel Sambuc 
3904f4a2713aSLionel Sambuc     // Merge the existing implementation with the new implementation.
3905f4a2713aSLionel Sambuc     Importer.Imported(D, ToImpl);
3906f4a2713aSLionel Sambuc   }
3907f4a2713aSLionel Sambuc 
3908f4a2713aSLionel Sambuc   return ToImpl;
3909f4a2713aSLionel Sambuc }
3910f4a2713aSLionel Sambuc 
VisitTemplateTypeParmDecl(TemplateTypeParmDecl * D)3911f4a2713aSLionel Sambuc Decl *ASTNodeImporter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
3912f4a2713aSLionel Sambuc   // For template arguments, we adopt the translation unit as our declaration
3913f4a2713aSLionel Sambuc   // context. This context will be fixed when the actual template declaration
3914f4a2713aSLionel Sambuc   // is created.
3915f4a2713aSLionel Sambuc 
3916f4a2713aSLionel Sambuc   // FIXME: Import default argument.
3917f4a2713aSLionel Sambuc   return TemplateTypeParmDecl::Create(Importer.getToContext(),
3918f4a2713aSLionel Sambuc                               Importer.getToContext().getTranslationUnitDecl(),
3919f4a2713aSLionel Sambuc                                       Importer.Import(D->getLocStart()),
3920f4a2713aSLionel Sambuc                                       Importer.Import(D->getLocation()),
3921f4a2713aSLionel Sambuc                                       D->getDepth(),
3922f4a2713aSLionel Sambuc                                       D->getIndex(),
3923f4a2713aSLionel Sambuc                                       Importer.Import(D->getIdentifier()),
3924f4a2713aSLionel Sambuc                                       D->wasDeclaredWithTypename(),
3925f4a2713aSLionel Sambuc                                       D->isParameterPack());
3926f4a2713aSLionel Sambuc }
3927f4a2713aSLionel Sambuc 
3928f4a2713aSLionel Sambuc Decl *
VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl * D)3929f4a2713aSLionel Sambuc ASTNodeImporter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
3930f4a2713aSLionel Sambuc   // Import the name of this declaration.
3931f4a2713aSLionel Sambuc   DeclarationName Name = Importer.Import(D->getDeclName());
3932f4a2713aSLionel Sambuc   if (D->getDeclName() && !Name)
3933*0a6a1f1dSLionel Sambuc     return nullptr;
3934f4a2713aSLionel Sambuc 
3935f4a2713aSLionel Sambuc   // Import the location of this declaration.
3936f4a2713aSLionel Sambuc   SourceLocation Loc = Importer.Import(D->getLocation());
3937f4a2713aSLionel Sambuc 
3938f4a2713aSLionel Sambuc   // Import the type of this declaration.
3939f4a2713aSLionel Sambuc   QualType T = Importer.Import(D->getType());
3940f4a2713aSLionel Sambuc   if (T.isNull())
3941*0a6a1f1dSLionel Sambuc     return nullptr;
3942f4a2713aSLionel Sambuc 
3943f4a2713aSLionel Sambuc   // Import type-source information.
3944f4a2713aSLionel Sambuc   TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
3945f4a2713aSLionel Sambuc   if (D->getTypeSourceInfo() && !TInfo)
3946*0a6a1f1dSLionel Sambuc     return nullptr;
3947f4a2713aSLionel Sambuc 
3948f4a2713aSLionel Sambuc   // FIXME: Import default argument.
3949f4a2713aSLionel Sambuc 
3950f4a2713aSLionel Sambuc   return NonTypeTemplateParmDecl::Create(Importer.getToContext(),
3951f4a2713aSLionel Sambuc                                Importer.getToContext().getTranslationUnitDecl(),
3952f4a2713aSLionel Sambuc                                          Importer.Import(D->getInnerLocStart()),
3953f4a2713aSLionel Sambuc                                          Loc, D->getDepth(), D->getPosition(),
3954f4a2713aSLionel Sambuc                                          Name.getAsIdentifierInfo(),
3955f4a2713aSLionel Sambuc                                          T, D->isParameterPack(), TInfo);
3956f4a2713aSLionel Sambuc }
3957f4a2713aSLionel Sambuc 
3958f4a2713aSLionel Sambuc Decl *
VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl * D)3959f4a2713aSLionel Sambuc ASTNodeImporter::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
3960f4a2713aSLionel Sambuc   // Import the name of this declaration.
3961f4a2713aSLionel Sambuc   DeclarationName Name = Importer.Import(D->getDeclName());
3962f4a2713aSLionel Sambuc   if (D->getDeclName() && !Name)
3963*0a6a1f1dSLionel Sambuc     return nullptr;
3964f4a2713aSLionel Sambuc 
3965f4a2713aSLionel Sambuc   // Import the location of this declaration.
3966f4a2713aSLionel Sambuc   SourceLocation Loc = Importer.Import(D->getLocation());
3967f4a2713aSLionel Sambuc 
3968f4a2713aSLionel Sambuc   // Import template parameters.
3969f4a2713aSLionel Sambuc   TemplateParameterList *TemplateParams
3970f4a2713aSLionel Sambuc     = ImportTemplateParameterList(D->getTemplateParameters());
3971f4a2713aSLionel Sambuc   if (!TemplateParams)
3972*0a6a1f1dSLionel Sambuc     return nullptr;
3973f4a2713aSLionel Sambuc 
3974f4a2713aSLionel Sambuc   // FIXME: Import default argument.
3975f4a2713aSLionel Sambuc 
3976f4a2713aSLionel Sambuc   return TemplateTemplateParmDecl::Create(Importer.getToContext(),
3977f4a2713aSLionel Sambuc                               Importer.getToContext().getTranslationUnitDecl(),
3978f4a2713aSLionel Sambuc                                           Loc, D->getDepth(), D->getPosition(),
3979f4a2713aSLionel Sambuc                                           D->isParameterPack(),
3980f4a2713aSLionel Sambuc                                           Name.getAsIdentifierInfo(),
3981f4a2713aSLionel Sambuc                                           TemplateParams);
3982f4a2713aSLionel Sambuc }
3983f4a2713aSLionel Sambuc 
VisitClassTemplateDecl(ClassTemplateDecl * D)3984f4a2713aSLionel Sambuc Decl *ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
3985f4a2713aSLionel Sambuc   // If this record has a definition in the translation unit we're coming from,
3986f4a2713aSLionel Sambuc   // but this particular declaration is not that definition, import the
3987f4a2713aSLionel Sambuc   // definition and map to that.
3988f4a2713aSLionel Sambuc   CXXRecordDecl *Definition
3989f4a2713aSLionel Sambuc     = cast_or_null<CXXRecordDecl>(D->getTemplatedDecl()->getDefinition());
3990f4a2713aSLionel Sambuc   if (Definition && Definition != D->getTemplatedDecl()) {
3991f4a2713aSLionel Sambuc     Decl *ImportedDef
3992f4a2713aSLionel Sambuc       = Importer.Import(Definition->getDescribedClassTemplate());
3993f4a2713aSLionel Sambuc     if (!ImportedDef)
3994*0a6a1f1dSLionel Sambuc       return nullptr;
3995f4a2713aSLionel Sambuc 
3996f4a2713aSLionel Sambuc     return Importer.Imported(D, ImportedDef);
3997f4a2713aSLionel Sambuc   }
3998f4a2713aSLionel Sambuc 
3999f4a2713aSLionel Sambuc   // Import the major distinguishing characteristics of this class template.
4000f4a2713aSLionel Sambuc   DeclContext *DC, *LexicalDC;
4001f4a2713aSLionel Sambuc   DeclarationName Name;
4002f4a2713aSLionel Sambuc   SourceLocation Loc;
4003f4a2713aSLionel Sambuc   if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
4004*0a6a1f1dSLionel Sambuc     return nullptr;
4005f4a2713aSLionel Sambuc 
4006f4a2713aSLionel Sambuc   // We may already have a template of the same name; try to find and match it.
4007f4a2713aSLionel Sambuc   if (!DC->isFunctionOrMethod()) {
4008f4a2713aSLionel Sambuc     SmallVector<NamedDecl *, 4> ConflictingDecls;
4009f4a2713aSLionel Sambuc     SmallVector<NamedDecl *, 2> FoundDecls;
4010*0a6a1f1dSLionel Sambuc     DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
4011f4a2713aSLionel Sambuc     for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
4012f4a2713aSLionel Sambuc       if (!FoundDecls[I]->isInIdentifierNamespace(Decl::IDNS_Ordinary))
4013f4a2713aSLionel Sambuc         continue;
4014f4a2713aSLionel Sambuc 
4015f4a2713aSLionel Sambuc       Decl *Found = FoundDecls[I];
4016f4a2713aSLionel Sambuc       if (ClassTemplateDecl *FoundTemplate
4017f4a2713aSLionel Sambuc                                         = dyn_cast<ClassTemplateDecl>(Found)) {
4018f4a2713aSLionel Sambuc         if (IsStructuralMatch(D, FoundTemplate)) {
4019f4a2713aSLionel Sambuc           // The class templates structurally match; call it the same template.
4020f4a2713aSLionel Sambuc           // FIXME: We may be filling in a forward declaration here. Handle
4021f4a2713aSLionel Sambuc           // this case!
4022f4a2713aSLionel Sambuc           Importer.Imported(D->getTemplatedDecl(),
4023f4a2713aSLionel Sambuc                             FoundTemplate->getTemplatedDecl());
4024f4a2713aSLionel Sambuc           return Importer.Imported(D, FoundTemplate);
4025f4a2713aSLionel Sambuc         }
4026f4a2713aSLionel Sambuc       }
4027f4a2713aSLionel Sambuc 
4028f4a2713aSLionel Sambuc       ConflictingDecls.push_back(FoundDecls[I]);
4029f4a2713aSLionel Sambuc     }
4030f4a2713aSLionel Sambuc 
4031f4a2713aSLionel Sambuc     if (!ConflictingDecls.empty()) {
4032f4a2713aSLionel Sambuc       Name = Importer.HandleNameConflict(Name, DC, Decl::IDNS_Ordinary,
4033f4a2713aSLionel Sambuc                                          ConflictingDecls.data(),
4034f4a2713aSLionel Sambuc                                          ConflictingDecls.size());
4035f4a2713aSLionel Sambuc     }
4036f4a2713aSLionel Sambuc 
4037f4a2713aSLionel Sambuc     if (!Name)
4038*0a6a1f1dSLionel Sambuc       return nullptr;
4039f4a2713aSLionel Sambuc   }
4040f4a2713aSLionel Sambuc 
4041f4a2713aSLionel Sambuc   CXXRecordDecl *DTemplated = D->getTemplatedDecl();
4042f4a2713aSLionel Sambuc 
4043f4a2713aSLionel Sambuc   // Create the declaration that is being templated.
4044f4a2713aSLionel Sambuc   SourceLocation StartLoc = Importer.Import(DTemplated->getLocStart());
4045f4a2713aSLionel Sambuc   SourceLocation IdLoc = Importer.Import(DTemplated->getLocation());
4046f4a2713aSLionel Sambuc   CXXRecordDecl *D2Templated = CXXRecordDecl::Create(Importer.getToContext(),
4047f4a2713aSLionel Sambuc                                                      DTemplated->getTagKind(),
4048f4a2713aSLionel Sambuc                                                      DC, StartLoc, IdLoc,
4049f4a2713aSLionel Sambuc                                                    Name.getAsIdentifierInfo());
4050f4a2713aSLionel Sambuc   D2Templated->setAccess(DTemplated->getAccess());
4051f4a2713aSLionel Sambuc   D2Templated->setQualifierInfo(Importer.Import(DTemplated->getQualifierLoc()));
4052f4a2713aSLionel Sambuc   D2Templated->setLexicalDeclContext(LexicalDC);
4053f4a2713aSLionel Sambuc 
4054f4a2713aSLionel Sambuc   // Create the class template declaration itself.
4055f4a2713aSLionel Sambuc   TemplateParameterList *TemplateParams
4056f4a2713aSLionel Sambuc     = ImportTemplateParameterList(D->getTemplateParameters());
4057f4a2713aSLionel Sambuc   if (!TemplateParams)
4058*0a6a1f1dSLionel Sambuc     return nullptr;
4059f4a2713aSLionel Sambuc 
4060f4a2713aSLionel Sambuc   ClassTemplateDecl *D2 = ClassTemplateDecl::Create(Importer.getToContext(), DC,
4061f4a2713aSLionel Sambuc                                                     Loc, Name, TemplateParams,
4062f4a2713aSLionel Sambuc                                                     D2Templated,
4063*0a6a1f1dSLionel Sambuc                                                     /*PrevDecl=*/nullptr);
4064f4a2713aSLionel Sambuc   D2Templated->setDescribedClassTemplate(D2);
4065f4a2713aSLionel Sambuc 
4066f4a2713aSLionel Sambuc   D2->setAccess(D->getAccess());
4067f4a2713aSLionel Sambuc   D2->setLexicalDeclContext(LexicalDC);
4068f4a2713aSLionel Sambuc   LexicalDC->addDeclInternal(D2);
4069f4a2713aSLionel Sambuc 
4070f4a2713aSLionel Sambuc   // Note the relationship between the class templates.
4071f4a2713aSLionel Sambuc   Importer.Imported(D, D2);
4072f4a2713aSLionel Sambuc   Importer.Imported(DTemplated, D2Templated);
4073f4a2713aSLionel Sambuc 
4074f4a2713aSLionel Sambuc   if (DTemplated->isCompleteDefinition() &&
4075f4a2713aSLionel Sambuc       !D2Templated->isCompleteDefinition()) {
4076f4a2713aSLionel Sambuc     // FIXME: Import definition!
4077f4a2713aSLionel Sambuc   }
4078f4a2713aSLionel Sambuc 
4079f4a2713aSLionel Sambuc   return D2;
4080f4a2713aSLionel Sambuc }
4081f4a2713aSLionel Sambuc 
VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl * D)4082f4a2713aSLionel Sambuc Decl *ASTNodeImporter::VisitClassTemplateSpecializationDecl(
4083f4a2713aSLionel Sambuc                                           ClassTemplateSpecializationDecl *D) {
4084f4a2713aSLionel Sambuc   // If this record has a definition in the translation unit we're coming from,
4085f4a2713aSLionel Sambuc   // but this particular declaration is not that definition, import the
4086f4a2713aSLionel Sambuc   // definition and map to that.
4087f4a2713aSLionel Sambuc   TagDecl *Definition = D->getDefinition();
4088f4a2713aSLionel Sambuc   if (Definition && Definition != D) {
4089f4a2713aSLionel Sambuc     Decl *ImportedDef = Importer.Import(Definition);
4090f4a2713aSLionel Sambuc     if (!ImportedDef)
4091*0a6a1f1dSLionel Sambuc       return nullptr;
4092f4a2713aSLionel Sambuc 
4093f4a2713aSLionel Sambuc     return Importer.Imported(D, ImportedDef);
4094f4a2713aSLionel Sambuc   }
4095f4a2713aSLionel Sambuc 
4096f4a2713aSLionel Sambuc   ClassTemplateDecl *ClassTemplate
4097f4a2713aSLionel Sambuc     = cast_or_null<ClassTemplateDecl>(Importer.Import(
4098f4a2713aSLionel Sambuc                                                  D->getSpecializedTemplate()));
4099f4a2713aSLionel Sambuc   if (!ClassTemplate)
4100*0a6a1f1dSLionel Sambuc     return nullptr;
4101f4a2713aSLionel Sambuc 
4102f4a2713aSLionel Sambuc   // Import the context of this declaration.
4103f4a2713aSLionel Sambuc   DeclContext *DC = ClassTemplate->getDeclContext();
4104f4a2713aSLionel Sambuc   if (!DC)
4105*0a6a1f1dSLionel Sambuc     return nullptr;
4106f4a2713aSLionel Sambuc 
4107f4a2713aSLionel Sambuc   DeclContext *LexicalDC = DC;
4108f4a2713aSLionel Sambuc   if (D->getDeclContext() != D->getLexicalDeclContext()) {
4109f4a2713aSLionel Sambuc     LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
4110f4a2713aSLionel Sambuc     if (!LexicalDC)
4111*0a6a1f1dSLionel Sambuc       return nullptr;
4112f4a2713aSLionel Sambuc   }
4113f4a2713aSLionel Sambuc 
4114f4a2713aSLionel Sambuc   // Import the location of this declaration.
4115f4a2713aSLionel Sambuc   SourceLocation StartLoc = Importer.Import(D->getLocStart());
4116f4a2713aSLionel Sambuc   SourceLocation IdLoc = Importer.Import(D->getLocation());
4117f4a2713aSLionel Sambuc 
4118f4a2713aSLionel Sambuc   // Import template arguments.
4119f4a2713aSLionel Sambuc   SmallVector<TemplateArgument, 2> TemplateArgs;
4120f4a2713aSLionel Sambuc   if (ImportTemplateArguments(D->getTemplateArgs().data(),
4121f4a2713aSLionel Sambuc                               D->getTemplateArgs().size(),
4122f4a2713aSLionel Sambuc                               TemplateArgs))
4123*0a6a1f1dSLionel Sambuc     return nullptr;
4124f4a2713aSLionel Sambuc 
4125f4a2713aSLionel Sambuc   // Try to find an existing specialization with these template arguments.
4126*0a6a1f1dSLionel Sambuc   void *InsertPos = nullptr;
4127f4a2713aSLionel Sambuc   ClassTemplateSpecializationDecl *D2
4128*0a6a1f1dSLionel Sambuc     = ClassTemplate->findSpecialization(TemplateArgs, InsertPos);
4129f4a2713aSLionel Sambuc   if (D2) {
4130f4a2713aSLionel Sambuc     // We already have a class template specialization with these template
4131f4a2713aSLionel Sambuc     // arguments.
4132f4a2713aSLionel Sambuc 
4133f4a2713aSLionel Sambuc     // FIXME: Check for specialization vs. instantiation errors.
4134f4a2713aSLionel Sambuc 
4135f4a2713aSLionel Sambuc     if (RecordDecl *FoundDef = D2->getDefinition()) {
4136f4a2713aSLionel Sambuc       if (!D->isCompleteDefinition() || IsStructuralMatch(D, FoundDef)) {
4137f4a2713aSLionel Sambuc         // The record types structurally match, or the "from" translation
4138f4a2713aSLionel Sambuc         // unit only had a forward declaration anyway; call it the same
4139f4a2713aSLionel Sambuc         // function.
4140f4a2713aSLionel Sambuc         return Importer.Imported(D, FoundDef);
4141f4a2713aSLionel Sambuc       }
4142f4a2713aSLionel Sambuc     }
4143f4a2713aSLionel Sambuc   } else {
4144f4a2713aSLionel Sambuc     // Create a new specialization.
4145f4a2713aSLionel Sambuc     D2 = ClassTemplateSpecializationDecl::Create(Importer.getToContext(),
4146f4a2713aSLionel Sambuc                                                  D->getTagKind(), DC,
4147f4a2713aSLionel Sambuc                                                  StartLoc, IdLoc,
4148f4a2713aSLionel Sambuc                                                  ClassTemplate,
4149f4a2713aSLionel Sambuc                                                  TemplateArgs.data(),
4150f4a2713aSLionel Sambuc                                                  TemplateArgs.size(),
4151*0a6a1f1dSLionel Sambuc                                                  /*PrevDecl=*/nullptr);
4152f4a2713aSLionel Sambuc     D2->setSpecializationKind(D->getSpecializationKind());
4153f4a2713aSLionel Sambuc 
4154f4a2713aSLionel Sambuc     // Add this specialization to the class template.
4155f4a2713aSLionel Sambuc     ClassTemplate->AddSpecialization(D2, InsertPos);
4156f4a2713aSLionel Sambuc 
4157f4a2713aSLionel Sambuc     // Import the qualifier, if any.
4158f4a2713aSLionel Sambuc     D2->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
4159f4a2713aSLionel Sambuc 
4160f4a2713aSLionel Sambuc     // Add the specialization to this context.
4161f4a2713aSLionel Sambuc     D2->setLexicalDeclContext(LexicalDC);
4162f4a2713aSLionel Sambuc     LexicalDC->addDeclInternal(D2);
4163f4a2713aSLionel Sambuc   }
4164f4a2713aSLionel Sambuc   Importer.Imported(D, D2);
4165f4a2713aSLionel Sambuc 
4166f4a2713aSLionel Sambuc   if (D->isCompleteDefinition() && ImportDefinition(D, D2))
4167*0a6a1f1dSLionel Sambuc     return nullptr;
4168f4a2713aSLionel Sambuc 
4169f4a2713aSLionel Sambuc   return D2;
4170f4a2713aSLionel Sambuc }
4171f4a2713aSLionel Sambuc 
VisitVarTemplateDecl(VarTemplateDecl * D)4172f4a2713aSLionel Sambuc Decl *ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) {
4173f4a2713aSLionel Sambuc   // If this variable has a definition in the translation unit we're coming
4174f4a2713aSLionel Sambuc   // from,
4175f4a2713aSLionel Sambuc   // but this particular declaration is not that definition, import the
4176f4a2713aSLionel Sambuc   // definition and map to that.
4177f4a2713aSLionel Sambuc   VarDecl *Definition =
4178f4a2713aSLionel Sambuc       cast_or_null<VarDecl>(D->getTemplatedDecl()->getDefinition());
4179f4a2713aSLionel Sambuc   if (Definition && Definition != D->getTemplatedDecl()) {
4180f4a2713aSLionel Sambuc     Decl *ImportedDef = Importer.Import(Definition->getDescribedVarTemplate());
4181f4a2713aSLionel Sambuc     if (!ImportedDef)
4182*0a6a1f1dSLionel Sambuc       return nullptr;
4183f4a2713aSLionel Sambuc 
4184f4a2713aSLionel Sambuc     return Importer.Imported(D, ImportedDef);
4185f4a2713aSLionel Sambuc   }
4186f4a2713aSLionel Sambuc 
4187f4a2713aSLionel Sambuc   // Import the major distinguishing characteristics of this variable template.
4188f4a2713aSLionel Sambuc   DeclContext *DC, *LexicalDC;
4189f4a2713aSLionel Sambuc   DeclarationName Name;
4190f4a2713aSLionel Sambuc   SourceLocation Loc;
4191f4a2713aSLionel Sambuc   if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
4192*0a6a1f1dSLionel Sambuc     return nullptr;
4193f4a2713aSLionel Sambuc 
4194f4a2713aSLionel Sambuc   // We may already have a template of the same name; try to find and match it.
4195f4a2713aSLionel Sambuc   assert(!DC->isFunctionOrMethod() &&
4196f4a2713aSLionel Sambuc          "Variable templates cannot be declared at function scope");
4197f4a2713aSLionel Sambuc   SmallVector<NamedDecl *, 4> ConflictingDecls;
4198f4a2713aSLionel Sambuc   SmallVector<NamedDecl *, 2> FoundDecls;
4199*0a6a1f1dSLionel Sambuc   DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
4200f4a2713aSLionel Sambuc   for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
4201f4a2713aSLionel Sambuc     if (!FoundDecls[I]->isInIdentifierNamespace(Decl::IDNS_Ordinary))
4202f4a2713aSLionel Sambuc       continue;
4203f4a2713aSLionel Sambuc 
4204f4a2713aSLionel Sambuc     Decl *Found = FoundDecls[I];
4205f4a2713aSLionel Sambuc     if (VarTemplateDecl *FoundTemplate = dyn_cast<VarTemplateDecl>(Found)) {
4206f4a2713aSLionel Sambuc       if (IsStructuralMatch(D, FoundTemplate)) {
4207f4a2713aSLionel Sambuc         // The variable templates structurally match; call it the same template.
4208f4a2713aSLionel Sambuc         Importer.Imported(D->getTemplatedDecl(),
4209f4a2713aSLionel Sambuc                           FoundTemplate->getTemplatedDecl());
4210f4a2713aSLionel Sambuc         return Importer.Imported(D, FoundTemplate);
4211f4a2713aSLionel Sambuc       }
4212f4a2713aSLionel Sambuc     }
4213f4a2713aSLionel Sambuc 
4214f4a2713aSLionel Sambuc     ConflictingDecls.push_back(FoundDecls[I]);
4215f4a2713aSLionel Sambuc   }
4216f4a2713aSLionel Sambuc 
4217f4a2713aSLionel Sambuc   if (!ConflictingDecls.empty()) {
4218f4a2713aSLionel Sambuc     Name = Importer.HandleNameConflict(Name, DC, Decl::IDNS_Ordinary,
4219f4a2713aSLionel Sambuc                                        ConflictingDecls.data(),
4220f4a2713aSLionel Sambuc                                        ConflictingDecls.size());
4221f4a2713aSLionel Sambuc   }
4222f4a2713aSLionel Sambuc 
4223f4a2713aSLionel Sambuc   if (!Name)
4224*0a6a1f1dSLionel Sambuc     return nullptr;
4225f4a2713aSLionel Sambuc 
4226f4a2713aSLionel Sambuc   VarDecl *DTemplated = D->getTemplatedDecl();
4227f4a2713aSLionel Sambuc 
4228f4a2713aSLionel Sambuc   // Import the type.
4229f4a2713aSLionel Sambuc   QualType T = Importer.Import(DTemplated->getType());
4230f4a2713aSLionel Sambuc   if (T.isNull())
4231*0a6a1f1dSLionel Sambuc     return nullptr;
4232f4a2713aSLionel Sambuc 
4233f4a2713aSLionel Sambuc   // Create the declaration that is being templated.
4234f4a2713aSLionel Sambuc   SourceLocation StartLoc = Importer.Import(DTemplated->getLocStart());
4235f4a2713aSLionel Sambuc   SourceLocation IdLoc = Importer.Import(DTemplated->getLocation());
4236f4a2713aSLionel Sambuc   TypeSourceInfo *TInfo = Importer.Import(DTemplated->getTypeSourceInfo());
4237f4a2713aSLionel Sambuc   VarDecl *D2Templated = VarDecl::Create(Importer.getToContext(), DC, StartLoc,
4238f4a2713aSLionel Sambuc                                          IdLoc, Name.getAsIdentifierInfo(), T,
4239f4a2713aSLionel Sambuc                                          TInfo, DTemplated->getStorageClass());
4240f4a2713aSLionel Sambuc   D2Templated->setAccess(DTemplated->getAccess());
4241f4a2713aSLionel Sambuc   D2Templated->setQualifierInfo(Importer.Import(DTemplated->getQualifierLoc()));
4242f4a2713aSLionel Sambuc   D2Templated->setLexicalDeclContext(LexicalDC);
4243f4a2713aSLionel Sambuc 
4244f4a2713aSLionel Sambuc   // Importer.Imported(DTemplated, D2Templated);
4245f4a2713aSLionel Sambuc   // LexicalDC->addDeclInternal(D2Templated);
4246f4a2713aSLionel Sambuc 
4247f4a2713aSLionel Sambuc   // Merge the initializer.
4248f4a2713aSLionel Sambuc   if (ImportDefinition(DTemplated, D2Templated))
4249*0a6a1f1dSLionel Sambuc     return nullptr;
4250f4a2713aSLionel Sambuc 
4251f4a2713aSLionel Sambuc   // Create the variable template declaration itself.
4252f4a2713aSLionel Sambuc   TemplateParameterList *TemplateParams =
4253f4a2713aSLionel Sambuc       ImportTemplateParameterList(D->getTemplateParameters());
4254f4a2713aSLionel Sambuc   if (!TemplateParams)
4255*0a6a1f1dSLionel Sambuc     return nullptr;
4256f4a2713aSLionel Sambuc 
4257f4a2713aSLionel Sambuc   VarTemplateDecl *D2 = VarTemplateDecl::Create(
4258*0a6a1f1dSLionel Sambuc       Importer.getToContext(), DC, Loc, Name, TemplateParams, D2Templated);
4259f4a2713aSLionel Sambuc   D2Templated->setDescribedVarTemplate(D2);
4260f4a2713aSLionel Sambuc 
4261f4a2713aSLionel Sambuc   D2->setAccess(D->getAccess());
4262f4a2713aSLionel Sambuc   D2->setLexicalDeclContext(LexicalDC);
4263f4a2713aSLionel Sambuc   LexicalDC->addDeclInternal(D2);
4264f4a2713aSLionel Sambuc 
4265f4a2713aSLionel Sambuc   // Note the relationship between the variable templates.
4266f4a2713aSLionel Sambuc   Importer.Imported(D, D2);
4267f4a2713aSLionel Sambuc   Importer.Imported(DTemplated, D2Templated);
4268f4a2713aSLionel Sambuc 
4269f4a2713aSLionel Sambuc   if (DTemplated->isThisDeclarationADefinition() &&
4270f4a2713aSLionel Sambuc       !D2Templated->isThisDeclarationADefinition()) {
4271f4a2713aSLionel Sambuc     // FIXME: Import definition!
4272f4a2713aSLionel Sambuc   }
4273f4a2713aSLionel Sambuc 
4274f4a2713aSLionel Sambuc   return D2;
4275f4a2713aSLionel Sambuc }
4276f4a2713aSLionel Sambuc 
VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl * D)4277f4a2713aSLionel Sambuc Decl *ASTNodeImporter::VisitVarTemplateSpecializationDecl(
4278f4a2713aSLionel Sambuc     VarTemplateSpecializationDecl *D) {
4279f4a2713aSLionel Sambuc   // If this record has a definition in the translation unit we're coming from,
4280f4a2713aSLionel Sambuc   // but this particular declaration is not that definition, import the
4281f4a2713aSLionel Sambuc   // definition and map to that.
4282f4a2713aSLionel Sambuc   VarDecl *Definition = D->getDefinition();
4283f4a2713aSLionel Sambuc   if (Definition && Definition != D) {
4284f4a2713aSLionel Sambuc     Decl *ImportedDef = Importer.Import(Definition);
4285f4a2713aSLionel Sambuc     if (!ImportedDef)
4286*0a6a1f1dSLionel Sambuc       return nullptr;
4287f4a2713aSLionel Sambuc 
4288f4a2713aSLionel Sambuc     return Importer.Imported(D, ImportedDef);
4289f4a2713aSLionel Sambuc   }
4290f4a2713aSLionel Sambuc 
4291f4a2713aSLionel Sambuc   VarTemplateDecl *VarTemplate = cast_or_null<VarTemplateDecl>(
4292f4a2713aSLionel Sambuc       Importer.Import(D->getSpecializedTemplate()));
4293f4a2713aSLionel Sambuc   if (!VarTemplate)
4294*0a6a1f1dSLionel Sambuc     return nullptr;
4295f4a2713aSLionel Sambuc 
4296f4a2713aSLionel Sambuc   // Import the context of this declaration.
4297f4a2713aSLionel Sambuc   DeclContext *DC = VarTemplate->getDeclContext();
4298f4a2713aSLionel Sambuc   if (!DC)
4299*0a6a1f1dSLionel Sambuc     return nullptr;
4300f4a2713aSLionel Sambuc 
4301f4a2713aSLionel Sambuc   DeclContext *LexicalDC = DC;
4302f4a2713aSLionel Sambuc   if (D->getDeclContext() != D->getLexicalDeclContext()) {
4303f4a2713aSLionel Sambuc     LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
4304f4a2713aSLionel Sambuc     if (!LexicalDC)
4305*0a6a1f1dSLionel Sambuc       return nullptr;
4306f4a2713aSLionel Sambuc   }
4307f4a2713aSLionel Sambuc 
4308f4a2713aSLionel Sambuc   // Import the location of this declaration.
4309f4a2713aSLionel Sambuc   SourceLocation StartLoc = Importer.Import(D->getLocStart());
4310f4a2713aSLionel Sambuc   SourceLocation IdLoc = Importer.Import(D->getLocation());
4311f4a2713aSLionel Sambuc 
4312f4a2713aSLionel Sambuc   // Import template arguments.
4313f4a2713aSLionel Sambuc   SmallVector<TemplateArgument, 2> TemplateArgs;
4314f4a2713aSLionel Sambuc   if (ImportTemplateArguments(D->getTemplateArgs().data(),
4315f4a2713aSLionel Sambuc                               D->getTemplateArgs().size(), TemplateArgs))
4316*0a6a1f1dSLionel Sambuc     return nullptr;
4317f4a2713aSLionel Sambuc 
4318f4a2713aSLionel Sambuc   // Try to find an existing specialization with these template arguments.
4319*0a6a1f1dSLionel Sambuc   void *InsertPos = nullptr;
4320f4a2713aSLionel Sambuc   VarTemplateSpecializationDecl *D2 = VarTemplate->findSpecialization(
4321*0a6a1f1dSLionel Sambuc       TemplateArgs, InsertPos);
4322f4a2713aSLionel Sambuc   if (D2) {
4323f4a2713aSLionel Sambuc     // We already have a variable template specialization with these template
4324f4a2713aSLionel Sambuc     // arguments.
4325f4a2713aSLionel Sambuc 
4326f4a2713aSLionel Sambuc     // FIXME: Check for specialization vs. instantiation errors.
4327f4a2713aSLionel Sambuc 
4328f4a2713aSLionel Sambuc     if (VarDecl *FoundDef = D2->getDefinition()) {
4329f4a2713aSLionel Sambuc       if (!D->isThisDeclarationADefinition() ||
4330f4a2713aSLionel Sambuc           IsStructuralMatch(D, FoundDef)) {
4331f4a2713aSLionel Sambuc         // The record types structurally match, or the "from" translation
4332f4a2713aSLionel Sambuc         // unit only had a forward declaration anyway; call it the same
4333f4a2713aSLionel Sambuc         // variable.
4334f4a2713aSLionel Sambuc         return Importer.Imported(D, FoundDef);
4335f4a2713aSLionel Sambuc       }
4336f4a2713aSLionel Sambuc     }
4337f4a2713aSLionel Sambuc   } else {
4338f4a2713aSLionel Sambuc 
4339f4a2713aSLionel Sambuc     // Import the type.
4340f4a2713aSLionel Sambuc     QualType T = Importer.Import(D->getType());
4341f4a2713aSLionel Sambuc     if (T.isNull())
4342*0a6a1f1dSLionel Sambuc       return nullptr;
4343f4a2713aSLionel Sambuc     TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
4344f4a2713aSLionel Sambuc 
4345f4a2713aSLionel Sambuc     // Create a new specialization.
4346f4a2713aSLionel Sambuc     D2 = VarTemplateSpecializationDecl::Create(
4347f4a2713aSLionel Sambuc         Importer.getToContext(), DC, StartLoc, IdLoc, VarTemplate, T, TInfo,
4348f4a2713aSLionel Sambuc         D->getStorageClass(), TemplateArgs.data(), TemplateArgs.size());
4349f4a2713aSLionel Sambuc     D2->setSpecializationKind(D->getSpecializationKind());
4350f4a2713aSLionel Sambuc     D2->setTemplateArgsInfo(D->getTemplateArgsInfo());
4351f4a2713aSLionel Sambuc 
4352f4a2713aSLionel Sambuc     // Add this specialization to the class template.
4353f4a2713aSLionel Sambuc     VarTemplate->AddSpecialization(D2, InsertPos);
4354f4a2713aSLionel Sambuc 
4355f4a2713aSLionel Sambuc     // Import the qualifier, if any.
4356f4a2713aSLionel Sambuc     D2->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
4357f4a2713aSLionel Sambuc 
4358f4a2713aSLionel Sambuc     // Add the specialization to this context.
4359f4a2713aSLionel Sambuc     D2->setLexicalDeclContext(LexicalDC);
4360f4a2713aSLionel Sambuc     LexicalDC->addDeclInternal(D2);
4361f4a2713aSLionel Sambuc   }
4362f4a2713aSLionel Sambuc   Importer.Imported(D, D2);
4363f4a2713aSLionel Sambuc 
4364f4a2713aSLionel Sambuc   if (D->isThisDeclarationADefinition() && ImportDefinition(D, D2))
4365*0a6a1f1dSLionel Sambuc     return nullptr;
4366f4a2713aSLionel Sambuc 
4367f4a2713aSLionel Sambuc   return D2;
4368f4a2713aSLionel Sambuc }
4369f4a2713aSLionel Sambuc 
4370f4a2713aSLionel Sambuc //----------------------------------------------------------------------------
4371f4a2713aSLionel Sambuc // Import Statements
4372f4a2713aSLionel Sambuc //----------------------------------------------------------------------------
4373f4a2713aSLionel Sambuc 
VisitStmt(Stmt * S)4374f4a2713aSLionel Sambuc Stmt *ASTNodeImporter::VisitStmt(Stmt *S) {
4375f4a2713aSLionel Sambuc   Importer.FromDiag(S->getLocStart(), diag::err_unsupported_ast_node)
4376f4a2713aSLionel Sambuc     << S->getStmtClassName();
4377*0a6a1f1dSLionel Sambuc   return nullptr;
4378f4a2713aSLionel Sambuc }
4379f4a2713aSLionel Sambuc 
4380f4a2713aSLionel Sambuc //----------------------------------------------------------------------------
4381f4a2713aSLionel Sambuc // Import Expressions
4382f4a2713aSLionel Sambuc //----------------------------------------------------------------------------
VisitExpr(Expr * E)4383f4a2713aSLionel Sambuc Expr *ASTNodeImporter::VisitExpr(Expr *E) {
4384f4a2713aSLionel Sambuc   Importer.FromDiag(E->getLocStart(), diag::err_unsupported_ast_node)
4385f4a2713aSLionel Sambuc     << E->getStmtClassName();
4386*0a6a1f1dSLionel Sambuc   return nullptr;
4387f4a2713aSLionel Sambuc }
4388f4a2713aSLionel Sambuc 
VisitDeclRefExpr(DeclRefExpr * E)4389f4a2713aSLionel Sambuc Expr *ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) {
4390f4a2713aSLionel Sambuc   ValueDecl *ToD = cast_or_null<ValueDecl>(Importer.Import(E->getDecl()));
4391f4a2713aSLionel Sambuc   if (!ToD)
4392*0a6a1f1dSLionel Sambuc     return nullptr;
4393f4a2713aSLionel Sambuc 
4394*0a6a1f1dSLionel Sambuc   NamedDecl *FoundD = nullptr;
4395f4a2713aSLionel Sambuc   if (E->getDecl() != E->getFoundDecl()) {
4396f4a2713aSLionel Sambuc     FoundD = cast_or_null<NamedDecl>(Importer.Import(E->getFoundDecl()));
4397f4a2713aSLionel Sambuc     if (!FoundD)
4398*0a6a1f1dSLionel Sambuc       return nullptr;
4399f4a2713aSLionel Sambuc   }
4400f4a2713aSLionel Sambuc 
4401f4a2713aSLionel Sambuc   QualType T = Importer.Import(E->getType());
4402f4a2713aSLionel Sambuc   if (T.isNull())
4403*0a6a1f1dSLionel Sambuc     return nullptr;
4404f4a2713aSLionel Sambuc 
4405f4a2713aSLionel Sambuc   DeclRefExpr *DRE = DeclRefExpr::Create(Importer.getToContext(),
4406f4a2713aSLionel Sambuc                                          Importer.Import(E->getQualifierLoc()),
4407f4a2713aSLionel Sambuc                                    Importer.Import(E->getTemplateKeywordLoc()),
4408f4a2713aSLionel Sambuc                                          ToD,
4409*0a6a1f1dSLionel Sambuc                                         E->refersToEnclosingVariableOrCapture(),
4410f4a2713aSLionel Sambuc                                          Importer.Import(E->getLocation()),
4411f4a2713aSLionel Sambuc                                          T, E->getValueKind(),
4412f4a2713aSLionel Sambuc                                          FoundD,
4413*0a6a1f1dSLionel Sambuc                                          /*FIXME:TemplateArgs=*/nullptr);
4414f4a2713aSLionel Sambuc   if (E->hadMultipleCandidates())
4415f4a2713aSLionel Sambuc     DRE->setHadMultipleCandidates(true);
4416f4a2713aSLionel Sambuc   return DRE;
4417f4a2713aSLionel Sambuc }
4418f4a2713aSLionel Sambuc 
VisitIntegerLiteral(IntegerLiteral * E)4419f4a2713aSLionel Sambuc Expr *ASTNodeImporter::VisitIntegerLiteral(IntegerLiteral *E) {
4420f4a2713aSLionel Sambuc   QualType T = Importer.Import(E->getType());
4421f4a2713aSLionel Sambuc   if (T.isNull())
4422*0a6a1f1dSLionel Sambuc     return nullptr;
4423f4a2713aSLionel Sambuc 
4424f4a2713aSLionel Sambuc   return IntegerLiteral::Create(Importer.getToContext(),
4425f4a2713aSLionel Sambuc                                 E->getValue(), T,
4426f4a2713aSLionel Sambuc                                 Importer.Import(E->getLocation()));
4427f4a2713aSLionel Sambuc }
4428f4a2713aSLionel Sambuc 
VisitCharacterLiteral(CharacterLiteral * E)4429f4a2713aSLionel Sambuc Expr *ASTNodeImporter::VisitCharacterLiteral(CharacterLiteral *E) {
4430f4a2713aSLionel Sambuc   QualType T = Importer.Import(E->getType());
4431f4a2713aSLionel Sambuc   if (T.isNull())
4432*0a6a1f1dSLionel Sambuc     return nullptr;
4433f4a2713aSLionel Sambuc 
4434f4a2713aSLionel Sambuc   return new (Importer.getToContext()) CharacterLiteral(E->getValue(),
4435f4a2713aSLionel Sambuc                                                         E->getKind(), T,
4436f4a2713aSLionel Sambuc                                           Importer.Import(E->getLocation()));
4437f4a2713aSLionel Sambuc }
4438f4a2713aSLionel Sambuc 
VisitParenExpr(ParenExpr * E)4439f4a2713aSLionel Sambuc Expr *ASTNodeImporter::VisitParenExpr(ParenExpr *E) {
4440f4a2713aSLionel Sambuc   Expr *SubExpr = Importer.Import(E->getSubExpr());
4441f4a2713aSLionel Sambuc   if (!SubExpr)
4442*0a6a1f1dSLionel Sambuc     return nullptr;
4443f4a2713aSLionel Sambuc 
4444f4a2713aSLionel Sambuc   return new (Importer.getToContext())
4445f4a2713aSLionel Sambuc                                   ParenExpr(Importer.Import(E->getLParen()),
4446f4a2713aSLionel Sambuc                                             Importer.Import(E->getRParen()),
4447f4a2713aSLionel Sambuc                                             SubExpr);
4448f4a2713aSLionel Sambuc }
4449f4a2713aSLionel Sambuc 
VisitUnaryOperator(UnaryOperator * E)4450f4a2713aSLionel Sambuc Expr *ASTNodeImporter::VisitUnaryOperator(UnaryOperator *E) {
4451f4a2713aSLionel Sambuc   QualType T = Importer.Import(E->getType());
4452f4a2713aSLionel Sambuc   if (T.isNull())
4453*0a6a1f1dSLionel Sambuc     return nullptr;
4454f4a2713aSLionel Sambuc 
4455f4a2713aSLionel Sambuc   Expr *SubExpr = Importer.Import(E->getSubExpr());
4456f4a2713aSLionel Sambuc   if (!SubExpr)
4457*0a6a1f1dSLionel Sambuc     return nullptr;
4458f4a2713aSLionel Sambuc 
4459f4a2713aSLionel Sambuc   return new (Importer.getToContext()) UnaryOperator(SubExpr, E->getOpcode(),
4460f4a2713aSLionel Sambuc                                                      T, E->getValueKind(),
4461f4a2713aSLionel Sambuc                                                      E->getObjectKind(),
4462f4a2713aSLionel Sambuc                                          Importer.Import(E->getOperatorLoc()));
4463f4a2713aSLionel Sambuc }
4464f4a2713aSLionel Sambuc 
VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr * E)4465f4a2713aSLionel Sambuc Expr *ASTNodeImporter::VisitUnaryExprOrTypeTraitExpr(
4466f4a2713aSLionel Sambuc                                             UnaryExprOrTypeTraitExpr *E) {
4467f4a2713aSLionel Sambuc   QualType ResultType = Importer.Import(E->getType());
4468f4a2713aSLionel Sambuc 
4469f4a2713aSLionel Sambuc   if (E->isArgumentType()) {
4470f4a2713aSLionel Sambuc     TypeSourceInfo *TInfo = Importer.Import(E->getArgumentTypeInfo());
4471f4a2713aSLionel Sambuc     if (!TInfo)
4472*0a6a1f1dSLionel Sambuc       return nullptr;
4473f4a2713aSLionel Sambuc 
4474f4a2713aSLionel Sambuc     return new (Importer.getToContext()) UnaryExprOrTypeTraitExpr(E->getKind(),
4475f4a2713aSLionel Sambuc                                            TInfo, ResultType,
4476f4a2713aSLionel Sambuc                                            Importer.Import(E->getOperatorLoc()),
4477f4a2713aSLionel Sambuc                                            Importer.Import(E->getRParenLoc()));
4478f4a2713aSLionel Sambuc   }
4479f4a2713aSLionel Sambuc 
4480f4a2713aSLionel Sambuc   Expr *SubExpr = Importer.Import(E->getArgumentExpr());
4481f4a2713aSLionel Sambuc   if (!SubExpr)
4482*0a6a1f1dSLionel Sambuc     return nullptr;
4483f4a2713aSLionel Sambuc 
4484f4a2713aSLionel Sambuc   return new (Importer.getToContext()) UnaryExprOrTypeTraitExpr(E->getKind(),
4485f4a2713aSLionel Sambuc                                           SubExpr, ResultType,
4486f4a2713aSLionel Sambuc                                           Importer.Import(E->getOperatorLoc()),
4487f4a2713aSLionel Sambuc                                           Importer.Import(E->getRParenLoc()));
4488f4a2713aSLionel Sambuc }
4489f4a2713aSLionel Sambuc 
VisitBinaryOperator(BinaryOperator * E)4490f4a2713aSLionel Sambuc Expr *ASTNodeImporter::VisitBinaryOperator(BinaryOperator *E) {
4491f4a2713aSLionel Sambuc   QualType T = Importer.Import(E->getType());
4492f4a2713aSLionel Sambuc   if (T.isNull())
4493*0a6a1f1dSLionel Sambuc     return nullptr;
4494f4a2713aSLionel Sambuc 
4495f4a2713aSLionel Sambuc   Expr *LHS = Importer.Import(E->getLHS());
4496f4a2713aSLionel Sambuc   if (!LHS)
4497*0a6a1f1dSLionel Sambuc     return nullptr;
4498f4a2713aSLionel Sambuc 
4499f4a2713aSLionel Sambuc   Expr *RHS = Importer.Import(E->getRHS());
4500f4a2713aSLionel Sambuc   if (!RHS)
4501*0a6a1f1dSLionel Sambuc     return nullptr;
4502f4a2713aSLionel Sambuc 
4503f4a2713aSLionel Sambuc   return new (Importer.getToContext()) BinaryOperator(LHS, RHS, E->getOpcode(),
4504f4a2713aSLionel Sambuc                                                       T, E->getValueKind(),
4505f4a2713aSLionel Sambuc                                                       E->getObjectKind(),
4506f4a2713aSLionel Sambuc                                            Importer.Import(E->getOperatorLoc()),
4507f4a2713aSLionel Sambuc                                                       E->isFPContractable());
4508f4a2713aSLionel Sambuc }
4509f4a2713aSLionel Sambuc 
VisitCompoundAssignOperator(CompoundAssignOperator * E)4510f4a2713aSLionel Sambuc Expr *ASTNodeImporter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
4511f4a2713aSLionel Sambuc   QualType T = Importer.Import(E->getType());
4512f4a2713aSLionel Sambuc   if (T.isNull())
4513*0a6a1f1dSLionel Sambuc     return nullptr;
4514f4a2713aSLionel Sambuc 
4515f4a2713aSLionel Sambuc   QualType CompLHSType = Importer.Import(E->getComputationLHSType());
4516f4a2713aSLionel Sambuc   if (CompLHSType.isNull())
4517*0a6a1f1dSLionel Sambuc     return nullptr;
4518f4a2713aSLionel Sambuc 
4519f4a2713aSLionel Sambuc   QualType CompResultType = Importer.Import(E->getComputationResultType());
4520f4a2713aSLionel Sambuc   if (CompResultType.isNull())
4521*0a6a1f1dSLionel Sambuc     return nullptr;
4522f4a2713aSLionel Sambuc 
4523f4a2713aSLionel Sambuc   Expr *LHS = Importer.Import(E->getLHS());
4524f4a2713aSLionel Sambuc   if (!LHS)
4525*0a6a1f1dSLionel Sambuc     return nullptr;
4526f4a2713aSLionel Sambuc 
4527f4a2713aSLionel Sambuc   Expr *RHS = Importer.Import(E->getRHS());
4528f4a2713aSLionel Sambuc   if (!RHS)
4529*0a6a1f1dSLionel Sambuc     return nullptr;
4530f4a2713aSLionel Sambuc 
4531f4a2713aSLionel Sambuc   return new (Importer.getToContext())
4532f4a2713aSLionel Sambuc                         CompoundAssignOperator(LHS, RHS, E->getOpcode(),
4533f4a2713aSLionel Sambuc                                                T, E->getValueKind(),
4534f4a2713aSLionel Sambuc                                                E->getObjectKind(),
4535f4a2713aSLionel Sambuc                                                CompLHSType, CompResultType,
4536f4a2713aSLionel Sambuc                                            Importer.Import(E->getOperatorLoc()),
4537f4a2713aSLionel Sambuc                                                E->isFPContractable());
4538f4a2713aSLionel Sambuc }
4539f4a2713aSLionel Sambuc 
ImportCastPath(CastExpr * E,CXXCastPath & Path)4540f4a2713aSLionel Sambuc static bool ImportCastPath(CastExpr *E, CXXCastPath &Path) {
4541f4a2713aSLionel Sambuc   if (E->path_empty()) return false;
4542f4a2713aSLionel Sambuc 
4543f4a2713aSLionel Sambuc   // TODO: import cast paths
4544f4a2713aSLionel Sambuc   return true;
4545f4a2713aSLionel Sambuc }
4546f4a2713aSLionel Sambuc 
VisitImplicitCastExpr(ImplicitCastExpr * E)4547f4a2713aSLionel Sambuc Expr *ASTNodeImporter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
4548f4a2713aSLionel Sambuc   QualType T = Importer.Import(E->getType());
4549f4a2713aSLionel Sambuc   if (T.isNull())
4550*0a6a1f1dSLionel Sambuc     return nullptr;
4551f4a2713aSLionel Sambuc 
4552f4a2713aSLionel Sambuc   Expr *SubExpr = Importer.Import(E->getSubExpr());
4553f4a2713aSLionel Sambuc   if (!SubExpr)
4554*0a6a1f1dSLionel Sambuc     return nullptr;
4555f4a2713aSLionel Sambuc 
4556f4a2713aSLionel Sambuc   CXXCastPath BasePath;
4557f4a2713aSLionel Sambuc   if (ImportCastPath(E, BasePath))
4558*0a6a1f1dSLionel Sambuc     return nullptr;
4559f4a2713aSLionel Sambuc 
4560f4a2713aSLionel Sambuc   return ImplicitCastExpr::Create(Importer.getToContext(), T, E->getCastKind(),
4561f4a2713aSLionel Sambuc                                   SubExpr, &BasePath, E->getValueKind());
4562f4a2713aSLionel Sambuc }
4563f4a2713aSLionel Sambuc 
VisitCStyleCastExpr(CStyleCastExpr * E)4564f4a2713aSLionel Sambuc Expr *ASTNodeImporter::VisitCStyleCastExpr(CStyleCastExpr *E) {
4565f4a2713aSLionel Sambuc   QualType T = Importer.Import(E->getType());
4566f4a2713aSLionel Sambuc   if (T.isNull())
4567*0a6a1f1dSLionel Sambuc     return nullptr;
4568f4a2713aSLionel Sambuc 
4569f4a2713aSLionel Sambuc   Expr *SubExpr = Importer.Import(E->getSubExpr());
4570f4a2713aSLionel Sambuc   if (!SubExpr)
4571*0a6a1f1dSLionel Sambuc     return nullptr;
4572f4a2713aSLionel Sambuc 
4573f4a2713aSLionel Sambuc   TypeSourceInfo *TInfo = Importer.Import(E->getTypeInfoAsWritten());
4574f4a2713aSLionel Sambuc   if (!TInfo && E->getTypeInfoAsWritten())
4575*0a6a1f1dSLionel Sambuc     return nullptr;
4576f4a2713aSLionel Sambuc 
4577f4a2713aSLionel Sambuc   CXXCastPath BasePath;
4578f4a2713aSLionel Sambuc   if (ImportCastPath(E, BasePath))
4579*0a6a1f1dSLionel Sambuc     return nullptr;
4580f4a2713aSLionel Sambuc 
4581f4a2713aSLionel Sambuc   return CStyleCastExpr::Create(Importer.getToContext(), T,
4582f4a2713aSLionel Sambuc                                 E->getValueKind(), E->getCastKind(),
4583f4a2713aSLionel Sambuc                                 SubExpr, &BasePath, TInfo,
4584f4a2713aSLionel Sambuc                                 Importer.Import(E->getLParenLoc()),
4585f4a2713aSLionel Sambuc                                 Importer.Import(E->getRParenLoc()));
4586f4a2713aSLionel Sambuc }
4587f4a2713aSLionel Sambuc 
ASTImporter(ASTContext & ToContext,FileManager & ToFileManager,ASTContext & FromContext,FileManager & FromFileManager,bool MinimalImport)4588f4a2713aSLionel Sambuc ASTImporter::ASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
4589f4a2713aSLionel Sambuc                          ASTContext &FromContext, FileManager &FromFileManager,
4590f4a2713aSLionel Sambuc                          bool MinimalImport)
4591f4a2713aSLionel Sambuc   : ToContext(ToContext), FromContext(FromContext),
4592f4a2713aSLionel Sambuc     ToFileManager(ToFileManager), FromFileManager(FromFileManager),
4593f4a2713aSLionel Sambuc     Minimal(MinimalImport), LastDiagFromFrom(false)
4594f4a2713aSLionel Sambuc {
4595f4a2713aSLionel Sambuc   ImportedDecls[FromContext.getTranslationUnitDecl()]
4596f4a2713aSLionel Sambuc     = ToContext.getTranslationUnitDecl();
4597f4a2713aSLionel Sambuc }
4598f4a2713aSLionel Sambuc 
~ASTImporter()4599f4a2713aSLionel Sambuc ASTImporter::~ASTImporter() { }
4600f4a2713aSLionel Sambuc 
Import(QualType FromT)4601f4a2713aSLionel Sambuc QualType ASTImporter::Import(QualType FromT) {
4602f4a2713aSLionel Sambuc   if (FromT.isNull())
4603f4a2713aSLionel Sambuc     return QualType();
4604f4a2713aSLionel Sambuc 
4605f4a2713aSLionel Sambuc   const Type *fromTy = FromT.getTypePtr();
4606f4a2713aSLionel Sambuc 
4607f4a2713aSLionel Sambuc   // Check whether we've already imported this type.
4608f4a2713aSLionel Sambuc   llvm::DenseMap<const Type *, const Type *>::iterator Pos
4609f4a2713aSLionel Sambuc     = ImportedTypes.find(fromTy);
4610f4a2713aSLionel Sambuc   if (Pos != ImportedTypes.end())
4611f4a2713aSLionel Sambuc     return ToContext.getQualifiedType(Pos->second, FromT.getLocalQualifiers());
4612f4a2713aSLionel Sambuc 
4613f4a2713aSLionel Sambuc   // Import the type
4614f4a2713aSLionel Sambuc   ASTNodeImporter Importer(*this);
4615f4a2713aSLionel Sambuc   QualType ToT = Importer.Visit(fromTy);
4616f4a2713aSLionel Sambuc   if (ToT.isNull())
4617f4a2713aSLionel Sambuc     return ToT;
4618f4a2713aSLionel Sambuc 
4619f4a2713aSLionel Sambuc   // Record the imported type.
4620f4a2713aSLionel Sambuc   ImportedTypes[fromTy] = ToT.getTypePtr();
4621f4a2713aSLionel Sambuc 
4622f4a2713aSLionel Sambuc   return ToContext.getQualifiedType(ToT, FromT.getLocalQualifiers());
4623f4a2713aSLionel Sambuc }
4624f4a2713aSLionel Sambuc 
Import(TypeSourceInfo * FromTSI)4625f4a2713aSLionel Sambuc TypeSourceInfo *ASTImporter::Import(TypeSourceInfo *FromTSI) {
4626f4a2713aSLionel Sambuc   if (!FromTSI)
4627f4a2713aSLionel Sambuc     return FromTSI;
4628f4a2713aSLionel Sambuc 
4629f4a2713aSLionel Sambuc   // FIXME: For now we just create a "trivial" type source info based
4630f4a2713aSLionel Sambuc   // on the type and a single location. Implement a real version of this.
4631f4a2713aSLionel Sambuc   QualType T = Import(FromTSI->getType());
4632f4a2713aSLionel Sambuc   if (T.isNull())
4633*0a6a1f1dSLionel Sambuc     return nullptr;
4634f4a2713aSLionel Sambuc 
4635f4a2713aSLionel Sambuc   return ToContext.getTrivialTypeSourceInfo(T,
4636f4a2713aSLionel Sambuc                         FromTSI->getTypeLoc().getLocStart());
4637f4a2713aSLionel Sambuc }
4638f4a2713aSLionel Sambuc 
Import(Decl * FromD)4639f4a2713aSLionel Sambuc Decl *ASTImporter::Import(Decl *FromD) {
4640f4a2713aSLionel Sambuc   if (!FromD)
4641*0a6a1f1dSLionel Sambuc     return nullptr;
4642f4a2713aSLionel Sambuc 
4643f4a2713aSLionel Sambuc   ASTNodeImporter Importer(*this);
4644f4a2713aSLionel Sambuc 
4645f4a2713aSLionel Sambuc   // Check whether we've already imported this declaration.
4646f4a2713aSLionel Sambuc   llvm::DenseMap<Decl *, Decl *>::iterator Pos = ImportedDecls.find(FromD);
4647f4a2713aSLionel Sambuc   if (Pos != ImportedDecls.end()) {
4648f4a2713aSLionel Sambuc     Decl *ToD = Pos->second;
4649f4a2713aSLionel Sambuc     Importer.ImportDefinitionIfNeeded(FromD, ToD);
4650f4a2713aSLionel Sambuc     return ToD;
4651f4a2713aSLionel Sambuc   }
4652f4a2713aSLionel Sambuc 
4653f4a2713aSLionel Sambuc   // Import the type
4654f4a2713aSLionel Sambuc   Decl *ToD = Importer.Visit(FromD);
4655f4a2713aSLionel Sambuc   if (!ToD)
4656*0a6a1f1dSLionel Sambuc     return nullptr;
4657f4a2713aSLionel Sambuc 
4658f4a2713aSLionel Sambuc   // Record the imported declaration.
4659f4a2713aSLionel Sambuc   ImportedDecls[FromD] = ToD;
4660f4a2713aSLionel Sambuc 
4661f4a2713aSLionel Sambuc   if (TagDecl *FromTag = dyn_cast<TagDecl>(FromD)) {
4662f4a2713aSLionel Sambuc     // Keep track of anonymous tags that have an associated typedef.
4663f4a2713aSLionel Sambuc     if (FromTag->getTypedefNameForAnonDecl())
4664f4a2713aSLionel Sambuc       AnonTagsWithPendingTypedefs.push_back(FromTag);
4665f4a2713aSLionel Sambuc   } else if (TypedefNameDecl *FromTypedef = dyn_cast<TypedefNameDecl>(FromD)) {
4666f4a2713aSLionel Sambuc     // When we've finished transforming a typedef, see whether it was the
4667f4a2713aSLionel Sambuc     // typedef for an anonymous tag.
4668f4a2713aSLionel Sambuc     for (SmallVectorImpl<TagDecl *>::iterator
4669f4a2713aSLionel Sambuc                FromTag = AnonTagsWithPendingTypedefs.begin(),
4670f4a2713aSLionel Sambuc             FromTagEnd = AnonTagsWithPendingTypedefs.end();
4671f4a2713aSLionel Sambuc          FromTag != FromTagEnd; ++FromTag) {
4672f4a2713aSLionel Sambuc       if ((*FromTag)->getTypedefNameForAnonDecl() == FromTypedef) {
4673f4a2713aSLionel Sambuc         if (TagDecl *ToTag = cast_or_null<TagDecl>(Import(*FromTag))) {
4674f4a2713aSLionel Sambuc           // We found the typedef for an anonymous tag; link them.
4675f4a2713aSLionel Sambuc           ToTag->setTypedefNameForAnonDecl(cast<TypedefNameDecl>(ToD));
4676f4a2713aSLionel Sambuc           AnonTagsWithPendingTypedefs.erase(FromTag);
4677f4a2713aSLionel Sambuc           break;
4678f4a2713aSLionel Sambuc         }
4679f4a2713aSLionel Sambuc       }
4680f4a2713aSLionel Sambuc     }
4681f4a2713aSLionel Sambuc   }
4682f4a2713aSLionel Sambuc 
4683f4a2713aSLionel Sambuc   return ToD;
4684f4a2713aSLionel Sambuc }
4685f4a2713aSLionel Sambuc 
ImportContext(DeclContext * FromDC)4686f4a2713aSLionel Sambuc DeclContext *ASTImporter::ImportContext(DeclContext *FromDC) {
4687f4a2713aSLionel Sambuc   if (!FromDC)
4688f4a2713aSLionel Sambuc     return FromDC;
4689f4a2713aSLionel Sambuc 
4690f4a2713aSLionel Sambuc   DeclContext *ToDC = cast_or_null<DeclContext>(Import(cast<Decl>(FromDC)));
4691f4a2713aSLionel Sambuc   if (!ToDC)
4692*0a6a1f1dSLionel Sambuc     return nullptr;
4693f4a2713aSLionel Sambuc 
4694f4a2713aSLionel Sambuc   // When we're using a record/enum/Objective-C class/protocol as a context, we
4695f4a2713aSLionel Sambuc   // need it to have a definition.
4696f4a2713aSLionel Sambuc   if (RecordDecl *ToRecord = dyn_cast<RecordDecl>(ToDC)) {
4697f4a2713aSLionel Sambuc     RecordDecl *FromRecord = cast<RecordDecl>(FromDC);
4698f4a2713aSLionel Sambuc     if (ToRecord->isCompleteDefinition()) {
4699f4a2713aSLionel Sambuc       // Do nothing.
4700f4a2713aSLionel Sambuc     } else if (FromRecord->isCompleteDefinition()) {
4701f4a2713aSLionel Sambuc       ASTNodeImporter(*this).ImportDefinition(FromRecord, ToRecord,
4702f4a2713aSLionel Sambuc                                               ASTNodeImporter::IDK_Basic);
4703f4a2713aSLionel Sambuc     } else {
4704f4a2713aSLionel Sambuc       CompleteDecl(ToRecord);
4705f4a2713aSLionel Sambuc     }
4706f4a2713aSLionel Sambuc   } else if (EnumDecl *ToEnum = dyn_cast<EnumDecl>(ToDC)) {
4707f4a2713aSLionel Sambuc     EnumDecl *FromEnum = cast<EnumDecl>(FromDC);
4708f4a2713aSLionel Sambuc     if (ToEnum->isCompleteDefinition()) {
4709f4a2713aSLionel Sambuc       // Do nothing.
4710f4a2713aSLionel Sambuc     } else if (FromEnum->isCompleteDefinition()) {
4711f4a2713aSLionel Sambuc       ASTNodeImporter(*this).ImportDefinition(FromEnum, ToEnum,
4712f4a2713aSLionel Sambuc                                               ASTNodeImporter::IDK_Basic);
4713f4a2713aSLionel Sambuc     } else {
4714f4a2713aSLionel Sambuc       CompleteDecl(ToEnum);
4715f4a2713aSLionel Sambuc     }
4716f4a2713aSLionel Sambuc   } else if (ObjCInterfaceDecl *ToClass = dyn_cast<ObjCInterfaceDecl>(ToDC)) {
4717f4a2713aSLionel Sambuc     ObjCInterfaceDecl *FromClass = cast<ObjCInterfaceDecl>(FromDC);
4718f4a2713aSLionel Sambuc     if (ToClass->getDefinition()) {
4719f4a2713aSLionel Sambuc       // Do nothing.
4720f4a2713aSLionel Sambuc     } else if (ObjCInterfaceDecl *FromDef = FromClass->getDefinition()) {
4721f4a2713aSLionel Sambuc       ASTNodeImporter(*this).ImportDefinition(FromDef, ToClass,
4722f4a2713aSLionel Sambuc                                               ASTNodeImporter::IDK_Basic);
4723f4a2713aSLionel Sambuc     } else {
4724f4a2713aSLionel Sambuc       CompleteDecl(ToClass);
4725f4a2713aSLionel Sambuc     }
4726f4a2713aSLionel Sambuc   } else if (ObjCProtocolDecl *ToProto = dyn_cast<ObjCProtocolDecl>(ToDC)) {
4727f4a2713aSLionel Sambuc     ObjCProtocolDecl *FromProto = cast<ObjCProtocolDecl>(FromDC);
4728f4a2713aSLionel Sambuc     if (ToProto->getDefinition()) {
4729f4a2713aSLionel Sambuc       // Do nothing.
4730f4a2713aSLionel Sambuc     } else if (ObjCProtocolDecl *FromDef = FromProto->getDefinition()) {
4731f4a2713aSLionel Sambuc       ASTNodeImporter(*this).ImportDefinition(FromDef, ToProto,
4732f4a2713aSLionel Sambuc                                               ASTNodeImporter::IDK_Basic);
4733f4a2713aSLionel Sambuc     } else {
4734f4a2713aSLionel Sambuc       CompleteDecl(ToProto);
4735f4a2713aSLionel Sambuc     }
4736f4a2713aSLionel Sambuc   }
4737f4a2713aSLionel Sambuc 
4738f4a2713aSLionel Sambuc   return ToDC;
4739f4a2713aSLionel Sambuc }
4740f4a2713aSLionel Sambuc 
Import(Expr * FromE)4741f4a2713aSLionel Sambuc Expr *ASTImporter::Import(Expr *FromE) {
4742f4a2713aSLionel Sambuc   if (!FromE)
4743*0a6a1f1dSLionel Sambuc     return nullptr;
4744f4a2713aSLionel Sambuc 
4745f4a2713aSLionel Sambuc   return cast_or_null<Expr>(Import(cast<Stmt>(FromE)));
4746f4a2713aSLionel Sambuc }
4747f4a2713aSLionel Sambuc 
Import(Stmt * FromS)4748f4a2713aSLionel Sambuc Stmt *ASTImporter::Import(Stmt *FromS) {
4749f4a2713aSLionel Sambuc   if (!FromS)
4750*0a6a1f1dSLionel Sambuc     return nullptr;
4751f4a2713aSLionel Sambuc 
4752f4a2713aSLionel Sambuc   // Check whether we've already imported this declaration.
4753f4a2713aSLionel Sambuc   llvm::DenseMap<Stmt *, Stmt *>::iterator Pos = ImportedStmts.find(FromS);
4754f4a2713aSLionel Sambuc   if (Pos != ImportedStmts.end())
4755f4a2713aSLionel Sambuc     return Pos->second;
4756f4a2713aSLionel Sambuc 
4757f4a2713aSLionel Sambuc   // Import the type
4758f4a2713aSLionel Sambuc   ASTNodeImporter Importer(*this);
4759f4a2713aSLionel Sambuc   Stmt *ToS = Importer.Visit(FromS);
4760f4a2713aSLionel Sambuc   if (!ToS)
4761*0a6a1f1dSLionel Sambuc     return nullptr;
4762f4a2713aSLionel Sambuc 
4763f4a2713aSLionel Sambuc   // Record the imported declaration.
4764f4a2713aSLionel Sambuc   ImportedStmts[FromS] = ToS;
4765f4a2713aSLionel Sambuc   return ToS;
4766f4a2713aSLionel Sambuc }
4767f4a2713aSLionel Sambuc 
Import(NestedNameSpecifier * FromNNS)4768f4a2713aSLionel Sambuc NestedNameSpecifier *ASTImporter::Import(NestedNameSpecifier *FromNNS) {
4769f4a2713aSLionel Sambuc   if (!FromNNS)
4770*0a6a1f1dSLionel Sambuc     return nullptr;
4771f4a2713aSLionel Sambuc 
4772f4a2713aSLionel Sambuc   NestedNameSpecifier *prefix = Import(FromNNS->getPrefix());
4773f4a2713aSLionel Sambuc 
4774f4a2713aSLionel Sambuc   switch (FromNNS->getKind()) {
4775f4a2713aSLionel Sambuc   case NestedNameSpecifier::Identifier:
4776f4a2713aSLionel Sambuc     if (IdentifierInfo *II = Import(FromNNS->getAsIdentifier())) {
4777f4a2713aSLionel Sambuc       return NestedNameSpecifier::Create(ToContext, prefix, II);
4778f4a2713aSLionel Sambuc     }
4779*0a6a1f1dSLionel Sambuc     return nullptr;
4780f4a2713aSLionel Sambuc 
4781f4a2713aSLionel Sambuc   case NestedNameSpecifier::Namespace:
4782f4a2713aSLionel Sambuc     if (NamespaceDecl *NS =
4783f4a2713aSLionel Sambuc           cast<NamespaceDecl>(Import(FromNNS->getAsNamespace()))) {
4784f4a2713aSLionel Sambuc       return NestedNameSpecifier::Create(ToContext, prefix, NS);
4785f4a2713aSLionel Sambuc     }
4786*0a6a1f1dSLionel Sambuc     return nullptr;
4787f4a2713aSLionel Sambuc 
4788f4a2713aSLionel Sambuc   case NestedNameSpecifier::NamespaceAlias:
4789f4a2713aSLionel Sambuc     if (NamespaceAliasDecl *NSAD =
4790f4a2713aSLionel Sambuc           cast<NamespaceAliasDecl>(Import(FromNNS->getAsNamespaceAlias()))) {
4791f4a2713aSLionel Sambuc       return NestedNameSpecifier::Create(ToContext, prefix, NSAD);
4792f4a2713aSLionel Sambuc     }
4793*0a6a1f1dSLionel Sambuc     return nullptr;
4794f4a2713aSLionel Sambuc 
4795f4a2713aSLionel Sambuc   case NestedNameSpecifier::Global:
4796f4a2713aSLionel Sambuc     return NestedNameSpecifier::GlobalSpecifier(ToContext);
4797f4a2713aSLionel Sambuc 
4798*0a6a1f1dSLionel Sambuc   case NestedNameSpecifier::Super:
4799*0a6a1f1dSLionel Sambuc     if (CXXRecordDecl *RD =
4800*0a6a1f1dSLionel Sambuc             cast<CXXRecordDecl>(Import(FromNNS->getAsRecordDecl()))) {
4801*0a6a1f1dSLionel Sambuc       return NestedNameSpecifier::SuperSpecifier(ToContext, RD);
4802*0a6a1f1dSLionel Sambuc     }
4803*0a6a1f1dSLionel Sambuc     return nullptr;
4804*0a6a1f1dSLionel Sambuc 
4805f4a2713aSLionel Sambuc   case NestedNameSpecifier::TypeSpec:
4806f4a2713aSLionel Sambuc   case NestedNameSpecifier::TypeSpecWithTemplate: {
4807f4a2713aSLionel Sambuc       QualType T = Import(QualType(FromNNS->getAsType(), 0u));
4808f4a2713aSLionel Sambuc       if (!T.isNull()) {
4809f4a2713aSLionel Sambuc         bool bTemplate = FromNNS->getKind() ==
4810f4a2713aSLionel Sambuc                          NestedNameSpecifier::TypeSpecWithTemplate;
4811f4a2713aSLionel Sambuc         return NestedNameSpecifier::Create(ToContext, prefix,
4812f4a2713aSLionel Sambuc                                            bTemplate, T.getTypePtr());
4813f4a2713aSLionel Sambuc       }
4814f4a2713aSLionel Sambuc     }
4815*0a6a1f1dSLionel Sambuc       return nullptr;
4816f4a2713aSLionel Sambuc   }
4817f4a2713aSLionel Sambuc 
4818f4a2713aSLionel Sambuc   llvm_unreachable("Invalid nested name specifier kind");
4819f4a2713aSLionel Sambuc }
4820f4a2713aSLionel Sambuc 
Import(NestedNameSpecifierLoc FromNNS)4821f4a2713aSLionel Sambuc NestedNameSpecifierLoc ASTImporter::Import(NestedNameSpecifierLoc FromNNS) {
4822f4a2713aSLionel Sambuc   // FIXME: Implement!
4823f4a2713aSLionel Sambuc   return NestedNameSpecifierLoc();
4824f4a2713aSLionel Sambuc }
4825f4a2713aSLionel Sambuc 
Import(TemplateName From)4826f4a2713aSLionel Sambuc TemplateName ASTImporter::Import(TemplateName From) {
4827f4a2713aSLionel Sambuc   switch (From.getKind()) {
4828f4a2713aSLionel Sambuc   case TemplateName::Template:
4829f4a2713aSLionel Sambuc     if (TemplateDecl *ToTemplate
4830f4a2713aSLionel Sambuc                 = cast_or_null<TemplateDecl>(Import(From.getAsTemplateDecl())))
4831f4a2713aSLionel Sambuc       return TemplateName(ToTemplate);
4832f4a2713aSLionel Sambuc 
4833f4a2713aSLionel Sambuc     return TemplateName();
4834f4a2713aSLionel Sambuc 
4835f4a2713aSLionel Sambuc   case TemplateName::OverloadedTemplate: {
4836f4a2713aSLionel Sambuc     OverloadedTemplateStorage *FromStorage = From.getAsOverloadedTemplate();
4837f4a2713aSLionel Sambuc     UnresolvedSet<2> ToTemplates;
4838f4a2713aSLionel Sambuc     for (OverloadedTemplateStorage::iterator I = FromStorage->begin(),
4839f4a2713aSLionel Sambuc                                              E = FromStorage->end();
4840f4a2713aSLionel Sambuc          I != E; ++I) {
4841f4a2713aSLionel Sambuc       if (NamedDecl *To = cast_or_null<NamedDecl>(Import(*I)))
4842f4a2713aSLionel Sambuc         ToTemplates.addDecl(To);
4843f4a2713aSLionel Sambuc       else
4844f4a2713aSLionel Sambuc         return TemplateName();
4845f4a2713aSLionel Sambuc     }
4846f4a2713aSLionel Sambuc     return ToContext.getOverloadedTemplateName(ToTemplates.begin(),
4847f4a2713aSLionel Sambuc                                                ToTemplates.end());
4848f4a2713aSLionel Sambuc   }
4849f4a2713aSLionel Sambuc 
4850f4a2713aSLionel Sambuc   case TemplateName::QualifiedTemplate: {
4851f4a2713aSLionel Sambuc     QualifiedTemplateName *QTN = From.getAsQualifiedTemplateName();
4852f4a2713aSLionel Sambuc     NestedNameSpecifier *Qualifier = Import(QTN->getQualifier());
4853f4a2713aSLionel Sambuc     if (!Qualifier)
4854f4a2713aSLionel Sambuc       return TemplateName();
4855f4a2713aSLionel Sambuc 
4856f4a2713aSLionel Sambuc     if (TemplateDecl *ToTemplate
4857f4a2713aSLionel Sambuc         = cast_or_null<TemplateDecl>(Import(From.getAsTemplateDecl())))
4858f4a2713aSLionel Sambuc       return ToContext.getQualifiedTemplateName(Qualifier,
4859f4a2713aSLionel Sambuc                                                 QTN->hasTemplateKeyword(),
4860f4a2713aSLionel Sambuc                                                 ToTemplate);
4861f4a2713aSLionel Sambuc 
4862f4a2713aSLionel Sambuc     return TemplateName();
4863f4a2713aSLionel Sambuc   }
4864f4a2713aSLionel Sambuc 
4865f4a2713aSLionel Sambuc   case TemplateName::DependentTemplate: {
4866f4a2713aSLionel Sambuc     DependentTemplateName *DTN = From.getAsDependentTemplateName();
4867f4a2713aSLionel Sambuc     NestedNameSpecifier *Qualifier = Import(DTN->getQualifier());
4868f4a2713aSLionel Sambuc     if (!Qualifier)
4869f4a2713aSLionel Sambuc       return TemplateName();
4870f4a2713aSLionel Sambuc 
4871f4a2713aSLionel Sambuc     if (DTN->isIdentifier()) {
4872f4a2713aSLionel Sambuc       return ToContext.getDependentTemplateName(Qualifier,
4873f4a2713aSLionel Sambuc                                                 Import(DTN->getIdentifier()));
4874f4a2713aSLionel Sambuc     }
4875f4a2713aSLionel Sambuc 
4876f4a2713aSLionel Sambuc     return ToContext.getDependentTemplateName(Qualifier, DTN->getOperator());
4877f4a2713aSLionel Sambuc   }
4878f4a2713aSLionel Sambuc 
4879f4a2713aSLionel Sambuc   case TemplateName::SubstTemplateTemplateParm: {
4880f4a2713aSLionel Sambuc     SubstTemplateTemplateParmStorage *subst
4881f4a2713aSLionel Sambuc       = From.getAsSubstTemplateTemplateParm();
4882f4a2713aSLionel Sambuc     TemplateTemplateParmDecl *param
4883f4a2713aSLionel Sambuc       = cast_or_null<TemplateTemplateParmDecl>(Import(subst->getParameter()));
4884f4a2713aSLionel Sambuc     if (!param)
4885f4a2713aSLionel Sambuc       return TemplateName();
4886f4a2713aSLionel Sambuc 
4887f4a2713aSLionel Sambuc     TemplateName replacement = Import(subst->getReplacement());
4888f4a2713aSLionel Sambuc     if (replacement.isNull()) return TemplateName();
4889f4a2713aSLionel Sambuc 
4890f4a2713aSLionel Sambuc     return ToContext.getSubstTemplateTemplateParm(param, replacement);
4891f4a2713aSLionel Sambuc   }
4892f4a2713aSLionel Sambuc 
4893f4a2713aSLionel Sambuc   case TemplateName::SubstTemplateTemplateParmPack: {
4894f4a2713aSLionel Sambuc     SubstTemplateTemplateParmPackStorage *SubstPack
4895f4a2713aSLionel Sambuc       = From.getAsSubstTemplateTemplateParmPack();
4896f4a2713aSLionel Sambuc     TemplateTemplateParmDecl *Param
4897f4a2713aSLionel Sambuc       = cast_or_null<TemplateTemplateParmDecl>(
4898f4a2713aSLionel Sambuc                                         Import(SubstPack->getParameterPack()));
4899f4a2713aSLionel Sambuc     if (!Param)
4900f4a2713aSLionel Sambuc       return TemplateName();
4901f4a2713aSLionel Sambuc 
4902f4a2713aSLionel Sambuc     ASTNodeImporter Importer(*this);
4903f4a2713aSLionel Sambuc     TemplateArgument ArgPack
4904f4a2713aSLionel Sambuc       = Importer.ImportTemplateArgument(SubstPack->getArgumentPack());
4905f4a2713aSLionel Sambuc     if (ArgPack.isNull())
4906f4a2713aSLionel Sambuc       return TemplateName();
4907f4a2713aSLionel Sambuc 
4908f4a2713aSLionel Sambuc     return ToContext.getSubstTemplateTemplateParmPack(Param, ArgPack);
4909f4a2713aSLionel Sambuc   }
4910f4a2713aSLionel Sambuc   }
4911f4a2713aSLionel Sambuc 
4912f4a2713aSLionel Sambuc   llvm_unreachable("Invalid template name kind");
4913f4a2713aSLionel Sambuc }
4914f4a2713aSLionel Sambuc 
Import(SourceLocation FromLoc)4915f4a2713aSLionel Sambuc SourceLocation ASTImporter::Import(SourceLocation FromLoc) {
4916f4a2713aSLionel Sambuc   if (FromLoc.isInvalid())
4917f4a2713aSLionel Sambuc     return SourceLocation();
4918f4a2713aSLionel Sambuc 
4919f4a2713aSLionel Sambuc   SourceManager &FromSM = FromContext.getSourceManager();
4920f4a2713aSLionel Sambuc 
4921f4a2713aSLionel Sambuc   // For now, map everything down to its spelling location, so that we
4922f4a2713aSLionel Sambuc   // don't have to import macro expansions.
4923f4a2713aSLionel Sambuc   // FIXME: Import macro expansions!
4924f4a2713aSLionel Sambuc   FromLoc = FromSM.getSpellingLoc(FromLoc);
4925f4a2713aSLionel Sambuc   std::pair<FileID, unsigned> Decomposed = FromSM.getDecomposedLoc(FromLoc);
4926f4a2713aSLionel Sambuc   SourceManager &ToSM = ToContext.getSourceManager();
4927*0a6a1f1dSLionel Sambuc   FileID ToFileID = Import(Decomposed.first);
4928*0a6a1f1dSLionel Sambuc   if (ToFileID.isInvalid())
4929*0a6a1f1dSLionel Sambuc     return SourceLocation();
4930*0a6a1f1dSLionel Sambuc   return ToSM.getLocForStartOfFile(ToFileID)
4931f4a2713aSLionel Sambuc              .getLocWithOffset(Decomposed.second);
4932f4a2713aSLionel Sambuc }
4933f4a2713aSLionel Sambuc 
Import(SourceRange FromRange)4934f4a2713aSLionel Sambuc SourceRange ASTImporter::Import(SourceRange FromRange) {
4935f4a2713aSLionel Sambuc   return SourceRange(Import(FromRange.getBegin()), Import(FromRange.getEnd()));
4936f4a2713aSLionel Sambuc }
4937f4a2713aSLionel Sambuc 
Import(FileID FromID)4938f4a2713aSLionel Sambuc FileID ASTImporter::Import(FileID FromID) {
4939f4a2713aSLionel Sambuc   llvm::DenseMap<FileID, FileID>::iterator Pos
4940f4a2713aSLionel Sambuc     = ImportedFileIDs.find(FromID);
4941f4a2713aSLionel Sambuc   if (Pos != ImportedFileIDs.end())
4942f4a2713aSLionel Sambuc     return Pos->second;
4943f4a2713aSLionel Sambuc 
4944f4a2713aSLionel Sambuc   SourceManager &FromSM = FromContext.getSourceManager();
4945f4a2713aSLionel Sambuc   SourceManager &ToSM = ToContext.getSourceManager();
4946f4a2713aSLionel Sambuc   const SrcMgr::SLocEntry &FromSLoc = FromSM.getSLocEntry(FromID);
4947f4a2713aSLionel Sambuc   assert(FromSLoc.isFile() && "Cannot handle macro expansions yet");
4948f4a2713aSLionel Sambuc 
4949f4a2713aSLionel Sambuc   // Include location of this file.
4950f4a2713aSLionel Sambuc   SourceLocation ToIncludeLoc = Import(FromSLoc.getFile().getIncludeLoc());
4951f4a2713aSLionel Sambuc 
4952f4a2713aSLionel Sambuc   // Map the FileID for to the "to" source manager.
4953f4a2713aSLionel Sambuc   FileID ToID;
4954f4a2713aSLionel Sambuc   const SrcMgr::ContentCache *Cache = FromSLoc.getFile().getContentCache();
4955f4a2713aSLionel Sambuc   if (Cache->OrigEntry) {
4956f4a2713aSLionel Sambuc     // FIXME: We probably want to use getVirtualFile(), so we don't hit the
4957f4a2713aSLionel Sambuc     // disk again
4958f4a2713aSLionel Sambuc     // FIXME: We definitely want to re-use the existing MemoryBuffer, rather
4959f4a2713aSLionel Sambuc     // than mmap the files several times.
4960f4a2713aSLionel Sambuc     const FileEntry *Entry = ToFileManager.getFile(Cache->OrigEntry->getName());
4961*0a6a1f1dSLionel Sambuc     if (!Entry)
4962*0a6a1f1dSLionel Sambuc       return FileID();
4963f4a2713aSLionel Sambuc     ToID = ToSM.createFileID(Entry, ToIncludeLoc,
4964f4a2713aSLionel Sambuc                              FromSLoc.getFile().getFileCharacteristic());
4965f4a2713aSLionel Sambuc   } else {
4966f4a2713aSLionel Sambuc     // FIXME: We want to re-use the existing MemoryBuffer!
4967f4a2713aSLionel Sambuc     const llvm::MemoryBuffer *
4968f4a2713aSLionel Sambuc         FromBuf = Cache->getBuffer(FromContext.getDiagnostics(), FromSM);
4969*0a6a1f1dSLionel Sambuc     std::unique_ptr<llvm::MemoryBuffer> ToBuf
4970f4a2713aSLionel Sambuc       = llvm::MemoryBuffer::getMemBufferCopy(FromBuf->getBuffer(),
4971f4a2713aSLionel Sambuc                                              FromBuf->getBufferIdentifier());
4972*0a6a1f1dSLionel Sambuc     ToID = ToSM.createFileID(std::move(ToBuf),
4973f4a2713aSLionel Sambuc                              FromSLoc.getFile().getFileCharacteristic());
4974f4a2713aSLionel Sambuc   }
4975f4a2713aSLionel Sambuc 
4976f4a2713aSLionel Sambuc 
4977f4a2713aSLionel Sambuc   ImportedFileIDs[FromID] = ToID;
4978f4a2713aSLionel Sambuc   return ToID;
4979f4a2713aSLionel Sambuc }
4980f4a2713aSLionel Sambuc 
ImportDefinition(Decl * From)4981f4a2713aSLionel Sambuc void ASTImporter::ImportDefinition(Decl *From) {
4982f4a2713aSLionel Sambuc   Decl *To = Import(From);
4983f4a2713aSLionel Sambuc   if (!To)
4984f4a2713aSLionel Sambuc     return;
4985f4a2713aSLionel Sambuc 
4986f4a2713aSLionel Sambuc   if (DeclContext *FromDC = cast<DeclContext>(From)) {
4987f4a2713aSLionel Sambuc     ASTNodeImporter Importer(*this);
4988f4a2713aSLionel Sambuc 
4989f4a2713aSLionel Sambuc     if (RecordDecl *ToRecord = dyn_cast<RecordDecl>(To)) {
4990f4a2713aSLionel Sambuc       if (!ToRecord->getDefinition()) {
4991f4a2713aSLionel Sambuc         Importer.ImportDefinition(cast<RecordDecl>(FromDC), ToRecord,
4992f4a2713aSLionel Sambuc                                   ASTNodeImporter::IDK_Everything);
4993f4a2713aSLionel Sambuc         return;
4994f4a2713aSLionel Sambuc       }
4995f4a2713aSLionel Sambuc     }
4996f4a2713aSLionel Sambuc 
4997f4a2713aSLionel Sambuc     if (EnumDecl *ToEnum = dyn_cast<EnumDecl>(To)) {
4998f4a2713aSLionel Sambuc       if (!ToEnum->getDefinition()) {
4999f4a2713aSLionel Sambuc         Importer.ImportDefinition(cast<EnumDecl>(FromDC), ToEnum,
5000f4a2713aSLionel Sambuc                                   ASTNodeImporter::IDK_Everything);
5001f4a2713aSLionel Sambuc         return;
5002f4a2713aSLionel Sambuc       }
5003f4a2713aSLionel Sambuc     }
5004f4a2713aSLionel Sambuc 
5005f4a2713aSLionel Sambuc     if (ObjCInterfaceDecl *ToIFace = dyn_cast<ObjCInterfaceDecl>(To)) {
5006f4a2713aSLionel Sambuc       if (!ToIFace->getDefinition()) {
5007f4a2713aSLionel Sambuc         Importer.ImportDefinition(cast<ObjCInterfaceDecl>(FromDC), ToIFace,
5008f4a2713aSLionel Sambuc                                   ASTNodeImporter::IDK_Everything);
5009f4a2713aSLionel Sambuc         return;
5010f4a2713aSLionel Sambuc       }
5011f4a2713aSLionel Sambuc     }
5012f4a2713aSLionel Sambuc 
5013f4a2713aSLionel Sambuc     if (ObjCProtocolDecl *ToProto = dyn_cast<ObjCProtocolDecl>(To)) {
5014f4a2713aSLionel Sambuc       if (!ToProto->getDefinition()) {
5015f4a2713aSLionel Sambuc         Importer.ImportDefinition(cast<ObjCProtocolDecl>(FromDC), ToProto,
5016f4a2713aSLionel Sambuc                                   ASTNodeImporter::IDK_Everything);
5017f4a2713aSLionel Sambuc         return;
5018f4a2713aSLionel Sambuc       }
5019f4a2713aSLionel Sambuc     }
5020f4a2713aSLionel Sambuc 
5021f4a2713aSLionel Sambuc     Importer.ImportDeclContext(FromDC, true);
5022f4a2713aSLionel Sambuc   }
5023f4a2713aSLionel Sambuc }
5024f4a2713aSLionel Sambuc 
Import(DeclarationName FromName)5025f4a2713aSLionel Sambuc DeclarationName ASTImporter::Import(DeclarationName FromName) {
5026f4a2713aSLionel Sambuc   if (!FromName)
5027f4a2713aSLionel Sambuc     return DeclarationName();
5028f4a2713aSLionel Sambuc 
5029f4a2713aSLionel Sambuc   switch (FromName.getNameKind()) {
5030f4a2713aSLionel Sambuc   case DeclarationName::Identifier:
5031f4a2713aSLionel Sambuc     return Import(FromName.getAsIdentifierInfo());
5032f4a2713aSLionel Sambuc 
5033f4a2713aSLionel Sambuc   case DeclarationName::ObjCZeroArgSelector:
5034f4a2713aSLionel Sambuc   case DeclarationName::ObjCOneArgSelector:
5035f4a2713aSLionel Sambuc   case DeclarationName::ObjCMultiArgSelector:
5036f4a2713aSLionel Sambuc     return Import(FromName.getObjCSelector());
5037f4a2713aSLionel Sambuc 
5038f4a2713aSLionel Sambuc   case DeclarationName::CXXConstructorName: {
5039f4a2713aSLionel Sambuc     QualType T = Import(FromName.getCXXNameType());
5040f4a2713aSLionel Sambuc     if (T.isNull())
5041f4a2713aSLionel Sambuc       return DeclarationName();
5042f4a2713aSLionel Sambuc 
5043f4a2713aSLionel Sambuc     return ToContext.DeclarationNames.getCXXConstructorName(
5044f4a2713aSLionel Sambuc                                                ToContext.getCanonicalType(T));
5045f4a2713aSLionel Sambuc   }
5046f4a2713aSLionel Sambuc 
5047f4a2713aSLionel Sambuc   case DeclarationName::CXXDestructorName: {
5048f4a2713aSLionel Sambuc     QualType T = Import(FromName.getCXXNameType());
5049f4a2713aSLionel Sambuc     if (T.isNull())
5050f4a2713aSLionel Sambuc       return DeclarationName();
5051f4a2713aSLionel Sambuc 
5052f4a2713aSLionel Sambuc     return ToContext.DeclarationNames.getCXXDestructorName(
5053f4a2713aSLionel Sambuc                                                ToContext.getCanonicalType(T));
5054f4a2713aSLionel Sambuc   }
5055f4a2713aSLionel Sambuc 
5056f4a2713aSLionel Sambuc   case DeclarationName::CXXConversionFunctionName: {
5057f4a2713aSLionel Sambuc     QualType T = Import(FromName.getCXXNameType());
5058f4a2713aSLionel Sambuc     if (T.isNull())
5059f4a2713aSLionel Sambuc       return DeclarationName();
5060f4a2713aSLionel Sambuc 
5061f4a2713aSLionel Sambuc     return ToContext.DeclarationNames.getCXXConversionFunctionName(
5062f4a2713aSLionel Sambuc                                                ToContext.getCanonicalType(T));
5063f4a2713aSLionel Sambuc   }
5064f4a2713aSLionel Sambuc 
5065f4a2713aSLionel Sambuc   case DeclarationName::CXXOperatorName:
5066f4a2713aSLionel Sambuc     return ToContext.DeclarationNames.getCXXOperatorName(
5067f4a2713aSLionel Sambuc                                           FromName.getCXXOverloadedOperator());
5068f4a2713aSLionel Sambuc 
5069f4a2713aSLionel Sambuc   case DeclarationName::CXXLiteralOperatorName:
5070f4a2713aSLionel Sambuc     return ToContext.DeclarationNames.getCXXLiteralOperatorName(
5071f4a2713aSLionel Sambuc                                    Import(FromName.getCXXLiteralIdentifier()));
5072f4a2713aSLionel Sambuc 
5073f4a2713aSLionel Sambuc   case DeclarationName::CXXUsingDirective:
5074f4a2713aSLionel Sambuc     // FIXME: STATICS!
5075f4a2713aSLionel Sambuc     return DeclarationName::getUsingDirectiveName();
5076f4a2713aSLionel Sambuc   }
5077f4a2713aSLionel Sambuc 
5078f4a2713aSLionel Sambuc   llvm_unreachable("Invalid DeclarationName Kind!");
5079f4a2713aSLionel Sambuc }
5080f4a2713aSLionel Sambuc 
Import(const IdentifierInfo * FromId)5081f4a2713aSLionel Sambuc IdentifierInfo *ASTImporter::Import(const IdentifierInfo *FromId) {
5082f4a2713aSLionel Sambuc   if (!FromId)
5083*0a6a1f1dSLionel Sambuc     return nullptr;
5084f4a2713aSLionel Sambuc 
5085f4a2713aSLionel Sambuc   return &ToContext.Idents.get(FromId->getName());
5086f4a2713aSLionel Sambuc }
5087f4a2713aSLionel Sambuc 
Import(Selector FromSel)5088f4a2713aSLionel Sambuc Selector ASTImporter::Import(Selector FromSel) {
5089f4a2713aSLionel Sambuc   if (FromSel.isNull())
5090f4a2713aSLionel Sambuc     return Selector();
5091f4a2713aSLionel Sambuc 
5092f4a2713aSLionel Sambuc   SmallVector<IdentifierInfo *, 4> Idents;
5093f4a2713aSLionel Sambuc   Idents.push_back(Import(FromSel.getIdentifierInfoForSlot(0)));
5094f4a2713aSLionel Sambuc   for (unsigned I = 1, N = FromSel.getNumArgs(); I < N; ++I)
5095f4a2713aSLionel Sambuc     Idents.push_back(Import(FromSel.getIdentifierInfoForSlot(I)));
5096f4a2713aSLionel Sambuc   return ToContext.Selectors.getSelector(FromSel.getNumArgs(), Idents.data());
5097f4a2713aSLionel Sambuc }
5098f4a2713aSLionel Sambuc 
HandleNameConflict(DeclarationName Name,DeclContext * DC,unsigned IDNS,NamedDecl ** Decls,unsigned NumDecls)5099f4a2713aSLionel Sambuc DeclarationName ASTImporter::HandleNameConflict(DeclarationName Name,
5100f4a2713aSLionel Sambuc                                                 DeclContext *DC,
5101f4a2713aSLionel Sambuc                                                 unsigned IDNS,
5102f4a2713aSLionel Sambuc                                                 NamedDecl **Decls,
5103f4a2713aSLionel Sambuc                                                 unsigned NumDecls) {
5104f4a2713aSLionel Sambuc   return Name;
5105f4a2713aSLionel Sambuc }
5106f4a2713aSLionel Sambuc 
ToDiag(SourceLocation Loc,unsigned DiagID)5107f4a2713aSLionel Sambuc DiagnosticBuilder ASTImporter::ToDiag(SourceLocation Loc, unsigned DiagID) {
5108f4a2713aSLionel Sambuc   if (LastDiagFromFrom)
5109f4a2713aSLionel Sambuc     ToContext.getDiagnostics().notePriorDiagnosticFrom(
5110f4a2713aSLionel Sambuc       FromContext.getDiagnostics());
5111f4a2713aSLionel Sambuc   LastDiagFromFrom = false;
5112f4a2713aSLionel Sambuc   return ToContext.getDiagnostics().Report(Loc, DiagID);
5113f4a2713aSLionel Sambuc }
5114f4a2713aSLionel Sambuc 
FromDiag(SourceLocation Loc,unsigned DiagID)5115f4a2713aSLionel Sambuc DiagnosticBuilder ASTImporter::FromDiag(SourceLocation Loc, unsigned DiagID) {
5116f4a2713aSLionel Sambuc   if (!LastDiagFromFrom)
5117f4a2713aSLionel Sambuc     FromContext.getDiagnostics().notePriorDiagnosticFrom(
5118f4a2713aSLionel Sambuc       ToContext.getDiagnostics());
5119f4a2713aSLionel Sambuc   LastDiagFromFrom = true;
5120f4a2713aSLionel Sambuc   return FromContext.getDiagnostics().Report(Loc, DiagID);
5121f4a2713aSLionel Sambuc }
5122f4a2713aSLionel Sambuc 
CompleteDecl(Decl * D)5123f4a2713aSLionel Sambuc void ASTImporter::CompleteDecl (Decl *D) {
5124f4a2713aSLionel Sambuc   if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
5125f4a2713aSLionel Sambuc     if (!ID->getDefinition())
5126f4a2713aSLionel Sambuc       ID->startDefinition();
5127f4a2713aSLionel Sambuc   }
5128f4a2713aSLionel Sambuc   else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) {
5129f4a2713aSLionel Sambuc     if (!PD->getDefinition())
5130f4a2713aSLionel Sambuc       PD->startDefinition();
5131f4a2713aSLionel Sambuc   }
5132f4a2713aSLionel Sambuc   else if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
5133f4a2713aSLionel Sambuc     if (!TD->getDefinition() && !TD->isBeingDefined()) {
5134f4a2713aSLionel Sambuc       TD->startDefinition();
5135f4a2713aSLionel Sambuc       TD->setCompleteDefinition(true);
5136f4a2713aSLionel Sambuc     }
5137f4a2713aSLionel Sambuc   }
5138f4a2713aSLionel Sambuc   else {
5139f4a2713aSLionel Sambuc     assert (0 && "CompleteDecl called on a Decl that can't be completed");
5140f4a2713aSLionel Sambuc   }
5141f4a2713aSLionel Sambuc }
5142f4a2713aSLionel Sambuc 
Imported(Decl * From,Decl * To)5143f4a2713aSLionel Sambuc Decl *ASTImporter::Imported(Decl *From, Decl *To) {
5144f4a2713aSLionel Sambuc   ImportedDecls[From] = To;
5145f4a2713aSLionel Sambuc   return To;
5146f4a2713aSLionel Sambuc }
5147f4a2713aSLionel Sambuc 
IsStructurallyEquivalent(QualType From,QualType To,bool Complain)5148f4a2713aSLionel Sambuc bool ASTImporter::IsStructurallyEquivalent(QualType From, QualType To,
5149f4a2713aSLionel Sambuc                                            bool Complain) {
5150f4a2713aSLionel Sambuc   llvm::DenseMap<const Type *, const Type *>::iterator Pos
5151f4a2713aSLionel Sambuc    = ImportedTypes.find(From.getTypePtr());
5152f4a2713aSLionel Sambuc   if (Pos != ImportedTypes.end() && ToContext.hasSameType(Import(From), To))
5153f4a2713aSLionel Sambuc     return true;
5154f4a2713aSLionel Sambuc 
5155f4a2713aSLionel Sambuc   StructuralEquivalenceContext Ctx(FromContext, ToContext, NonEquivalentDecls,
5156f4a2713aSLionel Sambuc                                    false, Complain);
5157f4a2713aSLionel Sambuc   return Ctx.IsStructurallyEquivalent(From, To);
5158f4a2713aSLionel Sambuc }
5159