blob: aae02a48cd8efbb9940427484e4de05fb184f08c [file] [log] [blame]
Douglas Gregor96e578d2010-02-05 17:54:41 +00001//===--- ASTImporter.cpp - Importing ASTs from other Contexts ---*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the ASTImporter class which imports AST nodes from one
11// context into another context.
12//
13//===----------------------------------------------------------------------===//
14#include "clang/AST/ASTImporter.h"
15
16#include "clang/AST/ASTContext.h"
Douglas Gregor811663e2010-02-10 00:15:17 +000017#include "clang/AST/ASTDiagnostic.h"
Douglas Gregor5c73e912010-02-11 00:48:18 +000018#include "clang/AST/DeclCXX.h"
Douglas Gregor96e578d2010-02-05 17:54:41 +000019#include "clang/AST/DeclObjC.h"
Douglas Gregor3aed6cd2010-02-08 21:09:39 +000020#include "clang/AST/DeclVisitor.h"
Douglas Gregor7eeb5972010-02-11 19:21:55 +000021#include "clang/AST/StmtVisitor.h"
Douglas Gregorfa7a0e52010-02-10 17:47:19 +000022#include "clang/AST/TypeLoc.h"
Douglas Gregor96e578d2010-02-05 17:54:41 +000023#include "clang/AST/TypeVisitor.h"
Douglas Gregor811663e2010-02-10 00:15:17 +000024#include "clang/Basic/FileManager.h"
25#include "clang/Basic/SourceManager.h"
26#include "llvm/Support/MemoryBuffer.h"
Douglas Gregor3996e242010-02-15 22:01:00 +000027#include <deque>
Douglas Gregor96e578d2010-02-05 17:54:41 +000028
29using namespace clang;
30
31namespace {
Douglas Gregor3aed6cd2010-02-08 21:09:39 +000032 class ASTNodeImporter : public TypeVisitor<ASTNodeImporter, QualType>,
Douglas Gregor7eeb5972010-02-11 19:21:55 +000033 public DeclVisitor<ASTNodeImporter, Decl *>,
34 public StmtVisitor<ASTNodeImporter, Stmt *> {
Douglas Gregor96e578d2010-02-05 17:54:41 +000035 ASTImporter &Importer;
36
37 public:
38 explicit ASTNodeImporter(ASTImporter &Importer) : Importer(Importer) { }
39
40 using TypeVisitor<ASTNodeImporter, QualType>::Visit;
Douglas Gregor62d311f2010-02-09 19:21:46 +000041 using DeclVisitor<ASTNodeImporter, Decl *>::Visit;
Douglas Gregor7eeb5972010-02-11 19:21:55 +000042 using StmtVisitor<ASTNodeImporter, Stmt *>::Visit;
Douglas Gregor96e578d2010-02-05 17:54:41 +000043
44 // Importing types
Douglas Gregore4c83e42010-02-09 22:48:33 +000045 QualType VisitType(Type *T);
Douglas Gregor96e578d2010-02-05 17:54:41 +000046 QualType VisitBuiltinType(BuiltinType *T);
47 QualType VisitComplexType(ComplexType *T);
48 QualType VisitPointerType(PointerType *T);
49 QualType VisitBlockPointerType(BlockPointerType *T);
50 QualType VisitLValueReferenceType(LValueReferenceType *T);
51 QualType VisitRValueReferenceType(RValueReferenceType *T);
52 QualType VisitMemberPointerType(MemberPointerType *T);
53 QualType VisitConstantArrayType(ConstantArrayType *T);
54 QualType VisitIncompleteArrayType(IncompleteArrayType *T);
55 QualType VisitVariableArrayType(VariableArrayType *T);
56 // FIXME: DependentSizedArrayType
57 // FIXME: DependentSizedExtVectorType
58 QualType VisitVectorType(VectorType *T);
59 QualType VisitExtVectorType(ExtVectorType *T);
60 QualType VisitFunctionNoProtoType(FunctionNoProtoType *T);
61 QualType VisitFunctionProtoType(FunctionProtoType *T);
62 // FIXME: UnresolvedUsingType
63 QualType VisitTypedefType(TypedefType *T);
64 QualType VisitTypeOfExprType(TypeOfExprType *T);
65 // FIXME: DependentTypeOfExprType
66 QualType VisitTypeOfType(TypeOfType *T);
67 QualType VisitDecltypeType(DecltypeType *T);
68 // FIXME: DependentDecltypeType
69 QualType VisitRecordType(RecordType *T);
70 QualType VisitEnumType(EnumType *T);
Douglas Gregor96e578d2010-02-05 17:54:41 +000071 // FIXME: TemplateTypeParmType
72 // FIXME: SubstTemplateTypeParmType
73 // FIXME: TemplateSpecializationType
Abramo Bagnara6150c882010-05-11 21:36:43 +000074 QualType VisitElaboratedType(ElaboratedType *T);
Douglas Gregorc1d2d8a2010-03-31 17:34:00 +000075 // FIXME: DependentNameType
Douglas Gregor96e578d2010-02-05 17:54:41 +000076 QualType VisitObjCInterfaceType(ObjCInterfaceType *T);
77 QualType VisitObjCObjectPointerType(ObjCObjectPointerType *T);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +000078
79 // Importing declarations
Douglas Gregorbb7930c2010-02-10 19:54:31 +000080 bool ImportDeclParts(NamedDecl *D, DeclContext *&DC,
81 DeclContext *&LexicalDC, DeclarationName &Name,
Douglas Gregorf18a2c72010-02-21 18:26:36 +000082 SourceLocation &Loc);
Douglas Gregor968d6332010-02-21 18:24:45 +000083 void ImportDeclContext(DeclContext *FromDC);
Douglas Gregor5c73e912010-02-11 00:48:18 +000084 bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord);
Douglas Gregor3996e242010-02-15 22:01:00 +000085 bool IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToRecord);
Douglas Gregore4c83e42010-02-09 22:48:33 +000086 Decl *VisitDecl(Decl *D);
Douglas Gregorf18a2c72010-02-21 18:26:36 +000087 Decl *VisitNamespaceDecl(NamespaceDecl *D);
Douglas Gregor5fa74c32010-02-10 21:10:29 +000088 Decl *VisitTypedefDecl(TypedefDecl *D);
Douglas Gregor98c10182010-02-12 22:17:39 +000089 Decl *VisitEnumDecl(EnumDecl *D);
Douglas Gregor5c73e912010-02-11 00:48:18 +000090 Decl *VisitRecordDecl(RecordDecl *D);
Douglas Gregor98c10182010-02-12 22:17:39 +000091 Decl *VisitEnumConstantDecl(EnumConstantDecl *D);
Douglas Gregorbb7930c2010-02-10 19:54:31 +000092 Decl *VisitFunctionDecl(FunctionDecl *D);
Douglas Gregor00eace12010-02-21 18:29:16 +000093 Decl *VisitCXXMethodDecl(CXXMethodDecl *D);
94 Decl *VisitCXXConstructorDecl(CXXConstructorDecl *D);
95 Decl *VisitCXXDestructorDecl(CXXDestructorDecl *D);
96 Decl *VisitCXXConversionDecl(CXXConversionDecl *D);
Douglas Gregor5c73e912010-02-11 00:48:18 +000097 Decl *VisitFieldDecl(FieldDecl *D);
Douglas Gregor7244b0b2010-02-17 00:34:30 +000098 Decl *VisitObjCIvarDecl(ObjCIvarDecl *D);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +000099 Decl *VisitVarDecl(VarDecl *D);
Douglas Gregor8b228d72010-02-17 21:22:52 +0000100 Decl *VisitImplicitParamDecl(ImplicitParamDecl *D);
Douglas Gregorbb7930c2010-02-10 19:54:31 +0000101 Decl *VisitParmVarDecl(ParmVarDecl *D);
Douglas Gregor43f54792010-02-17 02:12:47 +0000102 Decl *VisitObjCMethodDecl(ObjCMethodDecl *D);
Douglas Gregor84c51c32010-02-18 01:47:50 +0000103 Decl *VisitObjCCategoryDecl(ObjCCategoryDecl *D);
Douglas Gregor98d156a2010-02-17 16:12:00 +0000104 Decl *VisitObjCProtocolDecl(ObjCProtocolDecl *D);
Douglas Gregor45635322010-02-16 01:20:57 +0000105 Decl *VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
Douglas Gregora11c4582010-02-17 18:02:10 +0000106 Decl *VisitObjCPropertyDecl(ObjCPropertyDecl *D);
Douglas Gregor8661a722010-02-18 02:12:22 +0000107 Decl *VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D);
Douglas Gregor06537af2010-02-18 02:04:09 +0000108 Decl *VisitObjCClassDecl(ObjCClassDecl *D);
109
Douglas Gregor7eeb5972010-02-11 19:21:55 +0000110 // Importing statements
111 Stmt *VisitStmt(Stmt *S);
112
113 // Importing expressions
114 Expr *VisitExpr(Expr *E);
Douglas Gregor52f820e2010-02-19 01:17:02 +0000115 Expr *VisitDeclRefExpr(DeclRefExpr *E);
Douglas Gregor7eeb5972010-02-11 19:21:55 +0000116 Expr *VisitIntegerLiteral(IntegerLiteral *E);
Douglas Gregor623421d2010-02-18 02:21:22 +0000117 Expr *VisitCharacterLiteral(CharacterLiteral *E);
Douglas Gregorc74247e2010-02-19 01:07:06 +0000118 Expr *VisitParenExpr(ParenExpr *E);
119 Expr *VisitUnaryOperator(UnaryOperator *E);
Douglas Gregord8552cd2010-02-19 01:24:23 +0000120 Expr *VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E);
Douglas Gregorc74247e2010-02-19 01:07:06 +0000121 Expr *VisitBinaryOperator(BinaryOperator *E);
122 Expr *VisitCompoundAssignOperator(CompoundAssignOperator *E);
Douglas Gregor98c10182010-02-12 22:17:39 +0000123 Expr *VisitImplicitCastExpr(ImplicitCastExpr *E);
Douglas Gregor5481d322010-02-19 01:32:14 +0000124 Expr *VisitCStyleCastExpr(CStyleCastExpr *E);
Douglas Gregor96e578d2010-02-05 17:54:41 +0000125 };
126}
127
128//----------------------------------------------------------------------------
Douglas Gregor3996e242010-02-15 22:01:00 +0000129// Structural Equivalence
130//----------------------------------------------------------------------------
131
132namespace {
133 struct StructuralEquivalenceContext {
134 /// \brief AST contexts for which we are checking structural equivalence.
135 ASTContext &C1, &C2;
136
137 /// \brief Diagnostic object used to emit diagnostics.
138 Diagnostic &Diags;
139
140 /// \brief The set of "tentative" equivalences between two canonical
141 /// declarations, mapping from a declaration in the first context to the
142 /// declaration in the second context that we believe to be equivalent.
143 llvm::DenseMap<Decl *, Decl *> TentativeEquivalences;
144
145 /// \brief Queue of declarations in the first context whose equivalence
146 /// with a declaration in the second context still needs to be verified.
147 std::deque<Decl *> DeclsToCheck;
148
Douglas Gregorb4964f72010-02-15 23:54:17 +0000149 /// \brief Declaration (from, to) pairs that are known not to be equivalent
150 /// (which we have already complained about).
151 llvm::DenseSet<std::pair<Decl *, Decl *> > &NonEquivalentDecls;
152
Douglas Gregor3996e242010-02-15 22:01:00 +0000153 /// \brief Whether we're being strict about the spelling of types when
154 /// unifying two types.
155 bool StrictTypeSpelling;
156
157 StructuralEquivalenceContext(ASTContext &C1, ASTContext &C2,
158 Diagnostic &Diags,
Douglas Gregorb4964f72010-02-15 23:54:17 +0000159 llvm::DenseSet<std::pair<Decl *, Decl *> > &NonEquivalentDecls,
Douglas Gregor3996e242010-02-15 22:01:00 +0000160 bool StrictTypeSpelling = false)
Douglas Gregorb4964f72010-02-15 23:54:17 +0000161 : C1(C1), C2(C2), Diags(Diags), NonEquivalentDecls(NonEquivalentDecls),
162 StrictTypeSpelling(StrictTypeSpelling) { }
Douglas Gregor3996e242010-02-15 22:01:00 +0000163
164 /// \brief Determine whether the two declarations are structurally
165 /// equivalent.
166 bool IsStructurallyEquivalent(Decl *D1, Decl *D2);
167
168 /// \brief Determine whether the two types are structurally equivalent.
169 bool IsStructurallyEquivalent(QualType T1, QualType T2);
170
171 private:
172 /// \brief Finish checking all of the structural equivalences.
173 ///
174 /// \returns true if an error occurred, false otherwise.
175 bool Finish();
176
177 public:
178 DiagnosticBuilder Diag1(SourceLocation Loc, unsigned DiagID) {
179 return Diags.Report(FullSourceLoc(Loc, C1.getSourceManager()), DiagID);
180 }
181
182 DiagnosticBuilder Diag2(SourceLocation Loc, unsigned DiagID) {
183 return Diags.Report(FullSourceLoc(Loc, C2.getSourceManager()), DiagID);
184 }
185 };
186}
187
188static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
189 QualType T1, QualType T2);
190static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
191 Decl *D1, Decl *D2);
192
193/// \brief Determine if two APInts have the same value, after zero-extending
194/// one of them (if needed!) to ensure that the bit-widths match.
195static bool IsSameValue(const llvm::APInt &I1, const llvm::APInt &I2) {
196 if (I1.getBitWidth() == I2.getBitWidth())
197 return I1 == I2;
198
199 if (I1.getBitWidth() > I2.getBitWidth())
200 return I1 == llvm::APInt(I2).zext(I1.getBitWidth());
201
202 return llvm::APInt(I1).zext(I2.getBitWidth()) == I2;
203}
204
205/// \brief Determine if two APSInts have the same value, zero- or sign-extending
206/// as needed.
207static bool IsSameValue(const llvm::APSInt &I1, const llvm::APSInt &I2) {
208 if (I1.getBitWidth() == I2.getBitWidth() && I1.isSigned() == I2.isSigned())
209 return I1 == I2;
210
211 // Check for a bit-width mismatch.
212 if (I1.getBitWidth() > I2.getBitWidth())
213 return IsSameValue(I1, llvm::APSInt(I2).extend(I1.getBitWidth()));
214 else if (I2.getBitWidth() > I1.getBitWidth())
215 return IsSameValue(llvm::APSInt(I1).extend(I2.getBitWidth()), I2);
216
217 // We have a signedness mismatch. Turn the signed value into an unsigned
218 // value.
219 if (I1.isSigned()) {
220 if (I1.isNegative())
221 return false;
222
223 return llvm::APSInt(I1, true) == I2;
224 }
225
226 if (I2.isNegative())
227 return false;
228
229 return I1 == llvm::APSInt(I2, true);
230}
231
232/// \brief Determine structural equivalence of two expressions.
233static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
234 Expr *E1, Expr *E2) {
235 if (!E1 || !E2)
236 return E1 == E2;
237
238 // FIXME: Actually perform a structural comparison!
239 return true;
240}
241
242/// \brief Determine whether two identifiers are equivalent.
243static bool IsStructurallyEquivalent(const IdentifierInfo *Name1,
244 const IdentifierInfo *Name2) {
245 if (!Name1 || !Name2)
246 return Name1 == Name2;
247
248 return Name1->getName() == Name2->getName();
249}
250
251/// \brief Determine whether two nested-name-specifiers are equivalent.
252static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
253 NestedNameSpecifier *NNS1,
254 NestedNameSpecifier *NNS2) {
255 // FIXME: Implement!
256 return true;
257}
258
259/// \brief Determine whether two template arguments are equivalent.
260static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
261 const TemplateArgument &Arg1,
262 const TemplateArgument &Arg2) {
263 // FIXME: Implement!
264 return true;
265}
266
267/// \brief Determine structural equivalence for the common part of array
268/// types.
269static bool IsArrayStructurallyEquivalent(StructuralEquivalenceContext &Context,
270 const ArrayType *Array1,
271 const ArrayType *Array2) {
272 if (!IsStructurallyEquivalent(Context,
273 Array1->getElementType(),
274 Array2->getElementType()))
275 return false;
276 if (Array1->getSizeModifier() != Array2->getSizeModifier())
277 return false;
278 if (Array1->getIndexTypeQualifiers() != Array2->getIndexTypeQualifiers())
279 return false;
280
281 return true;
282}
283
284/// \brief Determine structural equivalence of two types.
285static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
286 QualType T1, QualType T2) {
287 if (T1.isNull() || T2.isNull())
288 return T1.isNull() && T2.isNull();
289
290 if (!Context.StrictTypeSpelling) {
291 // We aren't being strict about token-to-token equivalence of types,
292 // so map down to the canonical type.
293 T1 = Context.C1.getCanonicalType(T1);
294 T2 = Context.C2.getCanonicalType(T2);
295 }
296
297 if (T1.getQualifiers() != T2.getQualifiers())
298 return false;
299
Douglas Gregorb4964f72010-02-15 23:54:17 +0000300 Type::TypeClass TC = T1->getTypeClass();
Douglas Gregor3996e242010-02-15 22:01:00 +0000301
Douglas Gregorb4964f72010-02-15 23:54:17 +0000302 if (T1->getTypeClass() != T2->getTypeClass()) {
303 // Compare function types with prototypes vs. without prototypes as if
304 // both did not have prototypes.
305 if (T1->getTypeClass() == Type::FunctionProto &&
306 T2->getTypeClass() == Type::FunctionNoProto)
307 TC = Type::FunctionNoProto;
308 else if (T1->getTypeClass() == Type::FunctionNoProto &&
309 T2->getTypeClass() == Type::FunctionProto)
310 TC = Type::FunctionNoProto;
311 else
312 return false;
313 }
314
315 switch (TC) {
316 case Type::Builtin:
Douglas Gregor3996e242010-02-15 22:01:00 +0000317 // FIXME: Deal with Char_S/Char_U.
318 if (cast<BuiltinType>(T1)->getKind() != cast<BuiltinType>(T2)->getKind())
319 return false;
320 break;
321
322 case Type::Complex:
323 if (!IsStructurallyEquivalent(Context,
324 cast<ComplexType>(T1)->getElementType(),
325 cast<ComplexType>(T2)->getElementType()))
326 return false;
327 break;
328
329 case Type::Pointer:
330 if (!IsStructurallyEquivalent(Context,
331 cast<PointerType>(T1)->getPointeeType(),
332 cast<PointerType>(T2)->getPointeeType()))
333 return false;
334 break;
335
336 case Type::BlockPointer:
337 if (!IsStructurallyEquivalent(Context,
338 cast<BlockPointerType>(T1)->getPointeeType(),
339 cast<BlockPointerType>(T2)->getPointeeType()))
340 return false;
341 break;
342
343 case Type::LValueReference:
344 case Type::RValueReference: {
345 const ReferenceType *Ref1 = cast<ReferenceType>(T1);
346 const ReferenceType *Ref2 = cast<ReferenceType>(T2);
347 if (Ref1->isSpelledAsLValue() != Ref2->isSpelledAsLValue())
348 return false;
349 if (Ref1->isInnerRef() != Ref2->isInnerRef())
350 return false;
351 if (!IsStructurallyEquivalent(Context,
352 Ref1->getPointeeTypeAsWritten(),
353 Ref2->getPointeeTypeAsWritten()))
354 return false;
355 break;
356 }
357
358 case Type::MemberPointer: {
359 const MemberPointerType *MemPtr1 = cast<MemberPointerType>(T1);
360 const MemberPointerType *MemPtr2 = cast<MemberPointerType>(T2);
361 if (!IsStructurallyEquivalent(Context,
362 MemPtr1->getPointeeType(),
363 MemPtr2->getPointeeType()))
364 return false;
365 if (!IsStructurallyEquivalent(Context,
366 QualType(MemPtr1->getClass(), 0),
367 QualType(MemPtr2->getClass(), 0)))
368 return false;
369 break;
370 }
371
372 case Type::ConstantArray: {
373 const ConstantArrayType *Array1 = cast<ConstantArrayType>(T1);
374 const ConstantArrayType *Array2 = cast<ConstantArrayType>(T2);
375 if (!IsSameValue(Array1->getSize(), Array2->getSize()))
376 return false;
377
378 if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
379 return false;
380 break;
381 }
382
383 case Type::IncompleteArray:
384 if (!IsArrayStructurallyEquivalent(Context,
385 cast<ArrayType>(T1),
386 cast<ArrayType>(T2)))
387 return false;
388 break;
389
390 case Type::VariableArray: {
391 const VariableArrayType *Array1 = cast<VariableArrayType>(T1);
392 const VariableArrayType *Array2 = cast<VariableArrayType>(T2);
393 if (!IsStructurallyEquivalent(Context,
394 Array1->getSizeExpr(), Array2->getSizeExpr()))
395 return false;
396
397 if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
398 return false;
399
400 break;
401 }
402
403 case Type::DependentSizedArray: {
404 const DependentSizedArrayType *Array1 = cast<DependentSizedArrayType>(T1);
405 const DependentSizedArrayType *Array2 = cast<DependentSizedArrayType>(T2);
406 if (!IsStructurallyEquivalent(Context,
407 Array1->getSizeExpr(), Array2->getSizeExpr()))
408 return false;
409
410 if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
411 return false;
412
413 break;
414 }
415
416 case Type::DependentSizedExtVector: {
417 const DependentSizedExtVectorType *Vec1
418 = cast<DependentSizedExtVectorType>(T1);
419 const DependentSizedExtVectorType *Vec2
420 = cast<DependentSizedExtVectorType>(T2);
421 if (!IsStructurallyEquivalent(Context,
422 Vec1->getSizeExpr(), Vec2->getSizeExpr()))
423 return false;
424 if (!IsStructurallyEquivalent(Context,
425 Vec1->getElementType(),
426 Vec2->getElementType()))
427 return false;
428 break;
429 }
430
431 case Type::Vector:
432 case Type::ExtVector: {
433 const VectorType *Vec1 = cast<VectorType>(T1);
434 const VectorType *Vec2 = cast<VectorType>(T2);
435 if (!IsStructurallyEquivalent(Context,
436 Vec1->getElementType(),
437 Vec2->getElementType()))
438 return false;
439 if (Vec1->getNumElements() != Vec2->getNumElements())
440 return false;
441 if (Vec1->isAltiVec() != Vec2->isAltiVec())
442 return false;
443 if (Vec1->isPixel() != Vec2->isPixel())
444 return false;
Douglas Gregor01cc4372010-02-19 01:36:36 +0000445 break;
Douglas Gregor3996e242010-02-15 22:01:00 +0000446 }
447
448 case Type::FunctionProto: {
449 const FunctionProtoType *Proto1 = cast<FunctionProtoType>(T1);
450 const FunctionProtoType *Proto2 = cast<FunctionProtoType>(T2);
451 if (Proto1->getNumArgs() != Proto2->getNumArgs())
452 return false;
453 for (unsigned I = 0, N = Proto1->getNumArgs(); I != N; ++I) {
454 if (!IsStructurallyEquivalent(Context,
455 Proto1->getArgType(I),
456 Proto2->getArgType(I)))
457 return false;
458 }
459 if (Proto1->isVariadic() != Proto2->isVariadic())
460 return false;
461 if (Proto1->hasExceptionSpec() != Proto2->hasExceptionSpec())
462 return false;
463 if (Proto1->hasAnyExceptionSpec() != Proto2->hasAnyExceptionSpec())
464 return false;
465 if (Proto1->getNumExceptions() != Proto2->getNumExceptions())
466 return false;
467 for (unsigned I = 0, N = Proto1->getNumExceptions(); I != N; ++I) {
468 if (!IsStructurallyEquivalent(Context,
469 Proto1->getExceptionType(I),
470 Proto2->getExceptionType(I)))
471 return false;
472 }
473 if (Proto1->getTypeQuals() != Proto2->getTypeQuals())
474 return false;
475
476 // Fall through to check the bits common with FunctionNoProtoType.
477 }
478
479 case Type::FunctionNoProto: {
480 const FunctionType *Function1 = cast<FunctionType>(T1);
481 const FunctionType *Function2 = cast<FunctionType>(T2);
482 if (!IsStructurallyEquivalent(Context,
483 Function1->getResultType(),
484 Function2->getResultType()))
485 return false;
Rafael Espindolac50c27c2010-03-30 20:24:48 +0000486 if (Function1->getExtInfo() != Function2->getExtInfo())
487 return false;
Douglas Gregor3996e242010-02-15 22:01:00 +0000488 break;
489 }
490
491 case Type::UnresolvedUsing:
492 if (!IsStructurallyEquivalent(Context,
493 cast<UnresolvedUsingType>(T1)->getDecl(),
494 cast<UnresolvedUsingType>(T2)->getDecl()))
495 return false;
496
497 break;
498
499 case Type::Typedef:
500 if (!IsStructurallyEquivalent(Context,
501 cast<TypedefType>(T1)->getDecl(),
502 cast<TypedefType>(T2)->getDecl()))
503 return false;
504 break;
505
506 case Type::TypeOfExpr:
507 if (!IsStructurallyEquivalent(Context,
508 cast<TypeOfExprType>(T1)->getUnderlyingExpr(),
509 cast<TypeOfExprType>(T2)->getUnderlyingExpr()))
510 return false;
511 break;
512
513 case Type::TypeOf:
514 if (!IsStructurallyEquivalent(Context,
515 cast<TypeOfType>(T1)->getUnderlyingType(),
516 cast<TypeOfType>(T2)->getUnderlyingType()))
517 return false;
518 break;
519
520 case Type::Decltype:
521 if (!IsStructurallyEquivalent(Context,
522 cast<DecltypeType>(T1)->getUnderlyingExpr(),
523 cast<DecltypeType>(T2)->getUnderlyingExpr()))
524 return false;
525 break;
526
527 case Type::Record:
528 case Type::Enum:
529 if (!IsStructurallyEquivalent(Context,
530 cast<TagType>(T1)->getDecl(),
531 cast<TagType>(T2)->getDecl()))
532 return false;
533 break;
Abramo Bagnara6150c882010-05-11 21:36:43 +0000534
Douglas Gregor3996e242010-02-15 22:01:00 +0000535 case Type::TemplateTypeParm: {
536 const TemplateTypeParmType *Parm1 = cast<TemplateTypeParmType>(T1);
537 const TemplateTypeParmType *Parm2 = cast<TemplateTypeParmType>(T2);
538 if (Parm1->getDepth() != Parm2->getDepth())
539 return false;
540 if (Parm1->getIndex() != Parm2->getIndex())
541 return false;
542 if (Parm1->isParameterPack() != Parm2->isParameterPack())
543 return false;
544
545 // Names of template type parameters are never significant.
546 break;
547 }
548
549 case Type::SubstTemplateTypeParm: {
550 const SubstTemplateTypeParmType *Subst1
551 = cast<SubstTemplateTypeParmType>(T1);
552 const SubstTemplateTypeParmType *Subst2
553 = cast<SubstTemplateTypeParmType>(T2);
554 if (!IsStructurallyEquivalent(Context,
555 QualType(Subst1->getReplacedParameter(), 0),
556 QualType(Subst2->getReplacedParameter(), 0)))
557 return false;
558 if (!IsStructurallyEquivalent(Context,
559 Subst1->getReplacementType(),
560 Subst2->getReplacementType()))
561 return false;
562 break;
563 }
564
565 case Type::TemplateSpecialization: {
566 const TemplateSpecializationType *Spec1
567 = cast<TemplateSpecializationType>(T1);
568 const TemplateSpecializationType *Spec2
569 = cast<TemplateSpecializationType>(T2);
570 if (!IsStructurallyEquivalent(Context,
571 Spec1->getTemplateName(),
572 Spec2->getTemplateName()))
573 return false;
574 if (Spec1->getNumArgs() != Spec2->getNumArgs())
575 return false;
576 for (unsigned I = 0, N = Spec1->getNumArgs(); I != N; ++I) {
577 if (!IsStructurallyEquivalent(Context,
578 Spec1->getArg(I), Spec2->getArg(I)))
579 return false;
580 }
581 break;
582 }
583
Abramo Bagnara6150c882010-05-11 21:36:43 +0000584 case Type::Elaborated: {
585 const ElaboratedType *Elab1 = cast<ElaboratedType>(T1);
586 const ElaboratedType *Elab2 = cast<ElaboratedType>(T2);
587 // CHECKME: what if a keyword is ETK_None or ETK_typename ?
588 if (Elab1->getKeyword() != Elab2->getKeyword())
589 return false;
Douglas Gregor3996e242010-02-15 22:01:00 +0000590 if (!IsStructurallyEquivalent(Context,
Abramo Bagnara6150c882010-05-11 21:36:43 +0000591 Elab1->getQualifier(),
592 Elab2->getQualifier()))
Douglas Gregor3996e242010-02-15 22:01:00 +0000593 return false;
594 if (!IsStructurallyEquivalent(Context,
Abramo Bagnara6150c882010-05-11 21:36:43 +0000595 Elab1->getNamedType(),
596 Elab2->getNamedType()))
Douglas Gregor3996e242010-02-15 22:01:00 +0000597 return false;
598 break;
599 }
600
John McCalle78aac42010-03-10 03:28:59 +0000601 case Type::InjectedClassName: {
602 const InjectedClassNameType *Inj1 = cast<InjectedClassNameType>(T1);
603 const InjectedClassNameType *Inj2 = cast<InjectedClassNameType>(T2);
604 if (!IsStructurallyEquivalent(Context,
John McCall2408e322010-04-27 00:57:59 +0000605 Inj1->getInjectedSpecializationType(),
606 Inj2->getInjectedSpecializationType()))
John McCalle78aac42010-03-10 03:28:59 +0000607 return false;
608 break;
609 }
610
Douglas Gregorc1d2d8a2010-03-31 17:34:00 +0000611 case Type::DependentName: {
612 const DependentNameType *Typename1 = cast<DependentNameType>(T1);
613 const DependentNameType *Typename2 = cast<DependentNameType>(T2);
Douglas Gregor3996e242010-02-15 22:01:00 +0000614 if (!IsStructurallyEquivalent(Context,
615 Typename1->getQualifier(),
616 Typename2->getQualifier()))
617 return false;
618 if (!IsStructurallyEquivalent(Typename1->getIdentifier(),
619 Typename2->getIdentifier()))
620 return false;
621 if (!IsStructurallyEquivalent(Context,
622 QualType(Typename1->getTemplateId(), 0),
623 QualType(Typename2->getTemplateId(), 0)))
624 return false;
625
626 break;
627 }
628
629 case Type::ObjCInterface: {
630 const ObjCInterfaceType *Iface1 = cast<ObjCInterfaceType>(T1);
631 const ObjCInterfaceType *Iface2 = cast<ObjCInterfaceType>(T2);
632 if (!IsStructurallyEquivalent(Context,
633 Iface1->getDecl(), Iface2->getDecl()))
634 return false;
635 if (Iface1->getNumProtocols() != Iface2->getNumProtocols())
636 return false;
637 for (unsigned I = 0, N = Iface1->getNumProtocols(); I != N; ++I) {
638 if (!IsStructurallyEquivalent(Context,
639 Iface1->getProtocol(I),
640 Iface2->getProtocol(I)))
641 return false;
642 }
643 break;
644 }
645
646 case Type::ObjCObjectPointer: {
647 const ObjCObjectPointerType *Ptr1 = cast<ObjCObjectPointerType>(T1);
648 const ObjCObjectPointerType *Ptr2 = cast<ObjCObjectPointerType>(T2);
649 if (!IsStructurallyEquivalent(Context,
650 Ptr1->getPointeeType(),
651 Ptr2->getPointeeType()))
652 return false;
653 if (Ptr1->getNumProtocols() != Ptr2->getNumProtocols())
654 return false;
655 for (unsigned I = 0, N = Ptr1->getNumProtocols(); I != N; ++I) {
656 if (!IsStructurallyEquivalent(Context,
657 Ptr1->getProtocol(I),
658 Ptr2->getProtocol(I)))
659 return false;
660 }
661 break;
662 }
663
664 } // end switch
665
666 return true;
667}
668
669/// \brief Determine structural equivalence of two records.
670static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
671 RecordDecl *D1, RecordDecl *D2) {
672 if (D1->isUnion() != D2->isUnion()) {
673 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
674 << Context.C2.getTypeDeclType(D2);
675 Context.Diag1(D1->getLocation(), diag::note_odr_tag_kind_here)
676 << D1->getDeclName() << (unsigned)D1->getTagKind();
677 return false;
678 }
679
Douglas Gregorb4964f72010-02-15 23:54:17 +0000680 // Compare the definitions of these two records. If either or both are
681 // incomplete, we assume that they are equivalent.
682 D1 = D1->getDefinition();
683 D2 = D2->getDefinition();
684 if (!D1 || !D2)
685 return true;
686
Douglas Gregor3996e242010-02-15 22:01:00 +0000687 if (CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(D1)) {
688 if (CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(D2)) {
689 if (D1CXX->getNumBases() != D2CXX->getNumBases()) {
690 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
691 << Context.C2.getTypeDeclType(D2);
692 Context.Diag2(D2->getLocation(), diag::note_odr_number_of_bases)
693 << D2CXX->getNumBases();
694 Context.Diag1(D1->getLocation(), diag::note_odr_number_of_bases)
695 << D1CXX->getNumBases();
696 return false;
697 }
698
699 // Check the base classes.
700 for (CXXRecordDecl::base_class_iterator Base1 = D1CXX->bases_begin(),
701 BaseEnd1 = D1CXX->bases_end(),
702 Base2 = D2CXX->bases_begin();
703 Base1 != BaseEnd1;
704 ++Base1, ++Base2) {
705 if (!IsStructurallyEquivalent(Context,
706 Base1->getType(), Base2->getType())) {
707 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
708 << Context.C2.getTypeDeclType(D2);
709 Context.Diag2(Base2->getSourceRange().getBegin(), diag::note_odr_base)
710 << Base2->getType()
711 << Base2->getSourceRange();
712 Context.Diag1(Base1->getSourceRange().getBegin(), diag::note_odr_base)
713 << Base1->getType()
714 << Base1->getSourceRange();
715 return false;
716 }
717
718 // Check virtual vs. non-virtual inheritance mismatch.
719 if (Base1->isVirtual() != Base2->isVirtual()) {
720 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
721 << Context.C2.getTypeDeclType(D2);
722 Context.Diag2(Base2->getSourceRange().getBegin(),
723 diag::note_odr_virtual_base)
724 << Base2->isVirtual() << Base2->getSourceRange();
725 Context.Diag1(Base1->getSourceRange().getBegin(), diag::note_odr_base)
726 << Base1->isVirtual()
727 << Base1->getSourceRange();
728 return false;
729 }
730 }
731 } else if (D1CXX->getNumBases() > 0) {
732 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
733 << Context.C2.getTypeDeclType(D2);
734 const CXXBaseSpecifier *Base1 = D1CXX->bases_begin();
735 Context.Diag1(Base1->getSourceRange().getBegin(), diag::note_odr_base)
736 << Base1->getType()
737 << Base1->getSourceRange();
738 Context.Diag2(D2->getLocation(), diag::note_odr_missing_base);
739 return false;
740 }
741 }
742
743 // Check the fields for consistency.
744 CXXRecordDecl::field_iterator Field2 = D2->field_begin(),
745 Field2End = D2->field_end();
746 for (CXXRecordDecl::field_iterator Field1 = D1->field_begin(),
747 Field1End = D1->field_end();
748 Field1 != Field1End;
749 ++Field1, ++Field2) {
750 if (Field2 == Field2End) {
751 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
752 << Context.C2.getTypeDeclType(D2);
753 Context.Diag1(Field1->getLocation(), diag::note_odr_field)
754 << Field1->getDeclName() << Field1->getType();
755 Context.Diag2(D2->getLocation(), diag::note_odr_missing_field);
756 return false;
757 }
758
759 if (!IsStructurallyEquivalent(Context,
760 Field1->getType(), Field2->getType())) {
761 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
762 << Context.C2.getTypeDeclType(D2);
763 Context.Diag2(Field2->getLocation(), diag::note_odr_field)
764 << Field2->getDeclName() << Field2->getType();
765 Context.Diag1(Field1->getLocation(), diag::note_odr_field)
766 << Field1->getDeclName() << Field1->getType();
767 return false;
768 }
769
770 if (Field1->isBitField() != Field2->isBitField()) {
771 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
772 << Context.C2.getTypeDeclType(D2);
773 if (Field1->isBitField()) {
774 llvm::APSInt Bits;
775 Field1->getBitWidth()->isIntegerConstantExpr(Bits, Context.C1);
776 Context.Diag1(Field1->getLocation(), diag::note_odr_bit_field)
777 << Field1->getDeclName() << Field1->getType()
778 << Bits.toString(10, false);
779 Context.Diag2(Field2->getLocation(), diag::note_odr_not_bit_field)
780 << Field2->getDeclName();
781 } else {
782 llvm::APSInt Bits;
783 Field2->getBitWidth()->isIntegerConstantExpr(Bits, Context.C2);
784 Context.Diag2(Field2->getLocation(), diag::note_odr_bit_field)
785 << Field2->getDeclName() << Field2->getType()
786 << Bits.toString(10, false);
787 Context.Diag1(Field1->getLocation(),
788 diag::note_odr_not_bit_field)
789 << Field1->getDeclName();
790 }
791 return false;
792 }
793
794 if (Field1->isBitField()) {
795 // Make sure that the bit-fields are the same length.
796 llvm::APSInt Bits1, Bits2;
797 if (!Field1->getBitWidth()->isIntegerConstantExpr(Bits1, Context.C1))
798 return false;
799 if (!Field2->getBitWidth()->isIntegerConstantExpr(Bits2, Context.C2))
800 return false;
801
802 if (!IsSameValue(Bits1, Bits2)) {
803 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
804 << Context.C2.getTypeDeclType(D2);
805 Context.Diag2(Field2->getLocation(), diag::note_odr_bit_field)
806 << Field2->getDeclName() << Field2->getType()
807 << Bits2.toString(10, false);
808 Context.Diag1(Field1->getLocation(), diag::note_odr_bit_field)
809 << Field1->getDeclName() << Field1->getType()
810 << Bits1.toString(10, false);
811 return false;
812 }
813 }
814 }
815
816 if (Field2 != Field2End) {
817 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
818 << Context.C2.getTypeDeclType(D2);
819 Context.Diag2(Field2->getLocation(), diag::note_odr_field)
820 << Field2->getDeclName() << Field2->getType();
821 Context.Diag1(D1->getLocation(), diag::note_odr_missing_field);
822 return false;
823 }
824
825 return true;
826}
827
828/// \brief Determine structural equivalence of two enums.
829static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
830 EnumDecl *D1, EnumDecl *D2) {
831 EnumDecl::enumerator_iterator EC2 = D2->enumerator_begin(),
832 EC2End = D2->enumerator_end();
833 for (EnumDecl::enumerator_iterator EC1 = D1->enumerator_begin(),
834 EC1End = D1->enumerator_end();
835 EC1 != EC1End; ++EC1, ++EC2) {
836 if (EC2 == EC2End) {
837 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
838 << Context.C2.getTypeDeclType(D2);
839 Context.Diag1(EC1->getLocation(), diag::note_odr_enumerator)
840 << EC1->getDeclName()
841 << EC1->getInitVal().toString(10);
842 Context.Diag2(D2->getLocation(), diag::note_odr_missing_enumerator);
843 return false;
844 }
845
846 llvm::APSInt Val1 = EC1->getInitVal();
847 llvm::APSInt Val2 = EC2->getInitVal();
848 if (!IsSameValue(Val1, Val2) ||
849 !IsStructurallyEquivalent(EC1->getIdentifier(), EC2->getIdentifier())) {
850 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
851 << Context.C2.getTypeDeclType(D2);
852 Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
853 << EC2->getDeclName()
854 << EC2->getInitVal().toString(10);
855 Context.Diag1(EC1->getLocation(), diag::note_odr_enumerator)
856 << EC1->getDeclName()
857 << EC1->getInitVal().toString(10);
858 return false;
859 }
860 }
861
862 if (EC2 != EC2End) {
863 Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
864 << Context.C2.getTypeDeclType(D2);
865 Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
866 << EC2->getDeclName()
867 << EC2->getInitVal().toString(10);
868 Context.Diag1(D1->getLocation(), diag::note_odr_missing_enumerator);
869 return false;
870 }
871
872 return true;
873}
874
875/// \brief Determine structural equivalence of two declarations.
876static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
877 Decl *D1, Decl *D2) {
878 // FIXME: Check for known structural equivalences via a callback of some sort.
879
Douglas Gregorb4964f72010-02-15 23:54:17 +0000880 // Check whether we already know that these two declarations are not
881 // structurally equivalent.
882 if (Context.NonEquivalentDecls.count(std::make_pair(D1->getCanonicalDecl(),
883 D2->getCanonicalDecl())))
884 return false;
885
Douglas Gregor3996e242010-02-15 22:01:00 +0000886 // Determine whether we've already produced a tentative equivalence for D1.
887 Decl *&EquivToD1 = Context.TentativeEquivalences[D1->getCanonicalDecl()];
888 if (EquivToD1)
889 return EquivToD1 == D2->getCanonicalDecl();
890
891 // Produce a tentative equivalence D1 <-> D2, which will be checked later.
892 EquivToD1 = D2->getCanonicalDecl();
893 Context.DeclsToCheck.push_back(D1->getCanonicalDecl());
894 return true;
895}
896
897bool StructuralEquivalenceContext::IsStructurallyEquivalent(Decl *D1,
898 Decl *D2) {
899 if (!::IsStructurallyEquivalent(*this, D1, D2))
900 return false;
901
902 return !Finish();
903}
904
905bool StructuralEquivalenceContext::IsStructurallyEquivalent(QualType T1,
906 QualType T2) {
907 if (!::IsStructurallyEquivalent(*this, T1, T2))
908 return false;
909
910 return !Finish();
911}
912
913bool StructuralEquivalenceContext::Finish() {
914 while (!DeclsToCheck.empty()) {
915 // Check the next declaration.
916 Decl *D1 = DeclsToCheck.front();
917 DeclsToCheck.pop_front();
918
919 Decl *D2 = TentativeEquivalences[D1];
920 assert(D2 && "Unrecorded tentative equivalence?");
921
Douglas Gregorb4964f72010-02-15 23:54:17 +0000922 bool Equivalent = true;
923
Douglas Gregor3996e242010-02-15 22:01:00 +0000924 // FIXME: Switch on all declaration kinds. For now, we're just going to
925 // check the obvious ones.
926 if (RecordDecl *Record1 = dyn_cast<RecordDecl>(D1)) {
927 if (RecordDecl *Record2 = dyn_cast<RecordDecl>(D2)) {
928 // Check for equivalent structure names.
929 IdentifierInfo *Name1 = Record1->getIdentifier();
930 if (!Name1 && Record1->getTypedefForAnonDecl())
931 Name1 = Record1->getTypedefForAnonDecl()->getIdentifier();
932 IdentifierInfo *Name2 = Record2->getIdentifier();
933 if (!Name2 && Record2->getTypedefForAnonDecl())
934 Name2 = Record2->getTypedefForAnonDecl()->getIdentifier();
Douglas Gregorb4964f72010-02-15 23:54:17 +0000935 if (!::IsStructurallyEquivalent(Name1, Name2) ||
936 !::IsStructurallyEquivalent(*this, Record1, Record2))
937 Equivalent = false;
Douglas Gregor3996e242010-02-15 22:01:00 +0000938 } else {
939 // Record/non-record mismatch.
Douglas Gregorb4964f72010-02-15 23:54:17 +0000940 Equivalent = false;
Douglas Gregor3996e242010-02-15 22:01:00 +0000941 }
Douglas Gregorb4964f72010-02-15 23:54:17 +0000942 } else if (EnumDecl *Enum1 = dyn_cast<EnumDecl>(D1)) {
Douglas Gregor3996e242010-02-15 22:01:00 +0000943 if (EnumDecl *Enum2 = dyn_cast<EnumDecl>(D2)) {
944 // Check for equivalent enum names.
945 IdentifierInfo *Name1 = Enum1->getIdentifier();
946 if (!Name1 && Enum1->getTypedefForAnonDecl())
947 Name1 = Enum1->getTypedefForAnonDecl()->getIdentifier();
948 IdentifierInfo *Name2 = Enum2->getIdentifier();
949 if (!Name2 && Enum2->getTypedefForAnonDecl())
950 Name2 = Enum2->getTypedefForAnonDecl()->getIdentifier();
Douglas Gregorb4964f72010-02-15 23:54:17 +0000951 if (!::IsStructurallyEquivalent(Name1, Name2) ||
952 !::IsStructurallyEquivalent(*this, Enum1, Enum2))
953 Equivalent = false;
Douglas Gregor3996e242010-02-15 22:01:00 +0000954 } else {
955 // Enum/non-enum mismatch
Douglas Gregorb4964f72010-02-15 23:54:17 +0000956 Equivalent = false;
Douglas Gregor3996e242010-02-15 22:01:00 +0000957 }
Douglas Gregorb4964f72010-02-15 23:54:17 +0000958 } else if (TypedefDecl *Typedef1 = dyn_cast<TypedefDecl>(D1)) {
Douglas Gregor3996e242010-02-15 22:01:00 +0000959 if (TypedefDecl *Typedef2 = dyn_cast<TypedefDecl>(D2)) {
960 if (!::IsStructurallyEquivalent(Typedef1->getIdentifier(),
Douglas Gregorb4964f72010-02-15 23:54:17 +0000961 Typedef2->getIdentifier()) ||
962 !::IsStructurallyEquivalent(*this,
Douglas Gregor3996e242010-02-15 22:01:00 +0000963 Typedef1->getUnderlyingType(),
964 Typedef2->getUnderlyingType()))
Douglas Gregorb4964f72010-02-15 23:54:17 +0000965 Equivalent = false;
Douglas Gregor3996e242010-02-15 22:01:00 +0000966 } else {
967 // Typedef/non-typedef mismatch.
Douglas Gregorb4964f72010-02-15 23:54:17 +0000968 Equivalent = false;
Douglas Gregor3996e242010-02-15 22:01:00 +0000969 }
Douglas Gregor3996e242010-02-15 22:01:00 +0000970 }
Douglas Gregorb4964f72010-02-15 23:54:17 +0000971
972 if (!Equivalent) {
973 // Note that these two declarations are not equivalent (and we already
974 // know about it).
975 NonEquivalentDecls.insert(std::make_pair(D1->getCanonicalDecl(),
976 D2->getCanonicalDecl()));
977 return true;
978 }
Douglas Gregor3996e242010-02-15 22:01:00 +0000979 // FIXME: Check other declaration kinds!
980 }
981
982 return false;
983}
984
985//----------------------------------------------------------------------------
Douglas Gregor96e578d2010-02-05 17:54:41 +0000986// Import Types
987//----------------------------------------------------------------------------
988
Douglas Gregore4c83e42010-02-09 22:48:33 +0000989QualType ASTNodeImporter::VisitType(Type *T) {
990 Importer.FromDiag(SourceLocation(), diag::err_unsupported_ast_node)
991 << T->getTypeClassName();
992 return QualType();
993}
994
Douglas Gregor96e578d2010-02-05 17:54:41 +0000995QualType ASTNodeImporter::VisitBuiltinType(BuiltinType *T) {
996 switch (T->getKind()) {
997 case BuiltinType::Void: return Importer.getToContext().VoidTy;
998 case BuiltinType::Bool: return Importer.getToContext().BoolTy;
999
1000 case BuiltinType::Char_U:
1001 // The context we're importing from has an unsigned 'char'. If we're
1002 // importing into a context with a signed 'char', translate to
1003 // 'unsigned char' instead.
1004 if (Importer.getToContext().getLangOptions().CharIsSigned)
1005 return Importer.getToContext().UnsignedCharTy;
1006
1007 return Importer.getToContext().CharTy;
1008
1009 case BuiltinType::UChar: return Importer.getToContext().UnsignedCharTy;
1010
1011 case BuiltinType::Char16:
1012 // FIXME: Make sure that the "to" context supports C++!
1013 return Importer.getToContext().Char16Ty;
1014
1015 case BuiltinType::Char32:
1016 // FIXME: Make sure that the "to" context supports C++!
1017 return Importer.getToContext().Char32Ty;
1018
1019 case BuiltinType::UShort: return Importer.getToContext().UnsignedShortTy;
1020 case BuiltinType::UInt: return Importer.getToContext().UnsignedIntTy;
1021 case BuiltinType::ULong: return Importer.getToContext().UnsignedLongTy;
1022 case BuiltinType::ULongLong:
1023 return Importer.getToContext().UnsignedLongLongTy;
1024 case BuiltinType::UInt128: return Importer.getToContext().UnsignedInt128Ty;
1025
1026 case BuiltinType::Char_S:
1027 // The context we're importing from has an unsigned 'char'. If we're
1028 // importing into a context with a signed 'char', translate to
1029 // 'unsigned char' instead.
1030 if (!Importer.getToContext().getLangOptions().CharIsSigned)
1031 return Importer.getToContext().SignedCharTy;
1032
1033 return Importer.getToContext().CharTy;
1034
1035 case BuiltinType::SChar: return Importer.getToContext().SignedCharTy;
1036 case BuiltinType::WChar:
1037 // FIXME: If not in C++, shall we translate to the C equivalent of
1038 // wchar_t?
1039 return Importer.getToContext().WCharTy;
1040
1041 case BuiltinType::Short : return Importer.getToContext().ShortTy;
1042 case BuiltinType::Int : return Importer.getToContext().IntTy;
1043 case BuiltinType::Long : return Importer.getToContext().LongTy;
1044 case BuiltinType::LongLong : return Importer.getToContext().LongLongTy;
1045 case BuiltinType::Int128 : return Importer.getToContext().Int128Ty;
1046 case BuiltinType::Float: return Importer.getToContext().FloatTy;
1047 case BuiltinType::Double: return Importer.getToContext().DoubleTy;
1048 case BuiltinType::LongDouble: return Importer.getToContext().LongDoubleTy;
1049
1050 case BuiltinType::NullPtr:
1051 // FIXME: Make sure that the "to" context supports C++0x!
1052 return Importer.getToContext().NullPtrTy;
1053
1054 case BuiltinType::Overload: return Importer.getToContext().OverloadTy;
1055 case BuiltinType::Dependent: return Importer.getToContext().DependentTy;
1056 case BuiltinType::UndeducedAuto:
1057 // FIXME: Make sure that the "to" context supports C++0x!
1058 return Importer.getToContext().UndeducedAutoTy;
1059
1060 case BuiltinType::ObjCId:
1061 // FIXME: Make sure that the "to" context supports Objective-C!
1062 return Importer.getToContext().ObjCBuiltinIdTy;
1063
1064 case BuiltinType::ObjCClass:
1065 return Importer.getToContext().ObjCBuiltinClassTy;
1066
1067 case BuiltinType::ObjCSel:
1068 return Importer.getToContext().ObjCBuiltinSelTy;
1069 }
1070
1071 return QualType();
1072}
1073
1074QualType ASTNodeImporter::VisitComplexType(ComplexType *T) {
1075 QualType ToElementType = Importer.Import(T->getElementType());
1076 if (ToElementType.isNull())
1077 return QualType();
1078
1079 return Importer.getToContext().getComplexType(ToElementType);
1080}
1081
1082QualType ASTNodeImporter::VisitPointerType(PointerType *T) {
1083 QualType ToPointeeType = Importer.Import(T->getPointeeType());
1084 if (ToPointeeType.isNull())
1085 return QualType();
1086
1087 return Importer.getToContext().getPointerType(ToPointeeType);
1088}
1089
1090QualType ASTNodeImporter::VisitBlockPointerType(BlockPointerType *T) {
1091 // FIXME: Check for blocks support in "to" context.
1092 QualType ToPointeeType = Importer.Import(T->getPointeeType());
1093 if (ToPointeeType.isNull())
1094 return QualType();
1095
1096 return Importer.getToContext().getBlockPointerType(ToPointeeType);
1097}
1098
1099QualType ASTNodeImporter::VisitLValueReferenceType(LValueReferenceType *T) {
1100 // FIXME: Check for C++ support in "to" context.
1101 QualType ToPointeeType = Importer.Import(T->getPointeeTypeAsWritten());
1102 if (ToPointeeType.isNull())
1103 return QualType();
1104
1105 return Importer.getToContext().getLValueReferenceType(ToPointeeType);
1106}
1107
1108QualType ASTNodeImporter::VisitRValueReferenceType(RValueReferenceType *T) {
1109 // FIXME: Check for C++0x support in "to" context.
1110 QualType ToPointeeType = Importer.Import(T->getPointeeTypeAsWritten());
1111 if (ToPointeeType.isNull())
1112 return QualType();
1113
1114 return Importer.getToContext().getRValueReferenceType(ToPointeeType);
1115}
1116
1117QualType ASTNodeImporter::VisitMemberPointerType(MemberPointerType *T) {
1118 // FIXME: Check for C++ support in "to" context.
1119 QualType ToPointeeType = Importer.Import(T->getPointeeType());
1120 if (ToPointeeType.isNull())
1121 return QualType();
1122
1123 QualType ClassType = Importer.Import(QualType(T->getClass(), 0));
1124 return Importer.getToContext().getMemberPointerType(ToPointeeType,
1125 ClassType.getTypePtr());
1126}
1127
1128QualType ASTNodeImporter::VisitConstantArrayType(ConstantArrayType *T) {
1129 QualType ToElementType = Importer.Import(T->getElementType());
1130 if (ToElementType.isNull())
1131 return QualType();
1132
1133 return Importer.getToContext().getConstantArrayType(ToElementType,
1134 T->getSize(),
1135 T->getSizeModifier(),
1136 T->getIndexTypeCVRQualifiers());
1137}
1138
1139QualType ASTNodeImporter::VisitIncompleteArrayType(IncompleteArrayType *T) {
1140 QualType ToElementType = Importer.Import(T->getElementType());
1141 if (ToElementType.isNull())
1142 return QualType();
1143
1144 return Importer.getToContext().getIncompleteArrayType(ToElementType,
1145 T->getSizeModifier(),
1146 T->getIndexTypeCVRQualifiers());
1147}
1148
1149QualType ASTNodeImporter::VisitVariableArrayType(VariableArrayType *T) {
1150 QualType ToElementType = Importer.Import(T->getElementType());
1151 if (ToElementType.isNull())
1152 return QualType();
1153
1154 Expr *Size = Importer.Import(T->getSizeExpr());
1155 if (!Size)
1156 return QualType();
1157
1158 SourceRange Brackets = Importer.Import(T->getBracketsRange());
1159 return Importer.getToContext().getVariableArrayType(ToElementType, Size,
1160 T->getSizeModifier(),
1161 T->getIndexTypeCVRQualifiers(),
1162 Brackets);
1163}
1164
1165QualType ASTNodeImporter::VisitVectorType(VectorType *T) {
1166 QualType ToElementType = Importer.Import(T->getElementType());
1167 if (ToElementType.isNull())
1168 return QualType();
1169
1170 return Importer.getToContext().getVectorType(ToElementType,
1171 T->getNumElements(),
1172 T->isAltiVec(),
1173 T->isPixel());
1174}
1175
1176QualType ASTNodeImporter::VisitExtVectorType(ExtVectorType *T) {
1177 QualType ToElementType = Importer.Import(T->getElementType());
1178 if (ToElementType.isNull())
1179 return QualType();
1180
1181 return Importer.getToContext().getExtVectorType(ToElementType,
1182 T->getNumElements());
1183}
1184
1185QualType ASTNodeImporter::VisitFunctionNoProtoType(FunctionNoProtoType *T) {
1186 // FIXME: What happens if we're importing a function without a prototype
1187 // into C++? Should we make it variadic?
1188 QualType ToResultType = Importer.Import(T->getResultType());
1189 if (ToResultType.isNull())
1190 return QualType();
Rafael Espindolac50c27c2010-03-30 20:24:48 +00001191
Douglas Gregor96e578d2010-02-05 17:54:41 +00001192 return Importer.getToContext().getFunctionNoProtoType(ToResultType,
Rafael Espindolac50c27c2010-03-30 20:24:48 +00001193 T->getExtInfo());
Douglas Gregor96e578d2010-02-05 17:54:41 +00001194}
1195
1196QualType ASTNodeImporter::VisitFunctionProtoType(FunctionProtoType *T) {
1197 QualType ToResultType = Importer.Import(T->getResultType());
1198 if (ToResultType.isNull())
1199 return QualType();
1200
1201 // Import argument types
1202 llvm::SmallVector<QualType, 4> ArgTypes;
1203 for (FunctionProtoType::arg_type_iterator A = T->arg_type_begin(),
1204 AEnd = T->arg_type_end();
1205 A != AEnd; ++A) {
1206 QualType ArgType = Importer.Import(*A);
1207 if (ArgType.isNull())
1208 return QualType();
1209 ArgTypes.push_back(ArgType);
1210 }
1211
1212 // Import exception types
1213 llvm::SmallVector<QualType, 4> ExceptionTypes;
1214 for (FunctionProtoType::exception_iterator E = T->exception_begin(),
1215 EEnd = T->exception_end();
1216 E != EEnd; ++E) {
1217 QualType ExceptionType = Importer.Import(*E);
1218 if (ExceptionType.isNull())
1219 return QualType();
1220 ExceptionTypes.push_back(ExceptionType);
1221 }
1222
1223 return Importer.getToContext().getFunctionType(ToResultType, ArgTypes.data(),
1224 ArgTypes.size(),
1225 T->isVariadic(),
1226 T->getTypeQuals(),
1227 T->hasExceptionSpec(),
1228 T->hasAnyExceptionSpec(),
1229 ExceptionTypes.size(),
1230 ExceptionTypes.data(),
Rafael Espindolac50c27c2010-03-30 20:24:48 +00001231 T->getExtInfo());
Douglas Gregor96e578d2010-02-05 17:54:41 +00001232}
1233
1234QualType ASTNodeImporter::VisitTypedefType(TypedefType *T) {
1235 TypedefDecl *ToDecl
1236 = dyn_cast_or_null<TypedefDecl>(Importer.Import(T->getDecl()));
1237 if (!ToDecl)
1238 return QualType();
1239
1240 return Importer.getToContext().getTypeDeclType(ToDecl);
1241}
1242
1243QualType ASTNodeImporter::VisitTypeOfExprType(TypeOfExprType *T) {
1244 Expr *ToExpr = Importer.Import(T->getUnderlyingExpr());
1245 if (!ToExpr)
1246 return QualType();
1247
1248 return Importer.getToContext().getTypeOfExprType(ToExpr);
1249}
1250
1251QualType ASTNodeImporter::VisitTypeOfType(TypeOfType *T) {
1252 QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType());
1253 if (ToUnderlyingType.isNull())
1254 return QualType();
1255
1256 return Importer.getToContext().getTypeOfType(ToUnderlyingType);
1257}
1258
1259QualType ASTNodeImporter::VisitDecltypeType(DecltypeType *T) {
1260 Expr *ToExpr = Importer.Import(T->getUnderlyingExpr());
1261 if (!ToExpr)
1262 return QualType();
1263
1264 return Importer.getToContext().getDecltypeType(ToExpr);
1265}
1266
1267QualType ASTNodeImporter::VisitRecordType(RecordType *T) {
1268 RecordDecl *ToDecl
1269 = dyn_cast_or_null<RecordDecl>(Importer.Import(T->getDecl()));
1270 if (!ToDecl)
1271 return QualType();
1272
1273 return Importer.getToContext().getTagDeclType(ToDecl);
1274}
1275
1276QualType ASTNodeImporter::VisitEnumType(EnumType *T) {
1277 EnumDecl *ToDecl
1278 = dyn_cast_or_null<EnumDecl>(Importer.Import(T->getDecl()));
1279 if (!ToDecl)
1280 return QualType();
1281
1282 return Importer.getToContext().getTagDeclType(ToDecl);
1283}
1284
1285QualType ASTNodeImporter::VisitElaboratedType(ElaboratedType *T) {
Abramo Bagnara6150c882010-05-11 21:36:43 +00001286 NestedNameSpecifier *ToQualifier = 0;
1287 // Note: the qualifier in an ElaboratedType is optional.
1288 if (T->getQualifier()) {
1289 ToQualifier = Importer.Import(T->getQualifier());
1290 if (!ToQualifier)
1291 return QualType();
1292 }
Douglas Gregor96e578d2010-02-05 17:54:41 +00001293
1294 QualType ToNamedType = Importer.Import(T->getNamedType());
1295 if (ToNamedType.isNull())
1296 return QualType();
1297
Abramo Bagnara6150c882010-05-11 21:36:43 +00001298 return Importer.getToContext().getElaboratedType(T->getKeyword(),
1299 ToQualifier, ToNamedType);
Douglas Gregor96e578d2010-02-05 17:54:41 +00001300}
1301
1302QualType ASTNodeImporter::VisitObjCInterfaceType(ObjCInterfaceType *T) {
1303 ObjCInterfaceDecl *Class
1304 = dyn_cast_or_null<ObjCInterfaceDecl>(Importer.Import(T->getDecl()));
1305 if (!Class)
1306 return QualType();
1307
1308 llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
1309 for (ObjCInterfaceType::qual_iterator P = T->qual_begin(),
1310 PEnd = T->qual_end();
1311 P != PEnd; ++P) {
1312 ObjCProtocolDecl *Protocol
1313 = dyn_cast_or_null<ObjCProtocolDecl>(Importer.Import(*P));
1314 if (!Protocol)
1315 return QualType();
1316 Protocols.push_back(Protocol);
1317 }
1318
1319 return Importer.getToContext().getObjCInterfaceType(Class,
1320 Protocols.data(),
1321 Protocols.size());
1322}
1323
1324QualType ASTNodeImporter::VisitObjCObjectPointerType(ObjCObjectPointerType *T) {
1325 QualType ToPointeeType = Importer.Import(T->getPointeeType());
1326 if (ToPointeeType.isNull())
1327 return QualType();
1328
1329 llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
1330 for (ObjCObjectPointerType::qual_iterator P = T->qual_begin(),
1331 PEnd = T->qual_end();
1332 P != PEnd; ++P) {
1333 ObjCProtocolDecl *Protocol
1334 = dyn_cast_or_null<ObjCProtocolDecl>(Importer.Import(*P));
1335 if (!Protocol)
1336 return QualType();
1337 Protocols.push_back(Protocol);
1338 }
1339
1340 return Importer.getToContext().getObjCObjectPointerType(ToPointeeType,
1341 Protocols.data(),
1342 Protocols.size());
1343}
1344
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001345//----------------------------------------------------------------------------
1346// Import Declarations
1347//----------------------------------------------------------------------------
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001348bool ASTNodeImporter::ImportDeclParts(NamedDecl *D, DeclContext *&DC,
1349 DeclContext *&LexicalDC,
1350 DeclarationName &Name,
1351 SourceLocation &Loc) {
1352 // Import the context of this declaration.
1353 DC = Importer.ImportContext(D->getDeclContext());
1354 if (!DC)
1355 return true;
1356
1357 LexicalDC = DC;
1358 if (D->getDeclContext() != D->getLexicalDeclContext()) {
1359 LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
1360 if (!LexicalDC)
1361 return true;
1362 }
1363
1364 // Import the name of this declaration.
1365 Name = Importer.Import(D->getDeclName());
1366 if (D->getDeclName() && !Name)
1367 return true;
1368
1369 // Import the location of this declaration.
1370 Loc = Importer.Import(D->getLocation());
1371 return false;
1372}
1373
Douglas Gregor968d6332010-02-21 18:24:45 +00001374void ASTNodeImporter::ImportDeclContext(DeclContext *FromDC) {
1375 for (DeclContext::decl_iterator From = FromDC->decls_begin(),
1376 FromEnd = FromDC->decls_end();
1377 From != FromEnd;
1378 ++From)
1379 Importer.Import(*From);
1380}
1381
Douglas Gregor5c73e912010-02-11 00:48:18 +00001382bool ASTNodeImporter::IsStructuralMatch(RecordDecl *FromRecord,
Douglas Gregor3996e242010-02-15 22:01:00 +00001383 RecordDecl *ToRecord) {
Benjamin Kramer26d19c52010-02-18 13:02:13 +00001384 StructuralEquivalenceContext Ctx(Importer.getFromContext(),
Douglas Gregor3996e242010-02-15 22:01:00 +00001385 Importer.getToContext(),
Douglas Gregorb4964f72010-02-15 23:54:17 +00001386 Importer.getDiags(),
1387 Importer.getNonEquivalentDecls());
Benjamin Kramer26d19c52010-02-18 13:02:13 +00001388 return Ctx.IsStructurallyEquivalent(FromRecord, ToRecord);
Douglas Gregor5c73e912010-02-11 00:48:18 +00001389}
1390
Douglas Gregor98c10182010-02-12 22:17:39 +00001391bool ASTNodeImporter::IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToEnum) {
Benjamin Kramer26d19c52010-02-18 13:02:13 +00001392 StructuralEquivalenceContext Ctx(Importer.getFromContext(),
Douglas Gregor3996e242010-02-15 22:01:00 +00001393 Importer.getToContext(),
Douglas Gregorb4964f72010-02-15 23:54:17 +00001394 Importer.getDiags(),
1395 Importer.getNonEquivalentDecls());
Benjamin Kramer26d19c52010-02-18 13:02:13 +00001396 return Ctx.IsStructurallyEquivalent(FromEnum, ToEnum);
Douglas Gregor98c10182010-02-12 22:17:39 +00001397}
1398
Douglas Gregore4c83e42010-02-09 22:48:33 +00001399Decl *ASTNodeImporter::VisitDecl(Decl *D) {
Douglas Gregor811663e2010-02-10 00:15:17 +00001400 Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node)
Douglas Gregore4c83e42010-02-09 22:48:33 +00001401 << D->getDeclKindName();
1402 return 0;
1403}
1404
Douglas Gregorf18a2c72010-02-21 18:26:36 +00001405Decl *ASTNodeImporter::VisitNamespaceDecl(NamespaceDecl *D) {
1406 // Import the major distinguishing characteristics of this namespace.
1407 DeclContext *DC, *LexicalDC;
1408 DeclarationName Name;
1409 SourceLocation Loc;
1410 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
1411 return 0;
1412
1413 NamespaceDecl *MergeWithNamespace = 0;
1414 if (!Name) {
1415 // This is an anonymous namespace. Adopt an existing anonymous
1416 // namespace if we can.
1417 // FIXME: Not testable.
1418 if (TranslationUnitDecl *TU = dyn_cast<TranslationUnitDecl>(DC))
1419 MergeWithNamespace = TU->getAnonymousNamespace();
1420 else
1421 MergeWithNamespace = cast<NamespaceDecl>(DC)->getAnonymousNamespace();
1422 } else {
1423 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
1424 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
1425 Lookup.first != Lookup.second;
1426 ++Lookup.first) {
John McCalle87beb22010-04-23 18:46:30 +00001427 if (!(*Lookup.first)->isInIdentifierNamespace(Decl::IDNS_Namespace))
Douglas Gregorf18a2c72010-02-21 18:26:36 +00001428 continue;
1429
1430 if (NamespaceDecl *FoundNS = dyn_cast<NamespaceDecl>(*Lookup.first)) {
1431 MergeWithNamespace = FoundNS;
1432 ConflictingDecls.clear();
1433 break;
1434 }
1435
1436 ConflictingDecls.push_back(*Lookup.first);
1437 }
1438
1439 if (!ConflictingDecls.empty()) {
John McCalle87beb22010-04-23 18:46:30 +00001440 Name = Importer.HandleNameConflict(Name, DC, Decl::IDNS_Namespace,
Douglas Gregorf18a2c72010-02-21 18:26:36 +00001441 ConflictingDecls.data(),
1442 ConflictingDecls.size());
1443 }
1444 }
1445
1446 // Create the "to" namespace, if needed.
1447 NamespaceDecl *ToNamespace = MergeWithNamespace;
1448 if (!ToNamespace) {
1449 ToNamespace = NamespaceDecl::Create(Importer.getToContext(), DC, Loc,
1450 Name.getAsIdentifierInfo());
1451 ToNamespace->setLexicalDeclContext(LexicalDC);
1452 LexicalDC->addDecl(ToNamespace);
1453
1454 // If this is an anonymous namespace, register it as the anonymous
1455 // namespace within its context.
1456 if (!Name) {
1457 if (TranslationUnitDecl *TU = dyn_cast<TranslationUnitDecl>(DC))
1458 TU->setAnonymousNamespace(ToNamespace);
1459 else
1460 cast<NamespaceDecl>(DC)->setAnonymousNamespace(ToNamespace);
1461 }
1462 }
1463 Importer.Imported(D, ToNamespace);
1464
1465 ImportDeclContext(D);
1466
1467 return ToNamespace;
1468}
1469
Douglas Gregor5fa74c32010-02-10 21:10:29 +00001470Decl *ASTNodeImporter::VisitTypedefDecl(TypedefDecl *D) {
1471 // Import the major distinguishing characteristics of this typedef.
1472 DeclContext *DC, *LexicalDC;
1473 DeclarationName Name;
1474 SourceLocation Loc;
1475 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
1476 return 0;
1477
Douglas Gregor5fa74c32010-02-10 21:10:29 +00001478 // If this typedef is not in block scope, determine whether we've
1479 // seen a typedef with the same name (that we can merge with) or any
1480 // other entity by that name (which name lookup could conflict with).
1481 if (!DC->isFunctionOrMethod()) {
1482 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
1483 unsigned IDNS = Decl::IDNS_Ordinary;
1484 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
1485 Lookup.first != Lookup.second;
1486 ++Lookup.first) {
1487 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
1488 continue;
1489 if (TypedefDecl *FoundTypedef = dyn_cast<TypedefDecl>(*Lookup.first)) {
Douglas Gregorb4964f72010-02-15 23:54:17 +00001490 if (Importer.IsStructurallyEquivalent(D->getUnderlyingType(),
1491 FoundTypedef->getUnderlyingType()))
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001492 return Importer.Imported(D, FoundTypedef);
Douglas Gregor5fa74c32010-02-10 21:10:29 +00001493 }
1494
1495 ConflictingDecls.push_back(*Lookup.first);
1496 }
1497
1498 if (!ConflictingDecls.empty()) {
1499 Name = Importer.HandleNameConflict(Name, DC, IDNS,
1500 ConflictingDecls.data(),
1501 ConflictingDecls.size());
1502 if (!Name)
1503 return 0;
1504 }
1505 }
1506
Douglas Gregorb4964f72010-02-15 23:54:17 +00001507 // Import the underlying type of this typedef;
1508 QualType T = Importer.Import(D->getUnderlyingType());
1509 if (T.isNull())
1510 return 0;
1511
Douglas Gregor5fa74c32010-02-10 21:10:29 +00001512 // Create the new typedef node.
1513 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
1514 TypedefDecl *ToTypedef = TypedefDecl::Create(Importer.getToContext(), DC,
1515 Loc, Name.getAsIdentifierInfo(),
1516 TInfo);
Douglas Gregordd483172010-02-22 17:42:47 +00001517 ToTypedef->setAccess(D->getAccess());
Douglas Gregor5fa74c32010-02-10 21:10:29 +00001518 ToTypedef->setLexicalDeclContext(LexicalDC);
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001519 Importer.Imported(D, ToTypedef);
Douglas Gregor5fa74c32010-02-10 21:10:29 +00001520 LexicalDC->addDecl(ToTypedef);
Douglas Gregorb4964f72010-02-15 23:54:17 +00001521
Douglas Gregor5fa74c32010-02-10 21:10:29 +00001522 return ToTypedef;
1523}
1524
Douglas Gregor98c10182010-02-12 22:17:39 +00001525Decl *ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
1526 // Import the major distinguishing characteristics of this enum.
1527 DeclContext *DC, *LexicalDC;
1528 DeclarationName Name;
1529 SourceLocation Loc;
1530 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
1531 return 0;
1532
1533 // Figure out what enum name we're looking for.
1534 unsigned IDNS = Decl::IDNS_Tag;
1535 DeclarationName SearchName = Name;
1536 if (!SearchName && D->getTypedefForAnonDecl()) {
1537 SearchName = Importer.Import(D->getTypedefForAnonDecl()->getDeclName());
1538 IDNS = Decl::IDNS_Ordinary;
1539 } else if (Importer.getToContext().getLangOptions().CPlusPlus)
1540 IDNS |= Decl::IDNS_Ordinary;
1541
1542 // We may already have an enum of the same name; try to find and match it.
1543 if (!DC->isFunctionOrMethod() && SearchName) {
1544 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
1545 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
1546 Lookup.first != Lookup.second;
1547 ++Lookup.first) {
1548 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
1549 continue;
1550
1551 Decl *Found = *Lookup.first;
1552 if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(Found)) {
1553 if (const TagType *Tag = Typedef->getUnderlyingType()->getAs<TagType>())
1554 Found = Tag->getDecl();
1555 }
1556
1557 if (EnumDecl *FoundEnum = dyn_cast<EnumDecl>(Found)) {
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001558 if (IsStructuralMatch(D, FoundEnum))
1559 return Importer.Imported(D, FoundEnum);
Douglas Gregor98c10182010-02-12 22:17:39 +00001560 }
1561
1562 ConflictingDecls.push_back(*Lookup.first);
1563 }
1564
1565 if (!ConflictingDecls.empty()) {
1566 Name = Importer.HandleNameConflict(Name, DC, IDNS,
1567 ConflictingDecls.data(),
1568 ConflictingDecls.size());
1569 }
1570 }
1571
1572 // Create the enum declaration.
Douglas Gregor3996e242010-02-15 22:01:00 +00001573 EnumDecl *D2 = EnumDecl::Create(Importer.getToContext(), DC, Loc,
Douglas Gregor98c10182010-02-12 22:17:39 +00001574 Name.getAsIdentifierInfo(),
1575 Importer.Import(D->getTagKeywordLoc()),
1576 0);
John McCall3e11ebe2010-03-15 10:12:16 +00001577 // Import the qualifier, if any.
1578 if (D->getQualifier()) {
1579 NestedNameSpecifier *NNS = Importer.Import(D->getQualifier());
1580 SourceRange NNSRange = Importer.Import(D->getQualifierRange());
1581 D2->setQualifierInfo(NNS, NNSRange);
1582 }
Douglas Gregordd483172010-02-22 17:42:47 +00001583 D2->setAccess(D->getAccess());
Douglas Gregor3996e242010-02-15 22:01:00 +00001584 D2->setLexicalDeclContext(LexicalDC);
1585 Importer.Imported(D, D2);
1586 LexicalDC->addDecl(D2);
Douglas Gregor98c10182010-02-12 22:17:39 +00001587
1588 // Import the integer type.
1589 QualType ToIntegerType = Importer.Import(D->getIntegerType());
1590 if (ToIntegerType.isNull())
1591 return 0;
Douglas Gregor3996e242010-02-15 22:01:00 +00001592 D2->setIntegerType(ToIntegerType);
Douglas Gregor98c10182010-02-12 22:17:39 +00001593
1594 // Import the definition
1595 if (D->isDefinition()) {
1596 QualType T = Importer.Import(Importer.getFromContext().getTypeDeclType(D));
1597 if (T.isNull())
1598 return 0;
1599
1600 QualType ToPromotionType = Importer.Import(D->getPromotionType());
1601 if (ToPromotionType.isNull())
1602 return 0;
1603
Douglas Gregor3996e242010-02-15 22:01:00 +00001604 D2->startDefinition();
Douglas Gregor968d6332010-02-21 18:24:45 +00001605 ImportDeclContext(D);
John McCall9aa35be2010-05-06 08:49:23 +00001606
1607 // FIXME: we might need to merge the number of positive or negative bits
1608 // if the enumerator lists don't match.
1609 D2->completeDefinition(T, ToPromotionType,
1610 D->getNumPositiveBits(),
1611 D->getNumNegativeBits());
Douglas Gregor98c10182010-02-12 22:17:39 +00001612 }
1613
Douglas Gregor3996e242010-02-15 22:01:00 +00001614 return D2;
Douglas Gregor98c10182010-02-12 22:17:39 +00001615}
1616
Douglas Gregor5c73e912010-02-11 00:48:18 +00001617Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
1618 // If this record has a definition in the translation unit we're coming from,
1619 // but this particular declaration is not that definition, import the
1620 // definition and map to that.
Douglas Gregor0a5a2212010-02-11 01:04:33 +00001621 TagDecl *Definition = D->getDefinition();
Douglas Gregor5c73e912010-02-11 00:48:18 +00001622 if (Definition && Definition != D) {
1623 Decl *ImportedDef = Importer.Import(Definition);
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001624 if (!ImportedDef)
1625 return 0;
1626
1627 return Importer.Imported(D, ImportedDef);
Douglas Gregor5c73e912010-02-11 00:48:18 +00001628 }
1629
1630 // Import the major distinguishing characteristics of this record.
1631 DeclContext *DC, *LexicalDC;
1632 DeclarationName Name;
1633 SourceLocation Loc;
1634 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
1635 return 0;
1636
1637 // Figure out what structure name we're looking for.
1638 unsigned IDNS = Decl::IDNS_Tag;
1639 DeclarationName SearchName = Name;
1640 if (!SearchName && D->getTypedefForAnonDecl()) {
1641 SearchName = Importer.Import(D->getTypedefForAnonDecl()->getDeclName());
1642 IDNS = Decl::IDNS_Ordinary;
1643 } else if (Importer.getToContext().getLangOptions().CPlusPlus)
1644 IDNS |= Decl::IDNS_Ordinary;
1645
1646 // We may already have a record of the same name; try to find and match it.
Douglas Gregor25791052010-02-12 00:09:27 +00001647 RecordDecl *AdoptDecl = 0;
Douglas Gregor5c73e912010-02-11 00:48:18 +00001648 if (!DC->isFunctionOrMethod() && SearchName) {
1649 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
1650 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
1651 Lookup.first != Lookup.second;
1652 ++Lookup.first) {
1653 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
1654 continue;
1655
1656 Decl *Found = *Lookup.first;
1657 if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(Found)) {
1658 if (const TagType *Tag = Typedef->getUnderlyingType()->getAs<TagType>())
1659 Found = Tag->getDecl();
1660 }
1661
1662 if (RecordDecl *FoundRecord = dyn_cast<RecordDecl>(Found)) {
Douglas Gregor25791052010-02-12 00:09:27 +00001663 if (RecordDecl *FoundDef = FoundRecord->getDefinition()) {
1664 if (!D->isDefinition() || IsStructuralMatch(D, FoundDef)) {
1665 // The record types structurally match, or the "from" translation
1666 // unit only had a forward declaration anyway; call it the same
1667 // function.
1668 // FIXME: For C++, we should also merge methods here.
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001669 return Importer.Imported(D, FoundDef);
Douglas Gregor25791052010-02-12 00:09:27 +00001670 }
1671 } else {
1672 // We have a forward declaration of this type, so adopt that forward
1673 // declaration rather than building a new one.
1674 AdoptDecl = FoundRecord;
1675 continue;
1676 }
Douglas Gregor5c73e912010-02-11 00:48:18 +00001677 }
1678
1679 ConflictingDecls.push_back(*Lookup.first);
1680 }
1681
1682 if (!ConflictingDecls.empty()) {
1683 Name = Importer.HandleNameConflict(Name, DC, IDNS,
1684 ConflictingDecls.data(),
1685 ConflictingDecls.size());
1686 }
1687 }
1688
1689 // Create the record declaration.
Douglas Gregor3996e242010-02-15 22:01:00 +00001690 RecordDecl *D2 = AdoptDecl;
1691 if (!D2) {
1692 if (CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(D)) {
1693 CXXRecordDecl *D2CXX = CXXRecordDecl::Create(Importer.getToContext(),
Douglas Gregor25791052010-02-12 00:09:27 +00001694 D->getTagKind(),
1695 DC, Loc,
1696 Name.getAsIdentifierInfo(),
Douglas Gregor5c73e912010-02-11 00:48:18 +00001697 Importer.Import(D->getTagKeywordLoc()));
Douglas Gregor3996e242010-02-15 22:01:00 +00001698 D2 = D2CXX;
Douglas Gregordd483172010-02-22 17:42:47 +00001699 D2->setAccess(D->getAccess());
Douglas Gregor25791052010-02-12 00:09:27 +00001700
1701 if (D->isDefinition()) {
1702 // Add base classes.
1703 llvm::SmallVector<CXXBaseSpecifier *, 4> Bases;
1704 for (CXXRecordDecl::base_class_iterator
Douglas Gregor3996e242010-02-15 22:01:00 +00001705 Base1 = D1CXX->bases_begin(),
1706 FromBaseEnd = D1CXX->bases_end();
1707 Base1 != FromBaseEnd;
1708 ++Base1) {
1709 QualType T = Importer.Import(Base1->getType());
Douglas Gregor25791052010-02-12 00:09:27 +00001710 if (T.isNull())
1711 return 0;
1712
1713 Bases.push_back(
1714 new (Importer.getToContext())
Douglas Gregor3996e242010-02-15 22:01:00 +00001715 CXXBaseSpecifier(Importer.Import(Base1->getSourceRange()),
1716 Base1->isVirtual(),
1717 Base1->isBaseOfClass(),
1718 Base1->getAccessSpecifierAsWritten(),
Douglas Gregor5c73e912010-02-11 00:48:18 +00001719 T));
Douglas Gregor25791052010-02-12 00:09:27 +00001720 }
1721 if (!Bases.empty())
Douglas Gregor3996e242010-02-15 22:01:00 +00001722 D2CXX->setBases(Bases.data(), Bases.size());
Douglas Gregor5c73e912010-02-11 00:48:18 +00001723 }
Douglas Gregor25791052010-02-12 00:09:27 +00001724 } else {
Douglas Gregor3996e242010-02-15 22:01:00 +00001725 D2 = RecordDecl::Create(Importer.getToContext(), D->getTagKind(),
Douglas Gregor25791052010-02-12 00:09:27 +00001726 DC, Loc,
1727 Name.getAsIdentifierInfo(),
1728 Importer.Import(D->getTagKeywordLoc()));
Douglas Gregor5c73e912010-02-11 00:48:18 +00001729 }
John McCall3e11ebe2010-03-15 10:12:16 +00001730 // Import the qualifier, if any.
1731 if (D->getQualifier()) {
1732 NestedNameSpecifier *NNS = Importer.Import(D->getQualifier());
1733 SourceRange NNSRange = Importer.Import(D->getQualifierRange());
1734 D2->setQualifierInfo(NNS, NNSRange);
1735 }
Douglas Gregor3996e242010-02-15 22:01:00 +00001736 D2->setLexicalDeclContext(LexicalDC);
1737 LexicalDC->addDecl(D2);
Douglas Gregor5c73e912010-02-11 00:48:18 +00001738 }
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001739
Douglas Gregor3996e242010-02-15 22:01:00 +00001740 Importer.Imported(D, D2);
Douglas Gregor25791052010-02-12 00:09:27 +00001741
Douglas Gregor5c73e912010-02-11 00:48:18 +00001742 if (D->isDefinition()) {
Douglas Gregor3996e242010-02-15 22:01:00 +00001743 D2->startDefinition();
Douglas Gregor968d6332010-02-21 18:24:45 +00001744 ImportDeclContext(D);
Douglas Gregor3996e242010-02-15 22:01:00 +00001745 D2->completeDefinition();
Douglas Gregor5c73e912010-02-11 00:48:18 +00001746 }
1747
Douglas Gregor3996e242010-02-15 22:01:00 +00001748 return D2;
Douglas Gregor5c73e912010-02-11 00:48:18 +00001749}
1750
Douglas Gregor98c10182010-02-12 22:17:39 +00001751Decl *ASTNodeImporter::VisitEnumConstantDecl(EnumConstantDecl *D) {
1752 // Import the major distinguishing characteristics of this enumerator.
1753 DeclContext *DC, *LexicalDC;
1754 DeclarationName Name;
1755 SourceLocation Loc;
Douglas Gregorb4964f72010-02-15 23:54:17 +00001756 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
Douglas Gregor98c10182010-02-12 22:17:39 +00001757 return 0;
Douglas Gregorb4964f72010-02-15 23:54:17 +00001758
1759 QualType T = Importer.Import(D->getType());
1760 if (T.isNull())
1761 return 0;
1762
Douglas Gregor98c10182010-02-12 22:17:39 +00001763 // Determine whether there are any other declarations with the same name and
1764 // in the same context.
1765 if (!LexicalDC->isFunctionOrMethod()) {
1766 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
1767 unsigned IDNS = Decl::IDNS_Ordinary;
1768 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
1769 Lookup.first != Lookup.second;
1770 ++Lookup.first) {
1771 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
1772 continue;
1773
1774 ConflictingDecls.push_back(*Lookup.first);
1775 }
1776
1777 if (!ConflictingDecls.empty()) {
1778 Name = Importer.HandleNameConflict(Name, DC, IDNS,
1779 ConflictingDecls.data(),
1780 ConflictingDecls.size());
1781 if (!Name)
1782 return 0;
1783 }
1784 }
1785
1786 Expr *Init = Importer.Import(D->getInitExpr());
1787 if (D->getInitExpr() && !Init)
1788 return 0;
1789
1790 EnumConstantDecl *ToEnumerator
1791 = EnumConstantDecl::Create(Importer.getToContext(), cast<EnumDecl>(DC), Loc,
1792 Name.getAsIdentifierInfo(), T,
1793 Init, D->getInitVal());
Douglas Gregordd483172010-02-22 17:42:47 +00001794 ToEnumerator->setAccess(D->getAccess());
Douglas Gregor98c10182010-02-12 22:17:39 +00001795 ToEnumerator->setLexicalDeclContext(LexicalDC);
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001796 Importer.Imported(D, ToEnumerator);
Douglas Gregor98c10182010-02-12 22:17:39 +00001797 LexicalDC->addDecl(ToEnumerator);
1798 return ToEnumerator;
1799}
Douglas Gregor5c73e912010-02-11 00:48:18 +00001800
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001801Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
1802 // Import the major distinguishing characteristics of this function.
1803 DeclContext *DC, *LexicalDC;
1804 DeclarationName Name;
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001805 SourceLocation Loc;
Douglas Gregorb4964f72010-02-15 23:54:17 +00001806 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001807 return 0;
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001808
1809 // Try to find a function in our own ("to") context with the same name, same
1810 // type, and in the same context as the function we're importing.
1811 if (!LexicalDC->isFunctionOrMethod()) {
1812 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
1813 unsigned IDNS = Decl::IDNS_Ordinary;
1814 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
1815 Lookup.first != Lookup.second;
1816 ++Lookup.first) {
1817 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
1818 continue;
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001819
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001820 if (FunctionDecl *FoundFunction = dyn_cast<FunctionDecl>(*Lookup.first)) {
1821 if (isExternalLinkage(FoundFunction->getLinkage()) &&
1822 isExternalLinkage(D->getLinkage())) {
Douglas Gregorb4964f72010-02-15 23:54:17 +00001823 if (Importer.IsStructurallyEquivalent(D->getType(),
1824 FoundFunction->getType())) {
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001825 // FIXME: Actually try to merge the body and other attributes.
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001826 return Importer.Imported(D, FoundFunction);
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001827 }
1828
1829 // FIXME: Check for overloading more carefully, e.g., by boosting
1830 // Sema::IsOverload out to the AST library.
1831
1832 // Function overloading is okay in C++.
1833 if (Importer.getToContext().getLangOptions().CPlusPlus)
1834 continue;
1835
1836 // Complain about inconsistent function types.
1837 Importer.ToDiag(Loc, diag::err_odr_function_type_inconsistent)
Douglas Gregorb4964f72010-02-15 23:54:17 +00001838 << Name << D->getType() << FoundFunction->getType();
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001839 Importer.ToDiag(FoundFunction->getLocation(),
1840 diag::note_odr_value_here)
1841 << FoundFunction->getType();
1842 }
1843 }
1844
1845 ConflictingDecls.push_back(*Lookup.first);
1846 }
1847
1848 if (!ConflictingDecls.empty()) {
1849 Name = Importer.HandleNameConflict(Name, DC, IDNS,
1850 ConflictingDecls.data(),
1851 ConflictingDecls.size());
1852 if (!Name)
1853 return 0;
1854 }
Douglas Gregor62d311f2010-02-09 19:21:46 +00001855 }
Douglas Gregorb4964f72010-02-15 23:54:17 +00001856
1857 // Import the type.
1858 QualType T = Importer.Import(D->getType());
1859 if (T.isNull())
1860 return 0;
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001861
1862 // Import the function parameters.
1863 llvm::SmallVector<ParmVarDecl *, 8> Parameters;
1864 for (FunctionDecl::param_iterator P = D->param_begin(), PEnd = D->param_end();
1865 P != PEnd; ++P) {
1866 ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(*P));
1867 if (!ToP)
1868 return 0;
1869
1870 Parameters.push_back(ToP);
1871 }
1872
1873 // Create the imported function.
1874 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
Douglas Gregor00eace12010-02-21 18:29:16 +00001875 FunctionDecl *ToFunction = 0;
1876 if (CXXConstructorDecl *FromConstructor = dyn_cast<CXXConstructorDecl>(D)) {
1877 ToFunction = CXXConstructorDecl::Create(Importer.getToContext(),
1878 cast<CXXRecordDecl>(DC),
1879 Loc, Name, T, TInfo,
1880 FromConstructor->isExplicit(),
1881 D->isInlineSpecified(),
1882 D->isImplicit());
1883 } else if (isa<CXXDestructorDecl>(D)) {
1884 ToFunction = CXXDestructorDecl::Create(Importer.getToContext(),
1885 cast<CXXRecordDecl>(DC),
1886 Loc, Name, T,
1887 D->isInlineSpecified(),
1888 D->isImplicit());
1889 } else if (CXXConversionDecl *FromConversion
1890 = dyn_cast<CXXConversionDecl>(D)) {
1891 ToFunction = CXXConversionDecl::Create(Importer.getToContext(),
1892 cast<CXXRecordDecl>(DC),
1893 Loc, Name, T, TInfo,
1894 D->isInlineSpecified(),
1895 FromConversion->isExplicit());
1896 } else {
1897 ToFunction = FunctionDecl::Create(Importer.getToContext(), DC, Loc,
1898 Name, T, TInfo, D->getStorageClass(),
Douglas Gregorc4df4072010-04-19 22:54:31 +00001899 D->getStorageClassAsWritten(),
Douglas Gregor00eace12010-02-21 18:29:16 +00001900 D->isInlineSpecified(),
1901 D->hasWrittenPrototype());
1902 }
John McCall3e11ebe2010-03-15 10:12:16 +00001903
1904 // Import the qualifier, if any.
1905 if (D->getQualifier()) {
1906 NestedNameSpecifier *NNS = Importer.Import(D->getQualifier());
1907 SourceRange NNSRange = Importer.Import(D->getQualifierRange());
1908 ToFunction->setQualifierInfo(NNS, NNSRange);
1909 }
Douglas Gregordd483172010-02-22 17:42:47 +00001910 ToFunction->setAccess(D->getAccess());
Douglas Gregor43f54792010-02-17 02:12:47 +00001911 ToFunction->setLexicalDeclContext(LexicalDC);
1912 Importer.Imported(D, ToFunction);
1913 LexicalDC->addDecl(ToFunction);
Douglas Gregor62d311f2010-02-09 19:21:46 +00001914
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001915 // Set the parameters.
1916 for (unsigned I = 0, N = Parameters.size(); I != N; ++I) {
Douglas Gregor43f54792010-02-17 02:12:47 +00001917 Parameters[I]->setOwningFunction(ToFunction);
1918 ToFunction->addDecl(Parameters[I]);
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001919 }
Douglas Gregor43f54792010-02-17 02:12:47 +00001920 ToFunction->setParams(Parameters.data(), Parameters.size());
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001921
1922 // FIXME: Other bits to merge?
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001923
Douglas Gregor43f54792010-02-17 02:12:47 +00001924 return ToFunction;
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001925}
1926
Douglas Gregor00eace12010-02-21 18:29:16 +00001927Decl *ASTNodeImporter::VisitCXXMethodDecl(CXXMethodDecl *D) {
1928 return VisitFunctionDecl(D);
1929}
1930
1931Decl *ASTNodeImporter::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
1932 return VisitCXXMethodDecl(D);
1933}
1934
1935Decl *ASTNodeImporter::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
1936 return VisitCXXMethodDecl(D);
1937}
1938
1939Decl *ASTNodeImporter::VisitCXXConversionDecl(CXXConversionDecl *D) {
1940 return VisitCXXMethodDecl(D);
1941}
1942
Douglas Gregor5c73e912010-02-11 00:48:18 +00001943Decl *ASTNodeImporter::VisitFieldDecl(FieldDecl *D) {
1944 // Import the major distinguishing characteristics of a variable.
1945 DeclContext *DC, *LexicalDC;
1946 DeclarationName Name;
Douglas Gregor5c73e912010-02-11 00:48:18 +00001947 SourceLocation Loc;
Douglas Gregorb4964f72010-02-15 23:54:17 +00001948 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
1949 return 0;
1950
1951 // Import the type.
1952 QualType T = Importer.Import(D->getType());
1953 if (T.isNull())
Douglas Gregor5c73e912010-02-11 00:48:18 +00001954 return 0;
1955
1956 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
1957 Expr *BitWidth = Importer.Import(D->getBitWidth());
1958 if (!BitWidth && D->getBitWidth())
1959 return 0;
1960
1961 FieldDecl *ToField = FieldDecl::Create(Importer.getToContext(), DC,
1962 Loc, Name.getAsIdentifierInfo(),
1963 T, TInfo, BitWidth, D->isMutable());
Douglas Gregordd483172010-02-22 17:42:47 +00001964 ToField->setAccess(D->getAccess());
Douglas Gregor5c73e912010-02-11 00:48:18 +00001965 ToField->setLexicalDeclContext(LexicalDC);
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001966 Importer.Imported(D, ToField);
Douglas Gregor5c73e912010-02-11 00:48:18 +00001967 LexicalDC->addDecl(ToField);
1968 return ToField;
1969}
1970
Douglas Gregor7244b0b2010-02-17 00:34:30 +00001971Decl *ASTNodeImporter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
1972 // Import the major distinguishing characteristics of an ivar.
1973 DeclContext *DC, *LexicalDC;
1974 DeclarationName Name;
1975 SourceLocation Loc;
1976 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
1977 return 0;
1978
1979 // Determine whether we've already imported this ivar
1980 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
1981 Lookup.first != Lookup.second;
1982 ++Lookup.first) {
1983 if (ObjCIvarDecl *FoundIvar = dyn_cast<ObjCIvarDecl>(*Lookup.first)) {
1984 if (Importer.IsStructurallyEquivalent(D->getType(),
1985 FoundIvar->getType())) {
1986 Importer.Imported(D, FoundIvar);
1987 return FoundIvar;
1988 }
1989
1990 Importer.ToDiag(Loc, diag::err_odr_ivar_type_inconsistent)
1991 << Name << D->getType() << FoundIvar->getType();
1992 Importer.ToDiag(FoundIvar->getLocation(), diag::note_odr_value_here)
1993 << FoundIvar->getType();
1994 return 0;
1995 }
1996 }
1997
1998 // Import the type.
1999 QualType T = Importer.Import(D->getType());
2000 if (T.isNull())
2001 return 0;
2002
2003 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
2004 Expr *BitWidth = Importer.Import(D->getBitWidth());
2005 if (!BitWidth && D->getBitWidth())
2006 return 0;
2007
Daniel Dunbarfe3ead72010-04-02 20:10:03 +00002008 ObjCIvarDecl *ToIvar = ObjCIvarDecl::Create(Importer.getToContext(),
2009 cast<ObjCContainerDecl>(DC),
Douglas Gregor7244b0b2010-02-17 00:34:30 +00002010 Loc, Name.getAsIdentifierInfo(),
2011 T, TInfo, D->getAccessControl(),
2012 BitWidth);
2013 ToIvar->setLexicalDeclContext(LexicalDC);
2014 Importer.Imported(D, ToIvar);
2015 LexicalDC->addDecl(ToIvar);
2016 return ToIvar;
2017
2018}
2019
Douglas Gregorbb7930c2010-02-10 19:54:31 +00002020Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
2021 // Import the major distinguishing characteristics of a variable.
2022 DeclContext *DC, *LexicalDC;
2023 DeclarationName Name;
Douglas Gregorbb7930c2010-02-10 19:54:31 +00002024 SourceLocation Loc;
Douglas Gregorb4964f72010-02-15 23:54:17 +00002025 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00002026 return 0;
2027
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00002028 // Try to find a variable in our own ("to") context with the same name and
2029 // in the same context as the variable we're importing.
Douglas Gregor62d311f2010-02-09 19:21:46 +00002030 if (D->isFileVarDecl()) {
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00002031 VarDecl *MergeWithVar = 0;
2032 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
2033 unsigned IDNS = Decl::IDNS_Ordinary;
Douglas Gregor62d311f2010-02-09 19:21:46 +00002034 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00002035 Lookup.first != Lookup.second;
2036 ++Lookup.first) {
2037 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
2038 continue;
2039
2040 if (VarDecl *FoundVar = dyn_cast<VarDecl>(*Lookup.first)) {
2041 // We have found a variable that we may need to merge with. Check it.
2042 if (isExternalLinkage(FoundVar->getLinkage()) &&
2043 isExternalLinkage(D->getLinkage())) {
Douglas Gregorb4964f72010-02-15 23:54:17 +00002044 if (Importer.IsStructurallyEquivalent(D->getType(),
2045 FoundVar->getType())) {
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00002046 MergeWithVar = FoundVar;
2047 break;
2048 }
2049
Douglas Gregor56521c52010-02-12 17:23:39 +00002050 const ArrayType *FoundArray
2051 = Importer.getToContext().getAsArrayType(FoundVar->getType());
2052 const ArrayType *TArray
Douglas Gregorb4964f72010-02-15 23:54:17 +00002053 = Importer.getToContext().getAsArrayType(D->getType());
Douglas Gregor56521c52010-02-12 17:23:39 +00002054 if (FoundArray && TArray) {
2055 if (isa<IncompleteArrayType>(FoundArray) &&
2056 isa<ConstantArrayType>(TArray)) {
Douglas Gregorb4964f72010-02-15 23:54:17 +00002057 // Import the type.
2058 QualType T = Importer.Import(D->getType());
2059 if (T.isNull())
2060 return 0;
2061
Douglas Gregor56521c52010-02-12 17:23:39 +00002062 FoundVar->setType(T);
2063 MergeWithVar = FoundVar;
2064 break;
2065 } else if (isa<IncompleteArrayType>(TArray) &&
2066 isa<ConstantArrayType>(FoundArray)) {
2067 MergeWithVar = FoundVar;
2068 break;
Douglas Gregor2fbe5582010-02-10 17:16:49 +00002069 }
2070 }
2071
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00002072 Importer.ToDiag(Loc, diag::err_odr_variable_type_inconsistent)
Douglas Gregorb4964f72010-02-15 23:54:17 +00002073 << Name << D->getType() << FoundVar->getType();
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00002074 Importer.ToDiag(FoundVar->getLocation(), diag::note_odr_value_here)
2075 << FoundVar->getType();
2076 }
2077 }
2078
2079 ConflictingDecls.push_back(*Lookup.first);
2080 }
2081
2082 if (MergeWithVar) {
2083 // An equivalent variable with external linkage has been found. Link
2084 // the two declarations, then merge them.
Douglas Gregor8cdbe642010-02-12 23:44:20 +00002085 Importer.Imported(D, MergeWithVar);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00002086
2087 if (VarDecl *DDef = D->getDefinition()) {
2088 if (VarDecl *ExistingDef = MergeWithVar->getDefinition()) {
2089 Importer.ToDiag(ExistingDef->getLocation(),
2090 diag::err_odr_variable_multiple_def)
2091 << Name;
2092 Importer.FromDiag(DDef->getLocation(), diag::note_odr_defined_here);
2093 } else {
2094 Expr *Init = Importer.Import(DDef->getInit());
Douglas Gregord5058122010-02-11 01:19:42 +00002095 MergeWithVar->setInit(Init);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00002096 }
2097 }
2098
2099 return MergeWithVar;
2100 }
2101
2102 if (!ConflictingDecls.empty()) {
2103 Name = Importer.HandleNameConflict(Name, DC, IDNS,
2104 ConflictingDecls.data(),
2105 ConflictingDecls.size());
2106 if (!Name)
2107 return 0;
2108 }
2109 }
Douglas Gregorfa7a0e52010-02-10 17:47:19 +00002110
Douglas Gregorb4964f72010-02-15 23:54:17 +00002111 // Import the type.
2112 QualType T = Importer.Import(D->getType());
2113 if (T.isNull())
2114 return 0;
2115
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00002116 // Create the imported variable.
Douglas Gregorfa7a0e52010-02-10 17:47:19 +00002117 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00002118 VarDecl *ToVar = VarDecl::Create(Importer.getToContext(), DC, Loc,
2119 Name.getAsIdentifierInfo(), T, TInfo,
Douglas Gregorc4df4072010-04-19 22:54:31 +00002120 D->getStorageClass(),
2121 D->getStorageClassAsWritten());
John McCall3e11ebe2010-03-15 10:12:16 +00002122 // Import the qualifier, if any.
2123 if (D->getQualifier()) {
2124 NestedNameSpecifier *NNS = Importer.Import(D->getQualifier());
2125 SourceRange NNSRange = Importer.Import(D->getQualifierRange());
2126 ToVar->setQualifierInfo(NNS, NNSRange);
2127 }
Douglas Gregordd483172010-02-22 17:42:47 +00002128 ToVar->setAccess(D->getAccess());
Douglas Gregor62d311f2010-02-09 19:21:46 +00002129 ToVar->setLexicalDeclContext(LexicalDC);
Douglas Gregor8cdbe642010-02-12 23:44:20 +00002130 Importer.Imported(D, ToVar);
Douglas Gregor62d311f2010-02-09 19:21:46 +00002131 LexicalDC->addDecl(ToVar);
2132
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00002133 // Merge the initializer.
2134 // FIXME: Can we really import any initializer? Alternatively, we could force
2135 // ourselves to import every declaration of a variable and then only use
2136 // getInit() here.
Douglas Gregord5058122010-02-11 01:19:42 +00002137 ToVar->setInit(Importer.Import(const_cast<Expr *>(D->getAnyInitializer())));
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00002138
2139 // FIXME: Other bits to merge?
2140
2141 return ToVar;
2142}
2143
Douglas Gregor8b228d72010-02-17 21:22:52 +00002144Decl *ASTNodeImporter::VisitImplicitParamDecl(ImplicitParamDecl *D) {
2145 // Parameters are created in the translation unit's context, then moved
2146 // into the function declaration's context afterward.
2147 DeclContext *DC = Importer.getToContext().getTranslationUnitDecl();
2148
2149 // Import the name of this declaration.
2150 DeclarationName Name = Importer.Import(D->getDeclName());
2151 if (D->getDeclName() && !Name)
2152 return 0;
2153
2154 // Import the location of this declaration.
2155 SourceLocation Loc = Importer.Import(D->getLocation());
2156
2157 // Import the parameter's type.
2158 QualType T = Importer.Import(D->getType());
2159 if (T.isNull())
2160 return 0;
2161
2162 // Create the imported parameter.
2163 ImplicitParamDecl *ToParm
2164 = ImplicitParamDecl::Create(Importer.getToContext(), DC,
2165 Loc, Name.getAsIdentifierInfo(),
2166 T);
2167 return Importer.Imported(D, ToParm);
2168}
2169
Douglas Gregorbb7930c2010-02-10 19:54:31 +00002170Decl *ASTNodeImporter::VisitParmVarDecl(ParmVarDecl *D) {
2171 // Parameters are created in the translation unit's context, then moved
2172 // into the function declaration's context afterward.
2173 DeclContext *DC = Importer.getToContext().getTranslationUnitDecl();
2174
Douglas Gregorfa7a0e52010-02-10 17:47:19 +00002175 // Import the name of this declaration.
2176 DeclarationName Name = Importer.Import(D->getDeclName());
2177 if (D->getDeclName() && !Name)
2178 return 0;
2179
Douglas Gregorbb7930c2010-02-10 19:54:31 +00002180 // Import the location of this declaration.
2181 SourceLocation Loc = Importer.Import(D->getLocation());
2182
2183 // Import the parameter's type.
2184 QualType T = Importer.Import(D->getType());
2185 if (T.isNull())
2186 return 0;
2187
2188 // Create the imported parameter.
2189 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
2190 ParmVarDecl *ToParm = ParmVarDecl::Create(Importer.getToContext(), DC,
2191 Loc, Name.getAsIdentifierInfo(),
2192 T, TInfo, D->getStorageClass(),
Douglas Gregorc4df4072010-04-19 22:54:31 +00002193 D->getStorageClassAsWritten(),
Douglas Gregorbb7930c2010-02-10 19:54:31 +00002194 /*FIXME: Default argument*/ 0);
John McCallf3cd6652010-03-12 18:31:32 +00002195 ToParm->setHasInheritedDefaultArg(D->hasInheritedDefaultArg());
Douglas Gregor8cdbe642010-02-12 23:44:20 +00002196 return Importer.Imported(D, ToParm);
Douglas Gregorbb7930c2010-02-10 19:54:31 +00002197}
2198
Douglas Gregor43f54792010-02-17 02:12:47 +00002199Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
2200 // Import the major distinguishing characteristics of a method.
2201 DeclContext *DC, *LexicalDC;
2202 DeclarationName Name;
2203 SourceLocation Loc;
2204 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2205 return 0;
2206
2207 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
2208 Lookup.first != Lookup.second;
2209 ++Lookup.first) {
2210 if (ObjCMethodDecl *FoundMethod = dyn_cast<ObjCMethodDecl>(*Lookup.first)) {
2211 if (FoundMethod->isInstanceMethod() != D->isInstanceMethod())
2212 continue;
2213
2214 // Check return types.
2215 if (!Importer.IsStructurallyEquivalent(D->getResultType(),
2216 FoundMethod->getResultType())) {
2217 Importer.ToDiag(Loc, diag::err_odr_objc_method_result_type_inconsistent)
2218 << D->isInstanceMethod() << Name
2219 << D->getResultType() << FoundMethod->getResultType();
2220 Importer.ToDiag(FoundMethod->getLocation(),
2221 diag::note_odr_objc_method_here)
2222 << D->isInstanceMethod() << Name;
2223 return 0;
2224 }
2225
2226 // Check the number of parameters.
2227 if (D->param_size() != FoundMethod->param_size()) {
2228 Importer.ToDiag(Loc, diag::err_odr_objc_method_num_params_inconsistent)
2229 << D->isInstanceMethod() << Name
2230 << D->param_size() << FoundMethod->param_size();
2231 Importer.ToDiag(FoundMethod->getLocation(),
2232 diag::note_odr_objc_method_here)
2233 << D->isInstanceMethod() << Name;
2234 return 0;
2235 }
2236
2237 // Check parameter types.
2238 for (ObjCMethodDecl::param_iterator P = D->param_begin(),
2239 PEnd = D->param_end(), FoundP = FoundMethod->param_begin();
2240 P != PEnd; ++P, ++FoundP) {
2241 if (!Importer.IsStructurallyEquivalent((*P)->getType(),
2242 (*FoundP)->getType())) {
2243 Importer.FromDiag((*P)->getLocation(),
2244 diag::err_odr_objc_method_param_type_inconsistent)
2245 << D->isInstanceMethod() << Name
2246 << (*P)->getType() << (*FoundP)->getType();
2247 Importer.ToDiag((*FoundP)->getLocation(), diag::note_odr_value_here)
2248 << (*FoundP)->getType();
2249 return 0;
2250 }
2251 }
2252
2253 // Check variadic/non-variadic.
2254 // Check the number of parameters.
2255 if (D->isVariadic() != FoundMethod->isVariadic()) {
2256 Importer.ToDiag(Loc, diag::err_odr_objc_method_variadic_inconsistent)
2257 << D->isInstanceMethod() << Name;
2258 Importer.ToDiag(FoundMethod->getLocation(),
2259 diag::note_odr_objc_method_here)
2260 << D->isInstanceMethod() << Name;
2261 return 0;
2262 }
2263
2264 // FIXME: Any other bits we need to merge?
2265 return Importer.Imported(D, FoundMethod);
2266 }
2267 }
2268
2269 // Import the result type.
2270 QualType ResultTy = Importer.Import(D->getResultType());
2271 if (ResultTy.isNull())
2272 return 0;
2273
Douglas Gregor12852d92010-03-08 14:59:44 +00002274 TypeSourceInfo *ResultTInfo = Importer.Import(D->getResultTypeSourceInfo());
2275
Douglas Gregor43f54792010-02-17 02:12:47 +00002276 ObjCMethodDecl *ToMethod
2277 = ObjCMethodDecl::Create(Importer.getToContext(),
2278 Loc,
2279 Importer.Import(D->getLocEnd()),
2280 Name.getObjCSelector(),
Douglas Gregor12852d92010-03-08 14:59:44 +00002281 ResultTy, ResultTInfo, DC,
Douglas Gregor43f54792010-02-17 02:12:47 +00002282 D->isInstanceMethod(),
2283 D->isVariadic(),
2284 D->isSynthesized(),
2285 D->getImplementationControl());
2286
2287 // FIXME: When we decide to merge method definitions, we'll need to
2288 // deal with implicit parameters.
2289
2290 // Import the parameters
2291 llvm::SmallVector<ParmVarDecl *, 5> ToParams;
2292 for (ObjCMethodDecl::param_iterator FromP = D->param_begin(),
2293 FromPEnd = D->param_end();
2294 FromP != FromPEnd;
2295 ++FromP) {
2296 ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(*FromP));
2297 if (!ToP)
2298 return 0;
2299
2300 ToParams.push_back(ToP);
2301 }
2302
2303 // Set the parameters.
2304 for (unsigned I = 0, N = ToParams.size(); I != N; ++I) {
2305 ToParams[I]->setOwningFunction(ToMethod);
2306 ToMethod->addDecl(ToParams[I]);
2307 }
2308 ToMethod->setMethodParams(Importer.getToContext(),
Fariborz Jahaniancdabb312010-04-09 15:40:42 +00002309 ToParams.data(), ToParams.size(),
2310 ToParams.size());
Douglas Gregor43f54792010-02-17 02:12:47 +00002311
2312 ToMethod->setLexicalDeclContext(LexicalDC);
2313 Importer.Imported(D, ToMethod);
2314 LexicalDC->addDecl(ToMethod);
2315 return ToMethod;
2316}
2317
Douglas Gregor84c51c32010-02-18 01:47:50 +00002318Decl *ASTNodeImporter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
2319 // Import the major distinguishing characteristics of a category.
2320 DeclContext *DC, *LexicalDC;
2321 DeclarationName Name;
2322 SourceLocation Loc;
2323 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2324 return 0;
2325
2326 ObjCInterfaceDecl *ToInterface
2327 = cast_or_null<ObjCInterfaceDecl>(Importer.Import(D->getClassInterface()));
2328 if (!ToInterface)
2329 return 0;
2330
2331 // Determine if we've already encountered this category.
2332 ObjCCategoryDecl *MergeWithCategory
2333 = ToInterface->FindCategoryDeclaration(Name.getAsIdentifierInfo());
2334 ObjCCategoryDecl *ToCategory = MergeWithCategory;
2335 if (!ToCategory) {
2336 ToCategory = ObjCCategoryDecl::Create(Importer.getToContext(), DC,
2337 Importer.Import(D->getAtLoc()),
2338 Loc,
2339 Importer.Import(D->getCategoryNameLoc()),
2340 Name.getAsIdentifierInfo());
2341 ToCategory->setLexicalDeclContext(LexicalDC);
2342 LexicalDC->addDecl(ToCategory);
2343 Importer.Imported(D, ToCategory);
2344
2345 // Link this category into its class's category list.
2346 ToCategory->setClassInterface(ToInterface);
2347 ToCategory->insertNextClassCategory();
2348
2349 // Import protocols
2350 llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
2351 llvm::SmallVector<SourceLocation, 4> ProtocolLocs;
2352 ObjCCategoryDecl::protocol_loc_iterator FromProtoLoc
2353 = D->protocol_loc_begin();
2354 for (ObjCCategoryDecl::protocol_iterator FromProto = D->protocol_begin(),
2355 FromProtoEnd = D->protocol_end();
2356 FromProto != FromProtoEnd;
2357 ++FromProto, ++FromProtoLoc) {
2358 ObjCProtocolDecl *ToProto
2359 = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
2360 if (!ToProto)
2361 return 0;
2362 Protocols.push_back(ToProto);
2363 ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
2364 }
2365
2366 // FIXME: If we're merging, make sure that the protocol list is the same.
2367 ToCategory->setProtocolList(Protocols.data(), Protocols.size(),
2368 ProtocolLocs.data(), Importer.getToContext());
2369
2370 } else {
2371 Importer.Imported(D, ToCategory);
2372 }
2373
2374 // Import all of the members of this category.
Douglas Gregor968d6332010-02-21 18:24:45 +00002375 ImportDeclContext(D);
Douglas Gregor84c51c32010-02-18 01:47:50 +00002376
2377 // If we have an implementation, import it as well.
2378 if (D->getImplementation()) {
2379 ObjCCategoryImplDecl *Impl
2380 = cast<ObjCCategoryImplDecl>(Importer.Import(D->getImplementation()));
2381 if (!Impl)
2382 return 0;
2383
2384 ToCategory->setImplementation(Impl);
2385 }
2386
2387 return ToCategory;
2388}
2389
Douglas Gregor98d156a2010-02-17 16:12:00 +00002390Decl *ASTNodeImporter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
Douglas Gregor84c51c32010-02-18 01:47:50 +00002391 // Import the major distinguishing characteristics of a protocol.
Douglas Gregor98d156a2010-02-17 16:12:00 +00002392 DeclContext *DC, *LexicalDC;
2393 DeclarationName Name;
2394 SourceLocation Loc;
2395 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2396 return 0;
2397
2398 ObjCProtocolDecl *MergeWithProtocol = 0;
2399 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
2400 Lookup.first != Lookup.second;
2401 ++Lookup.first) {
2402 if (!(*Lookup.first)->isInIdentifierNamespace(Decl::IDNS_ObjCProtocol))
2403 continue;
2404
2405 if ((MergeWithProtocol = dyn_cast<ObjCProtocolDecl>(*Lookup.first)))
2406 break;
2407 }
2408
2409 ObjCProtocolDecl *ToProto = MergeWithProtocol;
2410 if (!ToProto || ToProto->isForwardDecl()) {
2411 if (!ToProto) {
2412 ToProto = ObjCProtocolDecl::Create(Importer.getToContext(), DC, Loc,
2413 Name.getAsIdentifierInfo());
2414 ToProto->setForwardDecl(D->isForwardDecl());
2415 ToProto->setLexicalDeclContext(LexicalDC);
2416 LexicalDC->addDecl(ToProto);
2417 }
2418 Importer.Imported(D, ToProto);
2419
2420 // Import protocols
2421 llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
2422 llvm::SmallVector<SourceLocation, 4> ProtocolLocs;
2423 ObjCProtocolDecl::protocol_loc_iterator
2424 FromProtoLoc = D->protocol_loc_begin();
2425 for (ObjCProtocolDecl::protocol_iterator FromProto = D->protocol_begin(),
2426 FromProtoEnd = D->protocol_end();
2427 FromProto != FromProtoEnd;
2428 ++FromProto, ++FromProtoLoc) {
2429 ObjCProtocolDecl *ToProto
2430 = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
2431 if (!ToProto)
2432 return 0;
2433 Protocols.push_back(ToProto);
2434 ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
2435 }
2436
2437 // FIXME: If we're merging, make sure that the protocol list is the same.
2438 ToProto->setProtocolList(Protocols.data(), Protocols.size(),
2439 ProtocolLocs.data(), Importer.getToContext());
2440 } else {
2441 Importer.Imported(D, ToProto);
2442 }
2443
Douglas Gregor84c51c32010-02-18 01:47:50 +00002444 // Import all of the members of this protocol.
Douglas Gregor968d6332010-02-21 18:24:45 +00002445 ImportDeclContext(D);
Douglas Gregor98d156a2010-02-17 16:12:00 +00002446
2447 return ToProto;
2448}
2449
Douglas Gregor45635322010-02-16 01:20:57 +00002450Decl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
2451 // Import the major distinguishing characteristics of an @interface.
2452 DeclContext *DC, *LexicalDC;
2453 DeclarationName Name;
2454 SourceLocation Loc;
2455 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2456 return 0;
2457
2458 ObjCInterfaceDecl *MergeWithIface = 0;
2459 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
2460 Lookup.first != Lookup.second;
2461 ++Lookup.first) {
2462 if (!(*Lookup.first)->isInIdentifierNamespace(Decl::IDNS_Ordinary))
2463 continue;
2464
2465 if ((MergeWithIface = dyn_cast<ObjCInterfaceDecl>(*Lookup.first)))
2466 break;
2467 }
2468
2469 ObjCInterfaceDecl *ToIface = MergeWithIface;
2470 if (!ToIface || ToIface->isForwardDecl()) {
2471 if (!ToIface) {
2472 ToIface = ObjCInterfaceDecl::Create(Importer.getToContext(),
2473 DC, Loc,
2474 Name.getAsIdentifierInfo(),
2475 Importer.Import(D->getClassLoc()),
2476 D->isForwardDecl(),
2477 D->isImplicitInterfaceDecl());
Douglas Gregor98d156a2010-02-17 16:12:00 +00002478 ToIface->setForwardDecl(D->isForwardDecl());
Douglas Gregor45635322010-02-16 01:20:57 +00002479 ToIface->setLexicalDeclContext(LexicalDC);
2480 LexicalDC->addDecl(ToIface);
2481 }
2482 Importer.Imported(D, ToIface);
2483
Douglas Gregor45635322010-02-16 01:20:57 +00002484 if (D->getSuperClass()) {
2485 ObjCInterfaceDecl *Super
2486 = cast_or_null<ObjCInterfaceDecl>(Importer.Import(D->getSuperClass()));
2487 if (!Super)
2488 return 0;
2489
2490 ToIface->setSuperClass(Super);
2491 ToIface->setSuperClassLoc(Importer.Import(D->getSuperClassLoc()));
2492 }
2493
2494 // Import protocols
2495 llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
2496 llvm::SmallVector<SourceLocation, 4> ProtocolLocs;
2497 ObjCInterfaceDecl::protocol_loc_iterator
2498 FromProtoLoc = D->protocol_loc_begin();
2499 for (ObjCInterfaceDecl::protocol_iterator FromProto = D->protocol_begin(),
2500 FromProtoEnd = D->protocol_end();
2501 FromProto != FromProtoEnd;
2502 ++FromProto, ++FromProtoLoc) {
2503 ObjCProtocolDecl *ToProto
2504 = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
2505 if (!ToProto)
2506 return 0;
2507 Protocols.push_back(ToProto);
2508 ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
2509 }
2510
2511 // FIXME: If we're merging, make sure that the protocol list is the same.
2512 ToIface->setProtocolList(Protocols.data(), Protocols.size(),
2513 ProtocolLocs.data(), Importer.getToContext());
2514
Douglas Gregor45635322010-02-16 01:20:57 +00002515 // Import @end range
2516 ToIface->setAtEndRange(Importer.Import(D->getAtEndRange()));
2517 } else {
2518 Importer.Imported(D, ToIface);
Douglas Gregor7244b0b2010-02-17 00:34:30 +00002519
2520 // Check for consistency of superclasses.
2521 DeclarationName FromSuperName, ToSuperName;
2522 if (D->getSuperClass())
2523 FromSuperName = Importer.Import(D->getSuperClass()->getDeclName());
2524 if (ToIface->getSuperClass())
2525 ToSuperName = ToIface->getSuperClass()->getDeclName();
2526 if (FromSuperName != ToSuperName) {
2527 Importer.ToDiag(ToIface->getLocation(),
2528 diag::err_odr_objc_superclass_inconsistent)
2529 << ToIface->getDeclName();
2530 if (ToIface->getSuperClass())
2531 Importer.ToDiag(ToIface->getSuperClassLoc(),
2532 diag::note_odr_objc_superclass)
2533 << ToIface->getSuperClass()->getDeclName();
2534 else
2535 Importer.ToDiag(ToIface->getLocation(),
2536 diag::note_odr_objc_missing_superclass);
2537 if (D->getSuperClass())
2538 Importer.FromDiag(D->getSuperClassLoc(),
2539 diag::note_odr_objc_superclass)
2540 << D->getSuperClass()->getDeclName();
2541 else
2542 Importer.FromDiag(D->getLocation(),
2543 diag::note_odr_objc_missing_superclass);
2544 return 0;
2545 }
Douglas Gregor45635322010-02-16 01:20:57 +00002546 }
2547
Douglas Gregor84c51c32010-02-18 01:47:50 +00002548 // Import categories. When the categories themselves are imported, they'll
2549 // hook themselves into this interface.
2550 for (ObjCCategoryDecl *FromCat = D->getCategoryList(); FromCat;
2551 FromCat = FromCat->getNextClassCategory())
2552 Importer.Import(FromCat);
2553
Douglas Gregor45635322010-02-16 01:20:57 +00002554 // Import all of the members of this class.
Douglas Gregor968d6332010-02-21 18:24:45 +00002555 ImportDeclContext(D);
Douglas Gregor45635322010-02-16 01:20:57 +00002556
2557 // If we have an @implementation, import it as well.
2558 if (D->getImplementation()) {
2559 ObjCImplementationDecl *Impl
2560 = cast<ObjCImplementationDecl>(Importer.Import(D->getImplementation()));
2561 if (!Impl)
2562 return 0;
2563
2564 ToIface->setImplementation(Impl);
2565 }
2566
Douglas Gregor98d156a2010-02-17 16:12:00 +00002567 return ToIface;
Douglas Gregor45635322010-02-16 01:20:57 +00002568}
2569
Douglas Gregora11c4582010-02-17 18:02:10 +00002570Decl *ASTNodeImporter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
2571 // Import the major distinguishing characteristics of an @property.
2572 DeclContext *DC, *LexicalDC;
2573 DeclarationName Name;
2574 SourceLocation Loc;
2575 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2576 return 0;
2577
2578 // Check whether we have already imported this property.
2579 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
2580 Lookup.first != Lookup.second;
2581 ++Lookup.first) {
2582 if (ObjCPropertyDecl *FoundProp
2583 = dyn_cast<ObjCPropertyDecl>(*Lookup.first)) {
2584 // Check property types.
2585 if (!Importer.IsStructurallyEquivalent(D->getType(),
2586 FoundProp->getType())) {
2587 Importer.ToDiag(Loc, diag::err_odr_objc_property_type_inconsistent)
2588 << Name << D->getType() << FoundProp->getType();
2589 Importer.ToDiag(FoundProp->getLocation(), diag::note_odr_value_here)
2590 << FoundProp->getType();
2591 return 0;
2592 }
2593
2594 // FIXME: Check property attributes, getters, setters, etc.?
2595
2596 // Consider these properties to be equivalent.
2597 Importer.Imported(D, FoundProp);
2598 return FoundProp;
2599 }
2600 }
2601
2602 // Import the type.
2603 QualType T = Importer.Import(D->getType());
2604 if (T.isNull())
2605 return 0;
2606
2607 // Create the new property.
2608 ObjCPropertyDecl *ToProperty
2609 = ObjCPropertyDecl::Create(Importer.getToContext(), DC, Loc,
2610 Name.getAsIdentifierInfo(),
2611 Importer.Import(D->getAtLoc()),
2612 T,
2613 D->getPropertyImplementation());
2614 Importer.Imported(D, ToProperty);
2615 ToProperty->setLexicalDeclContext(LexicalDC);
2616 LexicalDC->addDecl(ToProperty);
2617
2618 ToProperty->setPropertyAttributes(D->getPropertyAttributes());
2619 ToProperty->setGetterName(Importer.Import(D->getGetterName()));
2620 ToProperty->setSetterName(Importer.Import(D->getSetterName()));
2621 ToProperty->setGetterMethodDecl(
2622 cast_or_null<ObjCMethodDecl>(Importer.Import(D->getGetterMethodDecl())));
2623 ToProperty->setSetterMethodDecl(
2624 cast_or_null<ObjCMethodDecl>(Importer.Import(D->getSetterMethodDecl())));
2625 ToProperty->setPropertyIvarDecl(
2626 cast_or_null<ObjCIvarDecl>(Importer.Import(D->getPropertyIvarDecl())));
2627 return ToProperty;
2628}
2629
Douglas Gregor8661a722010-02-18 02:12:22 +00002630Decl *
2631ASTNodeImporter::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) {
2632 // Import the context of this declaration.
2633 DeclContext *DC = Importer.ImportContext(D->getDeclContext());
2634 if (!DC)
2635 return 0;
2636
2637 DeclContext *LexicalDC = DC;
2638 if (D->getDeclContext() != D->getLexicalDeclContext()) {
2639 LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
2640 if (!LexicalDC)
2641 return 0;
2642 }
2643
2644 // Import the location of this declaration.
2645 SourceLocation Loc = Importer.Import(D->getLocation());
2646
2647 llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
2648 llvm::SmallVector<SourceLocation, 4> Locations;
2649 ObjCForwardProtocolDecl::protocol_loc_iterator FromProtoLoc
2650 = D->protocol_loc_begin();
2651 for (ObjCForwardProtocolDecl::protocol_iterator FromProto
2652 = D->protocol_begin(), FromProtoEnd = D->protocol_end();
2653 FromProto != FromProtoEnd;
2654 ++FromProto, ++FromProtoLoc) {
2655 ObjCProtocolDecl *ToProto
2656 = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
2657 if (!ToProto)
2658 continue;
2659
2660 Protocols.push_back(ToProto);
2661 Locations.push_back(Importer.Import(*FromProtoLoc));
2662 }
2663
2664 ObjCForwardProtocolDecl *ToForward
2665 = ObjCForwardProtocolDecl::Create(Importer.getToContext(), DC, Loc,
2666 Protocols.data(), Protocols.size(),
2667 Locations.data());
2668 ToForward->setLexicalDeclContext(LexicalDC);
2669 LexicalDC->addDecl(ToForward);
2670 Importer.Imported(D, ToForward);
2671 return ToForward;
2672}
2673
Douglas Gregor06537af2010-02-18 02:04:09 +00002674Decl *ASTNodeImporter::VisitObjCClassDecl(ObjCClassDecl *D) {
2675 // Import the context of this declaration.
2676 DeclContext *DC = Importer.ImportContext(D->getDeclContext());
2677 if (!DC)
2678 return 0;
2679
2680 DeclContext *LexicalDC = DC;
2681 if (D->getDeclContext() != D->getLexicalDeclContext()) {
2682 LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
2683 if (!LexicalDC)
2684 return 0;
2685 }
2686
2687 // Import the location of this declaration.
2688 SourceLocation Loc = Importer.Import(D->getLocation());
2689
2690 llvm::SmallVector<ObjCInterfaceDecl *, 4> Interfaces;
2691 llvm::SmallVector<SourceLocation, 4> Locations;
2692 for (ObjCClassDecl::iterator From = D->begin(), FromEnd = D->end();
2693 From != FromEnd; ++From) {
2694 ObjCInterfaceDecl *ToIface
2695 = cast_or_null<ObjCInterfaceDecl>(Importer.Import(From->getInterface()));
2696 if (!ToIface)
2697 continue;
2698
2699 Interfaces.push_back(ToIface);
2700 Locations.push_back(Importer.Import(From->getLocation()));
2701 }
2702
2703 ObjCClassDecl *ToClass = ObjCClassDecl::Create(Importer.getToContext(), DC,
2704 Loc,
2705 Interfaces.data(),
2706 Locations.data(),
2707 Interfaces.size());
2708 ToClass->setLexicalDeclContext(LexicalDC);
2709 LexicalDC->addDecl(ToClass);
2710 Importer.Imported(D, ToClass);
2711 return ToClass;
2712}
2713
Douglas Gregor7eeb5972010-02-11 19:21:55 +00002714//----------------------------------------------------------------------------
2715// Import Statements
2716//----------------------------------------------------------------------------
2717
2718Stmt *ASTNodeImporter::VisitStmt(Stmt *S) {
2719 Importer.FromDiag(S->getLocStart(), diag::err_unsupported_ast_node)
2720 << S->getStmtClassName();
2721 return 0;
2722}
2723
2724//----------------------------------------------------------------------------
2725// Import Expressions
2726//----------------------------------------------------------------------------
2727Expr *ASTNodeImporter::VisitExpr(Expr *E) {
2728 Importer.FromDiag(E->getLocStart(), diag::err_unsupported_ast_node)
2729 << E->getStmtClassName();
2730 return 0;
2731}
2732
Douglas Gregor52f820e2010-02-19 01:17:02 +00002733Expr *ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) {
2734 NestedNameSpecifier *Qualifier = 0;
2735 if (E->getQualifier()) {
2736 Qualifier = Importer.Import(E->getQualifier());
2737 if (!E->getQualifier())
2738 return 0;
2739 }
2740
2741 ValueDecl *ToD = cast_or_null<ValueDecl>(Importer.Import(E->getDecl()));
2742 if (!ToD)
2743 return 0;
2744
2745 QualType T = Importer.Import(E->getType());
2746 if (T.isNull())
2747 return 0;
2748
2749 return DeclRefExpr::Create(Importer.getToContext(), Qualifier,
2750 Importer.Import(E->getQualifierRange()),
2751 ToD,
2752 Importer.Import(E->getLocation()),
2753 T,
2754 /*FIXME:TemplateArgs=*/0);
2755}
2756
Douglas Gregor7eeb5972010-02-11 19:21:55 +00002757Expr *ASTNodeImporter::VisitIntegerLiteral(IntegerLiteral *E) {
2758 QualType T = Importer.Import(E->getType());
2759 if (T.isNull())
2760 return 0;
2761
2762 return new (Importer.getToContext())
2763 IntegerLiteral(E->getValue(), T, Importer.Import(E->getLocation()));
2764}
2765
Douglas Gregor623421d2010-02-18 02:21:22 +00002766Expr *ASTNodeImporter::VisitCharacterLiteral(CharacterLiteral *E) {
2767 QualType T = Importer.Import(E->getType());
2768 if (T.isNull())
2769 return 0;
2770
2771 return new (Importer.getToContext()) CharacterLiteral(E->getValue(),
2772 E->isWide(), T,
2773 Importer.Import(E->getLocation()));
2774}
2775
Douglas Gregorc74247e2010-02-19 01:07:06 +00002776Expr *ASTNodeImporter::VisitParenExpr(ParenExpr *E) {
2777 Expr *SubExpr = Importer.Import(E->getSubExpr());
2778 if (!SubExpr)
2779 return 0;
2780
2781 return new (Importer.getToContext())
2782 ParenExpr(Importer.Import(E->getLParen()),
2783 Importer.Import(E->getRParen()),
2784 SubExpr);
2785}
2786
2787Expr *ASTNodeImporter::VisitUnaryOperator(UnaryOperator *E) {
2788 QualType T = Importer.Import(E->getType());
2789 if (T.isNull())
2790 return 0;
2791
2792 Expr *SubExpr = Importer.Import(E->getSubExpr());
2793 if (!SubExpr)
2794 return 0;
2795
2796 return new (Importer.getToContext()) UnaryOperator(SubExpr, E->getOpcode(),
2797 T,
2798 Importer.Import(E->getOperatorLoc()));
2799}
2800
Douglas Gregord8552cd2010-02-19 01:24:23 +00002801Expr *ASTNodeImporter::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
2802 QualType ResultType = Importer.Import(E->getType());
2803
2804 if (E->isArgumentType()) {
2805 TypeSourceInfo *TInfo = Importer.Import(E->getArgumentTypeInfo());
2806 if (!TInfo)
2807 return 0;
2808
2809 return new (Importer.getToContext()) SizeOfAlignOfExpr(E->isSizeOf(),
2810 TInfo, ResultType,
2811 Importer.Import(E->getOperatorLoc()),
2812 Importer.Import(E->getRParenLoc()));
2813 }
2814
2815 Expr *SubExpr = Importer.Import(E->getArgumentExpr());
2816 if (!SubExpr)
2817 return 0;
2818
2819 return new (Importer.getToContext()) SizeOfAlignOfExpr(E->isSizeOf(),
2820 SubExpr, ResultType,
2821 Importer.Import(E->getOperatorLoc()),
2822 Importer.Import(E->getRParenLoc()));
2823}
2824
Douglas Gregorc74247e2010-02-19 01:07:06 +00002825Expr *ASTNodeImporter::VisitBinaryOperator(BinaryOperator *E) {
2826 QualType T = Importer.Import(E->getType());
2827 if (T.isNull())
2828 return 0;
2829
2830 Expr *LHS = Importer.Import(E->getLHS());
2831 if (!LHS)
2832 return 0;
2833
2834 Expr *RHS = Importer.Import(E->getRHS());
2835 if (!RHS)
2836 return 0;
2837
2838 return new (Importer.getToContext()) BinaryOperator(LHS, RHS, E->getOpcode(),
2839 T,
2840 Importer.Import(E->getOperatorLoc()));
2841}
2842
2843Expr *ASTNodeImporter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
2844 QualType T = Importer.Import(E->getType());
2845 if (T.isNull())
2846 return 0;
2847
2848 QualType CompLHSType = Importer.Import(E->getComputationLHSType());
2849 if (CompLHSType.isNull())
2850 return 0;
2851
2852 QualType CompResultType = Importer.Import(E->getComputationResultType());
2853 if (CompResultType.isNull())
2854 return 0;
2855
2856 Expr *LHS = Importer.Import(E->getLHS());
2857 if (!LHS)
2858 return 0;
2859
2860 Expr *RHS = Importer.Import(E->getRHS());
2861 if (!RHS)
2862 return 0;
2863
2864 return new (Importer.getToContext())
2865 CompoundAssignOperator(LHS, RHS, E->getOpcode(),
2866 T, CompLHSType, CompResultType,
2867 Importer.Import(E->getOperatorLoc()));
2868}
2869
Douglas Gregor98c10182010-02-12 22:17:39 +00002870Expr *ASTNodeImporter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
2871 QualType T = Importer.Import(E->getType());
2872 if (T.isNull())
2873 return 0;
2874
2875 Expr *SubExpr = Importer.Import(E->getSubExpr());
2876 if (!SubExpr)
2877 return 0;
2878
Anders Carlsson0c509ee2010-04-24 16:57:13 +00002879 // FIXME: Initialize the base path.
Anders Carlsson5d270e82010-04-24 18:38:56 +00002880 assert(E->getBasePath().empty() && "FIXME: Must copy base path!");
Anders Carlsson0c509ee2010-04-24 16:57:13 +00002881 CXXBaseSpecifierArray BasePath;
Douglas Gregor98c10182010-02-12 22:17:39 +00002882 return new (Importer.getToContext()) ImplicitCastExpr(T, E->getCastKind(),
Anders Carlsson0c509ee2010-04-24 16:57:13 +00002883 SubExpr, BasePath,
Douglas Gregor98c10182010-02-12 22:17:39 +00002884 E->isLvalueCast());
2885}
2886
Douglas Gregor5481d322010-02-19 01:32:14 +00002887Expr *ASTNodeImporter::VisitCStyleCastExpr(CStyleCastExpr *E) {
2888 QualType T = Importer.Import(E->getType());
2889 if (T.isNull())
2890 return 0;
2891
2892 Expr *SubExpr = Importer.Import(E->getSubExpr());
2893 if (!SubExpr)
2894 return 0;
2895
2896 TypeSourceInfo *TInfo = Importer.Import(E->getTypeInfoAsWritten());
2897 if (!TInfo && E->getTypeInfoAsWritten())
2898 return 0;
2899
Anders Carlsson5d270e82010-04-24 18:38:56 +00002900 // FIXME: Initialize the base path.
2901 assert(E->getBasePath().empty() && "FIXME: Must copy base path!");
2902 CXXBaseSpecifierArray BasePath;
Douglas Gregor5481d322010-02-19 01:32:14 +00002903 return new (Importer.getToContext()) CStyleCastExpr(T, E->getCastKind(),
Anders Carlsson5d270e82010-04-24 18:38:56 +00002904 SubExpr, BasePath, TInfo,
Douglas Gregor5481d322010-02-19 01:32:14 +00002905 Importer.Import(E->getLParenLoc()),
2906 Importer.Import(E->getRParenLoc()));
2907}
2908
Douglas Gregor7eeb5972010-02-11 19:21:55 +00002909ASTImporter::ASTImporter(Diagnostic &Diags,
2910 ASTContext &ToContext, FileManager &ToFileManager,
2911 ASTContext &FromContext, FileManager &FromFileManager)
Douglas Gregor96e578d2010-02-05 17:54:41 +00002912 : ToContext(ToContext), FromContext(FromContext),
Douglas Gregor811663e2010-02-10 00:15:17 +00002913 ToFileManager(ToFileManager), FromFileManager(FromFileManager),
Douglas Gregor7eeb5972010-02-11 19:21:55 +00002914 Diags(Diags) {
Douglas Gregor62d311f2010-02-09 19:21:46 +00002915 ImportedDecls[FromContext.getTranslationUnitDecl()]
2916 = ToContext.getTranslationUnitDecl();
2917}
2918
2919ASTImporter::~ASTImporter() { }
Douglas Gregor96e578d2010-02-05 17:54:41 +00002920
2921QualType ASTImporter::Import(QualType FromT) {
2922 if (FromT.isNull())
2923 return QualType();
2924
Douglas Gregorf65bbb32010-02-08 15:18:58 +00002925 // Check whether we've already imported this type.
2926 llvm::DenseMap<Type *, Type *>::iterator Pos
2927 = ImportedTypes.find(FromT.getTypePtr());
2928 if (Pos != ImportedTypes.end())
2929 return ToContext.getQualifiedType(Pos->second, FromT.getQualifiers());
Douglas Gregor96e578d2010-02-05 17:54:41 +00002930
Douglas Gregorf65bbb32010-02-08 15:18:58 +00002931 // Import the type
Douglas Gregor96e578d2010-02-05 17:54:41 +00002932 ASTNodeImporter Importer(*this);
2933 QualType ToT = Importer.Visit(FromT.getTypePtr());
2934 if (ToT.isNull())
2935 return ToT;
2936
Douglas Gregorf65bbb32010-02-08 15:18:58 +00002937 // Record the imported type.
2938 ImportedTypes[FromT.getTypePtr()] = ToT.getTypePtr();
2939
Douglas Gregor96e578d2010-02-05 17:54:41 +00002940 return ToContext.getQualifiedType(ToT, FromT.getQualifiers());
2941}
2942
Douglas Gregor62d311f2010-02-09 19:21:46 +00002943TypeSourceInfo *ASTImporter::Import(TypeSourceInfo *FromTSI) {
Douglas Gregorfa7a0e52010-02-10 17:47:19 +00002944 if (!FromTSI)
2945 return FromTSI;
2946
2947 // FIXME: For now we just create a "trivial" type source info based
2948 // on the type and a seingle location. Implement a real version of
2949 // this.
2950 QualType T = Import(FromTSI->getType());
2951 if (T.isNull())
2952 return 0;
2953
2954 return ToContext.getTrivialTypeSourceInfo(T,
2955 FromTSI->getTypeLoc().getFullSourceRange().getBegin());
Douglas Gregor62d311f2010-02-09 19:21:46 +00002956}
2957
2958Decl *ASTImporter::Import(Decl *FromD) {
2959 if (!FromD)
2960 return 0;
2961
2962 // Check whether we've already imported this declaration.
2963 llvm::DenseMap<Decl *, Decl *>::iterator Pos = ImportedDecls.find(FromD);
2964 if (Pos != ImportedDecls.end())
2965 return Pos->second;
2966
2967 // Import the type
2968 ASTNodeImporter Importer(*this);
2969 Decl *ToD = Importer.Visit(FromD);
2970 if (!ToD)
2971 return 0;
2972
2973 // Record the imported declaration.
2974 ImportedDecls[FromD] = ToD;
Douglas Gregorb4964f72010-02-15 23:54:17 +00002975
2976 if (TagDecl *FromTag = dyn_cast<TagDecl>(FromD)) {
2977 // Keep track of anonymous tags that have an associated typedef.
2978 if (FromTag->getTypedefForAnonDecl())
2979 AnonTagsWithPendingTypedefs.push_back(FromTag);
2980 } else if (TypedefDecl *FromTypedef = dyn_cast<TypedefDecl>(FromD)) {
2981 // When we've finished transforming a typedef, see whether it was the
2982 // typedef for an anonymous tag.
2983 for (llvm::SmallVector<TagDecl *, 4>::iterator
2984 FromTag = AnonTagsWithPendingTypedefs.begin(),
2985 FromTagEnd = AnonTagsWithPendingTypedefs.end();
2986 FromTag != FromTagEnd; ++FromTag) {
2987 if ((*FromTag)->getTypedefForAnonDecl() == FromTypedef) {
2988 if (TagDecl *ToTag = cast_or_null<TagDecl>(Import(*FromTag))) {
2989 // We found the typedef for an anonymous tag; link them.
2990 ToTag->setTypedefForAnonDecl(cast<TypedefDecl>(ToD));
2991 AnonTagsWithPendingTypedefs.erase(FromTag);
2992 break;
2993 }
2994 }
2995 }
2996 }
2997
Douglas Gregor62d311f2010-02-09 19:21:46 +00002998 return ToD;
2999}
3000
3001DeclContext *ASTImporter::ImportContext(DeclContext *FromDC) {
3002 if (!FromDC)
3003 return FromDC;
3004
3005 return cast_or_null<DeclContext>(Import(cast<Decl>(FromDC)));
3006}
3007
3008Expr *ASTImporter::Import(Expr *FromE) {
3009 if (!FromE)
3010 return 0;
3011
3012 return cast_or_null<Expr>(Import(cast<Stmt>(FromE)));
3013}
3014
3015Stmt *ASTImporter::Import(Stmt *FromS) {
3016 if (!FromS)
3017 return 0;
3018
Douglas Gregor7eeb5972010-02-11 19:21:55 +00003019 // Check whether we've already imported this declaration.
3020 llvm::DenseMap<Stmt *, Stmt *>::iterator Pos = ImportedStmts.find(FromS);
3021 if (Pos != ImportedStmts.end())
3022 return Pos->second;
3023
3024 // Import the type
3025 ASTNodeImporter Importer(*this);
3026 Stmt *ToS = Importer.Visit(FromS);
3027 if (!ToS)
3028 return 0;
3029
3030 // Record the imported declaration.
3031 ImportedStmts[FromS] = ToS;
3032 return ToS;
Douglas Gregor62d311f2010-02-09 19:21:46 +00003033}
3034
3035NestedNameSpecifier *ASTImporter::Import(NestedNameSpecifier *FromNNS) {
3036 if (!FromNNS)
3037 return 0;
3038
3039 // FIXME: Implement!
3040 return 0;
3041}
3042
3043SourceLocation ASTImporter::Import(SourceLocation FromLoc) {
3044 if (FromLoc.isInvalid())
3045 return SourceLocation();
3046
Douglas Gregor811663e2010-02-10 00:15:17 +00003047 SourceManager &FromSM = FromContext.getSourceManager();
3048
3049 // For now, map everything down to its spelling location, so that we
3050 // don't have to import macro instantiations.
3051 // FIXME: Import macro instantiations!
3052 FromLoc = FromSM.getSpellingLoc(FromLoc);
3053 std::pair<FileID, unsigned> Decomposed = FromSM.getDecomposedLoc(FromLoc);
3054 SourceManager &ToSM = ToContext.getSourceManager();
3055 return ToSM.getLocForStartOfFile(Import(Decomposed.first))
3056 .getFileLocWithOffset(Decomposed.second);
Douglas Gregor62d311f2010-02-09 19:21:46 +00003057}
3058
3059SourceRange ASTImporter::Import(SourceRange FromRange) {
3060 return SourceRange(Import(FromRange.getBegin()), Import(FromRange.getEnd()));
3061}
3062
Douglas Gregor811663e2010-02-10 00:15:17 +00003063FileID ASTImporter::Import(FileID FromID) {
3064 llvm::DenseMap<unsigned, FileID>::iterator Pos
3065 = ImportedFileIDs.find(FromID.getHashValue());
3066 if (Pos != ImportedFileIDs.end())
3067 return Pos->second;
3068
3069 SourceManager &FromSM = FromContext.getSourceManager();
3070 SourceManager &ToSM = ToContext.getSourceManager();
3071 const SrcMgr::SLocEntry &FromSLoc = FromSM.getSLocEntry(FromID);
3072 assert(FromSLoc.isFile() && "Cannot handle macro instantiations yet");
3073
3074 // Include location of this file.
3075 SourceLocation ToIncludeLoc = Import(FromSLoc.getFile().getIncludeLoc());
3076
3077 // Map the FileID for to the "to" source manager.
3078 FileID ToID;
3079 const SrcMgr::ContentCache *Cache = FromSLoc.getFile().getContentCache();
3080 if (Cache->Entry) {
3081 // FIXME: We probably want to use getVirtualFile(), so we don't hit the
3082 // disk again
3083 // FIXME: We definitely want to re-use the existing MemoryBuffer, rather
3084 // than mmap the files several times.
3085 const FileEntry *Entry = ToFileManager.getFile(Cache->Entry->getName());
3086 ToID = ToSM.createFileID(Entry, ToIncludeLoc,
3087 FromSLoc.getFile().getFileCharacteristic());
3088 } else {
3089 // FIXME: We want to re-use the existing MemoryBuffer!
Chris Lattnerfb24a3a2010-04-20 20:35:58 +00003090 const llvm::MemoryBuffer *FromBuf = Cache->getBuffer(getDiags(), FromSM);
Douglas Gregor811663e2010-02-10 00:15:17 +00003091 llvm::MemoryBuffer *ToBuf
Chris Lattner58c79342010-04-05 22:42:27 +00003092 = llvm::MemoryBuffer::getMemBufferCopy(FromBuf->getBuffer(),
Douglas Gregor811663e2010-02-10 00:15:17 +00003093 FromBuf->getBufferIdentifier());
3094 ToID = ToSM.createFileIDForMemBuffer(ToBuf);
3095 }
3096
3097
3098 ImportedFileIDs[FromID.getHashValue()] = ToID;
3099 return ToID;
3100}
3101
Douglas Gregor96e578d2010-02-05 17:54:41 +00003102DeclarationName ASTImporter::Import(DeclarationName FromName) {
3103 if (!FromName)
3104 return DeclarationName();
3105
3106 switch (FromName.getNameKind()) {
3107 case DeclarationName::Identifier:
3108 return Import(FromName.getAsIdentifierInfo());
3109
3110 case DeclarationName::ObjCZeroArgSelector:
3111 case DeclarationName::ObjCOneArgSelector:
3112 case DeclarationName::ObjCMultiArgSelector:
3113 return Import(FromName.getObjCSelector());
3114
3115 case DeclarationName::CXXConstructorName: {
3116 QualType T = Import(FromName.getCXXNameType());
3117 if (T.isNull())
3118 return DeclarationName();
3119
3120 return ToContext.DeclarationNames.getCXXConstructorName(
3121 ToContext.getCanonicalType(T));
3122 }
3123
3124 case DeclarationName::CXXDestructorName: {
3125 QualType T = Import(FromName.getCXXNameType());
3126 if (T.isNull())
3127 return DeclarationName();
3128
3129 return ToContext.DeclarationNames.getCXXDestructorName(
3130 ToContext.getCanonicalType(T));
3131 }
3132
3133 case DeclarationName::CXXConversionFunctionName: {
3134 QualType T = Import(FromName.getCXXNameType());
3135 if (T.isNull())
3136 return DeclarationName();
3137
3138 return ToContext.DeclarationNames.getCXXConversionFunctionName(
3139 ToContext.getCanonicalType(T));
3140 }
3141
3142 case DeclarationName::CXXOperatorName:
3143 return ToContext.DeclarationNames.getCXXOperatorName(
3144 FromName.getCXXOverloadedOperator());
3145
3146 case DeclarationName::CXXLiteralOperatorName:
3147 return ToContext.DeclarationNames.getCXXLiteralOperatorName(
3148 Import(FromName.getCXXLiteralIdentifier()));
3149
3150 case DeclarationName::CXXUsingDirective:
3151 // FIXME: STATICS!
3152 return DeclarationName::getUsingDirectiveName();
3153 }
3154
3155 // Silence bogus GCC warning
3156 return DeclarationName();
3157}
3158
3159IdentifierInfo *ASTImporter::Import(IdentifierInfo *FromId) {
3160 if (!FromId)
3161 return 0;
3162
3163 return &ToContext.Idents.get(FromId->getName());
3164}
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00003165
Douglas Gregor43f54792010-02-17 02:12:47 +00003166Selector ASTImporter::Import(Selector FromSel) {
3167 if (FromSel.isNull())
3168 return Selector();
3169
3170 llvm::SmallVector<IdentifierInfo *, 4> Idents;
3171 Idents.push_back(Import(FromSel.getIdentifierInfoForSlot(0)));
3172 for (unsigned I = 1, N = FromSel.getNumArgs(); I < N; ++I)
3173 Idents.push_back(Import(FromSel.getIdentifierInfoForSlot(I)));
3174 return ToContext.Selectors.getSelector(FromSel.getNumArgs(), Idents.data());
3175}
3176
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00003177DeclarationName ASTImporter::HandleNameConflict(DeclarationName Name,
3178 DeclContext *DC,
3179 unsigned IDNS,
3180 NamedDecl **Decls,
3181 unsigned NumDecls) {
3182 return Name;
3183}
3184
3185DiagnosticBuilder ASTImporter::ToDiag(SourceLocation Loc, unsigned DiagID) {
Douglas Gregor7eeb5972010-02-11 19:21:55 +00003186 return Diags.Report(FullSourceLoc(Loc, ToContext.getSourceManager()),
3187 DiagID);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00003188}
3189
3190DiagnosticBuilder ASTImporter::FromDiag(SourceLocation Loc, unsigned DiagID) {
Douglas Gregor7eeb5972010-02-11 19:21:55 +00003191 return Diags.Report(FullSourceLoc(Loc, FromContext.getSourceManager()),
3192 DiagID);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00003193}
Douglas Gregor8cdbe642010-02-12 23:44:20 +00003194
3195Decl *ASTImporter::Imported(Decl *From, Decl *To) {
3196 ImportedDecls[From] = To;
3197 return To;
Daniel Dunbar9ced5422010-02-13 20:24:39 +00003198}
Douglas Gregorb4964f72010-02-15 23:54:17 +00003199
3200bool ASTImporter::IsStructurallyEquivalent(QualType From, QualType To) {
3201 llvm::DenseMap<Type *, Type *>::iterator Pos
3202 = ImportedTypes.find(From.getTypePtr());
3203 if (Pos != ImportedTypes.end() && ToContext.hasSameType(Import(From), To))
3204 return true;
3205
Benjamin Kramer26d19c52010-02-18 13:02:13 +00003206 StructuralEquivalenceContext Ctx(FromContext, ToContext, Diags,
Douglas Gregorb4964f72010-02-15 23:54:17 +00003207 NonEquivalentDecls);
Benjamin Kramer26d19c52010-02-18 13:02:13 +00003208 return Ctx.IsStructurallyEquivalent(From, To);
Douglas Gregorb4964f72010-02-15 23:54:17 +00003209}