Index: include/clang/AST/ASTImporter.h =================================================================== --- include/clang/AST/ASTImporter.h +++ include/clang/AST/ASTImporter.h @@ -23,6 +23,7 @@ namespace clang { class ASTContext; + class CXXBaseSpecifier; class Decl; class DeclContext; class DiagnosticsEngine; @@ -38,7 +39,9 @@ class ASTImporter { public: typedef llvm::DenseSet > NonEquivalentDeclSet; - + typedef llvm::DenseMap + ImportedCXXBaseSpecifierMap; + private: /// \brief The contexts we're importing to and from. ASTContext &ToContext, &FromContext; @@ -67,7 +70,12 @@ /// \brief Mapping from the already-imported FileIDs in the "from" source /// manager to the corresponding FileIDs in the "to" source manager. llvm::DenseMap ImportedFileIDs; - + + /// \brief Mapping from the already-imported CXXBasesSpecifier in + /// the "from" source manager to the corresponding CXXBasesSpecifier + /// in the "to" source manager. + ImportedCXXBaseSpecifierMap ImportedCXXBaseSpecifiers; + /// \brief Imported, anonymous tag declarations that are missing their /// corresponding typedefs. SmallVector AnonTagsWithPendingTypedefs; @@ -204,7 +212,14 @@ /// \returns the equivalent file ID in the source manager of the "to" /// context. FileID Import(FileID); - + + /// \brief Import the given CXXBaseSpecifier from the "from" context into + /// the "to" context. + /// + /// \returns the equivalent CXXBaseSpecifier in the source manager of the + /// "to" context. + CXXBaseSpecifier *Import(const CXXBaseSpecifier *FromSpec); + /// \brief Import the definition of the given declaration, including all of /// the declarations it contains. /// Index: lib/AST/ASTImporter.cpp =================================================================== --- lib/AST/ASTImporter.cpp +++ lib/AST/ASTImporter.cpp @@ -109,6 +109,8 @@ DeclarationNameInfo& To); void ImportDeclContext(DeclContext *FromDC, bool ForceImport = false); + bool ImportCastPath(CastExpr *E, CXXCastPath &Path); + typedef DesignatedInitExpr::Designator Designator; Designator ImportDesignator(const Designator &D); @@ -261,9 +263,23 @@ Expr *VisitBinaryOperator(BinaryOperator *E); Expr *VisitConditionalOperator(ConditionalOperator *E); Expr *VisitBinaryConditionalOperator(BinaryConditionalOperator *E); + Expr *VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E); + Expr *VisitExpressionTraitExpr(ExpressionTraitExpr *E); + Expr *VisitOpaqueValueExpr(OpaqueValueExpr *E); + Expr *VisitArraySubscriptExpr(ArraySubscriptExpr *E); Expr *VisitCompoundAssignOperator(CompoundAssignOperator *E); Expr *VisitImplicitCastExpr(ImplicitCastExpr *E); - Expr *VisitCStyleCastExpr(CStyleCastExpr *E); + Expr *VisitExplicitCastExpr(ExplicitCastExpr *E); + Expr *VisitImplicitValueInitExpr(ImplicitValueInitExpr *E); + Expr *VisitOffsetOfExpr(OffsetOfExpr *E); + Expr *VisitCXXThisExpr(CXXThisExpr *E); + Expr *VisitCXXThrowExpr(CXXThrowExpr *E); + Expr *VisitCXXNoexceptExpr(CXXNoexceptExpr *E); + Expr *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E); + Expr *VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E); + Expr *VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E); + Expr *VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *CE); + Expr *VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E); Expr *VisitCXXConstructExpr(CXXConstructExpr *E); Expr *VisitMemberExpr(MemberExpr *E); Expr *VisitCallExpr(CallExpr *E); @@ -5581,6 +5597,70 @@ T, E->getValueKind(), E->getObjectKind()); } +Expr *ASTNodeImporter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + TypeSourceInfo *ToQueried = Importer.Import(E->getQueriedTypeSourceInfo()); + if (!ToQueried) + return nullptr; + + Expr *Dim = Importer.Import(E->getDimensionExpression()); + if (!Dim && E->getDimensionExpression()) + return nullptr; + + return new (Importer.getToContext()) ArrayTypeTraitExpr( + Importer.Import(E->getExprLoc()), E->getTrait(), ToQueried, + E->getValue(), Dim, Importer.Import(E->getLocEnd()), T); +} + +Expr *ASTNodeImporter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + Expr *ToQueried = Importer.Import(E->getQueriedExpression()); + if (!ToQueried) + return nullptr; + + return new (Importer.getToContext()) ExpressionTraitExpr( + Importer.Import(E->getExprLoc()), E->getTrait(), ToQueried, + E->getValue(), Importer.Import(E->getLocEnd()), T); +} + +Expr *ASTNodeImporter::VisitOpaqueValueExpr(OpaqueValueExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + Expr *SourceExpr = Importer.Import(E->getSourceExpr()); + if (!SourceExpr && E->getSourceExpr()) + return nullptr; + + return new (Importer.getToContext()) OpaqueValueExpr( + Importer.Import(E->getExprLoc()), T, E->getValueKind(), + E->getObjectKind(), SourceExpr); +} + +Expr *ASTNodeImporter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + Expr *ToLHS = Importer.Import(E->getLHS()); + if (!ToLHS) + return nullptr; + + Expr *ToRHS = Importer.Import(E->getRHS()); + if (!ToRHS) + return nullptr; + + return new (Importer.getToContext()) ArraySubscriptExpr( + ToLHS, ToRHS, T, E->getValueKind(), E->getObjectKind(), + Importer.Import(E->getRBracketLoc())); +} + Expr *ASTNodeImporter::VisitCompoundAssignOperator(CompoundAssignOperator *E) { QualType T = Importer.Import(E->getType()); if (T.isNull()) @@ -5611,11 +5691,14 @@ E->isFPContractable()); } -static bool ImportCastPath(CastExpr *E, CXXCastPath &Path) { - if (E->path_empty()) return false; - - // TODO: import cast paths - return true; +bool ASTNodeImporter::ImportCastPath(CastExpr *CE, CXXCastPath &Path) { + for (auto I = CE->path_begin(), E = CE->path_end(); I != E; ++I) { + if (CXXBaseSpecifier *Spec = Importer.Import(*I)) + Path.push_back(Spec); + else + return true; + } + return false; } Expr *ASTNodeImporter::VisitImplicitCastExpr(ImplicitCastExpr *E) { @@ -5635,7 +5718,7 @@ SubExpr, &BasePath, E->getValueKind()); } -Expr *ASTNodeImporter::VisitCStyleCastExpr(CStyleCastExpr *E) { +Expr *ASTNodeImporter::VisitExplicitCastExpr(ExplicitCastExpr *E) { QualType T = Importer.Import(E->getType()); if (T.isNull()) return nullptr; @@ -5652,11 +5735,272 @@ if (ImportCastPath(E, BasePath)) return nullptr; - return CStyleCastExpr::Create(Importer.getToContext(), T, - E->getValueKind(), E->getCastKind(), - SubExpr, &BasePath, TInfo, - Importer.Import(E->getLParenLoc()), - Importer.Import(E->getRParenLoc())); + switch (E->getStmtClass()) { + case Stmt::CStyleCastExprClass: { + CStyleCastExpr *CCE = cast(E); + return CStyleCastExpr::Create(Importer.getToContext(), T, + E->getValueKind(), E->getCastKind(), + SubExpr, &BasePath, TInfo, + Importer.Import(CCE->getLParenLoc()), + Importer.Import(CCE->getRParenLoc())); + } + + case Stmt::CXXFunctionalCastExprClass: { + CXXFunctionalCastExpr *FCE = cast(E); + return CXXFunctionalCastExpr::Create(Importer.getToContext(), T, + E->getValueKind(), TInfo, + E->getCastKind(), SubExpr, &BasePath, + Importer.Import(FCE->getLParenLoc()), + Importer.Import(FCE->getRParenLoc())); + } + + case Stmt::ObjCBridgedCastExprClass: { + ObjCBridgedCastExpr *OCE = cast(E); + return new (Importer.getToContext()) ObjCBridgedCastExpr( + Importer.Import(OCE->getLParenLoc()), OCE->getBridgeKind(), + E->getCastKind(), Importer.Import(OCE->getBridgeKeywordLoc()), + TInfo, SubExpr); + } + default: + break; // just fall through + } + + CXXNamedCastExpr *Named = cast(E); + SourceLocation ExprLoc = Importer.Import(Named->getExprLoc()), + RParenLoc = Importer.Import(Named->getRParenLoc()); + SourceRange Brackets = Importer.Import(Named->getAngleBrackets()); + + switch (E->getStmtClass()) { + case Stmt::CXXStaticCastExprClass: + return CXXStaticCastExpr::Create(Importer.getToContext(), T, + E->getValueKind(), E->getCastKind(), + SubExpr, &BasePath, TInfo, + ExprLoc, RParenLoc, Brackets); + + case Stmt::CXXDynamicCastExprClass: + return CXXDynamicCastExpr::Create(Importer.getToContext(), T, + E->getValueKind(), E->getCastKind(), + SubExpr, &BasePath, TInfo, + ExprLoc, RParenLoc, Brackets); + + case Stmt::CXXReinterpretCastExprClass: + return CXXReinterpretCastExpr::Create(Importer.getToContext(), T, + E->getValueKind(), E->getCastKind(), + SubExpr, &BasePath, TInfo, + ExprLoc, RParenLoc, Brackets); + + case Stmt::CXXConstCastExprClass: + return CXXConstCastExpr::Create(Importer.getToContext(), T, + E->getValueKind(), SubExpr, TInfo, ExprLoc, + RParenLoc, Brackets); + default: + llvm_unreachable("Cast expression of unsupported type!"); + return nullptr; + } +} + +Expr *ASTNodeImporter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + return new (Importer.getToContext()) ImplicitValueInitExpr(T); +} + + +Expr *ASTNodeImporter::VisitOffsetOfExpr(OffsetOfExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + SmallVector Nodes; + for (int i = 0, e = E->getNumComponents(); i < e; ++i) { + const OffsetOfExpr::OffsetOfNode &Node = E->getComponent(i); + switch (Node.getKind()) { + case OffsetOfExpr::OffsetOfNode::Array: + Nodes.push_back(OffsetOfExpr::OffsetOfNode( + Importer.Import(Node.getLocStart()), + Node.getArrayExprIndex(), + Importer.Import(Node.getLocEnd()))); + break; + case OffsetOfExpr::OffsetOfNode::Base: { + CXXBaseSpecifier *BS = Importer.Import(Node.getBase()); + if (!BS && Node.getBase()) + return nullptr; + Nodes.push_back(OffsetOfExpr::OffsetOfNode(BS)); + break; + } + case OffsetOfExpr::OffsetOfNode::Field: { + FieldDecl *FD = cast_or_null(Importer.Import(Node.getField())); + if (!FD) + return nullptr; + Nodes.push_back(OffsetOfExpr::OffsetOfNode( + Importer.Import(Node.getLocStart()), FD, + Importer.Import(Node.getLocEnd()))); + break; + } + case OffsetOfExpr::OffsetOfNode::Identifier: { + IdentifierInfo *ToII = Importer.Import(Node.getFieldName()); + if (ToII) + return nullptr; + Nodes.push_back(OffsetOfExpr::OffsetOfNode( + Importer.Import(Node.getLocStart()), ToII, + Importer.Import(Node.getLocEnd()))); + break; + } + } + } + + SmallVector Exprs(E->getNumExpressions()); + for (int i = 0, e = E->getNumExpressions(); i < e; ++i) { + Expr *ToIndexExpr = Importer.Import(E->getIndexExpr(i)); + if (!ToIndexExpr) + return nullptr; + Exprs[i] = ToIndexExpr; + } + + TypeSourceInfo *TInfo = Importer.Import(E->getTypeSourceInfo()); + if (!TInfo && E->getTypeSourceInfo()) + return nullptr; + + return OffsetOfExpr::Create(Importer.getToContext(), T, + Importer.Import(E->getOperatorLoc()), + TInfo, Nodes, Exprs, + Importer.Import(E->getRParenLoc())); +} + +Expr *ASTNodeImporter::VisitCXXThisExpr(CXXThisExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + return new (Importer.getToContext()) CXXThisExpr( + Importer.Import(E->getExprLoc()), T, E->isImplicit()); +} + +Expr *ASTNodeImporter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + Expr *Operand = Importer.Import(E->getOperand()); + if (!Operand) + return nullptr; + + // We cannot get source CanThrowVal so correction is required after init + CXXNoexceptExpr *ToE = new (Importer.getToContext()) CXXNoexceptExpr( + T, Operand, E->getValue() ? CT_Cannot : CT_Dependent, + Importer.Import(E->getLocStart()), Importer.Import(E->getLocEnd())); + ToE->setInstantiationDependent(E->isInstantiationDependent()); + ToE->setValueDependent(E->isValueDependent()); + return ToE; +} + +Expr *ASTNodeImporter::VisitCXXThrowExpr(CXXThrowExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + Expr *SubExpr = Importer.Import(E->getSubExpr()); + if (!SubExpr && E->getSubExpr()) + return nullptr; + + return new (Importer.getToContext()) CXXThrowExpr( + SubExpr, T, Importer.Import(E->getExprLoc()), + E->isThrownVariableInScope()); +} + +Expr *ASTNodeImporter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { + ParmVarDecl *Param = cast_or_null(Importer.Import(E->getParam())); + if (!Param && E->getParam()) + return nullptr; + + Expr *SubExpr = Importer.Import(E->getExpr()); + if (!SubExpr && E->getExpr()) + return nullptr; + + return CXXDefaultArgExpr::Create( + Importer.getToContext(), Importer.Import(E->getExprLoc()), + Param, SubExpr); +} + +Expr *ASTNodeImporter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + TypeSourceInfo *TypeInfo = Importer.Import(E->getTypeSourceInfo()); + if (!TypeInfo) + return nullptr; + + return new (Importer.getToContext()) CXXScalarValueInitExpr( + T, TypeInfo, Importer.Import(E->getRParenLoc())); +} + +Expr *ASTNodeImporter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) { + Expr *SubExpr = Importer.Import(E->getSubExpr()); + if (!SubExpr) + return nullptr; + + auto *Dtor = cast_or_null( + Importer.Import(const_cast( + E->getTemporary()->getDestructor()))); + if (!Dtor) + return nullptr; + + ASTContext &ToCtx = Importer.getToContext(); + CXXTemporary *Temp = CXXTemporary::Create(ToCtx, Dtor); + return CXXBindTemporaryExpr::Create(ToCtx, Temp, SubExpr); +} + +Expr *ASTNodeImporter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *CE) { + QualType T = Importer.Import(CE->getType()); + if (T.isNull()) + return nullptr; + + SmallVector Args(CE->getNumArgs()); + ImportMultipleItems(CE->arg_begin(), CE->arg_end(), Args.begin()); + if (!checkNull(Args.begin(), Args.end())) + return nullptr; + + auto *Ctor = cast_or_null( + Importer.Import(CE->getConstructor())); + if (!Ctor) + return nullptr; + + return CXXTemporaryObjectExpr::Create( + Importer.getToContext(), T, + Importer.Import(CE->getExprLoc()), + Ctor, + CE->isElidable(), + Args, + CE->hadMultipleCandidates(), + CE->isListInitialization(), + CE->isStdInitListInitialization(), + CE->requiresZeroInitialization(), + CE->getConstructionKind(), + Importer.Import(CE->getParenOrBraceRange())); +} + +Expr * +ASTNodeImporter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + Expr *TempE = Importer.Import(E->GetTemporaryExpr()); + if (!TempE) + return nullptr; + + ValueDecl *ExtendedBy = cast_or_null( + Importer.Import(const_cast(E->getExtendingDecl()))); + if (!ExtendedBy && E->getExtendingDecl()) + return nullptr; + + auto *ToMTE = new (Importer.getToContext()) MaterializeTemporaryExpr( + T, TempE, E->isBoundToLvalueReference()); + ToMTE->setExtendingDecl(ExtendedBy, E->getManglingNumber()); + return ToMTE; } Expr *ASTNodeImporter::VisitCXXConstructExpr(CXXConstructExpr *E) { @@ -6165,6 +6509,21 @@ return ToID; } +CXXBaseSpecifier *ASTImporter::Import(const CXXBaseSpecifier *BaseSpec) { + auto Pos = ImportedCXXBaseSpecifiers.find(BaseSpec); + if (Pos != ImportedCXXBaseSpecifiers.end()) + return Pos->second; + + CXXBaseSpecifier *Imported = new (ToContext) CXXBaseSpecifier( + Import(BaseSpec->getSourceRange()), + BaseSpec->isVirtual(), BaseSpec->isBaseOfClass(), + BaseSpec->getAccessSpecifierAsWritten(), + Import(BaseSpec->getTypeSourceInfo()), + Import(BaseSpec->getEllipsisLoc())); + ImportedCXXBaseSpecifiers[BaseSpec] = Imported; + return Imported; +} + void ASTImporter::ImportDefinition(Decl *From) { Decl *To = Import(From); if (!To)