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