aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2015-12-30 11:49:41 +0000
committerDimitry Andric <dim@FreeBSD.org>2015-12-30 11:49:41 +0000
commit45b533945f0851ec234ca846e1af5ee1e4df0b6e (patch)
tree0a5b74c0b9ca73aded34df95c91fcaf3815230d8 /lib
parent7e86edd64bfae4e324224452e4ea879b3371a4bd (diff)
downloadsrc-45b533945f0851ec234ca846e1af5ee1e4df0b6e.tar.gz
src-45b533945f0851ec234ca846e1af5ee1e4df0b6e.zip
Vendor import of clang trunk r256633:vendor/clang/clang-trunk-r256633
Notes
Notes: svn path=/vendor/clang/dist/; revision=292920 svn path=/vendor/clang/clang-trunk-r256633/; revision=292923; tag=vendor/clang/clang-trunk-r256633
Diffstat (limited to 'lib')
-rw-r--r--lib/ARCMigrate/ARCMT.cpp7
-rw-r--r--lib/ARCMigrate/FileRemapper.cpp2
-rw-r--r--lib/ARCMigrate/ObjCMT.cpp52
-rw-r--r--lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp4
-rw-r--r--lib/ARCMigrate/TransGCAttrs.cpp4
-rw-r--r--lib/ARCMigrate/TransProperties.cpp26
-rw-r--r--lib/ARCMigrate/TransRetainReleaseDealloc.cpp28
-rw-r--r--lib/ARCMigrate/TransformActions.cpp7
-rw-r--r--lib/ARCMigrate/Transforms.cpp10
-rw-r--r--lib/AST/ASTContext.cpp502
-rw-r--r--lib/AST/ASTDiagnostic.cpp65
-rw-r--r--lib/AST/ASTDumper.cpp29
-rw-r--r--lib/AST/ASTImporter.cpp19
-rw-r--r--lib/AST/CMakeLists.txt5
-rw-r--r--lib/AST/CXXABI.h12
-rw-r--r--lib/AST/CXXInheritance.cpp85
-rw-r--r--lib/AST/Decl.cpp584
-rw-r--r--lib/AST/DeclBase.cpp60
-rw-r--r--lib/AST/DeclCXX.cpp43
-rw-r--r--lib/AST/DeclFriend.cpp7
-rw-r--r--lib/AST/DeclGroup.cpp7
-rw-r--r--lib/AST/DeclObjC.cpp90
-rw-r--r--lib/AST/DeclOpenMP.cpp10
-rw-r--r--lib/AST/DeclPrinter.cpp52
-rw-r--r--lib/AST/DeclTemplate.cpp148
-rw-r--r--lib/AST/DeclarationName.cpp2
-rw-r--r--lib/AST/Expr.cpp660
-rw-r--r--lib/AST/ExprCXX.cpp293
-rw-r--r--lib/AST/ExprClassification.cpp6
-rw-r--r--lib/AST/ExprConstant.cpp702
-rw-r--r--lib/AST/ExprObjC.cpp379
-rw-r--r--lib/AST/ExternalASTSource.cpp31
-rw-r--r--lib/AST/ItaniumCXXABI.cpp14
-rw-r--r--lib/AST/ItaniumMangle.cpp285
-rw-r--r--lib/AST/Mangle.cpp3
-rw-r--r--lib/AST/MicrosoftCXXABI.cpp45
-rw-r--r--lib/AST/MicrosoftMangle.cpp502
-rw-r--r--lib/AST/NSAPI.cpp11
-rw-r--r--lib/AST/NestedNameSpecifier.cpp7
-rw-r--r--lib/AST/OpenMPClause.cpp465
-rw-r--r--lib/AST/RawCommentList.cpp86
-rw-r--r--lib/AST/RecordLayoutBuilder.cpp535
-rw-r--r--lib/AST/Stmt.cpp1328
-rw-r--r--lib/AST/StmtCXX.cpp86
-rw-r--r--lib/AST/StmtIterator.cpp2
-rw-r--r--lib/AST/StmtObjC.cpp73
-rw-r--r--lib/AST/StmtOpenMP.cpp884
-rw-r--r--lib/AST/StmtPrinter.cpp208
-rw-r--r--lib/AST/StmtProfile.cpp119
-rw-r--r--lib/AST/TemplateBase.cpp117
-rw-r--r--lib/AST/TemplateName.cpp54
-rw-r--r--lib/AST/Type.cpp273
-rw-r--r--lib/AST/TypeLoc.cpp34
-rw-r--r--lib/AST/TypePrinter.cpp29
-rw-r--r--lib/AST/VTableBuilder.cpp324
-rw-r--r--lib/ASTMatchers/ASTMatchFinder.cpp25
-rw-r--r--lib/ASTMatchers/ASTMatchersInternal.cpp10
-rw-r--r--lib/ASTMatchers/Dynamic/Diagnostics.cpp8
-rw-r--r--lib/ASTMatchers/Dynamic/Marshallers.h22
-rw-r--r--lib/ASTMatchers/Dynamic/Parser.cpp2
-rw-r--r--lib/ASTMatchers/Dynamic/Registry.cpp120
-rw-r--r--lib/ASTMatchers/Dynamic/VariantValue.cpp2
-rw-r--r--lib/Analysis/AnalysisDeclContext.cpp17
-rw-r--r--lib/Analysis/BodyFarm.cpp5
-rw-r--r--lib/Analysis/CFG.cpp187
-rw-r--r--lib/Analysis/Consumed.cpp127
-rw-r--r--lib/Analysis/ThreadSafety.cpp135
-rw-r--r--lib/Analysis/ThreadSafetyCommon.cpp53
-rw-r--r--lib/Basic/Attributes.cpp4
-rw-r--r--lib/Basic/Builtins.cpp86
-rw-r--r--lib/Basic/Diagnostic.cpp24
-rw-r--r--lib/Basic/DiagnosticIDs.cpp38
-rw-r--r--lib/Basic/FileManager.cpp92
-rw-r--r--lib/Basic/IdentifierTable.cpp9
-rw-r--r--lib/Basic/Module.cpp20
-rw-r--r--lib/Basic/ObjCRuntime.cpp3
-rw-r--r--lib/Basic/OpenMPKinds.cpp168
-rw-r--r--lib/Basic/SanitizerBlacklist.cpp2
-rw-r--r--lib/Basic/SourceManager.cpp97
-rw-r--r--lib/Basic/TargetInfo.cpp144
-rw-r--r--lib/Basic/Targets.cpp3323
-rw-r--r--lib/Basic/Version.cpp2
-rw-r--r--lib/Basic/VirtualFileSystem.cpp631
-rw-r--r--lib/CodeGen/ABIInfo.h22
-rw-r--r--lib/CodeGen/Address.h126
-rw-r--r--lib/CodeGen/BackendUtil.cpp188
-rw-r--r--lib/CodeGen/CGAtomic.cpp641
-rw-r--r--lib/CodeGen/CGBlocks.cpp899
-rw-r--r--lib/CodeGen/CGBlocks.h33
-rw-r--r--lib/CodeGen/CGBuilder.h263
-rw-r--r--lib/CodeGen/CGBuiltin.cpp1422
-rw-r--r--lib/CodeGen/CGCUDANV.cpp22
-rw-r--r--lib/CodeGen/CGCXX.cpp49
-rw-r--r--lib/CodeGen/CGCXXABI.cpp64
-rw-r--r--lib/CodeGen/CGCXXABI.h106
-rw-r--r--lib/CodeGen/CGCall.cpp989
-rw-r--r--lib/CodeGen/CGCall.h26
-rw-r--r--lib/CodeGen/CGClass.cpp784
-rw-r--r--lib/CodeGen/CGCleanup.cpp235
-rw-r--r--lib/CodeGen/CGCleanup.h125
-rw-r--r--lib/CodeGen/CGDebugInfo.cpp565
-rw-r--r--lib/CodeGen/CGDebugInfo.h96
-rw-r--r--lib/CodeGen/CGDecl.cpp373
-rw-r--r--lib/CodeGen/CGDeclCXX.cpp68
-rw-r--r--lib/CodeGen/CGException.cpp427
-rw-r--r--lib/CodeGen/CGExpr.cpp1357
-rw-r--r--lib/CodeGen/CGExprAgg.cpp182
-rw-r--r--lib/CodeGen/CGExprCXX.cpp400
-rw-r--r--lib/CodeGen/CGExprComplex.cpp142
-rw-r--r--lib/CodeGen/CGExprConstant.cpp64
-rw-r--r--lib/CodeGen/CGExprScalar.cpp348
-rw-r--r--lib/CodeGen/CGLoopInfo.cpp178
-rw-r--r--lib/CodeGen/CGLoopInfo.h55
-rw-r--r--lib/CodeGen/CGObjC.cpp347
-rw-r--r--lib/CodeGen/CGObjCGNU.cpp267
-rw-r--r--lib/CodeGen/CGObjCMac.cpp1419
-rw-r--r--lib/CodeGen/CGObjCRuntime.cpp56
-rw-r--r--lib/CodeGen/CGObjCRuntime.h36
-rw-r--r--lib/CodeGen/CGOpenCLRuntime.cpp34
-rw-r--r--lib/CodeGen/CGOpenMPRuntime.cpp1619
-rw-r--r--lib/CodeGen/CGOpenMPRuntime.h108
-rw-r--r--lib/CodeGen/CGRecordLayoutBuilder.cpp2
-rw-r--r--lib/CodeGen/CGStmt.cpp243
-rw-r--r--lib/CodeGen/CGStmtOpenMP.cpp1040
-rw-r--r--lib/CodeGen/CGVTT.cpp1
-rw-r--r--lib/CodeGen/CGVTables.cpp175
-rw-r--r--lib/CodeGen/CGVTables.h4
-rw-r--r--lib/CodeGen/CGValue.h182
-rw-r--r--lib/CodeGen/CodeGenABITypes.cpp41
-rw-r--r--lib/CodeGen/CodeGenAction.cpp245
-rw-r--r--lib/CodeGen/CodeGenFunction.cpp312
-rw-r--r--lib/CodeGen/CodeGenFunction.h750
-rw-r--r--lib/CodeGen/CodeGenModule.cpp687
-rw-r--r--lib/CodeGen/CodeGenModule.h299
-rw-r--r--lib/CodeGen/CodeGenPGO.cpp81
-rw-r--r--lib/CodeGen/CodeGenPGO.h6
-rw-r--r--lib/CodeGen/CodeGenTBAA.cpp2
-rw-r--r--lib/CodeGen/CodeGenTypeCache.h108
-rw-r--r--lib/CodeGen/CodeGenTypes.cpp151
-rw-r--r--lib/CodeGen/CodeGenTypes.h21
-rw-r--r--lib/CodeGen/CoverageMappingGen.cpp67
-rw-r--r--lib/CodeGen/EHScopeStack.h29
-rw-r--r--lib/CodeGen/ItaniumCXXABI.cpp687
-rw-r--r--lib/CodeGen/MicrosoftCXXABI.cpp645
-rw-r--r--lib/CodeGen/ModuleBuilder.cpp15
-rw-r--r--lib/CodeGen/ObjectFilePCHContainerOperations.cpp153
-rw-r--r--lib/CodeGen/TargetInfo.cpp2022
-rw-r--r--lib/CodeGen/TargetInfo.h6
-rw-r--r--lib/Driver/Action.cpp16
-rw-r--r--lib/Driver/Compilation.cpp5
-rw-r--r--lib/Driver/CrossWindowsToolChain.cpp6
-rw-r--r--lib/Driver/Driver.cpp367
-rw-r--r--lib/Driver/DriverOptions.cpp2
-rw-r--r--lib/Driver/Job.cpp32
-rw-r--r--lib/Driver/MSVCToolChain.cpp324
-rw-r--r--lib/Driver/MinGWToolChain.cpp16
-rw-r--r--lib/Driver/Multilib.cpp5
-rw-r--r--lib/Driver/SanitizerArgs.cpp67
-rw-r--r--lib/Driver/ToolChain.cpp233
-rw-r--r--lib/Driver/ToolChains.cpp1582
-rw-r--r--lib/Driver/ToolChains.h342
-rw-r--r--lib/Driver/Tools.cpp3351
-rw-r--r--lib/Driver/Tools.h919
-rw-r--r--lib/Driver/Types.cpp13
-rw-r--r--lib/Edit/Commit.cpp2
-rw-r--r--lib/Edit/EditedSource.cpp82
-rw-r--r--lib/Format/ContinuationIndenter.cpp68
-rw-r--r--lib/Format/Encoding.h2
-rw-r--r--lib/Format/Format.cpp616
-rw-r--r--lib/Format/FormatToken.cpp23
-rw-r--r--lib/Format/FormatToken.h28
-rw-r--r--lib/Format/TokenAnnotator.cpp385
-rw-r--r--lib/Format/TokenAnnotator.h11
-rw-r--r--lib/Format/UnwrappedLineFormatter.cpp41
-rw-r--r--lib/Format/UnwrappedLineParser.cpp126
-rw-r--r--lib/Format/UnwrappedLineParser.h2
-rw-r--r--lib/Format/WhitespaceManager.cpp255
-rw-r--r--lib/Format/WhitespaceManager.h16
-rw-r--r--lib/Frontend/ASTMerge.cpp1
-rw-r--r--lib/Frontend/ASTUnit.cpp134
-rw-r--r--lib/Frontend/CMakeLists.txt2
-rw-r--r--lib/Frontend/CacheTokens.cpp3
-rw-r--r--lib/Frontend/ChainedIncludesSource.cpp20
-rw-r--r--lib/Frontend/CompilerInstance.cpp254
-rw-r--r--lib/Frontend/CompilerInvocation.cpp267
-rw-r--r--lib/Frontend/CreateInvocationFromCommandLine.cpp6
-rw-r--r--lib/Frontend/DependencyFile.cpp77
-rw-r--r--lib/Frontend/DiagnosticRenderer.cpp317
-rw-r--r--lib/Frontend/FrontendAction.cpp18
-rw-r--r--lib/Frontend/FrontendActions.cpp58
-rw-r--r--lib/Frontend/HeaderIncludeGen.cpp64
-rw-r--r--lib/Frontend/InitHeaderSearch.cpp90
-rw-r--r--lib/Frontend/InitPreprocessor.cpp59
-rw-r--r--lib/Frontend/LogDiagnosticPrinter.cpp4
-rw-r--r--lib/Frontend/ModuleDependencyCollector.cpp9
-rw-r--r--lib/Frontend/MultiplexConsumer.cpp10
-rw-r--r--lib/Frontend/PCHContainerOperations.cpp21
-rw-r--r--lib/Frontend/Rewrite/FrontendActions.cpp2
-rw-r--r--lib/Frontend/Rewrite/InclusionRewriter.cpp5
-rw-r--r--lib/Frontend/Rewrite/RewriteModernObjC.cpp69
-rw-r--r--lib/Frontend/Rewrite/RewriteObjC.cpp47
-rw-r--r--lib/Frontend/SerializedDiagnosticPrinter.cpp74
-rw-r--r--lib/Frontend/TestModuleFileExtension.cpp123
-rw-r--r--lib/Frontend/TestModuleFileExtension.h72
-rw-r--r--lib/Frontend/TextDiagnostic.cpp10
-rw-r--r--lib/Frontend/VerifyDiagnosticConsumer.cpp4
-rw-r--r--lib/Headers/CMakeLists.txt14
-rw-r--r--lib/Headers/Intrin.h34
-rw-r--r--lib/Headers/__clang_cuda_runtime_wrapper.h216
-rw-r--r--lib/Headers/__wmmintrin_aes.h10
-rw-r--r--lib/Headers/__wmmintrin_pclmul.h6
-rw-r--r--lib/Headers/adxintrin.h6
-rw-r--r--lib/Headers/altivec.h747
-rw-r--r--lib/Headers/ammintrin.h108
-rw-r--r--lib/Headers/arm_acle.h16
-rw-r--r--lib/Headers/avx2intrin.h451
-rw-r--r--lib/Headers/avx512bwintrin.h390
-rw-r--r--lib/Headers/avx512dqintrin.h538
-rw-r--r--lib/Headers/avx512erintrin.h26
-rw-r--r--lib/Headers/avx512fintrin.h701
-rw-r--r--lib/Headers/avx512vlbwintrin.h433
-rw-r--r--lib/Headers/avx512vldqintrin.h606
-rw-r--r--lib/Headers/avx512vlintrin.h2666
-rw-r--r--lib/Headers/avxintrin.h186
-rw-r--r--lib/Headers/bmi2intrin.h6
-rw-r--r--lib/Headers/bmiintrin.h18
-rw-r--r--lib/Headers/emmintrin.h81
-rw-r--r--lib/Headers/f16cintrin.h26
-rw-r--r--lib/Headers/fma4intrin.h8
-rw-r--r--lib/Headers/fmaintrin.h8
-rw-r--r--lib/Headers/fxsrintrin.h2
-rw-r--r--lib/Headers/htmxlintrin.h2
-rw-r--r--lib/Headers/immintrin.h95
-rw-r--r--lib/Headers/lzcntintrin.h6
-rw-r--r--lib/Headers/mm3dnow.h6
-rw-r--r--lib/Headers/mmintrin.h48
-rw-r--r--lib/Headers/module.modulemap25
-rw-r--r--lib/Headers/nmmintrin.h5
-rw-r--r--lib/Headers/pmmintrin.h10
-rw-r--r--lib/Headers/popcntintrin.h18
-rw-r--r--lib/Headers/prfchwintrin.h6
-rw-r--r--lib/Headers/rdseedintrin.h5
-rw-r--r--lib/Headers/rtmintrin.h2
-rw-r--r--lib/Headers/shaintrin.h8
-rw-r--r--lib/Headers/smmintrin.h181
-rw-r--r--lib/Headers/stdint.h14
-rw-r--r--lib/Headers/tbmintrin.h14
-rw-r--r--lib/Headers/tgmath.h2
-rw-r--r--lib/Headers/tmmintrin.h19
-rw-r--r--lib/Headers/wmmintrin.h9
-rw-r--r--lib/Headers/x86intrin.h24
-rw-r--r--lib/Headers/xmmintrin.h42
-rw-r--r--lib/Headers/xopintrin.h91
-rw-r--r--lib/Headers/xsavecintrin.h48
-rw-r--r--lib/Headers/xsaveintrin.h58
-rw-r--r--lib/Headers/xsaveoptintrin.h48
-rw-r--r--lib/Headers/xsavesintrin.h58
-rw-r--r--lib/Index/CommentToXML.cpp5
-rw-r--r--lib/Index/SimpleFormatContext.h12
-rw-r--r--lib/Index/USRGeneration.cpp13
-rw-r--r--lib/Lex/HeaderSearch.cpp296
-rw-r--r--lib/Lex/Lexer.cpp25
-rw-r--r--lib/Lex/LiteralSupport.cpp45
-rw-r--r--lib/Lex/MacroInfo.cpp14
-rw-r--r--lib/Lex/ModuleMap.cpp191
-rw-r--r--lib/Lex/PPDirectives.cpp90
-rw-r--r--lib/Lex/PPExpressions.cpp6
-rw-r--r--lib/Lex/PPLexerChange.cpp7
-rw-r--r--lib/Lex/PPMacroExpansion.cpp38
-rw-r--r--lib/Lex/Pragma.cpp8
-rw-r--r--lib/Lex/PreprocessingRecord.cpp2
-rw-r--r--lib/Lex/Preprocessor.cpp37
-rw-r--r--lib/Lex/TokenLexer.cpp17
-rw-r--r--lib/Parse/ParseAST.cpp17
-rw-r--r--lib/Parse/ParseCXXInlineMethods.cpp10
-rw-r--r--lib/Parse/ParseDecl.cpp77
-rw-r--r--lib/Parse/ParseDeclCXX.cpp365
-rw-r--r--lib/Parse/ParseExpr.cpp44
-rw-r--r--lib/Parse/ParseExprCXX.cpp55
-rw-r--r--lib/Parse/ParseObjc.cpp102
-rw-r--r--lib/Parse/ParseOpenMP.cpp377
-rw-r--r--lib/Parse/ParsePragma.cpp47
-rw-r--r--lib/Parse/ParseStmt.cpp63
-rw-r--r--lib/Parse/ParseStmtAsm.cpp40
-rw-r--r--lib/Parse/ParseTemplate.cpp13
-rw-r--r--lib/Parse/ParseTentative.cpp3
-rw-r--r--lib/Parse/Parser.cpp86
-rw-r--r--lib/Rewrite/Rewriter.cpp28
-rw-r--r--lib/Sema/AnalysisBasedWarnings.cpp184
-rw-r--r--lib/Sema/AttributeList.cpp31
-rw-r--r--lib/Sema/CMakeLists.txt1
-rw-r--r--lib/Sema/DeclSpec.cpp120
-rw-r--r--lib/Sema/JumpDiagnostics.cpp7
-rw-r--r--lib/Sema/MultiplexExternalSemaSource.cpp12
-rw-r--r--lib/Sema/ScopeInfo.cpp4
-rw-r--r--lib/Sema/Sema.cpp84
-rw-r--r--lib/Sema/SemaAccess.cpp13
-rw-r--r--lib/Sema/SemaCUDA.cpp144
-rw-r--r--lib/Sema/SemaCXXScopeSpec.cpp24
-rw-r--r--lib/Sema/SemaCast.cpp110
-rw-r--r--lib/Sema/SemaChecking.cpp423
-rw-r--r--lib/Sema/SemaCodeComplete.cpp49
-rw-r--r--lib/Sema/SemaCoroutine.cpp448
-rw-r--r--lib/Sema/SemaDecl.cpp1228
-rw-r--r--lib/Sema/SemaDeclAttr.cpp695
-rw-r--r--lib/Sema/SemaDeclCXX.cpp593
-rw-r--r--lib/Sema/SemaDeclObjC.cpp172
-rw-r--r--lib/Sema/SemaExceptionSpec.cpp68
-rw-r--r--lib/Sema/SemaExpr.cpp948
-rw-r--r--lib/Sema/SemaExprCXX.cpp226
-rw-r--r--lib/Sema/SemaExprMember.cpp83
-rw-r--r--lib/Sema/SemaExprObjC.cpp262
-rw-r--r--lib/Sema/SemaFixItUtils.cpp6
-rw-r--r--lib/Sema/SemaInit.cpp76
-rw-r--r--lib/Sema/SemaLambda.cpp115
-rw-r--r--lib/Sema/SemaLookup.cpp329
-rw-r--r--lib/Sema/SemaObjCProperty.cpp743
-rw-r--r--lib/Sema/SemaOpenMP.cpp2746
-rw-r--r--lib/Sema/SemaOverload.cpp810
-rw-r--r--lib/Sema/SemaPseudoObject.cpp323
-rw-r--r--lib/Sema/SemaStmt.cpp191
-rw-r--r--lib/Sema/SemaStmtAsm.cpp224
-rw-r--r--lib/Sema/SemaStmtAttr.cpp75
-rw-r--r--lib/Sema/SemaTemplate.cpp200
-rw-r--r--lib/Sema/SemaTemplateDeduction.cpp129
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp45
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp57
-rw-r--r--lib/Sema/SemaTemplateVariadic.cpp5
-rw-r--r--lib/Sema/SemaType.cpp630
-rw-r--r--lib/Sema/TreeTransform.h732
-rw-r--r--lib/Serialization/ASTCommon.cpp201
-rw-r--r--lib/Serialization/ASTCommon.h2
-rw-r--r--lib/Serialization/ASTReader.cpp2047
-rw-r--r--lib/Serialization/ASTReaderDecl.cpp437
-rw-r--r--lib/Serialization/ASTReaderInternals.h99
-rw-r--r--lib/Serialization/ASTReaderStmt.cpp331
-rw-r--r--lib/Serialization/ASTWriter.cpp1373
-rw-r--r--lib/Serialization/ASTWriterDecl.cpp250
-rw-r--r--lib/Serialization/ASTWriterStmt.cpp219
-rw-r--r--lib/Serialization/CMakeLists.txt1
-rw-r--r--lib/Serialization/GeneratePCH.cpp16
-rw-r--r--lib/Serialization/GlobalModuleIndex.cpp4
-rw-r--r--lib/Serialization/Module.cpp8
-rw-r--r--lib/Serialization/ModuleFileExtension.cpp22
-rw-r--r--lib/Serialization/ModuleManager.cpp122
-rw-r--r--lib/Serialization/MultiOnDiskHashTable.h330
-rw-r--r--lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp12
-rw-r--r--lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp44
-rw-r--r--lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp77
-rw-r--r--lib/StaticAnalyzer/Checkers/BoolAssignmentChecker.cpp46
-rw-r--r--lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp5
-rw-r--r--lib/StaticAnalyzer/Checkers/CMakeLists.txt6
-rw-r--r--lib/StaticAnalyzer/Checkers/CStringChecker.cpp199
-rw-r--r--lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp48
-rw-r--r--lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp7
-rw-r--r--lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp4
-rw-r--r--lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp33
-rw-r--r--lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp4
-rw-r--r--lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp22
-rw-r--r--lib/StaticAnalyzer/Checkers/Checkers.td118
-rw-r--r--lib/StaticAnalyzer/Checkers/ChrootChecker.cpp14
-rw-r--r--lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp71
-rw-r--r--lib/StaticAnalyzer/Checkers/DebugCheckers.cpp36
-rw-r--r--lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp43
-rw-r--r--lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp13
-rw-r--r--lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp4
-rw-r--r--lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp213
-rw-r--r--lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp711
-rw-r--r--lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp62
-rw-r--r--lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp4
-rw-r--r--lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp31
-rw-r--r--lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp25
-rw-r--r--lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp6
-rw-r--r--lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp1
-rw-r--r--lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp1201
-rw-r--r--lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp33
-rw-r--r--lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp4
-rw-r--r--lib/StaticAnalyzer/Checkers/Makefile6
-rw-r--r--lib/StaticAnalyzer/Checkers/MallocChecker.cpp226
-rw-r--r--lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp134
-rw-r--r--lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp8
-rw-r--r--lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp6
-rw-r--r--lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp4
-rw-r--r--lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp7
-rw-r--r--lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp42
-rw-r--r--lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp1066
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp4
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp5
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp4
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp8
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp21
-rw-r--r--lib/StaticAnalyzer/Checkers/PaddingChecker.cpp314
-rw-r--r--lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp6
-rw-r--r--lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp6
-rw-r--r--lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp38
-rw-r--r--lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp132
-rw-r--r--lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp8
-rw-r--r--lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp8
-rw-r--r--lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp45
-rw-r--r--lib/StaticAnalyzer/Checkers/StreamChecker.cpp34
-rw-r--r--lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp6
-rw-r--r--lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp4
-rw-r--r--lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp16
-rw-r--r--lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp4
-rw-r--r--lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp16
-rw-r--r--lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp13
-rw-r--r--lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp10
-rw-r--r--lib/StaticAnalyzer/Checkers/VforkChecker.cpp218
-rw-r--r--lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp24
-rw-r--r--lib/StaticAnalyzer/Core/AnalysisManager.cpp2
-rw-r--r--lib/StaticAnalyzer/Core/AnalyzerOptions.cpp21
-rw-r--r--lib/StaticAnalyzer/Core/BlockCounter.cpp8
-rw-r--r--lib/StaticAnalyzer/Core/BugReporter.cpp110
-rw-r--r--lib/StaticAnalyzer/Core/BugReporterVisitors.cpp74
-rw-r--r--lib/StaticAnalyzer/Core/CMakeLists.txt3
-rw-r--r--lib/StaticAnalyzer/Core/CallEvent.cpp120
-rw-r--r--lib/StaticAnalyzer/Core/Checker.cpp2
-rw-r--r--lib/StaticAnalyzer/Core/CheckerContext.cpp10
-rw-r--r--lib/StaticAnalyzer/Core/CheckerHelpers.cpp24
-rw-r--r--lib/StaticAnalyzer/Core/CheckerManager.cpp60
-rw-r--r--lib/StaticAnalyzer/Core/CheckerRegistry.cpp2
-rw-r--r--lib/StaticAnalyzer/Core/ConstraintManager.cpp2
-rw-r--r--lib/StaticAnalyzer/Core/CoreEngine.cpp8
-rw-r--r--lib/StaticAnalyzer/Core/DynamicTypeMap.cpp51
-rw-r--r--lib/StaticAnalyzer/Core/Environment.cpp17
-rw-r--r--lib/StaticAnalyzer/Core/ExplodedGraph.cpp10
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngine.cpp221
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineC.cpp207
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineCXX.cpp188
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp42
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineObjC.cpp119
-rw-r--r--lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp33
-rw-r--r--lib/StaticAnalyzer/Core/IssueHash.cpp196
-rw-r--r--lib/StaticAnalyzer/Core/LoopWidening.cpp68
-rw-r--r--lib/StaticAnalyzer/Core/Makefile6
-rw-r--r--lib/StaticAnalyzer/Core/MemRegion.cpp67
-rw-r--r--lib/StaticAnalyzer/Core/PathDiagnostic.cpp40
-rw-r--r--lib/StaticAnalyzer/Core/PlistDiagnostics.cpp53
-rw-r--r--lib/StaticAnalyzer/Core/ProgramState.cpp75
-rw-r--r--lib/StaticAnalyzer/Core/RangeConstraintManager.cpp188
-rw-r--r--lib/StaticAnalyzer/Core/RegionStore.cpp244
-rw-r--r--lib/StaticAnalyzer/Core/SValBuilder.cpp46
-rw-r--r--lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp67
-rw-r--r--lib/StaticAnalyzer/Core/SimpleConstraintManager.h21
-rw-r--r--lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp11
-rw-r--r--lib/StaticAnalyzer/Core/Store.cpp14
-rw-r--r--lib/StaticAnalyzer/Core/SymbolManager.cpp26
-rw-r--r--lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp29
-rw-r--r--lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp14
-rw-r--r--lib/StaticAnalyzer/Frontend/Makefile4
-rw-r--r--lib/Tooling/ArgumentsAdjusters.cpp12
-rw-r--r--lib/Tooling/CommonOptionsParser.cpp24
-rw-r--r--lib/Tooling/CompilationDatabase.cpp6
-rw-r--r--lib/Tooling/Core/CMakeLists.txt2
-rw-r--r--lib/Tooling/Core/Lookup.cpp113
-rw-r--r--lib/Tooling/Core/Replacement.cpp198
-rw-r--r--lib/Tooling/JSONCompilationDatabase.cpp93
-rw-r--r--lib/Tooling/Tooling.cpp115
464 files changed, 58105 insertions, 27257 deletions
diff --git a/lib/ARCMigrate/ARCMT.cpp b/lib/ARCMigrate/ARCMT.cpp
index e32884218597..8c04c8371cef 100644
--- a/lib/ARCMigrate/ARCMT.cpp
+++ b/lib/ARCMigrate/ARCMT.cpp
@@ -153,6 +153,9 @@ static bool HasARCRuntime(CompilerInvocation &origCI) {
if (triple.isiOS())
return triple.getOSMajorVersion() >= 5;
+ if (triple.isWatchOS())
+ return true;
+
if (triple.getOS() == llvm::Triple::Darwin)
return triple.getOSMajorVersion() >= 11;
@@ -206,7 +209,8 @@ createInvocationForMigration(CompilerInvocation &origCI,
WarnOpts.push_back("error=arc-unsafe-retained-assign");
CInvok->getDiagnosticOpts().Warnings = std::move(WarnOpts);
- CInvok->getLangOpts()->ObjCARCWeak = HasARCRuntime(origCI);
+ CInvok->getLangOpts()->ObjCWeakRuntime = HasARCRuntime(origCI);
+ CInvok->getLangOpts()->ObjCWeak = CInvok->getLangOpts()->ObjCWeakRuntime;
return CInvok.release();
}
@@ -600,7 +604,6 @@ bool MigrationProcess::applyTransform(TransformFn trans,
SmallString<512> newText;
llvm::raw_svector_ostream vecOS(newText);
buf.write(vecOS);
- vecOS.flush();
std::unique_ptr<llvm::MemoryBuffer> memBuf(
llvm::MemoryBuffer::getMemBufferCopy(
StringRef(newText.data(), newText.size()), newFname));
diff --git a/lib/ARCMigrate/FileRemapper.cpp b/lib/ARCMigrate/FileRemapper.cpp
index 72a55da5d50b..2cf20699aeef 100644
--- a/lib/ARCMigrate/FileRemapper.cpp
+++ b/lib/ARCMigrate/FileRemapper.cpp
@@ -144,7 +144,7 @@ bool FileRemapper::flushToFile(StringRef outputPath, DiagnosticsEngine &Diag) {
SmallString<64> tempPath;
int fd;
if (fs::createTemporaryFile(path::filename(origFE->getName()),
- path::extension(origFE->getName()), fd,
+ path::extension(origFE->getName()).drop_front(), fd,
tempPath))
return report("Could not create file: " + tempPath.str(), Diag);
diff --git a/lib/ARCMigrate/ObjCMT.cpp b/lib/ARCMigrate/ObjCMT.cpp
index b61a421ce415..50b113660d3a 100644
--- a/lib/ARCMigrate/ObjCMT.cpp
+++ b/lib/ARCMigrate/ObjCMT.cpp
@@ -214,25 +214,15 @@ namespace {
// FIXME. This duplicates one in RewriteObjCFoundationAPI.cpp
bool subscriptOperatorNeedsParens(const Expr *FullExpr) {
const Expr* Expr = FullExpr->IgnoreImpCasts();
- if (isa<ArraySubscriptExpr>(Expr) ||
- isa<CallExpr>(Expr) ||
- isa<DeclRefExpr>(Expr) ||
- isa<CXXNamedCastExpr>(Expr) ||
- isa<CXXConstructExpr>(Expr) ||
- isa<CXXThisExpr>(Expr) ||
- isa<CXXTypeidExpr>(Expr) ||
- isa<CXXUnresolvedConstructExpr>(Expr) ||
- isa<ObjCMessageExpr>(Expr) ||
- isa<ObjCPropertyRefExpr>(Expr) ||
- isa<ObjCProtocolExpr>(Expr) ||
- isa<MemberExpr>(Expr) ||
- isa<ObjCIvarRefExpr>(Expr) ||
- isa<ParenExpr>(FullExpr) ||
- isa<ParenListExpr>(Expr) ||
- isa<SizeOfPackExpr>(Expr))
- return false;
-
- return true;
+ return !(isa<ArraySubscriptExpr>(Expr) || isa<CallExpr>(Expr) ||
+ isa<DeclRefExpr>(Expr) || isa<CXXNamedCastExpr>(Expr) ||
+ isa<CXXConstructExpr>(Expr) || isa<CXXThisExpr>(Expr) ||
+ isa<CXXTypeidExpr>(Expr) ||
+ isa<CXXUnresolvedConstructExpr>(Expr) ||
+ isa<ObjCMessageExpr>(Expr) || isa<ObjCPropertyRefExpr>(Expr) ||
+ isa<ObjCProtocolExpr>(Expr) || isa<MemberExpr>(Expr) ||
+ isa<ObjCIvarRefExpr>(Expr) || isa<ParenExpr>(FullExpr) ||
+ isa<ParenListExpr>(Expr) || isa<SizeOfPackExpr>(Expr));
}
/// \brief - Rewrite message expression for Objective-C setter and getters into
@@ -665,9 +655,7 @@ ClassImplementsAllMethodsAndProperties(ASTContext &Ctx,
return false;
}
}
- if (HasAtleastOneRequiredProperty || HasAtleastOneRequiredMethod)
- return true;
- return false;
+ return HasAtleastOneRequiredProperty || HasAtleastOneRequiredMethod;
}
static bool rewriteToObjCInterfaceDecl(const ObjCInterfaceDecl *IDecl,
@@ -736,7 +724,7 @@ static bool rewriteToNSEnumDecl(const EnumDecl *EnumDcl,
SourceLocation EndOfEnumDclLoc = EnumDcl->getLocEnd();
EndOfEnumDclLoc = trans::findSemiAfterLocation(EndOfEnumDclLoc,
NS.getASTContext(), /*IsDecl*/true);
- if (!EndOfEnumDclLoc.isInvalid()) {
+ if (EndOfEnumDclLoc.isValid()) {
SourceRange EnumDclRange(EnumDcl->getLocStart(), EndOfEnumDclLoc);
commit.insertFromRange(TypedefDcl->getLocStart(), EnumDclRange);
}
@@ -746,7 +734,7 @@ static bool rewriteToNSEnumDecl(const EnumDecl *EnumDcl,
SourceLocation EndTypedefDclLoc = TypedefDcl->getLocEnd();
EndTypedefDclLoc = trans::findSemiAfterLocation(EndTypedefDclLoc,
NS.getASTContext(), /*IsDecl*/true);
- if (!EndTypedefDclLoc.isInvalid()) {
+ if (EndTypedefDclLoc.isValid()) {
SourceRange TDRange(TypedefDcl->getLocStart(), EndTypedefDclLoc);
commit.remove(TDRange);
}
@@ -755,7 +743,7 @@ static bool rewriteToNSEnumDecl(const EnumDecl *EnumDcl,
EndOfEnumDclLoc = trans::findLocationAfterSemi(EnumDcl->getLocEnd(), NS.getASTContext(),
/*IsDecl*/true);
- if (!EndOfEnumDclLoc.isInvalid()) {
+ if (EndOfEnumDclLoc.isValid()) {
SourceLocation BeginOfEnumDclLoc = EnumDcl->getLocStart();
// FIXME. This assumes that enum decl; is immediately preceded by eoln.
// It is trying to remove the enum decl. lines entirely.
@@ -1536,7 +1524,7 @@ ObjCMigrateASTConsumer::CF_BRIDGING_KIND
FuncDecl->hasAttr<NSReturnsNotRetainedAttr>() ||
FuncDecl->hasAttr<NSReturnsAutoreleasedAttr>());
- // Trivial case of when funciton is annotated and has no argument.
+ // Trivial case of when function is annotated and has no argument.
if (FuncIsReturnAnnotated && FuncDecl->getNumParams() == 0)
return CF_BRIDGING_NONE;
@@ -1665,7 +1653,7 @@ void ObjCMigrateASTConsumer::migrateAddMethodAnnotation(
Editor->commit(commit);
}
- // Trivial case of when funciton is annotated and has no argument.
+ // Trivial case of when function is annotated and has no argument.
if (MethodIsReturnAnnotated &&
(MethodDecl->param_begin() == MethodDecl->param_end()))
return;
@@ -1805,7 +1793,7 @@ private:
FileID FID;
unsigned Offset;
std::tie(FID, Offset) = SourceMgr.getDecomposedLoc(Loc);
- assert(!FID.isInvalid());
+ assert(FID.isValid());
SmallString<200> Path =
StringRef(SourceMgr.getFileEntryForID(FID)->getName());
llvm::sys::fs::make_absolute(Path);
@@ -1862,8 +1850,8 @@ void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) {
for (DeclContext::decl_iterator D = TU->decls_begin(), DEnd = TU->decls_end();
D != DEnd; ++D) {
FileID FID = PP.getSourceManager().getFileID((*D)->getLocation());
- if (!FID.isInvalid())
- if (!FileId.isInvalid() && FileId != FID) {
+ if (FID.isValid())
+ if (FileId.isValid() && FileId != FID) {
if (ASTMigrateActions & FrontendOptions::ObjCMT_Annotation)
AnnotateImplicitBridging(Ctx);
}
@@ -1982,7 +1970,6 @@ void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) {
SmallString<512> newText;
llvm::raw_svector_ostream vecOS(newText);
buf.write(vecOS);
- vecOS.flush();
std::unique_ptr<llvm::MemoryBuffer> memBuf(
llvm::MemoryBuffer::getMemBufferCopy(
StringRef(newText.data(), newText.size()), file->getName()));
@@ -2215,12 +2202,11 @@ static std::string applyEditsToTemp(const FileEntry *FE,
SmallString<512> NewText;
llvm::raw_svector_ostream OS(NewText);
Buf->write(OS);
- OS.flush();
SmallString<64> TempPath;
int FD;
if (fs::createTemporaryFile(path::filename(FE->getName()),
- path::extension(FE->getName()), FD,
+ path::extension(FE->getName()).drop_front(), FD,
TempPath)) {
reportDiag("Could not create file: " + TempPath.str(), Diag);
return std::string();
diff --git a/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp b/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp
index 9689f40760cd..d45d5d60b78a 100644
--- a/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp
+++ b/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp
@@ -104,9 +104,7 @@ public:
return false;
if (!S->getThen() || !Visit(S->getThen()))
return false;
- if (S->getElse() && !Visit(S->getElse()))
- return false;
- return true;
+ return !S->getElse() || Visit(S->getElse());
}
bool VisitWhileStmt(WhileStmt *S) {
if (S->getConditionVariable())
diff --git a/lib/ARCMigrate/TransGCAttrs.cpp b/lib/ARCMigrate/TransGCAttrs.cpp
index 10fce19b6f19..2ae6b78a4634 100644
--- a/lib/ARCMigrate/TransGCAttrs.cpp
+++ b/lib/ARCMigrate/TransGCAttrs.cpp
@@ -152,9 +152,7 @@ public:
return ID->getImplementation() != nullptr;
if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(ContD))
return CD->getImplementation() != nullptr;
- if (isa<ObjCImplDecl>(ContD))
- return true;
- return false;
+ return isa<ObjCImplDecl>(ContD);
}
return false;
}
diff --git a/lib/ARCMigrate/TransProperties.cpp b/lib/ARCMigrate/TransProperties.cpp
index ab128844b45f..8667bc2a37da 100644
--- a/lib/ARCMigrate/TransProperties.cpp
+++ b/lib/ARCMigrate/TransProperties.cpp
@@ -96,6 +96,10 @@ public:
collectProperties(iface, AtProps);
+ // Look through extensions.
+ for (auto *Ext : iface->visible_extensions())
+ collectProperties(Ext, AtProps);
+
typedef DeclContext::specific_decl_iterator<ObjCPropertyImplDecl>
prop_impl_iterator;
for (prop_impl_iterator
@@ -137,19 +141,6 @@ public:
Transaction Trans(Pass.TA);
rewriteProperty(props, atLoc);
}
-
- AtPropDeclsTy AtExtProps;
- // Look through extensions.
- for (auto *Ext : iface->visible_extensions())
- collectProperties(Ext, AtExtProps, &AtProps);
-
- for (AtPropDeclsTy::iterator
- I = AtExtProps.begin(), E = AtExtProps.end(); I != E; ++I) {
- SourceLocation atLoc = SourceLocation::getFromRawEncoding(I->first);
- PropsTy &props = I->second;
- Transaction Trans(Pass.TA);
- doActionForExtensionProp(props, atLoc);
- }
}
private:
@@ -177,15 +168,6 @@ private:
}
}
- void doActionForExtensionProp(PropsTy &props, SourceLocation atLoc) {
- llvm::DenseMap<IdentifierInfo *, PropActionKind>::iterator I;
- I = ActionOnProp.find(props[0].PropD->getIdentifier());
- if (I == ActionOnProp.end())
- return;
-
- doPropAction(I->second, props, atLoc, false);
- }
-
void rewriteProperty(PropsTy &props, SourceLocation atLoc) {
ObjCPropertyDecl::PropertyAttributeKind propAttrs = getPropertyAttrs(props);
diff --git a/lib/ARCMigrate/TransRetainReleaseDealloc.cpp b/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
index 7db1a1c378cc..f81133f3aad3 100644
--- a/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
+++ b/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
@@ -150,11 +150,8 @@ public:
return true;
}
- if (!hasSideEffects(rec, Pass.Ctx)) {
- if (tryRemoving(RecContainer))
- return true;
- }
- Pass.TA.replace(RecContainer->getSourceRange(), RecRange);
+ if (hasSideEffects(rec, Pass.Ctx) || !tryRemoving(RecContainer))
+ Pass.TA.replace(RecContainer->getSourceRange(), RecRange);
return true;
}
@@ -174,11 +171,8 @@ private:
/// return var;
///
bool isCommonUnusedAutorelease(ObjCMessageExpr *E) {
- if (isPlusOneAssignBeforeOrAfterAutorelease(E))
- return true;
- if (isReturnedAfterAutorelease(E))
- return true;
- return false;
+ return isPlusOneAssignBeforeOrAfterAutorelease(E) ||
+ isReturnedAfterAutorelease(E);
}
bool isReturnedAfterAutorelease(ObjCMessageExpr *E) {
@@ -225,11 +219,7 @@ private:
// Check for "RefD = [+1 retained object];".
if (BinaryOperator *Bop = dyn_cast<BinaryOperator>(S)) {
- if (RefD != getReferencedDecl(Bop->getLHS()))
- return false;
- if (isPlusOneAssign(Bop))
- return true;
- return false;
+ return (RefD == getReferencedDecl(Bop->getLHS())) && isPlusOneAssign(Bop);
}
if (DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
@@ -359,16 +349,16 @@ private:
return;
Stmt::child_range StmtExprChild = StmtE->children();
- if (!StmtExprChild)
+ if (StmtExprChild.begin() == StmtExprChild.end())
return;
- CompoundStmt *CompS = dyn_cast_or_null<CompoundStmt>(*StmtExprChild);
+ auto *CompS = dyn_cast_or_null<CompoundStmt>(*StmtExprChild.begin());
if (!CompS)
return;
Stmt::child_range CompStmtChild = CompS->children();
- if (!CompStmtChild)
+ if (CompStmtChild.begin() == CompStmtChild.end())
return;
- DeclStmt *DeclS = dyn_cast_or_null<DeclStmt>(*CompStmtChild);
+ auto *DeclS = dyn_cast_or_null<DeclStmt>(*CompStmtChild.begin());
if (!DeclS)
return;
if (!DeclS->isSingleDecl())
diff --git a/lib/ARCMigrate/TransformActions.cpp b/lib/ARCMigrate/TransformActions.cpp
index 9fb2f1d3eea8..c628b54ed414 100644
--- a/lib/ARCMigrate/TransformActions.cpp
+++ b/lib/ARCMigrate/TransformActions.cpp
@@ -505,11 +505,10 @@ void TransformActionsImpl::commitClearDiagnostic(ArrayRef<unsigned> IDs,
void TransformActionsImpl::addInsertion(SourceLocation loc, StringRef text) {
SourceManager &SM = Ctx.getSourceManager();
loc = SM.getExpansionLoc(loc);
- for (std::list<CharRange>::reverse_iterator
- I = Removals.rbegin(), E = Removals.rend(); I != E; ++I) {
- if (!SM.isBeforeInTranslationUnit(loc, I->End))
+ for (const CharRange &I : llvm::reverse(Removals)) {
+ if (!SM.isBeforeInTranslationUnit(loc, I.End))
break;
- if (I->Begin.isBeforeInTranslationUnitThan(loc))
+ if (I.Begin.isBeforeInTranslationUnitThan(loc))
return;
}
diff --git a/lib/ARCMigrate/Transforms.cpp b/lib/ARCMigrate/Transforms.cpp
index 56d3af7233bf..3fd36ff310f3 100644
--- a/lib/ARCMigrate/Transforms.cpp
+++ b/lib/ARCMigrate/Transforms.cpp
@@ -42,7 +42,7 @@ bool MigrationPass::CFBridgingFunctionsDefined() {
bool trans::canApplyWeak(ASTContext &Ctx, QualType type,
bool AllowOnUnknownClass) {
- if (!Ctx.getLangOpts().ObjCARCWeak)
+ if (!Ctx.getLangOpts().ObjCWeakRuntime)
return false;
QualType T = type;
@@ -50,7 +50,8 @@ bool trans::canApplyWeak(ASTContext &Ctx, QualType type,
return false;
// iOS is always safe to use 'weak'.
- if (Ctx.getTargetInfo().getTriple().isiOS())
+ if (Ctx.getTargetInfo().getTriple().isiOS() ||
+ Ctx.getTargetInfo().getTriple().isWatchOS())
AllowOnUnknownClass = true;
while (const PointerType *ptr = T->getAs<PointerType>())
@@ -112,10 +113,7 @@ bool trans::isPlusOne(const Expr *E) {
while (implCE && implCE->getCastKind() == CK_BitCast)
implCE = dyn_cast<ImplicitCastExpr>(implCE->getSubExpr());
- if (implCE && implCE->getCastKind() == CK_ARCConsumeObject)
- return true;
-
- return false;
+ return implCE && implCE->getCastKind() == CK_ARCConsumeObject;
}
/// \brief 'Loc' is the end of a statement range. This returns the location
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index fb9630180dca..108677abb8a4 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -19,6 +19,7 @@
#include "clang/AST/Comment.h"
#include "clang/AST/CommentCommandTraits.h"
#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclContextInternals.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
@@ -327,7 +328,7 @@ const Decl *adjustDeclToTemplate(const Decl *D) {
// FIXME: Adjust alias templates?
return D;
}
-} // unnamed namespace
+} // anonymous namespace
const RawComment *ASTContext::getRawCommentForAnyRedecl(
const Decl *D,
@@ -366,8 +367,10 @@ const RawComment *ASTContext::getRawCommentForAnyRedecl(
OriginalDeclForRC = I;
RawCommentAndCacheFlags Raw;
if (RC) {
- Raw.setRaw(RC);
+ // Call order swapped to work around ICE in VS2015 RTM (Release Win32)
+ // https://connect.microsoft.com/VisualStudio/feedback/details/1741530
Raw.setKind(RawCommentAndCacheFlags::FromDecl);
+ Raw.setRaw(RC);
} else
Raw.setKind(RawCommentAndCacheFlags::NoCommentInDecl);
Raw.setOriginalDecl(I);
@@ -428,7 +431,6 @@ comments::FullComment *ASTContext::cloneFullComment(comments::FullComment *FC,
new (*this) comments::FullComment(FC->getBlocks(),
ThisDeclInfo);
return CFC;
-
}
comments::FullComment *ASTContext::getLocalCommentForDeclUncached(const Decl *D) const {
@@ -659,8 +661,7 @@ ASTContext::getCanonicalTemplateTemplateParmDecl(
nullptr,
TemplateParameterList::Create(*this, SourceLocation(),
SourceLocation(),
- CanonParams.data(),
- CanonParams.size(),
+ CanonParams,
SourceLocation()));
// Get the new insert position for the node we care about.
@@ -681,9 +682,11 @@ CXXABI *ASTContext::createCXXABI(const TargetInfo &T) {
case TargetCXXABI::GenericARM: // Same as Itanium at this level
case TargetCXXABI::iOS:
case TargetCXXABI::iOS64:
+ case TargetCXXABI::WatchOS:
case TargetCXXABI::GenericAArch64:
case TargetCXXABI::GenericMIPS:
case TargetCXXABI::GenericItanium:
+ case TargetCXXABI::WebAssembly:
return CreateItaniumCXXABI(*this);
case TargetCXXABI::Microsoft:
return CreateMicrosoftCXXABI(*this);
@@ -732,19 +735,20 @@ ASTContext::ASTContext(LangOptions &LOpts, SourceManager &SM,
SubstTemplateTemplateParmPacks(this_()),
GlobalNestedNameSpecifier(nullptr), Int128Decl(nullptr),
UInt128Decl(nullptr), Float128StubDecl(nullptr),
- BuiltinVaListDecl(nullptr), ObjCIdDecl(nullptr), ObjCSelDecl(nullptr),
- ObjCClassDecl(nullptr), ObjCProtocolClassDecl(nullptr), BOOLDecl(nullptr),
+ BuiltinVaListDecl(nullptr), BuiltinMSVaListDecl(nullptr),
+ ObjCIdDecl(nullptr), ObjCSelDecl(nullptr), ObjCClassDecl(nullptr),
+ ObjCProtocolClassDecl(nullptr), BOOLDecl(nullptr),
CFConstantStringTypeDecl(nullptr), ObjCInstanceTypeDecl(nullptr),
FILEDecl(nullptr), jmp_bufDecl(nullptr), sigjmp_bufDecl(nullptr),
ucontext_tDecl(nullptr), BlockDescriptorType(nullptr),
BlockDescriptorExtendedType(nullptr), cudaConfigureCallDecl(nullptr),
FirstLocalImport(), LastLocalImport(), ExternCContext(nullptr),
- SourceMgr(SM), LangOpts(LOpts),
+ MakeIntegerSeqDecl(nullptr), SourceMgr(SM), LangOpts(LOpts),
SanitizerBL(new SanitizerBlacklist(LangOpts.SanitizerBlacklistFiles, SM)),
- AddrSpaceMap(nullptr), Target(nullptr), PrintingPolicy(LOpts),
- Idents(idents), Selectors(sels), BuiltinInfo(builtins),
- DeclarationNames(*this), ExternalSource(nullptr), Listener(nullptr),
- Comments(SM), CommentsLoaded(false),
+ AddrSpaceMap(nullptr), Target(nullptr), AuxTarget(nullptr),
+ PrintingPolicy(LOpts), Idents(idents), Selectors(sels),
+ BuiltinInfo(builtins), DeclarationNames(*this), ExternalSource(nullptr),
+ Listener(nullptr), Comments(SM), CommentsLoaded(false),
CommentCommandTraits(BumpAlloc, LOpts.CommentOpts), LastSDM(nullptr, 0) {
TUDecl = TranslationUnitDecl::Create(*this);
}
@@ -757,10 +761,8 @@ ASTContext::~ASTContext() {
ReleaseDeclContextMaps();
// Call all of the deallocation functions on all of their targets.
- for (DeallocationMap::const_iterator I = Deallocations.begin(),
- E = Deallocations.end(); I != E; ++I)
- for (unsigned J = 0, N = I->second.size(); J != N; ++J)
- (I->first)((I->second)[J]);
+ for (auto &Pair : Deallocations)
+ (Pair.first)(Pair.second);
// ASTRecordLayout objects in ASTRecordLayouts must always be destroyed
// because they can contain DenseMaps.
@@ -783,23 +785,33 @@ ASTContext::~ASTContext() {
A != AEnd; ++A)
A->second->~AttrVec();
+ for (std::pair<const MaterializeTemporaryExpr *, APValue *> &MTVPair :
+ MaterializedTemporaryValues)
+ MTVPair.second->~APValue();
+
llvm::DeleteContainerSeconds(MangleNumberingContexts);
}
void ASTContext::ReleaseParentMapEntries() {
- if (!AllParents) return;
- for (const auto &Entry : *AllParents) {
+ if (!PointerParents) return;
+ for (const auto &Entry : *PointerParents) {
if (Entry.second.is<ast_type_traits::DynTypedNode *>()) {
delete Entry.second.get<ast_type_traits::DynTypedNode *>();
- } else {
- assert(Entry.second.is<ParentVector *>());
+ } else if (Entry.second.is<ParentVector *>()) {
+ delete Entry.second.get<ParentVector *>();
+ }
+ }
+ for (const auto &Entry : *OtherParents) {
+ if (Entry.second.is<ast_type_traits::DynTypedNode *>()) {
+ delete Entry.second.get<ast_type_traits::DynTypedNode *>();
+ } else if (Entry.second.is<ParentVector *>()) {
delete Entry.second.get<ParentVector *>();
}
}
}
void ASTContext::AddDeallocation(void (*Callback)(void*), void *Data) {
- Deallocations[Callback].push_back(Data);
+ Deallocations.push_back({Callback, Data});
}
void
@@ -898,6 +910,24 @@ ExternCContextDecl *ASTContext::getExternCContextDecl() const {
return ExternCContext;
}
+BuiltinTemplateDecl *
+ASTContext::buildBuiltinTemplateDecl(BuiltinTemplateKind BTK,
+ const IdentifierInfo *II) const {
+ auto *BuiltinTemplate = BuiltinTemplateDecl::Create(*this, TUDecl, II, BTK);
+ BuiltinTemplate->setImplicit();
+ TUDecl->addDecl(BuiltinTemplate);
+
+ return BuiltinTemplate;
+}
+
+BuiltinTemplateDecl *
+ASTContext::getMakeIntegerSeqDecl() const {
+ if (!MakeIntegerSeqDecl)
+ MakeIntegerSeqDecl = buildBuiltinTemplateDecl(BTK__make_integer_seq,
+ getMakeIntegerSeqName());
+ return MakeIntegerSeqDecl;
+}
+
RecordDecl *ASTContext::buildImplicitRecord(StringRef Name,
RecordDecl::TagKind TK) const {
SourceLocation Loc;
@@ -950,13 +980,15 @@ void ASTContext::InitBuiltinType(CanQualType &R, BuiltinType::Kind K) {
Types.push_back(Ty);
}
-void ASTContext::InitBuiltinTypes(const TargetInfo &Target) {
+void ASTContext::InitBuiltinTypes(const TargetInfo &Target,
+ const TargetInfo *AuxTarget) {
assert((!this->Target || this->Target == &Target) &&
"Incorrect target reinitialization");
assert(VoidTy.isNull() && "Context reinitialized?");
this->Target = &Target;
-
+ this->AuxTarget = AuxTarget;
+
ABI.reset(createCXXABI(Target));
AddrSpaceMap = getAddressSpaceMap(Target, LangOpts);
AddrSpaceMapMangling = isAddrSpaceMapManglingEnabled(Target, LangOpts);
@@ -1043,6 +1075,10 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target) {
// Placeholder type for builtin functions.
InitBuiltinType(BuiltinFnTy, BuiltinType::BuiltinFn);
+ // Placeholder type for OMP array sections.
+ if (LangOpts.OpenMP)
+ InitBuiltinType(OMPArraySectionTy, BuiltinType::OMPArraySection);
+
// C99 6.2.5p11.
FloatComplexTy = getComplexType(FloatTy);
DoubleComplexTy = getComplexType(DoubleTy);
@@ -1059,10 +1095,21 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target) {
InitBuiltinType(OCLImage1dBufferTy, BuiltinType::OCLImage1dBuffer);
InitBuiltinType(OCLImage2dTy, BuiltinType::OCLImage2d);
InitBuiltinType(OCLImage2dArrayTy, BuiltinType::OCLImage2dArray);
+ InitBuiltinType(OCLImage2dDepthTy, BuiltinType::OCLImage2dDepth);
+ InitBuiltinType(OCLImage2dArrayDepthTy, BuiltinType::OCLImage2dArrayDepth);
+ InitBuiltinType(OCLImage2dMSAATy, BuiltinType::OCLImage2dMSAA);
+ InitBuiltinType(OCLImage2dArrayMSAATy, BuiltinType::OCLImage2dArrayMSAA);
+ InitBuiltinType(OCLImage2dMSAADepthTy, BuiltinType::OCLImage2dMSAADepth);
+ InitBuiltinType(OCLImage2dArrayMSAADepthTy,
+ BuiltinType::OCLImage2dArrayMSAADepth);
InitBuiltinType(OCLImage3dTy, BuiltinType::OCLImage3d);
InitBuiltinType(OCLSamplerTy, BuiltinType::OCLSampler);
InitBuiltinType(OCLEventTy, BuiltinType::OCLEvent);
+ InitBuiltinType(OCLClkEventTy, BuiltinType::OCLClkEvent);
+ InitBuiltinType(OCLQueueTy, BuiltinType::OCLQueue);
+ InitBuiltinType(OCLNDRangeTy, BuiltinType::OCLNDRange);
+ InitBuiltinType(OCLReserveIDTy, BuiltinType::OCLReserveID);
}
// Builtin type for __objc_yes and __objc_no
@@ -1083,7 +1130,7 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target) {
InitBuiltinType(HalfTy, BuiltinType::Half);
// Builtin type used to help define __builtin_va_list.
- VaListTagTy = QualType();
+ VaListTagDecl = nullptr;
}
DiagnosticsEngine &ASTContext::getDiagnostics() const {
@@ -1629,11 +1676,21 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
Align = Target->getIntAlign();
break;
case BuiltinType::OCLEvent:
+ case BuiltinType::OCLClkEvent:
+ case BuiltinType::OCLQueue:
+ case BuiltinType::OCLNDRange:
+ case BuiltinType::OCLReserveID:
case BuiltinType::OCLImage1d:
case BuiltinType::OCLImage1dArray:
case BuiltinType::OCLImage1dBuffer:
case BuiltinType::OCLImage2d:
case BuiltinType::OCLImage2dArray:
+ case BuiltinType::OCLImage2dDepth:
+ case BuiltinType::OCLImage2dArrayDepth:
+ case BuiltinType::OCLImage2dMSAA:
+ case BuiltinType::OCLImage2dArrayMSAA:
+ case BuiltinType::OCLImage2dMSAADepth:
+ case BuiltinType::OCLImage2dArrayMSAADepth:
case BuiltinType::OCLImage3d:
// Currently these types are pointers to opaque types.
Width = Target->getPointerWidth(0);
@@ -1861,7 +1918,7 @@ unsigned ASTContext::getPreferredTypeAlign(const Type *T) const {
/// getTargetDefaultAlignForAttributeAligned - Return the default alignment
/// for __attribute__((aligned)) on this target, to be used if no alignment
/// value is specified.
-unsigned ASTContext::getTargetDefaultAlignForAttributeAligned(void) const {
+unsigned ASTContext::getTargetDefaultAlignForAttributeAligned() const {
return getTargetInfo().getDefaultAlignForAttributeAligned();
}
@@ -2006,6 +2063,17 @@ void ASTContext::setObjCImplementation(ObjCCategoryDecl *CatD,
ObjCImpls[CatD] = ImplD;
}
+const ObjCMethodDecl *
+ASTContext::getObjCMethodRedeclaration(const ObjCMethodDecl *MD) const {
+ return ObjCMethodRedecls.lookup(MD);
+}
+
+void ASTContext::setObjCMethodRedeclaration(const ObjCMethodDecl *MD,
+ const ObjCMethodDecl *Redecl) {
+ assert(!getObjCMethodRedeclaration(MD) && "MD already has a redeclaration");
+ ObjCMethodRedecls[MD] = Redecl;
+}
+
const ObjCInterfaceDecl *ASTContext::getObjContainingInterface(
const NamedDecl *ND) const {
if (const ObjCInterfaceDecl *ID =
@@ -2759,9 +2827,10 @@ QualType ASTContext::getDependentSizedArrayType(QualType elementType,
QualType canon = getQualifiedType(QualType(canonTy,0),
canonElementType.Quals);
- // If we didn't need extra canonicalization for the element type,
- // then just use that as our result.
- if (QualType(canonElementType.Ty, 0) == elementType)
+ // If we didn't need extra canonicalization for the element type or the size
+ // expression, then just use that as our result.
+ if (QualType(canonElementType.Ty, 0) == elementType &&
+ canonTy->getSizeExpr() == numElements)
return canon;
// Otherwise, we need to build a type which follows the spelling
@@ -2956,6 +3025,21 @@ static bool isCanonicalResultType(QualType T) {
T.getObjCLifetime() == Qualifiers::OCL_ExplicitNone);
}
+CanQualType
+ASTContext::getCanonicalFunctionResultType(QualType ResultType) const {
+ CanQualType CanResultType = getCanonicalType(ResultType);
+
+ // Canonical result types do not have ARC lifetime qualifiers.
+ if (CanResultType.getQualifiers().hasObjCLifetime()) {
+ Qualifiers Qs = CanResultType.getQualifiers();
+ Qs.removeObjCLifetime();
+ return CanQualType::CreateUnsafe(
+ getQualifiedType(CanResultType.getUnqualifiedType(), Qs));
+ }
+
+ return CanResultType;
+}
+
QualType
ASTContext::getFunctionType(QualType ResultTy, ArrayRef<QualType> ArgArray,
const FunctionProtoType::ExtProtoInfo &EPI) const {
@@ -2993,14 +3077,8 @@ ASTContext::getFunctionType(QualType ResultTy, ArrayRef<QualType> ArgArray,
CanonicalEPI.HasTrailingReturn = false;
CanonicalEPI.ExceptionSpec = FunctionProtoType::ExceptionSpecInfo();
- // Result types do not have ARC lifetime qualifiers.
- QualType CanResultTy = getCanonicalType(ResultTy);
- if (ResultTy.getQualifiers().hasObjCLifetime()) {
- Qualifiers Qs = CanResultTy.getQualifiers();
- Qs.removeObjCLifetime();
- CanResultTy = getQualifiedType(CanResultTy.getUnqualifiedType(), Qs);
- }
-
+ // Adjust the canonical function result type.
+ CanQualType CanResultTy = getCanonicalFunctionResultType(ResultTy);
Canonical = getFunctionType(CanResultTy, CanonicalArgs, CanonicalEPI);
// Get the new insert position for the node we care about.
@@ -3164,7 +3242,6 @@ QualType ASTContext::getAttributedType(AttributedType::Kind attrKind,
return QualType(type, 0);
}
-
/// \brief Retrieve a substitution-result type.
QualType
ASTContext::getSubstTemplateTypeParmType(const TemplateTypeParmType *Parm,
@@ -3595,20 +3672,18 @@ static bool areSortedAndUniqued(ObjCProtocolDecl * const *Protocols,
return true;
}
-static void SortAndUniqueProtocols(ObjCProtocolDecl **Protocols,
- unsigned &NumProtocols) {
- ObjCProtocolDecl **ProtocolsEnd = Protocols+NumProtocols;
-
+static void
+SortAndUniqueProtocols(SmallVectorImpl<ObjCProtocolDecl *> &Protocols) {
// Sort protocols, keyed by name.
- llvm::array_pod_sort(Protocols, ProtocolsEnd, CmpProtocolNames);
+ llvm::array_pod_sort(Protocols.begin(), Protocols.end(), CmpProtocolNames);
// Canonicalize.
- for (unsigned I = 0, N = NumProtocols; I != N; ++I)
- Protocols[I] = Protocols[I]->getCanonicalDecl();
-
+ for (ObjCProtocolDecl *&P : Protocols)
+ P = P->getCanonicalDecl();
+
// Remove duplicates.
- ProtocolsEnd = std::unique(Protocols, ProtocolsEnd);
- NumProtocols = ProtocolsEnd-Protocols;
+ auto ProtocolsEnd = std::unique(Protocols.begin(), Protocols.end());
+ Protocols.erase(ProtocolsEnd, Protocols.end());
}
QualType ASTContext::getObjCObjectType(QualType BaseType,
@@ -3673,12 +3748,9 @@ QualType ASTContext::getObjCObjectType(
ArrayRef<ObjCProtocolDecl *> canonProtocols;
SmallVector<ObjCProtocolDecl*, 8> canonProtocolsVec;
if (!protocolsSorted) {
- canonProtocolsVec.insert(canonProtocolsVec.begin(),
- protocols.begin(),
- protocols.end());
- unsigned uniqueCount = protocols.size();
- SortAndUniqueProtocols(&canonProtocolsVec[0], uniqueCount);
- canonProtocols = llvm::makeArrayRef(&canonProtocolsVec[0], uniqueCount);
+ canonProtocolsVec.append(protocols.begin(), protocols.end());
+ SortAndUniqueProtocols(canonProtocolsVec);
+ canonProtocols = canonProtocolsVec;
} else {
canonProtocols = protocols;
}
@@ -3869,7 +3941,6 @@ QualType ASTContext::getTypeOfType(QualType tofType) const {
return QualType(tot, 0);
}
-
/// \brief Unlike many "get<Type>" functions, we don't unique DecltypeType
/// nodes. This would never be helpful, since each such type has its own
/// expression, and would not give a significant memory saving, since there
@@ -3921,20 +3992,20 @@ QualType ASTContext::getUnaryTransformType(QualType BaseType,
/// getAutoType - Return the uniqued reference to the 'auto' type which has been
/// deduced to the given type, or to the canonical undeduced 'auto' type, or the
/// canonical deduced-but-dependent 'auto' type.
-QualType ASTContext::getAutoType(QualType DeducedType, bool IsDecltypeAuto,
+QualType ASTContext::getAutoType(QualType DeducedType, AutoTypeKeyword Keyword,
bool IsDependent) const {
- if (DeducedType.isNull() && !IsDecltypeAuto && !IsDependent)
+ if (DeducedType.isNull() && Keyword == AutoTypeKeyword::Auto && !IsDependent)
return getAutoDeductType();
// Look in the folding set for an existing type.
void *InsertPos = nullptr;
llvm::FoldingSetNodeID ID;
- AutoType::Profile(ID, DeducedType, IsDecltypeAuto, IsDependent);
+ AutoType::Profile(ID, DeducedType, Keyword, IsDependent);
if (AutoType *AT = AutoTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(AT, 0);
AutoType *AT = new (*this, TypeAlignment) AutoType(DeducedType,
- IsDecltypeAuto,
+ Keyword,
IsDependent);
Types.push_back(AT);
if (InsertPos)
@@ -3974,7 +4045,7 @@ QualType ASTContext::getAtomicType(QualType T) const {
QualType ASTContext::getAutoDeductType() const {
if (AutoDeductTy.isNull())
AutoDeductTy = QualType(
- new (*this, TypeAlignment) AutoType(QualType(), /*decltype(auto)*/false,
+ new (*this, TypeAlignment) AutoType(QualType(), AutoTypeKeyword::Auto,
/*dependent*/false),
0);
return AutoDeductTy;
@@ -4310,7 +4381,7 @@ ASTContext::getCanonicalTemplateArgument(const TemplateArgument &Arg) const {
A != AEnd; (void)++A, ++Idx)
CanonArgs[Idx] = getCanonicalTemplateArgument(*A);
- return TemplateArgument(CanonArgs, Arg.pack_size());
+ return TemplateArgument(llvm::makeArrayRef(CanonArgs, Arg.pack_size()));
}
}
@@ -4374,7 +4445,6 @@ ASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const {
llvm_unreachable("Invalid NestedNameSpecifier::Kind!");
}
-
const ArrayType *ASTContext::getAsArrayType(QualType T) const {
// Handle the non-qualified case efficiently.
if (!T.hasLocalQualifiers()) {
@@ -4909,8 +4979,6 @@ bool ASTContext::BlockRequiresCopying(QualType Ty,
// If we have lifetime, that dominates.
if (Qualifiers::ObjCLifetime lifetime = qs.getObjCLifetime()) {
- assert(getLangOpts().ObjCAutoRefCount);
-
switch (lifetime) {
case Qualifiers::OCL_None: llvm_unreachable("impossible");
@@ -4944,14 +5012,14 @@ bool ASTContext::getByrefLifetime(QualType Ty,
if (Ty->isRecordType()) {
HasByrefExtendedLayout = true;
LifeTime = Qualifiers::OCL_None;
- }
- else if (getLangOpts().ObjCAutoRefCount)
- LifeTime = Ty.getObjCLifetime();
- // MRR.
- else if (Ty->isObjCObjectPointerType() || Ty->isBlockPointerType())
+ } else if ((LifeTime = Ty.getObjCLifetime())) {
+ // Honor the ARC qualifiers.
+ } else if (Ty->isObjCObjectPointerType() || Ty->isBlockPointerType()) {
+ // The MRR rule.
LifeTime = Qualifiers::OCL_ExplicitNone;
- else
+ } else {
LifeTime = Qualifiers::OCL_None;
+ }
return true;
}
@@ -4990,9 +5058,10 @@ CharUnits ASTContext::getObjCEncodingTypeSize(QualType type) const {
}
bool ASTContext::isMSStaticDataMemberInlineDefinition(const VarDecl *VD) const {
- return getLangOpts().MSVCCompat && VD->isStaticDataMember() &&
+ return getTargetInfo().getCXXABI().isMicrosoft() &&
+ VD->isStaticDataMember() &&
VD->getType()->isIntegralOrEnumerationType() &&
- VD->isFirstDecl() && !VD->isOutOfLine() && VD->hasInit();
+ !VD->getFirstDecl()->isOutOfLine() && VD->getFirstDecl()->hasInit();
}
static inline
@@ -5364,8 +5433,18 @@ static char getObjCEncodingForPrimitiveKind(const ASTContext *C,
case BuiltinType::OCLImage1dBuffer:
case BuiltinType::OCLImage2d:
case BuiltinType::OCLImage2dArray:
+ case BuiltinType::OCLImage2dDepth:
+ case BuiltinType::OCLImage2dArrayDepth:
+ case BuiltinType::OCLImage2dMSAA:
+ case BuiltinType::OCLImage2dArrayMSAA:
+ case BuiltinType::OCLImage2dMSAADepth:
+ case BuiltinType::OCLImage2dArrayMSAADepth:
case BuiltinType::OCLImage3d:
case BuiltinType::OCLEvent:
+ case BuiltinType::OCLClkEvent:
+ case BuiltinType::OCLQueue:
+ case BuiltinType::OCLNDRange:
+ case BuiltinType::OCLReserveID:
case BuiltinType::OCLSampler:
case BuiltinType::Dependent:
#define BUILTIN_TYPE(KIND, ID)
@@ -5779,7 +5858,6 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
// Just ignore it.
case Type::Auto:
return;
-
#define ABSTRACT_TYPE(KIND, BASE)
#define TYPE(KIND, BASE)
@@ -5998,10 +6076,19 @@ ObjCInterfaceDecl *ASTContext::getObjCProtocolDecl() const {
// __builtin_va_list Construction Functions
//===----------------------------------------------------------------------===//
-static TypedefDecl *CreateCharPtrBuiltinVaListDecl(const ASTContext *Context) {
- // typedef char* __builtin_va_list;
+static TypedefDecl *CreateCharPtrNamedVaListDecl(const ASTContext *Context,
+ StringRef Name) {
+ // typedef char* __builtin[_ms]_va_list;
QualType T = Context->getPointerType(Context->CharTy);
- return Context->buildImplicitTypedef(T, "__builtin_va_list");
+ return Context->buildImplicitTypedef(T, Name);
+}
+
+static TypedefDecl *CreateMSVaListDecl(const ASTContext *Context) {
+ return CreateCharPtrNamedVaListDecl(Context, "__builtin_ms_va_list");
+}
+
+static TypedefDecl *CreateCharPtrBuiltinVaListDecl(const ASTContext *Context) {
+ return CreateCharPtrNamedVaListDecl(Context, "__builtin_va_list");
}
static TypedefDecl *CreateVoidPtrBuiltinVaListDecl(const ASTContext *Context) {
@@ -6067,8 +6154,8 @@ CreateAArch64ABIBuiltinVaListDecl(const ASTContext *Context) {
VaListTagDecl->addDecl(Field);
}
VaListTagDecl->completeDefinition();
+ Context->VaListTagDecl = VaListTagDecl;
QualType VaListTagType = Context->getRecordType(VaListTagDecl);
- Context->VaListTagTy = VaListTagType;
// } __builtin_va_list;
return Context->buildImplicitTypedef(VaListTagType, "__builtin_va_list");
@@ -6119,8 +6206,8 @@ static TypedefDecl *CreatePowerABIBuiltinVaListDecl(const ASTContext *Context) {
VaListTagDecl->addDecl(Field);
}
VaListTagDecl->completeDefinition();
+ Context->VaListTagDecl = VaListTagDecl;
QualType VaListTagType = Context->getRecordType(VaListTagDecl);
- Context->VaListTagTy = VaListTagType;
// } __va_list_tag;
TypedefDecl *VaListTagTypedefDecl =
@@ -6139,7 +6226,7 @@ static TypedefDecl *CreatePowerABIBuiltinVaListDecl(const ASTContext *Context) {
static TypedefDecl *
CreateX86_64ABIBuiltinVaListDecl(const ASTContext *Context) {
- // typedef struct __va_list_tag {
+ // struct __va_list_tag {
RecordDecl *VaListTagDecl;
VaListTagDecl = Context->buildImplicitRecord("__va_list_tag");
VaListTagDecl->startDefinition();
@@ -6179,21 +6266,15 @@ CreateX86_64ABIBuiltinVaListDecl(const ASTContext *Context) {
VaListTagDecl->addDecl(Field);
}
VaListTagDecl->completeDefinition();
+ Context->VaListTagDecl = VaListTagDecl;
QualType VaListTagType = Context->getRecordType(VaListTagDecl);
- Context->VaListTagTy = VaListTagType;
-
- // } __va_list_tag;
- TypedefDecl *VaListTagTypedefDecl =
- Context->buildImplicitTypedef(VaListTagType, "__va_list_tag");
- QualType VaListTagTypedefType =
- Context->getTypedefType(VaListTagTypedefDecl);
+ // };
- // typedef __va_list_tag __builtin_va_list[1];
+ // typedef struct __va_list_tag __builtin_va_list[1];
llvm::APInt Size(Context->getTypeSize(Context->getSizeType()), 1);
- QualType VaListTagArrayType
- = Context->getConstantArrayType(VaListTagTypedefType,
- Size, ArrayType::Normal,0);
+ QualType VaListTagArrayType =
+ Context->getConstantArrayType(VaListTagType, Size, ArrayType::Normal, 0);
return Context->buildImplicitTypedef(VaListTagArrayType, "__builtin_va_list");
}
@@ -6248,7 +6329,7 @@ CreateAAPCSABIBuiltinVaListDecl(const ASTContext *Context) {
static TypedefDecl *
CreateSystemZBuiltinVaListDecl(const ASTContext *Context) {
- // typedef struct __va_list_tag {
+ // struct __va_list_tag {
RecordDecl *VaListTagDecl;
VaListTagDecl = Context->buildImplicitRecord("__va_list_tag");
VaListTagDecl->startDefinition();
@@ -6288,20 +6369,15 @@ CreateSystemZBuiltinVaListDecl(const ASTContext *Context) {
VaListTagDecl->addDecl(Field);
}
VaListTagDecl->completeDefinition();
+ Context->VaListTagDecl = VaListTagDecl;
QualType VaListTagType = Context->getRecordType(VaListTagDecl);
- Context->VaListTagTy = VaListTagType;
- // } __va_list_tag;
- TypedefDecl *VaListTagTypedefDecl =
- Context->buildImplicitTypedef(VaListTagType, "__va_list_tag");
- QualType VaListTagTypedefType =
- Context->getTypedefType(VaListTagTypedefDecl);
+ // };
// typedef __va_list_tag __builtin_va_list[1];
llvm::APInt Size(Context->getTypeSize(Context->getSizeType()), 1);
- QualType VaListTagArrayType
- = Context->getConstantArrayType(VaListTagTypedefType,
- Size, ArrayType::Normal,0);
+ QualType VaListTagArrayType =
+ Context->getConstantArrayType(VaListTagType, Size, ArrayType::Normal, 0);
return Context->buildImplicitTypedef(VaListTagArrayType, "__builtin_va_list");
}
@@ -6339,13 +6415,20 @@ TypedefDecl *ASTContext::getBuiltinVaListDecl() const {
return BuiltinVaListDecl;
}
-QualType ASTContext::getVaListTagType() const {
- // Force the creation of VaListTagTy by building the __builtin_va_list
+Decl *ASTContext::getVaListTagDecl() const {
+ // Force the creation of VaListTagDecl by building the __builtin_va_list
// declaration.
- if (VaListTagTy.isNull())
- (void) getBuiltinVaListDecl();
+ if (!VaListTagDecl)
+ (void)getBuiltinVaListDecl();
+
+ return VaListTagDecl;
+}
+
+TypedefDecl *ASTContext::getBuiltinMSVaListDecl() const {
+ if (!BuiltinMSVaListDecl)
+ BuiltinMSVaListDecl = CreateMSVaListDecl(this);
- return VaListTagTy;
+ return BuiltinMSVaListDecl;
}
void ASTContext::setObjCConstantStringInterface(ObjCInterfaceDecl *Decl) {
@@ -7734,6 +7817,10 @@ bool ASTContext::FunctionTypesMatchOnNSConsumedAttrs(
return true;
}
+void ASTContext::ResetObjCLayout(const ObjCContainerDecl *CD) {
+ ObjCLayouts[CD] = nullptr;
+}
+
/// mergeObjCGCQualifiers - This routine merges ObjC's GC attribute of 'LHS' and
/// 'RHS' attributes and returns the merged version; including for function
/// return types.
@@ -8128,7 +8215,7 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,
QualType ASTContext::GetBuiltinType(unsigned Id,
GetBuiltinTypeError &Error,
unsigned *IntegerConstantArgs) const {
- const char *TypeStr = BuiltinInfo.GetTypeString(Id);
+ const char *TypeStr = BuiltinInfo.getTypeString(Id);
SmallVector<QualType, 8> ArgTypes;
@@ -8212,7 +8299,8 @@ static GVALinkage basicGVALinkageForFunction(const ASTContext &Context,
if (!FD->isInlined())
return External;
- if ((!Context.getLangOpts().CPlusPlus && !Context.getLangOpts().MSVCCompat &&
+ if ((!Context.getLangOpts().CPlusPlus &&
+ !Context.getTargetInfo().getCXXABI().isMicrosoft() &&
!FD->hasAttr<DLLExportAttr>()) ||
FD->hasAttr<GNUInlineAttr>()) {
// FIXME: This doesn't match gcc's behavior for dllexport inline functions.
@@ -8235,13 +8323,13 @@ static GVALinkage basicGVALinkageForFunction(const ASTContext &Context,
return GVA_DiscardableODR;
}
-static GVALinkage adjustGVALinkageForDLLAttribute(GVALinkage L, const Decl *D) {
+static GVALinkage adjustGVALinkageForAttributes(GVALinkage L, const Decl *D) {
// See http://msdn.microsoft.com/en-us/library/xa0d9ste.aspx
// dllexport/dllimport on inline functions.
if (D->hasAttr<DLLImportAttr>()) {
if (L == GVA_DiscardableODR || L == GVA_StrongODR)
return GVA_AvailableExternally;
- } else if (D->hasAttr<DLLExportAttr>()) {
+ } else if (D->hasAttr<DLLExportAttr>() || D->hasAttr<CUDAGlobalAttr>()) {
if (L == GVA_DiscardableODR)
return GVA_StrongODR;
}
@@ -8249,8 +8337,8 @@ static GVALinkage adjustGVALinkageForDLLAttribute(GVALinkage L, const Decl *D) {
}
GVALinkage ASTContext::GetGVALinkageForFunction(const FunctionDecl *FD) const {
- return adjustGVALinkageForDLLAttribute(basicGVALinkageForFunction(*this, FD),
- FD);
+ return adjustGVALinkageForAttributes(basicGVALinkageForFunction(*this, FD),
+ FD);
}
static GVALinkage basicGVALinkageForVariable(const ASTContext &Context,
@@ -8285,9 +8373,14 @@ static GVALinkage basicGVALinkageForVariable(const ASTContext &Context,
switch (VD->getTemplateSpecializationKind()) {
case TSK_Undeclared:
- case TSK_ExplicitSpecialization:
return GVA_StrongExternal;
+ case TSK_ExplicitSpecialization:
+ return Context.getTargetInfo().getCXXABI().isMicrosoft() &&
+ VD->isStaticDataMember()
+ ? GVA_StrongODR
+ : GVA_StrongExternal;
+
case TSK_ExplicitInstantiationDefinition:
return GVA_StrongODR;
@@ -8302,8 +8395,8 @@ static GVALinkage basicGVALinkageForVariable(const ASTContext &Context,
}
GVALinkage ASTContext::GetGVALinkageForVariable(const VarDecl *VD) {
- return adjustGVALinkageForDLLAttribute(basicGVALinkageForVariable(*this, VD),
- VD);
+ return adjustGVALinkageForAttributes(basicGVALinkageForVariable(*this, VD),
+ VD);
}
bool ASTContext::DeclMustBeEmitted(const Decl *D) {
@@ -8313,6 +8406,9 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
// Global named register variables (GNU extension) are never emitted.
if (VD->getStorageClass() == SC_Register)
return false;
+ if (VD->getDescribedVarTemplate() ||
+ isa<VarTemplatePartialSpecializationDecl>(VD))
+ return false;
} else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
// We never need to emit an uninstantiated function template.
if (FD->getTemplatedKind() == FunctionDecl::TK_FunctionTemplate)
@@ -8385,7 +8481,8 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
return true;
// Variables that have initialization with side-effects are required.
- if (VD->getInit() && VD->getInit()->HasSideEffects(*this))
+ if (VD->getInit() && VD->getInit()->HasSideEffects(*this) &&
+ !VD->evaluateValue())
return true;
return false;
@@ -8425,6 +8522,8 @@ MangleContext *ASTContext::createMangleContext() {
case TargetCXXABI::GenericMIPS:
case TargetCXXABI::iOS:
case TargetCXXABI::iOS64:
+ case TargetCXXABI::WebAssembly:
+ case TargetCXXABI::WatchOS:
return ItaniumMangleContext::create(*this, getDiagnostics());
case TargetCXXABI::Microsoft:
return MicrosoftMangleContext::create(*this, getDiagnostics());
@@ -8543,6 +8642,25 @@ Expr *ASTContext::getDefaultArgExprForConstructor(const CXXConstructorDecl *CD,
cast<CXXConstructorDecl>(CD->getFirstDecl()), ParmIdx);
}
+void ASTContext::addTypedefNameForUnnamedTagDecl(TagDecl *TD,
+ TypedefNameDecl *DD) {
+ return ABI->addTypedefNameForUnnamedTagDecl(TD, DD);
+}
+
+TypedefNameDecl *
+ASTContext::getTypedefNameForUnnamedTagDecl(const TagDecl *TD) {
+ return ABI->getTypedefNameForUnnamedTagDecl(TD);
+}
+
+void ASTContext::addDeclaratorForUnnamedTagDecl(TagDecl *TD,
+ DeclaratorDecl *DD) {
+ return ABI->addDeclaratorForUnnamedTagDecl(TD, DD);
+}
+
+DeclaratorDecl *ASTContext::getDeclaratorForUnnamedTagDecl(const TagDecl *TD) {
+ return ABI->getDeclaratorForUnnamedTagDecl(TD);
+}
+
void ASTContext::setParameterIndex(const ParmVarDecl *D, unsigned int index) {
ParamIndices[D] = index;
}
@@ -8559,12 +8677,14 @@ ASTContext::getMaterializedTemporaryValue(const MaterializeTemporaryExpr *E,
bool MayCreate) {
assert(E && E->getStorageDuration() == SD_Static &&
"don't need to cache the computed value for this temporary");
- if (MayCreate)
- return &MaterializedTemporaryValues[E];
+ if (MayCreate) {
+ APValue *&MTVI = MaterializedTemporaryValues[E];
+ if (!MTVI)
+ MTVI = new (*this) APValue;
+ return MTVI;
+ }
- llvm::DenseMap<const MaterializeTemporaryExpr *, APValue>::iterator I =
- MaterializedTemporaryValues.find(E);
- return I == MaterializedTemporaryValues.end() ? nullptr : &I->second;
+ return MaterializedTemporaryValues.lookup(E);
}
bool ASTContext::AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const {
@@ -8587,6 +8707,32 @@ bool ASTContext::AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const {
namespace {
+ast_type_traits::DynTypedNode getSingleDynTypedNodeFromParentMap(
+ ASTContext::ParentMapPointers::mapped_type U) {
+ if (const auto *D = U.dyn_cast<const Decl *>())
+ return ast_type_traits::DynTypedNode::create(*D);
+ if (const auto *S = U.dyn_cast<const Stmt *>())
+ return ast_type_traits::DynTypedNode::create(*S);
+ return *U.get<ast_type_traits::DynTypedNode *>();
+}
+
+/// Template specializations to abstract away from pointers and TypeLocs.
+/// @{
+template <typename T>
+ast_type_traits::DynTypedNode createDynTypedNode(const T &Node) {
+ return ast_type_traits::DynTypedNode::create(*Node);
+}
+template <>
+ast_type_traits::DynTypedNode createDynTypedNode(const TypeLoc &Node) {
+ return ast_type_traits::DynTypedNode::create(Node);
+}
+template <>
+ast_type_traits::DynTypedNode
+createDynTypedNode(const NestedNameSpecifierLoc &Node) {
+ return ast_type_traits::DynTypedNode::create(Node);
+}
+/// @}
+
/// \brief A \c RecursiveASTVisitor that builds a map from nodes to their
/// parents as defined by the \c RecursiveASTVisitor.
///
@@ -8596,22 +8742,25 @@ namespace {
///
/// FIXME: Currently only builds up the map using \c Stmt and \c Decl nodes.
class ParentMapASTVisitor : public RecursiveASTVisitor<ParentMapASTVisitor> {
-
public:
/// \brief Builds and returns the translation unit's parent map.
///
/// The caller takes ownership of the returned \c ParentMap.
- static ASTContext::ParentMap *buildMap(TranslationUnitDecl &TU) {
- ParentMapASTVisitor Visitor(new ASTContext::ParentMap);
+ static std::pair<ASTContext::ParentMapPointers *,
+ ASTContext::ParentMapOtherNodes *>
+ buildMap(TranslationUnitDecl &TU) {
+ ParentMapASTVisitor Visitor(new ASTContext::ParentMapPointers,
+ new ASTContext::ParentMapOtherNodes);
Visitor.TraverseDecl(&TU);
- return Visitor.Parents;
+ return std::make_pair(Visitor.Parents, Visitor.OtherParents);
}
private:
typedef RecursiveASTVisitor<ParentMapASTVisitor> VisitorBase;
- ParentMapASTVisitor(ASTContext::ParentMap *Parents) : Parents(Parents) {
- }
+ ParentMapASTVisitor(ASTContext::ParentMapPointers *Parents,
+ ASTContext::ParentMapOtherNodes *OtherParents)
+ : Parents(Parents), OtherParents(OtherParents) {}
bool shouldVisitTemplateInstantiations() const {
return true;
@@ -8619,14 +8768,11 @@ namespace {
bool shouldVisitImplicitCode() const {
return true;
}
- // Disables data recursion. We intercept Traverse* methods in the RAV, which
- // are not triggered during data recursion.
- bool shouldUseDataRecursionFor(clang::Stmt *S) const {
- return false;
- }
- template <typename T>
- bool TraverseNode(T *Node, bool(VisitorBase:: *traverse) (T *)) {
+ template <typename T, typename MapNodeTy, typename BaseTraverseFn,
+ typename MapTy>
+ bool TraverseNode(T Node, MapNodeTy MapNode,
+ BaseTraverseFn BaseTraverse, MapTy *Parents) {
if (!Node)
return true;
if (ParentStack.size() > 0) {
@@ -8640,18 +8786,25 @@ namespace {
// map. The main problem there is to implement hash functions /
// comparison operators for all types that DynTypedNode supports that
// do not have pointer identity.
- auto &NodeOrVector = (*Parents)[Node];
+ auto &NodeOrVector = (*Parents)[MapNode];
if (NodeOrVector.isNull()) {
- NodeOrVector = new ast_type_traits::DynTypedNode(ParentStack.back());
+ if (const auto *D = ParentStack.back().get<Decl>())
+ NodeOrVector = D;
+ else if (const auto *S = ParentStack.back().get<Stmt>())
+ NodeOrVector = S;
+ else
+ NodeOrVector =
+ new ast_type_traits::DynTypedNode(ParentStack.back());
} else {
- if (NodeOrVector.template is<ast_type_traits::DynTypedNode *>()) {
- auto *Node =
- NodeOrVector.template get<ast_type_traits::DynTypedNode *>();
- auto *Vector = new ASTContext::ParentVector(1, *Node);
+ if (!NodeOrVector.template is<ASTContext::ParentVector *>()) {
+ auto *Vector = new ASTContext::ParentVector(
+ 1, getSingleDynTypedNodeFromParentMap(NodeOrVector));
+ if (auto *Node =
+ NodeOrVector
+ .template dyn_cast<ast_type_traits::DynTypedNode *>())
+ delete Node;
NodeOrVector = Vector;
- delete Node;
}
- assert(NodeOrVector.template is<ASTContext::ParentVector *>());
auto *Vector =
NodeOrVector.template get<ASTContext::ParentVector *>();
@@ -8666,47 +8819,74 @@ namespace {
Vector->push_back(ParentStack.back());
}
}
- ParentStack.push_back(ast_type_traits::DynTypedNode::create(*Node));
- bool Result = (this ->* traverse) (Node);
+ ParentStack.push_back(createDynTypedNode(Node));
+ bool Result = BaseTraverse();
ParentStack.pop_back();
return Result;
}
bool TraverseDecl(Decl *DeclNode) {
- return TraverseNode(DeclNode, &VisitorBase::TraverseDecl);
+ return TraverseNode(DeclNode, DeclNode,
+ [&] { return VisitorBase::TraverseDecl(DeclNode); },
+ Parents);
}
bool TraverseStmt(Stmt *StmtNode) {
- return TraverseNode(StmtNode, &VisitorBase::TraverseStmt);
+ return TraverseNode(StmtNode, StmtNode,
+ [&] { return VisitorBase::TraverseStmt(StmtNode); },
+ Parents);
+ }
+
+ bool TraverseTypeLoc(TypeLoc TypeLocNode) {
+ return TraverseNode(
+ TypeLocNode, ast_type_traits::DynTypedNode::create(TypeLocNode),
+ [&] { return VisitorBase::TraverseTypeLoc(TypeLocNode); },
+ OtherParents);
+ }
+
+ bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNSLocNode) {
+ return TraverseNode(
+ NNSLocNode, ast_type_traits::DynTypedNode::create(NNSLocNode),
+ [&] {
+ return VisitorBase::TraverseNestedNameSpecifierLoc(NNSLocNode);
+ },
+ OtherParents);
}
- ASTContext::ParentMap *Parents;
+ ASTContext::ParentMapPointers *Parents;
+ ASTContext::ParentMapOtherNodes *OtherParents;
llvm::SmallVector<ast_type_traits::DynTypedNode, 16> ParentStack;
friend class RecursiveASTVisitor<ParentMapASTVisitor>;
};
-} // end namespace
+} // anonymous namespace
-ArrayRef<ast_type_traits::DynTypedNode>
+template <typename NodeTy, typename MapTy>
+static ASTContext::DynTypedNodeList getDynNodeFromMap(const NodeTy &Node,
+ const MapTy &Map) {
+ auto I = Map.find(Node);
+ if (I == Map.end()) {
+ return llvm::ArrayRef<ast_type_traits::DynTypedNode>();
+ }
+ if (auto *V = I->second.template dyn_cast<ASTContext::ParentVector *>()) {
+ return llvm::makeArrayRef(*V);
+ }
+ return getSingleDynTypedNodeFromParentMap(I->second);
+}
+
+ASTContext::DynTypedNodeList
ASTContext::getParents(const ast_type_traits::DynTypedNode &Node) {
- assert(Node.getMemoizationData() &&
- "Invariant broken: only nodes that support memoization may be "
- "used in the parent map.");
- if (!AllParents) {
+ if (!PointerParents) {
// We always need to run over the whole translation unit, as
// hasAncestor can escape any subtree.
- AllParents.reset(
- ParentMapASTVisitor::buildMap(*getTranslationUnitDecl()));
- }
- ParentMap::const_iterator I = AllParents->find(Node.getMemoizationData());
- if (I == AllParents->end()) {
- return None;
- }
- if (auto *N = I->second.dyn_cast<ast_type_traits::DynTypedNode *>()) {
- return llvm::makeArrayRef(N, 1);
+ auto Maps = ParentMapASTVisitor::buildMap(*getTranslationUnitDecl());
+ PointerParents.reset(Maps.first);
+ OtherParents.reset(Maps.second);
}
- return *I->second.get<ParentVector *>();
+ if (Node.getNodeKind().hasPointerIdentity())
+ return getDynNodeFromMap(Node.getMemoizationData(), *PointerParents);
+ return getDynNodeFromMap(Node, *OtherParents);
}
bool
diff --git a/lib/AST/ASTDiagnostic.cpp b/lib/AST/ASTDiagnostic.cpp
index dddaa5af6fb0..0ab1fa788603 100644
--- a/lib/AST/ASTDiagnostic.cpp
+++ b/lib/AST/ASTDiagnostic.cpp
@@ -66,11 +66,63 @@ static QualType Desugar(ASTContext &Context, QualType QT, bool &ShouldAKA) {
continue;
}
- // Don't desugar template specializations, unless it's an alias template.
- if (const TemplateSpecializationType *TST
- = dyn_cast<TemplateSpecializationType>(Ty))
- if (!TST->isTypeAlias())
+ // Desugar FunctionType if return type or any parameter type should be
+ // desugared. Preserve nullability attribute on desugared types.
+ if (const FunctionType *FT = dyn_cast<FunctionType>(Ty)) {
+ bool DesugarReturn = false;
+ QualType SugarRT = FT->getReturnType();
+ QualType RT = Desugar(Context, SugarRT, DesugarReturn);
+ if (auto nullability = AttributedType::stripOuterNullability(SugarRT)) {
+ RT = Context.getAttributedType(
+ AttributedType::getNullabilityAttrKind(*nullability), RT, RT);
+ }
+
+ bool DesugarArgument = false;
+ SmallVector<QualType, 4> Args;
+ const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FT);
+ if (FPT) {
+ for (QualType SugarPT : FPT->param_types()) {
+ QualType PT = Desugar(Context, SugarPT, DesugarArgument);
+ if (auto nullability =
+ AttributedType::stripOuterNullability(SugarPT)) {
+ PT = Context.getAttributedType(
+ AttributedType::getNullabilityAttrKind(*nullability), PT, PT);
+ }
+ Args.push_back(PT);
+ }
+ }
+
+ if (DesugarReturn || DesugarArgument) {
+ ShouldAKA = true;
+ QT = FPT ? Context.getFunctionType(RT, Args, FPT->getExtProtoInfo())
+ : Context.getFunctionNoProtoType(RT, FT->getExtInfo());
+ break;
+ }
+ }
+
+ // Desugar template specializations if any template argument should be
+ // desugared.
+ if (const TemplateSpecializationType *TST =
+ dyn_cast<TemplateSpecializationType>(Ty)) {
+ if (!TST->isTypeAlias()) {
+ bool DesugarArgument = false;
+ SmallVector<TemplateArgument, 4> Args;
+ for (unsigned I = 0, N = TST->getNumArgs(); I != N; ++I) {
+ const TemplateArgument &Arg = TST->getArg(I);
+ if (Arg.getKind() == TemplateArgument::Type)
+ Args.push_back(Desugar(Context, Arg.getAsType(), DesugarArgument));
+ else
+ Args.push_back(Arg);
+ }
+
+ if (DesugarArgument) {
+ ShouldAKA = true;
+ QT = Context.getTemplateSpecializationType(
+ TST->getTemplateName(), Args.data(), Args.size(), QT);
+ }
break;
+ }
+ }
// Don't desugar magic Objective-C types.
if (QualType(Ty,0) == Context.getObjCIdType() ||
@@ -80,7 +132,8 @@ static QualType Desugar(ASTContext &Context, QualType QT, bool &ShouldAKA) {
break;
// Don't desugar va_list.
- if (QualType(Ty,0) == Context.getBuiltinVaListType())
+ if (QualType(Ty, 0) == Context.getBuiltinVaListType() ||
+ QualType(Ty, 0) == Context.getBuiltinMSVaListType())
break;
// Otherwise, do a single-step desugar.
@@ -393,8 +446,6 @@ void clang::FormatASTNodeDiagnosticArgument(
}
- OS.flush();
-
if (NeedQuotes) {
Output.insert(Output.begin()+OldEnd, '\'');
Output.push_back('\'');
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp
index c95922b141e0..e7fee0316b69 100644
--- a/lib/AST/ASTDumper.cpp
+++ b/lib/AST/ASTDumper.cpp
@@ -21,8 +21,10 @@
#include "clang/AST/DeclVisitor.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/AST/TypeVisitor.h"
+#include "clang/Basic/Builtins.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/SourceManager.h"
+#include "clang/Sema/LocInfoType.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;
using namespace clang::comments;
@@ -447,6 +449,7 @@ namespace {
const ClassTemplatePartialSpecializationDecl *D);
void VisitClassScopeFunctionSpecializationDecl(
const ClassScopeFunctionSpecializationDecl *D);
+ void VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D);
void VisitVarTemplateDecl(const VarTemplateDecl *D);
void VisitVarTemplateSpecializationDecl(
const VarTemplateSpecializationDecl *D);
@@ -653,6 +656,15 @@ void ASTDumper::dumpTypeAsChild(const Type *T) {
OS << "<<<NULL>>>";
return;
}
+ if (const LocInfoType *LIT = llvm::dyn_cast<LocInfoType>(T)) {
+ {
+ ColorScope Color(*this, TypeColor);
+ OS << "LocInfo Type";
+ }
+ dumpPointer(T);
+ dumpTypeAsChild(LIT->getTypeSourceInfo()->getType());
+ return;
+ }
{
ColorScope Color(*this, TypeColor);
@@ -1333,6 +1345,11 @@ void ASTDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) {
VisitTemplateDecl(D, false);
}
+void ASTDumper::VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) {
+ dumpName(D);
+ dumpTemplateParameters(D->getTemplateParameters());
+}
+
void ASTDumper::VisitVarTemplateSpecializationDecl(
const VarTemplateSpecializationDecl *D) {
dumpTemplateArgumentList(D->getTemplateArgs());
@@ -1378,20 +1395,23 @@ void ASTDumper::VisitTemplateTemplateParmDecl(
void ASTDumper::VisitUsingDecl(const UsingDecl *D) {
OS << ' ';
- D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
+ if (D->getQualifier())
+ D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
OS << D->getNameAsString();
}
void ASTDumper::VisitUnresolvedUsingTypenameDecl(
const UnresolvedUsingTypenameDecl *D) {
OS << ' ';
- D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
+ if (D->getQualifier())
+ D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
OS << D->getNameAsString();
}
void ASTDumper::VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) {
OS << ' ';
- D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
+ if (D->getQualifier())
+ D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
OS << D->getNameAsString();
dumpType(D->getType());
}
@@ -2017,6 +2037,9 @@ void ASTDumper::VisitSizeOfPackExpr(const SizeOfPackExpr *Node) {
VisitExpr(Node);
dumpPointer(Node->getPack());
dumpName(Node->getPack());
+ if (Node->isPartiallySubstituted())
+ for (const auto &A : Node->getPartialArguments())
+ dumpTemplateArgument(A);
}
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index 35c0f690db82..359db1ba81b3 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -1746,7 +1746,7 @@ QualType ASTNodeImporter::VisitAutoType(const AutoType *T) {
return QualType();
}
- return Importer.getToContext().getAutoType(ToDeduced, T->isDecltypeAuto(),
+ return Importer.getToContext().getAutoType(ToDeduced, T->getKeyword(),
/*IsDependent*/false);
}
@@ -2144,7 +2144,7 @@ TemplateParameterList *ASTNodeImporter::ImportTemplateParameterList(
return TemplateParameterList::Create(Importer.getToContext(),
Importer.Import(Params->getTemplateLoc()),
Importer.Import(Params->getLAngleLoc()),
- ToParams.data(), ToParams.size(),
+ ToParams,
Importer.Import(Params->getRAngleLoc()));
}
@@ -2210,11 +2210,9 @@ ASTNodeImporter::ImportTemplateArgument(const TemplateArgument &From) {
ToPack.reserve(From.pack_size());
if (ImportTemplateArguments(From.pack_begin(), From.pack_size(), ToPack))
return TemplateArgument();
-
- TemplateArgument *ToArgs
- = new (Importer.getToContext()) TemplateArgument[ToPack.size()];
- std::copy(ToPack.begin(), ToPack.end(), ToArgs);
- return TemplateArgument(ToArgs, ToPack.size());
+
+ return TemplateArgument(
+ llvm::makeArrayRef(ToPack).copy(Importer.getToContext()));
}
}
@@ -4917,13 +4915,14 @@ Stmt *ASTNodeImporter::VisitCXXForRangeStmt(CXXForRangeStmt *S) {
if (!ToBody && S->getBody())
return nullptr;
SourceLocation ToForLoc = Importer.Import(S->getForLoc());
+ SourceLocation ToCoawaitLoc = Importer.Import(S->getCoawaitLoc());
SourceLocation ToColonLoc = Importer.Import(S->getColonLoc());
SourceLocation ToRParenLoc = Importer.Import(S->getRParenLoc());
return new (Importer.getToContext()) CXXForRangeStmt(ToRange, ToBeginEnd,
ToCond, ToInc,
ToLoopVar, ToBody,
- ToForLoc, ToColonLoc,
- ToRParenLoc);
+ ToForLoc, ToCoawaitLoc,
+ ToColonLoc, ToRParenLoc);
}
Stmt *ASTNodeImporter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
@@ -5331,7 +5330,7 @@ Expr *ASTNodeImporter::VisitCallExpr(CallExpr *E) {
return new (Importer.getToContext())
CallExpr(Importer.getToContext(), ToCallee,
- ArrayRef<Expr*>(ToArgs_Copied, NumArgs), T, E->getValueKind(),
+ llvm::makeArrayRef(ToArgs_Copied, NumArgs), T, E->getValueKind(),
Importer.Import(E->getRParenLoc()));
}
diff --git a/lib/AST/CMakeLists.txt b/lib/AST/CMakeLists.txt
index 6ce347b4a31c..e28bd2e16d17 100644
--- a/lib/AST/CMakeLists.txt
+++ b/lib/AST/CMakeLists.txt
@@ -30,6 +30,7 @@ add_clang_library(clangAST
ExprClassification.cpp
ExprConstant.cpp
ExprCXX.cpp
+ ExprObjC.cpp
ExternalASTSource.cpp
InheritViz.cpp
ItaniumCXXABI.cpp
@@ -39,13 +40,17 @@ add_clang_library(clangAST
MicrosoftMangle.cpp
NestedNameSpecifier.cpp
NSAPI.cpp
+ OpenMPClause.cpp
ParentMap.cpp
RawCommentList.cpp
RecordLayout.cpp
RecordLayoutBuilder.cpp
SelectorLocationsKind.cpp
Stmt.cpp
+ StmtCXX.cpp
StmtIterator.cpp
+ StmtObjC.cpp
+ StmtOpenMP.cpp
StmtPrinter.cpp
StmtProfile.cpp
StmtViz.cpp
diff --git a/lib/AST/CXXABI.h b/lib/AST/CXXABI.h
index dad226474fa7..c23b9191c7ab 100644
--- a/lib/AST/CXXABI.h
+++ b/lib/AST/CXXABI.h
@@ -21,6 +21,7 @@ namespace clang {
class ASTContext;
class CXXConstructorDecl;
+class DeclaratorDecl;
class Expr;
class MemberPointerType;
class MangleNumberingContext;
@@ -57,6 +58,17 @@ public:
virtual Expr *getDefaultArgExprForConstructor(const CXXConstructorDecl *CD,
unsigned ParmIdx) = 0;
+
+ virtual void addTypedefNameForUnnamedTagDecl(TagDecl *TD,
+ TypedefNameDecl *DD) = 0;
+
+ virtual TypedefNameDecl *
+ getTypedefNameForUnnamedTagDecl(const TagDecl *TD) = 0;
+
+ virtual void addDeclaratorForUnnamedTagDecl(TagDecl *TD,
+ DeclaratorDecl *DD) = 0;
+
+ virtual DeclaratorDecl *getDeclaratorForUnnamedTagDecl(const TagDecl *TD) = 0;
};
/// Creates an instance of a C++ ABI class.
diff --git a/lib/AST/CXXInheritance.cpp b/lib/AST/CXXInheritance.cpp
index 800c8f83b880..6785a0c2935a 100644
--- a/lib/AST/CXXInheritance.cpp
+++ b/lib/AST/CXXInheritance.cpp
@@ -31,16 +31,16 @@ void CXXBasePaths::ComputeDeclsFound() {
Decls.insert(Path->Decls.front());
NumDeclsFound = Decls.size();
- DeclsFound = new NamedDecl * [NumDeclsFound];
- std::copy(Decls.begin(), Decls.end(), DeclsFound);
+ DeclsFound = llvm::make_unique<NamedDecl *[]>(NumDeclsFound);
+ std::copy(Decls.begin(), Decls.end(), DeclsFound.get());
}
CXXBasePaths::decl_range CXXBasePaths::found_decls() {
if (NumDeclsFound == 0)
ComputeDeclsFound();
- return decl_range(decl_iterator(DeclsFound),
- decl_iterator(DeclsFound + NumDeclsFound));
+ return decl_range(decl_iterator(DeclsFound.get()),
+ decl_iterator(DeclsFound.get() + NumDeclsFound));
}
/// isAmbiguous - Determines whether the set of paths provided is
@@ -85,9 +85,14 @@ bool CXXRecordDecl::isDerivedFrom(const CXXRecordDecl *Base,
return false;
Paths.setOrigin(const_cast<CXXRecordDecl*>(this));
- return lookupInBases(&FindBaseClass,
- const_cast<CXXRecordDecl*>(Base->getCanonicalDecl()),
- Paths);
+
+ const CXXRecordDecl *BaseDecl = Base->getCanonicalDecl();
+ // FIXME: Capturing 'this' is a workaround for name lookup bugs in GCC 4.7.
+ return lookupInBases(
+ [this, BaseDecl](const CXXBaseSpecifier *Specifier, CXXBasePath &Path) {
+ return FindBaseClass(Specifier, Path, BaseDecl);
+ },
+ Paths);
}
bool CXXRecordDecl::isVirtuallyDerivedFrom(const CXXRecordDecl *Base) const {
@@ -102,20 +107,20 @@ bool CXXRecordDecl::isVirtuallyDerivedFrom(const CXXRecordDecl *Base) const {
Paths.setOrigin(const_cast<CXXRecordDecl*>(this));
- const void *BasePtr = static_cast<const void*>(Base->getCanonicalDecl());
- return lookupInBases(&FindVirtualBaseClass,
- const_cast<void *>(BasePtr),
- Paths);
-}
-
-static bool BaseIsNot(const CXXRecordDecl *Base, void *OpaqueTarget) {
- // OpaqueTarget is a CXXRecordDecl*.
- return Base->getCanonicalDecl() != (const CXXRecordDecl*) OpaqueTarget;
+ const CXXRecordDecl *BaseDecl = Base->getCanonicalDecl();
+ // FIXME: Capturing 'this' is a workaround for name lookup bugs in GCC 4.7.
+ return lookupInBases(
+ [this, BaseDecl](const CXXBaseSpecifier *Specifier, CXXBasePath &Path) {
+ return FindVirtualBaseClass(Specifier, Path, BaseDecl);
+ },
+ Paths);
}
bool CXXRecordDecl::isProvablyNotDerivedFrom(const CXXRecordDecl *Base) const {
- return forallBases(BaseIsNot,
- const_cast<CXXRecordDecl *>(Base->getCanonicalDecl()));
+ const CXXRecordDecl *TargetDecl = Base->getCanonicalDecl();
+ return forallBases([TargetDecl](const CXXRecordDecl *Base) {
+ return Base->getCanonicalDecl() != TargetDecl;
+ });
}
bool
@@ -129,8 +134,7 @@ CXXRecordDecl::isCurrentInstantiation(const DeclContext *CurContext) const {
return false;
}
-bool CXXRecordDecl::forallBases(ForallBasesCallback *BaseMatches,
- void *OpaqueData,
+bool CXXRecordDecl::forallBases(ForallBasesCallback BaseMatches,
bool AllowShortCircuit) const {
SmallVector<const CXXRecordDecl*, 8> Queue;
@@ -156,7 +160,7 @@ bool CXXRecordDecl::forallBases(ForallBasesCallback *BaseMatches,
}
Queue.push_back(Base);
- if (!BaseMatches(Base, OpaqueData)) {
+ if (!BaseMatches(Base)) {
if (AllowShortCircuit) return false;
AllMatches = false;
continue;
@@ -171,10 +175,9 @@ bool CXXRecordDecl::forallBases(ForallBasesCallback *BaseMatches,
return AllMatches;
}
-bool CXXBasePaths::lookupInBases(ASTContext &Context,
- const CXXRecordDecl *Record,
- CXXRecordDecl::BaseMatchesCallback *BaseMatches,
- void *UserData) {
+bool CXXBasePaths::lookupInBases(
+ ASTContext &Context, const CXXRecordDecl *Record,
+ CXXRecordDecl::BaseMatchesCallback BaseMatches) {
bool FoundPath = false;
// The access of the path down to this record.
@@ -248,7 +251,7 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context,
// Track whether there's a path involving this specific base.
bool FoundPathThroughBase = false;
- if (BaseMatches(&BaseSpec, ScratchPath, UserData)) {
+ if (BaseMatches(&BaseSpec, ScratchPath)) {
// We've found a path that terminates at this base.
FoundPath = FoundPathThroughBase = true;
if (isRecordingPaths()) {
@@ -263,7 +266,7 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context,
CXXRecordDecl *BaseRecord
= cast<CXXRecordDecl>(BaseSpec.getType()->castAs<RecordType>()
->getDecl());
- if (lookupInBases(Context, BaseRecord, BaseMatches, UserData)) {
+ if (lookupInBases(Context, BaseRecord, BaseMatches)) {
// C++ [class.member.lookup]p2:
// A member name f in one sub-object B hides a member name f in
// a sub-object A if A is a base class sub-object of B. Any
@@ -296,11 +299,10 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context,
return FoundPath;
}
-bool CXXRecordDecl::lookupInBases(BaseMatchesCallback *BaseMatches,
- void *UserData,
+bool CXXRecordDecl::lookupInBases(BaseMatchesCallback BaseMatches,
CXXBasePaths &Paths) const {
// If we didn't find anything, report that.
- if (!Paths.lookupInBases(getASTContext(), this, BaseMatches, UserData))
+ if (!Paths.lookupInBases(getASTContext(), this, BaseMatches))
return false;
// If we're not recording paths or we won't ever find ambiguities,
@@ -353,8 +355,8 @@ bool CXXRecordDecl::lookupInBases(BaseMatchesCallback *BaseMatches,
bool CXXRecordDecl::FindBaseClass(const CXXBaseSpecifier *Specifier,
CXXBasePath &Path,
- void *BaseRecord) {
- assert(((Decl *)BaseRecord)->getCanonicalDecl() == BaseRecord &&
+ const CXXRecordDecl *BaseRecord) {
+ assert(BaseRecord->getCanonicalDecl() == BaseRecord &&
"User data for FindBaseClass is not canonical!");
return Specifier->getType()->castAs<RecordType>()->getDecl()
->getCanonicalDecl() == BaseRecord;
@@ -362,8 +364,8 @@ bool CXXRecordDecl::FindBaseClass(const CXXBaseSpecifier *Specifier,
bool CXXRecordDecl::FindVirtualBaseClass(const CXXBaseSpecifier *Specifier,
CXXBasePath &Path,
- void *BaseRecord) {
- assert(((Decl *)BaseRecord)->getCanonicalDecl() == BaseRecord &&
+ const CXXRecordDecl *BaseRecord) {
+ assert(BaseRecord->getCanonicalDecl() == BaseRecord &&
"User data for FindBaseClass is not canonical!");
return Specifier->isVirtual() &&
Specifier->getType()->castAs<RecordType>()->getDecl()
@@ -372,12 +374,11 @@ bool CXXRecordDecl::FindVirtualBaseClass(const CXXBaseSpecifier *Specifier,
bool CXXRecordDecl::FindTagMember(const CXXBaseSpecifier *Specifier,
CXXBasePath &Path,
- void *Name) {
+ DeclarationName Name) {
RecordDecl *BaseRecord =
Specifier->getType()->castAs<RecordType>()->getDecl();
- DeclarationName N = DeclarationName::getFromOpaquePtr(Name);
- for (Path.Decls = BaseRecord->lookup(N);
+ for (Path.Decls = BaseRecord->lookup(Name);
!Path.Decls.empty();
Path.Decls = Path.Decls.slice(1)) {
if (Path.Decls.front()->isInIdentifierNamespace(IDNS_Tag))
@@ -389,13 +390,12 @@ bool CXXRecordDecl::FindTagMember(const CXXBaseSpecifier *Specifier,
bool CXXRecordDecl::FindOrdinaryMember(const CXXBaseSpecifier *Specifier,
CXXBasePath &Path,
- void *Name) {
+ DeclarationName Name) {
RecordDecl *BaseRecord =
Specifier->getType()->castAs<RecordType>()->getDecl();
const unsigned IDNS = IDNS_Ordinary | IDNS_Tag | IDNS_Member;
- DeclarationName N = DeclarationName::getFromOpaquePtr(Name);
- for (Path.Decls = BaseRecord->lookup(N);
+ for (Path.Decls = BaseRecord->lookup(Name);
!Path.Decls.empty();
Path.Decls = Path.Decls.slice(1)) {
if (Path.Decls.front()->isInIdentifierNamespace(IDNS))
@@ -408,12 +408,11 @@ bool CXXRecordDecl::FindOrdinaryMember(const CXXBaseSpecifier *Specifier,
bool CXXRecordDecl::
FindNestedNameSpecifierMember(const CXXBaseSpecifier *Specifier,
CXXBasePath &Path,
- void *Name) {
+ DeclarationName Name) {
RecordDecl *BaseRecord =
Specifier->getType()->castAs<RecordType>()->getDecl();
- DeclarationName N = DeclarationName::getFromOpaquePtr(Name);
- for (Path.Decls = BaseRecord->lookup(N);
+ for (Path.Decls = BaseRecord->lookup(Name);
!Path.Decls.empty();
Path.Decls = Path.Decls.slice(1)) {
// FIXME: Refactor the "is it a nested-name-specifier?" check
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index ea4b2f517cd0..42bebc543e3e 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -207,13 +207,13 @@ static Optional<Visibility> getVisibilityOf(const NamedDecl *D,
// If we're ultimately computing the visibility of a type, look for
// a 'type_visibility' attribute before looking for 'visibility'.
if (kind == NamedDecl::VisibilityForType) {
- if (const TypeVisibilityAttr *A = D->getAttr<TypeVisibilityAttr>()) {
+ if (const auto *A = D->getAttr<TypeVisibilityAttr>()) {
return getVisibilityFromAttr(A);
}
}
// If this declaration has an explicit visibility attribute, use it.
- if (const VisibilityAttr *A = D->getAttr<VisibilityAttr>()) {
+ if (const auto *A = D->getAttr<VisibilityAttr>()) {
return getVisibilityFromAttr(A);
}
@@ -252,8 +252,7 @@ getLVForTemplateParameterList(const TemplateParameterList *Params,
// template <enum X> class A { ... };
// We have to be careful here, though, because we can be dealing with
// dependent types.
- if (const NonTypeTemplateParmDecl *NTTP =
- dyn_cast<NonTypeTemplateParmDecl>(P)) {
+ if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
// Handle the non-pack case first.
if (!NTTP->isExpandedParameterPack()) {
if (!NTTP->getType()->isDependentType()) {
@@ -273,7 +272,7 @@ getLVForTemplateParameterList(const TemplateParameterList *Params,
// Template template parameters can be restricted by their
// template parameters, recursively.
- const TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(P);
+ const auto *TTP = cast<TemplateTemplateParmDecl>(P);
// Handle the non-pack case first.
if (!TTP->isExpandedParameterPack()) {
@@ -329,7 +328,7 @@ static LinkageInfo getLVForTemplateArgumentList(ArrayRef<TemplateArgument> Args,
continue;
case TemplateArgument::Declaration:
- if (NamedDecl *ND = dyn_cast<NamedDecl>(Arg.getAsDecl())) {
+ if (const auto *ND = dyn_cast<NamedDecl>(Arg.getAsDecl())) {
assert(!usesTypeVisibility(ND));
LV.merge(getLVForDecl(ND, computation));
}
@@ -541,7 +540,7 @@ static bool useInlineVisibilityHidden(const NamedDecl *D) {
if (!Opts.CPlusPlus || !Opts.InlineVisibilityHidden)
return false;
- const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
+ const auto *FD = dyn_cast<FunctionDecl>(D);
if (!FD)
return false;
@@ -569,7 +568,7 @@ template <typename T> static bool isFirstInExternCContext(T *D) {
}
static bool isSingleLineLanguageLinkage(const Decl &D) {
- if (const LinkageSpecDecl *SD = dyn_cast<LinkageSpecDecl>(D.getDeclContext()))
+ if (const auto *SD = dyn_cast<LinkageSpecDecl>(D.getDeclContext()))
if (!SD->hasBraces())
return true;
return false;
@@ -587,7 +586,7 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
// - an object, reference, function or function template that is
// explicitly declared static; or,
// (This bullet corresponds to C99 6.2.2p3.)
- if (const VarDecl *Var = dyn_cast<VarDecl>(D)) {
+ if (const auto *Var = dyn_cast<VarDecl>(D)) {
// Explicitly declared static.
if (Var->getStorageClass() == SC_Static)
return LinkageInfo::internal();
@@ -634,8 +633,10 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
assert(!isa<FieldDecl>(D) && "Didn't expect a FieldDecl!");
if (D->isInAnonymousNamespace()) {
- const VarDecl *Var = dyn_cast<VarDecl>(D);
- const FunctionDecl *Func = dyn_cast<FunctionDecl>(D);
+ const auto *Var = dyn_cast<VarDecl>(D);
+ const auto *Func = dyn_cast<FunctionDecl>(D);
+ // FIXME: In C++11 onwards, anonymous namespaces should give decls
+ // within them internal linkage, not unique external linkage.
if ((!Var || !isFirstInExternCContext(Var)) &&
(!Func || !isFirstInExternCContext(Func)))
return LinkageInfo::uniqueExternal();
@@ -658,7 +659,7 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
for (const DeclContext *DC = D->getDeclContext();
!isa<TranslationUnitDecl>(DC);
DC = DC->getParent()) {
- const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(DC);
+ const auto *ND = dyn_cast<NamespaceDecl>(DC);
if (!ND) continue;
if (Optional<Visibility> Vis = getExplicitVisibility(ND, computation)) {
LV.mergeVisibility(*Vis, true);
@@ -692,7 +693,7 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
// name of
//
// - an object or reference, unless it has internal linkage; or
- if (const VarDecl *Var = dyn_cast<VarDecl>(D)) {
+ if (const auto *Var = dyn_cast<VarDecl>(D)) {
// GCC applies the following optimization to variables and static
// data members, but not to functions:
//
@@ -732,13 +733,12 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
// As per function and class template specializations (below),
// consider LV for the template and template arguments. We're at file
// scope, so we do not need to worry about nested specializations.
- if (const VarTemplateSpecializationDecl *spec
- = dyn_cast<VarTemplateSpecializationDecl>(Var)) {
+ if (const auto *spec = dyn_cast<VarTemplateSpecializationDecl>(Var)) {
mergeTemplateLV(LV, spec, computation);
}
// - a function, unless it has internal linkage; or
- } else if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
+ } else if (const auto *Function = dyn_cast<FunctionDecl>(D)) {
// In theory, we can modify the function's LV by the LV of its
// type unless it has C linkage (see comment above about variables
// for justification). In practice, GCC doesn't do this, so it's
@@ -785,7 +785,7 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
// - a named enumeration (7.2), or an unnamed enumeration
// defined in a typedef declaration in which the enumeration
// has the typedef name for linkage purposes (7.1.3); or
- } else if (const TagDecl *Tag = dyn_cast<TagDecl>(D)) {
+ } else if (const auto *Tag = dyn_cast<TagDecl>(D)) {
// Unnamed tags have no linkage.
if (!Tag->hasNameForLinkage())
return LinkageInfo::none();
@@ -793,8 +793,7 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
// If this is a class template specialization, consider the
// linkage of the template and template arguments. We're at file
// scope, so we do not need to worry about nested specializations.
- if (const ClassTemplateSpecializationDecl *spec
- = dyn_cast<ClassTemplateSpecializationDecl>(Tag)) {
+ if (const auto *spec = dyn_cast<ClassTemplateSpecializationDecl>(Tag)) {
mergeTemplateLV(LV, spec, computation);
}
@@ -808,7 +807,7 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
// - a template, unless it is a function template that has
// internal linkage (Clause 14);
- } else if (const TemplateDecl *temp = dyn_cast<TemplateDecl>(D)) {
+ } else if (const auto *temp = dyn_cast<TemplateDecl>(D)) {
bool considerVisibility = !hasExplicitVisibilityAlready(computation);
LinkageInfo tempLV =
getLVForTemplateParameterList(temp->getTemplateParameters(), computation);
@@ -824,10 +823,14 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
} else if (isa<ObjCInterfaceDecl>(D)) {
// fallout
+ } else if (auto *TD = dyn_cast<TypedefNameDecl>(D)) {
+ // A typedef declaration has linkage if it gives a type a name for
+ // linkage purposes.
+ if (!TD->getAnonDeclWithTypedefName(/*AnyRedecl*/true))
+ return LinkageInfo::none();
+
// Everything not covered here has no linkage.
} else {
- // FIXME: A typedef declaration has linkage if it gives a type a name for
- // linkage purposes.
return LinkageInfo::none();
}
@@ -897,7 +900,7 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D,
// Specifically, if this decl exists and has an explicit attribute.
const NamedDecl *explicitSpecSuppressor = nullptr;
- if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
+ if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
// If the type of the function uses a type with unique-external
// linkage, it's not legally usable from outside this translation unit.
// But only look at the type-as-written. If this function has an
@@ -928,9 +931,8 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D,
explicitSpecSuppressor = MD;
}
- } else if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
- if (const ClassTemplateSpecializationDecl *spec
- = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
+ } else if (const auto *RD = dyn_cast<CXXRecordDecl>(D)) {
+ if (const auto *spec = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
mergeTemplateLV(LV, spec, computation);
if (spec->isExplicitSpecialization()) {
explicitSpecSuppressor = spec;
@@ -945,9 +947,8 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D,
}
// Static data members.
- } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
- if (const VarTemplateSpecializationDecl *spec
- = dyn_cast<VarTemplateSpecializationDecl>(VD))
+ } else if (const auto *VD = dyn_cast<VarDecl>(D)) {
+ if (const auto *spec = dyn_cast<VarTemplateSpecializationDecl>(VD))
mergeTemplateLV(LV, spec, computation);
// Modify the variable's linkage by its type, but ignore the
@@ -962,7 +963,7 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D,
}
// Template members.
- } else if (const TemplateDecl *temp = dyn_cast<TemplateDecl>(D)) {
+ } else if (const auto *temp = dyn_cast<TemplateDecl>(D)) {
bool considerVisibility =
(!LV.isVisibilityExplicit() &&
!classLV.isVisibilityExplicit() &&
@@ -971,8 +972,7 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D,
getLVForTemplateParameterList(temp->getTemplateParameters(), computation);
LV.mergeMaybeWithVisibility(tempLV, considerVisibility);
- if (const RedeclarableTemplateDecl *redeclTemp =
- dyn_cast<RedeclarableTemplateDecl>(temp)) {
+ if (const auto *redeclTemp = dyn_cast<RedeclarableTemplateDecl>(temp)) {
if (isExplicitMemberSpecialization(redeclTemp)) {
explicitSpecSuppressor = temp->getTemplatedDecl();
}
@@ -1048,7 +1048,7 @@ getExplicitVisibilityAux(const NamedDecl *ND,
// If this is a member class of a specialization of a class template
// and the corresponding decl has explicit visibility, use that.
- if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(ND)) {
+ if (const auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
CXXRecordDecl *InstantiatedFrom = RD->getInstantiatedFromMemberClass();
if (InstantiatedFrom)
return getVisibilityOf(InstantiatedFrom, kind);
@@ -1057,8 +1057,7 @@ getExplicitVisibilityAux(const NamedDecl *ND,
// If there wasn't explicit visibility there, and this is a
// specialization of a class template, check for visibility
// on the pattern.
- if (const ClassTemplateSpecializationDecl *spec
- = dyn_cast<ClassTemplateSpecializationDecl>(ND))
+ if (const auto *spec = dyn_cast<ClassTemplateSpecializationDecl>(ND))
return getVisibilityOf(spec->getSpecializedTemplate()->getTemplatedDecl(),
kind);
@@ -1069,7 +1068,7 @@ getExplicitVisibilityAux(const NamedDecl *ND,
return getExplicitVisibilityAux(MostRecent, kind, true);
}
- if (const VarDecl *Var = dyn_cast<VarDecl>(ND)) {
+ if (const auto *Var = dyn_cast<VarDecl>(ND)) {
if (Var->isStaticDataMember()) {
VarDecl *InstantiatedFrom = Var->getInstantiatedFromStaticDataMember();
if (InstantiatedFrom)
@@ -1083,7 +1082,7 @@ getExplicitVisibilityAux(const NamedDecl *ND,
return None;
}
// Also handle function template specializations.
- if (const FunctionDecl *fn = dyn_cast<FunctionDecl>(ND)) {
+ if (const auto *fn = dyn_cast<FunctionDecl>(ND)) {
// If the function is a specialization of a template with an
// explicit visibility attribute, use that.
if (FunctionTemplateSpecializationInfo *templateInfo
@@ -1101,7 +1100,7 @@ getExplicitVisibilityAux(const NamedDecl *ND,
}
// The visibility of a template is stored in the templated decl.
- if (const TemplateDecl *TD = dyn_cast<TemplateDecl>(ND))
+ if (const auto *TD = dyn_cast<TemplateDecl>(ND))
return getVisibilityOf(TD->getTemplatedDecl(), kind);
return None;
@@ -1122,7 +1121,7 @@ static LinkageInfo getLVForClosure(const DeclContext *DC, Decl *ContextDecl,
return getLVForDecl(cast<NamedDecl>(ContextDecl), computation);
}
- if (const NamedDecl *ND = dyn_cast<NamedDecl>(DC))
+ if (const auto *ND = dyn_cast<NamedDecl>(DC))
return getLVForDecl(ND, computation);
return LinkageInfo::external();
@@ -1130,7 +1129,7 @@ static LinkageInfo getLVForClosure(const DeclContext *DC, Decl *ContextDecl,
static LinkageInfo getLVForLocalDecl(const NamedDecl *D,
LVComputationKind computation) {
- if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
+ if (const auto *Function = dyn_cast<FunctionDecl>(D)) {
if (Function->isInAnonymousNamespace() &&
!Function->isInExternCContext())
return LinkageInfo::uniqueExternal();
@@ -1153,7 +1152,7 @@ static LinkageInfo getLVForLocalDecl(const NamedDecl *D,
return LV;
}
- if (const VarDecl *Var = dyn_cast<VarDecl>(D)) {
+ if (const auto *Var = dyn_cast<VarDecl>(D)) {
if (Var->hasExternalStorage()) {
if (Var->isInAnonymousNamespace() && !Var->isInExternCContext())
return LinkageInfo::uniqueExternal();
@@ -1189,14 +1188,14 @@ static LinkageInfo getLVForLocalDecl(const NamedDecl *D,
return LinkageInfo::none();
LinkageInfo LV;
- if (const BlockDecl *BD = dyn_cast<BlockDecl>(OuterD)) {
+ if (const auto *BD = dyn_cast<BlockDecl>(OuterD)) {
if (!BD->getBlockManglingNumber())
return LinkageInfo::none();
LV = getLVForClosure(BD->getDeclContext()->getRedeclContext(),
BD->getBlockManglingContextDecl(), computation);
} else {
- const FunctionDecl *FD = cast<FunctionDecl>(OuterD);
+ const auto *FD = cast<FunctionDecl>(OuterD);
if (!FD->isInlined() &&
!isTemplateInstantiation(FD->getTemplateSpecializationKind()))
return LinkageInfo::none();
@@ -1224,13 +1223,45 @@ getOutermostEnclosingLambda(const CXXRecordDecl *Record) {
static LinkageInfo computeLVForDecl(const NamedDecl *D,
LVComputationKind computation) {
+ // Internal_linkage attribute overrides other considerations.
+ if (D->hasAttr<InternalLinkageAttr>())
+ return LinkageInfo::internal();
+
// Objective-C: treat all Objective-C declarations as having external
// linkage.
switch (D->getKind()) {
default:
break;
+
+ // Per C++ [basic.link]p2, only the names of objects, references,
+ // functions, types, templates, namespaces, and values ever have linkage.
+ //
+ // Note that the name of a typedef, namespace alias, using declaration,
+ // and so on are not the name of the corresponding type, namespace, or
+ // declaration, so they do *not* have linkage.
+ case Decl::ImplicitParam:
+ case Decl::Label:
+ case Decl::NamespaceAlias:
case Decl::ParmVar:
+ case Decl::Using:
+ case Decl::UsingShadow:
+ case Decl::UsingDirective:
return LinkageInfo::none();
+
+ case Decl::EnumConstant:
+ // C++ [basic.link]p4: an enumerator has the linkage of its enumeration.
+ return getLVForDecl(cast<EnumDecl>(D->getDeclContext()), computation);
+
+ case Decl::Typedef:
+ case Decl::TypeAlias:
+ // A typedef declaration has linkage if it gives a type a name for
+ // linkage purposes.
+ if (!D->getASTContext().getLangOpts().CPlusPlus ||
+ !cast<TypedefNameDecl>(D)
+ ->getAnonDeclWithTypedefName(/*AnyRedecl*/true))
+ return LinkageInfo::none();
+ break;
+
case Decl::TemplateTemplateParm: // count these as external
case Decl::NonTypeTemplateParm:
case Decl::ObjCAtDefsField:
@@ -1245,7 +1276,7 @@ static LinkageInfo computeLVForDecl(const NamedDecl *D,
return LinkageInfo::external();
case Decl::CXXRecord: {
- const CXXRecordDecl *Record = cast<CXXRecordDecl>(D);
+ const auto *Record = cast<CXXRecordDecl>(D);
if (Record->isLambda()) {
if (!Record->getLambdaManglingNumber()) {
// This lambda has no mangling number, so it's internal.
@@ -1314,6 +1345,10 @@ class LinkageComputer {
public:
static LinkageInfo getLVForDecl(const NamedDecl *D,
LVComputationKind computation) {
+ // Internal_linkage attribute overrides other considerations.
+ if (D->hasAttr<InternalLinkageAttr>())
+ return LinkageInfo::internal();
+
if (computation == LVForLinkageOnly && D->hasCachedLinkage())
return LinkageInfo(D->getCachedLinkage(), DefaultVisibility, false);
@@ -1336,7 +1371,7 @@ public:
// computed also does.
NamedDecl *Old = nullptr;
for (auto I : D->redecls()) {
- NamedDecl *T = cast<NamedDecl>(I);
+ auto *T = cast<NamedDecl>(I);
if (T == D)
continue;
if (!T->isInvalidDecl() && T->hasCachedLinkage()) {
@@ -1388,28 +1423,29 @@ void NamedDecl::printQualifiedName(raw_ostream &OS,
for (ContextsTy::reverse_iterator I = Contexts.rbegin(), E = Contexts.rend();
I != E; ++I) {
- if (const ClassTemplateSpecializationDecl *Spec
- = dyn_cast<ClassTemplateSpecializationDecl>(*I)) {
+ if (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(*I)) {
OS << Spec->getName();
const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
TemplateSpecializationType::PrintTemplateArgumentList(OS,
TemplateArgs.data(),
TemplateArgs.size(),
P);
- } else if (const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(*I)) {
+ } else if (const auto *ND = dyn_cast<NamespaceDecl>(*I)) {
if (P.SuppressUnwrittenScope &&
(ND->isAnonymousNamespace() || ND->isInline()))
continue;
- if (ND->isAnonymousNamespace())
- OS << "(anonymous namespace)";
+ if (ND->isAnonymousNamespace()) {
+ OS << (P.MSVCFormatting ? "`anonymous namespace\'"
+ : "(anonymous namespace)");
+ }
else
OS << *ND;
- } else if (const RecordDecl *RD = dyn_cast<RecordDecl>(*I)) {
+ } else if (const auto *RD = dyn_cast<RecordDecl>(*I)) {
if (!RD->getIdentifier())
OS << "(anonymous " << RD->getKindName() << ')';
else
OS << *RD;
- } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*I)) {
+ } else if (const auto *FD = dyn_cast<FunctionDecl>(*I)) {
const FunctionProtoType *FT = nullptr;
if (FD->hasWrittenPrototype())
FT = dyn_cast<FunctionProtoType>(FD->getType()->castAs<FunctionType>());
@@ -1430,6 +1466,15 @@ void NamedDecl::printQualifiedName(raw_ostream &OS,
}
}
OS << ')';
+ } else if (const auto *ED = dyn_cast<EnumDecl>(*I)) {
+ // C++ [dcl.enum]p10: Each enum-name and each unscoped
+ // enumerator is declared in the scope that immediately contains
+ // the enum-specifier. Each scoped enumerator is declared in the
+ // scope of the enumeration.
+ if (ED->isScoped() || ED->getIdentifier())
+ OS << *ED;
+ else
+ continue;
} else {
OS << *cast<NamedDecl>(*I);
}
@@ -1451,32 +1496,6 @@ void NamedDecl::getNameForDiagnostic(raw_ostream &OS,
printName(OS);
}
-static bool isKindReplaceableBy(Decl::Kind OldK, Decl::Kind NewK) {
- // For method declarations, we never replace.
- if (ObjCMethodDecl::classofKind(NewK))
- return false;
-
- if (OldK == NewK)
- return true;
-
- // A compatibility alias for a class can be replaced by an interface.
- if (ObjCCompatibleAliasDecl::classofKind(OldK) &&
- ObjCInterfaceDecl::classofKind(NewK))
- return true;
-
- // A typedef-declaration, alias-declaration, or Objective-C class declaration
- // can replace another declaration of the same type. Semantic analysis checks
- // that we have matching types.
- if ((TypedefNameDecl::classofKind(OldK) ||
- ObjCInterfaceDecl::classofKind(OldK)) &&
- (TypedefNameDecl::classofKind(NewK) ||
- ObjCInterfaceDecl::classofKind(NewK)))
- return true;
-
- // Otherwise, a kind mismatch implies that the declaration is not replaced.
- return false;
-}
-
template<typename T> static bool isRedeclarableImpl(Redeclarable<T> *) {
return true;
}
@@ -1500,9 +1519,19 @@ bool NamedDecl::declarationReplaces(NamedDecl *OldD, bool IsKnownNewer) const {
if (OldD->isFromASTFile() && isFromASTFile())
return false;
- if (!isKindReplaceableBy(OldD->getKind(), getKind()))
+ // A kind mismatch implies that the declaration is not replaced.
+ if (OldD->getKind() != getKind())
+ return false;
+
+ // For method declarations, we never replace. (Why?)
+ if (isa<ObjCMethodDecl>(this))
return false;
+ // For parameters, pick the newer one. This is either an error or (in
+ // Objective-C) permitted as an extension.
+ if (isa<ParmVarDecl>(this))
+ return true;
+
// Inline namespaces can give us two declarations with the same
// name and kind in the same scope but different contexts; we should
// keep both declarations in this case.
@@ -1510,28 +1539,8 @@ bool NamedDecl::declarationReplaces(NamedDecl *OldD, bool IsKnownNewer) const {
OldD->getDeclContext()->getRedeclContext()))
return false;
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(this))
- // For function declarations, we keep track of redeclarations.
- // FIXME: This returns false for functions that should in fact be replaced.
- // Instead, perform some kind of type check?
- if (FD->getPreviousDecl() != OldD)
- return false;
-
- // For function templates, the underlying function declarations are linked.
- if (const FunctionTemplateDecl *FunctionTemplate =
- dyn_cast<FunctionTemplateDecl>(this))
- return FunctionTemplate->getTemplatedDecl()->declarationReplaces(
- cast<FunctionTemplateDecl>(OldD)->getTemplatedDecl());
-
- // Using shadow declarations can be overloaded on their target declarations
- // if they introduce functions.
- // FIXME: If our target replaces the old target, can we replace the old
- // shadow declaration?
- if (auto *USD = dyn_cast<UsingShadowDecl>(this))
- if (USD->getTargetDecl() != cast<UsingShadowDecl>(OldD)->getTargetDecl())
- return false;
-
- // Using declarations can be overloaded if they introduce functions.
+ // Using declarations can be replaced if they import the same name from the
+ // same context.
if (auto *UD = dyn_cast<UsingDecl>(this)) {
ASTContext &Context = getASTContext();
return Context.getCanonicalNestedNameSpecifier(UD->getQualifier()) ==
@@ -1546,13 +1555,20 @@ bool NamedDecl::declarationReplaces(NamedDecl *OldD, bool IsKnownNewer) const {
}
// UsingDirectiveDecl's are not really NamedDecl's, and all have same name.
- // We want to keep it, unless it nominates same namespace.
+ // They can be replaced if they nominate the same namespace.
+ // FIXME: Is this true even if they have different module visibility?
if (auto *UD = dyn_cast<UsingDirectiveDecl>(this))
return UD->getNominatedNamespace()->getOriginalNamespace() ==
cast<UsingDirectiveDecl>(OldD)->getNominatedNamespace()
->getOriginalNamespace();
- if (!IsKnownNewer && isRedeclarable(getKind())) {
+ if (isRedeclarable(getKind())) {
+ if (getCanonicalDecl() != OldD->getCanonicalDecl())
+ return false;
+
+ if (IsKnownNewer)
+ return true;
+
// Check whether this is actually newer than OldD. We want to keep the
// newer declaration. This loop will usually only iterate once, because
// OldD is usually the previous declaration.
@@ -1567,11 +1583,16 @@ bool NamedDecl::declarationReplaces(NamedDecl *OldD, bool IsKnownNewer) const {
if (D->isCanonicalDecl())
return false;
}
+
+ // It's a newer declaration of the same kind of declaration in the same
+ // scope: we want this decl instead of the existing one.
+ return true;
}
- // It's a newer declaration of the same kind of declaration in the same scope,
- // and not an overload: we want this decl instead of the existing one.
- return true;
+ // In all other cases, we need to keep both declarations in case they have
+ // different visibility. Any attempt to use the name will result in an
+ // ambiguity if more than one is visible.
+ return false;
}
bool NamedDecl::hasLinkage() const {
@@ -1580,12 +1601,15 @@ bool NamedDecl::hasLinkage() const {
NamedDecl *NamedDecl::getUnderlyingDeclImpl() {
NamedDecl *ND = this;
- while (UsingShadowDecl *UD = dyn_cast<UsingShadowDecl>(ND))
+ while (auto *UD = dyn_cast<UsingShadowDecl>(ND))
ND = UD->getTargetDecl();
- if (ObjCCompatibleAliasDecl *AD = dyn_cast<ObjCCompatibleAliasDecl>(ND))
+ if (auto *AD = dyn_cast<ObjCCompatibleAliasDecl>(ND))
return AD->getClassInterface();
+ if (auto *AD = dyn_cast<NamespaceAliasDecl>(ND))
+ return AD->getNamespace();
+
return ND;
}
@@ -1599,8 +1623,7 @@ bool NamedDecl::isCXXInstanceMember() const {
if (isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D) || isa<MSPropertyDecl>(D))
return true;
- if (const CXXMethodDecl *MD =
- dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()))
+ if (const auto *MD = dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()))
return MD->isInstance();
return false;
}
@@ -1628,7 +1651,7 @@ void DeclaratorDecl::setQualifierInfo(NestedNameSpecifierLoc QualifierLoc) {
// Make sure the extended decl info is allocated.
if (!hasExtInfo()) {
// Save (non-extended) type source info pointer.
- TypeSourceInfo *savedTInfo = DeclInfo.get<TypeSourceInfo*>();
+ auto *savedTInfo = DeclInfo.get<TypeSourceInfo*>();
// Allocate external info struct.
DeclInfo = new (getASTContext()) ExtInfo;
// Restore savedTInfo into (extended) decl info.
@@ -1653,22 +1676,20 @@ void DeclaratorDecl::setQualifierInfo(NestedNameSpecifierLoc QualifierLoc) {
}
}
-void
-DeclaratorDecl::setTemplateParameterListsInfo(ASTContext &Context,
- unsigned NumTPLists,
- TemplateParameterList **TPLists) {
- assert(NumTPLists > 0);
+void DeclaratorDecl::setTemplateParameterListsInfo(
+ ASTContext &Context, ArrayRef<TemplateParameterList *> TPLists) {
+ assert(!TPLists.empty());
// Make sure the extended decl info is allocated.
if (!hasExtInfo()) {
// Save (non-extended) type source info pointer.
- TypeSourceInfo *savedTInfo = DeclInfo.get<TypeSourceInfo*>();
+ auto *savedTInfo = DeclInfo.get<TypeSourceInfo*>();
// Allocate external info struct.
DeclInfo = new (getASTContext()) ExtInfo;
// Restore savedTInfo into (extended) decl info.
getExtInfo()->TInfo = savedTInfo;
}
// Set the template parameter lists info.
- getExtInfo()->setTemplateParameterListsInfo(Context, NumTPLists, TPLists);
+ getExtInfo()->setTemplateParameterListsInfo(Context, TPLists);
}
SourceLocation DeclaratorDecl::getOuterLocStart() const {
@@ -1726,13 +1747,8 @@ SourceRange DeclaratorDecl::getSourceRange() const {
return SourceRange(getOuterLocStart(), RangeEnd);
}
-void
-QualifierInfo::setTemplateParameterListsInfo(ASTContext &Context,
- unsigned NumTPLists,
- TemplateParameterList **TPLists) {
- assert((NumTPLists == 0 || TPLists != nullptr) &&
- "Empty array of template parameters with positive size!");
-
+void QualifierInfo::setTemplateParameterListsInfo(
+ ASTContext &Context, ArrayRef<TemplateParameterList *> TPLists) {
// Free previous template parameters (if any).
if (NumTemplParamLists > 0) {
Context.Deallocate(TemplParamLists);
@@ -1740,10 +1756,10 @@ QualifierInfo::setTemplateParameterListsInfo(ASTContext &Context,
NumTemplParamLists = 0;
}
// Set info on matched template parameter lists (if any).
- if (NumTPLists > 0) {
- TemplParamLists = new (Context) TemplateParameterList*[NumTPLists];
- NumTemplParamLists = NumTPLists;
- std::copy(TPLists, TPLists + NumTPLists, TemplParamLists);
+ if (!TPLists.empty()) {
+ TemplParamLists = new (Context) TemplateParameterList *[TPLists.size()];
+ NumTemplParamLists = TPLists.size();
+ std::copy(TPLists.begin(), TPLists.end(), TemplParamLists);
}
}
@@ -1756,7 +1772,6 @@ const char *VarDecl::getStorageClassSpecifierString(StorageClass SC) {
case SC_None: break;
case SC_Auto: return "auto";
case SC_Extern: return "extern";
- case SC_OpenCLWorkGroupLocal: return "<<work-group-local>>";
case SC_PrivateExtern: return "__private_extern__";
case SC_Register: return "register";
case SC_Static: return "static";
@@ -1995,7 +2010,7 @@ VarDecl *VarDecl::getDefinition(ASTContext &C) {
VarDecl::DefinitionKind VarDecl::hasDefinition(ASTContext &C) const {
DefinitionKind Kind = DeclarationOnly;
-
+
const VarDecl *First = getFirstDecl();
for (auto I : First->redecls()) {
Kind = std::max(Kind, I->isThisDeclarationADefinition(C));
@@ -2016,6 +2031,31 @@ const Expr *VarDecl::getAnyInitializer(const VarDecl *&D) const {
return nullptr;
}
+bool VarDecl::hasInit() const {
+ if (auto *P = dyn_cast<ParmVarDecl>(this))
+ if (P->hasUnparsedDefaultArg() || P->hasUninstantiatedDefaultArg())
+ return false;
+
+ return !Init.isNull();
+}
+
+Expr *VarDecl::getInit() {
+ if (!hasInit())
+ return nullptr;
+
+ if (auto *S = Init.dyn_cast<Stmt *>())
+ return cast<Expr>(S);
+
+ return cast_or_null<Expr>(Init.get<EvaluatedStmt *>()->Value);
+}
+
+Stmt **VarDecl::getInitAddress() {
+ if (auto *ES = Init.dyn_cast<EvaluatedStmt *>())
+ return &ES->Value;
+
+ return Init.getAddrOfPtr1();
+}
+
bool VarDecl::isOutOfLine() const {
if (Decl::isOutOfLine())
return true;
@@ -2045,7 +2085,7 @@ VarDecl *VarDecl::getOutOfLineDefinition() {
}
void VarDecl::setInit(Expr *I) {
- if (EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>()) {
+ if (auto *Eval = Init.dyn_cast<EvaluatedStmt *>()) {
Eval->~EvaluatedStmt();
getASTContext().Deallocate(Eval);
}
@@ -2084,15 +2124,14 @@ bool VarDecl::isUsableInConstantExpressions(ASTContext &C) const {
/// form, which contains extra information on the evaluated value of the
/// initializer.
EvaluatedStmt *VarDecl::ensureEvaluatedStmt() const {
- EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>();
+ auto *Eval = Init.dyn_cast<EvaluatedStmt *>();
if (!Eval) {
- Stmt *S = Init.get<Stmt *>();
// Note: EvaluatedStmt contains an APValue, which usually holds
// resources not allocated from the ASTContext. We need to do some
// work to avoid leaking those, but we do so in VarDecl::evaluateValue
// where we can detect whether there's anything to clean up or not.
Eval = new (getASTContext()) EvaluatedStmt;
- Eval->Value = S;
+ Eval->Value = Init.get<Stmt *>();
Init = Eval;
}
return Eval;
@@ -2120,7 +2159,7 @@ APValue *VarDecl::evaluateValue(
if (Eval->WasEvaluated)
return Eval->Evaluated.isUninit() ? nullptr : &Eval->Evaluated;
- const Expr *Init = cast<Expr>(Eval->Value);
+ const auto *Init = cast<Expr>(Eval->Value);
assert(!Init->isValueDependent());
if (Eval->IsEvaluating) {
@@ -2156,6 +2195,27 @@ APValue *VarDecl::evaluateValue(
return Result ? &Eval->Evaluated : nullptr;
}
+APValue *VarDecl::getEvaluatedValue() const {
+ if (EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>())
+ if (Eval->WasEvaluated)
+ return &Eval->Evaluated;
+
+ return nullptr;
+}
+
+bool VarDecl::isInitKnownICE() const {
+ if (EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>())
+ return Eval->CheckedICE;
+
+ return false;
+}
+
+bool VarDecl::isInitICE() const {
+ assert(isInitKnownICE() &&
+ "Check whether we already know that the initializer is an ICE");
+ return Init.get<EvaluatedStmt *>()->IsICE;
+}
+
bool VarDecl::checkInitIsICE() const {
// Initializers of weak variables are never ICEs.
if (isWeak())
@@ -2167,7 +2227,7 @@ bool VarDecl::checkInitIsICE() const {
// integral constant expression.
return Eval->IsICE;
- const Expr *Init = cast<Expr>(Eval->Value);
+ const auto *Init = cast<Expr>(Eval->Value);
assert(!Init->isValueDependent());
// In C++11, evaluate the initializer to check whether it's a constant
@@ -2200,8 +2260,7 @@ VarDecl *VarDecl::getInstantiatedFromStaticDataMember() const {
}
TemplateSpecializationKind VarDecl::getTemplateSpecializationKind() const {
- if (const VarTemplateSpecializationDecl *Spec =
- dyn_cast<VarTemplateSpecializationDecl>(this))
+ if (const auto *Spec = dyn_cast<VarTemplateSpecializationDecl>(this))
return Spec->getSpecializationKind();
if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo())
@@ -2211,8 +2270,7 @@ TemplateSpecializationKind VarDecl::getTemplateSpecializationKind() const {
}
SourceLocation VarDecl::getPointOfInstantiation() const {
- if (const VarTemplateSpecializationDecl *Spec =
- dyn_cast<VarTemplateSpecializationDecl>(this))
+ if (const auto *Spec = dyn_cast<VarTemplateSpecializationDecl>(this))
return Spec->getPointOfInstantiation();
if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo())
@@ -2285,7 +2343,7 @@ ParmVarDecl *ParmVarDecl::Create(ASTContext &C, DeclContext *DC,
QualType ParmVarDecl::getOriginalType() const {
TypeSourceInfo *TSI = getTypeSourceInfo();
QualType T = TSI ? TSI->getType() : getType();
- if (const DecayedType *DT = dyn_cast<DecayedType>(T))
+ if (const auto *DT = dyn_cast<DecayedType>(T))
return DT->getOriginalType();
return T;
}
@@ -2315,22 +2373,56 @@ Expr *ParmVarDecl::getDefaultArg() {
assert(!hasUnparsedDefaultArg() && "Default argument is not yet parsed!");
assert(!hasUninstantiatedDefaultArg() &&
"Default argument is not yet instantiated!");
-
+
Expr *Arg = getInit();
- if (ExprWithCleanups *E = dyn_cast_or_null<ExprWithCleanups>(Arg))
+ if (auto *E = dyn_cast_or_null<ExprWithCleanups>(Arg))
return E->getSubExpr();
return Arg;
}
+void ParmVarDecl::setDefaultArg(Expr *defarg) {
+ ParmVarDeclBits.DefaultArgKind = DAK_Normal;
+ Init = defarg;
+}
+
SourceRange ParmVarDecl::getDefaultArgRange() const {
- if (const Expr *E = getInit())
- return E->getSourceRange();
+ switch (ParmVarDeclBits.DefaultArgKind) {
+ case DAK_None:
+ case DAK_Unparsed:
+ // Nothing we can do here.
+ return SourceRange();
- if (hasUninstantiatedDefaultArg())
+ case DAK_Uninstantiated:
return getUninstantiatedDefaultArg()->getSourceRange();
- return SourceRange();
+ case DAK_Normal:
+ if (const Expr *E = getInit())
+ return E->getSourceRange();
+
+ // Missing an actual expression, may be invalid.
+ return SourceRange();
+ }
+ llvm_unreachable("Invalid default argument kind.");
+}
+
+void ParmVarDecl::setUninstantiatedDefaultArg(Expr *arg) {
+ ParmVarDeclBits.DefaultArgKind = DAK_Uninstantiated;
+ Init = arg;
+}
+
+Expr *ParmVarDecl::getUninstantiatedDefaultArg() {
+ assert(hasUninstantiatedDefaultArg() &&
+ "Wrong kind of initialization expression!");
+ return cast_or_null<Expr>(Init.get<Stmt *>());
+}
+
+bool ParmVarDecl::hasDefaultArg() const {
+ // FIXME: We should just return false for DAK_None here once callers are
+ // prepared for the case that we encountered an invalid default argument and
+ // were unable to even build an invalid expression.
+ return hasUnparsedDefaultArg() || hasUninstantiatedDefaultArg() ||
+ !Init.isNull();
}
bool ParmVarDecl::isParameterPack() const {
@@ -2360,7 +2452,7 @@ void FunctionDecl::getNameForDiagnostic(
}
bool FunctionDecl::isVariadic() const {
- if (const FunctionProtoType *FT = getType()->getAs<FunctionProtoType>())
+ if (const auto *FT = getType()->getAs<FunctionProtoType>())
return FT->isVariadic();
return false;
}
@@ -2421,7 +2513,7 @@ void FunctionDecl::setBody(Stmt *B) {
void FunctionDecl::setPure(bool P) {
IsPure = P;
if (P)
- if (CXXRecordDecl *Parent = dyn_cast<CXXRecordDecl>(getDeclContext()))
+ if (auto *Parent = dyn_cast<CXXRecordDecl>(getDeclContext()))
Parent->markedVirtualFunctionPure();
}
@@ -2476,7 +2568,7 @@ bool FunctionDecl::isReservedGlobalPlacementOperator() const {
if (!getDeclContext()->getRedeclContext()->isTranslationUnit())
return false;
- const FunctionProtoType *proto = getType()->castAs<FunctionProtoType>();
+ const auto *proto = getType()->castAs<FunctionProtoType>();
if (proto->getNumParams() != 2 || proto->isVariadic())
return false;
@@ -2505,7 +2597,7 @@ bool FunctionDecl::isReplaceableGlobalAllocationFunction() const {
if (!getDeclContext()->getRedeclContext()->isTranslationUnit())
return false;
- const FunctionProtoType *FPT = getType()->castAs<FunctionProtoType>();
+ const auto *FPT = getType()->castAs<FunctionProtoType>();
if (FPT->getNumParams() == 0 || FPT->getNumParams() > 2 || FPT->isVariadic())
return false;
@@ -2547,7 +2639,7 @@ bool FunctionDecl::isInExternCXXContext() const {
}
bool FunctionDecl::isGlobal() const {
- if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(this))
+ if (const auto *Method = dyn_cast<CXXMethodDecl>(this))
return Method->isStatic();
if (getCanonicalDecl()->getStorageClass() == SC_Static)
@@ -2556,7 +2648,7 @@ bool FunctionDecl::isGlobal() const {
for (const DeclContext *DC = getDeclContext();
DC->isNamespace();
DC = DC->getParent()) {
- if (const NamespaceDecl *Namespace = cast<NamespaceDecl>(DC)) {
+ if (const auto *Namespace = cast<NamespaceDecl>(DC)) {
if (!Namespace->getDeclName())
return false;
break;
@@ -2608,8 +2700,8 @@ unsigned FunctionDecl::getBuiltinID() const {
ASTContext &Context = getASTContext();
if (Context.getLangOpts().CPlusPlus) {
- const LinkageSpecDecl *LinkageDecl = dyn_cast<LinkageSpecDecl>(
- getFirstDecl()->getDeclContext());
+ const auto *LinkageDecl =
+ dyn_cast<LinkageSpecDecl>(getFirstDecl()->getDeclContext());
// In C++, the first declaration of a builtin is always inside an implicit
// extern "C".
// FIXME: A recognised library function may not be directly in an extern "C"
@@ -2649,7 +2741,7 @@ unsigned FunctionDecl::getBuiltinID() const {
/// based on its FunctionType. This is the length of the ParamInfo array
/// after it has been created.
unsigned FunctionDecl::getNumParams() const {
- const FunctionProtoType *FPT = getType()->getAs<FunctionProtoType>();
+ const auto *FPT = getType()->getAs<FunctionProtoType>();
return FPT ? FPT->getNumParams() : 0;
}
@@ -2711,7 +2803,8 @@ bool FunctionDecl::isMSExternInline() const {
assert(isInlined() && "expected to get called on an inlined function!");
const ASTContext &Context = getASTContext();
- if (!Context.getLangOpts().MSVCCompat && !hasAttr<DLLExportAttr>())
+ if (!Context.getTargetInfo().getCXXABI().isMicrosoft() &&
+ !hasAttr<DLLExportAttr>())
return false;
for (const FunctionDecl *FD = getMostRecentDecl(); FD;
@@ -2840,7 +2933,7 @@ bool FunctionDecl::hasUnusedResultAttr() const {
QualType RetType = getReturnType();
if (RetType->isRecordType()) {
const CXXRecordDecl *Ret = RetType->getAsCXXRecordDecl();
- const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(this);
+ const auto *MD = dyn_cast<CXXMethodDecl>(this);
if (Ret && Ret->hasAttr<WarnUnusedResultAttr>() &&
!(MD && MD->getCorrespondingMethodInClass(Ret, true)))
return true;
@@ -2952,6 +3045,10 @@ FunctionDecl *FunctionDecl::getInstantiatedFromMemberFunction() const {
return nullptr;
}
+MemberSpecializationInfo *FunctionDecl::getMemberSpecializationInfo() const {
+ return TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo *>();
+}
+
void
FunctionDecl::setInstantiationOfMemberFunction(ASTContext &C,
FunctionDecl *FD,
@@ -2963,6 +3060,14 @@ FunctionDecl::setInstantiationOfMemberFunction(ASTContext &C,
TemplateOrSpecialization = Info;
}
+FunctionTemplateDecl *FunctionDecl::getDescribedFunctionTemplate() const {
+ return TemplateOrSpecialization.dyn_cast<FunctionTemplateDecl *>();
+}
+
+void FunctionDecl::setDescribedFunctionTemplate(FunctionTemplateDecl *Template) {
+ TemplateOrSpecialization = Template;
+}
+
bool FunctionDecl::isImplicitlyInstantiable() const {
// If the function is invalid, it can't be implicitly instantiated.
if (isInvalidDecl())
@@ -3069,6 +3174,12 @@ FunctionDecl *FunctionDecl::getClassScopeSpecializationPattern() const {
return getASTContext().getClassScopeSpecializationPattern(this);
}
+FunctionTemplateSpecializationInfo *
+FunctionDecl::getTemplateSpecializationInfo() const {
+ return TemplateOrSpecialization
+ .dyn_cast<FunctionTemplateSpecializationInfo *>();
+}
+
const TemplateArgumentList *
FunctionDecl::getTemplateSpecializationArgs() const {
if (FunctionTemplateSpecializationInfo *Info
@@ -3115,33 +3226,41 @@ FunctionDecl::setDependentTemplateSpecialization(ASTContext &Context,
const UnresolvedSetImpl &Templates,
const TemplateArgumentListInfo &TemplateArgs) {
assert(TemplateOrSpecialization.isNull());
- size_t Size = sizeof(DependentFunctionTemplateSpecializationInfo);
- Size += Templates.size() * sizeof(FunctionTemplateDecl*);
- Size += TemplateArgs.size() * sizeof(TemplateArgumentLoc);
- void *Buffer = Context.Allocate(Size);
DependentFunctionTemplateSpecializationInfo *Info =
- new (Buffer) DependentFunctionTemplateSpecializationInfo(Templates,
- TemplateArgs);
+ DependentFunctionTemplateSpecializationInfo::Create(Context, Templates,
+ TemplateArgs);
TemplateOrSpecialization = Info;
}
+DependentFunctionTemplateSpecializationInfo *
+FunctionDecl::getDependentSpecializationInfo() const {
+ return TemplateOrSpecialization
+ .dyn_cast<DependentFunctionTemplateSpecializationInfo *>();
+}
+
+DependentFunctionTemplateSpecializationInfo *
+DependentFunctionTemplateSpecializationInfo::Create(
+ ASTContext &Context, const UnresolvedSetImpl &Ts,
+ const TemplateArgumentListInfo &TArgs) {
+ void *Buffer = Context.Allocate(
+ totalSizeToAlloc<TemplateArgumentLoc, FunctionTemplateDecl *>(
+ TArgs.size(), Ts.size()));
+ return new (Buffer) DependentFunctionTemplateSpecializationInfo(Ts, TArgs);
+}
+
DependentFunctionTemplateSpecializationInfo::
DependentFunctionTemplateSpecializationInfo(const UnresolvedSetImpl &Ts,
const TemplateArgumentListInfo &TArgs)
: AngleLocs(TArgs.getLAngleLoc(), TArgs.getRAngleLoc()) {
- static_assert(sizeof(*this) % llvm::AlignOf<void *>::Alignment == 0,
- "Trailing data is unaligned!");
- d.NumTemplates = Ts.size();
- d.NumArgs = TArgs.size();
+ NumTemplates = Ts.size();
+ NumArgs = TArgs.size();
- FunctionTemplateDecl **TsArray =
- const_cast<FunctionTemplateDecl**>(getTemplates());
+ FunctionTemplateDecl **TsArray = getTrailingObjects<FunctionTemplateDecl *>();
for (unsigned I = 0, E = Ts.size(); I != E; ++I)
TsArray[I] = cast<FunctionTemplateDecl>(Ts[I]->getUnderlyingDecl());
- TemplateArgumentLoc *ArgsArray =
- const_cast<TemplateArgumentLoc*>(getTemplateArgs());
+ TemplateArgumentLoc *ArgsArray = getTrailingObjects<TemplateArgumentLoc>();
for (unsigned I = 0, E = TArgs.size(); I != E; ++I)
new (&ArgsArray[I]) TemplateArgumentLoc(TArgs[I]);
}
@@ -3335,7 +3454,7 @@ bool FieldDecl::isAnonymousStructOrUnion() const {
if (!isImplicit() || getDeclName())
return false;
- if (const RecordType *Record = getType()->getAs<RecordType>())
+ if (const auto *Record = getType()->getAs<RecordType>())
return Record->getDecl()->isAnonymousStructOrUnion();
return false;
@@ -3343,7 +3462,7 @@ bool FieldDecl::isAnonymousStructOrUnion() const {
unsigned FieldDecl::getBitWidthValue(const ASTContext &Ctx) const {
assert(isBitField() && "not a bitfield");
- Expr *BitWidth = static_cast<Expr *>(InitStorage.getPointer());
+ auto *BitWidth = static_cast<Expr *>(InitStorage.getPointer());
return BitWidth->EvaluateKnownConstInt(Ctx).getZExtValue();
}
@@ -3372,7 +3491,7 @@ SourceRange FieldDecl::getSourceRange() const {
case ISK_BitWidthOrNothing:
case ISK_InClassCopyInit:
case ISK_InClassListInit:
- if (const Expr *E = static_cast<const Expr *>(InitStorage.getPointer()))
+ if (const auto *E = static_cast<const Expr *>(InitStorage.getPointer()))
return SourceRange(getInnerLocStart(), E->getLocEnd());
// FALLTHROUGH
@@ -3408,7 +3527,7 @@ SourceRange TagDecl::getSourceRange() const {
TagDecl *TagDecl::getCanonicalDecl() { return getFirstDecl(); }
void TagDecl::setTypedefNameForAnonDecl(TypedefNameDecl *TDD) {
- NamedDeclOrQualifier = TDD;
+ TypedefNameDeclOrQualifier = TDD;
if (const Type *T = getTypeForDecl()) {
(void)T;
assert(T->isLinkageValid());
@@ -3419,7 +3538,7 @@ void TagDecl::setTypedefNameForAnonDecl(TypedefNameDecl *TDD) {
void TagDecl::startDefinition() {
IsBeingDefined = true;
- if (CXXRecordDecl *D = dyn_cast<CXXRecordDecl>(this)) {
+ if (auto *D = dyn_cast<CXXRecordDecl>(this)) {
struct CXXRecordDecl::DefinitionData *Data =
new (getASTContext()) struct CXXRecordDecl::DefinitionData(D);
for (auto I : redecls())
@@ -3452,7 +3571,7 @@ TagDecl *TagDecl::getDefinition() const {
}
}
- if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(this))
+ if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(this))
return CXXRD->getDefinition();
for (auto R : redecls())
@@ -3466,7 +3585,7 @@ void TagDecl::setQualifierInfo(NestedNameSpecifierLoc QualifierLoc) {
if (QualifierLoc) {
// Make sure the extended qualifier info is allocated.
if (!hasExtInfo())
- NamedDeclOrQualifier = new (getASTContext()) ExtInfo;
+ TypedefNameDeclOrQualifier = new (getASTContext()) ExtInfo;
// Set qualifier info.
getExtInfo()->QualifierLoc = QualifierLoc;
} else {
@@ -3474,7 +3593,7 @@ void TagDecl::setQualifierInfo(NestedNameSpecifierLoc QualifierLoc) {
if (hasExtInfo()) {
if (getExtInfo()->NumTemplParamLists == 0) {
getASTContext().Deallocate(getExtInfo());
- NamedDeclOrQualifier = (TypedefNameDecl*)nullptr;
+ TypedefNameDeclOrQualifier = (TypedefNameDecl *)nullptr;
}
else
getExtInfo()->QualifierLoc = QualifierLoc;
@@ -3482,16 +3601,15 @@ void TagDecl::setQualifierInfo(NestedNameSpecifierLoc QualifierLoc) {
}
}
-void TagDecl::setTemplateParameterListsInfo(ASTContext &Context,
- unsigned NumTPLists,
- TemplateParameterList **TPLists) {
- assert(NumTPLists > 0);
+void TagDecl::setTemplateParameterListsInfo(
+ ASTContext &Context, ArrayRef<TemplateParameterList *> TPLists) {
+ assert(!TPLists.empty());
// Make sure the extended decl info is allocated.
if (!hasExtInfo())
// Allocate external info struct.
- NamedDeclOrQualifier = new (getASTContext()) ExtInfo;
+ TypedefNameDeclOrQualifier = new (getASTContext()) ExtInfo;
// Set the template parameter lists info.
- getExtInfo()->setTemplateParameterListsInfo(Context, NumTPLists, TPLists);
+ getExtInfo()->setTemplateParameterListsInfo(Context, TPLists);
}
//===----------------------------------------------------------------------===//
@@ -3505,9 +3623,8 @@ EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC,
IdentifierInfo *Id,
EnumDecl *PrevDecl, bool IsScoped,
bool IsScopedUsingClassTag, bool IsFixed) {
- EnumDecl *Enum = new (C, DC) EnumDecl(C, DC, StartLoc, IdLoc, Id, PrevDecl,
- IsScoped, IsScopedUsingClassTag,
- IsFixed);
+ auto *Enum = new (C, DC) EnumDecl(C, DC, StartLoc, IdLoc, Id, PrevDecl,
+ IsScoped, IsScopedUsingClassTag, IsFixed);
Enum->MayHaveOutOfDateDef = C.getLangOpts().Modules;
C.getTypeDeclType(Enum, PrevDecl);
return Enum;
@@ -3647,10 +3764,6 @@ bool RecordDecl::isMsStruct(const ASTContext &C) const {
return hasAttr<MSStructAttr>() || C.getLangOpts().MSBitfields == 1;
}
-static bool isFieldOrIndirectField(Decl::Kind K) {
- return FieldDecl::classofKind(K) || IndirectFieldDecl::classofKind(K);
-}
-
void RecordDecl::LoadFieldsFromExternalStorage() const {
ExternalASTSource *Source = getASTContext().getExternalSource();
assert(hasExternalLexicalStorage() && Source && "No external storage?");
@@ -3659,16 +3772,10 @@ void RecordDecl::LoadFieldsFromExternalStorage() const {
ExternalASTSource::Deserializing TheFields(Source);
SmallVector<Decl*, 64> Decls;
- LoadedFieldsFromExternalStorage = true;
- switch (Source->FindExternalLexicalDecls(this, isFieldOrIndirectField,
- Decls)) {
- case ELR_Success:
- break;
-
- case ELR_AlreadyLoaded:
- case ELR_Failure:
- return;
- }
+ LoadedFieldsFromExternalStorage = true;
+ Source->FindExternalLexicalDecls(this, [](Decl::Kind K) {
+ return FieldDecl::classofKind(K) || IndirectFieldDecl::classofKind(K);
+ }, Decls);
#ifndef NDEBUG
// Check that all decls we got were FieldDecls.
@@ -3690,7 +3797,7 @@ bool RecordDecl::mayInsertExtraPadding(bool EmitRemark) const {
!Context.getLangOpts().SanitizeAddressFieldPadding)
return false;
const auto &Blacklist = Context.getSanitizerBlacklist();
- const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(this);
+ const auto *CXXRD = dyn_cast<CXXRecordDecl>(this);
// We may be able to relax some of these requirements.
int ReasonToReject = -1;
if (!CXXRD || CXXRD->isExternCContext())
@@ -3731,9 +3838,9 @@ const FieldDecl *RecordDecl::findFirstNamedDataMember() const {
if (I->getIdentifier())
return I;
- if (const RecordType *RT = I->getType()->getAs<RecordType>())
+ if (const auto *RT = I->getType()->getAs<RecordType>())
if (const FieldDecl *NamedDataMember =
- RT->getDecl()->findFirstNamedDataMember())
+ RT->getDecl()->findFirstNamedDataMember())
return NamedDataMember;
}
@@ -3757,26 +3864,17 @@ void BlockDecl::setParams(ArrayRef<ParmVarDecl *> NewParamInfo) {
}
}
-void BlockDecl::setCaptures(ASTContext &Context,
- const Capture *begin,
- const Capture *end,
- bool capturesCXXThis) {
- CapturesCXXThis = capturesCXXThis;
+void BlockDecl::setCaptures(ASTContext &Context, ArrayRef<Capture> Captures,
+ bool CapturesCXXThis) {
+ this->CapturesCXXThis = CapturesCXXThis;
+ this->NumCaptures = Captures.size();
- if (begin == end) {
- NumCaptures = 0;
- Captures = nullptr;
+ if (Captures.empty()) {
+ this->Captures = nullptr;
return;
}
- NumCaptures = end - begin;
-
- // Avoid new Capture[] because we don't want to provide a default
- // constructor.
- size_t allocationSize = NumCaptures * sizeof(Capture);
- void *buffer = Context.Allocate(allocationSize, /*alignment*/sizeof(void*));
- memcpy(buffer, begin, allocationSize);
- Captures = static_cast<Capture*>(buffer);
+ this->Captures = Captures.copy(Context).data();
}
bool BlockDecl::capturesVariable(const VarDecl *variable) const {
@@ -3889,18 +3987,28 @@ BlockDecl *BlockDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
return new (C, ID) BlockDecl(nullptr, SourceLocation());
}
+CapturedDecl::CapturedDecl(DeclContext *DC, unsigned NumParams)
+ : Decl(Captured, DC, SourceLocation()), DeclContext(Captured),
+ NumParams(NumParams), ContextParam(0), BodyAndNothrow(nullptr, false) {}
+
CapturedDecl *CapturedDecl::Create(ASTContext &C, DeclContext *DC,
unsigned NumParams) {
- return new (C, DC, NumParams * sizeof(ImplicitParamDecl *))
+ return new (C, DC, additionalSizeToAlloc<ImplicitParamDecl *>(NumParams))
CapturedDecl(DC, NumParams);
}
CapturedDecl *CapturedDecl::CreateDeserialized(ASTContext &C, unsigned ID,
unsigned NumParams) {
- return new (C, ID, NumParams * sizeof(ImplicitParamDecl *))
+ return new (C, ID, additionalSizeToAlloc<ImplicitParamDecl *>(NumParams))
CapturedDecl(nullptr, NumParams);
}
+Stmt *CapturedDecl::getBody() const { return BodyAndNothrow.getPointer(); }
+void CapturedDecl::setBody(Stmt *B) { BodyAndNothrow.setPointer(B); }
+
+bool CapturedDecl::isNothrow() const { return BodyAndNothrow.getInt(); }
+void CapturedDecl::setNothrow(bool Nothrow) { BodyAndNothrow.setInt(Nothrow); }
+
EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD,
SourceLocation L,
IdentifierInfo *Id, QualType T,
@@ -4042,9 +4150,9 @@ ImportDecl::ImportDecl(DeclContext *DC, SourceLocation StartLoc,
NextLocalImport()
{
assert(getNumModuleIdentifiers(Imported) == IdentifierLocs.size());
- SourceLocation *StoredLocs = reinterpret_cast<SourceLocation *>(this + 1);
- memcpy(StoredLocs, IdentifierLocs.data(),
- IdentifierLocs.size() * sizeof(SourceLocation));
+ auto *StoredLocs = getTrailingObjects<SourceLocation>();
+ std::uninitialized_copy(IdentifierLocs.begin(), IdentifierLocs.end(),
+ StoredLocs);
}
ImportDecl::ImportDecl(DeclContext *DC, SourceLocation StartLoc,
@@ -4052,13 +4160,14 @@ ImportDecl::ImportDecl(DeclContext *DC, SourceLocation StartLoc,
: Decl(Import, DC, StartLoc), ImportedAndComplete(Imported, false),
NextLocalImport()
{
- *reinterpret_cast<SourceLocation *>(this + 1) = EndLoc;
+ *getTrailingObjects<SourceLocation>() = EndLoc;
}
ImportDecl *ImportDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, Module *Imported,
ArrayRef<SourceLocation> IdentifierLocs) {
- return new (C, DC, IdentifierLocs.size() * sizeof(SourceLocation))
+ return new (C, DC,
+ additionalSizeToAlloc<SourceLocation>(IdentifierLocs.size()))
ImportDecl(DC, StartLoc, Imported, IdentifierLocs);
}
@@ -4066,16 +4175,15 @@ ImportDecl *ImportDecl::CreateImplicit(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc,
Module *Imported,
SourceLocation EndLoc) {
- ImportDecl *Import =
- new (C, DC, sizeof(SourceLocation)) ImportDecl(DC, StartLoc,
- Imported, EndLoc);
+ ImportDecl *Import = new (C, DC, additionalSizeToAlloc<SourceLocation>(1))
+ ImportDecl(DC, StartLoc, Imported, EndLoc);
Import->setImplicit();
return Import;
}
ImportDecl *ImportDecl::CreateDeserialized(ASTContext &C, unsigned ID,
unsigned NumLocations) {
- return new (C, ID, NumLocations * sizeof(SourceLocation))
+ return new (C, ID, additionalSizeToAlloc<SourceLocation>(NumLocations))
ImportDecl(EmptyShell());
}
@@ -4083,16 +4191,14 @@ ArrayRef<SourceLocation> ImportDecl::getIdentifierLocs() const {
if (!ImportedAndComplete.getInt())
return None;
- const SourceLocation *StoredLocs
- = reinterpret_cast<const SourceLocation *>(this + 1);
+ const auto *StoredLocs = getTrailingObjects<SourceLocation>();
return llvm::makeArrayRef(StoredLocs,
getNumModuleIdentifiers(getImportedModule()));
}
SourceRange ImportDecl::getSourceRange() const {
if (!ImportedAndComplete.getInt())
- return SourceRange(getLocation(),
- *reinterpret_cast<const SourceLocation *>(this + 1));
-
+ return SourceRange(getLocation(), *getTrailingObjects<SourceLocation>());
+
return SourceRange(getLocation(), getIdentifierLocs().back());
}
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index 4fcec53d6eb9..16394e865eb1 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -45,10 +45,19 @@ void Decl::updateOutOfDate(IdentifierInfo &II) const {
getASTContext().getExternalSource()->updateOutOfDateIdentifier(II);
}
+#define DECL(DERIVED, BASE) \
+ static_assert(Decl::DeclObjAlignment >= \
+ llvm::AlignOf<DERIVED##Decl>::Alignment, \
+ "Alignment sufficient after objects prepended to " #DERIVED);
+#define ABSTRACT_DECL(DECL)
+#include "clang/AST/DeclNodes.inc"
+
void *Decl::operator new(std::size_t Size, const ASTContext &Context,
unsigned ID, std::size_t Extra) {
// Allocate an extra 8 bytes worth of storage, which ensures that the
- // resulting pointer will still be 8-byte aligned.
+ // resulting pointer will still be 8-byte aligned.
+ static_assert(sizeof(unsigned) * 2 >= DeclObjAlignment,
+ "Decl won't be misaligned");
void *Start = Context.Allocate(Size + Extra + 8);
void *Result = (char*)Start + 8;
@@ -69,7 +78,13 @@ void *Decl::operator new(std::size_t Size, const ASTContext &Ctx,
// With local visibility enabled, we track the owning module even for local
// declarations.
if (Ctx.getLangOpts().ModulesLocalVisibility) {
- void *Buffer = ::operator new(sizeof(Module *) + Size + Extra, Ctx);
+ // Ensure required alignment of the resulting object by adding extra
+ // padding at the start if required.
+ size_t ExtraAlign =
+ llvm::OffsetToAlignment(sizeof(Module *), DeclObjAlignment);
+ char *Buffer = reinterpret_cast<char *>(
+ ::operator new(ExtraAlign + sizeof(Module *) + Size + Extra, Ctx));
+ Buffer += ExtraAlign;
return new (Buffer) Module*(nullptr) + 1;
}
return ::operator new(Size + Extra, Ctx);
@@ -251,6 +266,18 @@ void Decl::setDeclContextsImpl(DeclContext *SemaDC, DeclContext *LexicalDC,
}
}
+bool Decl::isLexicallyWithinFunctionOrMethod() const {
+ const DeclContext *LDC = getLexicalDeclContext();
+ while (true) {
+ if (LDC->isFunctionOrMethod())
+ return true;
+ if (!isa<TagDecl>(LDC))
+ return false;
+ LDC = LDC->getLexicalParent();
+ }
+ return false;
+}
+
bool Decl::isInAnonymousNamespace() const {
const DeclContext *DC = getDeclContext();
do {
@@ -612,6 +639,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
case ExternCContext:
case UsingDirective:
+ case BuiltinTemplate:
case ClassTemplateSpecialization:
case ClassTemplatePartialSpecialization:
case ClassScopeFunctionSpecialization:
@@ -1044,14 +1072,7 @@ DeclContext::LoadLexicalDeclsFromExternalStorage() const {
// Load the external declarations, if any.
SmallVector<Decl*, 64> Decls;
ExternalLexicalStorage = false;
- switch (Source->FindExternalLexicalDecls(this, Decls)) {
- case ELR_Success:
- break;
-
- case ELR_Failure:
- case ELR_AlreadyLoaded:
- return false;
- }
+ Source->FindExternalLexicalDecls(this, Decls);
if (Decls.empty())
return false;
@@ -1189,13 +1210,16 @@ void DeclContext::removeDecl(Decl *D) {
// Remove only decls that have a name
if (!ND->getDeclName()) return;
- StoredDeclsMap *Map = getPrimaryContext()->LookupPtr;
- if (!Map) return;
-
- StoredDeclsMap::iterator Pos = Map->find(ND->getDeclName());
- assert(Pos != Map->end() && "no lookup entry for decl");
- if (Pos->second.getAsVector() || Pos->second.getAsDecl() == ND)
- Pos->second.remove(ND);
+ auto *DC = this;
+ do {
+ StoredDeclsMap *Map = DC->getPrimaryContext()->LookupPtr;
+ if (Map) {
+ StoredDeclsMap::iterator Pos = Map->find(ND->getDeclName());
+ assert(Pos != Map->end() && "no lookup entry for decl");
+ if (Pos->second.getAsVector() || Pos->second.getAsDecl() == ND)
+ Pos->second.remove(ND);
+ }
+ } while (DC->isTransparentContext() && (DC = DC->getParent()));
}
}
@@ -1213,7 +1237,7 @@ void DeclContext::addHiddenDecl(Decl *D) {
}
// Notify a C++ record declaration that we've added a member, so it can
- // update it's class-specific state.
+ // update its class-specific state.
if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(this))
Record->addedMember(D);
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index d905fcf13a45..4f24fdc28f71 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -385,17 +385,11 @@ void CXXRecordDecl::addedClassSubobject(CXXRecordDecl *Subobj) {
}
}
-/// Callback function for CXXRecordDecl::forallBases that acknowledges
-/// that it saw a base class.
-static bool SawBase(const CXXRecordDecl *, void *) {
- return true;
-}
-
bool CXXRecordDecl::hasAnyDependentBases() const {
if (!isDependentContext())
return false;
- return !forallBases(SawBase, nullptr);
+ return !forallBases([](const CXXRecordDecl *) { return true; });
}
bool CXXRecordDecl::isTriviallyCopyable() const {
@@ -1224,6 +1218,10 @@ CXXRecordDecl *CXXRecordDecl::getInstantiatedFromMemberClass() const {
return nullptr;
}
+MemberSpecializationInfo *CXXRecordDecl::getMemberSpecializationInfo() const {
+ return TemplateOrInstantiation.dyn_cast<MemberSpecializationInfo *>();
+}
+
void
CXXRecordDecl::setInstantiationOfMemberClass(CXXRecordDecl *RD,
TemplateSpecializationKind TSK) {
@@ -1234,6 +1232,14 @@ CXXRecordDecl::setInstantiationOfMemberClass(CXXRecordDecl *RD,
= new (getASTContext()) MemberSpecializationInfo(RD, TSK);
}
+ClassTemplateDecl *CXXRecordDecl::getDescribedClassTemplate() const {
+ return TemplateOrInstantiation.dyn_cast<ClassTemplateDecl *>();
+}
+
+void CXXRecordDecl::setDescribedClassTemplate(ClassTemplateDecl *Template) {
+ TemplateOrInstantiation = Template;
+}
+
TemplateSpecializationKind CXXRecordDecl::getTemplateSpecializationKind() const{
if (const ClassTemplateSpecializationDecl *Spec
= dyn_cast<ClassTemplateSpecializationDecl>(this))
@@ -1681,8 +1687,8 @@ CXXCtorInitializer::CXXCtorInitializer(ASTContext &Context,
LParenLoc(L), RParenLoc(R), IsDelegating(false), IsVirtual(false),
IsWritten(false), SourceOrderOrNumArrayIndices(NumIndices)
{
- VarDecl **MyIndices = reinterpret_cast<VarDecl **> (this + 1);
- memcpy(MyIndices, Indices, NumIndices * sizeof(VarDecl *));
+ std::uninitialized_copy(Indices, Indices + NumIndices,
+ getTrailingObjects<VarDecl *>());
}
CXXCtorInitializer *CXXCtorInitializer::Create(ASTContext &Context,
@@ -1692,8 +1698,7 @@ CXXCtorInitializer *CXXCtorInitializer::Create(ASTContext &Context,
SourceLocation R,
VarDecl **Indices,
unsigned NumIndices) {
- void *Mem = Context.Allocate(sizeof(CXXCtorInitializer) +
- sizeof(VarDecl *) * NumIndices,
+ void *Mem = Context.Allocate(totalSizeToAlloc<VarDecl *>(NumIndices),
llvm::alignOf<CXXCtorInitializer>());
return new (Mem) CXXCtorInitializer(Context, Member, MemberLoc, L, Init, R,
Indices, NumIndices);
@@ -2023,6 +2028,22 @@ NamespaceDecl *NamespaceDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
SourceLocation(), nullptr, nullptr);
}
+NamespaceDecl *NamespaceDecl::getOriginalNamespace() {
+ if (isFirstDecl())
+ return this;
+
+ return AnonOrFirstNamespaceAndInline.getPointer();
+}
+
+const NamespaceDecl *NamespaceDecl::getOriginalNamespace() const {
+ if (isFirstDecl())
+ return this;
+
+ return AnonOrFirstNamespaceAndInline.getPointer();
+}
+
+bool NamespaceDecl::isOriginalNamespace() const { return isFirstDecl(); }
+
NamespaceDecl *NamespaceDecl::getNextRedeclarationImpl() {
return getNextRedeclaration();
}
diff --git a/lib/AST/DeclFriend.cpp b/lib/AST/DeclFriend.cpp
index a996cab093af..121403b07e57 100644
--- a/lib/AST/DeclFriend.cpp
+++ b/lib/AST/DeclFriend.cpp
@@ -46,7 +46,9 @@ FriendDecl *FriendDecl::Create(ASTContext &C, DeclContext *DC,
}
#endif
- std::size_t Extra = FriendTypeTPLists.size() * sizeof(TemplateParameterList*);
+ std::size_t Extra =
+ FriendDecl::additionalSizeToAlloc<TemplateParameterList *>(
+ FriendTypeTPLists.size());
FriendDecl *FD = new (C, DC, Extra) FriendDecl(DC, L, Friend, FriendL,
FriendTypeTPLists);
cast<CXXRecordDecl>(DC)->pushFriendDecl(FD);
@@ -55,7 +57,8 @@ FriendDecl *FriendDecl::Create(ASTContext &C, DeclContext *DC,
FriendDecl *FriendDecl::CreateDeserialized(ASTContext &C, unsigned ID,
unsigned FriendTypeNumTPLists) {
- std::size_t Extra = FriendTypeNumTPLists * sizeof(TemplateParameterList*);
+ std::size_t Extra =
+ additionalSizeToAlloc<TemplateParameterList *>(FriendTypeNumTPLists);
return new (C, ID, Extra) FriendDecl(EmptyShell(), FriendTypeNumTPLists);
}
diff --git a/lib/AST/DeclGroup.cpp b/lib/AST/DeclGroup.cpp
index 512837fdf3f4..f162e6d40c48 100644
--- a/lib/AST/DeclGroup.cpp
+++ b/lib/AST/DeclGroup.cpp
@@ -18,10 +18,8 @@
using namespace clang;
DeclGroup* DeclGroup::Create(ASTContext &C, Decl **Decls, unsigned NumDecls) {
- static_assert(sizeof(DeclGroup) % llvm::AlignOf<void *>::Alignment == 0,
- "Trailing data is unaligned!");
assert(NumDecls > 1 && "Invalid DeclGroup");
- unsigned Size = sizeof(DeclGroup) + sizeof(Decl*) * NumDecls;
+ unsigned Size = totalSizeToAlloc<Decl *>(NumDecls);
void* Mem = C.Allocate(Size, llvm::AlignOf<DeclGroup>::Alignment);
new (Mem) DeclGroup(NumDecls, Decls);
return static_cast<DeclGroup*>(Mem);
@@ -30,5 +28,6 @@ DeclGroup* DeclGroup::Create(ASTContext &C, Decl **Decls, unsigned NumDecls) {
DeclGroup::DeclGroup(unsigned numdecls, Decl** decls) : NumDecls(numdecls) {
assert(numdecls > 0);
assert(decls);
- memcpy(this+1, decls, numdecls * sizeof(*decls));
+ std::uninitialized_copy(decls, decls + numdecls,
+ getTrailingObjects<Decl *>());
}
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index 280c412ae8ff..050a0f53f1e5 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -161,6 +161,15 @@ ObjCPropertyDecl::findPropertyDecl(const DeclContext *DC,
return nullptr;
}
+ // If context is class, then lookup property in its extensions.
+ // This comes before property is looked up in primary class.
+ if (auto *IDecl = dyn_cast<ObjCInterfaceDecl>(DC)) {
+ for (const auto *Ext : IDecl->known_extensions())
+ if (ObjCPropertyDecl *PD = ObjCPropertyDecl::findPropertyDecl(Ext,
+ propertyID))
+ return PD;
+ }
+
DeclContext::lookup_result R = DC->lookup(propertyID);
for (DeclContext::lookup_iterator I = R.begin(), E = R.end(); I != E;
++I)
@@ -190,6 +199,15 @@ ObjCPropertyDecl *ObjCContainerDecl::FindPropertyDeclaration(
if (Def->isHidden())
return nullptr;
}
+
+ // Search the extensions of a class first; they override what's in
+ // the class itself.
+ if (const auto *ClassDecl = dyn_cast<ObjCInterfaceDecl>(this)) {
+ for (const auto *Ext : ClassDecl->visible_extensions()) {
+ if (auto *P = Ext->FindPropertyDeclaration(PropertyId))
+ return P;
+ }
+ }
if (ObjCPropertyDecl *PD =
ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId))
@@ -207,7 +225,7 @@ ObjCPropertyDecl *ObjCContainerDecl::FindPropertyDeclaration(
}
case Decl::ObjCInterface: {
const ObjCInterfaceDecl *OID = cast<ObjCInterfaceDecl>(this);
- // Look through categories (but not extensions).
+ // Look through categories (but not extensions; they were handled above).
for (const auto *Cat : OID->visible_categories()) {
if (!Cat->IsClassExtension())
if (ObjCPropertyDecl *P = Cat->FindPropertyDeclaration(PropertyId))
@@ -327,6 +345,13 @@ void ObjCInterfaceDecl::collectPropertiesToImplement(PropertyMap &PM,
PM[Prop->getIdentifier()] = Prop;
PO.push_back(Prop);
}
+ for (const auto *Ext : known_extensions()) {
+ const ObjCCategoryDecl *ClassExt = Ext;
+ for (auto *Prop : ClassExt->properties()) {
+ PM[Prop->getIdentifier()] = Prop;
+ PO.push_back(Prop);
+ }
+ }
for (const auto *PI : all_referenced_protocols())
PI->collectPropertiesToImplement(PM, PO);
// Note, the properties declared only in class extensions are still copied
@@ -747,6 +772,10 @@ void ObjCMethodDecl::setParamsAndSelLocs(ASTContext &C,
if (Params.empty() && SelLocs.empty())
return;
+ static_assert(llvm::AlignOf<ParmVarDecl *>::Alignment >=
+ llvm::AlignOf<SourceLocation>::Alignment,
+ "Alignment not sufficient for SourceLocation");
+
unsigned Size = sizeof(ParmVarDecl *) * NumParams +
sizeof(SourceLocation) * SelLocs.size();
ParamsAndSelLocs = C.Allocate(Size);
@@ -1182,18 +1211,47 @@ ObjCMethodDecl::findPropertyDecl(bool CheckOverrides) const {
if (isPropertyAccessor()) {
const ObjCContainerDecl *Container = cast<ObjCContainerDecl>(getParent());
- // If container is class extension, find its primary class.
- if (const ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(Container))
- if (CatDecl->IsClassExtension())
- Container = CatDecl->getClassInterface();
-
bool IsGetter = (NumArgs == 0);
- for (const auto *I : Container->properties()) {
- Selector NextSel = IsGetter ? I->getGetterName()
- : I->getSetterName();
- if (NextSel == Sel)
- return I;
+ /// Local function that attempts to find a matching property within the
+ /// given Objective-C container.
+ auto findMatchingProperty =
+ [&](const ObjCContainerDecl *Container) -> const ObjCPropertyDecl * {
+
+ for (const auto *I : Container->properties()) {
+ Selector NextSel = IsGetter ? I->getGetterName()
+ : I->getSetterName();
+ if (NextSel == Sel)
+ return I;
+ }
+
+ return nullptr;
+ };
+
+ // Look in the container we were given.
+ if (const auto *Found = findMatchingProperty(Container))
+ return Found;
+
+ // If we're in a category or extension, look in the main class.
+ const ObjCInterfaceDecl *ClassDecl = nullptr;
+ if (const auto *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
+ ClassDecl = Category->getClassInterface();
+ if (const auto *Found = findMatchingProperty(ClassDecl))
+ return Found;
+ } else {
+ // Determine whether the container is a class.
+ ClassDecl = dyn_cast<ObjCInterfaceDecl>(Container);
+ }
+
+ // If we have a class, check its visible extensions.
+ if (ClassDecl) {
+ for (const auto *Ext : ClassDecl->visible_extensions()) {
+ if (Ext == Container)
+ continue;
+
+ if (const auto *Found = findMatchingProperty(Ext))
+ return Found;
+ }
}
llvm_unreachable("Marked as a property accessor but no property found!");
@@ -1272,13 +1330,9 @@ ObjCTypeParamList *ObjCTypeParamList::create(
SourceLocation lAngleLoc,
ArrayRef<ObjCTypeParamDecl *> typeParams,
SourceLocation rAngleLoc) {
- unsigned size = sizeof(ObjCTypeParamList)
- + sizeof(ObjCTypeParamDecl *) * typeParams.size();
- static_assert(llvm::AlignOf<ObjCTypeParamList>::Alignment >=
- llvm::AlignOf<ObjCTypeParamDecl *>::Alignment,
- "type parameter list needs greater alignment");
- unsigned align = llvm::alignOf<ObjCTypeParamList>();
- void *mem = ctx.Allocate(size, align);
+ void *mem =
+ ctx.Allocate(totalSizeToAlloc<ObjCTypeParamDecl *>(typeParams.size()),
+ llvm::alignOf<ObjCTypeParamList>());
return new (mem) ObjCTypeParamList(lAngleLoc, typeParams, rAngleLoc);
}
diff --git a/lib/AST/DeclOpenMP.cpp b/lib/AST/DeclOpenMP.cpp
index 5f8b42b3f964..493e2cd41226 100644
--- a/lib/AST/DeclOpenMP.cpp
+++ b/lib/AST/DeclOpenMP.cpp
@@ -29,8 +29,9 @@ OMPThreadPrivateDecl *OMPThreadPrivateDecl::Create(ASTContext &C,
DeclContext *DC,
SourceLocation L,
ArrayRef<Expr *> VL) {
- OMPThreadPrivateDecl *D = new (C, DC, VL.size() * sizeof(Expr *))
- OMPThreadPrivateDecl(OMPThreadPrivate, DC, L);
+ OMPThreadPrivateDecl *D =
+ new (C, DC, additionalSizeToAlloc<Expr *>(VL.size()))
+ OMPThreadPrivateDecl(OMPThreadPrivate, DC, L);
D->NumVars = VL.size();
D->setVars(VL);
return D;
@@ -39,7 +40,7 @@ OMPThreadPrivateDecl *OMPThreadPrivateDecl::Create(ASTContext &C,
OMPThreadPrivateDecl *OMPThreadPrivateDecl::CreateDeserialized(ASTContext &C,
unsigned ID,
unsigned N) {
- OMPThreadPrivateDecl *D = new (C, ID, N * sizeof(Expr *))
+ OMPThreadPrivateDecl *D = new (C, ID, additionalSizeToAlloc<Expr *>(N))
OMPThreadPrivateDecl(OMPThreadPrivate, nullptr, SourceLocation());
D->NumVars = N;
return D;
@@ -48,7 +49,6 @@ OMPThreadPrivateDecl *OMPThreadPrivateDecl::CreateDeserialized(ASTContext &C,
void OMPThreadPrivateDecl::setVars(ArrayRef<Expr *> VL) {
assert(VL.size() == NumVars &&
"Number of variables is not the same as the preallocated buffer");
- Expr **Vars = reinterpret_cast<Expr **>(this + 1);
- std::copy(VL.begin(), VL.end(), Vars);
+ std::uninitialized_copy(VL.begin(), VL.end(), getTrailingObjects<Expr *>());
}
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
index 3202d8c75436..5c6002d55c0f 100644
--- a/lib/AST/DeclPrinter.cpp
+++ b/lib/AST/DeclPrinter.cpp
@@ -96,6 +96,7 @@ namespace {
void PrintTemplateParameters(const TemplateParameterList *Params,
const TemplateArgumentList *Args = nullptr);
void prettyPrintAttributes(Decl *D);
+ void prettyPrintPragmas(Decl *D);
void printDeclType(QualType T, StringRef DeclName, bool Pack = false);
};
}
@@ -197,12 +198,40 @@ raw_ostream& DeclPrinter::Indent(unsigned Indentation) {
void DeclPrinter::prettyPrintAttributes(Decl *D) {
if (Policy.PolishForDeclaration)
return;
-
+
+ if (D->hasAttrs()) {
+ AttrVec &Attrs = D->getAttrs();
+ for (auto *A : Attrs) {
+ switch (A->getKind()) {
+#define ATTR(X)
+#define PRAGMA_SPELLING_ATTR(X) case attr::X:
+#include "clang/Basic/AttrList.inc"
+ break;
+ default:
+ A->printPretty(Out, Policy);
+ break;
+ }
+ }
+ }
+}
+
+void DeclPrinter::prettyPrintPragmas(Decl *D) {
+ if (Policy.PolishForDeclaration)
+ return;
+
if (D->hasAttrs()) {
AttrVec &Attrs = D->getAttrs();
- for (AttrVec::const_iterator i=Attrs.begin(), e=Attrs.end(); i!=e; ++i) {
- Attr *A = *i;
- A->printPretty(Out, Policy);
+ for (auto *A : Attrs) {
+ switch (A->getKind()) {
+#define ATTR(X)
+#define PRAGMA_SPELLING_ATTR(X) case attr::X:
+#include "clang/Basic/AttrList.inc"
+ A->printPretty(Out, Policy);
+ Indent();
+ break;
+ default:
+ break;
+ }
}
}
}
@@ -408,6 +437,10 @@ void DeclPrinter::VisitEnumConstantDecl(EnumConstantDecl *D) {
}
void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
+ if (!D->getDescribedFunctionTemplate() &&
+ !D->isFunctionTemplateSpecialization())
+ prettyPrintPragmas(D);
+
CXXConstructorDecl *CDecl = dyn_cast<CXXConstructorDecl>(D);
CXXConversionDecl *ConversionDecl = dyn_cast<CXXConversionDecl>(D);
if (!Policy.SuppressSpecifiers) {
@@ -416,7 +449,7 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
case SC_Extern: Out << "extern "; break;
case SC_Static: Out << "static "; break;
case SC_PrivateExtern: Out << "__private_extern__ "; break;
- case SC_Auto: case SC_Register: case SC_OpenCLWorkGroupLocal:
+ case SC_Auto: case SC_Register:
llvm_unreachable("invalid for functions");
}
@@ -643,6 +676,7 @@ void DeclPrinter::VisitFriendDecl(FriendDecl *D) {
}
void DeclPrinter::VisitFieldDecl(FieldDecl *D) {
+ // FIXME: add printing of pragma attributes if required.
if (!Policy.SuppressSpecifiers && D->isMutable())
Out << "mutable ";
if (!Policy.SuppressSpecifiers && D->isModulePrivate())
@@ -672,6 +706,7 @@ void DeclPrinter::VisitLabelDecl(LabelDecl *D) {
}
void DeclPrinter::VisitVarDecl(VarDecl *D) {
+ prettyPrintPragmas(D);
if (!Policy.SuppressSpecifiers) {
StorageClass SC = D->getStorageClass();
if (SC != SC_None)
@@ -779,6 +814,7 @@ void DeclPrinter::VisitEmptyDecl(EmptyDecl *D) {
}
void DeclPrinter::VisitCXXRecordDecl(CXXRecordDecl *D) {
+ // FIXME: add printing of pragma attributes if required.
if (!Policy.SuppressSpecifiers && D->isModulePrivate())
Out << "__module_private__ ";
Out << D->getKindName();
@@ -914,11 +950,13 @@ void DeclPrinter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
if (PrintInstantiation) {
TemplateParameterList *Params = D->getTemplateParameters();
for (auto *I : D->specializations()) {
+ prettyPrintPragmas(I);
PrintTemplateParameters(Params, I->getTemplateSpecializationArgs());
Visit(I);
}
}
+ prettyPrintPragmas(D->getTemplatedDecl());
return VisitRedeclarableTemplateDecl(D);
}
@@ -1088,7 +1126,7 @@ void DeclPrinter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *OID) {
}
if (SID)
- Out << " : " << OID->getSuperClass()->getName();
+ Out << " : " << QualType(OID->getSuperClassType(), 0).getAsString(Policy);
// Protocols?
const ObjCList<ObjCProtocolDecl> &Protocols = OID->getReferencedProtocols();
@@ -1299,7 +1337,7 @@ void DeclPrinter::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
if (!D->isAccessDeclaration())
Out << "using ";
D->getQualifier()->print(Out, Policy);
- Out << D->getName();
+ Out << D->getDeclName();
}
void DeclPrinter::VisitUsingShadowDecl(UsingShadowDecl *D) {
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
index cde497b012e2..de3ebd23ef4f 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/lib/AST/DeclTemplate.cpp
@@ -18,6 +18,7 @@
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/TypeLoc.h"
+#include "clang/Basic/Builtins.h"
#include "clang/Basic/IdentifierTable.h"
#include "llvm/ADT/STLExtras.h"
#include <memory>
@@ -29,10 +30,10 @@ using namespace clang;
TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc,
SourceLocation LAngleLoc,
- NamedDecl **Params, unsigned NumParams,
+ ArrayRef<NamedDecl *> Params,
SourceLocation RAngleLoc)
: TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
- NumParams(NumParams), ContainsUnexpandedParameterPack(false) {
+ NumParams(Params.size()), ContainsUnexpandedParameterPack(false) {
assert(this->NumParams == NumParams && "Too many template parameters");
for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
NamedDecl *P = Params[Idx];
@@ -53,17 +54,13 @@ TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc,
}
}
-TemplateParameterList *
-TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc,
- SourceLocation LAngleLoc, NamedDecl **Params,
- unsigned NumParams, SourceLocation RAngleLoc) {
- unsigned Size = sizeof(TemplateParameterList)
- + sizeof(NamedDecl *) * NumParams;
- unsigned Align = std::max(llvm::alignOf<TemplateParameterList>(),
- llvm::alignOf<NamedDecl*>());
- void *Mem = C.Allocate(Size, Align);
+TemplateParameterList *TemplateParameterList::Create(
+ const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc,
+ ArrayRef<NamedDecl *> Params, SourceLocation RAngleLoc) {
+ void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *>(Params.size()),
+ llvm::alignOf<TemplateParameterList>());
return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
- NumParams, RAngleLoc);
+ RAngleLoc);
}
unsigned TemplateParameterList::getMinRequiredArguments() const {
@@ -240,8 +237,8 @@ static void GenerateInjectedTemplateArgs(ASTContext &Context,
}
if ((*Param)->isTemplateParameterPack())
- Arg = TemplateArgument::CreatePackCopy(Context, &Arg, 1);
-
+ Arg = TemplateArgument::CreatePackCopy(Context, Arg);
+
*Args++ = Arg;
}
}
@@ -552,10 +549,11 @@ NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(DeclContext *DC,
TemplateParmPosition(D, P), ParameterPack(true),
ExpandedParameterPack(true), NumExpandedTypes(NumExpandedTypes) {
if (ExpandedTypes && ExpandedTInfos) {
- void **TypesAndInfos = reinterpret_cast<void **>(this + 1);
+ auto TypesAndInfos =
+ getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
for (unsigned I = 0; I != NumExpandedTypes; ++I) {
- TypesAndInfos[2*I] = ExpandedTypes[I].getAsOpaquePtr();
- TypesAndInfos[2*I + 1] = ExpandedTInfos[I];
+ new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
+ TypesAndInfos[I].second = ExpandedTInfos[I];
}
}
}
@@ -579,10 +577,11 @@ NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
const QualType *ExpandedTypes,
unsigned NumExpandedTypes,
TypeSourceInfo **ExpandedTInfos) {
- unsigned Extra = NumExpandedTypes * 2 * sizeof(void*);
- return new (C, DC, Extra) NonTypeTemplateParmDecl(
- DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
- ExpandedTypes, NumExpandedTypes, ExpandedTInfos);
+ return new (C, DC,
+ additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
+ NumExpandedTypes))
+ NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
+ ExpandedTypes, NumExpandedTypes, ExpandedTInfos);
}
NonTypeTemplateParmDecl *
@@ -595,10 +594,12 @@ NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
NonTypeTemplateParmDecl *
NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
unsigned NumExpandedTypes) {
- unsigned Extra = NumExpandedTypes * 2 * sizeof(void*);
- return new (C, ID, Extra) NonTypeTemplateParmDecl(
- nullptr, SourceLocation(), SourceLocation(), 0, 0, nullptr, QualType(),
- nullptr, nullptr, NumExpandedTypes, nullptr);
+ return new (C, ID,
+ additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
+ NumExpandedTypes))
+ NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(), 0, 0,
+ nullptr, QualType(), nullptr, nullptr,
+ NumExpandedTypes, nullptr);
}
SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
@@ -628,8 +629,8 @@ TemplateTemplateParmDecl::TemplateTemplateParmDecl(
TemplateParmPosition(D, P), ParameterPack(true),
ExpandedParameterPack(true), NumExpandedParams(NumExpansions) {
if (Expansions)
- std::memcpy(reinterpret_cast<void*>(this + 1), Expansions,
- sizeof(TemplateParameterList*) * NumExpandedParams);
+ std::uninitialized_copy(Expansions, Expansions + NumExpandedParams,
+ getTrailingObjects<TemplateParameterList *>());
}
TemplateTemplateParmDecl *
@@ -647,9 +648,10 @@ TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
IdentifierInfo *Id,
TemplateParameterList *Params,
ArrayRef<TemplateParameterList *> Expansions) {
- return new (C, DC, sizeof(TemplateParameterList*) * Expansions.size())
- TemplateTemplateParmDecl(DC, L, D, P, Id, Params,
- Expansions.size(), Expansions.data());
+ return new (C, DC,
+ additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
+ TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions.size(),
+ Expansions.data());
}
TemplateTemplateParmDecl *
@@ -661,7 +663,8 @@ TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
TemplateTemplateParmDecl *
TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
unsigned NumExpansions) {
- return new (C, ID, sizeof(TemplateParameterList*) * NumExpansions)
+ return new (C, ID,
+ additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
nullptr, NumExpansions, nullptr);
}
@@ -682,18 +685,19 @@ void TemplateTemplateParmDecl::setDefaultArgument(
//===----------------------------------------------------------------------===//
// TemplateArgumentList Implementation
//===----------------------------------------------------------------------===//
+TemplateArgumentList::TemplateArgumentList(const TemplateArgument *Args,
+ unsigned NumArgs)
+ : Arguments(getTrailingObjects<TemplateArgument>()), NumArguments(NumArgs) {
+ std::uninitialized_copy(Args, Args + NumArgs,
+ getTrailingObjects<TemplateArgument>());
+}
+
TemplateArgumentList *
TemplateArgumentList::CreateCopy(ASTContext &Context,
const TemplateArgument *Args,
unsigned NumArgs) {
- std::size_t Size = sizeof(TemplateArgumentList)
- + NumArgs * sizeof(TemplateArgument);
- void *Mem = Context.Allocate(Size);
- TemplateArgument *StoredArgs
- = reinterpret_cast<TemplateArgument *>(
- static_cast<TemplateArgumentList *>(Mem) + 1);
- std::uninitialized_copy(Args, Args + NumArgs, StoredArgs);
- return new (Mem) TemplateArgumentList(StoredArgs, NumArgs, true);
+ void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(NumArgs));
+ return new (Mem) TemplateArgumentList(Args, NumArgs);
}
FunctionTemplateSpecializationInfo *
@@ -1187,3 +1191,69 @@ VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
unsigned ID) {
return new (C, ID) VarTemplatePartialSpecializationDecl(C);
}
+
+static TemplateParameterList *
+createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
+ // typename T
+ auto *T = TemplateTypeParmDecl::Create(
+ C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
+ /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
+ T->setImplicit(true);
+
+ // T ...Ints
+ TypeSourceInfo *TI =
+ C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
+ auto *N = NonTypeTemplateParmDecl::Create(
+ C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
+ /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
+ N->setImplicit(true);
+
+ // <typename T, T ...Ints>
+ NamedDecl *P[2] = {T, N};
+ auto *TPL = TemplateParameterList::Create(
+ C, SourceLocation(), SourceLocation(), P, SourceLocation());
+
+ // template <typename T, ...Ints> class IntSeq
+ auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
+ C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
+ /*ParameterPack=*/false, /*Id=*/nullptr, TPL);
+ TemplateTemplateParm->setImplicit(true);
+
+ // typename T
+ auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
+ C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
+ /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
+ TemplateTypeParm->setImplicit(true);
+
+ // T N
+ TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
+ QualType(TemplateTypeParm->getTypeForDecl(), 0));
+ auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
+ C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
+ /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
+ NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
+ NonTypeTemplateParm};
+
+ // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
+ return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
+ Params, SourceLocation());
+}
+
+static TemplateParameterList *createBuiltinTemplateParameterList(
+ const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
+ switch (BTK) {
+ case BTK__make_integer_seq:
+ return createMakeIntegerSeqParameterList(C, DC);
+ }
+
+ llvm_unreachable("unhandled BuiltinTemplateKind!");
+}
+
+void BuiltinTemplateDecl::anchor() {}
+
+BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
+ DeclarationName Name,
+ BuiltinTemplateKind BTK)
+ : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
+ createBuiltinTemplateParameterList(C, DC, BTK)),
+ BTK(BTK) {}
diff --git a/lib/AST/DeclarationName.cpp b/lib/AST/DeclarationName.cpp
index b7c287720027..b2f27275f49c 100644
--- a/lib/AST/DeclarationName.cpp
+++ b/lib/AST/DeclarationName.cpp
@@ -182,7 +182,7 @@ raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) {
}
case DeclarationName::CXXLiteralOperatorName:
- return OS << "operator \"\" " << N.getCXXLiteralIdentifier()->getName();
+ return OS << "operator\"\"" << N.getCXXLiteralIdentifier()->getName();
case DeclarationName::CXXConversionFunctionName: {
OS << "operator ";
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 2e066b2c42c6..bdd7a45f0850 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -331,7 +331,8 @@ DeclRefExpr::DeclRefExpr(const ASTContext &Ctx,
D(D), Loc(NameInfo.getLoc()), DNLoc(NameInfo.getInfo()) {
DeclRefExprBits.HasQualifier = QualifierLoc ? 1 : 0;
if (QualifierLoc) {
- getInternalQualifierLoc() = QualifierLoc;
+ new (getTrailingObjects<NestedNameSpecifierLoc>())
+ NestedNameSpecifierLoc(QualifierLoc);
auto *NNS = QualifierLoc.getNestedNameSpecifier();
if (NNS->isInstantiationDependent())
ExprBits.InstantiationDependent = true;
@@ -340,7 +341,7 @@ DeclRefExpr::DeclRefExpr(const ASTContext &Ctx,
}
DeclRefExprBits.HasFoundDecl = FoundD ? 1 : 0;
if (FoundD)
- getInternalFoundDecl() = FoundD;
+ *getTrailingObjects<NamedDecl *>() = FoundD;
DeclRefExprBits.HasTemplateKWAndArgsInfo
= (TemplateArgs || TemplateKWLoc.isValid()) ? 1 : 0;
DeclRefExprBits.RefersToEnclosingVariableOrCapture =
@@ -349,15 +350,15 @@ DeclRefExpr::DeclRefExpr(const ASTContext &Ctx,
bool Dependent = false;
bool InstantiationDependent = false;
bool ContainsUnexpandedParameterPack = false;
- getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc, *TemplateArgs,
- Dependent,
- InstantiationDependent,
- ContainsUnexpandedParameterPack);
+ getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
+ TemplateKWLoc, *TemplateArgs, getTrailingObjects<TemplateArgumentLoc>(),
+ Dependent, InstantiationDependent, ContainsUnexpandedParameterPack);
assert(!Dependent && "built a DeclRefExpr with dependent template args");
ExprBits.InstantiationDependent |= InstantiationDependent;
ExprBits.ContainsUnexpandedParameterPack |= ContainsUnexpandedParameterPack;
} else if (TemplateKWLoc.isValid()) {
- getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc);
+ getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
+ TemplateKWLoc);
}
DeclRefExprBits.HadMultipleCandidates = 0;
@@ -394,15 +395,13 @@ DeclRefExpr *DeclRefExpr::Create(const ASTContext &Context,
if (D == FoundD)
FoundD = nullptr;
- std::size_t Size = sizeof(DeclRefExpr);
- if (QualifierLoc)
- Size += sizeof(NestedNameSpecifierLoc);
- if (FoundD)
- Size += sizeof(NamedDecl *);
- if (TemplateArgs)
- Size += ASTTemplateKWAndArgsInfo::sizeFor(TemplateArgs->size());
- else if (TemplateKWLoc.isValid())
- Size += ASTTemplateKWAndArgsInfo::sizeFor(0);
+ bool HasTemplateKWAndArgsInfo = TemplateArgs || TemplateKWLoc.isValid();
+ std::size_t Size =
+ totalSizeToAlloc<NestedNameSpecifierLoc, NamedDecl *,
+ ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(
+ QualifierLoc ? 1 : 0, FoundD ? 1 : 0,
+ HasTemplateKWAndArgsInfo ? 1 : 0,
+ TemplateArgs ? TemplateArgs->size() : 0);
void *Mem = Context.Allocate(Size, llvm::alignOf<DeclRefExpr>());
return new (Mem) DeclRefExpr(Context, QualifierLoc, TemplateKWLoc, D,
@@ -415,14 +414,12 @@ DeclRefExpr *DeclRefExpr::CreateEmpty(const ASTContext &Context,
bool HasFoundDecl,
bool HasTemplateKWAndArgsInfo,
unsigned NumTemplateArgs) {
- std::size_t Size = sizeof(DeclRefExpr);
- if (HasQualifier)
- Size += sizeof(NestedNameSpecifierLoc);
- if (HasFoundDecl)
- Size += sizeof(NamedDecl *);
- if (HasTemplateKWAndArgsInfo)
- Size += ASTTemplateKWAndArgsInfo::sizeFor(NumTemplateArgs);
-
+ assert(NumTemplateArgs == 0 || HasTemplateKWAndArgsInfo);
+ std::size_t Size =
+ totalSizeToAlloc<NestedNameSpecifierLoc, NamedDecl *,
+ ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(
+ HasQualifier ? 1 : 0, HasFoundDecl ? 1 : 0, HasTemplateKWAndArgsInfo,
+ NumTemplateArgs);
void *Mem = Context.Allocate(Size, llvm::alignOf<DeclRefExpr>());
return new (Mem) DeclRefExpr(EmptyShell());
}
@@ -490,7 +487,6 @@ std::string PredefinedExpr::ComputeName(IdentType IT, const Decl *CurrentDecl) {
else
MC->mangleName(ND, Out);
- Out.flush();
if (!Buffer.empty() && Buffer.front() == '\01')
return Buffer.substr(1);
return Buffer.str();
@@ -652,7 +648,6 @@ std::string PredefinedExpr::ComputeName(IdentType IT, const Decl *CurrentDecl) {
Out << Proto;
- Out.flush();
return Name.str().str();
}
if (const CapturedDecl *CD = dyn_cast<CapturedDecl>(CurrentDecl)) {
@@ -684,7 +679,6 @@ std::string PredefinedExpr::ComputeName(IdentType IT, const Decl *CurrentDecl) {
MD->getSelector().print(Out);
Out << ']';
- Out.flush();
return Name.str().str();
}
if (isa<TranslationUnitDecl>(CurrentDecl) && IT == PrettyFunction) {
@@ -1002,15 +996,33 @@ void StringLiteral::setString(const ASTContext &C, StringRef Str,
/// can have escape sequences in them in addition to the usual trigraph and
/// escaped newline business. This routine handles this complexity.
///
-SourceLocation StringLiteral::
-getLocationOfByte(unsigned ByteNo, const SourceManager &SM,
- const LangOptions &Features, const TargetInfo &Target) const {
+/// The *StartToken sets the first token to be searched in this function and
+/// the *StartTokenByteOffset is the byte offset of the first token. Before
+/// returning, it updates the *StartToken to the TokNo of the token being found
+/// and sets *StartTokenByteOffset to the byte offset of the token in the
+/// string.
+/// Using these two parameters can reduce the time complexity from O(n^2) to
+/// O(n) if one wants to get the location of byte for all the tokens in a
+/// string.
+///
+SourceLocation
+StringLiteral::getLocationOfByte(unsigned ByteNo, const SourceManager &SM,
+ const LangOptions &Features,
+ const TargetInfo &Target, unsigned *StartToken,
+ unsigned *StartTokenByteOffset) const {
assert((Kind == StringLiteral::Ascii || Kind == StringLiteral::UTF8) &&
"Only narrow string literals are currently supported");
// Loop over all of the tokens in this string until we find the one that
// contains the byte we're looking for.
unsigned TokNo = 0;
+ unsigned StringOffset = 0;
+ if (StartToken)
+ TokNo = *StartToken;
+ if (StartTokenByteOffset) {
+ StringOffset = *StartTokenByteOffset;
+ ByteNo -= StringOffset;
+ }
while (1) {
assert(TokNo < getNumConcatenated() && "Invalid byte number!");
SourceLocation StrTokLoc = getStrTokenLoc(TokNo);
@@ -1019,14 +1031,20 @@ getLocationOfByte(unsigned ByteNo, const SourceManager &SM,
// the string literal, not the identifier for the macro it is potentially
// expanded through.
SourceLocation StrTokSpellingLoc = SM.getSpellingLoc(StrTokLoc);
-
+
// Re-lex the token to get its length and original spelling.
- std::pair<FileID, unsigned> LocInfo =SM.getDecomposedLoc(StrTokSpellingLoc);
+ std::pair<FileID, unsigned> LocInfo =
+ SM.getDecomposedLoc(StrTokSpellingLoc);
bool Invalid = false;
StringRef Buffer = SM.getBufferData(LocInfo.first, &Invalid);
- if (Invalid)
+ if (Invalid) {
+ if (StartTokenByteOffset != nullptr)
+ *StartTokenByteOffset = StringOffset;
+ if (StartToken != nullptr)
+ *StartToken = TokNo;
return StrTokSpellingLoc;
-
+ }
+
const char *StrData = Buffer.data()+LocInfo.second;
// Create a lexer starting at the beginning of this token.
@@ -1042,14 +1060,19 @@ getLocationOfByte(unsigned ByteNo, const SourceManager &SM,
// If the byte is in this token, return the location of the byte.
if (ByteNo < TokNumBytes ||
(ByteNo == TokNumBytes && TokNo == getNumConcatenated() - 1)) {
- unsigned Offset = SLP.getOffsetOfStringByte(TheTok, ByteNo);
-
+ unsigned Offset = SLP.getOffsetOfStringByte(TheTok, ByteNo);
+
// Now that we know the offset of the token in the spelling, use the
// preprocessor to get the offset in the original source.
+ if (StartTokenByteOffset != nullptr)
+ *StartTokenByteOffset = StringOffset;
+ if (StartToken != nullptr)
+ *StartToken = TokNo;
return Lexer::AdvanceToTokenCharacter(StrTokLoc, Offset, SM, Features);
}
-
+
// Move to the next string token.
+ StringOffset += TokNumBytes;
++TokNo;
ByteNo -= TokNumBytes;
}
@@ -1074,6 +1097,7 @@ StringRef UnaryOperator::getOpcodeStr(Opcode Op) {
case UO_Real: return "__real";
case UO_Imag: return "__imag";
case UO_Extension: return "__extension__";
+ case UO_Coawait: return "co_await";
}
llvm_unreachable("Unknown unary operator");
}
@@ -1090,6 +1114,7 @@ UnaryOperator::getOverloadedOpcode(OverloadedOperatorKind OO, bool Postfix) {
case OO_Minus: return UO_Minus;
case OO_Tilde: return UO_Not;
case OO_Exclaim: return UO_LNot;
+ case OO_Coawait: return UO_Coawait;
}
}
@@ -1103,6 +1128,7 @@ OverloadedOperatorKind UnaryOperator::getOverloadedOperator(Opcode Opc) {
case UO_Minus: return OO_Minus;
case UO_Not: return OO_Tilde;
case UO_LNot: return OO_Exclaim;
+ case UO_Coawait: return OO_Coawait;
default: return OO_None;
}
}
@@ -1288,9 +1314,8 @@ OffsetOfExpr *OffsetOfExpr::Create(const ASTContext &C, QualType type,
ArrayRef<OffsetOfNode> comps,
ArrayRef<Expr*> exprs,
SourceLocation RParenLoc) {
- void *Mem = C.Allocate(sizeof(OffsetOfExpr) +
- sizeof(OffsetOfNode) * comps.size() +
- sizeof(Expr*) * exprs.size());
+ void *Mem = C.Allocate(
+ totalSizeToAlloc<OffsetOfNode, Expr *>(comps.size(), exprs.size()));
return new (Mem) OffsetOfExpr(C, type, OperatorLoc, tsi, comps, exprs,
RParenLoc);
@@ -1298,9 +1323,8 @@ OffsetOfExpr *OffsetOfExpr::Create(const ASTContext &C, QualType type,
OffsetOfExpr *OffsetOfExpr::CreateEmpty(const ASTContext &C,
unsigned numComps, unsigned numExprs) {
- void *Mem = C.Allocate(sizeof(OffsetOfExpr) +
- sizeof(OffsetOfNode) * numComps +
- sizeof(Expr*) * numExprs);
+ void *Mem =
+ C.Allocate(totalSizeToAlloc<OffsetOfNode, Expr *>(numComps, numExprs));
return new (Mem) OffsetOfExpr(numComps, numExprs);
}
@@ -1330,7 +1354,7 @@ OffsetOfExpr::OffsetOfExpr(const ASTContext &C, QualType type,
}
}
-IdentifierInfo *OffsetOfExpr::OffsetOfNode::getFieldName() const {
+IdentifierInfo *OffsetOfNode::getFieldName() const {
assert(getKind() == Field || getKind() == Identifier);
if (getKind() == Field)
return getField()->getIdentifier();
@@ -1382,18 +1406,17 @@ MemberExpr *MemberExpr::Create(
ValueDecl *memberdecl, DeclAccessPair founddecl,
DeclarationNameInfo nameinfo, const TemplateArgumentListInfo *targs,
QualType ty, ExprValueKind vk, ExprObjectKind ok) {
- std::size_t Size = sizeof(MemberExpr);
bool hasQualOrFound = (QualifierLoc ||
founddecl.getDecl() != memberdecl ||
founddecl.getAccess() != memberdecl->getAccess());
- if (hasQualOrFound)
- Size += sizeof(MemberNameQualifier);
- if (targs)
- Size += ASTTemplateKWAndArgsInfo::sizeFor(targs->size());
- else if (TemplateKWLoc.isValid())
- Size += ASTTemplateKWAndArgsInfo::sizeFor(0);
+ bool HasTemplateKWAndArgsInfo = targs || TemplateKWLoc.isValid();
+ std::size_t Size =
+ totalSizeToAlloc<MemberExprNameQualifier, ASTTemplateKWAndArgsInfo,
+ TemplateArgumentLoc>(hasQualOrFound ? 1 : 0,
+ HasTemplateKWAndArgsInfo ? 1 : 0,
+ targs ? targs->size() : 0);
void *Mem = C.Allocate(Size, llvm::alignOf<MemberExpr>());
MemberExpr *E = new (Mem)
@@ -1412,7 +1435,8 @@ MemberExpr *MemberExpr::Create(
E->HasQualifierOrFoundDecl = true;
- MemberNameQualifier *NQ = E->getMemberQualifier();
+ MemberExprNameQualifier *NQ =
+ E->getTrailingObjects<MemberExprNameQualifier>();
NQ->QualifierLoc = QualifierLoc;
NQ->FoundDecl = founddecl;
}
@@ -1423,14 +1447,14 @@ MemberExpr *MemberExpr::Create(
bool Dependent = false;
bool InstantiationDependent = false;
bool ContainsUnexpandedParameterPack = false;
- E->getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc, *targs,
- Dependent,
- InstantiationDependent,
- ContainsUnexpandedParameterPack);
+ E->getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
+ TemplateKWLoc, *targs, E->getTrailingObjects<TemplateArgumentLoc>(),
+ Dependent, InstantiationDependent, ContainsUnexpandedParameterPack);
if (InstantiationDependent)
E->setInstantiationDependent(true);
} else if (TemplateKWLoc.isValid()) {
- E->getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc);
+ E->getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
+ TemplateKWLoc);
}
return E;
@@ -1719,9 +1743,9 @@ Expr *CastExpr::getSubExprAsWritten() {
CXXBaseSpecifier **CastExpr::path_buffer() {
switch (getStmtClass()) {
#define ABSTRACT_STMT(x)
-#define CASTEXPR(Type, Base) \
- case Stmt::Type##Class: \
- return reinterpret_cast<CXXBaseSpecifier**>(static_cast<Type*>(this)+1);
+#define CASTEXPR(Type, Base) \
+ case Stmt::Type##Class: \
+ return static_cast<Type *>(this)->getTrailingObjects<CXXBaseSpecifier *>();
#define STMT(Type, Base)
#include "clang/AST/StmtNodes.inc"
default:
@@ -1729,28 +1753,23 @@ CXXBaseSpecifier **CastExpr::path_buffer() {
}
}
-void CastExpr::setCastPath(const CXXCastPath &Path) {
- assert(Path.size() == path_size());
- memcpy(path_buffer(), Path.data(), Path.size() * sizeof(CXXBaseSpecifier*));
-}
-
ImplicitCastExpr *ImplicitCastExpr::Create(const ASTContext &C, QualType T,
CastKind Kind, Expr *Operand,
const CXXCastPath *BasePath,
ExprValueKind VK) {
unsigned PathSize = (BasePath ? BasePath->size() : 0);
- void *Buffer =
- C.Allocate(sizeof(ImplicitCastExpr) + PathSize * sizeof(CXXBaseSpecifier*));
+ void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));
ImplicitCastExpr *E =
new (Buffer) ImplicitCastExpr(T, Kind, Operand, PathSize, VK);
- if (PathSize) E->setCastPath(*BasePath);
+ if (PathSize)
+ std::uninitialized_copy_n(BasePath->data(), BasePath->size(),
+ E->getTrailingObjects<CXXBaseSpecifier *>());
return E;
}
ImplicitCastExpr *ImplicitCastExpr::CreateEmpty(const ASTContext &C,
unsigned PathSize) {
- void *Buffer =
- C.Allocate(sizeof(ImplicitCastExpr) + PathSize * sizeof(CXXBaseSpecifier*));
+ void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));
return new (Buffer) ImplicitCastExpr(EmptyShell(), PathSize);
}
@@ -1761,18 +1780,18 @@ CStyleCastExpr *CStyleCastExpr::Create(const ASTContext &C, QualType T,
TypeSourceInfo *WrittenTy,
SourceLocation L, SourceLocation R) {
unsigned PathSize = (BasePath ? BasePath->size() : 0);
- void *Buffer =
- C.Allocate(sizeof(CStyleCastExpr) + PathSize * sizeof(CXXBaseSpecifier*));
+ void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));
CStyleCastExpr *E =
new (Buffer) CStyleCastExpr(T, VK, K, Op, PathSize, WrittenTy, L, R);
- if (PathSize) E->setCastPath(*BasePath);
+ if (PathSize)
+ std::uninitialized_copy_n(BasePath->data(), BasePath->size(),
+ E->getTrailingObjects<CXXBaseSpecifier *>());
return E;
}
CStyleCastExpr *CStyleCastExpr::CreateEmpty(const ASTContext &C,
unsigned PathSize) {
- void *Buffer =
- C.Allocate(sizeof(CStyleCastExpr) + PathSize * sizeof(CXXBaseSpecifier*));
+ void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));
return new (Buffer) CStyleCastExpr(EmptyShell(), PathSize);
}
@@ -2045,6 +2064,9 @@ bool Expr::isUnusedResultAWarning(const Expr *&WarnE, SourceLocation &Loc,
case UO_LNot:
case UO_Deref:
break;
+ case UO_Coawait:
+ // This is just the 'operator co_await' call inside the guts of a
+ // dependent co_await call.
case UO_PostInc:
case UO_PostDec:
case UO_PreInc:
@@ -2880,7 +2902,10 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef,
return cast<CXXDefaultInitExpr>(this)->getExpr()
->isConstantInitializer(Ctx, false, Culprit);
}
- if (isEvaluatable(Ctx))
+ // Allow certain forms of UB in constant initializers: signed integer
+ // overflow and floating-point division by zero. We'll give a warning on
+ // these, but they're common enough that we have to accept them.
+ if (isEvaluatable(Ctx, SE_AllowUndefinedBehavior))
return true;
if (Culprit)
*Culprit = this;
@@ -2993,6 +3018,7 @@ bool Expr::HasSideEffects(const ASTContext &Ctx,
return true;
case MSPropertyRefExprClass:
+ case MSPropertySubscriptExprClass:
case CompoundAssignOperatorClass:
case VAArgExprClass:
case AtomicExprClass:
@@ -3000,6 +3026,8 @@ bool Expr::HasSideEffects(const ASTContext &Ctx,
case CXXNewExprClass:
case CXXDeleteExprClass:
case ExprWithCleanupsClass:
+ case CoawaitExprClass:
+ case CoyieldExprClass:
// These always have a side-effect.
return true;
@@ -3012,6 +3040,7 @@ bool Expr::HasSideEffects(const ASTContext &Ctx,
case ParenExprClass:
case ArraySubscriptExprClass:
+ case OMPArraySectionExprClass:
case MemberExprClass:
case ConditionalOperatorClass:
case BinaryConditionalOperatorClass:
@@ -3246,9 +3275,20 @@ Expr::isNullPointerConstant(ASTContext &Ctx,
// Check that it is a cast to void*.
if (const PointerType *PT = CE->getType()->getAs<PointerType>()) {
QualType Pointee = PT->getPointeeType();
- if (!Pointee.hasQualifiers() &&
- Pointee->isVoidType() && // to void*
- CE->getSubExpr()->getType()->isIntegerType()) // from int.
+ Qualifiers Q = Pointee.getQualifiers();
+ // In OpenCL v2.0 generic address space acts as a placeholder
+ // and should be ignored.
+ bool IsASValid = true;
+ if (Ctx.getLangOpts().OpenCLVersion >= 200) {
+ if (Pointee.getAddressSpace() == LangAS::opencl_generic)
+ Q.removeAddressSpace();
+ else
+ IsASValid = false;
+ }
+
+ if (IsASValid && !Q.hasQualifiers() &&
+ Pointee->isVoidType() && // to void*
+ CE->getSubExpr()->getType()->isIntegerType()) // from int.
return CE->getSubExpr()->isNullPointerConstant(Ctx, NPC);
}
}
@@ -3429,6 +3469,18 @@ bool Expr::refersToVectorElement() const {
return false;
}
+bool Expr::refersToGlobalRegisterVar() const {
+ const Expr *E = this->IgnoreParenImpCasts();
+
+ if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
+ if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
+ if (VD->getStorageClass() == SC_Register &&
+ VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())
+ return true;
+
+ return false;
+}
+
/// isArrow - Return true if the base expression is a pointer to vector,
/// return false if the base expression is a vector.
bool ExtVectorElementExpr::isArrow() const {
@@ -3464,7 +3516,7 @@ bool ExtVectorElementExpr::containsDuplicateElements() const {
/// getEncodedElementAccess - We encode the fields as a llvm ConstantArray.
void ExtVectorElementExpr::getEncodedElementAccess(
- SmallVectorImpl<unsigned> &Elts) const {
+ SmallVectorImpl<uint32_t> &Elts) const {
StringRef Comp = Accessor->getName();
if (Comp[0] == 's' || Comp[0] == 'S')
Comp = Comp.substr(1);
@@ -3492,285 +3544,6 @@ void ExtVectorElementExpr::getEncodedElementAccess(
}
}
-ObjCMessageExpr::ObjCMessageExpr(QualType T,
- ExprValueKind VK,
- SourceLocation LBracLoc,
- SourceLocation SuperLoc,
- bool IsInstanceSuper,
- QualType SuperType,
- Selector Sel,
- ArrayRef<SourceLocation> SelLocs,
- SelectorLocationsKind SelLocsK,
- ObjCMethodDecl *Method,
- ArrayRef<Expr *> Args,
- SourceLocation RBracLoc,
- bool isImplicit)
- : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary,
- /*TypeDependent=*/false, /*ValueDependent=*/false,
- /*InstantiationDependent=*/false,
- /*ContainsUnexpandedParameterPack=*/false),
- SelectorOrMethod(reinterpret_cast<uintptr_t>(Method? Method
- : Sel.getAsOpaquePtr())),
- Kind(IsInstanceSuper? SuperInstance : SuperClass),
- HasMethod(Method != nullptr), IsDelegateInitCall(false),
- IsImplicit(isImplicit), SuperLoc(SuperLoc), LBracLoc(LBracLoc),
- RBracLoc(RBracLoc)
-{
- initArgsAndSelLocs(Args, SelLocs, SelLocsK);
- setReceiverPointer(SuperType.getAsOpaquePtr());
-}
-
-ObjCMessageExpr::ObjCMessageExpr(QualType T,
- ExprValueKind VK,
- SourceLocation LBracLoc,
- TypeSourceInfo *Receiver,
- Selector Sel,
- ArrayRef<SourceLocation> SelLocs,
- SelectorLocationsKind SelLocsK,
- ObjCMethodDecl *Method,
- ArrayRef<Expr *> Args,
- SourceLocation RBracLoc,
- bool isImplicit)
- : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, T->isDependentType(),
- T->isDependentType(), T->isInstantiationDependentType(),
- T->containsUnexpandedParameterPack()),
- SelectorOrMethod(reinterpret_cast<uintptr_t>(Method? Method
- : Sel.getAsOpaquePtr())),
- Kind(Class),
- HasMethod(Method != nullptr), IsDelegateInitCall(false),
- IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc)
-{
- initArgsAndSelLocs(Args, SelLocs, SelLocsK);
- setReceiverPointer(Receiver);
-}
-
-ObjCMessageExpr::ObjCMessageExpr(QualType T,
- ExprValueKind VK,
- SourceLocation LBracLoc,
- Expr *Receiver,
- Selector Sel,
- ArrayRef<SourceLocation> SelLocs,
- SelectorLocationsKind SelLocsK,
- ObjCMethodDecl *Method,
- ArrayRef<Expr *> Args,
- SourceLocation RBracLoc,
- bool isImplicit)
- : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, Receiver->isTypeDependent(),
- Receiver->isTypeDependent(),
- Receiver->isInstantiationDependent(),
- Receiver->containsUnexpandedParameterPack()),
- SelectorOrMethod(reinterpret_cast<uintptr_t>(Method? Method
- : Sel.getAsOpaquePtr())),
- Kind(Instance),
- HasMethod(Method != nullptr), IsDelegateInitCall(false),
- IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc)
-{
- initArgsAndSelLocs(Args, SelLocs, SelLocsK);
- setReceiverPointer(Receiver);
-}
-
-void ObjCMessageExpr::initArgsAndSelLocs(ArrayRef<Expr *> Args,
- ArrayRef<SourceLocation> SelLocs,
- SelectorLocationsKind SelLocsK) {
- setNumArgs(Args.size());
- Expr **MyArgs = getArgs();
- for (unsigned I = 0; I != Args.size(); ++I) {
- if (Args[I]->isTypeDependent())
- ExprBits.TypeDependent = true;
- if (Args[I]->isValueDependent())
- ExprBits.ValueDependent = true;
- if (Args[I]->isInstantiationDependent())
- ExprBits.InstantiationDependent = true;
- if (Args[I]->containsUnexpandedParameterPack())
- ExprBits.ContainsUnexpandedParameterPack = true;
-
- MyArgs[I] = Args[I];
- }
-
- SelLocsKind = SelLocsK;
- if (!isImplicit()) {
- if (SelLocsK == SelLoc_NonStandard)
- std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs());
- }
-}
-
-ObjCMessageExpr *ObjCMessageExpr::Create(const ASTContext &Context, QualType T,
- ExprValueKind VK,
- SourceLocation LBracLoc,
- SourceLocation SuperLoc,
- bool IsInstanceSuper,
- QualType SuperType,
- Selector Sel,
- ArrayRef<SourceLocation> SelLocs,
- ObjCMethodDecl *Method,
- ArrayRef<Expr *> Args,
- SourceLocation RBracLoc,
- bool isImplicit) {
- assert((!SelLocs.empty() || isImplicit) &&
- "No selector locs for non-implicit message");
- ObjCMessageExpr *Mem;
- SelectorLocationsKind SelLocsK = SelectorLocationsKind();
- if (isImplicit)
- Mem = alloc(Context, Args.size(), 0);
- else
- Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
- return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, SuperLoc, IsInstanceSuper,
- SuperType, Sel, SelLocs, SelLocsK,
- Method, Args, RBracLoc, isImplicit);
-}
-
-ObjCMessageExpr *ObjCMessageExpr::Create(const ASTContext &Context, QualType T,
- ExprValueKind VK,
- SourceLocation LBracLoc,
- TypeSourceInfo *Receiver,
- Selector Sel,
- ArrayRef<SourceLocation> SelLocs,
- ObjCMethodDecl *Method,
- ArrayRef<Expr *> Args,
- SourceLocation RBracLoc,
- bool isImplicit) {
- assert((!SelLocs.empty() || isImplicit) &&
- "No selector locs for non-implicit message");
- ObjCMessageExpr *Mem;
- SelectorLocationsKind SelLocsK = SelectorLocationsKind();
- if (isImplicit)
- Mem = alloc(Context, Args.size(), 0);
- else
- Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
- return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel,
- SelLocs, SelLocsK, Method, Args, RBracLoc,
- isImplicit);
-}
-
-ObjCMessageExpr *ObjCMessageExpr::Create(const ASTContext &Context, QualType T,
- ExprValueKind VK,
- SourceLocation LBracLoc,
- Expr *Receiver,
- Selector Sel,
- ArrayRef<SourceLocation> SelLocs,
- ObjCMethodDecl *Method,
- ArrayRef<Expr *> Args,
- SourceLocation RBracLoc,
- bool isImplicit) {
- assert((!SelLocs.empty() || isImplicit) &&
- "No selector locs for non-implicit message");
- ObjCMessageExpr *Mem;
- SelectorLocationsKind SelLocsK = SelectorLocationsKind();
- if (isImplicit)
- Mem = alloc(Context, Args.size(), 0);
- else
- Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
- return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel,
- SelLocs, SelLocsK, Method, Args, RBracLoc,
- isImplicit);
-}
-
-ObjCMessageExpr *ObjCMessageExpr::CreateEmpty(const ASTContext &Context,
- unsigned NumArgs,
- unsigned NumStoredSelLocs) {
- ObjCMessageExpr *Mem = alloc(Context, NumArgs, NumStoredSelLocs);
- return new (Mem) ObjCMessageExpr(EmptyShell(), NumArgs);
-}
-
-ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C,
- ArrayRef<Expr *> Args,
- SourceLocation RBraceLoc,
- ArrayRef<SourceLocation> SelLocs,
- Selector Sel,
- SelectorLocationsKind &SelLocsK) {
- SelLocsK = hasStandardSelectorLocs(Sel, SelLocs, Args, RBraceLoc);
- unsigned NumStoredSelLocs = (SelLocsK == SelLoc_NonStandard) ? SelLocs.size()
- : 0;
- return alloc(C, Args.size(), NumStoredSelLocs);
-}
-
-ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C,
- unsigned NumArgs,
- unsigned NumStoredSelLocs) {
- unsigned Size = sizeof(ObjCMessageExpr) + sizeof(void *) +
- NumArgs * sizeof(Expr *) + NumStoredSelLocs * sizeof(SourceLocation);
- return (ObjCMessageExpr *)C.Allocate(Size,
- llvm::AlignOf<ObjCMessageExpr>::Alignment);
-}
-
-void ObjCMessageExpr::getSelectorLocs(
- SmallVectorImpl<SourceLocation> &SelLocs) const {
- for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)
- SelLocs.push_back(getSelectorLoc(i));
-}
-
-SourceRange ObjCMessageExpr::getReceiverRange() const {
- switch (getReceiverKind()) {
- case Instance:
- return getInstanceReceiver()->getSourceRange();
-
- case Class:
- return getClassReceiverTypeInfo()->getTypeLoc().getSourceRange();
-
- case SuperInstance:
- case SuperClass:
- return getSuperLoc();
- }
-
- llvm_unreachable("Invalid ReceiverKind!");
-}
-
-Selector ObjCMessageExpr::getSelector() const {
- if (HasMethod)
- return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod)
- ->getSelector();
- return Selector(SelectorOrMethod);
-}
-
-QualType ObjCMessageExpr::getReceiverType() const {
- switch (getReceiverKind()) {
- case Instance:
- return getInstanceReceiver()->getType();
- case Class:
- return getClassReceiver();
- case SuperInstance:
- case SuperClass:
- return getSuperType();
- }
-
- llvm_unreachable("unexpected receiver kind");
-}
-
-ObjCInterfaceDecl *ObjCMessageExpr::getReceiverInterface() const {
- QualType T = getReceiverType();
-
- if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
- return Ptr->getInterfaceDecl();
-
- if (const ObjCObjectType *Ty = T->getAs<ObjCObjectType>())
- return Ty->getInterface();
-
- return nullptr;
-}
-
-QualType ObjCPropertyRefExpr::getReceiverType(const ASTContext &ctx) const {
- if (isClassReceiver())
- return ctx.getObjCInterfaceType(getClassReceiver());
-
- if (isSuperReceiver())
- return getSuperReceiverType();
-
- return getBase()->getType();
-}
-
-StringRef ObjCBridgedCastExpr::getBridgeKindName() const {
- switch (getBridgeKind()) {
- case OBC_Bridge:
- return "__bridge";
- case OBC_BridgeTransfer:
- return "__bridge_transfer";
- case OBC_BridgeRetained:
- return "__bridge_retained";
- }
-
- llvm_unreachable("Invalid BridgeKind!");
-}
-
ShuffleVectorExpr::ShuffleVectorExpr(const ASTContext &C, ArrayRef<Expr*> args,
QualType Type, SourceLocation BLoc,
SourceLocation RP)
@@ -3883,7 +3656,7 @@ DesignatedInitExpr::DesignatedInitExpr(const ASTContext &C, QualType Ty,
this->Designators = new (C) Designator[NumDesignators];
// Record the initializer itself.
- child_range Child = children();
+ child_iterator Child = child_begin();
*Child++ = Init;
// Copy the designators and their subexpressions, computing
@@ -3939,7 +3712,8 @@ DesignatedInitExpr::Create(const ASTContext &C, Designator *Designators,
SourceLocation ColonOrEqualLoc,
bool UsesColonSyntax, Expr *Init) {
void *Mem = C.Allocate(sizeof(DesignatedInitExpr) +
- sizeof(Stmt *) * (IndexExprs.size() + 1), 8);
+ sizeof(Stmt *) * (IndexExprs.size() + 1),
+ llvm::alignOf<DesignatedInitExpr>());
return new (Mem) DesignatedInitExpr(C, C.VoidTy, NumDesignators, Designators,
ColonOrEqualLoc, UsesColonSyntax,
IndexExprs, Init);
@@ -4154,19 +3928,6 @@ PseudoObjectExpr::PseudoObjectExpr(QualType type, ExprValueKind VK,
}
//===----------------------------------------------------------------------===//
-// ExprIterator.
-//===----------------------------------------------------------------------===//
-
-Expr* ExprIterator::operator[](size_t idx) { return cast<Expr>(I[idx]); }
-Expr* ExprIterator::operator*() const { return cast<Expr>(*I); }
-Expr* ExprIterator::operator->() const { return cast<Expr>(*I); }
-const Expr* ConstExprIterator::operator[](size_t idx) const {
- return cast<Expr>(I[idx]);
-}
-const Expr* ConstExprIterator::operator*() const { return cast<Expr>(*I); }
-const Expr* ConstExprIterator::operator->() const { return cast<Expr>(*I); }
-
-//===----------------------------------------------------------------------===//
// Child Iterators for iterating over subexpressions/substatements
//===----------------------------------------------------------------------===//
@@ -4179,134 +3940,11 @@ Stmt::child_range UnaryExprOrTypeTraitExpr::children() {
if (const VariableArrayType* T = dyn_cast<VariableArrayType>(
getArgumentType().getTypePtr()))
return child_range(child_iterator(T), child_iterator());
- return child_range();
+ return child_range(child_iterator(), child_iterator());
}
return child_range(&Argument.Ex, &Argument.Ex + 1);
}
-// ObjCMessageExpr
-Stmt::child_range ObjCMessageExpr::children() {
- Stmt **begin;
- if (getReceiverKind() == Instance)
- begin = reinterpret_cast<Stmt **>(this + 1);
- else
- begin = reinterpret_cast<Stmt **>(getArgs());
- return child_range(begin,
- reinterpret_cast<Stmt **>(getArgs() + getNumArgs()));
-}
-
-ObjCArrayLiteral::ObjCArrayLiteral(ArrayRef<Expr *> Elements,
- QualType T, ObjCMethodDecl *Method,
- SourceRange SR)
- : Expr(ObjCArrayLiteralClass, T, VK_RValue, OK_Ordinary,
- false, false, false, false),
- NumElements(Elements.size()), Range(SR), ArrayWithObjectsMethod(Method)
-{
- Expr **SaveElements = getElements();
- for (unsigned I = 0, N = Elements.size(); I != N; ++I) {
- if (Elements[I]->isTypeDependent() || Elements[I]->isValueDependent())
- ExprBits.ValueDependent = true;
- if (Elements[I]->isInstantiationDependent())
- ExprBits.InstantiationDependent = true;
- if (Elements[I]->containsUnexpandedParameterPack())
- ExprBits.ContainsUnexpandedParameterPack = true;
-
- SaveElements[I] = Elements[I];
- }
-}
-
-ObjCArrayLiteral *ObjCArrayLiteral::Create(const ASTContext &C,
- ArrayRef<Expr *> Elements,
- QualType T, ObjCMethodDecl * Method,
- SourceRange SR) {
- void *Mem = C.Allocate(sizeof(ObjCArrayLiteral)
- + Elements.size() * sizeof(Expr *));
- return new (Mem) ObjCArrayLiteral(Elements, T, Method, SR);
-}
-
-ObjCArrayLiteral *ObjCArrayLiteral::CreateEmpty(const ASTContext &C,
- unsigned NumElements) {
-
- void *Mem = C.Allocate(sizeof(ObjCArrayLiteral)
- + NumElements * sizeof(Expr *));
- return new (Mem) ObjCArrayLiteral(EmptyShell(), NumElements);
-}
-
-ObjCDictionaryLiteral::ObjCDictionaryLiteral(
- ArrayRef<ObjCDictionaryElement> VK,
- bool HasPackExpansions,
- QualType T, ObjCMethodDecl *method,
- SourceRange SR)
- : Expr(ObjCDictionaryLiteralClass, T, VK_RValue, OK_Ordinary, false, false,
- false, false),
- NumElements(VK.size()), HasPackExpansions(HasPackExpansions), Range(SR),
- DictWithObjectsMethod(method)
-{
- KeyValuePair *KeyValues = getKeyValues();
- ExpansionData *Expansions = getExpansionData();
- for (unsigned I = 0; I < NumElements; I++) {
- if (VK[I].Key->isTypeDependent() || VK[I].Key->isValueDependent() ||
- VK[I].Value->isTypeDependent() || VK[I].Value->isValueDependent())
- ExprBits.ValueDependent = true;
- if (VK[I].Key->isInstantiationDependent() ||
- VK[I].Value->isInstantiationDependent())
- ExprBits.InstantiationDependent = true;
- if (VK[I].EllipsisLoc.isInvalid() &&
- (VK[I].Key->containsUnexpandedParameterPack() ||
- VK[I].Value->containsUnexpandedParameterPack()))
- ExprBits.ContainsUnexpandedParameterPack = true;
-
- KeyValues[I].Key = VK[I].Key;
- KeyValues[I].Value = VK[I].Value;
- if (Expansions) {
- Expansions[I].EllipsisLoc = VK[I].EllipsisLoc;
- if (VK[I].NumExpansions)
- Expansions[I].NumExpansionsPlusOne = *VK[I].NumExpansions + 1;
- else
- Expansions[I].NumExpansionsPlusOne = 0;
- }
- }
-}
-
-ObjCDictionaryLiteral *
-ObjCDictionaryLiteral::Create(const ASTContext &C,
- ArrayRef<ObjCDictionaryElement> VK,
- bool HasPackExpansions,
- QualType T, ObjCMethodDecl *method,
- SourceRange SR) {
- unsigned ExpansionsSize = 0;
- if (HasPackExpansions)
- ExpansionsSize = sizeof(ExpansionData) * VK.size();
-
- void *Mem = C.Allocate(sizeof(ObjCDictionaryLiteral) +
- sizeof(KeyValuePair) * VK.size() + ExpansionsSize);
- return new (Mem) ObjCDictionaryLiteral(VK, HasPackExpansions, T, method, SR);
-}
-
-ObjCDictionaryLiteral *
-ObjCDictionaryLiteral::CreateEmpty(const ASTContext &C, unsigned NumElements,
- bool HasPackExpansions) {
- unsigned ExpansionsSize = 0;
- if (HasPackExpansions)
- ExpansionsSize = sizeof(ExpansionData) * NumElements;
- void *Mem = C.Allocate(sizeof(ObjCDictionaryLiteral) +
- sizeof(KeyValuePair) * NumElements + ExpansionsSize);
- return new (Mem) ObjCDictionaryLiteral(EmptyShell(), NumElements,
- HasPackExpansions);
-}
-
-ObjCSubscriptRefExpr *ObjCSubscriptRefExpr::Create(const ASTContext &C,
- Expr *base,
- Expr *key, QualType T,
- ObjCMethodDecl *getMethod,
- ObjCMethodDecl *setMethod,
- SourceLocation RB) {
- void *Mem = C.Allocate(sizeof(ObjCSubscriptRefExpr));
- return new (Mem) ObjCSubscriptRefExpr(base, key, T, VK_LValue,
- OK_ObjCSubscript,
- getMethod, setMethod, RB);
-}
-
AtomicExpr::AtomicExpr(SourceLocation BLoc, ArrayRef<Expr*> args,
QualType t, AtomicOp op, SourceLocation RP)
: Expr(AtomicExprClass, t, VK_RValue, OK_Ordinary,
@@ -4373,3 +4011,29 @@ unsigned AtomicExpr::getNumSubExprs(AtomicOp Op) {
}
llvm_unreachable("unknown atomic op");
}
+
+QualType OMPArraySectionExpr::getBaseOriginalType(Expr *Base) {
+ unsigned ArraySectionCount = 0;
+ while (auto *OASE = dyn_cast<OMPArraySectionExpr>(Base->IgnoreParens())) {
+ Base = OASE->getBase();
+ ++ArraySectionCount;
+ }
+ while (auto *ASE = dyn_cast<ArraySubscriptExpr>(Base->IgnoreParens())) {
+ Base = ASE->getBase();
+ ++ArraySectionCount;
+ }
+ auto OriginalTy = Base->getType();
+ if (auto *DRE = dyn_cast<DeclRefExpr>(Base))
+ if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
+ OriginalTy = PVD->getOriginalType().getNonReferenceType();
+
+ for (unsigned Cnt = 0; Cnt < ArraySectionCount; ++Cnt) {
+ if (OriginalTy->isAnyPointerType())
+ OriginalTy = OriginalTy->getPointeeType();
+ else {
+ assert (OriginalTy->isArrayType());
+ OriginalTy = OriginalTy->castAsArrayTypeUnsafe()->getElementType();
+ }
+ }
+ return OriginalTy;
+}
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index d6f2ce63a0a5..4bb4b5073c4f 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -295,8 +295,11 @@ UnresolvedLookupExpr::Create(const ASTContext &C,
{
assert(Args || TemplateKWLoc.isValid());
unsigned num_args = Args ? Args->size() : 0;
- void *Mem = C.Allocate(sizeof(UnresolvedLookupExpr) +
- ASTTemplateKWAndArgsInfo::sizeFor(num_args));
+
+ std::size_t Size =
+ totalSizeToAlloc<ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(1,
+ num_args);
+ void *Mem = C.Allocate(Size, llvm::alignOf<UnresolvedLookupExpr>());
return new (Mem) UnresolvedLookupExpr(C, NamingClass, QualifierLoc,
TemplateKWLoc, NameInfo,
ADL, /*Overload*/ true, Args,
@@ -307,11 +310,11 @@ UnresolvedLookupExpr *
UnresolvedLookupExpr::CreateEmpty(const ASTContext &C,
bool HasTemplateKWAndArgsInfo,
unsigned NumTemplateArgs) {
- std::size_t size = sizeof(UnresolvedLookupExpr);
- if (HasTemplateKWAndArgsInfo)
- size += ASTTemplateKWAndArgsInfo::sizeFor(NumTemplateArgs);
-
- void *Mem = C.Allocate(size, llvm::alignOf<UnresolvedLookupExpr>());
+ assert(NumTemplateArgs == 0 || HasTemplateKWAndArgsInfo);
+ std::size_t Size =
+ totalSizeToAlloc<ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(
+ HasTemplateKWAndArgsInfo, NumTemplateArgs);
+ void *Mem = C.Allocate(Size, llvm::alignOf<UnresolvedLookupExpr>());
UnresolvedLookupExpr *E = new (Mem) UnresolvedLookupExpr(EmptyShell());
E->HasTemplateKWAndArgsInfo = HasTemplateKWAndArgsInfo;
return E;
@@ -367,10 +370,9 @@ OverloadExpr::OverloadExpr(StmtClass K, const ASTContext &C,
bool Dependent = false;
bool InstantiationDependent = false;
bool ContainsUnexpandedParameterPack = false;
- getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc, *TemplateArgs,
- Dependent,
- InstantiationDependent,
- ContainsUnexpandedParameterPack);
+ getTrailingASTTemplateKWAndArgsInfo()->initializeFrom(
+ TemplateKWLoc, *TemplateArgs, getTrailingTemplateArgumentLoc(),
+ Dependent, InstantiationDependent, ContainsUnexpandedParameterPack);
if (Dependent) {
ExprBits.TypeDependent = true;
@@ -381,7 +383,7 @@ OverloadExpr::OverloadExpr(StmtClass K, const ASTContext &C,
if (ContainsUnexpandedParameterPack)
ExprBits.ContainsUnexpandedParameterPack = true;
} else if (TemplateKWLoc.isValid()) {
- getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc);
+ getTrailingASTTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc);
}
if (isTypeDependent())
@@ -432,13 +434,13 @@ DependentScopeDeclRefExpr::DependentScopeDeclRefExpr(QualType T,
bool InstantiationDependent = true;
bool ContainsUnexpandedParameterPack
= ExprBits.ContainsUnexpandedParameterPack;
- getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc, *Args,
- Dependent,
- InstantiationDependent,
- ContainsUnexpandedParameterPack);
+ getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
+ TemplateKWLoc, *Args, getTrailingObjects<TemplateArgumentLoc>(),
+ Dependent, InstantiationDependent, ContainsUnexpandedParameterPack);
ExprBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack;
} else if (TemplateKWLoc.isValid()) {
- getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc);
+ getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
+ TemplateKWLoc);
}
}
@@ -449,12 +451,11 @@ DependentScopeDeclRefExpr::Create(const ASTContext &C,
const DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo *Args) {
assert(QualifierLoc && "should be created for dependent qualifiers");
- std::size_t size = sizeof(DependentScopeDeclRefExpr);
- if (Args)
- size += ASTTemplateKWAndArgsInfo::sizeFor(Args->size());
- else if (TemplateKWLoc.isValid())
- size += ASTTemplateKWAndArgsInfo::sizeFor(0);
- void *Mem = C.Allocate(size);
+ bool HasTemplateKWAndArgsInfo = Args || TemplateKWLoc.isValid();
+ std::size_t Size =
+ totalSizeToAlloc<ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(
+ HasTemplateKWAndArgsInfo, Args ? Args->size() : 0);
+ void *Mem = C.Allocate(Size);
return new (Mem) DependentScopeDeclRefExpr(C.DependentTy, QualifierLoc,
TemplateKWLoc, NameInfo, Args);
}
@@ -463,10 +464,11 @@ DependentScopeDeclRefExpr *
DependentScopeDeclRefExpr::CreateEmpty(const ASTContext &C,
bool HasTemplateKWAndArgsInfo,
unsigned NumTemplateArgs) {
- std::size_t size = sizeof(DependentScopeDeclRefExpr);
- if (HasTemplateKWAndArgsInfo)
- size += ASTTemplateKWAndArgsInfo::sizeFor(NumTemplateArgs);
- void *Mem = C.Allocate(size);
+ assert(NumTemplateArgs == 0 || HasTemplateKWAndArgsInfo);
+ std::size_t Size =
+ totalSizeToAlloc<ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(
+ HasTemplateKWAndArgsInfo, NumTemplateArgs);
+ void *Mem = C.Allocate(Size);
DependentScopeDeclRefExpr *E
= new (Mem) DependentScopeDeclRefExpr(QualType(), NestedNameSpecifierLoc(),
SourceLocation(),
@@ -587,19 +589,19 @@ CXXStaticCastExpr *CXXStaticCastExpr::Create(const ASTContext &C, QualType T,
SourceLocation RParenLoc,
SourceRange AngleBrackets) {
unsigned PathSize = (BasePath ? BasePath->size() : 0);
- void *Buffer = C.Allocate(sizeof(CXXStaticCastExpr)
- + PathSize * sizeof(CXXBaseSpecifier*));
+ void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));
CXXStaticCastExpr *E =
new (Buffer) CXXStaticCastExpr(T, VK, K, Op, PathSize, WrittenTy, L,
RParenLoc, AngleBrackets);
- if (PathSize) E->setCastPath(*BasePath);
+ if (PathSize)
+ std::uninitialized_copy_n(BasePath->data(), BasePath->size(),
+ E->getTrailingObjects<CXXBaseSpecifier *>());
return E;
}
CXXStaticCastExpr *CXXStaticCastExpr::CreateEmpty(const ASTContext &C,
unsigned PathSize) {
- void *Buffer =
- C.Allocate(sizeof(CXXStaticCastExpr) + PathSize * sizeof(CXXBaseSpecifier*));
+ void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));
return new (Buffer) CXXStaticCastExpr(EmptyShell(), PathSize);
}
@@ -612,19 +614,19 @@ CXXDynamicCastExpr *CXXDynamicCastExpr::Create(const ASTContext &C, QualType T,
SourceLocation RParenLoc,
SourceRange AngleBrackets) {
unsigned PathSize = (BasePath ? BasePath->size() : 0);
- void *Buffer = C.Allocate(sizeof(CXXDynamicCastExpr)
- + PathSize * sizeof(CXXBaseSpecifier*));
+ void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));
CXXDynamicCastExpr *E =
new (Buffer) CXXDynamicCastExpr(T, VK, K, Op, PathSize, WrittenTy, L,
RParenLoc, AngleBrackets);
- if (PathSize) E->setCastPath(*BasePath);
+ if (PathSize)
+ std::uninitialized_copy_n(BasePath->data(), BasePath->size(),
+ E->getTrailingObjects<CXXBaseSpecifier *>());
return E;
}
CXXDynamicCastExpr *CXXDynamicCastExpr::CreateEmpty(const ASTContext &C,
unsigned PathSize) {
- void *Buffer =
- C.Allocate(sizeof(CXXDynamicCastExpr) + PathSize * sizeof(CXXBaseSpecifier*));
+ void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));
return new (Buffer) CXXDynamicCastExpr(EmptyShell(), PathSize);
}
@@ -669,19 +671,19 @@ CXXReinterpretCastExpr::Create(const ASTContext &C, QualType T,
SourceLocation RParenLoc,
SourceRange AngleBrackets) {
unsigned PathSize = (BasePath ? BasePath->size() : 0);
- void *Buffer =
- C.Allocate(sizeof(CXXReinterpretCastExpr) + PathSize * sizeof(CXXBaseSpecifier*));
+ void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));
CXXReinterpretCastExpr *E =
new (Buffer) CXXReinterpretCastExpr(T, VK, K, Op, PathSize, WrittenTy, L,
RParenLoc, AngleBrackets);
- if (PathSize) E->setCastPath(*BasePath);
+ if (PathSize)
+ std::uninitialized_copy_n(BasePath->data(), BasePath->size(),
+ E->getTrailingObjects<CXXBaseSpecifier *>());
return E;
}
CXXReinterpretCastExpr *
CXXReinterpretCastExpr::CreateEmpty(const ASTContext &C, unsigned PathSize) {
- void *Buffer = C.Allocate(sizeof(CXXReinterpretCastExpr)
- + PathSize * sizeof(CXXBaseSpecifier*));
+ void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));
return new (Buffer) CXXReinterpretCastExpr(EmptyShell(), PathSize);
}
@@ -704,18 +706,18 @@ CXXFunctionalCastExpr::Create(const ASTContext &C, QualType T, ExprValueKind VK,
const CXXCastPath *BasePath,
SourceLocation L, SourceLocation R) {
unsigned PathSize = (BasePath ? BasePath->size() : 0);
- void *Buffer = C.Allocate(sizeof(CXXFunctionalCastExpr)
- + PathSize * sizeof(CXXBaseSpecifier*));
+ void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));
CXXFunctionalCastExpr *E =
new (Buffer) CXXFunctionalCastExpr(T, VK, Written, K, Op, PathSize, L, R);
- if (PathSize) E->setCastPath(*BasePath);
+ if (PathSize)
+ std::uninitialized_copy_n(BasePath->data(), BasePath->size(),
+ E->getTrailingObjects<CXXBaseSpecifier *>());
return E;
}
CXXFunctionalCastExpr *
CXXFunctionalCastExpr::CreateEmpty(const ASTContext &C, unsigned PathSize) {
- void *Buffer = C.Allocate(sizeof(CXXFunctionalCastExpr)
- + PathSize * sizeof(CXXBaseSpecifier*));
+ void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));
return new (Buffer) CXXFunctionalCastExpr(EmptyShell(), PathSize);
}
@@ -1070,15 +1072,15 @@ LambdaExpr::capture_range LambdaExpr::implicit_captures() const {
return capture_range(implicit_capture_begin(), implicit_capture_end());
}
-ArrayRef<VarDecl *>
-LambdaExpr::getCaptureInitIndexVars(capture_init_iterator Iter) const {
+ArrayRef<VarDecl *>
+LambdaExpr::getCaptureInitIndexVars(const_capture_init_iterator Iter) const {
assert(HasArrayIndexVars && "No array index-var data?");
unsigned Index = Iter - capture_init_begin();
assert(Index < getLambdaClass()->getLambdaData().NumCaptures &&
"Capture index out-of-range");
- VarDecl **IndexVars = getArrayIndexVars();
- unsigned *IndexStarts = getArrayIndexStarts();
+ VarDecl *const *IndexVars = getArrayIndexVars();
+ const unsigned *IndexStarts = getArrayIndexStarts();
return llvm::makeArrayRef(IndexVars + IndexStarts[Index],
IndexVars + IndexStarts[Index + 1]);
}
@@ -1099,9 +1101,13 @@ TemplateParameterList *LambdaExpr::getTemplateParameterList() const {
}
CompoundStmt *LambdaExpr::getBody() const {
+ // FIXME: this mutation in getBody is bogus. It should be
+ // initialized in ASTStmtReader::VisitLambdaExpr, but for reasons I
+ // don't understand, that doesn't work.
if (!getStoredStmts()[NumCaptures])
- getStoredStmts()[NumCaptures] = getCallOperator()->getBody();
-
+ *const_cast<clang::Stmt **>(&getStoredStmts()[NumCaptures]) =
+ getCallOperator()->getBody();
+
return reinterpret_cast<CompoundStmt *>(getStoredStmts()[NumCaptures]);
}
@@ -1191,63 +1197,40 @@ SourceLocation CXXUnresolvedConstructExpr::getLocStart() const {
return Type->getTypeLoc().getBeginLoc();
}
-CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(const ASTContext &C,
- Expr *Base, QualType BaseType,
- bool IsArrow,
- SourceLocation OperatorLoc,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- NamedDecl *FirstQualifierFoundInScope,
- DeclarationNameInfo MemberNameInfo,
- const TemplateArgumentListInfo *TemplateArgs)
- : Expr(CXXDependentScopeMemberExprClass, C.DependentTy,
- VK_LValue, OK_Ordinary, true, true, true,
- ((Base && Base->containsUnexpandedParameterPack()) ||
- (QualifierLoc &&
- QualifierLoc.getNestedNameSpecifier()
- ->containsUnexpandedParameterPack()) ||
- MemberNameInfo.containsUnexpandedParameterPack())),
- Base(Base), BaseType(BaseType), IsArrow(IsArrow),
- HasTemplateKWAndArgsInfo(TemplateArgs != nullptr ||
- TemplateKWLoc.isValid()),
- OperatorLoc(OperatorLoc), QualifierLoc(QualifierLoc),
- FirstQualifierFoundInScope(FirstQualifierFoundInScope),
- MemberNameInfo(MemberNameInfo) {
+CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(
+ const ASTContext &C, Expr *Base, QualType BaseType, bool IsArrow,
+ SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc,
+ SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierFoundInScope,
+ DeclarationNameInfo MemberNameInfo,
+ const TemplateArgumentListInfo *TemplateArgs)
+ : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, VK_LValue,
+ OK_Ordinary, true, true, true,
+ ((Base && Base->containsUnexpandedParameterPack()) ||
+ (QualifierLoc &&
+ QualifierLoc.getNestedNameSpecifier()
+ ->containsUnexpandedParameterPack()) ||
+ MemberNameInfo.containsUnexpandedParameterPack())),
+ Base(Base), BaseType(BaseType), IsArrow(IsArrow),
+ HasTemplateKWAndArgsInfo(TemplateArgs != nullptr ||
+ TemplateKWLoc.isValid()),
+ OperatorLoc(OperatorLoc), QualifierLoc(QualifierLoc),
+ FirstQualifierFoundInScope(FirstQualifierFoundInScope),
+ MemberNameInfo(MemberNameInfo) {
if (TemplateArgs) {
bool Dependent = true;
bool InstantiationDependent = true;
bool ContainsUnexpandedParameterPack = false;
- getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc, *TemplateArgs,
- Dependent,
- InstantiationDependent,
- ContainsUnexpandedParameterPack);
+ getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
+ TemplateKWLoc, *TemplateArgs, getTrailingObjects<TemplateArgumentLoc>(),
+ Dependent, InstantiationDependent, ContainsUnexpandedParameterPack);
if (ContainsUnexpandedParameterPack)
ExprBits.ContainsUnexpandedParameterPack = true;
} else if (TemplateKWLoc.isValid()) {
- getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc);
+ getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
+ TemplateKWLoc);
}
}
-CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(const ASTContext &C,
- Expr *Base, QualType BaseType,
- bool IsArrow,
- SourceLocation OperatorLoc,
- NestedNameSpecifierLoc QualifierLoc,
- NamedDecl *FirstQualifierFoundInScope,
- DeclarationNameInfo MemberNameInfo)
- : Expr(CXXDependentScopeMemberExprClass, C.DependentTy,
- VK_LValue, OK_Ordinary, true, true, true,
- ((Base && Base->containsUnexpandedParameterPack()) ||
- (QualifierLoc &&
- QualifierLoc.getNestedNameSpecifier()->
- containsUnexpandedParameterPack()) ||
- MemberNameInfo.containsUnexpandedParameterPack())),
- Base(Base), BaseType(BaseType), IsArrow(IsArrow),
- HasTemplateKWAndArgsInfo(false),
- OperatorLoc(OperatorLoc), QualifierLoc(QualifierLoc),
- FirstQualifierFoundInScope(FirstQualifierFoundInScope),
- MemberNameInfo(MemberNameInfo) { }
-
CXXDependentScopeMemberExpr *
CXXDependentScopeMemberExpr::Create(const ASTContext &C,
Expr *Base, QualType BaseType, bool IsArrow,
@@ -1257,18 +1240,13 @@ CXXDependentScopeMemberExpr::Create(const ASTContext &C,
NamedDecl *FirstQualifierFoundInScope,
DeclarationNameInfo MemberNameInfo,
const TemplateArgumentListInfo *TemplateArgs) {
- if (!TemplateArgs && !TemplateKWLoc.isValid())
- return new (C) CXXDependentScopeMemberExpr(C, Base, BaseType,
- IsArrow, OperatorLoc,
- QualifierLoc,
- FirstQualifierFoundInScope,
- MemberNameInfo);
-
+ bool HasTemplateKWAndArgsInfo = TemplateArgs || TemplateKWLoc.isValid();
unsigned NumTemplateArgs = TemplateArgs ? TemplateArgs->size() : 0;
- std::size_t size = sizeof(CXXDependentScopeMemberExpr)
- + ASTTemplateKWAndArgsInfo::sizeFor(NumTemplateArgs);
+ std::size_t Size =
+ totalSizeToAlloc<ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(
+ HasTemplateKWAndArgsInfo, NumTemplateArgs);
- void *Mem = C.Allocate(size, llvm::alignOf<CXXDependentScopeMemberExpr>());
+ void *Mem = C.Allocate(Size, llvm::alignOf<CXXDependentScopeMemberExpr>());
return new (Mem) CXXDependentScopeMemberExpr(C, Base, BaseType,
IsArrow, OperatorLoc,
QualifierLoc,
@@ -1281,22 +1259,18 @@ CXXDependentScopeMemberExpr *
CXXDependentScopeMemberExpr::CreateEmpty(const ASTContext &C,
bool HasTemplateKWAndArgsInfo,
unsigned NumTemplateArgs) {
- if (!HasTemplateKWAndArgsInfo)
- return new (C) CXXDependentScopeMemberExpr(C, nullptr, QualType(),
- 0, SourceLocation(),
- NestedNameSpecifierLoc(),
- nullptr, DeclarationNameInfo());
-
- std::size_t size = sizeof(CXXDependentScopeMemberExpr) +
- ASTTemplateKWAndArgsInfo::sizeFor(NumTemplateArgs);
- void *Mem = C.Allocate(size, llvm::alignOf<CXXDependentScopeMemberExpr>());
+ assert(NumTemplateArgs == 0 || HasTemplateKWAndArgsInfo);
+ std::size_t Size =
+ totalSizeToAlloc<ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(
+ HasTemplateKWAndArgsInfo, NumTemplateArgs);
+ void *Mem = C.Allocate(Size, llvm::alignOf<CXXDependentScopeMemberExpr>());
CXXDependentScopeMemberExpr *E
= new (Mem) CXXDependentScopeMemberExpr(C, nullptr, QualType(),
0, SourceLocation(),
NestedNameSpecifierLoc(),
SourceLocation(), nullptr,
DeclarationNameInfo(), nullptr);
- E->HasTemplateKWAndArgsInfo = true;
+ E->HasTemplateKWAndArgsInfo = HasTemplateKWAndArgsInfo;
return E;
}
@@ -1361,38 +1335,34 @@ bool UnresolvedMemberExpr::isImplicitAccess() const {
return cast<Expr>(Base)->isImplicitCXXThis();
}
-UnresolvedMemberExpr *
-UnresolvedMemberExpr::Create(const ASTContext &C, bool HasUnresolvedUsing,
- Expr *Base, QualType BaseType, bool IsArrow,
- SourceLocation OperatorLoc,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &MemberNameInfo,
- const TemplateArgumentListInfo *TemplateArgs,
- UnresolvedSetIterator Begin,
- UnresolvedSetIterator End) {
- std::size_t size = sizeof(UnresolvedMemberExpr);
- if (TemplateArgs)
- size += ASTTemplateKWAndArgsInfo::sizeFor(TemplateArgs->size());
- else if (TemplateKWLoc.isValid())
- size += ASTTemplateKWAndArgsInfo::sizeFor(0);
-
- void *Mem = C.Allocate(size, llvm::alignOf<UnresolvedMemberExpr>());
- return new (Mem) UnresolvedMemberExpr(C,
- HasUnresolvedUsing, Base, BaseType,
- IsArrow, OperatorLoc, QualifierLoc, TemplateKWLoc,
- MemberNameInfo, TemplateArgs, Begin, End);
+UnresolvedMemberExpr *UnresolvedMemberExpr::Create(
+ const ASTContext &C, bool HasUnresolvedUsing, Expr *Base, QualType BaseType,
+ bool IsArrow, SourceLocation OperatorLoc,
+ NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
+ const DeclarationNameInfo &MemberNameInfo,
+ const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin,
+ UnresolvedSetIterator End) {
+ bool HasTemplateKWAndArgsInfo = TemplateArgs || TemplateKWLoc.isValid();
+ std::size_t Size =
+ totalSizeToAlloc<ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(
+ HasTemplateKWAndArgsInfo, TemplateArgs ? TemplateArgs->size() : 0);
+
+ void *Mem = C.Allocate(Size, llvm::alignOf<UnresolvedMemberExpr>());
+ return new (Mem) UnresolvedMemberExpr(
+ C, HasUnresolvedUsing, Base, BaseType, IsArrow, OperatorLoc, QualifierLoc,
+ TemplateKWLoc, MemberNameInfo, TemplateArgs, Begin, End);
}
UnresolvedMemberExpr *
UnresolvedMemberExpr::CreateEmpty(const ASTContext &C,
bool HasTemplateKWAndArgsInfo,
unsigned NumTemplateArgs) {
- std::size_t size = sizeof(UnresolvedMemberExpr);
- if (HasTemplateKWAndArgsInfo)
- size += ASTTemplateKWAndArgsInfo::sizeFor(NumTemplateArgs);
+ assert(NumTemplateArgs == 0 || HasTemplateKWAndArgsInfo);
+ std::size_t Size =
+ totalSizeToAlloc<ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(
+ HasTemplateKWAndArgsInfo, NumTemplateArgs);
- void *Mem = C.Allocate(size, llvm::alignOf<UnresolvedMemberExpr>());
+ void *Mem = C.Allocate(Size, llvm::alignOf<UnresolvedMemberExpr>());
UnresolvedMemberExpr *E = new (Mem) UnresolvedMemberExpr(EmptyShell());
E->HasTemplateKWAndArgsInfo = HasTemplateKWAndArgsInfo;
return E;
@@ -1428,6 +1398,25 @@ CXXRecordDecl *UnresolvedMemberExpr::getNamingClass() const {
return Record;
}
+SizeOfPackExpr *
+SizeOfPackExpr::Create(ASTContext &Context, SourceLocation OperatorLoc,
+ NamedDecl *Pack, SourceLocation PackLoc,
+ SourceLocation RParenLoc,
+ Optional<unsigned> Length,
+ ArrayRef<TemplateArgument> PartialArgs) {
+ void *Storage = Context.Allocate(
+ sizeof(SizeOfPackExpr) + sizeof(TemplateArgument) * PartialArgs.size());
+ return new (Storage) SizeOfPackExpr(Context.getSizeType(), OperatorLoc, Pack,
+ PackLoc, RParenLoc, Length, PartialArgs);
+}
+
+SizeOfPackExpr *SizeOfPackExpr::CreateDeserialized(ASTContext &Context,
+ unsigned NumPartialArgs) {
+ void *Storage = Context.Allocate(
+ sizeof(SizeOfPackExpr) + sizeof(TemplateArgument) * NumPartialArgs);
+ return new (Storage) SizeOfPackExpr(EmptyShell(), NumPartialArgs);
+}
+
SubstNonTypeTemplateParmPackExpr::
SubstNonTypeTemplateParmPackExpr(QualType T,
NonTypeTemplateParmDecl *Param,
@@ -1439,25 +1428,25 @@ SubstNonTypeTemplateParmPackExpr(QualType T,
NumArguments(ArgPack.pack_size()), NameLoc(NameLoc) { }
TemplateArgument SubstNonTypeTemplateParmPackExpr::getArgumentPack() const {
- return TemplateArgument(Arguments, NumArguments);
+ return TemplateArgument(llvm::makeArrayRef(Arguments, NumArguments));
}
FunctionParmPackExpr::FunctionParmPackExpr(QualType T, ParmVarDecl *ParamPack,
SourceLocation NameLoc,
unsigned NumParams,
- Decl * const *Params)
- : Expr(FunctionParmPackExprClass, T, VK_LValue, OK_Ordinary,
- true, true, true, true),
- ParamPack(ParamPack), NameLoc(NameLoc), NumParameters(NumParams) {
+ ParmVarDecl *const *Params)
+ : Expr(FunctionParmPackExprClass, T, VK_LValue, OK_Ordinary, true, true,
+ true, true),
+ ParamPack(ParamPack), NameLoc(NameLoc), NumParameters(NumParams) {
if (Params)
std::uninitialized_copy(Params, Params + NumParams,
- reinterpret_cast<Decl**>(this+1));
+ reinterpret_cast<ParmVarDecl **>(this + 1));
}
FunctionParmPackExpr *
FunctionParmPackExpr::Create(const ASTContext &Context, QualType T,
ParmVarDecl *ParamPack, SourceLocation NameLoc,
- ArrayRef<Decl *> Params) {
+ ArrayRef<ParmVarDecl *> Params) {
return new (Context.Allocate(sizeof(FunctionParmPackExpr) +
sizeof(ParmVarDecl*) * Params.size()))
FunctionParmPackExpr(T, ParamPack, NameLoc, Params.size(), Params.data());
diff --git a/lib/AST/ExprClassification.cpp b/lib/AST/ExprClassification.cpp
index 9cc612eae9b7..a47b03c0afba 100644
--- a/lib/AST/ExprClassification.cpp
+++ b/lib/AST/ExprClassification.cpp
@@ -136,6 +136,8 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) {
case Expr::ObjCIvarRefExprClass:
case Expr::FunctionParmPackExprClass:
case Expr::MSPropertyRefExprClass:
+ case Expr::MSPropertySubscriptExprClass:
+ case Expr::OMPArraySectionExprClass:
return Cl::CL_LValue;
// C99 6.5.2.5p5 says that compound literals are lvalues.
@@ -185,6 +187,7 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) {
case Expr::CXXFoldExprClass:
case Expr::NoInitExprClass:
case Expr::DesignatedInitUpdateExprClass:
+ case Expr::CoyieldExprClass:
return Cl::CL_PRValue;
// Next come the complicated cases.
@@ -396,6 +399,9 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) {
assert(cast<InitListExpr>(E)->getNumInits() == 1 &&
"Only 1-element init lists can be glvalues.");
return ClassifyInternal(Ctx, cast<InitListExpr>(E)->getInit(0));
+
+ case Expr::CoawaitExprClass:
+ return ClassifyInternal(Ctx, cast<CoawaitExpr>(E)->getResumeExpr());
}
llvm_unreachable("unhandled expression kind in classification");
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index ed749cc56f1e..c4c4398c3622 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -114,7 +114,8 @@ namespace {
static
unsigned findMostDerivedSubobject(ASTContext &Ctx, QualType Base,
ArrayRef<APValue::LValuePathEntry> Path,
- uint64_t &ArraySize, QualType &Type) {
+ uint64_t &ArraySize, QualType &Type,
+ bool &IsArray) {
unsigned MostDerivedLength = 0;
Type = Base;
for (unsigned I = 0, N = Path.size(); I != N; ++I) {
@@ -124,18 +125,22 @@ namespace {
Type = CAT->getElementType();
ArraySize = CAT->getSize().getZExtValue();
MostDerivedLength = I + 1;
+ IsArray = true;
} else if (Type->isAnyComplexType()) {
const ComplexType *CT = Type->castAs<ComplexType>();
Type = CT->getElementType();
ArraySize = 2;
MostDerivedLength = I + 1;
+ IsArray = true;
} else if (const FieldDecl *FD = getAsField(Path[I])) {
Type = FD->getType();
ArraySize = 0;
MostDerivedLength = I + 1;
+ IsArray = false;
} else {
// Path[I] describes a base class.
ArraySize = 0;
+ IsArray = false;
}
}
return MostDerivedLength;
@@ -157,12 +162,17 @@ namespace {
/// Is this a pointer one past the end of an object?
bool IsOnePastTheEnd : 1;
+ /// Indicator of whether the most-derived object is an array element.
+ bool MostDerivedIsArrayElement : 1;
+
/// The length of the path to the most-derived object of which this is a
/// subobject.
- unsigned MostDerivedPathLength : 30;
+ unsigned MostDerivedPathLength : 29;
- /// The size of the array of which the most-derived object is an element, or
- /// 0 if the most-derived object is not an array element.
+ /// The size of the array of which the most-derived object is an element.
+ /// This will always be 0 if the most-derived object is not an array
+ /// element. 0 is not an indicator of whether or not the most-derived object
+ /// is an array, however, because 0-length arrays are allowed.
uint64_t MostDerivedArraySize;
/// The type of the most derived object referred to by this address.
@@ -176,21 +186,26 @@ namespace {
SubobjectDesignator() : Invalid(true) {}
explicit SubobjectDesignator(QualType T)
- : Invalid(false), IsOnePastTheEnd(false), MostDerivedPathLength(0),
- MostDerivedArraySize(0), MostDerivedType(T) {}
+ : Invalid(false), IsOnePastTheEnd(false),
+ MostDerivedIsArrayElement(false), MostDerivedPathLength(0),
+ MostDerivedArraySize(0), MostDerivedType(T) {}
SubobjectDesignator(ASTContext &Ctx, const APValue &V)
- : Invalid(!V.isLValue() || !V.hasLValuePath()), IsOnePastTheEnd(false),
- MostDerivedPathLength(0), MostDerivedArraySize(0) {
+ : Invalid(!V.isLValue() || !V.hasLValuePath()), IsOnePastTheEnd(false),
+ MostDerivedIsArrayElement(false), MostDerivedPathLength(0),
+ MostDerivedArraySize(0) {
if (!Invalid) {
IsOnePastTheEnd = V.isLValueOnePastTheEnd();
ArrayRef<PathEntry> VEntries = V.getLValuePath();
Entries.insert(Entries.end(), VEntries.begin(), VEntries.end());
- if (V.getLValueBase())
+ if (V.getLValueBase()) {
+ bool IsArray = false;
MostDerivedPathLength =
findMostDerivedSubobject(Ctx, getType(V.getLValueBase()),
V.getLValuePath(), MostDerivedArraySize,
- MostDerivedType);
+ MostDerivedType, IsArray);
+ MostDerivedIsArrayElement = IsArray;
+ }
}
}
@@ -204,7 +219,7 @@ namespace {
assert(!Invalid);
if (IsOnePastTheEnd)
return true;
- if (MostDerivedArraySize &&
+ if (MostDerivedIsArrayElement &&
Entries[MostDerivedPathLength - 1].ArrayIndex == MostDerivedArraySize)
return true;
return false;
@@ -228,6 +243,7 @@ namespace {
// This is a most-derived object.
MostDerivedType = CAT->getElementType();
+ MostDerivedIsArrayElement = true;
MostDerivedArraySize = CAT->getSize().getZExtValue();
MostDerivedPathLength = Entries.size();
}
@@ -242,6 +258,7 @@ namespace {
// If this isn't a base class, it's a new most-derived object.
if (const FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
MostDerivedType = FD->getType();
+ MostDerivedIsArrayElement = false;
MostDerivedArraySize = 0;
MostDerivedPathLength = Entries.size();
}
@@ -255,6 +272,7 @@ namespace {
// This is technically a most-derived object, though in practice this
// is unlikely to matter.
MostDerivedType = EltTy;
+ MostDerivedIsArrayElement = true;
MostDerivedArraySize = 2;
MostDerivedPathLength = Entries.size();
}
@@ -262,7 +280,8 @@ namespace {
/// Add N to the address of this subobject.
void adjustIndex(EvalInfo &Info, const Expr *E, uint64_t N) {
if (Invalid) return;
- if (MostDerivedPathLength == Entries.size() && MostDerivedArraySize) {
+ if (MostDerivedPathLength == Entries.size() &&
+ MostDerivedIsArrayElement) {
Entries.back().ArrayIndex += N;
if (Entries.back().ArrayIndex > MostDerivedArraySize) {
diagnosePointerArithmetic(Info, E, Entries.back().ArrayIndex);
@@ -454,6 +473,10 @@ namespace {
/// notes attached to it will also be stored, otherwise they will not be.
bool HasActiveDiagnostic;
+ /// \brief Have we emitted a diagnostic explaining why we couldn't constant
+ /// fold (not just why it's not strictly a constant expression)?
+ bool HasFoldFailureDiagnostic;
+
enum EvaluationMode {
/// Evaluate as a constant expression. Stop if we find that the expression
/// is not a constant expression.
@@ -492,7 +515,11 @@ namespace {
/// optimizer if we don't constant fold them here, but in an unevaluated
/// context we try to fold them immediately since the optimizer never
/// gets a chance to look at it.
- EM_PotentialConstantExpressionUnevaluated
+ EM_PotentialConstantExpressionUnevaluated,
+
+ /// Evaluate as a constant expression. Continue evaluating if we find a
+ /// MemberExpr with a base that can't be evaluated.
+ EM_DesignatorFold,
} EvalMode;
/// Are we checking whether the expression is a potential constant
@@ -514,7 +541,7 @@ namespace {
BottomFrame(*this, SourceLocation(), nullptr, nullptr, nullptr),
EvaluatingDecl((const ValueDecl *)nullptr),
EvaluatingDeclValue(nullptr), HasActiveDiagnostic(false),
- EvalMode(Mode) {}
+ HasFoldFailureDiagnostic(false), EvalMode(Mode) {}
void setEvaluatingDecl(APValue::LValueBase Base, APValue &Value) {
EvaluatingDecl = Base;
@@ -574,7 +601,7 @@ namespace {
/// Diagnose that the evaluation cannot be folded.
OptionalDiagnostic Diag(SourceLocation Loc, diag::kind DiagId
= diag::note_invalid_subexpr_in_const_expr,
- unsigned ExtraNotes = 0) {
+ unsigned ExtraNotes = 0, bool IsCCEDiag = false) {
if (EvalStatus.Diag) {
// If we have a prior diagnostic, it will be noting that the expression
// isn't a constant expression. This diagnostic is more important,
@@ -587,14 +614,14 @@ namespace {
case EM_ConstantFold:
case EM_IgnoreSideEffects:
case EM_EvaluateForOverflow:
- if (!EvalStatus.HasSideEffects)
+ if (!HasFoldFailureDiagnostic)
break;
- // We've had side-effects; we want the diagnostic from them, not
- // some later problem.
+ // We've already failed to fold something. Keep that diagnostic.
case EM_ConstantExpression:
case EM_PotentialConstantExpression:
case EM_ConstantExpressionUnevaluated:
case EM_PotentialConstantExpressionUnevaluated:
+ case EM_DesignatorFold:
HasActiveDiagnostic = false;
return OptionalDiagnostic();
}
@@ -608,6 +635,7 @@ namespace {
CallStackNotes = 0;
HasActiveDiagnostic = true;
+ HasFoldFailureDiagnostic = !IsCCEDiag;
EvalStatus.Diag->clear();
EvalStatus.Diag->reserve(1 + ExtraNotes + CallStackNotes);
addDiag(Loc, DiagId);
@@ -621,9 +649,9 @@ namespace {
OptionalDiagnostic Diag(const Expr *E, diag::kind DiagId
= diag::note_invalid_subexpr_in_const_expr,
- unsigned ExtraNotes = 0) {
+ unsigned ExtraNotes = 0, bool IsCCEDiag = false) {
if (EvalStatus.Diag)
- return Diag(E->getExprLoc(), DiagId, ExtraNotes);
+ return Diag(E->getExprLoc(), DiagId, ExtraNotes, IsCCEDiag);
HasActiveDiagnostic = false;
return OptionalDiagnostic();
}
@@ -643,7 +671,7 @@ namespace {
HasActiveDiagnostic = false;
return OptionalDiagnostic();
}
- return Diag(Loc, DiagId, ExtraNotes);
+ return Diag(Loc, DiagId, ExtraNotes, true);
}
/// Add a note to a prior diagnostic.
@@ -674,6 +702,7 @@ namespace {
case EM_ConstantExpression:
case EM_ConstantExpressionUnevaluated:
case EM_ConstantFold:
+ case EM_DesignatorFold:
return false;
}
llvm_unreachable("Missed EvalMode case");
@@ -686,6 +715,32 @@ namespace {
return keepEvaluatingAfterSideEffect();
}
+ /// Should we continue evaluation after encountering undefined behavior?
+ bool keepEvaluatingAfterUndefinedBehavior() {
+ switch (EvalMode) {
+ case EM_EvaluateForOverflow:
+ case EM_IgnoreSideEffects:
+ case EM_ConstantFold:
+ case EM_DesignatorFold:
+ return true;
+
+ case EM_PotentialConstantExpression:
+ case EM_PotentialConstantExpressionUnevaluated:
+ case EM_ConstantExpression:
+ case EM_ConstantExpressionUnevaluated:
+ return false;
+ }
+ llvm_unreachable("Missed EvalMode case");
+ }
+
+ /// Note that we hit something that was technically undefined behavior, but
+ /// that we can evaluate past it (such as signed overflow or floating-point
+ /// division by zero.)
+ bool noteUndefinedBehavior() {
+ EvalStatus.HasUndefinedBehavior = true;
+ return keepEvaluatingAfterUndefinedBehavior();
+ }
+
/// Should we continue evaluation as much as possible after encountering a
/// construct which can't be reduced to a value?
bool keepEvaluatingAfterFailure() {
@@ -702,10 +757,15 @@ namespace {
case EM_ConstantExpressionUnevaluated:
case EM_ConstantFold:
case EM_IgnoreSideEffects:
+ case EM_DesignatorFold:
return false;
}
llvm_unreachable("Missed EvalMode case");
}
+
+ bool allowInvalidBaseExpr() const {
+ return EvalMode == EM_DesignatorFold;
+ }
};
/// Object used to treat all foldable expressions as constant expressions.
@@ -736,6 +796,21 @@ namespace {
}
};
+ /// RAII object used to treat the current evaluation as the correct pointer
+ /// offset fold for the current EvalMode
+ struct FoldOffsetRAII {
+ EvalInfo &Info;
+ EvalInfo::EvaluationMode OldMode;
+ explicit FoldOffsetRAII(EvalInfo &Info, bool Subobject)
+ : Info(Info), OldMode(Info.EvalMode) {
+ if (!Info.checkingPotentialConstantExpression())
+ Info.EvalMode = Subobject ? EvalInfo::EM_DesignatorFold
+ : EvalInfo::EM_ConstantFold;
+ }
+
+ ~FoldOffsetRAII() { Info.EvalMode = OldMode; }
+ };
+
/// RAII object used to suppress diagnostics and side-effects from a
/// speculative evaluation.
class SpeculativeEvaluationRAII {
@@ -808,7 +883,7 @@ bool SubobjectDesignator::checkSubobject(EvalInfo &Info, const Expr *E,
void SubobjectDesignator::diagnosePointerArithmetic(EvalInfo &Info,
const Expr *E, uint64_t N) {
- if (MostDerivedPathLength == Entries.size() && MostDerivedArraySize)
+ if (MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement)
Info.CCEDiag(E, diag::note_constexpr_array_index)
<< static_cast<int>(N) << /*array*/ 0
<< static_cast<unsigned>(MostDerivedArraySize);
@@ -917,7 +992,8 @@ namespace {
struct LValue {
APValue::LValueBase Base;
CharUnits Offset;
- unsigned CallIndex;
+ bool InvalidBase : 1;
+ unsigned CallIndex : 31;
SubobjectDesignator Designator;
const APValue::LValueBase getLValueBase() const { return Base; }
@@ -938,17 +1014,23 @@ namespace {
assert(V.isLValue());
Base = V.getLValueBase();
Offset = V.getLValueOffset();
+ InvalidBase = false;
CallIndex = V.getLValueCallIndex();
Designator = SubobjectDesignator(Ctx, V);
}
- void set(APValue::LValueBase B, unsigned I = 0) {
+ void set(APValue::LValueBase B, unsigned I = 0, bool BInvalid = false) {
Base = B;
Offset = CharUnits::Zero();
+ InvalidBase = BInvalid;
CallIndex = I;
Designator = SubobjectDesignator(getType(B));
}
+ void setInvalid(APValue::LValueBase B, unsigned I = 0) {
+ set(B, I, true);
+ }
+
// Check that this LValue is not based on a null pointer. If it is, produce
// a diagnostic and mark the designator as invalid.
bool checkNullPointer(EvalInfo &Info, const Expr *E,
@@ -967,10 +1049,6 @@ namespace {
// Check this LValue refers to an object. If not, set the designator to be
// invalid and emit a diagnostic.
bool checkSubobject(EvalInfo &Info, const Expr *E, CheckSubobjectKind CSK) {
- // Outside C++11, do not build a designator referring to a subobject of
- // any object: we won't use such a designator for anything.
- if (!Info.getLangOpts().CPlusPlus11)
- Designator.setInvalid();
return (CSK == CSK_ArrayToPointer || checkNullPointer(Info, E, CSK)) &&
Designator.checkSubobject(Info, E, CSK);
}
@@ -1102,12 +1180,13 @@ static bool EvaluatePointer(const Expr *E, LValue &Result, EvalInfo &Info);
static bool EvaluateMemberPointer(const Expr *E, MemberPtr &Result,
EvalInfo &Info);
static bool EvaluateTemporary(const Expr *E, LValue &Result, EvalInfo &Info);
-static bool EvaluateInteger(const Expr *E, APSInt &Result, EvalInfo &Info);
+static bool EvaluateInteger(const Expr *E, APSInt &Result, EvalInfo &Info);
static bool EvaluateIntegerOrLValue(const Expr *E, APValue &Result,
EvalInfo &Info);
static bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info);
static bool EvaluateComplex(const Expr *E, ComplexValue &Res, EvalInfo &Info);
static bool EvaluateAtomic(const Expr *E, APValue &Result, EvalInfo &Info);
+static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result);
//===----------------------------------------------------------------------===//
// Misc utilities
@@ -1492,10 +1571,11 @@ static bool EvaluateAsBooleanCondition(const Expr *E, bool &Result,
}
template<typename T>
-static void HandleOverflow(EvalInfo &Info, const Expr *E,
+static bool HandleOverflow(EvalInfo &Info, const Expr *E,
const T &SrcValue, QualType DestType) {
Info.CCEDiag(E, diag::note_constexpr_overflow)
<< SrcValue << DestType;
+ return Info.noteUndefinedBehavior();
}
static bool HandleFloatToIntCast(EvalInfo &Info, const Expr *E,
@@ -1509,7 +1589,7 @@ static bool HandleFloatToIntCast(EvalInfo &Info, const Expr *E,
bool ignored;
if (Value.convertToInteger(Result, llvm::APFloat::rmTowardZero, &ignored)
& APFloat::opInvalidOp)
- HandleOverflow(Info, E, Value, DestType);
+ return HandleOverflow(Info, E, Value, DestType);
return true;
}
@@ -1521,13 +1601,13 @@ static bool HandleFloatToFloatCast(EvalInfo &Info, const Expr *E,
if (Result.convert(Info.Ctx.getFloatTypeSemantics(DestType),
APFloat::rmNearestTiesToEven, &ignored)
& APFloat::opOverflow)
- HandleOverflow(Info, E, Value, DestType);
+ return HandleOverflow(Info, E, Value, DestType);
return true;
}
static APSInt HandleIntToIntCast(EvalInfo &Info, const Expr *E,
QualType DestType, QualType SrcType,
- APSInt &Value) {
+ const APSInt &Value) {
unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
APSInt Result = Value;
// Figure out if this is a truncate, extend or noop cast.
@@ -1544,7 +1624,7 @@ static bool HandleIntToFloatCast(EvalInfo &Info, const Expr *E,
if (Result.convertFromAPInt(Value, Value.isSigned(),
APFloat::rmNearestTiesToEven)
& APFloat::opOverflow)
- HandleOverflow(Info, E, Value, DestType);
+ return HandleOverflow(Info, E, Value, DestType);
return true;
}
@@ -1620,23 +1700,26 @@ static bool EvalAndBitcastToAPInt(EvalInfo &Info, const Expr *E,
/// bits, and check for overflow in the original type (if that type was not an
/// unsigned type).
template<typename Operation>
-static APSInt CheckedIntArithmetic(EvalInfo &Info, const Expr *E,
- const APSInt &LHS, const APSInt &RHS,
- unsigned BitWidth, Operation Op) {
- if (LHS.isUnsigned())
- return Op(LHS, RHS);
+static bool CheckedIntArithmetic(EvalInfo &Info, const Expr *E,
+ const APSInt &LHS, const APSInt &RHS,
+ unsigned BitWidth, Operation Op,
+ APSInt &Result) {
+ if (LHS.isUnsigned()) {
+ Result = Op(LHS, RHS);
+ return true;
+ }
APSInt Value(Op(LHS.extend(BitWidth), RHS.extend(BitWidth)), false);
- APSInt Result = Value.trunc(LHS.getBitWidth());
+ Result = Value.trunc(LHS.getBitWidth());
if (Result.extend(BitWidth) != Value) {
if (Info.checkingForOverflow())
Info.Ctx.getDiagnostics().Report(E->getExprLoc(),
- diag::warn_integer_constant_overflow)
+ diag::warn_integer_constant_overflow)
<< Result.toString(10) << E->getType();
else
- HandleOverflow(Info, E, Value, E->getType());
+ return HandleOverflow(Info, E, Value, E->getType());
}
- return Result;
+ return true;
}
/// Perform the given binary integer operation.
@@ -1648,17 +1731,14 @@ static bool handleIntIntBinOp(EvalInfo &Info, const Expr *E, const APSInt &LHS,
Info.Diag(E);
return false;
case BO_Mul:
- Result = CheckedIntArithmetic(Info, E, LHS, RHS, LHS.getBitWidth() * 2,
- std::multiplies<APSInt>());
- return true;
+ return CheckedIntArithmetic(Info, E, LHS, RHS, LHS.getBitWidth() * 2,
+ std::multiplies<APSInt>(), Result);
case BO_Add:
- Result = CheckedIntArithmetic(Info, E, LHS, RHS, LHS.getBitWidth() + 1,
- std::plus<APSInt>());
- return true;
+ return CheckedIntArithmetic(Info, E, LHS, RHS, LHS.getBitWidth() + 1,
+ std::plus<APSInt>(), Result);
case BO_Sub:
- Result = CheckedIntArithmetic(Info, E, LHS, RHS, LHS.getBitWidth() + 1,
- std::minus<APSInt>());
- return true;
+ return CheckedIntArithmetic(Info, E, LHS, RHS, LHS.getBitWidth() + 1,
+ std::minus<APSInt>(), Result);
case BO_And: Result = LHS & RHS; return true;
case BO_Xor: Result = LHS ^ RHS; return true;
case BO_Or: Result = LHS | RHS; return true;
@@ -1668,11 +1748,13 @@ static bool handleIntIntBinOp(EvalInfo &Info, const Expr *E, const APSInt &LHS,
Info.Diag(E, diag::note_expr_divide_by_zero);
return false;
}
- // Check for overflow case: INT_MIN / -1 or INT_MIN % -1.
+ Result = (Opcode == BO_Rem ? LHS % RHS : LHS / RHS);
+ // Check for overflow case: INT_MIN / -1 or INT_MIN % -1. APSInt supports
+ // this operation and gives the two's complement result.
if (RHS.isNegative() && RHS.isAllOnesValue() &&
LHS.isSigned() && LHS.isMinSignedValue())
- HandleOverflow(Info, E, -LHS.extend(LHS.getBitWidth() + 1), E->getType());
- Result = (Opcode == BO_Rem ? LHS % RHS : LHS / RHS);
+ return HandleOverflow(Info, E, -LHS.extend(LHS.getBitWidth() + 1),
+ E->getType());
return true;
case BO_Shl: {
if (Info.getLangOpts().OpenCL)
@@ -1760,8 +1842,10 @@ static bool handleFloatFloatBinOp(EvalInfo &Info, const Expr *E,
break;
}
- if (LHS.isInfinity() || LHS.isNaN())
+ if (LHS.isInfinity() || LHS.isNaN()) {
Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << LHS.isNaN();
+ return Info.noteUndefinedBehavior();
+ }
return true;
}
@@ -2159,6 +2243,7 @@ enum AccessKinds {
AK_Decrement
};
+namespace {
/// A handle to a complete object (an object that is not a subobject of
/// another object).
struct CompleteObject {
@@ -2175,6 +2260,7 @@ struct CompleteObject {
explicit operator bool() const { return Value; }
};
+} // end anonymous namespace
/// Find the designated sub-object of an rvalue.
template<typename SubobjectHandler>
@@ -2488,7 +2574,7 @@ static bool AreElementsOfSameArray(QualType ObjType,
if (A.Entries.size() != B.Entries.size())
return false;
- bool IsArray = A.MostDerivedArraySize != 0;
+ bool IsArray = A.MostDerivedIsArrayElement;
if (IsArray && A.MostDerivedPathLength != A.Entries.size())
// A is a subobject of the array element.
return false;
@@ -2713,8 +2799,7 @@ static bool handleLValueToRValueConversion(EvalInfo &Info, const Expr *Conv,
// Check for special cases where there is no existing APValue to look at.
const Expr *Base = LVal.Base.dyn_cast<const Expr*>();
- if (!LVal.Designator.Invalid && Base && !LVal.CallIndex &&
- !Type.isVolatileQualified()) {
+ if (Base && !LVal.CallIndex && !Type.isVolatileQualified()) {
if (const CompoundLiteralExpr *CLE = dyn_cast<CompoundLiteralExpr>(Base)) {
// In C99, a CompoundLiteralExpr is an lvalue, and we defer evaluating the
// initializer until now for such expressions. Such an expression can't be
@@ -2959,7 +3044,7 @@ struct IncDecSubobjectHandler {
if (!WasNegative && Value.isNegative() &&
isOverflowingIntegerType(Info.Ctx, SubobjType)) {
APSInt ActualValue(Value, /*IsUnsigned*/true);
- HandleOverflow(Info, E, ActualValue, SubobjType);
+ return HandleOverflow(Info, E, ActualValue, SubobjType);
}
} else {
--Value;
@@ -2969,7 +3054,7 @@ struct IncDecSubobjectHandler {
unsigned BitWidth = Value.getBitWidth();
APSInt ActualValue(Value.sext(BitWidth + 1), /*IsUnsigned*/false);
ActualValue.setBit(BitWidth);
- HandleOverflow(Info, E, ActualValue, SubobjType);
+ return HandleOverflow(Info, E, ActualValue, SubobjType);
}
}
return true;
@@ -3253,12 +3338,21 @@ static bool EvaluateCond(EvalInfo &Info, const VarDecl *CondDecl,
return EvaluateAsBooleanCondition(Cond, Result, Info);
}
-static EvalStmtResult EvaluateStmt(APValue &Result, EvalInfo &Info,
+/// \brief A location where the result (returned value) of evaluating a
+/// statement should be stored.
+struct StmtResult {
+ /// The APValue that should be filled in with the returned value.
+ APValue &Value;
+ /// The location containing the result, if any (used to support RVO).
+ const LValue *Slot;
+};
+
+static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info,
const Stmt *S,
const SwitchCase *SC = nullptr);
/// Evaluate the body of a loop, and translate the result as appropriate.
-static EvalStmtResult EvaluateLoopBody(APValue &Result, EvalInfo &Info,
+static EvalStmtResult EvaluateLoopBody(StmtResult &Result, EvalInfo &Info,
const Stmt *Body,
const SwitchCase *Case = nullptr) {
BlockScopeRAII Scope(Info);
@@ -3277,7 +3371,7 @@ static EvalStmtResult EvaluateLoopBody(APValue &Result, EvalInfo &Info,
}
/// Evaluate a switch statement.
-static EvalStmtResult EvaluateSwitch(APValue &Result, EvalInfo &Info,
+static EvalStmtResult EvaluateSwitch(StmtResult &Result, EvalInfo &Info,
const SwitchStmt *SS) {
BlockScopeRAII Scope(Info);
@@ -3334,7 +3428,7 @@ static EvalStmtResult EvaluateSwitch(APValue &Result, EvalInfo &Info,
}
// Evaluate a statement.
-static EvalStmtResult EvaluateStmt(APValue &Result, EvalInfo &Info,
+static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info,
const Stmt *S, const SwitchCase *Case) {
if (!Info.nextStep(S))
return ESR_Failed;
@@ -3440,7 +3534,10 @@ static EvalStmtResult EvaluateStmt(APValue &Result, EvalInfo &Info,
case Stmt::ReturnStmtClass: {
const Expr *RetExpr = cast<ReturnStmt>(S)->getRetValue();
FullExpressionRAII Scope(Info);
- if (RetExpr && !Evaluate(Result, Info, RetExpr))
+ if (RetExpr &&
+ !(Result.Slot
+ ? EvaluateInPlace(Result.Value, Info, *Result.Slot, RetExpr)
+ : Evaluate(Result.Value, Info, RetExpr)))
return ESR_Failed;
return ESR_Returned;
}
@@ -3710,7 +3807,8 @@ static bool EvaluateArgs(ArrayRef<const Expr*> Args, ArgVector &ArgValues,
static bool HandleFunctionCall(SourceLocation CallLoc,
const FunctionDecl *Callee, const LValue *This,
ArrayRef<const Expr*> Args, const Stmt *Body,
- EvalInfo &Info, APValue &Result) {
+ EvalInfo &Info, APValue &Result,
+ const LValue *ResultSlot) {
ArgVector ArgValues(Args.size());
if (!EvaluateArgs(Args, ArgValues, Info))
return false;
@@ -3745,7 +3843,8 @@ static bool HandleFunctionCall(SourceLocation CallLoc,
return true;
}
- EvalStmtResult ESR = EvaluateStmt(Result, Info, Body);
+ StmtResult Ret = {Result, ResultSlot};
+ EvalStmtResult ESR = EvaluateStmt(Ret, Info, Body);
if (ESR == ESR_Succeeded) {
if (Callee->getReturnType()->isVoidType())
return true;
@@ -3774,6 +3873,11 @@ static bool HandleConstructorCall(SourceLocation CallLoc, const LValue &This,
CallStackFrame Frame(Info, CallLoc, Definition, &This, ArgValues.data());
+ // FIXME: Creating an APValue just to hold a nonexistent return value is
+ // wasteful.
+ APValue RetVal;
+ StmtResult Ret = {RetVal, nullptr};
+
// If it's a delegating constructor, just delegate.
if (Definition->isDelegatingConstructor()) {
CXXConstructorDecl::init_const_iterator I = Definition->init_begin();
@@ -3782,7 +3886,7 @@ static bool HandleConstructorCall(SourceLocation CallLoc, const LValue &This,
if (!EvaluateInPlace(Result, Info, This, (*I)->getInit()))
return false;
}
- return EvaluateStmt(Result, Info, Definition->getBody()) != ESR_Failed;
+ return EvaluateStmt(Ret, Info, Definition->getBody()) != ESR_Failed;
}
// For a trivial copy or move constructor, perform an APValue copy. This is
@@ -3890,7 +3994,7 @@ static bool HandleConstructorCall(SourceLocation CallLoc, const LValue &This,
}
return Success &&
- EvaluateStmt(Result, Info, Definition->getBody()) != ESR_Failed;
+ EvaluateStmt(Ret, Info, Definition->getBody()) != ESR_Failed;
}
//===----------------------------------------------------------------------===//
@@ -3902,11 +4006,12 @@ template <class Derived>
class ExprEvaluatorBase
: public ConstStmtVisitor<Derived, bool> {
private:
+ Derived &getDerived() { return static_cast<Derived&>(*this); }
bool DerivedSuccess(const APValue &V, const Expr *E) {
- return static_cast<Derived*>(this)->Success(V, E);
+ return getDerived().Success(V, E);
}
bool DerivedZeroInitialization(const Expr *E) {
- return static_cast<Derived*>(this)->ZeroInitialization(E);
+ return getDerived().ZeroInitialization(E);
}
// Check whether a conditional operator with a non-constant condition is a
@@ -4087,6 +4192,14 @@ public:
}
bool VisitCallExpr(const CallExpr *E) {
+ APValue Result;
+ if (!handleCallExpr(E, Result, nullptr))
+ return false;
+ return DerivedSuccess(Result, E);
+ }
+
+ bool handleCallExpr(const CallExpr *E, APValue &Result,
+ const LValue *ResultSlot) {
const Expr *Callee = E->getCallee()->IgnoreParens();
QualType CalleeType = Callee->getType();
@@ -4161,14 +4274,13 @@ public:
const FunctionDecl *Definition = nullptr;
Stmt *Body = FD->getBody(Definition);
- APValue Result;
if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition) ||
- !HandleFunctionCall(E->getExprLoc(), Definition, This, Args, Body,
- Info, Result))
+ !HandleFunctionCall(E->getExprLoc(), Definition, This, Args, Body, Info,
+ Result, ResultSlot))
return false;
- return DerivedSuccess(Result, E);
+ return true;
}
bool VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
@@ -4293,7 +4405,8 @@ public:
}
APValue ReturnValue;
- EvalStmtResult ESR = EvaluateStmt(ReturnValue, Info, *BI);
+ StmtResult Result = { ReturnValue, nullptr };
+ EvalStmtResult ESR = EvaluateStmt(Result, Info, *BI);
if (ESR != ESR_Succeeded) {
// FIXME: If the statement-expression terminated due to 'return',
// 'break', or 'continue', it would be nice to propagate that to
@@ -4345,20 +4458,24 @@ public:
bool VisitMemberExpr(const MemberExpr *E) {
// Handle non-static data members.
QualType BaseTy;
+ bool EvalOK;
if (E->isArrow()) {
- if (!EvaluatePointer(E->getBase(), Result, this->Info))
- return false;
+ EvalOK = EvaluatePointer(E->getBase(), Result, this->Info);
BaseTy = E->getBase()->getType()->castAs<PointerType>()->getPointeeType();
} else if (E->getBase()->isRValue()) {
assert(E->getBase()->getType()->isRecordType());
- if (!EvaluateTemporary(E->getBase(), Result, this->Info))
- return false;
+ EvalOK = EvaluateTemporary(E->getBase(), Result, this->Info);
BaseTy = E->getBase()->getType();
} else {
- if (!this->Visit(E->getBase()))
- return false;
+ EvalOK = this->Visit(E->getBase());
BaseTy = E->getBase()->getType();
}
+ if (!EvalOK) {
+ if (!this->Info.allowInvalidBaseExpr())
+ return false;
+ Result.setInvalid(E);
+ return true;
+ }
const ValueDecl *MD = E->getMemberDecl();
if (const FieldDecl *FD = dyn_cast<FieldDecl>(E->getMemberDecl())) {
@@ -4498,12 +4615,13 @@ public:
} // end anonymous namespace
/// Evaluate an expression as an lvalue. This can be legitimately called on
-/// expressions which are not glvalues, in two cases:
+/// expressions which are not glvalues, in three cases:
/// * function designators in C, and
/// * "extern void" objects
+/// * @selector() expressions in Objective-C
static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info) {
assert(E->isGLValue() || E->getType()->isFunctionType() ||
- E->getType()->isVoidType());
+ E->getType()->isVoidType() || isa<ObjCSelectorExpr>(E));
return LValueExprEvaluator(Info, Result).Visit(E);
}
@@ -4770,7 +4888,7 @@ public:
bool VisitObjCStringLiteral(const ObjCStringLiteral *E)
{ return Success(E); }
bool VisitObjCBoxedExpr(const ObjCBoxedExpr *E)
- { return Success(E); }
+ { return Success(E); }
bool VisitAddrLabelExpr(const AddrLabelExpr *E)
{ return Success(E); }
bool VisitCallExpr(const CallExpr *E);
@@ -4896,6 +5014,7 @@ bool PointerExprEvaluator::VisitCastExpr(const CastExpr* E) {
unsigned Size = Info.Ctx.getTypeSize(E->getType());
uint64_t N = Value.getInt().extOrTrunc(Size).getZExtValue();
Result.Base = (Expr*)nullptr;
+ Result.InvalidBase = false;
Result.Offset = CharUnits::fromQuantity(N);
Result.CallIndex = 0;
Result.Designator.setInvalid();
@@ -5148,6 +5267,9 @@ namespace {
}
bool ZeroInitialization(const Expr *E);
+ bool VisitCallExpr(const CallExpr *E) {
+ return handleCallExpr(E, Result, &This);
+ }
bool VisitCastExpr(const CastExpr *E);
bool VisitInitListExpr(const InitListExpr *E);
bool VisitCXXConstructExpr(const CXXConstructExpr *E);
@@ -5504,7 +5626,7 @@ namespace {
VectorExprEvaluator(EvalInfo &info, APValue &Result)
: ExprEvaluatorBaseTy(info), Result(Result) {}
- bool Success(const ArrayRef<APValue> &V, const Expr *E) {
+ bool Success(ArrayRef<APValue> V, const Expr *E) {
assert(V.size() == E->getType()->castAs<VectorType>()->getNumElements());
// FIXME: remove this APValue copy.
Result = APValue(V.data(), V.size());
@@ -5533,7 +5655,7 @@ static bool EvaluateVector(const Expr* E, APValue& Result, EvalInfo &Info) {
return VectorExprEvaluator(Info, Result).Visit(E);
}
-bool VectorExprEvaluator::VisitCastExpr(const CastExpr* E) {
+bool VectorExprEvaluator::VisitCastExpr(const CastExpr *E) {
const VectorType *VTy = E->getType()->castAs<VectorType>();
unsigned NElts = VTy->getNumElements();
@@ -5546,13 +5668,13 @@ bool VectorExprEvaluator::VisitCastExpr(const CastExpr* E) {
if (SETy->isIntegerType()) {
APSInt IntResult;
if (!EvaluateInteger(SE, IntResult, Info))
- return false;
- Val = APValue(IntResult);
+ return false;
+ Val = APValue(std::move(IntResult));
} else if (SETy->isRealFloatingType()) {
- APFloat F(0.0);
- if (!EvaluateFloat(SE, F, Info))
- return false;
- Val = APValue(F);
+ APFloat FloatResult(0.0);
+ if (!EvaluateFloat(SE, FloatResult, Info))
+ return false;
+ Val = APValue(std::move(FloatResult));
} else {
return Error(E);
}
@@ -5710,6 +5832,9 @@ namespace {
return EvaluateInPlace(Result.getArrayFiller(), Info, Subobject, &VIE);
}
+ bool VisitCallExpr(const CallExpr *E) {
+ return handleCallExpr(E, Result, &This);
+ }
bool VisitInitListExpr(const InitListExpr *E);
bool VisitCXXConstructExpr(const CXXConstructExpr *E);
bool VisitCXXConstructExpr(const CXXConstructExpr *E,
@@ -5998,8 +6123,7 @@ public:
bool VisitSizeOfPackExpr(const SizeOfPackExpr *E);
private:
- static QualType GetObjectType(APValue::LValueBase B);
- bool TryEvaluateBuiltinObjectSize(const CallExpr *E);
+ bool TryEvaluateBuiltinObjectSize(const CallExpr *E, unsigned Type);
// FIXME: Missing: array subscript of vector, member of vector
};
} // end anonymous namespace
@@ -6151,8 +6275,8 @@ static bool EvaluateBuiltinConstantP(ASTContext &Ctx, const Expr *Arg) {
APValue &V = Result.Val;
if (V.getKind() == APValue::Int)
return true;
-
- return EvaluateBuiltinConstantPForLValue(V);
+ if (V.getKind() == APValue::LValue)
+ return EvaluateBuiltinConstantPForLValue(V);
} else if (ArgType->isFloatingType() || ArgType->isAnyComplexType()) {
return Arg->isEvaluatable(Ctx);
} else if (ArgType->isPointerType() || Arg->isGLValue()) {
@@ -6171,7 +6295,7 @@ static bool EvaluateBuiltinConstantP(ASTContext &Ctx, const Expr *Arg) {
/// Retrieves the "underlying object type" of the given expression,
/// as used by __builtin_object_size.
-QualType IntExprEvaluator::GetObjectType(APValue::LValueBase B) {
+static QualType getObjectType(APValue::LValueBase B) {
if (const ValueDecl *D = B.dyn_cast<const ValueDecl*>()) {
if (const VarDecl *VD = dyn_cast<VarDecl>(D))
return VD->getType();
@@ -6183,49 +6307,258 @@ QualType IntExprEvaluator::GetObjectType(APValue::LValueBase B) {
return QualType();
}
-bool IntExprEvaluator::TryEvaluateBuiltinObjectSize(const CallExpr *E) {
- LValue Base;
+/// A more selective version of E->IgnoreParenCasts for
+/// TryEvaluateBuiltinObjectSize. This ignores some casts/parens that serve only
+/// to change the type of E.
+/// Ex. For E = `(short*)((char*)(&foo))`, returns `&foo`
+///
+/// Always returns an RValue with a pointer representation.
+static const Expr *ignorePointerCastsAndParens(const Expr *E) {
+ assert(E->isRValue() && E->getType()->hasPointerRepresentation());
+ auto *NoParens = E->IgnoreParens();
+ auto *Cast = dyn_cast<CastExpr>(NoParens);
+ if (Cast == nullptr)
+ return NoParens;
+
+ // We only conservatively allow a few kinds of casts, because this code is
+ // inherently a simple solution that seeks to support the common case.
+ auto CastKind = Cast->getCastKind();
+ if (CastKind != CK_NoOp && CastKind != CK_BitCast &&
+ CastKind != CK_AddressSpaceConversion)
+ return NoParens;
+
+ auto *SubExpr = Cast->getSubExpr();
+ if (!SubExpr->getType()->hasPointerRepresentation() || !SubExpr->isRValue())
+ return NoParens;
+ return ignorePointerCastsAndParens(SubExpr);
+}
+
+/// Checks to see if the given LValue's Designator is at the end of the LValue's
+/// record layout. e.g.
+/// struct { struct { int a, b; } fst, snd; } obj;
+/// obj.fst // no
+/// obj.snd // yes
+/// obj.fst.a // no
+/// obj.fst.b // no
+/// obj.snd.a // no
+/// obj.snd.b // yes
+///
+/// Please note: this function is specialized for how __builtin_object_size
+/// views "objects".
+static bool isDesignatorAtObjectEnd(const ASTContext &Ctx, const LValue &LVal) {
+ assert(!LVal.Designator.Invalid);
+
+ auto IsLastFieldDecl = [&Ctx](const FieldDecl *FD) {
+ if (FD->getParent()->isUnion())
+ return true;
+ const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(FD->getParent());
+ return FD->getFieldIndex() + 1 == Layout.getFieldCount();
+ };
+
+ auto &Base = LVal.getLValueBase();
+ if (auto *ME = dyn_cast_or_null<MemberExpr>(Base.dyn_cast<const Expr *>())) {
+ if (auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
+ if (!IsLastFieldDecl(FD))
+ return false;
+ } else if (auto *IFD = dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) {
+ for (auto *FD : IFD->chain())
+ if (!IsLastFieldDecl(cast<FieldDecl>(FD)))
+ return false;
+ }
+ }
+
+ QualType BaseType = getType(Base);
+ for (int I = 0, E = LVal.Designator.Entries.size(); I != E; ++I) {
+ if (BaseType->isArrayType()) {
+ // Because __builtin_object_size treats arrays as objects, we can ignore
+ // the index iff this is the last array in the Designator.
+ if (I + 1 == E)
+ return true;
+ auto *CAT = cast<ConstantArrayType>(Ctx.getAsArrayType(BaseType));
+ uint64_t Index = LVal.Designator.Entries[I].ArrayIndex;
+ if (Index + 1 != CAT->getSize())
+ return false;
+ BaseType = CAT->getElementType();
+ } else if (BaseType->isAnyComplexType()) {
+ auto *CT = BaseType->castAs<ComplexType>();
+ uint64_t Index = LVal.Designator.Entries[I].ArrayIndex;
+ if (Index != 1)
+ return false;
+ BaseType = CT->getElementType();
+ } else if (auto *FD = getAsField(LVal.Designator.Entries[I])) {
+ if (!IsLastFieldDecl(FD))
+ return false;
+ BaseType = FD->getType();
+ } else {
+ assert(getAsBaseClass(LVal.Designator.Entries[I]) != nullptr &&
+ "Expecting cast to a base class");
+ return false;
+ }
+ }
+ return true;
+}
+
+/// Tests to see if the LValue has a designator (that isn't necessarily valid).
+static bool refersToCompleteObject(const LValue &LVal) {
+ if (LVal.Designator.Invalid || !LVal.Designator.Entries.empty())
+ return false;
+
+ if (!LVal.InvalidBase)
+ return true;
+
+ auto *E = LVal.Base.dyn_cast<const Expr *>();
+ (void)E;
+ assert(E != nullptr && isa<MemberExpr>(E));
+ return false;
+}
+
+/// Tries to evaluate the __builtin_object_size for @p E. If successful, returns
+/// true and stores the result in @p Size.
+///
+/// If @p WasError is non-null, this will report whether the failure to evaluate
+/// is to be treated as an Error in IntExprEvaluator.
+static bool tryEvaluateBuiltinObjectSize(const Expr *E, unsigned Type,
+ EvalInfo &Info, uint64_t &Size,
+ bool *WasError = nullptr) {
+ if (WasError != nullptr)
+ *WasError = false;
+
+ auto Error = [&](const Expr *E) {
+ if (WasError != nullptr)
+ *WasError = true;
+ return false;
+ };
+
+ auto Success = [&](uint64_t S, const Expr *E) {
+ Size = S;
+ return true;
+ };
+
+ // Determine the denoted object.
+ LValue Base;
{
// The operand of __builtin_object_size is never evaluated for side-effects.
// If there are any, but we can determine the pointed-to object anyway, then
// ignore the side-effects.
SpeculativeEvaluationRAII SpeculativeEval(Info);
- if (!EvaluatePointer(E->getArg(0), Base, Info))
+ FoldOffsetRAII Fold(Info, Type & 1);
+
+ if (E->isGLValue()) {
+ // It's possible for us to be given GLValues if we're called via
+ // Expr::tryEvaluateObjectSize.
+ APValue RVal;
+ if (!EvaluateAsRValue(Info, E, RVal))
+ return false;
+ Base.setFrom(Info.Ctx, RVal);
+ } else if (!EvaluatePointer(ignorePointerCastsAndParens(E), Base, Info))
return false;
}
- if (!Base.getLValueBase()) {
- // It is not possible to determine which objects ptr points to at compile time,
- // __builtin_object_size should return (size_t) -1 for type 0 or 1
- // and (size_t) 0 for type 2 or 3.
- llvm::APSInt TypeIntVaue;
- const Expr *ExprType = E->getArg(1);
- if (!ExprType->EvaluateAsInt(TypeIntVaue, Info.Ctx))
- return false;
- if (TypeIntVaue == 0 || TypeIntVaue == 1)
- return Success(-1, E);
- if (TypeIntVaue == 2 || TypeIntVaue == 3)
- return Success(0, E);
+ CharUnits BaseOffset = Base.getLValueOffset();
+ // If we point to before the start of the object, there are no accessible
+ // bytes.
+ if (BaseOffset.isNegative())
+ return Success(0, E);
+
+ // In the case where we're not dealing with a subobject, we discard the
+ // subobject bit.
+ bool SubobjectOnly = (Type & 1) != 0 && !refersToCompleteObject(Base);
+
+ // If Type & 1 is 0, we need to be able to statically guarantee that the bytes
+ // exist. If we can't verify the base, then we can't do that.
+ //
+ // As a special case, we produce a valid object size for an unknown object
+ // with a known designator if Type & 1 is 1. For instance:
+ //
+ // extern struct X { char buff[32]; int a, b, c; } *p;
+ // int a = __builtin_object_size(p->buff + 4, 3); // returns 28
+ // int b = __builtin_object_size(p->buff + 4, 2); // returns 0, not 40
+ //
+ // This matches GCC's behavior.
+ if (Base.InvalidBase && !SubobjectOnly)
return Error(E);
+
+ // If we're not examining only the subobject, then we reset to a complete
+ // object designator
+ //
+ // If Type is 1 and we've lost track of the subobject, just find the complete
+ // object instead. (If Type is 3, that's not correct behavior and we should
+ // return 0 instead.)
+ LValue End = Base;
+ if (!SubobjectOnly || (End.Designator.Invalid && Type == 1)) {
+ QualType T = getObjectType(End.getLValueBase());
+ if (T.isNull())
+ End.Designator.setInvalid();
+ else {
+ End.Designator = SubobjectDesignator(T);
+ End.Offset = CharUnits::Zero();
+ }
}
- QualType T = GetObjectType(Base.getLValueBase());
- if (T.isNull() ||
- T->isIncompleteType() ||
- T->isFunctionType() ||
- T->isVariablyModifiedType() ||
- T->isDependentType())
+ // If it is not possible to determine which objects ptr points to at compile
+ // time, __builtin_object_size should return (size_t) -1 for type 0 or 1
+ // and (size_t) 0 for type 2 or 3.
+ if (End.Designator.Invalid)
+ return false;
+
+ // According to the GCC documentation, we want the size of the subobject
+ // denoted by the pointer. But that's not quite right -- what we actually
+ // want is the size of the immediately-enclosing array, if there is one.
+ int64_t AmountToAdd = 1;
+ if (End.Designator.MostDerivedIsArrayElement &&
+ End.Designator.Entries.size() == End.Designator.MostDerivedPathLength) {
+ // We got a pointer to an array. Step to its end.
+ AmountToAdd = End.Designator.MostDerivedArraySize -
+ End.Designator.Entries.back().ArrayIndex;
+ } else if (End.Designator.isOnePastTheEnd()) {
+ // We're already pointing at the end of the object.
+ AmountToAdd = 0;
+ }
+
+ QualType PointeeType = End.Designator.MostDerivedType;
+ assert(!PointeeType.isNull());
+ if (PointeeType->isIncompleteType() || PointeeType->isFunctionType())
return Error(E);
- CharUnits Size = Info.Ctx.getTypeSizeInChars(T);
- CharUnits Offset = Base.getLValueOffset();
+ if (!HandleLValueArrayAdjustment(Info, E, End, End.Designator.MostDerivedType,
+ AmountToAdd))
+ return false;
- if (!Offset.isNegative() && Offset <= Size)
- Size -= Offset;
- else
- Size = CharUnits::Zero();
- return Success(Size, E);
+ auto EndOffset = End.getLValueOffset();
+
+ // The following is a moderately common idiom in C:
+ //
+ // struct Foo { int a; char c[1]; };
+ // struct Foo *F = (struct Foo *)malloc(sizeof(struct Foo) + strlen(Bar));
+ // strcpy(&F->c[0], Bar);
+ //
+ // So, if we see that we're examining a 1-length (or 0-length) array at the
+ // end of a struct with an unknown base, we give up instead of breaking code
+ // that behaves this way. Note that we only do this when Type=1, because
+ // Type=3 is a lower bound, so answering conservatively is fine.
+ if (End.InvalidBase && SubobjectOnly && Type == 1 &&
+ End.Designator.Entries.size() == End.Designator.MostDerivedPathLength &&
+ End.Designator.MostDerivedIsArrayElement &&
+ End.Designator.MostDerivedArraySize < 2 &&
+ isDesignatorAtObjectEnd(Info.Ctx, End))
+ return false;
+
+ if (BaseOffset > EndOffset)
+ return Success(0, E);
+
+ return Success((EndOffset - BaseOffset).getQuantity(), E);
+}
+
+bool IntExprEvaluator::TryEvaluateBuiltinObjectSize(const CallExpr *E,
+ unsigned Type) {
+ uint64_t Size;
+ bool WasError;
+ if (::tryEvaluateBuiltinObjectSize(E->getArg(0), Type, Info, Size, &WasError))
+ return Success(Size, E);
+ if (WasError)
+ return Error(E);
+ return false;
}
bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) {
@@ -6234,17 +6567,16 @@ bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) {
return ExprEvaluatorBaseTy::VisitCallExpr(E);
case Builtin::BI__builtin_object_size: {
- if (TryEvaluateBuiltinObjectSize(E))
+ // The type was checked when we built the expression.
+ unsigned Type =
+ E->getArg(1)->EvaluateKnownConstInt(Info.Ctx).getZExtValue();
+ assert(Type <= 3 && "unexpected type");
+
+ if (TryEvaluateBuiltinObjectSize(E, Type))
return true;
- // If evaluating the argument has side-effects, we can't determine the size
- // of the object, and so we lower it to unknown now. CodeGen relies on us to
- // handle all cases where the expression has side-effects.
- if (E->getArg(0)->HasSideEffects(Info.Ctx)) {
- if (E->getArg(1)->EvaluateKnownConstInt(Info.Ctx).getZExtValue() <= 1)
- return Success(-1ULL, E);
- return Success(0, E);
- }
+ if (E->getArg(0)->HasSideEffects(Info.Ctx))
+ return Success((Type & 2) ? 0 : -1, E);
// Expression had no side effects, but we couldn't statically determine the
// size of the referenced object.
@@ -6254,10 +6586,13 @@ bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) {
case EvalInfo::EM_ConstantFold:
case EvalInfo::EM_EvaluateForOverflow:
case EvalInfo::EM_IgnoreSideEffects:
+ case EvalInfo::EM_DesignatorFold:
+ // Leave it to IR generation.
return Error(E);
case EvalInfo::EM_ConstantExpressionUnevaluated:
case EvalInfo::EM_PotentialConstantExpressionUnevaluated:
- return Success(-1ULL, E);
+ // Reduce it to a constant now.
+ return Success((Type & 2) ? 0 : -1, E);
}
}
@@ -6523,9 +6858,15 @@ static bool isOnePastTheEndOfCompleteObject(const ASTContext &Ctx,
!LV.getLValueDesignator().isOnePastTheEnd())
return false;
+ // A pointer to an incomplete type might be past-the-end if the type's size is
+ // zero. We cannot tell because the type is incomplete.
+ QualType Ty = getType(LV.getLValueBase());
+ if (Ty->isIncompleteType())
+ return true;
+
// We're a past-the-end pointer if we point to the byte after the object,
// no matter what our type or path is.
- auto Size = Ctx.getTypeSizeInChars(getType(LV.getLValueBase()));
+ auto Size = Ctx.getTypeSizeInChars(Ty);
return LV.getLValueOffset() == Size;
}
@@ -6555,7 +6896,13 @@ class DataRecursiveIntBinOpEvaluator {
EvalResult LHSResult; // meaningful only for binary operator expression.
enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind } Kind;
- Job() : StoredInfo(nullptr) {}
+ Job() = default;
+ Job(Job &&J)
+ : E(J.E), LHSResult(J.LHSResult), Kind(J.Kind),
+ StoredInfo(J.StoredInfo), OldEvalStatus(J.OldEvalStatus) {
+ J.StoredInfo = nullptr;
+ }
+
void startSpeculativeEval(EvalInfo &Info) {
OldEvalStatus = Info.EvalStatus;
Info.EvalStatus.Diag = nullptr;
@@ -6567,7 +6914,7 @@ class DataRecursiveIntBinOpEvaluator {
}
}
private:
- EvalInfo *StoredInfo; // non-null if status changed.
+ EvalInfo *StoredInfo = nullptr; // non-null if status changed.
Expr::EvalStatus OldEvalStatus;
};
@@ -6946,7 +7293,7 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
LValue LHSValue, RHSValue;
bool LHSOK = EvaluatePointer(E->getLHS(), LHSValue, Info);
- if (!LHSOK && Info.keepEvaluatingAfterFailure())
+ if (!LHSOK && !Info.keepEvaluatingAfterFailure())
return false;
if (!EvaluatePointer(E->getRHS(), RHSValue, Info) || !LHSOK)
@@ -6958,21 +7305,20 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
if (E->getOpcode() == BO_Sub) {
// Handle &&A - &&B.
if (!LHSValue.Offset.isZero() || !RHSValue.Offset.isZero())
- return false;
+ return Error(E);
const Expr *LHSExpr = LHSValue.Base.dyn_cast<const Expr*>();
const Expr *RHSExpr = RHSValue.Base.dyn_cast<const Expr*>();
if (!LHSExpr || !RHSExpr)
- return false;
+ return Error(E);
const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
if (!LHSAddrExpr || !RHSAddrExpr)
- return false;
+ return Error(E);
// Make sure both labels come from the same function.
if (LHSAddrExpr->getLabel()->getDeclContext() !=
RHSAddrExpr->getLabel()->getDeclContext())
- return false;
- Result = APValue(LHSAddrExpr, RHSAddrExpr);
- return true;
+ return Error(E);
+ return Success(APValue(LHSAddrExpr, RHSAddrExpr), E);
}
// Inequalities and subtractions between unrelated pointers have
// unspecified or undefined behavior.
@@ -7063,8 +7409,9 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
APSInt TrueResult = (LHS - RHS) / ElemSize;
APSInt Result = TrueResult.trunc(Info.Ctx.getIntWidth(E->getType()));
- if (Result.extend(65) != TrueResult)
- HandleOverflow(Info, E, TrueResult, E->getType());
+ if (Result.extend(65) != TrueResult &&
+ !HandleOverflow(Info, E, TrueResult, E->getType()))
+ return false;
return Success(Result, E);
}
@@ -7270,9 +7617,9 @@ bool IntExprEvaluator::VisitOffsetOfExpr(const OffsetOfExpr *OOE) {
return Error(OOE);
QualType CurrentType = OOE->getTypeSourceInfo()->getType();
for (unsigned i = 0; i != n; ++i) {
- OffsetOfExpr::OffsetOfNode ON = OOE->getComponent(i);
+ OffsetOfNode ON = OOE->getComponent(i);
switch (ON.getKind()) {
- case OffsetOfExpr::OffsetOfNode::Array: {
+ case OffsetOfNode::Array: {
const Expr *Idx = OOE->getIndexExpr(ON.getArrayExprIndex());
APSInt IdxResult;
if (!EvaluateInteger(Idx, IdxResult, Info))
@@ -7286,7 +7633,7 @@ bool IntExprEvaluator::VisitOffsetOfExpr(const OffsetOfExpr *OOE) {
break;
}
- case OffsetOfExpr::OffsetOfNode::Field: {
+ case OffsetOfNode::Field: {
FieldDecl *MemberDecl = ON.getField();
const RecordType *RT = CurrentType->getAs<RecordType>();
if (!RT)
@@ -7301,10 +7648,10 @@ bool IntExprEvaluator::VisitOffsetOfExpr(const OffsetOfExpr *OOE) {
break;
}
- case OffsetOfExpr::OffsetOfNode::Identifier:
+ case OffsetOfNode::Identifier:
llvm_unreachable("dependent __builtin_offsetof");
- case OffsetOfExpr::OffsetOfNode::Base: {
+ case OffsetOfNode::Base: {
CXXBaseSpecifier *BaseSpec = ON.getBase();
if (BaseSpec->isVirtual())
return Error(OOE);
@@ -7350,9 +7697,10 @@ bool IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
return false;
if (!Result.isInt()) return Error(E);
const APSInt &Value = Result.getInt();
- if (Value.isSigned() && Value.isMinSignedValue())
- HandleOverflow(Info, E, -Value.extend(Value.getBitWidth() + 1),
- E->getType());
+ if (Value.isSigned() && Value.isMinSignedValue() &&
+ !HandleOverflow(Info, E, -Value.extend(Value.getBitWidth() + 1),
+ E->getType()))
+ return false;
return Success(-Value, E);
}
case UO_Not: {
@@ -8512,6 +8860,12 @@ bool Expr::EvaluateAsBooleanCondition(bool &Result,
HandleConversionToBool(Scratch.Val, Result);
}
+static bool hasUnacceptableSideEffect(Expr::EvalStatus &Result,
+ Expr::SideEffectsKind SEK) {
+ return (SEK < Expr::SE_AllowSideEffects && Result.HasSideEffects) ||
+ (SEK < Expr::SE_AllowUndefinedBehavior && Result.HasUndefinedBehavior);
+}
+
bool Expr::EvaluateAsInt(APSInt &Result, const ASTContext &Ctx,
SideEffectsKind AllowSideEffects) const {
if (!getType()->isIntegralOrEnumerationType())
@@ -8519,7 +8873,7 @@ bool Expr::EvaluateAsInt(APSInt &Result, const ASTContext &Ctx,
EvalResult ExprResult;
if (!EvaluateAsRValue(ExprResult, Ctx) || !ExprResult.Val.isInt() ||
- (!AllowSideEffects && ExprResult.HasSideEffects))
+ hasUnacceptableSideEffect(ExprResult, AllowSideEffects))
return false;
Result = ExprResult.Val.getInt();
@@ -8551,7 +8905,9 @@ bool Expr::EvaluateAsInitializer(APValue &Value, const ASTContext &Ctx,
Expr::EvalStatus EStatus;
EStatus.Diag = &Notes;
- EvalInfo InitInfo(Ctx, EStatus, EvalInfo::EM_ConstantFold);
+ EvalInfo InitInfo(Ctx, EStatus, VD->isConstexpr()
+ ? EvalInfo::EM_ConstantExpression
+ : EvalInfo::EM_ConstantFold);
InitInfo.setEvaluatingDecl(VD, Value);
LValue LVal;
@@ -8580,9 +8936,10 @@ bool Expr::EvaluateAsInitializer(APValue &Value, const ASTContext &Ctx,
/// isEvaluatable - Call EvaluateAsRValue to see if this expression can be
/// constant folded, but discard the result.
-bool Expr::isEvaluatable(const ASTContext &Ctx) const {
+bool Expr::isEvaluatable(const ASTContext &Ctx, SideEffectsKind SEK) const {
EvalResult Result;
- return EvaluateAsRValue(Result, Ctx) && !Result.HasSideEffects;
+ return EvaluateAsRValue(Result, Ctx) &&
+ !hasUnacceptableSideEffect(Result, SEK);
}
APSInt Expr::EvaluateKnownConstInt(const ASTContext &Ctx,
@@ -8677,6 +9034,7 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) {
case Expr::ImaginaryLiteralClass:
case Expr::StringLiteralClass:
case Expr::ArraySubscriptExprClass:
+ case Expr::OMPArraySectionExprClass:
case Expr::MemberExprClass:
case Expr::CompoundAssignOperatorClass:
case Expr::CompoundLiteralExprClass:
@@ -8695,6 +9053,7 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) {
case Expr::CXXTypeidExprClass:
case Expr::CXXUuidofExprClass:
case Expr::MSPropertyRefExprClass:
+ case Expr::MSPropertySubscriptExprClass:
case Expr::CXXNullPtrLiteralExprClass:
case Expr::UserDefinedLiteralClass:
case Expr::CXXThisExprClass:
@@ -8740,6 +9099,8 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) {
case Expr::AtomicExprClass:
case Expr::LambdaExprClass:
case Expr::CXXFoldExprClass:
+ case Expr::CoawaitExprClass:
+ case Expr::CoyieldExprClass:
return ICEDiag(IK_NotICE, E->getLocStart());
case Expr::InitListExprClass: {
@@ -8825,6 +9186,7 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) {
case UO_PreDec:
case UO_AddrOf:
case UO_Deref:
+ case UO_Coawait:
// C99 6.6/3 allows increment and decrement within unevaluated
// subexpressions of constant expressions, but they can never be ICEs
// because an ICE cannot contain an lvalue operand.
@@ -9078,7 +9440,11 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Value, const ASTContext &Ctx,
if (!isIntegerConstantExpr(Ctx, Loc))
return false;
- if (!EvaluateAsInt(Value, Ctx))
+ // The only possible side-effects here are due to UB discovered in the
+ // evaluation (for instance, INT_MAX + 1). In such a case, we are still
+ // required to treat the expression as an ICE, so we produce the folded
+ // value.
+ if (!EvaluateAsInt(Value, Ctx, SE_AllowSideEffects))
llvm_unreachable("ICE cannot be evaluated!");
return true;
}
@@ -9172,7 +9538,7 @@ bool Expr::isPotentialConstantExpr(const FunctionDecl *FD,
HandleConstructorCall(Loc, This, Args, CD, Info, Scratch);
} else
HandleFunctionCall(Loc, FD, (MD && MD->isInstance()) ? &This : nullptr,
- Args, FD->getBody(), Info, Scratch);
+ Args, FD->getBody(), Info, Scratch, nullptr);
return Diags.empty();
}
@@ -9200,3 +9566,13 @@ bool Expr::isPotentialConstantExprUnevaluated(Expr *E,
Evaluate(ResultScratch, Info, E);
return Diags.empty();
}
+
+bool Expr::tryEvaluateObjectSize(uint64_t &Result, ASTContext &Ctx,
+ unsigned Type) const {
+ if (!getType()->isPointerType())
+ return false;
+
+ Expr::EvalStatus Status;
+ EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
+ return ::tryEvaluateBuiltinObjectSize(this, Type, Info, Result);
+}
diff --git a/lib/AST/ExprObjC.cpp b/lib/AST/ExprObjC.cpp
new file mode 100644
index 000000000000..46298c7a730b
--- /dev/null
+++ b/lib/AST/ExprObjC.cpp
@@ -0,0 +1,379 @@
+//===--- ExprObjC.cpp - (ObjC) Expression AST Node Implementation ---------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the subclesses of Expr class declared in ExprObjC.h
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/ExprObjC.h"
+
+#include "clang/AST/ASTContext.h"
+
+using namespace clang;
+
+ObjCArrayLiteral::ObjCArrayLiteral(ArrayRef<Expr *> Elements, QualType T,
+ ObjCMethodDecl *Method, SourceRange SR)
+ : Expr(ObjCArrayLiteralClass, T, VK_RValue, OK_Ordinary, false, false,
+ false, false),
+ NumElements(Elements.size()), Range(SR), ArrayWithObjectsMethod(Method) {
+ Expr **SaveElements = getElements();
+ for (unsigned I = 0, N = Elements.size(); I != N; ++I) {
+ if (Elements[I]->isTypeDependent() || Elements[I]->isValueDependent())
+ ExprBits.ValueDependent = true;
+ if (Elements[I]->isInstantiationDependent())
+ ExprBits.InstantiationDependent = true;
+ if (Elements[I]->containsUnexpandedParameterPack())
+ ExprBits.ContainsUnexpandedParameterPack = true;
+
+ SaveElements[I] = Elements[I];
+ }
+}
+
+ObjCArrayLiteral *ObjCArrayLiteral::Create(const ASTContext &C,
+ ArrayRef<Expr *> Elements,
+ QualType T, ObjCMethodDecl *Method,
+ SourceRange SR) {
+ void *Mem =
+ C.Allocate(sizeof(ObjCArrayLiteral) + Elements.size() * sizeof(Expr *));
+ return new (Mem) ObjCArrayLiteral(Elements, T, Method, SR);
+}
+
+ObjCArrayLiteral *ObjCArrayLiteral::CreateEmpty(const ASTContext &C,
+ unsigned NumElements) {
+
+ void *Mem =
+ C.Allocate(sizeof(ObjCArrayLiteral) + NumElements * sizeof(Expr *));
+ return new (Mem) ObjCArrayLiteral(EmptyShell(), NumElements);
+}
+
+ObjCDictionaryLiteral::ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK,
+ bool HasPackExpansions, QualType T,
+ ObjCMethodDecl *method,
+ SourceRange SR)
+ : Expr(ObjCDictionaryLiteralClass, T, VK_RValue, OK_Ordinary, false, false,
+ false, false),
+ NumElements(VK.size()), HasPackExpansions(HasPackExpansions), Range(SR),
+ DictWithObjectsMethod(method) {
+ KeyValuePair *KeyValues = getKeyValues();
+ ExpansionData *Expansions = getExpansionData();
+ for (unsigned I = 0; I < NumElements; I++) {
+ if (VK[I].Key->isTypeDependent() || VK[I].Key->isValueDependent() ||
+ VK[I].Value->isTypeDependent() || VK[I].Value->isValueDependent())
+ ExprBits.ValueDependent = true;
+ if (VK[I].Key->isInstantiationDependent() ||
+ VK[I].Value->isInstantiationDependent())
+ ExprBits.InstantiationDependent = true;
+ if (VK[I].EllipsisLoc.isInvalid() &&
+ (VK[I].Key->containsUnexpandedParameterPack() ||
+ VK[I].Value->containsUnexpandedParameterPack()))
+ ExprBits.ContainsUnexpandedParameterPack = true;
+
+ KeyValues[I].Key = VK[I].Key;
+ KeyValues[I].Value = VK[I].Value;
+ if (Expansions) {
+ Expansions[I].EllipsisLoc = VK[I].EllipsisLoc;
+ if (VK[I].NumExpansions)
+ Expansions[I].NumExpansionsPlusOne = *VK[I].NumExpansions + 1;
+ else
+ Expansions[I].NumExpansionsPlusOne = 0;
+ }
+ }
+}
+
+ObjCDictionaryLiteral *
+ObjCDictionaryLiteral::Create(const ASTContext &C,
+ ArrayRef<ObjCDictionaryElement> VK,
+ bool HasPackExpansions, QualType T,
+ ObjCMethodDecl *method, SourceRange SR) {
+ unsigned ExpansionsSize = 0;
+ if (HasPackExpansions)
+ ExpansionsSize = sizeof(ExpansionData) * VK.size();
+
+ void *Mem = C.Allocate(sizeof(ObjCDictionaryLiteral) +
+ sizeof(KeyValuePair) * VK.size() + ExpansionsSize);
+ return new (Mem) ObjCDictionaryLiteral(VK, HasPackExpansions, T, method, SR);
+}
+
+ObjCDictionaryLiteral *
+ObjCDictionaryLiteral::CreateEmpty(const ASTContext &C, unsigned NumElements,
+ bool HasPackExpansions) {
+ unsigned ExpansionsSize = 0;
+ if (HasPackExpansions)
+ ExpansionsSize = sizeof(ExpansionData) * NumElements;
+ void *Mem = C.Allocate(sizeof(ObjCDictionaryLiteral) +
+ sizeof(KeyValuePair) * NumElements + ExpansionsSize);
+ return new (Mem)
+ ObjCDictionaryLiteral(EmptyShell(), NumElements, HasPackExpansions);
+}
+
+QualType ObjCPropertyRefExpr::getReceiverType(const ASTContext &ctx) const {
+ if (isClassReceiver())
+ return ctx.getObjCInterfaceType(getClassReceiver());
+
+ if (isSuperReceiver())
+ return getSuperReceiverType();
+
+ return getBase()->getType();
+}
+
+ObjCSubscriptRefExpr *
+ObjCSubscriptRefExpr::Create(const ASTContext &C, Expr *base, Expr *key,
+ QualType T, ObjCMethodDecl *getMethod,
+ ObjCMethodDecl *setMethod, SourceLocation RB) {
+ void *Mem = C.Allocate(sizeof(ObjCSubscriptRefExpr));
+ return new (Mem) ObjCSubscriptRefExpr(
+ base, key, T, VK_LValue, OK_ObjCSubscript, getMethod, setMethod, RB);
+}
+
+ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
+ SourceLocation LBracLoc,
+ SourceLocation SuperLoc, bool IsInstanceSuper,
+ QualType SuperType, Selector Sel,
+ ArrayRef<SourceLocation> SelLocs,
+ SelectorLocationsKind SelLocsK,
+ ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
+ SourceLocation RBracLoc, bool isImplicit)
+ : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary,
+ /*TypeDependent=*/false, /*ValueDependent=*/false,
+ /*InstantiationDependent=*/false,
+ /*ContainsUnexpandedParameterPack=*/false),
+ SelectorOrMethod(
+ reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
+ Kind(IsInstanceSuper ? SuperInstance : SuperClass),
+ HasMethod(Method != nullptr), IsDelegateInitCall(false),
+ IsImplicit(isImplicit), SuperLoc(SuperLoc), LBracLoc(LBracLoc),
+ RBracLoc(RBracLoc) {
+ initArgsAndSelLocs(Args, SelLocs, SelLocsK);
+ setReceiverPointer(SuperType.getAsOpaquePtr());
+}
+
+ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
+ SourceLocation LBracLoc,
+ TypeSourceInfo *Receiver, Selector Sel,
+ ArrayRef<SourceLocation> SelLocs,
+ SelectorLocationsKind SelLocsK,
+ ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
+ SourceLocation RBracLoc, bool isImplicit)
+ : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, T->isDependentType(),
+ T->isDependentType(), T->isInstantiationDependentType(),
+ T->containsUnexpandedParameterPack()),
+ SelectorOrMethod(
+ reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
+ Kind(Class), HasMethod(Method != nullptr), IsDelegateInitCall(false),
+ IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) {
+ initArgsAndSelLocs(Args, SelLocs, SelLocsK);
+ setReceiverPointer(Receiver);
+}
+
+ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
+ SourceLocation LBracLoc, Expr *Receiver,
+ Selector Sel, ArrayRef<SourceLocation> SelLocs,
+ SelectorLocationsKind SelLocsK,
+ ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
+ SourceLocation RBracLoc, bool isImplicit)
+ : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary,
+ Receiver->isTypeDependent(), Receiver->isTypeDependent(),
+ Receiver->isInstantiationDependent(),
+ Receiver->containsUnexpandedParameterPack()),
+ SelectorOrMethod(
+ reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
+ Kind(Instance), HasMethod(Method != nullptr), IsDelegateInitCall(false),
+ IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) {
+ initArgsAndSelLocs(Args, SelLocs, SelLocsK);
+ setReceiverPointer(Receiver);
+}
+
+void ObjCMessageExpr::initArgsAndSelLocs(ArrayRef<Expr *> Args,
+ ArrayRef<SourceLocation> SelLocs,
+ SelectorLocationsKind SelLocsK) {
+ setNumArgs(Args.size());
+ Expr **MyArgs = getArgs();
+ for (unsigned I = 0; I != Args.size(); ++I) {
+ if (Args[I]->isTypeDependent())
+ ExprBits.TypeDependent = true;
+ if (Args[I]->isValueDependent())
+ ExprBits.ValueDependent = true;
+ if (Args[I]->isInstantiationDependent())
+ ExprBits.InstantiationDependent = true;
+ if (Args[I]->containsUnexpandedParameterPack())
+ ExprBits.ContainsUnexpandedParameterPack = true;
+
+ MyArgs[I] = Args[I];
+ }
+
+ SelLocsKind = SelLocsK;
+ if (!isImplicit()) {
+ if (SelLocsK == SelLoc_NonStandard)
+ std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs());
+ }
+}
+
+ObjCMessageExpr *
+ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,
+ SourceLocation LBracLoc, SourceLocation SuperLoc,
+ bool IsInstanceSuper, QualType SuperType, Selector Sel,
+ ArrayRef<SourceLocation> SelLocs,
+ ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
+ SourceLocation RBracLoc, bool isImplicit) {
+ assert((!SelLocs.empty() || isImplicit) &&
+ "No selector locs for non-implicit message");
+ ObjCMessageExpr *Mem;
+ SelectorLocationsKind SelLocsK = SelectorLocationsKind();
+ if (isImplicit)
+ Mem = alloc(Context, Args.size(), 0);
+ else
+ Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
+ return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, SuperLoc, IsInstanceSuper,
+ SuperType, Sel, SelLocs, SelLocsK, Method,
+ Args, RBracLoc, isImplicit);
+}
+
+ObjCMessageExpr *
+ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,
+ SourceLocation LBracLoc, TypeSourceInfo *Receiver,
+ Selector Sel, ArrayRef<SourceLocation> SelLocs,
+ ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
+ SourceLocation RBracLoc, bool isImplicit) {
+ assert((!SelLocs.empty() || isImplicit) &&
+ "No selector locs for non-implicit message");
+ ObjCMessageExpr *Mem;
+ SelectorLocationsKind SelLocsK = SelectorLocationsKind();
+ if (isImplicit)
+ Mem = alloc(Context, Args.size(), 0);
+ else
+ Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
+ return new (Mem)
+ ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
+ Args, RBracLoc, isImplicit);
+}
+
+ObjCMessageExpr *
+ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,
+ SourceLocation LBracLoc, Expr *Receiver, Selector Sel,
+ ArrayRef<SourceLocation> SelLocs,
+ ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
+ SourceLocation RBracLoc, bool isImplicit) {
+ assert((!SelLocs.empty() || isImplicit) &&
+ "No selector locs for non-implicit message");
+ ObjCMessageExpr *Mem;
+ SelectorLocationsKind SelLocsK = SelectorLocationsKind();
+ if (isImplicit)
+ Mem = alloc(Context, Args.size(), 0);
+ else
+ Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
+ return new (Mem)
+ ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
+ Args, RBracLoc, isImplicit);
+}
+
+ObjCMessageExpr *ObjCMessageExpr::CreateEmpty(const ASTContext &Context,
+ unsigned NumArgs,
+ unsigned NumStoredSelLocs) {
+ ObjCMessageExpr *Mem = alloc(Context, NumArgs, NumStoredSelLocs);
+ return new (Mem) ObjCMessageExpr(EmptyShell(), NumArgs);
+}
+
+ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C,
+ ArrayRef<Expr *> Args,
+ SourceLocation RBraceLoc,
+ ArrayRef<SourceLocation> SelLocs,
+ Selector Sel,
+ SelectorLocationsKind &SelLocsK) {
+ SelLocsK = hasStandardSelectorLocs(Sel, SelLocs, Args, RBraceLoc);
+ unsigned NumStoredSelLocs =
+ (SelLocsK == SelLoc_NonStandard) ? SelLocs.size() : 0;
+ return alloc(C, Args.size(), NumStoredSelLocs);
+}
+
+ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C, unsigned NumArgs,
+ unsigned NumStoredSelLocs) {
+ unsigned Size = sizeof(ObjCMessageExpr) + sizeof(void *) +
+ NumArgs * sizeof(Expr *) +
+ NumStoredSelLocs * sizeof(SourceLocation);
+ return (ObjCMessageExpr *)C.Allocate(
+ Size, llvm::AlignOf<ObjCMessageExpr>::Alignment);
+}
+
+void ObjCMessageExpr::getSelectorLocs(
+ SmallVectorImpl<SourceLocation> &SelLocs) const {
+ for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)
+ SelLocs.push_back(getSelectorLoc(i));
+}
+
+SourceRange ObjCMessageExpr::getReceiverRange() const {
+ switch (getReceiverKind()) {
+ case Instance:
+ return getInstanceReceiver()->getSourceRange();
+
+ case Class:
+ return getClassReceiverTypeInfo()->getTypeLoc().getSourceRange();
+
+ case SuperInstance:
+ case SuperClass:
+ return getSuperLoc();
+ }
+
+ llvm_unreachable("Invalid ReceiverKind!");
+}
+
+Selector ObjCMessageExpr::getSelector() const {
+ if (HasMethod)
+ return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod)
+ ->getSelector();
+ return Selector(SelectorOrMethod);
+}
+
+QualType ObjCMessageExpr::getReceiverType() const {
+ switch (getReceiverKind()) {
+ case Instance:
+ return getInstanceReceiver()->getType();
+ case Class:
+ return getClassReceiver();
+ case SuperInstance:
+ case SuperClass:
+ return getSuperType();
+ }
+
+ llvm_unreachable("unexpected receiver kind");
+}
+
+ObjCInterfaceDecl *ObjCMessageExpr::getReceiverInterface() const {
+ QualType T = getReceiverType();
+
+ if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
+ return Ptr->getInterfaceDecl();
+
+ if (const ObjCObjectType *Ty = T->getAs<ObjCObjectType>())
+ return Ty->getInterface();
+
+ return nullptr;
+}
+
+Stmt::child_range ObjCMessageExpr::children() {
+ Stmt **begin;
+ if (getReceiverKind() == Instance)
+ begin = reinterpret_cast<Stmt **>(this + 1);
+ else
+ begin = reinterpret_cast<Stmt **>(getArgs());
+ return child_range(begin,
+ reinterpret_cast<Stmt **>(getArgs() + getNumArgs()));
+}
+
+StringRef ObjCBridgedCastExpr::getBridgeKindName() const {
+ switch (getBridgeKind()) {
+ case OBC_Bridge:
+ return "__bridge";
+ case OBC_BridgeTransfer:
+ return "__bridge_transfer";
+ case OBC_BridgeRetained:
+ return "__bridge_retained";
+ }
+
+ llvm_unreachable("Invalid BridgeKind!");
+}
diff --git a/lib/AST/ExternalASTSource.cpp b/lib/AST/ExternalASTSource.cpp
index 1c82c355134e..e3de8c5fefa2 100644
--- a/lib/AST/ExternalASTSource.cpp
+++ b/lib/AST/ExternalASTSource.cpp
@@ -16,6 +16,7 @@
#include "clang/AST/ExternalASTSource.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclarationName.h"
+#include "clang/Basic/Module.h"
#include "llvm/Support/ErrorHandling.h"
using namespace clang;
@@ -27,9 +28,19 @@ ExternalASTSource::getSourceDescriptor(unsigned ID) {
return None;
}
-ExternalASTSource::ASTSourceDescriptor
-ExternalASTSource::getSourceDescriptor(const Module &M) {
- return ASTSourceDescriptor();
+ExternalASTSource::ASTSourceDescriptor::ASTSourceDescriptor(const Module &M)
+ : Signature(M.Signature), ClangModule(&M) {
+ if (M.Directory)
+ Path = M.Directory->getName();
+ if (auto *File = M.getASTFile())
+ ASTFile = File->getName();
+}
+
+std::string ExternalASTSource::ASTSourceDescriptor::getModuleName() const {
+ if (ClangModule)
+ return ClangModule->Name;
+ else
+ return PCHModuleName;
}
void ExternalASTSource::FindFileRegionDecls(FileID File, unsigned Offset,
@@ -92,17 +103,13 @@ ExternalASTSource::FindExternalVisibleDeclsByName(const DeclContext *DC,
return false;
}
-void ExternalASTSource::completeVisibleDeclsMap(const DeclContext *DC) {
-}
+void ExternalASTSource::completeVisibleDeclsMap(const DeclContext *DC) {}
-ExternalLoadResult
-ExternalASTSource::FindExternalLexicalDecls(const DeclContext *DC,
- bool (*isKindWeWant)(Decl::Kind),
- SmallVectorImpl<Decl*> &Result) {
- return ELR_AlreadyLoaded;
-}
+void ExternalASTSource::FindExternalLexicalDecls(
+ const DeclContext *DC, llvm::function_ref<bool(Decl::Kind)> IsKindWeWant,
+ SmallVectorImpl<Decl *> &Result) {}
-void ExternalASTSource::getMemoryBufferSizes(MemoryBufferSizes &sizes) const { }
+void ExternalASTSource::getMemoryBufferSizes(MemoryBufferSizes &sizes) const {}
uint32_t ExternalASTSource::incrementGeneration(ASTContext &C) {
uint32_t OldGeneration = CurrentGeneration;
diff --git a/lib/AST/ItaniumCXXABI.cpp b/lib/AST/ItaniumCXXABI.cpp
index 7503cbfc9805..8a2cc0fbee42 100644
--- a/lib/AST/ItaniumCXXABI.cpp
+++ b/lib/AST/ItaniumCXXABI.cpp
@@ -149,6 +149,20 @@ public:
return nullptr;
}
+ void addTypedefNameForUnnamedTagDecl(TagDecl *TD,
+ TypedefNameDecl *DD) override {}
+
+ TypedefNameDecl *getTypedefNameForUnnamedTagDecl(const TagDecl *TD) override {
+ return nullptr;
+ }
+
+ void addDeclaratorForUnnamedTagDecl(TagDecl *TD,
+ DeclaratorDecl *DD) override {}
+
+ DeclaratorDecl *getDeclaratorForUnnamedTagDecl(const TagDecl *TD) override {
+ return nullptr;
+ }
+
MangleNumberingContext *createMangleNumberingContext() const override {
return new ItaniumNumberingContext();
}
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index dac803e5d2ff..8018188a6b24 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -174,8 +174,6 @@ public:
void mangleStringLiteral(const StringLiteral *, raw_ostream &) override;
- void mangleCXXVTableBitSet(const CXXRecordDecl *RD, raw_ostream &) override;
-
bool getNextDiscriminator(const NamedDecl *ND, unsigned &disc) {
// Lambda closure types are already numbered.
if (isLambda(ND))
@@ -379,8 +377,8 @@ private:
void mangleType(const TagType*);
void mangleType(TemplateName);
- void mangleBareFunctionType(const FunctionType *T,
- bool MangleReturnType);
+ void mangleBareFunctionType(const FunctionType *T, bool MangleReturnType,
+ const FunctionDecl *FD = nullptr);
void mangleNeonVectorType(const VectorType *T);
void mangleAArch64NeonVectorType(const VectorType *T);
@@ -397,7 +395,8 @@ private:
void mangleCXXCtorType(CXXCtorType T);
void mangleCXXDtorType(CXXDtorType T);
- void mangleTemplateArgs(const ASTTemplateArgumentListInfo &TemplateArgs);
+ void mangleTemplateArgs(const TemplateArgumentLoc *TemplateArgs,
+ unsigned NumTemplateArgs);
void mangleTemplateArgs(const TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs);
void mangleTemplateArgs(const TemplateArgumentList &AL);
@@ -525,7 +524,7 @@ void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) {
}
mangleBareFunctionType(FD->getType()->getAs<FunctionType>(),
- MangleReturnType);
+ MangleReturnType, FD);
}
static const DeclContext *IgnoreLinkageSpecDecls(const DeclContext *DC) {
@@ -700,8 +699,7 @@ void CXXNameMangler::mangleFloat(const llvm::APFloat &f) {
assert(numCharacters != 0);
// Allocate a buffer of the right number of characters.
- SmallVector<char, 20> buffer;
- buffer.set_size(numCharacters);
+ SmallVector<char, 20> buffer(numCharacters);
// Fill the buffer left-to-right.
for (unsigned stringIndex = 0; stringIndex != numCharacters; ++stringIndex) {
@@ -1020,7 +1018,7 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
unsigned UnnamedMangle = getASTContext().getManglingNumber(TD);
Out << "Ut";
if (UnnamedMangle > 1)
- Out << llvm::utostr(UnnamedMangle - 2);
+ Out << UnnamedMangle - 2;
Out << '_';
break;
}
@@ -1285,7 +1283,8 @@ void CXXNameMangler::mangleLambda(const CXXRecordDecl *Lambda) {
Out << "Ul";
const FunctionProtoType *Proto = Lambda->getLambdaTypeInfo()->getType()->
getAs<FunctionProtoType>();
- mangleBareFunctionType(Proto, /*MangleReturnType=*/false);
+ mangleBareFunctionType(Proto, /*MangleReturnType=*/false,
+ Lambda->getLambdaStaticInvoker());
Out << "E";
// The number is omitted for the first closure type with a given
@@ -1756,6 +1755,9 @@ CXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity) {
// The conditional operator can't be overloaded, but we still handle it when
// mangling expressions.
case OO_Conditional: Out << "qu"; break;
+ // Proposal on cxx-abi-dev, 2015-10-21.
+ // ::= aw # co_await
+ case OO_Coawait: Out << "aw"; break;
case OO_None:
case NUM_OVERLOADED_OPERATORS:
@@ -1988,34 +1990,79 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
// ::= Dn # std::nullptr_t (i.e., decltype(nullptr))
// ::= u <source-name> # vendor extended type
switch (T->getKind()) {
- case BuiltinType::Void: Out << 'v'; break;
- case BuiltinType::Bool: Out << 'b'; break;
- case BuiltinType::Char_U: case BuiltinType::Char_S: Out << 'c'; break;
- case BuiltinType::UChar: Out << 'h'; break;
- case BuiltinType::UShort: Out << 't'; break;
- case BuiltinType::UInt: Out << 'j'; break;
- case BuiltinType::ULong: Out << 'm'; break;
- case BuiltinType::ULongLong: Out << 'y'; break;
- case BuiltinType::UInt128: Out << 'o'; break;
- case BuiltinType::SChar: Out << 'a'; break;
+ case BuiltinType::Void:
+ Out << 'v';
+ break;
+ case BuiltinType::Bool:
+ Out << 'b';
+ break;
+ case BuiltinType::Char_U:
+ case BuiltinType::Char_S:
+ Out << 'c';
+ break;
+ case BuiltinType::UChar:
+ Out << 'h';
+ break;
+ case BuiltinType::UShort:
+ Out << 't';
+ break;
+ case BuiltinType::UInt:
+ Out << 'j';
+ break;
+ case BuiltinType::ULong:
+ Out << 'm';
+ break;
+ case BuiltinType::ULongLong:
+ Out << 'y';
+ break;
+ case BuiltinType::UInt128:
+ Out << 'o';
+ break;
+ case BuiltinType::SChar:
+ Out << 'a';
+ break;
case BuiltinType::WChar_S:
- case BuiltinType::WChar_U: Out << 'w'; break;
- case BuiltinType::Char16: Out << "Ds"; break;
- case BuiltinType::Char32: Out << "Di"; break;
- case BuiltinType::Short: Out << 's'; break;
- case BuiltinType::Int: Out << 'i'; break;
- case BuiltinType::Long: Out << 'l'; break;
- case BuiltinType::LongLong: Out << 'x'; break;
- case BuiltinType::Int128: Out << 'n'; break;
- case BuiltinType::Half: Out << "Dh"; break;
- case BuiltinType::Float: Out << 'f'; break;
- case BuiltinType::Double: Out << 'd'; break;
+ case BuiltinType::WChar_U:
+ Out << 'w';
+ break;
+ case BuiltinType::Char16:
+ Out << "Ds";
+ break;
+ case BuiltinType::Char32:
+ Out << "Di";
+ break;
+ case BuiltinType::Short:
+ Out << 's';
+ break;
+ case BuiltinType::Int:
+ Out << 'i';
+ break;
+ case BuiltinType::Long:
+ Out << 'l';
+ break;
+ case BuiltinType::LongLong:
+ Out << 'x';
+ break;
+ case BuiltinType::Int128:
+ Out << 'n';
+ break;
+ case BuiltinType::Half:
+ Out << "Dh";
+ break;
+ case BuiltinType::Float:
+ Out << 'f';
+ break;
+ case BuiltinType::Double:
+ Out << 'd';
+ break;
case BuiltinType::LongDouble:
Out << (getASTContext().getTargetInfo().useFloat128ManglingForLongDouble()
? 'g'
: 'e');
break;
- case BuiltinType::NullPtr: Out << "Dn"; break;
+ case BuiltinType::NullPtr:
+ Out << "Dn";
+ break;
#define BUILTIN_TYPE(Id, SingletonId)
#define PLACEHOLDER_TYPE(Id, SingletonId) \
@@ -2023,17 +2070,69 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
#include "clang/AST/BuiltinTypes.def"
case BuiltinType::Dependent:
llvm_unreachable("mangling a placeholder type");
- case BuiltinType::ObjCId: Out << "11objc_object"; break;
- case BuiltinType::ObjCClass: Out << "10objc_class"; break;
- case BuiltinType::ObjCSel: Out << "13objc_selector"; break;
- case BuiltinType::OCLImage1d: Out << "11ocl_image1d"; break;
- case BuiltinType::OCLImage1dArray: Out << "16ocl_image1darray"; break;
- case BuiltinType::OCLImage1dBuffer: Out << "17ocl_image1dbuffer"; break;
- case BuiltinType::OCLImage2d: Out << "11ocl_image2d"; break;
- case BuiltinType::OCLImage2dArray: Out << "16ocl_image2darray"; break;
- case BuiltinType::OCLImage3d: Out << "11ocl_image3d"; break;
- case BuiltinType::OCLSampler: Out << "11ocl_sampler"; break;
- case BuiltinType::OCLEvent: Out << "9ocl_event"; break;
+ case BuiltinType::ObjCId:
+ Out << "11objc_object";
+ break;
+ case BuiltinType::ObjCClass:
+ Out << "10objc_class";
+ break;
+ case BuiltinType::ObjCSel:
+ Out << "13objc_selector";
+ break;
+ case BuiltinType::OCLImage1d:
+ Out << "11ocl_image1d";
+ break;
+ case BuiltinType::OCLImage1dArray:
+ Out << "16ocl_image1darray";
+ break;
+ case BuiltinType::OCLImage1dBuffer:
+ Out << "17ocl_image1dbuffer";
+ break;
+ case BuiltinType::OCLImage2d:
+ Out << "11ocl_image2d";
+ break;
+ case BuiltinType::OCLImage2dArray:
+ Out << "16ocl_image2darray";
+ break;
+ case BuiltinType::OCLImage2dDepth:
+ Out << "16ocl_image2ddepth";
+ break;
+ case BuiltinType::OCLImage2dArrayDepth:
+ Out << "21ocl_image2darraydepth";
+ break;
+ case BuiltinType::OCLImage2dMSAA:
+ Out << "15ocl_image2dmsaa";
+ break;
+ case BuiltinType::OCLImage2dArrayMSAA:
+ Out << "20ocl_image2darraymsaa";
+ break;
+ case BuiltinType::OCLImage2dMSAADepth:
+ Out << "20ocl_image2dmsaadepth";
+ break;
+ case BuiltinType::OCLImage2dArrayMSAADepth:
+ Out << "35ocl_image2darraymsaadepth";
+ break;
+ case BuiltinType::OCLImage3d:
+ Out << "11ocl_image3d";
+ break;
+ case BuiltinType::OCLSampler:
+ Out << "11ocl_sampler";
+ break;
+ case BuiltinType::OCLEvent:
+ Out << "9ocl_event";
+ break;
+ case BuiltinType::OCLClkEvent:
+ Out << "12ocl_clkevent";
+ break;
+ case BuiltinType::OCLQueue:
+ Out << "9ocl_queue";
+ break;
+ case BuiltinType::OCLNDRange:
+ Out << "11ocl_ndrange";
+ break;
+ case BuiltinType::OCLReserveID:
+ Out << "13ocl_reserveid";
+ break;
}
}
@@ -2056,11 +2155,26 @@ void CXXNameMangler::mangleType(const FunctionProtoType *T) {
Out << 'E';
}
+
void CXXNameMangler::mangleType(const FunctionNoProtoType *T) {
- llvm_unreachable("Can't mangle K&R function prototypes");
+ // Function types without prototypes can arise when mangling a function type
+ // within an overloadable function in C. We mangle these as the absence of any
+ // parameter types (not even an empty parameter list).
+ Out << 'F';
+
+ FunctionTypeDepthState saved = FunctionTypeDepth.push();
+
+ FunctionTypeDepth.enterResultType();
+ mangleType(T->getReturnType());
+ FunctionTypeDepth.leaveResultType();
+
+ FunctionTypeDepth.pop(saved);
+ Out << 'E';
}
+
void CXXNameMangler::mangleBareFunctionType(const FunctionType *T,
- bool MangleReturnType) {
+ bool MangleReturnType,
+ const FunctionDecl *FD) {
// We should never be mangling something without a prototype.
const FunctionProtoType *Proto = cast<FunctionProtoType>(T);
@@ -2083,8 +2197,19 @@ void CXXNameMangler::mangleBareFunctionType(const FunctionType *T,
return;
}
- for (const auto &Arg : Proto->param_types())
- mangleType(Context.getASTContext().getSignatureParameterType(Arg));
+ assert(!FD || FD->getNumParams() == Proto->getNumParams());
+ for (unsigned I = 0, E = Proto->getNumParams(); I != E; ++I) {
+ const auto &ParamTy = Proto->getParamType(I);
+ mangleType(Context.getASTContext().getSignatureParameterType(ParamTy));
+
+ if (FD) {
+ if (auto *Attr = FD->getParamDecl(I)->getAttr<PassObjectSizeAttr>()) {
+ // Attr can only take 1 character, so we can hardcode the length below.
+ assert(Attr->getType() <= 9 && Attr->getType() >= 0);
+ Out << "U17pass_object_size" << Attr->getType();
+ }
+ }
+ }
FunctionTypeDepth.pop(saved);
@@ -2325,7 +2450,7 @@ void CXXNameMangler::mangleAArch64NeonVectorType(const VectorType *T) {
EltName = mangleAArch64VectorBase(cast<BuiltinType>(EltType));
std::string TypeName =
- ("__" + EltName + "x" + llvm::utostr(T->getNumElements()) + "_t").str();
+ ("__" + EltName + "x" + Twine(T->getNumElements()) + "_t").str();
Out << TypeName.length() << TypeName;
}
@@ -2392,7 +2517,6 @@ void CXXNameMangler::mangleType(const ObjCObjectType *T) {
StringRef name = I->getName();
QualOS << name.size() << name;
}
- QualOS.flush();
Out << 'U' << QualStr.size() << QualStr;
}
@@ -2543,9 +2667,11 @@ void CXXNameMangler::mangleType(const UnaryTransformType *T) {
void CXXNameMangler::mangleType(const AutoType *T) {
QualType D = T->getDeducedType();
// <builtin-type> ::= Da # dependent auto
- if (D.isNull())
+ if (D.isNull()) {
+ assert(T->getKeyword() != AutoTypeKeyword::GNUAutoType &&
+ "shouldn't need to mangle __auto_type!");
Out << (T->isDecltypeAuto() ? "Dc" : "Da");
- else
+ } else
mangleType(D);
}
@@ -2699,7 +2825,9 @@ recurse:
case Expr::ParenListExprClass:
case Expr::LambdaExprClass:
case Expr::MSPropertyRefExprClass:
+ case Expr::MSPropertySubscriptExprClass:
case Expr::TypoExprClass: // This should no longer exist in the AST by now.
+ case Expr::OMPArraySectionExprClass:
llvm_unreachable("unexpected statement kind");
// FIXME: invent manglings for all these.
@@ -2908,7 +3036,7 @@ recurse:
ME->isArrow(), ME->getQualifier(), nullptr,
ME->getMemberName(), Arity);
if (ME->hasExplicitTemplateArgs())
- mangleTemplateArgs(ME->getExplicitTemplateArgs());
+ mangleTemplateArgs(ME->getTemplateArgs(), ME->getNumTemplateArgs());
break;
}
@@ -2920,7 +3048,7 @@ recurse:
ME->getFirstQualifierFoundInScope(),
ME->getMember(), Arity);
if (ME->hasExplicitTemplateArgs())
- mangleTemplateArgs(ME->getExplicitTemplateArgs());
+ mangleTemplateArgs(ME->getTemplateArgs(), ME->getNumTemplateArgs());
break;
}
@@ -2932,7 +3060,7 @@ recurse:
// base-unresolved-name, where <template-args> are just tacked
// onto the end.
if (ULE->hasExplicitTemplateArgs())
- mangleTemplateArgs(ULE->getExplicitTemplateArgs());
+ mangleTemplateArgs(ULE->getTemplateArgs(), ULE->getNumTemplateArgs());
break;
}
@@ -3254,7 +3382,7 @@ recurse:
// base-unresolved-name, where <template-args> are just tacked
// onto the end.
if (DRE->hasExplicitTemplateArgs())
- mangleTemplateArgs(DRE->getExplicitTemplateArgs());
+ mangleTemplateArgs(DRE->getTemplateArgs(), DRE->getNumTemplateArgs());
break;
}
@@ -3350,8 +3478,17 @@ recurse:
break;
case Expr::SizeOfPackExprClass: {
+ auto *SPE = cast<SizeOfPackExpr>(E);
+ if (SPE->isPartiallySubstituted()) {
+ Out << "sP";
+ for (const auto &A : SPE->getPartialArguments())
+ mangleTemplateArg(A);
+ Out << "E";
+ break;
+ }
+
Out << "sZ";
- const NamedDecl *Pack = cast<SizeOfPackExpr>(E)->getPack();
+ const NamedDecl *Pack = SPE->getPack();
if (const TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Pack))
mangleTemplateParameter(TTP->getIndex());
else if (const NonTypeTemplateParmDecl *NTTP
@@ -3394,6 +3531,18 @@ recurse:
case Expr::CXXThisExprClass:
Out << "fpT";
break;
+
+ case Expr::CoawaitExprClass:
+ // FIXME: Propose a non-vendor mangling.
+ Out << "v18co_await";
+ mangleExpression(cast<CoawaitExpr>(E)->getOperand());
+ break;
+
+ case Expr::CoyieldExprClass:
+ // FIXME: Propose a non-vendor mangling.
+ Out << "v18co_yield";
+ mangleExpression(cast<CoawaitExpr>(E)->getOperand());
+ break;
}
}
@@ -3501,12 +3650,12 @@ void CXXNameMangler::mangleCXXDtorType(CXXDtorType T) {
}
}
-void CXXNameMangler::mangleTemplateArgs(
- const ASTTemplateArgumentListInfo &TemplateArgs) {
+void CXXNameMangler::mangleTemplateArgs(const TemplateArgumentLoc *TemplateArgs,
+ unsigned NumTemplateArgs) {
// <template-args> ::= I <template-arg>+ E
Out << 'I';
- for (unsigned i = 0, e = TemplateArgs.NumTemplateArgs; i != e; ++i)
- mangleTemplateArg(TemplateArgs.getTemplateArgs()[i].getArgument());
+ for (unsigned i = 0; i != NumTemplateArgs; ++i)
+ mangleTemplateArg(TemplateArgs[i].getArgument());
Out << 'E';
}
@@ -4085,21 +4234,6 @@ void ItaniumMangleContextImpl::mangleTypeName(QualType Ty, raw_ostream &Out) {
mangleCXXRTTIName(Ty, Out);
}
-void ItaniumMangleContextImpl::mangleCXXVTableBitSet(const CXXRecordDecl *RD,
- raw_ostream &Out) {
- if (!RD->isExternallyVisible()) {
- // This part of the identifier needs to be unique across all translation
- // units in the linked program. The scheme fails if multiple translation
- // units are compiled using the same relative source file path, or if
- // multiple translation units are built from the same source file.
- SourceManager &SM = getASTContext().getSourceManager();
- Out << "[" << SM.getFileEntryForID(SM.getMainFileID())->getName() << "]";
- }
-
- CXXNameMangler Mangler(*this, Out);
- Mangler.mangleType(QualType(RD->getTypeForDecl(), 0));
-}
-
void ItaniumMangleContextImpl::mangleStringLiteral(const StringLiteral *, raw_ostream &) {
llvm_unreachable("Can't mangle string literals");
}
@@ -4108,4 +4242,3 @@ ItaniumMangleContext *
ItaniumMangleContext::create(ASTContext &Context, DiagnosticsEngine &Diags) {
return new ItaniumMangleContextImpl(Context, Diags);
}
-
diff --git a/lib/AST/Mangle.cpp b/lib/AST/Mangle.cpp
index 1a061c4f6632..014338f0490f 100644
--- a/lib/AST/Mangle.cpp
+++ b/lib/AST/Mangle.cpp
@@ -206,7 +206,6 @@ void MangleContext::mangleCtorBlock(const CXXConstructorDecl *CD,
SmallString<64> Buffer;
llvm::raw_svector_ostream Out(Buffer);
mangleCXXCtor(CD, CT, Out);
- Out.flush();
mangleFunctionBlock(*this, Buffer, BD, ResStream);
}
@@ -216,7 +215,6 @@ void MangleContext::mangleDtorBlock(const CXXDestructorDecl *DD,
SmallString<64> Buffer;
llvm::raw_svector_ostream Out(Buffer);
mangleCXXDtor(DD, DT, Out);
- Out.flush();
mangleFunctionBlock(*this, Buffer, BD, ResStream);
}
@@ -253,7 +251,6 @@ void MangleContext::mangleBlock(const DeclContext *DC, const BlockDecl *BD,
}
}
}
- Stream.flush();
mangleFunctionBlock(*this, Buffer, BD, Out);
}
diff --git a/lib/AST/MicrosoftCXXABI.cpp b/lib/AST/MicrosoftCXXABI.cpp
index aba6796256a7..6ba31ccf1e37 100644
--- a/lib/AST/MicrosoftCXXABI.cpp
+++ b/lib/AST/MicrosoftCXXABI.cpp
@@ -70,6 +70,11 @@ class MicrosoftCXXABI : public CXXABI {
llvm::SmallDenseMap<std::pair<const CXXConstructorDecl *, unsigned>, Expr *>
CtorToDefaultArgExpr;
+ llvm::SmallDenseMap<TagDecl *, DeclaratorDecl *>
+ UnnamedTagDeclToDeclaratorDecl;
+ llvm::SmallDenseMap<TagDecl *, TypedefNameDecl *>
+ UnnamedTagDeclToTypedefNameDecl;
+
public:
MicrosoftCXXABI(ASTContext &Ctx) : Context(Ctx) { }
@@ -84,17 +89,7 @@ public:
}
bool isNearlyEmpty(const CXXRecordDecl *RD) const override {
- // FIXME: Audit the corners
- if (!RD->isDynamicClass())
- return false;
-
- const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
-
- // In the Microsoft ABI, classes can have one or two vtable pointers.
- CharUnits PointerSize =
- Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0));
- return Layout.getNonVirtualSize() == PointerSize ||
- Layout.getNonVirtualSize() == PointerSize * 2;
+ llvm_unreachable("unapplicable to the MS ABI");
}
void addDefaultArgExprForConstructor(const CXXConstructorDecl *CD,
@@ -120,6 +115,34 @@ public:
RecordToCopyCtor[RD] = CD;
}
+ void addTypedefNameForUnnamedTagDecl(TagDecl *TD,
+ TypedefNameDecl *DD) override {
+ TD = TD->getCanonicalDecl();
+ DD = cast<TypedefNameDecl>(DD->getCanonicalDecl());
+ TypedefNameDecl *&I = UnnamedTagDeclToTypedefNameDecl[TD];
+ if (!I)
+ I = DD;
+ }
+
+ TypedefNameDecl *getTypedefNameForUnnamedTagDecl(const TagDecl *TD) override {
+ return UnnamedTagDeclToTypedefNameDecl.lookup(
+ const_cast<TagDecl *>(TD->getCanonicalDecl()));
+ }
+
+ void addDeclaratorForUnnamedTagDecl(TagDecl *TD,
+ DeclaratorDecl *DD) override {
+ TD = TD->getCanonicalDecl();
+ DD = cast<DeclaratorDecl>(DD->getCanonicalDecl());
+ DeclaratorDecl *&I = UnnamedTagDeclToDeclaratorDecl[TD];
+ if (!I)
+ I = DD;
+ }
+
+ DeclaratorDecl *getDeclaratorForUnnamedTagDecl(const TagDecl *TD) override {
+ return UnnamedTagDeclToDeclaratorDecl.lookup(
+ const_cast<TagDecl *>(TD->getCanonicalDecl()));
+ }
+
MangleNumberingContext *createMangleNumberingContext() const override {
return new MicrosoftNumberingContext();
}
diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp
index 48a8fa541a69..136a43b640f7 100644
--- a/lib/AST/MicrosoftMangle.cpp
+++ b/lib/AST/MicrosoftMangle.cpp
@@ -28,6 +28,7 @@
#include "clang/Basic/TargetInfo.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/JamCRC.h"
using namespace clang;
@@ -160,8 +161,6 @@ public:
void mangleSEHFinallyBlock(const NamedDecl *EnclosingDecl,
raw_ostream &Out) override;
void mangleStringLiteral(const StringLiteral *SL, raw_ostream &Out) override;
- void mangleCXXVTableBitSet(const CXXRecordDecl *RD,
- raw_ostream &Out) override;
bool getNextDiscriminator(const NamedDecl *ND, unsigned &disc) {
// Lambda closure types are already numbered.
if (isLambda(ND))
@@ -179,7 +178,9 @@ public:
// Anonymous tags are already numbered.
if (const TagDecl *Tag = dyn_cast<TagDecl>(ND)) {
- if (Tag->getName().empty() && !Tag->getTypedefNameForAnonDecl())
+ if (!Tag->hasNameForLinkage() &&
+ !getASTContext().getDeclaratorForUnnamedTagDecl(Tag) &&
+ !getASTContext().getTypedefNameForUnnamedTagDecl(Tag))
return false;
}
@@ -223,6 +224,9 @@ class MicrosoftCXXNameMangler {
typedef llvm::DenseMap<void *, unsigned> ArgBackRefMap;
ArgBackRefMap TypeBackReferences;
+ typedef std::set<int> PassObjectSizeArgsSet;
+ PassObjectSizeArgsSet PassObjectSizeArgs;
+
ASTContext &getASTContext() const { return Context.getASTContext(); }
// FIXME: If we add support for __ptr32/64 qualifiers, then we should push
@@ -262,6 +266,9 @@ public:
const CXXMethodDecl *MD,
const MicrosoftVTableContext::MethodVFTableLocation &ML);
void mangleNumber(int64_t Number);
+ void mangleTagTypeKind(TagTypeKind TK);
+ void mangleArtificalTagType(TagTypeKind TK, StringRef UnqualifiedName,
+ ArrayRef<StringRef> NestedNames = None);
void mangleType(QualType T, SourceRange Range,
QualifierMangleMode QMM = QMM_Mangle);
void mangleFunctionType(const FunctionType *T,
@@ -289,6 +296,7 @@ private:
void mangleObjCMethodName(const ObjCMethodDecl *MD);
void mangleArgumentType(QualType T, SourceRange Range);
+ void manglePassObjectSizeArg(const PassObjectSizeAttr *POSA);
// Declare manglers for every type class.
#define ABSTRACT_TYPE(CLASS, PARENT)
@@ -364,7 +372,8 @@ bool MicrosoftMangleContextImpl::shouldMangleCXXName(const NamedDecl *D) {
DC = getEffectiveParentContext(DC);
if (DC->isTranslationUnit() && D->getFormalLinkage() == InternalLinkage &&
- !isa<VarTemplateSpecializationDecl>(D))
+ !isa<VarTemplateSpecializationDecl>(D) &&
+ D->getIdentifier() != nullptr)
return false;
}
@@ -390,14 +399,8 @@ void MicrosoftCXXNameMangler::mangle(const NamedDecl *D, StringRef Prefix) {
mangleFunctionEncoding(FD, Context.shouldMangleDeclName(FD));
else if (const VarDecl *VD = dyn_cast<VarDecl>(D))
mangleVariableEncoding(VD);
- else {
- // TODO: Fields? Can MSVC even mangle them?
- // Issue a diagnostic for now.
- DiagnosticsEngine &Diags = Context.getDiags();
- unsigned DiagID = Diags.getCustomDiagID(
- DiagnosticsEngine::Error, "cannot mangle this declaration yet");
- Diags.Report(D->getLocation(), DiagID) << D->getSourceRange();
- }
+ else
+ llvm_unreachable("Tried to mangle unexpected NamedDecl!");
}
void MicrosoftCXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD,
@@ -420,7 +423,7 @@ void MicrosoftCXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD,
// We would like to mangle all extern "C" functions using this additional
// component but this would break compatibility with MSVC's behavior.
// Instead, do this when we know that compatibility isn't important (in
- // other words, when it is an overloaded extern "C" funciton).
+ // other words, when it is an overloaded extern "C" function).
if (FD->isExternC() && FD->hasAttr<OverloadableAttr>())
Out << "$$J0";
@@ -695,8 +698,7 @@ void MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
// Function templates aren't considered for name back referencing. This
// makes sense since function templates aren't likely to occur multiple
// times in a symbol.
- // FIXME: Test alias template mangling with MSVC 2013.
- if (!isa<ClassTemplateDecl>(TD)) {
+ if (isa<FunctionTemplateDecl>(TD)) {
mangleTemplateInstantiationName(TD, *TemplateArgs);
Out << '@';
return;
@@ -721,7 +723,6 @@ void MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
llvm::raw_svector_ostream Stream(TemplateMangling);
MicrosoftCXXNameMangler Extra(Context, Stream);
Extra.mangleTemplateInstantiationName(TD, *TemplateArgs);
- Stream.flush();
mangleSourceName(TemplateMangling);
return;
@@ -787,14 +788,21 @@ void MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
}
llvm::SmallString<64> Name("<unnamed-type-");
- if (TD->hasDeclaratorForAnonDecl()) {
- // Anonymous types with no tag or typedef get the name of their
+ if (DeclaratorDecl *DD =
+ Context.getASTContext().getDeclaratorForUnnamedTagDecl(TD)) {
+ // Anonymous types without a name for linkage purposes have their
// declarator mangled in if they have one.
- Name += TD->getDeclaratorForAnonDecl()->getName();
+ Name += DD->getName();
+ } else if (TypedefNameDecl *TND =
+ Context.getASTContext().getTypedefNameForUnnamedTagDecl(
+ TD)) {
+ // Anonymous types without a name for linkage purposes have their
+ // associate typedef mangled in if they have one.
+ Name += TND->getName();
} else {
// Otherwise, number the types using a $S prefix.
Name += "$S";
- Name += llvm::utostr(Context.getAnonymousStructId(TD));
+ Name += llvm::utostr(Context.getAnonymousStructId(TD) + 1);
}
Name += ">";
mangleSourceName(Name.str());
@@ -1039,6 +1047,14 @@ void MicrosoftCXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO,
break;
}
+ case OO_Coawait: {
+ DiagnosticsEngine &Diags = Context.getDiags();
+ unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
+ "cannot mangle this operator co_await yet");
+ Diags.Report(Loc, DiagID);
+ break;
+ }
+
case OO_None:
case NUM_OVERLOADED_OPERATORS:
llvm_unreachable("Not an overloaded operator");
@@ -1071,8 +1087,10 @@ void MicrosoftCXXNameMangler::mangleTemplateInstantiationName(
// Templates have their own context for back references.
ArgBackRefMap OuterArgsContext;
BackRefVec OuterTemplateContext;
+ PassObjectSizeArgsSet OuterPassObjectSizeArgs;
NameBackReferences.swap(OuterTemplateContext);
TypeBackReferences.swap(OuterArgsContext);
+ PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
mangleUnscopedTemplateName(TD);
mangleTemplateArgs(TD, TemplateArgs);
@@ -1080,6 +1098,7 @@ void MicrosoftCXXNameMangler::mangleTemplateInstantiationName(
// Restore the previous back reference contexts.
NameBackReferences.swap(OuterTemplateContext);
TypeBackReferences.swap(OuterArgsContext);
+ PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
}
void
@@ -1121,12 +1140,6 @@ void MicrosoftCXXNameMangler::mangleExpression(const Expr *E) {
UE = dyn_cast<CXXUuidofExpr>(E);
if (UE) {
- // This CXXUuidofExpr is mangled as-if it were actually a VarDecl from
- // const __s_GUID _GUID_{lower case UUID with underscores}
- StringRef Uuid = UE->getUuidAsStringRef(Context.getASTContext());
- std::string Name = "_GUID_" + Uuid.lower();
- std::replace(Name.begin(), Name.end(), '-', '_');
-
// If we had to peek through an address-of operator, treat this like we are
// dealing with a pointer type. Otherwise, treat it like a const reference.
//
@@ -1136,7 +1149,22 @@ void MicrosoftCXXNameMangler::mangleExpression(const Expr *E) {
Out << "$E?";
else
Out << "$1?";
- Out << Name << "@@3U__s_GUID@@B";
+
+ // This CXXUuidofExpr is mangled as-if it were actually a VarDecl from
+ // const __s_GUID _GUID_{lower case UUID with underscores}
+ StringRef Uuid = UE->getUuidAsStringRef(Context.getASTContext());
+ std::string Name = "_GUID_" + Uuid.lower();
+ std::replace(Name.begin(), Name.end(), '-', '_');
+
+ mangleSourceName(Name);
+ // Terminate the whole name with an '@'.
+ Out << '@';
+ // It's a global variable.
+ Out << '3';
+ // It's a struct called __s_GUID.
+ mangleArtificalTagType(TTK_Struct, "__s_GUID");
+ // It's const.
+ Out << 'B';
return;
}
@@ -1210,12 +1238,13 @@ void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
QualType T = TA.getNullPtrType();
if (const MemberPointerType *MPT = T->getAs<MemberPointerType>()) {
const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
- if (MPT->isMemberFunctionPointerType() && isa<ClassTemplateDecl>(TD)) {
+ if (MPT->isMemberFunctionPointerType() &&
+ !isa<FunctionTemplateDecl>(TD)) {
mangleMemberFunctionPointer(RD, nullptr);
return;
}
if (MPT->isMemberDataPointer()) {
- if (isa<ClassTemplateDecl>(TD)) {
+ if (!isa<FunctionTemplateDecl>(TD)) {
mangleMemberDataPointer(RD, nullptr);
return;
}
@@ -1455,6 +1484,27 @@ void MicrosoftCXXNameMangler::mangleArgumentType(QualType T,
}
}
+void MicrosoftCXXNameMangler::manglePassObjectSizeArg(
+ const PassObjectSizeAttr *POSA) {
+ int Type = POSA->getType();
+
+ auto Iter = PassObjectSizeArgs.insert(Type).first;
+ void *TypePtr = (void *)&*Iter;
+ ArgBackRefMap::iterator Found = TypeBackReferences.find(TypePtr);
+
+ if (Found == TypeBackReferences.end()) {
+ mangleArtificalTagType(TTK_Enum, "__pass_object_size" + llvm::utostr(Type),
+ {"__clang"});
+
+ if (TypeBackReferences.size() < 10) {
+ size_t Size = TypeBackReferences.size();
+ TypeBackReferences[TypePtr] = Size;
+ }
+ } else {
+ Out << Found->second;
+ }
+}
+
void MicrosoftCXXNameMangler::mangleType(QualType T, SourceRange Range,
QualifierMangleMode QMM) {
// Don't use the canonical types. MSVC includes things like 'const' on
@@ -1546,29 +1596,72 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers,
// ::= _W # wchar_t
// ::= _Z # __float80 (Digital Mars)
switch (T->getKind()) {
- case BuiltinType::Void: Out << 'X'; break;
- case BuiltinType::SChar: Out << 'C'; break;
- case BuiltinType::Char_U: case BuiltinType::Char_S: Out << 'D'; break;
- case BuiltinType::UChar: Out << 'E'; break;
- case BuiltinType::Short: Out << 'F'; break;
- case BuiltinType::UShort: Out << 'G'; break;
- case BuiltinType::Int: Out << 'H'; break;
- case BuiltinType::UInt: Out << 'I'; break;
- case BuiltinType::Long: Out << 'J'; break;
- case BuiltinType::ULong: Out << 'K'; break;
- case BuiltinType::Float: Out << 'M'; break;
- case BuiltinType::Double: Out << 'N'; break;
+ case BuiltinType::Void:
+ Out << 'X';
+ break;
+ case BuiltinType::SChar:
+ Out << 'C';
+ break;
+ case BuiltinType::Char_U:
+ case BuiltinType::Char_S:
+ Out << 'D';
+ break;
+ case BuiltinType::UChar:
+ Out << 'E';
+ break;
+ case BuiltinType::Short:
+ Out << 'F';
+ break;
+ case BuiltinType::UShort:
+ Out << 'G';
+ break;
+ case BuiltinType::Int:
+ Out << 'H';
+ break;
+ case BuiltinType::UInt:
+ Out << 'I';
+ break;
+ case BuiltinType::Long:
+ Out << 'J';
+ break;
+ case BuiltinType::ULong:
+ Out << 'K';
+ break;
+ case BuiltinType::Float:
+ Out << 'M';
+ break;
+ case BuiltinType::Double:
+ Out << 'N';
+ break;
// TODO: Determine size and mangle accordingly
- case BuiltinType::LongDouble: Out << 'O'; break;
- case BuiltinType::LongLong: Out << "_J"; break;
- case BuiltinType::ULongLong: Out << "_K"; break;
- case BuiltinType::Int128: Out << "_L"; break;
- case BuiltinType::UInt128: Out << "_M"; break;
- case BuiltinType::Bool: Out << "_N"; break;
- case BuiltinType::Char16: Out << "_S"; break;
- case BuiltinType::Char32: Out << "_U"; break;
+ case BuiltinType::LongDouble:
+ Out << 'O';
+ break;
+ case BuiltinType::LongLong:
+ Out << "_J";
+ break;
+ case BuiltinType::ULongLong:
+ Out << "_K";
+ break;
+ case BuiltinType::Int128:
+ Out << "_L";
+ break;
+ case BuiltinType::UInt128:
+ Out << "_M";
+ break;
+ case BuiltinType::Bool:
+ Out << "_N";
+ break;
+ case BuiltinType::Char16:
+ Out << "_S";
+ break;
+ case BuiltinType::Char32:
+ Out << "_U";
+ break;
case BuiltinType::WChar_S:
- case BuiltinType::WChar_U: Out << "_W"; break;
+ case BuiltinType::WChar_U:
+ Out << "_W";
+ break;
#define BUILTIN_TYPE(Id, SingletonId)
#define PLACEHOLDER_TYPE(Id, SingletonId) \
@@ -1577,28 +1670,102 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers,
case BuiltinType::Dependent:
llvm_unreachable("placeholder types shouldn't get to name mangling");
- case BuiltinType::ObjCId: Out << "PAUobjc_object@@"; break;
- case BuiltinType::ObjCClass: Out << "PAUobjc_class@@"; break;
- case BuiltinType::ObjCSel: Out << "PAUobjc_selector@@"; break;
+ case BuiltinType::ObjCId:
+ Out << "PA";
+ mangleArtificalTagType(TTK_Struct, "objc_object");
+ break;
+ case BuiltinType::ObjCClass:
+ Out << "PA";
+ mangleArtificalTagType(TTK_Struct, "objc_class");
+ break;
+ case BuiltinType::ObjCSel:
+ Out << "PA";
+ mangleArtificalTagType(TTK_Struct, "objc_selector");
+ break;
- case BuiltinType::OCLImage1d: Out << "PAUocl_image1d@@"; break;
- case BuiltinType::OCLImage1dArray: Out << "PAUocl_image1darray@@"; break;
- case BuiltinType::OCLImage1dBuffer: Out << "PAUocl_image1dbuffer@@"; break;
- case BuiltinType::OCLImage2d: Out << "PAUocl_image2d@@"; break;
- case BuiltinType::OCLImage2dArray: Out << "PAUocl_image2darray@@"; break;
- case BuiltinType::OCLImage3d: Out << "PAUocl_image3d@@"; break;
- case BuiltinType::OCLSampler: Out << "PAUocl_sampler@@"; break;
- case BuiltinType::OCLEvent: Out << "PAUocl_event@@"; break;
+ case BuiltinType::OCLImage1d:
+ Out << "PA";
+ mangleArtificalTagType(TTK_Struct, "ocl_image1d");
+ break;
+ case BuiltinType::OCLImage1dArray:
+ Out << "PA";
+ mangleArtificalTagType(TTK_Struct, "ocl_image1darray");
+ break;
+ case BuiltinType::OCLImage1dBuffer:
+ Out << "PA";
+ mangleArtificalTagType(TTK_Struct, "ocl_image1dbuffer");
+ break;
+ case BuiltinType::OCLImage2d:
+ Out << "PA";
+ mangleArtificalTagType(TTK_Struct, "ocl_image2d");
+ break;
+ case BuiltinType::OCLImage2dArray:
+ Out << "PA";
+ mangleArtificalTagType(TTK_Struct, "ocl_image2darray");
+ break;
+ case BuiltinType::OCLImage2dDepth:
+ Out << "PA";
+ mangleArtificalTagType(TTK_Struct, "ocl_image2ddepth");
+ break;
+ case BuiltinType::OCLImage2dArrayDepth:
+ Out << "PA";
+ mangleArtificalTagType(TTK_Struct, "ocl_image2darraydepth");
+ break;
+ case BuiltinType::OCLImage2dMSAA:
+ Out << "PA";
+ mangleArtificalTagType(TTK_Struct, "ocl_image2dmsaa");
+ break;
+ case BuiltinType::OCLImage2dArrayMSAA:
+ Out << "PA";
+ mangleArtificalTagType(TTK_Struct, "ocl_image2darraymsaa");
+ break;
+ case BuiltinType::OCLImage2dMSAADepth:
+ Out << "PA";
+ mangleArtificalTagType(TTK_Struct, "ocl_image2dmsaadepth");
+ break;
+ case BuiltinType::OCLImage2dArrayMSAADepth:
+ Out << "PA";
+ mangleArtificalTagType(TTK_Struct, "ocl_image2darraymsaadepth");
+ break;
+ case BuiltinType::OCLImage3d:
+ Out << "PA";
+ mangleArtificalTagType(TTK_Struct, "ocl_image3d");
+ break;
+ case BuiltinType::OCLSampler:
+ Out << "PA";
+ mangleArtificalTagType(TTK_Struct, "ocl_sampler");
+ break;
+ case BuiltinType::OCLEvent:
+ Out << "PA";
+ mangleArtificalTagType(TTK_Struct, "ocl_event");
+ break;
+ case BuiltinType::OCLClkEvent:
+ Out << "PA";
+ mangleArtificalTagType(TTK_Struct, "ocl_clkevent");
+ break;
+ case BuiltinType::OCLQueue:
+ Out << "PA";
+ mangleArtificalTagType(TTK_Struct, "ocl_queue");
+ break;
+ case BuiltinType::OCLNDRange:
+ Out << "PA";
+ mangleArtificalTagType(TTK_Struct, "ocl_ndrange");
+ break;
+ case BuiltinType::OCLReserveID:
+ Out << "PA";
+ mangleArtificalTagType(TTK_Struct, "ocl_reserveid");
+ break;
- case BuiltinType::NullPtr: Out << "$$T"; break;
+ case BuiltinType::NullPtr:
+ Out << "$$T";
+ break;
case BuiltinType::Half: {
DiagnosticsEngine &Diags = Context.getDiags();
- unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
- "cannot mangle this built-in %0 type yet");
+ unsigned DiagID = Diags.getCustomDiagID(
+ DiagnosticsEngine::Error, "cannot mangle this built-in %0 type yet");
Diags.Report(Range.getBegin(), DiagID)
- << T->getName(Context.getASTContext().getPrintingPolicy())
- << Range;
+ << T->getName(Context.getASTContext().getPrintingPolicy()) << Range;
break;
}
}
@@ -1620,7 +1787,8 @@ void MicrosoftCXXNameMangler::mangleType(const FunctionProtoType *T, Qualifiers,
}
void MicrosoftCXXNameMangler::mangleType(const FunctionNoProtoType *T,
Qualifiers, SourceRange) {
- llvm_unreachable("Can't mangle K&R function prototypes");
+ Out << "$$A6";
+ mangleFunctionType(T);
}
void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T,
@@ -1628,7 +1796,7 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T,
bool ForceThisQuals) {
// <function-type> ::= <this-cvr-qualifiers> <calling-convention>
// <return-type> <argument-list> <throw-spec>
- const FunctionProtoType *Proto = cast<FunctionProtoType>(T);
+ const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(T);
SourceRange Range;
if (D) Range = D->getSourceRange();
@@ -1699,12 +1867,14 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T,
}
Out << '@';
} else {
- QualType ResultType = Proto->getReturnType();
+ QualType ResultType = T->getReturnType();
if (const auto *AT =
dyn_cast_or_null<AutoType>(ResultType->getContainedAutoType())) {
Out << '?';
mangleQualifiers(ResultType.getLocalQualifiers(), /*IsMember=*/false);
Out << '?';
+ assert(AT->getKeyword() != AutoTypeKeyword::GNUAutoType &&
+ "shouldn't need to mangle __auto_type!");
mangleSourceName(AT->isDecltypeAuto() ? "<decltype-auto>" : "<auto>");
Out << '@';
} else {
@@ -1717,12 +1887,29 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T,
// <argument-list> ::= X # void
// ::= <type>+ @
// ::= <type>* Z # varargs
- if (Proto->getNumParams() == 0 && !Proto->isVariadic()) {
+ if (!Proto) {
+ // Function types without prototypes can arise when mangling a function type
+ // within an overloadable function in C. We mangle these as the absence of
+ // any parameter types (not even an empty parameter list).
+ Out << '@';
+ } else if (Proto->getNumParams() == 0 && !Proto->isVariadic()) {
Out << 'X';
} else {
// Happens for function pointer type arguments for example.
- for (const QualType &Arg : Proto->param_types())
- mangleArgumentType(Arg, Range);
+ for (unsigned I = 0, E = Proto->getNumParams(); I != E; ++I) {
+ mangleArgumentType(Proto->getParamType(I), Range);
+ // Mangle each pass_object_size parameter as if it's a paramater of enum
+ // type passed directly after the parameter with the pass_object_size
+ // attribute. The aforementioned enum's name is __pass_object_size, and we
+ // pretend it resides in a top-level namespace called __clang.
+ //
+ // FIXME: Is there a defined extension notation for the MS ABI, or is it
+ // necessary to just cross our fingers and hope this type+namespace
+ // combination doesn't conflict with anything?
+ if (D)
+ if (const auto *P = D->getParamDecl(I)->getAttr<PassObjectSizeAttr>())
+ manglePassObjectSizeArg(P);
+ }
// <builtin-type> ::= Z # ellipsis
if (Proto->isVariadic())
Out << 'Z';
@@ -1851,16 +2038,8 @@ void MicrosoftCXXNameMangler::mangleType(const UnresolvedUsingType *T,
// <struct-type> ::= U <name>
// <class-type> ::= V <name>
// <enum-type> ::= W4 <name>
-void MicrosoftCXXNameMangler::mangleType(const EnumType *T, Qualifiers,
- SourceRange) {
- mangleType(cast<TagType>(T)->getDecl());
-}
-void MicrosoftCXXNameMangler::mangleType(const RecordType *T, Qualifiers,
- SourceRange) {
- mangleType(cast<TagType>(T)->getDecl());
-}
-void MicrosoftCXXNameMangler::mangleType(const TagDecl *TD) {
- switch (TD->getTagKind()) {
+void MicrosoftCXXNameMangler::mangleTagTypeKind(TagTypeKind TTK) {
+ switch (TTK) {
case TTK_Union:
Out << 'T';
break;
@@ -1875,8 +2054,33 @@ void MicrosoftCXXNameMangler::mangleType(const TagDecl *TD) {
Out << "W4";
break;
}
+}
+void MicrosoftCXXNameMangler::mangleType(const EnumType *T, Qualifiers,
+ SourceRange) {
+ mangleType(cast<TagType>(T)->getDecl());
+}
+void MicrosoftCXXNameMangler::mangleType(const RecordType *T, Qualifiers,
+ SourceRange) {
+ mangleType(cast<TagType>(T)->getDecl());
+}
+void MicrosoftCXXNameMangler::mangleType(const TagDecl *TD) {
+ mangleTagTypeKind(TD->getTagKind());
mangleName(TD);
}
+void MicrosoftCXXNameMangler::mangleArtificalTagType(
+ TagTypeKind TK, StringRef UnqualifiedName, ArrayRef<StringRef> NestedNames) {
+ // <name> ::= <unscoped-name> {[<named-scope>]+ | [<nested-name>]}? @
+ mangleTagTypeKind(TK);
+
+ // Always start with the unqualified name.
+ mangleSourceName(UnqualifiedName);
+
+ for (auto I = NestedNames.rbegin(), E = NestedNames.rend(); I != E; ++I)
+ mangleSourceName(*I);
+
+ // Terminate the whole name with an '@'.
+ Out << '@';
+}
// <type> ::= <array-type>
// <array-type> ::= <pointer-cvr-qualifiers> <cvr-qualifiers>
@@ -2029,11 +2233,16 @@ void MicrosoftCXXNameMangler::mangleType(const RValueReferenceType *T,
void MicrosoftCXXNameMangler::mangleType(const ComplexType *T, Qualifiers,
SourceRange Range) {
- DiagnosticsEngine &Diags = Context.getDiags();
- unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
- "cannot mangle this complex number type yet");
- Diags.Report(Range.getBegin(), DiagID)
- << Range;
+ QualType ElementType = T->getElementType();
+
+ llvm::SmallString<64> TemplateMangling;
+ llvm::raw_svector_ostream Stream(TemplateMangling);
+ MicrosoftCXXNameMangler Extra(Context, Stream);
+ Stream << "?$";
+ Extra.mangleSourceName("_Complex");
+ Extra.mangleType(ElementType, Range, QMM_Escape);
+
+ mangleArtificalTagType(TTK_Struct, TemplateMangling, {"__clang"});
}
void MicrosoftCXXNameMangler::mangleType(const VectorType *T, Qualifiers Quals,
@@ -2043,46 +2252,44 @@ void MicrosoftCXXNameMangler::mangleType(const VectorType *T, Qualifiers Quals,
uint64_t Width = getASTContext().getTypeSize(T);
// Pattern match exactly the typedefs in our intrinsic headers. Anything that
// doesn't match the Intel types uses a custom mangling below.
- bool IsBuiltin = true;
+ size_t OutSizeBefore = Out.tell();
llvm::Triple::ArchType AT =
getASTContext().getTargetInfo().getTriple().getArch();
if (AT == llvm::Triple::x86 || AT == llvm::Triple::x86_64) {
if (Width == 64 && ET->getKind() == BuiltinType::LongLong) {
- Out << "T__m64";
+ mangleArtificalTagType(TTK_Union, "__m64");
} else if (Width >= 128) {
if (ET->getKind() == BuiltinType::Float)
- Out << "T__m" << Width;
+ mangleArtificalTagType(TTK_Union, "__m" + llvm::utostr(Width));
else if (ET->getKind() == BuiltinType::LongLong)
- Out << "T__m" << Width << 'i';
+ mangleArtificalTagType(TTK_Union, "__m" + llvm::utostr(Width) + 'i');
else if (ET->getKind() == BuiltinType::Double)
- Out << "U__m" << Width << 'd';
- else
- IsBuiltin = false;
- } else {
- IsBuiltin = false;
+ mangleArtificalTagType(TTK_Struct, "__m" + llvm::utostr(Width) + 'd');
}
- } else {
- IsBuiltin = false;
}
+ bool IsBuiltin = Out.tell() != OutSizeBefore;
if (!IsBuiltin) {
// The MS ABI doesn't have a special mangling for vector types, so we define
// our own mangling to handle uses of __vector_size__ on user-specified
// types, and for extensions like __v4sf.
- Out << "T__clang_vec" << T->getNumElements() << '_';
- mangleType(ET, Quals, Range);
- }
- Out << "@@";
+ llvm::SmallString<64> TemplateMangling;
+ llvm::raw_svector_ostream Stream(TemplateMangling);
+ MicrosoftCXXNameMangler Extra(Context, Stream);
+ Stream << "?$";
+ Extra.mangleSourceName("__vector");
+ Extra.mangleType(QualType(ET, 0), Range, QMM_Escape);
+ Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumElements()),
+ /*IsBoolean=*/false);
+
+ mangleArtificalTagType(TTK_Union, TemplateMangling, {"__clang"});
+ }
}
-void MicrosoftCXXNameMangler::mangleType(const ExtVectorType *T, Qualifiers,
- SourceRange Range) {
- DiagnosticsEngine &Diags = Context.getDiags();
- unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
- "cannot mangle this extended vector type yet");
- Diags.Report(Range.getBegin(), DiagID)
- << Range;
+void MicrosoftCXXNameMangler::mangleType(const ExtVectorType *T,
+ Qualifiers Quals, SourceRange Range) {
+ mangleType(static_cast<const VectorType *>(T), Quals, Range);
}
void MicrosoftCXXNameMangler::mangleType(const DependentSizedExtVectorType *T,
Qualifiers, SourceRange Range) {
@@ -2096,7 +2303,7 @@ void MicrosoftCXXNameMangler::mangleType(const DependentSizedExtVectorType *T,
void MicrosoftCXXNameMangler::mangleType(const ObjCInterfaceType *T, Qualifiers,
SourceRange) {
// ObjC interfaces have structs underlying them.
- Out << 'U';
+ mangleTagTypeKind(TTK_Struct);
mangleName(T->getDecl());
}
@@ -2209,11 +2416,16 @@ void MicrosoftCXXNameMangler::mangleType(const AutoType *T, Qualifiers,
void MicrosoftCXXNameMangler::mangleType(const AtomicType *T, Qualifiers,
SourceRange Range) {
- DiagnosticsEngine &Diags = Context.getDiags();
- unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
- "cannot mangle this C11 atomic type yet");
- Diags.Report(Range.getBegin(), DiagID)
- << Range;
+ QualType ValueType = T->getValueType();
+
+ llvm::SmallString<64> TemplateMangling;
+ llvm::raw_svector_ostream Stream(TemplateMangling);
+ MicrosoftCXXNameMangler Extra(Context, Stream);
+ Stream << "?$";
+ Extra.mangleSourceName("_Atomic");
+ Extra.mangleType(ValueType, Range, QMM_Escape);
+
+ mangleArtificalTagType(TTK_Struct, TemplateMangling, {"__clang"});
}
void MicrosoftMangleContextImpl::mangleCXXName(const NamedDecl *D,
@@ -2574,12 +2786,12 @@ void MicrosoftMangleContextImpl::mangleCXXDtor(const CXXDestructorDecl *D,
mangler.mangle(D);
}
-void MicrosoftMangleContextImpl::mangleReferenceTemporary(const VarDecl *VD,
- unsigned,
- raw_ostream &) {
- unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error,
- "cannot mangle this reference temporary yet");
- getDiags().Report(VD->getLocation(), DiagID);
+void MicrosoftMangleContextImpl::mangleReferenceTemporary(
+ const VarDecl *VD, unsigned ManglingNumber, raw_ostream &Out) {
+ MicrosoftCXXNameMangler Mangler(*this, Out);
+
+ Mangler.getStream() << "\01?$RT" << ManglingNumber << '@';
+ Mangler.mangle(VD, "");
}
void MicrosoftMangleContextImpl::mangleThreadSafeStaticGuardVariable(
@@ -2688,28 +2900,6 @@ void MicrosoftMangleContextImpl::mangleStringLiteral(const StringLiteral *SL,
// N.B. The length is in terms of bytes, not characters.
Mangler.mangleNumber(SL->getByteLength() + SL->getCharByteWidth());
- // We will use the "Rocksoft^tm Model CRC Algorithm" to describe the
- // properties of our CRC:
- // Width : 32
- // Poly : 04C11DB7
- // Init : FFFFFFFF
- // RefIn : True
- // RefOut : True
- // XorOut : 00000000
- // Check : 340BC6D9
- uint32_t CRC = 0xFFFFFFFFU;
-
- auto UpdateCRC = [&CRC](char Byte) {
- for (unsigned i = 0; i < 8; ++i) {
- bool Bit = CRC & 0x80000000U;
- if (Byte & (1U << i))
- Bit = !Bit;
- CRC <<= 1;
- if (Bit)
- CRC ^= 0x04C11DB7U;
- }
- };
-
auto GetLittleEndianByte = [&Mangler, &SL](unsigned Index) {
unsigned CharByteWidth = SL->getCharByteWidth();
uint32_t CodeUnit = SL->getCodeUnit(Index / CharByteWidth);
@@ -2725,22 +2915,19 @@ void MicrosoftMangleContextImpl::mangleStringLiteral(const StringLiteral *SL,
};
// CRC all the bytes of the StringLiteral.
+ llvm::JamCRC JC;
for (unsigned I = 0, E = SL->getByteLength(); I != E; ++I)
- UpdateCRC(GetLittleEndianByte(I));
+ JC.update(GetLittleEndianByte(I));
// The NUL terminator byte(s) were not present earlier,
// we need to manually process those bytes into the CRC.
for (unsigned NullTerminator = 0; NullTerminator < SL->getCharByteWidth();
++NullTerminator)
- UpdateCRC('\x00');
-
- // The literature refers to the process of reversing the bits in the final CRC
- // output as "reflection".
- CRC = llvm::reverseBits(CRC);
+ JC.update('\x00');
// <encoded-crc>: The CRC is encoded utilizing the standard number mangling
// scheme.
- Mangler.mangleNumber(CRC);
+ Mangler.mangleNumber(JC.getCRC());
// <encoded-string>: The mangled name also contains the first 32 _characters_
// (including null-terminator bytes) of the StringLiteral.
@@ -2790,21 +2977,6 @@ void MicrosoftMangleContextImpl::mangleStringLiteral(const StringLiteral *SL,
Mangler.getStream() << '@';
}
-void MicrosoftMangleContextImpl::mangleCXXVTableBitSet(const CXXRecordDecl *RD,
- raw_ostream &Out) {
- if (!RD->isExternallyVisible()) {
- // This part of the identifier needs to be unique across all translation
- // units in the linked program. The scheme fails if multiple translation
- // units are compiled using the same relative source file path, or if
- // multiple translation units are built from the same source file.
- SourceManager &SM = getASTContext().getSourceManager();
- Out << "[" << SM.getFileEntryForID(SM.getMainFileID())->getName() << "]";
- }
-
- MicrosoftCXXNameMangler mangler(*this, Out);
- mangler.mangleName(RD);
-}
-
MicrosoftMangleContext *
MicrosoftMangleContext::create(ASTContext &Context, DiagnosticsEngine &Diags) {
return new MicrosoftMangleContextImpl(Context, Diags);
diff --git a/lib/AST/NSAPI.cpp b/lib/AST/NSAPI.cpp
index c9264d59aae3..c562dae63231 100644
--- a/lib/AST/NSAPI.cpp
+++ b/lib/AST/NSAPI.cpp
@@ -450,9 +450,19 @@ NSAPI::getNSNumberFactoryMethodKind(QualType T) const {
case BuiltinType::OCLImage1dBuffer:
case BuiltinType::OCLImage2d:
case BuiltinType::OCLImage2dArray:
+ case BuiltinType::OCLImage2dDepth:
+ case BuiltinType::OCLImage2dArrayDepth:
+ case BuiltinType::OCLImage2dMSAA:
+ case BuiltinType::OCLImage2dArrayMSAA:
+ case BuiltinType::OCLImage2dMSAADepth:
+ case BuiltinType::OCLImage2dArrayMSAADepth:
case BuiltinType::OCLImage3d:
case BuiltinType::OCLSampler:
case BuiltinType::OCLEvent:
+ case BuiltinType::OCLClkEvent:
+ case BuiltinType::OCLQueue:
+ case BuiltinType::OCLNDRange:
+ case BuiltinType::OCLReserveID:
case BuiltinType::BoundMember:
case BuiltinType::Dependent:
case BuiltinType::Overload:
@@ -461,6 +471,7 @@ NSAPI::getNSNumberFactoryMethodKind(QualType T) const {
case BuiltinType::Half:
case BuiltinType::PseudoObject:
case BuiltinType::BuiltinFn:
+ case BuiltinType::OMPArraySection:
break;
}
diff --git a/lib/AST/NestedNameSpecifier.cpp b/lib/AST/NestedNameSpecifier.cpp
index 97425d001de0..d2370c88b9c5 100644
--- a/lib/AST/NestedNameSpecifier.cpp
+++ b/lib/AST/NestedNameSpecifier.cpp
@@ -318,7 +318,12 @@ NestedNameSpecifier::print(raw_ostream &OS,
OS << "::";
}
-void NestedNameSpecifier::dump(const LangOptions &LO) {
+void NestedNameSpecifier::dump(const LangOptions &LO) const {
+ print(llvm::errs(), PrintingPolicy(LO));
+}
+
+void NestedNameSpecifier::dump() const {
+ LangOptions LO;
print(llvm::errs(), PrintingPolicy(LO));
}
diff --git a/lib/AST/OpenMPClause.cpp b/lib/AST/OpenMPClause.cpp
new file mode 100644
index 000000000000..cd60d3727ba1
--- /dev/null
+++ b/lib/AST/OpenMPClause.cpp
@@ -0,0 +1,465 @@
+//===--- OpenMPClause.cpp - Classes for OpenMP clauses --------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the subclesses of Stmt class declared in OpenMPClause.h
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/OpenMPClause.h"
+
+#include "clang/AST/ASTContext.h"
+
+using namespace clang;
+
+OMPClause::child_range OMPClause::children() {
+ switch (getClauseKind()) {
+ default:
+ break;
+#define OPENMP_CLAUSE(Name, Class) \
+ case OMPC_##Name: \
+ return static_cast<Class *>(this)->children();
+#include "clang/Basic/OpenMPKinds.def"
+ }
+ llvm_unreachable("unknown OMPClause");
+}
+
+void OMPPrivateClause::setPrivateCopies(ArrayRef<Expr *> VL) {
+ assert(VL.size() == varlist_size() &&
+ "Number of private copies is not the same as the preallocated buffer");
+ std::copy(VL.begin(), VL.end(), varlist_end());
+}
+
+OMPPrivateClause *
+OMPPrivateClause::Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation EndLoc,
+ ArrayRef<Expr *> VL, ArrayRef<Expr *> PrivateVL) {
+ // Allocate space for private variables and initializer expressions.
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPPrivateClause),
+ llvm::alignOf<Expr *>()) +
+ 2 * sizeof(Expr *) * VL.size());
+ OMPPrivateClause *Clause =
+ new (Mem) OMPPrivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
+ Clause->setVarRefs(VL);
+ Clause->setPrivateCopies(PrivateVL);
+ return Clause;
+}
+
+OMPPrivateClause *OMPPrivateClause::CreateEmpty(const ASTContext &C,
+ unsigned N) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPPrivateClause),
+ llvm::alignOf<Expr *>()) +
+ 2 * sizeof(Expr *) * N);
+ return new (Mem) OMPPrivateClause(N);
+}
+
+void OMPFirstprivateClause::setPrivateCopies(ArrayRef<Expr *> VL) {
+ assert(VL.size() == varlist_size() &&
+ "Number of private copies is not the same as the preallocated buffer");
+ std::copy(VL.begin(), VL.end(), varlist_end());
+}
+
+void OMPFirstprivateClause::setInits(ArrayRef<Expr *> VL) {
+ assert(VL.size() == varlist_size() &&
+ "Number of inits is not the same as the preallocated buffer");
+ std::copy(VL.begin(), VL.end(), getPrivateCopies().end());
+}
+
+OMPFirstprivateClause *
+OMPFirstprivateClause::Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation EndLoc,
+ ArrayRef<Expr *> VL, ArrayRef<Expr *> PrivateVL,
+ ArrayRef<Expr *> InitVL) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPFirstprivateClause),
+ llvm::alignOf<Expr *>()) +
+ 3 * sizeof(Expr *) * VL.size());
+ OMPFirstprivateClause *Clause =
+ new (Mem) OMPFirstprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
+ Clause->setVarRefs(VL);
+ Clause->setPrivateCopies(PrivateVL);
+ Clause->setInits(InitVL);
+ return Clause;
+}
+
+OMPFirstprivateClause *OMPFirstprivateClause::CreateEmpty(const ASTContext &C,
+ unsigned N) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPFirstprivateClause),
+ llvm::alignOf<Expr *>()) +
+ 3 * sizeof(Expr *) * N);
+ return new (Mem) OMPFirstprivateClause(N);
+}
+
+void OMPLastprivateClause::setPrivateCopies(ArrayRef<Expr *> PrivateCopies) {
+ assert(PrivateCopies.size() == varlist_size() &&
+ "Number of private copies is not the same as the preallocated buffer");
+ std::copy(PrivateCopies.begin(), PrivateCopies.end(), varlist_end());
+}
+
+void OMPLastprivateClause::setSourceExprs(ArrayRef<Expr *> SrcExprs) {
+ assert(SrcExprs.size() == varlist_size() && "Number of source expressions is "
+ "not the same as the "
+ "preallocated buffer");
+ std::copy(SrcExprs.begin(), SrcExprs.end(), getPrivateCopies().end());
+}
+
+void OMPLastprivateClause::setDestinationExprs(ArrayRef<Expr *> DstExprs) {
+ assert(DstExprs.size() == varlist_size() && "Number of destination "
+ "expressions is not the same as "
+ "the preallocated buffer");
+ std::copy(DstExprs.begin(), DstExprs.end(), getSourceExprs().end());
+}
+
+void OMPLastprivateClause::setAssignmentOps(ArrayRef<Expr *> AssignmentOps) {
+ assert(AssignmentOps.size() == varlist_size() &&
+ "Number of assignment expressions is not the same as the preallocated "
+ "buffer");
+ std::copy(AssignmentOps.begin(), AssignmentOps.end(),
+ getDestinationExprs().end());
+}
+
+OMPLastprivateClause *OMPLastprivateClause::Create(
+ const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
+ ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPLastprivateClause),
+ llvm::alignOf<Expr *>()) +
+ 5 * sizeof(Expr *) * VL.size());
+ OMPLastprivateClause *Clause =
+ new (Mem) OMPLastprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
+ Clause->setVarRefs(VL);
+ Clause->setSourceExprs(SrcExprs);
+ Clause->setDestinationExprs(DstExprs);
+ Clause->setAssignmentOps(AssignmentOps);
+ return Clause;
+}
+
+OMPLastprivateClause *OMPLastprivateClause::CreateEmpty(const ASTContext &C,
+ unsigned N) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPLastprivateClause),
+ llvm::alignOf<Expr *>()) +
+ 5 * sizeof(Expr *) * N);
+ return new (Mem) OMPLastprivateClause(N);
+}
+
+OMPSharedClause *OMPSharedClause::Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc,
+ ArrayRef<Expr *> VL) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPSharedClause),
+ llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * VL.size());
+ OMPSharedClause *Clause =
+ new (Mem) OMPSharedClause(StartLoc, LParenLoc, EndLoc, VL.size());
+ Clause->setVarRefs(VL);
+ return Clause;
+}
+
+OMPSharedClause *OMPSharedClause::CreateEmpty(const ASTContext &C, unsigned N) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPSharedClause),
+ llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * N);
+ return new (Mem) OMPSharedClause(N);
+}
+
+void OMPLinearClause::setPrivates(ArrayRef<Expr *> PL) {
+ assert(PL.size() == varlist_size() &&
+ "Number of privates is not the same as the preallocated buffer");
+ std::copy(PL.begin(), PL.end(), varlist_end());
+}
+
+void OMPLinearClause::setInits(ArrayRef<Expr *> IL) {
+ assert(IL.size() == varlist_size() &&
+ "Number of inits is not the same as the preallocated buffer");
+ std::copy(IL.begin(), IL.end(), getPrivates().end());
+}
+
+void OMPLinearClause::setUpdates(ArrayRef<Expr *> UL) {
+ assert(UL.size() == varlist_size() &&
+ "Number of updates is not the same as the preallocated buffer");
+ std::copy(UL.begin(), UL.end(), getInits().end());
+}
+
+void OMPLinearClause::setFinals(ArrayRef<Expr *> FL) {
+ assert(FL.size() == varlist_size() &&
+ "Number of final updates is not the same as the preallocated buffer");
+ std::copy(FL.begin(), FL.end(), getUpdates().end());
+}
+
+OMPLinearClause *OMPLinearClause::Create(
+ const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
+ OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc,
+ SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL,
+ ArrayRef<Expr *> PL, ArrayRef<Expr *> IL, Expr *Step, Expr *CalcStep) {
+ // Allocate space for 4 lists (Vars, Inits, Updates, Finals) and 2 expressions
+ // (Step and CalcStep).
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPLinearClause),
+ llvm::alignOf<Expr *>()) +
+ (5 * VL.size() + 2) * sizeof(Expr *));
+ OMPLinearClause *Clause = new (Mem) OMPLinearClause(
+ StartLoc, LParenLoc, Modifier, ModifierLoc, ColonLoc, EndLoc, VL.size());
+ Clause->setVarRefs(VL);
+ Clause->setPrivates(PL);
+ Clause->setInits(IL);
+ // Fill update and final expressions with zeroes, they are provided later,
+ // after the directive construction.
+ std::fill(Clause->getInits().end(), Clause->getInits().end() + VL.size(),
+ nullptr);
+ std::fill(Clause->getUpdates().end(), Clause->getUpdates().end() + VL.size(),
+ nullptr);
+ Clause->setStep(Step);
+ Clause->setCalcStep(CalcStep);
+ return Clause;
+}
+
+OMPLinearClause *OMPLinearClause::CreateEmpty(const ASTContext &C,
+ unsigned NumVars) {
+ // Allocate space for 4 lists (Vars, Inits, Updates, Finals) and 2 expressions
+ // (Step and CalcStep).
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPLinearClause),
+ llvm::alignOf<Expr *>()) +
+ (5 * NumVars + 2) * sizeof(Expr *));
+ return new (Mem) OMPLinearClause(NumVars);
+}
+
+OMPAlignedClause *
+OMPAlignedClause::Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation ColonLoc,
+ SourceLocation EndLoc, ArrayRef<Expr *> VL, Expr *A) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPAlignedClause),
+ llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * (VL.size() + 1));
+ OMPAlignedClause *Clause = new (Mem)
+ OMPAlignedClause(StartLoc, LParenLoc, ColonLoc, EndLoc, VL.size());
+ Clause->setVarRefs(VL);
+ Clause->setAlignment(A);
+ return Clause;
+}
+
+OMPAlignedClause *OMPAlignedClause::CreateEmpty(const ASTContext &C,
+ unsigned NumVars) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPAlignedClause),
+ llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * (NumVars + 1));
+ return new (Mem) OMPAlignedClause(NumVars);
+}
+
+void OMPCopyinClause::setSourceExprs(ArrayRef<Expr *> SrcExprs) {
+ assert(SrcExprs.size() == varlist_size() && "Number of source expressions is "
+ "not the same as the "
+ "preallocated buffer");
+ std::copy(SrcExprs.begin(), SrcExprs.end(), varlist_end());
+}
+
+void OMPCopyinClause::setDestinationExprs(ArrayRef<Expr *> DstExprs) {
+ assert(DstExprs.size() == varlist_size() && "Number of destination "
+ "expressions is not the same as "
+ "the preallocated buffer");
+ std::copy(DstExprs.begin(), DstExprs.end(), getSourceExprs().end());
+}
+
+void OMPCopyinClause::setAssignmentOps(ArrayRef<Expr *> AssignmentOps) {
+ assert(AssignmentOps.size() == varlist_size() &&
+ "Number of assignment expressions is not the same as the preallocated "
+ "buffer");
+ std::copy(AssignmentOps.begin(), AssignmentOps.end(),
+ getDestinationExprs().end());
+}
+
+OMPCopyinClause *OMPCopyinClause::Create(
+ const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
+ ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPCopyinClause),
+ llvm::alignOf<Expr *>()) +
+ 4 * sizeof(Expr *) * VL.size());
+ OMPCopyinClause *Clause =
+ new (Mem) OMPCopyinClause(StartLoc, LParenLoc, EndLoc, VL.size());
+ Clause->setVarRefs(VL);
+ Clause->setSourceExprs(SrcExprs);
+ Clause->setDestinationExprs(DstExprs);
+ Clause->setAssignmentOps(AssignmentOps);
+ return Clause;
+}
+
+OMPCopyinClause *OMPCopyinClause::CreateEmpty(const ASTContext &C, unsigned N) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPCopyinClause),
+ llvm::alignOf<Expr *>()) +
+ 4 * sizeof(Expr *) * N);
+ return new (Mem) OMPCopyinClause(N);
+}
+
+void OMPCopyprivateClause::setSourceExprs(ArrayRef<Expr *> SrcExprs) {
+ assert(SrcExprs.size() == varlist_size() && "Number of source expressions is "
+ "not the same as the "
+ "preallocated buffer");
+ std::copy(SrcExprs.begin(), SrcExprs.end(), varlist_end());
+}
+
+void OMPCopyprivateClause::setDestinationExprs(ArrayRef<Expr *> DstExprs) {
+ assert(DstExprs.size() == varlist_size() && "Number of destination "
+ "expressions is not the same as "
+ "the preallocated buffer");
+ std::copy(DstExprs.begin(), DstExprs.end(), getSourceExprs().end());
+}
+
+void OMPCopyprivateClause::setAssignmentOps(ArrayRef<Expr *> AssignmentOps) {
+ assert(AssignmentOps.size() == varlist_size() &&
+ "Number of assignment expressions is not the same as the preallocated "
+ "buffer");
+ std::copy(AssignmentOps.begin(), AssignmentOps.end(),
+ getDestinationExprs().end());
+}
+
+OMPCopyprivateClause *OMPCopyprivateClause::Create(
+ const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
+ ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPCopyprivateClause),
+ llvm::alignOf<Expr *>()) +
+ 4 * sizeof(Expr *) * VL.size());
+ OMPCopyprivateClause *Clause =
+ new (Mem) OMPCopyprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
+ Clause->setVarRefs(VL);
+ Clause->setSourceExprs(SrcExprs);
+ Clause->setDestinationExprs(DstExprs);
+ Clause->setAssignmentOps(AssignmentOps);
+ return Clause;
+}
+
+OMPCopyprivateClause *OMPCopyprivateClause::CreateEmpty(const ASTContext &C,
+ unsigned N) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPCopyprivateClause),
+ llvm::alignOf<Expr *>()) +
+ 4 * sizeof(Expr *) * N);
+ return new (Mem) OMPCopyprivateClause(N);
+}
+
+void OMPReductionClause::setPrivates(ArrayRef<Expr *> Privates) {
+ assert(Privates.size() == varlist_size() &&
+ "Number of private copies is not the same as the preallocated buffer");
+ std::copy(Privates.begin(), Privates.end(), varlist_end());
+}
+
+void OMPReductionClause::setLHSExprs(ArrayRef<Expr *> LHSExprs) {
+ assert(
+ LHSExprs.size() == varlist_size() &&
+ "Number of LHS expressions is not the same as the preallocated buffer");
+ std::copy(LHSExprs.begin(), LHSExprs.end(), getPrivates().end());
+}
+
+void OMPReductionClause::setRHSExprs(ArrayRef<Expr *> RHSExprs) {
+ assert(
+ RHSExprs.size() == varlist_size() &&
+ "Number of RHS expressions is not the same as the preallocated buffer");
+ std::copy(RHSExprs.begin(), RHSExprs.end(), getLHSExprs().end());
+}
+
+void OMPReductionClause::setReductionOps(ArrayRef<Expr *> ReductionOps) {
+ assert(ReductionOps.size() == varlist_size() && "Number of reduction "
+ "expressions is not the same "
+ "as the preallocated buffer");
+ std::copy(ReductionOps.begin(), ReductionOps.end(), getRHSExprs().end());
+}
+
+OMPReductionClause *OMPReductionClause::Create(
+ const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL,
+ NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
+ ArrayRef<Expr *> Privates, ArrayRef<Expr *> LHSExprs,
+ ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPReductionClause),
+ llvm::alignOf<Expr *>()) +
+ 5 * sizeof(Expr *) * VL.size());
+ OMPReductionClause *Clause = new (Mem) OMPReductionClause(
+ StartLoc, LParenLoc, EndLoc, ColonLoc, VL.size(), QualifierLoc, NameInfo);
+ Clause->setVarRefs(VL);
+ Clause->setPrivates(Privates);
+ Clause->setLHSExprs(LHSExprs);
+ Clause->setRHSExprs(RHSExprs);
+ Clause->setReductionOps(ReductionOps);
+ return Clause;
+}
+
+OMPReductionClause *OMPReductionClause::CreateEmpty(const ASTContext &C,
+ unsigned N) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPReductionClause),
+ llvm::alignOf<Expr *>()) +
+ 5 * sizeof(Expr *) * N);
+ return new (Mem) OMPReductionClause(N);
+}
+
+OMPFlushClause *OMPFlushClause::Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc,
+ ArrayRef<Expr *> VL) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPFlushClause),
+ llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * VL.size());
+ OMPFlushClause *Clause =
+ new (Mem) OMPFlushClause(StartLoc, LParenLoc, EndLoc, VL.size());
+ Clause->setVarRefs(VL);
+ return Clause;
+}
+
+OMPFlushClause *OMPFlushClause::CreateEmpty(const ASTContext &C, unsigned N) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPFlushClause),
+ llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * N);
+ return new (Mem) OMPFlushClause(N);
+}
+
+OMPDependClause *
+OMPDependClause::Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation EndLoc,
+ OpenMPDependClauseKind DepKind, SourceLocation DepLoc,
+ SourceLocation ColonLoc, ArrayRef<Expr *> VL) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPDependClause),
+ llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * VL.size());
+ OMPDependClause *Clause =
+ new (Mem) OMPDependClause(StartLoc, LParenLoc, EndLoc, VL.size());
+ Clause->setVarRefs(VL);
+ Clause->setDependencyKind(DepKind);
+ Clause->setDependencyLoc(DepLoc);
+ Clause->setColonLoc(ColonLoc);
+ return Clause;
+}
+
+OMPDependClause *OMPDependClause::CreateEmpty(const ASTContext &C, unsigned N) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPDependClause),
+ llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * N);
+ return new (Mem) OMPDependClause(N);
+}
+
+OMPMapClause *OMPMapClause::Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc, ArrayRef<Expr *> VL,
+ OpenMPMapClauseKind TypeModifier,
+ OpenMPMapClauseKind Type,
+ SourceLocation TypeLoc) {
+ void *Mem = C.Allocate(
+ llvm::RoundUpToAlignment(sizeof(OMPMapClause), llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * VL.size());
+ OMPMapClause *Clause = new (Mem) OMPMapClause(
+ TypeModifier, Type, TypeLoc, StartLoc, LParenLoc, EndLoc, VL.size());
+ Clause->setVarRefs(VL);
+ Clause->setMapTypeModifier(TypeModifier);
+ Clause->setMapType(Type);
+ Clause->setMapLoc(TypeLoc);
+ return Clause;
+}
+
+OMPMapClause *OMPMapClause::CreateEmpty(const ASTContext &C, unsigned N) {
+ void *Mem = C.Allocate(
+ llvm::RoundUpToAlignment(sizeof(OMPMapClause), llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * N);
+ return new (Mem) OMPMapClause(N);
+}
diff --git a/lib/AST/RawCommentList.cpp b/lib/AST/RawCommentList.cpp
index 24b129a5c532..8317f76b8569 100644
--- a/lib/AST/RawCommentList.cpp
+++ b/lib/AST/RawCommentList.cpp
@@ -15,6 +15,7 @@
#include "clang/AST/CommentLexer.h"
#include "clang/AST/CommentParser.h"
#include "clang/AST/CommentSema.h"
+#include "clang/Basic/CharInfo.h"
#include "llvm/ADT/STLExtras.h"
using namespace clang;
@@ -62,12 +63,53 @@ std::pair<RawComment::CommentKind, bool> getCommentKind(StringRef Comment,
bool mergedCommentIsTrailingComment(StringRef Comment) {
return (Comment.size() > 3) && (Comment[3] == '<');
}
+
+/// Returns true if R1 and R2 both have valid locations that start on the same
+/// column.
+bool commentsStartOnSameColumn(const SourceManager &SM, const RawComment &R1,
+ const RawComment &R2) {
+ SourceLocation L1 = R1.getLocStart();
+ SourceLocation L2 = R2.getLocStart();
+ bool Invalid = false;
+ unsigned C1 = SM.getPresumedColumnNumber(L1, &Invalid);
+ if (!Invalid) {
+ unsigned C2 = SM.getPresumedColumnNumber(L2, &Invalid);
+ return !Invalid && (C1 == C2);
+ }
+ return false;
+}
} // unnamed namespace
+/// \brief Determines whether there is only whitespace in `Buffer` between `P`
+/// and the previous line.
+/// \param Buffer The buffer to search in.
+/// \param P The offset from the beginning of `Buffer` to start from.
+/// \return true if all of the characters in `Buffer` ranging from the closest
+/// line-ending character before `P` (or the beginning of `Buffer`) to `P - 1`
+/// are whitespace.
+static bool onlyWhitespaceOnLineBefore(const char *Buffer, unsigned P) {
+ // Search backwards until we see linefeed or carriage return.
+ for (unsigned I = P; I != 0; --I) {
+ char C = Buffer[I - 1];
+ if (isVerticalWhitespace(C))
+ return true;
+ if (!isHorizontalWhitespace(C))
+ return false;
+ }
+ // We hit the beginning of the buffer.
+ return true;
+}
+
+/// Returns whether `K` is an ordinary comment kind.
+static bool isOrdinaryKind(RawComment::CommentKind K) {
+ return (K == RawComment::RCK_OrdinaryBCPL) ||
+ (K == RawComment::RCK_OrdinaryC);
+}
+
RawComment::RawComment(const SourceManager &SourceMgr, SourceRange SR,
bool Merged, bool ParseAllComments) :
Range(SR), RawTextValid(false), BriefTextValid(false),
- IsAttached(false), IsAlmostTrailingComment(false),
+ IsAttached(false), IsTrailingComment(false), IsAlmostTrailingComment(false),
ParseAllComments(ParseAllComments) {
// Extract raw comment text, if possible.
if (SR.getBegin() == SR.getEnd() || getRawText(SourceMgr).empty()) {
@@ -75,17 +117,34 @@ RawComment::RawComment(const SourceManager &SourceMgr, SourceRange SR,
return;
}
+ // Guess comment kind.
+ std::pair<CommentKind, bool> K = getCommentKind(RawText, ParseAllComments);
+
+ // Guess whether an ordinary comment is trailing.
+ if (ParseAllComments && isOrdinaryKind(K.first)) {
+ FileID BeginFileID;
+ unsigned BeginOffset;
+ std::tie(BeginFileID, BeginOffset) =
+ SourceMgr.getDecomposedLoc(Range.getBegin());
+ if (BeginOffset != 0) {
+ bool Invalid = false;
+ const char *Buffer =
+ SourceMgr.getBufferData(BeginFileID, &Invalid).data();
+ IsTrailingComment |=
+ (!Invalid && !onlyWhitespaceOnLineBefore(Buffer, BeginOffset));
+ }
+ }
+
if (!Merged) {
- // Guess comment kind.
- std::pair<CommentKind, bool> K = getCommentKind(RawText, ParseAllComments);
Kind = K.first;
- IsTrailingComment = K.second;
+ IsTrailingComment |= K.second;
IsAlmostTrailingComment = RawText.startswith("//<") ||
RawText.startswith("/*<");
} else {
Kind = RCK_Merged;
- IsTrailingComment = mergedCommentIsTrailingComment(RawText);
+ IsTrailingComment =
+ IsTrailingComment || mergedCommentIsTrailingComment(RawText);
}
}
@@ -239,9 +298,22 @@ void RawCommentList::addComment(const RawComment &RC,
const RawComment &C2 = RC;
// Merge comments only if there is only whitespace between them.
- // Can't merge trailing and non-trailing comments.
+ // Can't merge trailing and non-trailing comments unless the second is
+ // non-trailing ordinary in the same column, as in the case:
+ // int x; // documents x
+ // // more text
+ // versus:
+ // int x; // documents x
+ // int y; // documents y
+ // or:
+ // int x; // documents x
+ // // documents y
+ // int y;
// Merge comments if they are on same or consecutive lines.
- if (C1.isTrailingComment() == C2.isTrailingComment() &&
+ if ((C1.isTrailingComment() == C2.isTrailingComment() ||
+ (C1.isTrailingComment() && !C2.isTrailingComment() &&
+ isOrdinaryKind(C2.getKind()) &&
+ commentsStartOnSameColumn(SourceMgr, C1, C2))) &&
onlyWhitespaceBetween(SourceMgr, C1.getLocEnd(), C2.getLocStart(),
/*MaxNewlinesAllowed=*/1)) {
SourceRange MergedRange(C1.getLocStart(), C2.getLocEnd());
diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp
index de7bcb826ebb..bc3c2a831c47 100644
--- a/lib/AST/RecordLayoutBuilder.cpp
+++ b/lib/AST/RecordLayoutBuilder.cpp
@@ -18,7 +18,6 @@
#include "clang/Basic/TargetInfo.h"
#include "clang/Sema/SemaDiagnostic.h"
#include "llvm/ADT/SmallSet.h"
-#include "llvm/Support/CrashRecoveryContext.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/MathExtras.h"
@@ -565,7 +564,7 @@ void EmptySubobjectMap::UpdateEmptyFieldSubobjects(const FieldDecl *FD,
typedef llvm::SmallPtrSet<const CXXRecordDecl*, 4> ClassSetTy;
-class RecordLayoutBuilder {
+class ItaniumRecordLayoutBuilder {
protected:
// FIXME: Remove this and make the appropriate fields public.
friend class clang::ASTContext;
@@ -656,19 +655,18 @@ protected:
/// Valid if UseExternalLayout is true.
ExternalLayout External;
- RecordLayoutBuilder(const ASTContext &Context,
- EmptySubobjectMap *EmptySubobjects)
- : Context(Context), EmptySubobjects(EmptySubobjects), Size(0),
- Alignment(CharUnits::One()), UnpackedAlignment(CharUnits::One()),
- UseExternalLayout(false), InferAlignment(false),
- Packed(false), IsUnion(false), IsMac68kAlign(false), IsMsStruct(false),
- UnfilledBitsInLastUnit(0), LastBitfieldTypeSize(0),
- MaxFieldAlignment(CharUnits::Zero()),
- DataSize(0), NonVirtualSize(CharUnits::Zero()),
- NonVirtualAlignment(CharUnits::One()),
- PrimaryBase(nullptr), PrimaryBaseIsVirtual(false),
- HasOwnVFPtr(false),
- FirstNearlyEmptyVBase(nullptr) {}
+ ItaniumRecordLayoutBuilder(const ASTContext &Context,
+ EmptySubobjectMap *EmptySubobjects)
+ : Context(Context), EmptySubobjects(EmptySubobjects), Size(0),
+ Alignment(CharUnits::One()), UnpackedAlignment(CharUnits::One()),
+ UseExternalLayout(false), InferAlignment(false), Packed(false),
+ IsUnion(false), IsMac68kAlign(false), IsMsStruct(false),
+ UnfilledBitsInLastUnit(0), LastBitfieldTypeSize(0),
+ MaxFieldAlignment(CharUnits::Zero()), DataSize(0),
+ NonVirtualSize(CharUnits::Zero()),
+ NonVirtualAlignment(CharUnits::One()), PrimaryBase(nullptr),
+ PrimaryBaseIsVirtual(false), HasOwnVFPtr(false),
+ FirstNearlyEmptyVBase(nullptr) {}
void Layout(const RecordDecl *D);
void Layout(const CXXRecordDecl *D);
@@ -782,13 +780,12 @@ protected:
void setDataSize(CharUnits NewSize) { DataSize = Context.toBits(NewSize); }
void setDataSize(uint64_t NewSize) { DataSize = NewSize; }
- RecordLayoutBuilder(const RecordLayoutBuilder &) = delete;
- void operator=(const RecordLayoutBuilder &) = delete;
+ ItaniumRecordLayoutBuilder(const ItaniumRecordLayoutBuilder &) = delete;
+ void operator=(const ItaniumRecordLayoutBuilder &) = delete;
};
} // end anonymous namespace
-void
-RecordLayoutBuilder::SelectPrimaryVBase(const CXXRecordDecl *RD) {
+void ItaniumRecordLayoutBuilder::SelectPrimaryVBase(const CXXRecordDecl *RD) {
for (const auto &I : RD->bases()) {
assert(!I.getType()->isDependentType() &&
"Cannot layout class with dependent bases.");
@@ -817,7 +814,7 @@ RecordLayoutBuilder::SelectPrimaryVBase(const CXXRecordDecl *RD) {
}
/// DeterminePrimaryBase - Determine the primary base of the given class.
-void RecordLayoutBuilder::DeterminePrimaryBase(const CXXRecordDecl *RD) {
+void ItaniumRecordLayoutBuilder::DeterminePrimaryBase(const CXXRecordDecl *RD) {
// If the class isn't dynamic, it won't have a primary base.
if (!RD->isDynamicClass())
return;
@@ -864,10 +861,8 @@ void RecordLayoutBuilder::DeterminePrimaryBase(const CXXRecordDecl *RD) {
assert(!PrimaryBase && "Should not get here with a primary base!");
}
-BaseSubobjectInfo *
-RecordLayoutBuilder::ComputeBaseSubobjectInfo(const CXXRecordDecl *RD,
- bool IsVirtual,
- BaseSubobjectInfo *Derived) {
+BaseSubobjectInfo *ItaniumRecordLayoutBuilder::ComputeBaseSubobjectInfo(
+ const CXXRecordDecl *RD, bool IsVirtual, BaseSubobjectInfo *Derived) {
BaseSubobjectInfo *Info;
if (IsVirtual) {
@@ -943,7 +938,8 @@ RecordLayoutBuilder::ComputeBaseSubobjectInfo(const CXXRecordDecl *RD,
return Info;
}
-void RecordLayoutBuilder::ComputeBaseSubobjectInfo(const CXXRecordDecl *RD) {
+void ItaniumRecordLayoutBuilder::ComputeBaseSubobjectInfo(
+ const CXXRecordDecl *RD) {
for (const auto &I : RD->bases()) {
bool IsVirtual = I.isVirtual();
@@ -966,8 +962,8 @@ void RecordLayoutBuilder::ComputeBaseSubobjectInfo(const CXXRecordDecl *RD) {
}
}
-void
-RecordLayoutBuilder::EnsureVTablePointerAlignment(CharUnits UnpackedBaseAlign) {
+void ItaniumRecordLayoutBuilder::EnsureVTablePointerAlignment(
+ CharUnits UnpackedBaseAlign) {
CharUnits BaseAlign = (Packed) ? CharUnits::One() : UnpackedBaseAlign;
// The maximum field alignment overrides base align.
@@ -984,8 +980,8 @@ RecordLayoutBuilder::EnsureVTablePointerAlignment(CharUnits UnpackedBaseAlign) {
UpdateAlignment(BaseAlign, UnpackedBaseAlign);
}
-void
-RecordLayoutBuilder::LayoutNonVirtualBases(const CXXRecordDecl *RD) {
+void ItaniumRecordLayoutBuilder::LayoutNonVirtualBases(
+ const CXXRecordDecl *RD) {
// Then, determine the primary base class.
DeterminePrimaryBase(RD);
@@ -1054,7 +1050,8 @@ RecordLayoutBuilder::LayoutNonVirtualBases(const CXXRecordDecl *RD) {
}
}
-void RecordLayoutBuilder::LayoutNonVirtualBase(const BaseSubobjectInfo *Base) {
+void ItaniumRecordLayoutBuilder::LayoutNonVirtualBase(
+ const BaseSubobjectInfo *Base) {
// Layout the base.
CharUnits Offset = LayoutBase(Base);
@@ -1065,9 +1062,8 @@ void RecordLayoutBuilder::LayoutNonVirtualBase(const BaseSubobjectInfo *Base) {
AddPrimaryVirtualBaseOffsets(Base, Offset);
}
-void
-RecordLayoutBuilder::AddPrimaryVirtualBaseOffsets(const BaseSubobjectInfo *Info,
- CharUnits Offset) {
+void ItaniumRecordLayoutBuilder::AddPrimaryVirtualBaseOffsets(
+ const BaseSubobjectInfo *Info, CharUnits Offset) {
// This base isn't interesting, it has no virtual bases.
if (!Info->Class->getNumVBases())
return;
@@ -1099,9 +1095,8 @@ RecordLayoutBuilder::AddPrimaryVirtualBaseOffsets(const BaseSubobjectInfo *Info,
}
}
-void
-RecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *RD,
- const CXXRecordDecl *MostDerivedClass) {
+void ItaniumRecordLayoutBuilder::LayoutVirtualBases(
+ const CXXRecordDecl *RD, const CXXRecordDecl *MostDerivedClass) {
const CXXRecordDecl *PrimaryBase;
bool PrimaryBaseIsVirtual;
@@ -1146,7 +1141,8 @@ RecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *RD,
}
}
-void RecordLayoutBuilder::LayoutVirtualBase(const BaseSubobjectInfo *Base) {
+void ItaniumRecordLayoutBuilder::LayoutVirtualBase(
+ const BaseSubobjectInfo *Base) {
assert(!Base->Derived && "Trying to lay out a primary virtual base!");
// Layout the base.
@@ -1160,7 +1156,8 @@ void RecordLayoutBuilder::LayoutVirtualBase(const BaseSubobjectInfo *Base) {
AddPrimaryVirtualBaseOffsets(Base, Offset);
}
-CharUnits RecordLayoutBuilder::LayoutBase(const BaseSubobjectInfo *Base) {
+CharUnits
+ItaniumRecordLayoutBuilder::LayoutBase(const BaseSubobjectInfo *Base) {
const ASTRecordLayout &Layout = Context.getASTRecordLayout(Base->Class);
@@ -1229,7 +1226,7 @@ CharUnits RecordLayoutBuilder::LayoutBase(const BaseSubobjectInfo *Base) {
return Offset;
}
-void RecordLayoutBuilder::InitializeLayout(const Decl *D) {
+void ItaniumRecordLayoutBuilder::InitializeLayout(const Decl *D) {
if (const RecordDecl *RD = dyn_cast<RecordDecl>(D)) {
IsUnion = RD->isUnion();
IsMsStruct = RD->isMsStruct(Context);
@@ -1277,7 +1274,7 @@ void RecordLayoutBuilder::InitializeLayout(const Decl *D) {
}
}
-void RecordLayoutBuilder::Layout(const RecordDecl *D) {
+void ItaniumRecordLayoutBuilder::Layout(const RecordDecl *D) {
InitializeLayout(D);
LayoutFields(D);
@@ -1286,7 +1283,7 @@ void RecordLayoutBuilder::Layout(const RecordDecl *D) {
FinishLayout(D);
}
-void RecordLayoutBuilder::Layout(const CXXRecordDecl *RD) {
+void ItaniumRecordLayoutBuilder::Layout(const CXXRecordDecl *RD) {
InitializeLayout(RD);
// Lay out the vtable and the non-virtual bases.
@@ -1326,7 +1323,7 @@ void RecordLayoutBuilder::Layout(const CXXRecordDecl *RD) {
#endif
}
-void RecordLayoutBuilder::Layout(const ObjCInterfaceDecl *D) {
+void ItaniumRecordLayoutBuilder::Layout(const ObjCInterfaceDecl *D) {
if (ObjCInterfaceDecl *SD = D->getSuperClass()) {
const ASTRecordLayout &SL = Context.getASTObjCInterfaceLayout(SD);
@@ -1349,7 +1346,7 @@ void RecordLayoutBuilder::Layout(const ObjCInterfaceDecl *D) {
FinishLayout(D);
}
-void RecordLayoutBuilder::LayoutFields(const RecordDecl *D) {
+void ItaniumRecordLayoutBuilder::LayoutFields(const RecordDecl *D) {
// Layout each field, for now, just sequentially, respecting alignment. In
// the future, this will need to be tweakable by targets.
bool InsertExtraPadding = D->mayInsertExtraPadding(/*EmitRemark=*/true);
@@ -1370,10 +1367,10 @@ roundUpSizeToCharAlignment(uint64_t Size,
return llvm::RoundUpToAlignment(Size, CharAlignment);
}
-void RecordLayoutBuilder::LayoutWideBitField(uint64_t FieldSize,
- uint64_t TypeSize,
- bool FieldPacked,
- const FieldDecl *D) {
+void ItaniumRecordLayoutBuilder::LayoutWideBitField(uint64_t FieldSize,
+ uint64_t TypeSize,
+ bool FieldPacked,
+ const FieldDecl *D) {
assert(Context.getLangOpts().CPlusPlus &&
"Can only have wide bit-fields in C++!");
@@ -1437,7 +1434,7 @@ void RecordLayoutBuilder::LayoutWideBitField(uint64_t FieldSize,
UpdateAlignment(TypeAlign);
}
-void RecordLayoutBuilder::LayoutBitField(const FieldDecl *D) {
+void ItaniumRecordLayoutBuilder::LayoutBitField(const FieldDecl *D) {
bool FieldPacked = Packed || D->hasAttr<PackedAttr>();
uint64_t FieldSize = D->getBitWidthValue(Context);
TypeInfo FieldInfo = Context.getTypeInfo(D->getType());
@@ -1568,6 +1565,12 @@ void RecordLayoutBuilder::LayoutBitField(const FieldDecl *D) {
UnpackedFieldAlign = std::min(UnpackedFieldAlign, MaxFieldAlignmentInBits);
}
+ // But, ms_struct just ignores all of that in unions, even explicit
+ // alignment attributes.
+ if (IsMsStruct && IsUnion) {
+ FieldAlign = UnpackedFieldAlign = 1;
+ }
+
// For purposes of diagnostics, we're going to simultaneously
// compute the field offsets that we would have used if we weren't
// adding any alignment padding or if the field weren't packed.
@@ -1634,9 +1637,20 @@ void RecordLayoutBuilder::LayoutBitField(const FieldDecl *D) {
// For unions, this is just a max operation, as usual.
if (IsUnion) {
- uint64_t RoundedFieldSize = roundUpSizeToCharAlignment(FieldSize,
- Context);
+ // For ms_struct, allocate the entire storage unit --- unless this
+ // is a zero-width bitfield, in which case just use a size of 1.
+ uint64_t RoundedFieldSize;
+ if (IsMsStruct) {
+ RoundedFieldSize =
+ (FieldSize ? TypeSize : Context.getTargetInfo().getCharWidth());
+
+ // Otherwise, allocate just the number of bytes required to store
+ // the bitfield.
+ } else {
+ RoundedFieldSize = roundUpSizeToCharAlignment(FieldSize, Context);
+ }
setDataSize(std::max(getDataSizeInBits(), RoundedFieldSize));
+
// For non-zero-width bitfields in ms_struct structs, allocate a new
// storage unit if necessary.
} else if (IsMsStruct && FieldSize) {
@@ -1672,8 +1686,8 @@ void RecordLayoutBuilder::LayoutBitField(const FieldDecl *D) {
Context.toCharUnitsFromBits(UnpackedFieldAlign));
}
-void RecordLayoutBuilder::LayoutField(const FieldDecl *D,
- bool InsertExtraPadding) {
+void ItaniumRecordLayoutBuilder::LayoutField(const FieldDecl *D,
+ bool InsertExtraPadding) {
if (D->isBitField()) {
LayoutBitField(D);
return;
@@ -1800,7 +1814,7 @@ void RecordLayoutBuilder::LayoutField(const FieldDecl *D,
UpdateAlignment(FieldAlign, UnpackedFieldAlign);
}
-void RecordLayoutBuilder::FinishLayout(const NamedDecl *D) {
+void ItaniumRecordLayoutBuilder::FinishLayout(const NamedDecl *D) {
// In C++, records cannot be of size 0.
if (Context.getLangOpts().CPlusPlus && getSizeInBits() == 0) {
if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
@@ -1852,7 +1866,7 @@ void RecordLayoutBuilder::FinishLayout(const NamedDecl *D) {
Diag(RD->getLocation(), diag::warn_padded_struct_size)
<< Context.getTypeDeclType(RD)
<< PadSize
- << (InBits ? 1 : 0) /*(byte|bit)*/ << (PadSize > 1); // plural or not
+ << (InBits ? 1 : 0); // (byte|bit)
}
// Warn if we packed it unnecessarily. If the alignment is 1 byte don't
@@ -1864,8 +1878,8 @@ void RecordLayoutBuilder::FinishLayout(const NamedDecl *D) {
}
}
-void RecordLayoutBuilder::UpdateAlignment(CharUnits NewAlignment,
- CharUnits UnpackedNewAlignment) {
+void ItaniumRecordLayoutBuilder::UpdateAlignment(
+ CharUnits NewAlignment, CharUnits UnpackedNewAlignment) {
// The alignment is not modified when using 'mac68k' alignment or when
// we have an externally-supplied layout that also provides overall alignment.
if (IsMac68kAlign || (UseExternalLayout && !InferAlignment))
@@ -1885,8 +1899,8 @@ void RecordLayoutBuilder::UpdateAlignment(CharUnits NewAlignment,
}
uint64_t
-RecordLayoutBuilder::updateExternalFieldOffset(const FieldDecl *Field,
- uint64_t ComputedOffset) {
+ItaniumRecordLayoutBuilder::updateExternalFieldOffset(const FieldDecl *Field,
+ uint64_t ComputedOffset) {
uint64_t ExternalFieldOffset = External.getExternalFieldOffset(Field);
if (InferAlignment && ExternalFieldOffset < ComputedOffset) {
@@ -1914,12 +1928,9 @@ static unsigned getPaddingDiagFromTagKind(TagTypeKind Tag) {
}
}
-void RecordLayoutBuilder::CheckFieldPadding(uint64_t Offset,
- uint64_t UnpaddedOffset,
- uint64_t UnpackedOffset,
- unsigned UnpackedAlign,
- bool isPacked,
- const FieldDecl *D) {
+void ItaniumRecordLayoutBuilder::CheckFieldPadding(
+ uint64_t Offset, uint64_t UnpaddedOffset, uint64_t UnpackedOffset,
+ unsigned UnpackedAlign, bool isPacked, const FieldDecl *D) {
// We let objc ivars without warning, objc interfaces generally are not used
// for padding tricks.
if (isa<ObjCIvarDecl>(D))
@@ -1945,14 +1956,14 @@ void RecordLayoutBuilder::CheckFieldPadding(uint64_t Offset,
<< getPaddingDiagFromTagKind(D->getParent()->getTagKind())
<< Context.getTypeDeclType(D->getParent())
<< PadSize
- << (InBits ? 1 : 0) /*(byte|bit)*/ << (PadSize > 1) // plural or not
+ << (InBits ? 1 : 0) // (byte|bit)
<< D->getIdentifier();
else
Diag(D->getLocation(), diag::warn_padded_struct_anon_field)
<< getPaddingDiagFromTagKind(D->getParent()->getTagKind())
<< Context.getTypeDeclType(D->getParent())
<< PadSize
- << (InBits ? 1 : 0) /*(byte|bit)*/ << (PadSize > 1); // plural or not
+ << (InBits ? 1 : 0); // (byte|bit)
}
// Warn if we packed it unnecessarily. If the alignment is 1 byte don't
@@ -2014,6 +2025,21 @@ static const CXXMethodDecl *computeKeyFunction(ASTContext &Context,
continue;
}
+ if (Context.getLangOpts().CUDA) {
+ // While compiler may see key method in this TU, during CUDA
+ // compilation we should ignore methods that are not accessible
+ // on this side of compilation.
+ if (Context.getLangOpts().CUDAIsDevice) {
+ // In device mode ignore methods without __device__ attribute.
+ if (!MD->hasAttr<CUDADeviceAttr>())
+ continue;
+ } else {
+ // In host mode ignore __device__-only methods.
+ if (!MD->hasAttr<CUDAHostAttr>() && MD->hasAttr<CUDADeviceAttr>())
+ continue;
+ }
+ }
+
// If the key function is dllimport but the class isn't, then the class has
// no key function. The DLL that exports the key function won't export the
// vtable in this case.
@@ -2027,8 +2053,8 @@ static const CXXMethodDecl *computeKeyFunction(ASTContext &Context,
return nullptr;
}
-DiagnosticBuilder
-RecordLayoutBuilder::Diag(SourceLocation Loc, unsigned DiagID) {
+DiagnosticBuilder ItaniumRecordLayoutBuilder::Diag(SourceLocation Loc,
+ unsigned DiagID) {
return Context.getDiagnostics().Report(Loc, DiagID);
}
@@ -2074,8 +2100,8 @@ static bool mustSkipTailPadding(TargetCXXABI ABI, const CXXRecordDecl *RD) {
llvm_unreachable("bad tail-padding use kind");
}
-static bool isMsLayout(const RecordDecl* D) {
- return D->getASTContext().getTargetInfo().getCXXABI().isMicrosoft();
+static bool isMsLayout(const ASTContext &Context) {
+ return Context.getTargetInfo().getCXXABI().isMicrosoft();
}
// This section contains an implementation of struct layout that is, up to the
@@ -2656,13 +2682,20 @@ void MicrosoftRecordLayoutBuilder::injectVFPtr(const CXXRecordDecl *RD) {
// alignment.
CharUnits Offset = PointerInfo.Size.RoundUpToAlignment(
std::max(RequiredAlignment, Alignment));
- // Increase the size of the object and push back all fields, the vbptr and all
- // bases by the offset amount.
+ // Push back the vbptr, but increase the size of the object and push back
+ // regular fields by the offset only if not using external record layout.
+ if (HasVBPtr)
+ VBPtrOffset += Offset;
+
+ if (UseExternalLayout)
+ return;
+
Size += Offset;
+
+ // If we're using an external layout, the fields offsets have already
+ // accounted for this adjustment.
for (uint64_t &FieldOffset : FieldOffsets)
FieldOffset += Context.toBits(Offset);
- if (HasVBPtr)
- VBPtrOffset += Offset;
for (BaseOffsetsMapTy::value_type &Base : Bases)
Base.second += Offset;
}
@@ -2840,32 +2873,6 @@ void MicrosoftRecordLayoutBuilder::computeVtorDispSet(
}
}
-/// \brief Get or compute information about the layout of the specified record
-/// (struct/union/class), which indicates its size and field position
-/// information.
-const ASTRecordLayout *
-ASTContext::BuildMicrosoftASTRecordLayout(const RecordDecl *D) const {
- MicrosoftRecordLayoutBuilder Builder(*this);
- if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
- Builder.cxxLayout(RD);
- return new (*this) ASTRecordLayout(
- *this, Builder.Size, Builder.Alignment, Builder.RequiredAlignment,
- Builder.HasOwnVFPtr,
- Builder.HasOwnVFPtr || Builder.PrimaryBase,
- Builder.VBPtrOffset, Builder.NonVirtualSize, Builder.FieldOffsets.data(),
- Builder.FieldOffsets.size(), Builder.NonVirtualSize,
- Builder.Alignment, CharUnits::Zero(), Builder.PrimaryBase,
- false, Builder.SharedVBPtrBase,
- Builder.EndsWithZeroSizedObject, Builder.LeadsWithZeroSizedBase,
- Builder.Bases, Builder.VBases);
- } else {
- Builder.layout(D);
- return new (*this) ASTRecordLayout(
- *this, Builder.Size, Builder.Alignment, Builder.RequiredAlignment,
- Builder.Size, Builder.FieldOffsets.data(), Builder.FieldOffsets.size());
- }
-}
-
/// getASTRecordLayout - Get or compute information about the layout of the
/// specified record (struct/union/class), which indicates its size and field
/// position information.
@@ -2892,54 +2899,63 @@ ASTContext::getASTRecordLayout(const RecordDecl *D) const {
const ASTRecordLayout *NewEntry = nullptr;
- if (isMsLayout(D)) {
- NewEntry = BuildMicrosoftASTRecordLayout(D);
- } else if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
- EmptySubobjectMap EmptySubobjects(*this, RD);
- RecordLayoutBuilder Builder(*this, &EmptySubobjects);
- Builder.Layout(RD);
-
- // In certain situations, we are allowed to lay out objects in the
- // tail-padding of base classes. This is ABI-dependent.
- // FIXME: this should be stored in the record layout.
- bool skipTailPadding =
- mustSkipTailPadding(getTargetInfo().getCXXABI(), cast<CXXRecordDecl>(D));
-
- // FIXME: This should be done in FinalizeLayout.
- CharUnits DataSize =
- skipTailPadding ? Builder.getSize() : Builder.getDataSize();
- CharUnits NonVirtualSize =
- skipTailPadding ? DataSize : Builder.NonVirtualSize;
- NewEntry =
- new (*this) ASTRecordLayout(*this, Builder.getSize(),
- Builder.Alignment,
- /*RequiredAlignment : used by MS-ABI)*/
- Builder.Alignment,
- Builder.HasOwnVFPtr,
- RD->isDynamicClass(),
- CharUnits::fromQuantity(-1),
- DataSize,
- Builder.FieldOffsets.data(),
- Builder.FieldOffsets.size(),
- NonVirtualSize,
- Builder.NonVirtualAlignment,
- EmptySubobjects.SizeOfLargestEmptySubobject,
- Builder.PrimaryBase,
- Builder.PrimaryBaseIsVirtual,
- nullptr, false, false,
- Builder.Bases, Builder.VBases);
+ if (isMsLayout(*this)) {
+ MicrosoftRecordLayoutBuilder Builder(*this);
+ if (const auto *RD = dyn_cast<CXXRecordDecl>(D)) {
+ Builder.cxxLayout(RD);
+ NewEntry = new (*this) ASTRecordLayout(
+ *this, Builder.Size, Builder.Alignment, Builder.RequiredAlignment,
+ Builder.HasOwnVFPtr, Builder.HasOwnVFPtr || Builder.PrimaryBase,
+ Builder.VBPtrOffset, Builder.NonVirtualSize,
+ Builder.FieldOffsets.data(), Builder.FieldOffsets.size(),
+ Builder.NonVirtualSize, Builder.Alignment, CharUnits::Zero(),
+ Builder.PrimaryBase, false, Builder.SharedVBPtrBase,
+ Builder.EndsWithZeroSizedObject, Builder.LeadsWithZeroSizedBase,
+ Builder.Bases, Builder.VBases);
+ } else {
+ Builder.layout(D);
+ NewEntry = new (*this) ASTRecordLayout(
+ *this, Builder.Size, Builder.Alignment, Builder.RequiredAlignment,
+ Builder.Size, Builder.FieldOffsets.data(),
+ Builder.FieldOffsets.size());
+ }
} else {
- RecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/nullptr);
- Builder.Layout(D);
-
- NewEntry =
- new (*this) ASTRecordLayout(*this, Builder.getSize(),
- Builder.Alignment,
- /*RequiredAlignment : used by MS-ABI)*/
- Builder.Alignment,
- Builder.getSize(),
- Builder.FieldOffsets.data(),
- Builder.FieldOffsets.size());
+ if (const auto *RD = dyn_cast<CXXRecordDecl>(D)) {
+ EmptySubobjectMap EmptySubobjects(*this, RD);
+ ItaniumRecordLayoutBuilder Builder(*this, &EmptySubobjects);
+ Builder.Layout(RD);
+
+ // In certain situations, we are allowed to lay out objects in the
+ // tail-padding of base classes. This is ABI-dependent.
+ // FIXME: this should be stored in the record layout.
+ bool skipTailPadding =
+ mustSkipTailPadding(getTargetInfo().getCXXABI(), RD);
+
+ // FIXME: This should be done in FinalizeLayout.
+ CharUnits DataSize =
+ skipTailPadding ? Builder.getSize() : Builder.getDataSize();
+ CharUnits NonVirtualSize =
+ skipTailPadding ? DataSize : Builder.NonVirtualSize;
+ NewEntry = new (*this) ASTRecordLayout(
+ *this, Builder.getSize(), Builder.Alignment,
+ /*RequiredAlignment : used by MS-ABI)*/
+ Builder.Alignment, Builder.HasOwnVFPtr, RD->isDynamicClass(),
+ CharUnits::fromQuantity(-1), DataSize, Builder.FieldOffsets.data(),
+ Builder.FieldOffsets.size(), NonVirtualSize,
+ Builder.NonVirtualAlignment,
+ EmptySubobjects.SizeOfLargestEmptySubobject, Builder.PrimaryBase,
+ Builder.PrimaryBaseIsVirtual, nullptr, false, false, Builder.Bases,
+ Builder.VBases);
+ } else {
+ ItaniumRecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/nullptr);
+ Builder.Layout(D);
+
+ NewEntry = new (*this) ASTRecordLayout(
+ *this, Builder.getSize(), Builder.Alignment,
+ /*RequiredAlignment : used by MS-ABI)*/
+ Builder.Alignment, Builder.getSize(), Builder.FieldOffsets.data(),
+ Builder.FieldOffsets.size());
+ }
}
ASTRecordLayouts[D] = NewEntry;
@@ -3049,7 +3065,7 @@ ASTContext::getObjCLayout(const ObjCInterfaceDecl *D,
return getObjCLayout(D, nullptr);
}
- RecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/nullptr);
+ ItaniumRecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/nullptr);
Builder.Layout(D);
const ASTRecordLayout *NewEntry =
@@ -3068,148 +3084,193 @@ ASTContext::getObjCLayout(const ObjCInterfaceDecl *D,
static void PrintOffset(raw_ostream &OS,
CharUnits Offset, unsigned IndentLevel) {
- OS << llvm::format("%4" PRId64 " | ", (int64_t)Offset.getQuantity());
+ OS << llvm::format("%10" PRId64 " | ", (int64_t)Offset.getQuantity());
+ OS.indent(IndentLevel * 2);
+}
+
+static void PrintBitFieldOffset(raw_ostream &OS, CharUnits Offset,
+ unsigned Begin, unsigned Width,
+ unsigned IndentLevel) {
+ llvm::SmallString<10> Buffer;
+ {
+ llvm::raw_svector_ostream BufferOS(Buffer);
+ BufferOS << Offset.getQuantity() << ':';
+ if (Width == 0) {
+ BufferOS << '-';
+ } else {
+ BufferOS << Begin << '-' << (Begin + Width - 1);
+ }
+ }
+
+ OS << llvm::right_justify(Buffer, 10) << " | ";
OS.indent(IndentLevel * 2);
}
static void PrintIndentNoOffset(raw_ostream &OS, unsigned IndentLevel) {
- OS << " | ";
+ OS << " | ";
OS.indent(IndentLevel * 2);
}
-static void DumpCXXRecordLayout(raw_ostream &OS,
- const CXXRecordDecl *RD, const ASTContext &C,
- CharUnits Offset,
- unsigned IndentLevel,
- const char* Description,
- bool IncludeVirtualBases) {
+static void DumpRecordLayout(raw_ostream &OS, const RecordDecl *RD,
+ const ASTContext &C,
+ CharUnits Offset,
+ unsigned IndentLevel,
+ const char* Description,
+ bool PrintSizeInfo,
+ bool IncludeVirtualBases) {
const ASTRecordLayout &Layout = C.getASTRecordLayout(RD);
+ auto CXXRD = dyn_cast<CXXRecordDecl>(RD);
PrintOffset(OS, Offset, IndentLevel);
- OS << C.getTypeDeclType(const_cast<CXXRecordDecl *>(RD)).getAsString();
+ OS << C.getTypeDeclType(const_cast<RecordDecl*>(RD)).getAsString();
if (Description)
OS << ' ' << Description;
- if (RD->isEmpty())
+ if (CXXRD && CXXRD->isEmpty())
OS << " (empty)";
OS << '\n';
IndentLevel++;
- const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
- bool HasOwnVFPtr = Layout.hasOwnVFPtr();
- bool HasOwnVBPtr = Layout.hasOwnVBPtr();
-
- // Vtable pointer.
- if (RD->isDynamicClass() && !PrimaryBase && !isMsLayout(RD)) {
- PrintOffset(OS, Offset, IndentLevel);
- OS << '(' << *RD << " vtable pointer)\n";
- } else if (HasOwnVFPtr) {
- PrintOffset(OS, Offset, IndentLevel);
- // vfptr (for Microsoft C++ ABI)
- OS << '(' << *RD << " vftable pointer)\n";
- }
-
- // Collect nvbases.
- SmallVector<const CXXRecordDecl *, 4> Bases;
- for (const CXXBaseSpecifier &Base : RD->bases()) {
- assert(!Base.getType()->isDependentType() &&
- "Cannot layout class with dependent bases.");
- if (!Base.isVirtual())
- Bases.push_back(Base.getType()->getAsCXXRecordDecl());
- }
+ // Dump bases.
+ if (CXXRD) {
+ const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
+ bool HasOwnVFPtr = Layout.hasOwnVFPtr();
+ bool HasOwnVBPtr = Layout.hasOwnVBPtr();
+
+ // Vtable pointer.
+ if (CXXRD->isDynamicClass() && !PrimaryBase && !isMsLayout(C)) {
+ PrintOffset(OS, Offset, IndentLevel);
+ OS << '(' << *RD << " vtable pointer)\n";
+ } else if (HasOwnVFPtr) {
+ PrintOffset(OS, Offset, IndentLevel);
+ // vfptr (for Microsoft C++ ABI)
+ OS << '(' << *RD << " vftable pointer)\n";
+ }
- // Sort nvbases by offset.
- std::stable_sort(Bases.begin(), Bases.end(),
- [&](const CXXRecordDecl *L, const CXXRecordDecl *R) {
- return Layout.getBaseClassOffset(L) < Layout.getBaseClassOffset(R);
- });
+ // Collect nvbases.
+ SmallVector<const CXXRecordDecl *, 4> Bases;
+ for (const CXXBaseSpecifier &Base : CXXRD->bases()) {
+ assert(!Base.getType()->isDependentType() &&
+ "Cannot layout class with dependent bases.");
+ if (!Base.isVirtual())
+ Bases.push_back(Base.getType()->getAsCXXRecordDecl());
+ }
- // Dump (non-virtual) bases
- for (const CXXRecordDecl *Base : Bases) {
- CharUnits BaseOffset = Offset + Layout.getBaseClassOffset(Base);
- DumpCXXRecordLayout(OS, Base, C, BaseOffset, IndentLevel,
- Base == PrimaryBase ? "(primary base)" : "(base)",
- /*IncludeVirtualBases=*/false);
- }
+ // Sort nvbases by offset.
+ std::stable_sort(Bases.begin(), Bases.end(),
+ [&](const CXXRecordDecl *L, const CXXRecordDecl *R) {
+ return Layout.getBaseClassOffset(L) < Layout.getBaseClassOffset(R);
+ });
+
+ // Dump (non-virtual) bases
+ for (const CXXRecordDecl *Base : Bases) {
+ CharUnits BaseOffset = Offset + Layout.getBaseClassOffset(Base);
+ DumpRecordLayout(OS, Base, C, BaseOffset, IndentLevel,
+ Base == PrimaryBase ? "(primary base)" : "(base)",
+ /*PrintSizeInfo=*/false,
+ /*IncludeVirtualBases=*/false);
+ }
- // vbptr (for Microsoft C++ ABI)
- if (HasOwnVBPtr) {
- PrintOffset(OS, Offset + Layout.getVBPtrOffset(), IndentLevel);
- OS << '(' << *RD << " vbtable pointer)\n";
+ // vbptr (for Microsoft C++ ABI)
+ if (HasOwnVBPtr) {
+ PrintOffset(OS, Offset + Layout.getVBPtrOffset(), IndentLevel);
+ OS << '(' << *RD << " vbtable pointer)\n";
+ }
}
// Dump fields.
uint64_t FieldNo = 0;
- for (CXXRecordDecl::field_iterator I = RD->field_begin(),
+ for (RecordDecl::field_iterator I = RD->field_begin(),
E = RD->field_end(); I != E; ++I, ++FieldNo) {
const FieldDecl &Field = **I;
- CharUnits FieldOffset = Offset +
- C.toCharUnitsFromBits(Layout.getFieldOffset(FieldNo));
-
- if (const CXXRecordDecl *D = Field.getType()->getAsCXXRecordDecl()) {
- DumpCXXRecordLayout(OS, D, C, FieldOffset, IndentLevel,
- Field.getName().data(),
- /*IncludeVirtualBases=*/true);
+ uint64_t LocalFieldOffsetInBits = Layout.getFieldOffset(FieldNo);
+ CharUnits FieldOffset =
+ Offset + C.toCharUnitsFromBits(LocalFieldOffsetInBits);
+
+ // Recursively dump fields of record type.
+ if (auto RT = Field.getType()->getAs<RecordType>()) {
+ DumpRecordLayout(OS, RT->getDecl(), C, FieldOffset, IndentLevel,
+ Field.getName().data(),
+ /*PrintSizeInfo=*/false,
+ /*IncludeVirtualBases=*/true);
continue;
}
- PrintOffset(OS, FieldOffset, IndentLevel);
+ if (Field.isBitField()) {
+ uint64_t LocalFieldByteOffsetInBits = C.toBits(FieldOffset - Offset);
+ unsigned Begin = LocalFieldOffsetInBits - LocalFieldByteOffsetInBits;
+ unsigned Width = Field.getBitWidthValue(C);
+ PrintBitFieldOffset(OS, FieldOffset, Begin, Width, IndentLevel);
+ } else {
+ PrintOffset(OS, FieldOffset, IndentLevel);
+ }
OS << Field.getType().getAsString() << ' ' << Field << '\n';
}
- if (!IncludeVirtualBases)
- return;
-
// Dump virtual bases.
- const ASTRecordLayout::VBaseOffsetsMapTy &vtordisps =
- Layout.getVBaseOffsetsMap();
- for (const CXXBaseSpecifier &Base : RD->vbases()) {
- assert(Base.isVirtual() && "Found non-virtual class!");
- const CXXRecordDecl *VBase = Base.getType()->getAsCXXRecordDecl();
+ if (CXXRD && IncludeVirtualBases) {
+ const ASTRecordLayout::VBaseOffsetsMapTy &VtorDisps =
+ Layout.getVBaseOffsetsMap();
- CharUnits VBaseOffset = Offset + Layout.getVBaseClassOffset(VBase);
+ for (const CXXBaseSpecifier &Base : CXXRD->vbases()) {
+ assert(Base.isVirtual() && "Found non-virtual class!");
+ const CXXRecordDecl *VBase = Base.getType()->getAsCXXRecordDecl();
- if (vtordisps.find(VBase)->second.hasVtorDisp()) {
- PrintOffset(OS, VBaseOffset - CharUnits::fromQuantity(4), IndentLevel);
- OS << "(vtordisp for vbase " << *VBase << ")\n";
- }
+ CharUnits VBaseOffset = Offset + Layout.getVBaseClassOffset(VBase);
+
+ if (VtorDisps.find(VBase)->second.hasVtorDisp()) {
+ PrintOffset(OS, VBaseOffset - CharUnits::fromQuantity(4), IndentLevel);
+ OS << "(vtordisp for vbase " << *VBase << ")\n";
+ }
- DumpCXXRecordLayout(OS, VBase, C, VBaseOffset, IndentLevel,
- VBase == PrimaryBase ?
- "(primary virtual base)" : "(virtual base)",
- /*IncludeVirtualBases=*/false);
+ DumpRecordLayout(OS, VBase, C, VBaseOffset, IndentLevel,
+ VBase == Layout.getPrimaryBase() ?
+ "(primary virtual base)" : "(virtual base)",
+ /*PrintSizeInfo=*/false,
+ /*IncludeVirtualBases=*/false);
+ }
}
+ if (!PrintSizeInfo) return;
+
PrintIndentNoOffset(OS, IndentLevel - 1);
OS << "[sizeof=" << Layout.getSize().getQuantity();
- if (!isMsLayout(RD))
+ if (CXXRD && !isMsLayout(C))
OS << ", dsize=" << Layout.getDataSize().getQuantity();
- OS << ", align=" << Layout.getAlignment().getQuantity() << '\n';
+ OS << ", align=" << Layout.getAlignment().getQuantity();
- PrintIndentNoOffset(OS, IndentLevel - 1);
- OS << " nvsize=" << Layout.getNonVirtualSize().getQuantity();
- OS << ", nvalign=" << Layout.getNonVirtualAlignment().getQuantity() << "]\n";
+ if (CXXRD) {
+ OS << ",\n";
+ PrintIndentNoOffset(OS, IndentLevel - 1);
+ OS << " nvsize=" << Layout.getNonVirtualSize().getQuantity();
+ OS << ", nvalign=" << Layout.getNonVirtualAlignment().getQuantity();
+ }
+ OS << "]\n";
}
void ASTContext::DumpRecordLayout(const RecordDecl *RD,
raw_ostream &OS,
bool Simple) const {
- const ASTRecordLayout &Info = getASTRecordLayout(RD);
+ if (!Simple) {
+ ::DumpRecordLayout(OS, RD, *this, CharUnits(), 0, nullptr,
+ /*PrintSizeInfo*/true,
+ /*IncludeVirtualBases=*/true);
+ return;
+ }
- if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
- if (!Simple)
- return DumpCXXRecordLayout(OS, CXXRD, *this, CharUnits(), 0, nullptr,
- /*IncludeVirtualBases=*/true);
+ // The "simple" format is designed to be parsed by the
+ // layout-override testing code. There shouldn't be any external
+ // uses of this format --- when LLDB overrides a layout, it sets up
+ // the data structures directly --- so feel free to adjust this as
+ // you like as long as you also update the rudimentary parser for it
+ // in libFrontend.
+ const ASTRecordLayout &Info = getASTRecordLayout(RD);
OS << "Type: " << getTypeDeclType(RD).getAsString() << "\n";
- if (!Simple) {
- OS << "Record: ";
- RD->dump();
- }
OS << "\nLayout: ";
OS << "<ASTRecordLayout\n";
OS << " Size:" << toBits(Info.getSize()) << "\n";
- if (!isMsLayout(RD))
+ if (!isMsLayout(*this))
OS << " DataSize:" << toBits(Info.getDataSize()) << "\n";
OS << " Alignment:" << toBits(Info.getAlignment()) << "\n";
OS << " FieldOffsets: [";
diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp
index e6292b495365..ca63d8486d82 100644
--- a/lib/AST/Stmt.cpp
+++ b/lib/AST/Stmt.cpp
@@ -15,6 +15,7 @@
#include "clang/AST/ASTDiagnostic.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
+#include "clang/AST/ExprOpenMP.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/StmtCXX.h"
#include "clang/AST/StmtObjC.h"
@@ -294,14 +295,15 @@ CompoundStmt::CompoundStmt(const ASTContext &C, ArrayRef<Stmt*> Stmts,
std::copy(Stmts.begin(), Stmts.end(), Body);
}
-void CompoundStmt::setStmts(const ASTContext &C, Stmt **Stmts,
- unsigned NumStmts) {
- if (this->Body)
+void CompoundStmt::setStmts(const ASTContext &C, ArrayRef<Stmt *> Stmts) {
+ if (Body)
C.Deallocate(Body);
- this->CompoundStmtBits.NumStmts = NumStmts;
+ CompoundStmtBits.NumStmts = Stmts.size();
+ assert(CompoundStmtBits.NumStmts == Stmts.size() &&
+ "NumStmts doesn't fit in bits of CompoundStmtBits.NumStmts!");
- Body = new (C) Stmt*[NumStmts];
- memcpy(Body, Stmts, sizeof(Stmt *) * NumStmts);
+ Body = new (C) Stmt*[Stmts.size()];
+ std::copy(Stmts.begin(), Stmts.end(), Body);
}
const char *LabelStmt::getName() const {
@@ -675,12 +677,6 @@ void MSAsmStmt::setInputExpr(unsigned i, Expr *E) {
Exprs[i + NumOutputs] = E;
}
-QualType CXXCatchStmt::getCaughtType() const {
- if (ExceptionDecl)
- return ExceptionDecl->getType();
- return QualType();
-}
-
//===----------------------------------------------------------------------===//
// Constructors
//===----------------------------------------------------------------------===//
@@ -724,12 +720,7 @@ MSAsmStmt::MSAsmStmt(const ASTContext &C, SourceLocation asmloc,
}
static StringRef copyIntoContext(const ASTContext &C, StringRef str) {
- if (str.empty())
- return StringRef();
- size_t size = str.size();
- char *buffer = new (C) char[size];
- memcpy(buffer, str.data(), size);
- return StringRef(buffer, size);
+ return str.copy(C);
}
void MSAsmStmt::initialize(const ASTContext &C, StringRef asmstr,
@@ -740,145 +731,29 @@ void MSAsmStmt::initialize(const ASTContext &C, StringRef asmstr,
assert(NumAsmToks == asmtoks.size());
assert(NumClobbers == clobbers.size());
- unsigned NumExprs = exprs.size();
- assert(NumExprs == NumOutputs + NumInputs);
- assert(NumExprs == constraints.size());
+ assert(exprs.size() == NumOutputs + NumInputs);
+ assert(exprs.size() == constraints.size());
AsmStr = copyIntoContext(C, asmstr);
- Exprs = new (C) Stmt*[NumExprs];
- for (unsigned i = 0, e = NumExprs; i != e; ++i)
- Exprs[i] = exprs[i];
+ Exprs = new (C) Stmt*[exprs.size()];
+ std::copy(exprs.begin(), exprs.end(), Exprs);
- AsmToks = new (C) Token[NumAsmToks];
- for (unsigned i = 0, e = NumAsmToks; i != e; ++i)
- AsmToks[i] = asmtoks[i];
+ AsmToks = new (C) Token[asmtoks.size()];
+ std::copy(asmtoks.begin(), asmtoks.end(), AsmToks);
- Constraints = new (C) StringRef[NumExprs];
- for (unsigned i = 0, e = NumExprs; i != e; ++i) {
- Constraints[i] = copyIntoContext(C, constraints[i]);
- }
+ Constraints = new (C) StringRef[exprs.size()];
+ std::transform(constraints.begin(), constraints.end(), Constraints,
+ [&](StringRef Constraint) {
+ return copyIntoContext(C, Constraint);
+ });
Clobbers = new (C) StringRef[NumClobbers];
- for (unsigned i = 0, e = NumClobbers; i != e; ++i) {
- // FIXME: Avoid the allocation/copy if at all possible.
- Clobbers[i] = copyIntoContext(C, clobbers[i]);
- }
-}
-
-ObjCForCollectionStmt::ObjCForCollectionStmt(Stmt *Elem, Expr *Collect,
- Stmt *Body, SourceLocation FCL,
- SourceLocation RPL)
-: Stmt(ObjCForCollectionStmtClass) {
- SubExprs[ELEM] = Elem;
- SubExprs[COLLECTION] = Collect;
- SubExprs[BODY] = Body;
- ForLoc = FCL;
- RParenLoc = RPL;
-}
-
-ObjCAtTryStmt::ObjCAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt,
- Stmt **CatchStmts, unsigned NumCatchStmts,
- Stmt *atFinallyStmt)
- : Stmt(ObjCAtTryStmtClass), AtTryLoc(atTryLoc),
- NumCatchStmts(NumCatchStmts), HasFinally(atFinallyStmt != nullptr) {
- Stmt **Stmts = getStmts();
- Stmts[0] = atTryStmt;
- for (unsigned I = 0; I != NumCatchStmts; ++I)
- Stmts[I + 1] = CatchStmts[I];
-
- if (HasFinally)
- Stmts[NumCatchStmts + 1] = atFinallyStmt;
-}
-
-ObjCAtTryStmt *ObjCAtTryStmt::Create(const ASTContext &Context,
- SourceLocation atTryLoc,
- Stmt *atTryStmt,
- Stmt **CatchStmts,
- unsigned NumCatchStmts,
- Stmt *atFinallyStmt) {
- unsigned Size = sizeof(ObjCAtTryStmt) +
- (1 + NumCatchStmts + (atFinallyStmt != nullptr)) * sizeof(Stmt *);
- void *Mem = Context.Allocate(Size, llvm::alignOf<ObjCAtTryStmt>());
- return new (Mem) ObjCAtTryStmt(atTryLoc, atTryStmt, CatchStmts, NumCatchStmts,
- atFinallyStmt);
-}
-
-ObjCAtTryStmt *ObjCAtTryStmt::CreateEmpty(const ASTContext &Context,
- unsigned NumCatchStmts,
- bool HasFinally) {
- unsigned Size = sizeof(ObjCAtTryStmt) +
- (1 + NumCatchStmts + HasFinally) * sizeof(Stmt *);
- void *Mem = Context.Allocate(Size, llvm::alignOf<ObjCAtTryStmt>());
- return new (Mem) ObjCAtTryStmt(EmptyShell(), NumCatchStmts, HasFinally);
-}
-
-SourceLocation ObjCAtTryStmt::getLocEnd() const {
- if (HasFinally)
- return getFinallyStmt()->getLocEnd();
- if (NumCatchStmts)
- return getCatchStmt(NumCatchStmts - 1)->getLocEnd();
- return getTryBody()->getLocEnd();
-}
-
-CXXTryStmt *CXXTryStmt::Create(const ASTContext &C, SourceLocation tryLoc,
- Stmt *tryBlock, ArrayRef<Stmt*> handlers) {
- std::size_t Size = sizeof(CXXTryStmt);
- Size += ((handlers.size() + 1) * sizeof(Stmt));
-
- void *Mem = C.Allocate(Size, llvm::alignOf<CXXTryStmt>());
- return new (Mem) CXXTryStmt(tryLoc, tryBlock, handlers);
-}
-
-CXXTryStmt *CXXTryStmt::Create(const ASTContext &C, EmptyShell Empty,
- unsigned numHandlers) {
- std::size_t Size = sizeof(CXXTryStmt);
- Size += ((numHandlers + 1) * sizeof(Stmt));
-
- void *Mem = C.Allocate(Size, llvm::alignOf<CXXTryStmt>());
- return new (Mem) CXXTryStmt(Empty, numHandlers);
-}
-
-CXXTryStmt::CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock,
- ArrayRef<Stmt*> handlers)
- : Stmt(CXXTryStmtClass), TryLoc(tryLoc), NumHandlers(handlers.size()) {
- Stmt **Stmts = reinterpret_cast<Stmt **>(this + 1);
- Stmts[0] = tryBlock;
- std::copy(handlers.begin(), handlers.end(), Stmts + 1);
-}
-
-CXXForRangeStmt::CXXForRangeStmt(DeclStmt *Range, DeclStmt *BeginEndStmt,
- Expr *Cond, Expr *Inc, DeclStmt *LoopVar,
- Stmt *Body, SourceLocation FL,
- SourceLocation CL, SourceLocation RPL)
- : Stmt(CXXForRangeStmtClass), ForLoc(FL), ColonLoc(CL), RParenLoc(RPL) {
- SubExprs[RANGE] = Range;
- SubExprs[BEGINEND] = BeginEndStmt;
- SubExprs[COND] = Cond;
- SubExprs[INC] = Inc;
- SubExprs[LOOPVAR] = LoopVar;
- SubExprs[BODY] = Body;
-}
-
-Expr *CXXForRangeStmt::getRangeInit() {
- DeclStmt *RangeStmt = getRangeStmt();
- VarDecl *RangeDecl = dyn_cast_or_null<VarDecl>(RangeStmt->getSingleDecl());
- assert(RangeDecl && "for-range should have a single var decl");
- return RangeDecl->getInit();
-}
-
-const Expr *CXXForRangeStmt::getRangeInit() const {
- return const_cast<CXXForRangeStmt*>(this)->getRangeInit();
-}
-
-VarDecl *CXXForRangeStmt::getLoopVariable() {
- Decl *LV = cast<DeclStmt>(getLoopVarStmt())->getSingleDecl();
- assert(LV && "No loop variable in CXXForRangeStmt");
- return cast<VarDecl>(LV);
-}
-
-const VarDecl *CXXForRangeStmt::getLoopVariable() const {
- return const_cast<CXXForRangeStmt*>(this)->getLoopVariable();
+ // FIXME: Avoid the allocation/copy if at all possible.
+ std::transform(clobbers.begin(), clobbers.end(), Clobbers,
+ [&](StringRef Clobber) {
+ return copyIntoContext(C, Clobber);
+ });
}
IfStmt::IfStmt(const ASTContext &C, SourceLocation IL, VarDecl *var, Expr *cond,
@@ -1070,6 +945,44 @@ SEHFinallyStmt* SEHFinallyStmt::Create(const ASTContext &C, SourceLocation Loc,
return new(C)SEHFinallyStmt(Loc,Block);
}
+CapturedStmt::Capture::Capture(SourceLocation Loc, VariableCaptureKind Kind,
+ VarDecl *Var)
+ : VarAndKind(Var, Kind), Loc(Loc) {
+ switch (Kind) {
+ case VCK_This:
+ assert(!Var && "'this' capture cannot have a variable!");
+ break;
+ case VCK_ByRef:
+ assert(Var && "capturing by reference must have a variable!");
+ break;
+ case VCK_ByCopy:
+ assert(Var && "capturing by copy must have a variable!");
+ assert(
+ (Var->getType()->isScalarType() || (Var->getType()->isReferenceType() &&
+ Var->getType()
+ ->castAs<ReferenceType>()
+ ->getPointeeType()
+ ->isScalarType())) &&
+ "captures by copy are expected to have a scalar type!");
+ break;
+ case VCK_VLAType:
+ assert(!Var &&
+ "Variable-length array type capture cannot have a variable!");
+ break;
+ }
+}
+
+CapturedStmt::VariableCaptureKind
+CapturedStmt::Capture::getCaptureKind() const {
+ return VarAndKind.getInt();
+}
+
+VarDecl *CapturedStmt::Capture::getCapturedVar() const {
+ assert((capturesVariable() || capturesVariableByCopy()) &&
+ "No variable available for 'this' or VAT capture");
+ return VarAndKind.getPointer();
+}
+
CapturedStmt::Capture *CapturedStmt::getStoredCaptures() const {
unsigned Size = sizeof(CapturedStmt) + sizeof(Stmt *) * (NumCaptures + 1);
@@ -1158,6 +1071,29 @@ Stmt::child_range CapturedStmt::children() {
return child_range(getStoredStmts(), getStoredStmts() + NumCaptures);
}
+CapturedDecl *CapturedStmt::getCapturedDecl() {
+ return CapDeclAndKind.getPointer();
+}
+const CapturedDecl *CapturedStmt::getCapturedDecl() const {
+ return CapDeclAndKind.getPointer();
+}
+
+/// \brief Set the outlined function declaration.
+void CapturedStmt::setCapturedDecl(CapturedDecl *D) {
+ assert(D && "null CapturedDecl");
+ CapDeclAndKind.setPointer(D);
+}
+
+/// \brief Retrieve the captured region kind.
+CapturedRegionKind CapturedStmt::getCapturedRegionKind() const {
+ return CapDeclAndKind.getInt();
+}
+
+/// \brief Set the captured region kind.
+void CapturedStmt::setCapturedRegionKind(CapturedRegionKind Kind) {
+ CapDeclAndKind.setInt(Kind);
+}
+
bool CapturedStmt::capturesVariable(const VarDecl *Var) const {
for (const auto &I : captures()) {
if (!I.capturesVariable())
@@ -1172,1095 +1108,3 @@ bool CapturedStmt::capturesVariable(const VarDecl *Var) const {
return false;
}
-
-StmtRange OMPClause::children() {
- switch(getClauseKind()) {
- default : break;
-#define OPENMP_CLAUSE(Name, Class) \
- case OMPC_ ## Name : return static_cast<Class *>(this)->children();
-#include "clang/Basic/OpenMPKinds.def"
- }
- llvm_unreachable("unknown OMPClause");
-}
-
-void OMPPrivateClause::setPrivateCopies(ArrayRef<Expr *> VL) {
- assert(VL.size() == varlist_size() &&
- "Number of private copies is not the same as the preallocated buffer");
- std::copy(VL.begin(), VL.end(), varlist_end());
-}
-
-OMPPrivateClause *
-OMPPrivateClause::Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc,
- ArrayRef<Expr *> VL, ArrayRef<Expr *> PrivateVL) {
- // Allocate space for private variables and initializer expressions.
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPPrivateClause),
- llvm::alignOf<Expr *>()) +
- 2 * sizeof(Expr *) * VL.size());
- OMPPrivateClause *Clause =
- new (Mem) OMPPrivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
- Clause->setVarRefs(VL);
- Clause->setPrivateCopies(PrivateVL);
- return Clause;
-}
-
-OMPPrivateClause *OMPPrivateClause::CreateEmpty(const ASTContext &C,
- unsigned N) {
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPPrivateClause),
- llvm::alignOf<Expr *>()) +
- 2 * sizeof(Expr *) * N);
- return new (Mem) OMPPrivateClause(N);
-}
-
-void OMPFirstprivateClause::setPrivateCopies(ArrayRef<Expr *> VL) {
- assert(VL.size() == varlist_size() &&
- "Number of private copies is not the same as the preallocated buffer");
- std::copy(VL.begin(), VL.end(), varlist_end());
-}
-
-void OMPFirstprivateClause::setInits(ArrayRef<Expr *> VL) {
- assert(VL.size() == varlist_size() &&
- "Number of inits is not the same as the preallocated buffer");
- std::copy(VL.begin(), VL.end(), getPrivateCopies().end());
-}
-
-OMPFirstprivateClause *
-OMPFirstprivateClause::Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc,
- ArrayRef<Expr *> VL, ArrayRef<Expr *> PrivateVL,
- ArrayRef<Expr *> InitVL) {
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPFirstprivateClause),
- llvm::alignOf<Expr *>()) +
- 3 * sizeof(Expr *) * VL.size());
- OMPFirstprivateClause *Clause =
- new (Mem) OMPFirstprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
- Clause->setVarRefs(VL);
- Clause->setPrivateCopies(PrivateVL);
- Clause->setInits(InitVL);
- return Clause;
-}
-
-OMPFirstprivateClause *OMPFirstprivateClause::CreateEmpty(const ASTContext &C,
- unsigned N) {
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPFirstprivateClause),
- llvm::alignOf<Expr *>()) +
- 3 * sizeof(Expr *) * N);
- return new (Mem) OMPFirstprivateClause(N);
-}
-
-void OMPLastprivateClause::setPrivateCopies(ArrayRef<Expr *> PrivateCopies) {
- assert(PrivateCopies.size() == varlist_size() &&
- "Number of private copies is not the same as the preallocated buffer");
- std::copy(PrivateCopies.begin(), PrivateCopies.end(), varlist_end());
-}
-
-void OMPLastprivateClause::setSourceExprs(ArrayRef<Expr *> SrcExprs) {
- assert(SrcExprs.size() == varlist_size() && "Number of source expressions is "
- "not the same as the "
- "preallocated buffer");
- std::copy(SrcExprs.begin(), SrcExprs.end(), getPrivateCopies().end());
-}
-
-void OMPLastprivateClause::setDestinationExprs(ArrayRef<Expr *> DstExprs) {
- assert(DstExprs.size() == varlist_size() && "Number of destination "
- "expressions is not the same as "
- "the preallocated buffer");
- std::copy(DstExprs.begin(), DstExprs.end(), getSourceExprs().end());
-}
-
-void OMPLastprivateClause::setAssignmentOps(ArrayRef<Expr *> AssignmentOps) {
- assert(AssignmentOps.size() == varlist_size() &&
- "Number of assignment expressions is not the same as the preallocated "
- "buffer");
- std::copy(AssignmentOps.begin(), AssignmentOps.end(),
- getDestinationExprs().end());
-}
-
-OMPLastprivateClause *OMPLastprivateClause::Create(
- const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
- ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps) {
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPLastprivateClause),
- llvm::alignOf<Expr *>()) +
- 5 * sizeof(Expr *) * VL.size());
- OMPLastprivateClause *Clause =
- new (Mem) OMPLastprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
- Clause->setVarRefs(VL);
- Clause->setSourceExprs(SrcExprs);
- Clause->setDestinationExprs(DstExprs);
- Clause->setAssignmentOps(AssignmentOps);
- return Clause;
-}
-
-OMPLastprivateClause *OMPLastprivateClause::CreateEmpty(const ASTContext &C,
- unsigned N) {
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPLastprivateClause),
- llvm::alignOf<Expr *>()) +
- 5 * sizeof(Expr *) * N);
- return new (Mem) OMPLastprivateClause(N);
-}
-
-OMPSharedClause *OMPSharedClause::Create(const ASTContext &C,
- SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc,
- ArrayRef<Expr *> VL) {
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPSharedClause),
- llvm::alignOf<Expr *>()) +
- sizeof(Expr *) * VL.size());
- OMPSharedClause *Clause = new (Mem) OMPSharedClause(StartLoc, LParenLoc,
- EndLoc, VL.size());
- Clause->setVarRefs(VL);
- return Clause;
-}
-
-OMPSharedClause *OMPSharedClause::CreateEmpty(const ASTContext &C,
- unsigned N) {
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPSharedClause),
- llvm::alignOf<Expr *>()) +
- sizeof(Expr *) * N);
- return new (Mem) OMPSharedClause(N);
-}
-
-void OMPLinearClause::setInits(ArrayRef<Expr *> IL) {
- assert(IL.size() == varlist_size() &&
- "Number of inits is not the same as the preallocated buffer");
- std::copy(IL.begin(), IL.end(), varlist_end());
-}
-
-void OMPLinearClause::setUpdates(ArrayRef<Expr *> UL) {
- assert(UL.size() == varlist_size() &&
- "Number of updates is not the same as the preallocated buffer");
- std::copy(UL.begin(), UL.end(), getInits().end());
-}
-
-void OMPLinearClause::setFinals(ArrayRef<Expr *> FL) {
- assert(FL.size() == varlist_size() &&
- "Number of final updates is not the same as the preallocated buffer");
- std::copy(FL.begin(), FL.end(), getUpdates().end());
-}
-
-OMPLinearClause *
-OMPLinearClause::Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation ColonLoc,
- SourceLocation EndLoc, ArrayRef<Expr *> VL,
- ArrayRef<Expr *> IL, Expr *Step, Expr *CalcStep) {
- // Allocate space for 4 lists (Vars, Inits, Updates, Finals) and 2 expressions
- // (Step and CalcStep).
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPLinearClause),
- llvm::alignOf<Expr *>()) +
- (4 * VL.size() + 2) * sizeof(Expr *));
- OMPLinearClause *Clause = new (Mem)
- OMPLinearClause(StartLoc, LParenLoc, ColonLoc, EndLoc, VL.size());
- Clause->setVarRefs(VL);
- Clause->setInits(IL);
- // Fill update and final expressions with zeroes, they are provided later,
- // after the directive construction.
- std::fill(Clause->getInits().end(), Clause->getInits().end() + VL.size(),
- nullptr);
- std::fill(Clause->getUpdates().end(), Clause->getUpdates().end() + VL.size(),
- nullptr);
- Clause->setStep(Step);
- Clause->setCalcStep(CalcStep);
- return Clause;
-}
-
-OMPLinearClause *OMPLinearClause::CreateEmpty(const ASTContext &C,
- unsigned NumVars) {
- // Allocate space for 4 lists (Vars, Inits, Updates, Finals) and 2 expressions
- // (Step and CalcStep).
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPLinearClause),
- llvm::alignOf<Expr *>()) +
- (4 * NumVars + 2) * sizeof(Expr *));
- return new (Mem) OMPLinearClause(NumVars);
-}
-
-OMPAlignedClause *
-OMPAlignedClause::Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation ColonLoc,
- SourceLocation EndLoc, ArrayRef<Expr *> VL, Expr *A) {
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPAlignedClause),
- llvm::alignOf<Expr *>()) +
- sizeof(Expr *) * (VL.size() + 1));
- OMPAlignedClause *Clause = new (Mem)
- OMPAlignedClause(StartLoc, LParenLoc, ColonLoc, EndLoc, VL.size());
- Clause->setVarRefs(VL);
- Clause->setAlignment(A);
- return Clause;
-}
-
-OMPAlignedClause *OMPAlignedClause::CreateEmpty(const ASTContext &C,
- unsigned NumVars) {
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPAlignedClause),
- llvm::alignOf<Expr *>()) +
- sizeof(Expr *) * (NumVars + 1));
- return new (Mem) OMPAlignedClause(NumVars);
-}
-
-void OMPCopyinClause::setSourceExprs(ArrayRef<Expr *> SrcExprs) {
- assert(SrcExprs.size() == varlist_size() && "Number of source expressions is "
- "not the same as the "
- "preallocated buffer");
- std::copy(SrcExprs.begin(), SrcExprs.end(), varlist_end());
-}
-
-void OMPCopyinClause::setDestinationExprs(ArrayRef<Expr *> DstExprs) {
- assert(DstExprs.size() == varlist_size() && "Number of destination "
- "expressions is not the same as "
- "the preallocated buffer");
- std::copy(DstExprs.begin(), DstExprs.end(), getSourceExprs().end());
-}
-
-void OMPCopyinClause::setAssignmentOps(ArrayRef<Expr *> AssignmentOps) {
- assert(AssignmentOps.size() == varlist_size() &&
- "Number of assignment expressions is not the same as the preallocated "
- "buffer");
- std::copy(AssignmentOps.begin(), AssignmentOps.end(),
- getDestinationExprs().end());
-}
-
-OMPCopyinClause *OMPCopyinClause::Create(
- const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
- ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps) {
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPCopyinClause),
- llvm::alignOf<Expr *>()) +
- 4 * sizeof(Expr *) * VL.size());
- OMPCopyinClause *Clause = new (Mem) OMPCopyinClause(StartLoc, LParenLoc,
- EndLoc, VL.size());
- Clause->setVarRefs(VL);
- Clause->setSourceExprs(SrcExprs);
- Clause->setDestinationExprs(DstExprs);
- Clause->setAssignmentOps(AssignmentOps);
- return Clause;
-}
-
-OMPCopyinClause *OMPCopyinClause::CreateEmpty(const ASTContext &C,
- unsigned N) {
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPCopyinClause),
- llvm::alignOf<Expr *>()) +
- 4 * sizeof(Expr *) * N);
- return new (Mem) OMPCopyinClause(N);
-}
-
-void OMPCopyprivateClause::setSourceExprs(ArrayRef<Expr *> SrcExprs) {
- assert(SrcExprs.size() == varlist_size() && "Number of source expressions is "
- "not the same as the "
- "preallocated buffer");
- std::copy(SrcExprs.begin(), SrcExprs.end(), varlist_end());
-}
-
-void OMPCopyprivateClause::setDestinationExprs(ArrayRef<Expr *> DstExprs) {
- assert(DstExprs.size() == varlist_size() && "Number of destination "
- "expressions is not the same as "
- "the preallocated buffer");
- std::copy(DstExprs.begin(), DstExprs.end(), getSourceExprs().end());
-}
-
-void OMPCopyprivateClause::setAssignmentOps(ArrayRef<Expr *> AssignmentOps) {
- assert(AssignmentOps.size() == varlist_size() &&
- "Number of assignment expressions is not the same as the preallocated "
- "buffer");
- std::copy(AssignmentOps.begin(), AssignmentOps.end(),
- getDestinationExprs().end());
-}
-
-OMPCopyprivateClause *OMPCopyprivateClause::Create(
- const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
- ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps) {
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPCopyprivateClause),
- llvm::alignOf<Expr *>()) +
- 4 * sizeof(Expr *) * VL.size());
- OMPCopyprivateClause *Clause =
- new (Mem) OMPCopyprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
- Clause->setVarRefs(VL);
- Clause->setSourceExprs(SrcExprs);
- Clause->setDestinationExprs(DstExprs);
- Clause->setAssignmentOps(AssignmentOps);
- return Clause;
-}
-
-OMPCopyprivateClause *OMPCopyprivateClause::CreateEmpty(const ASTContext &C,
- unsigned N) {
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPCopyprivateClause),
- llvm::alignOf<Expr *>()) +
- 4 * sizeof(Expr *) * N);
- return new (Mem) OMPCopyprivateClause(N);
-}
-
-void OMPExecutableDirective::setClauses(ArrayRef<OMPClause *> Clauses) {
- assert(Clauses.size() == getNumClauses() &&
- "Number of clauses is not the same as the preallocated buffer");
- std::copy(Clauses.begin(), Clauses.end(), getClauses().begin());
-}
-
-void OMPLoopDirective::setCounters(ArrayRef<Expr *> A) {
- assert(A.size() == getCollapsedNumber() &&
- "Number of loop counters is not the same as the collapsed number");
- std::copy(A.begin(), A.end(), getCounters().begin());
-}
-
-void OMPLoopDirective::setInits(ArrayRef<Expr *> A) {
- assert(A.size() == getCollapsedNumber() &&
- "Number of counter inits is not the same as the collapsed number");
- std::copy(A.begin(), A.end(), getInits().begin());
-}
-
-void OMPLoopDirective::setUpdates(ArrayRef<Expr *> A) {
- assert(A.size() == getCollapsedNumber() &&
- "Number of counter updates is not the same as the collapsed number");
- std::copy(A.begin(), A.end(), getUpdates().begin());
-}
-
-void OMPLoopDirective::setFinals(ArrayRef<Expr *> A) {
- assert(A.size() == getCollapsedNumber() &&
- "Number of counter finals is not the same as the collapsed number");
- std::copy(A.begin(), A.end(), getFinals().begin());
-}
-
-void OMPReductionClause::setLHSExprs(ArrayRef<Expr *> LHSExprs) {
- assert(
- LHSExprs.size() == varlist_size() &&
- "Number of LHS expressions is not the same as the preallocated buffer");
- std::copy(LHSExprs.begin(), LHSExprs.end(), varlist_end());
-}
-
-void OMPReductionClause::setRHSExprs(ArrayRef<Expr *> RHSExprs) {
- assert(
- RHSExprs.size() == varlist_size() &&
- "Number of RHS expressions is not the same as the preallocated buffer");
- std::copy(RHSExprs.begin(), RHSExprs.end(), getLHSExprs().end());
-}
-
-void OMPReductionClause::setReductionOps(ArrayRef<Expr *> ReductionOps) {
- assert(ReductionOps.size() == varlist_size() && "Number of reduction "
- "expressions is not the same "
- "as the preallocated buffer");
- std::copy(ReductionOps.begin(), ReductionOps.end(), getRHSExprs().end());
-}
-
-OMPReductionClause *OMPReductionClause::Create(
- const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL,
- NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
- ArrayRef<Expr *> LHSExprs, ArrayRef<Expr *> RHSExprs,
- ArrayRef<Expr *> ReductionOps) {
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPReductionClause),
- llvm::alignOf<Expr *>()) +
- 4 * sizeof(Expr *) * VL.size());
- OMPReductionClause *Clause = new (Mem) OMPReductionClause(
- StartLoc, LParenLoc, EndLoc, ColonLoc, VL.size(), QualifierLoc, NameInfo);
- Clause->setVarRefs(VL);
- Clause->setLHSExprs(LHSExprs);
- Clause->setRHSExprs(RHSExprs);
- Clause->setReductionOps(ReductionOps);
- return Clause;
-}
-
-OMPReductionClause *OMPReductionClause::CreateEmpty(const ASTContext &C,
- unsigned N) {
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPReductionClause),
- llvm::alignOf<Expr *>()) +
- 4 * sizeof(Expr *) * N);
- return new (Mem) OMPReductionClause(N);
-}
-
-OMPFlushClause *OMPFlushClause::Create(const ASTContext &C,
- SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc,
- ArrayRef<Expr *> VL) {
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPFlushClause),
- llvm::alignOf<Expr *>()) +
- sizeof(Expr *) * VL.size());
- OMPFlushClause *Clause =
- new (Mem) OMPFlushClause(StartLoc, LParenLoc, EndLoc, VL.size());
- Clause->setVarRefs(VL);
- return Clause;
-}
-
-OMPFlushClause *OMPFlushClause::CreateEmpty(const ASTContext &C, unsigned N) {
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPFlushClause),
- llvm::alignOf<Expr *>()) +
- sizeof(Expr *) * N);
- return new (Mem) OMPFlushClause(N);
-}
-
-OMPDependClause *
-OMPDependClause::Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc,
- OpenMPDependClauseKind DepKind, SourceLocation DepLoc,
- SourceLocation ColonLoc, ArrayRef<Expr *> VL) {
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPDependClause),
- llvm::alignOf<Expr *>()) +
- sizeof(Expr *) * VL.size());
- OMPDependClause *Clause =
- new (Mem) OMPDependClause(StartLoc, LParenLoc, EndLoc, VL.size());
- Clause->setVarRefs(VL);
- Clause->setDependencyKind(DepKind);
- Clause->setDependencyLoc(DepLoc);
- Clause->setColonLoc(ColonLoc);
- return Clause;
-}
-
-OMPDependClause *OMPDependClause::CreateEmpty(const ASTContext &C, unsigned N) {
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPDependClause),
- llvm::alignOf<Expr *>()) +
- sizeof(Expr *) * N);
- return new (Mem) OMPDependClause(N);
-}
-
-const OMPClause *
-OMPExecutableDirective::getSingleClause(OpenMPClauseKind K) const {
- auto &&I = getClausesOfKind(K);
-
- if (I) {
- auto *Clause = *I;
- assert(!++I && "There are at least 2 clauses of the specified kind");
- return Clause;
- }
- return nullptr;
-}
-
-OMPParallelDirective *OMPParallelDirective::Create(
- const ASTContext &C,
- SourceLocation StartLoc,
- SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelDirective),
- llvm::alignOf<OMPClause *>());
- void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() +
- sizeof(Stmt *));
- OMPParallelDirective *Dir = new (Mem) OMPParallelDirective(StartLoc, EndLoc,
- Clauses.size());
- Dir->setClauses(Clauses);
- Dir->setAssociatedStmt(AssociatedStmt);
- return Dir;
-}
-
-OMPParallelDirective *OMPParallelDirective::CreateEmpty(const ASTContext &C,
- unsigned NumClauses,
- EmptyShell) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelDirective),
- llvm::alignOf<OMPClause *>());
- void *Mem = C.Allocate(Size + sizeof(OMPClause *) * NumClauses +
- sizeof(Stmt *));
- return new (Mem) OMPParallelDirective(NumClauses);
-}
-
-OMPSimdDirective *
-OMPSimdDirective::Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation EndLoc, unsigned CollapsedNum,
- ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
- const HelperExprs &Exprs) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSimdDirective),
- llvm::alignOf<OMPClause *>());
- void *Mem =
- C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() +
- sizeof(Stmt *) * numLoopChildren(CollapsedNum, OMPD_simd));
- OMPSimdDirective *Dir = new (Mem)
- OMPSimdDirective(StartLoc, EndLoc, CollapsedNum, Clauses.size());
- Dir->setClauses(Clauses);
- Dir->setAssociatedStmt(AssociatedStmt);
- Dir->setIterationVariable(Exprs.IterationVarRef);
- Dir->setLastIteration(Exprs.LastIteration);
- Dir->setCalcLastIteration(Exprs.CalcLastIteration);
- Dir->setPreCond(Exprs.PreCond);
- Dir->setCond(Exprs.Cond);
- Dir->setInit(Exprs.Init);
- Dir->setInc(Exprs.Inc);
- Dir->setCounters(Exprs.Counters);
- Dir->setInits(Exprs.Inits);
- Dir->setUpdates(Exprs.Updates);
- Dir->setFinals(Exprs.Finals);
- return Dir;
-}
-
-OMPSimdDirective *OMPSimdDirective::CreateEmpty(const ASTContext &C,
- unsigned NumClauses,
- unsigned CollapsedNum,
- EmptyShell) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSimdDirective),
- llvm::alignOf<OMPClause *>());
- void *Mem =
- C.Allocate(Size + sizeof(OMPClause *) * NumClauses +
- sizeof(Stmt *) * numLoopChildren(CollapsedNum, OMPD_simd));
- return new (Mem) OMPSimdDirective(CollapsedNum, NumClauses);
-}
-
-OMPForDirective *
-OMPForDirective::Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation EndLoc, unsigned CollapsedNum,
- ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
- const HelperExprs &Exprs) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPForDirective),
- llvm::alignOf<OMPClause *>());
- void *Mem =
- C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() +
- sizeof(Stmt *) * numLoopChildren(CollapsedNum, OMPD_for));
- OMPForDirective *Dir =
- new (Mem) OMPForDirective(StartLoc, EndLoc, CollapsedNum, Clauses.size());
- Dir->setClauses(Clauses);
- Dir->setAssociatedStmt(AssociatedStmt);
- Dir->setIterationVariable(Exprs.IterationVarRef);
- Dir->setLastIteration(Exprs.LastIteration);
- Dir->setCalcLastIteration(Exprs.CalcLastIteration);
- Dir->setPreCond(Exprs.PreCond);
- Dir->setCond(Exprs.Cond);
- Dir->setInit(Exprs.Init);
- Dir->setInc(Exprs.Inc);
- Dir->setIsLastIterVariable(Exprs.IL);
- Dir->setLowerBoundVariable(Exprs.LB);
- Dir->setUpperBoundVariable(Exprs.UB);
- Dir->setStrideVariable(Exprs.ST);
- Dir->setEnsureUpperBound(Exprs.EUB);
- Dir->setNextLowerBound(Exprs.NLB);
- Dir->setNextUpperBound(Exprs.NUB);
- Dir->setCounters(Exprs.Counters);
- Dir->setInits(Exprs.Inits);
- Dir->setUpdates(Exprs.Updates);
- Dir->setFinals(Exprs.Finals);
- return Dir;
-}
-
-OMPForDirective *OMPForDirective::CreateEmpty(const ASTContext &C,
- unsigned NumClauses,
- unsigned CollapsedNum,
- EmptyShell) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPForDirective),
- llvm::alignOf<OMPClause *>());
- void *Mem =
- C.Allocate(Size + sizeof(OMPClause *) * NumClauses +
- sizeof(Stmt *) * numLoopChildren(CollapsedNum, OMPD_for));
- return new (Mem) OMPForDirective(CollapsedNum, NumClauses);
-}
-
-OMPForSimdDirective *
-OMPForSimdDirective::Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation EndLoc, unsigned CollapsedNum,
- ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
- const HelperExprs &Exprs) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPForSimdDirective),
- llvm::alignOf<OMPClause *>());
- void *Mem =
- C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() +
- sizeof(Stmt *) * numLoopChildren(CollapsedNum, OMPD_for_simd));
- OMPForSimdDirective *Dir = new (Mem)
- OMPForSimdDirective(StartLoc, EndLoc, CollapsedNum, Clauses.size());
- Dir->setClauses(Clauses);
- Dir->setAssociatedStmt(AssociatedStmt);
- Dir->setIterationVariable(Exprs.IterationVarRef);
- Dir->setLastIteration(Exprs.LastIteration);
- Dir->setCalcLastIteration(Exprs.CalcLastIteration);
- Dir->setPreCond(Exprs.PreCond);
- Dir->setCond(Exprs.Cond);
- Dir->setInit(Exprs.Init);
- Dir->setInc(Exprs.Inc);
- Dir->setIsLastIterVariable(Exprs.IL);
- Dir->setLowerBoundVariable(Exprs.LB);
- Dir->setUpperBoundVariable(Exprs.UB);
- Dir->setStrideVariable(Exprs.ST);
- Dir->setEnsureUpperBound(Exprs.EUB);
- Dir->setNextLowerBound(Exprs.NLB);
- Dir->setNextUpperBound(Exprs.NUB);
- Dir->setCounters(Exprs.Counters);
- Dir->setInits(Exprs.Inits);
- Dir->setUpdates(Exprs.Updates);
- Dir->setFinals(Exprs.Finals);
- return Dir;
-}
-
-OMPForSimdDirective *OMPForSimdDirective::CreateEmpty(const ASTContext &C,
- unsigned NumClauses,
- unsigned CollapsedNum,
- EmptyShell) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPForSimdDirective),
- llvm::alignOf<OMPClause *>());
- void *Mem =
- C.Allocate(Size + sizeof(OMPClause *) * NumClauses +
- sizeof(Stmt *) * numLoopChildren(CollapsedNum, OMPD_for_simd));
- return new (Mem) OMPForSimdDirective(CollapsedNum, NumClauses);
-}
-
-OMPSectionsDirective *OMPSectionsDirective::Create(
- const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSectionsDirective),
- llvm::alignOf<OMPClause *>());
- void *Mem =
- C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
- OMPSectionsDirective *Dir =
- new (Mem) OMPSectionsDirective(StartLoc, EndLoc, Clauses.size());
- Dir->setClauses(Clauses);
- Dir->setAssociatedStmt(AssociatedStmt);
- return Dir;
-}
-
-OMPSectionsDirective *OMPSectionsDirective::CreateEmpty(const ASTContext &C,
- unsigned NumClauses,
- EmptyShell) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSectionsDirective),
- llvm::alignOf<OMPClause *>());
- void *Mem =
- C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
- return new (Mem) OMPSectionsDirective(NumClauses);
-}
-
-OMPSectionDirective *OMPSectionDirective::Create(const ASTContext &C,
- SourceLocation StartLoc,
- SourceLocation EndLoc,
- Stmt *AssociatedStmt) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSectionDirective),
- llvm::alignOf<Stmt *>());
- void *Mem = C.Allocate(Size + sizeof(Stmt *));
- OMPSectionDirective *Dir = new (Mem) OMPSectionDirective(StartLoc, EndLoc);
- Dir->setAssociatedStmt(AssociatedStmt);
- return Dir;
-}
-
-OMPSectionDirective *OMPSectionDirective::CreateEmpty(const ASTContext &C,
- EmptyShell) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSectionDirective),
- llvm::alignOf<Stmt *>());
- void *Mem = C.Allocate(Size + sizeof(Stmt *));
- return new (Mem) OMPSectionDirective();
-}
-
-OMPSingleDirective *OMPSingleDirective::Create(const ASTContext &C,
- SourceLocation StartLoc,
- SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSingleDirective),
- llvm::alignOf<OMPClause *>());
- void *Mem =
- C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
- OMPSingleDirective *Dir =
- new (Mem) OMPSingleDirective(StartLoc, EndLoc, Clauses.size());
- Dir->setClauses(Clauses);
- Dir->setAssociatedStmt(AssociatedStmt);
- return Dir;
-}
-
-OMPSingleDirective *OMPSingleDirective::CreateEmpty(const ASTContext &C,
- unsigned NumClauses,
- EmptyShell) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSingleDirective),
- llvm::alignOf<OMPClause *>());
- void *Mem =
- C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
- return new (Mem) OMPSingleDirective(NumClauses);
-}
-
-OMPMasterDirective *OMPMasterDirective::Create(const ASTContext &C,
- SourceLocation StartLoc,
- SourceLocation EndLoc,
- Stmt *AssociatedStmt) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPMasterDirective),
- llvm::alignOf<Stmt *>());
- void *Mem = C.Allocate(Size + sizeof(Stmt *));
- OMPMasterDirective *Dir = new (Mem) OMPMasterDirective(StartLoc, EndLoc);
- Dir->setAssociatedStmt(AssociatedStmt);
- return Dir;
-}
-
-OMPMasterDirective *OMPMasterDirective::CreateEmpty(const ASTContext &C,
- EmptyShell) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPMasterDirective),
- llvm::alignOf<Stmt *>());
- void *Mem = C.Allocate(Size + sizeof(Stmt *));
- return new (Mem) OMPMasterDirective();
-}
-
-OMPCriticalDirective *OMPCriticalDirective::Create(
- const ASTContext &C, const DeclarationNameInfo &Name,
- SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPCriticalDirective),
- llvm::alignOf<Stmt *>());
- void *Mem = C.Allocate(Size + sizeof(Stmt *));
- OMPCriticalDirective *Dir =
- new (Mem) OMPCriticalDirective(Name, StartLoc, EndLoc);
- Dir->setAssociatedStmt(AssociatedStmt);
- return Dir;
-}
-
-OMPCriticalDirective *OMPCriticalDirective::CreateEmpty(const ASTContext &C,
- EmptyShell) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPCriticalDirective),
- llvm::alignOf<Stmt *>());
- void *Mem = C.Allocate(Size + sizeof(Stmt *));
- return new (Mem) OMPCriticalDirective();
-}
-
-OMPParallelForDirective *OMPParallelForDirective::Create(
- const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
- const HelperExprs &Exprs) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelForDirective),
- llvm::alignOf<OMPClause *>());
- void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() +
- sizeof(Stmt *) *
- numLoopChildren(CollapsedNum, OMPD_parallel_for));
- OMPParallelForDirective *Dir = new (Mem)
- OMPParallelForDirective(StartLoc, EndLoc, CollapsedNum, Clauses.size());
- Dir->setClauses(Clauses);
- Dir->setAssociatedStmt(AssociatedStmt);
- Dir->setIterationVariable(Exprs.IterationVarRef);
- Dir->setLastIteration(Exprs.LastIteration);
- Dir->setCalcLastIteration(Exprs.CalcLastIteration);
- Dir->setPreCond(Exprs.PreCond);
- Dir->setCond(Exprs.Cond);
- Dir->setInit(Exprs.Init);
- Dir->setInc(Exprs.Inc);
- Dir->setIsLastIterVariable(Exprs.IL);
- Dir->setLowerBoundVariable(Exprs.LB);
- Dir->setUpperBoundVariable(Exprs.UB);
- Dir->setStrideVariable(Exprs.ST);
- Dir->setEnsureUpperBound(Exprs.EUB);
- Dir->setNextLowerBound(Exprs.NLB);
- Dir->setNextUpperBound(Exprs.NUB);
- Dir->setCounters(Exprs.Counters);
- Dir->setInits(Exprs.Inits);
- Dir->setUpdates(Exprs.Updates);
- Dir->setFinals(Exprs.Finals);
- return Dir;
-}
-
-OMPParallelForDirective *
-OMPParallelForDirective::CreateEmpty(const ASTContext &C, unsigned NumClauses,
- unsigned CollapsedNum, EmptyShell) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelForDirective),
- llvm::alignOf<OMPClause *>());
- void *Mem = C.Allocate(Size + sizeof(OMPClause *) * NumClauses +
- sizeof(Stmt *) *
- numLoopChildren(CollapsedNum, OMPD_parallel_for));
- return new (Mem) OMPParallelForDirective(CollapsedNum, NumClauses);
-}
-
-OMPParallelForSimdDirective *OMPParallelForSimdDirective::Create(
- const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
- const HelperExprs &Exprs) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelForSimdDirective),
- llvm::alignOf<OMPClause *>());
- void *Mem = C.Allocate(
- Size + sizeof(OMPClause *) * Clauses.size() +
- sizeof(Stmt *) * numLoopChildren(CollapsedNum, OMPD_parallel_for_simd));
- OMPParallelForSimdDirective *Dir = new (Mem) OMPParallelForSimdDirective(
- StartLoc, EndLoc, CollapsedNum, Clauses.size());
- Dir->setClauses(Clauses);
- Dir->setAssociatedStmt(AssociatedStmt);
- Dir->setIterationVariable(Exprs.IterationVarRef);
- Dir->setLastIteration(Exprs.LastIteration);
- Dir->setCalcLastIteration(Exprs.CalcLastIteration);
- Dir->setPreCond(Exprs.PreCond);
- Dir->setCond(Exprs.Cond);
- Dir->setInit(Exprs.Init);
- Dir->setInc(Exprs.Inc);
- Dir->setIsLastIterVariable(Exprs.IL);
- Dir->setLowerBoundVariable(Exprs.LB);
- Dir->setUpperBoundVariable(Exprs.UB);
- Dir->setStrideVariable(Exprs.ST);
- Dir->setEnsureUpperBound(Exprs.EUB);
- Dir->setNextLowerBound(Exprs.NLB);
- Dir->setNextUpperBound(Exprs.NUB);
- Dir->setCounters(Exprs.Counters);
- Dir->setInits(Exprs.Inits);
- Dir->setUpdates(Exprs.Updates);
- Dir->setFinals(Exprs.Finals);
- return Dir;
-}
-
-OMPParallelForSimdDirective *
-OMPParallelForSimdDirective::CreateEmpty(const ASTContext &C,
- unsigned NumClauses,
- unsigned CollapsedNum, EmptyShell) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelForSimdDirective),
- llvm::alignOf<OMPClause *>());
- void *Mem = C.Allocate(
- Size + sizeof(OMPClause *) * NumClauses +
- sizeof(Stmt *) * numLoopChildren(CollapsedNum, OMPD_parallel_for_simd));
- return new (Mem) OMPParallelForSimdDirective(CollapsedNum, NumClauses);
-}
-
-OMPParallelSectionsDirective *OMPParallelSectionsDirective::Create(
- const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelSectionsDirective),
- llvm::alignOf<OMPClause *>());
- void *Mem =
- C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
- OMPParallelSectionsDirective *Dir =
- new (Mem) OMPParallelSectionsDirective(StartLoc, EndLoc, Clauses.size());
- Dir->setClauses(Clauses);
- Dir->setAssociatedStmt(AssociatedStmt);
- return Dir;
-}
-
-OMPParallelSectionsDirective *
-OMPParallelSectionsDirective::CreateEmpty(const ASTContext &C,
- unsigned NumClauses, EmptyShell) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelSectionsDirective),
- llvm::alignOf<OMPClause *>());
- void *Mem =
- C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
- return new (Mem) OMPParallelSectionsDirective(NumClauses);
-}
-
-OMPTaskDirective *OMPTaskDirective::Create(const ASTContext &C,
- SourceLocation StartLoc,
- SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPTaskDirective),
- llvm::alignOf<OMPClause *>());
- void *Mem =
- C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
- OMPTaskDirective *Dir =
- new (Mem) OMPTaskDirective(StartLoc, EndLoc, Clauses.size());
- Dir->setClauses(Clauses);
- Dir->setAssociatedStmt(AssociatedStmt);
- return Dir;
-}
-
-OMPTaskDirective *OMPTaskDirective::CreateEmpty(const ASTContext &C,
- unsigned NumClauses,
- EmptyShell) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPTaskDirective),
- llvm::alignOf<OMPClause *>());
- void *Mem =
- C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
- return new (Mem) OMPTaskDirective(NumClauses);
-}
-
-OMPTaskyieldDirective *OMPTaskyieldDirective::Create(const ASTContext &C,
- SourceLocation StartLoc,
- SourceLocation EndLoc) {
- void *Mem = C.Allocate(sizeof(OMPTaskyieldDirective));
- OMPTaskyieldDirective *Dir =
- new (Mem) OMPTaskyieldDirective(StartLoc, EndLoc);
- return Dir;
-}
-
-OMPTaskyieldDirective *OMPTaskyieldDirective::CreateEmpty(const ASTContext &C,
- EmptyShell) {
- void *Mem = C.Allocate(sizeof(OMPTaskyieldDirective));
- return new (Mem) OMPTaskyieldDirective();
-}
-
-OMPBarrierDirective *OMPBarrierDirective::Create(const ASTContext &C,
- SourceLocation StartLoc,
- SourceLocation EndLoc) {
- void *Mem = C.Allocate(sizeof(OMPBarrierDirective));
- OMPBarrierDirective *Dir = new (Mem) OMPBarrierDirective(StartLoc, EndLoc);
- return Dir;
-}
-
-OMPBarrierDirective *OMPBarrierDirective::CreateEmpty(const ASTContext &C,
- EmptyShell) {
- void *Mem = C.Allocate(sizeof(OMPBarrierDirective));
- return new (Mem) OMPBarrierDirective();
-}
-
-OMPTaskwaitDirective *OMPTaskwaitDirective::Create(const ASTContext &C,
- SourceLocation StartLoc,
- SourceLocation EndLoc) {
- void *Mem = C.Allocate(sizeof(OMPTaskwaitDirective));
- OMPTaskwaitDirective *Dir = new (Mem) OMPTaskwaitDirective(StartLoc, EndLoc);
- return Dir;
-}
-
-OMPTaskwaitDirective *OMPTaskwaitDirective::CreateEmpty(const ASTContext &C,
- EmptyShell) {
- void *Mem = C.Allocate(sizeof(OMPTaskwaitDirective));
- return new (Mem) OMPTaskwaitDirective();
-}
-
-OMPTaskgroupDirective *OMPTaskgroupDirective::Create(const ASTContext &C,
- SourceLocation StartLoc,
- SourceLocation EndLoc,
- Stmt *AssociatedStmt) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPTaskgroupDirective),
- llvm::alignOf<Stmt *>());
- void *Mem = C.Allocate(Size + sizeof(Stmt *));
- OMPTaskgroupDirective *Dir =
- new (Mem) OMPTaskgroupDirective(StartLoc, EndLoc);
- Dir->setAssociatedStmt(AssociatedStmt);
- return Dir;
-}
-
-OMPTaskgroupDirective *OMPTaskgroupDirective::CreateEmpty(const ASTContext &C,
- EmptyShell) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPTaskgroupDirective),
- llvm::alignOf<Stmt *>());
- void *Mem = C.Allocate(Size + sizeof(Stmt *));
- return new (Mem) OMPTaskgroupDirective();
-}
-
-OMPCancellationPointDirective *OMPCancellationPointDirective::Create(
- const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- OpenMPDirectiveKind CancelRegion) {
- unsigned Size = llvm::RoundUpToAlignment(
- sizeof(OMPCancellationPointDirective), llvm::alignOf<Stmt *>());
- void *Mem = C.Allocate(Size);
- OMPCancellationPointDirective *Dir =
- new (Mem) OMPCancellationPointDirective(StartLoc, EndLoc);
- Dir->setCancelRegion(CancelRegion);
- return Dir;
-}
-
-OMPCancellationPointDirective *
-OMPCancellationPointDirective::CreateEmpty(const ASTContext &C, EmptyShell) {
- unsigned Size = llvm::RoundUpToAlignment(
- sizeof(OMPCancellationPointDirective), llvm::alignOf<Stmt *>());
- void *Mem = C.Allocate(Size);
- return new (Mem) OMPCancellationPointDirective();
-}
-
-OMPCancelDirective *
-OMPCancelDirective::Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation EndLoc,
- OpenMPDirectiveKind CancelRegion) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPCancelDirective),
- llvm::alignOf<Stmt *>());
- void *Mem = C.Allocate(Size);
- OMPCancelDirective *Dir = new (Mem) OMPCancelDirective(StartLoc, EndLoc);
- Dir->setCancelRegion(CancelRegion);
- return Dir;
-}
-
-OMPCancelDirective *OMPCancelDirective::CreateEmpty(const ASTContext &C,
- EmptyShell) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPCancelDirective),
- llvm::alignOf<Stmt *>());
- void *Mem = C.Allocate(Size);
- return new (Mem) OMPCancelDirective();
-}
-
-OMPFlushDirective *OMPFlushDirective::Create(const ASTContext &C,
- SourceLocation StartLoc,
- SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPFlushDirective),
- llvm::alignOf<OMPClause *>());
- void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size());
- OMPFlushDirective *Dir =
- new (Mem) OMPFlushDirective(StartLoc, EndLoc, Clauses.size());
- Dir->setClauses(Clauses);
- return Dir;
-}
-
-OMPFlushDirective *OMPFlushDirective::CreateEmpty(const ASTContext &C,
- unsigned NumClauses,
- EmptyShell) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPFlushDirective),
- llvm::alignOf<OMPClause *>());
- void *Mem = C.Allocate(Size + sizeof(OMPClause *) * NumClauses);
- return new (Mem) OMPFlushDirective(NumClauses);
-}
-
-OMPOrderedDirective *OMPOrderedDirective::Create(const ASTContext &C,
- SourceLocation StartLoc,
- SourceLocation EndLoc,
- Stmt *AssociatedStmt) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPOrderedDirective),
- llvm::alignOf<Stmt *>());
- void *Mem = C.Allocate(Size + sizeof(Stmt *));
- OMPOrderedDirective *Dir = new (Mem) OMPOrderedDirective(StartLoc, EndLoc);
- Dir->setAssociatedStmt(AssociatedStmt);
- return Dir;
-}
-
-OMPOrderedDirective *OMPOrderedDirective::CreateEmpty(const ASTContext &C,
- EmptyShell) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPOrderedDirective),
- llvm::alignOf<Stmt *>());
- void *Mem = C.Allocate(Size + sizeof(Stmt *));
- return new (Mem) OMPOrderedDirective();
-}
-
-OMPAtomicDirective *OMPAtomicDirective::Create(
- const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *X, Expr *V,
- Expr *E, Expr *UE, bool IsXLHSInRHSPart, bool IsPostfixUpdate) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPAtomicDirective),
- llvm::alignOf<OMPClause *>());
- void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() +
- 5 * sizeof(Stmt *));
- OMPAtomicDirective *Dir =
- new (Mem) OMPAtomicDirective(StartLoc, EndLoc, Clauses.size());
- Dir->setClauses(Clauses);
- Dir->setAssociatedStmt(AssociatedStmt);
- Dir->setX(X);
- Dir->setV(V);
- Dir->setExpr(E);
- Dir->setUpdateExpr(UE);
- Dir->IsXLHSInRHSPart = IsXLHSInRHSPart;
- Dir->IsPostfixUpdate = IsPostfixUpdate;
- return Dir;
-}
-
-OMPAtomicDirective *OMPAtomicDirective::CreateEmpty(const ASTContext &C,
- unsigned NumClauses,
- EmptyShell) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPAtomicDirective),
- llvm::alignOf<OMPClause *>());
- void *Mem =
- C.Allocate(Size + sizeof(OMPClause *) * NumClauses + 5 * sizeof(Stmt *));
- return new (Mem) OMPAtomicDirective(NumClauses);
-}
-
-OMPTargetDirective *OMPTargetDirective::Create(const ASTContext &C,
- SourceLocation StartLoc,
- SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPTargetDirective),
- llvm::alignOf<OMPClause *>());
- void *Mem =
- C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
- OMPTargetDirective *Dir =
- new (Mem) OMPTargetDirective(StartLoc, EndLoc, Clauses.size());
- Dir->setClauses(Clauses);
- Dir->setAssociatedStmt(AssociatedStmt);
- return Dir;
-}
-
-OMPTargetDirective *OMPTargetDirective::CreateEmpty(const ASTContext &C,
- unsigned NumClauses,
- EmptyShell) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPTargetDirective),
- llvm::alignOf<OMPClause *>());
- void *Mem =
- C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
- return new (Mem) OMPTargetDirective(NumClauses);
-}
-
-OMPTeamsDirective *OMPTeamsDirective::Create(const ASTContext &C,
- SourceLocation StartLoc,
- SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPTeamsDirective),
- llvm::alignOf<OMPClause *>());
- void *Mem =
- C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
- OMPTeamsDirective *Dir =
- new (Mem) OMPTeamsDirective(StartLoc, EndLoc, Clauses.size());
- Dir->setClauses(Clauses);
- Dir->setAssociatedStmt(AssociatedStmt);
- return Dir;
-}
-
-OMPTeamsDirective *OMPTeamsDirective::CreateEmpty(const ASTContext &C,
- unsigned NumClauses,
- EmptyShell) {
- unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPTeamsDirective),
- llvm::alignOf<OMPClause *>());
- void *Mem =
- C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
- return new (Mem) OMPTeamsDirective(NumClauses);
-}
-
diff --git a/lib/AST/StmtCXX.cpp b/lib/AST/StmtCXX.cpp
new file mode 100644
index 000000000000..e39a01daf96c
--- /dev/null
+++ b/lib/AST/StmtCXX.cpp
@@ -0,0 +1,86 @@
+//===--- StmtCXX.cpp - Classes for representing C++ statements ------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the subclesses of Stmt class declared in StmtCXX.h
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/StmtCXX.h"
+
+#include "clang/AST/ASTContext.h"
+
+using namespace clang;
+
+QualType CXXCatchStmt::getCaughtType() const {
+ if (ExceptionDecl)
+ return ExceptionDecl->getType();
+ return QualType();
+}
+
+CXXTryStmt *CXXTryStmt::Create(const ASTContext &C, SourceLocation tryLoc,
+ Stmt *tryBlock, ArrayRef<Stmt *> handlers) {
+ std::size_t Size = sizeof(CXXTryStmt);
+ Size += ((handlers.size() + 1) * sizeof(Stmt *));
+
+ void *Mem = C.Allocate(Size, llvm::alignOf<CXXTryStmt>());
+ return new (Mem) CXXTryStmt(tryLoc, tryBlock, handlers);
+}
+
+CXXTryStmt *CXXTryStmt::Create(const ASTContext &C, EmptyShell Empty,
+ unsigned numHandlers) {
+ std::size_t Size = sizeof(CXXTryStmt);
+ Size += ((numHandlers + 1) * sizeof(Stmt *));
+
+ void *Mem = C.Allocate(Size, llvm::alignOf<CXXTryStmt>());
+ return new (Mem) CXXTryStmt(Empty, numHandlers);
+}
+
+CXXTryStmt::CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock,
+ ArrayRef<Stmt *> handlers)
+ : Stmt(CXXTryStmtClass), TryLoc(tryLoc), NumHandlers(handlers.size()) {
+ Stmt **Stmts = reinterpret_cast<Stmt **>(this + 1);
+ Stmts[0] = tryBlock;
+ std::copy(handlers.begin(), handlers.end(), Stmts + 1);
+}
+
+CXXForRangeStmt::CXXForRangeStmt(DeclStmt *Range, DeclStmt *BeginEndStmt,
+ Expr *Cond, Expr *Inc, DeclStmt *LoopVar,
+ Stmt *Body, SourceLocation FL,
+ SourceLocation CAL, SourceLocation CL,
+ SourceLocation RPL)
+ : Stmt(CXXForRangeStmtClass), ForLoc(FL), CoawaitLoc(CAL), ColonLoc(CL),
+ RParenLoc(RPL) {
+ SubExprs[RANGE] = Range;
+ SubExprs[BEGINEND] = BeginEndStmt;
+ SubExprs[COND] = Cond;
+ SubExprs[INC] = Inc;
+ SubExprs[LOOPVAR] = LoopVar;
+ SubExprs[BODY] = Body;
+}
+
+Expr *CXXForRangeStmt::getRangeInit() {
+ DeclStmt *RangeStmt = getRangeStmt();
+ VarDecl *RangeDecl = dyn_cast_or_null<VarDecl>(RangeStmt->getSingleDecl());
+ assert(RangeDecl && "for-range should have a single var decl");
+ return RangeDecl->getInit();
+}
+
+const Expr *CXXForRangeStmt::getRangeInit() const {
+ return const_cast<CXXForRangeStmt *>(this)->getRangeInit();
+}
+
+VarDecl *CXXForRangeStmt::getLoopVariable() {
+ Decl *LV = cast<DeclStmt>(getLoopVarStmt())->getSingleDecl();
+ assert(LV && "No loop variable in CXXForRangeStmt");
+ return cast<VarDecl>(LV);
+}
+
+const VarDecl *CXXForRangeStmt::getLoopVariable() const {
+ return const_cast<CXXForRangeStmt *>(this)->getLoopVariable();
+}
diff --git a/lib/AST/StmtIterator.cpp b/lib/AST/StmtIterator.cpp
index 732756fbec9a..861d0908209d 100644
--- a/lib/AST/StmtIterator.cpp
+++ b/lib/AST/StmtIterator.cpp
@@ -42,7 +42,7 @@ void StmtIteratorBase::NextVA() {
if (inDeclGroup()) {
if (VarDecl* VD = dyn_cast<VarDecl>(*DGI))
- if (VD->Init)
+ if (VD->hasInit())
return;
NextDecl();
diff --git a/lib/AST/StmtObjC.cpp b/lib/AST/StmtObjC.cpp
new file mode 100644
index 000000000000..a77550c7605d
--- /dev/null
+++ b/lib/AST/StmtObjC.cpp
@@ -0,0 +1,73 @@
+//===--- StmtObjC.cpp - Classes for representing ObjC statements ---------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the subclesses of Stmt class declared in StmtObjC.h
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/StmtObjC.h"
+
+#include "clang/AST/Expr.h"
+#include "clang/AST/ASTContext.h"
+
+using namespace clang;
+
+ObjCForCollectionStmt::ObjCForCollectionStmt(Stmt *Elem, Expr *Collect,
+ Stmt *Body, SourceLocation FCL,
+ SourceLocation RPL)
+ : Stmt(ObjCForCollectionStmtClass) {
+ SubExprs[ELEM] = Elem;
+ SubExprs[COLLECTION] = Collect;
+ SubExprs[BODY] = Body;
+ ForLoc = FCL;
+ RParenLoc = RPL;
+}
+
+ObjCAtTryStmt::ObjCAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt,
+ Stmt **CatchStmts, unsigned NumCatchStmts,
+ Stmt *atFinallyStmt)
+ : Stmt(ObjCAtTryStmtClass), AtTryLoc(atTryLoc),
+ NumCatchStmts(NumCatchStmts), HasFinally(atFinallyStmt != nullptr) {
+ Stmt **Stmts = getStmts();
+ Stmts[0] = atTryStmt;
+ for (unsigned I = 0; I != NumCatchStmts; ++I)
+ Stmts[I + 1] = CatchStmts[I];
+
+ if (HasFinally)
+ Stmts[NumCatchStmts + 1] = atFinallyStmt;
+}
+
+ObjCAtTryStmt *ObjCAtTryStmt::Create(const ASTContext &Context,
+ SourceLocation atTryLoc, Stmt *atTryStmt,
+ Stmt **CatchStmts, unsigned NumCatchStmts,
+ Stmt *atFinallyStmt) {
+ unsigned Size =
+ sizeof(ObjCAtTryStmt) +
+ (1 + NumCatchStmts + (atFinallyStmt != nullptr)) * sizeof(Stmt *);
+ void *Mem = Context.Allocate(Size, llvm::alignOf<ObjCAtTryStmt>());
+ return new (Mem) ObjCAtTryStmt(atTryLoc, atTryStmt, CatchStmts, NumCatchStmts,
+ atFinallyStmt);
+}
+
+ObjCAtTryStmt *ObjCAtTryStmt::CreateEmpty(const ASTContext &Context,
+ unsigned NumCatchStmts,
+ bool HasFinally) {
+ unsigned Size =
+ sizeof(ObjCAtTryStmt) + (1 + NumCatchStmts + HasFinally) * sizeof(Stmt *);
+ void *Mem = Context.Allocate(Size, llvm::alignOf<ObjCAtTryStmt>());
+ return new (Mem) ObjCAtTryStmt(EmptyShell(), NumCatchStmts, HasFinally);
+}
+
+SourceLocation ObjCAtTryStmt::getLocEnd() const {
+ if (HasFinally)
+ return getFinallyStmt()->getLocEnd();
+ if (NumCatchStmts)
+ return getCatchStmt(NumCatchStmts - 1)->getLocEnd();
+ return getTryBody()->getLocEnd();
+}
diff --git a/lib/AST/StmtOpenMP.cpp b/lib/AST/StmtOpenMP.cpp
new file mode 100644
index 000000000000..7f923d8a8251
--- /dev/null
+++ b/lib/AST/StmtOpenMP.cpp
@@ -0,0 +1,884 @@
+//===--- StmtOpenMP.cpp - Classes for OpenMP directives -------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the subclesses of Stmt class declared in StmtOpenMP.h
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/StmtOpenMP.h"
+
+#include "clang/AST/ASTContext.h"
+
+using namespace clang;
+
+void OMPExecutableDirective::setClauses(ArrayRef<OMPClause *> Clauses) {
+ assert(Clauses.size() == getNumClauses() &&
+ "Number of clauses is not the same as the preallocated buffer");
+ std::copy(Clauses.begin(), Clauses.end(), getClauses().begin());
+}
+
+void OMPLoopDirective::setCounters(ArrayRef<Expr *> A) {
+ assert(A.size() == getCollapsedNumber() &&
+ "Number of loop counters is not the same as the collapsed number");
+ std::copy(A.begin(), A.end(), getCounters().begin());
+}
+
+void OMPLoopDirective::setPrivateCounters(ArrayRef<Expr *> A) {
+ assert(A.size() == getCollapsedNumber() && "Number of loop private counters "
+ "is not the same as the collapsed "
+ "number");
+ std::copy(A.begin(), A.end(), getPrivateCounters().begin());
+}
+
+void OMPLoopDirective::setInits(ArrayRef<Expr *> A) {
+ assert(A.size() == getCollapsedNumber() &&
+ "Number of counter inits is not the same as the collapsed number");
+ std::copy(A.begin(), A.end(), getInits().begin());
+}
+
+void OMPLoopDirective::setUpdates(ArrayRef<Expr *> A) {
+ assert(A.size() == getCollapsedNumber() &&
+ "Number of counter updates is not the same as the collapsed number");
+ std::copy(A.begin(), A.end(), getUpdates().begin());
+}
+
+void OMPLoopDirective::setFinals(ArrayRef<Expr *> A) {
+ assert(A.size() == getCollapsedNumber() &&
+ "Number of counter finals is not the same as the collapsed number");
+ std::copy(A.begin(), A.end(), getFinals().begin());
+}
+
+OMPParallelDirective *OMPParallelDirective::Create(
+ const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
+ OMPParallelDirective *Dir =
+ new (Mem) OMPParallelDirective(StartLoc, EndLoc, Clauses.size());
+ Dir->setClauses(Clauses);
+ Dir->setAssociatedStmt(AssociatedStmt);
+ Dir->setHasCancel(HasCancel);
+ return Dir;
+}
+
+OMPParallelDirective *OMPParallelDirective::CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ EmptyShell) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
+ return new (Mem) OMPParallelDirective(NumClauses);
+}
+
+OMPSimdDirective *
+OMPSimdDirective::Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation EndLoc, unsigned CollapsedNum,
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
+ const HelperExprs &Exprs) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSimdDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() +
+ sizeof(Stmt *) * numLoopChildren(CollapsedNum, OMPD_simd));
+ OMPSimdDirective *Dir = new (Mem)
+ OMPSimdDirective(StartLoc, EndLoc, CollapsedNum, Clauses.size());
+ Dir->setClauses(Clauses);
+ Dir->setAssociatedStmt(AssociatedStmt);
+ Dir->setIterationVariable(Exprs.IterationVarRef);
+ Dir->setLastIteration(Exprs.LastIteration);
+ Dir->setCalcLastIteration(Exprs.CalcLastIteration);
+ Dir->setPreCond(Exprs.PreCond);
+ Dir->setCond(Exprs.Cond);
+ Dir->setInit(Exprs.Init);
+ Dir->setInc(Exprs.Inc);
+ Dir->setCounters(Exprs.Counters);
+ Dir->setPrivateCounters(Exprs.PrivateCounters);
+ Dir->setInits(Exprs.Inits);
+ Dir->setUpdates(Exprs.Updates);
+ Dir->setFinals(Exprs.Finals);
+ return Dir;
+}
+
+OMPSimdDirective *OMPSimdDirective::CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ unsigned CollapsedNum,
+ EmptyShell) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSimdDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * NumClauses +
+ sizeof(Stmt *) * numLoopChildren(CollapsedNum, OMPD_simd));
+ return new (Mem) OMPSimdDirective(CollapsedNum, NumClauses);
+}
+
+OMPForDirective *
+OMPForDirective::Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation EndLoc, unsigned CollapsedNum,
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
+ const HelperExprs &Exprs, bool HasCancel) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPForDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() +
+ sizeof(Stmt *) * numLoopChildren(CollapsedNum, OMPD_for));
+ OMPForDirective *Dir =
+ new (Mem) OMPForDirective(StartLoc, EndLoc, CollapsedNum, Clauses.size());
+ Dir->setClauses(Clauses);
+ Dir->setAssociatedStmt(AssociatedStmt);
+ Dir->setIterationVariable(Exprs.IterationVarRef);
+ Dir->setLastIteration(Exprs.LastIteration);
+ Dir->setCalcLastIteration(Exprs.CalcLastIteration);
+ Dir->setPreCond(Exprs.PreCond);
+ Dir->setCond(Exprs.Cond);
+ Dir->setInit(Exprs.Init);
+ Dir->setInc(Exprs.Inc);
+ Dir->setIsLastIterVariable(Exprs.IL);
+ Dir->setLowerBoundVariable(Exprs.LB);
+ Dir->setUpperBoundVariable(Exprs.UB);
+ Dir->setStrideVariable(Exprs.ST);
+ Dir->setEnsureUpperBound(Exprs.EUB);
+ Dir->setNextLowerBound(Exprs.NLB);
+ Dir->setNextUpperBound(Exprs.NUB);
+ Dir->setCounters(Exprs.Counters);
+ Dir->setPrivateCounters(Exprs.PrivateCounters);
+ Dir->setInits(Exprs.Inits);
+ Dir->setUpdates(Exprs.Updates);
+ Dir->setFinals(Exprs.Finals);
+ Dir->setHasCancel(HasCancel);
+ return Dir;
+}
+
+OMPForDirective *OMPForDirective::CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ unsigned CollapsedNum,
+ EmptyShell) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPForDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * NumClauses +
+ sizeof(Stmt *) * numLoopChildren(CollapsedNum, OMPD_for));
+ return new (Mem) OMPForDirective(CollapsedNum, NumClauses);
+}
+
+OMPForSimdDirective *
+OMPForSimdDirective::Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation EndLoc, unsigned CollapsedNum,
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
+ const HelperExprs &Exprs) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPForSimdDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() +
+ sizeof(Stmt *) * numLoopChildren(CollapsedNum, OMPD_for_simd));
+ OMPForSimdDirective *Dir = new (Mem)
+ OMPForSimdDirective(StartLoc, EndLoc, CollapsedNum, Clauses.size());
+ Dir->setClauses(Clauses);
+ Dir->setAssociatedStmt(AssociatedStmt);
+ Dir->setIterationVariable(Exprs.IterationVarRef);
+ Dir->setLastIteration(Exprs.LastIteration);
+ Dir->setCalcLastIteration(Exprs.CalcLastIteration);
+ Dir->setPreCond(Exprs.PreCond);
+ Dir->setCond(Exprs.Cond);
+ Dir->setInit(Exprs.Init);
+ Dir->setInc(Exprs.Inc);
+ Dir->setIsLastIterVariable(Exprs.IL);
+ Dir->setLowerBoundVariable(Exprs.LB);
+ Dir->setUpperBoundVariable(Exprs.UB);
+ Dir->setStrideVariable(Exprs.ST);
+ Dir->setEnsureUpperBound(Exprs.EUB);
+ Dir->setNextLowerBound(Exprs.NLB);
+ Dir->setNextUpperBound(Exprs.NUB);
+ Dir->setCounters(Exprs.Counters);
+ Dir->setPrivateCounters(Exprs.PrivateCounters);
+ Dir->setInits(Exprs.Inits);
+ Dir->setUpdates(Exprs.Updates);
+ Dir->setFinals(Exprs.Finals);
+ return Dir;
+}
+
+OMPForSimdDirective *OMPForSimdDirective::CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ unsigned CollapsedNum,
+ EmptyShell) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPForSimdDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * NumClauses +
+ sizeof(Stmt *) * numLoopChildren(CollapsedNum, OMPD_for_simd));
+ return new (Mem) OMPForSimdDirective(CollapsedNum, NumClauses);
+}
+
+OMPSectionsDirective *OMPSectionsDirective::Create(
+ const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSectionsDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
+ OMPSectionsDirective *Dir =
+ new (Mem) OMPSectionsDirective(StartLoc, EndLoc, Clauses.size());
+ Dir->setClauses(Clauses);
+ Dir->setAssociatedStmt(AssociatedStmt);
+ Dir->setHasCancel(HasCancel);
+ return Dir;
+}
+
+OMPSectionsDirective *OMPSectionsDirective::CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ EmptyShell) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSectionsDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
+ return new (Mem) OMPSectionsDirective(NumClauses);
+}
+
+OMPSectionDirective *OMPSectionDirective::Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ Stmt *AssociatedStmt,
+ bool HasCancel) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSectionDirective),
+ llvm::alignOf<Stmt *>());
+ void *Mem = C.Allocate(Size + sizeof(Stmt *));
+ OMPSectionDirective *Dir = new (Mem) OMPSectionDirective(StartLoc, EndLoc);
+ Dir->setAssociatedStmt(AssociatedStmt);
+ Dir->setHasCancel(HasCancel);
+ return Dir;
+}
+
+OMPSectionDirective *OMPSectionDirective::CreateEmpty(const ASTContext &C,
+ EmptyShell) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSectionDirective),
+ llvm::alignOf<Stmt *>());
+ void *Mem = C.Allocate(Size + sizeof(Stmt *));
+ return new (Mem) OMPSectionDirective();
+}
+
+OMPSingleDirective *OMPSingleDirective::Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSingleDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
+ OMPSingleDirective *Dir =
+ new (Mem) OMPSingleDirective(StartLoc, EndLoc, Clauses.size());
+ Dir->setClauses(Clauses);
+ Dir->setAssociatedStmt(AssociatedStmt);
+ return Dir;
+}
+
+OMPSingleDirective *OMPSingleDirective::CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ EmptyShell) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSingleDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
+ return new (Mem) OMPSingleDirective(NumClauses);
+}
+
+OMPMasterDirective *OMPMasterDirective::Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ Stmt *AssociatedStmt) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPMasterDirective),
+ llvm::alignOf<Stmt *>());
+ void *Mem = C.Allocate(Size + sizeof(Stmt *));
+ OMPMasterDirective *Dir = new (Mem) OMPMasterDirective(StartLoc, EndLoc);
+ Dir->setAssociatedStmt(AssociatedStmt);
+ return Dir;
+}
+
+OMPMasterDirective *OMPMasterDirective::CreateEmpty(const ASTContext &C,
+ EmptyShell) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPMasterDirective),
+ llvm::alignOf<Stmt *>());
+ void *Mem = C.Allocate(Size + sizeof(Stmt *));
+ return new (Mem) OMPMasterDirective();
+}
+
+OMPCriticalDirective *OMPCriticalDirective::Create(
+ const ASTContext &C, const DeclarationNameInfo &Name,
+ SourceLocation StartLoc, SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPCriticalDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
+ OMPCriticalDirective *Dir =
+ new (Mem) OMPCriticalDirective(Name, StartLoc, EndLoc, Clauses.size());
+ Dir->setClauses(Clauses);
+ Dir->setAssociatedStmt(AssociatedStmt);
+ return Dir;
+}
+
+OMPCriticalDirective *OMPCriticalDirective::CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ EmptyShell) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPCriticalDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
+ return new (Mem) OMPCriticalDirective(NumClauses);
+}
+
+OMPParallelForDirective *OMPParallelForDirective::Create(
+ const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
+ const HelperExprs &Exprs, bool HasCancel) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelForDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() +
+ sizeof(Stmt *) *
+ numLoopChildren(CollapsedNum, OMPD_parallel_for));
+ OMPParallelForDirective *Dir = new (Mem)
+ OMPParallelForDirective(StartLoc, EndLoc, CollapsedNum, Clauses.size());
+ Dir->setClauses(Clauses);
+ Dir->setAssociatedStmt(AssociatedStmt);
+ Dir->setIterationVariable(Exprs.IterationVarRef);
+ Dir->setLastIteration(Exprs.LastIteration);
+ Dir->setCalcLastIteration(Exprs.CalcLastIteration);
+ Dir->setPreCond(Exprs.PreCond);
+ Dir->setCon