diff options
author | Artem Dergachev <artem.dergachev@gmail.com> | 2016-04-14 11:51:27 +0000 |
---|---|---|
committer | Artem Dergachev <artem.dergachev@gmail.com> | 2016-04-14 11:51:27 +0000 |
commit | 4e7c6fdeeb89d223258f5f68ece38764f332b295 (patch) | |
tree | 6eb4d7cbeb0f12b154ae64d2a1147cc41ba159d8 /clang/lib/AST/ASTImporter.cpp | |
parent | 909d080d98acf3508b3e8d76b2c2b3371e17f618 (diff) | |
download | bcm5719-llvm-4e7c6fdeeb89d223258f5f68ece38764f332b295.tar.gz bcm5719-llvm-4e7c6fdeeb89d223258f5f68ece38764f332b295.zip |
[ASTImporter] Implement some expression-related AST node import.
Introduce ASTImporter unit test framework.
Fix a memory leak introduced in cf8ccff5: an array is allocated
in ImportArray and never freed.
Support new node kinds:
- GCCAsmStmt
- AddrLabelExpr
- AtomicExpr
- CompoundLiteralExpr
- CXXBoolLiteralExpr
- CXXNullPtrLiteralExpr
- CXXThisExpr
- DesignatedInitExpr
- GNUNullExpr
- ImplicitValueInitExpr
- InitListExpr
- OpaqueValueExpr
- PredefinedExpr
- ParenListExpr
- StmtExpr
- VAArgExpr
- BinaryConditionalOperator
- ConditionalOperator
- FloatingLiteral
- StringLiteral
- InjectedClassNameType
- TemplateTypeParmType
- LabelDecl
Patch by Aleksei Sidorin!
Differential Revision: http://reviews.llvm.org/D14286
llvm-svn: 266292
Diffstat (limited to 'clang/lib/AST/ASTImporter.cpp')
-rw-r--r-- | clang/lib/AST/ASTImporter.cpp | 581 |
1 files changed, 522 insertions, 59 deletions
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 484a4459395..747f9fc9bde 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -29,7 +29,7 @@ namespace clang { public DeclVisitor<ASTNodeImporter, Decl *>, public StmtVisitor<ASTNodeImporter, Stmt *> { ASTImporter &Importer; - + public: explicit ASTNodeImporter(ASTImporter &Importer) : Importer(Importer) { } @@ -64,11 +64,12 @@ namespace clang { QualType VisitDecltypeType(const DecltypeType *T); QualType VisitUnaryTransformType(const UnaryTransformType *T); QualType VisitAutoType(const AutoType *T); + QualType VisitInjectedClassNameType(const InjectedClassNameType *T); // FIXME: DependentDecltypeType QualType VisitRecordType(const RecordType *T); QualType VisitEnumType(const EnumType *T); QualType VisitAttributedType(const AttributedType *T); - // FIXME: TemplateTypeParmType + QualType VisitTemplateTypeParmType(const TemplateTypeParmType *T); // FIXME: SubstTemplateTypeParmType QualType VisitTemplateSpecializationType(const TemplateSpecializationType *T); QualType VisitElaboratedType(const ElaboratedType *T); @@ -86,6 +87,10 @@ namespace clang { void ImportDeclarationNameLoc(const DeclarationNameInfo &From, DeclarationNameInfo& To); void ImportDeclContext(DeclContext *FromDC, bool ForceImport = false); + + typedef DesignatedInitExpr::Designator Designator; + Designator ImportDesignator(const Designator &D); + /// \brief What we should import from the definition. enum ImportDefinitionKind { @@ -136,6 +141,7 @@ namespace clang { Decl *VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias); Decl *VisitTypedefDecl(TypedefDecl *D); Decl *VisitTypeAliasDecl(TypeAliasDecl *D); + Decl *VisitLabelDecl(LabelDecl *D); Decl *VisitEnumDecl(EnumDecl *D); Decl *VisitRecordDecl(RecordDecl *D); Decl *VisitEnumConstantDecl(EnumConstantDecl *D); @@ -175,6 +181,7 @@ namespace clang { DeclGroupRef ImportDeclGroup(DeclGroupRef DG); Stmt *VisitStmt(Stmt *S); + Stmt *VisitGCCAsmStmt(GCCAsmStmt *S); Stmt *VisitDeclStmt(DeclStmt *S); Stmt *VisitNullStmt(NullStmt *S); Stmt *VisitCompoundStmt(CompoundStmt *S); @@ -192,7 +199,6 @@ namespace clang { Stmt *VisitContinueStmt(ContinueStmt *S); Stmt *VisitBreakStmt(BreakStmt *S); Stmt *VisitReturnStmt(ReturnStmt *S); - // FIXME: GCCAsmStmt // FIXME: MSAsmStmt // FIXME: SEHExceptStmt // FIXME: SEHFinallyStmt @@ -213,13 +219,29 @@ namespace clang { // Importing expressions Expr *VisitExpr(Expr *E); + Expr *VisitVAArgExpr(VAArgExpr *E); + Expr *VisitGNUNullExpr(GNUNullExpr *E); + Expr *VisitPredefinedExpr(PredefinedExpr *E); Expr *VisitDeclRefExpr(DeclRefExpr *E); + Expr *VisitImplicitValueInitExpr(ImplicitValueInitExpr *ILE); + Expr *VisitDesignatedInitExpr(DesignatedInitExpr *E); + Expr *VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E); Expr *VisitIntegerLiteral(IntegerLiteral *E); + Expr *VisitFloatingLiteral(FloatingLiteral *E); Expr *VisitCharacterLiteral(CharacterLiteral *E); + Expr *VisitStringLiteral(StringLiteral *E); + Expr *VisitCompoundLiteralExpr(CompoundLiteralExpr *E); + Expr *VisitAtomicExpr(AtomicExpr *E); + Expr *VisitAddrLabelExpr(AddrLabelExpr *E); Expr *VisitParenExpr(ParenExpr *E); + Expr *VisitParenListExpr(ParenListExpr *E); + Expr *VisitStmtExpr(StmtExpr *E); Expr *VisitUnaryOperator(UnaryOperator *E); Expr *VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E); Expr *VisitBinaryOperator(BinaryOperator *E); + Expr *VisitConditionalOperator(ConditionalOperator *E); + Expr *VisitBinaryConditionalOperator(BinaryConditionalOperator *E); + Expr *VisitOpaqueValueExpr(OpaqueValueExpr *E); Expr *VisitCompoundAssignOperator(CompoundAssignOperator *E); Expr *VisitImplicitCastExpr(ImplicitCastExpr *E); Expr *VisitCStyleCastExpr(CStyleCastExpr *E); @@ -230,32 +252,34 @@ namespace clang { Expr *VisitMemberExpr(MemberExpr *E); Expr *VisitCallExpr(CallExpr *E); Expr *VisitInitListExpr(InitListExpr *E); - - template <typename T, typename Iter> bool ImportArray(Iter B, Iter E, llvm::ArrayRef<T*> &ToArray) { - size_t NumElements = E - B; - SmallVector<T *, 1> ImportedElements(NumElements); - ASTImporter &_Importer = Importer; - + + template<typename IIter, typename OIter> + void ImportArray(IIter Ibegin, IIter Iend, OIter Obegin) { + typedef typename std::remove_reference<decltype(*Obegin)>::type ItemT; + ASTImporter &ImporterRef = Importer; + std::transform(Ibegin, Iend, Obegin, + [&ImporterRef](ItemT From) -> ItemT { + return ImporterRef.Import(From); + }); + } + + template<typename IIter, typename OIter> + bool ImportArrayChecked(IIter Ibegin, IIter Iend, OIter Obegin) { + typedef typename std::remove_reference<decltype(**Obegin)>::type ItemT; + ASTImporter &ImporterRef = Importer; bool Failed = false; - std::transform(B, E, ImportedElements.begin(), - [&_Importer, &Failed](T *Element) -> T* { - T *ToElement = _Importer.Import(Element); - if (Element && !ToElement) + std::transform(Ibegin, Iend, Obegin, + [&ImporterRef, &Failed](ItemT *From) -> ItemT * { + ItemT *To = ImporterRef.Import(From); + if (!To && From) Failed = true; - return ToElement; + return To; }); - - if (Failed) - return false; - - T **CopiedElements = new (Importer.getToContext()) T*[NumElements]; - std::copy(ImportedElements.begin(), ImportedElements.end(), &CopiedElements[0]); - ToArray = llvm::ArrayRef<T*>(CopiedElements, NumElements); - - return true; + return Failed; } }; } + using namespace clang; //---------------------------------------------------------------------------- @@ -1791,6 +1815,28 @@ QualType ASTNodeImporter::VisitAutoType(const AutoType *T) { /*IsDependent*/false); } +QualType ASTNodeImporter::VisitInjectedClassNameType( + const InjectedClassNameType *T) { + CXXRecordDecl *D = cast_or_null<CXXRecordDecl>(Importer.Import(T->getDecl())); + if (!D) + return QualType(); + + QualType InjType = Importer.Import(T->getInjectedSpecializationType()); + if (InjType.isNull()) + return QualType(); + + // FIXME: ASTContext::getInjectedClassNameType is not suitable for AST reading + // See comments in InjectedClassNameType definition for details + // return Importer.getToContext().getInjectedClassNameType(D, InjType); + enum { + TypeAlignmentInBits = 4, + TypeAlignment = 1 << TypeAlignmentInBits + }; + + return QualType(new (Importer.getToContext(), TypeAlignment) + InjectedClassNameType(D, InjType), 0); +} + QualType ASTNodeImporter::VisitRecordType(const RecordType *T) { RecordDecl *ToDecl = dyn_cast_or_null<RecordDecl>(Importer.Import(T->getDecl())); @@ -1830,6 +1876,18 @@ QualType ASTNodeImporter::VisitAttributedType(const AttributedType *T) { ToModifiedType, ToEquivalentType); } + +QualType ASTNodeImporter::VisitTemplateTypeParmType( + const TemplateTypeParmType *T) { + TemplateTypeParmDecl *ParmDecl = + cast_or_null<TemplateTypeParmDecl>(Importer.Import(T->getDecl())); + if (!ParmDecl && T->getDecl()) + return QualType(); + + return Importer.getToContext().getTemplateTypeParmType( + T->getDepth(), T->getIndex(), T->isParameterPack(), ParmDecl); +} + QualType ASTNodeImporter::VisitTemplateSpecializationType( const TemplateSpecializationType *T) { TemplateName ToTemplate = Importer.Import(T->getTemplateName()); @@ -2525,6 +2583,39 @@ Decl *ASTNodeImporter::VisitTypeAliasDecl(TypeAliasDecl *D) { return VisitTypedefNameDecl(D, /*IsAlias=*/true); } +Decl *ASTNodeImporter::VisitLabelDecl(LabelDecl *D) { + // Import the major distinguishing characteristics of this label. + DeclContext *DC, *LexicalDC; + DeclarationName Name; + SourceLocation Loc; + NamedDecl *ToD; + if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc)) + return nullptr; + if (ToD) + return ToD; + + assert(LexicalDC->isFunctionOrMethod()); + + LabelDecl *ToLabel = D->isGnuLocal() + ? LabelDecl::Create(Importer.getToContext(), + DC, Importer.Import(D->getLocation()), + Name.getAsIdentifierInfo(), + Importer.Import(D->getLocStart())) + : LabelDecl::Create(Importer.getToContext(), + DC, Importer.Import(D->getLocation()), + Name.getAsIdentifierInfo()); + Importer.Imported(D, ToLabel); + + LabelStmt *Label = cast_or_null<LabelStmt>(Importer.Import(D->getStmt())); + if (!Label) + return nullptr; + + ToLabel->setStmt(Label); + ToLabel->setLexicalDeclContext(LexicalDC); + LexicalDC->addDeclInternal(ToLabel); + return ToLabel; +} + Decl *ASTNodeImporter::VisitEnumDecl(EnumDecl *D) { // Import the major distinguishing characteristics of this enum. DeclContext *DC, *LexicalDC; @@ -4328,16 +4419,16 @@ Decl *ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) { CXXRecordDecl *DTemplated = D->getTemplatedDecl(); // Create the declaration that is being templated. - SourceLocation StartLoc = Importer.Import(DTemplated->getLocStart()); - SourceLocation IdLoc = Importer.Import(DTemplated->getLocation()); - CXXRecordDecl *D2Templated = CXXRecordDecl::Create(Importer.getToContext(), - DTemplated->getTagKind(), - DC, StartLoc, IdLoc, - Name.getAsIdentifierInfo()); - D2Templated->setAccess(DTemplated->getAccess()); - D2Templated->setQualifierInfo(Importer.Import(DTemplated->getQualifierLoc())); - D2Templated->setLexicalDeclContext(LexicalDC); - + // Create the declaration that is being templated. + CXXRecordDecl *D2Templated = cast_or_null<CXXRecordDecl>( + Importer.Import(DTemplated)); + if (!D2Templated) + return nullptr; + + // Resolve possible cyclic import. + if (Decl *AlreadyImported = Importer.GetAlreadyImportedOrNull(D)) + return AlreadyImported; + // Create the class template declaration itself. TemplateParameterList *TemplateParams = ImportTemplateParameterList(D->getTemplateParameters()); @@ -4681,7 +4772,78 @@ DeclGroupRef ASTNodeImporter::ImportDeclGroup(DeclGroupRef DG) { << S->getStmtClassName(); return nullptr; } - + + +Stmt *ASTNodeImporter::VisitGCCAsmStmt(GCCAsmStmt *S) { + SmallVector<IdentifierInfo *, 4> Names; + for (unsigned I = 0, E = S->getNumOutputs(); I != E; I++) { + IdentifierInfo *ToII = Importer.Import(S->getOutputIdentifier(I)); + if (!ToII) + return nullptr; + Names.push_back(ToII); + } + for (unsigned I = 0, E = S->getNumInputs(); I != E; I++) { + IdentifierInfo *ToII = Importer.Import(S->getInputIdentifier(I)); + if (!ToII) + return nullptr; + Names.push_back(ToII); + } + + SmallVector<StringLiteral *, 4> Clobbers; + for (unsigned I = 0, E = S->getNumClobbers(); I != E; I++) { + StringLiteral *Clobber = cast_or_null<StringLiteral>( + Importer.Import(S->getClobberStringLiteral(I))); + if (!Clobber) + return nullptr; + Clobbers.push_back(Clobber); + } + + SmallVector<StringLiteral *, 4> Constraints; + for (unsigned I = 0, E = S->getNumOutputs(); I != E; I++) { + StringLiteral *Output = cast_or_null<StringLiteral>( + Importer.Import(S->getOutputConstraintLiteral(I))); + if (!Output) + return nullptr; + Constraints.push_back(Output); + } + + for (unsigned I = 0, E = S->getNumInputs(); I != E; I++) { + StringLiteral *Input = cast_or_null<StringLiteral>( + Importer.Import(S->getInputConstraintLiteral(I))); + if (!Input) + return nullptr; + Constraints.push_back(Input); + } + + SmallVector<Expr *, 4> Exprs(S->getNumOutputs() + S->getNumInputs()); + if (ImportArrayChecked(S->begin_outputs(), S->end_outputs(), Exprs.begin())) + return nullptr; + + if (ImportArrayChecked(S->begin_inputs(), S->end_inputs(), + Exprs.begin() + S->getNumOutputs())) + return nullptr; + + StringLiteral *AsmStr = cast_or_null<StringLiteral>( + Importer.Import(S->getAsmString())); + if (!AsmStr) + return nullptr; + + return new (Importer.getToContext()) GCCAsmStmt( + Importer.getToContext(), + Importer.Import(S->getAsmLoc()), + S->isSimple(), + S->isVolatile(), + S->getNumOutputs(), + S->getNumInputs(), + Names.data(), + Constraints.data(), + Exprs.data(), + AsmStr, + S->getNumClobbers(), + Clobbers.data(), + Importer.Import(S->getRParenLoc())); +} + Stmt *ASTNodeImporter::VisitDeclStmt(DeclStmt *S) { DeclGroupRef ToDG = ImportDeclGroup(S->getDeclGroup()); for (Decl *ToD : ToDG) { @@ -4700,9 +4862,9 @@ Stmt *ASTNodeImporter::VisitNullStmt(NullStmt *S) { } Stmt *ASTNodeImporter::VisitCompoundStmt(CompoundStmt *S) { - llvm::ArrayRef<Stmt *> ToStmts; + llvm::SmallVector<Stmt *, 8> ToStmts(S->size()); - if (!ImportArray(S->body_begin(), S->body_end(), ToStmts)) + if (ImportArrayChecked(S->body_begin(), S->body_end(), ToStmts.begin())) return nullptr; SourceLocation ToLBraceLoc = Importer.Import(S->getLBracLoc()); @@ -5123,6 +5285,48 @@ Expr *ASTNodeImporter::VisitExpr(Expr *E) { return nullptr; } +Expr *ASTNodeImporter::VisitVAArgExpr(VAArgExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + Expr *SubExpr = Importer.Import(E->getSubExpr()); + if (!SubExpr && E->getSubExpr()) + return nullptr; + + TypeSourceInfo *TInfo = Importer.Import(E->getWrittenTypeInfo()); + if (!TInfo) + return nullptr; + + return new (Importer.getToContext()) VAArgExpr( + Importer.Import(E->getBuiltinLoc()), SubExpr, TInfo, + Importer.Import(E->getRParenLoc()), T, E->isMicrosoftABI()); +} + + +Expr *ASTNodeImporter::VisitGNUNullExpr(GNUNullExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + return new (Importer.getToContext()) GNUNullExpr( + T, Importer.Import(E->getExprLoc())); +} + +Expr *ASTNodeImporter::VisitPredefinedExpr(PredefinedExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + StringLiteral *SL = cast_or_null<StringLiteral>( + Importer.Import(E->getFunctionName())); + if (!SL && E->getFunctionName()) + return nullptr; + + return new (Importer.getToContext()) PredefinedExpr( + Importer.Import(E->getExprLoc()), T, E->getIdentType(), SL); +} + Expr *ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) { ValueDecl *ToD = cast_or_null<ValueDecl>(Importer.Import(E->getDecl())); if (!ToD) @@ -5153,6 +5357,76 @@ Expr *ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) { return DRE; } +Expr *ASTNodeImporter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return NULL; + + return new (Importer.getToContext()) ImplicitValueInitExpr(T); +} + +ASTNodeImporter::Designator +ASTNodeImporter::ImportDesignator(const Designator &D) { + if (D.isFieldDesignator()) { + IdentifierInfo *ToFieldName = Importer.Import(D.getFieldName()); + // Caller checks for import error + return Designator(ToFieldName, Importer.Import(D.getDotLoc()), + Importer.Import(D.getFieldLoc())); + } + if (D.isArrayDesignator()) + return Designator(D.getFirstExprIndex(), + Importer.Import(D.getLBracketLoc()), + Importer.Import(D.getRBracketLoc())); + + assert(D.isArrayRangeDesignator()); + return Designator(D.getFirstExprIndex(), + Importer.Import(D.getLBracketLoc()), + Importer.Import(D.getEllipsisLoc()), + Importer.Import(D.getRBracketLoc())); +} + + +Expr *ASTNodeImporter::VisitDesignatedInitExpr(DesignatedInitExpr *DIE) { + Expr *Init = cast_or_null<Expr>(Importer.Import(DIE->getInit())); + if (!Init) + return nullptr; + + SmallVector<Expr *, 4> IndexExprs(DIE->getNumSubExprs() - 1); + // List elements from the second, the first is Init itself + for (unsigned I = 1, E = DIE->getNumSubExprs(); I < E; I++) { + if (Expr *Arg = cast_or_null<Expr>(Importer.Import(DIE->getSubExpr(I)))) + IndexExprs[I - 1] = Arg; + else + return nullptr; + } + + SmallVector<Designator, 4> Designators(DIE->size()); + std::transform(DIE->designators_begin(), DIE->designators_end(), + Designators.begin(), + [this](const Designator &D) -> Designator { + return ImportDesignator(D); + }); + + for (auto I = DIE->designators_begin(), E = DIE->designators_end(); I != E; + ++I) + if (I->isFieldDesignator() && !I->getFieldName()) + return nullptr; + + return DesignatedInitExpr::Create( + Importer.getToContext(), Designators.data(), Designators.size(), + IndexExprs, Importer.Import(DIE->getEqualOrColonLoc()), + DIE->usesGNUSyntax(), Init); +} + +Expr *ASTNodeImporter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + return new (Importer.getToContext()) + CXXNullPtrLiteralExpr(T, Importer.Import(E->getLocation())); +} + Expr *ASTNodeImporter::VisitIntegerLiteral(IntegerLiteral *E) { QualType T = Importer.Import(E->getType()); if (T.isNull()) @@ -5163,6 +5437,16 @@ Expr *ASTNodeImporter::VisitIntegerLiteral(IntegerLiteral *E) { Importer.Import(E->getLocation())); } +Expr *ASTNodeImporter::VisitFloatingLiteral(FloatingLiteral *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + return FloatingLiteral::Create(Importer.getToContext(), + E->getValue(), E->isExact(), T, + Importer.Import(E->getLocation())); +} + Expr *ASTNodeImporter::VisitCharacterLiteral(CharacterLiteral *E) { QualType T = Importer.Import(E->getType()); if (T.isNull()) @@ -5173,6 +5457,67 @@ Expr *ASTNodeImporter::VisitCharacterLiteral(CharacterLiteral *E) { Importer.Import(E->getLocation())); } +Expr *ASTNodeImporter::VisitStringLiteral(StringLiteral *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + SmallVector<SourceLocation, 4> Locations(E->getNumConcatenated()); + ImportArray(E->tokloc_begin(), E->tokloc_end(), Locations.begin()); + + return StringLiteral::Create(Importer.getToContext(), E->getBytes(), + E->getKind(), E->isPascal(), T, + Locations.data(), Locations.size()); +} + +Expr *ASTNodeImporter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + TypeSourceInfo *TInfo = Importer.Import(E->getTypeSourceInfo()); + if (!TInfo) + return nullptr; + + Expr *Init = Importer.Import(E->getInitializer()); + if (!Init) + return nullptr; + + return new (Importer.getToContext()) CompoundLiteralExpr( + Importer.Import(E->getLParenLoc()), TInfo, T, E->getValueKind(), + Init, E->isFileScope()); +} + +Expr *ASTNodeImporter::VisitAtomicExpr(AtomicExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + SmallVector<Expr *, 6> Exprs(E->getNumSubExprs()); + if (ImportArrayChecked( + E->getSubExprs(), E->getSubExprs() + E->getNumSubExprs(), + Exprs.begin())) + return nullptr; + + return new (Importer.getToContext()) AtomicExpr( + Importer.Import(E->getBuiltinLoc()), Exprs, T, E->getOp(), + Importer.Import(E->getRParenLoc())); +} + +Expr *ASTNodeImporter::VisitAddrLabelExpr(AddrLabelExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + LabelDecl *ToLabel = cast_or_null<LabelDecl>(Importer.Import(E->getLabel())); + if (!ToLabel) + return nullptr; + + return new (Importer.getToContext()) AddrLabelExpr( + Importer.Import(E->getAmpAmpLoc()), Importer.Import(E->getLabelLoc()), + ToLabel, T); +} + Expr *ASTNodeImporter::VisitParenExpr(ParenExpr *E) { Expr *SubExpr = Importer.Import(E->getSubExpr()); if (!SubExpr) @@ -5184,6 +5529,31 @@ Expr *ASTNodeImporter::VisitParenExpr(ParenExpr *E) { SubExpr); } +Expr *ASTNodeImporter::VisitParenListExpr(ParenListExpr *E) { + SmallVector<Expr *, 4> Exprs(E->getNumExprs()); + if (ImportArrayChecked( + E->getExprs(), E->getExprs() + E->getNumExprs(), Exprs.begin())) + return nullptr; + + return new (Importer.getToContext()) ParenListExpr( + Importer.getToContext(), Importer.Import(E->getLParenLoc()), + Exprs, Importer.Import(E->getLParenLoc())); +} + +Expr *ASTNodeImporter::VisitStmtExpr(StmtExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + CompoundStmt *ToSubStmt = cast_or_null<CompoundStmt>( + Importer.Import(E->getSubStmt())); + if (!ToSubStmt && E->getSubStmt()) + return nullptr; + + return new (Importer.getToContext()) StmtExpr(ToSubStmt, T, + Importer.Import(E->getLParenLoc()), Importer.Import(E->getRParenLoc())); +} + Expr *ASTNodeImporter::VisitUnaryOperator(UnaryOperator *E) { QualType T = Importer.Import(E->getType()); if (T.isNull()) @@ -5244,6 +5614,76 @@ Expr *ASTNodeImporter::VisitBinaryOperator(BinaryOperator *E) { E->isFPContractable()); } +Expr *ASTNodeImporter::VisitConditionalOperator(ConditionalOperator *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; + + Expr *ToCond = Importer.Import(E->getCond()); + if (!ToCond) + return nullptr; + + return new (Importer.getToContext()) ConditionalOperator( + ToCond, Importer.Import(E->getQuestionLoc()), + ToLHS, Importer.Import(E->getColonLoc()), + ToRHS, T, E->getValueKind(), E->getObjectKind()); +} + +Expr *ASTNodeImporter::VisitBinaryConditionalOperator( + BinaryConditionalOperator *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + Expr *Common = Importer.Import(E->getCommon()); + if (!Common) + return nullptr; + + Expr *Cond = Importer.Import(E->getCond()); + if (!Cond) + return nullptr; + + OpaqueValueExpr *OpaqueValue = cast_or_null<OpaqueValueExpr>( + Importer.Import(E->getOpaqueValue())); + if (!OpaqueValue) + return nullptr; + + Expr *TrueExpr = Importer.Import(E->getTrueExpr()); + if (!TrueExpr) + return nullptr; + + Expr *FalseExpr = Importer.Import(E->getFalseExpr()); + if (!FalseExpr) + return nullptr; + + return new (Importer.getToContext()) BinaryConditionalOperator( + Common, OpaqueValue, Cond, TrueExpr, FalseExpr, + Importer.Import(E->getQuestionLoc()), Importer.Import(E->getColonLoc()), + T, E->getValueKind(), E->getObjectKind()); +} + +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::VisitCompoundAssignOperator(CompoundAssignOperator *E) { QualType T = Importer.Import(E->getType()); if (T.isNull()) @@ -5332,9 +5772,9 @@ Expr *ASTNodeImporter::VisitCXXConstructExpr(CXXConstructExpr *E) { if (!ToCCD && E->getConstructor()) return nullptr; - ArrayRef<Expr *> ToArgs; - - if (!ImportArray(E->arg_begin(), E->arg_end(), ToArgs)) + SmallVector<Expr *, 6> ToArgs(E->getNumArgs()); + if (ImportArrayChecked(E->getArgs(), E->getArgs() + E->getNumArgs(), + ToArgs.begin())) return nullptr; return CXXConstructExpr::Create(Importer.getToContext(), T, @@ -5357,14 +5797,14 @@ Expr *ASTNodeImporter::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) { if (!ToFn) return nullptr; - ArrayRef<Expr *> ToArgs; + SmallVector<Expr *, 4> ToArgs(E->getNumArgs()); - if (!ImportArray(E->arg_begin(), E->arg_end(), ToArgs)) + if (ImportArrayChecked(E->arg_begin(), E->arg_end(), ToArgs.begin())) return nullptr; - return new (Importer.getToContext()) CXXMemberCallExpr(Importer.getToContext(), ToFn, - ToArgs, T, E->getValueKind(), - Importer.Import(E->getRParenLoc())); + return new (Importer.getToContext()) CXXMemberCallExpr( + Importer.getToContext(), ToFn, ToArgs, T, E->getValueKind(), + Importer.Import(E->getRParenLoc())); } Expr *ASTNodeImporter::VisitCXXThisExpr(CXXThisExpr *E) { @@ -5454,26 +5894,49 @@ Expr *ASTNodeImporter::VisitCallExpr(CallExpr *E) { Importer.Import(E->getRParenLoc())); } -Expr *ASTNodeImporter::VisitInitListExpr(InitListExpr *E) { - QualType T = Importer.Import(E->getType()); +Expr *ASTNodeImporter::VisitInitListExpr(InitListExpr *ILE) { + QualType T = Importer.Import(ILE->getType()); if (T.isNull()) return nullptr; - - ArrayRef<Expr *> ToInits; - if (!ImportArray(E->inits().begin(), E->inits().end(), ToInits)) + llvm::SmallVector<Expr *, 4> Exprs(ILE->getNumInits()); + if (ImportArrayChecked( + ILE->getInits(), ILE->getInits() + ILE->getNumInits(), Exprs.begin())) return nullptr; - - InitListExpr *ToE = new (Importer.getToContext()) - InitListExpr(Importer.getToContext(), - Importer.Import(E->getLBraceLoc()), - ToInits, - Importer.Import(E->getRBraceLoc())); - - if (ToE) - ToE->setType(T); - return ToE; + ASTContext &ToCtx = Importer.getToContext(); + InitListExpr *To = new (ToCtx) InitListExpr( + ToCtx, Importer.Import(ILE->getLBraceLoc()), + Exprs, Importer.Import(ILE->getLBraceLoc())); + To->setType(T); + + if (ILE->hasArrayFiller()) { + Expr *Filler = Importer.Import(ILE->getArrayFiller()); + if (!Filler) + return nullptr; + To->setArrayFiller(Filler); + } + + if (FieldDecl *FromFD = ILE->getInitializedFieldInUnion()) { + FieldDecl *ToFD = cast_or_null<FieldDecl>(Importer.Import(FromFD)); + if (!ToFD) + return nullptr; + To->setInitializedFieldInUnion(ToFD); + } + + if (InitListExpr *SyntForm = ILE->getSyntacticForm()) { + InitListExpr *ToSyntForm = cast_or_null<InitListExpr>( + Importer.Import(SyntForm)); + if (!ToSyntForm) + return nullptr; + To->setSyntacticForm(ToSyntForm); + } + + To->sawArrayRangeDesignator(ILE->hadArrayRangeDesignator()); + To->setValueDependent(ILE->isValueDependent()); + To->setInstantiationDependent(ILE->isInstantiationDependent()); + + return To; } ASTImporter::ASTImporter(ASTContext &ToContext, FileManager &ToFileManager, |