blob: 90a1958e566c23f391b5f3b599d109392d86d7ee [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 Gregor96e578d2010-02-05 17:54:41 +000018#include "clang/AST/DeclObjC.h"
Douglas Gregor3aed6cd2010-02-08 21:09:39 +000019#include "clang/AST/DeclVisitor.h"
Douglas Gregorfa7a0e52010-02-10 17:47:19 +000020#include "clang/AST/TypeLoc.h"
Douglas Gregor96e578d2010-02-05 17:54:41 +000021#include "clang/AST/TypeVisitor.h"
Douglas Gregor811663e2010-02-10 00:15:17 +000022#include "clang/Basic/FileManager.h"
23#include "clang/Basic/SourceManager.h"
24#include "llvm/Support/MemoryBuffer.h"
Douglas Gregor96e578d2010-02-05 17:54:41 +000025
26using namespace clang;
27
28namespace {
Douglas Gregor3aed6cd2010-02-08 21:09:39 +000029 class ASTNodeImporter : public TypeVisitor<ASTNodeImporter, QualType>,
30 public DeclVisitor<ASTNodeImporter, Decl *> {
Douglas Gregor96e578d2010-02-05 17:54:41 +000031 ASTImporter &Importer;
32
33 public:
34 explicit ASTNodeImporter(ASTImporter &Importer) : Importer(Importer) { }
35
36 using TypeVisitor<ASTNodeImporter, QualType>::Visit;
Douglas Gregor62d311f2010-02-09 19:21:46 +000037 using DeclVisitor<ASTNodeImporter, Decl *>::Visit;
Douglas Gregor96e578d2010-02-05 17:54:41 +000038
39 // Importing types
Douglas Gregore4c83e42010-02-09 22:48:33 +000040 QualType VisitType(Type *T);
Douglas Gregor96e578d2010-02-05 17:54:41 +000041 QualType VisitBuiltinType(BuiltinType *T);
42 QualType VisitComplexType(ComplexType *T);
43 QualType VisitPointerType(PointerType *T);
44 QualType VisitBlockPointerType(BlockPointerType *T);
45 QualType VisitLValueReferenceType(LValueReferenceType *T);
46 QualType VisitRValueReferenceType(RValueReferenceType *T);
47 QualType VisitMemberPointerType(MemberPointerType *T);
48 QualType VisitConstantArrayType(ConstantArrayType *T);
49 QualType VisitIncompleteArrayType(IncompleteArrayType *T);
50 QualType VisitVariableArrayType(VariableArrayType *T);
51 // FIXME: DependentSizedArrayType
52 // FIXME: DependentSizedExtVectorType
53 QualType VisitVectorType(VectorType *T);
54 QualType VisitExtVectorType(ExtVectorType *T);
55 QualType VisitFunctionNoProtoType(FunctionNoProtoType *T);
56 QualType VisitFunctionProtoType(FunctionProtoType *T);
57 // FIXME: UnresolvedUsingType
58 QualType VisitTypedefType(TypedefType *T);
59 QualType VisitTypeOfExprType(TypeOfExprType *T);
60 // FIXME: DependentTypeOfExprType
61 QualType VisitTypeOfType(TypeOfType *T);
62 QualType VisitDecltypeType(DecltypeType *T);
63 // FIXME: DependentDecltypeType
64 QualType VisitRecordType(RecordType *T);
65 QualType VisitEnumType(EnumType *T);
66 QualType VisitElaboratedType(ElaboratedType *T);
67 // FIXME: TemplateTypeParmType
68 // FIXME: SubstTemplateTypeParmType
69 // FIXME: TemplateSpecializationType
70 QualType VisitQualifiedNameType(QualifiedNameType *T);
71 // FIXME: TypenameType
72 QualType VisitObjCInterfaceType(ObjCInterfaceType *T);
73 QualType VisitObjCObjectPointerType(ObjCObjectPointerType *T);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +000074
75 // Importing declarations
Douglas Gregorbb7930c2010-02-10 19:54:31 +000076 bool ImportDeclParts(NamedDecl *D, DeclContext *&DC,
77 DeclContext *&LexicalDC, DeclarationName &Name,
78 SourceLocation &Loc);
79 bool ImportDeclParts(DeclaratorDecl *D,
80 DeclContext *&DC, DeclContext *&LexicalDC,
81 DeclarationName &Name, SourceLocation &Loc,
82 QualType &T);
Douglas Gregore4c83e42010-02-09 22:48:33 +000083 Decl *VisitDecl(Decl *D);
Douglas Gregor5fa74c32010-02-10 21:10:29 +000084 Decl *VisitTypedefDecl(TypedefDecl *D);
Douglas Gregorbb7930c2010-02-10 19:54:31 +000085 Decl *VisitFunctionDecl(FunctionDecl *D);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +000086 Decl *VisitVarDecl(VarDecl *D);
Douglas Gregorbb7930c2010-02-10 19:54:31 +000087 Decl *VisitParmVarDecl(ParmVarDecl *D);
Douglas Gregor96e578d2010-02-05 17:54:41 +000088 };
89}
90
91//----------------------------------------------------------------------------
92// Import Types
93//----------------------------------------------------------------------------
94
Douglas Gregore4c83e42010-02-09 22:48:33 +000095QualType ASTNodeImporter::VisitType(Type *T) {
96 Importer.FromDiag(SourceLocation(), diag::err_unsupported_ast_node)
97 << T->getTypeClassName();
98 return QualType();
99}
100
Douglas Gregor96e578d2010-02-05 17:54:41 +0000101QualType ASTNodeImporter::VisitBuiltinType(BuiltinType *T) {
102 switch (T->getKind()) {
103 case BuiltinType::Void: return Importer.getToContext().VoidTy;
104 case BuiltinType::Bool: return Importer.getToContext().BoolTy;
105
106 case BuiltinType::Char_U:
107 // The context we're importing from has an unsigned 'char'. If we're
108 // importing into a context with a signed 'char', translate to
109 // 'unsigned char' instead.
110 if (Importer.getToContext().getLangOptions().CharIsSigned)
111 return Importer.getToContext().UnsignedCharTy;
112
113 return Importer.getToContext().CharTy;
114
115 case BuiltinType::UChar: return Importer.getToContext().UnsignedCharTy;
116
117 case BuiltinType::Char16:
118 // FIXME: Make sure that the "to" context supports C++!
119 return Importer.getToContext().Char16Ty;
120
121 case BuiltinType::Char32:
122 // FIXME: Make sure that the "to" context supports C++!
123 return Importer.getToContext().Char32Ty;
124
125 case BuiltinType::UShort: return Importer.getToContext().UnsignedShortTy;
126 case BuiltinType::UInt: return Importer.getToContext().UnsignedIntTy;
127 case BuiltinType::ULong: return Importer.getToContext().UnsignedLongTy;
128 case BuiltinType::ULongLong:
129 return Importer.getToContext().UnsignedLongLongTy;
130 case BuiltinType::UInt128: return Importer.getToContext().UnsignedInt128Ty;
131
132 case BuiltinType::Char_S:
133 // The context we're importing from has an unsigned 'char'. If we're
134 // importing into a context with a signed 'char', translate to
135 // 'unsigned char' instead.
136 if (!Importer.getToContext().getLangOptions().CharIsSigned)
137 return Importer.getToContext().SignedCharTy;
138
139 return Importer.getToContext().CharTy;
140
141 case BuiltinType::SChar: return Importer.getToContext().SignedCharTy;
142 case BuiltinType::WChar:
143 // FIXME: If not in C++, shall we translate to the C equivalent of
144 // wchar_t?
145 return Importer.getToContext().WCharTy;
146
147 case BuiltinType::Short : return Importer.getToContext().ShortTy;
148 case BuiltinType::Int : return Importer.getToContext().IntTy;
149 case BuiltinType::Long : return Importer.getToContext().LongTy;
150 case BuiltinType::LongLong : return Importer.getToContext().LongLongTy;
151 case BuiltinType::Int128 : return Importer.getToContext().Int128Ty;
152 case BuiltinType::Float: return Importer.getToContext().FloatTy;
153 case BuiltinType::Double: return Importer.getToContext().DoubleTy;
154 case BuiltinType::LongDouble: return Importer.getToContext().LongDoubleTy;
155
156 case BuiltinType::NullPtr:
157 // FIXME: Make sure that the "to" context supports C++0x!
158 return Importer.getToContext().NullPtrTy;
159
160 case BuiltinType::Overload: return Importer.getToContext().OverloadTy;
161 case BuiltinType::Dependent: return Importer.getToContext().DependentTy;
162 case BuiltinType::UndeducedAuto:
163 // FIXME: Make sure that the "to" context supports C++0x!
164 return Importer.getToContext().UndeducedAutoTy;
165
166 case BuiltinType::ObjCId:
167 // FIXME: Make sure that the "to" context supports Objective-C!
168 return Importer.getToContext().ObjCBuiltinIdTy;
169
170 case BuiltinType::ObjCClass:
171 return Importer.getToContext().ObjCBuiltinClassTy;
172
173 case BuiltinType::ObjCSel:
174 return Importer.getToContext().ObjCBuiltinSelTy;
175 }
176
177 return QualType();
178}
179
180QualType ASTNodeImporter::VisitComplexType(ComplexType *T) {
181 QualType ToElementType = Importer.Import(T->getElementType());
182 if (ToElementType.isNull())
183 return QualType();
184
185 return Importer.getToContext().getComplexType(ToElementType);
186}
187
188QualType ASTNodeImporter::VisitPointerType(PointerType *T) {
189 QualType ToPointeeType = Importer.Import(T->getPointeeType());
190 if (ToPointeeType.isNull())
191 return QualType();
192
193 return Importer.getToContext().getPointerType(ToPointeeType);
194}
195
196QualType ASTNodeImporter::VisitBlockPointerType(BlockPointerType *T) {
197 // FIXME: Check for blocks support in "to" context.
198 QualType ToPointeeType = Importer.Import(T->getPointeeType());
199 if (ToPointeeType.isNull())
200 return QualType();
201
202 return Importer.getToContext().getBlockPointerType(ToPointeeType);
203}
204
205QualType ASTNodeImporter::VisitLValueReferenceType(LValueReferenceType *T) {
206 // FIXME: Check for C++ support in "to" context.
207 QualType ToPointeeType = Importer.Import(T->getPointeeTypeAsWritten());
208 if (ToPointeeType.isNull())
209 return QualType();
210
211 return Importer.getToContext().getLValueReferenceType(ToPointeeType);
212}
213
214QualType ASTNodeImporter::VisitRValueReferenceType(RValueReferenceType *T) {
215 // FIXME: Check for C++0x support in "to" context.
216 QualType ToPointeeType = Importer.Import(T->getPointeeTypeAsWritten());
217 if (ToPointeeType.isNull())
218 return QualType();
219
220 return Importer.getToContext().getRValueReferenceType(ToPointeeType);
221}
222
223QualType ASTNodeImporter::VisitMemberPointerType(MemberPointerType *T) {
224 // FIXME: Check for C++ support in "to" context.
225 QualType ToPointeeType = Importer.Import(T->getPointeeType());
226 if (ToPointeeType.isNull())
227 return QualType();
228
229 QualType ClassType = Importer.Import(QualType(T->getClass(), 0));
230 return Importer.getToContext().getMemberPointerType(ToPointeeType,
231 ClassType.getTypePtr());
232}
233
234QualType ASTNodeImporter::VisitConstantArrayType(ConstantArrayType *T) {
235 QualType ToElementType = Importer.Import(T->getElementType());
236 if (ToElementType.isNull())
237 return QualType();
238
239 return Importer.getToContext().getConstantArrayType(ToElementType,
240 T->getSize(),
241 T->getSizeModifier(),
242 T->getIndexTypeCVRQualifiers());
243}
244
245QualType ASTNodeImporter::VisitIncompleteArrayType(IncompleteArrayType *T) {
246 QualType ToElementType = Importer.Import(T->getElementType());
247 if (ToElementType.isNull())
248 return QualType();
249
250 return Importer.getToContext().getIncompleteArrayType(ToElementType,
251 T->getSizeModifier(),
252 T->getIndexTypeCVRQualifiers());
253}
254
255QualType ASTNodeImporter::VisitVariableArrayType(VariableArrayType *T) {
256 QualType ToElementType = Importer.Import(T->getElementType());
257 if (ToElementType.isNull())
258 return QualType();
259
260 Expr *Size = Importer.Import(T->getSizeExpr());
261 if (!Size)
262 return QualType();
263
264 SourceRange Brackets = Importer.Import(T->getBracketsRange());
265 return Importer.getToContext().getVariableArrayType(ToElementType, Size,
266 T->getSizeModifier(),
267 T->getIndexTypeCVRQualifiers(),
268 Brackets);
269}
270
271QualType ASTNodeImporter::VisitVectorType(VectorType *T) {
272 QualType ToElementType = Importer.Import(T->getElementType());
273 if (ToElementType.isNull())
274 return QualType();
275
276 return Importer.getToContext().getVectorType(ToElementType,
277 T->getNumElements(),
278 T->isAltiVec(),
279 T->isPixel());
280}
281
282QualType ASTNodeImporter::VisitExtVectorType(ExtVectorType *T) {
283 QualType ToElementType = Importer.Import(T->getElementType());
284 if (ToElementType.isNull())
285 return QualType();
286
287 return Importer.getToContext().getExtVectorType(ToElementType,
288 T->getNumElements());
289}
290
291QualType ASTNodeImporter::VisitFunctionNoProtoType(FunctionNoProtoType *T) {
292 // FIXME: What happens if we're importing a function without a prototype
293 // into C++? Should we make it variadic?
294 QualType ToResultType = Importer.Import(T->getResultType());
295 if (ToResultType.isNull())
296 return QualType();
297
298 return Importer.getToContext().getFunctionNoProtoType(ToResultType,
299 T->getNoReturnAttr(),
300 T->getCallConv());
301}
302
303QualType ASTNodeImporter::VisitFunctionProtoType(FunctionProtoType *T) {
304 QualType ToResultType = Importer.Import(T->getResultType());
305 if (ToResultType.isNull())
306 return QualType();
307
308 // Import argument types
309 llvm::SmallVector<QualType, 4> ArgTypes;
310 for (FunctionProtoType::arg_type_iterator A = T->arg_type_begin(),
311 AEnd = T->arg_type_end();
312 A != AEnd; ++A) {
313 QualType ArgType = Importer.Import(*A);
314 if (ArgType.isNull())
315 return QualType();
316 ArgTypes.push_back(ArgType);
317 }
318
319 // Import exception types
320 llvm::SmallVector<QualType, 4> ExceptionTypes;
321 for (FunctionProtoType::exception_iterator E = T->exception_begin(),
322 EEnd = T->exception_end();
323 E != EEnd; ++E) {
324 QualType ExceptionType = Importer.Import(*E);
325 if (ExceptionType.isNull())
326 return QualType();
327 ExceptionTypes.push_back(ExceptionType);
328 }
329
330 return Importer.getToContext().getFunctionType(ToResultType, ArgTypes.data(),
331 ArgTypes.size(),
332 T->isVariadic(),
333 T->getTypeQuals(),
334 T->hasExceptionSpec(),
335 T->hasAnyExceptionSpec(),
336 ExceptionTypes.size(),
337 ExceptionTypes.data(),
338 T->getNoReturnAttr(),
339 T->getCallConv());
340}
341
342QualType ASTNodeImporter::VisitTypedefType(TypedefType *T) {
343 TypedefDecl *ToDecl
344 = dyn_cast_or_null<TypedefDecl>(Importer.Import(T->getDecl()));
345 if (!ToDecl)
346 return QualType();
347
348 return Importer.getToContext().getTypeDeclType(ToDecl);
349}
350
351QualType ASTNodeImporter::VisitTypeOfExprType(TypeOfExprType *T) {
352 Expr *ToExpr = Importer.Import(T->getUnderlyingExpr());
353 if (!ToExpr)
354 return QualType();
355
356 return Importer.getToContext().getTypeOfExprType(ToExpr);
357}
358
359QualType ASTNodeImporter::VisitTypeOfType(TypeOfType *T) {
360 QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType());
361 if (ToUnderlyingType.isNull())
362 return QualType();
363
364 return Importer.getToContext().getTypeOfType(ToUnderlyingType);
365}
366
367QualType ASTNodeImporter::VisitDecltypeType(DecltypeType *T) {
368 Expr *ToExpr = Importer.Import(T->getUnderlyingExpr());
369 if (!ToExpr)
370 return QualType();
371
372 return Importer.getToContext().getDecltypeType(ToExpr);
373}
374
375QualType ASTNodeImporter::VisitRecordType(RecordType *T) {
376 RecordDecl *ToDecl
377 = dyn_cast_or_null<RecordDecl>(Importer.Import(T->getDecl()));
378 if (!ToDecl)
379 return QualType();
380
381 return Importer.getToContext().getTagDeclType(ToDecl);
382}
383
384QualType ASTNodeImporter::VisitEnumType(EnumType *T) {
385 EnumDecl *ToDecl
386 = dyn_cast_or_null<EnumDecl>(Importer.Import(T->getDecl()));
387 if (!ToDecl)
388 return QualType();
389
390 return Importer.getToContext().getTagDeclType(ToDecl);
391}
392
393QualType ASTNodeImporter::VisitElaboratedType(ElaboratedType *T) {
394 QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType());
395 if (ToUnderlyingType.isNull())
396 return QualType();
397
398 return Importer.getToContext().getElaboratedType(ToUnderlyingType,
399 T->getTagKind());
400}
401
402QualType ASTNodeImporter::VisitQualifiedNameType(QualifiedNameType *T) {
403 NestedNameSpecifier *ToQualifier = Importer.Import(T->getQualifier());
404 if (!ToQualifier)
405 return QualType();
406
407 QualType ToNamedType = Importer.Import(T->getNamedType());
408 if (ToNamedType.isNull())
409 return QualType();
410
411 return Importer.getToContext().getQualifiedNameType(ToQualifier, ToNamedType);
412}
413
414QualType ASTNodeImporter::VisitObjCInterfaceType(ObjCInterfaceType *T) {
415 ObjCInterfaceDecl *Class
416 = dyn_cast_or_null<ObjCInterfaceDecl>(Importer.Import(T->getDecl()));
417 if (!Class)
418 return QualType();
419
420 llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
421 for (ObjCInterfaceType::qual_iterator P = T->qual_begin(),
422 PEnd = T->qual_end();
423 P != PEnd; ++P) {
424 ObjCProtocolDecl *Protocol
425 = dyn_cast_or_null<ObjCProtocolDecl>(Importer.Import(*P));
426 if (!Protocol)
427 return QualType();
428 Protocols.push_back(Protocol);
429 }
430
431 return Importer.getToContext().getObjCInterfaceType(Class,
432 Protocols.data(),
433 Protocols.size());
434}
435
436QualType ASTNodeImporter::VisitObjCObjectPointerType(ObjCObjectPointerType *T) {
437 QualType ToPointeeType = Importer.Import(T->getPointeeType());
438 if (ToPointeeType.isNull())
439 return QualType();
440
441 llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
442 for (ObjCObjectPointerType::qual_iterator P = T->qual_begin(),
443 PEnd = T->qual_end();
444 P != PEnd; ++P) {
445 ObjCProtocolDecl *Protocol
446 = dyn_cast_or_null<ObjCProtocolDecl>(Importer.Import(*P));
447 if (!Protocol)
448 return QualType();
449 Protocols.push_back(Protocol);
450 }
451
452 return Importer.getToContext().getObjCObjectPointerType(ToPointeeType,
453 Protocols.data(),
454 Protocols.size());
455}
456
Douglas Gregor3aed6cd2010-02-08 21:09:39 +0000457//----------------------------------------------------------------------------
458// Import Declarations
459//----------------------------------------------------------------------------
Douglas Gregorbb7930c2010-02-10 19:54:31 +0000460bool ASTNodeImporter::ImportDeclParts(NamedDecl *D, DeclContext *&DC,
461 DeclContext *&LexicalDC,
462 DeclarationName &Name,
463 SourceLocation &Loc) {
464 // Import the context of this declaration.
465 DC = Importer.ImportContext(D->getDeclContext());
466 if (!DC)
467 return true;
468
469 LexicalDC = DC;
470 if (D->getDeclContext() != D->getLexicalDeclContext()) {
471 LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
472 if (!LexicalDC)
473 return true;
474 }
475
476 // Import the name of this declaration.
477 Name = Importer.Import(D->getDeclName());
478 if (D->getDeclName() && !Name)
479 return true;
480
481 // Import the location of this declaration.
482 Loc = Importer.Import(D->getLocation());
483 return false;
484}
485
486bool ASTNodeImporter::ImportDeclParts(DeclaratorDecl *D,
487 DeclContext *&DC,
488 DeclContext *&LexicalDC,
489 DeclarationName &Name,
490 SourceLocation &Loc,
491 QualType &T) {
492 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
493 return true;
494
495 // Import the type of this declaration.
496 T = Importer.Import(D->getType());
497 if (T.isNull())
498 return true;
499
500 return false;
501}
502
Douglas Gregore4c83e42010-02-09 22:48:33 +0000503Decl *ASTNodeImporter::VisitDecl(Decl *D) {
Douglas Gregor811663e2010-02-10 00:15:17 +0000504 Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node)
Douglas Gregore4c83e42010-02-09 22:48:33 +0000505 << D->getDeclKindName();
506 return 0;
507}
508
Douglas Gregor5fa74c32010-02-10 21:10:29 +0000509Decl *ASTNodeImporter::VisitTypedefDecl(TypedefDecl *D) {
510 // Import the major distinguishing characteristics of this typedef.
511 DeclContext *DC, *LexicalDC;
512 DeclarationName Name;
513 SourceLocation Loc;
514 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
515 return 0;
516
517 // Import the underlying type of this typedef;
518 QualType T = Importer.Import(D->getUnderlyingType());
519 if (T.isNull())
520 return 0;
521
522 // If this typedef is not in block scope, determine whether we've
523 // seen a typedef with the same name (that we can merge with) or any
524 // other entity by that name (which name lookup could conflict with).
525 if (!DC->isFunctionOrMethod()) {
526 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
527 unsigned IDNS = Decl::IDNS_Ordinary;
528 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
529 Lookup.first != Lookup.second;
530 ++Lookup.first) {
531 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
532 continue;
533 if (TypedefDecl *FoundTypedef = dyn_cast<TypedefDecl>(*Lookup.first)) {
534 if (Importer.getToContext().typesAreCompatible(T,
535 FoundTypedef->getUnderlyingType())) {
536 Importer.getImportedDecls()[D] = FoundTypedef;
537 return FoundTypedef;
538 }
539 }
540
541 ConflictingDecls.push_back(*Lookup.first);
542 }
543
544 if (!ConflictingDecls.empty()) {
545 Name = Importer.HandleNameConflict(Name, DC, IDNS,
546 ConflictingDecls.data(),
547 ConflictingDecls.size());
548 if (!Name)
549 return 0;
550 }
551 }
552
553 // Create the new typedef node.
554 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
555 TypedefDecl *ToTypedef = TypedefDecl::Create(Importer.getToContext(), DC,
556 Loc, Name.getAsIdentifierInfo(),
557 TInfo);
558 ToTypedef->setLexicalDeclContext(LexicalDC);
559 Importer.getImportedDecls()[D] = ToTypedef;
560 LexicalDC->addDecl(ToTypedef);
561 return ToTypedef;
562}
563
Douglas Gregorbb7930c2010-02-10 19:54:31 +0000564Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
565 // Import the major distinguishing characteristics of this function.
566 DeclContext *DC, *LexicalDC;
567 DeclarationName Name;
568 QualType T;
569 SourceLocation Loc;
570 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc, T))
Douglas Gregor3aed6cd2010-02-08 21:09:39 +0000571 return 0;
Douglas Gregorbb7930c2010-02-10 19:54:31 +0000572
573 // Try to find a function in our own ("to") context with the same name, same
574 // type, and in the same context as the function we're importing.
575 if (!LexicalDC->isFunctionOrMethod()) {
576 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
577 unsigned IDNS = Decl::IDNS_Ordinary;
578 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
579 Lookup.first != Lookup.second;
580 ++Lookup.first) {
581 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
582 continue;
Douglas Gregor3aed6cd2010-02-08 21:09:39 +0000583
Douglas Gregorbb7930c2010-02-10 19:54:31 +0000584 if (FunctionDecl *FoundFunction = dyn_cast<FunctionDecl>(*Lookup.first)) {
585 if (isExternalLinkage(FoundFunction->getLinkage()) &&
586 isExternalLinkage(D->getLinkage())) {
587 if (Importer.getToContext().typesAreCompatible(T,
588 FoundFunction->getType())) {
589 // FIXME: Actually try to merge the body and other attributes.
590 Importer.getImportedDecls()[D] = FoundFunction;
591 return FoundFunction;
592 }
593
594 // FIXME: Check for overloading more carefully, e.g., by boosting
595 // Sema::IsOverload out to the AST library.
596
597 // Function overloading is okay in C++.
598 if (Importer.getToContext().getLangOptions().CPlusPlus)
599 continue;
600
601 // Complain about inconsistent function types.
602 Importer.ToDiag(Loc, diag::err_odr_function_type_inconsistent)
603 << Name << T << FoundFunction->getType();
604 Importer.ToDiag(FoundFunction->getLocation(),
605 diag::note_odr_value_here)
606 << FoundFunction->getType();
607 }
608 }
609
610 ConflictingDecls.push_back(*Lookup.first);
611 }
612
613 if (!ConflictingDecls.empty()) {
614 Name = Importer.HandleNameConflict(Name, DC, IDNS,
615 ConflictingDecls.data(),
616 ConflictingDecls.size());
617 if (!Name)
618 return 0;
619 }
Douglas Gregor62d311f2010-02-09 19:21:46 +0000620 }
Douglas Gregorbb7930c2010-02-10 19:54:31 +0000621
622 // Import the function parameters.
623 llvm::SmallVector<ParmVarDecl *, 8> Parameters;
624 for (FunctionDecl::param_iterator P = D->param_begin(), PEnd = D->param_end();
625 P != PEnd; ++P) {
626 ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(*P));
627 if (!ToP)
628 return 0;
629
630 Parameters.push_back(ToP);
631 }
632
633 // Create the imported function.
634 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
635 FunctionDecl *ToFunction
636 = FunctionDecl::Create(Importer.getToContext(), DC, Loc,
637 Name, T, TInfo, D->getStorageClass(),
638 D->isInlineSpecified(),
639 D->hasWrittenPrototype());
640 ToFunction->setLexicalDeclContext(LexicalDC);
641 Importer.getImportedDecls()[D] = ToFunction;
642 LexicalDC->addDecl(ToFunction);
Douglas Gregor62d311f2010-02-09 19:21:46 +0000643
Douglas Gregorbb7930c2010-02-10 19:54:31 +0000644 // Set the parameters.
645 for (unsigned I = 0, N = Parameters.size(); I != N; ++I) {
646 Parameters[I]->setOwningFunction(ToFunction);
647 ToFunction->addDecl(Parameters[I]);
648 }
649 ToFunction->setParams(Importer.getToContext(),
650 Parameters.data(), Parameters.size());
651
652 // FIXME: Other bits to merge?
Douglas Gregor3aed6cd2010-02-08 21:09:39 +0000653
Douglas Gregorbb7930c2010-02-10 19:54:31 +0000654 return ToFunction;
655}
656
657Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
658 // Import the major distinguishing characteristics of a variable.
659 DeclContext *DC, *LexicalDC;
660 DeclarationName Name;
661 QualType T;
662 SourceLocation Loc;
663 if (ImportDeclParts(D, DC, LexicalDC, Name, Loc, T))
Douglas Gregor3aed6cd2010-02-08 21:09:39 +0000664 return 0;
665
Douglas Gregor3aed6cd2010-02-08 21:09:39 +0000666 // Try to find a variable in our own ("to") context with the same name and
667 // in the same context as the variable we're importing.
Douglas Gregor62d311f2010-02-09 19:21:46 +0000668 if (D->isFileVarDecl()) {
Douglas Gregor3aed6cd2010-02-08 21:09:39 +0000669 VarDecl *MergeWithVar = 0;
670 llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
671 unsigned IDNS = Decl::IDNS_Ordinary;
Douglas Gregor62d311f2010-02-09 19:21:46 +0000672 for (DeclContext::lookup_result Lookup = DC->lookup(Name);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +0000673 Lookup.first != Lookup.second;
674 ++Lookup.first) {
675 if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
676 continue;
677
678 if (VarDecl *FoundVar = dyn_cast<VarDecl>(*Lookup.first)) {
679 // We have found a variable that we may need to merge with. Check it.
680 if (isExternalLinkage(FoundVar->getLinkage()) &&
681 isExternalLinkage(D->getLinkage())) {
682 if (Importer.getToContext().typesAreCompatible(T,
683 FoundVar->getType())) {
684 MergeWithVar = FoundVar;
685 break;
686 }
687
Douglas Gregor2fbe5582010-02-10 17:16:49 +0000688 if (const IncompleteArrayType *FoundArray
689 = Importer.getToContext().getAsIncompleteArrayType(
690 FoundVar->getType())) {
691 if (const ConstantArrayType *TArray
692 = Importer.getToContext().getAsConstantArrayType(T)) {
693 if (Importer.getToContext().typesAreCompatible(
694 TArray->getElementType(),
695 FoundArray->getElementType())) {
696 FoundVar->setType(T);
697 MergeWithVar = FoundVar;
698 break;
699 }
700 }
701 } else if (const IncompleteArrayType *TArray
702 = Importer.getToContext().getAsIncompleteArrayType(T)) {
703 if (const ConstantArrayType *FoundArray
704 = Importer.getToContext().getAsConstantArrayType(
705 FoundVar->getType())) {
706 if (Importer.getToContext().typesAreCompatible(
707 TArray->getElementType(),
708 FoundArray->getElementType())) {
709 MergeWithVar = FoundVar;
710 break;
711 }
712 }
713 }
714
Douglas Gregor3aed6cd2010-02-08 21:09:39 +0000715 Importer.ToDiag(Loc, diag::err_odr_variable_type_inconsistent)
716 << Name << T << FoundVar->getType();
717 Importer.ToDiag(FoundVar->getLocation(), diag::note_odr_value_here)
718 << FoundVar->getType();
719 }
720 }
721
722 ConflictingDecls.push_back(*Lookup.first);
723 }
724
725 if (MergeWithVar) {
726 // An equivalent variable with external linkage has been found. Link
727 // the two declarations, then merge them.
728 Importer.getImportedDecls()[D] = MergeWithVar;
729
730 if (VarDecl *DDef = D->getDefinition()) {
731 if (VarDecl *ExistingDef = MergeWithVar->getDefinition()) {
732 Importer.ToDiag(ExistingDef->getLocation(),
733 diag::err_odr_variable_multiple_def)
734 << Name;
735 Importer.FromDiag(DDef->getLocation(), diag::note_odr_defined_here);
736 } else {
737 Expr *Init = Importer.Import(DDef->getInit());
738 MergeWithVar->setInit(Importer.getToContext(), Init);
739 }
740 }
741
742 return MergeWithVar;
743 }
744
745 if (!ConflictingDecls.empty()) {
746 Name = Importer.HandleNameConflict(Name, DC, IDNS,
747 ConflictingDecls.data(),
748 ConflictingDecls.size());
749 if (!Name)
750 return 0;
751 }
752 }
Douglas Gregorfa7a0e52010-02-10 17:47:19 +0000753
Douglas Gregor3aed6cd2010-02-08 21:09:39 +0000754 // Create the imported variable.
Douglas Gregorfa7a0e52010-02-10 17:47:19 +0000755 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
Douglas Gregor3aed6cd2010-02-08 21:09:39 +0000756 VarDecl *ToVar = VarDecl::Create(Importer.getToContext(), DC, Loc,
757 Name.getAsIdentifierInfo(), T, TInfo,
758 D->getStorageClass());
Douglas Gregor62d311f2010-02-09 19:21:46 +0000759 ToVar->setLexicalDeclContext(LexicalDC);
Douglas Gregor3aed6cd2010-02-08 21:09:39 +0000760 Importer.getImportedDecls()[D] = ToVar;
Douglas Gregor62d311f2010-02-09 19:21:46 +0000761 LexicalDC->addDecl(ToVar);
762
Douglas Gregor3aed6cd2010-02-08 21:09:39 +0000763 // Merge the initializer.
764 // FIXME: Can we really import any initializer? Alternatively, we could force
765 // ourselves to import every declaration of a variable and then only use
766 // getInit() here.
767 ToVar->setInit(Importer.getToContext(),
768 Importer.Import(const_cast<Expr *>(D->getAnyInitializer())));
769
770 // FIXME: Other bits to merge?
771
772 return ToVar;
773}
774
Douglas Gregorbb7930c2010-02-10 19:54:31 +0000775Decl *ASTNodeImporter::VisitParmVarDecl(ParmVarDecl *D) {
776 // Parameters are created in the translation unit's context, then moved
777 // into the function declaration's context afterward.
778 DeclContext *DC = Importer.getToContext().getTranslationUnitDecl();
779
Douglas Gregorfa7a0e52010-02-10 17:47:19 +0000780 // Import the name of this declaration.
781 DeclarationName Name = Importer.Import(D->getDeclName());
782 if (D->getDeclName() && !Name)
783 return 0;
784
Douglas Gregorbb7930c2010-02-10 19:54:31 +0000785 // Import the location of this declaration.
786 SourceLocation Loc = Importer.Import(D->getLocation());
787
788 // Import the parameter's type.
789 QualType T = Importer.Import(D->getType());
790 if (T.isNull())
791 return 0;
792
793 // Create the imported parameter.
794 TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
795 ParmVarDecl *ToParm = ParmVarDecl::Create(Importer.getToContext(), DC,
796 Loc, Name.getAsIdentifierInfo(),
797 T, TInfo, D->getStorageClass(),
798 /*FIXME: Default argument*/ 0);
799 Importer.getImportedDecls()[D] = ToParm;
800 return ToParm;
801}
802
Douglas Gregor811663e2010-02-10 00:15:17 +0000803ASTImporter::ASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
804 Diagnostic &ToDiags,
805 ASTContext &FromContext, FileManager &FromFileManager,
806 Diagnostic &FromDiags)
Douglas Gregor96e578d2010-02-05 17:54:41 +0000807 : ToContext(ToContext), FromContext(FromContext),
Douglas Gregor811663e2010-02-10 00:15:17 +0000808 ToFileManager(ToFileManager), FromFileManager(FromFileManager),
Douglas Gregor62d311f2010-02-09 19:21:46 +0000809 ToDiags(ToDiags), FromDiags(FromDiags) {
810 ImportedDecls[FromContext.getTranslationUnitDecl()]
811 = ToContext.getTranslationUnitDecl();
812}
813
814ASTImporter::~ASTImporter() { }
Douglas Gregor96e578d2010-02-05 17:54:41 +0000815
816QualType ASTImporter::Import(QualType FromT) {
817 if (FromT.isNull())
818 return QualType();
819
Douglas Gregorf65bbb32010-02-08 15:18:58 +0000820 // Check whether we've already imported this type.
821 llvm::DenseMap<Type *, Type *>::iterator Pos
822 = ImportedTypes.find(FromT.getTypePtr());
823 if (Pos != ImportedTypes.end())
824 return ToContext.getQualifiedType(Pos->second, FromT.getQualifiers());
Douglas Gregor96e578d2010-02-05 17:54:41 +0000825
Douglas Gregorf65bbb32010-02-08 15:18:58 +0000826 // Import the type
Douglas Gregor96e578d2010-02-05 17:54:41 +0000827 ASTNodeImporter Importer(*this);
828 QualType ToT = Importer.Visit(FromT.getTypePtr());
829 if (ToT.isNull())
830 return ToT;
831
Douglas Gregorf65bbb32010-02-08 15:18:58 +0000832 // Record the imported type.
833 ImportedTypes[FromT.getTypePtr()] = ToT.getTypePtr();
834
Douglas Gregor96e578d2010-02-05 17:54:41 +0000835 return ToContext.getQualifiedType(ToT, FromT.getQualifiers());
836}
837
Douglas Gregor62d311f2010-02-09 19:21:46 +0000838TypeSourceInfo *ASTImporter::Import(TypeSourceInfo *FromTSI) {
Douglas Gregorfa7a0e52010-02-10 17:47:19 +0000839 if (!FromTSI)
840 return FromTSI;
841
842 // FIXME: For now we just create a "trivial" type source info based
843 // on the type and a seingle location. Implement a real version of
844 // this.
845 QualType T = Import(FromTSI->getType());
846 if (T.isNull())
847 return 0;
848
849 return ToContext.getTrivialTypeSourceInfo(T,
850 FromTSI->getTypeLoc().getFullSourceRange().getBegin());
Douglas Gregor62d311f2010-02-09 19:21:46 +0000851}
852
853Decl *ASTImporter::Import(Decl *FromD) {
854 if (!FromD)
855 return 0;
856
857 // Check whether we've already imported this declaration.
858 llvm::DenseMap<Decl *, Decl *>::iterator Pos = ImportedDecls.find(FromD);
859 if (Pos != ImportedDecls.end())
860 return Pos->second;
861
862 // Import the type
863 ASTNodeImporter Importer(*this);
864 Decl *ToD = Importer.Visit(FromD);
865 if (!ToD)
866 return 0;
867
868 // Record the imported declaration.
869 ImportedDecls[FromD] = ToD;
870 return ToD;
871}
872
873DeclContext *ASTImporter::ImportContext(DeclContext *FromDC) {
874 if (!FromDC)
875 return FromDC;
876
877 return cast_or_null<DeclContext>(Import(cast<Decl>(FromDC)));
878}
879
880Expr *ASTImporter::Import(Expr *FromE) {
881 if (!FromE)
882 return 0;
883
884 return cast_or_null<Expr>(Import(cast<Stmt>(FromE)));
885}
886
887Stmt *ASTImporter::Import(Stmt *FromS) {
888 if (!FromS)
889 return 0;
890
891 // FIXME: Implement!
892 return 0;
893}
894
895NestedNameSpecifier *ASTImporter::Import(NestedNameSpecifier *FromNNS) {
896 if (!FromNNS)
897 return 0;
898
899 // FIXME: Implement!
900 return 0;
901}
902
903SourceLocation ASTImporter::Import(SourceLocation FromLoc) {
904 if (FromLoc.isInvalid())
905 return SourceLocation();
906
Douglas Gregor811663e2010-02-10 00:15:17 +0000907 SourceManager &FromSM = FromContext.getSourceManager();
908
909 // For now, map everything down to its spelling location, so that we
910 // don't have to import macro instantiations.
911 // FIXME: Import macro instantiations!
912 FromLoc = FromSM.getSpellingLoc(FromLoc);
913 std::pair<FileID, unsigned> Decomposed = FromSM.getDecomposedLoc(FromLoc);
914 SourceManager &ToSM = ToContext.getSourceManager();
915 return ToSM.getLocForStartOfFile(Import(Decomposed.first))
916 .getFileLocWithOffset(Decomposed.second);
Douglas Gregor62d311f2010-02-09 19:21:46 +0000917}
918
919SourceRange ASTImporter::Import(SourceRange FromRange) {
920 return SourceRange(Import(FromRange.getBegin()), Import(FromRange.getEnd()));
921}
922
Douglas Gregor811663e2010-02-10 00:15:17 +0000923FileID ASTImporter::Import(FileID FromID) {
924 llvm::DenseMap<unsigned, FileID>::iterator Pos
925 = ImportedFileIDs.find(FromID.getHashValue());
926 if (Pos != ImportedFileIDs.end())
927 return Pos->second;
928
929 SourceManager &FromSM = FromContext.getSourceManager();
930 SourceManager &ToSM = ToContext.getSourceManager();
931 const SrcMgr::SLocEntry &FromSLoc = FromSM.getSLocEntry(FromID);
932 assert(FromSLoc.isFile() && "Cannot handle macro instantiations yet");
933
934 // Include location of this file.
935 SourceLocation ToIncludeLoc = Import(FromSLoc.getFile().getIncludeLoc());
936
937 // Map the FileID for to the "to" source manager.
938 FileID ToID;
939 const SrcMgr::ContentCache *Cache = FromSLoc.getFile().getContentCache();
940 if (Cache->Entry) {
941 // FIXME: We probably want to use getVirtualFile(), so we don't hit the
942 // disk again
943 // FIXME: We definitely want to re-use the existing MemoryBuffer, rather
944 // than mmap the files several times.
945 const FileEntry *Entry = ToFileManager.getFile(Cache->Entry->getName());
946 ToID = ToSM.createFileID(Entry, ToIncludeLoc,
947 FromSLoc.getFile().getFileCharacteristic());
948 } else {
949 // FIXME: We want to re-use the existing MemoryBuffer!
950 const llvm::MemoryBuffer *FromBuf = Cache->getBuffer();
951 llvm::MemoryBuffer *ToBuf
952 = llvm::MemoryBuffer::getMemBufferCopy(FromBuf->getBufferStart(),
953 FromBuf->getBufferEnd(),
954 FromBuf->getBufferIdentifier());
955 ToID = ToSM.createFileIDForMemBuffer(ToBuf);
956 }
957
958
959 ImportedFileIDs[FromID.getHashValue()] = ToID;
960 return ToID;
961}
962
Douglas Gregor96e578d2010-02-05 17:54:41 +0000963DeclarationName ASTImporter::Import(DeclarationName FromName) {
964 if (!FromName)
965 return DeclarationName();
966
967 switch (FromName.getNameKind()) {
968 case DeclarationName::Identifier:
969 return Import(FromName.getAsIdentifierInfo());
970
971 case DeclarationName::ObjCZeroArgSelector:
972 case DeclarationName::ObjCOneArgSelector:
973 case DeclarationName::ObjCMultiArgSelector:
974 return Import(FromName.getObjCSelector());
975
976 case DeclarationName::CXXConstructorName: {
977 QualType T = Import(FromName.getCXXNameType());
978 if (T.isNull())
979 return DeclarationName();
980
981 return ToContext.DeclarationNames.getCXXConstructorName(
982 ToContext.getCanonicalType(T));
983 }
984
985 case DeclarationName::CXXDestructorName: {
986 QualType T = Import(FromName.getCXXNameType());
987 if (T.isNull())
988 return DeclarationName();
989
990 return ToContext.DeclarationNames.getCXXDestructorName(
991 ToContext.getCanonicalType(T));
992 }
993
994 case DeclarationName::CXXConversionFunctionName: {
995 QualType T = Import(FromName.getCXXNameType());
996 if (T.isNull())
997 return DeclarationName();
998
999 return ToContext.DeclarationNames.getCXXConversionFunctionName(
1000 ToContext.getCanonicalType(T));
1001 }
1002
1003 case DeclarationName::CXXOperatorName:
1004 return ToContext.DeclarationNames.getCXXOperatorName(
1005 FromName.getCXXOverloadedOperator());
1006
1007 case DeclarationName::CXXLiteralOperatorName:
1008 return ToContext.DeclarationNames.getCXXLiteralOperatorName(
1009 Import(FromName.getCXXLiteralIdentifier()));
1010
1011 case DeclarationName::CXXUsingDirective:
1012 // FIXME: STATICS!
1013 return DeclarationName::getUsingDirectiveName();
1014 }
1015
1016 // Silence bogus GCC warning
1017 return DeclarationName();
1018}
1019
1020IdentifierInfo *ASTImporter::Import(IdentifierInfo *FromId) {
1021 if (!FromId)
1022 return 0;
1023
1024 return &ToContext.Idents.get(FromId->getName());
1025}
Douglas Gregor3aed6cd2010-02-08 21:09:39 +00001026
1027DeclarationName ASTImporter::HandleNameConflict(DeclarationName Name,
1028 DeclContext *DC,
1029 unsigned IDNS,
1030 NamedDecl **Decls,
1031 unsigned NumDecls) {
1032 return Name;
1033}
1034
1035DiagnosticBuilder ASTImporter::ToDiag(SourceLocation Loc, unsigned DiagID) {
1036 return ToDiags.Report(FullSourceLoc(Loc, ToContext.getSourceManager()),
1037 DiagID);
1038}
1039
1040DiagnosticBuilder ASTImporter::FromDiag(SourceLocation Loc, unsigned DiagID) {
1041 return FromDiags.Report(FullSourceLoc(Loc, FromContext.getSourceManager()),
1042 DiagID);
1043}