blob: cde3402f7aa7995895198e9116b0f8f1cc6cd5b4 [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);
102
Douglas Gregor7eeb5972010-02-11 19:21:55 +0000103 // Importing statements
104 Stmt *VisitStmt(Stmt *S);
105
106 // Importing expressions
107 Expr *VisitExpr(Expr *E);
108 Expr *VisitIntegerLiteral(IntegerLiteral *E);
Douglas Gregor98c10182010-02-12 22:17:39 +0000109 Expr *VisitImplicitCastExpr(ImplicitCastExpr *E);
Douglas Gregor96e578d2010-02-05 17:54:41 +0000110 };
111}
112
113//----------------------------------------------------------------------------
Douglas Gregor3996e242010-02-15 22:01:00 +0000114// Structural Equivalence
115//----------------------------------------------------------------------------
116
117namespace {
118 struct StructuralEquivalenceContext {
119 /// \brief AST contexts for which we are checking structural equivalence.
120 ASTContext &C1, &C2;
121
122 /// \brief Diagnostic object used to emit diagnostics.
123 Diagnostic &Diags;
124
125 /// \brief The set of "tentative" equivalences between two canonical
126 /// declarations, mapping from a declaration in the first context to the
127 /// declaration in the second context that we believe to be equivalent.
128 llvm::DenseMap<Decl *, Decl *> TentativeEquivalences;
129
130 /// \brief Queue of declarations in the first context whose equivalence
131 /// with a declaration in the second context still needs to be verified.
132 std::deque<Decl *> DeclsToCheck;
133
Douglas Gregorb4964f72010-02-15 23:54:17 +0000134 /// \brief Declaration (from, to) pairs that are known not to be equivalent
135 /// (which we have already complained about).
136 llvm::DenseSet<std::pair<Decl *, Decl *> > &NonEquivalentDecls;
137
Douglas Gregor3996e242010-02-15 22:01:00 +0000138 /// \brief Whether we're being strict about the spelling of types when
139 /// unifying two types.
140 bool StrictTypeSpelling;
141
142 StructuralEquivalenceContext(ASTContext &C1, ASTContext &C2,
143 Diagnostic &Diags,
Douglas Gregorb4964f72010-02-15 23:54:17 +0000144 llvm::DenseSet<std::pair<Decl *, Decl *> > &NonEquivalentDecls,
Douglas Gregor3996e242010-02-15 22:01:00 +0000145 bool StrictTypeSpelling = false)
Douglas Gregorb4964f72010-02-15 23:54:17 +0000146 : C1(C1), C2(C2), Diags(Diags), NonEquivalentDecls(NonEquivalentDecls),
147 StrictTypeSpelling(StrictTypeSpelling) { }
Douglas Gregor3996e242010-02-15 22:01:00 +0000148
149 /// \brief Determine whether the two declarations are structurally
150 /// equivalent.
151 bool IsStructurallyEquivalent(Decl *D1, Decl *D2);
152
153 /// \brief Determine whether the two types are structurally equivalent.
154 bool IsStructurallyEquivalent(QualType T1, QualType T2);
155
156 private:
157 /// \brief Finish checking all of the structural equivalences.
158 ///
159 /// \returns true if an error occurred, false otherwise.
160 bool Finish();
161
162 public:
163 DiagnosticBuilder Diag1(SourceLocation Loc, unsigned DiagID) {
164 return Diags.Report(FullSourceLoc(Loc, C1.getSourceManager()), DiagID);
165 }
166
167 DiagnosticBuilder Diag2(SourceLocation Loc, unsigned DiagID) {
168 return Diags.Report(FullSourceLoc(Loc, C2.getSourceManager()), DiagID);
169 }
170 };
171}
172
173static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
174 QualType T1, QualType T2);
175static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
176 Decl *D1, Decl *D2);
177
178/// \brief Determine if two APInts have the same value, after zero-extending
179/// one of them (if needed!) to ensure that the bit-widths match.
180static bool IsSameValue(const llvm::APInt &I1, const llvm::APInt &I2) {
181 if (I1.getBitWidth() == I2.getBitWidth())
182 return I1 == I2;
183
184 if (I1.getBitWidth() > I2.getBitWidth())
185 return I1 == llvm::APInt(I2).zext(I1.getBitWidth());
186
187 return llvm::APInt(I1).zext(I2.getBitWidth()) == I2;
188}
189
190/// \brief Determine if two APSInts have the same value, zero- or sign-extending
191/// as needed.
192static bool IsSameValue(const llvm::APSInt &I1, const llvm::APSInt &I2) {
193 if (I1.getBitWidth() == I2.getBitWidth() && I1.isSigned() == I2.isSigned())
194 return I1 == I2;
195
196 // Check for a bit-width mismatch.
197 if (I1.getBitWidth() > I2.getBitWidth())
198 return IsSameValue(I1, llvm::APSInt(I2).extend(I1.getBitWidth()));
199 else if (I2.getBitWidth() > I1.getBitWidth())
200 return IsSameValue(llvm::APSInt(I1).extend(I2.getBitWidth()), I2);
201
202 // We have a signedness mismatch. Turn the signed value into an unsigned
203 // value.
204 if (I1.isSigned()) {
205 if (I1.isNegative())
206 return false;
207
208 return llvm::APSInt(I1, true) == I2;
209 }
210
211 if (I2.isNegative())
212 return false;
213
214 return I1 == llvm::APSInt(I2, true);
215}
216
217/// \brief Determine structural equivalence of two expressions.
218static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
219 Expr *E1, Expr *E2) {
220 if (!E1 || !E2)
221 return E1 == E2;
222
223 // FIXME: Actually perform a structural comparison!
224 return true;
225}
226
227/// \brief Determine whether two identifiers are equivalent.
228static bool IsStructurallyEquivalent(const IdentifierInfo *Name1,
229 const IdentifierInfo *Name2) {
230 if (!Name1 || !Name2)
231 return Name1 == Name2;
232
233 return Name1->getName() == Name2->getName();
234}
235
236/// \brief Determine whether two nested-name-specifiers are equivalent.
237static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
238 NestedNameSpecifier *NNS1,
239 NestedNameSpecifier *NNS2) {
240 // FIXME: Implement!
241 return true;
242}
243
244/// \brief Determine whether two template arguments are equivalent.
245static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
246 const TemplateArgument &Arg1,
247 const TemplateArgument &Arg2) {
248 // FIXME: Implement!
249 return true;
250}
251
252/// \brief Determine structural equivalence for the common part of array
253/// types.
254static bool IsArrayStructurallyEquivalent(StructuralEquivalenceContext &Context,
255 const ArrayType *Array1,
256 const ArrayType *Array2) {
257 if (!IsStructurallyEquivalent(Context,
258 Array1->getElementType(),
259 Array2->getElementType()))
260 return false;
261 if (Array1->getSizeModifier() != Array2->getSizeModifier())
262 return false;
263 if (Array1->getIndexTypeQualifiers() != Array2->getIndexTypeQualifiers())
264 return false;
265
266 return true;
267}
268
269/// \brief Determine structural equivalence of two types.
270static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
271 QualType T1, QualType T2) {
272 if (T1.isNull() || T2.isNull())
273 return T1.isNull() && T2.isNull();
274
275 if (!Context.StrictTypeSpelling) {
276 // We aren't being strict about token-to-token equivalence of types,
277 // so map down to the canonical type.
278 T1 = Context.C1.getCanonicalType(T1);
279 T2 = Context.C2.getCanonicalType(T2);
280 }
281
282 if (T1.getQualifiers() != T2.getQualifiers())
283 return false;
284
Douglas Gregorb4964f72010-02-15 23:54:17 +0000285 Type::TypeClass TC = T1->getTypeClass();
Douglas Gregor3996e242010-02-15 22:01:00 +0000286
Douglas Gregorb4964f72010-02-15 23:54:17 +0000287 if (T1->getTypeClass() != T2->getTypeClass()) {
288 // Compare function types with prototypes vs. without prototypes as if
289 // both did not have prototypes.
290 if (T1->getTypeClass() == Type::FunctionProto &&
291 T2->getTypeClass() == Type::FunctionNoProto)
292 TC = Type::FunctionNoProto;
293 else if (T1->getTypeClass() == Type::FunctionNoProto &&
294 T2->getTypeClass() == Type::FunctionProto)
295 TC = Type::FunctionNoProto;
296 else
297 return false;
298 }
299
300 switch (TC) {
301 case Type::Builtin:
Douglas Gregor3996e242010-02-15 22:01:00 +0000302 // FIXME: Deal with Char_S/Char_U.
303 if (cast<BuiltinType>(T1)->getKind() != cast<BuiltinType>(T2)->getKind())
304 return false;
305 break;
306
307 case Type::Complex:
308 if (!IsStructurallyEquivalent(Context,
309 cast<ComplexType>(T1)->getElementType(),
310 cast<ComplexType>(T2)->getElementType()))
311 return false;
312 break;
313
314 case Type::Pointer:
315 if (!IsStructurallyEquivalent(Context,
316 cast<PointerType>(T1)->getPointeeType(),
317 cast<PointerType>(T2)->getPointeeType()))
318 return false;
319 break;
320
321 case Type::BlockPointer:
322 if (!IsStructurallyEquivalent(Context,
323 cast<BlockPointerType>(T1)->getPointeeType(),
324 cast<BlockPointerType>(T2)->getPointeeType()))
325 return false;
326 break;
327
328 case Type::LValueReference:
329 case Type::RValueReference: {
330 const ReferenceType *Ref1 = cast<ReferenceType>(T1);
331 const ReferenceType *Ref2 = cast<ReferenceType>(T2);
332 if (Ref1->isSpelledAsLValue() != Ref2->isSpelledAsLValue())
333 return false;
334 if (Ref1->isInnerRef() != Ref2->isInnerRef())
335 return false;
336 if (!IsStructurallyEquivalent(Context,
337 Ref1->getPointeeTypeAsWritten(),
338 Ref2->getPointeeTypeAsWritten()))
339 return false;
340 break;
341 }
342
343 case Type::MemberPointer: {
344 const MemberPointerType *MemPtr1 = cast<MemberPointerType>(T1);
345 const MemberPointerType *MemPtr2 = cast<MemberPointerType>(T2);
346 if (!IsStructurallyEquivalent(Context,
347 MemPtr1->getPointeeType(),
348 MemPtr2->getPointeeType()))
349 return false;
350 if (!IsStructurallyEquivalent(Context,
351 QualType(MemPtr1->getClass(), 0),
352 QualType(MemPtr2->getClass(), 0)))
353 return false;
354 break;
355 }
356
357 case Type::ConstantArray: {
358 const ConstantArrayType *Array1 = cast<ConstantArrayType>(T1);
359 const ConstantArrayType *Array2 = cast<ConstantArrayType>(T2);
360 if (!IsSameValue(Array1->getSize(), Array2->getSize()))
361 return false;
362
363 if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
364 return false;
365 break;
366 }
367
368 case Type::IncompleteArray:
369 if (!IsArrayStructurallyEquivalent(Context,
370 cast<ArrayType>(T1),
371 cast<ArrayType>(T2)))
372 return false;
373 break;
374
375 case Type::VariableArray: {
376 const VariableArrayType *Array1 = cast<VariableArrayType>(T1);
377 const VariableArrayType *Array2 = cast<VariableArrayType>(T2);
378 if (!IsStructurallyEquivalent(Context,
379 Array1->getSizeExpr(), Array2->getSizeExpr()))
380 return false;
381
382 if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
383 return false;
384
385 break;
386 }
387
388 case Type::DependentSizedArray: {
389 const DependentSizedArrayType *Array1 = cast<DependentSizedArrayType>(T1);
390 const DependentSizedArrayType *Array2 = cast<DependentSizedArrayType>(T2);
391 if (!IsStructurallyEquivalent(Context,
392 Array1->getSizeExpr(), Array2->getSizeExpr()))
393 return false;
394
395 if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
396 return false;
397
398 break;
399 }
400
401 case Type::DependentSizedExtVector: {
402 const DependentSizedExtVectorType *Vec1
403 = cast<DependentSizedExtVectorType>(T1);
404 const DependentSizedExtVectorType *Vec2
405 = cast<DependentSizedExtVectorType>(T2);
406 if (!IsStructurallyEquivalent(Context,
407 Vec1->getSizeExpr(), Vec2->getSizeExpr()))
408 return false;
409 if (!IsStructurallyEquivalent(Context,
410 Vec1->getElementType(),
411 Vec2->getElementType()))
412 return false;
413 break;
414 }
415
416 case Type::Vector:
417 case Type::ExtVector: {
418 const VectorType *Vec1 = cast<VectorType>(T1);
419 const VectorType *Vec2 = cast<VectorType>(T2);
420 if (!IsStructurallyEquivalent(Context,
421 Vec1->getElementType(),
422 Vec2->getElementType()))
423 return false;
424 if (Vec1->getNumElements() != Vec2->getNumElements())
425 return false;
426 if (Vec1->isAltiVec() != Vec2->isAltiVec())
427 return false;
428 if (Vec1->isPixel() != Vec2->isPixel())
429 return false;
430 }
431
432 case Type::FunctionProto: {
433 const FunctionProtoType *Proto1 = cast<FunctionProtoType>(T1);
434 const FunctionProtoType *Proto2 = cast<FunctionProtoType>(T2);
435 if (Proto1->getNumArgs() != Proto2->getNumArgs())
436 return false;
437 for (unsigned I = 0, N = Proto1->getNumArgs(); I != N; ++I) {
438 if (!IsStructurallyEquivalent(Context,
439 Proto1->getArgType(I),
440 Proto2->getArgType(I)))
441 return false;
442 }
443 if (Proto1->isVariadic() != Proto2->isVariadic())
444 return false;
445 if (Proto1->hasExceptionSpec() != Proto2->hasExceptionSpec())
446 return false;
447 if (Proto1->hasAnyExceptionSpec() != Proto2->hasAnyExceptionSpec())
448 return false;
449 if (Proto1->getNumExceptions() != Proto2->getNumExceptions())
450 return false;
451 for (unsigned I = 0, N = Proto1->getNumExceptions(); I != N; ++I) {
452 if (!IsStructurallyEquivalent(Context,
453 Proto1->getExceptionType(I),
454 Proto2->getExceptionType(I)))
455 return false;
456 }
457 if (Proto1->getTypeQuals() != Proto2->getTypeQuals())
458 return false;
459
460 // Fall through to check the bits common with FunctionNoProtoType.
461 }
462
463 case Type::FunctionNoProto: {
464 const FunctionType *Function1 = cast<FunctionType>(T1);
465 const FunctionType *Function2 = cast<FunctionType>(T2);
466 if (!IsStructurallyEquivalent(Context,
467 Function1->getResultType(),
468 Function2->getResultType()))
469 return false;
470 if (Function1->getNoReturnAttr() != Function2->getNoReturnAttr())
471 return false;
472 if (Function1->getCallConv() != Function2->getCallConv())
473 return false;
474 break;
475 }
476
477 case Type::UnresolvedUsing:
478 if (!IsStructurallyEquivalent(Context,
479 cast<UnresolvedUsingType>(T1)->getDecl(),
480 cast<UnresolvedUsingType>(T2)->getDecl()))
481 return false;
482
483 break;
484
485 case Type::Typedef:
486 if (!IsStructurallyEquivalent(Context,
487 cast<TypedefType>(T1)->getDecl(),
488 cast<TypedefType>(T2)->getDecl()))
489 return false;
490 break;
491
492 case Type::TypeOfExpr:
493 if (!IsStructurallyEquivalent(Context,
494 cast<TypeOfExprType>(T1)->getUnderlyingExpr(),
495 cast<TypeOfExprType>(T2)->getUnderlyingExpr()))
496 return false;
497 break;
498
499 case Type::TypeOf:
500 if (!IsStructurallyEquivalent(Context,
501 cast<TypeOfType>(T1)->getUnderlyingType(),
502 cast<TypeOfType>(T2)->getUnderlyingType()))
503 return false;
504 break;
505
506 case Type::Decltype:
507 if (!IsStructurallyEquivalent(Context,
508 cast<DecltypeType>(T1)->getUnderlyingExpr(),
509 cast<DecltypeType>(T2)->getUnderlyingExpr()))
510 return false;
511 break;
512
513 case Type::Record:
514 case Type::Enum:
515 if (!IsStructurallyEquivalent(Context,
516 cast<TagType>(T1)->getDecl(),
517 cast<TagType>(T2)->getDecl()))
518 return false;
519 break;
520
521 case Type::Elaborated: {
522 const ElaboratedType *Elab1 = cast<ElaboratedType>(T1);
523 const ElaboratedType *Elab2 = cast<ElaboratedType>(T2);
524 if (Elab1->getTagKind() != Elab2->getTagKind())
525 return false;
526 if (!IsStructurallyEquivalent(Context,
527 Elab1->getUnderlyingType(),
528 Elab2->getUnderlyingType()))
529 return false;
530 break;
531 }
532
533 case Type::TemplateTypeParm: {
534 const TemplateTypeParmType *Parm1 = cast<TemplateTypeParmType>(T1);
535 const TemplateTypeParmType *Parm2 = cast<TemplateTypeParmType>(T2);
536 if (Parm1->getDepth() != Parm2->getDepth())
537 return false;
538 if (Parm1->getIndex() != Parm2->getIndex())
539 return false;
540 if (Parm1->isParameterPack() != Parm2->isParameterPack())
541 return false;
542
543 // Names of template type parameters are never significant.
544 break;
545 }
546
547 case Type::SubstTemplateTypeParm: {
548 const SubstTemplateTypeParmType *Subst1
549 = cast<SubstTemplateTypeParmType>(T1);
550 const SubstTemplateTypeParmType *Subst2
551 = cast<SubstTemplateTypeParmType>(T2);
552 if (!IsStructurallyEquivalent(Context,
553 QualType(Subst1->getReplacedParameter(), 0),
554 QualType(Subst2->getReplacedParameter(), 0)))
555 return false;
556 if (!IsStructurallyEquivalent(Context,
557 Subst1->getReplacementType(),
558 Subst2->getReplacementType()))
559 return false;
560 break;
561 }
562
563 case Type::TemplateSpecialization: {
564 const TemplateSpecializationType *Spec1
565 = cast<TemplateSpecializationType>(T1);
566 const TemplateSpecializationType *Spec2
567 = cast<TemplateSpecializationType>(T2);
568 if (!IsStructurallyEquivalent(Context,
569 Spec1->getTemplateName(),
570 Spec2->getTemplateName()))
571 return false;
572 if (Spec1->getNumArgs() != Spec2->getNumArgs())
573 return false;
574 for (unsigned I = 0, N = Spec1->getNumArgs(); I != N; ++I) {
575 if (!IsStructurallyEquivalent(Context,
576 Spec1->getArg(I), Spec2->getArg(I)))
577 return false;
578 }
579 break;
580 }
581
582 case Type::QualifiedName: {
583 const QualifiedNameType *Qual1 = cast<QualifiedNameType>(T1);
584 const QualifiedNameType *Qual2 = cast<QualifiedNameType>(T2);
585 if (!IsStructurallyEquivalent(Context,
586 Qual1->getQualifier(),
587 Qual2->getQualifier()))
588 return false;
589 if (!IsStructurallyEquivalent(Context,
590 Qual1->getNamedType(),
591 Qual2->getNamedType()))
592 return false;
593 break;
594 }
595
596 case Type::Typename: {
597 const TypenameType *Typename1 = cast<TypenameType>(T1);
598 const TypenameType *Typename2 = cast<TypenameType>(T2);
599 if (!IsStructurallyEquivalent(Context,
600 Typename1->getQualifier(),
601 Typename2->getQualifier()))
602 return false;
603 if (!IsStructurallyEquivalent(Typename1->getIdentifier(),
604 Typename2->getIdentifier()))
605 return false;
606 if (!IsStructurallyEquivalent(Context,
607 QualType(Typename1->getTemplateId(), 0),
608 QualType(Typename2->getTemplateId(), 0)))
609 return false;
610
611 break;
612 }
613
614 case Type::ObjCInterface: {
615 const ObjCInterfaceType *Iface1 = cast<ObjCInterfaceType>(T1);
616 const ObjCInterfaceType *Iface2 = cast<ObjCInterfaceType>(T2);
617 if (!IsStructurallyEquivalent(Context,
618 Iface1->getDecl(), Iface2->getDecl()))
619 return false;
620 if (Iface1->getNumProtocols() != Iface2->getNumProtocols())
621 return false;
622 for (unsigned I = 0, N = Iface1->getNumProtocols(); I != N; ++I) {
623 if (!IsStructurallyEquivalent(Context,
624 Iface1->getProtocol(I),
625 Iface2->getProtocol(I)))
626 return false;
627 }
628 break;
629 }
630
631 case Type::ObjCObjectPointer: {
632 const ObjCObjectPointerType *Ptr1 = cast<ObjCObjectPointerType>(T1);
633 const ObjCObjectPointerType *Ptr2 = cast<ObjCObjectPointerType>(T2);
634 if (!IsStructurallyEquivalent(Context,
635 Ptr1->getPointeeType(),
636 Ptr2->getPointeeType()))
637 return false;
638 if (Ptr1->getNumProtocols() != Ptr2->getNumProtocols())
639 return false;
640 for (unsigned I = 0, N = Ptr1->getNumProtocols(); I != N; ++I) {
641 if (!IsStructurallyEquivalent(Context,
642 Ptr1->getProtocol(I),
643 Ptr2->getProtocol(I)))
644 return false;
645 }
646 break;
647 }
648
649 } // end switch
650
651 return true;
652}
653
654/// \brief Determine structural equivalence of two records.
655static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
656 RecordDecl *D1, RecordDecl *D2) {
657 if (D1->isUnion() != D2->isUnion()) {
658 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
659 << Context.C2.getTypeDeclType(D2);
660 Context.Diag1(D1->getLocation(), diag::note_odr_tag_kind_here)
661 << D1->getDeclName() << (unsigned)D1->getTagKind();
662 return false;
663 }
664
Douglas Gregorb4964f72010-02-15 23:54:17 +0000665 // Compare the definitions of these two records. If either or both are
666 // incomplete, we assume that they are equivalent.
667 D1 = D1->getDefinition();
668 D2 = D2->getDefinition();
669 if (!D1 || !D2)
670 return true;
671
Douglas Gregor3996e242010-02-15 22:01:00 +0000672 if (CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(D1)) {
673 if (CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(D2)) {
674 if (D1CXX->getNumBases() != D2CXX->getNumBases()) {
675 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
676 << Context.C2.getTypeDeclType(D2);
677 Context.Diag2(D2->getLocation(), diag::note_odr_number_of_bases)
678 << D2CXX->getNumBases();
679 Context.Diag1(D1->getLocation(), diag::note_odr_number_of_bases)
680 << D1CXX->getNumBases();
681 return false;
682 }
683
684 // Check the base classes.
685 for (CXXRecordDecl::base_class_iterator Base1 = D1CXX->bases_begin(),
686 BaseEnd1 = D1CXX->bases_end(),
687 Base2 = D2CXX->bases_begin();
688 Base1 != BaseEnd1;
689 ++Base1, ++Base2) {
690 if (!IsStructurallyEquivalent(Context,
691 Base1->getType(), Base2->getType())) {
692 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
693 << Context.C2.getTypeDeclType(D2);
694 Context.Diag2(Base2->getSourceRange().getBegin(), diag::note_odr_base)
695 << Base2->getType()
696 << Base2->getSourceRange();
697 Context.Diag1(Base1->getSourceRange().getBegin(), diag::note_odr_base)
698 << Base1->getType()
699 << Base1->getSourceRange();
700 return false;
701 }
702
703 // Check virtual vs. non-virtual inheritance mismatch.
704 if (Base1->isVirtual() != Base2->isVirtual()) {
705 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
706 << Context.C2.getTypeDeclType(D2);
707 Context.Diag2(Base2->getSourceRange().getBegin(),
708 diag::note_odr_virtual_base)
709 << Base2->isVirtual() << Base2->getSourceRange();
710 Context.Diag1(Base1->getSourceRange().getBegin(), diag::note_odr_base)
711 << Base1->isVirtual()
712 << Base1->getSourceRange();
713 return false;
714 }
715 }
716 } else if (D1CXX->getNumBases() > 0) {
717 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
718 << Context.C2.getTypeDeclType(D2);
719 const CXXBaseSpecifier *Base1 = D1CXX->bases_begin();
720 Context.Diag1(Base1->getSourceRange().getBegin(), diag::note_odr_base)
721 << Base1->getType()
722 << Base1->getSourceRange();
723 Context.Diag2(D2->getLocation(), diag::note_odr_missing_base);
724 return false;
725 }
726 }
727
728 // Check the fields for consistency.
729 CXXRecordDecl::field_iterator Field2 = D2->field_begin(),
730 Field2End = D2->field_end();
731 for (CXXRecordDecl::field_iterator Field1 = D1->field_begin(),
732 Field1End = D1->field_end();
733 Field1 != Field1End;
734 ++Field1, ++Field2) {
735 if (Field2 == Field2End) {
736 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
737 << Context.C2.getTypeDeclType(D2);
738 Context.Diag1(Field1->getLocation(), diag::note_odr_field)
739 << Field1->getDeclName() << Field1->getType();
740 Context.Diag2(D2->getLocation(), diag::note_odr_missing_field);
741 return false;
742 }
743
744 if (!IsStructurallyEquivalent(Context,
745 Field1->getType(), Field2->getType())) {
746 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
747 << Context.C2.getTypeDeclType(D2);
748 Context.Diag2(Field2->getLocation(), diag::note_odr_field)
749 << Field2->getDeclName() << Field2->getType();
750 Context.Diag1(Field1->getLocation(), diag::note_odr_field)
751 << Field1->getDeclName() << Field1->getType();
752 return false;
753 }
754
755 if (Field1->isBitField() != Field2->isBitField()) {
756 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
757 << Context.C2.getTypeDeclType(D2);
758 if (Field1->isBitField()) {
759 llvm::APSInt Bits;
760 Field1->getBitWidth()->isIntegerConstantExpr(Bits, Context.C1);
761 Context.Diag1(Field1->getLocation(), diag::note_odr_bit_field)
762 << Field1->getDeclName() << Field1->getType()
763 << Bits.toString(10, false);
764 Context.Diag2(Field2->getLocation(), diag::note_odr_not_bit_field)
765 << Field2->getDeclName();
766 } else {
767 llvm::APSInt Bits;
768 Field2->getBitWidth()->isIntegerConstantExpr(Bits, Context.C2);
769 Context.Diag2(Field2->getLocation(), diag::note_odr_bit_field)
770 << Field2->getDeclName() << Field2->getType()
771 << Bits.toString(10, false);
772 Context.Diag1(Field1->getLocation(),
773 diag::note_odr_not_bit_field)
774 << Field1->getDeclName();
775 }
776 return false;
777 }
778
779 if (Field1->isBitField()) {
780 // Make sure that the bit-fields are the same length.
781 llvm::APSInt Bits1, Bits2;
782 if (!Field1->getBitWidth()->isIntegerConstantExpr(Bits1, Context.C1))
783 return false;
784 if (!Field2->getBitWidth()->isIntegerConstantExpr(Bits2, Context.C2))
785 return false;
786
787 if (!IsSameValue(Bits1, Bits2)) {
788 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
789 << Context.C2.getTypeDeclType(D2);
790 Context.Diag2(Field2->getLocation(), diag::note_odr_bit_field)
791 << Field2->getDeclName() << Field2->getType()
792 << Bits2.toString(10, false);
793 Context.Diag1(Field1->getLocation(), diag::note_odr_bit_field)
794 << Field1->getDeclName() << Field1->getType()
795 << Bits1.toString(10, false);
796 return false;
797 }
798 }
799 }
800
801 if (Field2 != Field2End) {
802 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
803 << Context.C2.getTypeDeclType(D2);
804 Context.Diag2(Field2->getLocation(), diag::note_odr_field)
805 << Field2->getDeclName() << Field2->getType();
806 Context.Diag1(D1->getLocation(), diag::note_odr_missing_field);
807 return false;
808 }
809
810 return true;
811}
812
813/// \brief Determine structural equivalence of two enums.
814static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
815 EnumDecl *D1, EnumDecl *D2) {
816 EnumDecl::enumerator_iterator EC2 = D2->enumerator_begin(),
817 EC2End = D2->enumerator_end();
818 for (EnumDecl::enumerator_iterator EC1 = D1->enumerator_begin(),
819 EC1End = D1->enumerator_end();
820 EC1 != EC1End; ++EC1, ++EC2) {
821 if (EC2 == EC2End) {
822 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
823 << Context.C2.getTypeDeclType(D2);
824 Context.Diag1(EC1->getLocation(), diag::note_odr_enumerator)
825 << EC1->getDeclName()
826 << EC1->getInitVal().toString(10);
827 Context.Diag2(D2->getLocation(), diag::note_odr_missing_enumerator);
828 return false;
829 }
830
831 llvm::APSInt Val1 = EC1->getInitVal();
832 llvm::APSInt Val2 = EC2->getInitVal();
833 if (!IsSameValue(Val1, Val2) ||
834 !IsStructurallyEquivalent(EC1->getIdentifier(), EC2->getIdentifier())) {
835 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
836 << Context.C2.getTypeDeclType(D2);
837 Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
838 << EC2->getDeclName()
839 << EC2->getInitVal().toString(10);
840 Context.Diag1(EC1->getLocation(), diag::note_odr_enumerator)
841 << EC1->getDeclName()
842 << EC1->getInitVal().toString(10);
843 return false;
844 }
845 }
846
847 if (EC2 != EC2End) {
848 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
849 << Context.C2.getTypeDeclType(D2);
850 Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
851 << EC2->getDeclName()
852 << EC2->getInitVal().toString(10);
853 Context.Diag1(D1->getLocation(), diag::note_odr_missing_enumerator);
854 return false;
855 }
856
857 return true;
858}
859
860/// \brief Determine structural equivalence of two declarations.
861static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
862 Decl *D1, Decl *D2) {
863 // FIXME: Check for known structural equivalences via a callback of some sort.
864
Douglas Gregorb4964f72010-02-15 23:54:17 +0000865 // Check whether we already know that these two declarations are not
866 // structurally equivalent.
867 if (Context.NonEquivalentDecls.count(std::make_pair(D1->getCanonicalDecl(),
868 D2->getCanonicalDecl())))
869 return false;
870
Douglas Gregor3996e242010-02-15 22:01:00 +0000871 // Determine whether we've already produced a tentative equivalence for D1.
872 Decl *&EquivToD1 = Context.TentativeEquivalences[D1->getCanonicalDecl()];
873 if (EquivToD1)
874 return EquivToD1 == D2->getCanonicalDecl();
875
876 // Produce a tentative equivalence D1 <-> D2, which will be checked later.
877 EquivToD1 = D2->getCanonicalDecl();
878 Context.DeclsToCheck.push_back(D1->getCanonicalDecl());
879 return true;
880}
881
882bool StructuralEquivalenceContext::IsStructurallyEquivalent(Decl *D1,
883 Decl *D2) {
884 if (!::IsStructurallyEquivalent(*this, D1, D2))
885 return false;
886
887 return !Finish();
888}
889
890bool StructuralEquivalenceContext::IsStructurallyEquivalent(QualType T1,
891 QualType T2) {
892 if (!::IsStructurallyEquivalent(*this, T1, T2))
893 return false;
894
895 return !Finish();
896}
897
898bool StructuralEquivalenceContext::Finish() {
899 while (!DeclsToCheck.empty()) {
900 // Check the next declaration.
901 Decl *D1 = DeclsToCheck.front();
902 DeclsToCheck.pop_front();
903
904 Decl *D2 = TentativeEquivalences[D1];
905 assert(D2 && "Unrecorded tentative equivalence?");
906
Douglas Gregorb4964f72010-02-15 23:54:17 +0000907 bool Equivalent = true;
908
Douglas Gregor3996e242010-02-15 22:01:00 +0000909 // FIXME: Switch on all declaration kinds. For now, we're just going to
910 // check the obvious ones.
911 if (RecordDecl *Record1 = dyn_cast<RecordDecl>(D1)) {
912 if (RecordDecl *Record2 = dyn_cast<RecordDecl>(D2)) {
913 // Check for equivalent structure names.
914 IdentifierInfo *Name1 = Record1->getIdentifier();
915 if (!Name1 && Record1->getTypedefForAnonDecl())
916 Name1 = Record1->getTypedefForAnonDecl()->getIdentifier();
917 IdentifierInfo *Name2 = Record2->getIdentifier();
918 if (!Name2 && Record2->getTypedefForAnonDecl())
919 Name2 = Record2->getTypedefForAnonDecl()->getIdentifier();
Douglas Gregorb4964f72010-02-15 23:54:17 +0000920 if (!::IsStructurallyEquivalent(Name1, Name2) ||
921 !::IsStructurallyEquivalent(*this, Record1, Record2))
922 Equivalent = false;
Douglas Gregor3996e242010-02-15 22:01:00 +0000923 } else {
924 // Record/non-record mismatch.
Douglas Gregorb4964f72010-02-15 23:54:17 +0000925 Equivalent = false;
Douglas Gregor3996e242010-02-15 22:01:00 +0000926 }
Douglas Gregorb4964f72010-02-15 23:54:17 +0000927 } else if (EnumDecl *Enum1 = dyn_cast<EnumDecl>(D1)) {
Douglas Gregor3996e242010-02-15 22:01:00 +0000928 if (EnumDecl *Enum2 = dyn_cast<EnumDecl>(D2)) {
929 // Check for equivalent enum names.
930 IdentifierInfo *Name1 = Enum1->getIdentifier();
931 if (!Name1 && Enum1->getTypedefForAnonDecl())
932 Name1 = Enum1->getTypedefForAnonDecl()->getIdentifier();
933 IdentifierInfo *Name2 = Enum2->getIdentifier();
934 if (!Name2 && Enum2->getTypedefForAnonDecl())
935 Name2 = Enum2->getTypedefForAnonDecl()->getIdentifier();
Douglas Gregorb4964f72010-02-15 23:54:17 +0000936 if (!::IsStructurallyEquivalent(Name1, Name2) ||
937 !::IsStructurallyEquivalent(*this, Enum1, Enum2))
938 Equivalent = false;
Douglas Gregor3996e242010-02-15 22:01:00 +0000939 } else {
940 // Enum/non-enum mismatch
Douglas Gregorb4964f72010-02-15 23:54:17 +0000941 Equivalent = false;
Douglas Gregor3996e242010-02-15 22:01:00 +0000942 }
Douglas Gregorb4964f72010-02-15 23:54:17 +0000943 } else if (TypedefDecl *Typedef1 = dyn_cast<TypedefDecl>(D1)) {
Douglas Gregor3996e242010-02-15 22:01:00 +0000944 if (TypedefDecl *Typedef2 = dyn_cast<TypedefDecl>(D2)) {
945 if (!::IsStructurallyEquivalent(Typedef1->getIdentifier(),
Douglas Gregorb4964f72010-02-15 23:54:17 +0000946 Typedef2->getIdentifier()) ||
947 !::IsStructurallyEquivalent(*this,
Douglas Gregor3996e242010-02-15 22:01:00 +0000948 Typedef1->getUnderlyingType(),
949 Typedef2->getUnderlyingType()))
Douglas Gregorb4964f72010-02-15 23:54:17 +0000950 Equivalent = false;
Douglas Gregor3996e242010-02-15 22:01:00 +0000951 } else {
952 // Typedef/non-typedef mismatch.
Douglas Gregorb4964f72010-02-15 23:54:17 +0000953 Equivalent = false;
Douglas Gregor3996e242010-02-15 22:01:00 +0000954 }
Douglas Gregor3996e242010-02-15 22:01:00 +0000955 }
Douglas Gregorb4964f72010-02-15 23:54:17 +0000956
957 if (!Equivalent) {
958 // Note that these two declarations are not equivalent (and we already
959 // know about it).
960 NonEquivalentDecls.insert(std::make_pair(D1->getCanonicalDecl(),
961 D2->getCanonicalDecl()));
962 return true;
963 }
Douglas Gregor3996e242010-02-15 22:01:00 +0000964 // FIXME: Check other declaration kinds!
965 }
966
967 return false;
968}
969
970//----------------------------------------------------------------------------
Douglas Gregor96e578d2010-02-05 17:54:41 +0000971// Import Types
972//----------------------------------------------------------------------------
973
Douglas Gregore4c83e42010-02-09 22:48:33 +0000974QualType ASTNodeImporter::VisitType(Type *T) {
975 Importer.FromDiag(SourceLocation(), diag::err_unsupported_ast_node)
976 << T->getTypeClassName();
977 return QualType();
978}
979
Douglas Gregor96e578d2010-02-05 17:54:41 +0000980QualType ASTNodeImporter::VisitBuiltinType(BuiltinType *T) {
981 switch (T->getKind()) {
982 case BuiltinType::Void: return Importer.getToContext().VoidTy;
983 case BuiltinType::Bool: return Importer.getToContext().BoolTy;
984
985 case BuiltinType::Char_U:
986 // The context we're importing from has an unsigned 'char'. If we're
987 // importing into a context with a signed 'char', translate to
988 // 'unsigned char' instead.
989 if (Importer.getToContext().getLangOptions().CharIsSigned)
990 return Importer.getToContext().UnsignedCharTy;
991
992 return Importer.getToContext().CharTy;
993
994 case BuiltinType::UChar: return Importer.getToContext().UnsignedCharTy;
995
996 case BuiltinType::Char16:
997 // FIXME: Make sure that the "to" context supports C++!
998 return Importer.getToContext().Char16Ty;
999
1000 case BuiltinType::Char32:
1001 // FIXME: Make sure that the "to" context supports C++!
1002 return Importer.getToContext().Char32Ty;
1003
1004 case BuiltinType::UShort: return Importer.getToContext().UnsignedShortTy;
1005 case BuiltinType::UInt: return Importer.getToContext().UnsignedIntTy;
1006 case BuiltinType::ULong: return Importer.getToContext().UnsignedLongTy;
1007 case BuiltinType::ULongLong:
1008 return Importer.getToContext().UnsignedLongLongTy;
1009 case BuiltinType::UInt128: return Importer.getToContext().UnsignedInt128Ty;
1010
1011 case BuiltinType::Char_S:
1012 // The context we're importing from has an unsigned 'char'. If we're
1013 // importing into a context with a signed 'char', translate to
1014 // 'unsigned char' instead.
1015 if (!Importer.getToContext().getLangOptions().CharIsSigned)
1016 return Importer.getToContext().SignedCharTy;
1017
1018 return Importer.getToContext().CharTy;
1019
1020 case BuiltinType::SChar: return Importer.getToContext().SignedCharTy;
1021 case BuiltinType::WChar:
1022 // FIXME: If not in C++, shall we translate to the C equivalent of
1023 // wchar_t?
1024 return Importer.getToContext().WCharTy;
1025
1026 case BuiltinType::Short : return Importer.getToContext().ShortTy;
1027 case BuiltinType::Int : return Importer.getToContext().IntTy;
1028 case BuiltinType::Long : return Importer.getToContext().LongTy;
1029 case BuiltinType::LongLong : return Importer.getToContext().LongLongTy;
1030 case BuiltinType::Int128 : return Importer.getToContext().Int128Ty;
1031 case BuiltinType::Float: return Importer.getToContext().FloatTy;
1032 case BuiltinType::Double: return Importer.getToContext().DoubleTy;
1033 case BuiltinType::LongDouble: return Importer.getToContext().LongDoubleTy;
1034
1035 case BuiltinType::NullPtr:
1036 // FIXME: Make sure that the "to" context supports C++0x!
1037 return Importer.getToContext().NullPtrTy;
1038
1039 case BuiltinType::Overload: return Importer.getToContext().OverloadTy;
1040 case BuiltinType::Dependent: return Importer.getToContext().DependentTy;
1041 case BuiltinType::UndeducedAuto:
1042 // FIXME: Make sure that the "to" context supports C++0x!
1043 return Importer.getToContext().UndeducedAutoTy;
1044
1045 case BuiltinType::ObjCId:
1046 // FIXME: Make sure that the "to" context supports Objective-C!
1047 return Importer.getToContext().ObjCBuiltinIdTy;
1048
1049 case BuiltinType::ObjCClass:
1050 return Importer.getToContext().ObjCBuiltinClassTy;
1051
1052 case BuiltinType::ObjCSel:
1053 return Importer.getToContext().ObjCBuiltinSelTy;
1054 }
1055
1056 return QualType();
1057}
1058
1059QualType ASTNodeImporter::VisitComplexType(ComplexType *T) {
1060 QualType ToElementType = Importer.Import(T->getElementType());
1061 if (ToElementType.isNull())
1062 return QualType();
1063
1064 return Importer.getToContext().getComplexType(ToElementType);
1065}
1066
1067QualType ASTNodeImporter::VisitPointerType(PointerType *T) {
1068 QualType ToPointeeType = Importer.Import(T->getPointeeType());
1069 if (ToPointeeType.isNull())
1070 return QualType();
1071
1072 return Importer.getToContext().getPointerType(ToPointeeType);
1073}
1074
1075QualType ASTNodeImporter::VisitBlockPointerType(BlockPointerType *T) {
1076 // FIXME: Check for blocks support in "to" context.
1077 QualType ToPointeeType = Importer.Import(T->getPointeeType());
1078 if (ToPointeeType.isNull())
1079 return QualType();
1080
1081 return Importer.getToContext().getBlockPointerType(ToPointeeType);
1082}
1083
1084QualType ASTNodeImporter::VisitLValueReferenceType(LValueReferenceType *T) {
1085 // FIXME: Check for C++ support in "to" context.
1086 QualType ToPointeeType = Importer.Import(T->getPointeeTypeAsWritten());
1087 if (ToPointeeType.isNull())
1088 return QualType();
1089
1090 return Importer.getToContext().getLValueReferenceType(ToPointeeType);
1091}
1092
1093QualType ASTNodeImporter::VisitRValueReferenceType(RValueReferenceType *T) {
1094 // FIXME: Check for C++0x support in "to" context.
1095 QualType ToPointeeType = Importer.Import(T->getPointeeTypeAsWritten());
1096 if (ToPointeeType.isNull())
1097 return QualType();
1098
1099 return Importer.getToContext().getRValueReferenceType(ToPointeeType);
1100}
1101
1102QualType ASTNodeImporter::VisitMemberPointerType(MemberPointerType *T) {
1103 // FIXME: Check for C++ support in "to" context.
1104 QualType ToPointeeType = Importer.Import(T->getPointeeType());
1105 if (ToPointeeType.isNull())
1106 return QualType();
1107
1108 QualType ClassType = Importer.Import(QualType(T->getClass(), 0));
1109 return Importer.getToContext().getMemberPointerType(ToPointeeType,
1110 ClassType.getTypePtr());
1111}
1112
1113QualType ASTNodeImporter::VisitConstantArrayType(ConstantArrayType *T) {
1114 QualType ToElementType = Importer.Import(T->getElementType());
1115 if (ToElementType.isNull())
1116 return QualType();
1117
1118 return Importer.getToContext().getConstantArrayType(ToElementType,
1119 T->getSize(),
1120 T->getSizeModifier(),
1121 T->getIndexTypeCVRQualifiers());
1122}
1123
1124QualType ASTNodeImporter::VisitIncompleteArrayType(IncompleteArrayType *T) {
1125 QualType ToElementType = Importer.Import(T->getElementType());
1126 if (ToElementType.isNull())
1127 return QualType();
1128
1129 return Importer.getToContext().getIncompleteArrayType(ToElementType,
1130 T->getSizeModifier(),
1131 T->getIndexTypeCVRQualifiers());
1132}
1133
1134QualType ASTNodeImporter::VisitVariableArrayType(VariableArrayType *T) {
1135 QualType ToElementType = Importer.Import(T->getElementType());
1136 if (ToElementType.isNull())
1137 return QualType();
1138
1139 Expr *Size = Importer.Import(T->getSizeExpr());
1140 if (!Size)
1141 return QualType();
1142
1143 SourceRange Brackets = Importer.Import(T->getBracketsRange());
1144 return Importer.getToContext().getVariableArrayType(ToElementType, Size,
1145 T->getSizeModifier(),
1146 T->getIndexTypeCVRQualifiers(),
1147 Brackets);
1148}
1149
1150QualType ASTNodeImporter::VisitVectorType(VectorType *T) {
1151 QualType ToElementType = Importer.Import(T->getElementType());
1152 if (ToElementType.isNull())
1153 return QualType();
1154
1155 return Importer.getToContext().getVectorType(ToElementType,
1156 T->getNumElements(),
1157 T->isAltiVec(),
1158 T->isPixel());
1159}
1160
1161QualType ASTNodeImporter::VisitExtVectorType(ExtVectorType *T) {
1162 QualType ToElementType = Importer.Import(T->getElementType());
1163 if (ToElementType.isNull())
1164 return QualType();
1165
1166 return Importer.getToContext().getExtVectorType(ToElementType,
1167 T->getNumElements());
1168}
1169
1170QualType ASTNodeImporter::VisitFunctionNoProtoType(FunctionNoProtoType *T) {
1171 // FIXME: What happens if we're importing a function without a prototype
1172 // into C++? Should we make it variadic?
1173 QualType ToResultType = Importer.Import(T->getResultType());
1174 if (ToResultType.isNull())
1175 return QualType();
1176
1177 return Importer.getToContext().getFunctionNoProtoType(ToResultType,
1178 T->getNoReturnAttr(),
1179 T->getCallConv());
1180}
1181
1182QualType ASTNodeImporter::VisitFunctionProtoType(FunctionProtoType *T) {
1183 QualType ToResultType = Importer.Import(T->getResultType());
1184 if (ToResultType.isNull())
1185 return QualType();
1186
1187 // Import argument types
1188 llvm::SmallVector<QualType, 4> ArgTypes;
1189 for (FunctionProtoType::arg_type_iterator A = T->arg_type_begin(),
1190 AEnd = T->arg_type_end();
1191 A != AEnd; ++A) {
1192 QualType ArgType = Importer.Import(*A);
1193 if (ArgType.isNull())
1194 return QualType();
1195 ArgTypes.push_back(ArgType);
1196 }
1197
1198 // Import exception types
1199 llvm::SmallVector<QualType, 4> ExceptionTypes;
1200 for (FunctionProtoType::exception_iterator E = T->exception_begin(),
1201 EEnd = T->exception_end();
1202 E != EEnd; ++E) {
1203 QualType ExceptionType = Importer.Import(*E);
1204 if (ExceptionType.isNull())
1205 return QualType();
1206 ExceptionTypes.push_back(ExceptionType);
1207 }
1208
1209 return Importer.getToContext().getFunctionType(ToResultType, ArgTypes.data(),
1210 ArgTypes.size(),
1211 T->isVariadic(),
1212 T->getTypeQuals(),
1213 T->hasExceptionSpec(),
1214 T->hasAnyExceptionSpec(),
1215 ExceptionTypes.size(),
1216 ExceptionTypes.data(),
1217 T->getNoReturnAttr(),
1218 T->getCallConv());
1219}
1220
1221QualType ASTNodeImporter::VisitTypedefType(TypedefType *T) {
1222 TypedefDecl *ToDecl
1223 = dyn_cast_or_null<TypedefDecl>(Importer.Import(T->getDecl()));
1224 if (!ToDecl)
1225 return QualType();
1226
1227 return Importer.getToContext().getTypeDeclType(ToDecl);
1228}
1229
1230QualType ASTNodeImporter::VisitTypeOfExprType(TypeOfExprType *T) {
1231 Expr *ToExpr = Importer.Import(T->getUnderlyingExpr());
1232 if (!ToExpr)
1233 return QualType();
1234
1235 return Importer.getToContext().getTypeOfExprType(ToExpr);
1236}
1237
1238QualType ASTNodeImporter::VisitTypeOfType(TypeOfType *T) {
1239 QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType());
1240 if (ToUnderlyingType.isNull())
1241 return QualType();
1242
1243 return Importer.getToContext().getTypeOfType(ToUnderlyingType);
1244}
1245
1246QualType ASTNodeImporter::VisitDecltypeType(DecltypeType *T) {
1247 Expr *ToExpr = Importer.Import(T->getUnderlyingExpr());
1248 if (!ToExpr)
1249 return QualType();
1250
1251 return Importer.getToContext().getDecltypeType(ToExpr);
1252}
1253
1254QualType ASTNodeImporter::VisitRecordType(RecordType *T) {
1255 RecordDecl *ToDecl
1256 = dyn_cast_or_null<RecordDecl>(Importer.Import(T->getDecl()));
1257 if (!ToDecl)
1258 return QualType();
1259
1260 return Importer.getToContext().getTagDeclType(ToDecl);
1261}
1262
1263QualType ASTNodeImporter::VisitEnumType(EnumType *T) {
1264 EnumDecl *ToDecl
1265 = dyn_cast_or_null<EnumDecl>(Importer.Import(T->getDecl()));
1266 if (!ToDecl)
1267 return QualType();
1268
1269 return Importer.getToContext().getTagDeclType(ToDecl);
1270}
1271
1272QualType ASTNodeImporter::VisitElaboratedType(ElaboratedType *T) {
1273 QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType());
1274 if (ToUnderlyingType.isNull())
1275 return QualType();
1276
1277 return Importer.getToContext().getElaboratedType(ToUnderlyingType,
1278 T->getTagKind());
1279}
1280
1281QualType ASTNodeImporter::VisitQualifiedNameType(QualifiedNameType *T) {
1282 NestedNameSpecifier *ToQualifier = Importer.Import(T->getQualifier());
1283 if (!ToQualifier)
1284 return QualType();
1285
1286 QualType ToNamedType = Importer.Import(T->getNamedType());
1287 if (ToNamedType.isNull())
1288 return QualType();
1289
1290 return Importer.getToContext().getQualifiedNameType(ToQualifier, ToNamedType);
1291}
1292
1293QualType ASTNodeImporter::VisitObjCInterfaceType(ObjCInterfaceType *T) {
1294 ObjCInterfaceDecl *Class
1295 = dyn_cast_or_null<ObjCInterfaceDecl>(Importer.Import(T->getDecl()));
1296 if (!Class)
1297 return QualType();
1298
1299 llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
1300 for (ObjCInterfaceType::qual_iterator P = T->qual_begin(),
1301 PEnd = T->qual_end();
1302 P != PEnd; ++P) {
1303 ObjCProtocolDecl *Protocol
1304 = dyn_cast_or_null<ObjCProtocolDecl>(Importer.Import(*P));
1305 if (!Protocol)
1306 return QualType();
1307 Protocols.push_back(Protocol);
1308 }
1309
1310 return Importer.getToContext().getObjCInterfaceType(Class,
1311 Protocols.data(),
1312 Protocols.size());
1313}
1314
1315QualType ASTNodeImporter::VisitObjCObjectPointerType(ObjCObjectPointerType *T) {
1316 QualType ToPointeeType = Importer.Import(T->getPointeeType());
1317 if (ToPointeeType.isNull())
1318 return QualType();
1319
1320 llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
1321 for (ObjCObjectPointerType::qual_iterator P = T->qual_begin(),
1322 PEnd = T->qual_end();
1323 P != PEnd; ++P) {
1324 ObjCProtocolDecl *Protocol
1325 = dyn_cast_or_null<ObjCProtocolDecl>(Importer.Import(*P));
1326 if (!Protocol)
1327 return QualType();
1328 Protocols.push_back(Protocol);
1329 }
1330
1331 return Importer.getToContext().getObjCObjectPointerType(ToPointeeType,
1332 Protocols.data(),
1333 Protocols.size());
1334}
1335
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001336//----------------------------------------------------------------------------
1337// Import Declarations
1338//----------------------------------------------------------------------------
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001339bool ASTNodeImporter::ImportDeclParts(NamedDecl *D, DeclContext *&DC,
1340 DeclContext *&LexicalDC,
1341 DeclarationName &Name,
1342 SourceLocation &Loc) {
1343 // Import the context of this declaration.
1344 DC = Importer.ImportContext(D->getDeclContext());
1345 if (!DC)
1346 return true;
1347
1348 LexicalDC = DC;
1349 if (D->getDeclContext() != D->getLexicalDeclContext()) {
1350 LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
1351 if (!LexicalDC)
1352 return true;
1353 }
1354
1355 // Import the name of this declaration.
1356 Name = Importer.Import(D->getDeclName());
1357 if (D->getDeclName() && !Name)
1358 return true;
1359
1360 // Import the location of this declaration.
1361 Loc = Importer.Import(D->getLocation());
1362 return false;
1363}
1364
Douglas Gregor5c73e912010-02-11 00:48:18 +00001365bool ASTNodeImporter::IsStructuralMatch(RecordDecl *FromRecord,
Douglas Gregor3996e242010-02-15 22:01:00 +00001366 RecordDecl *ToRecord) {
1367 StructuralEquivalenceContext SEC(Importer.getFromContext(),
1368 Importer.getToContext(),
Douglas Gregorb4964f72010-02-15 23:54:17 +00001369 Importer.getDiags(),
1370 Importer.getNonEquivalentDecls());
Douglas Gregor3996e242010-02-15 22:01:00 +00001371 return SEC.IsStructurallyEquivalent(FromRecord, ToRecord);
Douglas Gregor5c73e912010-02-11 00:48:18 +00001372}
1373
Douglas Gregor98c10182010-02-12 22:17:39 +00001374bool ASTNodeImporter::IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToEnum) {
Douglas Gregor3996e242010-02-15 22:01:00 +00001375 StructuralEquivalenceContext SEC(Importer.getFromContext(),
1376 Importer.getToContext(),
Douglas Gregorb4964f72010-02-15 23:54:17 +00001377 Importer.getDiags(),
1378 Importer.getNonEquivalentDecls());
Douglas Gregor3996e242010-02-15 22:01:00 +00001379 return SEC.IsStructurallyEquivalent(FromEnum, ToEnum);
Douglas Gregor98c10182010-02-12 22:17:39 +00001380}
1381
Douglas Gregore4c83e42010-02-09 22:48:33 +00001382Decl *ASTNodeImporter::VisitDecl(Decl *D) {
Douglas Gregor811663e2010-02-10 00:15:17 +00001383 Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node)
Douglas Gregore4c83e42010-02-09 22:48:33 +00001384 << D->getDeclKindName();
1385 return 0;
1386}
1387
Douglas Gregor5fa74c32010-02-10 21:10:29 +00001388Decl *ASTNodeImporter::VisitTypedefDecl(TypedefDecl *D) {
1389 // Import the major distinguishing characteristics of this typedef.
1390 DeclContext *DC, *LexicalDC;
1391 DeclarationName Name;
1392 SourceLocation Loc;
1393 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
1394 return 0;
1395
Douglas Gregor5fa74c32010-02-10 21:10:29 +00001396 // If this typedef is not in block scope, determine whether we've
1397 // seen a typedef with the same name (that we can merge with) or any
1398 // other entity by that name (which name lookup could conflict with).
1399 if (!DC->isFunctionOrMethod()) {
1400 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
1401 unsigned IDNS = Decl::IDNS_Ordinary;
1402 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
1403 Lookup.first != Lookup.second;
1404 ++Lookup.first) {
1405 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
1406 continue;
1407 if (TypedefDecl *FoundTypedef = dyn_cast<TypedefDecl>(*Lookup.first)) {
Douglas Gregorb4964f72010-02-15 23:54:17 +00001408 if (Importer.IsStructurallyEquivalent(D->getUnderlyingType(),
1409 FoundTypedef->getUnderlyingType()))
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001410 return Importer.Imported(D, FoundTypedef);
Douglas Gregor5fa74c32010-02-10 21:10:29 +00001411 }
1412
1413 ConflictingDecls.push_back(*Lookup.first);
1414 }
1415
1416 if (!ConflictingDecls.empty()) {
1417 Name = Importer.HandleNameConflict(Name, DC, IDNS,
1418 ConflictingDecls.data(),
1419 ConflictingDecls.size());
1420 if (!Name)
1421 return 0;
1422 }
1423 }
1424
Douglas Gregorb4964f72010-02-15 23:54:17 +00001425 // Import the underlying type of this typedef;
1426 QualType T = Importer.Import(D->getUnderlyingType());
1427 if (T.isNull())
1428 return 0;
1429
Douglas Gregor5fa74c32010-02-10 21:10:29 +00001430 // Create the new typedef node.
1431 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
1432 TypedefDecl *ToTypedef = TypedefDecl::Create(Importer.getToContext(), DC,
1433 Loc, Name.getAsIdentifierInfo(),
1434 TInfo);
1435 ToTypedef->setLexicalDeclContext(LexicalDC);
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001436 Importer.Imported(D, ToTypedef);
Douglas Gregor5fa74c32010-02-10 21:10:29 +00001437 LexicalDC->addDecl(ToTypedef);
Douglas Gregorb4964f72010-02-15 23:54:17 +00001438
Douglas Gregor5fa74c32010-02-10 21:10:29 +00001439 return ToTypedef;
1440}
1441
Douglas Gregor98c10182010-02-12 22:17:39 +00001442Decl *ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
1443 // Import the major distinguishing characteristics of this enum.
1444 DeclContext *DC, *LexicalDC;
1445 DeclarationName Name;
1446 SourceLocation Loc;
1447 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
1448 return 0;
1449
1450 // Figure out what enum name we're looking for.
1451 unsigned IDNS = Decl::IDNS_Tag;
1452 DeclarationName SearchName = Name;
1453 if (!SearchName && D->getTypedefForAnonDecl()) {
1454 SearchName = Importer.Import(D->getTypedefForAnonDecl()->getDeclName());
1455 IDNS = Decl::IDNS_Ordinary;
1456 } else if (Importer.getToContext().getLangOptions().CPlusPlus)
1457 IDNS |= Decl::IDNS_Ordinary;
1458
1459 // We may already have an enum of the same name; try to find and match it.
1460 if (!DC->isFunctionOrMethod() && SearchName) {
1461 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
1462 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
1463 Lookup.first != Lookup.second;
1464 ++Lookup.first) {
1465 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
1466 continue;
1467
1468 Decl *Found = *Lookup.first;
1469 if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(Found)) {
1470 if (const TagType *Tag = Typedef->getUnderlyingType()->getAs<TagType>())
1471 Found = Tag->getDecl();
1472 }
1473
1474 if (EnumDecl *FoundEnum = dyn_cast<EnumDecl>(Found)) {
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001475 if (IsStructuralMatch(D, FoundEnum))
1476 return Importer.Imported(D, FoundEnum);
Douglas Gregor98c10182010-02-12 22:17:39 +00001477 }
1478
1479 ConflictingDecls.push_back(*Lookup.first);
1480 }
1481
1482 if (!ConflictingDecls.empty()) {
1483 Name = Importer.HandleNameConflict(Name, DC, IDNS,
1484 ConflictingDecls.data(),
1485 ConflictingDecls.size());
1486 }
1487 }
1488
1489 // Create the enum declaration.
Douglas Gregor3996e242010-02-15 22:01:00 +00001490 EnumDecl *D2 = EnumDecl::Create(Importer.getToContext(), DC, Loc,
Douglas Gregor98c10182010-02-12 22:17:39 +00001491 Name.getAsIdentifierInfo(),
1492 Importer.Import(D->getTagKeywordLoc()),
1493 0);
Douglas Gregor3996e242010-02-15 22:01:00 +00001494 D2->setLexicalDeclContext(LexicalDC);
1495 Importer.Imported(D, D2);
1496 LexicalDC->addDecl(D2);
Douglas Gregor98c10182010-02-12 22:17:39 +00001497
1498 // Import the integer type.
1499 QualType ToIntegerType = Importer.Import(D->getIntegerType());
1500 if (ToIntegerType.isNull())
1501 return 0;
Douglas Gregor3996e242010-02-15 22:01:00 +00001502 D2->setIntegerType(ToIntegerType);
Douglas Gregor98c10182010-02-12 22:17:39 +00001503
1504 // Import the definition
1505 if (D->isDefinition()) {
1506 QualType T = Importer.Import(Importer.getFromContext().getTypeDeclType(D));
1507 if (T.isNull())
1508 return 0;
1509
1510 QualType ToPromotionType = Importer.Import(D->getPromotionType());
1511 if (ToPromotionType.isNull())
1512 return 0;
1513
Douglas Gregor3996e242010-02-15 22:01:00 +00001514 D2->startDefinition();
Douglas Gregor98c10182010-02-12 22:17:39 +00001515 for (DeclContext::decl_iterator FromMem = D->decls_begin(),
1516 FromMemEnd = D->decls_end();
1517 FromMem != FromMemEnd;
1518 ++FromMem)
1519 Importer.Import(*FromMem);
1520
Douglas Gregor3996e242010-02-15 22:01:00 +00001521 D2->completeDefinition(T, ToPromotionType);
Douglas Gregor98c10182010-02-12 22:17:39 +00001522 }
1523
Douglas Gregor3996e242010-02-15 22:01:00 +00001524 return D2;
Douglas Gregor98c10182010-02-12 22:17:39 +00001525}
1526
Douglas Gregor5c73e912010-02-11 00:48:18 +00001527Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
1528 // If this record has a definition in the translation unit we're coming from,
1529 // but this particular declaration is not that definition, import the
1530 // definition and map to that.
Douglas Gregor0a5a2212010-02-11 01:04:33 +00001531 TagDecl *Definition = D->getDefinition();
Douglas Gregor5c73e912010-02-11 00:48:18 +00001532 if (Definition && Definition != D) {
1533 Decl *ImportedDef = Importer.Import(Definition);
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001534 if (!ImportedDef)
1535 return 0;
1536
1537 return Importer.Imported(D, ImportedDef);
Douglas Gregor5c73e912010-02-11 00:48:18 +00001538 }
1539
1540 // Import the major distinguishing characteristics of this record.
1541 DeclContext *DC, *LexicalDC;
1542 DeclarationName Name;
1543 SourceLocation Loc;
1544 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
1545 return 0;
1546
1547 // Figure out what structure name we're looking for.
1548 unsigned IDNS = Decl::IDNS_Tag;
1549 DeclarationName SearchName = Name;
1550 if (!SearchName && D->getTypedefForAnonDecl()) {
1551 SearchName = Importer.Import(D->getTypedefForAnonDecl()->getDeclName());
1552 IDNS = Decl::IDNS_Ordinary;
1553 } else if (Importer.getToContext().getLangOptions().CPlusPlus)
1554 IDNS |= Decl::IDNS_Ordinary;
1555
1556 // We may already have a record of the same name; try to find and match it.
Douglas Gregor25791052010-02-12 00:09:27 +00001557 RecordDecl *AdoptDecl = 0;
Douglas Gregor5c73e912010-02-11 00:48:18 +00001558 if (!DC->isFunctionOrMethod() && SearchName) {
1559 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
1560 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
1561 Lookup.first != Lookup.second;
1562 ++Lookup.first) {
1563 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
1564 continue;
1565
1566 Decl *Found = *Lookup.first;
1567 if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(Found)) {
1568 if (const TagType *Tag = Typedef->getUnderlyingType()->getAs<TagType>())
1569 Found = Tag->getDecl();
1570 }
1571
1572 if (RecordDecl *FoundRecord = dyn_cast<RecordDecl>(Found)) {
Douglas Gregor25791052010-02-12 00:09:27 +00001573 if (RecordDecl *FoundDef = FoundRecord->getDefinition()) {
1574 if (!D->isDefinition() || IsStructuralMatch(D, FoundDef)) {
1575 // The record types structurally match, or the "from" translation
1576 // unit only had a forward declaration anyway; call it the same
1577 // function.
1578 // FIXME: For C++, we should also merge methods here.
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001579 return Importer.Imported(D, FoundDef);
Douglas Gregor25791052010-02-12 00:09:27 +00001580 }
1581 } else {
1582 // We have a forward declaration of this type, so adopt that forward
1583 // declaration rather than building a new one.
1584 AdoptDecl = FoundRecord;
1585 continue;
1586 }
Douglas Gregor5c73e912010-02-11 00:48:18 +00001587 }
1588
1589 ConflictingDecls.push_back(*Lookup.first);
1590 }
1591
1592 if (!ConflictingDecls.empty()) {
1593 Name = Importer.HandleNameConflict(Name, DC, IDNS,
1594 ConflictingDecls.data(),
1595 ConflictingDecls.size());
1596 }
1597 }
1598
1599 // Create the record declaration.
Douglas Gregor3996e242010-02-15 22:01:00 +00001600 RecordDecl *D2 = AdoptDecl;
1601 if (!D2) {
1602 if (CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(D)) {
1603 CXXRecordDecl *D2CXX = CXXRecordDecl::Create(Importer.getToContext(),
Douglas Gregor25791052010-02-12 00:09:27 +00001604 D->getTagKind(),
1605 DC, Loc,
1606 Name.getAsIdentifierInfo(),
Douglas Gregor5c73e912010-02-11 00:48:18 +00001607 Importer.Import(D->getTagKeywordLoc()));
Douglas Gregor3996e242010-02-15 22:01:00 +00001608 D2 = D2CXX;
Douglas Gregor25791052010-02-12 00:09:27 +00001609
1610 if (D->isDefinition()) {
1611 // Add base classes.
1612 llvm::SmallVector<CXXBaseSpecifier *, 4> Bases;
1613 for (CXXRecordDecl::base_class_iterator
Douglas Gregor3996e242010-02-15 22:01:00 +00001614 Base1 = D1CXX->bases_begin(),
1615 FromBaseEnd = D1CXX->bases_end();
1616 Base1 != FromBaseEnd;
1617 ++Base1) {
1618 QualType T = Importer.Import(Base1->getType());
Douglas Gregor25791052010-02-12 00:09:27 +00001619 if (T.isNull())
1620 return 0;
1621
1622 Bases.push_back(
1623 new (Importer.getToContext())
Douglas Gregor3996e242010-02-15 22:01:00 +00001624 CXXBaseSpecifier(Importer.Import(Base1->getSourceRange()),
1625 Base1->isVirtual(),
1626 Base1->isBaseOfClass(),
1627 Base1->getAccessSpecifierAsWritten(),
Douglas Gregor5c73e912010-02-11 00:48:18 +00001628 T));
Douglas Gregor25791052010-02-12 00:09:27 +00001629 }
1630 if (!Bases.empty())
Douglas Gregor3996e242010-02-15 22:01:00 +00001631 D2CXX->setBases(Bases.data(), Bases.size());
Douglas Gregor5c73e912010-02-11 00:48:18 +00001632 }
Douglas Gregor25791052010-02-12 00:09:27 +00001633 } else {
Douglas Gregor3996e242010-02-15 22:01:00 +00001634 D2 = RecordDecl::Create(Importer.getToContext(), D->getTagKind(),
Douglas Gregor25791052010-02-12 00:09:27 +00001635 DC, Loc,
1636 Name.getAsIdentifierInfo(),
1637 Importer.Import(D->getTagKeywordLoc()));
Douglas Gregor5c73e912010-02-11 00:48:18 +00001638 }
Douglas Gregor3996e242010-02-15 22:01:00 +00001639 D2->setLexicalDeclContext(LexicalDC);
1640 LexicalDC->addDecl(D2);
Douglas Gregor5c73e912010-02-11 00:48:18 +00001641 }
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001642
Douglas Gregor3996e242010-02-15 22:01:00 +00001643 Importer.Imported(D, D2);
Douglas Gregor25791052010-02-12 00:09:27 +00001644
Douglas Gregor5c73e912010-02-11 00:48:18 +00001645 if (D->isDefinition()) {
Douglas Gregor3996e242010-02-15 22:01:00 +00001646 D2->startDefinition();
Douglas Gregor5c73e912010-02-11 00:48:18 +00001647 for (DeclContext::decl_iterator FromMem = D->decls_begin(),
1648 FromMemEnd = D->decls_end();
1649 FromMem != FromMemEnd;
1650 ++FromMem)
1651 Importer.Import(*FromMem);
1652
Douglas Gregor3996e242010-02-15 22:01:00 +00001653 D2->completeDefinition();
Douglas Gregor5c73e912010-02-11 00:48:18 +00001654 }
1655
Douglas Gregor3996e242010-02-15 22:01:00 +00001656 return D2;
Douglas Gregor5c73e912010-02-11 00:48:18 +00001657}
1658
Douglas Gregor98c10182010-02-12 22:17:39 +00001659Decl *ASTNodeImporter::VisitEnumConstantDecl(EnumConstantDecl *D) {
1660 // Import the major distinguishing characteristics of this enumerator.
1661 DeclContext *DC, *LexicalDC;
1662 DeclarationName Name;
1663 SourceLocation Loc;
Douglas Gregorb4964f72010-02-15 23:54:17 +00001664 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
Douglas Gregor98c10182010-02-12 22:17:39 +00001665 return 0;
Douglas Gregorb4964f72010-02-15 23:54:17 +00001666
1667 QualType T = Importer.Import(D->getType());
1668 if (T.isNull())
1669 return 0;
1670
Douglas Gregor98c10182010-02-12 22:17:39 +00001671 // Determine whether there are any other declarations with the same name and
1672 // in the same context.
1673 if (!LexicalDC->isFunctionOrMethod()) {
1674 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
1675 unsigned IDNS = Decl::IDNS_Ordinary;
1676 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
1677 Lookup.first != Lookup.second;
1678 ++Lookup.first) {
1679 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
1680 continue;
1681
1682 ConflictingDecls.push_back(*Lookup.first);
1683 }
1684
1685 if (!ConflictingDecls.empty()) {
1686 Name = Importer.HandleNameConflict(Name, DC, IDNS,
1687 ConflictingDecls.data(),
1688 ConflictingDecls.size());
1689 if (!Name)
1690 return 0;
1691 }
1692 }
1693
1694 Expr *Init = Importer.Import(D->getInitExpr());
1695 if (D->getInitExpr() && !Init)
1696 return 0;
1697
1698 EnumConstantDecl *ToEnumerator
1699 = EnumConstantDecl::Create(Importer.getToContext(), cast<EnumDecl>(DC), Loc,
1700 Name.getAsIdentifierInfo(), T,
1701 Init, D->getInitVal());
1702 ToEnumerator->setLexicalDeclContext(LexicalDC);
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001703 Importer.Imported(D, ToEnumerator);
Douglas Gregor98c10182010-02-12 22:17:39 +00001704 LexicalDC->addDecl(ToEnumerator);
1705 return ToEnumerator;
1706}
Douglas Gregor5c73e912010-02-11 00:48:18 +00001707
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001708Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
1709 // Import the major distinguishing characteristics of this function.
1710 DeclContext *DC, *LexicalDC;
1711 DeclarationName Name;
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001712 SourceLocation Loc;
Douglas Gregorb4964f72010-02-15 23:54:17 +00001713 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001714 return 0;
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001715
1716 // Try to find a function in our own ("to") context with the same name, same
1717 // type, and in the same context as the function we're importing.
1718 if (!LexicalDC->isFunctionOrMethod()) {
1719 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
1720 unsigned IDNS = Decl::IDNS_Ordinary;
1721 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
1722 Lookup.first != Lookup.second;
1723 ++Lookup.first) {
1724 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
1725 continue;
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001726
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001727 if (FunctionDecl *FoundFunction = dyn_cast<FunctionDecl>(*Lookup.first)) {
1728 if (isExternalLinkage(FoundFunction->getLinkage()) &&
1729 isExternalLinkage(D->getLinkage())) {
Douglas Gregorb4964f72010-02-15 23:54:17 +00001730 if (Importer.IsStructurallyEquivalent(D->getType(),
1731 FoundFunction->getType())) {
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001732 // FIXME: Actually try to merge the body and other attributes.
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001733 return Importer.Imported(D, FoundFunction);
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001734 }
1735
1736 // FIXME: Check for overloading more carefully, e.g., by boosting
1737 // Sema::IsOverload out to the AST library.
1738
1739 // Function overloading is okay in C++.
1740 if (Importer.getToContext().getLangOptions().CPlusPlus)
1741 continue;
1742
1743 // Complain about inconsistent function types.
1744 Importer.ToDiag(Loc, diag::err_odr_function_type_inconsistent)
Douglas Gregorb4964f72010-02-15 23:54:17 +00001745 << Name << D->getType() << FoundFunction->getType();
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001746 Importer.ToDiag(FoundFunction->getLocation(),
1747 diag::note_odr_value_here)
1748 << FoundFunction->getType();
1749 }
1750 }
1751
1752 ConflictingDecls.push_back(*Lookup.first);
1753 }
1754
1755 if (!ConflictingDecls.empty()) {
1756 Name = Importer.HandleNameConflict(Name, DC, IDNS,
1757 ConflictingDecls.data(),
1758 ConflictingDecls.size());
1759 if (!Name)
1760 return 0;
1761 }
Douglas Gregor62d311f2010-02-09 19:21:46 +00001762 }
Douglas Gregorb4964f72010-02-15 23:54:17 +00001763
1764 // Import the type.
1765 QualType T = Importer.Import(D->getType());
1766 if (T.isNull())
1767 return 0;
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001768
1769 // Import the function parameters.
1770 llvm::SmallVector<ParmVarDecl *, 8> Parameters;
1771 for (FunctionDecl::param_iterator P = D->param_begin(), PEnd = D->param_end();
1772 P != PEnd; ++P) {
1773 ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(*P));
1774 if (!ToP)
1775 return 0;
1776
1777 Parameters.push_back(ToP);
1778 }
1779
1780 // Create the imported function.
1781 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
Douglas Gregor43f54792010-02-17 02:12:47 +00001782 FunctionDecl *ToFunction
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001783 = FunctionDecl::Create(Importer.getToContext(), DC, Loc,
1784 Name, T, TInfo, D->getStorageClass(),
1785 D->isInlineSpecified(),
1786 D->hasWrittenPrototype());
Douglas Gregor43f54792010-02-17 02:12:47 +00001787 ToFunction->setLexicalDeclContext(LexicalDC);
1788 Importer.Imported(D, ToFunction);
1789 LexicalDC->addDecl(ToFunction);
Douglas Gregor62d311f2010-02-09 19:21:46 +00001790
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001791 // Set the parameters.
1792 for (unsigned I = 0, N = Parameters.size(); I != N; ++I) {
Douglas Gregor43f54792010-02-17 02:12:47 +00001793 Parameters[I]->setOwningFunction(ToFunction);
1794 ToFunction->addDecl(Parameters[I]);
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001795 }
Douglas Gregor43f54792010-02-17 02:12:47 +00001796 ToFunction->setParams(Parameters.data(), Parameters.size());
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001797
1798 // FIXME: Other bits to merge?
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001799
Douglas Gregor43f54792010-02-17 02:12:47 +00001800 return ToFunction;
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001801}
1802
Douglas Gregor5c73e912010-02-11 00:48:18 +00001803Decl *ASTNodeImporter::VisitFieldDecl(FieldDecl *D) {
1804 // Import the major distinguishing characteristics of a variable.
1805 DeclContext *DC, *LexicalDC;
1806 DeclarationName Name;
Douglas Gregor5c73e912010-02-11 00:48:18 +00001807 SourceLocation Loc;
Douglas Gregorb4964f72010-02-15 23:54:17 +00001808 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
1809 return 0;
1810
1811 // Import the type.
1812 QualType T = Importer.Import(D->getType());
1813 if (T.isNull())
Douglas Gregor5c73e912010-02-11 00:48:18 +00001814 return 0;
1815
1816 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
1817 Expr *BitWidth = Importer.Import(D->getBitWidth());
1818 if (!BitWidth && D->getBitWidth())
1819 return 0;
1820
1821 FieldDecl *ToField = FieldDecl::Create(Importer.getToContext(), DC,
1822 Loc, Name.getAsIdentifierInfo(),
1823 T, TInfo, BitWidth, D->isMutable());
1824 ToField->setLexicalDeclContext(LexicalDC);
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001825 Importer.Imported(D, ToField);
Douglas Gregor5c73e912010-02-11 00:48:18 +00001826 LexicalDC->addDecl(ToField);
1827 return ToField;
1828}
1829
Douglas Gregor7244b0b2010-02-17 00:34:30 +00001830Decl *ASTNodeImporter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
1831 // Import the major distinguishing characteristics of an ivar.
1832 DeclContext *DC, *LexicalDC;
1833 DeclarationName Name;
1834 SourceLocation Loc;
1835 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
1836 return 0;
1837
1838 // Determine whether we've already imported this ivar
1839 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
1840 Lookup.first != Lookup.second;
1841 ++Lookup.first) {
1842 if (ObjCIvarDecl *FoundIvar = dyn_cast<ObjCIvarDecl>(*Lookup.first)) {
1843 if (Importer.IsStructurallyEquivalent(D->getType(),
1844 FoundIvar->getType())) {
1845 Importer.Imported(D, FoundIvar);
1846 return FoundIvar;
1847 }
1848
1849 Importer.ToDiag(Loc, diag::err_odr_ivar_type_inconsistent)
1850 << Name << D->getType() << FoundIvar->getType();
1851 Importer.ToDiag(FoundIvar->getLocation(), diag::note_odr_value_here)
1852 << FoundIvar->getType();
1853 return 0;
1854 }
1855 }
1856
1857 // Import the type.
1858 QualType T = Importer.Import(D->getType());
1859 if (T.isNull())
1860 return 0;
1861
1862 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
1863 Expr *BitWidth = Importer.Import(D->getBitWidth());
1864 if (!BitWidth && D->getBitWidth())
1865 return 0;
1866
1867 ObjCIvarDecl *ToIvar = ObjCIvarDecl::Create(Importer.getToContext(), DC,
1868 Loc, Name.getAsIdentifierInfo(),
1869 T, TInfo, D->getAccessControl(),
1870 BitWidth);
1871 ToIvar->setLexicalDeclContext(LexicalDC);
1872 Importer.Imported(D, ToIvar);
1873 LexicalDC->addDecl(ToIvar);
1874 return ToIvar;
1875
1876}
1877
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001878Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
1879 // Import the major distinguishing characteristics of a variable.
1880 DeclContext *DC, *LexicalDC;
1881 DeclarationName Name;
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001882 SourceLocation Loc;
Douglas Gregorb4964f72010-02-15 23:54:17 +00001883 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001884 return 0;
1885
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001886 // Try to find a variable in our own ("to") context with the same name and
1887 // in the same context as the variable we're importing.
Douglas Gregor62d311f2010-02-09 19:21:46 +00001888 if (D->isFileVarDecl()) {
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001889 VarDecl *MergeWithVar = 0;
1890 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
1891 unsigned IDNS = Decl::IDNS_Ordinary;
Douglas Gregor62d311f2010-02-09 19:21:46 +00001892 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001893 Lookup.first != Lookup.second;
1894 ++Lookup.first) {
1895 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
1896 continue;
1897
1898 if (VarDecl *FoundVar = dyn_cast<VarDecl>(*Lookup.first)) {
1899 // We have found a variable that we may need to merge with. Check it.
1900 if (isExternalLinkage(FoundVar->getLinkage()) &&
1901 isExternalLinkage(D->getLinkage())) {
Douglas Gregorb4964f72010-02-15 23:54:17 +00001902 if (Importer.IsStructurallyEquivalent(D->getType(),
1903 FoundVar->getType())) {
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001904 MergeWithVar = FoundVar;
1905 break;
1906 }
1907
Douglas Gregor56521c52010-02-12 17:23:39 +00001908 const ArrayType *FoundArray
1909 = Importer.getToContext().getAsArrayType(FoundVar->getType());
1910 const ArrayType *TArray
Douglas Gregorb4964f72010-02-15 23:54:17 +00001911 = Importer.getToContext().getAsArrayType(D->getType());
Douglas Gregor56521c52010-02-12 17:23:39 +00001912 if (FoundArray && TArray) {
1913 if (isa<IncompleteArrayType>(FoundArray) &&
1914 isa<ConstantArrayType>(TArray)) {
Douglas Gregorb4964f72010-02-15 23:54:17 +00001915 // Import the type.
1916 QualType T = Importer.Import(D->getType());
1917 if (T.isNull())
1918 return 0;
1919
Douglas Gregor56521c52010-02-12 17:23:39 +00001920 FoundVar->setType(T);
1921 MergeWithVar = FoundVar;
1922 break;
1923 } else if (isa<IncompleteArrayType>(TArray) &&
1924 isa<ConstantArrayType>(FoundArray)) {
1925 MergeWithVar = FoundVar;
1926 break;
Douglas Gregor2fbe5582010-02-10 17:16:49 +00001927 }
1928 }
1929
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001930 Importer.ToDiag(Loc, diag::err_odr_variable_type_inconsistent)
Douglas Gregorb4964f72010-02-15 23:54:17 +00001931 << Name << D->getType() << FoundVar->getType();
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001932 Importer.ToDiag(FoundVar->getLocation(), diag::note_odr_value_here)
1933 << FoundVar->getType();
1934 }
1935 }
1936
1937 ConflictingDecls.push_back(*Lookup.first);
1938 }
1939
1940 if (MergeWithVar) {
1941 // An equivalent variable with external linkage has been found. Link
1942 // the two declarations, then merge them.
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001943 Importer.Imported(D, MergeWithVar);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001944
1945 if (VarDecl *DDef = D->getDefinition()) {
1946 if (VarDecl *ExistingDef = MergeWithVar->getDefinition()) {
1947 Importer.ToDiag(ExistingDef->getLocation(),
1948 diag::err_odr_variable_multiple_def)
1949 << Name;
1950 Importer.FromDiag(DDef->getLocation(), diag::note_odr_defined_here);
1951 } else {
1952 Expr *Init = Importer.Import(DDef->getInit());
Douglas Gregord5058122010-02-11 01:19:42 +00001953 MergeWithVar->setInit(Init);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001954 }
1955 }
1956
1957 return MergeWithVar;
1958 }
1959
1960 if (!ConflictingDecls.empty()) {
1961 Name = Importer.HandleNameConflict(Name, DC, IDNS,
1962 ConflictingDecls.data(),
1963 ConflictingDecls.size());
1964 if (!Name)
1965 return 0;
1966 }
1967 }
Douglas Gregorfa7a0e52010-02-10 17:47:19 +00001968
Douglas Gregorb4964f72010-02-15 23:54:17 +00001969 // Import the type.
1970 QualType T = Importer.Import(D->getType());
1971 if (T.isNull())
1972 return 0;
1973
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001974 // Create the imported variable.
Douglas Gregorfa7a0e52010-02-10 17:47:19 +00001975 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001976 VarDecl *ToVar = VarDecl::Create(Importer.getToContext(), DC, Loc,
1977 Name.getAsIdentifierInfo(), T, TInfo,
1978 D->getStorageClass());
Douglas Gregor62d311f2010-02-09 19:21:46 +00001979 ToVar->setLexicalDeclContext(LexicalDC);
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001980 Importer.Imported(D, ToVar);
Douglas Gregor62d311f2010-02-09 19:21:46 +00001981 LexicalDC->addDecl(ToVar);
1982
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001983 // Merge the initializer.
1984 // FIXME: Can we really import any initializer? Alternatively, we could force
1985 // ourselves to import every declaration of a variable and then only use
1986 // getInit() here.
Douglas Gregord5058122010-02-11 01:19:42 +00001987 ToVar->setInit(Importer.Import(const_cast<Expr *>(D->getAnyInitializer())));
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001988
1989 // FIXME: Other bits to merge?
1990
1991 return ToVar;
1992}
1993
Douglas Gregor8b228d72010-02-17 21:22:52 +00001994Decl *ASTNodeImporter::VisitImplicitParamDecl(ImplicitParamDecl *D) {
1995 // Parameters are created in the translation unit's context, then moved
1996 // into the function declaration's context afterward.
1997 DeclContext *DC = Importer.getToContext().getTranslationUnitDecl();
1998
1999 // Import the name of this declaration.
2000 DeclarationName Name = Importer.Import(D->getDeclName());
2001 if (D->getDeclName() && !Name)
2002 return 0;
2003
2004 // Import the location of this declaration.
2005 SourceLocation Loc = Importer.Import(D->getLocation());
2006
2007 // Import the parameter's type.
2008 QualType T = Importer.Import(D->getType());
2009 if (T.isNull())
2010 return 0;
2011
2012 // Create the imported parameter.
2013 ImplicitParamDecl *ToParm
2014 = ImplicitParamDecl::Create(Importer.getToContext(), DC,
2015 Loc, Name.getAsIdentifierInfo(),
2016 T);
2017 return Importer.Imported(D, ToParm);
2018}
2019
Douglas Gregorbb7930c2010-02-10 19:54:31 +00002020Decl *ASTNodeImporter::VisitParmVarDecl(ParmVarDecl *D) {
2021 // Parameters are created in the translation unit's context, then moved
2022 // into the function declaration's context afterward.
2023 DeclContext *DC = Importer.getToContext().getTranslationUnitDecl();
2024
Douglas Gregorfa7a0e52010-02-10 17:47:19 +00002025 // Import the name of this declaration.
2026 DeclarationName Name = Importer.Import(D->getDeclName());
2027 if (D->getDeclName() && !Name)
2028 return 0;
2029
Douglas Gregorbb7930c2010-02-10 19:54:31 +00002030 // Import the location of this declaration.
2031 SourceLocation Loc = Importer.Import(D->getLocation());
2032
2033 // Import the parameter's type.
2034 QualType T = Importer.Import(D->getType());
2035 if (T.isNull())
2036 return 0;
2037
2038 // Create the imported parameter.
2039 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
2040 ParmVarDecl *ToParm = ParmVarDecl::Create(Importer.getToContext(), DC,
2041 Loc, Name.getAsIdentifierInfo(),
2042 T, TInfo, D->getStorageClass(),
2043 /*FIXME: Default argument*/ 0);
Douglas Gregor8cdbe642010-02-12 23:44:20 +00002044 return Importer.Imported(D, ToParm);
Douglas Gregorbb7930c2010-02-10 19:54:31 +00002045}
2046
Douglas Gregor43f54792010-02-17 02:12:47 +00002047Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
2048 // Import the major distinguishing characteristics of a method.
2049 DeclContext *DC, *LexicalDC;
2050 DeclarationName Name;
2051 SourceLocation Loc;
2052 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2053 return 0;
2054
2055 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
2056 Lookup.first != Lookup.second;
2057 ++Lookup.first) {
2058 if (ObjCMethodDecl *FoundMethod = dyn_cast<ObjCMethodDecl>(*Lookup.first)) {
2059 if (FoundMethod->isInstanceMethod() != D->isInstanceMethod())
2060 continue;
2061
2062 // Check return types.
2063 if (!Importer.IsStructurallyEquivalent(D->getResultType(),
2064 FoundMethod->getResultType())) {
2065 Importer.ToDiag(Loc, diag::err_odr_objc_method_result_type_inconsistent)
2066 << D->isInstanceMethod() << Name
2067 << D->getResultType() << FoundMethod->getResultType();
2068 Importer.ToDiag(FoundMethod->getLocation(),
2069 diag::note_odr_objc_method_here)
2070 << D->isInstanceMethod() << Name;
2071 return 0;
2072 }
2073
2074 // Check the number of parameters.
2075 if (D->param_size() != FoundMethod->param_size()) {
2076 Importer.ToDiag(Loc, diag::err_odr_objc_method_num_params_inconsistent)
2077 << D->isInstanceMethod() << Name
2078 << D->param_size() << FoundMethod->param_size();
2079 Importer.ToDiag(FoundMethod->getLocation(),
2080 diag::note_odr_objc_method_here)
2081 << D->isInstanceMethod() << Name;
2082 return 0;
2083 }
2084
2085 // Check parameter types.
2086 for (ObjCMethodDecl::param_iterator P = D->param_begin(),
2087 PEnd = D->param_end(), FoundP = FoundMethod->param_begin();
2088 P != PEnd; ++P, ++FoundP) {
2089 if (!Importer.IsStructurallyEquivalent((*P)->getType(),
2090 (*FoundP)->getType())) {
2091 Importer.FromDiag((*P)->getLocation(),
2092 diag::err_odr_objc_method_param_type_inconsistent)
2093 << D->isInstanceMethod() << Name
2094 << (*P)->getType() << (*FoundP)->getType();
2095 Importer.ToDiag((*FoundP)->getLocation(), diag::note_odr_value_here)
2096 << (*FoundP)->getType();
2097 return 0;
2098 }
2099 }
2100
2101 // Check variadic/non-variadic.
2102 // Check the number of parameters.
2103 if (D->isVariadic() != FoundMethod->isVariadic()) {
2104 Importer.ToDiag(Loc, diag::err_odr_objc_method_variadic_inconsistent)
2105 << D->isInstanceMethod() << Name;
2106 Importer.ToDiag(FoundMethod->getLocation(),
2107 diag::note_odr_objc_method_here)
2108 << D->isInstanceMethod() << Name;
2109 return 0;
2110 }
2111
2112 // FIXME: Any other bits we need to merge?
2113 return Importer.Imported(D, FoundMethod);
2114 }
2115 }
2116
2117 // Import the result type.
2118 QualType ResultTy = Importer.Import(D->getResultType());
2119 if (ResultTy.isNull())
2120 return 0;
2121
2122 ObjCMethodDecl *ToMethod
2123 = ObjCMethodDecl::Create(Importer.getToContext(),
2124 Loc,
2125 Importer.Import(D->getLocEnd()),
2126 Name.getObjCSelector(),
2127 ResultTy, DC,
2128 D->isInstanceMethod(),
2129 D->isVariadic(),
2130 D->isSynthesized(),
2131 D->getImplementationControl());
2132
2133 // FIXME: When we decide to merge method definitions, we'll need to
2134 // deal with implicit parameters.
2135
2136 // Import the parameters
2137 llvm::SmallVector<ParmVarDecl *, 5> ToParams;
2138 for (ObjCMethodDecl::param_iterator FromP = D->param_begin(),
2139 FromPEnd = D->param_end();
2140 FromP != FromPEnd;
2141 ++FromP) {
2142 ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(*FromP));
2143 if (!ToP)
2144 return 0;
2145
2146 ToParams.push_back(ToP);
2147 }
2148
2149 // Set the parameters.
2150 for (unsigned I = 0, N = ToParams.size(); I != N; ++I) {
2151 ToParams[I]->setOwningFunction(ToMethod);
2152 ToMethod->addDecl(ToParams[I]);
2153 }
2154 ToMethod->setMethodParams(Importer.getToContext(),
2155 ToParams.data(), ToParams.size());
2156
2157 ToMethod->setLexicalDeclContext(LexicalDC);
2158 Importer.Imported(D, ToMethod);
2159 LexicalDC->addDecl(ToMethod);
2160 return ToMethod;
2161}
2162
Douglas Gregor84c51c32010-02-18 01:47:50 +00002163Decl *ASTNodeImporter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
2164 // Import the major distinguishing characteristics of a category.
2165 DeclContext *DC, *LexicalDC;
2166 DeclarationName Name;
2167 SourceLocation Loc;
2168 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2169 return 0;
2170
2171 ObjCInterfaceDecl *ToInterface
2172 = cast_or_null<ObjCInterfaceDecl>(Importer.Import(D->getClassInterface()));
2173 if (!ToInterface)
2174 return 0;
2175
2176 // Determine if we've already encountered this category.
2177 ObjCCategoryDecl *MergeWithCategory
2178 = ToInterface->FindCategoryDeclaration(Name.getAsIdentifierInfo());
2179 ObjCCategoryDecl *ToCategory = MergeWithCategory;
2180 if (!ToCategory) {
2181 ToCategory = ObjCCategoryDecl::Create(Importer.getToContext(), DC,
2182 Importer.Import(D->getAtLoc()),
2183 Loc,
2184 Importer.Import(D->getCategoryNameLoc()),
2185 Name.getAsIdentifierInfo());
2186 ToCategory->setLexicalDeclContext(LexicalDC);
2187 LexicalDC->addDecl(ToCategory);
2188 Importer.Imported(D, ToCategory);
2189
2190 // Link this category into its class's category list.
2191 ToCategory->setClassInterface(ToInterface);
2192 ToCategory->insertNextClassCategory();
2193
2194 // Import protocols
2195 llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
2196 llvm::SmallVector<SourceLocation, 4> ProtocolLocs;
2197 ObjCCategoryDecl::protocol_loc_iterator FromProtoLoc
2198 = D->protocol_loc_begin();
2199 for (ObjCCategoryDecl::protocol_iterator FromProto = D->protocol_begin(),
2200 FromProtoEnd = D->protocol_end();
2201 FromProto != FromProtoEnd;
2202 ++FromProto, ++FromProtoLoc) {
2203 ObjCProtocolDecl *ToProto
2204 = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
2205 if (!ToProto)
2206 return 0;
2207 Protocols.push_back(ToProto);
2208 ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
2209 }
2210
2211 // FIXME: If we're merging, make sure that the protocol list is the same.
2212 ToCategory->setProtocolList(Protocols.data(), Protocols.size(),
2213 ProtocolLocs.data(), Importer.getToContext());
2214
2215 } else {
2216 Importer.Imported(D, ToCategory);
2217 }
2218
2219 // Import all of the members of this category.
2220 for (DeclContext::decl_iterator FromMem = D->decls_begin(),
2221 FromMemEnd = D->decls_end();
2222 FromMem != FromMemEnd;
2223 ++FromMem)
2224 Importer.Import(*FromMem);
2225
2226 // If we have an implementation, import it as well.
2227 if (D->getImplementation()) {
2228 ObjCCategoryImplDecl *Impl
2229 = cast<ObjCCategoryImplDecl>(Importer.Import(D->getImplementation()));
2230 if (!Impl)
2231 return 0;
2232
2233 ToCategory->setImplementation(Impl);
2234 }
2235
2236 return ToCategory;
2237}
2238
Douglas Gregor98d156a2010-02-17 16:12:00 +00002239Decl *ASTNodeImporter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
Douglas Gregor84c51c32010-02-18 01:47:50 +00002240 // Import the major distinguishing characteristics of a protocol.
Douglas Gregor98d156a2010-02-17 16:12:00 +00002241 DeclContext *DC, *LexicalDC;
2242 DeclarationName Name;
2243 SourceLocation Loc;
2244 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2245 return 0;
2246
2247 ObjCProtocolDecl *MergeWithProtocol = 0;
2248 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
2249 Lookup.first != Lookup.second;
2250 ++Lookup.first) {
2251 if (!(*Lookup.first)->isInIdentifierNamespace(Decl::IDNS_ObjCProtocol))
2252 continue;
2253
2254 if ((MergeWithProtocol = dyn_cast<ObjCProtocolDecl>(*Lookup.first)))
2255 break;
2256 }
2257
2258 ObjCProtocolDecl *ToProto = MergeWithProtocol;
2259 if (!ToProto || ToProto->isForwardDecl()) {
2260 if (!ToProto) {
2261 ToProto = ObjCProtocolDecl::Create(Importer.getToContext(), DC, Loc,
2262 Name.getAsIdentifierInfo());
2263 ToProto->setForwardDecl(D->isForwardDecl());
2264 ToProto->setLexicalDeclContext(LexicalDC);
2265 LexicalDC->addDecl(ToProto);
2266 }
2267 Importer.Imported(D, ToProto);
2268
2269 // Import protocols
2270 llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
2271 llvm::SmallVector<SourceLocation, 4> ProtocolLocs;
2272 ObjCProtocolDecl::protocol_loc_iterator
2273 FromProtoLoc = D->protocol_loc_begin();
2274 for (ObjCProtocolDecl::protocol_iterator FromProto = D->protocol_begin(),
2275 FromProtoEnd = D->protocol_end();
2276 FromProto != FromProtoEnd;
2277 ++FromProto, ++FromProtoLoc) {
2278 ObjCProtocolDecl *ToProto
2279 = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
2280 if (!ToProto)
2281 return 0;
2282 Protocols.push_back(ToProto);
2283 ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
2284 }
2285
2286 // FIXME: If we're merging, make sure that the protocol list is the same.
2287 ToProto->setProtocolList(Protocols.data(), Protocols.size(),
2288 ProtocolLocs.data(), Importer.getToContext());
2289 } else {
2290 Importer.Imported(D, ToProto);
2291 }
2292
Douglas Gregor84c51c32010-02-18 01:47:50 +00002293 // Import all of the members of this protocol.
Douglas Gregor98d156a2010-02-17 16:12:00 +00002294 for (DeclContext::decl_iterator FromMem = D->decls_begin(),
2295 FromMemEnd = D->decls_end();
2296 FromMem != FromMemEnd;
2297 ++FromMem)
2298 Importer.Import(*FromMem);
2299
2300 return ToProto;
2301}
2302
Douglas Gregor45635322010-02-16 01:20:57 +00002303Decl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
2304 // Import the major distinguishing characteristics of an @interface.
2305 DeclContext *DC, *LexicalDC;
2306 DeclarationName Name;
2307 SourceLocation Loc;
2308 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2309 return 0;
2310
2311 ObjCInterfaceDecl *MergeWithIface = 0;
2312 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
2313 Lookup.first != Lookup.second;
2314 ++Lookup.first) {
2315 if (!(*Lookup.first)->isInIdentifierNamespace(Decl::IDNS_Ordinary))
2316 continue;
2317
2318 if ((MergeWithIface = dyn_cast<ObjCInterfaceDecl>(*Lookup.first)))
2319 break;
2320 }
2321
2322 ObjCInterfaceDecl *ToIface = MergeWithIface;
2323 if (!ToIface || ToIface->isForwardDecl()) {
2324 if (!ToIface) {
2325 ToIface = ObjCInterfaceDecl::Create(Importer.getToContext(),
2326 DC, Loc,
2327 Name.getAsIdentifierInfo(),
2328 Importer.Import(D->getClassLoc()),
2329 D->isForwardDecl(),
2330 D->isImplicitInterfaceDecl());
Douglas Gregor98d156a2010-02-17 16:12:00 +00002331 ToIface->setForwardDecl(D->isForwardDecl());
Douglas Gregor45635322010-02-16 01:20:57 +00002332 ToIface->setLexicalDeclContext(LexicalDC);
2333 LexicalDC->addDecl(ToIface);
2334 }
2335 Importer.Imported(D, ToIface);
2336
Douglas Gregor45635322010-02-16 01:20:57 +00002337 if (D->getSuperClass()) {
2338 ObjCInterfaceDecl *Super
2339 = cast_or_null<ObjCInterfaceDecl>(Importer.Import(D->getSuperClass()));
2340 if (!Super)
2341 return 0;
2342
2343 ToIface->setSuperClass(Super);
2344 ToIface->setSuperClassLoc(Importer.Import(D->getSuperClassLoc()));
2345 }
2346
2347 // Import protocols
2348 llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
2349 llvm::SmallVector<SourceLocation, 4> ProtocolLocs;
2350 ObjCInterfaceDecl::protocol_loc_iterator
2351 FromProtoLoc = D->protocol_loc_begin();
2352 for (ObjCInterfaceDecl::protocol_iterator FromProto = D->protocol_begin(),
2353 FromProtoEnd = D->protocol_end();
2354 FromProto != FromProtoEnd;
2355 ++FromProto, ++FromProtoLoc) {
2356 ObjCProtocolDecl *ToProto
2357 = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
2358 if (!ToProto)
2359 return 0;
2360 Protocols.push_back(ToProto);
2361 ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
2362 }
2363
2364 // FIXME: If we're merging, make sure that the protocol list is the same.
2365 ToIface->setProtocolList(Protocols.data(), Protocols.size(),
2366 ProtocolLocs.data(), Importer.getToContext());
2367
Douglas Gregor45635322010-02-16 01:20:57 +00002368 // Import @end range
2369 ToIface->setAtEndRange(Importer.Import(D->getAtEndRange()));
2370 } else {
2371 Importer.Imported(D, ToIface);
Douglas Gregor7244b0b2010-02-17 00:34:30 +00002372
2373 // Check for consistency of superclasses.
2374 DeclarationName FromSuperName, ToSuperName;
2375 if (D->getSuperClass())
2376 FromSuperName = Importer.Import(D->getSuperClass()->getDeclName());
2377 if (ToIface->getSuperClass())
2378 ToSuperName = ToIface->getSuperClass()->getDeclName();
2379 if (FromSuperName != ToSuperName) {
2380 Importer.ToDiag(ToIface->getLocation(),
2381 diag::err_odr_objc_superclass_inconsistent)
2382 << ToIface->getDeclName();
2383 if (ToIface->getSuperClass())
2384 Importer.ToDiag(ToIface->getSuperClassLoc(),
2385 diag::note_odr_objc_superclass)
2386 << ToIface->getSuperClass()->getDeclName();
2387 else
2388 Importer.ToDiag(ToIface->getLocation(),
2389 diag::note_odr_objc_missing_superclass);
2390 if (D->getSuperClass())
2391 Importer.FromDiag(D->getSuperClassLoc(),
2392 diag::note_odr_objc_superclass)
2393 << D->getSuperClass()->getDeclName();
2394 else
2395 Importer.FromDiag(D->getLocation(),
2396 diag::note_odr_objc_missing_superclass);
2397 return 0;
2398 }
Douglas Gregor45635322010-02-16 01:20:57 +00002399 }
2400
Douglas Gregor84c51c32010-02-18 01:47:50 +00002401 // Import categories. When the categories themselves are imported, they'll
2402 // hook themselves into this interface.
2403 for (ObjCCategoryDecl *FromCat = D->getCategoryList(); FromCat;
2404 FromCat = FromCat->getNextClassCategory())
2405 Importer.Import(FromCat);
2406
Douglas Gregor45635322010-02-16 01:20:57 +00002407 // Import all of the members of this class.
2408 for (DeclContext::decl_iterator FromMem = D->decls_begin(),
2409 FromMemEnd = D->decls_end();
2410 FromMem != FromMemEnd;
2411 ++FromMem)
2412 Importer.Import(*FromMem);
2413
2414 // If we have an @implementation, import it as well.
2415 if (D->getImplementation()) {
2416 ObjCImplementationDecl *Impl
2417 = cast<ObjCImplementationDecl>(Importer.Import(D->getImplementation()));
2418 if (!Impl)
2419 return 0;
2420
2421 ToIface->setImplementation(Impl);
2422 }
2423
Douglas Gregor98d156a2010-02-17 16:12:00 +00002424 return ToIface;
Douglas Gregor45635322010-02-16 01:20:57 +00002425}
2426
Douglas Gregora11c4582010-02-17 18:02:10 +00002427Decl *ASTNodeImporter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
2428 // Import the major distinguishing characteristics of an @property.
2429 DeclContext *DC, *LexicalDC;
2430 DeclarationName Name;
2431 SourceLocation Loc;
2432 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2433 return 0;
2434
2435 // Check whether we have already imported this property.
2436 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
2437 Lookup.first != Lookup.second;
2438 ++Lookup.first) {
2439 if (ObjCPropertyDecl *FoundProp
2440 = dyn_cast<ObjCPropertyDecl>(*Lookup.first)) {
2441 // Check property types.
2442 if (!Importer.IsStructurallyEquivalent(D->getType(),
2443 FoundProp->getType())) {
2444 Importer.ToDiag(Loc, diag::err_odr_objc_property_type_inconsistent)
2445 << Name << D->getType() << FoundProp->getType();
2446 Importer.ToDiag(FoundProp->getLocation(), diag::note_odr_value_here)
2447 << FoundProp->getType();
2448 return 0;
2449 }
2450
2451 // FIXME: Check property attributes, getters, setters, etc.?
2452
2453 // Consider these properties to be equivalent.
2454 Importer.Imported(D, FoundProp);
2455 return FoundProp;
2456 }
2457 }
2458
2459 // Import the type.
2460 QualType T = Importer.Import(D->getType());
2461 if (T.isNull())
2462 return 0;
2463
2464 // Create the new property.
2465 ObjCPropertyDecl *ToProperty
2466 = ObjCPropertyDecl::Create(Importer.getToContext(), DC, Loc,
2467 Name.getAsIdentifierInfo(),
2468 Importer.Import(D->getAtLoc()),
2469 T,
2470 D->getPropertyImplementation());
2471 Importer.Imported(D, ToProperty);
2472 ToProperty->setLexicalDeclContext(LexicalDC);
2473 LexicalDC->addDecl(ToProperty);
2474
2475 ToProperty->setPropertyAttributes(D->getPropertyAttributes());
2476 ToProperty->setGetterName(Importer.Import(D->getGetterName()));
2477 ToProperty->setSetterName(Importer.Import(D->getSetterName()));
2478 ToProperty->setGetterMethodDecl(
2479 cast_or_null<ObjCMethodDecl>(Importer.Import(D->getGetterMethodDecl())));
2480 ToProperty->setSetterMethodDecl(
2481 cast_or_null<ObjCMethodDecl>(Importer.Import(D->getSetterMethodDecl())));
2482 ToProperty->setPropertyIvarDecl(
2483 cast_or_null<ObjCIvarDecl>(Importer.Import(D->getPropertyIvarDecl())));
2484 return ToProperty;
2485}
2486
Douglas Gregor7eeb5972010-02-11 19:21:55 +00002487//----------------------------------------------------------------------------
2488// Import Statements
2489//----------------------------------------------------------------------------
2490
2491Stmt *ASTNodeImporter::VisitStmt(Stmt *S) {
2492 Importer.FromDiag(S->getLocStart(), diag::err_unsupported_ast_node)
2493 << S->getStmtClassName();
2494 return 0;
2495}
2496
2497//----------------------------------------------------------------------------
2498// Import Expressions
2499//----------------------------------------------------------------------------
2500Expr *ASTNodeImporter::VisitExpr(Expr *E) {
2501 Importer.FromDiag(E->getLocStart(), diag::err_unsupported_ast_node)
2502 << E->getStmtClassName();
2503 return 0;
2504}
2505
2506Expr *ASTNodeImporter::VisitIntegerLiteral(IntegerLiteral *E) {
2507 QualType T = Importer.Import(E->getType());
2508 if (T.isNull())
2509 return 0;
2510
2511 return new (Importer.getToContext())
2512 IntegerLiteral(E->getValue(), T, Importer.Import(E->getLocation()));
2513}
2514
Douglas Gregor98c10182010-02-12 22:17:39 +00002515Expr *ASTNodeImporter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
2516 QualType T = Importer.Import(E->getType());
2517 if (T.isNull())
2518 return 0;
2519
2520 Expr *SubExpr = Importer.Import(E->getSubExpr());
2521 if (!SubExpr)
2522 return 0;
2523
2524 return new (Importer.getToContext()) ImplicitCastExpr(T, E->getCastKind(),
2525 SubExpr,
2526 E->isLvalueCast());
2527}
2528
Douglas Gregor7eeb5972010-02-11 19:21:55 +00002529ASTImporter::ASTImporter(Diagnostic &Diags,
2530 ASTContext &ToContext, FileManager &ToFileManager,
2531 ASTContext &FromContext, FileManager &FromFileManager)
Douglas Gregor96e578d2010-02-05 17:54:41 +00002532 : ToContext(ToContext), FromContext(FromContext),
Douglas Gregor811663e2010-02-10 00:15:17 +00002533 ToFileManager(ToFileManager), FromFileManager(FromFileManager),
Douglas Gregor7eeb5972010-02-11 19:21:55 +00002534 Diags(Diags) {
Douglas Gregor62d311f2010-02-09 19:21:46 +00002535 ImportedDecls[FromContext.getTranslationUnitDecl()]
2536 = ToContext.getTranslationUnitDecl();
2537}
2538
2539ASTImporter::~ASTImporter() { }
Douglas Gregor96e578d2010-02-05 17:54:41 +00002540
2541QualType ASTImporter::Import(QualType FromT) {
2542 if (FromT.isNull())
2543 return QualType();
2544
Douglas Gregorf65bbb32010-02-08 15:18:58 +00002545 // Check whether we've already imported this type.
2546 llvm::DenseMap<Type *, Type *>::iterator Pos
2547 = ImportedTypes.find(FromT.getTypePtr());
2548 if (Pos != ImportedTypes.end())
2549 return ToContext.getQualifiedType(Pos->second, FromT.getQualifiers());
Douglas Gregor96e578d2010-02-05 17:54:41 +00002550
Douglas Gregorf65bbb32010-02-08 15:18:58 +00002551 // Import the type
Douglas Gregor96e578d2010-02-05 17:54:41 +00002552 ASTNodeImporter Importer(*this);
2553 QualType ToT = Importer.Visit(FromT.getTypePtr());
2554 if (ToT.isNull())
2555 return ToT;
2556
Douglas Gregorf65bbb32010-02-08 15:18:58 +00002557 // Record the imported type.
2558 ImportedTypes[FromT.getTypePtr()] = ToT.getTypePtr();
2559
Douglas Gregor96e578d2010-02-05 17:54:41 +00002560 return ToContext.getQualifiedType(ToT, FromT.getQualifiers());
2561}
2562
Douglas Gregor62d311f2010-02-09 19:21:46 +00002563TypeSourceInfo *ASTImporter::Import(TypeSourceInfo *FromTSI) {
Douglas Gregorfa7a0e52010-02-10 17:47:19 +00002564 if (!FromTSI)
2565 return FromTSI;
2566
2567 // FIXME: For now we just create a "trivial" type source info based
2568 // on the type and a seingle location. Implement a real version of
2569 // this.
2570 QualType T = Import(FromTSI->getType());
2571 if (T.isNull())
2572 return 0;
2573
2574 return ToContext.getTrivialTypeSourceInfo(T,
2575 FromTSI->getTypeLoc().getFullSourceRange().getBegin());
Douglas Gregor62d311f2010-02-09 19:21:46 +00002576}
2577
2578Decl *ASTImporter::Import(Decl *FromD) {
2579 if (!FromD)
2580 return 0;
2581
2582 // Check whether we've already imported this declaration.
2583 llvm::DenseMap<Decl *, Decl *>::iterator Pos = ImportedDecls.find(FromD);
2584 if (Pos != ImportedDecls.end())
2585 return Pos->second;
2586
2587 // Import the type
2588 ASTNodeImporter Importer(*this);
2589 Decl *ToD = Importer.Visit(FromD);
2590 if (!ToD)
2591 return 0;
2592
2593 // Record the imported declaration.
2594 ImportedDecls[FromD] = ToD;
Douglas Gregorb4964f72010-02-15 23:54:17 +00002595
2596 if (TagDecl *FromTag = dyn_cast<TagDecl>(FromD)) {
2597 // Keep track of anonymous tags that have an associated typedef.
2598 if (FromTag->getTypedefForAnonDecl())
2599 AnonTagsWithPendingTypedefs.push_back(FromTag);
2600 } else if (TypedefDecl *FromTypedef = dyn_cast<TypedefDecl>(FromD)) {
2601 // When we've finished transforming a typedef, see whether it was the
2602 // typedef for an anonymous tag.
2603 for (llvm::SmallVector<TagDecl *, 4>::iterator
2604 FromTag = AnonTagsWithPendingTypedefs.begin(),
2605 FromTagEnd = AnonTagsWithPendingTypedefs.end();
2606 FromTag != FromTagEnd; ++FromTag) {
2607 if ((*FromTag)->getTypedefForAnonDecl() == FromTypedef) {
2608 if (TagDecl *ToTag = cast_or_null<TagDecl>(Import(*FromTag))) {
2609 // We found the typedef for an anonymous tag; link them.
2610 ToTag->setTypedefForAnonDecl(cast<TypedefDecl>(ToD));
2611 AnonTagsWithPendingTypedefs.erase(FromTag);
2612 break;
2613 }
2614 }
2615 }
2616 }
2617
Douglas Gregor62d311f2010-02-09 19:21:46 +00002618 return ToD;
2619}
2620
2621DeclContext *ASTImporter::ImportContext(DeclContext *FromDC) {
2622 if (!FromDC)
2623 return FromDC;
2624
2625 return cast_or_null<DeclContext>(Import(cast<Decl>(FromDC)));
2626}
2627
2628Expr *ASTImporter::Import(Expr *FromE) {
2629 if (!FromE)
2630 return 0;
2631
2632 return cast_or_null<Expr>(Import(cast<Stmt>(FromE)));
2633}
2634
2635Stmt *ASTImporter::Import(Stmt *FromS) {
2636 if (!FromS)
2637 return 0;
2638
Douglas Gregor7eeb5972010-02-11 19:21:55 +00002639 // Check whether we've already imported this declaration.
2640 llvm::DenseMap<Stmt *, Stmt *>::iterator Pos = ImportedStmts.find(FromS);
2641 if (Pos != ImportedStmts.end())
2642 return Pos->second;
2643
2644 // Import the type
2645 ASTNodeImporter Importer(*this);
2646 Stmt *ToS = Importer.Visit(FromS);
2647 if (!ToS)
2648 return 0;
2649
2650 // Record the imported declaration.
2651 ImportedStmts[FromS] = ToS;
2652 return ToS;
Douglas Gregor62d311f2010-02-09 19:21:46 +00002653}
2654
2655NestedNameSpecifier *ASTImporter::Import(NestedNameSpecifier *FromNNS) {
2656 if (!FromNNS)
2657 return 0;
2658
2659 // FIXME: Implement!
2660 return 0;
2661}
2662
2663SourceLocation ASTImporter::Import(SourceLocation FromLoc) {
2664 if (FromLoc.isInvalid())
2665 return SourceLocation();
2666
Douglas Gregor811663e2010-02-10 00:15:17 +00002667 SourceManager &FromSM = FromContext.getSourceManager();
2668
2669 // For now, map everything down to its spelling location, so that we
2670 // don't have to import macro instantiations.
2671 // FIXME: Import macro instantiations!
2672 FromLoc = FromSM.getSpellingLoc(FromLoc);
2673 std::pair<FileID, unsigned> Decomposed = FromSM.getDecomposedLoc(FromLoc);
2674 SourceManager &ToSM = ToContext.getSourceManager();
2675 return ToSM.getLocForStartOfFile(Import(Decomposed.first))
2676 .getFileLocWithOffset(Decomposed.second);
Douglas Gregor62d311f2010-02-09 19:21:46 +00002677}
2678
2679SourceRange ASTImporter::Import(SourceRange FromRange) {
2680 return SourceRange(Import(FromRange.getBegin()), Import(FromRange.getEnd()));
2681}
2682
Douglas Gregor811663e2010-02-10 00:15:17 +00002683FileID ASTImporter::Import(FileID FromID) {
2684 llvm::DenseMap<unsigned, FileID>::iterator Pos
2685 = ImportedFileIDs.find(FromID.getHashValue());
2686 if (Pos != ImportedFileIDs.end())
2687 return Pos->second;
2688
2689 SourceManager &FromSM = FromContext.getSourceManager();
2690 SourceManager &ToSM = ToContext.getSourceManager();
2691 const SrcMgr::SLocEntry &FromSLoc = FromSM.getSLocEntry(FromID);
2692 assert(FromSLoc.isFile() && "Cannot handle macro instantiations yet");
2693
2694 // Include location of this file.
2695 SourceLocation ToIncludeLoc = Import(FromSLoc.getFile().getIncludeLoc());
2696
2697 // Map the FileID for to the "to" source manager.
2698 FileID ToID;
2699 const SrcMgr::ContentCache *Cache = FromSLoc.getFile().getContentCache();
2700 if (Cache->Entry) {
2701 // FIXME: We probably want to use getVirtualFile(), so we don't hit the
2702 // disk again
2703 // FIXME: We definitely want to re-use the existing MemoryBuffer, rather
2704 // than mmap the files several times.
2705 const FileEntry *Entry = ToFileManager.getFile(Cache->Entry->getName());
2706 ToID = ToSM.createFileID(Entry, ToIncludeLoc,
2707 FromSLoc.getFile().getFileCharacteristic());
2708 } else {
2709 // FIXME: We want to re-use the existing MemoryBuffer!
2710 const llvm::MemoryBuffer *FromBuf = Cache->getBuffer();
2711 llvm::MemoryBuffer *ToBuf
2712 = llvm::MemoryBuffer::getMemBufferCopy(FromBuf->getBufferStart(),
2713 FromBuf->getBufferEnd(),
2714 FromBuf->getBufferIdentifier());
2715 ToID = ToSM.createFileIDForMemBuffer(ToBuf);
2716 }
2717
2718
2719 ImportedFileIDs[FromID.getHashValue()] = ToID;
2720 return ToID;
2721}
2722
Douglas Gregor96e578d2010-02-05 17:54:41 +00002723DeclarationName ASTImporter::Import(DeclarationName FromName) {
2724 if (!FromName)
2725 return DeclarationName();
2726
2727 switch (FromName.getNameKind()) {
2728 case DeclarationName::Identifier:
2729 return Import(FromName.getAsIdentifierInfo());
2730
2731 case DeclarationName::ObjCZeroArgSelector:
2732 case DeclarationName::ObjCOneArgSelector:
2733 case DeclarationName::ObjCMultiArgSelector:
2734 return Import(FromName.getObjCSelector());
2735
2736 case DeclarationName::CXXConstructorName: {
2737 QualType T = Import(FromName.getCXXNameType());
2738 if (T.isNull())
2739 return DeclarationName();
2740
2741 return ToContext.DeclarationNames.getCXXConstructorName(
2742 ToContext.getCanonicalType(T));
2743 }
2744
2745 case DeclarationName::CXXDestructorName: {
2746 QualType T = Import(FromName.getCXXNameType());
2747 if (T.isNull())
2748 return DeclarationName();
2749
2750 return ToContext.DeclarationNames.getCXXDestructorName(
2751 ToContext.getCanonicalType(T));
2752 }
2753
2754 case DeclarationName::CXXConversionFunctionName: {
2755 QualType T = Import(FromName.getCXXNameType());
2756 if (T.isNull())
2757 return DeclarationName();
2758
2759 return ToContext.DeclarationNames.getCXXConversionFunctionName(
2760 ToContext.getCanonicalType(T));
2761 }
2762
2763 case DeclarationName::CXXOperatorName:
2764 return ToContext.DeclarationNames.getCXXOperatorName(
2765 FromName.getCXXOverloadedOperator());
2766
2767 case DeclarationName::CXXLiteralOperatorName:
2768 return ToContext.DeclarationNames.getCXXLiteralOperatorName(
2769 Import(FromName.getCXXLiteralIdentifier()));
2770
2771 case DeclarationName::CXXUsingDirective:
2772 // FIXME: STATICS!
2773 return DeclarationName::getUsingDirectiveName();
2774 }
2775
2776 // Silence bogus GCC warning
2777 return DeclarationName();
2778}
2779
2780IdentifierInfo *ASTImporter::Import(IdentifierInfo *FromId) {
2781 if (!FromId)
2782 return 0;
2783
2784 return &ToContext.Idents.get(FromId->getName());
2785}
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00002786
Douglas Gregor43f54792010-02-17 02:12:47 +00002787Selector ASTImporter::Import(Selector FromSel) {
2788 if (FromSel.isNull())
2789 return Selector();
2790
2791 llvm::SmallVector<IdentifierInfo *, 4> Idents;
2792 Idents.push_back(Import(FromSel.getIdentifierInfoForSlot(0)));
2793 for (unsigned I = 1, N = FromSel.getNumArgs(); I < N; ++I)
2794 Idents.push_back(Import(FromSel.getIdentifierInfoForSlot(I)));
2795 return ToContext.Selectors.getSelector(FromSel.getNumArgs(), Idents.data());
2796}
2797
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00002798DeclarationName ASTImporter::HandleNameConflict(DeclarationName Name,
2799 DeclContext *DC,
2800 unsigned IDNS,
2801 NamedDecl **Decls,
2802 unsigned NumDecls) {
2803 return Name;
2804}
2805
2806DiagnosticBuilder ASTImporter::ToDiag(SourceLocation Loc, unsigned DiagID) {
Douglas Gregor7eeb5972010-02-11 19:21:55 +00002807 return Diags.Report(FullSourceLoc(Loc, ToContext.getSourceManager()),
2808 DiagID);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00002809}
2810
2811DiagnosticBuilder ASTImporter::FromDiag(SourceLocation Loc, unsigned DiagID) {
Douglas Gregor7eeb5972010-02-11 19:21:55 +00002812 return Diags.Report(FullSourceLoc(Loc, FromContext.getSourceManager()),
2813 DiagID);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00002814}
Douglas Gregor8cdbe642010-02-12 23:44:20 +00002815
2816Decl *ASTImporter::Imported(Decl *From, Decl *To) {
2817 ImportedDecls[From] = To;
2818 return To;
Daniel Dunbar9ced5422010-02-13 20:24:39 +00002819}
Douglas Gregorb4964f72010-02-15 23:54:17 +00002820
2821bool ASTImporter::IsStructurallyEquivalent(QualType From, QualType To) {
2822 llvm::DenseMap<Type *, Type *>::iterator Pos
2823 = ImportedTypes.find(From.getTypePtr());
2824 if (Pos != ImportedTypes.end() && ToContext.hasSameType(Import(From), To))
2825 return true;
2826
2827 StructuralEquivalenceContext SEC(FromContext, ToContext, Diags,
2828 NonEquivalentDecls);
2829 return SEC.IsStructurallyEquivalent(From, To);
2830}