blob: 7b00b9f73ba451385294dcff0ec0bbaa7613c887 [file] [log] [blame]
Douglas Gregor1b2949d2010-02-05 17:54:41 +00001//===--- ASTImporter.cpp - Importing ASTs from other Contexts ---*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the ASTImporter class which imports AST nodes from one
11// context into another context.
12//
13//===----------------------------------------------------------------------===//
14#include "clang/AST/ASTImporter.h"
15
16#include "clang/AST/ASTContext.h"
Douglas Gregor88523732010-02-10 00:15:17 +000017#include "clang/AST/ASTDiagnostic.h"
Douglas Gregor96a01b42010-02-11 00:48:18 +000018#include "clang/AST/DeclCXX.h"
Douglas Gregor1b2949d2010-02-05 17:54:41 +000019#include "clang/AST/DeclObjC.h"
Douglas Gregor089459a2010-02-08 21:09:39 +000020#include "clang/AST/DeclVisitor.h"
Douglas Gregor4800d952010-02-11 19:21:55 +000021#include "clang/AST/StmtVisitor.h"
Douglas Gregor82fc4bf2010-02-10 17:47:19 +000022#include "clang/AST/TypeLoc.h"
Douglas Gregor1b2949d2010-02-05 17:54:41 +000023#include "clang/AST/TypeVisitor.h"
Douglas Gregor88523732010-02-10 00:15:17 +000024#include "clang/Basic/FileManager.h"
25#include "clang/Basic/SourceManager.h"
26#include "llvm/Support/MemoryBuffer.h"
Douglas Gregor1b2949d2010-02-05 17:54:41 +000027
28using namespace clang;
29
30namespace {
Douglas Gregor089459a2010-02-08 21:09:39 +000031 class ASTNodeImporter : public TypeVisitor<ASTNodeImporter, QualType>,
Douglas Gregor4800d952010-02-11 19:21:55 +000032 public DeclVisitor<ASTNodeImporter, Decl *>,
33 public StmtVisitor<ASTNodeImporter, Stmt *> {
Douglas Gregor1b2949d2010-02-05 17:54:41 +000034 ASTImporter &Importer;
35
36 public:
37 explicit ASTNodeImporter(ASTImporter &Importer) : Importer(Importer) { }
38
39 using TypeVisitor<ASTNodeImporter, QualType>::Visit;
Douglas Gregor9bed8792010-02-09 19:21:46 +000040 using DeclVisitor<ASTNodeImporter, Decl *>::Visit;
Douglas Gregor4800d952010-02-11 19:21:55 +000041 using StmtVisitor<ASTNodeImporter, Stmt *>::Visit;
Douglas Gregor1b2949d2010-02-05 17:54:41 +000042
43 // Importing types
Douglas Gregor89cc9d62010-02-09 22:48:33 +000044 QualType VisitType(Type *T);
Douglas Gregor1b2949d2010-02-05 17:54:41 +000045 QualType VisitBuiltinType(BuiltinType *T);
46 QualType VisitComplexType(ComplexType *T);
47 QualType VisitPointerType(PointerType *T);
48 QualType VisitBlockPointerType(BlockPointerType *T);
49 QualType VisitLValueReferenceType(LValueReferenceType *T);
50 QualType VisitRValueReferenceType(RValueReferenceType *T);
51 QualType VisitMemberPointerType(MemberPointerType *T);
52 QualType VisitConstantArrayType(ConstantArrayType *T);
53 QualType VisitIncompleteArrayType(IncompleteArrayType *T);
54 QualType VisitVariableArrayType(VariableArrayType *T);
55 // FIXME: DependentSizedArrayType
56 // FIXME: DependentSizedExtVectorType
57 QualType VisitVectorType(VectorType *T);
58 QualType VisitExtVectorType(ExtVectorType *T);
59 QualType VisitFunctionNoProtoType(FunctionNoProtoType *T);
60 QualType VisitFunctionProtoType(FunctionProtoType *T);
61 // FIXME: UnresolvedUsingType
62 QualType VisitTypedefType(TypedefType *T);
63 QualType VisitTypeOfExprType(TypeOfExprType *T);
64 // FIXME: DependentTypeOfExprType
65 QualType VisitTypeOfType(TypeOfType *T);
66 QualType VisitDecltypeType(DecltypeType *T);
67 // FIXME: DependentDecltypeType
68 QualType VisitRecordType(RecordType *T);
69 QualType VisitEnumType(EnumType *T);
70 QualType VisitElaboratedType(ElaboratedType *T);
71 // FIXME: TemplateTypeParmType
72 // FIXME: SubstTemplateTypeParmType
73 // FIXME: TemplateSpecializationType
74 QualType VisitQualifiedNameType(QualifiedNameType *T);
75 // FIXME: TypenameType
76 QualType VisitObjCInterfaceType(ObjCInterfaceType *T);
77 QualType VisitObjCObjectPointerType(ObjCObjectPointerType *T);
Douglas Gregor089459a2010-02-08 21:09:39 +000078
79 // Importing declarations
Douglas Gregora404ea62010-02-10 19:54:31 +000080 bool ImportDeclParts(NamedDecl *D, DeclContext *&DC,
81 DeclContext *&LexicalDC, DeclarationName &Name,
82 SourceLocation &Loc);
Douglas Gregor36ead2e2010-02-12 22:17:39 +000083 bool ImportDeclParts(ValueDecl *D,
Douglas Gregora404ea62010-02-10 19:54:31 +000084 DeclContext *&DC, DeclContext *&LexicalDC,
85 DeclarationName &Name, SourceLocation &Loc,
86 QualType &T);
Douglas Gregor96a01b42010-02-11 00:48:18 +000087 bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord);
Douglas Gregor36ead2e2010-02-12 22:17:39 +000088 bool IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToEnum);
Douglas Gregor89cc9d62010-02-09 22:48:33 +000089 Decl *VisitDecl(Decl *D);
Douglas Gregor9e5d9962010-02-10 21:10:29 +000090 Decl *VisitTypedefDecl(TypedefDecl *D);
Douglas Gregor36ead2e2010-02-12 22:17:39 +000091 Decl *VisitEnumDecl(EnumDecl *D);
Douglas Gregor96a01b42010-02-11 00:48:18 +000092 Decl *VisitRecordDecl(RecordDecl *D);
Douglas Gregor36ead2e2010-02-12 22:17:39 +000093 Decl *VisitEnumConstantDecl(EnumConstantDecl *D);
Douglas Gregora404ea62010-02-10 19:54:31 +000094 Decl *VisitFunctionDecl(FunctionDecl *D);
Douglas Gregor96a01b42010-02-11 00:48:18 +000095 Decl *VisitFieldDecl(FieldDecl *D);
Douglas Gregor089459a2010-02-08 21:09:39 +000096 Decl *VisitVarDecl(VarDecl *D);
Douglas Gregora404ea62010-02-10 19:54:31 +000097 Decl *VisitParmVarDecl(ParmVarDecl *D);
Douglas Gregor4800d952010-02-11 19:21:55 +000098
99 // Importing statements
100 Stmt *VisitStmt(Stmt *S);
101
102 // Importing expressions
103 Expr *VisitExpr(Expr *E);
104 Expr *VisitIntegerLiteral(IntegerLiteral *E);
Douglas Gregor36ead2e2010-02-12 22:17:39 +0000105 Expr *VisitImplicitCastExpr(ImplicitCastExpr *E);
Douglas Gregor1b2949d2010-02-05 17:54:41 +0000106 };
107}
108
109//----------------------------------------------------------------------------
110// Import Types
111//----------------------------------------------------------------------------
112
Douglas Gregor89cc9d62010-02-09 22:48:33 +0000113QualType ASTNodeImporter::VisitType(Type *T) {
114 Importer.FromDiag(SourceLocation(), diag::err_unsupported_ast_node)
115 << T->getTypeClassName();
116 return QualType();
117}
118
Douglas Gregor1b2949d2010-02-05 17:54:41 +0000119QualType ASTNodeImporter::VisitBuiltinType(BuiltinType *T) {
120 switch (T->getKind()) {
121 case BuiltinType::Void: return Importer.getToContext().VoidTy;
122 case BuiltinType::Bool: return Importer.getToContext().BoolTy;
123
124 case BuiltinType::Char_U:
125 // The context we're importing from has an unsigned 'char'. If we're
126 // importing into a context with a signed 'char', translate to
127 // 'unsigned char' instead.
128 if (Importer.getToContext().getLangOptions().CharIsSigned)
129 return Importer.getToContext().UnsignedCharTy;
130
131 return Importer.getToContext().CharTy;
132
133 case BuiltinType::UChar: return Importer.getToContext().UnsignedCharTy;
134
135 case BuiltinType::Char16:
136 // FIXME: Make sure that the "to" context supports C++!
137 return Importer.getToContext().Char16Ty;
138
139 case BuiltinType::Char32:
140 // FIXME: Make sure that the "to" context supports C++!
141 return Importer.getToContext().Char32Ty;
142
143 case BuiltinType::UShort: return Importer.getToContext().UnsignedShortTy;
144 case BuiltinType::UInt: return Importer.getToContext().UnsignedIntTy;
145 case BuiltinType::ULong: return Importer.getToContext().UnsignedLongTy;
146 case BuiltinType::ULongLong:
147 return Importer.getToContext().UnsignedLongLongTy;
148 case BuiltinType::UInt128: return Importer.getToContext().UnsignedInt128Ty;
149
150 case BuiltinType::Char_S:
151 // The context we're importing from has an unsigned 'char'. If we're
152 // importing into a context with a signed 'char', translate to
153 // 'unsigned char' instead.
154 if (!Importer.getToContext().getLangOptions().CharIsSigned)
155 return Importer.getToContext().SignedCharTy;
156
157 return Importer.getToContext().CharTy;
158
159 case BuiltinType::SChar: return Importer.getToContext().SignedCharTy;
160 case BuiltinType::WChar:
161 // FIXME: If not in C++, shall we translate to the C equivalent of
162 // wchar_t?
163 return Importer.getToContext().WCharTy;
164
165 case BuiltinType::Short : return Importer.getToContext().ShortTy;
166 case BuiltinType::Int : return Importer.getToContext().IntTy;
167 case BuiltinType::Long : return Importer.getToContext().LongTy;
168 case BuiltinType::LongLong : return Importer.getToContext().LongLongTy;
169 case BuiltinType::Int128 : return Importer.getToContext().Int128Ty;
170 case BuiltinType::Float: return Importer.getToContext().FloatTy;
171 case BuiltinType::Double: return Importer.getToContext().DoubleTy;
172 case BuiltinType::LongDouble: return Importer.getToContext().LongDoubleTy;
173
174 case BuiltinType::NullPtr:
175 // FIXME: Make sure that the "to" context supports C++0x!
176 return Importer.getToContext().NullPtrTy;
177
178 case BuiltinType::Overload: return Importer.getToContext().OverloadTy;
179 case BuiltinType::Dependent: return Importer.getToContext().DependentTy;
180 case BuiltinType::UndeducedAuto:
181 // FIXME: Make sure that the "to" context supports C++0x!
182 return Importer.getToContext().UndeducedAutoTy;
183
184 case BuiltinType::ObjCId:
185 // FIXME: Make sure that the "to" context supports Objective-C!
186 return Importer.getToContext().ObjCBuiltinIdTy;
187
188 case BuiltinType::ObjCClass:
189 return Importer.getToContext().ObjCBuiltinClassTy;
190
191 case BuiltinType::ObjCSel:
192 return Importer.getToContext().ObjCBuiltinSelTy;
193 }
194
195 return QualType();
196}
197
198QualType ASTNodeImporter::VisitComplexType(ComplexType *T) {
199 QualType ToElementType = Importer.Import(T->getElementType());
200 if (ToElementType.isNull())
201 return QualType();
202
203 return Importer.getToContext().getComplexType(ToElementType);
204}
205
206QualType ASTNodeImporter::VisitPointerType(PointerType *T) {
207 QualType ToPointeeType = Importer.Import(T->getPointeeType());
208 if (ToPointeeType.isNull())
209 return QualType();
210
211 return Importer.getToContext().getPointerType(ToPointeeType);
212}
213
214QualType ASTNodeImporter::VisitBlockPointerType(BlockPointerType *T) {
215 // FIXME: Check for blocks support in "to" context.
216 QualType ToPointeeType = Importer.Import(T->getPointeeType());
217 if (ToPointeeType.isNull())
218 return QualType();
219
220 return Importer.getToContext().getBlockPointerType(ToPointeeType);
221}
222
223QualType ASTNodeImporter::VisitLValueReferenceType(LValueReferenceType *T) {
224 // FIXME: Check for C++ support in "to" context.
225 QualType ToPointeeType = Importer.Import(T->getPointeeTypeAsWritten());
226 if (ToPointeeType.isNull())
227 return QualType();
228
229 return Importer.getToContext().getLValueReferenceType(ToPointeeType);
230}
231
232QualType ASTNodeImporter::VisitRValueReferenceType(RValueReferenceType *T) {
233 // FIXME: Check for C++0x support in "to" context.
234 QualType ToPointeeType = Importer.Import(T->getPointeeTypeAsWritten());
235 if (ToPointeeType.isNull())
236 return QualType();
237
238 return Importer.getToContext().getRValueReferenceType(ToPointeeType);
239}
240
241QualType ASTNodeImporter::VisitMemberPointerType(MemberPointerType *T) {
242 // FIXME: Check for C++ support in "to" context.
243 QualType ToPointeeType = Importer.Import(T->getPointeeType());
244 if (ToPointeeType.isNull())
245 return QualType();
246
247 QualType ClassType = Importer.Import(QualType(T->getClass(), 0));
248 return Importer.getToContext().getMemberPointerType(ToPointeeType,
249 ClassType.getTypePtr());
250}
251
252QualType ASTNodeImporter::VisitConstantArrayType(ConstantArrayType *T) {
253 QualType ToElementType = Importer.Import(T->getElementType());
254 if (ToElementType.isNull())
255 return QualType();
256
257 return Importer.getToContext().getConstantArrayType(ToElementType,
258 T->getSize(),
259 T->getSizeModifier(),
260 T->getIndexTypeCVRQualifiers());
261}
262
263QualType ASTNodeImporter::VisitIncompleteArrayType(IncompleteArrayType *T) {
264 QualType ToElementType = Importer.Import(T->getElementType());
265 if (ToElementType.isNull())
266 return QualType();
267
268 return Importer.getToContext().getIncompleteArrayType(ToElementType,
269 T->getSizeModifier(),
270 T->getIndexTypeCVRQualifiers());
271}
272
273QualType ASTNodeImporter::VisitVariableArrayType(VariableArrayType *T) {
274 QualType ToElementType = Importer.Import(T->getElementType());
275 if (ToElementType.isNull())
276 return QualType();
277
278 Expr *Size = Importer.Import(T->getSizeExpr());
279 if (!Size)
280 return QualType();
281
282 SourceRange Brackets = Importer.Import(T->getBracketsRange());
283 return Importer.getToContext().getVariableArrayType(ToElementType, Size,
284 T->getSizeModifier(),
285 T->getIndexTypeCVRQualifiers(),
286 Brackets);
287}
288
289QualType ASTNodeImporter::VisitVectorType(VectorType *T) {
290 QualType ToElementType = Importer.Import(T->getElementType());
291 if (ToElementType.isNull())
292 return QualType();
293
294 return Importer.getToContext().getVectorType(ToElementType,
295 T->getNumElements(),
296 T->isAltiVec(),
297 T->isPixel());
298}
299
300QualType ASTNodeImporter::VisitExtVectorType(ExtVectorType *T) {
301 QualType ToElementType = Importer.Import(T->getElementType());
302 if (ToElementType.isNull())
303 return QualType();
304
305 return Importer.getToContext().getExtVectorType(ToElementType,
306 T->getNumElements());
307}
308
309QualType ASTNodeImporter::VisitFunctionNoProtoType(FunctionNoProtoType *T) {
310 // FIXME: What happens if we're importing a function without a prototype
311 // into C++? Should we make it variadic?
312 QualType ToResultType = Importer.Import(T->getResultType());
313 if (ToResultType.isNull())
314 return QualType();
315
316 return Importer.getToContext().getFunctionNoProtoType(ToResultType,
317 T->getNoReturnAttr(),
318 T->getCallConv());
319}
320
321QualType ASTNodeImporter::VisitFunctionProtoType(FunctionProtoType *T) {
322 QualType ToResultType = Importer.Import(T->getResultType());
323 if (ToResultType.isNull())
324 return QualType();
325
326 // Import argument types
327 llvm::SmallVector<QualType, 4> ArgTypes;
328 for (FunctionProtoType::arg_type_iterator A = T->arg_type_begin(),
329 AEnd = T->arg_type_end();
330 A != AEnd; ++A) {
331 QualType ArgType = Importer.Import(*A);
332 if (ArgType.isNull())
333 return QualType();
334 ArgTypes.push_back(ArgType);
335 }
336
337 // Import exception types
338 llvm::SmallVector<QualType, 4> ExceptionTypes;
339 for (FunctionProtoType::exception_iterator E = T->exception_begin(),
340 EEnd = T->exception_end();
341 E != EEnd; ++E) {
342 QualType ExceptionType = Importer.Import(*E);
343 if (ExceptionType.isNull())
344 return QualType();
345 ExceptionTypes.push_back(ExceptionType);
346 }
347
348 return Importer.getToContext().getFunctionType(ToResultType, ArgTypes.data(),
349 ArgTypes.size(),
350 T->isVariadic(),
351 T->getTypeQuals(),
352 T->hasExceptionSpec(),
353 T->hasAnyExceptionSpec(),
354 ExceptionTypes.size(),
355 ExceptionTypes.data(),
356 T->getNoReturnAttr(),
357 T->getCallConv());
358}
359
360QualType ASTNodeImporter::VisitTypedefType(TypedefType *T) {
361 TypedefDecl *ToDecl
362 = dyn_cast_or_null<TypedefDecl>(Importer.Import(T->getDecl()));
363 if (!ToDecl)
364 return QualType();
365
366 return Importer.getToContext().getTypeDeclType(ToDecl);
367}
368
369QualType ASTNodeImporter::VisitTypeOfExprType(TypeOfExprType *T) {
370 Expr *ToExpr = Importer.Import(T->getUnderlyingExpr());
371 if (!ToExpr)
372 return QualType();
373
374 return Importer.getToContext().getTypeOfExprType(ToExpr);
375}
376
377QualType ASTNodeImporter::VisitTypeOfType(TypeOfType *T) {
378 QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType());
379 if (ToUnderlyingType.isNull())
380 return QualType();
381
382 return Importer.getToContext().getTypeOfType(ToUnderlyingType);
383}
384
385QualType ASTNodeImporter::VisitDecltypeType(DecltypeType *T) {
386 Expr *ToExpr = Importer.Import(T->getUnderlyingExpr());
387 if (!ToExpr)
388 return QualType();
389
390 return Importer.getToContext().getDecltypeType(ToExpr);
391}
392
393QualType ASTNodeImporter::VisitRecordType(RecordType *T) {
394 RecordDecl *ToDecl
395 = dyn_cast_or_null<RecordDecl>(Importer.Import(T->getDecl()));
396 if (!ToDecl)
397 return QualType();
398
399 return Importer.getToContext().getTagDeclType(ToDecl);
400}
401
402QualType ASTNodeImporter::VisitEnumType(EnumType *T) {
403 EnumDecl *ToDecl
404 = dyn_cast_or_null<EnumDecl>(Importer.Import(T->getDecl()));
405 if (!ToDecl)
406 return QualType();
407
408 return Importer.getToContext().getTagDeclType(ToDecl);
409}
410
411QualType ASTNodeImporter::VisitElaboratedType(ElaboratedType *T) {
412 QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType());
413 if (ToUnderlyingType.isNull())
414 return QualType();
415
416 return Importer.getToContext().getElaboratedType(ToUnderlyingType,
417 T->getTagKind());
418}
419
420QualType ASTNodeImporter::VisitQualifiedNameType(QualifiedNameType *T) {
421 NestedNameSpecifier *ToQualifier = Importer.Import(T->getQualifier());
422 if (!ToQualifier)
423 return QualType();
424
425 QualType ToNamedType = Importer.Import(T->getNamedType());
426 if (ToNamedType.isNull())
427 return QualType();
428
429 return Importer.getToContext().getQualifiedNameType(ToQualifier, ToNamedType);
430}
431
432QualType ASTNodeImporter::VisitObjCInterfaceType(ObjCInterfaceType *T) {
433 ObjCInterfaceDecl *Class
434 = dyn_cast_or_null<ObjCInterfaceDecl>(Importer.Import(T->getDecl()));
435 if (!Class)
436 return QualType();
437
438 llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
439 for (ObjCInterfaceType::qual_iterator P = T->qual_begin(),
440 PEnd = T->qual_end();
441 P != PEnd; ++P) {
442 ObjCProtocolDecl *Protocol
443 = dyn_cast_or_null<ObjCProtocolDecl>(Importer.Import(*P));
444 if (!Protocol)
445 return QualType();
446 Protocols.push_back(Protocol);
447 }
448
449 return Importer.getToContext().getObjCInterfaceType(Class,
450 Protocols.data(),
451 Protocols.size());
452}
453
454QualType ASTNodeImporter::VisitObjCObjectPointerType(ObjCObjectPointerType *T) {
455 QualType ToPointeeType = Importer.Import(T->getPointeeType());
456 if (ToPointeeType.isNull())
457 return QualType();
458
459 llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
460 for (ObjCObjectPointerType::qual_iterator P = T->qual_begin(),
461 PEnd = T->qual_end();
462 P != PEnd; ++P) {
463 ObjCProtocolDecl *Protocol
464 = dyn_cast_or_null<ObjCProtocolDecl>(Importer.Import(*P));
465 if (!Protocol)
466 return QualType();
467 Protocols.push_back(Protocol);
468 }
469
470 return Importer.getToContext().getObjCObjectPointerType(ToPointeeType,
471 Protocols.data(),
472 Protocols.size());
473}
474
Douglas Gregor089459a2010-02-08 21:09:39 +0000475//----------------------------------------------------------------------------
476// Import Declarations
477//----------------------------------------------------------------------------
Douglas Gregora404ea62010-02-10 19:54:31 +0000478bool ASTNodeImporter::ImportDeclParts(NamedDecl *D, DeclContext *&DC,
479 DeclContext *&LexicalDC,
480 DeclarationName &Name,
481 SourceLocation &Loc) {
482 // Import the context of this declaration.
483 DC = Importer.ImportContext(D->getDeclContext());
484 if (!DC)
485 return true;
486
487 LexicalDC = DC;
488 if (D->getDeclContext() != D->getLexicalDeclContext()) {
489 LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
490 if (!LexicalDC)
491 return true;
492 }
493
494 // Import the name of this declaration.
495 Name = Importer.Import(D->getDeclName());
496 if (D->getDeclName() && !Name)
497 return true;
498
499 // Import the location of this declaration.
500 Loc = Importer.Import(D->getLocation());
501 return false;
502}
503
Douglas Gregor36ead2e2010-02-12 22:17:39 +0000504bool ASTNodeImporter::ImportDeclParts(ValueDecl *D,
Douglas Gregora404ea62010-02-10 19:54:31 +0000505 DeclContext *&DC,
506 DeclContext *&LexicalDC,
507 DeclarationName &Name,
508 SourceLocation &Loc,
509 QualType &T) {
510 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
511 return true;
512
513 // Import the type of this declaration.
514 T = Importer.Import(D->getType());
515 if (T.isNull())
516 return true;
517
518 return false;
519}
520
Douglas Gregor96a01b42010-02-11 00:48:18 +0000521bool ASTNodeImporter::IsStructuralMatch(RecordDecl *FromRecord,
522 RecordDecl *ToRecord) {
Douglas Gregor4800d952010-02-11 19:21:55 +0000523 if (FromRecord->isUnion() != ToRecord->isUnion()) {
524 Importer.ToDiag(ToRecord->getLocation(),
Douglas Gregor36ead2e2010-02-12 22:17:39 +0000525 diag::warn_odr_tag_type_inconsistent)
Douglas Gregor4800d952010-02-11 19:21:55 +0000526 << Importer.getToContext().getTypeDeclType(ToRecord);
527 Importer.FromDiag(FromRecord->getLocation(), diag::note_odr_tag_kind_here)
528 << FromRecord->getDeclName() << (unsigned)FromRecord->getTagKind();
Douglas Gregor96a01b42010-02-11 00:48:18 +0000529 return false;
Douglas Gregor4800d952010-02-11 19:21:55 +0000530 }
531
Douglas Gregor96a01b42010-02-11 00:48:18 +0000532 if (CXXRecordDecl *FromCXX = dyn_cast<CXXRecordDecl>(FromRecord)) {
533 if (CXXRecordDecl *ToCXX = dyn_cast<CXXRecordDecl>(ToRecord)) {
Douglas Gregor4800d952010-02-11 19:21:55 +0000534 if (FromCXX->getNumBases() != ToCXX->getNumBases()) {
535 Importer.ToDiag(ToRecord->getLocation(),
Douglas Gregor36ead2e2010-02-12 22:17:39 +0000536 diag::warn_odr_tag_type_inconsistent)
Douglas Gregor4800d952010-02-11 19:21:55 +0000537 << Importer.getToContext().getTypeDeclType(ToRecord);
538 Importer.ToDiag(ToRecord->getLocation(), diag::note_odr_number_of_bases)
539 << ToCXX->getNumBases();
540 Importer.FromDiag(FromRecord->getLocation(),
541 diag::note_odr_number_of_bases)
542 << FromCXX->getNumBases();
Douglas Gregor96a01b42010-02-11 00:48:18 +0000543 return false;
Douglas Gregor4800d952010-02-11 19:21:55 +0000544 }
545
Douglas Gregor96a01b42010-02-11 00:48:18 +0000546 // Check the base classes.
547 for (CXXRecordDecl::base_class_iterator FromBase = FromCXX->bases_begin(),
548 FromBaseEnd = FromCXX->bases_end(),
549 ToBase = ToCXX->bases_begin();
550 FromBase != FromBaseEnd;
Douglas Gregor4800d952010-02-11 19:21:55 +0000551 ++FromBase, ++ToBase) {
Douglas Gregor96a01b42010-02-11 00:48:18 +0000552 // Check the type we're inheriting from.
553 QualType FromBaseT = Importer.Import(FromBase->getType());
554 if (FromBaseT.isNull())
555 return false;
556
557 if (!Importer.getToContext().typesAreCompatible(FromBaseT,
Douglas Gregor4800d952010-02-11 19:21:55 +0000558 ToBase->getType())) {
559 Importer.ToDiag(ToRecord->getLocation(),
Douglas Gregor36ead2e2010-02-12 22:17:39 +0000560 diag::warn_odr_tag_type_inconsistent)
Douglas Gregor4800d952010-02-11 19:21:55 +0000561 << Importer.getToContext().getTypeDeclType(ToRecord);
562 Importer.ToDiag(ToBase->getSourceRange().getBegin(),
563 diag::note_odr_base)
564 << ToBase->getType()
565 << ToBase->getSourceRange();
566 Importer.FromDiag(FromBase->getSourceRange().getBegin(),
567 diag::note_odr_base)
568 << FromBase->getType()
569 << FromBase->getSourceRange();
Douglas Gregor96a01b42010-02-11 00:48:18 +0000570 return false;
Douglas Gregor4800d952010-02-11 19:21:55 +0000571 }
572
573 // Check virtual vs. non-virtual inheritance mismatch.
574 if (FromBase->isVirtual() != ToBase->isVirtual()) {
575 Importer.ToDiag(ToRecord->getLocation(),
Douglas Gregor36ead2e2010-02-12 22:17:39 +0000576 diag::warn_odr_tag_type_inconsistent)
Douglas Gregor4800d952010-02-11 19:21:55 +0000577 << Importer.getToContext().getTypeDeclType(ToRecord);
578 Importer.ToDiag(ToBase->getSourceRange().getBegin(),
579 diag::note_odr_virtual_base)
580 << ToBase->isVirtual() << ToBase->getSourceRange();
581 Importer.FromDiag(FromBase->getSourceRange().getBegin(),
582 diag::note_odr_base)
583 << FromBase->isVirtual()
584 << FromBase->getSourceRange();
585 return false;
586 }
Douglas Gregor96a01b42010-02-11 00:48:18 +0000587 }
588 } else if (FromCXX->getNumBases() > 0) {
Douglas Gregor4800d952010-02-11 19:21:55 +0000589 Importer.ToDiag(ToRecord->getLocation(),
Douglas Gregor36ead2e2010-02-12 22:17:39 +0000590 diag::warn_odr_tag_type_inconsistent)
Douglas Gregor4800d952010-02-11 19:21:55 +0000591 << Importer.getToContext().getTypeDeclType(ToRecord);
592 const CXXBaseSpecifier *FromBase = FromCXX->bases_begin();
593 Importer.FromDiag(FromBase->getSourceRange().getBegin(),
594 diag::note_odr_base)
595 << FromBase->getType()
596 << FromBase->getSourceRange();
597 Importer.ToDiag(ToRecord->getLocation(), diag::note_odr_missing_base);
Douglas Gregor96a01b42010-02-11 00:48:18 +0000598 return false;
599 }
600 }
601
602 // Check the fields for consistency.
603 CXXRecordDecl::field_iterator ToField = ToRecord->field_begin(),
604 ToFieldEnd = ToRecord->field_end();
605 for (CXXRecordDecl::field_iterator FromField = FromRecord->field_begin(),
606 FromFieldEnd = FromRecord->field_end();
607 FromField != FromFieldEnd;
608 ++FromField, ++ToField) {
Douglas Gregor4800d952010-02-11 19:21:55 +0000609 if (ToField == ToFieldEnd) {
610 Importer.ToDiag(ToRecord->getLocation(),
Douglas Gregor36ead2e2010-02-12 22:17:39 +0000611 diag::warn_odr_tag_type_inconsistent)
Douglas Gregor4800d952010-02-11 19:21:55 +0000612 << Importer.getToContext().getTypeDeclType(ToRecord);
613 Importer.FromDiag(FromField->getLocation(), diag::note_odr_field)
614 << FromField->getDeclName() << FromField->getType();
615 Importer.ToDiag(ToRecord->getLocation(), diag::note_odr_missing_field);
Douglas Gregor96a01b42010-02-11 00:48:18 +0000616 return false;
Douglas Gregor4800d952010-02-11 19:21:55 +0000617 }
618
Douglas Gregor96a01b42010-02-11 00:48:18 +0000619 QualType FromT = Importer.Import(FromField->getType());
620 if (FromT.isNull())
621 return false;
622
Douglas Gregor4800d952010-02-11 19:21:55 +0000623 if (!Importer.getToContext().typesAreCompatible(FromT, ToField->getType())){
624 Importer.ToDiag(ToRecord->getLocation(),
Douglas Gregor36ead2e2010-02-12 22:17:39 +0000625 diag::warn_odr_tag_type_inconsistent)
Douglas Gregor4800d952010-02-11 19:21:55 +0000626 << Importer.getToContext().getTypeDeclType(ToRecord);
627 Importer.ToDiag(ToField->getLocation(), diag::note_odr_field)
628 << ToField->getDeclName() << ToField->getType();
629 Importer.FromDiag(FromField->getLocation(), diag::note_odr_field)
630 << FromField->getDeclName() << FromField->getType();
Douglas Gregor96a01b42010-02-11 00:48:18 +0000631 return false;
Douglas Gregor4800d952010-02-11 19:21:55 +0000632 }
Douglas Gregor96a01b42010-02-11 00:48:18 +0000633
Douglas Gregor4800d952010-02-11 19:21:55 +0000634 if (FromField->isBitField() != ToField->isBitField()) {
635 Importer.ToDiag(ToRecord->getLocation(),
Douglas Gregor36ead2e2010-02-12 22:17:39 +0000636 diag::warn_odr_tag_type_inconsistent)
Douglas Gregor4800d952010-02-11 19:21:55 +0000637 << Importer.getToContext().getTypeDeclType(ToRecord);
638 if (FromField->isBitField()) {
639 llvm::APSInt Bits;
640 FromField->getBitWidth()->isIntegerConstantExpr(Bits,
641 Importer.getFromContext());
642 Importer.FromDiag(FromField->getLocation(), diag::note_odr_bit_field)
643 << FromField->getDeclName() << FromField->getType()
644 << Bits.toString(10, false);
645 Importer.ToDiag(ToField->getLocation(), diag::note_odr_not_bit_field)
646 << ToField->getDeclName();
647 } else {
648 llvm::APSInt Bits;
649 ToField->getBitWidth()->isIntegerConstantExpr(Bits,
650 Importer.getToContext());
651 Importer.ToDiag(ToField->getLocation(), diag::note_odr_bit_field)
652 << ToField->getDeclName() << ToField->getType()
653 << Bits.toString(10, false);
654 Importer.FromDiag(FromField->getLocation(),
655 diag::note_odr_not_bit_field)
656 << FromField->getDeclName();
657 }
Douglas Gregor96a01b42010-02-11 00:48:18 +0000658 return false;
Douglas Gregor4800d952010-02-11 19:21:55 +0000659 }
660
Douglas Gregor96a01b42010-02-11 00:48:18 +0000661 if (FromField->isBitField()) {
662 // Make sure that the bit-fields are the same length.
663 llvm::APSInt FromBits, ToBits;
664 if (!FromField->getBitWidth()->isIntegerConstantExpr(FromBits,
665 Importer.getFromContext()))
666 return false;
667 if (!ToField->getBitWidth()->isIntegerConstantExpr(ToBits,
668 Importer.getToContext()))
669 return false;
670
671 if (FromBits.getBitWidth() > ToBits.getBitWidth())
672 ToBits.extend(FromBits.getBitWidth());
673 else if (ToBits.getBitWidth() > FromBits.getBitWidth())
674 FromBits.extend(ToBits.getBitWidth());
675
676 FromBits.setIsUnsigned(true);
677 ToBits.setIsUnsigned(true);
678
Douglas Gregor4800d952010-02-11 19:21:55 +0000679 if (FromBits != ToBits) {
680 Importer.ToDiag(ToRecord->getLocation(),
Douglas Gregor36ead2e2010-02-12 22:17:39 +0000681 diag::warn_odr_tag_type_inconsistent)
Douglas Gregor4800d952010-02-11 19:21:55 +0000682 << Importer.getToContext().getTypeDeclType(ToRecord);
683 Importer.ToDiag(ToField->getLocation(), diag::note_odr_bit_field)
684 << ToField->getDeclName() << ToField->getType()
685 << ToBits.toString(10, false);
686 Importer.FromDiag(FromField->getLocation(), diag::note_odr_bit_field)
687 << FromField->getDeclName() << FromField->getType()
688 << FromBits.toString(10, false);
Douglas Gregor96a01b42010-02-11 00:48:18 +0000689 return false;
Douglas Gregor4800d952010-02-11 19:21:55 +0000690 }
Douglas Gregor96a01b42010-02-11 00:48:18 +0000691 }
692 }
693
Douglas Gregor4800d952010-02-11 19:21:55 +0000694 if (ToField != ToFieldEnd) {
695 Importer.ToDiag(ToRecord->getLocation(),
Douglas Gregor36ead2e2010-02-12 22:17:39 +0000696 diag::warn_odr_tag_type_inconsistent)
Douglas Gregor4800d952010-02-11 19:21:55 +0000697 << Importer.getToContext().getTypeDeclType(ToRecord);
698 Importer.ToDiag(ToField->getLocation(), diag::note_odr_field)
699 << ToField->getDeclName() << ToField->getType();
700 Importer.FromDiag(FromRecord->getLocation(), diag::note_odr_missing_field);
701 return false;
702 }
703
704 return true;
Douglas Gregor96a01b42010-02-11 00:48:18 +0000705}
706
Douglas Gregor36ead2e2010-02-12 22:17:39 +0000707bool ASTNodeImporter::IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToEnum) {
708 EnumDecl::enumerator_iterator ToEC = ToEnum->enumerator_begin(),
709 ToEnd = ToEnum->enumerator_end();
710 for (EnumDecl::enumerator_iterator FromEC = FromEnum->enumerator_begin(),
711 FromEnd = FromEnum->enumerator_end();
712 FromEC != FromEnd; ++FromEC, ++ToEC) {
713 if (ToEC == ToEnd) {
714 Importer.ToDiag(ToEnum->getLocation(),
715 diag::warn_odr_tag_type_inconsistent)
716 << Importer.getToContext().getTypeDeclType(ToEnum);
717 Importer.FromDiag(FromEC->getLocation(), diag::note_odr_enumerator)
718 << FromEC->getDeclName()
719 << FromEC->getInitVal().toString(10);
720 Importer.ToDiag(ToEnum->getLocation(),
721 diag::note_odr_missing_enumerator);
722 return false;
723 }
724
725 llvm::APSInt FromVal = FromEC->getInitVal();
726 llvm::APSInt ToVal = ToEC->getInitVal();
727 if (FromVal.getBitWidth() > ToVal.getBitWidth())
728 ToVal.extend(FromVal.getBitWidth());
729 else if (ToVal.getBitWidth() > FromVal.getBitWidth())
730 FromVal.extend(ToVal.getBitWidth());
731 if (FromVal.isSigned() != ToVal.isSigned()) {
732 if (FromVal.isSigned())
733 ToVal.setIsSigned(true);
734 else
735 FromVal.setIsSigned(true);
736 }
737
738 if (FromVal != ToVal ||
739 ToEC->getDeclName() != Importer.Import(FromEC->getDeclName())) {
740 Importer.ToDiag(ToEnum->getLocation(),
741 diag::warn_odr_tag_type_inconsistent)
742 << Importer.getToContext().getTypeDeclType(ToEnum);
743 Importer.ToDiag(ToEC->getLocation(), diag::note_odr_enumerator)
744 << ToEC->getDeclName()
745 << ToEC->getInitVal().toString(10);
746 Importer.FromDiag(FromEC->getLocation(), diag::note_odr_enumerator)
747 << FromEC->getDeclName()
748 << FromEC->getInitVal().toString(10);
749 return false;
750 }
751 }
752
753 if (ToEC != ToEnd) {
754 Importer.ToDiag(ToEnum->getLocation(),
755 diag::warn_odr_tag_type_inconsistent)
756 << Importer.getToContext().getTypeDeclType(ToEnum);
757 Importer.ToDiag(ToEC->getLocation(), diag::note_odr_enumerator)
758 << ToEC->getDeclName()
759 << ToEC->getInitVal().toString(10);
760 Importer.FromDiag(FromEnum->getLocation(),
761 diag::note_odr_missing_enumerator);
762 return false;
763 }
764
765 return true;
766}
767
Douglas Gregor89cc9d62010-02-09 22:48:33 +0000768Decl *ASTNodeImporter::VisitDecl(Decl *D) {
Douglas Gregor88523732010-02-10 00:15:17 +0000769 Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node)
Douglas Gregor89cc9d62010-02-09 22:48:33 +0000770 << D->getDeclKindName();
771 return 0;
772}
773
Douglas Gregor9e5d9962010-02-10 21:10:29 +0000774Decl *ASTNodeImporter::VisitTypedefDecl(TypedefDecl *D) {
775 // Import the major distinguishing characteristics of this typedef.
776 DeclContext *DC, *LexicalDC;
777 DeclarationName Name;
778 SourceLocation Loc;
779 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
780 return 0;
781
782 // Import the underlying type of this typedef;
783 QualType T = Importer.Import(D->getUnderlyingType());
784 if (T.isNull())
785 return 0;
786
787 // If this typedef is not in block scope, determine whether we've
788 // seen a typedef with the same name (that we can merge with) or any
789 // other entity by that name (which name lookup could conflict with).
790 if (!DC->isFunctionOrMethod()) {
791 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
792 unsigned IDNS = Decl::IDNS_Ordinary;
793 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
794 Lookup.first != Lookup.second;
795 ++Lookup.first) {
796 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
797 continue;
798 if (TypedefDecl *FoundTypedef = dyn_cast<TypedefDecl>(*Lookup.first)) {
799 if (Importer.getToContext().typesAreCompatible(T,
800 FoundTypedef->getUnderlyingType())) {
801 Importer.getImportedDecls()[D] = FoundTypedef;
802 return FoundTypedef;
803 }
804 }
805
806 ConflictingDecls.push_back(*Lookup.first);
807 }
808
809 if (!ConflictingDecls.empty()) {
810 Name = Importer.HandleNameConflict(Name, DC, IDNS,
811 ConflictingDecls.data(),
812 ConflictingDecls.size());
813 if (!Name)
814 return 0;
815 }
816 }
817
818 // Create the new typedef node.
819 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
820 TypedefDecl *ToTypedef = TypedefDecl::Create(Importer.getToContext(), DC,
821 Loc, Name.getAsIdentifierInfo(),
822 TInfo);
823 ToTypedef->setLexicalDeclContext(LexicalDC);
824 Importer.getImportedDecls()[D] = ToTypedef;
825 LexicalDC->addDecl(ToTypedef);
826 return ToTypedef;
827}
828
Douglas Gregor36ead2e2010-02-12 22:17:39 +0000829Decl *ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
830 // Import the major distinguishing characteristics of this enum.
831 DeclContext *DC, *LexicalDC;
832 DeclarationName Name;
833 SourceLocation Loc;
834 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
835 return 0;
836
837 // Figure out what enum name we're looking for.
838 unsigned IDNS = Decl::IDNS_Tag;
839 DeclarationName SearchName = Name;
840 if (!SearchName && D->getTypedefForAnonDecl()) {
841 SearchName = Importer.Import(D->getTypedefForAnonDecl()->getDeclName());
842 IDNS = Decl::IDNS_Ordinary;
843 } else if (Importer.getToContext().getLangOptions().CPlusPlus)
844 IDNS |= Decl::IDNS_Ordinary;
845
846 // We may already have an enum of the same name; try to find and match it.
847 if (!DC->isFunctionOrMethod() && SearchName) {
848 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
849 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
850 Lookup.first != Lookup.second;
851 ++Lookup.first) {
852 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
853 continue;
854
855 Decl *Found = *Lookup.first;
856 if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(Found)) {
857 if (const TagType *Tag = Typedef->getUnderlyingType()->getAs<TagType>())
858 Found = Tag->getDecl();
859 }
860
861 if (EnumDecl *FoundEnum = dyn_cast<EnumDecl>(Found)) {
862 if (IsStructuralMatch(D, FoundEnum)) {
863 // The enum types structurally match.
864 Importer.getImportedDecls()[D] = FoundEnum;
865 return FoundEnum;
866 }
867 }
868
869 ConflictingDecls.push_back(*Lookup.first);
870 }
871
872 if (!ConflictingDecls.empty()) {
873 Name = Importer.HandleNameConflict(Name, DC, IDNS,
874 ConflictingDecls.data(),
875 ConflictingDecls.size());
876 }
877 }
878
879 // Create the enum declaration.
880 EnumDecl *ToEnum = EnumDecl::Create(Importer.getToContext(), DC, Loc,
881 Name.getAsIdentifierInfo(),
882 Importer.Import(D->getTagKeywordLoc()),
883 0);
884 ToEnum->setLexicalDeclContext(LexicalDC);
885 Importer.getImportedDecls()[D] = ToEnum;
886 LexicalDC->addDecl(ToEnum);
887
888 // Import the integer type.
889 QualType ToIntegerType = Importer.Import(D->getIntegerType());
890 if (ToIntegerType.isNull())
891 return 0;
892 ToEnum->setIntegerType(ToIntegerType);
893
894 // Import the definition
895 if (D->isDefinition()) {
896 QualType T = Importer.Import(Importer.getFromContext().getTypeDeclType(D));
897 if (T.isNull())
898 return 0;
899
900 QualType ToPromotionType = Importer.Import(D->getPromotionType());
901 if (ToPromotionType.isNull())
902 return 0;
903
904 ToEnum->startDefinition();
905 for (DeclContext::decl_iterator FromMem = D->decls_begin(),
906 FromMemEnd = D->decls_end();
907 FromMem != FromMemEnd;
908 ++FromMem)
909 Importer.Import(*FromMem);
910
911 ToEnum->completeDefinition(T, ToPromotionType);
912 }
913
914 return ToEnum;
915}
916
Douglas Gregor96a01b42010-02-11 00:48:18 +0000917Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
918 // If this record has a definition in the translation unit we're coming from,
919 // but this particular declaration is not that definition, import the
920 // definition and map to that.
Douglas Gregor952b0172010-02-11 01:04:33 +0000921 TagDecl *Definition = D->getDefinition();
Douglas Gregor96a01b42010-02-11 00:48:18 +0000922 if (Definition && Definition != D) {
923 Decl *ImportedDef = Importer.Import(Definition);
924 Importer.getImportedDecls()[D] = ImportedDef;
925 return ImportedDef;
926 }
927
928 // Import the major distinguishing characteristics of this record.
929 DeclContext *DC, *LexicalDC;
930 DeclarationName Name;
931 SourceLocation Loc;
932 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
933 return 0;
934
935 // Figure out what structure name we're looking for.
936 unsigned IDNS = Decl::IDNS_Tag;
937 DeclarationName SearchName = Name;
938 if (!SearchName && D->getTypedefForAnonDecl()) {
939 SearchName = Importer.Import(D->getTypedefForAnonDecl()->getDeclName());
940 IDNS = Decl::IDNS_Ordinary;
941 } else if (Importer.getToContext().getLangOptions().CPlusPlus)
942 IDNS |= Decl::IDNS_Ordinary;
943
944 // We may already have a record of the same name; try to find and match it.
Douglas Gregore72b5dc2010-02-12 00:09:27 +0000945 RecordDecl *AdoptDecl = 0;
Douglas Gregor96a01b42010-02-11 00:48:18 +0000946 if (!DC->isFunctionOrMethod() && SearchName) {
947 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
948 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
949 Lookup.first != Lookup.second;
950 ++Lookup.first) {
951 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
952 continue;
953
954 Decl *Found = *Lookup.first;
955 if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(Found)) {
956 if (const TagType *Tag = Typedef->getUnderlyingType()->getAs<TagType>())
957 Found = Tag->getDecl();
958 }
959
960 if (RecordDecl *FoundRecord = dyn_cast<RecordDecl>(Found)) {
Douglas Gregore72b5dc2010-02-12 00:09:27 +0000961 if (RecordDecl *FoundDef = FoundRecord->getDefinition()) {
962 if (!D->isDefinition() || IsStructuralMatch(D, FoundDef)) {
963 // The record types structurally match, or the "from" translation
964 // unit only had a forward declaration anyway; call it the same
965 // function.
966 // FIXME: For C++, we should also merge methods here.
967 Importer.getImportedDecls()[D] = FoundDef;
968 return FoundDef;
969 }
970 } else {
971 // We have a forward declaration of this type, so adopt that forward
972 // declaration rather than building a new one.
973 AdoptDecl = FoundRecord;
974 continue;
975 }
Douglas Gregor96a01b42010-02-11 00:48:18 +0000976 }
977
978 ConflictingDecls.push_back(*Lookup.first);
979 }
980
981 if (!ConflictingDecls.empty()) {
982 Name = Importer.HandleNameConflict(Name, DC, IDNS,
983 ConflictingDecls.data(),
984 ConflictingDecls.size());
985 }
986 }
987
988 // Create the record declaration.
Douglas Gregore72b5dc2010-02-12 00:09:27 +0000989 RecordDecl *ToRecord = AdoptDecl;
990 if (!ToRecord) {
991 if (CXXRecordDecl *FromCXX = dyn_cast<CXXRecordDecl>(D)) {
992 CXXRecordDecl *ToCXX = CXXRecordDecl::Create(Importer.getToContext(),
993 D->getTagKind(),
994 DC, Loc,
995 Name.getAsIdentifierInfo(),
Douglas Gregor96a01b42010-02-11 00:48:18 +0000996 Importer.Import(D->getTagKeywordLoc()));
Douglas Gregore72b5dc2010-02-12 00:09:27 +0000997 ToRecord = ToCXX;
998
999 if (D->isDefinition()) {
1000 // Add base classes.
1001 llvm::SmallVector<CXXBaseSpecifier *, 4> Bases;
1002 for (CXXRecordDecl::base_class_iterator
1003 FromBase = FromCXX->bases_begin(),
1004 FromBaseEnd = FromCXX->bases_end();
1005 FromBase != FromBaseEnd;
1006 ++FromBase) {
1007 QualType T = Importer.Import(FromBase->getType());
1008 if (T.isNull())
1009 return 0;
1010
1011 Bases.push_back(
1012 new (Importer.getToContext())
Douglas Gregor96a01b42010-02-11 00:48:18 +00001013 CXXBaseSpecifier(Importer.Import(FromBase->getSourceRange()),
1014 FromBase->isVirtual(),
1015 FromBase->isBaseOfClass(),
1016 FromBase->getAccessSpecifierAsWritten(),
1017 T));
Douglas Gregore72b5dc2010-02-12 00:09:27 +00001018 }
1019 if (!Bases.empty())
1020 ToCXX->setBases(Bases.data(), Bases.size());
Douglas Gregor96a01b42010-02-11 00:48:18 +00001021 }
Douglas Gregore72b5dc2010-02-12 00:09:27 +00001022 } else {
1023 ToRecord = RecordDecl::Create(Importer.getToContext(), D->getTagKind(),
1024 DC, Loc,
1025 Name.getAsIdentifierInfo(),
1026 Importer.Import(D->getTagKeywordLoc()));
Douglas Gregor96a01b42010-02-11 00:48:18 +00001027 }
Douglas Gregore72b5dc2010-02-12 00:09:27 +00001028 ToRecord->setLexicalDeclContext(LexicalDC);
1029 LexicalDC->addDecl(ToRecord);
Douglas Gregor96a01b42010-02-11 00:48:18 +00001030 }
Douglas Gregor96a01b42010-02-11 00:48:18 +00001031 Importer.getImportedDecls()[D] = ToRecord;
Douglas Gregore72b5dc2010-02-12 00:09:27 +00001032
Douglas Gregor96a01b42010-02-11 00:48:18 +00001033 if (D->isDefinition()) {
1034 ToRecord->startDefinition();
1035 for (DeclContext::decl_iterator FromMem = D->decls_begin(),
1036 FromMemEnd = D->decls_end();
1037 FromMem != FromMemEnd;
1038 ++FromMem)
1039 Importer.Import(*FromMem);
1040
Douglas Gregor838db382010-02-11 01:19:42 +00001041 ToRecord->completeDefinition();
Douglas Gregor96a01b42010-02-11 00:48:18 +00001042 }
1043
1044 return ToRecord;
1045}
1046
Douglas Gregor36ead2e2010-02-12 22:17:39 +00001047Decl *ASTNodeImporter::VisitEnumConstantDecl(EnumConstantDecl *D) {
1048 // Import the major distinguishing characteristics of this enumerator.
1049 DeclContext *DC, *LexicalDC;
1050 DeclarationName Name;
1051 SourceLocation Loc;
1052 QualType T;
1053 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc, T))
1054 return 0;
1055
1056 // Determine whether there are any other declarations with the same name and
1057 // in the same context.
1058 if (!LexicalDC->isFunctionOrMethod()) {
1059 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
1060 unsigned IDNS = Decl::IDNS_Ordinary;
1061 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
1062 Lookup.first != Lookup.second;
1063 ++Lookup.first) {
1064 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
1065 continue;
1066
1067 ConflictingDecls.push_back(*Lookup.first);
1068 }
1069
1070 if (!ConflictingDecls.empty()) {
1071 Name = Importer.HandleNameConflict(Name, DC, IDNS,
1072 ConflictingDecls.data(),
1073 ConflictingDecls.size());
1074 if (!Name)
1075 return 0;
1076 }
1077 }
1078
1079 Expr *Init = Importer.Import(D->getInitExpr());
1080 if (D->getInitExpr() && !Init)
1081 return 0;
1082
1083 EnumConstantDecl *ToEnumerator
1084 = EnumConstantDecl::Create(Importer.getToContext(), cast<EnumDecl>(DC), Loc,
1085 Name.getAsIdentifierInfo(), T,
1086 Init, D->getInitVal());
1087 ToEnumerator->setLexicalDeclContext(LexicalDC);
1088 Importer.getImportedDecls()[D] = ToEnumerator;
1089 LexicalDC->addDecl(ToEnumerator);
1090 return ToEnumerator;
1091}
Douglas Gregor96a01b42010-02-11 00:48:18 +00001092
Douglas Gregora404ea62010-02-10 19:54:31 +00001093Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
1094 // Import the major distinguishing characteristics of this function.
1095 DeclContext *DC, *LexicalDC;
1096 DeclarationName Name;
1097 QualType T;
1098 SourceLocation Loc;
1099 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc, T))
Douglas Gregor089459a2010-02-08 21:09:39 +00001100 return 0;
Douglas Gregora404ea62010-02-10 19:54:31 +00001101
1102 // Try to find a function in our own ("to") context with the same name, same
1103 // type, and in the same context as the function we're importing.
1104 if (!LexicalDC->isFunctionOrMethod()) {
1105 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
1106 unsigned IDNS = Decl::IDNS_Ordinary;
1107 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
1108 Lookup.first != Lookup.second;
1109 ++Lookup.first) {
1110 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
1111 continue;
Douglas Gregor089459a2010-02-08 21:09:39 +00001112
Douglas Gregora404ea62010-02-10 19:54:31 +00001113 if (FunctionDecl *FoundFunction = dyn_cast<FunctionDecl>(*Lookup.first)) {
1114 if (isExternalLinkage(FoundFunction->getLinkage()) &&
1115 isExternalLinkage(D->getLinkage())) {
1116 if (Importer.getToContext().typesAreCompatible(T,
1117 FoundFunction->getType())) {
1118 // FIXME: Actually try to merge the body and other attributes.
1119 Importer.getImportedDecls()[D] = FoundFunction;
1120 return FoundFunction;
1121 }
1122
1123 // FIXME: Check for overloading more carefully, e.g., by boosting
1124 // Sema::IsOverload out to the AST library.
1125
1126 // Function overloading is okay in C++.
1127 if (Importer.getToContext().getLangOptions().CPlusPlus)
1128 continue;
1129
1130 // Complain about inconsistent function types.
1131 Importer.ToDiag(Loc, diag::err_odr_function_type_inconsistent)
1132 << Name << T << FoundFunction->getType();
1133 Importer.ToDiag(FoundFunction->getLocation(),
1134 diag::note_odr_value_here)
1135 << FoundFunction->getType();
1136 }
1137 }
1138
1139 ConflictingDecls.push_back(*Lookup.first);
1140 }
1141
1142 if (!ConflictingDecls.empty()) {
1143 Name = Importer.HandleNameConflict(Name, DC, IDNS,
1144 ConflictingDecls.data(),
1145 ConflictingDecls.size());
1146 if (!Name)
1147 return 0;
1148 }
Douglas Gregor9bed8792010-02-09 19:21:46 +00001149 }
Douglas Gregora404ea62010-02-10 19:54:31 +00001150
1151 // Import the function parameters.
1152 llvm::SmallVector<ParmVarDecl *, 8> Parameters;
1153 for (FunctionDecl::param_iterator P = D->param_begin(), PEnd = D->param_end();
1154 P != PEnd; ++P) {
1155 ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(*P));
1156 if (!ToP)
1157 return 0;
1158
1159 Parameters.push_back(ToP);
1160 }
1161
1162 // Create the imported function.
1163 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
Douglas Gregor36ead2e2010-02-12 22:17:39 +00001164 FunctionDecl *ToEnumerator
Douglas Gregora404ea62010-02-10 19:54:31 +00001165 = FunctionDecl::Create(Importer.getToContext(), DC, Loc,
1166 Name, T, TInfo, D->getStorageClass(),
1167 D->isInlineSpecified(),
1168 D->hasWrittenPrototype());
Douglas Gregor36ead2e2010-02-12 22:17:39 +00001169 ToEnumerator->setLexicalDeclContext(LexicalDC);
1170 Importer.getImportedDecls()[D] = ToEnumerator;
1171 LexicalDC->addDecl(ToEnumerator);
Douglas Gregor9bed8792010-02-09 19:21:46 +00001172
Douglas Gregora404ea62010-02-10 19:54:31 +00001173 // Set the parameters.
1174 for (unsigned I = 0, N = Parameters.size(); I != N; ++I) {
Douglas Gregor36ead2e2010-02-12 22:17:39 +00001175 Parameters[I]->setOwningFunction(ToEnumerator);
1176 ToEnumerator->addDecl(Parameters[I]);
Douglas Gregora404ea62010-02-10 19:54:31 +00001177 }
Douglas Gregor36ead2e2010-02-12 22:17:39 +00001178 ToEnumerator->setParams(Parameters.data(), Parameters.size());
Douglas Gregora404ea62010-02-10 19:54:31 +00001179
1180 // FIXME: Other bits to merge?
Douglas Gregor089459a2010-02-08 21:09:39 +00001181
Douglas Gregor36ead2e2010-02-12 22:17:39 +00001182 return ToEnumerator;
Douglas Gregora404ea62010-02-10 19:54:31 +00001183}
1184
Douglas Gregor96a01b42010-02-11 00:48:18 +00001185Decl *ASTNodeImporter::VisitFieldDecl(FieldDecl *D) {
1186 // Import the major distinguishing characteristics of a variable.
1187 DeclContext *DC, *LexicalDC;
1188 DeclarationName Name;
1189 QualType T;
1190 SourceLocation Loc;
1191 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc, T))
1192 return 0;
1193
1194 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
1195 Expr *BitWidth = Importer.Import(D->getBitWidth());
1196 if (!BitWidth && D->getBitWidth())
1197 return 0;
1198
1199 FieldDecl *ToField = FieldDecl::Create(Importer.getToContext(), DC,
1200 Loc, Name.getAsIdentifierInfo(),
1201 T, TInfo, BitWidth, D->isMutable());
1202 ToField->setLexicalDeclContext(LexicalDC);
1203 Importer.getImportedDecls()[D] = ToField;
1204 LexicalDC->addDecl(ToField);
1205 return ToField;
1206}
1207
Douglas Gregora404ea62010-02-10 19:54:31 +00001208Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
1209 // Import the major distinguishing characteristics of a variable.
1210 DeclContext *DC, *LexicalDC;
1211 DeclarationName Name;
1212 QualType T;
1213 SourceLocation Loc;
1214 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc, T))
Douglas Gregor089459a2010-02-08 21:09:39 +00001215 return 0;
1216
Douglas Gregor089459a2010-02-08 21:09:39 +00001217 // Try to find a variable in our own ("to") context with the same name and
1218 // in the same context as the variable we're importing.
Douglas Gregor9bed8792010-02-09 19:21:46 +00001219 if (D->isFileVarDecl()) {
Douglas Gregor089459a2010-02-08 21:09:39 +00001220 VarDecl *MergeWithVar = 0;
1221 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
1222 unsigned IDNS = Decl::IDNS_Ordinary;
Douglas Gregor9bed8792010-02-09 19:21:46 +00001223 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
Douglas Gregor089459a2010-02-08 21:09:39 +00001224 Lookup.first != Lookup.second;
1225 ++Lookup.first) {
1226 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
1227 continue;
1228
1229 if (VarDecl *FoundVar = dyn_cast<VarDecl>(*Lookup.first)) {
1230 // We have found a variable that we may need to merge with. Check it.
1231 if (isExternalLinkage(FoundVar->getLinkage()) &&
1232 isExternalLinkage(D->getLinkage())) {
1233 if (Importer.getToContext().typesAreCompatible(T,
1234 FoundVar->getType())) {
1235 MergeWithVar = FoundVar;
1236 break;
1237 }
1238
Douglas Gregord0145422010-02-12 17:23:39 +00001239 const ArrayType *FoundArray
1240 = Importer.getToContext().getAsArrayType(FoundVar->getType());
1241 const ArrayType *TArray
1242 = Importer.getToContext().getAsArrayType(T);
1243 if (FoundArray && TArray) {
1244 if (isa<IncompleteArrayType>(FoundArray) &&
1245 isa<ConstantArrayType>(TArray)) {
1246 FoundVar->setType(T);
1247 MergeWithVar = FoundVar;
1248 break;
1249 } else if (isa<IncompleteArrayType>(TArray) &&
1250 isa<ConstantArrayType>(FoundArray)) {
1251 MergeWithVar = FoundVar;
1252 break;
Douglas Gregor0f962a82010-02-10 17:16:49 +00001253 }
1254 }
1255
Douglas Gregor089459a2010-02-08 21:09:39 +00001256 Importer.ToDiag(Loc, diag::err_odr_variable_type_inconsistent)
1257 << Name << T << FoundVar->getType();
1258 Importer.ToDiag(FoundVar->getLocation(), diag::note_odr_value_here)
1259 << FoundVar->getType();
1260 }
1261 }
1262
1263 ConflictingDecls.push_back(*Lookup.first);
1264 }
1265
1266 if (MergeWithVar) {
1267 // An equivalent variable with external linkage has been found. Link
1268 // the two declarations, then merge them.
1269 Importer.getImportedDecls()[D] = MergeWithVar;
1270
1271 if (VarDecl *DDef = D->getDefinition()) {
1272 if (VarDecl *ExistingDef = MergeWithVar->getDefinition()) {
1273 Importer.ToDiag(ExistingDef->getLocation(),
1274 diag::err_odr_variable_multiple_def)
1275 << Name;
1276 Importer.FromDiag(DDef->getLocation(), diag::note_odr_defined_here);
1277 } else {
1278 Expr *Init = Importer.Import(DDef->getInit());
Douglas Gregor838db382010-02-11 01:19:42 +00001279 MergeWithVar->setInit(Init);
Douglas Gregor089459a2010-02-08 21:09:39 +00001280 }
1281 }
1282
1283 return MergeWithVar;
1284 }
1285
1286 if (!ConflictingDecls.empty()) {
1287 Name = Importer.HandleNameConflict(Name, DC, IDNS,
1288 ConflictingDecls.data(),
1289 ConflictingDecls.size());
1290 if (!Name)
1291 return 0;
1292 }
1293 }
Douglas Gregor82fc4bf2010-02-10 17:47:19 +00001294
Douglas Gregor089459a2010-02-08 21:09:39 +00001295 // Create the imported variable.
Douglas Gregor82fc4bf2010-02-10 17:47:19 +00001296 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
Douglas Gregor089459a2010-02-08 21:09:39 +00001297 VarDecl *ToVar = VarDecl::Create(Importer.getToContext(), DC, Loc,
1298 Name.getAsIdentifierInfo(), T, TInfo,
1299 D->getStorageClass());
Douglas Gregor9bed8792010-02-09 19:21:46 +00001300 ToVar->setLexicalDeclContext(LexicalDC);
Douglas Gregor089459a2010-02-08 21:09:39 +00001301 Importer.getImportedDecls()[D] = ToVar;
Douglas Gregor9bed8792010-02-09 19:21:46 +00001302 LexicalDC->addDecl(ToVar);
1303
Douglas Gregor089459a2010-02-08 21:09:39 +00001304 // Merge the initializer.
1305 // FIXME: Can we really import any initializer? Alternatively, we could force
1306 // ourselves to import every declaration of a variable and then only use
1307 // getInit() here.
Douglas Gregor838db382010-02-11 01:19:42 +00001308 ToVar->setInit(Importer.Import(const_cast<Expr *>(D->getAnyInitializer())));
Douglas Gregor089459a2010-02-08 21:09:39 +00001309
1310 // FIXME: Other bits to merge?
1311
1312 return ToVar;
1313}
1314
Douglas Gregora404ea62010-02-10 19:54:31 +00001315Decl *ASTNodeImporter::VisitParmVarDecl(ParmVarDecl *D) {
1316 // Parameters are created in the translation unit's context, then moved
1317 // into the function declaration's context afterward.
1318 DeclContext *DC = Importer.getToContext().getTranslationUnitDecl();
1319
Douglas Gregor82fc4bf2010-02-10 17:47:19 +00001320 // Import the name of this declaration.
1321 DeclarationName Name = Importer.Import(D->getDeclName());
1322 if (D->getDeclName() && !Name)
1323 return 0;
1324
Douglas Gregora404ea62010-02-10 19:54:31 +00001325 // Import the location of this declaration.
1326 SourceLocation Loc = Importer.Import(D->getLocation());
1327
1328 // Import the parameter's type.
1329 QualType T = Importer.Import(D->getType());
1330 if (T.isNull())
1331 return 0;
1332
1333 // Create the imported parameter.
1334 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
1335 ParmVarDecl *ToParm = ParmVarDecl::Create(Importer.getToContext(), DC,
1336 Loc, Name.getAsIdentifierInfo(),
1337 T, TInfo, D->getStorageClass(),
1338 /*FIXME: Default argument*/ 0);
1339 Importer.getImportedDecls()[D] = ToParm;
1340 return ToParm;
1341}
1342
Douglas Gregor4800d952010-02-11 19:21:55 +00001343//----------------------------------------------------------------------------
1344// Import Statements
1345//----------------------------------------------------------------------------
1346
1347Stmt *ASTNodeImporter::VisitStmt(Stmt *S) {
1348 Importer.FromDiag(S->getLocStart(), diag::err_unsupported_ast_node)
1349 << S->getStmtClassName();
1350 return 0;
1351}
1352
1353//----------------------------------------------------------------------------
1354// Import Expressions
1355//----------------------------------------------------------------------------
1356Expr *ASTNodeImporter::VisitExpr(Expr *E) {
1357 Importer.FromDiag(E->getLocStart(), diag::err_unsupported_ast_node)
1358 << E->getStmtClassName();
1359 return 0;
1360}
1361
1362Expr *ASTNodeImporter::VisitIntegerLiteral(IntegerLiteral *E) {
1363 QualType T = Importer.Import(E->getType());
1364 if (T.isNull())
1365 return 0;
1366
1367 return new (Importer.getToContext())
1368 IntegerLiteral(E->getValue(), T, Importer.Import(E->getLocation()));
1369}
1370
Douglas Gregor36ead2e2010-02-12 22:17:39 +00001371Expr *ASTNodeImporter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
1372 QualType T = Importer.Import(E->getType());
1373 if (T.isNull())
1374 return 0;
1375
1376 Expr *SubExpr = Importer.Import(E->getSubExpr());
1377 if (!SubExpr)
1378 return 0;
1379
1380 return new (Importer.getToContext()) ImplicitCastExpr(T, E->getCastKind(),
1381 SubExpr,
1382 E->isLvalueCast());
1383}
1384
Douglas Gregor4800d952010-02-11 19:21:55 +00001385ASTImporter::ASTImporter(Diagnostic &Diags,
1386 ASTContext &ToContext, FileManager &ToFileManager,
1387 ASTContext &FromContext, FileManager &FromFileManager)
Douglas Gregor1b2949d2010-02-05 17:54:41 +00001388 : ToContext(ToContext), FromContext(FromContext),
Douglas Gregor88523732010-02-10 00:15:17 +00001389 ToFileManager(ToFileManager), FromFileManager(FromFileManager),
Douglas Gregor4800d952010-02-11 19:21:55 +00001390 Diags(Diags) {
Douglas Gregor9bed8792010-02-09 19:21:46 +00001391 ImportedDecls[FromContext.getTranslationUnitDecl()]
1392 = ToContext.getTranslationUnitDecl();
1393}
1394
1395ASTImporter::~ASTImporter() { }
Douglas Gregor1b2949d2010-02-05 17:54:41 +00001396
1397QualType ASTImporter::Import(QualType FromT) {
1398 if (FromT.isNull())
1399 return QualType();
1400
Douglas Gregor169fba52010-02-08 15:18:58 +00001401 // Check whether we've already imported this type.
1402 llvm::DenseMap<Type *, Type *>::iterator Pos
1403 = ImportedTypes.find(FromT.getTypePtr());
1404 if (Pos != ImportedTypes.end())
1405 return ToContext.getQualifiedType(Pos->second, FromT.getQualifiers());
Douglas Gregor1b2949d2010-02-05 17:54:41 +00001406
Douglas Gregor169fba52010-02-08 15:18:58 +00001407 // Import the type
Douglas Gregor1b2949d2010-02-05 17:54:41 +00001408 ASTNodeImporter Importer(*this);
1409 QualType ToT = Importer.Visit(FromT.getTypePtr());
1410 if (ToT.isNull())
1411 return ToT;
1412
Douglas Gregor169fba52010-02-08 15:18:58 +00001413 // Record the imported type.
1414 ImportedTypes[FromT.getTypePtr()] = ToT.getTypePtr();
1415
Douglas Gregor1b2949d2010-02-05 17:54:41 +00001416 return ToContext.getQualifiedType(ToT, FromT.getQualifiers());
1417}
1418
Douglas Gregor9bed8792010-02-09 19:21:46 +00001419TypeSourceInfo *ASTImporter::Import(TypeSourceInfo *FromTSI) {
Douglas Gregor82fc4bf2010-02-10 17:47:19 +00001420 if (!FromTSI)
1421 return FromTSI;
1422
1423 // FIXME: For now we just create a "trivial" type source info based
1424 // on the type and a seingle location. Implement a real version of
1425 // this.
1426 QualType T = Import(FromTSI->getType());
1427 if (T.isNull())
1428 return 0;
1429
1430 return ToContext.getTrivialTypeSourceInfo(T,
1431 FromTSI->getTypeLoc().getFullSourceRange().getBegin());
Douglas Gregor9bed8792010-02-09 19:21:46 +00001432}
1433
1434Decl *ASTImporter::Import(Decl *FromD) {
1435 if (!FromD)
1436 return 0;
1437
1438 // Check whether we've already imported this declaration.
1439 llvm::DenseMap<Decl *, Decl *>::iterator Pos = ImportedDecls.find(FromD);
1440 if (Pos != ImportedDecls.end())
1441 return Pos->second;
1442
1443 // Import the type
1444 ASTNodeImporter Importer(*this);
1445 Decl *ToD = Importer.Visit(FromD);
1446 if (!ToD)
1447 return 0;
1448
1449 // Record the imported declaration.
1450 ImportedDecls[FromD] = ToD;
1451 return ToD;
1452}
1453
1454DeclContext *ASTImporter::ImportContext(DeclContext *FromDC) {
1455 if (!FromDC)
1456 return FromDC;
1457
1458 return cast_or_null<DeclContext>(Import(cast<Decl>(FromDC)));
1459}
1460
1461Expr *ASTImporter::Import(Expr *FromE) {
1462 if (!FromE)
1463 return 0;
1464
1465 return cast_or_null<Expr>(Import(cast<Stmt>(FromE)));
1466}
1467
1468Stmt *ASTImporter::Import(Stmt *FromS) {
1469 if (!FromS)
1470 return 0;
1471
Douglas Gregor4800d952010-02-11 19:21:55 +00001472 // Check whether we've already imported this declaration.
1473 llvm::DenseMap<Stmt *, Stmt *>::iterator Pos = ImportedStmts.find(FromS);
1474 if (Pos != ImportedStmts.end())
1475 return Pos->second;
1476
1477 // Import the type
1478 ASTNodeImporter Importer(*this);
1479 Stmt *ToS = Importer.Visit(FromS);
1480 if (!ToS)
1481 return 0;
1482
1483 // Record the imported declaration.
1484 ImportedStmts[FromS] = ToS;
1485 return ToS;
Douglas Gregor9bed8792010-02-09 19:21:46 +00001486}
1487
1488NestedNameSpecifier *ASTImporter::Import(NestedNameSpecifier *FromNNS) {
1489 if (!FromNNS)
1490 return 0;
1491
1492 // FIXME: Implement!
1493 return 0;
1494}
1495
1496SourceLocation ASTImporter::Import(SourceLocation FromLoc) {
1497 if (FromLoc.isInvalid())
1498 return SourceLocation();
1499
Douglas Gregor88523732010-02-10 00:15:17 +00001500 SourceManager &FromSM = FromContext.getSourceManager();
1501
1502 // For now, map everything down to its spelling location, so that we
1503 // don't have to import macro instantiations.
1504 // FIXME: Import macro instantiations!
1505 FromLoc = FromSM.getSpellingLoc(FromLoc);
1506 std::pair<FileID, unsigned> Decomposed = FromSM.getDecomposedLoc(FromLoc);
1507 SourceManager &ToSM = ToContext.getSourceManager();
1508 return ToSM.getLocForStartOfFile(Import(Decomposed.first))
1509 .getFileLocWithOffset(Decomposed.second);
Douglas Gregor9bed8792010-02-09 19:21:46 +00001510}
1511
1512SourceRange ASTImporter::Import(SourceRange FromRange) {
1513 return SourceRange(Import(FromRange.getBegin()), Import(FromRange.getEnd()));
1514}
1515
Douglas Gregor88523732010-02-10 00:15:17 +00001516FileID ASTImporter::Import(FileID FromID) {
1517 llvm::DenseMap<unsigned, FileID>::iterator Pos
1518 = ImportedFileIDs.find(FromID.getHashValue());
1519 if (Pos != ImportedFileIDs.end())
1520 return Pos->second;
1521
1522 SourceManager &FromSM = FromContext.getSourceManager();
1523 SourceManager &ToSM = ToContext.getSourceManager();
1524 const SrcMgr::SLocEntry &FromSLoc = FromSM.getSLocEntry(FromID);
1525 assert(FromSLoc.isFile() && "Cannot handle macro instantiations yet");
1526
1527 // Include location of this file.
1528 SourceLocation ToIncludeLoc = Import(FromSLoc.getFile().getIncludeLoc());
1529
1530 // Map the FileID for to the "to" source manager.
1531 FileID ToID;
1532 const SrcMgr::ContentCache *Cache = FromSLoc.getFile().getContentCache();
1533 if (Cache->Entry) {
1534 // FIXME: We probably want to use getVirtualFile(), so we don't hit the
1535 // disk again
1536 // FIXME: We definitely want to re-use the existing MemoryBuffer, rather
1537 // than mmap the files several times.
1538 const FileEntry *Entry = ToFileManager.getFile(Cache->Entry->getName());
1539 ToID = ToSM.createFileID(Entry, ToIncludeLoc,
1540 FromSLoc.getFile().getFileCharacteristic());
1541 } else {
1542 // FIXME: We want to re-use the existing MemoryBuffer!
1543 const llvm::MemoryBuffer *FromBuf = Cache->getBuffer();
1544 llvm::MemoryBuffer *ToBuf
1545 = llvm::MemoryBuffer::getMemBufferCopy(FromBuf->getBufferStart(),
1546 FromBuf->getBufferEnd(),
1547 FromBuf->getBufferIdentifier());
1548 ToID = ToSM.createFileIDForMemBuffer(ToBuf);
1549 }
1550
1551
1552 ImportedFileIDs[FromID.getHashValue()] = ToID;
1553 return ToID;
1554}
1555
Douglas Gregor1b2949d2010-02-05 17:54:41 +00001556DeclarationName ASTImporter::Import(DeclarationName FromName) {
1557 if (!FromName)
1558 return DeclarationName();
1559
1560 switch (FromName.getNameKind()) {
1561 case DeclarationName::Identifier:
1562 return Import(FromName.getAsIdentifierInfo());
1563
1564 case DeclarationName::ObjCZeroArgSelector:
1565 case DeclarationName::ObjCOneArgSelector:
1566 case DeclarationName::ObjCMultiArgSelector:
1567 return Import(FromName.getObjCSelector());
1568
1569 case DeclarationName::CXXConstructorName: {
1570 QualType T = Import(FromName.getCXXNameType());
1571 if (T.isNull())
1572 return DeclarationName();
1573
1574 return ToContext.DeclarationNames.getCXXConstructorName(
1575 ToContext.getCanonicalType(T));
1576 }
1577
1578 case DeclarationName::CXXDestructorName: {
1579 QualType T = Import(FromName.getCXXNameType());
1580 if (T.isNull())
1581 return DeclarationName();
1582
1583 return ToContext.DeclarationNames.getCXXDestructorName(
1584 ToContext.getCanonicalType(T));
1585 }
1586
1587 case DeclarationName::CXXConversionFunctionName: {
1588 QualType T = Import(FromName.getCXXNameType());
1589 if (T.isNull())
1590 return DeclarationName();
1591
1592 return ToContext.DeclarationNames.getCXXConversionFunctionName(
1593 ToContext.getCanonicalType(T));
1594 }
1595
1596 case DeclarationName::CXXOperatorName:
1597 return ToContext.DeclarationNames.getCXXOperatorName(
1598 FromName.getCXXOverloadedOperator());
1599
1600 case DeclarationName::CXXLiteralOperatorName:
1601 return ToContext.DeclarationNames.getCXXLiteralOperatorName(
1602 Import(FromName.getCXXLiteralIdentifier()));
1603
1604 case DeclarationName::CXXUsingDirective:
1605 // FIXME: STATICS!
1606 return DeclarationName::getUsingDirectiveName();
1607 }
1608
1609 // Silence bogus GCC warning
1610 return DeclarationName();
1611}
1612
1613IdentifierInfo *ASTImporter::Import(IdentifierInfo *FromId) {
1614 if (!FromId)
1615 return 0;
1616
1617 return &ToContext.Idents.get(FromId->getName());
1618}
Douglas Gregor089459a2010-02-08 21:09:39 +00001619
1620DeclarationName ASTImporter::HandleNameConflict(DeclarationName Name,
1621 DeclContext *DC,
1622 unsigned IDNS,
1623 NamedDecl **Decls,
1624 unsigned NumDecls) {
1625 return Name;
1626}
1627
1628DiagnosticBuilder ASTImporter::ToDiag(SourceLocation Loc, unsigned DiagID) {
Douglas Gregor4800d952010-02-11 19:21:55 +00001629 return Diags.Report(FullSourceLoc(Loc, ToContext.getSourceManager()),
1630 DiagID);
Douglas Gregor089459a2010-02-08 21:09:39 +00001631}
1632
1633DiagnosticBuilder ASTImporter::FromDiag(SourceLocation Loc, unsigned DiagID) {
Douglas Gregor4800d952010-02-11 19:21:55 +00001634 return Diags.Report(FullSourceLoc(Loc, FromContext.getSourceManager()),
1635 DiagID);
Douglas Gregor089459a2010-02-08 21:09:39 +00001636}