| File: | tools/clang/lib/AST/ASTImporter.cpp |
| Warning: | line 1133, column 54 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | //===- ASTImporter.cpp - Importing ASTs from other Contexts ---------------===// | |||
| 2 | // | |||
| 3 | // The LLVM Compiler Infrastructure | |||
| 4 | // | |||
| 5 | // This file is distributed under the University of Illinois Open Source | |||
| 6 | // License. See LICENSE.TXT for details. | |||
| 7 | // | |||
| 8 | //===----------------------------------------------------------------------===// | |||
| 9 | // | |||
| 10 | // This file defines the ASTImporter class which imports AST nodes from one | |||
| 11 | // context into another context. | |||
| 12 | // | |||
| 13 | //===----------------------------------------------------------------------===// | |||
| 14 | ||||
| 15 | #include "clang/AST/ASTImporter.h" | |||
| 16 | #include "clang/AST/ASTContext.h" | |||
| 17 | #include "clang/AST/ASTDiagnostic.h" | |||
| 18 | #include "clang/AST/ASTStructuralEquivalence.h" | |||
| 19 | #include "clang/AST/Attr.h" | |||
| 20 | #include "clang/AST/Decl.h" | |||
| 21 | #include "clang/AST/DeclAccessPair.h" | |||
| 22 | #include "clang/AST/DeclBase.h" | |||
| 23 | #include "clang/AST/DeclCXX.h" | |||
| 24 | #include "clang/AST/DeclFriend.h" | |||
| 25 | #include "clang/AST/DeclGroup.h" | |||
| 26 | #include "clang/AST/DeclObjC.h" | |||
| 27 | #include "clang/AST/DeclTemplate.h" | |||
| 28 | #include "clang/AST/DeclVisitor.h" | |||
| 29 | #include "clang/AST/DeclarationName.h" | |||
| 30 | #include "clang/AST/Expr.h" | |||
| 31 | #include "clang/AST/ExprCXX.h" | |||
| 32 | #include "clang/AST/ExprObjC.h" | |||
| 33 | #include "clang/AST/ExternalASTSource.h" | |||
| 34 | #include "clang/AST/LambdaCapture.h" | |||
| 35 | #include "clang/AST/NestedNameSpecifier.h" | |||
| 36 | #include "clang/AST/OperationKinds.h" | |||
| 37 | #include "clang/AST/Stmt.h" | |||
| 38 | #include "clang/AST/StmtCXX.h" | |||
| 39 | #include "clang/AST/StmtObjC.h" | |||
| 40 | #include "clang/AST/StmtVisitor.h" | |||
| 41 | #include "clang/AST/TemplateBase.h" | |||
| 42 | #include "clang/AST/TemplateName.h" | |||
| 43 | #include "clang/AST/Type.h" | |||
| 44 | #include "clang/AST/TypeLoc.h" | |||
| 45 | #include "clang/AST/TypeVisitor.h" | |||
| 46 | #include "clang/AST/UnresolvedSet.h" | |||
| 47 | #include "clang/Basic/ExceptionSpecificationType.h" | |||
| 48 | #include "clang/Basic/FileManager.h" | |||
| 49 | #include "clang/Basic/IdentifierTable.h" | |||
| 50 | #include "clang/Basic/LLVM.h" | |||
| 51 | #include "clang/Basic/LangOptions.h" | |||
| 52 | #include "clang/Basic/SourceLocation.h" | |||
| 53 | #include "clang/Basic/SourceManager.h" | |||
| 54 | #include "clang/Basic/Specifiers.h" | |||
| 55 | #include "llvm/ADT/APSInt.h" | |||
| 56 | #include "llvm/ADT/ArrayRef.h" | |||
| 57 | #include "llvm/ADT/DenseMap.h" | |||
| 58 | #include "llvm/ADT/None.h" | |||
| 59 | #include "llvm/ADT/Optional.h" | |||
| 60 | #include "llvm/ADT/STLExtras.h" | |||
| 61 | #include "llvm/ADT/SmallVector.h" | |||
| 62 | #include "llvm/Support/Casting.h" | |||
| 63 | #include "llvm/Support/ErrorHandling.h" | |||
| 64 | #include "llvm/Support/MemoryBuffer.h" | |||
| 65 | #include <algorithm> | |||
| 66 | #include <cassert> | |||
| 67 | #include <cstddef> | |||
| 68 | #include <memory> | |||
| 69 | #include <type_traits> | |||
| 70 | #include <utility> | |||
| 71 | ||||
| 72 | namespace clang { | |||
| 73 | ||||
| 74 | class ASTNodeImporter : public TypeVisitor<ASTNodeImporter, QualType>, | |||
| 75 | public DeclVisitor<ASTNodeImporter, Decl *>, | |||
| 76 | public StmtVisitor<ASTNodeImporter, Stmt *> { | |||
| 77 | ASTImporter &Importer; | |||
| 78 | ||||
| 79 | public: | |||
| 80 | explicit ASTNodeImporter(ASTImporter &Importer) : Importer(Importer) {} | |||
| 81 | ||||
| 82 | using TypeVisitor<ASTNodeImporter, QualType>::Visit; | |||
| 83 | using DeclVisitor<ASTNodeImporter, Decl *>::Visit; | |||
| 84 | using StmtVisitor<ASTNodeImporter, Stmt *>::Visit; | |||
| 85 | ||||
| 86 | // Importing types | |||
| 87 | QualType VisitType(const Type *T); | |||
| 88 | QualType VisitAtomicType(const AtomicType *T); | |||
| 89 | QualType VisitBuiltinType(const BuiltinType *T); | |||
| 90 | QualType VisitDecayedType(const DecayedType *T); | |||
| 91 | QualType VisitComplexType(const ComplexType *T); | |||
| 92 | QualType VisitPointerType(const PointerType *T); | |||
| 93 | QualType VisitBlockPointerType(const BlockPointerType *T); | |||
| 94 | QualType VisitLValueReferenceType(const LValueReferenceType *T); | |||
| 95 | QualType VisitRValueReferenceType(const RValueReferenceType *T); | |||
| 96 | QualType VisitMemberPointerType(const MemberPointerType *T); | |||
| 97 | QualType VisitConstantArrayType(const ConstantArrayType *T); | |||
| 98 | QualType VisitIncompleteArrayType(const IncompleteArrayType *T); | |||
| 99 | QualType VisitVariableArrayType(const VariableArrayType *T); | |||
| 100 | QualType VisitDependentSizedArrayType(const DependentSizedArrayType *T); | |||
| 101 | // FIXME: DependentSizedExtVectorType | |||
| 102 | QualType VisitVectorType(const VectorType *T); | |||
| 103 | QualType VisitExtVectorType(const ExtVectorType *T); | |||
| 104 | QualType VisitFunctionNoProtoType(const FunctionNoProtoType *T); | |||
| 105 | QualType VisitFunctionProtoType(const FunctionProtoType *T); | |||
| 106 | QualType VisitUnresolvedUsingType(const UnresolvedUsingType *T); | |||
| 107 | QualType VisitParenType(const ParenType *T); | |||
| 108 | QualType VisitTypedefType(const TypedefType *T); | |||
| 109 | QualType VisitTypeOfExprType(const TypeOfExprType *T); | |||
| 110 | // FIXME: DependentTypeOfExprType | |||
| 111 | QualType VisitTypeOfType(const TypeOfType *T); | |||
| 112 | QualType VisitDecltypeType(const DecltypeType *T); | |||
| 113 | QualType VisitUnaryTransformType(const UnaryTransformType *T); | |||
| 114 | QualType VisitAutoType(const AutoType *T); | |||
| 115 | QualType VisitInjectedClassNameType(const InjectedClassNameType *T); | |||
| 116 | // FIXME: DependentDecltypeType | |||
| 117 | QualType VisitRecordType(const RecordType *T); | |||
| 118 | QualType VisitEnumType(const EnumType *T); | |||
| 119 | QualType VisitAttributedType(const AttributedType *T); | |||
| 120 | QualType VisitTemplateTypeParmType(const TemplateTypeParmType *T); | |||
| 121 | QualType VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T); | |||
| 122 | QualType VisitTemplateSpecializationType(const TemplateSpecializationType *T); | |||
| 123 | QualType VisitElaboratedType(const ElaboratedType *T); | |||
| 124 | // FIXME: DependentNameType | |||
| 125 | QualType VisitPackExpansionType(const PackExpansionType *T); | |||
| 126 | QualType VisitDependentTemplateSpecializationType( | |||
| 127 | const DependentTemplateSpecializationType *T); | |||
| 128 | QualType VisitObjCInterfaceType(const ObjCInterfaceType *T); | |||
| 129 | QualType VisitObjCObjectType(const ObjCObjectType *T); | |||
| 130 | QualType VisitObjCObjectPointerType(const ObjCObjectPointerType *T); | |||
| 131 | ||||
| 132 | // Importing declarations | |||
| 133 | bool ImportDeclParts(NamedDecl *D, DeclContext *&DC, | |||
| 134 | DeclContext *&LexicalDC, DeclarationName &Name, | |||
| 135 | NamedDecl *&ToD, SourceLocation &Loc); | |||
| 136 | void ImportDefinitionIfNeeded(Decl *FromD, Decl *ToD = nullptr); | |||
| 137 | void ImportDeclarationNameLoc(const DeclarationNameInfo &From, | |||
| 138 | DeclarationNameInfo& To); | |||
| 139 | void ImportDeclContext(DeclContext *FromDC, bool ForceImport = false); | |||
| 140 | ||||
| 141 | bool ImportCastPath(CastExpr *E, CXXCastPath &Path); | |||
| 142 | ||||
| 143 | using Designator = DesignatedInitExpr::Designator; | |||
| 144 | ||||
| 145 | Designator ImportDesignator(const Designator &D); | |||
| 146 | ||||
| 147 | Optional<LambdaCapture> ImportLambdaCapture(const LambdaCapture &From); | |||
| 148 | ||||
| 149 | /// \brief What we should import from the definition. | |||
| 150 | enum ImportDefinitionKind { | |||
| 151 | /// \brief Import the default subset of the definition, which might be | |||
| 152 | /// nothing (if minimal import is set) or might be everything (if minimal | |||
| 153 | /// import is not set). | |||
| 154 | IDK_Default, | |||
| 155 | ||||
| 156 | /// \brief Import everything. | |||
| 157 | IDK_Everything, | |||
| 158 | ||||
| 159 | /// \brief Import only the bare bones needed to establish a valid | |||
| 160 | /// DeclContext. | |||
| 161 | IDK_Basic | |||
| 162 | }; | |||
| 163 | ||||
| 164 | bool shouldForceImportDeclContext(ImportDefinitionKind IDK) { | |||
| 165 | return IDK == IDK_Everything || | |||
| 166 | (IDK == IDK_Default && !Importer.isMinimalImport()); | |||
| 167 | } | |||
| 168 | ||||
| 169 | bool ImportDefinition(RecordDecl *From, RecordDecl *To, | |||
| 170 | ImportDefinitionKind Kind = IDK_Default); | |||
| 171 | bool ImportDefinition(VarDecl *From, VarDecl *To, | |||
| 172 | ImportDefinitionKind Kind = IDK_Default); | |||
| 173 | bool ImportDefinition(EnumDecl *From, EnumDecl *To, | |||
| 174 | ImportDefinitionKind Kind = IDK_Default); | |||
| 175 | bool ImportDefinition(ObjCInterfaceDecl *From, ObjCInterfaceDecl *To, | |||
| 176 | ImportDefinitionKind Kind = IDK_Default); | |||
| 177 | bool ImportDefinition(ObjCProtocolDecl *From, ObjCProtocolDecl *To, | |||
| 178 | ImportDefinitionKind Kind = IDK_Default); | |||
| 179 | TemplateParameterList *ImportTemplateParameterList( | |||
| 180 | TemplateParameterList *Params); | |||
| 181 | TemplateArgument ImportTemplateArgument(const TemplateArgument &From); | |||
| 182 | Optional<TemplateArgumentLoc> ImportTemplateArgumentLoc( | |||
| 183 | const TemplateArgumentLoc &TALoc); | |||
| 184 | bool ImportTemplateArguments(const TemplateArgument *FromArgs, | |||
| 185 | unsigned NumFromArgs, | |||
| 186 | SmallVectorImpl<TemplateArgument> &ToArgs); | |||
| 187 | ||||
| 188 | template <typename InContainerTy> | |||
| 189 | bool ImportTemplateArgumentListInfo(const InContainerTy &Container, | |||
| 190 | TemplateArgumentListInfo &ToTAInfo); | |||
| 191 | ||||
| 192 | template<typename InContainerTy> | |||
| 193 | bool ImportTemplateArgumentListInfo(SourceLocation FromLAngleLoc, | |||
| 194 | SourceLocation FromRAngleLoc, | |||
| 195 | const InContainerTy &Container, | |||
| 196 | TemplateArgumentListInfo &Result); | |||
| 197 | ||||
| 198 | bool ImportTemplateInformation(FunctionDecl *FromFD, FunctionDecl *ToFD); | |||
| 199 | ||||
| 200 | bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord, | |||
| 201 | bool Complain = true); | |||
| 202 | bool IsStructuralMatch(VarDecl *FromVar, VarDecl *ToVar, | |||
| 203 | bool Complain = true); | |||
| 204 | bool IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToRecord); | |||
| 205 | bool IsStructuralMatch(EnumConstantDecl *FromEC, EnumConstantDecl *ToEC); | |||
| 206 | bool IsStructuralMatch(FunctionTemplateDecl *From, | |||
| 207 | FunctionTemplateDecl *To); | |||
| 208 | bool IsStructuralMatch(ClassTemplateDecl *From, ClassTemplateDecl *To); | |||
| 209 | bool IsStructuralMatch(VarTemplateDecl *From, VarTemplateDecl *To); | |||
| 210 | Decl *VisitDecl(Decl *D); | |||
| 211 | Decl *VisitEmptyDecl(EmptyDecl *D); | |||
| 212 | Decl *VisitAccessSpecDecl(AccessSpecDecl *D); | |||
| 213 | Decl *VisitStaticAssertDecl(StaticAssertDecl *D); | |||
| 214 | Decl *VisitTranslationUnitDecl(TranslationUnitDecl *D); | |||
| 215 | Decl *VisitNamespaceDecl(NamespaceDecl *D); | |||
| 216 | Decl *VisitNamespaceAliasDecl(NamespaceAliasDecl *D); | |||
| 217 | Decl *VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias); | |||
| 218 | Decl *VisitTypedefDecl(TypedefDecl *D); | |||
| 219 | Decl *VisitTypeAliasDecl(TypeAliasDecl *D); | |||
| 220 | Decl *VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D); | |||
| 221 | Decl *VisitLabelDecl(LabelDecl *D); | |||
| 222 | Decl *VisitEnumDecl(EnumDecl *D); | |||
| 223 | Decl *VisitRecordDecl(RecordDecl *D); | |||
| 224 | Decl *VisitEnumConstantDecl(EnumConstantDecl *D); | |||
| 225 | Decl *VisitFunctionDecl(FunctionDecl *D); | |||
| 226 | Decl *VisitCXXMethodDecl(CXXMethodDecl *D); | |||
| 227 | Decl *VisitCXXConstructorDecl(CXXConstructorDecl *D); | |||
| 228 | Decl *VisitCXXDestructorDecl(CXXDestructorDecl *D); | |||
| 229 | Decl *VisitCXXConversionDecl(CXXConversionDecl *D); | |||
| 230 | Decl *VisitFieldDecl(FieldDecl *D); | |||
| 231 | Decl *VisitIndirectFieldDecl(IndirectFieldDecl *D); | |||
| 232 | Decl *VisitFriendDecl(FriendDecl *D); | |||
| 233 | Decl *VisitObjCIvarDecl(ObjCIvarDecl *D); | |||
| 234 | Decl *VisitVarDecl(VarDecl *D); | |||
| 235 | Decl *VisitImplicitParamDecl(ImplicitParamDecl *D); | |||
| 236 | Decl *VisitParmVarDecl(ParmVarDecl *D); | |||
| 237 | Decl *VisitObjCMethodDecl(ObjCMethodDecl *D); | |||
| 238 | Decl *VisitObjCTypeParamDecl(ObjCTypeParamDecl *D); | |||
| 239 | Decl *VisitObjCCategoryDecl(ObjCCategoryDecl *D); | |||
| 240 | Decl *VisitObjCProtocolDecl(ObjCProtocolDecl *D); | |||
| 241 | Decl *VisitLinkageSpecDecl(LinkageSpecDecl *D); | |||
| 242 | Decl *VisitUsingDecl(UsingDecl *D); | |||
| 243 | Decl *VisitUsingShadowDecl(UsingShadowDecl *D); | |||
| 244 | Decl *VisitUsingDirectiveDecl(UsingDirectiveDecl *D); | |||
| 245 | Decl *VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D); | |||
| 246 | Decl *VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D); | |||
| 247 | ||||
| 248 | ObjCTypeParamList *ImportObjCTypeParamList(ObjCTypeParamList *list); | |||
| 249 | Decl *VisitObjCInterfaceDecl(ObjCInterfaceDecl *D); | |||
| 250 | Decl *VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D); | |||
| 251 | Decl *VisitObjCImplementationDecl(ObjCImplementationDecl *D); | |||
| 252 | Decl *VisitObjCPropertyDecl(ObjCPropertyDecl *D); | |||
| 253 | Decl *VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D); | |||
| 254 | Decl *VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D); | |||
| 255 | Decl *VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D); | |||
| 256 | Decl *VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D); | |||
| 257 | Decl *VisitClassTemplateDecl(ClassTemplateDecl *D); | |||
| 258 | Decl *VisitClassTemplateSpecializationDecl( | |||
| 259 | ClassTemplateSpecializationDecl *D); | |||
| 260 | Decl *VisitVarTemplateDecl(VarTemplateDecl *D); | |||
| 261 | Decl *VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *D); | |||
| 262 | Decl *VisitFunctionTemplateDecl(FunctionTemplateDecl *D); | |||
| 263 | ||||
| 264 | // Importing statements | |||
| 265 | DeclGroupRef ImportDeclGroup(DeclGroupRef DG); | |||
| 266 | ||||
| 267 | Stmt *VisitStmt(Stmt *S); | |||
| 268 | Stmt *VisitGCCAsmStmt(GCCAsmStmt *S); | |||
| 269 | Stmt *VisitDeclStmt(DeclStmt *S); | |||
| 270 | Stmt *VisitNullStmt(NullStmt *S); | |||
| 271 | Stmt *VisitCompoundStmt(CompoundStmt *S); | |||
| 272 | Stmt *VisitCaseStmt(CaseStmt *S); | |||
| 273 | Stmt *VisitDefaultStmt(DefaultStmt *S); | |||
| 274 | Stmt *VisitLabelStmt(LabelStmt *S); | |||
| 275 | Stmt *VisitAttributedStmt(AttributedStmt *S); | |||
| 276 | Stmt *VisitIfStmt(IfStmt *S); | |||
| 277 | Stmt *VisitSwitchStmt(SwitchStmt *S); | |||
| 278 | Stmt *VisitWhileStmt(WhileStmt *S); | |||
| 279 | Stmt *VisitDoStmt(DoStmt *S); | |||
| 280 | Stmt *VisitForStmt(ForStmt *S); | |||
| 281 | Stmt *VisitGotoStmt(GotoStmt *S); | |||
| 282 | Stmt *VisitIndirectGotoStmt(IndirectGotoStmt *S); | |||
| 283 | Stmt *VisitContinueStmt(ContinueStmt *S); | |||
| 284 | Stmt *VisitBreakStmt(BreakStmt *S); | |||
| 285 | Stmt *VisitReturnStmt(ReturnStmt *S); | |||
| 286 | // FIXME: MSAsmStmt | |||
| 287 | // FIXME: SEHExceptStmt | |||
| 288 | // FIXME: SEHFinallyStmt | |||
| 289 | // FIXME: SEHTryStmt | |||
| 290 | // FIXME: SEHLeaveStmt | |||
| 291 | // FIXME: CapturedStmt | |||
| 292 | Stmt *VisitCXXCatchStmt(CXXCatchStmt *S); | |||
| 293 | Stmt *VisitCXXTryStmt(CXXTryStmt *S); | |||
| 294 | Stmt *VisitCXXForRangeStmt(CXXForRangeStmt *S); | |||
| 295 | // FIXME: MSDependentExistsStmt | |||
| 296 | Stmt *VisitObjCForCollectionStmt(ObjCForCollectionStmt *S); | |||
| 297 | Stmt *VisitObjCAtCatchStmt(ObjCAtCatchStmt *S); | |||
| 298 | Stmt *VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S); | |||
| 299 | Stmt *VisitObjCAtTryStmt(ObjCAtTryStmt *S); | |||
| 300 | Stmt *VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S); | |||
| 301 | Stmt *VisitObjCAtThrowStmt(ObjCAtThrowStmt *S); | |||
| 302 | Stmt *VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S); | |||
| 303 | ||||
| 304 | // Importing expressions | |||
| 305 | Expr *VisitExpr(Expr *E); | |||
| 306 | Expr *VisitVAArgExpr(VAArgExpr *E); | |||
| 307 | Expr *VisitGNUNullExpr(GNUNullExpr *E); | |||
| 308 | Expr *VisitPredefinedExpr(PredefinedExpr *E); | |||
| 309 | Expr *VisitDeclRefExpr(DeclRefExpr *E); | |||
| 310 | Expr *VisitImplicitValueInitExpr(ImplicitValueInitExpr *ILE); | |||
| 311 | Expr *VisitDesignatedInitExpr(DesignatedInitExpr *E); | |||
| 312 | Expr *VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E); | |||
| 313 | Expr *VisitIntegerLiteral(IntegerLiteral *E); | |||
| 314 | Expr *VisitFloatingLiteral(FloatingLiteral *E); | |||
| 315 | Expr *VisitCharacterLiteral(CharacterLiteral *E); | |||
| 316 | Expr *VisitStringLiteral(StringLiteral *E); | |||
| 317 | Expr *VisitCompoundLiteralExpr(CompoundLiteralExpr *E); | |||
| 318 | Expr *VisitAtomicExpr(AtomicExpr *E); | |||
| 319 | Expr *VisitAddrLabelExpr(AddrLabelExpr *E); | |||
| 320 | Expr *VisitParenExpr(ParenExpr *E); | |||
| 321 | Expr *VisitParenListExpr(ParenListExpr *E); | |||
| 322 | Expr *VisitStmtExpr(StmtExpr *E); | |||
| 323 | Expr *VisitUnaryOperator(UnaryOperator *E); | |||
| 324 | Expr *VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E); | |||
| 325 | Expr *VisitBinaryOperator(BinaryOperator *E); | |||
| 326 | Expr *VisitConditionalOperator(ConditionalOperator *E); | |||
| 327 | Expr *VisitBinaryConditionalOperator(BinaryConditionalOperator *E); | |||
| 328 | Expr *VisitOpaqueValueExpr(OpaqueValueExpr *E); | |||
| 329 | Expr *VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E); | |||
| 330 | Expr *VisitExpressionTraitExpr(ExpressionTraitExpr *E); | |||
| 331 | Expr *VisitArraySubscriptExpr(ArraySubscriptExpr *E); | |||
| 332 | Expr *VisitCompoundAssignOperator(CompoundAssignOperator *E); | |||
| 333 | Expr *VisitImplicitCastExpr(ImplicitCastExpr *E); | |||
| 334 | Expr *VisitExplicitCastExpr(ExplicitCastExpr *E); | |||
| 335 | Expr *VisitOffsetOfExpr(OffsetOfExpr *OE); | |||
| 336 | Expr *VisitCXXThrowExpr(CXXThrowExpr *E); | |||
| 337 | Expr *VisitCXXNoexceptExpr(CXXNoexceptExpr *E); | |||
| 338 | Expr *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E); | |||
| 339 | Expr *VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E); | |||
| 340 | Expr *VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E); | |||
| 341 | Expr *VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *CE); | |||
| 342 | Expr *VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E); | |||
| 343 | Expr *VisitPackExpansionExpr(PackExpansionExpr *E); | |||
| 344 | Expr *VisitSizeOfPackExpr(SizeOfPackExpr *E); | |||
| 345 | Expr *VisitCXXNewExpr(CXXNewExpr *CE); | |||
| 346 | Expr *VisitCXXDeleteExpr(CXXDeleteExpr *E); | |||
| 347 | Expr *VisitCXXConstructExpr(CXXConstructExpr *E); | |||
| 348 | Expr *VisitCXXMemberCallExpr(CXXMemberCallExpr *E); | |||
| 349 | Expr *VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E); | |||
| 350 | Expr *VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *CE); | |||
| 351 | Expr *VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E); | |||
| 352 | Expr *VisitExprWithCleanups(ExprWithCleanups *EWC); | |||
| 353 | Expr *VisitCXXThisExpr(CXXThisExpr *E); | |||
| 354 | Expr *VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E); | |||
| 355 | Expr *VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E); | |||
| 356 | Expr *VisitMemberExpr(MemberExpr *E); | |||
| 357 | Expr *VisitCallExpr(CallExpr *E); | |||
| 358 | Expr *VisitLambdaExpr(LambdaExpr *LE); | |||
| 359 | Expr *VisitInitListExpr(InitListExpr *E); | |||
| 360 | Expr *VisitArrayInitLoopExpr(ArrayInitLoopExpr *E); | |||
| 361 | Expr *VisitArrayInitIndexExpr(ArrayInitIndexExpr *E); | |||
| 362 | Expr *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E); | |||
| 363 | Expr *VisitCXXNamedCastExpr(CXXNamedCastExpr *E); | |||
| 364 | Expr *VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E); | |||
| 365 | Expr *VisitTypeTraitExpr(TypeTraitExpr *E); | |||
| 366 | Expr *VisitCXXTypeidExpr(CXXTypeidExpr *E); | |||
| 367 | ||||
| 368 | template<typename IIter, typename OIter> | |||
| 369 | void ImportArray(IIter Ibegin, IIter Iend, OIter Obegin) { | |||
| 370 | using ItemT = typename std::remove_reference<decltype(*Obegin)>::type; | |||
| 371 | ||||
| 372 | ASTImporter &ImporterRef = Importer; | |||
| 373 | std::transform(Ibegin, Iend, Obegin, | |||
| 374 | [&ImporterRef](ItemT From) -> ItemT { | |||
| 375 | return ImporterRef.Import(From); | |||
| 376 | }); | |||
| 377 | } | |||
| 378 | ||||
| 379 | template<typename IIter, typename OIter> | |||
| 380 | bool ImportArrayChecked(IIter Ibegin, IIter Iend, OIter Obegin) { | |||
| 381 | using ItemT = typename std::remove_reference<decltype(**Obegin)>::type; | |||
| 382 | ||||
| 383 | ASTImporter &ImporterRef = Importer; | |||
| 384 | bool Failed = false; | |||
| 385 | std::transform(Ibegin, Iend, Obegin, | |||
| 386 | [&ImporterRef, &Failed](ItemT *From) -> ItemT * { | |||
| 387 | auto *To = cast_or_null<ItemT>(ImporterRef.Import(From)); | |||
| 388 | if (!To && From) | |||
| 389 | Failed = true; | |||
| 390 | return To; | |||
| 391 | }); | |||
| 392 | return Failed; | |||
| 393 | } | |||
| 394 | ||||
| 395 | template<typename InContainerTy, typename OutContainerTy> | |||
| 396 | bool ImportContainerChecked(const InContainerTy &InContainer, | |||
| 397 | OutContainerTy &OutContainer) { | |||
| 398 | return ImportArrayChecked(InContainer.begin(), InContainer.end(), | |||
| 399 | OutContainer.begin()); | |||
| 400 | } | |||
| 401 | ||||
| 402 | template<typename InContainerTy, typename OIter> | |||
| 403 | bool ImportArrayChecked(const InContainerTy &InContainer, OIter Obegin) { | |||
| 404 | return ImportArrayChecked(InContainer.begin(), InContainer.end(), Obegin); | |||
| 405 | } | |||
| 406 | ||||
| 407 | // Importing overrides. | |||
| 408 | void ImportOverrides(CXXMethodDecl *ToMethod, CXXMethodDecl *FromMethod); | |||
| 409 | }; | |||
| 410 | ||||
| 411 | template <typename InContainerTy> | |||
| 412 | bool ASTNodeImporter::ImportTemplateArgumentListInfo( | |||
| 413 | SourceLocation FromLAngleLoc, SourceLocation FromRAngleLoc, | |||
| 414 | const InContainerTy &Container, TemplateArgumentListInfo &Result) { | |||
| 415 | TemplateArgumentListInfo ToTAInfo(Importer.Import(FromLAngleLoc), | |||
| 416 | Importer.Import(FromRAngleLoc)); | |||
| 417 | if (ImportTemplateArgumentListInfo(Container, ToTAInfo)) | |||
| 418 | return true; | |||
| 419 | Result = ToTAInfo; | |||
| 420 | return false; | |||
| 421 | } | |||
| 422 | ||||
| 423 | template <> | |||
| 424 | bool ASTNodeImporter::ImportTemplateArgumentListInfo<TemplateArgumentListInfo>( | |||
| 425 | const TemplateArgumentListInfo &From, TemplateArgumentListInfo &Result) { | |||
| 426 | return ImportTemplateArgumentListInfo( | |||
| 427 | From.getLAngleLoc(), From.getRAngleLoc(), From.arguments(), Result); | |||
| 428 | } | |||
| 429 | ||||
| 430 | template <> | |||
| 431 | bool ASTNodeImporter::ImportTemplateArgumentListInfo< | |||
| 432 | ASTTemplateArgumentListInfo>(const ASTTemplateArgumentListInfo &From, | |||
| 433 | TemplateArgumentListInfo &Result) { | |||
| 434 | return ImportTemplateArgumentListInfo(From.LAngleLoc, From.RAngleLoc, | |||
| 435 | From.arguments(), Result); | |||
| 436 | } | |||
| 437 | ||||
| 438 | } // namespace clang | |||
| 439 | ||||
| 440 | //---------------------------------------------------------------------------- | |||
| 441 | // Import Types | |||
| 442 | //---------------------------------------------------------------------------- | |||
| 443 | ||||
| 444 | using namespace clang; | |||
| 445 | ||||
| 446 | QualType ASTNodeImporter::VisitType(const Type *T) { | |||
| 447 | Importer.FromDiag(SourceLocation(), diag::err_unsupported_ast_node) | |||
| 448 | << T->getTypeClassName(); | |||
| 449 | return {}; | |||
| 450 | } | |||
| 451 | ||||
| 452 | QualType ASTNodeImporter::VisitAtomicType(const AtomicType *T){ | |||
| 453 | QualType UnderlyingType = Importer.Import(T->getValueType()); | |||
| 454 | if(UnderlyingType.isNull()) | |||
| 455 | return {}; | |||
| 456 | ||||
| 457 | return Importer.getToContext().getAtomicType(UnderlyingType); | |||
| 458 | } | |||
| 459 | ||||
| 460 | QualType ASTNodeImporter::VisitBuiltinType(const BuiltinType *T) { | |||
| 461 | switch (T->getKind()) { | |||
| 462 | #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ | |||
| 463 | case BuiltinType::Id: \ | |||
| 464 | return Importer.getToContext().SingletonId; | |||
| 465 | #include "clang/Basic/OpenCLImageTypes.def" | |||
| 466 | #define SHARED_SINGLETON_TYPE(Expansion) | |||
| 467 | #define BUILTIN_TYPE(Id, SingletonId) \ | |||
| 468 | case BuiltinType::Id: return Importer.getToContext().SingletonId; | |||
| 469 | #include "clang/AST/BuiltinTypes.def" | |||
| 470 | ||||
| 471 | // FIXME: for Char16, Char32, and NullPtr, make sure that the "to" | |||
| 472 | // context supports C++. | |||
| 473 | ||||
| 474 | // FIXME: for ObjCId, ObjCClass, and ObjCSel, make sure that the "to" | |||
| 475 | // context supports ObjC. | |||
| 476 | ||||
| 477 | case BuiltinType::Char_U: | |||
| 478 | // The context we're importing from has an unsigned 'char'. If we're | |||
| 479 | // importing into a context with a signed 'char', translate to | |||
| 480 | // 'unsigned char' instead. | |||
| 481 | if (Importer.getToContext().getLangOpts().CharIsSigned) | |||
| 482 | return Importer.getToContext().UnsignedCharTy; | |||
| 483 | ||||
| 484 | return Importer.getToContext().CharTy; | |||
| 485 | ||||
| 486 | case BuiltinType::Char_S: | |||
| 487 | // The context we're importing from has an unsigned 'char'. If we're | |||
| 488 | // importing into a context with a signed 'char', translate to | |||
| 489 | // 'unsigned char' instead. | |||
| 490 | if (!Importer.getToContext().getLangOpts().CharIsSigned) | |||
| 491 | return Importer.getToContext().SignedCharTy; | |||
| 492 | ||||
| 493 | return Importer.getToContext().CharTy; | |||
| 494 | ||||
| 495 | case BuiltinType::WChar_S: | |||
| 496 | case BuiltinType::WChar_U: | |||
| 497 | // FIXME: If not in C++, shall we translate to the C equivalent of | |||
| 498 | // wchar_t? | |||
| 499 | return Importer.getToContext().WCharTy; | |||
| 500 | } | |||
| 501 | ||||
| 502 | llvm_unreachable("Invalid BuiltinType Kind!")::llvm::llvm_unreachable_internal("Invalid BuiltinType Kind!" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/lib/AST/ASTImporter.cpp" , 502); | |||
| 503 | } | |||
| 504 | ||||
| 505 | QualType ASTNodeImporter::VisitDecayedType(const DecayedType *T) { | |||
| 506 | QualType OrigT = Importer.Import(T->getOriginalType()); | |||
| 507 | if (OrigT.isNull()) | |||
| 508 | return {}; | |||
| 509 | ||||
| 510 | return Importer.getToContext().getDecayedType(OrigT); | |||
| 511 | } | |||
| 512 | ||||
| 513 | QualType ASTNodeImporter::VisitComplexType(const ComplexType *T) { | |||
| 514 | QualType ToElementType = Importer.Import(T->getElementType()); | |||
| 515 | if (ToElementType.isNull()) | |||
| 516 | return {}; | |||
| 517 | ||||
| 518 | return Importer.getToContext().getComplexType(ToElementType); | |||
| 519 | } | |||
| 520 | ||||
| 521 | QualType ASTNodeImporter::VisitPointerType(const PointerType *T) { | |||
| 522 | QualType ToPointeeType = Importer.Import(T->getPointeeType()); | |||
| 523 | if (ToPointeeType.isNull()) | |||
| 524 | return {}; | |||
| 525 | ||||
| 526 | return Importer.getToContext().getPointerType(ToPointeeType); | |||
| 527 | } | |||
| 528 | ||||
| 529 | QualType ASTNodeImporter::VisitBlockPointerType(const BlockPointerType *T) { | |||
| 530 | // FIXME: Check for blocks support in "to" context. | |||
| 531 | QualType ToPointeeType = Importer.Import(T->getPointeeType()); | |||
| 532 | if (ToPointeeType.isNull()) | |||
| 533 | return {}; | |||
| 534 | ||||
| 535 | return Importer.getToContext().getBlockPointerType(ToPointeeType); | |||
| 536 | } | |||
| 537 | ||||
| 538 | QualType | |||
| 539 | ASTNodeImporter::VisitLValueReferenceType(const LValueReferenceType *T) { | |||
| 540 | // FIXME: Check for C++ support in "to" context. | |||
| 541 | QualType ToPointeeType = Importer.Import(T->getPointeeTypeAsWritten()); | |||
| 542 | if (ToPointeeType.isNull()) | |||
| 543 | return {}; | |||
| 544 | ||||
| 545 | return Importer.getToContext().getLValueReferenceType(ToPointeeType); | |||
| 546 | } | |||
| 547 | ||||
| 548 | QualType | |||
| 549 | ASTNodeImporter::VisitRValueReferenceType(const RValueReferenceType *T) { | |||
| 550 | // FIXME: Check for C++0x support in "to" context. | |||
| 551 | QualType ToPointeeType = Importer.Import(T->getPointeeTypeAsWritten()); | |||
| 552 | if (ToPointeeType.isNull()) | |||
| 553 | return {}; | |||
| 554 | ||||
| 555 | return Importer.getToContext().getRValueReferenceType(ToPointeeType); | |||
| 556 | } | |||
| 557 | ||||
| 558 | QualType ASTNodeImporter::VisitMemberPointerType(const MemberPointerType *T) { | |||
| 559 | // FIXME: Check for C++ support in "to" context. | |||
| 560 | QualType ToPointeeType = Importer.Import(T->getPointeeType()); | |||
| 561 | if (ToPointeeType.isNull()) | |||
| 562 | return {}; | |||
| 563 | ||||
| 564 | QualType ClassType = Importer.Import(QualType(T->getClass(), 0)); | |||
| 565 | return Importer.getToContext().getMemberPointerType(ToPointeeType, | |||
| 566 | ClassType.getTypePtr()); | |||
| 567 | } | |||
| 568 | ||||
| 569 | QualType ASTNodeImporter::VisitConstantArrayType(const ConstantArrayType *T) { | |||
| 570 | QualType ToElementType = Importer.Import(T->getElementType()); | |||
| 571 | if (ToElementType.isNull()) | |||
| 572 | return {}; | |||
| 573 | ||||
| 574 | return Importer.getToContext().getConstantArrayType(ToElementType, | |||
| 575 | T->getSize(), | |||
| 576 | T->getSizeModifier(), | |||
| 577 | T->getIndexTypeCVRQualifiers()); | |||
| 578 | } | |||
| 579 | ||||
| 580 | QualType | |||
| 581 | ASTNodeImporter::VisitIncompleteArrayType(const IncompleteArrayType *T) { | |||
| 582 | QualType ToElementType = Importer.Import(T->getElementType()); | |||
| 583 | if (ToElementType.isNull()) | |||
| 584 | return {}; | |||
| 585 | ||||
| 586 | return Importer.getToContext().getIncompleteArrayType(ToElementType, | |||
| 587 | T->getSizeModifier(), | |||
| 588 | T->getIndexTypeCVRQualifiers()); | |||
| 589 | } | |||
| 590 | ||||
| 591 | QualType ASTNodeImporter::VisitVariableArrayType(const VariableArrayType *T) { | |||
| 592 | QualType ToElementType = Importer.Import(T->getElementType()); | |||
| 593 | if (ToElementType.isNull()) | |||
| 594 | return {}; | |||
| 595 | ||||
| 596 | Expr *Size = Importer.Import(T->getSizeExpr()); | |||
| 597 | if (!Size) | |||
| 598 | return {}; | |||
| 599 | ||||
| 600 | SourceRange Brackets = Importer.Import(T->getBracketsRange()); | |||
| 601 | return Importer.getToContext().getVariableArrayType(ToElementType, Size, | |||
| 602 | T->getSizeModifier(), | |||
| 603 | T->getIndexTypeCVRQualifiers(), | |||
| 604 | Brackets); | |||
| 605 | } | |||
| 606 | ||||
| 607 | QualType ASTNodeImporter::VisitDependentSizedArrayType( | |||
| 608 | const DependentSizedArrayType *T) { | |||
| 609 | QualType ToElementType = Importer.Import(T->getElementType()); | |||
| 610 | if (ToElementType.isNull()) | |||
| 611 | return {}; | |||
| 612 | ||||
| 613 | // SizeExpr may be null if size is not specified directly. | |||
| 614 | // For example, 'int a[]'. | |||
| 615 | Expr *Size = Importer.Import(T->getSizeExpr()); | |||
| 616 | if (!Size && T->getSizeExpr()) | |||
| 617 | return {}; | |||
| 618 | ||||
| 619 | SourceRange Brackets = Importer.Import(T->getBracketsRange()); | |||
| 620 | return Importer.getToContext().getDependentSizedArrayType( | |||
| 621 | ToElementType, Size, T->getSizeModifier(), T->getIndexTypeCVRQualifiers(), | |||
| 622 | Brackets); | |||
| 623 | } | |||
| 624 | ||||
| 625 | QualType ASTNodeImporter::VisitVectorType(const VectorType *T) { | |||
| 626 | QualType ToElementType = Importer.Import(T->getElementType()); | |||
| 627 | if (ToElementType.isNull()) | |||
| 628 | return {}; | |||
| 629 | ||||
| 630 | return Importer.getToContext().getVectorType(ToElementType, | |||
| 631 | T->getNumElements(), | |||
| 632 | T->getVectorKind()); | |||
| 633 | } | |||
| 634 | ||||
| 635 | QualType ASTNodeImporter::VisitExtVectorType(const ExtVectorType *T) { | |||
| 636 | QualType ToElementType = Importer.Import(T->getElementType()); | |||
| 637 | if (ToElementType.isNull()) | |||
| 638 | return {}; | |||
| 639 | ||||
| 640 | return Importer.getToContext().getExtVectorType(ToElementType, | |||
| 641 | T->getNumElements()); | |||
| 642 | } | |||
| 643 | ||||
| 644 | QualType | |||
| 645 | ASTNodeImporter::VisitFunctionNoProtoType(const FunctionNoProtoType *T) { | |||
| 646 | // FIXME: What happens if we're importing a function without a prototype | |||
| 647 | // into C++? Should we make it variadic? | |||
| 648 | QualType ToResultType = Importer.Import(T->getReturnType()); | |||
| 649 | if (ToResultType.isNull()) | |||
| 650 | return {}; | |||
| 651 | ||||
| 652 | return Importer.getToContext().getFunctionNoProtoType(ToResultType, | |||
| 653 | T->getExtInfo()); | |||
| 654 | } | |||
| 655 | ||||
| 656 | QualType ASTNodeImporter::VisitFunctionProtoType(const FunctionProtoType *T) { | |||
| 657 | QualType ToResultType = Importer.Import(T->getReturnType()); | |||
| 658 | if (ToResultType.isNull()) | |||
| 659 | return {}; | |||
| 660 | ||||
| 661 | // Import argument types | |||
| 662 | SmallVector<QualType, 4> ArgTypes; | |||
| 663 | for (const auto &A : T->param_types()) { | |||
| 664 | QualType ArgType = Importer.Import(A); | |||
| 665 | if (ArgType.isNull()) | |||
| 666 | return {}; | |||
| 667 | ArgTypes.push_back(ArgType); | |||
| 668 | } | |||
| 669 | ||||
| 670 | // Import exception types | |||
| 671 | SmallVector<QualType, 4> ExceptionTypes; | |||
| 672 | for (const auto &E : T->exceptions()) { | |||
| 673 | QualType ExceptionType = Importer.Import(E); | |||
| 674 | if (ExceptionType.isNull()) | |||
| 675 | return {}; | |||
| 676 | ExceptionTypes.push_back(ExceptionType); | |||
| 677 | } | |||
| 678 | ||||
| 679 | FunctionProtoType::ExtProtoInfo FromEPI = T->getExtProtoInfo(); | |||
| 680 | FunctionProtoType::ExtProtoInfo ToEPI; | |||
| 681 | ||||
| 682 | ToEPI.ExtInfo = FromEPI.ExtInfo; | |||
| 683 | ToEPI.Variadic = FromEPI.Variadic; | |||
| 684 | ToEPI.HasTrailingReturn = FromEPI.HasTrailingReturn; | |||
| 685 | ToEPI.TypeQuals = FromEPI.TypeQuals; | |||
| 686 | ToEPI.RefQualifier = FromEPI.RefQualifier; | |||
| 687 | ToEPI.ExceptionSpec.Type = FromEPI.ExceptionSpec.Type; | |||
| 688 | ToEPI.ExceptionSpec.Exceptions = ExceptionTypes; | |||
| 689 | ToEPI.ExceptionSpec.NoexceptExpr = | |||
| 690 | Importer.Import(FromEPI.ExceptionSpec.NoexceptExpr); | |||
| 691 | ToEPI.ExceptionSpec.SourceDecl = cast_or_null<FunctionDecl>( | |||
| 692 | Importer.Import(FromEPI.ExceptionSpec.SourceDecl)); | |||
| 693 | ToEPI.ExceptionSpec.SourceTemplate = cast_or_null<FunctionDecl>( | |||
| 694 | Importer.Import(FromEPI.ExceptionSpec.SourceTemplate)); | |||
| 695 | ||||
| 696 | return Importer.getToContext().getFunctionType(ToResultType, ArgTypes, ToEPI); | |||
| 697 | } | |||
| 698 | ||||
| 699 | QualType ASTNodeImporter::VisitUnresolvedUsingType( | |||
| 700 | const UnresolvedUsingType *T) { | |||
| 701 | const auto *ToD = | |||
| 702 | cast_or_null<UnresolvedUsingTypenameDecl>(Importer.Import(T->getDecl())); | |||
| 703 | if (!ToD) | |||
| 704 | return {}; | |||
| 705 | ||||
| 706 | auto *ToPrevD = | |||
| 707 | cast_or_null<UnresolvedUsingTypenameDecl>( | |||
| 708 | Importer.Import(T->getDecl()->getPreviousDecl())); | |||
| 709 | if (!ToPrevD && T->getDecl()->getPreviousDecl()) | |||
| 710 | return {}; | |||
| 711 | ||||
| 712 | return Importer.getToContext().getTypeDeclType(ToD, ToPrevD); | |||
| 713 | } | |||
| 714 | ||||
| 715 | QualType ASTNodeImporter::VisitParenType(const ParenType *T) { | |||
| 716 | QualType ToInnerType = Importer.Import(T->getInnerType()); | |||
| 717 | if (ToInnerType.isNull()) | |||
| 718 | return {}; | |||
| 719 | ||||
| 720 | return Importer.getToContext().getParenType(ToInnerType); | |||
| 721 | } | |||
| 722 | ||||
| 723 | QualType ASTNodeImporter::VisitTypedefType(const TypedefType *T) { | |||
| 724 | auto *ToDecl = | |||
| 725 | dyn_cast_or_null<TypedefNameDecl>(Importer.Import(T->getDecl())); | |||
| 726 | if (!ToDecl) | |||
| 727 | return {}; | |||
| 728 | ||||
| 729 | return Importer.getToContext().getTypeDeclType(ToDecl); | |||
| 730 | } | |||
| 731 | ||||
| 732 | QualType ASTNodeImporter::VisitTypeOfExprType(const TypeOfExprType *T) { | |||
| 733 | Expr *ToExpr = Importer.Import(T->getUnderlyingExpr()); | |||
| 734 | if (!ToExpr) | |||
| 735 | return {}; | |||
| 736 | ||||
| 737 | return Importer.getToContext().getTypeOfExprType(ToExpr); | |||
| 738 | } | |||
| 739 | ||||
| 740 | QualType ASTNodeImporter::VisitTypeOfType(const TypeOfType *T) { | |||
| 741 | QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType()); | |||
| 742 | if (ToUnderlyingType.isNull()) | |||
| 743 | return {}; | |||
| 744 | ||||
| 745 | return Importer.getToContext().getTypeOfType(ToUnderlyingType); | |||
| 746 | } | |||
| 747 | ||||
| 748 | QualType ASTNodeImporter::VisitDecltypeType(const DecltypeType *T) { | |||
| 749 | // FIXME: Make sure that the "to" context supports C++0x! | |||
| 750 | Expr *ToExpr = Importer.Import(T->getUnderlyingExpr()); | |||
| 751 | if (!ToExpr) | |||
| 752 | return {}; | |||
| 753 | ||||
| 754 | QualType UnderlyingType = Importer.Import(T->getUnderlyingType()); | |||
| 755 | if (UnderlyingType.isNull()) | |||
| 756 | return {}; | |||
| 757 | ||||
| 758 | return Importer.getToContext().getDecltypeType(ToExpr, UnderlyingType); | |||
| 759 | } | |||
| 760 | ||||
| 761 | QualType ASTNodeImporter::VisitUnaryTransformType(const UnaryTransformType *T) { | |||
| 762 | QualType ToBaseType = Importer.Import(T->getBaseType()); | |||
| 763 | QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType()); | |||
| 764 | if (ToBaseType.isNull() || ToUnderlyingType.isNull()) | |||
| 765 | return {}; | |||
| 766 | ||||
| 767 | return Importer.getToContext().getUnaryTransformType(ToBaseType, | |||
| 768 | ToUnderlyingType, | |||
| 769 | T->getUTTKind()); | |||
| 770 | } | |||
| 771 | ||||
| 772 | QualType ASTNodeImporter::VisitAutoType(const AutoType *T) { | |||
| 773 | // FIXME: Make sure that the "to" context supports C++11! | |||
| 774 | QualType FromDeduced = T->getDeducedType(); | |||
| 775 | QualType ToDeduced; | |||
| 776 | if (!FromDeduced.isNull()) { | |||
| 777 | ToDeduced = Importer.Import(FromDeduced); | |||
| 778 | if (ToDeduced.isNull()) | |||
| 779 | return {}; | |||
| 780 | } | |||
| 781 | ||||
| 782 | return Importer.getToContext().getAutoType(ToDeduced, T->getKeyword(), | |||
| 783 | /*IsDependent*/false); | |||
| 784 | } | |||
| 785 | ||||
| 786 | QualType ASTNodeImporter::VisitInjectedClassNameType( | |||
| 787 | const InjectedClassNameType *T) { | |||
| 788 | auto *D = cast_or_null<CXXRecordDecl>(Importer.Import(T->getDecl())); | |||
| 789 | if (!D) | |||
| 790 | return {}; | |||
| 791 | ||||
| 792 | QualType InjType = Importer.Import(T->getInjectedSpecializationType()); | |||
| 793 | if (InjType.isNull()) | |||
| 794 | return {}; | |||
| 795 | ||||
| 796 | // FIXME: ASTContext::getInjectedClassNameType is not suitable for AST reading | |||
| 797 | // See comments in InjectedClassNameType definition for details | |||
| 798 | // return Importer.getToContext().getInjectedClassNameType(D, InjType); | |||
| 799 | enum { | |||
| 800 | TypeAlignmentInBits = 4, | |||
| 801 | TypeAlignment = 1 << TypeAlignmentInBits | |||
| 802 | }; | |||
| 803 | ||||
| 804 | return QualType(new (Importer.getToContext(), TypeAlignment) | |||
| 805 | InjectedClassNameType(D, InjType), 0); | |||
| 806 | } | |||
| 807 | ||||
| 808 | QualType ASTNodeImporter::VisitRecordType(const RecordType *T) { | |||
| 809 | auto *ToDecl = dyn_cast_or_null<RecordDecl>(Importer.Import(T->getDecl())); | |||
| 810 | if (!ToDecl) | |||
| 811 | return {}; | |||
| 812 | ||||
| 813 | return Importer.getToContext().getTagDeclType(ToDecl); | |||
| 814 | } | |||
| 815 | ||||
| 816 | QualType ASTNodeImporter::VisitEnumType(const EnumType *T) { | |||
| 817 | auto *ToDecl = dyn_cast_or_null<EnumDecl>(Importer.Import(T->getDecl())); | |||
| 818 | if (!ToDecl) | |||
| 819 | return {}; | |||
| 820 | ||||
| 821 | return Importer.getToContext().getTagDeclType(ToDecl); | |||
| 822 | } | |||
| 823 | ||||
| 824 | QualType ASTNodeImporter::VisitAttributedType(const AttributedType *T) { | |||
| 825 | QualType FromModifiedType = T->getModifiedType(); | |||
| 826 | QualType FromEquivalentType = T->getEquivalentType(); | |||
| 827 | QualType ToModifiedType; | |||
| 828 | QualType ToEquivalentType; | |||
| 829 | ||||
| 830 | if (!FromModifiedType.isNull()) { | |||
| 831 | ToModifiedType = Importer.Import(FromModifiedType); | |||
| 832 | if (ToModifiedType.isNull()) | |||
| 833 | return {}; | |||
| 834 | } | |||
| 835 | if (!FromEquivalentType.isNull()) { | |||
| 836 | ToEquivalentType = Importer.Import(FromEquivalentType); | |||
| 837 | if (ToEquivalentType.isNull()) | |||
| 838 | return {}; | |||
| 839 | } | |||
| 840 | ||||
| 841 | return Importer.getToContext().getAttributedType(T->getAttrKind(), | |||
| 842 | ToModifiedType, ToEquivalentType); | |||
| 843 | } | |||
| 844 | ||||
| 845 | QualType ASTNodeImporter::VisitTemplateTypeParmType( | |||
| 846 | const TemplateTypeParmType *T) { | |||
| 847 | auto *ParmDecl = | |||
| 848 | cast_or_null<TemplateTypeParmDecl>(Importer.Import(T->getDecl())); | |||
| 849 | if (!ParmDecl && T->getDecl()) | |||
| 850 | return {}; | |||
| 851 | ||||
| 852 | return Importer.getToContext().getTemplateTypeParmType( | |||
| 853 | T->getDepth(), T->getIndex(), T->isParameterPack(), ParmDecl); | |||
| 854 | } | |||
| 855 | ||||
| 856 | QualType ASTNodeImporter::VisitSubstTemplateTypeParmType( | |||
| 857 | const SubstTemplateTypeParmType *T) { | |||
| 858 | const auto *Replaced = | |||
| 859 | cast_or_null<TemplateTypeParmType>(Importer.Import( | |||
| 860 | QualType(T->getReplacedParameter(), 0)).getTypePtr()); | |||
| 861 | if (!Replaced) | |||
| 862 | return {}; | |||
| 863 | ||||
| 864 | QualType Replacement = Importer.Import(T->getReplacementType()); | |||
| 865 | if (Replacement.isNull()) | |||
| 866 | return {}; | |||
| 867 | Replacement = Replacement.getCanonicalType(); | |||
| 868 | ||||
| 869 | return Importer.getToContext().getSubstTemplateTypeParmType( | |||
| 870 | Replaced, Replacement); | |||
| 871 | } | |||
| 872 | ||||
| 873 | QualType ASTNodeImporter::VisitTemplateSpecializationType( | |||
| 874 | const TemplateSpecializationType *T) { | |||
| 875 | TemplateName ToTemplate = Importer.Import(T->getTemplateName()); | |||
| 876 | if (ToTemplate.isNull()) | |||
| 877 | return {}; | |||
| 878 | ||||
| 879 | SmallVector<TemplateArgument, 2> ToTemplateArgs; | |||
| 880 | if (ImportTemplateArguments(T->getArgs(), T->getNumArgs(), ToTemplateArgs)) | |||
| 881 | return {}; | |||
| 882 | ||||
| 883 | QualType ToCanonType; | |||
| 884 | if (!QualType(T, 0).isCanonical()) { | |||
| 885 | QualType FromCanonType | |||
| 886 | = Importer.getFromContext().getCanonicalType(QualType(T, 0)); | |||
| 887 | ToCanonType =Importer.Import(FromCanonType); | |||
| 888 | if (ToCanonType.isNull()) | |||
| 889 | return {}; | |||
| 890 | } | |||
| 891 | return Importer.getToContext().getTemplateSpecializationType(ToTemplate, | |||
| 892 | ToTemplateArgs, | |||
| 893 | ToCanonType); | |||
| 894 | } | |||
| 895 | ||||
| 896 | QualType ASTNodeImporter::VisitElaboratedType(const ElaboratedType *T) { | |||
| 897 | NestedNameSpecifier *ToQualifier = nullptr; | |||
| 898 | // Note: the qualifier in an ElaboratedType is optional. | |||
| 899 | if (T->getQualifier()) { | |||
| 900 | ToQualifier = Importer.Import(T->getQualifier()); | |||
| 901 | if (!ToQualifier) | |||
| 902 | return {}; | |||
| 903 | } | |||
| 904 | ||||
| 905 | QualType ToNamedType = Importer.Import(T->getNamedType()); | |||
| 906 | if (ToNamedType.isNull()) | |||
| 907 | return {}; | |||
| 908 | ||||
| 909 | return Importer.getToContext().getElaboratedType(T->getKeyword(), | |||
| 910 | ToQualifier, ToNamedType); | |||
| 911 | } | |||
| 912 | ||||
| 913 | QualType ASTNodeImporter::VisitPackExpansionType(const PackExpansionType *T) { | |||
| 914 | QualType Pattern = Importer.Import(T->getPattern()); | |||
| 915 | if (Pattern.isNull()) | |||
| 916 | return {}; | |||
| 917 | ||||
| 918 | return Importer.getToContext().getPackExpansionType(Pattern, | |||
| 919 | T->getNumExpansions()); | |||
| 920 | } | |||
| 921 | ||||
| 922 | QualType ASTNodeImporter::VisitDependentTemplateSpecializationType( | |||
| 923 | const DependentTemplateSpecializationType *T) { | |||
| 924 | NestedNameSpecifier *Qualifier = Importer.Import(T->getQualifier()); | |||
| 925 | if (!Qualifier && T->getQualifier()) | |||
| 926 | return {}; | |||
| 927 | ||||
| 928 | IdentifierInfo *Name = Importer.Import(T->getIdentifier()); | |||
| 929 | if (!Name && T->getIdentifier()) | |||
| 930 | return {}; | |||
| 931 | ||||
| 932 | SmallVector<TemplateArgument, 2> ToPack; | |||
| 933 | ToPack.reserve(T->getNumArgs()); | |||
| 934 | if (ImportTemplateArguments(T->getArgs(), T->getNumArgs(), ToPack)) | |||
| 935 | return {}; | |||
| 936 | ||||
| 937 | return Importer.getToContext().getDependentTemplateSpecializationType( | |||
| 938 | T->getKeyword(), Qualifier, Name, ToPack); | |||
| 939 | } | |||
| 940 | ||||
| 941 | QualType ASTNodeImporter::VisitObjCInterfaceType(const ObjCInterfaceType *T) { | |||
| 942 | auto *Class = | |||
| 943 | dyn_cast_or_null<ObjCInterfaceDecl>(Importer.Import(T->getDecl())); | |||
| 944 | if (!Class) | |||
| 945 | return {}; | |||
| 946 | ||||
| 947 | return Importer.getToContext().getObjCInterfaceType(Class); | |||
| 948 | } | |||
| 949 | ||||
| 950 | QualType ASTNodeImporter::VisitObjCObjectType(const ObjCObjectType *T) { | |||
| 951 | QualType ToBaseType = Importer.Import(T->getBaseType()); | |||
| 952 | if (ToBaseType.isNull()) | |||
| 953 | return {}; | |||
| 954 | ||||
| 955 | SmallVector<QualType, 4> TypeArgs; | |||
| 956 | for (auto TypeArg : T->getTypeArgsAsWritten()) { | |||
| 957 | QualType ImportedTypeArg = Importer.Import(TypeArg); | |||
| 958 | if (ImportedTypeArg.isNull()) | |||
| 959 | return {}; | |||
| 960 | ||||
| 961 | TypeArgs.push_back(ImportedTypeArg); | |||
| 962 | } | |||
| 963 | ||||
| 964 | SmallVector<ObjCProtocolDecl *, 4> Protocols; | |||
| 965 | for (auto *P : T->quals()) { | |||
| 966 | auto *Protocol = dyn_cast_or_null<ObjCProtocolDecl>(Importer.Import(P)); | |||
| 967 | if (!Protocol) | |||
| 968 | return {}; | |||
| 969 | Protocols.push_back(Protocol); | |||
| 970 | } | |||
| 971 | ||||
| 972 | return Importer.getToContext().getObjCObjectType(ToBaseType, TypeArgs, | |||
| 973 | Protocols, | |||
| 974 | T->isKindOfTypeAsWritten()); | |||
| 975 | } | |||
| 976 | ||||
| 977 | QualType | |||
| 978 | ASTNodeImporter::VisitObjCObjectPointerType(const ObjCObjectPointerType *T) { | |||
| 979 | QualType ToPointeeType = Importer.Import(T->getPointeeType()); | |||
| 980 | if (ToPointeeType.isNull()) | |||
| 981 | return {}; | |||
| 982 | ||||
| 983 | return Importer.getToContext().getObjCObjectPointerType(ToPointeeType); | |||
| 984 | } | |||
| 985 | ||||
| 986 | //---------------------------------------------------------------------------- | |||
| 987 | // Import Declarations | |||
| 988 | //---------------------------------------------------------------------------- | |||
| 989 | bool ASTNodeImporter::ImportDeclParts(NamedDecl *D, DeclContext *&DC, | |||
| 990 | DeclContext *&LexicalDC, | |||
| 991 | DeclarationName &Name, | |||
| 992 | NamedDecl *&ToD, | |||
| 993 | SourceLocation &Loc) { | |||
| 994 | // Import the context of this declaration. | |||
| 995 | DC = Importer.ImportContext(D->getDeclContext()); | |||
| 996 | if (!DC) | |||
| 997 | return true; | |||
| 998 | ||||
| 999 | LexicalDC = DC; | |||
| 1000 | if (D->getDeclContext() != D->getLexicalDeclContext()) { | |||
| 1001 | LexicalDC = Importer.ImportContext(D->getLexicalDeclContext()); | |||
| 1002 | if (!LexicalDC) | |||
| 1003 | return true; | |||
| 1004 | } | |||
| 1005 | ||||
| 1006 | // Import the name of this declaration. | |||
| 1007 | Name = Importer.Import(D->getDeclName()); | |||
| 1008 | if (D->getDeclName() && !Name) | |||
| 1009 | return true; | |||
| 1010 | ||||
| 1011 | // Import the location of this declaration. | |||
| 1012 | Loc = Importer.Import(D->getLocation()); | |||
| 1013 | ToD = cast_or_null<NamedDecl>(Importer.GetAlreadyImportedOrNull(D)); | |||
| 1014 | return false; | |||
| 1015 | } | |||
| 1016 | ||||
| 1017 | void ASTNodeImporter::ImportDefinitionIfNeeded(Decl *FromD, Decl *ToD) { | |||
| 1018 | if (!FromD) | |||
| 1019 | return; | |||
| 1020 | ||||
| 1021 | if (!ToD) { | |||
| 1022 | ToD = Importer.Import(FromD); | |||
| 1023 | if (!ToD) | |||
| 1024 | return; | |||
| 1025 | } | |||
| 1026 | ||||
| 1027 | if (auto *FromRecord = dyn_cast<RecordDecl>(FromD)) { | |||
| 1028 | if (auto *ToRecord = cast_or_null<RecordDecl>(ToD)) { | |||
| 1029 | if (FromRecord->getDefinition() && FromRecord->isCompleteDefinition() && !ToRecord->getDefinition()) { | |||
| 1030 | ImportDefinition(FromRecord, ToRecord); | |||
| 1031 | } | |||
| 1032 | } | |||
| 1033 | return; | |||
| 1034 | } | |||
| 1035 | ||||
| 1036 | if (auto *FromEnum = dyn_cast<EnumDecl>(FromD)) { | |||
| 1037 | if (auto *ToEnum = cast_or_null<EnumDecl>(ToD)) { | |||
| 1038 | if (FromEnum->getDefinition() && !ToEnum->getDefinition()) { | |||
| 1039 | ImportDefinition(FromEnum, ToEnum); | |||
| 1040 | } | |||
| 1041 | } | |||
| 1042 | return; | |||
| 1043 | } | |||
| 1044 | } | |||
| 1045 | ||||
| 1046 | void | |||
| 1047 | ASTNodeImporter::ImportDeclarationNameLoc(const DeclarationNameInfo &From, | |||
| 1048 | DeclarationNameInfo& To) { | |||
| 1049 | // NOTE: To.Name and To.Loc are already imported. | |||
| 1050 | // We only have to import To.LocInfo. | |||
| 1051 | switch (To.getName().getNameKind()) { | |||
| 1052 | case DeclarationName::Identifier: | |||
| 1053 | case DeclarationName::ObjCZeroArgSelector: | |||
| 1054 | case DeclarationName::ObjCOneArgSelector: | |||
| 1055 | case DeclarationName::ObjCMultiArgSelector: | |||
| 1056 | case DeclarationName::CXXUsingDirective: | |||
| 1057 | case DeclarationName::CXXDeductionGuideName: | |||
| 1058 | return; | |||
| 1059 | ||||
| 1060 | case DeclarationName::CXXOperatorName: { | |||
| 1061 | SourceRange Range = From.getCXXOperatorNameRange(); | |||
| 1062 | To.setCXXOperatorNameRange(Importer.Import(Range)); | |||
| 1063 | return; | |||
| 1064 | } | |||
| 1065 | case DeclarationName::CXXLiteralOperatorName: { | |||
| 1066 | SourceLocation Loc = From.getCXXLiteralOperatorNameLoc(); | |||
| 1067 | To.setCXXLiteralOperatorNameLoc(Importer.Import(Loc)); | |||
| 1068 | return; | |||
| 1069 | } | |||
| 1070 | case DeclarationName::CXXConstructorName: | |||
| 1071 | case DeclarationName::CXXDestructorName: | |||
| 1072 | case DeclarationName::CXXConversionFunctionName: { | |||
| 1073 | TypeSourceInfo *FromTInfo = From.getNamedTypeInfo(); | |||
| 1074 | To.setNamedTypeInfo(Importer.Import(FromTInfo)); | |||
| 1075 | return; | |||
| 1076 | } | |||
| 1077 | } | |||
| 1078 | llvm_unreachable("Unknown name kind.")::llvm::llvm_unreachable_internal("Unknown name kind.", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/lib/AST/ASTImporter.cpp" , 1078); | |||
| 1079 | } | |||
| 1080 | ||||
| 1081 | void ASTNodeImporter::ImportDeclContext(DeclContext *FromDC, bool ForceImport) { | |||
| 1082 | if (Importer.isMinimalImport() && !ForceImport) { | |||
| 1083 | Importer.ImportContext(FromDC); | |||
| 1084 | return; | |||
| 1085 | } | |||
| 1086 | ||||
| 1087 | for (auto *From : FromDC->decls()) | |||
| 1088 | Importer.Import(From); | |||
| 1089 | } | |||
| 1090 | ||||
| 1091 | bool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To, | |||
| 1092 | ImportDefinitionKind Kind) { | |||
| 1093 | if (To->getDefinition() || To->isBeingDefined()) { | |||
| 1094 | if (Kind == IDK_Everything) | |||
| 1095 | ImportDeclContext(From, /*ForceImport=*/true); | |||
| 1096 | ||||
| 1097 | return false; | |||
| 1098 | } | |||
| 1099 | ||||
| 1100 | To->startDefinition(); | |||
| 1101 | ||||
| 1102 | // Add base classes. | |||
| 1103 | if (auto *ToCXX = dyn_cast<CXXRecordDecl>(To)) { | |||
| 1104 | auto *FromCXX = cast<CXXRecordDecl>(From); | |||
| 1105 | ||||
| 1106 | struct CXXRecordDecl::DefinitionData &ToData = ToCXX->data(); | |||
| 1107 | struct CXXRecordDecl::DefinitionData &FromData = FromCXX->data(); | |||
| 1108 | ToData.UserDeclaredConstructor = FromData.UserDeclaredConstructor; | |||
| 1109 | ToData.UserDeclaredSpecialMembers = FromData.UserDeclaredSpecialMembers; | |||
| 1110 | ToData.Aggregate = FromData.Aggregate; | |||
| 1111 | ToData.PlainOldData = FromData.PlainOldData; | |||
| 1112 | ToData.Empty = FromData.Empty; | |||
| 1113 | ToData.Polymorphic = FromData.Polymorphic; | |||
| 1114 | ToData.Abstract = FromData.Abstract; | |||
| 1115 | ToData.IsStandardLayout = FromData.IsStandardLayout; | |||
| 1116 | ToData.IsCXX11StandardLayout = FromData.IsCXX11StandardLayout; | |||
| 1117 | ToData.HasBasesWithFields = FromData.HasBasesWithFields; | |||
| 1118 | ToData.HasBasesWithNonStaticDataMembers = | |||
| 1119 | FromData.HasBasesWithNonStaticDataMembers; | |||
| 1120 | ToData.HasPrivateFields = FromData.HasPrivateFields; | |||
| 1121 | ToData.HasProtectedFields = FromData.HasProtectedFields; | |||
| 1122 | ToData.HasPublicFields = FromData.HasPublicFields; | |||
| 1123 | ToData.HasMutableFields = FromData.HasMutableFields; | |||
| 1124 | ToData.HasVariantMembers = FromData.HasVariantMembers; | |||
| 1125 | ToData.HasOnlyCMembers = FromData.HasOnlyCMembers; | |||
| 1126 | ToData.HasInClassInitializer = FromData.HasInClassInitializer; | |||
| 1127 | ToData.HasUninitializedReferenceMember | |||
| 1128 | = FromData.HasUninitializedReferenceMember; | |||
| 1129 | ToData.HasUninitializedFields = FromData.HasUninitializedFields; | |||
| 1130 | ToData.HasInheritedConstructor = FromData.HasInheritedConstructor; | |||
| 1131 | ToData.HasInheritedAssignment = FromData.HasInheritedAssignment; | |||
| 1132 | ToData.NeedOverloadResolutionForCopyConstructor | |||
| 1133 | = FromData.NeedOverloadResolutionForCopyConstructor; | |||
| 1134 | ToData.NeedOverloadResolutionForMoveConstructor | |||
| 1135 | = FromData.NeedOverloadResolutionForMoveConstructor; | |||
| 1136 | ToData.NeedOverloadResolutionForMoveAssignment | |||
| 1137 | = FromData.NeedOverloadResolutionForMoveAssignment; | |||
| 1138 | ToData.NeedOverloadResolutionForDestructor | |||
| 1139 | = FromData.NeedOverloadResolutionForDestructor; | |||
| 1140 | ToData.DefaultedCopyConstructorIsDeleted | |||
| 1141 | = FromData.DefaultedCopyConstructorIsDeleted; | |||
| 1142 | ToData.DefaultedMoveConstructorIsDeleted | |||
| 1143 | = FromData.DefaultedMoveConstructorIsDeleted; | |||
| 1144 | ToData.DefaultedMoveAssignmentIsDeleted | |||
| 1145 | = FromData.DefaultedMoveAssignmentIsDeleted; | |||
| 1146 | ToData.DefaultedDestructorIsDeleted = FromData.DefaultedDestructorIsDeleted; | |||
| 1147 | ToData.HasTrivialSpecialMembers = FromData.HasTrivialSpecialMembers; | |||
| 1148 | ToData.HasIrrelevantDestructor = FromData.HasIrrelevantDestructor; | |||
| 1149 | ToData.HasConstexprNonCopyMoveConstructor | |||
| 1150 | = FromData.HasConstexprNonCopyMoveConstructor; | |||
| 1151 | ToData.HasDefaultedDefaultConstructor | |||
| 1152 | = FromData.HasDefaultedDefaultConstructor; | |||
| 1153 | ToData.DefaultedDefaultConstructorIsConstexpr | |||
| 1154 | = FromData.DefaultedDefaultConstructorIsConstexpr; | |||
| 1155 | ToData.HasConstexprDefaultConstructor | |||
| 1156 | = FromData.HasConstexprDefaultConstructor; | |||
| 1157 | ToData.HasNonLiteralTypeFieldsOrBases | |||
| 1158 | = FromData.HasNonLiteralTypeFieldsOrBases; | |||
| 1159 | // ComputedVisibleConversions not imported. | |||
| 1160 | ToData.UserProvidedDefaultConstructor | |||
| 1161 | = FromData.UserProvidedDefaultConstructor; | |||
| 1162 | ToData.DeclaredSpecialMembers = FromData.DeclaredSpecialMembers; | |||
| 1163 | ToData.ImplicitCopyConstructorCanHaveConstParamForVBase | |||
| 1164 | = FromData.ImplicitCopyConstructorCanHaveConstParamForVBase; | |||
| 1165 | ToData.ImplicitCopyConstructorCanHaveConstParamForNonVBase | |||
| 1166 | = FromData.ImplicitCopyConstructorCanHaveConstParamForNonVBase; | |||
| 1167 | ToData.ImplicitCopyAssignmentHasConstParam | |||
| 1168 | = FromData.ImplicitCopyAssignmentHasConstParam; | |||
| 1169 | ToData.HasDeclaredCopyConstructorWithConstParam | |||
| 1170 | = FromData.HasDeclaredCopyConstructorWithConstParam; | |||
| 1171 | ToData.HasDeclaredCopyAssignmentWithConstParam | |||
| 1172 | = FromData.HasDeclaredCopyAssignmentWithConstParam; | |||
| 1173 | ||||
| 1174 | SmallVector<CXXBaseSpecifier *, 4> Bases; | |||
| 1175 | for (const auto &Base1 : FromCXX->bases()) { | |||
| 1176 | QualType T = Importer.Import(Base1.getType()); | |||
| 1177 | if (T.isNull()) | |||
| 1178 | return true; | |||
| 1179 | ||||
| 1180 | SourceLocation EllipsisLoc; | |||
| 1181 | if (Base1.isPackExpansion()) | |||
| 1182 | EllipsisLoc = Importer.Import(Base1.getEllipsisLoc()); | |||
| 1183 | ||||
| 1184 | // Ensure that we have a definition for the base. | |||
| 1185 | ImportDefinitionIfNeeded(Base1.getType()->getAsCXXRecordDecl()); | |||
| 1186 | ||||
| 1187 | Bases.push_back( | |||
| 1188 | new (Importer.getToContext()) | |||
| 1189 | CXXBaseSpecifier(Importer.Import(Base1.getSourceRange()), | |||
| 1190 | Base1.isVirtual(), | |||
| 1191 | Base1.isBaseOfClass(), | |||
| 1192 | Base1.getAccessSpecifierAsWritten(), | |||
| 1193 | Importer.Import(Base1.getTypeSourceInfo()), | |||
| 1194 | EllipsisLoc)); | |||
| 1195 | } | |||
| 1196 | if (!Bases.empty()) | |||
| 1197 | ToCXX->setBases(Bases.data(), Bases.size()); | |||
| 1198 | } | |||
| 1199 | ||||
| 1200 | if (shouldForceImportDeclContext(Kind)) | |||
| 1201 | ImportDeclContext(From, /*ForceImport=*/true); | |||
| 1202 | ||||
| 1203 | To->completeDefinition(); | |||
| 1204 | return false; | |||
| 1205 | } | |||
| 1206 | ||||
| 1207 | bool ASTNodeImporter::ImportDefinition(VarDecl *From, VarDecl *To, | |||
| 1208 | ImportDefinitionKind Kind) { | |||
| 1209 | if (To->getAnyInitializer()) | |||
| 1210 | return false; | |||
| 1211 | ||||
| 1212 | // FIXME: Can we really import any initializer? Alternatively, we could force | |||
| 1213 | // ourselves to import every declaration of a variable and then only use | |||
| 1214 | // getInit() here. | |||
| 1215 | To->setInit(Importer.Import(const_cast<Expr *>(From->getAnyInitializer()))); | |||
| 1216 | ||||
| 1217 | // FIXME: Other bits to merge? | |||
| 1218 | ||||
| 1219 | return false; | |||
| 1220 | } | |||
| 1221 | ||||
| 1222 | bool ASTNodeImporter::ImportDefinition(EnumDecl *From, EnumDecl *To, | |||
| 1223 | ImportDefinitionKind Kind) { | |||
| 1224 | if (To->getDefinition() || To->isBeingDefined()) { | |||
| 1225 | if (Kind == IDK_Everything) | |||
| 1226 | ImportDeclContext(From, /*ForceImport=*/true); | |||
| 1227 | return false; | |||
| 1228 | } | |||
| 1229 | ||||
| 1230 | To->startDefinition(); | |||
| 1231 | ||||
| 1232 | QualType T = Importer.Import(Importer.getFromContext().getTypeDeclType(From)); | |||
| 1233 | if (T.isNull()) | |||
| 1234 | return true; | |||
| 1235 | ||||
| 1236 | QualType ToPromotionType = Importer.Import(From->getPromotionType()); | |||
| 1237 | if (ToPromotionType.isNull()) | |||
| 1238 | return true; | |||
| 1239 | ||||
| 1240 | if (shouldForceImportDeclContext(Kind)) | |||
| 1241 | ImportDeclContext(From, /*ForceImport=*/true); | |||
| 1242 | ||||
| 1243 | // FIXME: we might need to merge the number of positive or negative bits | |||
| 1244 | // if the enumerator lists don't match. | |||
| 1245 | To->completeDefinition(T, ToPromotionType, | |||
| 1246 | From->getNumPositiveBits(), | |||
| 1247 | From->getNumNegativeBits()); | |||
| 1248 | return false; | |||
| 1249 | } | |||
| 1250 | ||||
| 1251 | TemplateParameterList *ASTNodeImporter::ImportTemplateParameterList( | |||
| 1252 | TemplateParameterList *Params) { | |||
| 1253 | SmallVector<NamedDecl *, 4> ToParams(Params->size()); | |||
| 1254 | if (ImportContainerChecked(*Params, ToParams)) | |||
| 1255 | return nullptr; | |||
| 1256 | ||||
| 1257 | Expr *ToRequiresClause; | |||
| 1258 | if (Expr *const R = Params->getRequiresClause()) { | |||
| 1259 | ToRequiresClause = Importer.Import(R); | |||
| 1260 | if (!ToRequiresClause) | |||
| 1261 | return nullptr; | |||
| 1262 | } else { | |||
| 1263 | ToRequiresClause = nullptr; | |||
| 1264 | } | |||
| 1265 | ||||
| 1266 | return TemplateParameterList::Create(Importer.getToContext(), | |||
| 1267 | Importer.Import(Params->getTemplateLoc()), | |||
| 1268 | Importer.Import(Params->getLAngleLoc()), | |||
| 1269 | ToParams, | |||
| 1270 | Importer.Import(Params->getRAngleLoc()), | |||
| 1271 | ToRequiresClause); | |||
| 1272 | } | |||
| 1273 | ||||
| 1274 | TemplateArgument | |||
| 1275 | ASTNodeImporter::ImportTemplateArgument(const TemplateArgument &From) { | |||
| 1276 | switch (From.getKind()) { | |||
| 1277 | case TemplateArgument::Null: | |||
| 1278 | return TemplateArgument(); | |||
| 1279 | ||||
| 1280 | case TemplateArgument::Type: { | |||
| 1281 | QualType ToType = Importer.Import(From.getAsType()); | |||
| 1282 | if (ToType.isNull()) | |||
| 1283 | return {}; | |||
| 1284 | return TemplateArgument(ToType); | |||
| 1285 | } | |||
| 1286 | ||||
| 1287 | case TemplateArgument::Integral: { | |||
| 1288 | QualType ToType = Importer.Import(From.getIntegralType()); | |||
| 1289 | if (ToType.isNull()) | |||
| 1290 | return {}; | |||
| 1291 | return TemplateArgument(From, ToType); | |||
| 1292 | } | |||
| 1293 | ||||
| 1294 | case TemplateArgument::Declaration: { | |||
| 1295 | auto *To = cast_or_null<ValueDecl>(Importer.Import(From.getAsDecl())); | |||
| 1296 | QualType ToType = Importer.Import(From.getParamTypeForDecl()); | |||
| 1297 | if (!To || ToType.isNull()) | |||
| 1298 | return {}; | |||
| 1299 | return TemplateArgument(To, ToType); | |||
| 1300 | } | |||
| 1301 | ||||
| 1302 | case TemplateArgument::NullPtr: { | |||
| 1303 | QualType ToType = Importer.Import(From.getNullPtrType()); | |||
| 1304 | if (ToType.isNull()) | |||
| 1305 | return {}; | |||
| 1306 | return TemplateArgument(ToType, /*isNullPtr*/true); | |||
| 1307 | } | |||
| 1308 | ||||
| 1309 | case TemplateArgument::Template: { | |||
| 1310 | TemplateName ToTemplate = Importer.Import(From.getAsTemplate()); | |||
| 1311 | if (ToTemplate.isNull()) | |||
| 1312 | return {}; | |||
| 1313 | ||||
| 1314 | return TemplateArgument(ToTemplate); | |||
| 1315 | } | |||
| 1316 | ||||
| 1317 | case TemplateArgument::TemplateExpansion: { | |||
| 1318 | TemplateName ToTemplate | |||
| 1319 | = Importer.Import(From.getAsTemplateOrTemplatePattern()); | |||
| 1320 | if (ToTemplate.isNull()) | |||
| 1321 | return {}; | |||
| 1322 | ||||
| 1323 | return TemplateArgument(ToTemplate, From.getNumTemplateExpansions()); | |||
| 1324 | } | |||
| 1325 | ||||
| 1326 | case TemplateArgument::Expression: | |||
| 1327 | if (Expr *ToExpr = Importer.Import(From.getAsExpr())) | |||
| 1328 | return TemplateArgument(ToExpr); | |||
| 1329 | return TemplateArgument(); | |||
| 1330 | ||||
| 1331 | case TemplateArgument::Pack: { | |||
| 1332 | SmallVector<TemplateArgument, 2> ToPack; | |||
| 1333 | ToPack.reserve(From.pack_size()); | |||
| 1334 | if (ImportTemplateArguments(From.pack_begin(), From.pack_size(), ToPack)) | |||
| 1335 | return {}; | |||
| 1336 | ||||
| 1337 | return TemplateArgument( | |||
| 1338 | llvm::makeArrayRef(ToPack).copy(Importer.getToContext())); | |||
| 1339 | } | |||
| 1340 | } | |||
| 1341 | ||||
| 1342 | llvm_unreachable("Invalid template argument kind")::llvm::llvm_unreachable_internal("Invalid template argument kind" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/lib/AST/ASTImporter.cpp" , 1342); | |||
| 1343 | } | |||
| 1344 | ||||
| 1345 | Optional<TemplateArgumentLoc> | |||
| 1346 | ASTNodeImporter::ImportTemplateArgumentLoc(const TemplateArgumentLoc &TALoc) { | |||
| 1347 | TemplateArgument Arg = ImportTemplateArgument(TALoc.getArgument()); | |||
| 1348 | TemplateArgumentLocInfo FromInfo = TALoc.getLocInfo(); | |||
| 1349 | TemplateArgumentLocInfo ToInfo; | |||
| 1350 | if (Arg.getKind() == TemplateArgument::Expression) { | |||
| 1351 | Expr *E = Importer.Import(FromInfo.getAsExpr()); | |||
| 1352 | ToInfo = TemplateArgumentLocInfo(E); | |||
| 1353 | if (!E) | |||
| 1354 | return None; | |||
| 1355 | } else if (Arg.getKind() == TemplateArgument::Type) { | |||
| 1356 | if (TypeSourceInfo *TSI = Importer.Import(FromInfo.getAsTypeSourceInfo())) | |||
| 1357 | ToInfo = TemplateArgumentLocInfo(TSI); | |||
| 1358 | else | |||
| 1359 | return None; | |||
| 1360 | } else { | |||
| 1361 | ToInfo = TemplateArgumentLocInfo( | |||
| 1362 | Importer.Import(FromInfo.getTemplateQualifierLoc()), | |||
| 1363 | Importer.Import(FromInfo.getTemplateNameLoc()), | |||
| 1364 | Importer.Import(FromInfo.getTemplateEllipsisLoc())); | |||
| 1365 | } | |||
| 1366 | return TemplateArgumentLoc(Arg, ToInfo); | |||
| 1367 | } | |||
| 1368 | ||||
| 1369 | bool ASTNodeImporter::ImportTemplateArguments(const TemplateArgument *FromArgs, | |||
| 1370 | unsigned NumFromArgs, | |||
| 1371 | SmallVectorImpl<TemplateArgument> &ToArgs) { | |||
| 1372 | for (unsigned I = 0; I != NumFromArgs; ++I) { | |||
| 1373 | TemplateArgument To = ImportTemplateArgument(FromArgs[I]); | |||
| 1374 | if (To.isNull() && !FromArgs[I].isNull()) | |||
| 1375 | return true; | |||
| 1376 | ||||
| 1377 | ToArgs.push_back(To); | |||
| 1378 | } | |||
| 1379 | ||||
| 1380 | return false; | |||
| 1381 | } | |||
| 1382 | ||||
| 1383 | // We cannot use Optional<> pattern here and below because | |||
| 1384 | // TemplateArgumentListInfo's operator new is declared as deleted so it cannot | |||
| 1385 | // be stored in Optional. | |||
| 1386 | template <typename InContainerTy> | |||
| 1387 | bool ASTNodeImporter::ImportTemplateArgumentListInfo( | |||
| 1388 | const InContainerTy &Container, TemplateArgumentListInfo &ToTAInfo) { | |||
| 1389 | for (const auto &FromLoc : Container) { | |||
| 1390 | if (auto ToLoc = ImportTemplateArgumentLoc(FromLoc)) | |||
| 1391 | ToTAInfo.addArgument(*ToLoc); | |||
| 1392 | else | |||
| 1393 | return true; | |||
| 1394 | } | |||
| 1395 | return false; | |||
| 1396 | } | |||
| 1397 | ||||
| 1398 | bool ASTNodeImporter::IsStructuralMatch(RecordDecl *FromRecord, | |||
| 1399 | RecordDecl *ToRecord, bool Complain) { | |||
| 1400 | // Eliminate a potential failure point where we attempt to re-import | |||
| 1401 | // something we're trying to import while completing ToRecord. | |||
| 1402 | Decl *ToOrigin = Importer.GetOriginalDecl(ToRecord); | |||
| 1403 | if (ToOrigin) { | |||
| 1404 | auto *ToOriginRecord = dyn_cast<RecordDecl>(ToOrigin); | |||
| 1405 | if (ToOriginRecord) | |||
| 1406 | ToRecord = ToOriginRecord; | |||
| 1407 | } | |||
| 1408 | ||||
| 1409 | StructuralEquivalenceContext Ctx(Importer.getFromContext(), | |||
| 1410 | ToRecord->getASTContext(), | |||
| 1411 | Importer.getNonEquivalentDecls(), | |||
| 1412 | false, Complain); | |||
| 1413 | return Ctx.IsStructurallyEquivalent(FromRecord, ToRecord); | |||
| 1414 | } | |||
| 1415 | ||||
| 1416 | bool ASTNodeImporter::IsStructuralMatch(VarDecl *FromVar, VarDecl *ToVar, | |||
| 1417 | bool Complain) { | |||
| 1418 | StructuralEquivalenceContext Ctx( | |||
| 1419 | Importer.getFromContext(), Importer.getToContext(), | |||
| 1420 | Importer.getNonEquivalentDecls(), false, Complain); | |||
| 1421 | return Ctx.IsStructurallyEquivalent(FromVar, ToVar); | |||
| 1422 | } | |||
| 1423 | ||||
| 1424 | bool ASTNodeImporter::IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToEnum) { | |||
| 1425 | StructuralEquivalenceContext Ctx(Importer.getFromContext(), | |||
| 1426 | Importer.getToContext(), | |||
| 1427 | Importer.getNonEquivalentDecls()); | |||
| 1428 | return Ctx.IsStructurallyEquivalent(FromEnum, ToEnum); | |||
| 1429 | } | |||
| 1430 | ||||
| 1431 | bool ASTNodeImporter::IsStructuralMatch(FunctionTemplateDecl *From, | |||
| 1432 | FunctionTemplateDecl *To) { | |||
| 1433 | StructuralEquivalenceContext Ctx( | |||
| 1434 | Importer.getFromContext(), Importer.getToContext(), | |||
| 1435 | Importer.getNonEquivalentDecls(), false, false); | |||
| 1436 | return Ctx.IsStructurallyEquivalent(From, To); | |||
| 1437 | } | |||
| 1438 | ||||
| 1439 | bool ASTNodeImporter::IsStructuralMatch(EnumConstantDecl *FromEC, | |||
| 1440 | EnumConstantDecl *ToEC) { | |||
| 1441 | const llvm::APSInt &FromVal = FromEC->getInitVal(); | |||
| 1442 | const llvm::APSInt &ToVal = ToEC->getInitVal(); | |||
| 1443 | ||||
| 1444 | return FromVal.isSigned() == ToVal.isSigned() && | |||
| 1445 | FromVal.getBitWidth() == ToVal.getBitWidth() && | |||
| 1446 | FromVal == ToVal; | |||
| 1447 | } | |||
| 1448 | ||||
| 1449 | bool ASTNodeImporter::IsStructuralMatch(ClassTemplateDecl *From, | |||
| 1450 | ClassTemplateDecl *To) { | |||
| 1451 | StructuralEquivalenceContext Ctx(Importer.getFromContext(), | |||
| 1452 | Importer.getToContext(), | |||
| 1453 | Importer.getNonEquivalentDecls()); | |||
| 1454 | return Ctx.IsStructurallyEquivalent(From, To); | |||
| 1455 | } | |||
| 1456 | ||||
| 1457 | bool ASTNodeImporter::IsStructuralMatch(VarTemplateDecl *From, | |||
| 1458 | VarTemplateDecl *To) { | |||
| 1459 | StructuralEquivalenceContext Ctx(Importer.getFromContext(), | |||
| 1460 | Importer.getToContext(), | |||
| 1461 | Importer.getNonEquivalentDecls()); | |||
| 1462 | return Ctx.IsStructurallyEquivalent(From, To); | |||
| 1463 | } | |||
| 1464 | ||||
| 1465 | Decl *ASTNodeImporter::VisitDecl(Decl *D) { | |||
| 1466 | Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node) | |||
| 1467 | << D->getDeclKindName(); | |||
| 1468 | return nullptr; | |||
| 1469 | } | |||
| 1470 | ||||
| 1471 | Decl *ASTNodeImporter::VisitEmptyDecl(EmptyDecl *D) { | |||
| 1472 | // Import the context of this declaration. | |||
| 1473 | DeclContext *DC = Importer.ImportContext(D->getDeclContext()); | |||
| 1474 | if (!DC) | |||
| 1475 | return nullptr; | |||
| 1476 | ||||
| 1477 | DeclContext *LexicalDC = DC; | |||
| 1478 | if (D->getDeclContext() != D->getLexicalDeclContext()) { | |||
| 1479 | LexicalDC = Importer.ImportContext(D->getLexicalDeclContext()); | |||
| 1480 | if (!LexicalDC) | |||
| 1481 | return nullptr; | |||
| 1482 | } | |||
| 1483 | ||||
| 1484 | // Import the location of this declaration. | |||
| 1485 | SourceLocation Loc = Importer.Import(D->getLocation()); | |||
| 1486 | ||||
| 1487 | EmptyDecl *ToD = EmptyDecl::Create(Importer.getToContext(), DC, Loc); | |||
| 1488 | ToD->setLexicalDeclContext(LexicalDC); | |||
| 1489 | Importer.Imported(D, ToD); | |||
| 1490 | LexicalDC->addDeclInternal(ToD); | |||
| 1491 | return ToD; | |||
| 1492 | } | |||
| 1493 | ||||
| 1494 | Decl *ASTNodeImporter::VisitTranslationUnitDecl(TranslationUnitDecl *D) { | |||
| 1495 | TranslationUnitDecl *ToD = | |||
| 1496 | Importer.getToContext().getTranslationUnitDecl(); | |||
| 1497 | ||||
| 1498 | Importer.Imported(D, ToD); | |||
| 1499 | ||||
| 1500 | return ToD; | |||
| 1501 | } | |||
| 1502 | ||||
| 1503 | Decl *ASTNodeImporter::VisitAccessSpecDecl(AccessSpecDecl *D) { | |||
| 1504 | SourceLocation Loc = Importer.Import(D->getLocation()); | |||
| 1505 | SourceLocation ColonLoc = Importer.Import(D->getColonLoc()); | |||
| 1506 | ||||
| 1507 | // Import the context of this declaration. | |||
| 1508 | DeclContext *DC = Importer.ImportContext(D->getDeclContext()); | |||
| 1509 | if (!DC) | |||
| 1510 | return nullptr; | |||
| 1511 | ||||
| 1512 | AccessSpecDecl *accessSpecDecl | |||
| 1513 | = AccessSpecDecl::Create(Importer.getToContext(), D->getAccess(), | |||
| 1514 | DC, Loc, ColonLoc); | |||
| 1515 | ||||
| 1516 | if (!accessSpecDecl) | |||
| 1517 | return nullptr; | |||
| 1518 | ||||
| 1519 | // Lexical DeclContext and Semantic DeclContext | |||
| 1520 | // is always the same for the accessSpec. | |||
| 1521 | accessSpecDecl->setLexicalDeclContext(DC); | |||
| 1522 | DC->addDeclInternal(accessSpecDecl); | |||
| 1523 | ||||
| 1524 | return accessSpecDecl; | |||
| 1525 | } | |||
| 1526 | ||||
| 1527 | Decl *ASTNodeImporter::VisitStaticAssertDecl(StaticAssertDecl *D) { | |||
| 1528 | DeclContext *DC = Importer.ImportContext(D->getDeclContext()); | |||
| 1529 | if (!DC) | |||
| 1530 | return nullptr; | |||
| 1531 | ||||
| 1532 | DeclContext *LexicalDC = DC; | |||
| 1533 | ||||
| 1534 | // Import the location of this declaration. | |||
| 1535 | SourceLocation Loc = Importer.Import(D->getLocation()); | |||
| 1536 | ||||
| 1537 | Expr *AssertExpr = Importer.Import(D->getAssertExpr()); | |||
| 1538 | if (!AssertExpr) | |||
| 1539 | return nullptr; | |||
| 1540 | ||||
| 1541 | StringLiteral *FromMsg = D->getMessage(); | |||
| 1542 | auto *ToMsg = cast_or_null<StringLiteral>(Importer.Import(FromMsg)); | |||
| 1543 | if (!ToMsg && FromMsg) | |||
| 1544 | return nullptr; | |||
| 1545 | ||||
| 1546 | StaticAssertDecl *ToD = StaticAssertDecl::Create( | |||
| 1547 | Importer.getToContext(), DC, Loc, AssertExpr, ToMsg, | |||
| 1548 | Importer.Import(D->getRParenLoc()), D->isFailed()); | |||
| 1549 | ||||
| 1550 | ToD->setLexicalDeclContext(LexicalDC); | |||
| 1551 | LexicalDC->addDeclInternal(ToD); | |||
| 1552 | Importer.Imported(D, ToD); | |||
| 1553 | return ToD; | |||
| 1554 | } | |||
| 1555 | ||||
| 1556 | Decl *ASTNodeImporter::VisitNamespaceDecl(NamespaceDecl *D) { | |||
| 1557 | // Import the major distinguishing characteristics of this namespace. | |||
| 1558 | DeclContext *DC, *LexicalDC; | |||
| 1559 | DeclarationName Name; | |||
| 1560 | SourceLocation Loc; | |||
| 1561 | NamedDecl *ToD; | |||
| 1562 | if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc)) | |||
| 1563 | return nullptr; | |||
| 1564 | if (ToD) | |||
| 1565 | return ToD; | |||
| 1566 | ||||
| 1567 | NamespaceDecl *MergeWithNamespace = nullptr; | |||
| 1568 | if (!Name) { | |||
| 1569 | // This is an anonymous namespace. Adopt an existing anonymous | |||
| 1570 | // namespace if we can. | |||
| 1571 | // FIXME: Not testable. | |||
| 1572 | if (auto *TU = dyn_cast<TranslationUnitDecl>(DC)) | |||
| 1573 | MergeWithNamespace = TU->getAnonymousNamespace(); | |||
| 1574 | else | |||
| 1575 | MergeWithNamespace = cast<NamespaceDecl>(DC)->getAnonymousNamespace(); | |||
| 1576 | } else { | |||
| 1577 | SmallVector<NamedDecl *, 4> ConflictingDecls; | |||
| 1578 | SmallVector<NamedDecl *, 2> FoundDecls; | |||
| 1579 | DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls); | |||
| 1580 | for (auto *FoundDecl : FoundDecls) { | |||
| 1581 | if (!FoundDecl->isInIdentifierNamespace(Decl::IDNS_Namespace)) | |||
| 1582 | continue; | |||
| 1583 | ||||
| 1584 | if (auto *FoundNS = dyn_cast<NamespaceDecl>(FoundDecl)) { | |||
| 1585 | MergeWithNamespace = FoundNS; | |||
| 1586 | ConflictingDecls.clear(); | |||
| 1587 | break; | |||
| 1588 | } | |||
| 1589 | ||||
| 1590 | ConflictingDecls.push_back(FoundDecl); | |||
| 1591 | } | |||
| 1592 | ||||
| 1593 | if (!ConflictingDecls.empty()) { | |||
| 1594 | Name = Importer.HandleNameConflict(Name, DC, Decl::IDNS_Namespace, | |||
| 1595 | ConflictingDecls.data(), | |||
| 1596 | ConflictingDecls.size()); | |||
| 1597 | } | |||
| 1598 | } | |||
| 1599 | ||||
| 1600 | // Create the "to" namespace, if needed. | |||
| 1601 | NamespaceDecl *ToNamespace = MergeWithNamespace; | |||
| 1602 | if (!ToNamespace) { | |||
| 1603 | ToNamespace = NamespaceDecl::Create(Importer.getToContext(), DC, | |||
| 1604 | D->isInline(), | |||
| 1605 | Importer.Import(D->getLocStart()), | |||
| 1606 | Loc, Name.getAsIdentifierInfo(), | |||
| 1607 | /*PrevDecl=*/nullptr); | |||
| 1608 | ToNamespace->setLexicalDeclContext(LexicalDC); | |||
| 1609 | LexicalDC->addDeclInternal(ToNamespace); | |||
| 1610 | ||||
| 1611 | // If this is an anonymous namespace, register it as the anonymous | |||
| 1612 | // namespace within its context. | |||
| 1613 | if (!Name) { | |||
| 1614 | if (auto *TU = dyn_cast<TranslationUnitDecl>(DC)) | |||
| 1615 | TU->setAnonymousNamespace(ToNamespace); | |||
| 1616 | else | |||
| 1617 | cast<NamespaceDecl>(DC)->setAnonymousNamespace(ToNamespace); | |||
| 1618 | } | |||
| 1619 | } | |||
| 1620 | Importer.Imported(D, ToNamespace); | |||
| 1621 | ||||
| 1622 | ImportDeclContext(D); | |||
| 1623 | ||||
| 1624 | return ToNamespace; | |||
| 1625 | } | |||
| 1626 | ||||
| 1627 | Decl *ASTNodeImporter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) { | |||
| 1628 | // Import the major distinguishing characteristics of this namespace. | |||
| 1629 | DeclContext *DC, *LexicalDC; | |||
| 1630 | DeclarationName Name; | |||
| 1631 | SourceLocation Loc; | |||
| 1632 | NamedDecl *LookupD; | |||
| 1633 | if (ImportDeclParts(D, DC, LexicalDC, Name, LookupD, Loc)) | |||
| 1634 | return nullptr; | |||
| 1635 | if (LookupD) | |||
| 1636 | return LookupD; | |||
| 1637 | ||||
| 1638 | // NOTE: No conflict resolution is done for namespace aliases now. | |||
| 1639 | ||||
| 1640 | auto *TargetDecl = cast_or_null<NamespaceDecl>( | |||
| 1641 | Importer.Import(D->getNamespace())); | |||
| 1642 | if (!TargetDecl) | |||
| 1643 | return nullptr; | |||
| 1644 | ||||
| 1645 | IdentifierInfo *ToII = Importer.Import(D->getIdentifier()); | |||
| 1646 | if (!ToII) | |||
| 1647 | return nullptr; | |||
| 1648 | ||||
| 1649 | NestedNameSpecifierLoc ToQLoc = Importer.Import(D->getQualifierLoc()); | |||
| 1650 | if (D->getQualifierLoc() && !ToQLoc) | |||
| 1651 | return nullptr; | |||
| 1652 | ||||
| 1653 | NamespaceAliasDecl *ToD = NamespaceAliasDecl::Create( | |||
| 1654 | Importer.getToContext(), DC, Importer.Import(D->getNamespaceLoc()), | |||
| 1655 | Importer.Import(D->getAliasLoc()), ToII, ToQLoc, | |||
| 1656 | Importer.Import(D->getTargetNameLoc()), TargetDecl); | |||
| 1657 | ||||
| 1658 | ToD->setLexicalDeclContext(LexicalDC); | |||
| 1659 | Importer.Imported(D, ToD); | |||
| 1660 | LexicalDC->addDeclInternal(ToD); | |||
| 1661 | ||||
| 1662 | return ToD; | |||
| 1663 | } | |||
| 1664 | ||||
| 1665 | Decl *ASTNodeImporter::VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias) { | |||
| 1666 | // Import the major distinguishing characteristics of this typedef. | |||
| 1667 | DeclContext *DC, *LexicalDC; | |||
| 1668 | DeclarationName Name; | |||
| 1669 | SourceLocation Loc; | |||
| 1670 | NamedDecl *ToD; | |||
| 1671 | if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc)) | |||
| 1672 | return nullptr; | |||
| 1673 | if (ToD) | |||
| 1674 | return ToD; | |||
| 1675 | ||||
| 1676 | // If this typedef is not in block scope, determine whether we've | |||
| 1677 | // seen a typedef with the same name (that we can merge with) or any | |||
| 1678 | // other entity by that name (which name lookup could conflict with). | |||
| 1679 | if (!DC->isFunctionOrMethod()) { | |||
| 1680 | SmallVector<NamedDecl *, 4> ConflictingDecls; | |||
| 1681 | unsigned IDNS = Decl::IDNS_Ordinary; | |||
| 1682 | SmallVector<NamedDecl *, 2> FoundDecls; | |||
| 1683 | DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls); | |||
| 1684 | for (auto *FoundDecl : FoundDecls) { | |||
| 1685 | if (!FoundDecl->isInIdentifierNamespace(IDNS)) | |||
| 1686 | continue; | |||
| 1687 | if (auto *FoundTypedef = dyn_cast<TypedefNameDecl>(FoundDecl)) { | |||
| 1688 | if (Importer.IsStructurallyEquivalent(D->getUnderlyingType(), | |||
| 1689 | FoundTypedef->getUnderlyingType())) | |||
| 1690 | return Importer.Imported(D, FoundTypedef); | |||
| 1691 | } | |||
| 1692 | ||||
| 1693 | ConflictingDecls.push_back(FoundDecl); | |||
| 1694 | } | |||
| 1695 | ||||
| 1696 | if (!ConflictingDecls.empty()) { | |||
| 1697 | Name = Importer.HandleNameConflict(Name, DC, IDNS, | |||
| 1698 | ConflictingDecls.data(), | |||
| 1699 | ConflictingDecls.size()); | |||
| 1700 | if (!Name) | |||
| 1701 | return nullptr; | |||
| 1702 | } | |||
| 1703 | } | |||
| 1704 | ||||
| 1705 | // Import the underlying type of this typedef; | |||
| 1706 | QualType T = Importer.Import(D->getUnderlyingType()); | |||
| 1707 | if (T.isNull()) | |||
| 1708 | return nullptr; | |||
| 1709 | ||||
| 1710 | // Create the new typedef node. | |||
| 1711 | TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo()); | |||
| 1712 | SourceLocation StartL = Importer.Import(D->getLocStart()); | |||
| 1713 | TypedefNameDecl *ToTypedef; | |||
| 1714 | if (IsAlias) | |||
| 1715 | ToTypedef = TypeAliasDecl::Create(Importer.getToContext(), DC, StartL, Loc, | |||
| 1716 | Name.getAsIdentifierInfo(), TInfo); | |||
| 1717 | else | |||
| 1718 | ToTypedef = TypedefDecl::Create(Importer.getToContext(), DC, | |||
| 1719 | StartL, Loc, | |||
| 1720 | Name.getAsIdentifierInfo(), | |||
| 1721 | TInfo); | |||
| 1722 | ||||
| 1723 | ToTypedef->setAccess(D->getAccess()); | |||
| 1724 | ToTypedef->setLexicalDeclContext(LexicalDC); | |||
| 1725 | Importer.Imported(D, ToTypedef); | |||
| 1726 | ||||
| 1727 | // Templated declarations should not appear in DeclContext. | |||
| 1728 | TypeAliasDecl *FromAlias = IsAlias ? cast<TypeAliasDecl>(D) : nullptr; | |||
| 1729 | if (!FromAlias || !FromAlias->getDescribedAliasTemplate()) | |||
| 1730 | LexicalDC->addDeclInternal(ToTypedef); | |||
| 1731 | ||||
| 1732 | return ToTypedef; | |||
| 1733 | } | |||
| 1734 | ||||
| 1735 | Decl *ASTNodeImporter::VisitTypedefDecl(TypedefDecl *D) { | |||
| 1736 | return VisitTypedefNameDecl(D, /*IsAlias=*/false); | |||
| 1737 | } | |||
| 1738 | ||||
| 1739 | Decl *ASTNodeImporter::VisitTypeAliasDecl(TypeAliasDecl *D) { | |||
| 1740 | return VisitTypedefNameDecl(D, /*IsAlias=*/true); | |||
| 1741 | } | |||
| 1742 | ||||
| 1743 | Decl *ASTNodeImporter::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) { | |||
| 1744 | // Import the major distinguishing characteristics of this typedef. | |||
| 1745 | DeclContext *DC, *LexicalDC; | |||
| 1746 | DeclarationName Name; | |||
| 1747 | SourceLocation Loc; | |||
| 1748 | NamedDecl *FoundD; | |||
| 1749 | if (ImportDeclParts(D, DC, LexicalDC, Name, FoundD, Loc)) | |||
| 1750 | return nullptr; | |||
| 1751 | if (FoundD) | |||
| 1752 | return FoundD; | |||
| 1753 | ||||
| 1754 | // If this typedef is not in block scope, determine whether we've | |||
| 1755 | // seen a typedef with the same name (that we can merge with) or any | |||
| 1756 | // other entity by that name (which name lookup could conflict with). | |||
| 1757 | if (!DC->isFunctionOrMethod()) { | |||
| 1758 | SmallVector<NamedDecl *, 4> ConflictingDecls; | |||
| 1759 | unsigned IDNS = Decl::IDNS_Ordinary; | |||
| 1760 | SmallVector<NamedDecl *, 2> FoundDecls; | |||
| 1761 | DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls); | |||
| 1762 | for (auto *FoundDecl : FoundDecls) { | |||
| 1763 | if (!FoundDecl->isInIdentifierNamespace(IDNS)) | |||
| 1764 | continue; | |||
| 1765 | if (auto *FoundAlias = dyn_cast<TypeAliasTemplateDecl>(FoundDecl)) | |||
| 1766 | return Importer.Imported(D, FoundAlias); | |||
| 1767 | ConflictingDecls.push_back(FoundDecl); | |||
| 1768 | } | |||
| 1769 | ||||
| 1770 | if (!ConflictingDecls.empty()) { | |||
| 1771 | Name = Importer.HandleNameConflict(Name, DC, IDNS, | |||
| 1772 | ConflictingDecls.data(), | |||
| 1773 | ConflictingDecls.size()); | |||
| 1774 | if (!Name) | |||
| 1775 | return nullptr; | |||
| 1776 | } | |||
| 1777 | } | |||
| 1778 | ||||
| 1779 | TemplateParameterList *Params = ImportTemplateParameterList( | |||
| 1780 | D->getTemplateParameters()); | |||
| 1781 | if (!Params) | |||
| 1782 | return nullptr; | |||
| 1783 | ||||
| 1784 | auto *TemplDecl = cast_or_null<TypeAliasDecl>( | |||
| 1785 | Importer.Import(D->getTemplatedDecl())); | |||
| 1786 | if (!TemplDecl) | |||
| 1787 | return nullptr; | |||
| 1788 | ||||
| 1789 | TypeAliasTemplateDecl *ToAlias = TypeAliasTemplateDecl::Create( | |||
| 1790 | Importer.getToContext(), DC, Loc, Name, Params, TemplDecl); | |||
| 1791 | ||||
| 1792 | TemplDecl->setDescribedAliasTemplate(ToAlias); | |||
| 1793 | ||||
| 1794 | ToAlias->setAccess(D->getAccess()); | |||
| 1795 | ToAlias->setLexicalDeclContext(LexicalDC); | |||
| 1796 | Importer.Imported(D, ToAlias); | |||
| 1797 | LexicalDC->addDeclInternal(ToAlias); | |||
| 1798 | return ToAlias; | |||
| 1799 | } | |||
| 1800 | ||||
| 1801 | Decl *ASTNodeImporter::VisitLabelDecl(LabelDecl *D) { | |||
| 1802 | // Import the major distinguishing characteristics of this label. | |||
| 1803 | DeclContext *DC, *LexicalDC; | |||
| 1804 | DeclarationName Name; | |||
| 1805 | SourceLocation Loc; | |||
| 1806 | NamedDecl *ToD; | |||
| 1807 | if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc)) | |||
| 1808 | return nullptr; | |||
| 1809 | if (ToD) | |||
| 1810 | return ToD; | |||
| 1811 | ||||
| 1812 | assert(LexicalDC->isFunctionOrMethod())(static_cast <bool> (LexicalDC->isFunctionOrMethod() ) ? void (0) : __assert_fail ("LexicalDC->isFunctionOrMethod()" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/lib/AST/ASTImporter.cpp" , 1812, __extension__ __PRETTY_FUNCTION__)); | |||
| 1813 | ||||
| 1814 | LabelDecl *ToLabel = D->isGnuLocal() | |||
| 1815 | ? LabelDecl::Create(Importer.getToContext(), | |||
| 1816 | DC, Importer.Import(D->getLocation()), | |||
| 1817 | Name.getAsIdentifierInfo(), | |||
| 1818 | Importer.Import(D->getLocStart())) | |||
| 1819 | : LabelDecl::Create(Importer.getToContext(), | |||
| 1820 | DC, Importer.Import(D->getLocation()), | |||
| 1821 | Name.getAsIdentifierInfo()); | |||
| 1822 | Importer.Imported(D, ToLabel); | |||
| 1823 | ||||
| 1824 | auto *Label = cast_or_null<LabelStmt>(Importer.Import(D->getStmt())); | |||
| 1825 | if (!Label) | |||
| 1826 | return nullptr; | |||
| 1827 | ||||
| 1828 | ToLabel->setStmt(Label); | |||
| 1829 | ToLabel->setLexicalDeclContext(LexicalDC); | |||
| 1830 | LexicalDC->addDeclInternal(ToLabel); | |||
| 1831 | return ToLabel; | |||
| 1832 | } | |||
| 1833 | ||||
| 1834 | Decl *ASTNodeImporter::VisitEnumDecl(EnumDecl *D) { | |||
| 1835 | // Import the major distinguishing characteristics of this enum. | |||
| 1836 | DeclContext *DC, *LexicalDC; | |||
| 1837 | DeclarationName Name; | |||
| 1838 | SourceLocation Loc; | |||
| 1839 | NamedDecl *ToD; | |||
| 1840 | if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc)) | |||
| 1841 | return nullptr; | |||
| 1842 | if (ToD) | |||
| 1843 | return ToD; | |||
| 1844 | ||||
| 1845 | // Figure out what enum name we're looking for. | |||
| 1846 | unsigned IDNS = Decl::IDNS_Tag; | |||
| 1847 | DeclarationName SearchName = Name; | |||
| 1848 | if (!SearchName && D->getTypedefNameForAnonDecl()) { | |||
| 1849 | SearchName = Importer.Import(D->getTypedefNameForAnonDecl()->getDeclName()); | |||
| 1850 | IDNS = Decl::IDNS_Ordinary; | |||
| 1851 | } else if (Importer.getToContext().getLangOpts().CPlusPlus) | |||
| 1852 | IDNS |= Decl::IDNS_Ordinary; | |||
| 1853 | ||||
| 1854 | // We may already have an enum of the same name; try to find and match it. | |||
| 1855 | if (!DC->isFunctionOrMethod() && SearchName) { | |||
| 1856 | SmallVector<NamedDecl *, 4> ConflictingDecls; | |||
| 1857 | SmallVector<NamedDecl *, 2> FoundDecls; | |||
| 1858 | DC->getRedeclContext()->localUncachedLookup(SearchName, FoundDecls); | |||
| 1859 | for (auto *FoundDecl : FoundDecls) { | |||
| 1860 | if (!FoundDecl->isInIdentifierNamespace(IDNS)) | |||
| 1861 | continue; | |||
| 1862 | ||||
| 1863 | Decl *Found = FoundDecl; | |||
| 1864 | if (auto *Typedef = dyn_cast<TypedefNameDecl>(Found)) { | |||
| 1865 | if (const auto *Tag = Typedef->getUnderlyingType()->getAs<TagType>()) | |||
| 1866 | Found = Tag->getDecl(); | |||
| 1867 | } | |||
| 1868 | ||||
| 1869 | if (auto *FoundEnum = dyn_cast<EnumDecl>(Found)) { | |||
| 1870 | if (IsStructuralMatch(D, FoundEnum)) | |||
| 1871 | return Importer.Imported(D, FoundEnum); | |||
| 1872 | } | |||
| 1873 | ||||
| 1874 | ConflictingDecls.push_back(FoundDecl); | |||
| 1875 | } | |||
| 1876 | ||||
| 1877 | if (!ConflictingDecls.empty()) { | |||
| 1878 | Name = Importer.HandleNameConflict(Name, DC, IDNS, | |||
| 1879 | ConflictingDecls.data(), | |||
| 1880 | ConflictingDecls.size()); | |||
| 1881 | } | |||
| 1882 | } | |||
| 1883 | ||||
| 1884 | // Create the enum declaration. | |||
| 1885 | EnumDecl *D2 = EnumDecl::Create(Importer.getToContext(), DC, | |||
| 1886 | Importer.Import(D->getLocStart()), | |||
| 1887 | Loc, Name.getAsIdentifierInfo(), nullptr, | |||
| 1888 | D->isScoped(), D->isScopedUsingClassTag(), | |||
| 1889 | D->isFixed()); | |||
| 1890 | // Import the qualifier, if any. | |||
| 1891 | D2->setQualifierInfo(Importer.Import(D->getQualifierLoc())); | |||
| 1892 | D2->setAccess(D->getAccess()); | |||
| 1893 | D2->setLexicalDeclContext(LexicalDC); | |||
| 1894 | Importer.Imported(D, D2); | |||
| 1895 | LexicalDC->addDeclInternal(D2); | |||
| 1896 | ||||
| 1897 | // Import the integer type. | |||
| 1898 | QualType ToIntegerType = Importer.Import(D->getIntegerType()); | |||
| 1899 | if (ToIntegerType.isNull()) | |||
| 1900 | return nullptr; | |||
| 1901 | D2->setIntegerType(ToIntegerType); | |||
| 1902 | ||||
| 1903 | // Import the definition | |||
| 1904 | if (D->isCompleteDefinition() && ImportDefinition(D, D2)) | |||
| 1905 | return nullptr; | |||
| 1906 | ||||
| 1907 | return D2; | |||
| 1908 | } | |||
| 1909 | ||||
| 1910 | Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) { | |||
| 1911 | // If this record has a definition in the translation unit we're coming from, | |||
| 1912 | // but this particular declaration is not that definition, import the | |||
| 1913 | // definition and map to that. | |||
| 1914 | TagDecl *Definition = D->getDefinition(); | |||
| 1915 | if (Definition && Definition != D) { | |||
| 1916 | Decl *ImportedDef = Importer.Import(Definition); | |||
| 1917 | if (!ImportedDef) | |||
| 1918 | return nullptr; | |||
| 1919 | ||||
| 1920 | return Importer.Imported(D, ImportedDef); | |||
| 1921 | } | |||
| 1922 | ||||
| 1923 | // Import the major distinguishing characteristics of this record. | |||
| 1924 | DeclContext *DC, *LexicalDC; | |||
| 1925 | DeclarationName Name; | |||
| 1926 | SourceLocation Loc; | |||
| 1927 | NamedDecl *ToD; | |||
| 1928 | if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc)) | |||
| 1929 | return nullptr; | |||
| 1930 | if (ToD) | |||
| 1931 | return ToD; | |||
| 1932 | ||||
| 1933 | // Figure out what structure name we're looking for. | |||
| 1934 | unsigned IDNS = Decl::IDNS_Tag; | |||
| 1935 | DeclarationName SearchName = Name; | |||
| 1936 | if (!SearchName && D->getTypedefNameForAnonDecl()) { | |||
| 1937 | SearchName = Importer.Import(D->getTypedefNameForAnonDecl()->getDeclName()); | |||
| 1938 | IDNS = Decl::IDNS_Ordinary; | |||
| 1939 | } else if (Importer.getToContext().getLangOpts().CPlusPlus) | |||
| 1940 | IDNS |= Decl::IDNS_Ordinary; | |||
| 1941 | ||||
| 1942 | // We may already have a record of the same name; try to find and match it. | |||
| 1943 | RecordDecl *AdoptDecl = nullptr; | |||
| 1944 | RecordDecl *PrevDecl = nullptr; | |||
| 1945 | if (!DC->isFunctionOrMethod()) { | |||
| 1946 | SmallVector<NamedDecl *, 4> ConflictingDecls; | |||
| 1947 | SmallVector<NamedDecl *, 2> FoundDecls; | |||
| 1948 | DC->getRedeclContext()->localUncachedLookup(SearchName, FoundDecls); | |||
| 1949 | ||||
| 1950 | if (!FoundDecls.empty()) { | |||
| 1951 | // We're going to have to compare D against potentially conflicting Decls, so complete it. | |||
| 1952 | if (D->hasExternalLexicalStorage() && !D->isCompleteDefinition()) | |||
| 1953 | D->getASTContext().getExternalSource()->CompleteType(D); | |||
| 1954 | } | |||
| 1955 | ||||
| 1956 | for (auto *FoundDecl : FoundDecls) { | |||
| 1957 | if (!FoundDecl->isInIdentifierNamespace(IDNS)) | |||
| 1958 | continue; | |||
| 1959 | ||||
| 1960 | Decl *Found = FoundDecl; | |||
| 1961 | if (auto *Typedef = dyn_cast<TypedefNameDecl>(Found)) { | |||
| 1962 | if (const auto *Tag = Typedef->getUnderlyingType()->getAs<TagType>()) | |||
| 1963 | Found = Tag->getDecl(); | |||
| 1964 | } | |||
| 1965 | ||||
| 1966 | if (auto *FoundRecord = dyn_cast<RecordDecl>(Found)) { | |||
| 1967 | if (!SearchName) { | |||
| 1968 | // If both unnamed structs/unions are in a record context, make sure | |||
| 1969 | // they occur in the same location in the context records. | |||
| 1970 | if (Optional<unsigned> Index1 = | |||
| 1971 | StructuralEquivalenceContext::findUntaggedStructOrUnionIndex( | |||
| 1972 | D)) { | |||
| 1973 | if (Optional<unsigned> Index2 = StructuralEquivalenceContext:: | |||
| 1974 | findUntaggedStructOrUnionIndex(FoundRecord)) { | |||
| 1975 | if (*Index1 != *Index2) | |||
| 1976 | continue; | |||
| 1977 | } | |||
| 1978 | } | |||
| 1979 | } | |||
| 1980 | ||||
| 1981 | PrevDecl = FoundRecord; | |||
| 1982 | ||||
| 1983 | if (RecordDecl *FoundDef = FoundRecord->getDefinition()) { | |||
| 1984 | if ((SearchName && !D->isCompleteDefinition()) | |||
| 1985 | || (D->isCompleteDefinition() && | |||
| 1986 | D->isAnonymousStructOrUnion() | |||
| 1987 | == FoundDef->isAnonymousStructOrUnion() && | |||
| 1988 | IsStructuralMatch(D, FoundDef))) { | |||
| 1989 | // The record types structurally match, or the "from" translation | |||
| 1990 | // unit only had a forward declaration anyway; call it the same | |||
| 1991 | // function. | |||
| 1992 | // FIXME: For C++, we should also merge methods here. | |||
| 1993 | return Importer.Imported(D, FoundDef); | |||
| 1994 | } | |||
| 1995 | } else if (!D->isCompleteDefinition()) { | |||
| 1996 | // We have a forward declaration of this type, so adopt that forward | |||
| 1997 | // declaration rather than building a new one. | |||
| 1998 | ||||
| 1999 | // If one or both can be completed from external storage then try one | |||
| 2000 | // last time to complete and compare them before doing this. | |||
| 2001 | ||||
| 2002 | if (FoundRecord->hasExternalLexicalStorage() && | |||
| 2003 | !FoundRecord->isCompleteDefinition()) | |||
| 2004 | FoundRecord->getASTContext().getExternalSource()->CompleteType(FoundRecord); | |||
| 2005 | if (D->hasExternalLexicalStorage()) | |||
| 2006 | D->getASTContext().getExternalSource()->CompleteType(D); | |||
| 2007 | ||||
| 2008 | if (FoundRecord->isCompleteDefinition() && | |||
| 2009 | D->isCompleteDefinition() && | |||
| 2010 | !IsStructuralMatch(D, FoundRecord)) | |||
| 2011 | continue; | |||
| 2012 | ||||
| 2013 | AdoptDecl = FoundRecord; | |||
| 2014 | continue; | |||
| 2015 | } else if (!SearchName) { | |||
| 2016 | continue; | |||
| 2017 | } | |||
| 2018 | } | |||
| 2019 | ||||
| 2020 | ConflictingDecls.push_back(FoundDecl); | |||
| 2021 | } | |||
| 2022 | ||||
| 2023 | if (!ConflictingDecls.empty() && SearchName) { | |||
| 2024 | Name = Importer.HandleNameConflict(Name, DC, IDNS, | |||
| 2025 | ConflictingDecls.data(), | |||
| 2026 | ConflictingDecls.size()); | |||
| 2027 | } | |||
| 2028 | } | |||
| 2029 | ||||
| 2030 | // Create the record declaration. | |||
| 2031 | RecordDecl *D2 = AdoptDecl; | |||
| 2032 | SourceLocation StartLoc = Importer.Import(D->getLocStart()); | |||
| 2033 | if (!D2) { | |||
| 2034 | CXXRecordDecl *D2CXX = nullptr; | |||
| 2035 | if (auto *DCXX = dyn_cast<CXXRecordDecl>(D)) { | |||
| 2036 | if (DCXX->isLambda()) { | |||
| 2037 | TypeSourceInfo *TInfo = Importer.Import(DCXX->getLambdaTypeInfo()); | |||
| 2038 | D2CXX = CXXRecordDecl::CreateLambda(Importer.getToContext(), | |||
| 2039 | DC, TInfo, Loc, | |||
| 2040 | DCXX->isDependentLambda(), | |||
| 2041 | DCXX->isGenericLambda(), | |||
| 2042 | DCXX->getLambdaCaptureDefault()); | |||
| 2043 | Decl *CDecl = Importer.Import(DCXX->getLambdaContextDecl()); | |||
| 2044 | if (DCXX->getLambdaContextDecl() && !CDecl) | |||
| 2045 | return nullptr; | |||
| 2046 | D2CXX->setLambdaMangling(DCXX->getLambdaManglingNumber(), CDecl); | |||
| 2047 | } else if (DCXX->isInjectedClassName()) { | |||
| 2048 | // We have to be careful to do a similar dance to the one in | |||
| 2049 | // Sema::ActOnStartCXXMemberDeclarations | |||
| 2050 | CXXRecordDecl *const PrevDecl = nullptr; | |||
| 2051 | const bool DelayTypeCreation = true; | |||
| 2052 | D2CXX = CXXRecordDecl::Create( | |||
| 2053 | Importer.getToContext(), D->getTagKind(), DC, StartLoc, Loc, | |||
| 2054 | Name.getAsIdentifierInfo(), PrevDecl, DelayTypeCreation); | |||
| 2055 | Importer.getToContext().getTypeDeclType( | |||
| 2056 | D2CXX, dyn_cast<CXXRecordDecl>(DC)); | |||
| 2057 | } else { | |||
| 2058 | D2CXX = CXXRecordDecl::Create(Importer.getToContext(), | |||
| 2059 | D->getTagKind(), | |||
| 2060 | DC, StartLoc, Loc, | |||
| 2061 | Name.getAsIdentifierInfo()); | |||
| 2062 | } | |||
| 2063 | D2 = D2CXX; | |||
| 2064 | D2->setAccess(D->getAccess()); | |||
| 2065 | D2->setLexicalDeclContext(LexicalDC); | |||
| 2066 | if (!DCXX->getDescribedClassTemplate()) | |||
| 2067 | LexicalDC->addDeclInternal(D2); | |||
| 2068 | ||||
| 2069 | Importer.Imported(D, D2); | |||
| 2070 | ||||
| 2071 | if (ClassTemplateDecl *FromDescribed = | |||
| 2072 | DCXX->getDescribedClassTemplate()) { | |||
| 2073 | auto *ToDescribed = cast_or_null<ClassTemplateDecl>( | |||
| 2074 | Importer.Import(FromDescribed)); | |||
| 2075 | if (!ToDescribed) | |||
| 2076 | return nullptr; | |||
| 2077 | D2CXX->setDescribedClassTemplate(ToDescribed); | |||
| 2078 | } else if (MemberSpecializationInfo *MemberInfo = | |||
| 2079 | DCXX->getMemberSpecializationInfo()) { | |||
| 2080 | TemplateSpecializationKind SK = | |||
| 2081 | MemberInfo->getTemplateSpecializationKind(); | |||
| 2082 | CXXRecordDecl *FromInst = DCXX->getInstantiatedFromMemberClass(); | |||
| 2083 | auto *ToInst = | |||
| 2084 | cast_or_null<CXXRecordDecl>(Importer.Import(FromInst)); | |||
| 2085 | if (FromInst && !ToInst) | |||
| 2086 | return nullptr; | |||
| 2087 | D2CXX->setInstantiationOfMemberClass(ToInst, SK); | |||
| 2088 | D2CXX->getMemberSpecializationInfo()->setPointOfInstantiation( | |||
| 2089 | Importer.Import(MemberInfo->getPointOfInstantiation())); | |||
| 2090 | } | |||
| 2091 | } else { | |||
| 2092 | D2 = RecordDecl::Create(Importer.getToContext(), D->getTagKind(), | |||
| 2093 | DC, StartLoc, Loc, Name.getAsIdentifierInfo()); | |||
| 2094 | D2->setLexicalDeclContext(LexicalDC); | |||
| 2095 | LexicalDC->addDeclInternal(D2); | |||
| 2096 | } | |||
| 2097 | ||||
| 2098 | D2->setQualifierInfo(Importer.Import(D->getQualifierLoc())); | |||
| 2099 | if (D->isAnonymousStructOrUnion()) | |||
| 2100 | D2->setAnonymousStructOrUnion(true); | |||
| 2101 | if (PrevDecl) { | |||
| 2102 | // FIXME: do this for all Redeclarables, not just RecordDecls. | |||
| 2103 | D2->setPreviousDecl(PrevDecl); | |||
| 2104 | } | |||
| 2105 | } | |||
| 2106 | ||||
| 2107 | Importer.Imported(D, D2); | |||
| 2108 | ||||
| 2109 | if (D->isCompleteDefinition() && ImportDefinition(D, D2, IDK_Default)) | |||
| 2110 | return nullptr; | |||
| 2111 | ||||
| 2112 | return D2; | |||
| 2113 | } | |||
| 2114 | ||||
| 2115 | Decl *ASTNodeImporter::VisitEnumConstantDecl(EnumConstantDecl *D) { | |||
| 2116 | // Import the major distinguishing characteristics of this enumerator. | |||
| 2117 | DeclContext *DC, *LexicalDC; | |||
| 2118 | DeclarationName Name; | |||
| 2119 | SourceLocation Loc; | |||
| 2120 | NamedDecl *ToD; | |||
| 2121 | if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc)) | |||
| 2122 | return nullptr; | |||
| 2123 | if (ToD) | |||
| 2124 | return ToD; | |||
| 2125 | ||||
| 2126 | QualType T = Importer.Import(D->getType()); | |||
| 2127 | if (T.isNull()) | |||
| 2128 | return nullptr; | |||
| 2129 | ||||
| 2130 | // Determine whether there are any other declarations with the same name and | |||
| 2131 | // in the same context. | |||
| 2132 | if (!LexicalDC->isFunctionOrMethod()) { | |||
| 2133 | SmallVector<NamedDecl *, 4> ConflictingDecls; | |||
| 2134 | unsigned IDNS = Decl::IDNS_Ordinary; | |||
| 2135 | SmallVector<NamedDecl *, 2> FoundDecls; | |||
| 2136 | DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls); | |||
| 2137 | for (auto *FoundDecl : FoundDecls) { | |||
| 2138 | if (!FoundDecl->isInIdentifierNamespace(IDNS)) | |||
| 2139 | continue; | |||
| 2140 | ||||
| 2141 | if (auto *FoundEnumConstant = dyn_cast<EnumConstantDecl>(FoundDecl)) { | |||
| 2142 | if (IsStructuralMatch(D, FoundEnumConstant)) | |||
| 2143 | return Importer.Imported(D, FoundEnumConstant); | |||
| 2144 | } | |||
| 2145 | ||||
| 2146 | ConflictingDecls.push_back(FoundDecl); | |||
| 2147 | } | |||
| 2148 | ||||
| 2149 | if (!ConflictingDecls.empty()) { | |||
| 2150 | Name = Importer.HandleNameConflict(Name, DC, IDNS, | |||
| 2151 | ConflictingDecls.data(), | |||
| 2152 | ConflictingDecls.size()); | |||
| 2153 | if (!Name) | |||
| 2154 | return nullptr; | |||
| 2155 | } | |||
| 2156 | } | |||
| 2157 | ||||
| 2158 | Expr *Init = Importer.Import(D->getInitExpr()); | |||
| 2159 | if (D->getInitExpr() && !Init) | |||
| 2160 | return nullptr; | |||
| 2161 | ||||
| 2162 | EnumConstantDecl *ToEnumerator | |||
| 2163 | = EnumConstantDecl::Create(Importer.getToContext(), cast<EnumDecl>(DC), Loc, | |||
| 2164 | Name.getAsIdentifierInfo(), T, | |||
| 2165 | Init, D->getInitVal()); | |||
| 2166 | ToEnumerator->setAccess(D->getAccess()); | |||
| 2167 | ToEnumerator->setLexicalDeclContext(LexicalDC); | |||
| 2168 | Importer.Imported(D, ToEnumerator); | |||
| 2169 | LexicalDC->addDeclInternal(ToEnumerator); | |||
| 2170 | return ToEnumerator; | |||
| 2171 | } | |||
| 2172 | ||||
| 2173 | bool ASTNodeImporter::ImportTemplateInformation(FunctionDecl *FromFD, | |||
| 2174 | FunctionDecl *ToFD) { | |||
| 2175 | switch (FromFD->getTemplatedKind()) { | |||
| 2176 | case FunctionDecl::TK_NonTemplate: | |||
| 2177 | case FunctionDecl::TK_FunctionTemplate: | |||
| 2178 | return false; | |||
| 2179 | ||||
| 2180 | case FunctionDecl::TK_MemberSpecialization: { | |||
| 2181 | auto *InstFD = cast_or_null<FunctionDecl>( | |||
| 2182 | Importer.Import(FromFD->getInstantiatedFromMemberFunction())); | |||
| 2183 | if (!InstFD) | |||
| 2184 | return true; | |||
| 2185 | ||||
| 2186 | TemplateSpecializationKind TSK = FromFD->getTemplateSpecializationKind(); | |||
| 2187 | SourceLocation POI = Importer.Import( | |||
| 2188 | FromFD->getMemberSpecializationInfo()->getPointOfInstantiation()); | |||
| 2189 | ToFD->setInstantiationOfMemberFunction(InstFD, TSK); | |||
| 2190 | ToFD->getMemberSpecializationInfo()->setPointOfInstantiation(POI); | |||
| 2191 | return false; | |||
| 2192 | } | |||
| 2193 | ||||
| 2194 | case FunctionDecl::TK_FunctionTemplateSpecialization: { | |||
| 2195 | auto *FTSInfo = FromFD->getTemplateSpecializationInfo(); | |||
| 2196 | auto *Template = cast_or_null<FunctionTemplateDecl>( | |||
| 2197 | Importer.Import(FTSInfo->getTemplate())); | |||
| 2198 | if (!Template) | |||
| 2199 | return true; | |||
| 2200 | TemplateSpecializationKind TSK = FTSInfo->getTemplateSpecializationKind(); | |||
| 2201 | ||||
| 2202 | // Import template arguments. | |||
| 2203 | auto TemplArgs = FTSInfo->TemplateArguments->asArray(); | |||
| 2204 | SmallVector<TemplateArgument, 8> ToTemplArgs; | |||
| 2205 | if (ImportTemplateArguments(TemplArgs.data(), TemplArgs.size(), | |||
| 2206 | ToTemplArgs)) | |||
| 2207 | return true; | |||
| 2208 | ||||
| 2209 | TemplateArgumentList *ToTAList = TemplateArgumentList::CreateCopy( | |||
| 2210 | Importer.getToContext(), ToTemplArgs); | |||
| 2211 | ||||
| 2212 | TemplateArgumentListInfo ToTAInfo; | |||
| 2213 | const auto *FromTAArgsAsWritten = FTSInfo->TemplateArgumentsAsWritten; | |||
| 2214 | if (FromTAArgsAsWritten) | |||
| 2215 | if (ImportTemplateArgumentListInfo(*FromTAArgsAsWritten, ToTAInfo)) | |||
| 2216 | return true; | |||
| 2217 | ||||
| 2218 | SourceLocation POI = Importer.Import(FTSInfo->getPointOfInstantiation()); | |||
| 2219 | ||||
| 2220 | ToFD->setFunctionTemplateSpecialization( | |||
| 2221 | Template, ToTAList, /* InsertPos= */ nullptr, | |||
| 2222 | TSK, FromTAArgsAsWritten ? &ToTAInfo : nullptr, POI); | |||
| 2223 | return false; | |||
| 2224 | } | |||
| 2225 | ||||
| 2226 | case FunctionDecl::TK_DependentFunctionTemplateSpecialization: { | |||
| 2227 | auto *FromInfo = FromFD->getDependentSpecializationInfo(); | |||
| 2228 | UnresolvedSet<8> TemplDecls; | |||
| 2229 | unsigned NumTemplates = FromInfo->getNumTemplates(); | |||
| 2230 | for (unsigned I = 0; I < NumTemplates; I++) { | |||
| 2231 | if (auto *ToFTD = cast_or_null<FunctionTemplateDecl>( | |||
| 2232 | Importer.Import(FromInfo->getTemplate(I)))) | |||
| 2233 | TemplDecls.addDecl(ToFTD); | |||
| 2234 | else | |||
| 2235 | return true; | |||
| 2236 | } | |||
| 2237 | ||||
| 2238 | // Import TemplateArgumentListInfo. | |||
| 2239 | TemplateArgumentListInfo ToTAInfo; | |||
| 2240 | if (ImportTemplateArgumentListInfo( | |||
| 2241 | FromInfo->getLAngleLoc(), FromInfo->getRAngleLoc(), | |||
| 2242 | llvm::makeArrayRef(FromInfo->getTemplateArgs(), | |||
| 2243 | FromInfo->getNumTemplateArgs()), | |||
| 2244 | ToTAInfo)) | |||
| 2245 | return true; | |||
| 2246 | ||||
| 2247 | ToFD->setDependentTemplateSpecialization(Importer.getToContext(), | |||
| 2248 | TemplDecls, ToTAInfo); | |||
| 2249 | return false; | |||
| 2250 | } | |||
| 2251 | } | |||
| 2252 | llvm_unreachable("All cases should be covered!")::llvm::llvm_unreachable_internal("All cases should be covered!" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/lib/AST/ASTImporter.cpp" , 2252); | |||
| 2253 | } | |||
| 2254 | ||||
| 2255 | Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) { | |||
| 2256 | // Import the major distinguishing characteristics of this function. | |||
| 2257 | DeclContext *DC, *LexicalDC; | |||
| 2258 | DeclarationName Name; | |||
| 2259 | SourceLocation Loc; | |||
| 2260 | NamedDecl *ToD; | |||
| 2261 | if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc)) | |||
| 2262 | return nullptr; | |||
| 2263 | if (ToD) | |||
| 2264 | return ToD; | |||
| 2265 | ||||
| 2266 | const FunctionDecl *FoundWithoutBody = nullptr; | |||
| 2267 | ||||
| 2268 | // Try to find a function in our own ("to") context with the same name, same | |||
| 2269 | // type, and in the same context as the function we're importing. | |||
| 2270 | if (!LexicalDC->isFunctionOrMethod()) { | |||
| 2271 | SmallVector<NamedDecl *, 4> ConflictingDecls; | |||
| 2272 | unsigned IDNS = Decl::IDNS_Ordinary; | |||
| 2273 | SmallVector<NamedDecl *, 2> FoundDecls; | |||
| 2274 | DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls); | |||
| 2275 | for (auto *FoundDecl : FoundDecls) { | |||
| 2276 | if (!FoundDecl->isInIdentifierNamespace(IDNS)) | |||
| 2277 | continue; | |||
| 2278 | ||||
| 2279 | if (auto *FoundFunction = dyn_cast<FunctionDecl>(FoundDecl)) { | |||
| 2280 | if (FoundFunction->hasExternalFormalLinkage() && | |||
| 2281 | D->hasExternalFormalLinkage()) { | |||
| 2282 | if (Importer.IsStructurallyEquivalent(D->getType(), | |||
| 2283 | FoundFunction->getType())) { | |||
| 2284 | // FIXME: Actually try to merge the body and other attributes. | |||
| 2285 | const FunctionDecl *FromBodyDecl = nullptr; | |||
| 2286 | D->hasBody(FromBodyDecl); | |||
| 2287 | if (D == FromBodyDecl && !FoundFunction->hasBody()) { | |||
| 2288 | // This function is needed to merge completely. | |||
| 2289 | FoundWithoutBody = FoundFunction; | |||
| 2290 | break; | |||
| 2291 | } | |||
| 2292 | return Importer.Imported(D, FoundFunction); | |||
| 2293 | } | |||
| 2294 | ||||
| 2295 | // FIXME: Check for overloading more carefully, e.g., by boosting | |||
| 2296 | // Sema::IsOverload out to the AST library. | |||
| 2297 | ||||
| 2298 | // Function overloading is okay in C++. | |||
| 2299 | if (Importer.getToContext().getLangOpts().CPlusPlus) | |||
| 2300 | continue; | |||
| 2301 | ||||
| 2302 | // Complain about inconsistent function types. | |||
| 2303 | Importer.ToDiag(Loc, diag::err_odr_function_type_inconsistent) | |||
| 2304 | << Name << D->getType() << FoundFunction->getType(); | |||
| 2305 | Importer.ToDiag(FoundFunction->getLocation(), | |||
| 2306 | diag::note_odr_value_here) | |||
| 2307 | << FoundFunction->getType(); | |||
| 2308 | } | |||
| 2309 | } | |||
| 2310 | ||||
| 2311 | ConflictingDecls.push_back(FoundDecl); | |||
| 2312 | } | |||
| 2313 | ||||
| 2314 | if (!ConflictingDecls.empty()) { | |||
| 2315 | Name = Importer.HandleNameConflict(Name, DC, IDNS, | |||
| 2316 | ConflictingDecls.data(), | |||
| 2317 | ConflictingDecls.size()); | |||
| 2318 | if (!Name) | |||
| 2319 | return nullptr; | |||
| 2320 | } | |||
| 2321 | } | |||
| 2322 | ||||
| 2323 | DeclarationNameInfo NameInfo(Name, Loc); | |||
| 2324 | // Import additional name location/type info. | |||
| 2325 | ImportDeclarationNameLoc(D->getNameInfo(), NameInfo); | |||
| 2326 | ||||
| 2327 | QualType FromTy = D->getType(); | |||
| 2328 | bool usedDifferentExceptionSpec = false; | |||
| 2329 | ||||
| 2330 | if (const auto *FromFPT = D->getType()->getAs<FunctionProtoType>()) { | |||
| 2331 | FunctionProtoType::ExtProtoInfo FromEPI = FromFPT->getExtProtoInfo(); | |||
| 2332 | // FunctionProtoType::ExtProtoInfo's ExceptionSpecDecl can point to the | |||
| 2333 | // FunctionDecl that we are importing the FunctionProtoType for. | |||
| 2334 | // To avoid an infinite recursion when importing, create the FunctionDecl | |||
| 2335 | // with a simplified function type and update it afterwards. | |||
| 2336 | if (FromEPI.ExceptionSpec.SourceDecl || | |||
| 2337 | FromEPI.ExceptionSpec.SourceTemplate || | |||
| 2338 | FromEPI.ExceptionSpec.NoexceptExpr) { | |||
| 2339 | FunctionProtoType::ExtProtoInfo DefaultEPI; | |||
| 2340 | FromTy = Importer.getFromContext().getFunctionType( | |||
| 2341 | FromFPT->getReturnType(), FromFPT->getParamTypes(), DefaultEPI); | |||
| 2342 | usedDifferentExceptionSpec = true; | |||
| 2343 | } | |||
| 2344 | } | |||
| 2345 | ||||
| 2346 | // Import the type. | |||
| 2347 | QualType T = Importer.Import(FromTy); | |||
| 2348 | if (T.isNull()) | |||
| 2349 | return nullptr; | |||
| 2350 | ||||
| 2351 | // Import the function parameters. | |||
| 2352 | SmallVector<ParmVarDecl *, 8> Parameters; | |||
| 2353 | for (auto P : D->parameters()) { | |||
| 2354 | auto *ToP = cast_or_null<ParmVarDecl>(Importer.Import(P)); | |||
| 2355 | if (!ToP) | |||
| 2356 | return nullptr; | |||
| 2357 | ||||
| 2358 | Parameters.push_back(ToP); | |||
| 2359 | } | |||
| 2360 | ||||
| 2361 | TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo()); | |||
| 2362 | if (D->getTypeSourceInfo() && !TInfo) | |||
| 2363 | return nullptr; | |||
| 2364 | ||||
| 2365 | // Create the imported function. | |||
| 2366 | FunctionDecl *ToFunction = nullptr; | |||
| 2367 | SourceLocation InnerLocStart = Importer.Import(D->getInnerLocStart()); | |||
| 2368 | if (auto *FromConstructor = dyn_cast<CXXConstructorDecl>(D)) { | |||
| 2369 | ToFunction = CXXConstructorDecl::Create(Importer.getToContext(), | |||
| 2370 | cast<CXXRecordDecl>(DC), | |||
| 2371 | InnerLocStart, | |||
| 2372 | NameInfo, T, TInfo, | |||
| 2373 | FromConstructor->isExplicit(), | |||
| 2374 | D->isInlineSpecified(), | |||
| 2375 | D->isImplicit(), | |||
| 2376 | D->isConstexpr()); | |||
| 2377 | if (unsigned NumInitializers = FromConstructor->getNumCtorInitializers()) { | |||
| 2378 | SmallVector<CXXCtorInitializer *, 4> CtorInitializers; | |||
| 2379 | for (auto *I : FromConstructor->inits()) { | |||
| 2380 | auto *ToI = cast_or_null<CXXCtorInitializer>(Importer.Import(I)); | |||
| 2381 | if (!ToI && I) | |||
| 2382 | return nullptr; | |||
| 2383 | CtorInitializers.push_back(ToI); | |||
| 2384 | } | |||
| 2385 | auto **Memory = | |||
| 2386 | new (Importer.getToContext()) CXXCtorInitializer *[NumInitializers]; | |||
| 2387 | std::copy(CtorInitializers.begin(), CtorInitializers.end(), Memory); | |||
| 2388 | auto *ToCtor = cast<CXXConstructorDecl>(ToFunction); | |||
| 2389 | ToCtor->setCtorInitializers(Memory); | |||
| 2390 | ToCtor->setNumCtorInitializers(NumInitializers); | |||
| 2391 | } | |||
| 2392 | } else if (isa<CXXDestructorDecl>(D)) { | |||
| 2393 | ToFunction = CXXDestructorDecl::Create(Importer.getToContext(), | |||
| 2394 | cast<CXXRecordDecl>(DC), | |||
| 2395 | InnerLocStart, | |||
| 2396 | NameInfo, T, TInfo, | |||
| 2397 | D->isInlineSpecified(), | |||
| 2398 | D->isImplicit()); | |||
| 2399 | } else if (auto *FromConversion = dyn_cast<CXXConversionDecl>(D)) { | |||
| 2400 | ToFunction = CXXConversionDecl::Create(Importer.getToContext(), | |||
| 2401 | cast<CXXRecordDecl>(DC), | |||
| 2402 | InnerLocStart, | |||
| 2403 | NameInfo, T, TInfo, | |||
| 2404 | D->isInlineSpecified(), | |||
| 2405 | FromConversion->isExplicit(), | |||
| 2406 | D->isConstexpr(), | |||
| 2407 | Importer.Import(D->getLocEnd())); | |||
| 2408 | } else if (auto *Method = dyn_cast<CXXMethodDecl>(D)) { | |||
| 2409 | ToFunction = CXXMethodDecl::Create(Importer.getToContext(), | |||
| 2410 | cast<CXXRecordDecl>(DC), | |||
| 2411 | InnerLocStart, | |||
| 2412 | NameInfo, T, TInfo, | |||
| 2413 | Method->getStorageClass(), | |||
| 2414 | Method->isInlineSpecified(), | |||
| 2415 | D->isConstexpr(), | |||
| 2416 | Importer.Import(D->getLocEnd())); | |||
| 2417 | } else { | |||
| 2418 | ToFunction = FunctionDecl::Create(Importer.getToContext(), DC, | |||
| 2419 | InnerLocStart, | |||
| 2420 | NameInfo, T, TInfo, D->getStorageClass(), | |||
| 2421 | D->isInlineSpecified(), | |||
| 2422 | D->hasWrittenPrototype(), | |||
| 2423 | D->isConstexpr()); | |||
| 2424 | } | |||
| 2425 | ||||
| 2426 | // Import the qualifier, if any. | |||
| 2427 | ToFunction->setQualifierInfo(Importer.Import(D->getQualifierLoc())); | |||
| 2428 | ToFunction->setAccess(D->getAccess()); | |||
| 2429 | ToFunction->setLexicalDeclContext(LexicalDC); | |||
| 2430 | ToFunction->setVirtualAsWritten(D->isVirtualAsWritten()); | |||
| 2431 | ToFunction->setTrivial(D->isTrivial()); | |||
| 2432 | ToFunction->setPure(D->isPure()); | |||
| 2433 | Importer.Imported(D, ToFunction); | |||
| 2434 | ||||
| 2435 | // Set the parameters. | |||
| 2436 | for (auto *Param : Parameters) { | |||
| 2437 | Param->setOwningFunction(ToFunction); | |||
| 2438 | ToFunction->addDeclInternal(Param); | |||
| 2439 | } | |||
| 2440 | ToFunction->setParams(Parameters); | |||
| 2441 | ||||
| 2442 | if (FoundWithoutBody) { | |||
| 2443 | auto *Recent = const_cast<FunctionDecl *>( | |||
| 2444 | FoundWithoutBody->getMostRecentDecl()); | |||
| 2445 | ToFunction->setPreviousDecl(Recent); | |||
| 2446 | } | |||
| 2447 | ||||
| 2448 | // We need to complete creation of FunctionProtoTypeLoc manually with setting | |||
| 2449 | // params it refers to. | |||
| 2450 | if (TInfo) { | |||
| 2451 | if (auto ProtoLoc = | |||
| 2452 | TInfo->getTypeLoc().IgnoreParens().getAs<FunctionProtoTypeLoc>()) { | |||
| 2453 | for (unsigned I = 0, N = Parameters.size(); I != N; ++I) | |||
| 2454 | ProtoLoc.setParam(I, Parameters[I]); | |||
| 2455 | } | |||
| 2456 | } | |||
| 2457 | ||||
| 2458 | if (usedDifferentExceptionSpec) { | |||
| 2459 | // Update FunctionProtoType::ExtProtoInfo. | |||
| 2460 | QualType T = Importer.Import(D->getType()); | |||
| 2461 | if (T.isNull()) | |||
| 2462 | return nullptr; | |||
| 2463 | ToFunction->setType(T); | |||
| 2464 | } | |||
| 2465 | ||||
| 2466 | // Import the body, if any. | |||
| 2467 | if (Stmt *FromBody = D->getBody()) { | |||
| 2468 | if (Stmt *ToBody = Importer.Import(FromBody)) { | |||
| 2469 | ToFunction->setBody(ToBody); | |||
| 2470 | } | |||
| 2471 | } | |||
| 2472 | ||||
| 2473 | // FIXME: Other bits to merge? | |||
| 2474 | ||||
| 2475 | // If it is a template, import all related things. | |||
| 2476 | if (ImportTemplateInformation(D, ToFunction)) | |||
| 2477 | return nullptr; | |||
| 2478 | ||||
| 2479 | // Add this function to the lexical context. | |||
| 2480 | // NOTE: If the function is templated declaration, it should be not added into | |||
| 2481 | // LexicalDC. But described template is imported during import of | |||
| 2482 | // FunctionTemplateDecl (it happens later). So, we use source declaration | |||
| 2483 | // to determine if we should add the result function. | |||
| 2484 | if (!D->getDescribedFunctionTemplate()) | |||
| 2485 | LexicalDC->addDeclInternal(ToFunction); | |||
| 2486 | ||||
| 2487 | if (auto *FromCXXMethod = dyn_cast<CXXMethodDecl>(D)) | |||
| 2488 | ImportOverrides(cast<CXXMethodDecl>(ToFunction), FromCXXMethod); | |||
| 2489 | ||||
| 2490 | return ToFunction; | |||
| 2491 | } | |||
| 2492 | ||||
| 2493 | Decl *ASTNodeImporter::VisitCXXMethodDecl(CXXMethodDecl *D) { | |||
| 2494 | return VisitFunctionDecl(D); | |||
| 2495 | } | |||
| 2496 | ||||
| 2497 | Decl *ASTNodeImporter::VisitCXXConstructorDecl(CXXConstructorDecl *D) { | |||
| 2498 | return VisitCXXMethodDecl(D); | |||
| 2499 | } | |||
| 2500 | ||||
| 2501 | Decl *ASTNodeImporter::VisitCXXDestructorDecl(CXXDestructorDecl *D) { | |||
| 2502 | return VisitCXXMethodDecl(D); | |||
| 2503 | } | |||
| 2504 | ||||
| 2505 | Decl *ASTNodeImporter::VisitCXXConversionDecl(CXXConversionDecl *D) { | |||
| 2506 | return VisitCXXMethodDecl(D); | |||
| 2507 | } | |||
| 2508 | ||||
| 2509 | static unsigned getFieldIndex(Decl *F) { | |||
| 2510 | auto *Owner = dyn_cast<RecordDecl>(F->getDeclContext()); | |||
| 2511 | if (!Owner) | |||
| 2512 | return 0; | |||
| 2513 | ||||
| 2514 | unsigned Index = 1; | |||
| 2515 | for (const auto *D : Owner->noload_decls()) { | |||
| 2516 | if (D == F) | |||
| 2517 | return Index; | |||
| 2518 | ||||
| 2519 | if (isa<FieldDecl>(*D) || isa<IndirectFieldDecl>(*D)) | |||
| 2520 | ++Index; | |||
| 2521 | } | |||
| 2522 | ||||
| 2523 | return Index; | |||
| 2524 | } | |||
| 2525 | ||||
| 2526 | Decl *ASTNodeImporter::VisitFieldDecl(FieldDecl *D) { | |||
| 2527 | // Import the major distinguishing characteristics of a variable. | |||
| 2528 | DeclContext *DC, *LexicalDC; | |||
| 2529 | DeclarationName Name; | |||
| 2530 | SourceLocation Loc; | |||
| 2531 | NamedDecl *ToD; | |||
| 2532 | if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc)) | |||
| 2533 | return nullptr; | |||
| 2534 | if (ToD) | |||
| 2535 | return ToD; | |||
| 2536 | ||||
| 2537 | // Determine whether we've already imported this field. | |||
| 2538 | SmallVector<NamedDecl *, 2> FoundDecls; | |||
| 2539 | DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls); | |||
| 2540 | for (auto *FoundDecl : FoundDecls) { | |||
| 2541 | if (auto *FoundField = dyn_cast<FieldDecl>(FoundDecl)) { | |||
| 2542 | // For anonymous fields, match up by index. | |||
| 2543 | if (!Name && getFieldIndex(D) != getFieldIndex(FoundField)) | |||
| 2544 | continue; | |||
| 2545 | ||||
| 2546 | if (Importer.IsStructurallyEquivalent(D->getType(), | |||
| 2547 | FoundField->getType())) { | |||
| 2548 | Importer.Imported(D, FoundField); | |||
| 2549 | return FoundField; | |||
| 2550 | } | |||
| 2551 | ||||
| 2552 | Importer.ToDiag(Loc, diag::err_odr_field_type_inconsistent) | |||
| 2553 | << Name << D->getType() << FoundField->getType(); | |||
| 2554 | Importer.ToDiag(FoundField->getLocation(), diag::note_odr_value_here) | |||
| 2555 | << FoundField->getType(); | |||
| 2556 | return nullptr; | |||
| 2557 | } | |||
| 2558 | } | |||
| 2559 | ||||
| 2560 | // Import the type. | |||
| 2561 | QualType T = Importer.Import(D->getType()); | |||
| 2562 | if (T.isNull()) | |||
| 2563 | return nullptr; | |||
| 2564 | ||||
| 2565 | TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo()); | |||
| 2566 | Expr *BitWidth = Importer.Import(D->getBitWidth()); | |||
| 2567 | if (!BitWidth && D->getBitWidth()) | |||
| 2568 | return nullptr; | |||
| 2569 | ||||
| 2570 | FieldDecl *ToField = FieldDecl::Create(Importer.getToContext(), DC, | |||
| 2571 | Importer.Import(D->getInnerLocStart()), | |||
| 2572 | Loc, Name.getAsIdentifierInfo(), | |||
| 2573 | T, TInfo, BitWidth, D->isMutable(), | |||
| 2574 | D->getInClassInitStyle()); | |||
| 2575 | ToField->setAccess(D->getAccess()); | |||
| 2576 | ToField->setLexicalDeclContext(LexicalDC); | |||
| 2577 | if (Expr *FromInitializer = D->getInClassInitializer()) { | |||
| 2578 | Expr *ToInitializer = Importer.Import(FromInitializer); | |||
| 2579 | if (ToInitializer) | |||
| 2580 | ToField->setInClassInitializer(ToInitializer); | |||
| 2581 | else | |||
| 2582 | return nullptr; | |||
| 2583 | } | |||
| 2584 | ToField->setImplicit(D->isImplicit()); | |||
| 2585 | Importer.Imported(D, ToField); | |||
| 2586 | LexicalDC->addDeclInternal(ToField); | |||
| 2587 | return ToField; | |||
| 2588 | } | |||
| 2589 | ||||
| 2590 | Decl *ASTNodeImporter::VisitIndirectFieldDecl(IndirectFieldDecl *D) { | |||
| 2591 | // Import the major distinguishing characteristics of a variable. | |||
| 2592 | DeclContext *DC, *LexicalDC; | |||
| 2593 | DeclarationName Name; | |||
| 2594 | SourceLocation Loc; | |||
| 2595 | NamedDecl *ToD; | |||
| 2596 | if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc)) | |||
| 2597 | return nullptr; | |||
| 2598 | if (ToD) | |||
| 2599 | return ToD; | |||
| 2600 | ||||
| 2601 | // Determine whether we've already imported this field. | |||
| 2602 | SmallVector<NamedDecl *, 2> FoundDecls; | |||
| 2603 | DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls); | |||
| 2604 | for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) { | |||
| 2605 | if (auto *FoundField = dyn_cast<IndirectFieldDecl>(FoundDecls[I])) { | |||
| 2606 | // For anonymous indirect fields, match up by index. | |||
| 2607 | if (!Name && getFieldIndex(D) != getFieldIndex(FoundField)) | |||
| 2608 | continue; | |||
| 2609 | ||||
| 2610 | if (Importer.IsStructurallyEquivalent(D->getType(), | |||
| 2611 | FoundField->getType(), | |||
| 2612 | !Name.isEmpty())) { | |||
| 2613 | Importer.Imported(D, FoundField); | |||
| 2614 | return FoundField; | |||
| 2615 | } | |||
| 2616 | ||||
| 2617 | // If there are more anonymous fields to check, continue. | |||
| 2618 | if (!Name && I < N-1) | |||
| 2619 | continue; | |||
| 2620 | ||||
| 2621 | Importer.ToDiag(Loc, diag::err_odr_field_type_inconsistent) | |||
| 2622 | << Name << D->getType() << FoundField->getType(); | |||
| 2623 | Importer.ToDiag(FoundField->getLocation(), diag::note_odr_value_here) | |||
| 2624 | << FoundField->getType(); | |||
| 2625 | return nullptr; | |||
| 2626 | } | |||
| 2627 | } | |||
| 2628 | ||||
| 2629 | // Import the type. | |||
| 2630 | QualType T = Importer.Import(D->getType()); | |||
| 2631 | if (T.isNull()) | |||
| 2632 | return nullptr; | |||
| 2633 | ||||
| 2634 | auto **NamedChain = | |||
| 2635 | new (Importer.getToContext()) NamedDecl*[D->getChainingSize()]; | |||
| 2636 | ||||
| 2637 | unsigned i = 0; | |||
| 2638 | for (auto *PI : D->chain()) { | |||
| 2639 | Decl *D = Importer.Import(PI); | |||
| 2640 | if (!D) | |||
| 2641 | return nullptr; | |||
| 2642 | NamedChain[i++] = cast<NamedDecl>(D); | |||
| 2643 | } | |||
| 2644 | ||||
| 2645 | IndirectFieldDecl *ToIndirectField = IndirectFieldDecl::Create( | |||
| 2646 | Importer.getToContext(), DC, Loc, Name.getAsIdentifierInfo(), T, | |||
| 2647 | {NamedChain, D->getChainingSize()}); | |||
| 2648 | ||||
| 2649 | for (const auto *Attr : D->attrs()) | |||
| 2650 | ToIndirectField->addAttr(Attr->clone(Importer.getToContext())); | |||
| 2651 | ||||
| 2652 | ToIndirectField->setAccess(D->getAccess()); | |||
| 2653 | ToIndirectField->setLexicalDeclContext(LexicalDC); | |||
| 2654 | Importer.Imported(D, ToIndirectField); | |||
| 2655 | LexicalDC->addDeclInternal(ToIndirectField); | |||
| 2656 | return ToIndirectField; | |||
| 2657 | } | |||
| 2658 | ||||
| 2659 | Decl *ASTNodeImporter::VisitFriendDecl(FriendDecl *D) { | |||
| 2660 | // Import the major distinguishing characteristics of a declaration. | |||
| 2661 | DeclContext *DC = Importer.ImportContext(D->getDeclContext()); | |||
| 2662 | DeclContext *LexicalDC = D->getDeclContext() == D->getLexicalDeclContext() | |||
| 2663 | ? DC : Importer.ImportContext(D->getLexicalDeclContext()); | |||
| 2664 | if (!DC || !LexicalDC) | |||
| 2665 | return nullptr; | |||
| 2666 | ||||
| 2667 | // Determine whether we've already imported this decl. | |||
| 2668 | // FriendDecl is not a NamedDecl so we cannot use localUncachedLookup. | |||
| 2669 | auto *RD = cast<CXXRecordDecl>(DC); | |||
| 2670 | FriendDecl *ImportedFriend = RD->getFirstFriend(); | |||
| 2671 | StructuralEquivalenceContext Context( | |||
| 2672 | Importer.getFromContext(), Importer.getToContext(), | |||
| 2673 | Importer.getNonEquivalentDecls(), false, false); | |||
| 2674 | ||||
| 2675 | while (ImportedFriend) { | |||
| 2676 | if (D->getFriendDecl() && ImportedFriend->getFriendDecl()) { | |||
| 2677 | if (Context.IsStructurallyEquivalent(D->getFriendDecl(), | |||
| 2678 | ImportedFriend->getFriendDecl())) | |||
| 2679 | return Importer.Imported(D, ImportedFriend); | |||
| 2680 | ||||
| 2681 | } else if (D->getFriendType() && ImportedFriend->getFriendType()) { | |||
| 2682 | if (Importer.IsStructurallyEquivalent( | |||
| 2683 | D->getFriendType()->getType(), | |||
| 2684 | ImportedFriend->getFriendType()->getType(), true)) | |||
| 2685 | return Importer.Imported(D, ImportedFriend); | |||
| 2686 | } | |||
| 2687 | ImportedFriend = ImportedFriend->getNextFriend(); | |||
| 2688 | } | |||
| 2689 | ||||
| 2690 | // Not found. Create it. | |||
| 2691 | FriendDecl::FriendUnion ToFU; | |||
| 2692 | if (NamedDecl *FriendD = D->getFriendDecl()) | |||
| 2693 | ToFU = cast_or_null<NamedDecl>(Importer.Import(FriendD)); | |||
| 2694 | else | |||
| 2695 | ToFU = Importer.Import(D->getFriendType()); | |||
| 2696 | if (!ToFU) | |||
| 2697 | return nullptr; | |||
| 2698 | ||||
| 2699 | SmallVector<TemplateParameterList *, 1> ToTPLists(D->NumTPLists); | |||
| 2700 | auto **FromTPLists = D->getTrailingObjects<TemplateParameterList *>(); | |||
| 2701 | for (unsigned I = 0; I < D->NumTPLists; I++) { | |||
| 2702 | TemplateParameterList *List = ImportTemplateParameterList(FromTPLists[I]); | |||
| 2703 | if (!List) | |||
| 2704 | return nullptr; | |||
| 2705 | ToTPLists[I] = List; | |||
| 2706 | } | |||
| 2707 | ||||
| 2708 | FriendDecl *FrD = FriendDecl::Create(Importer.getToContext(), DC, | |||
| 2709 | Importer.Import(D->getLocation()), | |||
| 2710 | ToFU, Importer.Import(D->getFriendLoc()), | |||
| 2711 | ToTPLists); | |||
| 2712 | ||||
| 2713 | Importer.Imported(D, FrD); | |||
| 2714 | RD->pushFriendDecl(FrD); | |||
| 2715 | ||||
| 2716 | FrD->setAccess(D->getAccess()); | |||
| 2717 | FrD->setLexicalDeclContext(LexicalDC); | |||
| 2718 | LexicalDC->addDeclInternal(FrD); | |||
| 2719 | return FrD; | |||
| 2720 | } | |||
| 2721 | ||||
| 2722 | Decl *ASTNodeImporter::VisitObjCIvarDecl(ObjCIvarDecl *D) { | |||
| 2723 | // Import the major distinguishing characteristics of an ivar. | |||
| 2724 | DeclContext *DC, *LexicalDC; | |||
| 2725 | DeclarationName Name; | |||
| 2726 | SourceLocation Loc; | |||
| 2727 | NamedDecl *ToD; | |||
| 2728 | if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc)) | |||
| 2729 | return nullptr; | |||
| 2730 | if (ToD) | |||
| 2731 | return ToD; | |||
| 2732 | ||||
| 2733 | // Determine whether we've already imported this ivar | |||
| 2734 | SmallVector<NamedDecl *, 2> FoundDecls; | |||
| 2735 | DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls); | |||
| 2736 | for (auto *FoundDecl : FoundDecls) { | |||
| 2737 | if (auto *FoundIvar = dyn_cast<ObjCIvarDecl>(FoundDecl)) { | |||
| 2738 | if (Importer.IsStructurallyEquivalent(D->getType(), | |||
| 2739 | FoundIvar->getType())) { | |||
| 2740 | Importer.Imported(D, FoundIvar); | |||
| 2741 | return FoundIvar; | |||
| 2742 | } | |||
| 2743 | ||||
| 2744 | Importer.ToDiag(Loc, diag::err_odr_ivar_type_inconsistent) | |||
| 2745 | << Name << D->getType() << FoundIvar->getType(); | |||
| 2746 | Importer.ToDiag(FoundIvar->getLocation(), diag::note_odr_value_here) | |||
| 2747 | << FoundIvar->getType(); | |||
| 2748 | return nullptr; | |||
| 2749 | } | |||
| 2750 | } | |||
| 2751 | ||||
| 2752 | // Import the type. | |||
| 2753 | QualType T = Importer.Import(D->getType()); | |||
| 2754 | if (T.isNull()) | |||
| 2755 | return nullptr; | |||
| 2756 | ||||
| 2757 | TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo()); | |||
| 2758 | Expr *BitWidth = Importer.Import(D->getBitWidth()); | |||
| 2759 | if (!BitWidth && D->getBitWidth()) | |||
| 2760 | return nullptr; | |||
| 2761 | ||||
| 2762 | ObjCIvarDecl *ToIvar = ObjCIvarDecl::Create(Importer.getToContext(), | |||
| 2763 | cast<ObjCContainerDecl>(DC), | |||
| 2764 | Importer.Import(D->getInnerLocStart()), | |||
| 2765 | Loc, Name.getAsIdentifierInfo(), | |||
| 2766 | T, TInfo, D->getAccessControl(), | |||
| 2767 | BitWidth, D->getSynthesize()); | |||
| 2768 | ToIvar->setLexicalDeclContext(LexicalDC); | |||
| 2769 | Importer.Imported(D, ToIvar); | |||
| 2770 | LexicalDC->addDeclInternal(ToIvar); | |||
| 2771 | return ToIvar; | |||
| 2772 | } | |||
| 2773 | ||||
| 2774 | Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) { | |||
| 2775 | // Import the major distinguishing characteristics of a variable. | |||
| 2776 | DeclContext *DC, *LexicalDC; | |||
| 2777 | DeclarationName Name; | |||
| 2778 | SourceLocation Loc; | |||
| 2779 | NamedDecl *ToD; | |||
| 2780 | if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc)) | |||
| 2781 | return nullptr; | |||
| 2782 | if (ToD) | |||
| 2783 | return ToD; | |||
| 2784 | ||||
| 2785 | // Try to find a variable in our own ("to") context with the same name and | |||
| 2786 | // in the same context as the variable we're importing. | |||
| 2787 | if (D->isFileVarDecl()) { | |||
| 2788 | VarDecl *MergeWithVar = nullptr; | |||
| 2789 | SmallVector<NamedDecl *, 4> ConflictingDecls; | |||
| 2790 | unsigned IDNS = Decl::IDNS_Ordinary; | |||
| 2791 | SmallVector<NamedDecl *, 2> FoundDecls; | |||
| 2792 | DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls); | |||
| 2793 | for (auto *FoundDecl : FoundDecls) { | |||
| 2794 | if (!FoundDecl->isInIdentifierNamespace(IDNS)) | |||
| 2795 | continue; | |||
| 2796 | ||||
| 2797 | if (auto *FoundVar = dyn_cast<VarDecl>(FoundDecl)) { | |||
| 2798 | // We have found a variable that we may need to merge with. Check it. | |||
| 2799 | if (FoundVar->hasExternalFormalLinkage() && | |||
| 2800 | D->hasExternalFormalLinkage()) { | |||
| 2801 | if (Importer.IsStructurallyEquivalent(D->getType(), | |||
| 2802 | FoundVar->getType())) { | |||
| 2803 | MergeWithVar = FoundVar; | |||
| 2804 | break; | |||
| 2805 | } | |||
| 2806 | ||||
| 2807 | const ArrayType *FoundArray | |||
| 2808 | = Importer.getToContext().getAsArrayType(FoundVar->getType()); | |||
| 2809 | const ArrayType *TArray | |||
| 2810 | = Importer.getToContext().getAsArrayType(D->getType()); | |||
| 2811 | if (FoundArray && TArray) { | |||
| 2812 | if (isa<IncompleteArrayType>(FoundArray) && | |||
| 2813 | isa<ConstantArrayType>(TArray)) { | |||
| 2814 | // Import the type. | |||
| 2815 | QualType T = Importer.Import(D->getType()); | |||
| 2816 | if (T.isNull()) | |||
| 2817 | return nullptr; | |||
| 2818 | ||||
| 2819 | FoundVar->setType(T); | |||
| 2820 | MergeWithVar = FoundVar; | |||
| 2821 | break; | |||
| 2822 | } else if (isa<IncompleteArrayType>(TArray) && | |||
| 2823 | isa<ConstantArrayType>(FoundArray)) { | |||
| 2824 | MergeWithVar = FoundVar; | |||
| 2825 | break; | |||
| 2826 | } | |||
| 2827 | } | |||
| 2828 | ||||
| 2829 | Importer.ToDiag(Loc, diag::err_odr_variable_type_inconsistent) | |||
| 2830 | << Name << D->getType() << FoundVar->getType(); | |||
| 2831 | Importer.ToDiag(FoundVar->getLocation(), diag::note_odr_value_here) | |||
| 2832 | << FoundVar->getType(); | |||
| 2833 | } | |||
| 2834 | } | |||
| 2835 | ||||
| 2836 | ConflictingDecls.push_back(FoundDecl); | |||
| 2837 | } | |||
| 2838 | ||||
| 2839 | if (MergeWithVar) { | |||
| 2840 | // An equivalent variable with external linkage has been found. Link | |||
| 2841 | // the two declarations, then merge them. | |||
| 2842 | Importer.Imported(D, MergeWithVar); | |||
| 2843 | ||||
| 2844 | if (VarDecl *DDef = D->getDefinition()) { | |||
| 2845 | if (VarDecl *ExistingDef = MergeWithVar->getDefinition()) { | |||
| 2846 | Importer.ToDiag(ExistingDef->getLocation(), | |||
| 2847 | diag::err_odr_variable_multiple_def) | |||
| 2848 | << Name; | |||
| 2849 | Importer.FromDiag(DDef->getLocation(), diag::note_odr_defined_here); | |||
| 2850 | } else { | |||
| 2851 | Expr *Init = Importer.Import(DDef->getInit()); | |||
| 2852 | MergeWithVar->setInit(Init); | |||
| 2853 | if (DDef->isInitKnownICE()) { | |||
| 2854 | EvaluatedStmt *Eval = MergeWithVar->ensureEvaluatedStmt(); | |||
| 2855 | Eval->CheckedICE = true; | |||
| 2856 | Eval->IsICE = DDef->isInitICE(); | |||
| 2857 | } | |||
| 2858 | } | |||
| 2859 | } | |||
| 2860 | ||||
| 2861 | return MergeWithVar; | |||
| 2862 | } | |||
| 2863 | ||||
| 2864 | if (!ConflictingDecls.empty()) { | |||
| 2865 | Name = Importer.HandleNameConflict(Name, DC, IDNS, | |||
| 2866 | ConflictingDecls.data(), | |||
| 2867 | ConflictingDecls.size()); | |||
| 2868 | if (!Name) | |||
| 2869 | return nullptr; | |||
| 2870 | } | |||
| 2871 | } | |||
| 2872 | ||||
| 2873 | // Import the type. | |||
| 2874 | QualType T = Importer.Import(D->getType()); | |||
| 2875 | if (T.isNull()) | |||
| 2876 | return nullptr; | |||
| 2877 | ||||
| 2878 | // Create the imported variable. | |||
| 2879 | TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo()); | |||
| 2880 | VarDecl *ToVar = VarDecl::Create(Importer.getToContext(), DC, | |||
| 2881 | Importer.Import(D->getInnerLocStart()), | |||
| 2882 | Loc, Name.getAsIdentifierInfo(), | |||
| 2883 | T, TInfo, | |||
| 2884 | D->getStorageClass()); | |||
| 2885 | ToVar->setQualifierInfo(Importer.Import(D->getQualifierLoc())); | |||
| 2886 | ToVar->setAccess(D->getAccess()); | |||
| 2887 | ToVar->setLexicalDeclContext(LexicalDC); | |||
| 2888 | Importer.Imported(D, ToVar); | |||
| 2889 | ||||
| 2890 | // Templated declarations should never appear in the enclosing DeclContext. | |||
| 2891 | if (!D->getDescribedVarTemplate()) | |||
| 2892 | LexicalDC->addDeclInternal(ToVar); | |||
| 2893 | ||||
| 2894 | if (!D->isFileVarDecl() && | |||
| 2895 | D->isUsed()) | |||
| 2896 | ToVar->setIsUsed(); | |||
| 2897 | ||||
| 2898 | // Merge the initializer. | |||
| 2899 | if (ImportDefinition(D, ToVar)) | |||
| 2900 | return nullptr; | |||
| 2901 | ||||
| 2902 | if (D->isConstexpr()) | |||
| 2903 | ToVar->setConstexpr(true); | |||
| 2904 | ||||
| 2905 | return ToVar; | |||
| 2906 | } | |||
| 2907 | ||||
| 2908 | Decl *ASTNodeImporter::VisitImplicitParamDecl(ImplicitParamDecl *D) { | |||
| 2909 | // Parameters are created in the translation unit's context, then moved | |||
| 2910 | // into the function declaration's context afterward. | |||
| 2911 | DeclContext *DC = Importer.getToContext().getTranslationUnitDecl(); | |||
| 2912 | ||||
| 2913 | // Import the name of this declaration. | |||
| 2914 | DeclarationName Name = Importer.Import(D->getDeclName()); | |||
| 2915 | if (D->getDeclName() && !Name) | |||
| 2916 | return nullptr; | |||
| 2917 | ||||
| 2918 | // Import the location of this declaration. | |||
| 2919 | SourceLocation Loc = Importer.Import(D->getLocation()); | |||
| 2920 | ||||
| 2921 | // Import the parameter's type. | |||
| 2922 | QualType T = Importer.Import(D->getType()); | |||
| 2923 | if (T.isNull()) | |||
| 2924 | return nullptr; | |||
| 2925 | ||||
| 2926 | // Create the imported parameter. | |||
| 2927 | auto *ToParm = ImplicitParamDecl::Create(Importer.getToContext(), DC, Loc, | |||
| 2928 | Name.getAsIdentifierInfo(), T, | |||
| 2929 | D->getParameterKind()); | |||
| 2930 | return Importer.Imported(D, ToParm); | |||
| 2931 | } | |||
| 2932 | ||||
| 2933 | Decl *ASTNodeImporter::VisitParmVarDecl(ParmVarDecl *D) { | |||
| 2934 | // Parameters are created in the translation unit's context, then moved | |||
| 2935 | // into the function declaration's context afterward. | |||
| 2936 | DeclContext *DC = Importer.getToContext().getTranslationUnitDecl(); | |||
| 2937 | ||||
| 2938 | // Import the name of this declaration. | |||
| 2939 | DeclarationName Name = Importer.Import(D->getDeclName()); | |||
| 2940 | if (D->getDeclName() && !Name) | |||
| 2941 | return nullptr; | |||
| 2942 | ||||
| 2943 | // Import the location of this declaration. | |||
| 2944 | SourceLocation Loc = Importer.Import(D->getLocation()); | |||
| 2945 | ||||
| 2946 | // Import the parameter's type. | |||
| 2947 | QualType T = Importer.Import(D->getType()); | |||
| 2948 | if (T.isNull()) | |||
| 2949 | return nullptr; | |||
| 2950 | ||||
| 2951 | // Create the imported parameter. | |||
| 2952 | TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo()); | |||
| 2953 | ParmVarDecl *ToParm = ParmVarDecl::Create(Importer.getToContext(), DC, | |||
| 2954 | Importer.Import(D->getInnerLocStart()), | |||
| 2955 | Loc, Name.getAsIdentifierInfo(), | |||
| 2956 | T, TInfo, D->getStorageClass(), | |||
| 2957 | /*DefaultArg*/ nullptr); | |||
| 2958 | ||||
| 2959 | // Set the default argument. | |||
| 2960 | ToParm->setHasInheritedDefaultArg(D->hasInheritedDefaultArg()); | |||
| 2961 | ToParm->setKNRPromoted(D->isKNRPromoted()); | |||
| 2962 | ||||
| 2963 | Expr *ToDefArg = nullptr; | |||
| 2964 | Expr *FromDefArg = nullptr; | |||
| 2965 | if (D->hasUninstantiatedDefaultArg()) { | |||
| 2966 | FromDefArg = D->getUninstantiatedDefaultArg(); | |||
| 2967 | ToDefArg = Importer.Import(FromDefArg); | |||
| 2968 | ToParm->setUninstantiatedDefaultArg(ToDefArg); | |||
| 2969 | } else if (D->hasUnparsedDefaultArg()) { | |||
| 2970 | ToParm->setUnparsedDefaultArg(); | |||
| 2971 | } else if (D->hasDefaultArg()) { | |||
| 2972 | FromDefArg = D->getDefaultArg(); | |||
| 2973 | ToDefArg = Importer.Import(FromDefArg); | |||
| 2974 | ToParm->setDefaultArg(ToDefArg); | |||
| 2975 | } | |||
| 2976 | if (FromDefArg && !ToDefArg) | |||
| 2977 | return nullptr; | |||
| 2978 | ||||
| 2979 | if (D->isObjCMethodParameter()) { | |||
| 2980 | ToParm->setObjCMethodScopeInfo(D->getFunctionScopeIndex()); | |||
| 2981 | ToParm->setObjCDeclQualifier(D->getObjCDeclQualifier()); | |||
| 2982 | } else { | |||
| 2983 | ToParm->setScopeInfo(D->getFunctionScopeDepth(), | |||
| 2984 | D->getFunctionScopeIndex()); | |||
| 2985 | } | |||
| 2986 | ||||
| 2987 | if (D->isUsed()) | |||
| 2988 | ToParm->setIsUsed(); | |||
| 2989 | ||||
| 2990 | return Importer.Imported(D, ToParm); | |||
| 2991 | } | |||
| 2992 | ||||
| 2993 | Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) { | |||
| 2994 | // Import the major distinguishing characteristics of a method. | |||
| 2995 | DeclContext *DC, *LexicalDC; | |||
| 2996 | DeclarationName Name; | |||
| 2997 | SourceLocation Loc; | |||
| 2998 | NamedDecl *ToD; | |||
| 2999 | if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc)) | |||
| 3000 | return nullptr; | |||
| 3001 | if (ToD) | |||
| 3002 | return ToD; | |||
| 3003 | ||||
| 3004 | SmallVector<NamedDecl *, 2> FoundDecls; | |||
| 3005 | DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls); | |||
| 3006 | for (auto *FoundDecl : FoundDecls) { | |||
| 3007 | if (auto *FoundMethod = dyn_cast<ObjCMethodDecl>(FoundDecl)) { | |||
| 3008 | if (FoundMethod->isInstanceMethod() != D->isInstanceMethod()) | |||
| 3009 | continue; | |||
| 3010 | ||||
| 3011 | // Check return types. | |||
| 3012 | if (!Importer.IsStructurallyEquivalent(D->getReturnType(), | |||
| 3013 | FoundMethod->getReturnType())) { | |||
| 3014 | Importer.ToDiag(Loc, diag::err_odr_objc_method_result_type_inconsistent) | |||
| 3015 | << D->isInstanceMethod() << Name << D->getReturnType() | |||
| 3016 | << FoundMethod->getReturnType(); | |||
| 3017 | Importer.ToDiag(FoundMethod->getLocation(), | |||
| 3018 | diag::note_odr_objc_method_here) | |||
| 3019 | << D->isInstanceMethod() << Name; | |||
| 3020 | return nullptr; | |||
| 3021 | } | |||
| 3022 | ||||
| 3023 | // Check the number of parameters. | |||
| 3024 | if (D->param_size() != FoundMethod->param_size()) { | |||
| 3025 | Importer.ToDiag(Loc, diag::err_odr_objc_method_num_params_inconsistent) | |||
| 3026 | << D->isInstanceMethod() << Name | |||
| 3027 | << D->param_size() << FoundMethod->param_size(); | |||
| 3028 | Importer.ToDiag(FoundMethod->getLocation(), | |||
| 3029 | diag::note_odr_objc_method_here) | |||
| 3030 | << D->isInstanceMethod() << Name; | |||
| 3031 | return nullptr; | |||
| 3032 | } | |||
| 3033 | ||||
| 3034 | // Check parameter types. | |||
| 3035 | for (ObjCMethodDecl::param_iterator P = D->param_begin(), | |||
| 3036 | PEnd = D->param_end(), FoundP = FoundMethod->param_begin(); | |||
| 3037 | P != PEnd; ++P, ++FoundP) { | |||
| 3038 | if (!Importer.IsStructurallyEquivalent((*P)->getType(), | |||
| 3039 | (*FoundP)->getType())) { | |||
| 3040 | Importer.FromDiag((*P)->getLocation(), | |||
| 3041 | diag::err_odr_objc_method_param_type_inconsistent) | |||
| 3042 | << D->isInstanceMethod() << Name | |||
| 3043 | << (*P)->getType() << (*FoundP)->getType(); | |||
| 3044 | Importer.ToDiag((*FoundP)->getLocation(), diag::note_odr_value_here) | |||
| 3045 | << (*FoundP)->getType(); | |||
| 3046 | return nullptr; | |||
| 3047 | } | |||
| 3048 | } | |||
| 3049 | ||||
| 3050 | // Check variadic/non-variadic. | |||
| 3051 | // Check the number of parameters. | |||
| 3052 | if (D->isVariadic() != FoundMethod->isVariadic()) { | |||
| 3053 | Importer.ToDiag(Loc, diag::err_odr_objc_method_variadic_inconsistent) | |||
| 3054 | << D->isInstanceMethod() << Name; | |||
| 3055 | Importer.ToDiag(FoundMethod->getLocation(), | |||
| 3056 | diag::note_odr_objc_method_here) | |||
| 3057 | << D->isInstanceMethod() << Name; | |||
| 3058 | return nullptr; | |||
| 3059 | } | |||
| 3060 | ||||
| 3061 | // FIXME: Any other bits we need to merge? | |||
| 3062 | return Importer.Imported(D, FoundMethod); | |||
| 3063 | } | |||
| 3064 | } | |||
| 3065 | ||||
| 3066 | // Import the result type. | |||
| 3067 | QualType ResultTy = Importer.Import(D->getReturnType()); | |||
| 3068 | if (ResultTy.isNull()) | |||
| 3069 | return nullptr; | |||
| 3070 | ||||
| 3071 | TypeSourceInfo *ReturnTInfo = Importer.Import(D->getReturnTypeSourceInfo()); | |||
| 3072 | ||||
| 3073 | ObjCMethodDecl *ToMethod = ObjCMethodDecl::Create( | |||
| 3074 | Importer.getToContext(), Loc, Importer.Import(D->getLocEnd()), | |||
| 3075 | Name.getObjCSelector(), ResultTy, ReturnTInfo, DC, D->isInstanceMethod(), | |||
| 3076 | D->isVariadic(), D->isPropertyAccessor(), D->isImplicit(), D->isDefined(), | |||
| 3077 | D->getImplementationControl(), D->hasRelatedResultType()); | |||
| 3078 | ||||
| 3079 | // FIXME: When we decide to merge method definitions, we'll need to | |||
| 3080 | // deal with implicit parameters. | |||
| 3081 | ||||
| 3082 | // Import the parameters | |||
| 3083 | SmallVector<ParmVarDecl *, 5> ToParams; | |||
| 3084 | for (auto *FromP : D->parameters()) { | |||
| 3085 | auto *ToP = cast_or_null<ParmVarDecl>(Importer.Import(FromP)); | |||
| 3086 | if (!ToP) | |||
| 3087 | return nullptr; | |||
| 3088 | ||||
| 3089 | ToParams.push_back(ToP); | |||
| 3090 | } | |||
| 3091 | ||||
| 3092 | // Set the parameters. | |||
| 3093 | for (auto *ToParam : ToParams) { | |||
| 3094 | ToParam->setOwningFunction(ToMethod); | |||
| 3095 | ToMethod->addDeclInternal(ToParam); | |||
| 3096 | } | |||
| 3097 | ||||
| 3098 | SmallVector<SourceLocation, 12> SelLocs; | |||
| 3099 | D->getSelectorLocs(SelLocs); | |||
| 3100 | for (auto &Loc : SelLocs) | |||
| 3101 | Loc = Importer.Import(Loc); | |||
| 3102 | ||||
| 3103 | ToMethod->setMethodParams(Importer.getToContext(), ToParams, SelLocs); | |||
| 3104 | ||||
| 3105 | ToMethod->setLexicalDeclContext(LexicalDC); | |||
| 3106 | Importer.Imported(D, ToMethod); | |||
| 3107 | LexicalDC->addDeclInternal(ToMethod); | |||
| 3108 | return ToMethod; | |||
| 3109 | } | |||
| 3110 | ||||
| 3111 | Decl *ASTNodeImporter::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) { | |||
| 3112 | // Import the major distinguishing characteristics of a category. | |||
| 3113 | DeclContext *DC, *LexicalDC; | |||
| 3114 | DeclarationName Name; | |||
| 3115 | SourceLocation Loc; | |||
| 3116 | NamedDecl *ToD; | |||
| 3117 | if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc)) | |||
| 3118 | return nullptr; | |||
| 3119 | if (ToD) | |||
| 3120 | return ToD; | |||
| 3121 | ||||
| 3122 | TypeSourceInfo *BoundInfo = Importer.Import(D->getTypeSourceInfo()); | |||
| 3123 | if (!BoundInfo) | |||
| 3124 | return nullptr; | |||
| 3125 | ||||
| 3126 | ObjCTypeParamDecl *Result = ObjCTypeParamDecl::Create( | |||
| 3127 | Importer.getToContext(), DC, | |||
| 3128 | D->getVariance(), | |||
| 3129 | Importer.Import(D->getVarianceLoc()), | |||
| 3130 | D->getIndex(), | |||
| 3131 | Importer.Import(D->getLocation()), | |||
| 3132 | Name.getAsIdentifierInfo(), | |||
| 3133 | Importer.Import(D->getColonLoc()), | |||
| 3134 | BoundInfo); | |||
| 3135 | Importer.Imported(D, Result); | |||
| 3136 | Result->setLexicalDeclContext(LexicalDC); | |||
| 3137 | return Result; | |||
| 3138 | } | |||
| 3139 | ||||
| 3140 | Decl *ASTNodeImporter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) { | |||
| 3141 | // Import the major distinguishing characteristics of a category. | |||
| 3142 | DeclContext *DC, *LexicalDC; | |||
| 3143 | DeclarationName Name; | |||
| 3144 | SourceLocation Loc; | |||
| 3145 | NamedDecl *ToD; | |||
| 3146 | if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc)) | |||
| 3147 | return nullptr; | |||
| 3148 | if (ToD) | |||
| 3149 | return ToD; | |||
| 3150 | ||||
| 3151 | auto *ToInterface = | |||
| 3152 | cast_or_null<ObjCInterfaceDecl>(Importer.Import(D->getClassInterface())); | |||
| 3153 | if (!ToInterface) | |||
| 3154 | return nullptr; | |||
| 3155 | ||||
| 3156 | // Determine if we've already encountered this category. | |||
| 3157 | ObjCCategoryDecl *MergeWithCategory | |||
| 3158 | = ToInterface->FindCategoryDeclaration(Name.getAsIdentifierInfo()); | |||
| 3159 | ObjCCategoryDecl *ToCategory = MergeWithCategory; | |||
| 3160 | if (!ToCategory) { | |||
| 3161 | ToCategory = ObjCCategoryDecl::Create(Importer.getToContext(), DC, | |||
| 3162 | Importer.Import(D->getAtStartLoc()), | |||
| 3163 | Loc, | |||
| 3164 | Importer.Import(D->getCategoryNameLoc()), | |||
| 3165 | Name.getAsIdentifierInfo(), | |||
| 3166 | ToInterface, | |||
| 3167 | /*TypeParamList=*/nullptr, | |||
| 3168 | Importer.Import(D->getIvarLBraceLoc()), | |||
| 3169 | Importer.Import(D->getIvarRBraceLoc())); | |||
| 3170 | ToCategory->setLexicalDeclContext(LexicalDC); | |||
| 3171 | LexicalDC->addDeclInternal(ToCategory); | |||
| 3172 | Importer.Imported(D, ToCategory); | |||
| 3173 | // Import the type parameter list after calling Imported, to avoid | |||
| 3174 | // loops when bringing in their DeclContext. | |||
| 3175 | ToCategory->setTypeParamList(ImportObjCTypeParamList( | |||
| 3176 | D->getTypeParamList())); | |||
| 3177 | ||||
| 3178 | // Import protocols | |||
| 3179 | SmallVector<ObjCProtocolDecl *, 4> Protocols; | |||
| 3180 | SmallVector<SourceLocation, 4> ProtocolLocs; | |||
| 3181 | ObjCCategoryDecl::protocol_loc_iterator FromProtoLoc | |||
| 3182 | = D->protocol_loc_begin(); | |||
| 3183 | for (ObjCCategoryDecl::protocol_iterator FromProto = D->protocol_begin(), | |||
| 3184 | FromProtoEnd = D->protocol_end(); | |||
| 3185 | FromProto != FromProtoEnd; | |||
| 3186 | ++FromProto, ++FromProtoLoc) { | |||
| 3187 | auto *ToProto = | |||
| 3188 | cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto)); | |||
| 3189 | if (!ToProto) | |||
| 3190 | return nullptr; | |||
| 3191 | Protocols.push_back(ToProto); | |||
| 3192 | ProtocolLocs.push_back(Importer.Import(*FromProtoLoc)); | |||
| 3193 | } | |||
| 3194 | ||||
| 3195 | // FIXME: If we're merging, make sure that the protocol list is the same. | |||
| 3196 | ToCategory->setProtocolList(Protocols.data(), Protocols.size(), | |||
| 3197 | ProtocolLocs.data(), Importer.getToContext()); | |||
| 3198 | } else { | |||
| 3199 | Importer.Imported(D, ToCategory); | |||
| 3200 | } | |||
| 3201 | ||||
| 3202 | // Import all of the members of this category. | |||
| 3203 | ImportDeclContext(D); | |||
| 3204 | ||||
| 3205 | // If we have an implementation, import it as well. | |||
| 3206 | if (D->getImplementation()) { | |||
| 3207 | auto *Impl = | |||
| 3208 | cast_or_null<ObjCCategoryImplDecl>( | |||
| 3209 | Importer.Import(D->getImplementation())); | |||
| 3210 | if (!Impl) | |||
| 3211 | return nullptr; | |||
| 3212 | ||||
| 3213 | ToCategory->setImplementation(Impl); | |||
| 3214 | } | |||
| 3215 | ||||
| 3216 | return ToCategory; | |||
| 3217 | } | |||
| 3218 | ||||
| 3219 | bool ASTNodeImporter::ImportDefinition(ObjCProtocolDecl *From, | |||
| 3220 | ObjCProtocolDecl *To, | |||
| 3221 | ImportDefinitionKind Kind) { | |||
| 3222 | if (To->getDefinition()) { | |||
| 3223 | if (shouldForceImportDeclContext(Kind)) | |||
| 3224 | ImportDeclContext(From); | |||
| 3225 | return false; | |||
| 3226 | } | |||
| 3227 | ||||
| 3228 | // Start the protocol definition | |||
| 3229 | To->startDefinition(); | |||
| 3230 | ||||
| 3231 | // Import protocols | |||
| 3232 | SmallVector<ObjCProtocolDecl *, 4> Protocols; | |||
| 3233 | SmallVector<SourceLocation, 4> ProtocolLocs; | |||
| 3234 | ObjCProtocolDecl::protocol_loc_iterator | |||
| 3235 | FromProtoLoc = From->protocol_loc_begin(); | |||
| 3236 | for (ObjCProtocolDecl::protocol_iterator FromProto = From->protocol_begin(), | |||
| 3237 | FromProtoEnd = From->protocol_end(); | |||
| 3238 | FromProto != FromProtoEnd; | |||
| 3239 | ++FromProto, ++FromProtoLoc) { | |||
| 3240 | auto *ToProto = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto)); | |||
| 3241 | if (!ToProto) | |||
| 3242 | return true; | |||
| 3243 | Protocols.push_back(ToProto); | |||
| 3244 | ProtocolLocs.push_back(Importer.Import(*FromProtoLoc)); | |||
| 3245 | } | |||
| 3246 | ||||
| 3247 | // FIXME: If we're merging, make sure that the protocol list is the same. | |||
| 3248 | To->setProtocolList(Protocols.data(), Protocols.size(), | |||
| 3249 | ProtocolLocs.data(), Importer.getToContext()); | |||
| 3250 | ||||
| 3251 | if (shouldForceImportDeclContext(Kind)) { | |||
| 3252 | // Import all of the members of this protocol. | |||
| 3253 | ImportDeclContext(From, /*ForceImport=*/true); | |||
| 3254 | } | |||
| 3255 | return false; | |||
| 3256 | } | |||
| 3257 | ||||
| 3258 | Decl *ASTNodeImporter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) { | |||
| 3259 | // If this protocol has a definition in the translation unit we're coming | |||
| 3260 | // from, but this particular declaration is not that definition, import the | |||
| 3261 | // definition and map to that. | |||
| 3262 | ObjCProtocolDecl *Definition = D->getDefinition(); | |||
| 3263 | if (Definition && Definition != D) { | |||
| 3264 | Decl *ImportedDef = Importer.Import(Definition); | |||
| 3265 | if (!ImportedDef) | |||
| 3266 | return nullptr; | |||
| 3267 | ||||
| 3268 | return Importer.Imported(D, ImportedDef); | |||
| 3269 | } | |||
| 3270 | ||||
| 3271 | // Import the major distinguishing characteristics of a protocol. | |||
| 3272 | DeclContext *DC, *LexicalDC; | |||
| 3273 | DeclarationName Name; | |||
| 3274 | SourceLocation Loc; | |||
| 3275 | NamedDecl *ToD; | |||
| 3276 | if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc)) | |||
| 3277 | return nullptr; | |||
| 3278 | if (ToD) | |||
| 3279 | return ToD; | |||
| 3280 | ||||
| 3281 | ObjCProtocolDecl *MergeWithProtocol = nullptr; | |||
| 3282 | SmallVector<NamedDecl *, 2> FoundDecls; | |||
| 3283 | DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls); | |||
| 3284 | for (auto *FoundDecl : FoundDecls) { | |||
| 3285 | if (!FoundDecl->isInIdentifierNamespace(Decl::IDNS_ObjCProtocol)) | |||
| 3286 | continue; | |||
| 3287 | ||||
| 3288 | if ((MergeWithProtocol = dyn_cast<ObjCProtocolDecl>(FoundDecl))) | |||
| 3289 | break; | |||
| 3290 | } | |||
| 3291 | ||||
| 3292 | ObjCProtocolDecl *ToProto = MergeWithProtocol; | |||
| 3293 | if (!ToProto) { | |||
| 3294 | ToProto = ObjCProtocolDecl::Create(Importer.getToContext(), DC, | |||
| 3295 | Name.getAsIdentifierInfo(), Loc, | |||
| 3296 | Importer.Import(D->getAtStartLoc()), | |||
| 3297 | /*PrevDecl=*/nullptr); | |||
| 3298 | ToProto->setLexicalDeclContext(LexicalDC); | |||
| 3299 | LexicalDC->addDeclInternal(ToProto); | |||
| 3300 | } | |||
| 3301 | ||||
| 3302 | Importer.Imported(D, ToProto); | |||
| 3303 | ||||
| 3304 | if (D->isThisDeclarationADefinition() && ImportDefinition(D, ToProto)) | |||
| 3305 | return nullptr; | |||
| 3306 | ||||
| 3307 | return ToProto; | |||
| 3308 | } | |||
| 3309 | ||||
| 3310 | Decl *ASTNodeImporter::VisitLinkageSpecDecl(LinkageSpecDecl *D) { | |||
| 3311 | DeclContext *DC = Importer.ImportContext(D->getDeclContext()); | |||
| 3312 | DeclContext *LexicalDC = Importer.ImportContext(D->getLexicalDeclContext()); | |||
| 3313 | ||||
| 3314 | SourceLocation ExternLoc = Importer.Import(D->getExternLoc()); | |||
| 3315 | SourceLocation LangLoc = Importer.Import(D->getLocation()); | |||
| 3316 | ||||
| 3317 | bool HasBraces = D->hasBraces(); | |||
| 3318 | ||||
| 3319 | LinkageSpecDecl *ToLinkageSpec = | |||
| 3320 | LinkageSpecDecl::Create(Importer.getToContext(), | |||
| 3321 | DC, | |||
| 3322 | ExternLoc, | |||
| 3323 | LangLoc, | |||
| 3324 | D->getLanguage(), | |||
| 3325 | HasBraces); | |||
| 3326 | ||||
| 3327 | if (HasBraces) { | |||
| 3328 | SourceLocation RBraceLoc = Importer.Import(D->getRBraceLoc()); | |||
| 3329 | ToLinkageSpec->setRBraceLoc(RBraceLoc); | |||
| 3330 | } | |||
| 3331 | ||||
| 3332 | ToLinkageSpec->setLexicalDeclContext(LexicalDC); | |||
| 3333 | LexicalDC->addDeclInternal(ToLinkageSpec); | |||
| 3334 | ||||
| 3335 | Importer.Imported(D, ToLinkageSpec); | |||
| 3336 | ||||
| 3337 | return ToLinkageSpec; | |||
| 3338 | } | |||
| 3339 | ||||
| 3340 | Decl *ASTNodeImporter::VisitUsingDecl(UsingDecl *D) { | |||
| 3341 | DeclContext *DC, *LexicalDC; | |||
| 3342 | DeclarationName Name; | |||
| 3343 | SourceLocation Loc; | |||
| 3344 | NamedDecl *ToD = nullptr; | |||
| 3345 | if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc)) | |||
| 3346 | return nullptr; | |||
| 3347 | if (ToD) | |||
| 3348 | return ToD; | |||
| 3349 | ||||
| 3350 | DeclarationNameInfo NameInfo(Name, | |||
| 3351 | Importer.Import(D->getNameInfo().getLoc())); | |||
| 3352 | ImportDeclarationNameLoc(D->getNameInfo(), NameInfo); | |||
| 3353 | ||||
| 3354 | UsingDecl *ToUsing = UsingDecl::Create(Importer.getToContext(), DC, | |||
| 3355 | Importer.Import(D->getUsingLoc()), | |||
| 3356 | Importer.Import(D->getQualifierLoc()), | |||
| 3357 | NameInfo, D->hasTypename()); | |||
| 3358 | ToUsing->setLexicalDeclContext(LexicalDC); | |||
| 3359 | LexicalDC->addDeclInternal(ToUsing); | |||
| 3360 | Importer.Imported(D, ToUsing); | |||
| 3361 | ||||
| 3362 | if (NamedDecl *FromPattern = | |||
| 3363 | Importer.getFromContext().getInstantiatedFromUsingDecl(D)) { | |||
| 3364 | if (auto *ToPattern = | |||
| 3365 | dyn_cast_or_null<NamedDecl>(Importer.Import(FromPattern))) | |||
| 3366 | Importer.getToContext().setInstantiatedFromUsingDecl(ToUsing, ToPattern); | |||
| 3367 | else | |||
| 3368 | return nullptr; | |||
| 3369 | } | |||
| 3370 | ||||
| 3371 | for (auto *FromShadow : D->shadows()) { | |||
| 3372 | if (auto *ToShadow = | |||
| 3373 | dyn_cast_or_null<UsingShadowDecl>(Importer.Import(FromShadow))) | |||
| 3374 | ToUsing->addShadowDecl(ToShadow); | |||
| 3375 | else | |||
| 3376 | // FIXME: We return a nullptr here but the definition is already created | |||
| 3377 | // and available with lookups. How to fix this?.. | |||
| 3378 | return nullptr; | |||
| 3379 | } | |||
| 3380 | return ToUsing; | |||
| 3381 | } | |||
| 3382 | ||||
| 3383 | Decl *ASTNodeImporter::VisitUsingShadowDecl(UsingShadowDecl *D) { | |||
| 3384 | DeclContext *DC, *LexicalDC; | |||
| 3385 | DeclarationName Name; | |||
| 3386 | SourceLocation Loc; | |||
| 3387 | NamedDecl *ToD = nullptr; | |||
| 3388 | if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc)) | |||
| 3389 | return nullptr; | |||
| 3390 | if (ToD) | |||
| 3391 | return ToD; | |||
| 3392 | ||||
| 3393 | auto *ToUsing = dyn_cast_or_null<UsingDecl>( | |||
| 3394 | Importer.Import(D->getUsingDecl())); | |||
| 3395 | if (!ToUsing) | |||
| 3396 | return nullptr; | |||
| 3397 | ||||
| 3398 | auto *ToTarget = dyn_cast_or_null<NamedDecl>( | |||
| 3399 | Importer.Import(D->getTargetDecl())); | |||
| 3400 | if (!ToTarget) | |||
| 3401 | return nullptr; | |||
| 3402 | ||||
| 3403 | UsingShadowDecl *ToShadow = UsingShadowDecl::Create( | |||
| 3404 | Importer.getToContext(), DC, Loc, ToUsing, ToTarget); | |||
| 3405 | ||||
| 3406 | ToShadow->setLexicalDeclContext(LexicalDC); | |||
| 3407 | ToShadow->setAccess(D->getAccess()); | |||
| 3408 | Importer.Imported(D, ToShadow); | |||
| 3409 | ||||
| 3410 | if (UsingShadowDecl *FromPattern = | |||
| 3411 | Importer.getFromContext().getInstantiatedFromUsingShadowDecl(D)) { | |||
| 3412 | if (auto *ToPattern = | |||
| 3413 | dyn_cast_or_null<UsingShadowDecl>(Importer.Import(FromPattern))) | |||
| 3414 | Importer.getToContext().setInstantiatedFromUsingShadowDecl(ToShadow, | |||
| 3415 | ToPattern); | |||
| 3416 | else | |||
| 3417 | // FIXME: We return a nullptr here but the definition is already created | |||
| 3418 | // and available with lookups. How to fix this?.. | |||
| 3419 | return nullptr; | |||
| 3420 | } | |||
| 3421 | ||||
| 3422 | LexicalDC->addDeclInternal(ToShadow); | |||
| 3423 | ||||
| 3424 | return ToShadow; | |||
| 3425 | } | |||
| 3426 | ||||
| 3427 | Decl *ASTNodeImporter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) { | |||
| 3428 | DeclContext *DC, *LexicalDC; | |||
| 3429 | DeclarationName Name; | |||
| 3430 | SourceLocation Loc; | |||
| 3431 | NamedDecl *ToD = nullptr; | |||
| 3432 | if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc)) | |||
| 3433 | return nullptr; | |||
| 3434 | if (ToD) | |||
| 3435 | return ToD; | |||
| 3436 | ||||
| 3437 | DeclContext *ToComAncestor = Importer.ImportContext(D->getCommonAncestor()); | |||
| 3438 | if (!ToComAncestor) | |||
| 3439 | return nullptr; | |||
| 3440 | ||||
| 3441 | auto *ToNominated = cast_or_null<NamespaceDecl>( | |||
| 3442 | Importer.Import(D->getNominatedNamespace())); | |||
| 3443 | if (!ToNominated) | |||
| 3444 | return nullptr; | |||
| 3445 | ||||
| 3446 | UsingDirectiveDecl *ToUsingDir = UsingDirectiveDecl::Create( | |||
| 3447 | Importer.getToContext(), DC, Importer.Import(D->getUsingLoc()), | |||
| 3448 | Importer.Import(D->getNamespaceKeyLocation()), | |||
| 3449 | Importer.Import(D->getQualifierLoc()), | |||
| 3450 | Importer.Import(D->getIdentLocation()), ToNominated, ToComAncestor); | |||
| 3451 | ToUsingDir->setLexicalDeclContext(LexicalDC); | |||
| 3452 | LexicalDC->addDeclInternal(ToUsingDir); | |||
| 3453 | Importer.Imported(D, ToUsingDir); | |||
| 3454 | ||||
| 3455 | return ToUsingDir; | |||
| 3456 | } | |||
| 3457 | ||||
| 3458 | Decl *ASTNodeImporter::VisitUnresolvedUsingValueDecl( | |||
| 3459 | UnresolvedUsingValueDecl *D) { | |||
| 3460 | DeclContext *DC, *LexicalDC; | |||
| 3461 | DeclarationName Name; | |||
| 3462 | SourceLocation Loc; | |||
| 3463 | NamedDecl *ToD = nullptr; | |||
| 3464 | if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc)) | |||
| 3465 | return nullptr; | |||
| 3466 | if (ToD) | |||
| 3467 | return ToD; | |||
| 3468 | ||||
| 3469 | DeclarationNameInfo NameInfo(Name, Importer.Import(D->getNameInfo().getLoc())); | |||
| 3470 | ImportDeclarationNameLoc(D->getNameInfo(), NameInfo); | |||
| 3471 | ||||
| 3472 | UnresolvedUsingValueDecl *ToUsingValue = UnresolvedUsingValueDecl::Create( | |||
| 3473 | Importer.getToContext(), DC, Importer.Import(D->getUsingLoc()), | |||
| 3474 | Importer.Import(D->getQualifierLoc()), NameInfo, | |||
| 3475 | Importer.Import(D->getEllipsisLoc())); | |||
| 3476 | ||||
| 3477 | Importer.Imported(D, ToUsingValue); | |||
| 3478 | ToUsingValue->setAccess(D->getAccess()); | |||
| 3479 | ToUsingValue->setLexicalDeclContext(LexicalDC); | |||
| 3480 | LexicalDC->addDeclInternal(ToUsingValue); | |||
| 3481 | ||||
| 3482 | return ToUsingValue; | |||
| 3483 | } | |||
| 3484 | ||||
| 3485 | Decl *ASTNodeImporter::VisitUnresolvedUsingTypenameDecl( | |||
| 3486 | UnresolvedUsingTypenameDecl *D) { | |||
| 3487 | DeclContext *DC, *LexicalDC; | |||
| 3488 | DeclarationName Name; | |||
| 3489 | SourceLocation Loc; | |||
| 3490 | NamedDecl *ToD = nullptr; | |||
| 3491 | if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc)) | |||
| 3492 | return nullptr; | |||
| 3493 | if (ToD) | |||
| 3494 | return ToD; | |||
| 3495 | ||||
| 3496 | UnresolvedUsingTypenameDecl *ToUsing = UnresolvedUsingTypenameDecl::Create( | |||
| 3497 | Importer.getToContext(), DC, Importer.Import(D->getUsingLoc()), | |||
| 3498 | Importer.Import(D->getTypenameLoc()), | |||
| 3499 | Importer.Import(D->getQualifierLoc()), Loc, Name, | |||
| 3500 | Importer.Import(D->getEllipsisLoc())); | |||
| 3501 | ||||
| 3502 | Importer.Imported(D, ToUsing); | |||
| 3503 | ToUsing->setAccess(D->getAccess()); | |||
| 3504 | ToUsing->setLexicalDeclContext(LexicalDC); | |||
| 3505 | LexicalDC->addDeclInternal(ToUsing); | |||
| 3506 | ||||
| 3507 | return ToUsing; | |||
| 3508 | } | |||
| 3509 | ||||
| 3510 | bool ASTNodeImporter::ImportDefinition(ObjCInterfaceDecl *From, | |||
| 3511 | ObjCInterfaceDecl *To, | |||
| 3512 | ImportDefinitionKind Kind) { | |||
| 3513 | if (To->getDefinition()) { | |||
| 3514 | // Check consistency of superclass. | |||
| 3515 | ObjCInterfaceDecl *FromSuper = From->getSuperClass(); | |||
| 3516 | if (FromSuper) { | |||
| 3517 | FromSuper = cast_or_null<ObjCInterfaceDecl>(Importer.Import(FromSuper)); | |||
| 3518 | if (!FromSuper) | |||
| 3519 | return true; | |||
| 3520 | } | |||
| 3521 | ||||
| 3522 | ObjCInterfaceDecl *ToSuper = To->getSuperClass(); | |||
| 3523 | if ((bool)FromSuper != (bool)ToSuper || | |||
| 3524 | (FromSuper && !declaresSameEntity(FromSuper, ToSuper))) { | |||
| 3525 | Importer.ToDiag(To->getLocation(), | |||
| 3526 | diag::err_odr_objc_superclass_inconsistent) | |||
| 3527 | << To->getDeclName(); | |||
| 3528 | if (ToSuper) | |||
| 3529 | Importer.ToDiag(To->getSuperClassLoc(), diag::note_odr_objc_superclass) | |||
| 3530 | << To->getSuperClass()->getDeclName(); | |||
| 3531 | else | |||
| 3532 | Importer.ToDiag(To->getLocation(), | |||
| 3533 | diag::note_odr_objc_missing_superclass); | |||
| 3534 | if (From->getSuperClass()) | |||
| 3535 | Importer.FromDiag(From->getSuperClassLoc(), | |||
| 3536 | diag::note_odr_objc_superclass) | |||
| 3537 | << From->getSuperClass()->getDeclName(); | |||
| 3538 | else | |||
| 3539 | Importer.FromDiag(From->getLocation(), | |||
| 3540 | diag::note_odr_objc_missing_superclass); | |||
| 3541 | } | |||
| 3542 | ||||
| 3543 | if (shouldForceImportDeclContext(Kind)) | |||
| 3544 | ImportDeclContext(From); | |||
| 3545 | return false; | |||
| 3546 | } | |||
| 3547 | ||||
| 3548 | // Start the definition. | |||
| 3549 | To->startDefinition(); | |||
| 3550 | ||||
| 3551 | // If this class has a superclass, import it. | |||
| 3552 | if (From->getSuperClass()) { | |||
| 3553 | TypeSourceInfo *SuperTInfo = Importer.Import(From->getSuperClassTInfo()); | |||
| 3554 | if (!SuperTInfo) | |||
| 3555 | return true; | |||
| 3556 | ||||
| 3557 | To->setSuperClass(SuperTInfo); | |||
| 3558 | } | |||
| 3559 | ||||
| 3560 | // Import protocols | |||
| 3561 | SmallVector<ObjCProtocolDecl *, 4> Protocols; | |||
| 3562 | SmallVector<SourceLocation, 4> ProtocolLocs; | |||
| 3563 | ObjCInterfaceDecl::protocol_loc_iterator | |||
| 3564 | FromProtoLoc = From->protocol_loc_begin(); | |||
| 3565 | ||||
| 3566 | for (ObjCInterfaceDecl::protocol_iterator FromProto = From->protocol_begin(), | |||
| 3567 | FromProtoEnd = From->protocol_end(); | |||
| 3568 | FromProto != FromProtoEnd; | |||
| 3569 | ++FromProto, ++FromProtoLoc) { | |||
| 3570 | auto *ToProto = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto)); | |||
| 3571 | if (!ToProto) | |||
| 3572 | return true; | |||
| 3573 | Protocols.push_back(ToProto); | |||
| 3574 | ProtocolLocs.push_back(Importer.Import(*FromProtoLoc)); | |||
| 3575 | } | |||
| 3576 | ||||
| 3577 | // FIXME: If we're merging, make sure that the protocol list is the same. | |||
| 3578 | To->setProtocolList(Protocols.data(), Protocols.size(), | |||
| 3579 | ProtocolLocs.data(), Importer.getToContext()); | |||
| 3580 | ||||
| 3581 | // Import categories. When the categories themselves are imported, they'll | |||
| 3582 | // hook themselves into this interface. | |||
| 3583 | for (auto *Cat : From->known_categories()) | |||
| 3584 | Importer.Import(Cat); | |||
| 3585 | ||||
| 3586 | // If we have an @implementation, import it as well. | |||
| 3587 | if (From->getImplementation()) { | |||
| 3588 | auto *Impl = cast_or_null<ObjCImplementationDecl>( | |||
| 3589 | Importer.Import(From->getImplementation())); | |||
| 3590 | if (!Impl) | |||
| 3591 | return true; | |||
| 3592 | ||||
| 3593 | To->setImplementation(Impl); | |||
| 3594 | } | |||
| 3595 | ||||
| 3596 | if (shouldForceImportDeclContext(Kind)) { | |||
| 3597 | // Import all of the members of this class. | |||
| 3598 | ImportDeclContext(From, /*ForceImport=*/true); | |||
| 3599 | } | |||
| 3600 | return false; | |||
| 3601 | } | |||
| 3602 | ||||
| 3603 | ObjCTypeParamList * | |||
| 3604 | ASTNodeImporter::ImportObjCTypeParamList(ObjCTypeParamList *list) { | |||
| 3605 | if (!list) | |||
| 3606 | return nullptr; | |||
| 3607 | ||||
| 3608 | SmallVector<ObjCTypeParamDecl *, 4> toTypeParams; | |||
| 3609 | for (auto fromTypeParam : *list) { | |||
| 3610 | auto *toTypeParam = cast_or_null<ObjCTypeParamDecl>( | |||
| 3611 | Importer.Import(fromTypeParam)); | |||
| 3612 | if (!toTypeParam) | |||
| 3613 | return nullptr; | |||
| 3614 | ||||
| 3615 | toTypeParams.push_back(toTypeParam); | |||
| 3616 | } | |||
| 3617 | ||||
| 3618 | return ObjCTypeParamList::create(Importer.getToContext(), | |||
| 3619 | Importer.Import(list->getLAngleLoc()), | |||
| 3620 | toTypeParams, | |||
| 3621 | Importer.Import(list->getRAngleLoc())); | |||
| 3622 | } | |||
| 3623 | ||||
| 3624 | Decl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) { | |||
| 3625 | // If this class has a definition in the translation unit we're coming from, | |||
| 3626 | // but this particular declaration is not that definition, import the | |||
| 3627 | // definition and map to that. | |||
| 3628 | ObjCInterfaceDecl *Definition = D->getDefinition(); | |||
| 3629 | if (Definition && Definition != D) { | |||
| 3630 | Decl *ImportedDef = Importer.Import(Definition); | |||
| 3631 | if (!ImportedDef) | |||
| 3632 | return nullptr; | |||
| 3633 | ||||
| 3634 | return Importer.Imported(D, ImportedDef); | |||
| 3635 | } | |||
| 3636 | ||||
| 3637 | // Import the major distinguishing characteristics of an @interface. | |||
| 3638 | DeclContext *DC, *LexicalDC; | |||
| 3639 | DeclarationName Name; | |||
| 3640 | SourceLocation Loc; | |||
| 3641 | NamedDecl *ToD; | |||
| 3642 | if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc)) | |||
| 3643 | return nullptr; | |||
| 3644 | if (ToD) | |||
| 3645 | return ToD; | |||
| 3646 | ||||
| 3647 | // Look for an existing interface with the same name. | |||
| 3648 | ObjCInterfaceDecl *MergeWithIface = nullptr; | |||
| 3649 | SmallVector<NamedDecl *, 2> FoundDecls; | |||
| 3650 | DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls); | |||
| 3651 | for (auto *FoundDecl : FoundDecls) { | |||
| 3652 | if (!FoundDecl->isInIdentifierNamespace(Decl::IDNS_Ordinary)) | |||
| 3653 | continue; | |||
| 3654 | ||||
| 3655 | if ((MergeWithIface = dyn_cast<ObjCInterfaceDecl>(FoundDecl))) | |||
| 3656 | break; | |||
| 3657 | } | |||
| 3658 | ||||
| 3659 | // Create an interface declaration, if one does not already exist. | |||
| 3660 | ObjCInterfaceDecl *ToIface = MergeWithIface; | |||
| 3661 | if (!ToIface) { | |||
| 3662 | ToIface = ObjCInterfaceDecl::Create(Importer.getToContext(), DC, | |||
| 3663 | Importer.Import(D->getAtStartLoc()), | |||
| 3664 | Name.getAsIdentifierInfo(), | |||
| 3665 | /*TypeParamList=*/nullptr, | |||
| 3666 | /*PrevDecl=*/nullptr, Loc, | |||
| 3667 | D->isImplicitInterfaceDecl()); | |||
| 3668 | ToIface->setLexicalDeclContext(LexicalDC); | |||
| 3669 | LexicalDC->addDeclInternal(ToIface); | |||
| 3670 | } | |||
| 3671 | Importer.Imported(D, ToIface); | |||
| 3672 | // Import the type parameter list after calling Imported, to avoid | |||
| 3673 | // loops when bringing in their DeclContext. | |||
| 3674 | ToIface->setTypeParamList(ImportObjCTypeParamList( | |||
| 3675 | D->getTypeParamListAsWritten())); | |||
| 3676 | ||||
| 3677 | if (D->isThisDeclarationADefinition() && ImportDefinition(D, ToIface)) | |||
| 3678 | return nullptr; | |||
| 3679 | ||||
| 3680 | return ToIface; | |||
| 3681 | } | |||
| 3682 | ||||
| 3683 | Decl *ASTNodeImporter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) { | |||
| 3684 | auto *Category = cast_or_null<ObjCCategoryDecl>( | |||
| 3685 | Importer.Import(D->getCategoryDecl())); | |||
| 3686 | if (!Category) | |||
| 3687 | return nullptr; | |||
| 3688 | ||||
| 3689 | ObjCCategoryImplDecl *ToImpl = Category->getImplementation(); | |||
| 3690 | if (!ToImpl) { | |||
| 3691 | DeclContext *DC = Importer.ImportContext(D->getDeclContext()); | |||
| 3692 | if (!DC) | |||
| 3693 | return nullptr; | |||
| 3694 | ||||
| 3695 | SourceLocation CategoryNameLoc = Importer.Import(D->getCategoryNameLoc()); | |||
| 3696 | ToImpl = ObjCCategoryImplDecl::Create(Importer.getToContext(), DC, | |||
| 3697 | Importer.Import(D->getIdentifier()), | |||
| 3698 | Category->getClassInterface(), | |||
| 3699 | Importer.Import(D->getLocation()), | |||
| 3700 | Importer.Import(D->getAtStartLoc()), | |||
| 3701 | CategoryNameLoc); | |||
| 3702 | ||||
| 3703 | DeclContext *LexicalDC = DC; | |||
| 3704 | if (D->getDeclContext() != D->getLexicalDeclContext()) { | |||
| 3705 | LexicalDC = Importer.ImportContext(D->getLexicalDeclContext()); | |||
| 3706 | if (!LexicalDC) | |||
| 3707 | return nullptr; | |||
| 3708 | ||||
| 3709 | ToImpl->setLexicalDeclContext(LexicalDC); | |||
| 3710 | } | |||
| 3711 | ||||
| 3712 | LexicalDC->addDeclInternal(ToImpl); | |||
| 3713 | Category->setImplementation(ToImpl); | |||
| 3714 | } | |||
| 3715 | ||||
| 3716 | Importer.Imported(D, ToImpl); | |||
| 3717 | ImportDeclContext(D); | |||
| 3718 | return ToImpl; | |||
| 3719 | } | |||
| 3720 | ||||
| 3721 | Decl *ASTNodeImporter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) { | |||
| 3722 | // Find the corresponding interface. | |||
| 3723 | auto *Iface = cast_or_null<ObjCInterfaceDecl>( | |||
| 3724 | Importer.Import(D->getClassInterface())); | |||
| 3725 | if (!Iface) | |||
| 3726 | return nullptr; | |||
| 3727 | ||||
| 3728 | // Import the superclass, if any. | |||
| 3729 | ObjCInterfaceDecl *Super = nullptr; | |||
| 3730 | if (D->getSuperClass()) { | |||
| 3731 | Super = cast_or_null<ObjCInterfaceDecl>( | |||
| 3732 | Importer.Import(D->getSuperClass())); | |||
| 3733 | if (!Super) | |||
| 3734 | return nullptr; | |||
| 3735 | } | |||
| 3736 | ||||
| 3737 | ObjCImplementationDecl *Impl = Iface->getImplementation(); | |||
| 3738 | if (!Impl) { | |||
| 3739 | // We haven't imported an implementation yet. Create a new @implementation | |||
| 3740 | // now. | |||
| 3741 | Impl = ObjCImplementationDecl::Create(Importer.getToContext(), | |||
| 3742 | Importer.ImportContext(D->getDeclContext()), | |||
| 3743 | Iface, Super, | |||
| 3744 | Importer.Import(D->getLocation()), | |||
| 3745 | Importer.Import(D->getAtStartLoc()), | |||
| 3746 | Importer.Import(D->getSuperClassLoc()), | |||
| 3747 | Importer.Import(D->getIvarLBraceLoc()), | |||
| 3748 | Importer.Import(D->getIvarRBraceLoc())); | |||
| 3749 | ||||
| 3750 | if (D->getDeclContext() != D->getLexicalDeclContext()) { | |||
| 3751 | DeclContext *LexicalDC | |||
| 3752 | = Importer.ImportContext(D->getLexicalDeclContext()); | |||
| 3753 | if (!LexicalDC) | |||
| 3754 | return nullptr; | |||
| 3755 | Impl->setLexicalDeclContext(LexicalDC); | |||
| 3756 | } | |||
| 3757 | ||||
| 3758 | // Associate the implementation with the class it implements. | |||
| 3759 | Iface->setImplementation(Impl); | |||
| 3760 | Importer.Imported(D, Iface->getImplementation()); | |||
| 3761 | } else { | |||
| 3762 | Importer.Imported(D, Iface->getImplementation()); | |||
| 3763 | ||||
| 3764 | // Verify that the existing @implementation has the same superclass. | |||
| 3765 | if ((Super && !Impl->getSuperClass()) || | |||
| 3766 | (!Super && Impl->getSuperClass()) || | |||
| 3767 | (Super && Impl->getSuperClass() && | |||
| 3768 | !declaresSameEntity(Super->getCanonicalDecl(), | |||
| 3769 | Impl->getSuperClass()))) { | |||
| 3770 | Importer.ToDiag(Impl->getLocation(), | |||
| 3771 | diag::err_odr_objc_superclass_inconsistent) | |||
| 3772 | << Iface->getDeclName(); | |||
| 3773 | // FIXME: It would be nice to have the location of the superclass | |||
| 3774 | // below. | |||
| 3775 | if (Impl->getSuperClass()) | |||
| 3776 | Importer.ToDiag(Impl->getLocation(), | |||
| 3777 | diag::note_odr_objc_superclass) | |||
| 3778 | << Impl->getSuperClass()->getDeclName(); | |||
| 3779 | else | |||
| 3780 | Importer.ToDiag(Impl->getLocation(), | |||
| 3781 | diag::note_odr_objc_missing_superclass); | |||
| 3782 | if (D->getSuperClass()) | |||
| 3783 | Importer.FromDiag(D->getLocation(), | |||
| 3784 | diag::note_odr_objc_superclass) | |||
| 3785 | << D->getSuperClass()->getDeclName(); | |||
| 3786 | else | |||
| 3787 | Importer.FromDiag(D->getLocation(), | |||
| 3788 | diag::note_odr_objc_missing_superclass); | |||
| 3789 | return nullptr; | |||
| 3790 | } | |||
| 3791 | } | |||
| 3792 | ||||
| 3793 | // Import all of the members of this @implementation. | |||
| 3794 | ImportDeclContext(D); | |||
| 3795 | ||||
| 3796 | return Impl; | |||
| 3797 | } | |||
| 3798 | ||||
| 3799 | Decl *ASTNodeImporter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) { | |||
| 3800 | // Import the major distinguishing characteristics of an @property. | |||
| 3801 | DeclContext *DC, *LexicalDC; | |||
| 3802 | DeclarationName Name; | |||
| 3803 | SourceLocation Loc; | |||
| 3804 | NamedDecl *ToD; | |||
| 3805 | if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc)) | |||
| 3806 | return nullptr; | |||
| 3807 | if (ToD) | |||
| 3808 | return ToD; | |||
| 3809 | ||||
| 3810 | // Check whether we have already imported this property. | |||
| 3811 | SmallVector<NamedDecl *, 2> FoundDecls; | |||
| 3812 | DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls); | |||
| 3813 | for (auto *FoundDecl : FoundDecls) { | |||
| 3814 | if (auto *FoundProp = dyn_cast<ObjCPropertyDecl>(FoundDecl)) { | |||
| 3815 | // Check property types. | |||
| 3816 | if (!Importer.IsStructurallyEquivalent(D->getType(), | |||
| 3817 | FoundProp->getType())) { | |||
| 3818 | Importer.ToDiag(Loc, diag::err_odr_objc_property_type_inconsistent) | |||
| 3819 | << Name << D->getType() << FoundProp->getType(); | |||
| 3820 | Importer.ToDiag(FoundProp->getLocation(), diag::note_odr_value_here) | |||
| 3821 | << FoundProp->getType(); | |||
| 3822 | return nullptr; | |||
| 3823 | } | |||
| 3824 | ||||
| 3825 | // FIXME: Check property attributes, getters, setters, etc.? | |||
| 3826 | ||||
| 3827 | // Consider these properties to be equivalent. | |||
| 3828 | Importer.Imported(D, FoundProp); | |||
| 3829 | return FoundProp; | |||
| 3830 | } | |||
| 3831 | } | |||
| 3832 | ||||
| 3833 | // Import the type. | |||
| 3834 | TypeSourceInfo *TSI = Importer.Import(D->getTypeSourceInfo()); | |||
| 3835 | if (!TSI) | |||
| 3836 | return nullptr; | |||
| 3837 | ||||
| 3838 | // Create the new property. | |||
| 3839 | ObjCPropertyDecl *ToProperty | |||
| 3840 | = ObjCPropertyDecl::Create(Importer.getToContext(), DC, Loc, | |||
| 3841 | Name.getAsIdentifierInfo(), | |||
| 3842 | Importer.Import(D->getAtLoc()), | |||
| 3843 | Importer.Import(D->getLParenLoc()), | |||
| 3844 | Importer.Import(D->getType()), | |||
| 3845 | TSI, | |||
| 3846 | D->getPropertyImplementation()); | |||
| 3847 | Importer.Imported(D, ToProperty); | |||
| 3848 | ToProperty->setLexicalDeclContext(LexicalDC); | |||
| 3849 | LexicalDC->addDeclInternal(ToProperty); | |||
| 3850 | ||||
| 3851 | ToProperty->setPropertyAttributes(D->getPropertyAttributes()); | |||
| 3852 | ToProperty->setPropertyAttributesAsWritten( | |||
| 3853 | D->getPropertyAttributesAsWritten()); | |||
| 3854 | ToProperty->setGetterName(Importer.Import(D->getGetterName()), | |||
| 3855 | Importer.Import(D->getGetterNameLoc())); | |||
| 3856 | ToProperty->setSetterName(Importer.Import(D->getSetterName()), | |||
| 3857 | Importer.Import(D->getSetterNameLoc())); | |||
| 3858 | ToProperty->setGetterMethodDecl( | |||
| 3859 | cast_or_null<ObjCMethodDecl>(Importer.Import(D->getGetterMethodDecl()))); | |||
| 3860 | ToProperty->setSetterMethodDecl( | |||
| 3861 | cast_or_null<ObjCMethodDecl>(Importer.Import(D->getSetterMethodDecl()))); | |||
| 3862 | ToProperty->setPropertyIvarDecl( | |||
| 3863 | cast_or_null<ObjCIvarDecl>(Importer.Import(D->getPropertyIvarDecl()))); | |||
| 3864 | return ToProperty; | |||
| 3865 | } | |||
| 3866 | ||||
| 3867 | Decl *ASTNodeImporter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) { | |||
| 3868 | auto *Property = cast_or_null<ObjCPropertyDecl>( | |||
| 3869 | Importer.Import(D->getPropertyDecl())); | |||
| 3870 | if (!Property) | |||
| 3871 | return nullptr; | |||
| 3872 | ||||
| 3873 | DeclContext *DC = Importer.ImportContext(D->getDeclContext()); | |||
| 3874 | if (!DC) | |||
| 3875 | return nullptr; | |||
| 3876 | ||||
| 3877 | // Import the lexical declaration context. | |||
| 3878 | DeclContext *LexicalDC = DC; | |||
| 3879 | if (D->getDeclContext() != D->getLexicalDeclContext()) { | |||
| 3880 | LexicalDC = Importer.ImportContext(D->getLexicalDeclContext()); | |||
| 3881 | if (!LexicalDC) | |||
| 3882 | return nullptr; | |||
| 3883 | } | |||
| 3884 | ||||
| 3885 | auto *InImpl = dyn_cast<ObjCImplDecl>(LexicalDC); | |||
| 3886 | if (!InImpl) | |||
| 3887 | return nullptr; | |||
| 3888 | ||||
| 3889 | // Import the ivar (for an @synthesize). | |||
| 3890 | ObjCIvarDecl *Ivar = nullptr; | |||
| 3891 | if (D->getPropertyIvarDecl()) { | |||
| 3892 | Ivar = cast_or_null<ObjCIvarDecl>( | |||
| 3893 | Importer.Import(D->getPropertyIvarDecl())); | |||
| 3894 | if (!Ivar) | |||
| 3895 | return nullptr; | |||
| 3896 | } | |||
| 3897 | ||||
| 3898 | ObjCPropertyImplDecl *ToImpl | |||
| 3899 | = InImpl->FindPropertyImplDecl(Property->getIdentifier(), | |||
| 3900 | Property->getQueryKind()); | |||
| 3901 | if (!ToImpl) { | |||
| 3902 | ToImpl = ObjCPropertyImplDecl::Create(Importer.getToContext(), DC, | |||
| 3903 | Importer.Import(D->getLocStart()), | |||
| 3904 | Importer.Import(D->getLocation()), | |||
| 3905 | Property, | |||
| 3906 | D->getPropertyImplementation(), | |||
| 3907 | Ivar, | |||
| 3908 | Importer.Import(D->getPropertyIvarDeclLoc())); | |||
| 3909 | ToImpl->setLexicalDeclContext(LexicalDC); | |||
| 3910 | Importer.Imported(D, ToImpl); | |||
| 3911 | LexicalDC->addDeclInternal(ToImpl); | |||
| 3912 | } else { | |||
| 3913 | // Check that we have the same kind of property implementation (@synthesize | |||
| 3914 | // vs. @dynamic). | |||
| 3915 | if (D->getPropertyImplementation() != ToImpl->getPropertyImplementation()) { | |||
| 3916 | Importer.ToDiag(ToImpl->getLocation(), | |||
| 3917 | diag::err_odr_objc_property_impl_kind_inconsistent) | |||
| 3918 | << Property->getDeclName() | |||
| 3919 | << (ToImpl->getPropertyImplementation() | |||
| 3920 | == ObjCPropertyImplDecl::Dynamic); | |||
| 3921 | Importer.FromDiag(D->getLocation(), | |||
| 3922 | diag::note_odr_objc_property_impl_kind) | |||
| 3923 | << D->getPropertyDecl()->getDeclName() | |||
| 3924 | << (D->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic); | |||
| 3925 | return nullptr; | |||
| 3926 | } | |||
| 3927 | ||||
| 3928 | // For @synthesize, check that we have the same | |||
| 3929 | if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize && | |||
| 3930 | Ivar != ToImpl->getPropertyIvarDecl()) { | |||
| 3931 | Importer.ToDiag(ToImpl->getPropertyIvarDeclLoc(), | |||
| 3932 | diag::err_odr_objc_synthesize_ivar_inconsistent) | |||
| 3933 | << Property->getDeclName() | |||
| 3934 | << ToImpl->getPropertyIvarDecl()->getDeclName() | |||
| 3935 | << Ivar->getDeclName(); | |||
| 3936 | Importer.FromDiag(D->getPropertyIvarDeclLoc(), | |||
| 3937 | diag::note_odr_objc_synthesize_ivar_here) | |||
| 3938 | << D->getPropertyIvarDecl()->getDeclName(); | |||
| 3939 | return nullptr; | |||
| 3940 | } | |||
| 3941 | ||||
| 3942 | // Merge the existing implementation with the new implementation. | |||
| 3943 | Importer.Imported(D, ToImpl); | |||
| 3944 | } | |||
| 3945 | ||||
| 3946 | return ToImpl; | |||
| 3947 | } | |||
| 3948 | ||||
| 3949 | Decl *ASTNodeImporter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { | |||
| 3950 | // For template arguments, we adopt the translation unit as our declaration | |||
| 3951 | // context. This context will be fixed when the actual template declaration | |||
| 3952 | // is created. | |||
| 3953 | ||||
| 3954 | // FIXME: Import default argument. | |||
| 3955 | return TemplateTypeParmDecl::Create(Importer.getToContext(), | |||
| 3956 | Importer.getToContext().getTranslationUnitDecl(), | |||
| 3957 | Importer.Import(D->getLocStart()), | |||
| 3958 | Importer.Import(D->getLocation()), | |||
| 3959 | D->getDepth(), | |||
| 3960 | D->getIndex(), | |||
| 3961 | Importer.Import(D->getIdentifier()), | |||
| 3962 | D->wasDeclaredWithTypename(), | |||
| 3963 | D->isParameterPack()); | |||
| 3964 | } | |||
| 3965 | ||||
| 3966 | Decl * | |||
| 3967 | ASTNodeImporter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) { | |||
| 3968 | // Import the name of this declaration. | |||
| 3969 | DeclarationName Name = Importer.Import(D->getDeclName()); | |||
| 3970 | if (D->getDeclName() && !Name) | |||
| 3971 | return nullptr; | |||
| 3972 | ||||
| 3973 | // Import the location of this declaration. | |||
| 3974 | SourceLocation Loc = Importer.Import(D->getLocation()); | |||
| 3975 | ||||
| 3976 | // Import the type of this declaration. | |||
| 3977 | QualType T = Importer.Import(D->getType()); | |||
| 3978 | if (T.isNull()) | |||
| 3979 | return nullptr; | |||
| 3980 | ||||
| 3981 | // Import type-source information. | |||
| 3982 | TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo()); | |||
| 3983 | if (D->getTypeSourceInfo() && !TInfo) | |||
| 3984 | return nullptr; | |||
| 3985 | ||||
| 3986 | // FIXME: Import default argument. | |||
| 3987 | ||||
| 3988 | return NonTypeTemplateParmDecl::Create(Importer.getToContext(), | |||
| 3989 | Importer.getToContext().getTranslationUnitDecl(), | |||
| 3990 | Importer.Import(D->getInnerLocStart()), | |||
| 3991 | Loc, D->getDepth(), D->getPosition(), | |||
| 3992 | Name.getAsIdentifierInfo(), | |||
| 3993 | T, D->isParameterPack(), TInfo); | |||
| 3994 | } | |||
| 3995 | ||||
| 3996 | Decl * | |||
| 3997 | ASTNodeImporter::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) { | |||
| 3998 | // Import the name of this declaration. | |||
| 3999 | DeclarationName Name = Importer.Import(D->getDeclName()); | |||
| 4000 | if (D->getDeclName() && !Name) | |||
| 4001 | return nullptr; | |||
| 4002 | ||||
| 4003 | // Import the location of this declaration. | |||
| 4004 | SourceLocation Loc = Importer.Import(D->getLocation()); | |||
| 4005 | ||||
| 4006 | // Import template parameters. | |||
| 4007 | TemplateParameterList *TemplateParams | |||
| 4008 | = ImportTemplateParameterList(D->getTemplateParameters()); | |||
| 4009 | if (!TemplateParams) | |||
| 4010 | return nullptr; | |||
| 4011 | ||||
| 4012 | // FIXME: Import default argument. | |||
| 4013 | ||||
| 4014 | return TemplateTemplateParmDecl::Create(Importer.getToContext(), | |||
| 4015 | Importer.getToContext().getTranslationUnitDecl(), | |||
| 4016 | Loc, D->getDepth(), D->getPosition(), | |||
| 4017 | D->isParameterPack(), | |||
| 4018 | Name.getAsIdentifierInfo(), | |||
| 4019 | TemplateParams); | |||
| 4020 | } | |||
| 4021 | ||||
| 4022 | Decl *ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) { | |||
| 4023 | // If this record has a definition in the translation unit we're coming from, | |||
| 4024 | // but this particular declaration is not that definition, import the | |||
| 4025 | // definition and map to that. | |||
| 4026 | auto *Definition = | |||
| 4027 | cast_or_null<CXXRecordDecl>(D->getTemplatedDecl()->getDefinition()); | |||
| 4028 | if (Definition && Definition != D->getTemplatedDecl()) { | |||
| 4029 | Decl *ImportedDef | |||
| 4030 | = Importer.Import(Definition->getDescribedClassTemplate()); | |||
| 4031 | if (!ImportedDef) | |||
| 4032 | return nullptr; | |||
| 4033 | ||||
| 4034 | return Importer.Imported(D, ImportedDef); | |||
| 4035 | } | |||
| 4036 | ||||
| 4037 | // Import the major distinguishing characteristics of this class template. | |||
| 4038 | DeclContext *DC, *LexicalDC; | |||
| 4039 | DeclarationName Name; | |||
| 4040 | SourceLocation Loc; | |||
| 4041 | NamedDecl *ToD; | |||
| 4042 | if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc)) | |||
| 4043 | return nullptr; | |||
| 4044 | if (ToD) | |||
| 4045 | return ToD; | |||
| 4046 | ||||
| 4047 | // We may already have a template of the same name; try to find and match it. | |||
| 4048 | if (!DC->isFunctionOrMethod()) { | |||
| 4049 | SmallVector<NamedDecl *, 4> ConflictingDecls; | |||
| 4050 | SmallVector<NamedDecl *, 2> FoundDecls; | |||
| 4051 | DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls); | |||
| 4052 | for (auto *FoundDecl : FoundDecls) { | |||
| 4053 | if (!FoundDecl->isInIdentifierNamespace(Decl::IDNS_Ordinary)) | |||
| 4054 | continue; | |||
| 4055 | ||||
| 4056 | Decl *Found = FoundDecl; | |||
| 4057 | if (auto *FoundTemplate = dyn_cast<ClassTemplateDecl>(Found)) { | |||
| 4058 | if (IsStructuralMatch(D, FoundTemplate)) { | |||
| 4059 | // The class templates structurally match; call it the same template. | |||
| 4060 | // FIXME: We may be filling in a forward declaration here. Handle | |||
| 4061 | // this case! | |||
| 4062 | Importer.Imported(D->getTemplatedDecl(), | |||
| 4063 | FoundTemplate->getTemplatedDecl()); | |||
| 4064 | return Importer.Imported(D, FoundTemplate); | |||
| 4065 | } | |||
| 4066 | } | |||
| 4067 | ||||
| 4068 | ConflictingDecls.push_back(FoundDecl); | |||
| 4069 | } | |||
| 4070 | ||||
| 4071 | if (!ConflictingDecls.empty()) { | |||
| 4072 | Name = Importer.HandleNameConflict(Name, DC, Decl::IDNS_Ordinary, | |||
| 4073 | ConflictingDecls.data(), | |||
| 4074 | ConflictingDecls.size()); | |||
| 4075 | } | |||
| 4076 | ||||
| 4077 | if (!Name) | |||
| 4078 | return nullptr; | |||
| 4079 | } | |||
| 4080 | ||||
| 4081 | CXXRecordDecl *FromTemplated = D->getTemplatedDecl(); | |||
| 4082 | ||||
| 4083 | // Create the declaration that is being templated. | |||
| 4084 | auto *ToTemplated = cast_or_null<CXXRecordDecl>( | |||
| 4085 | Importer.Import(FromTemplated)); | |||
| 4086 | if (!ToTemplated) | |||
| 4087 | return nullptr; | |||
| 4088 | ||||
| 4089 | // Resolve possible cyclic import. | |||
| 4090 | if (Decl *AlreadyImported = Importer.GetAlreadyImportedOrNull(D)) | |||
| 4091 | return AlreadyImported; | |||
| 4092 | ||||
| 4093 | // Create the class template declaration itself. | |||
| 4094 | TemplateParameterList *TemplateParams = | |||
| 4095 | ImportTemplateParameterList(D->getTemplateParameters()); | |||
| 4096 | if (!TemplateParams) | |||
| 4097 | return nullptr; | |||
| 4098 | ||||
| 4099 | ClassTemplateDecl *D2 = ClassTemplateDecl::Create(Importer.getToContext(), DC, | |||
| 4100 | Loc, Name, TemplateParams, | |||
| 4101 | ToTemplated); | |||
| 4102 | ToTemplated->setDescribedClassTemplate(D2); | |||
| 4103 | ||||
| 4104 | D2->setAccess(D->getAccess()); | |||
| 4105 | D2->setLexicalDeclContext(LexicalDC); | |||
| 4106 | LexicalDC->addDeclInternal(D2); | |||
| 4107 | ||||
| 4108 | // Note the relationship between the class templates. | |||
| 4109 | Importer.Imported(D, D2); | |||
| 4110 | Importer.Imported(FromTemplated, ToTemplated); | |||
| 4111 | ||||
| 4112 | if (FromTemplated->isCompleteDefinition() && | |||
| 4113 | !ToTemplated->isCompleteDefinition()) { | |||
| 4114 | // FIXME: Import definition! | |||
| 4115 | } | |||
| 4116 | ||||
| 4117 | return D2; | |||
| 4118 | } | |||
| 4119 | ||||
| 4120 | Decl *ASTNodeImporter::VisitClassTemplateSpecializationDecl( | |||
| 4121 | ClassTemplateSpecializationDecl *D) { | |||
| 4122 | // If this record has a definition in the translation unit we're coming from, | |||
| 4123 | // but this particular declaration is not that definition, import the | |||
| 4124 | // definition and map to that. | |||
| 4125 | TagDecl *Definition = D->getDefinition(); | |||
| 4126 | if (Definition && Definition != D) { | |||
| 4127 | Decl *ImportedDef = Importer.Import(Definition); | |||
| 4128 | if (!ImportedDef) | |||
| 4129 | return nullptr; | |||
| 4130 | ||||
| 4131 | return Importer.Imported(D, ImportedDef); | |||
| 4132 | } | |||
| 4133 | ||||
| 4134 | auto *ClassTemplate = | |||
| 4135 | cast_or_null<ClassTemplateDecl>(Importer.Import( | |||
| 4136 | D->getSpecializedTemplate())); | |||
| 4137 | if (!ClassTemplate) | |||
| 4138 | return nullptr; | |||
| 4139 | ||||
| 4140 | // Import the context of this declaration. | |||
| 4141 | DeclContext *DC = ClassTemplate->getDeclContext(); | |||
| 4142 | if (!DC) | |||
| 4143 | return nullptr; | |||
| 4144 | ||||
| 4145 | DeclContext *LexicalDC = DC; | |||
| 4146 | if (D->getDeclContext() != D->getLexicalDeclContext()) { | |||
| 4147 | LexicalDC = Importer.ImportContext(D->getLexicalDeclContext()); | |||
| 4148 | if (!LexicalDC) | |||
| 4149 | return nullptr; | |||
| 4150 | } | |||
| 4151 | ||||
| 4152 | // Import the location of this declaration. | |||
| 4153 | SourceLocation StartLoc = Importer.Import(D->getLocStart()); | |||
| 4154 | SourceLocation IdLoc = Importer.Import(D->getLocation()); | |||
| 4155 | ||||
| 4156 | // Import template arguments. | |||
| 4157 | SmallVector<TemplateArgument, 2> TemplateArgs; | |||
| 4158 | if (ImportTemplateArguments(D->getTemplateArgs().data(), | |||
| 4159 | D->getTemplateArgs().size(), | |||
| 4160 | TemplateArgs)) | |||
| 4161 | return nullptr; | |||
| 4162 | ||||
| 4163 | // Try to find an existing specialization with these template arguments. | |||
| 4164 | void *InsertPos = nullptr; | |||
| 4165 | ClassTemplateSpecializationDecl *D2 | |||
| 4166 | = ClassTemplate->findSpecialization(TemplateArgs, InsertPos); | |||
| 4167 | if (D2) { | |||
| 4168 | // We already have a class template specialization with these template | |||
| 4169 | // arguments. | |||
| 4170 | ||||
| 4171 | // FIXME: Check for specialization vs. instantiation errors. | |||
| 4172 | ||||
| 4173 | if (RecordDecl *FoundDef = D2->getDefinition()) { | |||
| 4174 | if (!D->isCompleteDefinition() || IsStructuralMatch(D, FoundDef)) { | |||
| 4175 | // The record types structurally match, or the "from" translation | |||
| 4176 | // unit only had a forward declaration anyway; call it the same | |||
| 4177 | // function. | |||
| 4178 | return Importer.Imported(D, FoundDef); | |||
| 4179 | } | |||
| 4180 | } | |||
| 4181 | } else { | |||
| 4182 | // Create a new specialization. | |||
| 4183 | if (auto *PartialSpec = | |||
| 4184 | dyn_cast<ClassTemplatePartialSpecializationDecl>(D)) { | |||
| 4185 | // Import TemplateArgumentListInfo | |||
| 4186 | TemplateArgumentListInfo ToTAInfo; | |||
| 4187 | const auto &ASTTemplateArgs = *PartialSpec->getTemplateArgsAsWritten(); | |||
| 4188 | if (ImportTemplateArgumentListInfo(ASTTemplateArgs, ToTAInfo)) | |||
| 4189 | return nullptr; | |||
| 4190 | ||||
| 4191 | QualType CanonInjType = Importer.Import( | |||
| 4192 | PartialSpec->getInjectedSpecializationType()); | |||
| 4193 | if (CanonInjType.isNull()) | |||
| 4194 | return nullptr; | |||
| 4195 | CanonInjType = CanonInjType.getCanonicalType(); | |||
| 4196 | ||||
| 4197 | TemplateParameterList *ToTPList = ImportTemplateParameterList( | |||
| 4198 | PartialSpec->getTemplateParameters()); | |||
| 4199 | if (!ToTPList && PartialSpec->getTemplateParameters()) | |||
| 4200 | return nullptr; | |||
| 4201 | ||||
| 4202 | D2 = ClassTemplatePartialSpecializationDecl::Create( | |||
| 4203 | Importer.getToContext(), D->getTagKind(), DC, StartLoc, IdLoc, | |||
| 4204 | ToTPList, ClassTemplate, | |||
| 4205 | llvm::makeArrayRef(TemplateArgs.data(), TemplateArgs.size()), | |||
| 4206 | ToTAInfo, CanonInjType, nullptr); | |||
| 4207 | ||||
| 4208 | } else { | |||
| 4209 | D2 = ClassTemplateSpecializationDecl::Create(Importer.getToContext(), | |||
| 4210 | D->getTagKind(), DC, | |||
| 4211 | StartLoc, IdLoc, | |||
| 4212 | ClassTemplate, | |||
| 4213 | TemplateArgs, | |||
| 4214 | /*PrevDecl=*/nullptr); | |||
| 4215 | } | |||
| 4216 | ||||
| 4217 | D2->setSpecializationKind(D->getSpecializationKind()); | |||
| 4218 | ||||
| 4219 | // Add this specialization to the class template. | |||
| 4220 | ClassTemplate->AddSpecialization(D2, InsertPos); | |||
| 4221 | ||||
| 4222 | // Import the qualifier, if any. | |||
| 4223 | D2->setQualifierInfo(Importer.Import(D->getQualifierLoc())); | |||
| 4224 | ||||
| 4225 | Importer.Imported(D, D2); | |||
| 4226 | ||||
| 4227 | if (auto *TSI = D->getTypeAsWritten()) { | |||
| 4228 | TypeSourceInfo *TInfo = Importer.Import(TSI); | |||
| 4229 | if (!TInfo) | |||
| 4230 | return nullptr; | |||
| 4231 | D2->setTypeAsWritten(TInfo); | |||
| 4232 | D2->setTemplateKeywordLoc(Importer.Import(D->getTemplateKeywordLoc())); | |||
| 4233 | D2->setExternLoc(Importer.Import(D->getExternLoc())); | |||
| 4234 | } | |||
| 4235 | ||||
| 4236 | SourceLocation POI = Importer.Import(D->getPointOfInstantiation()); | |||
| 4237 | if (POI.isValid()) | |||
| 4238 | D2->setPointOfInstantiation(POI); | |||
| 4239 | else if (D->getPointOfInstantiation().isValid()) | |||
| 4240 | return nullptr; | |||
| 4241 | ||||
| 4242 | D2->setTemplateSpecializationKind(D->getTemplateSpecializationKind()); | |||
| 4243 | ||||
| 4244 | // Add the specialization to this context. | |||
| 4245 | D2->setLexicalDeclContext(LexicalDC); | |||
| 4246 | LexicalDC->addDeclInternal(D2); | |||
| 4247 | } | |||
| 4248 | Importer.Imported(D, D2); | |||
| 4249 | if (D->isCompleteDefinition() && ImportDefinition(D, D2)) | |||
| 4250 | return nullptr; | |||
| 4251 | ||||
| 4252 | return D2; | |||
| 4253 | } | |||
| 4254 | ||||
| 4255 | Decl *ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) { | |||
| 4256 | // If this variable has a definition in the translation unit we're coming | |||
| 4257 | // from, | |||
| 4258 | // but this particular declaration is not that definition, import the | |||
| 4259 | // definition and map to that. | |||
| 4260 | auto *Definition = | |||
| 4261 | cast_or_null<VarDecl>(D->getTemplatedDecl()->getDefinition()); | |||
| 4262 | if (Definition && Definition != D->getTemplatedDecl()) { | |||
| 4263 | Decl *ImportedDef = Importer.Import(Definition->getDescribedVarTemplate()); | |||
| 4264 | if (!ImportedDef) | |||
| 4265 | return nullptr; | |||
| 4266 | ||||
| 4267 | return Importer.Imported(D, ImportedDef); | |||
| 4268 | } | |||
| 4269 | ||||
| 4270 | // Import the major distinguishing characteristics of this variable template. | |||
| 4271 | DeclContext *DC, *LexicalDC; | |||
| 4272 | DeclarationName Name; | |||
| 4273 | SourceLocation Loc; | |||
| 4274 | NamedDecl *ToD; | |||
| 4275 | if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc)) | |||
| 4276 | return nullptr; | |||
| 4277 | if (ToD) | |||
| 4278 | return ToD; | |||
| 4279 | ||||
| 4280 | // We may already have a template of the same name; try to find and match it. | |||
| 4281 | assert(!DC->isFunctionOrMethod() &&(static_cast <bool> (!DC->isFunctionOrMethod() && "Variable templates cannot be declared at function scope") ? void (0) : __assert_fail ("!DC->isFunctionOrMethod() && \"Variable templates cannot be declared at function scope\"" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/lib/AST/ASTImporter.cpp" , 4282, __extension__ __PRETTY_FUNCTION__)) | |||
| 4282 | "Variable templates cannot be declared at function scope")(static_cast <bool> (!DC->isFunctionOrMethod() && "Variable templates cannot be declared at function scope") ? void (0) : __assert_fail ("!DC->isFunctionOrMethod() && \"Variable templates cannot be declared at function scope\"" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/lib/AST/ASTImporter.cpp" , 4282, __extension__ __PRETTY_FUNCTION__)); | |||
| 4283 | SmallVector<NamedDecl *, 4> ConflictingDecls; | |||
| 4284 | SmallVector<NamedDecl *, 2> FoundDecls; | |||
| 4285 | DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls); | |||
| 4286 | for (auto *FoundDecl : FoundDecls) { | |||
| 4287 | if (!FoundDecl->isInIdentifierNamespace(Decl::IDNS_Ordinary)) | |||
| 4288 | continue; | |||
| 4289 | ||||
| 4290 | Decl *Found = FoundDecl; | |||
| 4291 | if (auto *FoundTemplate = dyn_cast<VarTemplateDecl>(Found)) { | |||
| 4292 | if (IsStructuralMatch(D, FoundTemplate)) { | |||
| 4293 | // The variable templates structurally match; call it the same template. | |||
| 4294 | Importer.Imported(D->getTemplatedDecl(), | |||
| 4295 | FoundTemplate->getTemplatedDecl()); | |||
| 4296 | return Importer.Imported(D, FoundTemplate); | |||
| 4297 | } | |||
| 4298 | } | |||
| 4299 | ||||
| 4300 | ConflictingDecls.push_back(FoundDecl); | |||
| 4301 | } | |||
| 4302 | ||||
| 4303 | if (!ConflictingDecls.empty()) { | |||
| 4304 | Name = Importer.HandleNameConflict(Name, DC, Decl::IDNS_Ordinary, | |||
| 4305 | ConflictingDecls.data(), | |||
| 4306 | ConflictingDecls.size()); | |||
| 4307 | } | |||
| 4308 | ||||
| 4309 | if (!Name) | |||
| 4310 | return nullptr; | |||
| 4311 | ||||
| 4312 | VarDecl *DTemplated = D->getTemplatedDecl(); | |||
| 4313 | ||||
| 4314 | // Import the type. | |||
| 4315 | QualType T = Importer.Import(DTemplated->getType()); | |||
| 4316 | if (T.isNull()) | |||
| 4317 | return nullptr; | |||
| 4318 | ||||
| 4319 | // Create the declaration that is being templated. | |||
| 4320 | auto *ToTemplated = dyn_cast_or_null<VarDecl>(Importer.Import(DTemplated)); | |||
| 4321 | if (!ToTemplated) | |||
| 4322 | return nullptr; | |||
| 4323 | ||||
| 4324 | // Create the variable template declaration itself. | |||
| 4325 | TemplateParameterList *TemplateParams = | |||
| 4326 | ImportTemplateParameterList(D->getTemplateParameters()); | |||
| 4327 | if (!TemplateParams) | |||
| 4328 | return nullptr; | |||
| 4329 | ||||
| 4330 | VarTemplateDecl *ToVarTD = VarTemplateDecl::Create( | |||
| 4331 | Importer.getToContext(), DC, Loc, Name, TemplateParams, ToTemplated); | |||
| 4332 | ToTemplated->setDescribedVarTemplate(ToVarTD); | |||
| 4333 | ||||
| 4334 | ToVarTD->setAccess(D->getAccess()); | |||
| 4335 | ToVarTD->setLexicalDeclContext(LexicalDC); | |||
| 4336 | LexicalDC->addDeclInternal(ToVarTD); | |||
| 4337 | ||||
| 4338 | // Note the relationship between the variable templates. | |||
| 4339 | Importer.Imported(D, ToVarTD); | |||
| 4340 | Importer.Imported(DTemplated, ToTemplated); | |||
| 4341 | ||||
| 4342 | if (DTemplated->isThisDeclarationADefinition() && | |||
| 4343 | !ToTemplated->isThisDeclarationADefinition()) { | |||
| 4344 | // FIXME: Import definition! | |||
| 4345 | } | |||
| 4346 | ||||
| 4347 | return ToVarTD; | |||
| 4348 | } | |||
| 4349 | ||||
| 4350 | Decl *ASTNodeImporter::VisitVarTemplateSpecializationDecl( | |||
| 4351 | VarTemplateSpecializationDecl *D) { | |||
| 4352 | // If this record has a definition in the translation unit we're coming from, | |||
| 4353 | // but this particular declaration is not that definition, import the | |||
| 4354 | // definition and map to that. | |||
| 4355 | VarDecl *Definition = D->getDefinition(); | |||
| 4356 | if (Definition && Definition != D) { | |||
| 4357 | Decl *ImportedDef = Importer.Import(Definition); | |||
| 4358 | if (!ImportedDef) | |||
| 4359 | return nullptr; | |||
| 4360 | ||||
| 4361 | return Importer.Imported(D, ImportedDef); | |||
| 4362 | } | |||
| 4363 | ||||
| 4364 | auto *VarTemplate = cast_or_null<VarTemplateDecl>( | |||
| 4365 | Importer.Import(D->getSpecializedTemplate())); | |||
| 4366 | if (!VarTemplate) | |||
| 4367 | return nullptr; | |||
| 4368 | ||||
| 4369 | // Import the context of this declaration. | |||
| 4370 | DeclContext *DC = VarTemplate->getDeclContext(); | |||
| 4371 | if (!DC) | |||
| 4372 | return nullptr; | |||
| 4373 | ||||
| 4374 | DeclContext *LexicalDC = DC; | |||
| 4375 | if (D->getDeclContext() != D->getLexicalDeclContext()) { | |||
| 4376 | LexicalDC = Importer.ImportContext(D->getLexicalDeclContext()); | |||
| 4377 | if (!LexicalDC) | |||
| 4378 | return nullptr; | |||
| 4379 | } | |||
| 4380 | ||||
| 4381 | // Import the location of this declaration. | |||
| 4382 | SourceLocation StartLoc = Importer.Import(D->getLocStart()); | |||
| 4383 | SourceLocation IdLoc = Importer.Import(D->getLocation()); | |||
| 4384 | ||||
| 4385 | // Import template arguments. | |||
| 4386 | SmallVector<TemplateArgument, 2> TemplateArgs; | |||
| 4387 | if (ImportTemplateArguments(D->getTemplateArgs().data(), | |||
| 4388 | D->getTemplateArgs().size(), TemplateArgs)) | |||
| 4389 | return nullptr; | |||
| 4390 | ||||
| 4391 | // Try to find an existing specialization with these template arguments. | |||
| 4392 | void *InsertPos = nullptr; | |||
| 4393 | VarTemplateSpecializationDecl *D2 = VarTemplate->findSpecialization( | |||
| 4394 | TemplateArgs, InsertPos); | |||
| 4395 | if (D2) { | |||
| 4396 | // We already have a variable template specialization with these template | |||
| 4397 | // arguments. | |||
| 4398 | ||||
| 4399 | // FIXME: Check for specialization vs. instantiation errors. | |||
| 4400 | ||||
| 4401 | if (VarDecl *FoundDef = D2->getDefinition()) { | |||
| 4402 | if (!D->isThisDeclarationADefinition() || | |||
| 4403 | IsStructuralMatch(D, FoundDef)) { | |||
| 4404 | // The record types structurally match, or the "from" translation | |||
| 4405 | // unit only had a forward declaration anyway; call it the same | |||
| 4406 | // variable. | |||
| 4407 | return Importer.Imported(D, FoundDef); | |||
| 4408 | } | |||
| 4409 | } | |||
| 4410 | } else { | |||
| 4411 | // Import the type. | |||
| 4412 | QualType T = Importer.Import(D->getType()); | |||
| 4413 | if (T.isNull()) | |||
| 4414 | return nullptr; | |||
| 4415 | ||||
| 4416 | TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo()); | |||
| 4417 | if (D->getTypeSourceInfo() && !TInfo) | |||
| 4418 | return nullptr; | |||
| 4419 | ||||
| 4420 | TemplateArgumentListInfo ToTAInfo; | |||
| 4421 | if (ImportTemplateArgumentListInfo(D->getTemplateArgsInfo(), ToTAInfo)) | |||
| 4422 | return nullptr; | |||
| 4423 | ||||
| 4424 | using PartVarSpecDecl = VarTemplatePartialSpecializationDecl; | |||
| 4425 | // Create a new specialization. | |||
| 4426 | if (auto *FromPartial = dyn_cast<PartVarSpecDecl>(D)) { | |||
| 4427 | // Import TemplateArgumentListInfo | |||
| 4428 | TemplateArgumentListInfo ArgInfos; | |||
| 4429 | const auto *FromTAArgsAsWritten = FromPartial->getTemplateArgsAsWritten(); | |||
| 4430 | // NOTE: FromTAArgsAsWritten and template parameter list are non-null. | |||
| 4431 | if (ImportTemplateArgumentListInfo(*FromTAArgsAsWritten, ArgInfos)) | |||
| 4432 | return nullptr; | |||
| 4433 | ||||
| 4434 | TemplateParameterList *ToTPList = ImportTemplateParameterList( | |||
| 4435 | FromPartial->getTemplateParameters()); | |||
| 4436 | if (!ToTPList) | |||
| 4437 | return nullptr; | |||
| 4438 | ||||
| 4439 | auto *ToPartial = PartVarSpecDecl::Create( | |||
| 4440 | Importer.getToContext(), DC, StartLoc, IdLoc, ToTPList, VarTemplate, | |||
| 4441 | T, TInfo, D->getStorageClass(), TemplateArgs, ArgInfos); | |||
| 4442 | ||||
| 4443 | auto *FromInst = FromPartial->getInstantiatedFromMember(); | |||
| 4444 | auto *ToInst = cast_or_null<PartVarSpecDecl>(Importer.Import(FromInst)); | |||
| 4445 | if (FromInst && !ToInst) | |||
| 4446 | return nullptr; | |||
| 4447 | ||||
| 4448 | ToPartial->setInstantiatedFromMember(ToInst); | |||
| 4449 | if (FromPartial->isMemberSpecialization()) | |||
| 4450 | ToPartial->setMemberSpecialization(); | |||
| 4451 | ||||
| 4452 | D2 = ToPartial; | |||
| 4453 | } else { // Full specialization | |||
| 4454 | D2 = VarTemplateSpecializationDecl::Create( | |||
| 4455 | Importer.getToContext(), DC, StartLoc, IdLoc, VarTemplate, T, TInfo, | |||
| 4456 | D->getStorageClass(), TemplateArgs); | |||
| 4457 | } | |||
| 4458 | ||||
| 4459 | SourceLocation POI = D->getPointOfInstantiation(); | |||
| 4460 | if (POI.isValid()) | |||
| 4461 | D2->setPointOfInstantiation(Importer.Import(POI)); | |||
| 4462 | ||||
| 4463 | D2->setSpecializationKind(D->getSpecializationKind()); | |||
| 4464 | D2->setTemplateArgsInfo(ToTAInfo); | |||
| 4465 | ||||
| 4466 | // Add this specialization to the class template. | |||
| 4467 | VarTemplate->AddSpecialization(D2, InsertPos); | |||
| 4468 | ||||
| 4469 | // Import the qualifier, if any. | |||
| 4470 | D2->setQualifierInfo(Importer.Import(D->getQualifierLoc())); | |||
| 4471 | ||||
| 4472 | if (D->isConstexpr()) | |||
| 4473 | D2->setConstexpr(true); | |||
| 4474 | ||||
| 4475 | // Add the specialization to this context. | |||
| 4476 | D2->setLexicalDeclContext(LexicalDC); | |||
| 4477 | LexicalDC->addDeclInternal(D2); | |||
| 4478 | ||||
| 4479 | D2->setAccess(D->getAccess()); | |||
| 4480 | } | |||
| 4481 | ||||
| 4482 | Importer.Imported(D, D2); | |||
| 4483 | ||||
| 4484 | // NOTE: isThisDeclarationADefinition() can return DeclarationOnly even if | |||
| 4485 | // declaration has initializer. Should this be fixed in the AST?.. Anyway, | |||
| 4486 | // we have to check the declaration for initializer - otherwise, it won't be | |||
| 4487 | // imported. | |||
| 4488 | if ((D->isThisDeclarationADefinition() || D->hasInit()) && | |||
| 4489 | ImportDefinition(D, D2)) | |||
| 4490 | return nullptr; | |||
| 4491 | ||||
| 4492 | return D2; | |||
| 4493 | } | |||
| 4494 | ||||
| 4495 | Decl *ASTNodeImporter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { | |||
| 4496 | DeclContext *DC, *LexicalDC; | |||
| 4497 | DeclarationName Name; | |||
| 4498 | SourceLocation Loc; | |||
| 4499 | NamedDecl *ToD; | |||
| 4500 | ||||
| 4501 | if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc)) | |||
| 4502 | return nullptr; | |||
| 4503 | ||||
| 4504 | if (ToD) | |||
| 4505 | return ToD; | |||
| 4506 | ||||
| 4507 | // Try to find a function in our own ("to") context with the same name, same | |||
| 4508 | // type, and in the same context as the function we're importing. | |||
| 4509 | if (!LexicalDC->isFunctionOrMethod()) { | |||
| 4510 | unsigned IDNS = Decl::IDNS_Ordinary; | |||
| 4511 | SmallVector<NamedDecl *, 2> FoundDecls; | |||
| 4512 | DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls); | |||
| 4513 | for (auto *FoundDecl : FoundDecls) { | |||
| 4514 | if (!FoundDecl->isInIdentifierNamespace(IDNS)) | |||
| 4515 | continue; | |||
| 4516 | ||||
| 4517 | if (auto *FoundFunction = dyn_cast<FunctionTemplateDecl>(FoundDecl)) { | |||
| 4518 | if (FoundFunction->hasExternalFormalLinkage() && | |||
| 4519 | D->hasExternalFormalLinkage()) { | |||
| 4520 | if (IsStructuralMatch(D, FoundFunction)) { | |||
| 4521 | Importer.Imported(D, FoundFunction); | |||
| 4522 | // FIXME: Actually try to merge the body and other attributes. | |||
| 4523 | return FoundFunction; | |||
| 4524 | } | |||
| 4525 | } | |||
| 4526 | } | |||
| 4527 | } | |||
| 4528 | } | |||
| 4529 | ||||
| 4530 | TemplateParameterList *Params = | |||
| 4531 | ImportTemplateParameterList(D->getTemplateParameters()); | |||
| 4532 | if (!Params) | |||
| 4533 | return nullptr; | |||
| 4534 | ||||
| 4535 | auto *TemplatedFD = | |||
| 4536 | cast_or_null<FunctionDecl>(Importer.Import(D->getTemplatedDecl())); | |||
| 4537 | if (!TemplatedFD) | |||
| 4538 | return nullptr; | |||
| 4539 | ||||
| 4540 | FunctionTemplateDecl *ToFunc = FunctionTemplateDecl::Create( | |||
| 4541 | Importer.getToContext(), DC, Loc, Name, Params, TemplatedFD); | |||
| 4542 | ||||
| 4543 | TemplatedFD->setDescribedFunctionTemplate(ToFunc); | |||
| 4544 | ToFunc->setAccess(D->getAccess()); | |||
| 4545 | ToFunc->setLexicalDeclContext(LexicalDC); | |||
| 4546 | Importer.Imported(D, ToFunc); | |||
| 4547 | ||||
| 4548 | LexicalDC->addDeclInternal(ToFunc); | |||
| 4549 | return ToFunc; | |||
| 4550 | } | |||
| 4551 | ||||
| 4552 | //---------------------------------------------------------------------------- | |||
| 4553 | // Import Statements | |||
| 4554 | //---------------------------------------------------------------------------- | |||
| 4555 | ||||
| 4556 | DeclGroupRef ASTNodeImporter::ImportDeclGroup(DeclGroupRef DG) { | |||
| 4557 | if (DG.isNull()) | |||
| 4558 | return DeclGroupRef::Create(Importer.getToContext(), nullptr, 0); | |||
| 4559 | size_t NumDecls = DG.end() - DG.begin(); | |||
| 4560 | SmallVector<Decl *, 1> ToDecls(NumDecls); | |||
| 4561 | auto &_Importer = this->Importer; | |||
| 4562 | std::transform(DG.begin(), DG.end(), ToDecls.begin(), | |||
| 4563 | [&_Importer](Decl *D) -> Decl * { | |||
| 4564 | return _Importer.Import(D); | |||
| 4565 | }); | |||
| 4566 | return DeclGroupRef::Create(Importer.getToContext(), | |||
| 4567 | ToDecls.begin(), | |||
| 4568 | NumDecls); | |||
| 4569 | } | |||
| 4570 | ||||
| 4571 | Stmt *ASTNodeImporter::VisitStmt(Stmt *S) { | |||
| 4572 | Importer.FromDiag(S->getLocStart(), diag::err_unsupported_ast_node) | |||
| 4573 | << S->getStmtClassName(); | |||
| 4574 | return nullptr; | |||
| 4575 | } | |||
| 4576 | ||||
| 4577 | Stmt *ASTNodeImporter::VisitGCCAsmStmt(GCCAsmStmt *S) { | |||
| 4578 | SmallVector<IdentifierInfo *, 4> Names; | |||
| 4579 | for (unsigned I = 0, E = S->getNumOutputs(); I != E; I++) { | |||
| 4580 | IdentifierInfo *ToII = Importer.Import(S->getOutputIdentifier(I)); | |||
| 4581 | // ToII is nullptr when no symbolic name is given for output operand | |||
| 4582 | // see ParseStmtAsm::ParseAsmOperandsOpt | |||
| 4583 | if (!ToII && S->getOutputIdentifier(I)) | |||
| 4584 | return nullptr; | |||
| 4585 | Names.push_back(ToII); | |||
| 4586 | } | |||
| 4587 | for (unsigned I = 0, E = S->getNumInputs(); I != E; I++) { | |||
| 4588 | IdentifierInfo *ToII = Importer.Import(S->getInputIdentifier(I)); | |||
| 4589 | // ToII is nullptr when no symbolic name is given for input operand | |||
| 4590 | // see ParseStmtAsm::ParseAsmOperandsOpt | |||
| 4591 | if (!ToII && S->getInputIdentifier(I)) | |||
| 4592 | return nullptr; | |||
| 4593 | Names.push_back(ToII); | |||
| 4594 | } | |||
| 4595 | ||||
| 4596 | SmallVector<StringLiteral *, 4> Clobbers; | |||
| 4597 | for (unsigned I = 0, E = S->getNumClobbers(); I != E; I++) { | |||
| 4598 | auto *Clobber = cast_or_null<StringLiteral>( | |||
| 4599 | Importer.Import(S->getClobberStringLiteral(I))); | |||
| 4600 | if (!Clobber) | |||
| 4601 | return nullptr; | |||
| 4602 | Clobbers.push_back(Clobber); | |||
| 4603 | } | |||
| 4604 | ||||
| 4605 | SmallVector<StringLiteral *, 4> Constraints; | |||
| 4606 | for (unsigned I = 0, E = S->getNumOutputs(); I != E; I++) { | |||
| 4607 | auto *Output = cast_or_null<StringLiteral>( | |||
| 4608 | Importer.Import(S->getOutputConstraintLiteral(I))); | |||
| 4609 | if (!Output) | |||
| 4610 | return nullptr; | |||
| 4611 | Constraints.push_back(Output); | |||
| 4612 | } | |||
| 4613 | ||||
| 4614 | for (unsigned I = 0, E = S->getNumInputs(); I != E; I++) { | |||
| 4615 | auto *Input = cast_or_null<StringLiteral>( | |||
| 4616 | Importer.Import(S->getInputConstraintLiteral(I))); | |||
| 4617 | if (!Input) | |||
| 4618 | return nullptr; | |||
| 4619 | Constraints.push_back(Input); | |||
| 4620 | } | |||
| 4621 | ||||
| 4622 | SmallVector<Expr *, 4> Exprs(S->getNumOutputs() + S->getNumInputs()); | |||
| 4623 | if (ImportContainerChecked(S->outputs(), Exprs)) | |||
| 4624 | return nullptr; | |||
| 4625 | ||||
| 4626 | if (ImportArrayChecked(S->inputs(), Exprs.begin() + S->getNumOutputs())) | |||
| 4627 | return nullptr; | |||
| 4628 | ||||
| 4629 | auto *AsmStr = cast_or_null<StringLiteral>( | |||
| 4630 | Importer.Import(S->getAsmString())); | |||
| 4631 | if (!AsmStr) | |||
| 4632 | return nullptr; | |||
| 4633 | ||||
| 4634 | return new (Importer.getToContext()) GCCAsmStmt( | |||
| 4635 | Importer.getToContext(), | |||
| 4636 | Importer.Import(S->getAsmLoc()), | |||
| 4637 | S->isSimple(), | |||
| 4638 | S->isVolatile(), | |||
| 4639 | S->getNumOutputs(), | |||
| 4640 | S->getNumInputs(), | |||
| 4641 | Names.data(), | |||
| 4642 | Constraints.data(), | |||
| 4643 | Exprs.data(), | |||
| 4644 | AsmStr, | |||
| 4645 | S->getNumClobbers(), | |||
| 4646 | Clobbers.data(), | |||
| 4647 | Importer.Import(S->getRParenLoc())); | |||
| 4648 | } | |||
| 4649 | ||||
| 4650 | Stmt *ASTNodeImporter::VisitDeclStmt(DeclStmt *S) { | |||
| 4651 | DeclGroupRef ToDG = ImportDeclGroup(S->getDeclGroup()); | |||
| 4652 | for (auto *ToD : ToDG) { | |||
| 4653 | if (!ToD) | |||
| 4654 | return nullptr; | |||
| 4655 | } | |||
| 4656 | SourceLocation ToStartLoc = Importer.Import(S->getStartLoc()); | |||
| 4657 | SourceLocation ToEndLoc = Importer.Import(S->getEndLoc()); | |||
| 4658 | return new (Importer.getToContext()) DeclStmt(ToDG, ToStartLoc, ToEndLoc); | |||
| 4659 | } | |||
| 4660 | ||||
| 4661 | Stmt *ASTNodeImporter::VisitNullStmt(NullStmt *S) { | |||
| 4662 | SourceLocation ToSemiLoc = Importer.Import(S->getSemiLoc()); | |||
| 4663 | return new (Importer.getToContext()) NullStmt(ToSemiLoc, | |||
| 4664 | S->hasLeadingEmptyMacro()); | |||
| 4665 | } | |||
| 4666 | ||||
| 4667 | Stmt *ASTNodeImporter::VisitCompoundStmt(CompoundStmt *S) { | |||
| 4668 | SmallVector<Stmt *, 8> ToStmts(S->size()); | |||
| 4669 | ||||
| 4670 | if (ImportContainerChecked(S->body(), ToStmts)) | |||
| 4671 | return nullptr; | |||
| 4672 | ||||
| 4673 | SourceLocation ToLBraceLoc = Importer.Import(S->getLBracLoc()); | |||
| 4674 | SourceLocation ToRBraceLoc = Importer.Import(S->getRBracLoc()); | |||
| 4675 | return CompoundStmt::Create(Importer.getToContext(), ToStmts, ToLBraceLoc, | |||
| 4676 | ToRBraceLoc); | |||
| 4677 | } | |||
| 4678 | ||||
| 4679 | Stmt *ASTNodeImporter::VisitCaseStmt(CaseStmt *S) { | |||
| 4680 | Expr *ToLHS = Importer.Import(S->getLHS()); | |||
| 4681 | if (!ToLHS) | |||
| 4682 | return nullptr; | |||
| 4683 | Expr *ToRHS = Importer.Import(S->getRHS()); | |||
| 4684 | if (!ToRHS && S->getRHS()) | |||
| 4685 | return nullptr; | |||
| 4686 | Stmt *ToSubStmt = Importer.Import(S->getSubStmt()); | |||
| 4687 | if (!ToSubStmt && S->getSubStmt()) | |||
| 4688 | return nullptr; | |||
| 4689 | SourceLocation ToCaseLoc = Importer.Import(S->getCaseLoc()); | |||
| 4690 | SourceLocation ToEllipsisLoc = Importer.Import(S->getEllipsisLoc()); | |||
| 4691 | SourceLocation ToColonLoc = Importer.Import(S->getColonLoc()); | |||
| 4692 | auto *ToStmt = new (Importer.getToContext()) | |||
| 4693 | CaseStmt(ToLHS, ToRHS, ToCaseLoc, ToEllipsisLoc, ToColonLoc); | |||
| 4694 | ToStmt->setSubStmt(ToSubStmt); | |||
| 4695 | return ToStmt; | |||
| 4696 | } | |||
| 4697 | ||||
| 4698 | Stmt *ASTNodeImporter::VisitDefaultStmt(DefaultStmt *S) { | |||
| 4699 | SourceLocation ToDefaultLoc = Importer.Import(S->getDefaultLoc()); | |||
| 4700 | SourceLocation ToColonLoc = Importer.Import(S->getColonLoc()); | |||
| 4701 | Stmt *ToSubStmt = Importer.Import(S->getSubStmt()); | |||
| 4702 | if (!ToSubStmt && S->getSubStmt()) | |||
| 4703 | return nullptr; | |||
| 4704 | return new (Importer.getToContext()) DefaultStmt(ToDefaultLoc, ToColonLoc, | |||
| 4705 | ToSubStmt); | |||
| 4706 | } | |||
| 4707 | ||||
| 4708 | Stmt *ASTNodeImporter::VisitLabelStmt(LabelStmt *S) { | |||
| 4709 | SourceLocation ToIdentLoc = Importer.Import(S->getIdentLoc()); | |||
| 4710 | auto *ToLabelDecl = cast_or_null<LabelDecl>(Importer.Import(S->getDecl())); | |||
| 4711 | if (!ToLabelDecl && S->getDecl()) | |||
| 4712 | return nullptr; | |||
| 4713 | Stmt *ToSubStmt = Importer.Import(S->getSubStmt()); | |||
| 4714 | if (!ToSubStmt && S->getSubStmt()) | |||
| 4715 | return nullptr; | |||
| 4716 | return new (Importer.getToContext()) LabelStmt(ToIdentLoc, ToLabelDecl, | |||
| 4717 | ToSubStmt); | |||
| 4718 | } | |||
| 4719 | ||||
| 4720 | Stmt *ASTNodeImporter::VisitAttributedStmt(AttributedStmt *S) { | |||
| 4721 | SourceLocation ToAttrLoc = Importer.Import(S->getAttrLoc()); | |||
| 4722 | ArrayRef<const Attr*> FromAttrs(S->getAttrs()); | |||
| 4723 | SmallVector<const Attr *, 1> ToAttrs(FromAttrs.size()); | |||
| 4724 | ASTContext &_ToContext = Importer.getToContext(); | |||
| 4725 | std::transform(FromAttrs.begin(), FromAttrs.end(), ToAttrs.begin(), | |||
| 4726 | [&_ToContext](const Attr *A) -> const Attr * { | |||
| 4727 | return A->clone(_ToContext); | |||
| 4728 | }); | |||
| 4729 | for (const auto *ToA : ToAttrs) { | |||
| 4730 | if (!ToA) | |||
| 4731 | return nullptr; | |||
| 4732 | } | |||
| 4733 | Stmt *ToSubStmt = Importer.Import(S->getSubStmt()); | |||
| 4734 | if (!ToSubStmt && S->getSubStmt()) | |||
| 4735 | return nullptr; | |||
| 4736 | return AttributedStmt::Create(Importer.getToContext(), ToAttrLoc, | |||
| 4737 | ToAttrs, ToSubStmt); | |||
| 4738 | } | |||
| 4739 | ||||
| 4740 | Stmt *ASTNodeImporter::VisitIfStmt(IfStmt *S) { | |||
| 4741 | SourceLocation ToIfLoc = Importer.Import(S->getIfLoc()); | |||
| 4742 | Stmt *ToInit = Importer.Import(S->getInit()); | |||
| 4743 | if (!ToInit && S->getInit()) | |||
| 4744 | return nullptr; | |||
| 4745 | VarDecl *ToConditionVariable = nullptr; | |||
| 4746 | if (VarDecl *FromConditionVariable = S->getConditionVariable()) { | |||
| 4747 | ToConditionVariable = | |||
| 4748 | dyn_cast_or_null<VarDecl>(Importer.Import(FromConditionVariable)); | |||
| 4749 | if (!ToConditionVariable) | |||
| 4750 | return nullptr; | |||
| 4751 | } | |||
| 4752 | Expr *ToCondition = Importer.Import(S->getCond()); | |||
| 4753 | if (!ToCondition && S->getCond()) | |||
| 4754 | return nullptr; | |||
| 4755 | Stmt *ToThenStmt = Importer.Import(S->getThen()); | |||
| 4756 | if (!ToThenStmt && S->getThen()) | |||
| 4757 | return nullptr; | |||
| 4758 | SourceLocation ToElseLoc = Importer.Import(S->getElseLoc()); | |||
| 4759 | Stmt *ToElseStmt = Importer.Import(S->getElse()); | |||
| 4760 | if (!ToElseStmt && S->getElse()) | |||
| 4761 | return nullptr; | |||
| 4762 | return new (Importer.getToContext()) IfStmt(Importer.getToContext(), | |||
| 4763 | ToIfLoc, S->isConstexpr(), | |||
| 4764 | ToInit, | |||
| 4765 | ToConditionVariable, | |||
| 4766 | ToCondition, ToThenStmt, | |||
| 4767 | ToElseLoc, ToElseStmt); | |||
| 4768 | } | |||
| 4769 | ||||
| 4770 | Stmt *ASTNodeImporter::VisitSwitchStmt(SwitchStmt *S) { | |||
| 4771 | Stmt *ToInit = Importer.Import(S->getInit()); | |||
| 4772 | if (!ToInit && S->getInit()) | |||
| 4773 | return nullptr; | |||
| 4774 | VarDecl *ToConditionVariable = nullptr; | |||
| 4775 | if (VarDecl *FromConditionVariable = S->getConditionVariable()) { | |||
| 4776 | ToConditionVariable = | |||
| 4777 | dyn_cast_or_null<VarDecl>(Importer.Import(FromConditionVariable)); | |||
| 4778 | if (!ToConditionVariable) | |||
| 4779 | return nullptr; | |||
| 4780 | } | |||
| 4781 | Expr *ToCondition = Importer.Import(S->getCond()); | |||
| 4782 | if (!ToCondition && S->getCond()) | |||
| 4783 | return nullptr; | |||
| 4784 | auto *ToStmt = new (Importer.getToContext()) SwitchStmt( | |||
| 4785 | Importer.getToContext(), ToInit, | |||
| 4786 | ToConditionVariable, ToCondition); | |||
| 4787 | Stmt *ToBody = Importer.Import(S->getBody()); | |||
| 4788 | if (!ToBody && S->getBody()) | |||
| 4789 | return nullptr; | |||
| 4790 | ToStmt->setBody(ToBody); | |||
| 4791 | ToStmt->setSwitchLoc(Importer.Import(S->getSwitchLoc())); | |||
| 4792 | // Now we have to re-chain the cases. | |||
| 4793 | SwitchCase *LastChainedSwitchCase = nullptr; | |||
| 4794 | for (SwitchCase *SC = S->getSwitchCaseList(); SC != nullptr; | |||
| 4795 | SC = SC->getNextSwitchCase()) { | |||
| 4796 | auto *ToSC = dyn_cast_or_null<SwitchCase>(Importer.Import(SC)); | |||
| 4797 | if (!ToSC) | |||
| 4798 | return nullptr; | |||
| 4799 | if (LastChainedSwitchCase) | |||
| 4800 | LastChainedSwitchCase->setNextSwitchCase(ToSC); | |||
| 4801 | else | |||
| 4802 | ToStmt->setSwitchCaseList(ToSC); | |||
| 4803 | LastChainedSwitchCase = ToSC; | |||
| 4804 | } | |||
| 4805 | return ToStmt; | |||
| 4806 | } | |||
| 4807 | ||||
| 4808 | Stmt *ASTNodeImporter::VisitWhileStmt(WhileStmt *S) { | |||
| 4809 | VarDecl *ToConditionVariable = nullptr; | |||
| 4810 | if (VarDecl *FromConditionVariable = S->getConditionVariable()) { | |||
| 4811 | ToConditionVariable = | |||
| 4812 | dyn_cast_or_null<VarDecl>(Importer.Import(FromConditionVariable)); | |||
| 4813 | if (!ToConditionVariable) | |||
| 4814 | return nullptr; | |||
| 4815 | } | |||
| 4816 | Expr *ToCondition = Importer.Import(S->getCond()); | |||
| 4817 | if (!ToCondition && S->getCond()) | |||
| 4818 | return nullptr; | |||
| 4819 | Stmt *ToBody = Importer.Import(S->getBody()); | |||
| 4820 | if (!ToBody && S->getBody()) | |||
| 4821 | return nullptr; | |||
| 4822 | SourceLocation ToWhileLoc = Importer.Import(S->getWhileLoc()); | |||
| 4823 | return new (Importer.getToContext()) WhileStmt(Importer.getToContext(), | |||
| 4824 | ToConditionVariable, | |||
| 4825 | ToCondition, ToBody, | |||
| 4826 | ToWhileLoc); | |||
| 4827 | } | |||
| 4828 | ||||
| 4829 | Stmt *ASTNodeImporter::VisitDoStmt(DoStmt *S) { | |||
| 4830 | Stmt *ToBody = Importer.Import(S->getBody()); | |||
| 4831 | if (!ToBody && S->getBody()) | |||
| 4832 | return nullptr; | |||
| 4833 | Expr *ToCondition = Importer.Import(S->getCond()); | |||
| 4834 | if (!ToCondition && S->getCond()) | |||
| 4835 | return nullptr; | |||
| 4836 | SourceLocation ToDoLoc = Importer.Import(S->getDoLoc()); | |||
| 4837 | SourceLocation ToWhileLoc = Importer.Import(S->getWhileLoc()); | |||
| 4838 | SourceLocation ToRParenLoc = Importer.Import(S->getRParenLoc()); | |||
| 4839 | return new (Importer.getToContext()) DoStmt(ToBody, ToCondition, | |||
| 4840 | ToDoLoc, ToWhileLoc, | |||
| 4841 | ToRParenLoc); | |||
| 4842 | } | |||
| 4843 | ||||
| 4844 | Stmt *ASTNodeImporter::VisitForStmt(ForStmt *S) { | |||
| 4845 | Stmt *ToInit = Importer.Import(S->getInit()); | |||
| 4846 | if (!ToInit && S->getInit()) | |||
| 4847 | return nullptr; | |||
| 4848 | Expr *ToCondition = Importer.Import(S->getCond()); | |||
| 4849 | if (!ToCondition && S->getCond()) | |||
| 4850 | return nullptr; | |||
| 4851 | VarDecl *ToConditionVariable = nullptr; | |||
| 4852 | if (VarDecl *FromConditionVariable = S->getConditionVariable()) { | |||
| 4853 | ToConditionVariable = | |||
| 4854 | dyn_cast_or_null<VarDecl>(Importer.Import(FromConditionVariable)); | |||
| 4855 | if (!ToConditionVariable) | |||
| 4856 | return nullptr; | |||
| 4857 | } | |||
| 4858 | Expr *ToInc = Importer.Import(S->getInc()); | |||
| 4859 | if (!ToInc && S->getInc()) | |||
| 4860 | return nullptr; | |||
| 4861 | Stmt *ToBody = Importer.Import(S->getBody()); | |||
| 4862 | if (!ToBody && S->getBody()) | |||
| 4863 | return nullptr; | |||
| 4864 | SourceLocation ToForLoc = Importer.Import(S->getForLoc()); | |||
| 4865 | SourceLocation ToLParenLoc = Importer.Import(S->getLParenLoc()); | |||
| 4866 | SourceLocation ToRParenLoc = Importer.Import(S->getRParenLoc()); | |||
| 4867 | return new (Importer.getToContext()) ForStmt(Importer.getToContext(), | |||
| 4868 | ToInit, ToCondition, | |||
| 4869 | ToConditionVariable, | |||
| 4870 | ToInc, ToBody, | |||
| 4871 | ToForLoc, ToLParenLoc, | |||
| 4872 | ToRParenLoc); | |||
| 4873 | } | |||
| 4874 | ||||
| 4875 | Stmt *ASTNodeImporter::VisitGotoStmt(GotoStmt *S) { | |||
| 4876 | LabelDecl *ToLabel = nullptr; | |||
| 4877 | if (LabelDecl *FromLabel = S->getLabel()) { | |||
| 4878 | ToLabel = dyn_cast_or_null<LabelDecl>(Importer.Import(FromLabel)); | |||
| 4879 | if (!ToLabel) | |||
| 4880 | return nullptr; | |||
| 4881 | } | |||
| 4882 | SourceLocation ToGotoLoc = Importer.Import(S->getGotoLoc()); | |||
| 4883 | SourceLocation ToLabelLoc = Importer.Import(S->getLabelLoc()); | |||
| 4884 | return new (Importer.getToContext()) GotoStmt(ToLabel, | |||
| 4885 | ToGotoLoc, ToLabelLoc); | |||
| 4886 | } | |||
| 4887 | ||||
| 4888 | Stmt *ASTNodeImporter::VisitIndirectGotoStmt(IndirectGotoStmt *S) { | |||
| 4889 | SourceLocation ToGotoLoc = Importer.Import(S->getGotoLoc()); | |||
| 4890 | SourceLocation ToStarLoc = Importer.Import(S->getStarLoc()); | |||
| 4891 | Expr *ToTarget = Importer.Import(S->getTarget()); | |||
| 4892 | if (!ToTarget && S->getTarget()) | |||
| 4893 | return nullptr; | |||
| 4894 | return new (Importer.getToContext()) IndirectGotoStmt(ToGotoLoc, ToStarLoc, | |||
| 4895 | ToTarget); | |||
| 4896 | } | |||
| 4897 | ||||
| 4898 | Stmt *ASTNodeImporter::VisitContinueStmt(ContinueStmt *S) { | |||
| 4899 | SourceLocation ToContinueLoc = Importer.Import(S->getContinueLoc()); | |||
| 4900 | return new (Importer.getToContext()) ContinueStmt(ToContinueLoc); | |||
| 4901 | } | |||
| 4902 | ||||
| 4903 | Stmt *ASTNodeImporter::VisitBreakStmt(BreakStmt *S) { | |||
| 4904 | SourceLocation ToBreakLoc = Importer.Import(S->getBreakLoc()); | |||
| 4905 | return new (Importer.getToContext()) BreakStmt(ToBreakLoc); | |||
| 4906 | } | |||
| 4907 | ||||
| 4908 | Stmt *ASTNodeImporter::VisitReturnStmt(ReturnStmt *S) { | |||
| 4909 | SourceLocation ToRetLoc = Importer.Import(S->getReturnLoc()); | |||
| 4910 | Expr *ToRetExpr = Importer.Import(S->getRetValue()); | |||
| 4911 | if (!ToRetExpr && S->getRetValue()) | |||
| 4912 | return nullptr; | |||
| 4913 | auto *NRVOCandidate = const_cast<VarDecl *>(S->getNRVOCandidate()); | |||
| 4914 | auto *ToNRVOCandidate = cast_or_null<VarDecl>(Importer.Import(NRVOCandidate)); | |||
| 4915 | if (!ToNRVOCandidate && NRVOCandidate) | |||
| 4916 | return nullptr; | |||
| 4917 | return new (Importer.getToContext()) ReturnStmt(ToRetLoc, ToRetExpr, | |||
| 4918 | ToNRVOCandidate); | |||
| 4919 | } | |||
| 4920 | ||||
| 4921 | Stmt *ASTNodeImporter::VisitCXXCatchStmt(CXXCatchStmt *S) { | |||
| 4922 | SourceLocation ToCatchLoc = Importer.Import(S->getCatchLoc()); | |||
| 4923 | VarDecl *ToExceptionDecl = nullptr; | |||
| 4924 | if (VarDecl *FromExceptionDecl = S->getExceptionDecl()) { | |||
| 4925 | ToExceptionDecl = | |||
| 4926 | dyn_cast_or_null<VarDecl>(Importer.Import(FromExceptionDecl)); | |||
| 4927 | if (!ToExceptionDecl) | |||
| 4928 | return nullptr; | |||
| 4929 | } | |||
| 4930 | Stmt *ToHandlerBlock = Importer.Import(S->getHandlerBlock()); | |||
| 4931 | if (!ToHandlerBlock && S->getHandlerBlock()) | |||
| 4932 | return nullptr; | |||
| 4933 | return new (Importer.getToContext()) CXXCatchStmt(ToCatchLoc, | |||
| 4934 | ToExceptionDecl, | |||
| 4935 | ToHandlerBlock); | |||
| 4936 | } | |||
| 4937 | ||||
| 4938 | Stmt *ASTNodeImporter::VisitCXXTryStmt(CXXTryStmt *S) { | |||
| 4939 | SourceLocation ToTryLoc = Importer.Import(S->getTryLoc()); | |||
| 4940 | Stmt *ToTryBlock = Importer.Import(S->getTryBlock()); | |||
| 4941 | if (!ToTryBlock && S->getTryBlock()) | |||
| 4942 | return nullptr; | |||
| 4943 | SmallVector<Stmt *, 1> ToHandlers(S->getNumHandlers()); | |||
| 4944 | for (unsigned HI = 0, HE = S->getNumHandlers(); HI != HE; ++HI) { | |||
| 4945 | CXXCatchStmt *FromHandler = S->getHandler(HI); | |||
| 4946 | if (Stmt *ToHandler = Importer.Import(FromHandler)) | |||
| 4947 | ToHandlers[HI] = ToHandler; | |||
| 4948 | else | |||
| 4949 | return nullptr; | |||
| 4950 | } | |||
| 4951 | return CXXTryStmt::Create(Importer.getToContext(), ToTryLoc, ToTryBlock, | |||
| 4952 | ToHandlers); | |||
| 4953 | } | |||
| 4954 | ||||
| 4955 | Stmt *ASTNodeImporter::VisitCXXForRangeStmt(CXXForRangeStmt *S) { | |||
| 4956 | auto *ToRange = | |||
| 4957 | dyn_cast_or_null<DeclStmt>(Importer.Import(S->getRangeStmt())); | |||
| 4958 | if (!ToRange && S->getRangeStmt()) | |||
| 4959 | return nullptr; | |||
| 4960 | auto *ToBegin = | |||
| 4961 | dyn_cast_or_null<DeclStmt>(Importer.Import(S->getBeginStmt())); | |||
| 4962 | if (!ToBegin && S->getBeginStmt()) | |||
| 4963 | return nullptr; | |||
| 4964 | auto *ToEnd = | |||
| 4965 | dyn_cast_or_null<DeclStmt>(Importer.Import(S->getEndStmt())); | |||
| 4966 | if (!ToEnd && S->getEndStmt()) | |||
| 4967 | return nullptr; | |||
| 4968 | Expr *ToCond = Importer.Import(S->getCond()); | |||
| 4969 | if (!ToCond && S->getCond()) | |||
| 4970 | return nullptr; | |||
| 4971 | Expr *ToInc = Importer.Import(S->getInc()); | |||
| 4972 | if (!ToInc && S->getInc()) | |||
| 4973 | return nullptr; | |||
| 4974 | auto *ToLoopVar = | |||
| 4975 | dyn_cast_or_null<DeclStmt>(Importer.Import(S->getLoopVarStmt())); | |||
| 4976 | if (!ToLoopVar && S->getLoopVarStmt()) | |||
| 4977 | return nullptr; | |||
| 4978 | Stmt *ToBody = Importer.Import(S->getBody()); | |||
| 4979 | if (!ToBody && S->getBody()) | |||
| 4980 | return nullptr; | |||
| 4981 | SourceLocation ToForLoc = Importer.Import(S->getForLoc()); | |||
| 4982 | SourceLocation ToCoawaitLoc = Importer.Import(S->getCoawaitLoc()); | |||
| 4983 | SourceLocation ToColonLoc = Importer.Import(S->getColonLoc()); | |||
| 4984 | SourceLocation ToRParenLoc = Importer.Import(S->getRParenLoc()); | |||
| 4985 | return new (Importer.getToContext()) CXXForRangeStmt(ToRange, ToBegin, ToEnd, | |||
| 4986 | ToCond, ToInc, | |||
| 4987 | ToLoopVar, ToBody, | |||
| 4988 | ToForLoc, ToCoawaitLoc, | |||
| 4989 | ToColonLoc, ToRParenLoc); | |||
| 4990 | } | |||
| 4991 | ||||
| 4992 | Stmt *ASTNodeImporter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) { | |||
| 4993 | Stmt *ToElem = Importer.Import(S->getElement()); | |||
| 4994 | if (!ToElem && S->getElement()) | |||
| 4995 | return nullptr; | |||
| 4996 | Expr *ToCollect = Importer.Import(S->getCollection()); | |||
| 4997 | if (!ToCollect && S->getCollection()) | |||
| 4998 | return nullptr; | |||
| 4999 | Stmt *ToBody = Importer.Import(S->getBody()); | |||
| 5000 | if (!ToBody && S->getBody()) | |||
| 5001 | return nullptr; | |||
| 5002 | SourceLocation ToForLoc = Importer.Import(S->getForLoc()); | |||
| 5003 | SourceLocation ToRParenLoc = Importer.Import(S->getRParenLoc()); | |||
| 5004 | return new (Importer.getToContext()) ObjCForCollectionStmt(ToElem, | |||
| 5005 | ToCollect, | |||
| 5006 | ToBody, ToForLoc, | |||
| 5007 | ToRParenLoc); | |||
| 5008 | } | |||
| 5009 | ||||
| 5010 | Stmt *ASTNodeImporter::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) { | |||
| 5011 | SourceLocation ToAtCatchLoc = Importer.Import(S->getAtCatchLoc()); | |||
| 5012 | SourceLocation ToRParenLoc = Importer.Import(S->getRParenLoc()); | |||
| 5013 | VarDecl *ToExceptionDecl = nullptr; | |||
| 5014 | if (VarDecl *FromExceptionDecl = S->getCatchParamDecl()) { | |||
| 5015 | ToExceptionDecl = | |||
| 5016 | dyn_cast_or_null<VarDecl>(Importer.Import(FromExceptionDecl)); | |||
| 5017 | if (!ToExceptionDecl) | |||
| 5018 | return nullptr; | |||
| 5019 | } | |||
| 5020 | Stmt *ToBody = Importer.Import(S->getCatchBody()); | |||
| 5021 | if (!ToBody && S->getCatchBody()) | |||
| 5022 | return nullptr; | |||
| 5023 | return new (Importer.getToContext()) ObjCAtCatchStmt(ToAtCatchLoc, | |||
| 5024 | ToRParenLoc, | |||
| 5025 | ToExceptionDecl, | |||
| 5026 | ToBody); | |||
| 5027 | } | |||
| 5028 | ||||
| 5029 | Stmt *ASTNodeImporter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) { | |||
| 5030 | SourceLocation ToAtFinallyLoc = Importer.Import(S->getAtFinallyLoc()); | |||
| 5031 | Stmt *ToAtFinallyStmt = Importer.Import(S->getFinallyBody()); | |||
| 5032 | if (!ToAtFinallyStmt && S->getFinallyBody()) | |||
| 5033 | return nullptr; | |||
| 5034 | return new (Importer.getToContext()) ObjCAtFinallyStmt(ToAtFinallyLoc, | |||
| 5035 | ToAtFinallyStmt); | |||
| 5036 | } | |||
| 5037 | ||||
| 5038 | Stmt *ASTNodeImporter::VisitObjCAtTryStmt(ObjCAtTryStmt *S) { | |||
| 5039 | SourceLocation ToAtTryLoc = Importer.Import(S->getAtTryLoc()); | |||
| 5040 | Stmt *ToAtTryStmt = Importer.Import(S->getTryBody()); | |||
| 5041 | if (!ToAtTryStmt && S->getTryBody()) | |||
| 5042 | return nullptr; | |||
| 5043 | SmallVector<Stmt *, 1> ToCatchStmts(S->getNumCatchStmts()); | |||
| 5044 | for (unsigned CI = 0, CE = S->getNumCatchStmts(); CI != CE; ++CI) { | |||
| 5045 | ObjCAtCatchStmt *FromCatchStmt = S->getCatchStmt(CI); | |||
| 5046 | if (Stmt *ToCatchStmt = Importer.Import(FromCatchStmt)) | |||
| 5047 | ToCatchStmts[CI] = ToCatchStmt; | |||
| 5048 | else | |||
| 5049 | return nullptr; | |||
| 5050 | } | |||
| 5051 | Stmt *ToAtFinallyStmt = Importer.Import(S->getFinallyStmt()); | |||
| 5052 | if (!ToAtFinallyStmt && S->getFinallyStmt()) | |||
| 5053 | return nullptr; | |||
| 5054 | return ObjCAtTryStmt::Create(Importer.getToContext(), | |||
| 5055 | ToAtTryLoc, ToAtTryStmt, | |||
| 5056 | ToCatchStmts.begin(), ToCatchStmts.size(), | |||
| 5057 | ToAtFinallyStmt); | |||
| 5058 | } | |||
| 5059 | ||||
| 5060 | Stmt *ASTNodeImporter::VisitObjCAtSynchronizedStmt | |||
| 5061 | (ObjCAtSynchronizedStmt *S) { | |||
| 5062 | SourceLocation ToAtSynchronizedLoc = | |||
| 5063 | Importer.Import(S->getAtSynchronizedLoc()); | |||
| 5064 | Expr *ToSynchExpr = Importer.Import(S->getSynchExpr()); | |||
| 5065 | if (!ToSynchExpr && S->getSynchExpr()) | |||
| 5066 | return nullptr; | |||
| 5067 | Stmt *ToSynchBody = Importer.Import(S->getSynchBody()); | |||
| 5068 | if (!ToSynchBody && S->getSynchBody()) | |||
| 5069 | return nullptr; | |||
| 5070 | return new (Importer.getToContext()) ObjCAtSynchronizedStmt( | |||
| 5071 | ToAtSynchronizedLoc, ToSynchExpr, ToSynchBody); | |||
| 5072 | } | |||
| 5073 | ||||
| 5074 | Stmt *ASTNodeImporter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) { | |||
| 5075 | SourceLocation ToAtThrowLoc = Importer.Import(S->getThrowLoc()); | |||
| 5076 | Expr *ToThrow = Importer.Import(S->getThrowExpr()); | |||
| 5077 | if (!ToThrow && S->getThrowExpr()) | |||
| 5078 | return nullptr; | |||
| 5079 | return new (Importer.getToContext()) ObjCAtThrowStmt(ToAtThrowLoc, ToThrow); | |||
| 5080 | } | |||
| 5081 | ||||
| 5082 | Stmt *ASTNodeImporter::VisitObjCAutoreleasePoolStmt | |||
| 5083 | (ObjCAutoreleasePoolStmt *S) { | |||
| 5084 | SourceLocation ToAtLoc = Importer.Import(S->getAtLoc()); | |||
| 5085 | Stmt *ToSubStmt = Importer.Import(S->getSubStmt()); | |||
| 5086 | if (!ToSubStmt && S->getSubStmt()) | |||
| 5087 | return nullptr; | |||
| 5088 | return new (Importer.getToContext()) ObjCAutoreleasePoolStmt(ToAtLoc, | |||
| 5089 | ToSubStmt); | |||
| 5090 | } | |||
| 5091 | ||||
| 5092 | //---------------------------------------------------------------------------- | |||
| 5093 | // Import Expressions | |||
| 5094 | //---------------------------------------------------------------------------- | |||
| 5095 | Expr *ASTNodeImporter::VisitExpr(Expr *E) { | |||
| 5096 | Importer.FromDiag(E->getLocStart(), diag::err_unsupported_ast_node) | |||
| 5097 | << E->getStmtClassName(); | |||
| 5098 | return nullptr; | |||
| 5099 | } | |||
| 5100 | ||||
| 5101 | Expr *ASTNodeImporter::VisitVAArgExpr(VAArgExpr *E) { | |||
| 5102 | QualType T = Importer.Import(E->getType()); | |||
| 5103 | if (T.isNull()) | |||
| 5104 | return nullptr; | |||
| 5105 | ||||
| 5106 | Expr *SubExpr = Importer.Import(E->getSubExpr()); | |||
| 5107 | if (!SubExpr && E->getSubExpr()) | |||
| 5108 | return nullptr; | |||
| 5109 | ||||
| 5110 | TypeSourceInfo *TInfo = Importer.Import(E->getWrittenTypeInfo()); | |||
| 5111 | if (!TInfo) | |||
| 5112 | return nullptr; | |||
| 5113 | ||||
| 5114 | return new (Importer.getToContext()) VAArgExpr( | |||
| 5115 | Importer.Import(E->getBuiltinLoc()), SubExpr, TInfo, | |||
| 5116 | Importer.Import(E->getRParenLoc()), T, E->isMicrosoftABI()); | |||
| 5117 | } | |||
| 5118 | ||||
| 5119 | Expr *ASTNodeImporter::VisitGNUNullExpr(GNUNullExpr *E) { | |||
| 5120 | QualType T = Importer.Import(E->getType()); | |||
| 5121 | if (T.isNull()) | |||
| 5122 | return nullptr; | |||
| 5123 | ||||
| 5124 | return new (Importer.getToContext()) GNUNullExpr( | |||
| 5125 | T, Importer.Import(E->getLocStart())); | |||
| 5126 | } | |||
| 5127 | ||||
| 5128 | Expr *ASTNodeImporter::VisitPredefinedExpr(PredefinedExpr *E) { | |||
| 5129 | QualType T = Importer.Import(E->getType()); | |||
| 5130 | if (T.isNull()) | |||
| 5131 | return nullptr; | |||
| 5132 | ||||
| 5133 | auto *SL = cast_or_null<StringLiteral>(Importer.Import(E->getFunctionName())); | |||
| 5134 | if (!SL && E->getFunctionName()) | |||
| 5135 | return nullptr; | |||
| 5136 | ||||
| 5137 | return new (Importer.getToContext()) PredefinedExpr( | |||
| 5138 | Importer.Import(E->getLocStart()), T, E->getIdentType(), SL); | |||
| 5139 | } | |||
| 5140 | ||||
| 5141 | Expr *ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) { | |||
| 5142 | auto *ToD = cast_or_null<ValueDecl>(Importer.Import(E->getDecl())); | |||
| 5143 | if (!ToD) | |||
| 5144 | return nullptr; | |||
| 5145 | ||||
| 5146 | NamedDecl *FoundD = nullptr; | |||
| 5147 | if (E->getDecl() != E->getFoundDecl()) { | |||
| 5148 | FoundD = cast_or_null<NamedDecl>(Importer.Import(E->getFoundDecl())); | |||
| 5149 | if (!FoundD) | |||
| 5150 | return nullptr; | |||
| 5151 | } | |||
| 5152 | ||||
| 5153 | QualType T = Importer.Import(E->getType()); | |||
| 5154 | if (T.isNull()) | |||
| 5155 | return nullptr; | |||
| 5156 | ||||
| 5157 | TemplateArgumentListInfo ToTAInfo; | |||
| 5158 | TemplateArgumentListInfo *ResInfo = nullptr; | |||
| 5159 | if (E->hasExplicitTemplateArgs()) { | |||
| 5160 | if (ImportTemplateArgumentListInfo(E->template_arguments(), ToTAInfo)) | |||
| 5161 | return nullptr; | |||
| 5162 | ResInfo = &ToTAInfo; | |||
| 5163 | } | |||
| 5164 | ||||
| 5165 | DeclRefExpr *DRE = DeclRefExpr::Create(Importer.getToContext(), | |||
| 5166 | Importer.Import(E->getQualifierLoc()), | |||
| 5167 | Importer.Import(E->getTemplateKeywordLoc()), | |||
| 5168 | ToD, | |||
| 5169 | E->refersToEnclosingVariableOrCapture(), | |||
| 5170 | Importer.Import(E->getLocation()), | |||
| 5171 | T, E->getValueKind(), | |||
| 5172 | FoundD, ResInfo); | |||
| 5173 | if (E->hadMultipleCandidates()) | |||
| 5174 | DRE->setHadMultipleCandidates(true); | |||
| 5175 | return DRE; | |||
| 5176 | } | |||
| 5177 | ||||
| 5178 | Expr *ASTNodeImporter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) { | |||
| 5179 | QualType T = Importer.Import(E->getType()); | |||
| 5180 | if (T.isNull()) | |||
| 5181 | return nullptr; | |||
| 5182 | ||||
| 5183 | return new (Importer.getToContext()) ImplicitValueInitExpr(T); | |||
| 5184 | } | |||
| 5185 | ||||
| 5186 | ASTNodeImporter::Designator | |||
| 5187 | ASTNodeImporter::ImportDesignator(const Designator &D) { | |||
| 5188 | if (D.isFieldDesignator()) { | |||
| 5189 | IdentifierInfo *ToFieldName = Importer.Import(D.getFieldName()); | |||
| 5190 | // Caller checks for import error | |||
| 5191 | return Designator(ToFieldName, Importer.Import(D.getDotLoc()), | |||
| 5192 | Importer.Import(D.getFieldLoc())); | |||
| 5193 | } | |||
| 5194 | if (D.isArrayDesignator()) | |||
| 5195 | return Designator(D.getFirstExprIndex(), | |||
| 5196 | Importer.Import(D.getLBracketLoc()), | |||
| 5197 | Importer.Import(D.getRBracketLoc())); | |||
| 5198 | ||||
| 5199 | assert(D.isArrayRangeDesignator())(static_cast <bool> (D.isArrayRangeDesignator()) ? void (0) : __assert_fail ("D.isArrayRangeDesignator()", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/lib/AST/ASTImporter.cpp" , 5199, __extension__ __PRETTY_FUNCTION__)); | |||
| 5200 | return Designator(D.getFirstExprIndex(), | |||
| 5201 | Importer.Import(D.getLBracketLoc()), | |||
| 5202 | Importer.Import(D.getEllipsisLoc()), | |||
| 5203 | Importer.Import(D.getRBracketLoc())); | |||
| 5204 | } | |||
| 5205 | ||||
| 5206 | ||||
| 5207 | Expr *ASTNodeImporter::VisitDesignatedInitExpr(DesignatedInitExpr *DIE) { | |||
| 5208 | auto *Init = cast_or_null<Expr>(Importer.Import(DIE->getInit())); | |||
| 5209 | if (!Init) | |||
| 5210 | return nullptr; | |||
| 5211 | ||||
| 5212 | SmallVector<Expr *, 4> IndexExprs(DIE->getNumSubExprs() - 1); | |||
| 5213 | // List elements from the second, the first is Init itself | |||
| 5214 | for (unsigned I = 1, E = DIE->getNumSubExprs(); I < E; I++) { | |||
| 5215 | if (auto *Arg = cast_or_null<Expr>(Importer.Import(DIE->getSubExpr(I)))) | |||
| 5216 | IndexExprs[I - 1] = Arg; | |||
| 5217 | else | |||
| 5218 | return nullptr; | |||
| 5219 | } | |||
| 5220 | ||||
| 5221 | SmallVector<Designator, 4> Designators(DIE->size()); | |||
| 5222 | llvm::transform(DIE->designators(), Designators.begin(), | |||
| 5223 | [this](const Designator &D) -> Designator { | |||
| 5224 | return ImportDesignator(D); | |||
| 5225 | }); | |||
| 5226 | ||||
| 5227 | for (const auto &D : DIE->designators()) | |||
| 5228 | if (D.isFieldDesignator() && !D.getFieldName()) | |||
| 5229 | return nullptr; | |||
| 5230 | ||||
| 5231 | return DesignatedInitExpr::Create( | |||
| 5232 | Importer.getToContext(), Designators, | |||
| 5233 | IndexExprs, Importer.Import(DIE->getEqualOrColonLoc()), | |||
| 5234 | DIE->usesGNUSyntax(), Init); | |||
| 5235 | } | |||
| 5236 | ||||
| 5237 | Expr *ASTNodeImporter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) { | |||
| 5238 | QualType T = Importer.Import(E->getType()); | |||
| 5239 | if (T.isNull()) | |||
| 5240 | return nullptr; | |||
| 5241 | ||||
| 5242 | return new (Importer.getToContext()) | |||
| 5243 | CXXNullPtrLiteralExpr(T, Importer.Import(E->getLocation())); | |||
| 5244 | } | |||
| 5245 | ||||
| 5246 | Expr *ASTNodeImporter::VisitIntegerLiteral(IntegerLiteral *E) { | |||
| 5247 | QualType T = Importer.Import(E->getType()); | |||
| 5248 | if (T.isNull()) | |||
| 5249 | return nullptr; | |||
| 5250 | ||||
| 5251 | return IntegerLiteral::Create(Importer.getToContext(), | |||
| 5252 | E->getValue(), T, | |||
| 5253 | Importer.Import(E->getLocation())); | |||
| 5254 | } | |||
| 5255 | ||||
| 5256 | Expr *ASTNodeImporter::VisitFloatingLiteral(FloatingLiteral *E) { | |||
| 5257 | QualType T = Importer.Import(E->getType()); | |||
| 5258 | if (T.isNull()) | |||
| 5259 | return nullptr; | |||
| 5260 | ||||
| 5261 | return FloatingLiteral::Create(Importer.getToContext(), | |||
| 5262 | E->getValue(), E->isExact(), T, | |||
| 5263 | Importer.Import(E->getLocation())); | |||
| 5264 | } | |||
| 5265 | ||||
| 5266 | Expr *ASTNodeImporter::VisitCharacterLiteral(CharacterLiteral *E) { | |||
| 5267 | QualType T = Importer.Import(E->getType()); | |||
| 5268 | if (T.isNull()) | |||
| 5269 | return nullptr; | |||
| 5270 | ||||
| 5271 | return new (Importer.getToContext()) CharacterLiteral(E->getValue(), | |||
| 5272 | E->getKind(), T, | |||
| 5273 | Importer.Import(E->getLocation())); | |||
| 5274 | } | |||
| 5275 | ||||
| 5276 | Expr *ASTNodeImporter::VisitStringLiteral(StringLiteral *E) { | |||
| 5277 | QualType T = Importer.Import(E->getType()); | |||
| 5278 | if (T.isNull()) | |||
| 5279 | return nullptr; | |||
| 5280 | ||||
| 5281 | SmallVector<SourceLocation, 4> Locations(E->getNumConcatenated()); | |||
| 5282 | ImportArray(E->tokloc_begin(), E->tokloc_end(), Locations.begin()); | |||
| 5283 | ||||
| 5284 | return StringLiteral::Create(Importer.getToContext(), E->getBytes(), | |||
| 5285 | E->getKind(), E->isPascal(), T, | |||
| 5286 | Locations.data(), Locations.size()); | |||
| 5287 | } | |||
| 5288 | ||||
| 5289 | Expr *ASTNodeImporter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) { | |||
| 5290 | QualType T = Importer.Import(E->getType()); | |||
| 5291 | if (T.isNull()) | |||
| 5292 | return nullptr; | |||
| 5293 | ||||
| 5294 | TypeSourceInfo *TInfo = Importer.Import(E->getTypeSourceInfo()); | |||
| 5295 | if (!TInfo) | |||
| 5296 | return nullptr; | |||
| 5297 | ||||
| 5298 | Expr *Init = Importer.Import(E->getInitializer()); | |||
| 5299 | if (!Init) | |||
| 5300 | return nullptr; | |||
| 5301 | ||||
| 5302 | return new (Importer.getToContext()) CompoundLiteralExpr( | |||
| 5303 | Importer.Import(E->getLParenLoc()), TInfo, T, E->getValueKind(), | |||
| 5304 | Init, E->isFileScope()); | |||
| 5305 | } | |||
| 5306 | ||||
| 5307 | Expr *ASTNodeImporter::VisitAtomicExpr(AtomicExpr *E) { | |||
| 5308 | QualType T = Importer.Import(E->getType()); | |||
| 5309 | if (T.isNull()) | |||
| 5310 | return nullptr; | |||
| 5311 | ||||
| 5312 | SmallVector<Expr *, 6> Exprs(E->getNumSubExprs()); | |||
| 5313 | if (ImportArrayChecked( | |||
| 5314 | E->getSubExprs(), E->getSubExprs() + E->getNumSubExprs(), | |||
| 5315 | Exprs.begin())) | |||
| 5316 | return nullptr; | |||
| 5317 | ||||
| 5318 | return new (Importer.getToContext()) AtomicExpr( | |||
| 5319 | Importer.Import(E->getBuiltinLoc()), Exprs, T, E->getOp(), | |||
| 5320 | Importer.Import(E->getRParenLoc())); | |||
| 5321 | } | |||
| 5322 | ||||
| 5323 | Expr *ASTNodeImporter::VisitAddrLabelExpr(AddrLabelExpr *E) { | |||
| 5324 | QualType T = Importer.Import(E->getType()); | |||
| 5325 | if (T.isNull()) | |||
| 5326 | return nullptr; | |||
| 5327 | ||||
| 5328 | auto *ToLabel = cast_or_null<LabelDecl>(Importer.Import(E->getLabel())); | |||
| 5329 | if (!ToLabel) | |||
| 5330 | return nullptr; | |||
| 5331 | ||||
| 5332 | return new (Importer.getToContext()) AddrLabelExpr( | |||
| 5333 | Importer.Import(E->getAmpAmpLoc()), Importer.Import(E->getLabelLoc()), | |||
| 5334 | ToLabel, T); | |||
| 5335 | } | |||
| 5336 | ||||
| 5337 | Expr *ASTNodeImporter::VisitParenExpr(ParenExpr *E) { | |||
| 5338 | Expr *SubExpr = Importer.Import(E->getSubExpr()); | |||
| 5339 | if (!SubExpr) | |||
| 5340 | return nullptr; | |||
| 5341 | ||||
| 5342 | return new (Importer.getToContext()) | |||
| 5343 | ParenExpr(Importer.Import(E->getLParen()), | |||
| 5344 | Importer.Import(E->getRParen()), | |||
| 5345 | SubExpr); | |||
| 5346 | } | |||
| 5347 | ||||
| 5348 | Expr *ASTNodeImporter::VisitParenListExpr(ParenListExpr *E) { | |||
| 5349 | SmallVector<Expr *, 4> Exprs(E->getNumExprs()); | |||
| 5350 | if (ImportContainerChecked(E->exprs(), Exprs)) | |||
| 5351 | return nullptr; | |||
| 5352 | ||||
| 5353 | return new (Importer.getToContext()) ParenListExpr( | |||
| 5354 | Importer.getToContext(), Importer.Import(E->getLParenLoc()), | |||
| 5355 | Exprs, Importer.Import(E->getLParenLoc())); | |||
| 5356 | } | |||
| 5357 | ||||
| 5358 | Expr *ASTNodeImporter::VisitStmtExpr(StmtExpr *E) { | |||
| 5359 | QualType T = Importer.Import(E->getType()); | |||
| 5360 | if (T.isNull()) | |||
| 5361 | return nullptr; | |||
| 5362 | ||||
| 5363 | auto *ToSubStmt = cast_or_null<CompoundStmt>( | |||
| 5364 | Importer.Import(E->getSubStmt())); | |||
| 5365 | if (!ToSubStmt && E->getSubStmt()) | |||
| 5366 | return nullptr; | |||
| 5367 | ||||
| 5368 | return new (Importer.getToContext()) StmtExpr(ToSubStmt, T, | |||
| 5369 | Importer.Import(E->getLParenLoc()), Importer.Import(E->getRParenLoc())); | |||
| 5370 | } | |||
| 5371 | ||||
| 5372 | Expr *ASTNodeImporter::VisitUnaryOperator(UnaryOperator *E) { | |||
| 5373 | QualType T = Importer.Import(E->getType()); | |||
| 5374 | if (T.isNull()) | |||
| 5375 | return nullptr; | |||
| 5376 | ||||
| 5377 | Expr *SubExpr = Importer.Import(E->getSubExpr()); | |||
| 5378 | if (!SubExpr) | |||
| 5379 | return nullptr; | |||
| 5380 | ||||
| 5381 | return new (Importer.getToContext()) UnaryOperator( | |||
| 5382 | SubExpr, E->getOpcode(), T, E->getValueKind(), E->getObjectKind(), | |||
| 5383 | Importer.Import(E->getOperatorLoc()), E->canOverflow()); | |||
| 5384 | } | |||
| 5385 | ||||
| 5386 | Expr * | |||
| 5387 | ASTNodeImporter::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) { | |||
| 5388 | QualType ResultType = Importer.Import(E->getType()); | |||
| 5389 | ||||
| 5390 | if (E->isArgumentType()) { | |||
| 5391 | TypeSourceInfo *TInfo = Importer.Import(E->getArgumentTypeInfo()); | |||
| 5392 | if (!TInfo) | |||
| 5393 | return nullptr; | |||
| 5394 | ||||
| 5395 | return new (Importer.getToContext()) UnaryExprOrTypeTraitExpr(E->getKind(), | |||
| 5396 | TInfo, ResultType, | |||
| 5397 | Importer.Import(E->getOperatorLoc()), | |||
| 5398 | Importer.Import(E->getRParenLoc())); | |||
| 5399 | } | |||
| 5400 | ||||
| 5401 | Expr *SubExpr = Importer.Import(E->getArgumentExpr()); | |||
| 5402 | if (!SubExpr) | |||
| 5403 | return nullptr; | |||
| 5404 | ||||
| 5405 | return new (Importer.getToContext()) UnaryExprOrTypeTraitExpr(E->getKind(), | |||
| 5406 | SubExpr, ResultType, | |||
| 5407 | Importer.Import(E->getOperatorLoc()), | |||
| 5408 | Importer.Import(E->getRParenLoc())); | |||
| 5409 | } | |||
| 5410 | ||||
| 5411 | Expr *ASTNodeImporter::VisitBinaryOperator(BinaryOperator *E) { | |||
| 5412 | QualType T = Importer.Import(E->getType()); | |||
| 5413 | if (T.isNull()) | |||
| 5414 | return nullptr; | |||
| 5415 | ||||
| 5416 | Expr *LHS = Importer.Import(E->getLHS()); | |||
| 5417 | if (!LHS) | |||
| 5418 | return nullptr; | |||
| 5419 | ||||
| 5420 | Expr *RHS = Importer.Import(E->getRHS()); | |||
| 5421 | if (!RHS) | |||
| 5422 | return nullptr; | |||
| 5423 | ||||
| 5424 | return new (Importer.getToContext()) BinaryOperator(LHS, RHS, E->getOpcode(), | |||
| 5425 | T, E->getValueKind(), | |||
| 5426 | E->getObjectKind(), | |||
| 5427 | Importer.Import(E->getOperatorLoc()), | |||
| 5428 | E->getFPFeatures()); | |||
| 5429 | } | |||
| 5430 | ||||
| 5431 | Expr *ASTNodeImporter::VisitConditionalOperator(ConditionalOperator *E) { | |||
| 5432 | QualType T = Importer.Import(E->getType()); | |||
| 5433 | if (T.isNull()) | |||
| 5434 | return nullptr; | |||
| 5435 | ||||
| 5436 | Expr *ToLHS = Importer.Import(E->getLHS()); | |||
| 5437 | if (!ToLHS) | |||
| 5438 | return nullptr; | |||
| 5439 | ||||
| 5440 | Expr *ToRHS = Importer.Import(E->getRHS()); | |||
| 5441 | if (!ToRHS) | |||
| 5442 | return nullptr; | |||
| 5443 | ||||
| 5444 | Expr *ToCond = Importer.Import(E->getCond()); | |||
| 5445 | if (!ToCond) | |||
| 5446 | return nullptr; | |||
| 5447 | ||||
| 5448 | return new (Importer.getToContext()) ConditionalOperator( | |||
| 5449 | ToCond, Importer.Import(E->getQuestionLoc()), | |||
| 5450 | ToLHS, Importer.Import(E->getColonLoc()), | |||
| 5451 | ToRHS, T, E->getValueKind(), E->getObjectKind()); | |||
| 5452 | } | |||
| 5453 | ||||
| 5454 | Expr *ASTNodeImporter::VisitBinaryConditionalOperator( | |||
| 5455 | BinaryConditionalOperator *E) { | |||
| 5456 | QualType T = Importer.Import(E->getType()); | |||
| 5457 | if (T.isNull()) | |||
| 5458 | return nullptr; | |||
| 5459 | ||||
| 5460 | Expr *Common = Importer.Import(E->getCommon()); | |||
| 5461 | if (!Common) | |||
| 5462 | return nullptr; | |||
| 5463 | ||||
| 5464 | Expr *Cond = Importer.Import(E->getCond()); | |||
| 5465 | if (!Cond) | |||
| 5466 | return nullptr; | |||
| 5467 | ||||
| 5468 | auto *OpaqueValue = cast_or_null<OpaqueValueExpr>( | |||
| 5469 | Importer.Import(E->getOpaqueValue())); | |||
| 5470 | if (!OpaqueValue) | |||
| 5471 | return nullptr; | |||
| 5472 | ||||
| 5473 | Expr *TrueExpr = Importer.Import(E->getTrueExpr()); | |||
| 5474 | if (!TrueExpr) | |||
| 5475 | return nullptr; | |||
| 5476 | ||||
| 5477 | Expr *FalseExpr = Importer.Import(E->getFalseExpr()); | |||
| 5478 | if (!FalseExpr) | |||
| 5479 | return nullptr; | |||
| 5480 | ||||
| 5481 | return new (Importer.getToContext()) BinaryConditionalOperator( | |||
| 5482 | Common, OpaqueValue, Cond, TrueExpr, FalseExpr, | |||
| 5483 | Importer.Import(E->getQuestionLoc()), Importer.Import(E->getColonLoc()), | |||
| 5484 | T, E->getValueKind(), E->getObjectKind()); | |||
| 5485 | } | |||
| 5486 | ||||
| 5487 | Expr *ASTNodeImporter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) { | |||
| 5488 | QualType T = Importer.Import(E->getType()); | |||
| 5489 | if (T.isNull()) | |||
| 5490 | return nullptr; | |||
| 5491 | ||||
| 5492 | TypeSourceInfo *ToQueried = Importer.Import(E->getQueriedTypeSourceInfo()); | |||
| 5493 | if (!ToQueried) | |||
| 5494 | return nullptr; | |||
| 5495 | ||||
| 5496 | Expr *Dim = Importer.Import(E->getDimensionExpression()); | |||
| 5497 | if (!Dim && E->getDimensionExpression()) | |||
| 5498 | return nullptr; | |||
| 5499 | ||||
| 5500 | return new (Importer.getToContext()) ArrayTypeTraitExpr( | |||
| 5501 | Importer.Import(E->getLocStart()), E->getTrait(), ToQueried, | |||
| 5502 | E->getValue(), Dim, Importer.Import(E->getLocEnd()), T); | |||
| 5503 | } | |||
| 5504 | ||||
| 5505 | Expr *ASTNodeImporter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) { | |||
| 5506 | QualType T = Importer.Import(E->getType()); | |||
| 5507 | if (T.isNull()) | |||
| 5508 | return nullptr; | |||
| 5509 | ||||
| 5510 | Expr *ToQueried = Importer.Import(E->getQueriedExpression()); | |||
| 5511 | if (!ToQueried) | |||
| 5512 | return nullptr; | |||
| 5513 | ||||
| 5514 | return new (Importer.getToContext()) ExpressionTraitExpr( | |||
| 5515 | Importer.Import(E->getLocStart()), E->getTrait(), ToQueried, | |||
| 5516 | E->getValue(), Importer.Import(E->getLocEnd()), T); | |||
| 5517 | } | |||
| 5518 | ||||
| 5519 | Expr *ASTNodeImporter::VisitOpaqueValueExpr(OpaqueValueExpr *E) { | |||
| 5520 | QualType T = Importer.Import(E->getType()); | |||
| 5521 | if (T.isNull()) | |||
| 5522 | return nullptr; | |||
| 5523 | ||||
| 5524 | Expr *SourceExpr = Importer.Import(E->getSourceExpr()); | |||
| 5525 | if (!SourceExpr && E->getSourceExpr()) | |||
| 5526 | return nullptr; | |||
| 5527 | ||||
| 5528 | return new (Importer.getToContext()) OpaqueValueExpr( | |||
| 5529 | Importer.Import(E->getLocation()), T, E->getValueKind(), | |||
| 5530 | E->getObjectKind(), SourceExpr); | |||
| 5531 | } | |||
| 5532 | ||||
| 5533 | Expr *ASTNodeImporter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) { | |||
| 5534 | QualType T = Importer.Import(E->getType()); | |||
| 5535 | if (T.isNull()) | |||
| 5536 | return nullptr; | |||
| 5537 | ||||
| 5538 | Expr *ToLHS = Importer.Import(E->getLHS()); | |||
| 5539 | if (!ToLHS) | |||
| 5540 | return nullptr; | |||
| 5541 | ||||
| 5542 | Expr *ToRHS = Importer.Import(E->getRHS()); | |||
| 5543 | if (!ToRHS) | |||
| 5544 | return nullptr; | |||
| 5545 | ||||
| 5546 | return new (Importer.getToContext()) ArraySubscriptExpr( | |||
| 5547 | ToLHS, ToRHS, T, E->getValueKind(), E->getObjectKind(), | |||
| 5548 | Importer.Import(E->getRBracketLoc())); | |||
| 5549 | } | |||
| 5550 | ||||
| 5551 | Expr *ASTNodeImporter::VisitCompoundAssignOperator(CompoundAssignOperator *E) { | |||
| 5552 | QualType T = Importer.Import(E->getType()); | |||
| 5553 | if (T.isNull()) | |||
| 5554 | return nullptr; | |||
| 5555 | ||||
| 5556 | QualType CompLHSType = Importer.Import(E->getComputationLHSType()); | |||
| 5557 | if (CompLHSType.isNull()) | |||
| 5558 | return nullptr; | |||
| 5559 | ||||
| 5560 | QualType CompResultType = Importer.Import(E->getComputationResultType()); | |||
| 5561 | if (CompResultType.isNull()) | |||
| 5562 | return nullptr; | |||
| 5563 | ||||
| 5564 | Expr *LHS = Importer.Import(E->getLHS()); | |||
| 5565 | if (!LHS) | |||
| 5566 | return nullptr; | |||
| 5567 | ||||
| 5568 | Expr *RHS = Importer.Import(E->getRHS()); | |||
| 5569 | if (!RHS) | |||
| 5570 | return nullptr; | |||
| 5571 | ||||
| 5572 | return new (Importer.getToContext()) | |||
| 5573 | CompoundAssignOperator(LHS, RHS, E->getOpcode(), | |||
| 5574 | T, E->getValueKind(), | |||
| 5575 | E->getObjectKind(), | |||
| 5576 | CompLHSType, CompResultType, | |||
| 5577 | Importer.Import(E->getOperatorLoc()), | |||
| 5578 | E->getFPFeatures()); | |||
| 5579 | } | |||
| 5580 | ||||
| 5581 | bool ASTNodeImporter::ImportCastPath(CastExpr *CE, CXXCastPath &Path) { | |||
| 5582 | for (auto I = CE->path_begin(), E = CE->path_end(); I != E; ++I) { | |||
| 5583 | if (CXXBaseSpecifier *Spec = Importer.Import(*I)) | |||
| 5584 | Path.push_back(Spec); | |||
| 5585 | else | |||
| 5586 | return true; | |||
| 5587 | } | |||
| 5588 | return false; | |||
| 5589 | } | |||
| 5590 | ||||
| 5591 | Expr *ASTNodeImporter::VisitImplicitCastExpr(ImplicitCastExpr *E) { | |||
| 5592 | QualType T = Importer.Import(E->getType()); | |||
| 5593 | if (T.isNull()) | |||
| 5594 | return nullptr; | |||
| 5595 | ||||
| 5596 | Expr *SubExpr = Importer.Import(E->getSubExpr()); | |||
| 5597 | if (!SubExpr) | |||
| 5598 | return nullptr; | |||
| 5599 | ||||
| 5600 | CXXCastPath BasePath; | |||
| 5601 | if (ImportCastPath(E, BasePath)) | |||
| 5602 | return nullptr; | |||
| 5603 | ||||
| 5604 | return ImplicitCastExpr::Create(Importer.getToContext(), T, E->getCastKind(), | |||
| 5605 | SubExpr, &BasePath, E->getValueKind()); | |||
| 5606 | } | |||
| 5607 | ||||
| 5608 | Expr *ASTNodeImporter::VisitExplicitCastExpr(ExplicitCastExpr *E) { | |||
| 5609 | QualType T = Importer.Import(E->getType()); | |||
| 5610 | if (T.isNull()) | |||
| 5611 | return nullptr; | |||
| 5612 | ||||
| 5613 | Expr *SubExpr = Importer.Import(E->getSubExpr()); | |||
| 5614 | if (!SubExpr) | |||
| 5615 | return nullptr; | |||
| 5616 | ||||
| 5617 | TypeSourceInfo *TInfo = Importer.Import(E->getTypeInfoAsWritten()); | |||
| 5618 | if (!TInfo && E->getTypeInfoAsWritten()) | |||
| 5619 | return nullptr; | |||
| 5620 | ||||
| 5621 | CXXCastPath BasePath; | |||
| 5622 | if (ImportCastPath(E, BasePath)) | |||
| 5623 | return nullptr; | |||
| 5624 | ||||
| 5625 | switch (E->getStmtClass()) { | |||
| 5626 | case Stmt::CStyleCastExprClass: { | |||
| 5627 | auto *CCE = cast<CStyleCastExpr>(E); | |||
| 5628 | return CStyleCastExpr::Create(Importer.getToContext(), T, | |||
| 5629 | E->getValueKind(), E->getCastKind(), | |||
| 5630 | SubExpr, &BasePath, TInfo, | |||
| 5631 | Importer.Import(CCE->getLParenLoc()), | |||
| 5632 | Importer.Import(CCE->getRParenLoc())); | |||
| 5633 | } | |||
| 5634 | ||||
| 5635 | case Stmt::CXXFunctionalCastExprClass: { | |||
| 5636 | auto *FCE = cast<CXXFunctionalCastExpr>(E); | |||
| 5637 | return CXXFunctionalCastExpr::Create(Importer.getToContext(), T, | |||
| 5638 | E->getValueKind(), TInfo, | |||
| 5639 | E->getCastKind(), SubExpr, &BasePath, | |||
| 5640 | Importer.Import(FCE->getLParenLoc()), | |||
| 5641 | Importer.Import(FCE->getRParenLoc())); | |||
| 5642 | } | |||
| 5643 | ||||
| 5644 | case Stmt::ObjCBridgedCastExprClass: { | |||
| 5645 | auto *OCE = cast<ObjCBridgedCastExpr>(E); | |||
| 5646 | return new (Importer.getToContext()) ObjCBridgedCastExpr( | |||
| 5647 | Importer.Import(OCE->getLParenLoc()), OCE->getBridgeKind(), | |||
| 5648 | E->getCastKind(), Importer.Import(OCE->getBridgeKeywordLoc()), | |||
| 5649 | TInfo, SubExpr); | |||
| 5650 | } | |||
| 5651 | default: | |||
| 5652 | break; // just fall through | |||
| 5653 | } | |||
| 5654 | ||||
| 5655 | auto *Named = cast<CXXNamedCastExpr>(E); | |||
| 5656 | SourceLocation ExprLoc = Importer.Import(Named->getOperatorLoc()), | |||
| 5657 | RParenLoc = Importer.Import(Named->getRParenLoc()); | |||
| 5658 | SourceRange Brackets = Importer.Import(Named->getAngleBrackets()); | |||
| 5659 | ||||
| 5660 | switch (E->getStmtClass()) { | |||
| 5661 | case Stmt::CXXStaticCastExprClass: | |||
| 5662 | return CXXStaticCastExpr::Create(Importer.getToContext(), T, | |||
| 5663 | E->getValueKind(), E->getCastKind(), | |||
| 5664 | SubExpr, &BasePath, TInfo, | |||
| 5665 | ExprLoc, RParenLoc, Brackets); | |||
| 5666 | ||||
| 5667 | case Stmt::CXXDynamicCastExprClass: | |||
| 5668 | return CXXDynamicCastExpr::Create(Importer.getToContext(), T, | |||
| 5669 | E->getValueKind(), E->getCastKind(), | |||
| 5670 | SubExpr, &BasePath, TInfo, | |||
| 5671 | ExprLoc, RParenLoc, Brackets); | |||
| 5672 | ||||
| 5673 | case Stmt::CXXReinterpretCastExprClass: | |||
| 5674 | return CXXReinterpretCastExpr::Create(Importer.getToContext(), T, | |||
| 5675 | E->getValueKind(), E->getCastKind(), | |||
| 5676 | SubExpr, &BasePath, TInfo, | |||
| 5677 | ExprLoc, RParenLoc, Brackets); | |||
| 5678 | ||||
| 5679 | case Stmt::CXXConstCastExprClass: | |||
| 5680 | return CXXConstCastExpr::Create(Importer.getToContext(), T, | |||
| 5681 | E->getValueKind(), SubExpr, TInfo, ExprLoc, | |||
| 5682 | RParenLoc, Brackets); | |||
| 5683 | default: | |||
| 5684 | llvm_unreachable("Cast expression of unsupported type!")::llvm::llvm_unreachable_internal("Cast expression of unsupported type!" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/lib/AST/ASTImporter.cpp" , 5684); | |||
| 5685 | return nullptr; | |||
| 5686 | } | |||
| 5687 | } | |||
| 5688 | ||||
| 5689 | Expr *ASTNodeImporter::VisitOffsetOfExpr(OffsetOfExpr *OE) { | |||
| 5690 | QualType T = Importer.Import(OE->getType()); | |||
| 5691 | if (T.isNull()) | |||
| 5692 | return nullptr; | |||
| 5693 | ||||
| 5694 | SmallVector<OffsetOfNode, 4> Nodes; | |||
| 5695 | for (int I = 0, E = OE->getNumComponents(); I < E; ++I) { | |||
| 5696 | const OffsetOfNode &Node = OE->getComponent(I); | |||
| 5697 | ||||
| 5698 | switch (Node.getKind()) { | |||
| 5699 | case OffsetOfNode::Array: | |||
| 5700 | Nodes.push_back(OffsetOfNode(Importer.Import(Node.getLocStart()), | |||
| 5701 | Node.getArrayExprIndex(), | |||
| 5702 | Importer.Import(Node.getLocEnd()))); | |||
| 5703 | break; | |||
| 5704 | ||||
| 5705 | case OffsetOfNode::Base: { | |||
| 5706 | CXXBaseSpecifier *BS = Importer.Import(Node.getBase()); | |||
| 5707 | if (!BS && Node.getBase()) | |||
| 5708 | return nullptr; | |||
| 5709 | Nodes.push_back(OffsetOfNode(BS)); | |||
| 5710 | break; | |||
| 5711 | } | |||
| 5712 | case OffsetOfNode::Field: { | |||
| 5713 | auto *FD = cast_or_null<FieldDecl>(Importer.Import(Node.getField())); | |||
| 5714 | if (!FD) | |||
| 5715 | return nullptr; | |||
| 5716 | Nodes.push_back(OffsetOfNode(Importer.Import(Node.getLocStart()), FD, | |||
| 5717 | Importer.Import(Node.getLocEnd()))); | |||
| 5718 | break; | |||
| 5719 | } | |||
| 5720 | case OffsetOfNode::Identifier: { | |||
| 5721 | IdentifierInfo *ToII = Importer.Import(Node.getFieldName()); | |||
| 5722 | if (!ToII) | |||
| 5723 | return nullptr; | |||
| 5724 | Nodes.push_back(OffsetOfNode(Importer.Import(Node.getLocStart()), ToII, | |||
| 5725 | Importer.Import(Node.getLocEnd()))); | |||
| 5726 | break; | |||
| 5727 | } | |||
| 5728 | } | |||
| 5729 | } | |||
| 5730 | ||||
| 5731 | SmallVector<Expr *, 4> Exprs(OE->getNumExpressions()); | |||
| 5732 | for (int I = 0, E = OE->getNumExpressions(); I < E; ++I) { | |||
| 5733 | Expr *ToIndexExpr = Importer.Import(OE->getIndexExpr(I)); | |||
| 5734 | if (!ToIndexExpr) | |||
| 5735 | return nullptr; | |||
| 5736 | Exprs[I] = ToIndexExpr; | |||
| 5737 | } | |||
| 5738 | ||||
| 5739 | TypeSourceInfo *TInfo = Importer.Import(OE->getTypeSourceInfo()); | |||
| 5740 | if (!TInfo && OE->getTypeSourceInfo()) | |||
| 5741 | return nullptr; | |||
| 5742 | ||||
| 5743 | return OffsetOfExpr::Create(Importer.getToContext(), T, | |||
| 5744 | Importer.Import(OE->getOperatorLoc()), | |||
| 5745 | TInfo, Nodes, Exprs, | |||
| 5746 | Importer.Import(OE->getRParenLoc())); | |||
| 5747 | } | |||
| 5748 | ||||
| 5749 | Expr *ASTNodeImporter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) { | |||
| 5750 | QualType T = Importer.Import(E->getType()); | |||
| 5751 | if (T.isNull()) | |||
| 5752 | return nullptr; | |||
| 5753 | ||||
| 5754 | Expr *Operand = Importer.Import(E->getOperand()); | |||
| 5755 | if (!Operand) | |||
| 5756 | return nullptr; | |||
| 5757 | ||||
| 5758 | CanThrowResult CanThrow; | |||
| 5759 | if (E->isValueDependent()) | |||
| 5760 | CanThrow = CT_Dependent; | |||
| 5761 | else | |||
| 5762 | CanThrow = E->getValue() ? CT_Can : CT_Cannot; | |||
| 5763 | ||||
| 5764 | return new (Importer.getToContext()) CXXNoexceptExpr( | |||
| 5765 | T, Operand, CanThrow, | |||
| 5766 | Importer.Import(E->getLocStart()), Importer.Import(E->getLocEnd())); | |||
| 5767 | } | |||
| 5768 | ||||
| 5769 | Expr *ASTNodeImporter::VisitCXXThrowExpr(CXXThrowExpr *E) { | |||
| 5770 | QualType T = Importer.Import(E->getType()); | |||
| 5771 | if (T.isNull()) | |||
| 5772 | return nullptr; | |||
| 5773 | ||||
| 5774 | Expr *SubExpr = Importer.Import(E->getSubExpr()); | |||
| 5775 | if (!SubExpr && E->getSubExpr()) | |||
| 5776 | return nullptr; | |||
| 5777 | ||||
| 5778 | return new (Importer.getToContext()) CXXThrowExpr( | |||
| 5779 | SubExpr, T, Importer.Import(E->getThrowLoc()), | |||
| 5780 | E->isThrownVariableInScope()); | |||
| 5781 | } | |||
| 5782 | ||||
| 5783 | Expr *ASTNodeImporter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { | |||
| 5784 | auto *Param = cast_or_null<ParmVarDecl>(Importer.Import(E->getParam())); | |||
| 5785 | if (!Param) | |||
| 5786 | return nullptr; | |||
| 5787 | ||||
| 5788 | return CXXDefaultArgExpr::Create( | |||
| 5789 | Importer.getToContext(), Importer.Import(E->getUsedLocation()), Param); | |||
| 5790 | } | |||
| 5791 | ||||
| 5792 | Expr *ASTNodeImporter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) { | |||
| 5793 | QualType T = Importer.Import(E->getType()); | |||
| 5794 | if (T.isNull()) | |||
| 5795 | return nullptr; | |||
| 5796 | ||||
| 5797 | TypeSourceInfo *TypeInfo = Importer.Import(E->getTypeSourceInfo()); | |||
| 5798 | if (!TypeInfo) | |||
| 5799 | return nullptr; | |||
| 5800 | ||||
| 5801 | return new (Importer.getToContext()) CXXScalarValueInitExpr( | |||
| 5802 | T, TypeInfo, Importer.Import(E->getRParenLoc())); | |||
| 5803 | } | |||
| 5804 | ||||
| 5805 | Expr *ASTNodeImporter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) { | |||
| 5806 | Expr *SubExpr = Importer.Import(E->getSubExpr()); | |||
| 5807 | if (!SubExpr) | |||
| 5808 | return nullptr; | |||
| 5809 | ||||
| 5810 | auto *Dtor = cast_or_null<CXXDestructorDecl>( | |||
| 5811 | Importer.Import(const_cast<CXXDestructorDecl *>( | |||
| 5812 | E->getTemporary()->getDestructor()))); | |||
| 5813 | if (!Dtor) | |||
| 5814 | return nullptr; | |||
| 5815 | ||||
| 5816 | ASTContext &ToCtx = Importer.getToContext(); | |||
| 5817 | CXXTemporary *Temp = CXXTemporary::Create(ToCtx, Dtor); | |||
| 5818 | return CXXBindTemporaryExpr::Create(ToCtx, Temp, SubExpr); | |||
| 5819 | } | |||
| 5820 | ||||
| 5821 | Expr *ASTNodeImporter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *CE) { | |||
| 5822 | QualType T = Importer.Import(CE->getType()); | |||
| 5823 | if (T.isNull()) | |||
| 5824 | return nullptr; | |||
| 5825 | ||||
| 5826 | TypeSourceInfo *TInfo = Importer.Import(CE->getTypeSourceInfo()); | |||
| 5827 | if (!TInfo) | |||
| 5828 | return nullptr; | |||
| 5829 | ||||
| 5830 | SmallVector<Expr *, 8> Args(CE->getNumArgs()); | |||
| 5831 | if (ImportContainerChecked(CE->arguments(), Args)) | |||
| 5832 | return nullptr; | |||
| 5833 | ||||
| 5834 | auto *Ctor = cast_or_null<CXXConstructorDecl>( | |||
| 5835 | Importer.Import(CE->getConstructor())); | |||
| 5836 | if (!Ctor) | |||
| 5837 | return nullptr; | |||
| 5838 | ||||
| 5839 | return new (Importer.getToContext()) CXXTemporaryObjectExpr( | |||
| 5840 | Importer.getToContext(), Ctor, T, TInfo, Args, | |||
| 5841 | Importer.Import(CE->getParenOrBraceRange()), CE->hadMultipleCandidates(), | |||
| 5842 | CE->isListInitialization(), CE->isStdInitListInitialization(), | |||
| 5843 | CE->requiresZeroInitialization()); | |||
| 5844 | } | |||
| 5845 | ||||
| 5846 | Expr * | |||
| 5847 | ASTNodeImporter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) { | |||
| 5848 | QualType T = Importer.Import(E->getType()); | |||
| 5849 | if (T.isNull()) | |||
| 5850 | return nullptr; | |||
| 5851 | ||||
| 5852 | Expr *TempE = Importer.Import(E->GetTemporaryExpr()); | |||
| 5853 | if (!TempE) | |||
| 5854 | return nullptr; | |||
| 5855 | ||||
| 5856 | auto *ExtendedBy = cast_or_null<ValueDecl>( | |||
| 5857 | Importer.Import(const_cast<ValueDecl *>(E->getExtendingDecl()))); | |||
| 5858 | if (!ExtendedBy && E->getExtendingDecl()) | |||
| 5859 | return nullptr; | |||
| 5860 | ||||
| 5861 | auto *ToMTE = new (Importer.getToContext()) MaterializeTemporaryExpr( | |||
| 5862 | T, TempE, E->isBoundToLvalueReference()); | |||
| 5863 | ||||
| 5864 | // FIXME: Should ManglingNumber get numbers associated with 'to' context? | |||
| 5865 | ToMTE->setExtendingDecl(ExtendedBy, E->getManglingNumber()); | |||
| 5866 | return ToMTE; | |||
| 5867 | } | |||
| 5868 | ||||
| 5869 | Expr *ASTNodeImporter::VisitPackExpansionExpr(PackExpansionExpr *E) { | |||
| 5870 | QualType T = Importer.Import(E->getType()); | |||
| 5871 | if (T.isNull()) | |||
| 5872 | return nullptr; | |||
| 5873 | ||||
| 5874 | Expr *Pattern = Importer.Import(E->getPattern()); | |||
| 5875 | if (!Pattern) | |||
| 5876 | return nullptr; | |||
| 5877 | ||||
| 5878 | return new (Importer.getToContext()) PackExpansionExpr( | |||
| 5879 | T, Pattern, Importer.Import(E->getEllipsisLoc()), | |||
| 5880 | E->getNumExpansions()); | |||
| 5881 | } | |||
| 5882 | ||||
| 5883 | Expr *ASTNodeImporter::VisitSizeOfPackExpr(SizeOfPackExpr *E) { | |||
| 5884 | auto *Pack = cast_or_null<NamedDecl>(Importer.Import(E->getPack())); | |||
| 5885 | if (!Pack) | |||
| 5886 | return nullptr; | |||
| 5887 | ||||
| 5888 | Optional<unsigned> Length; | |||
| 5889 | ||||
| 5890 | if (!E->isValueDependent()) | |||
| 5891 | Length = E->getPackLength(); | |||
| 5892 | ||||
| 5893 | SmallVector<TemplateArgument, 8> PartialArguments; | |||
| 5894 | if (E->isPartiallySubstituted()) { | |||
| 5895 | if (ImportTemplateArguments(E->getPartialArguments().data(), | |||
| 5896 | E->getPartialArguments().size(), | |||
| 5897 | PartialArguments)) | |||
| 5898 | return nullptr; | |||
| 5899 | } | |||
| 5900 | ||||
| 5901 | return SizeOfPackExpr::Create( | |||
| 5902 | Importer.getToContext(), Importer.Import(E->getOperatorLoc()), Pack, | |||
| 5903 | Importer.Import(E->getPackLoc()), Importer.Import(E->getRParenLoc()), | |||
| 5904 | Length, PartialArguments); | |||
| 5905 | } | |||
| 5906 | ||||
| 5907 | Expr *ASTNodeImporter::VisitCXXNewExpr(CXXNewExpr *CE) { | |||
| 5908 | QualType T = Importer.Import(CE->getType()); | |||
| 5909 | if (T.isNull()) | |||
| 5910 | return nullptr; | |||
| 5911 | ||||
| 5912 | SmallVector<Expr *, 4> PlacementArgs(CE->getNumPlacementArgs()); | |||
| 5913 | if (ImportContainerChecked(CE->placement_arguments(), PlacementArgs)) | |||
| 5914 | return nullptr; | |||
| 5915 | ||||
| 5916 | auto *OperatorNewDecl = cast_or_null<FunctionDecl>( | |||
| 5917 | Importer.Import(CE->getOperatorNew())); | |||
| 5918 | if (!OperatorNewDecl && CE->getOperatorNew()) | |||
| 5919 | return nullptr; | |||
| 5920 | ||||
| 5921 | auto *OperatorDeleteDecl = cast_or_null<FunctionDecl>( | |||
| 5922 | Importer.Import(CE->getOperatorDelete())); | |||
| 5923 | if (!OperatorDeleteDecl && CE->getOperatorDelete()) | |||
| 5924 | return nullptr; | |||
| 5925 | ||||
| 5926 | Expr *ToInit = Importer.Import(CE->getInitializer()); | |||
| 5927 | if (!ToInit && CE->getInitializer()) | |||
| 5928 | return nullptr; | |||
| 5929 | ||||
| 5930 | TypeSourceInfo *TInfo = Importer.Import(CE->getAllocatedTypeSourceInfo()); | |||
| 5931 | if (!TInfo) | |||
| 5932 | return nullptr; | |||
| 5933 | ||||
| 5934 | Expr *ToArrSize = Importer.Import(CE->getArraySize()); | |||
| 5935 | if (!ToArrSize && CE->getArraySize()) | |||
| 5936 | return nullptr; | |||
| 5937 | ||||
| 5938 | return new (Importer.getToContext()) CXXNewExpr( | |||
| 5939 | Importer.getToContext(), | |||
| 5940 | CE->isGlobalNew(), | |||
| 5941 | OperatorNewDecl, OperatorDeleteDecl, | |||
| 5942 | CE->passAlignment(), | |||
| 5943 | CE->doesUsualArrayDeleteWantSize(), | |||
| 5944 | PlacementArgs, | |||
| 5945 | Importer.Import(CE->getTypeIdParens()), | |||
| 5946 | ToArrSize, CE->getInitializationStyle(), ToInit, T, TInfo, | |||
| 5947 | Importer.Import(CE->getSourceRange()), | |||
| 5948 | Importer.Import(CE->getDirectInitRange())); | |||
| 5949 | } | |||
| 5950 | ||||
| 5951 | Expr *ASTNodeImporter::VisitCXXDeleteExpr(CXXDeleteExpr *E) { | |||
| 5952 | QualType T = Importer.Import(E->getType()); | |||
| 5953 | if (T.isNull()) | |||
| 5954 | return nullptr; | |||
| 5955 | ||||
| 5956 | auto *OperatorDeleteDecl = cast_or_null<FunctionDecl>( | |||
| 5957 | Importer.Import(E->getOperatorDelete())); | |||
| 5958 | if (!OperatorDeleteDecl && E->getOperatorDelete()) | |||
| 5959 | return nullptr; | |||
| 5960 | ||||
| 5961 | Expr *ToArg = Importer.Import(E->getArgument()); | |||
| 5962 | if (!ToArg && E->getArgument()) | |||
| 5963 | return nullptr; | |||
| 5964 | ||||
| 5965 | return new (Importer.getToContext()) CXXDeleteExpr( | |||
| 5966 | T, E->isGlobalDelete(), | |||
| 5967 | E->isArrayForm(), | |||
| 5968 | E->isArrayFormAsWritten(), | |||
| 5969 | E->doesUsualArrayDeleteWantSize(), | |||
| 5970 | OperatorDeleteDecl, | |||
| 5971 | ToArg, | |||
| 5972 | Importer.Import(E->getLocStart())); | |||
| 5973 | } | |||
| 5974 | ||||
| 5975 | Expr *ASTNodeImporter::VisitCXXConstructExpr(CXXConstructExpr *E) { | |||
| 5976 | QualType T = Importer.Import(E->getType()); | |||
| 5977 | if (T.isNull()) | |||
| 5978 | return nullptr; | |||
| 5979 | ||||
| 5980 | auto *ToCCD = | |||
| 5981 | dyn_cast_or_null<CXXConstructorDecl>(Importer.Import(E->getConstructor())); | |||
| 5982 | if (!ToCCD) | |||
| 5983 | return nullptr; | |||
| 5984 | ||||
| 5985 | SmallVector<Expr *, 6> ToArgs(E->getNumArgs()); | |||
| 5986 | if (ImportContainerChecked(E->arguments(), ToArgs)) | |||
| 5987 | return nullptr; | |||
| 5988 | ||||
| 5989 | return CXXConstructExpr::Create(Importer.getToContext(), T, | |||
| 5990 | Importer.Import(E->getLocation()), | |||
| 5991 | ToCCD, E->isElidable(), | |||
| 5992 | ToArgs, E->hadMultipleCandidates(), | |||
| 5993 | E->isListInitialization(), | |||
| 5994 | E->isStdInitListInitialization(), | |||
| 5995 | E->requiresZeroInitialization(), | |||
| 5996 | E->getConstructionKind(), | |||
| 5997 | Importer.Import(E->getParenOrBraceRange())); | |||
| 5998 | } | |||
| 5999 | ||||
| 6000 | Expr *ASTNodeImporter::VisitExprWithCleanups(ExprWithCleanups *EWC) { | |||
| 6001 | Expr *SubExpr = Importer.Import(EWC->getSubExpr()); | |||
| 6002 | if (!SubExpr && EWC->getSubExpr()) | |||
| 6003 | return nullptr; | |||
| 6004 | ||||
| 6005 | SmallVector<ExprWithCleanups::CleanupObject, 8> Objs(EWC->getNumObjects()); | |||
| 6006 | for (unsigned I = 0, E = EWC->getNumObjects(); I < E; I++) | |||
| 6007 | if (ExprWithCleanups::CleanupObject Obj = | |||
| 6008 | cast_or_null<BlockDecl>(Importer.Import(EWC->getObject(I)))) | |||
| 6009 | Objs[I] = Obj; | |||
| 6010 | else | |||
| 6011 | return nullptr; | |||
| 6012 | ||||
| 6013 | return ExprWithCleanups::Create(Importer.getToContext(), | |||
| 6014 | SubExpr, EWC->cleanupsHaveSideEffects(), | |||
| 6015 | Objs); | |||
| 6016 | } | |||
| 6017 | ||||
| 6018 | Expr *ASTNodeImporter::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) { | |||
| 6019 | QualType T = Importer.Import(E->getType()); | |||
| 6020 | if (T.isNull()) | |||
| 6021 | return nullptr; | |||
| 6022 | ||||
| 6023 | Expr *ToFn = Importer.Import(E->getCallee()); | |||
| 6024 | if (!ToFn) | |||
| 6025 | return nullptr; | |||
| 6026 | ||||
| 6027 | SmallVector<Expr *, 4> ToArgs(E->getNumArgs()); | |||
| 6028 | if (ImportContainerChecked(E->arguments(), ToArgs)) | |||
| 6029 | return nullptr; | |||
| 6030 | ||||
| 6031 | return new (Importer.getToContext()) CXXMemberCallExpr( | |||
| 6032 | Importer.getToContext(), ToFn, ToArgs, T, E->getValueKind(), | |||
| 6033 | Importer.Import(E->getRParenLoc())); | |||
| 6034 | } | |||
| 6035 | ||||
| 6036 | Expr *ASTNodeImporter::VisitCXXThisExpr(CXXThisExpr *E) { | |||
| 6037 | QualType T = Importer.Import(E->getType()); | |||
| 6038 | if (T.isNull()) | |||
| 6039 | return nullptr; | |||
| 6040 | ||||
| 6041 | return new (Importer.getToContext()) | |||
| 6042 | CXXThisExpr(Importer.Import(E->getLocation()), T, E->isImplicit()); | |||
| 6043 | } | |||
| 6044 | ||||
| 6045 | Expr *ASTNodeImporter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) { | |||
| 6046 | QualType T = Importer.Import(E->getType()); | |||
| 6047 | if (T.isNull()) | |||
| 6048 | return nullptr; | |||
| 6049 | ||||
| 6050 | return new (Importer.getToContext()) | |||
| 6051 | CXXBoolLiteralExpr(E->getValue(), T, Importer.Import(E->getLocation())); | |||
| 6052 | } | |||
| 6053 | ||||
| 6054 | ||||
| 6055 | Expr *ASTNodeImporter::VisitMemberExpr(MemberExpr *E) { | |||
| 6056 | QualType T = Importer.Import(E->getType()); | |||
| 6057 | if (T.isNull()) | |||
| 6058 | return nullptr; | |||
| 6059 | ||||
| 6060 | Expr *ToBase = Importer.Import(E->getBase()); | |||
| 6061 | if (!ToBase && E->getBase()) | |||
| 6062 | return nullptr; | |||
| 6063 | ||||
| 6064 | auto *ToMember = dyn_cast<ValueDecl>(Importer.Import(E->getMemberDecl())); | |||
| 6065 | if (!ToMember && E->getMemberDecl()) | |||
| 6066 | return nullptr; | |||
| 6067 | ||||
| 6068 | DeclAccessPair ToFoundDecl = DeclAccessPair::make( | |||
| 6069 | dyn_cast<NamedDecl>(Importer.Import(E->getFoundDecl().getDecl())), | |||
| 6070 | E->getFoundDecl().getAccess()); | |||
| 6071 | ||||
| 6072 | DeclarationNameInfo ToMemberNameInfo( | |||
| 6073 | Importer.Import(E->getMemberNameInfo().getName()), | |||
| 6074 | Importer.Import(E->getMemberNameInfo().getLoc())); | |||
| 6075 | ||||
| 6076 | if (E->hasExplicitTemplateArgs()) { | |||
| 6077 | return nullptr; // FIXME: handle template arguments | |||
| 6078 | } | |||
| 6079 | ||||
| 6080 | return MemberExpr::Create(Importer.getToContext(), ToBase, | |||
| 6081 | E->isArrow(), | |||
| 6082 | Importer.Import(E->getOperatorLoc()), | |||
| 6083 | Importer.Import(E->getQualifierLoc()), | |||
| 6084 | Importer.Import(E->getTemplateKeywordLoc()), | |||
| 6085 | ToMember, ToFoundDecl, ToMemberNameInfo, | |||
| 6086 | nullptr, T, E->getValueKind(), | |||
| 6087 | E->getObjectKind()); | |||
| 6088 | } | |||
| 6089 | ||||
| 6090 | Expr *ASTNodeImporter::VisitCXXPseudoDestructorExpr( | |||
| 6091 | CXXPseudoDestructorExpr *E) { | |||
| 6092 | Expr *BaseE = Importer.Import(E->getBase()); | |||
| 6093 | if (!BaseE) | |||
| 6094 | return nullptr; | |||
| 6095 | ||||
| 6096 | TypeSourceInfo *ScopeInfo = Importer.Import(E->getScopeTypeInfo()); | |||
| 6097 | if (!ScopeInfo && E->getScopeTypeInfo()) | |||
| 6098 | return nullptr; | |||
| 6099 | ||||
| 6100 | PseudoDestructorTypeStorage Storage; | |||
| 6101 | if (IdentifierInfo *FromII = E->getDestroyedTypeIdentifier()) { | |||
| 6102 | IdentifierInfo *ToII = Importer.Import(FromII); | |||
| 6103 | if (!ToII) | |||
| 6104 | return nullptr; | |||
| 6105 | Storage = PseudoDestructorTypeStorage( | |||
| 6106 | ToII, Importer.Import(E->getDestroyedTypeLoc())); | |||
| 6107 | } else { | |||
| 6108 | TypeSourceInfo *TI = Importer.Import(E->getDestroyedTypeInfo()); | |||
| 6109 | if (!TI) | |||
| 6110 | return nullptr; | |||
| 6111 | Storage = PseudoDestructorTypeStorage(TI); | |||
| 6112 | } | |||
| 6113 | ||||
| 6114 | return new (Importer.getToContext()) CXXPseudoDestructorExpr( | |||
| 6115 | Importer.getToContext(), BaseE, E->isArrow(), | |||
| 6116 | Importer.Import(E->getOperatorLoc()), | |||
| 6117 | Importer.Import(E->getQualifierLoc()), | |||
| 6118 | ScopeInfo, Importer.Import(E->getColonColonLoc()), | |||
| 6119 | Importer.Import(E->getTildeLoc()), Storage); | |||
| 6120 | } | |||
| 6121 | ||||
| 6122 | Expr *ASTNodeImporter::VisitCXXDependentScopeMemberExpr( | |||
| 6123 | CXXDependentScopeMemberExpr *E) { | |||
| 6124 | Expr *Base = nullptr; | |||
| 6125 | if (!E->isImplicitAccess()) { | |||
| 6126 | Base = Importer.Import(E->getBase()); | |||
| 6127 | if (!Base) | |||
| 6128 | return nullptr; | |||
| 6129 | } | |||
| 6130 | ||||
| 6131 | QualType BaseType = Importer.Import(E->getBaseType()); | |||
| 6132 | if (BaseType.isNull()) | |||
| 6133 | return nullptr; | |||
| 6134 | ||||
| 6135 | TemplateArgumentListInfo ToTAInfo, *ResInfo = nullptr; | |||
| 6136 | if (E->hasExplicitTemplateArgs()) { | |||
| 6137 | if (ImportTemplateArgumentListInfo(E->getLAngleLoc(), E->getRAngleLoc(), | |||
| 6138 | E->template_arguments(), ToTAInfo)) | |||
| 6139 | return nullptr; | |||
| 6140 | ResInfo = &ToTAInfo; | |||
| 6141 | } | |||
| 6142 | ||||
| 6143 | DeclarationName Name = Importer.Import(E->getMember()); | |||
| 6144 | if (!E->getMember().isEmpty() && Name.isEmpty()) | |||
| 6145 | return nullptr; | |||
| 6146 | ||||
| 6147 | DeclarationNameInfo MemberNameInfo(Name, Importer.Import(E->getMemberLoc())); | |||
| 6148 | // Import additional name location/type info. | |||
| 6149 | ImportDeclarationNameLoc(E->getMemberNameInfo(), MemberNameInfo); | |||
| 6150 | auto ToFQ = Importer.Import(E->getFirstQualifierFoundInScope()); | |||
| 6151 | if (!ToFQ && E->getFirstQualifierFoundInScope()) | |||
| 6152 | return nullptr; | |||
| 6153 | ||||
| 6154 | return CXXDependentScopeMemberExpr::Create( | |||
| 6155 | Importer.getToContext(), Base, BaseType, E->isArrow(), | |||
| 6156 | Importer.Import(E->getOperatorLoc()), | |||
| 6157 | Importer.Import(E->getQualifierLoc()), | |||
| 6158 | Importer.Import(E->getTemplateKeywordLoc()), | |||
| 6159 | cast_or_null<NamedDecl>(ToFQ), MemberNameInfo, ResInfo); | |||
| 6160 | } | |||
| 6161 | ||||
| 6162 | Expr *ASTNodeImporter::VisitCXXUnresolvedConstructExpr( | |||
| 6163 | CXXUnresolvedConstructExpr *CE) { | |||
| 6164 | unsigned NumArgs = CE->arg_size(); | |||
| 6165 | ||||
| 6166 | SmallVector<Expr *, 8> ToArgs(NumArgs); | |||
| 6167 | if (ImportArrayChecked(CE->arg_begin(), CE->arg_end(), ToArgs.begin())) | |||
| 6168 | return nullptr; | |||
| 6169 | ||||
| 6170 | return CXXUnresolvedConstructExpr::Create( | |||
| 6171 | Importer.getToContext(), Importer.Import(CE->getTypeSourceInfo()), | |||
| 6172 | Importer.Import(CE->getLParenLoc()), llvm::makeArrayRef(ToArgs), | |||
| 6173 | Importer.Import(CE->getRParenLoc())); | |||
| 6174 | } | |||
| 6175 | ||||
| 6176 | Expr *ASTNodeImporter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) { | |||
| 6177 | auto *NamingClass = | |||
| 6178 | cast_or_null<CXXRecordDecl>(Importer.Import(E->getNamingClass())); | |||
| 6179 | if (E->getNamingClass() && !NamingClass) | |||
| 6180 | return nullptr; | |||
| 6181 | ||||
| 6182 | DeclarationName Name = Importer.Import(E->getName()); | |||
| 6183 | if (E->getName() && !Name) | |||
| 6184 | return nullptr; | |||
| 6185 | ||||
| 6186 | DeclarationNameInfo NameInfo(Name, Importer.Import(E->getNameLoc())); | |||
| 6187 | // Import additional name location/type info. | |||
| 6188 | ImportDeclarationNameLoc(E->getNameInfo(), NameInfo); | |||
| 6189 | ||||
| 6190 | UnresolvedSet<8> ToDecls; | |||
| 6191 | for (auto *D : E->decls()) { | |||
| 6192 | if (auto *To = cast_or_null<NamedDecl>(Importer.Import(D))) | |||
| 6193 | ToDecls.addDecl(To); | |||
| 6194 | else | |||
| 6195 | return nullptr; | |||
| 6196 | } | |||
| 6197 | ||||
| 6198 | TemplateArgumentListInfo ToTAInfo, *ResInfo = nullptr; | |||
| 6199 | if (E->hasExplicitTemplateArgs()) { | |||
| 6200 | if (ImportTemplateArgumentListInfo(E->getLAngleLoc(), E->getRAngleLoc(), | |||
| 6201 | E->template_arguments(), ToTAInfo)) | |||
| 6202 | return nullptr; | |||
| 6203 | ResInfo = &ToTAInfo; | |||
| 6204 | } | |||
| 6205 | ||||
| 6206 | if (ResInfo || E->getTemplateKeywordLoc().isValid()) | |||
| 6207 | return UnresolvedLookupExpr::Create( | |||
| 6208 | Importer.getToContext(), NamingClass, | |||
| 6209 | Importer.Import(E->getQualifierLoc()), | |||
| 6210 | Importer.Import(E->getTemplateKeywordLoc()), NameInfo, E->requiresADL(), | |||
| 6211 | ResInfo, ToDecls.begin(), ToDecls.end()); | |||
| 6212 | ||||
| 6213 | return UnresolvedLookupExpr::Create( | |||
| 6214 | Importer.getToContext(), NamingClass, | |||
| 6215 | Importer.Import(E->getQualifierLoc()), NameInfo, E->requiresADL(), | |||
| 6216 | E->isOverloaded(), ToDecls.begin(), ToDecls.end()); | |||
| 6217 | } | |||
| 6218 | ||||
| 6219 | Expr *ASTNodeImporter::VisitCallExpr(CallExpr *E) { | |||
| 6220 | QualType T = Importer.Import(E->getType()); | |||
| 6221 | if (T.isNull()) | |||
| 6222 | return nullptr; | |||
| 6223 | ||||
| 6224 | Expr *ToCallee = Importer.Import(E->getCallee()); | |||
| 6225 | if (!ToCallee && E->getCallee()) | |||
| 6226 | return nullptr; | |||
| 6227 | ||||
| 6228 | unsigned NumArgs = E->getNumArgs(); | |||
| 6229 | SmallVector<Expr *, 2> ToArgs(NumArgs); | |||
| 6230 | if (ImportContainerChecked(E->arguments(), ToArgs)) | |||
| 6231 | return nullptr; | |||
| 6232 | ||||
| 6233 | auto **ToArgs_Copied = new (Importer.getToContext()) Expr*[NumArgs]; | |||
| 6234 | ||||
| 6235 | for (unsigned ai = 0, ae = NumArgs; ai != ae; ++ai) | |||
| 6236 | ToArgs_Copied[ai] = ToArgs[ai]; | |||
| 6237 | ||||
| 6238 | if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E)) { | |||
| 6239 | return new (Importer.getToContext()) CXXOperatorCallExpr( | |||
| 6240 | Importer.getToContext(), OCE->getOperator(), ToCallee, ToArgs, T, | |||
| 6241 | OCE->getValueKind(), Importer.Import(OCE->getRParenLoc()), | |||
| 6242 | OCE->getFPFeatures()); | |||
| 6243 | } | |||
| 6244 | ||||
| 6245 | return new (Importer.getToContext()) | |||
| 6246 | CallExpr(Importer.getToContext(), ToCallee, | |||
| 6247 | llvm::makeArrayRef(ToArgs_Copied, NumArgs), T, E->getValueKind(), | |||
| 6248 | Importer.Import(E->getRParenLoc())); | |||
| 6249 | } | |||
| 6250 | ||||
| 6251 | Optional<LambdaCapture> | |||
| 6252 | ASTNodeImporter::ImportLambdaCapture(const LambdaCapture &From) { | |||
| 6253 | VarDecl *Var = nullptr; | |||
| 6254 | if (From.capturesVariable()) { | |||
| 6255 | Var = cast_or_null<VarDecl>(Importer.Import(From.getCapturedVar())); | |||
| 6256 | if (!Var) | |||
| 6257 | return None; | |||
| 6258 | } | |||
| 6259 | ||||
| 6260 | return LambdaCapture(Importer.Import(From.getLocation()), From.isImplicit(), | |||
| 6261 | From.getCaptureKind(), Var, | |||
| 6262 | From.isPackExpansion() | |||
| 6263 | ? Importer.Import(From.getEllipsisLoc()) | |||
| 6264 | : SourceLocation()); | |||
| 6265 | } | |||
| 6266 | ||||
| 6267 | Expr *ASTNodeImporter::VisitLambdaExpr(LambdaExpr *LE) { | |||
| 6268 | CXXRecordDecl *FromClass = LE->getLambdaClass(); | |||
| 6269 | auto *ToClass = dyn_cast_or_null<CXXRecordDecl>(Importer.Import(FromClass)); | |||
| 6270 | if (!ToClass) | |||
| 6271 | return nullptr; | |||
| 6272 | ||||
| 6273 | // NOTE: lambda classes are created with BeingDefined flag set up. | |||
| 6274 | // It means that ImportDefinition doesn't work for them and we should fill it | |||
| 6275 | // manually. | |||
| 6276 | if (ToClass->isBeingDefined()) { | |||
| 6277 | for (auto FromField : FromClass->fields()) { | |||
| 6278 | auto *ToField = cast_or_null<FieldDecl>(Importer.Import(FromField)); | |||
| 6279 | if (!ToField) | |||
| 6280 | return nullptr; | |||
| 6281 | } | |||
| 6282 | } | |||
| 6283 | ||||
| 6284 | auto *ToCallOp = dyn_cast_or_null<CXXMethodDecl>( | |||
| 6285 | Importer.Import(LE->getCallOperator())); | |||
| 6286 | if (!ToCallOp) | |||
| 6287 | return nullptr; | |||
| 6288 | ||||
| 6289 | ToClass->completeDefinition(); | |||
| 6290 | ||||
| 6291 | unsigned NumCaptures = LE->capture_size(); | |||
| 6292 | SmallVector<LambdaCapture, 8> Captures; | |||
| 6293 | Captures.reserve(NumCaptures); | |||
| 6294 | for (const auto &FromCapture : LE->captures()) { | |||
| 6295 | if (auto ToCapture = ImportLambdaCapture(FromCapture)) | |||
| 6296 | Captures.push_back(*ToCapture); | |||
| 6297 | else | |||
| 6298 | return nullptr; | |||
| 6299 | } | |||
| 6300 | ||||
| 6301 | SmallVector<Expr *, 8> InitCaptures(NumCaptures); | |||
| 6302 | if (ImportContainerChecked(LE->capture_inits(), InitCaptures)) | |||
| 6303 | return nullptr; | |||
| 6304 | ||||
| 6305 | return LambdaExpr::Create(Importer.getToContext(), ToClass, | |||
| 6306 | Importer.Import(LE->getIntroducerRange()), | |||
| 6307 | LE->getCaptureDefault(), | |||
| 6308 | Importer.Import(LE->getCaptureDefaultLoc()), | |||
| 6309 | Captures, | |||
| 6310 | LE->hasExplicitParameters(), | |||
| 6311 | LE->hasExplicitResultType(), | |||
| 6312 | InitCaptures, | |||
| 6313 | Importer.Import(LE->getLocEnd()), | |||
| 6314 | LE->containsUnexpandedParameterPack()); | |||
| 6315 | } | |||
| 6316 | ||||
| 6317 | Expr *ASTNodeImporter::VisitInitListExpr(InitListExpr *ILE) { | |||
| 6318 | QualType T = Importer.Import(ILE->getType()); | |||
| 6319 | if (T.isNull()) | |||
| 6320 | return nullptr; | |||
| 6321 | ||||
| 6322 | SmallVector<Expr *, 4> Exprs(ILE->getNumInits()); | |||
| 6323 | if (ImportContainerChecked(ILE->inits(), Exprs)) | |||
| 6324 | return nullptr; | |||
| 6325 | ||||
| 6326 | ASTContext &ToCtx = Importer.getToContext(); | |||
| 6327 | InitListExpr *To = new (ToCtx) InitListExpr( | |||
| 6328 | ToCtx, Importer.Import(ILE->getLBraceLoc()), | |||
| 6329 | Exprs, Importer.Import(ILE->getLBraceLoc())); | |||
| 6330 | To->setType(T); | |||
| 6331 | ||||
| 6332 | if (ILE->hasArrayFiller()) { | |||
| 6333 | Expr *Filler = Importer.Import(ILE->getArrayFiller()); | |||
| 6334 | if (!Filler) | |||
| 6335 | return nullptr; | |||
| 6336 | To->setArrayFiller(Filler); | |||
| 6337 | } | |||
| 6338 | ||||
| 6339 | if (FieldDecl *FromFD = ILE->getInitializedFieldInUnion()) { | |||
| 6340 | auto *ToFD = cast_or_null<FieldDecl>(Importer.Import(FromFD)); | |||
| 6341 | if (!ToFD) | |||
| 6342 | return nullptr; | |||
| 6343 | To->setInitializedFieldInUnion(ToFD); | |||
| 6344 | } | |||
| 6345 | ||||
| 6346 | if (InitListExpr *SyntForm = ILE->getSyntacticForm()) { | |||
| 6347 | auto *ToSyntForm = cast_or_null<InitListExpr>(Importer.Import(SyntForm)); | |||
| 6348 | if (!ToSyntForm) | |||
| 6349 | return nullptr; | |||
| 6350 | To->setSyntacticForm(ToSyntForm); | |||
| 6351 | } | |||
| 6352 | ||||
| 6353 | To->sawArrayRangeDesignator(ILE->hadArrayRangeDesignator()); | |||
| 6354 | To->setValueDependent(ILE->isValueDependent()); | |||
| 6355 | To->setInstantiationDependent(ILE->isInstantiationDependent()); | |||
| 6356 | ||||
| 6357 | return To; | |||
| 6358 | } | |||
| 6359 | ||||
| 6360 | Expr *ASTNodeImporter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *E) { | |||
| 6361 | QualType ToType = Importer.Import(E->getType()); | |||
| 6362 | if (ToType.isNull()) | |||
| 6363 | return nullptr; | |||
| 6364 | ||||
| 6365 | Expr *ToCommon = Importer.Import(E->getCommonExpr()); | |||
| 6366 | if (!ToCommon && E->getCommonExpr()) | |||
| 6367 | return nullptr; | |||
| 6368 | ||||
| 6369 | Expr *ToSubExpr = Importer.Import(E->getSubExpr()); | |||
| 6370 | if (!ToSubExpr && E->getSubExpr()) | |||
| 6371 | return nullptr; | |||
| 6372 | ||||
| 6373 | return new (Importer.getToContext()) | |||
| 6374 | ArrayInitLoopExpr(ToType, ToCommon, ToSubExpr); | |||
| 6375 | } | |||
| 6376 | ||||
| 6377 | Expr *ASTNodeImporter::VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) { | |||
| 6378 | QualType ToType = Importer.Import(E->getType()); | |||
| 6379 | if (ToType.isNull()) | |||
| 6380 | return nullptr; | |||
| 6381 | return new (Importer.getToContext()) ArrayInitIndexExpr(ToType); | |||
| 6382 | } | |||
| 6383 | ||||
| 6384 | Expr *ASTNodeImporter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) { | |||
| 6385 | auto *ToField = dyn_cast_or_null<FieldDecl>(Importer.Import(DIE->getField())); | |||
| ||||
| 6386 | if (!ToField && DIE->getField()) | |||
| 6387 | return nullptr; | |||
| 6388 | ||||
| 6389 | return CXXDefaultInitExpr::Create( | |||
| 6390 | Importer.getToContext(), Importer.Import(DIE->getLocStart()), ToField); | |||
| 6391 | } | |||
| 6392 | ||||
| 6393 | Expr *ASTNodeImporter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) { | |||
| 6394 | QualType ToType = Importer.Import(E->getType()); | |||
| 6395 | if (ToType.isNull() && !E->getType().isNull()) | |||
| 6396 | return nullptr; | |||
| 6397 | ExprValueKind VK = E->getValueKind(); | |||
| 6398 | CastKind CK = E->getCastKind(); | |||
| 6399 | Expr *ToOp = Importer.Import(E->getSubExpr()); | |||
| 6400 | if (!ToOp && E->getSubExpr()) | |||
| 6401 | return nullptr; | |||
| 6402 | CXXCastPath BasePath; | |||
| 6403 | if (ImportCastPath(E, BasePath)) | |||
| 6404 | return nullptr; | |||
| 6405 | TypeSourceInfo *ToWritten = Importer.Import(E->getTypeInfoAsWritten()); | |||
| 6406 | SourceLocation ToOperatorLoc = Importer.Import(E->getOperatorLoc()); | |||
| 6407 | SourceLocation ToRParenLoc = Importer.Import(E->getRParenLoc()); | |||
| 6408 | SourceRange ToAngleBrackets = Importer.Import(E->getAngleBrackets()); | |||
| 6409 | ||||
| 6410 | if (isa<CXXStaticCastExpr>(E)) { | |||
| 6411 | return CXXStaticCastExpr::Create( | |||
| 6412 | Importer.getToContext(), ToType, VK, CK, ToOp, &BasePath, | |||
| 6413 | ToWritten, ToOperatorLoc, ToRParenLoc, ToAngleBrackets); | |||
| 6414 | } else if (isa<CXXDynamicCastExpr>(E)) { | |||
| 6415 | return CXXDynamicCastExpr::Create( | |||
| 6416 | Importer.getToContext(), ToType, VK, CK, ToOp, &BasePath, | |||
| 6417 | ToWritten, ToOperatorLoc, ToRParenLoc, ToAngleBrackets); | |||
| 6418 | } else if (isa<CXXReinterpretCastExpr>(E)) { | |||
| 6419 | return CXXReinterpretCastExpr::Create( | |||
| 6420 | Importer.getToContext(), ToType, VK, CK, ToOp, &BasePath, | |||
| 6421 | ToWritten, ToOperatorLoc, ToRParenLoc, ToAngleBrackets); | |||
| 6422 | } else { | |||
| 6423 | return nullptr; | |||
| 6424 | } | |||
| 6425 | } | |||
| 6426 | ||||
| 6427 | Expr *ASTNodeImporter::VisitSubstNonTypeTemplateParmExpr( | |||
| 6428 | SubstNonTypeTemplateParmExpr *E) { | |||
| 6429 | QualType T = Importer.Import(E->getType()); | |||
| 6430 | if (T.isNull()) | |||
| 6431 | return nullptr; | |||
| 6432 | ||||
| 6433 | auto *Param = cast_or_null<NonTypeTemplateParmDecl>( | |||
| 6434 | Importer.Import(E->getParameter())); | |||
| 6435 | if (!Param) | |||
| 6436 | return nullptr; | |||
| 6437 | ||||
| 6438 | Expr *Replacement = Importer.Import(E->getReplacement()); | |||
| 6439 | if (!Replacement) | |||
| 6440 | return nullptr; | |||
| 6441 | ||||
| 6442 | return new (Importer.getToContext()) SubstNonTypeTemplateParmExpr( | |||
| 6443 | T, E->getValueKind(), Importer.Import(E->getExprLoc()), Param, | |||
| 6444 | Replacement); | |||
| 6445 | } | |||
| 6446 | ||||
| 6447 | Expr *ASTNodeImporter::VisitTypeTraitExpr(TypeTraitExpr *E) { | |||
| 6448 | QualType ToType = Importer.Import(E->getType()); | |||
| 6449 | if (ToType.isNull()) | |||
| 6450 | return nullptr; | |||
| 6451 | ||||
| 6452 | SmallVector<TypeSourceInfo *, 4> ToArgs(E->getNumArgs()); | |||
| 6453 | if (ImportContainerChecked(E->getArgs(), ToArgs)) | |||
| 6454 | return nullptr; | |||
| 6455 | ||||
| 6456 | // According to Sema::BuildTypeTrait(), if E is value-dependent, | |||
| 6457 | // Value is always false. | |||
| 6458 | bool ToValue = false; | |||
| 6459 | if (!E->isValueDependent()) | |||
| 6460 | ToValue = E->getValue(); | |||
| 6461 | ||||
| 6462 | return TypeTraitExpr::Create( | |||
| 6463 | Importer.getToContext(), ToType, Importer.Import(E->getLocStart()), | |||
| 6464 | E->getTrait(), ToArgs, Importer.Import(E->getLocEnd()), ToValue); | |||
| 6465 | } | |||
| 6466 | ||||
| 6467 | Expr *ASTNodeImporter::VisitCXXTypeidExpr(CXXTypeidExpr *E) { | |||
| 6468 | QualType ToType = Importer.Import(E->getType()); | |||
| 6469 | if (ToType.isNull()) | |||
| 6470 | return nullptr; | |||
| 6471 | ||||
| 6472 | if (E->isTypeOperand()) { | |||
| 6473 | TypeSourceInfo *TSI = Importer.Import(E->getTypeOperandSourceInfo()); | |||
| 6474 | if (!TSI) | |||
| 6475 | return nullptr; | |||
| 6476 | ||||
| 6477 | return new (Importer.getToContext()) | |||
| 6478 | CXXTypeidExpr(ToType, TSI, Importer.Import(E->getSourceRange())); | |||
| 6479 | } | |||
| 6480 | ||||
| 6481 | Expr *Op = Importer.Import(E->getExprOperand()); | |||
| 6482 | if (!Op) | |||
| 6483 | return nullptr; | |||
| 6484 | ||||
| 6485 | return new (Importer.getToContext()) | |||
| 6486 | CXXTypeidExpr(ToType, Op, Importer.Import(E->getSourceRange())); | |||
| 6487 | } | |||
| 6488 | ||||
| 6489 | void ASTNodeImporter::ImportOverrides(CXXMethodDecl *ToMethod, | |||
| 6490 | CXXMethodDecl *FromMethod) { | |||
| 6491 | for (auto *FromOverriddenMethod : FromMethod->overridden_methods()) | |||
| 6492 | ToMethod->addOverriddenMethod( | |||
| 6493 | cast<CXXMethodDecl>(Importer.Import(const_cast<CXXMethodDecl*>( | |||
| 6494 | FromOverriddenMethod)))); | |||
| 6495 | } | |||
| 6496 | ||||
| 6497 | ASTImporter::ASTImporter(ASTContext &ToContext, FileManager &ToFileManager, | |||
| 6498 | ASTContext &FromContext, FileManager &FromFileManager, | |||
| 6499 | bool MinimalImport) | |||
| 6500 | : ToContext(ToContext), FromContext(FromContext), | |||
| 6501 | ToFileManager(ToFileManager), FromFileManager(FromFileManager), | |||
| 6502 | Minimal(MinimalImport) { | |||
| 6503 | ImportedDecls[FromContext.getTranslationUnitDecl()] | |||
| 6504 | = ToContext.getTranslationUnitDecl(); | |||
| 6505 | } | |||
| 6506 | ||||
| 6507 | ASTImporter::~ASTImporter() = default; | |||
| 6508 | ||||
| 6509 | QualType ASTImporter::Import(QualType FromT) { | |||
| 6510 | if (FromT.isNull()) | |||
| 6511 | return {}; | |||
| 6512 | ||||
| 6513 | const Type *fromTy = FromT.getTypePtr(); | |||
| 6514 | ||||
| 6515 | // Check whether we've already imported this type. | |||
| 6516 | llvm::DenseMap<const Type *, const Type *>::iterator Pos | |||
| 6517 | = ImportedTypes.find(fromTy); | |||
| 6518 | if (Pos != ImportedTypes.end()) | |||
| 6519 | return ToContext.getQualifiedType(Pos->second, FromT.getLocalQualifiers()); | |||
| 6520 | ||||
| 6521 | // Import the type | |||
| 6522 | ASTNodeImporter Importer(*this); | |||
| 6523 | QualType ToT = Importer.Visit(fromTy); | |||
| 6524 | if (ToT.isNull()) | |||
| 6525 | return ToT; | |||
| 6526 | ||||
| 6527 | // Record the imported type. | |||
| 6528 | ImportedTypes[fromTy] = ToT.getTypePtr(); | |||
| 6529 | ||||
| 6530 | return ToContext.getQualifiedType(ToT, FromT.getLocalQualifiers()); | |||
| 6531 | } | |||
| 6532 | ||||
| 6533 | TypeSourceInfo *ASTImporter::Import(TypeSourceInfo *FromTSI) { | |||
| 6534 | if (!FromTSI) | |||
| 6535 | return FromTSI; | |||
| 6536 | ||||
| 6537 | // FIXME: For now we just create a "trivial" type source info based | |||
| 6538 | // on the type and a single location. Implement a real version of this. | |||
| 6539 | QualType T = Import(FromTSI->getType()); | |||
| 6540 | if (T.isNull()) | |||
| 6541 | return nullptr; | |||
| 6542 | ||||
| 6543 | return ToContext.getTrivialTypeSourceInfo(T, | |||
| 6544 | Import(FromTSI->getTypeLoc().getLocStart())); | |||
| 6545 | } | |||
| 6546 | ||||
| 6547 | Decl *ASTImporter::GetAlreadyImportedOrNull(Decl *FromD) { | |||
| 6548 | llvm::DenseMap<Decl *, Decl *>::iterator Pos = ImportedDecls.find(FromD); | |||
| 6549 | if (Pos != ImportedDecls.end()) { | |||
| 6550 | Decl *ToD = Pos->second; | |||
| 6551 | ASTNodeImporter(*this).ImportDefinitionIfNeeded(FromD, ToD); | |||
| 6552 | return ToD; | |||
| 6553 | } else { | |||
| 6554 | return nullptr; | |||
| 6555 | } | |||
| 6556 | } | |||
| 6557 | ||||
| 6558 | Decl *ASTImporter::Import(Decl *FromD) { | |||
| 6559 | if (!FromD) | |||
| 6560 | return nullptr; | |||
| 6561 | ||||
| 6562 | ASTNodeImporter Importer(*this); | |||
| 6563 | ||||
| 6564 | // Check whether we've already imported this declaration. | |||
| 6565 | llvm::DenseMap<Decl *, Decl *>::iterator Pos = ImportedDecls.find(FromD); | |||
| 6566 | if (Pos != ImportedDecls.end()) { | |||
| 6567 | Decl *ToD = Pos->second; | |||
| 6568 | Importer.ImportDefinitionIfNeeded(FromD, ToD); | |||
| 6569 | return ToD; | |||
| 6570 | } | |||
| 6571 | ||||
| 6572 | // Import the type | |||
| 6573 | Decl *ToD = Importer.Visit(FromD); | |||
| 6574 | if (!ToD) | |||
| 6575 | return nullptr; | |||
| 6576 | ||||
| 6577 | // Record the imported declaration. | |||
| 6578 | ImportedDecls[FromD] = ToD; | |||
| 6579 | ||||
| 6580 | if (auto *FromTag = dyn_cast<TagDecl>(FromD)) { | |||
| 6581 | // Keep track of anonymous tags that have an associated typedef. | |||
| 6582 | if (FromTag->getTypedefNameForAnonDecl()) | |||
| 6583 | AnonTagsWithPendingTypedefs.push_back(FromTag); | |||
| 6584 | } else if (auto *FromTypedef = dyn_cast<TypedefNameDecl>(FromD)) { | |||
| 6585 | // When we've finished transforming a typedef, see whether it was the | |||
| 6586 | // typedef for an anonymous tag. | |||
| 6587 | for (SmallVectorImpl<TagDecl *>::iterator | |||
| 6588 | FromTag = AnonTagsWithPendingTypedefs.begin(), | |||
| 6589 | FromTagEnd = AnonTagsWithPendingTypedefs.end(); | |||
| 6590 | FromTag != FromTagEnd; ++FromTag) { | |||
| 6591 | if ((*FromTag)->getTypedefNameForAnonDecl() == FromTypedef) { | |||
| 6592 | if (auto *ToTag = cast_or_null<TagDecl>(Import(*FromTag))) { | |||
| 6593 | // We found the typedef for an anonymous tag; link them. | |||
| 6594 | ToTag->setTypedefNameForAnonDecl(cast<TypedefNameDecl>(ToD)); | |||
| 6595 | AnonTagsWithPendingTypedefs.erase(FromTag); | |||
| 6596 | break; | |||
| 6597 | } | |||
| 6598 | } | |||
| 6599 | } | |||
| 6600 | } | |||
| 6601 | ||||
| 6602 | return ToD; | |||
| 6603 | } | |||
| 6604 | ||||
| 6605 | DeclContext *ASTImporter::ImportContext(DeclContext *FromDC) { | |||
| 6606 | if (!FromDC) | |||
| 6607 | return FromDC; | |||
| 6608 | ||||
| 6609 | auto *ToDC = cast_or_null<DeclContext>(Import(cast<Decl>(FromDC))); | |||
| 6610 | if (!ToDC) | |||
| 6611 | return nullptr; | |||
| 6612 | ||||
| 6613 | // When we're using a record/enum/Objective-C class/protocol as a context, we | |||
| 6614 | // need it to have a definition. | |||
| 6615 | if (auto *ToRecord = dyn_cast<RecordDecl>(ToDC)) { | |||
| 6616 | auto *FromRecord = cast<RecordDecl>(FromDC); | |||
| 6617 | if (ToRecord->isCompleteDefinition()) { | |||
| 6618 | // Do nothing. | |||
| 6619 | } else if (FromRecord->isCompleteDefinition()) { | |||
| 6620 | ASTNodeImporter(*this).ImportDefinition(FromRecord, ToRecord, | |||
| 6621 | ASTNodeImporter::IDK_Basic); | |||
| 6622 | } else { | |||
| 6623 | CompleteDecl(ToRecord); | |||
| 6624 | } | |||
| 6625 | } else if (auto *ToEnum = dyn_cast<EnumDecl>(ToDC)) { | |||
| 6626 | auto *FromEnum = cast<EnumDecl>(FromDC); | |||
| 6627 | if (ToEnum->isCompleteDefinition()) { | |||
| 6628 | // Do nothing. | |||
| 6629 | } else if (FromEnum->isCompleteDefinition()) { | |||
| 6630 | ASTNodeImporter(*this).ImportDefinition(FromEnum, ToEnum, | |||
| 6631 | ASTNodeImporter::IDK_Basic); | |||
| 6632 | } else { | |||
| 6633 | CompleteDecl(ToEnum); | |||
| 6634 | } | |||
| 6635 | } else if (auto *ToClass = dyn_cast<ObjCInterfaceDecl>(ToDC)) { | |||
| 6636 | auto *FromClass = cast<ObjCInterfaceDecl>(FromDC); | |||
| 6637 | if (ToClass->getDefinition()) { | |||
| 6638 | // Do nothing. | |||
| 6639 | } else if (ObjCInterfaceDecl *FromDef = FromClass->getDefinition()) { | |||
| 6640 | ASTNodeImporter(*this).ImportDefinition(FromDef, ToClass, | |||
| 6641 | ASTNodeImporter::IDK_Basic); | |||
| 6642 | } else { | |||
| 6643 | CompleteDecl(ToClass); | |||
| 6644 | } | |||
| 6645 | } else if (auto *ToProto = dyn_cast<ObjCProtocolDecl>(ToDC)) { | |||
| 6646 | auto *FromProto = cast<ObjCProtocolDecl>(FromDC); | |||
| 6647 | if (ToProto->getDefinition()) { | |||
| 6648 | // Do nothing. | |||
| 6649 | } else if (ObjCProtocolDecl *FromDef = FromProto->getDefinition()) { | |||
| 6650 | ASTNodeImporter(*this).ImportDefinition(FromDef, ToProto, | |||
| 6651 | ASTNodeImporter::IDK_Basic); | |||
| 6652 | } else { | |||
| 6653 | CompleteDecl(ToProto); | |||
| 6654 | } | |||
| 6655 | } | |||
| 6656 | ||||
| 6657 | return ToDC; | |||
| 6658 | } | |||
| 6659 | ||||
| 6660 | Expr *ASTImporter::Import(Expr *FromE) { | |||
| 6661 | if (!FromE) | |||
| 6662 | return nullptr; | |||
| 6663 | ||||
| 6664 | return cast_or_null<Expr>(Import(cast<Stmt>(FromE))); | |||
| 6665 | } | |||
| 6666 | ||||
| 6667 | Stmt *ASTImporter::Import(Stmt *FromS) { | |||
| 6668 | if (!FromS) | |||
| 6669 | return nullptr; | |||
| 6670 | ||||
| 6671 | // Check whether we've already imported this declaration. | |||
| 6672 | llvm::DenseMap<Stmt *, Stmt *>::iterator Pos = ImportedStmts.find(FromS); | |||
| 6673 | if (Pos != ImportedStmts.end()) | |||
| 6674 | return Pos->second; | |||
| 6675 | ||||
| 6676 | // Import the type | |||
| 6677 | ASTNodeImporter Importer(*this); | |||
| 6678 | Stmt *ToS = Importer.Visit(FromS); | |||
| 6679 | if (!ToS) | |||
| 6680 | return nullptr; | |||
| 6681 | ||||
| 6682 | // Record the imported declaration. | |||
| 6683 | ImportedStmts[FromS] = ToS; | |||
| 6684 | return ToS; | |||
| 6685 | } | |||
| 6686 | ||||
| 6687 | NestedNameSpecifier *ASTImporter::Import(NestedNameSpecifier *FromNNS) { | |||
| 6688 | if (!FromNNS) | |||
| 6689 | return nullptr; | |||
| 6690 | ||||
| 6691 | NestedNameSpecifier *prefix = Import(FromNNS->getPrefix()); | |||
| 6692 | ||||
| 6693 | switch (FromNNS->getKind()) { | |||
| 6694 | case NestedNameSpecifier::Identifier: | |||
| 6695 | if (IdentifierInfo *II = Import(FromNNS->getAsIdentifier())) { | |||
| 6696 | return NestedNameSpecifier::Create(ToContext, prefix, II); | |||
| 6697 | } | |||
| 6698 | return nullptr; | |||
| 6699 | ||||
| 6700 | case NestedNameSpecifier::Namespace: | |||
| 6701 | if (auto *NS = | |||
| 6702 | cast_or_null<NamespaceDecl>(Import(FromNNS->getAsNamespace()))) { | |||
| 6703 | return NestedNameSpecifier::Create(ToContext, prefix, NS); | |||
| 6704 | } | |||
| 6705 | return nullptr; | |||
| 6706 | ||||
| 6707 | case NestedNameSpecifier::NamespaceAlias: | |||
| 6708 | if (auto *NSAD = | |||
| 6709 | cast_or_null<NamespaceAliasDecl>(Import(FromNNS->getAsNamespaceAlias()))) { | |||
| 6710 | return NestedNameSpecifier::Create(ToContext, prefix, NSAD); | |||
| 6711 | } | |||
| 6712 | return nullptr; | |||
| 6713 | ||||
| 6714 | case NestedNameSpecifier::Global: | |||
| 6715 | return NestedNameSpecifier::GlobalSpecifier(ToContext); | |||
| 6716 | ||||
| 6717 | case NestedNameSpecifier::Super: | |||
| 6718 | if (auto *RD = | |||
| 6719 | cast_or_null<CXXRecordDecl>(Import(FromNNS->getAsRecordDecl()))) { | |||
| 6720 | return NestedNameSpecifier::SuperSpecifier(ToContext, RD); | |||
| 6721 | } | |||
| 6722 | return nullptr; | |||
| 6723 | ||||
| 6724 | case NestedNameSpecifier::TypeSpec: | |||
| 6725 | case NestedNameSpecifier::TypeSpecWithTemplate: { | |||
| 6726 | QualType T = Import(QualType(FromNNS->getAsType(), 0u)); | |||
| 6727 | if (!T.isNull()) { | |||
| 6728 | bool bTemplate = FromNNS->getKind() == | |||
| 6729 | NestedNameSpecifier::TypeSpecWithTemplate; | |||
| 6730 | return NestedNameSpecifier::Create(ToContext, prefix, | |||
| 6731 | bTemplate, T.getTypePtr()); | |||
| 6732 | } | |||
| 6733 | } | |||
| 6734 | return nullptr; | |||
| 6735 | } | |||
| 6736 | ||||
| 6737 | llvm_unreachable("Invalid nested name specifier kind")::llvm::llvm_unreachable_internal("Invalid nested name specifier kind" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/lib/AST/ASTImporter.cpp" , 6737); | |||
| 6738 | } | |||
| 6739 | ||||
| 6740 | NestedNameSpecifierLoc ASTImporter::Import(NestedNameSpecifierLoc FromNNS) { | |||
| 6741 | // Copied from NestedNameSpecifier mostly. | |||
| 6742 | SmallVector<NestedNameSpecifierLoc , 8> NestedNames; | |||
| 6743 | NestedNameSpecifierLoc NNS = FromNNS; | |||
| 6744 | ||||
| 6745 | // Push each of the nested-name-specifiers's onto a stack for | |||
| 6746 | // serialization in reverse order. | |||
| 6747 | while (NNS) { | |||
| 6748 | NestedNames.push_back(NNS); | |||
| 6749 | NNS = NNS.getPrefix(); | |||
| 6750 | } | |||
| 6751 | ||||
| 6752 | NestedNameSpecifierLocBuilder Builder; | |||
| 6753 | ||||
| 6754 | while (!NestedNames.empty()) { | |||
| 6755 | NNS = NestedNames.pop_back_val(); | |||
| 6756 | NestedNameSpecifier *Spec = Import(NNS.getNestedNameSpecifier()); | |||
| 6757 | if (!Spec) | |||
| 6758 | return NestedNameSpecifierLoc(); | |||
| 6759 | ||||
| 6760 | NestedNameSpecifier::SpecifierKind Kind = Spec->getKind(); | |||
| 6761 | switch (Kind) { | |||
| 6762 | case NestedNameSpecifier::Identifier: | |||
| 6763 | Builder.Extend(getToContext(), | |||
| 6764 | Spec->getAsIdentifier(), | |||
| 6765 | Import(NNS.getLocalBeginLoc()), | |||
| 6766 | Import(NNS.getLocalEndLoc())); | |||
| 6767 | break; | |||
| 6768 | ||||
| 6769 | case NestedNameSpecifier::Namespace: | |||
| 6770 | Builder.Extend(getToContext(), | |||
| 6771 | Spec->getAsNamespace(), | |||
| 6772 | Import(NNS.getLocalBeginLoc()), | |||
| 6773 | Import(NNS.getLocalEndLoc())); | |||
| 6774 | break; | |||
| 6775 | ||||
| 6776 | case NestedNameSpecifier::NamespaceAlias: | |||
| 6777 | Builder.Extend(getToContext(), | |||
| 6778 | Spec->getAsNamespaceAlias(), | |||
| 6779 | Import(NNS.getLocalBeginLoc()), | |||
| 6780 | Import(NNS.getLocalEndLoc())); | |||
| 6781 | break; | |||
| 6782 | ||||
| 6783 | case NestedNameSpecifier::TypeSpec: | |||
| 6784 | case NestedNameSpecifier::TypeSpecWithTemplate: { | |||
| 6785 | TypeSourceInfo *TSI = getToContext().getTrivialTypeSourceInfo( | |||
| 6786 | QualType(Spec->getAsType(), 0)); | |||
| 6787 | Builder.Extend(getToContext(), | |||
| 6788 | Import(NNS.getLocalBeginLoc()), | |||
| 6789 | TSI->getTypeLoc(), | |||
| 6790 | Import(NNS.getLocalEndLoc())); | |||
| 6791 | break; | |||
| 6792 | } | |||
| 6793 | ||||
| 6794 | case NestedNameSpecifier::Global: | |||
| 6795 | Builder.MakeGlobal(getToContext(), Import(NNS.getLocalBeginLoc())); | |||
| 6796 | break; | |||
| 6797 | ||||
| 6798 | case NestedNameSpecifier::Super: { | |||
| 6799 | SourceRange ToRange = Import(NNS.getSourceRange()); | |||
| 6800 | Builder.MakeSuper(getToContext(), | |||
| 6801 | Spec->getAsRecordDecl(), | |||
| 6802 | ToRange.getBegin(), | |||
| 6803 | ToRange.getEnd()); | |||
| 6804 | } | |||
| 6805 | } | |||
| 6806 | } | |||
| 6807 | ||||
| 6808 | return Builder.getWithLocInContext(getToContext()); | |||
| 6809 | } | |||
| 6810 | ||||
| 6811 | TemplateName ASTImporter::Import(TemplateName From) { | |||
| 6812 | switch (From.getKind()) { | |||
| 6813 | case TemplateName::Template: | |||
| 6814 | if (auto *ToTemplate = | |||
| 6815 | cast_or_null<TemplateDecl>(Import(From.getAsTemplateDecl()))) | |||
| 6816 | return TemplateName(ToTemplate); | |||
| 6817 | ||||
| 6818 | return {}; | |||
| 6819 | ||||
| 6820 | case TemplateName::OverloadedTemplate: { | |||
| 6821 | OverloadedTemplateStorage *FromStorage = From.getAsOverloadedTemplate(); | |||
| 6822 | UnresolvedSet<2> ToTemplates; | |||
| 6823 | for (auto *I : *FromStorage) { | |||
| 6824 | if (auto *To = cast_or_null<NamedDecl>(Import(I))) | |||
| 6825 | ToTemplates.addDecl(To); | |||
| 6826 | else | |||
| 6827 | return {}; | |||
| 6828 | } | |||
| 6829 | return ToContext.getOverloadedTemplateName(ToTemplates.begin(), | |||
| 6830 | ToTemplates.end()); | |||
| 6831 | } | |||
| 6832 | ||||
| 6833 | case TemplateName::QualifiedTemplate: { | |||
| 6834 | QualifiedTemplateName *QTN = From.getAsQualifiedTemplateName(); | |||
| 6835 | NestedNameSpecifier *Qualifier = Import(QTN->getQualifier()); | |||
| 6836 | if (!Qualifier) | |||
| 6837 | return {}; | |||
| 6838 | ||||
| 6839 | if (auto *ToTemplate = | |||
| 6840 | cast_or_null<TemplateDecl>(Import(From.getAsTemplateDecl()))) | |||
| 6841 | return ToContext.getQualifiedTemplateName(Qualifier, | |||
| 6842 | QTN->hasTemplateKeyword(), | |||
| 6843 | ToTemplate); | |||
| 6844 | ||||
| 6845 | return {}; | |||
| 6846 | } | |||
| 6847 | ||||
| 6848 | case TemplateName::DependentTemplate: { | |||
| 6849 | DependentTemplateName *DTN = From.getAsDependentTemplateName(); | |||
| 6850 | NestedNameSpecifier *Qualifier = Import(DTN->getQualifier()); | |||
| 6851 | if (!Qualifier) | |||
| 6852 | return {}; | |||
| 6853 | ||||
| 6854 | if (DTN->isIdentifier()) { | |||
| 6855 | return ToContext.getDependentTemplateName(Qualifier, | |||
| 6856 | Import(DTN->getIdentifier())); | |||
| 6857 | } | |||
| 6858 | ||||
| 6859 | return ToContext.getDependentTemplateName(Qualifier, DTN->getOperator()); | |||
| 6860 | } | |||
| 6861 | ||||
| 6862 | case TemplateName::SubstTemplateTemplateParm: { | |||
| 6863 | SubstTemplateTemplateParmStorage *subst | |||
| 6864 | = From.getAsSubstTemplateTemplateParm(); | |||
| 6865 | auto *param = | |||
| 6866 | cast_or_null<TemplateTemplateParmDecl>(Import(subst->getParameter())); | |||
| 6867 | if (!param) | |||
| 6868 | return {}; | |||
| 6869 | ||||
| 6870 | TemplateName replacement = Import(subst->getReplacement()); | |||
| 6871 | if (replacement.isNull()) | |||
| 6872 | return {}; | |||
| 6873 | ||||
| 6874 | return ToContext.getSubstTemplateTemplateParm(param, replacement); | |||
| 6875 | } | |||
| 6876 | ||||
| 6877 | case TemplateName::SubstTemplateTemplateParmPack: { | |||
| 6878 | SubstTemplateTemplateParmPackStorage *SubstPack | |||
| 6879 | = From.getAsSubstTemplateTemplateParmPack(); | |||
| 6880 | auto *Param = | |||
| 6881 | cast_or_null<TemplateTemplateParmDecl>( | |||
| 6882 | Import(SubstPack->getParameterPack())); | |||
| 6883 | if (!Param) | |||
| 6884 | return {}; | |||
| 6885 | ||||
| 6886 | ASTNodeImporter Importer(*this); | |||
| 6887 | TemplateArgument ArgPack | |||
| 6888 | = Importer.ImportTemplateArgument(SubstPack->getArgumentPack()); | |||
| 6889 | if (ArgPack.isNull()) | |||
| 6890 | return {}; | |||
| 6891 | ||||
| 6892 | return ToContext.getSubstTemplateTemplateParmPack(Param, ArgPack); | |||
| 6893 | } | |||
| 6894 | } | |||
| 6895 | ||||
| 6896 | llvm_unreachable("Invalid template name kind")::llvm::llvm_unreachable_internal("Invalid template name kind" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/lib/AST/ASTImporter.cpp" , 6896); | |||
| 6897 | } | |||
| 6898 | ||||
| 6899 | SourceLocation ASTImporter::Import(SourceLocation FromLoc) { | |||
| 6900 | if (FromLoc.isInvalid()) | |||
| 6901 | return {}; | |||
| 6902 | ||||
| 6903 | SourceManager &FromSM = FromContext.getSourceManager(); | |||
| 6904 | ||||
| 6905 | // For now, map everything down to its file location, so that we | |||
| 6906 | // don't have to import macro expansions. | |||
| 6907 | // FIXME: Import macro expansions! | |||
| 6908 | FromLoc = FromSM.getFileLoc(FromLoc); | |||
| 6909 | std::pair<FileID, unsigned> Decomposed = FromSM.getDecomposedLoc(FromLoc); | |||
| 6910 | SourceManager &ToSM = ToContext.getSourceManager(); | |||
| 6911 | FileID ToFileID = Import(Decomposed.first); | |||
| 6912 | if (ToFileID.isInvalid()) | |||
| 6913 | return {}; | |||
| 6914 | SourceLocation ret = ToSM.getLocForStartOfFile(ToFileID) | |||
| 6915 | .getLocWithOffset(Decomposed.second); | |||
| 6916 | return ret; | |||
| 6917 | } | |||
| 6918 | ||||
| 6919 | SourceRange ASTImporter::Import(SourceRange FromRange) { | |||
| 6920 | return SourceRange(Import(FromRange.getBegin()), Import(FromRange.getEnd())); | |||
| 6921 | } | |||
| 6922 | ||||
| 6923 | FileID ASTImporter::Import(FileID FromID) { | |||
| 6924 | llvm::DenseMap<FileID, FileID>::iterator Pos | |||
| 6925 | = ImportedFileIDs.find(FromID); | |||
| 6926 | if (Pos != ImportedFileIDs.end()) | |||
| 6927 | return Pos->second; | |||
| 6928 | ||||
| 6929 | SourceManager &FromSM = FromContext.getSourceManager(); | |||
| 6930 | SourceManager &ToSM = ToContext.getSourceManager(); | |||
| 6931 | const SrcMgr::SLocEntry &FromSLoc = FromSM.getSLocEntry(FromID); | |||
| 6932 | assert(FromSLoc.isFile() && "Cannot handle macro expansions yet")(static_cast <bool> (FromSLoc.isFile() && "Cannot handle macro expansions yet" ) ? void (0) : __assert_fail ("FromSLoc.isFile() && \"Cannot handle macro expansions yet\"" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/lib/AST/ASTImporter.cpp" , 6932, __extension__ __PRETTY_FUNCTION__)); | |||
| 6933 | ||||
| 6934 | // Include location of this file. | |||
| 6935 | SourceLocation ToIncludeLoc = Import(FromSLoc.getFile().getIncludeLoc()); | |||
| 6936 | ||||
| 6937 | // Map the FileID for to the "to" source manager. | |||
| 6938 | FileID ToID; | |||
| 6939 | const SrcMgr::ContentCache *Cache = FromSLoc.getFile().getContentCache(); | |||
| 6940 | if (Cache->OrigEntry && Cache->OrigEntry->getDir()) { | |||
| 6941 | // FIXME: We probably want to use getVirtualFile(), so we don't hit the | |||
| 6942 | // disk again | |||
| 6943 | // FIXME: We definitely want to re-use the existing MemoryBuffer, rather | |||
| 6944 | // than mmap the files several times. | |||
| 6945 | const FileEntry *Entry = ToFileManager.getFile(Cache->OrigEntry->getName()); | |||
| 6946 | if (!Entry) | |||
| 6947 | return {}; | |||
| 6948 | ToID = ToSM.createFileID(Entry, ToIncludeLoc, | |||
| 6949 | FromSLoc.getFile().getFileCharacteristic()); | |||
| 6950 | } else { | |||
| 6951 | // FIXME: We want to re-use the existing MemoryBuffer! | |||
| 6952 | const llvm::MemoryBuffer * | |||
| 6953 | FromBuf = Cache->getBuffer(FromContext.getDiagnostics(), FromSM); | |||
| 6954 | std::unique_ptr<llvm::MemoryBuffer> ToBuf | |||
| 6955 | = llvm::MemoryBuffer::getMemBufferCopy(FromBuf->getBuffer(), | |||
| 6956 | FromBuf->getBufferIdentifier()); | |||
| 6957 | ToID = ToSM.createFileID(std::move(ToBuf), | |||
| 6958 | FromSLoc.getFile().getFileCharacteristic()); | |||
| 6959 | } | |||
| 6960 | ||||
| 6961 | ImportedFileIDs[FromID] = ToID; | |||
| 6962 | return ToID; | |||
| 6963 | } | |||
| 6964 | ||||
| 6965 | CXXCtorInitializer *ASTImporter::Import(CXXCtorInitializer *From) { | |||
| 6966 | Expr *ToExpr = Import(From->getInit()); | |||
| 6967 | if (!ToExpr && From->getInit()) | |||
| 6968 | return nullptr; | |||
| 6969 | ||||
| 6970 | if (From->isBaseInitializer()) { | |||
| 6971 | TypeSourceInfo *ToTInfo = Import(From->getTypeSourceInfo()); | |||
| 6972 | if (!ToTInfo && From->getTypeSourceInfo()) | |||
| 6973 | return nullptr; | |||
| 6974 | ||||
| 6975 | return new (ToContext) CXXCtorInitializer( | |||
| 6976 | ToContext, ToTInfo, From->isBaseVirtual(), Import(From->getLParenLoc()), | |||
| 6977 | ToExpr, Import(From->getRParenLoc()), | |||
| 6978 | From->isPackExpansion() ? Import(From->getEllipsisLoc()) | |||
| 6979 | : SourceLocation()); | |||
| 6980 | } else if (From->isMemberInitializer()) { | |||
| 6981 | auto *ToField = cast_or_null<FieldDecl>(Import(From->getMember())); | |||
| 6982 | if (!ToField && From->getMember()) | |||
| 6983 | return nullptr; | |||
| 6984 | ||||
| 6985 | return new (ToContext) CXXCtorInitializer( | |||
| 6986 | ToContext, ToField, Import(From->getMemberLocation()), | |||
| 6987 | Import(From->getLParenLoc()), ToExpr, Import(From->getRParenLoc())); | |||
| 6988 | } else if (From->isIndirectMemberInitializer()) { | |||
| 6989 | auto *ToIField = cast_or_null<IndirectFieldDecl>( | |||
| 6990 | Import(From->getIndirectMember())); | |||
| 6991 | if (!ToIField && From->getIndirectMember()) | |||
| 6992 | return nullptr; | |||
| 6993 | ||||
| 6994 | return new (ToContext) CXXCtorInitializer( | |||
| 6995 | ToContext, ToIField, Import(From->getMemberLocation()), | |||
| 6996 | Import(From->getLParenLoc()), ToExpr, Import(From->getRParenLoc())); | |||
| 6997 | } else if (From->isDelegatingInitializer()) { | |||
| 6998 | TypeSourceInfo *ToTInfo = Import(From->getTypeSourceInfo()); | |||
| 6999 | if (!ToTInfo && From->getTypeSourceInfo()) | |||
| 7000 | return nullptr; | |||
| 7001 | ||||
| 7002 | return new (ToContext) | |||
| 7003 | CXXCtorInitializer(ToContext, ToTInfo, Import(From->getLParenLoc()), | |||
| 7004 | ToExpr, Import(From->getRParenLoc())); | |||
| 7005 | } else { | |||
| 7006 | return nullptr; | |||
| 7007 | } | |||
| 7008 | } | |||
| 7009 | ||||
| 7010 | CXXBaseSpecifier *ASTImporter::Import(const CXXBaseSpecifier *BaseSpec) { | |||
| 7011 | auto Pos = ImportedCXXBaseSpecifiers.find(BaseSpec); | |||
| 7012 | if (Pos != ImportedCXXBaseSpecifiers.end()) | |||
| 7013 | return Pos->second; | |||
| 7014 | ||||
| 7015 | CXXBaseSpecifier *Imported = new (ToContext) CXXBaseSpecifier( | |||
| 7016 | Import(BaseSpec->getSourceRange()), | |||
| 7017 | BaseSpec->isVirtual(), BaseSpec->isBaseOfClass(), | |||
| 7018 | BaseSpec->getAccessSpecifierAsWritten(), | |||
| 7019 | Import(BaseSpec->getTypeSourceInfo()), | |||
| 7020 | Import(BaseSpec->getEllipsisLoc())); | |||
| 7021 | ImportedCXXBaseSpecifiers[BaseSpec] = Imported; | |||
| 7022 | return Imported; | |||
| 7023 | } | |||
| 7024 | ||||
| 7025 | void ASTImporter::ImportDefinition(Decl *From) { | |||
| 7026 | Decl *To = Import(From); | |||
| 7027 | if (!To) | |||
| 7028 | return; | |||
| 7029 | ||||
| 7030 | if (auto *FromDC = cast<DeclContext>(From)) { | |||
| 7031 | ASTNodeImporter Importer(*this); | |||
| 7032 | ||||
| 7033 | if (auto *ToRecord = dyn_cast<RecordDecl>(To)) { | |||
| 7034 | if (!ToRecord->getDefinition()) { | |||
| 7035 | Importer.ImportDefinition(cast<RecordDecl>(FromDC), ToRecord, | |||
| 7036 | ASTNodeImporter::IDK_Everything); | |||
| 7037 | return; | |||
| 7038 | } | |||
| 7039 | } | |||
| 7040 | ||||
| 7041 | if (auto *ToEnum = dyn_cast<EnumDecl>(To)) { | |||
| 7042 | if (!ToEnum->getDefinition()) { | |||
| 7043 | Importer.ImportDefinition(cast<EnumDecl>(FromDC), ToEnum, | |||
| 7044 | ASTNodeImporter::IDK_Everything); | |||
| 7045 | return; | |||
| 7046 | } | |||
| 7047 | } | |||
| 7048 | ||||
| 7049 | if (auto *ToIFace = dyn_cast<ObjCInterfaceDecl>(To)) { | |||
| 7050 | if (!ToIFace->getDefinition()) { | |||
| 7051 | Importer.ImportDefinition(cast<ObjCInterfaceDecl>(FromDC), ToIFace, | |||
| 7052 | ASTNodeImporter::IDK_Everything); | |||
| 7053 | return; | |||
| 7054 | } | |||
| 7055 | } | |||
| 7056 | ||||
| 7057 | if (auto *ToProto = dyn_cast<ObjCProtocolDecl>(To)) { | |||
| 7058 | if (!ToProto->getDefinition()) { | |||
| 7059 | Importer.ImportDefinition(cast<ObjCProtocolDecl>(FromDC), ToProto, | |||
| 7060 | ASTNodeImporter::IDK_Everything); | |||
| 7061 | return; | |||
| 7062 | } | |||
| 7063 | } | |||
| 7064 | ||||
| 7065 | Importer.ImportDeclContext(FromDC, true); | |||
| 7066 | } | |||
| 7067 | } | |||
| 7068 | ||||
| 7069 | DeclarationName ASTImporter::Import(DeclarationName FromName) { | |||
| 7070 | if (!FromName) | |||
| 7071 | return {}; | |||
| 7072 | ||||
| 7073 | switch (FromName.getNameKind()) { | |||
| 7074 | case DeclarationName::Identifier: | |||
| 7075 | return Import(FromName.getAsIdentifierInfo()); | |||
| 7076 | ||||
| 7077 | case DeclarationName::ObjCZeroArgSelector: | |||
| 7078 | case DeclarationName::ObjCOneArgSelector: | |||
| 7079 | case DeclarationName::ObjCMultiArgSelector: | |||
| 7080 | return Import(FromName.getObjCSelector()); | |||
| 7081 | ||||
| 7082 | case DeclarationName::CXXConstructorName: { | |||
| 7083 | QualType T = Import(FromName.getCXXNameType()); | |||
| 7084 | if (T.isNull()) | |||
| 7085 | return {}; | |||
| 7086 | ||||
| 7087 | return ToContext.DeclarationNames.getCXXConstructorName( | |||
| 7088 | ToContext.getCanonicalType(T)); | |||
| 7089 | } | |||
| 7090 | ||||
| 7091 | case DeclarationName::CXXDestructorName: { | |||
| 7092 | QualType T = Import(FromName.getCXXNameType()); | |||
| 7093 | if (T.isNull()) | |||
| 7094 | return {}; | |||
| 7095 | ||||
| 7096 | return ToContext.DeclarationNames.getCXXDestructorName( | |||
| 7097 | ToContext.getCanonicalType(T)); | |||
| 7098 | } | |||
| 7099 | ||||
| 7100 | case DeclarationName::CXXDeductionGuideName: { | |||
| 7101 | auto *Template = cast_or_null<TemplateDecl>( | |||
| 7102 | Import(FromName.getCXXDeductionGuideTemplate())); | |||
| 7103 | if (!Template) | |||
| 7104 | return {}; | |||
| 7105 | return ToContext.DeclarationNames.getCXXDeductionGuideName(Template); | |||
| 7106 | } | |||
| 7107 | ||||
| 7108 | case DeclarationName::CXXConversionFunctionName: { | |||
| 7109 | QualType T = Import(FromName.getCXXNameType()); | |||
| 7110 | if (T.isNull()) | |||
| 7111 | return {}; | |||
| 7112 | ||||
| 7113 | return ToContext.DeclarationNames.getCXXConversionFunctionName( | |||
| 7114 | ToContext.getCanonicalType(T)); | |||
| 7115 | } | |||
| 7116 | ||||
| 7117 | case DeclarationName::CXXOperatorName: | |||
| 7118 | return ToContext.DeclarationNames.getCXXOperatorName( | |||
| 7119 | FromName.getCXXOverloadedOperator()); | |||
| 7120 | ||||
| 7121 | case DeclarationName::CXXLiteralOperatorName: | |||
| 7122 | return ToContext.DeclarationNames.getCXXLiteralOperatorName( | |||
| 7123 | Import(FromName.getCXXLiteralIdentifier())); | |||
| 7124 | ||||
| 7125 | case DeclarationName::CXXUsingDirective: | |||
| 7126 | // FIXME: STATICS! | |||
| 7127 | return DeclarationName::getUsingDirectiveName(); | |||
| 7128 | } | |||
| 7129 | ||||
| 7130 | llvm_unreachable("Invalid DeclarationName Kind!")::llvm::llvm_unreachable_internal("Invalid DeclarationName Kind!" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/lib/AST/ASTImporter.cpp" , 7130); | |||
| 7131 | } | |||
| 7132 | ||||
| 7133 | IdentifierInfo *ASTImporter::Import(const IdentifierInfo *FromId) { | |||
| 7134 | if (!FromId) | |||
| 7135 | return nullptr; | |||
| 7136 | ||||
| 7137 | IdentifierInfo *ToId = &ToContext.Idents.get(FromId->getName()); | |||
| 7138 | ||||
| 7139 | if (!ToId->getBuiltinID() && FromId->getBuiltinID()) | |||
| 7140 | ToId->setBuiltinID(FromId->getBuiltinID()); | |||
| 7141 | ||||
| 7142 | return ToId; | |||
| 7143 | } | |||
| 7144 | ||||
| 7145 | Selector ASTImporter::Import(Selector FromSel) { | |||
| 7146 | if (FromSel.isNull()) | |||
| 7147 | return {}; | |||
| 7148 | ||||
| 7149 | SmallVector<IdentifierInfo *, 4> Idents; | |||
| 7150 | Idents.push_back(Import(FromSel.getIdentifierInfoForSlot(0))); | |||
| 7151 | for (unsigned I = 1, N = FromSel.getNumArgs(); I < N; ++I) | |||
| 7152 | Idents.push_back(Import(FromSel.getIdentifierInfoForSlot(I))); | |||
| 7153 | return ToContext.Selectors.getSelector(FromSel.getNumArgs(), Idents.data()); | |||
| 7154 | } | |||
| 7155 | ||||
| 7156 | DeclarationName ASTImporter::HandleNameConflict(DeclarationName Name, | |||
| 7157 | DeclContext *DC, | |||
| 7158 | unsigned IDNS, | |||
| 7159 | NamedDecl **Decls, | |||
| 7160 | unsigned NumDecls) { | |||
| 7161 | return Name; | |||
| 7162 | } | |||
| 7163 | ||||
| 7164 | DiagnosticBuilder ASTImporter::ToDiag(SourceLocation Loc, unsigned DiagID) { | |||
| 7165 | if (LastDiagFromFrom) | |||
| 7166 | ToContext.getDiagnostics().notePriorDiagnosticFrom( | |||
| 7167 | FromContext.getDiagnostics()); | |||
| 7168 | LastDiagFromFrom = false; | |||
| 7169 | return ToContext.getDiagnostics().Report(Loc, DiagID); | |||
| 7170 | } | |||
| 7171 | ||||
| 7172 | DiagnosticBuilder ASTImporter::FromDiag(SourceLocation Loc, unsigned DiagID) { | |||
| 7173 | if (!LastDiagFromFrom) | |||
| 7174 | FromContext.getDiagnostics().notePriorDiagnosticFrom( | |||
| 7175 | ToContext.getDiagnostics()); | |||
| 7176 | LastDiagFromFrom = true; | |||
| 7177 | return FromContext.getDiagnostics().Report(Loc, DiagID); | |||
| 7178 | } | |||
| 7179 | ||||
| 7180 | void ASTImporter::CompleteDecl (Decl *D) { | |||
| 7181 | if (auto *ID = dyn_cast<ObjCInterfaceDecl>(D)) { | |||
| 7182 | if (!ID->getDefinition()) | |||
| 7183 | ID->startDefinition(); | |||
| 7184 | } | |||
| 7185 | else if (auto *PD = dyn_cast<ObjCProtocolDecl>(D)) { | |||
| 7186 | if (!PD->getDefinition()) | |||
| 7187 | PD->startDefinition(); | |||
| 7188 | } | |||
| 7189 | else if (auto *TD = dyn_cast<TagDecl>(D)) { | |||
| 7190 | if (!TD->getDefinition() && !TD->isBeingDefined()) { | |||
| 7191 | TD->startDefinition(); | |||
| 7192 | TD->setCompleteDefinition(true); | |||
| 7193 | } | |||
| 7194 | } | |||
| 7195 | else { | |||
| 7196 | assert(0 && "CompleteDecl called on a Decl that can't be completed")(static_cast <bool> (0 && "CompleteDecl called on a Decl that can't be completed" ) ? void (0) : __assert_fail ("0 && \"CompleteDecl called on a Decl that can't be completed\"" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/lib/AST/ASTImporter.cpp" , 7196, __extension__ __PRETTY_FUNCTION__)); | |||
| 7197 | } | |||
| 7198 | } | |||
| 7199 | ||||
| 7200 | Decl *ASTImporter::Imported(Decl *From, Decl *To) { | |||
| 7201 | if (From->hasAttrs()) { | |||
| 7202 | for (auto *FromAttr : From->getAttrs()) | |||
| 7203 | To->addAttr(FromAttr->clone(To->getASTContext())); | |||
| 7204 | } | |||
| 7205 | if (From->isUsed()) { | |||
| 7206 | To->setIsUsed(); | |||
| 7207 | } | |||
| 7208 | if (From->isImplicit()) { | |||
| 7209 | To->setImplicit(); | |||
| 7210 | } | |||
| 7211 | ImportedDecls[From] = To; | |||
| 7212 | return To; | |||
| 7213 | } | |||
| 7214 | ||||
| 7215 | bool ASTImporter::IsStructurallyEquivalent(QualType From, QualType To, | |||
| 7216 | bool Complain) { | |||
| 7217 | llvm::DenseMap<const Type *, const Type *>::iterator Pos | |||
| 7218 | = ImportedTypes.find(From.getTypePtr()); | |||
| 7219 | if (Pos != ImportedTypes.end() && ToContext.hasSameType(Import(From), To)) | |||
| 7220 | return true; | |||
| 7221 | ||||
| 7222 | StructuralEquivalenceContext Ctx(FromContext, ToContext, NonEquivalentDecls, | |||
| 7223 | false, Complain); | |||
| 7224 | return Ctx.IsStructurallyEquivalent(From, To); | |||
| 7225 | } |
| 1 | //===- llvm/Support/Casting.h - Allow flexible, checked, casts --*- C++ -*-===// |
| 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | // |
| 10 | // This file defines the isa<X>(), cast<X>(), dyn_cast<X>(), cast_or_null<X>(), |
| 11 | // and dyn_cast_or_null<X>() templates. |
| 12 | // |
| 13 | //===----------------------------------------------------------------------===// |
| 14 | |
| 15 | #ifndef LLVM_SUPPORT_CASTING_H |
| 16 | #define LLVM_SUPPORT_CASTING_H |
| 17 | |
| 18 | #include "llvm/Support/Compiler.h" |
| 19 | #include "llvm/Support/type_traits.h" |
| 20 | #include <cassert> |
| 21 | #include <memory> |
| 22 | #include <type_traits> |
| 23 | |
| 24 | namespace llvm { |
| 25 | |
| 26 | //===----------------------------------------------------------------------===// |
| 27 | // isa<x> Support Templates |
| 28 | //===----------------------------------------------------------------------===// |
| 29 | |
| 30 | // Define a template that can be specialized by smart pointers to reflect the |
| 31 | // fact that they are automatically dereferenced, and are not involved with the |
| 32 | // template selection process... the default implementation is a noop. |
| 33 | // |
| 34 | template<typename From> struct simplify_type { |
| 35 | using SimpleType = From; // The real type this represents... |
| 36 | |
| 37 | // An accessor to get the real value... |
| 38 | static SimpleType &getSimplifiedValue(From &Val) { return Val; } |
| 39 | }; |
| 40 | |
| 41 | template<typename From> struct simplify_type<const From> { |
| 42 | using NonConstSimpleType = typename simplify_type<From>::SimpleType; |
| 43 | using SimpleType = |
| 44 | typename add_const_past_pointer<NonConstSimpleType>::type; |
| 45 | using RetType = |
| 46 | typename add_lvalue_reference_if_not_pointer<SimpleType>::type; |
| 47 | |
| 48 | static RetType getSimplifiedValue(const From& Val) { |
| 49 | return simplify_type<From>::getSimplifiedValue(const_cast<From&>(Val)); |
| 50 | } |
| 51 | }; |
| 52 | |
| 53 | // The core of the implementation of isa<X> is here; To and From should be |
| 54 | // the names of classes. This template can be specialized to customize the |
| 55 | // implementation of isa<> without rewriting it from scratch. |
| 56 | template <typename To, typename From, typename Enabler = void> |
| 57 | struct isa_impl { |
| 58 | static inline bool doit(const From &Val) { |
| 59 | return To::classof(&Val); |
| 60 | } |
| 61 | }; |
| 62 | |
| 63 | /// \brief Always allow upcasts, and perform no dynamic check for them. |
| 64 | template <typename To, typename From> |
| 65 | struct isa_impl< |
| 66 | To, From, typename std::enable_if<std::is_base_of<To, From>::value>::type> { |
| 67 | static inline bool doit(const From &) { return true; } |
| 68 | }; |
| 69 | |
| 70 | template <typename To, typename From> struct isa_impl_cl { |
| 71 | static inline bool doit(const From &Val) { |
| 72 | return isa_impl<To, From>::doit(Val); |
| 73 | } |
| 74 | }; |
| 75 | |
| 76 | template <typename To, typename From> struct isa_impl_cl<To, const From> { |
| 77 | static inline bool doit(const From &Val) { |
| 78 | return isa_impl<To, From>::doit(Val); |
| 79 | } |
| 80 | }; |
| 81 | |
| 82 | template <typename To, typename From> |
| 83 | struct isa_impl_cl<To, const std::unique_ptr<From>> { |
| 84 | static inline bool doit(const std::unique_ptr<From> &Val) { |
| 85 | assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer" ) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\"" , "/build/llvm-toolchain-snapshot-7~svn329677/include/llvm/Support/Casting.h" , 85, __extension__ __PRETTY_FUNCTION__)); |
| 86 | return isa_impl_cl<To, From>::doit(*Val); |
| 87 | } |
| 88 | }; |
| 89 | |
| 90 | template <typename To, typename From> struct isa_impl_cl<To, From*> { |
| 91 | static inline bool doit(const From *Val) { |
| 92 | assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer" ) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\"" , "/build/llvm-toolchain-snapshot-7~svn329677/include/llvm/Support/Casting.h" , 92, __extension__ __PRETTY_FUNCTION__)); |
| 93 | return isa_impl<To, From>::doit(*Val); |
| 94 | } |
| 95 | }; |
| 96 | |
| 97 | template <typename To, typename From> struct isa_impl_cl<To, From*const> { |
| 98 | static inline bool doit(const From *Val) { |
| 99 | assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer" ) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\"" , "/build/llvm-toolchain-snapshot-7~svn329677/include/llvm/Support/Casting.h" , 99, __extension__ __PRETTY_FUNCTION__)); |
| 100 | return isa_impl<To, From>::doit(*Val); |
| 101 | } |
| 102 | }; |
| 103 | |
| 104 | template <typename To, typename From> struct isa_impl_cl<To, const From*> { |
| 105 | static inline bool doit(const From *Val) { |
| 106 | assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer" ) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\"" , "/build/llvm-toolchain-snapshot-7~svn329677/include/llvm/Support/Casting.h" , 106, __extension__ __PRETTY_FUNCTION__)); |
| 107 | return isa_impl<To, From>::doit(*Val); |
| 108 | } |
| 109 | }; |
| 110 | |
| 111 | template <typename To, typename From> struct isa_impl_cl<To, const From*const> { |
| 112 | static inline bool doit(const From *Val) { |
| 113 | assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer" ) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\"" , "/build/llvm-toolchain-snapshot-7~svn329677/include/llvm/Support/Casting.h" , 113, __extension__ __PRETTY_FUNCTION__)); |
| 114 | return isa_impl<To, From>::doit(*Val); |
| 115 | } |
| 116 | }; |
| 117 | |
| 118 | template<typename To, typename From, typename SimpleFrom> |
| 119 | struct isa_impl_wrap { |
| 120 | // When From != SimplifiedType, we can simplify the type some more by using |
| 121 | // the simplify_type template. |
| 122 | static bool doit(const From &Val) { |
| 123 | return isa_impl_wrap<To, SimpleFrom, |
| 124 | typename simplify_type<SimpleFrom>::SimpleType>::doit( |
| 125 | simplify_type<const From>::getSimplifiedValue(Val)); |
| 126 | } |
| 127 | }; |
| 128 | |
| 129 | template<typename To, typename FromTy> |
| 130 | struct isa_impl_wrap<To, FromTy, FromTy> { |
| 131 | // When From == SimpleType, we are as simple as we are going to get. |
| 132 | static bool doit(const FromTy &Val) { |
| 133 | return isa_impl_cl<To,FromTy>::doit(Val); |
| 134 | } |
| 135 | }; |
| 136 | |
| 137 | // isa<X> - Return true if the parameter to the template is an instance of the |
| 138 | // template type argument. Used like this: |
| 139 | // |
| 140 | // if (isa<Type>(myVal)) { ... } |
| 141 | // |
| 142 | template <class X, class Y> LLVM_NODISCARD[[clang::warn_unused_result]] inline bool isa(const Y &Val) { |
| 143 | return isa_impl_wrap<X, const Y, |
| 144 | typename simplify_type<const Y>::SimpleType>::doit(Val); |
| 145 | } |
| 146 | |
| 147 | //===----------------------------------------------------------------------===// |
| 148 | // cast<x> Support Templates |
| 149 | //===----------------------------------------------------------------------===// |
| 150 | |
| 151 | template<class To, class From> struct cast_retty; |
| 152 | |
| 153 | // Calculate what type the 'cast' function should return, based on a requested |
| 154 | // type of To and a source type of From. |
| 155 | template<class To, class From> struct cast_retty_impl { |
| 156 | using ret_type = To &; // Normal case, return Ty& |
| 157 | }; |
| 158 | template<class To, class From> struct cast_retty_impl<To, const From> { |
| 159 | using ret_type = const To &; // Normal case, return Ty& |
| 160 | }; |
| 161 | |
| 162 | template<class To, class From> struct cast_retty_impl<To, From*> { |
| 163 | using ret_type = To *; // Pointer arg case, return Ty* |
| 164 | }; |
| 165 | |
| 166 | template<class To, class From> struct cast_retty_impl<To, const From*> { |
| 167 | using ret_type = const To *; // Constant pointer arg case, return const Ty* |
| 168 | }; |
| 169 | |
| 170 | template<class To, class From> struct cast_retty_impl<To, const From*const> { |
| 171 | using ret_type = const To *; // Constant pointer arg case, return const Ty* |
| 172 | }; |
| 173 | |
| 174 | template <class To, class From> |
| 175 | struct cast_retty_impl<To, std::unique_ptr<From>> { |
| 176 | private: |
| 177 | using PointerType = typename cast_retty_impl<To, From *>::ret_type; |
| 178 | using ResultType = typename std::remove_pointer<PointerType>::type; |
| 179 | |
| 180 | public: |
| 181 | using ret_type = std::unique_ptr<ResultType>; |
| 182 | }; |
| 183 | |
| 184 | template<class To, class From, class SimpleFrom> |
| 185 | struct cast_retty_wrap { |
| 186 | // When the simplified type and the from type are not the same, use the type |
| 187 | // simplifier to reduce the type, then reuse cast_retty_impl to get the |
| 188 | // resultant type. |
| 189 | using ret_type = typename cast_retty<To, SimpleFrom>::ret_type; |
| 190 | }; |
| 191 | |
| 192 | template<class To, class FromTy> |
| 193 | struct cast_retty_wrap<To, FromTy, FromTy> { |
| 194 | // When the simplified type is equal to the from type, use it directly. |
| 195 | using ret_type = typename cast_retty_impl<To,FromTy>::ret_type; |
| 196 | }; |
| 197 | |
| 198 | template<class To, class From> |
| 199 | struct cast_retty { |
| 200 | using ret_type = typename cast_retty_wrap< |
| 201 | To, From, typename simplify_type<From>::SimpleType>::ret_type; |
| 202 | }; |
| 203 | |
| 204 | // Ensure the non-simple values are converted using the simplify_type template |
| 205 | // that may be specialized by smart pointers... |
| 206 | // |
| 207 | template<class To, class From, class SimpleFrom> struct cast_convert_val { |
| 208 | // This is not a simple type, use the template to simplify it... |
| 209 | static typename cast_retty<To, From>::ret_type doit(From &Val) { |
| 210 | return cast_convert_val<To, SimpleFrom, |
| 211 | typename simplify_type<SimpleFrom>::SimpleType>::doit( |
| 212 | simplify_type<From>::getSimplifiedValue(Val)); |
| 213 | } |
| 214 | }; |
| 215 | |
| 216 | template<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> { |
| 217 | // This _is_ a simple type, just cast it. |
| 218 | static typename cast_retty<To, FromTy>::ret_type doit(const FromTy &Val) { |
| 219 | typename cast_retty<To, FromTy>::ret_type Res2 |
| 220 | = (typename cast_retty<To, FromTy>::ret_type)const_cast<FromTy&>(Val); |
| 221 | return Res2; |
| 222 | } |
| 223 | }; |
| 224 | |
| 225 | template <class X> struct is_simple_type { |
| 226 | static const bool value = |
| 227 | std::is_same<X, typename simplify_type<X>::SimpleType>::value; |
| 228 | }; |
| 229 | |
| 230 | // cast<X> - Return the argument parameter cast to the specified type. This |
| 231 | // casting operator asserts that the type is correct, so it does not return null |
| 232 | // on failure. It does not allow a null argument (use cast_or_null for that). |
| 233 | // It is typically used like this: |
| 234 | // |
| 235 | // cast<Instruction>(myVal)->getParent() |
| 236 | // |
| 237 | template <class X, class Y> |
| 238 | inline typename std::enable_if<!is_simple_type<Y>::value, |
| 239 | typename cast_retty<X, const Y>::ret_type>::type |
| 240 | cast(const Y &Val) { |
| 241 | assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast<Ty>() argument of incompatible type!" ) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast<Ty>() argument of incompatible type!\"" , "/build/llvm-toolchain-snapshot-7~svn329677/include/llvm/Support/Casting.h" , 241, __extension__ __PRETTY_FUNCTION__)); |
| 242 | return cast_convert_val< |
| 243 | X, const Y, typename simplify_type<const Y>::SimpleType>::doit(Val); |
| 244 | } |
| 245 | |
| 246 | template <class X, class Y> |
| 247 | inline typename cast_retty<X, Y>::ret_type cast(Y &Val) { |
| 248 | assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast<Ty>() argument of incompatible type!" ) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast<Ty>() argument of incompatible type!\"" , "/build/llvm-toolchain-snapshot-7~svn329677/include/llvm/Support/Casting.h" , 248, __extension__ __PRETTY_FUNCTION__)); |
| 249 | return cast_convert_val<X, Y, |
| 250 | typename simplify_type<Y>::SimpleType>::doit(Val); |
| 251 | } |
| 252 | |
| 253 | template <class X, class Y> |
| 254 | inline typename cast_retty<X, Y *>::ret_type cast(Y *Val) { |
| 255 | assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast<Ty>() argument of incompatible type!" ) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast<Ty>() argument of incompatible type!\"" , "/build/llvm-toolchain-snapshot-7~svn329677/include/llvm/Support/Casting.h" , 255, __extension__ __PRETTY_FUNCTION__)); |
| 256 | return cast_convert_val<X, Y*, |
| 257 | typename simplify_type<Y*>::SimpleType>::doit(Val); |
| 258 | } |
| 259 | |
| 260 | template <class X, class Y> |
| 261 | inline typename cast_retty<X, std::unique_ptr<Y>>::ret_type |
| 262 | cast(std::unique_ptr<Y> &&Val) { |
| 263 | assert(isa<X>(Val.get()) && "cast<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val.get()) && "cast<Ty>() argument of incompatible type!") ? void (0 ) : __assert_fail ("isa<X>(Val.get()) && \"cast<Ty>() argument of incompatible type!\"" , "/build/llvm-toolchain-snapshot-7~svn329677/include/llvm/Support/Casting.h" , 263, __extension__ __PRETTY_FUNCTION__)); |
| 264 | using ret_type = typename cast_retty<X, std::unique_ptr<Y>>::ret_type; |
| 265 | return ret_type( |
| 266 | cast_convert_val<X, Y *, typename simplify_type<Y *>::SimpleType>::doit( |
| 267 | Val.release())); |
| 268 | } |
| 269 | |
| 270 | // cast_or_null<X> - Functionally identical to cast, except that a null value is |
| 271 | // accepted. |
| 272 | // |
| 273 | template <class X, class Y> |
| 274 | LLVM_NODISCARD[[clang::warn_unused_result]] inline |
| 275 | typename std::enable_if<!is_simple_type<Y>::value, |
| 276 | typename cast_retty<X, const Y>::ret_type>::type |
| 277 | cast_or_null(const Y &Val) { |
| 278 | if (!Val) |
| 279 | return nullptr; |
| 280 | assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!" ) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast_or_null<Ty>() argument of incompatible type!\"" , "/build/llvm-toolchain-snapshot-7~svn329677/include/llvm/Support/Casting.h" , 280, __extension__ __PRETTY_FUNCTION__)); |
| 281 | return cast<X>(Val); |
| 282 | } |
| 283 | |
| 284 | template <class X, class Y> |
| 285 | LLVM_NODISCARD[[clang::warn_unused_result]] inline |
| 286 | typename std::enable_if<!is_simple_type<Y>::value, |
| 287 | typename cast_retty<X, Y>::ret_type>::type |
| 288 | cast_or_null(Y &Val) { |
| 289 | if (!Val) |
| 290 | return nullptr; |
| 291 | assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!" ) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast_or_null<Ty>() argument of incompatible type!\"" , "/build/llvm-toolchain-snapshot-7~svn329677/include/llvm/Support/Casting.h" , 291, __extension__ __PRETTY_FUNCTION__)); |
| 292 | return cast<X>(Val); |
| 293 | } |
| 294 | |
| 295 | template <class X, class Y> |
| 296 | LLVM_NODISCARD[[clang::warn_unused_result]] inline typename cast_retty<X, Y *>::ret_type |
| 297 | cast_or_null(Y *Val) { |
| 298 | if (!Val) return nullptr; |
| 299 | assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!" ) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast_or_null<Ty>() argument of incompatible type!\"" , "/build/llvm-toolchain-snapshot-7~svn329677/include/llvm/Support/Casting.h" , 299, __extension__ __PRETTY_FUNCTION__)); |
| 300 | return cast<X>(Val); |
| 301 | } |
| 302 | |
| 303 | template <class X, class Y> |
| 304 | inline typename cast_retty<X, std::unique_ptr<Y>>::ret_type |
| 305 | cast_or_null(std::unique_ptr<Y> &&Val) { |
| 306 | if (!Val) |
| 307 | return nullptr; |
| 308 | return cast<X>(std::move(Val)); |
| 309 | } |
| 310 | |
| 311 | // dyn_cast<X> - Return the argument parameter cast to the specified type. This |
| 312 | // casting operator returns null if the argument is of the wrong type, so it can |
| 313 | // be used to test for a type as well as cast if successful. This should be |
| 314 | // used in the context of an if statement like this: |
| 315 | // |
| 316 | // if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... } |
| 317 | // |
| 318 | |
| 319 | template <class X, class Y> |
| 320 | LLVM_NODISCARD[[clang::warn_unused_result]] inline |
| 321 | typename std::enable_if<!is_simple_type<Y>::value, |
| 322 | typename cast_retty<X, const Y>::ret_type>::type |
| 323 | dyn_cast(const Y &Val) { |
| 324 | return isa<X>(Val) ? cast<X>(Val) : nullptr; |
| 325 | } |
| 326 | |
| 327 | template <class X, class Y> |
| 328 | LLVM_NODISCARD[[clang::warn_unused_result]] inline typename cast_retty<X, Y>::ret_type dyn_cast(Y &Val) { |
| 329 | return isa<X>(Val) ? cast<X>(Val) : nullptr; |
| 330 | } |
| 331 | |
| 332 | template <class X, class Y> |
| 333 | LLVM_NODISCARD[[clang::warn_unused_result]] inline typename cast_retty<X, Y *>::ret_type dyn_cast(Y *Val) { |
| 334 | return isa<X>(Val) ? cast<X>(Val) : nullptr; |
| 335 | } |
| 336 | |
| 337 | // dyn_cast_or_null<X> - Functionally identical to dyn_cast, except that a null |
| 338 | // value is accepted. |
| 339 | // |
| 340 | template <class X, class Y> |
| 341 | LLVM_NODISCARD[[clang::warn_unused_result]] inline |
| 342 | typename std::enable_if<!is_simple_type<Y>::value, |
| 343 | typename cast_retty<X, const Y>::ret_type>::type |
| 344 | dyn_cast_or_null(const Y &Val) { |
| 345 | return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr; |
| 346 | } |
| 347 | |
| 348 | template <class X, class Y> |
| 349 | LLVM_NODISCARD[[clang::warn_unused_result]] inline |
| 350 | typename std::enable_if<!is_simple_type<Y>::value, |
| 351 | typename cast_retty<X, Y>::ret_type>::type |
| 352 | dyn_cast_or_null(Y &Val) { |
| 353 | return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr; |
| 354 | } |
| 355 | |
| 356 | template <class X, class Y> |
| 357 | LLVM_NODISCARD[[clang::warn_unused_result]] inline typename cast_retty<X, Y *>::ret_type |
| 358 | dyn_cast_or_null(Y *Val) { |
| 359 | return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr; |
| 360 | } |
| 361 | |
| 362 | // unique_dyn_cast<X> - Given a unique_ptr<Y>, try to return a unique_ptr<X>, |
| 363 | // taking ownership of the input pointer iff isa<X>(Val) is true. If the |
| 364 | // cast is successful, From refers to nullptr on exit and the casted value |
| 365 | // is returned. If the cast is unsuccessful, the function returns nullptr |
| 366 | // and From is unchanged. |
| 367 | template <class X, class Y> |
| 368 | LLVM_NODISCARD[[clang::warn_unused_result]] inline auto unique_dyn_cast(std::unique_ptr<Y> &Val) |
| 369 | -> decltype(cast<X>(Val)) { |
| 370 | if (!isa<X>(Val)) |
| 371 | return nullptr; |
| 372 | return cast<X>(std::move(Val)); |
| 373 | } |
| 374 | |
| 375 | template <class X, class Y> |
| 376 | LLVM_NODISCARD[[clang::warn_unused_result]] inline auto unique_dyn_cast(std::unique_ptr<Y> &&Val) |
| 377 | -> decltype(cast<X>(Val)) { |
| 378 | return unique_dyn_cast<X, Y>(Val); |
| 379 | } |
| 380 | |
| 381 | // dyn_cast_or_null<X> - Functionally identical to unique_dyn_cast, except that |
| 382 | // a null value is accepted. |
| 383 | template <class X, class Y> |
| 384 | LLVM_NODISCARD[[clang::warn_unused_result]] inline auto unique_dyn_cast_or_null(std::unique_ptr<Y> &Val) |
| 385 | -> decltype(cast<X>(Val)) { |
| 386 | if (!Val) |
| 387 | return nullptr; |
| 388 | return unique_dyn_cast<X, Y>(Val); |
| 389 | } |
| 390 | |
| 391 | template <class X, class Y> |
| 392 | LLVM_NODISCARD[[clang::warn_unused_result]] inline auto unique_dyn_cast_or_null(std::unique_ptr<Y> &&Val) |
| 393 | -> decltype(cast<X>(Val)) { |
| 394 | return unique_dyn_cast_or_null<X, Y>(Val); |
| 395 | } |
| 396 | |
| 397 | } // end namespace llvm |
| 398 | |
| 399 | #endif // LLVM_SUPPORT_CASTING_H |
| 1 | //===- ExprCXX.h - Classes for representing expressions ---------*- C++ -*-===// | |||
| 2 | // | |||
| 3 | // The LLVM Compiler Infrastructure | |||
| 4 | // | |||
| 5 | // This file is distributed under the University of Illinois Open Source | |||
| 6 | // License. See LICENSE.TXT for details. | |||
| 7 | // | |||
| 8 | //===----------------------------------------------------------------------===// | |||
| 9 | // | |||
| 10 | /// \file | |||
| 11 | /// \brief Defines the clang::Expr interface and subclasses for C++ expressions. | |||
| 12 | // | |||
| 13 | //===----------------------------------------------------------------------===// | |||
| 14 | ||||
| 15 | #ifndef LLVM_CLANG_AST_EXPRCXX_H | |||
| 16 | #define LLVM_CLANG_AST_EXPRCXX_H | |||
| 17 | ||||
| 18 | #include "clang/AST/Decl.h" | |||
| 19 | #include "clang/AST/DeclBase.h" | |||
| 20 | #include "clang/AST/DeclCXX.h" | |||
| 21 | #include "clang/AST/DeclarationName.h" | |||
| 22 | #include "clang/AST/Expr.h" | |||
| 23 | #include "clang/AST/NestedNameSpecifier.h" | |||
| 24 | #include "clang/AST/OperationKinds.h" | |||
| 25 | #include "clang/AST/Stmt.h" | |||
| 26 | #include "clang/AST/TemplateBase.h" | |||
| 27 | #include "clang/AST/Type.h" | |||
| 28 | #include "clang/AST/UnresolvedSet.h" | |||
| 29 | #include "clang/Basic/ExceptionSpecificationType.h" | |||
| 30 | #include "clang/Basic/ExpressionTraits.h" | |||
| 31 | #include "clang/Basic/LLVM.h" | |||
| 32 | #include "clang/Basic/Lambda.h" | |||
| 33 | #include "clang/Basic/LangOptions.h" | |||
| 34 | #include "clang/Basic/OperatorKinds.h" | |||
| 35 | #include "clang/Basic/SourceLocation.h" | |||
| 36 | #include "clang/Basic/Specifiers.h" | |||
| 37 | #include "clang/Basic/TypeTraits.h" | |||
| 38 | #include "llvm/ADT/ArrayRef.h" | |||
| 39 | #include "llvm/ADT/None.h" | |||
| 40 | #include "llvm/ADT/Optional.h" | |||
| 41 | #include "llvm/ADT/PointerUnion.h" | |||
| 42 | #include "llvm/ADT/StringRef.h" | |||
| 43 | #include "llvm/ADT/iterator_range.h" | |||
| 44 | #include "llvm/Support/Casting.h" | |||
| 45 | #include "llvm/Support/Compiler.h" | |||
| 46 | #include "llvm/Support/TrailingObjects.h" | |||
| 47 | #include <cassert> | |||
| 48 | #include <cstddef> | |||
| 49 | #include <cstdint> | |||
| 50 | #include <memory> | |||
| 51 | ||||
| 52 | namespace clang { | |||
| 53 | ||||
| 54 | class ASTContext; | |||
| 55 | class DeclAccessPair; | |||
| 56 | class IdentifierInfo; | |||
| 57 | class LambdaCapture; | |||
| 58 | class NonTypeTemplateParmDecl; | |||
| 59 | class TemplateParameterList; | |||
| 60 | ||||
| 61 | //===--------------------------------------------------------------------===// | |||
| 62 | // C++ Expressions. | |||
| 63 | //===--------------------------------------------------------------------===// | |||
| 64 | ||||
| 65 | /// \brief A call to an overloaded operator written using operator | |||
| 66 | /// syntax. | |||
| 67 | /// | |||
| 68 | /// Represents a call to an overloaded operator written using operator | |||
| 69 | /// syntax, e.g., "x + y" or "*p". While semantically equivalent to a | |||
| 70 | /// normal call, this AST node provides better information about the | |||
| 71 | /// syntactic representation of the call. | |||
| 72 | /// | |||
| 73 | /// In a C++ template, this expression node kind will be used whenever | |||
| 74 | /// any of the arguments are type-dependent. In this case, the | |||
| 75 | /// function itself will be a (possibly empty) set of functions and | |||
| 76 | /// function templates that were found by name lookup at template | |||
| 77 | /// definition time. | |||
| 78 | class CXXOperatorCallExpr : public CallExpr { | |||
| 79 | /// \brief The overloaded operator. | |||
| 80 | OverloadedOperatorKind Operator; | |||
| 81 | ||||
| 82 | SourceRange Range; | |||
| 83 | ||||
| 84 | // Only meaningful for floating point types. | |||
| 85 | FPOptions FPFeatures; | |||
| 86 | ||||
| 87 | SourceRange getSourceRangeImpl() const LLVM_READONLY__attribute__((__pure__)); | |||
| 88 | ||||
| 89 | public: | |||
| 90 | friend class ASTStmtReader; | |||
| 91 | friend class ASTStmtWriter; | |||
| 92 | ||||
| 93 | CXXOperatorCallExpr(ASTContext& C, OverloadedOperatorKind Op, Expr *fn, | |||
| 94 | ArrayRef<Expr*> args, QualType t, ExprValueKind VK, | |||
| 95 | SourceLocation operatorloc, FPOptions FPFeatures) | |||
| 96 | : CallExpr(C, CXXOperatorCallExprClass, fn, args, t, VK, operatorloc), | |||
| 97 | Operator(Op), FPFeatures(FPFeatures) { | |||
| 98 | Range = getSourceRangeImpl(); | |||
| 99 | } | |||
| 100 | ||||
| 101 | explicit CXXOperatorCallExpr(ASTContext& C, EmptyShell Empty) | |||
| 102 | : CallExpr(C, CXXOperatorCallExprClass, Empty) {} | |||
| 103 | ||||
| 104 | /// \brief Returns the kind of overloaded operator that this | |||
| 105 | /// expression refers to. | |||
| 106 | OverloadedOperatorKind getOperator() const { return Operator; } | |||
| 107 | ||||
| 108 | static bool isAssignmentOp(OverloadedOperatorKind Opc) { | |||
| 109 | return Opc == OO_Equal || Opc == OO_StarEqual || | |||
| 110 | Opc == OO_SlashEqual || Opc == OO_PercentEqual || | |||
| 111 | Opc == OO_PlusEqual || Opc == OO_MinusEqual || | |||
| 112 | Opc == OO_LessLessEqual || Opc == OO_GreaterGreaterEqual || | |||
| 113 | Opc == OO_AmpEqual || Opc == OO_CaretEqual || | |||
| 114 | Opc == OO_PipeEqual; | |||
| 115 | } | |||
| 116 | bool isAssignmentOp() const { return isAssignmentOp(getOperator()); } | |||
| 117 | ||||
| 118 | /// \brief Is this written as an infix binary operator? | |||
| 119 | bool isInfixBinaryOp() const; | |||
| 120 | ||||
| 121 | /// \brief Returns the location of the operator symbol in the expression. | |||
| 122 | /// | |||
| 123 | /// When \c getOperator()==OO_Call, this is the location of the right | |||
| 124 | /// parentheses; when \c getOperator()==OO_Subscript, this is the location | |||
| 125 | /// of the right bracket. | |||
| 126 | SourceLocation getOperatorLoc() const { return getRParenLoc(); } | |||
| 127 | ||||
| 128 | SourceLocation getExprLoc() const LLVM_READONLY__attribute__((__pure__)) { | |||
| 129 | return (Operator < OO_Plus || Operator >= OO_Arrow || | |||
| 130 | Operator == OO_PlusPlus || Operator == OO_MinusMinus) | |||
| 131 | ? getLocStart() | |||
| 132 | : getOperatorLoc(); | |||
| 133 | } | |||
| 134 | ||||
| 135 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)) { return Range.getBegin(); } | |||
| 136 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)) { return Range.getEnd(); } | |||
| 137 | SourceRange getSourceRange() const { return Range; } | |||
| 138 | ||||
| 139 | static bool classof(const Stmt *T) { | |||
| 140 | return T->getStmtClass() == CXXOperatorCallExprClass; | |||
| 141 | } | |||
| 142 | ||||
| 143 | // Set the FP contractability status of this operator. Only meaningful for | |||
| 144 | // operations on floating point types. | |||
| 145 | void setFPFeatures(FPOptions F) { FPFeatures = F; } | |||
| 146 | ||||
| 147 | FPOptions getFPFeatures() const { return FPFeatures; } | |||
| 148 | ||||
| 149 | // Get the FP contractability status of this operator. Only meaningful for | |||
| 150 | // operations on floating point types. | |||
| 151 | bool isFPContractableWithinStatement() const { | |||
| 152 | return FPFeatures.allowFPContractWithinStatement(); | |||
| 153 | } | |||
| 154 | }; | |||
| 155 | ||||
| 156 | /// Represents a call to a member function that | |||
| 157 | /// may be written either with member call syntax (e.g., "obj.func()" | |||
| 158 | /// or "objptr->func()") or with normal function-call syntax | |||
| 159 | /// ("func()") within a member function that ends up calling a member | |||
| 160 | /// function. The callee in either case is a MemberExpr that contains | |||
| 161 | /// both the object argument and the member function, while the | |||
| 162 | /// arguments are the arguments within the parentheses (not including | |||
| 163 | /// the object argument). | |||
| 164 | class CXXMemberCallExpr : public CallExpr { | |||
| 165 | public: | |||
| 166 | CXXMemberCallExpr(ASTContext &C, Expr *fn, ArrayRef<Expr*> args, | |||
| 167 | QualType t, ExprValueKind VK, SourceLocation RP) | |||
| 168 | : CallExpr(C, CXXMemberCallExprClass, fn, args, t, VK, RP) {} | |||
| 169 | ||||
| 170 | CXXMemberCallExpr(ASTContext &C, EmptyShell Empty) | |||
| 171 | : CallExpr(C, CXXMemberCallExprClass, Empty) {} | |||
| 172 | ||||
| 173 | /// \brief Retrieves the implicit object argument for the member call. | |||
| 174 | /// | |||
| 175 | /// For example, in "x.f(5)", this returns the sub-expression "x". | |||
| 176 | Expr *getImplicitObjectArgument() const; | |||
| 177 | ||||
| 178 | /// \brief Retrieves the declaration of the called method. | |||
| 179 | CXXMethodDecl *getMethodDecl() const; | |||
| 180 | ||||
| 181 | /// \brief Retrieves the CXXRecordDecl for the underlying type of | |||
| 182 | /// the implicit object argument. | |||
| 183 | /// | |||
| 184 | /// Note that this is may not be the same declaration as that of the class | |||
| 185 | /// context of the CXXMethodDecl which this function is calling. | |||
| 186 | /// FIXME: Returns 0 for member pointer call exprs. | |||
| 187 | CXXRecordDecl *getRecordDecl() const; | |||
| 188 | ||||
| 189 | SourceLocation getExprLoc() const LLVM_READONLY__attribute__((__pure__)) { | |||
| 190 | SourceLocation CLoc = getCallee()->getExprLoc(); | |||
| 191 | if (CLoc.isValid()) | |||
| 192 | return CLoc; | |||
| 193 | ||||
| 194 | return getLocStart(); | |||
| 195 | } | |||
| 196 | ||||
| 197 | static bool classof(const Stmt *T) { | |||
| 198 | return T->getStmtClass() == CXXMemberCallExprClass; | |||
| 199 | } | |||
| 200 | }; | |||
| 201 | ||||
| 202 | /// \brief Represents a call to a CUDA kernel function. | |||
| 203 | class CUDAKernelCallExpr : public CallExpr { | |||
| 204 | private: | |||
| 205 | enum { CONFIG, END_PREARG }; | |||
| 206 | ||||
| 207 | public: | |||
| 208 | CUDAKernelCallExpr(ASTContext &C, Expr *fn, CallExpr *Config, | |||
| 209 | ArrayRef<Expr*> args, QualType t, ExprValueKind VK, | |||
| 210 | SourceLocation RP) | |||
| 211 | : CallExpr(C, CUDAKernelCallExprClass, fn, Config, args, t, VK, RP) {} | |||
| 212 | ||||
| 213 | CUDAKernelCallExpr(ASTContext &C, EmptyShell Empty) | |||
| 214 | : CallExpr(C, CUDAKernelCallExprClass, END_PREARG, Empty) {} | |||
| 215 | ||||
| 216 | const CallExpr *getConfig() const { | |||
| 217 | return cast_or_null<CallExpr>(getPreArg(CONFIG)); | |||
| 218 | } | |||
| 219 | CallExpr *getConfig() { return cast_or_null<CallExpr>(getPreArg(CONFIG)); } | |||
| 220 | ||||
| 221 | /// \brief Sets the kernel configuration expression. | |||
| 222 | /// | |||
| 223 | /// Note that this method cannot be called if config has already been set to a | |||
| 224 | /// non-null value. | |||
| 225 | void setConfig(CallExpr *E) { | |||
| 226 | assert(!getConfig() &&(static_cast <bool> (!getConfig() && "Cannot call setConfig if config is not null" ) ? void (0) : __assert_fail ("!getConfig() && \"Cannot call setConfig if config is not null\"" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 227, __extension__ __PRETTY_FUNCTION__)) | |||
| 227 | "Cannot call setConfig if config is not null")(static_cast <bool> (!getConfig() && "Cannot call setConfig if config is not null" ) ? void (0) : __assert_fail ("!getConfig() && \"Cannot call setConfig if config is not null\"" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 227, __extension__ __PRETTY_FUNCTION__)); | |||
| 228 | setPreArg(CONFIG, E); | |||
| 229 | setInstantiationDependent(isInstantiationDependent() || | |||
| 230 | E->isInstantiationDependent()); | |||
| 231 | setContainsUnexpandedParameterPack(containsUnexpandedParameterPack() || | |||
| 232 | E->containsUnexpandedParameterPack()); | |||
| 233 | } | |||
| 234 | ||||
| 235 | static bool classof(const Stmt *T) { | |||
| 236 | return T->getStmtClass() == CUDAKernelCallExprClass; | |||
| 237 | } | |||
| 238 | }; | |||
| 239 | ||||
| 240 | /// \brief Abstract class common to all of the C++ "named"/"keyword" casts. | |||
| 241 | /// | |||
| 242 | /// This abstract class is inherited by all of the classes | |||
| 243 | /// representing "named" casts: CXXStaticCastExpr for \c static_cast, | |||
| 244 | /// CXXDynamicCastExpr for \c dynamic_cast, CXXReinterpretCastExpr for | |||
| 245 | /// reinterpret_cast, and CXXConstCastExpr for \c const_cast. | |||
| 246 | class CXXNamedCastExpr : public ExplicitCastExpr { | |||
| 247 | private: | |||
| 248 | // the location of the casting op | |||
| 249 | SourceLocation Loc; | |||
| 250 | ||||
| 251 | // the location of the right parenthesis | |||
| 252 | SourceLocation RParenLoc; | |||
| 253 | ||||
| 254 | // range for '<' '>' | |||
| 255 | SourceRange AngleBrackets; | |||
| 256 | ||||
| 257 | protected: | |||
| 258 | friend class ASTStmtReader; | |||
| 259 | ||||
| 260 | CXXNamedCastExpr(StmtClass SC, QualType ty, ExprValueKind VK, | |||
| 261 | CastKind kind, Expr *op, unsigned PathSize, | |||
| 262 | TypeSourceInfo *writtenTy, SourceLocation l, | |||
| 263 | SourceLocation RParenLoc, | |||
| 264 | SourceRange AngleBrackets) | |||
| 265 | : ExplicitCastExpr(SC, ty, VK, kind, op, PathSize, writtenTy), Loc(l), | |||
| 266 | RParenLoc(RParenLoc), AngleBrackets(AngleBrackets) {} | |||
| 267 | ||||
| 268 | explicit CXXNamedCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize) | |||
| 269 | : ExplicitCastExpr(SC, Shell, PathSize) {} | |||
| 270 | ||||
| 271 | public: | |||
| 272 | const char *getCastName() const; | |||
| 273 | ||||
| 274 | /// \brief Retrieve the location of the cast operator keyword, e.g., | |||
| 275 | /// \c static_cast. | |||
| 276 | SourceLocation getOperatorLoc() const { return Loc; } | |||
| 277 | ||||
| 278 | /// \brief Retrieve the location of the closing parenthesis. | |||
| 279 | SourceLocation getRParenLoc() const { return RParenLoc; } | |||
| 280 | ||||
| 281 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)) { return Loc; } | |||
| 282 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)) { return RParenLoc; } | |||
| 283 | SourceRange getAngleBrackets() const LLVM_READONLY__attribute__((__pure__)) { return AngleBrackets; } | |||
| 284 | ||||
| 285 | static bool classof(const Stmt *T) { | |||
| 286 | switch (T->getStmtClass()) { | |||
| 287 | case CXXStaticCastExprClass: | |||
| 288 | case CXXDynamicCastExprClass: | |||
| 289 | case CXXReinterpretCastExprClass: | |||
| 290 | case CXXConstCastExprClass: | |||
| 291 | return true; | |||
| 292 | default: | |||
| 293 | return false; | |||
| 294 | } | |||
| 295 | } | |||
| 296 | }; | |||
| 297 | ||||
| 298 | /// \brief A C++ \c static_cast expression (C++ [expr.static.cast]). | |||
| 299 | /// | |||
| 300 | /// This expression node represents a C++ static cast, e.g., | |||
| 301 | /// \c static_cast<int>(1.0). | |||
| 302 | class CXXStaticCastExpr final | |||
| 303 | : public CXXNamedCastExpr, | |||
| 304 | private llvm::TrailingObjects<CXXStaticCastExpr, CXXBaseSpecifier *> { | |||
| 305 | CXXStaticCastExpr(QualType ty, ExprValueKind vk, CastKind kind, Expr *op, | |||
| 306 | unsigned pathSize, TypeSourceInfo *writtenTy, | |||
| 307 | SourceLocation l, SourceLocation RParenLoc, | |||
| 308 | SourceRange AngleBrackets) | |||
| 309 | : CXXNamedCastExpr(CXXStaticCastExprClass, ty, vk, kind, op, pathSize, | |||
| 310 | writtenTy, l, RParenLoc, AngleBrackets) {} | |||
| 311 | ||||
| 312 | explicit CXXStaticCastExpr(EmptyShell Empty, unsigned PathSize) | |||
| 313 | : CXXNamedCastExpr(CXXStaticCastExprClass, Empty, PathSize) {} | |||
| 314 | ||||
| 315 | public: | |||
| 316 | friend class CastExpr; | |||
| 317 | friend TrailingObjects; | |||
| 318 | ||||
| 319 | static CXXStaticCastExpr *Create(const ASTContext &Context, QualType T, | |||
| 320 | ExprValueKind VK, CastKind K, Expr *Op, | |||
| 321 | const CXXCastPath *Path, | |||
| 322 | TypeSourceInfo *Written, SourceLocation L, | |||
| 323 | SourceLocation RParenLoc, | |||
| 324 | SourceRange AngleBrackets); | |||
| 325 | static CXXStaticCastExpr *CreateEmpty(const ASTContext &Context, | |||
| 326 | unsigned PathSize); | |||
| 327 | ||||
| 328 | static bool classof(const Stmt *T) { | |||
| 329 | return T->getStmtClass() == CXXStaticCastExprClass; | |||
| 330 | } | |||
| 331 | }; | |||
| 332 | ||||
| 333 | /// \brief A C++ @c dynamic_cast expression (C++ [expr.dynamic.cast]). | |||
| 334 | /// | |||
| 335 | /// This expression node represents a dynamic cast, e.g., | |||
| 336 | /// \c dynamic_cast<Derived*>(BasePtr). Such a cast may perform a run-time | |||
| 337 | /// check to determine how to perform the type conversion. | |||
| 338 | class CXXDynamicCastExpr final | |||
| 339 | : public CXXNamedCastExpr, | |||
| 340 | private llvm::TrailingObjects<CXXDynamicCastExpr, CXXBaseSpecifier *> { | |||
| 341 | CXXDynamicCastExpr(QualType ty, ExprValueKind VK, CastKind kind, | |||
| 342 | Expr *op, unsigned pathSize, TypeSourceInfo *writtenTy, | |||
| 343 | SourceLocation l, SourceLocation RParenLoc, | |||
| 344 | SourceRange AngleBrackets) | |||
| 345 | : CXXNamedCastExpr(CXXDynamicCastExprClass, ty, VK, kind, op, pathSize, | |||
| 346 | writtenTy, l, RParenLoc, AngleBrackets) {} | |||
| 347 | ||||
| 348 | explicit CXXDynamicCastExpr(EmptyShell Empty, unsigned pathSize) | |||
| 349 | : CXXNamedCastExpr(CXXDynamicCastExprClass, Empty, pathSize) {} | |||
| 350 | ||||
| 351 | public: | |||
| 352 | friend class CastExpr; | |||
| 353 | friend TrailingObjects; | |||
| 354 | ||||
| 355 | static CXXDynamicCastExpr *Create(const ASTContext &Context, QualType T, | |||
| 356 | ExprValueKind VK, CastKind Kind, Expr *Op, | |||
| 357 | const CXXCastPath *Path, | |||
| 358 | TypeSourceInfo *Written, SourceLocation L, | |||
| 359 | SourceLocation RParenLoc, | |||
| 360 | SourceRange AngleBrackets); | |||
| 361 | ||||
| 362 | static CXXDynamicCastExpr *CreateEmpty(const ASTContext &Context, | |||
| 363 | unsigned pathSize); | |||
| 364 | ||||
| 365 | bool isAlwaysNull() const; | |||
| 366 | ||||
| 367 | static bool classof(const Stmt *T) { | |||
| 368 | return T->getStmtClass() == CXXDynamicCastExprClass; | |||
| 369 | } | |||
| 370 | }; | |||
| 371 | ||||
| 372 | /// \brief A C++ @c reinterpret_cast expression (C++ [expr.reinterpret.cast]). | |||
| 373 | /// | |||
| 374 | /// This expression node represents a reinterpret cast, e.g., | |||
| 375 | /// @c reinterpret_cast<int>(VoidPtr). | |||
| 376 | /// | |||
| 377 | /// A reinterpret_cast provides a differently-typed view of a value but | |||
| 378 | /// (in Clang, as in most C++ implementations) performs no actual work at | |||
| 379 | /// run time. | |||
| 380 | class CXXReinterpretCastExpr final | |||
| 381 | : public CXXNamedCastExpr, | |||
| 382 | private llvm::TrailingObjects<CXXReinterpretCastExpr, | |||
| 383 | CXXBaseSpecifier *> { | |||
| 384 | CXXReinterpretCastExpr(QualType ty, ExprValueKind vk, CastKind kind, | |||
| 385 | Expr *op, unsigned pathSize, | |||
| 386 | TypeSourceInfo *writtenTy, SourceLocation l, | |||
| 387 | SourceLocation RParenLoc, | |||
| 388 | SourceRange AngleBrackets) | |||
| 389 | : CXXNamedCastExpr(CXXReinterpretCastExprClass, ty, vk, kind, op, | |||
| 390 | pathSize, writtenTy, l, RParenLoc, AngleBrackets) {} | |||
| 391 | ||||
| 392 | CXXReinterpretCastExpr(EmptyShell Empty, unsigned pathSize) | |||
| 393 | : CXXNamedCastExpr(CXXReinterpretCastExprClass, Empty, pathSize) {} | |||
| 394 | ||||
| 395 | public: | |||
| 396 | friend class CastExpr; | |||
| 397 | friend TrailingObjects; | |||
| 398 | ||||
| 399 | static CXXReinterpretCastExpr *Create(const ASTContext &Context, QualType T, | |||
| 400 | ExprValueKind VK, CastKind Kind, | |||
| 401 | Expr *Op, const CXXCastPath *Path, | |||
| 402 | TypeSourceInfo *WrittenTy, SourceLocation L, | |||
| 403 | SourceLocation RParenLoc, | |||
| 404 | SourceRange AngleBrackets); | |||
| 405 | static CXXReinterpretCastExpr *CreateEmpty(const ASTContext &Context, | |||
| 406 | unsigned pathSize); | |||
| 407 | ||||
| 408 | static bool classof(const Stmt *T) { | |||
| 409 | return T->getStmtClass() == CXXReinterpretCastExprClass; | |||
| 410 | } | |||
| 411 | }; | |||
| 412 | ||||
| 413 | /// \brief A C++ \c const_cast expression (C++ [expr.const.cast]). | |||
| 414 | /// | |||
| 415 | /// This expression node represents a const cast, e.g., | |||
| 416 | /// \c const_cast<char*>(PtrToConstChar). | |||
| 417 | /// | |||
| 418 | /// A const_cast can remove type qualifiers but does not change the underlying | |||
| 419 | /// value. | |||
| 420 | class CXXConstCastExpr final | |||
| 421 | : public CXXNamedCastExpr, | |||
| 422 | private llvm::TrailingObjects<CXXConstCastExpr, CXXBaseSpecifier *> { | |||
| 423 | CXXConstCastExpr(QualType ty, ExprValueKind VK, Expr *op, | |||
| 424 | TypeSourceInfo *writtenTy, SourceLocation l, | |||
| 425 | SourceLocation RParenLoc, SourceRange AngleBrackets) | |||
| 426 | : CXXNamedCastExpr(CXXConstCastExprClass, ty, VK, CK_NoOp, op, | |||
| 427 | 0, writtenTy, l, RParenLoc, AngleBrackets) {} | |||
| 428 | ||||
| 429 | explicit CXXConstCastExpr(EmptyShell Empty) | |||
| 430 | : CXXNamedCastExpr(CXXConstCastExprClass, Empty, 0) {} | |||
| 431 | ||||
| 432 | public: | |||
| 433 | friend class CastExpr; | |||
| 434 | friend TrailingObjects; | |||
| 435 | ||||
| 436 | static CXXConstCastExpr *Create(const ASTContext &Context, QualType T, | |||
| 437 | ExprValueKind VK, Expr *Op, | |||
| 438 | TypeSourceInfo *WrittenTy, SourceLocation L, | |||
| 439 | SourceLocation RParenLoc, | |||
| 440 | SourceRange AngleBrackets); | |||
| 441 | static CXXConstCastExpr *CreateEmpty(const ASTContext &Context); | |||
| 442 | ||||
| 443 | static bool classof(const Stmt *T) { | |||
| 444 | return T->getStmtClass() == CXXConstCastExprClass; | |||
| 445 | } | |||
| 446 | }; | |||
| 447 | ||||
| 448 | /// \brief A call to a literal operator (C++11 [over.literal]) | |||
| 449 | /// written as a user-defined literal (C++11 [lit.ext]). | |||
| 450 | /// | |||
| 451 | /// Represents a user-defined literal, e.g. "foo"_bar or 1.23_xyz. While this | |||
| 452 | /// is semantically equivalent to a normal call, this AST node provides better | |||
| 453 | /// information about the syntactic representation of the literal. | |||
| 454 | /// | |||
| 455 | /// Since literal operators are never found by ADL and can only be declared at | |||
| 456 | /// namespace scope, a user-defined literal is never dependent. | |||
| 457 | class UserDefinedLiteral : public CallExpr { | |||
| 458 | /// \brief The location of a ud-suffix within the literal. | |||
| 459 | SourceLocation UDSuffixLoc; | |||
| 460 | ||||
| 461 | public: | |||
| 462 | friend class ASTStmtReader; | |||
| 463 | friend class ASTStmtWriter; | |||
| 464 | ||||
| 465 | UserDefinedLiteral(const ASTContext &C, Expr *Fn, ArrayRef<Expr*> Args, | |||
| 466 | QualType T, ExprValueKind VK, SourceLocation LitEndLoc, | |||
| 467 | SourceLocation SuffixLoc) | |||
| 468 | : CallExpr(C, UserDefinedLiteralClass, Fn, Args, T, VK, LitEndLoc), | |||
| 469 | UDSuffixLoc(SuffixLoc) {} | |||
| 470 | ||||
| 471 | explicit UserDefinedLiteral(const ASTContext &C, EmptyShell Empty) | |||
| 472 | : CallExpr(C, UserDefinedLiteralClass, Empty) {} | |||
| 473 | ||||
| 474 | /// The kind of literal operator which is invoked. | |||
| 475 | enum LiteralOperatorKind { | |||
| 476 | /// Raw form: operator "" X (const char *) | |||
| 477 | LOK_Raw, | |||
| 478 | ||||
| 479 | /// Raw form: operator "" X<cs...> () | |||
| 480 | LOK_Template, | |||
| 481 | ||||
| 482 | /// operator "" X (unsigned long long) | |||
| 483 | LOK_Integer, | |||
| 484 | ||||
| 485 | /// operator "" X (long double) | |||
| 486 | LOK_Floating, | |||
| 487 | ||||
| 488 | /// operator "" X (const CharT *, size_t) | |||
| 489 | LOK_String, | |||
| 490 | ||||
| 491 | /// operator "" X (CharT) | |||
| 492 | LOK_Character | |||
| 493 | }; | |||
| 494 | ||||
| 495 | /// \brief Returns the kind of literal operator invocation | |||
| 496 | /// which this expression represents. | |||
| 497 | LiteralOperatorKind getLiteralOperatorKind() const; | |||
| 498 | ||||
| 499 | /// \brief If this is not a raw user-defined literal, get the | |||
| 500 | /// underlying cooked literal (representing the literal with the suffix | |||
| 501 | /// removed). | |||
| 502 | Expr *getCookedLiteral(); | |||
| 503 | const Expr *getCookedLiteral() const { | |||
| 504 | return const_cast<UserDefinedLiteral*>(this)->getCookedLiteral(); | |||
| 505 | } | |||
| 506 | ||||
| 507 | SourceLocation getLocStart() const { | |||
| 508 | if (getLiteralOperatorKind() == LOK_Template) | |||
| 509 | return getRParenLoc(); | |||
| 510 | return getArg(0)->getLocStart(); | |||
| 511 | } | |||
| 512 | ||||
| 513 | SourceLocation getLocEnd() const { return getRParenLoc(); } | |||
| 514 | ||||
| 515 | /// \brief Returns the location of a ud-suffix in the expression. | |||
| 516 | /// | |||
| 517 | /// For a string literal, there may be multiple identical suffixes. This | |||
| 518 | /// returns the first. | |||
| 519 | SourceLocation getUDSuffixLoc() const { return UDSuffixLoc; } | |||
| 520 | ||||
| 521 | /// \brief Returns the ud-suffix specified for this literal. | |||
| 522 | const IdentifierInfo *getUDSuffix() const; | |||
| 523 | ||||
| 524 | static bool classof(const Stmt *S) { | |||
| 525 | return S->getStmtClass() == UserDefinedLiteralClass; | |||
| 526 | } | |||
| 527 | }; | |||
| 528 | ||||
| 529 | /// \brief A boolean literal, per ([C++ lex.bool] Boolean literals). | |||
| 530 | class CXXBoolLiteralExpr : public Expr { | |||
| 531 | bool Value; | |||
| 532 | SourceLocation Loc; | |||
| 533 | ||||
| 534 | public: | |||
| 535 | CXXBoolLiteralExpr(bool val, QualType Ty, SourceLocation l) | |||
| 536 | : Expr(CXXBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false, | |||
| 537 | false, false), | |||
| 538 | Value(val), Loc(l) {} | |||
| 539 | ||||
| 540 | explicit CXXBoolLiteralExpr(EmptyShell Empty) | |||
| 541 | : Expr(CXXBoolLiteralExprClass, Empty) {} | |||
| 542 | ||||
| 543 | bool getValue() const { return Value; } | |||
| 544 | void setValue(bool V) { Value = V; } | |||
| 545 | ||||
| 546 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)) { return Loc; } | |||
| 547 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)) { return Loc; } | |||
| 548 | ||||
| 549 | SourceLocation getLocation() const { return Loc; } | |||
| 550 | void setLocation(SourceLocation L) { Loc = L; } | |||
| 551 | ||||
| 552 | static bool classof(const Stmt *T) { | |||
| 553 | return T->getStmtClass() == CXXBoolLiteralExprClass; | |||
| 554 | } | |||
| 555 | ||||
| 556 | // Iterators | |||
| 557 | child_range children() { | |||
| 558 | return child_range(child_iterator(), child_iterator()); | |||
| 559 | } | |||
| 560 | }; | |||
| 561 | ||||
| 562 | /// \brief The null pointer literal (C++11 [lex.nullptr]) | |||
| 563 | /// | |||
| 564 | /// Introduced in C++11, the only literal of type \c nullptr_t is \c nullptr. | |||
| 565 | class CXXNullPtrLiteralExpr : public Expr { | |||
| 566 | SourceLocation Loc; | |||
| 567 | ||||
| 568 | public: | |||
| 569 | CXXNullPtrLiteralExpr(QualType Ty, SourceLocation l) | |||
| 570 | : Expr(CXXNullPtrLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, | |||
| 571 | false, false, false), | |||
| 572 | Loc(l) {} | |||
| 573 | ||||
| 574 | explicit CXXNullPtrLiteralExpr(EmptyShell Empty) | |||
| 575 | : Expr(CXXNullPtrLiteralExprClass, Empty) {} | |||
| 576 | ||||
| 577 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)) { return Loc; } | |||
| 578 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)) { return Loc; } | |||
| 579 | ||||
| 580 | SourceLocation getLocation() const { return Loc; } | |||
| 581 | void setLocation(SourceLocation L) { Loc = L; } | |||
| 582 | ||||
| 583 | static bool classof(const Stmt *T) { | |||
| 584 | return T->getStmtClass() == CXXNullPtrLiteralExprClass; | |||
| 585 | } | |||
| 586 | ||||
| 587 | child_range children() { | |||
| 588 | return child_range(child_iterator(), child_iterator()); | |||
| 589 | } | |||
| 590 | }; | |||
| 591 | ||||
| 592 | /// \brief Implicit construction of a std::initializer_list<T> object from an | |||
| 593 | /// array temporary within list-initialization (C++11 [dcl.init.list]p5). | |||
| 594 | class CXXStdInitializerListExpr : public Expr { | |||
| 595 | Stmt *SubExpr = nullptr; | |||
| 596 | ||||
| 597 | CXXStdInitializerListExpr(EmptyShell Empty) | |||
| 598 | : Expr(CXXStdInitializerListExprClass, Empty) {} | |||
| 599 | ||||
| 600 | public: | |||
| 601 | friend class ASTReader; | |||
| 602 | friend class ASTStmtReader; | |||
| 603 | ||||
| 604 | CXXStdInitializerListExpr(QualType Ty, Expr *SubExpr) | |||
| 605 | : Expr(CXXStdInitializerListExprClass, Ty, VK_RValue, OK_Ordinary, | |||
| 606 | Ty->isDependentType(), SubExpr->isValueDependent(), | |||
| 607 | SubExpr->isInstantiationDependent(), | |||
| 608 | SubExpr->containsUnexpandedParameterPack()), | |||
| 609 | SubExpr(SubExpr) {} | |||
| 610 | ||||
| 611 | Expr *getSubExpr() { return static_cast<Expr*>(SubExpr); } | |||
| 612 | const Expr *getSubExpr() const { return static_cast<const Expr*>(SubExpr); } | |||
| 613 | ||||
| 614 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)) { | |||
| 615 | return SubExpr->getLocStart(); | |||
| 616 | } | |||
| 617 | ||||
| 618 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)) { | |||
| 619 | return SubExpr->getLocEnd(); | |||
| 620 | } | |||
| 621 | ||||
| 622 | SourceRange getSourceRange() const LLVM_READONLY__attribute__((__pure__)) { | |||
| 623 | return SubExpr->getSourceRange(); | |||
| 624 | } | |||
| 625 | ||||
| 626 | static bool classof(const Stmt *S) { | |||
| 627 | return S->getStmtClass() == CXXStdInitializerListExprClass; | |||
| 628 | } | |||
| 629 | ||||
| 630 | child_range children() { return child_range(&SubExpr, &SubExpr + 1); } | |||
| 631 | }; | |||
| 632 | ||||
| 633 | /// A C++ \c typeid expression (C++ [expr.typeid]), which gets | |||
| 634 | /// the \c type_info that corresponds to the supplied type, or the (possibly | |||
| 635 | /// dynamic) type of the supplied expression. | |||
| 636 | /// | |||
| 637 | /// This represents code like \c typeid(int) or \c typeid(*objPtr) | |||
| 638 | class CXXTypeidExpr : public Expr { | |||
| 639 | private: | |||
| 640 | llvm::PointerUnion<Stmt *, TypeSourceInfo *> Operand; | |||
| 641 | SourceRange Range; | |||
| 642 | ||||
| 643 | public: | |||
| 644 | CXXTypeidExpr(QualType Ty, TypeSourceInfo *Operand, SourceRange R) | |||
| 645 | : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary, | |||
| 646 | // typeid is never type-dependent (C++ [temp.dep.expr]p4) | |||
| 647 | false, | |||
| 648 | // typeid is value-dependent if the type or expression are | |||
| 649 | // dependent | |||
| 650 | Operand->getType()->isDependentType(), | |||
| 651 | Operand->getType()->isInstantiationDependentType(), | |||
| 652 | Operand->getType()->containsUnexpandedParameterPack()), | |||
| 653 | Operand(Operand), Range(R) {} | |||
| 654 | ||||
| 655 | CXXTypeidExpr(QualType Ty, Expr *Operand, SourceRange R) | |||
| 656 | : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary, | |||
| 657 | // typeid is never type-dependent (C++ [temp.dep.expr]p4) | |||
| 658 | false, | |||
| 659 | // typeid is value-dependent if the type or expression are | |||
| 660 | // dependent | |||
| 661 | Operand->isTypeDependent() || Operand->isValueDependent(), | |||
| 662 | Operand->isInstantiationDependent(), | |||
| 663 | Operand->containsUnexpandedParameterPack()), | |||
| 664 | Operand(Operand), Range(R) {} | |||
| 665 | ||||
| 666 | CXXTypeidExpr(EmptyShell Empty, bool isExpr) | |||
| 667 | : Expr(CXXTypeidExprClass, Empty) { | |||
| 668 | if (isExpr) | |||
| 669 | Operand = (Expr*)nullptr; | |||
| 670 | else | |||
| 671 | Operand = (TypeSourceInfo*)nullptr; | |||
| 672 | } | |||
| 673 | ||||
| 674 | /// Determine whether this typeid has a type operand which is potentially | |||
| 675 | /// evaluated, per C++11 [expr.typeid]p3. | |||
| 676 | bool isPotentiallyEvaluated() const; | |||
| 677 | ||||
| 678 | bool isTypeOperand() const { return Operand.is<TypeSourceInfo *>(); } | |||
| 679 | ||||
| 680 | /// \brief Retrieves the type operand of this typeid() expression after | |||
| 681 | /// various required adjustments (removing reference types, cv-qualifiers). | |||
| 682 | QualType getTypeOperand(ASTContext &Context) const; | |||
| 683 | ||||
| 684 | /// \brief Retrieve source information for the type operand. | |||
| 685 | TypeSourceInfo *getTypeOperandSourceInfo() const { | |||
| 686 | assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)")(static_cast <bool> (isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)" ) ? void (0) : __assert_fail ("isTypeOperand() && \"Cannot call getTypeOperand for typeid(expr)\"" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 686, __extension__ __PRETTY_FUNCTION__)); | |||
| 687 | return Operand.get<TypeSourceInfo *>(); | |||
| 688 | } | |||
| 689 | ||||
| 690 | void setTypeOperandSourceInfo(TypeSourceInfo *TSI) { | |||
| 691 | assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)")(static_cast <bool> (isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)" ) ? void (0) : __assert_fail ("isTypeOperand() && \"Cannot call getTypeOperand for typeid(expr)\"" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 691, __extension__ __PRETTY_FUNCTION__)); | |||
| 692 | Operand = TSI; | |||
| 693 | } | |||
| 694 | ||||
| 695 | Expr *getExprOperand() const { | |||
| 696 | assert(!isTypeOperand() && "Cannot call getExprOperand for typeid(type)")(static_cast <bool> (!isTypeOperand() && "Cannot call getExprOperand for typeid(type)" ) ? void (0) : __assert_fail ("!isTypeOperand() && \"Cannot call getExprOperand for typeid(type)\"" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 696, __extension__ __PRETTY_FUNCTION__)); | |||
| 697 | return static_cast<Expr*>(Operand.get<Stmt *>()); | |||
| 698 | } | |||
| 699 | ||||
| 700 | void setExprOperand(Expr *E) { | |||
| 701 | assert(!isTypeOperand() && "Cannot call getExprOperand for typeid(type)")(static_cast <bool> (!isTypeOperand() && "Cannot call getExprOperand for typeid(type)" ) ? void (0) : __assert_fail ("!isTypeOperand() && \"Cannot call getExprOperand for typeid(type)\"" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 701, __extension__ __PRETTY_FUNCTION__)); | |||
| 702 | Operand = E; | |||
| 703 | } | |||
| 704 | ||||
| 705 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)) { return Range.getBegin(); } | |||
| 706 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)) { return Range.getEnd(); } | |||
| 707 | SourceRange getSourceRange() const LLVM_READONLY__attribute__((__pure__)) { return Range; } | |||
| 708 | void setSourceRange(SourceRange R) { Range = R; } | |||
| 709 | ||||
| 710 | static bool classof(const Stmt *T) { | |||
| 711 | return T->getStmtClass() == CXXTypeidExprClass; | |||
| 712 | } | |||
| 713 | ||||
| 714 | // Iterators | |||
| 715 | child_range children() { | |||
| 716 | if (isTypeOperand()) | |||
| 717 | return child_range(child_iterator(), child_iterator()); | |||
| 718 | Stmt **begin = reinterpret_cast<Stmt**>(&Operand); | |||
| 719 | return child_range(begin, begin + 1); | |||
| 720 | } | |||
| 721 | }; | |||
| 722 | ||||
| 723 | /// \brief A member reference to an MSPropertyDecl. | |||
| 724 | /// | |||
| 725 | /// This expression always has pseudo-object type, and therefore it is | |||
| 726 | /// typically not encountered in a fully-typechecked expression except | |||
| 727 | /// within the syntactic form of a PseudoObjectExpr. | |||
| 728 | class MSPropertyRefExpr : public Expr { | |||
| 729 | Expr *BaseExpr; | |||
| 730 | MSPropertyDecl *TheDecl; | |||
| 731 | SourceLocation MemberLoc; | |||
| 732 | bool IsArrow; | |||
| 733 | NestedNameSpecifierLoc QualifierLoc; | |||
| 734 | ||||
| 735 | public: | |||
| 736 | friend class ASTStmtReader; | |||
| 737 | ||||
| 738 | MSPropertyRefExpr(Expr *baseExpr, MSPropertyDecl *decl, bool isArrow, | |||
| 739 | QualType ty, ExprValueKind VK, | |||
| 740 | NestedNameSpecifierLoc qualifierLoc, | |||
| 741 | SourceLocation nameLoc) | |||
| 742 | : Expr(MSPropertyRefExprClass, ty, VK, OK_Ordinary, | |||
| 743 | /*type-dependent*/ false, baseExpr->isValueDependent(), | |||
| 744 | baseExpr->isInstantiationDependent(), | |||
| 745 | baseExpr->containsUnexpandedParameterPack()), | |||
| 746 | BaseExpr(baseExpr), TheDecl(decl), | |||
| 747 | MemberLoc(nameLoc), IsArrow(isArrow), | |||
| 748 | QualifierLoc(qualifierLoc) {} | |||
| 749 | ||||
| 750 | MSPropertyRefExpr(EmptyShell Empty) : Expr(MSPropertyRefExprClass, Empty) {} | |||
| 751 | ||||
| 752 | SourceRange getSourceRange() const LLVM_READONLY__attribute__((__pure__)) { | |||
| 753 | return SourceRange(getLocStart(), getLocEnd()); | |||
| 754 | } | |||
| 755 | ||||
| 756 | bool isImplicitAccess() const { | |||
| 757 | return getBaseExpr() && getBaseExpr()->isImplicitCXXThis(); | |||
| 758 | } | |||
| 759 | ||||
| 760 | SourceLocation getLocStart() const { | |||
| 761 | if (!isImplicitAccess()) | |||
| 762 | return BaseExpr->getLocStart(); | |||
| 763 | else if (QualifierLoc) | |||
| 764 | return QualifierLoc.getBeginLoc(); | |||
| 765 | else | |||
| 766 | return MemberLoc; | |||
| 767 | } | |||
| 768 | ||||
| 769 | SourceLocation getLocEnd() const { return getMemberLoc(); } | |||
| 770 | ||||
| 771 | child_range children() { | |||
| 772 | return child_range((Stmt**)&BaseExpr, (Stmt**)&BaseExpr + 1); | |||
| 773 | } | |||
| 774 | ||||
| 775 | static bool classof(const Stmt *T) { | |||
| 776 | return T->getStmtClass() == MSPropertyRefExprClass; | |||
| 777 | } | |||
| 778 | ||||
| 779 | Expr *getBaseExpr() const { return BaseExpr; } | |||
| 780 | MSPropertyDecl *getPropertyDecl() const { return TheDecl; } | |||
| 781 | bool isArrow() const { return IsArrow; } | |||
| 782 | SourceLocation getMemberLoc() const { return MemberLoc; } | |||
| 783 | NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } | |||
| 784 | }; | |||
| 785 | ||||
| 786 | /// MS property subscript expression. | |||
| 787 | /// MSVC supports 'property' attribute and allows to apply it to the | |||
| 788 | /// declaration of an empty array in a class or structure definition. | |||
| 789 | /// For example: | |||
| 790 | /// \code | |||
| 791 | /// __declspec(property(get=GetX, put=PutX)) int x[]; | |||
| 792 | /// \endcode | |||
| 793 | /// The above statement indicates that x[] can be used with one or more array | |||
| 794 | /// indices. In this case, i=p->x[a][b] will be turned into i=p->GetX(a, b), and | |||
| 795 | /// p->x[a][b] = i will be turned into p->PutX(a, b, i). | |||
| 796 | /// This is a syntactic pseudo-object expression. | |||
| 797 | class MSPropertySubscriptExpr : public Expr { | |||
| 798 | friend class ASTStmtReader; | |||
| 799 | ||||
| 800 | enum { BASE_EXPR, IDX_EXPR, NUM_SUBEXPRS = 2 }; | |||
| 801 | ||||
| 802 | Stmt *SubExprs[NUM_SUBEXPRS]; | |||
| 803 | SourceLocation RBracketLoc; | |||
| 804 | ||||
| 805 | void setBase(Expr *Base) { SubExprs[BASE_EXPR] = Base; } | |||
| 806 | void setIdx(Expr *Idx) { SubExprs[IDX_EXPR] = Idx; } | |||
| 807 | ||||
| 808 | public: | |||
| 809 | MSPropertySubscriptExpr(Expr *Base, Expr *Idx, QualType Ty, ExprValueKind VK, | |||
| 810 | ExprObjectKind OK, SourceLocation RBracketLoc) | |||
| 811 | : Expr(MSPropertySubscriptExprClass, Ty, VK, OK, Idx->isTypeDependent(), | |||
| 812 | Idx->isValueDependent(), Idx->isInstantiationDependent(), | |||
| 813 | Idx->containsUnexpandedParameterPack()), | |||
| 814 | RBracketLoc(RBracketLoc) { | |||
| 815 | SubExprs[BASE_EXPR] = Base; | |||
| 816 | SubExprs[IDX_EXPR] = Idx; | |||
| 817 | } | |||
| 818 | ||||
| 819 | /// \brief Create an empty array subscript expression. | |||
| 820 | explicit MSPropertySubscriptExpr(EmptyShell Shell) | |||
| 821 | : Expr(MSPropertySubscriptExprClass, Shell) {} | |||
| 822 | ||||
| 823 | Expr *getBase() { return cast<Expr>(SubExprs[BASE_EXPR]); } | |||
| 824 | const Expr *getBase() const { return cast<Expr>(SubExprs[BASE_EXPR]); } | |||
| 825 | ||||
| 826 | Expr *getIdx() { return cast<Expr>(SubExprs[IDX_EXPR]); } | |||
| 827 | const Expr *getIdx() const { return cast<Expr>(SubExprs[IDX_EXPR]); } | |||
| 828 | ||||
| 829 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)) { | |||
| 830 | return getBase()->getLocStart(); | |||
| 831 | } | |||
| 832 | ||||
| 833 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)) { return RBracketLoc; } | |||
| 834 | ||||
| 835 | SourceLocation getRBracketLoc() const { return RBracketLoc; } | |||
| 836 | void setRBracketLoc(SourceLocation L) { RBracketLoc = L; } | |||
| 837 | ||||
| 838 | SourceLocation getExprLoc() const LLVM_READONLY__attribute__((__pure__)) { | |||
| 839 | return getBase()->getExprLoc(); | |||
| 840 | } | |||
| 841 | ||||
| 842 | static bool classof(const Stmt *T) { | |||
| 843 | return T->getStmtClass() == MSPropertySubscriptExprClass; | |||
| 844 | } | |||
| 845 | ||||
| 846 | // Iterators | |||
| 847 | child_range children() { | |||
| 848 | return child_range(&SubExprs[0], &SubExprs[0] + NUM_SUBEXPRS); | |||
| 849 | } | |||
| 850 | }; | |||
| 851 | ||||
| 852 | /// A Microsoft C++ @c __uuidof expression, which gets | |||
| 853 | /// the _GUID that corresponds to the supplied type or expression. | |||
| 854 | /// | |||
| 855 | /// This represents code like @c __uuidof(COMTYPE) or @c __uuidof(*comPtr) | |||
| 856 | class CXXUuidofExpr : public Expr { | |||
| 857 | private: | |||
| 858 | llvm::PointerUnion<Stmt *, TypeSourceInfo *> Operand; | |||
| 859 | StringRef UuidStr; | |||
| 860 | SourceRange Range; | |||
| 861 | ||||
| 862 | public: | |||
| 863 | CXXUuidofExpr(QualType Ty, TypeSourceInfo *Operand, StringRef UuidStr, | |||
| 864 | SourceRange R) | |||
| 865 | : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary, false, | |||
| 866 | Operand->getType()->isDependentType(), | |||
| 867 | Operand->getType()->isInstantiationDependentType(), | |||
| 868 | Operand->getType()->containsUnexpandedParameterPack()), | |||
| 869 | Operand(Operand), UuidStr(UuidStr), Range(R) {} | |||
| 870 | ||||
| 871 | CXXUuidofExpr(QualType Ty, Expr *Operand, StringRef UuidStr, SourceRange R) | |||
| 872 | : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary, false, | |||
| 873 | Operand->isTypeDependent(), Operand->isInstantiationDependent(), | |||
| 874 | Operand->containsUnexpandedParameterPack()), | |||
| 875 | Operand(Operand), UuidStr(UuidStr), Range(R) {} | |||
| 876 | ||||
| 877 | CXXUuidofExpr(EmptyShell Empty, bool isExpr) | |||
| 878 | : Expr(CXXUuidofExprClass, Empty) { | |||
| 879 | if (isExpr) | |||
| 880 | Operand = (Expr*)nullptr; | |||
| 881 | else | |||
| 882 | Operand = (TypeSourceInfo*)nullptr; | |||
| 883 | } | |||
| 884 | ||||
| 885 | bool isTypeOperand() const { return Operand.is<TypeSourceInfo *>(); } | |||
| 886 | ||||
| 887 | /// \brief Retrieves the type operand of this __uuidof() expression after | |||
| 888 | /// various required adjustments (removing reference types, cv-qualifiers). | |||
| 889 | QualType getTypeOperand(ASTContext &Context) const; | |||
| 890 | ||||
| 891 | /// \brief Retrieve source information for the type operand. | |||
| 892 | TypeSourceInfo *getTypeOperandSourceInfo() const { | |||
| 893 | assert(isTypeOperand() && "Cannot call getTypeOperand for __uuidof(expr)")(static_cast <bool> (isTypeOperand() && "Cannot call getTypeOperand for __uuidof(expr)" ) ? void (0) : __assert_fail ("isTypeOperand() && \"Cannot call getTypeOperand for __uuidof(expr)\"" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 893, __extension__ __PRETTY_FUNCTION__)); | |||
| 894 | return Operand.get<TypeSourceInfo *>(); | |||
| 895 | } | |||
| 896 | ||||
| 897 | void setTypeOperandSourceInfo(TypeSourceInfo *TSI) { | |||
| 898 | assert(isTypeOperand() && "Cannot call getTypeOperand for __uuidof(expr)")(static_cast <bool> (isTypeOperand() && "Cannot call getTypeOperand for __uuidof(expr)" ) ? void (0) : __assert_fail ("isTypeOperand() && \"Cannot call getTypeOperand for __uuidof(expr)\"" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 898, __extension__ __PRETTY_FUNCTION__)); | |||
| 899 | Operand = TSI; | |||
| 900 | } | |||
| 901 | ||||
| 902 | Expr *getExprOperand() const { | |||
| 903 | assert(!isTypeOperand() && "Cannot call getExprOperand for __uuidof(type)")(static_cast <bool> (!isTypeOperand() && "Cannot call getExprOperand for __uuidof(type)" ) ? void (0) : __assert_fail ("!isTypeOperand() && \"Cannot call getExprOperand for __uuidof(type)\"" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 903, __extension__ __PRETTY_FUNCTION__)); | |||
| 904 | return static_cast<Expr*>(Operand.get<Stmt *>()); | |||
| 905 | } | |||
| 906 | ||||
| 907 | void setExprOperand(Expr *E) { | |||
| 908 | assert(!isTypeOperand() && "Cannot call getExprOperand for __uuidof(type)")(static_cast <bool> (!isTypeOperand() && "Cannot call getExprOperand for __uuidof(type)" ) ? void (0) : __assert_fail ("!isTypeOperand() && \"Cannot call getExprOperand for __uuidof(type)\"" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 908, __extension__ __PRETTY_FUNCTION__)); | |||
| 909 | Operand = E; | |||
| 910 | } | |||
| 911 | ||||
| 912 | void setUuidStr(StringRef US) { UuidStr = US; } | |||
| 913 | StringRef getUuidStr() const { return UuidStr; } | |||
| 914 | ||||
| 915 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)) { return Range.getBegin(); } | |||
| 916 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)) { return Range.getEnd(); } | |||
| 917 | SourceRange getSourceRange() const LLVM_READONLY__attribute__((__pure__)) { return Range; } | |||
| 918 | void setSourceRange(SourceRange R) { Range = R; } | |||
| 919 | ||||
| 920 | static bool classof(const Stmt *T) { | |||
| 921 | return T->getStmtClass() == CXXUuidofExprClass; | |||
| 922 | } | |||
| 923 | ||||
| 924 | // Iterators | |||
| 925 | child_range children() { | |||
| 926 | if (isTypeOperand()) | |||
| 927 | return child_range(child_iterator(), child_iterator()); | |||
| 928 | Stmt **begin = reinterpret_cast<Stmt**>(&Operand); | |||
| 929 | return child_range(begin, begin + 1); | |||
| 930 | } | |||
| 931 | }; | |||
| 932 | ||||
| 933 | /// \brief Represents the \c this expression in C++. | |||
| 934 | /// | |||
| 935 | /// This is a pointer to the object on which the current member function is | |||
| 936 | /// executing (C++ [expr.prim]p3). Example: | |||
| 937 | /// | |||
| 938 | /// \code | |||
| 939 | /// class Foo { | |||
| 940 | /// public: | |||
| 941 | /// void bar(); | |||
| 942 | /// void test() { this->bar(); } | |||
| 943 | /// }; | |||
| 944 | /// \endcode | |||
| 945 | class CXXThisExpr : public Expr { | |||
| 946 | SourceLocation Loc; | |||
| 947 | bool Implicit : 1; | |||
| 948 | ||||
| 949 | public: | |||
| 950 | CXXThisExpr(SourceLocation L, QualType Type, bool isImplicit) | |||
| 951 | : Expr(CXXThisExprClass, Type, VK_RValue, OK_Ordinary, | |||
| 952 | // 'this' is type-dependent if the class type of the enclosing | |||
| 953 | // member function is dependent (C++ [temp.dep.expr]p2) | |||
| 954 | Type->isDependentType(), Type->isDependentType(), | |||
| 955 | Type->isInstantiationDependentType(), | |||
| 956 | /*ContainsUnexpandedParameterPack=*/false), | |||
| 957 | Loc(L), Implicit(isImplicit) {} | |||
| 958 | ||||
| 959 | CXXThisExpr(EmptyShell Empty) : Expr(CXXThisExprClass, Empty) {} | |||
| 960 | ||||
| 961 | SourceLocation getLocation() const { return Loc; } | |||
| 962 | void setLocation(SourceLocation L) { Loc = L; } | |||
| 963 | ||||
| 964 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)) { return Loc; } | |||
| 965 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)) { return Loc; } | |||
| 966 | ||||
| 967 | bool isImplicit() const { return Implicit; } | |||
| 968 | void setImplicit(bool I) { Implicit = I; } | |||
| 969 | ||||
| 970 | static bool classof(const Stmt *T) { | |||
| 971 | return T->getStmtClass() == CXXThisExprClass; | |||
| 972 | } | |||
| 973 | ||||
| 974 | // Iterators | |||
| 975 | child_range children() { | |||
| 976 | return child_range(child_iterator(), child_iterator()); | |||
| 977 | } | |||
| 978 | }; | |||
| 979 | ||||
| 980 | /// \brief A C++ throw-expression (C++ [except.throw]). | |||
| 981 | /// | |||
| 982 | /// This handles 'throw' (for re-throwing the current exception) and | |||
| 983 | /// 'throw' assignment-expression. When assignment-expression isn't | |||
| 984 | /// present, Op will be null. | |||
| 985 | class CXXThrowExpr : public Expr { | |||
| 986 | friend class ASTStmtReader; | |||
| 987 | ||||
| 988 | Stmt *Op; | |||
| 989 | SourceLocation ThrowLoc; | |||
| 990 | ||||
| 991 | /// \brief Whether the thrown variable (if any) is in scope. | |||
| 992 | unsigned IsThrownVariableInScope : 1; | |||
| 993 | ||||
| 994 | public: | |||
| 995 | // \p Ty is the void type which is used as the result type of the | |||
| 996 | // expression. The \p l is the location of the throw keyword. \p expr | |||
| 997 | // can by null, if the optional expression to throw isn't present. | |||
| 998 | CXXThrowExpr(Expr *expr, QualType Ty, SourceLocation l, | |||
| 999 | bool IsThrownVariableInScope) | |||
| 1000 | : Expr(CXXThrowExprClass, Ty, VK_RValue, OK_Ordinary, false, false, | |||
| 1001 | expr && expr->isInstantiationDependent(), | |||
| 1002 | expr && expr->containsUnexpandedParameterPack()), | |||
| 1003 | Op(expr), ThrowLoc(l), | |||
| 1004 | IsThrownVariableInScope(IsThrownVariableInScope) {} | |||
| 1005 | CXXThrowExpr(EmptyShell Empty) : Expr(CXXThrowExprClass, Empty) {} | |||
| 1006 | ||||
| 1007 | const Expr *getSubExpr() const { return cast_or_null<Expr>(Op); } | |||
| 1008 | Expr *getSubExpr() { return cast_or_null<Expr>(Op); } | |||
| 1009 | ||||
| 1010 | SourceLocation getThrowLoc() const { return ThrowLoc; } | |||
| 1011 | ||||
| 1012 | /// \brief Determines whether the variable thrown by this expression (if any!) | |||
| 1013 | /// is within the innermost try block. | |||
| 1014 | /// | |||
| 1015 | /// This information is required to determine whether the NRVO can apply to | |||
| 1016 | /// this variable. | |||
| 1017 | bool isThrownVariableInScope() const { return IsThrownVariableInScope; } | |||
| 1018 | ||||
| 1019 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)) { return ThrowLoc; } | |||
| 1020 | ||||
| 1021 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)) { | |||
| 1022 | if (!getSubExpr()) | |||
| 1023 | return ThrowLoc; | |||
| 1024 | return getSubExpr()->getLocEnd(); | |||
| 1025 | } | |||
| 1026 | ||||
| 1027 | static bool classof(const Stmt *T) { | |||
| 1028 | return T->getStmtClass() == CXXThrowExprClass; | |||
| 1029 | } | |||
| 1030 | ||||
| 1031 | // Iterators | |||
| 1032 | child_range children() { | |||
| 1033 | return child_range(&Op, Op ? &Op+1 : &Op); | |||
| 1034 | } | |||
| 1035 | }; | |||
| 1036 | ||||
| 1037 | /// \brief A default argument (C++ [dcl.fct.default]). | |||
| 1038 | /// | |||
| 1039 | /// This wraps up a function call argument that was created from the | |||
| 1040 | /// corresponding parameter's default argument, when the call did not | |||
| 1041 | /// explicitly supply arguments for all of the parameters. | |||
| 1042 | class CXXDefaultArgExpr final : public Expr { | |||
| 1043 | /// \brief The parameter whose default is being used. | |||
| 1044 | ParmVarDecl *Param; | |||
| 1045 | ||||
| 1046 | /// \brief The location where the default argument expression was used. | |||
| 1047 | SourceLocation Loc; | |||
| 1048 | ||||
| 1049 | CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *param) | |||
| 1050 | : Expr(SC, | |||
| 1051 | param->hasUnparsedDefaultArg() | |||
| 1052 | ? param->getType().getNonReferenceType() | |||
| 1053 | : param->getDefaultArg()->getType(), | |||
| 1054 | param->getDefaultArg()->getValueKind(), | |||
| 1055 | param->getDefaultArg()->getObjectKind(), false, false, false, | |||
| 1056 | false), | |||
| 1057 | Param(param), Loc(Loc) {} | |||
| 1058 | ||||
| 1059 | public: | |||
| 1060 | friend class ASTStmtReader; | |||
| 1061 | friend class ASTStmtWriter; | |||
| 1062 | ||||
| 1063 | CXXDefaultArgExpr(EmptyShell Empty) : Expr(CXXDefaultArgExprClass, Empty) {} | |||
| 1064 | ||||
| 1065 | // \p Param is the parameter whose default argument is used by this | |||
| 1066 | // expression. | |||
| 1067 | static CXXDefaultArgExpr *Create(const ASTContext &C, SourceLocation Loc, | |||
| 1068 | ParmVarDecl *Param) { | |||
| 1069 | return new (C) CXXDefaultArgExpr(CXXDefaultArgExprClass, Loc, Param); | |||
| 1070 | } | |||
| 1071 | ||||
| 1072 | // Retrieve the parameter that the argument was created from. | |||
| 1073 | const ParmVarDecl *getParam() const { return Param; } | |||
| 1074 | ParmVarDecl *getParam() { return Param; } | |||
| 1075 | ||||
| 1076 | // Retrieve the actual argument to the function call. | |||
| 1077 | const Expr *getExpr() const { | |||
| 1078 | return getParam()->getDefaultArg(); | |||
| 1079 | } | |||
| 1080 | Expr *getExpr() { | |||
| 1081 | return getParam()->getDefaultArg(); | |||
| 1082 | } | |||
| 1083 | ||||
| 1084 | /// \brief Retrieve the location where this default argument was actually | |||
| 1085 | /// used. | |||
| 1086 | SourceLocation getUsedLocation() const { return Loc; } | |||
| 1087 | ||||
| 1088 | /// Default argument expressions have no representation in the | |||
| 1089 | /// source, so they have an empty source range. | |||
| 1090 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)) { return SourceLocation(); } | |||
| 1091 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)) { return SourceLocation(); } | |||
| 1092 | ||||
| 1093 | SourceLocation getExprLoc() const LLVM_READONLY__attribute__((__pure__)) { return Loc; } | |||
| 1094 | ||||
| 1095 | static bool classof(const Stmt *T) { | |||
| 1096 | return T->getStmtClass() == CXXDefaultArgExprClass; | |||
| 1097 | } | |||
| 1098 | ||||
| 1099 | // Iterators | |||
| 1100 | child_range children() { | |||
| 1101 | return child_range(child_iterator(), child_iterator()); | |||
| 1102 | } | |||
| 1103 | }; | |||
| 1104 | ||||
| 1105 | /// \brief A use of a default initializer in a constructor or in aggregate | |||
| 1106 | /// initialization. | |||
| 1107 | /// | |||
| 1108 | /// This wraps a use of a C++ default initializer (technically, | |||
| 1109 | /// a brace-or-equal-initializer for a non-static data member) when it | |||
| 1110 | /// is implicitly used in a mem-initializer-list in a constructor | |||
| 1111 | /// (C++11 [class.base.init]p8) or in aggregate initialization | |||
| 1112 | /// (C++1y [dcl.init.aggr]p7). | |||
| 1113 | class CXXDefaultInitExpr : public Expr { | |||
| 1114 | /// \brief The field whose default is being used. | |||
| 1115 | FieldDecl *Field; | |||
| 1116 | ||||
| 1117 | /// \brief The location where the default initializer expression was used. | |||
| 1118 | SourceLocation Loc; | |||
| 1119 | ||||
| 1120 | CXXDefaultInitExpr(const ASTContext &C, SourceLocation Loc, FieldDecl *Field, | |||
| 1121 | QualType T); | |||
| 1122 | ||||
| 1123 | CXXDefaultInitExpr(EmptyShell Empty) : Expr(CXXDefaultInitExprClass, Empty) {} | |||
| 1124 | ||||
| 1125 | public: | |||
| 1126 | friend class ASTReader; | |||
| 1127 | friend class ASTStmtReader; | |||
| 1128 | ||||
| 1129 | /// \p Field is the non-static data member whose default initializer is used | |||
| 1130 | /// by this expression. | |||
| 1131 | static CXXDefaultInitExpr *Create(const ASTContext &C, SourceLocation Loc, | |||
| 1132 | FieldDecl *Field) { | |||
| 1133 | return new (C) CXXDefaultInitExpr(C, Loc, Field, Field->getType()); | |||
| ||||
| 1134 | } | |||
| 1135 | ||||
| 1136 | /// \brief Get the field whose initializer will be used. | |||
| 1137 | FieldDecl *getField() { return Field; } | |||
| 1138 | const FieldDecl *getField() const { return Field; } | |||
| 1139 | ||||
| 1140 | /// \brief Get the initialization expression that will be used. | |||
| 1141 | const Expr *getExpr() const { | |||
| 1142 | assert(Field->getInClassInitializer() && "initializer hasn't been parsed")(static_cast <bool> (Field->getInClassInitializer() && "initializer hasn't been parsed") ? void (0) : __assert_fail ("Field->getInClassInitializer() && \"initializer hasn't been parsed\"" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 1142, __extension__ __PRETTY_FUNCTION__)); | |||
| 1143 | return Field->getInClassInitializer(); | |||
| 1144 | } | |||
| 1145 | Expr *getExpr() { | |||
| 1146 | assert(Field->getInClassInitializer() && "initializer hasn't been parsed")(static_cast <bool> (Field->getInClassInitializer() && "initializer hasn't been parsed") ? void (0) : __assert_fail ("Field->getInClassInitializer() && \"initializer hasn't been parsed\"" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 1146, __extension__ __PRETTY_FUNCTION__)); | |||
| 1147 | return Field->getInClassInitializer(); | |||
| 1148 | } | |||
| 1149 | ||||
| 1150 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)) { return Loc; } | |||
| 1151 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)) { return Loc; } | |||
| 1152 | ||||
| 1153 | static bool classof(const Stmt *T) { | |||
| 1154 | return T->getStmtClass() == CXXDefaultInitExprClass; | |||
| 1155 | } | |||
| 1156 | ||||
| 1157 | // Iterators | |||
| 1158 | child_range children() { | |||
| 1159 | return child_range(child_iterator(), child_iterator()); | |||
| 1160 | } | |||
| 1161 | }; | |||
| 1162 | ||||
| 1163 | /// \brief Represents a C++ temporary. | |||
| 1164 | class CXXTemporary { | |||
| 1165 | /// \brief The destructor that needs to be called. | |||
| 1166 | const CXXDestructorDecl *Destructor; | |||
| 1167 | ||||
| 1168 | explicit CXXTemporary(const CXXDestructorDecl *destructor) | |||
| 1169 | : Destructor(destructor) {} | |||
| 1170 | ||||
| 1171 | public: | |||
| 1172 | static CXXTemporary *Create(const ASTContext &C, | |||
| 1173 | const CXXDestructorDecl *Destructor); | |||
| 1174 | ||||
| 1175 | const CXXDestructorDecl *getDestructor() const { return Destructor; } | |||
| 1176 | ||||
| 1177 | void setDestructor(const CXXDestructorDecl *Dtor) { | |||
| 1178 | Destructor = Dtor; | |||
| 1179 | } | |||
| 1180 | }; | |||
| 1181 | ||||
| 1182 | /// \brief Represents binding an expression to a temporary. | |||
| 1183 | /// | |||
| 1184 | /// This ensures the destructor is called for the temporary. It should only be | |||
| 1185 | /// needed for non-POD, non-trivially destructable class types. For example: | |||
| 1186 | /// | |||
| 1187 | /// \code | |||
| 1188 | /// struct S { | |||
| 1189 | /// S() { } // User defined constructor makes S non-POD. | |||
| 1190 | /// ~S() { } // User defined destructor makes it non-trivial. | |||
| 1191 | /// }; | |||
| 1192 | /// void test() { | |||
| 1193 | /// const S &s_ref = S(); // Requires a CXXBindTemporaryExpr. | |||
| 1194 | /// } | |||
| 1195 | /// \endcode | |||
| 1196 | class CXXBindTemporaryExpr : public Expr { | |||
| 1197 | CXXTemporary *Temp = nullptr; | |||
| 1198 | Stmt *SubExpr = nullptr; | |||
| 1199 | ||||
| 1200 | CXXBindTemporaryExpr(CXXTemporary *temp, Expr* SubExpr) | |||
| 1201 | : Expr(CXXBindTemporaryExprClass, SubExpr->getType(), | |||
| 1202 | VK_RValue, OK_Ordinary, SubExpr->isTypeDependent(), | |||
| 1203 | SubExpr->isValueDependent(), | |||
| 1204 | SubExpr->isInstantiationDependent(), | |||
| 1205 | SubExpr->containsUnexpandedParameterPack()), | |||
| 1206 | Temp(temp), SubExpr(SubExpr) {} | |||
| 1207 | ||||
| 1208 | public: | |||
| 1209 | CXXBindTemporaryExpr(EmptyShell Empty) | |||
| 1210 | : Expr(CXXBindTemporaryExprClass, Empty) {} | |||
| 1211 | ||||
| 1212 | static CXXBindTemporaryExpr *Create(const ASTContext &C, CXXTemporary *Temp, | |||
| 1213 | Expr* SubExpr); | |||
| 1214 | ||||
| 1215 | CXXTemporary *getTemporary() { return Temp; } | |||
| 1216 | const CXXTemporary *getTemporary() const { return Temp; } | |||
| 1217 | void setTemporary(CXXTemporary *T) { Temp = T; } | |||
| 1218 | ||||
| 1219 | const Expr *getSubExpr() const { return cast<Expr>(SubExpr); } | |||
| 1220 | Expr *getSubExpr() { return cast<Expr>(SubExpr); } | |||
| 1221 | void setSubExpr(Expr *E) { SubExpr = E; } | |||
| 1222 | ||||
| 1223 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)) { | |||
| 1224 | return SubExpr->getLocStart(); | |||
| 1225 | } | |||
| 1226 | ||||
| 1227 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)) { return SubExpr->getLocEnd();} | |||
| 1228 | ||||
| 1229 | // Implement isa/cast/dyncast/etc. | |||
| 1230 | static bool classof(const Stmt *T) { | |||
| 1231 | return T->getStmtClass() == CXXBindTemporaryExprClass; | |||
| 1232 | } | |||
| 1233 | ||||
| 1234 | // Iterators | |||
| 1235 | child_range children() { return child_range(&SubExpr, &SubExpr + 1); } | |||
| 1236 | }; | |||
| 1237 | ||||
| 1238 | /// \brief Represents a call to a C++ constructor. | |||
| 1239 | class CXXConstructExpr : public Expr { | |||
| 1240 | public: | |||
| 1241 | enum ConstructionKind { | |||
| 1242 | CK_Complete, | |||
| 1243 | CK_NonVirtualBase, | |||
| 1244 | CK_VirtualBase, | |||
| 1245 | CK_Delegating | |||
| 1246 | }; | |||
| 1247 | ||||
| 1248 | private: | |||
| 1249 | CXXConstructorDecl *Constructor = nullptr; | |||
| 1250 | SourceLocation Loc; | |||
| 1251 | SourceRange ParenOrBraceRange; | |||
| 1252 | unsigned NumArgs : 16; | |||
| 1253 | unsigned Elidable : 1; | |||
| 1254 | unsigned HadMultipleCandidates : 1; | |||
| 1255 | unsigned ListInitialization : 1; | |||
| 1256 | unsigned StdInitListInitialization : 1; | |||
| 1257 | unsigned ZeroInitialization : 1; | |||
| 1258 | unsigned ConstructKind : 2; | |||
| 1259 | Stmt **Args = nullptr; | |||
| 1260 | ||||
| 1261 | void setConstructor(CXXConstructorDecl *C) { Constructor = C; } | |||
| 1262 | ||||
| 1263 | protected: | |||
| 1264 | CXXConstructExpr(const ASTContext &C, StmtClass SC, QualType T, | |||
| 1265 | SourceLocation Loc, | |||
| 1266 | CXXConstructorDecl *Ctor, | |||
| 1267 | bool Elidable, | |||
| 1268 | ArrayRef<Expr *> Args, | |||
| 1269 | bool HadMultipleCandidates, | |||
| 1270 | bool ListInitialization, | |||
| 1271 | bool StdInitListInitialization, | |||
| 1272 | bool ZeroInitialization, | |||
| 1273 | ConstructionKind ConstructKind, | |||
| 1274 | SourceRange ParenOrBraceRange); | |||
| 1275 | ||||
| 1276 | /// \brief Construct an empty C++ construction expression. | |||
| 1277 | CXXConstructExpr(StmtClass SC, EmptyShell Empty) | |||
| 1278 | : Expr(SC, Empty), NumArgs(0), Elidable(false), | |||
| 1279 | HadMultipleCandidates(false), ListInitialization(false), | |||
| 1280 | ZeroInitialization(false), ConstructKind(0) {} | |||
| 1281 | ||||
| 1282 | public: | |||
| 1283 | friend class ASTStmtReader; | |||
| 1284 | ||||
| 1285 | /// \brief Construct an empty C++ construction expression. | |||
| 1286 | explicit CXXConstructExpr(EmptyShell Empty) | |||
| 1287 | : CXXConstructExpr(CXXConstructExprClass, Empty) {} | |||
| 1288 | ||||
| 1289 | static CXXConstructExpr *Create(const ASTContext &C, QualType T, | |||
| 1290 | SourceLocation Loc, | |||
| 1291 | CXXConstructorDecl *Ctor, | |||
| 1292 | bool Elidable, | |||
| 1293 | ArrayRef<Expr *> Args, | |||
| 1294 | bool HadMultipleCandidates, | |||
| 1295 | bool ListInitialization, | |||
| 1296 | bool StdInitListInitialization, | |||
| 1297 | bool ZeroInitialization, | |||
| 1298 | ConstructionKind ConstructKind, | |||
| 1299 | SourceRange ParenOrBraceRange); | |||
| 1300 | ||||
| 1301 | /// \brief Get the constructor that this expression will (ultimately) call. | |||
| 1302 | CXXConstructorDecl *getConstructor() const { return Constructor; } | |||
| 1303 | ||||
| 1304 | SourceLocation getLocation() const { return Loc; } | |||
| 1305 | void setLocation(SourceLocation Loc) { this->Loc = Loc; } | |||
| 1306 | ||||
| 1307 | /// \brief Whether this construction is elidable. | |||
| 1308 | bool isElidable() const { return Elidable; } | |||
| 1309 | void setElidable(bool E) { Elidable = E; } | |||
| 1310 | ||||
| 1311 | /// \brief Whether the referred constructor was resolved from | |||
| 1312 | /// an overloaded set having size greater than 1. | |||
| 1313 | bool hadMultipleCandidates() const { return HadMultipleCandidates; } | |||
| 1314 | void setHadMultipleCandidates(bool V) { HadMultipleCandidates = V; } | |||
| 1315 | ||||
| 1316 | /// \brief Whether this constructor call was written as list-initialization. | |||
| 1317 | bool isListInitialization() const { return ListInitialization; } | |||
| 1318 | void setListInitialization(bool V) { ListInitialization = V; } | |||
| 1319 | ||||
| 1320 | /// \brief Whether this constructor call was written as list-initialization, | |||
| 1321 | /// but was interpreted as forming a std::initializer_list<T> from the list | |||
| 1322 | /// and passing that as a single constructor argument. | |||
| 1323 | /// See C++11 [over.match.list]p1 bullet 1. | |||
| 1324 | bool isStdInitListInitialization() const { return StdInitListInitialization; } | |||
| 1325 | void setStdInitListInitialization(bool V) { StdInitListInitialization = V; } | |||
| 1326 | ||||
| 1327 | /// \brief Whether this construction first requires | |||
| 1328 | /// zero-initialization before the initializer is called. | |||
| 1329 | bool requiresZeroInitialization() const { return ZeroInitialization; } | |||
| 1330 | void setRequiresZeroInitialization(bool ZeroInit) { | |||
| 1331 | ZeroInitialization = ZeroInit; | |||
| 1332 | } | |||
| 1333 | ||||
| 1334 | /// \brief Determine whether this constructor is actually constructing | |||
| 1335 | /// a base class (rather than a complete object). | |||
| 1336 | ConstructionKind getConstructionKind() const { | |||
| 1337 | return (ConstructionKind)ConstructKind; | |||
| 1338 | } | |||
| 1339 | void setConstructionKind(ConstructionKind CK) { | |||
| 1340 | ConstructKind = CK; | |||
| 1341 | } | |||
| 1342 | ||||
| 1343 | using arg_iterator = ExprIterator; | |||
| 1344 | using const_arg_iterator = ConstExprIterator; | |||
| 1345 | using arg_range = llvm::iterator_range<arg_iterator>; | |||
| 1346 | using arg_const_range = llvm::iterator_range<const_arg_iterator>; | |||
| 1347 | ||||
| 1348 | arg_range arguments() { return arg_range(arg_begin(), arg_end()); } | |||
| 1349 | arg_const_range arguments() const { | |||
| 1350 | return arg_const_range(arg_begin(), arg_end()); | |||
| 1351 | } | |||
| 1352 | ||||
| 1353 | arg_iterator arg_begin() { return Args; } | |||
| 1354 | arg_iterator arg_end() { return Args + NumArgs; } | |||
| 1355 | const_arg_iterator arg_begin() const { return Args; } | |||
| 1356 | const_arg_iterator arg_end() const { return Args + NumArgs; } | |||
| 1357 | ||||
| 1358 | Expr **getArgs() { return reinterpret_cast<Expr **>(Args); } | |||
| 1359 | const Expr *const *getArgs() const { | |||
| 1360 | return const_cast<CXXConstructExpr *>(this)->getArgs(); | |||
| 1361 | } | |||
| 1362 | unsigned getNumArgs() const { return NumArgs; } | |||
| 1363 | ||||
| 1364 | /// \brief Return the specified argument. | |||
| 1365 | Expr *getArg(unsigned Arg) { | |||
| 1366 | assert(Arg < NumArgs && "Arg access out of range!")(static_cast <bool> (Arg < NumArgs && "Arg access out of range!" ) ? void (0) : __assert_fail ("Arg < NumArgs && \"Arg access out of range!\"" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 1366, __extension__ __PRETTY_FUNCTION__)); | |||
| 1367 | return cast<Expr>(Args[Arg]); | |||
| 1368 | } | |||
| 1369 | const Expr *getArg(unsigned Arg) const { | |||
| 1370 | assert(Arg < NumArgs && "Arg access out of range!")(static_cast <bool> (Arg < NumArgs && "Arg access out of range!" ) ? void (0) : __assert_fail ("Arg < NumArgs && \"Arg access out of range!\"" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 1370, __extension__ __PRETTY_FUNCTION__)); | |||
| 1371 | return cast<Expr>(Args[Arg]); | |||
| 1372 | } | |||
| 1373 | ||||
| 1374 | /// \brief Set the specified argument. | |||
| 1375 | void setArg(unsigned Arg, Expr *ArgExpr) { | |||
| 1376 | assert(Arg < NumArgs && "Arg access out of range!")(static_cast <bool> (Arg < NumArgs && "Arg access out of range!" ) ? void (0) : __assert_fail ("Arg < NumArgs && \"Arg access out of range!\"" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 1376, __extension__ __PRETTY_FUNCTION__)); | |||
| 1377 | Args[Arg] = ArgExpr; | |||
| 1378 | } | |||
| 1379 | ||||
| 1380 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)); | |||
| 1381 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)); | |||
| 1382 | SourceRange getParenOrBraceRange() const { return ParenOrBraceRange; } | |||
| 1383 | void setParenOrBraceRange(SourceRange Range) { ParenOrBraceRange = Range; } | |||
| 1384 | ||||
| 1385 | static bool classof(const Stmt *T) { | |||
| 1386 | return T->getStmtClass() == CXXConstructExprClass || | |||
| 1387 | T->getStmtClass() == CXXTemporaryObjectExprClass; | |||
| 1388 | } | |||
| 1389 | ||||
| 1390 | // Iterators | |||
| 1391 | child_range children() { | |||
| 1392 | return child_range(&Args[0], &Args[0]+NumArgs); | |||
| 1393 | } | |||
| 1394 | }; | |||
| 1395 | ||||
| 1396 | /// \brief Represents a call to an inherited base class constructor from an | |||
| 1397 | /// inheriting constructor. This call implicitly forwards the arguments from | |||
| 1398 | /// the enclosing context (an inheriting constructor) to the specified inherited | |||
| 1399 | /// base class constructor. | |||
| 1400 | class CXXInheritedCtorInitExpr : public Expr { | |||
| 1401 | private: | |||
| 1402 | CXXConstructorDecl *Constructor = nullptr; | |||
| 1403 | ||||
| 1404 | /// The location of the using declaration. | |||
| 1405 | SourceLocation Loc; | |||
| 1406 | ||||
| 1407 | /// Whether this is the construction of a virtual base. | |||
| 1408 | unsigned ConstructsVirtualBase : 1; | |||
| 1409 | ||||
| 1410 | /// Whether the constructor is inherited from a virtual base class of the | |||
| 1411 | /// class that we construct. | |||
| 1412 | unsigned InheritedFromVirtualBase : 1; | |||
| 1413 | ||||
| 1414 | public: | |||
| 1415 | friend class ASTStmtReader; | |||
| 1416 | ||||
| 1417 | /// \brief Construct a C++ inheriting construction expression. | |||
| 1418 | CXXInheritedCtorInitExpr(SourceLocation Loc, QualType T, | |||
| 1419 | CXXConstructorDecl *Ctor, bool ConstructsVirtualBase, | |||
| 1420 | bool InheritedFromVirtualBase) | |||
| 1421 | : Expr(CXXInheritedCtorInitExprClass, T, VK_RValue, OK_Ordinary, false, | |||
| 1422 | false, false, false), | |||
| 1423 | Constructor(Ctor), Loc(Loc), | |||
| 1424 | ConstructsVirtualBase(ConstructsVirtualBase), | |||
| 1425 | InheritedFromVirtualBase(InheritedFromVirtualBase) { | |||
| 1426 | assert(!T->isDependentType())(static_cast <bool> (!T->isDependentType()) ? void ( 0) : __assert_fail ("!T->isDependentType()", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 1426, __extension__ __PRETTY_FUNCTION__)); | |||
| 1427 | } | |||
| 1428 | ||||
| 1429 | /// \brief Construct an empty C++ inheriting construction expression. | |||
| 1430 | explicit CXXInheritedCtorInitExpr(EmptyShell Empty) | |||
| 1431 | : Expr(CXXInheritedCtorInitExprClass, Empty), | |||
| 1432 | ConstructsVirtualBase(false), InheritedFromVirtualBase(false) {} | |||
| 1433 | ||||
| 1434 | /// \brief Get the constructor that this expression will call. | |||
| 1435 | CXXConstructorDecl *getConstructor() const { return Constructor; } | |||
| 1436 | ||||
| 1437 | /// \brief Determine whether this constructor is actually constructing | |||
| 1438 | /// a base class (rather than a complete object). | |||
| 1439 | bool constructsVBase() const { return ConstructsVirtualBase; } | |||
| 1440 | CXXConstructExpr::ConstructionKind getConstructionKind() const { | |||
| 1441 | return ConstructsVirtualBase ? CXXConstructExpr::CK_VirtualBase | |||
| 1442 | : CXXConstructExpr::CK_NonVirtualBase; | |||
| 1443 | } | |||
| 1444 | ||||
| 1445 | /// \brief Determine whether the inherited constructor is inherited from a | |||
| 1446 | /// virtual base of the object we construct. If so, we are not responsible | |||
| 1447 | /// for calling the inherited constructor (the complete object constructor | |||
| 1448 | /// does that), and so we don't need to pass any arguments. | |||
| 1449 | bool inheritedFromVBase() const { return InheritedFromVirtualBase; } | |||
| 1450 | ||||
| 1451 | SourceLocation getLocation() const LLVM_READONLY__attribute__((__pure__)) { return Loc; } | |||
| 1452 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)) { return Loc; } | |||
| 1453 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)) { return Loc; } | |||
| 1454 | ||||
| 1455 | static bool classof(const Stmt *T) { | |||
| 1456 | return T->getStmtClass() == CXXInheritedCtorInitExprClass; | |||
| 1457 | } | |||
| 1458 | ||||
| 1459 | child_range children() { | |||
| 1460 | return child_range(child_iterator(), child_iterator()); | |||
| 1461 | } | |||
| 1462 | }; | |||
| 1463 | ||||
| 1464 | /// \brief Represents an explicit C++ type conversion that uses "functional" | |||
| 1465 | /// notation (C++ [expr.type.conv]). | |||
| 1466 | /// | |||
| 1467 | /// Example: | |||
| 1468 | /// \code | |||
| 1469 | /// x = int(0.5); | |||
| 1470 | /// \endcode | |||
| 1471 | class CXXFunctionalCastExpr final | |||
| 1472 | : public ExplicitCastExpr, | |||
| 1473 | private llvm::TrailingObjects<CXXFunctionalCastExpr, CXXBaseSpecifier *> { | |||
| 1474 | SourceLocation LParenLoc; | |||
| 1475 | SourceLocation RParenLoc; | |||
| 1476 | ||||
| 1477 | CXXFunctionalCastExpr(QualType ty, ExprValueKind VK, | |||
| 1478 | TypeSourceInfo *writtenTy, | |||
| 1479 | CastKind kind, Expr *castExpr, unsigned pathSize, | |||
| 1480 | SourceLocation lParenLoc, SourceLocation rParenLoc) | |||
| 1481 | : ExplicitCastExpr(CXXFunctionalCastExprClass, ty, VK, kind, | |||
| 1482 | castExpr, pathSize, writtenTy), | |||
| 1483 | LParenLoc(lParenLoc), RParenLoc(rParenLoc) {} | |||
| 1484 | ||||
| 1485 | explicit CXXFunctionalCastExpr(EmptyShell Shell, unsigned PathSize) | |||
| 1486 | : ExplicitCastExpr(CXXFunctionalCastExprClass, Shell, PathSize) {} | |||
| 1487 | ||||
| 1488 | public: | |||
| 1489 | friend class CastExpr; | |||
| 1490 | friend TrailingObjects; | |||
| 1491 | ||||
| 1492 | static CXXFunctionalCastExpr *Create(const ASTContext &Context, QualType T, | |||
| 1493 | ExprValueKind VK, | |||
| 1494 | TypeSourceInfo *Written, | |||
| 1495 | CastKind Kind, Expr *Op, | |||
| 1496 | const CXXCastPath *Path, | |||
| 1497 | SourceLocation LPLoc, | |||
| 1498 | SourceLocation RPLoc); | |||
| 1499 | static CXXFunctionalCastExpr *CreateEmpty(const ASTContext &Context, | |||
| 1500 | unsigned PathSize); | |||
| 1501 | ||||
| 1502 | SourceLocation getLParenLoc() const { return LParenLoc; } | |||
| 1503 | void setLParenLoc(SourceLocation L) { LParenLoc = L; } | |||
| 1504 | SourceLocation getRParenLoc() const { return RParenLoc; } | |||
| 1505 | void setRParenLoc(SourceLocation L) { RParenLoc = L; } | |||
| 1506 | ||||
| 1507 | /// Determine whether this expression models list-initialization. | |||
| 1508 | bool isListInitialization() const { return LParenLoc.isInvalid(); } | |||
| 1509 | ||||
| 1510 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)); | |||
| 1511 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)); | |||
| 1512 | ||||
| 1513 | static bool classof(const Stmt *T) { | |||
| 1514 | return T->getStmtClass() == CXXFunctionalCastExprClass; | |||
| 1515 | } | |||
| 1516 | }; | |||
| 1517 | ||||
| 1518 | /// @brief Represents a C++ functional cast expression that builds a | |||
| 1519 | /// temporary object. | |||
| 1520 | /// | |||
| 1521 | /// This expression type represents a C++ "functional" cast | |||
| 1522 | /// (C++[expr.type.conv]) with N != 1 arguments that invokes a | |||
| 1523 | /// constructor to build a temporary object. With N == 1 arguments the | |||
| 1524 | /// functional cast expression will be represented by CXXFunctionalCastExpr. | |||
| 1525 | /// Example: | |||
| 1526 | /// \code | |||
| 1527 | /// struct X { X(int, float); } | |||
| 1528 | /// | |||
| 1529 | /// X create_X() { | |||
| 1530 | /// return X(1, 3.14f); // creates a CXXTemporaryObjectExpr | |||
| 1531 | /// }; | |||
| 1532 | /// \endcode | |||
| 1533 | class CXXTemporaryObjectExpr : public CXXConstructExpr { | |||
| 1534 | TypeSourceInfo *Type = nullptr; | |||
| 1535 | ||||
| 1536 | public: | |||
| 1537 | friend class ASTStmtReader; | |||
| 1538 | ||||
| 1539 | CXXTemporaryObjectExpr(const ASTContext &C, | |||
| 1540 | CXXConstructorDecl *Cons, | |||
| 1541 | QualType Type, | |||
| 1542 | TypeSourceInfo *TSI, | |||
| 1543 | ArrayRef<Expr *> Args, | |||
| 1544 | SourceRange ParenOrBraceRange, | |||
| 1545 | bool HadMultipleCandidates, | |||
| 1546 | bool ListInitialization, | |||
| 1547 | bool StdInitListInitialization, | |||
| 1548 | bool ZeroInitialization); | |||
| 1549 | explicit CXXTemporaryObjectExpr(EmptyShell Empty) | |||
| 1550 | : CXXConstructExpr(CXXTemporaryObjectExprClass, Empty) {} | |||
| 1551 | ||||
| 1552 | TypeSourceInfo *getTypeSourceInfo() const { return Type; } | |||
| 1553 | ||||
| 1554 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)); | |||
| 1555 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)); | |||
| 1556 | ||||
| 1557 | static bool classof(const Stmt *T) { | |||
| 1558 | return T->getStmtClass() == CXXTemporaryObjectExprClass; | |||
| 1559 | } | |||
| 1560 | }; | |||
| 1561 | ||||
| 1562 | /// \brief A C++ lambda expression, which produces a function object | |||
| 1563 | /// (of unspecified type) that can be invoked later. | |||
| 1564 | /// | |||
| 1565 | /// Example: | |||
| 1566 | /// \code | |||
| 1567 | /// void low_pass_filter(std::vector<double> &values, double cutoff) { | |||
| 1568 | /// values.erase(std::remove_if(values.begin(), values.end(), | |||
| 1569 | /// [=](double value) { return value > cutoff; }); | |||
| 1570 | /// } | |||
| 1571 | /// \endcode | |||
| 1572 | /// | |||
| 1573 | /// C++11 lambda expressions can capture local variables, either by copying | |||
| 1574 | /// the values of those local variables at the time the function | |||
| 1575 | /// object is constructed (not when it is called!) or by holding a | |||
| 1576 | /// reference to the local variable. These captures can occur either | |||
| 1577 | /// implicitly or can be written explicitly between the square | |||
| 1578 | /// brackets ([...]) that start the lambda expression. | |||
| 1579 | /// | |||
| 1580 | /// C++1y introduces a new form of "capture" called an init-capture that | |||
| 1581 | /// includes an initializing expression (rather than capturing a variable), | |||
| 1582 | /// and which can never occur implicitly. | |||
| 1583 | class LambdaExpr final : public Expr, | |||
| 1584 | private llvm::TrailingObjects<LambdaExpr, Stmt *> { | |||
| 1585 | /// \brief The source range that covers the lambda introducer ([...]). | |||
| 1586 | SourceRange IntroducerRange; | |||
| 1587 | ||||
| 1588 | /// \brief The source location of this lambda's capture-default ('=' or '&'). | |||
| 1589 | SourceLocation CaptureDefaultLoc; | |||
| 1590 | ||||
| 1591 | /// \brief The number of captures. | |||
| 1592 | unsigned NumCaptures : 16; | |||
| 1593 | ||||
| 1594 | /// \brief The default capture kind, which is a value of type | |||
| 1595 | /// LambdaCaptureDefault. | |||
| 1596 | unsigned CaptureDefault : 2; | |||
| 1597 | ||||
| 1598 | /// \brief Whether this lambda had an explicit parameter list vs. an | |||
| 1599 | /// implicit (and empty) parameter list. | |||
| 1600 | unsigned ExplicitParams : 1; | |||
| 1601 | ||||
| 1602 | /// \brief Whether this lambda had the result type explicitly specified. | |||
| 1603 | unsigned ExplicitResultType : 1; | |||
| 1604 | ||||
| 1605 | /// \brief The location of the closing brace ('}') that completes | |||
| 1606 | /// the lambda. | |||
| 1607 | /// | |||
| 1608 | /// The location of the brace is also available by looking up the | |||
| 1609 | /// function call operator in the lambda class. However, it is | |||
| 1610 | /// stored here to improve the performance of getSourceRange(), and | |||
| 1611 | /// to avoid having to deserialize the function call operator from a | |||
| 1612 | /// module file just to determine the source range. | |||
| 1613 | SourceLocation ClosingBrace; | |||
| 1614 | ||||
| 1615 | /// \brief Construct a lambda expression. | |||
| 1616 | LambdaExpr(QualType T, SourceRange IntroducerRange, | |||
| 1617 | LambdaCaptureDefault CaptureDefault, | |||
| 1618 | SourceLocation CaptureDefaultLoc, ArrayRef<LambdaCapture> Captures, | |||
| 1619 | bool ExplicitParams, bool ExplicitResultType, | |||
| 1620 | ArrayRef<Expr *> CaptureInits, SourceLocation ClosingBrace, | |||
| 1621 | bool ContainsUnexpandedParameterPack); | |||
| 1622 | ||||
| 1623 | /// \brief Construct an empty lambda expression. | |||
| 1624 | LambdaExpr(EmptyShell Empty, unsigned NumCaptures) | |||
| 1625 | : Expr(LambdaExprClass, Empty), NumCaptures(NumCaptures), | |||
| 1626 | CaptureDefault(LCD_None), ExplicitParams(false), | |||
| 1627 | ExplicitResultType(false) { | |||
| 1628 | getStoredStmts()[NumCaptures] = nullptr; | |||
| 1629 | } | |||
| 1630 | ||||
| 1631 | Stmt **getStoredStmts() { return getTrailingObjects<Stmt *>(); } | |||
| 1632 | ||||
| 1633 | Stmt *const *getStoredStmts() const { return getTrailingObjects<Stmt *>(); } | |||
| 1634 | ||||
| 1635 | public: | |||
| 1636 | friend class ASTStmtReader; | |||
| 1637 | friend class ASTStmtWriter; | |||
| 1638 | friend TrailingObjects; | |||
| 1639 | ||||
| 1640 | /// \brief Construct a new lambda expression. | |||
| 1641 | static LambdaExpr * | |||
| 1642 | Create(const ASTContext &C, CXXRecordDecl *Class, SourceRange IntroducerRange, | |||
| 1643 | LambdaCaptureDefault CaptureDefault, SourceLocation CaptureDefaultLoc, | |||
| 1644 | ArrayRef<LambdaCapture> Captures, bool ExplicitParams, | |||
| 1645 | bool ExplicitResultType, ArrayRef<Expr *> CaptureInits, | |||
| 1646 | SourceLocation ClosingBrace, bool ContainsUnexpandedParameterPack); | |||
| 1647 | ||||
| 1648 | /// \brief Construct a new lambda expression that will be deserialized from | |||
| 1649 | /// an external source. | |||
| 1650 | static LambdaExpr *CreateDeserialized(const ASTContext &C, | |||
| 1651 | unsigned NumCaptures); | |||
| 1652 | ||||
| 1653 | /// \brief Determine the default capture kind for this lambda. | |||
| 1654 | LambdaCaptureDefault getCaptureDefault() const { | |||
| 1655 | return static_cast<LambdaCaptureDefault>(CaptureDefault); | |||
| 1656 | } | |||
| 1657 | ||||
| 1658 | /// \brief Retrieve the location of this lambda's capture-default, if any. | |||
| 1659 | SourceLocation getCaptureDefaultLoc() const { | |||
| 1660 | return CaptureDefaultLoc; | |||
| 1661 | } | |||
| 1662 | ||||
| 1663 | /// \brief Determine whether one of this lambda's captures is an init-capture. | |||
| 1664 | bool isInitCapture(const LambdaCapture *Capture) const; | |||
| 1665 | ||||
| 1666 | /// \brief An iterator that walks over the captures of the lambda, | |||
| 1667 | /// both implicit and explicit. | |||
| 1668 | using capture_iterator = const LambdaCapture *; | |||
| 1669 | ||||
| 1670 | /// \brief An iterator over a range of lambda captures. | |||
| 1671 | using capture_range = llvm::iterator_range<capture_iterator>; | |||
| 1672 | ||||
| 1673 | /// \brief Retrieve this lambda's captures. | |||
| 1674 | capture_range captures() const; | |||
| 1675 | ||||
| 1676 | /// \brief Retrieve an iterator pointing to the first lambda capture. | |||
| 1677 | capture_iterator capture_begin() const; | |||
| 1678 | ||||
| 1679 | /// \brief Retrieve an iterator pointing past the end of the | |||
| 1680 | /// sequence of lambda captures. | |||
| 1681 | capture_iterator capture_end() const; | |||
| 1682 | ||||
| 1683 | /// \brief Determine the number of captures in this lambda. | |||
| 1684 | unsigned capture_size() const { return NumCaptures; } | |||
| 1685 | ||||
| 1686 | /// \brief Retrieve this lambda's explicit captures. | |||
| 1687 | capture_range explicit_captures() const; | |||
| 1688 | ||||
| 1689 | /// \brief Retrieve an iterator pointing to the first explicit | |||
| 1690 | /// lambda capture. | |||
| 1691 | capture_iterator explicit_capture_begin() const; | |||
| 1692 | ||||
| 1693 | /// \brief Retrieve an iterator pointing past the end of the sequence of | |||
| 1694 | /// explicit lambda captures. | |||
| 1695 | capture_iterator explicit_capture_end() const; | |||
| 1696 | ||||
| 1697 | /// \brief Retrieve this lambda's implicit captures. | |||
| 1698 | capture_range implicit_captures() const; | |||
| 1699 | ||||
| 1700 | /// \brief Retrieve an iterator pointing to the first implicit | |||
| 1701 | /// lambda capture. | |||
| 1702 | capture_iterator implicit_capture_begin() const; | |||
| 1703 | ||||
| 1704 | /// \brief Retrieve an iterator pointing past the end of the sequence of | |||
| 1705 | /// implicit lambda captures. | |||
| 1706 | capture_iterator implicit_capture_end() const; | |||
| 1707 | ||||
| 1708 | /// \brief Iterator that walks over the capture initialization | |||
| 1709 | /// arguments. | |||
| 1710 | using capture_init_iterator = Expr **; | |||
| 1711 | ||||
| 1712 | /// \brief Const iterator that walks over the capture initialization | |||
| 1713 | /// arguments. | |||
| 1714 | using const_capture_init_iterator = Expr *const *; | |||
| 1715 | ||||
| 1716 | /// \brief Retrieve the initialization expressions for this lambda's captures. | |||
| 1717 | llvm::iterator_range<capture_init_iterator> capture_inits() { | |||
| 1718 | return llvm::make_range(capture_init_begin(), capture_init_end()); | |||
| 1719 | } | |||
| 1720 | ||||
| 1721 | /// \brief Retrieve the initialization expressions for this lambda's captures. | |||
| 1722 | llvm::iterator_range<const_capture_init_iterator> capture_inits() const { | |||
| 1723 | return llvm::make_range(capture_init_begin(), capture_init_end()); | |||
| 1724 | } | |||
| 1725 | ||||
| 1726 | /// \brief Retrieve the first initialization argument for this | |||
| 1727 | /// lambda expression (which initializes the first capture field). | |||
| 1728 | capture_init_iterator capture_init_begin() { | |||
| 1729 | return reinterpret_cast<Expr **>(getStoredStmts()); | |||
| 1730 | } | |||
| 1731 | ||||
| 1732 | /// \brief Retrieve the first initialization argument for this | |||
| 1733 | /// lambda expression (which initializes the first capture field). | |||
| 1734 | const_capture_init_iterator capture_init_begin() const { | |||
| 1735 | return reinterpret_cast<Expr *const *>(getStoredStmts()); | |||
| 1736 | } | |||
| 1737 | ||||
| 1738 | /// \brief Retrieve the iterator pointing one past the last | |||
| 1739 | /// initialization argument for this lambda expression. | |||
| 1740 | capture_init_iterator capture_init_end() { | |||
| 1741 | return capture_init_begin() + NumCaptures; | |||
| 1742 | } | |||
| 1743 | ||||
| 1744 | /// \brief Retrieve the iterator pointing one past the last | |||
| 1745 | /// initialization argument for this lambda expression. | |||
| 1746 | const_capture_init_iterator capture_init_end() const { | |||
| 1747 | return capture_init_begin() + NumCaptures; | |||
| 1748 | } | |||
| 1749 | ||||
| 1750 | /// \brief Retrieve the source range covering the lambda introducer, | |||
| 1751 | /// which contains the explicit capture list surrounded by square | |||
| 1752 | /// brackets ([...]). | |||
| 1753 | SourceRange getIntroducerRange() const { return IntroducerRange; } | |||
| 1754 | ||||
| 1755 | /// \brief Retrieve the class that corresponds to the lambda. | |||
| 1756 | /// | |||
| 1757 | /// This is the "closure type" (C++1y [expr.prim.lambda]), and stores the | |||
| 1758 | /// captures in its fields and provides the various operations permitted | |||
| 1759 | /// on a lambda (copying, calling). | |||
| 1760 | CXXRecordDecl *getLambdaClass() const; | |||
| 1761 | ||||
| 1762 | /// \brief Retrieve the function call operator associated with this | |||
| 1763 | /// lambda expression. | |||
| 1764 | CXXMethodDecl *getCallOperator() const; | |||
| 1765 | ||||
| 1766 | /// \brief If this is a generic lambda expression, retrieve the template | |||
| 1767 | /// parameter list associated with it, or else return null. | |||
| 1768 | TemplateParameterList *getTemplateParameterList() const; | |||
| 1769 | ||||
| 1770 | /// \brief Whether this is a generic lambda. | |||
| 1771 | bool isGenericLambda() const { return getTemplateParameterList(); } | |||
| 1772 | ||||
| 1773 | /// \brief Retrieve the body of the lambda. | |||
| 1774 | CompoundStmt *getBody() const; | |||
| 1775 | ||||
| 1776 | /// \brief Determine whether the lambda is mutable, meaning that any | |||
| 1777 | /// captures values can be modified. | |||
| 1778 | bool isMutable() const; | |||
| 1779 | ||||
| 1780 | /// \brief Determine whether this lambda has an explicit parameter | |||
| 1781 | /// list vs. an implicit (empty) parameter list. | |||
| 1782 | bool hasExplicitParameters() const { return ExplicitParams; } | |||
| 1783 | ||||
| 1784 | /// \brief Whether this lambda had its result type explicitly specified. | |||
| 1785 | bool hasExplicitResultType() const { return ExplicitResultType; } | |||
| 1786 | ||||
| 1787 | static bool classof(const Stmt *T) { | |||
| 1788 | return T->getStmtClass() == LambdaExprClass; | |||
| 1789 | } | |||
| 1790 | ||||
| 1791 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)) { | |||
| 1792 | return IntroducerRange.getBegin(); | |||
| 1793 | } | |||
| 1794 | ||||
| 1795 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)) { return ClosingBrace; } | |||
| 1796 | ||||
| 1797 | child_range children() { | |||
| 1798 | // Includes initialization exprs plus body stmt | |||
| 1799 | return child_range(getStoredStmts(), getStoredStmts() + NumCaptures + 1); | |||
| 1800 | } | |||
| 1801 | }; | |||
| 1802 | ||||
| 1803 | /// An expression "T()" which creates a value-initialized rvalue of type | |||
| 1804 | /// T, which is a non-class type. See (C++98 [5.2.3p2]). | |||
| 1805 | class CXXScalarValueInitExpr : public Expr { | |||
| 1806 | friend class ASTStmtReader; | |||
| 1807 | ||||
| 1808 | SourceLocation RParenLoc; | |||
| 1809 | TypeSourceInfo *TypeInfo; | |||
| 1810 | ||||
| 1811 | public: | |||
| 1812 | /// \brief Create an explicitly-written scalar-value initialization | |||
| 1813 | /// expression. | |||
| 1814 | CXXScalarValueInitExpr(QualType Type, TypeSourceInfo *TypeInfo, | |||
| 1815 | SourceLocation rParenLoc) | |||
| 1816 | : Expr(CXXScalarValueInitExprClass, Type, VK_RValue, OK_Ordinary, | |||
| 1817 | false, false, Type->isInstantiationDependentType(), | |||
| 1818 | Type->containsUnexpandedParameterPack()), | |||
| 1819 | RParenLoc(rParenLoc), TypeInfo(TypeInfo) {} | |||
| 1820 | ||||
| 1821 | explicit CXXScalarValueInitExpr(EmptyShell Shell) | |||
| 1822 | : Expr(CXXScalarValueInitExprClass, Shell) {} | |||
| 1823 | ||||
| 1824 | TypeSourceInfo *getTypeSourceInfo() const { | |||
| 1825 | return TypeInfo; | |||
| 1826 | } | |||
| 1827 | ||||
| 1828 | SourceLocation getRParenLoc() const { return RParenLoc; } | |||
| 1829 | ||||
| 1830 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)); | |||
| 1831 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)) { return RParenLoc; } | |||
| 1832 | ||||
| 1833 | static bool classof(const Stmt *T) { | |||
| 1834 | return T->getStmtClass() == CXXScalarValueInitExprClass; | |||
| 1835 | } | |||
| 1836 | ||||
| 1837 | // Iterators | |||
| 1838 | child_range children() { | |||
| 1839 | return child_range(child_iterator(), child_iterator()); | |||
| 1840 | } | |||
| 1841 | }; | |||
| 1842 | ||||
| 1843 | /// \brief Represents a new-expression for memory allocation and constructor | |||
| 1844 | /// calls, e.g: "new CXXNewExpr(foo)". | |||
| 1845 | class CXXNewExpr : public Expr { | |||
| 1846 | friend class ASTStmtReader; | |||
| 1847 | friend class ASTStmtWriter; | |||
| 1848 | ||||
| 1849 | /// Contains an optional array size expression, an optional initialization | |||
| 1850 | /// expression, and any number of optional placement arguments, in that order. | |||
| 1851 | Stmt **SubExprs = nullptr; | |||
| 1852 | ||||
| 1853 | /// \brief Points to the allocation function used. | |||
| 1854 | FunctionDecl *OperatorNew; | |||
| 1855 | ||||
| 1856 | /// \brief Points to the deallocation function used in case of error. May be | |||
| 1857 | /// null. | |||
| 1858 | FunctionDecl *OperatorDelete; | |||
| 1859 | ||||
| 1860 | /// \brief The allocated type-source information, as written in the source. | |||
| 1861 | TypeSourceInfo *AllocatedTypeInfo; | |||
| 1862 | ||||
| 1863 | /// \brief If the allocated type was expressed as a parenthesized type-id, | |||
| 1864 | /// the source range covering the parenthesized type-id. | |||
| 1865 | SourceRange TypeIdParens; | |||
| 1866 | ||||
| 1867 | /// \brief Range of the entire new expression. | |||
| 1868 | SourceRange Range; | |||
| 1869 | ||||
| 1870 | /// \brief Source-range of a paren-delimited initializer. | |||
| 1871 | SourceRange DirectInitRange; | |||
| 1872 | ||||
| 1873 | /// Was the usage ::new, i.e. is the global new to be used? | |||
| 1874 | unsigned GlobalNew : 1; | |||
| 1875 | ||||
| 1876 | /// Do we allocate an array? If so, the first SubExpr is the size expression. | |||
| 1877 | unsigned Array : 1; | |||
| 1878 | ||||
| 1879 | /// Should the alignment be passed to the allocation function? | |||
| 1880 | unsigned PassAlignment : 1; | |||
| 1881 | ||||
| 1882 | /// If this is an array allocation, does the usual deallocation | |||
| 1883 | /// function for the allocated type want to know the allocated size? | |||
| 1884 | unsigned UsualArrayDeleteWantsSize : 1; | |||
| 1885 | ||||
| 1886 | /// The number of placement new arguments. | |||
| 1887 | unsigned NumPlacementArgs : 26; | |||
| 1888 | ||||
| 1889 | /// What kind of initializer do we have? Could be none, parens, or braces. | |||
| 1890 | /// In storage, we distinguish between "none, and no initializer expr", and | |||
| 1891 | /// "none, but an implicit initializer expr". | |||
| 1892 | unsigned StoredInitializationStyle : 2; | |||
| 1893 | ||||
| 1894 | public: | |||
| 1895 | enum InitializationStyle { | |||
| 1896 | /// New-expression has no initializer as written. | |||
| 1897 | NoInit, | |||
| 1898 | ||||
| 1899 | /// New-expression has a C++98 paren-delimited initializer. | |||
| 1900 | CallInit, | |||
| 1901 | ||||
| 1902 | /// New-expression has a C++11 list-initializer. | |||
| 1903 | ListInit | |||
| 1904 | }; | |||
| 1905 | ||||
| 1906 | CXXNewExpr(const ASTContext &C, bool globalNew, FunctionDecl *operatorNew, | |||
| 1907 | FunctionDecl *operatorDelete, bool PassAlignment, | |||
| 1908 | bool usualArrayDeleteWantsSize, ArrayRef<Expr*> placementArgs, | |||
| 1909 | SourceRange typeIdParens, Expr *arraySize, | |||
| 1910 | InitializationStyle initializationStyle, Expr *initializer, | |||
| 1911 | QualType ty, TypeSourceInfo *AllocatedTypeInfo, | |||
| 1912 | SourceRange Range, SourceRange directInitRange); | |||
| 1913 | explicit CXXNewExpr(EmptyShell Shell) | |||
| 1914 | : Expr(CXXNewExprClass, Shell) {} | |||
| 1915 | ||||
| 1916 | void AllocateArgsArray(const ASTContext &C, bool isArray, | |||
| 1917 | unsigned numPlaceArgs, bool hasInitializer); | |||
| 1918 | ||||
| 1919 | QualType getAllocatedType() const { | |||
| 1920 | assert(getType()->isPointerType())(static_cast <bool> (getType()->isPointerType()) ? void (0) : __assert_fail ("getType()->isPointerType()", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 1920, __extension__ __PRETTY_FUNCTION__)); | |||
| 1921 | return getType()->getAs<PointerType>()->getPointeeType(); | |||
| 1922 | } | |||
| 1923 | ||||
| 1924 | TypeSourceInfo *getAllocatedTypeSourceInfo() const { | |||
| 1925 | return AllocatedTypeInfo; | |||
| 1926 | } | |||
| 1927 | ||||
| 1928 | /// \brief True if the allocation result needs to be null-checked. | |||
| 1929 | /// | |||
| 1930 | /// C++11 [expr.new]p13: | |||
| 1931 | /// If the allocation function returns null, initialization shall | |||
| 1932 | /// not be done, the deallocation function shall not be called, | |||
| 1933 | /// and the value of the new-expression shall be null. | |||
| 1934 | /// | |||
| 1935 | /// C++ DR1748: | |||
| 1936 | /// If the allocation function is a reserved placement allocation | |||
| 1937 | /// function that returns null, the behavior is undefined. | |||
| 1938 | /// | |||
| 1939 | /// An allocation function is not allowed to return null unless it | |||
| 1940 | /// has a non-throwing exception-specification. The '03 rule is | |||
| 1941 | /// identical except that the definition of a non-throwing | |||
| 1942 | /// exception specification is just "is it throw()?". | |||
| 1943 | bool shouldNullCheckAllocation(const ASTContext &Ctx) const; | |||
| 1944 | ||||
| 1945 | FunctionDecl *getOperatorNew() const { return OperatorNew; } | |||
| 1946 | void setOperatorNew(FunctionDecl *D) { OperatorNew = D; } | |||
| 1947 | FunctionDecl *getOperatorDelete() const { return OperatorDelete; } | |||
| 1948 | void setOperatorDelete(FunctionDecl *D) { OperatorDelete = D; } | |||
| 1949 | ||||
| 1950 | bool isArray() const { return Array; } | |||
| 1951 | ||||
| 1952 | Expr *getArraySize() { | |||
| 1953 | return Array ? cast<Expr>(SubExprs[0]) : nullptr; | |||
| 1954 | } | |||
| 1955 | const Expr *getArraySize() const { | |||
| 1956 | return Array ? cast<Expr>(SubExprs[0]) : nullptr; | |||
| 1957 | } | |||
| 1958 | ||||
| 1959 | unsigned getNumPlacementArgs() const { return NumPlacementArgs; } | |||
| 1960 | ||||
| 1961 | Expr **getPlacementArgs() { | |||
| 1962 | return reinterpret_cast<Expr **>(SubExprs + Array + hasInitializer()); | |||
| 1963 | } | |||
| 1964 | ||||
| 1965 | Expr *getPlacementArg(unsigned i) { | |||
| 1966 | assert(i < NumPlacementArgs && "Index out of range")(static_cast <bool> (i < NumPlacementArgs && "Index out of range") ? void (0) : __assert_fail ("i < NumPlacementArgs && \"Index out of range\"" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 1966, __extension__ __PRETTY_FUNCTION__)); | |||
| 1967 | return getPlacementArgs()[i]; | |||
| 1968 | } | |||
| 1969 | const Expr *getPlacementArg(unsigned i) const { | |||
| 1970 | assert(i < NumPlacementArgs && "Index out of range")(static_cast <bool> (i < NumPlacementArgs && "Index out of range") ? void (0) : __assert_fail ("i < NumPlacementArgs && \"Index out of range\"" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 1970, __extension__ __PRETTY_FUNCTION__)); | |||
| 1971 | return const_cast<CXXNewExpr*>(this)->getPlacementArg(i); | |||
| 1972 | } | |||
| 1973 | ||||
| 1974 | bool isParenTypeId() const { return TypeIdParens.isValid(); } | |||
| 1975 | SourceRange getTypeIdParens() const { return TypeIdParens; } | |||
| 1976 | ||||
| 1977 | bool isGlobalNew() const { return GlobalNew; } | |||
| 1978 | ||||
| 1979 | /// \brief Whether this new-expression has any initializer at all. | |||
| 1980 | bool hasInitializer() const { return StoredInitializationStyle > 0; } | |||
| 1981 | ||||
| 1982 | /// \brief The kind of initializer this new-expression has. | |||
| 1983 | InitializationStyle getInitializationStyle() const { | |||
| 1984 | if (StoredInitializationStyle == 0) | |||
| 1985 | return NoInit; | |||
| 1986 | return static_cast<InitializationStyle>(StoredInitializationStyle-1); | |||
| 1987 | } | |||
| 1988 | ||||
| 1989 | /// \brief The initializer of this new-expression. | |||
| 1990 | Expr *getInitializer() { | |||
| 1991 | return hasInitializer() ? cast<Expr>(SubExprs[Array]) : nullptr; | |||
| 1992 | } | |||
| 1993 | const Expr *getInitializer() const { | |||
| 1994 | return hasInitializer() ? cast<Expr>(SubExprs[Array]) : nullptr; | |||
| 1995 | } | |||
| 1996 | ||||
| 1997 | /// \brief Returns the CXXConstructExpr from this new-expression, or null. | |||
| 1998 | const CXXConstructExpr *getConstructExpr() const { | |||
| 1999 | return dyn_cast_or_null<CXXConstructExpr>(getInitializer()); | |||
| 2000 | } | |||
| 2001 | ||||
| 2002 | /// Indicates whether the required alignment should be implicitly passed to | |||
| 2003 | /// the allocation function. | |||
| 2004 | bool passAlignment() const { | |||
| 2005 | return PassAlignment; | |||
| 2006 | } | |||
| 2007 | ||||
| 2008 | /// Answers whether the usual array deallocation function for the | |||
| 2009 | /// allocated type expects the size of the allocation as a | |||
| 2010 | /// parameter. | |||
| 2011 | bool doesUsualArrayDeleteWantSize() const { | |||
| 2012 | return UsualArrayDeleteWantsSize; | |||
| 2013 | } | |||
| 2014 | ||||
| 2015 | using arg_iterator = ExprIterator; | |||
| 2016 | using const_arg_iterator = ConstExprIterator; | |||
| 2017 | ||||
| 2018 | llvm::iterator_range<arg_iterator> placement_arguments() { | |||
| 2019 | return llvm::make_range(placement_arg_begin(), placement_arg_end()); | |||
| 2020 | } | |||
| 2021 | ||||
| 2022 | llvm::iterator_range<const_arg_iterator> placement_arguments() const { | |||
| 2023 | return llvm::make_range(placement_arg_begin(), placement_arg_end()); | |||
| 2024 | } | |||
| 2025 | ||||
| 2026 | arg_iterator placement_arg_begin() { | |||
| 2027 | return SubExprs + Array + hasInitializer(); | |||
| 2028 | } | |||
| 2029 | arg_iterator placement_arg_end() { | |||
| 2030 | return SubExprs + Array + hasInitializer() + getNumPlacementArgs(); | |||
| 2031 | } | |||
| 2032 | const_arg_iterator placement_arg_begin() const { | |||
| 2033 | return SubExprs + Array + hasInitializer(); | |||
| 2034 | } | |||
| 2035 | const_arg_iterator placement_arg_end() const { | |||
| 2036 | return SubExprs + Array + hasInitializer() + getNumPlacementArgs(); | |||
| 2037 | } | |||
| 2038 | ||||
| 2039 | using raw_arg_iterator = Stmt **; | |||
| 2040 | ||||
| 2041 | raw_arg_iterator raw_arg_begin() { return SubExprs; } | |||
| 2042 | raw_arg_iterator raw_arg_end() { | |||
| 2043 | return SubExprs + Array + hasInitializer() + getNumPlacementArgs(); | |||
| 2044 | } | |||
| 2045 | const_arg_iterator raw_arg_begin() const { return SubExprs; } | |||
| 2046 | const_arg_iterator raw_arg_end() const { | |||
| 2047 | return SubExprs + Array + hasInitializer() + getNumPlacementArgs(); | |||
| 2048 | } | |||
| 2049 | ||||
| 2050 | SourceLocation getStartLoc() const { return Range.getBegin(); } | |||
| 2051 | SourceLocation getEndLoc() const { return Range.getEnd(); } | |||
| 2052 | ||||
| 2053 | SourceRange getDirectInitRange() const { return DirectInitRange; } | |||
| 2054 | ||||
| 2055 | SourceRange getSourceRange() const LLVM_READONLY__attribute__((__pure__)) { | |||
| 2056 | return Range; | |||
| 2057 | } | |||
| 2058 | ||||
| 2059 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)) { return getStartLoc(); } | |||
| 2060 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)) { return getEndLoc(); } | |||
| 2061 | ||||
| 2062 | static bool classof(const Stmt *T) { | |||
| 2063 | return T->getStmtClass() == CXXNewExprClass; | |||
| 2064 | } | |||
| 2065 | ||||
| 2066 | // Iterators | |||
| 2067 | child_range children() { | |||
| 2068 | return child_range(raw_arg_begin(), raw_arg_end()); | |||
| 2069 | } | |||
| 2070 | }; | |||
| 2071 | ||||
| 2072 | /// \brief Represents a \c delete expression for memory deallocation and | |||
| 2073 | /// destructor calls, e.g. "delete[] pArray". | |||
| 2074 | class CXXDeleteExpr : public Expr { | |||
| 2075 | /// Points to the operator delete overload that is used. Could be a member. | |||
| 2076 | FunctionDecl *OperatorDelete = nullptr; | |||
| 2077 | ||||
| 2078 | /// The pointer expression to be deleted. | |||
| 2079 | Stmt *Argument = nullptr; | |||
| 2080 | ||||
| 2081 | /// Location of the expression. | |||
| 2082 | SourceLocation Loc; | |||
| 2083 | ||||
| 2084 | /// Is this a forced global delete, i.e. "::delete"? | |||
| 2085 | bool GlobalDelete : 1; | |||
| 2086 | ||||
| 2087 | /// Is this the array form of delete, i.e. "delete[]"? | |||
| 2088 | bool ArrayForm : 1; | |||
| 2089 | ||||
| 2090 | /// ArrayFormAsWritten can be different from ArrayForm if 'delete' is applied | |||
| 2091 | /// to pointer-to-array type (ArrayFormAsWritten will be false while ArrayForm | |||
| 2092 | /// will be true). | |||
| 2093 | bool ArrayFormAsWritten : 1; | |||
| 2094 | ||||
| 2095 | /// Does the usual deallocation function for the element type require | |||
| 2096 | /// a size_t argument? | |||
| 2097 | bool UsualArrayDeleteWantsSize : 1; | |||
| 2098 | ||||
| 2099 | public: | |||
| 2100 | friend class ASTStmtReader; | |||
| 2101 | ||||
| 2102 | CXXDeleteExpr(QualType ty, bool globalDelete, bool arrayForm, | |||
| 2103 | bool arrayFormAsWritten, bool usualArrayDeleteWantsSize, | |||
| 2104 | FunctionDecl *operatorDelete, Expr *arg, SourceLocation loc) | |||
| 2105 | : Expr(CXXDeleteExprClass, ty, VK_RValue, OK_Ordinary, false, false, | |||
| 2106 | arg->isInstantiationDependent(), | |||
| 2107 | arg->containsUnexpandedParameterPack()), | |||
| 2108 | OperatorDelete(operatorDelete), Argument(arg), Loc(loc), | |||
| 2109 | GlobalDelete(globalDelete), | |||
| 2110 | ArrayForm(arrayForm), ArrayFormAsWritten(arrayFormAsWritten), | |||
| 2111 | UsualArrayDeleteWantsSize(usualArrayDeleteWantsSize) {} | |||
| 2112 | explicit CXXDeleteExpr(EmptyShell Shell) : Expr(CXXDeleteExprClass, Shell) {} | |||
| 2113 | ||||
| 2114 | bool isGlobalDelete() const { return GlobalDelete; } | |||
| 2115 | bool isArrayForm() const { return ArrayForm; } | |||
| 2116 | bool isArrayFormAsWritten() const { return ArrayFormAsWritten; } | |||
| 2117 | ||||
| 2118 | /// Answers whether the usual array deallocation function for the | |||
| 2119 | /// allocated type expects the size of the allocation as a | |||
| 2120 | /// parameter. This can be true even if the actual deallocation | |||
| 2121 | /// function that we're using doesn't want a size. | |||
| 2122 | bool doesUsualArrayDeleteWantSize() const { | |||
| 2123 | return UsualArrayDeleteWantsSize; | |||
| 2124 | } | |||
| 2125 | ||||
| 2126 | FunctionDecl *getOperatorDelete() const { return OperatorDelete; } | |||
| 2127 | ||||
| 2128 | Expr *getArgument() { return cast<Expr>(Argument); } | |||
| 2129 | const Expr *getArgument() const { return cast<Expr>(Argument); } | |||
| 2130 | ||||
| 2131 | /// \brief Retrieve the type being destroyed. | |||
| 2132 | /// | |||
| 2133 | /// If the type being destroyed is a dependent type which may or may not | |||
| 2134 | /// be a pointer, return an invalid type. | |||
| 2135 | QualType getDestroyedType() const; | |||
| 2136 | ||||
| 2137 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)) { return Loc; } | |||
| 2138 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)) {return Argument->getLocEnd();} | |||
| 2139 | ||||
| 2140 | static bool classof(const Stmt *T) { | |||
| 2141 | return T->getStmtClass() == CXXDeleteExprClass; | |||
| 2142 | } | |||
| 2143 | ||||
| 2144 | // Iterators | |||
| 2145 | child_range children() { return child_range(&Argument, &Argument+1); } | |||
| 2146 | }; | |||
| 2147 | ||||
| 2148 | /// \brief Stores the type being destroyed by a pseudo-destructor expression. | |||
| 2149 | class PseudoDestructorTypeStorage { | |||
| 2150 | /// \brief Either the type source information or the name of the type, if | |||
| 2151 | /// it couldn't be resolved due to type-dependence. | |||
| 2152 | llvm::PointerUnion<TypeSourceInfo *, IdentifierInfo *> Type; | |||
| 2153 | ||||
| 2154 | /// \brief The starting source location of the pseudo-destructor type. | |||
| 2155 | SourceLocation Location; | |||
| 2156 | ||||
| 2157 | public: | |||
| 2158 | PseudoDestructorTypeStorage() = default; | |||
| 2159 | ||||
| 2160 | PseudoDestructorTypeStorage(IdentifierInfo *II, SourceLocation Loc) | |||
| 2161 | : Type(II), Location(Loc) {} | |||
| 2162 | ||||
| 2163 | PseudoDestructorTypeStorage(TypeSourceInfo *Info); | |||
| 2164 | ||||
| 2165 | TypeSourceInfo *getTypeSourceInfo() const { | |||
| 2166 | return Type.dyn_cast<TypeSourceInfo *>(); | |||
| 2167 | } | |||
| 2168 | ||||
| 2169 | IdentifierInfo *getIdentifier() const { | |||
| 2170 | return Type.dyn_cast<IdentifierInfo *>(); | |||
| 2171 | } | |||
| 2172 | ||||
| 2173 | SourceLocation getLocation() const { return Location; } | |||
| 2174 | }; | |||
| 2175 | ||||
| 2176 | /// \brief Represents a C++ pseudo-destructor (C++ [expr.pseudo]). | |||
| 2177 | /// | |||
| 2178 | /// A pseudo-destructor is an expression that looks like a member access to a | |||
| 2179 | /// destructor of a scalar type, except that scalar types don't have | |||
| 2180 | /// destructors. For example: | |||
| 2181 | /// | |||
| 2182 | /// \code | |||
| 2183 | /// typedef int T; | |||
| 2184 | /// void f(int *p) { | |||
| 2185 | /// p->T::~T(); | |||
| 2186 | /// } | |||
| 2187 | /// \endcode | |||
| 2188 | /// | |||
| 2189 | /// Pseudo-destructors typically occur when instantiating templates such as: | |||
| 2190 | /// | |||
| 2191 | /// \code | |||
| 2192 | /// template<typename T> | |||
| 2193 | /// void destroy(T* ptr) { | |||
| 2194 | /// ptr->T::~T(); | |||
| 2195 | /// } | |||
| 2196 | /// \endcode | |||
| 2197 | /// | |||
| 2198 | /// for scalar types. A pseudo-destructor expression has no run-time semantics | |||
| 2199 | /// beyond evaluating the base expression. | |||
| 2200 | class CXXPseudoDestructorExpr : public Expr { | |||
| 2201 | friend class ASTStmtReader; | |||
| 2202 | ||||
| 2203 | /// \brief The base expression (that is being destroyed). | |||
| 2204 | Stmt *Base = nullptr; | |||
| 2205 | ||||
| 2206 | /// \brief Whether the operator was an arrow ('->'); otherwise, it was a | |||
| 2207 | /// period ('.'). | |||
| 2208 | bool IsArrow : 1; | |||
| 2209 | ||||
| 2210 | /// \brief The location of the '.' or '->' operator. | |||
| 2211 | SourceLocation OperatorLoc; | |||
| 2212 | ||||
| 2213 | /// \brief The nested-name-specifier that follows the operator, if present. | |||
| 2214 | NestedNameSpecifierLoc QualifierLoc; | |||
| 2215 | ||||
| 2216 | /// \brief The type that precedes the '::' in a qualified pseudo-destructor | |||
| 2217 | /// expression. | |||
| 2218 | TypeSourceInfo *ScopeType = nullptr; | |||
| 2219 | ||||
| 2220 | /// \brief The location of the '::' in a qualified pseudo-destructor | |||
| 2221 | /// expression. | |||
| 2222 | SourceLocation ColonColonLoc; | |||
| 2223 | ||||
| 2224 | /// \brief The location of the '~'. | |||
| 2225 | SourceLocation TildeLoc; | |||
| 2226 | ||||
| 2227 | /// \brief The type being destroyed, or its name if we were unable to | |||
| 2228 | /// resolve the name. | |||
| 2229 | PseudoDestructorTypeStorage DestroyedType; | |||
| 2230 | ||||
| 2231 | public: | |||
| 2232 | CXXPseudoDestructorExpr(const ASTContext &Context, | |||
| 2233 | Expr *Base, bool isArrow, SourceLocation OperatorLoc, | |||
| 2234 | NestedNameSpecifierLoc QualifierLoc, | |||
| 2235 | TypeSourceInfo *ScopeType, | |||
| 2236 | SourceLocation ColonColonLoc, | |||
| 2237 | SourceLocation TildeLoc, | |||
| 2238 | PseudoDestructorTypeStorage DestroyedType); | |||
| 2239 | ||||
| 2240 | explicit CXXPseudoDestructorExpr(EmptyShell Shell) | |||
| 2241 | : Expr(CXXPseudoDestructorExprClass, Shell), IsArrow(false) {} | |||
| 2242 | ||||
| 2243 | Expr *getBase() const { return cast<Expr>(Base); } | |||
| 2244 | ||||
| 2245 | /// \brief Determines whether this member expression actually had | |||
| 2246 | /// a C++ nested-name-specifier prior to the name of the member, e.g., | |||
| 2247 | /// x->Base::foo. | |||
| 2248 | bool hasQualifier() const { return QualifierLoc.hasQualifier(); } | |||
| 2249 | ||||
| 2250 | /// \brief Retrieves the nested-name-specifier that qualifies the type name, | |||
| 2251 | /// with source-location information. | |||
| 2252 | NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } | |||
| 2253 | ||||
| 2254 | /// \brief If the member name was qualified, retrieves the | |||
| 2255 | /// nested-name-specifier that precedes the member name. Otherwise, returns | |||
| 2256 | /// null. | |||
| 2257 | NestedNameSpecifier *getQualifier() const { | |||
| 2258 | return QualifierLoc.getNestedNameSpecifier(); | |||
| 2259 | } | |||
| 2260 | ||||
| 2261 | /// \brief Determine whether this pseudo-destructor expression was written | |||
| 2262 | /// using an '->' (otherwise, it used a '.'). | |||
| 2263 | bool isArrow() const { return IsArrow; } | |||
| 2264 | ||||
| 2265 | /// \brief Retrieve the location of the '.' or '->' operator. | |||
| 2266 | SourceLocation getOperatorLoc() const { return OperatorLoc; } | |||
| 2267 | ||||
| 2268 | /// \brief Retrieve the scope type in a qualified pseudo-destructor | |||
| 2269 | /// expression. | |||
| 2270 | /// | |||
| 2271 | /// Pseudo-destructor expressions can have extra qualification within them | |||
| 2272 | /// that is not part of the nested-name-specifier, e.g., \c p->T::~T(). | |||
| 2273 | /// Here, if the object type of the expression is (or may be) a scalar type, | |||
| 2274 | /// \p T may also be a scalar type and, therefore, cannot be part of a | |||
| 2275 | /// nested-name-specifier. It is stored as the "scope type" of the pseudo- | |||
| 2276 | /// destructor expression. | |||
| 2277 | TypeSourceInfo *getScopeTypeInfo() const { return ScopeType; } | |||
| 2278 | ||||
| 2279 | /// \brief Retrieve the location of the '::' in a qualified pseudo-destructor | |||
| 2280 | /// expression. | |||
| 2281 | SourceLocation getColonColonLoc() const { return ColonColonLoc; } | |||
| 2282 | ||||
| 2283 | /// \brief Retrieve the location of the '~'. | |||
| 2284 | SourceLocation getTildeLoc() const { return TildeLoc; } | |||
| 2285 | ||||
| 2286 | /// \brief Retrieve the source location information for the type | |||
| 2287 | /// being destroyed. | |||
| 2288 | /// | |||
| 2289 | /// This type-source information is available for non-dependent | |||
| 2290 | /// pseudo-destructor expressions and some dependent pseudo-destructor | |||
| 2291 | /// expressions. Returns null if we only have the identifier for a | |||
| 2292 | /// dependent pseudo-destructor expression. | |||
| 2293 | TypeSourceInfo *getDestroyedTypeInfo() const { | |||
| 2294 | return DestroyedType.getTypeSourceInfo(); | |||
| 2295 | } | |||
| 2296 | ||||
| 2297 | /// \brief In a dependent pseudo-destructor expression for which we do not | |||
| 2298 | /// have full type information on the destroyed type, provides the name | |||
| 2299 | /// of the destroyed type. | |||
| 2300 | IdentifierInfo *getDestroyedTypeIdentifier() const { | |||
| 2301 | return DestroyedType.getIdentifier(); | |||
| 2302 | } | |||
| 2303 | ||||
| 2304 | /// \brief Retrieve the type being destroyed. | |||
| 2305 | QualType getDestroyedType() const; | |||
| 2306 | ||||
| 2307 | /// \brief Retrieve the starting location of the type being destroyed. | |||
| 2308 | SourceLocation getDestroyedTypeLoc() const { | |||
| 2309 | return DestroyedType.getLocation(); | |||
| 2310 | } | |||
| 2311 | ||||
| 2312 | /// \brief Set the name of destroyed type for a dependent pseudo-destructor | |||
| 2313 | /// expression. | |||
| 2314 | void setDestroyedType(IdentifierInfo *II, SourceLocation Loc) { | |||
| 2315 | DestroyedType = PseudoDestructorTypeStorage(II, Loc); | |||
| 2316 | } | |||
| 2317 | ||||
| 2318 | /// \brief Set the destroyed type. | |||
| 2319 | void setDestroyedType(TypeSourceInfo *Info) { | |||
| 2320 | DestroyedType = PseudoDestructorTypeStorage(Info); | |||
| 2321 | } | |||
| 2322 | ||||
| 2323 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)) {return Base->getLocStart();} | |||
| 2324 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)); | |||
| 2325 | ||||
| 2326 | static bool classof(const Stmt *T) { | |||
| 2327 | return T->getStmtClass() == CXXPseudoDestructorExprClass; | |||
| 2328 | } | |||
| 2329 | ||||
| 2330 | // Iterators | |||
| 2331 | child_range children() { return child_range(&Base, &Base + 1); } | |||
| 2332 | }; | |||
| 2333 | ||||
| 2334 | /// \brief A type trait used in the implementation of various C++11 and | |||
| 2335 | /// Library TR1 trait templates. | |||
| 2336 | /// | |||
| 2337 | /// \code | |||
| 2338 | /// __is_pod(int) == true | |||
| 2339 | /// __is_enum(std::string) == false | |||
| 2340 | /// __is_trivially_constructible(vector<int>, int*, int*) | |||
| 2341 | /// \endcode | |||
| 2342 | class TypeTraitExpr final | |||
| 2343 | : public Expr, | |||
| 2344 | private llvm::TrailingObjects<TypeTraitExpr, TypeSourceInfo *> { | |||
| 2345 | /// \brief The location of the type trait keyword. | |||
| 2346 | SourceLocation Loc; | |||
| 2347 | ||||
| 2348 | /// \brief The location of the closing parenthesis. | |||
| 2349 | SourceLocation RParenLoc; | |||
| 2350 | ||||
| 2351 | // Note: The TypeSourceInfos for the arguments are allocated after the | |||
| 2352 | // TypeTraitExpr. | |||
| 2353 | ||||
| 2354 | TypeTraitExpr(QualType T, SourceLocation Loc, TypeTrait Kind, | |||
| 2355 | ArrayRef<TypeSourceInfo *> Args, | |||
| 2356 | SourceLocation RParenLoc, | |||
| 2357 | bool Value); | |||
| 2358 | ||||
| 2359 | TypeTraitExpr(EmptyShell Empty) : Expr(TypeTraitExprClass, Empty) {} | |||
| 2360 | ||||
| 2361 | size_t numTrailingObjects(OverloadToken<TypeSourceInfo *>) const { | |||
| 2362 | return getNumArgs(); | |||
| 2363 | } | |||
| 2364 | ||||
| 2365 | public: | |||
| 2366 | friend class ASTStmtReader; | |||
| 2367 | friend class ASTStmtWriter; | |||
| 2368 | friend TrailingObjects; | |||
| 2369 | ||||
| 2370 | /// \brief Create a new type trait expression. | |||
| 2371 | static TypeTraitExpr *Create(const ASTContext &C, QualType T, | |||
| 2372 | SourceLocation Loc, TypeTrait Kind, | |||
| 2373 | ArrayRef<TypeSourceInfo *> Args, | |||
| 2374 | SourceLocation RParenLoc, | |||
| 2375 | bool Value); | |||
| 2376 | ||||
| 2377 | static TypeTraitExpr *CreateDeserialized(const ASTContext &C, | |||
| 2378 | unsigned NumArgs); | |||
| 2379 | ||||
| 2380 | /// \brief Determine which type trait this expression uses. | |||
| 2381 | TypeTrait getTrait() const { | |||
| 2382 | return static_cast<TypeTrait>(TypeTraitExprBits.Kind); | |||
| 2383 | } | |||
| 2384 | ||||
| 2385 | bool getValue() const { | |||
| 2386 | assert(!isValueDependent())(static_cast <bool> (!isValueDependent()) ? void (0) : __assert_fail ("!isValueDependent()", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 2386, __extension__ __PRETTY_FUNCTION__)); | |||
| 2387 | return TypeTraitExprBits.Value; | |||
| 2388 | } | |||
| 2389 | ||||
| 2390 | /// \brief Determine the number of arguments to this type trait. | |||
| 2391 | unsigned getNumArgs() const { return TypeTraitExprBits.NumArgs; } | |||
| 2392 | ||||
| 2393 | /// \brief Retrieve the Ith argument. | |||
| 2394 | TypeSourceInfo *getArg(unsigned I) const { | |||
| 2395 | assert(I < getNumArgs() && "Argument out-of-range")(static_cast <bool> (I < getNumArgs() && "Argument out-of-range" ) ? void (0) : __assert_fail ("I < getNumArgs() && \"Argument out-of-range\"" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 2395, __extension__ __PRETTY_FUNCTION__)); | |||
| 2396 | return getArgs()[I]; | |||
| 2397 | } | |||
| 2398 | ||||
| 2399 | /// \brief Retrieve the argument types. | |||
| 2400 | ArrayRef<TypeSourceInfo *> getArgs() const { | |||
| 2401 | return llvm::makeArrayRef(getTrailingObjects<TypeSourceInfo *>(), | |||
| 2402 | getNumArgs()); | |||
| 2403 | } | |||
| 2404 | ||||
| 2405 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)) { return Loc; } | |||
| 2406 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)) { return RParenLoc; } | |||
| 2407 | ||||
| 2408 | static bool classof(const Stmt *T) { | |||
| 2409 | return T->getStmtClass() == TypeTraitExprClass; | |||
| 2410 | } | |||
| 2411 | ||||
| 2412 | // Iterators | |||
| 2413 | child_range children() { | |||
| 2414 | return child_range(child_iterator(), child_iterator()); | |||
| 2415 | } | |||
| 2416 | }; | |||
| 2417 | ||||
| 2418 | /// \brief An Embarcadero array type trait, as used in the implementation of | |||
| 2419 | /// __array_rank and __array_extent. | |||
| 2420 | /// | |||
| 2421 | /// Example: | |||
| 2422 | /// \code | |||
| 2423 | /// __array_rank(int[10][20]) == 2 | |||
| 2424 | /// __array_extent(int, 1) == 20 | |||
| 2425 | /// \endcode | |||
| 2426 | class ArrayTypeTraitExpr : public Expr { | |||
| 2427 | /// \brief The trait. An ArrayTypeTrait enum in MSVC compat unsigned. | |||
| 2428 | unsigned ATT : 2; | |||
| 2429 | ||||
| 2430 | /// \brief The value of the type trait. Unspecified if dependent. | |||
| 2431 | uint64_t Value = 0; | |||
| 2432 | ||||
| 2433 | /// \brief The array dimension being queried, or -1 if not used. | |||
| 2434 | Expr *Dimension; | |||
| 2435 | ||||
| 2436 | /// \brief The location of the type trait keyword. | |||
| 2437 | SourceLocation Loc; | |||
| 2438 | ||||
| 2439 | /// \brief The location of the closing paren. | |||
| 2440 | SourceLocation RParen; | |||
| 2441 | ||||
| 2442 | /// \brief The type being queried. | |||
| 2443 | TypeSourceInfo *QueriedType = nullptr; | |||
| 2444 | ||||
| 2445 | virtual void anchor(); | |||
| 2446 | ||||
| 2447 | public: | |||
| 2448 | friend class ASTStmtReader; | |||
| 2449 | ||||
| 2450 | ArrayTypeTraitExpr(SourceLocation loc, ArrayTypeTrait att, | |||
| 2451 | TypeSourceInfo *queried, uint64_t value, | |||
| 2452 | Expr *dimension, SourceLocation rparen, QualType ty) | |||
| 2453 | : Expr(ArrayTypeTraitExprClass, ty, VK_RValue, OK_Ordinary, | |||
| 2454 | false, queried->getType()->isDependentType(), | |||
| 2455 | (queried->getType()->isInstantiationDependentType() || | |||
| 2456 | (dimension && dimension->isInstantiationDependent())), | |||
| 2457 | queried->getType()->containsUnexpandedParameterPack()), | |||
| 2458 | ATT(att), Value(value), Dimension(dimension), | |||
| 2459 | Loc(loc), RParen(rparen), QueriedType(queried) {} | |||
| 2460 | ||||
| 2461 | explicit ArrayTypeTraitExpr(EmptyShell Empty) | |||
| 2462 | : Expr(ArrayTypeTraitExprClass, Empty), ATT(0) {} | |||
| 2463 | ||||
| 2464 | virtual ~ArrayTypeTraitExpr() = default; | |||
| 2465 | ||||
| 2466 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)) { return Loc; } | |||
| 2467 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)) { return RParen; } | |||
| 2468 | ||||
| 2469 | ArrayTypeTrait getTrait() const { return static_cast<ArrayTypeTrait>(ATT); } | |||
| 2470 | ||||
| 2471 | QualType getQueriedType() const { return QueriedType->getType(); } | |||
| 2472 | ||||
| 2473 | TypeSourceInfo *getQueriedTypeSourceInfo() const { return QueriedType; } | |||
| 2474 | ||||
| 2475 | uint64_t getValue() const { assert(!isTypeDependent())(static_cast <bool> (!isTypeDependent()) ? void (0) : __assert_fail ("!isTypeDependent()", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 2475, __extension__ __PRETTY_FUNCTION__)); return Value; } | |||
| 2476 | ||||
| 2477 | Expr *getDimensionExpression() const { return Dimension; } | |||
| 2478 | ||||
| 2479 | static bool classof(const Stmt *T) { | |||
| 2480 | return T->getStmtClass() == ArrayTypeTraitExprClass; | |||
| 2481 | } | |||
| 2482 | ||||
| 2483 | // Iterators | |||
| 2484 | child_range children() { | |||
| 2485 | return child_range(child_iterator(), child_iterator()); | |||
| 2486 | } | |||
| 2487 | }; | |||
| 2488 | ||||
| 2489 | /// \brief An expression trait intrinsic. | |||
| 2490 | /// | |||
| 2491 | /// Example: | |||
| 2492 | /// \code | |||
| 2493 | /// __is_lvalue_expr(std::cout) == true | |||
| 2494 | /// __is_lvalue_expr(1) == false | |||
| 2495 | /// \endcode | |||
| 2496 | class ExpressionTraitExpr : public Expr { | |||
| 2497 | /// \brief The trait. A ExpressionTrait enum in MSVC compatible unsigned. | |||
| 2498 | unsigned ET : 31; | |||
| 2499 | ||||
| 2500 | /// \brief The value of the type trait. Unspecified if dependent. | |||
| 2501 | unsigned Value : 1; | |||
| 2502 | ||||
| 2503 | /// \brief The location of the type trait keyword. | |||
| 2504 | SourceLocation Loc; | |||
| 2505 | ||||
| 2506 | /// \brief The location of the closing paren. | |||
| 2507 | SourceLocation RParen; | |||
| 2508 | ||||
| 2509 | /// \brief The expression being queried. | |||
| 2510 | Expr* QueriedExpression = nullptr; | |||
| 2511 | ||||
| 2512 | public: | |||
| 2513 | friend class ASTStmtReader; | |||
| 2514 | ||||
| 2515 | ExpressionTraitExpr(SourceLocation loc, ExpressionTrait et, | |||
| 2516 | Expr *queried, bool value, | |||
| 2517 | SourceLocation rparen, QualType resultType) | |||
| 2518 | : Expr(ExpressionTraitExprClass, resultType, VK_RValue, OK_Ordinary, | |||
| 2519 | false, // Not type-dependent | |||
| 2520 | // Value-dependent if the argument is type-dependent. | |||
| 2521 | queried->isTypeDependent(), | |||
| 2522 | queried->isInstantiationDependent(), | |||
| 2523 | queried->containsUnexpandedParameterPack()), | |||
| 2524 | ET(et), Value(value), Loc(loc), RParen(rparen), | |||
| 2525 | QueriedExpression(queried) {} | |||
| 2526 | ||||
| 2527 | explicit ExpressionTraitExpr(EmptyShell Empty) | |||
| 2528 | : Expr(ExpressionTraitExprClass, Empty), ET(0), Value(false) {} | |||
| 2529 | ||||
| 2530 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)) { return Loc; } | |||
| 2531 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)) { return RParen; } | |||
| 2532 | ||||
| 2533 | ExpressionTrait getTrait() const { return static_cast<ExpressionTrait>(ET); } | |||
| 2534 | ||||
| 2535 | Expr *getQueriedExpression() const { return QueriedExpression; } | |||
| 2536 | ||||
| 2537 | bool getValue() const { return Value; } | |||
| 2538 | ||||
| 2539 | static bool classof(const Stmt *T) { | |||
| 2540 | return T->getStmtClass() == ExpressionTraitExprClass; | |||
| 2541 | } | |||
| 2542 | ||||
| 2543 | // Iterators | |||
| 2544 | child_range children() { | |||
| 2545 | return child_range(child_iterator(), child_iterator()); | |||
| 2546 | } | |||
| 2547 | }; | |||
| 2548 | ||||
| 2549 | /// \brief A reference to an overloaded function set, either an | |||
| 2550 | /// \c UnresolvedLookupExpr or an \c UnresolvedMemberExpr. | |||
| 2551 | class OverloadExpr : public Expr { | |||
| 2552 | /// \brief The common name of these declarations. | |||
| 2553 | DeclarationNameInfo NameInfo; | |||
| 2554 | ||||
| 2555 | /// \brief The nested-name-specifier that qualifies the name, if any. | |||
| 2556 | NestedNameSpecifierLoc QualifierLoc; | |||
| 2557 | ||||
| 2558 | /// The results. These are undesugared, which is to say, they may | |||
| 2559 | /// include UsingShadowDecls. Access is relative to the naming | |||
| 2560 | /// class. | |||
| 2561 | // FIXME: Allocate this data after the OverloadExpr subclass. | |||
| 2562 | DeclAccessPair *Results = nullptr; | |||
| 2563 | ||||
| 2564 | unsigned NumResults = 0; | |||
| 2565 | ||||
| 2566 | protected: | |||
| 2567 | /// \brief Whether the name includes info for explicit template | |||
| 2568 | /// keyword and arguments. | |||
| 2569 | bool HasTemplateKWAndArgsInfo = false; | |||
| 2570 | ||||
| 2571 | OverloadExpr(StmtClass K, const ASTContext &C, | |||
| 2572 | NestedNameSpecifierLoc QualifierLoc, | |||
| 2573 | SourceLocation TemplateKWLoc, | |||
| 2574 | const DeclarationNameInfo &NameInfo, | |||
| 2575 | const TemplateArgumentListInfo *TemplateArgs, | |||
| 2576 | UnresolvedSetIterator Begin, UnresolvedSetIterator End, | |||
| 2577 | bool KnownDependent, | |||
| 2578 | bool KnownInstantiationDependent, | |||
| 2579 | bool KnownContainsUnexpandedParameterPack); | |||
| 2580 | ||||
| 2581 | OverloadExpr(StmtClass K, EmptyShell Empty) : Expr(K, Empty) {} | |||
| 2582 | ||||
| 2583 | /// \brief Return the optional template keyword and arguments info. | |||
| 2584 | ASTTemplateKWAndArgsInfo * | |||
| 2585 | getTrailingASTTemplateKWAndArgsInfo(); // defined far below. | |||
| 2586 | ||||
| 2587 | /// \brief Return the optional template keyword and arguments info. | |||
| 2588 | const ASTTemplateKWAndArgsInfo *getTrailingASTTemplateKWAndArgsInfo() const { | |||
| 2589 | return const_cast<OverloadExpr *>(this) | |||
| 2590 | ->getTrailingASTTemplateKWAndArgsInfo(); | |||
| 2591 | } | |||
| 2592 | ||||
| 2593 | /// Return the optional template arguments. | |||
| 2594 | TemplateArgumentLoc *getTrailingTemplateArgumentLoc(); // defined far below | |||
| 2595 | ||||
| 2596 | void initializeResults(const ASTContext &C, | |||
| 2597 | UnresolvedSetIterator Begin, | |||
| 2598 | UnresolvedSetIterator End); | |||
| 2599 | ||||
| 2600 | public: | |||
| 2601 | friend class ASTStmtReader; | |||
| 2602 | friend class ASTStmtWriter; | |||
| 2603 | ||||
| 2604 | struct FindResult { | |||
| 2605 | OverloadExpr *Expression; | |||
| 2606 | bool IsAddressOfOperand; | |||
| 2607 | bool HasFormOfMemberPointer; | |||
| 2608 | }; | |||
| 2609 | ||||
| 2610 | /// \brief Finds the overloaded expression in the given expression \p E of | |||
| 2611 | /// OverloadTy. | |||
| 2612 | /// | |||
| 2613 | /// \return the expression (which must be there) and true if it has | |||
| 2614 | /// the particular form of a member pointer expression | |||
| 2615 | static FindResult find(Expr *E) { | |||
| 2616 | assert(E->getType()->isSpecificBuiltinType(BuiltinType::Overload))(static_cast <bool> (E->getType()->isSpecificBuiltinType (BuiltinType::Overload)) ? void (0) : __assert_fail ("E->getType()->isSpecificBuiltinType(BuiltinType::Overload)" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 2616, __extension__ __PRETTY_FUNCTION__)); | |||
| 2617 | ||||
| 2618 | FindResult Result; | |||
| 2619 | ||||
| 2620 | E = E->IgnoreParens(); | |||
| 2621 | if (isa<UnaryOperator>(E)) { | |||
| 2622 | assert(cast<UnaryOperator>(E)->getOpcode() == UO_AddrOf)(static_cast <bool> (cast<UnaryOperator>(E)->getOpcode () == UO_AddrOf) ? void (0) : __assert_fail ("cast<UnaryOperator>(E)->getOpcode() == UO_AddrOf" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 2622, __extension__ __PRETTY_FUNCTION__)); | |||
| 2623 | E = cast<UnaryOperator>(E)->getSubExpr(); | |||
| 2624 | OverloadExpr *Ovl = cast<OverloadExpr>(E->IgnoreParens()); | |||
| 2625 | ||||
| 2626 | Result.HasFormOfMemberPointer = (E == Ovl && Ovl->getQualifier()); | |||
| 2627 | Result.IsAddressOfOperand = true; | |||
| 2628 | Result.Expression = Ovl; | |||
| 2629 | } else { | |||
| 2630 | Result.HasFormOfMemberPointer = false; | |||
| 2631 | Result.IsAddressOfOperand = false; | |||
| 2632 | Result.Expression = cast<OverloadExpr>(E); | |||
| 2633 | } | |||
| 2634 | ||||
| 2635 | return Result; | |||
| 2636 | } | |||
| 2637 | ||||
| 2638 | /// \brief Gets the naming class of this lookup, if any. | |||
| 2639 | CXXRecordDecl *getNamingClass() const; | |||
| 2640 | ||||
| 2641 | using decls_iterator = UnresolvedSetImpl::iterator; | |||
| 2642 | ||||
| 2643 | decls_iterator decls_begin() const { return UnresolvedSetIterator(Results); } | |||
| 2644 | decls_iterator decls_end() const { | |||
| 2645 | return UnresolvedSetIterator(Results + NumResults); | |||
| 2646 | } | |||
| 2647 | llvm::iterator_range<decls_iterator> decls() const { | |||
| 2648 | return llvm::make_range(decls_begin(), decls_end()); | |||
| 2649 | } | |||
| 2650 | ||||
| 2651 | /// \brief Gets the number of declarations in the unresolved set. | |||
| 2652 | unsigned getNumDecls() const { return NumResults; } | |||
| 2653 | ||||
| 2654 | /// \brief Gets the full name info. | |||
| 2655 | const DeclarationNameInfo &getNameInfo() const { return NameInfo; } | |||
| 2656 | ||||
| 2657 | /// \brief Gets the name looked up. | |||
| 2658 | DeclarationName getName() const { return NameInfo.getName(); } | |||
| 2659 | ||||
| 2660 | /// \brief Gets the location of the name. | |||
| 2661 | SourceLocation getNameLoc() const { return NameInfo.getLoc(); } | |||
| 2662 | ||||
| 2663 | /// \brief Fetches the nested-name qualifier, if one was given. | |||
| 2664 | NestedNameSpecifier *getQualifier() const { | |||
| 2665 | return QualifierLoc.getNestedNameSpecifier(); | |||
| 2666 | } | |||
| 2667 | ||||
| 2668 | /// \brief Fetches the nested-name qualifier with source-location | |||
| 2669 | /// information, if one was given. | |||
| 2670 | NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } | |||
| 2671 | ||||
| 2672 | /// \brief Retrieve the location of the template keyword preceding | |||
| 2673 | /// this name, if any. | |||
| 2674 | SourceLocation getTemplateKeywordLoc() const { | |||
| 2675 | if (!HasTemplateKWAndArgsInfo) return SourceLocation(); | |||
| 2676 | return getTrailingASTTemplateKWAndArgsInfo()->TemplateKWLoc; | |||
| 2677 | } | |||
| 2678 | ||||
| 2679 | /// \brief Retrieve the location of the left angle bracket starting the | |||
| 2680 | /// explicit template argument list following the name, if any. | |||
| 2681 | SourceLocation getLAngleLoc() const { | |||
| 2682 | if (!HasTemplateKWAndArgsInfo) return SourceLocation(); | |||
| 2683 | return getTrailingASTTemplateKWAndArgsInfo()->LAngleLoc; | |||
| 2684 | } | |||
| 2685 | ||||
| 2686 | /// \brief Retrieve the location of the right angle bracket ending the | |||
| 2687 | /// explicit template argument list following the name, if any. | |||
| 2688 | SourceLocation getRAngleLoc() const { | |||
| 2689 | if (!HasTemplateKWAndArgsInfo) return SourceLocation(); | |||
| 2690 | return getTrailingASTTemplateKWAndArgsInfo()->RAngleLoc; | |||
| 2691 | } | |||
| 2692 | ||||
| 2693 | /// \brief Determines whether the name was preceded by the template keyword. | |||
| 2694 | bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); } | |||
| 2695 | ||||
| 2696 | /// \brief Determines whether this expression had explicit template arguments. | |||
| 2697 | bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); } | |||
| 2698 | ||||
| 2699 | TemplateArgumentLoc const *getTemplateArgs() const { | |||
| 2700 | if (!hasExplicitTemplateArgs()) | |||
| 2701 | return nullptr; | |||
| 2702 | return const_cast<OverloadExpr *>(this)->getTrailingTemplateArgumentLoc(); | |||
| 2703 | } | |||
| 2704 | ||||
| 2705 | unsigned getNumTemplateArgs() const { | |||
| 2706 | if (!hasExplicitTemplateArgs()) | |||
| 2707 | return 0; | |||
| 2708 | ||||
| 2709 | return getTrailingASTTemplateKWAndArgsInfo()->NumTemplateArgs; | |||
| 2710 | } | |||
| 2711 | ||||
| 2712 | ArrayRef<TemplateArgumentLoc> template_arguments() const { | |||
| 2713 | return {getTemplateArgs(), getNumTemplateArgs()}; | |||
| 2714 | } | |||
| 2715 | ||||
| 2716 | /// \brief Copies the template arguments into the given structure. | |||
| 2717 | void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const { | |||
| 2718 | if (hasExplicitTemplateArgs()) | |||
| 2719 | getTrailingASTTemplateKWAndArgsInfo()->copyInto(getTemplateArgs(), List); | |||
| 2720 | } | |||
| 2721 | ||||
| 2722 | static bool classof(const Stmt *T) { | |||
| 2723 | return T->getStmtClass() == UnresolvedLookupExprClass || | |||
| 2724 | T->getStmtClass() == UnresolvedMemberExprClass; | |||
| 2725 | } | |||
| 2726 | }; | |||
| 2727 | ||||
| 2728 | /// \brief A reference to a name which we were able to look up during | |||
| 2729 | /// parsing but could not resolve to a specific declaration. | |||
| 2730 | /// | |||
| 2731 | /// This arises in several ways: | |||
| 2732 | /// * we might be waiting for argument-dependent lookup; | |||
| 2733 | /// * the name might resolve to an overloaded function; | |||
| 2734 | /// and eventually: | |||
| 2735 | /// * the lookup might have included a function template. | |||
| 2736 | /// | |||
| 2737 | /// These never include UnresolvedUsingValueDecls, which are always class | |||
| 2738 | /// members and therefore appear only in UnresolvedMemberLookupExprs. | |||
| 2739 | class UnresolvedLookupExpr final | |||
| 2740 | : public OverloadExpr, | |||
| 2741 | private llvm::TrailingObjects< | |||
| 2742 | UnresolvedLookupExpr, ASTTemplateKWAndArgsInfo, TemplateArgumentLoc> { | |||
| 2743 | friend class ASTStmtReader; | |||
| 2744 | friend class OverloadExpr; | |||
| 2745 | friend TrailingObjects; | |||
| 2746 | ||||
| 2747 | /// True if these lookup results should be extended by | |||
| 2748 | /// argument-dependent lookup if this is the operand of a function | |||
| 2749 | /// call. | |||
| 2750 | bool RequiresADL = false; | |||
| 2751 | ||||
| 2752 | /// True if these lookup results are overloaded. This is pretty | |||
| 2753 | /// trivially rederivable if we urgently need to kill this field. | |||
| 2754 | bool Overloaded = false; | |||
| 2755 | ||||
| 2756 | /// The naming class (C++ [class.access.base]p5) of the lookup, if | |||
| 2757 | /// any. This can generally be recalculated from the context chain, | |||
| 2758 | /// but that can be fairly expensive for unqualified lookups. If we | |||
| 2759 | /// want to improve memory use here, this could go in a union | |||
| 2760 | /// against the qualified-lookup bits. | |||
| 2761 | CXXRecordDecl *NamingClass = nullptr; | |||
| 2762 | ||||
| 2763 | UnresolvedLookupExpr(const ASTContext &C, | |||
| 2764 | CXXRecordDecl *NamingClass, | |||
| 2765 | NestedNameSpecifierLoc QualifierLoc, | |||
| 2766 | SourceLocation TemplateKWLoc, | |||
| 2767 | const DeclarationNameInfo &NameInfo, | |||
| 2768 | bool RequiresADL, bool Overloaded, | |||
| 2769 | const TemplateArgumentListInfo *TemplateArgs, | |||
| 2770 | UnresolvedSetIterator Begin, UnresolvedSetIterator End) | |||
| 2771 | : OverloadExpr(UnresolvedLookupExprClass, C, QualifierLoc, TemplateKWLoc, | |||
| 2772 | NameInfo, TemplateArgs, Begin, End, false, false, false), | |||
| 2773 | RequiresADL(RequiresADL), | |||
| 2774 | Overloaded(Overloaded), NamingClass(NamingClass) {} | |||
| 2775 | ||||
| 2776 | UnresolvedLookupExpr(EmptyShell Empty) | |||
| 2777 | : OverloadExpr(UnresolvedLookupExprClass, Empty) {} | |||
| 2778 | ||||
| 2779 | size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const { | |||
| 2780 | return HasTemplateKWAndArgsInfo ? 1 : 0; | |||
| 2781 | } | |||
| 2782 | ||||
| 2783 | public: | |||
| 2784 | static UnresolvedLookupExpr *Create(const ASTContext &C, | |||
| 2785 | CXXRecordDecl *NamingClass, | |||
| 2786 | NestedNameSpecifierLoc QualifierLoc, | |||
| 2787 | const DeclarationNameInfo &NameInfo, | |||
| 2788 | bool ADL, bool Overloaded, | |||
| 2789 | UnresolvedSetIterator Begin, | |||
| 2790 | UnresolvedSetIterator End) { | |||
| 2791 | return new(C) UnresolvedLookupExpr(C, NamingClass, QualifierLoc, | |||
| 2792 | SourceLocation(), NameInfo, | |||
| 2793 | ADL, Overloaded, nullptr, Begin, End); | |||
| 2794 | } | |||
| 2795 | ||||
| 2796 | static UnresolvedLookupExpr *Create(const ASTContext &C, | |||
| 2797 | CXXRecordDecl *NamingClass, | |||
| 2798 | NestedNameSpecifierLoc QualifierLoc, | |||
| 2799 | SourceLocation TemplateKWLoc, | |||
| 2800 | const DeclarationNameInfo &NameInfo, | |||
| 2801 | bool ADL, | |||
| 2802 | const TemplateArgumentListInfo *Args, | |||
| 2803 | UnresolvedSetIterator Begin, | |||
| 2804 | UnresolvedSetIterator End); | |||
| 2805 | ||||
| 2806 | static UnresolvedLookupExpr *CreateEmpty(const ASTContext &C, | |||
| 2807 | bool HasTemplateKWAndArgsInfo, | |||
| 2808 | unsigned NumTemplateArgs); | |||
| 2809 | ||||
| 2810 | /// True if this declaration should be extended by | |||
| 2811 | /// argument-dependent lookup. | |||
| 2812 | bool requiresADL() const { return RequiresADL; } | |||
| 2813 | ||||
| 2814 | /// True if this lookup is overloaded. | |||
| 2815 | bool isOverloaded() const { return Overloaded; } | |||
| 2816 | ||||
| 2817 | /// Gets the 'naming class' (in the sense of C++0x | |||
| 2818 | /// [class.access.base]p5) of the lookup. This is the scope | |||
| 2819 | /// that was looked in to find these results. | |||
| 2820 | CXXRecordDecl *getNamingClass() const { return NamingClass; } | |||
| 2821 | ||||
| 2822 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)) { | |||
| 2823 | if (NestedNameSpecifierLoc l = getQualifierLoc()) | |||
| 2824 | return l.getBeginLoc(); | |||
| 2825 | return getNameInfo().getLocStart(); | |||
| 2826 | } | |||
| 2827 | ||||
| 2828 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)) { | |||
| 2829 | if (hasExplicitTemplateArgs()) | |||
| 2830 | return getRAngleLoc(); | |||
| 2831 | return getNameInfo().getLocEnd(); | |||
| 2832 | } | |||
| 2833 | ||||
| 2834 | child_range children() { | |||
| 2835 | return child_range(child_iterator(), child_iterator()); | |||
| 2836 | } | |||
| 2837 | ||||
| 2838 | static bool classof(const Stmt *T) { | |||
| 2839 | return T->getStmtClass() == UnresolvedLookupExprClass; | |||
| 2840 | } | |||
| 2841 | }; | |||
| 2842 | ||||
| 2843 | /// \brief A qualified reference to a name whose declaration cannot | |||
| 2844 | /// yet be resolved. | |||
| 2845 | /// | |||
| 2846 | /// DependentScopeDeclRefExpr is similar to DeclRefExpr in that | |||
| 2847 | /// it expresses a reference to a declaration such as | |||
| 2848 | /// X<T>::value. The difference, however, is that an | |||
| 2849 | /// DependentScopeDeclRefExpr node is used only within C++ templates when | |||
| 2850 | /// the qualification (e.g., X<T>::) refers to a dependent type. In | |||
| 2851 | /// this case, X<T>::value cannot resolve to a declaration because the | |||
| 2852 | /// declaration will differ from one instantiation of X<T> to the | |||
| 2853 | /// next. Therefore, DependentScopeDeclRefExpr keeps track of the | |||
| 2854 | /// qualifier (X<T>::) and the name of the entity being referenced | |||
| 2855 | /// ("value"). Such expressions will instantiate to a DeclRefExpr once the | |||
| 2856 | /// declaration can be found. | |||
| 2857 | class DependentScopeDeclRefExpr final | |||
| 2858 | : public Expr, | |||
| 2859 | private llvm::TrailingObjects<DependentScopeDeclRefExpr, | |||
| 2860 | ASTTemplateKWAndArgsInfo, | |||
| 2861 | TemplateArgumentLoc> { | |||
| 2862 | /// \brief The nested-name-specifier that qualifies this unresolved | |||
| 2863 | /// declaration name. | |||
| 2864 | NestedNameSpecifierLoc QualifierLoc; | |||
| 2865 | ||||
| 2866 | /// \brief The name of the entity we will be referencing. | |||
| 2867 | DeclarationNameInfo NameInfo; | |||
| 2868 | ||||
| 2869 | /// \brief Whether the name includes info for explicit template | |||
| 2870 | /// keyword and arguments. | |||
| 2871 | bool HasTemplateKWAndArgsInfo; | |||
| 2872 | ||||
| 2873 | DependentScopeDeclRefExpr(QualType T, | |||
| 2874 | NestedNameSpecifierLoc QualifierLoc, | |||
| 2875 | SourceLocation TemplateKWLoc, | |||
| 2876 | const DeclarationNameInfo &NameInfo, | |||
| 2877 | const TemplateArgumentListInfo *Args); | |||
| 2878 | ||||
| 2879 | size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const { | |||
| 2880 | return HasTemplateKWAndArgsInfo ? 1 : 0; | |||
| 2881 | } | |||
| 2882 | ||||
| 2883 | public: | |||
| 2884 | friend class ASTStmtReader; | |||
| 2885 | friend class ASTStmtWriter; | |||
| 2886 | friend TrailingObjects; | |||
| 2887 | ||||
| 2888 | static DependentScopeDeclRefExpr *Create(const ASTContext &C, | |||
| 2889 | NestedNameSpecifierLoc QualifierLoc, | |||
| 2890 | SourceLocation TemplateKWLoc, | |||
| 2891 | const DeclarationNameInfo &NameInfo, | |||
| 2892 | const TemplateArgumentListInfo *TemplateArgs); | |||
| 2893 | ||||
| 2894 | static DependentScopeDeclRefExpr *CreateEmpty(const ASTContext &C, | |||
| 2895 | bool HasTemplateKWAndArgsInfo, | |||
| 2896 | unsigned NumTemplateArgs); | |||
| 2897 | ||||
| 2898 | /// \brief Retrieve the name that this expression refers to. | |||
| 2899 | const DeclarationNameInfo &getNameInfo() const { return NameInfo; } | |||
| 2900 | ||||
| 2901 | /// \brief Retrieve the name that this expression refers to. | |||
| 2902 | DeclarationName getDeclName() const { return NameInfo.getName(); } | |||
| 2903 | ||||
| 2904 | /// \brief Retrieve the location of the name within the expression. | |||
| 2905 | /// | |||
| 2906 | /// For example, in "X<T>::value" this is the location of "value". | |||
| 2907 | SourceLocation getLocation() const { return NameInfo.getLoc(); } | |||
| 2908 | ||||
| 2909 | /// \brief Retrieve the nested-name-specifier that qualifies the | |||
| 2910 | /// name, with source location information. | |||
| 2911 | NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } | |||
| 2912 | ||||
| 2913 | /// \brief Retrieve the nested-name-specifier that qualifies this | |||
| 2914 | /// declaration. | |||
| 2915 | NestedNameSpecifier *getQualifier() const { | |||
| 2916 | return QualifierLoc.getNestedNameSpecifier(); | |||
| 2917 | } | |||
| 2918 | ||||
| 2919 | /// \brief Retrieve the location of the template keyword preceding | |||
| 2920 | /// this name, if any. | |||
| 2921 | SourceLocation getTemplateKeywordLoc() const { | |||
| 2922 | if (!HasTemplateKWAndArgsInfo) return SourceLocation(); | |||
| 2923 | return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->TemplateKWLoc; | |||
| 2924 | } | |||
| 2925 | ||||
| 2926 | /// \brief Retrieve the location of the left angle bracket starting the | |||
| 2927 | /// explicit template argument list following the name, if any. | |||
| 2928 | SourceLocation getLAngleLoc() const { | |||
| 2929 | if (!HasTemplateKWAndArgsInfo) return SourceLocation(); | |||
| 2930 | return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->LAngleLoc; | |||
| 2931 | } | |||
| 2932 | ||||
| 2933 | /// \brief Retrieve the location of the right angle bracket ending the | |||
| 2934 | /// explicit template argument list following the name, if any. | |||
| 2935 | SourceLocation getRAngleLoc() const { | |||
| 2936 | if (!HasTemplateKWAndArgsInfo) return SourceLocation(); | |||
| 2937 | return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->RAngleLoc; | |||
| 2938 | } | |||
| 2939 | ||||
| 2940 | /// Determines whether the name was preceded by the template keyword. | |||
| 2941 | bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); } | |||
| 2942 | ||||
| 2943 | /// Determines whether this lookup had explicit template arguments. | |||
| 2944 | bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); } | |||
| 2945 | ||||
| 2946 | /// \brief Copies the template arguments (if present) into the given | |||
| 2947 | /// structure. | |||
| 2948 | void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const { | |||
| 2949 | if (hasExplicitTemplateArgs()) | |||
| 2950 | getTrailingObjects<ASTTemplateKWAndArgsInfo>()->copyInto( | |||
| 2951 | getTrailingObjects<TemplateArgumentLoc>(), List); | |||
| 2952 | } | |||
| 2953 | ||||
| 2954 | TemplateArgumentLoc const *getTemplateArgs() const { | |||
| 2955 | if (!hasExplicitTemplateArgs()) | |||
| 2956 | return nullptr; | |||
| 2957 | ||||
| 2958 | return getTrailingObjects<TemplateArgumentLoc>(); | |||
| 2959 | } | |||
| 2960 | ||||
| 2961 | unsigned getNumTemplateArgs() const { | |||
| 2962 | if (!hasExplicitTemplateArgs()) | |||
| 2963 | return 0; | |||
| 2964 | ||||
| 2965 | return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs; | |||
| 2966 | } | |||
| 2967 | ||||
| 2968 | ArrayRef<TemplateArgumentLoc> template_arguments() const { | |||
| 2969 | return {getTemplateArgs(), getNumTemplateArgs()}; | |||
| 2970 | } | |||
| 2971 | ||||
| 2972 | /// Note: getLocStart() is the start of the whole DependentScopeDeclRefExpr, | |||
| 2973 | /// and differs from getLocation().getStart(). | |||
| 2974 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)) { | |||
| 2975 | return QualifierLoc.getBeginLoc(); | |||
| 2976 | } | |||
| 2977 | ||||
| 2978 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)) { | |||
| 2979 | if (hasExplicitTemplateArgs()) | |||
| 2980 | return getRAngleLoc(); | |||
| 2981 | return getLocation(); | |||
| 2982 | } | |||
| 2983 | ||||
| 2984 | static bool classof(const Stmt *T) { | |||
| 2985 | return T->getStmtClass() == DependentScopeDeclRefExprClass; | |||
| 2986 | } | |||
| 2987 | ||||
| 2988 | child_range children() { | |||
| 2989 | return child_range(child_iterator(), child_iterator()); | |||
| 2990 | } | |||
| 2991 | }; | |||
| 2992 | ||||
| 2993 | /// Represents an expression -- generally a full-expression -- that | |||
| 2994 | /// introduces cleanups to be run at the end of the sub-expression's | |||
| 2995 | /// evaluation. The most common source of expression-introduced | |||
| 2996 | /// cleanups is temporary objects in C++, but several other kinds of | |||
| 2997 | /// expressions can create cleanups, including basically every | |||
| 2998 | /// call in ARC that returns an Objective-C pointer. | |||
| 2999 | /// | |||
| 3000 | /// This expression also tracks whether the sub-expression contains a | |||
| 3001 | /// potentially-evaluated block literal. The lifetime of a block | |||
| 3002 | /// literal is the extent of the enclosing scope. | |||
| 3003 | class ExprWithCleanups final | |||
| 3004 | : public Expr, | |||
| 3005 | private llvm::TrailingObjects<ExprWithCleanups, BlockDecl *> { | |||
| 3006 | public: | |||
| 3007 | /// The type of objects that are kept in the cleanup. | |||
| 3008 | /// It's useful to remember the set of blocks; we could also | |||
| 3009 | /// remember the set of temporaries, but there's currently | |||
| 3010 | /// no need. | |||
| 3011 | using CleanupObject = BlockDecl *; | |||
| 3012 | ||||
| 3013 | private: | |||
| 3014 | friend class ASTStmtReader; | |||
| 3015 | friend TrailingObjects; | |||
| 3016 | ||||
| 3017 | Stmt *SubExpr; | |||
| 3018 | ||||
| 3019 | ExprWithCleanups(EmptyShell, unsigned NumObjects); | |||
| 3020 | ExprWithCleanups(Expr *SubExpr, bool CleanupsHaveSideEffects, | |||
| 3021 | ArrayRef<CleanupObject> Objects); | |||
| 3022 | ||||
| 3023 | public: | |||
| 3024 | static ExprWithCleanups *Create(const ASTContext &C, EmptyShell empty, | |||
| 3025 | unsigned numObjects); | |||
| 3026 | ||||
| 3027 | static ExprWithCleanups *Create(const ASTContext &C, Expr *subexpr, | |||
| 3028 | bool CleanupsHaveSideEffects, | |||
| 3029 | ArrayRef<CleanupObject> objects); | |||
| 3030 | ||||
| 3031 | ArrayRef<CleanupObject> getObjects() const { | |||
| 3032 | return llvm::makeArrayRef(getTrailingObjects<CleanupObject>(), | |||
| 3033 | getNumObjects()); | |||
| 3034 | } | |||
| 3035 | ||||
| 3036 | unsigned getNumObjects() const { return ExprWithCleanupsBits.NumObjects; } | |||
| 3037 | ||||
| 3038 | CleanupObject getObject(unsigned i) const { | |||
| 3039 | assert(i < getNumObjects() && "Index out of range")(static_cast <bool> (i < getNumObjects() && "Index out of range" ) ? void (0) : __assert_fail ("i < getNumObjects() && \"Index out of range\"" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 3039, __extension__ __PRETTY_FUNCTION__)); | |||
| 3040 | return getObjects()[i]; | |||
| 3041 | } | |||
| 3042 | ||||
| 3043 | Expr *getSubExpr() { return cast<Expr>(SubExpr); } | |||
| 3044 | const Expr *getSubExpr() const { return cast<Expr>(SubExpr); } | |||
| 3045 | ||||
| 3046 | bool cleanupsHaveSideEffects() const { | |||
| 3047 | return ExprWithCleanupsBits.CleanupsHaveSideEffects; | |||
| 3048 | } | |||
| 3049 | ||||
| 3050 | /// As with any mutator of the AST, be very careful | |||
| 3051 | /// when modifying an existing AST to preserve its invariants. | |||
| 3052 | void setSubExpr(Expr *E) { SubExpr = E; } | |||
| 3053 | ||||
| 3054 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)) { | |||
| 3055 | return SubExpr->getLocStart(); | |||
| 3056 | } | |||
| 3057 | ||||
| 3058 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)) { return SubExpr->getLocEnd();} | |||
| 3059 | ||||
| 3060 | // Implement isa/cast/dyncast/etc. | |||
| 3061 | static bool classof(const Stmt *T) { | |||
| 3062 | return T->getStmtClass() == ExprWithCleanupsClass; | |||
| 3063 | } | |||
| 3064 | ||||
| 3065 | // Iterators | |||
| 3066 | child_range children() { return child_range(&SubExpr, &SubExpr + 1); } | |||
| 3067 | }; | |||
| 3068 | ||||
| 3069 | /// \brief Describes an explicit type conversion that uses functional | |||
| 3070 | /// notion but could not be resolved because one or more arguments are | |||
| 3071 | /// type-dependent. | |||
| 3072 | /// | |||
| 3073 | /// The explicit type conversions expressed by | |||
| 3074 | /// CXXUnresolvedConstructExpr have the form <tt>T(a1, a2, ..., aN)</tt>, | |||
| 3075 | /// where \c T is some type and \c a1, \c a2, ..., \c aN are values, and | |||
| 3076 | /// either \c T is a dependent type or one or more of the <tt>a</tt>'s is | |||
| 3077 | /// type-dependent. For example, this would occur in a template such | |||
| 3078 | /// as: | |||
| 3079 | /// | |||
| 3080 | /// \code | |||
| 3081 | /// template<typename T, typename A1> | |||
| 3082 | /// inline T make_a(const A1& a1) { | |||
| 3083 | /// return T(a1); | |||
| 3084 | /// } | |||
| 3085 | /// \endcode | |||
| 3086 | /// | |||
| 3087 | /// When the returned expression is instantiated, it may resolve to a | |||
| 3088 | /// constructor call, conversion function call, or some kind of type | |||
| 3089 | /// conversion. | |||
| 3090 | class CXXUnresolvedConstructExpr final | |||
| 3091 | : public Expr, | |||
| 3092 | private llvm::TrailingObjects<CXXUnresolvedConstructExpr, Expr *> { | |||
| 3093 | friend class ASTStmtReader; | |||
| 3094 | friend TrailingObjects; | |||
| 3095 | ||||
| 3096 | /// \brief The type being constructed. | |||
| 3097 | TypeSourceInfo *Type = nullptr; | |||
| 3098 | ||||
| 3099 | /// \brief The location of the left parentheses ('('). | |||
| 3100 | SourceLocation LParenLoc; | |||
| 3101 | ||||
| 3102 | /// \brief The location of the right parentheses (')'). | |||
| 3103 | SourceLocation RParenLoc; | |||
| 3104 | ||||
| 3105 | /// \brief The number of arguments used to construct the type. | |||
| 3106 | unsigned NumArgs; | |||
| 3107 | ||||
| 3108 | CXXUnresolvedConstructExpr(TypeSourceInfo *Type, | |||
| 3109 | SourceLocation LParenLoc, | |||
| 3110 | ArrayRef<Expr*> Args, | |||
| 3111 | SourceLocation RParenLoc); | |||
| 3112 | ||||
| 3113 | CXXUnresolvedConstructExpr(EmptyShell Empty, unsigned NumArgs) | |||
| 3114 | : Expr(CXXUnresolvedConstructExprClass, Empty), NumArgs(NumArgs) {} | |||
| 3115 | ||||
| 3116 | public: | |||
| 3117 | static CXXUnresolvedConstructExpr *Create(const ASTContext &C, | |||
| 3118 | TypeSourceInfo *Type, | |||
| 3119 | SourceLocation LParenLoc, | |||
| 3120 | ArrayRef<Expr*> Args, | |||
| 3121 | SourceLocation RParenLoc); | |||
| 3122 | ||||
| 3123 | static CXXUnresolvedConstructExpr *CreateEmpty(const ASTContext &C, | |||
| 3124 | unsigned NumArgs); | |||
| 3125 | ||||
| 3126 | /// \brief Retrieve the type that is being constructed, as specified | |||
| 3127 | /// in the source code. | |||
| 3128 | QualType getTypeAsWritten() const { return Type->getType(); } | |||
| 3129 | ||||
| 3130 | /// \brief Retrieve the type source information for the type being | |||
| 3131 | /// constructed. | |||
| 3132 | TypeSourceInfo *getTypeSourceInfo() const { return Type; } | |||
| 3133 | ||||
| 3134 | /// \brief Retrieve the location of the left parentheses ('(') that | |||
| 3135 | /// precedes the argument list. | |||
| 3136 | SourceLocation getLParenLoc() const { return LParenLoc; } | |||
| 3137 | void setLParenLoc(SourceLocation L) { LParenLoc = L; } | |||
| 3138 | ||||
| 3139 | /// \brief Retrieve the location of the right parentheses (')') that | |||
| 3140 | /// follows the argument list. | |||
| 3141 | SourceLocation getRParenLoc() const { return RParenLoc; } | |||
| 3142 | void setRParenLoc(SourceLocation L) { RParenLoc = L; } | |||
| 3143 | ||||
| 3144 | /// Determine whether this expression models list-initialization. | |||
| 3145 | /// If so, there will be exactly one subexpression, which will be | |||
| 3146 | /// an InitListExpr. | |||
| 3147 | bool isListInitialization() const { return LParenLoc.isInvalid(); } | |||
| 3148 | ||||
| 3149 | /// \brief Retrieve the number of arguments. | |||
| 3150 | unsigned arg_size() const { return NumArgs; } | |||
| 3151 | ||||
| 3152 | using arg_iterator = Expr **; | |||
| 3153 | ||||
| 3154 | arg_iterator arg_begin() { return getTrailingObjects<Expr *>(); } | |||
| 3155 | arg_iterator arg_end() { return arg_begin() + NumArgs; } | |||
| 3156 | ||||
| 3157 | using const_arg_iterator = const Expr* const *; | |||
| 3158 | ||||
| 3159 | const_arg_iterator arg_begin() const { return getTrailingObjects<Expr *>(); } | |||
| 3160 | const_arg_iterator arg_end() const { | |||
| 3161 | return arg_begin() + NumArgs; | |||
| 3162 | } | |||
| 3163 | ||||
| 3164 | Expr *getArg(unsigned I) { | |||
| 3165 | assert(I < NumArgs && "Argument index out-of-range")(static_cast <bool> (I < NumArgs && "Argument index out-of-range" ) ? void (0) : __assert_fail ("I < NumArgs && \"Argument index out-of-range\"" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 3165, __extension__ __PRETTY_FUNCTION__)); | |||
| 3166 | return *(arg_begin() + I); | |||
| 3167 | } | |||
| 3168 | ||||
| 3169 | const Expr *getArg(unsigned I) const { | |||
| 3170 | assert(I < NumArgs && "Argument index out-of-range")(static_cast <bool> (I < NumArgs && "Argument index out-of-range" ) ? void (0) : __assert_fail ("I < NumArgs && \"Argument index out-of-range\"" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 3170, __extension__ __PRETTY_FUNCTION__)); | |||
| 3171 | return *(arg_begin() + I); | |||
| 3172 | } | |||
| 3173 | ||||
| 3174 | void setArg(unsigned I, Expr *E) { | |||
| 3175 | assert(I < NumArgs && "Argument index out-of-range")(static_cast <bool> (I < NumArgs && "Argument index out-of-range" ) ? void (0) : __assert_fail ("I < NumArgs && \"Argument index out-of-range\"" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 3175, __extension__ __PRETTY_FUNCTION__)); | |||
| 3176 | *(arg_begin() + I) = E; | |||
| 3177 | } | |||
| 3178 | ||||
| 3179 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)); | |||
| 3180 | ||||
| 3181 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)) { | |||
| 3182 | if (!RParenLoc.isValid() && NumArgs > 0) | |||
| 3183 | return getArg(NumArgs - 1)->getLocEnd(); | |||
| 3184 | return RParenLoc; | |||
| 3185 | } | |||
| 3186 | ||||
| 3187 | static bool classof(const Stmt *T) { | |||
| 3188 | return T->getStmtClass() == CXXUnresolvedConstructExprClass; | |||
| 3189 | } | |||
| 3190 | ||||
| 3191 | // Iterators | |||
| 3192 | child_range children() { | |||
| 3193 | Stmt **begin = reinterpret_cast<Stmt **>(arg_begin()); | |||
| 3194 | return child_range(begin, begin + NumArgs); | |||
| 3195 | } | |||
| 3196 | }; | |||
| 3197 | ||||
| 3198 | /// \brief Represents a C++ member access expression where the actual | |||
| 3199 | /// member referenced could not be resolved because the base | |||
| 3200 | /// expression or the member name was dependent. | |||
| 3201 | /// | |||
| 3202 | /// Like UnresolvedMemberExprs, these can be either implicit or | |||
| 3203 | /// explicit accesses. It is only possible to get one of these with | |||
| 3204 | /// an implicit access if a qualifier is provided. | |||
| 3205 | class CXXDependentScopeMemberExpr final | |||
| 3206 | : public Expr, | |||
| 3207 | private llvm::TrailingObjects<CXXDependentScopeMemberExpr, | |||
| 3208 | ASTTemplateKWAndArgsInfo, | |||
| 3209 | TemplateArgumentLoc> { | |||
| 3210 | /// \brief The expression for the base pointer or class reference, | |||
| 3211 | /// e.g., the \c x in x.f. Can be null in implicit accesses. | |||
| 3212 | Stmt *Base; | |||
| 3213 | ||||
| 3214 | /// \brief The type of the base expression. Never null, even for | |||
| 3215 | /// implicit accesses. | |||
| 3216 | QualType BaseType; | |||
| 3217 | ||||
| 3218 | /// \brief Whether this member expression used the '->' operator or | |||
| 3219 | /// the '.' operator. | |||
| 3220 | bool IsArrow : 1; | |||
| 3221 | ||||
| 3222 | /// \brief Whether this member expression has info for explicit template | |||
| 3223 | /// keyword and arguments. | |||
| 3224 | bool HasTemplateKWAndArgsInfo : 1; | |||
| 3225 | ||||
| 3226 | /// \brief The location of the '->' or '.' operator. | |||
| 3227 | SourceLocation OperatorLoc; | |||
| 3228 | ||||
| 3229 | /// \brief The nested-name-specifier that precedes the member name, if any. | |||
| 3230 | NestedNameSpecifierLoc QualifierLoc; | |||
| 3231 | ||||
| 3232 | /// \brief In a qualified member access expression such as t->Base::f, this | |||
| 3233 | /// member stores the resolves of name lookup in the context of the member | |||
| 3234 | /// access expression, to be used at instantiation time. | |||
| 3235 | /// | |||
| 3236 | /// FIXME: This member, along with the QualifierLoc, could | |||
| 3237 | /// be stuck into a structure that is optionally allocated at the end of | |||
| 3238 | /// the CXXDependentScopeMemberExpr, to save space in the common case. | |||
| 3239 | NamedDecl *FirstQualifierFoundInScope; | |||
| 3240 | ||||
| 3241 | /// \brief The member to which this member expression refers, which | |||
| 3242 | /// can be name, overloaded operator, or destructor. | |||
| 3243 | /// | |||
| 3244 | /// FIXME: could also be a template-id | |||
| 3245 | DeclarationNameInfo MemberNameInfo; | |||
| 3246 | ||||
| 3247 | size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const { | |||
| 3248 | return HasTemplateKWAndArgsInfo ? 1 : 0; | |||
| 3249 | } | |||
| 3250 | ||||
| 3251 | CXXDependentScopeMemberExpr(const ASTContext &C, Expr *Base, | |||
| 3252 | QualType BaseType, bool IsArrow, | |||
| 3253 | SourceLocation OperatorLoc, | |||
| 3254 | NestedNameSpecifierLoc QualifierLoc, | |||
| 3255 | SourceLocation TemplateKWLoc, | |||
| 3256 | NamedDecl *FirstQualifierFoundInScope, | |||
| 3257 | DeclarationNameInfo MemberNameInfo, | |||
| 3258 | const TemplateArgumentListInfo *TemplateArgs); | |||
| 3259 | ||||
| 3260 | public: | |||
| 3261 | friend class ASTStmtReader; | |||
| 3262 | friend class ASTStmtWriter; | |||
| 3263 | friend TrailingObjects; | |||
| 3264 | ||||
| 3265 | CXXDependentScopeMemberExpr(const ASTContext &C, Expr *Base, | |||
| 3266 | QualType BaseType, bool IsArrow, | |||
| 3267 | SourceLocation OperatorLoc, | |||
| 3268 | NestedNameSpecifierLoc QualifierLoc, | |||
| 3269 | NamedDecl *FirstQualifierFoundInScope, | |||
| 3270 | DeclarationNameInfo MemberNameInfo); | |||
| 3271 | ||||
| 3272 | static CXXDependentScopeMemberExpr * | |||
| 3273 | Create(const ASTContext &C, Expr *Base, QualType BaseType, bool IsArrow, | |||
| 3274 | SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, | |||
| 3275 | SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierFoundInScope, | |||
| 3276 | DeclarationNameInfo MemberNameInfo, | |||
| 3277 | const TemplateArgumentListInfo *TemplateArgs); | |||
| 3278 | ||||
| 3279 | static CXXDependentScopeMemberExpr * | |||
| 3280 | CreateEmpty(const ASTContext &C, bool HasTemplateKWAndArgsInfo, | |||
| 3281 | unsigned NumTemplateArgs); | |||
| 3282 | ||||
| 3283 | /// \brief True if this is an implicit access, i.e. one in which the | |||
| 3284 | /// member being accessed was not written in the source. The source | |||
| 3285 | /// location of the operator is invalid in this case. | |||
| 3286 | bool isImplicitAccess() const; | |||
| 3287 | ||||
| 3288 | /// \brief Retrieve the base object of this member expressions, | |||
| 3289 | /// e.g., the \c x in \c x.m. | |||
| 3290 | Expr *getBase() const { | |||
| 3291 | assert(!isImplicitAccess())(static_cast <bool> (!isImplicitAccess()) ? void (0) : __assert_fail ("!isImplicitAccess()", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 3291, __extension__ __PRETTY_FUNCTION__)); | |||
| 3292 | return cast<Expr>(Base); | |||
| 3293 | } | |||
| 3294 | ||||
| 3295 | QualType getBaseType() const { return BaseType; } | |||
| 3296 | ||||
| 3297 | /// \brief Determine whether this member expression used the '->' | |||
| 3298 | /// operator; otherwise, it used the '.' operator. | |||
| 3299 | bool isArrow() const { return IsArrow; } | |||
| 3300 | ||||
| 3301 | /// \brief Retrieve the location of the '->' or '.' operator. | |||
| 3302 | SourceLocation getOperatorLoc() const { return OperatorLoc; } | |||
| 3303 | ||||
| 3304 | /// \brief Retrieve the nested-name-specifier that qualifies the member | |||
| 3305 | /// name. | |||
| 3306 | NestedNameSpecifier *getQualifier() const { | |||
| 3307 | return QualifierLoc.getNestedNameSpecifier(); | |||
| 3308 | } | |||
| 3309 | ||||
| 3310 | /// \brief Retrieve the nested-name-specifier that qualifies the member | |||
| 3311 | /// name, with source location information. | |||
| 3312 | NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } | |||
| 3313 | ||||
| 3314 | /// \brief Retrieve the first part of the nested-name-specifier that was | |||
| 3315 | /// found in the scope of the member access expression when the member access | |||
| 3316 | /// was initially parsed. | |||
| 3317 | /// | |||
| 3318 | /// This function only returns a useful result when member access expression | |||
| 3319 | /// uses a qualified member name, e.g., "x.Base::f". Here, the declaration | |||
| 3320 | /// returned by this function describes what was found by unqualified name | |||
| 3321 | /// lookup for the identifier "Base" within the scope of the member access | |||
| 3322 | /// expression itself. At template instantiation time, this information is | |||
| 3323 | /// combined with the results of name lookup into the type of the object | |||
| 3324 | /// expression itself (the class type of x). | |||
| 3325 | NamedDecl *getFirstQualifierFoundInScope() const { | |||
| 3326 | return FirstQualifierFoundInScope; | |||
| 3327 | } | |||
| 3328 | ||||
| 3329 | /// \brief Retrieve the name of the member that this expression | |||
| 3330 | /// refers to. | |||
| 3331 | const DeclarationNameInfo &getMemberNameInfo() const { | |||
| 3332 | return MemberNameInfo; | |||
| 3333 | } | |||
| 3334 | ||||
| 3335 | /// \brief Retrieve the name of the member that this expression | |||
| 3336 | /// refers to. | |||
| 3337 | DeclarationName getMember() const { return MemberNameInfo.getName(); } | |||
| 3338 | ||||
| 3339 | // \brief Retrieve the location of the name of the member that this | |||
| 3340 | // expression refers to. | |||
| 3341 | SourceLocation getMemberLoc() const { return MemberNameInfo.getLoc(); } | |||
| 3342 | ||||
| 3343 | /// \brief Retrieve the location of the template keyword preceding the | |||
| 3344 | /// member name, if any. | |||
| 3345 | SourceLocation getTemplateKeywordLoc() const { | |||
| 3346 | if (!HasTemplateKWAndArgsInfo) return SourceLocation(); | |||
| 3347 | return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->TemplateKWLoc; | |||
| 3348 | } | |||
| 3349 | ||||
| 3350 | /// \brief Retrieve the location of the left angle bracket starting the | |||
| 3351 | /// explicit template argument list following the member name, if any. | |||
| 3352 | SourceLocation getLAngleLoc() const { | |||
| 3353 | if (!HasTemplateKWAndArgsInfo) return SourceLocation(); | |||
| 3354 | return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->LAngleLoc; | |||
| 3355 | } | |||
| 3356 | ||||
| 3357 | /// \brief Retrieve the location of the right angle bracket ending the | |||
| 3358 | /// explicit template argument list following the member name, if any. | |||
| 3359 | SourceLocation getRAngleLoc() const { | |||
| 3360 | if (!HasTemplateKWAndArgsInfo) return SourceLocation(); | |||
| 3361 | return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->RAngleLoc; | |||
| 3362 | } | |||
| 3363 | ||||
| 3364 | /// Determines whether the member name was preceded by the template keyword. | |||
| 3365 | bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); } | |||
| 3366 | ||||
| 3367 | /// \brief Determines whether this member expression actually had a C++ | |||
| 3368 | /// template argument list explicitly specified, e.g., x.f<int>. | |||
| 3369 | bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); } | |||
| 3370 | ||||
| 3371 | /// \brief Copies the template arguments (if present) into the given | |||
| 3372 | /// structure. | |||
| 3373 | void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const { | |||
| 3374 | if (hasExplicitTemplateArgs()) | |||
| 3375 | getTrailingObjects<ASTTemplateKWAndArgsInfo>()->copyInto( | |||
| 3376 | getTrailingObjects<TemplateArgumentLoc>(), List); | |||
| 3377 | } | |||
| 3378 | ||||
| 3379 | /// \brief Retrieve the template arguments provided as part of this | |||
| 3380 | /// template-id. | |||
| 3381 | const TemplateArgumentLoc *getTemplateArgs() const { | |||
| 3382 | if (!hasExplicitTemplateArgs()) | |||
| 3383 | return nullptr; | |||
| 3384 | ||||
| 3385 | return getTrailingObjects<TemplateArgumentLoc>(); | |||
| 3386 | } | |||
| 3387 | ||||
| 3388 | /// \brief Retrieve the number of template arguments provided as part of this | |||
| 3389 | /// template-id. | |||
| 3390 | unsigned getNumTemplateArgs() const { | |||
| 3391 | if (!hasExplicitTemplateArgs()) | |||
| 3392 | return 0; | |||
| 3393 | ||||
| 3394 | return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs; | |||
| 3395 | } | |||
| 3396 | ||||
| 3397 | ArrayRef<TemplateArgumentLoc> template_arguments() const { | |||
| 3398 | return {getTemplateArgs(), getNumTemplateArgs()}; | |||
| 3399 | } | |||
| 3400 | ||||
| 3401 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)) { | |||
| 3402 | if (!isImplicitAccess()) | |||
| 3403 | return Base->getLocStart(); | |||
| 3404 | if (getQualifier()) | |||
| 3405 | return getQualifierLoc().getBeginLoc(); | |||
| 3406 | return MemberNameInfo.getBeginLoc(); | |||
| 3407 | } | |||
| 3408 | ||||
| 3409 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)) { | |||
| 3410 | if (hasExplicitTemplateArgs()) | |||
| 3411 | return getRAngleLoc(); | |||
| 3412 | return MemberNameInfo.getEndLoc(); | |||
| 3413 | } | |||
| 3414 | ||||
| 3415 | static bool classof(const Stmt *T) { | |||
| 3416 | return T->getStmtClass() == CXXDependentScopeMemberExprClass; | |||
| 3417 | } | |||
| 3418 | ||||
| 3419 | // Iterators | |||
| 3420 | child_range children() { | |||
| 3421 | if (isImplicitAccess()) | |||
| 3422 | return child_range(child_iterator(), child_iterator()); | |||
| 3423 | return child_range(&Base, &Base + 1); | |||
| 3424 | } | |||
| 3425 | }; | |||
| 3426 | ||||
| 3427 | /// \brief Represents a C++ member access expression for which lookup | |||
| 3428 | /// produced a set of overloaded functions. | |||
| 3429 | /// | |||
| 3430 | /// The member access may be explicit or implicit: | |||
| 3431 | /// \code | |||
| 3432 | /// struct A { | |||
| 3433 | /// int a, b; | |||
| 3434 | /// int explicitAccess() { return this->a + this->A::b; } | |||
| 3435 | /// int implicitAccess() { return a + A::b; } | |||
| 3436 | /// }; | |||
| 3437 | /// \endcode | |||
| 3438 | /// | |||
| 3439 | /// In the final AST, an explicit access always becomes a MemberExpr. | |||
| 3440 | /// An implicit access may become either a MemberExpr or a | |||
| 3441 | /// DeclRefExpr, depending on whether the member is static. | |||
| 3442 | class UnresolvedMemberExpr final | |||
| 3443 | : public OverloadExpr, | |||
| 3444 | private llvm::TrailingObjects< | |||
| 3445 | UnresolvedMemberExpr, ASTTemplateKWAndArgsInfo, TemplateArgumentLoc> { | |||
| 3446 | friend class ASTStmtReader; | |||
| 3447 | friend class OverloadExpr; | |||
| 3448 | friend TrailingObjects; | |||
| 3449 | ||||
| 3450 | /// \brief Whether this member expression used the '->' operator or | |||
| 3451 | /// the '.' operator. | |||
| 3452 | bool IsArrow : 1; | |||
| 3453 | ||||
| 3454 | /// \brief Whether the lookup results contain an unresolved using | |||
| 3455 | /// declaration. | |||
| 3456 | bool HasUnresolvedUsing : 1; | |||
| 3457 | ||||
| 3458 | /// \brief The expression for the base pointer or class reference, | |||
| 3459 | /// e.g., the \c x in x.f. | |||
| 3460 | /// | |||
| 3461 | /// This can be null if this is an 'unbased' member expression. | |||
| 3462 | Stmt *Base = nullptr; | |||
| 3463 | ||||
| 3464 | /// \brief The type of the base expression; never null. | |||
| 3465 | QualType BaseType; | |||
| 3466 | ||||
| 3467 | /// \brief The location of the '->' or '.' operator. | |||
| 3468 | SourceLocation OperatorLoc; | |||
| 3469 | ||||
| 3470 | UnresolvedMemberExpr(const ASTContext &C, bool HasUnresolvedUsing, | |||
| 3471 | Expr *Base, QualType BaseType, bool IsArrow, | |||
| 3472 | SourceLocation OperatorLoc, | |||
| 3473 | NestedNameSpecifierLoc QualifierLoc, | |||
| 3474 | SourceLocation TemplateKWLoc, | |||
| 3475 | const DeclarationNameInfo &MemberNameInfo, | |||
| 3476 | const TemplateArgumentListInfo *TemplateArgs, | |||
| 3477 | UnresolvedSetIterator Begin, UnresolvedSetIterator End); | |||
| 3478 | ||||
| 3479 | UnresolvedMemberExpr(EmptyShell Empty) | |||
| 3480 | : OverloadExpr(UnresolvedMemberExprClass, Empty), IsArrow(false), | |||
| 3481 | HasUnresolvedUsing(false) {} | |||
| 3482 | ||||
| 3483 | size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const { | |||
| 3484 | return HasTemplateKWAndArgsInfo ? 1 : 0; | |||
| 3485 | } | |||
| 3486 | ||||
| 3487 | public: | |||
| 3488 | static UnresolvedMemberExpr * | |||
| 3489 | Create(const ASTContext &C, bool HasUnresolvedUsing, | |||
| 3490 | Expr *Base, QualType BaseType, bool IsArrow, | |||
| 3491 | SourceLocation OperatorLoc, | |||
| 3492 | NestedNameSpecifierLoc QualifierLoc, | |||
| 3493 | SourceLocation TemplateKWLoc, | |||
| 3494 | const DeclarationNameInfo &MemberNameInfo, | |||
| 3495 | const TemplateArgumentListInfo *TemplateArgs, | |||
| 3496 | UnresolvedSetIterator Begin, UnresolvedSetIterator End); | |||
| 3497 | ||||
| 3498 | static UnresolvedMemberExpr * | |||
| 3499 | CreateEmpty(const ASTContext &C, bool HasTemplateKWAndArgsInfo, | |||
| 3500 | unsigned NumTemplateArgs); | |||
| 3501 | ||||
| 3502 | /// \brief True if this is an implicit access, i.e., one in which the | |||
| 3503 | /// member being accessed was not written in the source. | |||
| 3504 | /// | |||
| 3505 | /// The source location of the operator is invalid in this case. | |||
| 3506 | bool isImplicitAccess() const; | |||
| 3507 | ||||
| 3508 | /// \brief Retrieve the base object of this member expressions, | |||
| 3509 | /// e.g., the \c x in \c x.m. | |||
| 3510 | Expr *getBase() { | |||
| 3511 | assert(!isImplicitAccess())(static_cast <bool> (!isImplicitAccess()) ? void (0) : __assert_fail ("!isImplicitAccess()", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 3511, __extension__ __PRETTY_FUNCTION__)); | |||
| 3512 | return cast<Expr>(Base); | |||
| 3513 | } | |||
| 3514 | const Expr *getBase() const { | |||
| 3515 | assert(!isImplicitAccess())(static_cast <bool> (!isImplicitAccess()) ? void (0) : __assert_fail ("!isImplicitAccess()", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 3515, __extension__ __PRETTY_FUNCTION__)); | |||
| 3516 | return cast<Expr>(Base); | |||
| 3517 | } | |||
| 3518 | ||||
| 3519 | QualType getBaseType() const { return BaseType; } | |||
| 3520 | ||||
| 3521 | /// \brief Determine whether the lookup results contain an unresolved using | |||
| 3522 | /// declaration. | |||
| 3523 | bool hasUnresolvedUsing() const { return HasUnresolvedUsing; } | |||
| 3524 | ||||
| 3525 | /// \brief Determine whether this member expression used the '->' | |||
| 3526 | /// operator; otherwise, it used the '.' operator. | |||
| 3527 | bool isArrow() const { return IsArrow; } | |||
| 3528 | ||||
| 3529 | /// \brief Retrieve the location of the '->' or '.' operator. | |||
| 3530 | SourceLocation getOperatorLoc() const { return OperatorLoc; } | |||
| 3531 | ||||
| 3532 | /// \brief Retrieve the naming class of this lookup. | |||
| 3533 | CXXRecordDecl *getNamingClass() const; | |||
| 3534 | ||||
| 3535 | /// \brief Retrieve the full name info for the member that this expression | |||
| 3536 | /// refers to. | |||
| 3537 | const DeclarationNameInfo &getMemberNameInfo() const { return getNameInfo(); } | |||
| 3538 | ||||
| 3539 | /// \brief Retrieve the name of the member that this expression | |||
| 3540 | /// refers to. | |||
| 3541 | DeclarationName getMemberName() const { return getName(); } | |||
| 3542 | ||||
| 3543 | // \brief Retrieve the location of the name of the member that this | |||
| 3544 | // expression refers to. | |||
| 3545 | SourceLocation getMemberLoc() const { return getNameLoc(); } | |||
| 3546 | ||||
| 3547 | // \brief Return the preferred location (the member name) for the arrow when | |||
| 3548 | // diagnosing a problem with this expression. | |||
| 3549 | SourceLocation getExprLoc() const LLVM_READONLY__attribute__((__pure__)) { return getMemberLoc(); } | |||
| 3550 | ||||
| 3551 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)) { | |||
| 3552 | if (!isImplicitAccess()) | |||
| 3553 | return Base->getLocStart(); | |||
| 3554 | if (NestedNameSpecifierLoc l = getQualifierLoc()) | |||
| 3555 | return l.getBeginLoc(); | |||
| 3556 | return getMemberNameInfo().getLocStart(); | |||
| 3557 | } | |||
| 3558 | ||||
| 3559 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)) { | |||
| 3560 | if (hasExplicitTemplateArgs()) | |||
| 3561 | return getRAngleLoc(); | |||
| 3562 | return getMemberNameInfo().getLocEnd(); | |||
| 3563 | } | |||
| 3564 | ||||
| 3565 | static bool classof(const Stmt *T) { | |||
| 3566 | return T->getStmtClass() == UnresolvedMemberExprClass; | |||
| 3567 | } | |||
| 3568 | ||||
| 3569 | // Iterators | |||
| 3570 | child_range children() { | |||
| 3571 | if (isImplicitAccess()) | |||
| 3572 | return child_range(child_iterator(), child_iterator()); | |||
| 3573 | return child_range(&Base, &Base + 1); | |||
| 3574 | } | |||
| 3575 | }; | |||
| 3576 | ||||
| 3577 | inline ASTTemplateKWAndArgsInfo * | |||
| 3578 | OverloadExpr::getTrailingASTTemplateKWAndArgsInfo() { | |||
| 3579 | if (!HasTemplateKWAndArgsInfo) | |||
| 3580 | return nullptr; | |||
| 3581 | ||||
| 3582 | if (isa<UnresolvedLookupExpr>(this)) | |||
| 3583 | return cast<UnresolvedLookupExpr>(this) | |||
| 3584 | ->getTrailingObjects<ASTTemplateKWAndArgsInfo>(); | |||
| 3585 | else | |||
| 3586 | return cast<UnresolvedMemberExpr>(this) | |||
| 3587 | ->getTrailingObjects<ASTTemplateKWAndArgsInfo>(); | |||
| 3588 | } | |||
| 3589 | ||||
| 3590 | inline TemplateArgumentLoc *OverloadExpr::getTrailingTemplateArgumentLoc() { | |||
| 3591 | if (isa<UnresolvedLookupExpr>(this)) | |||
| 3592 | return cast<UnresolvedLookupExpr>(this) | |||
| 3593 | ->getTrailingObjects<TemplateArgumentLoc>(); | |||
| 3594 | else | |||
| 3595 | return cast<UnresolvedMemberExpr>(this) | |||
| 3596 | ->getTrailingObjects<TemplateArgumentLoc>(); | |||
| 3597 | } | |||
| 3598 | ||||
| 3599 | /// \brief Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]). | |||
| 3600 | /// | |||
| 3601 | /// The noexcept expression tests whether a given expression might throw. Its | |||
| 3602 | /// result is a boolean constant. | |||
| 3603 | class CXXNoexceptExpr : public Expr { | |||
| 3604 | friend class ASTStmtReader; | |||
| 3605 | ||||
| 3606 | bool Value : 1; | |||
| 3607 | Stmt *Operand; | |||
| 3608 | SourceRange Range; | |||
| 3609 | ||||
| 3610 | public: | |||
| 3611 | CXXNoexceptExpr(QualType Ty, Expr *Operand, CanThrowResult Val, | |||
| 3612 | SourceLocation Keyword, SourceLocation RParen) | |||
| 3613 | : Expr(CXXNoexceptExprClass, Ty, VK_RValue, OK_Ordinary, | |||
| 3614 | /*TypeDependent*/false, | |||
| 3615 | /*ValueDependent*/Val == CT_Dependent, | |||
| 3616 | Val == CT_Dependent || Operand->isInstantiationDependent(), | |||
| 3617 | Operand->containsUnexpandedParameterPack()), | |||
| 3618 | Value(Val == CT_Cannot), Operand(Operand), Range(Keyword, RParen) {} | |||
| 3619 | ||||
| 3620 | CXXNoexceptExpr(EmptyShell Empty) : Expr(CXXNoexceptExprClass, Empty) {} | |||
| 3621 | ||||
| 3622 | Expr *getOperand() const { return static_cast<Expr*>(Operand); } | |||
| 3623 | ||||
| 3624 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)) { return Range.getBegin(); } | |||
| 3625 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)) { return Range.getEnd(); } | |||
| 3626 | SourceRange getSourceRange() const LLVM_READONLY__attribute__((__pure__)) { return Range; } | |||
| 3627 | ||||
| 3628 | bool getValue() const { return Value; } | |||
| 3629 | ||||
| 3630 | static bool classof(const Stmt *T) { | |||
| 3631 | return T->getStmtClass() == CXXNoexceptExprClass; | |||
| 3632 | } | |||
| 3633 | ||||
| 3634 | // Iterators | |||
| 3635 | child_range children() { return child_range(&Operand, &Operand + 1); } | |||
| 3636 | }; | |||
| 3637 | ||||
| 3638 | /// \brief Represents a C++11 pack expansion that produces a sequence of | |||
| 3639 | /// expressions. | |||
| 3640 | /// | |||
| 3641 | /// A pack expansion expression contains a pattern (which itself is an | |||
| 3642 | /// expression) followed by an ellipsis. For example: | |||
| 3643 | /// | |||
| 3644 | /// \code | |||
| 3645 | /// template<typename F, typename ...Types> | |||
| 3646 | /// void forward(F f, Types &&...args) { | |||
| 3647 | /// f(static_cast<Types&&>(args)...); | |||
| 3648 | /// } | |||
| 3649 | /// \endcode | |||
| 3650 | /// | |||
| 3651 | /// Here, the argument to the function object \c f is a pack expansion whose | |||
| 3652 | /// pattern is \c static_cast<Types&&>(args). When the \c forward function | |||
| 3653 | /// template is instantiated, the pack expansion will instantiate to zero or | |||
| 3654 | /// or more function arguments to the function object \c f. | |||
| 3655 | class PackExpansionExpr : public Expr { | |||
| 3656 | friend class ASTStmtReader; | |||
| 3657 | friend class ASTStmtWriter; | |||
| 3658 | ||||
| 3659 | SourceLocation EllipsisLoc; | |||
| 3660 | ||||
| 3661 | /// \brief The number of expansions that will be produced by this pack | |||
| 3662 | /// expansion expression, if known. | |||
| 3663 | /// | |||
| 3664 | /// When zero, the number of expansions is not known. Otherwise, this value | |||
| 3665 | /// is the number of expansions + 1. | |||
| 3666 | unsigned NumExpansions; | |||
| 3667 | ||||
| 3668 | Stmt *Pattern; | |||
| 3669 | ||||
| 3670 | public: | |||
| 3671 | PackExpansionExpr(QualType T, Expr *Pattern, SourceLocation EllipsisLoc, | |||
| 3672 | Optional<unsigned> NumExpansions) | |||
| 3673 | : Expr(PackExpansionExprClass, T, Pattern->getValueKind(), | |||
| 3674 | Pattern->getObjectKind(), /*TypeDependent=*/true, | |||
| 3675 | /*ValueDependent=*/true, /*InstantiationDependent=*/true, | |||
| 3676 | /*ContainsUnexpandedParameterPack=*/false), | |||
| 3677 | EllipsisLoc(EllipsisLoc), | |||
| 3678 | NumExpansions(NumExpansions ? *NumExpansions + 1 : 0), | |||
| 3679 | Pattern(Pattern) {} | |||
| 3680 | ||||
| 3681 | PackExpansionExpr(EmptyShell Empty) : Expr(PackExpansionExprClass, Empty) {} | |||
| 3682 | ||||
| 3683 | /// \brief Retrieve the pattern of the pack expansion. | |||
| 3684 | Expr *getPattern() { return reinterpret_cast<Expr *>(Pattern); } | |||
| 3685 | ||||
| 3686 | /// \brief Retrieve the pattern of the pack expansion. | |||
| 3687 | const Expr *getPattern() const { return reinterpret_cast<Expr *>(Pattern); } | |||
| 3688 | ||||
| 3689 | /// \brief Retrieve the location of the ellipsis that describes this pack | |||
| 3690 | /// expansion. | |||
| 3691 | SourceLocation getEllipsisLoc() const { return EllipsisLoc; } | |||
| 3692 | ||||
| 3693 | /// \brief Determine the number of expansions that will be produced when | |||
| 3694 | /// this pack expansion is instantiated, if already known. | |||
| 3695 | Optional<unsigned> getNumExpansions() const { | |||
| 3696 | if (NumExpansions) | |||
| 3697 | return NumExpansions - 1; | |||
| 3698 | ||||
| 3699 | return None; | |||
| 3700 | } | |||
| 3701 | ||||
| 3702 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)) { | |||
| 3703 | return Pattern->getLocStart(); | |||
| 3704 | } | |||
| 3705 | ||||
| 3706 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)) { return EllipsisLoc; } | |||
| 3707 | ||||
| 3708 | static bool classof(const Stmt *T) { | |||
| 3709 | return T->getStmtClass() == PackExpansionExprClass; | |||
| 3710 | } | |||
| 3711 | ||||
| 3712 | // Iterators | |||
| 3713 | child_range children() { | |||
| 3714 | return child_range(&Pattern, &Pattern + 1); | |||
| 3715 | } | |||
| 3716 | }; | |||
| 3717 | ||||
| 3718 | /// \brief Represents an expression that computes the length of a parameter | |||
| 3719 | /// pack. | |||
| 3720 | /// | |||
| 3721 | /// \code | |||
| 3722 | /// template<typename ...Types> | |||
| 3723 | /// struct count { | |||
| 3724 | /// static const unsigned value = sizeof...(Types); | |||
| 3725 | /// }; | |||
| 3726 | /// \endcode | |||
| 3727 | class SizeOfPackExpr final | |||
| 3728 | : public Expr, | |||
| 3729 | private llvm::TrailingObjects<SizeOfPackExpr, TemplateArgument> { | |||
| 3730 | friend class ASTStmtReader; | |||
| 3731 | friend class ASTStmtWriter; | |||
| 3732 | friend TrailingObjects; | |||
| 3733 | ||||
| 3734 | /// \brief The location of the \c sizeof keyword. | |||
| 3735 | SourceLocation OperatorLoc; | |||
| 3736 | ||||
| 3737 | /// \brief The location of the name of the parameter pack. | |||
| 3738 | SourceLocation PackLoc; | |||
| 3739 | ||||
| 3740 | /// \brief The location of the closing parenthesis. | |||
| 3741 | SourceLocation RParenLoc; | |||
| 3742 | ||||
| 3743 | /// \brief The length of the parameter pack, if known. | |||
| 3744 | /// | |||
| 3745 | /// When this expression is not value-dependent, this is the length of | |||
| 3746 | /// the pack. When the expression was parsed rather than instantiated | |||
| 3747 | /// (and thus is value-dependent), this is zero. | |||
| 3748 | /// | |||
| 3749 | /// After partial substitution into a sizeof...(X) expression (for instance, | |||
| 3750 | /// within an alias template or during function template argument deduction), | |||
| 3751 | /// we store a trailing array of partially-substituted TemplateArguments, | |||
| 3752 | /// and this is the length of that array. | |||
| 3753 | unsigned Length; | |||
| 3754 | ||||
| 3755 | /// \brief The parameter pack. | |||
| 3756 | NamedDecl *Pack = nullptr; | |||
| 3757 | ||||
| 3758 | /// \brief Create an expression that computes the length of | |||
| 3759 | /// the given parameter pack. | |||
| 3760 | SizeOfPackExpr(QualType SizeType, SourceLocation OperatorLoc, NamedDecl *Pack, | |||
| 3761 | SourceLocation PackLoc, SourceLocation RParenLoc, | |||
| 3762 | Optional<unsigned> Length, ArrayRef<TemplateArgument> PartialArgs) | |||
| 3763 | : Expr(SizeOfPackExprClass, SizeType, VK_RValue, OK_Ordinary, | |||
| 3764 | /*TypeDependent=*/false, /*ValueDependent=*/!Length, | |||
| 3765 | /*InstantiationDependent=*/!Length, | |||
| 3766 | /*ContainsUnexpandedParameterPack=*/false), | |||
| 3767 | OperatorLoc(OperatorLoc), PackLoc(PackLoc), RParenLoc(RParenLoc), | |||
| 3768 | Length(Length ? *Length : PartialArgs.size()), Pack(Pack) { | |||
| 3769 | assert((!Length || PartialArgs.empty()) &&(static_cast <bool> ((!Length || PartialArgs.empty()) && "have partial args for non-dependent sizeof... expression") ? void (0) : __assert_fail ("(!Length || PartialArgs.empty()) && \"have partial args for non-dependent sizeof... expression\"" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 3770, __extension__ __PRETTY_FUNCTION__)) | |||
| 3770 | "have partial args for non-dependent sizeof... expression")(static_cast <bool> ((!Length || PartialArgs.empty()) && "have partial args for non-dependent sizeof... expression") ? void (0) : __assert_fail ("(!Length || PartialArgs.empty()) && \"have partial args for non-dependent sizeof... expression\"" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 3770, __extension__ __PRETTY_FUNCTION__)); | |||
| 3771 | TemplateArgument *Args = getTrailingObjects<TemplateArgument>(); | |||
| 3772 | std::uninitialized_copy(PartialArgs.begin(), PartialArgs.end(), Args); | |||
| 3773 | } | |||
| 3774 | ||||
| 3775 | /// \brief Create an empty expression. | |||
| 3776 | SizeOfPackExpr(EmptyShell Empty, unsigned NumPartialArgs) | |||
| 3777 | : Expr(SizeOfPackExprClass, Empty), Length(NumPartialArgs) {} | |||
| 3778 | ||||
| 3779 | public: | |||
| 3780 | static SizeOfPackExpr *Create(ASTContext &Context, SourceLocation OperatorLoc, | |||
| 3781 | NamedDecl *Pack, SourceLocation PackLoc, | |||
| 3782 | SourceLocation RParenLoc, | |||
| 3783 | Optional<unsigned> Length = None, | |||
| 3784 | ArrayRef<TemplateArgument> PartialArgs = None); | |||
| 3785 | static SizeOfPackExpr *CreateDeserialized(ASTContext &Context, | |||
| 3786 | unsigned NumPartialArgs); | |||
| 3787 | ||||
| 3788 | /// \brief Determine the location of the 'sizeof' keyword. | |||
| 3789 | SourceLocation getOperatorLoc() const { return OperatorLoc; } | |||
| 3790 | ||||
| 3791 | /// \brief Determine the location of the parameter pack. | |||
| 3792 | SourceLocation getPackLoc() const { return PackLoc; } | |||
| 3793 | ||||
| 3794 | /// \brief Determine the location of the right parenthesis. | |||
| 3795 | SourceLocation getRParenLoc() const { return RParenLoc; } | |||
| 3796 | ||||
| 3797 | /// \brief Retrieve the parameter pack. | |||
| 3798 | NamedDecl *getPack() const { return Pack; } | |||
| 3799 | ||||
| 3800 | /// \brief Retrieve the length of the parameter pack. | |||
| 3801 | /// | |||
| 3802 | /// This routine may only be invoked when the expression is not | |||
| 3803 | /// value-dependent. | |||
| 3804 | unsigned getPackLength() const { | |||
| 3805 | assert(!isValueDependent() &&(static_cast <bool> (!isValueDependent() && "Cannot get the length of a value-dependent pack size expression" ) ? void (0) : __assert_fail ("!isValueDependent() && \"Cannot get the length of a value-dependent pack size expression\"" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 3806, __extension__ __PRETTY_FUNCTION__)) | |||
| 3806 | "Cannot get the length of a value-dependent pack size expression")(static_cast <bool> (!isValueDependent() && "Cannot get the length of a value-dependent pack size expression" ) ? void (0) : __assert_fail ("!isValueDependent() && \"Cannot get the length of a value-dependent pack size expression\"" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 3806, __extension__ __PRETTY_FUNCTION__)); | |||
| 3807 | return Length; | |||
| 3808 | } | |||
| 3809 | ||||
| 3810 | /// \brief Determine whether this represents a partially-substituted sizeof... | |||
| 3811 | /// expression, such as is produced for: | |||
| 3812 | /// | |||
| 3813 | /// template<typename ...Ts> using X = int[sizeof...(Ts)]; | |||
| 3814 | /// template<typename ...Us> void f(X<Us..., 1, 2, 3, Us...>); | |||
| 3815 | bool isPartiallySubstituted() const { | |||
| 3816 | return isValueDependent() && Length; | |||
| 3817 | } | |||
| 3818 | ||||
| 3819 | /// \brief Get | |||
| 3820 | ArrayRef<TemplateArgument> getPartialArguments() const { | |||
| 3821 | assert(isPartiallySubstituted())(static_cast <bool> (isPartiallySubstituted()) ? void ( 0) : __assert_fail ("isPartiallySubstituted()", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 3821, __extension__ __PRETTY_FUNCTION__)); | |||
| 3822 | const TemplateArgument *Args = getTrailingObjects<TemplateArgument>(); | |||
| 3823 | return llvm::makeArrayRef(Args, Args + Length); | |||
| 3824 | } | |||
| 3825 | ||||
| 3826 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)) { return OperatorLoc; } | |||
| 3827 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)) { return RParenLoc; } | |||
| 3828 | ||||
| 3829 | static bool classof(const Stmt *T) { | |||
| 3830 | return T->getStmtClass() == SizeOfPackExprClass; | |||
| 3831 | } | |||
| 3832 | ||||
| 3833 | // Iterators | |||
| 3834 | child_range children() { | |||
| 3835 | return child_range(child_iterator(), child_iterator()); | |||
| 3836 | } | |||
| 3837 | }; | |||
| 3838 | ||||
| 3839 | /// \brief Represents a reference to a non-type template parameter | |||
| 3840 | /// that has been substituted with a template argument. | |||
| 3841 | class SubstNonTypeTemplateParmExpr : public Expr { | |||
| 3842 | friend class ASTReader; | |||
| 3843 | friend class ASTStmtReader; | |||
| 3844 | ||||
| 3845 | /// \brief The replaced parameter. | |||
| 3846 | NonTypeTemplateParmDecl *Param; | |||
| 3847 | ||||
| 3848 | /// \brief The replacement expression. | |||
| 3849 | Stmt *Replacement; | |||
| 3850 | ||||
| 3851 | /// \brief The location of the non-type template parameter reference. | |||
| 3852 | SourceLocation NameLoc; | |||
| 3853 | ||||
| 3854 | explicit SubstNonTypeTemplateParmExpr(EmptyShell Empty) | |||
| 3855 | : Expr(SubstNonTypeTemplateParmExprClass, Empty) {} | |||
| 3856 | ||||
| 3857 | public: | |||
| 3858 | SubstNonTypeTemplateParmExpr(QualType type, | |||
| 3859 | ExprValueKind valueKind, | |||
| 3860 | SourceLocation loc, | |||
| 3861 | NonTypeTemplateParmDecl *param, | |||
| 3862 | Expr *replacement) | |||
| 3863 | : Expr(SubstNonTypeTemplateParmExprClass, type, valueKind, OK_Ordinary, | |||
| 3864 | replacement->isTypeDependent(), replacement->isValueDependent(), | |||
| 3865 | replacement->isInstantiationDependent(), | |||
| 3866 | replacement->containsUnexpandedParameterPack()), | |||
| 3867 | Param(param), Replacement(replacement), NameLoc(loc) {} | |||
| 3868 | ||||
| 3869 | SourceLocation getNameLoc() const { return NameLoc; } | |||
| 3870 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)) { return NameLoc; } | |||
| 3871 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)) { return NameLoc; } | |||
| 3872 | ||||
| 3873 | Expr *getReplacement() const { return cast<Expr>(Replacement); } | |||
| 3874 | ||||
| 3875 | NonTypeTemplateParmDecl *getParameter() const { return Param; } | |||
| 3876 | ||||
| 3877 | static bool classof(const Stmt *s) { | |||
| 3878 | return s->getStmtClass() == SubstNonTypeTemplateParmExprClass; | |||
| 3879 | } | |||
| 3880 | ||||
| 3881 | // Iterators | |||
| 3882 | child_range children() { return child_range(&Replacement, &Replacement+1); } | |||
| 3883 | }; | |||
| 3884 | ||||
| 3885 | /// \brief Represents a reference to a non-type template parameter pack that | |||
| 3886 | /// has been substituted with a non-template argument pack. | |||
| 3887 | /// | |||
| 3888 | /// When a pack expansion in the source code contains multiple parameter packs | |||
| 3889 | /// and those parameter packs correspond to different levels of template | |||
| 3890 | /// parameter lists, this node is used to represent a non-type template | |||
| 3891 | /// parameter pack from an outer level, which has already had its argument pack | |||
| 3892 | /// substituted but that still lives within a pack expansion that itself | |||
| 3893 | /// could not be instantiated. When actually performing a substitution into | |||
| 3894 | /// that pack expansion (e.g., when all template parameters have corresponding | |||
| 3895 | /// arguments), this type will be replaced with the appropriate underlying | |||
| 3896 | /// expression at the current pack substitution index. | |||
| 3897 | class SubstNonTypeTemplateParmPackExpr : public Expr { | |||
| 3898 | friend class ASTReader; | |||
| 3899 | friend class ASTStmtReader; | |||
| 3900 | ||||
| 3901 | /// \brief The non-type template parameter pack itself. | |||
| 3902 | NonTypeTemplateParmDecl *Param; | |||
| 3903 | ||||
| 3904 | /// \brief A pointer to the set of template arguments that this | |||
| 3905 | /// parameter pack is instantiated with. | |||
| 3906 | const TemplateArgument *Arguments; | |||
| 3907 | ||||
| 3908 | /// \brief The number of template arguments in \c Arguments. | |||
| 3909 | unsigned NumArguments; | |||
| 3910 | ||||
| 3911 | /// \brief The location of the non-type template parameter pack reference. | |||
| 3912 | SourceLocation NameLoc; | |||
| 3913 | ||||
| 3914 | explicit SubstNonTypeTemplateParmPackExpr(EmptyShell Empty) | |||
| 3915 | : Expr(SubstNonTypeTemplateParmPackExprClass, Empty) {} | |||
| 3916 | ||||
| 3917 | public: | |||
| 3918 | SubstNonTypeTemplateParmPackExpr(QualType T, | |||
| 3919 | ExprValueKind ValueKind, | |||
| 3920 | NonTypeTemplateParmDecl *Param, | |||
| 3921 | SourceLocation NameLoc, | |||
| 3922 | const TemplateArgument &ArgPack); | |||
| 3923 | ||||
| 3924 | /// \brief Retrieve the non-type template parameter pack being substituted. | |||
| 3925 | NonTypeTemplateParmDecl *getParameterPack() const { return Param; } | |||
| 3926 | ||||
| 3927 | /// \brief Retrieve the location of the parameter pack name. | |||
| 3928 | SourceLocation getParameterPackLocation() const { return NameLoc; } | |||
| 3929 | ||||
| 3930 | /// \brief Retrieve the template argument pack containing the substituted | |||
| 3931 | /// template arguments. | |||
| 3932 | TemplateArgument getArgumentPack() const; | |||
| 3933 | ||||
| 3934 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)) { return NameLoc; } | |||
| 3935 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)) { return NameLoc; } | |||
| 3936 | ||||
| 3937 | static bool classof(const Stmt *T) { | |||
| 3938 | return T->getStmtClass() == SubstNonTypeTemplateParmPackExprClass; | |||
| 3939 | } | |||
| 3940 | ||||
| 3941 | // Iterators | |||
| 3942 | child_range children() { | |||
| 3943 | return child_range(child_iterator(), child_iterator()); | |||
| 3944 | } | |||
| 3945 | }; | |||
| 3946 | ||||
| 3947 | /// \brief Represents a reference to a function parameter pack that has been | |||
| 3948 | /// substituted but not yet expanded. | |||
| 3949 | /// | |||
| 3950 | /// When a pack expansion contains multiple parameter packs at different levels, | |||
| 3951 | /// this node is used to represent a function parameter pack at an outer level | |||
| 3952 | /// which we have already substituted to refer to expanded parameters, but where | |||
| 3953 | /// the containing pack expansion cannot yet be expanded. | |||
| 3954 | /// | |||
| 3955 | /// \code | |||
| 3956 | /// template<typename...Ts> struct S { | |||
| 3957 | /// template<typename...Us> auto f(Ts ...ts) -> decltype(g(Us(ts)...)); | |||
| 3958 | /// }; | |||
| 3959 | /// template struct S<int, int>; | |||
| 3960 | /// \endcode | |||
| 3961 | class FunctionParmPackExpr final | |||
| 3962 | : public Expr, | |||
| 3963 | private llvm::TrailingObjects<FunctionParmPackExpr, ParmVarDecl *> { | |||
| 3964 | friend class ASTReader; | |||
| 3965 | friend class ASTStmtReader; | |||
| 3966 | friend TrailingObjects; | |||
| 3967 | ||||
| 3968 | /// \brief The function parameter pack which was referenced. | |||
| 3969 | ParmVarDecl *ParamPack; | |||
| 3970 | ||||
| 3971 | /// \brief The location of the function parameter pack reference. | |||
| 3972 | SourceLocation NameLoc; | |||
| 3973 | ||||
| 3974 | /// \brief The number of expansions of this pack. | |||
| 3975 | unsigned NumParameters; | |||
| 3976 | ||||
| 3977 | FunctionParmPackExpr(QualType T, ParmVarDecl *ParamPack, | |||
| 3978 | SourceLocation NameLoc, unsigned NumParams, | |||
| 3979 | ParmVarDecl *const *Params); | |||
| 3980 | ||||
| 3981 | public: | |||
| 3982 | static FunctionParmPackExpr *Create(const ASTContext &Context, QualType T, | |||
| 3983 | ParmVarDecl *ParamPack, | |||
| 3984 | SourceLocation NameLoc, | |||
| 3985 | ArrayRef<ParmVarDecl *> Params); | |||
| 3986 | static FunctionParmPackExpr *CreateEmpty(const ASTContext &Context, | |||
| 3987 | unsigned NumParams); | |||
| 3988 | ||||
| 3989 | /// \brief Get the parameter pack which this expression refers to. | |||
| 3990 | ParmVarDecl *getParameterPack() const { return ParamPack; } | |||
| 3991 | ||||
| 3992 | /// \brief Get the location of the parameter pack. | |||
| 3993 | SourceLocation getParameterPackLocation() const { return NameLoc; } | |||
| 3994 | ||||
| 3995 | /// \brief Iterators over the parameters which the parameter pack expanded | |||
| 3996 | /// into. | |||
| 3997 | using iterator = ParmVarDecl * const *; | |||
| 3998 | iterator begin() const { return getTrailingObjects<ParmVarDecl *>(); } | |||
| 3999 | iterator end() const { return begin() + NumParameters; } | |||
| 4000 | ||||
| 4001 | /// \brief Get the number of parameters in this parameter pack. | |||
| 4002 | unsigned getNumExpansions() const { return NumParameters; } | |||
| 4003 | ||||
| 4004 | /// \brief Get an expansion of the parameter pack by index. | |||
| 4005 | ParmVarDecl *getExpansion(unsigned I) const { return begin()[I]; } | |||
| 4006 | ||||
| 4007 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)) { return NameLoc; } | |||
| 4008 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)) { return NameLoc; } | |||
| 4009 | ||||
| 4010 | static bool classof(const Stmt *T) { | |||
| 4011 | return T->getStmtClass() == FunctionParmPackExprClass; | |||
| 4012 | } | |||
| 4013 | ||||
| 4014 | child_range children() { | |||
| 4015 | return child_range(child_iterator(), child_iterator()); | |||
| 4016 | } | |||
| 4017 | }; | |||
| 4018 | ||||
| 4019 | /// \brief Represents a prvalue temporary that is written into memory so that | |||
| 4020 | /// a reference can bind to it. | |||
| 4021 | /// | |||
| 4022 | /// Prvalue expressions are materialized when they need to have an address | |||
| 4023 | /// in memory for a reference to bind to. This happens when binding a | |||
| 4024 | /// reference to the result of a conversion, e.g., | |||
| 4025 | /// | |||
| 4026 | /// \code | |||
| 4027 | /// const int &r = 1.0; | |||
| 4028 | /// \endcode | |||
| 4029 | /// | |||
| 4030 | /// Here, 1.0 is implicitly converted to an \c int. That resulting \c int is | |||
| 4031 | /// then materialized via a \c MaterializeTemporaryExpr, and the reference | |||
| 4032 | /// binds to the temporary. \c MaterializeTemporaryExprs are always glvalues | |||
| 4033 | /// (either an lvalue or an xvalue, depending on the kind of reference binding | |||
| 4034 | /// to it), maintaining the invariant that references always bind to glvalues. | |||
| 4035 | /// | |||
| 4036 | /// Reference binding and copy-elision can both extend the lifetime of a | |||
| 4037 | /// temporary. When either happens, the expression will also track the | |||
| 4038 | /// declaration which is responsible for the lifetime extension. | |||
| 4039 | class MaterializeTemporaryExpr : public Expr { | |||
| 4040 | private: | |||
| 4041 | friend class ASTStmtReader; | |||
| 4042 | friend class ASTStmtWriter; | |||
| 4043 | ||||
| 4044 | struct ExtraState { | |||
| 4045 | /// \brief The temporary-generating expression whose value will be | |||
| 4046 | /// materialized. | |||
| 4047 | Stmt *Temporary; | |||
| 4048 | ||||
| 4049 | /// \brief The declaration which lifetime-extended this reference, if any. | |||
| 4050 | /// Either a VarDecl, or (for a ctor-initializer) a FieldDecl. | |||
| 4051 | const ValueDecl *ExtendingDecl; | |||
| 4052 | ||||
| 4053 | unsigned ManglingNumber; | |||
| 4054 | }; | |||
| 4055 | llvm::PointerUnion<Stmt *, ExtraState *> State; | |||
| 4056 | ||||
| 4057 | void initializeExtraState(const ValueDecl *ExtendedBy, | |||
| 4058 | unsigned ManglingNumber); | |||
| 4059 | ||||
| 4060 | public: | |||
| 4061 | MaterializeTemporaryExpr(QualType T, Expr *Temporary, | |||
| 4062 | bool BoundToLvalueReference) | |||
| 4063 | : Expr(MaterializeTemporaryExprClass, T, | |||
| 4064 | BoundToLvalueReference? VK_LValue : VK_XValue, OK_Ordinary, | |||
| 4065 | Temporary->isTypeDependent(), Temporary->isValueDependent(), | |||
| 4066 | Temporary->isInstantiationDependent(), | |||
| 4067 | Temporary->containsUnexpandedParameterPack()), | |||
| 4068 | State(Temporary) {} | |||
| 4069 | ||||
| 4070 | MaterializeTemporaryExpr(EmptyShell Empty) | |||
| 4071 | : Expr(MaterializeTemporaryExprClass, Empty) {} | |||
| 4072 | ||||
| 4073 | Stmt *getTemporary() const { | |||
| 4074 | return State.is<Stmt *>() ? State.get<Stmt *>() | |||
| 4075 | : State.get<ExtraState *>()->Temporary; | |||
| 4076 | } | |||
| 4077 | ||||
| 4078 | /// \brief Retrieve the temporary-generating subexpression whose value will | |||
| 4079 | /// be materialized into a glvalue. | |||
| 4080 | Expr *GetTemporaryExpr() const { return static_cast<Expr *>(getTemporary()); } | |||
| 4081 | ||||
| 4082 | /// \brief Retrieve the storage duration for the materialized temporary. | |||
| 4083 | StorageDuration getStorageDuration() const { | |||
| 4084 | const ValueDecl *ExtendingDecl = getExtendingDecl(); | |||
| 4085 | if (!ExtendingDecl) | |||
| 4086 | return SD_FullExpression; | |||
| 4087 | // FIXME: This is not necessarily correct for a temporary materialized | |||
| 4088 | // within a default initializer. | |||
| 4089 | if (isa<FieldDecl>(ExtendingDecl)) | |||
| 4090 | return SD_Automatic; | |||
| 4091 | // FIXME: This only works because storage class specifiers are not allowed | |||
| 4092 | // on decomposition declarations. | |||
| 4093 | if (isa<BindingDecl>(ExtendingDecl)) | |||
| 4094 | return ExtendingDecl->getDeclContext()->isFunctionOrMethod() | |||
| 4095 | ? SD_Automatic | |||
| 4096 | : SD_Static; | |||
| 4097 | return cast<VarDecl>(ExtendingDecl)->getStorageDuration(); | |||
| 4098 | } | |||
| 4099 | ||||
| 4100 | /// \brief Get the declaration which triggered the lifetime-extension of this | |||
| 4101 | /// temporary, if any. | |||
| 4102 | const ValueDecl *getExtendingDecl() const { | |||
| 4103 | return State.is<Stmt *>() ? nullptr | |||
| 4104 | : State.get<ExtraState *>()->ExtendingDecl; | |||
| 4105 | } | |||
| 4106 | ||||
| 4107 | void setExtendingDecl(const ValueDecl *ExtendedBy, unsigned ManglingNumber); | |||
| 4108 | ||||
| 4109 | unsigned getManglingNumber() const { | |||
| 4110 | return State.is<Stmt *>() ? 0 : State.get<ExtraState *>()->ManglingNumber; | |||
| 4111 | } | |||
| 4112 | ||||
| 4113 | /// \brief Determine whether this materialized temporary is bound to an | |||
| 4114 | /// lvalue reference; otherwise, it's bound to an rvalue reference. | |||
| 4115 | bool isBoundToLvalueReference() const { | |||
| 4116 | return getValueKind() == VK_LValue; | |||
| 4117 | } | |||
| 4118 | ||||
| 4119 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)) { | |||
| 4120 | return getTemporary()->getLocStart(); | |||
| 4121 | } | |||
| 4122 | ||||
| 4123 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)) { | |||
| 4124 | return getTemporary()->getLocEnd(); | |||
| 4125 | } | |||
| 4126 | ||||
| 4127 | static bool classof(const Stmt *T) { | |||
| 4128 | return T->getStmtClass() == MaterializeTemporaryExprClass; | |||
| 4129 | } | |||
| 4130 | ||||
| 4131 | // Iterators | |||
| 4132 | child_range children() { | |||
| 4133 | if (State.is<Stmt *>()) | |||
| 4134 | return child_range(State.getAddrOfPtr1(), State.getAddrOfPtr1() + 1); | |||
| 4135 | ||||
| 4136 | auto ES = State.get<ExtraState *>(); | |||
| 4137 | return child_range(&ES->Temporary, &ES->Temporary + 1); | |||
| 4138 | } | |||
| 4139 | }; | |||
| 4140 | ||||
| 4141 | /// \brief Represents a folding of a pack over an operator. | |||
| 4142 | /// | |||
| 4143 | /// This expression is always dependent and represents a pack expansion of the | |||
| 4144 | /// forms: | |||
| 4145 | /// | |||
| 4146 | /// ( expr op ... ) | |||
| 4147 | /// ( ... op expr ) | |||
| 4148 | /// ( expr op ... op expr ) | |||
| 4149 | class CXXFoldExpr : public Expr { | |||
| 4150 | friend class ASTStmtReader; | |||
| 4151 | friend class ASTStmtWriter; | |||
| 4152 | ||||
| 4153 | SourceLocation LParenLoc; | |||
| 4154 | SourceLocation EllipsisLoc; | |||
| 4155 | SourceLocation RParenLoc; | |||
| 4156 | Stmt *SubExprs[2]; | |||
| 4157 | BinaryOperatorKind Opcode; | |||
| 4158 | ||||
| 4159 | public: | |||
| 4160 | CXXFoldExpr(QualType T, SourceLocation LParenLoc, Expr *LHS, | |||
| 4161 | BinaryOperatorKind Opcode, SourceLocation EllipsisLoc, Expr *RHS, | |||
| 4162 | SourceLocation RParenLoc) | |||
| 4163 | : Expr(CXXFoldExprClass, T, VK_RValue, OK_Ordinary, | |||
| 4164 | /*Dependent*/ true, true, true, | |||
| 4165 | /*ContainsUnexpandedParameterPack*/ false), | |||
| 4166 | LParenLoc(LParenLoc), EllipsisLoc(EllipsisLoc), RParenLoc(RParenLoc), | |||
| 4167 | Opcode(Opcode) { | |||
| 4168 | SubExprs[0] = LHS; | |||
| 4169 | SubExprs[1] = RHS; | |||
| 4170 | } | |||
| 4171 | ||||
| 4172 | CXXFoldExpr(EmptyShell Empty) : Expr(CXXFoldExprClass, Empty) {} | |||
| 4173 | ||||
| 4174 | Expr *getLHS() const { return static_cast<Expr*>(SubExprs[0]); } | |||
| 4175 | Expr *getRHS() const { return static_cast<Expr*>(SubExprs[1]); } | |||
| 4176 | ||||
| 4177 | /// Does this produce a right-associated sequence of operators? | |||
| 4178 | bool isRightFold() const { | |||
| 4179 | return getLHS() && getLHS()->containsUnexpandedParameterPack(); | |||
| 4180 | } | |||
| 4181 | ||||
| 4182 | /// Does this produce a left-associated sequence of operators? | |||
| 4183 | bool isLeftFold() const { return !isRightFold(); } | |||
| 4184 | ||||
| 4185 | /// Get the pattern, that is, the operand that contains an unexpanded pack. | |||
| 4186 | Expr *getPattern() const { return isLeftFold() ? getRHS() : getLHS(); } | |||
| 4187 | ||||
| 4188 | /// Get the operand that doesn't contain a pack, for a binary fold. | |||
| 4189 | Expr *getInit() const { return isLeftFold() ? getLHS() : getRHS(); } | |||
| 4190 | ||||
| 4191 | SourceLocation getEllipsisLoc() const { return EllipsisLoc; } | |||
| 4192 | BinaryOperatorKind getOperator() const { return Opcode; } | |||
| 4193 | ||||
| 4194 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)) { | |||
| 4195 | return LParenLoc; | |||
| 4196 | } | |||
| 4197 | ||||
| 4198 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)) { | |||
| 4199 | return RParenLoc; | |||
| 4200 | } | |||
| 4201 | ||||
| 4202 | static bool classof(const Stmt *T) { | |||
| 4203 | return T->getStmtClass() == CXXFoldExprClass; | |||
| 4204 | } | |||
| 4205 | ||||
| 4206 | // Iterators | |||
| 4207 | child_range children() { return child_range(SubExprs, SubExprs + 2); } | |||
| 4208 | }; | |||
| 4209 | ||||
| 4210 | /// \brief Represents an expression that might suspend coroutine execution; | |||
| 4211 | /// either a co_await or co_yield expression. | |||
| 4212 | /// | |||
| 4213 | /// Evaluation of this expression first evaluates its 'ready' expression. If | |||
| 4214 | /// that returns 'false': | |||
| 4215 | /// -- execution of the coroutine is suspended | |||
| 4216 | /// -- the 'suspend' expression is evaluated | |||
| 4217 | /// -- if the 'suspend' expression returns 'false', the coroutine is | |||
| 4218 | /// resumed | |||
| 4219 | /// -- otherwise, control passes back to the resumer. | |||
| 4220 | /// If the coroutine is not suspended, or when it is resumed, the 'resume' | |||
| 4221 | /// expression is evaluated, and its result is the result of the overall | |||
| 4222 | /// expression. | |||
| 4223 | class CoroutineSuspendExpr : public Expr { | |||
| 4224 | friend class ASTStmtReader; | |||
| 4225 | ||||
| 4226 | SourceLocation KeywordLoc; | |||
| 4227 | ||||
| 4228 | enum SubExpr { Common, Ready, Suspend, Resume, Count }; | |||
| 4229 | ||||
| 4230 | Stmt *SubExprs[SubExpr::Count]; | |||
| 4231 | OpaqueValueExpr *OpaqueValue = nullptr; | |||
| 4232 | ||||
| 4233 | public: | |||
| 4234 | CoroutineSuspendExpr(StmtClass SC, SourceLocation KeywordLoc, Expr *Common, | |||
| 4235 | Expr *Ready, Expr *Suspend, Expr *Resume, | |||
| 4236 | OpaqueValueExpr *OpaqueValue) | |||
| 4237 | : Expr(SC, Resume->getType(), Resume->getValueKind(), | |||
| 4238 | Resume->getObjectKind(), Resume->isTypeDependent(), | |||
| 4239 | Resume->isValueDependent(), Common->isInstantiationDependent(), | |||
| 4240 | Common->containsUnexpandedParameterPack()), | |||
| 4241 | KeywordLoc(KeywordLoc), OpaqueValue(OpaqueValue) { | |||
| 4242 | SubExprs[SubExpr::Common] = Common; | |||
| 4243 | SubExprs[SubExpr::Ready] = Ready; | |||
| 4244 | SubExprs[SubExpr::Suspend] = Suspend; | |||
| 4245 | SubExprs[SubExpr::Resume] = Resume; | |||
| 4246 | } | |||
| 4247 | ||||
| 4248 | CoroutineSuspendExpr(StmtClass SC, SourceLocation KeywordLoc, QualType Ty, | |||
| 4249 | Expr *Common) | |||
| 4250 | : Expr(SC, Ty, VK_RValue, OK_Ordinary, true, true, true, | |||
| 4251 | Common->containsUnexpandedParameterPack()), | |||
| 4252 | KeywordLoc(KeywordLoc) { | |||
| 4253 | assert(Common->isTypeDependent() && Ty->isDependentType() &&(static_cast <bool> (Common->isTypeDependent() && Ty->isDependentType() && "wrong constructor for non-dependent co_await/co_yield expression" ) ? void (0) : __assert_fail ("Common->isTypeDependent() && Ty->isDependentType() && \"wrong constructor for non-dependent co_await/co_yield expression\"" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 4254, __extension__ __PRETTY_FUNCTION__)) | |||
| 4254 | "wrong constructor for non-dependent co_await/co_yield expression")(static_cast <bool> (Common->isTypeDependent() && Ty->isDependentType() && "wrong constructor for non-dependent co_await/co_yield expression" ) ? void (0) : __assert_fail ("Common->isTypeDependent() && Ty->isDependentType() && \"wrong constructor for non-dependent co_await/co_yield expression\"" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 4254, __extension__ __PRETTY_FUNCTION__)); | |||
| 4255 | SubExprs[SubExpr::Common] = Common; | |||
| 4256 | SubExprs[SubExpr::Ready] = nullptr; | |||
| 4257 | SubExprs[SubExpr::Suspend] = nullptr; | |||
| 4258 | SubExprs[SubExpr::Resume] = nullptr; | |||
| 4259 | } | |||
| 4260 | ||||
| 4261 | CoroutineSuspendExpr(StmtClass SC, EmptyShell Empty) : Expr(SC, Empty) { | |||
| 4262 | SubExprs[SubExpr::Common] = nullptr; | |||
| 4263 | SubExprs[SubExpr::Ready] = nullptr; | |||
| 4264 | SubExprs[SubExpr::Suspend] = nullptr; | |||
| 4265 | SubExprs[SubExpr::Resume] = nullptr; | |||
| 4266 | } | |||
| 4267 | ||||
| 4268 | SourceLocation getKeywordLoc() const { return KeywordLoc; } | |||
| 4269 | ||||
| 4270 | Expr *getCommonExpr() const { | |||
| 4271 | return static_cast<Expr*>(SubExprs[SubExpr::Common]); | |||
| 4272 | } | |||
| 4273 | ||||
| 4274 | /// \brief getOpaqueValue - Return the opaque value placeholder. | |||
| 4275 | OpaqueValueExpr *getOpaqueValue() const { return OpaqueValue; } | |||
| 4276 | ||||
| 4277 | Expr *getReadyExpr() const { | |||
| 4278 | return static_cast<Expr*>(SubExprs[SubExpr::Ready]); | |||
| 4279 | } | |||
| 4280 | ||||
| 4281 | Expr *getSuspendExpr() const { | |||
| 4282 | return static_cast<Expr*>(SubExprs[SubExpr::Suspend]); | |||
| 4283 | } | |||
| 4284 | ||||
| 4285 | Expr *getResumeExpr() const { | |||
| 4286 | return static_cast<Expr*>(SubExprs[SubExpr::Resume]); | |||
| 4287 | } | |||
| 4288 | ||||
| 4289 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)) { | |||
| 4290 | return KeywordLoc; | |||
| 4291 | } | |||
| 4292 | ||||
| 4293 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)) { | |||
| 4294 | return getCommonExpr()->getLocEnd(); | |||
| 4295 | } | |||
| 4296 | ||||
| 4297 | child_range children() { | |||
| 4298 | return child_range(SubExprs, SubExprs + SubExpr::Count); | |||
| 4299 | } | |||
| 4300 | ||||
| 4301 | static bool classof(const Stmt *T) { | |||
| 4302 | return T->getStmtClass() == CoawaitExprClass || | |||
| 4303 | T->getStmtClass() == CoyieldExprClass; | |||
| 4304 | } | |||
| 4305 | }; | |||
| 4306 | ||||
| 4307 | /// \brief Represents a 'co_await' expression. | |||
| 4308 | class CoawaitExpr : public CoroutineSuspendExpr { | |||
| 4309 | friend class ASTStmtReader; | |||
| 4310 | ||||
| 4311 | public: | |||
| 4312 | CoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand, Expr *Ready, | |||
| 4313 | Expr *Suspend, Expr *Resume, OpaqueValueExpr *OpaqueValue, | |||
| 4314 | bool IsImplicit = false) | |||
| 4315 | : CoroutineSuspendExpr(CoawaitExprClass, CoawaitLoc, Operand, Ready, | |||
| 4316 | Suspend, Resume, OpaqueValue) { | |||
| 4317 | CoawaitBits.IsImplicit = IsImplicit; | |||
| 4318 | } | |||
| 4319 | ||||
| 4320 | CoawaitExpr(SourceLocation CoawaitLoc, QualType Ty, Expr *Operand, | |||
| 4321 | bool IsImplicit = false) | |||
| 4322 | : CoroutineSuspendExpr(CoawaitExprClass, CoawaitLoc, Ty, Operand) { | |||
| 4323 | CoawaitBits.IsImplicit = IsImplicit; | |||
| 4324 | } | |||
| 4325 | ||||
| 4326 | CoawaitExpr(EmptyShell Empty) | |||
| 4327 | : CoroutineSuspendExpr(CoawaitExprClass, Empty) {} | |||
| 4328 | ||||
| 4329 | Expr *getOperand() const { | |||
| 4330 | // FIXME: Dig out the actual operand or store it. | |||
| 4331 | return getCommonExpr(); | |||
| 4332 | } | |||
| 4333 | ||||
| 4334 | bool isImplicit() const { return CoawaitBits.IsImplicit; } | |||
| 4335 | void setIsImplicit(bool value = true) { CoawaitBits.IsImplicit = value; } | |||
| 4336 | ||||
| 4337 | static bool classof(const Stmt *T) { | |||
| 4338 | return T->getStmtClass() == CoawaitExprClass; | |||
| 4339 | } | |||
| 4340 | }; | |||
| 4341 | ||||
| 4342 | /// \brief Represents a 'co_await' expression while the type of the promise | |||
| 4343 | /// is dependent. | |||
| 4344 | class DependentCoawaitExpr : public Expr { | |||
| 4345 | friend class ASTStmtReader; | |||
| 4346 | ||||
| 4347 | SourceLocation KeywordLoc; | |||
| 4348 | Stmt *SubExprs[2]; | |||
| 4349 | ||||
| 4350 | public: | |||
| 4351 | DependentCoawaitExpr(SourceLocation KeywordLoc, QualType Ty, Expr *Op, | |||
| 4352 | UnresolvedLookupExpr *OpCoawait) | |||
| 4353 | : Expr(DependentCoawaitExprClass, Ty, VK_RValue, OK_Ordinary, | |||
| 4354 | /*TypeDependent*/ true, /*ValueDependent*/ true, | |||
| 4355 | /*InstantiationDependent*/ true, | |||
| 4356 | Op->containsUnexpandedParameterPack()), | |||
| 4357 | KeywordLoc(KeywordLoc) { | |||
| 4358 | // NOTE: A co_await expression is dependent on the coroutines promise | |||
| 4359 | // type and may be dependent even when the `Op` expression is not. | |||
| 4360 | assert(Ty->isDependentType() &&(static_cast <bool> (Ty->isDependentType() && "wrong constructor for non-dependent co_await/co_yield expression" ) ? void (0) : __assert_fail ("Ty->isDependentType() && \"wrong constructor for non-dependent co_await/co_yield expression\"" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 4361, __extension__ __PRETTY_FUNCTION__)) | |||
| 4361 | "wrong constructor for non-dependent co_await/co_yield expression")(static_cast <bool> (Ty->isDependentType() && "wrong constructor for non-dependent co_await/co_yield expression" ) ? void (0) : __assert_fail ("Ty->isDependentType() && \"wrong constructor for non-dependent co_await/co_yield expression\"" , "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/ExprCXX.h" , 4361, __extension__ __PRETTY_FUNCTION__)); | |||
| 4362 | SubExprs[0] = Op; | |||
| 4363 | SubExprs[1] = OpCoawait; | |||
| 4364 | } | |||
| 4365 | ||||
| 4366 | DependentCoawaitExpr(EmptyShell Empty) | |||
| 4367 | : Expr(DependentCoawaitExprClass, Empty) {} | |||
| 4368 | ||||
| 4369 | Expr *getOperand() const { return cast<Expr>(SubExprs[0]); } | |||
| 4370 | ||||
| 4371 | UnresolvedLookupExpr *getOperatorCoawaitLookup() const { | |||
| 4372 | return cast<UnresolvedLookupExpr>(SubExprs[1]); | |||
| 4373 | } | |||
| 4374 | ||||
| 4375 | SourceLocation getKeywordLoc() const { return KeywordLoc; } | |||
| 4376 | ||||
| 4377 | SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)) { return KeywordLoc; } | |||
| 4378 | ||||
| 4379 | SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)) { | |||
| 4380 | return getOperand()->getLocEnd(); | |||
| 4381 | } | |||
| 4382 | ||||
| 4383 | child_range children() { return child_range(SubExprs, SubExprs + 2); } | |||
| 4384 | ||||
| 4385 | static bool classof(const Stmt *T) { | |||
| 4386 | return T->getStmtClass() == DependentCoawaitExprClass; | |||
| 4387 | } | |||
| 4388 | }; | |||
| 4389 | ||||
| 4390 | /// \brief Represents a 'co_yield' expression. | |||
| 4391 | class CoyieldExpr : public CoroutineSuspendExpr { | |||
| 4392 | friend class ASTStmtReader; | |||
| 4393 | ||||
| 4394 | public: | |||
| 4395 | CoyieldExpr(SourceLocation CoyieldLoc, Expr *Operand, Expr *Ready, | |||
| 4396 | Expr *Suspend, Expr *Resume, OpaqueValueExpr *OpaqueValue) | |||
| 4397 | : CoroutineSuspendExpr(CoyieldExprClass, CoyieldLoc, Operand, Ready, | |||
| 4398 | Suspend, Resume, OpaqueValue) {} | |||
| 4399 | CoyieldExpr(SourceLocation CoyieldLoc, QualType Ty, Expr *Operand) | |||
| 4400 | : CoroutineSuspendExpr(CoyieldExprClass, CoyieldLoc, Ty, Operand) {} | |||
| 4401 | CoyieldExpr(EmptyShell Empty) | |||
| 4402 | : CoroutineSuspendExpr(CoyieldExprClass, Empty) {} | |||
| 4403 | ||||
| 4404 | Expr *getOperand() const { | |||
| 4405 | // FIXME: Dig out the actual operand or store it. | |||
| 4406 | return getCommonExpr(); | |||
| 4407 | } | |||
| 4408 | ||||
| 4409 | static bool classof(const Stmt *T) { | |||
| 4410 | return T->getStmtClass() == CoyieldExprClass; | |||
| 4411 | } | |||
| 4412 | }; | |||
| 4413 | ||||
| 4414 | } // namespace clang | |||
| 4415 | ||||
| 4416 | #endif // LLVM_CLANG_AST_EXPRCXX_H |