blob: 62cc33925428a8d0c3fae01fd1c81b88d84b725d [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 Gregorfa7a0e52010-02-10 17:47:19 +000021#include "clang/AST/TypeLoc.h"
Douglas Gregor96e578d2010-02-05 17:54:41 +000022#include "clang/AST/TypeVisitor.h"
Douglas Gregor811663e2010-02-10 00:15:17 +000023#include "clang/Basic/FileManager.h"
24#include "clang/Basic/SourceManager.h"
25#include "llvm/Support/MemoryBuffer.h"
Douglas Gregor96e578d2010-02-05 17:54:41 +000026
27using namespace clang;
28
29namespace {
Douglas Gregor3aed6cd2010-02-08 21:09:39 +000030 class ASTNodeImporter : public TypeVisitor<ASTNodeImporter, QualType>,
31 public DeclVisitor<ASTNodeImporter, Decl *> {
Douglas Gregor96e578d2010-02-05 17:54:41 +000032 ASTImporter &Importer;
33
34 public:
35 explicit ASTNodeImporter(ASTImporter &Importer) : Importer(Importer) { }
36
37 using TypeVisitor<ASTNodeImporter, QualType>::Visit;
Douglas Gregor62d311f2010-02-09 19:21:46 +000038 using DeclVisitor<ASTNodeImporter, Decl *>::Visit;
Douglas Gregor96e578d2010-02-05 17:54:41 +000039
40 // Importing types
Douglas Gregore4c83e42010-02-09 22:48:33 +000041 QualType VisitType(Type *T);
Douglas Gregor96e578d2010-02-05 17:54:41 +000042 QualType VisitBuiltinType(BuiltinType *T);
43 QualType VisitComplexType(ComplexType *T);
44 QualType VisitPointerType(PointerType *T);
45 QualType VisitBlockPointerType(BlockPointerType *T);
46 QualType VisitLValueReferenceType(LValueReferenceType *T);
47 QualType VisitRValueReferenceType(RValueReferenceType *T);
48 QualType VisitMemberPointerType(MemberPointerType *T);
49 QualType VisitConstantArrayType(ConstantArrayType *T);
50 QualType VisitIncompleteArrayType(IncompleteArrayType *T);
51 QualType VisitVariableArrayType(VariableArrayType *T);
52 // FIXME: DependentSizedArrayType
53 // FIXME: DependentSizedExtVectorType
54 QualType VisitVectorType(VectorType *T);
55 QualType VisitExtVectorType(ExtVectorType *T);
56 QualType VisitFunctionNoProtoType(FunctionNoProtoType *T);
57 QualType VisitFunctionProtoType(FunctionProtoType *T);
58 // FIXME: UnresolvedUsingType
59 QualType VisitTypedefType(TypedefType *T);
60 QualType VisitTypeOfExprType(TypeOfExprType *T);
61 // FIXME: DependentTypeOfExprType
62 QualType VisitTypeOfType(TypeOfType *T);
63 QualType VisitDecltypeType(DecltypeType *T);
64 // FIXME: DependentDecltypeType
65 QualType VisitRecordType(RecordType *T);
66 QualType VisitEnumType(EnumType *T);
67 QualType VisitElaboratedType(ElaboratedType *T);
68 // FIXME: TemplateTypeParmType
69 // FIXME: SubstTemplateTypeParmType
70 // FIXME: TemplateSpecializationType
71 QualType VisitQualifiedNameType(QualifiedNameType *T);
72 // FIXME: TypenameType
73 QualType VisitObjCInterfaceType(ObjCInterfaceType *T);
74 QualType VisitObjCObjectPointerType(ObjCObjectPointerType *T);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +000075
76 // Importing declarations
Douglas Gregorbb7930c2010-02-10 19:54:31 +000077 bool ImportDeclParts(NamedDecl *D, DeclContext *&DC,
78 DeclContext *&LexicalDC, DeclarationName &Name,
79 SourceLocation &Loc);
80 bool ImportDeclParts(DeclaratorDecl *D,
81 DeclContext *&DC, DeclContext *&LexicalDC,
82 DeclarationName &Name, SourceLocation &Loc,
83 QualType &T);
Douglas Gregor5c73e912010-02-11 00:48:18 +000084 bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord);
Douglas Gregore4c83e42010-02-09 22:48:33 +000085 Decl *VisitDecl(Decl *D);
Douglas Gregor5fa74c32010-02-10 21:10:29 +000086 Decl *VisitTypedefDecl(TypedefDecl *D);
Douglas Gregor5c73e912010-02-11 00:48:18 +000087 Decl *VisitRecordDecl(RecordDecl *D);
Douglas Gregorbb7930c2010-02-10 19:54:31 +000088 Decl *VisitFunctionDecl(FunctionDecl *D);
Douglas Gregor5c73e912010-02-11 00:48:18 +000089 Decl *VisitFieldDecl(FieldDecl *D);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +000090 Decl *VisitVarDecl(VarDecl *D);
Douglas Gregorbb7930c2010-02-10 19:54:31 +000091 Decl *VisitParmVarDecl(ParmVarDecl *D);
Douglas Gregor96e578d2010-02-05 17:54:41 +000092 };
93}
94
95//----------------------------------------------------------------------------
96// Import Types
97//----------------------------------------------------------------------------
98
Douglas Gregore4c83e42010-02-09 22:48:33 +000099QualType ASTNodeImporter::VisitType(Type *T) {
100 Importer.FromDiag(SourceLocation(), diag::err_unsupported_ast_node)
101 << T->getTypeClassName();
102 return QualType();
103}
104
Douglas Gregor96e578d2010-02-05 17:54:41 +0000105QualType ASTNodeImporter::VisitBuiltinType(BuiltinType *T) {
106 switch (T->getKind()) {
107 case BuiltinType::Void: return Importer.getToContext().VoidTy;
108 case BuiltinType::Bool: return Importer.getToContext().BoolTy;
109
110 case BuiltinType::Char_U:
111 // The context we're importing from has an unsigned 'char'. If we're
112 // importing into a context with a signed 'char', translate to
113 // 'unsigned char' instead.
114 if (Importer.getToContext().getLangOptions().CharIsSigned)
115 return Importer.getToContext().UnsignedCharTy;
116
117 return Importer.getToContext().CharTy;
118
119 case BuiltinType::UChar: return Importer.getToContext().UnsignedCharTy;
120
121 case BuiltinType::Char16:
122 // FIXME: Make sure that the "to" context supports C++!
123 return Importer.getToContext().Char16Ty;
124
125 case BuiltinType::Char32:
126 // FIXME: Make sure that the "to" context supports C++!
127 return Importer.getToContext().Char32Ty;
128
129 case BuiltinType::UShort: return Importer.getToContext().UnsignedShortTy;
130 case BuiltinType::UInt: return Importer.getToContext().UnsignedIntTy;
131 case BuiltinType::ULong: return Importer.getToContext().UnsignedLongTy;
132 case BuiltinType::ULongLong:
133 return Importer.getToContext().UnsignedLongLongTy;
134 case BuiltinType::UInt128: return Importer.getToContext().UnsignedInt128Ty;
135
136 case BuiltinType::Char_S:
137 // The context we're importing from has an unsigned 'char'. If we're
138 // importing into a context with a signed 'char', translate to
139 // 'unsigned char' instead.
140 if (!Importer.getToContext().getLangOptions().CharIsSigned)
141 return Importer.getToContext().SignedCharTy;
142
143 return Importer.getToContext().CharTy;
144
145 case BuiltinType::SChar: return Importer.getToContext().SignedCharTy;
146 case BuiltinType::WChar:
147 // FIXME: If not in C++, shall we translate to the C equivalent of
148 // wchar_t?
149 return Importer.getToContext().WCharTy;
150
151 case BuiltinType::Short : return Importer.getToContext().ShortTy;
152 case BuiltinType::Int : return Importer.getToContext().IntTy;
153 case BuiltinType::Long : return Importer.getToContext().LongTy;
154 case BuiltinType::LongLong : return Importer.getToContext().LongLongTy;
155 case BuiltinType::Int128 : return Importer.getToContext().Int128Ty;
156 case BuiltinType::Float: return Importer.getToContext().FloatTy;
157 case BuiltinType::Double: return Importer.getToContext().DoubleTy;
158 case BuiltinType::LongDouble: return Importer.getToContext().LongDoubleTy;
159
160 case BuiltinType::NullPtr:
161 // FIXME: Make sure that the "to" context supports C++0x!
162 return Importer.getToContext().NullPtrTy;
163
164 case BuiltinType::Overload: return Importer.getToContext().OverloadTy;
165 case BuiltinType::Dependent: return Importer.getToContext().DependentTy;
166 case BuiltinType::UndeducedAuto:
167 // FIXME: Make sure that the "to" context supports C++0x!
168 return Importer.getToContext().UndeducedAutoTy;
169
170 case BuiltinType::ObjCId:
171 // FIXME: Make sure that the "to" context supports Objective-C!
172 return Importer.getToContext().ObjCBuiltinIdTy;
173
174 case BuiltinType::ObjCClass:
175 return Importer.getToContext().ObjCBuiltinClassTy;
176
177 case BuiltinType::ObjCSel:
178 return Importer.getToContext().ObjCBuiltinSelTy;
179 }
180
181 return QualType();
182}
183
184QualType ASTNodeImporter::VisitComplexType(ComplexType *T) {
185 QualType ToElementType = Importer.Import(T->getElementType());
186 if (ToElementType.isNull())
187 return QualType();
188
189 return Importer.getToContext().getComplexType(ToElementType);
190}
191
192QualType ASTNodeImporter::VisitPointerType(PointerType *T) {
193 QualType ToPointeeType = Importer.Import(T->getPointeeType());
194 if (ToPointeeType.isNull())
195 return QualType();
196
197 return Importer.getToContext().getPointerType(ToPointeeType);
198}
199
200QualType ASTNodeImporter::VisitBlockPointerType(BlockPointerType *T) {
201 // FIXME: Check for blocks support in "to" context.
202 QualType ToPointeeType = Importer.Import(T->getPointeeType());
203 if (ToPointeeType.isNull())
204 return QualType();
205
206 return Importer.getToContext().getBlockPointerType(ToPointeeType);
207}
208
209QualType ASTNodeImporter::VisitLValueReferenceType(LValueReferenceType *T) {
210 // FIXME: Check for C++ support in "to" context.
211 QualType ToPointeeType = Importer.Import(T->getPointeeTypeAsWritten());
212 if (ToPointeeType.isNull())
213 return QualType();
214
215 return Importer.getToContext().getLValueReferenceType(ToPointeeType);
216}
217
218QualType ASTNodeImporter::VisitRValueReferenceType(RValueReferenceType *T) {
219 // FIXME: Check for C++0x support in "to" context.
220 QualType ToPointeeType = Importer.Import(T->getPointeeTypeAsWritten());
221 if (ToPointeeType.isNull())
222 return QualType();
223
224 return Importer.getToContext().getRValueReferenceType(ToPointeeType);
225}
226
227QualType ASTNodeImporter::VisitMemberPointerType(MemberPointerType *T) {
228 // FIXME: Check for C++ support in "to" context.
229 QualType ToPointeeType = Importer.Import(T->getPointeeType());
230 if (ToPointeeType.isNull())
231 return QualType();
232
233 QualType ClassType = Importer.Import(QualType(T->getClass(), 0));
234 return Importer.getToContext().getMemberPointerType(ToPointeeType,
235 ClassType.getTypePtr());
236}
237
238QualType ASTNodeImporter::VisitConstantArrayType(ConstantArrayType *T) {
239 QualType ToElementType = Importer.Import(T->getElementType());
240 if (ToElementType.isNull())
241 return QualType();
242
243 return Importer.getToContext().getConstantArrayType(ToElementType,
244 T->getSize(),
245 T->getSizeModifier(),
246 T->getIndexTypeCVRQualifiers());
247}
248
249QualType ASTNodeImporter::VisitIncompleteArrayType(IncompleteArrayType *T) {
250 QualType ToElementType = Importer.Import(T->getElementType());
251 if (ToElementType.isNull())
252 return QualType();
253
254 return Importer.getToContext().getIncompleteArrayType(ToElementType,
255 T->getSizeModifier(),
256 T->getIndexTypeCVRQualifiers());
257}
258
259QualType ASTNodeImporter::VisitVariableArrayType(VariableArrayType *T) {
260 QualType ToElementType = Importer.Import(T->getElementType());
261 if (ToElementType.isNull())
262 return QualType();
263
264 Expr *Size = Importer.Import(T->getSizeExpr());
265 if (!Size)
266 return QualType();
267
268 SourceRange Brackets = Importer.Import(T->getBracketsRange());
269 return Importer.getToContext().getVariableArrayType(ToElementType, Size,
270 T->getSizeModifier(),
271 T->getIndexTypeCVRQualifiers(),
272 Brackets);
273}
274
275QualType ASTNodeImporter::VisitVectorType(VectorType *T) {
276 QualType ToElementType = Importer.Import(T->getElementType());
277 if (ToElementType.isNull())
278 return QualType();
279
280 return Importer.getToContext().getVectorType(ToElementType,
281 T->getNumElements(),
282 T->isAltiVec(),
283 T->isPixel());
284}
285
286QualType ASTNodeImporter::VisitExtVectorType(ExtVectorType *T) {
287 QualType ToElementType = Importer.Import(T->getElementType());
288 if (ToElementType.isNull())
289 return QualType();
290
291 return Importer.getToContext().getExtVectorType(ToElementType,
292 T->getNumElements());
293}
294
295QualType ASTNodeImporter::VisitFunctionNoProtoType(FunctionNoProtoType *T) {
296 // FIXME: What happens if we're importing a function without a prototype
297 // into C++? Should we make it variadic?
298 QualType ToResultType = Importer.Import(T->getResultType());
299 if (ToResultType.isNull())
300 return QualType();
301
302 return Importer.getToContext().getFunctionNoProtoType(ToResultType,
303 T->getNoReturnAttr(),
304 T->getCallConv());
305}
306
307QualType ASTNodeImporter::VisitFunctionProtoType(FunctionProtoType *T) {
308 QualType ToResultType = Importer.Import(T->getResultType());
309 if (ToResultType.isNull())
310 return QualType();
311
312 // Import argument types
313 llvm::SmallVector<QualType, 4> ArgTypes;
314 for (FunctionProtoType::arg_type_iterator A = T->arg_type_begin(),
315 AEnd = T->arg_type_end();
316 A != AEnd; ++A) {
317 QualType ArgType = Importer.Import(*A);
318 if (ArgType.isNull())
319 return QualType();
320 ArgTypes.push_back(ArgType);
321 }
322
323 // Import exception types
324 llvm::SmallVector<QualType, 4> ExceptionTypes;
325 for (FunctionProtoType::exception_iterator E = T->exception_begin(),
326 EEnd = T->exception_end();
327 E != EEnd; ++E) {
328 QualType ExceptionType = Importer.Import(*E);
329 if (ExceptionType.isNull())
330 return QualType();
331 ExceptionTypes.push_back(ExceptionType);
332 }
333
334 return Importer.getToContext().getFunctionType(ToResultType, ArgTypes.data(),
335 ArgTypes.size(),
336 T->isVariadic(),
337 T->getTypeQuals(),
338 T->hasExceptionSpec(),
339 T->hasAnyExceptionSpec(),
340 ExceptionTypes.size(),
341 ExceptionTypes.data(),
342 T->getNoReturnAttr(),
343 T->getCallConv());
344}
345
346QualType ASTNodeImporter::VisitTypedefType(TypedefType *T) {
347 TypedefDecl *ToDecl
348 = dyn_cast_or_null<TypedefDecl>(Importer.Import(T->getDecl()));
349 if (!ToDecl)
350 return QualType();
351
352 return Importer.getToContext().getTypeDeclType(ToDecl);
353}
354
355QualType ASTNodeImporter::VisitTypeOfExprType(TypeOfExprType *T) {
356 Expr *ToExpr = Importer.Import(T->getUnderlyingExpr());
357 if (!ToExpr)
358 return QualType();
359
360 return Importer.getToContext().getTypeOfExprType(ToExpr);
361}
362
363QualType ASTNodeImporter::VisitTypeOfType(TypeOfType *T) {
364 QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType());
365 if (ToUnderlyingType.isNull())
366 return QualType();
367
368 return Importer.getToContext().getTypeOfType(ToUnderlyingType);
369}
370
371QualType ASTNodeImporter::VisitDecltypeType(DecltypeType *T) {
372 Expr *ToExpr = Importer.Import(T->getUnderlyingExpr());
373 if (!ToExpr)
374 return QualType();
375
376 return Importer.getToContext().getDecltypeType(ToExpr);
377}
378
379QualType ASTNodeImporter::VisitRecordType(RecordType *T) {
380 RecordDecl *ToDecl
381 = dyn_cast_or_null<RecordDecl>(Importer.Import(T->getDecl()));
382 if (!ToDecl)
383 return QualType();
384
385 return Importer.getToContext().getTagDeclType(ToDecl);
386}
387
388QualType ASTNodeImporter::VisitEnumType(EnumType *T) {
389 EnumDecl *ToDecl
390 = dyn_cast_or_null<EnumDecl>(Importer.Import(T->getDecl()));
391 if (!ToDecl)
392 return QualType();
393
394 return Importer.getToContext().getTagDeclType(ToDecl);
395}
396
397QualType ASTNodeImporter::VisitElaboratedType(ElaboratedType *T) {
398 QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType());
399 if (ToUnderlyingType.isNull())
400 return QualType();
401
402 return Importer.getToContext().getElaboratedType(ToUnderlyingType,
403 T->getTagKind());
404}
405
406QualType ASTNodeImporter::VisitQualifiedNameType(QualifiedNameType *T) {
407 NestedNameSpecifier *ToQualifier = Importer.Import(T->getQualifier());
408 if (!ToQualifier)
409 return QualType();
410
411 QualType ToNamedType = Importer.Import(T->getNamedType());
412 if (ToNamedType.isNull())
413 return QualType();
414
415 return Importer.getToContext().getQualifiedNameType(ToQualifier, ToNamedType);
416}
417
418QualType ASTNodeImporter::VisitObjCInterfaceType(ObjCInterfaceType *T) {
419 ObjCInterfaceDecl *Class
420 = dyn_cast_or_null<ObjCInterfaceDecl>(Importer.Import(T->getDecl()));
421 if (!Class)
422 return QualType();
423
424 llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
425 for (ObjCInterfaceType::qual_iterator P = T->qual_begin(),
426 PEnd = T->qual_end();
427 P != PEnd; ++P) {
428 ObjCProtocolDecl *Protocol
429 = dyn_cast_or_null<ObjCProtocolDecl>(Importer.Import(*P));
430 if (!Protocol)
431 return QualType();
432 Protocols.push_back(Protocol);
433 }
434
435 return Importer.getToContext().getObjCInterfaceType(Class,
436 Protocols.data(),
437 Protocols.size());
438}
439
440QualType ASTNodeImporter::VisitObjCObjectPointerType(ObjCObjectPointerType *T) {
441 QualType ToPointeeType = Importer.Import(T->getPointeeType());
442 if (ToPointeeType.isNull())
443 return QualType();
444
445 llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
446 for (ObjCObjectPointerType::qual_iterator P = T->qual_begin(),
447 PEnd = T->qual_end();
448 P != PEnd; ++P) {
449 ObjCProtocolDecl *Protocol
450 = dyn_cast_or_null<ObjCProtocolDecl>(Importer.Import(*P));
451 if (!Protocol)
452 return QualType();
453 Protocols.push_back(Protocol);
454 }
455
456 return Importer.getToContext().getObjCObjectPointerType(ToPointeeType,
457 Protocols.data(),
458 Protocols.size());
459}
460
Douglas Gregor3aed6cd2010-02-08 21:09:39 +0000461//----------------------------------------------------------------------------
462// Import Declarations
463//----------------------------------------------------------------------------
Douglas Gregorbb7930c2010-02-10 19:54:31 +0000464bool ASTNodeImporter::ImportDeclParts(NamedDecl *D, DeclContext *&DC,
465 DeclContext *&LexicalDC,
466 DeclarationName &Name,
467 SourceLocation &Loc) {
468 // Import the context of this declaration.
469 DC = Importer.ImportContext(D->getDeclContext());
470 if (!DC)
471 return true;
472
473 LexicalDC = DC;
474 if (D->getDeclContext() != D->getLexicalDeclContext()) {
475 LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
476 if (!LexicalDC)
477 return true;
478 }
479
480 // Import the name of this declaration.
481 Name = Importer.Import(D->getDeclName());
482 if (D->getDeclName() && !Name)
483 return true;
484
485 // Import the location of this declaration.
486 Loc = Importer.Import(D->getLocation());
487 return false;
488}
489
490bool ASTNodeImporter::ImportDeclParts(DeclaratorDecl *D,
491 DeclContext *&DC,
492 DeclContext *&LexicalDC,
493 DeclarationName &Name,
494 SourceLocation &Loc,
495 QualType &T) {
496 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
497 return true;
498
499 // Import the type of this declaration.
500 T = Importer.Import(D->getType());
501 if (T.isNull())
502 return true;
503
504 return false;
505}
506
Douglas Gregor5c73e912010-02-11 00:48:18 +0000507bool ASTNodeImporter::IsStructuralMatch(RecordDecl *FromRecord,
508 RecordDecl *ToRecord) {
509 // FIXME: If we know that the two records are the same according to the ODR,
510 // we could diagnose structural mismatches here. However, we don't really
511 // have that information.
512 if (FromRecord->isUnion() != ToRecord->isUnion())
513 return false;
514
515 if (CXXRecordDecl *FromCXX = dyn_cast<CXXRecordDecl>(FromRecord)) {
516 if (CXXRecordDecl *ToCXX = dyn_cast<CXXRecordDecl>(ToRecord)) {
517 if (FromCXX->getNumBases() != ToCXX->getNumBases())
518 return false;
519
520 // Check the base classes.
521 for (CXXRecordDecl::base_class_iterator FromBase = FromCXX->bases_begin(),
522 FromBaseEnd = FromCXX->bases_end(),
523 ToBase = ToCXX->bases_begin();
524 FromBase != FromBaseEnd;
525 ++FromBase, ++ToBase) {
526 // Check virtual vs. non-virtual inheritance mismatch.
527 if (FromBase->isVirtual() != ToBase->isVirtual())
528 return false;
529
530 // Check the type we're inheriting from.
531 QualType FromBaseT = Importer.Import(FromBase->getType());
532 if (FromBaseT.isNull())
533 return false;
534
535 if (!Importer.getToContext().typesAreCompatible(FromBaseT,
536 ToBase->getType()))
537 return false;
538 }
539 } else if (FromCXX->getNumBases() > 0) {
540 return false;
541 }
542 }
543
544 // Check the fields for consistency.
545 CXXRecordDecl::field_iterator ToField = ToRecord->field_begin(),
546 ToFieldEnd = ToRecord->field_end();
547 for (CXXRecordDecl::field_iterator FromField = FromRecord->field_begin(),
548 FromFieldEnd = FromRecord->field_end();
549 FromField != FromFieldEnd;
550 ++FromField, ++ToField) {
551 if (ToField == ToFieldEnd)
552 return false;
553
554 QualType FromT = Importer.Import(FromField->getType());
555 if (FromT.isNull())
556 return false;
557
558 if (FromField->isBitField() != ToField->isBitField())
559 return false;
560
561 if (!Importer.getToContext().typesAreCompatible(FromT, ToField->getType()))
562 return false;
563
564 if (FromField->isBitField()) {
565 // Make sure that the bit-fields are the same length.
566 llvm::APSInt FromBits, ToBits;
567 if (!FromField->getBitWidth()->isIntegerConstantExpr(FromBits,
568 Importer.getFromContext()))
569 return false;
570 if (!ToField->getBitWidth()->isIntegerConstantExpr(ToBits,
571 Importer.getToContext()))
572 return false;
573
574 if (FromBits.getBitWidth() > ToBits.getBitWidth())
575 ToBits.extend(FromBits.getBitWidth());
576 else if (ToBits.getBitWidth() > FromBits.getBitWidth())
577 FromBits.extend(ToBits.getBitWidth());
578
579 FromBits.setIsUnsigned(true);
580 ToBits.setIsUnsigned(true);
581
582 if (FromBits != ToBits)
583 return false;
584 }
585 }
586
587 return ToField == ToFieldEnd;
588}
589
Douglas Gregore4c83e42010-02-09 22:48:33 +0000590Decl *ASTNodeImporter::VisitDecl(Decl *D) {
Douglas Gregor811663e2010-02-10 00:15:17 +0000591 Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node)
Douglas Gregore4c83e42010-02-09 22:48:33 +0000592 << D->getDeclKindName();
593 return 0;
594}
595
Douglas Gregor5fa74c32010-02-10 21:10:29 +0000596Decl *ASTNodeImporter::VisitTypedefDecl(TypedefDecl *D) {
597 // Import the major distinguishing characteristics of this typedef.
598 DeclContext *DC, *LexicalDC;
599 DeclarationName Name;
600 SourceLocation Loc;
601 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
602 return 0;
603
604 // Import the underlying type of this typedef;
605 QualType T = Importer.Import(D->getUnderlyingType());
606 if (T.isNull())
607 return 0;
608
609 // If this typedef is not in block scope, determine whether we've
610 // seen a typedef with the same name (that we can merge with) or any
611 // other entity by that name (which name lookup could conflict with).
612 if (!DC->isFunctionOrMethod()) {
613 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
614 unsigned IDNS = Decl::IDNS_Ordinary;
615 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
616 Lookup.first != Lookup.second;
617 ++Lookup.first) {
618 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
619 continue;
620 if (TypedefDecl *FoundTypedef = dyn_cast<TypedefDecl>(*Lookup.first)) {
621 if (Importer.getToContext().typesAreCompatible(T,
622 FoundTypedef->getUnderlyingType())) {
623 Importer.getImportedDecls()[D] = FoundTypedef;
624 return FoundTypedef;
625 }
626 }
627
628 ConflictingDecls.push_back(*Lookup.first);
629 }
630
631 if (!ConflictingDecls.empty()) {
632 Name = Importer.HandleNameConflict(Name, DC, IDNS,
633 ConflictingDecls.data(),
634 ConflictingDecls.size());
635 if (!Name)
636 return 0;
637 }
638 }
639
640 // Create the new typedef node.
641 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
642 TypedefDecl *ToTypedef = TypedefDecl::Create(Importer.getToContext(), DC,
643 Loc, Name.getAsIdentifierInfo(),
644 TInfo);
645 ToTypedef->setLexicalDeclContext(LexicalDC);
646 Importer.getImportedDecls()[D] = ToTypedef;
647 LexicalDC->addDecl(ToTypedef);
648 return ToTypedef;
649}
650
Douglas Gregor5c73e912010-02-11 00:48:18 +0000651Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
652 // If this record has a definition in the translation unit we're coming from,
653 // but this particular declaration is not that definition, import the
654 // definition and map to that.
Douglas Gregor0a5a2212010-02-11 01:04:33 +0000655 TagDecl *Definition = D->getDefinition();
Douglas Gregor5c73e912010-02-11 00:48:18 +0000656 if (Definition && Definition != D) {
657 Decl *ImportedDef = Importer.Import(Definition);
658 Importer.getImportedDecls()[D] = ImportedDef;
659 return ImportedDef;
660 }
661
662 // Import the major distinguishing characteristics of this record.
663 DeclContext *DC, *LexicalDC;
664 DeclarationName Name;
665 SourceLocation Loc;
666 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
667 return 0;
668
669 // Figure out what structure name we're looking for.
670 unsigned IDNS = Decl::IDNS_Tag;
671 DeclarationName SearchName = Name;
672 if (!SearchName && D->getTypedefForAnonDecl()) {
673 SearchName = Importer.Import(D->getTypedefForAnonDecl()->getDeclName());
674 IDNS = Decl::IDNS_Ordinary;
675 } else if (Importer.getToContext().getLangOptions().CPlusPlus)
676 IDNS |= Decl::IDNS_Ordinary;
677
678 // We may already have a record of the same name; try to find and match it.
679 if (!DC->isFunctionOrMethod() && SearchName) {
680 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
681 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
682 Lookup.first != Lookup.second;
683 ++Lookup.first) {
684 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
685 continue;
686
687 Decl *Found = *Lookup.first;
688 if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(Found)) {
689 if (const TagType *Tag = Typedef->getUnderlyingType()->getAs<TagType>())
690 Found = Tag->getDecl();
691 }
692
693 if (RecordDecl *FoundRecord = dyn_cast<RecordDecl>(Found)) {
694 if (IsStructuralMatch(D, FoundRecord)) {
695 // The record types structurally match.
696 // FIXME: For C++, we should also merge methods here.
697 Importer.getImportedDecls()[D] = FoundRecord;
698 return FoundRecord;
699 }
700 }
701
702 ConflictingDecls.push_back(*Lookup.first);
703 }
704
705 if (!ConflictingDecls.empty()) {
706 Name = Importer.HandleNameConflict(Name, DC, IDNS,
707 ConflictingDecls.data(),
708 ConflictingDecls.size());
709 }
710 }
711
712 // Create the record declaration.
713 RecordDecl *ToRecord = 0;
714 if (CXXRecordDecl *FromCXX = dyn_cast<CXXRecordDecl>(D)) {
715 CXXRecordDecl *ToCXX = CXXRecordDecl::Create(Importer.getToContext(),
716 D->getTagKind(),
717 DC, Loc,
718 Name.getAsIdentifierInfo(),
719 Importer.Import(D->getTagKeywordLoc()));
720 ToRecord = ToCXX;
721
722 if (D->isDefinition()) {
723 // Add base classes.
724 llvm::SmallVector<CXXBaseSpecifier *, 4> Bases;
725 for (CXXRecordDecl::base_class_iterator FromBase = FromCXX->bases_begin(),
726 FromBaseEnd = FromCXX->bases_end();
727 FromBase != FromBaseEnd;
728 ++FromBase) {
729 QualType T = Importer.Import(FromBase->getType());
730 if (T.isNull())
731 return 0;
732
733 Bases.push_back(
734 new (Importer.getToContext())
735 CXXBaseSpecifier(Importer.Import(FromBase->getSourceRange()),
736 FromBase->isVirtual(),
737 FromBase->isBaseOfClass(),
738 FromBase->getAccessSpecifierAsWritten(),
739 T));
740 }
741 if (!Bases.empty())
Douglas Gregor4a62bdf2010-02-11 01:30:34 +0000742 ToCXX->setBases(Bases.data(), Bases.size());
Douglas Gregor5c73e912010-02-11 00:48:18 +0000743 }
744 } else {
745 ToRecord = RecordDecl::Create(Importer.getToContext(), D->getTagKind(),
746 DC, Loc,
747 Name.getAsIdentifierInfo(),
748 Importer.Import(D->getTagKeywordLoc()));
749 }
750 ToRecord->setLexicalDeclContext(LexicalDC);
751 Importer.getImportedDecls()[D] = ToRecord;
752 LexicalDC->addDecl(ToRecord);
753
754 if (D->isDefinition()) {
755 ToRecord->startDefinition();
756 for (DeclContext::decl_iterator FromMem = D->decls_begin(),
757 FromMemEnd = D->decls_end();
758 FromMem != FromMemEnd;
759 ++FromMem)
760 Importer.Import(*FromMem);
761
Douglas Gregord5058122010-02-11 01:19:42 +0000762 ToRecord->completeDefinition();
Douglas Gregor5c73e912010-02-11 00:48:18 +0000763 }
764
765 return ToRecord;
766}
767
768
Douglas Gregorbb7930c2010-02-10 19:54:31 +0000769Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
770 // Import the major distinguishing characteristics of this function.
771 DeclContext *DC, *LexicalDC;
772 DeclarationName Name;
773 QualType T;
774 SourceLocation Loc;
775 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc, T))
Douglas Gregor3aed6cd2010-02-08 21:09:39 +0000776 return 0;
Douglas Gregorbb7930c2010-02-10 19:54:31 +0000777
778 // Try to find a function in our own ("to") context with the same name, same
779 // type, and in the same context as the function we're importing.
780 if (!LexicalDC->isFunctionOrMethod()) {
781 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
782 unsigned IDNS = Decl::IDNS_Ordinary;
783 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
784 Lookup.first != Lookup.second;
785 ++Lookup.first) {
786 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
787 continue;
Douglas Gregor3aed6cd2010-02-08 21:09:39 +0000788
Douglas Gregorbb7930c2010-02-10 19:54:31 +0000789 if (FunctionDecl *FoundFunction = dyn_cast<FunctionDecl>(*Lookup.first)) {
790 if (isExternalLinkage(FoundFunction->getLinkage()) &&
791 isExternalLinkage(D->getLinkage())) {
792 if (Importer.getToContext().typesAreCompatible(T,
793 FoundFunction->getType())) {
794 // FIXME: Actually try to merge the body and other attributes.
795 Importer.getImportedDecls()[D] = FoundFunction;
796 return FoundFunction;
797 }
798
799 // FIXME: Check for overloading more carefully, e.g., by boosting
800 // Sema::IsOverload out to the AST library.
801
802 // Function overloading is okay in C++.
803 if (Importer.getToContext().getLangOptions().CPlusPlus)
804 continue;
805
806 // Complain about inconsistent function types.
807 Importer.ToDiag(Loc, diag::err_odr_function_type_inconsistent)
808 << Name << T << FoundFunction->getType();
809 Importer.ToDiag(FoundFunction->getLocation(),
810 diag::note_odr_value_here)
811 << FoundFunction->getType();
812 }
813 }
814
815 ConflictingDecls.push_back(*Lookup.first);
816 }
817
818 if (!ConflictingDecls.empty()) {
819 Name = Importer.HandleNameConflict(Name, DC, IDNS,
820 ConflictingDecls.data(),
821 ConflictingDecls.size());
822 if (!Name)
823 return 0;
824 }
Douglas Gregor62d311f2010-02-09 19:21:46 +0000825 }
Douglas Gregorbb7930c2010-02-10 19:54:31 +0000826
827 // Import the function parameters.
828 llvm::SmallVector<ParmVarDecl *, 8> Parameters;
829 for (FunctionDecl::param_iterator P = D->param_begin(), PEnd = D->param_end();
830 P != PEnd; ++P) {
831 ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(*P));
832 if (!ToP)
833 return 0;
834
835 Parameters.push_back(ToP);
836 }
837
838 // Create the imported function.
839 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
840 FunctionDecl *ToFunction
841 = FunctionDecl::Create(Importer.getToContext(), DC, Loc,
842 Name, T, TInfo, D->getStorageClass(),
843 D->isInlineSpecified(),
844 D->hasWrittenPrototype());
845 ToFunction->setLexicalDeclContext(LexicalDC);
846 Importer.getImportedDecls()[D] = ToFunction;
847 LexicalDC->addDecl(ToFunction);
Douglas Gregor62d311f2010-02-09 19:21:46 +0000848
Douglas Gregorbb7930c2010-02-10 19:54:31 +0000849 // Set the parameters.
850 for (unsigned I = 0, N = Parameters.size(); I != N; ++I) {
851 Parameters[I]->setOwningFunction(ToFunction);
852 ToFunction->addDecl(Parameters[I]);
853 }
Douglas Gregord5058122010-02-11 01:19:42 +0000854 ToFunction->setParams(Parameters.data(), Parameters.size());
Douglas Gregorbb7930c2010-02-10 19:54:31 +0000855
856 // FIXME: Other bits to merge?
Douglas Gregor3aed6cd2010-02-08 21:09:39 +0000857
Douglas Gregorbb7930c2010-02-10 19:54:31 +0000858 return ToFunction;
859}
860
Douglas Gregor5c73e912010-02-11 00:48:18 +0000861Decl *ASTNodeImporter::VisitFieldDecl(FieldDecl *D) {
862 // Import the major distinguishing characteristics of a variable.
863 DeclContext *DC, *LexicalDC;
864 DeclarationName Name;
865 QualType T;
866 SourceLocation Loc;
867 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc, T))
868 return 0;
869
870 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
871 Expr *BitWidth = Importer.Import(D->getBitWidth());
872 if (!BitWidth && D->getBitWidth())
873 return 0;
874
875 FieldDecl *ToField = FieldDecl::Create(Importer.getToContext(), DC,
876 Loc, Name.getAsIdentifierInfo(),
877 T, TInfo, BitWidth, D->isMutable());
878 ToField->setLexicalDeclContext(LexicalDC);
879 Importer.getImportedDecls()[D] = ToField;
880 LexicalDC->addDecl(ToField);
881 return ToField;
882}
883
Douglas Gregorbb7930c2010-02-10 19:54:31 +0000884Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
885 // Import the major distinguishing characteristics of a variable.
886 DeclContext *DC, *LexicalDC;
887 DeclarationName Name;
888 QualType T;
889 SourceLocation Loc;
890 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc, T))
Douglas Gregor3aed6cd2010-02-08 21:09:39 +0000891 return 0;
892
Douglas Gregor3aed6cd2010-02-08 21:09:39 +0000893 // Try to find a variable in our own ("to") context with the same name and
894 // in the same context as the variable we're importing.
Douglas Gregor62d311f2010-02-09 19:21:46 +0000895 if (D->isFileVarDecl()) {
Douglas Gregor3aed6cd2010-02-08 21:09:39 +0000896 VarDecl *MergeWithVar = 0;
897 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
898 unsigned IDNS = Decl::IDNS_Ordinary;
Douglas Gregor62d311f2010-02-09 19:21:46 +0000899 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +0000900 Lookup.first != Lookup.second;
901 ++Lookup.first) {
902 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
903 continue;
904
905 if (VarDecl *FoundVar = dyn_cast<VarDecl>(*Lookup.first)) {
906 // We have found a variable that we may need to merge with. Check it.
907 if (isExternalLinkage(FoundVar->getLinkage()) &&
908 isExternalLinkage(D->getLinkage())) {
909 if (Importer.getToContext().typesAreCompatible(T,
910 FoundVar->getType())) {
911 MergeWithVar = FoundVar;
912 break;
913 }
914
Douglas Gregor2fbe5582010-02-10 17:16:49 +0000915 if (const IncompleteArrayType *FoundArray
916 = Importer.getToContext().getAsIncompleteArrayType(
917 FoundVar->getType())) {
918 if (const ConstantArrayType *TArray
919 = Importer.getToContext().getAsConstantArrayType(T)) {
920 if (Importer.getToContext().typesAreCompatible(
921 TArray->getElementType(),
922 FoundArray->getElementType())) {
923 FoundVar->setType(T);
924 MergeWithVar = FoundVar;
925 break;
926 }
927 }
928 } else if (const IncompleteArrayType *TArray
929 = Importer.getToContext().getAsIncompleteArrayType(T)) {
930 if (const ConstantArrayType *FoundArray
931 = Importer.getToContext().getAsConstantArrayType(
932 FoundVar->getType())) {
933 if (Importer.getToContext().typesAreCompatible(
934 TArray->getElementType(),
935 FoundArray->getElementType())) {
936 MergeWithVar = FoundVar;
937 break;
938 }
939 }
940 }
941
Douglas Gregor3aed6cd2010-02-08 21:09:39 +0000942 Importer.ToDiag(Loc, diag::err_odr_variable_type_inconsistent)
943 << Name << T << FoundVar->getType();
944 Importer.ToDiag(FoundVar->getLocation(), diag::note_odr_value_here)
945 << FoundVar->getType();
946 }
947 }
948
949 ConflictingDecls.push_back(*Lookup.first);
950 }
951
952 if (MergeWithVar) {
953 // An equivalent variable with external linkage has been found. Link
954 // the two declarations, then merge them.
955 Importer.getImportedDecls()[D] = MergeWithVar;
956
957 if (VarDecl *DDef = D->getDefinition()) {
958 if (VarDecl *ExistingDef = MergeWithVar->getDefinition()) {
959 Importer.ToDiag(ExistingDef->getLocation(),
960 diag::err_odr_variable_multiple_def)
961 << Name;
962 Importer.FromDiag(DDef->getLocation(), diag::note_odr_defined_here);
963 } else {
964 Expr *Init = Importer.Import(DDef->getInit());
Douglas Gregord5058122010-02-11 01:19:42 +0000965 MergeWithVar->setInit(Init);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +0000966 }
967 }
968
969 return MergeWithVar;
970 }
971
972 if (!ConflictingDecls.empty()) {
973 Name = Importer.HandleNameConflict(Name, DC, IDNS,
974 ConflictingDecls.data(),
975 ConflictingDecls.size());
976 if (!Name)
977 return 0;
978 }
979 }
Douglas Gregorfa7a0e52010-02-10 17:47:19 +0000980
Douglas Gregor3aed6cd2010-02-08 21:09:39 +0000981 // Create the imported variable.
Douglas Gregorfa7a0e52010-02-10 17:47:19 +0000982 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
Douglas Gregor3aed6cd2010-02-08 21:09:39 +0000983 VarDecl *ToVar = VarDecl::Create(Importer.getToContext(), DC, Loc,
984 Name.getAsIdentifierInfo(), T, TInfo,
985 D->getStorageClass());
Douglas Gregor62d311f2010-02-09 19:21:46 +0000986 ToVar->setLexicalDeclContext(LexicalDC);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +0000987 Importer.getImportedDecls()[D] = ToVar;
Douglas Gregor62d311f2010-02-09 19:21:46 +0000988 LexicalDC->addDecl(ToVar);
989
Douglas Gregor3aed6cd2010-02-08 21:09:39 +0000990 // Merge the initializer.
991 // FIXME: Can we really import any initializer? Alternatively, we could force
992 // ourselves to import every declaration of a variable and then only use
993 // getInit() here.
Douglas Gregord5058122010-02-11 01:19:42 +0000994 ToVar->setInit(Importer.Import(const_cast<Expr *>(D->getAnyInitializer())));
Douglas Gregor3aed6cd2010-02-08 21:09:39 +0000995
996 // FIXME: Other bits to merge?
997
998 return ToVar;
999}
1000
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001001Decl *ASTNodeImporter::VisitParmVarDecl(ParmVarDecl *D) {
1002 // Parameters are created in the translation unit's context, then moved
1003 // into the function declaration's context afterward.
1004 DeclContext *DC = Importer.getToContext().getTranslationUnitDecl();
1005
Douglas Gregorfa7a0e52010-02-10 17:47:19 +00001006 // Import the name of this declaration.
1007 DeclarationName Name = Importer.Import(D->getDeclName());
1008 if (D->getDeclName() && !Name)
1009 return 0;
1010
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001011 // Import the location of this declaration.
1012 SourceLocation Loc = Importer.Import(D->getLocation());
1013
1014 // Import the parameter's type.
1015 QualType T = Importer.Import(D->getType());
1016 if (T.isNull())
1017 return 0;
1018
1019 // Create the imported parameter.
1020 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
1021 ParmVarDecl *ToParm = ParmVarDecl::Create(Importer.getToContext(), DC,
1022 Loc, Name.getAsIdentifierInfo(),
1023 T, TInfo, D->getStorageClass(),
1024 /*FIXME: Default argument*/ 0);
1025 Importer.getImportedDecls()[D] = ToParm;
1026 return ToParm;
1027}
1028
Douglas Gregor811663e2010-02-10 00:15:17 +00001029ASTImporter::ASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
1030 Diagnostic &ToDiags,
1031 ASTContext &FromContext, FileManager &FromFileManager,
1032 Diagnostic &FromDiags)
Douglas Gregor96e578d2010-02-05 17:54:41 +00001033 : ToContext(ToContext), FromContext(FromContext),
Douglas Gregor811663e2010-02-10 00:15:17 +00001034 ToFileManager(ToFileManager), FromFileManager(FromFileManager),
Douglas Gregor62d311f2010-02-09 19:21:46 +00001035 ToDiags(ToDiags), FromDiags(FromDiags) {
1036 ImportedDecls[FromContext.getTranslationUnitDecl()]
1037 = ToContext.getTranslationUnitDecl();
1038}
1039
1040ASTImporter::~ASTImporter() { }
Douglas Gregor96e578d2010-02-05 17:54:41 +00001041
1042QualType ASTImporter::Import(QualType FromT) {
1043 if (FromT.isNull())
1044 return QualType();
1045
Douglas Gregorf65bbb32010-02-08 15:18:58 +00001046 // Check whether we've already imported this type.
1047 llvm::DenseMap<Type *, Type *>::iterator Pos
1048 = ImportedTypes.find(FromT.getTypePtr());
1049 if (Pos != ImportedTypes.end())
1050 return ToContext.getQualifiedType(Pos->second, FromT.getQualifiers());
Douglas Gregor96e578d2010-02-05 17:54:41 +00001051
Douglas Gregorf65bbb32010-02-08 15:18:58 +00001052 // Import the type
Douglas Gregor96e578d2010-02-05 17:54:41 +00001053 ASTNodeImporter Importer(*this);
1054 QualType ToT = Importer.Visit(FromT.getTypePtr());
1055 if (ToT.isNull())
1056 return ToT;
1057
Douglas Gregorf65bbb32010-02-08 15:18:58 +00001058 // Record the imported type.
1059 ImportedTypes[FromT.getTypePtr()] = ToT.getTypePtr();
1060
Douglas Gregor96e578d2010-02-05 17:54:41 +00001061 return ToContext.getQualifiedType(ToT, FromT.getQualifiers());
1062}
1063
Douglas Gregor62d311f2010-02-09 19:21:46 +00001064TypeSourceInfo *ASTImporter::Import(TypeSourceInfo *FromTSI) {
Douglas Gregorfa7a0e52010-02-10 17:47:19 +00001065 if (!FromTSI)
1066 return FromTSI;
1067
1068 // FIXME: For now we just create a "trivial" type source info based
1069 // on the type and a seingle location. Implement a real version of
1070 // this.
1071 QualType T = Import(FromTSI->getType());
1072 if (T.isNull())
1073 return 0;
1074
1075 return ToContext.getTrivialTypeSourceInfo(T,
1076 FromTSI->getTypeLoc().getFullSourceRange().getBegin());
Douglas Gregor62d311f2010-02-09 19:21:46 +00001077}
1078
1079Decl *ASTImporter::Import(Decl *FromD) {
1080 if (!FromD)
1081 return 0;
1082
1083 // Check whether we've already imported this declaration.
1084 llvm::DenseMap<Decl *, Decl *>::iterator Pos = ImportedDecls.find(FromD);
1085 if (Pos != ImportedDecls.end())
1086 return Pos->second;
1087
1088 // Import the type
1089 ASTNodeImporter Importer(*this);
1090 Decl *ToD = Importer.Visit(FromD);
1091 if (!ToD)
1092 return 0;
1093
1094 // Record the imported declaration.
1095 ImportedDecls[FromD] = ToD;
1096 return ToD;
1097}
1098
1099DeclContext *ASTImporter::ImportContext(DeclContext *FromDC) {
1100 if (!FromDC)
1101 return FromDC;
1102
1103 return cast_or_null<DeclContext>(Import(cast<Decl>(FromDC)));
1104}
1105
1106Expr *ASTImporter::Import(Expr *FromE) {
1107 if (!FromE)
1108 return 0;
1109
1110 return cast_or_null<Expr>(Import(cast<Stmt>(FromE)));
1111}
1112
1113Stmt *ASTImporter::Import(Stmt *FromS) {
1114 if (!FromS)
1115 return 0;
1116
1117 // FIXME: Implement!
1118 return 0;
1119}
1120
1121NestedNameSpecifier *ASTImporter::Import(NestedNameSpecifier *FromNNS) {
1122 if (!FromNNS)
1123 return 0;
1124
1125 // FIXME: Implement!
1126 return 0;
1127}
1128
1129SourceLocation ASTImporter::Import(SourceLocation FromLoc) {
1130 if (FromLoc.isInvalid())
1131 return SourceLocation();
1132
Douglas Gregor811663e2010-02-10 00:15:17 +00001133 SourceManager &FromSM = FromContext.getSourceManager();
1134
1135 // For now, map everything down to its spelling location, so that we
1136 // don't have to import macro instantiations.
1137 // FIXME: Import macro instantiations!
1138 FromLoc = FromSM.getSpellingLoc(FromLoc);
1139 std::pair<FileID, unsigned> Decomposed = FromSM.getDecomposedLoc(FromLoc);
1140 SourceManager &ToSM = ToContext.getSourceManager();
1141 return ToSM.getLocForStartOfFile(Import(Decomposed.first))
1142 .getFileLocWithOffset(Decomposed.second);
Douglas Gregor62d311f2010-02-09 19:21:46 +00001143}
1144
1145SourceRange ASTImporter::Import(SourceRange FromRange) {
1146 return SourceRange(Import(FromRange.getBegin()), Import(FromRange.getEnd()));
1147}
1148
Douglas Gregor811663e2010-02-10 00:15:17 +00001149FileID ASTImporter::Import(FileID FromID) {
1150 llvm::DenseMap<unsigned, FileID>::iterator Pos
1151 = ImportedFileIDs.find(FromID.getHashValue());
1152 if (Pos != ImportedFileIDs.end())
1153 return Pos->second;
1154
1155 SourceManager &FromSM = FromContext.getSourceManager();
1156 SourceManager &ToSM = ToContext.getSourceManager();
1157 const SrcMgr::SLocEntry &FromSLoc = FromSM.getSLocEntry(FromID);
1158 assert(FromSLoc.isFile() && "Cannot handle macro instantiations yet");
1159
1160 // Include location of this file.
1161 SourceLocation ToIncludeLoc = Import(FromSLoc.getFile().getIncludeLoc());
1162
1163 // Map the FileID for to the "to" source manager.
1164 FileID ToID;
1165 const SrcMgr::ContentCache *Cache = FromSLoc.getFile().getContentCache();
1166 if (Cache->Entry) {
1167 // FIXME: We probably want to use getVirtualFile(), so we don't hit the
1168 // disk again
1169 // FIXME: We definitely want to re-use the existing MemoryBuffer, rather
1170 // than mmap the files several times.
1171 const FileEntry *Entry = ToFileManager.getFile(Cache->Entry->getName());
1172 ToID = ToSM.createFileID(Entry, ToIncludeLoc,
1173 FromSLoc.getFile().getFileCharacteristic());
1174 } else {
1175 // FIXME: We want to re-use the existing MemoryBuffer!
1176 const llvm::MemoryBuffer *FromBuf = Cache->getBuffer();
1177 llvm::MemoryBuffer *ToBuf
1178 = llvm::MemoryBuffer::getMemBufferCopy(FromBuf->getBufferStart(),
1179 FromBuf->getBufferEnd(),
1180 FromBuf->getBufferIdentifier());
1181 ToID = ToSM.createFileIDForMemBuffer(ToBuf);
1182 }
1183
1184
1185 ImportedFileIDs[FromID.getHashValue()] = ToID;
1186 return ToID;
1187}
1188
Douglas Gregor96e578d2010-02-05 17:54:41 +00001189DeclarationName ASTImporter::Import(DeclarationName FromName) {
1190 if (!FromName)
1191 return DeclarationName();
1192
1193 switch (FromName.getNameKind()) {
1194 case DeclarationName::Identifier:
1195 return Import(FromName.getAsIdentifierInfo());
1196
1197 case DeclarationName::ObjCZeroArgSelector:
1198 case DeclarationName::ObjCOneArgSelector:
1199 case DeclarationName::ObjCMultiArgSelector:
1200 return Import(FromName.getObjCSelector());
1201
1202 case DeclarationName::CXXConstructorName: {
1203 QualType T = Import(FromName.getCXXNameType());
1204 if (T.isNull())
1205 return DeclarationName();
1206
1207 return ToContext.DeclarationNames.getCXXConstructorName(
1208 ToContext.getCanonicalType(T));
1209 }
1210
1211 case DeclarationName::CXXDestructorName: {
1212 QualType T = Import(FromName.getCXXNameType());
1213 if (T.isNull())
1214 return DeclarationName();
1215
1216 return ToContext.DeclarationNames.getCXXDestructorName(
1217 ToContext.getCanonicalType(T));
1218 }
1219
1220 case DeclarationName::CXXConversionFunctionName: {
1221 QualType T = Import(FromName.getCXXNameType());
1222 if (T.isNull())
1223 return DeclarationName();
1224
1225 return ToContext.DeclarationNames.getCXXConversionFunctionName(
1226 ToContext.getCanonicalType(T));
1227 }
1228
1229 case DeclarationName::CXXOperatorName:
1230 return ToContext.DeclarationNames.getCXXOperatorName(
1231 FromName.getCXXOverloadedOperator());
1232
1233 case DeclarationName::CXXLiteralOperatorName:
1234 return ToContext.DeclarationNames.getCXXLiteralOperatorName(
1235 Import(FromName.getCXXLiteralIdentifier()));
1236
1237 case DeclarationName::CXXUsingDirective:
1238 // FIXME: STATICS!
1239 return DeclarationName::getUsingDirectiveName();
1240 }
1241
1242 // Silence bogus GCC warning
1243 return DeclarationName();
1244}
1245
1246IdentifierInfo *ASTImporter::Import(IdentifierInfo *FromId) {
1247 if (!FromId)
1248 return 0;
1249
1250 return &ToContext.Idents.get(FromId->getName());
1251}
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001252
1253DeclarationName ASTImporter::HandleNameConflict(DeclarationName Name,
1254 DeclContext *DC,
1255 unsigned IDNS,
1256 NamedDecl **Decls,
1257 unsigned NumDecls) {
1258 return Name;
1259}
1260
1261DiagnosticBuilder ASTImporter::ToDiag(SourceLocation Loc, unsigned DiagID) {
1262 return ToDiags.Report(FullSourceLoc(Loc, ToContext.getSourceManager()),
1263 DiagID);
1264}
1265
1266DiagnosticBuilder ASTImporter::FromDiag(SourceLocation Loc, unsigned DiagID) {
1267 return FromDiags.Report(FullSourceLoc(Loc, FromContext.getSourceManager()),
1268 DiagID);
1269}