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