blob: 6840c61bed32ed1d18c048dabd8cd67459a6f4a7 [file] [log] [blame]
Douglas Gregor96e578d2010-02-05 17:54:41 +00001//===--- ASTImporter.cpp - Importing ASTs from other Contexts ---*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the ASTImporter class which imports AST nodes from one
11// context into another context.
12//
13//===----------------------------------------------------------------------===//
14#include "clang/AST/ASTImporter.h"
15
16#include "clang/AST/ASTContext.h"
Douglas Gregor811663e2010-02-10 00:15:17 +000017#include "clang/AST/ASTDiagnostic.h"
Douglas Gregor5c73e912010-02-11 00:48:18 +000018#include "clang/AST/DeclCXX.h"
Douglas Gregor96e578d2010-02-05 17:54:41 +000019#include "clang/AST/DeclObjC.h"
Douglas Gregor3aed6cd2010-02-08 21:09:39 +000020#include "clang/AST/DeclVisitor.h"
Douglas Gregor7eeb5972010-02-11 19:21:55 +000021#include "clang/AST/StmtVisitor.h"
Douglas Gregorfa7a0e52010-02-10 17:47:19 +000022#include "clang/AST/TypeLoc.h"
Douglas Gregor96e578d2010-02-05 17:54:41 +000023#include "clang/AST/TypeVisitor.h"
Douglas Gregor811663e2010-02-10 00:15:17 +000024#include "clang/Basic/FileManager.h"
25#include "clang/Basic/SourceManager.h"
26#include "llvm/Support/MemoryBuffer.h"
Douglas Gregor96e578d2010-02-05 17:54:41 +000027
28using namespace clang;
29
30namespace {
Douglas Gregor3aed6cd2010-02-08 21:09:39 +000031 class ASTNodeImporter : public TypeVisitor<ASTNodeImporter, QualType>,
Douglas Gregor7eeb5972010-02-11 19:21:55 +000032 public DeclVisitor<ASTNodeImporter, Decl *>,
33 public StmtVisitor<ASTNodeImporter, Stmt *> {
Douglas Gregor96e578d2010-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 Gregor62d311f2010-02-09 19:21:46 +000040 using DeclVisitor<ASTNodeImporter, Decl *>::Visit;
Douglas Gregor7eeb5972010-02-11 19:21:55 +000041 using StmtVisitor<ASTNodeImporter, Stmt *>::Visit;
Douglas Gregor96e578d2010-02-05 17:54:41 +000042
43 // Importing types
Douglas Gregore4c83e42010-02-09 22:48:33 +000044 QualType VisitType(Type *T);
Douglas Gregor96e578d2010-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 Gregor3aed6cd2010-02-08 21:09:39 +000078
79 // Importing declarations
Douglas Gregorbb7930c2010-02-10 19:54:31 +000080 bool ImportDeclParts(NamedDecl *D, DeclContext *&DC,
81 DeclContext *&LexicalDC, DeclarationName &Name,
82 SourceLocation &Loc);
Douglas Gregor98c10182010-02-12 22:17:39 +000083 bool ImportDeclParts(ValueDecl *D,
Douglas Gregorbb7930c2010-02-10 19:54:31 +000084 DeclContext *&DC, DeclContext *&LexicalDC,
85 DeclarationName &Name, SourceLocation &Loc,
86 QualType &T);
Douglas Gregor5c73e912010-02-11 00:48:18 +000087 bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord);
Douglas Gregor98c10182010-02-12 22:17:39 +000088 bool IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToEnum);
Douglas Gregore4c83e42010-02-09 22:48:33 +000089 Decl *VisitDecl(Decl *D);
Douglas Gregor5fa74c32010-02-10 21:10:29 +000090 Decl *VisitTypedefDecl(TypedefDecl *D);
Douglas Gregor98c10182010-02-12 22:17:39 +000091 Decl *VisitEnumDecl(EnumDecl *D);
Douglas Gregor5c73e912010-02-11 00:48:18 +000092 Decl *VisitRecordDecl(RecordDecl *D);
Douglas Gregor98c10182010-02-12 22:17:39 +000093 Decl *VisitEnumConstantDecl(EnumConstantDecl *D);
Douglas Gregorbb7930c2010-02-10 19:54:31 +000094 Decl *VisitFunctionDecl(FunctionDecl *D);
Douglas Gregor5c73e912010-02-11 00:48:18 +000095 Decl *VisitFieldDecl(FieldDecl *D);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +000096 Decl *VisitVarDecl(VarDecl *D);
Douglas Gregorbb7930c2010-02-10 19:54:31 +000097 Decl *VisitParmVarDecl(ParmVarDecl *D);
Douglas Gregor7eeb5972010-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 Gregor98c10182010-02-12 22:17:39 +0000105 Expr *VisitImplicitCastExpr(ImplicitCastExpr *E);
Douglas Gregor96e578d2010-02-05 17:54:41 +0000106 };
107}
108
109//----------------------------------------------------------------------------
110// Import Types
111//----------------------------------------------------------------------------
112
Douglas Gregore4c83e42010-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 Gregor96e578d2010-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 Gregor3aed6cd2010-02-08 21:09:39 +0000475//----------------------------------------------------------------------------
476// Import Declarations
477//----------------------------------------------------------------------------
Douglas Gregorbb7930c2010-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 Gregor98c10182010-02-12 22:17:39 +0000504bool ASTNodeImporter::ImportDeclParts(ValueDecl *D,
Douglas Gregorbb7930c2010-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 Gregor5c73e912010-02-11 00:48:18 +0000521bool ASTNodeImporter::IsStructuralMatch(RecordDecl *FromRecord,
522 RecordDecl *ToRecord) {
Douglas Gregor7eeb5972010-02-11 19:21:55 +0000523 if (FromRecord->isUnion() != ToRecord->isUnion()) {
524 Importer.ToDiag(ToRecord->getLocation(),
Douglas Gregor98c10182010-02-12 22:17:39 +0000525 diag::warn_odr_tag_type_inconsistent)
Douglas Gregor7eeb5972010-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 Gregor5c73e912010-02-11 00:48:18 +0000529 return false;
Douglas Gregor7eeb5972010-02-11 19:21:55 +0000530 }
531
Douglas Gregor5c73e912010-02-11 00:48:18 +0000532 if (CXXRecordDecl *FromCXX = dyn_cast<CXXRecordDecl>(FromRecord)) {
533 if (CXXRecordDecl *ToCXX = dyn_cast<CXXRecordDecl>(ToRecord)) {
Douglas Gregor7eeb5972010-02-11 19:21:55 +0000534 if (FromCXX->getNumBases() != ToCXX->getNumBases()) {
535 Importer.ToDiag(ToRecord->getLocation(),
Douglas Gregor98c10182010-02-12 22:17:39 +0000536 diag::warn_odr_tag_type_inconsistent)
Douglas Gregor7eeb5972010-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 Gregor5c73e912010-02-11 00:48:18 +0000543 return false;
Douglas Gregor7eeb5972010-02-11 19:21:55 +0000544 }
545
Douglas Gregor5c73e912010-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 Gregor7eeb5972010-02-11 19:21:55 +0000551 ++FromBase, ++ToBase) {
Douglas Gregor5c73e912010-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 Gregor7eeb5972010-02-11 19:21:55 +0000558 ToBase->getType())) {
559 Importer.ToDiag(ToRecord->getLocation(),
Douglas Gregor98c10182010-02-12 22:17:39 +0000560 diag::warn_odr_tag_type_inconsistent)
Douglas Gregor7eeb5972010-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 Gregor5c73e912010-02-11 00:48:18 +0000570 return false;
Douglas Gregor7eeb5972010-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 Gregor98c10182010-02-12 22:17:39 +0000576 diag::warn_odr_tag_type_inconsistent)
Douglas Gregor7eeb5972010-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 Gregor5c73e912010-02-11 00:48:18 +0000587 }
588 } else if (FromCXX->getNumBases() > 0) {
Douglas Gregor7eeb5972010-02-11 19:21:55 +0000589 Importer.ToDiag(ToRecord->getLocation(),
Douglas Gregor98c10182010-02-12 22:17:39 +0000590 diag::warn_odr_tag_type_inconsistent)
Douglas Gregor7eeb5972010-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 Gregor5c73e912010-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 Gregor7eeb5972010-02-11 19:21:55 +0000609 if (ToField == ToFieldEnd) {
610 Importer.ToDiag(ToRecord->getLocation(),
Douglas Gregor98c10182010-02-12 22:17:39 +0000611 diag::warn_odr_tag_type_inconsistent)
Douglas Gregor7eeb5972010-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 Gregor5c73e912010-02-11 00:48:18 +0000616 return false;
Douglas Gregor7eeb5972010-02-11 19:21:55 +0000617 }
618
Douglas Gregor5c73e912010-02-11 00:48:18 +0000619 QualType FromT = Importer.Import(FromField->getType());
620 if (FromT.isNull())
621 return false;
622
Douglas Gregor7eeb5972010-02-11 19:21:55 +0000623 if (!Importer.getToContext().typesAreCompatible(FromT, ToField->getType())){
624 Importer.ToDiag(ToRecord->getLocation(),
Douglas Gregor98c10182010-02-12 22:17:39 +0000625 diag::warn_odr_tag_type_inconsistent)
Douglas Gregor7eeb5972010-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 Gregor5c73e912010-02-11 00:48:18 +0000631 return false;
Douglas Gregor7eeb5972010-02-11 19:21:55 +0000632 }
Douglas Gregor5c73e912010-02-11 00:48:18 +0000633
Douglas Gregor7eeb5972010-02-11 19:21:55 +0000634 if (FromField->isBitField() != ToField->isBitField()) {
635 Importer.ToDiag(ToRecord->getLocation(),
Douglas Gregor98c10182010-02-12 22:17:39 +0000636 diag::warn_odr_tag_type_inconsistent)
Douglas Gregor7eeb5972010-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 Gregor5c73e912010-02-11 00:48:18 +0000658 return false;
Douglas Gregor7eeb5972010-02-11 19:21:55 +0000659 }
660
Douglas Gregor5c73e912010-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 Gregor7eeb5972010-02-11 19:21:55 +0000679 if (FromBits != ToBits) {
680 Importer.ToDiag(ToRecord->getLocation(),
Douglas Gregor98c10182010-02-12 22:17:39 +0000681 diag::warn_odr_tag_type_inconsistent)
Douglas Gregor7eeb5972010-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 Gregor5c73e912010-02-11 00:48:18 +0000689 return false;
Douglas Gregor7eeb5972010-02-11 19:21:55 +0000690 }
Douglas Gregor5c73e912010-02-11 00:48:18 +0000691 }
692 }
693
Douglas Gregor7eeb5972010-02-11 19:21:55 +0000694 if (ToField != ToFieldEnd) {
695 Importer.ToDiag(ToRecord->getLocation(),
Douglas Gregor98c10182010-02-12 22:17:39 +0000696 diag::warn_odr_tag_type_inconsistent)
Douglas Gregor7eeb5972010-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 Gregor5c73e912010-02-11 00:48:18 +0000705}
706
Douglas Gregor98c10182010-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 Gregore4c83e42010-02-09 22:48:33 +0000768Decl *ASTNodeImporter::VisitDecl(Decl *D) {
Douglas Gregor811663e2010-02-10 00:15:17 +0000769 Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node)
Douglas Gregore4c83e42010-02-09 22:48:33 +0000770 << D->getDeclKindName();
771 return 0;
772}
773
Douglas Gregor5fa74c32010-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,
Douglas Gregor8cdbe642010-02-12 23:44:20 +0000800 FoundTypedef->getUnderlyingType()))
801 return Importer.Imported(D, FoundTypedef);
Douglas Gregor5fa74c32010-02-10 21:10:29 +0000802 }
803
804 ConflictingDecls.push_back(*Lookup.first);
805 }
806
807 if (!ConflictingDecls.empty()) {
808 Name = Importer.HandleNameConflict(Name, DC, IDNS,
809 ConflictingDecls.data(),
810 ConflictingDecls.size());
811 if (!Name)
812 return 0;
813 }
814 }
815
816 // Create the new typedef node.
817 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
818 TypedefDecl *ToTypedef = TypedefDecl::Create(Importer.getToContext(), DC,
819 Loc, Name.getAsIdentifierInfo(),
820 TInfo);
821 ToTypedef->setLexicalDeclContext(LexicalDC);
Douglas Gregor8cdbe642010-02-12 23:44:20 +0000822 Importer.Imported(D, ToTypedef);
Douglas Gregor5fa74c32010-02-10 21:10:29 +0000823 LexicalDC->addDecl(ToTypedef);
824 return ToTypedef;
825}
826
Douglas Gregor98c10182010-02-12 22:17:39 +0000827Decl *ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
828 // Import the major distinguishing characteristics of this enum.
829 DeclContext *DC, *LexicalDC;
830 DeclarationName Name;
831 SourceLocation Loc;
832 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
833 return 0;
834
835 // Figure out what enum name we're looking for.
836 unsigned IDNS = Decl::IDNS_Tag;
837 DeclarationName SearchName = Name;
838 if (!SearchName && D->getTypedefForAnonDecl()) {
839 SearchName = Importer.Import(D->getTypedefForAnonDecl()->getDeclName());
840 IDNS = Decl::IDNS_Ordinary;
841 } else if (Importer.getToContext().getLangOptions().CPlusPlus)
842 IDNS |= Decl::IDNS_Ordinary;
843
844 // We may already have an enum of the same name; try to find and match it.
845 if (!DC->isFunctionOrMethod() && SearchName) {
846 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
847 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
848 Lookup.first != Lookup.second;
849 ++Lookup.first) {
850 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
851 continue;
852
853 Decl *Found = *Lookup.first;
854 if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(Found)) {
855 if (const TagType *Tag = Typedef->getUnderlyingType()->getAs<TagType>())
856 Found = Tag->getDecl();
857 }
858
859 if (EnumDecl *FoundEnum = dyn_cast<EnumDecl>(Found)) {
Douglas Gregor8cdbe642010-02-12 23:44:20 +0000860 if (IsStructuralMatch(D, FoundEnum))
861 return Importer.Imported(D, FoundEnum);
Douglas Gregor98c10182010-02-12 22:17:39 +0000862 }
863
864 ConflictingDecls.push_back(*Lookup.first);
865 }
866
867 if (!ConflictingDecls.empty()) {
868 Name = Importer.HandleNameConflict(Name, DC, IDNS,
869 ConflictingDecls.data(),
870 ConflictingDecls.size());
871 }
872 }
873
874 // Create the enum declaration.
875 EnumDecl *ToEnum = EnumDecl::Create(Importer.getToContext(), DC, Loc,
876 Name.getAsIdentifierInfo(),
877 Importer.Import(D->getTagKeywordLoc()),
878 0);
879 ToEnum->setLexicalDeclContext(LexicalDC);
Douglas Gregor8cdbe642010-02-12 23:44:20 +0000880 Importer.Imported(D, ToEnum);
Douglas Gregor98c10182010-02-12 22:17:39 +0000881 LexicalDC->addDecl(ToEnum);
882
883 // Import the integer type.
884 QualType ToIntegerType = Importer.Import(D->getIntegerType());
885 if (ToIntegerType.isNull())
886 return 0;
887 ToEnum->setIntegerType(ToIntegerType);
888
889 // Import the definition
890 if (D->isDefinition()) {
891 QualType T = Importer.Import(Importer.getFromContext().getTypeDeclType(D));
892 if (T.isNull())
893 return 0;
894
895 QualType ToPromotionType = Importer.Import(D->getPromotionType());
896 if (ToPromotionType.isNull())
897 return 0;
898
899 ToEnum->startDefinition();
900 for (DeclContext::decl_iterator FromMem = D->decls_begin(),
901 FromMemEnd = D->decls_end();
902 FromMem != FromMemEnd;
903 ++FromMem)
904 Importer.Import(*FromMem);
905
906 ToEnum->completeDefinition(T, ToPromotionType);
907 }
908
909 return ToEnum;
910}
911
Douglas Gregor5c73e912010-02-11 00:48:18 +0000912Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
913 // If this record has a definition in the translation unit we're coming from,
914 // but this particular declaration is not that definition, import the
915 // definition and map to that.
Douglas Gregor0a5a2212010-02-11 01:04:33 +0000916 TagDecl *Definition = D->getDefinition();
Douglas Gregor5c73e912010-02-11 00:48:18 +0000917 if (Definition && Definition != D) {
918 Decl *ImportedDef = Importer.Import(Definition);
Douglas Gregor8cdbe642010-02-12 23:44:20 +0000919 if (!ImportedDef)
920 return 0;
921
922 return Importer.Imported(D, ImportedDef);
Douglas Gregor5c73e912010-02-11 00:48:18 +0000923 }
924
925 // Import the major distinguishing characteristics of this record.
926 DeclContext *DC, *LexicalDC;
927 DeclarationName Name;
928 SourceLocation Loc;
929 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
930 return 0;
931
932 // Figure out what structure name we're looking for.
933 unsigned IDNS = Decl::IDNS_Tag;
934 DeclarationName SearchName = Name;
935 if (!SearchName && D->getTypedefForAnonDecl()) {
936 SearchName = Importer.Import(D->getTypedefForAnonDecl()->getDeclName());
937 IDNS = Decl::IDNS_Ordinary;
938 } else if (Importer.getToContext().getLangOptions().CPlusPlus)
939 IDNS |= Decl::IDNS_Ordinary;
940
941 // We may already have a record of the same name; try to find and match it.
Douglas Gregor25791052010-02-12 00:09:27 +0000942 RecordDecl *AdoptDecl = 0;
Douglas Gregor5c73e912010-02-11 00:48:18 +0000943 if (!DC->isFunctionOrMethod() && SearchName) {
944 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
945 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
946 Lookup.first != Lookup.second;
947 ++Lookup.first) {
948 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
949 continue;
950
951 Decl *Found = *Lookup.first;
952 if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(Found)) {
953 if (const TagType *Tag = Typedef->getUnderlyingType()->getAs<TagType>())
954 Found = Tag->getDecl();
955 }
956
957 if (RecordDecl *FoundRecord = dyn_cast<RecordDecl>(Found)) {
Douglas Gregor25791052010-02-12 00:09:27 +0000958 if (RecordDecl *FoundDef = FoundRecord->getDefinition()) {
959 if (!D->isDefinition() || IsStructuralMatch(D, FoundDef)) {
960 // The record types structurally match, or the "from" translation
961 // unit only had a forward declaration anyway; call it the same
962 // function.
963 // FIXME: For C++, we should also merge methods here.
Douglas Gregor8cdbe642010-02-12 23:44:20 +0000964 return Importer.Imported(D, FoundDef);
Douglas Gregor25791052010-02-12 00:09:27 +0000965 }
966 } else {
967 // We have a forward declaration of this type, so adopt that forward
968 // declaration rather than building a new one.
969 AdoptDecl = FoundRecord;
970 continue;
971 }
Douglas Gregor5c73e912010-02-11 00:48:18 +0000972 }
973
974 ConflictingDecls.push_back(*Lookup.first);
975 }
976
977 if (!ConflictingDecls.empty()) {
978 Name = Importer.HandleNameConflict(Name, DC, IDNS,
979 ConflictingDecls.data(),
980 ConflictingDecls.size());
981 }
982 }
983
984 // Create the record declaration.
Douglas Gregor25791052010-02-12 00:09:27 +0000985 RecordDecl *ToRecord = AdoptDecl;
986 if (!ToRecord) {
987 if (CXXRecordDecl *FromCXX = dyn_cast<CXXRecordDecl>(D)) {
988 CXXRecordDecl *ToCXX = CXXRecordDecl::Create(Importer.getToContext(),
989 D->getTagKind(),
990 DC, Loc,
991 Name.getAsIdentifierInfo(),
Douglas Gregor5c73e912010-02-11 00:48:18 +0000992 Importer.Import(D->getTagKeywordLoc()));
Douglas Gregor25791052010-02-12 00:09:27 +0000993 ToRecord = ToCXX;
994
995 if (D->isDefinition()) {
996 // Add base classes.
997 llvm::SmallVector<CXXBaseSpecifier *, 4> Bases;
998 for (CXXRecordDecl::base_class_iterator
999 FromBase = FromCXX->bases_begin(),
1000 FromBaseEnd = FromCXX->bases_end();
1001 FromBase != FromBaseEnd;
1002 ++FromBase) {
1003 QualType T = Importer.Import(FromBase->getType());
1004 if (T.isNull())
1005 return 0;
1006
1007 Bases.push_back(
1008 new (Importer.getToContext())
Douglas Gregor5c73e912010-02-11 00:48:18 +00001009 CXXBaseSpecifier(Importer.Import(FromBase->getSourceRange()),
1010 FromBase->isVirtual(),
1011 FromBase->isBaseOfClass(),
1012 FromBase->getAccessSpecifierAsWritten(),
1013 T));
Douglas Gregor25791052010-02-12 00:09:27 +00001014 }
1015 if (!Bases.empty())
1016 ToCXX->setBases(Bases.data(), Bases.size());
Douglas Gregor5c73e912010-02-11 00:48:18 +00001017 }
Douglas Gregor25791052010-02-12 00:09:27 +00001018 } else {
1019 ToRecord = RecordDecl::Create(Importer.getToContext(), D->getTagKind(),
1020 DC, Loc,
1021 Name.getAsIdentifierInfo(),
1022 Importer.Import(D->getTagKeywordLoc()));
Douglas Gregor5c73e912010-02-11 00:48:18 +00001023 }
Douglas Gregor25791052010-02-12 00:09:27 +00001024 ToRecord->setLexicalDeclContext(LexicalDC);
1025 LexicalDC->addDecl(ToRecord);
Douglas Gregor5c73e912010-02-11 00:48:18 +00001026 }
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001027
1028 Importer.Imported(D, ToRecord);
Douglas Gregor25791052010-02-12 00:09:27 +00001029
Douglas Gregor5c73e912010-02-11 00:48:18 +00001030 if (D->isDefinition()) {
1031 ToRecord->startDefinition();
1032 for (DeclContext::decl_iterator FromMem = D->decls_begin(),
1033 FromMemEnd = D->decls_end();
1034 FromMem != FromMemEnd;
1035 ++FromMem)
1036 Importer.Import(*FromMem);
1037
Douglas Gregord5058122010-02-11 01:19:42 +00001038 ToRecord->completeDefinition();
Douglas Gregor5c73e912010-02-11 00:48:18 +00001039 }
1040
1041 return ToRecord;
1042}
1043
Douglas Gregor98c10182010-02-12 22:17:39 +00001044Decl *ASTNodeImporter::VisitEnumConstantDecl(EnumConstantDecl *D) {
1045 // Import the major distinguishing characteristics of this enumerator.
1046 DeclContext *DC, *LexicalDC;
1047 DeclarationName Name;
1048 SourceLocation Loc;
1049 QualType T;
1050 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc, T))
1051 return 0;
1052
1053 // Determine whether there are any other declarations with the same name and
1054 // in the same context.
1055 if (!LexicalDC->isFunctionOrMethod()) {
1056 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
1057 unsigned IDNS = Decl::IDNS_Ordinary;
1058 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
1059 Lookup.first != Lookup.second;
1060 ++Lookup.first) {
1061 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
1062 continue;
1063
1064 ConflictingDecls.push_back(*Lookup.first);
1065 }
1066
1067 if (!ConflictingDecls.empty()) {
1068 Name = Importer.HandleNameConflict(Name, DC, IDNS,
1069 ConflictingDecls.data(),
1070 ConflictingDecls.size());
1071 if (!Name)
1072 return 0;
1073 }
1074 }
1075
1076 Expr *Init = Importer.Import(D->getInitExpr());
1077 if (D->getInitExpr() && !Init)
1078 return 0;
1079
1080 EnumConstantDecl *ToEnumerator
1081 = EnumConstantDecl::Create(Importer.getToContext(), cast<EnumDecl>(DC), Loc,
1082 Name.getAsIdentifierInfo(), T,
1083 Init, D->getInitVal());
1084 ToEnumerator->setLexicalDeclContext(LexicalDC);
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001085 Importer.Imported(D, ToEnumerator);
Douglas Gregor98c10182010-02-12 22:17:39 +00001086 LexicalDC->addDecl(ToEnumerator);
1087 return ToEnumerator;
1088}
Douglas Gregor5c73e912010-02-11 00:48:18 +00001089
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001090Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
1091 // Import the major distinguishing characteristics of this function.
1092 DeclContext *DC, *LexicalDC;
1093 DeclarationName Name;
1094 QualType T;
1095 SourceLocation Loc;
1096 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc, T))
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001097 return 0;
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001098
1099 // Try to find a function in our own ("to") context with the same name, same
1100 // type, and in the same context as the function we're importing.
1101 if (!LexicalDC->isFunctionOrMethod()) {
1102 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
1103 unsigned IDNS = Decl::IDNS_Ordinary;
1104 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
1105 Lookup.first != Lookup.second;
1106 ++Lookup.first) {
1107 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
1108 continue;
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001109
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001110 if (FunctionDecl *FoundFunction = dyn_cast<FunctionDecl>(*Lookup.first)) {
1111 if (isExternalLinkage(FoundFunction->getLinkage()) &&
1112 isExternalLinkage(D->getLinkage())) {
1113 if (Importer.getToContext().typesAreCompatible(T,
1114 FoundFunction->getType())) {
1115 // FIXME: Actually try to merge the body and other attributes.
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001116 return Importer.Imported(D, FoundFunction);
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001117 }
1118
1119 // FIXME: Check for overloading more carefully, e.g., by boosting
1120 // Sema::IsOverload out to the AST library.
1121
1122 // Function overloading is okay in C++.
1123 if (Importer.getToContext().getLangOptions().CPlusPlus)
1124 continue;
1125
1126 // Complain about inconsistent function types.
1127 Importer.ToDiag(Loc, diag::err_odr_function_type_inconsistent)
1128 << Name << T << FoundFunction->getType();
1129 Importer.ToDiag(FoundFunction->getLocation(),
1130 diag::note_odr_value_here)
1131 << FoundFunction->getType();
1132 }
1133 }
1134
1135 ConflictingDecls.push_back(*Lookup.first);
1136 }
1137
1138 if (!ConflictingDecls.empty()) {
1139 Name = Importer.HandleNameConflict(Name, DC, IDNS,
1140 ConflictingDecls.data(),
1141 ConflictingDecls.size());
1142 if (!Name)
1143 return 0;
1144 }
Douglas Gregor62d311f2010-02-09 19:21:46 +00001145 }
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001146
1147 // Import the function parameters.
1148 llvm::SmallVector<ParmVarDecl *, 8> Parameters;
1149 for (FunctionDecl::param_iterator P = D->param_begin(), PEnd = D->param_end();
1150 P != PEnd; ++P) {
1151 ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(*P));
1152 if (!ToP)
1153 return 0;
1154
1155 Parameters.push_back(ToP);
1156 }
1157
1158 // Create the imported function.
1159 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
Douglas Gregor98c10182010-02-12 22:17:39 +00001160 FunctionDecl *ToEnumerator
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001161 = FunctionDecl::Create(Importer.getToContext(), DC, Loc,
1162 Name, T, TInfo, D->getStorageClass(),
1163 D->isInlineSpecified(),
1164 D->hasWrittenPrototype());
Douglas Gregor98c10182010-02-12 22:17:39 +00001165 ToEnumerator->setLexicalDeclContext(LexicalDC);
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001166 Importer.Imported(D, ToEnumerator);
Douglas Gregor98c10182010-02-12 22:17:39 +00001167 LexicalDC->addDecl(ToEnumerator);
Douglas Gregor62d311f2010-02-09 19:21:46 +00001168
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001169 // Set the parameters.
1170 for (unsigned I = 0, N = Parameters.size(); I != N; ++I) {
Douglas Gregor98c10182010-02-12 22:17:39 +00001171 Parameters[I]->setOwningFunction(ToEnumerator);
1172 ToEnumerator->addDecl(Parameters[I]);
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001173 }
Douglas Gregor98c10182010-02-12 22:17:39 +00001174 ToEnumerator->setParams(Parameters.data(), Parameters.size());
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001175
1176 // FIXME: Other bits to merge?
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001177
Douglas Gregor98c10182010-02-12 22:17:39 +00001178 return ToEnumerator;
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001179}
1180
Douglas Gregor5c73e912010-02-11 00:48:18 +00001181Decl *ASTNodeImporter::VisitFieldDecl(FieldDecl *D) {
1182 // Import the major distinguishing characteristics of a variable.
1183 DeclContext *DC, *LexicalDC;
1184 DeclarationName Name;
1185 QualType T;
1186 SourceLocation Loc;
1187 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc, T))
1188 return 0;
1189
1190 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
1191 Expr *BitWidth = Importer.Import(D->getBitWidth());
1192 if (!BitWidth && D->getBitWidth())
1193 return 0;
1194
1195 FieldDecl *ToField = FieldDecl::Create(Importer.getToContext(), DC,
1196 Loc, Name.getAsIdentifierInfo(),
1197 T, TInfo, BitWidth, D->isMutable());
1198 ToField->setLexicalDeclContext(LexicalDC);
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001199 Importer.Imported(D, ToField);
Douglas Gregor5c73e912010-02-11 00:48:18 +00001200 LexicalDC->addDecl(ToField);
1201 return ToField;
1202}
1203
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001204Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
1205 // Import the major distinguishing characteristics of a variable.
1206 DeclContext *DC, *LexicalDC;
1207 DeclarationName Name;
1208 QualType T;
1209 SourceLocation Loc;
1210 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc, T))
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001211 return 0;
1212
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001213 // Try to find a variable in our own ("to") context with the same name and
1214 // in the same context as the variable we're importing.
Douglas Gregor62d311f2010-02-09 19:21:46 +00001215 if (D->isFileVarDecl()) {
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001216 VarDecl *MergeWithVar = 0;
1217 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
1218 unsigned IDNS = Decl::IDNS_Ordinary;
Douglas Gregor62d311f2010-02-09 19:21:46 +00001219 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001220 Lookup.first != Lookup.second;
1221 ++Lookup.first) {
1222 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
1223 continue;
1224
1225 if (VarDecl *FoundVar = dyn_cast<VarDecl>(*Lookup.first)) {
1226 // We have found a variable that we may need to merge with. Check it.
1227 if (isExternalLinkage(FoundVar->getLinkage()) &&
1228 isExternalLinkage(D->getLinkage())) {
1229 if (Importer.getToContext().typesAreCompatible(T,
1230 FoundVar->getType())) {
1231 MergeWithVar = FoundVar;
1232 break;
1233 }
1234
Douglas Gregor56521c52010-02-12 17:23:39 +00001235 const ArrayType *FoundArray
1236 = Importer.getToContext().getAsArrayType(FoundVar->getType());
1237 const ArrayType *TArray
1238 = Importer.getToContext().getAsArrayType(T);
1239 if (FoundArray && TArray) {
1240 if (isa<IncompleteArrayType>(FoundArray) &&
1241 isa<ConstantArrayType>(TArray)) {
1242 FoundVar->setType(T);
1243 MergeWithVar = FoundVar;
1244 break;
1245 } else if (isa<IncompleteArrayType>(TArray) &&
1246 isa<ConstantArrayType>(FoundArray)) {
1247 MergeWithVar = FoundVar;
1248 break;
Douglas Gregor2fbe5582010-02-10 17:16:49 +00001249 }
1250 }
1251
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001252 Importer.ToDiag(Loc, diag::err_odr_variable_type_inconsistent)
1253 << Name << T << FoundVar->getType();
1254 Importer.ToDiag(FoundVar->getLocation(), diag::note_odr_value_here)
1255 << FoundVar->getType();
1256 }
1257 }
1258
1259 ConflictingDecls.push_back(*Lookup.first);
1260 }
1261
1262 if (MergeWithVar) {
1263 // An equivalent variable with external linkage has been found. Link
1264 // the two declarations, then merge them.
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001265 Importer.Imported(D, MergeWithVar);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001266
1267 if (VarDecl *DDef = D->getDefinition()) {
1268 if (VarDecl *ExistingDef = MergeWithVar->getDefinition()) {
1269 Importer.ToDiag(ExistingDef->getLocation(),
1270 diag::err_odr_variable_multiple_def)
1271 << Name;
1272 Importer.FromDiag(DDef->getLocation(), diag::note_odr_defined_here);
1273 } else {
1274 Expr *Init = Importer.Import(DDef->getInit());
Douglas Gregord5058122010-02-11 01:19:42 +00001275 MergeWithVar->setInit(Init);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001276 }
1277 }
1278
1279 return MergeWithVar;
1280 }
1281
1282 if (!ConflictingDecls.empty()) {
1283 Name = Importer.HandleNameConflict(Name, DC, IDNS,
1284 ConflictingDecls.data(),
1285 ConflictingDecls.size());
1286 if (!Name)
1287 return 0;
1288 }
1289 }
Douglas Gregorfa7a0e52010-02-10 17:47:19 +00001290
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001291 // Create the imported variable.
Douglas Gregorfa7a0e52010-02-10 17:47:19 +00001292 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001293 VarDecl *ToVar = VarDecl::Create(Importer.getToContext(), DC, Loc,
1294 Name.getAsIdentifierInfo(), T, TInfo,
1295 D->getStorageClass());
Douglas Gregor62d311f2010-02-09 19:21:46 +00001296 ToVar->setLexicalDeclContext(LexicalDC);
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001297 Importer.Imported(D, ToVar);
Douglas Gregor62d311f2010-02-09 19:21:46 +00001298 LexicalDC->addDecl(ToVar);
1299
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001300 // Merge the initializer.
1301 // FIXME: Can we really import any initializer? Alternatively, we could force
1302 // ourselves to import every declaration of a variable and then only use
1303 // getInit() here.
Douglas Gregord5058122010-02-11 01:19:42 +00001304 ToVar->setInit(Importer.Import(const_cast<Expr *>(D->getAnyInitializer())));
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001305
1306 // FIXME: Other bits to merge?
1307
1308 return ToVar;
1309}
1310
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001311Decl *ASTNodeImporter::VisitParmVarDecl(ParmVarDecl *D) {
1312 // Parameters are created in the translation unit's context, then moved
1313 // into the function declaration's context afterward.
1314 DeclContext *DC = Importer.getToContext().getTranslationUnitDecl();
1315
Douglas Gregorfa7a0e52010-02-10 17:47:19 +00001316 // Import the name of this declaration.
1317 DeclarationName Name = Importer.Import(D->getDeclName());
1318 if (D->getDeclName() && !Name)
1319 return 0;
1320
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001321 // Import the location of this declaration.
1322 SourceLocation Loc = Importer.Import(D->getLocation());
1323
1324 // Import the parameter's type.
1325 QualType T = Importer.Import(D->getType());
1326 if (T.isNull())
1327 return 0;
1328
1329 // Create the imported parameter.
1330 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
1331 ParmVarDecl *ToParm = ParmVarDecl::Create(Importer.getToContext(), DC,
1332 Loc, Name.getAsIdentifierInfo(),
1333 T, TInfo, D->getStorageClass(),
1334 /*FIXME: Default argument*/ 0);
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001335 return Importer.Imported(D, ToParm);
Douglas Gregorbb7930c2010-02-10 19:54:31 +00001336}
1337
Douglas Gregor7eeb5972010-02-11 19:21:55 +00001338//----------------------------------------------------------------------------
1339// Import Statements
1340//----------------------------------------------------------------------------
1341
1342Stmt *ASTNodeImporter::VisitStmt(Stmt *S) {
1343 Importer.FromDiag(S->getLocStart(), diag::err_unsupported_ast_node)
1344 << S->getStmtClassName();
1345 return 0;
1346}
1347
1348//----------------------------------------------------------------------------
1349// Import Expressions
1350//----------------------------------------------------------------------------
1351Expr *ASTNodeImporter::VisitExpr(Expr *E) {
1352 Importer.FromDiag(E->getLocStart(), diag::err_unsupported_ast_node)
1353 << E->getStmtClassName();
1354 return 0;
1355}
1356
1357Expr *ASTNodeImporter::VisitIntegerLiteral(IntegerLiteral *E) {
1358 QualType T = Importer.Import(E->getType());
1359 if (T.isNull())
1360 return 0;
1361
1362 return new (Importer.getToContext())
1363 IntegerLiteral(E->getValue(), T, Importer.Import(E->getLocation()));
1364}
1365
Douglas Gregor98c10182010-02-12 22:17:39 +00001366Expr *ASTNodeImporter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
1367 QualType T = Importer.Import(E->getType());
1368 if (T.isNull())
1369 return 0;
1370
1371 Expr *SubExpr = Importer.Import(E->getSubExpr());
1372 if (!SubExpr)
1373 return 0;
1374
1375 return new (Importer.getToContext()) ImplicitCastExpr(T, E->getCastKind(),
1376 SubExpr,
1377 E->isLvalueCast());
1378}
1379
Douglas Gregor7eeb5972010-02-11 19:21:55 +00001380ASTImporter::ASTImporter(Diagnostic &Diags,
1381 ASTContext &ToContext, FileManager &ToFileManager,
1382 ASTContext &FromContext, FileManager &FromFileManager)
Douglas Gregor96e578d2010-02-05 17:54:41 +00001383 : ToContext(ToContext), FromContext(FromContext),
Douglas Gregor811663e2010-02-10 00:15:17 +00001384 ToFileManager(ToFileManager), FromFileManager(FromFileManager),
Douglas Gregor7eeb5972010-02-11 19:21:55 +00001385 Diags(Diags) {
Douglas Gregor62d311f2010-02-09 19:21:46 +00001386 ImportedDecls[FromContext.getTranslationUnitDecl()]
1387 = ToContext.getTranslationUnitDecl();
1388}
1389
1390ASTImporter::~ASTImporter() { }
Douglas Gregor96e578d2010-02-05 17:54:41 +00001391
1392QualType ASTImporter::Import(QualType FromT) {
1393 if (FromT.isNull())
1394 return QualType();
1395
Douglas Gregorf65bbb32010-02-08 15:18:58 +00001396 // Check whether we've already imported this type.
1397 llvm::DenseMap<Type *, Type *>::iterator Pos
1398 = ImportedTypes.find(FromT.getTypePtr());
1399 if (Pos != ImportedTypes.end())
1400 return ToContext.getQualifiedType(Pos->second, FromT.getQualifiers());
Douglas Gregor96e578d2010-02-05 17:54:41 +00001401
Douglas Gregorf65bbb32010-02-08 15:18:58 +00001402 // Import the type
Douglas Gregor96e578d2010-02-05 17:54:41 +00001403 ASTNodeImporter Importer(*this);
1404 QualType ToT = Importer.Visit(FromT.getTypePtr());
1405 if (ToT.isNull())
1406 return ToT;
1407
Douglas Gregorf65bbb32010-02-08 15:18:58 +00001408 // Record the imported type.
1409 ImportedTypes[FromT.getTypePtr()] = ToT.getTypePtr();
1410
Douglas Gregor96e578d2010-02-05 17:54:41 +00001411 return ToContext.getQualifiedType(ToT, FromT.getQualifiers());
1412}
1413
Douglas Gregor62d311f2010-02-09 19:21:46 +00001414TypeSourceInfo *ASTImporter::Import(TypeSourceInfo *FromTSI) {
Douglas Gregorfa7a0e52010-02-10 17:47:19 +00001415 if (!FromTSI)
1416 return FromTSI;
1417
1418 // FIXME: For now we just create a "trivial" type source info based
1419 // on the type and a seingle location. Implement a real version of
1420 // this.
1421 QualType T = Import(FromTSI->getType());
1422 if (T.isNull())
1423 return 0;
1424
1425 return ToContext.getTrivialTypeSourceInfo(T,
1426 FromTSI->getTypeLoc().getFullSourceRange().getBegin());
Douglas Gregor62d311f2010-02-09 19:21:46 +00001427}
1428
1429Decl *ASTImporter::Import(Decl *FromD) {
1430 if (!FromD)
1431 return 0;
1432
1433 // Check whether we've already imported this declaration.
1434 llvm::DenseMap<Decl *, Decl *>::iterator Pos = ImportedDecls.find(FromD);
1435 if (Pos != ImportedDecls.end())
1436 return Pos->second;
1437
1438 // Import the type
1439 ASTNodeImporter Importer(*this);
1440 Decl *ToD = Importer.Visit(FromD);
1441 if (!ToD)
1442 return 0;
1443
1444 // Record the imported declaration.
1445 ImportedDecls[FromD] = ToD;
1446 return ToD;
1447}
1448
1449DeclContext *ASTImporter::ImportContext(DeclContext *FromDC) {
1450 if (!FromDC)
1451 return FromDC;
1452
1453 return cast_or_null<DeclContext>(Import(cast<Decl>(FromDC)));
1454}
1455
1456Expr *ASTImporter::Import(Expr *FromE) {
1457 if (!FromE)
1458 return 0;
1459
1460 return cast_or_null<Expr>(Import(cast<Stmt>(FromE)));
1461}
1462
1463Stmt *ASTImporter::Import(Stmt *FromS) {
1464 if (!FromS)
1465 return 0;
1466
Douglas Gregor7eeb5972010-02-11 19:21:55 +00001467 // Check whether we've already imported this declaration.
1468 llvm::DenseMap<Stmt *, Stmt *>::iterator Pos = ImportedStmts.find(FromS);
1469 if (Pos != ImportedStmts.end())
1470 return Pos->second;
1471
1472 // Import the type
1473 ASTNodeImporter Importer(*this);
1474 Stmt *ToS = Importer.Visit(FromS);
1475 if (!ToS)
1476 return 0;
1477
1478 // Record the imported declaration.
1479 ImportedStmts[FromS] = ToS;
1480 return ToS;
Douglas Gregor62d311f2010-02-09 19:21:46 +00001481}
1482
1483NestedNameSpecifier *ASTImporter::Import(NestedNameSpecifier *FromNNS) {
1484 if (!FromNNS)
1485 return 0;
1486
1487 // FIXME: Implement!
1488 return 0;
1489}
1490
1491SourceLocation ASTImporter::Import(SourceLocation FromLoc) {
1492 if (FromLoc.isInvalid())
1493 return SourceLocation();
1494
Douglas Gregor811663e2010-02-10 00:15:17 +00001495 SourceManager &FromSM = FromContext.getSourceManager();
1496
1497 // For now, map everything down to its spelling location, so that we
1498 // don't have to import macro instantiations.
1499 // FIXME: Import macro instantiations!
1500 FromLoc = FromSM.getSpellingLoc(FromLoc);
1501 std::pair<FileID, unsigned> Decomposed = FromSM.getDecomposedLoc(FromLoc);
1502 SourceManager &ToSM = ToContext.getSourceManager();
1503 return ToSM.getLocForStartOfFile(Import(Decomposed.first))
1504 .getFileLocWithOffset(Decomposed.second);
Douglas Gregor62d311f2010-02-09 19:21:46 +00001505}
1506
1507SourceRange ASTImporter::Import(SourceRange FromRange) {
1508 return SourceRange(Import(FromRange.getBegin()), Import(FromRange.getEnd()));
1509}
1510
Douglas Gregor811663e2010-02-10 00:15:17 +00001511FileID ASTImporter::Import(FileID FromID) {
1512 llvm::DenseMap<unsigned, FileID>::iterator Pos
1513 = ImportedFileIDs.find(FromID.getHashValue());
1514 if (Pos != ImportedFileIDs.end())
1515 return Pos->second;
1516
1517 SourceManager &FromSM = FromContext.getSourceManager();
1518 SourceManager &ToSM = ToContext.getSourceManager();
1519 const SrcMgr::SLocEntry &FromSLoc = FromSM.getSLocEntry(FromID);
1520 assert(FromSLoc.isFile() && "Cannot handle macro instantiations yet");
1521
1522 // Include location of this file.
1523 SourceLocation ToIncludeLoc = Import(FromSLoc.getFile().getIncludeLoc());
1524
1525 // Map the FileID for to the "to" source manager.
1526 FileID ToID;
1527 const SrcMgr::ContentCache *Cache = FromSLoc.getFile().getContentCache();
1528 if (Cache->Entry) {
1529 // FIXME: We probably want to use getVirtualFile(), so we don't hit the
1530 // disk again
1531 // FIXME: We definitely want to re-use the existing MemoryBuffer, rather
1532 // than mmap the files several times.
1533 const FileEntry *Entry = ToFileManager.getFile(Cache->Entry->getName());
1534 ToID = ToSM.createFileID(Entry, ToIncludeLoc,
1535 FromSLoc.getFile().getFileCharacteristic());
1536 } else {
1537 // FIXME: We want to re-use the existing MemoryBuffer!
1538 const llvm::MemoryBuffer *FromBuf = Cache->getBuffer();
1539 llvm::MemoryBuffer *ToBuf
1540 = llvm::MemoryBuffer::getMemBufferCopy(FromBuf->getBufferStart(),
1541 FromBuf->getBufferEnd(),
1542 FromBuf->getBufferIdentifier());
1543 ToID = ToSM.createFileIDForMemBuffer(ToBuf);
1544 }
1545
1546
1547 ImportedFileIDs[FromID.getHashValue()] = ToID;
1548 return ToID;
1549}
1550
Douglas Gregor96e578d2010-02-05 17:54:41 +00001551DeclarationName ASTImporter::Import(DeclarationName FromName) {
1552 if (!FromName)
1553 return DeclarationName();
1554
1555 switch (FromName.getNameKind()) {
1556 case DeclarationName::Identifier:
1557 return Import(FromName.getAsIdentifierInfo());
1558
1559 case DeclarationName::ObjCZeroArgSelector:
1560 case DeclarationName::ObjCOneArgSelector:
1561 case DeclarationName::ObjCMultiArgSelector:
1562 return Import(FromName.getObjCSelector());
1563
1564 case DeclarationName::CXXConstructorName: {
1565 QualType T = Import(FromName.getCXXNameType());
1566 if (T.isNull())
1567 return DeclarationName();
1568
1569 return ToContext.DeclarationNames.getCXXConstructorName(
1570 ToContext.getCanonicalType(T));
1571 }
1572
1573 case DeclarationName::CXXDestructorName: {
1574 QualType T = Import(FromName.getCXXNameType());
1575 if (T.isNull())
1576 return DeclarationName();
1577
1578 return ToContext.DeclarationNames.getCXXDestructorName(
1579 ToContext.getCanonicalType(T));
1580 }
1581
1582 case DeclarationName::CXXConversionFunctionName: {
1583 QualType T = Import(FromName.getCXXNameType());
1584 if (T.isNull())
1585 return DeclarationName();
1586
1587 return ToContext.DeclarationNames.getCXXConversionFunctionName(
1588 ToContext.getCanonicalType(T));
1589 }
1590
1591 case DeclarationName::CXXOperatorName:
1592 return ToContext.DeclarationNames.getCXXOperatorName(
1593 FromName.getCXXOverloadedOperator());
1594
1595 case DeclarationName::CXXLiteralOperatorName:
1596 return ToContext.DeclarationNames.getCXXLiteralOperatorName(
1597 Import(FromName.getCXXLiteralIdentifier()));
1598
1599 case DeclarationName::CXXUsingDirective:
1600 // FIXME: STATICS!
1601 return DeclarationName::getUsingDirectiveName();
1602 }
1603
1604 // Silence bogus GCC warning
1605 return DeclarationName();
1606}
1607
1608IdentifierInfo *ASTImporter::Import(IdentifierInfo *FromId) {
1609 if (!FromId)
1610 return 0;
1611
1612 return &ToContext.Idents.get(FromId->getName());
1613}
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001614
1615DeclarationName ASTImporter::HandleNameConflict(DeclarationName Name,
1616 DeclContext *DC,
1617 unsigned IDNS,
1618 NamedDecl **Decls,
1619 unsigned NumDecls) {
1620 return Name;
1621}
1622
1623DiagnosticBuilder ASTImporter::ToDiag(SourceLocation Loc, unsigned DiagID) {
Douglas Gregor7eeb5972010-02-11 19:21:55 +00001624 return Diags.Report(FullSourceLoc(Loc, ToContext.getSourceManager()),
1625 DiagID);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001626}
1627
1628DiagnosticBuilder ASTImporter::FromDiag(SourceLocation Loc, unsigned DiagID) {
Douglas Gregor7eeb5972010-02-11 19:21:55 +00001629 return Diags.Report(FullSourceLoc(Loc, FromContext.getSourceManager()),
1630 DiagID);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001631}
Douglas Gregor8cdbe642010-02-12 23:44:20 +00001632
1633Decl *ASTImporter::Imported(Decl *From, Decl *To) {
1634 ImportedDecls[From] = To;
1635 return To;
1636}