blob: c6edc7712036655d59855954b3833ac5826ec7ed [file] [log] [blame]
Douglas Gregor96e578d2010-02-05 17:54:41 +00001//===--- ASTImporter.cpp - Importing ASTs from other Contexts ---*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the ASTImporter class which imports AST nodes from one
11// context into another context.
12//
13//===----------------------------------------------------------------------===//
14#include "clang/AST/ASTImporter.h"
Douglas Gregor96e578d2010-02-05 17:54:41 +000015#include "clang/AST/ASTContext.h"
Douglas Gregor811663e2010-02-10 00:15:17 +000016#include "clang/AST/ASTDiagnostic.h"
Douglas Gregor5c73e912010-02-11 00:48:18 +000017#include "clang/AST/DeclCXX.h"
Douglas Gregor96e578d2010-02-05 17:54:41 +000018#include "clang/AST/DeclObjC.h"
Douglas Gregor3aed6cd2010-02-08 21:09:39 +000019#include "clang/AST/DeclVisitor.h"
Douglas Gregor7eeb5972010-02-11 19:21:55 +000020#include "clang/AST/StmtVisitor.h"
Douglas Gregor96e578d2010-02-05 17:54:41 +000021#include "clang/AST/TypeVisitor.h"
Douglas Gregor811663e2010-02-10 00:15:17 +000022#include "clang/Basic/FileManager.h"
23#include "clang/Basic/SourceManager.h"
24#include "llvm/Support/MemoryBuffer.h"
Douglas Gregor3996e242010-02-15 22:01:00 +000025#include <deque>
Douglas Gregor96e578d2010-02-05 17:54:41 +000026
Douglas Gregor3c2404b2011-11-03 18:07:07 +000027namespace clang {
Douglas Gregor3aed6cd2010-02-08 21:09:39 +000028 class ASTNodeImporter : public TypeVisitor<ASTNodeImporter, QualType>,
Douglas Gregor7eeb5972010-02-11 19:21:55 +000029 public DeclVisitor<ASTNodeImporter, Decl *>,
30 public StmtVisitor<ASTNodeImporter, Stmt *> {
Douglas Gregor96e578d2010-02-05 17:54:41 +000031 ASTImporter &Importer;
32
33 public:
34 explicit ASTNodeImporter(ASTImporter &Importer) : Importer(Importer) { }
35
36 using TypeVisitor<ASTNodeImporter, QualType>::Visit;
Douglas Gregor62d311f2010-02-09 19:21:46 +000037 using DeclVisitor<ASTNodeImporter, Decl *>::Visit;
Douglas Gregor7eeb5972010-02-11 19:21:55 +000038 using StmtVisitor<ASTNodeImporter, Stmt *>::Visit;
Douglas Gregor96e578d2010-02-05 17:54:41 +000039
40 // Importing types
John McCall424cec92011-01-19 06:33:43 +000041 QualType VisitType(const Type *T);
42 QualType VisitBuiltinType(const BuiltinType *T);
43 QualType VisitComplexType(const ComplexType *T);
44 QualType VisitPointerType(const PointerType *T);
45 QualType VisitBlockPointerType(const BlockPointerType *T);
46 QualType VisitLValueReferenceType(const LValueReferenceType *T);
47 QualType VisitRValueReferenceType(const RValueReferenceType *T);
48 QualType VisitMemberPointerType(const MemberPointerType *T);
49 QualType VisitConstantArrayType(const ConstantArrayType *T);
50 QualType VisitIncompleteArrayType(const IncompleteArrayType *T);
51 QualType VisitVariableArrayType(const VariableArrayType *T);
Douglas Gregor96e578d2010-02-05 17:54:41 +000052 // FIXME: DependentSizedArrayType
53 // FIXME: DependentSizedExtVectorType
John McCall424cec92011-01-19 06:33:43 +000054 QualType VisitVectorType(const VectorType *T);
55 QualType VisitExtVectorType(const ExtVectorType *T);
56 QualType VisitFunctionNoProtoType(const FunctionNoProtoType *T);
57 QualType VisitFunctionProtoType(const FunctionProtoType *T);
Douglas Gregor96e578d2010-02-05 17:54:41 +000058 // FIXME: UnresolvedUsingType
Sean Callananda6df8a2011-08-11 16:56:07 +000059 QualType VisitParenType(const ParenType *T);
John McCall424cec92011-01-19 06:33:43 +000060 QualType VisitTypedefType(const TypedefType *T);
61 QualType VisitTypeOfExprType(const TypeOfExprType *T);
Douglas Gregor96e578d2010-02-05 17:54:41 +000062 // FIXME: DependentTypeOfExprType
John McCall424cec92011-01-19 06:33:43 +000063 QualType VisitTypeOfType(const TypeOfType *T);
64 QualType VisitDecltypeType(const DecltypeType *T);
Alexis Hunte852b102011-05-24 22:41:36 +000065 QualType VisitUnaryTransformType(const UnaryTransformType *T);
Richard Smith30482bc2011-02-20 03:19:35 +000066 QualType VisitAutoType(const AutoType *T);
Douglas Gregor96e578d2010-02-05 17:54:41 +000067 // FIXME: DependentDecltypeType
John McCall424cec92011-01-19 06:33:43 +000068 QualType VisitRecordType(const RecordType *T);
69 QualType VisitEnumType(const EnumType *T);
Douglas Gregor96e578d2010-02-05 17:54:41 +000070 // FIXME: TemplateTypeParmType
71 // FIXME: SubstTemplateTypeParmType
John McCall424cec92011-01-19 06:33:43 +000072 QualType VisitTemplateSpecializationType(const TemplateSpecializationType *T);
73 QualType VisitElaboratedType(const ElaboratedType *T);
Douglas Gregorc1d2d8a2010-03-31 17:34:00 +000074 // FIXME: DependentNameType
John McCallc392f372010-06-11 00:33:02 +000075 // FIXME: DependentTemplateSpecializationType
John McCall424cec92011-01-19 06:33:43 +000076 QualType VisitObjCInterfaceType(const ObjCInterfaceType *T);
77 QualType VisitObjCObjectType(const ObjCObjectType *T);
78 QualType VisitObjCObjectPointerType(const ObjCObjectPointerType *T);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +000079
Douglas Gregor95d82832012-01-24 18:36:04 +000080 // Importing declarations
Douglas Gregorbb7930c2010-02-10 19:54:31 +000081 bool ImportDeclParts(NamedDecl *D, DeclContext *&DC,
82 DeclContext *&LexicalDC, DeclarationName &Name,
Douglas Gregorf18a2c72010-02-21 18:26:36 +000083 SourceLocation &Loc);
Douglas Gregord451ea92011-07-29 23:31:30 +000084 void ImportDefinitionIfNeeded(Decl *FromD, Decl *ToD = 0);
Abramo Bagnarad6d2f182010-08-11 22:01:17 +000085 void ImportDeclarationNameLoc(const DeclarationNameInfo &From,
86 DeclarationNameInfo& To);
Douglas Gregor0a791672011-01-18 03:11:38 +000087 void ImportDeclContext(DeclContext *FromDC, bool ForceImport = false);
Douglas Gregor2e15c842012-02-01 21:00:38 +000088
Douglas Gregor95d82832012-01-24 18:36:04 +000089 /// \brief What we should import from the definition.
90 enum ImportDefinitionKind {
91 /// \brief Import the default subset of the definition, which might be
92 /// nothing (if minimal import is set) or might be everything (if minimal
93 /// import is not set).
94 IDK_Default,
95 /// \brief Import everything.
96 IDK_Everything,
97 /// \brief Import only the bare bones needed to establish a valid
98 /// DeclContext.
99 IDK_Basic
100 };
101
Douglas Gregor2e15c842012-02-01 21:00:38 +0000102 bool shouldForceImportDeclContext(ImportDefinitionKind IDK) {
103 return IDK == IDK_Everything ||
104 (IDK == IDK_Default && !Importer.isMinimalImport());
105 }
106
Douglas Gregord451ea92011-07-29 23:31:30 +0000107 bool ImportDefinition(RecordDecl *From, RecordDecl *To,
Douglas Gregor95d82832012-01-24 18:36:04 +0000108 ImportDefinitionKind Kind = IDK_Default);
Larisse Voufo39a1e502013-08-06 01:03:05 +0000109 bool ImportDefinition(VarDecl *From, VarDecl *To,
110 ImportDefinitionKind Kind = IDK_Default);
Douglas Gregord451ea92011-07-29 23:31:30 +0000111 bool ImportDefinition(EnumDecl *From, EnumDecl *To,
Douglas Gregor2e15c842012-02-01 21:00:38 +0000112 ImportDefinitionKind Kind = IDK_Default);
Douglas Gregor2aa53772012-01-24 17:42:07 +0000113 bool ImportDefinition(ObjCInterfaceDecl *From, ObjCInterfaceDecl *To,
Douglas Gregor2e15c842012-02-01 21:00:38 +0000114 ImportDefinitionKind Kind = IDK_Default);
Douglas Gregor2aa53772012-01-24 17:42:07 +0000115 bool ImportDefinition(ObjCProtocolDecl *From, ObjCProtocolDecl *To,
Douglas Gregor2e15c842012-02-01 21:00:38 +0000116 ImportDefinitionKind Kind = IDK_Default);
Douglas Gregora082a492010-11-30 19:14:50 +0000117 TemplateParameterList *ImportTemplateParameterList(
118 TemplateParameterList *Params);
Douglas Gregore2e50d332010-12-01 01:36:18 +0000119 TemplateArgument ImportTemplateArgument(const TemplateArgument &From);
120 bool ImportTemplateArguments(const TemplateArgument *FromArgs,
121 unsigned NumFromArgs,
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000122 SmallVectorImpl<TemplateArgument> &ToArgs);
Douglas Gregordd6006f2012-07-17 21:16:27 +0000123 bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord,
124 bool Complain = true);
Larisse Voufo39a1e502013-08-06 01:03:05 +0000125 bool IsStructuralMatch(VarDecl *FromVar, VarDecl *ToVar,
126 bool Complain = true);
Douglas Gregor3996e242010-02-15 22:01:00 +0000127 bool IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToRecord);
Douglas Gregor91155082012-11-14 22:29:20 +0000128 bool IsStructuralMatch(EnumConstantDecl *FromEC, EnumConstantDecl *ToEC);
Douglas Gregora082a492010-11-30 19:14:50 +0000129 bool IsStructuralMatch(ClassTemplateDecl *From, ClassTemplateDecl *To);
Larisse Voufo39a1e502013-08-06 01:03:05 +0000130 bool IsStructuralMatch(VarTemplateDecl *From, VarTemplateDecl *To);
Douglas Gregore4c83e42010-02-09 22:48:33 +0000131 Decl *VisitDecl(Decl *D);
Sean Callanan65198272011-11-17 23:20:56 +0000132 Decl *VisitTranslationUnitDecl(TranslationUnitDecl *D);
Douglas Gregorf18a2c72010-02-21 18:26:36 +0000133 Decl *VisitNamespaceDecl(NamespaceDecl *D);
Richard Smithdda56e42011-04-15 14:24:37 +0000134 Decl *VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias);
Douglas Gregor5fa74c32010-02-10 21:10:29 +0000135 Decl *VisitTypedefDecl(TypedefDecl *D);
Richard Smithdda56e42011-04-15 14:24:37 +0000136 Decl *VisitTypeAliasDecl(TypeAliasDecl *D);
Douglas Gregor98c10182010-02-12 22:17:39 +0000137 Decl *VisitEnumDecl(EnumDecl *D);
Douglas Gregor5c73e912010-02-11 00:48:18 +0000138 Decl *VisitRecordDecl(RecordDecl *D);
Douglas Gregor98c10182010-02-12 22:17:39 +0000139 Decl *VisitEnumConstantDecl(EnumConstantDecl *D);
Douglas Gregorbb7930c2010-02-10 19:54:31 +0000140 Decl *VisitFunctionDecl(FunctionDecl *D);
Douglas Gregor00eace12010-02-21 18:29:16 +0000141 Decl *VisitCXXMethodDecl(CXXMethodDecl *D);
142 Decl *VisitCXXConstructorDecl(CXXConstructorDecl *D);
143 Decl *VisitCXXDestructorDecl(CXXDestructorDecl *D);
144 Decl *VisitCXXConversionDecl(CXXConversionDecl *D);
Douglas Gregor5c73e912010-02-11 00:48:18 +0000145 Decl *VisitFieldDecl(FieldDecl *D);
Francois Pichet783dd6e2010-11-21 06:08:52 +0000146 Decl *VisitIndirectFieldDecl(IndirectFieldDecl *D);
Douglas Gregor7244b0b2010-02-17 00:34:30 +0000147 Decl *VisitObjCIvarDecl(ObjCIvarDecl *D);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +0000148 Decl *VisitVarDecl(VarDecl *D);
Douglas Gregor8b228d72010-02-17 21:22:52 +0000149 Decl *VisitImplicitParamDecl(ImplicitParamDecl *D);
Douglas Gregorbb7930c2010-02-10 19:54:31 +0000150 Decl *VisitParmVarDecl(ParmVarDecl *D);
Douglas Gregor43f54792010-02-17 02:12:47 +0000151 Decl *VisitObjCMethodDecl(ObjCMethodDecl *D);
Douglas Gregor84c51c32010-02-18 01:47:50 +0000152 Decl *VisitObjCCategoryDecl(ObjCCategoryDecl *D);
Douglas Gregor98d156a2010-02-17 16:12:00 +0000153 Decl *VisitObjCProtocolDecl(ObjCProtocolDecl *D);
Douglas Gregor45635322010-02-16 01:20:57 +0000154 Decl *VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
Douglas Gregor4da9d682010-12-07 15:32:12 +0000155 Decl *VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
Douglas Gregorda8025c2010-12-07 01:26:03 +0000156 Decl *VisitObjCImplementationDecl(ObjCImplementationDecl *D);
Douglas Gregora11c4582010-02-17 18:02:10 +0000157 Decl *VisitObjCPropertyDecl(ObjCPropertyDecl *D);
Douglas Gregor14a49e22010-12-07 18:32:03 +0000158 Decl *VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
Douglas Gregora082a492010-11-30 19:14:50 +0000159 Decl *VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
160 Decl *VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
161 Decl *VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
162 Decl *VisitClassTemplateDecl(ClassTemplateDecl *D);
Douglas Gregore2e50d332010-12-01 01:36:18 +0000163 Decl *VisitClassTemplateSpecializationDecl(
164 ClassTemplateSpecializationDecl *D);
Larisse Voufo39a1e502013-08-06 01:03:05 +0000165 Decl *VisitVarTemplateDecl(VarTemplateDecl *D);
166 Decl *VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *D);
167
Douglas Gregor7eeb5972010-02-11 19:21:55 +0000168 // Importing statements
169 Stmt *VisitStmt(Stmt *S);
170
171 // Importing expressions
172 Expr *VisitExpr(Expr *E);
Douglas Gregor52f820e2010-02-19 01:17:02 +0000173 Expr *VisitDeclRefExpr(DeclRefExpr *E);
Douglas Gregor7eeb5972010-02-11 19:21:55 +0000174 Expr *VisitIntegerLiteral(IntegerLiteral *E);
Douglas Gregor623421d2010-02-18 02:21:22 +0000175 Expr *VisitCharacterLiteral(CharacterLiteral *E);
Douglas Gregorc74247e2010-02-19 01:07:06 +0000176 Expr *VisitParenExpr(ParenExpr *E);
177 Expr *VisitUnaryOperator(UnaryOperator *E);
Peter Collingbournee190dee2011-03-11 19:24:49 +0000178 Expr *VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E);
Douglas Gregorc74247e2010-02-19 01:07:06 +0000179 Expr *VisitBinaryOperator(BinaryOperator *E);
180 Expr *VisitCompoundAssignOperator(CompoundAssignOperator *E);
Douglas Gregor98c10182010-02-12 22:17:39 +0000181 Expr *VisitImplicitCastExpr(ImplicitCastExpr *E);
Douglas Gregor5481d322010-02-19 01:32:14 +0000182 Expr *VisitCStyleCastExpr(CStyleCastExpr *E);
Douglas Gregor96e578d2010-02-05 17:54:41 +0000183 };
184}
Douglas Gregor3c2404b2011-11-03 18:07:07 +0000185using namespace clang;
Douglas Gregor96e578d2010-02-05 17:54:41 +0000186
187//----------------------------------------------------------------------------
Douglas Gregor3996e242010-02-15 22:01:00 +0000188// Structural Equivalence
189//----------------------------------------------------------------------------
190
191namespace {
192 struct StructuralEquivalenceContext {
193 /// \brief AST contexts for which we are checking structural equivalence.
194 ASTContext &C1, &C2;
195
Douglas Gregor3996e242010-02-15 22:01:00 +0000196 /// \brief The set of "tentative" equivalences between two canonical
197 /// declarations, mapping from a declaration in the first context to the
198 /// declaration in the second context that we believe to be equivalent.
199 llvm::DenseMap<Decl *, Decl *> TentativeEquivalences;
200
201 /// \brief Queue of declarations in the first context whose equivalence
202 /// with a declaration in the second context still needs to be verified.
203 std::deque<Decl *> DeclsToCheck;
204
Douglas Gregorb4964f72010-02-15 23:54:17 +0000205 /// \brief Declaration (from, to) pairs that are known not to be equivalent
206 /// (which we have already complained about).
207 llvm::DenseSet<std::pair<Decl *, Decl *> > &NonEquivalentDecls;
208
Douglas Gregor3996e242010-02-15 22:01:00 +0000209 /// \brief Whether we're being strict about the spelling of types when
210 /// unifying two types.
211 bool StrictTypeSpelling;
Douglas Gregordd6006f2012-07-17 21:16:27 +0000212
213 /// \brief Whether to complain about failures.
214 bool Complain;
215
Richard Smith5bb4cdf2012-12-20 02:22:15 +0000216 /// \brief \c true if the last diagnostic came from C2.
217 bool LastDiagFromC2;
218
Douglas Gregor3996e242010-02-15 22:01:00 +0000219 StructuralEquivalenceContext(ASTContext &C1, ASTContext &C2,
Douglas Gregorb4964f72010-02-15 23:54:17 +0000220 llvm::DenseSet<std::pair<Decl *, Decl *> > &NonEquivalentDecls,
Douglas Gregordd6006f2012-07-17 21:16:27 +0000221 bool StrictTypeSpelling = false,
222 bool Complain = true)
Argyrios Kyrtzidisd0040642010-11-18 20:06:41 +0000223 : C1(C1), C2(C2), NonEquivalentDecls(NonEquivalentDecls),
Richard Smith5bb4cdf2012-12-20 02:22:15 +0000224 StrictTypeSpelling(StrictTypeSpelling), Complain(Complain),
225 LastDiagFromC2(false) {}
Douglas Gregor3996e242010-02-15 22:01:00 +0000226
227 /// \brief Determine whether the two declarations are structurally
228 /// equivalent.
229 bool IsStructurallyEquivalent(Decl *D1, Decl *D2);
230
231 /// \brief Determine whether the two types are structurally equivalent.
232 bool IsStructurallyEquivalent(QualType T1, QualType T2);
233
234 private:
235 /// \brief Finish checking all of the structural equivalences.
236 ///
237 /// \returns true if an error occurred, false otherwise.
238 bool Finish();
239
240 public:
241 DiagnosticBuilder Diag1(SourceLocation Loc, unsigned DiagID) {
Douglas Gregor069bbaf2012-10-26 15:34:11 +0000242 assert(Complain && "Not allowed to complain");
Richard Smith5bb4cdf2012-12-20 02:22:15 +0000243 if (LastDiagFromC2)
244 C1.getDiagnostics().notePriorDiagnosticFrom(C2.getDiagnostics());
245 LastDiagFromC2 = false;
Argyrios Kyrtzidisd0040642010-11-18 20:06:41 +0000246 return C1.getDiagnostics().Report(Loc, DiagID);
Douglas Gregor3996e242010-02-15 22:01:00 +0000247 }
248
249 DiagnosticBuilder Diag2(SourceLocation Loc, unsigned DiagID) {
Douglas Gregor069bbaf2012-10-26 15:34:11 +0000250 assert(Complain && "Not allowed to complain");
Richard Smith5bb4cdf2012-12-20 02:22:15 +0000251 if (!LastDiagFromC2)
252 C2.getDiagnostics().notePriorDiagnosticFrom(C1.getDiagnostics());
253 LastDiagFromC2 = true;
Argyrios Kyrtzidisd0040642010-11-18 20:06:41 +0000254 return C2.getDiagnostics().Report(Loc, DiagID);
Douglas Gregor3996e242010-02-15 22:01:00 +0000255 }
256 };
257}
258
259static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
260 QualType T1, QualType T2);
261static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
262 Decl *D1, Decl *D2);
263
Douglas Gregor3996e242010-02-15 22:01:00 +0000264/// \brief Determine structural equivalence of two expressions.
265static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
266 Expr *E1, Expr *E2) {
267 if (!E1 || !E2)
268 return E1 == E2;
269
270 // FIXME: Actually perform a structural comparison!
271 return true;
272}
273
274/// \brief Determine whether two identifiers are equivalent.
275static bool IsStructurallyEquivalent(const IdentifierInfo *Name1,
276 const IdentifierInfo *Name2) {
277 if (!Name1 || !Name2)
278 return Name1 == Name2;
279
280 return Name1->getName() == Name2->getName();
281}
282
283/// \brief Determine whether two nested-name-specifiers are equivalent.
284static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
285 NestedNameSpecifier *NNS1,
286 NestedNameSpecifier *NNS2) {
287 // FIXME: Implement!
288 return true;
289}
290
291/// \brief Determine whether two template arguments are equivalent.
292static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
293 const TemplateArgument &Arg1,
294 const TemplateArgument &Arg2) {
Douglas Gregore2e50d332010-12-01 01:36:18 +0000295 if (Arg1.getKind() != Arg2.getKind())
296 return false;
297
298 switch (Arg1.getKind()) {
299 case TemplateArgument::Null:
300 return true;
301
302 case TemplateArgument::Type:
303 return Context.IsStructurallyEquivalent(Arg1.getAsType(), Arg2.getAsType());
Eli Friedmanb826a002012-09-26 02:36:12 +0000304
Douglas Gregore2e50d332010-12-01 01:36:18 +0000305 case TemplateArgument::Integral:
306 if (!Context.IsStructurallyEquivalent(Arg1.getIntegralType(),
307 Arg2.getIntegralType()))
308 return false;
309
Eric Christopher6dcc3762012-07-15 00:23:57 +0000310 return llvm::APSInt::isSameValue(Arg1.getAsIntegral(), Arg2.getAsIntegral());
Douglas Gregore2e50d332010-12-01 01:36:18 +0000311
312 case TemplateArgument::Declaration:
313 return Context.IsStructurallyEquivalent(Arg1.getAsDecl(), Arg2.getAsDecl());
Eli Friedmanb826a002012-09-26 02:36:12 +0000314
315 case TemplateArgument::NullPtr:
316 return true; // FIXME: Is this correct?
317
Douglas Gregore2e50d332010-12-01 01:36:18 +0000318 case TemplateArgument::Template:
319 return IsStructurallyEquivalent(Context,
320 Arg1.getAsTemplate(),
321 Arg2.getAsTemplate());
Douglas Gregore4ff4b52011-01-05 18:58:31 +0000322
323 case TemplateArgument::TemplateExpansion:
324 return IsStructurallyEquivalent(Context,
325 Arg1.getAsTemplateOrTemplatePattern(),
326 Arg2.getAsTemplateOrTemplatePattern());
327
Douglas Gregore2e50d332010-12-01 01:36:18 +0000328 case TemplateArgument::Expression:
329 return IsStructurallyEquivalent(Context,
330 Arg1.getAsExpr(), Arg2.getAsExpr());
331
332 case TemplateArgument::Pack:
333 if (Arg1.pack_size() != Arg2.pack_size())
334 return false;
335
336 for (unsigned I = 0, N = Arg1.pack_size(); I != N; ++I)
337 if (!IsStructurallyEquivalent(Context,
338 Arg1.pack_begin()[I],
339 Arg2.pack_begin()[I]))
340 return false;
341
342 return true;
343 }
344
345 llvm_unreachable("Invalid template argument kind");
Douglas Gregor3996e242010-02-15 22:01:00 +0000346}
347
348/// \brief Determine structural equivalence for the common part of array
349/// types.
350static bool IsArrayStructurallyEquivalent(StructuralEquivalenceContext &Context,
351 const ArrayType *Array1,
352 const ArrayType *Array2) {
353 if (!IsStructurallyEquivalent(Context,
354 Array1->getElementType(),
355 Array2->getElementType()))
356 return false;
357 if (Array1->getSizeModifier() != Array2->getSizeModifier())
358 return false;
359 if (Array1->getIndexTypeQualifiers() != Array2->getIndexTypeQualifiers())
360 return false;
361
362 return true;
363}
364
365/// \brief Determine structural equivalence of two types.
366static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
367 QualType T1, QualType T2) {
368 if (T1.isNull() || T2.isNull())
369 return T1.isNull() && T2.isNull();
370
371 if (!Context.StrictTypeSpelling) {
372 // We aren't being strict about token-to-token equivalence of types,
373 // so map down to the canonical type.
374 T1 = Context.C1.getCanonicalType(T1);
375 T2 = Context.C2.getCanonicalType(T2);
376 }
377
378 if (T1.getQualifiers() != T2.getQualifiers())
379 return false;
380
Douglas Gregorb4964f72010-02-15 23:54:17 +0000381 Type::TypeClass TC = T1->getTypeClass();
Douglas Gregor3996e242010-02-15 22:01:00 +0000382
Douglas Gregorb4964f72010-02-15 23:54:17 +0000383 if (T1->getTypeClass() != T2->getTypeClass()) {
384 // Compare function types with prototypes vs. without prototypes as if
385 // both did not have prototypes.
386 if (T1->getTypeClass() == Type::FunctionProto &&
387 T2->getTypeClass() == Type::FunctionNoProto)
388 TC = Type::FunctionNoProto;
389 else if (T1->getTypeClass() == Type::FunctionNoProto &&
390 T2->getTypeClass() == Type::FunctionProto)
391 TC = Type::FunctionNoProto;
392 else
393 return false;
394 }
395
396 switch (TC) {
397 case Type::Builtin:
Douglas Gregor3996e242010-02-15 22:01:00 +0000398 // FIXME: Deal with Char_S/Char_U.
399 if (cast<BuiltinType>(T1)->getKind() != cast<BuiltinType>(T2)->getKind())
400 return false;
401 break;
402
403 case Type::Complex:
404 if (!IsStructurallyEquivalent(Context,
405 cast<ComplexType>(T1)->getElementType(),
406 cast<ComplexType>(T2)->getElementType()))
407 return false;
408 break;
409
Reid Kleckner8a365022013-06-24 17:51:48 +0000410 case Type::Decayed:
411 if (!IsStructurallyEquivalent(Context,
412 cast<DecayedType>(T1)->getPointeeType(),
413 cast<DecayedType>(T2)->getPointeeType()))
414 return false;
415 break;
416
Douglas Gregor3996e242010-02-15 22:01:00 +0000417 case Type::Pointer:
418 if (!IsStructurallyEquivalent(Context,
419 cast<PointerType>(T1)->getPointeeType(),
420 cast<PointerType>(T2)->getPointeeType()))
421 return false;
422 break;
423
424 case Type::BlockPointer:
425 if (!IsStructurallyEquivalent(Context,
426 cast<BlockPointerType>(T1)->getPointeeType(),
427 cast<BlockPointerType>(T2)->getPointeeType()))
428 return false;
429 break;
430
431 case Type::LValueReference:
432 case Type::RValueReference: {
433 const ReferenceType *Ref1 = cast<ReferenceType>(T1);
434 const ReferenceType *Ref2 = cast<ReferenceType>(T2);
435 if (Ref1->isSpelledAsLValue() != Ref2->isSpelledAsLValue())
436 return false;
437 if (Ref1->isInnerRef() != Ref2->isInnerRef())
438 return false;
439 if (!IsStructurallyEquivalent(Context,
440 Ref1->getPointeeTypeAsWritten(),
441 Ref2->getPointeeTypeAsWritten()))
442 return false;
443 break;
444 }
445
446 case Type::MemberPointer: {
447 const MemberPointerType *MemPtr1 = cast<MemberPointerType>(T1);
448 const MemberPointerType *MemPtr2 = cast<MemberPointerType>(T2);
449 if (!IsStructurallyEquivalent(Context,
450 MemPtr1->getPointeeType(),
451 MemPtr2->getPointeeType()))
452 return false;
453 if (!IsStructurallyEquivalent(Context,
454 QualType(MemPtr1->getClass(), 0),
455 QualType(MemPtr2->getClass(), 0)))
456 return false;
457 break;
458 }
459
460 case Type::ConstantArray: {
461 const ConstantArrayType *Array1 = cast<ConstantArrayType>(T1);
462 const ConstantArrayType *Array2 = cast<ConstantArrayType>(T2);
Eric Christopher6dcc3762012-07-15 00:23:57 +0000463 if (!llvm::APInt::isSameValue(Array1->getSize(), Array2->getSize()))
Douglas Gregor3996e242010-02-15 22:01:00 +0000464 return false;
465
466 if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
467 return false;
468 break;
469 }
470
471 case Type::IncompleteArray:
472 if (!IsArrayStructurallyEquivalent(Context,
473 cast<ArrayType>(T1),
474 cast<ArrayType>(T2)))
475 return false;
476 break;
477
478 case Type::VariableArray: {
479 const VariableArrayType *Array1 = cast<VariableArrayType>(T1);
480 const VariableArrayType *Array2 = cast<VariableArrayType>(T2);
481 if (!IsStructurallyEquivalent(Context,
482 Array1->getSizeExpr(), Array2->getSizeExpr()))
483 return false;
484
485 if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
486 return false;
487
488 break;
489 }
490
491 case Type::DependentSizedArray: {
492 const DependentSizedArrayType *Array1 = cast<DependentSizedArrayType>(T1);
493 const DependentSizedArrayType *Array2 = cast<DependentSizedArrayType>(T2);
494 if (!IsStructurallyEquivalent(Context,
495 Array1->getSizeExpr(), Array2->getSizeExpr()))
496 return false;
497
498 if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
499 return false;
500
501 break;
502 }
503
504 case Type::DependentSizedExtVector: {
505 const DependentSizedExtVectorType *Vec1
506 = cast<DependentSizedExtVectorType>(T1);
507 const DependentSizedExtVectorType *Vec2
508 = cast<DependentSizedExtVectorType>(T2);
509 if (!IsStructurallyEquivalent(Context,
510 Vec1->getSizeExpr(), Vec2->getSizeExpr()))
511 return false;
512 if (!IsStructurallyEquivalent(Context,
513 Vec1->getElementType(),
514 Vec2->getElementType()))
515 return false;
516 break;
517 }
518
519 case Type::Vector:
520 case Type::ExtVector: {
521 const VectorType *Vec1 = cast<VectorType>(T1);
522 const VectorType *Vec2 = cast<VectorType>(T2);
523 if (!IsStructurallyEquivalent(Context,
524 Vec1->getElementType(),
525 Vec2->getElementType()))
526 return false;
527 if (Vec1->getNumElements() != Vec2->getNumElements())
528 return false;
Bob Wilsonaeb56442010-11-10 21:56:12 +0000529 if (Vec1->getVectorKind() != Vec2->getVectorKind())
Douglas Gregor3996e242010-02-15 22:01:00 +0000530 return false;
Douglas Gregor01cc4372010-02-19 01:36:36 +0000531 break;
Douglas Gregor3996e242010-02-15 22:01:00 +0000532 }
533
534 case Type::FunctionProto: {
535 const FunctionProtoType *Proto1 = cast<FunctionProtoType>(T1);
536 const FunctionProtoType *Proto2 = cast<FunctionProtoType>(T2);
537 if (Proto1->getNumArgs() != Proto2->getNumArgs())
538 return false;
539 for (unsigned I = 0, N = Proto1->getNumArgs(); I != N; ++I) {
540 if (!IsStructurallyEquivalent(Context,
541 Proto1->getArgType(I),
542 Proto2->getArgType(I)))
543 return false;
544 }
545 if (Proto1->isVariadic() != Proto2->isVariadic())
546 return false;
Sebastian Redlfa453cf2011-03-12 11:50:43 +0000547 if (Proto1->getExceptionSpecType() != Proto2->getExceptionSpecType())
Douglas Gregor3996e242010-02-15 22:01:00 +0000548 return false;
Sebastian Redlfa453cf2011-03-12 11:50:43 +0000549 if (Proto1->getExceptionSpecType() == EST_Dynamic) {
550 if (Proto1->getNumExceptions() != Proto2->getNumExceptions())
551 return false;
552 for (unsigned I = 0, N = Proto1->getNumExceptions(); I != N; ++I) {
553 if (!IsStructurallyEquivalent(Context,
554 Proto1->getExceptionType(I),
555 Proto2->getExceptionType(I)))
556 return false;
557 }
558 } else if (Proto1->getExceptionSpecType() == EST_ComputedNoexcept) {
Douglas Gregor3996e242010-02-15 22:01:00 +0000559 if (!IsStructurallyEquivalent(Context,
Sebastian Redlfa453cf2011-03-12 11:50:43 +0000560 Proto1->getNoexceptExpr(),
561 Proto2->getNoexceptExpr()))
Douglas Gregor3996e242010-02-15 22:01:00 +0000562 return false;
563 }
564 if (Proto1->getTypeQuals() != Proto2->getTypeQuals())
565 return false;
566
567 // Fall through to check the bits common with FunctionNoProtoType.
568 }
569
570 case Type::FunctionNoProto: {
571 const FunctionType *Function1 = cast<FunctionType>(T1);
572 const FunctionType *Function2 = cast<FunctionType>(T2);
573 if (!IsStructurallyEquivalent(Context,
574 Function1->getResultType(),
575 Function2->getResultType()))
576 return false;
Rafael Espindolac50c27c2010-03-30 20:24:48 +0000577 if (Function1->getExtInfo() != Function2->getExtInfo())
578 return false;
Douglas Gregor3996e242010-02-15 22:01:00 +0000579 break;
580 }
581
582 case Type::UnresolvedUsing:
583 if (!IsStructurallyEquivalent(Context,
584 cast<UnresolvedUsingType>(T1)->getDecl(),
585 cast<UnresolvedUsingType>(T2)->getDecl()))
586 return false;
587
588 break;
John McCall81904512011-01-06 01:58:22 +0000589
590 case Type::Attributed:
591 if (!IsStructurallyEquivalent(Context,
592 cast<AttributedType>(T1)->getModifiedType(),
593 cast<AttributedType>(T2)->getModifiedType()))
594 return false;
595 if (!IsStructurallyEquivalent(Context,
596 cast<AttributedType>(T1)->getEquivalentType(),
597 cast<AttributedType>(T2)->getEquivalentType()))
598 return false;
599 break;
Douglas Gregor3996e242010-02-15 22:01:00 +0000600
Abramo Bagnara924a8f32010-12-10 16:29:40 +0000601 case Type::Paren:
602 if (!IsStructurallyEquivalent(Context,
603 cast<ParenType>(T1)->getInnerType(),
604 cast<ParenType>(T2)->getInnerType()))
605 return false;
606 break;
607
Douglas Gregor3996e242010-02-15 22:01:00 +0000608 case Type::Typedef:
609 if (!IsStructurallyEquivalent(Context,
610 cast<TypedefType>(T1)->getDecl(),
611 cast<TypedefType>(T2)->getDecl()))
612 return false;
613 break;
614
615 case Type::TypeOfExpr:
616 if (!IsStructurallyEquivalent(Context,
617 cast<TypeOfExprType>(T1)->getUnderlyingExpr(),
618 cast<TypeOfExprType>(T2)->getUnderlyingExpr()))
619 return false;
620 break;
621
622 case Type::TypeOf:
623 if (!IsStructurallyEquivalent(Context,
624 cast<TypeOfType>(T1)->getUnderlyingType(),
625 cast<TypeOfType>(T2)->getUnderlyingType()))
626 return false;
627 break;
Alexis Hunte852b102011-05-24 22:41:36 +0000628
629 case Type::UnaryTransform:
630 if (!IsStructurallyEquivalent(Context,
631 cast<UnaryTransformType>(T1)->getUnderlyingType(),
632 cast<UnaryTransformType>(T1)->getUnderlyingType()))
633 return false;
634 break;
635
Douglas Gregor3996e242010-02-15 22:01:00 +0000636 case Type::Decltype:
637 if (!IsStructurallyEquivalent(Context,
638 cast<DecltypeType>(T1)->getUnderlyingExpr(),
639 cast<DecltypeType>(T2)->getUnderlyingExpr()))
640 return false;
641 break;
642
Richard Smith30482bc2011-02-20 03:19:35 +0000643 case Type::Auto:
644 if (!IsStructurallyEquivalent(Context,
645 cast<AutoType>(T1)->getDeducedType(),
646 cast<AutoType>(T2)->getDeducedType()))
647 return false;
648 break;
649
Douglas Gregor3996e242010-02-15 22:01:00 +0000650 case Type::Record:
651 case Type::Enum:
652 if (!IsStructurallyEquivalent(Context,
653 cast<TagType>(T1)->getDecl(),
654 cast<TagType>(T2)->getDecl()))
655 return false;
656 break;
Abramo Bagnara6150c882010-05-11 21:36:43 +0000657
Douglas Gregor3996e242010-02-15 22:01:00 +0000658 case Type::TemplateTypeParm: {
659 const TemplateTypeParmType *Parm1 = cast<TemplateTypeParmType>(T1);
660 const TemplateTypeParmType *Parm2 = cast<TemplateTypeParmType>(T2);
661 if (Parm1->getDepth() != Parm2->getDepth())
662 return false;
663 if (Parm1->getIndex() != Parm2->getIndex())
664 return false;
665 if (Parm1->isParameterPack() != Parm2->isParameterPack())
666 return false;
667
668 // Names of template type parameters are never significant.
669 break;
670 }
671
672 case Type::SubstTemplateTypeParm: {
673 const SubstTemplateTypeParmType *Subst1
674 = cast<SubstTemplateTypeParmType>(T1);
675 const SubstTemplateTypeParmType *Subst2
676 = cast<SubstTemplateTypeParmType>(T2);
677 if (!IsStructurallyEquivalent(Context,
678 QualType(Subst1->getReplacedParameter(), 0),
679 QualType(Subst2->getReplacedParameter(), 0)))
680 return false;
681 if (!IsStructurallyEquivalent(Context,
682 Subst1->getReplacementType(),
683 Subst2->getReplacementType()))
684 return false;
685 break;
686 }
687
Douglas Gregorfb322d82011-01-14 05:11:40 +0000688 case Type::SubstTemplateTypeParmPack: {
689 const SubstTemplateTypeParmPackType *Subst1
690 = cast<SubstTemplateTypeParmPackType>(T1);
691 const SubstTemplateTypeParmPackType *Subst2
692 = cast<SubstTemplateTypeParmPackType>(T2);
693 if (!IsStructurallyEquivalent(Context,
694 QualType(Subst1->getReplacedParameter(), 0),
695 QualType(Subst2->getReplacedParameter(), 0)))
696 return false;
697 if (!IsStructurallyEquivalent(Context,
698 Subst1->getArgumentPack(),
699 Subst2->getArgumentPack()))
700 return false;
701 break;
702 }
Douglas Gregor3996e242010-02-15 22:01:00 +0000703 case Type::TemplateSpecialization: {
704 const TemplateSpecializationType *Spec1
705 = cast<TemplateSpecializationType>(T1);
706 const TemplateSpecializationType *Spec2
707 = cast<TemplateSpecializationType>(T2);
708 if (!IsStructurallyEquivalent(Context,
709 Spec1->getTemplateName(),
710 Spec2->getTemplateName()))
711 return false;
712 if (Spec1->getNumArgs() != Spec2->getNumArgs())
713 return false;
714 for (unsigned I = 0, N = Spec1->getNumArgs(); I != N; ++I) {
715 if (!IsStructurallyEquivalent(Context,
716 Spec1->getArg(I), Spec2->getArg(I)))
717 return false;
718 }
719 break;
720 }
721
Abramo Bagnara6150c882010-05-11 21:36:43 +0000722 case Type::Elaborated: {
723 const ElaboratedType *Elab1 = cast<ElaboratedType>(T1);
724 const ElaboratedType *Elab2 = cast<ElaboratedType>(T2);
725 // CHECKME: what if a keyword is ETK_None or ETK_typename ?
726 if (Elab1->getKeyword() != Elab2->getKeyword())
727 return false;
Douglas Gregor3996e242010-02-15 22:01:00 +0000728 if (!IsStructurallyEquivalent(Context,
Abramo Bagnara6150c882010-05-11 21:36:43 +0000729 Elab1->getQualifier(),
730 Elab2->getQualifier()))
Douglas Gregor3996e242010-02-15 22:01:00 +0000731 return false;
732 if (!IsStructurallyEquivalent(Context,
Abramo Bagnara6150c882010-05-11 21:36:43 +0000733 Elab1->getNamedType(),
734 Elab2->getNamedType()))
Douglas Gregor3996e242010-02-15 22:01:00 +0000735 return false;
736 break;
737 }
738
John McCalle78aac42010-03-10 03:28:59 +0000739 case Type::InjectedClassName: {
740 const InjectedClassNameType *Inj1 = cast<InjectedClassNameType>(T1);
741 const InjectedClassNameType *Inj2 = cast<InjectedClassNameType>(T2);
742 if (!IsStructurallyEquivalent(Context,
John McCall2408e322010-04-27 00:57:59 +0000743 Inj1->getInjectedSpecializationType(),
744 Inj2->getInjectedSpecializationType()))
John McCalle78aac42010-03-10 03:28:59 +0000745 return false;
746 break;
747 }
748
Douglas Gregorc1d2d8a2010-03-31 17:34:00 +0000749 case Type::DependentName: {
750 const DependentNameType *Typename1 = cast<DependentNameType>(T1);
751 const DependentNameType *Typename2 = cast<DependentNameType>(T2);
Douglas Gregor3996e242010-02-15 22:01:00 +0000752 if (!IsStructurallyEquivalent(Context,
753 Typename1->getQualifier(),
754 Typename2->getQualifier()))
755 return false;
756 if (!IsStructurallyEquivalent(Typename1->getIdentifier(),
757 Typename2->getIdentifier()))
758 return false;
Douglas Gregor3996e242010-02-15 22:01:00 +0000759
760 break;
761 }
762
John McCallc392f372010-06-11 00:33:02 +0000763 case Type::DependentTemplateSpecialization: {
764 const DependentTemplateSpecializationType *Spec1 =
765 cast<DependentTemplateSpecializationType>(T1);
766 const DependentTemplateSpecializationType *Spec2 =
767 cast<DependentTemplateSpecializationType>(T2);
768 if (!IsStructurallyEquivalent(Context,
769 Spec1->getQualifier(),
770 Spec2->getQualifier()))
771 return false;
772 if (!IsStructurallyEquivalent(Spec1->getIdentifier(),
773 Spec2->getIdentifier()))
774 return false;
775 if (Spec1->getNumArgs() != Spec2->getNumArgs())
776 return false;
777 for (unsigned I = 0, N = Spec1->getNumArgs(); I != N; ++I) {
778 if (!IsStructurallyEquivalent(Context,
779 Spec1->getArg(I), Spec2->getArg(I)))
780 return false;
781 }
782 break;
783 }
Douglas Gregord2fa7662010-12-20 02:24:11 +0000784
785 case Type::PackExpansion:
786 if (!IsStructurallyEquivalent(Context,
787 cast<PackExpansionType>(T1)->getPattern(),
788 cast<PackExpansionType>(T2)->getPattern()))
789 return false;
790 break;
791
Douglas Gregor3996e242010-02-15 22:01:00 +0000792 case Type::ObjCInterface: {
793 const ObjCInterfaceType *Iface1 = cast<ObjCInterfaceType>(T1);
794 const ObjCInterfaceType *Iface2 = cast<ObjCInterfaceType>(T2);
795 if (!IsStructurallyEquivalent(Context,
796 Iface1->getDecl(), Iface2->getDecl()))
797 return false;
John McCall8b07ec22010-05-15 11:32:37 +0000798 break;
799 }
800
801 case Type::ObjCObject: {
802 const ObjCObjectType *Obj1 = cast<ObjCObjectType>(T1);
803 const ObjCObjectType *Obj2 = cast<ObjCObjectType>(T2);
804 if (!IsStructurallyEquivalent(Context,
805 Obj1->getBaseType(),
806 Obj2->getBaseType()))
Douglas Gregor3996e242010-02-15 22:01:00 +0000807 return false;
John McCall8b07ec22010-05-15 11:32:37 +0000808 if (Obj1->getNumProtocols() != Obj2->getNumProtocols())
809 return false;
810 for (unsigned I = 0, N = Obj1->getNumProtocols(); I != N; ++I) {
Douglas Gregor3996e242010-02-15 22:01:00 +0000811 if (!IsStructurallyEquivalent(Context,
John McCall8b07ec22010-05-15 11:32:37 +0000812 Obj1->getProtocol(I),
813 Obj2->getProtocol(I)))
Douglas Gregor3996e242010-02-15 22:01:00 +0000814 return false;
815 }
816 break;
817 }
818
819 case Type::ObjCObjectPointer: {
820 const ObjCObjectPointerType *Ptr1 = cast<ObjCObjectPointerType>(T1);
821 const ObjCObjectPointerType *Ptr2 = cast<ObjCObjectPointerType>(T2);
822 if (!IsStructurallyEquivalent(Context,
823 Ptr1->getPointeeType(),
824 Ptr2->getPointeeType()))
825 return false;
Douglas Gregor3996e242010-02-15 22:01:00 +0000826 break;
827 }
Eli Friedman0dfb8892011-10-06 23:00:33 +0000828
829 case Type::Atomic: {
830 if (!IsStructurallyEquivalent(Context,
831 cast<AtomicType>(T1)->getValueType(),
832 cast<AtomicType>(T2)->getValueType()))
833 return false;
834 break;
835 }
836
Douglas Gregor3996e242010-02-15 22:01:00 +0000837 } // end switch
838
839 return true;
840}
841
Douglas Gregor03d1ed32011-10-14 21:54:42 +0000842/// \brief Determine structural equivalence of two fields.
843static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
844 FieldDecl *Field1, FieldDecl *Field2) {
845 RecordDecl *Owner2 = cast<RecordDecl>(Field2->getDeclContext());
Douglas Gregorceb32bf2012-10-26 16:45:11 +0000846
847 // For anonymous structs/unions, match up the anonymous struct/union type
848 // declarations directly, so that we don't go off searching for anonymous
849 // types
850 if (Field1->isAnonymousStructOrUnion() &&
851 Field2->isAnonymousStructOrUnion()) {
852 RecordDecl *D1 = Field1->getType()->castAs<RecordType>()->getDecl();
853 RecordDecl *D2 = Field2->getType()->castAs<RecordType>()->getDecl();
854 return IsStructurallyEquivalent(Context, D1, D2);
855 }
Sean Callanan969c5bd2013-04-26 22:49:25 +0000856
857 // Check for equivalent field names.
858 IdentifierInfo *Name1 = Field1->getIdentifier();
859 IdentifierInfo *Name2 = Field2->getIdentifier();
860 if (!::IsStructurallyEquivalent(Name1, Name2))
861 return false;
Douglas Gregorceb32bf2012-10-26 16:45:11 +0000862
863 if (!IsStructurallyEquivalent(Context,
Douglas Gregor03d1ed32011-10-14 21:54:42 +0000864 Field1->getType(), Field2->getType())) {
Douglas Gregor069bbaf2012-10-26 15:34:11 +0000865 if (Context.Complain) {
866 Context.Diag2(Owner2->getLocation(), diag::warn_odr_tag_type_inconsistent)
867 << Context.C2.getTypeDeclType(Owner2);
868 Context.Diag2(Field2->getLocation(), diag::note_odr_field)
869 << Field2->getDeclName() << Field2->getType();
870 Context.Diag1(Field1->getLocation(), diag::note_odr_field)
871 << Field1->getDeclName() << Field1->getType();
872 }
Douglas Gregor03d1ed32011-10-14 21:54:42 +0000873 return false;
874 }
875
876 if (Field1->isBitField() != Field2->isBitField()) {
Douglas Gregor069bbaf2012-10-26 15:34:11 +0000877 if (Context.Complain) {
878 Context.Diag2(Owner2->getLocation(), diag::warn_odr_tag_type_inconsistent)
879 << Context.C2.getTypeDeclType(Owner2);
880 if (Field1->isBitField()) {
881 Context.Diag1(Field1->getLocation(), diag::note_odr_bit_field)
882 << Field1->getDeclName() << Field1->getType()
883 << Field1->getBitWidthValue(Context.C1);
884 Context.Diag2(Field2->getLocation(), diag::note_odr_not_bit_field)
885 << Field2->getDeclName();
886 } else {
887 Context.Diag2(Field2->getLocation(), diag::note_odr_bit_field)
888 << Field2->getDeclName() << Field2->getType()
889 << Field2->getBitWidthValue(Context.C2);
890 Context.Diag1(Field1->getLocation(), diag::note_odr_not_bit_field)
891 << Field1->getDeclName();
892 }
Douglas Gregor03d1ed32011-10-14 21:54:42 +0000893 }
894 return false;
895 }
896
897 if (Field1->isBitField()) {
898 // Make sure that the bit-fields are the same length.
899 unsigned Bits1 = Field1->getBitWidthValue(Context.C1);
900 unsigned Bits2 = Field2->getBitWidthValue(Context.C2);
901
902 if (Bits1 != Bits2) {
Douglas Gregor069bbaf2012-10-26 15:34:11 +0000903 if (Context.Complain) {
904 Context.Diag2(Owner2->getLocation(), diag::warn_odr_tag_type_inconsistent)
905 << Context.C2.getTypeDeclType(Owner2);
906 Context.Diag2(Field2->getLocation(), diag::note_odr_bit_field)
907 << Field2->getDeclName() << Field2->getType() << Bits2;
908 Context.Diag1(Field1->getLocation(), diag::note_odr_bit_field)
909 << Field1->getDeclName() << Field1->getType() << Bits1;
910 }
Douglas Gregor03d1ed32011-10-14 21:54:42 +0000911 return false;
912 }
913 }
914
915 return true;
916}
917
Douglas Gregorceb32bf2012-10-26 16:45:11 +0000918/// \brief Find the index of the given anonymous struct/union within its
919/// context.
920///
921/// \returns Returns the index of this anonymous struct/union in its context,
922/// including the next assigned index (if none of them match). Returns an
923/// empty option if the context is not a record, i.e.. if the anonymous
924/// struct/union is at namespace or block scope.
David Blaikie05785d12013-02-20 22:23:23 +0000925static Optional<unsigned> findAnonymousStructOrUnionIndex(RecordDecl *Anon) {
Douglas Gregorceb32bf2012-10-26 16:45:11 +0000926 ASTContext &Context = Anon->getASTContext();
927 QualType AnonTy = Context.getRecordType(Anon);
928
929 RecordDecl *Owner = dyn_cast<RecordDecl>(Anon->getDeclContext());
930 if (!Owner)
David Blaikie7a30dc52013-02-21 01:47:18 +0000931 return None;
Douglas Gregorceb32bf2012-10-26 16:45:11 +0000932
933 unsigned Index = 0;
934 for (DeclContext::decl_iterator D = Owner->noload_decls_begin(),
935 DEnd = Owner->noload_decls_end();
936 D != DEnd; ++D) {
937 FieldDecl *F = dyn_cast<FieldDecl>(*D);
938 if (!F || !F->isAnonymousStructOrUnion())
939 continue;
940
941 if (Context.hasSameType(F->getType(), AnonTy))
942 break;
943
944 ++Index;
945 }
946
947 return Index;
948}
949
Douglas Gregor3996e242010-02-15 22:01:00 +0000950/// \brief Determine structural equivalence of two records.
951static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
952 RecordDecl *D1, RecordDecl *D2) {
953 if (D1->isUnion() != D2->isUnion()) {
Douglas Gregor069bbaf2012-10-26 15:34:11 +0000954 if (Context.Complain) {
955 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
956 << Context.C2.getTypeDeclType(D2);
957 Context.Diag1(D1->getLocation(), diag::note_odr_tag_kind_here)
958 << D1->getDeclName() << (unsigned)D1->getTagKind();
959 }
Douglas Gregor3996e242010-02-15 22:01:00 +0000960 return false;
961 }
Douglas Gregorceb32bf2012-10-26 16:45:11 +0000962
963 if (D1->isAnonymousStructOrUnion() && D2->isAnonymousStructOrUnion()) {
964 // If both anonymous structs/unions are in a record context, make sure
965 // they occur in the same location in the context records.
David Blaikie05785d12013-02-20 22:23:23 +0000966 if (Optional<unsigned> Index1 = findAnonymousStructOrUnionIndex(D1)) {
967 if (Optional<unsigned> Index2 = findAnonymousStructOrUnionIndex(D2)) {
Douglas Gregorceb32bf2012-10-26 16:45:11 +0000968 if (*Index1 != *Index2)
969 return false;
970 }
971 }
972 }
973
Douglas Gregore2e50d332010-12-01 01:36:18 +0000974 // If both declarations are class template specializations, we know
975 // the ODR applies, so check the template and template arguments.
976 ClassTemplateSpecializationDecl *Spec1
977 = dyn_cast<ClassTemplateSpecializationDecl>(D1);
978 ClassTemplateSpecializationDecl *Spec2
979 = dyn_cast<ClassTemplateSpecializationDecl>(D2);
980 if (Spec1 && Spec2) {
981 // Check that the specialized templates are the same.
982 if (!IsStructurallyEquivalent(Context, Spec1->getSpecializedTemplate(),
983 Spec2->getSpecializedTemplate()))
984 return false;
985
986 // Check that the template arguments are the same.
987 if (Spec1->getTemplateArgs().size() != Spec2->getTemplateArgs().size())
988 return false;
989
990 for (unsigned I = 0, N = Spec1->getTemplateArgs().size(); I != N; ++I)
991 if (!IsStructurallyEquivalent(Context,
992 Spec1->getTemplateArgs().get(I),
993 Spec2->getTemplateArgs().get(I)))
994 return false;
995 }
996 // If one is a class template specialization and the other is not, these
Chris Lattner57540c52011-04-15 05:22:18 +0000997 // structures are different.
Douglas Gregore2e50d332010-12-01 01:36:18 +0000998 else if (Spec1 || Spec2)
999 return false;
1000
Douglas Gregorb4964f72010-02-15 23:54:17 +00001001 // Compare the definitions of these two records. If either or both are
1002 // incomplete, we assume that they are equivalent.
1003 D1 = D1->getDefinition();
1004 D2 = D2->getDefinition();
1005 if (!D1 || !D2)
1006 return true;
1007
Douglas Gregor3996e242010-02-15 22:01:00 +00001008 if (CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(D1)) {
1009 if (CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(D2)) {
1010 if (D1CXX->getNumBases() != D2CXX->getNumBases()) {
Douglas Gregor069bbaf2012-10-26 15:34:11 +00001011 if (Context.Complain) {
1012 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
1013 << Context.C2.getTypeDeclType(D2);
1014 Context.Diag2(D2->getLocation(), diag::note_odr_number_of_bases)
1015 << D2CXX->getNumBases();
1016 Context.Diag1(D1->getLocation(), diag::note_odr_number_of_bases)
1017 << D1CXX->getNumBases();
1018 }
Douglas Gregor3996e242010-02-15 22:01:00 +00001019 return false;
1020 }
1021
1022 // Check the base classes.
1023 for (CXXRecordDecl::base_class_iterator Base1 = D1CXX->bases_begin(),
1024 BaseEnd1 = D1CXX->bases_end(),
1025 Base2 = D2CXX->bases_begin();
1026 Base1 != BaseEnd1;
1027 ++Base1, ++Base2) {
1028 if (!IsStructurallyEquivalent(Context,
1029 Base1->getType(), Base2->getType())) {
Douglas Gregor069bbaf2012-10-26 15:34:11 +00001030 if (Context.Complain) {
1031 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
1032 << Context.C2.getTypeDeclType(D2);
1033 Context.Diag2(Base2->getLocStart(), diag::note_odr_base)
1034 << Base2->getType()
1035 << Base2->getSourceRange();
1036 Context.Diag1(Base1->getLocStart(), diag::note_odr_base)
1037 << Base1->getType()
1038 << Base1->getSourceRange();
1039 }
Douglas Gregor3996e242010-02-15 22:01:00 +00001040 return false;
1041 }
1042
1043 // Check virtual vs. non-virtual inheritance mismatch.
1044 if (Base1->isVirtual() != Base2->isVirtual()) {
Douglas Gregor069bbaf2012-10-26 15:34:11 +00001045 if (Context.Complain) {
1046 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
1047 << Context.C2.getTypeDeclType(D2);
1048 Context.Diag2(Base2->getLocStart(),
1049 diag::note_odr_virtual_base)
1050 << Base2->isVirtual() << Base2->getSourceRange();
1051 Context.Diag1(Base1->getLocStart(), diag::note_odr_base)
1052 << Base1->isVirtual()
1053 << Base1->getSourceRange();
1054 }
Douglas Gregor3996e242010-02-15 22:01:00 +00001055 return false;
1056 }
1057 }
1058 } else if (D1CXX->getNumBases() > 0) {
Douglas Gregor069bbaf2012-10-26 15:34:11 +00001059 if (Context.Complain) {
1060 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
1061 << Context.C2.getTypeDeclType(D2);
1062 const CXXBaseSpecifier *Base1 = D1CXX->bases_begin();
1063 Context.Diag1(Base1->getLocStart(), diag::note_odr_base)
1064 << Base1->getType()
1065 << Base1->getSourceRange();
1066 Context.Diag2(D2->getLocation(), diag::note_odr_missing_base);
1067 }
Douglas Gregor3996e242010-02-15 22:01:00 +00001068 return false;
1069 }
1070 }
1071
1072 // Check the fields for consistency.
Dmitri Gribenko898cff02012-05-19 17:17:26 +00001073 RecordDecl::field_iterator Field2 = D2->field_begin(),
Douglas Gregor3996e242010-02-15 22:01:00 +00001074 Field2End = D2->field_end();
Dmitri Gribenko898cff02012-05-19 17:17:26 +00001075 for (RecordDecl::field_iterator Field1 = D1->field_begin(),
Douglas Gregor3996e242010-02-15 22:01:00 +00001076 Field1End = D1->field_end();
1077 Field1 != Field1End;
1078 ++Field1, ++Field2) {
1079 if (Field2 == Field2End) {
Douglas Gregor069bbaf2012-10-26 15:34:11 +00001080 if (Context.Complain) {
1081 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
1082 << Context.C2.getTypeDeclType(D2);
1083 Context.Diag1(Field1->getLocation(), diag::note_odr_field)
1084 << Field1->getDeclName() << Field1->getType();
1085 Context.Diag2(D2->getLocation(), diag::note_odr_missing_field);
1086 }
Douglas Gregor3996e242010-02-15 22:01:00 +00001087 return false;
1088 }
1089
David Blaikie40ed2972012-06-06 20:45:41 +00001090 if (!IsStructurallyEquivalent(Context, *Field1, *Field2))
Douglas Gregor03d1ed32011-10-14 21:54:42 +00001091 return false;
Douglas Gregor3996e242010-02-15 22:01:00 +00001092 }
1093
1094 if (Field2 != Field2End) {
Douglas Gregor069bbaf2012-10-26 15:34:11 +00001095 if (Context.Complain) {
1096 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
1097 << Context.C2.getTypeDeclType(D2);
1098 Context.Diag2(Field2->getLocation(), diag::note_odr_field)
1099 << Field2->getDeclName() << Field2->getType();
1100 Context.Diag1(D1->getLocation(), diag::note_odr_missing_field);
1101 }
Douglas Gregor3996e242010-02-15 22:01:00 +00001102 return false;
1103 }
1104
1105 return true;
1106}
1107
1108/// \brief Determine structural equivalence of two enums.
1109static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
1110 EnumDecl *D1, EnumDecl *D2) {
1111 EnumDecl::enumerator_iterator EC2 = D2->enumerator_begin(),
1112 EC2End = D2->enumerator_end();
1113 for (EnumDecl::enumerator_iterator EC1 = D1->enumerator_begin(),
1114 EC1End = D1->enumerator_end();
1115 EC1 != EC1End; ++EC1, ++EC2) {
1116 if (EC2 == EC2End) {
Douglas Gregor069bbaf2012-10-26 15:34:11 +00001117 if (Context.Complain) {
1118 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
1119 << Context.C2.getTypeDeclType(D2);
1120 Context.Diag1(EC1->getLocation(), diag::note_odr_enumerator)
1121 << EC1->getDeclName()
1122 << EC1->getInitVal().toString(10);
1123 Context.Diag2(D2->getLocation(), diag::note_odr_missing_enumerator);
1124 }
Douglas Gregor3996e242010-02-15 22:01:00 +00001125 return false;
1126 }
1127
1128 llvm::APSInt Val1 = EC1->getInitVal();
1129 llvm::APSInt Val2 = EC2->getInitVal();
Eric Christopher6dcc3762012-07-15 00:23:57 +00001130 if (!llvm::APSInt::isSameValue(Val1, Val2) ||
Douglas Gregor3996e242010-02-15 22:01:00 +00001131 !IsStructurallyEquivalent(EC1->getIdentifier(), EC2->getIdentifier())) {
Douglas Gregor069bbaf2012-10-26 15:34:11 +00001132 if (Context.Complain) {
1133 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
1134 << Context.C2.getTypeDeclType(D2);
1135 Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
1136 << EC2->getDeclName()
1137 << EC2->getInitVal().toString(10);
1138 Context.Diag1(EC1->getLocation(), diag::note_odr_enumerator)
1139 << EC1->getDeclName()
1140 << EC1->getInitVal().toString(10);
1141 }
Douglas Gregor3996e242010-02-15 22:01:00 +00001142 return false;
1143 }
1144 }
1145
1146 if (EC2 != EC2End) {
Douglas Gregor069bbaf2012-10-26 15:34:11 +00001147 if (Context.Complain) {
1148 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
1149 << Context.C2.getTypeDeclType(D2);
1150 Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
1151 << EC2->getDeclName()
1152 << EC2->getInitVal().toString(10);
1153 Context.Diag1(D1->getLocation(), diag::note_odr_missing_enumerator);
1154 }
Douglas Gregor3996e242010-02-15 22:01:00 +00001155 return false;
1156 }
1157
1158 return true;
1159}
Douglas Gregora082a492010-11-30 19:14:50 +00001160
1161static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
1162 TemplateParameterList *Params1,
1163 TemplateParameterList *Params2) {
1164 if (Params1->size() != Params2->size()) {
Douglas Gregor069bbaf2012-10-26 15:34:11 +00001165 if (Context.Complain) {
1166 Context.Diag2(Params2->getTemplateLoc(),
1167 diag::err_odr_different_num_template_parameters)
1168 << Params1->size() << Params2->size();
1169 Context.Diag1(Params1->getTemplateLoc(),
1170 diag::note_odr_template_parameter_list);
1171 }
Douglas Gregora082a492010-11-30 19:14:50 +00001172 return false;
1173 }
Douglas Gregor3996e242010-02-15 22:01:00 +00001174
Douglas Gregora082a492010-11-30 19:14:50 +00001175 for (unsigned I = 0, N = Params1->size(); I != N; ++I) {
1176 if (Params1->getParam(I)->getKind() != Params2->getParam(I)->getKind()) {
Douglas Gregor069bbaf2012-10-26 15:34:11 +00001177 if (Context.Complain) {
1178 Context.Diag2(Params2->getParam(I)->getLocation(),
1179 diag::err_odr_different_template_parameter_kind);
1180 Context.Diag1(Params1->getParam(I)->getLocation(),
1181 diag::note_odr_template_parameter_here);
1182 }
Douglas Gregora082a492010-11-30 19:14:50 +00001183 return false;
1184 }
1185
1186 if (!Context.IsStructurallyEquivalent(Params1->getParam(I),
1187 Params2->getParam(I))) {
1188
1189 return false;
1190 }
1191 }
1192
1193 return true;
1194}
1195
1196static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
1197 TemplateTypeParmDecl *D1,
1198 TemplateTypeParmDecl *D2) {
1199 if (D1->isParameterPack() != D2->isParameterPack()) {
Douglas Gregor069bbaf2012-10-26 15:34:11 +00001200 if (Context.Complain) {
1201 Context.Diag2(D2->getLocation(), diag::err_odr_parameter_pack_non_pack)
1202 << D2->isParameterPack();
1203 Context.Diag1(D1->getLocation(), diag::note_odr_parameter_pack_non_pack)
1204 << D1->isParameterPack();
1205 }
Douglas Gregora082a492010-11-30 19:14:50 +00001206 return false;
1207 }
1208
1209 return true;
1210}
1211
1212static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
1213 NonTypeTemplateParmDecl *D1,
1214 NonTypeTemplateParmDecl *D2) {
Douglas Gregora082a492010-11-30 19:14:50 +00001215 if (D1->isParameterPack() != D2->isParameterPack()) {
Douglas Gregor3c7380b2012-10-26 15:36:15 +00001216 if (Context.Complain) {
Douglas Gregor069bbaf2012-10-26 15:34:11 +00001217 Context.Diag2(D2->getLocation(), diag::err_odr_parameter_pack_non_pack)
1218 << D2->isParameterPack();
1219 Context.Diag1(D1->getLocation(), diag::note_odr_parameter_pack_non_pack)
1220 << D1->isParameterPack();
1221 }
Douglas Gregora082a492010-11-30 19:14:50 +00001222 return false;
1223 }
Douglas Gregora082a492010-11-30 19:14:50 +00001224
1225 // Check types.
1226 if (!Context.IsStructurallyEquivalent(D1->getType(), D2->getType())) {
Douglas Gregor069bbaf2012-10-26 15:34:11 +00001227 if (Context.Complain) {
1228 Context.Diag2(D2->getLocation(),
1229 diag::err_odr_non_type_parameter_type_inconsistent)
1230 << D2->getType() << D1->getType();
1231 Context.Diag1(D1->getLocation(), diag::note_odr_value_here)
1232 << D1->getType();
1233 }
Douglas Gregora082a492010-11-30 19:14:50 +00001234 return false;
1235 }
1236
1237 return true;
1238}
1239
1240static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
1241 TemplateTemplateParmDecl *D1,
1242 TemplateTemplateParmDecl *D2) {
Douglas Gregora082a492010-11-30 19:14:50 +00001243 if (D1->isParameterPack() != D2->isParameterPack()) {
Douglas Gregor069bbaf2012-10-26 15:34:11 +00001244 if (Context.Complain) {
1245 Context.Diag2(D2->getLocation(), diag::err_odr_parameter_pack_non_pack)
1246 << D2->isParameterPack();
1247 Context.Diag1(D1->getLocation(), diag::note_odr_parameter_pack_non_pack)
1248 << D1->isParameterPack();
1249 }
Douglas Gregora082a492010-11-30 19:14:50 +00001250 return false;
1251 }
Douglas Gregor3c7380b2012-10-26 15:36:15 +00001252
Douglas Gregora082a492010-11-30 19:14:50 +00001253 // Check template parameter lists.
1254 return IsStructurallyEquivalent(Context, D1->getTemplateParameters(),
1255 D2->getTemplateParameters());
1256}
1257
1258static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
1259 ClassTemplateDecl *D1,
1260 ClassTemplateDecl *D2) {
1261 // Check template parameters.
1262 if (!IsStructurallyEquivalent(Context,
1263 D1->getTemplateParameters(),
1264 D2->getTemplateParameters()))
1265 return false;
1266
1267 // Check the templated declaration.
1268 return Context.IsStructurallyEquivalent(D1->getTemplatedDecl(),
1269 D2->getTemplatedDecl());
1270}
1271
Douglas Gregor3996e242010-02-15 22:01:00 +00001272/// \brief Determine structural equivalence of two declarations.
1273static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
1274 Decl *D1, Decl *D2) {
1275 // FIXME: Check for known structural equivalences via a callback of some sort.
1276
Douglas Gregorb4964f72010-02-15 23:54:17 +00001277 // Check whether we already know that these two declarations are not
1278 // structurally equivalent.
1279 if (Context.NonEquivalentDecls.count(std::make_pair(D1->getCanonicalDecl(),
1280 D2->getCanonicalDecl())))
1281 return false;
1282
Douglas Gregor3996e242010-02-15 22:01:00 +00001283 // Determine whether we've already produced a tentative equivalence for D1.
1284 Decl *&EquivToD1 = Context.TentativeEquivalences[D1->getCanonicalDecl()];
1285 if (EquivToD1)
1286 return EquivToD1 == D2->getCanonicalDecl();
1287
1288 // Produce a tentative equivalence D1 <-> D2, which will be checked later.
1289 EquivToD1 = D2->getCanonicalDecl();
1290 Context.DeclsToCheck.push_back(D1->getCanonicalDecl());
1291 return true;
1292}
1293
1294bool StructuralEquivalenceContext::IsStructurallyEquivalent(Decl *D1,
1295 Decl *D2) {
1296 if (!::IsStructurallyEquivalent(*this, D1, D2))
1297 return false;
1298
1299 return !Finish();
1300}
1301
1302bool StructuralEquivalenceContext::IsStructurallyEquivalent(QualType T1,
1303 QualType T2) {
1304 if (!::IsStructurallyEquivalent(*this, T1, T2))
1305 return false;
1306
1307 return !Finish();
1308}
1309
1310bool StructuralEquivalenceContext::Finish() {
1311 while (!DeclsToCheck.empty()) {
1312 // Check the next declaration.
1313 Decl *D1 = DeclsToCheck.front();
1314 DeclsToCheck.pop_front();
1315
1316 Decl *D2 = TentativeEquivalences[D1];
1317 assert(D2 && "Unrecorded tentative equivalence?");
1318
Douglas Gregorb4964f72010-02-15 23:54:17 +00001319 bool Equivalent = true;
1320
Douglas Gregor3996e242010-02-15 22:01:00 +00001321 // FIXME: Switch on all declaration kinds. For now, we're just going to
1322 // check the obvious ones.
1323 if (RecordDecl *Record1 = dyn_cast<RecordDecl>(D1)) {
1324 if (RecordDecl *Record2 = dyn_cast<RecordDecl>(D2)) {
1325 // Check for equivalent structure names.
1326 IdentifierInfo *Name1 = Record1->getIdentifier();
Richard Smithdda56e42011-04-15 14:24:37 +00001327 if (!Name1 && Record1->getTypedefNameForAnonDecl())
1328 Name1 = Record1->getTypedefNameForAnonDecl()->getIdentifier();
Douglas Gregor3996e242010-02-15 22:01:00 +00001329 IdentifierInfo *Name2 = Record2->getIdentifier();
Richard Smithdda56e42011-04-15 14:24:37 +00001330 if (!Name2 && Record2->getTypedefNameForAnonDecl())
1331 Name2 = Record2->getTypedefNameForAnonDecl()->getIdentifier();
Douglas Gregorb4964f72010-02-15 23:54:17 +00001332 if (!::IsStructurallyEquivalent(Name1, Name2) ||
1333 !::IsStructurallyEquivalent(*this, Record1, Record2))
1334 Equivalent = false;
Douglas Gregor3996e242010-02-15 22:01:00 +00001335 } else {
1336 // Record/non-record mismatch.
Douglas Gregorb4964f72010-02-15 23:54:17 +00001337 Equivalent = false;
Douglas Gregor3996e242010-02-15 22:01:00 +00001338 }
Douglas Gregorb4964f72010-02-15 23:54:17 +00001339 } else if (EnumDecl *Enum1 = dyn_cast<EnumDecl>(D1)) {
Douglas Gregor3996e242010-02-15 22:01:00 +00001340 if (EnumDecl *Enum2 = dyn_cast<EnumDecl>(D2)) {
1341 // Check for equivalent enum names.
1342 IdentifierInfo *Name1 = Enum1->getIdentifier();
Richard Smithdda56e42011-04-15 14:24:37 +00001343 if (!Name1 && Enum1->getTypedefNameForAnonDecl())
1344 Name1 = Enum1->getTypedefNameForAnonDecl()->getIdentifier();
Douglas Gregor3996e242010-02-15 22:01:00 +00001345 IdentifierInfo *Name2 = Enum2->getIdentifier();
Richard Smithdda56e42011-04-15 14:24:37 +00001346 if (!Name2 && Enum2->getTypedefNameForAnonDecl())
1347 Name2 = Enum2->getTypedefNameForAnonDecl()->getIdentifier();
Douglas Gregorb4964f72010-02-15 23:54:17 +00001348 if (!::IsStructurallyEquivalent(Name1, Name2) ||
1349 !::IsStructurallyEquivalent(*this, Enum1, Enum2))
1350 Equivalent = false;
Douglas Gregor3996e242010-02-15 22:01:00 +00001351 } else {
1352 // Enum/non-enum mismatch
Douglas Gregorb4964f72010-02-15 23:54:17 +00001353 Equivalent = false;
Douglas Gregor3996e242010-02-15 22:01:00 +00001354 }
Richard Smithdda56e42011-04-15 14:24:37 +00001355 } else if (TypedefNameDecl *Typedef1 = dyn_cast<TypedefNameDecl>(D1)) {
1356 if (TypedefNameDecl *Typedef2 = dyn_cast<TypedefNameDecl>(D2)) {
Douglas Gregor3996e242010-02-15 22:01:00 +00001357 if (!::IsStructurallyEquivalent(Typedef1->getIdentifier(),
Douglas Gregorb4964f72010-02-15 23:54:17 +00001358 Typedef2->getIdentifier()) ||
1359 !::IsStructurallyEquivalent(*this,
Douglas Gregor3996e242010-02-15 22:01:00 +00001360 Typedef1->getUnderlyingType(),
1361 Typedef2->getUnderlyingType()))
Douglas Gregorb4964f72010-02-15 23:54:17 +00001362 Equivalent = false;
Douglas Gregor3996e242010-02-15 22:01:00 +00001363 } else {
1364 // Typedef/non-typedef mismatch.
Douglas Gregorb4964f72010-02-15 23:54:17 +00001365 Equivalent = false;
Douglas Gregor3996e242010-02-15 22:01:00 +00001366 }
Douglas Gregora082a492010-11-30 19:14:50 +00001367 } else if (ClassTemplateDecl *ClassTemplate1
1368 = dyn_cast<ClassTemplateDecl>(D1)) {
1369 if (ClassTemplateDecl *ClassTemplate2 = dyn_cast<ClassTemplateDecl>(D2)) {
1370 if (!::IsStructurallyEquivalent(ClassTemplate1->getIdentifier(),
1371 ClassTemplate2->getIdentifier()) ||
1372 !::IsStructurallyEquivalent(*this, ClassTemplate1, ClassTemplate2))
1373 Equivalent = false;
1374 } else {
1375 // Class template/non-class-template mismatch.
1376 Equivalent = false;
1377 }
1378 } else if (TemplateTypeParmDecl *TTP1= dyn_cast<TemplateTypeParmDecl>(D1)) {
1379 if (TemplateTypeParmDecl *TTP2 = dyn_cast<TemplateTypeParmDecl>(D2)) {
1380 if (!::IsStructurallyEquivalent(*this, TTP1, TTP2))
1381 Equivalent = false;
1382 } else {
1383 // Kind mismatch.
1384 Equivalent = false;
1385 }
1386 } else if (NonTypeTemplateParmDecl *NTTP1
1387 = dyn_cast<NonTypeTemplateParmDecl>(D1)) {
1388 if (NonTypeTemplateParmDecl *NTTP2
1389 = dyn_cast<NonTypeTemplateParmDecl>(D2)) {
1390 if (!::IsStructurallyEquivalent(*this, NTTP1, NTTP2))
1391 Equivalent = false;
1392 } else {
1393 // Kind mismatch.
1394 Equivalent = false;
1395 }
1396 } else if (TemplateTemplateParmDecl *TTP1
1397 = dyn_cast<TemplateTemplateParmDecl>(D1)) {
1398 if (TemplateTemplateParmDecl *TTP2
1399 = dyn_cast<TemplateTemplateParmDecl>(D2)) {
1400 if (!::IsStructurallyEquivalent(*this, TTP1, TTP2))
1401 Equivalent = false;
1402 } else {
1403 // Kind mismatch.
1404 Equivalent = false;
1405 }
1406 }
1407
Douglas Gregorb4964f72010-02-15 23:54:17 +00001408 if (!Equivalent) {
1409 // Note that these two declarations are not equivalent (and we already
1410 // know about it).
1411 NonEquivalentDecls.insert(std::make_pair(D1->getCanonicalDecl(),
1412 D2->getCanonicalDecl()));
1413 return true;
1414 }
Douglas Gregor3996e242010-02-15 22:01:00 +00001415 // FIXME: Check other declaration kinds!
1416 }
1417
1418 return false;
1419}
1420
1421//----------------------------------------------------------------------------
Douglas Gregor96e578d2010-02-05 17:54:41 +00001422// Import Types
1423//----------------------------------------------------------------------------
1424
John McCall424cec92011-01-19 06:33:43 +00001425QualType ASTNodeImporter::VisitType(const Type *T) {
Douglas Gregore4c83e42010-02-09 22:48:33 +00001426 Importer.FromDiag(SourceLocation(), diag::err_unsupported_ast_node)
1427 << T->getTypeClassName();
1428 return QualType();
1429}
1430
John McCall424cec92011-01-19 06:33:43 +00001431QualType ASTNodeImporter::VisitBuiltinType(const BuiltinType *T) {
Douglas Gregor96e578d2010-02-05 17:54:41 +00001432 switch (T->getKind()) {
John McCalle314e272011-10-18 21:02:43 +00001433#define SHARED_SINGLETON_TYPE(Expansion)
1434#define BUILTIN_TYPE(Id, SingletonId) \
1435 case BuiltinType::Id: return Importer.getToContext().SingletonId;
1436#include "clang/AST/BuiltinTypes.def"
1437
1438 // FIXME: for Char16, Char32, and NullPtr, make sure that the "to"
1439 // context supports C++.
1440
1441 // FIXME: for ObjCId, ObjCClass, and ObjCSel, make sure that the "to"
1442 // context supports ObjC.
1443
Douglas Gregor96e578d2010-02-05 17:54:41 +00001444 case BuiltinType::Char_U:
1445 // The context we're importing from has an unsigned 'char'. If we're
1446 // importing into a context with a signed 'char', translate to
1447 // 'unsigned char' instead.
David Blaikiebbafb8a2012-03-11 07:00:24 +00001448 if (Importer.getToContext().getLangOpts().CharIsSigned)
Douglas Gregor96e578d2010-02-05 17:54:41 +00001449 return Importer.getToContext().UnsignedCharTy;
1450
1451 return Importer.getToContext().CharTy;
1452
Douglas Gregor96e578d2010-02-05 17:54:41 +00001453 case BuiltinType::Char_S:
1454 // The context we're importing from has an unsigned 'char'. If we're
1455 // importing into a context with a signed 'char', translate to
1456 // 'unsigned char' instead.
David Blaikiebbafb8a2012-03-11 07:00:24 +00001457 if (!Importer.getToContext().getLangOpts().CharIsSigned)
Douglas Gregor96e578d2010-02-05 17:54:41 +00001458 return Importer.getToContext().SignedCharTy;
1459
1460 return Importer.getToContext().CharTy;
1461
Chris Lattnerad3467e2010-12-25 23:25:43 +00001462 case BuiltinType::WChar_S:
1463 case BuiltinType::WChar_U:
Douglas Gregor96e578d2010-02-05 17:54:41 +00001464 // FIXME: If not in C++, shall we translate to the C equivalent of
1465 // wchar_t?
1466 return Importer.getToContext().WCharTy;
Douglas Gregor96e578d2010-02-05 17:54:41 +00001467 }
David Blaikiee4d798f2012-01-20 21:50:17 +00001468
1469 llvm_unreachable("Invalid BuiltinType Kind!");
Douglas Gregor96e578d2010-02-05 17:54:41 +00001470}
1471
John McCall424cec92011-01-19 06:33:43 +00001472QualType ASTNodeImporter::VisitComplexType(const ComplexType *T) {
Douglas Gregor96e578d2010-02-05 17:54:41 +00001473 QualType ToElementType = Importer.Import(T->getElementType());
1474 if (ToElementType.isNull())
1475 return QualType();
1476
1477 return Importer.getToContext().getComplexType(ToElementType);
1478}
1479
John McCall424cec92011-01-19 06:33:43 +00001480QualType ASTNodeImporter::VisitPointerType(const PointerType *T) {
Douglas Gregor96e578d2010-02-05 17:54:41 +00001481 QualType ToPointeeType = Importer.Import(T->getPointeeType());
1482 if (ToPointeeType.isNull())
1483 return QualType();
1484
1485 return Importer.getToContext().getPointerType(ToPointeeType);
1486}
1487
John McCall424cec92011-01-19 06:33:43 +00001488QualType ASTNodeImporter::VisitBlockPointerType(const BlockPointerType *T) {
Douglas Gregor96e578d2010-02-05 17:54:41 +00001489 // FIXME: Check for blocks support in "to" context.
1490 QualType ToPointeeType = Importer.Import(T->getPointeeType());
1491 if (ToPointeeType.isNull())
1492 return QualType();
1493
1494 return Importer.getToContext().getBlockPointerType(ToPointeeType);
1495}
1496
John McCall424cec92011-01-19 06:33:43 +00001497QualType
1498ASTNodeImporter::VisitLValueReferenceType(const LValueReferenceType *T) {
Douglas Gregor96e578d2010-02-05 17:54:41 +00001499 // FIXME: Check for C++ support in "to" context.
1500 QualType ToPointeeType = Importer.Import(T->getPointeeTypeAsWritten());
1501 if (ToPointeeType.isNull())
1502 return QualType();
1503
1504 return Importer.getToContext().getLValueReferenceType(ToPointeeType);
1505}
1506
John McCall424cec92011-01-19 06:33:43 +00001507QualType
1508ASTNodeImporter::VisitRValueReferenceType(const RValueReferenceType *T) {
Douglas Gregor96e578d2010-02-05 17:54:41 +00001509 // FIXME: Check for C++0x support in "to" context.
1510 QualType ToPointeeType = Importer.Import(T->getPointeeTypeAsWritten());
1511 if (ToPointeeType.isNull())
1512 return QualType();
1513
1514 return Importer.getToContext().getRValueReferenceType(ToPointeeType);
1515}
1516
John McCall424cec92011-01-19 06:33:43 +00001517QualType ASTNodeImporter::VisitMemberPointerType(const MemberPointerType *T) {
Douglas Gregor96e578d2010-02-05 17:54:41 +00001518 // FIXME: Check for C++ support in "to" context.
1519 QualType ToPointeeType = Importer.Import(T->getPointeeType());
1520 if (ToPointeeType.isNull())
1521 return QualType();
1522
1523 QualType ClassType = Importer.Import(QualType(T->getClass(), 0));
1524 return Importer.getToContext().getMemberPointerType(ToPointeeType,
1525 ClassType.getTypePtr());
1526}
1527
John McCall424cec92011-01-19 06:33:43 +00001528QualType ASTNodeImporter::VisitConstantArrayType(const ConstantArrayType *T) {
Douglas Gregor96e578d2010-02-05 17:54:41 +00001529 QualType ToElementType = Importer.Import(T->getElementType());
1530 if (ToElementType.isNull())
1531 return QualType();
1532
1533 return Importer.getToContext().getConstantArrayType(ToElementType,
1534 T->getSize(),
1535 T->getSizeModifier(),
1536 T->getIndexTypeCVRQualifiers());
1537}
1538
John McCall424cec92011-01-19 06:33:43 +00001539QualType
1540ASTNodeImporter::VisitIncompleteArrayType(const IncompleteArrayType *T) {
Douglas Gregor96e578d2010-02-05 17:54:41 +00001541 QualType ToElementType = Importer.Import(T->getElementType());
1542 if (ToElementType.isNull())
1543 return QualType();
1544
1545 return Importer.getToContext().getIncompleteArrayType(ToElementType,
1546 T->getSizeModifier(),
1547 T->getIndexTypeCVRQualifiers());
1548}
1549
John McCall424cec92011-01-19 06:33:43 +00001550QualType ASTNodeImporter::VisitVariableArrayType(const VariableArrayType *T) {
Douglas Gregor96e578d2010-02-05 17:54:41 +00001551 QualType ToElementType = Importer.Import(T->getElementType());
1552 if (ToElementType.isNull())
1553 return QualType();
1554
1555 Expr *Size = Importer.Import(T->getSizeExpr());
1556 if (!Size)
1557 return QualType();
1558
1559 SourceRange Brackets = Importer.Import(T->getBracketsRange());
1560 return Importer.getToContext().getVariableArrayType(ToElementType, Size,
1561 T->getSizeModifier(),
1562 T->getIndexTypeCVRQualifiers(),
1563 Brackets);
1564}
1565
John McCall424cec92011-01-19 06:33:43 +00001566QualType ASTNodeImporter::VisitVectorType(const VectorType *T) {
Douglas Gregor96e578d2010-02-05 17:54:41 +00001567 QualType ToElementType = Importer.Import(T->getElementType());
1568 if (ToElementType.isNull())
1569 return QualType();
1570
1571 return Importer.getToContext().getVectorType(ToElementType,
1572 T->getNumElements(),
Bob Wilsonaeb56442010-11-10 21:56:12 +00001573 T->getVectorKind());
Douglas Gregor96e578d2010-02-05 17:54:41 +00001574}
1575
John McCall424cec92011-01-19 06:33:43 +00001576QualType ASTNodeImporter::VisitExtVectorType(const ExtVectorType *T) {
Douglas Gregor96e578d2010-02-05 17:54:41 +00001577 QualType ToElementType = Importer.Import(T->getElementType());
1578 if (ToElementType.isNull())
1579 return QualType();
1580
1581 return Importer.getToContext().getExtVectorType(ToElementType,
1582 T->getNumElements());
1583}
1584
John McCall424cec92011-01-19 06:33:43 +00001585QualType
1586ASTNodeImporter::VisitFunctionNoProtoType(const FunctionNoProtoType *T) {
Douglas Gregor96e578d2010-02-05 17:54:41 +00001587 // FIXME: What happens if we're importing a function without a prototype
1588 // into C++? Should we make it variadic?
1589 QualType ToResultType = Importer.Import(T->getResultType());
1590 if (ToResultType.isNull())
1591 return QualType();
Rafael Espindolac50c27c2010-03-30 20:24:48 +00001592
Douglas Gregor96e578d2010-02-05 17:54:41 +00001593 return Importer.getToContext().getFunctionNoProtoType(ToResultType,
Rafael Espindolac50c27c2010-03-30 20:24:48 +00001594 T->getExtInfo());
Douglas Gregor96e578d2010-02-05 17:54:41 +00001595}
1596
Argyrios Kyrtzidis2f458532012-09-25 19:26:39 +00001597QualType ASTNodeImporter::VisitFunctionProtoType(const FunctionProtoType *T) {
Douglas Gregor96e578d2010-02-05 17:54:41 +00001598 QualType ToResultType = Importer.Import(T->getResultType());
1599 if (ToResultType.isNull())
1600 return QualType();
1601
1602 // Import argument types
Chris Lattner0e62c1c2011-07-23 10:55:15 +00001603 SmallVector<QualType, 4> ArgTypes;
Douglas Gregor96e578d2010-02-05 17:54:41 +00001604 for (FunctionProtoType::arg_type_iterator A = T->arg_type_begin(),
1605 AEnd = T->arg_type_end();
1606 A != AEnd; ++A) {
1607 QualType ArgType = Importer.Import(*A);
1608 if (ArgType.isNull())
1609 return QualType();
1610 ArgTypes.push_back(ArgType);
1611 }
1612
1613 // Import exception types
Chris Lattner0e62c1c2011-07-23 10:55:15 +00001614 SmallVector<QualType, 4> ExceptionTypes;
Douglas Gregor96e578d2010-02-05 17:54:41 +00001615 for (FunctionProtoType::exception_iterator E = T->exception_begin(),
1616 EEnd = T->exception_end();
1617 E != EEnd; ++E) {
1618 QualType ExceptionType = Importer.Import(*E);
1619 if (ExceptionType.isNull())
1620 return QualType();
1621 ExceptionTypes.push_back(ExceptionType);
1622 }
John McCalldb40c7f2010-12-14 08:05:40 +00001623
Argyrios Kyrtzidisb41791d2012-09-22 01:58:06 +00001624 FunctionProtoType::ExtProtoInfo FromEPI = T->getExtProtoInfo();
1625 FunctionProtoType::ExtProtoInfo ToEPI;
1626
1627 ToEPI.ExtInfo = FromEPI.ExtInfo;
1628 ToEPI.Variadic = FromEPI.Variadic;
1629 ToEPI.HasTrailingReturn = FromEPI.HasTrailingReturn;
1630 ToEPI.TypeQuals = FromEPI.TypeQuals;
1631 ToEPI.RefQualifier = FromEPI.RefQualifier;
1632 ToEPI.NumExceptions = ExceptionTypes.size();
1633 ToEPI.Exceptions = ExceptionTypes.data();
1634 ToEPI.ConsumedArguments = FromEPI.ConsumedArguments;
Argyrios Kyrtzidis2f458532012-09-25 19:26:39 +00001635 ToEPI.ExceptionSpecType = FromEPI.ExceptionSpecType;
1636 ToEPI.NoexceptExpr = Importer.Import(FromEPI.NoexceptExpr);
1637 ToEPI.ExceptionSpecDecl = cast_or_null<FunctionDecl>(
Argyrios Kyrtzidisb41791d2012-09-22 01:58:06 +00001638 Importer.Import(FromEPI.ExceptionSpecDecl));
Argyrios Kyrtzidis2f458532012-09-25 19:26:39 +00001639 ToEPI.ExceptionSpecTemplate = cast_or_null<FunctionDecl>(
Argyrios Kyrtzidisb41791d2012-09-22 01:58:06 +00001640 Importer.Import(FromEPI.ExceptionSpecTemplate));
Argyrios Kyrtzidisb41791d2012-09-22 01:58:06 +00001641
Jordan Rose5c382722013-03-08 21:51:21 +00001642 return Importer.getToContext().getFunctionType(ToResultType, ArgTypes, ToEPI);
Argyrios Kyrtzidisb41791d2012-09-22 01:58:06 +00001643}
1644
Sean Callananda6df8a2011-08-11 16:56:07 +00001645QualType ASTNodeImporter::VisitParenType(const ParenType *T) {
1646 QualType ToInnerType = Importer.Import(T->getInnerType());
1647 if (ToInnerType.isNull())
1648 return QualType();
1649
1650 return Importer.getToContext().getParenType(ToInnerType);
1651}
1652
John McCall424cec92011-01-19 06:33:43 +00001653QualType ASTNodeImporter::VisitTypedefType(const TypedefType *T) {
Richard Smithdda56e42011-04-15 14:24:37 +00001654 TypedefNameDecl *ToDecl
1655 = dyn_cast_or_null<TypedefNameDecl>(Importer.Import(T->getDecl()));
Douglas Gregor96e578d2010-02-05 17:54:41 +00001656 if (!ToDecl)
1657 return QualType();
1658
1659 return Importer.getToContext().getTypeDeclType(ToDecl);
1660}
1661
John McCall424cec92011-01-19 06:33:43 +00001662QualType ASTNodeImporter::VisitTypeOfExprType(const TypeOfExprType *T) {
Douglas Gregor96e578d2010-02-05 17:54:41 +00001663 Expr *ToExpr = Importer.Import(T->getUnderlyingExpr());
1664 if (!ToExpr)
1665 return QualType();
1666
1667 return Importer.getToContext().getTypeOfExprType(ToExpr);
1668}
1669
John McCall424cec92011-01-19 06:33:43 +00001670QualType ASTNodeImporter::VisitTypeOfType(const TypeOfType *T) {
Douglas Gregor96e578d2010-02-05 17:54:41 +00001671 QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType());
1672 if (ToUnderlyingType.isNull())
1673 return QualType();
1674
1675 return Importer.getToContext().getTypeOfType(ToUnderlyingType);
1676}
1677
John McCall424cec92011-01-19 06:33:43 +00001678QualType ASTNodeImporter::VisitDecltypeType(const DecltypeType *T) {
Richard Smith30482bc2011-02-20 03:19:35 +00001679 // FIXME: Make sure that the "to" context supports C++0x!
Douglas Gregor96e578d2010-02-05 17:54:41 +00001680 Expr *ToExpr = Importer.Import(T->getUnderlyingExpr());
1681 if (!ToExpr)
1682 return QualType();
1683
Douglas Gregor81495f32012-02-12 18:42:33 +00001684 QualType UnderlyingType = Importer.Import(T->getUnderlyingType());
1685 if (UnderlyingType.isNull())
1686 return QualType();
1687
1688 return Importer.getToContext().getDecltypeType(ToExpr, UnderlyingType);
Douglas Gregor96e578d2010-02-05 17:54:41 +00001689}
1690
Alexis Hunte852b102011-05-24 22:41:36 +00001691QualType ASTNodeImporter::VisitUnaryTransformType(const UnaryTransformType *T) {
1692 QualType ToBaseType = Importer.Import(T->getBaseType());
1693 QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType());
1694 if (ToBaseType.isNull() || ToUnderlyingType.isNull())
1695 return QualType();
1696
1697 return Importer.getToContext().getUnaryTransformType(ToBaseType,
1698 ToUnderlyingType,
1699 T->getUTTKind());
1700}
1701
Richard Smith30482bc2011-02-20 03:19:35 +00001702QualType ASTNodeImporter::VisitAutoType(const AutoType *T) {
Richard Smith74aeef52013-04-26 16:15:35 +00001703 // FIXME: Make sure that the "to" context supports C++11!
Richard Smith30482bc2011-02-20 03:19:35 +00001704 QualType FromDeduced = T->getDeducedType();
1705 QualType ToDeduced;
1706 if (!FromDeduced.isNull()) {
1707 ToDeduced = Importer.Import(FromDeduced);
1708 if (ToDeduced.isNull())
1709 return QualType();
1710 }
1711
Faisal Vali2b391ab2013-09-26 19:54:12 +00001712 return Importer.getToContext().getAutoType(ToDeduced, T->isDecltypeAuto(),
1713 /*IsDependent*/false);
Richard Smith30482bc2011-02-20 03:19:35 +00001714}
1715
John McCall424cec92011-01-19 06:33:43 +00001716QualType ASTNodeImporter::VisitRecordType(const RecordType *T) {
Douglas Gregor96e578d2010-02-05 17:54:41 +00001717 RecordDecl *ToDecl
1718 = dyn_cast_or_null<RecordDecl>(Importer.Import(T->getDecl()));
1719 if (!ToDecl)
1720 return QualType();
1721
1722 return Importer.getToContext().getTagDeclType(ToDecl);
1723}
1724
John McCall424cec92011-01-19 06:33:43 +00001725QualType ASTNodeImporter::VisitEnumType(const EnumType *T) {
Douglas Gregor96e578d2010-02-05 17:54:41 +00001726 EnumDecl *ToDecl
1727 = dyn_cast_or_null<EnumDecl>(Importer.Import(T->getDecl()));
1728 if (!ToDecl)
1729 return QualType();
1730
1731 return Importer.getToContext().getTagDeclType(ToDecl);
1732}
1733
Douglas Gregore2e50d332010-12-01 01:36:18 +00001734QualType ASTNodeImporter::VisitTemplateSpecializationType(
John McCall424cec92011-01-19 06:33:43 +00001735 const TemplateSpecializationType *T) {
Douglas Gregore2e50d332010-12-01 01:36:18 +00001736 TemplateName ToTemplate = Importer.Import(T->getTemplateName());
1737 if (ToTemplate.isNull())
1738 return QualType();
1739
Chris Lattner0e62c1c2011-07-23 10:55:15 +00001740 SmallVector<TemplateArgument, 2> ToTemplateArgs;
Douglas Gregore2e50d332010-12-01 01:36:18 +00001741 if (ImportTemplateArguments(T->getArgs(), T->getNumArgs(), ToTemplateArgs))
1742 return QualType();
1743
1744 QualType ToCanonType;
1745 if (!QualType(T, 0).isCanonical()) {
1746 QualType FromCanonType
1747 = Importer.getFromContext().getCanonicalType(QualType(T, 0));
1748 ToCanonType =Importer.Import(FromCanonType);
1749 if (ToCanonType.isNull())
1750 return QualType();
1751 }
1752 return Importer.getToContext().getTemplateSpecializationType(ToTemplate,
1753 ToTemplateArgs.data(),
1754 ToTemplateArgs.size(),
1755 ToCanonType);
1756}
1757
John McCall424cec92011-01-19 06:33:43 +00001758QualType ASTNodeImporter::VisitElaboratedType(const ElaboratedType *T) {
Abramo Bagnara6150c882010-05-11 21:36:43 +00001759 NestedNameSpecifier *ToQualifier = 0;
1760 // Note: the qualifier in an ElaboratedType is optional.
1761 if (T->getQualifier()) {
1762 ToQualifier = Importer.Import(T->getQualifier());
1763 if (!ToQualifier)
1764 return QualType();
1765 }
Douglas Gregor96e578d2010-02-05 17:54:41 +00001766
1767 QualType ToNamedType = Importer.Import(T->getNamedType());
1768 if (ToNamedType.isNull())
1769 return QualType();
1770
Abramo Bagnara6150c882010-05-11 21:36:43 +00001771 return Importer.getToContext().getElaboratedType(T->getKeyword(),
1772 ToQualifier, ToNamedType);
Douglas Gregor96e578d2010-02-05 17:54:41 +00001773}
1774
John McCall424cec92011-01-19 06:33:43 +00001775QualType ASTNodeImporter::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
Douglas Gregor96e578d2010-02-05 17:54:41 +00001776 ObjCInterfaceDecl *Class
1777 = dyn_cast_or_null<ObjCInterfaceDecl>(Importer.Import(T->getDecl()));
1778 if (!Class)
1779 return QualType();
1780
John McCall8b07ec22010-05-15 11:32:37 +00001781 return Importer.getToContext().getObjCInterfaceType(Class);
1782}
1783
John McCall424cec92011-01-19 06:33:43 +00001784QualType ASTNodeImporter::VisitObjCObjectType(const ObjCObjectType *T) {
John McCall8b07ec22010-05-15 11:32:37 +00001785 QualType ToBaseType = Importer.Import(T->getBaseType());
1786 if (ToBaseType.isNull())
1787 return QualType();
1788
Chris Lattner0e62c1c2011-07-23 10:55:15 +00001789 SmallVector<ObjCProtocolDecl *, 4> Protocols;
John McCall8b07ec22010-05-15 11:32:37 +00001790 for (ObjCObjectType::qual_iterator P = T->qual_begin(),
Douglas Gregor96e578d2010-02-05 17:54:41 +00001791 PEnd = T->qual_end();
1792 P != PEnd; ++P) {
1793 ObjCProtocolDecl *Protocol
1794 = dyn_cast_or_null<ObjCProtocolDecl>(Importer.Import(*P));
1795 if (!Protocol)
1796 return QualType();
1797 Protocols.push_back(Protocol);
1798 }
1799
John McCall8b07ec22010-05-15 11:32:37 +00001800 return Importer.getToContext().getObjCObjectType(ToBaseType,
1801 Protocols.data(),
1802 Protocols.size());
Douglas Gregor96e578d2010-02-05 17:54:41 +00001803}
1804
John McCall424cec92011-01-19 06:33:43 +00001805QualType
1806ASTNodeImporter::VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
Douglas Gregor96e578d2010-02-05 17:54:41 +00001807 QualType ToPointeeType = Importer.Import(T->getPointeeType());
1808 if (ToPointeeType.isNull())
1809 return QualType();
1810
John McCall8b07ec22010-05-15 11:32:37 +00001811 return Importer.getToContext().getObjCObjectPointerType(ToPointeeType);
Douglas Gregor96e578d2010-02-05 17:54:41 +00001812}
1813
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001814//----------------------------------------------------------------------------
1815// Import Declarations
1816//----------------------------------------------------------------------------
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001817bool ASTNodeImporter::ImportDeclParts(NamedDecl *D, DeclContext *&DC,
1818 DeclContext *&LexicalDC,
1819 DeclarationName &Name,
1820 SourceLocation &Loc) {
1821 // Import the context of this declaration.
1822 DC = Importer.ImportContext(D->getDeclContext());
1823 if (!DC)
1824 return true;
1825
1826 LexicalDC = DC;
1827 if (D->getDeclContext() != D->getLexicalDeclContext()) {
1828 LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
1829 if (!LexicalDC)
1830 return true;
1831 }
1832
1833 // Import the name of this declaration.
1834 Name = Importer.Import(D->getDeclName());
1835 if (D->getDeclName() && !Name)
1836 return true;
1837
1838 // Import the location of this declaration.
1839 Loc = Importer.Import(D->getLocation());
1840 return false;
1841}
1842
Douglas Gregord451ea92011-07-29 23:31:30 +00001843void ASTNodeImporter::ImportDefinitionIfNeeded(Decl *FromD, Decl *ToD) {
1844 if (!FromD)
1845 return;
1846
1847 if (!ToD) {
1848 ToD = Importer.Import(FromD);
1849 if (!ToD)
1850 return;
1851 }
1852
1853 if (RecordDecl *FromRecord = dyn_cast<RecordDecl>(FromD)) {
1854 if (RecordDecl *ToRecord = cast_or_null<RecordDecl>(ToD)) {
Sean Callanan19dfc932013-01-11 23:17:47 +00001855 if (FromRecord->getDefinition() && FromRecord->isCompleteDefinition() && !ToRecord->getDefinition()) {
Douglas Gregord451ea92011-07-29 23:31:30 +00001856 ImportDefinition(FromRecord, ToRecord);
1857 }
1858 }
1859 return;
1860 }
1861
1862 if (EnumDecl *FromEnum = dyn_cast<EnumDecl>(FromD)) {
1863 if (EnumDecl *ToEnum = cast_or_null<EnumDecl>(ToD)) {
1864 if (FromEnum->getDefinition() && !ToEnum->getDefinition()) {
1865 ImportDefinition(FromEnum, ToEnum);
1866 }
1867 }
1868 return;
1869 }
1870}
1871
Abramo Bagnarad6d2f182010-08-11 22:01:17 +00001872void
1873ASTNodeImporter::ImportDeclarationNameLoc(const DeclarationNameInfo &From,
1874 DeclarationNameInfo& To) {
1875 // NOTE: To.Name and To.Loc are already imported.
1876 // We only have to import To.LocInfo.
1877 switch (To.getName().getNameKind()) {
1878 case DeclarationName::Identifier:
1879 case DeclarationName::ObjCZeroArgSelector:
1880 case DeclarationName::ObjCOneArgSelector:
1881 case DeclarationName::ObjCMultiArgSelector:
1882 case DeclarationName::CXXUsingDirective:
1883 return;
1884
1885 case DeclarationName::CXXOperatorName: {
1886 SourceRange Range = From.getCXXOperatorNameRange();
1887 To.setCXXOperatorNameRange(Importer.Import(Range));
1888 return;
1889 }
1890 case DeclarationName::CXXLiteralOperatorName: {
1891 SourceLocation Loc = From.getCXXLiteralOperatorNameLoc();
1892 To.setCXXLiteralOperatorNameLoc(Importer.Import(Loc));
1893 return;
1894 }
1895 case DeclarationName::CXXConstructorName:
1896 case DeclarationName::CXXDestructorName:
1897 case DeclarationName::CXXConversionFunctionName: {
1898 TypeSourceInfo *FromTInfo = From.getNamedTypeInfo();
1899 To.setNamedTypeInfo(Importer.Import(FromTInfo));
1900 return;
1901 }
Abramo Bagnarad6d2f182010-08-11 22:01:17 +00001902 }
Douglas Gregor07216d12011-11-02 20:52:01 +00001903 llvm_unreachable("Unknown name kind.");
Abramo Bagnarad6d2f182010-08-11 22:01:17 +00001904}
1905
Douglas Gregor2e15c842012-02-01 21:00:38 +00001906void ASTNodeImporter::ImportDeclContext(DeclContext *FromDC, bool ForceImport) {
Douglas Gregor0a791672011-01-18 03:11:38 +00001907 if (Importer.isMinimalImport() && !ForceImport) {
Sean Callanan81d577c2011-07-22 23:46:03 +00001908 Importer.ImportContext(FromDC);
Douglas Gregor0a791672011-01-18 03:11:38 +00001909 return;
1910 }
1911
Douglas Gregor968d6332010-02-21 18:24:45 +00001912 for (DeclContext::decl_iterator From = FromDC->decls_begin(),
1913 FromEnd = FromDC->decls_end();
1914 From != FromEnd;
1915 ++From)
1916 Importer.Import(*From);
1917}
1918
Douglas Gregord451ea92011-07-29 23:31:30 +00001919bool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To,
Douglas Gregor95d82832012-01-24 18:36:04 +00001920 ImportDefinitionKind Kind) {
1921 if (To->getDefinition() || To->isBeingDefined()) {
1922 if (Kind == IDK_Everything)
1923 ImportDeclContext(From, /*ForceImport=*/true);
1924
Douglas Gregore2e50d332010-12-01 01:36:18 +00001925 return false;
Douglas Gregor95d82832012-01-24 18:36:04 +00001926 }
Douglas Gregore2e50d332010-12-01 01:36:18 +00001927
1928 To->startDefinition();
1929
1930 // Add base classes.
1931 if (CXXRecordDecl *ToCXX = dyn_cast<CXXRecordDecl>(To)) {
1932 CXXRecordDecl *FromCXX = cast<CXXRecordDecl>(From);
Douglas Gregor3c2404b2011-11-03 18:07:07 +00001933
1934 struct CXXRecordDecl::DefinitionData &ToData = ToCXX->data();
1935 struct CXXRecordDecl::DefinitionData &FromData = FromCXX->data();
1936 ToData.UserDeclaredConstructor = FromData.UserDeclaredConstructor;
Richard Smith328aae52012-11-30 05:11:39 +00001937 ToData.UserDeclaredSpecialMembers = FromData.UserDeclaredSpecialMembers;
Douglas Gregor3c2404b2011-11-03 18:07:07 +00001938 ToData.Aggregate = FromData.Aggregate;
1939 ToData.PlainOldData = FromData.PlainOldData;
1940 ToData.Empty = FromData.Empty;
1941 ToData.Polymorphic = FromData.Polymorphic;
1942 ToData.Abstract = FromData.Abstract;
1943 ToData.IsStandardLayout = FromData.IsStandardLayout;
1944 ToData.HasNoNonEmptyBases = FromData.HasNoNonEmptyBases;
1945 ToData.HasPrivateFields = FromData.HasPrivateFields;
1946 ToData.HasProtectedFields = FromData.HasProtectedFields;
1947 ToData.HasPublicFields = FromData.HasPublicFields;
1948 ToData.HasMutableFields = FromData.HasMutableFields;
Richard Smith561fb152012-02-25 07:33:38 +00001949 ToData.HasOnlyCMembers = FromData.HasOnlyCMembers;
Richard Smithe2648ba2012-05-07 01:07:30 +00001950 ToData.HasInClassInitializer = FromData.HasInClassInitializer;
Richard Smith593f9932012-12-08 02:01:17 +00001951 ToData.HasUninitializedReferenceMember
1952 = FromData.HasUninitializedReferenceMember;
Richard Smith6b02d462012-12-08 08:32:28 +00001953 ToData.NeedOverloadResolutionForMoveConstructor
1954 = FromData.NeedOverloadResolutionForMoveConstructor;
1955 ToData.NeedOverloadResolutionForMoveAssignment
1956 = FromData.NeedOverloadResolutionForMoveAssignment;
1957 ToData.NeedOverloadResolutionForDestructor
1958 = FromData.NeedOverloadResolutionForDestructor;
1959 ToData.DefaultedMoveConstructorIsDeleted
1960 = FromData.DefaultedMoveConstructorIsDeleted;
1961 ToData.DefaultedMoveAssignmentIsDeleted
1962 = FromData.DefaultedMoveAssignmentIsDeleted;
1963 ToData.DefaultedDestructorIsDeleted = FromData.DefaultedDestructorIsDeleted;
Richard Smith328aae52012-11-30 05:11:39 +00001964 ToData.HasTrivialSpecialMembers = FromData.HasTrivialSpecialMembers;
1965 ToData.HasIrrelevantDestructor = FromData.HasIrrelevantDestructor;
Douglas Gregor3c2404b2011-11-03 18:07:07 +00001966 ToData.HasConstexprNonCopyMoveConstructor
1967 = FromData.HasConstexprNonCopyMoveConstructor;
Richard Smith561fb152012-02-25 07:33:38 +00001968 ToData.DefaultedDefaultConstructorIsConstexpr
1969 = FromData.DefaultedDefaultConstructorIsConstexpr;
Richard Smith561fb152012-02-25 07:33:38 +00001970 ToData.HasConstexprDefaultConstructor
1971 = FromData.HasConstexprDefaultConstructor;
Douglas Gregor3c2404b2011-11-03 18:07:07 +00001972 ToData.HasNonLiteralTypeFieldsOrBases
1973 = FromData.HasNonLiteralTypeFieldsOrBases;
Richard Smith561fb152012-02-25 07:33:38 +00001974 // ComputedVisibleConversions not imported.
Douglas Gregor3c2404b2011-11-03 18:07:07 +00001975 ToData.UserProvidedDefaultConstructor
1976 = FromData.UserProvidedDefaultConstructor;
Richard Smith328aae52012-11-30 05:11:39 +00001977 ToData.DeclaredSpecialMembers = FromData.DeclaredSpecialMembers;
Richard Smith1c33fe82012-11-28 06:23:12 +00001978 ToData.ImplicitCopyConstructorHasConstParam
1979 = FromData.ImplicitCopyConstructorHasConstParam;
1980 ToData.ImplicitCopyAssignmentHasConstParam
1981 = FromData.ImplicitCopyAssignmentHasConstParam;
1982 ToData.HasDeclaredCopyConstructorWithConstParam
1983 = FromData.HasDeclaredCopyConstructorWithConstParam;
1984 ToData.HasDeclaredCopyAssignmentWithConstParam
1985 = FromData.HasDeclaredCopyAssignmentWithConstParam;
Douglas Gregor3c2404b2011-11-03 18:07:07 +00001986 ToData.FailedImplicitMoveConstructor
1987 = FromData.FailedImplicitMoveConstructor;
1988 ToData.FailedImplicitMoveAssignment = FromData.FailedImplicitMoveAssignment;
Richard Smith561fb152012-02-25 07:33:38 +00001989 ToData.IsLambda = FromData.IsLambda;
1990
Chris Lattner0e62c1c2011-07-23 10:55:15 +00001991 SmallVector<CXXBaseSpecifier *, 4> Bases;
Douglas Gregore2e50d332010-12-01 01:36:18 +00001992 for (CXXRecordDecl::base_class_iterator
1993 Base1 = FromCXX->bases_begin(),
1994 FromBaseEnd = FromCXX->bases_end();
1995 Base1 != FromBaseEnd;
1996 ++Base1) {
1997 QualType T = Importer.Import(Base1->getType());
1998 if (T.isNull())
Douglas Gregor96303ea2010-12-02 19:33:37 +00001999 return true;
Douglas Gregor752a5952011-01-03 22:36:02 +00002000
2001 SourceLocation EllipsisLoc;
2002 if (Base1->isPackExpansion())
2003 EllipsisLoc = Importer.Import(Base1->getEllipsisLoc());
Douglas Gregord451ea92011-07-29 23:31:30 +00002004
2005 // Ensure that we have a definition for the base.
2006 ImportDefinitionIfNeeded(Base1->getType()->getAsCXXRecordDecl());
2007
Douglas Gregore2e50d332010-12-01 01:36:18 +00002008 Bases.push_back(
2009 new (Importer.getToContext())
2010 CXXBaseSpecifier(Importer.Import(Base1->getSourceRange()),
2011 Base1->isVirtual(),
2012 Base1->isBaseOfClass(),
2013 Base1->getAccessSpecifierAsWritten(),
Douglas Gregor752a5952011-01-03 22:36:02 +00002014 Importer.Import(Base1->getTypeSourceInfo()),
2015 EllipsisLoc));
Douglas Gregore2e50d332010-12-01 01:36:18 +00002016 }
2017 if (!Bases.empty())
2018 ToCXX->setBases(Bases.data(), Bases.size());
2019 }
2020
Douglas Gregor2e15c842012-02-01 21:00:38 +00002021 if (shouldForceImportDeclContext(Kind))
Douglas Gregor95d82832012-01-24 18:36:04 +00002022 ImportDeclContext(From, /*ForceImport=*/true);
2023
Douglas Gregore2e50d332010-12-01 01:36:18 +00002024 To->completeDefinition();
Douglas Gregor96303ea2010-12-02 19:33:37 +00002025 return false;
Douglas Gregore2e50d332010-12-01 01:36:18 +00002026}
2027
Larisse Voufo39a1e502013-08-06 01:03:05 +00002028bool ASTNodeImporter::ImportDefinition(VarDecl *From, VarDecl *To,
2029 ImportDefinitionKind Kind) {
2030 if (To->getDefinition())
2031 return false;
2032
2033 // FIXME: Can we really import any initializer? Alternatively, we could force
2034 // ourselves to import every declaration of a variable and then only use
2035 // getInit() here.
2036 To->setInit(Importer.Import(const_cast<Expr *>(From->getAnyInitializer())));
2037
2038 // FIXME: Other bits to merge?
2039
2040 return false;
2041}
2042
Douglas Gregord451ea92011-07-29 23:31:30 +00002043bool ASTNodeImporter::ImportDefinition(EnumDecl *From, EnumDecl *To,
Douglas Gregor2e15c842012-02-01 21:00:38 +00002044 ImportDefinitionKind Kind) {
2045 if (To->getDefinition() || To->isBeingDefined()) {
2046 if (Kind == IDK_Everything)
2047 ImportDeclContext(From, /*ForceImport=*/true);
Douglas Gregord451ea92011-07-29 23:31:30 +00002048 return false;
Douglas Gregor2e15c842012-02-01 21:00:38 +00002049 }
Douglas Gregord451ea92011-07-29 23:31:30 +00002050
2051 To->startDefinition();
2052
2053 QualType T = Importer.Import(Importer.getFromContext().getTypeDeclType(From));
2054 if (T.isNull())
2055 return true;
2056
2057 QualType ToPromotionType = Importer.Import(From->getPromotionType());
2058 if (ToPromotionType.isNull())
2059 return true;
Douglas Gregor2e15c842012-02-01 21:00:38 +00002060
2061 if (shouldForceImportDeclContext(Kind))
2062 ImportDeclContext(From, /*ForceImport=*/true);
Douglas Gregord451ea92011-07-29 23:31:30 +00002063
2064 // FIXME: we might need to merge the number of positive or negative bits
2065 // if the enumerator lists don't match.
2066 To->completeDefinition(T, ToPromotionType,
2067 From->getNumPositiveBits(),
2068 From->getNumNegativeBits());
2069 return false;
2070}
2071
Douglas Gregora082a492010-11-30 19:14:50 +00002072TemplateParameterList *ASTNodeImporter::ImportTemplateParameterList(
2073 TemplateParameterList *Params) {
Chris Lattner0e62c1c2011-07-23 10:55:15 +00002074 SmallVector<NamedDecl *, 4> ToParams;
Douglas Gregora082a492010-11-30 19:14:50 +00002075 ToParams.reserve(Params->size());
2076 for (TemplateParameterList::iterator P = Params->begin(),
2077 PEnd = Params->end();
2078 P != PEnd; ++P) {
2079 Decl *To = Importer.Import(*P);
2080 if (!To)
2081 return 0;
2082
2083 ToParams.push_back(cast<NamedDecl>(To));
2084 }
2085
2086 return TemplateParameterList::Create(Importer.getToContext(),
2087 Importer.Import(Params->getTemplateLoc()),
2088 Importer.Import(Params->getLAngleLoc()),
2089 ToParams.data(), ToParams.size(),
2090 Importer.Import(Params->getRAngleLoc()));
2091}
2092
Douglas Gregore2e50d332010-12-01 01:36:18 +00002093TemplateArgument
2094ASTNodeImporter::ImportTemplateArgument(const TemplateArgument &From) {
2095 switch (From.getKind()) {
2096 case TemplateArgument::Null:
2097 return TemplateArgument();
2098
2099 case TemplateArgument::Type: {
2100 QualType ToType = Importer.Import(From.getAsType());
2101 if (ToType.isNull())
2102 return TemplateArgument();
2103 return TemplateArgument(ToType);
2104 }
2105
2106 case TemplateArgument::Integral: {
2107 QualType ToType = Importer.Import(From.getIntegralType());
2108 if (ToType.isNull())
2109 return TemplateArgument();
Benjamin Kramer6003ad52012-06-07 15:09:51 +00002110 return TemplateArgument(From, ToType);
Douglas Gregore2e50d332010-12-01 01:36:18 +00002111 }
2112
Eli Friedmanb826a002012-09-26 02:36:12 +00002113 case TemplateArgument::Declaration: {
2114 ValueDecl *FromD = From.getAsDecl();
2115 if (ValueDecl *To = cast_or_null<ValueDecl>(Importer.Import(FromD)))
2116 return TemplateArgument(To, From.isDeclForReferenceParam());
Douglas Gregore2e50d332010-12-01 01:36:18 +00002117 return TemplateArgument();
Eli Friedmanb826a002012-09-26 02:36:12 +00002118 }
2119
2120 case TemplateArgument::NullPtr: {
2121 QualType ToType = Importer.Import(From.getNullPtrType());
2122 if (ToType.isNull())
2123 return TemplateArgument();
2124 return TemplateArgument(ToType, /*isNullPtr*/true);
2125 }
2126
Douglas Gregore2e50d332010-12-01 01:36:18 +00002127 case TemplateArgument::Template: {
2128 TemplateName ToTemplate = Importer.Import(From.getAsTemplate());
2129 if (ToTemplate.isNull())
2130 return TemplateArgument();
2131
2132 return TemplateArgument(ToTemplate);
2133 }
Douglas Gregore4ff4b52011-01-05 18:58:31 +00002134
2135 case TemplateArgument::TemplateExpansion: {
2136 TemplateName ToTemplate
2137 = Importer.Import(From.getAsTemplateOrTemplatePattern());
2138 if (ToTemplate.isNull())
2139 return TemplateArgument();
2140
Douglas Gregore1d60df2011-01-14 23:41:42 +00002141 return TemplateArgument(ToTemplate, From.getNumTemplateExpansions());
Douglas Gregore4ff4b52011-01-05 18:58:31 +00002142 }
2143
Douglas Gregore2e50d332010-12-01 01:36:18 +00002144 case TemplateArgument::Expression:
2145 if (Expr *ToExpr = Importer.Import(From.getAsExpr()))
2146 return TemplateArgument(ToExpr);
2147 return TemplateArgument();
2148
2149 case TemplateArgument::Pack: {
Chris Lattner0e62c1c2011-07-23 10:55:15 +00002150 SmallVector<TemplateArgument, 2> ToPack;
Douglas Gregore2e50d332010-12-01 01:36:18 +00002151 ToPack.reserve(From.pack_size());
2152 if (ImportTemplateArguments(From.pack_begin(), From.pack_size(), ToPack))
2153 return TemplateArgument();
2154
2155 TemplateArgument *ToArgs
2156 = new (Importer.getToContext()) TemplateArgument[ToPack.size()];
2157 std::copy(ToPack.begin(), ToPack.end(), ToArgs);
2158 return TemplateArgument(ToArgs, ToPack.size());
2159 }
2160 }
2161
2162 llvm_unreachable("Invalid template argument kind");
Douglas Gregore2e50d332010-12-01 01:36:18 +00002163}
2164
2165bool ASTNodeImporter::ImportTemplateArguments(const TemplateArgument *FromArgs,
2166 unsigned NumFromArgs,
Chris Lattner0e62c1c2011-07-23 10:55:15 +00002167 SmallVectorImpl<TemplateArgument> &ToArgs) {
Douglas Gregore2e50d332010-12-01 01:36:18 +00002168 for (unsigned I = 0; I != NumFromArgs; ++I) {
2169 TemplateArgument To = ImportTemplateArgument(FromArgs[I]);
2170 if (To.isNull() && !FromArgs[I].isNull())
2171 return true;
2172
2173 ToArgs.push_back(To);
2174 }
2175
2176 return false;
2177}
2178
Douglas Gregor5c73e912010-02-11 00:48:18 +00002179bool ASTNodeImporter::IsStructuralMatch(RecordDecl *FromRecord,
Douglas Gregordd6006f2012-07-17 21:16:27 +00002180 RecordDecl *ToRecord, bool Complain) {
Benjamin Kramer26d19c52010-02-18 13:02:13 +00002181 StructuralEquivalenceContext Ctx(Importer.getFromContext(),
Douglas Gregor3996e242010-02-15 22:01:00 +00002182 Importer.getToContext(),
Douglas Gregordd6006f2012-07-17 21:16:27 +00002183 Importer.getNonEquivalentDecls(),
2184 false, Complain);
Benjamin Kramer26d19c52010-02-18 13:02:13 +00002185 return Ctx.IsStructurallyEquivalent(FromRecord, ToRecord);
Douglas Gregor5c73e912010-02-11 00:48:18 +00002186}
2187
Larisse Voufo39a1e502013-08-06 01:03:05 +00002188bool ASTNodeImporter::IsStructuralMatch(VarDecl *FromVar, VarDecl *ToVar,
2189 bool Complain) {
2190 StructuralEquivalenceContext Ctx(
2191 Importer.getFromContext(), Importer.getToContext(),
2192 Importer.getNonEquivalentDecls(), false, Complain);
2193 return Ctx.IsStructurallyEquivalent(FromVar, ToVar);
2194}
2195
Douglas Gregor98c10182010-02-12 22:17:39 +00002196bool ASTNodeImporter::IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToEnum) {
Benjamin Kramer26d19c52010-02-18 13:02:13 +00002197 StructuralEquivalenceContext Ctx(Importer.getFromContext(),
Douglas Gregor3996e242010-02-15 22:01:00 +00002198 Importer.getToContext(),
Douglas Gregorb4964f72010-02-15 23:54:17 +00002199 Importer.getNonEquivalentDecls());
Benjamin Kramer26d19c52010-02-18 13:02:13 +00002200 return Ctx.IsStructurallyEquivalent(FromEnum, ToEnum);
Douglas Gregor98c10182010-02-12 22:17:39 +00002201}
2202
Douglas Gregor91155082012-11-14 22:29:20 +00002203bool ASTNodeImporter::IsStructuralMatch(EnumConstantDecl *FromEC,
2204 EnumConstantDecl *ToEC)
2205{
2206 const llvm::APSInt &FromVal = FromEC->getInitVal();
2207 const llvm::APSInt &ToVal = ToEC->getInitVal();
2208
2209 return FromVal.isSigned() == ToVal.isSigned() &&
2210 FromVal.getBitWidth() == ToVal.getBitWidth() &&
2211 FromVal == ToVal;
2212}
2213
2214bool ASTNodeImporter::IsStructuralMatch(ClassTemplateDecl *From,
Douglas Gregora082a492010-11-30 19:14:50 +00002215 ClassTemplateDecl *To) {
2216 StructuralEquivalenceContext Ctx(Importer.getFromContext(),
2217 Importer.getToContext(),
2218 Importer.getNonEquivalentDecls());
2219 return Ctx.IsStructurallyEquivalent(From, To);
2220}
2221
Larisse Voufo39a1e502013-08-06 01:03:05 +00002222bool ASTNodeImporter::IsStructuralMatch(VarTemplateDecl *From,
2223 VarTemplateDecl *To) {
2224 StructuralEquivalenceContext Ctx(Importer.getFromContext(),
2225 Importer.getToContext(),
2226 Importer.getNonEquivalentDecls());
2227 return Ctx.IsStructurallyEquivalent(From, To);
2228}
2229
Douglas Gregore4c83e42010-02-09 22:48:33 +00002230Decl *ASTNodeImporter::VisitDecl(Decl *D) {
Douglas Gregor811663e2010-02-10 00:15:17 +00002231 Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node)
Douglas Gregore4c83e42010-02-09 22:48:33 +00002232 << D->getDeclKindName();
2233 return 0;
2234}
2235
Sean Callanan65198272011-11-17 23:20:56 +00002236Decl *ASTNodeImporter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
2237 TranslationUnitDecl *ToD =
2238 Importer.getToContext().getTranslationUnitDecl();
2239
2240 Importer.Imported(D, ToD);
2241
2242 return ToD;
2243}
2244
Douglas Gregorf18a2c72010-02-21 18:26:36 +00002245Decl *ASTNodeImporter::VisitNamespaceDecl(NamespaceDecl *D) {
2246 // Import the major distinguishing characteristics of this namespace.
2247 DeclContext *DC, *LexicalDC;
2248 DeclarationName Name;
2249 SourceLocation Loc;
2250 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2251 return 0;
2252
2253 NamespaceDecl *MergeWithNamespace = 0;
2254 if (!Name) {
2255 // This is an anonymous namespace. Adopt an existing anonymous
2256 // namespace if we can.
2257 // FIXME: Not testable.
2258 if (TranslationUnitDecl *TU = dyn_cast<TranslationUnitDecl>(DC))
2259 MergeWithNamespace = TU->getAnonymousNamespace();
2260 else
2261 MergeWithNamespace = cast<NamespaceDecl>(DC)->getAnonymousNamespace();
2262 } else {
Chris Lattner0e62c1c2011-07-23 10:55:15 +00002263 SmallVector<NamedDecl *, 4> ConflictingDecls;
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002264 SmallVector<NamedDecl *, 2> FoundDecls;
Douglas Gregor9e0a5b32011-10-15 00:10:27 +00002265 DC->localUncachedLookup(Name, FoundDecls);
2266 for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
2267 if (!FoundDecls[I]->isInIdentifierNamespace(Decl::IDNS_Namespace))
Douglas Gregorf18a2c72010-02-21 18:26:36 +00002268 continue;
2269
Douglas Gregor9e0a5b32011-10-15 00:10:27 +00002270 if (NamespaceDecl *FoundNS = dyn_cast<NamespaceDecl>(FoundDecls[I])) {
Douglas Gregorf18a2c72010-02-21 18:26:36 +00002271 MergeWithNamespace = FoundNS;
2272 ConflictingDecls.clear();
2273 break;
2274 }
2275
Douglas Gregor9e0a5b32011-10-15 00:10:27 +00002276 ConflictingDecls.push_back(FoundDecls[I]);
Douglas Gregorf18a2c72010-02-21 18:26:36 +00002277 }
2278
2279 if (!ConflictingDecls.empty()) {
John McCalle87beb22010-04-23 18:46:30 +00002280 Name = Importer.HandleNameConflict(Name, DC, Decl::IDNS_Namespace,
Douglas Gregorf18a2c72010-02-21 18:26:36 +00002281 ConflictingDecls.data(),
2282 ConflictingDecls.size());
2283 }
2284 }
2285
2286 // Create the "to" namespace, if needed.
2287 NamespaceDecl *ToNamespace = MergeWithNamespace;
2288 if (!ToNamespace) {
Abramo Bagnarab5545be2011-03-08 12:38:20 +00002289 ToNamespace = NamespaceDecl::Create(Importer.getToContext(), DC,
Douglas Gregore57e7522012-01-07 09:11:48 +00002290 D->isInline(),
Abramo Bagnarab5545be2011-03-08 12:38:20 +00002291 Importer.Import(D->getLocStart()),
Douglas Gregore57e7522012-01-07 09:11:48 +00002292 Loc, Name.getAsIdentifierInfo(),
2293 /*PrevDecl=*/0);
Douglas Gregorf18a2c72010-02-21 18:26:36 +00002294 ToNamespace->setLexicalDeclContext(LexicalDC);
Sean Callanan95e74be2011-10-21 02:57:43 +00002295 LexicalDC->addDeclInternal(ToNamespace);
Douglas Gregorf18a2c72010-02-21 18:26:36 +00002296
2297 // If this is an anonymous namespace, register it as the anonymous
2298 // namespace within its context.
2299 if (!Name) {
2300 if (TranslationUnitDecl *TU = dyn_cast<TranslationUnitDecl>(DC))
2301 TU->setAnonymousNamespace(ToNamespace);
2302 else
2303 cast<NamespaceDecl>(DC)->setAnonymousNamespace(ToNamespace);
2304 }
2305 }
2306 Importer.Imported(D, ToNamespace);
2307
2308 ImportDeclContext(D);
2309
2310 return ToNamespace;
2311}
2312
Richard Smithdda56e42011-04-15 14:24:37 +00002313Decl *ASTNodeImporter::VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias) {
Douglas Gregor5fa74c32010-02-10 21:10:29 +00002314 // Import the major distinguishing characteristics of this typedef.
2315 DeclContext *DC, *LexicalDC;
2316 DeclarationName Name;
2317 SourceLocation Loc;
2318 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2319 return 0;
2320
Douglas Gregor5fa74c32010-02-10 21:10:29 +00002321 // If this typedef is not in block scope, determine whether we've
2322 // seen a typedef with the same name (that we can merge with) or any
2323 // other entity by that name (which name lookup could conflict with).
2324 if (!DC->isFunctionOrMethod()) {
Chris Lattner0e62c1c2011-07-23 10:55:15 +00002325 SmallVector<NamedDecl *, 4> ConflictingDecls;
Douglas Gregor5fa74c32010-02-10 21:10:29 +00002326 unsigned IDNS = Decl::IDNS_Ordinary;
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002327 SmallVector<NamedDecl *, 2> FoundDecls;
Douglas Gregor9e0a5b32011-10-15 00:10:27 +00002328 DC->localUncachedLookup(Name, FoundDecls);
2329 for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
2330 if (!FoundDecls[I]->isInIdentifierNamespace(IDNS))
Douglas Gregor5fa74c32010-02-10 21:10:29 +00002331 continue;
Richard Smithdda56e42011-04-15 14:24:37 +00002332 if (TypedefNameDecl *FoundTypedef =
Douglas Gregor9e0a5b32011-10-15 00:10:27 +00002333 dyn_cast<TypedefNameDecl>(FoundDecls[I])) {
Douglas Gregorb4964f72010-02-15 23:54:17 +00002334 if (Importer.IsStructurallyEquivalent(D->getUnderlyingType(),
2335 FoundTypedef->getUnderlyingType()))
Douglas Gregor8cdbe642010-02-12 23:44:20 +00002336 return Importer.Imported(D, FoundTypedef);
Douglas Gregor5fa74c32010-02-10 21:10:29 +00002337 }
2338
Douglas Gregor9e0a5b32011-10-15 00:10:27 +00002339 ConflictingDecls.push_back(FoundDecls[I]);
Douglas Gregor5fa74c32010-02-10 21:10:29 +00002340 }
2341
2342 if (!ConflictingDecls.empty()) {
2343 Name = Importer.HandleNameConflict(Name, DC, IDNS,
2344 ConflictingDecls.data(),
2345 ConflictingDecls.size());
2346 if (!Name)
2347 return 0;
2348 }
2349 }
2350
Douglas Gregorb4964f72010-02-15 23:54:17 +00002351 // Import the underlying type of this typedef;
2352 QualType T = Importer.Import(D->getUnderlyingType());
2353 if (T.isNull())
2354 return 0;
2355
Douglas Gregor5fa74c32010-02-10 21:10:29 +00002356 // Create the new typedef node.
2357 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
Abramo Bagnarab3185b02011-03-06 15:48:19 +00002358 SourceLocation StartL = Importer.Import(D->getLocStart());
Richard Smithdda56e42011-04-15 14:24:37 +00002359 TypedefNameDecl *ToTypedef;
2360 if (IsAlias)
Douglas Gregor03d1ed32011-10-14 21:54:42 +00002361 ToTypedef = TypeAliasDecl::Create(Importer.getToContext(), DC,
2362 StartL, Loc,
2363 Name.getAsIdentifierInfo(),
2364 TInfo);
2365 else
Richard Smithdda56e42011-04-15 14:24:37 +00002366 ToTypedef = TypedefDecl::Create(Importer.getToContext(), DC,
2367 StartL, Loc,
2368 Name.getAsIdentifierInfo(),
2369 TInfo);
Douglas Gregor03d1ed32011-10-14 21:54:42 +00002370
Douglas Gregordd483172010-02-22 17:42:47 +00002371 ToTypedef->setAccess(D->getAccess());
Douglas Gregor5fa74c32010-02-10 21:10:29 +00002372 ToTypedef->setLexicalDeclContext(LexicalDC);
Douglas Gregor8cdbe642010-02-12 23:44:20 +00002373 Importer.Imported(D, ToTypedef);
Sean Callanan95e74be2011-10-21 02:57:43 +00002374 LexicalDC->addDeclInternal(ToTypedef);
Douglas Gregorb4964f72010-02-15 23:54:17 +00002375
Douglas Gregor5fa74c32010-02-10 21:10:29 +00002376 return ToTypedef;
2377}
2378
Richard Smithdda56e42011-04-15 14:24:37 +00002379Decl *ASTNodeImporter::VisitTypedefDecl(TypedefDecl *D) {
2380 return VisitTypedefNameDecl(D, /*IsAlias=*/false);
2381}
2382
2383Decl *ASTNodeImporter::VisitTypeAliasDecl(TypeAliasDecl *D) {
2384 return VisitTypedefNameDecl(D, /*IsAlias=*/true);
2385}
2386
Douglas Gregor98c10182010-02-12 22:17:39 +00002387Decl *ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
2388 // Import the major distinguishing characteristics of this enum.
2389 DeclContext *DC, *LexicalDC;
2390 DeclarationName Name;
2391 SourceLocation Loc;
2392 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2393 return 0;
2394
2395 // Figure out what enum name we're looking for.
2396 unsigned IDNS = Decl::IDNS_Tag;
2397 DeclarationName SearchName = Name;
Richard Smithdda56e42011-04-15 14:24:37 +00002398 if (!SearchName && D->getTypedefNameForAnonDecl()) {
2399 SearchName = Importer.Import(D->getTypedefNameForAnonDecl()->getDeclName());
Douglas Gregor98c10182010-02-12 22:17:39 +00002400 IDNS = Decl::IDNS_Ordinary;
David Blaikiebbafb8a2012-03-11 07:00:24 +00002401 } else if (Importer.getToContext().getLangOpts().CPlusPlus)
Douglas Gregor98c10182010-02-12 22:17:39 +00002402 IDNS |= Decl::IDNS_Ordinary;
2403
2404 // We may already have an enum of the same name; try to find and match it.
2405 if (!DC->isFunctionOrMethod() && SearchName) {
Chris Lattner0e62c1c2011-07-23 10:55:15 +00002406 SmallVector<NamedDecl *, 4> ConflictingDecls;
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002407 SmallVector<NamedDecl *, 2> FoundDecls;
Douglas Gregor9e0a5b32011-10-15 00:10:27 +00002408 DC->localUncachedLookup(SearchName, FoundDecls);
2409 for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
2410 if (!FoundDecls[I]->isInIdentifierNamespace(IDNS))
Douglas Gregor98c10182010-02-12 22:17:39 +00002411 continue;
2412
Douglas Gregor9e0a5b32011-10-15 00:10:27 +00002413 Decl *Found = FoundDecls[I];
Richard Smithdda56e42011-04-15 14:24:37 +00002414 if (TypedefNameDecl *Typedef = dyn_cast<TypedefNameDecl>(Found)) {
Douglas Gregor98c10182010-02-12 22:17:39 +00002415 if (const TagType *Tag = Typedef->getUnderlyingType()->getAs<TagType>())
2416 Found = Tag->getDecl();
2417 }
2418
2419 if (EnumDecl *FoundEnum = dyn_cast<EnumDecl>(Found)) {
Douglas Gregor8cdbe642010-02-12 23:44:20 +00002420 if (IsStructuralMatch(D, FoundEnum))
2421 return Importer.Imported(D, FoundEnum);
Douglas Gregor98c10182010-02-12 22:17:39 +00002422 }
2423
Douglas Gregor9e0a5b32011-10-15 00:10:27 +00002424 ConflictingDecls.push_back(FoundDecls[I]);
Douglas Gregor98c10182010-02-12 22:17:39 +00002425 }
2426
2427 if (!ConflictingDecls.empty()) {
2428 Name = Importer.HandleNameConflict(Name, DC, IDNS,
2429 ConflictingDecls.data(),
2430 ConflictingDecls.size());
2431 }
2432 }
2433
2434 // Create the enum declaration.
Abramo Bagnara29c2d462011-03-09 14:09:51 +00002435 EnumDecl *D2 = EnumDecl::Create(Importer.getToContext(), DC,
2436 Importer.Import(D->getLocStart()),
2437 Loc, Name.getAsIdentifierInfo(), 0,
Abramo Bagnara0e05e242010-12-03 18:54:17 +00002438 D->isScoped(), D->isScopedUsingClassTag(),
2439 D->isFixed());
John McCall3e11ebe2010-03-15 10:12:16 +00002440 // Import the qualifier, if any.
Douglas Gregor14454802011-02-25 02:25:35 +00002441 D2->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
Douglas Gregordd483172010-02-22 17:42:47 +00002442 D2->setAccess(D->getAccess());
Douglas Gregor3996e242010-02-15 22:01:00 +00002443 D2->setLexicalDeclContext(LexicalDC);
2444 Importer.Imported(D, D2);
Sean Callanan95e74be2011-10-21 02:57:43 +00002445 LexicalDC->addDeclInternal(D2);
Douglas Gregor98c10182010-02-12 22:17:39 +00002446
2447 // Import the integer type.
2448 QualType ToIntegerType = Importer.Import(D->getIntegerType());
2449 if (ToIntegerType.isNull())
2450 return 0;
Douglas Gregor3996e242010-02-15 22:01:00 +00002451 D2->setIntegerType(ToIntegerType);
Douglas Gregor98c10182010-02-12 22:17:39 +00002452
2453 // Import the definition
John McCallf937c022011-10-07 06:10:15 +00002454 if (D->isCompleteDefinition() && ImportDefinition(D, D2))
Douglas Gregord451ea92011-07-29 23:31:30 +00002455 return 0;
Douglas Gregor98c10182010-02-12 22:17:39 +00002456
Douglas Gregor3996e242010-02-15 22:01:00 +00002457 return D2;
Douglas Gregor98c10182010-02-12 22:17:39 +00002458}
2459
Douglas Gregor5c73e912010-02-11 00:48:18 +00002460Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
2461 // If this record has a definition in the translation unit we're coming from,
2462 // but this particular declaration is not that definition, import the
2463 // definition and map to that.
Douglas Gregor0a5a2212010-02-11 01:04:33 +00002464 TagDecl *Definition = D->getDefinition();
Douglas Gregor5c73e912010-02-11 00:48:18 +00002465 if (Definition && Definition != D) {
2466 Decl *ImportedDef = Importer.Import(Definition);
Douglas Gregor8cdbe642010-02-12 23:44:20 +00002467 if (!ImportedDef)
2468 return 0;
2469
2470 return Importer.Imported(D, ImportedDef);
Douglas Gregor5c73e912010-02-11 00:48:18 +00002471 }
2472
2473 // Import the major distinguishing characteristics of this record.
2474 DeclContext *DC, *LexicalDC;
2475 DeclarationName Name;
2476 SourceLocation Loc;
2477 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2478 return 0;
2479
2480 // Figure out what structure name we're looking for.
2481 unsigned IDNS = Decl::IDNS_Tag;
2482 DeclarationName SearchName = Name;
Richard Smithdda56e42011-04-15 14:24:37 +00002483 if (!SearchName && D->getTypedefNameForAnonDecl()) {
2484 SearchName = Importer.Import(D->getTypedefNameForAnonDecl()->getDeclName());
Douglas Gregor5c73e912010-02-11 00:48:18 +00002485 IDNS = Decl::IDNS_Ordinary;
David Blaikiebbafb8a2012-03-11 07:00:24 +00002486 } else if (Importer.getToContext().getLangOpts().CPlusPlus)
Douglas Gregor5c73e912010-02-11 00:48:18 +00002487 IDNS |= Decl::IDNS_Ordinary;
2488
2489 // We may already have a record of the same name; try to find and match it.
Douglas Gregor25791052010-02-12 00:09:27 +00002490 RecordDecl *AdoptDecl = 0;
Douglas Gregordd6006f2012-07-17 21:16:27 +00002491 if (!DC->isFunctionOrMethod()) {
Chris Lattner0e62c1c2011-07-23 10:55:15 +00002492 SmallVector<NamedDecl *, 4> ConflictingDecls;
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002493 SmallVector<NamedDecl *, 2> FoundDecls;
Douglas Gregor9e0a5b32011-10-15 00:10:27 +00002494 DC->localUncachedLookup(SearchName, FoundDecls);
2495 for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
2496 if (!FoundDecls[I]->isInIdentifierNamespace(IDNS))
Douglas Gregor5c73e912010-02-11 00:48:18 +00002497 continue;
2498
Douglas Gregor9e0a5b32011-10-15 00:10:27 +00002499 Decl *Found = FoundDecls[I];
Richard Smithdda56e42011-04-15 14:24:37 +00002500 if (TypedefNameDecl *Typedef = dyn_cast<TypedefNameDecl>(Found)) {
Douglas Gregor5c73e912010-02-11 00:48:18 +00002501 if (const TagType *Tag = Typedef->getUnderlyingType()->getAs<TagType>())
2502 Found = Tag->getDecl();
2503 }
2504
2505 if (RecordDecl *FoundRecord = dyn_cast<RecordDecl>(Found)) {
Douglas Gregorceb32bf2012-10-26 16:45:11 +00002506 if (D->isAnonymousStructOrUnion() &&
2507 FoundRecord->isAnonymousStructOrUnion()) {
2508 // If both anonymous structs/unions are in a record context, make sure
2509 // they occur in the same location in the context records.
David Blaikie05785d12013-02-20 22:23:23 +00002510 if (Optional<unsigned> Index1
Douglas Gregorceb32bf2012-10-26 16:45:11 +00002511 = findAnonymousStructOrUnionIndex(D)) {
David Blaikie05785d12013-02-20 22:23:23 +00002512 if (Optional<unsigned> Index2 =
2513 findAnonymousStructOrUnionIndex(FoundRecord)) {
Douglas Gregorceb32bf2012-10-26 16:45:11 +00002514 if (*Index1 != *Index2)
2515 continue;
2516 }
2517 }
2518 }
2519
Douglas Gregor25791052010-02-12 00:09:27 +00002520 if (RecordDecl *FoundDef = FoundRecord->getDefinition()) {
Douglas Gregordd6006f2012-07-17 21:16:27 +00002521 if ((SearchName && !D->isCompleteDefinition())
2522 || (D->isCompleteDefinition() &&
2523 D->isAnonymousStructOrUnion()
2524 == FoundDef->isAnonymousStructOrUnion() &&
2525 IsStructuralMatch(D, FoundDef))) {
Douglas Gregor25791052010-02-12 00:09:27 +00002526 // The record types structurally match, or the "from" translation
2527 // unit only had a forward declaration anyway; call it the same
2528 // function.
2529 // FIXME: For C++, we should also merge methods here.
Douglas Gregor8cdbe642010-02-12 23:44:20 +00002530 return Importer.Imported(D, FoundDef);
Douglas Gregor25791052010-02-12 00:09:27 +00002531 }
Douglas Gregordd6006f2012-07-17 21:16:27 +00002532 } else if (!D->isCompleteDefinition()) {
Douglas Gregor25791052010-02-12 00:09:27 +00002533 // We have a forward declaration of this type, so adopt that forward
2534 // declaration rather than building a new one.
2535 AdoptDecl = FoundRecord;
2536 continue;
Douglas Gregordd6006f2012-07-17 21:16:27 +00002537 } else if (!SearchName) {
2538 continue;
2539 }
Douglas Gregor5c73e912010-02-11 00:48:18 +00002540 }
2541
Douglas Gregor9e0a5b32011-10-15 00:10:27 +00002542 ConflictingDecls.push_back(FoundDecls[I]);
Douglas Gregor5c73e912010-02-11 00:48:18 +00002543 }
2544
Douglas Gregordd6006f2012-07-17 21:16:27 +00002545 if (!ConflictingDecls.empty() && SearchName) {
Douglas Gregor5c73e912010-02-11 00:48:18 +00002546 Name = Importer.HandleNameConflict(Name, DC, IDNS,
2547 ConflictingDecls.data(),
2548 ConflictingDecls.size());
2549 }
2550 }
2551
2552 // Create the record declaration.
Douglas Gregor3996e242010-02-15 22:01:00 +00002553 RecordDecl *D2 = AdoptDecl;
Abramo Bagnara29c2d462011-03-09 14:09:51 +00002554 SourceLocation StartLoc = Importer.Import(D->getLocStart());
Douglas Gregor3996e242010-02-15 22:01:00 +00002555 if (!D2) {
John McCall1c70e992010-06-03 19:28:45 +00002556 if (isa<CXXRecordDecl>(D)) {
Douglas Gregor3996e242010-02-15 22:01:00 +00002557 CXXRecordDecl *D2CXX = CXXRecordDecl::Create(Importer.getToContext(),
Douglas Gregor25791052010-02-12 00:09:27 +00002558 D->getTagKind(),
Abramo Bagnara29c2d462011-03-09 14:09:51 +00002559 DC, StartLoc, Loc,
2560 Name.getAsIdentifierInfo());
Douglas Gregor3996e242010-02-15 22:01:00 +00002561 D2 = D2CXX;
Douglas Gregordd483172010-02-22 17:42:47 +00002562 D2->setAccess(D->getAccess());
Douglas Gregor25791052010-02-12 00:09:27 +00002563 } else {
Douglas Gregor3996e242010-02-15 22:01:00 +00002564 D2 = RecordDecl::Create(Importer.getToContext(), D->getTagKind(),
Abramo Bagnara29c2d462011-03-09 14:09:51 +00002565 DC, StartLoc, Loc, Name.getAsIdentifierInfo());
Douglas Gregor5c73e912010-02-11 00:48:18 +00002566 }
Douglas Gregor14454802011-02-25 02:25:35 +00002567
2568 D2->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
Douglas Gregor3996e242010-02-15 22:01:00 +00002569 D2->setLexicalDeclContext(LexicalDC);
Sean Callanan95e74be2011-10-21 02:57:43 +00002570 LexicalDC->addDeclInternal(D2);
Douglas Gregordd6006f2012-07-17 21:16:27 +00002571 if (D->isAnonymousStructOrUnion())
2572 D2->setAnonymousStructOrUnion(true);
Douglas Gregor5c73e912010-02-11 00:48:18 +00002573 }
Douglas Gregor8cdbe642010-02-12 23:44:20 +00002574
Douglas Gregor3996e242010-02-15 22:01:00 +00002575 Importer.Imported(D, D2);
Douglas Gregor25791052010-02-12 00:09:27 +00002576
Douglas Gregor95d82832012-01-24 18:36:04 +00002577 if (D->isCompleteDefinition() && ImportDefinition(D, D2, IDK_Default))
Douglas Gregore2e50d332010-12-01 01:36:18 +00002578 return 0;
Douglas Gregor5c73e912010-02-11 00:48:18 +00002579
Douglas Gregor3996e242010-02-15 22:01:00 +00002580 return D2;
Douglas Gregor5c73e912010-02-11 00:48:18 +00002581}
2582
Douglas Gregor98c10182010-02-12 22:17:39 +00002583Decl *ASTNodeImporter::VisitEnumConstantDecl(EnumConstantDecl *D) {
2584 // Import the major distinguishing characteristics of this enumerator.
2585 DeclContext *DC, *LexicalDC;
2586 DeclarationName Name;
2587 SourceLocation Loc;
Douglas Gregorb4964f72010-02-15 23:54:17 +00002588 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
Douglas Gregor98c10182010-02-12 22:17:39 +00002589 return 0;
Douglas Gregorb4964f72010-02-15 23:54:17 +00002590
2591 QualType T = Importer.Import(D->getType());
2592 if (T.isNull())
2593 return 0;
2594
Douglas Gregor98c10182010-02-12 22:17:39 +00002595 // Determine whether there are any other declarations with the same name and
2596 // in the same context.
2597 if (!LexicalDC->isFunctionOrMethod()) {
Chris Lattner0e62c1c2011-07-23 10:55:15 +00002598 SmallVector<NamedDecl *, 4> ConflictingDecls;
Douglas Gregor98c10182010-02-12 22:17:39 +00002599 unsigned IDNS = Decl::IDNS_Ordinary;
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002600 SmallVector<NamedDecl *, 2> FoundDecls;
Douglas Gregor9e0a5b32011-10-15 00:10:27 +00002601 DC->localUncachedLookup(Name, FoundDecls);
2602 for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
2603 if (!FoundDecls[I]->isInIdentifierNamespace(IDNS))
Douglas Gregor98c10182010-02-12 22:17:39 +00002604 continue;
Douglas Gregor91155082012-11-14 22:29:20 +00002605
2606 if (EnumConstantDecl *FoundEnumConstant
2607 = dyn_cast<EnumConstantDecl>(FoundDecls[I])) {
2608 if (IsStructuralMatch(D, FoundEnumConstant))
2609 return Importer.Imported(D, FoundEnumConstant);
2610 }
2611
Douglas Gregor9e0a5b32011-10-15 00:10:27 +00002612 ConflictingDecls.push_back(FoundDecls[I]);
Douglas Gregor98c10182010-02-12 22:17:39 +00002613 }
2614
2615 if (!ConflictingDecls.empty()) {
2616 Name = Importer.HandleNameConflict(Name, DC, IDNS,
2617 ConflictingDecls.data(),
2618 ConflictingDecls.size());
2619 if (!Name)
2620 return 0;
2621 }
2622 }
2623
2624 Expr *Init = Importer.Import(D->getInitExpr());
2625 if (D->getInitExpr() && !Init)
2626 return 0;
2627
2628 EnumConstantDecl *ToEnumerator
2629 = EnumConstantDecl::Create(Importer.getToContext(), cast<EnumDecl>(DC), Loc,
2630 Name.getAsIdentifierInfo(), T,
2631 Init, D->getInitVal());
Douglas Gregordd483172010-02-22 17:42:47 +00002632 ToEnumerator->setAccess(D->getAccess());
Douglas Gregor98c10182010-02-12 22:17:39 +00002633 ToEnumerator->setLexicalDeclContext(LexicalDC);
Douglas Gregor8cdbe642010-02-12 23:44:20 +00002634 Importer.Imported(D, ToEnumerator);
Sean Callanan95e74be2011-10-21 02:57:43 +00002635 LexicalDC->addDeclInternal(ToEnumerator);
Douglas Gregor98c10182010-02-12 22:17:39 +00002636 return ToEnumerator;
2637}
Douglas Gregor5c73e912010-02-11 00:48:18 +00002638
Douglas Gregorbb7930c2010-02-10 19:54:31 +00002639Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
2640 // Import the major distinguishing characteristics of this function.
2641 DeclContext *DC, *LexicalDC;
2642 DeclarationName Name;
Douglas Gregorbb7930c2010-02-10 19:54:31 +00002643 SourceLocation Loc;
Douglas Gregorb4964f72010-02-15 23:54:17 +00002644 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00002645 return 0;
Abramo Bagnarad6d2f182010-08-11 22:01:17 +00002646
Douglas Gregorbb7930c2010-02-10 19:54:31 +00002647 // Try to find a function in our own ("to") context with the same name, same
2648 // type, and in the same context as the function we're importing.
2649 if (!LexicalDC->isFunctionOrMethod()) {
Chris Lattner0e62c1c2011-07-23 10:55:15 +00002650 SmallVector<NamedDecl *, 4> ConflictingDecls;
Douglas Gregorbb7930c2010-02-10 19:54:31 +00002651 unsigned IDNS = Decl::IDNS_Ordinary;
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002652 SmallVector<NamedDecl *, 2> FoundDecls;
Douglas Gregor9e0a5b32011-10-15 00:10:27 +00002653 DC->localUncachedLookup(Name, FoundDecls);
2654 for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
2655 if (!FoundDecls[I]->isInIdentifierNamespace(IDNS))
Douglas Gregorbb7930c2010-02-10 19:54:31 +00002656 continue;
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00002657
Douglas Gregor9e0a5b32011-10-15 00:10:27 +00002658 if (FunctionDecl *FoundFunction = dyn_cast<FunctionDecl>(FoundDecls[I])) {
Rafael Espindola3ae00052013-05-13 00:12:11 +00002659 if (FoundFunction->hasExternalFormalLinkage() &&
2660 D->hasExternalFormalLinkage()) {
Douglas Gregorb4964f72010-02-15 23:54:17 +00002661 if (Importer.IsStructurallyEquivalent(D->getType(),
2662 FoundFunction->getType())) {
Douglas Gregorbb7930c2010-02-10 19:54:31 +00002663 // FIXME: Actually try to merge the body and other attributes.
Douglas Gregor8cdbe642010-02-12 23:44:20 +00002664 return Importer.Imported(D, FoundFunction);
Douglas Gregorbb7930c2010-02-10 19:54:31 +00002665 }
2666
2667 // FIXME: Check for overloading more carefully, e.g., by boosting
2668 // Sema::IsOverload out to the AST library.
2669
2670 // Function overloading is okay in C++.
David Blaikiebbafb8a2012-03-11 07:00:24 +00002671 if (Importer.getToContext().getLangOpts().CPlusPlus)
Douglas Gregorbb7930c2010-02-10 19:54:31 +00002672 continue;
2673
2674 // Complain about inconsistent function types.
2675 Importer.ToDiag(Loc, diag::err_odr_function_type_inconsistent)
Douglas Gregorb4964f72010-02-15 23:54:17 +00002676 << Name << D->getType() << FoundFunction->getType();
Douglas Gregorbb7930c2010-02-10 19:54:31 +00002677 Importer.ToDiag(FoundFunction->getLocation(),
2678 diag::note_odr_value_here)
2679 << FoundFunction->getType();
2680 }
2681 }
2682
Douglas Gregor9e0a5b32011-10-15 00:10:27 +00002683 ConflictingDecls.push_back(FoundDecls[I]);
Douglas Gregorbb7930c2010-02-10 19:54:31 +00002684 }
2685
2686 if (!ConflictingDecls.empty()) {
2687 Name = Importer.HandleNameConflict(Name, DC, IDNS,
2688 ConflictingDecls.data(),
2689 ConflictingDecls.size());
2690 if (!Name)
2691 return 0;
2692 }
Douglas Gregor62d311f2010-02-09 19:21:46 +00002693 }
Douglas Gregorb4964f72010-02-15 23:54:17 +00002694
Abramo Bagnarad6d2f182010-08-11 22:01:17 +00002695 DeclarationNameInfo NameInfo(Name, Loc);
2696 // Import additional name location/type info.
2697 ImportDeclarationNameLoc(D->getNameInfo(), NameInfo);
2698
Argyrios Kyrtzidis2f458532012-09-25 19:26:39 +00002699 QualType FromTy = D->getType();
2700 bool usedDifferentExceptionSpec = false;
2701
2702 if (const FunctionProtoType *
2703 FromFPT = D->getType()->getAs<FunctionProtoType>()) {
2704 FunctionProtoType::ExtProtoInfo FromEPI = FromFPT->getExtProtoInfo();
2705 // FunctionProtoType::ExtProtoInfo's ExceptionSpecDecl can point to the
2706 // FunctionDecl that we are importing the FunctionProtoType for.
2707 // To avoid an infinite recursion when importing, create the FunctionDecl
2708 // with a simplified function type and update it afterwards.
2709 if (FromEPI.ExceptionSpecDecl || FromEPI.ExceptionSpecTemplate ||
2710 FromEPI.NoexceptExpr) {
2711 FunctionProtoType::ExtProtoInfo DefaultEPI;
2712 FromTy = Importer.getFromContext().getFunctionType(
Reid Kleckner896b32f2013-06-10 20:51:09 +00002713 FromFPT->getResultType(), FromFPT->getArgTypes(), DefaultEPI);
Argyrios Kyrtzidis2f458532012-09-25 19:26:39 +00002714 usedDifferentExceptionSpec = true;
2715 }
2716 }
2717
Douglas Gregorb4964f72010-02-15 23:54:17 +00002718 // Import the type.
Argyrios Kyrtzidis2f458532012-09-25 19:26:39 +00002719 QualType T = Importer.Import(FromTy);
Douglas Gregorb4964f72010-02-15 23:54:17 +00002720 if (T.isNull())
2721 return 0;
Douglas Gregorbb7930c2010-02-10 19:54:31 +00002722
2723 // Import the function parameters.
Chris Lattner0e62c1c2011-07-23 10:55:15 +00002724 SmallVector<ParmVarDecl *, 8> Parameters;
Douglas Gregorbb7930c2010-02-10 19:54:31 +00002725 for (FunctionDecl::param_iterator P = D->param_begin(), PEnd = D->param_end();
2726 P != PEnd; ++P) {
2727 ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(*P));
2728 if (!ToP)
2729 return 0;
2730
2731 Parameters.push_back(ToP);
2732 }
2733
2734 // Create the imported function.
2735 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
Douglas Gregor00eace12010-02-21 18:29:16 +00002736 FunctionDecl *ToFunction = 0;
2737 if (CXXConstructorDecl *FromConstructor = dyn_cast<CXXConstructorDecl>(D)) {
2738 ToFunction = CXXConstructorDecl::Create(Importer.getToContext(),
2739 cast<CXXRecordDecl>(DC),
Abramo Bagnaradff19302011-03-08 08:55:46 +00002740 D->getInnerLocStart(),
Abramo Bagnarad6d2f182010-08-11 22:01:17 +00002741 NameInfo, T, TInfo,
Douglas Gregor00eace12010-02-21 18:29:16 +00002742 FromConstructor->isExplicit(),
2743 D->isInlineSpecified(),
Richard Smitha77a0a62011-08-15 21:04:07 +00002744 D->isImplicit(),
2745 D->isConstexpr());
Douglas Gregor00eace12010-02-21 18:29:16 +00002746 } else if (isa<CXXDestructorDecl>(D)) {
2747 ToFunction = CXXDestructorDecl::Create(Importer.getToContext(),
2748 cast<CXXRecordDecl>(DC),
Abramo Bagnaradff19302011-03-08 08:55:46 +00002749 D->getInnerLocStart(),
Craig Silversteinaf8808d2010-10-21 00:44:50 +00002750 NameInfo, T, TInfo,
Douglas Gregor00eace12010-02-21 18:29:16 +00002751 D->isInlineSpecified(),
2752 D->isImplicit());
2753 } else if (CXXConversionDecl *FromConversion
2754 = dyn_cast<CXXConversionDecl>(D)) {
2755 ToFunction = CXXConversionDecl::Create(Importer.getToContext(),
2756 cast<CXXRecordDecl>(DC),
Abramo Bagnaradff19302011-03-08 08:55:46 +00002757 D->getInnerLocStart(),
Abramo Bagnarad6d2f182010-08-11 22:01:17 +00002758 NameInfo, T, TInfo,
Douglas Gregor00eace12010-02-21 18:29:16 +00002759 D->isInlineSpecified(),
Douglas Gregorf2f08062011-03-08 17:10:18 +00002760 FromConversion->isExplicit(),
Richard Smitha77a0a62011-08-15 21:04:07 +00002761 D->isConstexpr(),
Douglas Gregorf2f08062011-03-08 17:10:18 +00002762 Importer.Import(D->getLocEnd()));
Douglas Gregora50ad132010-11-29 16:04:58 +00002763 } else if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
2764 ToFunction = CXXMethodDecl::Create(Importer.getToContext(),
2765 cast<CXXRecordDecl>(DC),
Abramo Bagnaradff19302011-03-08 08:55:46 +00002766 D->getInnerLocStart(),
Douglas Gregora50ad132010-11-29 16:04:58 +00002767 NameInfo, T, TInfo,
Rafael Espindola6ae7e502013-04-03 19:27:57 +00002768 Method->getStorageClass(),
Douglas Gregorf2f08062011-03-08 17:10:18 +00002769 Method->isInlineSpecified(),
Richard Smitha77a0a62011-08-15 21:04:07 +00002770 D->isConstexpr(),
Douglas Gregorf2f08062011-03-08 17:10:18 +00002771 Importer.Import(D->getLocEnd()));
Douglas Gregor00eace12010-02-21 18:29:16 +00002772 } else {
Abramo Bagnarad6d2f182010-08-11 22:01:17 +00002773 ToFunction = FunctionDecl::Create(Importer.getToContext(), DC,
Abramo Bagnaradff19302011-03-08 08:55:46 +00002774 D->getInnerLocStart(),
Abramo Bagnarad6d2f182010-08-11 22:01:17 +00002775 NameInfo, T, TInfo, D->getStorageClass(),
Douglas Gregor00eace12010-02-21 18:29:16 +00002776 D->isInlineSpecified(),
Richard Smitha77a0a62011-08-15 21:04:07 +00002777 D->hasWrittenPrototype(),
2778 D->isConstexpr());
Douglas Gregor00eace12010-02-21 18:29:16 +00002779 }
John McCall3e11ebe2010-03-15 10:12:16 +00002780
2781 // Import the qualifier, if any.
Douglas Gregor14454802011-02-25 02:25:35 +00002782 ToFunction->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
Douglas Gregordd483172010-02-22 17:42:47 +00002783 ToFunction->setAccess(D->getAccess());
Douglas Gregor43f54792010-02-17 02:12:47 +00002784 ToFunction->setLexicalDeclContext(LexicalDC);
John McCall08432c82011-01-27 02:37:01 +00002785 ToFunction->setVirtualAsWritten(D->isVirtualAsWritten());
2786 ToFunction->setTrivial(D->isTrivial());
2787 ToFunction->setPure(D->isPure());
Douglas Gregor43f54792010-02-17 02:12:47 +00002788 Importer.Imported(D, ToFunction);
Douglas Gregor62d311f2010-02-09 19:21:46 +00002789
Douglas Gregorbb7930c2010-02-10 19:54:31 +00002790 // Set the parameters.
2791 for (unsigned I = 0, N = Parameters.size(); I != N; ++I) {
Douglas Gregor43f54792010-02-17 02:12:47 +00002792 Parameters[I]->setOwningFunction(ToFunction);
Sean Callanan95e74be2011-10-21 02:57:43 +00002793 ToFunction->addDeclInternal(Parameters[I]);
Douglas Gregorbb7930c2010-02-10 19:54:31 +00002794 }
David Blaikie9c70e042011-09-21 18:16:56 +00002795 ToFunction->setParams(Parameters);
Douglas Gregorbb7930c2010-02-10 19:54:31 +00002796
Argyrios Kyrtzidis2f458532012-09-25 19:26:39 +00002797 if (usedDifferentExceptionSpec) {
2798 // Update FunctionProtoType::ExtProtoInfo.
2799 QualType T = Importer.Import(D->getType());
2800 if (T.isNull())
2801 return 0;
2802 ToFunction->setType(T);
Argyrios Kyrtzidisb41791d2012-09-22 01:58:06 +00002803 }
2804
Douglas Gregorbb7930c2010-02-10 19:54:31 +00002805 // FIXME: Other bits to merge?
Douglas Gregor0eaa2bf2010-10-01 23:55:07 +00002806
2807 // Add this function to the lexical context.
Sean Callanan95e74be2011-10-21 02:57:43 +00002808 LexicalDC->addDeclInternal(ToFunction);
Douglas Gregor0eaa2bf2010-10-01 23:55:07 +00002809
Douglas Gregor43f54792010-02-17 02:12:47 +00002810 return ToFunction;
Douglas Gregorbb7930c2010-02-10 19:54:31 +00002811}
2812
Douglas Gregor00eace12010-02-21 18:29:16 +00002813Decl *ASTNodeImporter::VisitCXXMethodDecl(CXXMethodDecl *D) {
2814 return VisitFunctionDecl(D);
2815}
2816
2817Decl *ASTNodeImporter::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
2818 return VisitCXXMethodDecl(D);
2819}
2820
2821Decl *ASTNodeImporter::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
2822 return VisitCXXMethodDecl(D);
2823}
2824
2825Decl *ASTNodeImporter::VisitCXXConversionDecl(CXXConversionDecl *D) {
2826 return VisitCXXMethodDecl(D);
2827}
2828
Douglas Gregorceb32bf2012-10-26 16:45:11 +00002829static unsigned getFieldIndex(Decl *F) {
2830 RecordDecl *Owner = dyn_cast<RecordDecl>(F->getDeclContext());
2831 if (!Owner)
2832 return 0;
2833
2834 unsigned Index = 1;
2835 for (DeclContext::decl_iterator D = Owner->noload_decls_begin(),
2836 DEnd = Owner->noload_decls_end();
2837 D != DEnd; ++D) {
2838 if (*D == F)
2839 return Index;
2840
2841 if (isa<FieldDecl>(*D) || isa<IndirectFieldDecl>(*D))
2842 ++Index;
2843 }
2844
2845 return Index;
2846}
2847
Douglas Gregor5c73e912010-02-11 00:48:18 +00002848Decl *ASTNodeImporter::VisitFieldDecl(FieldDecl *D) {
2849 // Import the major distinguishing characteristics of a variable.
2850 DeclContext *DC, *LexicalDC;
2851 DeclarationName Name;
Douglas Gregor5c73e912010-02-11 00:48:18 +00002852 SourceLocation Loc;
Douglas Gregorb4964f72010-02-15 23:54:17 +00002853 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2854 return 0;
2855
Douglas Gregor03d1ed32011-10-14 21:54:42 +00002856 // Determine whether we've already imported this field.
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002857 SmallVector<NamedDecl *, 2> FoundDecls;
Douglas Gregor9e0a5b32011-10-15 00:10:27 +00002858 DC->localUncachedLookup(Name, FoundDecls);
2859 for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
2860 if (FieldDecl *FoundField = dyn_cast<FieldDecl>(FoundDecls[I])) {
Douglas Gregorceb32bf2012-10-26 16:45:11 +00002861 // For anonymous fields, match up by index.
2862 if (!Name && getFieldIndex(D) != getFieldIndex(FoundField))
2863 continue;
2864
Douglas Gregor03d1ed32011-10-14 21:54:42 +00002865 if (Importer.IsStructurallyEquivalent(D->getType(),
2866 FoundField->getType())) {
2867 Importer.Imported(D, FoundField);
2868 return FoundField;
2869 }
2870
2871 Importer.ToDiag(Loc, diag::err_odr_field_type_inconsistent)
2872 << Name << D->getType() << FoundField->getType();
2873 Importer.ToDiag(FoundField->getLocation(), diag::note_odr_value_here)
2874 << FoundField->getType();
2875 return 0;
2876 }
2877 }
2878
Douglas Gregorb4964f72010-02-15 23:54:17 +00002879 // Import the type.
2880 QualType T = Importer.Import(D->getType());
2881 if (T.isNull())
Douglas Gregor5c73e912010-02-11 00:48:18 +00002882 return 0;
2883
2884 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
2885 Expr *BitWidth = Importer.Import(D->getBitWidth());
2886 if (!BitWidth && D->getBitWidth())
2887 return 0;
2888
Abramo Bagnaradff19302011-03-08 08:55:46 +00002889 FieldDecl *ToField = FieldDecl::Create(Importer.getToContext(), DC,
2890 Importer.Import(D->getInnerLocStart()),
Douglas Gregor5c73e912010-02-11 00:48:18 +00002891 Loc, Name.getAsIdentifierInfo(),
Richard Smith938f40b2011-06-11 17:19:42 +00002892 T, TInfo, BitWidth, D->isMutable(),
Richard Smith2b013182012-06-10 03:12:00 +00002893 D->getInClassInitStyle());
Douglas Gregordd483172010-02-22 17:42:47 +00002894 ToField->setAccess(D->getAccess());
Douglas Gregor5c73e912010-02-11 00:48:18 +00002895 ToField->setLexicalDeclContext(LexicalDC);
Richard Smith938f40b2011-06-11 17:19:42 +00002896 if (ToField->hasInClassInitializer())
2897 ToField->setInClassInitializer(D->getInClassInitializer());
Douglas Gregorceb32bf2012-10-26 16:45:11 +00002898 ToField->setImplicit(D->isImplicit());
Douglas Gregor8cdbe642010-02-12 23:44:20 +00002899 Importer.Imported(D, ToField);
Sean Callanan95e74be2011-10-21 02:57:43 +00002900 LexicalDC->addDeclInternal(ToField);
Douglas Gregor5c73e912010-02-11 00:48:18 +00002901 return ToField;
2902}
2903
Francois Pichet783dd6e2010-11-21 06:08:52 +00002904Decl *ASTNodeImporter::VisitIndirectFieldDecl(IndirectFieldDecl *D) {
2905 // Import the major distinguishing characteristics of a variable.
2906 DeclContext *DC, *LexicalDC;
2907 DeclarationName Name;
2908 SourceLocation Loc;
2909 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2910 return 0;
2911
Douglas Gregor03d1ed32011-10-14 21:54:42 +00002912 // Determine whether we've already imported this field.
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002913 SmallVector<NamedDecl *, 2> FoundDecls;
Douglas Gregor9e0a5b32011-10-15 00:10:27 +00002914 DC->localUncachedLookup(Name, FoundDecls);
2915 for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
Douglas Gregor03d1ed32011-10-14 21:54:42 +00002916 if (IndirectFieldDecl *FoundField
Douglas Gregor9e0a5b32011-10-15 00:10:27 +00002917 = dyn_cast<IndirectFieldDecl>(FoundDecls[I])) {
Douglas Gregorceb32bf2012-10-26 16:45:11 +00002918 // For anonymous indirect fields, match up by index.
2919 if (!Name && getFieldIndex(D) != getFieldIndex(FoundField))
2920 continue;
2921
Douglas Gregor03d1ed32011-10-14 21:54:42 +00002922 if (Importer.IsStructurallyEquivalent(D->getType(),
Douglas Gregordd6006f2012-07-17 21:16:27 +00002923 FoundField->getType(),
David Blaikie7d170102013-05-15 07:37:26 +00002924 !Name.isEmpty())) {
Douglas Gregor03d1ed32011-10-14 21:54:42 +00002925 Importer.Imported(D, FoundField);
2926 return FoundField;
2927 }
Douglas Gregordd6006f2012-07-17 21:16:27 +00002928
2929 // If there are more anonymous fields to check, continue.
2930 if (!Name && I < N-1)
2931 continue;
2932
Douglas Gregor03d1ed32011-10-14 21:54:42 +00002933 Importer.ToDiag(Loc, diag::err_odr_field_type_inconsistent)
2934 << Name << D->getType() << FoundField->getType();
2935 Importer.ToDiag(FoundField->getLocation(), diag::note_odr_value_here)
2936 << FoundField->getType();
2937 return 0;
2938 }
2939 }
2940
Francois Pichet783dd6e2010-11-21 06:08:52 +00002941 // Import the type.
2942 QualType T = Importer.Import(D->getType());
2943 if (T.isNull())
2944 return 0;
2945
2946 NamedDecl **NamedChain =
2947 new (Importer.getToContext())NamedDecl*[D->getChainingSize()];
2948
2949 unsigned i = 0;
2950 for (IndirectFieldDecl::chain_iterator PI = D->chain_begin(),
2951 PE = D->chain_end(); PI != PE; ++PI) {
2952 Decl* D = Importer.Import(*PI);
2953 if (!D)
2954 return 0;
2955 NamedChain[i++] = cast<NamedDecl>(D);
2956 }
2957
2958 IndirectFieldDecl *ToIndirectField = IndirectFieldDecl::Create(
2959 Importer.getToContext(), DC,
2960 Loc, Name.getAsIdentifierInfo(), T,
2961 NamedChain, D->getChainingSize());
2962 ToIndirectField->setAccess(D->getAccess());
2963 ToIndirectField->setLexicalDeclContext(LexicalDC);
2964 Importer.Imported(D, ToIndirectField);
Sean Callanan95e74be2011-10-21 02:57:43 +00002965 LexicalDC->addDeclInternal(ToIndirectField);
Francois Pichet783dd6e2010-11-21 06:08:52 +00002966 return ToIndirectField;
2967}
2968
Douglas Gregor7244b0b2010-02-17 00:34:30 +00002969Decl *ASTNodeImporter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
2970 // Import the major distinguishing characteristics of an ivar.
2971 DeclContext *DC, *LexicalDC;
2972 DeclarationName Name;
2973 SourceLocation Loc;
2974 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2975 return 0;
2976
2977 // Determine whether we've already imported this ivar
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002978 SmallVector<NamedDecl *, 2> FoundDecls;
Douglas Gregor9e0a5b32011-10-15 00:10:27 +00002979 DC->localUncachedLookup(Name, FoundDecls);
2980 for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
2981 if (ObjCIvarDecl *FoundIvar = dyn_cast<ObjCIvarDecl>(FoundDecls[I])) {
Douglas Gregor7244b0b2010-02-17 00:34:30 +00002982 if (Importer.IsStructurallyEquivalent(D->getType(),
2983 FoundIvar->getType())) {
2984 Importer.Imported(D, FoundIvar);
2985 return FoundIvar;
2986 }
2987
2988 Importer.ToDiag(Loc, diag::err_odr_ivar_type_inconsistent)
2989 << Name << D->getType() << FoundIvar->getType();
2990 Importer.ToDiag(FoundIvar->getLocation(), diag::note_odr_value_here)
2991 << FoundIvar->getType();
2992 return 0;
2993 }
2994 }
2995
2996 // Import the type.
2997 QualType T = Importer.Import(D->getType());
2998 if (T.isNull())
2999 return 0;
3000
3001 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
3002 Expr *BitWidth = Importer.Import(D->getBitWidth());
3003 if (!BitWidth && D->getBitWidth())
3004 return 0;
3005
Daniel Dunbarfe3ead72010-04-02 20:10:03 +00003006 ObjCIvarDecl *ToIvar = ObjCIvarDecl::Create(Importer.getToContext(),
3007 cast<ObjCContainerDecl>(DC),
Abramo Bagnaradff19302011-03-08 08:55:46 +00003008 Importer.Import(D->getInnerLocStart()),
Douglas Gregor7244b0b2010-02-17 00:34:30 +00003009 Loc, Name.getAsIdentifierInfo(),
3010 T, TInfo, D->getAccessControl(),
Fariborz Jahanianaea8e1e2010-07-17 18:35:47 +00003011 BitWidth, D->getSynthesize());
Douglas Gregor7244b0b2010-02-17 00:34:30 +00003012 ToIvar->setLexicalDeclContext(LexicalDC);
3013 Importer.Imported(D, ToIvar);
Sean Callanan95e74be2011-10-21 02:57:43 +00003014 LexicalDC->addDeclInternal(ToIvar);
Douglas Gregor7244b0b2010-02-17 00:34:30 +00003015 return ToIvar;
3016
3017}
3018
Douglas Gregorbb7930c2010-02-10 19:54:31 +00003019Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
3020 // Import the major distinguishing characteristics of a variable.
3021 DeclContext *DC, *LexicalDC;
3022 DeclarationName Name;
Douglas Gregorbb7930c2010-02-10 19:54:31 +00003023 SourceLocation Loc;
Douglas Gregorb4964f72010-02-15 23:54:17 +00003024 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00003025 return 0;
3026
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00003027 // Try to find a variable in our own ("to") context with the same name and
3028 // in the same context as the variable we're importing.
Douglas Gregor62d311f2010-02-09 19:21:46 +00003029 if (D->isFileVarDecl()) {
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00003030 VarDecl *MergeWithVar = 0;
Chris Lattner0e62c1c2011-07-23 10:55:15 +00003031 SmallVector<NamedDecl *, 4> ConflictingDecls;
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00003032 unsigned IDNS = Decl::IDNS_Ordinary;
Dmitri Gribenkof8579502013-01-12 19:30:44 +00003033 SmallVector<NamedDecl *, 2> FoundDecls;
Douglas Gregor9e0a5b32011-10-15 00:10:27 +00003034 DC->localUncachedLookup(Name, FoundDecls);
3035 for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
3036 if (!FoundDecls[I]->isInIdentifierNamespace(IDNS))
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00003037 continue;
3038
Douglas Gregor9e0a5b32011-10-15 00:10:27 +00003039 if (VarDecl *FoundVar = dyn_cast<VarDecl>(FoundDecls[I])) {
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00003040 // We have found a variable that we may need to merge with. Check it.
Rafael Espindola3ae00052013-05-13 00:12:11 +00003041 if (FoundVar->hasExternalFormalLinkage() &&
3042 D->hasExternalFormalLinkage()) {
Douglas Gregorb4964f72010-02-15 23:54:17 +00003043 if (Importer.IsStructurallyEquivalent(D->getType(),
3044 FoundVar->getType())) {
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00003045 MergeWithVar = FoundVar;
3046 break;
3047 }
3048
Douglas Gregor56521c52010-02-12 17:23:39 +00003049 const ArrayType *FoundArray
3050 = Importer.getToContext().getAsArrayType(FoundVar->getType());
3051 const ArrayType *TArray
Douglas Gregorb4964f72010-02-15 23:54:17 +00003052 = Importer.getToContext().getAsArrayType(D->getType());
Douglas Gregor56521c52010-02-12 17:23:39 +00003053 if (FoundArray && TArray) {
3054 if (isa<IncompleteArrayType>(FoundArray) &&
3055 isa<ConstantArrayType>(TArray)) {
Douglas Gregorb4964f72010-02-15 23:54:17 +00003056 // Import the type.
3057 QualType T = Importer.Import(D->getType());
3058 if (T.isNull())
3059 return 0;
3060
Douglas Gregor56521c52010-02-12 17:23:39 +00003061 FoundVar->setType(T);
3062 MergeWithVar = FoundVar;
3063 break;
3064 } else if (isa<IncompleteArrayType>(TArray) &&
3065 isa<ConstantArrayType>(FoundArray)) {
3066 MergeWithVar = FoundVar;
3067 break;
Douglas Gregor2fbe5582010-02-10 17:16:49 +00003068 }
3069 }
3070
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00003071 Importer.ToDiag(Loc, diag::err_odr_variable_type_inconsistent)
Douglas Gregorb4964f72010-02-15 23:54:17 +00003072 << Name << D->getType() << FoundVar->getType();
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00003073 Importer.ToDiag(FoundVar->getLocation(), diag::note_odr_value_here)
3074 << FoundVar->getType();
3075 }
3076 }
3077
Douglas Gregor9e0a5b32011-10-15 00:10:27 +00003078 ConflictingDecls.push_back(FoundDecls[I]);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00003079 }
3080
3081 if (MergeWithVar) {
3082 // An equivalent variable with external linkage has been found. Link
3083 // the two declarations, then merge them.
Douglas Gregor8cdbe642010-02-12 23:44:20 +00003084 Importer.Imported(D, MergeWithVar);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00003085
3086 if (VarDecl *DDef = D->getDefinition()) {
3087 if (VarDecl *ExistingDef = MergeWithVar->getDefinition()) {
3088 Importer.ToDiag(ExistingDef->getLocation(),
3089 diag::err_odr_variable_multiple_def)
3090 << Name;
3091 Importer.FromDiag(DDef->getLocation(), diag::note_odr_defined_here);
3092 } else {
3093 Expr *Init = Importer.Import(DDef->getInit());
Douglas Gregord5058122010-02-11 01:19:42 +00003094 MergeWithVar->setInit(Init);
Richard Smithd0b4dd62011-12-19 06:19:21 +00003095 if (DDef->isInitKnownICE()) {
3096 EvaluatedStmt *Eval = MergeWithVar->ensureEvaluatedStmt();
3097 Eval->CheckedICE = true;
3098 Eval->IsICE = DDef->isInitICE();
3099 }
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00003100 }
3101 }
3102
3103 return MergeWithVar;
3104 }
3105
3106 if (!ConflictingDecls.empty()) {
3107 Name = Importer.HandleNameConflict(Name, DC, IDNS,
3108 ConflictingDecls.data(),
3109 ConflictingDecls.size());
3110 if (!Name)
3111 return 0;
3112 }
3113 }
Douglas Gregorfa7a0e52010-02-10 17:47:19 +00003114
Douglas Gregorb4964f72010-02-15 23:54:17 +00003115 // Import the type.
3116 QualType T = Importer.Import(D->getType());
3117 if (T.isNull())
3118 return 0;
3119
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00003120 // Create the imported variable.
Douglas Gregorfa7a0e52010-02-10 17:47:19 +00003121 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
Abramo Bagnaradff19302011-03-08 08:55:46 +00003122 VarDecl *ToVar = VarDecl::Create(Importer.getToContext(), DC,
3123 Importer.Import(D->getInnerLocStart()),
3124 Loc, Name.getAsIdentifierInfo(),
3125 T, TInfo,
Rafael Espindola6ae7e502013-04-03 19:27:57 +00003126 D->getStorageClass());
Douglas Gregor14454802011-02-25 02:25:35 +00003127 ToVar->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
Douglas Gregordd483172010-02-22 17:42:47 +00003128 ToVar->setAccess(D->getAccess());
Douglas Gregor62d311f2010-02-09 19:21:46 +00003129 ToVar->setLexicalDeclContext(LexicalDC);
Douglas Gregor8cdbe642010-02-12 23:44:20 +00003130 Importer.Imported(D, ToVar);
Sean Callanan95e74be2011-10-21 02:57:43 +00003131 LexicalDC->addDeclInternal(ToVar);
Douglas Gregor62d311f2010-02-09 19:21:46 +00003132
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00003133 // Merge the initializer.
Larisse Voufo39a1e502013-08-06 01:03:05 +00003134 if (ImportDefinition(D, ToVar))
3135 return 0;
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00003136
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00003137 return ToVar;
3138}
3139
Douglas Gregor8b228d72010-02-17 21:22:52 +00003140Decl *ASTNodeImporter::VisitImplicitParamDecl(ImplicitParamDecl *D) {
3141 // Parameters are created in the translation unit's context, then moved
3142 // into the function declaration's context afterward.
3143 DeclContext *DC = Importer.getToContext().getTranslationUnitDecl();
3144
3145 // Import the name of this declaration.
3146 DeclarationName Name = Importer.Import(D->getDeclName());
3147 if (D->getDeclName() && !Name)
3148 return 0;
3149
3150 // Import the location of this declaration.
3151 SourceLocation Loc = Importer.Import(D->getLocation());
3152
3153 // Import the parameter's type.
3154 QualType T = Importer.Import(D->getType());
3155 if (T.isNull())
3156 return 0;
3157
3158 // Create the imported parameter.
3159 ImplicitParamDecl *ToParm
3160 = ImplicitParamDecl::Create(Importer.getToContext(), DC,
3161 Loc, Name.getAsIdentifierInfo(),
3162 T);
3163 return Importer.Imported(D, ToParm);
3164}
3165
Douglas Gregorbb7930c2010-02-10 19:54:31 +00003166Decl *ASTNodeImporter::VisitParmVarDecl(ParmVarDecl *D) {
3167 // Parameters are created in the translation unit's context, then moved
3168 // into the function declaration's context afterward.
3169 DeclContext *DC = Importer.getToContext().getTranslationUnitDecl();
3170
Douglas Gregorfa7a0e52010-02-10 17:47:19 +00003171 // Import the name of this declaration.
3172 DeclarationName Name = Importer.Import(D->getDeclName());
3173 if (D->getDeclName() && !Name)
3174 return 0;
3175
Douglas Gregorbb7930c2010-02-10 19:54:31 +00003176 // Import the location of this declaration.
3177 SourceLocation Loc = Importer.Import(D->getLocation());
3178
3179 // Import the parameter's type.
3180 QualType T = Importer.Import(D->getType());
3181 if (T.isNull())
3182 return 0;
3183
3184 // Create the imported parameter.
3185 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
3186 ParmVarDecl *ToParm = ParmVarDecl::Create(Importer.getToContext(), DC,
Abramo Bagnaradff19302011-03-08 08:55:46 +00003187 Importer.Import(D->getInnerLocStart()),
Douglas Gregorbb7930c2010-02-10 19:54:31 +00003188 Loc, Name.getAsIdentifierInfo(),
3189 T, TInfo, D->getStorageClass(),
3190 /*FIXME: Default argument*/ 0);
John McCallf3cd6652010-03-12 18:31:32 +00003191 ToParm->setHasInheritedDefaultArg(D->hasInheritedDefaultArg());
Douglas Gregor8cdbe642010-02-12 23:44:20 +00003192 return Importer.Imported(D, ToParm);
Douglas Gregorbb7930c2010-02-10 19:54:31 +00003193}
3194
Douglas Gregor43f54792010-02-17 02:12:47 +00003195Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
3196 // Import the major distinguishing characteristics of a method.
3197 DeclContext *DC, *LexicalDC;
3198 DeclarationName Name;
3199 SourceLocation Loc;
3200 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
3201 return 0;
3202
Dmitri Gribenkof8579502013-01-12 19:30:44 +00003203 SmallVector<NamedDecl *, 2> FoundDecls;
Douglas Gregor9e0a5b32011-10-15 00:10:27 +00003204 DC->localUncachedLookup(Name, FoundDecls);
3205 for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
3206 if (ObjCMethodDecl *FoundMethod = dyn_cast<ObjCMethodDecl>(FoundDecls[I])) {
Douglas Gregor43f54792010-02-17 02:12:47 +00003207 if (FoundMethod->isInstanceMethod() != D->isInstanceMethod())
3208 continue;
3209
3210 // Check return types.
3211 if (!Importer.IsStructurallyEquivalent(D->getResultType(),
3212 FoundMethod->getResultType())) {
3213 Importer.ToDiag(Loc, diag::err_odr_objc_method_result_type_inconsistent)
3214 << D->isInstanceMethod() << Name
3215 << D->getResultType() << FoundMethod->getResultType();
3216 Importer.ToDiag(FoundMethod->getLocation(),
3217 diag::note_odr_objc_method_here)
3218 << D->isInstanceMethod() << Name;
3219 return 0;
3220 }
3221
3222 // Check the number of parameters.
3223 if (D->param_size() != FoundMethod->param_size()) {
3224 Importer.ToDiag(Loc, diag::err_odr_objc_method_num_params_inconsistent)
3225 << D->isInstanceMethod() << Name
3226 << D->param_size() << FoundMethod->param_size();
3227 Importer.ToDiag(FoundMethod->getLocation(),
3228 diag::note_odr_objc_method_here)
3229 << D->isInstanceMethod() << Name;
3230 return 0;
3231 }
3232
3233 // Check parameter types.
3234 for (ObjCMethodDecl::param_iterator P = D->param_begin(),
3235 PEnd = D->param_end(), FoundP = FoundMethod->param_begin();
3236 P != PEnd; ++P, ++FoundP) {
3237 if (!Importer.IsStructurallyEquivalent((*P)->getType(),
3238 (*FoundP)->getType())) {
3239 Importer.FromDiag((*P)->getLocation(),
3240 diag::err_odr_objc_method_param_type_inconsistent)
3241 << D->isInstanceMethod() << Name
3242 << (*P)->getType() << (*FoundP)->getType();
3243 Importer.ToDiag((*FoundP)->getLocation(), diag::note_odr_value_here)
3244 << (*FoundP)->getType();
3245 return 0;
3246 }
3247 }
3248
3249 // Check variadic/non-variadic.
3250 // Check the number of parameters.
3251 if (D->isVariadic() != FoundMethod->isVariadic()) {
3252 Importer.ToDiag(Loc, diag::err_odr_objc_method_variadic_inconsistent)
3253 << D->isInstanceMethod() << Name;
3254 Importer.ToDiag(FoundMethod->getLocation(),
3255 diag::note_odr_objc_method_here)
3256 << D->isInstanceMethod() << Name;
3257 return 0;
3258 }
3259
3260 // FIXME: Any other bits we need to merge?
3261 return Importer.Imported(D, FoundMethod);
3262 }
3263 }
3264
3265 // Import the result type.
3266 QualType ResultTy = Importer.Import(D->getResultType());
3267 if (ResultTy.isNull())
3268 return 0;
3269
Douglas Gregor12852d92010-03-08 14:59:44 +00003270 TypeSourceInfo *ResultTInfo = Importer.Import(D->getResultTypeSourceInfo());
3271
Douglas Gregor43f54792010-02-17 02:12:47 +00003272 ObjCMethodDecl *ToMethod
3273 = ObjCMethodDecl::Create(Importer.getToContext(),
3274 Loc,
3275 Importer.Import(D->getLocEnd()),
3276 Name.getObjCSelector(),
Douglas Gregor12852d92010-03-08 14:59:44 +00003277 ResultTy, ResultTInfo, DC,
Douglas Gregor43f54792010-02-17 02:12:47 +00003278 D->isInstanceMethod(),
3279 D->isVariadic(),
Jordan Rosed01e83a2012-10-10 16:42:25 +00003280 D->isPropertyAccessor(),
Argyrios Kyrtzidis004df6e2011-08-17 19:25:08 +00003281 D->isImplicit(),
Fariborz Jahanian6e7e8cc2010-07-22 18:24:20 +00003282 D->isDefined(),
Douglas Gregor33823722011-06-11 01:09:30 +00003283 D->getImplementationControl(),
3284 D->hasRelatedResultType());
Douglas Gregor43f54792010-02-17 02:12:47 +00003285
3286 // FIXME: When we decide to merge method definitions, we'll need to
3287 // deal with implicit parameters.
3288
3289 // Import the parameters
Chris Lattner0e62c1c2011-07-23 10:55:15 +00003290 SmallVector<ParmVarDecl *, 5> ToParams;
Douglas Gregor43f54792010-02-17 02:12:47 +00003291 for (ObjCMethodDecl::param_iterator FromP = D->param_begin(),
3292 FromPEnd = D->param_end();
3293 FromP != FromPEnd;
3294 ++FromP) {
3295 ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(*FromP));
3296 if (!ToP)
3297 return 0;
3298
3299 ToParams.push_back(ToP);
3300 }
3301
3302 // Set the parameters.
3303 for (unsigned I = 0, N = ToParams.size(); I != N; ++I) {
3304 ToParams[I]->setOwningFunction(ToMethod);
Sean Callanan95e74be2011-10-21 02:57:43 +00003305 ToMethod->addDeclInternal(ToParams[I]);
Douglas Gregor43f54792010-02-17 02:12:47 +00003306 }
Argyrios Kyrtzidisb8c3aaf2011-10-03 06:37:04 +00003307 SmallVector<SourceLocation, 12> SelLocs;
3308 D->getSelectorLocs(SelLocs);
3309 ToMethod->setMethodParams(Importer.getToContext(), ToParams, SelLocs);
Douglas Gregor43f54792010-02-17 02:12:47 +00003310
3311 ToMethod->setLexicalDeclContext(LexicalDC);
3312 Importer.Imported(D, ToMethod);
Sean Callanan95e74be2011-10-21 02:57:43 +00003313 LexicalDC->addDeclInternal(ToMethod);
Douglas Gregor43f54792010-02-17 02:12:47 +00003314 return ToMethod;
3315}
3316
Douglas Gregor84c51c32010-02-18 01:47:50 +00003317Decl *ASTNodeImporter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
3318 // Import the major distinguishing characteristics of a category.
3319 DeclContext *DC, *LexicalDC;
3320 DeclarationName Name;
3321 SourceLocation Loc;
3322 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
3323 return 0;
3324
3325 ObjCInterfaceDecl *ToInterface
3326 = cast_or_null<ObjCInterfaceDecl>(Importer.Import(D->getClassInterface()));
3327 if (!ToInterface)
3328 return 0;
3329
3330 // Determine if we've already encountered this category.
3331 ObjCCategoryDecl *MergeWithCategory
3332 = ToInterface->FindCategoryDeclaration(Name.getAsIdentifierInfo());
3333 ObjCCategoryDecl *ToCategory = MergeWithCategory;
3334 if (!ToCategory) {
3335 ToCategory = ObjCCategoryDecl::Create(Importer.getToContext(), DC,
Argyrios Kyrtzidis52f53fb2011-10-04 04:48:02 +00003336 Importer.Import(D->getAtStartLoc()),
Douglas Gregor84c51c32010-02-18 01:47:50 +00003337 Loc,
3338 Importer.Import(D->getCategoryNameLoc()),
Argyrios Kyrtzidis3a5094b2011-08-30 19:43:26 +00003339 Name.getAsIdentifierInfo(),
Fariborz Jahaniana7765fe2012-02-20 20:09:20 +00003340 ToInterface,
3341 Importer.Import(D->getIvarLBraceLoc()),
3342 Importer.Import(D->getIvarRBraceLoc()));
Douglas Gregor84c51c32010-02-18 01:47:50 +00003343 ToCategory->setLexicalDeclContext(LexicalDC);
Sean Callanan95e74be2011-10-21 02:57:43 +00003344 LexicalDC->addDeclInternal(ToCategory);
Douglas Gregor84c51c32010-02-18 01:47:50 +00003345 Importer.Imported(D, ToCategory);
3346
Douglas Gregor84c51c32010-02-18 01:47:50 +00003347 // Import protocols
Chris Lattner0e62c1c2011-07-23 10:55:15 +00003348 SmallVector<ObjCProtocolDecl *, 4> Protocols;
3349 SmallVector<SourceLocation, 4> ProtocolLocs;
Douglas Gregor84c51c32010-02-18 01:47:50 +00003350 ObjCCategoryDecl::protocol_loc_iterator FromProtoLoc
3351 = D->protocol_loc_begin();
3352 for (ObjCCategoryDecl::protocol_iterator FromProto = D->protocol_begin(),
3353 FromProtoEnd = D->protocol_end();
3354 FromProto != FromProtoEnd;
3355 ++FromProto, ++FromProtoLoc) {
3356 ObjCProtocolDecl *ToProto
3357 = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
3358 if (!ToProto)
3359 return 0;
3360 Protocols.push_back(ToProto);
3361 ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
3362 }
3363
3364 // FIXME: If we're merging, make sure that the protocol list is the same.
3365 ToCategory->setProtocolList(Protocols.data(), Protocols.size(),
3366 ProtocolLocs.data(), Importer.getToContext());
3367
3368 } else {
3369 Importer.Imported(D, ToCategory);
3370 }
3371
3372 // Import all of the members of this category.
Douglas Gregor968d6332010-02-21 18:24:45 +00003373 ImportDeclContext(D);
Douglas Gregor84c51c32010-02-18 01:47:50 +00003374
3375 // If we have an implementation, import it as well.
3376 if (D->getImplementation()) {
3377 ObjCCategoryImplDecl *Impl
Douglas Gregor35fd7bc2010-12-08 16:41:55 +00003378 = cast_or_null<ObjCCategoryImplDecl>(
3379 Importer.Import(D->getImplementation()));
Douglas Gregor84c51c32010-02-18 01:47:50 +00003380 if (!Impl)
3381 return 0;
3382
3383 ToCategory->setImplementation(Impl);
3384 }
3385
3386 return ToCategory;
3387}
3388
Douglas Gregor2aa53772012-01-24 17:42:07 +00003389bool ASTNodeImporter::ImportDefinition(ObjCProtocolDecl *From,
3390 ObjCProtocolDecl *To,
Douglas Gregor2e15c842012-02-01 21:00:38 +00003391 ImportDefinitionKind Kind) {
Douglas Gregor2aa53772012-01-24 17:42:07 +00003392 if (To->getDefinition()) {
Douglas Gregor2e15c842012-02-01 21:00:38 +00003393 if (shouldForceImportDeclContext(Kind))
3394 ImportDeclContext(From);
Douglas Gregor2aa53772012-01-24 17:42:07 +00003395 return false;
3396 }
3397
3398 // Start the protocol definition
3399 To->startDefinition();
3400
3401 // Import protocols
3402 SmallVector<ObjCProtocolDecl *, 4> Protocols;
3403 SmallVector<SourceLocation, 4> ProtocolLocs;
3404 ObjCProtocolDecl::protocol_loc_iterator
3405 FromProtoLoc = From->protocol_loc_begin();
3406 for (ObjCProtocolDecl::protocol_iterator FromProto = From->protocol_begin(),
3407 FromProtoEnd = From->protocol_end();
3408 FromProto != FromProtoEnd;
3409 ++FromProto, ++FromProtoLoc) {
3410 ObjCProtocolDecl *ToProto
3411 = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
3412 if (!ToProto)
3413 return true;
3414 Protocols.push_back(ToProto);
3415 ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
3416 }
3417
3418 // FIXME: If we're merging, make sure that the protocol list is the same.
3419 To->setProtocolList(Protocols.data(), Protocols.size(),
3420 ProtocolLocs.data(), Importer.getToContext());
3421
Douglas Gregor2e15c842012-02-01 21:00:38 +00003422 if (shouldForceImportDeclContext(Kind)) {
3423 // Import all of the members of this protocol.
3424 ImportDeclContext(From, /*ForceImport=*/true);
3425 }
Douglas Gregor2aa53772012-01-24 17:42:07 +00003426 return false;
3427}
3428
Douglas Gregor98d156a2010-02-17 16:12:00 +00003429Decl *ASTNodeImporter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
Douglas Gregor2aa53772012-01-24 17:42:07 +00003430 // If this protocol has a definition in the translation unit we're coming
3431 // from, but this particular declaration is not that definition, import the
3432 // definition and map to that.
3433 ObjCProtocolDecl *Definition = D->getDefinition();
3434 if (Definition && Definition != D) {
3435 Decl *ImportedDef = Importer.Import(Definition);
3436 if (!ImportedDef)
3437 return 0;
3438
3439 return Importer.Imported(D, ImportedDef);
3440 }
3441
Douglas Gregor84c51c32010-02-18 01:47:50 +00003442 // Import the major distinguishing characteristics of a protocol.
Douglas Gregor98d156a2010-02-17 16:12:00 +00003443 DeclContext *DC, *LexicalDC;
3444 DeclarationName Name;
3445 SourceLocation Loc;
3446 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
3447 return 0;
3448
3449 ObjCProtocolDecl *MergeWithProtocol = 0;
Dmitri Gribenkof8579502013-01-12 19:30:44 +00003450 SmallVector<NamedDecl *, 2> FoundDecls;
Douglas Gregor9e0a5b32011-10-15 00:10:27 +00003451 DC->localUncachedLookup(Name, FoundDecls);
3452 for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
3453 if (!FoundDecls[I]->isInIdentifierNamespace(Decl::IDNS_ObjCProtocol))
Douglas Gregor98d156a2010-02-17 16:12:00 +00003454 continue;
3455
Douglas Gregor9e0a5b32011-10-15 00:10:27 +00003456 if ((MergeWithProtocol = dyn_cast<ObjCProtocolDecl>(FoundDecls[I])))
Douglas Gregor98d156a2010-02-17 16:12:00 +00003457 break;
3458 }
3459
3460 ObjCProtocolDecl *ToProto = MergeWithProtocol;
Douglas Gregor2aa53772012-01-24 17:42:07 +00003461 if (!ToProto) {
3462 ToProto = ObjCProtocolDecl::Create(Importer.getToContext(), DC,
3463 Name.getAsIdentifierInfo(), Loc,
3464 Importer.Import(D->getAtStartLoc()),
3465 /*PrevDecl=*/0);
3466 ToProto->setLexicalDeclContext(LexicalDC);
3467 LexicalDC->addDeclInternal(ToProto);
Douglas Gregor98d156a2010-02-17 16:12:00 +00003468 }
Douglas Gregor2aa53772012-01-24 17:42:07 +00003469
3470 Importer.Imported(D, ToProto);
Douglas Gregor98d156a2010-02-17 16:12:00 +00003471
Douglas Gregor2aa53772012-01-24 17:42:07 +00003472 if (D->isThisDeclarationADefinition() && ImportDefinition(D, ToProto))
3473 return 0;
3474
Douglas Gregor98d156a2010-02-17 16:12:00 +00003475 return ToProto;
3476}
3477
Douglas Gregor2aa53772012-01-24 17:42:07 +00003478bool ASTNodeImporter::ImportDefinition(ObjCInterfaceDecl *From,
3479 ObjCInterfaceDecl *To,
Douglas Gregor2e15c842012-02-01 21:00:38 +00003480 ImportDefinitionKind Kind) {
Douglas Gregor2aa53772012-01-24 17:42:07 +00003481 if (To->getDefinition()) {
3482 // Check consistency of superclass.
3483 ObjCInterfaceDecl *FromSuper = From->getSuperClass();
3484 if (FromSuper) {
3485 FromSuper = cast_or_null<ObjCInterfaceDecl>(Importer.Import(FromSuper));
3486 if (!FromSuper)
3487 return true;
3488 }
3489
3490 ObjCInterfaceDecl *ToSuper = To->getSuperClass();
3491 if ((bool)FromSuper != (bool)ToSuper ||
3492 (FromSuper && !declaresSameEntity(FromSuper, ToSuper))) {
3493 Importer.ToDiag(To->getLocation(),
3494 diag::err_odr_objc_superclass_inconsistent)
3495 << To->getDeclName();
3496 if (ToSuper)
3497 Importer.ToDiag(To->getSuperClassLoc(), diag::note_odr_objc_superclass)
3498 << To->getSuperClass()->getDeclName();
3499 else
3500 Importer.ToDiag(To->getLocation(),
3501 diag::note_odr_objc_missing_superclass);
3502 if (From->getSuperClass())
3503 Importer.FromDiag(From->getSuperClassLoc(),
3504 diag::note_odr_objc_superclass)
3505 << From->getSuperClass()->getDeclName();
3506 else
3507 Importer.FromDiag(From->getLocation(),
3508 diag::note_odr_objc_missing_superclass);
3509 }
3510
Douglas Gregor2e15c842012-02-01 21:00:38 +00003511 if (shouldForceImportDeclContext(Kind))
3512 ImportDeclContext(From);
Douglas Gregor2aa53772012-01-24 17:42:07 +00003513 return false;
3514 }
3515
3516 // Start the definition.
3517 To->startDefinition();
3518
3519 // If this class has a superclass, import it.
3520 if (From->getSuperClass()) {
3521 ObjCInterfaceDecl *Super = cast_or_null<ObjCInterfaceDecl>(
3522 Importer.Import(From->getSuperClass()));
3523 if (!Super)
3524 return true;
3525
3526 To->setSuperClass(Super);
3527 To->setSuperClassLoc(Importer.Import(From->getSuperClassLoc()));
3528 }
3529
3530 // Import protocols
3531 SmallVector<ObjCProtocolDecl *, 4> Protocols;
3532 SmallVector<SourceLocation, 4> ProtocolLocs;
3533 ObjCInterfaceDecl::protocol_loc_iterator
3534 FromProtoLoc = From->protocol_loc_begin();
3535
3536 for (ObjCInterfaceDecl::protocol_iterator FromProto = From->protocol_begin(),
3537 FromProtoEnd = From->protocol_end();
3538 FromProto != FromProtoEnd;
3539 ++FromProto, ++FromProtoLoc) {
3540 ObjCProtocolDecl *ToProto
3541 = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
3542 if (!ToProto)
3543 return true;
3544 Protocols.push_back(ToProto);
3545 ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
3546 }
3547
3548 // FIXME: If we're merging, make sure that the protocol list is the same.
3549 To->setProtocolList(Protocols.data(), Protocols.size(),
3550 ProtocolLocs.data(), Importer.getToContext());
3551
3552 // Import categories. When the categories themselves are imported, they'll
3553 // hook themselves into this interface.
Douglas Gregor048fbfa2013-01-16 23:00:23 +00003554 for (ObjCInterfaceDecl::known_categories_iterator
3555 Cat = From->known_categories_begin(),
3556 CatEnd = From->known_categories_end();
3557 Cat != CatEnd; ++Cat) {
3558 Importer.Import(*Cat);
3559 }
3560
Douglas Gregor2aa53772012-01-24 17:42:07 +00003561 // If we have an @implementation, import it as well.
3562 if (From->getImplementation()) {
3563 ObjCImplementationDecl *Impl = cast_or_null<ObjCImplementationDecl>(
3564 Importer.Import(From->getImplementation()));
3565 if (!Impl)
3566 return true;
3567
3568 To->setImplementation(Impl);
3569 }
3570
Douglas Gregor2e15c842012-02-01 21:00:38 +00003571 if (shouldForceImportDeclContext(Kind)) {
3572 // Import all of the members of this class.
3573 ImportDeclContext(From, /*ForceImport=*/true);
3574 }
Douglas Gregor2aa53772012-01-24 17:42:07 +00003575 return false;
3576}
3577
Douglas Gregor45635322010-02-16 01:20:57 +00003578Decl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
Douglas Gregor2aa53772012-01-24 17:42:07 +00003579 // If this class has a definition in the translation unit we're coming from,
3580 // but this particular declaration is not that definition, import the
3581 // definition and map to that.
3582 ObjCInterfaceDecl *Definition = D->getDefinition();
3583 if (Definition && Definition != D) {
3584 Decl *ImportedDef = Importer.Import(Definition);
3585 if (!ImportedDef)
3586 return 0;
3587
3588 return Importer.Imported(D, ImportedDef);
3589 }
3590
Douglas Gregor45635322010-02-16 01:20:57 +00003591 // Import the major distinguishing characteristics of an @interface.
3592 DeclContext *DC, *LexicalDC;
3593 DeclarationName Name;
3594 SourceLocation Loc;
3595 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
3596 return 0;
3597
Douglas Gregor2aa53772012-01-24 17:42:07 +00003598 // Look for an existing interface with the same name.
Douglas Gregor45635322010-02-16 01:20:57 +00003599 ObjCInterfaceDecl *MergeWithIface = 0;
Dmitri Gribenkof8579502013-01-12 19:30:44 +00003600 SmallVector<NamedDecl *, 2> FoundDecls;
Douglas Gregor9e0a5b32011-10-15 00:10:27 +00003601 DC->localUncachedLookup(Name, FoundDecls);
3602 for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
3603 if (!FoundDecls[I]->isInIdentifierNamespace(Decl::IDNS_Ordinary))
Douglas Gregor45635322010-02-16 01:20:57 +00003604 continue;
3605
Douglas Gregor9e0a5b32011-10-15 00:10:27 +00003606 if ((MergeWithIface = dyn_cast<ObjCInterfaceDecl>(FoundDecls[I])))
Douglas Gregor45635322010-02-16 01:20:57 +00003607 break;
3608 }
3609
Douglas Gregor2aa53772012-01-24 17:42:07 +00003610 // Create an interface declaration, if one does not already exist.
Douglas Gregor45635322010-02-16 01:20:57 +00003611 ObjCInterfaceDecl *ToIface = MergeWithIface;
Douglas Gregor2aa53772012-01-24 17:42:07 +00003612 if (!ToIface) {
3613 ToIface = ObjCInterfaceDecl::Create(Importer.getToContext(), DC,
3614 Importer.Import(D->getAtStartLoc()),
3615 Name.getAsIdentifierInfo(),
3616 /*PrevDecl=*/0,Loc,
3617 D->isImplicitInterfaceDecl());
3618 ToIface->setLexicalDeclContext(LexicalDC);
3619 LexicalDC->addDeclInternal(ToIface);
Douglas Gregor45635322010-02-16 01:20:57 +00003620 }
Douglas Gregor2aa53772012-01-24 17:42:07 +00003621 Importer.Imported(D, ToIface);
Douglas Gregor45635322010-02-16 01:20:57 +00003622
Douglas Gregor2aa53772012-01-24 17:42:07 +00003623 if (D->isThisDeclarationADefinition() && ImportDefinition(D, ToIface))
3624 return 0;
Douglas Gregor45635322010-02-16 01:20:57 +00003625
Douglas Gregor98d156a2010-02-17 16:12:00 +00003626 return ToIface;
Douglas Gregor45635322010-02-16 01:20:57 +00003627}
3628
Douglas Gregor4da9d682010-12-07 15:32:12 +00003629Decl *ASTNodeImporter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
3630 ObjCCategoryDecl *Category = cast_or_null<ObjCCategoryDecl>(
3631 Importer.Import(D->getCategoryDecl()));
3632 if (!Category)
3633 return 0;
3634
3635 ObjCCategoryImplDecl *ToImpl = Category->getImplementation();
3636 if (!ToImpl) {
3637 DeclContext *DC = Importer.ImportContext(D->getDeclContext());
3638 if (!DC)
3639 return 0;
3640
Argyrios Kyrtzidis4996f5f2011-12-09 00:31:40 +00003641 SourceLocation CategoryNameLoc = Importer.Import(D->getCategoryNameLoc());
Douglas Gregor4da9d682010-12-07 15:32:12 +00003642 ToImpl = ObjCCategoryImplDecl::Create(Importer.getToContext(), DC,
Douglas Gregor4da9d682010-12-07 15:32:12 +00003643 Importer.Import(D->getIdentifier()),
Argyrios Kyrtzidis52f53fb2011-10-04 04:48:02 +00003644 Category->getClassInterface(),
3645 Importer.Import(D->getLocation()),
Argyrios Kyrtzidis4996f5f2011-12-09 00:31:40 +00003646 Importer.Import(D->getAtStartLoc()),
3647 CategoryNameLoc);
Douglas Gregor4da9d682010-12-07 15:32:12 +00003648
3649 DeclContext *LexicalDC = DC;
3650 if (D->getDeclContext() != D->getLexicalDeclContext()) {
3651 LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
3652 if (!LexicalDC)
3653 return 0;
3654
3655 ToImpl->setLexicalDeclContext(LexicalDC);
3656 }
3657
Sean Callanan95e74be2011-10-21 02:57:43 +00003658 LexicalDC->addDeclInternal(ToImpl);
Douglas Gregor4da9d682010-12-07 15:32:12 +00003659 Category->setImplementation(ToImpl);
3660 }
3661
3662 Importer.Imported(D, ToImpl);
Douglas Gregor35fd7bc2010-12-08 16:41:55 +00003663 ImportDeclContext(D);
Douglas Gregor4da9d682010-12-07 15:32:12 +00003664 return ToImpl;
3665}
3666
Douglas Gregorda8025c2010-12-07 01:26:03 +00003667Decl *ASTNodeImporter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
3668 // Find the corresponding interface.
3669 ObjCInterfaceDecl *Iface = cast_or_null<ObjCInterfaceDecl>(
3670 Importer.Import(D->getClassInterface()));
3671 if (!Iface)
3672 return 0;
3673
3674 // Import the superclass, if any.
3675 ObjCInterfaceDecl *Super = 0;
3676 if (D->getSuperClass()) {
3677 Super = cast_or_null<ObjCInterfaceDecl>(
3678 Importer.Import(D->getSuperClass()));
3679 if (!Super)
3680 return 0;
3681 }
3682
3683 ObjCImplementationDecl *Impl = Iface->getImplementation();
3684 if (!Impl) {
3685 // We haven't imported an implementation yet. Create a new @implementation
3686 // now.
3687 Impl = ObjCImplementationDecl::Create(Importer.getToContext(),
3688 Importer.ImportContext(D->getDeclContext()),
Argyrios Kyrtzidis52f53fb2011-10-04 04:48:02 +00003689 Iface, Super,
Douglas Gregorda8025c2010-12-07 01:26:03 +00003690 Importer.Import(D->getLocation()),
Fariborz Jahaniana7765fe2012-02-20 20:09:20 +00003691 Importer.Import(D->getAtStartLoc()),
Argyrios Kyrtzidis5d2ce842013-05-03 22:31:26 +00003692 Importer.Import(D->getSuperClassLoc()),
Fariborz Jahaniana7765fe2012-02-20 20:09:20 +00003693 Importer.Import(D->getIvarLBraceLoc()),
3694 Importer.Import(D->getIvarRBraceLoc()));
Douglas Gregorda8025c2010-12-07 01:26:03 +00003695
3696 if (D->getDeclContext() != D->getLexicalDeclContext()) {
3697 DeclContext *LexicalDC
3698 = Importer.ImportContext(D->getLexicalDeclContext());
3699 if (!LexicalDC)
3700 return 0;
3701 Impl->setLexicalDeclContext(LexicalDC);
3702 }
3703
3704 // Associate the implementation with the class it implements.
3705 Iface->setImplementation(Impl);
3706 Importer.Imported(D, Iface->getImplementation());
3707 } else {
3708 Importer.Imported(D, Iface->getImplementation());
3709
3710 // Verify that the existing @implementation has the same superclass.
3711 if ((Super && !Impl->getSuperClass()) ||
3712 (!Super && Impl->getSuperClass()) ||
3713 (Super && Impl->getSuperClass() &&
Douglas Gregor0b144e12011-12-15 00:29:59 +00003714 !declaresSameEntity(Super->getCanonicalDecl(), Impl->getSuperClass()))) {
Douglas Gregorda8025c2010-12-07 01:26:03 +00003715 Importer.ToDiag(Impl->getLocation(),
3716 diag::err_odr_objc_superclass_inconsistent)
3717 << Iface->getDeclName();
3718 // FIXME: It would be nice to have the location of the superclass
3719 // below.
3720 if (Impl->getSuperClass())
3721 Importer.ToDiag(Impl->getLocation(),
3722 diag::note_odr_objc_superclass)
3723 << Impl->getSuperClass()->getDeclName();
3724 else
3725 Importer.ToDiag(Impl->getLocation(),
3726 diag::note_odr_objc_missing_superclass);
3727 if (D->getSuperClass())
3728 Importer.FromDiag(D->getLocation(),
3729 diag::note_odr_objc_superclass)
3730 << D->getSuperClass()->getDeclName();
3731 else
3732 Importer.FromDiag(D->getLocation(),
3733 diag::note_odr_objc_missing_superclass);
3734 return 0;
3735 }
3736 }
3737
3738 // Import all of the members of this @implementation.
3739 ImportDeclContext(D);
3740
3741 return Impl;
3742}
3743
Douglas Gregora11c4582010-02-17 18:02:10 +00003744Decl *ASTNodeImporter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
3745 // Import the major distinguishing characteristics of an @property.
3746 DeclContext *DC, *LexicalDC;
3747 DeclarationName Name;
3748 SourceLocation Loc;
3749 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
3750 return 0;
3751
3752 // Check whether we have already imported this property.
Dmitri Gribenkof8579502013-01-12 19:30:44 +00003753 SmallVector<NamedDecl *, 2> FoundDecls;
Douglas Gregor9e0a5b32011-10-15 00:10:27 +00003754 DC->localUncachedLookup(Name, FoundDecls);
3755 for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
Douglas Gregora11c4582010-02-17 18:02:10 +00003756 if (ObjCPropertyDecl *FoundProp
Douglas Gregor9e0a5b32011-10-15 00:10:27 +00003757 = dyn_cast<ObjCPropertyDecl>(FoundDecls[I])) {
Douglas Gregora11c4582010-02-17 18:02:10 +00003758 // Check property types.
3759 if (!Importer.IsStructurallyEquivalent(D->getType(),
3760 FoundProp->getType())) {
3761 Importer.ToDiag(Loc, diag::err_odr_objc_property_type_inconsistent)
3762 << Name << D->getType() << FoundProp->getType();
3763 Importer.ToDiag(FoundProp->getLocation(), diag::note_odr_value_here)
3764 << FoundProp->getType();
3765 return 0;
3766 }
3767
3768 // FIXME: Check property attributes, getters, setters, etc.?
3769
3770 // Consider these properties to be equivalent.
3771 Importer.Imported(D, FoundProp);
3772 return FoundProp;
3773 }
3774 }
3775
3776 // Import the type.
John McCall339bb662010-06-04 20:50:08 +00003777 TypeSourceInfo *T = Importer.Import(D->getTypeSourceInfo());
3778 if (!T)
Douglas Gregora11c4582010-02-17 18:02:10 +00003779 return 0;
3780
3781 // Create the new property.
3782 ObjCPropertyDecl *ToProperty
3783 = ObjCPropertyDecl::Create(Importer.getToContext(), DC, Loc,
3784 Name.getAsIdentifierInfo(),
3785 Importer.Import(D->getAtLoc()),
Fariborz Jahanian86c2f5c2012-02-29 22:18:55 +00003786 Importer.Import(D->getLParenLoc()),
Douglas Gregora11c4582010-02-17 18:02:10 +00003787 T,
3788 D->getPropertyImplementation());
3789 Importer.Imported(D, ToProperty);
3790 ToProperty->setLexicalDeclContext(LexicalDC);
Sean Callanan95e74be2011-10-21 02:57:43 +00003791 LexicalDC->addDeclInternal(ToProperty);
Douglas Gregora11c4582010-02-17 18:02:10 +00003792
3793 ToProperty->setPropertyAttributes(D->getPropertyAttributes());
Fariborz Jahanian3bf0ded2010-06-22 23:20:40 +00003794 ToProperty->setPropertyAttributesAsWritten(
3795 D->getPropertyAttributesAsWritten());
Douglas Gregora11c4582010-02-17 18:02:10 +00003796 ToProperty->setGetterName(Importer.Import(D->getGetterName()));
3797 ToProperty->setSetterName(Importer.Import(D->getSetterName()));
3798 ToProperty->setGetterMethodDecl(
3799 cast_or_null<ObjCMethodDecl>(Importer.Import(D->getGetterMethodDecl())));
3800 ToProperty->setSetterMethodDecl(
3801 cast_or_null<ObjCMethodDecl>(Importer.Import(D->getSetterMethodDecl())));
3802 ToProperty->setPropertyIvarDecl(
3803 cast_or_null<ObjCIvarDecl>(Importer.Import(D->getPropertyIvarDecl())));
3804 return ToProperty;
3805}
3806
Douglas Gregor14a49e22010-12-07 18:32:03 +00003807Decl *ASTNodeImporter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
3808 ObjCPropertyDecl *Property = cast_or_null<ObjCPropertyDecl>(
3809 Importer.Import(D->getPropertyDecl()));
3810 if (!Property)
3811 return 0;
3812
3813 DeclContext *DC = Importer.ImportContext(D->getDeclContext());
3814 if (!DC)
3815 return 0;
3816
3817 // Import the lexical declaration context.
3818 DeclContext *LexicalDC = DC;
3819 if (D->getDeclContext() != D->getLexicalDeclContext()) {
3820 LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
3821 if (!LexicalDC)
3822 return 0;
3823 }
3824
3825 ObjCImplDecl *InImpl = dyn_cast<ObjCImplDecl>(LexicalDC);
3826 if (!InImpl)
3827 return 0;
3828
3829 // Import the ivar (for an @synthesize).
3830 ObjCIvarDecl *Ivar = 0;
3831 if (D->getPropertyIvarDecl()) {
3832 Ivar = cast_or_null<ObjCIvarDecl>(
3833 Importer.Import(D->getPropertyIvarDecl()));
3834 if (!Ivar)
3835 return 0;
3836 }
3837
3838 ObjCPropertyImplDecl *ToImpl
3839 = InImpl->FindPropertyImplDecl(Property->getIdentifier());
3840 if (!ToImpl) {
3841 ToImpl = ObjCPropertyImplDecl::Create(Importer.getToContext(), DC,
3842 Importer.Import(D->getLocStart()),
3843 Importer.Import(D->getLocation()),
3844 Property,
3845 D->getPropertyImplementation(),
3846 Ivar,
3847 Importer.Import(D->getPropertyIvarDeclLoc()));
3848 ToImpl->setLexicalDeclContext(LexicalDC);
3849 Importer.Imported(D, ToImpl);
Sean Callanan95e74be2011-10-21 02:57:43 +00003850 LexicalDC->addDeclInternal(ToImpl);
Douglas Gregor14a49e22010-12-07 18:32:03 +00003851 } else {
3852 // Check that we have the same kind of property implementation (@synthesize
3853 // vs. @dynamic).
3854 if (D->getPropertyImplementation() != ToImpl->getPropertyImplementation()) {
3855 Importer.ToDiag(ToImpl->getLocation(),
3856 diag::err_odr_objc_property_impl_kind_inconsistent)
3857 << Property->getDeclName()
3858 << (ToImpl->getPropertyImplementation()
3859 == ObjCPropertyImplDecl::Dynamic);
3860 Importer.FromDiag(D->getLocation(),
3861 diag::note_odr_objc_property_impl_kind)
3862 << D->getPropertyDecl()->getDeclName()
3863 << (D->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic);
3864 return 0;
3865 }
3866
3867 // For @synthesize, check that we have the same
3868 if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize &&
3869 Ivar != ToImpl->getPropertyIvarDecl()) {
3870 Importer.ToDiag(ToImpl->getPropertyIvarDeclLoc(),
3871 diag::err_odr_objc_synthesize_ivar_inconsistent)
3872 << Property->getDeclName()
3873 << ToImpl->getPropertyIvarDecl()->getDeclName()
3874 << Ivar->getDeclName();
3875 Importer.FromDiag(D->getPropertyIvarDeclLoc(),
3876 diag::note_odr_objc_synthesize_ivar_here)
3877 << D->getPropertyIvarDecl()->getDeclName();
3878 return 0;
3879 }
3880
3881 // Merge the existing implementation with the new implementation.
3882 Importer.Imported(D, ToImpl);
3883 }
3884
3885 return ToImpl;
3886}
3887
Douglas Gregora082a492010-11-30 19:14:50 +00003888Decl *ASTNodeImporter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
3889 // For template arguments, we adopt the translation unit as our declaration
3890 // context. This context will be fixed when the actual template declaration
3891 // is created.
3892
3893 // FIXME: Import default argument.
3894 return TemplateTypeParmDecl::Create(Importer.getToContext(),
3895 Importer.getToContext().getTranslationUnitDecl(),
Abramo Bagnarab3185b02011-03-06 15:48:19 +00003896 Importer.Import(D->getLocStart()),
Douglas Gregora082a492010-11-30 19:14:50 +00003897 Importer.Import(D->getLocation()),
3898 D->getDepth(),
3899 D->getIndex(),
3900 Importer.Import(D->getIdentifier()),
3901 D->wasDeclaredWithTypename(),
3902 D->isParameterPack());
3903}
3904
3905Decl *
3906ASTNodeImporter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
3907 // Import the name of this declaration.
3908 DeclarationName Name = Importer.Import(D->getDeclName());
3909 if (D->getDeclName() && !Name)
3910 return 0;
3911
3912 // Import the location of this declaration.
3913 SourceLocation Loc = Importer.Import(D->getLocation());
3914
3915 // Import the type of this declaration.
3916 QualType T = Importer.Import(D->getType());
3917 if (T.isNull())
3918 return 0;
3919
3920 // Import type-source information.
3921 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
3922 if (D->getTypeSourceInfo() && !TInfo)
3923 return 0;
3924
3925 // FIXME: Import default argument.
3926
3927 return NonTypeTemplateParmDecl::Create(Importer.getToContext(),
3928 Importer.getToContext().getTranslationUnitDecl(),
Abramo Bagnaradff19302011-03-08 08:55:46 +00003929 Importer.Import(D->getInnerLocStart()),
Douglas Gregora082a492010-11-30 19:14:50 +00003930 Loc, D->getDepth(), D->getPosition(),
3931 Name.getAsIdentifierInfo(),
Douglas Gregorda3cc0d2010-12-23 23:51:58 +00003932 T, D->isParameterPack(), TInfo);
Douglas Gregora082a492010-11-30 19:14:50 +00003933}
3934
3935Decl *
3936ASTNodeImporter::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
3937 // Import the name of this declaration.
3938 DeclarationName Name = Importer.Import(D->getDeclName());
3939 if (D->getDeclName() && !Name)
3940 return 0;
3941
3942 // Import the location of this declaration.
3943 SourceLocation Loc = Importer.Import(D->getLocation());
3944
3945 // Import template parameters.
3946 TemplateParameterList *TemplateParams
3947 = ImportTemplateParameterList(D->getTemplateParameters());
3948 if (!TemplateParams)
3949 return 0;
3950
3951 // FIXME: Import default argument.
3952
3953 return TemplateTemplateParmDecl::Create(Importer.getToContext(),
3954 Importer.getToContext().getTranslationUnitDecl(),
3955 Loc, D->getDepth(), D->getPosition(),
Douglas Gregorf5500772011-01-05 15:48:55 +00003956 D->isParameterPack(),
Douglas Gregora082a492010-11-30 19:14:50 +00003957 Name.getAsIdentifierInfo(),
3958 TemplateParams);
3959}
3960
3961Decl *ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
3962 // If this record has a definition in the translation unit we're coming from,
3963 // but this particular declaration is not that definition, import the
3964 // definition and map to that.
3965 CXXRecordDecl *Definition
3966 = cast_or_null<CXXRecordDecl>(D->getTemplatedDecl()->getDefinition());
3967 if (Definition && Definition != D->getTemplatedDecl()) {
3968 Decl *ImportedDef
3969 = Importer.Import(Definition->getDescribedClassTemplate());
3970 if (!ImportedDef)
3971 return 0;
3972
3973 return Importer.Imported(D, ImportedDef);
3974 }
3975
3976 // Import the major distinguishing characteristics of this class template.
3977 DeclContext *DC, *LexicalDC;
3978 DeclarationName Name;
3979 SourceLocation Loc;
3980 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
3981 return 0;
3982
3983 // We may already have a template of the same name; try to find and match it.
3984 if (!DC->isFunctionOrMethod()) {
Chris Lattner0e62c1c2011-07-23 10:55:15 +00003985 SmallVector<NamedDecl *, 4> ConflictingDecls;
Dmitri Gribenkof8579502013-01-12 19:30:44 +00003986 SmallVector<NamedDecl *, 2> FoundDecls;
Douglas Gregor9e0a5b32011-10-15 00:10:27 +00003987 DC->localUncachedLookup(Name, FoundDecls);
3988 for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
3989 if (!FoundDecls[I]->isInIdentifierNamespace(Decl::IDNS_Ordinary))
Douglas Gregora082a492010-11-30 19:14:50 +00003990 continue;
3991
Douglas Gregor9e0a5b32011-10-15 00:10:27 +00003992 Decl *Found = FoundDecls[I];
Douglas Gregora082a492010-11-30 19:14:50 +00003993 if (ClassTemplateDecl *FoundTemplate
3994 = dyn_cast<ClassTemplateDecl>(Found)) {
3995 if (IsStructuralMatch(D, FoundTemplate)) {
3996 // The class templates structurally match; call it the same template.
3997 // FIXME: We may be filling in a forward declaration here. Handle
3998 // this case!
3999 Importer.Imported(D->getTemplatedDecl(),
4000 FoundTemplate->getTemplatedDecl());
4001 return Importer.Imported(D, FoundTemplate);
4002 }
4003 }
4004
Douglas Gregor9e0a5b32011-10-15 00:10:27 +00004005 ConflictingDecls.push_back(FoundDecls[I]);
Douglas Gregora082a492010-11-30 19:14:50 +00004006 }
4007
4008 if (!ConflictingDecls.empty()) {
4009 Name = Importer.HandleNameConflict(Name, DC, Decl::IDNS_Ordinary,
4010 ConflictingDecls.data(),
4011 ConflictingDecls.size());
4012 }
4013
4014 if (!Name)
4015 return 0;
4016 }
4017
4018 CXXRecordDecl *DTemplated = D->getTemplatedDecl();
4019
4020 // Create the declaration that is being templated.
Abramo Bagnara29c2d462011-03-09 14:09:51 +00004021 SourceLocation StartLoc = Importer.Import(DTemplated->getLocStart());
4022 SourceLocation IdLoc = Importer.Import(DTemplated->getLocation());
Douglas Gregora082a492010-11-30 19:14:50 +00004023 CXXRecordDecl *D2Templated = CXXRecordDecl::Create(Importer.getToContext(),
4024 DTemplated->getTagKind(),
Abramo Bagnara29c2d462011-03-09 14:09:51 +00004025 DC, StartLoc, IdLoc,
4026 Name.getAsIdentifierInfo());
Douglas Gregora082a492010-11-30 19:14:50 +00004027 D2Templated->setAccess(DTemplated->getAccess());
Douglas Gregor14454802011-02-25 02:25:35 +00004028 D2Templated->setQualifierInfo(Importer.Import(DTemplated->getQualifierLoc()));
Douglas Gregora082a492010-11-30 19:14:50 +00004029 D2Templated->setLexicalDeclContext(LexicalDC);
4030
4031 // Create the class template declaration itself.
4032 TemplateParameterList *TemplateParams
4033 = ImportTemplateParameterList(D->getTemplateParameters());
4034 if (!TemplateParams)
4035 return 0;
4036
4037 ClassTemplateDecl *D2 = ClassTemplateDecl::Create(Importer.getToContext(), DC,
4038 Loc, Name, TemplateParams,
4039 D2Templated,
4040 /*PrevDecl=*/0);
4041 D2Templated->setDescribedClassTemplate(D2);
4042
4043 D2->setAccess(D->getAccess());
4044 D2->setLexicalDeclContext(LexicalDC);
Sean Callanan95e74be2011-10-21 02:57:43 +00004045 LexicalDC->addDeclInternal(D2);
Douglas Gregora082a492010-11-30 19:14:50 +00004046
4047 // Note the relationship between the class templates.
4048 Importer.Imported(D, D2);
4049 Importer.Imported(DTemplated, D2Templated);
4050
John McCallf937c022011-10-07 06:10:15 +00004051 if (DTemplated->isCompleteDefinition() &&
4052 !D2Templated->isCompleteDefinition()) {
Douglas Gregora082a492010-11-30 19:14:50 +00004053 // FIXME: Import definition!
4054 }
4055
4056 return D2;
4057}
4058
Douglas Gregore2e50d332010-12-01 01:36:18 +00004059Decl *ASTNodeImporter::VisitClassTemplateSpecializationDecl(
4060 ClassTemplateSpecializationDecl *D) {
4061 // If this record has a definition in the translation unit we're coming from,
4062 // but this particular declaration is not that definition, import the
4063 // definition and map to that.
4064 TagDecl *Definition = D->getDefinition();
4065 if (Definition && Definition != D) {
4066 Decl *ImportedDef = Importer.Import(Definition);
4067 if (!ImportedDef)
4068 return 0;
4069
4070 return Importer.Imported(D, ImportedDef);
4071 }
4072
4073 ClassTemplateDecl *ClassTemplate
4074 = cast_or_null<ClassTemplateDecl>(Importer.Import(
4075 D->getSpecializedTemplate()));
4076 if (!ClassTemplate)
4077 return 0;
4078
4079 // Import the context of this declaration.
4080 DeclContext *DC = ClassTemplate->getDeclContext();
4081 if (!DC)
4082 return 0;
4083
4084 DeclContext *LexicalDC = DC;
4085 if (D->getDeclContext() != D->getLexicalDeclContext()) {
4086 LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
4087 if (!LexicalDC)
4088 return 0;
4089 }
4090
4091 // Import the location of this declaration.
Abramo Bagnara29c2d462011-03-09 14:09:51 +00004092 SourceLocation StartLoc = Importer.Import(D->getLocStart());
4093 SourceLocation IdLoc = Importer.Import(D->getLocation());
Douglas Gregore2e50d332010-12-01 01:36:18 +00004094
4095 // Import template arguments.
Chris Lattner0e62c1c2011-07-23 10:55:15 +00004096 SmallVector<TemplateArgument, 2> TemplateArgs;
Douglas Gregore2e50d332010-12-01 01:36:18 +00004097 if (ImportTemplateArguments(D->getTemplateArgs().data(),
4098 D->getTemplateArgs().size(),
4099 TemplateArgs))
4100 return 0;
4101
4102 // Try to find an existing specialization with these template arguments.
4103 void *InsertPos = 0;
4104 ClassTemplateSpecializationDecl *D2
4105 = ClassTemplate->findSpecialization(TemplateArgs.data(),
4106 TemplateArgs.size(), InsertPos);
4107 if (D2) {
4108 // We already have a class template specialization with these template
4109 // arguments.
4110
4111 // FIXME: Check for specialization vs. instantiation errors.
4112
4113 if (RecordDecl *FoundDef = D2->getDefinition()) {
John McCallf937c022011-10-07 06:10:15 +00004114 if (!D->isCompleteDefinition() || IsStructuralMatch(D, FoundDef)) {
Douglas Gregore2e50d332010-12-01 01:36:18 +00004115 // The record types structurally match, or the "from" translation
4116 // unit only had a forward declaration anyway; call it the same
4117 // function.
4118 return Importer.Imported(D, FoundDef);
4119 }
4120 }
4121 } else {
4122 // Create a new specialization.
4123 D2 = ClassTemplateSpecializationDecl::Create(Importer.getToContext(),
4124 D->getTagKind(), DC,
Abramo Bagnara29c2d462011-03-09 14:09:51 +00004125 StartLoc, IdLoc,
4126 ClassTemplate,
Douglas Gregore2e50d332010-12-01 01:36:18 +00004127 TemplateArgs.data(),
4128 TemplateArgs.size(),
4129 /*PrevDecl=*/0);
4130 D2->setSpecializationKind(D->getSpecializationKind());
4131
4132 // Add this specialization to the class template.
4133 ClassTemplate->AddSpecialization(D2, InsertPos);
4134
4135 // Import the qualifier, if any.
Douglas Gregor14454802011-02-25 02:25:35 +00004136 D2->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
Douglas Gregore2e50d332010-12-01 01:36:18 +00004137
4138 // Add the specialization to this context.
4139 D2->setLexicalDeclContext(LexicalDC);
Sean Callanan95e74be2011-10-21 02:57:43 +00004140 LexicalDC->addDeclInternal(D2);
Douglas Gregore2e50d332010-12-01 01:36:18 +00004141 }
4142 Importer.Imported(D, D2);
4143
John McCallf937c022011-10-07 06:10:15 +00004144 if (D->isCompleteDefinition() && ImportDefinition(D, D2))
Douglas Gregore2e50d332010-12-01 01:36:18 +00004145 return 0;
4146
4147 return D2;
4148}
4149
Larisse Voufo39a1e502013-08-06 01:03:05 +00004150Decl *ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) {
4151 // If this variable has a definition in the translation unit we're coming
4152 // from,
4153 // but this particular declaration is not that definition, import the
4154 // definition and map to that.
4155 VarDecl *Definition =
4156 cast_or_null<VarDecl>(D->getTemplatedDecl()->getDefinition());
4157 if (Definition && Definition != D->getTemplatedDecl()) {
4158 Decl *ImportedDef = Importer.Import(Definition->getDescribedVarTemplate());
4159 if (!ImportedDef)
4160 return 0;
4161
4162 return Importer.Imported(D, ImportedDef);
4163 }
4164
4165 // Import the major distinguishing characteristics of this variable template.
4166 DeclContext *DC, *LexicalDC;
4167 DeclarationName Name;
4168 SourceLocation Loc;
4169 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
4170 return 0;
4171
4172 // We may already have a template of the same name; try to find and match it.
4173 assert(!DC->isFunctionOrMethod() &&
4174 "Variable templates cannot be declared at function scope");
4175 SmallVector<NamedDecl *, 4> ConflictingDecls;
4176 SmallVector<NamedDecl *, 2> FoundDecls;
4177 DC->localUncachedLookup(Name, FoundDecls);
4178 for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
4179 if (!FoundDecls[I]->isInIdentifierNamespace(Decl::IDNS_Ordinary))
4180 continue;
4181
4182 Decl *Found = FoundDecls[I];
4183 if (VarTemplateDecl *FoundTemplate = dyn_cast<VarTemplateDecl>(Found)) {
4184 if (IsStructuralMatch(D, FoundTemplate)) {
4185 // The variable templates structurally match; call it the same template.
4186 Importer.Imported(D->getTemplatedDecl(),
4187 FoundTemplate->getTemplatedDecl());
4188 return Importer.Imported(D, FoundTemplate);
4189 }
4190 }
4191
4192 ConflictingDecls.push_back(FoundDecls[I]);
4193 }
4194
4195 if (!ConflictingDecls.empty()) {
4196 Name = Importer.HandleNameConflict(Name, DC, Decl::IDNS_Ordinary,
4197 ConflictingDecls.data(),
4198 ConflictingDecls.size());
4199 }
4200
4201 if (!Name)
4202 return 0;
4203
4204 VarDecl *DTemplated = D->getTemplatedDecl();
4205
4206 // Import the type.
4207 QualType T = Importer.Import(DTemplated->getType());
4208 if (T.isNull())
4209 return 0;
4210
4211 // Create the declaration that is being templated.
4212 SourceLocation StartLoc = Importer.Import(DTemplated->getLocStart());
4213 SourceLocation IdLoc = Importer.Import(DTemplated->getLocation());
4214 TypeSourceInfo *TInfo = Importer.Import(DTemplated->getTypeSourceInfo());
4215 VarDecl *D2Templated = VarDecl::Create(Importer.getToContext(), DC, StartLoc,
4216 IdLoc, Name.getAsIdentifierInfo(), T,
4217 TInfo, DTemplated->getStorageClass());
4218 D2Templated->setAccess(DTemplated->getAccess());
4219 D2Templated->setQualifierInfo(Importer.Import(DTemplated->getQualifierLoc()));
4220 D2Templated->setLexicalDeclContext(LexicalDC);
4221
4222 // Importer.Imported(DTemplated, D2Templated);
4223 // LexicalDC->addDeclInternal(D2Templated);
4224
4225 // Merge the initializer.
4226 if (ImportDefinition(DTemplated, D2Templated))
4227 return 0;
4228
4229 // Create the variable template declaration itself.
4230 TemplateParameterList *TemplateParams =
4231 ImportTemplateParameterList(D->getTemplateParameters());
4232 if (!TemplateParams)
4233 return 0;
4234
4235 VarTemplateDecl *D2 = VarTemplateDecl::Create(
4236 Importer.getToContext(), DC, Loc, Name, TemplateParams, D2Templated,
4237 /*PrevDecl=*/0);
4238 D2Templated->setDescribedVarTemplate(D2);
4239
4240 D2->setAccess(D->getAccess());
4241 D2->setLexicalDeclContext(LexicalDC);
4242 LexicalDC->addDeclInternal(D2);
4243
4244 // Note the relationship between the variable templates.
4245 Importer.Imported(D, D2);
4246 Importer.Imported(DTemplated, D2Templated);
4247
4248 if (DTemplated->isThisDeclarationADefinition() &&
4249 !D2Templated->isThisDeclarationADefinition()) {
4250 // FIXME: Import definition!
4251 }
4252
4253 return D2;
4254}
4255
4256Decl *ASTNodeImporter::VisitVarTemplateSpecializationDecl(
4257 VarTemplateSpecializationDecl *D) {
4258 // If this record has a definition in the translation unit we're coming from,
4259 // but this particular declaration is not that definition, import the
4260 // definition and map to that.
4261 VarDecl *Definition = D->getDefinition();
4262 if (Definition && Definition != D) {
4263 Decl *ImportedDef = Importer.Import(Definition);
4264 if (!ImportedDef)
4265 return 0;
4266
4267 return Importer.Imported(D, ImportedDef);
4268 }
4269
4270 VarTemplateDecl *VarTemplate = cast_or_null<VarTemplateDecl>(
4271 Importer.Import(D->getSpecializedTemplate()));
4272 if (!VarTemplate)
4273 return 0;
4274
4275 // Import the context of this declaration.
4276 DeclContext *DC = VarTemplate->getDeclContext();
4277 if (!DC)
4278 return 0;
4279
4280 DeclContext *LexicalDC = DC;
4281 if (D->getDeclContext() != D->getLexicalDeclContext()) {
4282 LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
4283 if (!LexicalDC)
4284 return 0;
4285 }
4286
4287 // Import the location of this declaration.
4288 SourceLocation StartLoc = Importer.Import(D->getLocStart());
4289 SourceLocation IdLoc = Importer.Import(D->getLocation());
4290
4291 // Import template arguments.
4292 SmallVector<TemplateArgument, 2> TemplateArgs;
4293 if (ImportTemplateArguments(D->getTemplateArgs().data(),
4294 D->getTemplateArgs().size(), TemplateArgs))
4295 return 0;
4296
4297 // Try to find an existing specialization with these template arguments.
4298 void *InsertPos = 0;
4299 VarTemplateSpecializationDecl *D2 = VarTemplate->findSpecialization(
4300 TemplateArgs.data(), TemplateArgs.size(), InsertPos);
4301 if (D2) {
4302 // We already have a variable template specialization with these template
4303 // arguments.
4304
4305 // FIXME: Check for specialization vs. instantiation errors.
4306
4307 if (VarDecl *FoundDef = D2->getDefinition()) {
4308 if (!D->isThisDeclarationADefinition() ||
4309 IsStructuralMatch(D, FoundDef)) {
4310 // The record types structurally match, or the "from" translation
4311 // unit only had a forward declaration anyway; call it the same
4312 // variable.
4313 return Importer.Imported(D, FoundDef);
4314 }
4315 }
4316 } else {
4317
4318 // Import the type.
4319 QualType T = Importer.Import(D->getType());
4320 if (T.isNull())
4321 return 0;
4322 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
4323
4324 // Create a new specialization.
4325 D2 = VarTemplateSpecializationDecl::Create(
4326 Importer.getToContext(), DC, StartLoc, IdLoc, VarTemplate, T, TInfo,
4327 D->getStorageClass(), TemplateArgs.data(), TemplateArgs.size());
4328 D2->setSpecializationKind(D->getSpecializationKind());
4329 D2->setTemplateArgsInfo(D->getTemplateArgsInfo());
4330
4331 // Add this specialization to the class template.
4332 VarTemplate->AddSpecialization(D2, InsertPos);
4333
4334 // Import the qualifier, if any.
4335 D2->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
4336
4337 // Add the specialization to this context.
4338 D2->setLexicalDeclContext(LexicalDC);
4339 LexicalDC->addDeclInternal(D2);
4340 }
4341 Importer.Imported(D, D2);
4342
4343 if (D->isThisDeclarationADefinition() && ImportDefinition(D, D2))
4344 return 0;
4345
4346 return D2;
4347}
4348
Douglas Gregor7eeb5972010-02-11 19:21:55 +00004349//----------------------------------------------------------------------------
4350// Import Statements
4351//----------------------------------------------------------------------------
4352
4353Stmt *ASTNodeImporter::VisitStmt(Stmt *S) {
4354 Importer.FromDiag(S->getLocStart(), diag::err_unsupported_ast_node)
4355 << S->getStmtClassName();
4356 return 0;
4357}
4358
4359//----------------------------------------------------------------------------
4360// Import Expressions
4361//----------------------------------------------------------------------------
4362Expr *ASTNodeImporter::VisitExpr(Expr *E) {
4363 Importer.FromDiag(E->getLocStart(), diag::err_unsupported_ast_node)
4364 << E->getStmtClassName();
4365 return 0;
4366}
4367
Douglas Gregor52f820e2010-02-19 01:17:02 +00004368Expr *ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) {
Douglas Gregor52f820e2010-02-19 01:17:02 +00004369 ValueDecl *ToD = cast_or_null<ValueDecl>(Importer.Import(E->getDecl()));
4370 if (!ToD)
4371 return 0;
Chandler Carruth8d26bb02011-05-01 23:48:14 +00004372
4373 NamedDecl *FoundD = 0;
4374 if (E->getDecl() != E->getFoundDecl()) {
4375 FoundD = cast_or_null<NamedDecl>(Importer.Import(E->getFoundDecl()));
4376 if (!FoundD)
4377 return 0;
4378 }
Douglas Gregor52f820e2010-02-19 01:17:02 +00004379
4380 QualType T = Importer.Import(E->getType());
4381 if (T.isNull())
4382 return 0;
Abramo Bagnara635ed24e2011-10-05 07:56:41 +00004383
4384 DeclRefExpr *DRE = DeclRefExpr::Create(Importer.getToContext(),
4385 Importer.Import(E->getQualifierLoc()),
Abramo Bagnara7945c982012-01-27 09:46:47 +00004386 Importer.Import(E->getTemplateKeywordLoc()),
Abramo Bagnara635ed24e2011-10-05 07:56:41 +00004387 ToD,
John McCall113bee02012-03-10 09:33:50 +00004388 E->refersToEnclosingLocal(),
Abramo Bagnara635ed24e2011-10-05 07:56:41 +00004389 Importer.Import(E->getLocation()),
4390 T, E->getValueKind(),
4391 FoundD,
4392 /*FIXME:TemplateArgs=*/0);
4393 if (E->hadMultipleCandidates())
4394 DRE->setHadMultipleCandidates(true);
4395 return DRE;
Douglas Gregor52f820e2010-02-19 01:17:02 +00004396}
4397
Douglas Gregor7eeb5972010-02-11 19:21:55 +00004398Expr *ASTNodeImporter::VisitIntegerLiteral(IntegerLiteral *E) {
4399 QualType T = Importer.Import(E->getType());
4400 if (T.isNull())
4401 return 0;
4402
Argyrios Kyrtzidis43b20572010-08-28 09:06:06 +00004403 return IntegerLiteral::Create(Importer.getToContext(),
4404 E->getValue(), T,
4405 Importer.Import(E->getLocation()));
Douglas Gregor7eeb5972010-02-11 19:21:55 +00004406}
4407
Douglas Gregor623421d2010-02-18 02:21:22 +00004408Expr *ASTNodeImporter::VisitCharacterLiteral(CharacterLiteral *E) {
4409 QualType T = Importer.Import(E->getType());
4410 if (T.isNull())
4411 return 0;
4412
Douglas Gregorfb65e592011-07-27 05:40:30 +00004413 return new (Importer.getToContext()) CharacterLiteral(E->getValue(),
4414 E->getKind(), T,
Douglas Gregor623421d2010-02-18 02:21:22 +00004415 Importer.Import(E->getLocation()));
4416}
4417
Douglas Gregorc74247e2010-02-19 01:07:06 +00004418Expr *ASTNodeImporter::VisitParenExpr(ParenExpr *E) {
4419 Expr *SubExpr = Importer.Import(E->getSubExpr());
4420 if (!SubExpr)
4421 return 0;
4422
4423 return new (Importer.getToContext())
4424 ParenExpr(Importer.Import(E->getLParen()),
4425 Importer.Import(E->getRParen()),
4426 SubExpr);
4427}
4428
4429Expr *ASTNodeImporter::VisitUnaryOperator(UnaryOperator *E) {
4430 QualType T = Importer.Import(E->getType());
4431 if (T.isNull())
4432 return 0;
4433
4434 Expr *SubExpr = Importer.Import(E->getSubExpr());
4435 if (!SubExpr)
4436 return 0;
4437
4438 return new (Importer.getToContext()) UnaryOperator(SubExpr, E->getOpcode(),
John McCall7decc9e2010-11-18 06:31:45 +00004439 T, E->getValueKind(),
4440 E->getObjectKind(),
Douglas Gregorc74247e2010-02-19 01:07:06 +00004441 Importer.Import(E->getOperatorLoc()));
4442}
4443
Peter Collingbournee190dee2011-03-11 19:24:49 +00004444Expr *ASTNodeImporter::VisitUnaryExprOrTypeTraitExpr(
4445 UnaryExprOrTypeTraitExpr *E) {
Douglas Gregord8552cd2010-02-19 01:24:23 +00004446 QualType ResultType = Importer.Import(E->getType());
4447
4448 if (E->isArgumentType()) {
4449 TypeSourceInfo *TInfo = Importer.Import(E->getArgumentTypeInfo());
4450 if (!TInfo)
4451 return 0;
4452
Peter Collingbournee190dee2011-03-11 19:24:49 +00004453 return new (Importer.getToContext()) UnaryExprOrTypeTraitExpr(E->getKind(),
4454 TInfo, ResultType,
Douglas Gregord8552cd2010-02-19 01:24:23 +00004455 Importer.Import(E->getOperatorLoc()),
4456 Importer.Import(E->getRParenLoc()));
4457 }
4458
4459 Expr *SubExpr = Importer.Import(E->getArgumentExpr());
4460 if (!SubExpr)
4461 return 0;
4462
Peter Collingbournee190dee2011-03-11 19:24:49 +00004463 return new (Importer.getToContext()) UnaryExprOrTypeTraitExpr(E->getKind(),
4464 SubExpr, ResultType,
Douglas Gregord8552cd2010-02-19 01:24:23 +00004465 Importer.Import(E->getOperatorLoc()),
4466 Importer.Import(E->getRParenLoc()));
4467}
4468
Douglas Gregorc74247e2010-02-19 01:07:06 +00004469Expr *ASTNodeImporter::VisitBinaryOperator(BinaryOperator *E) {
4470 QualType T = Importer.Import(E->getType());
4471 if (T.isNull())
4472 return 0;
4473
4474 Expr *LHS = Importer.Import(E->getLHS());
4475 if (!LHS)
4476 return 0;
4477
4478 Expr *RHS = Importer.Import(E->getRHS());
4479 if (!RHS)
4480 return 0;
4481
4482 return new (Importer.getToContext()) BinaryOperator(LHS, RHS, E->getOpcode(),
John McCall7decc9e2010-11-18 06:31:45 +00004483 T, E->getValueKind(),
4484 E->getObjectKind(),
Lang Hames5de91cc2012-10-02 04:45:10 +00004485 Importer.Import(E->getOperatorLoc()),
4486 E->isFPContractable());
Douglas Gregorc74247e2010-02-19 01:07:06 +00004487}
4488
4489Expr *ASTNodeImporter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
4490 QualType T = Importer.Import(E->getType());
4491 if (T.isNull())
4492 return 0;
4493
4494 QualType CompLHSType = Importer.Import(E->getComputationLHSType());
4495 if (CompLHSType.isNull())
4496 return 0;
4497
4498 QualType CompResultType = Importer.Import(E->getComputationResultType());
4499 if (CompResultType.isNull())
4500 return 0;
4501
4502 Expr *LHS = Importer.Import(E->getLHS());
4503 if (!LHS)
4504 return 0;
4505
4506 Expr *RHS = Importer.Import(E->getRHS());
4507 if (!RHS)
4508 return 0;
4509
4510 return new (Importer.getToContext())
4511 CompoundAssignOperator(LHS, RHS, E->getOpcode(),
John McCall7decc9e2010-11-18 06:31:45 +00004512 T, E->getValueKind(),
4513 E->getObjectKind(),
4514 CompLHSType, CompResultType,
Lang Hames5de91cc2012-10-02 04:45:10 +00004515 Importer.Import(E->getOperatorLoc()),
4516 E->isFPContractable());
Douglas Gregorc74247e2010-02-19 01:07:06 +00004517}
4518
Benjamin Kramer8aef5962011-03-26 12:38:21 +00004519static bool ImportCastPath(CastExpr *E, CXXCastPath &Path) {
John McCallcf142162010-08-07 06:22:56 +00004520 if (E->path_empty()) return false;
4521
4522 // TODO: import cast paths
4523 return true;
4524}
4525
Douglas Gregor98c10182010-02-12 22:17:39 +00004526Expr *ASTNodeImporter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
4527 QualType T = Importer.Import(E->getType());
4528 if (T.isNull())
4529 return 0;
4530
4531 Expr *SubExpr = Importer.Import(E->getSubExpr());
4532 if (!SubExpr)
4533 return 0;
John McCallcf142162010-08-07 06:22:56 +00004534
4535 CXXCastPath BasePath;
4536 if (ImportCastPath(E, BasePath))
4537 return 0;
4538
4539 return ImplicitCastExpr::Create(Importer.getToContext(), T, E->getCastKind(),
John McCall2536c6d2010-08-25 10:28:54 +00004540 SubExpr, &BasePath, E->getValueKind());
Douglas Gregor98c10182010-02-12 22:17:39 +00004541}
4542
Douglas Gregor5481d322010-02-19 01:32:14 +00004543Expr *ASTNodeImporter::VisitCStyleCastExpr(CStyleCastExpr *E) {
4544 QualType T = Importer.Import(E->getType());
4545 if (T.isNull())
4546 return 0;
4547
4548 Expr *SubExpr = Importer.Import(E->getSubExpr());
4549 if (!SubExpr)
4550 return 0;
4551
4552 TypeSourceInfo *TInfo = Importer.Import(E->getTypeInfoAsWritten());
4553 if (!TInfo && E->getTypeInfoAsWritten())
4554 return 0;
4555
John McCallcf142162010-08-07 06:22:56 +00004556 CXXCastPath BasePath;
4557 if (ImportCastPath(E, BasePath))
4558 return 0;
4559
John McCall7decc9e2010-11-18 06:31:45 +00004560 return CStyleCastExpr::Create(Importer.getToContext(), T,
4561 E->getValueKind(), E->getCastKind(),
John McCallcf142162010-08-07 06:22:56 +00004562 SubExpr, &BasePath, TInfo,
4563 Importer.Import(E->getLParenLoc()),
4564 Importer.Import(E->getRParenLoc()));
Douglas Gregor5481d322010-02-19 01:32:14 +00004565}
4566
Argyrios Kyrtzidisd0040642010-11-18 20:06:41 +00004567ASTImporter::ASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
Douglas Gregor0a791672011-01-18 03:11:38 +00004568 ASTContext &FromContext, FileManager &FromFileManager,
4569 bool MinimalImport)
Douglas Gregor96e578d2010-02-05 17:54:41 +00004570 : ToContext(ToContext), FromContext(FromContext),
Douglas Gregor0a791672011-01-18 03:11:38 +00004571 ToFileManager(ToFileManager), FromFileManager(FromFileManager),
Richard Smith5bb4cdf2012-12-20 02:22:15 +00004572 Minimal(MinimalImport), LastDiagFromFrom(false)
Douglas Gregor0a791672011-01-18 03:11:38 +00004573{
Douglas Gregor62d311f2010-02-09 19:21:46 +00004574 ImportedDecls[FromContext.getTranslationUnitDecl()]
4575 = ToContext.getTranslationUnitDecl();
4576}
4577
4578ASTImporter::~ASTImporter() { }
Douglas Gregor96e578d2010-02-05 17:54:41 +00004579
4580QualType ASTImporter::Import(QualType FromT) {
4581 if (FromT.isNull())
4582 return QualType();
John McCall424cec92011-01-19 06:33:43 +00004583
4584 const Type *fromTy = FromT.getTypePtr();
Douglas Gregor96e578d2010-02-05 17:54:41 +00004585
Douglas Gregorf65bbb32010-02-08 15:18:58 +00004586 // Check whether we've already imported this type.
John McCall424cec92011-01-19 06:33:43 +00004587 llvm::DenseMap<const Type *, const Type *>::iterator Pos
4588 = ImportedTypes.find(fromTy);
Douglas Gregorf65bbb32010-02-08 15:18:58 +00004589 if (Pos != ImportedTypes.end())
John McCall424cec92011-01-19 06:33:43 +00004590 return ToContext.getQualifiedType(Pos->second, FromT.getLocalQualifiers());
Douglas Gregor96e578d2010-02-05 17:54:41 +00004591
Douglas Gregorf65bbb32010-02-08 15:18:58 +00004592 // Import the type
Douglas Gregor96e578d2010-02-05 17:54:41 +00004593 ASTNodeImporter Importer(*this);
John McCall424cec92011-01-19 06:33:43 +00004594 QualType ToT = Importer.Visit(fromTy);
Douglas Gregor96e578d2010-02-05 17:54:41 +00004595 if (ToT.isNull())
4596 return ToT;
4597
Douglas Gregorf65bbb32010-02-08 15:18:58 +00004598 // Record the imported type.
John McCall424cec92011-01-19 06:33:43 +00004599 ImportedTypes[fromTy] = ToT.getTypePtr();
Douglas Gregorf65bbb32010-02-08 15:18:58 +00004600
John McCall424cec92011-01-19 06:33:43 +00004601 return ToContext.getQualifiedType(ToT, FromT.getLocalQualifiers());
Douglas Gregor96e578d2010-02-05 17:54:41 +00004602}
4603
Douglas Gregor62d311f2010-02-09 19:21:46 +00004604TypeSourceInfo *ASTImporter::Import(TypeSourceInfo *FromTSI) {
Douglas Gregorfa7a0e52010-02-10 17:47:19 +00004605 if (!FromTSI)
4606 return FromTSI;
4607
4608 // FIXME: For now we just create a "trivial" type source info based
Nick Lewycky19b9f952010-07-26 16:56:01 +00004609 // on the type and a single location. Implement a real version of this.
Douglas Gregorfa7a0e52010-02-10 17:47:19 +00004610 QualType T = Import(FromTSI->getType());
4611 if (T.isNull())
4612 return 0;
4613
4614 return ToContext.getTrivialTypeSourceInfo(T,
Daniel Dunbar62ee6412012-03-09 18:35:03 +00004615 FromTSI->getTypeLoc().getLocStart());
Douglas Gregor62d311f2010-02-09 19:21:46 +00004616}
4617
4618Decl *ASTImporter::Import(Decl *FromD) {
4619 if (!FromD)
4620 return 0;
4621
Douglas Gregord451ea92011-07-29 23:31:30 +00004622 ASTNodeImporter Importer(*this);
4623
Douglas Gregor62d311f2010-02-09 19:21:46 +00004624 // Check whether we've already imported this declaration.
4625 llvm::DenseMap<Decl *, Decl *>::iterator Pos = ImportedDecls.find(FromD);
Douglas Gregord451ea92011-07-29 23:31:30 +00004626 if (Pos != ImportedDecls.end()) {
4627 Decl *ToD = Pos->second;
4628 Importer.ImportDefinitionIfNeeded(FromD, ToD);
4629 return ToD;
4630 }
Douglas Gregor62d311f2010-02-09 19:21:46 +00004631
4632 // Import the type
Douglas Gregor62d311f2010-02-09 19:21:46 +00004633 Decl *ToD = Importer.Visit(FromD);
4634 if (!ToD)
4635 return 0;
4636
4637 // Record the imported declaration.
4638 ImportedDecls[FromD] = ToD;
Douglas Gregorb4964f72010-02-15 23:54:17 +00004639
4640 if (TagDecl *FromTag = dyn_cast<TagDecl>(FromD)) {
4641 // Keep track of anonymous tags that have an associated typedef.
Richard Smithdda56e42011-04-15 14:24:37 +00004642 if (FromTag->getTypedefNameForAnonDecl())
Douglas Gregorb4964f72010-02-15 23:54:17 +00004643 AnonTagsWithPendingTypedefs.push_back(FromTag);
Richard Smithdda56e42011-04-15 14:24:37 +00004644 } else if (TypedefNameDecl *FromTypedef = dyn_cast<TypedefNameDecl>(FromD)) {
Douglas Gregorb4964f72010-02-15 23:54:17 +00004645 // When we've finished transforming a typedef, see whether it was the
4646 // typedef for an anonymous tag.
Craig Topper2341c0d2013-07-04 03:08:24 +00004647 for (SmallVectorImpl<TagDecl *>::iterator
Douglas Gregorb4964f72010-02-15 23:54:17 +00004648 FromTag = AnonTagsWithPendingTypedefs.begin(),
4649 FromTagEnd = AnonTagsWithPendingTypedefs.end();
4650 FromTag != FromTagEnd; ++FromTag) {
Richard Smithdda56e42011-04-15 14:24:37 +00004651 if ((*FromTag)->getTypedefNameForAnonDecl() == FromTypedef) {
Douglas Gregorb4964f72010-02-15 23:54:17 +00004652 if (TagDecl *ToTag = cast_or_null<TagDecl>(Import(*FromTag))) {
4653 // We found the typedef for an anonymous tag; link them.
Richard Smithdda56e42011-04-15 14:24:37 +00004654 ToTag->setTypedefNameForAnonDecl(cast<TypedefNameDecl>(ToD));
Douglas Gregorb4964f72010-02-15 23:54:17 +00004655 AnonTagsWithPendingTypedefs.erase(FromTag);
4656 break;
4657 }
4658 }
4659 }
4660 }
4661
Douglas Gregor62d311f2010-02-09 19:21:46 +00004662 return ToD;
4663}
4664
4665DeclContext *ASTImporter::ImportContext(DeclContext *FromDC) {
4666 if (!FromDC)
4667 return FromDC;
4668
Douglas Gregor95d82832012-01-24 18:36:04 +00004669 DeclContext *ToDC = cast_or_null<DeclContext>(Import(cast<Decl>(FromDC)));
Douglas Gregor2e15c842012-02-01 21:00:38 +00004670 if (!ToDC)
4671 return 0;
4672
4673 // When we're using a record/enum/Objective-C class/protocol as a context, we
4674 // need it to have a definition.
4675 if (RecordDecl *ToRecord = dyn_cast<RecordDecl>(ToDC)) {
Douglas Gregor63db9712012-01-25 01:13:20 +00004676 RecordDecl *FromRecord = cast<RecordDecl>(FromDC);
Douglas Gregor2e15c842012-02-01 21:00:38 +00004677 if (ToRecord->isCompleteDefinition()) {
4678 // Do nothing.
4679 } else if (FromRecord->isCompleteDefinition()) {
4680 ASTNodeImporter(*this).ImportDefinition(FromRecord, ToRecord,
4681 ASTNodeImporter::IDK_Basic);
4682 } else {
4683 CompleteDecl(ToRecord);
4684 }
4685 } else if (EnumDecl *ToEnum = dyn_cast<EnumDecl>(ToDC)) {
4686 EnumDecl *FromEnum = cast<EnumDecl>(FromDC);
4687 if (ToEnum->isCompleteDefinition()) {
4688 // Do nothing.
4689 } else if (FromEnum->isCompleteDefinition()) {
4690 ASTNodeImporter(*this).ImportDefinition(FromEnum, ToEnum,
4691 ASTNodeImporter::IDK_Basic);
4692 } else {
4693 CompleteDecl(ToEnum);
4694 }
4695 } else if (ObjCInterfaceDecl *ToClass = dyn_cast<ObjCInterfaceDecl>(ToDC)) {
4696 ObjCInterfaceDecl *FromClass = cast<ObjCInterfaceDecl>(FromDC);
4697 if (ToClass->getDefinition()) {
4698 // Do nothing.
4699 } else if (ObjCInterfaceDecl *FromDef = FromClass->getDefinition()) {
4700 ASTNodeImporter(*this).ImportDefinition(FromDef, ToClass,
4701 ASTNodeImporter::IDK_Basic);
4702 } else {
4703 CompleteDecl(ToClass);
4704 }
4705 } else if (ObjCProtocolDecl *ToProto = dyn_cast<ObjCProtocolDecl>(ToDC)) {
4706 ObjCProtocolDecl *FromProto = cast<ObjCProtocolDecl>(FromDC);
4707 if (ToProto->getDefinition()) {
4708 // Do nothing.
4709 } else if (ObjCProtocolDecl *FromDef = FromProto->getDefinition()) {
4710 ASTNodeImporter(*this).ImportDefinition(FromDef, ToProto,
4711 ASTNodeImporter::IDK_Basic);
4712 } else {
4713 CompleteDecl(ToProto);
4714 }
Douglas Gregor95d82832012-01-24 18:36:04 +00004715 }
4716
4717 return ToDC;
Douglas Gregor62d311f2010-02-09 19:21:46 +00004718}
4719
4720Expr *ASTImporter::Import(Expr *FromE) {
4721 if (!FromE)
4722 return 0;
4723
4724 return cast_or_null<Expr>(Import(cast<Stmt>(FromE)));
4725}
4726
4727Stmt *ASTImporter::Import(Stmt *FromS) {
4728 if (!FromS)
4729 return 0;
4730
Douglas Gregor7eeb5972010-02-11 19:21:55 +00004731 // Check whether we've already imported this declaration.
4732 llvm::DenseMap<Stmt *, Stmt *>::iterator Pos = ImportedStmts.find(FromS);
4733 if (Pos != ImportedStmts.end())
4734 return Pos->second;
4735
4736 // Import the type
4737 ASTNodeImporter Importer(*this);
4738 Stmt *ToS = Importer.Visit(FromS);
4739 if (!ToS)
4740 return 0;
4741
4742 // Record the imported declaration.
4743 ImportedStmts[FromS] = ToS;
4744 return ToS;
Douglas Gregor62d311f2010-02-09 19:21:46 +00004745}
4746
4747NestedNameSpecifier *ASTImporter::Import(NestedNameSpecifier *FromNNS) {
4748 if (!FromNNS)
4749 return 0;
4750
Douglas Gregor90ebf252011-04-27 16:48:40 +00004751 NestedNameSpecifier *prefix = Import(FromNNS->getPrefix());
4752
4753 switch (FromNNS->getKind()) {
4754 case NestedNameSpecifier::Identifier:
4755 if (IdentifierInfo *II = Import(FromNNS->getAsIdentifier())) {
4756 return NestedNameSpecifier::Create(ToContext, prefix, II);
4757 }
4758 return 0;
4759
4760 case NestedNameSpecifier::Namespace:
4761 if (NamespaceDecl *NS =
4762 cast<NamespaceDecl>(Import(FromNNS->getAsNamespace()))) {
4763 return NestedNameSpecifier::Create(ToContext, prefix, NS);
4764 }
4765 return 0;
4766
4767 case NestedNameSpecifier::NamespaceAlias:
4768 if (NamespaceAliasDecl *NSAD =
4769 cast<NamespaceAliasDecl>(Import(FromNNS->getAsNamespaceAlias()))) {
4770 return NestedNameSpecifier::Create(ToContext, prefix, NSAD);
4771 }
4772 return 0;
4773
4774 case NestedNameSpecifier::Global:
4775 return NestedNameSpecifier::GlobalSpecifier(ToContext);
4776
4777 case NestedNameSpecifier::TypeSpec:
4778 case NestedNameSpecifier::TypeSpecWithTemplate: {
4779 QualType T = Import(QualType(FromNNS->getAsType(), 0u));
4780 if (!T.isNull()) {
4781 bool bTemplate = FromNNS->getKind() ==
4782 NestedNameSpecifier::TypeSpecWithTemplate;
4783 return NestedNameSpecifier::Create(ToContext, prefix,
4784 bTemplate, T.getTypePtr());
4785 }
4786 }
4787 return 0;
4788 }
4789
4790 llvm_unreachable("Invalid nested name specifier kind");
Douglas Gregor62d311f2010-02-09 19:21:46 +00004791}
4792
Douglas Gregor14454802011-02-25 02:25:35 +00004793NestedNameSpecifierLoc ASTImporter::Import(NestedNameSpecifierLoc FromNNS) {
4794 // FIXME: Implement!
4795 return NestedNameSpecifierLoc();
4796}
4797
Douglas Gregore2e50d332010-12-01 01:36:18 +00004798TemplateName ASTImporter::Import(TemplateName From) {
4799 switch (From.getKind()) {
4800 case TemplateName::Template:
4801 if (TemplateDecl *ToTemplate
4802 = cast_or_null<TemplateDecl>(Import(From.getAsTemplateDecl())))
4803 return TemplateName(ToTemplate);
4804
4805 return TemplateName();
4806
4807 case TemplateName::OverloadedTemplate: {
4808 OverloadedTemplateStorage *FromStorage = From.getAsOverloadedTemplate();
4809 UnresolvedSet<2> ToTemplates;
4810 for (OverloadedTemplateStorage::iterator I = FromStorage->begin(),
4811 E = FromStorage->end();
4812 I != E; ++I) {
4813 if (NamedDecl *To = cast_or_null<NamedDecl>(Import(*I)))
4814 ToTemplates.addDecl(To);
4815 else
4816 return TemplateName();
4817 }
4818 return ToContext.getOverloadedTemplateName(ToTemplates.begin(),
4819 ToTemplates.end());
4820 }
4821
4822 case TemplateName::QualifiedTemplate: {
4823 QualifiedTemplateName *QTN = From.getAsQualifiedTemplateName();
4824 NestedNameSpecifier *Qualifier = Import(QTN->getQualifier());
4825 if (!Qualifier)
4826 return TemplateName();
4827
4828 if (TemplateDecl *ToTemplate
4829 = cast_or_null<TemplateDecl>(Import(From.getAsTemplateDecl())))
4830 return ToContext.getQualifiedTemplateName(Qualifier,
4831 QTN->hasTemplateKeyword(),
4832 ToTemplate);
4833
4834 return TemplateName();
4835 }
4836
4837 case TemplateName::DependentTemplate: {
4838 DependentTemplateName *DTN = From.getAsDependentTemplateName();
4839 NestedNameSpecifier *Qualifier = Import(DTN->getQualifier());
4840 if (!Qualifier)
4841 return TemplateName();
4842
4843 if (DTN->isIdentifier()) {
4844 return ToContext.getDependentTemplateName(Qualifier,
4845 Import(DTN->getIdentifier()));
4846 }
4847
4848 return ToContext.getDependentTemplateName(Qualifier, DTN->getOperator());
4849 }
John McCalld9dfe3a2011-06-30 08:33:18 +00004850
4851 case TemplateName::SubstTemplateTemplateParm: {
4852 SubstTemplateTemplateParmStorage *subst
4853 = From.getAsSubstTemplateTemplateParm();
4854 TemplateTemplateParmDecl *param
4855 = cast_or_null<TemplateTemplateParmDecl>(Import(subst->getParameter()));
4856 if (!param)
4857 return TemplateName();
4858
4859 TemplateName replacement = Import(subst->getReplacement());
4860 if (replacement.isNull()) return TemplateName();
4861
4862 return ToContext.getSubstTemplateTemplateParm(param, replacement);
4863 }
Douglas Gregor5590be02011-01-15 06:45:20 +00004864
4865 case TemplateName::SubstTemplateTemplateParmPack: {
4866 SubstTemplateTemplateParmPackStorage *SubstPack
4867 = From.getAsSubstTemplateTemplateParmPack();
4868 TemplateTemplateParmDecl *Param
4869 = cast_or_null<TemplateTemplateParmDecl>(
4870 Import(SubstPack->getParameterPack()));
4871 if (!Param)
4872 return TemplateName();
4873
4874 ASTNodeImporter Importer(*this);
4875 TemplateArgument ArgPack
4876 = Importer.ImportTemplateArgument(SubstPack->getArgumentPack());
4877 if (ArgPack.isNull())
4878 return TemplateName();
4879
4880 return ToContext.getSubstTemplateTemplateParmPack(Param, ArgPack);
4881 }
Douglas Gregore2e50d332010-12-01 01:36:18 +00004882 }
4883
4884 llvm_unreachable("Invalid template name kind");
Douglas Gregore2e50d332010-12-01 01:36:18 +00004885}
4886
Douglas Gregor62d311f2010-02-09 19:21:46 +00004887SourceLocation ASTImporter::Import(SourceLocation FromLoc) {
4888 if (FromLoc.isInvalid())
4889 return SourceLocation();
4890
Douglas Gregor811663e2010-02-10 00:15:17 +00004891 SourceManager &FromSM = FromContext.getSourceManager();
4892
4893 // For now, map everything down to its spelling location, so that we
Chandler Carruth25366412011-07-15 00:04:35 +00004894 // don't have to import macro expansions.
4895 // FIXME: Import macro expansions!
Douglas Gregor811663e2010-02-10 00:15:17 +00004896 FromLoc = FromSM.getSpellingLoc(FromLoc);
4897 std::pair<FileID, unsigned> Decomposed = FromSM.getDecomposedLoc(FromLoc);
4898 SourceManager &ToSM = ToContext.getSourceManager();
4899 return ToSM.getLocForStartOfFile(Import(Decomposed.first))
Argyrios Kyrtzidise6e67de2011-09-19 20:40:19 +00004900 .getLocWithOffset(Decomposed.second);
Douglas Gregor62d311f2010-02-09 19:21:46 +00004901}
4902
4903SourceRange ASTImporter::Import(SourceRange FromRange) {
4904 return SourceRange(Import(FromRange.getBegin()), Import(FromRange.getEnd()));
4905}
4906
Douglas Gregor811663e2010-02-10 00:15:17 +00004907FileID ASTImporter::Import(FileID FromID) {
Sebastian Redl99219f12010-09-30 01:03:06 +00004908 llvm::DenseMap<FileID, FileID>::iterator Pos
4909 = ImportedFileIDs.find(FromID);
Douglas Gregor811663e2010-02-10 00:15:17 +00004910 if (Pos != ImportedFileIDs.end())
4911 return Pos->second;
4912
4913 SourceManager &FromSM = FromContext.getSourceManager();
4914 SourceManager &ToSM = ToContext.getSourceManager();
4915 const SrcMgr::SLocEntry &FromSLoc = FromSM.getSLocEntry(FromID);
Chandler Carruth25366412011-07-15 00:04:35 +00004916 assert(FromSLoc.isFile() && "Cannot handle macro expansions yet");
Douglas Gregor811663e2010-02-10 00:15:17 +00004917
4918 // Include location of this file.
4919 SourceLocation ToIncludeLoc = Import(FromSLoc.getFile().getIncludeLoc());
4920
4921 // Map the FileID for to the "to" source manager.
4922 FileID ToID;
4923 const SrcMgr::ContentCache *Cache = FromSLoc.getFile().getContentCache();
Argyrios Kyrtzidis11e6f0a2011-03-05 01:03:53 +00004924 if (Cache->OrigEntry) {
Douglas Gregor811663e2010-02-10 00:15:17 +00004925 // FIXME: We probably want to use getVirtualFile(), so we don't hit the
4926 // disk again
4927 // FIXME: We definitely want to re-use the existing MemoryBuffer, rather
4928 // than mmap the files several times.
Argyrios Kyrtzidis11e6f0a2011-03-05 01:03:53 +00004929 const FileEntry *Entry = ToFileManager.getFile(Cache->OrigEntry->getName());
Douglas Gregor811663e2010-02-10 00:15:17 +00004930 ToID = ToSM.createFileID(Entry, ToIncludeLoc,
4931 FromSLoc.getFile().getFileCharacteristic());
4932 } else {
4933 // FIXME: We want to re-use the existing MemoryBuffer!
Argyrios Kyrtzidisd0040642010-11-18 20:06:41 +00004934 const llvm::MemoryBuffer *
4935 FromBuf = Cache->getBuffer(FromContext.getDiagnostics(), FromSM);
Douglas Gregor811663e2010-02-10 00:15:17 +00004936 llvm::MemoryBuffer *ToBuf
Chris Lattner58c79342010-04-05 22:42:27 +00004937 = llvm::MemoryBuffer::getMemBufferCopy(FromBuf->getBuffer(),
Douglas Gregor811663e2010-02-10 00:15:17 +00004938 FromBuf->getBufferIdentifier());
Argyrios Kyrtzidis6566e232012-11-09 19:40:45 +00004939 ToID = ToSM.createFileIDForMemBuffer(ToBuf,
4940 FromSLoc.getFile().getFileCharacteristic());
Douglas Gregor811663e2010-02-10 00:15:17 +00004941 }
4942
4943
Sebastian Redl99219f12010-09-30 01:03:06 +00004944 ImportedFileIDs[FromID] = ToID;
Douglas Gregor811663e2010-02-10 00:15:17 +00004945 return ToID;
4946}
4947
Douglas Gregor0a791672011-01-18 03:11:38 +00004948void ASTImporter::ImportDefinition(Decl *From) {
4949 Decl *To = Import(From);
4950 if (!To)
4951 return;
4952
4953 if (DeclContext *FromDC = cast<DeclContext>(From)) {
4954 ASTNodeImporter Importer(*this);
Sean Callanan53a6bff2011-07-19 22:38:25 +00004955
4956 if (RecordDecl *ToRecord = dyn_cast<RecordDecl>(To)) {
4957 if (!ToRecord->getDefinition()) {
4958 Importer.ImportDefinition(cast<RecordDecl>(FromDC), ToRecord,
Douglas Gregor95d82832012-01-24 18:36:04 +00004959 ASTNodeImporter::IDK_Everything);
Sean Callanan53a6bff2011-07-19 22:38:25 +00004960 return;
4961 }
4962 }
Douglas Gregord451ea92011-07-29 23:31:30 +00004963
4964 if (EnumDecl *ToEnum = dyn_cast<EnumDecl>(To)) {
4965 if (!ToEnum->getDefinition()) {
4966 Importer.ImportDefinition(cast<EnumDecl>(FromDC), ToEnum,
Douglas Gregor2e15c842012-02-01 21:00:38 +00004967 ASTNodeImporter::IDK_Everything);
Douglas Gregord451ea92011-07-29 23:31:30 +00004968 return;
4969 }
4970 }
Douglas Gregor2aa53772012-01-24 17:42:07 +00004971
4972 if (ObjCInterfaceDecl *ToIFace = dyn_cast<ObjCInterfaceDecl>(To)) {
4973 if (!ToIFace->getDefinition()) {
4974 Importer.ImportDefinition(cast<ObjCInterfaceDecl>(FromDC), ToIFace,
Douglas Gregor2e15c842012-02-01 21:00:38 +00004975 ASTNodeImporter::IDK_Everything);
Douglas Gregor2aa53772012-01-24 17:42:07 +00004976 return;
4977 }
4978 }
Douglas Gregord451ea92011-07-29 23:31:30 +00004979
Douglas Gregor2aa53772012-01-24 17:42:07 +00004980 if (ObjCProtocolDecl *ToProto = dyn_cast<ObjCProtocolDecl>(To)) {
4981 if (!ToProto->getDefinition()) {
4982 Importer.ImportDefinition(cast<ObjCProtocolDecl>(FromDC), ToProto,
Douglas Gregor2e15c842012-02-01 21:00:38 +00004983 ASTNodeImporter::IDK_Everything);
Douglas Gregor2aa53772012-01-24 17:42:07 +00004984 return;
4985 }
4986 }
4987
Douglas Gregor0a791672011-01-18 03:11:38 +00004988 Importer.ImportDeclContext(FromDC, true);
4989 }
4990}
4991
Douglas Gregor96e578d2010-02-05 17:54:41 +00004992DeclarationName ASTImporter::Import(DeclarationName FromName) {
4993 if (!FromName)
4994 return DeclarationName();
4995
4996 switch (FromName.getNameKind()) {
4997 case DeclarationName::Identifier:
4998 return Import(FromName.getAsIdentifierInfo());
4999
5000 case DeclarationName::ObjCZeroArgSelector:
5001 case DeclarationName::ObjCOneArgSelector:
5002 case DeclarationName::ObjCMultiArgSelector:
5003 return Import(FromName.getObjCSelector());
5004
5005 case DeclarationName::CXXConstructorName: {
5006 QualType T = Import(FromName.getCXXNameType());
5007 if (T.isNull())
5008 return DeclarationName();
5009
5010 return ToContext.DeclarationNames.getCXXConstructorName(
5011 ToContext.getCanonicalType(T));
5012 }
5013
5014 case DeclarationName::CXXDestructorName: {
5015 QualType T = Import(FromName.getCXXNameType());
5016 if (T.isNull())
5017 return DeclarationName();
5018
5019 return ToContext.DeclarationNames.getCXXDestructorName(
5020 ToContext.getCanonicalType(T));
5021 }
5022
5023 case DeclarationName::CXXConversionFunctionName: {
5024 QualType T = Import(FromName.getCXXNameType());
5025 if (T.isNull())
5026 return DeclarationName();
5027
5028 return ToContext.DeclarationNames.getCXXConversionFunctionName(
5029 ToContext.getCanonicalType(T));
5030 }
5031
5032 case DeclarationName::CXXOperatorName:
5033 return ToContext.DeclarationNames.getCXXOperatorName(
5034 FromName.getCXXOverloadedOperator());
5035
5036 case DeclarationName::CXXLiteralOperatorName:
5037 return ToContext.DeclarationNames.getCXXLiteralOperatorName(
5038 Import(FromName.getCXXLiteralIdentifier()));
5039
5040 case DeclarationName::CXXUsingDirective:
5041 // FIXME: STATICS!
5042 return DeclarationName::getUsingDirectiveName();
5043 }
5044
David Blaikiee4d798f2012-01-20 21:50:17 +00005045 llvm_unreachable("Invalid DeclarationName Kind!");
Douglas Gregor96e578d2010-02-05 17:54:41 +00005046}
5047
Douglas Gregore2e50d332010-12-01 01:36:18 +00005048IdentifierInfo *ASTImporter::Import(const IdentifierInfo *FromId) {
Douglas Gregor96e578d2010-02-05 17:54:41 +00005049 if (!FromId)
5050 return 0;
5051
5052 return &ToContext.Idents.get(FromId->getName());
5053}
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00005054
Douglas Gregor43f54792010-02-17 02:12:47 +00005055Selector ASTImporter::Import(Selector FromSel) {
5056 if (FromSel.isNull())
5057 return Selector();
5058
Chris Lattner0e62c1c2011-07-23 10:55:15 +00005059 SmallVector<IdentifierInfo *, 4> Idents;
Douglas Gregor43f54792010-02-17 02:12:47 +00005060 Idents.push_back(Import(FromSel.getIdentifierInfoForSlot(0)));
5061 for (unsigned I = 1, N = FromSel.getNumArgs(); I < N; ++I)
5062 Idents.push_back(Import(FromSel.getIdentifierInfoForSlot(I)));
5063 return ToContext.Selectors.getSelector(FromSel.getNumArgs(), Idents.data());
5064}
5065
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00005066DeclarationName ASTImporter::HandleNameConflict(DeclarationName Name,
5067 DeclContext *DC,
5068 unsigned IDNS,
5069 NamedDecl **Decls,
5070 unsigned NumDecls) {
5071 return Name;
5072}
5073
5074DiagnosticBuilder ASTImporter::ToDiag(SourceLocation Loc, unsigned DiagID) {
Richard Smith5bb4cdf2012-12-20 02:22:15 +00005075 if (LastDiagFromFrom)
5076 ToContext.getDiagnostics().notePriorDiagnosticFrom(
5077 FromContext.getDiagnostics());
5078 LastDiagFromFrom = false;
Argyrios Kyrtzidisd0040642010-11-18 20:06:41 +00005079 return ToContext.getDiagnostics().Report(Loc, DiagID);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00005080}
5081
5082DiagnosticBuilder ASTImporter::FromDiag(SourceLocation Loc, unsigned DiagID) {
Richard Smith5bb4cdf2012-12-20 02:22:15 +00005083 if (!LastDiagFromFrom)
5084 FromContext.getDiagnostics().notePriorDiagnosticFrom(
5085 ToContext.getDiagnostics());
5086 LastDiagFromFrom = true;
Argyrios Kyrtzidisd0040642010-11-18 20:06:41 +00005087 return FromContext.getDiagnostics().Report(Loc, DiagID);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00005088}
Douglas Gregor8cdbe642010-02-12 23:44:20 +00005089
Douglas Gregor2e15c842012-02-01 21:00:38 +00005090void ASTImporter::CompleteDecl (Decl *D) {
5091 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
5092 if (!ID->getDefinition())
5093 ID->startDefinition();
5094 }
5095 else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) {
5096 if (!PD->getDefinition())
5097 PD->startDefinition();
5098 }
5099 else if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
5100 if (!TD->getDefinition() && !TD->isBeingDefined()) {
5101 TD->startDefinition();
5102 TD->setCompleteDefinition(true);
5103 }
5104 }
5105 else {
5106 assert (0 && "CompleteDecl called on a Decl that can't be completed");
5107 }
5108}
5109
Douglas Gregor8cdbe642010-02-12 23:44:20 +00005110Decl *ASTImporter::Imported(Decl *From, Decl *To) {
5111 ImportedDecls[From] = To;
5112 return To;
Daniel Dunbar9ced5422010-02-13 20:24:39 +00005113}
Douglas Gregorb4964f72010-02-15 23:54:17 +00005114
Douglas Gregordd6006f2012-07-17 21:16:27 +00005115bool ASTImporter::IsStructurallyEquivalent(QualType From, QualType To,
5116 bool Complain) {
John McCall424cec92011-01-19 06:33:43 +00005117 llvm::DenseMap<const Type *, const Type *>::iterator Pos
Douglas Gregorb4964f72010-02-15 23:54:17 +00005118 = ImportedTypes.find(From.getTypePtr());
5119 if (Pos != ImportedTypes.end() && ToContext.hasSameType(Import(From), To))
5120 return true;
5121
Douglas Gregordd6006f2012-07-17 21:16:27 +00005122 StructuralEquivalenceContext Ctx(FromContext, ToContext, NonEquivalentDecls,
5123 false, Complain);
Benjamin Kramer26d19c52010-02-18 13:02:13 +00005124 return Ctx.IsStructurallyEquivalent(From, To);
Douglas Gregorb4964f72010-02-15 23:54:17 +00005125}