ASTImporter.cpp revision 204643
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
16203955Srdivacky#include "clang/AST/ASTContext.h"
17203955Srdivacky#include "clang/AST/ASTDiagnostic.h"
18203955Srdivacky#include "clang/AST/DeclCXX.h"
19203955Srdivacky#include "clang/AST/DeclObjC.h"
20203955Srdivacky#include "clang/AST/DeclVisitor.h"
21203955Srdivacky#include "clang/AST/StmtVisitor.h"
22203955Srdivacky#include "clang/AST/TypeLoc.h"
23203955Srdivacky#include "clang/AST/TypeVisitor.h"
24203955Srdivacky#include "clang/Basic/FileManager.h"
25203955Srdivacky#include "clang/Basic/SourceManager.h"
26203955Srdivacky#include "llvm/Support/MemoryBuffer.h"
27203955Srdivacky#include <deque>
28203955Srdivacky
29203955Srdivackyusing namespace clang;
30203955Srdivacky
31203955Srdivackynamespace {
32203955Srdivacky  class ASTNodeImporter : public TypeVisitor<ASTNodeImporter, QualType>,
33203955Srdivacky                          public DeclVisitor<ASTNodeImporter, Decl *>,
34203955Srdivacky                          public StmtVisitor<ASTNodeImporter, Stmt *> {
35203955Srdivacky    ASTImporter &Importer;
36203955Srdivacky
37203955Srdivacky  public:
38203955Srdivacky    explicit ASTNodeImporter(ASTImporter &Importer) : Importer(Importer) { }
39203955Srdivacky
40203955Srdivacky    using TypeVisitor<ASTNodeImporter, QualType>::Visit;
41203955Srdivacky    using DeclVisitor<ASTNodeImporter, Decl *>::Visit;
42203955Srdivacky    using StmtVisitor<ASTNodeImporter, Stmt *>::Visit;
43203955Srdivacky
44203955Srdivacky    // Importing types
45203955Srdivacky    QualType VisitType(Type *T);
46203955Srdivacky    QualType VisitBuiltinType(BuiltinType *T);
47203955Srdivacky    QualType VisitComplexType(ComplexType *T);
48203955Srdivacky    QualType VisitPointerType(PointerType *T);
49203955Srdivacky    QualType VisitBlockPointerType(BlockPointerType *T);
50203955Srdivacky    QualType VisitLValueReferenceType(LValueReferenceType *T);
51203955Srdivacky    QualType VisitRValueReferenceType(RValueReferenceType *T);
52203955Srdivacky    QualType VisitMemberPointerType(MemberPointerType *T);
53203955Srdivacky    QualType VisitConstantArrayType(ConstantArrayType *T);
54203955Srdivacky    QualType VisitIncompleteArrayType(IncompleteArrayType *T);
55203955Srdivacky    QualType VisitVariableArrayType(VariableArrayType *T);
56203955Srdivacky    // FIXME: DependentSizedArrayType
57203955Srdivacky    // FIXME: DependentSizedExtVectorType
58203955Srdivacky    QualType VisitVectorType(VectorType *T);
59203955Srdivacky    QualType VisitExtVectorType(ExtVectorType *T);
60203955Srdivacky    QualType VisitFunctionNoProtoType(FunctionNoProtoType *T);
61203955Srdivacky    QualType VisitFunctionProtoType(FunctionProtoType *T);
62203955Srdivacky    // FIXME: UnresolvedUsingType
63203955Srdivacky    QualType VisitTypedefType(TypedefType *T);
64203955Srdivacky    QualType VisitTypeOfExprType(TypeOfExprType *T);
65203955Srdivacky    // FIXME: DependentTypeOfExprType
66203955Srdivacky    QualType VisitTypeOfType(TypeOfType *T);
67203955Srdivacky    QualType VisitDecltypeType(DecltypeType *T);
68203955Srdivacky    // FIXME: DependentDecltypeType
69203955Srdivacky    QualType VisitRecordType(RecordType *T);
70203955Srdivacky    QualType VisitEnumType(EnumType *T);
71203955Srdivacky    QualType VisitElaboratedType(ElaboratedType *T);
72203955Srdivacky    // FIXME: TemplateTypeParmType
73203955Srdivacky    // FIXME: SubstTemplateTypeParmType
74203955Srdivacky    // FIXME: TemplateSpecializationType
75203955Srdivacky    QualType VisitQualifiedNameType(QualifiedNameType *T);
76203955Srdivacky    // FIXME: TypenameType
77203955Srdivacky    QualType VisitObjCInterfaceType(ObjCInterfaceType *T);
78203955Srdivacky    QualType VisitObjCObjectPointerType(ObjCObjectPointerType *T);
79203955Srdivacky
80203955Srdivacky    // Importing declarations
81203955Srdivacky    bool ImportDeclParts(NamedDecl *D, DeclContext *&DC,
82203955Srdivacky                         DeclContext *&LexicalDC, DeclarationName &Name,
83204643Srdivacky                         SourceLocation &Loc);
84204643Srdivacky    void ImportDeclContext(DeclContext *FromDC);
85203955Srdivacky    bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord);
86203955Srdivacky    bool IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToRecord);
87203955Srdivacky    Decl *VisitDecl(Decl *D);
88204643Srdivacky    Decl *VisitNamespaceDecl(NamespaceDecl *D);
89203955Srdivacky    Decl *VisitTypedefDecl(TypedefDecl *D);
90203955Srdivacky    Decl *VisitEnumDecl(EnumDecl *D);
91203955Srdivacky    Decl *VisitRecordDecl(RecordDecl *D);
92203955Srdivacky    Decl *VisitEnumConstantDecl(EnumConstantDecl *D);
93203955Srdivacky    Decl *VisitFunctionDecl(FunctionDecl *D);
94204643Srdivacky    Decl *VisitCXXMethodDecl(CXXMethodDecl *D);
95204643Srdivacky    Decl *VisitCXXConstructorDecl(CXXConstructorDecl *D);
96204643Srdivacky    Decl *VisitCXXDestructorDecl(CXXDestructorDecl *D);
97204643Srdivacky    Decl *VisitCXXConversionDecl(CXXConversionDecl *D);
98203955Srdivacky    Decl *VisitFieldDecl(FieldDecl *D);
99204643Srdivacky    Decl *VisitObjCIvarDecl(ObjCIvarDecl *D);
100203955Srdivacky    Decl *VisitVarDecl(VarDecl *D);
101204643Srdivacky    Decl *VisitImplicitParamDecl(ImplicitParamDecl *D);
102203955Srdivacky    Decl *VisitParmVarDecl(ParmVarDecl *D);
103204643Srdivacky    Decl *VisitObjCMethodDecl(ObjCMethodDecl *D);
104204643Srdivacky    Decl *VisitObjCCategoryDecl(ObjCCategoryDecl *D);
105204643Srdivacky    Decl *VisitObjCProtocolDecl(ObjCProtocolDecl *D);
106203955Srdivacky    Decl *VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
107204643Srdivacky    Decl *VisitObjCPropertyDecl(ObjCPropertyDecl *D);
108204643Srdivacky    Decl *VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D);
109204643Srdivacky    Decl *VisitObjCClassDecl(ObjCClassDecl *D);
110203955Srdivacky
111203955Srdivacky    // Importing statements
112203955Srdivacky    Stmt *VisitStmt(Stmt *S);
113203955Srdivacky
114203955Srdivacky    // Importing expressions
115203955Srdivacky    Expr *VisitExpr(Expr *E);
116204643Srdivacky    Expr *VisitDeclRefExpr(DeclRefExpr *E);
117203955Srdivacky    Expr *VisitIntegerLiteral(IntegerLiteral *E);
118204643Srdivacky    Expr *VisitCharacterLiteral(CharacterLiteral *E);
119204643Srdivacky    Expr *VisitParenExpr(ParenExpr *E);
120204643Srdivacky    Expr *VisitUnaryOperator(UnaryOperator *E);
121204643Srdivacky    Expr *VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E);
122204643Srdivacky    Expr *VisitBinaryOperator(BinaryOperator *E);
123204643Srdivacky    Expr *VisitCompoundAssignOperator(CompoundAssignOperator *E);
124203955Srdivacky    Expr *VisitImplicitCastExpr(ImplicitCastExpr *E);
125204643Srdivacky    Expr *VisitCStyleCastExpr(CStyleCastExpr *E);
126203955Srdivacky  };
127203955Srdivacky}
128203955Srdivacky
129203955Srdivacky//----------------------------------------------------------------------------
130203955Srdivacky// Structural Equivalence
131203955Srdivacky//----------------------------------------------------------------------------
132203955Srdivacky
133203955Srdivackynamespace {
134203955Srdivacky  struct StructuralEquivalenceContext {
135203955Srdivacky    /// \brief AST contexts for which we are checking structural equivalence.
136203955Srdivacky    ASTContext &C1, &C2;
137203955Srdivacky
138203955Srdivacky    /// \brief Diagnostic object used to emit diagnostics.
139203955Srdivacky    Diagnostic &Diags;
140203955Srdivacky
141203955Srdivacky    /// \brief The set of "tentative" equivalences between two canonical
142203955Srdivacky    /// declarations, mapping from a declaration in the first context to the
143203955Srdivacky    /// declaration in the second context that we believe to be equivalent.
144203955Srdivacky    llvm::DenseMap<Decl *, Decl *> TentativeEquivalences;
145203955Srdivacky
146203955Srdivacky    /// \brief Queue of declarations in the first context whose equivalence
147203955Srdivacky    /// with a declaration in the second context still needs to be verified.
148203955Srdivacky    std::deque<Decl *> DeclsToCheck;
149203955Srdivacky
150203955Srdivacky    /// \brief Declaration (from, to) pairs that are known not to be equivalent
151203955Srdivacky    /// (which we have already complained about).
152203955Srdivacky    llvm::DenseSet<std::pair<Decl *, Decl *> > &NonEquivalentDecls;
153203955Srdivacky
154203955Srdivacky    /// \brief Whether we're being strict about the spelling of types when
155203955Srdivacky    /// unifying two types.
156203955Srdivacky    bool StrictTypeSpelling;
157203955Srdivacky
158203955Srdivacky    StructuralEquivalenceContext(ASTContext &C1, ASTContext &C2,
159203955Srdivacky                                 Diagnostic &Diags,
160203955Srdivacky               llvm::DenseSet<std::pair<Decl *, Decl *> > &NonEquivalentDecls,
161203955Srdivacky                                 bool StrictTypeSpelling = false)
162203955Srdivacky      : C1(C1), C2(C2), Diags(Diags), NonEquivalentDecls(NonEquivalentDecls),
163203955Srdivacky        StrictTypeSpelling(StrictTypeSpelling) { }
164203955Srdivacky
165203955Srdivacky    /// \brief Determine whether the two declarations are structurally
166203955Srdivacky    /// equivalent.
167203955Srdivacky    bool IsStructurallyEquivalent(Decl *D1, Decl *D2);
168203955Srdivacky
169203955Srdivacky    /// \brief Determine whether the two types are structurally equivalent.
170203955Srdivacky    bool IsStructurallyEquivalent(QualType T1, QualType T2);
171203955Srdivacky
172203955Srdivacky  private:
173203955Srdivacky    /// \brief Finish checking all of the structural equivalences.
174203955Srdivacky    ///
175203955Srdivacky    /// \returns true if an error occurred, false otherwise.
176203955Srdivacky    bool Finish();
177203955Srdivacky
178203955Srdivacky  public:
179203955Srdivacky    DiagnosticBuilder Diag1(SourceLocation Loc, unsigned DiagID) {
180203955Srdivacky      return Diags.Report(FullSourceLoc(Loc, C1.getSourceManager()), DiagID);
181203955Srdivacky    }
182203955Srdivacky
183203955Srdivacky    DiagnosticBuilder Diag2(SourceLocation Loc, unsigned DiagID) {
184203955Srdivacky      return Diags.Report(FullSourceLoc(Loc, C2.getSourceManager()), DiagID);
185203955Srdivacky    }
186203955Srdivacky  };
187203955Srdivacky}
188203955Srdivacky
189203955Srdivackystatic bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
190203955Srdivacky                                     QualType T1, QualType T2);
191203955Srdivackystatic bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
192203955Srdivacky                                     Decl *D1, Decl *D2);
193203955Srdivacky
194203955Srdivacky/// \brief Determine if two APInts have the same value, after zero-extending
195203955Srdivacky/// one of them (if needed!) to ensure that the bit-widths match.
196203955Srdivackystatic bool IsSameValue(const llvm::APInt &I1, const llvm::APInt &I2) {
197203955Srdivacky  if (I1.getBitWidth() == I2.getBitWidth())
198203955Srdivacky    return I1 == I2;
199203955Srdivacky
200203955Srdivacky  if (I1.getBitWidth() > I2.getBitWidth())
201203955Srdivacky    return I1 == llvm::APInt(I2).zext(I1.getBitWidth());
202203955Srdivacky
203203955Srdivacky  return llvm::APInt(I1).zext(I2.getBitWidth()) == I2;
204203955Srdivacky}
205203955Srdivacky
206203955Srdivacky/// \brief Determine if two APSInts have the same value, zero- or sign-extending
207203955Srdivacky/// as needed.
208203955Srdivackystatic bool IsSameValue(const llvm::APSInt &I1, const llvm::APSInt &I2) {
209203955Srdivacky  if (I1.getBitWidth() == I2.getBitWidth() && I1.isSigned() == I2.isSigned())
210203955Srdivacky    return I1 == I2;
211203955Srdivacky
212203955Srdivacky  // Check for a bit-width mismatch.
213203955Srdivacky  if (I1.getBitWidth() > I2.getBitWidth())
214203955Srdivacky    return IsSameValue(I1, llvm::APSInt(I2).extend(I1.getBitWidth()));
215203955Srdivacky  else if (I2.getBitWidth() > I1.getBitWidth())
216203955Srdivacky    return IsSameValue(llvm::APSInt(I1).extend(I2.getBitWidth()), I2);
217203955Srdivacky
218203955Srdivacky  // We have a signedness mismatch. Turn the signed value into an unsigned
219203955Srdivacky  // value.
220203955Srdivacky  if (I1.isSigned()) {
221203955Srdivacky    if (I1.isNegative())
222203955Srdivacky      return false;
223203955Srdivacky
224203955Srdivacky    return llvm::APSInt(I1, true) == I2;
225203955Srdivacky  }
226203955Srdivacky
227203955Srdivacky  if (I2.isNegative())
228203955Srdivacky    return false;
229203955Srdivacky
230203955Srdivacky  return I1 == llvm::APSInt(I2, true);
231203955Srdivacky}
232203955Srdivacky
233203955Srdivacky/// \brief Determine structural equivalence of two expressions.
234203955Srdivackystatic bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
235203955Srdivacky                                     Expr *E1, Expr *E2) {
236203955Srdivacky  if (!E1 || !E2)
237203955Srdivacky    return E1 == E2;
238203955Srdivacky
239203955Srdivacky  // FIXME: Actually perform a structural comparison!
240203955Srdivacky  return true;
241203955Srdivacky}
242203955Srdivacky
243203955Srdivacky/// \brief Determine whether two identifiers are equivalent.
244203955Srdivackystatic bool IsStructurallyEquivalent(const IdentifierInfo *Name1,
245203955Srdivacky                                     const IdentifierInfo *Name2) {
246203955Srdivacky  if (!Name1 || !Name2)
247203955Srdivacky    return Name1 == Name2;
248203955Srdivacky
249203955Srdivacky  return Name1->getName() == Name2->getName();
250203955Srdivacky}
251203955Srdivacky
252203955Srdivacky/// \brief Determine whether two nested-name-specifiers are equivalent.
253203955Srdivackystatic bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
254203955Srdivacky                                     NestedNameSpecifier *NNS1,
255203955Srdivacky                                     NestedNameSpecifier *NNS2) {
256203955Srdivacky  // FIXME: Implement!
257203955Srdivacky  return true;
258203955Srdivacky}
259203955Srdivacky
260203955Srdivacky/// \brief Determine whether two template arguments are equivalent.
261203955Srdivackystatic bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
262203955Srdivacky                                     const TemplateArgument &Arg1,
263203955Srdivacky                                     const TemplateArgument &Arg2) {
264203955Srdivacky  // FIXME: Implement!
265203955Srdivacky  return true;
266203955Srdivacky}
267203955Srdivacky
268203955Srdivacky/// \brief Determine structural equivalence for the common part of array
269203955Srdivacky/// types.
270203955Srdivackystatic bool IsArrayStructurallyEquivalent(StructuralEquivalenceContext &Context,
271203955Srdivacky                                          const ArrayType *Array1,
272203955Srdivacky                                          const ArrayType *Array2) {
273203955Srdivacky  if (!IsStructurallyEquivalent(Context,
274203955Srdivacky                                Array1->getElementType(),
275203955Srdivacky                                Array2->getElementType()))
276203955Srdivacky    return false;
277203955Srdivacky  if (Array1->getSizeModifier() != Array2->getSizeModifier())
278203955Srdivacky    return false;
279203955Srdivacky  if (Array1->getIndexTypeQualifiers() != Array2->getIndexTypeQualifiers())
280203955Srdivacky    return false;
281203955Srdivacky
282203955Srdivacky  return true;
283203955Srdivacky}
284203955Srdivacky
285203955Srdivacky/// \brief Determine structural equivalence of two types.
286203955Srdivackystatic bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
287203955Srdivacky                                     QualType T1, QualType T2) {
288203955Srdivacky  if (T1.isNull() || T2.isNull())
289203955Srdivacky    return T1.isNull() && T2.isNull();
290203955Srdivacky
291203955Srdivacky  if (!Context.StrictTypeSpelling) {
292203955Srdivacky    // We aren't being strict about token-to-token equivalence of types,
293203955Srdivacky    // so map down to the canonical type.
294203955Srdivacky    T1 = Context.C1.getCanonicalType(T1);
295203955Srdivacky    T2 = Context.C2.getCanonicalType(T2);
296203955Srdivacky  }
297203955Srdivacky
298203955Srdivacky  if (T1.getQualifiers() != T2.getQualifiers())
299203955Srdivacky    return false;
300203955Srdivacky
301203955Srdivacky  Type::TypeClass TC = T1->getTypeClass();
302203955Srdivacky
303203955Srdivacky  if (T1->getTypeClass() != T2->getTypeClass()) {
304203955Srdivacky    // Compare function types with prototypes vs. without prototypes as if
305203955Srdivacky    // both did not have prototypes.
306203955Srdivacky    if (T1->getTypeClass() == Type::FunctionProto &&
307203955Srdivacky        T2->getTypeClass() == Type::FunctionNoProto)
308203955Srdivacky      TC = Type::FunctionNoProto;
309203955Srdivacky    else if (T1->getTypeClass() == Type::FunctionNoProto &&
310203955Srdivacky             T2->getTypeClass() == Type::FunctionProto)
311203955Srdivacky      TC = Type::FunctionNoProto;
312203955Srdivacky    else
313203955Srdivacky      return false;
314203955Srdivacky  }
315203955Srdivacky
316203955Srdivacky  switch (TC) {
317203955Srdivacky  case Type::Builtin:
318203955Srdivacky    // FIXME: Deal with Char_S/Char_U.
319203955Srdivacky    if (cast<BuiltinType>(T1)->getKind() != cast<BuiltinType>(T2)->getKind())
320203955Srdivacky      return false;
321203955Srdivacky    break;
322203955Srdivacky
323203955Srdivacky  case Type::Complex:
324203955Srdivacky    if (!IsStructurallyEquivalent(Context,
325203955Srdivacky                                  cast<ComplexType>(T1)->getElementType(),
326203955Srdivacky                                  cast<ComplexType>(T2)->getElementType()))
327203955Srdivacky      return false;
328203955Srdivacky    break;
329203955Srdivacky
330203955Srdivacky  case Type::Pointer:
331203955Srdivacky    if (!IsStructurallyEquivalent(Context,
332203955Srdivacky                                  cast<PointerType>(T1)->getPointeeType(),
333203955Srdivacky                                  cast<PointerType>(T2)->getPointeeType()))
334203955Srdivacky      return false;
335203955Srdivacky    break;
336203955Srdivacky
337203955Srdivacky  case Type::BlockPointer:
338203955Srdivacky    if (!IsStructurallyEquivalent(Context,
339203955Srdivacky                                  cast<BlockPointerType>(T1)->getPointeeType(),
340203955Srdivacky                                  cast<BlockPointerType>(T2)->getPointeeType()))
341203955Srdivacky      return false;
342203955Srdivacky    break;
343203955Srdivacky
344203955Srdivacky  case Type::LValueReference:
345203955Srdivacky  case Type::RValueReference: {
346203955Srdivacky    const ReferenceType *Ref1 = cast<ReferenceType>(T1);
347203955Srdivacky    const ReferenceType *Ref2 = cast<ReferenceType>(T2);
348203955Srdivacky    if (Ref1->isSpelledAsLValue() != Ref2->isSpelledAsLValue())
349203955Srdivacky      return false;
350203955Srdivacky    if (Ref1->isInnerRef() != Ref2->isInnerRef())
351203955Srdivacky      return false;
352203955Srdivacky    if (!IsStructurallyEquivalent(Context,
353203955Srdivacky                                  Ref1->getPointeeTypeAsWritten(),
354203955Srdivacky                                  Ref2->getPointeeTypeAsWritten()))
355203955Srdivacky      return false;
356203955Srdivacky    break;
357203955Srdivacky  }
358203955Srdivacky
359203955Srdivacky  case Type::MemberPointer: {
360203955Srdivacky    const MemberPointerType *MemPtr1 = cast<MemberPointerType>(T1);
361203955Srdivacky    const MemberPointerType *MemPtr2 = cast<MemberPointerType>(T2);
362203955Srdivacky    if (!IsStructurallyEquivalent(Context,
363203955Srdivacky                                  MemPtr1->getPointeeType(),
364203955Srdivacky                                  MemPtr2->getPointeeType()))
365203955Srdivacky      return false;
366203955Srdivacky    if (!IsStructurallyEquivalent(Context,
367203955Srdivacky                                  QualType(MemPtr1->getClass(), 0),
368203955Srdivacky                                  QualType(MemPtr2->getClass(), 0)))
369203955Srdivacky      return false;
370203955Srdivacky    break;
371203955Srdivacky  }
372203955Srdivacky
373203955Srdivacky  case Type::ConstantArray: {
374203955Srdivacky    const ConstantArrayType *Array1 = cast<ConstantArrayType>(T1);
375203955Srdivacky    const ConstantArrayType *Array2 = cast<ConstantArrayType>(T2);
376203955Srdivacky    if (!IsSameValue(Array1->getSize(), Array2->getSize()))
377203955Srdivacky      return false;
378203955Srdivacky
379203955Srdivacky    if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
380203955Srdivacky      return false;
381203955Srdivacky    break;
382203955Srdivacky  }
383203955Srdivacky
384203955Srdivacky  case Type::IncompleteArray:
385203955Srdivacky    if (!IsArrayStructurallyEquivalent(Context,
386203955Srdivacky                                       cast<ArrayType>(T1),
387203955Srdivacky                                       cast<ArrayType>(T2)))
388203955Srdivacky      return false;
389203955Srdivacky    break;
390203955Srdivacky
391203955Srdivacky  case Type::VariableArray: {
392203955Srdivacky    const VariableArrayType *Array1 = cast<VariableArrayType>(T1);
393203955Srdivacky    const VariableArrayType *Array2 = cast<VariableArrayType>(T2);
394203955Srdivacky    if (!IsStructurallyEquivalent(Context,
395203955Srdivacky                                  Array1->getSizeExpr(), Array2->getSizeExpr()))
396203955Srdivacky      return false;
397203955Srdivacky
398203955Srdivacky    if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
399203955Srdivacky      return false;
400203955Srdivacky
401203955Srdivacky    break;
402203955Srdivacky  }
403203955Srdivacky
404203955Srdivacky  case Type::DependentSizedArray: {
405203955Srdivacky    const DependentSizedArrayType *Array1 = cast<DependentSizedArrayType>(T1);
406203955Srdivacky    const DependentSizedArrayType *Array2 = cast<DependentSizedArrayType>(T2);
407203955Srdivacky    if (!IsStructurallyEquivalent(Context,
408203955Srdivacky                                  Array1->getSizeExpr(), Array2->getSizeExpr()))
409203955Srdivacky      return false;
410203955Srdivacky
411203955Srdivacky    if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
412203955Srdivacky      return false;
413203955Srdivacky
414203955Srdivacky    break;
415203955Srdivacky  }
416203955Srdivacky
417203955Srdivacky  case Type::DependentSizedExtVector: {
418203955Srdivacky    const DependentSizedExtVectorType *Vec1
419203955Srdivacky      = cast<DependentSizedExtVectorType>(T1);
420203955Srdivacky    const DependentSizedExtVectorType *Vec2
421203955Srdivacky      = cast<DependentSizedExtVectorType>(T2);
422203955Srdivacky    if (!IsStructurallyEquivalent(Context,
423203955Srdivacky                                  Vec1->getSizeExpr(), Vec2->getSizeExpr()))
424203955Srdivacky      return false;
425203955Srdivacky    if (!IsStructurallyEquivalent(Context,
426203955Srdivacky                                  Vec1->getElementType(),
427203955Srdivacky                                  Vec2->getElementType()))
428203955Srdivacky      return false;
429203955Srdivacky    break;
430203955Srdivacky  }
431203955Srdivacky
432203955Srdivacky  case Type::Vector:
433203955Srdivacky  case Type::ExtVector: {
434203955Srdivacky    const VectorType *Vec1 = cast<VectorType>(T1);
435203955Srdivacky    const VectorType *Vec2 = cast<VectorType>(T2);
436203955Srdivacky    if (!IsStructurallyEquivalent(Context,
437203955Srdivacky                                  Vec1->getElementType(),
438203955Srdivacky                                  Vec2->getElementType()))
439203955Srdivacky      return false;
440203955Srdivacky    if (Vec1->getNumElements() != Vec2->getNumElements())
441203955Srdivacky      return false;
442203955Srdivacky    if (Vec1->isAltiVec() != Vec2->isAltiVec())
443203955Srdivacky      return false;
444203955Srdivacky    if (Vec1->isPixel() != Vec2->isPixel())
445203955Srdivacky      return false;
446204643Srdivacky    break;
447203955Srdivacky  }
448203955Srdivacky
449203955Srdivacky  case Type::FunctionProto: {
450203955Srdivacky    const FunctionProtoType *Proto1 = cast<FunctionProtoType>(T1);
451203955Srdivacky    const FunctionProtoType *Proto2 = cast<FunctionProtoType>(T2);
452203955Srdivacky    if (Proto1->getNumArgs() != Proto2->getNumArgs())
453203955Srdivacky      return false;
454203955Srdivacky    for (unsigned I = 0, N = Proto1->getNumArgs(); I != N; ++I) {
455203955Srdivacky      if (!IsStructurallyEquivalent(Context,
456203955Srdivacky                                    Proto1->getArgType(I),
457203955Srdivacky                                    Proto2->getArgType(I)))
458203955Srdivacky        return false;
459203955Srdivacky    }
460203955Srdivacky    if (Proto1->isVariadic() != Proto2->isVariadic())
461203955Srdivacky      return false;
462203955Srdivacky    if (Proto1->hasExceptionSpec() != Proto2->hasExceptionSpec())
463203955Srdivacky      return false;
464203955Srdivacky    if (Proto1->hasAnyExceptionSpec() != Proto2->hasAnyExceptionSpec())
465203955Srdivacky      return false;
466203955Srdivacky    if (Proto1->getNumExceptions() != Proto2->getNumExceptions())
467203955Srdivacky      return false;
468203955Srdivacky    for (unsigned I = 0, N = Proto1->getNumExceptions(); I != N; ++I) {
469203955Srdivacky      if (!IsStructurallyEquivalent(Context,
470203955Srdivacky                                    Proto1->getExceptionType(I),
471203955Srdivacky                                    Proto2->getExceptionType(I)))
472203955Srdivacky        return false;
473203955Srdivacky    }
474203955Srdivacky    if (Proto1->getTypeQuals() != Proto2->getTypeQuals())
475203955Srdivacky      return false;
476203955Srdivacky
477203955Srdivacky    // Fall through to check the bits common with FunctionNoProtoType.
478203955Srdivacky  }
479203955Srdivacky
480203955Srdivacky  case Type::FunctionNoProto: {
481203955Srdivacky    const FunctionType *Function1 = cast<FunctionType>(T1);
482203955Srdivacky    const FunctionType *Function2 = cast<FunctionType>(T2);
483203955Srdivacky    if (!IsStructurallyEquivalent(Context,
484203955Srdivacky                                  Function1->getResultType(),
485203955Srdivacky                                  Function2->getResultType()))
486203955Srdivacky      return false;
487203955Srdivacky    if (Function1->getNoReturnAttr() != Function2->getNoReturnAttr())
488203955Srdivacky      return false;
489203955Srdivacky    if (Function1->getCallConv() != Function2->getCallConv())
490203955Srdivacky      return false;
491203955Srdivacky    break;
492203955Srdivacky  }
493203955Srdivacky
494203955Srdivacky  case Type::UnresolvedUsing:
495203955Srdivacky    if (!IsStructurallyEquivalent(Context,
496203955Srdivacky                                  cast<UnresolvedUsingType>(T1)->getDecl(),
497203955Srdivacky                                  cast<UnresolvedUsingType>(T2)->getDecl()))
498203955Srdivacky      return false;
499203955Srdivacky
500203955Srdivacky    break;
501203955Srdivacky
502203955Srdivacky  case Type::Typedef:
503203955Srdivacky    if (!IsStructurallyEquivalent(Context,
504203955Srdivacky                                  cast<TypedefType>(T1)->getDecl(),
505203955Srdivacky                                  cast<TypedefType>(T2)->getDecl()))
506203955Srdivacky      return false;
507203955Srdivacky    break;
508203955Srdivacky
509203955Srdivacky  case Type::TypeOfExpr:
510203955Srdivacky    if (!IsStructurallyEquivalent(Context,
511203955Srdivacky                                cast<TypeOfExprType>(T1)->getUnderlyingExpr(),
512203955Srdivacky                                cast<TypeOfExprType>(T2)->getUnderlyingExpr()))
513203955Srdivacky      return false;
514203955Srdivacky    break;
515203955Srdivacky
516203955Srdivacky  case Type::TypeOf:
517203955Srdivacky    if (!IsStructurallyEquivalent(Context,
518203955Srdivacky                                  cast<TypeOfType>(T1)->getUnderlyingType(),
519203955Srdivacky                                  cast<TypeOfType>(T2)->getUnderlyingType()))
520203955Srdivacky      return false;
521203955Srdivacky    break;
522203955Srdivacky
523203955Srdivacky  case Type::Decltype:
524203955Srdivacky    if (!IsStructurallyEquivalent(Context,
525203955Srdivacky                                  cast<DecltypeType>(T1)->getUnderlyingExpr(),
526203955Srdivacky                                  cast<DecltypeType>(T2)->getUnderlyingExpr()))
527203955Srdivacky      return false;
528203955Srdivacky    break;
529203955Srdivacky
530203955Srdivacky  case Type::Record:
531203955Srdivacky  case Type::Enum:
532203955Srdivacky    if (!IsStructurallyEquivalent(Context,
533203955Srdivacky                                  cast<TagType>(T1)->getDecl(),
534203955Srdivacky                                  cast<TagType>(T2)->getDecl()))
535203955Srdivacky      return false;
536203955Srdivacky    break;
537203955Srdivacky
538203955Srdivacky  case Type::Elaborated: {
539203955Srdivacky    const ElaboratedType *Elab1 = cast<ElaboratedType>(T1);
540203955Srdivacky    const ElaboratedType *Elab2 = cast<ElaboratedType>(T2);
541203955Srdivacky    if (Elab1->getTagKind() != Elab2->getTagKind())
542203955Srdivacky      return false;
543203955Srdivacky    if (!IsStructurallyEquivalent(Context,
544203955Srdivacky                                  Elab1->getUnderlyingType(),
545203955Srdivacky                                  Elab2->getUnderlyingType()))
546203955Srdivacky      return false;
547203955Srdivacky    break;
548203955Srdivacky  }
549203955Srdivacky
550203955Srdivacky  case Type::TemplateTypeParm: {
551203955Srdivacky    const TemplateTypeParmType *Parm1 = cast<TemplateTypeParmType>(T1);
552203955Srdivacky    const TemplateTypeParmType *Parm2 = cast<TemplateTypeParmType>(T2);
553203955Srdivacky    if (Parm1->getDepth() != Parm2->getDepth())
554203955Srdivacky      return false;
555203955Srdivacky    if (Parm1->getIndex() != Parm2->getIndex())
556203955Srdivacky      return false;
557203955Srdivacky    if (Parm1->isParameterPack() != Parm2->isParameterPack())
558203955Srdivacky      return false;
559203955Srdivacky
560203955Srdivacky    // Names of template type parameters are never significant.
561203955Srdivacky    break;
562203955Srdivacky  }
563203955Srdivacky
564203955Srdivacky  case Type::SubstTemplateTypeParm: {
565203955Srdivacky    const SubstTemplateTypeParmType *Subst1
566203955Srdivacky      = cast<SubstTemplateTypeParmType>(T1);
567203955Srdivacky    const SubstTemplateTypeParmType *Subst2
568203955Srdivacky      = cast<SubstTemplateTypeParmType>(T2);
569203955Srdivacky    if (!IsStructurallyEquivalent(Context,
570203955Srdivacky                                  QualType(Subst1->getReplacedParameter(), 0),
571203955Srdivacky                                  QualType(Subst2->getReplacedParameter(), 0)))
572203955Srdivacky      return false;
573203955Srdivacky    if (!IsStructurallyEquivalent(Context,
574203955Srdivacky                                  Subst1->getReplacementType(),
575203955Srdivacky                                  Subst2->getReplacementType()))
576203955Srdivacky      return false;
577203955Srdivacky    break;
578203955Srdivacky  }
579203955Srdivacky
580203955Srdivacky  case Type::TemplateSpecialization: {
581203955Srdivacky    const TemplateSpecializationType *Spec1
582203955Srdivacky      = cast<TemplateSpecializationType>(T1);
583203955Srdivacky    const TemplateSpecializationType *Spec2
584203955Srdivacky      = cast<TemplateSpecializationType>(T2);
585203955Srdivacky    if (!IsStructurallyEquivalent(Context,
586203955Srdivacky                                  Spec1->getTemplateName(),
587203955Srdivacky                                  Spec2->getTemplateName()))
588203955Srdivacky      return false;
589203955Srdivacky    if (Spec1->getNumArgs() != Spec2->getNumArgs())
590203955Srdivacky      return false;
591203955Srdivacky    for (unsigned I = 0, N = Spec1->getNumArgs(); I != N; ++I) {
592203955Srdivacky      if (!IsStructurallyEquivalent(Context,
593203955Srdivacky                                    Spec1->getArg(I), Spec2->getArg(I)))
594203955Srdivacky        return false;
595203955Srdivacky    }
596203955Srdivacky    break;
597203955Srdivacky  }
598203955Srdivacky
599203955Srdivacky  case Type::QualifiedName: {
600203955Srdivacky    const QualifiedNameType *Qual1 = cast<QualifiedNameType>(T1);
601203955Srdivacky    const QualifiedNameType *Qual2 = cast<QualifiedNameType>(T2);
602203955Srdivacky    if (!IsStructurallyEquivalent(Context,
603203955Srdivacky                                  Qual1->getQualifier(),
604203955Srdivacky                                  Qual2->getQualifier()))
605203955Srdivacky      return false;
606203955Srdivacky    if (!IsStructurallyEquivalent(Context,
607203955Srdivacky                                  Qual1->getNamedType(),
608203955Srdivacky                                  Qual2->getNamedType()))
609203955Srdivacky      return false;
610203955Srdivacky    break;
611203955Srdivacky  }
612203955Srdivacky
613203955Srdivacky  case Type::Typename: {
614203955Srdivacky    const TypenameType *Typename1 = cast<TypenameType>(T1);
615203955Srdivacky    const TypenameType *Typename2 = cast<TypenameType>(T2);
616203955Srdivacky    if (!IsStructurallyEquivalent(Context,
617203955Srdivacky                                  Typename1->getQualifier(),
618203955Srdivacky                                  Typename2->getQualifier()))
619203955Srdivacky      return false;
620203955Srdivacky    if (!IsStructurallyEquivalent(Typename1->getIdentifier(),
621203955Srdivacky                                  Typename2->getIdentifier()))
622203955Srdivacky      return false;
623203955Srdivacky    if (!IsStructurallyEquivalent(Context,
624203955Srdivacky                                  QualType(Typename1->getTemplateId(), 0),
625203955Srdivacky                                  QualType(Typename2->getTemplateId(), 0)))
626203955Srdivacky      return false;
627203955Srdivacky
628203955Srdivacky    break;
629203955Srdivacky  }
630203955Srdivacky
631203955Srdivacky  case Type::ObjCInterface: {
632203955Srdivacky    const ObjCInterfaceType *Iface1 = cast<ObjCInterfaceType>(T1);
633203955Srdivacky    const ObjCInterfaceType *Iface2 = cast<ObjCInterfaceType>(T2);
634203955Srdivacky    if (!IsStructurallyEquivalent(Context,
635203955Srdivacky                                  Iface1->getDecl(), Iface2->getDecl()))
636203955Srdivacky      return false;
637203955Srdivacky    if (Iface1->getNumProtocols() != Iface2->getNumProtocols())
638203955Srdivacky      return false;
639203955Srdivacky    for (unsigned I = 0, N = Iface1->getNumProtocols(); I != N; ++I) {
640203955Srdivacky      if (!IsStructurallyEquivalent(Context,
641203955Srdivacky                                    Iface1->getProtocol(I),
642203955Srdivacky                                    Iface2->getProtocol(I)))
643203955Srdivacky        return false;
644203955Srdivacky    }
645203955Srdivacky    break;
646203955Srdivacky  }
647203955Srdivacky
648203955Srdivacky  case Type::ObjCObjectPointer: {
649203955Srdivacky    const ObjCObjectPointerType *Ptr1 = cast<ObjCObjectPointerType>(T1);
650203955Srdivacky    const ObjCObjectPointerType *Ptr2 = cast<ObjCObjectPointerType>(T2);
651203955Srdivacky    if (!IsStructurallyEquivalent(Context,
652203955Srdivacky                                  Ptr1->getPointeeType(),
653203955Srdivacky                                  Ptr2->getPointeeType()))
654203955Srdivacky      return false;
655203955Srdivacky    if (Ptr1->getNumProtocols() != Ptr2->getNumProtocols())
656203955Srdivacky      return false;
657203955Srdivacky    for (unsigned I = 0, N = Ptr1->getNumProtocols(); I != N; ++I) {
658203955Srdivacky      if (!IsStructurallyEquivalent(Context,
659203955Srdivacky                                    Ptr1->getProtocol(I),
660203955Srdivacky                                    Ptr2->getProtocol(I)))
661203955Srdivacky        return false;
662203955Srdivacky    }
663203955Srdivacky    break;
664203955Srdivacky  }
665203955Srdivacky
666203955Srdivacky  } // end switch
667203955Srdivacky
668203955Srdivacky  return true;
669203955Srdivacky}
670203955Srdivacky
671203955Srdivacky/// \brief Determine structural equivalence of two records.
672203955Srdivackystatic bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
673203955Srdivacky                                     RecordDecl *D1, RecordDecl *D2) {
674203955Srdivacky  if (D1->isUnion() != D2->isUnion()) {
675203955Srdivacky    Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
676203955Srdivacky      << Context.C2.getTypeDeclType(D2);
677203955Srdivacky    Context.Diag1(D1->getLocation(), diag::note_odr_tag_kind_here)
678203955Srdivacky      << D1->getDeclName() << (unsigned)D1->getTagKind();
679203955Srdivacky    return false;
680203955Srdivacky  }
681203955Srdivacky
682203955Srdivacky  // Compare the definitions of these two records. If either or both are
683203955Srdivacky  // incomplete, we assume that they are equivalent.
684203955Srdivacky  D1 = D1->getDefinition();
685203955Srdivacky  D2 = D2->getDefinition();
686203955Srdivacky  if (!D1 || !D2)
687203955Srdivacky    return true;
688203955Srdivacky
689203955Srdivacky  if (CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(D1)) {
690203955Srdivacky    if (CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(D2)) {
691203955Srdivacky      if (D1CXX->getNumBases() != D2CXX->getNumBases()) {
692203955Srdivacky        Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
693203955Srdivacky        << Context.C2.getTypeDeclType(D2);
694203955Srdivacky        Context.Diag2(D2->getLocation(), diag::note_odr_number_of_bases)
695203955Srdivacky        << D2CXX->getNumBases();
696203955Srdivacky        Context.Diag1(D1->getLocation(), diag::note_odr_number_of_bases)
697203955Srdivacky        << D1CXX->getNumBases();
698203955Srdivacky        return false;
699203955Srdivacky      }
700203955Srdivacky
701203955Srdivacky      // Check the base classes.
702203955Srdivacky      for (CXXRecordDecl::base_class_iterator Base1 = D1CXX->bases_begin(),
703203955Srdivacky                                           BaseEnd1 = D1CXX->bases_end(),
704203955Srdivacky                                                Base2 = D2CXX->bases_begin();
705203955Srdivacky           Base1 != BaseEnd1;
706203955Srdivacky           ++Base1, ++Base2) {
707203955Srdivacky        if (!IsStructurallyEquivalent(Context,
708203955Srdivacky                                      Base1->getType(), Base2->getType())) {
709203955Srdivacky          Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
710203955Srdivacky            << Context.C2.getTypeDeclType(D2);
711203955Srdivacky          Context.Diag2(Base2->getSourceRange().getBegin(), diag::note_odr_base)
712203955Srdivacky            << Base2->getType()
713203955Srdivacky            << Base2->getSourceRange();
714203955Srdivacky          Context.Diag1(Base1->getSourceRange().getBegin(), diag::note_odr_base)
715203955Srdivacky            << Base1->getType()
716203955Srdivacky            << Base1->getSourceRange();
717203955Srdivacky          return false;
718203955Srdivacky        }
719203955Srdivacky
720203955Srdivacky        // Check virtual vs. non-virtual inheritance mismatch.
721203955Srdivacky        if (Base1->isVirtual() != Base2->isVirtual()) {
722203955Srdivacky          Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
723203955Srdivacky            << Context.C2.getTypeDeclType(D2);
724203955Srdivacky          Context.Diag2(Base2->getSourceRange().getBegin(),
725203955Srdivacky                        diag::note_odr_virtual_base)
726203955Srdivacky            << Base2->isVirtual() << Base2->getSourceRange();
727203955Srdivacky          Context.Diag1(Base1->getSourceRange().getBegin(), diag::note_odr_base)
728203955Srdivacky            << Base1->isVirtual()
729203955Srdivacky            << Base1->getSourceRange();
730203955Srdivacky          return false;
731203955Srdivacky        }
732203955Srdivacky      }
733203955Srdivacky    } else if (D1CXX->getNumBases() > 0) {
734203955Srdivacky      Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
735203955Srdivacky        << Context.C2.getTypeDeclType(D2);
736203955Srdivacky      const CXXBaseSpecifier *Base1 = D1CXX->bases_begin();
737203955Srdivacky      Context.Diag1(Base1->getSourceRange().getBegin(), diag::note_odr_base)
738203955Srdivacky        << Base1->getType()
739203955Srdivacky        << Base1->getSourceRange();
740203955Srdivacky      Context.Diag2(D2->getLocation(), diag::note_odr_missing_base);
741203955Srdivacky      return false;
742203955Srdivacky    }
743203955Srdivacky  }
744203955Srdivacky
745203955Srdivacky  // Check the fields for consistency.
746203955Srdivacky  CXXRecordDecl::field_iterator Field2 = D2->field_begin(),
747203955Srdivacky                             Field2End = D2->field_end();
748203955Srdivacky  for (CXXRecordDecl::field_iterator Field1 = D1->field_begin(),
749203955Srdivacky                                  Field1End = D1->field_end();
750203955Srdivacky       Field1 != Field1End;
751203955Srdivacky       ++Field1, ++Field2) {
752203955Srdivacky    if (Field2 == Field2End) {
753203955Srdivacky      Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
754203955Srdivacky        << Context.C2.getTypeDeclType(D2);
755203955Srdivacky      Context.Diag1(Field1->getLocation(), diag::note_odr_field)
756203955Srdivacky        << Field1->getDeclName() << Field1->getType();
757203955Srdivacky      Context.Diag2(D2->getLocation(), diag::note_odr_missing_field);
758203955Srdivacky      return false;
759203955Srdivacky    }
760203955Srdivacky
761203955Srdivacky    if (!IsStructurallyEquivalent(Context,
762203955Srdivacky                                  Field1->getType(), Field2->getType())) {
763203955Srdivacky      Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
764203955Srdivacky        << Context.C2.getTypeDeclType(D2);
765203955Srdivacky      Context.Diag2(Field2->getLocation(), diag::note_odr_field)
766203955Srdivacky        << Field2->getDeclName() << Field2->getType();
767203955Srdivacky      Context.Diag1(Field1->getLocation(), diag::note_odr_field)
768203955Srdivacky        << Field1->getDeclName() << Field1->getType();
769203955Srdivacky      return false;
770203955Srdivacky    }
771203955Srdivacky
772203955Srdivacky    if (Field1->isBitField() != Field2->isBitField()) {
773203955Srdivacky      Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
774203955Srdivacky        << Context.C2.getTypeDeclType(D2);
775203955Srdivacky      if (Field1->isBitField()) {
776203955Srdivacky        llvm::APSInt Bits;
777203955Srdivacky        Field1->getBitWidth()->isIntegerConstantExpr(Bits, Context.C1);
778203955Srdivacky        Context.Diag1(Field1->getLocation(), diag::note_odr_bit_field)
779203955Srdivacky          << Field1->getDeclName() << Field1->getType()
780203955Srdivacky          << Bits.toString(10, false);
781203955Srdivacky        Context.Diag2(Field2->getLocation(), diag::note_odr_not_bit_field)
782203955Srdivacky          << Field2->getDeclName();
783203955Srdivacky      } else {
784203955Srdivacky        llvm::APSInt Bits;
785203955Srdivacky        Field2->getBitWidth()->isIntegerConstantExpr(Bits, Context.C2);
786203955Srdivacky        Context.Diag2(Field2->getLocation(), diag::note_odr_bit_field)
787203955Srdivacky          << Field2->getDeclName() << Field2->getType()
788203955Srdivacky          << Bits.toString(10, false);
789203955Srdivacky        Context.Diag1(Field1->getLocation(),
790203955Srdivacky                          diag::note_odr_not_bit_field)
791203955Srdivacky        << Field1->getDeclName();
792203955Srdivacky      }
793203955Srdivacky      return false;
794203955Srdivacky    }
795203955Srdivacky
796203955Srdivacky    if (Field1->isBitField()) {
797203955Srdivacky      // Make sure that the bit-fields are the same length.
798203955Srdivacky      llvm::APSInt Bits1, Bits2;
799203955Srdivacky      if (!Field1->getBitWidth()->isIntegerConstantExpr(Bits1, Context.C1))
800203955Srdivacky        return false;
801203955Srdivacky      if (!Field2->getBitWidth()->isIntegerConstantExpr(Bits2, Context.C2))
802203955Srdivacky        return false;
803203955Srdivacky
804203955Srdivacky      if (!IsSameValue(Bits1, Bits2)) {
805203955Srdivacky        Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
806203955Srdivacky          << Context.C2.getTypeDeclType(D2);
807203955Srdivacky        Context.Diag2(Field2->getLocation(), diag::note_odr_bit_field)
808203955Srdivacky          << Field2->getDeclName() << Field2->getType()
809203955Srdivacky          << Bits2.toString(10, false);
810203955Srdivacky        Context.Diag1(Field1->getLocation(), diag::note_odr_bit_field)
811203955Srdivacky          << Field1->getDeclName() << Field1->getType()
812203955Srdivacky          << Bits1.toString(10, false);
813203955Srdivacky        return false;
814203955Srdivacky      }
815203955Srdivacky    }
816203955Srdivacky  }
817203955Srdivacky
818203955Srdivacky  if (Field2 != Field2End) {
819203955Srdivacky    Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
820203955Srdivacky      << Context.C2.getTypeDeclType(D2);
821203955Srdivacky    Context.Diag2(Field2->getLocation(), diag::note_odr_field)
822203955Srdivacky      << Field2->getDeclName() << Field2->getType();
823203955Srdivacky    Context.Diag1(D1->getLocation(), diag::note_odr_missing_field);
824203955Srdivacky    return false;
825203955Srdivacky  }
826203955Srdivacky
827203955Srdivacky  return true;
828203955Srdivacky}
829203955Srdivacky
830203955Srdivacky/// \brief Determine structural equivalence of two enums.
831203955Srdivackystatic bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
832203955Srdivacky                                     EnumDecl *D1, EnumDecl *D2) {
833203955Srdivacky  EnumDecl::enumerator_iterator EC2 = D2->enumerator_begin(),
834203955Srdivacky                             EC2End = D2->enumerator_end();
835203955Srdivacky  for (EnumDecl::enumerator_iterator EC1 = D1->enumerator_begin(),
836203955Srdivacky                                  EC1End = D1->enumerator_end();
837203955Srdivacky       EC1 != EC1End; ++EC1, ++EC2) {
838203955Srdivacky    if (EC2 == EC2End) {
839203955Srdivacky      Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
840203955Srdivacky        << Context.C2.getTypeDeclType(D2);
841203955Srdivacky      Context.Diag1(EC1->getLocation(), diag::note_odr_enumerator)
842203955Srdivacky        << EC1->getDeclName()
843203955Srdivacky        << EC1->getInitVal().toString(10);
844203955Srdivacky      Context.Diag2(D2->getLocation(), diag::note_odr_missing_enumerator);
845203955Srdivacky      return false;
846203955Srdivacky    }
847203955Srdivacky
848203955Srdivacky    llvm::APSInt Val1 = EC1->getInitVal();
849203955Srdivacky    llvm::APSInt Val2 = EC2->getInitVal();
850203955Srdivacky    if (!IsSameValue(Val1, Val2) ||
851203955Srdivacky        !IsStructurallyEquivalent(EC1->getIdentifier(), EC2->getIdentifier())) {
852203955Srdivacky      Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
853203955Srdivacky        << Context.C2.getTypeDeclType(D2);
854203955Srdivacky      Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
855203955Srdivacky        << EC2->getDeclName()
856203955Srdivacky        << EC2->getInitVal().toString(10);
857203955Srdivacky      Context.Diag1(EC1->getLocation(), diag::note_odr_enumerator)
858203955Srdivacky        << EC1->getDeclName()
859203955Srdivacky        << EC1->getInitVal().toString(10);
860203955Srdivacky      return false;
861203955Srdivacky    }
862203955Srdivacky  }
863203955Srdivacky
864203955Srdivacky  if (EC2 != EC2End) {
865203955Srdivacky    Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
866203955Srdivacky      << Context.C2.getTypeDeclType(D2);
867203955Srdivacky    Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
868203955Srdivacky      << EC2->getDeclName()
869203955Srdivacky      << EC2->getInitVal().toString(10);
870203955Srdivacky    Context.Diag1(D1->getLocation(), diag::note_odr_missing_enumerator);
871203955Srdivacky    return false;
872203955Srdivacky  }
873203955Srdivacky
874203955Srdivacky  return true;
875203955Srdivacky}
876203955Srdivacky
877203955Srdivacky/// \brief Determine structural equivalence of two declarations.
878203955Srdivackystatic bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
879203955Srdivacky                                     Decl *D1, Decl *D2) {
880203955Srdivacky  // FIXME: Check for known structural equivalences via a callback of some sort.
881203955Srdivacky
882203955Srdivacky  // Check whether we already know that these two declarations are not
883203955Srdivacky  // structurally equivalent.
884203955Srdivacky  if (Context.NonEquivalentDecls.count(std::make_pair(D1->getCanonicalDecl(),
885203955Srdivacky                                                      D2->getCanonicalDecl())))
886203955Srdivacky    return false;
887203955Srdivacky
888203955Srdivacky  // Determine whether we've already produced a tentative equivalence for D1.
889203955Srdivacky  Decl *&EquivToD1 = Context.TentativeEquivalences[D1->getCanonicalDecl()];
890203955Srdivacky  if (EquivToD1)
891203955Srdivacky    return EquivToD1 == D2->getCanonicalDecl();
892203955Srdivacky
893203955Srdivacky  // Produce a tentative equivalence D1 <-> D2, which will be checked later.
894203955Srdivacky  EquivToD1 = D2->getCanonicalDecl();
895203955Srdivacky  Context.DeclsToCheck.push_back(D1->getCanonicalDecl());
896203955Srdivacky  return true;
897203955Srdivacky}
898203955Srdivacky
899203955Srdivackybool StructuralEquivalenceContext::IsStructurallyEquivalent(Decl *D1,
900203955Srdivacky                                                            Decl *D2) {
901203955Srdivacky  if (!::IsStructurallyEquivalent(*this, D1, D2))
902203955Srdivacky    return false;
903203955Srdivacky
904203955Srdivacky  return !Finish();
905203955Srdivacky}
906203955Srdivacky
907203955Srdivackybool StructuralEquivalenceContext::IsStructurallyEquivalent(QualType T1,
908203955Srdivacky                                                            QualType T2) {
909203955Srdivacky  if (!::IsStructurallyEquivalent(*this, T1, T2))
910203955Srdivacky    return false;
911203955Srdivacky
912203955Srdivacky  return !Finish();
913203955Srdivacky}
914203955Srdivacky
915203955Srdivackybool StructuralEquivalenceContext::Finish() {
916203955Srdivacky  while (!DeclsToCheck.empty()) {
917203955Srdivacky    // Check the next declaration.
918203955Srdivacky    Decl *D1 = DeclsToCheck.front();
919203955Srdivacky    DeclsToCheck.pop_front();
920203955Srdivacky
921203955Srdivacky    Decl *D2 = TentativeEquivalences[D1];
922203955Srdivacky    assert(D2 && "Unrecorded tentative equivalence?");
923203955Srdivacky
924203955Srdivacky    bool Equivalent = true;
925203955Srdivacky
926203955Srdivacky    // FIXME: Switch on all declaration kinds. For now, we're just going to
927203955Srdivacky    // check the obvious ones.
928203955Srdivacky    if (RecordDecl *Record1 = dyn_cast<RecordDecl>(D1)) {
929203955Srdivacky      if (RecordDecl *Record2 = dyn_cast<RecordDecl>(D2)) {
930203955Srdivacky        // Check for equivalent structure names.
931203955Srdivacky        IdentifierInfo *Name1 = Record1->getIdentifier();
932203955Srdivacky        if (!Name1 && Record1->getTypedefForAnonDecl())
933203955Srdivacky          Name1 = Record1->getTypedefForAnonDecl()->getIdentifier();
934203955Srdivacky        IdentifierInfo *Name2 = Record2->getIdentifier();
935203955Srdivacky        if (!Name2 && Record2->getTypedefForAnonDecl())
936203955Srdivacky          Name2 = Record2->getTypedefForAnonDecl()->getIdentifier();
937203955Srdivacky        if (!::IsStructurallyEquivalent(Name1, Name2) ||
938203955Srdivacky            !::IsStructurallyEquivalent(*this, Record1, Record2))
939203955Srdivacky          Equivalent = false;
940203955Srdivacky      } else {
941203955Srdivacky        // Record/non-record mismatch.
942203955Srdivacky        Equivalent = false;
943203955Srdivacky      }
944203955Srdivacky    } else if (EnumDecl *Enum1 = dyn_cast<EnumDecl>(D1)) {
945203955Srdivacky      if (EnumDecl *Enum2 = dyn_cast<EnumDecl>(D2)) {
946203955Srdivacky        // Check for equivalent enum names.
947203955Srdivacky        IdentifierInfo *Name1 = Enum1->getIdentifier();
948203955Srdivacky        if (!Name1 && Enum1->getTypedefForAnonDecl())
949203955Srdivacky          Name1 = Enum1->getTypedefForAnonDecl()->getIdentifier();
950203955Srdivacky        IdentifierInfo *Name2 = Enum2->getIdentifier();
951203955Srdivacky        if (!Name2 && Enum2->getTypedefForAnonDecl())
952203955Srdivacky          Name2 = Enum2->getTypedefForAnonDecl()->getIdentifier();
953203955Srdivacky        if (!::IsStructurallyEquivalent(Name1, Name2) ||
954203955Srdivacky            !::IsStructurallyEquivalent(*this, Enum1, Enum2))
955203955Srdivacky          Equivalent = false;
956203955Srdivacky      } else {
957203955Srdivacky        // Enum/non-enum mismatch
958203955Srdivacky        Equivalent = false;
959203955Srdivacky      }
960203955Srdivacky    } else if (TypedefDecl *Typedef1 = dyn_cast<TypedefDecl>(D1)) {
961203955Srdivacky      if (TypedefDecl *Typedef2 = dyn_cast<TypedefDecl>(D2)) {
962203955Srdivacky        if (!::IsStructurallyEquivalent(Typedef1->getIdentifier(),
963203955Srdivacky                                        Typedef2->getIdentifier()) ||
964203955Srdivacky            !::IsStructurallyEquivalent(*this,
965203955Srdivacky                                        Typedef1->getUnderlyingType(),
966203955Srdivacky                                        Typedef2->getUnderlyingType()))
967203955Srdivacky          Equivalent = false;
968203955Srdivacky      } else {
969203955Srdivacky        // Typedef/non-typedef mismatch.
970203955Srdivacky        Equivalent = false;
971203955Srdivacky      }
972203955Srdivacky    }
973203955Srdivacky
974203955Srdivacky    if (!Equivalent) {
975203955Srdivacky      // Note that these two declarations are not equivalent (and we already
976203955Srdivacky      // know about it).
977203955Srdivacky      NonEquivalentDecls.insert(std::make_pair(D1->getCanonicalDecl(),
978203955Srdivacky                                               D2->getCanonicalDecl()));
979203955Srdivacky      return true;
980203955Srdivacky    }
981203955Srdivacky    // FIXME: Check other declaration kinds!
982203955Srdivacky  }
983203955Srdivacky
984203955Srdivacky  return false;
985203955Srdivacky}
986203955Srdivacky
987203955Srdivacky//----------------------------------------------------------------------------
988203955Srdivacky// Import Types
989203955Srdivacky//----------------------------------------------------------------------------
990203955Srdivacky
991203955SrdivackyQualType ASTNodeImporter::VisitType(Type *T) {
992203955Srdivacky  Importer.FromDiag(SourceLocation(), diag::err_unsupported_ast_node)
993203955Srdivacky    << T->getTypeClassName();
994203955Srdivacky  return QualType();
995203955Srdivacky}
996203955Srdivacky
997203955SrdivackyQualType ASTNodeImporter::VisitBuiltinType(BuiltinType *T) {
998203955Srdivacky  switch (T->getKind()) {
999203955Srdivacky  case BuiltinType::Void: return Importer.getToContext().VoidTy;
1000203955Srdivacky  case BuiltinType::Bool: return Importer.getToContext().BoolTy;
1001203955Srdivacky
1002203955Srdivacky  case BuiltinType::Char_U:
1003203955Srdivacky    // The context we're importing from has an unsigned 'char'. If we're
1004203955Srdivacky    // importing into a context with a signed 'char', translate to
1005203955Srdivacky    // 'unsigned char' instead.
1006203955Srdivacky    if (Importer.getToContext().getLangOptions().CharIsSigned)
1007203955Srdivacky      return Importer.getToContext().UnsignedCharTy;
1008203955Srdivacky
1009203955Srdivacky    return Importer.getToContext().CharTy;
1010203955Srdivacky
1011203955Srdivacky  case BuiltinType::UChar: return Importer.getToContext().UnsignedCharTy;
1012203955Srdivacky
1013203955Srdivacky  case BuiltinType::Char16:
1014203955Srdivacky    // FIXME: Make sure that the "to" context supports C++!
1015203955Srdivacky    return Importer.getToContext().Char16Ty;
1016203955Srdivacky
1017203955Srdivacky  case BuiltinType::Char32:
1018203955Srdivacky    // FIXME: Make sure that the "to" context supports C++!
1019203955Srdivacky    return Importer.getToContext().Char32Ty;
1020203955Srdivacky
1021203955Srdivacky  case BuiltinType::UShort: return Importer.getToContext().UnsignedShortTy;
1022203955Srdivacky  case BuiltinType::UInt: return Importer.getToContext().UnsignedIntTy;
1023203955Srdivacky  case BuiltinType::ULong: return Importer.getToContext().UnsignedLongTy;
1024203955Srdivacky  case BuiltinType::ULongLong:
1025203955Srdivacky    return Importer.getToContext().UnsignedLongLongTy;
1026203955Srdivacky  case BuiltinType::UInt128: return Importer.getToContext().UnsignedInt128Ty;
1027203955Srdivacky
1028203955Srdivacky  case BuiltinType::Char_S:
1029203955Srdivacky    // The context we're importing from has an unsigned 'char'. If we're
1030203955Srdivacky    // importing into a context with a signed 'char', translate to
1031203955Srdivacky    // 'unsigned char' instead.
1032203955Srdivacky    if (!Importer.getToContext().getLangOptions().CharIsSigned)
1033203955Srdivacky      return Importer.getToContext().SignedCharTy;
1034203955Srdivacky
1035203955Srdivacky    return Importer.getToContext().CharTy;
1036203955Srdivacky
1037203955Srdivacky  case BuiltinType::SChar: return Importer.getToContext().SignedCharTy;
1038203955Srdivacky  case BuiltinType::WChar:
1039203955Srdivacky    // FIXME: If not in C++, shall we translate to the C equivalent of
1040203955Srdivacky    // wchar_t?
1041203955Srdivacky    return Importer.getToContext().WCharTy;
1042203955Srdivacky
1043203955Srdivacky  case BuiltinType::Short : return Importer.getToContext().ShortTy;
1044203955Srdivacky  case BuiltinType::Int : return Importer.getToContext().IntTy;
1045203955Srdivacky  case BuiltinType::Long : return Importer.getToContext().LongTy;
1046203955Srdivacky  case BuiltinType::LongLong : return Importer.getToContext().LongLongTy;
1047203955Srdivacky  case BuiltinType::Int128 : return Importer.getToContext().Int128Ty;
1048203955Srdivacky  case BuiltinType::Float: return Importer.getToContext().FloatTy;
1049203955Srdivacky  case BuiltinType::Double: return Importer.getToContext().DoubleTy;
1050203955Srdivacky  case BuiltinType::LongDouble: return Importer.getToContext().LongDoubleTy;
1051203955Srdivacky
1052203955Srdivacky  case BuiltinType::NullPtr:
1053203955Srdivacky    // FIXME: Make sure that the "to" context supports C++0x!
1054203955Srdivacky    return Importer.getToContext().NullPtrTy;
1055203955Srdivacky
1056203955Srdivacky  case BuiltinType::Overload: return Importer.getToContext().OverloadTy;
1057203955Srdivacky  case BuiltinType::Dependent: return Importer.getToContext().DependentTy;
1058203955Srdivacky  case BuiltinType::UndeducedAuto:
1059203955Srdivacky    // FIXME: Make sure that the "to" context supports C++0x!
1060203955Srdivacky    return Importer.getToContext().UndeducedAutoTy;
1061203955Srdivacky
1062203955Srdivacky  case BuiltinType::ObjCId:
1063203955Srdivacky    // FIXME: Make sure that the "to" context supports Objective-C!
1064203955Srdivacky    return Importer.getToContext().ObjCBuiltinIdTy;
1065203955Srdivacky
1066203955Srdivacky  case BuiltinType::ObjCClass:
1067203955Srdivacky    return Importer.getToContext().ObjCBuiltinClassTy;
1068203955Srdivacky
1069203955Srdivacky  case BuiltinType::ObjCSel:
1070203955Srdivacky    return Importer.getToContext().ObjCBuiltinSelTy;
1071203955Srdivacky  }
1072203955Srdivacky
1073203955Srdivacky  return QualType();
1074203955Srdivacky}
1075203955Srdivacky
1076203955SrdivackyQualType ASTNodeImporter::VisitComplexType(ComplexType *T) {
1077203955Srdivacky  QualType ToElementType = Importer.Import(T->getElementType());
1078203955Srdivacky  if (ToElementType.isNull())
1079203955Srdivacky    return QualType();
1080203955Srdivacky
1081203955Srdivacky  return Importer.getToContext().getComplexType(ToElementType);
1082203955Srdivacky}
1083203955Srdivacky
1084203955SrdivackyQualType ASTNodeImporter::VisitPointerType(PointerType *T) {
1085203955Srdivacky  QualType ToPointeeType = Importer.Import(T->getPointeeType());
1086203955Srdivacky  if (ToPointeeType.isNull())
1087203955Srdivacky    return QualType();
1088203955Srdivacky
1089203955Srdivacky  return Importer.getToContext().getPointerType(ToPointeeType);
1090203955Srdivacky}
1091203955Srdivacky
1092203955SrdivackyQualType ASTNodeImporter::VisitBlockPointerType(BlockPointerType *T) {
1093203955Srdivacky  // FIXME: Check for blocks support in "to" context.
1094203955Srdivacky  QualType ToPointeeType = Importer.Import(T->getPointeeType());
1095203955Srdivacky  if (ToPointeeType.isNull())
1096203955Srdivacky    return QualType();
1097203955Srdivacky
1098203955Srdivacky  return Importer.getToContext().getBlockPointerType(ToPointeeType);
1099203955Srdivacky}
1100203955Srdivacky
1101203955SrdivackyQualType ASTNodeImporter::VisitLValueReferenceType(LValueReferenceType *T) {
1102203955Srdivacky  // FIXME: Check for C++ support in "to" context.
1103203955Srdivacky  QualType ToPointeeType = Importer.Import(T->getPointeeTypeAsWritten());
1104203955Srdivacky  if (ToPointeeType.isNull())
1105203955Srdivacky    return QualType();
1106203955Srdivacky
1107203955Srdivacky  return Importer.getToContext().getLValueReferenceType(ToPointeeType);
1108203955Srdivacky}
1109203955Srdivacky
1110203955SrdivackyQualType ASTNodeImporter::VisitRValueReferenceType(RValueReferenceType *T) {
1111203955Srdivacky  // FIXME: Check for C++0x support in "to" context.
1112203955Srdivacky  QualType ToPointeeType = Importer.Import(T->getPointeeTypeAsWritten());
1113203955Srdivacky  if (ToPointeeType.isNull())
1114203955Srdivacky    return QualType();
1115203955Srdivacky
1116203955Srdivacky  return Importer.getToContext().getRValueReferenceType(ToPointeeType);
1117203955Srdivacky}
1118203955Srdivacky
1119203955SrdivackyQualType ASTNodeImporter::VisitMemberPointerType(MemberPointerType *T) {
1120203955Srdivacky  // FIXME: Check for C++ support in "to" context.
1121203955Srdivacky  QualType ToPointeeType = Importer.Import(T->getPointeeType());
1122203955Srdivacky  if (ToPointeeType.isNull())
1123203955Srdivacky    return QualType();
1124203955Srdivacky
1125203955Srdivacky  QualType ClassType = Importer.Import(QualType(T->getClass(), 0));
1126203955Srdivacky  return Importer.getToContext().getMemberPointerType(ToPointeeType,
1127203955Srdivacky                                                      ClassType.getTypePtr());
1128203955Srdivacky}
1129203955Srdivacky
1130203955SrdivackyQualType ASTNodeImporter::VisitConstantArrayType(ConstantArrayType *T) {
1131203955Srdivacky  QualType ToElementType = Importer.Import(T->getElementType());
1132203955Srdivacky  if (ToElementType.isNull())
1133203955Srdivacky    return QualType();
1134203955Srdivacky
1135203955Srdivacky  return Importer.getToContext().getConstantArrayType(ToElementType,
1136203955Srdivacky                                                      T->getSize(),
1137203955Srdivacky                                                      T->getSizeModifier(),
1138203955Srdivacky                                               T->getIndexTypeCVRQualifiers());
1139203955Srdivacky}
1140203955Srdivacky
1141203955SrdivackyQualType ASTNodeImporter::VisitIncompleteArrayType(IncompleteArrayType *T) {
1142203955Srdivacky  QualType ToElementType = Importer.Import(T->getElementType());
1143203955Srdivacky  if (ToElementType.isNull())
1144203955Srdivacky    return QualType();
1145203955Srdivacky
1146203955Srdivacky  return Importer.getToContext().getIncompleteArrayType(ToElementType,
1147203955Srdivacky                                                        T->getSizeModifier(),
1148203955Srdivacky                                                T->getIndexTypeCVRQualifiers());
1149203955Srdivacky}
1150203955Srdivacky
1151203955SrdivackyQualType ASTNodeImporter::VisitVariableArrayType(VariableArrayType *T) {
1152203955Srdivacky  QualType ToElementType = Importer.Import(T->getElementType());
1153203955Srdivacky  if (ToElementType.isNull())
1154203955Srdivacky    return QualType();
1155203955Srdivacky
1156203955Srdivacky  Expr *Size = Importer.Import(T->getSizeExpr());
1157203955Srdivacky  if (!Size)
1158203955Srdivacky    return QualType();
1159203955Srdivacky
1160203955Srdivacky  SourceRange Brackets = Importer.Import(T->getBracketsRange());
1161203955Srdivacky  return Importer.getToContext().getVariableArrayType(ToElementType, Size,
1162203955Srdivacky                                                      T->getSizeModifier(),
1163203955Srdivacky                                                T->getIndexTypeCVRQualifiers(),
1164203955Srdivacky                                                      Brackets);
1165203955Srdivacky}
1166203955Srdivacky
1167203955SrdivackyQualType ASTNodeImporter::VisitVectorType(VectorType *T) {
1168203955Srdivacky  QualType ToElementType = Importer.Import(T->getElementType());
1169203955Srdivacky  if (ToElementType.isNull())
1170203955Srdivacky    return QualType();
1171203955Srdivacky
1172203955Srdivacky  return Importer.getToContext().getVectorType(ToElementType,
1173203955Srdivacky                                               T->getNumElements(),
1174203955Srdivacky                                               T->isAltiVec(),
1175203955Srdivacky                                               T->isPixel());
1176203955Srdivacky}
1177203955Srdivacky
1178203955SrdivackyQualType ASTNodeImporter::VisitExtVectorType(ExtVectorType *T) {
1179203955Srdivacky  QualType ToElementType = Importer.Import(T->getElementType());
1180203955Srdivacky  if (ToElementType.isNull())
1181203955Srdivacky    return QualType();
1182203955Srdivacky
1183203955Srdivacky  return Importer.getToContext().getExtVectorType(ToElementType,
1184203955Srdivacky                                                  T->getNumElements());
1185203955Srdivacky}
1186203955Srdivacky
1187203955SrdivackyQualType ASTNodeImporter::VisitFunctionNoProtoType(FunctionNoProtoType *T) {
1188203955Srdivacky  // FIXME: What happens if we're importing a function without a prototype
1189203955Srdivacky  // into C++? Should we make it variadic?
1190203955Srdivacky  QualType ToResultType = Importer.Import(T->getResultType());
1191203955Srdivacky  if (ToResultType.isNull())
1192203955Srdivacky    return QualType();
1193203955Srdivacky
1194203955Srdivacky  return Importer.getToContext().getFunctionNoProtoType(ToResultType,
1195203955Srdivacky                                                        T->getNoReturnAttr(),
1196203955Srdivacky                                                        T->getCallConv());
1197203955Srdivacky}
1198203955Srdivacky
1199203955SrdivackyQualType ASTNodeImporter::VisitFunctionProtoType(FunctionProtoType *T) {
1200203955Srdivacky  QualType ToResultType = Importer.Import(T->getResultType());
1201203955Srdivacky  if (ToResultType.isNull())
1202203955Srdivacky    return QualType();
1203203955Srdivacky
1204203955Srdivacky  // Import argument types
1205203955Srdivacky  llvm::SmallVector<QualType, 4> ArgTypes;
1206203955Srdivacky  for (FunctionProtoType::arg_type_iterator A = T->arg_type_begin(),
1207203955Srdivacky                                         AEnd = T->arg_type_end();
1208203955Srdivacky       A != AEnd; ++A) {
1209203955Srdivacky    QualType ArgType = Importer.Import(*A);
1210203955Srdivacky    if (ArgType.isNull())
1211203955Srdivacky      return QualType();
1212203955Srdivacky    ArgTypes.push_back(ArgType);
1213203955Srdivacky  }
1214203955Srdivacky
1215203955Srdivacky  // Import exception types
1216203955Srdivacky  llvm::SmallVector<QualType, 4> ExceptionTypes;
1217203955Srdivacky  for (FunctionProtoType::exception_iterator E = T->exception_begin(),
1218203955Srdivacky                                          EEnd = T->exception_end();
1219203955Srdivacky       E != EEnd; ++E) {
1220203955Srdivacky    QualType ExceptionType = Importer.Import(*E);
1221203955Srdivacky    if (ExceptionType.isNull())
1222203955Srdivacky      return QualType();
1223203955Srdivacky    ExceptionTypes.push_back(ExceptionType);
1224203955Srdivacky  }
1225203955Srdivacky
1226203955Srdivacky  return Importer.getToContext().getFunctionType(ToResultType, ArgTypes.data(),
1227203955Srdivacky                                                 ArgTypes.size(),
1228203955Srdivacky                                                 T->isVariadic(),
1229203955Srdivacky                                                 T->getTypeQuals(),
1230203955Srdivacky                                                 T->hasExceptionSpec(),
1231203955Srdivacky                                                 T->hasAnyExceptionSpec(),
1232203955Srdivacky                                                 ExceptionTypes.size(),
1233203955Srdivacky                                                 ExceptionTypes.data(),
1234203955Srdivacky                                                 T->getNoReturnAttr(),
1235203955Srdivacky                                                 T->getCallConv());
1236203955Srdivacky}
1237203955Srdivacky
1238203955SrdivackyQualType ASTNodeImporter::VisitTypedefType(TypedefType *T) {
1239203955Srdivacky  TypedefDecl *ToDecl
1240203955Srdivacky                 = dyn_cast_or_null<TypedefDecl>(Importer.Import(T->getDecl()));
1241203955Srdivacky  if (!ToDecl)
1242203955Srdivacky    return QualType();
1243203955Srdivacky
1244203955Srdivacky  return Importer.getToContext().getTypeDeclType(ToDecl);
1245203955Srdivacky}
1246203955Srdivacky
1247203955SrdivackyQualType ASTNodeImporter::VisitTypeOfExprType(TypeOfExprType *T) {
1248203955Srdivacky  Expr *ToExpr = Importer.Import(T->getUnderlyingExpr());
1249203955Srdivacky  if (!ToExpr)
1250203955Srdivacky    return QualType();
1251203955Srdivacky
1252203955Srdivacky  return Importer.getToContext().getTypeOfExprType(ToExpr);
1253203955Srdivacky}
1254203955Srdivacky
1255203955SrdivackyQualType ASTNodeImporter::VisitTypeOfType(TypeOfType *T) {
1256203955Srdivacky  QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType());
1257203955Srdivacky  if (ToUnderlyingType.isNull())
1258203955Srdivacky    return QualType();
1259203955Srdivacky
1260203955Srdivacky  return Importer.getToContext().getTypeOfType(ToUnderlyingType);
1261203955Srdivacky}
1262203955Srdivacky
1263203955SrdivackyQualType ASTNodeImporter::VisitDecltypeType(DecltypeType *T) {
1264203955Srdivacky  Expr *ToExpr = Importer.Import(T->getUnderlyingExpr());
1265203955Srdivacky  if (!ToExpr)
1266203955Srdivacky    return QualType();
1267203955Srdivacky
1268203955Srdivacky  return Importer.getToContext().getDecltypeType(ToExpr);
1269203955Srdivacky}
1270203955Srdivacky
1271203955SrdivackyQualType ASTNodeImporter::VisitRecordType(RecordType *T) {
1272203955Srdivacky  RecordDecl *ToDecl
1273203955Srdivacky    = dyn_cast_or_null<RecordDecl>(Importer.Import(T->getDecl()));
1274203955Srdivacky  if (!ToDecl)
1275203955Srdivacky    return QualType();
1276203955Srdivacky
1277203955Srdivacky  return Importer.getToContext().getTagDeclType(ToDecl);
1278203955Srdivacky}
1279203955Srdivacky
1280203955SrdivackyQualType ASTNodeImporter::VisitEnumType(EnumType *T) {
1281203955Srdivacky  EnumDecl *ToDecl
1282203955Srdivacky    = dyn_cast_or_null<EnumDecl>(Importer.Import(T->getDecl()));
1283203955Srdivacky  if (!ToDecl)
1284203955Srdivacky    return QualType();
1285203955Srdivacky
1286203955Srdivacky  return Importer.getToContext().getTagDeclType(ToDecl);
1287203955Srdivacky}
1288203955Srdivacky
1289203955SrdivackyQualType ASTNodeImporter::VisitElaboratedType(ElaboratedType *T) {
1290203955Srdivacky  QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType());
1291203955Srdivacky  if (ToUnderlyingType.isNull())
1292203955Srdivacky    return QualType();
1293203955Srdivacky
1294203955Srdivacky  return Importer.getToContext().getElaboratedType(ToUnderlyingType,
1295203955Srdivacky                                                   T->getTagKind());
1296203955Srdivacky}
1297203955Srdivacky
1298203955SrdivackyQualType ASTNodeImporter::VisitQualifiedNameType(QualifiedNameType *T) {
1299203955Srdivacky  NestedNameSpecifier *ToQualifier = Importer.Import(T->getQualifier());
1300203955Srdivacky  if (!ToQualifier)
1301203955Srdivacky    return QualType();
1302203955Srdivacky
1303203955Srdivacky  QualType ToNamedType = Importer.Import(T->getNamedType());
1304203955Srdivacky  if (ToNamedType.isNull())
1305203955Srdivacky    return QualType();
1306203955Srdivacky
1307203955Srdivacky  return Importer.getToContext().getQualifiedNameType(ToQualifier, ToNamedType);
1308203955Srdivacky}
1309203955Srdivacky
1310203955SrdivackyQualType ASTNodeImporter::VisitObjCInterfaceType(ObjCInterfaceType *T) {
1311203955Srdivacky  ObjCInterfaceDecl *Class
1312203955Srdivacky    = dyn_cast_or_null<ObjCInterfaceDecl>(Importer.Import(T->getDecl()));
1313203955Srdivacky  if (!Class)
1314203955Srdivacky    return QualType();
1315203955Srdivacky
1316203955Srdivacky  llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
1317203955Srdivacky  for (ObjCInterfaceType::qual_iterator P = T->qual_begin(),
1318203955Srdivacky                                     PEnd = T->qual_end();
1319203955Srdivacky       P != PEnd; ++P) {
1320203955Srdivacky    ObjCProtocolDecl *Protocol
1321203955Srdivacky      = dyn_cast_or_null<ObjCProtocolDecl>(Importer.Import(*P));
1322203955Srdivacky    if (!Protocol)
1323203955Srdivacky      return QualType();
1324203955Srdivacky    Protocols.push_back(Protocol);
1325203955Srdivacky  }
1326203955Srdivacky
1327203955Srdivacky  return Importer.getToContext().getObjCInterfaceType(Class,
1328203955Srdivacky                                                      Protocols.data(),
1329203955Srdivacky                                                      Protocols.size());
1330203955Srdivacky}
1331203955Srdivacky
1332203955SrdivackyQualType ASTNodeImporter::VisitObjCObjectPointerType(ObjCObjectPointerType *T) {
1333203955Srdivacky  QualType ToPointeeType = Importer.Import(T->getPointeeType());
1334203955Srdivacky  if (ToPointeeType.isNull())
1335203955Srdivacky    return QualType();
1336203955Srdivacky
1337203955Srdivacky  llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
1338203955Srdivacky  for (ObjCObjectPointerType::qual_iterator P = T->qual_begin(),
1339203955Srdivacky                                         PEnd = T->qual_end();
1340203955Srdivacky       P != PEnd; ++P) {
1341203955Srdivacky    ObjCProtocolDecl *Protocol
1342203955Srdivacky      = dyn_cast_or_null<ObjCProtocolDecl>(Importer.Import(*P));
1343203955Srdivacky    if (!Protocol)
1344203955Srdivacky      return QualType();
1345203955Srdivacky    Protocols.push_back(Protocol);
1346203955Srdivacky  }
1347203955Srdivacky
1348203955Srdivacky  return Importer.getToContext().getObjCObjectPointerType(ToPointeeType,
1349203955Srdivacky                                                          Protocols.data(),
1350203955Srdivacky                                                          Protocols.size());
1351203955Srdivacky}
1352203955Srdivacky
1353203955Srdivacky//----------------------------------------------------------------------------
1354203955Srdivacky// Import Declarations
1355203955Srdivacky//----------------------------------------------------------------------------
1356203955Srdivackybool ASTNodeImporter::ImportDeclParts(NamedDecl *D, DeclContext *&DC,
1357203955Srdivacky                                      DeclContext *&LexicalDC,
1358203955Srdivacky                                      DeclarationName &Name,
1359203955Srdivacky                                      SourceLocation &Loc) {
1360203955Srdivacky  // Import the context of this declaration.
1361203955Srdivacky  DC = Importer.ImportContext(D->getDeclContext());
1362203955Srdivacky  if (!DC)
1363203955Srdivacky    return true;
1364203955Srdivacky
1365203955Srdivacky  LexicalDC = DC;
1366203955Srdivacky  if (D->getDeclContext() != D->getLexicalDeclContext()) {
1367203955Srdivacky    LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
1368203955Srdivacky    if (!LexicalDC)
1369203955Srdivacky      return true;
1370203955Srdivacky  }
1371203955Srdivacky
1372203955Srdivacky  // Import the name of this declaration.
1373203955Srdivacky  Name = Importer.Import(D->getDeclName());
1374203955Srdivacky  if (D->getDeclName() && !Name)
1375203955Srdivacky    return true;
1376203955Srdivacky
1377203955Srdivacky  // Import the location of this declaration.
1378203955Srdivacky  Loc = Importer.Import(D->getLocation());
1379203955Srdivacky  return false;
1380203955Srdivacky}
1381203955Srdivacky
1382204643Srdivackyvoid ASTNodeImporter::ImportDeclContext(DeclContext *FromDC) {
1383204643Srdivacky  for (DeclContext::decl_iterator From = FromDC->decls_begin(),
1384204643Srdivacky                               FromEnd = FromDC->decls_end();
1385204643Srdivacky       From != FromEnd;
1386204643Srdivacky       ++From)
1387204643Srdivacky    Importer.Import(*From);
1388204643Srdivacky}
1389204643Srdivacky
1390203955Srdivackybool ASTNodeImporter::IsStructuralMatch(RecordDecl *FromRecord,
1391203955Srdivacky                                        RecordDecl *ToRecord) {
1392204643Srdivacky  StructuralEquivalenceContext Ctx(Importer.getFromContext(),
1393203955Srdivacky                                   Importer.getToContext(),
1394203955Srdivacky                                   Importer.getDiags(),
1395203955Srdivacky                                   Importer.getNonEquivalentDecls());
1396204643Srdivacky  return Ctx.IsStructurallyEquivalent(FromRecord, ToRecord);
1397203955Srdivacky}
1398203955Srdivacky
1399203955Srdivackybool ASTNodeImporter::IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToEnum) {
1400204643Srdivacky  StructuralEquivalenceContext Ctx(Importer.getFromContext(),
1401203955Srdivacky                                   Importer.getToContext(),
1402203955Srdivacky                                   Importer.getDiags(),
1403203955Srdivacky                                   Importer.getNonEquivalentDecls());
1404204643Srdivacky  return Ctx.IsStructurallyEquivalent(FromEnum, ToEnum);
1405203955Srdivacky}
1406203955Srdivacky
1407203955SrdivackyDecl *ASTNodeImporter::VisitDecl(Decl *D) {
1408203955Srdivacky  Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node)
1409203955Srdivacky    << D->getDeclKindName();
1410203955Srdivacky  return 0;
1411203955Srdivacky}
1412203955Srdivacky
1413204643SrdivackyDecl *ASTNodeImporter::VisitNamespaceDecl(NamespaceDecl *D) {
1414204643Srdivacky  // Import the major distinguishing characteristics of this namespace.
1415204643Srdivacky  DeclContext *DC, *LexicalDC;
1416204643Srdivacky  DeclarationName Name;
1417204643Srdivacky  SourceLocation Loc;
1418204643Srdivacky  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
1419204643Srdivacky    return 0;
1420204643Srdivacky
1421204643Srdivacky  NamespaceDecl *MergeWithNamespace = 0;
1422204643Srdivacky  if (!Name) {
1423204643Srdivacky    // This is an anonymous namespace. Adopt an existing anonymous
1424204643Srdivacky    // namespace if we can.
1425204643Srdivacky    // FIXME: Not testable.
1426204643Srdivacky    if (TranslationUnitDecl *TU = dyn_cast<TranslationUnitDecl>(DC))
1427204643Srdivacky      MergeWithNamespace = TU->getAnonymousNamespace();
1428204643Srdivacky    else
1429204643Srdivacky      MergeWithNamespace = cast<NamespaceDecl>(DC)->getAnonymousNamespace();
1430204643Srdivacky  } else {
1431204643Srdivacky    llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
1432204643Srdivacky    for (DeclContext::lookup_result Lookup = DC->lookup(Name);
1433204643Srdivacky         Lookup.first != Lookup.second;
1434204643Srdivacky         ++Lookup.first) {
1435204643Srdivacky      if (!(*Lookup.first)->isInIdentifierNamespace(Decl::IDNS_Ordinary))
1436204643Srdivacky        continue;
1437204643Srdivacky
1438204643Srdivacky      if (NamespaceDecl *FoundNS = dyn_cast<NamespaceDecl>(*Lookup.first)) {
1439204643Srdivacky        MergeWithNamespace = FoundNS;
1440204643Srdivacky        ConflictingDecls.clear();
1441204643Srdivacky        break;
1442204643Srdivacky      }
1443204643Srdivacky
1444204643Srdivacky      ConflictingDecls.push_back(*Lookup.first);
1445204643Srdivacky    }
1446204643Srdivacky
1447204643Srdivacky    if (!ConflictingDecls.empty()) {
1448204643Srdivacky      Name = Importer.HandleNameConflict(Name, DC, Decl::IDNS_Ordinary,
1449204643Srdivacky                                         ConflictingDecls.data(),
1450204643Srdivacky                                         ConflictingDecls.size());
1451204643Srdivacky    }
1452204643Srdivacky  }
1453204643Srdivacky
1454204643Srdivacky  // Create the "to" namespace, if needed.
1455204643Srdivacky  NamespaceDecl *ToNamespace = MergeWithNamespace;
1456204643Srdivacky  if (!ToNamespace) {
1457204643Srdivacky    ToNamespace = NamespaceDecl::Create(Importer.getToContext(), DC, Loc,
1458204643Srdivacky                                        Name.getAsIdentifierInfo());
1459204643Srdivacky    ToNamespace->setLexicalDeclContext(LexicalDC);
1460204643Srdivacky    LexicalDC->addDecl(ToNamespace);
1461204643Srdivacky
1462204643Srdivacky    // If this is an anonymous namespace, register it as the anonymous
1463204643Srdivacky    // namespace within its context.
1464204643Srdivacky    if (!Name) {
1465204643Srdivacky      if (TranslationUnitDecl *TU = dyn_cast<TranslationUnitDecl>(DC))
1466204643Srdivacky        TU->setAnonymousNamespace(ToNamespace);
1467204643Srdivacky      else
1468204643Srdivacky        cast<NamespaceDecl>(DC)->setAnonymousNamespace(ToNamespace);
1469204643Srdivacky    }
1470204643Srdivacky  }
1471204643Srdivacky  Importer.Imported(D, ToNamespace);
1472204643Srdivacky
1473204643Srdivacky  ImportDeclContext(D);
1474204643Srdivacky
1475204643Srdivacky  return ToNamespace;
1476204643Srdivacky}
1477204643Srdivacky
1478203955SrdivackyDecl *ASTNodeImporter::VisitTypedefDecl(TypedefDecl *D) {
1479203955Srdivacky  // Import the major distinguishing characteristics of this typedef.
1480203955Srdivacky  DeclContext *DC, *LexicalDC;
1481203955Srdivacky  DeclarationName Name;
1482203955Srdivacky  SourceLocation Loc;
1483203955Srdivacky  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
1484203955Srdivacky    return 0;
1485203955Srdivacky
1486203955Srdivacky  // If this typedef is not in block scope, determine whether we've
1487203955Srdivacky  // seen a typedef with the same name (that we can merge with) or any
1488203955Srdivacky  // other entity by that name (which name lookup could conflict with).
1489203955Srdivacky  if (!DC->isFunctionOrMethod()) {
1490203955Srdivacky    llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
1491203955Srdivacky    unsigned IDNS = Decl::IDNS_Ordinary;
1492203955Srdivacky    for (DeclContext::lookup_result Lookup = DC->lookup(Name);
1493203955Srdivacky         Lookup.first != Lookup.second;
1494203955Srdivacky         ++Lookup.first) {
1495203955Srdivacky      if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
1496203955Srdivacky        continue;
1497203955Srdivacky      if (TypedefDecl *FoundTypedef = dyn_cast<TypedefDecl>(*Lookup.first)) {
1498203955Srdivacky        if (Importer.IsStructurallyEquivalent(D->getUnderlyingType(),
1499203955Srdivacky                                            FoundTypedef->getUnderlyingType()))
1500203955Srdivacky          return Importer.Imported(D, FoundTypedef);
1501203955Srdivacky      }
1502203955Srdivacky
1503203955Srdivacky      ConflictingDecls.push_back(*Lookup.first);
1504203955Srdivacky    }
1505203955Srdivacky
1506203955Srdivacky    if (!ConflictingDecls.empty()) {
1507203955Srdivacky      Name = Importer.HandleNameConflict(Name, DC, IDNS,
1508203955Srdivacky                                         ConflictingDecls.data(),
1509203955Srdivacky                                         ConflictingDecls.size());
1510203955Srdivacky      if (!Name)
1511203955Srdivacky        return 0;
1512203955Srdivacky    }
1513203955Srdivacky  }
1514203955Srdivacky
1515203955Srdivacky  // Import the underlying type of this typedef;
1516203955Srdivacky  QualType T = Importer.Import(D->getUnderlyingType());
1517203955Srdivacky  if (T.isNull())
1518203955Srdivacky    return 0;
1519203955Srdivacky
1520203955Srdivacky  // Create the new typedef node.
1521203955Srdivacky  TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
1522203955Srdivacky  TypedefDecl *ToTypedef = TypedefDecl::Create(Importer.getToContext(), DC,
1523203955Srdivacky                                               Loc, Name.getAsIdentifierInfo(),
1524203955Srdivacky                                               TInfo);
1525204643Srdivacky  ToTypedef->setAccess(D->getAccess());
1526203955Srdivacky  ToTypedef->setLexicalDeclContext(LexicalDC);
1527203955Srdivacky  Importer.Imported(D, ToTypedef);
1528203955Srdivacky  LexicalDC->addDecl(ToTypedef);
1529203955Srdivacky
1530203955Srdivacky  return ToTypedef;
1531203955Srdivacky}
1532203955Srdivacky
1533203955SrdivackyDecl *ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
1534203955Srdivacky  // Import the major distinguishing characteristics of this enum.
1535203955Srdivacky  DeclContext *DC, *LexicalDC;
1536203955Srdivacky  DeclarationName Name;
1537203955Srdivacky  SourceLocation Loc;
1538203955Srdivacky  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
1539203955Srdivacky    return 0;
1540203955Srdivacky
1541203955Srdivacky  // Figure out what enum name we're looking for.
1542203955Srdivacky  unsigned IDNS = Decl::IDNS_Tag;
1543203955Srdivacky  DeclarationName SearchName = Name;
1544203955Srdivacky  if (!SearchName && D->getTypedefForAnonDecl()) {
1545203955Srdivacky    SearchName = Importer.Import(D->getTypedefForAnonDecl()->getDeclName());
1546203955Srdivacky    IDNS = Decl::IDNS_Ordinary;
1547203955Srdivacky  } else if (Importer.getToContext().getLangOptions().CPlusPlus)
1548203955Srdivacky    IDNS |= Decl::IDNS_Ordinary;
1549203955Srdivacky
1550203955Srdivacky  // We may already have an enum of the same name; try to find and match it.
1551203955Srdivacky  if (!DC->isFunctionOrMethod() && SearchName) {
1552203955Srdivacky    llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
1553203955Srdivacky    for (DeclContext::lookup_result Lookup = DC->lookup(Name);
1554203955Srdivacky         Lookup.first != Lookup.second;
1555203955Srdivacky         ++Lookup.first) {
1556203955Srdivacky      if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
1557203955Srdivacky        continue;
1558203955Srdivacky
1559203955Srdivacky      Decl *Found = *Lookup.first;
1560203955Srdivacky      if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(Found)) {
1561203955Srdivacky        if (const TagType *Tag = Typedef->getUnderlyingType()->getAs<TagType>())
1562203955Srdivacky          Found = Tag->getDecl();
1563203955Srdivacky      }
1564203955Srdivacky
1565203955Srdivacky      if (EnumDecl *FoundEnum = dyn_cast<EnumDecl>(Found)) {
1566203955Srdivacky        if (IsStructuralMatch(D, FoundEnum))
1567203955Srdivacky          return Importer.Imported(D, FoundEnum);
1568203955Srdivacky      }
1569203955Srdivacky
1570203955Srdivacky      ConflictingDecls.push_back(*Lookup.first);
1571203955Srdivacky    }
1572203955Srdivacky
1573203955Srdivacky    if (!ConflictingDecls.empty()) {
1574203955Srdivacky      Name = Importer.HandleNameConflict(Name, DC, IDNS,
1575203955Srdivacky                                         ConflictingDecls.data(),
1576203955Srdivacky                                         ConflictingDecls.size());
1577203955Srdivacky    }
1578203955Srdivacky  }
1579203955Srdivacky
1580203955Srdivacky  // Create the enum declaration.
1581203955Srdivacky  EnumDecl *D2 = EnumDecl::Create(Importer.getToContext(), DC, Loc,
1582203955Srdivacky                                      Name.getAsIdentifierInfo(),
1583203955Srdivacky                                      Importer.Import(D->getTagKeywordLoc()),
1584203955Srdivacky                                      0);
1585204643Srdivacky  D2->setAccess(D->getAccess());
1586203955Srdivacky  D2->setLexicalDeclContext(LexicalDC);
1587203955Srdivacky  Importer.Imported(D, D2);
1588203955Srdivacky  LexicalDC->addDecl(D2);
1589203955Srdivacky
1590203955Srdivacky  // Import the integer type.
1591203955Srdivacky  QualType ToIntegerType = Importer.Import(D->getIntegerType());
1592203955Srdivacky  if (ToIntegerType.isNull())
1593203955Srdivacky    return 0;
1594203955Srdivacky  D2->setIntegerType(ToIntegerType);
1595203955Srdivacky
1596203955Srdivacky  // Import the definition
1597203955Srdivacky  if (D->isDefinition()) {
1598203955Srdivacky    QualType T = Importer.Import(Importer.getFromContext().getTypeDeclType(D));
1599203955Srdivacky    if (T.isNull())
1600203955Srdivacky      return 0;
1601203955Srdivacky
1602203955Srdivacky    QualType ToPromotionType = Importer.Import(D->getPromotionType());
1603203955Srdivacky    if (ToPromotionType.isNull())
1604203955Srdivacky      return 0;
1605203955Srdivacky
1606203955Srdivacky    D2->startDefinition();
1607204643Srdivacky    ImportDeclContext(D);
1608203955Srdivacky    D2->completeDefinition(T, ToPromotionType);
1609203955Srdivacky  }
1610203955Srdivacky
1611203955Srdivacky  return D2;
1612203955Srdivacky}
1613203955Srdivacky
1614203955SrdivackyDecl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
1615203955Srdivacky  // If this record has a definition in the translation unit we're coming from,
1616203955Srdivacky  // but this particular declaration is not that definition, import the
1617203955Srdivacky  // definition and map to that.
1618203955Srdivacky  TagDecl *Definition = D->getDefinition();
1619203955Srdivacky  if (Definition && Definition != D) {
1620203955Srdivacky    Decl *ImportedDef = Importer.Import(Definition);
1621203955Srdivacky    if (!ImportedDef)
1622203955Srdivacky      return 0;
1623203955Srdivacky
1624203955Srdivacky    return Importer.Imported(D, ImportedDef);
1625203955Srdivacky  }
1626203955Srdivacky
1627203955Srdivacky  // Import the major distinguishing characteristics of this record.
1628203955Srdivacky  DeclContext *DC, *LexicalDC;
1629203955Srdivacky  DeclarationName Name;
1630203955Srdivacky  SourceLocation Loc;
1631203955Srdivacky  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
1632203955Srdivacky    return 0;
1633203955Srdivacky
1634203955Srdivacky  // Figure out what structure name we're looking for.
1635203955Srdivacky  unsigned IDNS = Decl::IDNS_Tag;
1636203955Srdivacky  DeclarationName SearchName = Name;
1637203955Srdivacky  if (!SearchName && D->getTypedefForAnonDecl()) {
1638203955Srdivacky    SearchName = Importer.Import(D->getTypedefForAnonDecl()->getDeclName());
1639203955Srdivacky    IDNS = Decl::IDNS_Ordinary;
1640203955Srdivacky  } else if (Importer.getToContext().getLangOptions().CPlusPlus)
1641203955Srdivacky    IDNS |= Decl::IDNS_Ordinary;
1642203955Srdivacky
1643203955Srdivacky  // We may already have a record of the same name; try to find and match it.
1644203955Srdivacky  RecordDecl *AdoptDecl = 0;
1645203955Srdivacky  if (!DC->isFunctionOrMethod() && SearchName) {
1646203955Srdivacky    llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
1647203955Srdivacky    for (DeclContext::lookup_result Lookup = DC->lookup(Name);
1648203955Srdivacky         Lookup.first != Lookup.second;
1649203955Srdivacky         ++Lookup.first) {
1650203955Srdivacky      if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
1651203955Srdivacky        continue;
1652203955Srdivacky
1653203955Srdivacky      Decl *Found = *Lookup.first;
1654203955Srdivacky      if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(Found)) {
1655203955Srdivacky        if (const TagType *Tag = Typedef->getUnderlyingType()->getAs<TagType>())
1656203955Srdivacky          Found = Tag->getDecl();
1657203955Srdivacky      }
1658203955Srdivacky
1659203955Srdivacky      if (RecordDecl *FoundRecord = dyn_cast<RecordDecl>(Found)) {
1660203955Srdivacky        if (RecordDecl *FoundDef = FoundRecord->getDefinition()) {
1661203955Srdivacky          if (!D->isDefinition() || IsStructuralMatch(D, FoundDef)) {
1662203955Srdivacky            // The record types structurally match, or the "from" translation
1663203955Srdivacky            // unit only had a forward declaration anyway; call it the same
1664203955Srdivacky            // function.
1665203955Srdivacky            // FIXME: For C++, we should also merge methods here.
1666203955Srdivacky            return Importer.Imported(D, FoundDef);
1667203955Srdivacky          }
1668203955Srdivacky        } else {
1669203955Srdivacky          // We have a forward declaration of this type, so adopt that forward
1670203955Srdivacky          // declaration rather than building a new one.
1671203955Srdivacky          AdoptDecl = FoundRecord;
1672203955Srdivacky          continue;
1673203955Srdivacky        }
1674203955Srdivacky      }
1675203955Srdivacky
1676203955Srdivacky      ConflictingDecls.push_back(*Lookup.first);
1677203955Srdivacky    }
1678203955Srdivacky
1679203955Srdivacky    if (!ConflictingDecls.empty()) {
1680203955Srdivacky      Name = Importer.HandleNameConflict(Name, DC, IDNS,
1681203955Srdivacky                                         ConflictingDecls.data(),
1682203955Srdivacky                                         ConflictingDecls.size());
1683203955Srdivacky    }
1684203955Srdivacky  }
1685203955Srdivacky
1686203955Srdivacky  // Create the record declaration.
1687203955Srdivacky  RecordDecl *D2 = AdoptDecl;
1688203955Srdivacky  if (!D2) {
1689203955Srdivacky    if (CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(D)) {
1690203955Srdivacky      CXXRecordDecl *D2CXX = CXXRecordDecl::Create(Importer.getToContext(),
1691203955Srdivacky                                                   D->getTagKind(),
1692203955Srdivacky                                                   DC, Loc,
1693203955Srdivacky                                                   Name.getAsIdentifierInfo(),
1694203955Srdivacky                                        Importer.Import(D->getTagKeywordLoc()));
1695203955Srdivacky      D2 = D2CXX;
1696204643Srdivacky      D2->setAccess(D->getAccess());
1697203955Srdivacky
1698203955Srdivacky      if (D->isDefinition()) {
1699203955Srdivacky        // Add base classes.
1700203955Srdivacky        llvm::SmallVector<CXXBaseSpecifier *, 4> Bases;
1701203955Srdivacky        for (CXXRecordDecl::base_class_iterator
1702203955Srdivacky                  Base1 = D1CXX->bases_begin(),
1703203955Srdivacky               FromBaseEnd = D1CXX->bases_end();
1704203955Srdivacky             Base1 != FromBaseEnd;
1705203955Srdivacky             ++Base1) {
1706203955Srdivacky          QualType T = Importer.Import(Base1->getType());
1707203955Srdivacky          if (T.isNull())
1708203955Srdivacky            return 0;
1709203955Srdivacky
1710203955Srdivacky          Bases.push_back(
1711203955Srdivacky            new (Importer.getToContext())
1712203955Srdivacky                  CXXBaseSpecifier(Importer.Import(Base1->getSourceRange()),
1713203955Srdivacky                                   Base1->isVirtual(),
1714203955Srdivacky                                   Base1->isBaseOfClass(),
1715203955Srdivacky                                   Base1->getAccessSpecifierAsWritten(),
1716203955Srdivacky                                   T));
1717203955Srdivacky        }
1718203955Srdivacky        if (!Bases.empty())
1719203955Srdivacky          D2CXX->setBases(Bases.data(), Bases.size());
1720203955Srdivacky      }
1721203955Srdivacky    } else {
1722203955Srdivacky      D2 = RecordDecl::Create(Importer.getToContext(), D->getTagKind(),
1723203955Srdivacky                                    DC, Loc,
1724203955Srdivacky                                    Name.getAsIdentifierInfo(),
1725203955Srdivacky                                    Importer.Import(D->getTagKeywordLoc()));
1726203955Srdivacky    }
1727203955Srdivacky    D2->setLexicalDeclContext(LexicalDC);
1728203955Srdivacky    LexicalDC->addDecl(D2);
1729203955Srdivacky  }
1730203955Srdivacky
1731203955Srdivacky  Importer.Imported(D, D2);
1732203955Srdivacky
1733203955Srdivacky  if (D->isDefinition()) {
1734203955Srdivacky    D2->startDefinition();
1735204643Srdivacky    ImportDeclContext(D);
1736203955Srdivacky    D2->completeDefinition();
1737203955Srdivacky  }
1738203955Srdivacky
1739203955Srdivacky  return D2;
1740203955Srdivacky}
1741203955Srdivacky
1742203955SrdivackyDecl *ASTNodeImporter::VisitEnumConstantDecl(EnumConstantDecl *D) {
1743203955Srdivacky  // Import the major distinguishing characteristics of this enumerator.
1744203955Srdivacky  DeclContext *DC, *LexicalDC;
1745203955Srdivacky  DeclarationName Name;
1746203955Srdivacky  SourceLocation Loc;
1747203955Srdivacky  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
1748203955Srdivacky    return 0;
1749203955Srdivacky
1750203955Srdivacky  QualType T = Importer.Import(D->getType());
1751203955Srdivacky  if (T.isNull())
1752203955Srdivacky    return 0;
1753203955Srdivacky
1754203955Srdivacky  // Determine whether there are any other declarations with the same name and
1755203955Srdivacky  // in the same context.
1756203955Srdivacky  if (!LexicalDC->isFunctionOrMethod()) {
1757203955Srdivacky    llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
1758203955Srdivacky    unsigned IDNS = Decl::IDNS_Ordinary;
1759203955Srdivacky    for (DeclContext::lookup_result Lookup = DC->lookup(Name);
1760203955Srdivacky         Lookup.first != Lookup.second;
1761203955Srdivacky         ++Lookup.first) {
1762203955Srdivacky      if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
1763203955Srdivacky        continue;
1764203955Srdivacky
1765203955Srdivacky      ConflictingDecls.push_back(*Lookup.first);
1766203955Srdivacky    }
1767203955Srdivacky
1768203955Srdivacky    if (!ConflictingDecls.empty()) {
1769203955Srdivacky      Name = Importer.HandleNameConflict(Name, DC, IDNS,
1770203955Srdivacky                                         ConflictingDecls.data(),
1771203955Srdivacky                                         ConflictingDecls.size());
1772203955Srdivacky      if (!Name)
1773203955Srdivacky        return 0;
1774203955Srdivacky    }
1775203955Srdivacky  }
1776203955Srdivacky
1777203955Srdivacky  Expr *Init = Importer.Import(D->getInitExpr());
1778203955Srdivacky  if (D->getInitExpr() && !Init)
1779203955Srdivacky    return 0;
1780203955Srdivacky
1781203955Srdivacky  EnumConstantDecl *ToEnumerator
1782203955Srdivacky    = EnumConstantDecl::Create(Importer.getToContext(), cast<EnumDecl>(DC), Loc,
1783203955Srdivacky                               Name.getAsIdentifierInfo(), T,
1784203955Srdivacky                               Init, D->getInitVal());
1785204643Srdivacky  ToEnumerator->setAccess(D->getAccess());
1786203955Srdivacky  ToEnumerator->setLexicalDeclContext(LexicalDC);
1787203955Srdivacky  Importer.Imported(D, ToEnumerator);
1788203955Srdivacky  LexicalDC->addDecl(ToEnumerator);
1789203955Srdivacky  return ToEnumerator;
1790203955Srdivacky}
1791203955Srdivacky
1792203955SrdivackyDecl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
1793203955Srdivacky  // Import the major distinguishing characteristics of this function.
1794203955Srdivacky  DeclContext *DC, *LexicalDC;
1795203955Srdivacky  DeclarationName Name;
1796203955Srdivacky  SourceLocation Loc;
1797203955Srdivacky  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
1798203955Srdivacky    return 0;
1799203955Srdivacky
1800203955Srdivacky  // Try to find a function in our own ("to") context with the same name, same
1801203955Srdivacky  // type, and in the same context as the function we're importing.
1802203955Srdivacky  if (!LexicalDC->isFunctionOrMethod()) {
1803203955Srdivacky    llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
1804203955Srdivacky    unsigned IDNS = Decl::IDNS_Ordinary;
1805203955Srdivacky    for (DeclContext::lookup_result Lookup = DC->lookup(Name);
1806203955Srdivacky         Lookup.first != Lookup.second;
1807203955Srdivacky         ++Lookup.first) {
1808203955Srdivacky      if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
1809203955Srdivacky        continue;
1810203955Srdivacky
1811203955Srdivacky      if (FunctionDecl *FoundFunction = dyn_cast<FunctionDecl>(*Lookup.first)) {
1812203955Srdivacky        if (isExternalLinkage(FoundFunction->getLinkage()) &&
1813203955Srdivacky            isExternalLinkage(D->getLinkage())) {
1814203955Srdivacky          if (Importer.IsStructurallyEquivalent(D->getType(),
1815203955Srdivacky                                                FoundFunction->getType())) {
1816203955Srdivacky            // FIXME: Actually try to merge the body and other attributes.
1817203955Srdivacky            return Importer.Imported(D, FoundFunction);
1818203955Srdivacky          }
1819203955Srdivacky
1820203955Srdivacky          // FIXME: Check for overloading more carefully, e.g., by boosting
1821203955Srdivacky          // Sema::IsOverload out to the AST library.
1822203955Srdivacky
1823203955Srdivacky          // Function overloading is okay in C++.
1824203955Srdivacky          if (Importer.getToContext().getLangOptions().CPlusPlus)
1825203955Srdivacky            continue;
1826203955Srdivacky
1827203955Srdivacky          // Complain about inconsistent function types.
1828203955Srdivacky          Importer.ToDiag(Loc, diag::err_odr_function_type_inconsistent)
1829203955Srdivacky            << Name << D->getType() << FoundFunction->getType();
1830203955Srdivacky          Importer.ToDiag(FoundFunction->getLocation(),
1831203955Srdivacky                          diag::note_odr_value_here)
1832203955Srdivacky            << FoundFunction->getType();
1833203955Srdivacky        }
1834203955Srdivacky      }
1835203955Srdivacky
1836203955Srdivacky      ConflictingDecls.push_back(*Lookup.first);
1837203955Srdivacky    }
1838203955Srdivacky
1839203955Srdivacky    if (!ConflictingDecls.empty()) {
1840203955Srdivacky      Name = Importer.HandleNameConflict(Name, DC, IDNS,
1841203955Srdivacky                                         ConflictingDecls.data(),
1842203955Srdivacky                                         ConflictingDecls.size());
1843203955Srdivacky      if (!Name)
1844203955Srdivacky        return 0;
1845203955Srdivacky    }
1846203955Srdivacky  }
1847203955Srdivacky
1848203955Srdivacky  // Import the type.
1849203955Srdivacky  QualType T = Importer.Import(D->getType());
1850203955Srdivacky  if (T.isNull())
1851203955Srdivacky    return 0;
1852203955Srdivacky
1853203955Srdivacky  // Import the function parameters.
1854203955Srdivacky  llvm::SmallVector<ParmVarDecl *, 8> Parameters;
1855203955Srdivacky  for (FunctionDecl::param_iterator P = D->param_begin(), PEnd = D->param_end();
1856203955Srdivacky       P != PEnd; ++P) {
1857203955Srdivacky    ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(*P));
1858203955Srdivacky    if (!ToP)
1859203955Srdivacky      return 0;
1860203955Srdivacky
1861203955Srdivacky    Parameters.push_back(ToP);
1862203955Srdivacky  }
1863203955Srdivacky
1864203955Srdivacky  // Create the imported function.
1865203955Srdivacky  TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
1866204643Srdivacky  FunctionDecl *ToFunction = 0;
1867204643Srdivacky  if (CXXConstructorDecl *FromConstructor = dyn_cast<CXXConstructorDecl>(D)) {
1868204643Srdivacky    ToFunction = CXXConstructorDecl::Create(Importer.getToContext(),
1869204643Srdivacky                                            cast<CXXRecordDecl>(DC),
1870204643Srdivacky                                            Loc, Name, T, TInfo,
1871204643Srdivacky                                            FromConstructor->isExplicit(),
1872204643Srdivacky                                            D->isInlineSpecified(),
1873204643Srdivacky                                            D->isImplicit());
1874204643Srdivacky  } else if (isa<CXXDestructorDecl>(D)) {
1875204643Srdivacky    ToFunction = CXXDestructorDecl::Create(Importer.getToContext(),
1876204643Srdivacky                                           cast<CXXRecordDecl>(DC),
1877204643Srdivacky                                           Loc, Name, T,
1878204643Srdivacky                                           D->isInlineSpecified(),
1879204643Srdivacky                                           D->isImplicit());
1880204643Srdivacky  } else if (CXXConversionDecl *FromConversion
1881204643Srdivacky                                           = dyn_cast<CXXConversionDecl>(D)) {
1882204643Srdivacky    ToFunction = CXXConversionDecl::Create(Importer.getToContext(),
1883204643Srdivacky                                           cast<CXXRecordDecl>(DC),
1884204643Srdivacky                                           Loc, Name, T, TInfo,
1885204643Srdivacky                                           D->isInlineSpecified(),
1886204643Srdivacky                                           FromConversion->isExplicit());
1887204643Srdivacky  } else {
1888204643Srdivacky    ToFunction = FunctionDecl::Create(Importer.getToContext(), DC, Loc,
1889204643Srdivacky                                      Name, T, TInfo, D->getStorageClass(),
1890204643Srdivacky                                      D->isInlineSpecified(),
1891204643Srdivacky                                      D->hasWrittenPrototype());
1892204643Srdivacky  }
1893204643Srdivacky  ToFunction->setAccess(D->getAccess());
1894204643Srdivacky  ToFunction->setLexicalDeclContext(LexicalDC);
1895204643Srdivacky  Importer.Imported(D, ToFunction);
1896204643Srdivacky  LexicalDC->addDecl(ToFunction);
1897203955Srdivacky
1898203955Srdivacky  // Set the parameters.
1899203955Srdivacky  for (unsigned I = 0, N = Parameters.size(); I != N; ++I) {
1900204643Srdivacky    Parameters[I]->setOwningFunction(ToFunction);
1901204643Srdivacky    ToFunction->addDecl(Parameters[I]);
1902203955Srdivacky  }
1903204643Srdivacky  ToFunction->setParams(Parameters.data(), Parameters.size());
1904203955Srdivacky
1905203955Srdivacky  // FIXME: Other bits to merge?
1906203955Srdivacky
1907204643Srdivacky  return ToFunction;
1908203955Srdivacky}
1909203955Srdivacky
1910204643SrdivackyDecl *ASTNodeImporter::VisitCXXMethodDecl(CXXMethodDecl *D) {
1911204643Srdivacky  return VisitFunctionDecl(D);
1912204643Srdivacky}
1913204643Srdivacky
1914204643SrdivackyDecl *ASTNodeImporter::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
1915204643Srdivacky  return VisitCXXMethodDecl(D);
1916204643Srdivacky}
1917204643Srdivacky
1918204643SrdivackyDecl *ASTNodeImporter::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
1919204643Srdivacky  return VisitCXXMethodDecl(D);
1920204643Srdivacky}
1921204643Srdivacky
1922204643SrdivackyDecl *ASTNodeImporter::VisitCXXConversionDecl(CXXConversionDecl *D) {
1923204643Srdivacky  return VisitCXXMethodDecl(D);
1924204643Srdivacky}
1925204643Srdivacky
1926203955SrdivackyDecl *ASTNodeImporter::VisitFieldDecl(FieldDecl *D) {
1927203955Srdivacky  // Import the major distinguishing characteristics of a variable.
1928203955Srdivacky  DeclContext *DC, *LexicalDC;
1929203955Srdivacky  DeclarationName Name;
1930203955Srdivacky  SourceLocation Loc;
1931203955Srdivacky  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
1932203955Srdivacky    return 0;
1933203955Srdivacky
1934203955Srdivacky  // Import the type.
1935203955Srdivacky  QualType T = Importer.Import(D->getType());
1936203955Srdivacky  if (T.isNull())
1937203955Srdivacky    return 0;
1938203955Srdivacky
1939203955Srdivacky  TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
1940203955Srdivacky  Expr *BitWidth = Importer.Import(D->getBitWidth());
1941203955Srdivacky  if (!BitWidth && D->getBitWidth())
1942203955Srdivacky    return 0;
1943203955Srdivacky
1944203955Srdivacky  FieldDecl *ToField = FieldDecl::Create(Importer.getToContext(), DC,
1945203955Srdivacky                                         Loc, Name.getAsIdentifierInfo(),
1946203955Srdivacky                                         T, TInfo, BitWidth, D->isMutable());
1947204643Srdivacky  ToField->setAccess(D->getAccess());
1948203955Srdivacky  ToField->setLexicalDeclContext(LexicalDC);
1949203955Srdivacky  Importer.Imported(D, ToField);
1950203955Srdivacky  LexicalDC->addDecl(ToField);
1951203955Srdivacky  return ToField;
1952203955Srdivacky}
1953203955Srdivacky
1954204643SrdivackyDecl *ASTNodeImporter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
1955204643Srdivacky  // Import the major distinguishing characteristics of an ivar.
1956204643Srdivacky  DeclContext *DC, *LexicalDC;
1957204643Srdivacky  DeclarationName Name;
1958204643Srdivacky  SourceLocation Loc;
1959204643Srdivacky  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
1960204643Srdivacky    return 0;
1961204643Srdivacky
1962204643Srdivacky  // Determine whether we've already imported this ivar
1963204643Srdivacky  for (DeclContext::lookup_result Lookup = DC->lookup(Name);
1964204643Srdivacky       Lookup.first != Lookup.second;
1965204643Srdivacky       ++Lookup.first) {
1966204643Srdivacky    if (ObjCIvarDecl *FoundIvar = dyn_cast<ObjCIvarDecl>(*Lookup.first)) {
1967204643Srdivacky      if (Importer.IsStructurallyEquivalent(D->getType(),
1968204643Srdivacky                                            FoundIvar->getType())) {
1969204643Srdivacky        Importer.Imported(D, FoundIvar);
1970204643Srdivacky        return FoundIvar;
1971204643Srdivacky      }
1972204643Srdivacky
1973204643Srdivacky      Importer.ToDiag(Loc, diag::err_odr_ivar_type_inconsistent)
1974204643Srdivacky        << Name << D->getType() << FoundIvar->getType();
1975204643Srdivacky      Importer.ToDiag(FoundIvar->getLocation(), diag::note_odr_value_here)
1976204643Srdivacky        << FoundIvar->getType();
1977204643Srdivacky      return 0;
1978204643Srdivacky    }
1979204643Srdivacky  }
1980204643Srdivacky
1981204643Srdivacky  // Import the type.
1982204643Srdivacky  QualType T = Importer.Import(D->getType());
1983204643Srdivacky  if (T.isNull())
1984204643Srdivacky    return 0;
1985204643Srdivacky
1986204643Srdivacky  TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
1987204643Srdivacky  Expr *BitWidth = Importer.Import(D->getBitWidth());
1988204643Srdivacky  if (!BitWidth && D->getBitWidth())
1989204643Srdivacky    return 0;
1990204643Srdivacky
1991204643Srdivacky  ObjCIvarDecl *ToIvar = ObjCIvarDecl::Create(Importer.getToContext(), DC,
1992204643Srdivacky                                              Loc, Name.getAsIdentifierInfo(),
1993204643Srdivacky                                              T, TInfo, D->getAccessControl(),
1994204643Srdivacky                                              BitWidth);
1995204643Srdivacky  ToIvar->setLexicalDeclContext(LexicalDC);
1996204643Srdivacky  Importer.Imported(D, ToIvar);
1997204643Srdivacky  LexicalDC->addDecl(ToIvar);
1998204643Srdivacky  return ToIvar;
1999204643Srdivacky
2000204643Srdivacky}
2001204643Srdivacky
2002203955SrdivackyDecl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
2003203955Srdivacky  // Import the major distinguishing characteristics of a variable.
2004203955Srdivacky  DeclContext *DC, *LexicalDC;
2005203955Srdivacky  DeclarationName Name;
2006203955Srdivacky  SourceLocation Loc;
2007203955Srdivacky  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2008203955Srdivacky    return 0;
2009203955Srdivacky
2010203955Srdivacky  // Try to find a variable in our own ("to") context with the same name and
2011203955Srdivacky  // in the same context as the variable we're importing.
2012203955Srdivacky  if (D->isFileVarDecl()) {
2013203955Srdivacky    VarDecl *MergeWithVar = 0;
2014203955Srdivacky    llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
2015203955Srdivacky    unsigned IDNS = Decl::IDNS_Ordinary;
2016203955Srdivacky    for (DeclContext::lookup_result Lookup = DC->lookup(Name);
2017203955Srdivacky         Lookup.first != Lookup.second;
2018203955Srdivacky         ++Lookup.first) {
2019203955Srdivacky      if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
2020203955Srdivacky        continue;
2021203955Srdivacky
2022203955Srdivacky      if (VarDecl *FoundVar = dyn_cast<VarDecl>(*Lookup.first)) {
2023203955Srdivacky        // We have found a variable that we may need to merge with. Check it.
2024203955Srdivacky        if (isExternalLinkage(FoundVar->getLinkage()) &&
2025203955Srdivacky            isExternalLinkage(D->getLinkage())) {
2026203955Srdivacky          if (Importer.IsStructurallyEquivalent(D->getType(),
2027203955Srdivacky                                                FoundVar->getType())) {
2028203955Srdivacky            MergeWithVar = FoundVar;
2029203955Srdivacky            break;
2030203955Srdivacky          }
2031203955Srdivacky
2032203955Srdivacky          const ArrayType *FoundArray
2033203955Srdivacky            = Importer.getToContext().getAsArrayType(FoundVar->getType());
2034203955Srdivacky          const ArrayType *TArray
2035203955Srdivacky            = Importer.getToContext().getAsArrayType(D->getType());
2036203955Srdivacky          if (FoundArray && TArray) {
2037203955Srdivacky            if (isa<IncompleteArrayType>(FoundArray) &&
2038203955Srdivacky                isa<ConstantArrayType>(TArray)) {
2039203955Srdivacky              // Import the type.
2040203955Srdivacky              QualType T = Importer.Import(D->getType());
2041203955Srdivacky              if (T.isNull())
2042203955Srdivacky                return 0;
2043203955Srdivacky
2044203955Srdivacky              FoundVar->setType(T);
2045203955Srdivacky              MergeWithVar = FoundVar;
2046203955Srdivacky              break;
2047203955Srdivacky            } else if (isa<IncompleteArrayType>(TArray) &&
2048203955Srdivacky                       isa<ConstantArrayType>(FoundArray)) {
2049203955Srdivacky              MergeWithVar = FoundVar;
2050203955Srdivacky              break;
2051203955Srdivacky            }
2052203955Srdivacky          }
2053203955Srdivacky
2054203955Srdivacky          Importer.ToDiag(Loc, diag::err_odr_variable_type_inconsistent)
2055203955Srdivacky            << Name << D->getType() << FoundVar->getType();
2056203955Srdivacky          Importer.ToDiag(FoundVar->getLocation(), diag::note_odr_value_here)
2057203955Srdivacky            << FoundVar->getType();
2058203955Srdivacky        }
2059203955Srdivacky      }
2060203955Srdivacky
2061203955Srdivacky      ConflictingDecls.push_back(*Lookup.first);
2062203955Srdivacky    }
2063203955Srdivacky
2064203955Srdivacky    if (MergeWithVar) {
2065203955Srdivacky      // An equivalent variable with external linkage has been found. Link
2066203955Srdivacky      // the two declarations, then merge them.
2067203955Srdivacky      Importer.Imported(D, MergeWithVar);
2068203955Srdivacky
2069203955Srdivacky      if (VarDecl *DDef = D->getDefinition()) {
2070203955Srdivacky        if (VarDecl *ExistingDef = MergeWithVar->getDefinition()) {
2071203955Srdivacky          Importer.ToDiag(ExistingDef->getLocation(),
2072203955Srdivacky                          diag::err_odr_variable_multiple_def)
2073203955Srdivacky            << Name;
2074203955Srdivacky          Importer.FromDiag(DDef->getLocation(), diag::note_odr_defined_here);
2075203955Srdivacky        } else {
2076203955Srdivacky          Expr *Init = Importer.Import(DDef->getInit());
2077203955Srdivacky          MergeWithVar->setInit(Init);
2078203955Srdivacky        }
2079203955Srdivacky      }
2080203955Srdivacky
2081203955Srdivacky      return MergeWithVar;
2082203955Srdivacky    }
2083203955Srdivacky
2084203955Srdivacky    if (!ConflictingDecls.empty()) {
2085203955Srdivacky      Name = Importer.HandleNameConflict(Name, DC, IDNS,
2086203955Srdivacky                                         ConflictingDecls.data(),
2087203955Srdivacky                                         ConflictingDecls.size());
2088203955Srdivacky      if (!Name)
2089203955Srdivacky        return 0;
2090203955Srdivacky    }
2091203955Srdivacky  }
2092203955Srdivacky
2093203955Srdivacky  // Import the type.
2094203955Srdivacky  QualType T = Importer.Import(D->getType());
2095203955Srdivacky  if (T.isNull())
2096203955Srdivacky    return 0;
2097203955Srdivacky
2098203955Srdivacky  // Create the imported variable.
2099203955Srdivacky  TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
2100203955Srdivacky  VarDecl *ToVar = VarDecl::Create(Importer.getToContext(), DC, Loc,
2101203955Srdivacky                                   Name.getAsIdentifierInfo(), T, TInfo,
2102203955Srdivacky                                   D->getStorageClass());
2103204643Srdivacky  ToVar->setAccess(D->getAccess());
2104203955Srdivacky  ToVar->setLexicalDeclContext(LexicalDC);
2105203955Srdivacky  Importer.Imported(D, ToVar);
2106203955Srdivacky  LexicalDC->addDecl(ToVar);
2107203955Srdivacky
2108203955Srdivacky  // Merge the initializer.
2109203955Srdivacky  // FIXME: Can we really import any initializer? Alternatively, we could force
2110203955Srdivacky  // ourselves to import every declaration of a variable and then only use
2111203955Srdivacky  // getInit() here.
2112203955Srdivacky  ToVar->setInit(Importer.Import(const_cast<Expr *>(D->getAnyInitializer())));
2113203955Srdivacky
2114203955Srdivacky  // FIXME: Other bits to merge?
2115203955Srdivacky
2116203955Srdivacky  return ToVar;
2117203955Srdivacky}
2118203955Srdivacky
2119204643SrdivackyDecl *ASTNodeImporter::VisitImplicitParamDecl(ImplicitParamDecl *D) {
2120204643Srdivacky  // Parameters are created in the translation unit's context, then moved
2121204643Srdivacky  // into the function declaration's context afterward.
2122204643Srdivacky  DeclContext *DC = Importer.getToContext().getTranslationUnitDecl();
2123204643Srdivacky
2124204643Srdivacky  // Import the name of this declaration.
2125204643Srdivacky  DeclarationName Name = Importer.Import(D->getDeclName());
2126204643Srdivacky  if (D->getDeclName() && !Name)
2127204643Srdivacky    return 0;
2128204643Srdivacky
2129204643Srdivacky  // Import the location of this declaration.
2130204643Srdivacky  SourceLocation Loc = Importer.Import(D->getLocation());
2131204643Srdivacky
2132204643Srdivacky  // Import the parameter's type.
2133204643Srdivacky  QualType T = Importer.Import(D->getType());
2134204643Srdivacky  if (T.isNull())
2135204643Srdivacky    return 0;
2136204643Srdivacky
2137204643Srdivacky  // Create the imported parameter.
2138204643Srdivacky  ImplicitParamDecl *ToParm
2139204643Srdivacky    = ImplicitParamDecl::Create(Importer.getToContext(), DC,
2140204643Srdivacky                                Loc, Name.getAsIdentifierInfo(),
2141204643Srdivacky                                T);
2142204643Srdivacky  return Importer.Imported(D, ToParm);
2143204643Srdivacky}
2144204643Srdivacky
2145203955SrdivackyDecl *ASTNodeImporter::VisitParmVarDecl(ParmVarDecl *D) {
2146203955Srdivacky  // Parameters are created in the translation unit's context, then moved
2147203955Srdivacky  // into the function declaration's context afterward.
2148203955Srdivacky  DeclContext *DC = Importer.getToContext().getTranslationUnitDecl();
2149203955Srdivacky
2150203955Srdivacky  // Import the name of this declaration.
2151203955Srdivacky  DeclarationName Name = Importer.Import(D->getDeclName());
2152203955Srdivacky  if (D->getDeclName() && !Name)
2153203955Srdivacky    return 0;
2154203955Srdivacky
2155203955Srdivacky  // Import the location of this declaration.
2156203955Srdivacky  SourceLocation Loc = Importer.Import(D->getLocation());
2157203955Srdivacky
2158203955Srdivacky  // Import the parameter's type.
2159203955Srdivacky  QualType T = Importer.Import(D->getType());
2160203955Srdivacky  if (T.isNull())
2161203955Srdivacky    return 0;
2162203955Srdivacky
2163203955Srdivacky  // Create the imported parameter.
2164203955Srdivacky  TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
2165203955Srdivacky  ParmVarDecl *ToParm = ParmVarDecl::Create(Importer.getToContext(), DC,
2166203955Srdivacky                                            Loc, Name.getAsIdentifierInfo(),
2167203955Srdivacky                                            T, TInfo, D->getStorageClass(),
2168203955Srdivacky                                            /*FIXME: Default argument*/ 0);
2169203955Srdivacky  return Importer.Imported(D, ToParm);
2170203955Srdivacky}
2171203955Srdivacky
2172204643SrdivackyDecl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
2173204643Srdivacky  // Import the major distinguishing characteristics of a method.
2174204643Srdivacky  DeclContext *DC, *LexicalDC;
2175204643Srdivacky  DeclarationName Name;
2176204643Srdivacky  SourceLocation Loc;
2177204643Srdivacky  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2178204643Srdivacky    return 0;
2179204643Srdivacky
2180204643Srdivacky  for (DeclContext::lookup_result Lookup = DC->lookup(Name);
2181204643Srdivacky       Lookup.first != Lookup.second;
2182204643Srdivacky       ++Lookup.first) {
2183204643Srdivacky    if (ObjCMethodDecl *FoundMethod = dyn_cast<ObjCMethodDecl>(*Lookup.first)) {
2184204643Srdivacky      if (FoundMethod->isInstanceMethod() != D->isInstanceMethod())
2185204643Srdivacky        continue;
2186204643Srdivacky
2187204643Srdivacky      // Check return types.
2188204643Srdivacky      if (!Importer.IsStructurallyEquivalent(D->getResultType(),
2189204643Srdivacky                                             FoundMethod->getResultType())) {
2190204643Srdivacky        Importer.ToDiag(Loc, diag::err_odr_objc_method_result_type_inconsistent)
2191204643Srdivacky          << D->isInstanceMethod() << Name
2192204643Srdivacky          << D->getResultType() << FoundMethod->getResultType();
2193204643Srdivacky        Importer.ToDiag(FoundMethod->getLocation(),
2194204643Srdivacky                        diag::note_odr_objc_method_here)
2195204643Srdivacky          << D->isInstanceMethod() << Name;
2196204643Srdivacky        return 0;
2197204643Srdivacky      }
2198204643Srdivacky
2199204643Srdivacky      // Check the number of parameters.
2200204643Srdivacky      if (D->param_size() != FoundMethod->param_size()) {
2201204643Srdivacky        Importer.ToDiag(Loc, diag::err_odr_objc_method_num_params_inconsistent)
2202204643Srdivacky          << D->isInstanceMethod() << Name
2203204643Srdivacky          << D->param_size() << FoundMethod->param_size();
2204204643Srdivacky        Importer.ToDiag(FoundMethod->getLocation(),
2205204643Srdivacky                        diag::note_odr_objc_method_here)
2206204643Srdivacky          << D->isInstanceMethod() << Name;
2207204643Srdivacky        return 0;
2208204643Srdivacky      }
2209204643Srdivacky
2210204643Srdivacky      // Check parameter types.
2211204643Srdivacky      for (ObjCMethodDecl::param_iterator P = D->param_begin(),
2212204643Srdivacky             PEnd = D->param_end(), FoundP = FoundMethod->param_begin();
2213204643Srdivacky           P != PEnd; ++P, ++FoundP) {
2214204643Srdivacky        if (!Importer.IsStructurallyEquivalent((*P)->getType(),
2215204643Srdivacky                                               (*FoundP)->getType())) {
2216204643Srdivacky          Importer.FromDiag((*P)->getLocation(),
2217204643Srdivacky                            diag::err_odr_objc_method_param_type_inconsistent)
2218204643Srdivacky            << D->isInstanceMethod() << Name
2219204643Srdivacky            << (*P)->getType() << (*FoundP)->getType();
2220204643Srdivacky          Importer.ToDiag((*FoundP)->getLocation(), diag::note_odr_value_here)
2221204643Srdivacky            << (*FoundP)->getType();
2222204643Srdivacky          return 0;
2223204643Srdivacky        }
2224204643Srdivacky      }
2225204643Srdivacky
2226204643Srdivacky      // Check variadic/non-variadic.
2227204643Srdivacky      // Check the number of parameters.
2228204643Srdivacky      if (D->isVariadic() != FoundMethod->isVariadic()) {
2229204643Srdivacky        Importer.ToDiag(Loc, diag::err_odr_objc_method_variadic_inconsistent)
2230204643Srdivacky          << D->isInstanceMethod() << Name;
2231204643Srdivacky        Importer.ToDiag(FoundMethod->getLocation(),
2232204643Srdivacky                        diag::note_odr_objc_method_here)
2233204643Srdivacky          << D->isInstanceMethod() << Name;
2234204643Srdivacky        return 0;
2235204643Srdivacky      }
2236204643Srdivacky
2237204643Srdivacky      // FIXME: Any other bits we need to merge?
2238204643Srdivacky      return Importer.Imported(D, FoundMethod);
2239204643Srdivacky    }
2240204643Srdivacky  }
2241204643Srdivacky
2242204643Srdivacky  // Import the result type.
2243204643Srdivacky  QualType ResultTy = Importer.Import(D->getResultType());
2244204643Srdivacky  if (ResultTy.isNull())
2245204643Srdivacky    return 0;
2246204643Srdivacky
2247204643Srdivacky  ObjCMethodDecl *ToMethod
2248204643Srdivacky    = ObjCMethodDecl::Create(Importer.getToContext(),
2249204643Srdivacky                             Loc,
2250204643Srdivacky                             Importer.Import(D->getLocEnd()),
2251204643Srdivacky                             Name.getObjCSelector(),
2252204643Srdivacky                             ResultTy, DC,
2253204643Srdivacky                             D->isInstanceMethod(),
2254204643Srdivacky                             D->isVariadic(),
2255204643Srdivacky                             D->isSynthesized(),
2256204643Srdivacky                             D->getImplementationControl());
2257204643Srdivacky
2258204643Srdivacky  // FIXME: When we decide to merge method definitions, we'll need to
2259204643Srdivacky  // deal with implicit parameters.
2260204643Srdivacky
2261204643Srdivacky  // Import the parameters
2262204643Srdivacky  llvm::SmallVector<ParmVarDecl *, 5> ToParams;
2263204643Srdivacky  for (ObjCMethodDecl::param_iterator FromP = D->param_begin(),
2264204643Srdivacky                                   FromPEnd = D->param_end();
2265204643Srdivacky       FromP != FromPEnd;
2266204643Srdivacky       ++FromP) {
2267204643Srdivacky    ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(*FromP));
2268204643Srdivacky    if (!ToP)
2269204643Srdivacky      return 0;
2270204643Srdivacky
2271204643Srdivacky    ToParams.push_back(ToP);
2272204643Srdivacky  }
2273204643Srdivacky
2274204643Srdivacky  // Set the parameters.
2275204643Srdivacky  for (unsigned I = 0, N = ToParams.size(); I != N; ++I) {
2276204643Srdivacky    ToParams[I]->setOwningFunction(ToMethod);
2277204643Srdivacky    ToMethod->addDecl(ToParams[I]);
2278204643Srdivacky  }
2279204643Srdivacky  ToMethod->setMethodParams(Importer.getToContext(),
2280204643Srdivacky                            ToParams.data(), ToParams.size());
2281204643Srdivacky
2282204643Srdivacky  ToMethod->setLexicalDeclContext(LexicalDC);
2283204643Srdivacky  Importer.Imported(D, ToMethod);
2284204643Srdivacky  LexicalDC->addDecl(ToMethod);
2285204643Srdivacky  return ToMethod;
2286204643Srdivacky}
2287204643Srdivacky
2288204643SrdivackyDecl *ASTNodeImporter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
2289204643Srdivacky  // Import the major distinguishing characteristics of a category.
2290204643Srdivacky  DeclContext *DC, *LexicalDC;
2291204643Srdivacky  DeclarationName Name;
2292204643Srdivacky  SourceLocation Loc;
2293204643Srdivacky  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2294204643Srdivacky    return 0;
2295204643Srdivacky
2296204643Srdivacky  ObjCInterfaceDecl *ToInterface
2297204643Srdivacky    = cast_or_null<ObjCInterfaceDecl>(Importer.Import(D->getClassInterface()));
2298204643Srdivacky  if (!ToInterface)
2299204643Srdivacky    return 0;
2300204643Srdivacky
2301204643Srdivacky  // Determine if we've already encountered this category.
2302204643Srdivacky  ObjCCategoryDecl *MergeWithCategory
2303204643Srdivacky    = ToInterface->FindCategoryDeclaration(Name.getAsIdentifierInfo());
2304204643Srdivacky  ObjCCategoryDecl *ToCategory = MergeWithCategory;
2305204643Srdivacky  if (!ToCategory) {
2306204643Srdivacky    ToCategory = ObjCCategoryDecl::Create(Importer.getToContext(), DC,
2307204643Srdivacky                                          Importer.Import(D->getAtLoc()),
2308204643Srdivacky                                          Loc,
2309204643Srdivacky                                       Importer.Import(D->getCategoryNameLoc()),
2310204643Srdivacky                                          Name.getAsIdentifierInfo());
2311204643Srdivacky    ToCategory->setLexicalDeclContext(LexicalDC);
2312204643Srdivacky    LexicalDC->addDecl(ToCategory);
2313204643Srdivacky    Importer.Imported(D, ToCategory);
2314204643Srdivacky
2315204643Srdivacky    // Link this category into its class's category list.
2316204643Srdivacky    ToCategory->setClassInterface(ToInterface);
2317204643Srdivacky    ToCategory->insertNextClassCategory();
2318204643Srdivacky
2319204643Srdivacky    // Import protocols
2320204643Srdivacky    llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
2321204643Srdivacky    llvm::SmallVector<SourceLocation, 4> ProtocolLocs;
2322204643Srdivacky    ObjCCategoryDecl::protocol_loc_iterator FromProtoLoc
2323204643Srdivacky      = D->protocol_loc_begin();
2324204643Srdivacky    for (ObjCCategoryDecl::protocol_iterator FromProto = D->protocol_begin(),
2325204643Srdivacky                                          FromProtoEnd = D->protocol_end();
2326204643Srdivacky         FromProto != FromProtoEnd;
2327204643Srdivacky         ++FromProto, ++FromProtoLoc) {
2328204643Srdivacky      ObjCProtocolDecl *ToProto
2329204643Srdivacky        = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
2330204643Srdivacky      if (!ToProto)
2331204643Srdivacky        return 0;
2332204643Srdivacky      Protocols.push_back(ToProto);
2333204643Srdivacky      ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
2334204643Srdivacky    }
2335204643Srdivacky
2336204643Srdivacky    // FIXME: If we're merging, make sure that the protocol list is the same.
2337204643Srdivacky    ToCategory->setProtocolList(Protocols.data(), Protocols.size(),
2338204643Srdivacky                                ProtocolLocs.data(), Importer.getToContext());
2339204643Srdivacky
2340204643Srdivacky  } else {
2341204643Srdivacky    Importer.Imported(D, ToCategory);
2342204643Srdivacky  }
2343204643Srdivacky
2344204643Srdivacky  // Import all of the members of this category.
2345204643Srdivacky  ImportDeclContext(D);
2346204643Srdivacky
2347204643Srdivacky  // If we have an implementation, import it as well.
2348204643Srdivacky  if (D->getImplementation()) {
2349204643Srdivacky    ObjCCategoryImplDecl *Impl
2350204643Srdivacky      = cast<ObjCCategoryImplDecl>(Importer.Import(D->getImplementation()));
2351204643Srdivacky    if (!Impl)
2352204643Srdivacky      return 0;
2353204643Srdivacky
2354204643Srdivacky    ToCategory->setImplementation(Impl);
2355204643Srdivacky  }
2356204643Srdivacky
2357204643Srdivacky  return ToCategory;
2358204643Srdivacky}
2359204643Srdivacky
2360204643SrdivackyDecl *ASTNodeImporter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
2361204643Srdivacky  // Import the major distinguishing characteristics of a protocol.
2362204643Srdivacky  DeclContext *DC, *LexicalDC;
2363204643Srdivacky  DeclarationName Name;
2364204643Srdivacky  SourceLocation Loc;
2365204643Srdivacky  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2366204643Srdivacky    return 0;
2367204643Srdivacky
2368204643Srdivacky  ObjCProtocolDecl *MergeWithProtocol = 0;
2369204643Srdivacky  for (DeclContext::lookup_result Lookup = DC->lookup(Name);
2370204643Srdivacky       Lookup.first != Lookup.second;
2371204643Srdivacky       ++Lookup.first) {
2372204643Srdivacky    if (!(*Lookup.first)->isInIdentifierNamespace(Decl::IDNS_ObjCProtocol))
2373204643Srdivacky      continue;
2374204643Srdivacky
2375204643Srdivacky    if ((MergeWithProtocol = dyn_cast<ObjCProtocolDecl>(*Lookup.first)))
2376204643Srdivacky      break;
2377204643Srdivacky  }
2378204643Srdivacky
2379204643Srdivacky  ObjCProtocolDecl *ToProto = MergeWithProtocol;
2380204643Srdivacky  if (!ToProto || ToProto->isForwardDecl()) {
2381204643Srdivacky    if (!ToProto) {
2382204643Srdivacky      ToProto = ObjCProtocolDecl::Create(Importer.getToContext(), DC, Loc,
2383204643Srdivacky                                         Name.getAsIdentifierInfo());
2384204643Srdivacky      ToProto->setForwardDecl(D->isForwardDecl());
2385204643Srdivacky      ToProto->setLexicalDeclContext(LexicalDC);
2386204643Srdivacky      LexicalDC->addDecl(ToProto);
2387204643Srdivacky    }
2388204643Srdivacky    Importer.Imported(D, ToProto);
2389204643Srdivacky
2390204643Srdivacky    // Import protocols
2391204643Srdivacky    llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
2392204643Srdivacky    llvm::SmallVector<SourceLocation, 4> ProtocolLocs;
2393204643Srdivacky    ObjCProtocolDecl::protocol_loc_iterator
2394204643Srdivacky      FromProtoLoc = D->protocol_loc_begin();
2395204643Srdivacky    for (ObjCProtocolDecl::protocol_iterator FromProto = D->protocol_begin(),
2396204643Srdivacky                                          FromProtoEnd = D->protocol_end();
2397204643Srdivacky       FromProto != FromProtoEnd;
2398204643Srdivacky       ++FromProto, ++FromProtoLoc) {
2399204643Srdivacky      ObjCProtocolDecl *ToProto
2400204643Srdivacky        = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
2401204643Srdivacky      if (!ToProto)
2402204643Srdivacky        return 0;
2403204643Srdivacky      Protocols.push_back(ToProto);
2404204643Srdivacky      ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
2405204643Srdivacky    }
2406204643Srdivacky
2407204643Srdivacky    // FIXME: If we're merging, make sure that the protocol list is the same.
2408204643Srdivacky    ToProto->setProtocolList(Protocols.data(), Protocols.size(),
2409204643Srdivacky                             ProtocolLocs.data(), Importer.getToContext());
2410204643Srdivacky  } else {
2411204643Srdivacky    Importer.Imported(D, ToProto);
2412204643Srdivacky  }
2413204643Srdivacky
2414204643Srdivacky  // Import all of the members of this protocol.
2415204643Srdivacky  ImportDeclContext(D);
2416204643Srdivacky
2417204643Srdivacky  return ToProto;
2418204643Srdivacky}
2419204643Srdivacky
2420203955SrdivackyDecl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
2421203955Srdivacky  // Import the major distinguishing characteristics of an @interface.
2422203955Srdivacky  DeclContext *DC, *LexicalDC;
2423203955Srdivacky  DeclarationName Name;
2424203955Srdivacky  SourceLocation Loc;
2425203955Srdivacky  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2426203955Srdivacky    return 0;
2427203955Srdivacky
2428203955Srdivacky  ObjCInterfaceDecl *MergeWithIface = 0;
2429203955Srdivacky  for (DeclContext::lookup_result Lookup = DC->lookup(Name);
2430203955Srdivacky       Lookup.first != Lookup.second;
2431203955Srdivacky       ++Lookup.first) {
2432203955Srdivacky    if (!(*Lookup.first)->isInIdentifierNamespace(Decl::IDNS_Ordinary))
2433203955Srdivacky      continue;
2434203955Srdivacky
2435203955Srdivacky    if ((MergeWithIface = dyn_cast<ObjCInterfaceDecl>(*Lookup.first)))
2436203955Srdivacky      break;
2437203955Srdivacky  }
2438203955Srdivacky
2439203955Srdivacky  ObjCInterfaceDecl *ToIface = MergeWithIface;
2440203955Srdivacky  if (!ToIface || ToIface->isForwardDecl()) {
2441203955Srdivacky    if (!ToIface) {
2442203955Srdivacky      ToIface = ObjCInterfaceDecl::Create(Importer.getToContext(),
2443203955Srdivacky                                          DC, Loc,
2444203955Srdivacky                                          Name.getAsIdentifierInfo(),
2445203955Srdivacky                                          Importer.Import(D->getClassLoc()),
2446203955Srdivacky                                          D->isForwardDecl(),
2447203955Srdivacky                                          D->isImplicitInterfaceDecl());
2448204643Srdivacky      ToIface->setForwardDecl(D->isForwardDecl());
2449203955Srdivacky      ToIface->setLexicalDeclContext(LexicalDC);
2450203955Srdivacky      LexicalDC->addDecl(ToIface);
2451203955Srdivacky    }
2452203955Srdivacky    Importer.Imported(D, ToIface);
2453203955Srdivacky
2454203955Srdivacky    if (D->getSuperClass()) {
2455203955Srdivacky      ObjCInterfaceDecl *Super
2456203955Srdivacky        = cast_or_null<ObjCInterfaceDecl>(Importer.Import(D->getSuperClass()));
2457203955Srdivacky      if (!Super)
2458203955Srdivacky        return 0;
2459203955Srdivacky
2460203955Srdivacky      ToIface->setSuperClass(Super);
2461203955Srdivacky      ToIface->setSuperClassLoc(Importer.Import(D->getSuperClassLoc()));
2462203955Srdivacky    }
2463203955Srdivacky
2464203955Srdivacky    // Import protocols
2465203955Srdivacky    llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
2466203955Srdivacky    llvm::SmallVector<SourceLocation, 4> ProtocolLocs;
2467203955Srdivacky    ObjCInterfaceDecl::protocol_loc_iterator
2468203955Srdivacky      FromProtoLoc = D->protocol_loc_begin();
2469203955Srdivacky    for (ObjCInterfaceDecl::protocol_iterator FromProto = D->protocol_begin(),
2470203955Srdivacky                                           FromProtoEnd = D->protocol_end();
2471203955Srdivacky       FromProto != FromProtoEnd;
2472203955Srdivacky       ++FromProto, ++FromProtoLoc) {
2473203955Srdivacky      ObjCProtocolDecl *ToProto
2474203955Srdivacky        = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
2475203955Srdivacky      if (!ToProto)
2476203955Srdivacky        return 0;
2477203955Srdivacky      Protocols.push_back(ToProto);
2478203955Srdivacky      ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
2479203955Srdivacky    }
2480203955Srdivacky
2481203955Srdivacky    // FIXME: If we're merging, make sure that the protocol list is the same.
2482203955Srdivacky    ToIface->setProtocolList(Protocols.data(), Protocols.size(),
2483203955Srdivacky                             ProtocolLocs.data(), Importer.getToContext());
2484203955Srdivacky
2485203955Srdivacky    // Import @end range
2486203955Srdivacky    ToIface->setAtEndRange(Importer.Import(D->getAtEndRange()));
2487203955Srdivacky  } else {
2488203955Srdivacky    Importer.Imported(D, ToIface);
2489204643Srdivacky
2490204643Srdivacky    // Check for consistency of superclasses.
2491204643Srdivacky    DeclarationName FromSuperName, ToSuperName;
2492204643Srdivacky    if (D->getSuperClass())
2493204643Srdivacky      FromSuperName = Importer.Import(D->getSuperClass()->getDeclName());
2494204643Srdivacky    if (ToIface->getSuperClass())
2495204643Srdivacky      ToSuperName = ToIface->getSuperClass()->getDeclName();
2496204643Srdivacky    if (FromSuperName != ToSuperName) {
2497204643Srdivacky      Importer.ToDiag(ToIface->getLocation(),
2498204643Srdivacky                      diag::err_odr_objc_superclass_inconsistent)
2499204643Srdivacky        << ToIface->getDeclName();
2500204643Srdivacky      if (ToIface->getSuperClass())
2501204643Srdivacky        Importer.ToDiag(ToIface->getSuperClassLoc(),
2502204643Srdivacky                        diag::note_odr_objc_superclass)
2503204643Srdivacky          << ToIface->getSuperClass()->getDeclName();
2504204643Srdivacky      else
2505204643Srdivacky        Importer.ToDiag(ToIface->getLocation(),
2506204643Srdivacky                        diag::note_odr_objc_missing_superclass);
2507204643Srdivacky      if (D->getSuperClass())
2508204643Srdivacky        Importer.FromDiag(D->getSuperClassLoc(),
2509204643Srdivacky                          diag::note_odr_objc_superclass)
2510204643Srdivacky          << D->getSuperClass()->getDeclName();
2511204643Srdivacky      else
2512204643Srdivacky        Importer.FromDiag(D->getLocation(),
2513204643Srdivacky                          diag::note_odr_objc_missing_superclass);
2514204643Srdivacky      return 0;
2515204643Srdivacky    }
2516203955Srdivacky  }
2517203955Srdivacky
2518204643Srdivacky  // Import categories. When the categories themselves are imported, they'll
2519204643Srdivacky  // hook themselves into this interface.
2520204643Srdivacky  for (ObjCCategoryDecl *FromCat = D->getCategoryList(); FromCat;
2521204643Srdivacky       FromCat = FromCat->getNextClassCategory())
2522204643Srdivacky    Importer.Import(FromCat);
2523204643Srdivacky
2524203955Srdivacky  // Import all of the members of this class.
2525204643Srdivacky  ImportDeclContext(D);
2526203955Srdivacky
2527203955Srdivacky  // If we have an @implementation, import it as well.
2528203955Srdivacky  if (D->getImplementation()) {
2529203955Srdivacky    ObjCImplementationDecl *Impl
2530203955Srdivacky      = cast<ObjCImplementationDecl>(Importer.Import(D->getImplementation()));
2531203955Srdivacky    if (!Impl)
2532203955Srdivacky      return 0;
2533203955Srdivacky
2534203955Srdivacky    ToIface->setImplementation(Impl);
2535203955Srdivacky  }
2536203955Srdivacky
2537204643Srdivacky  return ToIface;
2538203955Srdivacky}
2539203955Srdivacky
2540204643SrdivackyDecl *ASTNodeImporter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
2541204643Srdivacky  // Import the major distinguishing characteristics of an @property.
2542204643Srdivacky  DeclContext *DC, *LexicalDC;
2543204643Srdivacky  DeclarationName Name;
2544204643Srdivacky  SourceLocation Loc;
2545204643Srdivacky  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
2546204643Srdivacky    return 0;
2547204643Srdivacky
2548204643Srdivacky  // Check whether we have already imported this property.
2549204643Srdivacky  for (DeclContext::lookup_result Lookup = DC->lookup(Name);
2550204643Srdivacky       Lookup.first != Lookup.second;
2551204643Srdivacky       ++Lookup.first) {
2552204643Srdivacky    if (ObjCPropertyDecl *FoundProp
2553204643Srdivacky                                = dyn_cast<ObjCPropertyDecl>(*Lookup.first)) {
2554204643Srdivacky      // Check property types.
2555204643Srdivacky      if (!Importer.IsStructurallyEquivalent(D->getType(),
2556204643Srdivacky                                             FoundProp->getType())) {
2557204643Srdivacky        Importer.ToDiag(Loc, diag::err_odr_objc_property_type_inconsistent)
2558204643Srdivacky          << Name << D->getType() << FoundProp->getType();
2559204643Srdivacky        Importer.ToDiag(FoundProp->getLocation(), diag::note_odr_value_here)
2560204643Srdivacky          << FoundProp->getType();
2561204643Srdivacky        return 0;
2562204643Srdivacky      }
2563204643Srdivacky
2564204643Srdivacky      // FIXME: Check property attributes, getters, setters, etc.?
2565204643Srdivacky
2566204643Srdivacky      // Consider these properties to be equivalent.
2567204643Srdivacky      Importer.Imported(D, FoundProp);
2568204643Srdivacky      return FoundProp;
2569204643Srdivacky    }
2570204643Srdivacky  }
2571204643Srdivacky
2572204643Srdivacky  // Import the type.
2573204643Srdivacky  QualType T = Importer.Import(D->getType());
2574204643Srdivacky  if (T.isNull())
2575204643Srdivacky    return 0;
2576204643Srdivacky
2577204643Srdivacky  // Create the new property.
2578204643Srdivacky  ObjCPropertyDecl *ToProperty
2579204643Srdivacky    = ObjCPropertyDecl::Create(Importer.getToContext(), DC, Loc,
2580204643Srdivacky                               Name.getAsIdentifierInfo(),
2581204643Srdivacky                               Importer.Import(D->getAtLoc()),
2582204643Srdivacky                               T,
2583204643Srdivacky                               D->getPropertyImplementation());
2584204643Srdivacky  Importer.Imported(D, ToProperty);
2585204643Srdivacky  ToProperty->setLexicalDeclContext(LexicalDC);
2586204643Srdivacky  LexicalDC->addDecl(ToProperty);
2587204643Srdivacky
2588204643Srdivacky  ToProperty->setPropertyAttributes(D->getPropertyAttributes());
2589204643Srdivacky  ToProperty->setGetterName(Importer.Import(D->getGetterName()));
2590204643Srdivacky  ToProperty->setSetterName(Importer.Import(D->getSetterName()));
2591204643Srdivacky  ToProperty->setGetterMethodDecl(
2592204643Srdivacky     cast_or_null<ObjCMethodDecl>(Importer.Import(D->getGetterMethodDecl())));
2593204643Srdivacky  ToProperty->setSetterMethodDecl(
2594204643Srdivacky     cast_or_null<ObjCMethodDecl>(Importer.Import(D->getSetterMethodDecl())));
2595204643Srdivacky  ToProperty->setPropertyIvarDecl(
2596204643Srdivacky       cast_or_null<ObjCIvarDecl>(Importer.Import(D->getPropertyIvarDecl())));
2597204643Srdivacky  return ToProperty;
2598204643Srdivacky}
2599204643Srdivacky
2600204643SrdivackyDecl *
2601204643SrdivackyASTNodeImporter::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) {
2602204643Srdivacky  // Import the context of this declaration.
2603204643Srdivacky  DeclContext *DC = Importer.ImportContext(D->getDeclContext());
2604204643Srdivacky  if (!DC)
2605204643Srdivacky    return 0;
2606204643Srdivacky
2607204643Srdivacky  DeclContext *LexicalDC = DC;
2608204643Srdivacky  if (D->getDeclContext() != D->getLexicalDeclContext()) {
2609204643Srdivacky    LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
2610204643Srdivacky    if (!LexicalDC)
2611204643Srdivacky      return 0;
2612204643Srdivacky  }
2613204643Srdivacky
2614204643Srdivacky  // Import the location of this declaration.
2615204643Srdivacky  SourceLocation Loc = Importer.Import(D->getLocation());
2616204643Srdivacky
2617204643Srdivacky  llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
2618204643Srdivacky  llvm::SmallVector<SourceLocation, 4> Locations;
2619204643Srdivacky  ObjCForwardProtocolDecl::protocol_loc_iterator FromProtoLoc
2620204643Srdivacky    = D->protocol_loc_begin();
2621204643Srdivacky  for (ObjCForwardProtocolDecl::protocol_iterator FromProto
2622204643Srdivacky         = D->protocol_begin(), FromProtoEnd = D->protocol_end();
2623204643Srdivacky       FromProto != FromProtoEnd;
2624204643Srdivacky       ++FromProto, ++FromProtoLoc) {
2625204643Srdivacky    ObjCProtocolDecl *ToProto
2626204643Srdivacky      = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
2627204643Srdivacky    if (!ToProto)
2628204643Srdivacky      continue;
2629204643Srdivacky
2630204643Srdivacky    Protocols.push_back(ToProto);
2631204643Srdivacky    Locations.push_back(Importer.Import(*FromProtoLoc));
2632204643Srdivacky  }
2633204643Srdivacky
2634204643Srdivacky  ObjCForwardProtocolDecl *ToForward
2635204643Srdivacky    = ObjCForwardProtocolDecl::Create(Importer.getToContext(), DC, Loc,
2636204643Srdivacky                                      Protocols.data(), Protocols.size(),
2637204643Srdivacky                                      Locations.data());
2638204643Srdivacky  ToForward->setLexicalDeclContext(LexicalDC);
2639204643Srdivacky  LexicalDC->addDecl(ToForward);
2640204643Srdivacky  Importer.Imported(D, ToForward);
2641204643Srdivacky  return ToForward;
2642204643Srdivacky}
2643204643Srdivacky
2644204643SrdivackyDecl *ASTNodeImporter::VisitObjCClassDecl(ObjCClassDecl *D) {
2645204643Srdivacky  // Import the context of this declaration.
2646204643Srdivacky  DeclContext *DC = Importer.ImportContext(D->getDeclContext());
2647204643Srdivacky  if (!DC)
2648204643Srdivacky    return 0;
2649204643Srdivacky
2650204643Srdivacky  DeclContext *LexicalDC = DC;
2651204643Srdivacky  if (D->getDeclContext() != D->getLexicalDeclContext()) {
2652204643Srdivacky    LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
2653204643Srdivacky    if (!LexicalDC)
2654204643Srdivacky      return 0;
2655204643Srdivacky  }
2656204643Srdivacky
2657204643Srdivacky  // Import the location of this declaration.
2658204643Srdivacky  SourceLocation Loc = Importer.Import(D->getLocation());
2659204643Srdivacky
2660204643Srdivacky  llvm::SmallVector<ObjCInterfaceDecl *, 4> Interfaces;
2661204643Srdivacky  llvm::SmallVector<SourceLocation, 4> Locations;
2662204643Srdivacky  for (ObjCClassDecl::iterator From = D->begin(), FromEnd = D->end();
2663204643Srdivacky       From != FromEnd; ++From) {
2664204643Srdivacky    ObjCInterfaceDecl *ToIface
2665204643Srdivacky      = cast_or_null<ObjCInterfaceDecl>(Importer.Import(From->getInterface()));
2666204643Srdivacky    if (!ToIface)
2667204643Srdivacky      continue;
2668204643Srdivacky
2669204643Srdivacky    Interfaces.push_back(ToIface);
2670204643Srdivacky    Locations.push_back(Importer.Import(From->getLocation()));
2671204643Srdivacky  }
2672204643Srdivacky
2673204643Srdivacky  ObjCClassDecl *ToClass = ObjCClassDecl::Create(Importer.getToContext(), DC,
2674204643Srdivacky                                                 Loc,
2675204643Srdivacky                                                 Interfaces.data(),
2676204643Srdivacky                                                 Locations.data(),
2677204643Srdivacky                                                 Interfaces.size());
2678204643Srdivacky  ToClass->setLexicalDeclContext(LexicalDC);
2679204643Srdivacky  LexicalDC->addDecl(ToClass);
2680204643Srdivacky  Importer.Imported(D, ToClass);
2681204643Srdivacky  return ToClass;
2682204643Srdivacky}
2683204643Srdivacky
2684203955Srdivacky//----------------------------------------------------------------------------
2685203955Srdivacky// Import Statements
2686203955Srdivacky//----------------------------------------------------------------------------
2687203955Srdivacky
2688203955SrdivackyStmt *ASTNodeImporter::VisitStmt(Stmt *S) {
2689203955Srdivacky  Importer.FromDiag(S->getLocStart(), diag::err_unsupported_ast_node)
2690203955Srdivacky    << S->getStmtClassName();
2691203955Srdivacky  return 0;
2692203955Srdivacky}
2693203955Srdivacky
2694203955Srdivacky//----------------------------------------------------------------------------
2695203955Srdivacky// Import Expressions
2696203955Srdivacky//----------------------------------------------------------------------------
2697203955SrdivackyExpr *ASTNodeImporter::VisitExpr(Expr *E) {
2698203955Srdivacky  Importer.FromDiag(E->getLocStart(), diag::err_unsupported_ast_node)
2699203955Srdivacky    << E->getStmtClassName();
2700203955Srdivacky  return 0;
2701203955Srdivacky}
2702203955Srdivacky
2703204643SrdivackyExpr *ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) {
2704204643Srdivacky  NestedNameSpecifier *Qualifier = 0;
2705204643Srdivacky  if (E->getQualifier()) {
2706204643Srdivacky    Qualifier = Importer.Import(E->getQualifier());
2707204643Srdivacky    if (!E->getQualifier())
2708204643Srdivacky      return 0;
2709204643Srdivacky  }
2710204643Srdivacky
2711204643Srdivacky  ValueDecl *ToD = cast_or_null<ValueDecl>(Importer.Import(E->getDecl()));
2712204643Srdivacky  if (!ToD)
2713204643Srdivacky    return 0;
2714204643Srdivacky
2715204643Srdivacky  QualType T = Importer.Import(E->getType());
2716204643Srdivacky  if (T.isNull())
2717204643Srdivacky    return 0;
2718204643Srdivacky
2719204643Srdivacky  return DeclRefExpr::Create(Importer.getToContext(), Qualifier,
2720204643Srdivacky                             Importer.Import(E->getQualifierRange()),
2721204643Srdivacky                             ToD,
2722204643Srdivacky                             Importer.Import(E->getLocation()),
2723204643Srdivacky                             T,
2724204643Srdivacky                             /*FIXME:TemplateArgs=*/0);
2725204643Srdivacky}
2726204643Srdivacky
2727203955SrdivackyExpr *ASTNodeImporter::VisitIntegerLiteral(IntegerLiteral *E) {
2728203955Srdivacky  QualType T = Importer.Import(E->getType());
2729203955Srdivacky  if (T.isNull())
2730203955Srdivacky    return 0;
2731203955Srdivacky
2732203955Srdivacky  return new (Importer.getToContext())
2733203955Srdivacky    IntegerLiteral(E->getValue(), T, Importer.Import(E->getLocation()));
2734203955Srdivacky}
2735203955Srdivacky
2736204643SrdivackyExpr *ASTNodeImporter::VisitCharacterLiteral(CharacterLiteral *E) {
2737204643Srdivacky  QualType T = Importer.Import(E->getType());
2738204643Srdivacky  if (T.isNull())
2739204643Srdivacky    return 0;
2740204643Srdivacky
2741204643Srdivacky  return new (Importer.getToContext()) CharacterLiteral(E->getValue(),
2742204643Srdivacky                                                        E->isWide(), T,
2743204643Srdivacky                                          Importer.Import(E->getLocation()));
2744204643Srdivacky}
2745204643Srdivacky
2746204643SrdivackyExpr *ASTNodeImporter::VisitParenExpr(ParenExpr *E) {
2747204643Srdivacky  Expr *SubExpr = Importer.Import(E->getSubExpr());
2748204643Srdivacky  if (!SubExpr)
2749204643Srdivacky    return 0;
2750204643Srdivacky
2751204643Srdivacky  return new (Importer.getToContext())
2752204643Srdivacky                                  ParenExpr(Importer.Import(E->getLParen()),
2753204643Srdivacky                                            Importer.Import(E->getRParen()),
2754204643Srdivacky                                            SubExpr);
2755204643Srdivacky}
2756204643Srdivacky
2757204643SrdivackyExpr *ASTNodeImporter::VisitUnaryOperator(UnaryOperator *E) {
2758204643Srdivacky  QualType T = Importer.Import(E->getType());
2759204643Srdivacky  if (T.isNull())
2760204643Srdivacky    return 0;
2761204643Srdivacky
2762204643Srdivacky  Expr *SubExpr = Importer.Import(E->getSubExpr());
2763204643Srdivacky  if (!SubExpr)
2764204643Srdivacky    return 0;
2765204643Srdivacky
2766204643Srdivacky  return new (Importer.getToContext()) UnaryOperator(SubExpr, E->getOpcode(),
2767204643Srdivacky                                                     T,
2768204643Srdivacky                                         Importer.Import(E->getOperatorLoc()));
2769204643Srdivacky}
2770204643Srdivacky
2771204643SrdivackyExpr *ASTNodeImporter::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
2772204643Srdivacky  QualType ResultType = Importer.Import(E->getType());
2773204643Srdivacky
2774204643Srdivacky  if (E->isArgumentType()) {
2775204643Srdivacky    TypeSourceInfo *TInfo = Importer.Import(E->getArgumentTypeInfo());
2776204643Srdivacky    if (!TInfo)
2777204643Srdivacky      return 0;
2778204643Srdivacky
2779204643Srdivacky    return new (Importer.getToContext()) SizeOfAlignOfExpr(E->isSizeOf(),
2780204643Srdivacky                                                           TInfo, ResultType,
2781204643Srdivacky                                           Importer.Import(E->getOperatorLoc()),
2782204643Srdivacky                                           Importer.Import(E->getRParenLoc()));
2783204643Srdivacky  }
2784204643Srdivacky
2785204643Srdivacky  Expr *SubExpr = Importer.Import(E->getArgumentExpr());
2786204643Srdivacky  if (!SubExpr)
2787204643Srdivacky    return 0;
2788204643Srdivacky
2789204643Srdivacky  return new (Importer.getToContext()) SizeOfAlignOfExpr(E->isSizeOf(),
2790204643Srdivacky                                                         SubExpr, ResultType,
2791204643Srdivacky                                          Importer.Import(E->getOperatorLoc()),
2792204643Srdivacky                                          Importer.Import(E->getRParenLoc()));
2793204643Srdivacky}
2794204643Srdivacky
2795204643SrdivackyExpr *ASTNodeImporter::VisitBinaryOperator(BinaryOperator *E) {
2796204643Srdivacky  QualType T = Importer.Import(E->getType());
2797204643Srdivacky  if (T.isNull())
2798204643Srdivacky    return 0;
2799204643Srdivacky
2800204643Srdivacky  Expr *LHS = Importer.Import(E->getLHS());
2801204643Srdivacky  if (!LHS)
2802204643Srdivacky    return 0;
2803204643Srdivacky
2804204643Srdivacky  Expr *RHS = Importer.Import(E->getRHS());
2805204643Srdivacky  if (!RHS)
2806204643Srdivacky    return 0;
2807204643Srdivacky
2808204643Srdivacky  return new (Importer.getToContext()) BinaryOperator(LHS, RHS, E->getOpcode(),
2809204643Srdivacky                                                      T,
2810204643Srdivacky                                          Importer.Import(E->getOperatorLoc()));
2811204643Srdivacky}
2812204643Srdivacky
2813204643SrdivackyExpr *ASTNodeImporter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
2814204643Srdivacky  QualType T = Importer.Import(E->getType());
2815204643Srdivacky  if (T.isNull())
2816204643Srdivacky    return 0;
2817204643Srdivacky
2818204643Srdivacky  QualType CompLHSType = Importer.Import(E->getComputationLHSType());
2819204643Srdivacky  if (CompLHSType.isNull())
2820204643Srdivacky    return 0;
2821204643Srdivacky
2822204643Srdivacky  QualType CompResultType = Importer.Import(E->getComputationResultType());
2823204643Srdivacky  if (CompResultType.isNull())
2824204643Srdivacky    return 0;
2825204643Srdivacky
2826204643Srdivacky  Expr *LHS = Importer.Import(E->getLHS());
2827204643Srdivacky  if (!LHS)
2828204643Srdivacky    return 0;
2829204643Srdivacky
2830204643Srdivacky  Expr *RHS = Importer.Import(E->getRHS());
2831204643Srdivacky  if (!RHS)
2832204643Srdivacky    return 0;
2833204643Srdivacky
2834204643Srdivacky  return new (Importer.getToContext())
2835204643Srdivacky                        CompoundAssignOperator(LHS, RHS, E->getOpcode(),
2836204643Srdivacky                                               T, CompLHSType, CompResultType,
2837204643Srdivacky                                          Importer.Import(E->getOperatorLoc()));
2838204643Srdivacky}
2839204643Srdivacky
2840203955SrdivackyExpr *ASTNodeImporter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
2841203955Srdivacky  QualType T = Importer.Import(E->getType());
2842203955Srdivacky  if (T.isNull())
2843203955Srdivacky    return 0;
2844203955Srdivacky
2845203955Srdivacky  Expr *SubExpr = Importer.Import(E->getSubExpr());
2846203955Srdivacky  if (!SubExpr)
2847203955Srdivacky    return 0;
2848203955Srdivacky
2849203955Srdivacky  return new (Importer.getToContext()) ImplicitCastExpr(T, E->getCastKind(),
2850203955Srdivacky                                                        SubExpr,
2851203955Srdivacky                                                        E->isLvalueCast());
2852203955Srdivacky}
2853203955Srdivacky
2854204643SrdivackyExpr *ASTNodeImporter::VisitCStyleCastExpr(CStyleCastExpr *E) {
2855204643Srdivacky  QualType T = Importer.Import(E->getType());
2856204643Srdivacky  if (T.isNull())
2857204643Srdivacky    return 0;
2858204643Srdivacky
2859204643Srdivacky  Expr *SubExpr = Importer.Import(E->getSubExpr());
2860204643Srdivacky  if (!SubExpr)
2861204643Srdivacky    return 0;
2862204643Srdivacky
2863204643Srdivacky  TypeSourceInfo *TInfo = Importer.Import(E->getTypeInfoAsWritten());
2864204643Srdivacky  if (!TInfo && E->getTypeInfoAsWritten())
2865204643Srdivacky    return 0;
2866204643Srdivacky
2867204643Srdivacky  return new (Importer.getToContext()) CStyleCastExpr(T, E->getCastKind(),
2868204643Srdivacky                                                      SubExpr, TInfo,
2869204643Srdivacky                                            Importer.Import(E->getLParenLoc()),
2870204643Srdivacky                                            Importer.Import(E->getRParenLoc()));
2871204643Srdivacky}
2872204643Srdivacky
2873203955SrdivackyASTImporter::ASTImporter(Diagnostic &Diags,
2874203955Srdivacky                         ASTContext &ToContext, FileManager &ToFileManager,
2875203955Srdivacky                         ASTContext &FromContext, FileManager &FromFileManager)
2876203955Srdivacky  : ToContext(ToContext), FromContext(FromContext),
2877203955Srdivacky    ToFileManager(ToFileManager), FromFileManager(FromFileManager),
2878203955Srdivacky    Diags(Diags) {
2879203955Srdivacky  ImportedDecls[FromContext.getTranslationUnitDecl()]
2880203955Srdivacky    = ToContext.getTranslationUnitDecl();
2881203955Srdivacky}
2882203955Srdivacky
2883203955SrdivackyASTImporter::~ASTImporter() { }
2884203955Srdivacky
2885203955SrdivackyQualType ASTImporter::Import(QualType FromT) {
2886203955Srdivacky  if (FromT.isNull())
2887203955Srdivacky    return QualType();
2888203955Srdivacky
2889203955Srdivacky  // Check whether we've already imported this type.
2890203955Srdivacky  llvm::DenseMap<Type *, Type *>::iterator Pos
2891203955Srdivacky    = ImportedTypes.find(FromT.getTypePtr());
2892203955Srdivacky  if (Pos != ImportedTypes.end())
2893203955Srdivacky    return ToContext.getQualifiedType(Pos->second, FromT.getQualifiers());
2894203955Srdivacky
2895203955Srdivacky  // Import the type
2896203955Srdivacky  ASTNodeImporter Importer(*this);
2897203955Srdivacky  QualType ToT = Importer.Visit(FromT.getTypePtr());
2898203955Srdivacky  if (ToT.isNull())
2899203955Srdivacky    return ToT;
2900203955Srdivacky
2901203955Srdivacky  // Record the imported type.
2902203955Srdivacky  ImportedTypes[FromT.getTypePtr()] = ToT.getTypePtr();
2903203955Srdivacky
2904203955Srdivacky  return ToContext.getQualifiedType(ToT, FromT.getQualifiers());
2905203955Srdivacky}
2906203955Srdivacky
2907203955SrdivackyTypeSourceInfo *ASTImporter::Import(TypeSourceInfo *FromTSI) {
2908203955Srdivacky  if (!FromTSI)
2909203955Srdivacky    return FromTSI;
2910203955Srdivacky
2911203955Srdivacky  // FIXME: For now we just create a "trivial" type source info based
2912203955Srdivacky  // on the type and a seingle location. Implement a real version of
2913203955Srdivacky  // this.
2914203955Srdivacky  QualType T = Import(FromTSI->getType());
2915203955Srdivacky  if (T.isNull())
2916203955Srdivacky    return 0;
2917203955Srdivacky
2918203955Srdivacky  return ToContext.getTrivialTypeSourceInfo(T,
2919203955Srdivacky                        FromTSI->getTypeLoc().getFullSourceRange().getBegin());
2920203955Srdivacky}
2921203955Srdivacky
2922203955SrdivackyDecl *ASTImporter::Import(Decl *FromD) {
2923203955Srdivacky  if (!FromD)
2924203955Srdivacky    return 0;
2925203955Srdivacky
2926203955Srdivacky  // Check whether we've already imported this declaration.
2927203955Srdivacky  llvm::DenseMap<Decl *, Decl *>::iterator Pos = ImportedDecls.find(FromD);
2928203955Srdivacky  if (Pos != ImportedDecls.end())
2929203955Srdivacky    return Pos->second;
2930203955Srdivacky
2931203955Srdivacky  // Import the type
2932203955Srdivacky  ASTNodeImporter Importer(*this);
2933203955Srdivacky  Decl *ToD = Importer.Visit(FromD);
2934203955Srdivacky  if (!ToD)
2935203955Srdivacky    return 0;
2936203955Srdivacky
2937203955Srdivacky  // Record the imported declaration.
2938203955Srdivacky  ImportedDecls[FromD] = ToD;
2939203955Srdivacky
2940203955Srdivacky  if (TagDecl *FromTag = dyn_cast<TagDecl>(FromD)) {
2941203955Srdivacky    // Keep track of anonymous tags that have an associated typedef.
2942203955Srdivacky    if (FromTag->getTypedefForAnonDecl())
2943203955Srdivacky      AnonTagsWithPendingTypedefs.push_back(FromTag);
2944203955Srdivacky  } else if (TypedefDecl *FromTypedef = dyn_cast<TypedefDecl>(FromD)) {
2945203955Srdivacky    // When we've finished transforming a typedef, see whether it was the
2946203955Srdivacky    // typedef for an anonymous tag.
2947203955Srdivacky    for (llvm::SmallVector<TagDecl *, 4>::iterator
2948203955Srdivacky               FromTag = AnonTagsWithPendingTypedefs.begin(),
2949203955Srdivacky            FromTagEnd = AnonTagsWithPendingTypedefs.end();
2950203955Srdivacky         FromTag != FromTagEnd; ++FromTag) {
2951203955Srdivacky      if ((*FromTag)->getTypedefForAnonDecl() == FromTypedef) {
2952203955Srdivacky        if (TagDecl *ToTag = cast_or_null<TagDecl>(Import(*FromTag))) {
2953203955Srdivacky          // We found the typedef for an anonymous tag; link them.
2954203955Srdivacky          ToTag->setTypedefForAnonDecl(cast<TypedefDecl>(ToD));
2955203955Srdivacky          AnonTagsWithPendingTypedefs.erase(FromTag);
2956203955Srdivacky          break;
2957203955Srdivacky        }
2958203955Srdivacky      }
2959203955Srdivacky    }
2960203955Srdivacky  }
2961203955Srdivacky
2962203955Srdivacky  return ToD;
2963203955Srdivacky}
2964203955Srdivacky
2965203955SrdivackyDeclContext *ASTImporter::ImportContext(DeclContext *FromDC) {
2966203955Srdivacky  if (!FromDC)
2967203955Srdivacky    return FromDC;
2968203955Srdivacky
2969203955Srdivacky  return cast_or_null<DeclContext>(Import(cast<Decl>(FromDC)));
2970203955Srdivacky}
2971203955Srdivacky
2972203955SrdivackyExpr *ASTImporter::Import(Expr *FromE) {
2973203955Srdivacky  if (!FromE)
2974203955Srdivacky    return 0;
2975203955Srdivacky
2976203955Srdivacky  return cast_or_null<Expr>(Import(cast<Stmt>(FromE)));
2977203955Srdivacky}
2978203955Srdivacky
2979203955SrdivackyStmt *ASTImporter::Import(Stmt *FromS) {
2980203955Srdivacky  if (!FromS)
2981203955Srdivacky    return 0;
2982203955Srdivacky
2983203955Srdivacky  // Check whether we've already imported this declaration.
2984203955Srdivacky  llvm::DenseMap<Stmt *, Stmt *>::iterator Pos = ImportedStmts.find(FromS);
2985203955Srdivacky  if (Pos != ImportedStmts.end())
2986203955Srdivacky    return Pos->second;
2987203955Srdivacky
2988203955Srdivacky  // Import the type
2989203955Srdivacky  ASTNodeImporter Importer(*this);
2990203955Srdivacky  Stmt *ToS = Importer.Visit(FromS);
2991203955Srdivacky  if (!ToS)
2992203955Srdivacky    return 0;
2993203955Srdivacky
2994203955Srdivacky  // Record the imported declaration.
2995203955Srdivacky  ImportedStmts[FromS] = ToS;
2996203955Srdivacky  return ToS;
2997203955Srdivacky}
2998203955Srdivacky
2999203955SrdivackyNestedNameSpecifier *ASTImporter::Import(NestedNameSpecifier *FromNNS) {
3000203955Srdivacky  if (!FromNNS)
3001203955Srdivacky    return 0;
3002203955Srdivacky
3003203955Srdivacky  // FIXME: Implement!
3004203955Srdivacky  return 0;
3005203955Srdivacky}
3006203955Srdivacky
3007203955SrdivackySourceLocation ASTImporter::Import(SourceLocation FromLoc) {
3008203955Srdivacky  if (FromLoc.isInvalid())
3009203955Srdivacky    return SourceLocation();
3010203955Srdivacky
3011203955Srdivacky  SourceManager &FromSM = FromContext.getSourceManager();
3012203955Srdivacky
3013203955Srdivacky  // For now, map everything down to its spelling location, so that we
3014203955Srdivacky  // don't have to import macro instantiations.
3015203955Srdivacky  // FIXME: Import macro instantiations!
3016203955Srdivacky  FromLoc = FromSM.getSpellingLoc(FromLoc);
3017203955Srdivacky  std::pair<FileID, unsigned> Decomposed = FromSM.getDecomposedLoc(FromLoc);
3018203955Srdivacky  SourceManager &ToSM = ToContext.getSourceManager();
3019203955Srdivacky  return ToSM.getLocForStartOfFile(Import(Decomposed.first))
3020203955Srdivacky             .getFileLocWithOffset(Decomposed.second);
3021203955Srdivacky}
3022203955Srdivacky
3023203955SrdivackySourceRange ASTImporter::Import(SourceRange FromRange) {
3024203955Srdivacky  return SourceRange(Import(FromRange.getBegin()), Import(FromRange.getEnd()));
3025203955Srdivacky}
3026203955Srdivacky
3027203955SrdivackyFileID ASTImporter::Import(FileID FromID) {
3028203955Srdivacky  llvm::DenseMap<unsigned, FileID>::iterator Pos
3029203955Srdivacky    = ImportedFileIDs.find(FromID.getHashValue());
3030203955Srdivacky  if (Pos != ImportedFileIDs.end())
3031203955Srdivacky    return Pos->second;
3032203955Srdivacky
3033203955Srdivacky  SourceManager &FromSM = FromContext.getSourceManager();
3034203955Srdivacky  SourceManager &ToSM = ToContext.getSourceManager();
3035203955Srdivacky  const SrcMgr::SLocEntry &FromSLoc = FromSM.getSLocEntry(FromID);
3036203955Srdivacky  assert(FromSLoc.isFile() && "Cannot handle macro instantiations yet");
3037203955Srdivacky
3038203955Srdivacky  // Include location of this file.
3039203955Srdivacky  SourceLocation ToIncludeLoc = Import(FromSLoc.getFile().getIncludeLoc());
3040203955Srdivacky
3041203955Srdivacky  // Map the FileID for to the "to" source manager.
3042203955Srdivacky  FileID ToID;
3043203955Srdivacky  const SrcMgr::ContentCache *Cache = FromSLoc.getFile().getContentCache();
3044203955Srdivacky  if (Cache->Entry) {
3045203955Srdivacky    // FIXME: We probably want to use getVirtualFile(), so we don't hit the
3046203955Srdivacky    // disk again
3047203955Srdivacky    // FIXME: We definitely want to re-use the existing MemoryBuffer, rather
3048203955Srdivacky    // than mmap the files several times.
3049203955Srdivacky    const FileEntry *Entry = ToFileManager.getFile(Cache->Entry->getName());
3050203955Srdivacky    ToID = ToSM.createFileID(Entry, ToIncludeLoc,
3051203955Srdivacky                             FromSLoc.getFile().getFileCharacteristic());
3052203955Srdivacky  } else {
3053203955Srdivacky    // FIXME: We want to re-use the existing MemoryBuffer!
3054203955Srdivacky    const llvm::MemoryBuffer *FromBuf = Cache->getBuffer();
3055203955Srdivacky    llvm::MemoryBuffer *ToBuf
3056203955Srdivacky      = llvm::MemoryBuffer::getMemBufferCopy(FromBuf->getBufferStart(),
3057203955Srdivacky                                             FromBuf->getBufferEnd(),
3058203955Srdivacky                                             FromBuf->getBufferIdentifier());
3059203955Srdivacky    ToID = ToSM.createFileIDForMemBuffer(ToBuf);
3060203955Srdivacky  }
3061203955Srdivacky
3062203955Srdivacky
3063203955Srdivacky  ImportedFileIDs[FromID.getHashValue()] = ToID;
3064203955Srdivacky  return ToID;
3065203955Srdivacky}
3066203955Srdivacky
3067203955SrdivackyDeclarationName ASTImporter::Import(DeclarationName FromName) {
3068203955Srdivacky  if (!FromName)
3069203955Srdivacky    return DeclarationName();
3070203955Srdivacky
3071203955Srdivacky  switch (FromName.getNameKind()) {
3072203955Srdivacky  case DeclarationName::Identifier:
3073203955Srdivacky    return Import(FromName.getAsIdentifierInfo());
3074203955Srdivacky
3075203955Srdivacky  case DeclarationName::ObjCZeroArgSelector:
3076203955Srdivacky  case DeclarationName::ObjCOneArgSelector:
3077203955Srdivacky  case DeclarationName::ObjCMultiArgSelector:
3078203955Srdivacky    return Import(FromName.getObjCSelector());
3079203955Srdivacky
3080203955Srdivacky  case DeclarationName::CXXConstructorName: {
3081203955Srdivacky    QualType T = Import(FromName.getCXXNameType());
3082203955Srdivacky    if (T.isNull())
3083203955Srdivacky      return DeclarationName();
3084203955Srdivacky
3085203955Srdivacky    return ToContext.DeclarationNames.getCXXConstructorName(
3086203955Srdivacky                                               ToContext.getCanonicalType(T));
3087203955Srdivacky  }
3088203955Srdivacky
3089203955Srdivacky  case DeclarationName::CXXDestructorName: {
3090203955Srdivacky    QualType T = Import(FromName.getCXXNameType());
3091203955Srdivacky    if (T.isNull())
3092203955Srdivacky      return DeclarationName();
3093203955Srdivacky
3094203955Srdivacky    return ToContext.DeclarationNames.getCXXDestructorName(
3095203955Srdivacky                                               ToContext.getCanonicalType(T));
3096203955Srdivacky  }
3097203955Srdivacky
3098203955Srdivacky  case DeclarationName::CXXConversionFunctionName: {
3099203955Srdivacky    QualType T = Import(FromName.getCXXNameType());
3100203955Srdivacky    if (T.isNull())
3101203955Srdivacky      return DeclarationName();
3102203955Srdivacky
3103203955Srdivacky    return ToContext.DeclarationNames.getCXXConversionFunctionName(
3104203955Srdivacky                                               ToContext.getCanonicalType(T));
3105203955Srdivacky  }
3106203955Srdivacky
3107203955Srdivacky  case DeclarationName::CXXOperatorName:
3108203955Srdivacky    return ToContext.DeclarationNames.getCXXOperatorName(
3109203955Srdivacky                                          FromName.getCXXOverloadedOperator());
3110203955Srdivacky
3111203955Srdivacky  case DeclarationName::CXXLiteralOperatorName:
3112203955Srdivacky    return ToContext.DeclarationNames.getCXXLiteralOperatorName(
3113203955Srdivacky                                   Import(FromName.getCXXLiteralIdentifier()));
3114203955Srdivacky
3115203955Srdivacky  case DeclarationName::CXXUsingDirective:
3116203955Srdivacky    // FIXME: STATICS!
3117203955Srdivacky    return DeclarationName::getUsingDirectiveName();
3118203955Srdivacky  }
3119203955Srdivacky
3120203955Srdivacky  // Silence bogus GCC warning
3121203955Srdivacky  return DeclarationName();
3122203955Srdivacky}
3123203955Srdivacky
3124203955SrdivackyIdentifierInfo *ASTImporter::Import(IdentifierInfo *FromId) {
3125203955Srdivacky  if (!FromId)
3126203955Srdivacky    return 0;
3127203955Srdivacky
3128203955Srdivacky  return &ToContext.Idents.get(FromId->getName());
3129203955Srdivacky}
3130203955Srdivacky
3131204643SrdivackySelector ASTImporter::Import(Selector FromSel) {
3132204643Srdivacky  if (FromSel.isNull())
3133204643Srdivacky    return Selector();
3134204643Srdivacky
3135204643Srdivacky  llvm::SmallVector<IdentifierInfo *, 4> Idents;
3136204643Srdivacky  Idents.push_back(Import(FromSel.getIdentifierInfoForSlot(0)));
3137204643Srdivacky  for (unsigned I = 1, N = FromSel.getNumArgs(); I < N; ++I)
3138204643Srdivacky    Idents.push_back(Import(FromSel.getIdentifierInfoForSlot(I)));
3139204643Srdivacky  return ToContext.Selectors.getSelector(FromSel.getNumArgs(), Idents.data());
3140204643Srdivacky}
3141204643Srdivacky
3142203955SrdivackyDeclarationName ASTImporter::HandleNameConflict(DeclarationName Name,
3143203955Srdivacky                                                DeclContext *DC,
3144203955Srdivacky                                                unsigned IDNS,
3145203955Srdivacky                                                NamedDecl **Decls,
3146203955Srdivacky                                                unsigned NumDecls) {
3147203955Srdivacky  return Name;
3148203955Srdivacky}
3149203955Srdivacky
3150203955SrdivackyDiagnosticBuilder ASTImporter::ToDiag(SourceLocation Loc, unsigned DiagID) {
3151203955Srdivacky  return Diags.Report(FullSourceLoc(Loc, ToContext.getSourceManager()),
3152203955Srdivacky                      DiagID);
3153203955Srdivacky}
3154203955Srdivacky
3155203955SrdivackyDiagnosticBuilder ASTImporter::FromDiag(SourceLocation Loc, unsigned DiagID) {
3156203955Srdivacky  return Diags.Report(FullSourceLoc(Loc, FromContext.getSourceManager()),
3157203955Srdivacky                      DiagID);
3158203955Srdivacky}
3159203955Srdivacky
3160203955SrdivackyDecl *ASTImporter::Imported(Decl *From, Decl *To) {
3161203955Srdivacky  ImportedDecls[From] = To;
3162203955Srdivacky  return To;
3163203955Srdivacky}
3164203955Srdivacky
3165203955Srdivackybool ASTImporter::IsStructurallyEquivalent(QualType From, QualType To) {
3166203955Srdivacky  llvm::DenseMap<Type *, Type *>::iterator Pos
3167203955Srdivacky   = ImportedTypes.find(From.getTypePtr());
3168203955Srdivacky  if (Pos != ImportedTypes.end() && ToContext.hasSameType(Import(From), To))
3169203955Srdivacky    return true;
3170203955Srdivacky
3171204643Srdivacky  StructuralEquivalenceContext Ctx(FromContext, ToContext, Diags,
3172203955Srdivacky                                   NonEquivalentDecls);
3173204643Srdivacky  return Ctx.IsStructurallyEquivalent(From, To);
3174203955Srdivacky}
3175