blob: 573bab7b23c34bc5cf131cff2d354fed2112bb3c [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"
15
16#include "clang/AST/ASTContext.h"
Douglas Gregor811663e2010-02-10 00:15:17 +000017#include "clang/AST/ASTDiagnostic.h"
Douglas Gregor5c73e912010-02-11 00:48:18 +000018#include "clang/AST/DeclCXX.h"
Douglas Gregor96e578d2010-02-05 17:54:41 +000019#include "clang/AST/DeclObjC.h"
Douglas Gregor3aed6cd2010-02-08 21:09:39 +000020#include "clang/AST/DeclVisitor.h"
Douglas Gregor7eeb5972010-02-11 19:21:55 +000021#include "clang/AST/StmtVisitor.h"
Douglas Gregorfa7a0e52010-02-10 17:47:19 +000022#include "clang/AST/TypeLoc.h"
Douglas Gregor96e578d2010-02-05 17:54:41 +000023#include "clang/AST/TypeVisitor.h"
Douglas Gregor811663e2010-02-10 00:15:17 +000024#include "clang/Basic/FileManager.h"
25#include "clang/Basic/SourceManager.h"
26#include "llvm/Support/MemoryBuffer.h"
Douglas Gregor3996e242010-02-15 22:01:00 +000027#include <deque>
Douglas Gregor96e578d2010-02-05 17:54:41 +000028
29using namespace clang;
30
31namespace {
Douglas Gregor3aed6cd2010-02-08 21:09:39 +000032 class ASTNodeImporter : public TypeVisitor<ASTNodeImporter, QualType>,
Douglas Gregor7eeb5972010-02-11 19:21:55 +000033 public DeclVisitor<ASTNodeImporter, Decl *>,
34 public StmtVisitor<ASTNodeImporter, Stmt *> {
Douglas Gregor96e578d2010-02-05 17:54:41 +000035 ASTImporter &Importer;
36
37 public:
38 explicit ASTNodeImporter(ASTImporter &Importer) : Importer(Importer) { }
39
40 using TypeVisitor<ASTNodeImporter, QualType>::Visit;
Douglas Gregor62d311f2010-02-09 19:21:46 +000041 using DeclVisitor<ASTNodeImporter, Decl *>::Visit;
Douglas Gregor7eeb5972010-02-11 19:21:55 +000042 using StmtVisitor<ASTNodeImporter, Stmt *>::Visit;
Douglas Gregor96e578d2010-02-05 17:54:41 +000043
44 // Importing types
Douglas Gregore4c83e42010-02-09 22:48:33 +000045 QualType VisitType(Type *T);
Douglas Gregor96e578d2010-02-05 17:54:41 +000046 QualType VisitBuiltinType(BuiltinType *T);
47 QualType VisitComplexType(ComplexType *T);
48 QualType VisitPointerType(PointerType *T);
49 QualType VisitBlockPointerType(BlockPointerType *T);
50 QualType VisitLValueReferenceType(LValueReferenceType *T);
51 QualType VisitRValueReferenceType(RValueReferenceType *T);
52 QualType VisitMemberPointerType(MemberPointerType *T);
53 QualType VisitConstantArrayType(ConstantArrayType *T);
54 QualType VisitIncompleteArrayType(IncompleteArrayType *T);
55 QualType VisitVariableArrayType(VariableArrayType *T);
56 // FIXME: DependentSizedArrayType
57 // FIXME: DependentSizedExtVectorType
58 QualType VisitVectorType(VectorType *T);
59 QualType VisitExtVectorType(ExtVectorType *T);
60 QualType VisitFunctionNoProtoType(FunctionNoProtoType *T);
61 QualType VisitFunctionProtoType(FunctionProtoType *T);
62 // FIXME: UnresolvedUsingType
63 QualType VisitTypedefType(TypedefType *T);
64 QualType VisitTypeOfExprType(TypeOfExprType *T);
65 // FIXME: DependentTypeOfExprType
66 QualType VisitTypeOfType(TypeOfType *T);
67 QualType VisitDecltypeType(DecltypeType *T);
68 // FIXME: DependentDecltypeType
69 QualType VisitRecordType(RecordType *T);
70 QualType VisitEnumType(EnumType *T);
71 QualType VisitElaboratedType(ElaboratedType *T);
72 // FIXME: TemplateTypeParmType
73 // FIXME: SubstTemplateTypeParmType
74 // FIXME: TemplateSpecializationType
75 QualType VisitQualifiedNameType(QualifiedNameType *T);
76 // FIXME: TypenameType
77 QualType VisitObjCInterfaceType(ObjCInterfaceType *T);
78 QualType VisitObjCObjectPointerType(ObjCObjectPointerType *T);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +000079
80 // Importing declarations
Douglas Gregorbb7930c2010-02-10 19:54:31 +000081 bool ImportDeclParts(NamedDecl *D, DeclContext *&DC,
82 DeclContext *&LexicalDC, DeclarationName &Name,
83 SourceLocation &Loc);
Douglas Gregor5c73e912010-02-11 00:48:18 +000084 bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord);
Douglas Gregor3996e242010-02-15 22:01:00 +000085 bool IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToRecord);
Douglas Gregore4c83e42010-02-09 22:48:33 +000086 Decl *VisitDecl(Decl *D);
Douglas Gregor5fa74c32010-02-10 21:10:29 +000087 Decl *VisitTypedefDecl(TypedefDecl *D);
Douglas Gregor98c10182010-02-12 22:17:39 +000088 Decl *VisitEnumDecl(EnumDecl *D);
Douglas Gregor5c73e912010-02-11 00:48:18 +000089 Decl *VisitRecordDecl(RecordDecl *D);
Douglas Gregor98c10182010-02-12 22:17:39 +000090 Decl *VisitEnumConstantDecl(EnumConstantDecl *D);
Douglas Gregorbb7930c2010-02-10 19:54:31 +000091 Decl *VisitFunctionDecl(FunctionDecl *D);
Douglas Gregor5c73e912010-02-11 00:48:18 +000092 Decl *VisitFieldDecl(FieldDecl *D);
Douglas Gregor7244b0b2010-02-17 00:34:30 +000093 Decl *VisitObjCIvarDecl(ObjCIvarDecl *D);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +000094 Decl *VisitVarDecl(VarDecl *D);
Douglas Gregor8b228d72010-02-17 21:22:52 +000095 Decl *VisitImplicitParamDecl(ImplicitParamDecl *D);
Douglas Gregorbb7930c2010-02-10 19:54:31 +000096 Decl *VisitParmVarDecl(ParmVarDecl *D);
Douglas Gregor43f54792010-02-17 02:12:47 +000097 Decl *VisitObjCMethodDecl(ObjCMethodDecl *D);
Douglas Gregor84c51c32010-02-18 01:47:50 +000098 Decl *VisitObjCCategoryDecl(ObjCCategoryDecl *D);
Douglas Gregor98d156a2010-02-17 16:12:00 +000099 Decl *VisitObjCProtocolDecl(ObjCProtocolDecl *D);
Douglas Gregor45635322010-02-16 01:20:57 +0000100 Decl *VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
Douglas Gregora11c4582010-02-17 18:02:10 +0000101 Decl *VisitObjCPropertyDecl(ObjCPropertyDecl *D);
Douglas Gregor8661a722010-02-18 02:12:22 +0000102 Decl *VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D);
Douglas Gregor06537af2010-02-18 02:04:09 +0000103 Decl *VisitObjCClassDecl(ObjCClassDecl *D);
104
Douglas Gregor7eeb5972010-02-11 19:21:55 +0000105 // Importing statements
106 Stmt *VisitStmt(Stmt *S);
107
108 // Importing expressions
109 Expr *VisitExpr(Expr *E);
Douglas Gregor52f820e2010-02-19 01:17:02 +0000110 Expr *VisitDeclRefExpr(DeclRefExpr *E);
Douglas Gregor7eeb5972010-02-11 19:21:55 +0000111 Expr *VisitIntegerLiteral(IntegerLiteral *E);
Douglas Gregor623421d2010-02-18 02:21:22 +0000112 Expr *VisitCharacterLiteral(CharacterLiteral *E);
Douglas Gregorc74247e2010-02-19 01:07:06 +0000113 Expr *VisitParenExpr(ParenExpr *E);
114 Expr *VisitUnaryOperator(UnaryOperator *E);
Douglas Gregord8552cd2010-02-19 01:24:23 +0000115 Expr *VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E);
Douglas Gregorc74247e2010-02-19 01:07:06 +0000116 Expr *VisitBinaryOperator(BinaryOperator *E);
117 Expr *VisitCompoundAssignOperator(CompoundAssignOperator *E);
Douglas Gregor98c10182010-02-12 22:17:39 +0000118 Expr *VisitImplicitCastExpr(ImplicitCastExpr *E);
Douglas Gregor96e578d2010-02-05 17:54:41 +0000119 };
120}
121
122//----------------------------------------------------------------------------
Douglas Gregor3996e242010-02-15 22:01:00 +0000123// Structural Equivalence
124//----------------------------------------------------------------------------
125
126namespace {
127 struct StructuralEquivalenceContext {
128 /// \brief AST contexts for which we are checking structural equivalence.
129 ASTContext &C1, &C2;
130
131 /// \brief Diagnostic object used to emit diagnostics.
132 Diagnostic &Diags;
133
134 /// \brief The set of "tentative" equivalences between two canonical
135 /// declarations, mapping from a declaration in the first context to the
136 /// declaration in the second context that we believe to be equivalent.
137 llvm::DenseMap<Decl *, Decl *> TentativeEquivalences;
138
139 /// \brief Queue of declarations in the first context whose equivalence
140 /// with a declaration in the second context still needs to be verified.
141 std::deque<Decl *> DeclsToCheck;
142
Douglas Gregorb4964f72010-02-15 23:54:17 +0000143 /// \brief Declaration (from, to) pairs that are known not to be equivalent
144 /// (which we have already complained about).
145 llvm::DenseSet<std::pair<Decl *, Decl *> > &NonEquivalentDecls;
146
Douglas Gregor3996e242010-02-15 22:01:00 +0000147 /// \brief Whether we're being strict about the spelling of types when
148 /// unifying two types.
149 bool StrictTypeSpelling;
150
151 StructuralEquivalenceContext(ASTContext &C1, ASTContext &C2,
152 Diagnostic &Diags,
Douglas Gregorb4964f72010-02-15 23:54:17 +0000153 llvm::DenseSet<std::pair<Decl *, Decl *> > &NonEquivalentDecls,
Douglas Gregor3996e242010-02-15 22:01:00 +0000154 bool StrictTypeSpelling = false)
Douglas Gregorb4964f72010-02-15 23:54:17 +0000155 : C1(C1), C2(C2), Diags(Diags), NonEquivalentDecls(NonEquivalentDecls),
156 StrictTypeSpelling(StrictTypeSpelling) { }
Douglas Gregor3996e242010-02-15 22:01:00 +0000157
158 /// \brief Determine whether the two declarations are structurally
159 /// equivalent.
160 bool IsStructurallyEquivalent(Decl *D1, Decl *D2);
161
162 /// \brief Determine whether the two types are structurally equivalent.
163 bool IsStructurallyEquivalent(QualType T1, QualType T2);
164
165 private:
166 /// \brief Finish checking all of the structural equivalences.
167 ///
168 /// \returns true if an error occurred, false otherwise.
169 bool Finish();
170
171 public:
172 DiagnosticBuilder Diag1(SourceLocation Loc, unsigned DiagID) {
173 return Diags.Report(FullSourceLoc(Loc, C1.getSourceManager()), DiagID);
174 }
175
176 DiagnosticBuilder Diag2(SourceLocation Loc, unsigned DiagID) {
177 return Diags.Report(FullSourceLoc(Loc, C2.getSourceManager()), DiagID);
178 }
179 };
180}
181
182static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
183 QualType T1, QualType T2);
184static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
185 Decl *D1, Decl *D2);
186
187/// \brief Determine if two APInts have the same value, after zero-extending
188/// one of them (if needed!) to ensure that the bit-widths match.
189static bool IsSameValue(const llvm::APInt &I1, const llvm::APInt &I2) {
190 if (I1.getBitWidth() == I2.getBitWidth())
191 return I1 == I2;
192
193 if (I1.getBitWidth() > I2.getBitWidth())
194 return I1 == llvm::APInt(I2).zext(I1.getBitWidth());
195
196 return llvm::APInt(I1).zext(I2.getBitWidth()) == I2;
197}
198
199/// \brief Determine if two APSInts have the same value, zero- or sign-extending
200/// as needed.
201static bool IsSameValue(const llvm::APSInt &I1, const llvm::APSInt &I2) {
202 if (I1.getBitWidth() == I2.getBitWidth() && I1.isSigned() == I2.isSigned())
203 return I1 == I2;
204
205 // Check for a bit-width mismatch.
206 if (I1.getBitWidth() > I2.getBitWidth())
207 return IsSameValue(I1, llvm::APSInt(I2).extend(I1.getBitWidth()));
208 else if (I2.getBitWidth() > I1.getBitWidth())
209 return IsSameValue(llvm::APSInt(I1).extend(I2.getBitWidth()), I2);
210
211 // We have a signedness mismatch. Turn the signed value into an unsigned
212 // value.
213 if (I1.isSigned()) {
214 if (I1.isNegative())
215 return false;
216
217 return llvm::APSInt(I1, true) == I2;
218 }
219
220 if (I2.isNegative())
221 return false;
222
223 return I1 == llvm::APSInt(I2, true);
224}
225
226/// \brief Determine structural equivalence of two expressions.
227static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
228 Expr *E1, Expr *E2) {
229 if (!E1 || !E2)
230 return E1 == E2;
231
232 // FIXME: Actually perform a structural comparison!
233 return true;
234}
235
236/// \brief Determine whether two identifiers are equivalent.
237static bool IsStructurallyEquivalent(const IdentifierInfo *Name1,
238 const IdentifierInfo *Name2) {
239 if (!Name1 || !Name2)
240 return Name1 == Name2;
241
242 return Name1->getName() == Name2->getName();
243}
244
245/// \brief Determine whether two nested-name-specifiers are equivalent.
246static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
247 NestedNameSpecifier *NNS1,
248 NestedNameSpecifier *NNS2) {
249 // FIXME: Implement!
250 return true;
251}
252
253/// \brief Determine whether two template arguments are equivalent.
254static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
255 const TemplateArgument &Arg1,
256 const TemplateArgument &Arg2) {
257 // FIXME: Implement!
258 return true;
259}
260
261/// \brief Determine structural equivalence for the common part of array
262/// types.
263static bool IsArrayStructurallyEquivalent(StructuralEquivalenceContext &Context,
264 const ArrayType *Array1,
265 const ArrayType *Array2) {
266 if (!IsStructurallyEquivalent(Context,
267 Array1->getElementType(),
268 Array2->getElementType()))
269 return false;
270 if (Array1->getSizeModifier() != Array2->getSizeModifier())
271 return false;
272 if (Array1->getIndexTypeQualifiers() != Array2->getIndexTypeQualifiers())
273 return false;
274
275 return true;
276}
277
278/// \brief Determine structural equivalence of two types.
279static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
280 QualType T1, QualType T2) {
281 if (T1.isNull() || T2.isNull())
282 return T1.isNull() && T2.isNull();
283
284 if (!Context.StrictTypeSpelling) {
285 // We aren't being strict about token-to-token equivalence of types,
286 // so map down to the canonical type.
287 T1 = Context.C1.getCanonicalType(T1);
288 T2 = Context.C2.getCanonicalType(T2);
289 }
290
291 if (T1.getQualifiers() != T2.getQualifiers())
292 return false;
293
Douglas Gregorb4964f72010-02-15 23:54:17 +0000294 Type::TypeClass TC = T1->getTypeClass();
Douglas Gregor3996e242010-02-15 22:01:00 +0000295
Douglas Gregorb4964f72010-02-15 23:54:17 +0000296 if (T1->getTypeClass() != T2->getTypeClass()) {
297 // Compare function types with prototypes vs. without prototypes as if
298 // both did not have prototypes.
299 if (T1->getTypeClass() == Type::FunctionProto &&
300 T2->getTypeClass() == Type::FunctionNoProto)
301 TC = Type::FunctionNoProto;
302 else if (T1->getTypeClass() == Type::FunctionNoProto &&
303 T2->getTypeClass() == Type::FunctionProto)
304 TC = Type::FunctionNoProto;
305 else
306 return false;
307 }
308
309 switch (TC) {
310 case Type::Builtin:
Douglas Gregor3996e242010-02-15 22:01:00 +0000311 // FIXME: Deal with Char_S/Char_U.
312 if (cast<BuiltinType>(T1)->getKind() != cast<BuiltinType>(T2)->getKind())
313 return false;
314 break;
315
316 case Type::Complex:
317 if (!IsStructurallyEquivalent(Context,
318 cast<ComplexType>(T1)->getElementType(),
319 cast<ComplexType>(T2)->getElementType()))
320 return false;
321 break;
322
323 case Type::Pointer:
324 if (!IsStructurallyEquivalent(Context,
325 cast<PointerType>(T1)->getPointeeType(),
326 cast<PointerType>(T2)->getPointeeType()))
327 return false;
328 break;
329
330 case Type::BlockPointer:
331 if (!IsStructurallyEquivalent(Context,
332 cast<BlockPointerType>(T1)->getPointeeType(),
333 cast<BlockPointerType>(T2)->getPointeeType()))
334 return false;
335 break;
336
337 case Type::LValueReference:
338 case Type::RValueReference: {
339 const ReferenceType *Ref1 = cast<ReferenceType>(T1);
340 const ReferenceType *Ref2 = cast<ReferenceType>(T2);
341 if (Ref1->isSpelledAsLValue() != Ref2->isSpelledAsLValue())
342 return false;
343 if (Ref1->isInnerRef() != Ref2->isInnerRef())
344 return false;
345 if (!IsStructurallyEquivalent(Context,
346 Ref1->getPointeeTypeAsWritten(),
347 Ref2->getPointeeTypeAsWritten()))
348 return false;
349 break;
350 }
351
352 case Type::MemberPointer: {
353 const MemberPointerType *MemPtr1 = cast<MemberPointerType>(T1);
354 const MemberPointerType *MemPtr2 = cast<MemberPointerType>(T2);
355 if (!IsStructurallyEquivalent(Context,
356 MemPtr1->getPointeeType(),
357 MemPtr2->getPointeeType()))
358 return false;
359 if (!IsStructurallyEquivalent(Context,
360 QualType(MemPtr1->getClass(), 0),
361 QualType(MemPtr2->getClass(), 0)))
362 return false;
363 break;
364 }
365
366 case Type::ConstantArray: {
367 const ConstantArrayType *Array1 = cast<ConstantArrayType>(T1);
368 const ConstantArrayType *Array2 = cast<ConstantArrayType>(T2);
369 if (!IsSameValue(Array1->getSize(), Array2->getSize()))
370 return false;
371
372 if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
373 return false;
374 break;
375 }
376
377 case Type::IncompleteArray:
378 if (!IsArrayStructurallyEquivalent(Context,
379 cast<ArrayType>(T1),
380 cast<ArrayType>(T2)))
381 return false;
382 break;
383
384 case Type::VariableArray: {
385 const VariableArrayType *Array1 = cast<VariableArrayType>(T1);
386 const VariableArrayType *Array2 = cast<VariableArrayType>(T2);
387 if (!IsStructurallyEquivalent(Context,
388 Array1->getSizeExpr(), Array2->getSizeExpr()))
389 return false;
390
391 if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
392 return false;
393
394 break;
395 }
396
397 case Type::DependentSizedArray: {
398 const DependentSizedArrayType *Array1 = cast<DependentSizedArrayType>(T1);
399 const DependentSizedArrayType *Array2 = cast<DependentSizedArrayType>(T2);
400 if (!IsStructurallyEquivalent(Context,
401 Array1->getSizeExpr(), Array2->getSizeExpr()))
402 return false;
403
404 if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
405 return false;
406
407 break;
408 }
409
410 case Type::DependentSizedExtVector: {
411 const DependentSizedExtVectorType *Vec1
412 = cast<DependentSizedExtVectorType>(T1);
413 const DependentSizedExtVectorType *Vec2
414 = cast<DependentSizedExtVectorType>(T2);
415 if (!IsStructurallyEquivalent(Context,
416 Vec1->getSizeExpr(), Vec2->getSizeExpr()))
417 return false;
418 if (!IsStructurallyEquivalent(Context,
419 Vec1->getElementType(),
420 Vec2->getElementType()))
421 return false;
422 break;
423 }
424
425 case Type::Vector:
426 case Type::ExtVector: {
427 const VectorType *Vec1 = cast<VectorType>(T1);
428 const VectorType *Vec2 = cast<VectorType>(T2);
429 if (!IsStructurallyEquivalent(Context,
430 Vec1->getElementType(),
431 Vec2->getElementType()))
432 return false;
433 if (Vec1->getNumElements() != Vec2->getNumElements())
434 return false;
435 if (Vec1->isAltiVec() != Vec2->isAltiVec())
436 return false;
437 if (Vec1->isPixel() != Vec2->isPixel())
438 return false;
439 }
440
441 case Type::FunctionProto: {
442 const FunctionProtoType *Proto1 = cast<FunctionProtoType>(T1);
443 const FunctionProtoType *Proto2 = cast<FunctionProtoType>(T2);
444 if (Proto1->getNumArgs() != Proto2->getNumArgs())
445 return false;
446 for (unsigned I = 0, N = Proto1->getNumArgs(); I != N; ++I) {
447 if (!IsStructurallyEquivalent(Context,
448 Proto1->getArgType(I),
449 Proto2->getArgType(I)))
450 return false;
451 }
452 if (Proto1->isVariadic() != Proto2->isVariadic())
453 return false;
454 if (Proto1->hasExceptionSpec() != Proto2->hasExceptionSpec())
455 return false;
456 if (Proto1->hasAnyExceptionSpec() != Proto2->hasAnyExceptionSpec())
457 return false;
458 if (Proto1->getNumExceptions() != Proto2->getNumExceptions())
459 return false;
460 for (unsigned I = 0, N = Proto1->getNumExceptions(); I != N; ++I) {
461 if (!IsStructurallyEquivalent(Context,
462 Proto1->getExceptionType(I),
463 Proto2->getExceptionType(I)))
464 return false;
465 }
466 if (Proto1->getTypeQuals() != Proto2->getTypeQuals())
467 return false;
468
469 // Fall through to check the bits common with FunctionNoProtoType.
470 }
471
472 case Type::FunctionNoProto: {
473 const FunctionType *Function1 = cast<FunctionType>(T1);
474 const FunctionType *Function2 = cast<FunctionType>(T2);
475 if (!IsStructurallyEquivalent(Context,
476 Function1->getResultType(),
477 Function2->getResultType()))
478 return false;
479 if (Function1->getNoReturnAttr() != Function2->getNoReturnAttr())
480 return false;
481 if (Function1->getCallConv() != Function2->getCallConv())
482 return false;
483 break;
484 }
485
486 case Type::UnresolvedUsing:
487 if (!IsStructurallyEquivalent(Context,
488 cast<UnresolvedUsingType>(T1)->getDecl(),
489 cast<UnresolvedUsingType>(T2)->getDecl()))
490 return false;
491
492 break;
493
494 case Type::Typedef:
495 if (!IsStructurallyEquivalent(Context,
496 cast<TypedefType>(T1)->getDecl(),
497 cast<TypedefType>(T2)->getDecl()))
498 return false;
499 break;
500
501 case Type::TypeOfExpr:
502 if (!IsStructurallyEquivalent(Context,
503 cast<TypeOfExprType>(T1)->getUnderlyingExpr(),
504 cast<TypeOfExprType>(T2)->getUnderlyingExpr()))
505 return false;
506 break;
507
508 case Type::TypeOf:
509 if (!IsStructurallyEquivalent(Context,
510 cast<TypeOfType>(T1)->getUnderlyingType(),
511 cast<TypeOfType>(T2)->getUnderlyingType()))
512 return false;
513 break;
514
515 case Type::Decltype:
516 if (!IsStructurallyEquivalent(Context,
517 cast<DecltypeType>(T1)->getUnderlyingExpr(),
518 cast<DecltypeType>(T2)->getUnderlyingExpr()))
519 return false;
520 break;
521
522 case Type::Record:
523 case Type::Enum:
524 if (!IsStructurallyEquivalent(Context,
525 cast<TagType>(T1)->getDecl(),
526 cast<TagType>(T2)->getDecl()))
527 return false;
528 break;
529
530 case Type::Elaborated: {
531 const ElaboratedType *Elab1 = cast<ElaboratedType>(T1);
532 const ElaboratedType *Elab2 = cast<ElaboratedType>(T2);
533 if (Elab1->getTagKind() != Elab2->getTagKind())
534 return false;
535 if (!IsStructurallyEquivalent(Context,
536 Elab1->getUnderlyingType(),
537 Elab2->getUnderlyingType()))
538 return false;
539 break;
540 }
541
542 case Type::TemplateTypeParm: {
543 const TemplateTypeParmType *Parm1 = cast<TemplateTypeParmType>(T1);
544 const TemplateTypeParmType *Parm2 = cast<TemplateTypeParmType>(T2);
545 if (Parm1->getDepth() != Parm2->getDepth())
546 return false;
547 if (Parm1->getIndex() != Parm2->getIndex())
548 return false;
549 if (Parm1->isParameterPack() != Parm2->isParameterPack())
550 return false;
551
552 // Names of template type parameters are never significant.
553 break;
554 }
555
556 case Type::SubstTemplateTypeParm: {
557 const SubstTemplateTypeParmType *Subst1
558 = cast<SubstTemplateTypeParmType>(T1);
559 const SubstTemplateTypeParmType *Subst2
560 = cast<SubstTemplateTypeParmType>(T2);
561 if (!IsStructurallyEquivalent(Context,
562 QualType(Subst1->getReplacedParameter(), 0),
563 QualType(Subst2->getReplacedParameter(), 0)))
564 return false;
565 if (!IsStructurallyEquivalent(Context,
566 Subst1->getReplacementType(),
567 Subst2->getReplacementType()))
568 return false;
569 break;
570 }
571
572 case Type::TemplateSpecialization: {
573 const TemplateSpecializationType *Spec1
574 = cast<TemplateSpecializationType>(T1);
575 const TemplateSpecializationType *Spec2
576 = cast<TemplateSpecializationType>(T2);
577 if (!IsStructurallyEquivalent(Context,
578 Spec1->getTemplateName(),
579 Spec2->getTemplateName()))
580 return false;
581 if (Spec1->getNumArgs() != Spec2->getNumArgs())
582 return false;
583 for (unsigned I = 0, N = Spec1->getNumArgs(); I != N; ++I) {
584 if (!IsStructurallyEquivalent(Context,
585 Spec1->getArg(I), Spec2->getArg(I)))
586 return false;
587 }
588 break;
589 }
590
591 case Type::QualifiedName: {
592 const QualifiedNameType *Qual1 = cast<QualifiedNameType>(T1);
593 const QualifiedNameType *Qual2 = cast<QualifiedNameType>(T2);
594 if (!IsStructurallyEquivalent(Context,
595 Qual1->getQualifier(),
596 Qual2->getQualifier()))
597 return false;
598 if (!IsStructurallyEquivalent(Context,
599 Qual1->getNamedType(),
600 Qual2->getNamedType()))
601 return false;
602 break;
603 }
604
605 case Type::Typename: {
606 const TypenameType *Typename1 = cast<TypenameType>(T1);
607 const TypenameType *Typename2 = cast<TypenameType>(T2);
608 if (!IsStructurallyEquivalent(Context,
609 Typename1->getQualifier(),
610 Typename2->getQualifier()))
611 return false;
612 if (!IsStructurallyEquivalent(Typename1->getIdentifier(),
613 Typename2->getIdentifier()))
614 return false;
615 if (!IsStructurallyEquivalent(Context,
616 QualType(Typename1->getTemplateId(), 0),
617 QualType(Typename2->getTemplateId(), 0)))
618 return false;
619
620 break;
621 }
622
623 case Type::ObjCInterface: {
624 const ObjCInterfaceType *Iface1 = cast<ObjCInterfaceType>(T1);
625 const ObjCInterfaceType *Iface2 = cast<ObjCInterfaceType>(T2);
626 if (!IsStructurallyEquivalent(Context,
627 Iface1->getDecl(), Iface2->getDecl()))
628 return false;
629 if (Iface1->getNumProtocols() != Iface2->getNumProtocols())
630 return false;
631 for (unsigned I = 0, N = Iface1->getNumProtocols(); I != N; ++I) {
632 if (!IsStructurallyEquivalent(Context,
633 Iface1->getProtocol(I),
634 Iface2->getProtocol(I)))
635 return false;
636 }
637 break;
638 }
639
640 case Type::ObjCObjectPointer: {
641 const ObjCObjectPointerType *Ptr1 = cast<ObjCObjectPointerType>(T1);
642 const ObjCObjectPointerType *Ptr2 = cast<ObjCObjectPointerType>(T2);
643 if (!IsStructurallyEquivalent(Context,
644 Ptr1->getPointeeType(),
645 Ptr2->getPointeeType()))
646 return false;
647 if (Ptr1->getNumProtocols() != Ptr2->getNumProtocols())
648 return false;
649 for (unsigned I = 0, N = Ptr1->getNumProtocols(); I != N; ++I) {
650 if (!IsStructurallyEquivalent(Context,
651 Ptr1->getProtocol(I),
652 Ptr2->getProtocol(I)))
653 return false;
654 }
655 break;
656 }
657
658 } // end switch
659
660 return true;
661}
662
663/// \brief Determine structural equivalence of two records.
664static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
665 RecordDecl *D1, RecordDecl *D2) {
666 if (D1->isUnion() != D2->isUnion()) {
667 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
668 << Context.C2.getTypeDeclType(D2);
669 Context.Diag1(D1->getLocation(), diag::note_odr_tag_kind_here)
670 << D1->getDeclName() << (unsigned)D1->getTagKind();
671 return false;
672 }
673
Douglas Gregorb4964f72010-02-15 23:54:17 +0000674 // Compare the definitions of these two records. If either or both are
675 // incomplete, we assume that they are equivalent.
676 D1 = D1->getDefinition();
677 D2 = D2->getDefinition();
678 if (!D1 || !D2)
679 return true;
680
Douglas Gregor3996e242010-02-15 22:01:00 +0000681 if (CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(D1)) {
682 if (CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(D2)) {
683 if (D1CXX->getNumBases() != D2CXX->getNumBases()) {
684 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
685 << Context.C2.getTypeDeclType(D2);
686 Context.Diag2(D2->getLocation(), diag::note_odr_number_of_bases)
687 << D2CXX->getNumBases();
688 Context.Diag1(D1->getLocation(), diag::note_odr_number_of_bases)
689 << D1CXX->getNumBases();
690 return false;
691 }
692
693 // Check the base classes.
694 for (CXXRecordDecl::base_class_iterator Base1 = D1CXX->bases_begin(),
695 BaseEnd1 = D1CXX->bases_end(),
696 Base2 = D2CXX->bases_begin();
697 Base1 != BaseEnd1;
698 ++Base1, ++Base2) {
699 if (!IsStructurallyEquivalent(Context,
700 Base1->getType(), Base2->getType())) {
701 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
702 << Context.C2.getTypeDeclType(D2);
703 Context.Diag2(Base2->getSourceRange().getBegin(), diag::note_odr_base)
704 << Base2->getType()
705 << Base2->getSourceRange();
706 Context.Diag1(Base1->getSourceRange().getBegin(), diag::note_odr_base)
707 << Base1->getType()
708 << Base1->getSourceRange();
709 return false;
710 }
711
712 // Check virtual vs. non-virtual inheritance mismatch.
713 if (Base1->isVirtual() != Base2->isVirtual()) {
714 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
715 << Context.C2.getTypeDeclType(D2);
716 Context.Diag2(Base2->getSourceRange().getBegin(),
717 diag::note_odr_virtual_base)
718 << Base2->isVirtual() << Base2->getSourceRange();
719 Context.Diag1(Base1->getSourceRange().getBegin(), diag::note_odr_base)
720 << Base1->isVirtual()
721 << Base1->getSourceRange();
722 return false;
723 }
724 }
725 } else if (D1CXX->getNumBases() > 0) {
726 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
727 << Context.C2.getTypeDeclType(D2);
728 const CXXBaseSpecifier *Base1 = D1CXX->bases_begin();
729 Context.Diag1(Base1->getSourceRange().getBegin(), diag::note_odr_base)
730 << Base1->getType()
731 << Base1->getSourceRange();
732 Context.Diag2(D2->getLocation(), diag::note_odr_missing_base);
733 return false;
734 }
735 }
736
737 // Check the fields for consistency.
738 CXXRecordDecl::field_iterator Field2 = D2->field_begin(),
739 Field2End = D2->field_end();
740 for (CXXRecordDecl::field_iterator Field1 = D1->field_begin(),
741 Field1End = D1->field_end();
742 Field1 != Field1End;
743 ++Field1, ++Field2) {
744 if (Field2 == Field2End) {
745 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
746 << Context.C2.getTypeDeclType(D2);
747 Context.Diag1(Field1->getLocation(), diag::note_odr_field)
748 << Field1->getDeclName() << Field1->getType();
749 Context.Diag2(D2->getLocation(), diag::note_odr_missing_field);
750 return false;
751 }
752
753 if (!IsStructurallyEquivalent(Context,
754 Field1->getType(), Field2->getType())) {
755 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
756 << Context.C2.getTypeDeclType(D2);
757 Context.Diag2(Field2->getLocation(), diag::note_odr_field)
758 << Field2->getDeclName() << Field2->getType();
759 Context.Diag1(Field1->getLocation(), diag::note_odr_field)
760 << Field1->getDeclName() << Field1->getType();
761 return false;
762 }
763
764 if (Field1->isBitField() != Field2->isBitField()) {
765 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
766 << Context.C2.getTypeDeclType(D2);
767 if (Field1->isBitField()) {
768 llvm::APSInt Bits;
769 Field1->getBitWidth()->isIntegerConstantExpr(Bits, Context.C1);
770 Context.Diag1(Field1->getLocation(), diag::note_odr_bit_field)
771 << Field1->getDeclName() << Field1->getType()
772 << Bits.toString(10, false);
773 Context.Diag2(Field2->getLocation(), diag::note_odr_not_bit_field)
774 << Field2->getDeclName();
775 } else {
776 llvm::APSInt Bits;
777 Field2->getBitWidth()->isIntegerConstantExpr(Bits, Context.C2);
778 Context.Diag2(Field2->getLocation(), diag::note_odr_bit_field)
779 << Field2->getDeclName() << Field2->getType()
780 << Bits.toString(10, false);
781 Context.Diag1(Field1->getLocation(),
782 diag::note_odr_not_bit_field)
783 << Field1->getDeclName();
784 }
785 return false;
786 }
787
788 if (Field1->isBitField()) {
789 // Make sure that the bit-fields are the same length.
790 llvm::APSInt Bits1, Bits2;
791 if (!Field1->getBitWidth()->isIntegerConstantExpr(Bits1, Context.C1))
792 return false;
793 if (!Field2->getBitWidth()->isIntegerConstantExpr(Bits2, Context.C2))
794 return false;
795
796 if (!IsSameValue(Bits1, Bits2)) {
797 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
798 << Context.C2.getTypeDeclType(D2);
799 Context.Diag2(Field2->getLocation(), diag::note_odr_bit_field)
800 << Field2->getDeclName() << Field2->getType()
801 << Bits2.toString(10, false);
802 Context.Diag1(Field1->getLocation(), diag::note_odr_bit_field)
803 << Field1->getDeclName() << Field1->getType()
804 << Bits1.toString(10, false);
805 return false;
806 }
807 }
808 }
809
810 if (Field2 != Field2End) {
811 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
812 << Context.C2.getTypeDeclType(D2);
813 Context.Diag2(Field2->getLocation(), diag::note_odr_field)
814 << Field2->getDeclName() << Field2->getType();
815 Context.Diag1(D1->getLocation(), diag::note_odr_missing_field);
816 return false;
817 }
818
819 return true;
820}
821
822/// \brief Determine structural equivalence of two enums.
823static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
824 EnumDecl *D1, EnumDecl *D2) {
825 EnumDecl::enumerator_iterator EC2 = D2->enumerator_begin(),
826 EC2End = D2->enumerator_end();
827 for (EnumDecl::enumerator_iterator EC1 = D1->enumerator_begin(),
828 EC1End = D1->enumerator_end();
829 EC1 != EC1End; ++EC1, ++EC2) {
830 if (EC2 == EC2End) {
831 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
832 << Context.C2.getTypeDeclType(D2);
833 Context.Diag1(EC1->getLocation(), diag::note_odr_enumerator)
834 << EC1->getDeclName()
835 << EC1->getInitVal().toString(10);
836 Context.Diag2(D2->getLocation(), diag::note_odr_missing_enumerator);
837 return false;
838 }
839
840 llvm::APSInt Val1 = EC1->getInitVal();
841 llvm::APSInt Val2 = EC2->getInitVal();
842 if (!IsSameValue(Val1, Val2) ||
843 !IsStructurallyEquivalent(EC1->getIdentifier(), EC2->getIdentifier())) {
844 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
845 << Context.C2.getTypeDeclType(D2);
846 Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
847 << EC2->getDeclName()
848 << EC2->getInitVal().toString(10);
849 Context.Diag1(EC1->getLocation(), diag::note_odr_enumerator)
850 << EC1->getDeclName()
851 << EC1->getInitVal().toString(10);
852 return false;
853 }
854 }
855
856 if (EC2 != EC2End) {
857 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
858 << Context.C2.getTypeDeclType(D2);
859 Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
860 << EC2->getDeclName()
861 << EC2->getInitVal().toString(10);
862 Context.Diag1(D1->getLocation(), diag::note_odr_missing_enumerator);
863 return false;
864 }
865
866 return true;
867}
868
869/// \brief Determine structural equivalence of two declarations.
870static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
871 Decl *D1, Decl *D2) {
872 // FIXME: Check for known structural equivalences via a callback of some sort.
873
Douglas Gregorb4964f72010-02-15 23:54:17 +0000874 // Check whether we already know that these two declarations are not
875 // structurally equivalent.
876 if (Context.NonEquivalentDecls.count(std::make_pair(D1->getCanonicalDecl(),
877 D2->getCanonicalDecl())))
878 return false;
879
Douglas Gregor3996e242010-02-15 22:01:00 +0000880 // Determine whether we've already produced a tentative equivalence for D1.
881 Decl *&EquivToD1 = Context.TentativeEquivalences[D1->getCanonicalDecl()];
882 if (EquivToD1)
883 return EquivToD1 == D2->getCanonicalDecl();
884
885 // Produce a tentative equivalence D1 <-> D2, which will be checked later.
886 EquivToD1 = D2->getCanonicalDecl();
887 Context.DeclsToCheck.push_back(D1->getCanonicalDecl());
888 return true;
889}
890
891bool StructuralEquivalenceContext::IsStructurallyEquivalent(Decl *D1,
892 Decl *D2) {
893 if (!::IsStructurallyEquivalent(*this, D1, D2))
894 return false;
895
896 return !Finish();
897}
898
899bool StructuralEquivalenceContext::IsStructurallyEquivalent(QualType T1,
900 QualType T2) {
901 if (!::IsStructurallyEquivalent(*this, T1, T2))
902 return false;
903
904 return !Finish();
905}
906
907bool StructuralEquivalenceContext::Finish() {
908 while (!DeclsToCheck.empty()) {
909 // Check the next declaration.
910 Decl *D1 = DeclsToCheck.front();
911 DeclsToCheck.pop_front();
912
913 Decl *D2 = TentativeEquivalences[D1];
914 assert(D2 && "Unrecorded tentative equivalence?");
915
Douglas Gregorb4964f72010-02-15 23:54:17 +0000916 bool Equivalent = true;
917
Douglas Gregor3996e242010-02-15 22:01:00 +0000918 // FIXME: Switch on all declaration kinds. For now, we're just going to
919 // check the obvious ones.
920 if (RecordDecl *Record1 = dyn_cast<RecordDecl>(D1)) {
921 if (RecordDecl *Record2 = dyn_cast<RecordDecl>(D2)) {
922 // Check for equivalent structure names.
923 IdentifierInfo *Name1 = Record1->getIdentifier();
924 if (!Name1 && Record1->getTypedefForAnonDecl())
925 Name1 = Record1->getTypedefForAnonDecl()->getIdentifier();
926 IdentifierInfo *Name2 = Record2->getIdentifier();
927 if (!Name2 && Record2->getTypedefForAnonDecl())
928 Name2 = Record2->getTypedefForAnonDecl()->getIdentifier();
Douglas Gregorb4964f72010-02-15 23:54:17 +0000929 if (!::IsStructurallyEquivalent(Name1, Name2) ||
930 !::IsStructurallyEquivalent(*this, Record1, Record2))
931 Equivalent = false;
Douglas Gregor3996e242010-02-15 22:01:00 +0000932 } else {
933 // Record/non-record mismatch.
Douglas Gregorb4964f72010-02-15 23:54:17 +0000934 Equivalent = false;
Douglas Gregor3996e242010-02-15 22:01:00 +0000935 }
Douglas Gregorb4964f72010-02-15 23:54:17 +0000936 } else if (EnumDecl *Enum1 = dyn_cast<EnumDecl>(D1)) {
Douglas Gregor3996e242010-02-15 22:01:00 +0000937 if (EnumDecl *Enum2 = dyn_cast<EnumDecl>(D2)) {
938 // Check for equivalent enum names.
939 IdentifierInfo *Name1 = Enum1->getIdentifier();
940 if (!Name1 && Enum1->getTypedefForAnonDecl())
941 Name1 = Enum1->getTypedefForAnonDecl()->getIdentifier();
942 IdentifierInfo *Name2 = Enum2->getIdentifier();
943 if (!Name2 && Enum2->getTypedefForAnonDecl())
944 Name2 = Enum2->getTypedefForAnonDecl()->getIdentifier();
Douglas Gregorb4964f72010-02-15 23:54:17 +0000945 if (!::IsStructurallyEquivalent(Name1, Name2) ||
946 !::IsStructurallyEquivalent(*this, Enum1, Enum2))
947 Equivalent = false;
Douglas Gregor3996e242010-02-15 22:01:00 +0000948 } else {
949 // Enum/non-enum mismatch
Douglas Gregorb4964f72010-02-15 23:54:17 +0000950 Equivalent = false;
Douglas Gregor3996e242010-02-15 22:01:00 +0000951 }
Douglas Gregorb4964f72010-02-15 23:54:17 +0000952 } else if (TypedefDecl *Typedef1 = dyn_cast<TypedefDecl>(D1)) {
Douglas Gregor3996e242010-02-15 22:01:00 +0000953 if (TypedefDecl *Typedef2 = dyn_cast<TypedefDecl>(D2)) {
954 if (!::IsStructurallyEquivalent(Typedef1->getIdentifier(),
Douglas Gregorb4964f72010-02-15 23:54:17 +0000955 Typedef2->getIdentifier()) ||
956 !::IsStructurallyEquivalent(*this,
Douglas Gregor3996e242010-02-15 22:01:00 +0000957 Typedef1->getUnderlyingType(),
958 Typedef2->getUnderlyingType()))
Douglas Gregorb4964f72010-02-15 23:54:17 +0000959 Equivalent = false;
Douglas Gregor3996e242010-02-15 22:01:00 +0000960 } else {
961 // Typedef/non-typedef mismatch.
Douglas Gregorb4964f72010-02-15 23:54:17 +0000962 Equivalent = false;
Douglas Gregor3996e242010-02-15 22:01:00 +0000963 }
Douglas Gregor3996e242010-02-15 22:01:00 +0000964 }
Douglas Gregorb4964f72010-02-15 23:54:17 +0000965
966 if (!Equivalent) {
967 // Note that these two declarations are not equivalent (and we already
968 // know about it).
969 NonEquivalentDecls.insert(std::make_pair(D1->getCanonicalDecl(),
970 D2->getCanonicalDecl()));
971 return true;
972 }
Douglas Gregor3996e242010-02-15 22:01:00 +0000973 // FIXME: Check other declaration kinds!
974 }
975
976 return false;
977}
978
979//----------------------------------------------------------------------------
Douglas Gregor96e578d2010-02-05 17:54:41 +0000980// Import Types
981//----------------------------------------------------------------------------
982
Douglas Gregore4c83e42010-02-09 22:48:33 +0000983QualType ASTNodeImporter::VisitType(Type *T) {
984 Importer.FromDiag(SourceLocation(), diag::err_unsupported_ast_node)
985 << T->getTypeClassName();
986 return QualType();
987}
988
Douglas Gregor96e578d2010-02-05 17:54:41 +0000989QualType ASTNodeImporter::VisitBuiltinType(BuiltinType *T) {
990 switch (T->getKind()) {
991 case BuiltinType::Void: return Importer.getToContext().VoidTy;
992 case BuiltinType::Bool: return Importer.getToContext().BoolTy;
993
994 case BuiltinType::Char_U:
995 // The context we're importing from has an unsigned 'char'. If we're
996 // importing into a context with a signed 'char', translate to
997 // 'unsigned char' instead.
998 if (Importer.getToContext().getLangOptions().CharIsSigned)
999 return Importer.getToContext().UnsignedCharTy;
1000
1001 return Importer.getToContext().CharTy;
1002
1003 case BuiltinType::UChar: return Importer.getToContext().UnsignedCharTy;
1004
1005 case BuiltinType::Char16:
1006 // FIXME: Make sure that the "to" context supports C++!
1007 return Importer.getToContext().Char16Ty;
1008
1009 case BuiltinType::Char32:
1010 // FIXME: Make sure that the "to" context supports C++!
1011 return Importer.getToContext().Char32Ty;
1012
1013 case BuiltinType::UShort: return Importer.getToContext().UnsignedShortTy;
1014 case BuiltinType::UInt: return Importer.getToContext().UnsignedIntTy;
1015 case BuiltinType::ULong: return Importer.getToContext().UnsignedLongTy;
1016 case BuiltinType::ULongLong:
1017 return Importer.getToContext().UnsignedLongLongTy;
1018 case BuiltinType::UInt128: return Importer.getToContext().UnsignedInt128Ty;
1019
1020 case BuiltinType::Char_S:
1021 // The context we're importing from has an unsigned 'char'. If we're
1022 // importing into a context with a signed 'char', translate to
1023 // 'unsigned char' instead.
1024 if (!Importer.getToContext().getLangOptions().CharIsSigned)
1025 return Importer.getToContext().SignedCharTy;
1026
1027 return Importer.getToContext().CharTy;
1028
1029 case BuiltinType::SChar: return Importer.getToContext().SignedCharTy;
1030 case BuiltinType::WChar:
1031 // FIXME: If not in C++, shall we translate to the C equivalent of
1032 // wchar_t?
1033 return Importer.getToContext().WCharTy;
1034
1035 case BuiltinType::Short : return Importer.getToContext().ShortTy;
1036 case BuiltinType::Int : return Importer.getToContext().IntTy;
1037 case BuiltinType::Long : return Importer.getToContext().LongTy;
1038 case BuiltinType::LongLong : return Importer.getToContext().LongLongTy;
1039 case BuiltinType::Int128 : return Importer.getToContext().Int128Ty;
1040 case BuiltinType::Float: return Importer.getToContext().FloatTy;
1041 case BuiltinType::Double: return Importer.getToContext().DoubleTy;
1042 case BuiltinType::LongDouble: return Importer.getToContext().LongDoubleTy;
1043
1044 case BuiltinType::NullPtr:
1045 // FIXME: Make sure that the "to" context supports C++0x!
1046 return Importer.getToContext().NullPtrTy;
1047
1048 case BuiltinType::Overload: return Importer.getToContext().OverloadTy;
1049 case BuiltinType::Dependent: return Importer.getToContext().DependentTy;
1050 case BuiltinType::UndeducedAuto:
1051 // FIXME: Make sure that the "to" context supports C++0x!
1052 return Importer.getToContext().UndeducedAutoTy;
1053
1054 case BuiltinType::ObjCId:
1055 // FIXME: Make sure that the "to" context supports Objective-C!
1056 return Importer.getToContext().ObjCBuiltinIdTy;
1057
1058 case BuiltinType::ObjCClass:
1059 return Importer.getToContext().ObjCBuiltinClassTy;
1060
1061 case BuiltinType::ObjCSel:
1062 return Importer.getToContext().ObjCBuiltinSelTy;
1063 }
1064
1065 return QualType();
1066}
1067
1068QualType ASTNodeImporter::VisitComplexType(ComplexType *T) {
1069 QualType ToElementType = Importer.Import(T->getElementType());
1070 if (ToElementType.isNull())
1071 return QualType();
1072
1073 return Importer.getToContext().getComplexType(ToElementType);
1074}
1075
1076QualType ASTNodeImporter::VisitPointerType(PointerType *T) {
1077 QualType ToPointeeType = Importer.Import(T->getPointeeType());
1078 if (ToPointeeType.isNull())
1079 return QualType();
1080
1081 return Importer.getToContext().getPointerType(ToPointeeType);
1082}
1083
1084QualType ASTNodeImporter::VisitBlockPointerType(BlockPointerType *T) {
1085 // FIXME: Check for blocks support in "to" context.
1086 QualType ToPointeeType = Importer.Import(T->getPointeeType());
1087 if (ToPointeeType.isNull())
1088 return QualType();
1089
1090 return Importer.getToContext().getBlockPointerType(ToPointeeType);
1091}
1092
1093QualType ASTNodeImporter::VisitLValueReferenceType(LValueReferenceType *T) {
1094 // FIXME: Check for C++ support in "to" context.
1095 QualType ToPointeeType = Importer.Import(T->getPointeeTypeAsWritten());
1096 if (ToPointeeType.isNull())
1097 return QualType();
1098
1099 return Importer.getToContext().getLValueReferenceType(ToPointeeType);
1100}
1101
1102QualType ASTNodeImporter::VisitRValueReferenceType(RValueReferenceType *T) {
1103 // FIXME: Check for C++0x support in "to" context.
1104 QualType ToPointeeType = Importer.Import(T->getPointeeTypeAsWritten());
1105 if (ToPointeeType.isNull())
1106 return QualType();
1107
1108 return Importer.getToContext().getRValueReferenceType(ToPointeeType);
1109}
1110
1111QualType ASTNodeImporter::VisitMemberPointerType(MemberPointerType *T) {
1112 // FIXME: Check for C++ support in "to" context.
1113 QualType ToPointeeType = Importer.Import(T->getPointeeType());
1114 if (ToPointeeType.isNull())
1115 return QualType();
1116
1117 QualType ClassType = Importer.Import(QualType(T->getClass(), 0));
1118 return Importer.getToContext().getMemberPointerType(ToPointeeType,
1119 ClassType.getTypePtr());
1120}
1121
1122QualType ASTNodeImporter::VisitConstantArrayType(ConstantArrayType *T) {
1123 QualType ToElementType = Importer.Import(T->getElementType());
1124 if (ToElementType.isNull())
1125 return QualType();
1126
1127 return Importer.getToContext().getConstantArrayType(ToElementType,
1128 T->getSize(),
1129 T->getSizeModifier(),
1130 T->getIndexTypeCVRQualifiers());
1131}
1132
1133QualType ASTNodeImporter::VisitIncompleteArrayType(IncompleteArrayType *T) {
1134 QualType ToElementType = Importer.Import(T->getElementType());
1135 if (ToElementType.isNull())
1136 return QualType();
1137
1138 return Importer.getToContext().getIncompleteArrayType(ToElementType,
1139 T->getSizeModifier(),
1140 T->getIndexTypeCVRQualifiers());
1141}
1142
1143QualType ASTNodeImporter::VisitVariableArrayType(VariableArrayType *T) {
1144 QualType ToElementType = Importer.Import(T->getElementType());
1145 if (ToElementType.isNull())
1146 return QualType();
1147
1148 Expr *Size = Importer.Import(T->getSizeExpr());
1149 if (!Size)
1150 return QualType();
1151
1152 SourceRange Brackets = Importer.Import(T->getBracketsRange());
1153 return Importer.getToContext().getVariableArrayType(ToElementType, Size,
1154 T->getSizeModifier(),
1155 T->getIndexTypeCVRQualifiers(),
1156 Brackets);
1157}
1158
1159QualType ASTNodeImporter::VisitVectorType(VectorType *T) {
1160 QualType ToElementType = Importer.Import(T->getElementType());
1161 if (ToElementType.isNull())
1162 return QualType();
1163
1164 return Importer.getToContext().getVectorType(ToElementType,
1165 T->getNumElements(),
1166 T->isAltiVec(),
1167 T->isPixel());
1168}
1169
1170QualType ASTNodeImporter::VisitExtVectorType(ExtVectorType *T) {
1171 QualType ToElementType = Importer.Import(T->getElementType());
1172 if (ToElementType.isNull())
1173 return QualType();
1174
1175 return Importer.getToContext().getExtVectorType(ToElementType,
1176 T->getNumElements());
1177}
1178
1179QualType ASTNodeImporter::VisitFunctionNoProtoType(FunctionNoProtoType *T) {
1180 // FIXME: What happens if we're importing a function without a prototype
1181 // into C++? Should we make it variadic?
1182 QualType ToResultType = Importer.Import(T->getResultType());
1183 if (ToResultType.isNull())
1184 return QualType();
1185
1186 return Importer.getToContext().getFunctionNoProtoType(ToResultType,
1187 T->getNoReturnAttr(),
1188 T->getCallConv());
1189}
1190
1191QualType ASTNodeImporter::VisitFunctionProtoType(FunctionProtoType *T) {
1192 QualType ToResultType = Importer.Import(T->getResultType());
1193 if (ToResultType.isNull())
1194 return QualType();
1195
1196 // Import argument types
1197 llvm::SmallVector<QualType, 4> ArgTypes;
1198 for (FunctionProtoType::arg_type_iterator A = T->arg_type_begin(),
1199 AEnd = T->arg_type_end();
1200 A != AEnd; ++A) {
1201 QualType ArgType = Importer.Import(*A);
1202 if (ArgType.isNull())
1203 return QualType();
1204 ArgTypes.push_back(ArgType);
1205 }
1206
1207 // Import exception types
1208 llvm::SmallVector<QualType, 4> ExceptionTypes;
1209 for (FunctionProtoType::exception_iterator E = T->exception_begin(),
1210 EEnd = T->exception_end();
1211 E != EEnd; ++E) {
1212 QualType ExceptionType = Importer.Import(*E);
1213 if (ExceptionType.isNull())
1214 return QualType();
1215 ExceptionTypes.push_back(ExceptionType);
1216 }
1217
1218 return Importer.getToContext().getFunctionType(ToResultType, ArgTypes.data(),
1219 ArgTypes.size(),
1220 T->isVariadic(),
1221 T->getTypeQuals(),
1222 T->hasExceptionSpec(),
1223 T->hasAnyExceptionSpec(),
1224 ExceptionTypes.size(),
1225 ExceptionTypes.data(),
1226 T->getNoReturnAttr(),
1227 T->getCallConv());
1228}
1229
1230QualType ASTNodeImporter::VisitTypedefType(TypedefType *T) {
1231 TypedefDecl *ToDecl
1232 = dyn_cast_or_null<TypedefDecl>(Importer.Import(T->getDecl()));
1233 if (!ToDecl)
1234 return QualType();
1235
1236 return Importer.getToContext().getTypeDeclType(ToDecl);
1237}
1238
1239QualType ASTNodeImporter::VisitTypeOfExprType(TypeOfExprType *T) {
1240 Expr *ToExpr = Importer.Import(T->getUnderlyingExpr());
1241 if (!ToExpr)
1242 return QualType();
1243
1244 return Importer.getToContext().getTypeOfExprType(ToExpr);
1245}
1246
1247QualType ASTNodeImporter::VisitTypeOfType(TypeOfType *T) {
1248 QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType());
1249 if (ToUnderlyingType.isNull())
1250 return QualType();
1251
1252 return Importer.getToContext().getTypeOfType(ToUnderlyingType);
1253}
1254
1255QualType ASTNodeImporter::VisitDecltypeType(DecltypeType *T) {
1256 Expr *ToExpr = Importer.Import(T->getUnderlyingExpr());
1257 if (!ToExpr)
1258 return QualType();
1259
1260 return Importer.getToContext().getDecltypeType(ToExpr);
1261}
1262
1263QualType ASTNodeImporter::VisitRecordType(RecordType *T) {
1264 RecordDecl *ToDecl
1265 = dyn_cast_or_null<RecordDecl>(Importer.Import(T->getDecl()));
1266 if (!ToDecl)
1267 return QualType();
1268
1269 return Importer.getToContext().getTagDeclType(ToDecl);
1270}
1271
1272QualType ASTNodeImporter::VisitEnumType(EnumType *T) {
1273 EnumDecl *ToDecl
1274 = dyn_cast_or_null<EnumDecl>(Importer.Import(T->getDecl()));
1275 if (!ToDecl)
1276 return QualType();
1277
1278 return Importer.getToContext().getTagDeclType(ToDecl);
1279}
1280
1281QualType ASTNodeImporter::VisitElaboratedType(ElaboratedType *T) {
1282 QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType());
1283 if (ToUnderlyingType.isNull())
1284 return QualType();
1285
1286 return Importer.getToContext().getElaboratedType(ToUnderlyingType,
1287 T->getTagKind());
1288}
1289
1290QualType ASTNodeImporter::VisitQualifiedNameType(QualifiedNameType *T) {
1291 NestedNameSpecifier *ToQualifier = Importer.Import(T->getQualifier());
1292 if (!ToQualifier)
1293 return QualType();
1294
1295 QualType ToNamedType = Importer.Import(T->getNamedType());
1296 if (ToNamedType.isNull())
1297 return QualType();
1298
1299 return Importer.getToContext().getQualifiedNameType(ToQualifier, ToNamedType);
1300}
1301
1302QualType ASTNodeImporter::VisitObjCInterfaceType(ObjCInterfaceType *T) {
1303 ObjCInterfaceDecl *Class
1304 = dyn_cast_or_null<ObjCInterfaceDecl>(Importer.Import(T->getDecl()));
1305 if (!Class)
1306 return QualType();
1307
1308 llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
1309 for (ObjCInterfaceType::qual_iterator P = T->qual_begin(),
1310 PEnd = T->qual_end();
1311 P != PEnd; ++P) {
1312 ObjCProtocolDecl *Protocol
1313 = dyn_cast_or_null<ObjCProtocolDecl>(Importer.Import(*P));
1314 if (!Protocol)
1315 return QualType();
1316 Protocols.push_back(Protocol);
1317 }
1318
1319 return Importer.getToContext().getObjCInterfaceType(Class,
1320 Protocols.data(),
1321 Protocols.size());
1322}
1323
1324QualType ASTNodeImporter::VisitObjCObjectPointerType(ObjCObjectPointerType *T) {
1325 QualType ToPointeeType = Importer.Import(T->getPointeeType());
1326 if (ToPointeeType.isNull())
1327 return QualType();
1328
1329 llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
1330 for (ObjCObjectPointerType::qual_iterator P = T->qual_begin(),
1331 PEnd = T->qual_end();
1332 P != PEnd; ++P) {
1333 ObjCProtocolDecl *Protocol
1334 = dyn_cast_or_null<ObjCProtocolDecl>(Importer.Import(*P));
1335 if (!Protocol)
1336 return QualType();
1337 Protocols.push_back(Protocol);
1338 }
1339
1340 return Importer.getToContext().getObjCObjectPointerType(ToPointeeType,
1341 Protocols.data(),
1342 Protocols.size());
1343}
1344
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001345//----------------------------------------------------------------------------
1346// Import Declarations
1347//----------------------------------------------------------------------------
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001348bool ASTNodeImporter::ImportDeclParts(NamedDecl *D, DeclContext *&DC,
1349 DeclContext *&LexicalDC,
1350 DeclarationName &Name,
1351 SourceLocation &Loc) {
1352 // Import the context of this declaration.
1353 DC = Importer.ImportContext(D->getDeclContext());
1354 if (!DC)
1355 return true;
1356
1357 LexicalDC = DC;
1358 if (D->getDeclContext() != D->getLexicalDeclContext()) {
1359 LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
1360 if (!LexicalDC)
1361 return true;
1362 }
1363
1364 // Import the name of this declaration.
1365 Name = Importer.Import(D->getDeclName());
1366 if (D->getDeclName() && !Name)
1367 return true;
1368
1369 // Import the location of this declaration.
1370 Loc = Importer.Import(D->getLocation());
1371 return false;
1372}
1373
Douglas Gregor5c73e912010-02-11 00:48:18 +00001374bool ASTNodeImporter::IsStructuralMatch(RecordDecl *FromRecord,
Douglas Gregor3996e242010-02-15 22:01:00 +00001375 RecordDecl *ToRecord) {
Benjamin Kramer26d19c52010-02-18 13:02:13 +00001376 StructuralEquivalenceContext Ctx(Importer.getFromContext(),
Douglas Gregor3996e242010-02-15 22:01:00 +00001377 Importer.getToContext(),
Douglas Gregorb4964f72010-02-15 23:54:17 +00001378 Importer.getDiags(),
1379 Importer.getNonEquivalentDecls());
Benjamin Kramer26d19c52010-02-18 13:02:13 +00001380 return Ctx.IsStructurallyEquivalent(FromRecord, ToRecord);
Douglas Gregor5c73e912010-02-11 00:48:18 +00001381}
1382
Douglas Gregor98c10182010-02-12 22:17:39 +00001383bool ASTNodeImporter::IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToEnum) {
Benjamin Kramer26d19c52010-02-18 13:02:13 +00001384 StructuralEquivalenceContext Ctx(Importer.getFromContext(),
Douglas Gregor3996e242010-02-15 22:01:00 +00001385 Importer.getToContext(),
Douglas Gregorb4964f72010-02-15 23:54:17 +00001386 Importer.getDiags(),
1387 Importer.getNonEquivalentDecls());
Benjamin Kramer26d19c52010-02-18 13:02:13 +00001388 return Ctx.IsStructurallyEquivalent(FromEnum, ToEnum);
Douglas Gregor98c10182010-02-12 22:17:39 +00001389}
1390
Douglas Gregore4c83e42010-02-09 22:48:33 +00001391Decl *ASTNodeImporter::VisitDecl(Decl *D) {
Douglas Gregor811663e2010-02-10 00:15:17 +00001392 Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node)
Douglas Gregore4c83e42010-02-09 22:48:33 +00001393 << D->getDeclKindName();
1394 return 0;
1395}
1396
Douglas Gregor5fa74c32010-02-10 21:10:29 +00001397Decl *ASTNodeImporter::VisitTypedefDecl(TypedefDecl *D) {
1398 // Import the major distinguishing characteristics of this typedef.
1399 DeclContext *DC, *LexicalDC;
1400 DeclarationName Name;
1401 SourceLocation Loc;
1402 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
1403 return 0;
1404
Douglas Gregor5fa74c32010-02-10 21:10:29 +00001405 // If this typedef is not in block scope, determine whether we've
1406 // seen a typedef with the same name (that we can merge with) or any
1407 // other entity by that name (which name lookup could conflict with).
1408 if (!DC->isFunctionOrMethod()) {
1409 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
1410 unsigned IDNS = Decl::IDNS_Ordinary;
1411 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
1412 Lookup.first != Lookup.second;
1413 ++Lookup.first) {
1414 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
1415 continue;
1416 if (TypedefDecl *FoundTypedef = dyn_cast<TypedefDecl>(*Lookup.first)) {
Douglas Gregorb4964f72010-02-15 23:54:17 +00001417 if (Importer.IsStructurallyEquivalent(D->getUnderlyingType(),
1418 FoundTypedef->getUnderlyingType()))
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001419 return Importer.Imported(D, FoundTypedef);
Douglas Gregor5fa74c32010-02-10 21:10:29 +00001420 }
1421
1422 ConflictingDecls.push_back(*Lookup.first);
1423 }
1424
1425 if (!ConflictingDecls.empty()) {
1426 Name = Importer.HandleNameConflict(Name, DC, IDNS,
1427 ConflictingDecls.data(),
1428 ConflictingDecls.size());
1429 if (!Name)
1430 return 0;
1431 }
1432 }
1433
Douglas Gregorb4964f72010-02-15 23:54:17 +00001434 // Import the underlying type of this typedef;
1435 QualType T = Importer.Import(D->getUnderlyingType());
1436 if (T.isNull())
1437 return 0;
1438
Douglas Gregor5fa74c32010-02-10 21:10:29 +00001439 // Create the new typedef node.
1440 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
1441 TypedefDecl *ToTypedef = TypedefDecl::Create(Importer.getToContext(), DC,
1442 Loc, Name.getAsIdentifierInfo(),
1443 TInfo);
1444 ToTypedef->setLexicalDeclContext(LexicalDC);
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001445 Importer.Imported(D, ToTypedef);
Douglas Gregor5fa74c32010-02-10 21:10:29 +00001446 LexicalDC->addDecl(ToTypedef);
Douglas Gregorb4964f72010-02-15 23:54:17 +00001447
Douglas Gregor5fa74c32010-02-10 21:10:29 +00001448 return ToTypedef;
1449}
1450
Douglas Gregor98c10182010-02-12 22:17:39 +00001451Decl *ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
1452 // Import the major distinguishing characteristics of this enum.
1453 DeclContext *DC, *LexicalDC;
1454 DeclarationName Name;
1455 SourceLocation Loc;
1456 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
1457 return 0;
1458
1459 // Figure out what enum name we're looking for.
1460 unsigned IDNS = Decl::IDNS_Tag;
1461 DeclarationName SearchName = Name;
1462 if (!SearchName && D->getTypedefForAnonDecl()) {
1463 SearchName = Importer.Import(D->getTypedefForAnonDecl()->getDeclName());
1464 IDNS = Decl::IDNS_Ordinary;
1465 } else if (Importer.getToContext().getLangOptions().CPlusPlus)
1466 IDNS |= Decl::IDNS_Ordinary;
1467
1468 // We may already have an enum of the same name; try to find and match it.
1469 if (!DC->isFunctionOrMethod() && SearchName) {
1470 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
1471 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
1472 Lookup.first != Lookup.second;
1473 ++Lookup.first) {
1474 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
1475 continue;
1476
1477 Decl *Found = *Lookup.first;
1478 if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(Found)) {
1479 if (const TagType *Tag = Typedef->getUnderlyingType()->getAs<TagType>())
1480 Found = Tag->getDecl();
1481 }
1482
1483 if (EnumDecl *FoundEnum = dyn_cast<EnumDecl>(Found)) {
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001484 if (IsStructuralMatch(D, FoundEnum))
1485 return Importer.Imported(D, FoundEnum);
Douglas Gregor98c10182010-02-12 22:17:39 +00001486 }
1487
1488 ConflictingDecls.push_back(*Lookup.first);
1489 }
1490
1491 if (!ConflictingDecls.empty()) {
1492 Name = Importer.HandleNameConflict(Name, DC, IDNS,
1493 ConflictingDecls.data(),
1494 ConflictingDecls.size());
1495 }
1496 }
1497
1498 // Create the enum declaration.
Douglas Gregor3996e242010-02-15 22:01:00 +00001499 EnumDecl *D2 = EnumDecl::Create(Importer.getToContext(), DC, Loc,
Douglas Gregor98c10182010-02-12 22:17:39 +00001500 Name.getAsIdentifierInfo(),
1501 Importer.Import(D->getTagKeywordLoc()),
1502 0);
Douglas Gregor3996e242010-02-15 22:01:00 +00001503 D2->setLexicalDeclContext(LexicalDC);
1504 Importer.Imported(D, D2);
1505 LexicalDC->addDecl(D2);
Douglas Gregor98c10182010-02-12 22:17:39 +00001506
1507 // Import the integer type.
1508 QualType ToIntegerType = Importer.Import(D->getIntegerType());
1509 if (ToIntegerType.isNull())
1510 return 0;
Douglas Gregor3996e242010-02-15 22:01:00 +00001511 D2->setIntegerType(ToIntegerType);
Douglas Gregor98c10182010-02-12 22:17:39 +00001512
1513 // Import the definition
1514 if (D->isDefinition()) {
1515 QualType T = Importer.Import(Importer.getFromContext().getTypeDeclType(D));
1516 if (T.isNull())
1517 return 0;
1518
1519 QualType ToPromotionType = Importer.Import(D->getPromotionType());
1520 if (ToPromotionType.isNull())
1521 return 0;
1522
Douglas Gregor3996e242010-02-15 22:01:00 +00001523 D2->startDefinition();
Douglas Gregor98c10182010-02-12 22:17:39 +00001524 for (DeclContext::decl_iterator FromMem = D->decls_begin(),
1525 FromMemEnd = D->decls_end();
1526 FromMem != FromMemEnd;
1527 ++FromMem)
1528 Importer.Import(*FromMem);
1529
Douglas Gregor3996e242010-02-15 22:01:00 +00001530 D2->completeDefinition(T, ToPromotionType);
Douglas Gregor98c10182010-02-12 22:17:39 +00001531 }
1532
Douglas Gregor3996e242010-02-15 22:01:00 +00001533 return D2;
Douglas Gregor98c10182010-02-12 22:17:39 +00001534}
1535
Douglas Gregor5c73e912010-02-11 00:48:18 +00001536Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
1537 // If this record has a definition in the translation unit we're coming from,
1538 // but this particular declaration is not that definition, import the
1539 // definition and map to that.
Douglas Gregor0a5a2212010-02-11 01:04:33 +00001540 TagDecl *Definition = D->getDefinition();
Douglas Gregor5c73e912010-02-11 00:48:18 +00001541 if (Definition && Definition != D) {
1542 Decl *ImportedDef = Importer.Import(Definition);
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001543 if (!ImportedDef)
1544 return 0;
1545
1546 return Importer.Imported(D, ImportedDef);
Douglas Gregor5c73e912010-02-11 00:48:18 +00001547 }
1548
1549 // Import the major distinguishing characteristics of this record.
1550 DeclContext *DC, *LexicalDC;
1551 DeclarationName Name;
1552 SourceLocation Loc;
1553 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
1554 return 0;
1555
1556 // Figure out what structure name we're looking for.
1557 unsigned IDNS = Decl::IDNS_Tag;
1558 DeclarationName SearchName = Name;
1559 if (!SearchName && D->getTypedefForAnonDecl()) {
1560 SearchName = Importer.Import(D->getTypedefForAnonDecl()->getDeclName());
1561 IDNS = Decl::IDNS_Ordinary;
1562 } else if (Importer.getToContext().getLangOptions().CPlusPlus)
1563 IDNS |= Decl::IDNS_Ordinary;
1564
1565 // We may already have a record of the same name; try to find and match it.
Douglas Gregor25791052010-02-12 00:09:27 +00001566 RecordDecl *AdoptDecl = 0;
Douglas Gregor5c73e912010-02-11 00:48:18 +00001567 if (!DC->isFunctionOrMethod() && SearchName) {
1568 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
1569 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
1570 Lookup.first != Lookup.second;
1571 ++Lookup.first) {
1572 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
1573 continue;
1574
1575 Decl *Found = *Lookup.first;
1576 if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(Found)) {
1577 if (const TagType *Tag = Typedef->getUnderlyingType()->getAs<TagType>())
1578 Found = Tag->getDecl();
1579 }
1580
1581 if (RecordDecl *FoundRecord = dyn_cast<RecordDecl>(Found)) {
Douglas Gregor25791052010-02-12 00:09:27 +00001582 if (RecordDecl *FoundDef = FoundRecord->getDefinition()) {
1583 if (!D->isDefinition() || IsStructuralMatch(D, FoundDef)) {
1584 // The record types structurally match, or the "from" translation
1585 // unit only had a forward declaration anyway; call it the same
1586 // function.
1587 // FIXME: For C++, we should also merge methods here.
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001588 return Importer.Imported(D, FoundDef);
Douglas Gregor25791052010-02-12 00:09:27 +00001589 }
1590 } else {
1591 // We have a forward declaration of this type, so adopt that forward
1592 // declaration rather than building a new one.
1593 AdoptDecl = FoundRecord;
1594 continue;
1595 }
Douglas Gregor5c73e912010-02-11 00:48:18 +00001596 }
1597
1598 ConflictingDecls.push_back(*Lookup.first);
1599 }
1600
1601 if (!ConflictingDecls.empty()) {
1602 Name = Importer.HandleNameConflict(Name, DC, IDNS,
1603 ConflictingDecls.data(),
1604 ConflictingDecls.size());
1605 }
1606 }
1607
1608 // Create the record declaration.
Douglas Gregor3996e242010-02-15 22:01:00 +00001609 RecordDecl *D2 = AdoptDecl;
1610 if (!D2) {
1611 if (CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(D)) {
1612 CXXRecordDecl *D2CXX = CXXRecordDecl::Create(Importer.getToContext(),
Douglas Gregor25791052010-02-12 00:09:27 +00001613 D->getTagKind(),
1614 DC, Loc,
1615 Name.getAsIdentifierInfo(),
Douglas Gregor5c73e912010-02-11 00:48:18 +00001616 Importer.Import(D->getTagKeywordLoc()));
Douglas Gregor3996e242010-02-15 22:01:00 +00001617 D2 = D2CXX;
Douglas Gregor25791052010-02-12 00:09:27 +00001618
1619 if (D->isDefinition()) {
1620 // Add base classes.
1621 llvm::SmallVector<CXXBaseSpecifier *, 4> Bases;
1622 for (CXXRecordDecl::base_class_iterator
Douglas Gregor3996e242010-02-15 22:01:00 +00001623 Base1 = D1CXX->bases_begin(),
1624 FromBaseEnd = D1CXX->bases_end();
1625 Base1 != FromBaseEnd;
1626 ++Base1) {
1627 QualType T = Importer.Import(Base1->getType());
Douglas Gregor25791052010-02-12 00:09:27 +00001628 if (T.isNull())
1629 return 0;
1630
1631 Bases.push_back(
1632 new (Importer.getToContext())
Douglas Gregor3996e242010-02-15 22:01:00 +00001633 CXXBaseSpecifier(Importer.Import(Base1->getSourceRange()),
1634 Base1->isVirtual(),
1635 Base1->isBaseOfClass(),
1636 Base1->getAccessSpecifierAsWritten(),
Douglas Gregor5c73e912010-02-11 00:48:18 +00001637 T));
Douglas Gregor25791052010-02-12 00:09:27 +00001638 }
1639 if (!Bases.empty())
Douglas Gregor3996e242010-02-15 22:01:00 +00001640 D2CXX->setBases(Bases.data(), Bases.size());
Douglas Gregor5c73e912010-02-11 00:48:18 +00001641 }
Douglas Gregor25791052010-02-12 00:09:27 +00001642 } else {
Douglas Gregor3996e242010-02-15 22:01:00 +00001643 D2 = RecordDecl::Create(Importer.getToContext(), D->getTagKind(),
Douglas Gregor25791052010-02-12 00:09:27 +00001644 DC, Loc,
1645 Name.getAsIdentifierInfo(),
1646 Importer.Import(D->getTagKeywordLoc()));
Douglas Gregor5c73e912010-02-11 00:48:18 +00001647 }
Douglas Gregor3996e242010-02-15 22:01:00 +00001648 D2->setLexicalDeclContext(LexicalDC);
1649 LexicalDC->addDecl(D2);
Douglas Gregor5c73e912010-02-11 00:48:18 +00001650 }
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001651
Douglas Gregor3996e242010-02-15 22:01:00 +00001652 Importer.Imported(D, D2);
Douglas Gregor25791052010-02-12 00:09:27 +00001653
Douglas Gregor5c73e912010-02-11 00:48:18 +00001654 if (D->isDefinition()) {
Douglas Gregor3996e242010-02-15 22:01:00 +00001655 D2->startDefinition();
Douglas Gregor5c73e912010-02-11 00:48:18 +00001656 for (DeclContext::decl_iterator FromMem = D->decls_begin(),
1657 FromMemEnd = D->decls_end();
1658 FromMem != FromMemEnd;
1659 ++FromMem)
1660 Importer.Import(*FromMem);
1661
Douglas Gregor3996e242010-02-15 22:01:00 +00001662 D2->completeDefinition();
Douglas Gregor5c73e912010-02-11 00:48:18 +00001663 }
1664
Douglas Gregor3996e242010-02-15 22:01:00 +00001665 return D2;
Douglas Gregor5c73e912010-02-11 00:48:18 +00001666}
1667
Douglas Gregor98c10182010-02-12 22:17:39 +00001668Decl *ASTNodeImporter::VisitEnumConstantDecl(EnumConstantDecl *D) {
1669 // Import the major distinguishing characteristics of this enumerator.
1670 DeclContext *DC, *LexicalDC;
1671 DeclarationName Name;
1672 SourceLocation Loc;
Douglas Gregorb4964f72010-02-15 23:54:17 +00001673 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
Douglas Gregor98c10182010-02-12 22:17:39 +00001674 return 0;
Douglas Gregorb4964f72010-02-15 23:54:17 +00001675
1676 QualType T = Importer.Import(D->getType());
1677 if (T.isNull())
1678 return 0;
1679
Douglas Gregor98c10182010-02-12 22:17:39 +00001680 // Determine whether there are any other declarations with the same name and
1681 // in the same context.
1682 if (!LexicalDC->isFunctionOrMethod()) {
1683 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
1684 unsigned IDNS = Decl::IDNS_Ordinary;
1685 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
1686 Lookup.first != Lookup.second;
1687 ++Lookup.first) {
1688 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
1689 continue;
1690
1691 ConflictingDecls.push_back(*Lookup.first);
1692 }
1693
1694 if (!ConflictingDecls.empty()) {
1695 Name = Importer.HandleNameConflict(Name, DC, IDNS,
1696 ConflictingDecls.data(),
1697 ConflictingDecls.size());
1698 if (!Name)
1699 return 0;
1700 }
1701 }
1702
1703 Expr *Init = Importer.Import(D->getInitExpr());
1704 if (D->getInitExpr() && !Init)
1705 return 0;
1706
1707 EnumConstantDecl *ToEnumerator
1708 = EnumConstantDecl::Create(Importer.getToContext(), cast<EnumDecl>(DC), Loc,
1709 Name.getAsIdentifierInfo(), T,
1710 Init, D->getInitVal());
1711 ToEnumerator->setLexicalDeclContext(LexicalDC);
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001712 Importer.Imported(D, ToEnumerator);
Douglas Gregor98c10182010-02-12 22:17:39 +00001713 LexicalDC->addDecl(ToEnumerator);
1714 return ToEnumerator;
1715}
Douglas Gregor5c73e912010-02-11 00:48:18 +00001716
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001717Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
1718 // Import the major distinguishing characteristics of this function.
1719 DeclContext *DC, *LexicalDC;
1720 DeclarationName Name;
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001721 SourceLocation Loc;
Douglas Gregorb4964f72010-02-15 23:54:17 +00001722 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001723 return 0;
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001724
1725 // Try to find a function in our own ("to") context with the same name, same
1726 // type, and in the same context as the function we're importing.
1727 if (!LexicalDC->isFunctionOrMethod()) {
1728 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
1729 unsigned IDNS = Decl::IDNS_Ordinary;
1730 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
1731 Lookup.first != Lookup.second;
1732 ++Lookup.first) {
1733 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
1734 continue;
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001735
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001736 if (FunctionDecl *FoundFunction = dyn_cast<FunctionDecl>(*Lookup.first)) {
1737 if (isExternalLinkage(FoundFunction->getLinkage()) &&
1738 isExternalLinkage(D->getLinkage())) {
Douglas Gregorb4964f72010-02-15 23:54:17 +00001739 if (Importer.IsStructurallyEquivalent(D->getType(),
1740 FoundFunction->getType())) {
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001741 // FIXME: Actually try to merge the body and other attributes.
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001742 return Importer.Imported(D, FoundFunction);
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001743 }
1744
1745 // FIXME: Check for overloading more carefully, e.g., by boosting
1746 // Sema::IsOverload out to the AST library.
1747
1748 // Function overloading is okay in C++.
1749 if (Importer.getToContext().getLangOptions().CPlusPlus)
1750 continue;
1751
1752 // Complain about inconsistent function types.
1753 Importer.ToDiag(Loc, diag::err_odr_function_type_inconsistent)
Douglas Gregorb4964f72010-02-15 23:54:17 +00001754 << Name << D->getType() << FoundFunction->getType();
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001755 Importer.ToDiag(FoundFunction->getLocation(),
1756 diag::note_odr_value_here)
1757 << FoundFunction->getType();
1758 }
1759 }
1760
1761 ConflictingDecls.push_back(*Lookup.first);
1762 }
1763
1764 if (!ConflictingDecls.empty()) {
1765 Name = Importer.HandleNameConflict(Name, DC, IDNS,
1766 ConflictingDecls.data(),
1767 ConflictingDecls.size());
1768 if (!Name)
1769 return 0;
1770 }
Douglas Gregor62d311f2010-02-09 19:21:46 +00001771 }
Douglas Gregorb4964f72010-02-15 23:54:17 +00001772
1773 // Import the type.
1774 QualType T = Importer.Import(D->getType());
1775 if (T.isNull())
1776 return 0;
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001777
1778 // Import the function parameters.
1779 llvm::SmallVector<ParmVarDecl *, 8> Parameters;
1780 for (FunctionDecl::param_iterator P = D->param_begin(), PEnd = D->param_end();
1781 P != PEnd; ++P) {
1782 ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(*P));
1783 if (!ToP)
1784 return 0;
1785
1786 Parameters.push_back(ToP);
1787 }
1788
1789 // Create the imported function.
1790 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
Douglas Gregor43f54792010-02-17 02:12:47 +00001791 FunctionDecl *ToFunction
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001792 = FunctionDecl::Create(Importer.getToContext(), DC, Loc,
1793 Name, T, TInfo, D->getStorageClass(),
1794 D->isInlineSpecified(),
1795 D->hasWrittenPrototype());
Douglas Gregor43f54792010-02-17 02:12:47 +00001796 ToFunction->setLexicalDeclContext(LexicalDC);
1797 Importer.Imported(D, ToFunction);
1798 LexicalDC->addDecl(ToFunction);
Douglas Gregor62d311f2010-02-09 19:21:46 +00001799
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001800 // Set the parameters.
1801 for (unsigned I = 0, N = Parameters.size(); I != N; ++I) {
Douglas Gregor43f54792010-02-17 02:12:47 +00001802 Parameters[I]->setOwningFunction(ToFunction);
1803 ToFunction->addDecl(Parameters[I]);
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001804 }
Douglas Gregor43f54792010-02-17 02:12:47 +00001805 ToFunction->setParams(Parameters.data(), Parameters.size());
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001806
1807 // FIXME: Other bits to merge?
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001808
Douglas Gregor43f54792010-02-17 02:12:47 +00001809 return ToFunction;
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001810}
1811
Douglas Gregor5c73e912010-02-11 00:48:18 +00001812Decl *ASTNodeImporter::VisitFieldDecl(FieldDecl *D) {
1813 // Import the major distinguishing characteristics of a variable.
1814 DeclContext *DC, *LexicalDC;
1815 DeclarationName Name;
Douglas Gregor5c73e912010-02-11 00:48:18 +00001816 SourceLocation Loc;
Douglas Gregorb4964f72010-02-15 23:54:17 +00001817 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
1818 return 0;
1819
1820 // Import the type.
1821 QualType T = Importer.Import(D->getType());
1822 if (T.isNull())
Douglas Gregor5c73e912010-02-11 00:48:18 +00001823 return 0;
1824
1825 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
1826 Expr *BitWidth = Importer.Import(D->getBitWidth());
1827 if (!BitWidth && D->getBitWidth())
1828 return 0;
1829
1830 FieldDecl *ToField = FieldDecl::Create(Importer.getToContext(), DC,
1831 Loc, Name.getAsIdentifierInfo(),
1832 T, TInfo, BitWidth, D->isMutable());
1833 ToField->setLexicalDeclContext(LexicalDC);
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001834 Importer.Imported(D, ToField);
Douglas Gregor5c73e912010-02-11 00:48:18 +00001835 LexicalDC->addDecl(ToField);
1836 return ToField;
1837}
1838
Douglas Gregor7244b0b2010-02-17 00:34:30 +00001839Decl *ASTNodeImporter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
1840 // Import the major distinguishing characteristics of an ivar.
1841 DeclContext *DC, *LexicalDC;
1842 DeclarationName Name;
1843 SourceLocation Loc;
1844 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
1845 return 0;
1846
1847 // Determine whether we've already imported this ivar
1848 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
1849 Lookup.first != Lookup.second;
1850 ++Lookup.first) {
1851 if (ObjCIvarDecl *FoundIvar = dyn_cast<ObjCIvarDecl>(*Lookup.first)) {
1852 if (Importer.IsStructurallyEquivalent(D->getType(),
1853 FoundIvar->getType())) {
1854 Importer.Imported(D, FoundIvar);
1855 return FoundIvar;
1856 }
1857
1858 Importer.ToDiag(Loc, diag::err_odr_ivar_type_inconsistent)
1859 << Name << D->getType() << FoundIvar->getType();
1860 Importer.ToDiag(FoundIvar->getLocation(), diag::note_odr_value_here)
1861 << FoundIvar->getType();
1862 return 0;
1863 }
1864 }
1865
1866 // Import the type.
1867 QualType T = Importer.Import(D->getType());
1868 if (T.isNull())
1869 return 0;
1870
1871 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
1872 Expr *BitWidth = Importer.Import(D->getBitWidth());
1873 if (!BitWidth && D->getBitWidth())
1874 return 0;
1875
1876 ObjCIvarDecl *ToIvar = ObjCIvarDecl::Create(Importer.getToContext(), DC,
1877 Loc, Name.getAsIdentifierInfo(),
1878 T, TInfo, D->getAccessControl(),
1879 BitWidth);
1880 ToIvar->setLexicalDeclContext(LexicalDC);
1881 Importer.Imported(D, ToIvar);
1882 LexicalDC->addDecl(ToIvar);
1883 return ToIvar;
1884
1885}
1886
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001887Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
1888 // Import the major distinguishing characteristics of a variable.
1889 DeclContext *DC, *LexicalDC;
1890 DeclarationName Name;
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001891 SourceLocation Loc;
Douglas Gregorb4964f72010-02-15 23:54:17 +00001892 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001893 return 0;
1894
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001895 // Try to find a variable in our own ("to") context with the same name and
1896 // in the same context as the variable we're importing.
Douglas Gregor62d311f2010-02-09 19:21:46 +00001897 if (D->isFileVarDecl()) {
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001898 VarDecl *MergeWithVar = 0;
1899 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
1900 unsigned IDNS = Decl::IDNS_Ordinary;
Douglas Gregor62d311f2010-02-09 19:21:46 +00001901 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001902 Lookup.first != Lookup.second;
1903 ++Lookup.first) {
1904 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
1905 continue;
1906
1907 if (VarDecl *FoundVar = dyn_cast<VarDecl>(*Lookup.first)) {
1908 // We have found a variable that we may need to merge with. Check it.
1909 if (isExternalLinkage(FoundVar->getLinkage()) &&
1910 isExternalLinkage(D->getLinkage())) {
Douglas Gregorb4964f72010-02-15 23:54:17 +00001911 if (Importer.IsStructurallyEquivalent(D->getType(),
1912 FoundVar->getType())) {
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001913 MergeWithVar = FoundVar;
1914 break;
1915 }
1916
Douglas Gregor56521c52010-02-12 17:23:39 +00001917 const ArrayType *FoundArray
1918 = Importer.getToContext().getAsArrayType(FoundVar->getType());
1919 const ArrayType *TArray
Douglas Gregorb4964f72010-02-15 23:54:17 +00001920 = Importer.getToContext().getAsArrayType(D->getType());
Douglas Gregor56521c52010-02-12 17:23:39 +00001921 if (FoundArray && TArray) {
1922 if (isa<IncompleteArrayType>(FoundArray) &&
1923 isa<ConstantArrayType>(TArray)) {
Douglas Gregorb4964f72010-02-15 23:54:17 +00001924 // Import the type.
1925 QualType T = Importer.Import(D->getType());
1926 if (T.isNull())
1927 return 0;
1928
Douglas Gregor56521c52010-02-12 17:23:39 +00001929 FoundVar->setType(T);
1930 MergeWithVar = FoundVar;
1931 break;
1932 } else if (isa<IncompleteArrayType>(TArray) &&
1933 isa<ConstantArrayType>(FoundArray)) {
1934 MergeWithVar = FoundVar;
1935 break;
Douglas Gregor2fbe5582010-02-10 17:16:49 +00001936 }
1937 }
1938
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001939 Importer.ToDiag(Loc, diag::err_odr_variable_type_inconsistent)
Douglas Gregorb4964f72010-02-15 23:54:17 +00001940 << Name << D->getType() << FoundVar->getType();
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001941 Importer.ToDiag(FoundVar->getLocation(), diag::note_odr_value_here)
1942 << FoundVar->getType();
1943 }
1944 }
1945
1946 ConflictingDecls.push_back(*Lookup.first);
1947 }
1948
1949 if (MergeWithVar) {
1950 // An equivalent variable with external linkage has been found. Link
1951 // the two declarations, then merge them.
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001952 Importer.Imported(D, MergeWithVar);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001953
1954 if (VarDecl *DDef = D->getDefinition()) {
1955 if (VarDecl *ExistingDef = MergeWithVar->getDefinition()) {
1956 Importer.ToDiag(ExistingDef->getLocation(),
1957 diag::err_odr_variable_multiple_def)
1958 << Name;
1959 Importer.FromDiag(DDef->getLocation(), diag::note_odr_defined_here);
1960 } else {
1961 Expr *Init = Importer.Import(DDef->getInit());
Douglas Gregord5058122010-02-11 01:19:42 +00001962 MergeWithVar->setInit(Init);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001963 }
1964 }
1965
1966 return MergeWithVar;
1967 }
1968
1969 if (!ConflictingDecls.empty()) {
1970 Name = Importer.HandleNameConflict(Name, DC, IDNS,
1971 ConflictingDecls.data(),
1972 ConflictingDecls.size());
1973 if (!Name)
1974 return 0;
1975 }
1976 }
Douglas Gregorfa7a0e52010-02-10 17:47:19 +00001977
Douglas Gregorb4964f72010-02-15 23:54:17 +00001978 // Import the type.
1979 QualType T = Importer.Import(D->getType());
1980 if (T.isNull())
1981 return 0;
1982
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001983 // Create the imported variable.
Douglas Gregorfa7a0e52010-02-10 17:47:19 +00001984 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001985 VarDecl *ToVar = VarDecl::Create(Importer.getToContext(), DC, Loc,
1986 Name.getAsIdentifierInfo(), T, TInfo,
1987 D->getStorageClass());
Douglas Gregor62d311f2010-02-09 19:21:46 +00001988 ToVar->setLexicalDeclContext(LexicalDC);
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001989 Importer.Imported(D, ToVar);
Douglas Gregor62d311f2010-02-09 19:21:46 +00001990 LexicalDC->addDecl(ToVar);
1991
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001992 // Merge the initializer.
1993 // FIXME: Can we really import any initializer? Alternatively, we could force
1994 // ourselves to import every declaration of a variable and then only use
1995 // getInit() here.
Douglas Gregord5058122010-02-11 01:19:42 +00001996 ToVar->setInit(Importer.Import(const_cast<Expr *>(D->getAnyInitializer())));
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001997
1998 // FIXME: Other bits to merge?
1999
2000 return ToVar;
2001}
2002
Douglas Gregor8b228d72010-02-17 21:22:52 +00002003Decl *ASTNodeImporter::VisitImplicitParamDecl(ImplicitParamDecl *D) {
2004 // Parameters are created in the translation unit's context, then moved
2005 // into the function declaration's context afterward.
2006 DeclContext *DC = Importer.getToContext().getTranslationUnitDecl();
2007
2008 // Import the name of this declaration.
2009 DeclarationName Name = Importer.Import(D->getDeclName());
2010 if (D->getDeclName() && !Name)
2011 return 0;
2012
2013 // Import the location of this declaration.
2014 SourceLocation Loc = Importer.Import(D->getLocation());
2015
2016 // Import the parameter's type.
2017 QualType T = Importer.Import(D->getType());
2018 if (T.isNull())
2019 return 0;
2020
2021 // Create the imported parameter.
2022 ImplicitParamDecl *ToParm
2023 = ImplicitParamDecl::Create(Importer.getToContext(), DC,
2024 Loc, Name.getAsIdentifierInfo(),
2025 T);
2026 return Importer.Imported(D, ToParm);
2027}
2028
Douglas Gregorbb7930c2010-02-10 19:54:31 +00002029Decl *ASTNodeImporter::VisitParmVarDecl(ParmVarDecl *D) {
2030 // Parameters are created in the translation unit's context, then moved
2031 // into the function declaration's context afterward.
2032 DeclContext *DC = Importer.getToContext().getTranslationUnitDecl();
2033
Douglas Gregorfa7a0e52010-02-10 17:47:19 +00002034 // Import the name of this declaration.
2035 DeclarationName Name = Importer.Import(D->getDeclName());
2036 if (D->getDeclName() && !Name)
2037 return 0;
2038
Douglas Gregorbb7930c2010-02-10 19:54:31 +00002039 // Import the location of this declaration.
2040 SourceLocation Loc = Importer.Import(D->getLocation());
2041
2042 // Import the parameter's type.
2043 QualType T = Importer.Import(D->getType());
2044 if (T.isNull())
2045 return 0;
2046
2047 // Create the imported parameter.
2048 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
2049 ParmVarDecl *ToParm = ParmVarDecl::Create(Importer.getToContext(), DC,
2050 Loc, Name.getAsIdentifierInfo(),
2051 T, TInfo, D->getStorageClass(),
2052 /*FIXME: Default argument*/ 0);
Douglas Gregor8cdbe642010-02-12 23:44:20 +00002053 return Importer.Imported(D, ToParm);
Douglas Gregorbb7930c2010-02-10 19:54:31 +00002054}
2055
Douglas Gregor43f54792010-02-17 02:12:47 +00002056Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
2057 // Import the major distinguishing characteristics of a method.
2058 DeclContext *DC, *LexicalDC;
2059 DeclarationName Name;
2060 SourceLocation Loc;
2061 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2062 return 0;
2063
2064 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
2065 Lookup.first != Lookup.second;
2066 ++Lookup.first) {
2067 if (ObjCMethodDecl *FoundMethod = dyn_cast<ObjCMethodDecl>(*Lookup.first)) {
2068 if (FoundMethod->isInstanceMethod() != D->isInstanceMethod())
2069 continue;
2070
2071 // Check return types.
2072 if (!Importer.IsStructurallyEquivalent(D->getResultType(),
2073 FoundMethod->getResultType())) {
2074 Importer.ToDiag(Loc, diag::err_odr_objc_method_result_type_inconsistent)
2075 << D->isInstanceMethod() << Name
2076 << D->getResultType() << FoundMethod->getResultType();
2077 Importer.ToDiag(FoundMethod->getLocation(),
2078 diag::note_odr_objc_method_here)
2079 << D->isInstanceMethod() << Name;
2080 return 0;
2081 }
2082
2083 // Check the number of parameters.
2084 if (D->param_size() != FoundMethod->param_size()) {
2085 Importer.ToDiag(Loc, diag::err_odr_objc_method_num_params_inconsistent)
2086 << D->isInstanceMethod() << Name
2087 << D->param_size() << FoundMethod->param_size();
2088 Importer.ToDiag(FoundMethod->getLocation(),
2089 diag::note_odr_objc_method_here)
2090 << D->isInstanceMethod() << Name;
2091 return 0;
2092 }
2093
2094 // Check parameter types.
2095 for (ObjCMethodDecl::param_iterator P = D->param_begin(),
2096 PEnd = D->param_end(), FoundP = FoundMethod->param_begin();
2097 P != PEnd; ++P, ++FoundP) {
2098 if (!Importer.IsStructurallyEquivalent((*P)->getType(),
2099 (*FoundP)->getType())) {
2100 Importer.FromDiag((*P)->getLocation(),
2101 diag::err_odr_objc_method_param_type_inconsistent)
2102 << D->isInstanceMethod() << Name
2103 << (*P)->getType() << (*FoundP)->getType();
2104 Importer.ToDiag((*FoundP)->getLocation(), diag::note_odr_value_here)
2105 << (*FoundP)->getType();
2106 return 0;
2107 }
2108 }
2109
2110 // Check variadic/non-variadic.
2111 // Check the number of parameters.
2112 if (D->isVariadic() != FoundMethod->isVariadic()) {
2113 Importer.ToDiag(Loc, diag::err_odr_objc_method_variadic_inconsistent)
2114 << D->isInstanceMethod() << Name;
2115 Importer.ToDiag(FoundMethod->getLocation(),
2116 diag::note_odr_objc_method_here)
2117 << D->isInstanceMethod() << Name;
2118 return 0;
2119 }
2120
2121 // FIXME: Any other bits we need to merge?
2122 return Importer.Imported(D, FoundMethod);
2123 }
2124 }
2125
2126 // Import the result type.
2127 QualType ResultTy = Importer.Import(D->getResultType());
2128 if (ResultTy.isNull())
2129 return 0;
2130
2131 ObjCMethodDecl *ToMethod
2132 = ObjCMethodDecl::Create(Importer.getToContext(),
2133 Loc,
2134 Importer.Import(D->getLocEnd()),
2135 Name.getObjCSelector(),
2136 ResultTy, DC,
2137 D->isInstanceMethod(),
2138 D->isVariadic(),
2139 D->isSynthesized(),
2140 D->getImplementationControl());
2141
2142 // FIXME: When we decide to merge method definitions, we'll need to
2143 // deal with implicit parameters.
2144
2145 // Import the parameters
2146 llvm::SmallVector<ParmVarDecl *, 5> ToParams;
2147 for (ObjCMethodDecl::param_iterator FromP = D->param_begin(),
2148 FromPEnd = D->param_end();
2149 FromP != FromPEnd;
2150 ++FromP) {
2151 ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(*FromP));
2152 if (!ToP)
2153 return 0;
2154
2155 ToParams.push_back(ToP);
2156 }
2157
2158 // Set the parameters.
2159 for (unsigned I = 0, N = ToParams.size(); I != N; ++I) {
2160 ToParams[I]->setOwningFunction(ToMethod);
2161 ToMethod->addDecl(ToParams[I]);
2162 }
2163 ToMethod->setMethodParams(Importer.getToContext(),
2164 ToParams.data(), ToParams.size());
2165
2166 ToMethod->setLexicalDeclContext(LexicalDC);
2167 Importer.Imported(D, ToMethod);
2168 LexicalDC->addDecl(ToMethod);
2169 return ToMethod;
2170}
2171
Douglas Gregor84c51c32010-02-18 01:47:50 +00002172Decl *ASTNodeImporter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
2173 // Import the major distinguishing characteristics of a category.
2174 DeclContext *DC, *LexicalDC;
2175 DeclarationName Name;
2176 SourceLocation Loc;
2177 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2178 return 0;
2179
2180 ObjCInterfaceDecl *ToInterface
2181 = cast_or_null<ObjCInterfaceDecl>(Importer.Import(D->getClassInterface()));
2182 if (!ToInterface)
2183 return 0;
2184
2185 // Determine if we've already encountered this category.
2186 ObjCCategoryDecl *MergeWithCategory
2187 = ToInterface->FindCategoryDeclaration(Name.getAsIdentifierInfo());
2188 ObjCCategoryDecl *ToCategory = MergeWithCategory;
2189 if (!ToCategory) {
2190 ToCategory = ObjCCategoryDecl::Create(Importer.getToContext(), DC,
2191 Importer.Import(D->getAtLoc()),
2192 Loc,
2193 Importer.Import(D->getCategoryNameLoc()),
2194 Name.getAsIdentifierInfo());
2195 ToCategory->setLexicalDeclContext(LexicalDC);
2196 LexicalDC->addDecl(ToCategory);
2197 Importer.Imported(D, ToCategory);
2198
2199 // Link this category into its class's category list.
2200 ToCategory->setClassInterface(ToInterface);
2201 ToCategory->insertNextClassCategory();
2202
2203 // Import protocols
2204 llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
2205 llvm::SmallVector<SourceLocation, 4> ProtocolLocs;
2206 ObjCCategoryDecl::protocol_loc_iterator FromProtoLoc
2207 = D->protocol_loc_begin();
2208 for (ObjCCategoryDecl::protocol_iterator FromProto = D->protocol_begin(),
2209 FromProtoEnd = D->protocol_end();
2210 FromProto != FromProtoEnd;
2211 ++FromProto, ++FromProtoLoc) {
2212 ObjCProtocolDecl *ToProto
2213 = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
2214 if (!ToProto)
2215 return 0;
2216 Protocols.push_back(ToProto);
2217 ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
2218 }
2219
2220 // FIXME: If we're merging, make sure that the protocol list is the same.
2221 ToCategory->setProtocolList(Protocols.data(), Protocols.size(),
2222 ProtocolLocs.data(), Importer.getToContext());
2223
2224 } else {
2225 Importer.Imported(D, ToCategory);
2226 }
2227
2228 // Import all of the members of this category.
2229 for (DeclContext::decl_iterator FromMem = D->decls_begin(),
2230 FromMemEnd = D->decls_end();
2231 FromMem != FromMemEnd;
2232 ++FromMem)
2233 Importer.Import(*FromMem);
2234
2235 // If we have an implementation, import it as well.
2236 if (D->getImplementation()) {
2237 ObjCCategoryImplDecl *Impl
2238 = cast<ObjCCategoryImplDecl>(Importer.Import(D->getImplementation()));
2239 if (!Impl)
2240 return 0;
2241
2242 ToCategory->setImplementation(Impl);
2243 }
2244
2245 return ToCategory;
2246}
2247
Douglas Gregor98d156a2010-02-17 16:12:00 +00002248Decl *ASTNodeImporter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
Douglas Gregor84c51c32010-02-18 01:47:50 +00002249 // Import the major distinguishing characteristics of a protocol.
Douglas Gregor98d156a2010-02-17 16:12:00 +00002250 DeclContext *DC, *LexicalDC;
2251 DeclarationName Name;
2252 SourceLocation Loc;
2253 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2254 return 0;
2255
2256 ObjCProtocolDecl *MergeWithProtocol = 0;
2257 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
2258 Lookup.first != Lookup.second;
2259 ++Lookup.first) {
2260 if (!(*Lookup.first)->isInIdentifierNamespace(Decl::IDNS_ObjCProtocol))
2261 continue;
2262
2263 if ((MergeWithProtocol = dyn_cast<ObjCProtocolDecl>(*Lookup.first)))
2264 break;
2265 }
2266
2267 ObjCProtocolDecl *ToProto = MergeWithProtocol;
2268 if (!ToProto || ToProto->isForwardDecl()) {
2269 if (!ToProto) {
2270 ToProto = ObjCProtocolDecl::Create(Importer.getToContext(), DC, Loc,
2271 Name.getAsIdentifierInfo());
2272 ToProto->setForwardDecl(D->isForwardDecl());
2273 ToProto->setLexicalDeclContext(LexicalDC);
2274 LexicalDC->addDecl(ToProto);
2275 }
2276 Importer.Imported(D, ToProto);
2277
2278 // Import protocols
2279 llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
2280 llvm::SmallVector<SourceLocation, 4> ProtocolLocs;
2281 ObjCProtocolDecl::protocol_loc_iterator
2282 FromProtoLoc = D->protocol_loc_begin();
2283 for (ObjCProtocolDecl::protocol_iterator FromProto = D->protocol_begin(),
2284 FromProtoEnd = D->protocol_end();
2285 FromProto != FromProtoEnd;
2286 ++FromProto, ++FromProtoLoc) {
2287 ObjCProtocolDecl *ToProto
2288 = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
2289 if (!ToProto)
2290 return 0;
2291 Protocols.push_back(ToProto);
2292 ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
2293 }
2294
2295 // FIXME: If we're merging, make sure that the protocol list is the same.
2296 ToProto->setProtocolList(Protocols.data(), Protocols.size(),
2297 ProtocolLocs.data(), Importer.getToContext());
2298 } else {
2299 Importer.Imported(D, ToProto);
2300 }
2301
Douglas Gregor84c51c32010-02-18 01:47:50 +00002302 // Import all of the members of this protocol.
Douglas Gregor98d156a2010-02-17 16:12:00 +00002303 for (DeclContext::decl_iterator FromMem = D->decls_begin(),
2304 FromMemEnd = D->decls_end();
2305 FromMem != FromMemEnd;
2306 ++FromMem)
2307 Importer.Import(*FromMem);
2308
2309 return ToProto;
2310}
2311
Douglas Gregor45635322010-02-16 01:20:57 +00002312Decl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
2313 // Import the major distinguishing characteristics of an @interface.
2314 DeclContext *DC, *LexicalDC;
2315 DeclarationName Name;
2316 SourceLocation Loc;
2317 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2318 return 0;
2319
2320 ObjCInterfaceDecl *MergeWithIface = 0;
2321 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
2322 Lookup.first != Lookup.second;
2323 ++Lookup.first) {
2324 if (!(*Lookup.first)->isInIdentifierNamespace(Decl::IDNS_Ordinary))
2325 continue;
2326
2327 if ((MergeWithIface = dyn_cast<ObjCInterfaceDecl>(*Lookup.first)))
2328 break;
2329 }
2330
2331 ObjCInterfaceDecl *ToIface = MergeWithIface;
2332 if (!ToIface || ToIface->isForwardDecl()) {
2333 if (!ToIface) {
2334 ToIface = ObjCInterfaceDecl::Create(Importer.getToContext(),
2335 DC, Loc,
2336 Name.getAsIdentifierInfo(),
2337 Importer.Import(D->getClassLoc()),
2338 D->isForwardDecl(),
2339 D->isImplicitInterfaceDecl());
Douglas Gregor98d156a2010-02-17 16:12:00 +00002340 ToIface->setForwardDecl(D->isForwardDecl());
Douglas Gregor45635322010-02-16 01:20:57 +00002341 ToIface->setLexicalDeclContext(LexicalDC);
2342 LexicalDC->addDecl(ToIface);
2343 }
2344 Importer.Imported(D, ToIface);
2345
Douglas Gregor45635322010-02-16 01:20:57 +00002346 if (D->getSuperClass()) {
2347 ObjCInterfaceDecl *Super
2348 = cast_or_null<ObjCInterfaceDecl>(Importer.Import(D->getSuperClass()));
2349 if (!Super)
2350 return 0;
2351
2352 ToIface->setSuperClass(Super);
2353 ToIface->setSuperClassLoc(Importer.Import(D->getSuperClassLoc()));
2354 }
2355
2356 // Import protocols
2357 llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
2358 llvm::SmallVector<SourceLocation, 4> ProtocolLocs;
2359 ObjCInterfaceDecl::protocol_loc_iterator
2360 FromProtoLoc = D->protocol_loc_begin();
2361 for (ObjCInterfaceDecl::protocol_iterator FromProto = D->protocol_begin(),
2362 FromProtoEnd = D->protocol_end();
2363 FromProto != FromProtoEnd;
2364 ++FromProto, ++FromProtoLoc) {
2365 ObjCProtocolDecl *ToProto
2366 = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
2367 if (!ToProto)
2368 return 0;
2369 Protocols.push_back(ToProto);
2370 ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
2371 }
2372
2373 // FIXME: If we're merging, make sure that the protocol list is the same.
2374 ToIface->setProtocolList(Protocols.data(), Protocols.size(),
2375 ProtocolLocs.data(), Importer.getToContext());
2376
Douglas Gregor45635322010-02-16 01:20:57 +00002377 // Import @end range
2378 ToIface->setAtEndRange(Importer.Import(D->getAtEndRange()));
2379 } else {
2380 Importer.Imported(D, ToIface);
Douglas Gregor7244b0b2010-02-17 00:34:30 +00002381
2382 // Check for consistency of superclasses.
2383 DeclarationName FromSuperName, ToSuperName;
2384 if (D->getSuperClass())
2385 FromSuperName = Importer.Import(D->getSuperClass()->getDeclName());
2386 if (ToIface->getSuperClass())
2387 ToSuperName = ToIface->getSuperClass()->getDeclName();
2388 if (FromSuperName != ToSuperName) {
2389 Importer.ToDiag(ToIface->getLocation(),
2390 diag::err_odr_objc_superclass_inconsistent)
2391 << ToIface->getDeclName();
2392 if (ToIface->getSuperClass())
2393 Importer.ToDiag(ToIface->getSuperClassLoc(),
2394 diag::note_odr_objc_superclass)
2395 << ToIface->getSuperClass()->getDeclName();
2396 else
2397 Importer.ToDiag(ToIface->getLocation(),
2398 diag::note_odr_objc_missing_superclass);
2399 if (D->getSuperClass())
2400 Importer.FromDiag(D->getSuperClassLoc(),
2401 diag::note_odr_objc_superclass)
2402 << D->getSuperClass()->getDeclName();
2403 else
2404 Importer.FromDiag(D->getLocation(),
2405 diag::note_odr_objc_missing_superclass);
2406 return 0;
2407 }
Douglas Gregor45635322010-02-16 01:20:57 +00002408 }
2409
Douglas Gregor84c51c32010-02-18 01:47:50 +00002410 // Import categories. When the categories themselves are imported, they'll
2411 // hook themselves into this interface.
2412 for (ObjCCategoryDecl *FromCat = D->getCategoryList(); FromCat;
2413 FromCat = FromCat->getNextClassCategory())
2414 Importer.Import(FromCat);
2415
Douglas Gregor45635322010-02-16 01:20:57 +00002416 // Import all of the members of this class.
2417 for (DeclContext::decl_iterator FromMem = D->decls_begin(),
2418 FromMemEnd = D->decls_end();
2419 FromMem != FromMemEnd;
2420 ++FromMem)
2421 Importer.Import(*FromMem);
2422
2423 // If we have an @implementation, import it as well.
2424 if (D->getImplementation()) {
2425 ObjCImplementationDecl *Impl
2426 = cast<ObjCImplementationDecl>(Importer.Import(D->getImplementation()));
2427 if (!Impl)
2428 return 0;
2429
2430 ToIface->setImplementation(Impl);
2431 }
2432
Douglas Gregor98d156a2010-02-17 16:12:00 +00002433 return ToIface;
Douglas Gregor45635322010-02-16 01:20:57 +00002434}
2435
Douglas Gregora11c4582010-02-17 18:02:10 +00002436Decl *ASTNodeImporter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
2437 // Import the major distinguishing characteristics of an @property.
2438 DeclContext *DC, *LexicalDC;
2439 DeclarationName Name;
2440 SourceLocation Loc;
2441 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2442 return 0;
2443
2444 // Check whether we have already imported this property.
2445 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
2446 Lookup.first != Lookup.second;
2447 ++Lookup.first) {
2448 if (ObjCPropertyDecl *FoundProp
2449 = dyn_cast<ObjCPropertyDecl>(*Lookup.first)) {
2450 // Check property types.
2451 if (!Importer.IsStructurallyEquivalent(D->getType(),
2452 FoundProp->getType())) {
2453 Importer.ToDiag(Loc, diag::err_odr_objc_property_type_inconsistent)
2454 << Name << D->getType() << FoundProp->getType();
2455 Importer.ToDiag(FoundProp->getLocation(), diag::note_odr_value_here)
2456 << FoundProp->getType();
2457 return 0;
2458 }
2459
2460 // FIXME: Check property attributes, getters, setters, etc.?
2461
2462 // Consider these properties to be equivalent.
2463 Importer.Imported(D, FoundProp);
2464 return FoundProp;
2465 }
2466 }
2467
2468 // Import the type.
2469 QualType T = Importer.Import(D->getType());
2470 if (T.isNull())
2471 return 0;
2472
2473 // Create the new property.
2474 ObjCPropertyDecl *ToProperty
2475 = ObjCPropertyDecl::Create(Importer.getToContext(), DC, Loc,
2476 Name.getAsIdentifierInfo(),
2477 Importer.Import(D->getAtLoc()),
2478 T,
2479 D->getPropertyImplementation());
2480 Importer.Imported(D, ToProperty);
2481 ToProperty->setLexicalDeclContext(LexicalDC);
2482 LexicalDC->addDecl(ToProperty);
2483
2484 ToProperty->setPropertyAttributes(D->getPropertyAttributes());
2485 ToProperty->setGetterName(Importer.Import(D->getGetterName()));
2486 ToProperty->setSetterName(Importer.Import(D->getSetterName()));
2487 ToProperty->setGetterMethodDecl(
2488 cast_or_null<ObjCMethodDecl>(Importer.Import(D->getGetterMethodDecl())));
2489 ToProperty->setSetterMethodDecl(
2490 cast_or_null<ObjCMethodDecl>(Importer.Import(D->getSetterMethodDecl())));
2491 ToProperty->setPropertyIvarDecl(
2492 cast_or_null<ObjCIvarDecl>(Importer.Import(D->getPropertyIvarDecl())));
2493 return ToProperty;
2494}
2495
Douglas Gregor8661a722010-02-18 02:12:22 +00002496Decl *
2497ASTNodeImporter::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) {
2498 // Import the context of this declaration.
2499 DeclContext *DC = Importer.ImportContext(D->getDeclContext());
2500 if (!DC)
2501 return 0;
2502
2503 DeclContext *LexicalDC = DC;
2504 if (D->getDeclContext() != D->getLexicalDeclContext()) {
2505 LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
2506 if (!LexicalDC)
2507 return 0;
2508 }
2509
2510 // Import the location of this declaration.
2511 SourceLocation Loc = Importer.Import(D->getLocation());
2512
2513 llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
2514 llvm::SmallVector<SourceLocation, 4> Locations;
2515 ObjCForwardProtocolDecl::protocol_loc_iterator FromProtoLoc
2516 = D->protocol_loc_begin();
2517 for (ObjCForwardProtocolDecl::protocol_iterator FromProto
2518 = D->protocol_begin(), FromProtoEnd = D->protocol_end();
2519 FromProto != FromProtoEnd;
2520 ++FromProto, ++FromProtoLoc) {
2521 ObjCProtocolDecl *ToProto
2522 = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
2523 if (!ToProto)
2524 continue;
2525
2526 Protocols.push_back(ToProto);
2527 Locations.push_back(Importer.Import(*FromProtoLoc));
2528 }
2529
2530 ObjCForwardProtocolDecl *ToForward
2531 = ObjCForwardProtocolDecl::Create(Importer.getToContext(), DC, Loc,
2532 Protocols.data(), Protocols.size(),
2533 Locations.data());
2534 ToForward->setLexicalDeclContext(LexicalDC);
2535 LexicalDC->addDecl(ToForward);
2536 Importer.Imported(D, ToForward);
2537 return ToForward;
2538}
2539
Douglas Gregor06537af2010-02-18 02:04:09 +00002540Decl *ASTNodeImporter::VisitObjCClassDecl(ObjCClassDecl *D) {
2541 // Import the context of this declaration.
2542 DeclContext *DC = Importer.ImportContext(D->getDeclContext());
2543 if (!DC)
2544 return 0;
2545
2546 DeclContext *LexicalDC = DC;
2547 if (D->getDeclContext() != D->getLexicalDeclContext()) {
2548 LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
2549 if (!LexicalDC)
2550 return 0;
2551 }
2552
2553 // Import the location of this declaration.
2554 SourceLocation Loc = Importer.Import(D->getLocation());
2555
2556 llvm::SmallVector<ObjCInterfaceDecl *, 4> Interfaces;
2557 llvm::SmallVector<SourceLocation, 4> Locations;
2558 for (ObjCClassDecl::iterator From = D->begin(), FromEnd = D->end();
2559 From != FromEnd; ++From) {
2560 ObjCInterfaceDecl *ToIface
2561 = cast_or_null<ObjCInterfaceDecl>(Importer.Import(From->getInterface()));
2562 if (!ToIface)
2563 continue;
2564
2565 Interfaces.push_back(ToIface);
2566 Locations.push_back(Importer.Import(From->getLocation()));
2567 }
2568
2569 ObjCClassDecl *ToClass = ObjCClassDecl::Create(Importer.getToContext(), DC,
2570 Loc,
2571 Interfaces.data(),
2572 Locations.data(),
2573 Interfaces.size());
2574 ToClass->setLexicalDeclContext(LexicalDC);
2575 LexicalDC->addDecl(ToClass);
2576 Importer.Imported(D, ToClass);
2577 return ToClass;
2578}
2579
Douglas Gregor7eeb5972010-02-11 19:21:55 +00002580//----------------------------------------------------------------------------
2581// Import Statements
2582//----------------------------------------------------------------------------
2583
2584Stmt *ASTNodeImporter::VisitStmt(Stmt *S) {
2585 Importer.FromDiag(S->getLocStart(), diag::err_unsupported_ast_node)
2586 << S->getStmtClassName();
2587 return 0;
2588}
2589
2590//----------------------------------------------------------------------------
2591// Import Expressions
2592//----------------------------------------------------------------------------
2593Expr *ASTNodeImporter::VisitExpr(Expr *E) {
2594 Importer.FromDiag(E->getLocStart(), diag::err_unsupported_ast_node)
2595 << E->getStmtClassName();
2596 return 0;
2597}
2598
Douglas Gregor52f820e2010-02-19 01:17:02 +00002599Expr *ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) {
2600 NestedNameSpecifier *Qualifier = 0;
2601 if (E->getQualifier()) {
2602 Qualifier = Importer.Import(E->getQualifier());
2603 if (!E->getQualifier())
2604 return 0;
2605 }
2606
2607 ValueDecl *ToD = cast_or_null<ValueDecl>(Importer.Import(E->getDecl()));
2608 if (!ToD)
2609 return 0;
2610
2611 QualType T = Importer.Import(E->getType());
2612 if (T.isNull())
2613 return 0;
2614
2615 return DeclRefExpr::Create(Importer.getToContext(), Qualifier,
2616 Importer.Import(E->getQualifierRange()),
2617 ToD,
2618 Importer.Import(E->getLocation()),
2619 T,
2620 /*FIXME:TemplateArgs=*/0);
2621}
2622
Douglas Gregor7eeb5972010-02-11 19:21:55 +00002623Expr *ASTNodeImporter::VisitIntegerLiteral(IntegerLiteral *E) {
2624 QualType T = Importer.Import(E->getType());
2625 if (T.isNull())
2626 return 0;
2627
2628 return new (Importer.getToContext())
2629 IntegerLiteral(E->getValue(), T, Importer.Import(E->getLocation()));
2630}
2631
Douglas Gregor623421d2010-02-18 02:21:22 +00002632Expr *ASTNodeImporter::VisitCharacterLiteral(CharacterLiteral *E) {
2633 QualType T = Importer.Import(E->getType());
2634 if (T.isNull())
2635 return 0;
2636
2637 return new (Importer.getToContext()) CharacterLiteral(E->getValue(),
2638 E->isWide(), T,
2639 Importer.Import(E->getLocation()));
2640}
2641
Douglas Gregorc74247e2010-02-19 01:07:06 +00002642Expr *ASTNodeImporter::VisitParenExpr(ParenExpr *E) {
2643 Expr *SubExpr = Importer.Import(E->getSubExpr());
2644 if (!SubExpr)
2645 return 0;
2646
2647 return new (Importer.getToContext())
2648 ParenExpr(Importer.Import(E->getLParen()),
2649 Importer.Import(E->getRParen()),
2650 SubExpr);
2651}
2652
2653Expr *ASTNodeImporter::VisitUnaryOperator(UnaryOperator *E) {
2654 QualType T = Importer.Import(E->getType());
2655 if (T.isNull())
2656 return 0;
2657
2658 Expr *SubExpr = Importer.Import(E->getSubExpr());
2659 if (!SubExpr)
2660 return 0;
2661
2662 return new (Importer.getToContext()) UnaryOperator(SubExpr, E->getOpcode(),
2663 T,
2664 Importer.Import(E->getOperatorLoc()));
2665}
2666
Douglas Gregord8552cd2010-02-19 01:24:23 +00002667Expr *ASTNodeImporter::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
2668 QualType ResultType = Importer.Import(E->getType());
2669
2670 if (E->isArgumentType()) {
2671 TypeSourceInfo *TInfo = Importer.Import(E->getArgumentTypeInfo());
2672 if (!TInfo)
2673 return 0;
2674
2675 return new (Importer.getToContext()) SizeOfAlignOfExpr(E->isSizeOf(),
2676 TInfo, ResultType,
2677 Importer.Import(E->getOperatorLoc()),
2678 Importer.Import(E->getRParenLoc()));
2679 }
2680
2681 Expr *SubExpr = Importer.Import(E->getArgumentExpr());
2682 if (!SubExpr)
2683 return 0;
2684
2685 return new (Importer.getToContext()) SizeOfAlignOfExpr(E->isSizeOf(),
2686 SubExpr, ResultType,
2687 Importer.Import(E->getOperatorLoc()),
2688 Importer.Import(E->getRParenLoc()));
2689}
2690
Douglas Gregorc74247e2010-02-19 01:07:06 +00002691Expr *ASTNodeImporter::VisitBinaryOperator(BinaryOperator *E) {
2692 QualType T = Importer.Import(E->getType());
2693 if (T.isNull())
2694 return 0;
2695
2696 Expr *LHS = Importer.Import(E->getLHS());
2697 if (!LHS)
2698 return 0;
2699
2700 Expr *RHS = Importer.Import(E->getRHS());
2701 if (!RHS)
2702 return 0;
2703
2704 return new (Importer.getToContext()) BinaryOperator(LHS, RHS, E->getOpcode(),
2705 T,
2706 Importer.Import(E->getOperatorLoc()));
2707}
2708
2709Expr *ASTNodeImporter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
2710 QualType T = Importer.Import(E->getType());
2711 if (T.isNull())
2712 return 0;
2713
2714 QualType CompLHSType = Importer.Import(E->getComputationLHSType());
2715 if (CompLHSType.isNull())
2716 return 0;
2717
2718 QualType CompResultType = Importer.Import(E->getComputationResultType());
2719 if (CompResultType.isNull())
2720 return 0;
2721
2722 Expr *LHS = Importer.Import(E->getLHS());
2723 if (!LHS)
2724 return 0;
2725
2726 Expr *RHS = Importer.Import(E->getRHS());
2727 if (!RHS)
2728 return 0;
2729
2730 return new (Importer.getToContext())
2731 CompoundAssignOperator(LHS, RHS, E->getOpcode(),
2732 T, CompLHSType, CompResultType,
2733 Importer.Import(E->getOperatorLoc()));
2734}
2735
Douglas Gregor98c10182010-02-12 22:17:39 +00002736Expr *ASTNodeImporter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
2737 QualType T = Importer.Import(E->getType());
2738 if (T.isNull())
2739 return 0;
2740
2741 Expr *SubExpr = Importer.Import(E->getSubExpr());
2742 if (!SubExpr)
2743 return 0;
2744
2745 return new (Importer.getToContext()) ImplicitCastExpr(T, E->getCastKind(),
2746 SubExpr,
2747 E->isLvalueCast());
2748}
2749
Douglas Gregor7eeb5972010-02-11 19:21:55 +00002750ASTImporter::ASTImporter(Diagnostic &Diags,
2751 ASTContext &ToContext, FileManager &ToFileManager,
2752 ASTContext &FromContext, FileManager &FromFileManager)
Douglas Gregor96e578d2010-02-05 17:54:41 +00002753 : ToContext(ToContext), FromContext(FromContext),
Douglas Gregor811663e2010-02-10 00:15:17 +00002754 ToFileManager(ToFileManager), FromFileManager(FromFileManager),
Douglas Gregor7eeb5972010-02-11 19:21:55 +00002755 Diags(Diags) {
Douglas Gregor62d311f2010-02-09 19:21:46 +00002756 ImportedDecls[FromContext.getTranslationUnitDecl()]
2757 = ToContext.getTranslationUnitDecl();
2758}
2759
2760ASTImporter::~ASTImporter() { }
Douglas Gregor96e578d2010-02-05 17:54:41 +00002761
2762QualType ASTImporter::Import(QualType FromT) {
2763 if (FromT.isNull())
2764 return QualType();
2765
Douglas Gregorf65bbb32010-02-08 15:18:58 +00002766 // Check whether we've already imported this type.
2767 llvm::DenseMap<Type *, Type *>::iterator Pos
2768 = ImportedTypes.find(FromT.getTypePtr());
2769 if (Pos != ImportedTypes.end())
2770 return ToContext.getQualifiedType(Pos->second, FromT.getQualifiers());
Douglas Gregor96e578d2010-02-05 17:54:41 +00002771
Douglas Gregorf65bbb32010-02-08 15:18:58 +00002772 // Import the type
Douglas Gregor96e578d2010-02-05 17:54:41 +00002773 ASTNodeImporter Importer(*this);
2774 QualType ToT = Importer.Visit(FromT.getTypePtr());
2775 if (ToT.isNull())
2776 return ToT;
2777
Douglas Gregorf65bbb32010-02-08 15:18:58 +00002778 // Record the imported type.
2779 ImportedTypes[FromT.getTypePtr()] = ToT.getTypePtr();
2780
Douglas Gregor96e578d2010-02-05 17:54:41 +00002781 return ToContext.getQualifiedType(ToT, FromT.getQualifiers());
2782}
2783
Douglas Gregor62d311f2010-02-09 19:21:46 +00002784TypeSourceInfo *ASTImporter::Import(TypeSourceInfo *FromTSI) {
Douglas Gregorfa7a0e52010-02-10 17:47:19 +00002785 if (!FromTSI)
2786 return FromTSI;
2787
2788 // FIXME: For now we just create a "trivial" type source info based
2789 // on the type and a seingle location. Implement a real version of
2790 // this.
2791 QualType T = Import(FromTSI->getType());
2792 if (T.isNull())
2793 return 0;
2794
2795 return ToContext.getTrivialTypeSourceInfo(T,
2796 FromTSI->getTypeLoc().getFullSourceRange().getBegin());
Douglas Gregor62d311f2010-02-09 19:21:46 +00002797}
2798
2799Decl *ASTImporter::Import(Decl *FromD) {
2800 if (!FromD)
2801 return 0;
2802
2803 // Check whether we've already imported this declaration.
2804 llvm::DenseMap<Decl *, Decl *>::iterator Pos = ImportedDecls.find(FromD);
2805 if (Pos != ImportedDecls.end())
2806 return Pos->second;
2807
2808 // Import the type
2809 ASTNodeImporter Importer(*this);
2810 Decl *ToD = Importer.Visit(FromD);
2811 if (!ToD)
2812 return 0;
2813
2814 // Record the imported declaration.
2815 ImportedDecls[FromD] = ToD;
Douglas Gregorb4964f72010-02-15 23:54:17 +00002816
2817 if (TagDecl *FromTag = dyn_cast<TagDecl>(FromD)) {
2818 // Keep track of anonymous tags that have an associated typedef.
2819 if (FromTag->getTypedefForAnonDecl())
2820 AnonTagsWithPendingTypedefs.push_back(FromTag);
2821 } else if (TypedefDecl *FromTypedef = dyn_cast<TypedefDecl>(FromD)) {
2822 // When we've finished transforming a typedef, see whether it was the
2823 // typedef for an anonymous tag.
2824 for (llvm::SmallVector<TagDecl *, 4>::iterator
2825 FromTag = AnonTagsWithPendingTypedefs.begin(),
2826 FromTagEnd = AnonTagsWithPendingTypedefs.end();
2827 FromTag != FromTagEnd; ++FromTag) {
2828 if ((*FromTag)->getTypedefForAnonDecl() == FromTypedef) {
2829 if (TagDecl *ToTag = cast_or_null<TagDecl>(Import(*FromTag))) {
2830 // We found the typedef for an anonymous tag; link them.
2831 ToTag->setTypedefForAnonDecl(cast<TypedefDecl>(ToD));
2832 AnonTagsWithPendingTypedefs.erase(FromTag);
2833 break;
2834 }
2835 }
2836 }
2837 }
2838
Douglas Gregor62d311f2010-02-09 19:21:46 +00002839 return ToD;
2840}
2841
2842DeclContext *ASTImporter::ImportContext(DeclContext *FromDC) {
2843 if (!FromDC)
2844 return FromDC;
2845
2846 return cast_or_null<DeclContext>(Import(cast<Decl>(FromDC)));
2847}
2848
2849Expr *ASTImporter::Import(Expr *FromE) {
2850 if (!FromE)
2851 return 0;
2852
2853 return cast_or_null<Expr>(Import(cast<Stmt>(FromE)));
2854}
2855
2856Stmt *ASTImporter::Import(Stmt *FromS) {
2857 if (!FromS)
2858 return 0;
2859
Douglas Gregor7eeb5972010-02-11 19:21:55 +00002860 // Check whether we've already imported this declaration.
2861 llvm::DenseMap<Stmt *, Stmt *>::iterator Pos = ImportedStmts.find(FromS);
2862 if (Pos != ImportedStmts.end())
2863 return Pos->second;
2864
2865 // Import the type
2866 ASTNodeImporter Importer(*this);
2867 Stmt *ToS = Importer.Visit(FromS);
2868 if (!ToS)
2869 return 0;
2870
2871 // Record the imported declaration.
2872 ImportedStmts[FromS] = ToS;
2873 return ToS;
Douglas Gregor62d311f2010-02-09 19:21:46 +00002874}
2875
2876NestedNameSpecifier *ASTImporter::Import(NestedNameSpecifier *FromNNS) {
2877 if (!FromNNS)
2878 return 0;
2879
2880 // FIXME: Implement!
2881 return 0;
2882}
2883
2884SourceLocation ASTImporter::Import(SourceLocation FromLoc) {
2885 if (FromLoc.isInvalid())
2886 return SourceLocation();
2887
Douglas Gregor811663e2010-02-10 00:15:17 +00002888 SourceManager &FromSM = FromContext.getSourceManager();
2889
2890 // For now, map everything down to its spelling location, so that we
2891 // don't have to import macro instantiations.
2892 // FIXME: Import macro instantiations!
2893 FromLoc = FromSM.getSpellingLoc(FromLoc);
2894 std::pair<FileID, unsigned> Decomposed = FromSM.getDecomposedLoc(FromLoc);
2895 SourceManager &ToSM = ToContext.getSourceManager();
2896 return ToSM.getLocForStartOfFile(Import(Decomposed.first))
2897 .getFileLocWithOffset(Decomposed.second);
Douglas Gregor62d311f2010-02-09 19:21:46 +00002898}
2899
2900SourceRange ASTImporter::Import(SourceRange FromRange) {
2901 return SourceRange(Import(FromRange.getBegin()), Import(FromRange.getEnd()));
2902}
2903
Douglas Gregor811663e2010-02-10 00:15:17 +00002904FileID ASTImporter::Import(FileID FromID) {
2905 llvm::DenseMap<unsigned, FileID>::iterator Pos
2906 = ImportedFileIDs.find(FromID.getHashValue());
2907 if (Pos != ImportedFileIDs.end())
2908 return Pos->second;
2909
2910 SourceManager &FromSM = FromContext.getSourceManager();
2911 SourceManager &ToSM = ToContext.getSourceManager();
2912 const SrcMgr::SLocEntry &FromSLoc = FromSM.getSLocEntry(FromID);
2913 assert(FromSLoc.isFile() && "Cannot handle macro instantiations yet");
2914
2915 // Include location of this file.
2916 SourceLocation ToIncludeLoc = Import(FromSLoc.getFile().getIncludeLoc());
2917
2918 // Map the FileID for to the "to" source manager.
2919 FileID ToID;
2920 const SrcMgr::ContentCache *Cache = FromSLoc.getFile().getContentCache();
2921 if (Cache->Entry) {
2922 // FIXME: We probably want to use getVirtualFile(), so we don't hit the
2923 // disk again
2924 // FIXME: We definitely want to re-use the existing MemoryBuffer, rather
2925 // than mmap the files several times.
2926 const FileEntry *Entry = ToFileManager.getFile(Cache->Entry->getName());
2927 ToID = ToSM.createFileID(Entry, ToIncludeLoc,
2928 FromSLoc.getFile().getFileCharacteristic());
2929 } else {
2930 // FIXME: We want to re-use the existing MemoryBuffer!
2931 const llvm::MemoryBuffer *FromBuf = Cache->getBuffer();
2932 llvm::MemoryBuffer *ToBuf
2933 = llvm::MemoryBuffer::getMemBufferCopy(FromBuf->getBufferStart(),
2934 FromBuf->getBufferEnd(),
2935 FromBuf->getBufferIdentifier());
2936 ToID = ToSM.createFileIDForMemBuffer(ToBuf);
2937 }
2938
2939
2940 ImportedFileIDs[FromID.getHashValue()] = ToID;
2941 return ToID;
2942}
2943
Douglas Gregor96e578d2010-02-05 17:54:41 +00002944DeclarationName ASTImporter::Import(DeclarationName FromName) {
2945 if (!FromName)
2946 return DeclarationName();
2947
2948 switch (FromName.getNameKind()) {
2949 case DeclarationName::Identifier:
2950 return Import(FromName.getAsIdentifierInfo());
2951
2952 case DeclarationName::ObjCZeroArgSelector:
2953 case DeclarationName::ObjCOneArgSelector:
2954 case DeclarationName::ObjCMultiArgSelector:
2955 return Import(FromName.getObjCSelector());
2956
2957 case DeclarationName::CXXConstructorName: {
2958 QualType T = Import(FromName.getCXXNameType());
2959 if (T.isNull())
2960 return DeclarationName();
2961
2962 return ToContext.DeclarationNames.getCXXConstructorName(
2963 ToContext.getCanonicalType(T));
2964 }
2965
2966 case DeclarationName::CXXDestructorName: {
2967 QualType T = Import(FromName.getCXXNameType());
2968 if (T.isNull())
2969 return DeclarationName();
2970
2971 return ToContext.DeclarationNames.getCXXDestructorName(
2972 ToContext.getCanonicalType(T));
2973 }
2974
2975 case DeclarationName::CXXConversionFunctionName: {
2976 QualType T = Import(FromName.getCXXNameType());
2977 if (T.isNull())
2978 return DeclarationName();
2979
2980 return ToContext.DeclarationNames.getCXXConversionFunctionName(
2981 ToContext.getCanonicalType(T));
2982 }
2983
2984 case DeclarationName::CXXOperatorName:
2985 return ToContext.DeclarationNames.getCXXOperatorName(
2986 FromName.getCXXOverloadedOperator());
2987
2988 case DeclarationName::CXXLiteralOperatorName:
2989 return ToContext.DeclarationNames.getCXXLiteralOperatorName(
2990 Import(FromName.getCXXLiteralIdentifier()));
2991
2992 case DeclarationName::CXXUsingDirective:
2993 // FIXME: STATICS!
2994 return DeclarationName::getUsingDirectiveName();
2995 }
2996
2997 // Silence bogus GCC warning
2998 return DeclarationName();
2999}
3000
3001IdentifierInfo *ASTImporter::Import(IdentifierInfo *FromId) {
3002 if (!FromId)
3003 return 0;
3004
3005 return &ToContext.Idents.get(FromId->getName());
3006}
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00003007
Douglas Gregor43f54792010-02-17 02:12:47 +00003008Selector ASTImporter::Import(Selector FromSel) {
3009 if (FromSel.isNull())
3010 return Selector();
3011
3012 llvm::SmallVector<IdentifierInfo *, 4> Idents;
3013 Idents.push_back(Import(FromSel.getIdentifierInfoForSlot(0)));
3014 for (unsigned I = 1, N = FromSel.getNumArgs(); I < N; ++I)
3015 Idents.push_back(Import(FromSel.getIdentifierInfoForSlot(I)));
3016 return ToContext.Selectors.getSelector(FromSel.getNumArgs(), Idents.data());
3017}
3018
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00003019DeclarationName ASTImporter::HandleNameConflict(DeclarationName Name,
3020 DeclContext *DC,
3021 unsigned IDNS,
3022 NamedDecl **Decls,
3023 unsigned NumDecls) {
3024 return Name;
3025}
3026
3027DiagnosticBuilder ASTImporter::ToDiag(SourceLocation Loc, unsigned DiagID) {
Douglas Gregor7eeb5972010-02-11 19:21:55 +00003028 return Diags.Report(FullSourceLoc(Loc, ToContext.getSourceManager()),
3029 DiagID);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00003030}
3031
3032DiagnosticBuilder ASTImporter::FromDiag(SourceLocation Loc, unsigned DiagID) {
Douglas Gregor7eeb5972010-02-11 19:21:55 +00003033 return Diags.Report(FullSourceLoc(Loc, FromContext.getSourceManager()),
3034 DiagID);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00003035}
Douglas Gregor8cdbe642010-02-12 23:44:20 +00003036
3037Decl *ASTImporter::Imported(Decl *From, Decl *To) {
3038 ImportedDecls[From] = To;
3039 return To;
Daniel Dunbar9ced5422010-02-13 20:24:39 +00003040}
Douglas Gregorb4964f72010-02-15 23:54:17 +00003041
3042bool ASTImporter::IsStructurallyEquivalent(QualType From, QualType To) {
3043 llvm::DenseMap<Type *, Type *>::iterator Pos
3044 = ImportedTypes.find(From.getTypePtr());
3045 if (Pos != ImportedTypes.end() && ToContext.hasSameType(Import(From), To))
3046 return true;
3047
Benjamin Kramer26d19c52010-02-18 13:02:13 +00003048 StructuralEquivalenceContext Ctx(FromContext, ToContext, Diags,
Douglas Gregorb4964f72010-02-15 23:54:17 +00003049 NonEquivalentDecls);
Benjamin Kramer26d19c52010-02-18 13:02:13 +00003050 return Ctx.IsStructurallyEquivalent(From, To);
Douglas Gregorb4964f72010-02-15 23:54:17 +00003051}