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