1203955Srdivacky//===--- ASTImporter.cpp - Importing ASTs from other Contexts ---*- C++ -*-===//
2203955Srdivacky//
3203955Srdivacky//                     The LLVM Compiler Infrastructure
4203955Srdivacky//
5203955Srdivacky// This file is distributed under the University of Illinois Open Source
6203955Srdivacky// License. See LICENSE.TXT for details.
7203955Srdivacky//
8203955Srdivacky//===----------------------------------------------------------------------===//
9203955Srdivacky//
10203955Srdivacky//  This file defines the ASTImporter class which imports AST nodes from one
11203955Srdivacky//  context into another context.
12203955Srdivacky//
13203955Srdivacky//===----------------------------------------------------------------------===//
14203955Srdivacky#include "clang/AST/ASTImporter.h"
15203955Srdivacky#include "clang/AST/ASTContext.h"
16203955Srdivacky#include "clang/AST/ASTDiagnostic.h"
17203955Srdivacky#include "clang/AST/DeclCXX.h"
18203955Srdivacky#include "clang/AST/DeclObjC.h"
19203955Srdivacky#include "clang/AST/DeclVisitor.h"
20203955Srdivacky#include "clang/AST/StmtVisitor.h"
21203955Srdivacky#include "clang/AST/TypeVisitor.h"
22203955Srdivacky#include "clang/Basic/FileManager.h"
23203955Srdivacky#include "clang/Basic/SourceManager.h"
24203955Srdivacky#include "llvm/Support/MemoryBuffer.h"
25203955Srdivacky#include <deque>
26203955Srdivacky
27235633Sdimnamespace clang {
28203955Srdivacky  class ASTNodeImporter : public TypeVisitor<ASTNodeImporter, QualType>,
29203955Srdivacky                          public DeclVisitor<ASTNodeImporter, Decl *>,
30203955Srdivacky                          public StmtVisitor<ASTNodeImporter, Stmt *> {
31203955Srdivacky    ASTImporter &Importer;
32203955Srdivacky
33203955Srdivacky  public:
34203955Srdivacky    explicit ASTNodeImporter(ASTImporter &Importer) : Importer(Importer) { }
35203955Srdivacky
36203955Srdivacky    using TypeVisitor<ASTNodeImporter, QualType>::Visit;
37203955Srdivacky    using DeclVisitor<ASTNodeImporter, Decl *>::Visit;
38203955Srdivacky    using StmtVisitor<ASTNodeImporter, Stmt *>::Visit;
39203955Srdivacky
40203955Srdivacky    // Importing types
41218893Sdim    QualType VisitType(const Type *T);
42218893Sdim    QualType VisitBuiltinType(const BuiltinType *T);
43218893Sdim    QualType VisitComplexType(const ComplexType *T);
44218893Sdim    QualType VisitPointerType(const PointerType *T);
45218893Sdim    QualType VisitBlockPointerType(const BlockPointerType *T);
46218893Sdim    QualType VisitLValueReferenceType(const LValueReferenceType *T);
47218893Sdim    QualType VisitRValueReferenceType(const RValueReferenceType *T);
48218893Sdim    QualType VisitMemberPointerType(const MemberPointerType *T);
49218893Sdim    QualType VisitConstantArrayType(const ConstantArrayType *T);
50218893Sdim    QualType VisitIncompleteArrayType(const IncompleteArrayType *T);
51218893Sdim    QualType VisitVariableArrayType(const VariableArrayType *T);
52203955Srdivacky    // FIXME: DependentSizedArrayType
53203955Srdivacky    // FIXME: DependentSizedExtVectorType
54218893Sdim    QualType VisitVectorType(const VectorType *T);
55218893Sdim    QualType VisitExtVectorType(const ExtVectorType *T);
56218893Sdim    QualType VisitFunctionNoProtoType(const FunctionNoProtoType *T);
57218893Sdim    QualType VisitFunctionProtoType(const FunctionProtoType *T);
58203955Srdivacky    // FIXME: UnresolvedUsingType
59226890Sdim    QualType VisitParenType(const ParenType *T);
60218893Sdim    QualType VisitTypedefType(const TypedefType *T);
61218893Sdim    QualType VisitTypeOfExprType(const TypeOfExprType *T);
62203955Srdivacky    // FIXME: DependentTypeOfExprType
63218893Sdim    QualType VisitTypeOfType(const TypeOfType *T);
64218893Sdim    QualType VisitDecltypeType(const DecltypeType *T);
65223017Sdim    QualType VisitUnaryTransformType(const UnaryTransformType *T);
66218893Sdim    QualType VisitAutoType(const AutoType *T);
67203955Srdivacky    // FIXME: DependentDecltypeType
68218893Sdim    QualType VisitRecordType(const RecordType *T);
69218893Sdim    QualType VisitEnumType(const EnumType *T);
70203955Srdivacky    // FIXME: TemplateTypeParmType
71203955Srdivacky    // FIXME: SubstTemplateTypeParmType
72218893Sdim    QualType VisitTemplateSpecializationType(const TemplateSpecializationType *T);
73218893Sdim    QualType VisitElaboratedType(const ElaboratedType *T);
74206084Srdivacky    // FIXME: DependentNameType
75210299Sed    // FIXME: DependentTemplateSpecializationType
76218893Sdim    QualType VisitObjCInterfaceType(const ObjCInterfaceType *T);
77218893Sdim    QualType VisitObjCObjectType(const ObjCObjectType *T);
78218893Sdim    QualType VisitObjCObjectPointerType(const ObjCObjectPointerType *T);
79203955Srdivacky
80235633Sdim    // Importing declarations
81203955Srdivacky    bool ImportDeclParts(NamedDecl *D, DeclContext *&DC,
82203955Srdivacky                         DeclContext *&LexicalDC, DeclarationName &Name,
83204643Srdivacky                         SourceLocation &Loc);
84226890Sdim    void ImportDefinitionIfNeeded(Decl *FromD, Decl *ToD = 0);
85212904Sdim    void ImportDeclarationNameLoc(const DeclarationNameInfo &From,
86212904Sdim                                  DeclarationNameInfo& To);
87218893Sdim    void ImportDeclContext(DeclContext *FromDC, bool ForceImport = false);
88235633Sdim
89235633Sdim    /// \brief What we should import from the definition.
90235633Sdim    enum ImportDefinitionKind {
91235633Sdim      /// \brief Import the default subset of the definition, which might be
92235633Sdim      /// nothing (if minimal import is set) or might be everything (if minimal
93235633Sdim      /// import is not set).
94235633Sdim      IDK_Default,
95235633Sdim      /// \brief Import everything.
96235633Sdim      IDK_Everything,
97235633Sdim      /// \brief Import only the bare bones needed to establish a valid
98235633Sdim      /// DeclContext.
99235633Sdim      IDK_Basic
100235633Sdim    };
101235633Sdim
102235633Sdim    bool shouldForceImportDeclContext(ImportDefinitionKind IDK) {
103235633Sdim      return IDK == IDK_Everything ||
104235633Sdim             (IDK == IDK_Default && !Importer.isMinimalImport());
105235633Sdim    }
106235633Sdim
107226890Sdim    bool ImportDefinition(RecordDecl *From, RecordDecl *To,
108235633Sdim                          ImportDefinitionKind Kind = IDK_Default);
109263509Sdim    bool ImportDefinition(VarDecl *From, VarDecl *To,
110263509Sdim                          ImportDefinitionKind Kind = IDK_Default);
111226890Sdim    bool ImportDefinition(EnumDecl *From, EnumDecl *To,
112235633Sdim                          ImportDefinitionKind Kind = IDK_Default);
113235633Sdim    bool ImportDefinition(ObjCInterfaceDecl *From, ObjCInterfaceDecl *To,
114235633Sdim                          ImportDefinitionKind Kind = IDK_Default);
115235633Sdim    bool ImportDefinition(ObjCProtocolDecl *From, ObjCProtocolDecl *To,
116235633Sdim                          ImportDefinitionKind Kind = IDK_Default);
117218893Sdim    TemplateParameterList *ImportTemplateParameterList(
118218893Sdim                                                 TemplateParameterList *Params);
119218893Sdim    TemplateArgument ImportTemplateArgument(const TemplateArgument &From);
120218893Sdim    bool ImportTemplateArguments(const TemplateArgument *FromArgs,
121218893Sdim                                 unsigned NumFromArgs,
122226890Sdim                               SmallVectorImpl<TemplateArgument> &ToArgs);
123245431Sdim    bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord,
124245431Sdim                           bool Complain = true);
125263509Sdim    bool IsStructuralMatch(VarDecl *FromVar, VarDecl *ToVar,
126263509Sdim                           bool Complain = true);
127203955Srdivacky    bool IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToRecord);
128252723Sdim    bool IsStructuralMatch(EnumConstantDecl *FromEC, EnumConstantDecl *ToEC);
129218893Sdim    bool IsStructuralMatch(ClassTemplateDecl *From, ClassTemplateDecl *To);
130263509Sdim    bool IsStructuralMatch(VarTemplateDecl *From, VarTemplateDecl *To);
131203955Srdivacky    Decl *VisitDecl(Decl *D);
132235633Sdim    Decl *VisitTranslationUnitDecl(TranslationUnitDecl *D);
133204643Srdivacky    Decl *VisitNamespaceDecl(NamespaceDecl *D);
134221345Sdim    Decl *VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias);
135203955Srdivacky    Decl *VisitTypedefDecl(TypedefDecl *D);
136221345Sdim    Decl *VisitTypeAliasDecl(TypeAliasDecl *D);
137203955Srdivacky    Decl *VisitEnumDecl(EnumDecl *D);
138203955Srdivacky    Decl *VisitRecordDecl(RecordDecl *D);
139203955Srdivacky    Decl *VisitEnumConstantDecl(EnumConstantDecl *D);
140203955Srdivacky    Decl *VisitFunctionDecl(FunctionDecl *D);
141204643Srdivacky    Decl *VisitCXXMethodDecl(CXXMethodDecl *D);
142204643Srdivacky    Decl *VisitCXXConstructorDecl(CXXConstructorDecl *D);
143204643Srdivacky    Decl *VisitCXXDestructorDecl(CXXDestructorDecl *D);
144204643Srdivacky    Decl *VisitCXXConversionDecl(CXXConversionDecl *D);
145203955Srdivacky    Decl *VisitFieldDecl(FieldDecl *D);
146218893Sdim    Decl *VisitIndirectFieldDecl(IndirectFieldDecl *D);
147204643Srdivacky    Decl *VisitObjCIvarDecl(ObjCIvarDecl *D);
148203955Srdivacky    Decl *VisitVarDecl(VarDecl *D);
149204643Srdivacky    Decl *VisitImplicitParamDecl(ImplicitParamDecl *D);
150203955Srdivacky    Decl *VisitParmVarDecl(ParmVarDecl *D);
151204643Srdivacky    Decl *VisitObjCMethodDecl(ObjCMethodDecl *D);
152204643Srdivacky    Decl *VisitObjCCategoryDecl(ObjCCategoryDecl *D);
153204643Srdivacky    Decl *VisitObjCProtocolDecl(ObjCProtocolDecl *D);
154203955Srdivacky    Decl *VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
155218893Sdim    Decl *VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
156218893Sdim    Decl *VisitObjCImplementationDecl(ObjCImplementationDecl *D);
157204643Srdivacky    Decl *VisitObjCPropertyDecl(ObjCPropertyDecl *D);
158218893Sdim    Decl *VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
159218893Sdim    Decl *VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
160218893Sdim    Decl *VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
161218893Sdim    Decl *VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
162218893Sdim    Decl *VisitClassTemplateDecl(ClassTemplateDecl *D);
163218893Sdim    Decl *VisitClassTemplateSpecializationDecl(
164218893Sdim                                            ClassTemplateSpecializationDecl *D);
165263509Sdim    Decl *VisitVarTemplateDecl(VarTemplateDecl *D);
166263509Sdim    Decl *VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *D);
167263509Sdim
168203955Srdivacky    // Importing statements
169203955Srdivacky    Stmt *VisitStmt(Stmt *S);
170203955Srdivacky
171203955Srdivacky    // Importing expressions
172203955Srdivacky    Expr *VisitExpr(Expr *E);
173204643Srdivacky    Expr *VisitDeclRefExpr(DeclRefExpr *E);
174203955Srdivacky    Expr *VisitIntegerLiteral(IntegerLiteral *E);
175204643Srdivacky    Expr *VisitCharacterLiteral(CharacterLiteral *E);
176204643Srdivacky    Expr *VisitParenExpr(ParenExpr *E);
177204643Srdivacky    Expr *VisitUnaryOperator(UnaryOperator *E);
178221345Sdim    Expr *VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E);
179204643Srdivacky    Expr *VisitBinaryOperator(BinaryOperator *E);
180204643Srdivacky    Expr *VisitCompoundAssignOperator(CompoundAssignOperator *E);
181203955Srdivacky    Expr *VisitImplicitCastExpr(ImplicitCastExpr *E);
182204643Srdivacky    Expr *VisitCStyleCastExpr(CStyleCastExpr *E);
183203955Srdivacky  };
184203955Srdivacky}
185235633Sdimusing namespace clang;
186203955Srdivacky
187203955Srdivacky//----------------------------------------------------------------------------
188203955Srdivacky// Structural Equivalence
189203955Srdivacky//----------------------------------------------------------------------------
190203955Srdivacky
191203955Srdivackynamespace {
192203955Srdivacky  struct StructuralEquivalenceContext {
193203955Srdivacky    /// \brief AST contexts for which we are checking structural equivalence.
194203955Srdivacky    ASTContext &C1, &C2;
195203955Srdivacky
196203955Srdivacky    /// \brief The set of "tentative" equivalences between two canonical
197203955Srdivacky    /// declarations, mapping from a declaration in the first context to the
198203955Srdivacky    /// declaration in the second context that we believe to be equivalent.
199203955Srdivacky    llvm::DenseMap<Decl *, Decl *> TentativeEquivalences;
200203955Srdivacky
201203955Srdivacky    /// \brief Queue of declarations in the first context whose equivalence
202203955Srdivacky    /// with a declaration in the second context still needs to be verified.
203203955Srdivacky    std::deque<Decl *> DeclsToCheck;
204203955Srdivacky
205203955Srdivacky    /// \brief Declaration (from, to) pairs that are known not to be equivalent
206203955Srdivacky    /// (which we have already complained about).
207203955Srdivacky    llvm::DenseSet<std::pair<Decl *, Decl *> > &NonEquivalentDecls;
208203955Srdivacky
209203955Srdivacky    /// \brief Whether we're being strict about the spelling of types when
210203955Srdivacky    /// unifying two types.
211203955Srdivacky    bool StrictTypeSpelling;
212245431Sdim
213245431Sdim    /// \brief Whether to complain about failures.
214245431Sdim    bool Complain;
215245431Sdim
216252723Sdim    /// \brief \c true if the last diagnostic came from C2.
217252723Sdim    bool LastDiagFromC2;
218252723Sdim
219203955Srdivacky    StructuralEquivalenceContext(ASTContext &C1, ASTContext &C2,
220203955Srdivacky               llvm::DenseSet<std::pair<Decl *, Decl *> > &NonEquivalentDecls,
221245431Sdim                                 bool StrictTypeSpelling = false,
222245431Sdim                                 bool Complain = true)
223218893Sdim      : C1(C1), C2(C2), NonEquivalentDecls(NonEquivalentDecls),
224252723Sdim        StrictTypeSpelling(StrictTypeSpelling), Complain(Complain),
225252723Sdim        LastDiagFromC2(false) {}
226203955Srdivacky
227203955Srdivacky    /// \brief Determine whether the two declarations are structurally
228203955Srdivacky    /// equivalent.
229203955Srdivacky    bool IsStructurallyEquivalent(Decl *D1, Decl *D2);
230203955Srdivacky
231203955Srdivacky    /// \brief Determine whether the two types are structurally equivalent.
232203955Srdivacky    bool IsStructurallyEquivalent(QualType T1, QualType T2);
233203955Srdivacky
234203955Srdivacky  private:
235203955Srdivacky    /// \brief Finish checking all of the structural equivalences.
236203955Srdivacky    ///
237203955Srdivacky    /// \returns true if an error occurred, false otherwise.
238203955Srdivacky    bool Finish();
239203955Srdivacky
240203955Srdivacky  public:
241203955Srdivacky    DiagnosticBuilder Diag1(SourceLocation Loc, unsigned DiagID) {
242245431Sdim      assert(Complain && "Not allowed to complain");
243252723Sdim      if (LastDiagFromC2)
244252723Sdim        C1.getDiagnostics().notePriorDiagnosticFrom(C2.getDiagnostics());
245252723Sdim      LastDiagFromC2 = false;
246218893Sdim      return C1.getDiagnostics().Report(Loc, DiagID);
247203955Srdivacky    }
248203955Srdivacky
249203955Srdivacky    DiagnosticBuilder Diag2(SourceLocation Loc, unsigned DiagID) {
250245431Sdim      assert(Complain && "Not allowed to complain");
251252723Sdim      if (!LastDiagFromC2)
252252723Sdim        C2.getDiagnostics().notePriorDiagnosticFrom(C1.getDiagnostics());
253252723Sdim      LastDiagFromC2 = true;
254218893Sdim      return C2.getDiagnostics().Report(Loc, DiagID);
255203955Srdivacky    }
256203955Srdivacky  };
257203955Srdivacky}
258203955Srdivacky
259203955Srdivackystatic bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
260203955Srdivacky                                     QualType T1, QualType T2);
261203955Srdivackystatic bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
262203955Srdivacky                                     Decl *D1, Decl *D2);
263203955Srdivacky
264203955Srdivacky/// \brief Determine structural equivalence of two expressions.
265203955Srdivackystatic bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
266203955Srdivacky                                     Expr *E1, Expr *E2) {
267203955Srdivacky  if (!E1 || !E2)
268203955Srdivacky    return E1 == E2;
269203955Srdivacky
270203955Srdivacky  // FIXME: Actually perform a structural comparison!
271203955Srdivacky  return true;
272203955Srdivacky}
273203955Srdivacky
274203955Srdivacky/// \brief Determine whether two identifiers are equivalent.
275203955Srdivackystatic bool IsStructurallyEquivalent(const IdentifierInfo *Name1,
276203955Srdivacky                                     const IdentifierInfo *Name2) {
277203955Srdivacky  if (!Name1 || !Name2)
278203955Srdivacky    return Name1 == Name2;
279203955Srdivacky
280203955Srdivacky  return Name1->getName() == Name2->getName();
281203955Srdivacky}
282203955Srdivacky
283203955Srdivacky/// \brief Determine whether two nested-name-specifiers are equivalent.
284203955Srdivackystatic bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
285203955Srdivacky                                     NestedNameSpecifier *NNS1,
286203955Srdivacky                                     NestedNameSpecifier *NNS2) {
287203955Srdivacky  // FIXME: Implement!
288203955Srdivacky  return true;
289203955Srdivacky}
290203955Srdivacky
291203955Srdivacky/// \brief Determine whether two template arguments are equivalent.
292203955Srdivackystatic bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
293203955Srdivacky                                     const TemplateArgument &Arg1,
294203955Srdivacky                                     const TemplateArgument &Arg2) {
295218893Sdim  if (Arg1.getKind() != Arg2.getKind())
296218893Sdim    return false;
297218893Sdim
298218893Sdim  switch (Arg1.getKind()) {
299218893Sdim  case TemplateArgument::Null:
300218893Sdim    return true;
301218893Sdim
302218893Sdim  case TemplateArgument::Type:
303218893Sdim    return Context.IsStructurallyEquivalent(Arg1.getAsType(), Arg2.getAsType());
304245431Sdim
305218893Sdim  case TemplateArgument::Integral:
306218893Sdim    if (!Context.IsStructurallyEquivalent(Arg1.getIntegralType(),
307218893Sdim                                          Arg2.getIntegralType()))
308218893Sdim      return false;
309218893Sdim
310245431Sdim    return llvm::APSInt::isSameValue(Arg1.getAsIntegral(), Arg2.getAsIntegral());
311218893Sdim
312218893Sdim  case TemplateArgument::Declaration:
313218893Sdim    return Context.IsStructurallyEquivalent(Arg1.getAsDecl(), Arg2.getAsDecl());
314245431Sdim
315245431Sdim  case TemplateArgument::NullPtr:
316245431Sdim    return true; // FIXME: Is this correct?
317245431Sdim
318218893Sdim  case TemplateArgument::Template:
319218893Sdim    return IsStructurallyEquivalent(Context,
320218893Sdim                                    Arg1.getAsTemplate(),
321218893Sdim                                    Arg2.getAsTemplate());
322218893Sdim
323218893Sdim  case TemplateArgument::TemplateExpansion:
324218893Sdim    return IsStructurallyEquivalent(Context,
325218893Sdim                                    Arg1.getAsTemplateOrTemplatePattern(),
326218893Sdim                                    Arg2.getAsTemplateOrTemplatePattern());
327218893Sdim
328218893Sdim  case TemplateArgument::Expression:
329218893Sdim    return IsStructurallyEquivalent(Context,
330218893Sdim                                    Arg1.getAsExpr(), Arg2.getAsExpr());
331218893Sdim
332218893Sdim  case TemplateArgument::Pack:
333218893Sdim    if (Arg1.pack_size() != Arg2.pack_size())
334218893Sdim      return false;
335218893Sdim
336218893Sdim    for (unsigned I = 0, N = Arg1.pack_size(); I != N; ++I)
337218893Sdim      if (!IsStructurallyEquivalent(Context,
338218893Sdim                                    Arg1.pack_begin()[I],
339218893Sdim                                    Arg2.pack_begin()[I]))
340218893Sdim        return false;
341218893Sdim
342218893Sdim    return true;
343218893Sdim  }
344218893Sdim
345218893Sdim  llvm_unreachable("Invalid template argument kind");
346203955Srdivacky}
347203955Srdivacky
348203955Srdivacky/// \brief Determine structural equivalence for the common part of array
349203955Srdivacky/// types.
350203955Srdivackystatic bool IsArrayStructurallyEquivalent(StructuralEquivalenceContext &Context,
351203955Srdivacky                                          const ArrayType *Array1,
352203955Srdivacky                                          const ArrayType *Array2) {
353203955Srdivacky  if (!IsStructurallyEquivalent(Context,
354203955Srdivacky                                Array1->getElementType(),
355203955Srdivacky                                Array2->getElementType()))
356203955Srdivacky    return false;
357203955Srdivacky  if (Array1->getSizeModifier() != Array2->getSizeModifier())
358203955Srdivacky    return false;
359203955Srdivacky  if (Array1->getIndexTypeQualifiers() != Array2->getIndexTypeQualifiers())
360203955Srdivacky    return false;
361203955Srdivacky
362203955Srdivacky  return true;
363203955Srdivacky}
364203955Srdivacky
365203955Srdivacky/// \brief Determine structural equivalence of two types.
366203955Srdivackystatic bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
367203955Srdivacky                                     QualType T1, QualType T2) {
368203955Srdivacky  if (T1.isNull() || T2.isNull())
369203955Srdivacky    return T1.isNull() && T2.isNull();
370203955Srdivacky
371203955Srdivacky  if (!Context.StrictTypeSpelling) {
372203955Srdivacky    // We aren't being strict about token-to-token equivalence of types,
373203955Srdivacky    // so map down to the canonical type.
374203955Srdivacky    T1 = Context.C1.getCanonicalType(T1);
375203955Srdivacky    T2 = Context.C2.getCanonicalType(T2);
376203955Srdivacky  }
377203955Srdivacky
378203955Srdivacky  if (T1.getQualifiers() != T2.getQualifiers())
379203955Srdivacky    return false;
380203955Srdivacky
381203955Srdivacky  Type::TypeClass TC = T1->getTypeClass();
382203955Srdivacky
383203955Srdivacky  if (T1->getTypeClass() != T2->getTypeClass()) {
384203955Srdivacky    // Compare function types with prototypes vs. without prototypes as if
385203955Srdivacky    // both did not have prototypes.
386203955Srdivacky    if (T1->getTypeClass() == Type::FunctionProto &&
387203955Srdivacky        T2->getTypeClass() == Type::FunctionNoProto)
388203955Srdivacky      TC = Type::FunctionNoProto;
389203955Srdivacky    else if (T1->getTypeClass() == Type::FunctionNoProto &&
390203955Srdivacky             T2->getTypeClass() == Type::FunctionProto)
391203955Srdivacky      TC = Type::FunctionNoProto;
392203955Srdivacky    else
393203955Srdivacky      return false;
394203955Srdivacky  }
395203955Srdivacky
396203955Srdivacky  switch (TC) {
397203955Srdivacky  case Type::Builtin:
398203955Srdivacky    // FIXME: Deal with Char_S/Char_U.
399203955Srdivacky    if (cast<BuiltinType>(T1)->getKind() != cast<BuiltinType>(T2)->getKind())
400203955Srdivacky      return false;
401203955Srdivacky    break;
402203955Srdivacky
403203955Srdivacky  case Type::Complex:
404203955Srdivacky    if (!IsStructurallyEquivalent(Context,
405203955Srdivacky                                  cast<ComplexType>(T1)->getElementType(),
406203955Srdivacky                                  cast<ComplexType>(T2)->getElementType()))
407203955Srdivacky      return false;
408203955Srdivacky    break;
409203955Srdivacky
410263509Sdim  case Type::Decayed:
411263509Sdim    if (!IsStructurallyEquivalent(Context,
412263509Sdim                                  cast<DecayedType>(T1)->getPointeeType(),
413263509Sdim                                  cast<DecayedType>(T2)->getPointeeType()))
414263509Sdim      return false;
415263509Sdim    break;
416263509Sdim
417203955Srdivacky  case Type::Pointer:
418203955Srdivacky    if (!IsStructurallyEquivalent(Context,
419203955Srdivacky                                  cast<PointerType>(T1)->getPointeeType(),
420203955Srdivacky                                  cast<PointerType>(T2)->getPointeeType()))
421203955Srdivacky      return false;
422203955Srdivacky    break;
423203955Srdivacky
424203955Srdivacky  case Type::BlockPointer:
425203955Srdivacky    if (!IsStructurallyEquivalent(Context,
426203955Srdivacky                                  cast<BlockPointerType>(T1)->getPointeeType(),
427203955Srdivacky                                  cast<BlockPointerType>(T2)->getPointeeType()))
428203955Srdivacky      return false;
429203955Srdivacky    break;
430203955Srdivacky
431203955Srdivacky  case Type::LValueReference:
432203955Srdivacky  case Type::RValueReference: {
433203955Srdivacky    const ReferenceType *Ref1 = cast<ReferenceType>(T1);
434203955Srdivacky    const ReferenceType *Ref2 = cast<ReferenceType>(T2);
435203955Srdivacky    if (Ref1->isSpelledAsLValue() != Ref2->isSpelledAsLValue())
436203955Srdivacky      return false;
437203955Srdivacky    if (Ref1->isInnerRef() != Ref2->isInnerRef())
438203955Srdivacky      return false;
439203955Srdivacky    if (!IsStructurallyEquivalent(Context,
440203955Srdivacky                                  Ref1->getPointeeTypeAsWritten(),
441203955Srdivacky                                  Ref2->getPointeeTypeAsWritten()))
442203955Srdivacky      return false;
443203955Srdivacky    break;
444203955Srdivacky  }
445203955Srdivacky
446203955Srdivacky  case Type::MemberPointer: {
447203955Srdivacky    const MemberPointerType *MemPtr1 = cast<MemberPointerType>(T1);
448203955Srdivacky    const MemberPointerType *MemPtr2 = cast<MemberPointerType>(T2);
449203955Srdivacky    if (!IsStructurallyEquivalent(Context,
450203955Srdivacky                                  MemPtr1->getPointeeType(),
451203955Srdivacky                                  MemPtr2->getPointeeType()))
452203955Srdivacky      return false;
453203955Srdivacky    if (!IsStructurallyEquivalent(Context,
454203955Srdivacky                                  QualType(MemPtr1->getClass(), 0),
455203955Srdivacky                                  QualType(MemPtr2->getClass(), 0)))
456203955Srdivacky      return false;
457203955Srdivacky    break;
458203955Srdivacky  }
459203955Srdivacky
460203955Srdivacky  case Type::ConstantArray: {
461203955Srdivacky    const ConstantArrayType *Array1 = cast<ConstantArrayType>(T1);
462203955Srdivacky    const ConstantArrayType *Array2 = cast<ConstantArrayType>(T2);
463245431Sdim    if (!llvm::APInt::isSameValue(Array1->getSize(), Array2->getSize()))
464203955Srdivacky      return false;
465203955Srdivacky
466203955Srdivacky    if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
467203955Srdivacky      return false;
468203955Srdivacky    break;
469203955Srdivacky  }
470203955Srdivacky
471203955Srdivacky  case Type::IncompleteArray:
472203955Srdivacky    if (!IsArrayStructurallyEquivalent(Context,
473203955Srdivacky                                       cast<ArrayType>(T1),
474203955Srdivacky                                       cast<ArrayType>(T2)))
475203955Srdivacky      return false;
476203955Srdivacky    break;
477203955Srdivacky
478203955Srdivacky  case Type::VariableArray: {
479203955Srdivacky    const VariableArrayType *Array1 = cast<VariableArrayType>(T1);
480203955Srdivacky    const VariableArrayType *Array2 = cast<VariableArrayType>(T2);
481203955Srdivacky    if (!IsStructurallyEquivalent(Context,
482203955Srdivacky                                  Array1->getSizeExpr(), Array2->getSizeExpr()))
483203955Srdivacky      return false;
484203955Srdivacky
485203955Srdivacky    if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
486203955Srdivacky      return false;
487203955Srdivacky
488203955Srdivacky    break;
489203955Srdivacky  }
490203955Srdivacky
491203955Srdivacky  case Type::DependentSizedArray: {
492203955Srdivacky    const DependentSizedArrayType *Array1 = cast<DependentSizedArrayType>(T1);
493203955Srdivacky    const DependentSizedArrayType *Array2 = cast<DependentSizedArrayType>(T2);
494203955Srdivacky    if (!IsStructurallyEquivalent(Context,
495203955Srdivacky                                  Array1->getSizeExpr(), Array2->getSizeExpr()))
496203955Srdivacky      return false;
497203955Srdivacky
498203955Srdivacky    if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
499203955Srdivacky      return false;
500203955Srdivacky
501203955Srdivacky    break;
502203955Srdivacky  }
503203955Srdivacky
504203955Srdivacky  case Type::DependentSizedExtVector: {
505203955Srdivacky    const DependentSizedExtVectorType *Vec1
506203955Srdivacky      = cast<DependentSizedExtVectorType>(T1);
507203955Srdivacky    const DependentSizedExtVectorType *Vec2
508203955Srdivacky      = cast<DependentSizedExtVectorType>(T2);
509203955Srdivacky    if (!IsStructurallyEquivalent(Context,
510203955Srdivacky                                  Vec1->getSizeExpr(), Vec2->getSizeExpr()))
511203955Srdivacky      return false;
512203955Srdivacky    if (!IsStructurallyEquivalent(Context,
513203955Srdivacky                                  Vec1->getElementType(),
514203955Srdivacky                                  Vec2->getElementType()))
515203955Srdivacky      return false;
516203955Srdivacky    break;
517203955Srdivacky  }
518203955Srdivacky
519203955Srdivacky  case Type::Vector:
520203955Srdivacky  case Type::ExtVector: {
521203955Srdivacky    const VectorType *Vec1 = cast<VectorType>(T1);
522203955Srdivacky    const VectorType *Vec2 = cast<VectorType>(T2);
523203955Srdivacky    if (!IsStructurallyEquivalent(Context,
524203955Srdivacky                                  Vec1->getElementType(),
525203955Srdivacky                                  Vec2->getElementType()))
526203955Srdivacky      return false;
527203955Srdivacky    if (Vec1->getNumElements() != Vec2->getNumElements())
528203955Srdivacky      return false;
529218893Sdim    if (Vec1->getVectorKind() != Vec2->getVectorKind())
530203955Srdivacky      return false;
531204643Srdivacky    break;
532203955Srdivacky  }
533203955Srdivacky
534203955Srdivacky  case Type::FunctionProto: {
535203955Srdivacky    const FunctionProtoType *Proto1 = cast<FunctionProtoType>(T1);
536203955Srdivacky    const FunctionProtoType *Proto2 = cast<FunctionProtoType>(T2);
537203955Srdivacky    if (Proto1->getNumArgs() != Proto2->getNumArgs())
538203955Srdivacky      return false;
539203955Srdivacky    for (unsigned I = 0, N = Proto1->getNumArgs(); I != N; ++I) {
540203955Srdivacky      if (!IsStructurallyEquivalent(Context,
541203955Srdivacky                                    Proto1->getArgType(I),
542203955Srdivacky                                    Proto2->getArgType(I)))
543203955Srdivacky        return false;
544203955Srdivacky    }
545203955Srdivacky    if (Proto1->isVariadic() != Proto2->isVariadic())
546203955Srdivacky      return false;
547221345Sdim    if (Proto1->getExceptionSpecType() != Proto2->getExceptionSpecType())
548203955Srdivacky      return false;
549221345Sdim    if (Proto1->getExceptionSpecType() == EST_Dynamic) {
550221345Sdim      if (Proto1->getNumExceptions() != Proto2->getNumExceptions())
551221345Sdim        return false;
552221345Sdim      for (unsigned I = 0, N = Proto1->getNumExceptions(); I != N; ++I) {
553221345Sdim        if (!IsStructurallyEquivalent(Context,
554221345Sdim                                      Proto1->getExceptionType(I),
555221345Sdim                                      Proto2->getExceptionType(I)))
556221345Sdim          return false;
557221345Sdim      }
558221345Sdim    } else if (Proto1->getExceptionSpecType() == EST_ComputedNoexcept) {
559203955Srdivacky      if (!IsStructurallyEquivalent(Context,
560221345Sdim                                    Proto1->getNoexceptExpr(),
561221345Sdim                                    Proto2->getNoexceptExpr()))
562203955Srdivacky        return false;
563203955Srdivacky    }
564203955Srdivacky    if (Proto1->getTypeQuals() != Proto2->getTypeQuals())
565203955Srdivacky      return false;
566203955Srdivacky
567203955Srdivacky    // Fall through to check the bits common with FunctionNoProtoType.
568203955Srdivacky  }
569203955Srdivacky
570203955Srdivacky  case Type::FunctionNoProto: {
571203955Srdivacky    const FunctionType *Function1 = cast<FunctionType>(T1);
572203955Srdivacky    const FunctionType *Function2 = cast<FunctionType>(T2);
573203955Srdivacky    if (!IsStructurallyEquivalent(Context,
574203955Srdivacky                                  Function1->getResultType(),
575203955Srdivacky                                  Function2->getResultType()))
576203955Srdivacky      return false;
577206084Srdivacky      if (Function1->getExtInfo() != Function2->getExtInfo())
578206084Srdivacky        return false;
579203955Srdivacky    break;
580203955Srdivacky  }
581203955Srdivacky
582203955Srdivacky  case Type::UnresolvedUsing:
583203955Srdivacky    if (!IsStructurallyEquivalent(Context,
584203955Srdivacky                                  cast<UnresolvedUsingType>(T1)->getDecl(),
585203955Srdivacky                                  cast<UnresolvedUsingType>(T2)->getDecl()))
586203955Srdivacky      return false;
587203955Srdivacky
588203955Srdivacky    break;
589218893Sdim
590218893Sdim  case Type::Attributed:
591218893Sdim    if (!IsStructurallyEquivalent(Context,
592218893Sdim                                  cast<AttributedType>(T1)->getModifiedType(),
593218893Sdim                                  cast<AttributedType>(T2)->getModifiedType()))
594218893Sdim      return false;
595218893Sdim    if (!IsStructurallyEquivalent(Context,
596218893Sdim                                cast<AttributedType>(T1)->getEquivalentType(),
597218893Sdim                                cast<AttributedType>(T2)->getEquivalentType()))
598218893Sdim      return false;
599218893Sdim    break;
600203955Srdivacky
601218893Sdim  case Type::Paren:
602218893Sdim    if (!IsStructurallyEquivalent(Context,
603218893Sdim                                  cast<ParenType>(T1)->getInnerType(),
604218893Sdim                                  cast<ParenType>(T2)->getInnerType()))
605218893Sdim      return false;
606218893Sdim    break;
607218893Sdim
608203955Srdivacky  case Type::Typedef:
609203955Srdivacky    if (!IsStructurallyEquivalent(Context,
610203955Srdivacky                                  cast<TypedefType>(T1)->getDecl(),
611203955Srdivacky                                  cast<TypedefType>(T2)->getDecl()))
612203955Srdivacky      return false;
613203955Srdivacky    break;
614203955Srdivacky
615203955Srdivacky  case Type::TypeOfExpr:
616203955Srdivacky    if (!IsStructurallyEquivalent(Context,
617203955Srdivacky                                cast<TypeOfExprType>(T1)->getUnderlyingExpr(),
618203955Srdivacky                                cast<TypeOfExprType>(T2)->getUnderlyingExpr()))
619203955Srdivacky      return false;
620203955Srdivacky    break;
621203955Srdivacky
622203955Srdivacky  case Type::TypeOf:
623203955Srdivacky    if (!IsStructurallyEquivalent(Context,
624203955Srdivacky                                  cast<TypeOfType>(T1)->getUnderlyingType(),
625203955Srdivacky                                  cast<TypeOfType>(T2)->getUnderlyingType()))
626203955Srdivacky      return false;
627203955Srdivacky    break;
628223017Sdim
629223017Sdim  case Type::UnaryTransform:
630223017Sdim    if (!IsStructurallyEquivalent(Context,
631223017Sdim                             cast<UnaryTransformType>(T1)->getUnderlyingType(),
632223017Sdim                             cast<UnaryTransformType>(T1)->getUnderlyingType()))
633223017Sdim      return false;
634223017Sdim    break;
635223017Sdim
636203955Srdivacky  case Type::Decltype:
637203955Srdivacky    if (!IsStructurallyEquivalent(Context,
638203955Srdivacky                                  cast<DecltypeType>(T1)->getUnderlyingExpr(),
639203955Srdivacky                                  cast<DecltypeType>(T2)->getUnderlyingExpr()))
640203955Srdivacky      return false;
641203955Srdivacky    break;
642203955Srdivacky
643218893Sdim  case Type::Auto:
644218893Sdim    if (!IsStructurallyEquivalent(Context,
645218893Sdim                                  cast<AutoType>(T1)->getDeducedType(),
646218893Sdim                                  cast<AutoType>(T2)->getDeducedType()))
647218893Sdim      return false;
648218893Sdim    break;
649218893Sdim
650203955Srdivacky  case Type::Record:
651203955Srdivacky  case Type::Enum:
652203955Srdivacky    if (!IsStructurallyEquivalent(Context,
653203955Srdivacky                                  cast<TagType>(T1)->getDecl(),
654203955Srdivacky                                  cast<TagType>(T2)->getDecl()))
655203955Srdivacky      return false;
656203955Srdivacky    break;
657208600Srdivacky
658203955Srdivacky  case Type::TemplateTypeParm: {
659203955Srdivacky    const TemplateTypeParmType *Parm1 = cast<TemplateTypeParmType>(T1);
660203955Srdivacky    const TemplateTypeParmType *Parm2 = cast<TemplateTypeParmType>(T2);
661203955Srdivacky    if (Parm1->getDepth() != Parm2->getDepth())
662203955Srdivacky      return false;
663203955Srdivacky    if (Parm1->getIndex() != Parm2->getIndex())
664203955Srdivacky      return false;
665203955Srdivacky    if (Parm1->isParameterPack() != Parm2->isParameterPack())
666203955Srdivacky      return false;
667203955Srdivacky
668203955Srdivacky    // Names of template type parameters are never significant.
669203955Srdivacky    break;
670203955Srdivacky  }
671203955Srdivacky
672203955Srdivacky  case Type::SubstTemplateTypeParm: {
673203955Srdivacky    const SubstTemplateTypeParmType *Subst1
674203955Srdivacky      = cast<SubstTemplateTypeParmType>(T1);
675203955Srdivacky    const SubstTemplateTypeParmType *Subst2
676203955Srdivacky      = cast<SubstTemplateTypeParmType>(T2);
677203955Srdivacky    if (!IsStructurallyEquivalent(Context,
678203955Srdivacky                                  QualType(Subst1->getReplacedParameter(), 0),
679203955Srdivacky                                  QualType(Subst2->getReplacedParameter(), 0)))
680203955Srdivacky      return false;
681203955Srdivacky    if (!IsStructurallyEquivalent(Context,
682203955Srdivacky                                  Subst1->getReplacementType(),
683203955Srdivacky                                  Subst2->getReplacementType()))
684203955Srdivacky      return false;
685203955Srdivacky    break;
686203955Srdivacky  }
687203955Srdivacky
688218893Sdim  case Type::SubstTemplateTypeParmPack: {
689218893Sdim    const SubstTemplateTypeParmPackType *Subst1
690218893Sdim      = cast<SubstTemplateTypeParmPackType>(T1);
691218893Sdim    const SubstTemplateTypeParmPackType *Subst2
692218893Sdim      = cast<SubstTemplateTypeParmPackType>(T2);
693218893Sdim    if (!IsStructurallyEquivalent(Context,
694218893Sdim                                  QualType(Subst1->getReplacedParameter(), 0),
695218893Sdim                                  QualType(Subst2->getReplacedParameter(), 0)))
696218893Sdim      return false;
697218893Sdim    if (!IsStructurallyEquivalent(Context,
698218893Sdim                                  Subst1->getArgumentPack(),
699218893Sdim                                  Subst2->getArgumentPack()))
700218893Sdim      return false;
701218893Sdim    break;
702218893Sdim  }
703203955Srdivacky  case Type::TemplateSpecialization: {
704203955Srdivacky    const TemplateSpecializationType *Spec1
705203955Srdivacky      = cast<TemplateSpecializationType>(T1);
706203955Srdivacky    const TemplateSpecializationType *Spec2
707203955Srdivacky      = cast<TemplateSpecializationType>(T2);
708203955Srdivacky    if (!IsStructurallyEquivalent(Context,
709203955Srdivacky                                  Spec1->getTemplateName(),
710203955Srdivacky                                  Spec2->getTemplateName()))
711203955Srdivacky      return false;
712203955Srdivacky    if (Spec1->getNumArgs() != Spec2->getNumArgs())
713203955Srdivacky      return false;
714203955Srdivacky    for (unsigned I = 0, N = Spec1->getNumArgs(); I != N; ++I) {
715203955Srdivacky      if (!IsStructurallyEquivalent(Context,
716203955Srdivacky                                    Spec1->getArg(I), Spec2->getArg(I)))
717203955Srdivacky        return false;
718203955Srdivacky    }
719203955Srdivacky    break;
720203955Srdivacky  }
721203955Srdivacky
722208600Srdivacky  case Type::Elaborated: {
723208600Srdivacky    const ElaboratedType *Elab1 = cast<ElaboratedType>(T1);
724208600Srdivacky    const ElaboratedType *Elab2 = cast<ElaboratedType>(T2);
725208600Srdivacky    // CHECKME: what if a keyword is ETK_None or ETK_typename ?
726208600Srdivacky    if (Elab1->getKeyword() != Elab2->getKeyword())
727208600Srdivacky      return false;
728203955Srdivacky    if (!IsStructurallyEquivalent(Context,
729208600Srdivacky                                  Elab1->getQualifier(),
730208600Srdivacky                                  Elab2->getQualifier()))
731203955Srdivacky      return false;
732203955Srdivacky    if (!IsStructurallyEquivalent(Context,
733208600Srdivacky                                  Elab1->getNamedType(),
734208600Srdivacky                                  Elab2->getNamedType()))
735203955Srdivacky      return false;
736203955Srdivacky    break;
737203955Srdivacky  }
738203955Srdivacky
739204962Srdivacky  case Type::InjectedClassName: {
740204962Srdivacky    const InjectedClassNameType *Inj1 = cast<InjectedClassNameType>(T1);
741204962Srdivacky    const InjectedClassNameType *Inj2 = cast<InjectedClassNameType>(T2);
742204962Srdivacky    if (!IsStructurallyEquivalent(Context,
743207619Srdivacky                                  Inj1->getInjectedSpecializationType(),
744207619Srdivacky                                  Inj2->getInjectedSpecializationType()))
745204962Srdivacky      return false;
746204962Srdivacky    break;
747204962Srdivacky  }
748204962Srdivacky
749206084Srdivacky  case Type::DependentName: {
750206084Srdivacky    const DependentNameType *Typename1 = cast<DependentNameType>(T1);
751206084Srdivacky    const DependentNameType *Typename2 = cast<DependentNameType>(T2);
752203955Srdivacky    if (!IsStructurallyEquivalent(Context,
753203955Srdivacky                                  Typename1->getQualifier(),
754203955Srdivacky                                  Typename2->getQualifier()))
755203955Srdivacky      return false;
756203955Srdivacky    if (!IsStructurallyEquivalent(Typename1->getIdentifier(),
757203955Srdivacky                                  Typename2->getIdentifier()))
758203955Srdivacky      return false;
759203955Srdivacky
760203955Srdivacky    break;
761203955Srdivacky  }
762203955Srdivacky
763210299Sed  case Type::DependentTemplateSpecialization: {
764210299Sed    const DependentTemplateSpecializationType *Spec1 =
765210299Sed      cast<DependentTemplateSpecializationType>(T1);
766210299Sed    const DependentTemplateSpecializationType *Spec2 =
767210299Sed      cast<DependentTemplateSpecializationType>(T2);
768210299Sed    if (!IsStructurallyEquivalent(Context,
769210299Sed                                  Spec1->getQualifier(),
770210299Sed                                  Spec2->getQualifier()))
771210299Sed      return false;
772210299Sed    if (!IsStructurallyEquivalent(Spec1->getIdentifier(),
773210299Sed                                  Spec2->getIdentifier()))
774210299Sed      return false;
775210299Sed    if (Spec1->getNumArgs() != Spec2->getNumArgs())
776210299Sed      return false;
777210299Sed    for (unsigned I = 0, N = Spec1->getNumArgs(); I != N; ++I) {
778210299Sed      if (!IsStructurallyEquivalent(Context,
779210299Sed                                    Spec1->getArg(I), Spec2->getArg(I)))
780210299Sed        return false;
781210299Sed    }
782210299Sed    break;
783210299Sed  }
784218893Sdim
785218893Sdim  case Type::PackExpansion:
786218893Sdim    if (!IsStructurallyEquivalent(Context,
787218893Sdim                                  cast<PackExpansionType>(T1)->getPattern(),
788218893Sdim                                  cast<PackExpansionType>(T2)->getPattern()))
789218893Sdim      return false;
790218893Sdim    break;
791218893Sdim
792203955Srdivacky  case Type::ObjCInterface: {
793203955Srdivacky    const ObjCInterfaceType *Iface1 = cast<ObjCInterfaceType>(T1);
794203955Srdivacky    const ObjCInterfaceType *Iface2 = cast<ObjCInterfaceType>(T2);
795203955Srdivacky    if (!IsStructurallyEquivalent(Context,
796203955Srdivacky                                  Iface1->getDecl(), Iface2->getDecl()))
797203955Srdivacky      return false;
798208600Srdivacky    break;
799208600Srdivacky  }
800208600Srdivacky
801208600Srdivacky  case Type::ObjCObject: {
802208600Srdivacky    const ObjCObjectType *Obj1 = cast<ObjCObjectType>(T1);
803208600Srdivacky    const ObjCObjectType *Obj2 = cast<ObjCObjectType>(T2);
804208600Srdivacky    if (!IsStructurallyEquivalent(Context,
805208600Srdivacky                                  Obj1->getBaseType(),
806208600Srdivacky                                  Obj2->getBaseType()))
807203955Srdivacky      return false;
808208600Srdivacky    if (Obj1->getNumProtocols() != Obj2->getNumProtocols())
809208600Srdivacky      return false;
810208600Srdivacky    for (unsigned I = 0, N = Obj1->getNumProtocols(); I != N; ++I) {
811203955Srdivacky      if (!IsStructurallyEquivalent(Context,
812208600Srdivacky                                    Obj1->getProtocol(I),
813208600Srdivacky                                    Obj2->getProtocol(I)))
814203955Srdivacky        return false;
815203955Srdivacky    }
816203955Srdivacky    break;
817203955Srdivacky  }
818203955Srdivacky
819203955Srdivacky  case Type::ObjCObjectPointer: {
820203955Srdivacky    const ObjCObjectPointerType *Ptr1 = cast<ObjCObjectPointerType>(T1);
821203955Srdivacky    const ObjCObjectPointerType *Ptr2 = cast<ObjCObjectPointerType>(T2);
822203955Srdivacky    if (!IsStructurallyEquivalent(Context,
823203955Srdivacky                                  Ptr1->getPointeeType(),
824203955Srdivacky                                  Ptr2->getPointeeType()))
825203955Srdivacky      return false;
826203955Srdivacky    break;
827203955Srdivacky  }
828226890Sdim
829226890Sdim  case Type::Atomic: {
830226890Sdim    if (!IsStructurallyEquivalent(Context,
831226890Sdim                                  cast<AtomicType>(T1)->getValueType(),
832226890Sdim                                  cast<AtomicType>(T2)->getValueType()))
833226890Sdim      return false;
834226890Sdim    break;
835226890Sdim  }
836226890Sdim
837203955Srdivacky  } // end switch
838203955Srdivacky
839203955Srdivacky  return true;
840203955Srdivacky}
841203955Srdivacky
842226890Sdim/// \brief Determine structural equivalence of two fields.
843226890Sdimstatic bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
844226890Sdim                                     FieldDecl *Field1, FieldDecl *Field2) {
845226890Sdim  RecordDecl *Owner2 = cast<RecordDecl>(Field2->getDeclContext());
846245431Sdim
847245431Sdim  // For anonymous structs/unions, match up the anonymous struct/union type
848245431Sdim  // declarations directly, so that we don't go off searching for anonymous
849245431Sdim  // types
850245431Sdim  if (Field1->isAnonymousStructOrUnion() &&
851245431Sdim      Field2->isAnonymousStructOrUnion()) {
852245431Sdim    RecordDecl *D1 = Field1->getType()->castAs<RecordType>()->getDecl();
853245431Sdim    RecordDecl *D2 = Field2->getType()->castAs<RecordType>()->getDecl();
854245431Sdim    return IsStructurallyEquivalent(Context, D1, D2);
855245431Sdim  }
856252723Sdim
857252723Sdim  // Check for equivalent field names.
858252723Sdim  IdentifierInfo *Name1 = Field1->getIdentifier();
859252723Sdim  IdentifierInfo *Name2 = Field2->getIdentifier();
860252723Sdim  if (!::IsStructurallyEquivalent(Name1, Name2))
861252723Sdim    return false;
862245431Sdim
863245431Sdim  if (!IsStructurallyEquivalent(Context,
864226890Sdim                                Field1->getType(), Field2->getType())) {
865245431Sdim    if (Context.Complain) {
866245431Sdim      Context.Diag2(Owner2->getLocation(), diag::warn_odr_tag_type_inconsistent)
867245431Sdim        << Context.C2.getTypeDeclType(Owner2);
868245431Sdim      Context.Diag2(Field2->getLocation(), diag::note_odr_field)
869245431Sdim        << Field2->getDeclName() << Field2->getType();
870245431Sdim      Context.Diag1(Field1->getLocation(), diag::note_odr_field)
871245431Sdim        << Field1->getDeclName() << Field1->getType();
872245431Sdim    }
873226890Sdim    return false;
874226890Sdim  }
875226890Sdim
876226890Sdim  if (Field1->isBitField() != Field2->isBitField()) {
877245431Sdim    if (Context.Complain) {
878245431Sdim      Context.Diag2(Owner2->getLocation(), diag::warn_odr_tag_type_inconsistent)
879245431Sdim        << Context.C2.getTypeDeclType(Owner2);
880245431Sdim      if (Field1->isBitField()) {
881245431Sdim        Context.Diag1(Field1->getLocation(), diag::note_odr_bit_field)
882245431Sdim        << Field1->getDeclName() << Field1->getType()
883245431Sdim        << Field1->getBitWidthValue(Context.C1);
884245431Sdim        Context.Diag2(Field2->getLocation(), diag::note_odr_not_bit_field)
885245431Sdim        << Field2->getDeclName();
886245431Sdim      } else {
887245431Sdim        Context.Diag2(Field2->getLocation(), diag::note_odr_bit_field)
888245431Sdim        << Field2->getDeclName() << Field2->getType()
889245431Sdim        << Field2->getBitWidthValue(Context.C2);
890245431Sdim        Context.Diag1(Field1->getLocation(), diag::note_odr_not_bit_field)
891245431Sdim        << Field1->getDeclName();
892245431Sdim      }
893226890Sdim    }
894226890Sdim    return false;
895226890Sdim  }
896226890Sdim
897226890Sdim  if (Field1->isBitField()) {
898226890Sdim    // Make sure that the bit-fields are the same length.
899226890Sdim    unsigned Bits1 = Field1->getBitWidthValue(Context.C1);
900226890Sdim    unsigned Bits2 = Field2->getBitWidthValue(Context.C2);
901226890Sdim
902226890Sdim    if (Bits1 != Bits2) {
903245431Sdim      if (Context.Complain) {
904245431Sdim        Context.Diag2(Owner2->getLocation(), diag::warn_odr_tag_type_inconsistent)
905245431Sdim          << Context.C2.getTypeDeclType(Owner2);
906245431Sdim        Context.Diag2(Field2->getLocation(), diag::note_odr_bit_field)
907245431Sdim          << Field2->getDeclName() << Field2->getType() << Bits2;
908245431Sdim        Context.Diag1(Field1->getLocation(), diag::note_odr_bit_field)
909245431Sdim          << Field1->getDeclName() << Field1->getType() << Bits1;
910245431Sdim      }
911226890Sdim      return false;
912226890Sdim    }
913226890Sdim  }
914226890Sdim
915226890Sdim  return true;
916226890Sdim}
917226890Sdim
918245431Sdim/// \brief Find the index of the given anonymous struct/union within its
919245431Sdim/// context.
920245431Sdim///
921245431Sdim/// \returns Returns the index of this anonymous struct/union in its context,
922245431Sdim/// including the next assigned index (if none of them match). Returns an
923245431Sdim/// empty option if the context is not a record, i.e.. if the anonymous
924245431Sdim/// struct/union is at namespace or block scope.
925252723Sdimstatic Optional<unsigned> findAnonymousStructOrUnionIndex(RecordDecl *Anon) {
926245431Sdim  ASTContext &Context = Anon->getASTContext();
927245431Sdim  QualType AnonTy = Context.getRecordType(Anon);
928245431Sdim
929245431Sdim  RecordDecl *Owner = dyn_cast<RecordDecl>(Anon->getDeclContext());
930245431Sdim  if (!Owner)
931252723Sdim    return None;
932245431Sdim
933245431Sdim  unsigned Index = 0;
934245431Sdim  for (DeclContext::decl_iterator D = Owner->noload_decls_begin(),
935245431Sdim                               DEnd = Owner->noload_decls_end();
936245431Sdim       D != DEnd; ++D) {
937245431Sdim    FieldDecl *F = dyn_cast<FieldDecl>(*D);
938245431Sdim    if (!F || !F->isAnonymousStructOrUnion())
939245431Sdim      continue;
940245431Sdim
941245431Sdim    if (Context.hasSameType(F->getType(), AnonTy))
942245431Sdim      break;
943245431Sdim
944245431Sdim    ++Index;
945245431Sdim  }
946245431Sdim
947245431Sdim  return Index;
948245431Sdim}
949245431Sdim
950203955Srdivacky/// \brief Determine structural equivalence of two records.
951203955Srdivackystatic bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
952203955Srdivacky                                     RecordDecl *D1, RecordDecl *D2) {
953203955Srdivacky  if (D1->isUnion() != D2->isUnion()) {
954245431Sdim    if (Context.Complain) {
955245431Sdim      Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
956245431Sdim        << Context.C2.getTypeDeclType(D2);
957245431Sdim      Context.Diag1(D1->getLocation(), diag::note_odr_tag_kind_here)
958245431Sdim        << D1->getDeclName() << (unsigned)D1->getTagKind();
959245431Sdim    }
960203955Srdivacky    return false;
961203955Srdivacky  }
962245431Sdim
963245431Sdim  if (D1->isAnonymousStructOrUnion() && D2->isAnonymousStructOrUnion()) {
964245431Sdim    // If both anonymous structs/unions are in a record context, make sure
965245431Sdim    // they occur in the same location in the context records.
966252723Sdim    if (Optional<unsigned> Index1 = findAnonymousStructOrUnionIndex(D1)) {
967252723Sdim      if (Optional<unsigned> Index2 = findAnonymousStructOrUnionIndex(D2)) {
968245431Sdim        if (*Index1 != *Index2)
969245431Sdim          return false;
970245431Sdim      }
971245431Sdim    }
972245431Sdim  }
973245431Sdim
974218893Sdim  // If both declarations are class template specializations, we know
975218893Sdim  // the ODR applies, so check the template and template arguments.
976218893Sdim  ClassTemplateSpecializationDecl *Spec1
977218893Sdim    = dyn_cast<ClassTemplateSpecializationDecl>(D1);
978218893Sdim  ClassTemplateSpecializationDecl *Spec2
979218893Sdim    = dyn_cast<ClassTemplateSpecializationDecl>(D2);
980218893Sdim  if (Spec1 && Spec2) {
981218893Sdim    // Check that the specialized templates are the same.
982218893Sdim    if (!IsStructurallyEquivalent(Context, Spec1->getSpecializedTemplate(),
983218893Sdim                                  Spec2->getSpecializedTemplate()))
984218893Sdim      return false;
985218893Sdim
986218893Sdim    // Check that the template arguments are the same.
987218893Sdim    if (Spec1->getTemplateArgs().size() != Spec2->getTemplateArgs().size())
988218893Sdim      return false;
989218893Sdim
990218893Sdim    for (unsigned I = 0, N = Spec1->getTemplateArgs().size(); I != N; ++I)
991218893Sdim      if (!IsStructurallyEquivalent(Context,
992218893Sdim                                    Spec1->getTemplateArgs().get(I),
993218893Sdim                                    Spec2->getTemplateArgs().get(I)))
994218893Sdim        return false;
995218893Sdim  }
996218893Sdim  // If one is a class template specialization and the other is not, these
997221345Sdim  // structures are different.
998218893Sdim  else if (Spec1 || Spec2)
999218893Sdim    return false;
1000218893Sdim
1001203955Srdivacky  // Compare the definitions of these two records. If either or both are
1002203955Srdivacky  // incomplete, we assume that they are equivalent.
1003203955Srdivacky  D1 = D1->getDefinition();
1004203955Srdivacky  D2 = D2->getDefinition();
1005203955Srdivacky  if (!D1 || !D2)
1006203955Srdivacky    return true;
1007203955Srdivacky
1008203955Srdivacky  if (CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(D1)) {
1009203955Srdivacky    if (CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(D2)) {
1010203955Srdivacky      if (D1CXX->getNumBases() != D2CXX->getNumBases()) {
1011245431Sdim        if (Context.Complain) {
1012245431Sdim          Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
1013245431Sdim            << Context.C2.getTypeDeclType(D2);
1014245431Sdim          Context.Diag2(D2->getLocation(), diag::note_odr_number_of_bases)
1015245431Sdim            << D2CXX->getNumBases();
1016245431Sdim          Context.Diag1(D1->getLocation(), diag::note_odr_number_of_bases)
1017245431Sdim            << D1CXX->getNumBases();
1018245431Sdim        }
1019203955Srdivacky        return false;
1020203955Srdivacky      }
1021203955Srdivacky
1022203955Srdivacky      // Check the base classes.
1023203955Srdivacky      for (CXXRecordDecl::base_class_iterator Base1 = D1CXX->bases_begin(),
1024203955Srdivacky                                           BaseEnd1 = D1CXX->bases_end(),
1025203955Srdivacky                                                Base2 = D2CXX->bases_begin();
1026203955Srdivacky           Base1 != BaseEnd1;
1027203955Srdivacky           ++Base1, ++Base2) {
1028203955Srdivacky        if (!IsStructurallyEquivalent(Context,
1029203955Srdivacky                                      Base1->getType(), Base2->getType())) {
1030245431Sdim          if (Context.Complain) {
1031245431Sdim            Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
1032245431Sdim              << Context.C2.getTypeDeclType(D2);
1033245431Sdim            Context.Diag2(Base2->getLocStart(), diag::note_odr_base)
1034245431Sdim              << Base2->getType()
1035245431Sdim              << Base2->getSourceRange();
1036245431Sdim            Context.Diag1(Base1->getLocStart(), diag::note_odr_base)
1037245431Sdim              << Base1->getType()
1038245431Sdim              << Base1->getSourceRange();
1039245431Sdim          }
1040203955Srdivacky          return false;
1041203955Srdivacky        }
1042203955Srdivacky
1043203955Srdivacky        // Check virtual vs. non-virtual inheritance mismatch.
1044203955Srdivacky        if (Base1->isVirtual() != Base2->isVirtual()) {
1045245431Sdim          if (Context.Complain) {
1046245431Sdim            Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
1047245431Sdim              << Context.C2.getTypeDeclType(D2);
1048245431Sdim            Context.Diag2(Base2->getLocStart(),
1049245431Sdim                          diag::note_odr_virtual_base)
1050245431Sdim              << Base2->isVirtual() << Base2->getSourceRange();
1051245431Sdim            Context.Diag1(Base1->getLocStart(), diag::note_odr_base)
1052245431Sdim              << Base1->isVirtual()
1053245431Sdim              << Base1->getSourceRange();
1054245431Sdim          }
1055203955Srdivacky          return false;
1056203955Srdivacky        }
1057203955Srdivacky      }
1058203955Srdivacky    } else if (D1CXX->getNumBases() > 0) {
1059245431Sdim      if (Context.Complain) {
1060245431Sdim        Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
1061245431Sdim          << Context.C2.getTypeDeclType(D2);
1062245431Sdim        const CXXBaseSpecifier *Base1 = D1CXX->bases_begin();
1063245431Sdim        Context.Diag1(Base1->getLocStart(), diag::note_odr_base)
1064245431Sdim          << Base1->getType()
1065245431Sdim          << Base1->getSourceRange();
1066245431Sdim        Context.Diag2(D2->getLocation(), diag::note_odr_missing_base);
1067245431Sdim      }
1068203955Srdivacky      return false;
1069203955Srdivacky    }
1070203955Srdivacky  }
1071203955Srdivacky
1072203955Srdivacky  // Check the fields for consistency.
1073245431Sdim  RecordDecl::field_iterator Field2 = D2->field_begin(),
1074203955Srdivacky                             Field2End = D2->field_end();
1075245431Sdim  for (RecordDecl::field_iterator Field1 = D1->field_begin(),
1076203955Srdivacky                                  Field1End = D1->field_end();
1077203955Srdivacky       Field1 != Field1End;
1078203955Srdivacky       ++Field1, ++Field2) {
1079203955Srdivacky    if (Field2 == Field2End) {
1080245431Sdim      if (Context.Complain) {
1081245431Sdim        Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
1082245431Sdim          << Context.C2.getTypeDeclType(D2);
1083245431Sdim        Context.Diag1(Field1->getLocation(), diag::note_odr_field)
1084245431Sdim          << Field1->getDeclName() << Field1->getType();
1085245431Sdim        Context.Diag2(D2->getLocation(), diag::note_odr_missing_field);
1086245431Sdim      }
1087203955Srdivacky      return false;
1088203955Srdivacky    }
1089203955Srdivacky
1090226890Sdim    if (!IsStructurallyEquivalent(Context, *Field1, *Field2))
1091226890Sdim      return false;
1092203955Srdivacky  }
1093203955Srdivacky
1094203955Srdivacky  if (Field2 != Field2End) {
1095245431Sdim    if (Context.Complain) {
1096245431Sdim      Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
1097245431Sdim        << Context.C2.getTypeDeclType(D2);
1098245431Sdim      Context.Diag2(Field2->getLocation(), diag::note_odr_field)
1099245431Sdim        << Field2->getDeclName() << Field2->getType();
1100245431Sdim      Context.Diag1(D1->getLocation(), diag::note_odr_missing_field);
1101245431Sdim    }
1102203955Srdivacky    return false;
1103203955Srdivacky  }
1104203955Srdivacky
1105203955Srdivacky  return true;
1106203955Srdivacky}
1107203955Srdivacky
1108203955Srdivacky/// \brief Determine structural equivalence of two enums.
1109203955Srdivackystatic bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
1110203955Srdivacky                                     EnumDecl *D1, EnumDecl *D2) {
1111203955Srdivacky  EnumDecl::enumerator_iterator EC2 = D2->enumerator_begin(),
1112203955Srdivacky                             EC2End = D2->enumerator_end();
1113203955Srdivacky  for (EnumDecl::enumerator_iterator EC1 = D1->enumerator_begin(),
1114203955Srdivacky                                  EC1End = D1->enumerator_end();
1115203955Srdivacky       EC1 != EC1End; ++EC1, ++EC2) {
1116203955Srdivacky    if (EC2 == EC2End) {
1117245431Sdim      if (Context.Complain) {
1118245431Sdim        Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
1119245431Sdim          << Context.C2.getTypeDeclType(D2);
1120245431Sdim        Context.Diag1(EC1->getLocation(), diag::note_odr_enumerator)
1121245431Sdim          << EC1->getDeclName()
1122245431Sdim          << EC1->getInitVal().toString(10);
1123245431Sdim        Context.Diag2(D2->getLocation(), diag::note_odr_missing_enumerator);
1124245431Sdim      }
1125203955Srdivacky      return false;
1126203955Srdivacky    }
1127203955Srdivacky
1128203955Srdivacky    llvm::APSInt Val1 = EC1->getInitVal();
1129203955Srdivacky    llvm::APSInt Val2 = EC2->getInitVal();
1130245431Sdim    if (!llvm::APSInt::isSameValue(Val1, Val2) ||
1131203955Srdivacky        !IsStructurallyEquivalent(EC1->getIdentifier(), EC2->getIdentifier())) {
1132245431Sdim      if (Context.Complain) {
1133245431Sdim        Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
1134245431Sdim          << Context.C2.getTypeDeclType(D2);
1135245431Sdim        Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
1136245431Sdim          << EC2->getDeclName()
1137245431Sdim          << EC2->getInitVal().toString(10);
1138245431Sdim        Context.Diag1(EC1->getLocation(), diag::note_odr_enumerator)
1139245431Sdim          << EC1->getDeclName()
1140245431Sdim          << EC1->getInitVal().toString(10);
1141245431Sdim      }
1142245431Sdim      return false;
1143245431Sdim    }
1144245431Sdim  }
1145245431Sdim
1146245431Sdim  if (EC2 != EC2End) {
1147245431Sdim    if (Context.Complain) {
1148203955Srdivacky      Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
1149203955Srdivacky        << Context.C2.getTypeDeclType(D2);
1150203955Srdivacky      Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
1151203955Srdivacky        << EC2->getDeclName()
1152203955Srdivacky        << EC2->getInitVal().toString(10);
1153245431Sdim      Context.Diag1(D1->getLocation(), diag::note_odr_missing_enumerator);
1154203955Srdivacky    }
1155203955Srdivacky    return false;
1156203955Srdivacky  }
1157203955Srdivacky
1158203955Srdivacky  return true;
1159203955Srdivacky}
1160218893Sdim
1161218893Sdimstatic bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
1162218893Sdim                                     TemplateParameterList *Params1,
1163218893Sdim                                     TemplateParameterList *Params2) {
1164218893Sdim  if (Params1->size() != Params2->size()) {
1165245431Sdim    if (Context.Complain) {
1166245431Sdim      Context.Diag2(Params2->getTemplateLoc(),
1167245431Sdim                    diag::err_odr_different_num_template_parameters)
1168245431Sdim        << Params1->size() << Params2->size();
1169245431Sdim      Context.Diag1(Params1->getTemplateLoc(),
1170245431Sdim                    diag::note_odr_template_parameter_list);
1171245431Sdim    }
1172218893Sdim    return false;
1173218893Sdim  }
1174203955Srdivacky
1175218893Sdim  for (unsigned I = 0, N = Params1->size(); I != N; ++I) {
1176218893Sdim    if (Params1->getParam(I)->getKind() != Params2->getParam(I)->getKind()) {
1177245431Sdim      if (Context.Complain) {
1178245431Sdim        Context.Diag2(Params2->getParam(I)->getLocation(),
1179245431Sdim                      diag::err_odr_different_template_parameter_kind);
1180245431Sdim        Context.Diag1(Params1->getParam(I)->getLocation(),
1181245431Sdim                      diag::note_odr_template_parameter_here);
1182245431Sdim      }
1183218893Sdim      return false;
1184218893Sdim    }
1185218893Sdim
1186218893Sdim    if (!Context.IsStructurallyEquivalent(Params1->getParam(I),
1187218893Sdim                                          Params2->getParam(I))) {
1188218893Sdim
1189218893Sdim      return false;
1190218893Sdim    }
1191218893Sdim  }
1192218893Sdim
1193218893Sdim  return true;
1194218893Sdim}
1195218893Sdim
1196218893Sdimstatic bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
1197218893Sdim                                     TemplateTypeParmDecl *D1,
1198218893Sdim                                     TemplateTypeParmDecl *D2) {
1199218893Sdim  if (D1->isParameterPack() != D2->isParameterPack()) {
1200245431Sdim    if (Context.Complain) {
1201245431Sdim      Context.Diag2(D2->getLocation(), diag::err_odr_parameter_pack_non_pack)
1202245431Sdim        << D2->isParameterPack();
1203245431Sdim      Context.Diag1(D1->getLocation(), diag::note_odr_parameter_pack_non_pack)
1204245431Sdim        << D1->isParameterPack();
1205245431Sdim    }
1206218893Sdim    return false;
1207218893Sdim  }
1208218893Sdim
1209218893Sdim  return true;
1210218893Sdim}
1211218893Sdim
1212218893Sdimstatic bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
1213218893Sdim                                     NonTypeTemplateParmDecl *D1,
1214218893Sdim                                     NonTypeTemplateParmDecl *D2) {
1215218893Sdim  if (D1->isParameterPack() != D2->isParameterPack()) {
1216245431Sdim    if (Context.Complain) {
1217245431Sdim      Context.Diag2(D2->getLocation(), diag::err_odr_parameter_pack_non_pack)
1218245431Sdim        << D2->isParameterPack();
1219245431Sdim      Context.Diag1(D1->getLocation(), diag::note_odr_parameter_pack_non_pack)
1220245431Sdim        << D1->isParameterPack();
1221245431Sdim    }
1222218893Sdim    return false;
1223218893Sdim  }
1224218893Sdim
1225218893Sdim  // Check types.
1226218893Sdim  if (!Context.IsStructurallyEquivalent(D1->getType(), D2->getType())) {
1227245431Sdim    if (Context.Complain) {
1228245431Sdim      Context.Diag2(D2->getLocation(),
1229245431Sdim                    diag::err_odr_non_type_parameter_type_inconsistent)
1230245431Sdim        << D2->getType() << D1->getType();
1231245431Sdim      Context.Diag1(D1->getLocation(), diag::note_odr_value_here)
1232245431Sdim        << D1->getType();
1233245431Sdim    }
1234218893Sdim    return false;
1235218893Sdim  }
1236218893Sdim
1237218893Sdim  return true;
1238218893Sdim}
1239218893Sdim
1240218893Sdimstatic bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
1241218893Sdim                                     TemplateTemplateParmDecl *D1,
1242218893Sdim                                     TemplateTemplateParmDecl *D2) {
1243218893Sdim  if (D1->isParameterPack() != D2->isParameterPack()) {
1244245431Sdim    if (Context.Complain) {
1245245431Sdim      Context.Diag2(D2->getLocation(), diag::err_odr_parameter_pack_non_pack)
1246245431Sdim        << D2->isParameterPack();
1247245431Sdim      Context.Diag1(D1->getLocation(), diag::note_odr_parameter_pack_non_pack)
1248245431Sdim        << D1->isParameterPack();
1249245431Sdim    }
1250218893Sdim    return false;
1251218893Sdim  }
1252245431Sdim
1253218893Sdim  // Check template parameter lists.
1254218893Sdim  return IsStructurallyEquivalent(Context, D1->getTemplateParameters(),
1255218893Sdim                                  D2->getTemplateParameters());
1256218893Sdim}
1257218893Sdim
1258218893Sdimstatic bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
1259218893Sdim                                     ClassTemplateDecl *D1,
1260218893Sdim                                     ClassTemplateDecl *D2) {
1261218893Sdim  // Check template parameters.
1262218893Sdim  if (!IsStructurallyEquivalent(Context,
1263218893Sdim                                D1->getTemplateParameters(),
1264218893Sdim                                D2->getTemplateParameters()))
1265218893Sdim    return false;
1266218893Sdim
1267218893Sdim  // Check the templated declaration.
1268218893Sdim  return Context.IsStructurallyEquivalent(D1->getTemplatedDecl(),
1269218893Sdim                                          D2->getTemplatedDecl());
1270218893Sdim}
1271218893Sdim
1272203955Srdivacky/// \brief Determine structural equivalence of two declarations.
1273203955Srdivackystatic bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
1274203955Srdivacky                                     Decl *D1, Decl *D2) {
1275203955Srdivacky  // FIXME: Check for known structural equivalences via a callback of some sort.
1276203955Srdivacky
1277203955Srdivacky  // Check whether we already know that these two declarations are not
1278203955Srdivacky  // structurally equivalent.
1279203955Srdivacky  if (Context.NonEquivalentDecls.count(std::make_pair(D1->getCanonicalDecl(),
1280203955Srdivacky                                                      D2->getCanonicalDecl())))
1281203955Srdivacky    return false;
1282203955Srdivacky
1283203955Srdivacky  // Determine whether we've already produced a tentative equivalence for D1.
1284203955Srdivacky  Decl *&EquivToD1 = Context.TentativeEquivalences[D1->getCanonicalDecl()];
1285203955Srdivacky  if (EquivToD1)
1286203955Srdivacky    return EquivToD1 == D2->getCanonicalDecl();
1287203955Srdivacky
1288203955Srdivacky  // Produce a tentative equivalence D1 <-> D2, which will be checked later.
1289203955Srdivacky  EquivToD1 = D2->getCanonicalDecl();
1290203955Srdivacky  Context.DeclsToCheck.push_back(D1->getCanonicalDecl());
1291203955Srdivacky  return true;
1292203955Srdivacky}
1293203955Srdivacky
1294203955Srdivackybool StructuralEquivalenceContext::IsStructurallyEquivalent(Decl *D1,
1295203955Srdivacky                                                            Decl *D2) {
1296203955Srdivacky  if (!::IsStructurallyEquivalent(*this, D1, D2))
1297203955Srdivacky    return false;
1298203955Srdivacky
1299203955Srdivacky  return !Finish();
1300203955Srdivacky}
1301203955Srdivacky
1302203955Srdivackybool StructuralEquivalenceContext::IsStructurallyEquivalent(QualType T1,
1303203955Srdivacky                                                            QualType T2) {
1304203955Srdivacky  if (!::IsStructurallyEquivalent(*this, T1, T2))
1305203955Srdivacky    return false;
1306203955Srdivacky
1307203955Srdivacky  return !Finish();
1308203955Srdivacky}
1309203955Srdivacky
1310203955Srdivackybool StructuralEquivalenceContext::Finish() {
1311203955Srdivacky  while (!DeclsToCheck.empty()) {
1312203955Srdivacky    // Check the next declaration.
1313203955Srdivacky    Decl *D1 = DeclsToCheck.front();
1314203955Srdivacky    DeclsToCheck.pop_front();
1315203955Srdivacky
1316203955Srdivacky    Decl *D2 = TentativeEquivalences[D1];
1317203955Srdivacky    assert(D2 && "Unrecorded tentative equivalence?");
1318203955Srdivacky
1319203955Srdivacky    bool Equivalent = true;
1320203955Srdivacky
1321203955Srdivacky    // FIXME: Switch on all declaration kinds. For now, we're just going to
1322203955Srdivacky    // check the obvious ones.
1323203955Srdivacky    if (RecordDecl *Record1 = dyn_cast<RecordDecl>(D1)) {
1324203955Srdivacky      if (RecordDecl *Record2 = dyn_cast<RecordDecl>(D2)) {
1325203955Srdivacky        // Check for equivalent structure names.
1326203955Srdivacky        IdentifierInfo *Name1 = Record1->getIdentifier();
1327221345Sdim        if (!Name1 && Record1->getTypedefNameForAnonDecl())
1328221345Sdim          Name1 = Record1->getTypedefNameForAnonDecl()->getIdentifier();
1329203955Srdivacky        IdentifierInfo *Name2 = Record2->getIdentifier();
1330221345Sdim        if (!Name2 && Record2->getTypedefNameForAnonDecl())
1331221345Sdim          Name2 = Record2->getTypedefNameForAnonDecl()->getIdentifier();
1332203955Srdivacky        if (!::IsStructurallyEquivalent(Name1, Name2) ||
1333203955Srdivacky            !::IsStructurallyEquivalent(*this, Record1, Record2))
1334203955Srdivacky          Equivalent = false;
1335203955Srdivacky      } else {
1336203955Srdivacky        // Record/non-record mismatch.
1337203955Srdivacky        Equivalent = false;
1338203955Srdivacky      }
1339203955Srdivacky    } else if (EnumDecl *Enum1 = dyn_cast<EnumDecl>(D1)) {
1340203955Srdivacky      if (EnumDecl *Enum2 = dyn_cast<EnumDecl>(D2)) {
1341203955Srdivacky        // Check for equivalent enum names.
1342203955Srdivacky        IdentifierInfo *Name1 = Enum1->getIdentifier();
1343221345Sdim        if (!Name1 && Enum1->getTypedefNameForAnonDecl())
1344221345Sdim          Name1 = Enum1->getTypedefNameForAnonDecl()->getIdentifier();
1345203955Srdivacky        IdentifierInfo *Name2 = Enum2->getIdentifier();
1346221345Sdim        if (!Name2 && Enum2->getTypedefNameForAnonDecl())
1347221345Sdim          Name2 = Enum2->getTypedefNameForAnonDecl()->getIdentifier();
1348203955Srdivacky        if (!::IsStructurallyEquivalent(Name1, Name2) ||
1349203955Srdivacky            !::IsStructurallyEquivalent(*this, Enum1, Enum2))
1350203955Srdivacky          Equivalent = false;
1351203955Srdivacky      } else {
1352203955Srdivacky        // Enum/non-enum mismatch
1353203955Srdivacky        Equivalent = false;
1354203955Srdivacky      }
1355221345Sdim    } else if (TypedefNameDecl *Typedef1 = dyn_cast<TypedefNameDecl>(D1)) {
1356221345Sdim      if (TypedefNameDecl *Typedef2 = dyn_cast<TypedefNameDecl>(D2)) {
1357203955Srdivacky        if (!::IsStructurallyEquivalent(Typedef1->getIdentifier(),
1358203955Srdivacky                                        Typedef2->getIdentifier()) ||
1359203955Srdivacky            !::IsStructurallyEquivalent(*this,
1360203955Srdivacky                                        Typedef1->getUnderlyingType(),
1361203955Srdivacky                                        Typedef2->getUnderlyingType()))
1362203955Srdivacky          Equivalent = false;
1363203955Srdivacky      } else {
1364203955Srdivacky        // Typedef/non-typedef mismatch.
1365203955Srdivacky        Equivalent = false;
1366203955Srdivacky      }
1367218893Sdim    } else if (ClassTemplateDecl *ClassTemplate1
1368218893Sdim                                           = dyn_cast<ClassTemplateDecl>(D1)) {
1369218893Sdim      if (ClassTemplateDecl *ClassTemplate2 = dyn_cast<ClassTemplateDecl>(D2)) {
1370218893Sdim        if (!::IsStructurallyEquivalent(ClassTemplate1->getIdentifier(),
1371218893Sdim                                        ClassTemplate2->getIdentifier()) ||
1372218893Sdim            !::IsStructurallyEquivalent(*this, ClassTemplate1, ClassTemplate2))
1373218893Sdim          Equivalent = false;
1374218893Sdim      } else {
1375218893Sdim        // Class template/non-class-template mismatch.
1376218893Sdim        Equivalent = false;
1377218893Sdim      }
1378218893Sdim    } else if (TemplateTypeParmDecl *TTP1= dyn_cast<TemplateTypeParmDecl>(D1)) {
1379218893Sdim      if (TemplateTypeParmDecl *TTP2 = dyn_cast<TemplateTypeParmDecl>(D2)) {
1380218893Sdim        if (!::IsStructurallyEquivalent(*this, TTP1, TTP2))
1381218893Sdim          Equivalent = false;
1382218893Sdim      } else {
1383218893Sdim        // Kind mismatch.
1384218893Sdim        Equivalent = false;
1385218893Sdim      }
1386218893Sdim    } else if (NonTypeTemplateParmDecl *NTTP1
1387218893Sdim                                     = dyn_cast<NonTypeTemplateParmDecl>(D1)) {
1388218893Sdim      if (NonTypeTemplateParmDecl *NTTP2
1389218893Sdim                                      = dyn_cast<NonTypeTemplateParmDecl>(D2)) {
1390218893Sdim        if (!::IsStructurallyEquivalent(*this, NTTP1, NTTP2))
1391218893Sdim          Equivalent = false;
1392218893Sdim      } else {
1393218893Sdim        // Kind mismatch.
1394218893Sdim        Equivalent = false;
1395218893Sdim      }
1396218893Sdim    } else if (TemplateTemplateParmDecl *TTP1
1397218893Sdim                                  = dyn_cast<TemplateTemplateParmDecl>(D1)) {
1398218893Sdim      if (TemplateTemplateParmDecl *TTP2
1399218893Sdim                                    = dyn_cast<TemplateTemplateParmDecl>(D2)) {
1400218893Sdim        if (!::IsStructurallyEquivalent(*this, TTP1, TTP2))
1401218893Sdim          Equivalent = false;
1402218893Sdim      } else {
1403218893Sdim        // Kind mismatch.
1404218893Sdim        Equivalent = false;
1405218893Sdim      }
1406218893Sdim    }
1407218893Sdim
1408203955Srdivacky    if (!Equivalent) {
1409203955Srdivacky      // Note that these two declarations are not equivalent (and we already
1410203955Srdivacky      // know about it).
1411203955Srdivacky      NonEquivalentDecls.insert(std::make_pair(D1->getCanonicalDecl(),
1412203955Srdivacky                                               D2->getCanonicalDecl()));
1413203955Srdivacky      return true;
1414203955Srdivacky    }
1415203955Srdivacky    // FIXME: Check other declaration kinds!
1416203955Srdivacky  }
1417203955Srdivacky
1418203955Srdivacky  return false;
1419203955Srdivacky}
1420203955Srdivacky
1421203955Srdivacky//----------------------------------------------------------------------------
1422203955Srdivacky// Import Types
1423203955Srdivacky//----------------------------------------------------------------------------
1424203955Srdivacky
1425218893SdimQualType ASTNodeImporter::VisitType(const Type *T) {
1426203955Srdivacky  Importer.FromDiag(SourceLocation(), diag::err_unsupported_ast_node)
1427203955Srdivacky    << T->getTypeClassName();
1428203955Srdivacky  return QualType();
1429203955Srdivacky}
1430203955Srdivacky
1431218893SdimQualType ASTNodeImporter::VisitBuiltinType(const BuiltinType *T) {
1432203955Srdivacky  switch (T->getKind()) {
1433235633Sdim#define SHARED_SINGLETON_TYPE(Expansion)
1434235633Sdim#define BUILTIN_TYPE(Id, SingletonId) \
1435235633Sdim  case BuiltinType::Id: return Importer.getToContext().SingletonId;
1436235633Sdim#include "clang/AST/BuiltinTypes.def"
1437235633Sdim
1438235633Sdim  // FIXME: for Char16, Char32, and NullPtr, make sure that the "to"
1439235633Sdim  // context supports C++.
1440235633Sdim
1441235633Sdim  // FIXME: for ObjCId, ObjCClass, and ObjCSel, make sure that the "to"
1442235633Sdim  // context supports ObjC.
1443235633Sdim
1444203955Srdivacky  case BuiltinType::Char_U:
1445203955Srdivacky    // The context we're importing from has an unsigned 'char'. If we're
1446203955Srdivacky    // importing into a context with a signed 'char', translate to
1447203955Srdivacky    // 'unsigned char' instead.
1448235633Sdim    if (Importer.getToContext().getLangOpts().CharIsSigned)
1449203955Srdivacky      return Importer.getToContext().UnsignedCharTy;
1450203955Srdivacky
1451203955Srdivacky    return Importer.getToContext().CharTy;
1452203955Srdivacky
1453203955Srdivacky  case BuiltinType::Char_S:
1454203955Srdivacky    // The context we're importing from has an unsigned 'char'. If we're
1455203955Srdivacky    // importing into a context with a signed 'char', translate to
1456203955Srdivacky    // 'unsigned char' instead.
1457235633Sdim    if (!Importer.getToContext().getLangOpts().CharIsSigned)
1458203955Srdivacky      return Importer.getToContext().SignedCharTy;
1459203955Srdivacky
1460203955Srdivacky    return Importer.getToContext().CharTy;
1461203955Srdivacky
1462218893Sdim  case BuiltinType::WChar_S:
1463218893Sdim  case BuiltinType::WChar_U:
1464203955Srdivacky    // FIXME: If not in C++, shall we translate to the C equivalent of
1465203955Srdivacky    // wchar_t?
1466203955Srdivacky    return Importer.getToContext().WCharTy;
1467235633Sdim  }
1468203955Srdivacky
1469235633Sdim  llvm_unreachable("Invalid BuiltinType Kind!");
1470203955Srdivacky}
1471203955Srdivacky
1472218893SdimQualType ASTNodeImporter::VisitComplexType(const ComplexType *T) {
1473203955Srdivacky  QualType ToElementType = Importer.Import(T->getElementType());
1474203955Srdivacky  if (ToElementType.isNull())
1475203955Srdivacky    return QualType();
1476203955Srdivacky
1477203955Srdivacky  return Importer.getToContext().getComplexType(ToElementType);
1478203955Srdivacky}
1479203955Srdivacky
1480218893SdimQualType ASTNodeImporter::VisitPointerType(const PointerType *T) {
1481203955Srdivacky  QualType ToPointeeType = Importer.Import(T->getPointeeType());
1482203955Srdivacky  if (ToPointeeType.isNull())
1483203955Srdivacky    return QualType();
1484203955Srdivacky
1485203955Srdivacky  return Importer.getToContext().getPointerType(ToPointeeType);
1486203955Srdivacky}
1487203955Srdivacky
1488218893SdimQualType ASTNodeImporter::VisitBlockPointerType(const BlockPointerType *T) {
1489203955Srdivacky  // FIXME: Check for blocks support in "to" context.
1490203955Srdivacky  QualType ToPointeeType = Importer.Import(T->getPointeeType());
1491203955Srdivacky  if (ToPointeeType.isNull())
1492203955Srdivacky    return QualType();
1493203955Srdivacky
1494203955Srdivacky  return Importer.getToContext().getBlockPointerType(ToPointeeType);
1495203955Srdivacky}
1496203955Srdivacky
1497218893SdimQualType
1498218893SdimASTNodeImporter::VisitLValueReferenceType(const LValueReferenceType *T) {
1499203955Srdivacky  // FIXME: Check for C++ support in "to" context.
1500203955Srdivacky  QualType ToPointeeType = Importer.Import(T->getPointeeTypeAsWritten());
1501203955Srdivacky  if (ToPointeeType.isNull())
1502203955Srdivacky    return QualType();
1503203955Srdivacky
1504203955Srdivacky  return Importer.getToContext().getLValueReferenceType(ToPointeeType);
1505203955Srdivacky}
1506203955Srdivacky
1507218893SdimQualType
1508218893SdimASTNodeImporter::VisitRValueReferenceType(const RValueReferenceType *T) {
1509203955Srdivacky  // FIXME: Check for C++0x support in "to" context.
1510203955Srdivacky  QualType ToPointeeType = Importer.Import(T->getPointeeTypeAsWritten());
1511203955Srdivacky  if (ToPointeeType.isNull())
1512203955Srdivacky    return QualType();
1513203955Srdivacky
1514203955Srdivacky  return Importer.getToContext().getRValueReferenceType(ToPointeeType);
1515203955Srdivacky}
1516203955Srdivacky
1517218893SdimQualType ASTNodeImporter::VisitMemberPointerType(const MemberPointerType *T) {
1518203955Srdivacky  // FIXME: Check for C++ support in "to" context.
1519203955Srdivacky  QualType ToPointeeType = Importer.Import(T->getPointeeType());
1520203955Srdivacky  if (ToPointeeType.isNull())
1521203955Srdivacky    return QualType();
1522203955Srdivacky
1523203955Srdivacky  QualType ClassType = Importer.Import(QualType(T->getClass(), 0));
1524203955Srdivacky  return Importer.getToContext().getMemberPointerType(ToPointeeType,
1525203955Srdivacky                                                      ClassType.getTypePtr());
1526203955Srdivacky}
1527203955Srdivacky
1528218893SdimQualType ASTNodeImporter::VisitConstantArrayType(const ConstantArrayType *T) {
1529203955Srdivacky  QualType ToElementType = Importer.Import(T->getElementType());
1530203955Srdivacky  if (ToElementType.isNull())
1531203955Srdivacky    return QualType();
1532203955Srdivacky
1533203955Srdivacky  return Importer.getToContext().getConstantArrayType(ToElementType,
1534203955Srdivacky                                                      T->getSize(),
1535203955Srdivacky                                                      T->getSizeModifier(),
1536203955Srdivacky                                               T->getIndexTypeCVRQualifiers());
1537203955Srdivacky}
1538203955Srdivacky
1539218893SdimQualType
1540218893SdimASTNodeImporter::VisitIncompleteArrayType(const IncompleteArrayType *T) {
1541203955Srdivacky  QualType ToElementType = Importer.Import(T->getElementType());
1542203955Srdivacky  if (ToElementType.isNull())
1543203955Srdivacky    return QualType();
1544203955Srdivacky
1545203955Srdivacky  return Importer.getToContext().getIncompleteArrayType(ToElementType,
1546203955Srdivacky                                                        T->getSizeModifier(),
1547203955Srdivacky                                                T->getIndexTypeCVRQualifiers());
1548203955Srdivacky}
1549203955Srdivacky
1550218893SdimQualType ASTNodeImporter::VisitVariableArrayType(const VariableArrayType *T) {
1551203955Srdivacky  QualType ToElementType = Importer.Import(T->getElementType());
1552203955Srdivacky  if (ToElementType.isNull())
1553203955Srdivacky    return QualType();
1554203955Srdivacky
1555203955Srdivacky  Expr *Size = Importer.Import(T->getSizeExpr());
1556203955Srdivacky  if (!Size)
1557203955Srdivacky    return QualType();
1558203955Srdivacky
1559203955Srdivacky  SourceRange Brackets = Importer.Import(T->getBracketsRange());
1560203955Srdivacky  return Importer.getToContext().getVariableArrayType(ToElementType, Size,
1561203955Srdivacky                                                      T->getSizeModifier(),
1562203955Srdivacky                                                T->getIndexTypeCVRQualifiers(),
1563203955Srdivacky                                                      Brackets);
1564203955Srdivacky}
1565203955Srdivacky
1566218893SdimQualType ASTNodeImporter::VisitVectorType(const VectorType *T) {
1567203955Srdivacky  QualType ToElementType = Importer.Import(T->getElementType());
1568203955Srdivacky  if (ToElementType.isNull())
1569203955Srdivacky    return QualType();
1570203955Srdivacky
1571203955Srdivacky  return Importer.getToContext().getVectorType(ToElementType,
1572203955Srdivacky                                               T->getNumElements(),
1573218893Sdim                                               T->getVectorKind());
1574203955Srdivacky}
1575203955Srdivacky
1576218893SdimQualType ASTNodeImporter::VisitExtVectorType(const ExtVectorType *T) {
1577203955Srdivacky  QualType ToElementType = Importer.Import(T->getElementType());
1578203955Srdivacky  if (ToElementType.isNull())
1579203955Srdivacky    return QualType();
1580203955Srdivacky
1581203955Srdivacky  return Importer.getToContext().getExtVectorType(ToElementType,
1582203955Srdivacky                                                  T->getNumElements());
1583203955Srdivacky}
1584203955Srdivacky
1585218893SdimQualType
1586218893SdimASTNodeImporter::VisitFunctionNoProtoType(const FunctionNoProtoType *T) {
1587203955Srdivacky  // FIXME: What happens if we're importing a function without a prototype
1588203955Srdivacky  // into C++? Should we make it variadic?
1589203955Srdivacky  QualType ToResultType = Importer.Import(T->getResultType());
1590203955Srdivacky  if (ToResultType.isNull())
1591203955Srdivacky    return QualType();
1592206084Srdivacky
1593203955Srdivacky  return Importer.getToContext().getFunctionNoProtoType(ToResultType,
1594206084Srdivacky                                                        T->getExtInfo());
1595203955Srdivacky}
1596203955Srdivacky
1597218893SdimQualType ASTNodeImporter::VisitFunctionProtoType(const FunctionProtoType *T) {
1598203955Srdivacky  QualType ToResultType = Importer.Import(T->getResultType());
1599203955Srdivacky  if (ToResultType.isNull())
1600203955Srdivacky    return QualType();
1601203955Srdivacky
1602203955Srdivacky  // Import argument types
1603226890Sdim  SmallVector<QualType, 4> ArgTypes;
1604203955Srdivacky  for (FunctionProtoType::arg_type_iterator A = T->arg_type_begin(),
1605203955Srdivacky                                         AEnd = T->arg_type_end();
1606203955Srdivacky       A != AEnd; ++A) {
1607203955Srdivacky    QualType ArgType = Importer.Import(*A);
1608203955Srdivacky    if (ArgType.isNull())
1609203955Srdivacky      return QualType();
1610203955Srdivacky    ArgTypes.push_back(ArgType);
1611203955Srdivacky  }
1612203955Srdivacky
1613203955Srdivacky  // Import exception types
1614226890Sdim  SmallVector<QualType, 4> ExceptionTypes;
1615203955Srdivacky  for (FunctionProtoType::exception_iterator E = T->exception_begin(),
1616203955Srdivacky                                          EEnd = T->exception_end();
1617203955Srdivacky       E != EEnd; ++E) {
1618203955Srdivacky    QualType ExceptionType = Importer.Import(*E);
1619203955Srdivacky    if (ExceptionType.isNull())
1620203955Srdivacky      return QualType();
1621203955Srdivacky    ExceptionTypes.push_back(ExceptionType);
1622203955Srdivacky  }
1623218893Sdim
1624245431Sdim  FunctionProtoType::ExtProtoInfo FromEPI = T->getExtProtoInfo();
1625245431Sdim  FunctionProtoType::ExtProtoInfo ToEPI;
1626245431Sdim
1627245431Sdim  ToEPI.ExtInfo = FromEPI.ExtInfo;
1628245431Sdim  ToEPI.Variadic = FromEPI.Variadic;
1629245431Sdim  ToEPI.HasTrailingReturn = FromEPI.HasTrailingReturn;
1630245431Sdim  ToEPI.TypeQuals = FromEPI.TypeQuals;
1631245431Sdim  ToEPI.RefQualifier = FromEPI.RefQualifier;
1632245431Sdim  ToEPI.NumExceptions = ExceptionTypes.size();
1633245431Sdim  ToEPI.Exceptions = ExceptionTypes.data();
1634245431Sdim  ToEPI.ConsumedArguments = FromEPI.ConsumedArguments;
1635245431Sdim  ToEPI.ExceptionSpecType = FromEPI.ExceptionSpecType;
1636245431Sdim  ToEPI.NoexceptExpr = Importer.Import(FromEPI.NoexceptExpr);
1637245431Sdim  ToEPI.ExceptionSpecDecl = cast_or_null<FunctionDecl>(
1638245431Sdim                                Importer.Import(FromEPI.ExceptionSpecDecl));
1639245431Sdim  ToEPI.ExceptionSpecTemplate = cast_or_null<FunctionDecl>(
1640245431Sdim                                Importer.Import(FromEPI.ExceptionSpecTemplate));
1641245431Sdim
1642252723Sdim  return Importer.getToContext().getFunctionType(ToResultType, ArgTypes, ToEPI);
1643203955Srdivacky}
1644203955Srdivacky
1645226890SdimQualType ASTNodeImporter::VisitParenType(const ParenType *T) {
1646226890Sdim  QualType ToInnerType = Importer.Import(T->getInnerType());
1647226890Sdim  if (ToInnerType.isNull())
1648226890Sdim    return QualType();
1649226890Sdim
1650226890Sdim  return Importer.getToContext().getParenType(ToInnerType);
1651226890Sdim}
1652226890Sdim
1653218893SdimQualType ASTNodeImporter::VisitTypedefType(const TypedefType *T) {
1654221345Sdim  TypedefNameDecl *ToDecl
1655221345Sdim             = dyn_cast_or_null<TypedefNameDecl>(Importer.Import(T->getDecl()));
1656203955Srdivacky  if (!ToDecl)
1657203955Srdivacky    return QualType();
1658203955Srdivacky
1659203955Srdivacky  return Importer.getToContext().getTypeDeclType(ToDecl);
1660203955Srdivacky}
1661203955Srdivacky
1662218893SdimQualType ASTNodeImporter::VisitTypeOfExprType(const TypeOfExprType *T) {
1663203955Srdivacky  Expr *ToExpr = Importer.Import(T->getUnderlyingExpr());
1664203955Srdivacky  if (!ToExpr)
1665203955Srdivacky    return QualType();
1666203955Srdivacky
1667203955Srdivacky  return Importer.getToContext().getTypeOfExprType(ToExpr);
1668203955Srdivacky}
1669203955Srdivacky
1670218893SdimQualType ASTNodeImporter::VisitTypeOfType(const TypeOfType *T) {
1671203955Srdivacky  QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType());
1672203955Srdivacky  if (ToUnderlyingType.isNull())
1673203955Srdivacky    return QualType();
1674203955Srdivacky
1675203955Srdivacky  return Importer.getToContext().getTypeOfType(ToUnderlyingType);
1676203955Srdivacky}
1677203955Srdivacky
1678218893SdimQualType ASTNodeImporter::VisitDecltypeType(const DecltypeType *T) {
1679218893Sdim  // FIXME: Make sure that the "to" context supports C++0x!
1680203955Srdivacky  Expr *ToExpr = Importer.Import(T->getUnderlyingExpr());
1681203955Srdivacky  if (!ToExpr)
1682203955Srdivacky    return QualType();
1683203955Srdivacky
1684235633Sdim  QualType UnderlyingType = Importer.Import(T->getUnderlyingType());
1685235633Sdim  if (UnderlyingType.isNull())
1686235633Sdim    return QualType();
1687235633Sdim
1688235633Sdim  return Importer.getToContext().getDecltypeType(ToExpr, UnderlyingType);
1689203955Srdivacky}
1690203955Srdivacky
1691223017SdimQualType ASTNodeImporter::VisitUnaryTransformType(const UnaryTransformType *T) {
1692223017Sdim  QualType ToBaseType = Importer.Import(T->getBaseType());
1693223017Sdim  QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType());
1694223017Sdim  if (ToBaseType.isNull() || ToUnderlyingType.isNull())
1695223017Sdim    return QualType();
1696223017Sdim
1697223017Sdim  return Importer.getToContext().getUnaryTransformType(ToBaseType,
1698223017Sdim                                                       ToUnderlyingType,
1699223017Sdim                                                       T->getUTTKind());
1700223017Sdim}
1701223017Sdim
1702218893SdimQualType ASTNodeImporter::VisitAutoType(const AutoType *T) {
1703252723Sdim  // FIXME: Make sure that the "to" context supports C++11!
1704218893Sdim  QualType FromDeduced = T->getDeducedType();
1705218893Sdim  QualType ToDeduced;
1706218893Sdim  if (!FromDeduced.isNull()) {
1707218893Sdim    ToDeduced = Importer.Import(FromDeduced);
1708218893Sdim    if (ToDeduced.isNull())
1709218893Sdim      return QualType();
1710218893Sdim  }
1711218893Sdim
1712263509Sdim  return Importer.getToContext().getAutoType(ToDeduced, T->isDecltypeAuto(),
1713263509Sdim                                             /*IsDependent*/false);
1714218893Sdim}
1715218893Sdim
1716218893SdimQualType ASTNodeImporter::VisitRecordType(const RecordType *T) {
1717203955Srdivacky  RecordDecl *ToDecl
1718203955Srdivacky    = dyn_cast_or_null<RecordDecl>(Importer.Import(T->getDecl()));
1719203955Srdivacky  if (!ToDecl)
1720203955Srdivacky    return QualType();
1721203955Srdivacky
1722203955Srdivacky  return Importer.getToContext().getTagDeclType(ToDecl);
1723203955Srdivacky}
1724203955Srdivacky
1725218893SdimQualType ASTNodeImporter::VisitEnumType(const EnumType *T) {
1726203955Srdivacky  EnumDecl *ToDecl
1727203955Srdivacky    = dyn_cast_or_null<EnumDecl>(Importer.Import(T->getDecl()));
1728203955Srdivacky  if (!ToDecl)
1729203955Srdivacky    return QualType();
1730203955Srdivacky
1731203955Srdivacky  return Importer.getToContext().getTagDeclType(ToDecl);
1732203955Srdivacky}
1733203955Srdivacky
1734218893SdimQualType ASTNodeImporter::VisitTemplateSpecializationType(
1735218893Sdim                                       const TemplateSpecializationType *T) {
1736218893Sdim  TemplateName ToTemplate = Importer.Import(T->getTemplateName());
1737218893Sdim  if (ToTemplate.isNull())
1738218893Sdim    return QualType();
1739218893Sdim
1740226890Sdim  SmallVector<TemplateArgument, 2> ToTemplateArgs;
1741218893Sdim  if (ImportTemplateArguments(T->getArgs(), T->getNumArgs(), ToTemplateArgs))
1742218893Sdim    return QualType();
1743218893Sdim
1744218893Sdim  QualType ToCanonType;
1745218893Sdim  if (!QualType(T, 0).isCanonical()) {
1746218893Sdim    QualType FromCanonType
1747218893Sdim      = Importer.getFromContext().getCanonicalType(QualType(T, 0));
1748218893Sdim    ToCanonType =Importer.Import(FromCanonType);
1749218893Sdim    if (ToCanonType.isNull())
1750218893Sdim      return QualType();
1751218893Sdim  }
1752218893Sdim  return Importer.getToContext().getTemplateSpecializationType(ToTemplate,
1753218893Sdim                                                         ToTemplateArgs.data(),
1754218893Sdim                                                         ToTemplateArgs.size(),
1755218893Sdim                                                               ToCanonType);
1756218893Sdim}
1757218893Sdim
1758218893SdimQualType ASTNodeImporter::VisitElaboratedType(const ElaboratedType *T) {
1759208600Srdivacky  NestedNameSpecifier *ToQualifier = 0;
1760208600Srdivacky  // Note: the qualifier in an ElaboratedType is optional.
1761208600Srdivacky  if (T->getQualifier()) {
1762208600Srdivacky    ToQualifier = Importer.Import(T->getQualifier());
1763208600Srdivacky    if (!ToQualifier)
1764208600Srdivacky      return QualType();
1765208600Srdivacky  }
1766203955Srdivacky
1767203955Srdivacky  QualType ToNamedType = Importer.Import(T->getNamedType());
1768203955Srdivacky  if (ToNamedType.isNull())
1769203955Srdivacky    return QualType();
1770203955Srdivacky
1771208600Srdivacky  return Importer.getToContext().getElaboratedType(T->getKeyword(),
1772208600Srdivacky                                                   ToQualifier, ToNamedType);
1773203955Srdivacky}
1774203955Srdivacky
1775218893SdimQualType ASTNodeImporter::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
1776203955Srdivacky  ObjCInterfaceDecl *Class
1777203955Srdivacky    = dyn_cast_or_null<ObjCInterfaceDecl>(Importer.Import(T->getDecl()));
1778203955Srdivacky  if (!Class)
1779203955Srdivacky    return QualType();
1780203955Srdivacky
1781208600Srdivacky  return Importer.getToContext().getObjCInterfaceType(Class);
1782208600Srdivacky}
1783208600Srdivacky
1784218893SdimQualType ASTNodeImporter::VisitObjCObjectType(const ObjCObjectType *T) {
1785208600Srdivacky  QualType ToBaseType = Importer.Import(T->getBaseType());
1786208600Srdivacky  if (ToBaseType.isNull())
1787208600Srdivacky    return QualType();
1788208600Srdivacky
1789226890Sdim  SmallVector<ObjCProtocolDecl *, 4> Protocols;
1790208600Srdivacky  for (ObjCObjectType::qual_iterator P = T->qual_begin(),
1791203955Srdivacky                                     PEnd = T->qual_end();
1792203955Srdivacky       P != PEnd; ++P) {
1793203955Srdivacky    ObjCProtocolDecl *Protocol
1794203955Srdivacky      = dyn_cast_or_null<ObjCProtocolDecl>(Importer.Import(*P));
1795203955Srdivacky    if (!Protocol)
1796203955Srdivacky      return QualType();
1797203955Srdivacky    Protocols.push_back(Protocol);
1798203955Srdivacky  }
1799203955Srdivacky
1800208600Srdivacky  return Importer.getToContext().getObjCObjectType(ToBaseType,
1801208600Srdivacky                                                   Protocols.data(),
1802208600Srdivacky                                                   Protocols.size());
1803203955Srdivacky}
1804203955Srdivacky
1805218893SdimQualType
1806218893SdimASTNodeImporter::VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
1807203955Srdivacky  QualType ToPointeeType = Importer.Import(T->getPointeeType());
1808203955Srdivacky  if (ToPointeeType.isNull())
1809203955Srdivacky    return QualType();
1810203955Srdivacky
1811208600Srdivacky  return Importer.getToContext().getObjCObjectPointerType(ToPointeeType);
1812203955Srdivacky}
1813203955Srdivacky
1814203955Srdivacky//----------------------------------------------------------------------------
1815203955Srdivacky// Import Declarations
1816203955Srdivacky//----------------------------------------------------------------------------
1817203955Srdivackybool ASTNodeImporter::ImportDeclParts(NamedDecl *D, DeclContext *&DC,
1818203955Srdivacky                                      DeclContext *&LexicalDC,
1819203955Srdivacky                                      DeclarationName &Name,
1820203955Srdivacky                                      SourceLocation &Loc) {
1821203955Srdivacky  // Import the context of this declaration.
1822203955Srdivacky  DC = Importer.ImportContext(D->getDeclContext());
1823203955Srdivacky  if (!DC)
1824203955Srdivacky    return true;
1825203955Srdivacky
1826203955Srdivacky  LexicalDC = DC;
1827203955Srdivacky  if (D->getDeclContext() != D->getLexicalDeclContext()) {
1828203955Srdivacky    LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
1829203955Srdivacky    if (!LexicalDC)
1830203955Srdivacky      return true;
1831203955Srdivacky  }
1832203955Srdivacky
1833203955Srdivacky  // Import the name of this declaration.
1834203955Srdivacky  Name = Importer.Import(D->getDeclName());
1835203955Srdivacky  if (D->getDeclName() && !Name)
1836203955Srdivacky    return true;
1837203955Srdivacky
1838203955Srdivacky  // Import the location of this declaration.
1839203955Srdivacky  Loc = Importer.Import(D->getLocation());
1840203955Srdivacky  return false;
1841203955Srdivacky}
1842203955Srdivacky
1843226890Sdimvoid ASTNodeImporter::ImportDefinitionIfNeeded(Decl *FromD, Decl *ToD) {
1844226890Sdim  if (!FromD)
1845226890Sdim    return;
1846226890Sdim
1847226890Sdim  if (!ToD) {
1848226890Sdim    ToD = Importer.Import(FromD);
1849226890Sdim    if (!ToD)
1850226890Sdim      return;
1851226890Sdim  }
1852226890Sdim
1853226890Sdim  if (RecordDecl *FromRecord = dyn_cast<RecordDecl>(FromD)) {
1854226890Sdim    if (RecordDecl *ToRecord = cast_or_null<RecordDecl>(ToD)) {
1855252723Sdim      if (FromRecord->getDefinition() && FromRecord->isCompleteDefinition() && !ToRecord->getDefinition()) {
1856226890Sdim        ImportDefinition(FromRecord, ToRecord);
1857226890Sdim      }
1858226890Sdim    }
1859226890Sdim    return;
1860226890Sdim  }
1861226890Sdim
1862226890Sdim  if (EnumDecl *FromEnum = dyn_cast<EnumDecl>(FromD)) {
1863226890Sdim    if (EnumDecl *ToEnum = cast_or_null<EnumDecl>(ToD)) {
1864226890Sdim      if (FromEnum->getDefinition() && !ToEnum->getDefinition()) {
1865226890Sdim        ImportDefinition(FromEnum, ToEnum);
1866226890Sdim      }
1867226890Sdim    }
1868226890Sdim    return;
1869226890Sdim  }
1870226890Sdim}
1871226890Sdim
1872212904Sdimvoid
1873212904SdimASTNodeImporter::ImportDeclarationNameLoc(const DeclarationNameInfo &From,
1874212904Sdim                                          DeclarationNameInfo& To) {
1875212904Sdim  // NOTE: To.Name and To.Loc are already imported.
1876212904Sdim  // We only have to import To.LocInfo.
1877212904Sdim  switch (To.getName().getNameKind()) {
1878212904Sdim  case DeclarationName::Identifier:
1879212904Sdim  case DeclarationName::ObjCZeroArgSelector:
1880212904Sdim  case DeclarationName::ObjCOneArgSelector:
1881212904Sdim  case DeclarationName::ObjCMultiArgSelector:
1882212904Sdim  case DeclarationName::CXXUsingDirective:
1883212904Sdim    return;
1884212904Sdim
1885212904Sdim  case DeclarationName::CXXOperatorName: {
1886212904Sdim    SourceRange Range = From.getCXXOperatorNameRange();
1887212904Sdim    To.setCXXOperatorNameRange(Importer.Import(Range));
1888212904Sdim    return;
1889212904Sdim  }
1890212904Sdim  case DeclarationName::CXXLiteralOperatorName: {
1891212904Sdim    SourceLocation Loc = From.getCXXLiteralOperatorNameLoc();
1892212904Sdim    To.setCXXLiteralOperatorNameLoc(Importer.Import(Loc));
1893212904Sdim    return;
1894212904Sdim  }
1895212904Sdim  case DeclarationName::CXXConstructorName:
1896212904Sdim  case DeclarationName::CXXDestructorName:
1897212904Sdim  case DeclarationName::CXXConversionFunctionName: {
1898212904Sdim    TypeSourceInfo *FromTInfo = From.getNamedTypeInfo();
1899212904Sdim    To.setNamedTypeInfo(Importer.Import(FromTInfo));
1900212904Sdim    return;
1901212904Sdim  }
1902212904Sdim  }
1903235633Sdim  llvm_unreachable("Unknown name kind.");
1904212904Sdim}
1905212904Sdim
1906235633Sdimvoid ASTNodeImporter::ImportDeclContext(DeclContext *FromDC, bool ForceImport) {
1907218893Sdim  if (Importer.isMinimalImport() && !ForceImport) {
1908226890Sdim    Importer.ImportContext(FromDC);
1909218893Sdim    return;
1910218893Sdim  }
1911218893Sdim
1912204643Srdivacky  for (DeclContext::decl_iterator From = FromDC->decls_begin(),
1913204643Srdivacky                               FromEnd = FromDC->decls_end();
1914204643Srdivacky       From != FromEnd;
1915204643Srdivacky       ++From)
1916204643Srdivacky    Importer.Import(*From);
1917204643Srdivacky}
1918204643Srdivacky
1919226890Sdimbool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To,
1920235633Sdim                                       ImportDefinitionKind Kind) {
1921235633Sdim  if (To->getDefinition() || To->isBeingDefined()) {
1922235633Sdim    if (Kind == IDK_Everything)
1923235633Sdim      ImportDeclContext(From, /*ForceImport=*/true);
1924235633Sdim
1925218893Sdim    return false;
1926235633Sdim  }
1927218893Sdim
1928218893Sdim  To->startDefinition();
1929218893Sdim
1930218893Sdim  // Add base classes.
1931218893Sdim  if (CXXRecordDecl *ToCXX = dyn_cast<CXXRecordDecl>(To)) {
1932218893Sdim    CXXRecordDecl *FromCXX = cast<CXXRecordDecl>(From);
1933235633Sdim
1934235633Sdim    struct CXXRecordDecl::DefinitionData &ToData = ToCXX->data();
1935235633Sdim    struct CXXRecordDecl::DefinitionData &FromData = FromCXX->data();
1936235633Sdim    ToData.UserDeclaredConstructor = FromData.UserDeclaredConstructor;
1937252723Sdim    ToData.UserDeclaredSpecialMembers = FromData.UserDeclaredSpecialMembers;
1938235633Sdim    ToData.Aggregate = FromData.Aggregate;
1939235633Sdim    ToData.PlainOldData = FromData.PlainOldData;
1940235633Sdim    ToData.Empty = FromData.Empty;
1941235633Sdim    ToData.Polymorphic = FromData.Polymorphic;
1942235633Sdim    ToData.Abstract = FromData.Abstract;
1943235633Sdim    ToData.IsStandardLayout = FromData.IsStandardLayout;
1944235633Sdim    ToData.HasNoNonEmptyBases = FromData.HasNoNonEmptyBases;
1945235633Sdim    ToData.HasPrivateFields = FromData.HasPrivateFields;
1946235633Sdim    ToData.HasProtectedFields = FromData.HasProtectedFields;
1947235633Sdim    ToData.HasPublicFields = FromData.HasPublicFields;
1948235633Sdim    ToData.HasMutableFields = FromData.HasMutableFields;
1949235633Sdim    ToData.HasOnlyCMembers = FromData.HasOnlyCMembers;
1950245431Sdim    ToData.HasInClassInitializer = FromData.HasInClassInitializer;
1951252723Sdim    ToData.HasUninitializedReferenceMember
1952252723Sdim      = FromData.HasUninitializedReferenceMember;
1953252723Sdim    ToData.NeedOverloadResolutionForMoveConstructor
1954252723Sdim      = FromData.NeedOverloadResolutionForMoveConstructor;
1955252723Sdim    ToData.NeedOverloadResolutionForMoveAssignment
1956252723Sdim      = FromData.NeedOverloadResolutionForMoveAssignment;
1957252723Sdim    ToData.NeedOverloadResolutionForDestructor
1958252723Sdim      = FromData.NeedOverloadResolutionForDestructor;
1959252723Sdim    ToData.DefaultedMoveConstructorIsDeleted
1960252723Sdim      = FromData.DefaultedMoveConstructorIsDeleted;
1961252723Sdim    ToData.DefaultedMoveAssignmentIsDeleted
1962252723Sdim      = FromData.DefaultedMoveAssignmentIsDeleted;
1963252723Sdim    ToData.DefaultedDestructorIsDeleted = FromData.DefaultedDestructorIsDeleted;
1964252723Sdim    ToData.HasTrivialSpecialMembers = FromData.HasTrivialSpecialMembers;
1965252723Sdim    ToData.HasIrrelevantDestructor = FromData.HasIrrelevantDestructor;
1966235633Sdim    ToData.HasConstexprNonCopyMoveConstructor
1967235633Sdim      = FromData.HasConstexprNonCopyMoveConstructor;
1968235633Sdim    ToData.DefaultedDefaultConstructorIsConstexpr
1969235633Sdim      = FromData.DefaultedDefaultConstructorIsConstexpr;
1970235633Sdim    ToData.HasConstexprDefaultConstructor
1971235633Sdim      = FromData.HasConstexprDefaultConstructor;
1972235633Sdim    ToData.HasNonLiteralTypeFieldsOrBases
1973235633Sdim      = FromData.HasNonLiteralTypeFieldsOrBases;
1974235633Sdim    // ComputedVisibleConversions not imported.
1975235633Sdim    ToData.UserProvidedDefaultConstructor
1976235633Sdim      = FromData.UserProvidedDefaultConstructor;
1977252723Sdim    ToData.DeclaredSpecialMembers = FromData.DeclaredSpecialMembers;
1978252723Sdim    ToData.ImplicitCopyConstructorHasConstParam
1979252723Sdim      = FromData.ImplicitCopyConstructorHasConstParam;
1980252723Sdim    ToData.ImplicitCopyAssignmentHasConstParam
1981252723Sdim      = FromData.ImplicitCopyAssignmentHasConstParam;
1982252723Sdim    ToData.HasDeclaredCopyConstructorWithConstParam
1983252723Sdim      = FromData.HasDeclaredCopyConstructorWithConstParam;
1984252723Sdim    ToData.HasDeclaredCopyAssignmentWithConstParam
1985252723Sdim      = FromData.HasDeclaredCopyAssignmentWithConstParam;
1986235633Sdim    ToData.IsLambda = FromData.IsLambda;
1987235633Sdim
1988226890Sdim    SmallVector<CXXBaseSpecifier *, 4> Bases;
1989218893Sdim    for (CXXRecordDecl::base_class_iterator
1990218893Sdim                  Base1 = FromCXX->bases_begin(),
1991218893Sdim            FromBaseEnd = FromCXX->bases_end();
1992218893Sdim         Base1 != FromBaseEnd;
1993218893Sdim         ++Base1) {
1994218893Sdim      QualType T = Importer.Import(Base1->getType());
1995218893Sdim      if (T.isNull())
1996218893Sdim        return true;
1997218893Sdim
1998218893Sdim      SourceLocation EllipsisLoc;
1999218893Sdim      if (Base1->isPackExpansion())
2000218893Sdim        EllipsisLoc = Importer.Import(Base1->getEllipsisLoc());
2001226890Sdim
2002226890Sdim      // Ensure that we have a definition for the base.
2003226890Sdim      ImportDefinitionIfNeeded(Base1->getType()->getAsCXXRecordDecl());
2004226890Sdim
2005218893Sdim      Bases.push_back(
2006218893Sdim                    new (Importer.getToContext())
2007218893Sdim                      CXXBaseSpecifier(Importer.Import(Base1->getSourceRange()),
2008218893Sdim                                       Base1->isVirtual(),
2009218893Sdim                                       Base1->isBaseOfClass(),
2010218893Sdim                                       Base1->getAccessSpecifierAsWritten(),
2011218893Sdim                                   Importer.Import(Base1->getTypeSourceInfo()),
2012218893Sdim                                       EllipsisLoc));
2013218893Sdim    }
2014218893Sdim    if (!Bases.empty())
2015218893Sdim      ToCXX->setBases(Bases.data(), Bases.size());
2016218893Sdim  }
2017218893Sdim
2018235633Sdim  if (shouldForceImportDeclContext(Kind))
2019235633Sdim    ImportDeclContext(From, /*ForceImport=*/true);
2020235633Sdim
2021218893Sdim  To->completeDefinition();
2022218893Sdim  return false;
2023218893Sdim}
2024218893Sdim
2025263509Sdimbool ASTNodeImporter::ImportDefinition(VarDecl *From, VarDecl *To,
2026263509Sdim                                       ImportDefinitionKind Kind) {
2027263509Sdim  if (To->getDefinition())
2028263509Sdim    return false;
2029263509Sdim
2030263509Sdim  // FIXME: Can we really import any initializer? Alternatively, we could force
2031263509Sdim  // ourselves to import every declaration of a variable and then only use
2032263509Sdim  // getInit() here.
2033263509Sdim  To->setInit(Importer.Import(const_cast<Expr *>(From->getAnyInitializer())));
2034263509Sdim
2035263509Sdim  // FIXME: Other bits to merge?
2036263509Sdim
2037263509Sdim  return false;
2038263509Sdim}
2039263509Sdim
2040226890Sdimbool ASTNodeImporter::ImportDefinition(EnumDecl *From, EnumDecl *To,
2041235633Sdim                                       ImportDefinitionKind Kind) {
2042235633Sdim  if (To->getDefinition() || To->isBeingDefined()) {
2043235633Sdim    if (Kind == IDK_Everything)
2044235633Sdim      ImportDeclContext(From, /*ForceImport=*/true);
2045226890Sdim    return false;
2046235633Sdim  }
2047226890Sdim
2048226890Sdim  To->startDefinition();
2049226890Sdim
2050226890Sdim  QualType T = Importer.Import(Importer.getFromContext().getTypeDeclType(From));
2051226890Sdim  if (T.isNull())
2052226890Sdim    return true;
2053226890Sdim
2054226890Sdim  QualType ToPromotionType = Importer.Import(From->getPromotionType());
2055226890Sdim  if (ToPromotionType.isNull())
2056226890Sdim    return true;
2057235633Sdim
2058235633Sdim  if (shouldForceImportDeclContext(Kind))
2059235633Sdim    ImportDeclContext(From, /*ForceImport=*/true);
2060226890Sdim
2061226890Sdim  // FIXME: we might need to merge the number of positive or negative bits
2062226890Sdim  // if the enumerator lists don't match.
2063226890Sdim  To->completeDefinition(T, ToPromotionType,
2064226890Sdim                         From->getNumPositiveBits(),
2065226890Sdim                         From->getNumNegativeBits());
2066226890Sdim  return false;
2067226890Sdim}
2068226890Sdim
2069218893SdimTemplateParameterList *ASTNodeImporter::ImportTemplateParameterList(
2070218893Sdim                                                TemplateParameterList *Params) {
2071226890Sdim  SmallVector<NamedDecl *, 4> ToParams;
2072218893Sdim  ToParams.reserve(Params->size());
2073218893Sdim  for (TemplateParameterList::iterator P = Params->begin(),
2074218893Sdim                                    PEnd = Params->end();
2075218893Sdim       P != PEnd; ++P) {
2076218893Sdim    Decl *To = Importer.Import(*P);
2077218893Sdim    if (!To)
2078218893Sdim      return 0;
2079218893Sdim
2080218893Sdim    ToParams.push_back(cast<NamedDecl>(To));
2081218893Sdim  }
2082218893Sdim
2083218893Sdim  return TemplateParameterList::Create(Importer.getToContext(),
2084218893Sdim                                       Importer.Import(Params->getTemplateLoc()),
2085218893Sdim                                       Importer.Import(Params->getLAngleLoc()),
2086218893Sdim                                       ToParams.data(), ToParams.size(),
2087218893Sdim                                       Importer.Import(Params->getRAngleLoc()));
2088218893Sdim}
2089218893Sdim
2090218893SdimTemplateArgument
2091218893SdimASTNodeImporter::ImportTemplateArgument(const TemplateArgument &From) {
2092218893Sdim  switch (From.getKind()) {
2093218893Sdim  case TemplateArgument::Null:
2094218893Sdim    return TemplateArgument();
2095218893Sdim
2096218893Sdim  case TemplateArgument::Type: {
2097218893Sdim    QualType ToType = Importer.Import(From.getAsType());
2098218893Sdim    if (ToType.isNull())
2099218893Sdim      return TemplateArgument();
2100218893Sdim    return TemplateArgument(ToType);
2101218893Sdim  }
2102218893Sdim
2103218893Sdim  case TemplateArgument::Integral: {
2104218893Sdim    QualType ToType = Importer.Import(From.getIntegralType());
2105218893Sdim    if (ToType.isNull())
2106218893Sdim      return TemplateArgument();
2107245431Sdim    return TemplateArgument(From, ToType);
2108218893Sdim  }
2109218893Sdim
2110245431Sdim  case TemplateArgument::Declaration: {
2111245431Sdim    ValueDecl *FromD = From.getAsDecl();
2112245431Sdim    if (ValueDecl *To = cast_or_null<ValueDecl>(Importer.Import(FromD)))
2113245431Sdim      return TemplateArgument(To, From.isDeclForReferenceParam());
2114218893Sdim    return TemplateArgument();
2115245431Sdim  }
2116245431Sdim
2117245431Sdim  case TemplateArgument::NullPtr: {
2118245431Sdim    QualType ToType = Importer.Import(From.getNullPtrType());
2119245431Sdim    if (ToType.isNull())
2120245431Sdim      return TemplateArgument();
2121245431Sdim    return TemplateArgument(ToType, /*isNullPtr*/true);
2122245431Sdim  }
2123245431Sdim
2124218893Sdim  case TemplateArgument::Template: {
2125218893Sdim    TemplateName ToTemplate = Importer.Import(From.getAsTemplate());
2126218893Sdim    if (ToTemplate.isNull())
2127218893Sdim      return TemplateArgument();
2128218893Sdim
2129218893Sdim    return TemplateArgument(ToTemplate);
2130218893Sdim  }
2131218893Sdim
2132218893Sdim  case TemplateArgument::TemplateExpansion: {
2133218893Sdim    TemplateName ToTemplate
2134218893Sdim      = Importer.Import(From.getAsTemplateOrTemplatePattern());
2135218893Sdim    if (ToTemplate.isNull())
2136218893Sdim      return TemplateArgument();
2137218893Sdim
2138218893Sdim    return TemplateArgument(ToTemplate, From.getNumTemplateExpansions());
2139218893Sdim  }
2140218893Sdim
2141218893Sdim  case TemplateArgument::Expression:
2142218893Sdim    if (Expr *ToExpr = Importer.Import(From.getAsExpr()))
2143218893Sdim      return TemplateArgument(ToExpr);
2144218893Sdim    return TemplateArgument();
2145218893Sdim
2146218893Sdim  case TemplateArgument::Pack: {
2147226890Sdim    SmallVector<TemplateArgument, 2> ToPack;
2148218893Sdim    ToPack.reserve(From.pack_size());
2149218893Sdim    if (ImportTemplateArguments(From.pack_begin(), From.pack_size(), ToPack))
2150218893Sdim      return TemplateArgument();
2151218893Sdim
2152218893Sdim    TemplateArgument *ToArgs
2153218893Sdim      = new (Importer.getToContext()) TemplateArgument[ToPack.size()];
2154218893Sdim    std::copy(ToPack.begin(), ToPack.end(), ToArgs);
2155218893Sdim    return TemplateArgument(ToArgs, ToPack.size());
2156218893Sdim  }
2157218893Sdim  }
2158218893Sdim
2159218893Sdim  llvm_unreachable("Invalid template argument kind");
2160218893Sdim}
2161218893Sdim
2162218893Sdimbool ASTNodeImporter::ImportTemplateArguments(const TemplateArgument *FromArgs,
2163218893Sdim                                              unsigned NumFromArgs,
2164226890Sdim                              SmallVectorImpl<TemplateArgument> &ToArgs) {
2165218893Sdim  for (unsigned I = 0; I != NumFromArgs; ++I) {
2166218893Sdim    TemplateArgument To = ImportTemplateArgument(FromArgs[I]);
2167218893Sdim    if (To.isNull() && !FromArgs[I].isNull())
2168218893Sdim      return true;
2169218893Sdim
2170218893Sdim    ToArgs.push_back(To);
2171218893Sdim  }
2172218893Sdim
2173218893Sdim  return false;
2174218893Sdim}
2175218893Sdim
2176203955Srdivackybool ASTNodeImporter::IsStructuralMatch(RecordDecl *FromRecord,
2177245431Sdim                                        RecordDecl *ToRecord, bool Complain) {
2178263509Sdim  // Eliminate a potential failure point where we attempt to re-import
2179263509Sdim  // something we're trying to import while completing ToRecord.
2180263509Sdim  Decl *ToOrigin = Importer.GetOriginalDecl(ToRecord);
2181263509Sdim  if (ToOrigin) {
2182263509Sdim    RecordDecl *ToOriginRecord = dyn_cast<RecordDecl>(ToOrigin);
2183263509Sdim    if (ToOriginRecord)
2184263509Sdim      ToRecord = ToOriginRecord;
2185263509Sdim  }
2186263509Sdim
2187204643Srdivacky  StructuralEquivalenceContext Ctx(Importer.getFromContext(),
2188263509Sdim                                   ToRecord->getASTContext(),
2189245431Sdim                                   Importer.getNonEquivalentDecls(),
2190245431Sdim                                   false, Complain);
2191204643Srdivacky  return Ctx.IsStructurallyEquivalent(FromRecord, ToRecord);
2192203955Srdivacky}
2193203955Srdivacky
2194263509Sdimbool ASTNodeImporter::IsStructuralMatch(VarDecl *FromVar, VarDecl *ToVar,
2195263509Sdim                                        bool Complain) {
2196263509Sdim  StructuralEquivalenceContext Ctx(
2197263509Sdim      Importer.getFromContext(), Importer.getToContext(),
2198263509Sdim      Importer.getNonEquivalentDecls(), false, Complain);
2199263509Sdim  return Ctx.IsStructurallyEquivalent(FromVar, ToVar);
2200263509Sdim}
2201263509Sdim
2202203955Srdivackybool ASTNodeImporter::IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToEnum) {
2203204643Srdivacky  StructuralEquivalenceContext Ctx(Importer.getFromContext(),
2204203955Srdivacky                                   Importer.getToContext(),
2205203955Srdivacky                                   Importer.getNonEquivalentDecls());
2206204643Srdivacky  return Ctx.IsStructurallyEquivalent(FromEnum, ToEnum);
2207203955Srdivacky}
2208203955Srdivacky
2209252723Sdimbool ASTNodeImporter::IsStructuralMatch(EnumConstantDecl *FromEC,
2210252723Sdim                                        EnumConstantDecl *ToEC)
2211252723Sdim{
2212252723Sdim  const llvm::APSInt &FromVal = FromEC->getInitVal();
2213252723Sdim  const llvm::APSInt &ToVal = ToEC->getInitVal();
2214252723Sdim
2215252723Sdim  return FromVal.isSigned() == ToVal.isSigned() &&
2216252723Sdim         FromVal.getBitWidth() == ToVal.getBitWidth() &&
2217252723Sdim         FromVal == ToVal;
2218252723Sdim}
2219252723Sdim
2220252723Sdimbool ASTNodeImporter::IsStructuralMatch(ClassTemplateDecl *From,
2221218893Sdim                                        ClassTemplateDecl *To) {
2222218893Sdim  StructuralEquivalenceContext Ctx(Importer.getFromContext(),
2223218893Sdim                                   Importer.getToContext(),
2224218893Sdim                                   Importer.getNonEquivalentDecls());
2225218893Sdim  return Ctx.IsStructurallyEquivalent(From, To);
2226218893Sdim}
2227218893Sdim
2228263509Sdimbool ASTNodeImporter::IsStructuralMatch(VarTemplateDecl *From,
2229263509Sdim                                        VarTemplateDecl *To) {
2230263509Sdim  StructuralEquivalenceContext Ctx(Importer.getFromContext(),
2231263509Sdim                                   Importer.getToContext(),
2232263509Sdim                                   Importer.getNonEquivalentDecls());
2233263509Sdim  return Ctx.IsStructurallyEquivalent(From, To);
2234263509Sdim}
2235263509Sdim
2236203955SrdivackyDecl *ASTNodeImporter::VisitDecl(Decl *D) {
2237203955Srdivacky  Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node)
2238203955Srdivacky    << D->getDeclKindName();
2239203955Srdivacky  return 0;
2240203955Srdivacky}
2241203955Srdivacky
2242235633SdimDecl *ASTNodeImporter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
2243235633Sdim  TranslationUnitDecl *ToD =
2244235633Sdim    Importer.getToContext().getTranslationUnitDecl();
2245235633Sdim
2246235633Sdim  Importer.Imported(D, ToD);
2247235633Sdim
2248235633Sdim  return ToD;
2249235633Sdim}
2250235633Sdim
2251204643SrdivackyDecl *ASTNodeImporter::VisitNamespaceDecl(NamespaceDecl *D) {
2252204643Srdivacky  // Import the major distinguishing characteristics of this namespace.
2253204643Srdivacky  DeclContext *DC, *LexicalDC;
2254204643Srdivacky  DeclarationName Name;
2255204643Srdivacky  SourceLocation Loc;
2256204643Srdivacky  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2257204643Srdivacky    return 0;
2258204643Srdivacky
2259204643Srdivacky  NamespaceDecl *MergeWithNamespace = 0;
2260204643Srdivacky  if (!Name) {
2261204643Srdivacky    // This is an anonymous namespace. Adopt an existing anonymous
2262204643Srdivacky    // namespace if we can.
2263204643Srdivacky    // FIXME: Not testable.
2264204643Srdivacky    if (TranslationUnitDecl *TU = dyn_cast<TranslationUnitDecl>(DC))
2265204643Srdivacky      MergeWithNamespace = TU->getAnonymousNamespace();
2266204643Srdivacky    else
2267204643Srdivacky      MergeWithNamespace = cast<NamespaceDecl>(DC)->getAnonymousNamespace();
2268204643Srdivacky  } else {
2269226890Sdim    SmallVector<NamedDecl *, 4> ConflictingDecls;
2270252723Sdim    SmallVector<NamedDecl *, 2> FoundDecls;
2271226890Sdim    DC->localUncachedLookup(Name, FoundDecls);
2272226890Sdim    for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
2273226890Sdim      if (!FoundDecls[I]->isInIdentifierNamespace(Decl::IDNS_Namespace))
2274204643Srdivacky        continue;
2275204643Srdivacky
2276226890Sdim      if (NamespaceDecl *FoundNS = dyn_cast<NamespaceDecl>(FoundDecls[I])) {
2277204643Srdivacky        MergeWithNamespace = FoundNS;
2278204643Srdivacky        ConflictingDecls.clear();
2279204643Srdivacky        break;
2280204643Srdivacky      }
2281204643Srdivacky
2282226890Sdim      ConflictingDecls.push_back(FoundDecls[I]);
2283204643Srdivacky    }
2284204643Srdivacky
2285204643Srdivacky    if (!ConflictingDecls.empty()) {
2286207619Srdivacky      Name = Importer.HandleNameConflict(Name, DC, Decl::IDNS_Namespace,
2287204643Srdivacky                                         ConflictingDecls.data(),
2288204643Srdivacky                                         ConflictingDecls.size());
2289204643Srdivacky    }
2290204643Srdivacky  }
2291204643Srdivacky
2292204643Srdivacky  // Create the "to" namespace, if needed.
2293204643Srdivacky  NamespaceDecl *ToNamespace = MergeWithNamespace;
2294204643Srdivacky  if (!ToNamespace) {
2295221345Sdim    ToNamespace = NamespaceDecl::Create(Importer.getToContext(), DC,
2296235633Sdim                                        D->isInline(),
2297221345Sdim                                        Importer.Import(D->getLocStart()),
2298235633Sdim                                        Loc, Name.getAsIdentifierInfo(),
2299235633Sdim                                        /*PrevDecl=*/0);
2300204643Srdivacky    ToNamespace->setLexicalDeclContext(LexicalDC);
2301235633Sdim    LexicalDC->addDeclInternal(ToNamespace);
2302204643Srdivacky
2303204643Srdivacky    // If this is an anonymous namespace, register it as the anonymous
2304204643Srdivacky    // namespace within its context.
2305204643Srdivacky    if (!Name) {
2306204643Srdivacky      if (TranslationUnitDecl *TU = dyn_cast<TranslationUnitDecl>(DC))
2307204643Srdivacky        TU->setAnonymousNamespace(ToNamespace);
2308204643Srdivacky      else
2309204643Srdivacky        cast<NamespaceDecl>(DC)->setAnonymousNamespace(ToNamespace);
2310204643Srdivacky    }
2311204643Srdivacky  }
2312204643Srdivacky  Importer.Imported(D, ToNamespace);
2313204643Srdivacky
2314204643Srdivacky  ImportDeclContext(D);
2315204643Srdivacky
2316204643Srdivacky  return ToNamespace;
2317204643Srdivacky}
2318204643Srdivacky
2319221345SdimDecl *ASTNodeImporter::VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias) {
2320203955Srdivacky  // Import the major distinguishing characteristics of this typedef.
2321203955Srdivacky  DeclContext *DC, *LexicalDC;
2322203955Srdivacky  DeclarationName Name;
2323203955Srdivacky  SourceLocation Loc;
2324203955Srdivacky  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2325203955Srdivacky    return 0;
2326203955Srdivacky
2327203955Srdivacky  // If this typedef is not in block scope, determine whether we've
2328203955Srdivacky  // seen a typedef with the same name (that we can merge with) or any
2329203955Srdivacky  // other entity by that name (which name lookup could conflict with).
2330203955Srdivacky  if (!DC->isFunctionOrMethod()) {
2331226890Sdim    SmallVector<NamedDecl *, 4> ConflictingDecls;
2332203955Srdivacky    unsigned IDNS = Decl::IDNS_Ordinary;
2333252723Sdim    SmallVector<NamedDecl *, 2> FoundDecls;
2334226890Sdim    DC->localUncachedLookup(Name, FoundDecls);
2335226890Sdim    for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
2336226890Sdim      if (!FoundDecls[I]->isInIdentifierNamespace(IDNS))
2337203955Srdivacky        continue;
2338221345Sdim      if (TypedefNameDecl *FoundTypedef =
2339226890Sdim            dyn_cast<TypedefNameDecl>(FoundDecls[I])) {
2340203955Srdivacky        if (Importer.IsStructurallyEquivalent(D->getUnderlyingType(),
2341203955Srdivacky                                            FoundTypedef->getUnderlyingType()))
2342203955Srdivacky          return Importer.Imported(D, FoundTypedef);
2343203955Srdivacky      }
2344203955Srdivacky
2345226890Sdim      ConflictingDecls.push_back(FoundDecls[I]);
2346203955Srdivacky    }
2347203955Srdivacky
2348203955Srdivacky    if (!ConflictingDecls.empty()) {
2349203955Srdivacky      Name = Importer.HandleNameConflict(Name, DC, IDNS,
2350203955Srdivacky                                         ConflictingDecls.data(),
2351203955Srdivacky                                         ConflictingDecls.size());
2352203955Srdivacky      if (!Name)
2353203955Srdivacky        return 0;
2354203955Srdivacky    }
2355203955Srdivacky  }
2356203955Srdivacky
2357203955Srdivacky  // Import the underlying type of this typedef;
2358203955Srdivacky  QualType T = Importer.Import(D->getUnderlyingType());
2359203955Srdivacky  if (T.isNull())
2360203955Srdivacky    return 0;
2361203955Srdivacky
2362203955Srdivacky  // Create the new typedef node.
2363203955Srdivacky  TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
2364221345Sdim  SourceLocation StartL = Importer.Import(D->getLocStart());
2365221345Sdim  TypedefNameDecl *ToTypedef;
2366221345Sdim  if (IsAlias)
2367226890Sdim    ToTypedef = TypeAliasDecl::Create(Importer.getToContext(), DC,
2368226890Sdim                                      StartL, Loc,
2369226890Sdim                                      Name.getAsIdentifierInfo(),
2370226890Sdim                                      TInfo);
2371226890Sdim  else
2372221345Sdim    ToTypedef = TypedefDecl::Create(Importer.getToContext(), DC,
2373221345Sdim                                    StartL, Loc,
2374221345Sdim                                    Name.getAsIdentifierInfo(),
2375221345Sdim                                    TInfo);
2376226890Sdim
2377204643Srdivacky  ToTypedef->setAccess(D->getAccess());
2378203955Srdivacky  ToTypedef->setLexicalDeclContext(LexicalDC);
2379203955Srdivacky  Importer.Imported(D, ToTypedef);
2380235633Sdim  LexicalDC->addDeclInternal(ToTypedef);
2381203955Srdivacky
2382203955Srdivacky  return ToTypedef;
2383203955Srdivacky}
2384203955Srdivacky
2385221345SdimDecl *ASTNodeImporter::VisitTypedefDecl(TypedefDecl *D) {
2386221345Sdim  return VisitTypedefNameDecl(D, /*IsAlias=*/false);
2387221345Sdim}
2388221345Sdim
2389221345SdimDecl *ASTNodeImporter::VisitTypeAliasDecl(TypeAliasDecl *D) {
2390221345Sdim  return VisitTypedefNameDecl(D, /*IsAlias=*/true);
2391221345Sdim}
2392221345Sdim
2393203955SrdivackyDecl *ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
2394203955Srdivacky  // Import the major distinguishing characteristics of this enum.
2395203955Srdivacky  DeclContext *DC, *LexicalDC;
2396203955Srdivacky  DeclarationName Name;
2397203955Srdivacky  SourceLocation Loc;
2398203955Srdivacky  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2399203955Srdivacky    return 0;
2400203955Srdivacky
2401203955Srdivacky  // Figure out what enum name we're looking for.
2402203955Srdivacky  unsigned IDNS = Decl::IDNS_Tag;
2403203955Srdivacky  DeclarationName SearchName = Name;
2404221345Sdim  if (!SearchName && D->getTypedefNameForAnonDecl()) {
2405221345Sdim    SearchName = Importer.Import(D->getTypedefNameForAnonDecl()->getDeclName());
2406203955Srdivacky    IDNS = Decl::IDNS_Ordinary;
2407235633Sdim  } else if (Importer.getToContext().getLangOpts().CPlusPlus)
2408203955Srdivacky    IDNS |= Decl::IDNS_Ordinary;
2409203955Srdivacky
2410203955Srdivacky  // We may already have an enum of the same name; try to find and match it.
2411203955Srdivacky  if (!DC->isFunctionOrMethod() && SearchName) {
2412226890Sdim    SmallVector<NamedDecl *, 4> ConflictingDecls;
2413252723Sdim    SmallVector<NamedDecl *, 2> FoundDecls;
2414226890Sdim    DC->localUncachedLookup(SearchName, FoundDecls);
2415226890Sdim    for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
2416226890Sdim      if (!FoundDecls[I]->isInIdentifierNamespace(IDNS))
2417203955Srdivacky        continue;
2418203955Srdivacky
2419226890Sdim      Decl *Found = FoundDecls[I];
2420221345Sdim      if (TypedefNameDecl *Typedef = dyn_cast<TypedefNameDecl>(Found)) {
2421203955Srdivacky        if (const TagType *Tag = Typedef->getUnderlyingType()->getAs<TagType>())
2422203955Srdivacky          Found = Tag->getDecl();
2423203955Srdivacky      }
2424203955Srdivacky
2425203955Srdivacky      if (EnumDecl *FoundEnum = dyn_cast<EnumDecl>(Found)) {
2426203955Srdivacky        if (IsStructuralMatch(D, FoundEnum))
2427203955Srdivacky          return Importer.Imported(D, FoundEnum);
2428203955Srdivacky      }
2429203955Srdivacky
2430226890Sdim      ConflictingDecls.push_back(FoundDecls[I]);
2431203955Srdivacky    }
2432203955Srdivacky
2433203955Srdivacky    if (!ConflictingDecls.empty()) {
2434203955Srdivacky      Name = Importer.HandleNameConflict(Name, DC, IDNS,
2435203955Srdivacky                                         ConflictingDecls.data(),
2436203955Srdivacky                                         ConflictingDecls.size());
2437203955Srdivacky    }
2438203955Srdivacky  }
2439203955Srdivacky
2440203955Srdivacky  // Create the enum declaration.
2441221345Sdim  EnumDecl *D2 = EnumDecl::Create(Importer.getToContext(), DC,
2442221345Sdim                                  Importer.Import(D->getLocStart()),
2443221345Sdim                                  Loc, Name.getAsIdentifierInfo(), 0,
2444218893Sdim                                  D->isScoped(), D->isScopedUsingClassTag(),
2445218893Sdim                                  D->isFixed());
2446205219Srdivacky  // Import the qualifier, if any.
2447219077Sdim  D2->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
2448204643Srdivacky  D2->setAccess(D->getAccess());
2449203955Srdivacky  D2->setLexicalDeclContext(LexicalDC);
2450203955Srdivacky  Importer.Imported(D, D2);
2451235633Sdim  LexicalDC->addDeclInternal(D2);
2452203955Srdivacky
2453203955Srdivacky  // Import the integer type.
2454203955Srdivacky  QualType ToIntegerType = Importer.Import(D->getIntegerType());
2455203955Srdivacky  if (ToIntegerType.isNull())
2456203955Srdivacky    return 0;
2457203955Srdivacky  D2->setIntegerType(ToIntegerType);
2458203955Srdivacky
2459203955Srdivacky  // Import the definition
2460226890Sdim  if (D->isCompleteDefinition() && ImportDefinition(D, D2))
2461226890Sdim    return 0;
2462203955Srdivacky
2463203955Srdivacky  return D2;
2464203955Srdivacky}
2465203955Srdivacky
2466203955SrdivackyDecl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
2467203955Srdivacky  // If this record has a definition in the translation unit we're coming from,
2468203955Srdivacky  // but this particular declaration is not that definition, import the
2469203955Srdivacky  // definition and map to that.
2470203955Srdivacky  TagDecl *Definition = D->getDefinition();
2471203955Srdivacky  if (Definition && Definition != D) {
2472203955Srdivacky    Decl *ImportedDef = Importer.Import(Definition);
2473203955Srdivacky    if (!ImportedDef)
2474203955Srdivacky      return 0;
2475203955Srdivacky
2476203955Srdivacky    return Importer.Imported(D, ImportedDef);
2477203955Srdivacky  }
2478203955Srdivacky
2479203955Srdivacky  // Import the major distinguishing characteristics of this record.
2480203955Srdivacky  DeclContext *DC, *LexicalDC;
2481203955Srdivacky  DeclarationName Name;
2482203955Srdivacky  SourceLocation Loc;
2483203955Srdivacky  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2484203955Srdivacky    return 0;
2485203955Srdivacky
2486203955Srdivacky  // Figure out what structure name we're looking for.
2487203955Srdivacky  unsigned IDNS = Decl::IDNS_Tag;
2488203955Srdivacky  DeclarationName SearchName = Name;
2489221345Sdim  if (!SearchName && D->getTypedefNameForAnonDecl()) {
2490221345Sdim    SearchName = Importer.Import(D->getTypedefNameForAnonDecl()->getDeclName());
2491203955Srdivacky    IDNS = Decl::IDNS_Ordinary;
2492235633Sdim  } else if (Importer.getToContext().getLangOpts().CPlusPlus)
2493203955Srdivacky    IDNS |= Decl::IDNS_Ordinary;
2494203955Srdivacky
2495203955Srdivacky  // We may already have a record of the same name; try to find and match it.
2496203955Srdivacky  RecordDecl *AdoptDecl = 0;
2497245431Sdim  if (!DC->isFunctionOrMethod()) {
2498226890Sdim    SmallVector<NamedDecl *, 4> ConflictingDecls;
2499252723Sdim    SmallVector<NamedDecl *, 2> FoundDecls;
2500226890Sdim    DC->localUncachedLookup(SearchName, FoundDecls);
2501226890Sdim    for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
2502226890Sdim      if (!FoundDecls[I]->isInIdentifierNamespace(IDNS))
2503203955Srdivacky        continue;
2504203955Srdivacky
2505226890Sdim      Decl *Found = FoundDecls[I];
2506221345Sdim      if (TypedefNameDecl *Typedef = dyn_cast<TypedefNameDecl>(Found)) {
2507203955Srdivacky        if (const TagType *Tag = Typedef->getUnderlyingType()->getAs<TagType>())
2508203955Srdivacky          Found = Tag->getDecl();
2509203955Srdivacky      }
2510203955Srdivacky
2511203955Srdivacky      if (RecordDecl *FoundRecord = dyn_cast<RecordDecl>(Found)) {
2512245431Sdim        if (D->isAnonymousStructOrUnion() &&
2513245431Sdim            FoundRecord->isAnonymousStructOrUnion()) {
2514245431Sdim          // If both anonymous structs/unions are in a record context, make sure
2515245431Sdim          // they occur in the same location in the context records.
2516252723Sdim          if (Optional<unsigned> Index1
2517245431Sdim              = findAnonymousStructOrUnionIndex(D)) {
2518252723Sdim            if (Optional<unsigned> Index2 =
2519252723Sdim                    findAnonymousStructOrUnionIndex(FoundRecord)) {
2520245431Sdim              if (*Index1 != *Index2)
2521245431Sdim                continue;
2522245431Sdim            }
2523245431Sdim          }
2524245431Sdim        }
2525245431Sdim
2526203955Srdivacky        if (RecordDecl *FoundDef = FoundRecord->getDefinition()) {
2527245431Sdim          if ((SearchName && !D->isCompleteDefinition())
2528245431Sdim              || (D->isCompleteDefinition() &&
2529245431Sdim                  D->isAnonymousStructOrUnion()
2530245431Sdim                    == FoundDef->isAnonymousStructOrUnion() &&
2531245431Sdim                  IsStructuralMatch(D, FoundDef))) {
2532203955Srdivacky            // The record types structurally match, or the "from" translation
2533203955Srdivacky            // unit only had a forward declaration anyway; call it the same
2534203955Srdivacky            // function.
2535203955Srdivacky            // FIXME: For C++, we should also merge methods here.
2536203955Srdivacky            return Importer.Imported(D, FoundDef);
2537203955Srdivacky          }
2538245431Sdim        } else if (!D->isCompleteDefinition()) {
2539203955Srdivacky          // We have a forward declaration of this type, so adopt that forward
2540203955Srdivacky          // declaration rather than building a new one.
2541203955Srdivacky          AdoptDecl = FoundRecord;
2542203955Srdivacky          continue;
2543245431Sdim        } else if (!SearchName) {
2544245431Sdim          continue;
2545245431Sdim        }
2546203955Srdivacky      }
2547203955Srdivacky
2548226890Sdim      ConflictingDecls.push_back(FoundDecls[I]);
2549203955Srdivacky    }
2550203955Srdivacky
2551245431Sdim    if (!ConflictingDecls.empty() && SearchName) {
2552203955Srdivacky      Name = Importer.HandleNameConflict(Name, DC, IDNS,
2553203955Srdivacky                                         ConflictingDecls.data(),
2554203955Srdivacky                                         ConflictingDecls.size());
2555203955Srdivacky    }
2556203955Srdivacky  }
2557203955Srdivacky
2558203955Srdivacky  // Create the record declaration.
2559203955Srdivacky  RecordDecl *D2 = AdoptDecl;
2560221345Sdim  SourceLocation StartLoc = Importer.Import(D->getLocStart());
2561203955Srdivacky  if (!D2) {
2562210299Sed    if (isa<CXXRecordDecl>(D)) {
2563203955Srdivacky      CXXRecordDecl *D2CXX = CXXRecordDecl::Create(Importer.getToContext(),
2564203955Srdivacky                                                   D->getTagKind(),
2565221345Sdim                                                   DC, StartLoc, Loc,
2566221345Sdim                                                   Name.getAsIdentifierInfo());
2567203955Srdivacky      D2 = D2CXX;
2568204643Srdivacky      D2->setAccess(D->getAccess());
2569203955Srdivacky    } else {
2570203955Srdivacky      D2 = RecordDecl::Create(Importer.getToContext(), D->getTagKind(),
2571221345Sdim                              DC, StartLoc, Loc, Name.getAsIdentifierInfo());
2572203955Srdivacky    }
2573219077Sdim
2574219077Sdim    D2->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
2575203955Srdivacky    D2->setLexicalDeclContext(LexicalDC);
2576235633Sdim    LexicalDC->addDeclInternal(D2);
2577245431Sdim    if (D->isAnonymousStructOrUnion())
2578245431Sdim      D2->setAnonymousStructOrUnion(true);
2579203955Srdivacky  }
2580203955Srdivacky
2581203955Srdivacky  Importer.Imported(D, D2);
2582203955Srdivacky
2583235633Sdim  if (D->isCompleteDefinition() && ImportDefinition(D, D2, IDK_Default))
2584218893Sdim    return 0;
2585203955Srdivacky
2586203955Srdivacky  return D2;
2587203955Srdivacky}
2588203955Srdivacky
2589203955SrdivackyDecl *ASTNodeImporter::VisitEnumConstantDecl(EnumConstantDecl *D) {
2590203955Srdivacky  // Import the major distinguishing characteristics of this enumerator.
2591203955Srdivacky  DeclContext *DC, *LexicalDC;
2592203955Srdivacky  DeclarationName Name;
2593203955Srdivacky  SourceLocation Loc;
2594203955Srdivacky  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2595203955Srdivacky    return 0;
2596203955Srdivacky
2597203955Srdivacky  QualType T = Importer.Import(D->getType());
2598203955Srdivacky  if (T.isNull())
2599203955Srdivacky    return 0;
2600203955Srdivacky
2601203955Srdivacky  // Determine whether there are any other declarations with the same name and
2602203955Srdivacky  // in the same context.
2603203955Srdivacky  if (!LexicalDC->isFunctionOrMethod()) {
2604226890Sdim    SmallVector<NamedDecl *, 4> ConflictingDecls;
2605203955Srdivacky    unsigned IDNS = Decl::IDNS_Ordinary;
2606252723Sdim    SmallVector<NamedDecl *, 2> FoundDecls;
2607226890Sdim    DC->localUncachedLookup(Name, FoundDecls);
2608226890Sdim    for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
2609226890Sdim      if (!FoundDecls[I]->isInIdentifierNamespace(IDNS))
2610203955Srdivacky        continue;
2611252723Sdim
2612252723Sdim      if (EnumConstantDecl *FoundEnumConstant
2613252723Sdim            = dyn_cast<EnumConstantDecl>(FoundDecls[I])) {
2614252723Sdim        if (IsStructuralMatch(D, FoundEnumConstant))
2615252723Sdim          return Importer.Imported(D, FoundEnumConstant);
2616252723Sdim      }
2617252723Sdim
2618226890Sdim      ConflictingDecls.push_back(FoundDecls[I]);
2619203955Srdivacky    }
2620203955Srdivacky
2621203955Srdivacky    if (!ConflictingDecls.empty()) {
2622203955Srdivacky      Name = Importer.HandleNameConflict(Name, DC, IDNS,
2623203955Srdivacky                                         ConflictingDecls.data(),
2624203955Srdivacky                                         ConflictingDecls.size());
2625203955Srdivacky      if (!Name)
2626203955Srdivacky        return 0;
2627203955Srdivacky    }
2628203955Srdivacky  }
2629203955Srdivacky
2630203955Srdivacky  Expr *Init = Importer.Import(D->getInitExpr());
2631203955Srdivacky  if (D->getInitExpr() && !Init)
2632203955Srdivacky    return 0;
2633203955Srdivacky
2634203955Srdivacky  EnumConstantDecl *ToEnumerator
2635203955Srdivacky    = EnumConstantDecl::Create(Importer.getToContext(), cast<EnumDecl>(DC), Loc,
2636203955Srdivacky                               Name.getAsIdentifierInfo(), T,
2637203955Srdivacky                               Init, D->getInitVal());
2638204643Srdivacky  ToEnumerator->setAccess(D->getAccess());
2639203955Srdivacky  ToEnumerator->setLexicalDeclContext(LexicalDC);
2640203955Srdivacky  Importer.Imported(D, ToEnumerator);
2641235633Sdim  LexicalDC->addDeclInternal(ToEnumerator);
2642203955Srdivacky  return ToEnumerator;
2643203955Srdivacky}
2644203955Srdivacky
2645203955SrdivackyDecl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
2646203955Srdivacky  // Import the major distinguishing characteristics of this function.
2647203955Srdivacky  DeclContext *DC, *LexicalDC;
2648203955Srdivacky  DeclarationName Name;
2649203955Srdivacky  SourceLocation Loc;
2650203955Srdivacky  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2651203955Srdivacky    return 0;
2652212904Sdim
2653203955Srdivacky  // Try to find a function in our own ("to") context with the same name, same
2654203955Srdivacky  // type, and in the same context as the function we're importing.
2655203955Srdivacky  if (!LexicalDC->isFunctionOrMethod()) {
2656226890Sdim    SmallVector<NamedDecl *, 4> ConflictingDecls;
2657203955Srdivacky    unsigned IDNS = Decl::IDNS_Ordinary;
2658252723Sdim    SmallVector<NamedDecl *, 2> FoundDecls;
2659226890Sdim    DC->localUncachedLookup(Name, FoundDecls);
2660226890Sdim    for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
2661226890Sdim      if (!FoundDecls[I]->isInIdentifierNamespace(IDNS))
2662203955Srdivacky        continue;
2663203955Srdivacky
2664226890Sdim      if (FunctionDecl *FoundFunction = dyn_cast<FunctionDecl>(FoundDecls[I])) {
2665263509Sdim        if (FoundFunction->hasExternalFormalLinkage() &&
2666263509Sdim            D->hasExternalFormalLinkage()) {
2667203955Srdivacky          if (Importer.IsStructurallyEquivalent(D->getType(),
2668203955Srdivacky                                                FoundFunction->getType())) {
2669203955Srdivacky            // FIXME: Actually try to merge the body and other attributes.
2670203955Srdivacky            return Importer.Imported(D, FoundFunction);
2671203955Srdivacky          }
2672203955Srdivacky
2673203955Srdivacky          // FIXME: Check for overloading more carefully, e.g., by boosting
2674203955Srdivacky          // Sema::IsOverload out to the AST library.
2675203955Srdivacky
2676203955Srdivacky          // Function overloading is okay in C++.
2677235633Sdim          if (Importer.getToContext().getLangOpts().CPlusPlus)
2678203955Srdivacky            continue;
2679203955Srdivacky
2680203955Srdivacky          // Complain about inconsistent function types.
2681203955Srdivacky          Importer.ToDiag(Loc, diag::err_odr_function_type_inconsistent)
2682203955Srdivacky            << Name << D->getType() << FoundFunction->getType();
2683203955Srdivacky          Importer.ToDiag(FoundFunction->getLocation(),
2684203955Srdivacky                          diag::note_odr_value_here)
2685203955Srdivacky            << FoundFunction->getType();
2686203955Srdivacky        }
2687203955Srdivacky      }
2688203955Srdivacky
2689226890Sdim      ConflictingDecls.push_back(FoundDecls[I]);
2690203955Srdivacky    }
2691203955Srdivacky
2692203955Srdivacky    if (!ConflictingDecls.empty()) {
2693203955Srdivacky      Name = Importer.HandleNameConflict(Name, DC, IDNS,
2694203955Srdivacky                                         ConflictingDecls.data(),
2695203955Srdivacky                                         ConflictingDecls.size());
2696203955Srdivacky      if (!Name)
2697203955Srdivacky        return 0;
2698203955Srdivacky    }
2699203955Srdivacky  }
2700203955Srdivacky
2701212904Sdim  DeclarationNameInfo NameInfo(Name, Loc);
2702212904Sdim  // Import additional name location/type info.
2703212904Sdim  ImportDeclarationNameLoc(D->getNameInfo(), NameInfo);
2704212904Sdim
2705245431Sdim  QualType FromTy = D->getType();
2706245431Sdim  bool usedDifferentExceptionSpec = false;
2707245431Sdim
2708245431Sdim  if (const FunctionProtoType *
2709245431Sdim        FromFPT = D->getType()->getAs<FunctionProtoType>()) {
2710245431Sdim    FunctionProtoType::ExtProtoInfo FromEPI = FromFPT->getExtProtoInfo();
2711245431Sdim    // FunctionProtoType::ExtProtoInfo's ExceptionSpecDecl can point to the
2712245431Sdim    // FunctionDecl that we are importing the FunctionProtoType for.
2713245431Sdim    // To avoid an infinite recursion when importing, create the FunctionDecl
2714245431Sdim    // with a simplified function type and update it afterwards.
2715245431Sdim    if (FromEPI.ExceptionSpecDecl || FromEPI.ExceptionSpecTemplate ||
2716245431Sdim        FromEPI.NoexceptExpr) {
2717245431Sdim      FunctionProtoType::ExtProtoInfo DefaultEPI;
2718245431Sdim      FromTy = Importer.getFromContext().getFunctionType(
2719263509Sdim          FromFPT->getResultType(), FromFPT->getArgTypes(), DefaultEPI);
2720245431Sdim      usedDifferentExceptionSpec = true;
2721245431Sdim    }
2722245431Sdim  }
2723245431Sdim
2724203955Srdivacky  // Import the type.
2725245431Sdim  QualType T = Importer.Import(FromTy);
2726203955Srdivacky  if (T.isNull())
2727203955Srdivacky    return 0;
2728203955Srdivacky
2729203955Srdivacky  // Import the function parameters.
2730226890Sdim  SmallVector<ParmVarDecl *, 8> Parameters;
2731203955Srdivacky  for (FunctionDecl::param_iterator P = D->param_begin(), PEnd = D->param_end();
2732203955Srdivacky       P != PEnd; ++P) {
2733203955Srdivacky    ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(*P));
2734203955Srdivacky    if (!ToP)
2735203955Srdivacky      return 0;
2736203955Srdivacky
2737203955Srdivacky    Parameters.push_back(ToP);
2738203955Srdivacky  }
2739203955Srdivacky
2740203955Srdivacky  // Create the imported function.
2741203955Srdivacky  TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
2742204643Srdivacky  FunctionDecl *ToFunction = 0;
2743204643Srdivacky  if (CXXConstructorDecl *FromConstructor = dyn_cast<CXXConstructorDecl>(D)) {
2744204643Srdivacky    ToFunction = CXXConstructorDecl::Create(Importer.getToContext(),
2745204643Srdivacky                                            cast<CXXRecordDecl>(DC),
2746221345Sdim                                            D->getInnerLocStart(),
2747212904Sdim                                            NameInfo, T, TInfo,
2748204643Srdivacky                                            FromConstructor->isExplicit(),
2749204643Srdivacky                                            D->isInlineSpecified(),
2750226890Sdim                                            D->isImplicit(),
2751226890Sdim                                            D->isConstexpr());
2752204643Srdivacky  } else if (isa<CXXDestructorDecl>(D)) {
2753204643Srdivacky    ToFunction = CXXDestructorDecl::Create(Importer.getToContext(),
2754204643Srdivacky                                           cast<CXXRecordDecl>(DC),
2755221345Sdim                                           D->getInnerLocStart(),
2756218893Sdim                                           NameInfo, T, TInfo,
2757204643Srdivacky                                           D->isInlineSpecified(),
2758204643Srdivacky                                           D->isImplicit());
2759204643Srdivacky  } else if (CXXConversionDecl *FromConversion
2760204643Srdivacky                                           = dyn_cast<CXXConversionDecl>(D)) {
2761204643Srdivacky    ToFunction = CXXConversionDecl::Create(Importer.getToContext(),
2762204643Srdivacky                                           cast<CXXRecordDecl>(DC),
2763221345Sdim                                           D->getInnerLocStart(),
2764212904Sdim                                           NameInfo, T, TInfo,
2765204643Srdivacky                                           D->isInlineSpecified(),
2766221345Sdim                                           FromConversion->isExplicit(),
2767226890Sdim                                           D->isConstexpr(),
2768221345Sdim                                           Importer.Import(D->getLocEnd()));
2769218893Sdim  } else if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
2770218893Sdim    ToFunction = CXXMethodDecl::Create(Importer.getToContext(),
2771218893Sdim                                       cast<CXXRecordDecl>(DC),
2772221345Sdim                                       D->getInnerLocStart(),
2773218893Sdim                                       NameInfo, T, TInfo,
2774252723Sdim                                       Method->getStorageClass(),
2775221345Sdim                                       Method->isInlineSpecified(),
2776226890Sdim                                       D->isConstexpr(),
2777221345Sdim                                       Importer.Import(D->getLocEnd()));
2778204643Srdivacky  } else {
2779212904Sdim    ToFunction = FunctionDecl::Create(Importer.getToContext(), DC,
2780221345Sdim                                      D->getInnerLocStart(),
2781212904Sdim                                      NameInfo, T, TInfo, D->getStorageClass(),
2782204643Srdivacky                                      D->isInlineSpecified(),
2783226890Sdim                                      D->hasWrittenPrototype(),
2784226890Sdim                                      D->isConstexpr());
2785204643Srdivacky  }
2786205219Srdivacky
2787205219Srdivacky  // Import the qualifier, if any.
2788219077Sdim  ToFunction->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
2789204643Srdivacky  ToFunction->setAccess(D->getAccess());
2790204643Srdivacky  ToFunction->setLexicalDeclContext(LexicalDC);
2791218893Sdim  ToFunction->setVirtualAsWritten(D->isVirtualAsWritten());
2792218893Sdim  ToFunction->setTrivial(D->isTrivial());
2793218893Sdim  ToFunction->setPure(D->isPure());
2794204643Srdivacky  Importer.Imported(D, ToFunction);
2795203955Srdivacky
2796203955Srdivacky  // Set the parameters.
2797203955Srdivacky  for (unsigned I = 0, N = Parameters.size(); I != N; ++I) {
2798204643Srdivacky    Parameters[I]->setOwningFunction(ToFunction);
2799235633Sdim    ToFunction->addDeclInternal(Parameters[I]);
2800203955Srdivacky  }
2801226890Sdim  ToFunction->setParams(Parameters);
2802203955Srdivacky
2803245431Sdim  if (usedDifferentExceptionSpec) {
2804245431Sdim    // Update FunctionProtoType::ExtProtoInfo.
2805245431Sdim    QualType T = Importer.Import(D->getType());
2806245431Sdim    if (T.isNull())
2807245431Sdim      return 0;
2808245431Sdim    ToFunction->setType(T);
2809245431Sdim  }
2810245431Sdim
2811203955Srdivacky  // FIXME: Other bits to merge?
2812218893Sdim
2813218893Sdim  // Add this function to the lexical context.
2814235633Sdim  LexicalDC->addDeclInternal(ToFunction);
2815218893Sdim
2816204643Srdivacky  return ToFunction;
2817203955Srdivacky}
2818203955Srdivacky
2819204643SrdivackyDecl *ASTNodeImporter::VisitCXXMethodDecl(CXXMethodDecl *D) {
2820204643Srdivacky  return VisitFunctionDecl(D);
2821204643Srdivacky}
2822204643Srdivacky
2823204643SrdivackyDecl *ASTNodeImporter::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
2824204643Srdivacky  return VisitCXXMethodDecl(D);
2825204643Srdivacky}
2826204643Srdivacky
2827204643SrdivackyDecl *ASTNodeImporter::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
2828204643Srdivacky  return VisitCXXMethodDecl(D);
2829204643Srdivacky}
2830204643Srdivacky
2831204643SrdivackyDecl *ASTNodeImporter::VisitCXXConversionDecl(CXXConversionDecl *D) {
2832204643Srdivacky  return VisitCXXMethodDecl(D);
2833204643Srdivacky}
2834204643Srdivacky
2835245431Sdimstatic unsigned getFieldIndex(Decl *F) {
2836245431Sdim  RecordDecl *Owner = dyn_cast<RecordDecl>(F->getDeclContext());
2837245431Sdim  if (!Owner)
2838245431Sdim    return 0;
2839245431Sdim
2840245431Sdim  unsigned Index = 1;
2841245431Sdim  for (DeclContext::decl_iterator D = Owner->noload_decls_begin(),
2842245431Sdim                               DEnd = Owner->noload_decls_end();
2843245431Sdim       D != DEnd; ++D) {
2844245431Sdim    if (*D == F)
2845245431Sdim      return Index;
2846245431Sdim
2847245431Sdim    if (isa<FieldDecl>(*D) || isa<IndirectFieldDecl>(*D))
2848245431Sdim      ++Index;
2849245431Sdim  }
2850245431Sdim
2851245431Sdim  return Index;
2852245431Sdim}
2853245431Sdim
2854203955SrdivackyDecl *ASTNodeImporter::VisitFieldDecl(FieldDecl *D) {
2855203955Srdivacky  // Import the major distinguishing characteristics of a variable.
2856203955Srdivacky  DeclContext *DC, *LexicalDC;
2857203955Srdivacky  DeclarationName Name;
2858203955Srdivacky  SourceLocation Loc;
2859203955Srdivacky  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2860203955Srdivacky    return 0;
2861203955Srdivacky
2862226890Sdim  // Determine whether we've already imported this field.
2863252723Sdim  SmallVector<NamedDecl *, 2> FoundDecls;
2864226890Sdim  DC->localUncachedLookup(Name, FoundDecls);
2865226890Sdim  for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
2866226890Sdim    if (FieldDecl *FoundField = dyn_cast<FieldDecl>(FoundDecls[I])) {
2867245431Sdim      // For anonymous fields, match up by index.
2868245431Sdim      if (!Name && getFieldIndex(D) != getFieldIndex(FoundField))
2869245431Sdim        continue;
2870245431Sdim
2871226890Sdim      if (Importer.IsStructurallyEquivalent(D->getType(),
2872226890Sdim                                            FoundField->getType())) {
2873226890Sdim        Importer.Imported(D, FoundField);
2874226890Sdim        return FoundField;
2875226890Sdim      }
2876226890Sdim
2877226890Sdim      Importer.ToDiag(Loc, diag::err_odr_field_type_inconsistent)
2878226890Sdim        << Name << D->getType() << FoundField->getType();
2879226890Sdim      Importer.ToDiag(FoundField->getLocation(), diag::note_odr_value_here)
2880226890Sdim        << FoundField->getType();
2881226890Sdim      return 0;
2882226890Sdim    }
2883226890Sdim  }
2884226890Sdim
2885203955Srdivacky  // Import the type.
2886203955Srdivacky  QualType T = Importer.Import(D->getType());
2887203955Srdivacky  if (T.isNull())
2888203955Srdivacky    return 0;
2889203955Srdivacky
2890203955Srdivacky  TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
2891203955Srdivacky  Expr *BitWidth = Importer.Import(D->getBitWidth());
2892203955Srdivacky  if (!BitWidth && D->getBitWidth())
2893203955Srdivacky    return 0;
2894203955Srdivacky
2895221345Sdim  FieldDecl *ToField = FieldDecl::Create(Importer.getToContext(), DC,
2896221345Sdim                                         Importer.Import(D->getInnerLocStart()),
2897203955Srdivacky                                         Loc, Name.getAsIdentifierInfo(),
2898223017Sdim                                         T, TInfo, BitWidth, D->isMutable(),
2899245431Sdim                                         D->getInClassInitStyle());
2900204643Srdivacky  ToField->setAccess(D->getAccess());
2901203955Srdivacky  ToField->setLexicalDeclContext(LexicalDC);
2902223017Sdim  if (ToField->hasInClassInitializer())
2903223017Sdim    ToField->setInClassInitializer(D->getInClassInitializer());
2904245431Sdim  ToField->setImplicit(D->isImplicit());
2905203955Srdivacky  Importer.Imported(D, ToField);
2906235633Sdim  LexicalDC->addDeclInternal(ToField);
2907203955Srdivacky  return ToField;
2908203955Srdivacky}
2909203955Srdivacky
2910218893SdimDecl *ASTNodeImporter::VisitIndirectFieldDecl(IndirectFieldDecl *D) {
2911218893Sdim  // Import the major distinguishing characteristics of a variable.
2912218893Sdim  DeclContext *DC, *LexicalDC;
2913218893Sdim  DeclarationName Name;
2914218893Sdim  SourceLocation Loc;
2915218893Sdim  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2916218893Sdim    return 0;
2917218893Sdim
2918226890Sdim  // Determine whether we've already imported this field.
2919252723Sdim  SmallVector<NamedDecl *, 2> FoundDecls;
2920226890Sdim  DC->localUncachedLookup(Name, FoundDecls);
2921226890Sdim  for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
2922226890Sdim    if (IndirectFieldDecl *FoundField
2923226890Sdim                                = dyn_cast<IndirectFieldDecl>(FoundDecls[I])) {
2924245431Sdim      // For anonymous indirect fields, match up by index.
2925245431Sdim      if (!Name && getFieldIndex(D) != getFieldIndex(FoundField))
2926245431Sdim        continue;
2927245431Sdim
2928226890Sdim      if (Importer.IsStructurallyEquivalent(D->getType(),
2929245431Sdim                                            FoundField->getType(),
2930263509Sdim                                            !Name.isEmpty())) {
2931226890Sdim        Importer.Imported(D, FoundField);
2932226890Sdim        return FoundField;
2933226890Sdim      }
2934245431Sdim
2935245431Sdim      // If there are more anonymous fields to check, continue.
2936245431Sdim      if (!Name && I < N-1)
2937245431Sdim        continue;
2938245431Sdim
2939226890Sdim      Importer.ToDiag(Loc, diag::err_odr_field_type_inconsistent)
2940226890Sdim        << Name << D->getType() << FoundField->getType();
2941226890Sdim      Importer.ToDiag(FoundField->getLocation(), diag::note_odr_value_here)
2942226890Sdim        << FoundField->getType();
2943226890Sdim      return 0;
2944226890Sdim    }
2945226890Sdim  }
2946226890Sdim
2947218893Sdim  // Import the type.
2948218893Sdim  QualType T = Importer.Import(D->getType());
2949218893Sdim  if (T.isNull())
2950218893Sdim    return 0;
2951218893Sdim
2952218893Sdim  NamedDecl **NamedChain =
2953218893Sdim    new (Importer.getToContext())NamedDecl*[D->getChainingSize()];
2954218893Sdim
2955218893Sdim  unsigned i = 0;
2956218893Sdim  for (IndirectFieldDecl::chain_iterator PI = D->chain_begin(),
2957218893Sdim       PE = D->chain_end(); PI != PE; ++PI) {
2958218893Sdim    Decl* D = Importer.Import(*PI);
2959218893Sdim    if (!D)
2960218893Sdim      return 0;
2961218893Sdim    NamedChain[i++] = cast<NamedDecl>(D);
2962218893Sdim  }
2963218893Sdim
2964218893Sdim  IndirectFieldDecl *ToIndirectField = IndirectFieldDecl::Create(
2965218893Sdim                                         Importer.getToContext(), DC,
2966218893Sdim                                         Loc, Name.getAsIdentifierInfo(), T,
2967218893Sdim                                         NamedChain, D->getChainingSize());
2968218893Sdim  ToIndirectField->setAccess(D->getAccess());
2969218893Sdim  ToIndirectField->setLexicalDeclContext(LexicalDC);
2970218893Sdim  Importer.Imported(D, ToIndirectField);
2971235633Sdim  LexicalDC->addDeclInternal(ToIndirectField);
2972218893Sdim  return ToIndirectField;
2973218893Sdim}
2974218893Sdim
2975204643SrdivackyDecl *ASTNodeImporter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
2976204643Srdivacky  // Import the major distinguishing characteristics of an ivar.
2977204643Srdivacky  DeclContext *DC, *LexicalDC;
2978204643Srdivacky  DeclarationName Name;
2979204643Srdivacky  SourceLocation Loc;
2980204643Srdivacky  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2981204643Srdivacky    return 0;
2982204643Srdivacky
2983204643Srdivacky  // Determine whether we've already imported this ivar
2984252723Sdim  SmallVector<NamedDecl *, 2> FoundDecls;
2985226890Sdim  DC->localUncachedLookup(Name, FoundDecls);
2986226890Sdim  for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
2987226890Sdim    if (ObjCIvarDecl *FoundIvar = dyn_cast<ObjCIvarDecl>(FoundDecls[I])) {
2988204643Srdivacky      if (Importer.IsStructurallyEquivalent(D->getType(),
2989204643Srdivacky                                            FoundIvar->getType())) {
2990204643Srdivacky        Importer.Imported(D, FoundIvar);
2991204643Srdivacky        return FoundIvar;
2992204643Srdivacky      }
2993204643Srdivacky
2994204643Srdivacky      Importer.ToDiag(Loc, diag::err_odr_ivar_type_inconsistent)
2995204643Srdivacky        << Name << D->getType() << FoundIvar->getType();
2996204643Srdivacky      Importer.ToDiag(FoundIvar->getLocation(), diag::note_odr_value_here)
2997204643Srdivacky        << FoundIvar->getType();
2998204643Srdivacky      return 0;
2999204643Srdivacky    }
3000204643Srdivacky  }
3001204643Srdivacky
3002204643Srdivacky  // Import the type.
3003204643Srdivacky  QualType T = Importer.Import(D->getType());
3004204643Srdivacky  if (T.isNull())
3005204643Srdivacky    return 0;
3006204643Srdivacky
3007204643Srdivacky  TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
3008204643Srdivacky  Expr *BitWidth = Importer.Import(D->getBitWidth());
3009204643Srdivacky  if (!BitWidth && D->getBitWidth())
3010204643Srdivacky    return 0;
3011204643Srdivacky
3012206125Srdivacky  ObjCIvarDecl *ToIvar = ObjCIvarDecl::Create(Importer.getToContext(),
3013206125Srdivacky                                              cast<ObjCContainerDecl>(DC),
3014221345Sdim                                       Importer.Import(D->getInnerLocStart()),
3015204643Srdivacky                                              Loc, Name.getAsIdentifierInfo(),
3016204643Srdivacky                                              T, TInfo, D->getAccessControl(),
3017263509Sdim                                              BitWidth, D->getSynthesize(),
3018263509Sdim                                              D->getBackingIvarReferencedInAccessor());
3019204643Srdivacky  ToIvar->setLexicalDeclContext(LexicalDC);
3020204643Srdivacky  Importer.Imported(D, ToIvar);
3021235633Sdim  LexicalDC->addDeclInternal(ToIvar);
3022204643Srdivacky  return ToIvar;
3023204643Srdivacky
3024204643Srdivacky}
3025204643Srdivacky
3026203955SrdivackyDecl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
3027203955Srdivacky  // Import the major distinguishing characteristics of a variable.
3028203955Srdivacky  DeclContext *DC, *LexicalDC;
3029203955Srdivacky  DeclarationName Name;
3030203955Srdivacky  SourceLocation Loc;
3031203955Srdivacky  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
3032203955Srdivacky    return 0;
3033203955Srdivacky
3034203955Srdivacky  // Try to find a variable in our own ("to") context with the same name and
3035203955Srdivacky  // in the same context as the variable we're importing.
3036203955Srdivacky  if (D->isFileVarDecl()) {
3037203955Srdivacky    VarDecl *MergeWithVar = 0;
3038226890Sdim    SmallVector<NamedDecl *, 4> ConflictingDecls;
3039203955Srdivacky    unsigned IDNS = Decl::IDNS_Ordinary;
3040252723Sdim    SmallVector<NamedDecl *, 2> FoundDecls;
3041226890Sdim    DC->localUncachedLookup(Name, FoundDecls);
3042226890Sdim    for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
3043226890Sdim      if (!FoundDecls[I]->isInIdentifierNamespace(IDNS))
3044203955Srdivacky        continue;
3045203955Srdivacky
3046226890Sdim      if (VarDecl *FoundVar = dyn_cast<VarDecl>(FoundDecls[I])) {
3047203955Srdivacky        // We have found a variable that we may need to merge with. Check it.
3048263509Sdim        if (FoundVar->hasExternalFormalLinkage() &&
3049263509Sdim            D->hasExternalFormalLinkage()) {
3050203955Srdivacky          if (Importer.IsStructurallyEquivalent(D->getType(),
3051203955Srdivacky                                                FoundVar->getType())) {
3052203955Srdivacky            MergeWithVar = FoundVar;
3053203955Srdivacky            break;
3054203955Srdivacky          }
3055203955Srdivacky
3056203955Srdivacky          const ArrayType *FoundArray
3057203955Srdivacky            = Importer.getToContext().getAsArrayType(FoundVar->getType());
3058203955Srdivacky          const ArrayType *TArray
3059203955Srdivacky            = Importer.getToContext().getAsArrayType(D->getType());
3060203955Srdivacky          if (FoundArray && TArray) {
3061203955Srdivacky            if (isa<IncompleteArrayType>(FoundArray) &&
3062203955Srdivacky                isa<ConstantArrayType>(TArray)) {
3063203955Srdivacky              // Import the type.
3064203955Srdivacky              QualType T = Importer.Import(D->getType());
3065203955Srdivacky              if (T.isNull())
3066203955Srdivacky                return 0;
3067203955Srdivacky
3068203955Srdivacky              FoundVar->setType(T);
3069203955Srdivacky              MergeWithVar = FoundVar;
3070203955Srdivacky              break;
3071203955Srdivacky            } else if (isa<IncompleteArrayType>(TArray) &&
3072203955Srdivacky                       isa<ConstantArrayType>(FoundArray)) {
3073203955Srdivacky              MergeWithVar = FoundVar;
3074203955Srdivacky              break;
3075203955Srdivacky            }
3076203955Srdivacky          }
3077203955Srdivacky
3078203955Srdivacky          Importer.ToDiag(Loc, diag::err_odr_variable_type_inconsistent)
3079203955Srdivacky            << Name << D->getType() << FoundVar->getType();
3080203955Srdivacky          Importer.ToDiag(FoundVar->getLocation(), diag::note_odr_value_here)
3081203955Srdivacky            << FoundVar->getType();
3082203955Srdivacky        }
3083203955Srdivacky      }
3084203955Srdivacky
3085226890Sdim      ConflictingDecls.push_back(FoundDecls[I]);
3086203955Srdivacky    }
3087203955Srdivacky
3088203955Srdivacky    if (MergeWithVar) {
3089203955Srdivacky      // An equivalent variable with external linkage has been found. Link
3090203955Srdivacky      // the two declarations, then merge them.
3091203955Srdivacky      Importer.Imported(D, MergeWithVar);
3092203955Srdivacky
3093203955Srdivacky      if (VarDecl *DDef = D->getDefinition()) {
3094203955Srdivacky        if (VarDecl *ExistingDef = MergeWithVar->getDefinition()) {
3095203955Srdivacky          Importer.ToDiag(ExistingDef->getLocation(),
3096203955Srdivacky                          diag::err_odr_variable_multiple_def)
3097203955Srdivacky            << Name;
3098203955Srdivacky          Importer.FromDiag(DDef->getLocation(), diag::note_odr_defined_here);
3099203955Srdivacky        } else {
3100203955Srdivacky          Expr *Init = Importer.Import(DDef->getInit());
3101203955Srdivacky          MergeWithVar->setInit(Init);
3102235633Sdim          if (DDef->isInitKnownICE()) {
3103235633Sdim            EvaluatedStmt *Eval = MergeWithVar->ensureEvaluatedStmt();
3104235633Sdim            Eval->CheckedICE = true;
3105235633Sdim            Eval->IsICE = DDef->isInitICE();
3106235633Sdim          }
3107203955Srdivacky        }
3108203955Srdivacky      }
3109203955Srdivacky
3110203955Srdivacky      return MergeWithVar;
3111203955Srdivacky    }
3112203955Srdivacky
3113203955Srdivacky    if (!ConflictingDecls.empty()) {
3114203955Srdivacky      Name = Importer.HandleNameConflict(Name, DC, IDNS,
3115203955Srdivacky                                         ConflictingDecls.data(),
3116203955Srdivacky                                         ConflictingDecls.size());
3117203955Srdivacky      if (!Name)
3118203955Srdivacky        return 0;
3119203955Srdivacky    }
3120203955Srdivacky  }
3121203955Srdivacky
3122203955Srdivacky  // Import the type.
3123203955Srdivacky  QualType T = Importer.Import(D->getType());
3124203955Srdivacky  if (T.isNull())
3125203955Srdivacky    return 0;
3126203955Srdivacky
3127203955Srdivacky  // Create the imported variable.
3128203955Srdivacky  TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
3129221345Sdim  VarDecl *ToVar = VarDecl::Create(Importer.getToContext(), DC,
3130221345Sdim                                   Importer.Import(D->getInnerLocStart()),
3131221345Sdim                                   Loc, Name.getAsIdentifierInfo(),
3132221345Sdim                                   T, TInfo,
3133252723Sdim                                   D->getStorageClass());
3134219077Sdim  ToVar->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
3135204643Srdivacky  ToVar->setAccess(D->getAccess());
3136203955Srdivacky  ToVar->setLexicalDeclContext(LexicalDC);
3137203955Srdivacky  Importer.Imported(D, ToVar);
3138235633Sdim  LexicalDC->addDeclInternal(ToVar);
3139203955Srdivacky
3140203955Srdivacky  // Merge the initializer.
3141263509Sdim  if (ImportDefinition(D, ToVar))
3142263509Sdim    return 0;
3143203955Srdivacky
3144203955Srdivacky  return ToVar;
3145203955Srdivacky}
3146203955Srdivacky
3147204643SrdivackyDecl *ASTNodeImporter::VisitImplicitParamDecl(ImplicitParamDecl *D) {
3148204643Srdivacky  // Parameters are created in the translation unit's context, then moved
3149204643Srdivacky  // into the function declaration's context afterward.
3150204643Srdivacky  DeclContext *DC = Importer.getToContext().getTranslationUnitDecl();
3151204643Srdivacky
3152204643Srdivacky  // Import the name of this declaration.
3153204643Srdivacky  DeclarationName Name = Importer.Import(D->getDeclName());
3154204643Srdivacky  if (D->getDeclName() && !Name)
3155204643Srdivacky    return 0;
3156204643Srdivacky
3157204643Srdivacky  // Import the location of this declaration.
3158204643Srdivacky  SourceLocation Loc = Importer.Import(D->getLocation());
3159204643Srdivacky
3160204643Srdivacky  // Import the parameter's type.
3161204643Srdivacky  QualType T = Importer.Import(D->getType());
3162204643Srdivacky  if (T.isNull())
3163204643Srdivacky    return 0;
3164204643Srdivacky
3165204643Srdivacky  // Create the imported parameter.
3166204643Srdivacky  ImplicitParamDecl *ToParm
3167204643Srdivacky    = ImplicitParamDecl::Create(Importer.getToContext(), DC,
3168204643Srdivacky                                Loc, Name.getAsIdentifierInfo(),
3169204643Srdivacky                                T);
3170204643Srdivacky  return Importer.Imported(D, ToParm);
3171204643Srdivacky}
3172204643Srdivacky
3173203955SrdivackyDecl *ASTNodeImporter::VisitParmVarDecl(ParmVarDecl *D) {
3174203955Srdivacky  // Parameters are created in the translation unit's context, then moved
3175203955Srdivacky  // into the function declaration's context afterward.
3176203955Srdivacky  DeclContext *DC = Importer.getToContext().getTranslationUnitDecl();
3177203955Srdivacky
3178203955Srdivacky  // Import the name of this declaration.
3179203955Srdivacky  DeclarationName Name = Importer.Import(D->getDeclName());
3180203955Srdivacky  if (D->getDeclName() && !Name)
3181203955Srdivacky    return 0;
3182203955Srdivacky
3183203955Srdivacky  // Import the location of this declaration.
3184203955Srdivacky  SourceLocation Loc = Importer.Import(D->getLocation());
3185203955Srdivacky
3186203955Srdivacky  // Import the parameter's type.
3187203955Srdivacky  QualType T = Importer.Import(D->getType());
3188203955Srdivacky  if (T.isNull())
3189203955Srdivacky    return 0;
3190203955Srdivacky
3191203955Srdivacky  // Create the imported parameter.
3192203955Srdivacky  TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
3193203955Srdivacky  ParmVarDecl *ToParm = ParmVarDecl::Create(Importer.getToContext(), DC,
3194221345Sdim                                     Importer.Import(D->getInnerLocStart()),
3195203955Srdivacky                                            Loc, Name.getAsIdentifierInfo(),
3196203955Srdivacky                                            T, TInfo, D->getStorageClass(),
3197203955Srdivacky                                            /*FIXME: Default argument*/ 0);
3198205219Srdivacky  ToParm->setHasInheritedDefaultArg(D->hasInheritedDefaultArg());
3199203955Srdivacky  return Importer.Imported(D, ToParm);
3200203955Srdivacky}
3201203955Srdivacky
3202204643SrdivackyDecl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
3203204643Srdivacky  // Import the major distinguishing characteristics of a method.
3204204643Srdivacky  DeclContext *DC, *LexicalDC;
3205204643Srdivacky  DeclarationName Name;
3206204643Srdivacky  SourceLocation Loc;
3207204643Srdivacky  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
3208204643Srdivacky    return 0;
3209204643Srdivacky
3210252723Sdim  SmallVector<NamedDecl *, 2> FoundDecls;
3211226890Sdim  DC->localUncachedLookup(Name, FoundDecls);
3212226890Sdim  for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
3213226890Sdim    if (ObjCMethodDecl *FoundMethod = dyn_cast<ObjCMethodDecl>(FoundDecls[I])) {
3214204643Srdivacky      if (FoundMethod->isInstanceMethod() != D->isInstanceMethod())
3215204643Srdivacky        continue;
3216204643Srdivacky
3217204643Srdivacky      // Check return types.
3218204643Srdivacky      if (!Importer.IsStructurallyEquivalent(D->getResultType(),
3219204643Srdivacky                                             FoundMethod->getResultType())) {
3220204643Srdivacky        Importer.ToDiag(Loc, diag::err_odr_objc_method_result_type_inconsistent)
3221204643Srdivacky          << D->isInstanceMethod() << Name
3222204643Srdivacky          << D->getResultType() << FoundMethod->getResultType();
3223204643Srdivacky        Importer.ToDiag(FoundMethod->getLocation(),
3224204643Srdivacky                        diag::note_odr_objc_method_here)
3225204643Srdivacky          << D->isInstanceMethod() << Name;
3226204643Srdivacky        return 0;
3227204643Srdivacky      }
3228204643Srdivacky
3229204643Srdivacky      // Check the number of parameters.
3230204643Srdivacky      if (D->param_size() != FoundMethod->param_size()) {
3231204643Srdivacky        Importer.ToDiag(Loc, diag::err_odr_objc_method_num_params_inconsistent)
3232204643Srdivacky          << D->isInstanceMethod() << Name
3233204643Srdivacky          << D->param_size() << FoundMethod->param_size();
3234204643Srdivacky        Importer.ToDiag(FoundMethod->getLocation(),
3235204643Srdivacky                        diag::note_odr_objc_method_here)
3236204643Srdivacky          << D->isInstanceMethod() << Name;
3237204643Srdivacky        return 0;
3238204643Srdivacky      }
3239204643Srdivacky
3240204643Srdivacky      // Check parameter types.
3241204643Srdivacky      for (ObjCMethodDecl::param_iterator P = D->param_begin(),
3242204643Srdivacky             PEnd = D->param_end(), FoundP = FoundMethod->param_begin();
3243204643Srdivacky           P != PEnd; ++P, ++FoundP) {
3244204643Srdivacky        if (!Importer.IsStructurallyEquivalent((*P)->getType(),
3245204643Srdivacky                                               (*FoundP)->getType())) {
3246204643Srdivacky          Importer.FromDiag((*P)->getLocation(),
3247204643Srdivacky                            diag::err_odr_objc_method_param_type_inconsistent)
3248204643Srdivacky            << D->isInstanceMethod() << Name
3249204643Srdivacky            << (*P)->getType() << (*FoundP)->getType();
3250204643Srdivacky          Importer.ToDiag((*FoundP)->getLocation(), diag::note_odr_value_here)
3251204643Srdivacky            << (*FoundP)->getType();
3252204643Srdivacky          return 0;
3253204643Srdivacky        }
3254204643Srdivacky      }
3255204643Srdivacky
3256204643Srdivacky      // Check variadic/non-variadic.
3257204643Srdivacky      // Check the number of parameters.
3258204643Srdivacky      if (D->isVariadic() != FoundMethod->isVariadic()) {
3259204643Srdivacky        Importer.ToDiag(Loc, diag::err_odr_objc_method_variadic_inconsistent)
3260204643Srdivacky          << D->isInstanceMethod() << Name;
3261204643Srdivacky        Importer.ToDiag(FoundMethod->getLocation(),
3262204643Srdivacky                        diag::note_odr_objc_method_here)
3263204643Srdivacky          << D->isInstanceMethod() << Name;
3264204643Srdivacky        return 0;
3265204643Srdivacky      }
3266204643Srdivacky
3267204643Srdivacky      // FIXME: Any other bits we need to merge?
3268204643Srdivacky      return Importer.Imported(D, FoundMethod);
3269204643Srdivacky    }
3270204643Srdivacky  }
3271204643Srdivacky
3272204643Srdivacky  // Import the result type.
3273204643Srdivacky  QualType ResultTy = Importer.Import(D->getResultType());
3274204643Srdivacky  if (ResultTy.isNull())
3275204643Srdivacky    return 0;
3276204643Srdivacky
3277204962Srdivacky  TypeSourceInfo *ResultTInfo = Importer.Import(D->getResultTypeSourceInfo());
3278204962Srdivacky
3279204643Srdivacky  ObjCMethodDecl *ToMethod
3280204643Srdivacky    = ObjCMethodDecl::Create(Importer.getToContext(),
3281204643Srdivacky                             Loc,
3282204643Srdivacky                             Importer.Import(D->getLocEnd()),
3283204643Srdivacky                             Name.getObjCSelector(),
3284204962Srdivacky                             ResultTy, ResultTInfo, DC,
3285204643Srdivacky                             D->isInstanceMethod(),
3286204643Srdivacky                             D->isVariadic(),
3287245431Sdim                             D->isPropertyAccessor(),
3288226890Sdim                             D->isImplicit(),
3289212904Sdim                             D->isDefined(),
3290223017Sdim                             D->getImplementationControl(),
3291223017Sdim                             D->hasRelatedResultType());
3292204643Srdivacky
3293204643Srdivacky  // FIXME: When we decide to merge method definitions, we'll need to
3294204643Srdivacky  // deal with implicit parameters.
3295204643Srdivacky
3296204643Srdivacky  // Import the parameters
3297226890Sdim  SmallVector<ParmVarDecl *, 5> ToParams;
3298204643Srdivacky  for (ObjCMethodDecl::param_iterator FromP = D->param_begin(),
3299204643Srdivacky                                   FromPEnd = D->param_end();
3300204643Srdivacky       FromP != FromPEnd;
3301204643Srdivacky       ++FromP) {
3302204643Srdivacky    ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(*FromP));
3303204643Srdivacky    if (!ToP)
3304204643Srdivacky      return 0;
3305204643Srdivacky
3306204643Srdivacky    ToParams.push_back(ToP);
3307204643Srdivacky  }
3308204643Srdivacky
3309204643Srdivacky  // Set the parameters.
3310204643Srdivacky  for (unsigned I = 0, N = ToParams.size(); I != N; ++I) {
3311204643Srdivacky    ToParams[I]->setOwningFunction(ToMethod);
3312235633Sdim    ToMethod->addDeclInternal(ToParams[I]);
3313204643Srdivacky  }
3314226890Sdim  SmallVector<SourceLocation, 12> SelLocs;
3315226890Sdim  D->getSelectorLocs(SelLocs);
3316226890Sdim  ToMethod->setMethodParams(Importer.getToContext(), ToParams, SelLocs);
3317204643Srdivacky
3318204643Srdivacky  ToMethod->setLexicalDeclContext(LexicalDC);
3319204643Srdivacky  Importer.Imported(D, ToMethod);
3320235633Sdim  LexicalDC->addDeclInternal(ToMethod);
3321204643Srdivacky  return ToMethod;
3322204643Srdivacky}
3323204643Srdivacky
3324204643SrdivackyDecl *ASTNodeImporter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
3325204643Srdivacky  // Import the major distinguishing characteristics of a category.
3326204643Srdivacky  DeclContext *DC, *LexicalDC;
3327204643Srdivacky  DeclarationName Name;
3328204643Srdivacky  SourceLocation Loc;
3329204643Srdivacky  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
3330204643Srdivacky    return 0;
3331204643Srdivacky
3332204643Srdivacky  ObjCInterfaceDecl *ToInterface
3333204643Srdivacky    = cast_or_null<ObjCInterfaceDecl>(Importer.Import(D->getClassInterface()));
3334204643Srdivacky  if (!ToInterface)
3335204643Srdivacky    return 0;
3336204643Srdivacky
3337204643Srdivacky  // Determine if we've already encountered this category.
3338204643Srdivacky  ObjCCategoryDecl *MergeWithCategory
3339204643Srdivacky    = ToInterface->FindCategoryDeclaration(Name.getAsIdentifierInfo());
3340204643Srdivacky  ObjCCategoryDecl *ToCategory = MergeWithCategory;
3341204643Srdivacky  if (!ToCategory) {
3342204643Srdivacky    ToCategory = ObjCCategoryDecl::Create(Importer.getToContext(), DC,
3343226890Sdim                                          Importer.Import(D->getAtStartLoc()),
3344204643Srdivacky                                          Loc,
3345204643Srdivacky                                       Importer.Import(D->getCategoryNameLoc()),
3346226890Sdim                                          Name.getAsIdentifierInfo(),
3347235633Sdim                                          ToInterface,
3348235633Sdim                                       Importer.Import(D->getIvarLBraceLoc()),
3349235633Sdim                                       Importer.Import(D->getIvarRBraceLoc()));
3350204643Srdivacky    ToCategory->setLexicalDeclContext(LexicalDC);
3351235633Sdim    LexicalDC->addDeclInternal(ToCategory);
3352204643Srdivacky    Importer.Imported(D, ToCategory);
3353204643Srdivacky
3354204643Srdivacky    // Import protocols
3355226890Sdim    SmallVector<ObjCProtocolDecl *, 4> Protocols;
3356226890Sdim    SmallVector<SourceLocation, 4> ProtocolLocs;
3357204643Srdivacky    ObjCCategoryDecl::protocol_loc_iterator FromProtoLoc
3358204643Srdivacky      = D->protocol_loc_begin();
3359204643Srdivacky    for (ObjCCategoryDecl::protocol_iterator FromProto = D->protocol_begin(),
3360204643Srdivacky                                          FromProtoEnd = D->protocol_end();
3361204643Srdivacky         FromProto != FromProtoEnd;
3362204643Srdivacky         ++FromProto, ++FromProtoLoc) {
3363204643Srdivacky      ObjCProtocolDecl *ToProto
3364204643Srdivacky        = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
3365204643Srdivacky      if (!ToProto)
3366204643Srdivacky        return 0;
3367204643Srdivacky      Protocols.push_back(ToProto);
3368204643Srdivacky      ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
3369204643Srdivacky    }
3370204643Srdivacky
3371204643Srdivacky    // FIXME: If we're merging, make sure that the protocol list is the same.
3372204643Srdivacky    ToCategory->setProtocolList(Protocols.data(), Protocols.size(),
3373204643Srdivacky                                ProtocolLocs.data(), Importer.getToContext());
3374204643Srdivacky
3375204643Srdivacky  } else {
3376204643Srdivacky    Importer.Imported(D, ToCategory);
3377204643Srdivacky  }
3378204643Srdivacky
3379204643Srdivacky  // Import all of the members of this category.
3380204643Srdivacky  ImportDeclContext(D);
3381204643Srdivacky
3382204643Srdivacky  // If we have an implementation, import it as well.
3383204643Srdivacky  if (D->getImplementation()) {
3384204643Srdivacky    ObjCCategoryImplDecl *Impl
3385218893Sdim      = cast_or_null<ObjCCategoryImplDecl>(
3386218893Sdim                                       Importer.Import(D->getImplementation()));
3387204643Srdivacky    if (!Impl)
3388204643Srdivacky      return 0;
3389204643Srdivacky
3390204643Srdivacky    ToCategory->setImplementation(Impl);
3391204643Srdivacky  }
3392204643Srdivacky
3393204643Srdivacky  return ToCategory;
3394204643Srdivacky}
3395204643Srdivacky
3396235633Sdimbool ASTNodeImporter::ImportDefinition(ObjCProtocolDecl *From,
3397235633Sdim                                       ObjCProtocolDecl *To,
3398235633Sdim                                       ImportDefinitionKind Kind) {
3399235633Sdim  if (To->getDefinition()) {
3400235633Sdim    if (shouldForceImportDeclContext(Kind))
3401235633Sdim      ImportDeclContext(From);
3402235633Sdim    return false;
3403235633Sdim  }
3404235633Sdim
3405235633Sdim  // Start the protocol definition
3406235633Sdim  To->startDefinition();
3407235633Sdim
3408235633Sdim  // Import protocols
3409235633Sdim  SmallVector<ObjCProtocolDecl *, 4> Protocols;
3410235633Sdim  SmallVector<SourceLocation, 4> ProtocolLocs;
3411235633Sdim  ObjCProtocolDecl::protocol_loc_iterator
3412235633Sdim  FromProtoLoc = From->protocol_loc_begin();
3413235633Sdim  for (ObjCProtocolDecl::protocol_iterator FromProto = From->protocol_begin(),
3414235633Sdim                                        FromProtoEnd = From->protocol_end();
3415235633Sdim       FromProto != FromProtoEnd;
3416235633Sdim       ++FromProto, ++FromProtoLoc) {
3417235633Sdim    ObjCProtocolDecl *ToProto
3418235633Sdim      = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
3419235633Sdim    if (!ToProto)
3420235633Sdim      return true;
3421235633Sdim    Protocols.push_back(ToProto);
3422235633Sdim    ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
3423235633Sdim  }
3424235633Sdim
3425235633Sdim  // FIXME: If we're merging, make sure that the protocol list is the same.
3426235633Sdim  To->setProtocolList(Protocols.data(), Protocols.size(),
3427235633Sdim                      ProtocolLocs.data(), Importer.getToContext());
3428235633Sdim
3429235633Sdim  if (shouldForceImportDeclContext(Kind)) {
3430235633Sdim    // Import all of the members of this protocol.
3431235633Sdim    ImportDeclContext(From, /*ForceImport=*/true);
3432235633Sdim  }
3433235633Sdim  return false;
3434235633Sdim}
3435235633Sdim
3436204643SrdivackyDecl *ASTNodeImporter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
3437235633Sdim  // If this protocol has a definition in the translation unit we're coming
3438235633Sdim  // from, but this particular declaration is not that definition, import the
3439235633Sdim  // definition and map to that.
3440235633Sdim  ObjCProtocolDecl *Definition = D->getDefinition();
3441235633Sdim  if (Definition && Definition != D) {
3442235633Sdim    Decl *ImportedDef = Importer.Import(Definition);
3443235633Sdim    if (!ImportedDef)
3444235633Sdim      return 0;
3445235633Sdim
3446235633Sdim    return Importer.Imported(D, ImportedDef);
3447235633Sdim  }
3448235633Sdim
3449204643Srdivacky  // Import the major distinguishing characteristics of a protocol.
3450204643Srdivacky  DeclContext *DC, *LexicalDC;
3451204643Srdivacky  DeclarationName Name;
3452204643Srdivacky  SourceLocation Loc;
3453204643Srdivacky  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
3454204643Srdivacky    return 0;
3455204643Srdivacky
3456204643Srdivacky  ObjCProtocolDecl *MergeWithProtocol = 0;
3457252723Sdim  SmallVector<NamedDecl *, 2> FoundDecls;
3458226890Sdim  DC->localUncachedLookup(Name, FoundDecls);
3459226890Sdim  for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
3460226890Sdim    if (!FoundDecls[I]->isInIdentifierNamespace(Decl::IDNS_ObjCProtocol))
3461204643Srdivacky      continue;
3462204643Srdivacky
3463226890Sdim    if ((MergeWithProtocol = dyn_cast<ObjCProtocolDecl>(FoundDecls[I])))
3464204643Srdivacky      break;
3465204643Srdivacky  }
3466204643Srdivacky
3467204643Srdivacky  ObjCProtocolDecl *ToProto = MergeWithProtocol;
3468235633Sdim  if (!ToProto) {
3469235633Sdim    ToProto = ObjCProtocolDecl::Create(Importer.getToContext(), DC,
3470235633Sdim                                       Name.getAsIdentifierInfo(), Loc,
3471235633Sdim                                       Importer.Import(D->getAtStartLoc()),
3472235633Sdim                                       /*PrevDecl=*/0);
3473235633Sdim    ToProto->setLexicalDeclContext(LexicalDC);
3474235633Sdim    LexicalDC->addDeclInternal(ToProto);
3475235633Sdim  }
3476235633Sdim
3477235633Sdim  Importer.Imported(D, ToProto);
3478235633Sdim
3479235633Sdim  if (D->isThisDeclarationADefinition() && ImportDefinition(D, ToProto))
3480235633Sdim    return 0;
3481235633Sdim
3482235633Sdim  return ToProto;
3483235633Sdim}
3484235633Sdim
3485235633Sdimbool ASTNodeImporter::ImportDefinition(ObjCInterfaceDecl *From,
3486235633Sdim                                       ObjCInterfaceDecl *To,
3487235633Sdim                                       ImportDefinitionKind Kind) {
3488235633Sdim  if (To->getDefinition()) {
3489235633Sdim    // Check consistency of superclass.
3490235633Sdim    ObjCInterfaceDecl *FromSuper = From->getSuperClass();
3491235633Sdim    if (FromSuper) {
3492235633Sdim      FromSuper = cast_or_null<ObjCInterfaceDecl>(Importer.Import(FromSuper));
3493235633Sdim      if (!FromSuper)
3494235633Sdim        return true;
3495204643Srdivacky    }
3496235633Sdim
3497235633Sdim    ObjCInterfaceDecl *ToSuper = To->getSuperClass();
3498235633Sdim    if ((bool)FromSuper != (bool)ToSuper ||
3499235633Sdim        (FromSuper && !declaresSameEntity(FromSuper, ToSuper))) {
3500235633Sdim      Importer.ToDiag(To->getLocation(),
3501235633Sdim                      diag::err_odr_objc_superclass_inconsistent)
3502235633Sdim        << To->getDeclName();
3503235633Sdim      if (ToSuper)
3504235633Sdim        Importer.ToDiag(To->getSuperClassLoc(), diag::note_odr_objc_superclass)
3505235633Sdim          << To->getSuperClass()->getDeclName();
3506235633Sdim      else
3507235633Sdim        Importer.ToDiag(To->getLocation(),
3508235633Sdim                        diag::note_odr_objc_missing_superclass);
3509235633Sdim      if (From->getSuperClass())
3510235633Sdim        Importer.FromDiag(From->getSuperClassLoc(),
3511235633Sdim                          diag::note_odr_objc_superclass)
3512235633Sdim        << From->getSuperClass()->getDeclName();
3513235633Sdim      else
3514235633Sdim        Importer.FromDiag(From->getLocation(),
3515235633Sdim                          diag::note_odr_objc_missing_superclass);
3516235633Sdim    }
3517235633Sdim
3518235633Sdim    if (shouldForceImportDeclContext(Kind))
3519235633Sdim      ImportDeclContext(From);
3520235633Sdim    return false;
3521235633Sdim  }
3522235633Sdim
3523235633Sdim  // Start the definition.
3524235633Sdim  To->startDefinition();
3525235633Sdim
3526235633Sdim  // If this class has a superclass, import it.
3527235633Sdim  if (From->getSuperClass()) {
3528235633Sdim    ObjCInterfaceDecl *Super = cast_or_null<ObjCInterfaceDecl>(
3529235633Sdim                                 Importer.Import(From->getSuperClass()));
3530235633Sdim    if (!Super)
3531235633Sdim      return true;
3532235633Sdim
3533235633Sdim    To->setSuperClass(Super);
3534235633Sdim    To->setSuperClassLoc(Importer.Import(From->getSuperClassLoc()));
3535235633Sdim  }
3536235633Sdim
3537235633Sdim  // Import protocols
3538235633Sdim  SmallVector<ObjCProtocolDecl *, 4> Protocols;
3539235633Sdim  SmallVector<SourceLocation, 4> ProtocolLocs;
3540235633Sdim  ObjCInterfaceDecl::protocol_loc_iterator
3541235633Sdim  FromProtoLoc = From->protocol_loc_begin();
3542235633Sdim
3543235633Sdim  for (ObjCInterfaceDecl::protocol_iterator FromProto = From->protocol_begin(),
3544235633Sdim                                         FromProtoEnd = From->protocol_end();
3545204643Srdivacky       FromProto != FromProtoEnd;
3546204643Srdivacky       ++FromProto, ++FromProtoLoc) {
3547235633Sdim    ObjCProtocolDecl *ToProto
3548235633Sdim      = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
3549235633Sdim    if (!ToProto)
3550235633Sdim      return true;
3551235633Sdim    Protocols.push_back(ToProto);
3552235633Sdim    ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
3553235633Sdim  }
3554235633Sdim
3555235633Sdim  // FIXME: If we're merging, make sure that the protocol list is the same.
3556235633Sdim  To->setProtocolList(Protocols.data(), Protocols.size(),
3557235633Sdim                      ProtocolLocs.data(), Importer.getToContext());
3558235633Sdim
3559235633Sdim  // Import categories. When the categories themselves are imported, they'll
3560235633Sdim  // hook themselves into this interface.
3561252723Sdim  for (ObjCInterfaceDecl::known_categories_iterator
3562252723Sdim         Cat = From->known_categories_begin(),
3563252723Sdim         CatEnd = From->known_categories_end();
3564252723Sdim       Cat != CatEnd; ++Cat) {
3565252723Sdim    Importer.Import(*Cat);
3566252723Sdim  }
3567252723Sdim
3568235633Sdim  // If we have an @implementation, import it as well.
3569235633Sdim  if (From->getImplementation()) {
3570235633Sdim    ObjCImplementationDecl *Impl = cast_or_null<ObjCImplementationDecl>(
3571235633Sdim                                     Importer.Import(From->getImplementation()));
3572235633Sdim    if (!Impl)
3573235633Sdim      return true;
3574204643Srdivacky
3575235633Sdim    To->setImplementation(Impl);
3576204643Srdivacky  }
3577204643Srdivacky
3578235633Sdim  if (shouldForceImportDeclContext(Kind)) {
3579235633Sdim    // Import all of the members of this class.
3580235633Sdim    ImportDeclContext(From, /*ForceImport=*/true);
3581235633Sdim  }
3582235633Sdim  return false;
3583204643Srdivacky}
3584204643Srdivacky
3585203955SrdivackyDecl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
3586235633Sdim  // If this class has a definition in the translation unit we're coming from,
3587235633Sdim  // but this particular declaration is not that definition, import the
3588235633Sdim  // definition and map to that.
3589235633Sdim  ObjCInterfaceDecl *Definition = D->getDefinition();
3590235633Sdim  if (Definition && Definition != D) {
3591235633Sdim    Decl *ImportedDef = Importer.Import(Definition);
3592235633Sdim    if (!ImportedDef)
3593235633Sdim      return 0;
3594235633Sdim
3595235633Sdim    return Importer.Imported(D, ImportedDef);
3596235633Sdim  }
3597235633Sdim
3598203955Srdivacky  // Import the major distinguishing characteristics of an @interface.
3599203955Srdivacky  DeclContext *DC, *LexicalDC;
3600203955Srdivacky  DeclarationName Name;
3601203955Srdivacky  SourceLocation Loc;
3602203955Srdivacky  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
3603203955Srdivacky    return 0;
3604203955Srdivacky
3605235633Sdim  // Look for an existing interface with the same name.
3606203955Srdivacky  ObjCInterfaceDecl *MergeWithIface = 0;
3607252723Sdim  SmallVector<NamedDecl *, 2> FoundDecls;
3608226890Sdim  DC->localUncachedLookup(Name, FoundDecls);
3609226890Sdim  for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
3610226890Sdim    if (!FoundDecls[I]->isInIdentifierNamespace(Decl::IDNS_Ordinary))
3611203955Srdivacky      continue;
3612203955Srdivacky
3613226890Sdim    if ((MergeWithIface = dyn_cast<ObjCInterfaceDecl>(FoundDecls[I])))
3614203955Srdivacky      break;
3615203955Srdivacky  }
3616203955Srdivacky
3617235633Sdim  // Create an interface declaration, if one does not already exist.
3618203955Srdivacky  ObjCInterfaceDecl *ToIface = MergeWithIface;
3619235633Sdim  if (!ToIface) {
3620235633Sdim    ToIface = ObjCInterfaceDecl::Create(Importer.getToContext(), DC,
3621235633Sdim                                        Importer.Import(D->getAtStartLoc()),
3622235633Sdim                                        Name.getAsIdentifierInfo(),
3623235633Sdim                                        /*PrevDecl=*/0,Loc,
3624235633Sdim                                        D->isImplicitInterfaceDecl());
3625235633Sdim    ToIface->setLexicalDeclContext(LexicalDC);
3626235633Sdim    LexicalDC->addDeclInternal(ToIface);
3627203955Srdivacky  }
3628235633Sdim  Importer.Imported(D, ToIface);
3629203955Srdivacky
3630235633Sdim  if (D->isThisDeclarationADefinition() && ImportDefinition(D, ToIface))
3631235633Sdim    return 0;
3632203955Srdivacky
3633204643Srdivacky  return ToIface;
3634203955Srdivacky}
3635203955Srdivacky
3636218893SdimDecl *ASTNodeImporter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
3637218893Sdim  ObjCCategoryDecl *Category = cast_or_null<ObjCCategoryDecl>(
3638218893Sdim                                        Importer.Import(D->getCategoryDecl()));
3639218893Sdim  if (!Category)
3640218893Sdim    return 0;
3641218893Sdim
3642218893Sdim  ObjCCategoryImplDecl *ToImpl = Category->getImplementation();
3643218893Sdim  if (!ToImpl) {
3644218893Sdim    DeclContext *DC = Importer.ImportContext(D->getDeclContext());
3645218893Sdim    if (!DC)
3646218893Sdim      return 0;
3647218893Sdim
3648235633Sdim    SourceLocation CategoryNameLoc = Importer.Import(D->getCategoryNameLoc());
3649218893Sdim    ToImpl = ObjCCategoryImplDecl::Create(Importer.getToContext(), DC,
3650226890Sdim                                          Importer.Import(D->getIdentifier()),
3651226890Sdim                                          Category->getClassInterface(),
3652218893Sdim                                          Importer.Import(D->getLocation()),
3653235633Sdim                                          Importer.Import(D->getAtStartLoc()),
3654235633Sdim                                          CategoryNameLoc);
3655218893Sdim
3656218893Sdim    DeclContext *LexicalDC = DC;
3657218893Sdim    if (D->getDeclContext() != D->getLexicalDeclContext()) {
3658218893Sdim      LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
3659218893Sdim      if (!LexicalDC)
3660218893Sdim        return 0;
3661218893Sdim
3662218893Sdim      ToImpl->setLexicalDeclContext(LexicalDC);
3663218893Sdim    }
3664218893Sdim
3665235633Sdim    LexicalDC->addDeclInternal(ToImpl);
3666218893Sdim    Category->setImplementation(ToImpl);
3667218893Sdim  }
3668218893Sdim
3669218893Sdim  Importer.Imported(D, ToImpl);
3670218893Sdim  ImportDeclContext(D);
3671218893Sdim  return ToImpl;
3672218893Sdim}
3673218893Sdim
3674218893SdimDecl *ASTNodeImporter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
3675218893Sdim  // Find the corresponding interface.
3676218893Sdim  ObjCInterfaceDecl *Iface = cast_or_null<ObjCInterfaceDecl>(
3677218893Sdim                                       Importer.Import(D->getClassInterface()));
3678218893Sdim  if (!Iface)
3679218893Sdim    return 0;
3680218893Sdim
3681218893Sdim  // Import the superclass, if any.
3682218893Sdim  ObjCInterfaceDecl *Super = 0;
3683218893Sdim  if (D->getSuperClass()) {
3684218893Sdim    Super = cast_or_null<ObjCInterfaceDecl>(
3685218893Sdim                                          Importer.Import(D->getSuperClass()));
3686218893Sdim    if (!Super)
3687218893Sdim      return 0;
3688218893Sdim  }
3689218893Sdim
3690218893Sdim  ObjCImplementationDecl *Impl = Iface->getImplementation();
3691218893Sdim  if (!Impl) {
3692218893Sdim    // We haven't imported an implementation yet. Create a new @implementation
3693218893Sdim    // now.
3694218893Sdim    Impl = ObjCImplementationDecl::Create(Importer.getToContext(),
3695218893Sdim                                  Importer.ImportContext(D->getDeclContext()),
3696226890Sdim                                          Iface, Super,
3697218893Sdim                                          Importer.Import(D->getLocation()),
3698235633Sdim                                          Importer.Import(D->getAtStartLoc()),
3699252723Sdim                                          Importer.Import(D->getSuperClassLoc()),
3700235633Sdim                                          Importer.Import(D->getIvarLBraceLoc()),
3701235633Sdim                                          Importer.Import(D->getIvarRBraceLoc()));
3702218893Sdim
3703218893Sdim    if (D->getDeclContext() != D->getLexicalDeclContext()) {
3704218893Sdim      DeclContext *LexicalDC
3705218893Sdim        = Importer.ImportContext(D->getLexicalDeclContext());
3706218893Sdim      if (!LexicalDC)
3707218893Sdim        return 0;
3708218893Sdim      Impl->setLexicalDeclContext(LexicalDC);
3709218893Sdim    }
3710218893Sdim
3711218893Sdim    // Associate the implementation with the class it implements.
3712218893Sdim    Iface->setImplementation(Impl);
3713218893Sdim    Importer.Imported(D, Iface->getImplementation());
3714218893Sdim  } else {
3715218893Sdim    Importer.Imported(D, Iface->getImplementation());
3716218893Sdim
3717218893Sdim    // Verify that the existing @implementation has the same superclass.
3718218893Sdim    if ((Super && !Impl->getSuperClass()) ||
3719218893Sdim        (!Super && Impl->getSuperClass()) ||
3720218893Sdim        (Super && Impl->getSuperClass() &&
3721235633Sdim         !declaresSameEntity(Super->getCanonicalDecl(), Impl->getSuperClass()))) {
3722218893Sdim        Importer.ToDiag(Impl->getLocation(),
3723218893Sdim                        diag::err_odr_objc_superclass_inconsistent)
3724218893Sdim          << Iface->getDeclName();
3725218893Sdim        // FIXME: It would be nice to have the location of the superclass
3726218893Sdim        // below.
3727218893Sdim        if (Impl->getSuperClass())
3728218893Sdim          Importer.ToDiag(Impl->getLocation(),
3729218893Sdim                          diag::note_odr_objc_superclass)
3730218893Sdim          << Impl->getSuperClass()->getDeclName();
3731218893Sdim        else
3732218893Sdim          Importer.ToDiag(Impl->getLocation(),
3733218893Sdim                          diag::note_odr_objc_missing_superclass);
3734218893Sdim        if (D->getSuperClass())
3735218893Sdim          Importer.FromDiag(D->getLocation(),
3736218893Sdim                            diag::note_odr_objc_superclass)
3737218893Sdim          << D->getSuperClass()->getDeclName();
3738218893Sdim        else
3739218893Sdim          Importer.FromDiag(D->getLocation(),
3740218893Sdim                            diag::note_odr_objc_missing_superclass);
3741218893Sdim      return 0;
3742218893Sdim    }
3743218893Sdim  }
3744218893Sdim
3745218893Sdim  // Import all of the members of this @implementation.
3746218893Sdim  ImportDeclContext(D);
3747218893Sdim
3748218893Sdim  return Impl;
3749218893Sdim}
3750218893Sdim
3751204643SrdivackyDecl *ASTNodeImporter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
3752204643Srdivacky  // Import the major distinguishing characteristics of an @property.
3753204643Srdivacky  DeclContext *DC, *LexicalDC;
3754204643Srdivacky  DeclarationName Name;
3755204643Srdivacky  SourceLocation Loc;
3756204643Srdivacky  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
3757204643Srdivacky    return 0;
3758204643Srdivacky
3759204643Srdivacky  // Check whether we have already imported this property.
3760252723Sdim  SmallVector<NamedDecl *, 2> FoundDecls;
3761226890Sdim  DC->localUncachedLookup(Name, FoundDecls);
3762226890Sdim  for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
3763204643Srdivacky    if (ObjCPropertyDecl *FoundProp
3764226890Sdim                                = dyn_cast<ObjCPropertyDecl>(FoundDecls[I])) {
3765204643Srdivacky      // Check property types.
3766204643Srdivacky      if (!Importer.IsStructurallyEquivalent(D->getType(),
3767204643Srdivacky                                             FoundProp->getType())) {
3768204643Srdivacky        Importer.ToDiag(Loc, diag::err_odr_objc_property_type_inconsistent)
3769204643Srdivacky          << Name << D->getType() << FoundProp->getType();
3770204643Srdivacky        Importer.ToDiag(FoundProp->getLocation(), diag::note_odr_value_here)
3771204643Srdivacky          << FoundProp->getType();
3772204643Srdivacky        return 0;
3773204643Srdivacky      }
3774204643Srdivacky
3775204643Srdivacky      // FIXME: Check property attributes, getters, setters, etc.?
3776204643Srdivacky
3777204643Srdivacky      // Consider these properties to be equivalent.
3778204643Srdivacky      Importer.Imported(D, FoundProp);
3779204643Srdivacky      return FoundProp;
3780204643Srdivacky    }
3781204643Srdivacky  }
3782204643Srdivacky
3783204643Srdivacky  // Import the type.
3784210299Sed  TypeSourceInfo *T = Importer.Import(D->getTypeSourceInfo());
3785210299Sed  if (!T)
3786204643Srdivacky    return 0;
3787204643Srdivacky
3788204643Srdivacky  // Create the new property.
3789204643Srdivacky  ObjCPropertyDecl *ToProperty
3790204643Srdivacky    = ObjCPropertyDecl::Create(Importer.getToContext(), DC, Loc,
3791204643Srdivacky                               Name.getAsIdentifierInfo(),
3792204643Srdivacky                               Importer.Import(D->getAtLoc()),
3793235633Sdim                               Importer.Import(D->getLParenLoc()),
3794204643Srdivacky                               T,
3795204643Srdivacky                               D->getPropertyImplementation());
3796204643Srdivacky  Importer.Imported(D, ToProperty);
3797204643Srdivacky  ToProperty->setLexicalDeclContext(LexicalDC);
3798235633Sdim  LexicalDC->addDeclInternal(ToProperty);
3799204643Srdivacky
3800204643Srdivacky  ToProperty->setPropertyAttributes(D->getPropertyAttributes());
3801210299Sed  ToProperty->setPropertyAttributesAsWritten(
3802210299Sed                                      D->getPropertyAttributesAsWritten());
3803204643Srdivacky  ToProperty->setGetterName(Importer.Import(D->getGetterName()));
3804204643Srdivacky  ToProperty->setSetterName(Importer.Import(D->getSetterName()));
3805204643Srdivacky  ToProperty->setGetterMethodDecl(
3806204643Srdivacky     cast_or_null<ObjCMethodDecl>(Importer.Import(D->getGetterMethodDecl())));
3807204643Srdivacky  ToProperty->setSetterMethodDecl(
3808204643Srdivacky     cast_or_null<ObjCMethodDecl>(Importer.Import(D->getSetterMethodDecl())));
3809204643Srdivacky  ToProperty->setPropertyIvarDecl(
3810204643Srdivacky       cast_or_null<ObjCIvarDecl>(Importer.Import(D->getPropertyIvarDecl())));
3811204643Srdivacky  return ToProperty;
3812204643Srdivacky}
3813204643Srdivacky
3814218893SdimDecl *ASTNodeImporter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
3815218893Sdim  ObjCPropertyDecl *Property = cast_or_null<ObjCPropertyDecl>(
3816218893Sdim                                        Importer.Import(D->getPropertyDecl()));
3817218893Sdim  if (!Property)
3818218893Sdim    return 0;
3819218893Sdim
3820218893Sdim  DeclContext *DC = Importer.ImportContext(D->getDeclContext());
3821218893Sdim  if (!DC)
3822218893Sdim    return 0;
3823218893Sdim
3824218893Sdim  // Import the lexical declaration context.
3825218893Sdim  DeclContext *LexicalDC = DC;
3826218893Sdim  if (D->getDeclContext() != D->getLexicalDeclContext()) {
3827218893Sdim    LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
3828218893Sdim    if (!LexicalDC)
3829218893Sdim      return 0;
3830218893Sdim  }
3831218893Sdim
3832218893Sdim  ObjCImplDecl *InImpl = dyn_cast<ObjCImplDecl>(LexicalDC);
3833218893Sdim  if (!InImpl)
3834218893Sdim    return 0;
3835218893Sdim
3836218893Sdim  // Import the ivar (for an @synthesize).
3837218893Sdim  ObjCIvarDecl *Ivar = 0;
3838218893Sdim  if (D->getPropertyIvarDecl()) {
3839218893Sdim    Ivar = cast_or_null<ObjCIvarDecl>(
3840218893Sdim                                    Importer.Import(D->getPropertyIvarDecl()));
3841218893Sdim    if (!Ivar)
3842218893Sdim      return 0;
3843218893Sdim  }
3844218893Sdim
3845218893Sdim  ObjCPropertyImplDecl *ToImpl
3846218893Sdim    = InImpl->FindPropertyImplDecl(Property->getIdentifier());
3847218893Sdim  if (!ToImpl) {
3848218893Sdim    ToImpl = ObjCPropertyImplDecl::Create(Importer.getToContext(), DC,
3849218893Sdim                                          Importer.Import(D->getLocStart()),
3850218893Sdim                                          Importer.Import(D->getLocation()),
3851218893Sdim                                          Property,
3852218893Sdim                                          D->getPropertyImplementation(),
3853218893Sdim                                          Ivar,
3854218893Sdim                                  Importer.Import(D->getPropertyIvarDeclLoc()));
3855218893Sdim    ToImpl->setLexicalDeclContext(LexicalDC);
3856218893Sdim    Importer.Imported(D, ToImpl);
3857235633Sdim    LexicalDC->addDeclInternal(ToImpl);
3858218893Sdim  } else {
3859218893Sdim    // Check that we have the same kind of property implementation (@synthesize
3860218893Sdim    // vs. @dynamic).
3861218893Sdim    if (D->getPropertyImplementation() != ToImpl->getPropertyImplementation()) {
3862218893Sdim      Importer.ToDiag(ToImpl->getLocation(),
3863218893Sdim                      diag::err_odr_objc_property_impl_kind_inconsistent)
3864218893Sdim        << Property->getDeclName()
3865218893Sdim        << (ToImpl->getPropertyImplementation()
3866218893Sdim                                              == ObjCPropertyImplDecl::Dynamic);
3867218893Sdim      Importer.FromDiag(D->getLocation(),
3868218893Sdim                        diag::note_odr_objc_property_impl_kind)
3869218893Sdim        << D->getPropertyDecl()->getDeclName()
3870218893Sdim        << (D->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic);
3871218893Sdim      return 0;
3872218893Sdim    }
3873218893Sdim
3874218893Sdim    // For @synthesize, check that we have the same
3875218893Sdim    if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize &&
3876218893Sdim        Ivar != ToImpl->getPropertyIvarDecl()) {
3877218893Sdim      Importer.ToDiag(ToImpl->getPropertyIvarDeclLoc(),
3878218893Sdim                      diag::err_odr_objc_synthesize_ivar_inconsistent)
3879218893Sdim        << Property->getDeclName()
3880218893Sdim        << ToImpl->getPropertyIvarDecl()->getDeclName()
3881218893Sdim        << Ivar->getDeclName();
3882218893Sdim      Importer.FromDiag(D->getPropertyIvarDeclLoc(),
3883218893Sdim                        diag::note_odr_objc_synthesize_ivar_here)
3884218893Sdim        << D->getPropertyIvarDecl()->getDeclName();
3885218893Sdim      return 0;
3886218893Sdim    }
3887218893Sdim
3888218893Sdim    // Merge the existing implementation with the new implementation.
3889218893Sdim    Importer.Imported(D, ToImpl);
3890218893Sdim  }
3891218893Sdim
3892218893Sdim  return ToImpl;
3893218893Sdim}
3894218893Sdim
3895218893SdimDecl *ASTNodeImporter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
3896218893Sdim  // For template arguments, we adopt the translation unit as our declaration
3897218893Sdim  // context. This context will be fixed when the actual template declaration
3898218893Sdim  // is created.
3899218893Sdim
3900218893Sdim  // FIXME: Import default argument.
3901218893Sdim  return TemplateTypeParmDecl::Create(Importer.getToContext(),
3902218893Sdim                              Importer.getToContext().getTranslationUnitDecl(),
3903221345Sdim                                      Importer.Import(D->getLocStart()),
3904218893Sdim                                      Importer.Import(D->getLocation()),
3905218893Sdim                                      D->getDepth(),
3906218893Sdim                                      D->getIndex(),
3907218893Sdim                                      Importer.Import(D->getIdentifier()),
3908218893Sdim                                      D->wasDeclaredWithTypename(),
3909218893Sdim                                      D->isParameterPack());
3910218893Sdim}
3911218893Sdim
3912218893SdimDecl *
3913218893SdimASTNodeImporter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
3914218893Sdim  // Import the name of this declaration.
3915218893Sdim  DeclarationName Name = Importer.Import(D->getDeclName());
3916218893Sdim  if (D->getDeclName() && !Name)
3917218893Sdim    return 0;
3918218893Sdim
3919218893Sdim  // Import the location of this declaration.
3920218893Sdim  SourceLocation Loc = Importer.Import(D->getLocation());
3921218893Sdim
3922218893Sdim  // Import the type of this declaration.
3923218893Sdim  QualType T = Importer.Import(D->getType());
3924218893Sdim  if (T.isNull())
3925218893Sdim    return 0;
3926218893Sdim
3927218893Sdim  // Import type-source information.
3928218893Sdim  TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
3929218893Sdim  if (D->getTypeSourceInfo() && !TInfo)
3930218893Sdim    return 0;
3931218893Sdim
3932218893Sdim  // FIXME: Import default argument.
3933218893Sdim
3934218893Sdim  return NonTypeTemplateParmDecl::Create(Importer.getToContext(),
3935218893Sdim                               Importer.getToContext().getTranslationUnitDecl(),
3936221345Sdim                                         Importer.Import(D->getInnerLocStart()),
3937218893Sdim                                         Loc, D->getDepth(), D->getPosition(),
3938218893Sdim                                         Name.getAsIdentifierInfo(),
3939218893Sdim                                         T, D->isParameterPack(), TInfo);
3940218893Sdim}
3941218893Sdim
3942218893SdimDecl *
3943218893SdimASTNodeImporter::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
3944218893Sdim  // Import the name of this declaration.
3945218893Sdim  DeclarationName Name = Importer.Import(D->getDeclName());
3946218893Sdim  if (D->getDeclName() && !Name)
3947218893Sdim    return 0;
3948218893Sdim
3949218893Sdim  // Import the location of this declaration.
3950218893Sdim  SourceLocation Loc = Importer.Import(D->getLocation());
3951218893Sdim
3952218893Sdim  // Import template parameters.
3953218893Sdim  TemplateParameterList *TemplateParams
3954218893Sdim    = ImportTemplateParameterList(D->getTemplateParameters());
3955218893Sdim  if (!TemplateParams)
3956218893Sdim    return 0;
3957218893Sdim
3958218893Sdim  // FIXME: Import default argument.
3959218893Sdim
3960218893Sdim  return TemplateTemplateParmDecl::Create(Importer.getToContext(),
3961218893Sdim                              Importer.getToContext().getTranslationUnitDecl(),
3962218893Sdim                                          Loc, D->getDepth(), D->getPosition(),
3963218893Sdim                                          D->isParameterPack(),
3964218893Sdim                                          Name.getAsIdentifierInfo(),
3965218893Sdim                                          TemplateParams);
3966218893Sdim}
3967218893Sdim
3968218893SdimDecl *ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
3969218893Sdim  // If this record has a definition in the translation unit we're coming from,
3970218893Sdim  // but this particular declaration is not that definition, import the
3971218893Sdim  // definition and map to that.
3972218893Sdim  CXXRecordDecl *Definition
3973218893Sdim    = cast_or_null<CXXRecordDecl>(D->getTemplatedDecl()->getDefinition());
3974218893Sdim  if (Definition && Definition != D->getTemplatedDecl()) {
3975218893Sdim    Decl *ImportedDef
3976218893Sdim      = Importer.Import(Definition->getDescribedClassTemplate());
3977218893Sdim    if (!ImportedDef)
3978218893Sdim      return 0;
3979218893Sdim
3980218893Sdim    return Importer.Imported(D, ImportedDef);
3981218893Sdim  }
3982218893Sdim
3983218893Sdim  // Import the major distinguishing characteristics of this class template.
3984218893Sdim  DeclContext *DC, *LexicalDC;
3985218893Sdim  DeclarationName Name;
3986218893Sdim  SourceLocation Loc;
3987218893Sdim  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
3988218893Sdim    return 0;
3989218893Sdim
3990218893Sdim  // We may already have a template of the same name; try to find and match it.
3991218893Sdim  if (!DC->isFunctionOrMethod()) {
3992226890Sdim    SmallVector<NamedDecl *, 4> ConflictingDecls;
3993252723Sdim    SmallVector<NamedDecl *, 2> FoundDecls;
3994226890Sdim    DC->localUncachedLookup(Name, FoundDecls);
3995226890Sdim    for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
3996226890Sdim      if (!FoundDecls[I]->isInIdentifierNamespace(Decl::IDNS_Ordinary))
3997218893Sdim        continue;
3998218893Sdim
3999226890Sdim      Decl *Found = FoundDecls[I];
4000218893Sdim      if (ClassTemplateDecl *FoundTemplate
4001218893Sdim                                        = dyn_cast<ClassTemplateDecl>(Found)) {
4002218893Sdim        if (IsStructuralMatch(D, FoundTemplate)) {
4003218893Sdim          // The class templates structurally match; call it the same template.
4004218893Sdim          // FIXME: We may be filling in a forward declaration here. Handle
4005218893Sdim          // this case!
4006218893Sdim          Importer.Imported(D->getTemplatedDecl(),
4007218893Sdim                            FoundTemplate->getTemplatedDecl());
4008218893Sdim          return Importer.Imported(D, FoundTemplate);
4009218893Sdim        }
4010218893Sdim      }
4011218893Sdim
4012226890Sdim      ConflictingDecls.push_back(FoundDecls[I]);
4013218893Sdim    }
4014218893Sdim
4015218893Sdim    if (!ConflictingDecls.empty()) {
4016218893Sdim      Name = Importer.HandleNameConflict(Name, DC, Decl::IDNS_Ordinary,
4017218893Sdim                                         ConflictingDecls.data(),
4018218893Sdim                                         ConflictingDecls.size());
4019218893Sdim    }
4020218893Sdim
4021218893Sdim    if (!Name)
4022218893Sdim      return 0;
4023218893Sdim  }
4024218893Sdim
4025218893Sdim  CXXRecordDecl *DTemplated = D->getTemplatedDecl();
4026218893Sdim
4027218893Sdim  // Create the declaration that is being templated.
4028221345Sdim  SourceLocation StartLoc = Importer.Import(DTemplated->getLocStart());
4029221345Sdim  SourceLocation IdLoc = Importer.Import(DTemplated->getLocation());
4030218893Sdim  CXXRecordDecl *D2Templated = CXXRecordDecl::Create(Importer.getToContext(),
4031218893Sdim                                                     DTemplated->getTagKind(),
4032221345Sdim                                                     DC, StartLoc, IdLoc,
4033221345Sdim                                                   Name.getAsIdentifierInfo());
4034218893Sdim  D2Templated->setAccess(DTemplated->getAccess());
4035219077Sdim  D2Templated->setQualifierInfo(Importer.Import(DTemplated->getQualifierLoc()));
4036218893Sdim  D2Templated->setLexicalDeclContext(LexicalDC);
4037218893Sdim
4038218893Sdim  // Create the class template declaration itself.
4039218893Sdim  TemplateParameterList *TemplateParams
4040218893Sdim    = ImportTemplateParameterList(D->getTemplateParameters());
4041218893Sdim  if (!TemplateParams)
4042218893Sdim    return 0;
4043218893Sdim
4044218893Sdim  ClassTemplateDecl *D2 = ClassTemplateDecl::Create(Importer.getToContext(), DC,
4045218893Sdim                                                    Loc, Name, TemplateParams,
4046218893Sdim                                                    D2Templated,
4047218893Sdim  /*PrevDecl=*/0);
4048218893Sdim  D2Templated->setDescribedClassTemplate(D2);
4049218893Sdim
4050218893Sdim  D2->setAccess(D->getAccess());
4051218893Sdim  D2->setLexicalDeclContext(LexicalDC);
4052235633Sdim  LexicalDC->addDeclInternal(D2);
4053218893Sdim
4054218893Sdim  // Note the relationship between the class templates.
4055218893Sdim  Importer.Imported(D, D2);
4056218893Sdim  Importer.Imported(DTemplated, D2Templated);
4057218893Sdim
4058226890Sdim  if (DTemplated->isCompleteDefinition() &&
4059226890Sdim      !D2Templated->isCompleteDefinition()) {
4060218893Sdim    // FIXME: Import definition!
4061218893Sdim  }
4062218893Sdim
4063218893Sdim  return D2;
4064218893Sdim}
4065218893Sdim
4066218893SdimDecl *ASTNodeImporter::VisitClassTemplateSpecializationDecl(
4067218893Sdim                                          ClassTemplateSpecializationDecl *D) {
4068218893Sdim  // If this record has a definition in the translation unit we're coming from,
4069218893Sdim  // but this particular declaration is not that definition, import the
4070218893Sdim  // definition and map to that.
4071218893Sdim  TagDecl *Definition = D->getDefinition();
4072218893Sdim  if (Definition && Definition != D) {
4073218893Sdim    Decl *ImportedDef = Importer.Import(Definition);
4074218893Sdim    if (!ImportedDef)
4075218893Sdim      return 0;
4076218893Sdim
4077218893Sdim    return Importer.Imported(D, ImportedDef);
4078218893Sdim  }
4079218893Sdim
4080218893Sdim  ClassTemplateDecl *ClassTemplate
4081218893Sdim    = cast_or_null<ClassTemplateDecl>(Importer.Import(
4082218893Sdim                                                 D->getSpecializedTemplate()));
4083218893Sdim  if (!ClassTemplate)
4084218893Sdim    return 0;
4085218893Sdim
4086218893Sdim  // Import the context of this declaration.
4087218893Sdim  DeclContext *DC = ClassTemplate->getDeclContext();
4088218893Sdim  if (!DC)
4089218893Sdim    return 0;
4090218893Sdim
4091218893Sdim  DeclContext *LexicalDC = DC;
4092218893Sdim  if (D->getDeclContext() != D->getLexicalDeclContext()) {
4093218893Sdim    LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
4094218893Sdim    if (!LexicalDC)
4095218893Sdim      return 0;
4096218893Sdim  }
4097218893Sdim
4098218893Sdim  // Import the location of this declaration.
4099221345Sdim  SourceLocation StartLoc = Importer.Import(D->getLocStart());
4100221345Sdim  SourceLocation IdLoc = Importer.Import(D->getLocation());
4101218893Sdim
4102218893Sdim  // Import template arguments.
4103226890Sdim  SmallVector<TemplateArgument, 2> TemplateArgs;
4104218893Sdim  if (ImportTemplateArguments(D->getTemplateArgs().data(),
4105218893Sdim                              D->getTemplateArgs().size(),
4106218893Sdim                              TemplateArgs))
4107218893Sdim    return 0;
4108218893Sdim
4109218893Sdim  // Try to find an existing specialization with these template arguments.
4110218893Sdim  void *InsertPos = 0;
4111218893Sdim  ClassTemplateSpecializationDecl *D2
4112218893Sdim    = ClassTemplate->findSpecialization(TemplateArgs.data(),
4113218893Sdim                                        TemplateArgs.size(), InsertPos);
4114218893Sdim  if (D2) {
4115218893Sdim    // We already have a class template specialization with these template
4116218893Sdim    // arguments.
4117218893Sdim
4118218893Sdim    // FIXME: Check for specialization vs. instantiation errors.
4119218893Sdim
4120218893Sdim    if (RecordDecl *FoundDef = D2->getDefinition()) {
4121226890Sdim      if (!D->isCompleteDefinition() || IsStructuralMatch(D, FoundDef)) {
4122218893Sdim        // The record types structurally match, or the "from" translation
4123218893Sdim        // unit only had a forward declaration anyway; call it the same
4124218893Sdim        // function.
4125218893Sdim        return Importer.Imported(D, FoundDef);
4126218893Sdim      }
4127218893Sdim    }
4128218893Sdim  } else {
4129218893Sdim    // Create a new specialization.
4130218893Sdim    D2 = ClassTemplateSpecializationDecl::Create(Importer.getToContext(),
4131218893Sdim                                                 D->getTagKind(), DC,
4132221345Sdim                                                 StartLoc, IdLoc,
4133221345Sdim                                                 ClassTemplate,
4134218893Sdim                                                 TemplateArgs.data(),
4135218893Sdim                                                 TemplateArgs.size(),
4136218893Sdim                                                 /*PrevDecl=*/0);
4137218893Sdim    D2->setSpecializationKind(D->getSpecializationKind());
4138218893Sdim
4139218893Sdim    // Add this specialization to the class template.
4140218893Sdim    ClassTemplate->AddSpecialization(D2, InsertPos);
4141218893Sdim
4142218893Sdim    // Import the qualifier, if any.
4143219077Sdim    D2->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
4144218893Sdim
4145218893Sdim    // Add the specialization to this context.
4146218893Sdim    D2->setLexicalDeclContext(LexicalDC);
4147235633Sdim    LexicalDC->addDeclInternal(D2);
4148218893Sdim  }
4149218893Sdim  Importer.Imported(D, D2);
4150218893Sdim
4151226890Sdim  if (D->isCompleteDefinition() && ImportDefinition(D, D2))
4152218893Sdim    return 0;
4153218893Sdim
4154218893Sdim  return D2;
4155218893Sdim}
4156218893Sdim
4157263509SdimDecl *ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) {
4158263509Sdim  // If this variable has a definition in the translation unit we're coming
4159263509Sdim  // from,
4160263509Sdim  // but this particular declaration is not that definition, import the
4161263509Sdim  // definition and map to that.
4162263509Sdim  VarDecl *Definition =
4163263509Sdim      cast_or_null<VarDecl>(D->getTemplatedDecl()->getDefinition());
4164263509Sdim  if (Definition && Definition != D->getTemplatedDecl()) {
4165263509Sdim    Decl *ImportedDef = Importer.Import(Definition->getDescribedVarTemplate());
4166263509Sdim    if (!ImportedDef)
4167263509Sdim      return 0;
4168263509Sdim
4169263509Sdim    return Importer.Imported(D, ImportedDef);
4170263509Sdim  }
4171263509Sdim
4172263509Sdim  // Import the major distinguishing characteristics of this variable template.
4173263509Sdim  DeclContext *DC, *LexicalDC;
4174263509Sdim  DeclarationName Name;
4175263509Sdim  SourceLocation Loc;
4176263509Sdim  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
4177263509Sdim    return 0;
4178263509Sdim
4179263509Sdim  // We may already have a template of the same name; try to find and match it.
4180263509Sdim  assert(!DC->isFunctionOrMethod() &&
4181263509Sdim         "Variable templates cannot be declared at function scope");
4182263509Sdim  SmallVector<NamedDecl *, 4> ConflictingDecls;
4183263509Sdim  SmallVector<NamedDecl *, 2> FoundDecls;
4184263509Sdim  DC->localUncachedLookup(Name, FoundDecls);
4185263509Sdim  for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
4186263509Sdim    if (!FoundDecls[I]->isInIdentifierNamespace(Decl::IDNS_Ordinary))
4187263509Sdim      continue;
4188263509Sdim
4189263509Sdim    Decl *Found = FoundDecls[I];
4190263509Sdim    if (VarTemplateDecl *FoundTemplate = dyn_cast<VarTemplateDecl>(Found)) {
4191263509Sdim      if (IsStructuralMatch(D, FoundTemplate)) {
4192263509Sdim        // The variable templates structurally match; call it the same template.
4193263509Sdim        Importer.Imported(D->getTemplatedDecl(),
4194263509Sdim                          FoundTemplate->getTemplatedDecl());
4195263509Sdim        return Importer.Imported(D, FoundTemplate);
4196263509Sdim      }
4197263509Sdim    }
4198263509Sdim
4199263509Sdim    ConflictingDecls.push_back(FoundDecls[I]);
4200263509Sdim  }
4201263509Sdim
4202263509Sdim  if (!ConflictingDecls.empty()) {
4203263509Sdim    Name = Importer.HandleNameConflict(Name, DC, Decl::IDNS_Ordinary,
4204263509Sdim                                       ConflictingDecls.data(),
4205263509Sdim                                       ConflictingDecls.size());
4206263509Sdim  }
4207263509Sdim
4208263509Sdim  if (!Name)
4209263509Sdim    return 0;
4210263509Sdim
4211263509Sdim  VarDecl *DTemplated = D->getTemplatedDecl();
4212263509Sdim
4213263509Sdim  // Import the type.
4214263509Sdim  QualType T = Importer.Import(DTemplated->getType());
4215263509Sdim  if (T.isNull())
4216263509Sdim    return 0;
4217263509Sdim
4218263509Sdim  // Create the declaration that is being templated.
4219263509Sdim  SourceLocation StartLoc = Importer.Import(DTemplated->getLocStart());
4220263509Sdim  SourceLocation IdLoc = Importer.Import(DTemplated->getLocation());
4221263509Sdim  TypeSourceInfo *TInfo = Importer.Import(DTemplated->getTypeSourceInfo());
4222263509Sdim  VarDecl *D2Templated = VarDecl::Create(Importer.getToContext(), DC, StartLoc,
4223263509Sdim                                         IdLoc, Name.getAsIdentifierInfo(), T,
4224263509Sdim                                         TInfo, DTemplated->getStorageClass());
4225263509Sdim  D2Templated->setAccess(DTemplated->getAccess());
4226263509Sdim  D2Templated->setQualifierInfo(Importer.Import(DTemplated->getQualifierLoc()));
4227263509Sdim  D2Templated->setLexicalDeclContext(LexicalDC);
4228263509Sdim
4229263509Sdim  // Importer.Imported(DTemplated, D2Templated);
4230263509Sdim  // LexicalDC->addDeclInternal(D2Templated);
4231263509Sdim
4232263509Sdim  // Merge the initializer.
4233263509Sdim  if (ImportDefinition(DTemplated, D2Templated))
4234263509Sdim    return 0;
4235263509Sdim
4236263509Sdim  // Create the variable template declaration itself.
4237263509Sdim  TemplateParameterList *TemplateParams =
4238263509Sdim      ImportTemplateParameterList(D->getTemplateParameters());
4239263509Sdim  if (!TemplateParams)
4240263509Sdim    return 0;
4241263509Sdim
4242263509Sdim  VarTemplateDecl *D2 = VarTemplateDecl::Create(
4243263509Sdim      Importer.getToContext(), DC, Loc, Name, TemplateParams, D2Templated,
4244263509Sdim      /*PrevDecl=*/0);
4245263509Sdim  D2Templated->setDescribedVarTemplate(D2);
4246263509Sdim
4247263509Sdim  D2->setAccess(D->getAccess());
4248263509Sdim  D2->setLexicalDeclContext(LexicalDC);
4249263509Sdim  LexicalDC->addDeclInternal(D2);
4250263509Sdim
4251263509Sdim  // Note the relationship between the variable templates.
4252263509Sdim  Importer.Imported(D, D2);
4253263509Sdim  Importer.Imported(DTemplated, D2Templated);
4254263509Sdim
4255263509Sdim  if (DTemplated->isThisDeclarationADefinition() &&
4256263509Sdim      !D2Templated->isThisDeclarationADefinition()) {
4257263509Sdim    // FIXME: Import definition!
4258263509Sdim  }
4259263509Sdim
4260263509Sdim  return D2;
4261263509Sdim}
4262263509Sdim
4263263509SdimDecl *ASTNodeImporter::VisitVarTemplateSpecializationDecl(
4264263509Sdim    VarTemplateSpecializationDecl *D) {
4265263509Sdim  // If this record has a definition in the translation unit we're coming from,
4266263509Sdim  // but this particular declaration is not that definition, import the
4267263509Sdim  // definition and map to that.
4268263509Sdim  VarDecl *Definition = D->getDefinition();
4269263509Sdim  if (Definition && Definition != D) {
4270263509Sdim    Decl *ImportedDef = Importer.Import(Definition);
4271263509Sdim    if (!ImportedDef)
4272263509Sdim      return 0;
4273263509Sdim
4274263509Sdim    return Importer.Imported(D, ImportedDef);
4275263509Sdim  }
4276263509Sdim
4277263509Sdim  VarTemplateDecl *VarTemplate = cast_or_null<VarTemplateDecl>(
4278263509Sdim      Importer.Import(D->getSpecializedTemplate()));
4279263509Sdim  if (!VarTemplate)
4280263509Sdim    return 0;
4281263509Sdim
4282263509Sdim  // Import the context of this declaration.
4283263509Sdim  DeclContext *DC = VarTemplate->getDeclContext();
4284263509Sdim  if (!DC)
4285263509Sdim    return 0;
4286263509Sdim
4287263509Sdim  DeclContext *LexicalDC = DC;
4288263509Sdim  if (D->getDeclContext() != D->getLexicalDeclContext()) {
4289263509Sdim    LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
4290263509Sdim    if (!LexicalDC)
4291263509Sdim      return 0;
4292263509Sdim  }
4293263509Sdim
4294263509Sdim  // Import the location of this declaration.
4295263509Sdim  SourceLocation StartLoc = Importer.Import(D->getLocStart());
4296263509Sdim  SourceLocation IdLoc = Importer.Import(D->getLocation());
4297263509Sdim
4298263509Sdim  // Import template arguments.
4299263509Sdim  SmallVector<TemplateArgument, 2> TemplateArgs;
4300263509Sdim  if (ImportTemplateArguments(D->getTemplateArgs().data(),
4301263509Sdim                              D->getTemplateArgs().size(), TemplateArgs))
4302263509Sdim    return 0;
4303263509Sdim
4304263509Sdim  // Try to find an existing specialization with these template arguments.
4305263509Sdim  void *InsertPos = 0;
4306263509Sdim  VarTemplateSpecializationDecl *D2 = VarTemplate->findSpecialization(
4307263509Sdim      TemplateArgs.data(), TemplateArgs.size(), InsertPos);
4308263509Sdim  if (D2) {
4309263509Sdim    // We already have a variable template specialization with these template
4310263509Sdim    // arguments.
4311263509Sdim
4312263509Sdim    // FIXME: Check for specialization vs. instantiation errors.
4313263509Sdim
4314263509Sdim    if (VarDecl *FoundDef = D2->getDefinition()) {
4315263509Sdim      if (!D->isThisDeclarationADefinition() ||
4316263509Sdim          IsStructuralMatch(D, FoundDef)) {
4317263509Sdim        // The record types structurally match, or the "from" translation
4318263509Sdim        // unit only had a forward declaration anyway; call it the same
4319263509Sdim        // variable.
4320263509Sdim        return Importer.Imported(D, FoundDef);
4321263509Sdim      }
4322263509Sdim    }
4323263509Sdim  } else {
4324263509Sdim
4325263509Sdim    // Import the type.
4326263509Sdim    QualType T = Importer.Import(D->getType());
4327263509Sdim    if (T.isNull())
4328263509Sdim      return 0;
4329263509Sdim    TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
4330263509Sdim
4331263509Sdim    // Create a new specialization.
4332263509Sdim    D2 = VarTemplateSpecializationDecl::Create(
4333263509Sdim        Importer.getToContext(), DC, StartLoc, IdLoc, VarTemplate, T, TInfo,
4334263509Sdim        D->getStorageClass(), TemplateArgs.data(), TemplateArgs.size());
4335263509Sdim    D2->setSpecializationKind(D->getSpecializationKind());
4336263509Sdim    D2->setTemplateArgsInfo(D->getTemplateArgsInfo());
4337263509Sdim
4338263509Sdim    // Add this specialization to the class template.
4339263509Sdim    VarTemplate->AddSpecialization(D2, InsertPos);
4340263509Sdim
4341263509Sdim    // Import the qualifier, if any.
4342263509Sdim    D2->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
4343263509Sdim
4344263509Sdim    // Add the specialization to this context.
4345263509Sdim    D2->setLexicalDeclContext(LexicalDC);
4346263509Sdim    LexicalDC->addDeclInternal(D2);
4347263509Sdim  }
4348263509Sdim  Importer.Imported(D, D2);
4349263509Sdim
4350263509Sdim  if (D->isThisDeclarationADefinition() && ImportDefinition(D, D2))
4351263509Sdim    return 0;
4352263509Sdim
4353263509Sdim  return D2;
4354263509Sdim}
4355263509Sdim
4356203955Srdivacky//----------------------------------------------------------------------------
4357203955Srdivacky// Import Statements
4358203955Srdivacky//----------------------------------------------------------------------------
4359203955Srdivacky
4360203955SrdivackyStmt *ASTNodeImporter::VisitStmt(Stmt *S) {
4361203955Srdivacky  Importer.FromDiag(S->getLocStart(), diag::err_unsupported_ast_node)
4362203955Srdivacky    << S->getStmtClassName();
4363203955Srdivacky  return 0;
4364203955Srdivacky}
4365203955Srdivacky
4366203955Srdivacky//----------------------------------------------------------------------------
4367203955Srdivacky// Import Expressions
4368203955Srdivacky//----------------------------------------------------------------------------
4369203955SrdivackyExpr *ASTNodeImporter::VisitExpr(Expr *E) {
4370203955Srdivacky  Importer.FromDiag(E->getLocStart(), diag::err_unsupported_ast_node)
4371203955Srdivacky    << E->getStmtClassName();
4372203955Srdivacky  return 0;
4373203955Srdivacky}
4374203955Srdivacky
4375204643SrdivackyExpr *ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) {
4376204643Srdivacky  ValueDecl *ToD = cast_or_null<ValueDecl>(Importer.Import(E->getDecl()));
4377204643Srdivacky  if (!ToD)
4378204643Srdivacky    return 0;
4379221345Sdim
4380221345Sdim  NamedDecl *FoundD = 0;
4381221345Sdim  if (E->getDecl() != E->getFoundDecl()) {
4382221345Sdim    FoundD = cast_or_null<NamedDecl>(Importer.Import(E->getFoundDecl()));
4383221345Sdim    if (!FoundD)
4384221345Sdim      return 0;
4385221345Sdim  }
4386204643Srdivacky
4387204643Srdivacky  QualType T = Importer.Import(E->getType());
4388204643Srdivacky  if (T.isNull())
4389204643Srdivacky    return 0;
4390226890Sdim
4391226890Sdim  DeclRefExpr *DRE = DeclRefExpr::Create(Importer.getToContext(),
4392226890Sdim                                         Importer.Import(E->getQualifierLoc()),
4393235633Sdim                                   Importer.Import(E->getTemplateKeywordLoc()),
4394226890Sdim                                         ToD,
4395235633Sdim                                         E->refersToEnclosingLocal(),
4396226890Sdim                                         Importer.Import(E->getLocation()),
4397226890Sdim                                         T, E->getValueKind(),
4398226890Sdim                                         FoundD,
4399226890Sdim                                         /*FIXME:TemplateArgs=*/0);
4400226890Sdim  if (E->hadMultipleCandidates())
4401226890Sdim    DRE->setHadMultipleCandidates(true);
4402226890Sdim  return DRE;
4403204643Srdivacky}
4404204643Srdivacky
4405203955SrdivackyExpr *ASTNodeImporter::VisitIntegerLiteral(IntegerLiteral *E) {
4406203955Srdivacky  QualType T = Importer.Import(E->getType());
4407203955Srdivacky  if (T.isNull())
4408203955Srdivacky    return 0;
4409203955Srdivacky
4410212904Sdim  return IntegerLiteral::Create(Importer.getToContext(),
4411212904Sdim                                E->getValue(), T,
4412212904Sdim                                Importer.Import(E->getLocation()));
4413203955Srdivacky}
4414203955Srdivacky
4415204643SrdivackyExpr *ASTNodeImporter::VisitCharacterLiteral(CharacterLiteral *E) {
4416204643Srdivacky  QualType T = Importer.Import(E->getType());
4417204643Srdivacky  if (T.isNull())
4418204643Srdivacky    return 0;
4419204643Srdivacky
4420226890Sdim  return new (Importer.getToContext()) CharacterLiteral(E->getValue(),
4421226890Sdim                                                        E->getKind(), T,
4422204643Srdivacky                                          Importer.Import(E->getLocation()));
4423204643Srdivacky}
4424204643Srdivacky
4425204643SrdivackyExpr *ASTNodeImporter::VisitParenExpr(ParenExpr *E) {
4426204643Srdivacky  Expr *SubExpr = Importer.Import(E->getSubExpr());
4427204643Srdivacky  if (!SubExpr)
4428204643Srdivacky    return 0;
4429204643Srdivacky
4430204643Srdivacky  return new (Importer.getToContext())
4431204643Srdivacky                                  ParenExpr(Importer.Import(E->getLParen()),
4432204643Srdivacky                                            Importer.Import(E->getRParen()),
4433204643Srdivacky                                            SubExpr);
4434204643Srdivacky}
4435204643Srdivacky
4436204643SrdivackyExpr *ASTNodeImporter::VisitUnaryOperator(UnaryOperator *E) {
4437204643Srdivacky  QualType T = Importer.Import(E->getType());
4438204643Srdivacky  if (T.isNull())
4439204643Srdivacky    return 0;
4440204643Srdivacky
4441204643Srdivacky  Expr *SubExpr = Importer.Import(E->getSubExpr());
4442204643Srdivacky  if (!SubExpr)
4443204643Srdivacky    return 0;
4444204643Srdivacky
4445204643Srdivacky  return new (Importer.getToContext()) UnaryOperator(SubExpr, E->getOpcode(),
4446218893Sdim                                                     T, E->getValueKind(),
4447218893Sdim                                                     E->getObjectKind(),
4448204643Srdivacky                                         Importer.Import(E->getOperatorLoc()));
4449204643Srdivacky}
4450204643Srdivacky
4451221345SdimExpr *ASTNodeImporter::VisitUnaryExprOrTypeTraitExpr(
4452221345Sdim                                            UnaryExprOrTypeTraitExpr *E) {
4453204643Srdivacky  QualType ResultType = Importer.Import(E->getType());
4454204643Srdivacky
4455204643Srdivacky  if (E->isArgumentType()) {
4456204643Srdivacky    TypeSourceInfo *TInfo = Importer.Import(E->getArgumentTypeInfo());
4457204643Srdivacky    if (!TInfo)
4458204643Srdivacky      return 0;
4459204643Srdivacky
4460221345Sdim    return new (Importer.getToContext()) UnaryExprOrTypeTraitExpr(E->getKind(),
4461221345Sdim                                           TInfo, ResultType,
4462204643Srdivacky                                           Importer.Import(E->getOperatorLoc()),
4463204643Srdivacky                                           Importer.Import(E->getRParenLoc()));
4464204643Srdivacky  }
4465204643Srdivacky
4466204643Srdivacky  Expr *SubExpr = Importer.Import(E->getArgumentExpr());
4467204643Srdivacky  if (!SubExpr)
4468204643Srdivacky    return 0;
4469204643Srdivacky
4470221345Sdim  return new (Importer.getToContext()) UnaryExprOrTypeTraitExpr(E->getKind(),
4471221345Sdim                                          SubExpr, ResultType,
4472204643Srdivacky                                          Importer.Import(E->getOperatorLoc()),
4473204643Srdivacky                                          Importer.Import(E->getRParenLoc()));
4474204643Srdivacky}
4475204643Srdivacky
4476204643SrdivackyExpr *ASTNodeImporter::VisitBinaryOperator(BinaryOperator *E) {
4477204643Srdivacky  QualType T = Importer.Import(E->getType());
4478204643Srdivacky  if (T.isNull())
4479204643Srdivacky    return 0;
4480204643Srdivacky
4481204643Srdivacky  Expr *LHS = Importer.Import(E->getLHS());
4482204643Srdivacky  if (!LHS)
4483204643Srdivacky    return 0;
4484204643Srdivacky
4485204643Srdivacky  Expr *RHS = Importer.Import(E->getRHS());
4486204643Srdivacky  if (!RHS)
4487204643Srdivacky    return 0;
4488204643Srdivacky
4489204643Srdivacky  return new (Importer.getToContext()) BinaryOperator(LHS, RHS, E->getOpcode(),
4490218893Sdim                                                      T, E->getValueKind(),
4491218893Sdim                                                      E->getObjectKind(),
4492245431Sdim                                           Importer.Import(E->getOperatorLoc()),
4493245431Sdim                                                      E->isFPContractable());
4494204643Srdivacky}
4495204643Srdivacky
4496204643SrdivackyExpr *ASTNodeImporter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
4497204643Srdivacky  QualType T = Importer.Import(E->getType());
4498204643Srdivacky  if (T.isNull())
4499204643Srdivacky    return 0;
4500204643Srdivacky
4501204643Srdivacky  QualType CompLHSType = Importer.Import(E->getComputationLHSType());
4502204643Srdivacky  if (CompLHSType.isNull())
4503204643Srdivacky    return 0;
4504204643Srdivacky
4505204643Srdivacky  QualType CompResultType = Importer.Import(E->getComputationResultType());
4506204643Srdivacky  if (CompResultType.isNull())
4507204643Srdivacky    return 0;
4508204643Srdivacky
4509204643Srdivacky  Expr *LHS = Importer.Import(E->getLHS());
4510204643Srdivacky  if (!LHS)
4511204643Srdivacky    return 0;
4512204643Srdivacky
4513204643Srdivacky  Expr *RHS = Importer.Import(E->getRHS());
4514204643Srdivacky  if (!RHS)
4515204643Srdivacky    return 0;
4516204643Srdivacky
4517204643Srdivacky  return new (Importer.getToContext())
4518204643Srdivacky                        CompoundAssignOperator(LHS, RHS, E->getOpcode(),
4519218893Sdim                                               T, E->getValueKind(),
4520218893Sdim                                               E->getObjectKind(),
4521218893Sdim                                               CompLHSType, CompResultType,
4522245431Sdim                                           Importer.Import(E->getOperatorLoc()),
4523245431Sdim                                               E->isFPContractable());
4524204643Srdivacky}
4525204643Srdivacky
4526221345Sdimstatic bool ImportCastPath(CastExpr *E, CXXCastPath &Path) {
4527212904Sdim  if (E->path_empty()) return false;
4528212904Sdim
4529212904Sdim  // TODO: import cast paths
4530212904Sdim  return true;
4531212904Sdim}
4532212904Sdim
4533203955SrdivackyExpr *ASTNodeImporter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
4534203955Srdivacky  QualType T = Importer.Import(E->getType());
4535203955Srdivacky  if (T.isNull())
4536203955Srdivacky    return 0;
4537203955Srdivacky
4538203955Srdivacky  Expr *SubExpr = Importer.Import(E->getSubExpr());
4539203955Srdivacky  if (!SubExpr)
4540203955Srdivacky    return 0;
4541212904Sdim
4542212904Sdim  CXXCastPath BasePath;
4543212904Sdim  if (ImportCastPath(E, BasePath))
4544212904Sdim    return 0;
4545212904Sdim
4546212904Sdim  return ImplicitCastExpr::Create(Importer.getToContext(), T, E->getCastKind(),
4547212904Sdim                                  SubExpr, &BasePath, E->getValueKind());
4548203955Srdivacky}
4549203955Srdivacky
4550204643SrdivackyExpr *ASTNodeImporter::VisitCStyleCastExpr(CStyleCastExpr *E) {
4551204643Srdivacky  QualType T = Importer.Import(E->getType());
4552204643Srdivacky  if (T.isNull())
4553204643Srdivacky    return 0;
4554204643Srdivacky
4555204643Srdivacky  Expr *SubExpr = Importer.Import(E->getSubExpr());
4556204643Srdivacky  if (!SubExpr)
4557204643Srdivacky    return 0;
4558204643Srdivacky
4559204643Srdivacky  TypeSourceInfo *TInfo = Importer.Import(E->getTypeInfoAsWritten());
4560204643Srdivacky  if (!TInfo && E->getTypeInfoAsWritten())
4561204643Srdivacky    return 0;
4562204643Srdivacky
4563212904Sdim  CXXCastPath BasePath;
4564212904Sdim  if (ImportCastPath(E, BasePath))
4565212904Sdim    return 0;
4566212904Sdim
4567218893Sdim  return CStyleCastExpr::Create(Importer.getToContext(), T,
4568218893Sdim                                E->getValueKind(), E->getCastKind(),
4569212904Sdim                                SubExpr, &BasePath, TInfo,
4570212904Sdim                                Importer.Import(E->getLParenLoc()),
4571212904Sdim                                Importer.Import(E->getRParenLoc()));
4572204643Srdivacky}
4573204643Srdivacky
4574218893SdimASTImporter::ASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
4575218893Sdim                         ASTContext &FromContext, FileManager &FromFileManager,
4576218893Sdim                         bool MinimalImport)
4577203955Srdivacky  : ToContext(ToContext), FromContext(FromContext),
4578203955Srdivacky    ToFileManager(ToFileManager), FromFileManager(FromFileManager),
4579252723Sdim    Minimal(MinimalImport), LastDiagFromFrom(false)
4580218893Sdim{
4581203955Srdivacky  ImportedDecls[FromContext.getTranslationUnitDecl()]
4582203955Srdivacky    = ToContext.getTranslationUnitDecl();
4583203955Srdivacky}
4584203955Srdivacky
4585203955SrdivackyASTImporter::~ASTImporter() { }
4586203955Srdivacky
4587203955SrdivackyQualType ASTImporter::Import(QualType FromT) {
4588203955Srdivacky  if (FromT.isNull())
4589203955Srdivacky    return QualType();
4590218893Sdim
4591218893Sdim  const Type *fromTy = FromT.getTypePtr();
4592203955Srdivacky
4593203955Srdivacky  // Check whether we've already imported this type.
4594218893Sdim  llvm::DenseMap<const Type *, const Type *>::iterator Pos
4595218893Sdim    = ImportedTypes.find(fromTy);
4596203955Srdivacky  if (Pos != ImportedTypes.end())
4597218893Sdim    return ToContext.getQualifiedType(Pos->second, FromT.getLocalQualifiers());
4598203955Srdivacky
4599203955Srdivacky  // Import the type
4600203955Srdivacky  ASTNodeImporter Importer(*this);
4601218893Sdim  QualType ToT = Importer.Visit(fromTy);
4602203955Srdivacky  if (ToT.isNull())
4603203955Srdivacky    return ToT;
4604203955Srdivacky
4605203955Srdivacky  // Record the imported type.
4606218893Sdim  ImportedTypes[fromTy] = ToT.getTypePtr();
4607203955Srdivacky
4608218893Sdim  return ToContext.getQualifiedType(ToT, FromT.getLocalQualifiers());
4609203955Srdivacky}
4610203955Srdivacky
4611203955SrdivackyTypeSourceInfo *ASTImporter::Import(TypeSourceInfo *FromTSI) {
4612203955Srdivacky  if (!FromTSI)
4613203955Srdivacky    return FromTSI;
4614203955Srdivacky
4615203955Srdivacky  // FIXME: For now we just create a "trivial" type source info based
4616212904Sdim  // on the type and a single location. Implement a real version of this.
4617203955Srdivacky  QualType T = Import(FromTSI->getType());
4618203955Srdivacky  if (T.isNull())
4619203955Srdivacky    return 0;
4620203955Srdivacky
4621203955Srdivacky  return ToContext.getTrivialTypeSourceInfo(T,
4622235633Sdim                        FromTSI->getTypeLoc().getLocStart());
4623203955Srdivacky}
4624203955Srdivacky
4625203955SrdivackyDecl *ASTImporter::Import(Decl *FromD) {
4626203955Srdivacky  if (!FromD)
4627203955Srdivacky    return 0;
4628203955Srdivacky
4629226890Sdim  ASTNodeImporter Importer(*this);
4630226890Sdim
4631203955Srdivacky  // Check whether we've already imported this declaration.
4632203955Srdivacky  llvm::DenseMap<Decl *, Decl *>::iterator Pos = ImportedDecls.find(FromD);
4633226890Sdim  if (Pos != ImportedDecls.end()) {
4634226890Sdim    Decl *ToD = Pos->second;
4635226890Sdim    Importer.ImportDefinitionIfNeeded(FromD, ToD);
4636226890Sdim    return ToD;
4637226890Sdim  }
4638203955Srdivacky
4639203955Srdivacky  // Import the type
4640203955Srdivacky  Decl *ToD = Importer.Visit(FromD);
4641203955Srdivacky  if (!ToD)
4642203955Srdivacky    return 0;
4643203955Srdivacky
4644203955Srdivacky  // Record the imported declaration.
4645203955Srdivacky  ImportedDecls[FromD] = ToD;
4646203955Srdivacky
4647203955Srdivacky  if (TagDecl *FromTag = dyn_cast<TagDecl>(FromD)) {
4648203955Srdivacky    // Keep track of anonymous tags that have an associated typedef.
4649221345Sdim    if (FromTag->getTypedefNameForAnonDecl())
4650203955Srdivacky      AnonTagsWithPendingTypedefs.push_back(FromTag);
4651221345Sdim  } else if (TypedefNameDecl *FromTypedef = dyn_cast<TypedefNameDecl>(FromD)) {
4652203955Srdivacky    // When we've finished transforming a typedef, see whether it was the
4653203955Srdivacky    // typedef for an anonymous tag.
4654263509Sdim    for (SmallVectorImpl<TagDecl *>::iterator
4655203955Srdivacky               FromTag = AnonTagsWithPendingTypedefs.begin(),
4656203955Srdivacky            FromTagEnd = AnonTagsWithPendingTypedefs.end();
4657203955Srdivacky         FromTag != FromTagEnd; ++FromTag) {
4658221345Sdim      if ((*FromTag)->getTypedefNameForAnonDecl() == FromTypedef) {
4659203955Srdivacky        if (TagDecl *ToTag = cast_or_null<TagDecl>(Import(*FromTag))) {
4660203955Srdivacky          // We found the typedef for an anonymous tag; link them.
4661221345Sdim          ToTag->setTypedefNameForAnonDecl(cast<TypedefNameDecl>(ToD));
4662203955Srdivacky          AnonTagsWithPendingTypedefs.erase(FromTag);
4663203955Srdivacky          break;
4664203955Srdivacky        }
4665203955Srdivacky      }
4666203955Srdivacky    }
4667203955Srdivacky  }
4668203955Srdivacky
4669203955Srdivacky  return ToD;
4670203955Srdivacky}
4671203955Srdivacky
4672203955SrdivackyDeclContext *ASTImporter::ImportContext(DeclContext *FromDC) {
4673203955Srdivacky  if (!FromDC)
4674203955Srdivacky    return FromDC;
4675203955Srdivacky
4676235633Sdim  DeclContext *ToDC = cast_or_null<DeclContext>(Import(cast<Decl>(FromDC)));
4677235633Sdim  if (!ToDC)
4678235633Sdim    return 0;
4679235633Sdim
4680235633Sdim  // When we're using a record/enum/Objective-C class/protocol as a context, we
4681235633Sdim  // need it to have a definition.
4682235633Sdim  if (RecordDecl *ToRecord = dyn_cast<RecordDecl>(ToDC)) {
4683235633Sdim    RecordDecl *FromRecord = cast<RecordDecl>(FromDC);
4684235633Sdim    if (ToRecord->isCompleteDefinition()) {
4685235633Sdim      // Do nothing.
4686235633Sdim    } else if (FromRecord->isCompleteDefinition()) {
4687235633Sdim      ASTNodeImporter(*this).ImportDefinition(FromRecord, ToRecord,
4688235633Sdim                                              ASTNodeImporter::IDK_Basic);
4689235633Sdim    } else {
4690235633Sdim      CompleteDecl(ToRecord);
4691235633Sdim    }
4692235633Sdim  } else if (EnumDecl *ToEnum = dyn_cast<EnumDecl>(ToDC)) {
4693235633Sdim    EnumDecl *FromEnum = cast<EnumDecl>(FromDC);
4694235633Sdim    if (ToEnum->isCompleteDefinition()) {
4695235633Sdim      // Do nothing.
4696235633Sdim    } else if (FromEnum->isCompleteDefinition()) {
4697235633Sdim      ASTNodeImporter(*this).ImportDefinition(FromEnum, ToEnum,
4698235633Sdim                                              ASTNodeImporter::IDK_Basic);
4699235633Sdim    } else {
4700235633Sdim      CompleteDecl(ToEnum);
4701235633Sdim    }
4702235633Sdim  } else if (ObjCInterfaceDecl *ToClass = dyn_cast<ObjCInterfaceDecl>(ToDC)) {
4703235633Sdim    ObjCInterfaceDecl *FromClass = cast<ObjCInterfaceDecl>(FromDC);
4704235633Sdim    if (ToClass->getDefinition()) {
4705235633Sdim      // Do nothing.
4706235633Sdim    } else if (ObjCInterfaceDecl *FromDef = FromClass->getDefinition()) {
4707235633Sdim      ASTNodeImporter(*this).ImportDefinition(FromDef, ToClass,
4708235633Sdim                                              ASTNodeImporter::IDK_Basic);
4709235633Sdim    } else {
4710235633Sdim      CompleteDecl(ToClass);
4711235633Sdim    }
4712235633Sdim  } else if (ObjCProtocolDecl *ToProto = dyn_cast<ObjCProtocolDecl>(ToDC)) {
4713235633Sdim    ObjCProtocolDecl *FromProto = cast<ObjCProtocolDecl>(FromDC);
4714235633Sdim    if (ToProto->getDefinition()) {
4715235633Sdim      // Do nothing.
4716235633Sdim    } else if (ObjCProtocolDecl *FromDef = FromProto->getDefinition()) {
4717235633Sdim      ASTNodeImporter(*this).ImportDefinition(FromDef, ToProto,
4718235633Sdim                                              ASTNodeImporter::IDK_Basic);
4719235633Sdim    } else {
4720235633Sdim      CompleteDecl(ToProto);
4721235633Sdim    }
4722235633Sdim  }
4723235633Sdim
4724235633Sdim  return ToDC;
4725203955Srdivacky}
4726203955Srdivacky
4727203955SrdivackyExpr *ASTImporter::Import(Expr *FromE) {
4728203955Srdivacky  if (!FromE)
4729203955Srdivacky    return 0;
4730203955Srdivacky
4731203955Srdivacky  return cast_or_null<Expr>(Import(cast<Stmt>(FromE)));
4732203955Srdivacky}
4733203955Srdivacky
4734203955SrdivackyStmt *ASTImporter::Import(Stmt *FromS) {
4735203955Srdivacky  if (!FromS)
4736203955Srdivacky    return 0;
4737203955Srdivacky
4738203955Srdivacky  // Check whether we've already imported this declaration.
4739203955Srdivacky  llvm::DenseMap<Stmt *, Stmt *>::iterator Pos = ImportedStmts.find(FromS);
4740203955Srdivacky  if (Pos != ImportedStmts.end())
4741203955Srdivacky    return Pos->second;
4742203955Srdivacky
4743203955Srdivacky  // Import the type
4744203955Srdivacky  ASTNodeImporter Importer(*this);
4745203955Srdivacky  Stmt *ToS = Importer.Visit(FromS);
4746203955Srdivacky  if (!ToS)
4747203955Srdivacky    return 0;
4748203955Srdivacky
4749203955Srdivacky  // Record the imported declaration.
4750203955Srdivacky  ImportedStmts[FromS] = ToS;
4751203955Srdivacky  return ToS;
4752203955Srdivacky}
4753203955Srdivacky
4754203955SrdivackyNestedNameSpecifier *ASTImporter::Import(NestedNameSpecifier *FromNNS) {
4755203955Srdivacky  if (!FromNNS)
4756203955Srdivacky    return 0;
4757203955Srdivacky
4758221345Sdim  NestedNameSpecifier *prefix = Import(FromNNS->getPrefix());
4759221345Sdim
4760221345Sdim  switch (FromNNS->getKind()) {
4761221345Sdim  case NestedNameSpecifier::Identifier:
4762221345Sdim    if (IdentifierInfo *II = Import(FromNNS->getAsIdentifier())) {
4763221345Sdim      return NestedNameSpecifier::Create(ToContext, prefix, II);
4764221345Sdim    }
4765221345Sdim    return 0;
4766221345Sdim
4767221345Sdim  case NestedNameSpecifier::Namespace:
4768221345Sdim    if (NamespaceDecl *NS =
4769221345Sdim          cast<NamespaceDecl>(Import(FromNNS->getAsNamespace()))) {
4770221345Sdim      return NestedNameSpecifier::Create(ToContext, prefix, NS);
4771221345Sdim    }
4772221345Sdim    return 0;
4773221345Sdim
4774221345Sdim  case NestedNameSpecifier::NamespaceAlias:
4775221345Sdim    if (NamespaceAliasDecl *NSAD =
4776221345Sdim          cast<NamespaceAliasDecl>(Import(FromNNS->getAsNamespaceAlias()))) {
4777221345Sdim      return NestedNameSpecifier::Create(ToContext, prefix, NSAD);
4778221345Sdim    }
4779221345Sdim    return 0;
4780221345Sdim
4781221345Sdim  case NestedNameSpecifier::Global:
4782221345Sdim    return NestedNameSpecifier::GlobalSpecifier(ToContext);
4783221345Sdim
4784221345Sdim  case NestedNameSpecifier::TypeSpec:
4785221345Sdim  case NestedNameSpecifier::TypeSpecWithTemplate: {
4786221345Sdim      QualType T = Import(QualType(FromNNS->getAsType(), 0u));
4787221345Sdim      if (!T.isNull()) {
4788221345Sdim        bool bTemplate = FromNNS->getKind() ==
4789221345Sdim                         NestedNameSpecifier::TypeSpecWithTemplate;
4790221345Sdim        return NestedNameSpecifier::Create(ToContext, prefix,
4791221345Sdim                                           bTemplate, T.getTypePtr());
4792221345Sdim      }
4793221345Sdim    }
4794221345Sdim    return 0;
4795221345Sdim  }
4796221345Sdim
4797221345Sdim  llvm_unreachable("Invalid nested name specifier kind");
4798203955Srdivacky}
4799203955Srdivacky
4800219077SdimNestedNameSpecifierLoc ASTImporter::Import(NestedNameSpecifierLoc FromNNS) {
4801219077Sdim  // FIXME: Implement!
4802219077Sdim  return NestedNameSpecifierLoc();
4803219077Sdim}
4804219077Sdim
4805218893SdimTemplateName ASTImporter::Import(TemplateName From) {
4806218893Sdim  switch (From.getKind()) {
4807218893Sdim  case TemplateName::Template:
4808218893Sdim    if (TemplateDecl *ToTemplate
4809218893Sdim                = cast_or_null<TemplateDecl>(Import(From.getAsTemplateDecl())))
4810218893Sdim      return TemplateName(ToTemplate);
4811218893Sdim
4812218893Sdim    return TemplateName();
4813218893Sdim
4814218893Sdim  case TemplateName::OverloadedTemplate: {
4815218893Sdim    OverloadedTemplateStorage *FromStorage = From.getAsOverloadedTemplate();
4816218893Sdim    UnresolvedSet<2> ToTemplates;
4817218893Sdim    for (OverloadedTemplateStorage::iterator I = FromStorage->begin(),
4818218893Sdim                                             E = FromStorage->end();
4819218893Sdim         I != E; ++I) {
4820218893Sdim      if (NamedDecl *To = cast_or_null<NamedDecl>(Import(*I)))
4821218893Sdim        ToTemplates.addDecl(To);
4822218893Sdim      else
4823218893Sdim        return TemplateName();
4824218893Sdim    }
4825218893Sdim    return ToContext.getOverloadedTemplateName(ToTemplates.begin(),
4826218893Sdim                                               ToTemplates.end());
4827218893Sdim  }
4828218893Sdim
4829218893Sdim  case TemplateName::QualifiedTemplate: {
4830218893Sdim    QualifiedTemplateName *QTN = From.getAsQualifiedTemplateName();
4831218893Sdim    NestedNameSpecifier *Qualifier = Import(QTN->getQualifier());
4832218893Sdim    if (!Qualifier)
4833218893Sdim      return TemplateName();
4834218893Sdim
4835218893Sdim    if (TemplateDecl *ToTemplate
4836218893Sdim        = cast_or_null<TemplateDecl>(Import(From.getAsTemplateDecl())))
4837218893Sdim      return ToContext.getQualifiedTemplateName(Qualifier,
4838218893Sdim                                                QTN->hasTemplateKeyword(),
4839218893Sdim                                                ToTemplate);
4840218893Sdim
4841218893Sdim    return TemplateName();
4842218893Sdim  }
4843218893Sdim
4844218893Sdim  case TemplateName::DependentTemplate: {
4845218893Sdim    DependentTemplateName *DTN = From.getAsDependentTemplateName();
4846218893Sdim    NestedNameSpecifier *Qualifier = Import(DTN->getQualifier());
4847218893Sdim    if (!Qualifier)
4848218893Sdim      return TemplateName();
4849218893Sdim
4850218893Sdim    if (DTN->isIdentifier()) {
4851218893Sdim      return ToContext.getDependentTemplateName(Qualifier,
4852218893Sdim                                                Import(DTN->getIdentifier()));
4853218893Sdim    }
4854218893Sdim
4855218893Sdim    return ToContext.getDependentTemplateName(Qualifier, DTN->getOperator());
4856218893Sdim  }
4857224145Sdim
4858224145Sdim  case TemplateName::SubstTemplateTemplateParm: {
4859224145Sdim    SubstTemplateTemplateParmStorage *subst
4860224145Sdim      = From.getAsSubstTemplateTemplateParm();
4861224145Sdim    TemplateTemplateParmDecl *param
4862224145Sdim      = cast_or_null<TemplateTemplateParmDecl>(Import(subst->getParameter()));
4863224145Sdim    if (!param)
4864224145Sdim      return TemplateName();
4865224145Sdim
4866224145Sdim    TemplateName replacement = Import(subst->getReplacement());
4867224145Sdim    if (replacement.isNull()) return TemplateName();
4868224145Sdim
4869224145Sdim    return ToContext.getSubstTemplateTemplateParm(param, replacement);
4870224145Sdim  }
4871218893Sdim
4872218893Sdim  case TemplateName::SubstTemplateTemplateParmPack: {
4873218893Sdim    SubstTemplateTemplateParmPackStorage *SubstPack
4874218893Sdim      = From.getAsSubstTemplateTemplateParmPack();
4875218893Sdim    TemplateTemplateParmDecl *Param
4876218893Sdim      = cast_or_null<TemplateTemplateParmDecl>(
4877218893Sdim                                        Import(SubstPack->getParameterPack()));
4878218893Sdim    if (!Param)
4879218893Sdim      return TemplateName();
4880218893Sdim
4881218893Sdim    ASTNodeImporter Importer(*this);
4882218893Sdim    TemplateArgument ArgPack
4883218893Sdim      = Importer.ImportTemplateArgument(SubstPack->getArgumentPack());
4884218893Sdim    if (ArgPack.isNull())
4885218893Sdim      return TemplateName();
4886218893Sdim
4887218893Sdim    return ToContext.getSubstTemplateTemplateParmPack(Param, ArgPack);
4888218893Sdim  }
4889218893Sdim  }
4890218893Sdim
4891218893Sdim  llvm_unreachable("Invalid template name kind");
4892218893Sdim}
4893218893Sdim
4894203955SrdivackySourceLocation ASTImporter::Import(SourceLocation FromLoc) {
4895203955Srdivacky  if (FromLoc.isInvalid())
4896203955Srdivacky    return SourceLocation();
4897203955Srdivacky
4898203955Srdivacky  SourceManager &FromSM = FromContext.getSourceManager();
4899203955Srdivacky
4900203955Srdivacky  // For now, map everything down to its spelling location, so that we
4901224145Sdim  // don't have to import macro expansions.
4902224145Sdim  // FIXME: Import macro expansions!
4903203955Srdivacky  FromLoc = FromSM.getSpellingLoc(FromLoc);
4904203955Srdivacky  std::pair<FileID, unsigned> Decomposed = FromSM.getDecomposedLoc(FromLoc);
4905203955Srdivacky  SourceManager &ToSM = ToContext.getSourceManager();
4906203955Srdivacky  return ToSM.getLocForStartOfFile(Import(Decomposed.first))
4907226890Sdim             .getLocWithOffset(Decomposed.second);
4908203955Srdivacky}
4909203955Srdivacky
4910203955SrdivackySourceRange ASTImporter::Import(SourceRange FromRange) {
4911203955Srdivacky  return SourceRange(Import(FromRange.getBegin()), Import(FromRange.getEnd()));
4912203955Srdivacky}
4913203955Srdivacky
4914203955SrdivackyFileID ASTImporter::Import(FileID FromID) {
4915218893Sdim  llvm::DenseMap<FileID, FileID>::iterator Pos
4916218893Sdim    = ImportedFileIDs.find(FromID);
4917203955Srdivacky  if (Pos != ImportedFileIDs.end())
4918203955Srdivacky    return Pos->second;
4919203955Srdivacky
4920203955Srdivacky  SourceManager &FromSM = FromContext.getSourceManager();
4921203955Srdivacky  SourceManager &ToSM = ToContext.getSourceManager();
4922203955Srdivacky  const SrcMgr::SLocEntry &FromSLoc = FromSM.getSLocEntry(FromID);
4923224145Sdim  assert(FromSLoc.isFile() && "Cannot handle macro expansions yet");
4924203955Srdivacky
4925203955Srdivacky  // Include location of this file.
4926203955Srdivacky  SourceLocation ToIncludeLoc = Import(FromSLoc.getFile().getIncludeLoc());
4927203955Srdivacky
4928203955Srdivacky  // Map the FileID for to the "to" source manager.
4929203955Srdivacky  FileID ToID;
4930203955Srdivacky  const SrcMgr::ContentCache *Cache = FromSLoc.getFile().getContentCache();
4931221345Sdim  if (Cache->OrigEntry) {
4932203955Srdivacky    // FIXME: We probably want to use getVirtualFile(), so we don't hit the
4933203955Srdivacky    // disk again
4934203955Srdivacky    // FIXME: We definitely want to re-use the existing MemoryBuffer, rather
4935203955Srdivacky    // than mmap the files several times.
4936221345Sdim    const FileEntry *Entry = ToFileManager.getFile(Cache->OrigEntry->getName());
4937203955Srdivacky    ToID = ToSM.createFileID(Entry, ToIncludeLoc,
4938203955Srdivacky                             FromSLoc.getFile().getFileCharacteristic());
4939203955Srdivacky  } else {
4940203955Srdivacky    // FIXME: We want to re-use the existing MemoryBuffer!
4941218893Sdim    const llvm::MemoryBuffer *
4942218893Sdim        FromBuf = Cache->getBuffer(FromContext.getDiagnostics(), FromSM);
4943203955Srdivacky    llvm::MemoryBuffer *ToBuf
4944206275Srdivacky      = llvm::MemoryBuffer::getMemBufferCopy(FromBuf->getBuffer(),
4945203955Srdivacky                                             FromBuf->getBufferIdentifier());
4946245431Sdim    ToID = ToSM.createFileIDForMemBuffer(ToBuf,
4947245431Sdim                                    FromSLoc.getFile().getFileCharacteristic());
4948203955Srdivacky  }
4949203955Srdivacky
4950203955Srdivacky
4951218893Sdim  ImportedFileIDs[FromID] = ToID;
4952203955Srdivacky  return ToID;
4953203955Srdivacky}
4954203955Srdivacky
4955218893Sdimvoid ASTImporter::ImportDefinition(Decl *From) {
4956218893Sdim  Decl *To = Import(From);
4957218893Sdim  if (!To)
4958218893Sdim    return;
4959218893Sdim
4960218893Sdim  if (DeclContext *FromDC = cast<DeclContext>(From)) {
4961218893Sdim    ASTNodeImporter Importer(*this);
4962226890Sdim
4963226890Sdim    if (RecordDecl *ToRecord = dyn_cast<RecordDecl>(To)) {
4964226890Sdim      if (!ToRecord->getDefinition()) {
4965226890Sdim        Importer.ImportDefinition(cast<RecordDecl>(FromDC), ToRecord,
4966235633Sdim                                  ASTNodeImporter::IDK_Everything);
4967226890Sdim        return;
4968226890Sdim      }
4969226890Sdim    }
4970226890Sdim
4971226890Sdim    if (EnumDecl *ToEnum = dyn_cast<EnumDecl>(To)) {
4972226890Sdim      if (!ToEnum->getDefinition()) {
4973226890Sdim        Importer.ImportDefinition(cast<EnumDecl>(FromDC), ToEnum,
4974235633Sdim                                  ASTNodeImporter::IDK_Everything);
4975226890Sdim        return;
4976226890Sdim      }
4977226890Sdim    }
4978235633Sdim
4979235633Sdim    if (ObjCInterfaceDecl *ToIFace = dyn_cast<ObjCInterfaceDecl>(To)) {
4980235633Sdim      if (!ToIFace->getDefinition()) {
4981235633Sdim        Importer.ImportDefinition(cast<ObjCInterfaceDecl>(FromDC), ToIFace,
4982235633Sdim                                  ASTNodeImporter::IDK_Everything);
4983235633Sdim        return;
4984235633Sdim      }
4985235633Sdim    }
4986226890Sdim
4987235633Sdim    if (ObjCProtocolDecl *ToProto = dyn_cast<ObjCProtocolDecl>(To)) {
4988235633Sdim      if (!ToProto->getDefinition()) {
4989235633Sdim        Importer.ImportDefinition(cast<ObjCProtocolDecl>(FromDC), ToProto,
4990235633Sdim                                  ASTNodeImporter::IDK_Everything);
4991235633Sdim        return;
4992235633Sdim      }
4993235633Sdim    }
4994235633Sdim
4995218893Sdim    Importer.ImportDeclContext(FromDC, true);
4996218893Sdim  }
4997218893Sdim}
4998218893Sdim
4999203955SrdivackyDeclarationName ASTImporter::Import(DeclarationName FromName) {
5000203955Srdivacky  if (!FromName)
5001203955Srdivacky    return DeclarationName();
5002203955Srdivacky
5003203955Srdivacky  switch (FromName.getNameKind()) {
5004203955Srdivacky  case DeclarationName::Identifier:
5005203955Srdivacky    return Import(FromName.getAsIdentifierInfo());
5006203955Srdivacky
5007203955Srdivacky  case DeclarationName::ObjCZeroArgSelector:
5008203955Srdivacky  case DeclarationName::ObjCOneArgSelector:
5009203955Srdivacky  case DeclarationName::ObjCMultiArgSelector:
5010203955Srdivacky    return Import(FromName.getObjCSelector());
5011203955Srdivacky
5012203955Srdivacky  case DeclarationName::CXXConstructorName: {
5013203955Srdivacky    QualType T = Import(FromName.getCXXNameType());
5014203955Srdivacky    if (T.isNull())
5015203955Srdivacky      return DeclarationName();
5016203955Srdivacky
5017203955Srdivacky    return ToContext.DeclarationNames.getCXXConstructorName(
5018203955Srdivacky                                               ToContext.getCanonicalType(T));
5019203955Srdivacky  }
5020203955Srdivacky
5021203955Srdivacky  case DeclarationName::CXXDestructorName: {
5022203955Srdivacky    QualType T = Import(FromName.getCXXNameType());
5023203955Srdivacky    if (T.isNull())
5024203955Srdivacky      return DeclarationName();
5025203955Srdivacky
5026203955Srdivacky    return ToContext.DeclarationNames.getCXXDestructorName(
5027203955Srdivacky                                               ToContext.getCanonicalType(T));
5028203955Srdivacky  }
5029203955Srdivacky
5030203955Srdivacky  case DeclarationName::CXXConversionFunctionName: {
5031203955Srdivacky    QualType T = Import(FromName.getCXXNameType());
5032203955Srdivacky    if (T.isNull())
5033203955Srdivacky      return DeclarationName();
5034203955Srdivacky
5035203955Srdivacky    return ToContext.DeclarationNames.getCXXConversionFunctionName(
5036203955Srdivacky                                               ToContext.getCanonicalType(T));
5037203955Srdivacky  }
5038203955Srdivacky
5039203955Srdivacky  case DeclarationName::CXXOperatorName:
5040203955Srdivacky    return ToContext.DeclarationNames.getCXXOperatorName(
5041203955Srdivacky                                          FromName.getCXXOverloadedOperator());
5042203955Srdivacky
5043203955Srdivacky  case DeclarationName::CXXLiteralOperatorName:
5044203955Srdivacky    return ToContext.DeclarationNames.getCXXLiteralOperatorName(
5045203955Srdivacky                                   Import(FromName.getCXXLiteralIdentifier()));
5046203955Srdivacky
5047203955Srdivacky  case DeclarationName::CXXUsingDirective:
5048203955Srdivacky    // FIXME: STATICS!
5049203955Srdivacky    return DeclarationName::getUsingDirectiveName();
5050203955Srdivacky  }
5051203955Srdivacky
5052235633Sdim  llvm_unreachable("Invalid DeclarationName Kind!");
5053203955Srdivacky}
5054203955Srdivacky
5055218893SdimIdentifierInfo *ASTImporter::Import(const IdentifierInfo *FromId) {
5056203955Srdivacky  if (!FromId)
5057203955Srdivacky    return 0;
5058203955Srdivacky
5059203955Srdivacky  return &ToContext.Idents.get(FromId->getName());
5060203955Srdivacky}
5061203955Srdivacky
5062204643SrdivackySelector ASTImporter::Import(Selector FromSel) {
5063204643Srdivacky  if (FromSel.isNull())
5064204643Srdivacky    return Selector();
5065204643Srdivacky
5066226890Sdim  SmallVector<IdentifierInfo *, 4> Idents;
5067204643Srdivacky  Idents.push_back(Import(FromSel.getIdentifierInfoForSlot(0)));
5068204643Srdivacky  for (unsigned I = 1, N = FromSel.getNumArgs(); I < N; ++I)
5069204643Srdivacky    Idents.push_back(Import(FromSel.getIdentifierInfoForSlot(I)));
5070204643Srdivacky  return ToContext.Selectors.getSelector(FromSel.getNumArgs(), Idents.data());
5071204643Srdivacky}
5072204643Srdivacky
5073203955SrdivackyDeclarationName ASTImporter::HandleNameConflict(DeclarationName Name,
5074203955Srdivacky                                                DeclContext *DC,
5075203955Srdivacky                                                unsigned IDNS,
5076203955Srdivacky                                                NamedDecl **Decls,
5077203955Srdivacky                                                unsigned NumDecls) {
5078203955Srdivacky  return Name;
5079203955Srdivacky}
5080203955Srdivacky
5081203955SrdivackyDiagnosticBuilder ASTImporter::ToDiag(SourceLocation Loc, unsigned DiagID) {
5082252723Sdim  if (LastDiagFromFrom)
5083252723Sdim    ToContext.getDiagnostics().notePriorDiagnosticFrom(
5084252723Sdim      FromContext.getDiagnostics());
5085252723Sdim  LastDiagFromFrom = false;
5086218893Sdim  return ToContext.getDiagnostics().Report(Loc, DiagID);
5087203955Srdivacky}
5088203955Srdivacky
5089203955SrdivackyDiagnosticBuilder ASTImporter::FromDiag(SourceLocation Loc, unsigned DiagID) {
5090252723Sdim  if (!LastDiagFromFrom)
5091252723Sdim    FromContext.getDiagnostics().notePriorDiagnosticFrom(
5092252723Sdim      ToContext.getDiagnostics());
5093252723Sdim  LastDiagFromFrom = true;
5094218893Sdim  return FromContext.getDiagnostics().Report(Loc, DiagID);
5095203955Srdivacky}
5096203955Srdivacky
5097235633Sdimvoid ASTImporter::CompleteDecl (Decl *D) {
5098235633Sdim  if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
5099235633Sdim    if (!ID->getDefinition())
5100235633Sdim      ID->startDefinition();
5101235633Sdim  }
5102235633Sdim  else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) {
5103235633Sdim    if (!PD->getDefinition())
5104235633Sdim      PD->startDefinition();
5105235633Sdim  }
5106235633Sdim  else if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
5107235633Sdim    if (!TD->getDefinition() && !TD->isBeingDefined()) {
5108235633Sdim      TD->startDefinition();
5109235633Sdim      TD->setCompleteDefinition(true);
5110235633Sdim    }
5111235633Sdim  }
5112235633Sdim  else {
5113235633Sdim    assert (0 && "CompleteDecl called on a Decl that can't be completed");
5114235633Sdim  }
5115235633Sdim}
5116235633Sdim
5117203955SrdivackyDecl *ASTImporter::Imported(Decl *From, Decl *To) {
5118203955Srdivacky  ImportedDecls[From] = To;
5119203955Srdivacky  return To;
5120203955Srdivacky}
5121203955Srdivacky
5122245431Sdimbool ASTImporter::IsStructurallyEquivalent(QualType From, QualType To,
5123245431Sdim                                           bool Complain) {
5124218893Sdim  llvm::DenseMap<const Type *, const Type *>::iterator Pos
5125203955Srdivacky   = ImportedTypes.find(From.getTypePtr());
5126203955Srdivacky  if (Pos != ImportedTypes.end() && ToContext.hasSameType(Import(From), To))
5127203955Srdivacky    return true;
5128203955Srdivacky
5129245431Sdim  StructuralEquivalenceContext Ctx(FromContext, ToContext, NonEquivalentDecls,
5130245431Sdim                                   false, Complain);
5131204643Srdivacky  return Ctx.IsStructurallyEquivalent(From, To);
5132203955Srdivacky}
5133