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