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