blob: 9766d3a370559c97994c03cc080eab2f077bddc7 [file] [log] [blame]
Douglas Gregor1b2949d2010-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 Gregor88523732010-02-10 00:15:17 +000017#include "clang/AST/ASTDiagnostic.h"
Douglas Gregor96a01b42010-02-11 00:48:18 +000018#include "clang/AST/DeclCXX.h"
Douglas Gregor1b2949d2010-02-05 17:54:41 +000019#include "clang/AST/DeclObjC.h"
Douglas Gregor089459a2010-02-08 21:09:39 +000020#include "clang/AST/DeclVisitor.h"
Douglas Gregor4800d952010-02-11 19:21:55 +000021#include "clang/AST/StmtVisitor.h"
Douglas Gregor82fc4bf2010-02-10 17:47:19 +000022#include "clang/AST/TypeLoc.h"
Douglas Gregor1b2949d2010-02-05 17:54:41 +000023#include "clang/AST/TypeVisitor.h"
Douglas Gregor88523732010-02-10 00:15:17 +000024#include "clang/Basic/FileManager.h"
25#include "clang/Basic/SourceManager.h"
26#include "llvm/Support/MemoryBuffer.h"
Douglas Gregor73dc30b2010-02-15 22:01:00 +000027#include <deque>
Douglas Gregor1b2949d2010-02-05 17:54:41 +000028
29using namespace clang;
30
31namespace {
Douglas Gregor089459a2010-02-08 21:09:39 +000032 class ASTNodeImporter : public TypeVisitor<ASTNodeImporter, QualType>,
Douglas Gregor4800d952010-02-11 19:21:55 +000033 public DeclVisitor<ASTNodeImporter, Decl *>,
34 public StmtVisitor<ASTNodeImporter, Stmt *> {
Douglas Gregor1b2949d2010-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 Gregor9bed8792010-02-09 19:21:46 +000041 using DeclVisitor<ASTNodeImporter, Decl *>::Visit;
Douglas Gregor4800d952010-02-11 19:21:55 +000042 using StmtVisitor<ASTNodeImporter, Stmt *>::Visit;
Douglas Gregor1b2949d2010-02-05 17:54:41 +000043
44 // Importing types
Douglas Gregor89cc9d62010-02-09 22:48:33 +000045 QualType VisitType(Type *T);
Douglas Gregor1b2949d2010-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);
Douglas Gregor4714c122010-03-31 17:34:00 +000076 // FIXME: DependentNameType
Douglas Gregor1b2949d2010-02-05 17:54:41 +000077 QualType VisitObjCInterfaceType(ObjCInterfaceType *T);
78 QualType VisitObjCObjectPointerType(ObjCObjectPointerType *T);
Douglas Gregor089459a2010-02-08 21:09:39 +000079
80 // Importing declarations
Douglas Gregora404ea62010-02-10 19:54:31 +000081 bool ImportDeclParts(NamedDecl *D, DeclContext *&DC,
82 DeclContext *&LexicalDC, DeclarationName &Name,
Douglas Gregor788c62d2010-02-21 18:26:36 +000083 SourceLocation &Loc);
Douglas Gregor083a8212010-02-21 18:24:45 +000084 void ImportDeclContext(DeclContext *FromDC);
Douglas Gregor96a01b42010-02-11 00:48:18 +000085 bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord);
Douglas Gregor73dc30b2010-02-15 22:01:00 +000086 bool IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToRecord);
Douglas Gregor89cc9d62010-02-09 22:48:33 +000087 Decl *VisitDecl(Decl *D);
Douglas Gregor788c62d2010-02-21 18:26:36 +000088 Decl *VisitNamespaceDecl(NamespaceDecl *D);
Douglas Gregor9e5d9962010-02-10 21:10:29 +000089 Decl *VisitTypedefDecl(TypedefDecl *D);
Douglas Gregor36ead2e2010-02-12 22:17:39 +000090 Decl *VisitEnumDecl(EnumDecl *D);
Douglas Gregor96a01b42010-02-11 00:48:18 +000091 Decl *VisitRecordDecl(RecordDecl *D);
Douglas Gregor36ead2e2010-02-12 22:17:39 +000092 Decl *VisitEnumConstantDecl(EnumConstantDecl *D);
Douglas Gregora404ea62010-02-10 19:54:31 +000093 Decl *VisitFunctionDecl(FunctionDecl *D);
Douglas Gregorc144f352010-02-21 18:29:16 +000094 Decl *VisitCXXMethodDecl(CXXMethodDecl *D);
95 Decl *VisitCXXConstructorDecl(CXXConstructorDecl *D);
96 Decl *VisitCXXDestructorDecl(CXXDestructorDecl *D);
97 Decl *VisitCXXConversionDecl(CXXConversionDecl *D);
Douglas Gregor96a01b42010-02-11 00:48:18 +000098 Decl *VisitFieldDecl(FieldDecl *D);
Douglas Gregor2e55e3a2010-02-17 00:34:30 +000099 Decl *VisitObjCIvarDecl(ObjCIvarDecl *D);
Douglas Gregor089459a2010-02-08 21:09:39 +0000100 Decl *VisitVarDecl(VarDecl *D);
Douglas Gregor2cd00932010-02-17 21:22:52 +0000101 Decl *VisitImplicitParamDecl(ImplicitParamDecl *D);
Douglas Gregora404ea62010-02-10 19:54:31 +0000102 Decl *VisitParmVarDecl(ParmVarDecl *D);
Douglas Gregorc3f2d2b2010-02-17 02:12:47 +0000103 Decl *VisitObjCMethodDecl(ObjCMethodDecl *D);
Douglas Gregorb4677b62010-02-18 01:47:50 +0000104 Decl *VisitObjCCategoryDecl(ObjCCategoryDecl *D);
Douglas Gregor2e2a4002010-02-17 16:12:00 +0000105 Decl *VisitObjCProtocolDecl(ObjCProtocolDecl *D);
Douglas Gregora12d2942010-02-16 01:20:57 +0000106 Decl *VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
Douglas Gregore3261622010-02-17 18:02:10 +0000107 Decl *VisitObjCPropertyDecl(ObjCPropertyDecl *D);
Douglas Gregor2b785022010-02-18 02:12:22 +0000108 Decl *VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D);
Douglas Gregora2bc15b2010-02-18 02:04:09 +0000109 Decl *VisitObjCClassDecl(ObjCClassDecl *D);
110
Douglas Gregor4800d952010-02-11 19:21:55 +0000111 // Importing statements
112 Stmt *VisitStmt(Stmt *S);
113
114 // Importing expressions
115 Expr *VisitExpr(Expr *E);
Douglas Gregor44080632010-02-19 01:17:02 +0000116 Expr *VisitDeclRefExpr(DeclRefExpr *E);
Douglas Gregor4800d952010-02-11 19:21:55 +0000117 Expr *VisitIntegerLiteral(IntegerLiteral *E);
Douglas Gregorb2e400a2010-02-18 02:21:22 +0000118 Expr *VisitCharacterLiteral(CharacterLiteral *E);
Douglas Gregorf638f952010-02-19 01:07:06 +0000119 Expr *VisitParenExpr(ParenExpr *E);
120 Expr *VisitUnaryOperator(UnaryOperator *E);
Douglas Gregorbd249a52010-02-19 01:24:23 +0000121 Expr *VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E);
Douglas Gregorf638f952010-02-19 01:07:06 +0000122 Expr *VisitBinaryOperator(BinaryOperator *E);
123 Expr *VisitCompoundAssignOperator(CompoundAssignOperator *E);
Douglas Gregor36ead2e2010-02-12 22:17:39 +0000124 Expr *VisitImplicitCastExpr(ImplicitCastExpr *E);
Douglas Gregor008847a2010-02-19 01:32:14 +0000125 Expr *VisitCStyleCastExpr(CStyleCastExpr *E);
Douglas Gregor1b2949d2010-02-05 17:54:41 +0000126 };
127}
128
129//----------------------------------------------------------------------------
Douglas Gregor73dc30b2010-02-15 22:01:00 +0000130// Structural Equivalence
131//----------------------------------------------------------------------------
132
133namespace {
134 struct StructuralEquivalenceContext {
135 /// \brief AST contexts for which we are checking structural equivalence.
136 ASTContext &C1, &C2;
137
138 /// \brief Diagnostic object used to emit diagnostics.
139 Diagnostic &Diags;
140
141 /// \brief The set of "tentative" equivalences between two canonical
142 /// declarations, mapping from a declaration in the first context to the
143 /// declaration in the second context that we believe to be equivalent.
144 llvm::DenseMap<Decl *, Decl *> TentativeEquivalences;
145
146 /// \brief Queue of declarations in the first context whose equivalence
147 /// with a declaration in the second context still needs to be verified.
148 std::deque<Decl *> DeclsToCheck;
149
Douglas Gregorea35d112010-02-15 23:54:17 +0000150 /// \brief Declaration (from, to) pairs that are known not to be equivalent
151 /// (which we have already complained about).
152 llvm::DenseSet<std::pair<Decl *, Decl *> > &NonEquivalentDecls;
153
Douglas Gregor73dc30b2010-02-15 22:01:00 +0000154 /// \brief Whether we're being strict about the spelling of types when
155 /// unifying two types.
156 bool StrictTypeSpelling;
157
158 StructuralEquivalenceContext(ASTContext &C1, ASTContext &C2,
159 Diagnostic &Diags,
Douglas Gregorea35d112010-02-15 23:54:17 +0000160 llvm::DenseSet<std::pair<Decl *, Decl *> > &NonEquivalentDecls,
Douglas Gregor73dc30b2010-02-15 22:01:00 +0000161 bool StrictTypeSpelling = false)
Douglas Gregorea35d112010-02-15 23:54:17 +0000162 : C1(C1), C2(C2), Diags(Diags), NonEquivalentDecls(NonEquivalentDecls),
163 StrictTypeSpelling(StrictTypeSpelling) { }
Douglas Gregor73dc30b2010-02-15 22:01:00 +0000164
165 /// \brief Determine whether the two declarations are structurally
166 /// equivalent.
167 bool IsStructurallyEquivalent(Decl *D1, Decl *D2);
168
169 /// \brief Determine whether the two types are structurally equivalent.
170 bool IsStructurallyEquivalent(QualType T1, QualType T2);
171
172 private:
173 /// \brief Finish checking all of the structural equivalences.
174 ///
175 /// \returns true if an error occurred, false otherwise.
176 bool Finish();
177
178 public:
179 DiagnosticBuilder Diag1(SourceLocation Loc, unsigned DiagID) {
180 return Diags.Report(FullSourceLoc(Loc, C1.getSourceManager()), DiagID);
181 }
182
183 DiagnosticBuilder Diag2(SourceLocation Loc, unsigned DiagID) {
184 return Diags.Report(FullSourceLoc(Loc, C2.getSourceManager()), DiagID);
185 }
186 };
187}
188
189static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
190 QualType T1, QualType T2);
191static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
192 Decl *D1, Decl *D2);
193
194/// \brief Determine if two APInts have the same value, after zero-extending
195/// one of them (if needed!) to ensure that the bit-widths match.
196static bool IsSameValue(const llvm::APInt &I1, const llvm::APInt &I2) {
197 if (I1.getBitWidth() == I2.getBitWidth())
198 return I1 == I2;
199
200 if (I1.getBitWidth() > I2.getBitWidth())
201 return I1 == llvm::APInt(I2).zext(I1.getBitWidth());
202
203 return llvm::APInt(I1).zext(I2.getBitWidth()) == I2;
204}
205
206/// \brief Determine if two APSInts have the same value, zero- or sign-extending
207/// as needed.
208static bool IsSameValue(const llvm::APSInt &I1, const llvm::APSInt &I2) {
209 if (I1.getBitWidth() == I2.getBitWidth() && I1.isSigned() == I2.isSigned())
210 return I1 == I2;
211
212 // Check for a bit-width mismatch.
213 if (I1.getBitWidth() > I2.getBitWidth())
214 return IsSameValue(I1, llvm::APSInt(I2).extend(I1.getBitWidth()));
215 else if (I2.getBitWidth() > I1.getBitWidth())
216 return IsSameValue(llvm::APSInt(I1).extend(I2.getBitWidth()), I2);
217
218 // We have a signedness mismatch. Turn the signed value into an unsigned
219 // value.
220 if (I1.isSigned()) {
221 if (I1.isNegative())
222 return false;
223
224 return llvm::APSInt(I1, true) == I2;
225 }
226
227 if (I2.isNegative())
228 return false;
229
230 return I1 == llvm::APSInt(I2, true);
231}
232
233/// \brief Determine structural equivalence of two expressions.
234static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
235 Expr *E1, Expr *E2) {
236 if (!E1 || !E2)
237 return E1 == E2;
238
239 // FIXME: Actually perform a structural comparison!
240 return true;
241}
242
243/// \brief Determine whether two identifiers are equivalent.
244static bool IsStructurallyEquivalent(const IdentifierInfo *Name1,
245 const IdentifierInfo *Name2) {
246 if (!Name1 || !Name2)
247 return Name1 == Name2;
248
249 return Name1->getName() == Name2->getName();
250}
251
252/// \brief Determine whether two nested-name-specifiers are equivalent.
253static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
254 NestedNameSpecifier *NNS1,
255 NestedNameSpecifier *NNS2) {
256 // FIXME: Implement!
257 return true;
258}
259
260/// \brief Determine whether two template arguments are equivalent.
261static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
262 const TemplateArgument &Arg1,
263 const TemplateArgument &Arg2) {
264 // FIXME: Implement!
265 return true;
266}
267
268/// \brief Determine structural equivalence for the common part of array
269/// types.
270static bool IsArrayStructurallyEquivalent(StructuralEquivalenceContext &Context,
271 const ArrayType *Array1,
272 const ArrayType *Array2) {
273 if (!IsStructurallyEquivalent(Context,
274 Array1->getElementType(),
275 Array2->getElementType()))
276 return false;
277 if (Array1->getSizeModifier() != Array2->getSizeModifier())
278 return false;
279 if (Array1->getIndexTypeQualifiers() != Array2->getIndexTypeQualifiers())
280 return false;
281
282 return true;
283}
284
285/// \brief Determine structural equivalence of two types.
286static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
287 QualType T1, QualType T2) {
288 if (T1.isNull() || T2.isNull())
289 return T1.isNull() && T2.isNull();
290
291 if (!Context.StrictTypeSpelling) {
292 // We aren't being strict about token-to-token equivalence of types,
293 // so map down to the canonical type.
294 T1 = Context.C1.getCanonicalType(T1);
295 T2 = Context.C2.getCanonicalType(T2);
296 }
297
298 if (T1.getQualifiers() != T2.getQualifiers())
299 return false;
300
Douglas Gregorea35d112010-02-15 23:54:17 +0000301 Type::TypeClass TC = T1->getTypeClass();
Douglas Gregor73dc30b2010-02-15 22:01:00 +0000302
Douglas Gregorea35d112010-02-15 23:54:17 +0000303 if (T1->getTypeClass() != T2->getTypeClass()) {
304 // Compare function types with prototypes vs. without prototypes as if
305 // both did not have prototypes.
306 if (T1->getTypeClass() == Type::FunctionProto &&
307 T2->getTypeClass() == Type::FunctionNoProto)
308 TC = Type::FunctionNoProto;
309 else if (T1->getTypeClass() == Type::FunctionNoProto &&
310 T2->getTypeClass() == Type::FunctionProto)
311 TC = Type::FunctionNoProto;
312 else
313 return false;
314 }
315
316 switch (TC) {
317 case Type::Builtin:
Douglas Gregor73dc30b2010-02-15 22:01:00 +0000318 // FIXME: Deal with Char_S/Char_U.
319 if (cast<BuiltinType>(T1)->getKind() != cast<BuiltinType>(T2)->getKind())
320 return false;
321 break;
322
323 case Type::Complex:
324 if (!IsStructurallyEquivalent(Context,
325 cast<ComplexType>(T1)->getElementType(),
326 cast<ComplexType>(T2)->getElementType()))
327 return false;
328 break;
329
330 case Type::Pointer:
331 if (!IsStructurallyEquivalent(Context,
332 cast<PointerType>(T1)->getPointeeType(),
333 cast<PointerType>(T2)->getPointeeType()))
334 return false;
335 break;
336
337 case Type::BlockPointer:
338 if (!IsStructurallyEquivalent(Context,
339 cast<BlockPointerType>(T1)->getPointeeType(),
340 cast<BlockPointerType>(T2)->getPointeeType()))
341 return false;
342 break;
343
344 case Type::LValueReference:
345 case Type::RValueReference: {
346 const ReferenceType *Ref1 = cast<ReferenceType>(T1);
347 const ReferenceType *Ref2 = cast<ReferenceType>(T2);
348 if (Ref1->isSpelledAsLValue() != Ref2->isSpelledAsLValue())
349 return false;
350 if (Ref1->isInnerRef() != Ref2->isInnerRef())
351 return false;
352 if (!IsStructurallyEquivalent(Context,
353 Ref1->getPointeeTypeAsWritten(),
354 Ref2->getPointeeTypeAsWritten()))
355 return false;
356 break;
357 }
358
359 case Type::MemberPointer: {
360 const MemberPointerType *MemPtr1 = cast<MemberPointerType>(T1);
361 const MemberPointerType *MemPtr2 = cast<MemberPointerType>(T2);
362 if (!IsStructurallyEquivalent(Context,
363 MemPtr1->getPointeeType(),
364 MemPtr2->getPointeeType()))
365 return false;
366 if (!IsStructurallyEquivalent(Context,
367 QualType(MemPtr1->getClass(), 0),
368 QualType(MemPtr2->getClass(), 0)))
369 return false;
370 break;
371 }
372
373 case Type::ConstantArray: {
374 const ConstantArrayType *Array1 = cast<ConstantArrayType>(T1);
375 const ConstantArrayType *Array2 = cast<ConstantArrayType>(T2);
376 if (!IsSameValue(Array1->getSize(), Array2->getSize()))
377 return false;
378
379 if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
380 return false;
381 break;
382 }
383
384 case Type::IncompleteArray:
385 if (!IsArrayStructurallyEquivalent(Context,
386 cast<ArrayType>(T1),
387 cast<ArrayType>(T2)))
388 return false;
389 break;
390
391 case Type::VariableArray: {
392 const VariableArrayType *Array1 = cast<VariableArrayType>(T1);
393 const VariableArrayType *Array2 = cast<VariableArrayType>(T2);
394 if (!IsStructurallyEquivalent(Context,
395 Array1->getSizeExpr(), Array2->getSizeExpr()))
396 return false;
397
398 if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
399 return false;
400
401 break;
402 }
403
404 case Type::DependentSizedArray: {
405 const DependentSizedArrayType *Array1 = cast<DependentSizedArrayType>(T1);
406 const DependentSizedArrayType *Array2 = cast<DependentSizedArrayType>(T2);
407 if (!IsStructurallyEquivalent(Context,
408 Array1->getSizeExpr(), Array2->getSizeExpr()))
409 return false;
410
411 if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
412 return false;
413
414 break;
415 }
416
417 case Type::DependentSizedExtVector: {
418 const DependentSizedExtVectorType *Vec1
419 = cast<DependentSizedExtVectorType>(T1);
420 const DependentSizedExtVectorType *Vec2
421 = cast<DependentSizedExtVectorType>(T2);
422 if (!IsStructurallyEquivalent(Context,
423 Vec1->getSizeExpr(), Vec2->getSizeExpr()))
424 return false;
425 if (!IsStructurallyEquivalent(Context,
426 Vec1->getElementType(),
427 Vec2->getElementType()))
428 return false;
429 break;
430 }
431
432 case Type::Vector:
433 case Type::ExtVector: {
434 const VectorType *Vec1 = cast<VectorType>(T1);
435 const VectorType *Vec2 = cast<VectorType>(T2);
436 if (!IsStructurallyEquivalent(Context,
437 Vec1->getElementType(),
438 Vec2->getElementType()))
439 return false;
440 if (Vec1->getNumElements() != Vec2->getNumElements())
441 return false;
442 if (Vec1->isAltiVec() != Vec2->isAltiVec())
443 return false;
444 if (Vec1->isPixel() != Vec2->isPixel())
445 return false;
Douglas Gregor0e12b442010-02-19 01:36:36 +0000446 break;
Douglas Gregor73dc30b2010-02-15 22:01:00 +0000447 }
448
449 case Type::FunctionProto: {
450 const FunctionProtoType *Proto1 = cast<FunctionProtoType>(T1);
451 const FunctionProtoType *Proto2 = cast<FunctionProtoType>(T2);
452 if (Proto1->getNumArgs() != Proto2->getNumArgs())
453 return false;
454 for (unsigned I = 0, N = Proto1->getNumArgs(); I != N; ++I) {
455 if (!IsStructurallyEquivalent(Context,
456 Proto1->getArgType(I),
457 Proto2->getArgType(I)))
458 return false;
459 }
460 if (Proto1->isVariadic() != Proto2->isVariadic())
461 return false;
462 if (Proto1->hasExceptionSpec() != Proto2->hasExceptionSpec())
463 return false;
464 if (Proto1->hasAnyExceptionSpec() != Proto2->hasAnyExceptionSpec())
465 return false;
466 if (Proto1->getNumExceptions() != Proto2->getNumExceptions())
467 return false;
468 for (unsigned I = 0, N = Proto1->getNumExceptions(); I != N; ++I) {
469 if (!IsStructurallyEquivalent(Context,
470 Proto1->getExceptionType(I),
471 Proto2->getExceptionType(I)))
472 return false;
473 }
474 if (Proto1->getTypeQuals() != Proto2->getTypeQuals())
475 return false;
476
477 // Fall through to check the bits common with FunctionNoProtoType.
478 }
479
480 case Type::FunctionNoProto: {
481 const FunctionType *Function1 = cast<FunctionType>(T1);
482 const FunctionType *Function2 = cast<FunctionType>(T2);
483 if (!IsStructurallyEquivalent(Context,
484 Function1->getResultType(),
485 Function2->getResultType()))
486 return false;
Rafael Espindola264ba482010-03-30 20:24:48 +0000487 if (Function1->getExtInfo() != Function2->getExtInfo())
488 return false;
Douglas Gregor73dc30b2010-02-15 22:01:00 +0000489 break;
490 }
491
492 case Type::UnresolvedUsing:
493 if (!IsStructurallyEquivalent(Context,
494 cast<UnresolvedUsingType>(T1)->getDecl(),
495 cast<UnresolvedUsingType>(T2)->getDecl()))
496 return false;
497
498 break;
499
500 case Type::Typedef:
501 if (!IsStructurallyEquivalent(Context,
502 cast<TypedefType>(T1)->getDecl(),
503 cast<TypedefType>(T2)->getDecl()))
504 return false;
505 break;
506
507 case Type::TypeOfExpr:
508 if (!IsStructurallyEquivalent(Context,
509 cast<TypeOfExprType>(T1)->getUnderlyingExpr(),
510 cast<TypeOfExprType>(T2)->getUnderlyingExpr()))
511 return false;
512 break;
513
514 case Type::TypeOf:
515 if (!IsStructurallyEquivalent(Context,
516 cast<TypeOfType>(T1)->getUnderlyingType(),
517 cast<TypeOfType>(T2)->getUnderlyingType()))
518 return false;
519 break;
520
521 case Type::Decltype:
522 if (!IsStructurallyEquivalent(Context,
523 cast<DecltypeType>(T1)->getUnderlyingExpr(),
524 cast<DecltypeType>(T2)->getUnderlyingExpr()))
525 return false;
526 break;
527
528 case Type::Record:
529 case Type::Enum:
530 if (!IsStructurallyEquivalent(Context,
531 cast<TagType>(T1)->getDecl(),
532 cast<TagType>(T2)->getDecl()))
533 return false;
534 break;
535
536 case Type::Elaborated: {
537 const ElaboratedType *Elab1 = cast<ElaboratedType>(T1);
538 const ElaboratedType *Elab2 = cast<ElaboratedType>(T2);
539 if (Elab1->getTagKind() != Elab2->getTagKind())
540 return false;
541 if (!IsStructurallyEquivalent(Context,
542 Elab1->getUnderlyingType(),
543 Elab2->getUnderlyingType()))
544 return false;
545 break;
546 }
547
548 case Type::TemplateTypeParm: {
549 const TemplateTypeParmType *Parm1 = cast<TemplateTypeParmType>(T1);
550 const TemplateTypeParmType *Parm2 = cast<TemplateTypeParmType>(T2);
551 if (Parm1->getDepth() != Parm2->getDepth())
552 return false;
553 if (Parm1->getIndex() != Parm2->getIndex())
554 return false;
555 if (Parm1->isParameterPack() != Parm2->isParameterPack())
556 return false;
557
558 // Names of template type parameters are never significant.
559 break;
560 }
561
562 case Type::SubstTemplateTypeParm: {
563 const SubstTemplateTypeParmType *Subst1
564 = cast<SubstTemplateTypeParmType>(T1);
565 const SubstTemplateTypeParmType *Subst2
566 = cast<SubstTemplateTypeParmType>(T2);
567 if (!IsStructurallyEquivalent(Context,
568 QualType(Subst1->getReplacedParameter(), 0),
569 QualType(Subst2->getReplacedParameter(), 0)))
570 return false;
571 if (!IsStructurallyEquivalent(Context,
572 Subst1->getReplacementType(),
573 Subst2->getReplacementType()))
574 return false;
575 break;
576 }
577
578 case Type::TemplateSpecialization: {
579 const TemplateSpecializationType *Spec1
580 = cast<TemplateSpecializationType>(T1);
581 const TemplateSpecializationType *Spec2
582 = cast<TemplateSpecializationType>(T2);
583 if (!IsStructurallyEquivalent(Context,
584 Spec1->getTemplateName(),
585 Spec2->getTemplateName()))
586 return false;
587 if (Spec1->getNumArgs() != Spec2->getNumArgs())
588 return false;
589 for (unsigned I = 0, N = Spec1->getNumArgs(); I != N; ++I) {
590 if (!IsStructurallyEquivalent(Context,
591 Spec1->getArg(I), Spec2->getArg(I)))
592 return false;
593 }
594 break;
595 }
596
597 case Type::QualifiedName: {
598 const QualifiedNameType *Qual1 = cast<QualifiedNameType>(T1);
599 const QualifiedNameType *Qual2 = cast<QualifiedNameType>(T2);
600 if (!IsStructurallyEquivalent(Context,
601 Qual1->getQualifier(),
602 Qual2->getQualifier()))
603 return false;
604 if (!IsStructurallyEquivalent(Context,
605 Qual1->getNamedType(),
606 Qual2->getNamedType()))
607 return false;
608 break;
609 }
610
John McCall3cb0ebd2010-03-10 03:28:59 +0000611 case Type::InjectedClassName: {
612 const InjectedClassNameType *Inj1 = cast<InjectedClassNameType>(T1);
613 const InjectedClassNameType *Inj2 = cast<InjectedClassNameType>(T2);
614 if (!IsStructurallyEquivalent(Context,
615 Inj1->getUnderlyingType(),
616 Inj2->getUnderlyingType()))
617 return false;
618 break;
619 }
620
Douglas Gregor4714c122010-03-31 17:34:00 +0000621 case Type::DependentName: {
622 const DependentNameType *Typename1 = cast<DependentNameType>(T1);
623 const DependentNameType *Typename2 = cast<DependentNameType>(T2);
Douglas Gregor73dc30b2010-02-15 22:01:00 +0000624 if (!IsStructurallyEquivalent(Context,
625 Typename1->getQualifier(),
626 Typename2->getQualifier()))
627 return false;
628 if (!IsStructurallyEquivalent(Typename1->getIdentifier(),
629 Typename2->getIdentifier()))
630 return false;
631 if (!IsStructurallyEquivalent(Context,
632 QualType(Typename1->getTemplateId(), 0),
633 QualType(Typename2->getTemplateId(), 0)))
634 return false;
635
636 break;
637 }
638
639 case Type::ObjCInterface: {
640 const ObjCInterfaceType *Iface1 = cast<ObjCInterfaceType>(T1);
641 const ObjCInterfaceType *Iface2 = cast<ObjCInterfaceType>(T2);
642 if (!IsStructurallyEquivalent(Context,
643 Iface1->getDecl(), Iface2->getDecl()))
644 return false;
645 if (Iface1->getNumProtocols() != Iface2->getNumProtocols())
646 return false;
647 for (unsigned I = 0, N = Iface1->getNumProtocols(); I != N; ++I) {
648 if (!IsStructurallyEquivalent(Context,
649 Iface1->getProtocol(I),
650 Iface2->getProtocol(I)))
651 return false;
652 }
653 break;
654 }
655
656 case Type::ObjCObjectPointer: {
657 const ObjCObjectPointerType *Ptr1 = cast<ObjCObjectPointerType>(T1);
658 const ObjCObjectPointerType *Ptr2 = cast<ObjCObjectPointerType>(T2);
659 if (!IsStructurallyEquivalent(Context,
660 Ptr1->getPointeeType(),
661 Ptr2->getPointeeType()))
662 return false;
663 if (Ptr1->getNumProtocols() != Ptr2->getNumProtocols())
664 return false;
665 for (unsigned I = 0, N = Ptr1->getNumProtocols(); I != N; ++I) {
666 if (!IsStructurallyEquivalent(Context,
667 Ptr1->getProtocol(I),
668 Ptr2->getProtocol(I)))
669 return false;
670 }
671 break;
672 }
673
674 } // end switch
675
676 return true;
677}
678
679/// \brief Determine structural equivalence of two records.
680static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
681 RecordDecl *D1, RecordDecl *D2) {
682 if (D1->isUnion() != D2->isUnion()) {
683 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
684 << Context.C2.getTypeDeclType(D2);
685 Context.Diag1(D1->getLocation(), diag::note_odr_tag_kind_here)
686 << D1->getDeclName() << (unsigned)D1->getTagKind();
687 return false;
688 }
689
Douglas Gregorea35d112010-02-15 23:54:17 +0000690 // Compare the definitions of these two records. If either or both are
691 // incomplete, we assume that they are equivalent.
692 D1 = D1->getDefinition();
693 D2 = D2->getDefinition();
694 if (!D1 || !D2)
695 return true;
696
Douglas Gregor73dc30b2010-02-15 22:01:00 +0000697 if (CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(D1)) {
698 if (CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(D2)) {
699 if (D1CXX->getNumBases() != D2CXX->getNumBases()) {
700 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
701 << Context.C2.getTypeDeclType(D2);
702 Context.Diag2(D2->getLocation(), diag::note_odr_number_of_bases)
703 << D2CXX->getNumBases();
704 Context.Diag1(D1->getLocation(), diag::note_odr_number_of_bases)
705 << D1CXX->getNumBases();
706 return false;
707 }
708
709 // Check the base classes.
710 for (CXXRecordDecl::base_class_iterator Base1 = D1CXX->bases_begin(),
711 BaseEnd1 = D1CXX->bases_end(),
712 Base2 = D2CXX->bases_begin();
713 Base1 != BaseEnd1;
714 ++Base1, ++Base2) {
715 if (!IsStructurallyEquivalent(Context,
716 Base1->getType(), Base2->getType())) {
717 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
718 << Context.C2.getTypeDeclType(D2);
719 Context.Diag2(Base2->getSourceRange().getBegin(), diag::note_odr_base)
720 << Base2->getType()
721 << Base2->getSourceRange();
722 Context.Diag1(Base1->getSourceRange().getBegin(), diag::note_odr_base)
723 << Base1->getType()
724 << Base1->getSourceRange();
725 return false;
726 }
727
728 // Check virtual vs. non-virtual inheritance mismatch.
729 if (Base1->isVirtual() != Base2->isVirtual()) {
730 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
731 << Context.C2.getTypeDeclType(D2);
732 Context.Diag2(Base2->getSourceRange().getBegin(),
733 diag::note_odr_virtual_base)
734 << Base2->isVirtual() << Base2->getSourceRange();
735 Context.Diag1(Base1->getSourceRange().getBegin(), diag::note_odr_base)
736 << Base1->isVirtual()
737 << Base1->getSourceRange();
738 return false;
739 }
740 }
741 } else if (D1CXX->getNumBases() > 0) {
742 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
743 << Context.C2.getTypeDeclType(D2);
744 const CXXBaseSpecifier *Base1 = D1CXX->bases_begin();
745 Context.Diag1(Base1->getSourceRange().getBegin(), diag::note_odr_base)
746 << Base1->getType()
747 << Base1->getSourceRange();
748 Context.Diag2(D2->getLocation(), diag::note_odr_missing_base);
749 return false;
750 }
751 }
752
753 // Check the fields for consistency.
754 CXXRecordDecl::field_iterator Field2 = D2->field_begin(),
755 Field2End = D2->field_end();
756 for (CXXRecordDecl::field_iterator Field1 = D1->field_begin(),
757 Field1End = D1->field_end();
758 Field1 != Field1End;
759 ++Field1, ++Field2) {
760 if (Field2 == Field2End) {
761 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
762 << Context.C2.getTypeDeclType(D2);
763 Context.Diag1(Field1->getLocation(), diag::note_odr_field)
764 << Field1->getDeclName() << Field1->getType();
765 Context.Diag2(D2->getLocation(), diag::note_odr_missing_field);
766 return false;
767 }
768
769 if (!IsStructurallyEquivalent(Context,
770 Field1->getType(), Field2->getType())) {
771 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
772 << Context.C2.getTypeDeclType(D2);
773 Context.Diag2(Field2->getLocation(), diag::note_odr_field)
774 << Field2->getDeclName() << Field2->getType();
775 Context.Diag1(Field1->getLocation(), diag::note_odr_field)
776 << Field1->getDeclName() << Field1->getType();
777 return false;
778 }
779
780 if (Field1->isBitField() != Field2->isBitField()) {
781 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
782 << Context.C2.getTypeDeclType(D2);
783 if (Field1->isBitField()) {
784 llvm::APSInt Bits;
785 Field1->getBitWidth()->isIntegerConstantExpr(Bits, Context.C1);
786 Context.Diag1(Field1->getLocation(), diag::note_odr_bit_field)
787 << Field1->getDeclName() << Field1->getType()
788 << Bits.toString(10, false);
789 Context.Diag2(Field2->getLocation(), diag::note_odr_not_bit_field)
790 << Field2->getDeclName();
791 } else {
792 llvm::APSInt Bits;
793 Field2->getBitWidth()->isIntegerConstantExpr(Bits, Context.C2);
794 Context.Diag2(Field2->getLocation(), diag::note_odr_bit_field)
795 << Field2->getDeclName() << Field2->getType()
796 << Bits.toString(10, false);
797 Context.Diag1(Field1->getLocation(),
798 diag::note_odr_not_bit_field)
799 << Field1->getDeclName();
800 }
801 return false;
802 }
803
804 if (Field1->isBitField()) {
805 // Make sure that the bit-fields are the same length.
806 llvm::APSInt Bits1, Bits2;
807 if (!Field1->getBitWidth()->isIntegerConstantExpr(Bits1, Context.C1))
808 return false;
809 if (!Field2->getBitWidth()->isIntegerConstantExpr(Bits2, Context.C2))
810 return false;
811
812 if (!IsSameValue(Bits1, Bits2)) {
813 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
814 << Context.C2.getTypeDeclType(D2);
815 Context.Diag2(Field2->getLocation(), diag::note_odr_bit_field)
816 << Field2->getDeclName() << Field2->getType()
817 << Bits2.toString(10, false);
818 Context.Diag1(Field1->getLocation(), diag::note_odr_bit_field)
819 << Field1->getDeclName() << Field1->getType()
820 << Bits1.toString(10, false);
821 return false;
822 }
823 }
824 }
825
826 if (Field2 != Field2End) {
827 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
828 << Context.C2.getTypeDeclType(D2);
829 Context.Diag2(Field2->getLocation(), diag::note_odr_field)
830 << Field2->getDeclName() << Field2->getType();
831 Context.Diag1(D1->getLocation(), diag::note_odr_missing_field);
832 return false;
833 }
834
835 return true;
836}
837
838/// \brief Determine structural equivalence of two enums.
839static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
840 EnumDecl *D1, EnumDecl *D2) {
841 EnumDecl::enumerator_iterator EC2 = D2->enumerator_begin(),
842 EC2End = D2->enumerator_end();
843 for (EnumDecl::enumerator_iterator EC1 = D1->enumerator_begin(),
844 EC1End = D1->enumerator_end();
845 EC1 != EC1End; ++EC1, ++EC2) {
846 if (EC2 == EC2End) {
847 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
848 << Context.C2.getTypeDeclType(D2);
849 Context.Diag1(EC1->getLocation(), diag::note_odr_enumerator)
850 << EC1->getDeclName()
851 << EC1->getInitVal().toString(10);
852 Context.Diag2(D2->getLocation(), diag::note_odr_missing_enumerator);
853 return false;
854 }
855
856 llvm::APSInt Val1 = EC1->getInitVal();
857 llvm::APSInt Val2 = EC2->getInitVal();
858 if (!IsSameValue(Val1, Val2) ||
859 !IsStructurallyEquivalent(EC1->getIdentifier(), EC2->getIdentifier())) {
860 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
861 << Context.C2.getTypeDeclType(D2);
862 Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
863 << EC2->getDeclName()
864 << EC2->getInitVal().toString(10);
865 Context.Diag1(EC1->getLocation(), diag::note_odr_enumerator)
866 << EC1->getDeclName()
867 << EC1->getInitVal().toString(10);
868 return false;
869 }
870 }
871
872 if (EC2 != EC2End) {
873 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
874 << Context.C2.getTypeDeclType(D2);
875 Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
876 << EC2->getDeclName()
877 << EC2->getInitVal().toString(10);
878 Context.Diag1(D1->getLocation(), diag::note_odr_missing_enumerator);
879 return false;
880 }
881
882 return true;
883}
884
885/// \brief Determine structural equivalence of two declarations.
886static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
887 Decl *D1, Decl *D2) {
888 // FIXME: Check for known structural equivalences via a callback of some sort.
889
Douglas Gregorea35d112010-02-15 23:54:17 +0000890 // Check whether we already know that these two declarations are not
891 // structurally equivalent.
892 if (Context.NonEquivalentDecls.count(std::make_pair(D1->getCanonicalDecl(),
893 D2->getCanonicalDecl())))
894 return false;
895
Douglas Gregor73dc30b2010-02-15 22:01:00 +0000896 // Determine whether we've already produced a tentative equivalence for D1.
897 Decl *&EquivToD1 = Context.TentativeEquivalences[D1->getCanonicalDecl()];
898 if (EquivToD1)
899 return EquivToD1 == D2->getCanonicalDecl();
900
901 // Produce a tentative equivalence D1 <-> D2, which will be checked later.
902 EquivToD1 = D2->getCanonicalDecl();
903 Context.DeclsToCheck.push_back(D1->getCanonicalDecl());
904 return true;
905}
906
907bool StructuralEquivalenceContext::IsStructurallyEquivalent(Decl *D1,
908 Decl *D2) {
909 if (!::IsStructurallyEquivalent(*this, D1, D2))
910 return false;
911
912 return !Finish();
913}
914
915bool StructuralEquivalenceContext::IsStructurallyEquivalent(QualType T1,
916 QualType T2) {
917 if (!::IsStructurallyEquivalent(*this, T1, T2))
918 return false;
919
920 return !Finish();
921}
922
923bool StructuralEquivalenceContext::Finish() {
924 while (!DeclsToCheck.empty()) {
925 // Check the next declaration.
926 Decl *D1 = DeclsToCheck.front();
927 DeclsToCheck.pop_front();
928
929 Decl *D2 = TentativeEquivalences[D1];
930 assert(D2 && "Unrecorded tentative equivalence?");
931
Douglas Gregorea35d112010-02-15 23:54:17 +0000932 bool Equivalent = true;
933
Douglas Gregor73dc30b2010-02-15 22:01:00 +0000934 // FIXME: Switch on all declaration kinds. For now, we're just going to
935 // check the obvious ones.
936 if (RecordDecl *Record1 = dyn_cast<RecordDecl>(D1)) {
937 if (RecordDecl *Record2 = dyn_cast<RecordDecl>(D2)) {
938 // Check for equivalent structure names.
939 IdentifierInfo *Name1 = Record1->getIdentifier();
940 if (!Name1 && Record1->getTypedefForAnonDecl())
941 Name1 = Record1->getTypedefForAnonDecl()->getIdentifier();
942 IdentifierInfo *Name2 = Record2->getIdentifier();
943 if (!Name2 && Record2->getTypedefForAnonDecl())
944 Name2 = Record2->getTypedefForAnonDecl()->getIdentifier();
Douglas Gregorea35d112010-02-15 23:54:17 +0000945 if (!::IsStructurallyEquivalent(Name1, Name2) ||
946 !::IsStructurallyEquivalent(*this, Record1, Record2))
947 Equivalent = false;
Douglas Gregor73dc30b2010-02-15 22:01:00 +0000948 } else {
949 // Record/non-record mismatch.
Douglas Gregorea35d112010-02-15 23:54:17 +0000950 Equivalent = false;
Douglas Gregor73dc30b2010-02-15 22:01:00 +0000951 }
Douglas Gregorea35d112010-02-15 23:54:17 +0000952 } else if (EnumDecl *Enum1 = dyn_cast<EnumDecl>(D1)) {
Douglas Gregor73dc30b2010-02-15 22:01:00 +0000953 if (EnumDecl *Enum2 = dyn_cast<EnumDecl>(D2)) {
954 // Check for equivalent enum names.
955 IdentifierInfo *Name1 = Enum1->getIdentifier();
956 if (!Name1 && Enum1->getTypedefForAnonDecl())
957 Name1 = Enum1->getTypedefForAnonDecl()->getIdentifier();
958 IdentifierInfo *Name2 = Enum2->getIdentifier();
959 if (!Name2 && Enum2->getTypedefForAnonDecl())
960 Name2 = Enum2->getTypedefForAnonDecl()->getIdentifier();
Douglas Gregorea35d112010-02-15 23:54:17 +0000961 if (!::IsStructurallyEquivalent(Name1, Name2) ||
962 !::IsStructurallyEquivalent(*this, Enum1, Enum2))
963 Equivalent = false;
Douglas Gregor73dc30b2010-02-15 22:01:00 +0000964 } else {
965 // Enum/non-enum mismatch
Douglas Gregorea35d112010-02-15 23:54:17 +0000966 Equivalent = false;
Douglas Gregor73dc30b2010-02-15 22:01:00 +0000967 }
Douglas Gregorea35d112010-02-15 23:54:17 +0000968 } else if (TypedefDecl *Typedef1 = dyn_cast<TypedefDecl>(D1)) {
Douglas Gregor73dc30b2010-02-15 22:01:00 +0000969 if (TypedefDecl *Typedef2 = dyn_cast<TypedefDecl>(D2)) {
970 if (!::IsStructurallyEquivalent(Typedef1->getIdentifier(),
Douglas Gregorea35d112010-02-15 23:54:17 +0000971 Typedef2->getIdentifier()) ||
972 !::IsStructurallyEquivalent(*this,
Douglas Gregor73dc30b2010-02-15 22:01:00 +0000973 Typedef1->getUnderlyingType(),
974 Typedef2->getUnderlyingType()))
Douglas Gregorea35d112010-02-15 23:54:17 +0000975 Equivalent = false;
Douglas Gregor73dc30b2010-02-15 22:01:00 +0000976 } else {
977 // Typedef/non-typedef mismatch.
Douglas Gregorea35d112010-02-15 23:54:17 +0000978 Equivalent = false;
Douglas Gregor73dc30b2010-02-15 22:01:00 +0000979 }
Douglas Gregor73dc30b2010-02-15 22:01:00 +0000980 }
Douglas Gregorea35d112010-02-15 23:54:17 +0000981
982 if (!Equivalent) {
983 // Note that these two declarations are not equivalent (and we already
984 // know about it).
985 NonEquivalentDecls.insert(std::make_pair(D1->getCanonicalDecl(),
986 D2->getCanonicalDecl()));
987 return true;
988 }
Douglas Gregor73dc30b2010-02-15 22:01:00 +0000989 // FIXME: Check other declaration kinds!
990 }
991
992 return false;
993}
994
995//----------------------------------------------------------------------------
Douglas Gregor1b2949d2010-02-05 17:54:41 +0000996// Import Types
997//----------------------------------------------------------------------------
998
Douglas Gregor89cc9d62010-02-09 22:48:33 +0000999QualType ASTNodeImporter::VisitType(Type *T) {
1000 Importer.FromDiag(SourceLocation(), diag::err_unsupported_ast_node)
1001 << T->getTypeClassName();
1002 return QualType();
1003}
1004
Douglas Gregor1b2949d2010-02-05 17:54:41 +00001005QualType ASTNodeImporter::VisitBuiltinType(BuiltinType *T) {
1006 switch (T->getKind()) {
1007 case BuiltinType::Void: return Importer.getToContext().VoidTy;
1008 case BuiltinType::Bool: return Importer.getToContext().BoolTy;
1009
1010 case BuiltinType::Char_U:
1011 // The context we're importing from has an unsigned 'char'. If we're
1012 // importing into a context with a signed 'char', translate to
1013 // 'unsigned char' instead.
1014 if (Importer.getToContext().getLangOptions().CharIsSigned)
1015 return Importer.getToContext().UnsignedCharTy;
1016
1017 return Importer.getToContext().CharTy;
1018
1019 case BuiltinType::UChar: return Importer.getToContext().UnsignedCharTy;
1020
1021 case BuiltinType::Char16:
1022 // FIXME: Make sure that the "to" context supports C++!
1023 return Importer.getToContext().Char16Ty;
1024
1025 case BuiltinType::Char32:
1026 // FIXME: Make sure that the "to" context supports C++!
1027 return Importer.getToContext().Char32Ty;
1028
1029 case BuiltinType::UShort: return Importer.getToContext().UnsignedShortTy;
1030 case BuiltinType::UInt: return Importer.getToContext().UnsignedIntTy;
1031 case BuiltinType::ULong: return Importer.getToContext().UnsignedLongTy;
1032 case BuiltinType::ULongLong:
1033 return Importer.getToContext().UnsignedLongLongTy;
1034 case BuiltinType::UInt128: return Importer.getToContext().UnsignedInt128Ty;
1035
1036 case BuiltinType::Char_S:
1037 // The context we're importing from has an unsigned 'char'. If we're
1038 // importing into a context with a signed 'char', translate to
1039 // 'unsigned char' instead.
1040 if (!Importer.getToContext().getLangOptions().CharIsSigned)
1041 return Importer.getToContext().SignedCharTy;
1042
1043 return Importer.getToContext().CharTy;
1044
1045 case BuiltinType::SChar: return Importer.getToContext().SignedCharTy;
1046 case BuiltinType::WChar:
1047 // FIXME: If not in C++, shall we translate to the C equivalent of
1048 // wchar_t?
1049 return Importer.getToContext().WCharTy;
1050
1051 case BuiltinType::Short : return Importer.getToContext().ShortTy;
1052 case BuiltinType::Int : return Importer.getToContext().IntTy;
1053 case BuiltinType::Long : return Importer.getToContext().LongTy;
1054 case BuiltinType::LongLong : return Importer.getToContext().LongLongTy;
1055 case BuiltinType::Int128 : return Importer.getToContext().Int128Ty;
1056 case BuiltinType::Float: return Importer.getToContext().FloatTy;
1057 case BuiltinType::Double: return Importer.getToContext().DoubleTy;
1058 case BuiltinType::LongDouble: return Importer.getToContext().LongDoubleTy;
1059
1060 case BuiltinType::NullPtr:
1061 // FIXME: Make sure that the "to" context supports C++0x!
1062 return Importer.getToContext().NullPtrTy;
1063
1064 case BuiltinType::Overload: return Importer.getToContext().OverloadTy;
1065 case BuiltinType::Dependent: return Importer.getToContext().DependentTy;
1066 case BuiltinType::UndeducedAuto:
1067 // FIXME: Make sure that the "to" context supports C++0x!
1068 return Importer.getToContext().UndeducedAutoTy;
1069
1070 case BuiltinType::ObjCId:
1071 // FIXME: Make sure that the "to" context supports Objective-C!
1072 return Importer.getToContext().ObjCBuiltinIdTy;
1073
1074 case BuiltinType::ObjCClass:
1075 return Importer.getToContext().ObjCBuiltinClassTy;
1076
1077 case BuiltinType::ObjCSel:
1078 return Importer.getToContext().ObjCBuiltinSelTy;
1079 }
1080
1081 return QualType();
1082}
1083
1084QualType ASTNodeImporter::VisitComplexType(ComplexType *T) {
1085 QualType ToElementType = Importer.Import(T->getElementType());
1086 if (ToElementType.isNull())
1087 return QualType();
1088
1089 return Importer.getToContext().getComplexType(ToElementType);
1090}
1091
1092QualType ASTNodeImporter::VisitPointerType(PointerType *T) {
1093 QualType ToPointeeType = Importer.Import(T->getPointeeType());
1094 if (ToPointeeType.isNull())
1095 return QualType();
1096
1097 return Importer.getToContext().getPointerType(ToPointeeType);
1098}
1099
1100QualType ASTNodeImporter::VisitBlockPointerType(BlockPointerType *T) {
1101 // FIXME: Check for blocks support in "to" context.
1102 QualType ToPointeeType = Importer.Import(T->getPointeeType());
1103 if (ToPointeeType.isNull())
1104 return QualType();
1105
1106 return Importer.getToContext().getBlockPointerType(ToPointeeType);
1107}
1108
1109QualType ASTNodeImporter::VisitLValueReferenceType(LValueReferenceType *T) {
1110 // FIXME: Check for C++ support in "to" context.
1111 QualType ToPointeeType = Importer.Import(T->getPointeeTypeAsWritten());
1112 if (ToPointeeType.isNull())
1113 return QualType();
1114
1115 return Importer.getToContext().getLValueReferenceType(ToPointeeType);
1116}
1117
1118QualType ASTNodeImporter::VisitRValueReferenceType(RValueReferenceType *T) {
1119 // FIXME: Check for C++0x support in "to" context.
1120 QualType ToPointeeType = Importer.Import(T->getPointeeTypeAsWritten());
1121 if (ToPointeeType.isNull())
1122 return QualType();
1123
1124 return Importer.getToContext().getRValueReferenceType(ToPointeeType);
1125}
1126
1127QualType ASTNodeImporter::VisitMemberPointerType(MemberPointerType *T) {
1128 // FIXME: Check for C++ support in "to" context.
1129 QualType ToPointeeType = Importer.Import(T->getPointeeType());
1130 if (ToPointeeType.isNull())
1131 return QualType();
1132
1133 QualType ClassType = Importer.Import(QualType(T->getClass(), 0));
1134 return Importer.getToContext().getMemberPointerType(ToPointeeType,
1135 ClassType.getTypePtr());
1136}
1137
1138QualType ASTNodeImporter::VisitConstantArrayType(ConstantArrayType *T) {
1139 QualType ToElementType = Importer.Import(T->getElementType());
1140 if (ToElementType.isNull())
1141 return QualType();
1142
1143 return Importer.getToContext().getConstantArrayType(ToElementType,
1144 T->getSize(),
1145 T->getSizeModifier(),
1146 T->getIndexTypeCVRQualifiers());
1147}
1148
1149QualType ASTNodeImporter::VisitIncompleteArrayType(IncompleteArrayType *T) {
1150 QualType ToElementType = Importer.Import(T->getElementType());
1151 if (ToElementType.isNull())
1152 return QualType();
1153
1154 return Importer.getToContext().getIncompleteArrayType(ToElementType,
1155 T->getSizeModifier(),
1156 T->getIndexTypeCVRQualifiers());
1157}
1158
1159QualType ASTNodeImporter::VisitVariableArrayType(VariableArrayType *T) {
1160 QualType ToElementType = Importer.Import(T->getElementType());
1161 if (ToElementType.isNull())
1162 return QualType();
1163
1164 Expr *Size = Importer.Import(T->getSizeExpr());
1165 if (!Size)
1166 return QualType();
1167
1168 SourceRange Brackets = Importer.Import(T->getBracketsRange());
1169 return Importer.getToContext().getVariableArrayType(ToElementType, Size,
1170 T->getSizeModifier(),
1171 T->getIndexTypeCVRQualifiers(),
1172 Brackets);
1173}
1174
1175QualType ASTNodeImporter::VisitVectorType(VectorType *T) {
1176 QualType ToElementType = Importer.Import(T->getElementType());
1177 if (ToElementType.isNull())
1178 return QualType();
1179
1180 return Importer.getToContext().getVectorType(ToElementType,
1181 T->getNumElements(),
1182 T->isAltiVec(),
1183 T->isPixel());
1184}
1185
1186QualType ASTNodeImporter::VisitExtVectorType(ExtVectorType *T) {
1187 QualType ToElementType = Importer.Import(T->getElementType());
1188 if (ToElementType.isNull())
1189 return QualType();
1190
1191 return Importer.getToContext().getExtVectorType(ToElementType,
1192 T->getNumElements());
1193}
1194
1195QualType ASTNodeImporter::VisitFunctionNoProtoType(FunctionNoProtoType *T) {
1196 // FIXME: What happens if we're importing a function without a prototype
1197 // into C++? Should we make it variadic?
1198 QualType ToResultType = Importer.Import(T->getResultType());
1199 if (ToResultType.isNull())
1200 return QualType();
Rafael Espindola264ba482010-03-30 20:24:48 +00001201
Douglas Gregor1b2949d2010-02-05 17:54:41 +00001202 return Importer.getToContext().getFunctionNoProtoType(ToResultType,
Rafael Espindola264ba482010-03-30 20:24:48 +00001203 T->getExtInfo());
Douglas Gregor1b2949d2010-02-05 17:54:41 +00001204}
1205
1206QualType ASTNodeImporter::VisitFunctionProtoType(FunctionProtoType *T) {
1207 QualType ToResultType = Importer.Import(T->getResultType());
1208 if (ToResultType.isNull())
1209 return QualType();
1210
1211 // Import argument types
1212 llvm::SmallVector<QualType, 4> ArgTypes;
1213 for (FunctionProtoType::arg_type_iterator A = T->arg_type_begin(),
1214 AEnd = T->arg_type_end();
1215 A != AEnd; ++A) {
1216 QualType ArgType = Importer.Import(*A);
1217 if (ArgType.isNull())
1218 return QualType();
1219 ArgTypes.push_back(ArgType);
1220 }
1221
1222 // Import exception types
1223 llvm::SmallVector<QualType, 4> ExceptionTypes;
1224 for (FunctionProtoType::exception_iterator E = T->exception_begin(),
1225 EEnd = T->exception_end();
1226 E != EEnd; ++E) {
1227 QualType ExceptionType = Importer.Import(*E);
1228 if (ExceptionType.isNull())
1229 return QualType();
1230 ExceptionTypes.push_back(ExceptionType);
1231 }
1232
1233 return Importer.getToContext().getFunctionType(ToResultType, ArgTypes.data(),
1234 ArgTypes.size(),
1235 T->isVariadic(),
1236 T->getTypeQuals(),
1237 T->hasExceptionSpec(),
1238 T->hasAnyExceptionSpec(),
1239 ExceptionTypes.size(),
1240 ExceptionTypes.data(),
Rafael Espindola264ba482010-03-30 20:24:48 +00001241 T->getExtInfo());
Douglas Gregor1b2949d2010-02-05 17:54:41 +00001242}
1243
1244QualType ASTNodeImporter::VisitTypedefType(TypedefType *T) {
1245 TypedefDecl *ToDecl
1246 = dyn_cast_or_null<TypedefDecl>(Importer.Import(T->getDecl()));
1247 if (!ToDecl)
1248 return QualType();
1249
1250 return Importer.getToContext().getTypeDeclType(ToDecl);
1251}
1252
1253QualType ASTNodeImporter::VisitTypeOfExprType(TypeOfExprType *T) {
1254 Expr *ToExpr = Importer.Import(T->getUnderlyingExpr());
1255 if (!ToExpr)
1256 return QualType();
1257
1258 return Importer.getToContext().getTypeOfExprType(ToExpr);
1259}
1260
1261QualType ASTNodeImporter::VisitTypeOfType(TypeOfType *T) {
1262 QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType());
1263 if (ToUnderlyingType.isNull())
1264 return QualType();
1265
1266 return Importer.getToContext().getTypeOfType(ToUnderlyingType);
1267}
1268
1269QualType ASTNodeImporter::VisitDecltypeType(DecltypeType *T) {
1270 Expr *ToExpr = Importer.Import(T->getUnderlyingExpr());
1271 if (!ToExpr)
1272 return QualType();
1273
1274 return Importer.getToContext().getDecltypeType(ToExpr);
1275}
1276
1277QualType ASTNodeImporter::VisitRecordType(RecordType *T) {
1278 RecordDecl *ToDecl
1279 = dyn_cast_or_null<RecordDecl>(Importer.Import(T->getDecl()));
1280 if (!ToDecl)
1281 return QualType();
1282
1283 return Importer.getToContext().getTagDeclType(ToDecl);
1284}
1285
1286QualType ASTNodeImporter::VisitEnumType(EnumType *T) {
1287 EnumDecl *ToDecl
1288 = dyn_cast_or_null<EnumDecl>(Importer.Import(T->getDecl()));
1289 if (!ToDecl)
1290 return QualType();
1291
1292 return Importer.getToContext().getTagDeclType(ToDecl);
1293}
1294
1295QualType ASTNodeImporter::VisitElaboratedType(ElaboratedType *T) {
1296 QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType());
1297 if (ToUnderlyingType.isNull())
1298 return QualType();
1299
1300 return Importer.getToContext().getElaboratedType(ToUnderlyingType,
1301 T->getTagKind());
1302}
1303
1304QualType ASTNodeImporter::VisitQualifiedNameType(QualifiedNameType *T) {
1305 NestedNameSpecifier *ToQualifier = Importer.Import(T->getQualifier());
1306 if (!ToQualifier)
1307 return QualType();
1308
1309 QualType ToNamedType = Importer.Import(T->getNamedType());
1310 if (ToNamedType.isNull())
1311 return QualType();
1312
1313 return Importer.getToContext().getQualifiedNameType(ToQualifier, ToNamedType);
1314}
1315
1316QualType ASTNodeImporter::VisitObjCInterfaceType(ObjCInterfaceType *T) {
1317 ObjCInterfaceDecl *Class
1318 = dyn_cast_or_null<ObjCInterfaceDecl>(Importer.Import(T->getDecl()));
1319 if (!Class)
1320 return QualType();
1321
1322 llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
1323 for (ObjCInterfaceType::qual_iterator P = T->qual_begin(),
1324 PEnd = T->qual_end();
1325 P != PEnd; ++P) {
1326 ObjCProtocolDecl *Protocol
1327 = dyn_cast_or_null<ObjCProtocolDecl>(Importer.Import(*P));
1328 if (!Protocol)
1329 return QualType();
1330 Protocols.push_back(Protocol);
1331 }
1332
1333 return Importer.getToContext().getObjCInterfaceType(Class,
1334 Protocols.data(),
1335 Protocols.size());
1336}
1337
1338QualType ASTNodeImporter::VisitObjCObjectPointerType(ObjCObjectPointerType *T) {
1339 QualType ToPointeeType = Importer.Import(T->getPointeeType());
1340 if (ToPointeeType.isNull())
1341 return QualType();
1342
1343 llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
1344 for (ObjCObjectPointerType::qual_iterator P = T->qual_begin(),
1345 PEnd = T->qual_end();
1346 P != PEnd; ++P) {
1347 ObjCProtocolDecl *Protocol
1348 = dyn_cast_or_null<ObjCProtocolDecl>(Importer.Import(*P));
1349 if (!Protocol)
1350 return QualType();
1351 Protocols.push_back(Protocol);
1352 }
1353
1354 return Importer.getToContext().getObjCObjectPointerType(ToPointeeType,
1355 Protocols.data(),
1356 Protocols.size());
1357}
1358
Douglas Gregor089459a2010-02-08 21:09:39 +00001359//----------------------------------------------------------------------------
1360// Import Declarations
1361//----------------------------------------------------------------------------
Douglas Gregora404ea62010-02-10 19:54:31 +00001362bool ASTNodeImporter::ImportDeclParts(NamedDecl *D, DeclContext *&DC,
1363 DeclContext *&LexicalDC,
1364 DeclarationName &Name,
1365 SourceLocation &Loc) {
1366 // Import the context of this declaration.
1367 DC = Importer.ImportContext(D->getDeclContext());
1368 if (!DC)
1369 return true;
1370
1371 LexicalDC = DC;
1372 if (D->getDeclContext() != D->getLexicalDeclContext()) {
1373 LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
1374 if (!LexicalDC)
1375 return true;
1376 }
1377
1378 // Import the name of this declaration.
1379 Name = Importer.Import(D->getDeclName());
1380 if (D->getDeclName() && !Name)
1381 return true;
1382
1383 // Import the location of this declaration.
1384 Loc = Importer.Import(D->getLocation());
1385 return false;
1386}
1387
Douglas Gregor083a8212010-02-21 18:24:45 +00001388void ASTNodeImporter::ImportDeclContext(DeclContext *FromDC) {
1389 for (DeclContext::decl_iterator From = FromDC->decls_begin(),
1390 FromEnd = FromDC->decls_end();
1391 From != FromEnd;
1392 ++From)
1393 Importer.Import(*From);
1394}
1395
Douglas Gregor96a01b42010-02-11 00:48:18 +00001396bool ASTNodeImporter::IsStructuralMatch(RecordDecl *FromRecord,
Douglas Gregor73dc30b2010-02-15 22:01:00 +00001397 RecordDecl *ToRecord) {
Benjamin Kramerbb2d1762010-02-18 13:02:13 +00001398 StructuralEquivalenceContext Ctx(Importer.getFromContext(),
Douglas Gregor73dc30b2010-02-15 22:01:00 +00001399 Importer.getToContext(),
Douglas Gregorea35d112010-02-15 23:54:17 +00001400 Importer.getDiags(),
1401 Importer.getNonEquivalentDecls());
Benjamin Kramerbb2d1762010-02-18 13:02:13 +00001402 return Ctx.IsStructurallyEquivalent(FromRecord, ToRecord);
Douglas Gregor96a01b42010-02-11 00:48:18 +00001403}
1404
Douglas Gregor36ead2e2010-02-12 22:17:39 +00001405bool ASTNodeImporter::IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToEnum) {
Benjamin Kramerbb2d1762010-02-18 13:02:13 +00001406 StructuralEquivalenceContext Ctx(Importer.getFromContext(),
Douglas Gregor73dc30b2010-02-15 22:01:00 +00001407 Importer.getToContext(),
Douglas Gregorea35d112010-02-15 23:54:17 +00001408 Importer.getDiags(),
1409 Importer.getNonEquivalentDecls());
Benjamin Kramerbb2d1762010-02-18 13:02:13 +00001410 return Ctx.IsStructurallyEquivalent(FromEnum, ToEnum);
Douglas Gregor36ead2e2010-02-12 22:17:39 +00001411}
1412
Douglas Gregor89cc9d62010-02-09 22:48:33 +00001413Decl *ASTNodeImporter::VisitDecl(Decl *D) {
Douglas Gregor88523732010-02-10 00:15:17 +00001414 Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node)
Douglas Gregor89cc9d62010-02-09 22:48:33 +00001415 << D->getDeclKindName();
1416 return 0;
1417}
1418
Douglas Gregor788c62d2010-02-21 18:26:36 +00001419Decl *ASTNodeImporter::VisitNamespaceDecl(NamespaceDecl *D) {
1420 // Import the major distinguishing characteristics of this namespace.
1421 DeclContext *DC, *LexicalDC;
1422 DeclarationName Name;
1423 SourceLocation Loc;
1424 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
1425 return 0;
1426
1427 NamespaceDecl *MergeWithNamespace = 0;
1428 if (!Name) {
1429 // This is an anonymous namespace. Adopt an existing anonymous
1430 // namespace if we can.
1431 // FIXME: Not testable.
1432 if (TranslationUnitDecl *TU = dyn_cast<TranslationUnitDecl>(DC))
1433 MergeWithNamespace = TU->getAnonymousNamespace();
1434 else
1435 MergeWithNamespace = cast<NamespaceDecl>(DC)->getAnonymousNamespace();
1436 } else {
1437 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
1438 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
1439 Lookup.first != Lookup.second;
1440 ++Lookup.first) {
John McCall0d6b1642010-04-23 18:46:30 +00001441 if (!(*Lookup.first)->isInIdentifierNamespace(Decl::IDNS_Namespace))
Douglas Gregor788c62d2010-02-21 18:26:36 +00001442 continue;
1443
1444 if (NamespaceDecl *FoundNS = dyn_cast<NamespaceDecl>(*Lookup.first)) {
1445 MergeWithNamespace = FoundNS;
1446 ConflictingDecls.clear();
1447 break;
1448 }
1449
1450 ConflictingDecls.push_back(*Lookup.first);
1451 }
1452
1453 if (!ConflictingDecls.empty()) {
John McCall0d6b1642010-04-23 18:46:30 +00001454 Name = Importer.HandleNameConflict(Name, DC, Decl::IDNS_Namespace,
Douglas Gregor788c62d2010-02-21 18:26:36 +00001455 ConflictingDecls.data(),
1456 ConflictingDecls.size());
1457 }
1458 }
1459
1460 // Create the "to" namespace, if needed.
1461 NamespaceDecl *ToNamespace = MergeWithNamespace;
1462 if (!ToNamespace) {
1463 ToNamespace = NamespaceDecl::Create(Importer.getToContext(), DC, Loc,
1464 Name.getAsIdentifierInfo());
1465 ToNamespace->setLexicalDeclContext(LexicalDC);
1466 LexicalDC->addDecl(ToNamespace);
1467
1468 // If this is an anonymous namespace, register it as the anonymous
1469 // namespace within its context.
1470 if (!Name) {
1471 if (TranslationUnitDecl *TU = dyn_cast<TranslationUnitDecl>(DC))
1472 TU->setAnonymousNamespace(ToNamespace);
1473 else
1474 cast<NamespaceDecl>(DC)->setAnonymousNamespace(ToNamespace);
1475 }
1476 }
1477 Importer.Imported(D, ToNamespace);
1478
1479 ImportDeclContext(D);
1480
1481 return ToNamespace;
1482}
1483
Douglas Gregor9e5d9962010-02-10 21:10:29 +00001484Decl *ASTNodeImporter::VisitTypedefDecl(TypedefDecl *D) {
1485 // Import the major distinguishing characteristics of this typedef.
1486 DeclContext *DC, *LexicalDC;
1487 DeclarationName Name;
1488 SourceLocation Loc;
1489 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
1490 return 0;
1491
Douglas Gregor9e5d9962010-02-10 21:10:29 +00001492 // If this typedef is not in block scope, determine whether we've
1493 // seen a typedef with the same name (that we can merge with) or any
1494 // other entity by that name (which name lookup could conflict with).
1495 if (!DC->isFunctionOrMethod()) {
1496 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
1497 unsigned IDNS = Decl::IDNS_Ordinary;
1498 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
1499 Lookup.first != Lookup.second;
1500 ++Lookup.first) {
1501 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
1502 continue;
1503 if (TypedefDecl *FoundTypedef = dyn_cast<TypedefDecl>(*Lookup.first)) {
Douglas Gregorea35d112010-02-15 23:54:17 +00001504 if (Importer.IsStructurallyEquivalent(D->getUnderlyingType(),
1505 FoundTypedef->getUnderlyingType()))
Douglas Gregor5ce5dab2010-02-12 23:44:20 +00001506 return Importer.Imported(D, FoundTypedef);
Douglas Gregor9e5d9962010-02-10 21:10:29 +00001507 }
1508
1509 ConflictingDecls.push_back(*Lookup.first);
1510 }
1511
1512 if (!ConflictingDecls.empty()) {
1513 Name = Importer.HandleNameConflict(Name, DC, IDNS,
1514 ConflictingDecls.data(),
1515 ConflictingDecls.size());
1516 if (!Name)
1517 return 0;
1518 }
1519 }
1520
Douglas Gregorea35d112010-02-15 23:54:17 +00001521 // Import the underlying type of this typedef;
1522 QualType T = Importer.Import(D->getUnderlyingType());
1523 if (T.isNull())
1524 return 0;
1525
Douglas Gregor9e5d9962010-02-10 21:10:29 +00001526 // Create the new typedef node.
1527 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
1528 TypedefDecl *ToTypedef = TypedefDecl::Create(Importer.getToContext(), DC,
1529 Loc, Name.getAsIdentifierInfo(),
1530 TInfo);
Douglas Gregor325bf172010-02-22 17:42:47 +00001531 ToTypedef->setAccess(D->getAccess());
Douglas Gregor9e5d9962010-02-10 21:10:29 +00001532 ToTypedef->setLexicalDeclContext(LexicalDC);
Douglas Gregor5ce5dab2010-02-12 23:44:20 +00001533 Importer.Imported(D, ToTypedef);
Douglas Gregor9e5d9962010-02-10 21:10:29 +00001534 LexicalDC->addDecl(ToTypedef);
Douglas Gregorea35d112010-02-15 23:54:17 +00001535
Douglas Gregor9e5d9962010-02-10 21:10:29 +00001536 return ToTypedef;
1537}
1538
Douglas Gregor36ead2e2010-02-12 22:17:39 +00001539Decl *ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
1540 // Import the major distinguishing characteristics of this enum.
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 enum 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 an enum of the same name; try to find and match it.
1557 if (!DC->isFunctionOrMethod() && SearchName) {
1558 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
1559 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
1560 Lookup.first != Lookup.second;
1561 ++Lookup.first) {
1562 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
1563 continue;
1564
1565 Decl *Found = *Lookup.first;
1566 if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(Found)) {
1567 if (const TagType *Tag = Typedef->getUnderlyingType()->getAs<TagType>())
1568 Found = Tag->getDecl();
1569 }
1570
1571 if (EnumDecl *FoundEnum = dyn_cast<EnumDecl>(Found)) {
Douglas Gregor5ce5dab2010-02-12 23:44:20 +00001572 if (IsStructuralMatch(D, FoundEnum))
1573 return Importer.Imported(D, FoundEnum);
Douglas Gregor36ead2e2010-02-12 22:17:39 +00001574 }
1575
1576 ConflictingDecls.push_back(*Lookup.first);
1577 }
1578
1579 if (!ConflictingDecls.empty()) {
1580 Name = Importer.HandleNameConflict(Name, DC, IDNS,
1581 ConflictingDecls.data(),
1582 ConflictingDecls.size());
1583 }
1584 }
1585
1586 // Create the enum declaration.
Douglas Gregor73dc30b2010-02-15 22:01:00 +00001587 EnumDecl *D2 = EnumDecl::Create(Importer.getToContext(), DC, Loc,
Douglas Gregor36ead2e2010-02-12 22:17:39 +00001588 Name.getAsIdentifierInfo(),
1589 Importer.Import(D->getTagKeywordLoc()),
1590 0);
John McCallb6217662010-03-15 10:12:16 +00001591 // Import the qualifier, if any.
1592 if (D->getQualifier()) {
1593 NestedNameSpecifier *NNS = Importer.Import(D->getQualifier());
1594 SourceRange NNSRange = Importer.Import(D->getQualifierRange());
1595 D2->setQualifierInfo(NNS, NNSRange);
1596 }
Douglas Gregor325bf172010-02-22 17:42:47 +00001597 D2->setAccess(D->getAccess());
Douglas Gregor73dc30b2010-02-15 22:01:00 +00001598 D2->setLexicalDeclContext(LexicalDC);
1599 Importer.Imported(D, D2);
1600 LexicalDC->addDecl(D2);
Douglas Gregor36ead2e2010-02-12 22:17:39 +00001601
1602 // Import the integer type.
1603 QualType ToIntegerType = Importer.Import(D->getIntegerType());
1604 if (ToIntegerType.isNull())
1605 return 0;
Douglas Gregor73dc30b2010-02-15 22:01:00 +00001606 D2->setIntegerType(ToIntegerType);
Douglas Gregor36ead2e2010-02-12 22:17:39 +00001607
1608 // Import the definition
1609 if (D->isDefinition()) {
1610 QualType T = Importer.Import(Importer.getFromContext().getTypeDeclType(D));
1611 if (T.isNull())
1612 return 0;
1613
1614 QualType ToPromotionType = Importer.Import(D->getPromotionType());
1615 if (ToPromotionType.isNull())
1616 return 0;
1617
Douglas Gregor73dc30b2010-02-15 22:01:00 +00001618 D2->startDefinition();
Douglas Gregor083a8212010-02-21 18:24:45 +00001619 ImportDeclContext(D);
Douglas Gregor73dc30b2010-02-15 22:01:00 +00001620 D2->completeDefinition(T, ToPromotionType);
Douglas Gregor36ead2e2010-02-12 22:17:39 +00001621 }
1622
Douglas Gregor73dc30b2010-02-15 22:01:00 +00001623 return D2;
Douglas Gregor36ead2e2010-02-12 22:17:39 +00001624}
1625
Douglas Gregor96a01b42010-02-11 00:48:18 +00001626Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
1627 // If this record has a definition in the translation unit we're coming from,
1628 // but this particular declaration is not that definition, import the
1629 // definition and map to that.
Douglas Gregor952b0172010-02-11 01:04:33 +00001630 TagDecl *Definition = D->getDefinition();
Douglas Gregor96a01b42010-02-11 00:48:18 +00001631 if (Definition && Definition != D) {
1632 Decl *ImportedDef = Importer.Import(Definition);
Douglas Gregor5ce5dab2010-02-12 23:44:20 +00001633 if (!ImportedDef)
1634 return 0;
1635
1636 return Importer.Imported(D, ImportedDef);
Douglas Gregor96a01b42010-02-11 00:48:18 +00001637 }
1638
1639 // Import the major distinguishing characteristics of this record.
1640 DeclContext *DC, *LexicalDC;
1641 DeclarationName Name;
1642 SourceLocation Loc;
1643 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
1644 return 0;
1645
1646 // Figure out what structure name we're looking for.
1647 unsigned IDNS = Decl::IDNS_Tag;
1648 DeclarationName SearchName = Name;
1649 if (!SearchName && D->getTypedefForAnonDecl()) {
1650 SearchName = Importer.Import(D->getTypedefForAnonDecl()->getDeclName());
1651 IDNS = Decl::IDNS_Ordinary;
1652 } else if (Importer.getToContext().getLangOptions().CPlusPlus)
1653 IDNS |= Decl::IDNS_Ordinary;
1654
1655 // We may already have a record of the same name; try to find and match it.
Douglas Gregore72b5dc2010-02-12 00:09:27 +00001656 RecordDecl *AdoptDecl = 0;
Douglas Gregor96a01b42010-02-11 00:48:18 +00001657 if (!DC->isFunctionOrMethod() && SearchName) {
1658 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
1659 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
1660 Lookup.first != Lookup.second;
1661 ++Lookup.first) {
1662 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
1663 continue;
1664
1665 Decl *Found = *Lookup.first;
1666 if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(Found)) {
1667 if (const TagType *Tag = Typedef->getUnderlyingType()->getAs<TagType>())
1668 Found = Tag->getDecl();
1669 }
1670
1671 if (RecordDecl *FoundRecord = dyn_cast<RecordDecl>(Found)) {
Douglas Gregore72b5dc2010-02-12 00:09:27 +00001672 if (RecordDecl *FoundDef = FoundRecord->getDefinition()) {
1673 if (!D->isDefinition() || IsStructuralMatch(D, FoundDef)) {
1674 // The record types structurally match, or the "from" translation
1675 // unit only had a forward declaration anyway; call it the same
1676 // function.
1677 // FIXME: For C++, we should also merge methods here.
Douglas Gregor5ce5dab2010-02-12 23:44:20 +00001678 return Importer.Imported(D, FoundDef);
Douglas Gregore72b5dc2010-02-12 00:09:27 +00001679 }
1680 } else {
1681 // We have a forward declaration of this type, so adopt that forward
1682 // declaration rather than building a new one.
1683 AdoptDecl = FoundRecord;
1684 continue;
1685 }
Douglas Gregor96a01b42010-02-11 00:48:18 +00001686 }
1687
1688 ConflictingDecls.push_back(*Lookup.first);
1689 }
1690
1691 if (!ConflictingDecls.empty()) {
1692 Name = Importer.HandleNameConflict(Name, DC, IDNS,
1693 ConflictingDecls.data(),
1694 ConflictingDecls.size());
1695 }
1696 }
1697
1698 // Create the record declaration.
Douglas Gregor73dc30b2010-02-15 22:01:00 +00001699 RecordDecl *D2 = AdoptDecl;
1700 if (!D2) {
1701 if (CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(D)) {
1702 CXXRecordDecl *D2CXX = CXXRecordDecl::Create(Importer.getToContext(),
Douglas Gregore72b5dc2010-02-12 00:09:27 +00001703 D->getTagKind(),
1704 DC, Loc,
1705 Name.getAsIdentifierInfo(),
Douglas Gregor96a01b42010-02-11 00:48:18 +00001706 Importer.Import(D->getTagKeywordLoc()));
Douglas Gregor73dc30b2010-02-15 22:01:00 +00001707 D2 = D2CXX;
Douglas Gregor325bf172010-02-22 17:42:47 +00001708 D2->setAccess(D->getAccess());
Douglas Gregore72b5dc2010-02-12 00:09:27 +00001709
1710 if (D->isDefinition()) {
1711 // Add base classes.
1712 llvm::SmallVector<CXXBaseSpecifier *, 4> Bases;
1713 for (CXXRecordDecl::base_class_iterator
Douglas Gregor73dc30b2010-02-15 22:01:00 +00001714 Base1 = D1CXX->bases_begin(),
1715 FromBaseEnd = D1CXX->bases_end();
1716 Base1 != FromBaseEnd;
1717 ++Base1) {
1718 QualType T = Importer.Import(Base1->getType());
Douglas Gregore72b5dc2010-02-12 00:09:27 +00001719 if (T.isNull())
1720 return 0;
1721
1722 Bases.push_back(
1723 new (Importer.getToContext())
Douglas Gregor73dc30b2010-02-15 22:01:00 +00001724 CXXBaseSpecifier(Importer.Import(Base1->getSourceRange()),
1725 Base1->isVirtual(),
1726 Base1->isBaseOfClass(),
1727 Base1->getAccessSpecifierAsWritten(),
Douglas Gregor96a01b42010-02-11 00:48:18 +00001728 T));
Douglas Gregore72b5dc2010-02-12 00:09:27 +00001729 }
1730 if (!Bases.empty())
Douglas Gregor73dc30b2010-02-15 22:01:00 +00001731 D2CXX->setBases(Bases.data(), Bases.size());
Douglas Gregor96a01b42010-02-11 00:48:18 +00001732 }
Douglas Gregore72b5dc2010-02-12 00:09:27 +00001733 } else {
Douglas Gregor73dc30b2010-02-15 22:01:00 +00001734 D2 = RecordDecl::Create(Importer.getToContext(), D->getTagKind(),
Douglas Gregore72b5dc2010-02-12 00:09:27 +00001735 DC, Loc,
1736 Name.getAsIdentifierInfo(),
1737 Importer.Import(D->getTagKeywordLoc()));
Douglas Gregor96a01b42010-02-11 00:48:18 +00001738 }
John McCallb6217662010-03-15 10:12:16 +00001739 // Import the qualifier, if any.
1740 if (D->getQualifier()) {
1741 NestedNameSpecifier *NNS = Importer.Import(D->getQualifier());
1742 SourceRange NNSRange = Importer.Import(D->getQualifierRange());
1743 D2->setQualifierInfo(NNS, NNSRange);
1744 }
Douglas Gregor73dc30b2010-02-15 22:01:00 +00001745 D2->setLexicalDeclContext(LexicalDC);
1746 LexicalDC->addDecl(D2);
Douglas Gregor96a01b42010-02-11 00:48:18 +00001747 }
Douglas Gregor5ce5dab2010-02-12 23:44:20 +00001748
Douglas Gregor73dc30b2010-02-15 22:01:00 +00001749 Importer.Imported(D, D2);
Douglas Gregore72b5dc2010-02-12 00:09:27 +00001750
Douglas Gregor96a01b42010-02-11 00:48:18 +00001751 if (D->isDefinition()) {
Douglas Gregor73dc30b2010-02-15 22:01:00 +00001752 D2->startDefinition();
Douglas Gregor083a8212010-02-21 18:24:45 +00001753 ImportDeclContext(D);
Douglas Gregor73dc30b2010-02-15 22:01:00 +00001754 D2->completeDefinition();
Douglas Gregor96a01b42010-02-11 00:48:18 +00001755 }
1756
Douglas Gregor73dc30b2010-02-15 22:01:00 +00001757 return D2;
Douglas Gregor96a01b42010-02-11 00:48:18 +00001758}
1759
Douglas Gregor36ead2e2010-02-12 22:17:39 +00001760Decl *ASTNodeImporter::VisitEnumConstantDecl(EnumConstantDecl *D) {
1761 // Import the major distinguishing characteristics of this enumerator.
1762 DeclContext *DC, *LexicalDC;
1763 DeclarationName Name;
1764 SourceLocation Loc;
Douglas Gregorea35d112010-02-15 23:54:17 +00001765 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
Douglas Gregor36ead2e2010-02-12 22:17:39 +00001766 return 0;
Douglas Gregorea35d112010-02-15 23:54:17 +00001767
1768 QualType T = Importer.Import(D->getType());
1769 if (T.isNull())
1770 return 0;
1771
Douglas Gregor36ead2e2010-02-12 22:17:39 +00001772 // Determine whether there are any other declarations with the same name and
1773 // in the same context.
1774 if (!LexicalDC->isFunctionOrMethod()) {
1775 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
1776 unsigned IDNS = Decl::IDNS_Ordinary;
1777 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
1778 Lookup.first != Lookup.second;
1779 ++Lookup.first) {
1780 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
1781 continue;
1782
1783 ConflictingDecls.push_back(*Lookup.first);
1784 }
1785
1786 if (!ConflictingDecls.empty()) {
1787 Name = Importer.HandleNameConflict(Name, DC, IDNS,
1788 ConflictingDecls.data(),
1789 ConflictingDecls.size());
1790 if (!Name)
1791 return 0;
1792 }
1793 }
1794
1795 Expr *Init = Importer.Import(D->getInitExpr());
1796 if (D->getInitExpr() && !Init)
1797 return 0;
1798
1799 EnumConstantDecl *ToEnumerator
1800 = EnumConstantDecl::Create(Importer.getToContext(), cast<EnumDecl>(DC), Loc,
1801 Name.getAsIdentifierInfo(), T,
1802 Init, D->getInitVal());
Douglas Gregor325bf172010-02-22 17:42:47 +00001803 ToEnumerator->setAccess(D->getAccess());
Douglas Gregor36ead2e2010-02-12 22:17:39 +00001804 ToEnumerator->setLexicalDeclContext(LexicalDC);
Douglas Gregor5ce5dab2010-02-12 23:44:20 +00001805 Importer.Imported(D, ToEnumerator);
Douglas Gregor36ead2e2010-02-12 22:17:39 +00001806 LexicalDC->addDecl(ToEnumerator);
1807 return ToEnumerator;
1808}
Douglas Gregor96a01b42010-02-11 00:48:18 +00001809
Douglas Gregora404ea62010-02-10 19:54:31 +00001810Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
1811 // Import the major distinguishing characteristics of this function.
1812 DeclContext *DC, *LexicalDC;
1813 DeclarationName Name;
Douglas Gregora404ea62010-02-10 19:54:31 +00001814 SourceLocation Loc;
Douglas Gregorea35d112010-02-15 23:54:17 +00001815 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
Douglas Gregor089459a2010-02-08 21:09:39 +00001816 return 0;
Douglas Gregora404ea62010-02-10 19:54:31 +00001817
1818 // Try to find a function in our own ("to") context with the same name, same
1819 // type, and in the same context as the function we're importing.
1820 if (!LexicalDC->isFunctionOrMethod()) {
1821 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
1822 unsigned IDNS = Decl::IDNS_Ordinary;
1823 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
1824 Lookup.first != Lookup.second;
1825 ++Lookup.first) {
1826 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
1827 continue;
Douglas Gregor089459a2010-02-08 21:09:39 +00001828
Douglas Gregora404ea62010-02-10 19:54:31 +00001829 if (FunctionDecl *FoundFunction = dyn_cast<FunctionDecl>(*Lookup.first)) {
1830 if (isExternalLinkage(FoundFunction->getLinkage()) &&
1831 isExternalLinkage(D->getLinkage())) {
Douglas Gregorea35d112010-02-15 23:54:17 +00001832 if (Importer.IsStructurallyEquivalent(D->getType(),
1833 FoundFunction->getType())) {
Douglas Gregora404ea62010-02-10 19:54:31 +00001834 // FIXME: Actually try to merge the body and other attributes.
Douglas Gregor5ce5dab2010-02-12 23:44:20 +00001835 return Importer.Imported(D, FoundFunction);
Douglas Gregora404ea62010-02-10 19:54:31 +00001836 }
1837
1838 // FIXME: Check for overloading more carefully, e.g., by boosting
1839 // Sema::IsOverload out to the AST library.
1840
1841 // Function overloading is okay in C++.
1842 if (Importer.getToContext().getLangOptions().CPlusPlus)
1843 continue;
1844
1845 // Complain about inconsistent function types.
1846 Importer.ToDiag(Loc, diag::err_odr_function_type_inconsistent)
Douglas Gregorea35d112010-02-15 23:54:17 +00001847 << Name << D->getType() << FoundFunction->getType();
Douglas Gregora404ea62010-02-10 19:54:31 +00001848 Importer.ToDiag(FoundFunction->getLocation(),
1849 diag::note_odr_value_here)
1850 << FoundFunction->getType();
1851 }
1852 }
1853
1854 ConflictingDecls.push_back(*Lookup.first);
1855 }
1856
1857 if (!ConflictingDecls.empty()) {
1858 Name = Importer.HandleNameConflict(Name, DC, IDNS,
1859 ConflictingDecls.data(),
1860 ConflictingDecls.size());
1861 if (!Name)
1862 return 0;
1863 }
Douglas Gregor9bed8792010-02-09 19:21:46 +00001864 }
Douglas Gregorea35d112010-02-15 23:54:17 +00001865
1866 // Import the type.
1867 QualType T = Importer.Import(D->getType());
1868 if (T.isNull())
1869 return 0;
Douglas Gregora404ea62010-02-10 19:54:31 +00001870
1871 // Import the function parameters.
1872 llvm::SmallVector<ParmVarDecl *, 8> Parameters;
1873 for (FunctionDecl::param_iterator P = D->param_begin(), PEnd = D->param_end();
1874 P != PEnd; ++P) {
1875 ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(*P));
1876 if (!ToP)
1877 return 0;
1878
1879 Parameters.push_back(ToP);
1880 }
1881
1882 // Create the imported function.
1883 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
Douglas Gregorc144f352010-02-21 18:29:16 +00001884 FunctionDecl *ToFunction = 0;
1885 if (CXXConstructorDecl *FromConstructor = dyn_cast<CXXConstructorDecl>(D)) {
1886 ToFunction = CXXConstructorDecl::Create(Importer.getToContext(),
1887 cast<CXXRecordDecl>(DC),
1888 Loc, Name, T, TInfo,
1889 FromConstructor->isExplicit(),
1890 D->isInlineSpecified(),
1891 D->isImplicit());
1892 } else if (isa<CXXDestructorDecl>(D)) {
1893 ToFunction = CXXDestructorDecl::Create(Importer.getToContext(),
1894 cast<CXXRecordDecl>(DC),
1895 Loc, Name, T,
1896 D->isInlineSpecified(),
1897 D->isImplicit());
1898 } else if (CXXConversionDecl *FromConversion
1899 = dyn_cast<CXXConversionDecl>(D)) {
1900 ToFunction = CXXConversionDecl::Create(Importer.getToContext(),
1901 cast<CXXRecordDecl>(DC),
1902 Loc, Name, T, TInfo,
1903 D->isInlineSpecified(),
1904 FromConversion->isExplicit());
1905 } else {
1906 ToFunction = FunctionDecl::Create(Importer.getToContext(), DC, Loc,
1907 Name, T, TInfo, D->getStorageClass(),
Douglas Gregor16573fa2010-04-19 22:54:31 +00001908 D->getStorageClassAsWritten(),
Douglas Gregorc144f352010-02-21 18:29:16 +00001909 D->isInlineSpecified(),
1910 D->hasWrittenPrototype());
1911 }
John McCallb6217662010-03-15 10:12:16 +00001912
1913 // Import the qualifier, if any.
1914 if (D->getQualifier()) {
1915 NestedNameSpecifier *NNS = Importer.Import(D->getQualifier());
1916 SourceRange NNSRange = Importer.Import(D->getQualifierRange());
1917 ToFunction->setQualifierInfo(NNS, NNSRange);
1918 }
Douglas Gregor325bf172010-02-22 17:42:47 +00001919 ToFunction->setAccess(D->getAccess());
Douglas Gregorc3f2d2b2010-02-17 02:12:47 +00001920 ToFunction->setLexicalDeclContext(LexicalDC);
1921 Importer.Imported(D, ToFunction);
1922 LexicalDC->addDecl(ToFunction);
Douglas Gregor9bed8792010-02-09 19:21:46 +00001923
Douglas Gregora404ea62010-02-10 19:54:31 +00001924 // Set the parameters.
1925 for (unsigned I = 0, N = Parameters.size(); I != N; ++I) {
Douglas Gregorc3f2d2b2010-02-17 02:12:47 +00001926 Parameters[I]->setOwningFunction(ToFunction);
1927 ToFunction->addDecl(Parameters[I]);
Douglas Gregora404ea62010-02-10 19:54:31 +00001928 }
Douglas Gregorc3f2d2b2010-02-17 02:12:47 +00001929 ToFunction->setParams(Parameters.data(), Parameters.size());
Douglas Gregora404ea62010-02-10 19:54:31 +00001930
1931 // FIXME: Other bits to merge?
Douglas Gregor089459a2010-02-08 21:09:39 +00001932
Douglas Gregorc3f2d2b2010-02-17 02:12:47 +00001933 return ToFunction;
Douglas Gregora404ea62010-02-10 19:54:31 +00001934}
1935
Douglas Gregorc144f352010-02-21 18:29:16 +00001936Decl *ASTNodeImporter::VisitCXXMethodDecl(CXXMethodDecl *D) {
1937 return VisitFunctionDecl(D);
1938}
1939
1940Decl *ASTNodeImporter::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
1941 return VisitCXXMethodDecl(D);
1942}
1943
1944Decl *ASTNodeImporter::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
1945 return VisitCXXMethodDecl(D);
1946}
1947
1948Decl *ASTNodeImporter::VisitCXXConversionDecl(CXXConversionDecl *D) {
1949 return VisitCXXMethodDecl(D);
1950}
1951
Douglas Gregor96a01b42010-02-11 00:48:18 +00001952Decl *ASTNodeImporter::VisitFieldDecl(FieldDecl *D) {
1953 // Import the major distinguishing characteristics of a variable.
1954 DeclContext *DC, *LexicalDC;
1955 DeclarationName Name;
Douglas Gregor96a01b42010-02-11 00:48:18 +00001956 SourceLocation Loc;
Douglas Gregorea35d112010-02-15 23:54:17 +00001957 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
1958 return 0;
1959
1960 // Import the type.
1961 QualType T = Importer.Import(D->getType());
1962 if (T.isNull())
Douglas Gregor96a01b42010-02-11 00:48:18 +00001963 return 0;
1964
1965 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
1966 Expr *BitWidth = Importer.Import(D->getBitWidth());
1967 if (!BitWidth && D->getBitWidth())
1968 return 0;
1969
1970 FieldDecl *ToField = FieldDecl::Create(Importer.getToContext(), DC,
1971 Loc, Name.getAsIdentifierInfo(),
1972 T, TInfo, BitWidth, D->isMutable());
Douglas Gregor325bf172010-02-22 17:42:47 +00001973 ToField->setAccess(D->getAccess());
Douglas Gregor96a01b42010-02-11 00:48:18 +00001974 ToField->setLexicalDeclContext(LexicalDC);
Douglas Gregor5ce5dab2010-02-12 23:44:20 +00001975 Importer.Imported(D, ToField);
Douglas Gregor96a01b42010-02-11 00:48:18 +00001976 LexicalDC->addDecl(ToField);
1977 return ToField;
1978}
1979
Douglas Gregor2e55e3a2010-02-17 00:34:30 +00001980Decl *ASTNodeImporter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
1981 // Import the major distinguishing characteristics of an ivar.
1982 DeclContext *DC, *LexicalDC;
1983 DeclarationName Name;
1984 SourceLocation Loc;
1985 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
1986 return 0;
1987
1988 // Determine whether we've already imported this ivar
1989 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
1990 Lookup.first != Lookup.second;
1991 ++Lookup.first) {
1992 if (ObjCIvarDecl *FoundIvar = dyn_cast<ObjCIvarDecl>(*Lookup.first)) {
1993 if (Importer.IsStructurallyEquivalent(D->getType(),
1994 FoundIvar->getType())) {
1995 Importer.Imported(D, FoundIvar);
1996 return FoundIvar;
1997 }
1998
1999 Importer.ToDiag(Loc, diag::err_odr_ivar_type_inconsistent)
2000 << Name << D->getType() << FoundIvar->getType();
2001 Importer.ToDiag(FoundIvar->getLocation(), diag::note_odr_value_here)
2002 << FoundIvar->getType();
2003 return 0;
2004 }
2005 }
2006
2007 // Import the type.
2008 QualType T = Importer.Import(D->getType());
2009 if (T.isNull())
2010 return 0;
2011
2012 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
2013 Expr *BitWidth = Importer.Import(D->getBitWidth());
2014 if (!BitWidth && D->getBitWidth())
2015 return 0;
2016
Daniel Dunbara0654922010-04-02 20:10:03 +00002017 ObjCIvarDecl *ToIvar = ObjCIvarDecl::Create(Importer.getToContext(),
2018 cast<ObjCContainerDecl>(DC),
Douglas Gregor2e55e3a2010-02-17 00:34:30 +00002019 Loc, Name.getAsIdentifierInfo(),
2020 T, TInfo, D->getAccessControl(),
2021 BitWidth);
2022 ToIvar->setLexicalDeclContext(LexicalDC);
2023 Importer.Imported(D, ToIvar);
2024 LexicalDC->addDecl(ToIvar);
2025 return ToIvar;
2026
2027}
2028
Douglas Gregora404ea62010-02-10 19:54:31 +00002029Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
2030 // Import the major distinguishing characteristics of a variable.
2031 DeclContext *DC, *LexicalDC;
2032 DeclarationName Name;
Douglas Gregora404ea62010-02-10 19:54:31 +00002033 SourceLocation Loc;
Douglas Gregorea35d112010-02-15 23:54:17 +00002034 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
Douglas Gregor089459a2010-02-08 21:09:39 +00002035 return 0;
2036
Douglas Gregor089459a2010-02-08 21:09:39 +00002037 // Try to find a variable in our own ("to") context with the same name and
2038 // in the same context as the variable we're importing.
Douglas Gregor9bed8792010-02-09 19:21:46 +00002039 if (D->isFileVarDecl()) {
Douglas Gregor089459a2010-02-08 21:09:39 +00002040 VarDecl *MergeWithVar = 0;
2041 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
2042 unsigned IDNS = Decl::IDNS_Ordinary;
Douglas Gregor9bed8792010-02-09 19:21:46 +00002043 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
Douglas Gregor089459a2010-02-08 21:09:39 +00002044 Lookup.first != Lookup.second;
2045 ++Lookup.first) {
2046 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
2047 continue;
2048
2049 if (VarDecl *FoundVar = dyn_cast<VarDecl>(*Lookup.first)) {
2050 // We have found a variable that we may need to merge with. Check it.
2051 if (isExternalLinkage(FoundVar->getLinkage()) &&
2052 isExternalLinkage(D->getLinkage())) {
Douglas Gregorea35d112010-02-15 23:54:17 +00002053 if (Importer.IsStructurallyEquivalent(D->getType(),
2054 FoundVar->getType())) {
Douglas Gregor089459a2010-02-08 21:09:39 +00002055 MergeWithVar = FoundVar;
2056 break;
2057 }
2058
Douglas Gregord0145422010-02-12 17:23:39 +00002059 const ArrayType *FoundArray
2060 = Importer.getToContext().getAsArrayType(FoundVar->getType());
2061 const ArrayType *TArray
Douglas Gregorea35d112010-02-15 23:54:17 +00002062 = Importer.getToContext().getAsArrayType(D->getType());
Douglas Gregord0145422010-02-12 17:23:39 +00002063 if (FoundArray && TArray) {
2064 if (isa<IncompleteArrayType>(FoundArray) &&
2065 isa<ConstantArrayType>(TArray)) {
Douglas Gregorea35d112010-02-15 23:54:17 +00002066 // Import the type.
2067 QualType T = Importer.Import(D->getType());
2068 if (T.isNull())
2069 return 0;
2070
Douglas Gregord0145422010-02-12 17:23:39 +00002071 FoundVar->setType(T);
2072 MergeWithVar = FoundVar;
2073 break;
2074 } else if (isa<IncompleteArrayType>(TArray) &&
2075 isa<ConstantArrayType>(FoundArray)) {
2076 MergeWithVar = FoundVar;
2077 break;
Douglas Gregor0f962a82010-02-10 17:16:49 +00002078 }
2079 }
2080
Douglas Gregor089459a2010-02-08 21:09:39 +00002081 Importer.ToDiag(Loc, diag::err_odr_variable_type_inconsistent)
Douglas Gregorea35d112010-02-15 23:54:17 +00002082 << Name << D->getType() << FoundVar->getType();
Douglas Gregor089459a2010-02-08 21:09:39 +00002083 Importer.ToDiag(FoundVar->getLocation(), diag::note_odr_value_here)
2084 << FoundVar->getType();
2085 }
2086 }
2087
2088 ConflictingDecls.push_back(*Lookup.first);
2089 }
2090
2091 if (MergeWithVar) {
2092 // An equivalent variable with external linkage has been found. Link
2093 // the two declarations, then merge them.
Douglas Gregor5ce5dab2010-02-12 23:44:20 +00002094 Importer.Imported(D, MergeWithVar);
Douglas Gregor089459a2010-02-08 21:09:39 +00002095
2096 if (VarDecl *DDef = D->getDefinition()) {
2097 if (VarDecl *ExistingDef = MergeWithVar->getDefinition()) {
2098 Importer.ToDiag(ExistingDef->getLocation(),
2099 diag::err_odr_variable_multiple_def)
2100 << Name;
2101 Importer.FromDiag(DDef->getLocation(), diag::note_odr_defined_here);
2102 } else {
2103 Expr *Init = Importer.Import(DDef->getInit());
Douglas Gregor838db382010-02-11 01:19:42 +00002104 MergeWithVar->setInit(Init);
Douglas Gregor089459a2010-02-08 21:09:39 +00002105 }
2106 }
2107
2108 return MergeWithVar;
2109 }
2110
2111 if (!ConflictingDecls.empty()) {
2112 Name = Importer.HandleNameConflict(Name, DC, IDNS,
2113 ConflictingDecls.data(),
2114 ConflictingDecls.size());
2115 if (!Name)
2116 return 0;
2117 }
2118 }
Douglas Gregor82fc4bf2010-02-10 17:47:19 +00002119
Douglas Gregorea35d112010-02-15 23:54:17 +00002120 // Import the type.
2121 QualType T = Importer.Import(D->getType());
2122 if (T.isNull())
2123 return 0;
2124
Douglas Gregor089459a2010-02-08 21:09:39 +00002125 // Create the imported variable.
Douglas Gregor82fc4bf2010-02-10 17:47:19 +00002126 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
Douglas Gregor089459a2010-02-08 21:09:39 +00002127 VarDecl *ToVar = VarDecl::Create(Importer.getToContext(), DC, Loc,
2128 Name.getAsIdentifierInfo(), T, TInfo,
Douglas Gregor16573fa2010-04-19 22:54:31 +00002129 D->getStorageClass(),
2130 D->getStorageClassAsWritten());
John McCallb6217662010-03-15 10:12:16 +00002131 // Import the qualifier, if any.
2132 if (D->getQualifier()) {
2133 NestedNameSpecifier *NNS = Importer.Import(D->getQualifier());
2134 SourceRange NNSRange = Importer.Import(D->getQualifierRange());
2135 ToVar->setQualifierInfo(NNS, NNSRange);
2136 }
Douglas Gregor325bf172010-02-22 17:42:47 +00002137 ToVar->setAccess(D->getAccess());
Douglas Gregor9bed8792010-02-09 19:21:46 +00002138 ToVar->setLexicalDeclContext(LexicalDC);
Douglas Gregor5ce5dab2010-02-12 23:44:20 +00002139 Importer.Imported(D, ToVar);
Douglas Gregor9bed8792010-02-09 19:21:46 +00002140 LexicalDC->addDecl(ToVar);
2141
Douglas Gregor089459a2010-02-08 21:09:39 +00002142 // Merge the initializer.
2143 // FIXME: Can we really import any initializer? Alternatively, we could force
2144 // ourselves to import every declaration of a variable and then only use
2145 // getInit() here.
Douglas Gregor838db382010-02-11 01:19:42 +00002146 ToVar->setInit(Importer.Import(const_cast<Expr *>(D->getAnyInitializer())));
Douglas Gregor089459a2010-02-08 21:09:39 +00002147
2148 // FIXME: Other bits to merge?
2149
2150 return ToVar;
2151}
2152
Douglas Gregor2cd00932010-02-17 21:22:52 +00002153Decl *ASTNodeImporter::VisitImplicitParamDecl(ImplicitParamDecl *D) {
2154 // Parameters are created in the translation unit's context, then moved
2155 // into the function declaration's context afterward.
2156 DeclContext *DC = Importer.getToContext().getTranslationUnitDecl();
2157
2158 // Import the name of this declaration.
2159 DeclarationName Name = Importer.Import(D->getDeclName());
2160 if (D->getDeclName() && !Name)
2161 return 0;
2162
2163 // Import the location of this declaration.
2164 SourceLocation Loc = Importer.Import(D->getLocation());
2165
2166 // Import the parameter's type.
2167 QualType T = Importer.Import(D->getType());
2168 if (T.isNull())
2169 return 0;
2170
2171 // Create the imported parameter.
2172 ImplicitParamDecl *ToParm
2173 = ImplicitParamDecl::Create(Importer.getToContext(), DC,
2174 Loc, Name.getAsIdentifierInfo(),
2175 T);
2176 return Importer.Imported(D, ToParm);
2177}
2178
Douglas Gregora404ea62010-02-10 19:54:31 +00002179Decl *ASTNodeImporter::VisitParmVarDecl(ParmVarDecl *D) {
2180 // Parameters are created in the translation unit's context, then moved
2181 // into the function declaration's context afterward.
2182 DeclContext *DC = Importer.getToContext().getTranslationUnitDecl();
2183
Douglas Gregor82fc4bf2010-02-10 17:47:19 +00002184 // Import the name of this declaration.
2185 DeclarationName Name = Importer.Import(D->getDeclName());
2186 if (D->getDeclName() && !Name)
2187 return 0;
2188
Douglas Gregora404ea62010-02-10 19:54:31 +00002189 // Import the location of this declaration.
2190 SourceLocation Loc = Importer.Import(D->getLocation());
2191
2192 // Import the parameter's type.
2193 QualType T = Importer.Import(D->getType());
2194 if (T.isNull())
2195 return 0;
2196
2197 // Create the imported parameter.
2198 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
2199 ParmVarDecl *ToParm = ParmVarDecl::Create(Importer.getToContext(), DC,
2200 Loc, Name.getAsIdentifierInfo(),
2201 T, TInfo, D->getStorageClass(),
Douglas Gregor16573fa2010-04-19 22:54:31 +00002202 D->getStorageClassAsWritten(),
Douglas Gregora404ea62010-02-10 19:54:31 +00002203 /*FIXME: Default argument*/ 0);
John McCallbf73b352010-03-12 18:31:32 +00002204 ToParm->setHasInheritedDefaultArg(D->hasInheritedDefaultArg());
Douglas Gregor5ce5dab2010-02-12 23:44:20 +00002205 return Importer.Imported(D, ToParm);
Douglas Gregora404ea62010-02-10 19:54:31 +00002206}
2207
Douglas Gregorc3f2d2b2010-02-17 02:12:47 +00002208Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
2209 // Import the major distinguishing characteristics of a method.
2210 DeclContext *DC, *LexicalDC;
2211 DeclarationName Name;
2212 SourceLocation Loc;
2213 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2214 return 0;
2215
2216 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
2217 Lookup.first != Lookup.second;
2218 ++Lookup.first) {
2219 if (ObjCMethodDecl *FoundMethod = dyn_cast<ObjCMethodDecl>(*Lookup.first)) {
2220 if (FoundMethod->isInstanceMethod() != D->isInstanceMethod())
2221 continue;
2222
2223 // Check return types.
2224 if (!Importer.IsStructurallyEquivalent(D->getResultType(),
2225 FoundMethod->getResultType())) {
2226 Importer.ToDiag(Loc, diag::err_odr_objc_method_result_type_inconsistent)
2227 << D->isInstanceMethod() << Name
2228 << D->getResultType() << FoundMethod->getResultType();
2229 Importer.ToDiag(FoundMethod->getLocation(),
2230 diag::note_odr_objc_method_here)
2231 << D->isInstanceMethod() << Name;
2232 return 0;
2233 }
2234
2235 // Check the number of parameters.
2236 if (D->param_size() != FoundMethod->param_size()) {
2237 Importer.ToDiag(Loc, diag::err_odr_objc_method_num_params_inconsistent)
2238 << D->isInstanceMethod() << Name
2239 << D->param_size() << FoundMethod->param_size();
2240 Importer.ToDiag(FoundMethod->getLocation(),
2241 diag::note_odr_objc_method_here)
2242 << D->isInstanceMethod() << Name;
2243 return 0;
2244 }
2245
2246 // Check parameter types.
2247 for (ObjCMethodDecl::param_iterator P = D->param_begin(),
2248 PEnd = D->param_end(), FoundP = FoundMethod->param_begin();
2249 P != PEnd; ++P, ++FoundP) {
2250 if (!Importer.IsStructurallyEquivalent((*P)->getType(),
2251 (*FoundP)->getType())) {
2252 Importer.FromDiag((*P)->getLocation(),
2253 diag::err_odr_objc_method_param_type_inconsistent)
2254 << D->isInstanceMethod() << Name
2255 << (*P)->getType() << (*FoundP)->getType();
2256 Importer.ToDiag((*FoundP)->getLocation(), diag::note_odr_value_here)
2257 << (*FoundP)->getType();
2258 return 0;
2259 }
2260 }
2261
2262 // Check variadic/non-variadic.
2263 // Check the number of parameters.
2264 if (D->isVariadic() != FoundMethod->isVariadic()) {
2265 Importer.ToDiag(Loc, diag::err_odr_objc_method_variadic_inconsistent)
2266 << D->isInstanceMethod() << Name;
2267 Importer.ToDiag(FoundMethod->getLocation(),
2268 diag::note_odr_objc_method_here)
2269 << D->isInstanceMethod() << Name;
2270 return 0;
2271 }
2272
2273 // FIXME: Any other bits we need to merge?
2274 return Importer.Imported(D, FoundMethod);
2275 }
2276 }
2277
2278 // Import the result type.
2279 QualType ResultTy = Importer.Import(D->getResultType());
2280 if (ResultTy.isNull())
2281 return 0;
2282
Douglas Gregor4bc1cb62010-03-08 14:59:44 +00002283 TypeSourceInfo *ResultTInfo = Importer.Import(D->getResultTypeSourceInfo());
2284
Douglas Gregorc3f2d2b2010-02-17 02:12:47 +00002285 ObjCMethodDecl *ToMethod
2286 = ObjCMethodDecl::Create(Importer.getToContext(),
2287 Loc,
2288 Importer.Import(D->getLocEnd()),
2289 Name.getObjCSelector(),
Douglas Gregor4bc1cb62010-03-08 14:59:44 +00002290 ResultTy, ResultTInfo, DC,
Douglas Gregorc3f2d2b2010-02-17 02:12:47 +00002291 D->isInstanceMethod(),
2292 D->isVariadic(),
2293 D->isSynthesized(),
2294 D->getImplementationControl());
2295
2296 // FIXME: When we decide to merge method definitions, we'll need to
2297 // deal with implicit parameters.
2298
2299 // Import the parameters
2300 llvm::SmallVector<ParmVarDecl *, 5> ToParams;
2301 for (ObjCMethodDecl::param_iterator FromP = D->param_begin(),
2302 FromPEnd = D->param_end();
2303 FromP != FromPEnd;
2304 ++FromP) {
2305 ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(*FromP));
2306 if (!ToP)
2307 return 0;
2308
2309 ToParams.push_back(ToP);
2310 }
2311
2312 // Set the parameters.
2313 for (unsigned I = 0, N = ToParams.size(); I != N; ++I) {
2314 ToParams[I]->setOwningFunction(ToMethod);
2315 ToMethod->addDecl(ToParams[I]);
2316 }
2317 ToMethod->setMethodParams(Importer.getToContext(),
Fariborz Jahanian4ecb25f2010-04-09 15:40:42 +00002318 ToParams.data(), ToParams.size(),
2319 ToParams.size());
Douglas Gregorc3f2d2b2010-02-17 02:12:47 +00002320
2321 ToMethod->setLexicalDeclContext(LexicalDC);
2322 Importer.Imported(D, ToMethod);
2323 LexicalDC->addDecl(ToMethod);
2324 return ToMethod;
2325}
2326
Douglas Gregorb4677b62010-02-18 01:47:50 +00002327Decl *ASTNodeImporter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
2328 // Import the major distinguishing characteristics of a category.
2329 DeclContext *DC, *LexicalDC;
2330 DeclarationName Name;
2331 SourceLocation Loc;
2332 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2333 return 0;
2334
2335 ObjCInterfaceDecl *ToInterface
2336 = cast_or_null<ObjCInterfaceDecl>(Importer.Import(D->getClassInterface()));
2337 if (!ToInterface)
2338 return 0;
2339
2340 // Determine if we've already encountered this category.
2341 ObjCCategoryDecl *MergeWithCategory
2342 = ToInterface->FindCategoryDeclaration(Name.getAsIdentifierInfo());
2343 ObjCCategoryDecl *ToCategory = MergeWithCategory;
2344 if (!ToCategory) {
2345 ToCategory = ObjCCategoryDecl::Create(Importer.getToContext(), DC,
2346 Importer.Import(D->getAtLoc()),
2347 Loc,
2348 Importer.Import(D->getCategoryNameLoc()),
2349 Name.getAsIdentifierInfo());
2350 ToCategory->setLexicalDeclContext(LexicalDC);
2351 LexicalDC->addDecl(ToCategory);
2352 Importer.Imported(D, ToCategory);
2353
2354 // Link this category into its class's category list.
2355 ToCategory->setClassInterface(ToInterface);
2356 ToCategory->insertNextClassCategory();
2357
2358 // Import protocols
2359 llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
2360 llvm::SmallVector<SourceLocation, 4> ProtocolLocs;
2361 ObjCCategoryDecl::protocol_loc_iterator FromProtoLoc
2362 = D->protocol_loc_begin();
2363 for (ObjCCategoryDecl::protocol_iterator FromProto = D->protocol_begin(),
2364 FromProtoEnd = D->protocol_end();
2365 FromProto != FromProtoEnd;
2366 ++FromProto, ++FromProtoLoc) {
2367 ObjCProtocolDecl *ToProto
2368 = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
2369 if (!ToProto)
2370 return 0;
2371 Protocols.push_back(ToProto);
2372 ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
2373 }
2374
2375 // FIXME: If we're merging, make sure that the protocol list is the same.
2376 ToCategory->setProtocolList(Protocols.data(), Protocols.size(),
2377 ProtocolLocs.data(), Importer.getToContext());
2378
2379 } else {
2380 Importer.Imported(D, ToCategory);
2381 }
2382
2383 // Import all of the members of this category.
Douglas Gregor083a8212010-02-21 18:24:45 +00002384 ImportDeclContext(D);
Douglas Gregorb4677b62010-02-18 01:47:50 +00002385
2386 // If we have an implementation, import it as well.
2387 if (D->getImplementation()) {
2388 ObjCCategoryImplDecl *Impl
2389 = cast<ObjCCategoryImplDecl>(Importer.Import(D->getImplementation()));
2390 if (!Impl)
2391 return 0;
2392
2393 ToCategory->setImplementation(Impl);
2394 }
2395
2396 return ToCategory;
2397}
2398
Douglas Gregor2e2a4002010-02-17 16:12:00 +00002399Decl *ASTNodeImporter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
Douglas Gregorb4677b62010-02-18 01:47:50 +00002400 // Import the major distinguishing characteristics of a protocol.
Douglas Gregor2e2a4002010-02-17 16:12:00 +00002401 DeclContext *DC, *LexicalDC;
2402 DeclarationName Name;
2403 SourceLocation Loc;
2404 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2405 return 0;
2406
2407 ObjCProtocolDecl *MergeWithProtocol = 0;
2408 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
2409 Lookup.first != Lookup.second;
2410 ++Lookup.first) {
2411 if (!(*Lookup.first)->isInIdentifierNamespace(Decl::IDNS_ObjCProtocol))
2412 continue;
2413
2414 if ((MergeWithProtocol = dyn_cast<ObjCProtocolDecl>(*Lookup.first)))
2415 break;
2416 }
2417
2418 ObjCProtocolDecl *ToProto = MergeWithProtocol;
2419 if (!ToProto || ToProto->isForwardDecl()) {
2420 if (!ToProto) {
2421 ToProto = ObjCProtocolDecl::Create(Importer.getToContext(), DC, Loc,
2422 Name.getAsIdentifierInfo());
2423 ToProto->setForwardDecl(D->isForwardDecl());
2424 ToProto->setLexicalDeclContext(LexicalDC);
2425 LexicalDC->addDecl(ToProto);
2426 }
2427 Importer.Imported(D, ToProto);
2428
2429 // Import protocols
2430 llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
2431 llvm::SmallVector<SourceLocation, 4> ProtocolLocs;
2432 ObjCProtocolDecl::protocol_loc_iterator
2433 FromProtoLoc = D->protocol_loc_begin();
2434 for (ObjCProtocolDecl::protocol_iterator FromProto = D->protocol_begin(),
2435 FromProtoEnd = D->protocol_end();
2436 FromProto != FromProtoEnd;
2437 ++FromProto, ++FromProtoLoc) {
2438 ObjCProtocolDecl *ToProto
2439 = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
2440 if (!ToProto)
2441 return 0;
2442 Protocols.push_back(ToProto);
2443 ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
2444 }
2445
2446 // FIXME: If we're merging, make sure that the protocol list is the same.
2447 ToProto->setProtocolList(Protocols.data(), Protocols.size(),
2448 ProtocolLocs.data(), Importer.getToContext());
2449 } else {
2450 Importer.Imported(D, ToProto);
2451 }
2452
Douglas Gregorb4677b62010-02-18 01:47:50 +00002453 // Import all of the members of this protocol.
Douglas Gregor083a8212010-02-21 18:24:45 +00002454 ImportDeclContext(D);
Douglas Gregor2e2a4002010-02-17 16:12:00 +00002455
2456 return ToProto;
2457}
2458
Douglas Gregora12d2942010-02-16 01:20:57 +00002459Decl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
2460 // Import the major distinguishing characteristics of an @interface.
2461 DeclContext *DC, *LexicalDC;
2462 DeclarationName Name;
2463 SourceLocation Loc;
2464 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2465 return 0;
2466
2467 ObjCInterfaceDecl *MergeWithIface = 0;
2468 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
2469 Lookup.first != Lookup.second;
2470 ++Lookup.first) {
2471 if (!(*Lookup.first)->isInIdentifierNamespace(Decl::IDNS_Ordinary))
2472 continue;
2473
2474 if ((MergeWithIface = dyn_cast<ObjCInterfaceDecl>(*Lookup.first)))
2475 break;
2476 }
2477
2478 ObjCInterfaceDecl *ToIface = MergeWithIface;
2479 if (!ToIface || ToIface->isForwardDecl()) {
2480 if (!ToIface) {
2481 ToIface = ObjCInterfaceDecl::Create(Importer.getToContext(),
2482 DC, Loc,
2483 Name.getAsIdentifierInfo(),
2484 Importer.Import(D->getClassLoc()),
2485 D->isForwardDecl(),
2486 D->isImplicitInterfaceDecl());
Douglas Gregor2e2a4002010-02-17 16:12:00 +00002487 ToIface->setForwardDecl(D->isForwardDecl());
Douglas Gregora12d2942010-02-16 01:20:57 +00002488 ToIface->setLexicalDeclContext(LexicalDC);
2489 LexicalDC->addDecl(ToIface);
2490 }
2491 Importer.Imported(D, ToIface);
2492
Douglas Gregora12d2942010-02-16 01:20:57 +00002493 if (D->getSuperClass()) {
2494 ObjCInterfaceDecl *Super
2495 = cast_or_null<ObjCInterfaceDecl>(Importer.Import(D->getSuperClass()));
2496 if (!Super)
2497 return 0;
2498
2499 ToIface->setSuperClass(Super);
2500 ToIface->setSuperClassLoc(Importer.Import(D->getSuperClassLoc()));
2501 }
2502
2503 // Import protocols
2504 llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
2505 llvm::SmallVector<SourceLocation, 4> ProtocolLocs;
2506 ObjCInterfaceDecl::protocol_loc_iterator
2507 FromProtoLoc = D->protocol_loc_begin();
2508 for (ObjCInterfaceDecl::protocol_iterator FromProto = D->protocol_begin(),
2509 FromProtoEnd = D->protocol_end();
2510 FromProto != FromProtoEnd;
2511 ++FromProto, ++FromProtoLoc) {
2512 ObjCProtocolDecl *ToProto
2513 = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
2514 if (!ToProto)
2515 return 0;
2516 Protocols.push_back(ToProto);
2517 ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
2518 }
2519
2520 // FIXME: If we're merging, make sure that the protocol list is the same.
2521 ToIface->setProtocolList(Protocols.data(), Protocols.size(),
2522 ProtocolLocs.data(), Importer.getToContext());
2523
Douglas Gregora12d2942010-02-16 01:20:57 +00002524 // Import @end range
2525 ToIface->setAtEndRange(Importer.Import(D->getAtEndRange()));
2526 } else {
2527 Importer.Imported(D, ToIface);
Douglas Gregor2e55e3a2010-02-17 00:34:30 +00002528
2529 // Check for consistency of superclasses.
2530 DeclarationName FromSuperName, ToSuperName;
2531 if (D->getSuperClass())
2532 FromSuperName = Importer.Import(D->getSuperClass()->getDeclName());
2533 if (ToIface->getSuperClass())
2534 ToSuperName = ToIface->getSuperClass()->getDeclName();
2535 if (FromSuperName != ToSuperName) {
2536 Importer.ToDiag(ToIface->getLocation(),
2537 diag::err_odr_objc_superclass_inconsistent)
2538 << ToIface->getDeclName();
2539 if (ToIface->getSuperClass())
2540 Importer.ToDiag(ToIface->getSuperClassLoc(),
2541 diag::note_odr_objc_superclass)
2542 << ToIface->getSuperClass()->getDeclName();
2543 else
2544 Importer.ToDiag(ToIface->getLocation(),
2545 diag::note_odr_objc_missing_superclass);
2546 if (D->getSuperClass())
2547 Importer.FromDiag(D->getSuperClassLoc(),
2548 diag::note_odr_objc_superclass)
2549 << D->getSuperClass()->getDeclName();
2550 else
2551 Importer.FromDiag(D->getLocation(),
2552 diag::note_odr_objc_missing_superclass);
2553 return 0;
2554 }
Douglas Gregora12d2942010-02-16 01:20:57 +00002555 }
2556
Douglas Gregorb4677b62010-02-18 01:47:50 +00002557 // Import categories. When the categories themselves are imported, they'll
2558 // hook themselves into this interface.
2559 for (ObjCCategoryDecl *FromCat = D->getCategoryList(); FromCat;
2560 FromCat = FromCat->getNextClassCategory())
2561 Importer.Import(FromCat);
2562
Douglas Gregora12d2942010-02-16 01:20:57 +00002563 // Import all of the members of this class.
Douglas Gregor083a8212010-02-21 18:24:45 +00002564 ImportDeclContext(D);
Douglas Gregora12d2942010-02-16 01:20:57 +00002565
2566 // If we have an @implementation, import it as well.
2567 if (D->getImplementation()) {
2568 ObjCImplementationDecl *Impl
2569 = cast<ObjCImplementationDecl>(Importer.Import(D->getImplementation()));
2570 if (!Impl)
2571 return 0;
2572
2573 ToIface->setImplementation(Impl);
2574 }
2575
Douglas Gregor2e2a4002010-02-17 16:12:00 +00002576 return ToIface;
Douglas Gregora12d2942010-02-16 01:20:57 +00002577}
2578
Douglas Gregore3261622010-02-17 18:02:10 +00002579Decl *ASTNodeImporter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
2580 // Import the major distinguishing characteristics of an @property.
2581 DeclContext *DC, *LexicalDC;
2582 DeclarationName Name;
2583 SourceLocation Loc;
2584 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2585 return 0;
2586
2587 // Check whether we have already imported this property.
2588 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
2589 Lookup.first != Lookup.second;
2590 ++Lookup.first) {
2591 if (ObjCPropertyDecl *FoundProp
2592 = dyn_cast<ObjCPropertyDecl>(*Lookup.first)) {
2593 // Check property types.
2594 if (!Importer.IsStructurallyEquivalent(D->getType(),
2595 FoundProp->getType())) {
2596 Importer.ToDiag(Loc, diag::err_odr_objc_property_type_inconsistent)
2597 << Name << D->getType() << FoundProp->getType();
2598 Importer.ToDiag(FoundProp->getLocation(), diag::note_odr_value_here)
2599 << FoundProp->getType();
2600 return 0;
2601 }
2602
2603 // FIXME: Check property attributes, getters, setters, etc.?
2604
2605 // Consider these properties to be equivalent.
2606 Importer.Imported(D, FoundProp);
2607 return FoundProp;
2608 }
2609 }
2610
2611 // Import the type.
2612 QualType T = Importer.Import(D->getType());
2613 if (T.isNull())
2614 return 0;
2615
2616 // Create the new property.
2617 ObjCPropertyDecl *ToProperty
2618 = ObjCPropertyDecl::Create(Importer.getToContext(), DC, Loc,
2619 Name.getAsIdentifierInfo(),
2620 Importer.Import(D->getAtLoc()),
2621 T,
2622 D->getPropertyImplementation());
2623 Importer.Imported(D, ToProperty);
2624 ToProperty->setLexicalDeclContext(LexicalDC);
2625 LexicalDC->addDecl(ToProperty);
2626
2627 ToProperty->setPropertyAttributes(D->getPropertyAttributes());
2628 ToProperty->setGetterName(Importer.Import(D->getGetterName()));
2629 ToProperty->setSetterName(Importer.Import(D->getSetterName()));
2630 ToProperty->setGetterMethodDecl(
2631 cast_or_null<ObjCMethodDecl>(Importer.Import(D->getGetterMethodDecl())));
2632 ToProperty->setSetterMethodDecl(
2633 cast_or_null<ObjCMethodDecl>(Importer.Import(D->getSetterMethodDecl())));
2634 ToProperty->setPropertyIvarDecl(
2635 cast_or_null<ObjCIvarDecl>(Importer.Import(D->getPropertyIvarDecl())));
2636 return ToProperty;
2637}
2638
Douglas Gregor2b785022010-02-18 02:12:22 +00002639Decl *
2640ASTNodeImporter::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) {
2641 // Import the context of this declaration.
2642 DeclContext *DC = Importer.ImportContext(D->getDeclContext());
2643 if (!DC)
2644 return 0;
2645
2646 DeclContext *LexicalDC = DC;
2647 if (D->getDeclContext() != D->getLexicalDeclContext()) {
2648 LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
2649 if (!LexicalDC)
2650 return 0;
2651 }
2652
2653 // Import the location of this declaration.
2654 SourceLocation Loc = Importer.Import(D->getLocation());
2655
2656 llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
2657 llvm::SmallVector<SourceLocation, 4> Locations;
2658 ObjCForwardProtocolDecl::protocol_loc_iterator FromProtoLoc
2659 = D->protocol_loc_begin();
2660 for (ObjCForwardProtocolDecl::protocol_iterator FromProto
2661 = D->protocol_begin(), FromProtoEnd = D->protocol_end();
2662 FromProto != FromProtoEnd;
2663 ++FromProto, ++FromProtoLoc) {
2664 ObjCProtocolDecl *ToProto
2665 = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
2666 if (!ToProto)
2667 continue;
2668
2669 Protocols.push_back(ToProto);
2670 Locations.push_back(Importer.Import(*FromProtoLoc));
2671 }
2672
2673 ObjCForwardProtocolDecl *ToForward
2674 = ObjCForwardProtocolDecl::Create(Importer.getToContext(), DC, Loc,
2675 Protocols.data(), Protocols.size(),
2676 Locations.data());
2677 ToForward->setLexicalDeclContext(LexicalDC);
2678 LexicalDC->addDecl(ToForward);
2679 Importer.Imported(D, ToForward);
2680 return ToForward;
2681}
2682
Douglas Gregora2bc15b2010-02-18 02:04:09 +00002683Decl *ASTNodeImporter::VisitObjCClassDecl(ObjCClassDecl *D) {
2684 // Import the context of this declaration.
2685 DeclContext *DC = Importer.ImportContext(D->getDeclContext());
2686 if (!DC)
2687 return 0;
2688
2689 DeclContext *LexicalDC = DC;
2690 if (D->getDeclContext() != D->getLexicalDeclContext()) {
2691 LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
2692 if (!LexicalDC)
2693 return 0;
2694 }
2695
2696 // Import the location of this declaration.
2697 SourceLocation Loc = Importer.Import(D->getLocation());
2698
2699 llvm::SmallVector<ObjCInterfaceDecl *, 4> Interfaces;
2700 llvm::SmallVector<SourceLocation, 4> Locations;
2701 for (ObjCClassDecl::iterator From = D->begin(), FromEnd = D->end();
2702 From != FromEnd; ++From) {
2703 ObjCInterfaceDecl *ToIface
2704 = cast_or_null<ObjCInterfaceDecl>(Importer.Import(From->getInterface()));
2705 if (!ToIface)
2706 continue;
2707
2708 Interfaces.push_back(ToIface);
2709 Locations.push_back(Importer.Import(From->getLocation()));
2710 }
2711
2712 ObjCClassDecl *ToClass = ObjCClassDecl::Create(Importer.getToContext(), DC,
2713 Loc,
2714 Interfaces.data(),
2715 Locations.data(),
2716 Interfaces.size());
2717 ToClass->setLexicalDeclContext(LexicalDC);
2718 LexicalDC->addDecl(ToClass);
2719 Importer.Imported(D, ToClass);
2720 return ToClass;
2721}
2722
Douglas Gregor4800d952010-02-11 19:21:55 +00002723//----------------------------------------------------------------------------
2724// Import Statements
2725//----------------------------------------------------------------------------
2726
2727Stmt *ASTNodeImporter::VisitStmt(Stmt *S) {
2728 Importer.FromDiag(S->getLocStart(), diag::err_unsupported_ast_node)
2729 << S->getStmtClassName();
2730 return 0;
2731}
2732
2733//----------------------------------------------------------------------------
2734// Import Expressions
2735//----------------------------------------------------------------------------
2736Expr *ASTNodeImporter::VisitExpr(Expr *E) {
2737 Importer.FromDiag(E->getLocStart(), diag::err_unsupported_ast_node)
2738 << E->getStmtClassName();
2739 return 0;
2740}
2741
Douglas Gregor44080632010-02-19 01:17:02 +00002742Expr *ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) {
2743 NestedNameSpecifier *Qualifier = 0;
2744 if (E->getQualifier()) {
2745 Qualifier = Importer.Import(E->getQualifier());
2746 if (!E->getQualifier())
2747 return 0;
2748 }
2749
2750 ValueDecl *ToD = cast_or_null<ValueDecl>(Importer.Import(E->getDecl()));
2751 if (!ToD)
2752 return 0;
2753
2754 QualType T = Importer.Import(E->getType());
2755 if (T.isNull())
2756 return 0;
2757
2758 return DeclRefExpr::Create(Importer.getToContext(), Qualifier,
2759 Importer.Import(E->getQualifierRange()),
2760 ToD,
2761 Importer.Import(E->getLocation()),
2762 T,
2763 /*FIXME:TemplateArgs=*/0);
2764}
2765
Douglas Gregor4800d952010-02-11 19:21:55 +00002766Expr *ASTNodeImporter::VisitIntegerLiteral(IntegerLiteral *E) {
2767 QualType T = Importer.Import(E->getType());
2768 if (T.isNull())
2769 return 0;
2770
2771 return new (Importer.getToContext())
2772 IntegerLiteral(E->getValue(), T, Importer.Import(E->getLocation()));
2773}
2774
Douglas Gregorb2e400a2010-02-18 02:21:22 +00002775Expr *ASTNodeImporter::VisitCharacterLiteral(CharacterLiteral *E) {
2776 QualType T = Importer.Import(E->getType());
2777 if (T.isNull())
2778 return 0;
2779
2780 return new (Importer.getToContext()) CharacterLiteral(E->getValue(),
2781 E->isWide(), T,
2782 Importer.Import(E->getLocation()));
2783}
2784
Douglas Gregorf638f952010-02-19 01:07:06 +00002785Expr *ASTNodeImporter::VisitParenExpr(ParenExpr *E) {
2786 Expr *SubExpr = Importer.Import(E->getSubExpr());
2787 if (!SubExpr)
2788 return 0;
2789
2790 return new (Importer.getToContext())
2791 ParenExpr(Importer.Import(E->getLParen()),
2792 Importer.Import(E->getRParen()),
2793 SubExpr);
2794}
2795
2796Expr *ASTNodeImporter::VisitUnaryOperator(UnaryOperator *E) {
2797 QualType T = Importer.Import(E->getType());
2798 if (T.isNull())
2799 return 0;
2800
2801 Expr *SubExpr = Importer.Import(E->getSubExpr());
2802 if (!SubExpr)
2803 return 0;
2804
2805 return new (Importer.getToContext()) UnaryOperator(SubExpr, E->getOpcode(),
2806 T,
2807 Importer.Import(E->getOperatorLoc()));
2808}
2809
Douglas Gregorbd249a52010-02-19 01:24:23 +00002810Expr *ASTNodeImporter::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
2811 QualType ResultType = Importer.Import(E->getType());
2812
2813 if (E->isArgumentType()) {
2814 TypeSourceInfo *TInfo = Importer.Import(E->getArgumentTypeInfo());
2815 if (!TInfo)
2816 return 0;
2817
2818 return new (Importer.getToContext()) SizeOfAlignOfExpr(E->isSizeOf(),
2819 TInfo, ResultType,
2820 Importer.Import(E->getOperatorLoc()),
2821 Importer.Import(E->getRParenLoc()));
2822 }
2823
2824 Expr *SubExpr = Importer.Import(E->getArgumentExpr());
2825 if (!SubExpr)
2826 return 0;
2827
2828 return new (Importer.getToContext()) SizeOfAlignOfExpr(E->isSizeOf(),
2829 SubExpr, ResultType,
2830 Importer.Import(E->getOperatorLoc()),
2831 Importer.Import(E->getRParenLoc()));
2832}
2833
Douglas Gregorf638f952010-02-19 01:07:06 +00002834Expr *ASTNodeImporter::VisitBinaryOperator(BinaryOperator *E) {
2835 QualType T = Importer.Import(E->getType());
2836 if (T.isNull())
2837 return 0;
2838
2839 Expr *LHS = Importer.Import(E->getLHS());
2840 if (!LHS)
2841 return 0;
2842
2843 Expr *RHS = Importer.Import(E->getRHS());
2844 if (!RHS)
2845 return 0;
2846
2847 return new (Importer.getToContext()) BinaryOperator(LHS, RHS, E->getOpcode(),
2848 T,
2849 Importer.Import(E->getOperatorLoc()));
2850}
2851
2852Expr *ASTNodeImporter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
2853 QualType T = Importer.Import(E->getType());
2854 if (T.isNull())
2855 return 0;
2856
2857 QualType CompLHSType = Importer.Import(E->getComputationLHSType());
2858 if (CompLHSType.isNull())
2859 return 0;
2860
2861 QualType CompResultType = Importer.Import(E->getComputationResultType());
2862 if (CompResultType.isNull())
2863 return 0;
2864
2865 Expr *LHS = Importer.Import(E->getLHS());
2866 if (!LHS)
2867 return 0;
2868
2869 Expr *RHS = Importer.Import(E->getRHS());
2870 if (!RHS)
2871 return 0;
2872
2873 return new (Importer.getToContext())
2874 CompoundAssignOperator(LHS, RHS, E->getOpcode(),
2875 T, CompLHSType, CompResultType,
2876 Importer.Import(E->getOperatorLoc()));
2877}
2878
Douglas Gregor36ead2e2010-02-12 22:17:39 +00002879Expr *ASTNodeImporter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
2880 QualType T = Importer.Import(E->getType());
2881 if (T.isNull())
2882 return 0;
2883
2884 Expr *SubExpr = Importer.Import(E->getSubExpr());
2885 if (!SubExpr)
2886 return 0;
2887
2888 return new (Importer.getToContext()) ImplicitCastExpr(T, E->getCastKind(),
2889 SubExpr,
Anders Carlsson88465d32010-04-23 22:18:37 +00002890 /* FIXME: */0,
Douglas Gregor36ead2e2010-02-12 22:17:39 +00002891 E->isLvalueCast());
2892}
2893
Douglas Gregor008847a2010-02-19 01:32:14 +00002894Expr *ASTNodeImporter::VisitCStyleCastExpr(CStyleCastExpr *E) {
2895 QualType T = Importer.Import(E->getType());
2896 if (T.isNull())
2897 return 0;
2898
2899 Expr *SubExpr = Importer.Import(E->getSubExpr());
2900 if (!SubExpr)
2901 return 0;
2902
2903 TypeSourceInfo *TInfo = Importer.Import(E->getTypeInfoAsWritten());
2904 if (!TInfo && E->getTypeInfoAsWritten())
2905 return 0;
2906
2907 return new (Importer.getToContext()) CStyleCastExpr(T, E->getCastKind(),
2908 SubExpr, TInfo,
2909 Importer.Import(E->getLParenLoc()),
2910 Importer.Import(E->getRParenLoc()));
2911}
2912
Douglas Gregor4800d952010-02-11 19:21:55 +00002913ASTImporter::ASTImporter(Diagnostic &Diags,
2914 ASTContext &ToContext, FileManager &ToFileManager,
2915 ASTContext &FromContext, FileManager &FromFileManager)
Douglas Gregor1b2949d2010-02-05 17:54:41 +00002916 : ToContext(ToContext), FromContext(FromContext),
Douglas Gregor88523732010-02-10 00:15:17 +00002917 ToFileManager(ToFileManager), FromFileManager(FromFileManager),
Douglas Gregor4800d952010-02-11 19:21:55 +00002918 Diags(Diags) {
Douglas Gregor9bed8792010-02-09 19:21:46 +00002919 ImportedDecls[FromContext.getTranslationUnitDecl()]
2920 = ToContext.getTranslationUnitDecl();
2921}
2922
2923ASTImporter::~ASTImporter() { }
Douglas Gregor1b2949d2010-02-05 17:54:41 +00002924
2925QualType ASTImporter::Import(QualType FromT) {
2926 if (FromT.isNull())
2927 return QualType();
2928
Douglas Gregor169fba52010-02-08 15:18:58 +00002929 // Check whether we've already imported this type.
2930 llvm::DenseMap<Type *, Type *>::iterator Pos
2931 = ImportedTypes.find(FromT.getTypePtr());
2932 if (Pos != ImportedTypes.end())
2933 return ToContext.getQualifiedType(Pos->second, FromT.getQualifiers());
Douglas Gregor1b2949d2010-02-05 17:54:41 +00002934
Douglas Gregor169fba52010-02-08 15:18:58 +00002935 // Import the type
Douglas Gregor1b2949d2010-02-05 17:54:41 +00002936 ASTNodeImporter Importer(*this);
2937 QualType ToT = Importer.Visit(FromT.getTypePtr());
2938 if (ToT.isNull())
2939 return ToT;
2940
Douglas Gregor169fba52010-02-08 15:18:58 +00002941 // Record the imported type.
2942 ImportedTypes[FromT.getTypePtr()] = ToT.getTypePtr();
2943
Douglas Gregor1b2949d2010-02-05 17:54:41 +00002944 return ToContext.getQualifiedType(ToT, FromT.getQualifiers());
2945}
2946
Douglas Gregor9bed8792010-02-09 19:21:46 +00002947TypeSourceInfo *ASTImporter::Import(TypeSourceInfo *FromTSI) {
Douglas Gregor82fc4bf2010-02-10 17:47:19 +00002948 if (!FromTSI)
2949 return FromTSI;
2950
2951 // FIXME: For now we just create a "trivial" type source info based
2952 // on the type and a seingle location. Implement a real version of
2953 // this.
2954 QualType T = Import(FromTSI->getType());
2955 if (T.isNull())
2956 return 0;
2957
2958 return ToContext.getTrivialTypeSourceInfo(T,
2959 FromTSI->getTypeLoc().getFullSourceRange().getBegin());
Douglas Gregor9bed8792010-02-09 19:21:46 +00002960}
2961
2962Decl *ASTImporter::Import(Decl *FromD) {
2963 if (!FromD)
2964 return 0;
2965
2966 // Check whether we've already imported this declaration.
2967 llvm::DenseMap<Decl *, Decl *>::iterator Pos = ImportedDecls.find(FromD);
2968 if (Pos != ImportedDecls.end())
2969 return Pos->second;
2970
2971 // Import the type
2972 ASTNodeImporter Importer(*this);
2973 Decl *ToD = Importer.Visit(FromD);
2974 if (!ToD)
2975 return 0;
2976
2977 // Record the imported declaration.
2978 ImportedDecls[FromD] = ToD;
Douglas Gregorea35d112010-02-15 23:54:17 +00002979
2980 if (TagDecl *FromTag = dyn_cast<TagDecl>(FromD)) {
2981 // Keep track of anonymous tags that have an associated typedef.
2982 if (FromTag->getTypedefForAnonDecl())
2983 AnonTagsWithPendingTypedefs.push_back(FromTag);
2984 } else if (TypedefDecl *FromTypedef = dyn_cast<TypedefDecl>(FromD)) {
2985 // When we've finished transforming a typedef, see whether it was the
2986 // typedef for an anonymous tag.
2987 for (llvm::SmallVector<TagDecl *, 4>::iterator
2988 FromTag = AnonTagsWithPendingTypedefs.begin(),
2989 FromTagEnd = AnonTagsWithPendingTypedefs.end();
2990 FromTag != FromTagEnd; ++FromTag) {
2991 if ((*FromTag)->getTypedefForAnonDecl() == FromTypedef) {
2992 if (TagDecl *ToTag = cast_or_null<TagDecl>(Import(*FromTag))) {
2993 // We found the typedef for an anonymous tag; link them.
2994 ToTag->setTypedefForAnonDecl(cast<TypedefDecl>(ToD));
2995 AnonTagsWithPendingTypedefs.erase(FromTag);
2996 break;
2997 }
2998 }
2999 }
3000 }
3001
Douglas Gregor9bed8792010-02-09 19:21:46 +00003002 return ToD;
3003}
3004
3005DeclContext *ASTImporter::ImportContext(DeclContext *FromDC) {
3006 if (!FromDC)
3007 return FromDC;
3008
3009 return cast_or_null<DeclContext>(Import(cast<Decl>(FromDC)));
3010}
3011
3012Expr *ASTImporter::Import(Expr *FromE) {
3013 if (!FromE)
3014 return 0;
3015
3016 return cast_or_null<Expr>(Import(cast<Stmt>(FromE)));
3017}
3018
3019Stmt *ASTImporter::Import(Stmt *FromS) {
3020 if (!FromS)
3021 return 0;
3022
Douglas Gregor4800d952010-02-11 19:21:55 +00003023 // Check whether we've already imported this declaration.
3024 llvm::DenseMap<Stmt *, Stmt *>::iterator Pos = ImportedStmts.find(FromS);
3025 if (Pos != ImportedStmts.end())
3026 return Pos->second;
3027
3028 // Import the type
3029 ASTNodeImporter Importer(*this);
3030 Stmt *ToS = Importer.Visit(FromS);
3031 if (!ToS)
3032 return 0;
3033
3034 // Record the imported declaration.
3035 ImportedStmts[FromS] = ToS;
3036 return ToS;
Douglas Gregor9bed8792010-02-09 19:21:46 +00003037}
3038
3039NestedNameSpecifier *ASTImporter::Import(NestedNameSpecifier *FromNNS) {
3040 if (!FromNNS)
3041 return 0;
3042
3043 // FIXME: Implement!
3044 return 0;
3045}
3046
3047SourceLocation ASTImporter::Import(SourceLocation FromLoc) {
3048 if (FromLoc.isInvalid())
3049 return SourceLocation();
3050
Douglas Gregor88523732010-02-10 00:15:17 +00003051 SourceManager &FromSM = FromContext.getSourceManager();
3052
3053 // For now, map everything down to its spelling location, so that we
3054 // don't have to import macro instantiations.
3055 // FIXME: Import macro instantiations!
3056 FromLoc = FromSM.getSpellingLoc(FromLoc);
3057 std::pair<FileID, unsigned> Decomposed = FromSM.getDecomposedLoc(FromLoc);
3058 SourceManager &ToSM = ToContext.getSourceManager();
3059 return ToSM.getLocForStartOfFile(Import(Decomposed.first))
3060 .getFileLocWithOffset(Decomposed.second);
Douglas Gregor9bed8792010-02-09 19:21:46 +00003061}
3062
3063SourceRange ASTImporter::Import(SourceRange FromRange) {
3064 return SourceRange(Import(FromRange.getBegin()), Import(FromRange.getEnd()));
3065}
3066
Douglas Gregor88523732010-02-10 00:15:17 +00003067FileID ASTImporter::Import(FileID FromID) {
3068 llvm::DenseMap<unsigned, FileID>::iterator Pos
3069 = ImportedFileIDs.find(FromID.getHashValue());
3070 if (Pos != ImportedFileIDs.end())
3071 return Pos->second;
3072
3073 SourceManager &FromSM = FromContext.getSourceManager();
3074 SourceManager &ToSM = ToContext.getSourceManager();
3075 const SrcMgr::SLocEntry &FromSLoc = FromSM.getSLocEntry(FromID);
3076 assert(FromSLoc.isFile() && "Cannot handle macro instantiations yet");
3077
3078 // Include location of this file.
3079 SourceLocation ToIncludeLoc = Import(FromSLoc.getFile().getIncludeLoc());
3080
3081 // Map the FileID for to the "to" source manager.
3082 FileID ToID;
3083 const SrcMgr::ContentCache *Cache = FromSLoc.getFile().getContentCache();
3084 if (Cache->Entry) {
3085 // FIXME: We probably want to use getVirtualFile(), so we don't hit the
3086 // disk again
3087 // FIXME: We definitely want to re-use the existing MemoryBuffer, rather
3088 // than mmap the files several times.
3089 const FileEntry *Entry = ToFileManager.getFile(Cache->Entry->getName());
3090 ToID = ToSM.createFileID(Entry, ToIncludeLoc,
3091 FromSLoc.getFile().getFileCharacteristic());
3092 } else {
3093 // FIXME: We want to re-use the existing MemoryBuffer!
Chris Lattnere127a0d2010-04-20 20:35:58 +00003094 const llvm::MemoryBuffer *FromBuf = Cache->getBuffer(getDiags(), FromSM);
Douglas Gregor88523732010-02-10 00:15:17 +00003095 llvm::MemoryBuffer *ToBuf
Chris Lattnera0a270c2010-04-05 22:42:27 +00003096 = llvm::MemoryBuffer::getMemBufferCopy(FromBuf->getBuffer(),
Douglas Gregor88523732010-02-10 00:15:17 +00003097 FromBuf->getBufferIdentifier());
3098 ToID = ToSM.createFileIDForMemBuffer(ToBuf);
3099 }
3100
3101
3102 ImportedFileIDs[FromID.getHashValue()] = ToID;
3103 return ToID;
3104}
3105
Douglas Gregor1b2949d2010-02-05 17:54:41 +00003106DeclarationName ASTImporter::Import(DeclarationName FromName) {
3107 if (!FromName)
3108 return DeclarationName();
3109
3110 switch (FromName.getNameKind()) {
3111 case DeclarationName::Identifier:
3112 return Import(FromName.getAsIdentifierInfo());
3113
3114 case DeclarationName::ObjCZeroArgSelector:
3115 case DeclarationName::ObjCOneArgSelector:
3116 case DeclarationName::ObjCMultiArgSelector:
3117 return Import(FromName.getObjCSelector());
3118
3119 case DeclarationName::CXXConstructorName: {
3120 QualType T = Import(FromName.getCXXNameType());
3121 if (T.isNull())
3122 return DeclarationName();
3123
3124 return ToContext.DeclarationNames.getCXXConstructorName(
3125 ToContext.getCanonicalType(T));
3126 }
3127
3128 case DeclarationName::CXXDestructorName: {
3129 QualType T = Import(FromName.getCXXNameType());
3130 if (T.isNull())
3131 return DeclarationName();
3132
3133 return ToContext.DeclarationNames.getCXXDestructorName(
3134 ToContext.getCanonicalType(T));
3135 }
3136
3137 case DeclarationName::CXXConversionFunctionName: {
3138 QualType T = Import(FromName.getCXXNameType());
3139 if (T.isNull())
3140 return DeclarationName();
3141
3142 return ToContext.DeclarationNames.getCXXConversionFunctionName(
3143 ToContext.getCanonicalType(T));
3144 }
3145
3146 case DeclarationName::CXXOperatorName:
3147 return ToContext.DeclarationNames.getCXXOperatorName(
3148 FromName.getCXXOverloadedOperator());
3149
3150 case DeclarationName::CXXLiteralOperatorName:
3151 return ToContext.DeclarationNames.getCXXLiteralOperatorName(
3152 Import(FromName.getCXXLiteralIdentifier()));
3153
3154 case DeclarationName::CXXUsingDirective:
3155 // FIXME: STATICS!
3156 return DeclarationName::getUsingDirectiveName();
3157 }
3158
3159 // Silence bogus GCC warning
3160 return DeclarationName();
3161}
3162
3163IdentifierInfo *ASTImporter::Import(IdentifierInfo *FromId) {
3164 if (!FromId)
3165 return 0;
3166
3167 return &ToContext.Idents.get(FromId->getName());
3168}
Douglas Gregor089459a2010-02-08 21:09:39 +00003169
Douglas Gregorc3f2d2b2010-02-17 02:12:47 +00003170Selector ASTImporter::Import(Selector FromSel) {
3171 if (FromSel.isNull())
3172 return Selector();
3173
3174 llvm::SmallVector<IdentifierInfo *, 4> Idents;
3175 Idents.push_back(Import(FromSel.getIdentifierInfoForSlot(0)));
3176 for (unsigned I = 1, N = FromSel.getNumArgs(); I < N; ++I)
3177 Idents.push_back(Import(FromSel.getIdentifierInfoForSlot(I)));
3178 return ToContext.Selectors.getSelector(FromSel.getNumArgs(), Idents.data());
3179}
3180
Douglas Gregor089459a2010-02-08 21:09:39 +00003181DeclarationName ASTImporter::HandleNameConflict(DeclarationName Name,
3182 DeclContext *DC,
3183 unsigned IDNS,
3184 NamedDecl **Decls,
3185 unsigned NumDecls) {
3186 return Name;
3187}
3188
3189DiagnosticBuilder ASTImporter::ToDiag(SourceLocation Loc, unsigned DiagID) {
Douglas Gregor4800d952010-02-11 19:21:55 +00003190 return Diags.Report(FullSourceLoc(Loc, ToContext.getSourceManager()),
3191 DiagID);
Douglas Gregor089459a2010-02-08 21:09:39 +00003192}
3193
3194DiagnosticBuilder ASTImporter::FromDiag(SourceLocation Loc, unsigned DiagID) {
Douglas Gregor4800d952010-02-11 19:21:55 +00003195 return Diags.Report(FullSourceLoc(Loc, FromContext.getSourceManager()),
3196 DiagID);
Douglas Gregor089459a2010-02-08 21:09:39 +00003197}
Douglas Gregor5ce5dab2010-02-12 23:44:20 +00003198
3199Decl *ASTImporter::Imported(Decl *From, Decl *To) {
3200 ImportedDecls[From] = To;
3201 return To;
Daniel Dunbaraf667582010-02-13 20:24:39 +00003202}
Douglas Gregorea35d112010-02-15 23:54:17 +00003203
3204bool ASTImporter::IsStructurallyEquivalent(QualType From, QualType To) {
3205 llvm::DenseMap<Type *, Type *>::iterator Pos
3206 = ImportedTypes.find(From.getTypePtr());
3207 if (Pos != ImportedTypes.end() && ToContext.hasSameType(Import(From), To))
3208 return true;
3209
Benjamin Kramerbb2d1762010-02-18 13:02:13 +00003210 StructuralEquivalenceContext Ctx(FromContext, ToContext, Diags,
Douglas Gregorea35d112010-02-15 23:54:17 +00003211 NonEquivalentDecls);
Benjamin Kramerbb2d1762010-02-18 13:02:13 +00003212 return Ctx.IsStructurallyEquivalent(From, To);
Douglas Gregorea35d112010-02-15 23:54:17 +00003213}