aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/clang-c/Index.h146
-rw-r--r--include/clang/AST/ASTContext.h97
-rw-r--r--include/clang/AST/ASTContextAllocate.h38
-rw-r--r--include/clang/AST/ASTDiagnostic.h12
-rw-r--r--include/clang/AST/ASTDumperUtils.h97
-rw-r--r--include/clang/AST/ASTImporter.h193
-rw-r--r--include/clang/AST/ASTImporterLookupTable.h75
-rw-r--r--include/clang/AST/ASTStructuralEquivalence.h14
-rw-r--r--include/clang/AST/ASTVector.h1
-rw-r--r--include/clang/AST/Attr.h14
-rw-r--r--include/clang/AST/AttrIterator.h19
-rw-r--r--include/clang/AST/AttrVisitor.h76
-rw-r--r--include/clang/AST/BaseSubobject.h1
-rw-r--r--include/clang/AST/CMakeLists.txt9
-rw-r--r--include/clang/AST/CanonicalType.h2
-rw-r--r--include/clang/AST/Comment.h35
-rw-r--r--include/clang/AST/CommentDiagnostic.h15
-rw-r--r--include/clang/AST/CommentVisitor.h34
-rw-r--r--include/clang/AST/Decl.h718
-rw-r--r--include/clang/AST/DeclBase.h621
-rw-r--r--include/clang/AST/DeclCXX.h154
-rw-r--r--include/clang/AST/DeclFriend.h2
-rw-r--r--include/clang/AST/DeclObjC.h191
-rw-r--r--include/clang/AST/DeclOpenMP.h120
-rw-r--r--include/clang/AST/DeclTemplate.h4
-rw-r--r--include/clang/AST/DeclVisitor.h13
-rw-r--r--include/clang/AST/DeclarationName.h621
-rw-r--r--include/clang/AST/EvaluatedExprVisitor.h18
-rw-r--r--include/clang/AST/Expr.h1312
-rw-r--r--include/clang/AST/ExprCXX.h1613
-rw-r--r--include/clang/AST/ExprObjC.h90
-rw-r--r--include/clang/AST/ExprOpenMP.h6
-rw-r--r--include/clang/AST/FormatString.h (renamed from include/clang/Analysis/Analyses/FormatString.h)37
-rw-r--r--include/clang/AST/GlobalDecl.h28
-rw-r--r--include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h4
-rw-r--r--include/clang/AST/Mangle.h1
-rw-r--r--include/clang/AST/NSAPI.h11
-rw-r--r--include/clang/AST/NestedNameSpecifier.h11
-rw-r--r--include/clang/AST/ODRHash.h10
-rw-r--r--include/clang/AST/OSLog.h (renamed from include/clang/Analysis/Analyses/OSLog.h)42
-rw-r--r--include/clang/AST/OpenMPClause.h448
-rw-r--r--include/clang/AST/OperationKinds.def16
-rw-r--r--include/clang/AST/PrettyPrinter.h62
-rw-r--r--include/clang/AST/RawCommentList.h6
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h104
-rw-r--r--include/clang/AST/Stmt.h1763
-rw-r--r--include/clang/AST/StmtCXX.h56
-rw-r--r--include/clang/AST/StmtDataCollectors.td6
-rw-r--r--include/clang/AST/StmtObjC.h38
-rw-r--r--include/clang/AST/StmtOpenMP.h40
-rw-r--r--include/clang/AST/StmtVisitor.h51
-rw-r--r--include/clang/AST/TemplateArgumentVisitor.h99
-rw-r--r--include/clang/AST/TemplateBase.h21
-rw-r--r--include/clang/AST/TemplateName.h1
-rw-r--r--include/clang/AST/TextNodeDumper.h298
-rw-r--r--include/clang/AST/Type.h909
-rw-r--r--include/clang/AST/TypeLoc.h93
-rw-r--r--include/clang/ASTMatchers/ASTMatchers.h252
-rw-r--r--include/clang/ASTMatchers/ASTMatchersInternal.h2
-rw-r--r--include/clang/ASTMatchers/Dynamic/Parser.h1
-rw-r--r--include/clang/Analysis/Analyses/ExprMutationAnalyzer.h96
-rw-r--r--include/clang/Analysis/Analyses/LiveVariables.h8
-rw-r--r--include/clang/Analysis/Analyses/PseudoConstantAnalysis.h45
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafetyCommon.h2
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafetyTIL.h8
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafetyTraverse.h21
-rw-r--r--include/clang/Analysis/AnalysisDeclContext.h32
-rw-r--r--include/clang/Analysis/AnalysisDiagnostic.h15
-rw-r--r--include/clang/Analysis/CallGraph.h1
-rw-r--r--include/clang/Analysis/CloneDetection.h2
-rw-r--r--include/clang/Analysis/ConstructionContext.h14
-rw-r--r--include/clang/Analysis/ProgramPoint.h28
-rw-r--r--include/clang/Analysis/SelectorExtras.h37
-rw-r--r--include/clang/Basic/AlignedAllocation.h4
-rw-r--r--include/clang/Basic/AllDiagnostics.h22
-rw-r--r--include/clang/Basic/Attr.td278
-rw-r--r--include/clang/Basic/AttrDocs.td453
-rw-r--r--include/clang/Basic/Builtins.def35
-rw-r--r--include/clang/Basic/BuiltinsAArch64.def105
-rw-r--r--include/clang/Basic/BuiltinsAMDGPU.def37
-rw-r--r--include/clang/Basic/BuiltinsARM.def98
-rw-r--r--include/clang/Basic/BuiltinsHexagon.def3296
-rw-r--r--include/clang/Basic/BuiltinsNios2.def70
-rw-r--r--include/clang/Basic/BuiltinsPPC.def6
-rw-r--r--include/clang/Basic/BuiltinsWebAssembly.def90
-rw-r--r--include/clang/Basic/BuiltinsX86.def251
-rw-r--r--include/clang/Basic/BuiltinsX86_64.def7
-rw-r--r--include/clang/Basic/CodeGenOptions.def (renamed from include/clang/Frontend/CodeGenOptions.def)30
-rw-r--r--include/clang/Basic/CodeGenOptions.h (renamed from include/clang/Frontend/CodeGenOptions.h)36
-rw-r--r--include/clang/Basic/Cuda.h8
-rw-r--r--include/clang/Basic/DebugInfoOptions.h6
-rw-r--r--include/clang/Basic/DeclNodes.td1
-rw-r--r--include/clang/Basic/Diagnostic.h9
-rw-r--r--include/clang/Basic/DiagnosticAST.h29
-rw-r--r--include/clang/Basic/DiagnosticASTKinds.td39
-rw-r--r--include/clang/Basic/DiagnosticAnalysis.h29
-rw-r--r--include/clang/Basic/DiagnosticComment.h29
-rw-r--r--include/clang/Basic/DiagnosticCommonKinds.td51
-rw-r--r--include/clang/Basic/DiagnosticCrossTU.h29
-rw-r--r--include/clang/Basic/DiagnosticCrossTUKinds.td9
-rw-r--r--include/clang/Basic/DiagnosticDriver.h29
-rw-r--r--include/clang/Basic/DiagnosticDriverKinds.td41
-rw-r--r--include/clang/Basic/DiagnosticFrontend.h29
-rw-r--r--include/clang/Basic/DiagnosticFrontendKinds.td70
-rw-r--r--include/clang/Basic/DiagnosticGroups.td28
-rw-r--r--include/clang/Basic/DiagnosticIDs.h2
-rw-r--r--include/clang/Basic/DiagnosticLex.h29
-rw-r--r--include/clang/Basic/DiagnosticLexKinds.td23
-rw-r--r--include/clang/Basic/DiagnosticParse.h29
-rw-r--r--include/clang/Basic/DiagnosticParseKinds.td65
-rw-r--r--include/clang/Basic/DiagnosticRefactoring.h29
-rw-r--r--include/clang/Basic/DiagnosticSema.h29
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td408
-rw-r--r--include/clang/Basic/DiagnosticSerialization.h29
-rw-r--r--include/clang/Basic/Features.def40
-rw-r--r--include/clang/Basic/FileManager.h44
-rw-r--r--include/clang/Basic/FileSystemStatCache.h46
-rw-r--r--include/clang/Basic/FixedPoint.h138
-rw-r--r--include/clang/Basic/IdentifierTable.h237
-rw-r--r--include/clang/Basic/LangOptions.def17
-rw-r--r--include/clang/Basic/LangOptions.h83
-rw-r--r--include/clang/Basic/MSP430Target.def247
-rw-r--r--include/clang/Basic/ObjCRuntime.h74
-rw-r--r--include/clang/Basic/OpenCLExtensionTypes.def41
-rw-r--r--include/clang/Basic/OpenCLExtensions.def1
-rw-r--r--include/clang/Basic/OpenMPKinds.def37
-rw-r--r--include/clang/Basic/OpenMPKinds.h17
-rw-r--r--include/clang/Basic/PlistSupport.h25
-rw-r--r--include/clang/Basic/Sanitizers.def29
-rw-r--r--include/clang/Basic/Sanitizers.h2
-rw-r--r--include/clang/Basic/SourceLocation.h4
-rw-r--r--include/clang/Basic/SourceManager.h21
-rw-r--r--include/clang/Basic/Specifiers.h1
-rw-r--r--include/clang/Basic/StmtNodes.td6
-rw-r--r--include/clang/Basic/TargetBuiltins.h10
-rw-r--r--include/clang/Basic/TargetInfo.h36
-rw-r--r--include/clang/Basic/TargetOptions.h14
-rw-r--r--include/clang/Basic/TokenKinds.def85
-rw-r--r--include/clang/Basic/TokenKinds.h3
-rw-r--r--include/clang/Basic/TypeTraits.h6
-rw-r--r--include/clang/Basic/VirtualFileSystem.h454
-rw-r--r--include/clang/Basic/X86Target.def9
-rw-r--r--include/clang/Basic/XRayInstr.h2
-rw-r--r--include/clang/Basic/arm_neon.td109
-rw-r--r--include/clang/Basic/arm_neon_incl.td7
-rw-r--r--include/clang/CodeGen/CGFunctionInfo.h6
-rw-r--r--include/clang/CodeGen/SwiftCallingConv.h3
-rw-r--r--include/clang/CrossTU/CrossTUDiagnostic.h18
-rw-r--r--include/clang/CrossTU/CrossTranslationUnit.h30
-rw-r--r--include/clang/Driver/Action.h27
-rw-r--r--include/clang/Driver/CC1Options.td61
-rw-r--r--include/clang/Driver/CLCompatOptions.td83
-rw-r--r--include/clang/Driver/DarwinSDKInfo.h42
-rw-r--r--include/clang/Driver/Distro.h12
-rw-r--r--include/clang/Driver/Driver.h23
-rw-r--r--include/clang/Driver/DriverDiagnostic.h15
-rw-r--r--include/clang/Driver/Job.h15
-rw-r--r--include/clang/Driver/Options.td199
-rw-r--r--include/clang/Driver/SanitizerArgs.h5
-rw-r--r--include/clang/Driver/ToolChain.h42
-rw-r--r--include/clang/Driver/Types.def1
-rw-r--r--include/clang/Format/Format.h71
-rw-r--r--include/clang/Frontend/ASTConsumers.h4
-rw-r--r--include/clang/Frontend/ASTUnit.h48
-rw-r--r--include/clang/Frontend/CompilerInstance.h15
-rw-r--r--include/clang/Frontend/CompilerInvocation.h23
-rw-r--r--include/clang/Frontend/FrontendAction.h20
-rw-r--r--include/clang/Frontend/FrontendActions.h18
-rw-r--r--include/clang/Frontend/FrontendDiagnostic.h15
-rw-r--r--include/clang/Frontend/FrontendOptions.h9
-rw-r--r--include/clang/Frontend/LangStandards.def3
-rw-r--r--include/clang/Frontend/PCHContainerOperations.h106
-rw-r--r--include/clang/Frontend/PrecompiledPreamble.h26
-rw-r--r--include/clang/Frontend/Utils.h19
-rw-r--r--include/clang/Index/IndexDataConsumer.h5
-rw-r--r--include/clang/Index/IndexSymbol.h6
-rw-r--r--include/clang/Index/IndexingAction.h11
-rw-r--r--include/clang/Index/USRGeneration.h27
-rw-r--r--include/clang/Lex/CodeCompletionHandler.h7
-rw-r--r--include/clang/Lex/DirectoryLookup.h2
-rw-r--r--include/clang/Lex/HeaderMap.h3
-rw-r--r--include/clang/Lex/HeaderSearch.h26
-rw-r--r--include/clang/Lex/LexDiagnostic.h15
-rw-r--r--include/clang/Lex/Lexer.h26
-rw-r--r--include/clang/Lex/MacroInfo.h3
-rw-r--r--include/clang/Lex/ModuleMap.h16
-rw-r--r--include/clang/Lex/PPCallbacks.h13
-rw-r--r--include/clang/Lex/PTHLexer.h107
-rw-r--r--include/clang/Lex/PTHManager.h149
-rw-r--r--include/clang/Lex/Pragma.h2
-rw-r--r--include/clang/Lex/PreprocessingRecord.h1
-rw-r--r--include/clang/Lex/Preprocessor.h115
-rw-r--r--include/clang/Lex/PreprocessorLexer.h2
-rw-r--r--include/clang/Lex/PreprocessorOptions.h19
-rw-r--r--include/clang/Lex/TokenConcatenation.h4
-rw-r--r--include/clang/Lex/TokenLexer.h44
-rw-r--r--include/clang/Parse/LoopHint.h (renamed from include/clang/Sema/LoopHint.h)6
-rw-r--r--include/clang/Parse/ParseDiagnostic.h15
-rw-r--r--include/clang/Parse/Parser.h63
-rw-r--r--include/clang/Sema/CodeCompleteConsumer.h70
-rw-r--r--include/clang/Sema/CodeCompleteOptions.h3
-rw-r--r--include/clang/Sema/DeclSpec.h89
-rw-r--r--include/clang/Sema/Initialization.h25
-rw-r--r--include/clang/Sema/Lookup.h6
-rw-r--r--include/clang/Sema/Overload.h13
-rw-r--r--include/clang/Sema/ParsedAttr.h228
-rw-r--r--include/clang/Sema/Scope.h1
-rw-r--r--include/clang/Sema/ScopeInfo.h17
-rw-r--r--include/clang/Sema/Sema.h356
-rw-r--r--include/clang/Sema/SemaDiagnostic.h15
-rw-r--r--include/clang/Serialization/ASTBitCodes.h14
-rw-r--r--include/clang/Serialization/ASTReader.h37
-rw-r--r--include/clang/Serialization/ASTWriter.h18
-rw-r--r--include/clang/Serialization/ContinuousRangeMap.h2
-rw-r--r--include/clang/Serialization/GlobalModuleIndex.h17
-rw-r--r--include/clang/Serialization/PCHContainerOperations.h117
-rw-r--r--include/clang/Serialization/SerializationDiagnostic.h15
-rw-r--r--include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h37
-rw-r--r--include/clang/StaticAnalyzer/Checkers/CheckerBase.td50
-rw-r--r--include/clang/StaticAnalyzer/Checkers/Checkers.td579
-rw-r--r--include/clang/StaticAnalyzer/Checkers/ClangCheckers.h22
-rw-r--r--include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h232
-rw-r--r--include/clang/StaticAnalyzer/Core/Analyses.def1
-rw-r--r--include/clang/StaticAnalyzer/Core/AnalyzerOptions.def377
-rw-r--r--include/clang/StaticAnalyzer/Core/AnalyzerOptions.h607
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h39
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/BugType.h2
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h2
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h21
-rw-r--r--include/clang/StaticAnalyzer/Core/Checker.h2
-rw-r--r--include/clang/StaticAnalyzer/Core/CheckerManager.h16
-rw-r--r--include/clang/StaticAnalyzer/Core/CheckerOptInfo.h44
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h11
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h3
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h80
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h50
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h5
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h1
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h72
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h50
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h65
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h42
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h108
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h2
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/Regions.def1
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h281
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SMTContext.h31
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h753
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SMTSolver.h731
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h4
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h4
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/Store.h9
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h5
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h29
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h10
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h1
-rw-r--r--include/clang/StaticAnalyzer/Core/RetainSummaryManager.h798
-rw-r--r--include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h4
-rw-r--r--include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h (renamed from include/clang/StaticAnalyzer/Core/CheckerRegistry.h)31
-rw-r--r--include/clang/StaticAnalyzer/Frontend/FrontendActions.h7
-rw-r--r--include/clang/Tooling/AllTUsExecution.h4
-rw-r--r--include/clang/Tooling/CompilationDatabase.h21
-rw-r--r--include/clang/Tooling/CompilationDatabasePluginRegistry.h21
-rw-r--r--include/clang/Tooling/DiagnosticsYaml.h10
-rw-r--r--include/clang/Tooling/Execution.h9
-rw-r--r--include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h2
-rw-r--r--include/clang/Tooling/Refactoring/RefactoringDiagnostic.h17
-rw-r--r--include/clang/Tooling/StandaloneExecution.h5
-rw-r--r--include/clang/Tooling/Tooling.h31
-rw-r--r--include/clang/module.modulemap22
270 files changed, 17259 insertions, 9613 deletions
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
index 65dada38b050..c51dfb1598b9 100644
--- a/include/clang-c/Index.h
+++ b/include/clang-c/Index.h
@@ -32,7 +32,7 @@
* compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable.
*/
#define CINDEX_VERSION_MAJOR 0
-#define CINDEX_VERSION_MINOR 49
+#define CINDEX_VERSION_MINOR 50
#define CINDEX_VERSION_ENCODE(major, minor) ( \
((major) * 10000) \
@@ -178,7 +178,6 @@ typedef struct CXVersion {
* A negative value indicates that the cursor is not a function declaration.
*/
enum CXCursor_ExceptionSpecificationKind {
-
/**
* The cursor has no exception specification.
*/
@@ -1332,7 +1331,17 @@ enum CXTranslationUnit_Flags {
*
* The function bodies of the main file are not skipped.
*/
- CXTranslationUnit_LimitSkipFunctionBodiesToPreamble = 0x800
+ CXTranslationUnit_LimitSkipFunctionBodiesToPreamble = 0x800,
+
+ /**
+ * Used to indicate that attributed types should be included in CXType.
+ */
+ CXTranslationUnit_IncludeAttributedTypes = 0x1000,
+
+ /**
+ * Used to indicate that implicit attributes should be visited.
+ */
+ CXTranslationUnit_VisitImplicitAttributes = 0x2000
};
/**
@@ -2559,7 +2568,25 @@ enum CXCursorKind {
CXCursor_VisibilityAttr = 417,
CXCursor_DLLExport = 418,
CXCursor_DLLImport = 419,
- CXCursor_LastAttr = CXCursor_DLLImport,
+ CXCursor_NSReturnsRetained = 420,
+ CXCursor_NSReturnsNotRetained = 421,
+ CXCursor_NSReturnsAutoreleased = 422,
+ CXCursor_NSConsumesSelf = 423,
+ CXCursor_NSConsumed = 424,
+ CXCursor_ObjCException = 425,
+ CXCursor_ObjCNSObject = 426,
+ CXCursor_ObjCIndependentClass = 427,
+ CXCursor_ObjCPreciseLifetime = 428,
+ CXCursor_ObjCReturnsInnerPointer = 429,
+ CXCursor_ObjCRequiresSuper = 430,
+ CXCursor_ObjCRootClass = 431,
+ CXCursor_ObjCSubclassingRestricted = 432,
+ CXCursor_ObjCExplicitProtocolImpl = 433,
+ CXCursor_ObjCDesignatedInitializer = 434,
+ CXCursor_ObjCRuntimeVisible = 435,
+ CXCursor_ObjCBoxable = 436,
+ CXCursor_FlagEnum = 437,
+ CXCursor_LastAttr = CXCursor_FlagEnum,
/* Preprocessing */
CXCursor_PreprocessingDirective = 500,
@@ -3266,7 +3293,25 @@ enum CXTypeKind {
CXType_OCLSampler = 157,
CXType_OCLEvent = 158,
CXType_OCLQueue = 159,
- CXType_OCLReserveID = 160
+ CXType_OCLReserveID = 160,
+
+ CXType_ObjCObject = 161,
+ CXType_ObjCTypeParam = 162,
+ CXType_Attributed = 163,
+
+ CXType_OCLIntelSubgroupAVCMcePayload = 164,
+ CXType_OCLIntelSubgroupAVCImePayload = 165,
+ CXType_OCLIntelSubgroupAVCRefPayload = 166,
+ CXType_OCLIntelSubgroupAVCSicPayload = 167,
+ CXType_OCLIntelSubgroupAVCMceResult = 168,
+ CXType_OCLIntelSubgroupAVCImeResult = 169,
+ CXType_OCLIntelSubgroupAVCRefResult = 170,
+ CXType_OCLIntelSubgroupAVCSicResult = 171,
+ CXType_OCLIntelSubgroupAVCImeResultSingleRefStreamout = 172,
+ CXType_OCLIntelSubgroupAVCImeResultDualRefStreamout = 173,
+ CXType_OCLIntelSubgroupAVCImeSingleRefStreamin = 174,
+
+ CXType_OCLIntelSubgroupAVCImeDualRefStreamin = 175
};
/**
@@ -3291,6 +3336,7 @@ enum CXCallingConv {
CXCallingConv_Swift = 13,
CXCallingConv_PreserveMost = 14,
CXCallingConv_PreserveAll = 15,
+ CXCallingConv_AArch64VectorCall = 16,
CXCallingConv_Invalid = 100,
CXCallingConv_Unexposed = 200
@@ -3628,6 +3674,43 @@ CINDEX_LINKAGE int clang_getNumArgTypes(CXType T);
CINDEX_LINKAGE CXType clang_getArgType(CXType T, unsigned i);
/**
+ * Retrieves the base type of the ObjCObjectType.
+ *
+ * If the type is not an ObjC object, an invalid type is returned.
+ */
+CINDEX_LINKAGE CXType clang_Type_getObjCObjectBaseType(CXType T);
+
+/**
+ * Retrieve the number of protocol references associated with an ObjC object/id.
+ *
+ * If the type is not an ObjC object, 0 is returned.
+ */
+CINDEX_LINKAGE unsigned clang_Type_getNumObjCProtocolRefs(CXType T);
+
+/**
+ * Retrieve the decl for a protocol reference for an ObjC object/id.
+ *
+ * If the type is not an ObjC object or there are not enough protocol
+ * references, an invalid cursor is returned.
+ */
+CINDEX_LINKAGE CXCursor clang_Type_getObjCProtocolDecl(CXType T, unsigned i);
+
+/**
+ * Retreive the number of type arguments associated with an ObjC object.
+ *
+ * If the type is not an ObjC object, 0 is returned.
+ */
+CINDEX_LINKAGE unsigned clang_Type_getNumObjCTypeArgs(CXType T);
+
+/**
+ * Retrieve a type argument associated with an ObjC object.
+ *
+ * If the type is not an ObjC or the index is not valid,
+ * an invalid type is returned.
+ */
+CINDEX_LINKAGE CXType clang_Type_getObjCTypeArg(CXType T, unsigned i);
+
+/**
* Return 1 if the CXType is a variadic function type, and 0 otherwise.
*/
CINDEX_LINKAGE unsigned clang_isFunctionTypeVariadic(CXType T);
@@ -3700,6 +3783,33 @@ CINDEX_LINKAGE CXType clang_Type_getNamedType(CXType T);
*/
CINDEX_LINKAGE unsigned clang_Type_isTransparentTagTypedef(CXType T);
+enum CXTypeNullabilityKind {
+ /**
+ * Values of this type can never be null.
+ */
+ CXTypeNullability_NonNull = 0,
+ /**
+ * Values of this type can be null.
+ */
+ CXTypeNullability_Nullable = 1,
+ /**
+ * Whether values of this type can be null is (explicitly)
+ * unspecified. This captures a (fairly rare) case where we
+ * can't conclude anything about the nullability of the type even
+ * though it has been considered.
+ */
+ CXTypeNullability_Unspecified = 2,
+ /**
+ * Nullability is not applicable to this type.
+ */
+ CXTypeNullability_Invalid = 3
+};
+
+/**
+ * Retrieve the nullability kind of a pointer type.
+ */
+CINDEX_LINKAGE enum CXTypeNullabilityKind clang_Type_getNullability(CXType T);
+
/**
* List the possible error codes for \c clang_Type_getSizeOf,
* \c clang_Type_getAlignOf, \c clang_Type_getOffsetOf and
@@ -3779,6 +3889,13 @@ CINDEX_LINKAGE long long clang_Type_getSizeOf(CXType T);
CINDEX_LINKAGE long long clang_Type_getOffsetOf(CXType T, const char *S);
/**
+ * Return the type that was modified by this attributed type.
+ *
+ * If the type is not an attributed type, an invalid type is returned.
+ */
+CINDEX_LINKAGE CXType clang_Type_getModifiedType(CXType T);
+
+/**
* Return the offset of the field represented by the Cursor.
*
* If the cursor is not a field declaration, -1 is returned.
@@ -4348,6 +4465,18 @@ CINDEX_LINKAGE unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C,
unsigned reserved);
/**
+ * Given a cursor that represents a property declaration, return the
+ * name of the method that implements the getter.
+ */
+CINDEX_LINKAGE CXString clang_Cursor_getObjCPropertyGetterName(CXCursor C);
+
+/**
+ * Given a cursor that represents a property declaration, return the
+ * name of the method that implements the setter, if any.
+ */
+CINDEX_LINKAGE CXString clang_Cursor_getObjCPropertySetterName(CXCursor C);
+
+/**
* 'Qualifiers' written next to the return and parameter types in
* Objective-C method declarations.
*/
@@ -5492,9 +5621,14 @@ enum CXCompletionContext {
CXCompletionContext_NaturalLanguage = 1 << 21,
/**
+ * #include file completions should be included in the results.
+ */
+ CXCompletionContext_IncludedFile = 1 << 22,
+
+ /**
* The current context is unknown, so set all contexts.
*/
- CXCompletionContext_Unknown = ((1 << 22) - 1)
+ CXCompletionContext_Unknown = ((1 << 23) - 1)
};
/**
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index a9ab687a8de9..13870116c7fd 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -15,6 +15,7 @@
#ifndef LLVM_CLANG_AST_ASTCONTEXT_H
#define LLVM_CLANG_AST_ASTCONTEXT_H
+#include "clang/AST/ASTContextAllocate.h"
#include "clang/AST/ASTTypeTraits.h"
#include "clang/AST/CanonicalType.h"
#include "clang/AST/CommentCommandTraits.h"
@@ -22,6 +23,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclarationName.h"
+#include "clang/AST/Expr.h"
#include "clang/AST/ExternalASTSource.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/PrettyPrinter.h"
@@ -30,6 +32,7 @@
#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
#include "clang/Basic/AddressSpaces.h"
+#include "clang/Basic/AttrKinds.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/LangOptions.h"
@@ -79,6 +82,7 @@ struct fltSemantics;
namespace clang {
+class APFixedPoint;
class APValue;
class ASTMutationListener;
class ASTRecordLayout;
@@ -92,6 +96,7 @@ class CXXMethodDecl;
class CXXRecordDecl;
class DiagnosticsEngine;
class Expr;
+class FixedPointSemantics;
class MangleContext;
class MangleNumberingContext;
class MaterializeTemporaryExpr;
@@ -148,6 +153,22 @@ struct TypeInfo {
/// Holds long-lived AST nodes (such as types and decls) that can be
/// referred to throughout the semantic analysis of a file.
class ASTContext : public RefCountedBase<ASTContext> {
+public:
+ /// Copy initialization expr of a __block variable and a boolean flag that
+ /// indicates whether the expression can throw.
+ struct BlockVarCopyInit {
+ BlockVarCopyInit() = default;
+ BlockVarCopyInit(Expr *CopyExpr, bool CanThrow)
+ : ExprAndFlag(CopyExpr, CanThrow) {}
+ void setExprAndFlag(Expr *CopyExpr, bool CanThrow) {
+ ExprAndFlag.setPointerAndInt(CopyExpr, CanThrow);
+ }
+ Expr *getCopyExpr() const { return ExprAndFlag.getPointer(); }
+ bool canThrow() const { return ExprAndFlag.getInt(); }
+ llvm::PointerIntPair<Expr *, 1, bool> ExprAndFlag;
+ };
+
+private:
friend class NestedNameSpecifier;
mutable SmallVector<Type *, 0> Types;
@@ -242,8 +263,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// interface.
llvm::DenseMap<const ObjCMethodDecl*,const ObjCMethodDecl*> ObjCMethodRedecls;
- /// Mapping from __block VarDecls to their copy initialization expr.
- llvm::DenseMap<const VarDecl*, Expr*> BlockVarCopyInits;
+ /// Mapping from __block VarDecls to BlockVarCopyInit.
+ llvm::DenseMap<const VarDecl *, BlockVarCopyInit> BlockVarCopyInits;
/// Mapping from class scope functions specialization to their
/// template patterns.
@@ -316,7 +337,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
mutable IdentifierInfo *BoolName = nullptr;
/// The identifier 'NSObject'.
- IdentifierInfo *NSObjectName = nullptr;
+ mutable IdentifierInfo *NSObjectName = nullptr;
/// The identifier 'NSCopying'.
IdentifierInfo *NSCopyingName = nullptr;
@@ -549,26 +570,6 @@ public:
IntrusiveRefCntPtr<ExternalASTSource> ExternalSource;
ASTMutationListener *Listener = nullptr;
- /// Contains parents of a node.
- using ParentVector = llvm::SmallVector<ast_type_traits::DynTypedNode, 2>;
-
- /// Maps from a node to its parents. This is used for nodes that have
- /// pointer identity only, which are more common and we can save space by
- /// only storing a unique pointer to them.
- using ParentMapPointers =
- llvm::DenseMap<const void *,
- llvm::PointerUnion4<const Decl *, const Stmt *,
- ast_type_traits::DynTypedNode *,
- ParentVector *>>;
-
- /// Parent map for nodes without pointer identity. We store a full
- /// DynTypedNode for all keys.
- using ParentMapOtherNodes =
- llvm::DenseMap<ast_type_traits::DynTypedNode,
- llvm::PointerUnion4<const Decl *, const Stmt *,
- ast_type_traits::DynTypedNode *,
- ParentVector *>>;
-
/// Container for either a single DynTypedNode or for an ArrayRef to
/// DynTypedNode. For use with ParentMap.
class DynTypedNodeList {
@@ -610,7 +611,17 @@ public:
}
};
- /// Returns the parents of the given node.
+ // A traversal scope limits the parts of the AST visible to certain analyses.
+ // RecursiveASTVisitor::TraverseAST will only visit reachable nodes, and
+ // getParents() will only observe reachable parent edges.
+ //
+ // The scope is defined by a set of "top-level" declarations.
+ // Initially, it is the entire TU: {getTranslationUnitDecl()}.
+ // Changing the scope clears the parent cache, which is expensive to rebuild.
+ std::vector<Decl *> getTraversalScope() const { return TraversalScope; }
+ void setTraversalScope(const std::vector<Decl *> &);
+
+ /// Returns the parents of the given node (within the traversal scope).
///
/// Note that this will lazily compute the parents of all nodes
/// and store them for later retrieval. Thus, the first call is O(n)
@@ -977,7 +988,8 @@ public:
/// Get the additional modules in which the definition \p Def has
/// been merged.
ArrayRef<Module*> getModulesWithMergedDefinition(const NamedDecl *Def) {
- auto MergedIt = MergedDefModules.find(Def);
+ auto MergedIt =
+ MergedDefModules.find(cast<NamedDecl>(Def->getCanonicalDecl()));
if (MergedIt == MergedDefModules.end())
return None;
return MergedIt->second;
@@ -1041,6 +1053,9 @@ public:
CanQualType OCLSamplerTy, OCLEventTy, OCLClkEventTy;
CanQualType OCLQueueTy, OCLReserveIDTy;
CanQualType OMPArraySectionTy;
+#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
+ CanQualType Id##Ty;
+#include "clang/Basic/OpenCLExtensionTypes.def"
// Types for deductions in C++0x [stmt.ranged]'s desugaring. Built on demand.
mutable QualType AutoDeductTy; // Deduction against 'auto'.
@@ -1403,7 +1418,7 @@ public:
QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType TST) const;
- QualType getAttributedType(AttributedType::Kind attrKind,
+ QualType getAttributedType(attr::Kind attrKind,
QualType modifiedType,
QualType equivalentType);
@@ -1656,7 +1671,7 @@ public:
}
/// Retrieve the identifier 'NSObject'.
- IdentifierInfo *getNSObjectName() {
+ IdentifierInfo *getNSObjectName() const {
if (!NSObjectName) {
NSObjectName = &Idents.get("NSObject");
}
@@ -1961,6 +1976,9 @@ public:
unsigned char getFixedPointScale(QualType Ty) const;
unsigned char getFixedPointIBits(QualType Ty) const;
+ FixedPointSemantics getFixedPointSemantics(QualType Ty) const;
+ APFixedPoint getFixedPointMax(QualType Ty) const;
+ APFixedPoint getFixedPointMin(QualType Ty) const;
DeclarationNameInfo getNameForTemplate(TemplateName Name,
SourceLocation NameLoc) const;
@@ -2488,6 +2506,8 @@ public:
unsigned getTargetAddressSpace(LangAS AS) const;
+ LangAS getLangASForBuiltinAddressSpace(unsigned AS) const;
+
/// Get target-dependent integer value for null pointer which is used for
/// constant folding.
uint64_t getTargetNullPointerValue(QualType QT) const;
@@ -2657,12 +2677,13 @@ public:
/// otherwise returns null.
const ObjCInterfaceDecl *getObjContainingInterface(const NamedDecl *ND) const;
- /// Set the copy inialization expression of a block var decl.
- void setBlockVarCopyInits(VarDecl*VD, Expr* Init);
+ /// Set the copy inialization expression of a block var decl. \p CanThrow
+ /// indicates whether the copy expression can throw or not.
+ void setBlockVarCopyInit(const VarDecl* VD, Expr *CopyExpr, bool CanThrow);
/// Get the copy initialization expression of the VarDecl \p VD, or
/// nullptr if none exists.
- Expr *getBlockVarCopyInits(const VarDecl* VD);
+ BlockVarCopyInit getBlockVarCopyInit(const VarDecl* VD) const;
/// Allocate an uninitialized TypeSourceInfo.
///
@@ -2718,7 +2739,7 @@ public:
/// predicate.
void forEachMultiversionedFunctionVersion(
const FunctionDecl *FD,
- llvm::function_ref<void(const FunctionDecl *)> Pred) const;
+ llvm::function_ref<void(FunctionDecl *)> Pred) const;
const CXXConstructorDecl *
getCopyConstructorForExceptionObject(CXXRecordDecl *RD);
@@ -2894,13 +2915,13 @@ private:
// but we include it here so that ASTContext can quickly deallocate them.
llvm::PointerIntPair<StoredDeclsMap *, 1> LastSDM;
- std::unique_ptr<ParentMapPointers> PointerParents;
- std::unique_ptr<ParentMapOtherNodes> OtherParents;
+ std::vector<Decl *> TraversalScope;
+ class ParentMap;
+ std::unique_ptr<ParentMap> Parents;
std::unique_ptr<VTableContextBase> VTContext;
void ReleaseDeclContextMaps();
- void ReleaseParentMapEntries();
public:
enum PragmaSectionFlag : unsigned {
@@ -2949,8 +2970,8 @@ inline Selector GetUnarySelector(StringRef name, ASTContext &Ctx) {
/// This placement form of operator new uses the ASTContext's allocator for
/// obtaining memory.
///
-/// IMPORTANT: These are also declared in clang/AST/AttrIterator.h! Any changes
-/// here need to also be made there.
+/// IMPORTANT: These are also declared in clang/AST/ASTContextAllocate.h!
+/// Any changes here need to also be made there.
///
/// We intentionally avoid using a nothrow specification here so that the calls
/// to this operator will not perform a null check on the result -- the
@@ -2973,7 +2994,7 @@ inline Selector GetUnarySelector(StringRef name, ASTContext &Ctx) {
/// allocator supports it).
/// @return The allocated memory. Could be nullptr.
inline void *operator new(size_t Bytes, const clang::ASTContext &C,
- size_t Alignment) {
+ size_t Alignment /* = 8 */) {
return C.Allocate(Bytes, Alignment);
}
@@ -3011,7 +3032,7 @@ inline void operator delete(void *Ptr, const clang::ASTContext &C, size_t) {
/// allocator supports it).
/// @return The allocated memory. Could be nullptr.
inline void *operator new[](size_t Bytes, const clang::ASTContext& C,
- size_t Alignment = 8) {
+ size_t Alignment /* = 8 */) {
return C.Allocate(Bytes, Alignment);
}
diff --git a/include/clang/AST/ASTContextAllocate.h b/include/clang/AST/ASTContextAllocate.h
new file mode 100644
index 000000000000..5b9eed208a4d
--- /dev/null
+++ b/include/clang/AST/ASTContextAllocate.h
@@ -0,0 +1,38 @@
+//===- ASTContextAllocate.h - ASTContext allocate functions -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares ASTContext allocation functions separate from the main
+// code in ASTContext.h.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_ASTCONTEXTALLOCATE_H
+#define LLVM_CLANG_AST_ASTCONTEXTALLOCATE_H
+
+#include <cstddef>
+
+namespace clang {
+
+class ASTContext;
+
+} // namespace clang
+
+// Defined in ASTContext.h
+void *operator new(size_t Bytes, const clang::ASTContext &C,
+ size_t Alignment = 8);
+void *operator new[](size_t Bytes, const clang::ASTContext &C,
+ size_t Alignment = 8);
+
+// It is good practice to pair new/delete operators. Also, MSVC gives many
+// warnings if a matching delete overload is not declared, even though the
+// throw() spec guarantees it will not be implicitly called.
+void operator delete(void *Ptr, const clang::ASTContext &C, size_t);
+void operator delete[](void *Ptr, const clang::ASTContext &C, size_t);
+
+#endif // LLVM_CLANG_AST_ASTCONTEXTALLOCATE_H
diff --git a/include/clang/AST/ASTDiagnostic.h b/include/clang/AST/ASTDiagnostic.h
index 2534272da3a3..fe92604587ef 100644
--- a/include/clang/AST/ASTDiagnostic.h
+++ b/include/clang/AST/ASTDiagnostic.h
@@ -11,19 +11,9 @@
#define LLVM_CLANG_AST_ASTDIAGNOSTIC_H
#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticAST.h"
namespace clang {
- namespace diag {
- enum {
-#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
- SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
-#define ASTSTART
-#include "clang/Basic/DiagnosticASTKinds.inc"
-#undef DIAG
- NUM_BUILTIN_AST_DIAGNOSTICS
- };
- } // end namespace diag
-
/// DiagnosticsEngine argument formatting function for diagnostics that
/// involve AST nodes.
///
diff --git a/include/clang/AST/ASTDumperUtils.h b/include/clang/AST/ASTDumperUtils.h
new file mode 100644
index 000000000000..5e62e902b423
--- /dev/null
+++ b/include/clang/AST/ASTDumperUtils.h
@@ -0,0 +1,97 @@
+//===--- ASTDumperUtils.h - Printing of AST nodes -------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements AST utilities for traversal down the tree.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_ASTDUMPERUTILS_H
+#define LLVM_CLANG_AST_ASTDUMPERUTILS_H
+
+#include "llvm/Support/raw_ostream.h"
+
+namespace clang {
+
+// Colors used for various parts of the AST dump
+// Do not use bold yellow for any text. It is hard to read on white screens.
+
+struct TerminalColor {
+ llvm::raw_ostream::Colors Color;
+ bool Bold;
+};
+
+// Red - CastColor
+// Green - TypeColor
+// Bold Green - DeclKindNameColor, UndeserializedColor
+// Yellow - AddressColor, LocationColor
+// Blue - CommentColor, NullColor, IndentColor
+// Bold Blue - AttrColor
+// Bold Magenta - StmtColor
+// Cyan - ValueKindColor, ObjectKindColor
+// Bold Cyan - ValueColor, DeclNameColor
+
+// Decl kind names (VarDecl, FunctionDecl, etc)
+static const TerminalColor DeclKindNameColor = {llvm::raw_ostream::GREEN, true};
+// Attr names (CleanupAttr, GuardedByAttr, etc)
+static const TerminalColor AttrColor = {llvm::raw_ostream::BLUE, true};
+// Statement names (DeclStmt, ImplicitCastExpr, etc)
+static const TerminalColor StmtColor = {llvm::raw_ostream::MAGENTA, true};
+// Comment names (FullComment, ParagraphComment, TextComment, etc)
+static const TerminalColor CommentColor = {llvm::raw_ostream::BLUE, false};
+
+// Type names (int, float, etc, plus user defined types)
+static const TerminalColor TypeColor = {llvm::raw_ostream::GREEN, false};
+
+// Pointer address
+static const TerminalColor AddressColor = {llvm::raw_ostream::YELLOW, false};
+// Source locations
+static const TerminalColor LocationColor = {llvm::raw_ostream::YELLOW, false};
+
+// lvalue/xvalue
+static const TerminalColor ValueKindColor = {llvm::raw_ostream::CYAN, false};
+// bitfield/objcproperty/objcsubscript/vectorcomponent
+static const TerminalColor ObjectKindColor = {llvm::raw_ostream::CYAN, false};
+
+// Null statements
+static const TerminalColor NullColor = {llvm::raw_ostream::BLUE, false};
+
+// Undeserialized entities
+static const TerminalColor UndeserializedColor = {llvm::raw_ostream::GREEN,
+ true};
+
+// CastKind from CastExpr's
+static const TerminalColor CastColor = {llvm::raw_ostream::RED, false};
+
+// Value of the statement
+static const TerminalColor ValueColor = {llvm::raw_ostream::CYAN, true};
+// Decl names
+static const TerminalColor DeclNameColor = {llvm::raw_ostream::CYAN, true};
+
+// Indents ( `, -. | )
+static const TerminalColor IndentColor = {llvm::raw_ostream::BLUE, false};
+
+class ColorScope {
+ llvm::raw_ostream &OS;
+ const bool ShowColors;
+
+public:
+ ColorScope(llvm::raw_ostream &OS, bool ShowColors, TerminalColor Color)
+ : OS(OS), ShowColors(ShowColors) {
+ if (ShowColors)
+ OS.changeColor(Color.Color, Color.Bold);
+ }
+ ~ColorScope() {
+ if (ShowColors)
+ OS.resetColor();
+ }
+};
+
+} // namespace clang
+
+#endif // LLVM_CLANG_AST_ASTDUMPERUTILS_H
diff --git a/include/clang/AST/ASTImporter.h b/include/clang/AST/ASTImporter.h
index 2e9a8775a8a2..dbb9cf35ddea 100644
--- a/include/clang/AST/ASTImporter.h
+++ b/include/clang/AST/ASTImporter.h
@@ -25,12 +25,15 @@
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Error.h"
#include <utility>
namespace clang {
class ASTContext;
+class ASTImporterLookupTable;
class CXXBaseSpecifier;
class CXXCtorInitializer;
class Decl;
@@ -43,6 +46,29 @@ class TagDecl;
class TypeSourceInfo;
class Attr;
+ class ImportError : public llvm::ErrorInfo<ImportError> {
+ public:
+ /// \brief Kind of error when importing an AST component.
+ enum ErrorKind {
+ NameConflict, /// Naming ambiguity (likely ODR violation).
+ UnsupportedConstruct, /// Not supported node or case.
+ Unknown /// Other error.
+ };
+
+ ErrorKind Error;
+
+ static char ID;
+
+ ImportError() : Error(Unknown) { }
+ ImportError(const ImportError &Other) : Error(Other.Error) { }
+ ImportError(ErrorKind Error) : Error(Error) { }
+
+ std::string toString() const;
+
+ void log(raw_ostream &OS) const override;
+ std::error_code convertToErrorCode() const override;
+ };
+
// \brief Returns with a list of declarations started from the canonical decl
// then followed by subsequent decls in the translation unit.
// This gives a canonical list for each entry in the redecl chain.
@@ -55,12 +81,21 @@ class Attr;
/// Imports selected nodes from one AST context into another context,
/// merging AST nodes where appropriate.
class ASTImporter {
+ friend class ASTNodeImporter;
public:
using NonEquivalentDeclSet = llvm::DenseSet<std::pair<Decl *, Decl *>>;
using ImportedCXXBaseSpecifierMap =
llvm::DenseMap<const CXXBaseSpecifier *, CXXBaseSpecifier *>;
private:
+
+ /// Pointer to the import specific lookup table, which may be shared
+ /// amongst several ASTImporter objects.
+ /// This is an externally managed resource (and should exist during the
+ /// lifetime of the ASTImporter object)
+ /// If not set then the original C/C++ lookup is used.
+ ASTImporterLookupTable *LookupTable = nullptr;
+
/// The contexts we're importing to and from.
ASTContext &ToContext, &FromContext;
@@ -98,9 +133,13 @@ class Attr;
/// (which we have already complained about).
NonEquivalentDeclSet NonEquivalentDecls;
+ using FoundDeclsTy = SmallVector<NamedDecl *, 2>;
+ FoundDeclsTy findDeclsInToCtx(DeclContext *DC, DeclarationName Name);
+
+ void AddToLookupTable(Decl *ToD);
+
public:
- /// Create a new AST importer.
- ///
+
/// \param ToContext The context we'll be importing into.
///
/// \param ToFileManager The file manager we'll be importing into.
@@ -112,9 +151,14 @@ class Attr;
/// \param MinimalImport If true, the importer will attempt to import
/// as little as it can, e.g., by importing declarations as forward
/// declarations that can be completed at a later point.
+ ///
+ /// \param LookupTable The importer specific lookup table which may be
+ /// shared amongst several ASTImporter objects.
+ /// If not set then the original C/C++ lookup is used.
ASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
ASTContext &FromContext, FileManager &FromFileManager,
- bool MinimalImport);
+ bool MinimalImport,
+ ASTImporterLookupTable *LookupTable = nullptr);
virtual ~ASTImporter();
@@ -122,31 +166,60 @@ class Attr;
/// to-be-completed forward declarations when possible.
bool isMinimalImport() const { return Minimal; }
+ /// \brief Import the given object, returns the result.
+ ///
+ /// \param To Import the object into this variable.
+ /// \param From Object to import.
+ /// \return Error information (success or error).
+ template <typename ImportT>
+ LLVM_NODISCARD llvm::Error importInto(ImportT &To, const ImportT &From) {
+ To = Import(From);
+ if (From && !To)
+ return llvm::make_error<ImportError>();
+ return llvm::Error::success();
+ // FIXME: this should be the final code
+ //auto ToOrErr = Import(From);
+ //if (ToOrErr)
+ // To = *ToOrErr;
+ //return ToOrErr.takeError();
+ }
+
/// Import the given type from the "from" context into the "to"
- /// context.
+ /// context. A null type is imported as a null type (no error).
///
- /// \returns the equivalent type in the "to" context, or a NULL type if
- /// an error occurred.
+ /// \returns The equivalent type in the "to" context, or the import error.
+ llvm::Expected<QualType> Import_New(QualType FromT);
+ // FIXME: Remove this version.
QualType Import(QualType FromT);
/// Import the given type source information from the
/// "from" context into the "to" context.
///
- /// \returns the equivalent type source information in the "to"
- /// context, or NULL if an error occurred.
+ /// \returns The equivalent type source information in the "to"
+ /// context, or the import error.
+ llvm::Expected<TypeSourceInfo *> Import_New(TypeSourceInfo *FromTSI);
+ // FIXME: Remove this version.
TypeSourceInfo *Import(TypeSourceInfo *FromTSI);
/// Import the given attribute from the "from" context into the
/// "to" context.
///
- /// \returns the equivalent attribute in the "to" context.
+ /// \returns The equivalent attribute in the "to" context, or the import
+ /// error.
+ llvm::Expected<Attr *> Import_New(const Attr *FromAttr);
+ // FIXME: Remove this version.
Attr *Import(const Attr *FromAttr);
/// Import the given declaration from the "from" context into the
/// "to" context.
///
- /// \returns the equivalent declaration in the "to" context, or a NULL type
- /// if an error occurred.
+ /// \returns The equivalent declaration in the "to" context, or the import
+ /// error.
+ llvm::Expected<Decl *> Import_New(Decl *FromD);
+ llvm::Expected<Decl *> Import_New(const Decl *FromD) {
+ return Import_New(const_cast<Decl *>(FromD));
+ }
+ // FIXME: Remove this version.
Decl *Import(Decl *FromD);
Decl *Import(const Decl *FromD) {
return Import(const_cast<Decl *>(FromD));
@@ -155,104 +228,137 @@ class Attr;
/// Return the copy of the given declaration in the "to" context if
/// it has already been imported from the "from" context. Otherwise return
/// NULL.
- Decl *GetAlreadyImportedOrNull(Decl *FromD);
+ Decl *GetAlreadyImportedOrNull(const Decl *FromD) const;
/// Import the given declaration context from the "from"
/// AST context into the "to" AST context.
///
/// \returns the equivalent declaration context in the "to"
- /// context, or a NULL type if an error occurred.
- DeclContext *ImportContext(DeclContext *FromDC);
+ /// context, or error value.
+ llvm::Expected<DeclContext *> ImportContext(DeclContext *FromDC);
/// Import the given expression from the "from" context into the
/// "to" context.
///
- /// \returns the equivalent expression in the "to" context, or NULL if
- /// an error occurred.
+ /// \returns The equivalent expression in the "to" context, or the import
+ /// error.
+ llvm::Expected<Expr *> Import_New(Expr *FromE);
+ // FIXME: Remove this version.
Expr *Import(Expr *FromE);
/// Import the given statement from the "from" context into the
/// "to" context.
///
- /// \returns the equivalent statement in the "to" context, or NULL if
- /// an error occurred.
+ /// \returns The equivalent statement in the "to" context, or the import
+ /// error.
+ llvm::Expected<Stmt *> Import_New(Stmt *FromS);
+ // FIXME: Remove this version.
Stmt *Import(Stmt *FromS);
/// Import the given nested-name-specifier from the "from"
/// context into the "to" context.
///
- /// \returns the equivalent nested-name-specifier in the "to"
- /// context, or NULL if an error occurred.
+ /// \returns The equivalent nested-name-specifier in the "to"
+ /// context, or the import error.
+ llvm::Expected<NestedNameSpecifier *>
+ Import_New(NestedNameSpecifier *FromNNS);
+ // FIXME: Remove this version.
NestedNameSpecifier *Import(NestedNameSpecifier *FromNNS);
- /// Import the given nested-name-specifier from the "from"
+ /// Import the given nested-name-specifier-loc from the "from"
/// context into the "to" context.
///
- /// \returns the equivalent nested-name-specifier in the "to"
- /// context.
+ /// \returns The equivalent nested-name-specifier-loc in the "to"
+ /// context, or the import error.
+ llvm::Expected<NestedNameSpecifierLoc>
+ Import_New(NestedNameSpecifierLoc FromNNS);
+ // FIXME: Remove this version.
NestedNameSpecifierLoc Import(NestedNameSpecifierLoc FromNNS);
- /// Import the goven template name from the "from" context into the
- /// "to" context.
+ /// Import the given template name from the "from" context into the
+ /// "to" context, or the import error.
+ llvm::Expected<TemplateName> Import_New(TemplateName From);
+ // FIXME: Remove this version.
TemplateName Import(TemplateName From);
/// Import the given source location from the "from" context into
/// the "to" context.
///
- /// \returns the equivalent source location in the "to" context, or an
- /// invalid source location if an error occurred.
+ /// \returns The equivalent source location in the "to" context, or the
+ /// import error.
+ llvm::Expected<SourceLocation> Import_New(SourceLocation FromLoc);
+ // FIXME: Remove this version.
SourceLocation Import(SourceLocation FromLoc);
/// Import the given source range from the "from" context into
/// the "to" context.
///
- /// \returns the equivalent source range in the "to" context, or an
- /// invalid source location if an error occurred.
+ /// \returns The equivalent source range in the "to" context, or the import
+ /// error.
+ llvm::Expected<SourceRange> Import_New(SourceRange FromRange);
+ // FIXME: Remove this version.
SourceRange Import(SourceRange FromRange);
/// Import the given declaration name from the "from"
/// context into the "to" context.
///
- /// \returns the equivalent declaration name in the "to" context,
- /// or an empty declaration name if an error occurred.
+ /// \returns The equivalent declaration name in the "to" context, or the
+ /// import error.
+ llvm::Expected<DeclarationName> Import_New(DeclarationName FromName);
+ // FIXME: Remove this version.
DeclarationName Import(DeclarationName FromName);
/// Import the given identifier from the "from" context
/// into the "to" context.
///
- /// \returns the equivalent identifier in the "to" context.
+ /// \returns The equivalent identifier in the "to" context. Note: It
+ /// returns nullptr only if the FromId was nullptr.
IdentifierInfo *Import(const IdentifierInfo *FromId);
/// Import the given Objective-C selector from the "from"
/// context into the "to" context.
///
- /// \returns the equivalent selector in the "to" context.
+ /// \returns The equivalent selector in the "to" context, or the import
+ /// error.
+ llvm::Expected<Selector> Import_New(Selector FromSel);
+ // FIXME: Remove this version.
Selector Import(Selector FromSel);
/// Import the given file ID from the "from" context into the
/// "to" context.
///
- /// \returns the equivalent file ID in the source manager of the "to"
- /// context.
+ /// \returns The equivalent file ID in the source manager of the "to"
+ /// context, or the import error.
+ llvm::Expected<FileID> Import_New(FileID);
+ // FIXME: Remove this version.
FileID Import(FileID);
/// Import the given C++ constructor initializer from the "from"
/// context into the "to" context.
///
- /// \returns the equivalent initializer in the "to" context.
+ /// \returns The equivalent initializer in the "to" context, or the import
+ /// error.
+ llvm::Expected<CXXCtorInitializer *>
+ Import_New(CXXCtorInitializer *FromInit);
+ // FIXME: Remove this version.
CXXCtorInitializer *Import(CXXCtorInitializer *FromInit);
/// Import the given CXXBaseSpecifier from the "from" context into
/// the "to" context.
///
- /// \returns the equivalent CXXBaseSpecifier in the source manager of the
- /// "to" context.
+ /// \returns The equivalent CXXBaseSpecifier in the source manager of the
+ /// "to" context, or the import error.
+ llvm::Expected<CXXBaseSpecifier *>
+ Import_New(const CXXBaseSpecifier *FromSpec);
+ // FIXME: Remove this version.
CXXBaseSpecifier *Import(const CXXBaseSpecifier *FromSpec);
/// Import the definition of the given declaration, including all of
/// the declarations it contains.
- ///
- /// This routine is intended to be used
+ LLVM_NODISCARD llvm::Error ImportDefinition_New(Decl *From);
+
+ // FIXME: Compatibility function.
+ // Usages of this should be changed to ImportDefinition_New.
void ImportDefinition(Decl *From);
/// Cope with a name conflict when importing a declaration into the
@@ -333,6 +439,13 @@ class Attr;
/// equivalent.
bool IsStructurallyEquivalent(QualType From, QualType To,
bool Complain = true);
+
+ /// Determine the index of a field in its parent record.
+ /// F should be a field (or indirect field) declaration.
+ /// \returns The index of the field in its parent context (starting from 0).
+ /// On error `None` is returned (parent context is non-record).
+ static llvm::Optional<unsigned> getFieldIndex(Decl *F);
+
};
} // namespace clang
diff --git a/include/clang/AST/ASTImporterLookupTable.h b/include/clang/AST/ASTImporterLookupTable.h
new file mode 100644
index 000000000000..14cafe817ddc
--- /dev/null
+++ b/include/clang/AST/ASTImporterLookupTable.h
@@ -0,0 +1,75 @@
+//===- ASTImporterLookupTable.h - ASTImporter specific lookup--*- C++ -*---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ASTImporterLookupTable class which implements a
+// lookup procedure for the import mechanism.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_ASTIMPORTERLOOKUPTABLE_H
+#define LLVM_CLANG_AST_ASTIMPORTERLOOKUPTABLE_H
+
+#include "clang/AST/DeclBase.h" // lookup_result
+#include "clang/AST/DeclarationName.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SetVector.h"
+
+namespace clang {
+
+class ASTContext;
+class NamedDecl;
+class DeclContext;
+
+// There are certain cases when normal C/C++ lookup (localUncachedLookup)
+// does not find AST nodes. E.g.:
+// Example 1:
+// template <class T>
+// struct X {
+// friend void foo(); // this is never found in the DC of the TU.
+// };
+// Example 2:
+// // The fwd decl to Foo is not found in the lookupPtr of the DC of the
+// // translation unit decl.
+// // Here we could find the node by doing a traverse throught the list of
+// // the Decls in the DC, but that would not scale.
+// struct A { struct Foo *p; };
+// This is a severe problem because the importer decides if it has to create a
+// new Decl or not based on the lookup results.
+// To overcome these cases we need an importer specific lookup table which
+// holds every node and we are not interested in any C/C++ specific visibility
+// considerations. Simply, we must know if there is an existing Decl in a
+// given DC. Once we found it then we can handle any visibility related tasks.
+class ASTImporterLookupTable {
+
+ // We store a list of declarations for each name.
+ // And we collect these lists for each DeclContext.
+ // We could have a flat map with (DeclContext, Name) tuple as key, but a two
+ // level map seems easier to handle.
+ using DeclList = llvm::SmallSetVector<NamedDecl *, 2>;
+ using NameMap = llvm::SmallDenseMap<DeclarationName, DeclList, 4>;
+ using DCMap = llvm::DenseMap<DeclContext *, NameMap>;
+
+ void add(DeclContext *DC, NamedDecl *ND);
+ void remove(DeclContext *DC, NamedDecl *ND);
+
+ DCMap LookupTable;
+
+public:
+ ASTImporterLookupTable(TranslationUnitDecl &TU);
+ void add(NamedDecl *ND);
+ void remove(NamedDecl *ND);
+ using LookupResult = DeclList;
+ LookupResult lookup(DeclContext *DC, DeclarationName Name) const;
+ void dump(DeclContext *DC) const;
+ void dump() const;
+};
+
+} // namespace clang
+
+#endif // LLVM_CLANG_AST_ASTIMPORTERLOOKUPTABLE_H
diff --git a/include/clang/AST/ASTStructuralEquivalence.h b/include/clang/AST/ASTStructuralEquivalence.h
index d32f87d43e04..f8847505bc72 100644
--- a/include/clang/AST/ASTStructuralEquivalence.h
+++ b/include/clang/AST/ASTStructuralEquivalence.h
@@ -15,6 +15,7 @@
#ifndef LLVM_CLANG_AST_ASTSTRUCTURALEQUIVALENCE_H
#define LLVM_CLANG_AST_ASTSTRUCTURALEQUIVALENCE_H
+#include "clang/AST/DeclBase.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/Optional.h"
@@ -114,8 +115,19 @@ struct StructuralEquivalenceContext {
private:
/// Finish checking all of the structural equivalences.
///
- /// \returns true if an error occurred, false otherwise.
+ /// \returns true if the equivalence check failed (non-equivalence detected),
+ /// false if equivalence was detected.
bool Finish();
+
+ /// Check for common properties at Finish.
+ /// \returns true if D1 and D2 may be equivalent,
+ /// false if they are for sure not.
+ bool CheckCommonEquivalence(Decl *D1, Decl *D2);
+
+ /// Check for class dependent properties at Finish.
+ /// \returns true if D1 and D2 may be equivalent,
+ /// false if they are for sure not.
+ bool CheckKindSpecificEquivalence(Decl *D1, Decl *D2);
};
} // namespace clang
diff --git a/include/clang/AST/ASTVector.h b/include/clang/AST/ASTVector.h
index 80cd6b7007a6..51de119f080e 100644
--- a/include/clang/AST/ASTVector.h
+++ b/include/clang/AST/ASTVector.h
@@ -18,6 +18,7 @@
#ifndef LLVM_CLANG_AST_ASTVECTOR_H
#define LLVM_CLANG_AST_ASTVECTOR_H
+#include "clang/AST/ASTContextAllocate.h"
#include "llvm/ADT/PointerIntPair.h"
#include <algorithm>
#include <cassert>
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index 20922742f687..3a319326d269 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_AST_ATTR_H
#define LLVM_CLANG_AST_ATTR_H
+#include "clang/AST/ASTContextAllocate.h" // For Attrs.inc
#include "clang/AST/AttrIterator.h"
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
@@ -113,6 +114,19 @@ public:
void printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const;
};
+class TypeAttr : public Attr {
+protected:
+ TypeAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex,
+ bool IsLateParsed)
+ : Attr(AK, R, SpellingListIndex, IsLateParsed) {}
+
+public:
+ static bool classof(const Attr *A) {
+ return A->getKind() >= attr::FirstTypeAttr &&
+ A->getKind() <= attr::LastTypeAttr;
+ }
+};
+
class StmtAttr : public Attr {
protected:
StmtAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex,
diff --git a/include/clang/AST/AttrIterator.h b/include/clang/AST/AttrIterator.h
index 2087ecc0e70c..43ad1c931967 100644
--- a/include/clang/AST/AttrIterator.h
+++ b/include/clang/AST/AttrIterator.h
@@ -26,25 +26,6 @@ namespace clang {
class ASTContext;
class Attr;
-} // namespace clang
-
-// Defined in ASTContext.h
-void *operator new(size_t Bytes, const clang::ASTContext &C,
- size_t Alignment = 8);
-
-// FIXME: Being forced to not have a default argument here due to redeclaration
-// rules on default arguments sucks
-void *operator new[](size_t Bytes, const clang::ASTContext &C,
- size_t Alignment);
-
-// It is good practice to pair new/delete operators. Also, MSVC gives many
-// warnings if a matching delete overload is not declared, even though the
-// throw() spec guarantees it will not be implicitly called.
-void operator delete(void *Ptr, const clang::ASTContext &C, size_t);
-void operator delete[](void *Ptr, const clang::ASTContext &C, size_t);
-
-namespace clang {
-
/// AttrVec - A vector of Attr, which is how they are stored on the AST.
using AttrVec = SmallVector<Attr *, 4>;
diff --git a/include/clang/AST/AttrVisitor.h b/include/clang/AST/AttrVisitor.h
new file mode 100644
index 000000000000..867f9e7ad18d
--- /dev/null
+++ b/include/clang/AST/AttrVisitor.h
@@ -0,0 +1,76 @@
+//===- AttrVisitor.h - Visitor for Attr subclasses --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the AttrVisitor interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_ATTRVISITOR_H
+#define LLVM_CLANG_AST_ATTRVISITOR_H
+
+#include "clang/AST/Attr.h"
+
+namespace clang {
+
+namespace attrvisitor {
+
+/// A simple visitor class that helps create attribute visitors.
+template <template <typename> class Ptr, typename ImplClass,
+ typename RetTy = void, class... ParamTys>
+class Base {
+public:
+#define PTR(CLASS) typename Ptr<CLASS>::type
+#define DISPATCH(NAME) \
+ return static_cast<ImplClass *>(this)->Visit##NAME(static_cast<PTR(NAME)>(A))
+
+ RetTy Visit(PTR(Attr) A) {
+ switch (A->getKind()) {
+
+#define ATTR(NAME) \
+ case attr::NAME: \
+ DISPATCH(NAME##Attr);
+#include "clang/Basic/AttrList.inc"
+ }
+ llvm_unreachable("Attr that isn't part of AttrList.inc!");
+ }
+
+ // If the implementation chooses not to implement a certain visit
+ // method, fall back to the parent.
+#define ATTR(NAME) \
+ RetTy Visit##NAME##Attr(PTR(NAME##Attr) A) { DISPATCH(Attr); }
+#include "clang/Basic/AttrList.inc"
+
+ RetTy VisitAttr(PTR(Attr)) { return RetTy(); }
+
+#undef PTR
+#undef DISPATCH
+};
+
+} // namespace attrvisitor
+
+/// A simple visitor class that helps create attribute visitors.
+///
+/// This class does not preserve constness of Attr pointers (see
+/// also ConstAttrVisitor).
+template <typename ImplClass, typename RetTy = void, typename... ParamTys>
+class AttrVisitor : public attrvisitor::Base<std::add_pointer, ImplClass, RetTy,
+ ParamTys...> {};
+
+/// A simple visitor class that helps create attribute visitors.
+///
+/// This class preserves constness of Attr pointers (see also
+/// AttrVisitor).
+template <typename ImplClass, typename RetTy = void, typename... ParamTys>
+class ConstAttrVisitor
+ : public attrvisitor::Base<llvm::make_const_ptr, ImplClass, RetTy,
+ ParamTys...> {};
+
+} // namespace clang
+
+#endif // LLVM_CLANG_AST_ATTRVISITOR_H
diff --git a/include/clang/AST/BaseSubobject.h b/include/clang/AST/BaseSubobject.h
index 2b702c76b2fa..8fd4ac69ebd6 100644
--- a/include/clang/AST/BaseSubobject.h
+++ b/include/clang/AST/BaseSubobject.h
@@ -15,6 +15,7 @@
#define LLVM_CLANG_AST_BASESUBOBJECT_H
#include "clang/AST/CharUnits.h"
+#include "clang/AST/DeclCXX.h"
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/Support/type_traits.h"
#include <cstdint>
diff --git a/include/clang/AST/CMakeLists.txt b/include/clang/AST/CMakeLists.txt
index 942d08d585fe..da16987141c2 100644
--- a/include/clang/AST/CMakeLists.txt
+++ b/include/clang/AST/CMakeLists.txt
@@ -8,10 +8,15 @@ clang_tablegen(AttrImpl.inc -gen-clang-attr-impl
SOURCE ../Basic/Attr.td
TARGET ClangAttrImpl)
-clang_tablegen(AttrDump.inc -gen-clang-attr-dump
+clang_tablegen(AttrTextNodeDump.inc -gen-clang-attr-text-node-dump
-I ${CMAKE_CURRENT_SOURCE_DIR}/../../
SOURCE ../Basic/Attr.td
- TARGET ClangAttrDump)
+ TARGET ClangAttrTextDump)
+
+clang_tablegen(AttrNodeTraverse.inc -gen-clang-attr-node-traverse
+ -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
+ SOURCE ../Basic/Attr.td
+ TARGET ClangAttrTraverse)
clang_tablegen(AttrVisitor.inc -gen-clang-attr-ast-visitor
-I ${CMAKE_CURRENT_SOURCE_DIR}/../../
diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h
index 0e738da43ad4..c2f01e7d5460 100644
--- a/include/clang/AST/CanonicalType.h
+++ b/include/clang/AST/CanonicalType.h
@@ -510,7 +510,7 @@ struct CanProxyAdaptor<FunctionProtoType>
}
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariadic)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getTypeQuals)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getTypeQuals)
using param_type_iterator =
CanTypeIterator<FunctionProtoType::param_type_iterator>;
diff --git a/include/clang/AST/Comment.h b/include/clang/AST/Comment.h
index f5538dec2a14..1b590562e152 100644
--- a/include/clang/AST/Comment.h
+++ b/include/clang/AST/Comment.h
@@ -215,13 +215,9 @@ public:
SourceRange getSourceRange() const LLVM_READONLY { return Range; }
- SourceLocation getLocStart() const LLVM_READONLY {
- return Range.getBegin();
- }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return Range.getEnd();
- }
+ SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
SourceLocation getLocation() const LLVM_READONLY { return Loc; }
@@ -351,8 +347,7 @@ public:
}
SourceRange getCommandNameRange() const {
- return SourceRange(getLocStart().getLocWithOffset(-1),
- getLocEnd());
+ return SourceRange(getBeginLoc().getLocWithOffset(-1), getEndLoc());
}
RenderKind getRenderKind() const {
@@ -566,9 +561,9 @@ public:
ParagraphCommentBits.IsWhitespaceValid = false;
- setSourceRange(SourceRange(Content.front()->getLocStart(),
- Content.back()->getLocEnd()));
- setLocation(Content.front()->getLocStart());
+ setSourceRange(SourceRange(Content.front()->getBeginLoc(),
+ Content.back()->getEndLoc()));
+ setLocation(Content.front()->getBeginLoc());
}
static bool classof(const Comment *C) {
@@ -662,13 +657,13 @@ public:
}
SourceLocation getCommandNameBeginLoc() const {
- return getLocStart().getLocWithOffset(1);
+ return getBeginLoc().getLocWithOffset(1);
}
SourceRange getCommandNameRange(const CommandTraits &Traits) const {
StringRef Name = getCommandName(Traits);
return SourceRange(getCommandNameBeginLoc(),
- getLocStart().getLocWithOffset(1 + Name.size()));
+ getBeginLoc().getLocWithOffset(1 + Name.size()));
}
unsigned getNumArgs() const {
@@ -688,7 +683,7 @@ public:
if (Args.size() > 0) {
SourceLocation NewLocEnd = Args.back().Range.getEnd();
if (NewLocEnd.isValid())
- setSourceRange(SourceRange(getLocStart(), NewLocEnd));
+ setSourceRange(SourceRange(getBeginLoc(), NewLocEnd));
}
}
@@ -702,9 +697,9 @@ public:
void setParagraph(ParagraphComment *PC) {
Paragraph = PC;
- SourceLocation NewLocEnd = PC->getLocEnd();
+ SourceLocation NewLocEnd = PC->getEndLoc();
if (NewLocEnd.isValid())
- setSourceRange(SourceRange(getLocStart(), NewLocEnd));
+ setSourceRange(SourceRange(getBeginLoc(), NewLocEnd));
}
CommandMarkerKind getCommandMarker() const LLVM_READONLY {
@@ -978,7 +973,7 @@ public:
}
SourceRange getTextRange() const {
- return SourceRange(TextBegin, getLocEnd());
+ return SourceRange(TextBegin, getEndLoc());
}
};
@@ -1105,9 +1100,9 @@ public:
if (Blocks.empty())
return;
- setSourceRange(SourceRange(Blocks.front()->getLocStart(),
- Blocks.back()->getLocEnd()));
- setLocation(Blocks.front()->getLocStart());
+ setSourceRange(
+ SourceRange(Blocks.front()->getBeginLoc(), Blocks.back()->getEndLoc()));
+ setLocation(Blocks.front()->getBeginLoc());
}
static bool classof(const Comment *C) {
diff --git a/include/clang/AST/CommentDiagnostic.h b/include/clang/AST/CommentDiagnostic.h
index f3a209bf6e7c..b9816f1a8e62 100644
--- a/include/clang/AST/CommentDiagnostic.h
+++ b/include/clang/AST/CommentDiagnostic.h
@@ -10,20 +10,7 @@
#ifndef LLVM_CLANG_AST_COMMENTDIAGNOSTIC_H
#define LLVM_CLANG_AST_COMMENTDIAGNOSTIC_H
-#include "clang/Basic/Diagnostic.h"
-
-namespace clang {
- namespace diag {
- enum {
-#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
- SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
-#define COMMENTSTART
-#include "clang/Basic/DiagnosticCommentKinds.inc"
-#undef DIAG
- NUM_BUILTIN_COMMENT_DIAGNOSTICS
- };
- } // end namespace diag
-} // end namespace clang
+#include "clang/Basic/DiagnosticComment.h"
#endif
diff --git a/include/clang/AST/CommentVisitor.h b/include/clang/AST/CommentVisitor.h
index d1cc2d0a4e5e..e37e9d6cd299 100644
--- a/include/clang/AST/CommentVisitor.h
+++ b/include/clang/AST/CommentVisitor.h
@@ -11,22 +11,21 @@
#define LLVM_CLANG_AST_COMMENTVISITOR_H
#include "clang/AST/Comment.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/ErrorHandling.h"
namespace clang {
namespace comments {
-
-template <typename T> struct make_ptr { using type = T *; };
-template <typename T> struct make_const_ptr { using type = const T *; };
-
-template<template <typename> class Ptr, typename ImplClass, typename RetTy=void>
+template <template <typename> class Ptr, typename ImplClass,
+ typename RetTy = void, class... ParamTys>
class CommentVisitorBase {
public:
#define PTR(CLASS) typename Ptr<CLASS>::type
-#define DISPATCH(NAME, CLASS) \
- return static_cast<ImplClass*>(this)->visit ## NAME(static_cast<PTR(CLASS)>(C))
+#define DISPATCH(NAME, CLASS) \
+ return static_cast<ImplClass *>(this)->visit##NAME( \
+ static_cast<PTR(CLASS)>(C), std::forward<ParamTys>(P)...)
- RetTy visit(PTR(Comment) C) {
+ RetTy visit(PTR(Comment) C, ParamTys... P) {
if (!C)
return RetTy();
@@ -44,25 +43,26 @@ public:
// If the derived class does not implement a certain Visit* method, fall back
// on Visit* method for the superclass.
#define ABSTRACT_COMMENT(COMMENT) COMMENT
-#define COMMENT(CLASS, PARENT) \
- RetTy visit ## CLASS(PTR(CLASS) C) { DISPATCH(PARENT, PARENT); }
+#define COMMENT(CLASS, PARENT) \
+ RetTy visit##CLASS(PTR(CLASS) C, ParamTys... P) { DISPATCH(PARENT, PARENT); }
#include "clang/AST/CommentNodes.inc"
#undef ABSTRACT_COMMENT
#undef COMMENT
- RetTy visitComment(PTR(Comment) C) { return RetTy(); }
+ RetTy visitComment(PTR(Comment) C, ParamTys... P) { return RetTy(); }
#undef PTR
#undef DISPATCH
};
-template<typename ImplClass, typename RetTy=void>
-class CommentVisitor :
- public CommentVisitorBase<make_ptr, ImplClass, RetTy> {};
+template <typename ImplClass, typename RetTy = void, class... ParamTys>
+class CommentVisitor : public CommentVisitorBase<std::add_pointer, ImplClass,
+ RetTy, ParamTys...> {};
-template<typename ImplClass, typename RetTy=void>
-class ConstCommentVisitor :
- public CommentVisitorBase<make_const_ptr, ImplClass, RetTy> {};
+template <typename ImplClass, typename RetTy = void, class... ParamTys>
+class ConstCommentVisitor
+ : public CommentVisitorBase<llvm::make_const_ptr, ImplClass, RetTy,
+ ParamTys...> {};
} // namespace comments
} // namespace clang
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index ebdb2890daf5..de2765391f0f 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -15,6 +15,7 @@
#define LLVM_CLANG_AST_DECL_H
#include "clang/AST/APValue.h"
+#include "clang/AST/ASTContextAllocate.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/ExternalASTSource.h"
@@ -81,7 +82,7 @@ class VarTemplateDecl;
/// A client can read the relevant info using TypeLoc wrappers, e.g:
/// @code
/// TypeLoc TL = TypeSourceInfo->getTypeLoc();
-/// TL.getStartLoc().print(OS, SrcMgr);
+/// TL.getBeginLoc().print(OS, SrcMgr);
/// @endcode
class alignas(8) TypeSourceInfo {
// Contains a memory block after the class, used for type source information,
@@ -614,7 +615,7 @@ public:
return SourceRange(LocStart, RBraceLoc);
}
- SourceLocation getLocStart() const LLVM_READONLY { return LocStart; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return LocStart; }
SourceLocation getRBraceLoc() const { return RBraceLoc; }
void setLocStart(SourceLocation L) { LocStart = L; }
void setRBraceLoc(SourceLocation L) { RBraceLoc = L; }
@@ -735,7 +736,7 @@ public:
SourceRange getSourceRange() const override LLVM_READONLY;
- SourceLocation getLocStart() const LLVM_READONLY {
+ SourceLocation getBeginLoc() const LLVM_READONLY {
return getOuterLocStart();
}
@@ -866,8 +867,12 @@ private:
unsigned SClass : 3;
unsigned TSCSpec : 2;
unsigned InitStyle : 2;
+
+ /// Whether this variable is an ARC pseudo-__strong variable; see
+ /// isARCPseudoStrong() for details.
+ unsigned ARCPseudoStrong : 1;
};
- enum { NumVarDeclBits = 7 };
+ enum { NumVarDeclBits = 8 };
protected:
enum { NumParameterIndexBits = 8 };
@@ -940,10 +945,6 @@ protected:
/// Whether this variable is the for-in loop declaration in Objective-C.
unsigned ObjCForDecl : 1;
- /// Whether this variable is an ARC pseudo-__strong
- /// variable; see isARCPseudoStrong() for details.
- unsigned ARCPseudoStrong : 1;
-
/// Whether this variable is (C++1z) inline.
unsigned IsInline : 1;
@@ -965,6 +966,8 @@ protected:
/// Defines kind of the ImplicitParamDecl: 'this', 'self', 'vtt', '_cmd' or
/// something else.
unsigned ImplicitParamKind : 3;
+
+ unsigned EscapingByref : 1;
};
union {
@@ -1347,17 +1350,15 @@ public:
NonParmVarDeclBits.ObjCForDecl = FRD;
}
- /// Determine whether this variable is an ARC pseudo-__strong
- /// variable. A pseudo-__strong variable has a __strong-qualified
- /// type but does not actually retain the object written into it.
- /// Generally such variables are also 'const' for safety.
- bool isARCPseudoStrong() const {
- return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.ARCPseudoStrong;
- }
- void setARCPseudoStrong(bool ps) {
- assert(!isa<ParmVarDecl>(this));
- NonParmVarDeclBits.ARCPseudoStrong = ps;
- }
+ /// Determine whether this variable is an ARC pseudo-__strong variable. A
+ /// pseudo-__strong variable has a __strong-qualified type but does not
+ /// actually retain the object written into it. Generally such variables are
+ /// also 'const' for safety. There are 3 cases where this will be set, 1) if
+ /// the variable is annotated with the objc_externally_retained attribute, 2)
+ /// if its 'self' in a non-init method, or 3) if its the variable in an for-in
+ /// loop.
+ bool isARCPseudoStrong() const { return VarDeclBits.ARCPseudoStrong; }
+ void setARCPseudoStrong(bool PS) { VarDeclBits.ARCPseudoStrong = PS; }
/// Whether this variable is (C++1z) inline.
bool isInline() const {
@@ -1407,6 +1408,19 @@ public:
NonParmVarDeclBits.PreviousDeclInSameBlockScope = Same;
}
+ /// Indicates the capture is a __block variable that is captured by a block
+ /// that can potentially escape (a block for which BlockDecl::doesNotEscape
+ /// returns false).
+ bool isEscapingByref() const;
+
+ /// Indicates the capture is a __block variable that is never captured by an
+ /// escaping block.
+ bool isNonEscapingByref() const;
+
+ void setEscapingByref() {
+ NonParmVarDeclBits.EscapingByref = true;
+ }
+
/// Retrieve the variable declaration from which this variable could
/// be instantiated, if it is an instantiation (rather than a non-template).
VarDecl *getTemplateInstantiationPattern() const;
@@ -1461,6 +1475,9 @@ public:
// has no definition within this source file.
bool isKnownToBeDefined() const;
+ /// Do we need to emit an exit-time destructor for this variable?
+ bool isNoDestroy(const ASTContext &) const;
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K >= firstVar && K <= lastVar; }
@@ -1701,6 +1718,13 @@ private:
unsigned getParameterIndexLarge() const;
};
+enum class MultiVersionKind {
+ None,
+ Target,
+ CPUSpecific,
+ CPUDispatch
+};
+
/// Represents a function declaration or definition.
///
/// Since a given function can be declared several times in a program,
@@ -1711,8 +1735,11 @@ private:
/// contains all of the information known about the function. Other,
/// previous declarations of the function are available via the
/// getPreviousDecl() chain.
-class FunctionDecl : public DeclaratorDecl, public DeclContext,
+class FunctionDecl : public DeclaratorDecl,
+ public DeclContext,
public Redeclarable<FunctionDecl> {
+ // This class stores some data in DeclContext::FunctionDeclBits
+ // to save some space. Use the provided accessors to access it.
public:
/// The kind of templated function a FunctionDecl can be.
enum TemplatedKind {
@@ -1731,64 +1758,6 @@ private:
LazyDeclStmtPtr Body;
- // FIXME: This can be packed into the bitfields in DeclContext.
- // NOTE: VC++ packs bitfields poorly if the types differ.
- unsigned SClass : 3;
- unsigned IsInline : 1;
- unsigned IsInlineSpecified : 1;
-
-protected:
- // This is shared by CXXConstructorDecl, CXXConversionDecl, and
- // CXXDeductionGuideDecl.
- unsigned IsExplicitSpecified : 1;
-
-private:
- unsigned IsVirtualAsWritten : 1;
- unsigned IsPure : 1;
- unsigned HasInheritedPrototype : 1;
- unsigned HasWrittenPrototype : 1;
- unsigned IsDeleted : 1;
- unsigned IsTrivial : 1; // sunk from CXXMethodDecl
-
- /// This flag indicates whether this function is trivial for the purpose of
- /// calls. This is meaningful only when this function is a copy/move
- /// constructor or a destructor.
- unsigned IsTrivialForCall : 1;
-
- unsigned IsDefaulted : 1; // sunk from CXXMethoDecl
- unsigned IsExplicitlyDefaulted : 1; //sunk from CXXMethodDecl
- unsigned HasImplicitReturnZero : 1;
- unsigned IsLateTemplateParsed : 1;
- unsigned IsConstexpr : 1;
- unsigned InstantiationIsPending : 1;
-
- /// Indicates if the function uses __try.
- unsigned UsesSEHTry : 1;
-
- /// Indicates if the function was a definition but its body was
- /// skipped.
- unsigned HasSkippedBody : 1;
-
- /// Indicates if the function declaration will have a body, once we're done
- /// parsing it.
- unsigned WillHaveBody : 1;
-
- /// Indicates that this function is a multiversioned function using attribute
- /// 'target'.
- unsigned IsMultiVersion : 1;
-
-protected:
- /// [C++17] Only used by CXXDeductionGuideDecl. Declared here to avoid
- /// increasing the size of CXXDeductionGuideDecl by the size of an unsigned
- /// int as opposed to adding a single bit to FunctionDecl.
- /// Indicates that the Deduction Guide is the implicitly generated 'copy
- /// deduction candidate' (is used during overload resolution).
- unsigned IsCopyDeductionCandidate : 1;
-
-private:
-
- /// Store the ODRHash after first calculation.
- unsigned HasODRHash : 1;
unsigned ODRHash;
/// End part of this FunctionDecl's source range.
@@ -1858,25 +1827,22 @@ private:
void setParams(ASTContext &C, ArrayRef<ParmVarDecl *> NewParamInfo);
+ // This is unfortunately needed because ASTDeclWriter::VisitFunctionDecl
+ // need to access this bit but we want to avoid making ASTDeclWriter
+ // a friend of FunctionDeclBitfields just for this.
+ bool isDeletedBit() const { return FunctionDeclBits.IsDeleted; }
+
+ /// Whether an ODRHash has been stored.
+ bool hasODRHash() const { return FunctionDeclBits.HasODRHash; }
+
+ /// State that an ODRHash has been stored.
+ void setHasODRHash(bool B = true) { FunctionDeclBits.HasODRHash = B; }
+
protected:
FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, QualType T,
TypeSourceInfo *TInfo, StorageClass S, bool isInlineSpecified,
- bool isConstexprSpecified)
- : DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo,
- StartLoc),
- DeclContext(DK), redeclarable_base(C), SClass(S),
- IsInline(isInlineSpecified), IsInlineSpecified(isInlineSpecified),
- IsExplicitSpecified(false), IsVirtualAsWritten(false), IsPure(false),
- HasInheritedPrototype(false), HasWrittenPrototype(true),
- IsDeleted(false), IsTrivial(false), IsTrivialForCall(false),
- IsDefaulted(false),
- IsExplicitlyDefaulted(false), HasImplicitReturnZero(false),
- IsLateTemplateParsed(false), IsConstexpr(isConstexprSpecified),
- InstantiationIsPending(false), UsesSEHTry(false), HasSkippedBody(false),
- WillHaveBody(false), IsMultiVersion(false),
- IsCopyDeductionCandidate(false), HasODRHash(false), ODRHash(0),
- EndRangeLoc(NameInfo.getEndLoc()), DNLoc(NameInfo.getInfo()) {}
+ bool isConstexprSpecified);
using redeclarable_base = Redeclarable<FunctionDecl>;
@@ -2015,13 +1981,13 @@ public:
/// This does not determine whether the function has been defined (e.g., in a
/// previous definition); for that information, use isDefined.
bool isThisDeclarationADefinition() const {
- return IsDeleted || IsDefaulted || Body || HasSkippedBody ||
- IsLateTemplateParsed || WillHaveBody || hasDefiningAttr();
+ return isDeletedAsWritten() || isDefaulted() || Body || hasSkippedBody() ||
+ isLateTemplateParsed() || willHaveBody() || hasDefiningAttr();
}
/// Returns whether this specific declaration of the function has a body.
bool doesThisDeclarationHaveABody() const {
- return Body || IsLateTemplateParsed;
+ return Body || isLateTemplateParsed();
}
void setBody(Stmt *B);
@@ -2031,62 +1997,102 @@ public:
bool isVariadic() const;
/// Whether this function is marked as virtual explicitly.
- bool isVirtualAsWritten() const { return IsVirtualAsWritten; }
- void setVirtualAsWritten(bool V) { IsVirtualAsWritten = V; }
+ bool isVirtualAsWritten() const {
+ return FunctionDeclBits.IsVirtualAsWritten;
+ }
+
+ /// State that this function is marked as virtual explicitly.
+ void setVirtualAsWritten(bool V) { FunctionDeclBits.IsVirtualAsWritten = V; }
/// Whether this virtual function is pure, i.e. makes the containing class
/// abstract.
- bool isPure() const { return IsPure; }
+ bool isPure() const { return FunctionDeclBits.IsPure; }
void setPure(bool P = true);
/// Whether this templated function will be late parsed.
- bool isLateTemplateParsed() const { return IsLateTemplateParsed; }
- void setLateTemplateParsed(bool ILT = true) { IsLateTemplateParsed = ILT; }
+ bool isLateTemplateParsed() const {
+ return FunctionDeclBits.IsLateTemplateParsed;
+ }
+
+ /// State that this templated function will be late parsed.
+ void setLateTemplateParsed(bool ILT = true) {
+ FunctionDeclBits.IsLateTemplateParsed = ILT;
+ }
/// Whether this function is "trivial" in some specialized C++ senses.
/// Can only be true for default constructors, copy constructors,
/// copy assignment operators, and destructors. Not meaningful until
/// the class has been fully built by Sema.
- bool isTrivial() const { return IsTrivial; }
- void setTrivial(bool IT) { IsTrivial = IT; }
+ bool isTrivial() const { return FunctionDeclBits.IsTrivial; }
+ void setTrivial(bool IT) { FunctionDeclBits.IsTrivial = IT; }
- bool isTrivialForCall() const { return IsTrivialForCall; }
- void setTrivialForCall(bool IT) { IsTrivialForCall = IT; }
+ bool isTrivialForCall() const { return FunctionDeclBits.IsTrivialForCall; }
+ void setTrivialForCall(bool IT) { FunctionDeclBits.IsTrivialForCall = IT; }
/// Whether this function is defaulted per C++0x. Only valid for
/// special member functions.
- bool isDefaulted() const { return IsDefaulted; }
- void setDefaulted(bool D = true) { IsDefaulted = D; }
+ bool isDefaulted() const { return FunctionDeclBits.IsDefaulted; }
+ void setDefaulted(bool D = true) { FunctionDeclBits.IsDefaulted = D; }
/// Whether this function is explicitly defaulted per C++0x. Only valid
/// for special member functions.
- bool isExplicitlyDefaulted() const { return IsExplicitlyDefaulted; }
- void setExplicitlyDefaulted(bool ED = true) { IsExplicitlyDefaulted = ED; }
+ bool isExplicitlyDefaulted() const {
+ return FunctionDeclBits.IsExplicitlyDefaulted;
+ }
+
+ /// State that this function is explicitly defaulted per C++0x. Only valid
+ /// for special member functions.
+ void setExplicitlyDefaulted(bool ED = true) {
+ FunctionDeclBits.IsExplicitlyDefaulted = ED;
+ }
/// Whether falling off this function implicitly returns null/zero.
/// If a more specific implicit return value is required, front-ends
/// should synthesize the appropriate return statements.
- bool hasImplicitReturnZero() const { return HasImplicitReturnZero; }
- void setHasImplicitReturnZero(bool IRZ) { HasImplicitReturnZero = IRZ; }
+ bool hasImplicitReturnZero() const {
+ return FunctionDeclBits.HasImplicitReturnZero;
+ }
+
+ /// State that falling off this function implicitly returns null/zero.
+ /// If a more specific implicit return value is required, front-ends
+ /// should synthesize the appropriate return statements.
+ void setHasImplicitReturnZero(bool IRZ) {
+ FunctionDeclBits.HasImplicitReturnZero = IRZ;
+ }
/// Whether this function has a prototype, either because one
/// was explicitly written or because it was "inherited" by merging
/// a declaration without a prototype with a declaration that has a
/// prototype.
bool hasPrototype() const {
- return HasWrittenPrototype || HasInheritedPrototype;
+ return hasWrittenPrototype() || hasInheritedPrototype();
+ }
+
+ /// Whether this function has a written prototype.
+ bool hasWrittenPrototype() const {
+ return FunctionDeclBits.HasWrittenPrototype;
}
- bool hasWrittenPrototype() const { return HasWrittenPrototype; }
+ /// State that this function has a written prototype.
+ void setHasWrittenPrototype(bool P = true) {
+ FunctionDeclBits.HasWrittenPrototype = P;
+ }
/// Whether this function inherited its prototype from a
/// previous declaration.
- bool hasInheritedPrototype() const { return HasInheritedPrototype; }
- void setHasInheritedPrototype(bool P = true) { HasInheritedPrototype = P; }
+ bool hasInheritedPrototype() const {
+ return FunctionDeclBits.HasInheritedPrototype;
+ }
+
+ /// State that this function inherited its prototype from a
+ /// previous declaration.
+ void setHasInheritedPrototype(bool P = true) {
+ FunctionDeclBits.HasInheritedPrototype = P;
+ }
/// Whether this is a (C++11) constexpr function or constexpr constructor.
- bool isConstexpr() const { return IsConstexpr; }
- void setConstexpr(bool IC) { IsConstexpr = IC; }
+ bool isConstexpr() const { return FunctionDeclBits.IsConstexpr; }
+ void setConstexpr(bool IC) { FunctionDeclBits.IsConstexpr = IC; }
/// Whether the instantiation of this function is pending.
/// This bit is set when the decision to instantiate this function is made
@@ -2094,12 +2100,19 @@ public:
/// cases where instantiation did not happen because the template definition
/// was not seen in this TU. This bit remains set in those cases, under the
/// assumption that the instantiation will happen in some other TU.
- bool instantiationIsPending() const { return InstantiationIsPending; }
- void setInstantiationIsPending(bool IC) { InstantiationIsPending = IC; }
+ bool instantiationIsPending() const {
+ return FunctionDeclBits.InstantiationIsPending;
+ }
+
+ /// State that the instantiation of this function is pending.
+ /// (see instantiationIsPending)
+ void setInstantiationIsPending(bool IC) {
+ FunctionDeclBits.InstantiationIsPending = IC;
+ }
/// Indicates the function uses __try.
- bool usesSEHTry() const { return UsesSEHTry; }
- void setUsesSEHTry(bool UST) { UsesSEHTry = UST; }
+ bool usesSEHTry() const { return FunctionDeclBits.UsesSEHTry; }
+ void setUsesSEHTry(bool UST) { FunctionDeclBits.UsesSEHTry = UST; }
/// Whether this function has been deleted.
///
@@ -2120,9 +2133,15 @@ public:
/// };
/// @endcode
// If a function is deleted, its first declaration must be.
- bool isDeleted() const { return getCanonicalDecl()->IsDeleted; }
- bool isDeletedAsWritten() const { return IsDeleted && !IsDefaulted; }
- void setDeletedAsWritten(bool D = true) { IsDeleted = D; }
+ bool isDeleted() const {
+ return getCanonicalDecl()->FunctionDeclBits.IsDeleted;
+ }
+
+ bool isDeletedAsWritten() const {
+ return FunctionDeclBits.IsDeleted && !isDefaulted();
+ }
+
+ void setDeletedAsWritten(bool D = true) { FunctionDeclBits.IsDeleted = D; }
/// Determines whether this function is "main", which is the
/// entry point into an executable program.
@@ -2193,22 +2212,32 @@ public:
bool isNoReturn() const;
/// True if the function was a definition but its body was skipped.
- bool hasSkippedBody() const { return HasSkippedBody; }
- void setHasSkippedBody(bool Skipped = true) { HasSkippedBody = Skipped; }
+ bool hasSkippedBody() const { return FunctionDeclBits.HasSkippedBody; }
+ void setHasSkippedBody(bool Skipped = true) {
+ FunctionDeclBits.HasSkippedBody = Skipped;
+ }
/// True if this function will eventually have a body, once it's fully parsed.
- bool willHaveBody() const { return WillHaveBody; }
- void setWillHaveBody(bool V = true) { WillHaveBody = V; }
+ bool willHaveBody() const { return FunctionDeclBits.WillHaveBody; }
+ void setWillHaveBody(bool V = true) { FunctionDeclBits.WillHaveBody = V; }
/// True if this function is considered a multiversioned function.
- bool isMultiVersion() const { return getCanonicalDecl()->IsMultiVersion; }
+ bool isMultiVersion() const {
+ return getCanonicalDecl()->FunctionDeclBits.IsMultiVersion;
+ }
/// Sets the multiversion state for this declaration and all of its
/// redeclarations.
void setIsMultiVersion(bool V = true) {
- getCanonicalDecl()->IsMultiVersion = V;
+ getCanonicalDecl()->FunctionDeclBits.IsMultiVersion = V;
}
+ /// Gets the kind of multiversioning attribute this declaration has. Note that
+ /// this can return a value even if the function is not multiversion, such as
+ /// the case of 'target'.
+ MultiVersionKind getMultiVersionKind() const;
+
+
/// True if this function is a multiversioned dispatch function as a part of
/// the cpu_specific/cpu_dispatch functionality.
bool isCPUDispatchMultiVersion() const;
@@ -2216,6 +2245,10 @@ public:
/// part of the cpu_specific/cpu_dispatch functionality.
bool isCPUSpecificMultiVersion() const;
+ /// True if this function is a multiversioned dispatch function as a part of
+ /// the target functionality.
+ bool isTargetMultiVersion() const;
+
void setPreviousDeclaration(FunctionDecl * PrevDecl);
FunctionDecl *getCanonicalDecl() override;
@@ -2267,8 +2300,7 @@ public:
unsigned getMinRequiredArguments() const;
QualType getReturnType() const {
- assert(getType()->getAs<FunctionType>() && "Expected a FunctionType!");
- return getType()->getAs<FunctionType>()->getReturnType();
+ return getType()->castAs<FunctionType>()->getReturnType();
}
/// Attempt to compute an informative source range covering the
@@ -2276,47 +2308,62 @@ public:
/// limited representation in the AST.
SourceRange getReturnTypeSourceRange() const;
+ /// Get the declared return type, which may differ from the actual return
+ /// type if the return type is deduced.
+ QualType getDeclaredReturnType() const {
+ auto *TSI = getTypeSourceInfo();
+ QualType T = TSI ? TSI->getType() : getType();
+ return T->castAs<FunctionType>()->getReturnType();
+ }
+
/// Attempt to compute an informative source range covering the
/// function exception specification, if any.
SourceRange getExceptionSpecSourceRange() const;
/// Determine the type of an expression that calls this function.
QualType getCallResultType() const {
- assert(getType()->getAs<FunctionType>() && "Expected a FunctionType!");
- return getType()->getAs<FunctionType>()->getCallResultType(getASTContext());
+ return getType()->castAs<FunctionType>()->getCallResultType(
+ getASTContext());
}
- /// Returns the WarnUnusedResultAttr that is either declared on this
- /// function, or its return type declaration.
- const Attr *getUnusedResultAttr() const;
-
- /// Returns true if this function or its return type has the
- /// warn_unused_result attribute.
- bool hasUnusedResultAttr() const { return getUnusedResultAttr() != nullptr; }
-
/// Returns the storage class as written in the source. For the
/// computed linkage of symbol, see getLinkage.
- StorageClass getStorageClass() const { return StorageClass(SClass); }
+ StorageClass getStorageClass() const {
+ return static_cast<StorageClass>(FunctionDeclBits.SClass);
+ }
+
+ /// Sets the storage class as written in the source.
+ void setStorageClass(StorageClass SClass) {
+ FunctionDeclBits.SClass = SClass;
+ }
/// Determine whether the "inline" keyword was specified for this
/// function.
- bool isInlineSpecified() const { return IsInlineSpecified; }
+ bool isInlineSpecified() const { return FunctionDeclBits.IsInlineSpecified; }
/// Set whether the "inline" keyword was specified for this function.
void setInlineSpecified(bool I) {
- IsInlineSpecified = I;
- IsInline = I;
+ FunctionDeclBits.IsInlineSpecified = I;
+ FunctionDeclBits.IsInline = I;
}
/// Flag that this function is implicitly inline.
- void setImplicitlyInline() {
- IsInline = true;
- }
+ void setImplicitlyInline(bool I = true) { FunctionDeclBits.IsInline = I; }
/// Determine whether this function should be inlined, because it is
/// either marked "inline" or "constexpr" or is a member function of a class
/// that was defined in the class body.
- bool isInlined() const { return IsInline; }
+ bool isInlined() const { return FunctionDeclBits.IsInline; }
+
+ /// Whether this function is marked as explicit explicitly.
+ bool isExplicitSpecified() const {
+ return FunctionDeclBits.IsExplicitSpecified;
+ }
+
+ /// State that this function is marked as explicit explicitly.
+ void setExplicitSpecified(bool ExpSpec = true) {
+ FunctionDeclBits.IsExplicitSpecified = ExpSpec;
+ }
bool isInlineDefinitionExternallyVisible() const;
@@ -2851,7 +2898,7 @@ public:
const Type *getTypeForDecl() const { return TypeForDecl; }
void setTypeForDecl(const Type *TD) { TypeForDecl = TD; }
- SourceLocation getLocStart() const LLVM_READONLY { return LocStart; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return LocStart; }
void setLocStart(SourceLocation L) { LocStart = L; }
SourceRange getSourceRange() const override LLVM_READONLY {
if (LocStart.isValid())
@@ -3014,64 +3061,16 @@ public:
};
/// Represents the declaration of a struct/union/class/enum.
-class TagDecl
- : public TypeDecl, public DeclContext, public Redeclarable<TagDecl> {
+class TagDecl : public TypeDecl,
+ public DeclContext,
+ public Redeclarable<TagDecl> {
+ // This class stores some data in DeclContext::TagDeclBits
+ // to save some space. Use the provided accessors to access it.
public:
// This is really ugly.
using TagKind = TagTypeKind;
private:
- // FIXME: This can be packed into the bitfields in Decl.
- /// The TagKind enum.
- unsigned TagDeclKind : 3;
-
- /// True if this is a definition ("struct foo {};"), false if it is a
- /// declaration ("struct foo;"). It is not considered a definition
- /// until the definition has been fully processed.
- unsigned IsCompleteDefinition : 1;
-
-protected:
- /// True if this is currently being defined.
- unsigned IsBeingDefined : 1;
-
-private:
- /// True if this tag declaration is "embedded" (i.e., defined or declared
- /// for the very first time) in the syntax of a declarator.
- unsigned IsEmbeddedInDeclarator : 1;
-
- /// True if this tag is free standing, e.g. "struct foo;".
- unsigned IsFreeStanding : 1;
-
-protected:
- // These are used by (and only defined for) EnumDecl.
- unsigned NumPositiveBits : 8;
- unsigned NumNegativeBits : 8;
-
- /// True if this tag declaration is a scoped enumeration. Only
- /// possible in C++11 mode.
- unsigned IsScoped : 1;
-
- /// If this tag declaration is a scoped enum,
- /// then this is true if the scoped enum was declared using the class
- /// tag, false if it was declared with the struct tag. No meaning is
- /// associated if this tag declaration is not a scoped enum.
- unsigned IsScopedUsingClassTag : 1;
-
- /// True if this is an enumeration with fixed underlying type. Only
- /// possible in C++11, Microsoft extensions, or Objective C mode.
- unsigned IsFixed : 1;
-
- /// Indicates whether it is possible for declarations of this kind
- /// to have an out-of-date definition.
- ///
- /// This option is only enabled when modules are enabled.
- unsigned MayHaveOutOfDateDef : 1;
-
- /// Has the full definition of this type been required by a use somewhere in
- /// the TU.
- unsigned IsCompleteDefinitionRequired : 1;
-
-private:
SourceRange BraceRange;
// A struct representing syntactic qualifier info,
@@ -3097,16 +3096,7 @@ private:
protected:
TagDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id, TagDecl *PrevDecl,
- SourceLocation StartL)
- : TypeDecl(DK, DC, L, Id, StartL), DeclContext(DK), redeclarable_base(C),
- TagDeclKind(TK), IsCompleteDefinition(false), IsBeingDefined(false),
- IsEmbeddedInDeclarator(false), IsFreeStanding(false),
- IsCompleteDefinitionRequired(false),
- TypedefNameDeclOrQualifier((TypedefNameDecl *)nullptr) {
- assert((DK != Enum || TK == TTK_Enum) &&
- "EnumDecl not matched with TTK_Enum");
- setPreviousDecl(PrevDecl);
- }
+ SourceLocation StartL);
using redeclarable_base = Redeclarable<TagDecl>;
@@ -3127,6 +3117,17 @@ protected:
/// This is a helper function for derived classes.
void completeDefinition();
+ /// True if this decl is currently being defined.
+ void setBeingDefined(bool V = true) { TagDeclBits.IsBeingDefined = V; }
+
+ /// Indicates whether it is possible for declarations of this kind
+ /// to have an out-of-date definition.
+ ///
+ /// This option is only enabled when modules are enabled.
+ void setMayHaveOutOfDateDef(bool V = true) {
+ TagDeclBits.MayHaveOutOfDateDef = V;
+ }
+
public:
friend class ASTDeclReader;
friend class ASTDeclWriter;
@@ -3146,7 +3147,7 @@ public:
/// Return SourceLocation representing start of source
/// range ignoring outer template declarations.
- SourceLocation getInnerLocStart() const { return getLocStart(); }
+ SourceLocation getInnerLocStart() const { return getBeginLoc(); }
/// Return SourceLocation representing start of source
/// range taking into account any outer template declarations.
@@ -3165,33 +3166,54 @@ public:
}
/// Return true if this decl has its body fully specified.
- bool isCompleteDefinition() const {
- return IsCompleteDefinition;
+ bool isCompleteDefinition() const { return TagDeclBits.IsCompleteDefinition; }
+
+ /// True if this decl has its body fully specified.
+ void setCompleteDefinition(bool V = true) {
+ TagDeclBits.IsCompleteDefinition = V;
}
/// Return true if this complete decl is
/// required to be complete for some existing use.
bool isCompleteDefinitionRequired() const {
- return IsCompleteDefinitionRequired;
+ return TagDeclBits.IsCompleteDefinitionRequired;
}
- /// Return true if this decl is currently being defined.
- bool isBeingDefined() const {
- return IsBeingDefined;
+ /// True if this complete decl is
+ /// required to be complete for some existing use.
+ void setCompleteDefinitionRequired(bool V = true) {
+ TagDeclBits.IsCompleteDefinitionRequired = V;
}
+ /// Return true if this decl is currently being defined.
+ bool isBeingDefined() const { return TagDeclBits.IsBeingDefined; }
+
+ /// True if this tag declaration is "embedded" (i.e., defined or declared
+ /// for the very first time) in the syntax of a declarator.
bool isEmbeddedInDeclarator() const {
- return IsEmbeddedInDeclarator;
+ return TagDeclBits.IsEmbeddedInDeclarator;
}
+
+ /// True if this tag declaration is "embedded" (i.e., defined or declared
+ /// for the very first time) in the syntax of a declarator.
void setEmbeddedInDeclarator(bool isInDeclarator) {
- IsEmbeddedInDeclarator = isInDeclarator;
+ TagDeclBits.IsEmbeddedInDeclarator = isInDeclarator;
}
- bool isFreeStanding() const { return IsFreeStanding; }
+ /// True if this tag is free standing, e.g. "struct foo;".
+ bool isFreeStanding() const { return TagDeclBits.IsFreeStanding; }
+
+ /// True if this tag is free standing, e.g. "struct foo;".
void setFreeStanding(bool isFreeStanding = true) {
- IsFreeStanding = isFreeStanding;
+ TagDeclBits.IsFreeStanding = isFreeStanding;
}
+ /// Indicates whether it is possible for declarations of this kind
+ /// to have an out-of-date definition.
+ ///
+ /// This option is only enabled when modules are enabled.
+ bool mayHaveOutOfDateDef() const { return TagDeclBits.MayHaveOutOfDateDef; }
+
/// Whether this declaration declares a type that is
/// dependent, i.e., a type that somehow depends on template
/// parameters.
@@ -3214,21 +3236,15 @@ public:
/// the struct/union/class/enum.
TagDecl *getDefinition() const;
- void setCompleteDefinition(bool V) { IsCompleteDefinition = V; }
-
- void setCompleteDefinitionRequired(bool V = true) {
- IsCompleteDefinitionRequired = V;
- }
-
StringRef getKindName() const {
return TypeWithKeyword::getTagTypeKindName(getTagKind());
}
TagKind getTagKind() const {
- return TagKind(TagDeclKind);
+ return static_cast<TagKind>(TagDeclBits.TagDeclKind);
}
- void setTagKind(TagKind TK) { TagDeclKind = TK; }
+ void setTagKind(TagKind TK) { TagDeclBits.TagDeclKind = TK; }
bool isStruct() const { return getTagKind() == TTK_Struct; }
bool isInterface() const { return getTagKind() == TTK_Interface; }
@@ -3308,6 +3324,9 @@ public:
/// with a fixed underlying type, and in C we allow them to be forward-declared
/// with no underlying type as an extension.
class EnumDecl : public TagDecl {
+ // This class stores some data in DeclContext::EnumDeclBits
+ // to save some space. Use the provided accessors to access it.
+
/// This represent the integer type that the enum corresponds
/// to for code generation purposes. Note that the enumerator constants may
/// have a different type than this does.
@@ -3336,28 +3355,50 @@ class EnumDecl : public TagDecl {
MemberSpecializationInfo *SpecializationInfo = nullptr;
/// Store the ODRHash after first calculation.
- unsigned HasODRHash : 1;
+ /// The corresponding flag HasODRHash is in EnumDeclBits
+ /// and can be accessed with the provided accessors.
unsigned ODRHash;
EnumDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id, EnumDecl *PrevDecl,
- bool Scoped, bool ScopedUsingClassTag, bool Fixed)
- : TagDecl(Enum, TTK_Enum, C, DC, IdLoc, Id, PrevDecl, StartLoc) {
- assert(Scoped || !ScopedUsingClassTag);
- IntegerType = (const Type *)nullptr;
- NumNegativeBits = 0;
- NumPositiveBits = 0;
- IsScoped = Scoped;
- IsScopedUsingClassTag = ScopedUsingClassTag;
- IsFixed = Fixed;
- HasODRHash = false;
- ODRHash = 0;
- }
+ bool Scoped, bool ScopedUsingClassTag, bool Fixed);
void anchor() override;
void setInstantiationOfMemberEnum(ASTContext &C, EnumDecl *ED,
TemplateSpecializationKind TSK);
+
+ /// Sets the width in bits required to store all the
+ /// non-negative enumerators of this enum.
+ void setNumPositiveBits(unsigned Num) {
+ EnumDeclBits.NumPositiveBits = Num;
+ assert(EnumDeclBits.NumPositiveBits == Num && "can't store this bitcount");
+ }
+
+ /// Returns the width in bits required to store all the
+ /// negative enumerators of this enum. (see getNumNegativeBits)
+ void setNumNegativeBits(unsigned Num) { EnumDeclBits.NumNegativeBits = Num; }
+
+ /// True if this tag declaration is a scoped enumeration. Only
+ /// possible in C++11 mode.
+ void setScoped(bool Scoped = true) { EnumDeclBits.IsScoped = Scoped; }
+
+ /// If this tag declaration is a scoped enum,
+ /// then this is true if the scoped enum was declared using the class
+ /// tag, false if it was declared with the struct tag. No meaning is
+ /// associated if this tag declaration is not a scoped enum.
+ void setScopedUsingClassTag(bool ScopedUCT = true) {
+ EnumDeclBits.IsScopedUsingClassTag = ScopedUCT;
+ }
+
+ /// True if this is an Objective-C, C++11, or
+ /// Microsoft-style enumeration with a fixed underlying type.
+ void setFixed(bool Fixed = true) { EnumDeclBits.IsFixed = Fixed; }
+
+ /// True if a valid hash is stored in ODRHash.
+ bool hasODRHash() const { return EnumDeclBits.HasODRHash; }
+ void setHasODRHash(bool Hash = true) { EnumDeclBits.HasODRHash = Hash; }
+
public:
friend class ASTDeclReader;
@@ -3462,13 +3503,7 @@ public:
/// Returns the width in bits required to store all the
/// non-negative enumerators of this enum.
- unsigned getNumPositiveBits() const {
- return NumPositiveBits;
- }
- void setNumPositiveBits(unsigned Num) {
- NumPositiveBits = Num;
- assert(NumPositiveBits == Num && "can't store this bitcount");
- }
+ unsigned getNumPositiveBits() const { return EnumDeclBits.NumPositiveBits; }
/// Returns the width in bits required to store all the
/// negative enumerators of this enum. These widths include
@@ -3479,28 +3514,19 @@ public:
/// -1 1111111 1
/// -10 1110110 5
/// -101 1001011 8
- unsigned getNumNegativeBits() const {
- return NumNegativeBits;
- }
- void setNumNegativeBits(unsigned Num) {
- NumNegativeBits = Num;
- }
+ unsigned getNumNegativeBits() const { return EnumDeclBits.NumNegativeBits; }
/// Returns true if this is a C++11 scoped enumeration.
- bool isScoped() const {
- return IsScoped;
- }
+ bool isScoped() const { return EnumDeclBits.IsScoped; }
/// Returns true if this is a C++11 scoped enumeration.
bool isScopedUsingClassTag() const {
- return IsScopedUsingClassTag;
+ return EnumDeclBits.IsScopedUsingClassTag;
}
/// Returns true if this is an Objective-C, C++11, or
/// Microsoft-style enumeration with a fixed underlying type.
- bool isFixed() const {
- return IsFixed;
- }
+ bool isFixed() const { return EnumDeclBits.IsFixed; }
unsigned getODRHash();
@@ -3565,7 +3591,10 @@ public:
/// union Y { int A, B; }; // Has body with members A and B (FieldDecls).
/// This decl will be marked invalid if *any* members are invalid.
class RecordDecl : public TagDecl {
+ // This class stores some data in DeclContext::RecordDeclBits
+ // to save some space. Use the provided accessors to access it.
public:
+ friend class DeclContext;
/// Enum that represents the different ways arguments are passed to and
/// returned from function calls. This takes into account the target-specific
/// and version-specific rules along with the rules determined by the
@@ -3589,46 +3618,6 @@ public:
APK_CanNeverPassInRegs
};
-private:
- friend class DeclContext;
-
- // FIXME: This can be packed into the bitfields in Decl.
- /// This is true if this struct ends with a flexible
- /// array member (e.g. int X[]) or if this union contains a struct that does.
- /// If so, this cannot be contained in arrays or other structs as a member.
- unsigned HasFlexibleArrayMember : 1;
-
- /// Whether this is the type of an anonymous struct or union.
- unsigned AnonymousStructOrUnion : 1;
-
- /// This is true if this struct has at least one member
- /// containing an Objective-C object pointer type.
- unsigned HasObjectMember : 1;
-
- /// This is true if struct has at least one member of
- /// 'volatile' type.
- unsigned HasVolatileMember : 1;
-
- /// Whether the field declarations of this record have been loaded
- /// from external storage. To avoid unnecessary deserialization of
- /// methods/nested types we allow deserialization of just the fields
- /// when needed.
- mutable unsigned LoadedFieldsFromExternalStorage : 1;
-
- /// Basic properties of non-trivial C structs.
- unsigned NonTrivialToPrimitiveDefaultInitialize : 1;
- unsigned NonTrivialToPrimitiveCopy : 1;
- unsigned NonTrivialToPrimitiveDestroy : 1;
-
- /// Indicates whether this struct is destroyed in the callee.
- ///
- /// Please note that MSVC won't merge adjacent bitfields if they don't have
- /// the same type.
- unsigned ParamDestroyedInCallee : 1;
-
- /// Represents the way this type is passed to a function.
- unsigned ArgPassingRestrictions : 2;
-
protected:
RecordDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
@@ -3655,8 +3644,13 @@ public:
return const_cast<RecordDecl*>(this)->getMostRecentDecl();
}
- bool hasFlexibleArrayMember() const { return HasFlexibleArrayMember; }
- void setHasFlexibleArrayMember(bool V) { HasFlexibleArrayMember = V; }
+ bool hasFlexibleArrayMember() const {
+ return RecordDeclBits.HasFlexibleArrayMember;
+ }
+
+ void setHasFlexibleArrayMember(bool V) {
+ RecordDeclBits.HasFlexibleArrayMember = V;
+ }
/// Whether this is an anonymous struct or union. To be an anonymous
/// struct or union, it must have been declared without a name and
@@ -3669,47 +3663,54 @@ public:
/// union X { int i; float f; };
/// union { int i; float f; } obj;
/// @endcode
- bool isAnonymousStructOrUnion() const { return AnonymousStructOrUnion; }
+ bool isAnonymousStructOrUnion() const {
+ return RecordDeclBits.AnonymousStructOrUnion;
+ }
+
void setAnonymousStructOrUnion(bool Anon) {
- AnonymousStructOrUnion = Anon;
+ RecordDeclBits.AnonymousStructOrUnion = Anon;
}
- bool hasObjectMember() const { return HasObjectMember; }
- void setHasObjectMember (bool val) { HasObjectMember = val; }
+ bool hasObjectMember() const { return RecordDeclBits.HasObjectMember; }
+ void setHasObjectMember(bool val) { RecordDeclBits.HasObjectMember = val; }
+
+ bool hasVolatileMember() const { return RecordDeclBits.HasVolatileMember; }
- bool hasVolatileMember() const { return HasVolatileMember; }
- void setHasVolatileMember (bool val) { HasVolatileMember = val; }
+ void setHasVolatileMember(bool val) {
+ RecordDeclBits.HasVolatileMember = val;
+ }
bool hasLoadedFieldsFromExternalStorage() const {
- return LoadedFieldsFromExternalStorage;
+ return RecordDeclBits.LoadedFieldsFromExternalStorage;
}
- void setHasLoadedFieldsFromExternalStorage(bool val) {
- LoadedFieldsFromExternalStorage = val;
+
+ void setHasLoadedFieldsFromExternalStorage(bool val) const {
+ RecordDeclBits.LoadedFieldsFromExternalStorage = val;
}
/// Functions to query basic properties of non-trivial C structs.
bool isNonTrivialToPrimitiveDefaultInitialize() const {
- return NonTrivialToPrimitiveDefaultInitialize;
+ return RecordDeclBits.NonTrivialToPrimitiveDefaultInitialize;
}
void setNonTrivialToPrimitiveDefaultInitialize(bool V) {
- NonTrivialToPrimitiveDefaultInitialize = V;
+ RecordDeclBits.NonTrivialToPrimitiveDefaultInitialize = V;
}
bool isNonTrivialToPrimitiveCopy() const {
- return NonTrivialToPrimitiveCopy;
+ return RecordDeclBits.NonTrivialToPrimitiveCopy;
}
void setNonTrivialToPrimitiveCopy(bool V) {
- NonTrivialToPrimitiveCopy = V;
+ RecordDeclBits.NonTrivialToPrimitiveCopy = V;
}
bool isNonTrivialToPrimitiveDestroy() const {
- return NonTrivialToPrimitiveDestroy;
+ return RecordDeclBits.NonTrivialToPrimitiveDestroy;
}
void setNonTrivialToPrimitiveDestroy(bool V) {
- NonTrivialToPrimitiveDestroy = V;
+ RecordDeclBits.NonTrivialToPrimitiveDestroy = V;
}
/// Determine whether this class can be passed in registers. In C++ mode,
@@ -3720,19 +3721,19 @@ public:
}
ArgPassingKind getArgPassingRestrictions() const {
- return static_cast<ArgPassingKind>(ArgPassingRestrictions);
+ return static_cast<ArgPassingKind>(RecordDeclBits.ArgPassingRestrictions);
}
void setArgPassingRestrictions(ArgPassingKind Kind) {
- ArgPassingRestrictions = static_cast<uint8_t>(Kind);
+ RecordDeclBits.ArgPassingRestrictions = Kind;
}
bool isParamDestroyedInCallee() const {
- return ParamDestroyedInCallee;
+ return RecordDeclBits.ParamDestroyedInCallee;
}
void setParamDestroyedInCallee(bool V) {
- ParamDestroyedInCallee = V;
+ RecordDeclBits.ParamDestroyedInCallee = V;
}
/// Determines whether this declaration represents the
@@ -3855,6 +3856,8 @@ public:
/// unnamed FunctionDecl. For example:
/// ^{ statement-body } or ^(int arg1, float arg2){ statement-body }
class BlockDecl : public Decl, public DeclContext {
+ // This class stores some data in DeclContext::BlockDeclBits
+ // to save some space. Use the provided accessors to access it.
public:
/// A class which contains all the information about a particular
/// captured value.
@@ -3885,6 +3888,14 @@ public:
/// variable.
bool isByRef() const { return VariableAndFlags.getInt() & flag_isByRef; }
+ bool isEscapingByref() const {
+ return getVariable()->isEscapingByref();
+ }
+
+ bool isNonEscapingByref() const {
+ return getVariable()->isNonEscapingByref();
+ }
+
/// Whether this is a nested capture, i.e. the variable captured
/// is not from outside the immediately enclosing function/block.
bool isNested() const { return VariableAndFlags.getInt() & flag_isNested; }
@@ -3895,16 +3906,6 @@ public:
};
private:
- // FIXME: This can be packed into the bitfields in Decl.
- bool IsVariadic : 1;
- bool CapturesCXXThis : 1;
- bool BlockMissingReturnType : 1;
- bool IsConversionFromLambda : 1;
-
- /// A bit that indicates this block is passed directly to a function as a
- /// non-escaping parameter.
- bool DoesNotEscape : 1;
-
/// A new[]'d array of pointers to ParmVarDecls for the formal
/// parameters of this function. This is null if a prototype or if there are
/// no formals.
@@ -3921,10 +3922,7 @@ private:
Decl *ManglingContextDecl = nullptr;
protected:
- BlockDecl(DeclContext *DC, SourceLocation CaretLoc)
- : Decl(Block, DC, CaretLoc), DeclContext(Block), IsVariadic(false),
- CapturesCXXThis(false), BlockMissingReturnType(true),
- IsConversionFromLambda(false), DoesNotEscape(false) {}
+ BlockDecl(DeclContext *DC, SourceLocation CaretLoc);
public:
static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L);
@@ -3932,8 +3930,8 @@ public:
SourceLocation getCaretLocation() const { return getLocation(); }
- bool isVariadic() const { return IsVariadic; }
- void setIsVariadic(bool value) { IsVariadic = value; }
+ bool isVariadic() const { return BlockDeclBits.IsVariadic; }
+ void setIsVariadic(bool value) { BlockDeclBits.IsVariadic = value; }
CompoundStmt *getCompoundBody() const { return (CompoundStmt*) Body; }
Stmt *getBody() const override { return (Stmt*) Body; }
@@ -3976,7 +3974,7 @@ public:
/// True if this block (or its nested blocks) captures
/// anything of local storage from its enclosing scopes.
- bool hasCaptures() const { return NumCaptures != 0 || CapturesCXXThis; }
+ bool hasCaptures() const { return NumCaptures || capturesCXXThis(); }
/// Returns the number of captured variables.
/// Does not include an entry for 'this'.
@@ -3989,15 +3987,27 @@ public:
capture_const_iterator capture_begin() const { return captures().begin(); }
capture_const_iterator capture_end() const { return captures().end(); }
- bool capturesCXXThis() const { return CapturesCXXThis; }
- bool blockMissingReturnType() const { return BlockMissingReturnType; }
- void setBlockMissingReturnType(bool val) { BlockMissingReturnType = val; }
+ bool capturesCXXThis() const { return BlockDeclBits.CapturesCXXThis; }
+ void setCapturesCXXThis(bool B = true) { BlockDeclBits.CapturesCXXThis = B; }
+
+ bool blockMissingReturnType() const {
+ return BlockDeclBits.BlockMissingReturnType;
+ }
+
+ void setBlockMissingReturnType(bool val = true) {
+ BlockDeclBits.BlockMissingReturnType = val;
+ }
- bool isConversionFromLambda() const { return IsConversionFromLambda; }
- void setIsConversionFromLambda(bool val) { IsConversionFromLambda = val; }
+ bool isConversionFromLambda() const {
+ return BlockDeclBits.IsConversionFromLambda;
+ }
+
+ void setIsConversionFromLambda(bool val = true) {
+ BlockDeclBits.IsConversionFromLambda = val;
+ }
- bool doesNotEscape() const { return DoesNotEscape; }
- void setDoesNotEscape() { DoesNotEscape = true; }
+ bool doesNotEscape() const { return BlockDeclBits.DoesNotEscape; }
+ void setDoesNotEscape(bool B = true) { BlockDeclBits.DoesNotEscape = B; }
bool capturesVariable(const VarDecl *var) const;
@@ -4223,16 +4233,16 @@ public:
SourceLocation getRBraceLoc() const { return RBraceLoc; }
void setRBraceLoc(SourceLocation L) { RBraceLoc = L; }
- SourceLocation getLocEnd() const LLVM_READONLY {
+ SourceLocation getEndLoc() const LLVM_READONLY {
if (RBraceLoc.isValid())
return RBraceLoc;
// No braces: get the end location of the (only) declaration in context
// (if present).
- return decls_empty() ? getLocation() : decls_begin()->getLocEnd();
+ return decls_empty() ? getLocation() : decls_begin()->getEndLoc();
}
SourceRange getSourceRange() const override LLVM_READONLY {
- return SourceRange(getLocation(), getLocEnd());
+ return SourceRange(getLocation(), getEndLoc());
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index d6b89d971d94..8405a43fa098 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -16,6 +16,7 @@
#include "clang/AST/AttrIterator.h"
#include "clang/AST/DeclarationName.h"
+#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
@@ -406,11 +407,11 @@ public:
return SourceRange(getLocation(), getLocation());
}
- SourceLocation getLocStart() const LLVM_READONLY {
+ SourceLocation getBeginLoc() const LLVM_READONLY {
return getSourceRange().getBegin();
}
- SourceLocation getLocEnd() const LLVM_READONLY {
+ SourceLocation getEndLoc() const LLVM_READONLY {
return getSourceRange().getEnd();
}
@@ -481,13 +482,7 @@ public:
const AttrVec &getAttrs() const;
void dropAttrs();
-
- void addAttr(Attr *A) {
- if (hasAttrs())
- getAttrs().push_back(A);
- else
- setAttrs(AttrVec(1, A));
- }
+ void addAttr(Attr *A);
using attr_iterator = AttrVec::const_iterator;
using attr_range = llvm::iterator_range<attr_iterator>;
@@ -1070,11 +1065,11 @@ public:
unsigned OldNS = IdentifierNamespace;
assert((OldNS & (IDNS_Tag | IDNS_Ordinary |
IDNS_TagFriend | IDNS_OrdinaryFriend |
- IDNS_LocalExtern)) &&
+ IDNS_LocalExtern | IDNS_NonMemberOperator)) &&
"namespace includes neither ordinary nor tag");
assert(!(OldNS & ~(IDNS_Tag | IDNS_Ordinary | IDNS_Type |
IDNS_TagFriend | IDNS_OrdinaryFriend |
- IDNS_LocalExtern)) &&
+ IDNS_LocalExtern | IDNS_NonMemberOperator)) &&
"namespace includes other than ordinary or tag");
Decl *Prev = getPreviousDecl();
@@ -1087,7 +1082,8 @@ public:
IdentifierNamespace |= IDNS_Tag | IDNS_Type;
}
- if (OldNS & (IDNS_Ordinary | IDNS_OrdinaryFriend | IDNS_LocalExtern)) {
+ if (OldNS & (IDNS_Ordinary | IDNS_OrdinaryFriend |
+ IDNS_LocalExtern | IDNS_NonMemberOperator)) {
IdentifierNamespace |= IDNS_OrdinaryFriend;
if (PerformFriendInjection ||
(Prev && Prev->getIdentifierNamespace() & IDNS_Ordinary))
@@ -1141,6 +1137,9 @@ public:
void dump(raw_ostream &Out, bool Deserialize = false) const;
+ /// \return Unique reproducible object identifier
+ int64_t getID() const;
+
/// Looks through the Decl's underlying type to extract a FunctionType
/// when possible. Will return null if the type underlying the Decl does not
/// have a FunctionType.
@@ -1214,7 +1213,6 @@ public:
value_type SingleElement;
public:
- iterator() = default;
explicit iterator(pointer Pos, value_type Single = nullptr)
: IteratorBase(Pos), SingleElement(Single) {}
@@ -1250,47 +1248,424 @@ public:
/// that directly derive from DeclContext are mentioned, not their subclasses):
///
/// TranslationUnitDecl
+/// ExternCContext
/// NamespaceDecl
-/// FunctionDecl
/// TagDecl
+/// OMPDeclareReductionDecl
+/// FunctionDecl
/// ObjCMethodDecl
/// ObjCContainerDecl
/// LinkageSpecDecl
/// ExportDecl
/// BlockDecl
-/// OMPDeclareReductionDecl
+/// CapturedDecl
class DeclContext {
- /// DeclKind - This indicates which class this is.
- unsigned DeclKind : 8;
+ /// For makeDeclVisibleInContextImpl
+ friend class ASTDeclReader;
+ /// For reconcileExternalVisibleStorage, CreateStoredDeclsMap,
+ /// hasNeedToReconcileExternalVisibleStorage
+ friend class ExternalASTSource;
+ /// For CreateStoredDeclsMap
+ friend class DependentDiagnostic;
+ /// For hasNeedToReconcileExternalVisibleStorage,
+ /// hasLazyLocalLexicalLookups, hasLazyExternalLexicalLookups
+ friend class ASTWriter;
- /// Whether this declaration context also has some external
- /// storage that contains additional declarations that are lexically
- /// part of this context.
- mutable bool ExternalLexicalStorage : 1;
+ // We use uint64_t in the bit-fields below since some bit-fields
+ // cross the unsigned boundary and this breaks the packing.
+
+ /// Stores the bits used by DeclContext.
+ /// If modified NumDeclContextBit, the ctor of DeclContext and the accessor
+ /// methods in DeclContext should be updated appropriately.
+ class DeclContextBitfields {
+ friend class DeclContext;
+ /// DeclKind - This indicates which class this is.
+ uint64_t DeclKind : 7;
+
+ /// Whether this declaration context also has some external
+ /// storage that contains additional declarations that are lexically
+ /// part of this context.
+ mutable uint64_t ExternalLexicalStorage : 1;
+
+ /// Whether this declaration context also has some external
+ /// storage that contains additional declarations that are visible
+ /// in this context.
+ mutable uint64_t ExternalVisibleStorage : 1;
+
+ /// Whether this declaration context has had externally visible
+ /// storage added since the last lookup. In this case, \c LookupPtr's
+ /// invariant may not hold and needs to be fixed before we perform
+ /// another lookup.
+ mutable uint64_t NeedToReconcileExternalVisibleStorage : 1;
+
+ /// If \c true, this context may have local lexical declarations
+ /// that are missing from the lookup table.
+ mutable uint64_t HasLazyLocalLexicalLookups : 1;
+
+ /// If \c true, the external source may have lexical declarations
+ /// that are missing from the lookup table.
+ mutable uint64_t HasLazyExternalLexicalLookups : 1;
+
+ /// If \c true, lookups should only return identifier from
+ /// DeclContext scope (for example TranslationUnit). Used in
+ /// LookupQualifiedName()
+ mutable uint64_t UseQualifiedLookup : 1;
+ };
- /// Whether this declaration context also has some external
- /// storage that contains additional declarations that are visible
- /// in this context.
- mutable bool ExternalVisibleStorage : 1;
+ /// Number of bits in DeclContextBitfields.
+ enum { NumDeclContextBits = 13 };
- /// Whether this declaration context has had external visible
- /// storage added since the last lookup. In this case, \c LookupPtr's
- /// invariant may not hold and needs to be fixed before we perform
- /// another lookup.
- mutable bool NeedToReconcileExternalVisibleStorage : 1;
+ /// Stores the bits used by TagDecl.
+ /// If modified NumTagDeclBits and the accessor
+ /// methods in TagDecl should be updated appropriately.
+ class TagDeclBitfields {
+ friend class TagDecl;
+ /// For the bits in DeclContextBitfields
+ uint64_t : NumDeclContextBits;
- /// If \c true, this context may have local lexical declarations
- /// that are missing from the lookup table.
- mutable bool HasLazyLocalLexicalLookups : 1;
+ /// The TagKind enum.
+ uint64_t TagDeclKind : 3;
- /// If \c true, the external source may have lexical declarations
- /// that are missing from the lookup table.
- mutable bool HasLazyExternalLexicalLookups : 1;
+ /// True if this is a definition ("struct foo {};"), false if it is a
+ /// declaration ("struct foo;"). It is not considered a definition
+ /// until the definition has been fully processed.
+ uint64_t IsCompleteDefinition : 1;
+
+ /// True if this is currently being defined.
+ uint64_t IsBeingDefined : 1;
+
+ /// True if this tag declaration is "embedded" (i.e., defined or declared
+ /// for the very first time) in the syntax of a declarator.
+ uint64_t IsEmbeddedInDeclarator : 1;
+
+ /// True if this tag is free standing, e.g. "struct foo;".
+ uint64_t IsFreeStanding : 1;
+
+ /// Indicates whether it is possible for declarations of this kind
+ /// to have an out-of-date definition.
+ ///
+ /// This option is only enabled when modules are enabled.
+ uint64_t MayHaveOutOfDateDef : 1;
+
+ /// Has the full definition of this type been required by a use somewhere in
+ /// the TU.
+ uint64_t IsCompleteDefinitionRequired : 1;
+ };
+
+ /// Number of non-inherited bits in TagDeclBitfields.
+ enum { NumTagDeclBits = 9 };
+
+ /// Stores the bits used by EnumDecl.
+ /// If modified NumEnumDeclBit and the accessor
+ /// methods in EnumDecl should be updated appropriately.
+ class EnumDeclBitfields {
+ friend class EnumDecl;
+ /// For the bits in DeclContextBitfields.
+ uint64_t : NumDeclContextBits;
+ /// For the bits in TagDeclBitfields.
+ uint64_t : NumTagDeclBits;
+
+ /// Width in bits required to store all the non-negative
+ /// enumerators of this enum.
+ uint64_t NumPositiveBits : 8;
+
+ /// Width in bits required to store all the negative
+ /// enumerators of this enum.
+ uint64_t NumNegativeBits : 8;
+
+ /// True if this tag declaration is a scoped enumeration. Only
+ /// possible in C++11 mode.
+ uint64_t IsScoped : 1;
+
+ /// If this tag declaration is a scoped enum,
+ /// then this is true if the scoped enum was declared using the class
+ /// tag, false if it was declared with the struct tag. No meaning is
+ /// associated if this tag declaration is not a scoped enum.
+ uint64_t IsScopedUsingClassTag : 1;
+
+ /// True if this is an enumeration with fixed underlying type. Only
+ /// possible in C++11, Microsoft extensions, or Objective C mode.
+ uint64_t IsFixed : 1;
+
+ /// True if a valid hash is stored in ODRHash.
+ uint64_t HasODRHash : 1;
+ };
+
+ /// Number of non-inherited bits in EnumDeclBitfields.
+ enum { NumEnumDeclBits = 20 };
+
+ /// Stores the bits used by RecordDecl.
+ /// If modified NumRecordDeclBits and the accessor
+ /// methods in RecordDecl should be updated appropriately.
+ class RecordDeclBitfields {
+ friend class RecordDecl;
+ /// For the bits in DeclContextBitfields.
+ uint64_t : NumDeclContextBits;
+ /// For the bits in TagDeclBitfields.
+ uint64_t : NumTagDeclBits;
+
+ /// This is true if this struct ends with a flexible
+ /// array member (e.g. int X[]) or if this union contains a struct that does.
+ /// If so, this cannot be contained in arrays or other structs as a member.
+ uint64_t HasFlexibleArrayMember : 1;
+
+ /// Whether this is the type of an anonymous struct or union.
+ uint64_t AnonymousStructOrUnion : 1;
+
+ /// This is true if this struct has at least one member
+ /// containing an Objective-C object pointer type.
+ uint64_t HasObjectMember : 1;
+
+ /// This is true if struct has at least one member of
+ /// 'volatile' type.
+ uint64_t HasVolatileMember : 1;
+
+ /// Whether the field declarations of this record have been loaded
+ /// from external storage. To avoid unnecessary deserialization of
+ /// methods/nested types we allow deserialization of just the fields
+ /// when needed.
+ mutable uint64_t LoadedFieldsFromExternalStorage : 1;
+
+ /// Basic properties of non-trivial C structs.
+ uint64_t NonTrivialToPrimitiveDefaultInitialize : 1;
+ uint64_t NonTrivialToPrimitiveCopy : 1;
+ uint64_t NonTrivialToPrimitiveDestroy : 1;
+
+ /// Indicates whether this struct is destroyed in the callee.
+ uint64_t ParamDestroyedInCallee : 1;
+
+ /// Represents the way this type is passed to a function.
+ uint64_t ArgPassingRestrictions : 2;
+ };
+
+ /// Number of non-inherited bits in RecordDeclBitfields.
+ enum { NumRecordDeclBits = 11 };
+
+ /// Stores the bits used by OMPDeclareReductionDecl.
+ /// If modified NumOMPDeclareReductionDeclBits and the accessor
+ /// methods in OMPDeclareReductionDecl should be updated appropriately.
+ class OMPDeclareReductionDeclBitfields {
+ friend class OMPDeclareReductionDecl;
+ /// For the bits in DeclContextBitfields
+ uint64_t : NumDeclContextBits;
+
+ /// Kind of initializer,
+ /// function call or omp_priv<init_expr> initializtion.
+ uint64_t InitializerKind : 2;
+ };
+
+ /// Number of non-inherited bits in OMPDeclareReductionDeclBitfields.
+ enum { NumOMPDeclareReductionDeclBits = 2 };
+
+ /// Stores the bits used by FunctionDecl.
+ /// If modified NumFunctionDeclBits and the accessor
+ /// methods in FunctionDecl and CXXDeductionGuideDecl
+ /// (for IsCopyDeductionCandidate) should be updated appropriately.
+ class FunctionDeclBitfields {
+ friend class FunctionDecl;
+ /// For IsCopyDeductionCandidate
+ friend class CXXDeductionGuideDecl;
+ /// For the bits in DeclContextBitfields.
+ uint64_t : NumDeclContextBits;
+
+ uint64_t SClass : 3;
+ uint64_t IsInline : 1;
+ uint64_t IsInlineSpecified : 1;
+
+ /// This is shared by CXXConstructorDecl,
+ /// CXXConversionDecl, and CXXDeductionGuideDecl.
+ uint64_t IsExplicitSpecified : 1;
+
+ uint64_t IsVirtualAsWritten : 1;
+ uint64_t IsPure : 1;
+ uint64_t HasInheritedPrototype : 1;
+ uint64_t HasWrittenPrototype : 1;
+ uint64_t IsDeleted : 1;
+ /// Used by CXXMethodDecl
+ uint64_t IsTrivial : 1;
+
+ /// This flag indicates whether this function is trivial for the purpose of
+ /// calls. This is meaningful only when this function is a copy/move
+ /// constructor or a destructor.
+ uint64_t IsTrivialForCall : 1;
+
+ /// Used by CXXMethodDecl
+ uint64_t IsDefaulted : 1;
+ /// Used by CXXMethodDecl
+ uint64_t IsExplicitlyDefaulted : 1;
+ uint64_t HasImplicitReturnZero : 1;
+ uint64_t IsLateTemplateParsed : 1;
+ uint64_t IsConstexpr : 1;
+ uint64_t InstantiationIsPending : 1;
+
+ /// Indicates if the function uses __try.
+ uint64_t UsesSEHTry : 1;
+
+ /// Indicates if the function was a definition
+ /// but its body was skipped.
+ uint64_t HasSkippedBody : 1;
+
+ /// Indicates if the function declaration will
+ /// have a body, once we're done parsing it.
+ uint64_t WillHaveBody : 1;
+
+ /// Indicates that this function is a multiversioned
+ /// function using attribute 'target'.
+ uint64_t IsMultiVersion : 1;
+
+ /// [C++17] Only used by CXXDeductionGuideDecl. Indicates that
+ /// the Deduction Guide is the implicitly generated 'copy
+ /// deduction candidate' (is used during overload resolution).
+ uint64_t IsCopyDeductionCandidate : 1;
+
+ /// Store the ODRHash after first calculation.
+ uint64_t HasODRHash : 1;
+ };
+
+ /// Number of non-inherited bits in FunctionDeclBitfields.
+ enum { NumFunctionDeclBits = 25 };
+
+ /// Stores the bits used by CXXConstructorDecl. If modified
+ /// NumCXXConstructorDeclBits and the accessor
+ /// methods in CXXConstructorDecl should be updated appropriately.
+ class CXXConstructorDeclBitfields {
+ friend class CXXConstructorDecl;
+ /// For the bits in DeclContextBitfields.
+ uint64_t : NumDeclContextBits;
+ /// For the bits in FunctionDeclBitfields.
+ uint64_t : NumFunctionDeclBits;
+
+ /// 25 bits to fit in the remaining availible space.
+ /// Note that this makes CXXConstructorDeclBitfields take
+ /// exactly 64 bits and thus the width of NumCtorInitializers
+ /// will need to be shrunk if some bit is added to NumDeclContextBitfields,
+ /// NumFunctionDeclBitfields or CXXConstructorDeclBitfields.
+ uint64_t NumCtorInitializers : 25;
+ uint64_t IsInheritingConstructor : 1;
+ };
+
+ /// Number of non-inherited bits in CXXConstructorDeclBitfields.
+ enum { NumCXXConstructorDeclBits = 26 };
+
+ /// Stores the bits used by ObjCMethodDecl.
+ /// If modified NumObjCMethodDeclBits and the accessor
+ /// methods in ObjCMethodDecl should be updated appropriately.
+ class ObjCMethodDeclBitfields {
+ friend class ObjCMethodDecl;
+
+ /// For the bits in DeclContextBitfields.
+ uint64_t : NumDeclContextBits;
+
+ /// The conventional meaning of this method; an ObjCMethodFamily.
+ /// This is not serialized; instead, it is computed on demand and
+ /// cached.
+ mutable uint64_t Family : ObjCMethodFamilyBitWidth;
+
+ /// instance (true) or class (false) method.
+ uint64_t IsInstance : 1;
+ uint64_t IsVariadic : 1;
+
+ /// True if this method is the getter or setter for an explicit property.
+ uint64_t IsPropertyAccessor : 1;
+
+ /// Method has a definition.
+ uint64_t IsDefined : 1;
+
+ /// Method redeclaration in the same interface.
+ uint64_t IsRedeclaration : 1;
+
+ /// Is redeclared in the same interface.
+ mutable uint64_t HasRedeclaration : 1;
+
+ /// \@required/\@optional
+ uint64_t DeclImplementation : 2;
+
+ /// in, inout, etc.
+ uint64_t objcDeclQualifier : 7;
+
+ /// Indicates whether this method has a related result type.
+ uint64_t RelatedResultType : 1;
- /// If \c true, lookups should only return identifier from
- /// DeclContext scope (for example TranslationUnit). Used in
- /// LookupQualifiedName()
- mutable bool UseQualifiedLookup : 1;
+ /// Whether the locations of the selector identifiers are in a
+ /// "standard" position, a enum SelectorLocationsKind.
+ uint64_t SelLocsKind : 2;
+
+ /// Whether this method overrides any other in the class hierarchy.
+ ///
+ /// A method is said to override any method in the class's
+ /// base classes, its protocols, or its categories' protocols, that has
+ /// the same selector and is of the same kind (class or instance).
+ /// A method in an implementation is not considered as overriding the same
+ /// method in the interface or its categories.
+ uint64_t IsOverriding : 1;
+
+ /// Indicates if the method was a definition but its body was skipped.
+ uint64_t HasSkippedBody : 1;
+ };
+
+ /// Number of non-inherited bits in ObjCMethodDeclBitfields.
+ enum { NumObjCMethodDeclBits = 24 };
+
+ /// Stores the bits used by ObjCContainerDecl.
+ /// If modified NumObjCContainerDeclBits and the accessor
+ /// methods in ObjCContainerDecl should be updated appropriately.
+ class ObjCContainerDeclBitfields {
+ friend class ObjCContainerDecl;
+ /// For the bits in DeclContextBitfields
+ uint32_t : NumDeclContextBits;
+
+ // Not a bitfield but this saves space.
+ // Note that ObjCContainerDeclBitfields is full.
+ SourceLocation AtStart;
+ };
+
+ /// Number of non-inherited bits in ObjCContainerDeclBitfields.
+ /// Note that here we rely on the fact that SourceLocation is 32 bits
+ /// wide. We check this with the static_assert in the ctor of DeclContext.
+ enum { NumObjCContainerDeclBits = 64 - NumDeclContextBits };
+
+ /// Stores the bits used by LinkageSpecDecl.
+ /// If modified NumLinkageSpecDeclBits and the accessor
+ /// methods in LinkageSpecDecl should be updated appropriately.
+ class LinkageSpecDeclBitfields {
+ friend class LinkageSpecDecl;
+ /// For the bits in DeclContextBitfields.
+ uint64_t : NumDeclContextBits;
+
+ /// The language for this linkage specification with values
+ /// in the enum LinkageSpecDecl::LanguageIDs.
+ uint64_t Language : 3;
+
+ /// True if this linkage spec has braces.
+ /// This is needed so that hasBraces() returns the correct result while the
+ /// linkage spec body is being parsed. Once RBraceLoc has been set this is
+ /// not used, so it doesn't need to be serialized.
+ uint64_t HasBraces : 1;
+ };
+
+ /// Number of non-inherited bits in LinkageSpecDeclBitfields.
+ enum { NumLinkageSpecDeclBits = 4 };
+
+ /// Stores the bits used by BlockDecl.
+ /// If modified NumBlockDeclBits and the accessor
+ /// methods in BlockDecl should be updated appropriately.
+ class BlockDeclBitfields {
+ friend class BlockDecl;
+ /// For the bits in DeclContextBitfields.
+ uint64_t : NumDeclContextBits;
+
+ uint64_t IsVariadic : 1;
+ uint64_t CapturesCXXThis : 1;
+ uint64_t BlockMissingReturnType : 1;
+ uint64_t IsConversionFromLambda : 1;
+
+ /// A bit that indicates this block is passed directly to a function as a
+ /// non-escaping parameter.
+ uint64_t DoesNotEscape : 1;
+ };
+
+ /// Number of non-inherited bits in BlockDeclBitfields.
+ enum { NumBlockDeclBits = 5 };
/// Pointer to the data structure used to lookup declarations
/// within this context (or a DependentStoredDeclsMap if this is a
@@ -1301,9 +1676,50 @@ class DeclContext {
mutable StoredDeclsMap *LookupPtr = nullptr;
protected:
- friend class ASTDeclReader;
- friend class ASTWriter;
- friend class ExternalASTSource;
+ /// This anonymous union stores the bits belonging to DeclContext and classes
+ /// deriving from it. The goal is to use otherwise wasted
+ /// space in DeclContext to store data belonging to derived classes.
+ /// The space saved is especially significient when pointers are aligned
+ /// to 8 bytes. In this case due to alignment requirements we have a
+ /// little less than 8 bytes free in DeclContext which we can use.
+ /// We check that none of the classes in this union is larger than
+ /// 8 bytes with static_asserts in the ctor of DeclContext.
+ union {
+ DeclContextBitfields DeclContextBits;
+ TagDeclBitfields TagDeclBits;
+ EnumDeclBitfields EnumDeclBits;
+ RecordDeclBitfields RecordDeclBits;
+ OMPDeclareReductionDeclBitfields OMPDeclareReductionDeclBits;
+ FunctionDeclBitfields FunctionDeclBits;
+ CXXConstructorDeclBitfields CXXConstructorDeclBits;
+ ObjCMethodDeclBitfields ObjCMethodDeclBits;
+ ObjCContainerDeclBitfields ObjCContainerDeclBits;
+ LinkageSpecDeclBitfields LinkageSpecDeclBits;
+ BlockDeclBitfields BlockDeclBits;
+
+ static_assert(sizeof(DeclContextBitfields) <= 8,
+ "DeclContextBitfields is larger than 8 bytes!");
+ static_assert(sizeof(TagDeclBitfields) <= 8,
+ "TagDeclBitfields is larger than 8 bytes!");
+ static_assert(sizeof(EnumDeclBitfields) <= 8,
+ "EnumDeclBitfields is larger than 8 bytes!");
+ static_assert(sizeof(RecordDeclBitfields) <= 8,
+ "RecordDeclBitfields is larger than 8 bytes!");
+ static_assert(sizeof(OMPDeclareReductionDeclBitfields) <= 8,
+ "OMPDeclareReductionDeclBitfields is larger than 8 bytes!");
+ static_assert(sizeof(FunctionDeclBitfields) <= 8,
+ "FunctionDeclBitfields is larger than 8 bytes!");
+ static_assert(sizeof(CXXConstructorDeclBitfields) <= 8,
+ "CXXConstructorDeclBitfields is larger than 8 bytes!");
+ static_assert(sizeof(ObjCMethodDeclBitfields) <= 8,
+ "ObjCMethodDeclBitfields is larger than 8 bytes!");
+ static_assert(sizeof(ObjCContainerDeclBitfields) <= 8,
+ "ObjCContainerDeclBitfields is larger than 8 bytes!");
+ static_assert(sizeof(LinkageSpecDeclBitfields) <= 8,
+ "LinkageSpecDeclBitfields is larger than 8 bytes!");
+ static_assert(sizeof(BlockDeclBitfields) <= 8,
+ "BlockDeclBitfields is larger than 8 bytes!");
+ };
/// FirstDecl - The first declaration stored within this declaration
/// context.
@@ -1321,18 +1737,13 @@ protected:
static std::pair<Decl *, Decl *>
BuildDeclChain(ArrayRef<Decl*> Decls, bool FieldsAlreadyLoaded);
- DeclContext(Decl::Kind K)
- : DeclKind(K), ExternalLexicalStorage(false),
- ExternalVisibleStorage(false),
- NeedToReconcileExternalVisibleStorage(false),
- HasLazyLocalLexicalLookups(false), HasLazyExternalLexicalLookups(false),
- UseQualifiedLookup(false) {}
+ DeclContext(Decl::Kind K);
public:
~DeclContext();
Decl::Kind getDeclKind() const {
- return static_cast<Decl::Kind>(DeclKind);
+ return static_cast<Decl::Kind>(DeclContextBits.DeclKind);
}
const char *getDeclKindName() const;
@@ -1371,54 +1782,54 @@ public:
return cast<Decl>(this)->getASTContext();
}
- bool isClosure() const {
- return DeclKind == Decl::Block;
- }
+ bool isClosure() const { return getDeclKind() == Decl::Block; }
bool isObjCContainer() const {
- switch (DeclKind) {
- case Decl::ObjCCategory:
- case Decl::ObjCCategoryImpl:
- case Decl::ObjCImplementation:
- case Decl::ObjCInterface:
- case Decl::ObjCProtocol:
- return true;
+ switch (getDeclKind()) {
+ case Decl::ObjCCategory:
+ case Decl::ObjCCategoryImpl:
+ case Decl::ObjCImplementation:
+ case Decl::ObjCInterface:
+ case Decl::ObjCProtocol:
+ return true;
+ default:
+ return false;
}
- return false;
}
bool isFunctionOrMethod() const {
- switch (DeclKind) {
+ switch (getDeclKind()) {
case Decl::Block:
case Decl::Captured:
case Decl::ObjCMethod:
return true;
default:
- return DeclKind >= Decl::firstFunction && DeclKind <= Decl::lastFunction;
+ return getDeclKind() >= Decl::firstFunction &&
+ getDeclKind() <= Decl::lastFunction;
}
}
/// Test whether the context supports looking up names.
bool isLookupContext() const {
- return !isFunctionOrMethod() && DeclKind != Decl::LinkageSpec &&
- DeclKind != Decl::Export;
+ return !isFunctionOrMethod() && getDeclKind() != Decl::LinkageSpec &&
+ getDeclKind() != Decl::Export;
}
bool isFileContext() const {
- return DeclKind == Decl::TranslationUnit || DeclKind == Decl::Namespace;
+ return getDeclKind() == Decl::TranslationUnit ||
+ getDeclKind() == Decl::Namespace;
}
bool isTranslationUnit() const {
- return DeclKind == Decl::TranslationUnit;
+ return getDeclKind() == Decl::TranslationUnit;
}
bool isRecord() const {
- return DeclKind >= Decl::firstRecord && DeclKind <= Decl::lastRecord;
+ return getDeclKind() >= Decl::firstRecord &&
+ getDeclKind() <= Decl::lastRecord;
}
- bool isNamespace() const {
- return DeclKind == Decl::Namespace;
- }
+ bool isNamespace() const { return getDeclKind() == Decl::Namespace; }
bool isStdNamespace() const;
@@ -1886,7 +2297,7 @@ public:
void setMustBuildLookupTable() {
assert(this == getPrimaryContext() &&
"should only be called on primary context");
- HasLazyExternalLexicalLookups = true;
+ DeclContextBits.HasLazyExternalLexicalLookups = true;
}
/// Retrieve the internal representation of the lookup structure.
@@ -1898,24 +2309,28 @@ public:
/// Whether this DeclContext has external storage containing
/// additional declarations that are lexically in this context.
- bool hasExternalLexicalStorage() const { return ExternalLexicalStorage; }
+ bool hasExternalLexicalStorage() const {
+ return DeclContextBits.ExternalLexicalStorage;
+ }
/// State whether this DeclContext has external storage for
/// declarations lexically in this context.
- void setHasExternalLexicalStorage(bool ES = true) {
- ExternalLexicalStorage = ES;
+ void setHasExternalLexicalStorage(bool ES = true) const {
+ DeclContextBits.ExternalLexicalStorage = ES;
}
/// Whether this DeclContext has external storage containing
/// additional declarations that are visible in this context.
- bool hasExternalVisibleStorage() const { return ExternalVisibleStorage; }
+ bool hasExternalVisibleStorage() const {
+ return DeclContextBits.ExternalVisibleStorage;
+ }
/// State whether this DeclContext has external storage for
/// declarations visible in this context.
- void setHasExternalVisibleStorage(bool ES = true) {
- ExternalVisibleStorage = ES;
+ void setHasExternalVisibleStorage(bool ES = true) const {
+ DeclContextBits.ExternalVisibleStorage = ES;
if (ES && LookupPtr)
- NeedToReconcileExternalVisibleStorage = true;
+ DeclContextBits.NeedToReconcileExternalVisibleStorage = true;
}
/// Determine whether the given declaration is stored in the list of
@@ -1925,14 +2340,14 @@ public:
D == LastDecl);
}
- bool setUseQualifiedLookup(bool use = true) {
- bool old_value = UseQualifiedLookup;
- UseQualifiedLookup = use;
+ bool setUseQualifiedLookup(bool use = true) const {
+ bool old_value = DeclContextBits.UseQualifiedLookup;
+ DeclContextBits.UseQualifiedLookup = use;
return old_value;
}
bool shouldUseQualifiedLookup() const {
- return UseQualifiedLookup;
+ return DeclContextBits.UseQualifiedLookup;
}
static bool classof(const Decl *D);
@@ -1944,7 +2359,45 @@ public:
bool Deserialize = false) const;
private:
- friend class DependentDiagnostic;
+ /// Whether this declaration context has had externally visible
+ /// storage added since the last lookup. In this case, \c LookupPtr's
+ /// invariant may not hold and needs to be fixed before we perform
+ /// another lookup.
+ bool hasNeedToReconcileExternalVisibleStorage() const {
+ return DeclContextBits.NeedToReconcileExternalVisibleStorage;
+ }
+
+ /// State that this declaration context has had externally visible
+ /// storage added since the last lookup. In this case, \c LookupPtr's
+ /// invariant may not hold and needs to be fixed before we perform
+ /// another lookup.
+ void setNeedToReconcileExternalVisibleStorage(bool Need = true) const {
+ DeclContextBits.NeedToReconcileExternalVisibleStorage = Need;
+ }
+
+ /// If \c true, this context may have local lexical declarations
+ /// that are missing from the lookup table.
+ bool hasLazyLocalLexicalLookups() const {
+ return DeclContextBits.HasLazyLocalLexicalLookups;
+ }
+
+ /// If \c true, this context may have local lexical declarations
+ /// that are missing from the lookup table.
+ void setHasLazyLocalLexicalLookups(bool HasLLLL = true) const {
+ DeclContextBits.HasLazyLocalLexicalLookups = HasLLLL;
+ }
+
+ /// If \c true, the external source may have lexical declarations
+ /// that are missing from the lookup table.
+ bool hasLazyExternalLexicalLookups() const {
+ return DeclContextBits.HasLazyExternalLexicalLookups;
+ }
+
+ /// If \c true, the external source may have lexical declarations
+ /// that are missing from the lookup table.
+ void setHasLazyExternalLexicalLookups(bool HasLELL = true) const {
+ DeclContextBits.HasLazyExternalLexicalLookups = HasLELL;
+ }
void reconcileExternalVisibleStorage() const;
bool LoadLexicalDeclsFromExternalStorage() const;
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 4353f66a34e4..d3357c245d86 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -233,12 +233,12 @@ public:
/// Retrieves the source range that contains the entire base specifier.
SourceRange getSourceRange() const LLVM_READONLY { return Range; }
- SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
+ SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
/// Get the location at which the base class type was written.
SourceLocation getBaseTypeLoc() const LLVM_READONLY {
- return BaseTypeInfo->getTypeLoc().getLocStart();
+ return BaseTypeInfo->getTypeLoc().getBeginLoc();
}
/// Determines whether the base class is a virtual base class (or not).
@@ -974,10 +974,7 @@ public:
bool needsImplicitDefaultConstructor() const {
return !data().UserDeclaredConstructor &&
!(data().DeclaredSpecialMembers & SMF_DefaultConstructor) &&
- // C++14 [expr.prim.lambda]p20:
- // The closure type associated with a lambda-expression has no
- // default constructor.
- !isLambda();
+ (!isLambda() || lambdaIsDefaultConstructibleAndAssignable());
}
/// Determine whether this class has any user-declared constructors.
@@ -1167,10 +1164,7 @@ public:
!hasUserDeclaredCopyAssignment() &&
!hasUserDeclaredMoveConstructor() &&
!hasUserDeclaredDestructor() &&
- // C++1z [expr.prim.lambda]p21: "the closure type has a deleted copy
- // assignment operator". The intent is that this counts as a user
- // declared copy assignment, but we do not model it that way.
- !isLambda();
+ (!isLambda() || lambdaIsDefaultConstructibleAndAssignable());
}
/// Determine whether we need to eagerly declare a move assignment
@@ -1210,6 +1204,10 @@ public:
/// a template).
bool isGenericLambda() const;
+ /// Determine whether this lambda should have an implicit default constructor
+ /// and copy and move assignment operators.
+ bool lambdaIsDefaultConstructibleAndAssignable() const;
+
/// Retrieve the lambda call operator of the closure type
/// if this is a closure type.
CXXMethodDecl *getLambdaCallOperator() const;
@@ -1543,7 +1541,7 @@ public:
///
/// C++11 [class]p6:
/// "A trivial class is a class that has a trivial default constructor and
- /// is trivially copiable."
+ /// is trivially copyable."
bool isTrivial() const {
return isTriviallyCopyable() && hasTrivialDefaultConstructor();
}
@@ -1999,7 +1997,8 @@ private:
SC_None, false, false) {
if (EndLocation.isValid())
setRangeEnd(EndLocation);
- IsExplicitSpecified = IsExplicit;
+ setExplicitSpecified(IsExplicit);
+ setIsCopyDeductionCandidate(false);
}
public:
@@ -2015,21 +2014,20 @@ public:
static CXXDeductionGuideDecl *CreateDeserialized(ASTContext &C, unsigned ID);
/// Whether this deduction guide is explicit.
- bool isExplicit() const { return IsExplicitSpecified; }
-
- /// Whether this deduction guide was declared with the 'explicit' specifier.
- bool isExplicitSpecified() const { return IsExplicitSpecified; }
+ bool isExplicit() const { return isExplicitSpecified(); }
/// Get the template for which this guide performs deduction.
TemplateDecl *getDeducedTemplate() const {
return getDeclName().getCXXDeductionGuideTemplate();
}
- void setIsCopyDeductionCandidate() {
- IsCopyDeductionCandidate = true;
+ void setIsCopyDeductionCandidate(bool isCDC = true) {
+ FunctionDeclBits.IsCopyDeductionCandidate = isCDC;
}
- bool isCopyDeductionCandidate() const { return IsCopyDeductionCandidate; }
+ bool isCopyDeductionCandidate() const {
+ return FunctionDeclBits.IsCopyDeductionCandidate;
+ }
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -2109,10 +2107,15 @@ public:
Base, IsAppleKext);
}
- /// Determine whether this is a usual deallocation function
- /// (C++ [basic.stc.dynamic.deallocation]p2), which is an overloaded
- /// delete or delete[] operator with a particular signature.
- bool isUsualDeallocationFunction() const;
+ /// Determine whether this is a usual deallocation function (C++
+ /// [basic.stc.dynamic.deallocation]p2), which is an overloaded delete or
+ /// delete[] operator with a particular signature. Populates \p PreventedBy
+ /// with the declarations of the functions of the same kind if they were the
+ /// reason for this function returning false. This is used by
+ /// Sema::isUsualDeallocationFunction to reconsider the answer based on the
+ /// context.
+ bool isUsualDeallocationFunction(
+ SmallVectorImpl<const FunctionDecl *> &PreventedBy) const;
/// Determine whether this is a copy-assignment operator, regardless
/// of whether it was declared implicitly or explicitly.
@@ -2177,9 +2180,12 @@ public:
/// that for the call operator of a lambda closure type, this returns the
/// desugared 'this' type (a pointer to the closure type), not the captured
/// 'this' type.
- QualType getThisType(ASTContext &C) const;
+ QualType getThisType() const;
+
+ static QualType getThisType(const FunctionProtoType *FPT,
+ const CXXRecordDecl *Decl);
- unsigned getTypeQualifiers() const {
+ Qualifiers getTypeQualifiers() const {
return getType()->getAs<FunctionProtoType>()->getTypeQuals();
}
@@ -2312,6 +2318,9 @@ public:
CXXCtorInitializer(ASTContext &Context, TypeSourceInfo *TInfo,
SourceLocation L, Expr *Init, SourceLocation R);
+ /// \return Unique reproducible object identifier.
+ int64_t getID(const ASTContext &Context) const;
+
/// Determine whether this initializer is initializing a base class.
bool isBaseInitializer() const {
return Initializee.is<TypeSourceInfo*>() && !IsDelegating;
@@ -2475,31 +2484,20 @@ public:
class CXXConstructorDecl final
: public CXXMethodDecl,
private llvm::TrailingObjects<CXXConstructorDecl, InheritedConstructor> {
+ // This class stores some data in DeclContext::CXXConstructorDeclBits
+ // to save some space. Use the provided accessors to access it.
+
/// \name Support for base and member initializers.
/// \{
/// The arguments used to initialize the base or member.
LazyCXXCtorInitializersPtr CtorInitializers;
- unsigned NumCtorInitializers : 31;
- /// \}
-
- /// Whether this constructor declaration is an implicitly-declared
- /// inheriting constructor.
- unsigned IsInheritingConstructor : 1;
CXXConstructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
bool isExplicitSpecified, bool isInline,
bool isImplicitlyDeclared, bool isConstexpr,
- InheritedConstructor Inherited)
- : CXXMethodDecl(CXXConstructor, C, RD, StartLoc, NameInfo, T, TInfo,
- SC_None, isInline, isConstexpr, SourceLocation()),
- NumCtorInitializers(0), IsInheritingConstructor((bool)Inherited) {
- setImplicit(isImplicitlyDeclared);
- if (Inherited)
- *getTrailingObjects<InheritedConstructor>() = Inherited;
- IsExplicitSpecified = isExplicitSpecified;
- }
+ InheritedConstructor Inherited);
void anchor() override;
@@ -2542,12 +2540,12 @@ public:
/// Retrieve an iterator past the last initializer.
init_iterator init_end() {
- return init_begin() + NumCtorInitializers;
+ return init_begin() + getNumCtorInitializers();
}
/// Retrieve an iterator past the last initializer.
init_const_iterator init_end() const {
- return init_begin() + NumCtorInitializers;
+ return init_begin() + getNumCtorInitializers();
}
using init_reverse_iterator = std::reverse_iterator<init_iterator>;
@@ -2571,20 +2569,22 @@ public:
/// Determine the number of arguments used to initialize the member
/// or base.
unsigned getNumCtorInitializers() const {
- return NumCtorInitializers;
+ return CXXConstructorDeclBits.NumCtorInitializers;
}
void setNumCtorInitializers(unsigned numCtorInitializers) {
- NumCtorInitializers = numCtorInitializers;
+ CXXConstructorDeclBits.NumCtorInitializers = numCtorInitializers;
+ // This assert added because NumCtorInitializers is stored
+ // in CXXConstructorDeclBits as a bitfield and its width has
+ // been shrunk from 32 bits to fit into CXXConstructorDeclBitfields.
+ assert(CXXConstructorDeclBits.NumCtorInitializers ==
+ numCtorInitializers && "NumCtorInitializers overflow!");
}
void setCtorInitializers(CXXCtorInitializer **Initializers) {
CtorInitializers = Initializers;
}
- /// Whether this function is marked as explicit explicitly.
- bool isExplicitSpecified() const { return IsExplicitSpecified; }
-
/// Whether this function is explicit.
bool isExplicit() const {
return getCanonicalDecl()->isExplicitSpecified();
@@ -2665,12 +2665,20 @@ public:
/// Determine whether this is an implicit constructor synthesized to
/// model a call to a constructor inherited from a base class.
- bool isInheritingConstructor() const { return IsInheritingConstructor; }
+ bool isInheritingConstructor() const {
+ return CXXConstructorDeclBits.IsInheritingConstructor;
+ }
+
+ /// State that this is an implicit constructor synthesized to
+ /// model a call to a constructor inherited from a base class.
+ void setInheritingConstructor(bool isIC = true) {
+ CXXConstructorDeclBits.IsInheritingConstructor = isIC;
+ }
/// Get the constructor that this inheriting constructor is based on.
InheritedConstructor getInheritedConstructor() const {
- return IsInheritingConstructor ? *getTrailingObjects<InheritedConstructor>()
- : InheritedConstructor();
+ return isInheritingConstructor() ?
+ *getTrailingObjects<InheritedConstructor>() : InheritedConstructor();
}
CXXConstructorDecl *getCanonicalDecl() override {
@@ -2765,7 +2773,7 @@ class CXXConversionDecl : public CXXMethodDecl {
SourceLocation EndLocation)
: CXXMethodDecl(CXXConversion, C, RD, StartLoc, NameInfo, T, TInfo,
SC_None, isInline, isConstexpr, EndLocation) {
- IsExplicitSpecified = isExplicitSpecified;
+ setExplicitSpecified(isExplicitSpecified);
}
void anchor() override;
@@ -2783,9 +2791,6 @@ public:
SourceLocation EndLocation);
static CXXConversionDecl *CreateDeserialized(ASTContext &C, unsigned ID);
- /// Whether this function is marked as explicit explicitly.
- bool isExplicitSpecified() const { return IsExplicitSpecified; }
-
/// Whether this function is explicit.
bool isExplicit() const {
return getCanonicalDecl()->isExplicitSpecified();
@@ -2820,7 +2825,8 @@ public:
/// \endcode
class LinkageSpecDecl : public Decl, public DeclContext {
virtual void anchor();
-
+ // This class stores some data in DeclContext::LinkageSpecDeclBits to save
+ // some space. Use the provided accessors to access it.
public:
/// Represents the language in a linkage specification.
///
@@ -2834,16 +2840,6 @@ public:
};
private:
- /// The language for this linkage specification.
- unsigned Language : 3;
-
- /// True if this linkage spec has braces.
- ///
- /// This is needed so that hasBraces() returns the correct result while the
- /// linkage spec body is being parsed. Once RBraceLoc has been set this is
- /// not used, so it doesn't need to be serialized.
- unsigned HasBraces : 1;
-
/// The source location for the extern keyword.
SourceLocation ExternLoc;
@@ -2851,10 +2847,7 @@ private:
SourceLocation RBraceLoc;
LinkageSpecDecl(DeclContext *DC, SourceLocation ExternLoc,
- SourceLocation LangLoc, LanguageIDs lang, bool HasBraces)
- : Decl(LinkageSpec, DC, LangLoc), DeclContext(LinkageSpec),
- Language(lang), HasBraces(HasBraces), ExternLoc(ExternLoc),
- RBraceLoc(SourceLocation()) {}
+ SourceLocation LangLoc, LanguageIDs lang, bool HasBraces);
public:
static LinkageSpecDecl *Create(ASTContext &C, DeclContext *DC,
@@ -2864,16 +2857,18 @@ public:
static LinkageSpecDecl *CreateDeserialized(ASTContext &C, unsigned ID);
/// Return the language specified by this linkage specification.
- LanguageIDs getLanguage() const { return LanguageIDs(Language); }
+ LanguageIDs getLanguage() const {
+ return static_cast<LanguageIDs>(LinkageSpecDeclBits.Language);
+ }
/// Set the language specified by this linkage specification.
- void setLanguage(LanguageIDs L) { Language = L; }
+ void setLanguage(LanguageIDs L) { LinkageSpecDeclBits.Language = L; }
/// Determines whether this linkage specification had braces in
/// its syntactic form.
bool hasBraces() const {
- assert(!RBraceLoc.isValid() || HasBraces);
- return HasBraces;
+ assert(!RBraceLoc.isValid() || LinkageSpecDeclBits.HasBraces);
+ return LinkageSpecDeclBits.HasBraces;
}
SourceLocation getExternLoc() const { return ExternLoc; }
@@ -2881,19 +2876,19 @@ public:
void setExternLoc(SourceLocation L) { ExternLoc = L; }
void setRBraceLoc(SourceLocation L) {
RBraceLoc = L;
- HasBraces = RBraceLoc.isValid();
+ LinkageSpecDeclBits.HasBraces = RBraceLoc.isValid();
}
- SourceLocation getLocEnd() const LLVM_READONLY {
+ SourceLocation getEndLoc() const LLVM_READONLY {
if (hasBraces())
return getRBraceLoc();
// No braces: get the end location of the (only) declaration in context
// (if present).
- return decls_empty() ? getLocation() : decls_begin()->getLocEnd();
+ return decls_empty() ? getLocation() : decls_begin()->getEndLoc();
}
SourceRange getSourceRange() const override LLVM_READONLY {
- return SourceRange(ExternLoc, getLocEnd());
+ return SourceRange(ExternLoc, getEndLoc());
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -3698,7 +3693,7 @@ class UnresolvedUsingTypenameDecl
public:
/// Returns the source location of the 'using' keyword.
- SourceLocation getUsingLoc() const { return getLocStart(); }
+ SourceLocation getUsingLoc() const { return getBeginLoc(); }
/// Returns the source location of the 'typename' keyword.
SourceLocation getTypenameLoc() const { return TypenameLocation; }
@@ -3923,6 +3918,7 @@ class MSPropertyDecl : public DeclaratorDecl {
: DeclaratorDecl(MSProperty, DC, L, N, T, TInfo, StartL),
GetterId(Getter), SetterId(Setter) {}
+ void anchor() override;
public:
friend class ASTDeclReader;
diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h
index a8de8ed16840..b5808f23de6f 100644
--- a/include/clang/AST/DeclFriend.h
+++ b/include/clang/AST/DeclFriend.h
@@ -158,7 +158,7 @@ public:
if (DD->getOuterLocStart() != DD->getInnerLocStart())
return DD->getSourceRange();
}
- return SourceRange(getFriendLoc(), ND->getLocEnd());
+ return SourceRange(getFriendLoc(), ND->getEndLoc());
}
else if (TypeSourceInfo *TInfo = getFriendType()) {
SourceLocation StartL =
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index c1cc726e3152..5b57411f9785 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -137,62 +137,17 @@ public:
/// the above methods are setMenu:, menu, replaceSubview:with:, and defaultMenu.
///
class ObjCMethodDecl : public NamedDecl, public DeclContext {
+ // This class stores some data in DeclContext::ObjCMethodDeclBits
+ // to save some space. Use the provided accessors to access it.
+
public:
enum ImplementationControl { None, Required, Optional };
private:
- // The conventional meaning of this method; an ObjCMethodFamily.
- // This is not serialized; instead, it is computed on demand and
- // cached.
- mutable unsigned Family : ObjCMethodFamilyBitWidth;
-
- /// instance (true) or class (false) method.
- unsigned IsInstance : 1;
- unsigned IsVariadic : 1;
-
- /// True if this method is the getter or setter for an explicit property.
- unsigned IsPropertyAccessor : 1;
-
- // Method has a definition.
- unsigned IsDefined : 1;
-
- /// Method redeclaration in the same interface.
- unsigned IsRedeclaration : 1;
-
- /// Is redeclared in the same interface.
- mutable unsigned HasRedeclaration : 1;
-
- // NOTE: VC++ treats enums as signed, avoid using ImplementationControl enum
- /// \@required/\@optional
- unsigned DeclImplementation : 2;
-
- // NOTE: VC++ treats enums as signed, avoid using the ObjCDeclQualifier enum
- /// in, inout, etc.
- unsigned objcDeclQualifier : 7;
-
- /// Indicates whether this method has a related result type.
- unsigned RelatedResultType : 1;
-
- /// Whether the locations of the selector identifiers are in a
- /// "standard" position, a enum SelectorLocationsKind.
- unsigned SelLocsKind : 2;
-
- /// Whether this method overrides any other in the class hierarchy.
- ///
- /// A method is said to override any method in the class's
- /// base classes, its protocols, or its categories' protocols, that has
- /// the same selector and is of the same kind (class or instance).
- /// A method in an implementation is not considered as overriding the same
- /// method in the interface or its categories.
- unsigned IsOverriding : 1;
-
- /// Indicates if the method was a definition but its body was skipped.
- unsigned HasSkippedBody : 1;
-
- // Return type of this method.
+ /// Return type of this method.
QualType MethodDeclType;
- // Type source information for the return type.
+ /// Type source information for the return type.
TypeSourceInfo *ReturnTInfo;
/// Array of ParmVarDecls for the formal parameters of this method
@@ -203,7 +158,7 @@ private:
/// List of attributes for this method declaration.
SourceLocation DeclEndLoc; // the location of the ';' or '{'.
- // The following are only used for method definitions, null otherwise.
+ /// The following are only used for method definitions, null otherwise.
LazyDeclStmtPtr Body;
/// SelfDecl - Decl for the implicit self parameter. This is lazily
@@ -220,21 +175,14 @@ private:
bool isVariadic = false, bool isPropertyAccessor = false,
bool isImplicitlyDeclared = false, bool isDefined = false,
ImplementationControl impControl = None,
- bool HasRelatedResultType = false)
- : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo),
- DeclContext(ObjCMethod), Family(InvalidObjCMethodFamily),
- IsInstance(isInstance), IsVariadic(isVariadic),
- IsPropertyAccessor(isPropertyAccessor), IsDefined(isDefined),
- IsRedeclaration(0), HasRedeclaration(0), DeclImplementation(impControl),
- objcDeclQualifier(OBJC_TQ_None),
- RelatedResultType(HasRelatedResultType),
- SelLocsKind(SelLoc_StandardNoSpace), IsOverriding(0), HasSkippedBody(0),
- MethodDeclType(T), ReturnTInfo(ReturnTInfo), DeclEndLoc(endLoc) {
- setImplicit(isImplicitlyDeclared);
- }
+ bool HasRelatedResultType = false);
SelectorLocationsKind getSelLocsKind() const {
- return (SelectorLocationsKind)SelLocsKind;
+ return static_cast<SelectorLocationsKind>(ObjCMethodDeclBits.SelLocsKind);
+ }
+
+ void setSelLocsKind(SelectorLocationsKind Kind) {
+ ObjCMethodDeclBits.SelLocsKind = Kind;
}
bool hasStandardSelLocs() const {
@@ -244,10 +192,10 @@ private:
/// Get a pointer to the stored selector identifiers locations array.
/// No locations will be stored if HasStandardSelLocs is true.
SourceLocation *getStoredSelLocs() {
- return reinterpret_cast<SourceLocation*>(getParams() + NumParams);
+ return reinterpret_cast<SourceLocation *>(getParams() + NumParams);
}
const SourceLocation *getStoredSelLocs() const {
- return reinterpret_cast<const SourceLocation*>(getParams() + NumParams);
+ return reinterpret_cast<const SourceLocation *>(getParams() + NumParams);
}
/// Get a pointer to the stored selector identifiers locations array.
@@ -297,36 +245,50 @@ public:
}
ObjCDeclQualifier getObjCDeclQualifier() const {
- return ObjCDeclQualifier(objcDeclQualifier);
+ return static_cast<ObjCDeclQualifier>(ObjCMethodDeclBits.objcDeclQualifier);
+ }
+
+ void setObjCDeclQualifier(ObjCDeclQualifier QV) {
+ ObjCMethodDeclBits.objcDeclQualifier = QV;
}
- void setObjCDeclQualifier(ObjCDeclQualifier QV) { objcDeclQualifier = QV; }
/// Determine whether this method has a result type that is related
/// to the message receiver's type.
- bool hasRelatedResultType() const { return RelatedResultType; }
+ bool hasRelatedResultType() const {
+ return ObjCMethodDeclBits.RelatedResultType;
+ }
/// Note whether this method has a related result type.
- void SetRelatedResultType(bool RRT = true) { RelatedResultType = RRT; }
+ void setRelatedResultType(bool RRT = true) {
+ ObjCMethodDeclBits.RelatedResultType = RRT;
+ }
/// True if this is a method redeclaration in the same interface.
- bool isRedeclaration() const { return IsRedeclaration; }
+ bool isRedeclaration() const { return ObjCMethodDeclBits.IsRedeclaration; }
+ void setIsRedeclaration(bool RD) { ObjCMethodDeclBits.IsRedeclaration = RD; }
void setAsRedeclaration(const ObjCMethodDecl *PrevMethod);
+ /// True if redeclared in the same interface.
+ bool hasRedeclaration() const { return ObjCMethodDeclBits.HasRedeclaration; }
+ void setHasRedeclaration(bool HRD) const {
+ ObjCMethodDeclBits.HasRedeclaration = HRD;
+ }
+
/// Returns the location where the declarator ends. It will be
/// the location of ';' for a method declaration and the location of '{'
/// for a method definition.
SourceLocation getDeclaratorEndLoc() const { return DeclEndLoc; }
// Location information, modeled after the Stmt API.
- SourceLocation getLocStart() const LLVM_READONLY { return getLocation(); }
- SourceLocation getLocEnd() const LLVM_READONLY;
+ SourceLocation getBeginLoc() const LLVM_READONLY { return getLocation(); }
+ SourceLocation getEndLoc() const LLVM_READONLY;
SourceRange getSourceRange() const override LLVM_READONLY {
- return SourceRange(getLocation(), getLocEnd());
+ return SourceRange(getLocation(), getEndLoc());
}
SourceLocation getSelectorStartLoc() const {
if (isImplicit())
- return getLocStart();
+ return getBeginLoc();
return getSelectorLoc(0);
}
@@ -407,6 +369,14 @@ public:
NumParams);
}
+ ParmVarDecl *getParamDecl(unsigned Idx) {
+ assert(Idx < NumParams && "Index out of bounds!");
+ return getParams()[Idx];
+ }
+ const ParmVarDecl *getParamDecl(unsigned Idx) const {
+ return const_cast<ObjCMethodDecl *>(this)->getParamDecl(Idx);
+ }
+
/// Sets the method's parameters and selector source locations.
/// If the method is implicit (not coming from source) \p SelLocs is
/// ignored.
@@ -449,18 +419,26 @@ public:
/// Determines the family of this method.
ObjCMethodFamily getMethodFamily() const;
- bool isInstanceMethod() const { return IsInstance; }
- void setInstanceMethod(bool isInst) { IsInstance = isInst; }
- bool isVariadic() const { return IsVariadic; }
- void setVariadic(bool isVar) { IsVariadic = isVar; }
+ bool isInstanceMethod() const { return ObjCMethodDeclBits.IsInstance; }
+ void setInstanceMethod(bool isInst) {
+ ObjCMethodDeclBits.IsInstance = isInst;
+ }
- bool isClassMethod() const { return !IsInstance; }
+ bool isVariadic() const { return ObjCMethodDeclBits.IsVariadic; }
+ void setVariadic(bool isVar) { ObjCMethodDeclBits.IsVariadic = isVar; }
- bool isPropertyAccessor() const { return IsPropertyAccessor; }
- void setPropertyAccessor(bool isAccessor) { IsPropertyAccessor = isAccessor; }
+ bool isClassMethod() const { return !isInstanceMethod(); }
- bool isDefined() const { return IsDefined; }
- void setDefined(bool isDefined) { IsDefined = isDefined; }
+ bool isPropertyAccessor() const {
+ return ObjCMethodDeclBits.IsPropertyAccessor;
+ }
+
+ void setPropertyAccessor(bool isAccessor) {
+ ObjCMethodDeclBits.IsPropertyAccessor = isAccessor;
+ }
+
+ bool isDefined() const { return ObjCMethodDeclBits.IsDefined; }
+ void setDefined(bool isDefined) { ObjCMethodDeclBits.IsDefined = isDefined; }
/// Whether this method overrides any other in the class hierarchy.
///
@@ -469,8 +447,8 @@ public:
/// the same selector and is of the same kind (class or instance).
/// A method in an implementation is not considered as overriding the same
/// method in the interface or its categories.
- bool isOverriding() const { return IsOverriding; }
- void setOverriding(bool isOverriding) { IsOverriding = isOverriding; }
+ bool isOverriding() const { return ObjCMethodDeclBits.IsOverriding; }
+ void setOverriding(bool IsOver) { ObjCMethodDeclBits.IsOverriding = IsOver; }
/// Return overridden methods for the given \p Method.
///
@@ -484,8 +462,10 @@ public:
SmallVectorImpl<const ObjCMethodDecl *> &Overridden) const;
/// True if the method was a definition but its body was skipped.
- bool hasSkippedBody() const { return HasSkippedBody; }
- void setHasSkippedBody(bool Skipped = true) { HasSkippedBody = Skipped; }
+ bool hasSkippedBody() const { return ObjCMethodDeclBits.HasSkippedBody; }
+ void setHasSkippedBody(bool Skipped = true) {
+ ObjCMethodDeclBits.HasSkippedBody = Skipped;
+ }
/// Returns the property associated with this method's selector.
///
@@ -496,11 +476,11 @@ public:
// Related to protocols declared in \@protocol
void setDeclImplementation(ImplementationControl ic) {
- DeclImplementation = ic;
+ ObjCMethodDeclBits.DeclImplementation = ic;
}
ImplementationControl getImplementationControl() const {
- return ImplementationControl(DeclImplementation);
+ return ImplementationControl(ObjCMethodDeclBits.DeclImplementation);
}
bool isOptional() const {
@@ -534,6 +514,9 @@ public:
/// Returns whether this specific method is a definition.
bool isThisDeclarationADefinition() const { return hasBody(); }
+ /// Is this method defined in the NSObject base class?
+ bool definedInNSObject(const ASTContext &) const;
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == ObjCMethod; }
@@ -984,7 +967,8 @@ public:
/// ObjCProtocolDecl, and ObjCImplDecl.
///
class ObjCContainerDecl : public NamedDecl, public DeclContext {
- SourceLocation AtStart;
+ // This class stores some data in DeclContext::ObjCContainerDeclBits
+ // to save some space. Use the provided accessors to access it.
// These two locations in the range mark the end of the method container.
// The first points to the '@' token, and the second to the 'end' token.
@@ -993,10 +977,8 @@ class ObjCContainerDecl : public NamedDecl, public DeclContext {
void anchor() override;
public:
- ObjCContainerDecl(Kind DK, DeclContext *DC,
- IdentifierInfo *Id, SourceLocation nameLoc,
- SourceLocation atStartLoc)
- : NamedDecl(DK, DC, nameLoc, Id), DeclContext(DK), AtStart(atStartLoc) {}
+ ObjCContainerDecl(Kind DK, DeclContext *DC, IdentifierInfo *Id,
+ SourceLocation nameLoc, SourceLocation atStartLoc);
// Iterator access to instance/class properties.
using prop_iterator = specific_decl_iterator<ObjCPropertyDecl>;
@@ -1130,20 +1112,19 @@ public:
virtual void collectPropertiesToImplement(PropertyMap &PM,
PropertyDeclOrder &PO) const {}
- SourceLocation getAtStartLoc() const { return AtStart; }
- void setAtStartLoc(SourceLocation Loc) { AtStart = Loc; }
+ SourceLocation getAtStartLoc() const { return ObjCContainerDeclBits.AtStart; }
- // Marks the end of the container.
- SourceRange getAtEndRange() const {
- return AtEnd;
+ void setAtStartLoc(SourceLocation Loc) {
+ ObjCContainerDeclBits.AtStart = Loc;
}
- void setAtEndRange(SourceRange atEnd) {
- AtEnd = atEnd;
- }
+ // Marks the end of the container.
+ SourceRange getAtEndRange() const { return AtEnd; }
+
+ void setAtEndRange(SourceRange atEnd) { AtEnd = atEnd; }
SourceRange getSourceRange() const override LLVM_READONLY {
- return SourceRange(AtStart, getAtEndRange().getEnd());
+ return SourceRange(getAtStartLoc(), getAtEndRange().getEnd());
}
// Implement isa/cast/dyncast/etc.
@@ -2831,7 +2812,7 @@ public:
SourceRange getSourceRange() const override LLVM_READONLY;
- SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; }
void setAtLoc(SourceLocation Loc) { AtLoc = Loc; }
ObjCPropertyDecl *getPropertyDecl() const {
diff --git a/include/clang/AST/DeclOpenMP.h b/include/clang/AST/DeclOpenMP.h
index bec3acffc433..8540cc5b25b6 100644
--- a/include/clang/AST/DeclOpenMP.h
+++ b/include/clang/AST/DeclOpenMP.h
@@ -18,6 +18,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExternalASTSource.h"
+#include "clang/AST/OpenMPClause.h"
#include "clang/AST/Type.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/TrailingObjects.h"
@@ -100,6 +101,8 @@ public:
///
/// Here 'omp_out += omp_in' is a combiner and 'omp_priv = 0' is an initializer.
class OMPDeclareReductionDecl final : public ValueDecl, public DeclContext {
+ // This class stores some data in DeclContext::OMPDeclareReductionDeclBits
+ // to save some space. Use the provided accessors to access it.
public:
enum InitKind {
CallInit, // Initialized by function call.
@@ -110,11 +113,17 @@ public:
private:
friend class ASTDeclReader;
/// Combiner for declare reduction construct.
- Expr *Combiner;
+ Expr *Combiner = nullptr;
/// Initializer for declare reduction construct.
- Expr *Initializer;
- /// Kind of initializer - function call or omp_priv<init_expr> initializtion.
- InitKind InitializerKind = CallInit;
+ Expr *Initializer = nullptr;
+ /// In parameter of the combiner.
+ Expr *In = nullptr;
+ /// Out parameter of the combiner.
+ Expr *Out = nullptr;
+ /// Priv parameter of the initializer.
+ Expr *Priv = nullptr;
+ /// Orig parameter of the initializer.
+ Expr *Orig = nullptr;
/// Reference to the previous declare reduction construct in the same
/// scope with the same name. Required for proper templates instantiation if
@@ -125,10 +134,7 @@ private:
OMPDeclareReductionDecl(Kind DK, DeclContext *DC, SourceLocation L,
DeclarationName Name, QualType Ty,
- OMPDeclareReductionDecl *PrevDeclInScope)
- : ValueDecl(DK, DC, L, Name, Ty), DeclContext(DK), Combiner(nullptr),
- Initializer(nullptr), InitializerKind(CallInit),
- PrevDeclInScope(PrevDeclInScope) {}
+ OMPDeclareReductionDecl *PrevDeclInScope);
void setPrevDeclInScope(OMPDeclareReductionDecl *Prev) {
PrevDeclInScope = Prev;
@@ -146,19 +152,43 @@ public:
/// Get combiner expression of the declare reduction construct.
Expr *getCombiner() { return Combiner; }
const Expr *getCombiner() const { return Combiner; }
+ /// Get In variable of the combiner.
+ Expr *getCombinerIn() { return In; }
+ const Expr *getCombinerIn() const { return In; }
+ /// Get Out variable of the combiner.
+ Expr *getCombinerOut() { return Out; }
+ const Expr *getCombinerOut() const { return Out; }
/// Set combiner expression for the declare reduction construct.
void setCombiner(Expr *E) { Combiner = E; }
+ /// Set combiner In and Out vars.
+ void setCombinerData(Expr *InE, Expr *OutE) {
+ In = InE;
+ Out = OutE;
+ }
/// Get initializer expression (if specified) of the declare reduction
/// construct.
Expr *getInitializer() { return Initializer; }
const Expr *getInitializer() const { return Initializer; }
/// Get initializer kind.
- InitKind getInitializerKind() const { return InitializerKind; }
+ InitKind getInitializerKind() const {
+ return static_cast<InitKind>(OMPDeclareReductionDeclBits.InitializerKind);
+ }
+ /// Get Orig variable of the initializer.
+ Expr *getInitOrig() { return Orig; }
+ const Expr *getInitOrig() const { return Orig; }
+ /// Get Priv variable of the initializer.
+ Expr *getInitPriv() { return Priv; }
+ const Expr *getInitPriv() const { return Priv; }
/// Set initializer expression for the declare reduction construct.
void setInitializer(Expr *E, InitKind IK) {
Initializer = E;
- InitializerKind = IK;
+ OMPDeclareReductionDeclBits.InitializerKind = IK;
+ }
+ /// Set initializer Orig and Priv vars.
+ void setInitializerData(Expr *OrigE, Expr *PrivE) {
+ Orig = OrigE;
+ Priv = PrivE;
}
/// Get reference to previous declare reduction construct in the same
@@ -210,6 +240,76 @@ public:
static bool classofKind(Kind K) { return K == OMPCapturedExpr; }
};
+/// This represents '#pragma omp requires...' directive.
+/// For example
+///
+/// \code
+/// #pragma omp requires unified_address
+/// \endcode
+///
+class OMPRequiresDecl final
+ : public Decl,
+ private llvm::TrailingObjects<OMPRequiresDecl, OMPClause *> {
+ friend class ASTDeclReader;
+ friend TrailingObjects;
+
+ // Number of clauses associated with this requires declaration
+ unsigned NumClauses = 0;
+
+ virtual void anchor();
+
+ OMPRequiresDecl(Kind DK, DeclContext *DC, SourceLocation L)
+ : Decl(DK, DC, L), NumClauses(0) {}
+
+ /// Returns an array of immutable clauses associated with this requires
+ /// declaration
+ ArrayRef<const OMPClause *> getClauses() const {
+ return llvm::makeArrayRef(getTrailingObjects<OMPClause *>(), NumClauses);
+ }
+
+ /// Returns an array of clauses associated with this requires declaration
+ MutableArrayRef<OMPClause *> getClauses() {
+ return MutableArrayRef<OMPClause *>(getTrailingObjects<OMPClause *>(),
+ NumClauses);
+ }
+
+ /// Sets an array of clauses to this requires declaration
+ void setClauses(ArrayRef<OMPClause *> CL);
+
+public:
+ /// Create requires node.
+ static OMPRequiresDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L, ArrayRef<OMPClause *> CL);
+ /// Create deserialized requires node.
+ static OMPRequiresDecl *CreateDeserialized(ASTContext &C, unsigned ID,
+ unsigned N);
+
+ using clauselist_iterator = MutableArrayRef<OMPClause *>::iterator;
+ using clauselist_const_iterator = ArrayRef<const OMPClause *>::iterator;
+ using clauselist_range = llvm::iterator_range<clauselist_iterator>;
+ using clauselist_const_range = llvm::iterator_range<clauselist_const_iterator>;
+
+ unsigned clauselist_size() const { return NumClauses; }
+ bool clauselist_empty() const { return NumClauses == 0; }
+
+ clauselist_range clauselists() {
+ return clauselist_range(clauselist_begin(), clauselist_end());
+ }
+ clauselist_const_range clauselists() const {
+ return clauselist_const_range(clauselist_begin(), clauselist_end());
+ }
+ clauselist_iterator clauselist_begin() { return getClauses().begin(); }
+ clauselist_iterator clauselist_end() { return getClauses().end(); }
+ clauselist_const_iterator clauselist_begin() const {
+ return getClauses().begin();
+ }
+ clauselist_const_iterator clauselist_end() const {
+ return getClauses().end();
+ }
+
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classofKind(Kind K) { return K == OMPRequires; }
+};
} // end namespace clang
#endif
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index e0ea7cb8b1b8..f6e3d8f300ba 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -751,6 +751,7 @@ class RedeclarableTemplateDecl : public TemplateDecl,
return getMostRecentDecl();
}
+ void anchor() override;
protected:
template <typename EntryType> struct SpecEntryTraits {
using DeclType = EntryType;
@@ -1093,6 +1094,9 @@ public:
/// template.
ArrayRef<TemplateArgument> getInjectedTemplateArgs();
+ /// Merge \p Prev with our RedeclarableTemplateDecl::Common.
+ void mergePrevDecl(FunctionTemplateDecl *Prev);
+
/// Create a function template node.
static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
diff --git a/include/clang/AST/DeclVisitor.h b/include/clang/AST/DeclVisitor.h
index 520a4a10bfe1..c6cbc9ff7faa 100644
--- a/include/clang/AST/DeclVisitor.h
+++ b/include/clang/AST/DeclVisitor.h
@@ -21,15 +21,12 @@
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclOpenMP.h"
#include "clang/AST/DeclTemplate.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/ErrorHandling.h"
namespace clang {
namespace declvisitor {
-
-template <typename T> struct make_ptr { using type = T *; };
-template <typename T> struct make_const_ptr { using type = const T *; };
-
/// A simple visitor class that helps create declaration visitors.
template<template <typename> class Ptr, typename ImplClass, typename RetTy=void>
class Base {
@@ -66,16 +63,16 @@ public:
///
/// This class does not preserve constness of Decl pointers (see also
/// ConstDeclVisitor).
-template<typename ImplClass, typename RetTy = void>
+template <typename ImplClass, typename RetTy = void>
class DeclVisitor
- : public declvisitor::Base<declvisitor::make_ptr, ImplClass, RetTy> {};
+ : public declvisitor::Base<std::add_pointer, ImplClass, RetTy> {};
/// A simple visitor class that helps create declaration visitors.
///
/// This class preserves constness of Decl pointers (see also DeclVisitor).
-template<typename ImplClass, typename RetTy = void>
+template <typename ImplClass, typename RetTy = void>
class ConstDeclVisitor
- : public declvisitor::Base<declvisitor::make_const_ptr, ImplClass, RetTy> {};
+ : public declvisitor::Base<llvm::make_const_ptr, ImplClass, RetTy> {};
} // namespace clang
diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h
index 856f3ab5720e..62afae23ec79 100644
--- a/include/clang/AST/DeclarationName.h
+++ b/include/clang/AST/DeclarationName.h
@@ -14,11 +14,14 @@
#ifndef LLVM_CLANG_AST_DECLARATIONNAME_H
#define LLVM_CLANG_AST_DECLARATIONNAME_H
+#include "clang/AST/Type.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/ADT/FoldingSet.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/type_traits.h"
#include <cassert>
@@ -30,67 +33,195 @@ namespace clang {
class ASTContext;
template <typename> class CanQual;
-class CXXDeductionGuideNameExtra;
-class CXXLiteralOperatorIdName;
-class CXXOperatorIdName;
-class CXXSpecialName;
-class DeclarationNameExtra;
-class IdentifierInfo;
+class DeclarationName;
+class DeclarationNameTable;
class MultiKeywordSelector;
-enum OverloadedOperatorKind : int;
struct PrintingPolicy;
-class QualType;
class TemplateDecl;
-class Type;
class TypeSourceInfo;
class UsingDirectiveDecl;
using CanQualType = CanQual<Type>;
-/// DeclarationName - The name of a declaration. In the common case,
-/// this just stores an IdentifierInfo pointer to a normal
-/// name. However, it also provides encodings for Objective-C
-/// selectors (optimizing zero- and one-argument selectors, which make
-/// up 78% percent of all selectors in Cocoa.h) and special C++ names
-/// for constructors, destructors, and conversion functions.
-class DeclarationName {
+namespace detail {
+
+/// CXXSpecialNameExtra records the type associated with one of the "special"
+/// kinds of declaration names in C++, e.g., constructors, destructors, and
+/// conversion functions. Note that CXXSpecialName is used for C++ constructor,
+/// destructor and conversion functions, but the actual kind is not stored in
+/// CXXSpecialName. Instead we use three different FoldingSet<CXXSpecialName>
+/// in DeclarationNameTable.
+class alignas(IdentifierInfoAlignment) CXXSpecialNameExtra
+ : public llvm::FoldingSetNode {
+ friend class clang::DeclarationName;
+ friend class clang::DeclarationNameTable;
+
+ /// The type associated with this declaration name.
+ QualType Type;
+
+ /// Extra information associated with this declaration name that
+ /// can be used by the front end. All bits are really needed
+ /// so it is not possible to stash something in the low order bits.
+ void *FETokenInfo;
+
+ CXXSpecialNameExtra(QualType QT) : Type(QT), FETokenInfo(nullptr) {}
+
public:
- /// NameKind - The kind of name this object contains.
- enum NameKind {
- Identifier,
- ObjCZeroArgSelector,
- ObjCOneArgSelector,
- ObjCMultiArgSelector,
- CXXConstructorName,
- CXXDestructorName,
- CXXConversionFunctionName,
- CXXDeductionGuideName,
- CXXOperatorName,
- CXXLiteralOperatorName,
- CXXUsingDirective
- };
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ ID.AddPointer(Type.getAsOpaquePtr());
+ }
+};
- static const unsigned NumNameKinds = CXXUsingDirective + 1;
+/// Contains extra information for the name of a C++ deduction guide.
+class alignas(IdentifierInfoAlignment) CXXDeductionGuideNameExtra
+ : public detail::DeclarationNameExtra,
+ public llvm::FoldingSetNode {
+ friend class clang::DeclarationName;
+ friend class clang::DeclarationNameTable;
-private:
+ /// The template named by the deduction guide.
+ TemplateDecl *Template;
+
+ /// Extra information associated with this operator name that
+ /// can be used by the front end. All bits are really needed
+ /// so it is not possible to stash something in the low order bits.
+ void *FETokenInfo;
+
+ CXXDeductionGuideNameExtra(TemplateDecl *TD)
+ : DeclarationNameExtra(CXXDeductionGuideName), Template(TD),
+ FETokenInfo(nullptr) {}
+
+public:
+ void Profile(llvm::FoldingSetNodeID &ID) { ID.AddPointer(Template); }
+};
+
+/// Contains extra information for the name of an overloaded operator
+/// in C++, such as "operator+. This do not includes literal or conversion
+/// operators. For literal operators see CXXLiteralOperatorIdName and for
+/// conversion operators see CXXSpecialNameExtra.
+class alignas(IdentifierInfoAlignment) CXXOperatorIdName {
+ friend class clang::DeclarationName;
+ friend class clang::DeclarationNameTable;
+
+ /// The kind of this operator.
+ OverloadedOperatorKind Kind = OO_None;
+
+ /// Extra information associated with this operator name that
+ /// can be used by the front end. All bits are really needed
+ /// so it is not possible to stash something in the low order bits.
+ void *FETokenInfo = nullptr;
+};
+
+/// Contains the actual identifier that makes up the
+/// name of a C++ literal operator.
+class alignas(IdentifierInfoAlignment) CXXLiteralOperatorIdName
+ : public detail::DeclarationNameExtra,
+ public llvm::FoldingSetNode {
+ friend class clang::DeclarationName;
+ friend class clang::DeclarationNameTable;
+
+ IdentifierInfo *ID;
+
+ /// Extra information associated with this operator name that
+ /// can be used by the front end. All bits are really needed
+ /// so it is not possible to stash something in the low order bits.
+ void *FETokenInfo;
+
+ CXXLiteralOperatorIdName(IdentifierInfo *II)
+ : DeclarationNameExtra(CXXLiteralOperatorName), ID(II),
+ FETokenInfo(nullptr) {}
+
+public:
+ void Profile(llvm::FoldingSetNodeID &FSID) { FSID.AddPointer(ID); }
+};
+
+} // namespace detail
+
+/// The name of a declaration. In the common case, this just stores
+/// an IdentifierInfo pointer to a normal name. However, it also provides
+/// encodings for Objective-C selectors (optimizing zero- and one-argument
+/// selectors, which make up 78% percent of all selectors in Cocoa.h),
+/// special C++ names for constructors, destructors, and conversion functions,
+/// and C++ overloaded operators.
+class DeclarationName {
friend class DeclarationNameTable;
friend class NamedDecl;
- /// StoredNameKind - The kind of name that is actually stored in the
+ /// StoredNameKind represent the kind of name that is actually stored in the
/// upper bits of the Ptr field. This is only used internally.
///
- /// Note: The entries here are synchronized with the entries in Selector,
- /// for efficient translation between the two.
+ /// NameKind, StoredNameKind, and DeclarationNameExtra::ExtraKind
+ /// must satisfy the following properties. These properties enable
+ /// efficient conversion between the various kinds.
+ ///
+ /// * The first seven enumerators of StoredNameKind must have the same
+ /// numerical value as the first seven enumerators of NameKind.
+ /// This enable efficient conversion between the two enumerations
+ /// in the usual case.
+ ///
+ /// * The enumerations values of DeclarationNameExtra::ExtraKind must start
+ /// at zero, and correspond to the numerical value of the first non-inline
+ /// enumeration values of NameKind minus an offset. This makes conversion
+ /// between DeclarationNameExtra::ExtraKind and NameKind possible with
+ /// a single addition/substraction.
+ ///
+ /// * The enumeration values of Selector::IdentifierInfoFlag must correspond
+ /// to the relevant enumeration values of StoredNameKind.
+ /// More specifically:
+ /// * ZeroArg == StoredObjCZeroArgSelector,
+ /// * OneArg == StoredObjCOneArgSelector,
+ /// * MultiArg == StoredDeclarationNameExtra
+ ///
+ /// * PtrMask must mask the low 3 bits of Ptr.
enum StoredNameKind {
StoredIdentifier = 0,
- StoredObjCZeroArgSelector = 0x01,
- StoredObjCOneArgSelector = 0x02,
- StoredDeclarationNameExtra = 0x03,
- PtrMask = 0x03
+ StoredObjCZeroArgSelector = Selector::ZeroArg,
+ StoredObjCOneArgSelector = Selector::OneArg,
+ StoredCXXConstructorName = 3,
+ StoredCXXDestructorName = 4,
+ StoredCXXConversionFunctionName = 5,
+ StoredCXXOperatorName = 6,
+ StoredDeclarationNameExtra = Selector::MultiArg,
+ PtrMask = 7,
+ UncommonNameKindOffset = 8
+ };
+
+ static_assert(alignof(IdentifierInfo) >= 8 &&
+ alignof(detail::DeclarationNameExtra) >= 8 &&
+ alignof(detail::CXXSpecialNameExtra) >= 8 &&
+ alignof(detail::CXXOperatorIdName) >= 8 &&
+ alignof(detail::CXXDeductionGuideNameExtra) >= 8 &&
+ alignof(detail::CXXLiteralOperatorIdName) >= 8,
+ "The various classes that DeclarationName::Ptr can point to"
+ " must be at least aligned to 8 bytes!");
+
+public:
+ /// The kind of the name stored in this DeclarationName.
+ /// The first 7 enumeration values are stored inline and correspond
+ /// to frequently used kinds. The rest is stored in DeclarationNameExtra
+ /// and correspond to infrequently used kinds.
+ enum NameKind {
+ Identifier = StoredIdentifier,
+ ObjCZeroArgSelector = StoredObjCZeroArgSelector,
+ ObjCOneArgSelector = StoredObjCOneArgSelector,
+ CXXConstructorName = StoredCXXConstructorName,
+ CXXDestructorName = StoredCXXDestructorName,
+ CXXConversionFunctionName = StoredCXXConversionFunctionName,
+ CXXOperatorName = StoredCXXOperatorName,
+ CXXDeductionGuideName = UncommonNameKindOffset +
+ detail::DeclarationNameExtra::CXXDeductionGuideName,
+ CXXLiteralOperatorName =
+ UncommonNameKindOffset +
+ detail::DeclarationNameExtra::CXXLiteralOperatorName,
+ CXXUsingDirective = UncommonNameKindOffset +
+ detail::DeclarationNameExtra::CXXUsingDirective,
+ ObjCMultiArgSelector = UncommonNameKindOffset +
+ detail::DeclarationNameExtra::ObjCMultiArgSelector
};
- /// Ptr - The lowest two bits are used to express what kind of name
- /// we're actually storing, using the values of NameKind. Depending
+private:
+ /// The lowest three bits of Ptr are used to express what kind of name
+ /// we're actually storing, using the values of StoredNameKind. Depending
/// on the kind of name this is, the upper bits of Ptr may have one
/// of several different meanings:
///
@@ -105,99 +236,141 @@ private:
/// with one argument, and Ptr is an IdentifierInfo pointer
/// pointing to the selector name.
///
+ /// StoredCXXConstructorName - The name of a C++ constructor,
+ /// Ptr points to a CXXSpecialNameExtra.
+ ///
+ /// StoredCXXDestructorName - The name of a C++ destructor,
+ /// Ptr points to a CXXSpecialNameExtra.
+ ///
+ /// StoredCXXConversionFunctionName - The name of a C++ conversion function,
+ /// Ptr points to a CXXSpecialNameExtra.
+ ///
+ /// StoredCXXOperatorName - The name of an overloaded C++ operator,
+ /// Ptr points to a CXXOperatorIdName.
+ ///
/// StoredDeclarationNameExtra - Ptr is actually a pointer to a
/// DeclarationNameExtra structure, whose first value will tell us
- /// whether this is an Objective-C selector, C++ operator-id name,
- /// or special C++ name.
+ /// whether this is an Objective-C selector, C++ deduction guide,
+ /// C++ literal operator, or C++ using directive.
uintptr_t Ptr = 0;
- // Construct a declaration name from the name of a C++ constructor,
- // destructor, or conversion function.
- DeclarationName(DeclarationNameExtra *Name)
- : Ptr(reinterpret_cast<uintptr_t>(Name)) {
- assert((Ptr & PtrMask) == 0 && "Improperly aligned DeclarationNameExtra");
- Ptr |= StoredDeclarationNameExtra;
+ StoredNameKind getStoredNameKind() const {
+ return static_cast<StoredNameKind>(Ptr & PtrMask);
}
- /// Construct a declaration name from a raw pointer.
- DeclarationName(uintptr_t Ptr) : Ptr(Ptr) {}
+ void *getPtr() const { return reinterpret_cast<void *>(Ptr & ~PtrMask); }
- /// getStoredNameKind - Return the kind of object that is stored in
- /// Ptr.
- StoredNameKind getStoredNameKind() const {
- return static_cast<StoredNameKind>(Ptr & PtrMask);
+ void setPtrAndKind(const void *P, StoredNameKind Kind) {
+ uintptr_t PAsInteger = reinterpret_cast<uintptr_t>(P);
+ assert((Kind & ~PtrMask) == 0 &&
+ "Invalid StoredNameKind in setPtrAndKind!");
+ assert((PAsInteger & PtrMask) == 0 &&
+ "Improperly aligned pointer in setPtrAndKind!");
+ Ptr = PAsInteger | Kind;
}
- /// getExtra - Get the "extra" information associated with this
- /// multi-argument selector or C++ special name.
- DeclarationNameExtra *getExtra() const {
- assert(getStoredNameKind() == StoredDeclarationNameExtra &&
- "Declaration name does not store an Extra structure");
- return reinterpret_cast<DeclarationNameExtra *>(Ptr & ~PtrMask);
+ /// Construct a declaration name from a DeclarationNameExtra.
+ DeclarationName(detail::DeclarationNameExtra *Name) {
+ setPtrAndKind(Name, StoredDeclarationNameExtra);
}
- /// getAsCXXSpecialName - If the stored pointer is actually a
- /// CXXSpecialName, returns a pointer to it. Otherwise, returns
- /// a NULL pointer.
- CXXSpecialName *getAsCXXSpecialName() const {
- NameKind Kind = getNameKind();
- if (Kind >= CXXConstructorName && Kind <= CXXConversionFunctionName)
- return reinterpret_cast<CXXSpecialName *>(getExtra());
- return nullptr;
+ /// Construct a declaration name from a CXXSpecialNameExtra.
+ DeclarationName(detail::CXXSpecialNameExtra *Name,
+ StoredNameKind StoredKind) {
+ assert((StoredKind == StoredCXXConstructorName ||
+ StoredKind == StoredCXXDestructorName ||
+ StoredKind == StoredCXXConversionFunctionName) &&
+ "Invalid StoredNameKind when constructing a DeclarationName"
+ " from a CXXSpecialNameExtra!");
+ setPtrAndKind(Name, StoredKind);
}
- /// If the stored pointer is actually a CXXDeductionGuideNameExtra, returns a
- /// pointer to it. Otherwise, returns a NULL pointer.
- CXXDeductionGuideNameExtra *getAsCXXDeductionGuideNameExtra() const {
- if (getNameKind() == CXXDeductionGuideName)
- return reinterpret_cast<CXXDeductionGuideNameExtra *>(getExtra());
- return nullptr;
+ /// Construct a DeclarationName from a CXXOperatorIdName.
+ DeclarationName(detail::CXXOperatorIdName *Name) {
+ setPtrAndKind(Name, StoredCXXOperatorName);
}
- /// getAsCXXOperatorIdName
- CXXOperatorIdName *getAsCXXOperatorIdName() const {
- if (getNameKind() == CXXOperatorName)
- return reinterpret_cast<CXXOperatorIdName *>(getExtra());
- return nullptr;
+ /// Assert that the stored pointer points to an IdentifierInfo and return it.
+ IdentifierInfo *castAsIdentifierInfo() const {
+ assert((getStoredNameKind() == StoredIdentifier) &&
+ "DeclarationName does not store an IdentifierInfo!");
+ return static_cast<IdentifierInfo *>(getPtr());
}
- CXXLiteralOperatorIdName *getAsCXXLiteralOperatorIdName() const {
- if (getNameKind() == CXXLiteralOperatorName)
- return reinterpret_cast<CXXLiteralOperatorIdName *>(getExtra());
- return nullptr;
+ /// Assert that the stored pointer points to a DeclarationNameExtra
+ /// and return it.
+ detail::DeclarationNameExtra *castAsExtra() const {
+ assert((getStoredNameKind() == StoredDeclarationNameExtra) &&
+ "DeclarationName does not store an Extra structure!");
+ return static_cast<detail::DeclarationNameExtra *>(getPtr());
}
- /// getFETokenInfoAsVoidSlow - Retrieves the front end-specified pointer
- /// for this name as a void pointer if it's not an identifier.
- void *getFETokenInfoAsVoidSlow() const;
+ /// Assert that the stored pointer points to a CXXSpecialNameExtra
+ /// and return it.
+ detail::CXXSpecialNameExtra *castAsCXXSpecialNameExtra() const {
+ assert((getStoredNameKind() == StoredCXXConstructorName ||
+ getStoredNameKind() == StoredCXXDestructorName ||
+ getStoredNameKind() == StoredCXXConversionFunctionName) &&
+ "DeclarationName does not store a CXXSpecialNameExtra!");
+ return static_cast<detail::CXXSpecialNameExtra *>(getPtr());
+ }
+
+ /// Assert that the stored pointer points to a CXXOperatorIdName
+ /// and return it.
+ detail::CXXOperatorIdName *castAsCXXOperatorIdName() const {
+ assert((getStoredNameKind() == StoredCXXOperatorName) &&
+ "DeclarationName does not store a CXXOperatorIdName!");
+ return static_cast<detail::CXXOperatorIdName *>(getPtr());
+ }
+
+ /// Assert that the stored pointer points to a CXXDeductionGuideNameExtra
+ /// and return it.
+ detail::CXXDeductionGuideNameExtra *castAsCXXDeductionGuideNameExtra() const {
+ assert(getNameKind() == CXXDeductionGuideName &&
+ "DeclarationName does not store a CXXDeductionGuideNameExtra!");
+ return static_cast<detail::CXXDeductionGuideNameExtra *>(getPtr());
+ }
+
+ /// Assert that the stored pointer points to a CXXLiteralOperatorIdName
+ /// and return it.
+ detail::CXXLiteralOperatorIdName *castAsCXXLiteralOperatorIdName() const {
+ assert(getNameKind() == CXXLiteralOperatorName &&
+ "DeclarationName does not store a CXXLiteralOperatorIdName!");
+ return static_cast<detail::CXXLiteralOperatorIdName *>(getPtr());
+ }
+
+ /// Get and set the FETokenInfo in the less common cases where the
+ /// declaration name do not point to an identifier.
+ void *getFETokenInfoSlow() const;
+ void setFETokenInfoSlow(void *T);
public:
- /// DeclarationName - Used to create an empty selector.
- DeclarationName() = default;
+ /// Construct an empty declaration name.
+ DeclarationName() { setPtrAndKind(nullptr, StoredIdentifier); }
- // Construct a declaration name from an IdentifierInfo *.
- DeclarationName(const IdentifierInfo *II)
- : Ptr(reinterpret_cast<uintptr_t>(II)) {
- assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
+ /// Construct a declaration name from an IdentifierInfo *.
+ DeclarationName(const IdentifierInfo *II) {
+ setPtrAndKind(II, StoredIdentifier);
}
- // Construct a declaration name from an Objective-C selector.
+ /// Construct a declaration name from an Objective-C selector.
DeclarationName(Selector Sel) : Ptr(Sel.InfoPtr) {}
- /// getUsingDirectiveName - Return name for all using-directives.
- static DeclarationName getUsingDirectiveName();
+ /// Returns the name for all C++ using-directives.
+ static DeclarationName getUsingDirectiveName() {
+ // Single instance of DeclarationNameExtra for using-directive
+ static detail::DeclarationNameExtra UDirExtra(
+ detail::DeclarationNameExtra::CXXUsingDirective);
+ return DeclarationName(&UDirExtra);
+ }
- // operator bool() - Evaluates true when this declaration name is
- // non-empty.
+ /// Evaluates true when this declaration name is non-empty.
explicit operator bool() const {
- return ((Ptr & PtrMask) != 0) ||
- (reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask));
+ return getPtr() || (getStoredNameKind() != StoredIdentifier);
}
/// Evaluates true when this declaration name is empty.
- bool isEmpty() const {
- return !*this;
- }
+ bool isEmpty() const { return !*this; }
/// Predicate functions for querying what type of name this is.
bool isIdentifier() const { return getStoredNameKind() == StoredIdentifier; }
@@ -208,8 +381,19 @@ public:
return getStoredNameKind() == StoredObjCOneArgSelector;
}
- /// getNameKind - Determine what kind of name this is.
- NameKind getNameKind() const;
+ /// Determine what kind of name this is.
+ NameKind getNameKind() const {
+ // We rely on the fact that the first 7 NameKind and StoredNameKind
+ // have the same numerical value. This makes the usual case efficient.
+ StoredNameKind StoredKind = getStoredNameKind();
+ if (StoredKind != StoredDeclarationNameExtra)
+ return static_cast<NameKind>(StoredKind);
+ // We have to consult DeclarationNameExtra. We rely on the fact that the
+ // enumeration values of ExtraKind correspond to the enumeration values of
+ // NameKind minus an offset of UncommonNameKindOffset.
+ unsigned ExtraKind = castAsExtra()->getKind();
+ return static_cast<NameKind>(UncommonNameKindOffset + ExtraKind);
+ }
/// Determines whether the name itself is dependent, e.g., because it
/// involves a C++ type that is itself dependent.
@@ -219,95 +403,128 @@ public:
/// callee in a call expression with dependent arguments.
bool isDependentName() const;
- /// getNameAsString - Retrieve the human-readable string for this name.
+ /// Retrieve the human-readable string for this name.
std::string getAsString() const;
- /// getAsIdentifierInfo - Retrieve the IdentifierInfo * stored in
- /// this declaration name, or NULL if this declaration name isn't a
- /// simple identifier.
+ /// Retrieve the IdentifierInfo * stored in this declaration name,
+ /// or null if this declaration name isn't a simple identifier.
IdentifierInfo *getAsIdentifierInfo() const {
if (isIdentifier())
- return reinterpret_cast<IdentifierInfo *>(Ptr);
+ return castAsIdentifierInfo();
return nullptr;
}
- /// getAsOpaqueInteger - Get the representation of this declaration
- /// name as an opaque integer.
+ /// Get the representation of this declaration name as an opaque integer.
uintptr_t getAsOpaqueInteger() const { return Ptr; }
- /// getAsOpaquePtr - Get the representation of this declaration name as
- /// an opaque pointer.
- void *getAsOpaquePtr() const { return reinterpret_cast<void*>(Ptr); }
+ /// Get the representation of this declaration name as an opaque pointer.
+ void *getAsOpaquePtr() const { return reinterpret_cast<void *>(Ptr); }
+ /// Get a declaration name from an opaque pointer returned by getAsOpaquePtr.
static DeclarationName getFromOpaquePtr(void *P) {
DeclarationName N;
- N.Ptr = reinterpret_cast<uintptr_t> (P);
+ N.Ptr = reinterpret_cast<uintptr_t>(P);
return N;
}
+ /// Get a declaration name from an opaque integer
+ /// returned by getAsOpaqueInteger.
static DeclarationName getFromOpaqueInteger(uintptr_t P) {
DeclarationName N;
N.Ptr = P;
return N;
}
- /// getCXXNameType - If this name is one of the C++ names (of a
- /// constructor, destructor, or conversion function), return the
- /// type associated with that name.
- QualType getCXXNameType() const;
+ /// If this name is one of the C++ names (of a constructor, destructor,
+ /// or conversion function), return the type associated with that name.
+ QualType getCXXNameType() const {
+ if (getStoredNameKind() == StoredCXXConstructorName ||
+ getStoredNameKind() == StoredCXXDestructorName ||
+ getStoredNameKind() == StoredCXXConversionFunctionName) {
+ assert(getPtr() && "getCXXNameType on a null DeclarationName!");
+ return castAsCXXSpecialNameExtra()->Type;
+ }
+ return QualType();
+ }
/// If this name is the name of a C++ deduction guide, return the
/// template associated with that name.
- TemplateDecl *getCXXDeductionGuideTemplate() const;
+ TemplateDecl *getCXXDeductionGuideTemplate() const {
+ if (getNameKind() == CXXDeductionGuideName) {
+ assert(getPtr() &&
+ "getCXXDeductionGuideTemplate on a null DeclarationName!");
+ return castAsCXXDeductionGuideNameExtra()->Template;
+ }
+ return nullptr;
+ }
- /// getCXXOverloadedOperator - If this name is the name of an
- /// overloadable operator in C++ (e.g., @c operator+), retrieve the
- /// kind of overloaded operator.
- OverloadedOperatorKind getCXXOverloadedOperator() const;
+ /// If this name is the name of an overloadable operator in C++
+ /// (e.g., @c operator+), retrieve the kind of overloaded operator.
+ OverloadedOperatorKind getCXXOverloadedOperator() const {
+ if (getStoredNameKind() == StoredCXXOperatorName) {
+ assert(getPtr() && "getCXXOverloadedOperator on a null DeclarationName!");
+ return castAsCXXOperatorIdName()->Kind;
+ }
+ return OO_None;
+ }
- /// getCXXLiteralIdentifier - If this name is the name of a literal
- /// operator, retrieve the identifier associated with it.
- IdentifierInfo *getCXXLiteralIdentifier() const;
+ /// If this name is the name of a literal operator,
+ /// retrieve the identifier associated with it.
+ IdentifierInfo *getCXXLiteralIdentifier() const {
+ if (getNameKind() == CXXLiteralOperatorName) {
+ assert(getPtr() && "getCXXLiteralIdentifier on a null DeclarationName!");
+ return castAsCXXLiteralOperatorIdName()->ID;
+ }
+ return nullptr;
+ }
- /// getObjCSelector - Get the Objective-C selector stored in this
- /// declaration name.
+ /// Get the Objective-C selector stored in this declaration name.
Selector getObjCSelector() const {
assert((getNameKind() == ObjCZeroArgSelector ||
getNameKind() == ObjCOneArgSelector ||
- getNameKind() == ObjCMultiArgSelector ||
- Ptr == 0) && "Not a selector!");
+ getNameKind() == ObjCMultiArgSelector || !getPtr()) &&
+ "Not a selector!");
return Selector(Ptr);
}
- /// getFETokenInfo/setFETokenInfo - The language front-end is
- /// allowed to associate arbitrary metadata with some kinds of
- /// declaration names, including normal identifiers and C++
- /// constructors, destructors, and conversion functions.
- template<typename T>
- T *getFETokenInfo() const {
- if (const IdentifierInfo *Info = getAsIdentifierInfo())
- return Info->getFETokenInfo<T>();
- return static_cast<T*>(getFETokenInfoAsVoidSlow());
+ /// Get and set FETokenInfo. The language front-end is allowed to associate
+ /// arbitrary metadata with some kinds of declaration names, including normal
+ /// identifiers and C++ constructors, destructors, and conversion functions.
+ void *getFETokenInfo() const {
+ assert(getPtr() && "getFETokenInfo on an empty DeclarationName!");
+ if (getStoredNameKind() == StoredIdentifier)
+ return castAsIdentifierInfo()->getFETokenInfo();
+ return getFETokenInfoSlow();
}
- void setFETokenInfo(void *T);
+ void setFETokenInfo(void *T) {
+ assert(getPtr() && "setFETokenInfo on an empty DeclarationName!");
+ if (getStoredNameKind() == StoredIdentifier)
+ castAsIdentifierInfo()->setFETokenInfo(T);
+ else
+ setFETokenInfoSlow(T);
+ }
- /// operator== - Determine whether the specified names are identical..
+ /// Determine whether the specified names are identical.
friend bool operator==(DeclarationName LHS, DeclarationName RHS) {
return LHS.Ptr == RHS.Ptr;
}
- /// operator!= - Determine whether the specified names are different.
+ /// Determine whether the specified names are different.
friend bool operator!=(DeclarationName LHS, DeclarationName RHS) {
return LHS.Ptr != RHS.Ptr;
}
static DeclarationName getEmptyMarker() {
- return DeclarationName(uintptr_t(-1));
+ DeclarationName Name;
+ Name.Ptr = uintptr_t(-1);
+ return Name;
}
static DeclarationName getTombstoneMarker() {
- return DeclarationName(uintptr_t(-2));
+ DeclarationName Name;
+ Name.Ptr = uintptr_t(-2);
+ return Name;
}
static int compare(DeclarationName LHS, DeclarationName RHS);
@@ -343,67 +560,88 @@ inline bool operator>=(DeclarationName LHS, DeclarationName RHS) {
return DeclarationName::compare(LHS, RHS) >= 0;
}
-/// DeclarationNameTable - Used to store and retrieve DeclarationName
+/// DeclarationNameTable is used to store and retrieve DeclarationName
/// instances for the various kinds of declaration names, e.g., normal
/// identifiers, C++ constructor names, etc. This class contains
/// uniqued versions of each of the C++ special names, which can be
-/// retrieved using its member functions (e.g.,
-/// getCXXConstructorName).
+/// retrieved using its member functions (e.g., getCXXConstructorName).
class DeclarationNameTable {
+ /// Used to allocate elements in the FoldingSets below.
const ASTContext &Ctx;
- // Actually a FoldingSet<CXXSpecialName> *
- void *CXXSpecialNamesImpl;
-
- // Operator names
- CXXOperatorIdName *CXXOperatorNames;
-
- // Actually a CXXOperatorIdName*
- void *CXXLiteralOperatorNames;
-
- // FoldingSet<CXXDeductionGuideNameExtra> *
- void *CXXDeductionGuideNames;
+ /// Manage the uniqued CXXSpecialNameExtra representing C++ constructors.
+ /// getCXXConstructorName and getCXXSpecialName can be used to obtain
+ /// a DeclarationName from the corresponding type of the constructor.
+ llvm::FoldingSet<detail::CXXSpecialNameExtra> CXXConstructorNames;
+
+ /// Manage the uniqued CXXSpecialNameExtra representing C++ destructors.
+ /// getCXXDestructorName and getCXXSpecialName can be used to obtain
+ /// a DeclarationName from the corresponding type of the destructor.
+ llvm::FoldingSet<detail::CXXSpecialNameExtra> CXXDestructorNames;
+
+ /// Manage the uniqued CXXSpecialNameExtra representing C++ conversion
+ /// functions. getCXXConversionFunctionName and getCXXSpecialName can be
+ /// used to obtain a DeclarationName from the corresponding type of the
+ /// conversion function.
+ llvm::FoldingSet<detail::CXXSpecialNameExtra> CXXConversionFunctionNames;
+
+ /// Manage the uniqued CXXOperatorIdName, which contain extra information
+ /// for the name of overloaded C++ operators. getCXXOperatorName
+ /// can be used to obtain a DeclarationName from the operator kind.
+ detail::CXXOperatorIdName CXXOperatorNames[NUM_OVERLOADED_OPERATORS];
+
+ /// Manage the uniqued CXXLiteralOperatorIdName, which contain extra
+ /// information for the name of C++ literal operators.
+ /// getCXXLiteralOperatorName can be used to obtain a DeclarationName
+ /// from the corresponding IdentifierInfo.
+ llvm::FoldingSet<detail::CXXLiteralOperatorIdName> CXXLiteralOperatorNames;
+
+ /// Manage the uniqued CXXDeductionGuideNameExtra, which contain
+ /// extra information for the name of a C++ deduction guide.
+ /// getCXXDeductionGuideName can be used to obtain a DeclarationName
+ /// from the corresponding template declaration.
+ llvm::FoldingSet<detail::CXXDeductionGuideNameExtra> CXXDeductionGuideNames;
public:
DeclarationNameTable(const ASTContext &C);
DeclarationNameTable(const DeclarationNameTable &) = delete;
DeclarationNameTable &operator=(const DeclarationNameTable &) = delete;
+ DeclarationNameTable(DeclarationNameTable &&) = delete;
+ DeclarationNameTable &operator=(DeclarationNameTable &&) = delete;
+ ~DeclarationNameTable() = default;
- ~DeclarationNameTable();
-
- /// getIdentifier - Create a declaration name that is a simple
- /// identifier.
+ /// Create a declaration name that is a simple identifier.
DeclarationName getIdentifier(const IdentifierInfo *ID) {
return DeclarationName(ID);
}
- /// getCXXConstructorName - Returns the name of a C++ constructor
- /// for the given Type.
+ /// Returns the name of a C++ constructor for the given Type.
DeclarationName getCXXConstructorName(CanQualType Ty);
- /// getCXXDestructorName - Returns the name of a C++ destructor
- /// for the given Type.
+ /// Returns the name of a C++ destructor for the given Type.
DeclarationName getCXXDestructorName(CanQualType Ty);
/// Returns the name of a C++ deduction guide for the given template.
DeclarationName getCXXDeductionGuideName(TemplateDecl *TD);
- /// getCXXConversionFunctionName - Returns the name of a C++
- /// conversion function for the given Type.
+ /// Returns the name of a C++ conversion function for the given Type.
DeclarationName getCXXConversionFunctionName(CanQualType Ty);
- /// getCXXSpecialName - Returns a declaration name for special kind
- /// of C++ name, e.g., for a constructor, destructor, or conversion
- /// function.
+ /// Returns a declaration name for special kind of C++ name,
+ /// e.g., for a constructor, destructor, or conversion function.
+ /// Kind must be one of:
+ /// * DeclarationName::CXXConstructorName,
+ /// * DeclarationName::CXXDestructorName or
+ /// * DeclarationName::CXXConversionFunctionName
DeclarationName getCXXSpecialName(DeclarationName::NameKind Kind,
CanQualType Ty);
- /// getCXXOperatorName - Get the name of the overloadable C++
- /// operator corresponding to Op.
- DeclarationName getCXXOperatorName(OverloadedOperatorKind Op);
+ /// Get the name of the overloadable C++ operator corresponding to Op.
+ DeclarationName getCXXOperatorName(OverloadedOperatorKind Op) {
+ return DeclarationName(&CXXOperatorNames[Op]);
+ }
- /// getCXXLiteralOperatorName - Get the name of the literal operator function
- /// with II as the identifier.
+ /// Get the name of the literal operator function with II as the identifier.
DeclarationName getCXXLiteralOperatorName(IdentifierInfo *II);
};
@@ -491,9 +729,10 @@ public:
/// getNamedTypeInfo - Returns the source type info associated to
/// the name. Assumes it is a constructor, destructor or conversion.
TypeSourceInfo *getNamedTypeInfo() const {
- assert(Name.getNameKind() == DeclarationName::CXXConstructorName ||
- Name.getNameKind() == DeclarationName::CXXDestructorName ||
- Name.getNameKind() == DeclarationName::CXXConversionFunctionName);
+ if (Name.getNameKind() != DeclarationName::CXXConstructorName &&
+ Name.getNameKind() != DeclarationName::CXXDestructorName &&
+ Name.getNameKind() != DeclarationName::CXXConversionFunctionName)
+ return nullptr;
return LocInfo.NamedType.TInfo;
}
@@ -509,7 +748,8 @@ public:
/// getCXXOperatorNameRange - Gets the range of the operator name
/// (without the operator keyword). Assumes it is a (non-literal) operator.
SourceRange getCXXOperatorNameRange() const {
- assert(Name.getNameKind() == DeclarationName::CXXOperatorName);
+ if (Name.getNameKind() != DeclarationName::CXXOperatorName)
+ return SourceRange();
return SourceRange(
SourceLocation::getFromRawEncoding(LocInfo.CXXOperatorName.BeginOpNameLoc),
SourceLocation::getFromRawEncoding(LocInfo.CXXOperatorName.EndOpNameLoc)
@@ -528,7 +768,8 @@ public:
/// operator name (not the operator keyword).
/// Assumes it is a literal operator.
SourceLocation getCXXLiteralOperatorNameLoc() const {
- assert(Name.getNameKind() == DeclarationName::CXXLiteralOperatorName);
+ if (Name.getNameKind() != DeclarationName::CXXLiteralOperatorName)
+ return SourceLocation();
return SourceLocation::
getFromRawEncoding(LocInfo.CXXLiteralOperatorName.OpNameLoc);
}
@@ -557,22 +798,16 @@ public:
/// getBeginLoc - Retrieve the location of the first token.
SourceLocation getBeginLoc() const { return NameLoc; }
- /// getEndLoc - Retrieve the location of the last token.
- SourceLocation getEndLoc() const { return getLocEnd(); }
-
/// getSourceRange - The range of the declaration name.
SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(getLocStart(), getLocEnd());
+ return SourceRange(getBeginLoc(), getEndLoc());
}
- SourceLocation getLocStart() const LLVM_READONLY {
- return getBeginLoc();
- }
-
- SourceLocation getLocEnd() const LLVM_READONLY {
+ SourceLocation getEndLoc() const LLVM_READONLY {
SourceLocation EndLoc = getEndLocPrivate();
- return EndLoc.isValid() ? EndLoc : getLocStart();
+ return EndLoc.isValid() ? EndLoc : getBeginLoc();
}
+
private:
SourceLocation getEndLocPrivate() const;
};
diff --git a/include/clang/AST/EvaluatedExprVisitor.h b/include/clang/AST/EvaluatedExprVisitor.h
index 1aec5ae842d4..f356584144e6 100644
--- a/include/clang/AST/EvaluatedExprVisitor.h
+++ b/include/clang/AST/EvaluatedExprVisitor.h
@@ -19,6 +19,7 @@
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/StmtVisitor.h"
+#include "llvm/ADT/STLExtras.h"
namespace clang {
@@ -107,23 +108,22 @@ public:
};
/// EvaluatedExprVisitor - This class visits 'Expr *'s
-template<typename ImplClass>
+template <typename ImplClass>
class EvaluatedExprVisitor
- : public EvaluatedExprVisitorBase<make_ptr, ImplClass> {
+ : public EvaluatedExprVisitorBase<std::add_pointer, ImplClass> {
public:
- explicit EvaluatedExprVisitor(const ASTContext &Context) :
- EvaluatedExprVisitorBase<make_ptr, ImplClass>(Context) { }
+ explicit EvaluatedExprVisitor(const ASTContext &Context)
+ : EvaluatedExprVisitorBase<std::add_pointer, ImplClass>(Context) {}
};
/// ConstEvaluatedExprVisitor - This class visits 'const Expr *'s.
-template<typename ImplClass>
+template <typename ImplClass>
class ConstEvaluatedExprVisitor
- : public EvaluatedExprVisitorBase<make_const_ptr, ImplClass> {
+ : public EvaluatedExprVisitorBase<llvm::make_const_ptr, ImplClass> {
public:
- explicit ConstEvaluatedExprVisitor(const ASTContext &Context) :
- EvaluatedExprVisitorBase<make_const_ptr, ImplClass>(Context) { }
+ explicit ConstEvaluatedExprVisitor(const ASTContext &Context)
+ : EvaluatedExprVisitorBase<llvm::make_const_ptr, ImplClass>(Context) {}
};
-
}
#endif // LLVM_CLANG_AST_EVALUATEDEXPRVISITOR_H
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index c18fbf05df68..3de73428829b 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -32,6 +32,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/AtomicOrdering.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/TrailingObjects.h"
namespace clang {
class APValue;
@@ -99,10 +100,9 @@ struct SubobjectAdjustment {
}
};
-/// Expr - This represents one expression. Note that Expr's are subclasses of
-/// Stmt. This allows an expression to be transparently used any place a Stmt
-/// is required.
-///
+/// This represents one expression. Note that Expr's are subclasses of Stmt.
+/// This allows an expression to be transparently used any place a Stmt is
+/// required.
class Expr : public Stmt {
QualType TR;
@@ -583,7 +583,8 @@ public:
/// this function returns true, it returns the folded constant in Result. If
/// the expression is a glvalue, an lvalue-to-rvalue conversion will be
/// applied.
- bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx) const;
+ bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx,
+ bool InConstantContext = false) const;
/// EvaluateAsBooleanCondition - Return true if this is a constant
/// which we can fold and convert to a boolean condition using
@@ -600,7 +601,7 @@ public:
/// EvaluateAsInt - Return true if this is a constant which we can fold and
/// convert to an integer, using any crazy technique that we want to.
- bool EvaluateAsInt(llvm::APSInt &Result, const ASTContext &Ctx,
+ bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx,
SideEffectsKind AllowSideEffects = SE_NoSideEffects) const;
/// EvaluateAsFloat - Return true if this is a constant which we can fold and
@@ -632,8 +633,13 @@ public:
/// EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded
/// integer. This must be called on an expression that constant folds to an
/// integer.
- llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx,
- SmallVectorImpl<PartialDiagnosticAt> *Diag = nullptr) const;
+ llvm::APSInt EvaluateKnownConstInt(
+ const ASTContext &Ctx,
+ SmallVectorImpl<PartialDiagnosticAt> *Diag = nullptr) const;
+
+ llvm::APSInt EvaluateKnownConstIntCheckOverflow(
+ const ASTContext &Ctx,
+ SmallVectorImpl<PartialDiagnosticAt> *Diag = nullptr) const;
void EvaluateForOverflow(const ASTContext &Ctx) const;
@@ -864,6 +870,70 @@ public:
};
//===----------------------------------------------------------------------===//
+// Wrapper Expressions.
+//===----------------------------------------------------------------------===//
+
+/// FullExpr - Represents a "full-expression" node.
+class FullExpr : public Expr {
+protected:
+ Stmt *SubExpr;
+
+ FullExpr(StmtClass SC, Expr *subexpr)
+ : Expr(SC, subexpr->getType(),
+ subexpr->getValueKind(), subexpr->getObjectKind(),
+ subexpr->isTypeDependent(), subexpr->isValueDependent(),
+ subexpr->isInstantiationDependent(),
+ subexpr->containsUnexpandedParameterPack()), SubExpr(subexpr) {}
+ FullExpr(StmtClass SC, EmptyShell Empty)
+ : Expr(SC, Empty) {}
+public:
+ const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
+ Expr *getSubExpr() { return cast<Expr>(SubExpr); }
+
+ /// As with any mutator of the AST, be very careful when modifying an
+ /// existing AST to preserve its invariants.
+ void setSubExpr(Expr *E) { SubExpr = E; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() >= firstFullExprConstant &&
+ T->getStmtClass() <= lastFullExprConstant;
+ }
+};
+
+/// ConstantExpr - An expression that occurs in a constant context.
+class ConstantExpr : public FullExpr {
+ ConstantExpr(Expr *subexpr)
+ : FullExpr(ConstantExprClass, subexpr) {}
+
+public:
+ static ConstantExpr *Create(const ASTContext &Context, Expr *E) {
+ assert(!isa<ConstantExpr>(E));
+ return new (Context) ConstantExpr(E);
+ }
+
+ /// Build an empty constant expression wrapper.
+ explicit ConstantExpr(EmptyShell Empty)
+ : FullExpr(ConstantExprClass, Empty) {}
+
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return SubExpr->getBeginLoc();
+ }
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return SubExpr->getEndLoc();
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ConstantExprClass;
+ }
+
+ // Iterators
+ child_range children() { return child_range(&SubExpr, &SubExpr+1); }
+ const_child_range children() const {
+ return const_child_range(&SubExpr, &SubExpr + 1);
+ }
+};
+
+//===----------------------------------------------------------------------===//
// Primary Expressions.
//===----------------------------------------------------------------------===//
@@ -875,7 +945,6 @@ public:
class OpaqueValueExpr : public Expr {
friend class ASTStmtReader;
Expr *SourceExpr;
- SourceLocation Loc;
public:
OpaqueValueExpr(SourceLocation Loc, QualType T, ExprValueKind VK,
@@ -889,8 +958,9 @@ public:
T->isInstantiationDependentType() ||
(SourceExpr && SourceExpr->isInstantiationDependent()),
false),
- SourceExpr(SourceExpr), Loc(Loc) {
+ SourceExpr(SourceExpr) {
setIsUnique(false);
+ OpaqueValueExprBits.Loc = Loc;
}
/// Given an expression which invokes a copy constructor --- i.e. a
@@ -899,20 +969,19 @@ public:
static const OpaqueValueExpr *findInCopyConstruct(const Expr *expr);
explicit OpaqueValueExpr(EmptyShell Empty)
- : Expr(OpaqueValueExprClass, Empty) { }
+ : Expr(OpaqueValueExprClass, Empty) {}
/// Retrieve the location of this expression.
- SourceLocation getLocation() const { return Loc; }
+ SourceLocation getLocation() const { return OpaqueValueExprBits.Loc; }
- SourceLocation getLocStart() const LLVM_READONLY {
- return SourceExpr ? SourceExpr->getLocStart() : Loc;
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return SourceExpr ? SourceExpr->getBeginLoc() : getLocation();
}
- SourceLocation getLocEnd() const LLVM_READONLY {
- return SourceExpr ? SourceExpr->getLocEnd() : Loc;
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return SourceExpr ? SourceExpr->getEndLoc() : getLocation();
}
SourceLocation getExprLoc() const LLVM_READONLY {
- if (SourceExpr) return SourceExpr->getExprLoc();
- return Loc;
+ return SourceExpr ? SourceExpr->getExprLoc() : getLocation();
}
child_range children() {
@@ -974,63 +1043,52 @@ class DeclRefExpr final
private llvm::TrailingObjects<DeclRefExpr, NestedNameSpecifierLoc,
NamedDecl *, ASTTemplateKWAndArgsInfo,
TemplateArgumentLoc> {
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+ friend TrailingObjects;
+
/// The declaration that we are referencing.
ValueDecl *D;
- /// The location of the declaration name itself.
- SourceLocation Loc;
-
/// Provides source/type location info for the declaration name
/// embedded in D.
DeclarationNameLoc DNLoc;
size_t numTrailingObjects(OverloadToken<NestedNameSpecifierLoc>) const {
- return hasQualifier() ? 1 : 0;
+ return hasQualifier();
}
size_t numTrailingObjects(OverloadToken<NamedDecl *>) const {
- return hasFoundDecl() ? 1 : 0;
+ return hasFoundDecl();
}
size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
- return hasTemplateKWAndArgsInfo() ? 1 : 0;
+ return hasTemplateKWAndArgsInfo();
}
/// Test whether there is a distinct FoundDecl attached to the end of
/// this DRE.
bool hasFoundDecl() const { return DeclRefExprBits.HasFoundDecl; }
- DeclRefExpr(const ASTContext &Ctx,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- ValueDecl *D, bool RefersToEnlosingVariableOrCapture,
- const DeclarationNameInfo &NameInfo,
- NamedDecl *FoundD,
- const TemplateArgumentListInfo *TemplateArgs,
- QualType T, ExprValueKind VK);
+ DeclRefExpr(const ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc,
+ SourceLocation TemplateKWLoc, ValueDecl *D,
+ bool RefersToEnlosingVariableOrCapture,
+ const DeclarationNameInfo &NameInfo, NamedDecl *FoundD,
+ const TemplateArgumentListInfo *TemplateArgs, QualType T,
+ ExprValueKind VK);
/// Construct an empty declaration reference expression.
- explicit DeclRefExpr(EmptyShell Empty)
- : Expr(DeclRefExprClass, Empty) { }
+ explicit DeclRefExpr(EmptyShell Empty) : Expr(DeclRefExprClass, Empty) {}
/// Computes the type- and value-dependence flags for this
/// declaration reference expression.
- void computeDependence(const ASTContext &C);
+ void computeDependence(const ASTContext &Ctx);
public:
- DeclRefExpr(ValueDecl *D, bool RefersToEnclosingVariableOrCapture, QualType T,
+ DeclRefExpr(const ASTContext &Ctx, ValueDecl *D,
+ bool RefersToEnclosingVariableOrCapture, QualType T,
ExprValueKind VK, SourceLocation L,
- const DeclarationNameLoc &LocInfo = DeclarationNameLoc())
- : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false, false),
- D(D), Loc(L), DNLoc(LocInfo) {
- DeclRefExprBits.HasQualifier = 0;
- DeclRefExprBits.HasTemplateKWAndArgsInfo = 0;
- DeclRefExprBits.HasFoundDecl = 0;
- DeclRefExprBits.HadMultipleCandidates = 0;
- DeclRefExprBits.RefersToEnclosingVariableOrCapture =
- RefersToEnclosingVariableOrCapture;
- computeDependence(D->getASTContext());
- }
+ const DeclarationNameLoc &LocInfo = DeclarationNameLoc());
static DeclRefExpr *
Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc,
@@ -1048,8 +1106,7 @@ public:
const TemplateArgumentListInfo *TemplateArgs = nullptr);
/// Construct an empty declaration reference expression.
- static DeclRefExpr *CreateEmpty(const ASTContext &Context,
- bool HasQualifier,
+ static DeclRefExpr *CreateEmpty(const ASTContext &Context, bool HasQualifier,
bool HasFoundDecl,
bool HasTemplateKWAndArgsInfo,
unsigned NumTemplateArgs);
@@ -1059,13 +1116,13 @@ public:
void setDecl(ValueDecl *NewD) { D = NewD; }
DeclarationNameInfo getNameInfo() const {
- return DeclarationNameInfo(getDecl()->getDeclName(), Loc, DNLoc);
+ return DeclarationNameInfo(getDecl()->getDeclName(), getLocation(), DNLoc);
}
- SourceLocation getLocation() const { return Loc; }
- void setLocation(SourceLocation L) { Loc = L; }
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY;
+ SourceLocation getLocation() const { return DeclRefExprBits.Loc; }
+ void setLocation(SourceLocation L) { DeclRefExprBits.Loc = L; }
+ SourceLocation getBeginLoc() const LLVM_READONLY;
+ SourceLocation getEndLoc() const LLVM_READONLY;
/// Determine whether this declaration reference was preceded by a
/// C++ nested-name-specifier, e.g., \c N::foo.
@@ -1108,21 +1165,24 @@ public:
/// Retrieve the location of the template keyword preceding
/// this name, if any.
SourceLocation getTemplateKeywordLoc() const {
- if (!hasTemplateKWAndArgsInfo()) return SourceLocation();
+ if (!hasTemplateKWAndArgsInfo())
+ return SourceLocation();
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->TemplateKWLoc;
}
/// Retrieve the location of the left angle bracket starting the
/// explicit template argument list following the name, if any.
SourceLocation getLAngleLoc() const {
- if (!hasTemplateKWAndArgsInfo()) return SourceLocation();
+ if (!hasTemplateKWAndArgsInfo())
+ return SourceLocation();
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->LAngleLoc;
}
/// Retrieve the location of the right angle bracket ending the
/// explicit template argument list following the name, if any.
SourceLocation getRAngleLoc() const {
- if (!hasTemplateKWAndArgsInfo()) return SourceLocation();
+ if (!hasTemplateKWAndArgsInfo())
+ return SourceLocation();
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->RAngleLoc;
}
@@ -1147,7 +1207,6 @@ public:
const TemplateArgumentLoc *getTemplateArgs() const {
if (!hasExplicitTemplateArgs())
return nullptr;
-
return getTrailingObjects<TemplateArgumentLoc>();
}
@@ -1156,7 +1215,6 @@ public:
unsigned getNumTemplateArgs() const {
if (!hasExplicitTemplateArgs())
return 0;
-
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs;
}
@@ -1194,68 +1252,6 @@ public:
const_child_range children() const {
return const_child_range(const_child_iterator(), const_child_iterator());
}
-
- friend TrailingObjects;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-};
-
-/// [C99 6.4.2.2] - A predefined identifier such as __func__.
-class PredefinedExpr : public Expr {
-public:
- enum IdentType {
- Func,
- Function,
- LFunction, // Same as Function, but as wide string.
- FuncDName,
- FuncSig,
- LFuncSig, // Same as FuncSig, but as as wide string
- PrettyFunction,
- /// The same as PrettyFunction, except that the
- /// 'virtual' keyword is omitted for virtual member functions.
- PrettyFunctionNoVirtual
- };
-
-private:
- SourceLocation Loc;
- IdentType Type;
- Stmt *FnName;
-
-public:
- PredefinedExpr(SourceLocation L, QualType FNTy, IdentType IT,
- StringLiteral *SL);
-
- /// Construct an empty predefined expression.
- explicit PredefinedExpr(EmptyShell Empty)
- : Expr(PredefinedExprClass, Empty), Loc(), Type(Func), FnName(nullptr) {}
-
- IdentType getIdentType() const { return Type; }
-
- SourceLocation getLocation() const { return Loc; }
- void setLocation(SourceLocation L) { Loc = L; }
-
- StringLiteral *getFunctionName();
- const StringLiteral *getFunctionName() const {
- return const_cast<PredefinedExpr *>(this)->getFunctionName();
- }
-
- static StringRef getIdentTypeName(IdentType IT);
- static std::string ComputeName(IdentType IT, const Decl *CurrentDecl);
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == PredefinedExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&FnName, &FnName + 1); }
- const_child_range children() const {
- return const_child_range(&FnName, &FnName + 1);
- }
-
- friend class ASTStmtReader;
};
/// Used by IntegerLiteral/FloatingLiteral to store the numeric without
@@ -1331,8 +1327,8 @@ public:
/// Returns a new empty integer literal.
static IntegerLiteral *Create(const ASTContext &C, EmptyShell Empty);
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return Loc; }
/// Retrieve the location of the literal.
SourceLocation getLocation() const { return Loc; }
@@ -1370,8 +1366,8 @@ class FixedPointLiteral : public Expr, public APIntStorage {
QualType type, SourceLocation l,
unsigned Scale);
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return Loc; }
/// \brief Retrieve the location of the literal.
SourceLocation getLocation() const { return Loc; }
@@ -1424,8 +1420,8 @@ public:
return static_cast<CharacterKind>(CharacterLiteralBits.Kind);
}
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return Loc; }
unsigned getValue() const { return Value; }
@@ -1497,8 +1493,8 @@ public:
SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return Loc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == FloatingLiteralClass;
@@ -1534,8 +1530,10 @@ public:
Expr *getSubExpr() { return cast<Expr>(Val); }
void setSubExpr(Expr *E) { Val = E; }
- SourceLocation getLocStart() const LLVM_READONLY { return Val->getLocStart(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Val->getLocEnd(); }
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return Val->getBeginLoc();
+ }
+ SourceLocation getEndLoc() const LLVM_READONLY { return Val->getEndLoc(); }
static bool classof(const Stmt *T) {
return T->getStmtClass() == ImaginaryLiteralClass;
@@ -1549,14 +1547,15 @@ public:
};
/// StringLiteral - This represents a string literal expression, e.g. "foo"
-/// or L"bar" (wide strings). The actual string is returned by getBytes()
-/// is NOT null-terminated, and the length of the string is determined by
-/// calling getByteLength(). The C type for a string is always a
-/// ConstantArrayType. In C++, the char type is const qualified, in C it is
-/// not.
+/// or L"bar" (wide strings). The actual string data can be obtained with
+/// getBytes() and is NOT null-terminated. The length of the string data is
+/// determined by calling getByteLength().
+///
+/// The C type for a string is always a ConstantArrayType. In C++, the char
+/// type is const qualified, in C it is not.
///
/// Note that strings in C can be formed by concatenation of multiple string
-/// literal pptokens in translation phase #6. This keeps track of the locations
+/// literal pptokens in translation phase #6. This keeps track of the locations
/// of each of these pieces.
///
/// Strings in C can also be truncated and extended by assigning into arrays,
@@ -1564,131 +1563,156 @@ public:
/// char X[2] = "foobar";
/// In this case, getByteLength() will return 6, but the string literal will
/// have type "char[2]".
-class StringLiteral : public Expr {
+class StringLiteral final
+ : public Expr,
+ private llvm::TrailingObjects<StringLiteral, unsigned, SourceLocation,
+ char> {
+ friend class ASTStmtReader;
+ friend TrailingObjects;
+
+ /// StringLiteral is followed by several trailing objects. They are in order:
+ ///
+ /// * A single unsigned storing the length in characters of this string. The
+ /// length in bytes is this length times the width of a single character.
+ /// Always present and stored as a trailing objects because storing it in
+ /// StringLiteral would increase the size of StringLiteral by sizeof(void *)
+ /// due to alignment requirements. If you add some data to StringLiteral,
+ /// consider moving it inside StringLiteral.
+ ///
+ /// * An array of getNumConcatenated() SourceLocation, one for each of the
+ /// token this string is made of.
+ ///
+ /// * An array of getByteLength() char used to store the string data.
+
public:
- enum StringKind {
- Ascii,
- Wide,
- UTF8,
- UTF16,
- UTF32
- };
+ enum StringKind { Ascii, Wide, UTF8, UTF16, UTF32 };
private:
- friend class ASTStmtReader;
+ unsigned numTrailingObjects(OverloadToken<unsigned>) const { return 1; }
+ unsigned numTrailingObjects(OverloadToken<SourceLocation>) const {
+ return getNumConcatenated();
+ }
- union {
- const char *asChar;
- const uint16_t *asUInt16;
- const uint32_t *asUInt32;
- } StrData;
- unsigned Length;
- unsigned CharByteWidth : 4;
- unsigned Kind : 3;
- unsigned IsPascal : 1;
- unsigned NumConcatenated;
- SourceLocation TokLocs[1];
-
- StringLiteral(QualType Ty) :
- Expr(StringLiteralClass, Ty, VK_LValue, OK_Ordinary, false, false, false,
- false) {}
-
- static int mapCharByteWidth(TargetInfo const &target,StringKind k);
+ unsigned numTrailingObjects(OverloadToken<char>) const {
+ return getByteLength();
+ }
+
+ char *getStrDataAsChar() { return getTrailingObjects<char>(); }
+ const char *getStrDataAsChar() const { return getTrailingObjects<char>(); }
+
+ const uint16_t *getStrDataAsUInt16() const {
+ return reinterpret_cast<const uint16_t *>(getTrailingObjects<char>());
+ }
+
+ const uint32_t *getStrDataAsUInt32() const {
+ return reinterpret_cast<const uint32_t *>(getTrailingObjects<char>());
+ }
+
+ /// Build a string literal.
+ StringLiteral(const ASTContext &Ctx, StringRef Str, StringKind Kind,
+ bool Pascal, QualType Ty, const SourceLocation *Loc,
+ unsigned NumConcatenated);
+
+ /// Build an empty string literal.
+ StringLiteral(EmptyShell Empty, unsigned NumConcatenated, unsigned Length,
+ unsigned CharByteWidth);
+
+ /// Map a target and string kind to the appropriate character width.
+ static unsigned mapCharByteWidth(TargetInfo const &Target, StringKind SK);
+
+ /// Set one of the string literal token.
+ void setStrTokenLoc(unsigned TokNum, SourceLocation L) {
+ assert(TokNum < getNumConcatenated() && "Invalid tok number");
+ getTrailingObjects<SourceLocation>()[TokNum] = L;
+ }
public:
/// This is the "fully general" constructor that allows representation of
/// strings formed from multiple concatenated tokens.
- static StringLiteral *Create(const ASTContext &C, StringRef Str,
+ static StringLiteral *Create(const ASTContext &Ctx, StringRef Str,
StringKind Kind, bool Pascal, QualType Ty,
- const SourceLocation *Loc, unsigned NumStrs);
+ const SourceLocation *Loc,
+ unsigned NumConcatenated);
/// Simple constructor for string literals made from one token.
- static StringLiteral *Create(const ASTContext &C, StringRef Str,
+ static StringLiteral *Create(const ASTContext &Ctx, StringRef Str,
StringKind Kind, bool Pascal, QualType Ty,
SourceLocation Loc) {
- return Create(C, Str, Kind, Pascal, Ty, &Loc, 1);
+ return Create(Ctx, Str, Kind, Pascal, Ty, &Loc, 1);
}
/// Construct an empty string literal.
- static StringLiteral *CreateEmpty(const ASTContext &C, unsigned NumStrs);
+ static StringLiteral *CreateEmpty(const ASTContext &Ctx,
+ unsigned NumConcatenated, unsigned Length,
+ unsigned CharByteWidth);
StringRef getString() const {
- assert(CharByteWidth==1
- && "This function is used in places that assume strings use char");
- return StringRef(StrData.asChar, getByteLength());
+ assert(getCharByteWidth() == 1 &&
+ "This function is used in places that assume strings use char");
+ return StringRef(getStrDataAsChar(), getByteLength());
}
/// Allow access to clients that need the byte representation, such as
/// ASTWriterStmt::VisitStringLiteral().
StringRef getBytes() const {
// FIXME: StringRef may not be the right type to use as a result for this.
- if (CharByteWidth == 1)
- return StringRef(StrData.asChar, getByteLength());
- if (CharByteWidth == 4)
- return StringRef(reinterpret_cast<const char*>(StrData.asUInt32),
- getByteLength());
- assert(CharByteWidth == 2 && "unsupported CharByteWidth");
- return StringRef(reinterpret_cast<const char*>(StrData.asUInt16),
- getByteLength());
+ return StringRef(getStrDataAsChar(), getByteLength());
}
void outputString(raw_ostream &OS) const;
uint32_t getCodeUnit(size_t i) const {
- assert(i < Length && "out of bounds access");
- if (CharByteWidth == 1)
- return static_cast<unsigned char>(StrData.asChar[i]);
- if (CharByteWidth == 4)
- return StrData.asUInt32[i];
- assert(CharByteWidth == 2 && "unsupported CharByteWidth");
- return StrData.asUInt16[i];
+ assert(i < getLength() && "out of bounds access");
+ switch (getCharByteWidth()) {
+ case 1:
+ return static_cast<unsigned char>(getStrDataAsChar()[i]);
+ case 2:
+ return getStrDataAsUInt16()[i];
+ case 4:
+ return getStrDataAsUInt32()[i];
+ }
+ llvm_unreachable("Unsupported character width!");
}
- unsigned getByteLength() const { return CharByteWidth*Length; }
- unsigned getLength() const { return Length; }
- unsigned getCharByteWidth() const { return CharByteWidth; }
-
- /// Sets the string data to the given string data.
- void setString(const ASTContext &C, StringRef Str,
- StringKind Kind, bool IsPascal);
-
- StringKind getKind() const { return static_cast<StringKind>(Kind); }
+ unsigned getByteLength() const { return getCharByteWidth() * getLength(); }
+ unsigned getLength() const { return *getTrailingObjects<unsigned>(); }
+ unsigned getCharByteWidth() const { return StringLiteralBits.CharByteWidth; }
+ StringKind getKind() const {
+ return static_cast<StringKind>(StringLiteralBits.Kind);
+ }
- bool isAscii() const { return Kind == Ascii; }
- bool isWide() const { return Kind == Wide; }
- bool isUTF8() const { return Kind == UTF8; }
- bool isUTF16() const { return Kind == UTF16; }
- bool isUTF32() const { return Kind == UTF32; }
- bool isPascal() const { return IsPascal; }
+ bool isAscii() const { return getKind() == Ascii; }
+ bool isWide() const { return getKind() == Wide; }
+ bool isUTF8() const { return getKind() == UTF8; }
+ bool isUTF16() const { return getKind() == UTF16; }
+ bool isUTF32() const { return getKind() == UTF32; }
+ bool isPascal() const { return StringLiteralBits.IsPascal; }
bool containsNonAscii() const {
- StringRef Str = getString();
- for (unsigned i = 0, e = Str.size(); i != e; ++i)
- if (!isASCII(Str[i]))
+ for (auto c : getString())
+ if (!isASCII(c))
return true;
return false;
}
bool containsNonAsciiOrNull() const {
- StringRef Str = getString();
- for (unsigned i = 0, e = Str.size(); i != e; ++i)
- if (!isASCII(Str[i]) || !Str[i])
+ for (auto c : getString())
+ if (!isASCII(c) || !c)
return true;
return false;
}
/// getNumConcatenated - Get the number of string literal tokens that were
/// concatenated in translation phase #6 to form this string literal.
- unsigned getNumConcatenated() const { return NumConcatenated; }
+ unsigned getNumConcatenated() const {
+ return StringLiteralBits.NumConcatenated;
+ }
+ /// Get one of the string literal token.
SourceLocation getStrTokenLoc(unsigned TokNum) const {
- assert(TokNum < NumConcatenated && "Invalid tok number");
- return TokLocs[TokNum];
- }
- void setStrTokenLoc(unsigned TokNum, SourceLocation L) {
- assert(TokNum < NumConcatenated && "Invalid tok number");
- TokLocs[TokNum] = L;
+ assert(TokNum < getNumConcatenated() && "Invalid tok number");
+ return getTrailingObjects<SourceLocation>()[TokNum];
}
/// getLocationOfByte - Return a source location that points to the specified
@@ -1705,14 +1729,18 @@ public:
unsigned *StartTokenByteOffset = nullptr) const;
typedef const SourceLocation *tokloc_iterator;
- tokloc_iterator tokloc_begin() const { return TokLocs; }
- tokloc_iterator tokloc_end() const { return TokLocs + NumConcatenated; }
- SourceLocation getLocStart() const LLVM_READONLY { return TokLocs[0]; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return TokLocs[NumConcatenated - 1];
+ tokloc_iterator tokloc_begin() const {
+ return getTrailingObjects<SourceLocation>();
}
+ tokloc_iterator tokloc_end() const {
+ return getTrailingObjects<SourceLocation>() + getNumConcatenated();
+ }
+
+ SourceLocation getBeginLoc() const LLVM_READONLY { return *tokloc_begin(); }
+ SourceLocation getEndLoc() const LLVM_READONLY { return *(tokloc_end() - 1); }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == StringLiteralClass;
}
@@ -1726,6 +1754,91 @@ public:
}
};
+/// [C99 6.4.2.2] - A predefined identifier such as __func__.
+class PredefinedExpr final
+ : public Expr,
+ private llvm::TrailingObjects<PredefinedExpr, Stmt *> {
+ friend class ASTStmtReader;
+ friend TrailingObjects;
+
+ // PredefinedExpr is optionally followed by a single trailing
+ // "Stmt *" for the predefined identifier. It is present if and only if
+ // hasFunctionName() is true and is always a "StringLiteral *".
+
+public:
+ enum IdentKind {
+ Func,
+ Function,
+ LFunction, // Same as Function, but as wide string.
+ FuncDName,
+ FuncSig,
+ LFuncSig, // Same as FuncSig, but as as wide string
+ PrettyFunction,
+ /// The same as PrettyFunction, except that the
+ /// 'virtual' keyword is omitted for virtual member functions.
+ PrettyFunctionNoVirtual
+ };
+
+private:
+ PredefinedExpr(SourceLocation L, QualType FNTy, IdentKind IK,
+ StringLiteral *SL);
+
+ explicit PredefinedExpr(EmptyShell Empty, bool HasFunctionName);
+
+ /// True if this PredefinedExpr has storage for a function name.
+ bool hasFunctionName() const { return PredefinedExprBits.HasFunctionName; }
+
+ void setFunctionName(StringLiteral *SL) {
+ assert(hasFunctionName() &&
+ "This PredefinedExpr has no storage for a function name!");
+ *getTrailingObjects<Stmt *>() = SL;
+ }
+
+public:
+ /// Create a PredefinedExpr.
+ static PredefinedExpr *Create(const ASTContext &Ctx, SourceLocation L,
+ QualType FNTy, IdentKind IK, StringLiteral *SL);
+
+ /// Create an empty PredefinedExpr.
+ static PredefinedExpr *CreateEmpty(const ASTContext &Ctx,
+ bool HasFunctionName);
+
+ IdentKind getIdentKind() const {
+ return static_cast<IdentKind>(PredefinedExprBits.Kind);
+ }
+
+ SourceLocation getLocation() const { return PredefinedExprBits.Loc; }
+ void setLocation(SourceLocation L) { PredefinedExprBits.Loc = L; }
+
+ StringLiteral *getFunctionName() {
+ return hasFunctionName()
+ ? static_cast<StringLiteral *>(*getTrailingObjects<Stmt *>())
+ : nullptr;
+ }
+
+ const StringLiteral *getFunctionName() const {
+ return hasFunctionName()
+ ? static_cast<StringLiteral *>(*getTrailingObjects<Stmt *>())
+ : nullptr;
+ }
+
+ static StringRef getIdentKindName(IdentKind IK);
+ static std::string ComputeName(IdentKind IK, const Decl *CurrentDecl);
+
+ SourceLocation getBeginLoc() const { return getLocation(); }
+ SourceLocation getEndLoc() const { return getLocation(); }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == PredefinedExprClass;
+ }
+
+ // Iterators
+ child_range children() {
+ return child_range(getTrailingObjects<Stmt *>(),
+ getTrailingObjects<Stmt *>() + hasFunctionName());
+ }
+};
+
/// ParenExpr - This represents a parethesized expression, e.g. "(1)". This
/// AST node is only formed if full location information is requested.
class ParenExpr : public Expr {
@@ -1748,8 +1861,8 @@ public:
Expr *getSubExpr() { return cast<Expr>(Val); }
void setSubExpr(Expr *E) { Val = E; }
- SourceLocation getLocStart() const LLVM_READONLY { return L; }
- SourceLocation getLocEnd() const LLVM_READONLY { return R; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return L; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return R; }
/// Get the location of the left parentheses '('.
SourceLocation getLParen() const { return L; }
@@ -1781,15 +1894,11 @@ public:
/// later returns zero in the type of the operand.
///
class UnaryOperator : public Expr {
+ Stmt *Val;
+
public:
typedef UnaryOperatorKind Opcode;
-private:
- unsigned Opc : 5;
- unsigned CanOverflow : 1;
- SourceLocation Loc;
- Stmt *Val;
-public:
UnaryOperator(Expr *input, Opcode opc, QualType type, ExprValueKind VK,
ExprObjectKind OK, SourceLocation l, bool CanOverflow)
: Expr(UnaryOperatorClass, type, VK, OK,
@@ -1798,21 +1907,28 @@ public:
(input->isInstantiationDependent() ||
type->isInstantiationDependentType()),
input->containsUnexpandedParameterPack()),
- Opc(opc), CanOverflow(CanOverflow), Loc(l), Val(input) {}
+ Val(input) {
+ UnaryOperatorBits.Opc = opc;
+ UnaryOperatorBits.CanOverflow = CanOverflow;
+ UnaryOperatorBits.Loc = l;
+ }
/// Build an empty unary operator.
- explicit UnaryOperator(EmptyShell Empty)
- : Expr(UnaryOperatorClass, Empty), Opc(UO_AddrOf) { }
+ explicit UnaryOperator(EmptyShell Empty) : Expr(UnaryOperatorClass, Empty) {
+ UnaryOperatorBits.Opc = UO_AddrOf;
+ }
- Opcode getOpcode() const { return static_cast<Opcode>(Opc); }
- void setOpcode(Opcode O) { Opc = O; }
+ Opcode getOpcode() const {
+ return static_cast<Opcode>(UnaryOperatorBits.Opc);
+ }
+ void setOpcode(Opcode Opc) { UnaryOperatorBits.Opc = Opc; }
Expr *getSubExpr() const { return cast<Expr>(Val); }
void setSubExpr(Expr *E) { Val = E; }
/// getOperatorLoc - Return the location of the operator.
- SourceLocation getOperatorLoc() const { return Loc; }
- void setOperatorLoc(SourceLocation L) { Loc = L; }
+ SourceLocation getOperatorLoc() const { return UnaryOperatorBits.Loc; }
+ void setOperatorLoc(SourceLocation L) { UnaryOperatorBits.Loc = L; }
/// Returns true if the unary operator can cause an overflow. For instance,
/// signed int i = INT_MAX; i++;
@@ -1820,8 +1936,8 @@ public:
/// Due to integer promotions, c++ is promoted to an int before the postfix
/// increment, and the result is an int that cannot overflow. However, i++
/// can overflow.
- bool canOverflow() const { return CanOverflow; }
- void setCanOverflow(bool C) { CanOverflow = C; }
+ bool canOverflow() const { return UnaryOperatorBits.CanOverflow; }
+ void setCanOverflow(bool C) { UnaryOperatorBits.CanOverflow = C; }
/// isPostfix - Return true if this is a postfix operation, like x++.
static bool isPostfix(Opcode Op) {
@@ -1872,13 +1988,13 @@ public:
/// the given unary opcode.
static OverloadedOperatorKind getOverloadedOperator(Opcode Opc);
- SourceLocation getLocStart() const LLVM_READONLY {
- return isPostfix() ? Val->getLocStart() : Loc;
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return isPostfix() ? Val->getBeginLoc() : getOperatorLoc();
}
- SourceLocation getLocEnd() const LLVM_READONLY {
- return isPostfix() ? Loc : Val->getLocEnd();
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return isPostfix() ? getOperatorLoc() : Val->getEndLoc();
}
- SourceLocation getExprLoc() const LLVM_READONLY { return Loc; }
+ SourceLocation getExprLoc() const { return getOperatorLoc(); }
static bool classof(const Stmt *T) {
return T->getStmtClass() == UnaryOperatorClass;
@@ -1980,8 +2096,8 @@ public:
/// contains the location of the period (if there is one) and the
/// identifier.
SourceRange getSourceRange() const LLVM_READONLY { return Range; }
- SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
+ SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
};
/// OffsetOfExpr - [C99 7.17] - This represents an expression of the form
@@ -2080,8 +2196,8 @@ public:
return NumExprs;
}
- SourceLocation getLocStart() const LLVM_READONLY { return OperatorLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return OperatorLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == OffsetOfExprClass;
@@ -2176,8 +2292,8 @@ public:
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceLocation getLocStart() const LLVM_READONLY { return OpLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return OpLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == UnaryExprOrTypeTraitExprClass;
@@ -2194,9 +2310,11 @@ public:
/// ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
class ArraySubscriptExpr : public Expr {
- enum { LHS, RHS, END_EXPR=2 };
- Stmt* SubExprs[END_EXPR];
- SourceLocation RBracketLoc;
+ enum { LHS, RHS, END_EXPR };
+ Stmt *SubExprs[END_EXPR];
+
+ bool lhsIsBase() const { return getRHS()->getType()->isIntegerType(); }
+
public:
ArraySubscriptExpr(Expr *lhs, Expr *rhs, QualType t,
ExprValueKind VK, ExprObjectKind OK,
@@ -2207,10 +2325,10 @@ public:
(lhs->isInstantiationDependent() ||
rhs->isInstantiationDependent()),
(lhs->containsUnexpandedParameterPack() ||
- rhs->containsUnexpandedParameterPack())),
- RBracketLoc(rbracketloc) {
+ rhs->containsUnexpandedParameterPack())) {
SubExprs[LHS] = lhs;
SubExprs[RHS] = rhs;
+ ArraySubscriptExprBits.RBracketLoc = rbracketloc;
}
/// Create an empty array subscript expression.
@@ -2234,29 +2352,23 @@ public:
const Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); }
void setRHS(Expr *E) { SubExprs[RHS] = E; }
- Expr *getBase() {
- return getRHS()->getType()->isIntegerType() ? getLHS() : getRHS();
- }
+ Expr *getBase() { return lhsIsBase() ? getLHS() : getRHS(); }
+ const Expr *getBase() const { return lhsIsBase() ? getLHS() : getRHS(); }
- const Expr *getBase() const {
- return getRHS()->getType()->isIntegerType() ? getLHS() : getRHS();
- }
+ Expr *getIdx() { return lhsIsBase() ? getRHS() : getLHS(); }
+ const Expr *getIdx() const { return lhsIsBase() ? getRHS() : getLHS(); }
- Expr *getIdx() {
- return getRHS()->getType()->isIntegerType() ? getRHS() : getLHS();
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return getLHS()->getBeginLoc();
}
+ SourceLocation getEndLoc() const { return getRBracketLoc(); }
- const Expr *getIdx() const {
- return getRHS()->getType()->isIntegerType() ? getRHS() : getLHS();
+ SourceLocation getRBracketLoc() const {
+ return ArraySubscriptExprBits.RBracketLoc;
}
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return getLHS()->getLocStart();
+ void setRBracketLoc(SourceLocation L) {
+ ArraySubscriptExprBits.RBracketLoc = L;
}
- SourceLocation getLocEnd() const LLVM_READONLY { return RBracketLoc; }
-
- SourceLocation getRBracketLoc() const { return RBracketLoc; }
- void setRBracketLoc(SourceLocation L) { RBracketLoc = L; }
SourceLocation getExprLoc() const LLVM_READONLY {
return getBase()->getExprLoc();
@@ -2282,127 +2394,221 @@ public:
/// a subclass for overloaded operator calls that use operator syntax, e.g.,
/// "str1 + str2" to resolve to a function call.
class CallExpr : public Expr {
- enum { FN=0, PREARGS_START=1 };
- Stmt **SubExprs;
+ enum { FN = 0, PREARGS_START = 1 };
+
+ /// The number of arguments in the call expression.
unsigned NumArgs;
+
+ /// The location of the right parenthese. This has a different meaning for
+ /// the derived classes of CallExpr.
SourceLocation RParenLoc;
void updateDependenciesFromArg(Expr *Arg);
+ // CallExpr store some data in trailing objects. However since CallExpr
+ // is used a base of other expression classes we cannot use
+ // llvm::TrailingObjects. Instead we manually perform the pointer arithmetic
+ // and casts.
+ //
+ // The trailing objects are in order:
+ //
+ // * A single "Stmt *" for the callee expression.
+ //
+ // * An array of getNumPreArgs() "Stmt *" for the pre-argument expressions.
+ //
+ // * An array of getNumArgs() "Stmt *" for the argument expressions.
+ //
+ // Note that we store the offset in bytes from the this pointer to the start
+ // of the trailing objects. It would be perfectly possible to compute it
+ // based on the dynamic kind of the CallExpr. However 1.) we have plenty of
+ // space in the bit-fields of Stmt. 2.) It was benchmarked to be faster to
+ // compute this once and then load the offset from the bit-fields of Stmt,
+ // instead of re-computing the offset each time the trailing objects are
+ // accessed.
+
+ /// Return a pointer to the start of the trailing array of "Stmt *".
+ Stmt **getTrailingStmts() {
+ return reinterpret_cast<Stmt **>(reinterpret_cast<char *>(this) +
+ CallExprBits.OffsetToTrailingObjects);
+ }
+ Stmt *const *getTrailingStmts() const {
+ return const_cast<CallExpr *>(this)->getTrailingStmts();
+ }
+
+ /// Map a statement class to the appropriate offset in bytes from the
+ /// this pointer to the trailing objects.
+ static unsigned offsetToTrailingObjects(StmtClass SC);
+
+public:
+ enum class ADLCallKind : bool { NotADL, UsesADL };
+ static constexpr ADLCallKind NotADL = ADLCallKind::NotADL;
+ static constexpr ADLCallKind UsesADL = ADLCallKind::UsesADL;
+
protected:
- // These versions of the constructor are for derived classes.
- CallExpr(const ASTContext &C, StmtClass SC, Expr *fn,
- ArrayRef<Expr *> preargs, ArrayRef<Expr *> args, QualType t,
- ExprValueKind VK, SourceLocation rparenloc);
- CallExpr(const ASTContext &C, StmtClass SC, Expr *fn, ArrayRef<Expr *> args,
- QualType t, ExprValueKind VK, SourceLocation rparenloc);
- CallExpr(const ASTContext &C, StmtClass SC, unsigned NumPreArgs,
+ /// Build a call expression, assuming that appropriate storage has been
+ /// allocated for the trailing objects.
+ CallExpr(StmtClass SC, Expr *Fn, ArrayRef<Expr *> PreArgs,
+ ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK,
+ SourceLocation RParenLoc, unsigned MinNumArgs, ADLCallKind UsesADL);
+
+ /// Build an empty call expression, for deserialization.
+ CallExpr(StmtClass SC, unsigned NumPreArgs, unsigned NumArgs,
EmptyShell Empty);
- Stmt *getPreArg(unsigned i) {
- assert(i < getNumPreArgs() && "Prearg access out of range!");
- return SubExprs[PREARGS_START+i];
+ /// Return the size in bytes needed for the trailing objects.
+ /// Used by the derived classes to allocate the right amount of storage.
+ static unsigned sizeOfTrailingObjects(unsigned NumPreArgs, unsigned NumArgs) {
+ return (1 + NumPreArgs + NumArgs) * sizeof(Stmt *);
}
- const Stmt *getPreArg(unsigned i) const {
- assert(i < getNumPreArgs() && "Prearg access out of range!");
- return SubExprs[PREARGS_START+i];
+
+ Stmt *getPreArg(unsigned I) {
+ assert(I < getNumPreArgs() && "Prearg access out of range!");
+ return getTrailingStmts()[PREARGS_START + I];
+ }
+ const Stmt *getPreArg(unsigned I) const {
+ assert(I < getNumPreArgs() && "Prearg access out of range!");
+ return getTrailingStmts()[PREARGS_START + I];
}
- void setPreArg(unsigned i, Stmt *PreArg) {
- assert(i < getNumPreArgs() && "Prearg access out of range!");
- SubExprs[PREARGS_START+i] = PreArg;
+ void setPreArg(unsigned I, Stmt *PreArg) {
+ assert(I < getNumPreArgs() && "Prearg access out of range!");
+ getTrailingStmts()[PREARGS_START + I] = PreArg;
}
unsigned getNumPreArgs() const { return CallExprBits.NumPreArgs; }
public:
- CallExpr(const ASTContext& C, Expr *fn, ArrayRef<Expr*> args, QualType t,
- ExprValueKind VK, SourceLocation rparenloc);
+ /// Create a call expression. Fn is the callee expression, Args is the
+ /// argument array, Ty is the type of the call expression (which is *not*
+ /// the return type in general), VK is the value kind of the call expression
+ /// (lvalue, rvalue, ...), and RParenLoc is the location of the right
+ /// parenthese in the call expression. MinNumArgs specifies the minimum
+ /// number of arguments. The actual number of arguments will be the greater
+ /// of Args.size() and MinNumArgs. This is used in a few places to allocate
+ /// enough storage for the default arguments. UsesADL specifies whether the
+ /// callee was found through argument-dependent lookup.
+ ///
+ /// Note that you can use CreateTemporary if you need a temporary call
+ /// expression on the stack.
+ static CallExpr *Create(const ASTContext &Ctx, Expr *Fn,
+ ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK,
+ SourceLocation RParenLoc, unsigned MinNumArgs = 0,
+ ADLCallKind UsesADL = NotADL);
+
+ /// Create a temporary call expression with no arguments in the memory
+ /// pointed to by Mem. Mem must points to at least sizeof(CallExpr)
+ /// + sizeof(Stmt *) bytes of storage, aligned to alignof(CallExpr):
+ ///
+ /// \code{.cpp}
+ /// llvm::AlignedCharArray<alignof(CallExpr),
+ /// sizeof(CallExpr) + sizeof(Stmt *)> Buffer;
+ /// CallExpr *TheCall = CallExpr::CreateTemporary(Buffer.buffer, etc);
+ /// \endcode
+ static CallExpr *CreateTemporary(void *Mem, Expr *Fn, QualType Ty,
+ ExprValueKind VK, SourceLocation RParenLoc,
+ ADLCallKind UsesADL = NotADL);
- /// Build an empty call expression.
- CallExpr(const ASTContext &C, StmtClass SC, EmptyShell Empty);
+ /// Create an empty call expression, for deserialization.
+ static CallExpr *CreateEmpty(const ASTContext &Ctx, unsigned NumArgs,
+ EmptyShell Empty);
- const Expr *getCallee() const { return cast<Expr>(SubExprs[FN]); }
- Expr *getCallee() { return cast<Expr>(SubExprs[FN]); }
- void setCallee(Expr *F) { SubExprs[FN] = F; }
+ Expr *getCallee() { return cast<Expr>(getTrailingStmts()[FN]); }
+ const Expr *getCallee() const { return cast<Expr>(getTrailingStmts()[FN]); }
+ void setCallee(Expr *F) { getTrailingStmts()[FN] = F; }
- Decl *getCalleeDecl();
+ ADLCallKind getADLCallKind() const {
+ return static_cast<ADLCallKind>(CallExprBits.UsesADL);
+ }
+ void setADLCallKind(ADLCallKind V = UsesADL) {
+ CallExprBits.UsesADL = static_cast<bool>(V);
+ }
+ bool usesADL() const { return getADLCallKind() == UsesADL; }
+
+ Decl *getCalleeDecl() { return getCallee()->getReferencedDeclOfCallee(); }
const Decl *getCalleeDecl() const {
- return const_cast<CallExpr*>(this)->getCalleeDecl();
+ return getCallee()->getReferencedDeclOfCallee();
}
- /// If the callee is a FunctionDecl, return it. Otherwise return 0.
- FunctionDecl *getDirectCallee();
+ /// If the callee is a FunctionDecl, return it. Otherwise return null.
+ FunctionDecl *getDirectCallee() {
+ return dyn_cast_or_null<FunctionDecl>(getCalleeDecl());
+ }
const FunctionDecl *getDirectCallee() const {
- return const_cast<CallExpr*>(this)->getDirectCallee();
+ return dyn_cast_or_null<FunctionDecl>(getCalleeDecl());
}
/// getNumArgs - Return the number of actual arguments to this call.
- ///
unsigned getNumArgs() const { return NumArgs; }
/// Retrieve the call arguments.
Expr **getArgs() {
- return reinterpret_cast<Expr **>(SubExprs+getNumPreArgs()+PREARGS_START);
+ return reinterpret_cast<Expr **>(getTrailingStmts() + PREARGS_START +
+ getNumPreArgs());
}
const Expr *const *getArgs() const {
- return reinterpret_cast<Expr **>(SubExprs + getNumPreArgs() +
- PREARGS_START);
+ return reinterpret_cast<const Expr *const *>(
+ getTrailingStmts() + PREARGS_START + getNumPreArgs());
}
/// getArg - Return the specified argument.
Expr *getArg(unsigned Arg) {
- assert(Arg < NumArgs && "Arg access out of range!");
- return cast_or_null<Expr>(SubExprs[Arg + getNumPreArgs() + PREARGS_START]);
+ assert(Arg < getNumArgs() && "Arg access out of range!");
+ return getArgs()[Arg];
}
const Expr *getArg(unsigned Arg) const {
- assert(Arg < NumArgs && "Arg access out of range!");
- return cast_or_null<Expr>(SubExprs[Arg + getNumPreArgs() + PREARGS_START]);
+ assert(Arg < getNumArgs() && "Arg access out of range!");
+ return getArgs()[Arg];
}
/// setArg - Set the specified argument.
void setArg(unsigned Arg, Expr *ArgExpr) {
- assert(Arg < NumArgs && "Arg access out of range!");
- SubExprs[Arg+getNumPreArgs()+PREARGS_START] = ArgExpr;
+ assert(Arg < getNumArgs() && "Arg access out of range!");
+ getArgs()[Arg] = ArgExpr;
}
- /// setNumArgs - This changes the number of arguments present in this call.
- /// Any orphaned expressions are deleted by this, and any new operands are set
- /// to null.
- void setNumArgs(const ASTContext& C, unsigned NumArgs);
+ /// Reduce the number of arguments in this call expression. This is used for
+ /// example during error recovery to drop extra arguments. There is no way
+ /// to perform the opposite because: 1.) We don't track how much storage
+ /// we have for the argument array 2.) This would potentially require growing
+ /// the argument array, something we cannot support since the arguments are
+ /// stored in a trailing array.
+ void shrinkNumArgs(unsigned NewNumArgs) {
+ assert((NewNumArgs <= getNumArgs()) &&
+ "shrinkNumArgs cannot increase the number of arguments!");
+ NumArgs = NewNumArgs;
+ }
typedef ExprIterator arg_iterator;
typedef ConstExprIterator const_arg_iterator;
typedef llvm::iterator_range<arg_iterator> arg_range;
- typedef llvm::iterator_range<const_arg_iterator> arg_const_range;
+ typedef llvm::iterator_range<const_arg_iterator> const_arg_range;
arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
- arg_const_range arguments() const {
- return arg_const_range(arg_begin(), arg_end());
+ const_arg_range arguments() const {
+ return const_arg_range(arg_begin(), arg_end());
}
- arg_iterator arg_begin() { return SubExprs+PREARGS_START+getNumPreArgs(); }
- arg_iterator arg_end() {
- return SubExprs+PREARGS_START+getNumPreArgs()+getNumArgs();
+ arg_iterator arg_begin() {
+ return getTrailingStmts() + PREARGS_START + getNumPreArgs();
}
+ arg_iterator arg_end() { return arg_begin() + getNumArgs(); }
+
const_arg_iterator arg_begin() const {
- return SubExprs+PREARGS_START+getNumPreArgs();
- }
- const_arg_iterator arg_end() const {
- return SubExprs+PREARGS_START+getNumPreArgs()+getNumArgs();
+ return getTrailingStmts() + PREARGS_START + getNumPreArgs();
}
+ const_arg_iterator arg_end() const { return arg_begin() + getNumArgs(); }
/// This method provides fast access to all the subexpressions of
/// a CallExpr without going through the slower virtual child_iterator
/// interface. This provides efficient reverse iteration of the
/// subexpressions. This is currently used for CFG construction.
- ArrayRef<Stmt*> getRawSubExprs() {
- return llvm::makeArrayRef(SubExprs,
- getNumPreArgs() + PREARGS_START + getNumArgs());
+ ArrayRef<Stmt *> getRawSubExprs() {
+ return llvm::makeArrayRef(getTrailingStmts(),
+ PREARGS_START + getNumPreArgs() + getNumArgs());
}
/// getNumCommas - Return the number of commas that must have been present in
/// this function call.
- unsigned getNumCommas() const { return NumArgs ? NumArgs - 1 : 0; }
+ unsigned getNumCommas() const { return getNumArgs() ? getNumArgs() - 1 : 0; }
/// getBuiltinCallee - If this is a call to a builtin, return the builtin ID
/// of the callee. If not, return 0.
@@ -2417,18 +2623,27 @@ public:
/// type.
QualType getCallReturnType(const ASTContext &Ctx) const;
+ /// Returns the WarnUnusedResultAttr that is either declared on the called
+ /// function, or its return type declaration.
+ const Attr *getUnusedResultAttr(const ASTContext &Ctx) const;
+
+ /// Returns true if this call expression should warn on unused results.
+ bool hasUnusedResultAttr(const ASTContext &Ctx) const {
+ return getUnusedResultAttr(Ctx) != nullptr;
+ }
+
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY;
+ SourceLocation getBeginLoc() const LLVM_READONLY;
+ SourceLocation getEndLoc() const LLVM_READONLY;
/// Return true if this is a call to __assume() or __builtin_assume() with
/// a non-value-dependent constant parameter evaluating as false.
bool isBuiltinAssumeFalse(const ASTContext &Ctx) const;
bool isCallToStdMove() const {
- const FunctionDecl* FD = getDirectCallee();
+ const FunctionDecl *FD = getDirectCallee();
return getNumArgs() == 1 && FD && FD->isInStdNamespace() &&
FD->getIdentifier() && FD->getIdentifier()->isStr("move");
}
@@ -2440,13 +2655,14 @@ public:
// Iterators
child_range children() {
- return child_range(&SubExprs[0],
- &SubExprs[0]+NumArgs+getNumPreArgs()+PREARGS_START);
+ return child_range(getTrailingStmts(), getTrailingStmts() + PREARGS_START +
+ getNumPreArgs() + getNumArgs());
}
const_child_range children() const {
- return const_child_range(&SubExprs[0], &SubExprs[0] + NumArgs +
- getNumPreArgs() + PREARGS_START);
+ return const_child_range(getTrailingStmts(),
+ getTrailingStmts() + PREARGS_START +
+ getNumPreArgs() + getNumArgs());
}
};
@@ -2468,6 +2684,10 @@ class MemberExpr final
private llvm::TrailingObjects<MemberExpr, MemberExprNameQualifier,
ASTTemplateKWAndArgsInfo,
TemplateArgumentLoc> {
+ friend class ASTReader;
+ friend class ASTStmtWriter;
+ friend TrailingObjects;
+
/// Base - the expression for the base pointer or structure references. In
/// X.F, this is "X".
Stmt *Base;
@@ -2483,35 +2703,20 @@ class MemberExpr final
/// MemberLoc - This is the location of the member name.
SourceLocation MemberLoc;
- /// This is the location of the -> or . in the expression.
- SourceLocation OperatorLoc;
-
- /// IsArrow - True if this is "X->F", false if this is "X.F".
- bool IsArrow : 1;
-
- /// True if this member expression used a nested-name-specifier to
- /// refer to the member, e.g., "x->Base::f", or found its member via a using
- /// declaration. When true, a MemberExprNameQualifier
- /// structure is allocated immediately after the MemberExpr.
- bool HasQualifierOrFoundDecl : 1;
-
- /// True if this member expression specified a template keyword
- /// and/or a template argument list explicitly, e.g., x->f<int>,
- /// x->template f, x->template f<int>.
- /// When true, an ASTTemplateKWAndArgsInfo structure and its
- /// TemplateArguments (if any) are present.
- bool HasTemplateKWAndArgsInfo : 1;
-
- /// True if this member expression refers to a method that
- /// was resolved from an overloaded set having size greater than 1.
- bool HadMultipleCandidates : 1;
-
size_t numTrailingObjects(OverloadToken<MemberExprNameQualifier>) const {
- return HasQualifierOrFoundDecl ? 1 : 0;
+ return hasQualifierOrFoundDecl();
}
size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
- return HasTemplateKWAndArgsInfo ? 1 : 0;
+ return hasTemplateKWAndArgsInfo();
+ }
+
+ bool hasQualifierOrFoundDecl() const {
+ return MemberExprBits.HasQualifierOrFoundDecl;
+ }
+
+ bool hasTemplateKWAndArgsInfo() const {
+ return MemberExprBits.HasTemplateKWAndArgsInfo;
}
public:
@@ -2522,10 +2727,13 @@ public:
base->isValueDependent(), base->isInstantiationDependent(),
base->containsUnexpandedParameterPack()),
Base(base), MemberDecl(memberdecl), MemberDNLoc(NameInfo.getInfo()),
- MemberLoc(NameInfo.getLoc()), OperatorLoc(operatorloc),
- IsArrow(isarrow), HasQualifierOrFoundDecl(false),
- HasTemplateKWAndArgsInfo(false), HadMultipleCandidates(false) {
+ MemberLoc(NameInfo.getLoc()) {
assert(memberdecl->getDeclName() == NameInfo.getName());
+ MemberExprBits.IsArrow = isarrow;
+ MemberExprBits.HasQualifierOrFoundDecl = false;
+ MemberExprBits.HasTemplateKWAndArgsInfo = false;
+ MemberExprBits.HadMultipleCandidates = false;
+ MemberExprBits.OperatorLoc = operatorloc;
}
// NOTE: this constructor should be used only when it is known that
@@ -2538,10 +2746,13 @@ public:
: Expr(MemberExprClass, ty, VK, OK, base->isTypeDependent(),
base->isValueDependent(), base->isInstantiationDependent(),
base->containsUnexpandedParameterPack()),
- Base(base), MemberDecl(memberdecl), MemberDNLoc(), MemberLoc(l),
- OperatorLoc(operatorloc), IsArrow(isarrow),
- HasQualifierOrFoundDecl(false), HasTemplateKWAndArgsInfo(false),
- HadMultipleCandidates(false) {}
+ Base(base), MemberDecl(memberdecl), MemberDNLoc(), MemberLoc(l) {
+ MemberExprBits.IsArrow = isarrow;
+ MemberExprBits.HasQualifierOrFoundDecl = false;
+ MemberExprBits.HasTemplateKWAndArgsInfo = false;
+ MemberExprBits.HadMultipleCandidates = false;
+ MemberExprBits.OperatorLoc = operatorloc;
+ }
static MemberExpr *Create(const ASTContext &C, Expr *base, bool isarrow,
SourceLocation OperatorLoc,
@@ -2564,7 +2775,7 @@ public:
/// Retrieves the declaration found by lookup.
DeclAccessPair getFoundDecl() const {
- if (!HasQualifierOrFoundDecl)
+ if (!hasQualifierOrFoundDecl())
return DeclAccessPair::make(getMemberDecl(),
getMemberDecl()->getAccess());
return getTrailingObjects<MemberExprNameQualifier>()->FoundDecl;
@@ -2579,9 +2790,8 @@ public:
/// nested-name-specifier that precedes the member name, with source-location
/// information.
NestedNameSpecifierLoc getQualifierLoc() const {
- if (!HasQualifierOrFoundDecl)
+ if (!hasQualifierOrFoundDecl())
return NestedNameSpecifierLoc();
-
return getTrailingObjects<MemberExprNameQualifier>()->QualifierLoc;
}
@@ -2595,21 +2805,24 @@ public:
/// Retrieve the location of the template keyword preceding
/// the member name, if any.
SourceLocation getTemplateKeywordLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+ if (!hasTemplateKWAndArgsInfo())
+ return SourceLocation();
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->TemplateKWLoc;
}
/// Retrieve the location of the left angle bracket starting the
/// explicit template argument list following the member name, if any.
SourceLocation getLAngleLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+ if (!hasTemplateKWAndArgsInfo())
+ return SourceLocation();
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->LAngleLoc;
}
/// Retrieve the location of the right angle bracket ending the
/// explicit template argument list following the member name, if any.
SourceLocation getRAngleLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+ if (!hasTemplateKWAndArgsInfo())
+ return SourceLocation();
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->RAngleLoc;
}
@@ -2656,18 +2869,18 @@ public:
MemberLoc, MemberDNLoc);
}
- SourceLocation getOperatorLoc() const LLVM_READONLY { return OperatorLoc; }
+ SourceLocation getOperatorLoc() const { return MemberExprBits.OperatorLoc; }
- bool isArrow() const { return IsArrow; }
- void setArrow(bool A) { IsArrow = A; }
+ bool isArrow() const { return MemberExprBits.IsArrow; }
+ void setArrow(bool A) { MemberExprBits.IsArrow = A; }
/// getMemberLoc - Return the location of the "member", in X->F, it is the
/// location of 'F'.
SourceLocation getMemberLoc() const { return MemberLoc; }
void setMemberLoc(SourceLocation L) { MemberLoc = L; }
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY;
+ SourceLocation getBeginLoc() const LLVM_READONLY;
+ SourceLocation getEndLoc() const LLVM_READONLY;
SourceLocation getExprLoc() const LLVM_READONLY { return MemberLoc; }
@@ -2679,13 +2892,13 @@ public:
/// Returns true if this member expression refers to a method that
/// was resolved from an overloaded set having size greater than 1.
bool hadMultipleCandidates() const {
- return HadMultipleCandidates;
+ return MemberExprBits.HadMultipleCandidates;
}
/// Sets the flag telling whether this expression refers to
/// a method that was resolved from an overloaded set having size
/// greater than 1.
void setHadMultipleCandidates(bool V = true) {
- HadMultipleCandidates = V;
+ MemberExprBits.HadMultipleCandidates = V;
}
/// Returns true if virtual dispatch is performed.
@@ -2705,10 +2918,6 @@ public:
const_child_range children() const {
return const_child_range(&Base, &Base + 1);
}
-
- friend TrailingObjects;
- friend class ASTReader;
- friend class ASTStmtWriter;
};
/// CompoundLiteralExpr - [C99 6.5.2.5]
@@ -2756,19 +2965,19 @@ public:
TInfoAndScope.setPointer(tinfo);
}
- SourceLocation getLocStart() const LLVM_READONLY {
+ SourceLocation getBeginLoc() const LLVM_READONLY {
// FIXME: Init should never be null.
if (!Init)
return SourceLocation();
if (LParenLoc.isInvalid())
- return Init->getLocStart();
+ return Init->getBeginLoc();
return LParenLoc;
}
- SourceLocation getLocEnd() const LLVM_READONLY {
+ SourceLocation getEndLoc() const LLVM_READONLY {
// FIXME: Init should never be null.
if (!Init)
return SourceLocation();
- return Init->getLocEnd();
+ return Init->getEndLoc();
}
static bool classof(const Stmt *T) {
@@ -2787,28 +2996,15 @@ public:
/// representation in the source code (ExplicitCastExpr's derived
/// classes).
class CastExpr : public Expr {
-public:
- using BasePathSizeTy = unsigned int;
- static_assert(std::numeric_limits<BasePathSizeTy>::max() >= 16384,
- "[implimits] Direct and indirect base classes [16384].");
-
-private:
Stmt *Op;
bool CastConsistency() const;
- BasePathSizeTy *BasePathSize();
-
const CXXBaseSpecifier * const *path_buffer() const {
return const_cast<CastExpr*>(this)->path_buffer();
}
CXXBaseSpecifier **path_buffer();
- void setBasePathSize(BasePathSizeTy basePathSize) {
- assert(!path_empty() && basePathSize != 0);
- *(BasePathSize()) = basePathSize;
- }
-
protected:
CastExpr(StmtClass SC, QualType ty, ExprValueKind VK, const CastKind kind,
Expr *op, unsigned BasePathSize)
@@ -2829,9 +3025,9 @@ protected:
Op(op) {
CastExprBits.Kind = kind;
CastExprBits.PartOfExplicitCast = false;
- CastExprBits.BasePathIsEmpty = BasePathSize == 0;
- if (!path_empty())
- setBasePathSize(BasePathSize);
+ CastExprBits.BasePathSize = BasePathSize;
+ assert((CastExprBits.BasePathSize == BasePathSize) &&
+ "BasePathSize overflow!");
assert(CastConsistency());
}
@@ -2839,9 +3035,9 @@ protected:
CastExpr(StmtClass SC, EmptyShell Empty, unsigned BasePathSize)
: Expr(SC, Empty) {
CastExprBits.PartOfExplicitCast = false;
- CastExprBits.BasePathIsEmpty = BasePathSize == 0;
- if (!path_empty())
- setBasePathSize(BasePathSize);
+ CastExprBits.BasePathSize = BasePathSize;
+ assert((CastExprBits.BasePathSize == BasePathSize) &&
+ "BasePathSize overflow!");
}
public:
@@ -2868,13 +3064,9 @@ public:
NamedDecl *getConversionFunction() const;
typedef CXXBaseSpecifier **path_iterator;
- typedef const CXXBaseSpecifier * const *path_const_iterator;
- bool path_empty() const { return CastExprBits.BasePathIsEmpty; }
- unsigned path_size() const {
- if (path_empty())
- return 0U;
- return *(const_cast<CastExpr *>(this)->BasePathSize());
- }
+ typedef const CXXBaseSpecifier *const *path_const_iterator;
+ bool path_empty() const { return path_size() == 0; }
+ unsigned path_size() const { return CastExprBits.BasePathSize; }
path_iterator path_begin() { return path_buffer(); }
path_iterator path_end() { return path_buffer() + path_size(); }
path_const_iterator path_begin() const { return path_buffer(); }
@@ -2922,17 +3114,11 @@ public:
/// @endcode
class ImplicitCastExpr final
: public CastExpr,
- private llvm::TrailingObjects<ImplicitCastExpr, CastExpr::BasePathSizeTy,
- CXXBaseSpecifier *> {
- size_t numTrailingObjects(OverloadToken<CastExpr::BasePathSizeTy>) const {
- return path_empty() ? 0 : 1;
- }
+ private llvm::TrailingObjects<ImplicitCastExpr, CXXBaseSpecifier *> {
-private:
ImplicitCastExpr(QualType ty, CastKind kind, Expr *op,
unsigned BasePathLength, ExprValueKind VK)
- : CastExpr(ImplicitCastExprClass, ty, VK, kind, op, BasePathLength) {
- }
+ : CastExpr(ImplicitCastExprClass, ty, VK, kind, op, BasePathLength) { }
/// Construct an empty implicit cast.
explicit ImplicitCastExpr(EmptyShell Shell, unsigned PathSize)
@@ -2958,11 +3144,11 @@ public:
static ImplicitCastExpr *CreateEmpty(const ASTContext &Context,
unsigned PathSize);
- SourceLocation getLocStart() const LLVM_READONLY {
- return getSubExpr()->getLocStart();
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return getSubExpr()->getBeginLoc();
}
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getSubExpr()->getLocEnd();
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return getSubExpr()->getEndLoc();
}
static bool classof(const Stmt *T) {
@@ -2975,8 +3161,13 @@ public:
inline Expr *Expr::IgnoreImpCasts() {
Expr *e = this;
- while (ImplicitCastExpr *ice = dyn_cast<ImplicitCastExpr>(e))
- e = ice->getSubExpr();
+ while (true)
+ if (ImplicitCastExpr *ice = dyn_cast<ImplicitCastExpr>(e))
+ e = ice->getSubExpr();
+ else if (FullExpr *fe = dyn_cast<FullExpr>(e))
+ e = fe->getSubExpr();
+ else
+ break;
return e;
}
@@ -3032,8 +3223,7 @@ public:
/// (Type)expr. For example: @c (int)f.
class CStyleCastExpr final
: public ExplicitCastExpr,
- private llvm::TrailingObjects<CStyleCastExpr, CastExpr::BasePathSizeTy,
- CXXBaseSpecifier *> {
+ private llvm::TrailingObjects<CStyleCastExpr, CXXBaseSpecifier *> {
SourceLocation LPLoc; // the location of the left paren
SourceLocation RPLoc; // the location of the right paren
@@ -3047,10 +3237,6 @@ class CStyleCastExpr final
explicit CStyleCastExpr(EmptyShell Shell, unsigned PathSize)
: ExplicitCastExpr(CStyleCastExprClass, Shell, PathSize) { }
- size_t numTrailingObjects(OverloadToken<CastExpr::BasePathSizeTy>) const {
- return path_empty() ? 0 : 1;
- }
-
public:
static CStyleCastExpr *Create(const ASTContext &Context, QualType T,
ExprValueKind VK, CastKind K,
@@ -3067,9 +3253,9 @@ public:
SourceLocation getRParenLoc() const { return RPLoc; }
void setRParenLoc(SourceLocation L) { RPLoc = L; }
- SourceLocation getLocStart() const LLVM_READONLY { return LPLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getSubExpr()->getLocEnd();
+ SourceLocation getBeginLoc() const LLVM_READONLY { return LPLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return getSubExpr()->getEndLoc();
}
static bool classof(const Stmt *T) {
@@ -3099,20 +3285,11 @@ public:
/// "+" resolves to an overloaded operator, CXXOperatorCallExpr will
/// be used to express the computation.
class BinaryOperator : public Expr {
-public:
- typedef BinaryOperatorKind Opcode;
-
-private:
- unsigned Opc : 6;
-
- // This is only meaningful for operations on floating point types and 0
- // otherwise.
- unsigned FPFeatures : 2;
- SourceLocation OpLoc;
-
enum { LHS, RHS, END_EXPR };
- Stmt* SubExprs[END_EXPR];
+ Stmt *SubExprs[END_EXPR];
+
public:
+ typedef BinaryOperatorKind Opcode;
BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
ExprValueKind VK, ExprObjectKind OK,
@@ -3123,8 +3300,10 @@ public:
(lhs->isInstantiationDependent() ||
rhs->isInstantiationDependent()),
(lhs->containsUnexpandedParameterPack() ||
- rhs->containsUnexpandedParameterPack())),
- Opc(opc), FPFeatures(FPFeatures.getInt()), OpLoc(opLoc) {
+ rhs->containsUnexpandedParameterPack())) {
+ BinaryOperatorBits.Opc = opc;
+ BinaryOperatorBits.FPFeatures = FPFeatures.getInt();
+ BinaryOperatorBits.OpLoc = opLoc;
SubExprs[LHS] = lhs;
SubExprs[RHS] = rhs;
assert(!isCompoundAssignmentOp() &&
@@ -3132,26 +3311,29 @@ public:
}
/// Construct an empty binary operator.
- explicit BinaryOperator(EmptyShell Empty)
- : Expr(BinaryOperatorClass, Empty), Opc(BO_Comma) { }
+ explicit BinaryOperator(EmptyShell Empty) : Expr(BinaryOperatorClass, Empty) {
+ BinaryOperatorBits.Opc = BO_Comma;
+ }
- SourceLocation getExprLoc() const LLVM_READONLY { return OpLoc; }
- SourceLocation getOperatorLoc() const { return OpLoc; }
- void setOperatorLoc(SourceLocation L) { OpLoc = L; }
+ SourceLocation getExprLoc() const { return getOperatorLoc(); }
+ SourceLocation getOperatorLoc() const { return BinaryOperatorBits.OpLoc; }
+ void setOperatorLoc(SourceLocation L) { BinaryOperatorBits.OpLoc = L; }
- Opcode getOpcode() const { return static_cast<Opcode>(Opc); }
- void setOpcode(Opcode O) { Opc = O; }
+ Opcode getOpcode() const {
+ return static_cast<Opcode>(BinaryOperatorBits.Opc);
+ }
+ void setOpcode(Opcode Opc) { BinaryOperatorBits.Opc = Opc; }
Expr *getLHS() const { return cast<Expr>(SubExprs[LHS]); }
void setLHS(Expr *E) { SubExprs[LHS] = E; }
Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); }
void setRHS(Expr *E) { SubExprs[RHS] = E; }
- SourceLocation getLocStart() const LLVM_READONLY {
- return getLHS()->getLocStart();
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return getLHS()->getBeginLoc();
}
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getRHS()->getLocEnd();
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return getRHS()->getEndLoc();
}
/// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
@@ -3169,7 +3351,11 @@ public:
static OverloadedOperatorKind getOverloadedOperator(Opcode Opc);
/// predicates to categorize the respective opcodes.
- bool isPtrMemOp() const { return Opc == BO_PtrMemD || Opc == BO_PtrMemI; }
+ static bool isPtrMemOp(Opcode Opc) {
+ return Opc == BO_PtrMemD || Opc == BO_PtrMemI;
+ }
+ bool isPtrMemOp() const { return isPtrMemOp(getOpcode()); }
+
static bool isMultiplicativeOp(Opcode Opc) {
return Opc >= BO_Mul && Opc <= BO_Rem;
}
@@ -3268,16 +3454,24 @@ public:
// Set the FP contractability status of this operator. Only meaningful for
// operations on floating point types.
- void setFPFeatures(FPOptions F) { FPFeatures = F.getInt(); }
+ void setFPFeatures(FPOptions F) {
+ BinaryOperatorBits.FPFeatures = F.getInt();
+ }
- FPOptions getFPFeatures() const { return FPOptions(FPFeatures); }
+ FPOptions getFPFeatures() const {
+ return FPOptions(BinaryOperatorBits.FPFeatures);
+ }
// Get the FP contractability status of this operator. Only meaningful for
// operations on floating point types.
bool isFPContractableWithinStatement() const {
- return FPOptions(FPFeatures).allowFPContractWithinStatement();
+ return getFPFeatures().allowFPContractWithinStatement();
}
+ // Get the FENV_ACCESS status of this operator. Only meaningful for
+ // operations on floating point types.
+ bool isFEnvAccessOn() const { return getFPFeatures().allowFEnvAccess(); }
+
protected:
BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
ExprValueKind VK, ExprObjectKind OK,
@@ -3288,14 +3482,17 @@ protected:
(lhs->isInstantiationDependent() ||
rhs->isInstantiationDependent()),
(lhs->containsUnexpandedParameterPack() ||
- rhs->containsUnexpandedParameterPack())),
- Opc(opc), FPFeatures(FPFeatures.getInt()), OpLoc(opLoc) {
+ rhs->containsUnexpandedParameterPack())) {
+ BinaryOperatorBits.Opc = opc;
+ BinaryOperatorBits.FPFeatures = FPFeatures.getInt();
+ BinaryOperatorBits.OpLoc = opLoc;
SubExprs[LHS] = lhs;
SubExprs[RHS] = rhs;
}
- BinaryOperator(StmtClass SC, EmptyShell Empty)
- : Expr(SC, Empty), Opc(BO_MulAssign) { }
+ BinaryOperator(StmtClass SC, EmptyShell Empty) : Expr(SC, Empty) {
+ BinaryOperatorBits.Opc = BO_MulAssign;
+ }
};
/// CompoundAssignOperator - For compound assignments (e.g. +=), we keep
@@ -3430,11 +3627,11 @@ public:
Expr *getLHS() const { return cast<Expr>(SubExprs[LHS]); }
Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); }
- SourceLocation getLocStart() const LLVM_READONLY {
- return getCond()->getLocStart();
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return getCond()->getBeginLoc();
}
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getRHS()->getLocEnd();
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return getRHS()->getEndLoc();
}
static bool classof(const Stmt *T) {
@@ -3518,11 +3715,11 @@ public:
return cast<Expr>(SubExprs[RHS]);
}
- SourceLocation getLocStart() const LLVM_READONLY {
- return getCommon()->getLocStart();
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return getCommon()->getBeginLoc();
}
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getFalseExpr()->getLocEnd();
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return getFalseExpr()->getEndLoc();
}
static bool classof(const Stmt *T) {
@@ -3576,8 +3773,8 @@ public:
SourceLocation getLabelLoc() const { return LabelLoc; }
void setLabelLoc(SourceLocation L) { LabelLoc = L; }
- SourceLocation getLocStart() const LLVM_READONLY { return AmpAmpLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return LabelLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return AmpAmpLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return LabelLoc; }
LabelDecl *getLabel() const { return Label; }
void setLabel(LabelDecl *L) { Label = L; }
@@ -3621,8 +3818,8 @@ public:
const CompoundStmt *getSubStmt() const { return cast<CompoundStmt>(SubStmt); }
void setSubStmt(CompoundStmt *S) { SubStmt = S; }
- SourceLocation getLocStart() const LLVM_READONLY { return LParenLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return LParenLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
SourceLocation getLParenLoc() const { return LParenLoc; }
void setLParenLoc(SourceLocation L) { LParenLoc = L; }
@@ -3670,8 +3867,8 @@ public:
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return BuiltinLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == ShuffleVectorExprClass;
@@ -3754,8 +3951,8 @@ public:
/// getRParenLoc - Return the location of final right parenthesis.
SourceLocation getRParenLoc() const { return RParenLoc; }
- SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return BuiltinLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == ConvertVectorExprClass;
@@ -3835,8 +4032,8 @@ public:
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return BuiltinLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == ChooseExprClass;
@@ -3874,8 +4071,8 @@ public:
SourceLocation getTokenLocation() const { return TokenLoc; }
void setTokenLocation(SourceLocation L) { TokenLoc = L; }
- SourceLocation getLocStart() const LLVM_READONLY { return TokenLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return TokenLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return TokenLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return TokenLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == GNUNullExprClass;
@@ -3926,8 +4123,8 @@ public:
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return BuiltinLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == VAArgExprClass;
@@ -4160,8 +4357,8 @@ public:
InitListExprBits.HadArrayRangeDesignator = ARD;
}
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY;
+ SourceLocation getBeginLoc() const LLVM_READONLY;
+ SourceLocation getEndLoc() const LLVM_READONLY;
static bool classof(const Stmt *T) {
return T->getStmtClass() == InitListExprClass;
@@ -4395,17 +4592,17 @@ public:
return ArrayOrRange.Index;
}
- SourceLocation getLocStart() const LLVM_READONLY {
+ SourceLocation getBeginLoc() const LLVM_READONLY {
if (Kind == FieldDesignator)
return getDotLoc().isInvalid()? getFieldLoc() : getDotLoc();
else
return getLBracketLoc();
}
- SourceLocation getLocEnd() const LLVM_READONLY {
+ SourceLocation getEndLoc() const LLVM_READONLY {
return Kind == FieldDesignator ? getFieldLoc() : getRBracketLoc();
}
SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(getLocStart(), getLocEnd());
+ return SourceRange(getBeginLoc(), getEndLoc());
}
};
@@ -4484,8 +4681,8 @@ public:
SourceRange getDesignatorsSourceRange() const;
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY;
+ SourceLocation getBeginLoc() const LLVM_READONLY;
+ SourceLocation getEndLoc() const LLVM_READONLY;
static bool classof(const Stmt *T) {
return T->getStmtClass() == DesignatedInitExprClass;
@@ -4526,8 +4723,8 @@ public:
return T->getStmtClass() == NoInitExprClass;
}
- SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return SourceLocation(); }
+ SourceLocation getEndLoc() const LLVM_READONLY { return SourceLocation(); }
// Iterators
child_range children() {
@@ -4561,8 +4758,8 @@ public:
explicit DesignatedInitUpdateExpr(EmptyShell Empty)
: Expr(DesignatedInitUpdateExprClass, Empty) { }
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY;
+ SourceLocation getBeginLoc() const LLVM_READONLY;
+ SourceLocation getEndLoc() const LLVM_READONLY;
static bool classof(const Stmt *T) {
return T->getStmtClass() == DesignatedInitUpdateExprClass;
@@ -4636,11 +4833,11 @@ public:
return S->getStmtClass() == ArrayInitLoopExprClass;
}
- SourceLocation getLocStart() const LLVM_READONLY {
- return getCommonExpr()->getLocStart();
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return getCommonExpr()->getBeginLoc();
}
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getCommonExpr()->getLocEnd();
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return getCommonExpr()->getEndLoc();
}
child_range children() {
@@ -4671,8 +4868,8 @@ public:
return S->getStmtClass() == ArrayInitIndexExprClass;
}
- SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return SourceLocation(); }
+ SourceLocation getEndLoc() const LLVM_READONLY { return SourceLocation(); }
child_range children() {
return child_range(child_iterator(), child_iterator());
@@ -4707,8 +4904,8 @@ public:
return T->getStmtClass() == ImplicitValueInitExprClass;
}
- SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return SourceLocation(); }
+ SourceLocation getEndLoc() const LLVM_READONLY { return SourceLocation(); }
// Iterators
child_range children() {
@@ -4719,31 +4916,46 @@ public:
}
};
-class ParenListExpr : public Expr {
- Stmt **Exprs;
- unsigned NumExprs;
+class ParenListExpr final
+ : public Expr,
+ private llvm::TrailingObjects<ParenListExpr, Stmt *> {
+ friend class ASTStmtReader;
+ friend TrailingObjects;
+
+ /// The location of the left and right parentheses.
SourceLocation LParenLoc, RParenLoc;
-public:
- ParenListExpr(const ASTContext& C, SourceLocation lparenloc,
- ArrayRef<Expr*> exprs, SourceLocation rparenloc);
+ /// Build a paren list.
+ ParenListExpr(SourceLocation LParenLoc, ArrayRef<Expr *> Exprs,
+ SourceLocation RParenLoc);
/// Build an empty paren list.
- explicit ParenListExpr(EmptyShell Empty) : Expr(ParenListExprClass, Empty) { }
+ ParenListExpr(EmptyShell Empty, unsigned NumExprs);
+
+public:
+ /// Create a paren list.
+ static ParenListExpr *Create(const ASTContext &Ctx, SourceLocation LParenLoc,
+ ArrayRef<Expr *> Exprs,
+ SourceLocation RParenLoc);
- unsigned getNumExprs() const { return NumExprs; }
+ /// Create an empty paren list.
+ static ParenListExpr *CreateEmpty(const ASTContext &Ctx, unsigned NumExprs);
- const Expr* getExpr(unsigned Init) const {
+ /// Return the number of expressions in this paren list.
+ unsigned getNumExprs() const { return ParenListExprBits.NumExprs; }
+
+ Expr *getExpr(unsigned Init) {
assert(Init < getNumExprs() && "Initializer access out of range!");
- return cast_or_null<Expr>(Exprs[Init]);
+ return getExprs()[Init];
}
- Expr* getExpr(unsigned Init) {
- assert(Init < getNumExprs() && "Initializer access out of range!");
- return cast_or_null<Expr>(Exprs[Init]);
+ const Expr *getExpr(unsigned Init) const {
+ return const_cast<ParenListExpr *>(this)->getExpr(Init);
}
- Expr **getExprs() { return reinterpret_cast<Expr **>(Exprs); }
+ Expr **getExprs() {
+ return reinterpret_cast<Expr **>(getTrailingObjects<Stmt *>());
+ }
ArrayRef<Expr *> exprs() {
return llvm::makeArrayRef(getExprs(), getNumExprs());
@@ -4751,9 +4963,8 @@ public:
SourceLocation getLParenLoc() const { return LParenLoc; }
SourceLocation getRParenLoc() const { return RParenLoc; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return LParenLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+ SourceLocation getBeginLoc() const { return getLParenLoc(); }
+ SourceLocation getEndLoc() const { return getRParenLoc(); }
static bool classof(const Stmt *T) {
return T->getStmtClass() == ParenListExprClass;
@@ -4761,14 +4972,13 @@ public:
// Iterators
child_range children() {
- return child_range(&Exprs[0], &Exprs[0]+NumExprs);
+ return child_range(getTrailingObjects<Stmt *>(),
+ getTrailingObjects<Stmt *>() + getNumExprs());
}
const_child_range children() const {
- return const_child_range(&Exprs[0], &Exprs[0] + NumExprs);
+ return const_child_range(getTrailingObjects<Stmt *>(),
+ getTrailingObjects<Stmt *>() + getNumExprs());
}
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
};
/// Represents a C11 generic selection.
@@ -4876,8 +5086,8 @@ public:
const Expr *getResultExpr() const { return getAssocExpr(getResultIndex()); }
Expr *getResultExpr() { return getAssocExpr(getResultIndex()); }
- SourceLocation getLocStart() const LLVM_READONLY { return GenericLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return GenericLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == GenericSelectionExprClass;
@@ -4942,10 +5152,10 @@ public:
/// aggregate Constant of ConstantInt(s).
void getEncodedElementAccess(SmallVectorImpl<uint32_t> &Elts) const;
- SourceLocation getLocStart() const LLVM_READONLY {
- return getBase()->getLocStart();
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return getBase()->getBeginLoc();
}
- SourceLocation getLocEnd() const LLVM_READONLY { return AccessorLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return AccessorLoc; }
/// isArrow - Return true if the base expression is a pointer to vector,
/// return false if the base expression is a vector.
@@ -4987,8 +5197,12 @@ public:
const Stmt *getBody() const;
Stmt *getBody();
- SourceLocation getLocStart() const LLVM_READONLY { return getCaretLocation(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return getBody()->getLocEnd(); }
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return getCaretLocation();
+ }
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return getBody()->getEndLoc();
+ }
/// getFunctionType - Return the underlying function type for this block.
const FunctionProtoType *getFunctionType() const;
@@ -5040,8 +5254,8 @@ public:
/// getRParenLoc - Return the location of final right parenthesis.
SourceLocation getRParenLoc() const { return RParenLoc; }
- SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return BuiltinLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == AsTypeExprClass;
@@ -5182,11 +5396,11 @@ public:
return getSyntacticForm()->getExprLoc();
}
- SourceLocation getLocStart() const LLVM_READONLY {
- return getSyntacticForm()->getLocStart();
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return getSyntacticForm()->getBeginLoc();
}
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getSyntacticForm()->getLocEnd();
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return getSyntacticForm()->getEndLoc();
}
child_range children() {
@@ -5309,8 +5523,8 @@ public:
SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
SourceLocation getRParenLoc() const { return RParenLoc; }
- SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return BuiltinLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == AtomicExprClass;
@@ -5363,8 +5577,8 @@ public:
return const_child_range(const_child_iterator(), const_child_iterator());
}
- SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return SourceLocation(); }
+ SourceLocation getEndLoc() const LLVM_READONLY { return SourceLocation(); }
static bool classof(const Stmt *T) {
return T->getStmtClass() == TypoExprClass;
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 7ab8020dec64..6ef837a2fc40 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -75,43 +75,46 @@ class TemplateParameterList;
/// function itself will be a (possibly empty) set of functions and
/// function templates that were found by name lookup at template
/// definition time.
-class CXXOperatorCallExpr : public CallExpr {
- /// The overloaded operator.
- OverloadedOperatorKind Operator;
+class CXXOperatorCallExpr final : public CallExpr {
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
SourceRange Range;
- // Only meaningful for floating point types.
- FPOptions FPFeatures;
+ // CXXOperatorCallExpr has some trailing objects belonging
+ // to CallExpr. See CallExpr for the details.
SourceRange getSourceRangeImpl() const LLVM_READONLY;
-public:
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
+ CXXOperatorCallExpr(OverloadedOperatorKind OpKind, Expr *Fn,
+ ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK,
+ SourceLocation OperatorLoc, FPOptions FPFeatures,
+ ADLCallKind UsesADL);
- CXXOperatorCallExpr(ASTContext& C, OverloadedOperatorKind Op, Expr *fn,
- ArrayRef<Expr*> args, QualType t, ExprValueKind VK,
- SourceLocation operatorloc, FPOptions FPFeatures)
- : CallExpr(C, CXXOperatorCallExprClass, fn, args, t, VK, operatorloc),
- Operator(Op), FPFeatures(FPFeatures) {
- Range = getSourceRangeImpl();
- }
+ CXXOperatorCallExpr(unsigned NumArgs, EmptyShell Empty);
- explicit CXXOperatorCallExpr(ASTContext& C, EmptyShell Empty)
- : CallExpr(C, CXXOperatorCallExprClass, Empty) {}
+public:
+ static CXXOperatorCallExpr *
+ Create(const ASTContext &Ctx, OverloadedOperatorKind OpKind, Expr *Fn,
+ ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK,
+ SourceLocation OperatorLoc, FPOptions FPFeatures,
+ ADLCallKind UsesADL = NotADL);
- /// Returns the kind of overloaded operator that this
- /// expression refers to.
- OverloadedOperatorKind getOperator() const { return Operator; }
+ static CXXOperatorCallExpr *CreateEmpty(const ASTContext &Ctx,
+ unsigned NumArgs, EmptyShell Empty);
+
+ /// Returns the kind of overloaded operator that this expression refers to.
+ OverloadedOperatorKind getOperator() const {
+ return static_cast<OverloadedOperatorKind>(
+ CXXOperatorCallExprBits.OperatorKind);
+ }
static bool isAssignmentOp(OverloadedOperatorKind Opc) {
- return Opc == OO_Equal || Opc == OO_StarEqual ||
- Opc == OO_SlashEqual || Opc == OO_PercentEqual ||
- Opc == OO_PlusEqual || Opc == OO_MinusEqual ||
- Opc == OO_LessLessEqual || Opc == OO_GreaterGreaterEqual ||
- Opc == OO_AmpEqual || Opc == OO_CaretEqual ||
- Opc == OO_PipeEqual;
+ return Opc == OO_Equal || Opc == OO_StarEqual || Opc == OO_SlashEqual ||
+ Opc == OO_PercentEqual || Opc == OO_PlusEqual ||
+ Opc == OO_MinusEqual || Opc == OO_LessLessEqual ||
+ Opc == OO_GreaterGreaterEqual || Opc == OO_AmpEqual ||
+ Opc == OO_CaretEqual || Opc == OO_PipeEqual;
}
bool isAssignmentOp() const { return isAssignmentOp(getOperator()); }
@@ -126,14 +129,15 @@ public:
SourceLocation getOperatorLoc() const { return getRParenLoc(); }
SourceLocation getExprLoc() const LLVM_READONLY {
+ OverloadedOperatorKind Operator = getOperator();
return (Operator < OO_Plus || Operator >= OO_Arrow ||
Operator == OO_PlusPlus || Operator == OO_MinusMinus)
- ? getLocStart()
+ ? getBeginLoc()
: getOperatorLoc();
}
- SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
+ SourceLocation getBeginLoc() const { return Range.getBegin(); }
+ SourceLocation getEndLoc() const { return Range.getEnd(); }
SourceRange getSourceRange() const { return Range; }
static bool classof(const Stmt *T) {
@@ -142,14 +146,17 @@ public:
// Set the FP contractability status of this operator. Only meaningful for
// operations on floating point types.
- void setFPFeatures(FPOptions F) { FPFeatures = F; }
-
- FPOptions getFPFeatures() const { return FPFeatures; }
+ void setFPFeatures(FPOptions F) {
+ CXXOperatorCallExprBits.FPFeatures = F.getInt();
+ }
+ FPOptions getFPFeatures() const {
+ return FPOptions(CXXOperatorCallExprBits.FPFeatures);
+ }
// Get the FP contractability status of this operator. Only meaningful for
// operations on floating point types.
bool isFPContractableWithinStatement() const {
- return FPFeatures.allowFPContractWithinStatement();
+ return getFPFeatures().allowFPContractWithinStatement();
}
};
@@ -161,14 +168,23 @@ public:
/// both the object argument and the member function, while the
/// arguments are the arguments within the parentheses (not including
/// the object argument).
-class CXXMemberCallExpr : public CallExpr {
+class CXXMemberCallExpr final : public CallExpr {
+ // CXXMemberCallExpr has some trailing objects belonging
+ // to CallExpr. See CallExpr for the details.
+
+ CXXMemberCallExpr(Expr *Fn, ArrayRef<Expr *> Args, QualType Ty,
+ ExprValueKind VK, SourceLocation RP, unsigned MinNumArgs);
+
+ CXXMemberCallExpr(unsigned NumArgs, EmptyShell Empty);
+
public:
- CXXMemberCallExpr(ASTContext &C, Expr *fn, ArrayRef<Expr*> args,
- QualType t, ExprValueKind VK, SourceLocation RP)
- : CallExpr(C, CXXMemberCallExprClass, fn, args, t, VK, RP) {}
+ static CXXMemberCallExpr *Create(const ASTContext &Ctx, Expr *Fn,
+ ArrayRef<Expr *> Args, QualType Ty,
+ ExprValueKind VK, SourceLocation RP,
+ unsigned MinNumArgs = 0);
- CXXMemberCallExpr(ASTContext &C, EmptyShell Empty)
- : CallExpr(C, CXXMemberCallExprClass, Empty) {}
+ static CXXMemberCallExpr *CreateEmpty(const ASTContext &Ctx, unsigned NumArgs,
+ EmptyShell Empty);
/// Retrieves the implicit object argument for the member call.
///
@@ -191,7 +207,7 @@ public:
if (CLoc.isValid())
return CLoc;
- return getLocStart();
+ return getBeginLoc();
}
static bool classof(const Stmt *T) {
@@ -200,18 +216,26 @@ public:
};
/// Represents a call to a CUDA kernel function.
-class CUDAKernelCallExpr : public CallExpr {
-private:
+class CUDAKernelCallExpr final : public CallExpr {
enum { CONFIG, END_PREARG };
+ // CUDAKernelCallExpr has some trailing objects belonging
+ // to CallExpr. See CallExpr for the details.
+
+ CUDAKernelCallExpr(Expr *Fn, CallExpr *Config, ArrayRef<Expr *> Args,
+ QualType Ty, ExprValueKind VK, SourceLocation RP,
+ unsigned MinNumArgs);
+
+ CUDAKernelCallExpr(unsigned NumArgs, EmptyShell Empty);
+
public:
- CUDAKernelCallExpr(ASTContext &C, Expr *fn, CallExpr *Config,
- ArrayRef<Expr*> args, QualType t, ExprValueKind VK,
- SourceLocation RP)
- : CallExpr(C, CUDAKernelCallExprClass, fn, Config, args, t, VK, RP) {}
+ static CUDAKernelCallExpr *Create(const ASTContext &Ctx, Expr *Fn,
+ CallExpr *Config, ArrayRef<Expr *> Args,
+ QualType Ty, ExprValueKind VK,
+ SourceLocation RP, unsigned MinNumArgs = 0);
- CUDAKernelCallExpr(ASTContext &C, EmptyShell Empty)
- : CallExpr(C, CUDAKernelCallExprClass, END_PREARG, Empty) {}
+ static CUDAKernelCallExpr *CreateEmpty(const ASTContext &Ctx,
+ unsigned NumArgs, EmptyShell Empty);
const CallExpr *getConfig() const {
return cast_or_null<CallExpr>(getPreArg(CONFIG));
@@ -278,8 +302,8 @@ public:
/// Retrieve the location of the closing parenthesis.
SourceLocation getRParenLoc() const { return RParenLoc; }
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
SourceRange getAngleBrackets() const LLVM_READONLY { return AngleBrackets; }
static bool classof(const Stmt *T) {
@@ -301,8 +325,7 @@ public:
/// \c static_cast<int>(1.0).
class CXXStaticCastExpr final
: public CXXNamedCastExpr,
- private llvm::TrailingObjects<CXXStaticCastExpr, CastExpr::BasePathSizeTy,
- CXXBaseSpecifier *> {
+ private llvm::TrailingObjects<CXXStaticCastExpr, CXXBaseSpecifier *> {
CXXStaticCastExpr(QualType ty, ExprValueKind vk, CastKind kind, Expr *op,
unsigned pathSize, TypeSourceInfo *writtenTy,
SourceLocation l, SourceLocation RParenLoc,
@@ -313,10 +336,6 @@ class CXXStaticCastExpr final
explicit CXXStaticCastExpr(EmptyShell Empty, unsigned PathSize)
: CXXNamedCastExpr(CXXStaticCastExprClass, Empty, PathSize) {}
- size_t numTrailingObjects(OverloadToken<CastExpr::BasePathSizeTy>) const {
- return path_empty() ? 0 : 1;
- }
-
public:
friend class CastExpr;
friend TrailingObjects;
@@ -342,8 +361,7 @@ public:
/// check to determine how to perform the type conversion.
class CXXDynamicCastExpr final
: public CXXNamedCastExpr,
- private llvm::TrailingObjects<
- CXXDynamicCastExpr, CastExpr::BasePathSizeTy, CXXBaseSpecifier *> {
+ private llvm::TrailingObjects<CXXDynamicCastExpr, CXXBaseSpecifier *> {
CXXDynamicCastExpr(QualType ty, ExprValueKind VK, CastKind kind,
Expr *op, unsigned pathSize, TypeSourceInfo *writtenTy,
SourceLocation l, SourceLocation RParenLoc,
@@ -354,10 +372,6 @@ class CXXDynamicCastExpr final
explicit CXXDynamicCastExpr(EmptyShell Empty, unsigned pathSize)
: CXXNamedCastExpr(CXXDynamicCastExprClass, Empty, pathSize) {}
- size_t numTrailingObjects(OverloadToken<CastExpr::BasePathSizeTy>) const {
- return path_empty() ? 0 : 1;
- }
-
public:
friend class CastExpr;
friend TrailingObjects;
@@ -390,7 +404,6 @@ public:
class CXXReinterpretCastExpr final
: public CXXNamedCastExpr,
private llvm::TrailingObjects<CXXReinterpretCastExpr,
- CastExpr::BasePathSizeTy,
CXXBaseSpecifier *> {
CXXReinterpretCastExpr(QualType ty, ExprValueKind vk, CastKind kind,
Expr *op, unsigned pathSize,
@@ -403,10 +416,6 @@ class CXXReinterpretCastExpr final
CXXReinterpretCastExpr(EmptyShell Empty, unsigned pathSize)
: CXXNamedCastExpr(CXXReinterpretCastExprClass, Empty, pathSize) {}
- size_t numTrailingObjects(OverloadToken<CastExpr::BasePathSizeTy>) const {
- return path_empty() ? 0 : 1;
- }
-
public:
friend class CastExpr;
friend TrailingObjects;
@@ -434,8 +443,7 @@ public:
/// value.
class CXXConstCastExpr final
: public CXXNamedCastExpr,
- private llvm::TrailingObjects<CXXConstCastExpr, CastExpr::BasePathSizeTy,
- CXXBaseSpecifier *> {
+ private llvm::TrailingObjects<CXXConstCastExpr, CXXBaseSpecifier *> {
CXXConstCastExpr(QualType ty, ExprValueKind VK, Expr *op,
TypeSourceInfo *writtenTy, SourceLocation l,
SourceLocation RParenLoc, SourceRange AngleBrackets)
@@ -445,10 +453,6 @@ class CXXConstCastExpr final
explicit CXXConstCastExpr(EmptyShell Empty)
: CXXNamedCastExpr(CXXConstCastExprClass, Empty, 0) {}
- size_t numTrailingObjects(OverloadToken<CastExpr::BasePathSizeTy>) const {
- return path_empty() ? 0 : 1;
- }
-
public:
friend class CastExpr;
friend TrailingObjects;
@@ -474,22 +478,30 @@ public:
///
/// Since literal operators are never found by ADL and can only be declared at
/// namespace scope, a user-defined literal is never dependent.
-class UserDefinedLiteral : public CallExpr {
+class UserDefinedLiteral final : public CallExpr {
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+
/// The location of a ud-suffix within the literal.
SourceLocation UDSuffixLoc;
-public:
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
+ // UserDefinedLiteral has some trailing objects belonging
+ // to CallExpr. See CallExpr for the details.
- UserDefinedLiteral(const ASTContext &C, Expr *Fn, ArrayRef<Expr*> Args,
- QualType T, ExprValueKind VK, SourceLocation LitEndLoc,
- SourceLocation SuffixLoc)
- : CallExpr(C, UserDefinedLiteralClass, Fn, Args, T, VK, LitEndLoc),
- UDSuffixLoc(SuffixLoc) {}
+ UserDefinedLiteral(Expr *Fn, ArrayRef<Expr *> Args, QualType Ty,
+ ExprValueKind VK, SourceLocation LitEndLoc,
+ SourceLocation SuffixLoc);
- explicit UserDefinedLiteral(const ASTContext &C, EmptyShell Empty)
- : CallExpr(C, UserDefinedLiteralClass, Empty) {}
+ UserDefinedLiteral(unsigned NumArgs, EmptyShell Empty);
+
+public:
+ static UserDefinedLiteral *Create(const ASTContext &Ctx, Expr *Fn,
+ ArrayRef<Expr *> Args, QualType Ty,
+ ExprValueKind VK, SourceLocation LitEndLoc,
+ SourceLocation SuffixLoc);
+
+ static UserDefinedLiteral *CreateEmpty(const ASTContext &Ctx,
+ unsigned NumArgs, EmptyShell Empty);
/// The kind of literal operator which is invoked.
enum LiteralOperatorKind {
@@ -524,13 +536,13 @@ public:
return const_cast<UserDefinedLiteral*>(this)->getCookedLiteral();
}
- SourceLocation getLocStart() const {
+ SourceLocation getBeginLoc() const {
if (getLiteralOperatorKind() == LOK_Template)
return getRParenLoc();
- return getArg(0)->getLocStart();
+ return getArg(0)->getBeginLoc();
}
- SourceLocation getLocEnd() const { return getRParenLoc(); }
+ SourceLocation getEndLoc() const { return getRParenLoc(); }
/// Returns the location of a ud-suffix in the expression.
///
@@ -548,26 +560,25 @@ public:
/// A boolean literal, per ([C++ lex.bool] Boolean literals).
class CXXBoolLiteralExpr : public Expr {
- bool Value;
- SourceLocation Loc;
-
public:
- CXXBoolLiteralExpr(bool val, QualType Ty, SourceLocation l)
+ CXXBoolLiteralExpr(bool Val, QualType Ty, SourceLocation Loc)
: Expr(CXXBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
- false, false),
- Value(val), Loc(l) {}
+ false, false) {
+ CXXBoolLiteralExprBits.Value = Val;
+ CXXBoolLiteralExprBits.Loc = Loc;
+ }
explicit CXXBoolLiteralExpr(EmptyShell Empty)
: Expr(CXXBoolLiteralExprClass, Empty) {}
- bool getValue() const { return Value; }
- void setValue(bool V) { Value = V; }
+ bool getValue() const { return CXXBoolLiteralExprBits.Value; }
+ void setValue(bool V) { CXXBoolLiteralExprBits.Value = V; }
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
+ SourceLocation getBeginLoc() const { return getLocation(); }
+ SourceLocation getEndLoc() const { return getLocation(); }
- SourceLocation getLocation() const { return Loc; }
- void setLocation(SourceLocation L) { Loc = L; }
+ SourceLocation getLocation() const { return CXXBoolLiteralExprBits.Loc; }
+ void setLocation(SourceLocation L) { CXXBoolLiteralExprBits.Loc = L; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXBoolLiteralExprClass;
@@ -583,22 +594,21 @@ public:
///
/// Introduced in C++11, the only literal of type \c nullptr_t is \c nullptr.
class CXXNullPtrLiteralExpr : public Expr {
- SourceLocation Loc;
-
public:
- CXXNullPtrLiteralExpr(QualType Ty, SourceLocation l)
+ CXXNullPtrLiteralExpr(QualType Ty, SourceLocation Loc)
: Expr(CXXNullPtrLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false,
- false, false, false),
- Loc(l) {}
+ false, false, false) {
+ CXXNullPtrLiteralExprBits.Loc = Loc;
+ }
explicit CXXNullPtrLiteralExpr(EmptyShell Empty)
: Expr(CXXNullPtrLiteralExprClass, Empty) {}
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
+ SourceLocation getBeginLoc() const { return getLocation(); }
+ SourceLocation getEndLoc() const { return getLocation(); }
- SourceLocation getLocation() const { return Loc; }
- void setLocation(SourceLocation L) { Loc = L; }
+ SourceLocation getLocation() const { return CXXNullPtrLiteralExprBits.Loc; }
+ void setLocation(SourceLocation L) { CXXNullPtrLiteralExprBits.Loc = L; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXNullPtrLiteralExprClass;
@@ -631,12 +641,12 @@ public:
Expr *getSubExpr() { return static_cast<Expr*>(SubExpr); }
const Expr *getSubExpr() const { return static_cast<const Expr*>(SubExpr); }
- SourceLocation getLocStart() const LLVM_READONLY {
- return SubExpr->getLocStart();
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return SubExpr->getBeginLoc();
}
- SourceLocation getLocEnd() const LLVM_READONLY {
- return SubExpr->getLocEnd();
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return SubExpr->getEndLoc();
}
/// Retrieve the source range of the expression.
@@ -723,8 +733,8 @@ public:
Operand = E;
}
- SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
+ SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
SourceRange getSourceRange() const LLVM_READONLY { return Range; }
void setSourceRange(SourceRange R) { Range = R; }
@@ -771,23 +781,23 @@ public:
MSPropertyRefExpr(EmptyShell Empty) : Expr(MSPropertyRefExprClass, Empty) {}
SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(getLocStart(), getLocEnd());
+ return SourceRange(getBeginLoc(), getEndLoc());
}
bool isImplicitAccess() const {
return getBaseExpr() && getBaseExpr()->isImplicitCXXThis();
}
- SourceLocation getLocStart() const {
+ SourceLocation getBeginLoc() const {
if (!isImplicitAccess())
- return BaseExpr->getLocStart();
+ return BaseExpr->getBeginLoc();
else if (QualifierLoc)
return QualifierLoc.getBeginLoc();
else
return MemberLoc;
}
- SourceLocation getLocEnd() const { return getMemberLoc(); }
+ SourceLocation getEndLoc() const { return getMemberLoc(); }
child_range children() {
return child_range((Stmt**)&BaseExpr, (Stmt**)&BaseExpr + 1);
@@ -847,11 +857,11 @@ public:
Expr *getIdx() { return cast<Expr>(SubExprs[IDX_EXPR]); }
const Expr *getIdx() const { return cast<Expr>(SubExprs[IDX_EXPR]); }
- SourceLocation getLocStart() const LLVM_READONLY {
- return getBase()->getLocStart();
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return getBase()->getBeginLoc();
}
- SourceLocation getLocEnd() const LLVM_READONLY { return RBracketLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RBracketLoc; }
SourceLocation getRBracketLoc() const { return RBracketLoc; }
void setRBracketLoc(SourceLocation L) { RBracketLoc = L; }
@@ -933,8 +943,8 @@ public:
void setUuidStr(StringRef US) { UuidStr = US; }
StringRef getUuidStr() const { return UuidStr; }
- SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
+ SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
SourceRange getSourceRange() const LLVM_READONLY { return Range; }
void setSourceRange(SourceRange R) { Range = R; }
@@ -964,29 +974,28 @@ public:
/// };
/// \endcode
class CXXThisExpr : public Expr {
- SourceLocation Loc;
- bool Implicit : 1;
-
public:
- CXXThisExpr(SourceLocation L, QualType Type, bool isImplicit)
- : Expr(CXXThisExprClass, Type, VK_RValue, OK_Ordinary,
+ CXXThisExpr(SourceLocation L, QualType Ty, bool IsImplicit)
+ : Expr(CXXThisExprClass, Ty, VK_RValue, OK_Ordinary,
// 'this' is type-dependent if the class type of the enclosing
// member function is dependent (C++ [temp.dep.expr]p2)
- Type->isDependentType(), Type->isDependentType(),
- Type->isInstantiationDependentType(),
- /*ContainsUnexpandedParameterPack=*/false),
- Loc(L), Implicit(isImplicit) {}
+ Ty->isDependentType(), Ty->isDependentType(),
+ Ty->isInstantiationDependentType(),
+ /*ContainsUnexpandedParameterPack=*/false) {
+ CXXThisExprBits.IsImplicit = IsImplicit;
+ CXXThisExprBits.Loc = L;
+ }
CXXThisExpr(EmptyShell Empty) : Expr(CXXThisExprClass, Empty) {}
- SourceLocation getLocation() const { return Loc; }
- void setLocation(SourceLocation L) { Loc = L; }
+ SourceLocation getLocation() const { return CXXThisExprBits.Loc; }
+ void setLocation(SourceLocation L) { CXXThisExprBits.Loc = L; }
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
+ SourceLocation getBeginLoc() const { return getLocation(); }
+ SourceLocation getEndLoc() const { return getLocation(); }
- bool isImplicit() const { return Implicit; }
- void setImplicit(bool I) { Implicit = I; }
+ bool isImplicit() const { return CXXThisExprBits.IsImplicit; }
+ void setImplicit(bool I) { CXXThisExprBits.IsImplicit = I; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXThisExprClass;
@@ -1006,43 +1015,44 @@ public:
class CXXThrowExpr : public Expr {
friend class ASTStmtReader;
- Stmt *Op;
- SourceLocation ThrowLoc;
-
- /// Whether the thrown variable (if any) is in scope.
- unsigned IsThrownVariableInScope : 1;
+ /// The optional expression in the throw statement.
+ Stmt *Operand;
public:
// \p Ty is the void type which is used as the result type of the
- // expression. The \p l is the location of the throw keyword. \p expr
- // can by null, if the optional expression to throw isn't present.
- CXXThrowExpr(Expr *expr, QualType Ty, SourceLocation l,
+ // expression. The \p Loc is the location of the throw keyword.
+ // \p Operand is the expression in the throw statement, and can be
+ // null if not present.
+ CXXThrowExpr(Expr *Operand, QualType Ty, SourceLocation Loc,
bool IsThrownVariableInScope)
: Expr(CXXThrowExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
- expr && expr->isInstantiationDependent(),
- expr && expr->containsUnexpandedParameterPack()),
- Op(expr), ThrowLoc(l),
- IsThrownVariableInScope(IsThrownVariableInScope) {}
+ Operand && Operand->isInstantiationDependent(),
+ Operand && Operand->containsUnexpandedParameterPack()),
+ Operand(Operand) {
+ CXXThrowExprBits.ThrowLoc = Loc;
+ CXXThrowExprBits.IsThrownVariableInScope = IsThrownVariableInScope;
+ }
CXXThrowExpr(EmptyShell Empty) : Expr(CXXThrowExprClass, Empty) {}
- const Expr *getSubExpr() const { return cast_or_null<Expr>(Op); }
- Expr *getSubExpr() { return cast_or_null<Expr>(Op); }
+ const Expr *getSubExpr() const { return cast_or_null<Expr>(Operand); }
+ Expr *getSubExpr() { return cast_or_null<Expr>(Operand); }
- SourceLocation getThrowLoc() const { return ThrowLoc; }
+ SourceLocation getThrowLoc() const { return CXXThrowExprBits.ThrowLoc; }
/// Determines whether the variable thrown by this expression (if any!)
/// is within the innermost try block.
///
/// This information is required to determine whether the NRVO can apply to
/// this variable.
- bool isThrownVariableInScope() const { return IsThrownVariableInScope; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return ThrowLoc; }
+ bool isThrownVariableInScope() const {
+ return CXXThrowExprBits.IsThrownVariableInScope;
+ }
- SourceLocation getLocEnd() const LLVM_READONLY {
+ SourceLocation getBeginLoc() const { return getThrowLoc(); }
+ SourceLocation getEndLoc() const LLVM_READONLY {
if (!getSubExpr())
- return ThrowLoc;
- return getSubExpr()->getLocEnd();
+ return getThrowLoc();
+ return getSubExpr()->getEndLoc();
}
static bool classof(const Stmt *T) {
@@ -1051,7 +1061,7 @@ public:
// Iterators
child_range children() {
- return child_range(&Op, Op ? &Op+1 : &Op);
+ return child_range(&Operand, Operand ? &Operand + 1 : &Operand);
}
};
@@ -1061,26 +1071,24 @@ public:
/// corresponding parameter's default argument, when the call did not
/// explicitly supply arguments for all of the parameters.
class CXXDefaultArgExpr final : public Expr {
+ friend class ASTStmtReader;
+
/// The parameter whose default is being used.
ParmVarDecl *Param;
- /// The location where the default argument expression was used.
- SourceLocation Loc;
-
- CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *param)
+ CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *Param)
: Expr(SC,
- param->hasUnparsedDefaultArg()
- ? param->getType().getNonReferenceType()
- : param->getDefaultArg()->getType(),
- param->getDefaultArg()->getValueKind(),
- param->getDefaultArg()->getObjectKind(), false, false, false,
+ Param->hasUnparsedDefaultArg()
+ ? Param->getType().getNonReferenceType()
+ : Param->getDefaultArg()->getType(),
+ Param->getDefaultArg()->getValueKind(),
+ Param->getDefaultArg()->getObjectKind(), false, false, false,
false),
- Param(param), Loc(Loc) {}
+ Param(Param) {
+ CXXDefaultArgExprBits.Loc = Loc;
+ }
public:
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-
CXXDefaultArgExpr(EmptyShell Empty) : Expr(CXXDefaultArgExprClass, Empty) {}
// \p Param is the parameter whose default argument is used by this
@@ -1095,23 +1103,18 @@ public:
ParmVarDecl *getParam() { return Param; }
// Retrieve the actual argument to the function call.
- const Expr *getExpr() const {
- return getParam()->getDefaultArg();
- }
- Expr *getExpr() {
- return getParam()->getDefaultArg();
- }
+ const Expr *getExpr() const { return getParam()->getDefaultArg(); }
+ Expr *getExpr() { return getParam()->getDefaultArg(); }
- /// Retrieve the location where this default argument was actually
- /// used.
- SourceLocation getUsedLocation() const { return Loc; }
+ /// Retrieve the location where this default argument was actually used.
+ SourceLocation getUsedLocation() const { return CXXDefaultArgExprBits.Loc; }
/// Default argument expressions have no representation in the
/// source, so they have an empty source range.
- SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }
+ SourceLocation getBeginLoc() const { return SourceLocation(); }
+ SourceLocation getEndLoc() const { return SourceLocation(); }
- SourceLocation getExprLoc() const LLVM_READONLY { return Loc; }
+ SourceLocation getExprLoc() const { return getUsedLocation(); }
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXDefaultArgExprClass;
@@ -1132,26 +1135,23 @@ public:
/// (C++11 [class.base.init]p8) or in aggregate initialization
/// (C++1y [dcl.init.aggr]p7).
class CXXDefaultInitExpr : public Expr {
+ friend class ASTReader;
+ friend class ASTStmtReader;
+
/// The field whose default is being used.
FieldDecl *Field;
- /// The location where the default initializer expression was used.
- SourceLocation Loc;
-
- CXXDefaultInitExpr(const ASTContext &C, SourceLocation Loc, FieldDecl *Field,
- QualType T);
+ CXXDefaultInitExpr(const ASTContext &Ctx, SourceLocation Loc,
+ FieldDecl *Field, QualType Ty);
CXXDefaultInitExpr(EmptyShell Empty) : Expr(CXXDefaultInitExprClass, Empty) {}
public:
- friend class ASTReader;
- friend class ASTStmtReader;
-
/// \p Field is the non-static data member whose default initializer is used
/// by this expression.
- static CXXDefaultInitExpr *Create(const ASTContext &C, SourceLocation Loc,
+ static CXXDefaultInitExpr *Create(const ASTContext &Ctx, SourceLocation Loc,
FieldDecl *Field) {
- return new (C) CXXDefaultInitExpr(C, Loc, Field, Field->getType());
+ return new (Ctx) CXXDefaultInitExpr(Ctx, Loc, Field, Field->getType());
}
/// Get the field whose initializer will be used.
@@ -1168,8 +1168,8 @@ public:
return Field->getInClassInitializer();
}
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
+ SourceLocation getBeginLoc() const { return CXXDefaultInitExprBits.Loc; }
+ SourceLocation getEndLoc() const { return CXXDefaultInitExprBits.Loc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXDefaultInitExprClass;
@@ -1241,11 +1241,13 @@ public:
Expr *getSubExpr() { return cast<Expr>(SubExpr); }
void setSubExpr(Expr *E) { SubExpr = E; }
- SourceLocation getLocStart() const LLVM_READONLY {
- return SubExpr->getLocStart();
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return SubExpr->getBeginLoc();
}
- SourceLocation getLocEnd() const LLVM_READONLY { return SubExpr->getLocEnd();}
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return SubExpr->getEndLoc();
+ }
// Implement isa/cast/dyncast/etc.
static bool classof(const Stmt *T) {
@@ -1258,6 +1260,8 @@ public:
/// Represents a call to a C++ constructor.
class CXXConstructExpr : public Expr {
+ friend class ASTStmtReader;
+
public:
enum ConstructionKind {
CK_Complete,
@@ -1267,150 +1271,173 @@ public:
};
private:
- CXXConstructorDecl *Constructor = nullptr;
- SourceLocation Loc;
+ /// A pointer to the constructor which will be ultimately called.
+ CXXConstructorDecl *Constructor;
+
SourceRange ParenOrBraceRange;
- unsigned NumArgs : 16;
- unsigned Elidable : 1;
- unsigned HadMultipleCandidates : 1;
- unsigned ListInitialization : 1;
- unsigned StdInitListInitialization : 1;
- unsigned ZeroInitialization : 1;
- unsigned ConstructKind : 2;
- Stmt **Args = nullptr;
- void setConstructor(CXXConstructorDecl *C) { Constructor = C; }
+ /// The number of arguments.
+ unsigned NumArgs;
+
+ // We would like to stash the arguments of the constructor call after
+ // CXXConstructExpr. However CXXConstructExpr is used as a base class of
+ // CXXTemporaryObjectExpr which makes the use of llvm::TrailingObjects
+ // impossible.
+ //
+ // Instead we manually stash the trailing object after the full object
+ // containing CXXConstructExpr (that is either CXXConstructExpr or
+ // CXXTemporaryObjectExpr).
+ //
+ // The trailing objects are:
+ //
+ // * An array of getNumArgs() "Stmt *" for the arguments of the
+ // constructor call.
+
+ /// Return a pointer to the start of the trailing arguments.
+ /// Defined just after CXXTemporaryObjectExpr.
+ inline Stmt **getTrailingArgs();
+ const Stmt *const *getTrailingArgs() const {
+ return const_cast<CXXConstructExpr *>(this)->getTrailingArgs();
+ }
protected:
- CXXConstructExpr(const ASTContext &C, StmtClass SC, QualType T,
- SourceLocation Loc,
- CXXConstructorDecl *Ctor,
- bool Elidable,
- ArrayRef<Expr *> Args,
- bool HadMultipleCandidates,
- bool ListInitialization,
- bool StdInitListInitialization,
- bool ZeroInitialization,
- ConstructionKind ConstructKind,
+ /// Build a C++ construction expression.
+ CXXConstructExpr(StmtClass SC, QualType Ty, SourceLocation Loc,
+ CXXConstructorDecl *Ctor, bool Elidable,
+ ArrayRef<Expr *> Args, bool HadMultipleCandidates,
+ bool ListInitialization, bool StdInitListInitialization,
+ bool ZeroInitialization, ConstructionKind ConstructKind,
SourceRange ParenOrBraceRange);
- /// Construct an empty C++ construction expression.
- CXXConstructExpr(StmtClass SC, EmptyShell Empty)
- : Expr(SC, Empty), NumArgs(0), Elidable(false),
- HadMultipleCandidates(false), ListInitialization(false),
- ZeroInitialization(false), ConstructKind(0) {}
+ /// Build an empty C++ construction expression.
+ CXXConstructExpr(StmtClass SC, EmptyShell Empty, unsigned NumArgs);
+
+ /// Return the size in bytes of the trailing objects. Used by
+ /// CXXTemporaryObjectExpr to allocate the right amount of storage.
+ static unsigned sizeOfTrailingObjects(unsigned NumArgs) {
+ return NumArgs * sizeof(Stmt *);
+ }
public:
- friend class ASTStmtReader;
+ /// Create a C++ construction expression.
+ static CXXConstructExpr *
+ Create(const ASTContext &Ctx, QualType Ty, SourceLocation Loc,
+ CXXConstructorDecl *Ctor, bool Elidable, ArrayRef<Expr *> Args,
+ bool HadMultipleCandidates, bool ListInitialization,
+ bool StdInitListInitialization, bool ZeroInitialization,
+ ConstructionKind ConstructKind, SourceRange ParenOrBraceRange);
- /// Construct an empty C++ construction expression.
- explicit CXXConstructExpr(EmptyShell Empty)
- : CXXConstructExpr(CXXConstructExprClass, Empty) {}
-
- static CXXConstructExpr *Create(const ASTContext &C, QualType T,
- SourceLocation Loc,
- CXXConstructorDecl *Ctor,
- bool Elidable,
- ArrayRef<Expr *> Args,
- bool HadMultipleCandidates,
- bool ListInitialization,
- bool StdInitListInitialization,
- bool ZeroInitialization,
- ConstructionKind ConstructKind,
- SourceRange ParenOrBraceRange);
+ /// Create an empty C++ construction expression.
+ static CXXConstructExpr *CreateEmpty(const ASTContext &Ctx, unsigned NumArgs);
/// Get the constructor that this expression will (ultimately) call.
CXXConstructorDecl *getConstructor() const { return Constructor; }
- SourceLocation getLocation() const { return Loc; }
- void setLocation(SourceLocation Loc) { this->Loc = Loc; }
+ SourceLocation getLocation() const { return CXXConstructExprBits.Loc; }
+ void setLocation(SourceLocation Loc) { CXXConstructExprBits.Loc = Loc; }
/// Whether this construction is elidable.
- bool isElidable() const { return Elidable; }
- void setElidable(bool E) { Elidable = E; }
+ bool isElidable() const { return CXXConstructExprBits.Elidable; }
+ void setElidable(bool E) { CXXConstructExprBits.Elidable = E; }
/// Whether the referred constructor was resolved from
/// an overloaded set having size greater than 1.
- bool hadMultipleCandidates() const { return HadMultipleCandidates; }
- void setHadMultipleCandidates(bool V) { HadMultipleCandidates = V; }
+ bool hadMultipleCandidates() const {
+ return CXXConstructExprBits.HadMultipleCandidates;
+ }
+ void setHadMultipleCandidates(bool V) {
+ CXXConstructExprBits.HadMultipleCandidates = V;
+ }
/// Whether this constructor call was written as list-initialization.
- bool isListInitialization() const { return ListInitialization; }
- void setListInitialization(bool V) { ListInitialization = V; }
+ bool isListInitialization() const {
+ return CXXConstructExprBits.ListInitialization;
+ }
+ void setListInitialization(bool V) {
+ CXXConstructExprBits.ListInitialization = V;
+ }
/// Whether this constructor call was written as list-initialization,
/// but was interpreted as forming a std::initializer_list<T> from the list
/// and passing that as a single constructor argument.
/// See C++11 [over.match.list]p1 bullet 1.
- bool isStdInitListInitialization() const { return StdInitListInitialization; }
- void setStdInitListInitialization(bool V) { StdInitListInitialization = V; }
+ bool isStdInitListInitialization() const {
+ return CXXConstructExprBits.StdInitListInitialization;
+ }
+ void setStdInitListInitialization(bool V) {
+ CXXConstructExprBits.StdInitListInitialization = V;
+ }
/// Whether this construction first requires
/// zero-initialization before the initializer is called.
- bool requiresZeroInitialization() const { return ZeroInitialization; }
+ bool requiresZeroInitialization() const {
+ return CXXConstructExprBits.ZeroInitialization;
+ }
void setRequiresZeroInitialization(bool ZeroInit) {
- ZeroInitialization = ZeroInit;
+ CXXConstructExprBits.ZeroInitialization = ZeroInit;
}
/// Determine whether this constructor is actually constructing
/// a base class (rather than a complete object).
ConstructionKind getConstructionKind() const {
- return (ConstructionKind)ConstructKind;
+ return static_cast<ConstructionKind>(CXXConstructExprBits.ConstructionKind);
}
void setConstructionKind(ConstructionKind CK) {
- ConstructKind = CK;
+ CXXConstructExprBits.ConstructionKind = CK;
}
using arg_iterator = ExprIterator;
using const_arg_iterator = ConstExprIterator;
using arg_range = llvm::iterator_range<arg_iterator>;
- using arg_const_range = llvm::iterator_range<const_arg_iterator>;
+ using const_arg_range = llvm::iterator_range<const_arg_iterator>;
arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
- arg_const_range arguments() const {
- return arg_const_range(arg_begin(), arg_end());
+ const_arg_range arguments() const {
+ return const_arg_range(arg_begin(), arg_end());
}
- arg_iterator arg_begin() { return Args; }
- arg_iterator arg_end() { return Args + NumArgs; }
- const_arg_iterator arg_begin() const { return Args; }
- const_arg_iterator arg_end() const { return Args + NumArgs; }
+ arg_iterator arg_begin() { return getTrailingArgs(); }
+ arg_iterator arg_end() { return arg_begin() + getNumArgs(); }
+ const_arg_iterator arg_begin() const { return getTrailingArgs(); }
+ const_arg_iterator arg_end() const { return arg_begin() + getNumArgs(); }
- Expr **getArgs() { return reinterpret_cast<Expr **>(Args); }
+ Expr **getArgs() { return reinterpret_cast<Expr **>(getTrailingArgs()); }
const Expr *const *getArgs() const {
- return const_cast<CXXConstructExpr *>(this)->getArgs();
+ return reinterpret_cast<const Expr *const *>(getTrailingArgs());
}
+
+ /// Return the number of arguments to the constructor call.
unsigned getNumArgs() const { return NumArgs; }
/// Return the specified argument.
Expr *getArg(unsigned Arg) {
- assert(Arg < NumArgs && "Arg access out of range!");
- return cast<Expr>(Args[Arg]);
+ assert(Arg < getNumArgs() && "Arg access out of range!");
+ return getArgs()[Arg];
}
const Expr *getArg(unsigned Arg) const {
- assert(Arg < NumArgs && "Arg access out of range!");
- return cast<Expr>(Args[Arg]);
+ assert(Arg < getNumArgs() && "Arg access out of range!");
+ return getArgs()[Arg];
}
/// Set the specified argument.
void setArg(unsigned Arg, Expr *ArgExpr) {
- assert(Arg < NumArgs && "Arg access out of range!");
- Args[Arg] = ArgExpr;
+ assert(Arg < getNumArgs() && "Arg access out of range!");
+ getArgs()[Arg] = ArgExpr;
}
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY;
+ SourceLocation getBeginLoc() const LLVM_READONLY;
+ SourceLocation getEndLoc() const LLVM_READONLY;
SourceRange getParenOrBraceRange() const { return ParenOrBraceRange; }
void setParenOrBraceRange(SourceRange Range) { ParenOrBraceRange = Range; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXConstructExprClass ||
- T->getStmtClass() == CXXTemporaryObjectExprClass;
+ T->getStmtClass() == CXXTemporaryObjectExprClass;
}
// Iterators
child_range children() {
- return child_range(&Args[0], &Args[0]+NumArgs);
+ return child_range(getTrailingArgs(), getTrailingArgs() + getNumArgs());
}
};
@@ -1470,8 +1497,8 @@ public:
bool inheritedFromVBase() const { return InheritedFromVirtualBase; }
SourceLocation getLocation() const LLVM_READONLY { return Loc; }
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return Loc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXInheritedCtorInitExprClass;
@@ -1491,8 +1518,7 @@ public:
/// \endcode
class CXXFunctionalCastExpr final
: public ExplicitCastExpr,
- private llvm::TrailingObjects<
- CXXFunctionalCastExpr, CastExpr::BasePathSizeTy, CXXBaseSpecifier *> {
+ private llvm::TrailingObjects<CXXFunctionalCastExpr, CXXBaseSpecifier *> {
SourceLocation LParenLoc;
SourceLocation RParenLoc;
@@ -1507,10 +1533,6 @@ class CXXFunctionalCastExpr final
explicit CXXFunctionalCastExpr(EmptyShell Shell, unsigned PathSize)
: ExplicitCastExpr(CXXFunctionalCastExprClass, Shell, PathSize) {}
- size_t numTrailingObjects(OverloadToken<CastExpr::BasePathSizeTy>) const {
- return path_empty() ? 0 : 1;
- }
-
public:
friend class CastExpr;
friend TrailingObjects;
@@ -1533,8 +1555,8 @@ public:
/// Determine whether this expression models list-initialization.
bool isListInitialization() const { return LParenLoc.isInvalid(); }
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY;
+ SourceLocation getBeginLoc() const LLVM_READONLY;
+ SourceLocation getEndLoc() const LLVM_READONLY;
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXFunctionalCastExprClass;
@@ -1556,35 +1578,53 @@ public:
/// return X(1, 3.14f); // creates a CXXTemporaryObjectExpr
/// };
/// \endcode
-class CXXTemporaryObjectExpr : public CXXConstructExpr {
- TypeSourceInfo *Type = nullptr;
-
-public:
+class CXXTemporaryObjectExpr final : public CXXConstructExpr {
friend class ASTStmtReader;
- CXXTemporaryObjectExpr(const ASTContext &C,
- CXXConstructorDecl *Cons,
- QualType Type,
- TypeSourceInfo *TSI,
- ArrayRef<Expr *> Args,
+ // CXXTemporaryObjectExpr has some trailing objects belonging
+ // to CXXConstructExpr. See the comment inside CXXConstructExpr
+ // for more details.
+
+ TypeSourceInfo *TSI;
+
+ CXXTemporaryObjectExpr(CXXConstructorDecl *Cons, QualType Ty,
+ TypeSourceInfo *TSI, ArrayRef<Expr *> Args,
SourceRange ParenOrBraceRange,
- bool HadMultipleCandidates,
- bool ListInitialization,
+ bool HadMultipleCandidates, bool ListInitialization,
bool StdInitListInitialization,
bool ZeroInitialization);
- explicit CXXTemporaryObjectExpr(EmptyShell Empty)
- : CXXConstructExpr(CXXTemporaryObjectExprClass, Empty) {}
- TypeSourceInfo *getTypeSourceInfo() const { return Type; }
+ CXXTemporaryObjectExpr(EmptyShell Empty, unsigned NumArgs);
+
+public:
+ static CXXTemporaryObjectExpr *
+ Create(const ASTContext &Ctx, CXXConstructorDecl *Cons, QualType Ty,
+ TypeSourceInfo *TSI, ArrayRef<Expr *> Args,
+ SourceRange ParenOrBraceRange, bool HadMultipleCandidates,
+ bool ListInitialization, bool StdInitListInitialization,
+ bool ZeroInitialization);
+
+ static CXXTemporaryObjectExpr *CreateEmpty(const ASTContext &Ctx,
+ unsigned NumArgs);
+
+ TypeSourceInfo *getTypeSourceInfo() const { return TSI; }
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY;
+ SourceLocation getBeginLoc() const LLVM_READONLY;
+ SourceLocation getEndLoc() const LLVM_READONLY;
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXTemporaryObjectExprClass;
}
};
+Stmt **CXXConstructExpr::getTrailingArgs() {
+ if (auto *E = dyn_cast<CXXTemporaryObjectExpr>(this))
+ return reinterpret_cast<Stmt **>(E + 1);
+ assert((getStmtClass() == CXXConstructExprClass) &&
+ "Unexpected class deriving from CXXConstructExpr!");
+ return reinterpret_cast<Stmt **>(this + 1);
+}
+
/// A C++ lambda expression, which produces a function object
/// (of unspecified type) that can be invoked later.
///
@@ -1814,11 +1854,11 @@ public:
return T->getStmtClass() == LambdaExprClass;
}
- SourceLocation getLocStart() const LLVM_READONLY {
+ SourceLocation getBeginLoc() const LLVM_READONLY {
return IntroducerRange.getBegin();
}
- SourceLocation getLocEnd() const LLVM_READONLY { return ClosingBrace; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return ClosingBrace; }
child_range children() {
// Includes initialization exprs plus body stmt
@@ -1831,18 +1871,19 @@ public:
class CXXScalarValueInitExpr : public Expr {
friend class ASTStmtReader;
- SourceLocation RParenLoc;
TypeSourceInfo *TypeInfo;
public:
/// Create an explicitly-written scalar-value initialization
/// expression.
CXXScalarValueInitExpr(QualType Type, TypeSourceInfo *TypeInfo,
- SourceLocation rParenLoc)
- : Expr(CXXScalarValueInitExprClass, Type, VK_RValue, OK_Ordinary,
- false, false, Type->isInstantiationDependentType(),
+ SourceLocation RParenLoc)
+ : Expr(CXXScalarValueInitExprClass, Type, VK_RValue, OK_Ordinary, false,
+ false, Type->isInstantiationDependentType(),
Type->containsUnexpandedParameterPack()),
- RParenLoc(rParenLoc), TypeInfo(TypeInfo) {}
+ TypeInfo(TypeInfo) {
+ CXXScalarValueInitExprBits.RParenLoc = RParenLoc;
+ }
explicit CXXScalarValueInitExpr(EmptyShell Shell)
: Expr(CXXScalarValueInitExprClass, Shell) {}
@@ -1851,10 +1892,12 @@ public:
return TypeInfo;
}
- SourceLocation getRParenLoc() const { return RParenLoc; }
+ SourceLocation getRParenLoc() const {
+ return CXXScalarValueInitExprBits.RParenLoc;
+ }
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY;
+ SourceLocation getEndLoc() const { return getRParenLoc(); }
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXScalarValueInitExprClass;
@@ -1868,54 +1911,56 @@ public:
/// Represents a new-expression for memory allocation and constructor
/// calls, e.g: "new CXXNewExpr(foo)".
-class CXXNewExpr : public Expr {
+class CXXNewExpr final
+ : public Expr,
+ private llvm::TrailingObjects<CXXNewExpr, Stmt *, SourceRange> {
friend class ASTStmtReader;
friend class ASTStmtWriter;
-
- /// Contains an optional array size expression, an optional initialization
- /// expression, and any number of optional placement arguments, in that order.
- Stmt **SubExprs = nullptr;
+ friend TrailingObjects;
/// Points to the allocation function used.
FunctionDecl *OperatorNew;
- /// Points to the deallocation function used in case of error. May be
- /// null.
+ /// Points to the deallocation function used in case of error. May be null.
FunctionDecl *OperatorDelete;
/// The allocated type-source information, as written in the source.
TypeSourceInfo *AllocatedTypeInfo;
- /// If the allocated type was expressed as a parenthesized type-id,
- /// the source range covering the parenthesized type-id.
- SourceRange TypeIdParens;
-
/// Range of the entire new expression.
SourceRange Range;
/// Source-range of a paren-delimited initializer.
SourceRange DirectInitRange;
- /// Was the usage ::new, i.e. is the global new to be used?
- unsigned GlobalNew : 1;
-
- /// Do we allocate an array? If so, the first SubExpr is the size expression.
- unsigned Array : 1;
-
- /// Should the alignment be passed to the allocation function?
- unsigned PassAlignment : 1;
-
- /// If this is an array allocation, does the usual deallocation
- /// function for the allocated type want to know the allocated size?
- unsigned UsualArrayDeleteWantsSize : 1;
+ // CXXNewExpr is followed by several optional trailing objects.
+ // They are in order:
+ //
+ // * An optional "Stmt *" for the array size expression.
+ // Present if and ony if isArray().
+ //
+ // * An optional "Stmt *" for the init expression.
+ // Present if and only if hasInitializer().
+ //
+ // * An array of getNumPlacementArgs() "Stmt *" for the placement new
+ // arguments, if any.
+ //
+ // * An optional SourceRange for the range covering the parenthesized type-id
+ // if the allocated type was expressed as a parenthesized type-id.
+ // Present if and only if isParenTypeId().
+ unsigned arraySizeOffset() const { return 0; }
+ unsigned initExprOffset() const { return arraySizeOffset() + isArray(); }
+ unsigned placementNewArgsOffset() const {
+ return initExprOffset() + hasInitializer();
+ }
- /// The number of placement new arguments.
- unsigned NumPlacementArgs : 26;
+ unsigned numTrailingObjects(OverloadToken<Stmt *>) const {
+ return isArray() + hasInitializer() + getNumPlacementArgs();
+ }
- /// What kind of initializer do we have? Could be none, parens, or braces.
- /// In storage, we distinguish between "none, and no initializer expr", and
- /// "none, but an implicit initializer expr".
- unsigned StoredInitializationStyle : 2;
+ unsigned numTrailingObjects(OverloadToken<SourceRange>) const {
+ return isParenTypeId();
+ }
public:
enum InitializationStyle {
@@ -1929,18 +1974,35 @@ public:
ListInit
};
- CXXNewExpr(const ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
- FunctionDecl *operatorDelete, bool PassAlignment,
- bool usualArrayDeleteWantsSize, ArrayRef<Expr*> placementArgs,
- SourceRange typeIdParens, Expr *arraySize,
- InitializationStyle initializationStyle, Expr *initializer,
- QualType ty, TypeSourceInfo *AllocatedTypeInfo,
- SourceRange Range, SourceRange directInitRange);
- explicit CXXNewExpr(EmptyShell Shell)
- : Expr(CXXNewExprClass, Shell) {}
+private:
+ /// Build a c++ new expression.
+ CXXNewExpr(bool IsGlobalNew, FunctionDecl *OperatorNew,
+ FunctionDecl *OperatorDelete, bool ShouldPassAlignment,
+ bool UsualArrayDeleteWantsSize, ArrayRef<Expr *> PlacementArgs,
+ SourceRange TypeIdParens, Expr *ArraySize,
+ InitializationStyle InitializationStyle, Expr *Initializer,
+ QualType Ty, TypeSourceInfo *AllocatedTypeInfo, SourceRange Range,
+ SourceRange DirectInitRange);
+
+ /// Build an empty c++ new expression.
+ CXXNewExpr(EmptyShell Empty, bool IsArray, unsigned NumPlacementArgs,
+ bool IsParenTypeId);
- void AllocateArgsArray(const ASTContext &C, bool isArray,
- unsigned numPlaceArgs, bool hasInitializer);
+public:
+ /// Create a c++ new expression.
+ static CXXNewExpr *
+ Create(const ASTContext &Ctx, bool IsGlobalNew, FunctionDecl *OperatorNew,
+ FunctionDecl *OperatorDelete, bool ShouldPassAlignment,
+ bool UsualArrayDeleteWantsSize, ArrayRef<Expr *> PlacementArgs,
+ SourceRange TypeIdParens, Expr *ArraySize,
+ InitializationStyle InitializationStyle, Expr *Initializer,
+ QualType Ty, TypeSourceInfo *AllocatedTypeInfo, SourceRange Range,
+ SourceRange DirectInitRange);
+
+ /// Create an empty c++ new expression.
+ static CXXNewExpr *CreateEmpty(const ASTContext &Ctx, bool IsArray,
+ bool HasInit, unsigned NumPlacementArgs,
+ bool IsParenTypeId);
QualType getAllocatedType() const {
assert(getType()->isPointerType());
@@ -1966,58 +2028,74 @@ public:
/// has a non-throwing exception-specification. The '03 rule is
/// identical except that the definition of a non-throwing
/// exception specification is just "is it throw()?".
- bool shouldNullCheckAllocation(const ASTContext &Ctx) const;
+ bool shouldNullCheckAllocation() const;
FunctionDecl *getOperatorNew() const { return OperatorNew; }
void setOperatorNew(FunctionDecl *D) { OperatorNew = D; }
FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
void setOperatorDelete(FunctionDecl *D) { OperatorDelete = D; }
- bool isArray() const { return Array; }
+ bool isArray() const { return CXXNewExprBits.IsArray; }
Expr *getArraySize() {
- return Array ? cast<Expr>(SubExprs[0]) : nullptr;
+ return isArray()
+ ? cast<Expr>(getTrailingObjects<Stmt *>()[arraySizeOffset()])
+ : nullptr;
}
const Expr *getArraySize() const {
- return Array ? cast<Expr>(SubExprs[0]) : nullptr;
+ return isArray()
+ ? cast<Expr>(getTrailingObjects<Stmt *>()[arraySizeOffset()])
+ : nullptr;
}
- unsigned getNumPlacementArgs() const { return NumPlacementArgs; }
+ unsigned getNumPlacementArgs() const {
+ return CXXNewExprBits.NumPlacementArgs;
+ }
Expr **getPlacementArgs() {
- return reinterpret_cast<Expr **>(SubExprs + Array + hasInitializer());
+ return reinterpret_cast<Expr **>(getTrailingObjects<Stmt *>() +
+ placementNewArgsOffset());
}
- Expr *getPlacementArg(unsigned i) {
- assert(i < NumPlacementArgs && "Index out of range");
- return getPlacementArgs()[i];
+ Expr *getPlacementArg(unsigned I) {
+ assert((I < getNumPlacementArgs()) && "Index out of range!");
+ return getPlacementArgs()[I];
}
- const Expr *getPlacementArg(unsigned i) const {
- assert(i < NumPlacementArgs && "Index out of range");
- return const_cast<CXXNewExpr*>(this)->getPlacementArg(i);
+ const Expr *getPlacementArg(unsigned I) const {
+ return const_cast<CXXNewExpr *>(this)->getPlacementArg(I);
}
- bool isParenTypeId() const { return TypeIdParens.isValid(); }
- SourceRange getTypeIdParens() const { return TypeIdParens; }
+ bool isParenTypeId() const { return CXXNewExprBits.IsParenTypeId; }
+ SourceRange getTypeIdParens() const {
+ return isParenTypeId() ? getTrailingObjects<SourceRange>()[0]
+ : SourceRange();
+ }
- bool isGlobalNew() const { return GlobalNew; }
+ bool isGlobalNew() const { return CXXNewExprBits.IsGlobalNew; }
/// Whether this new-expression has any initializer at all.
- bool hasInitializer() const { return StoredInitializationStyle > 0; }
+ bool hasInitializer() const {
+ return CXXNewExprBits.StoredInitializationStyle > 0;
+ }
/// The kind of initializer this new-expression has.
InitializationStyle getInitializationStyle() const {
- if (StoredInitializationStyle == 0)
+ if (CXXNewExprBits.StoredInitializationStyle == 0)
return NoInit;
- return static_cast<InitializationStyle>(StoredInitializationStyle-1);
+ return static_cast<InitializationStyle>(
+ CXXNewExprBits.StoredInitializationStyle - 1);
}
/// The initializer of this new-expression.
Expr *getInitializer() {
- return hasInitializer() ? cast<Expr>(SubExprs[Array]) : nullptr;
+ return hasInitializer()
+ ? cast<Expr>(getTrailingObjects<Stmt *>()[initExprOffset()])
+ : nullptr;
}
const Expr *getInitializer() const {
- return hasInitializer() ? cast<Expr>(SubExprs[Array]) : nullptr;
+ return hasInitializer()
+ ? cast<Expr>(getTrailingObjects<Stmt *>()[initExprOffset()])
+ : nullptr;
}
/// Returns the CXXConstructExpr from this new-expression, or null.
@@ -2027,15 +2105,13 @@ public:
/// Indicates whether the required alignment should be implicitly passed to
/// the allocation function.
- bool passAlignment() const {
- return PassAlignment;
- }
+ bool passAlignment() const { return CXXNewExprBits.ShouldPassAlignment; }
/// Answers whether the usual array deallocation function for the
/// allocated type expects the size of the allocation as a
/// parameter.
bool doesUsualArrayDeleteWantSize() const {
- return UsualArrayDeleteWantsSize;
+ return CXXNewExprBits.UsualArrayDeleteWantsSize;
}
using arg_iterator = ExprIterator;
@@ -2050,103 +2126,85 @@ public:
}
arg_iterator placement_arg_begin() {
- return SubExprs + Array + hasInitializer();
+ return getTrailingObjects<Stmt *>() + placementNewArgsOffset();
}
arg_iterator placement_arg_end() {
- return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
+ return placement_arg_begin() + getNumPlacementArgs();
}
const_arg_iterator placement_arg_begin() const {
- return SubExprs + Array + hasInitializer();
+ return getTrailingObjects<Stmt *>() + placementNewArgsOffset();
}
const_arg_iterator placement_arg_end() const {
- return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
+ return placement_arg_begin() + getNumPlacementArgs();
}
using raw_arg_iterator = Stmt **;
- raw_arg_iterator raw_arg_begin() { return SubExprs; }
+ raw_arg_iterator raw_arg_begin() { return getTrailingObjects<Stmt *>(); }
raw_arg_iterator raw_arg_end() {
- return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
+ return raw_arg_begin() + numTrailingObjects(OverloadToken<Stmt *>());
+ }
+ const_arg_iterator raw_arg_begin() const {
+ return getTrailingObjects<Stmt *>();
}
- const_arg_iterator raw_arg_begin() const { return SubExprs; }
const_arg_iterator raw_arg_end() const {
- return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
+ return raw_arg_begin() + numTrailingObjects(OverloadToken<Stmt *>());
}
- SourceLocation getStartLoc() const { return Range.getBegin(); }
+ SourceLocation getBeginLoc() const { return Range.getBegin(); }
SourceLocation getEndLoc() const { return Range.getEnd(); }
SourceRange getDirectInitRange() const { return DirectInitRange; }
-
- SourceRange getSourceRange() const LLVM_READONLY {
- return Range;
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return getStartLoc(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
+ SourceRange getSourceRange() const { return Range; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXNewExprClass;
}
// Iterators
- child_range children() {
- return child_range(raw_arg_begin(), raw_arg_end());
- }
+ child_range children() { return child_range(raw_arg_begin(), raw_arg_end()); }
};
/// Represents a \c delete expression for memory deallocation and
/// destructor calls, e.g. "delete[] pArray".
class CXXDeleteExpr : public Expr {
+ friend class ASTStmtReader;
+
/// Points to the operator delete overload that is used. Could be a member.
FunctionDecl *OperatorDelete = nullptr;
/// The pointer expression to be deleted.
Stmt *Argument = nullptr;
- /// Location of the expression.
- SourceLocation Loc;
-
- /// Is this a forced global delete, i.e. "::delete"?
- bool GlobalDelete : 1;
-
- /// Is this the array form of delete, i.e. "delete[]"?
- bool ArrayForm : 1;
-
- /// ArrayFormAsWritten can be different from ArrayForm if 'delete' is applied
- /// to pointer-to-array type (ArrayFormAsWritten will be false while ArrayForm
- /// will be true).
- bool ArrayFormAsWritten : 1;
-
- /// Does the usual deallocation function for the element type require
- /// a size_t argument?
- bool UsualArrayDeleteWantsSize : 1;
-
public:
- friend class ASTStmtReader;
+ CXXDeleteExpr(QualType Ty, bool GlobalDelete, bool ArrayForm,
+ bool ArrayFormAsWritten, bool UsualArrayDeleteWantsSize,
+ FunctionDecl *OperatorDelete, Expr *Arg, SourceLocation Loc)
+ : Expr(CXXDeleteExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
+ Arg->isInstantiationDependent(),
+ Arg->containsUnexpandedParameterPack()),
+ OperatorDelete(OperatorDelete), Argument(Arg) {
+ CXXDeleteExprBits.GlobalDelete = GlobalDelete;
+ CXXDeleteExprBits.ArrayForm = ArrayForm;
+ CXXDeleteExprBits.ArrayFormAsWritten = ArrayFormAsWritten;
+ CXXDeleteExprBits.UsualArrayDeleteWantsSize = UsualArrayDeleteWantsSize;
+ CXXDeleteExprBits.Loc = Loc;
+ }
- CXXDeleteExpr(QualType ty, bool globalDelete, bool arrayForm,
- bool arrayFormAsWritten, bool usualArrayDeleteWantsSize,
- FunctionDecl *operatorDelete, Expr *arg, SourceLocation loc)
- : Expr(CXXDeleteExprClass, ty, VK_RValue, OK_Ordinary, false, false,
- arg->isInstantiationDependent(),
- arg->containsUnexpandedParameterPack()),
- OperatorDelete(operatorDelete), Argument(arg), Loc(loc),
- GlobalDelete(globalDelete),
- ArrayForm(arrayForm), ArrayFormAsWritten(arrayFormAsWritten),
- UsualArrayDeleteWantsSize(usualArrayDeleteWantsSize) {}
explicit CXXDeleteExpr(EmptyShell Shell) : Expr(CXXDeleteExprClass, Shell) {}
- bool isGlobalDelete() const { return GlobalDelete; }
- bool isArrayForm() const { return ArrayForm; }
- bool isArrayFormAsWritten() const { return ArrayFormAsWritten; }
+ bool isGlobalDelete() const { return CXXDeleteExprBits.GlobalDelete; }
+ bool isArrayForm() const { return CXXDeleteExprBits.ArrayForm; }
+ bool isArrayFormAsWritten() const {
+ return CXXDeleteExprBits.ArrayFormAsWritten;
+ }
/// Answers whether the usual array deallocation function for the
/// allocated type expects the size of the allocation as a
/// parameter. This can be true even if the actual deallocation
/// function that we're using doesn't want a size.
bool doesUsualArrayDeleteWantSize() const {
- return UsualArrayDeleteWantsSize;
+ return CXXDeleteExprBits.UsualArrayDeleteWantsSize;
}
FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
@@ -2160,15 +2218,17 @@ public:
/// be a pointer, return an invalid type.
QualType getDestroyedType() const;
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY {return Argument->getLocEnd();}
+ SourceLocation getBeginLoc() const { return CXXDeleteExprBits.Loc; }
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return Argument->getEndLoc();
+ }
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXDeleteExprClass;
}
// Iterators
- child_range children() { return child_range(&Argument, &Argument+1); }
+ child_range children() { return child_range(&Argument, &Argument + 1); }
};
/// Stores the type being destroyed by a pseudo-destructor expression.
@@ -2346,8 +2406,10 @@ public:
DestroyedType = PseudoDestructorTypeStorage(Info);
}
- SourceLocation getLocStart() const LLVM_READONLY {return Base->getLocStart();}
- SourceLocation getLocEnd() const LLVM_READONLY;
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return Base->getBeginLoc();
+ }
+ SourceLocation getEndLoc() const LLVM_READONLY;
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXPseudoDestructorExprClass;
@@ -2428,8 +2490,8 @@ public:
getNumArgs());
}
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == TypeTraitExprClass;
@@ -2468,8 +2530,6 @@ class ArrayTypeTraitExpr : public Expr {
/// The type being queried.
TypeSourceInfo *QueriedType = nullptr;
- virtual void anchor();
-
public:
friend class ASTStmtReader;
@@ -2487,10 +2547,8 @@ public:
explicit ArrayTypeTraitExpr(EmptyShell Empty)
: Expr(ArrayTypeTraitExprClass, Empty), ATT(0) {}
- virtual ~ArrayTypeTraitExpr() = default;
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParen; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RParen; }
ArrayTypeTrait getTrait() const { return static_cast<ArrayTypeTrait>(ATT); }
@@ -2553,8 +2611,8 @@ public:
explicit ExpressionTraitExpr(EmptyShell Empty)
: Expr(ExpressionTraitExprClass, Empty), ET(0), Value(false) {}
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParen; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RParen; }
ExpressionTrait getTrait() const { return static_cast<ExpressionTrait>(ET); }
@@ -2575,58 +2633,54 @@ public:
/// A reference to an overloaded function set, either an
/// \c UnresolvedLookupExpr or an \c UnresolvedMemberExpr.
class OverloadExpr : public Expr {
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+
/// The common name of these declarations.
DeclarationNameInfo NameInfo;
/// The nested-name-specifier that qualifies the name, if any.
NestedNameSpecifierLoc QualifierLoc;
- /// The results. These are undesugared, which is to say, they may
- /// include UsingShadowDecls. Access is relative to the naming
- /// class.
- // FIXME: Allocate this data after the OverloadExpr subclass.
- DeclAccessPair *Results = nullptr;
-
- unsigned NumResults = 0;
-
protected:
- /// Whether the name includes info for explicit template
- /// keyword and arguments.
- bool HasTemplateKWAndArgsInfo = false;
-
- OverloadExpr(StmtClass K, const ASTContext &C,
+ OverloadExpr(StmtClass SC, const ASTContext &Context,
NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateKWLoc,
const DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo *TemplateArgs,
UnresolvedSetIterator Begin, UnresolvedSetIterator End,
- bool KnownDependent,
- bool KnownInstantiationDependent,
+ bool KnownDependent, bool KnownInstantiationDependent,
bool KnownContainsUnexpandedParameterPack);
- OverloadExpr(StmtClass K, EmptyShell Empty) : Expr(K, Empty) {}
+ OverloadExpr(StmtClass SC, EmptyShell Empty, unsigned NumResults,
+ bool HasTemplateKWAndArgsInfo);
- /// Return the optional template keyword and arguments info.
- ASTTemplateKWAndArgsInfo *
- getTrailingASTTemplateKWAndArgsInfo(); // defined far below.
+ /// Return the results. Defined after UnresolvedMemberExpr.
+ inline DeclAccessPair *getTrailingResults();
+ const DeclAccessPair *getTrailingResults() const {
+ return const_cast<OverloadExpr *>(this)->getTrailingResults();
+ }
/// Return the optional template keyword and arguments info.
+ /// Defined after UnresolvedMemberExpr.
+ inline ASTTemplateKWAndArgsInfo *getTrailingASTTemplateKWAndArgsInfo();
const ASTTemplateKWAndArgsInfo *getTrailingASTTemplateKWAndArgsInfo() const {
return const_cast<OverloadExpr *>(this)
->getTrailingASTTemplateKWAndArgsInfo();
}
- /// Return the optional template arguments.
- TemplateArgumentLoc *getTrailingTemplateArgumentLoc(); // defined far below
+ /// Return the optional template arguments. Defined after
+ /// UnresolvedMemberExpr.
+ inline TemplateArgumentLoc *getTrailingTemplateArgumentLoc();
+ const TemplateArgumentLoc *getTrailingTemplateArgumentLoc() const {
+ return const_cast<OverloadExpr *>(this)->getTrailingTemplateArgumentLoc();
+ }
- void initializeResults(const ASTContext &C,
- UnresolvedSetIterator Begin,
- UnresolvedSetIterator End);
+ bool hasTemplateKWAndArgsInfo() const {
+ return OverloadExprBits.HasTemplateKWAndArgsInfo;
+ }
public:
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-
struct FindResult {
OverloadExpr *Expression;
bool IsAddressOfOperand;
@@ -2662,20 +2716,26 @@ public:
}
/// Gets the naming class of this lookup, if any.
- CXXRecordDecl *getNamingClass() const;
+ /// Defined after UnresolvedMemberExpr.
+ inline CXXRecordDecl *getNamingClass();
+ const CXXRecordDecl *getNamingClass() const {
+ return const_cast<OverloadExpr *>(this)->getNamingClass();
+ }
using decls_iterator = UnresolvedSetImpl::iterator;
- decls_iterator decls_begin() const { return UnresolvedSetIterator(Results); }
+ decls_iterator decls_begin() const {
+ return UnresolvedSetIterator(getTrailingResults());
+ }
decls_iterator decls_end() const {
- return UnresolvedSetIterator(Results + NumResults);
+ return UnresolvedSetIterator(getTrailingResults() + getNumDecls());
}
llvm::iterator_range<decls_iterator> decls() const {
return llvm::make_range(decls_begin(), decls_end());
}
/// Gets the number of declarations in the unresolved set.
- unsigned getNumDecls() const { return NumResults; }
+ unsigned getNumDecls() const { return OverloadExprBits.NumResults; }
/// Gets the full name info.
const DeclarationNameInfo &getNameInfo() const { return NameInfo; }
@@ -2698,21 +2758,24 @@ public:
/// Retrieve the location of the template keyword preceding
/// this name, if any.
SourceLocation getTemplateKeywordLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+ if (!hasTemplateKWAndArgsInfo())
+ return SourceLocation();
return getTrailingASTTemplateKWAndArgsInfo()->TemplateKWLoc;
}
/// Retrieve the location of the left angle bracket starting the
/// explicit template argument list following the name, if any.
SourceLocation getLAngleLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+ if (!hasTemplateKWAndArgsInfo())
+ return SourceLocation();
return getTrailingASTTemplateKWAndArgsInfo()->LAngleLoc;
}
/// Retrieve the location of the right angle bracket ending the
/// explicit template argument list following the name, if any.
SourceLocation getRAngleLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+ if (!hasTemplateKWAndArgsInfo())
+ return SourceLocation();
return getTrailingASTTemplateKWAndArgsInfo()->RAngleLoc;
}
@@ -2764,97 +2827,93 @@ public:
/// members and therefore appear only in UnresolvedMemberLookupExprs.
class UnresolvedLookupExpr final
: public OverloadExpr,
- private llvm::TrailingObjects<
- UnresolvedLookupExpr, ASTTemplateKWAndArgsInfo, TemplateArgumentLoc> {
+ private llvm::TrailingObjects<UnresolvedLookupExpr, DeclAccessPair,
+ ASTTemplateKWAndArgsInfo,
+ TemplateArgumentLoc> {
friend class ASTStmtReader;
friend class OverloadExpr;
friend TrailingObjects;
- /// True if these lookup results should be extended by
- /// argument-dependent lookup if this is the operand of a function
- /// call.
- bool RequiresADL = false;
-
- /// True if these lookup results are overloaded. This is pretty
- /// trivially rederivable if we urgently need to kill this field.
- bool Overloaded = false;
-
/// The naming class (C++ [class.access.base]p5) of the lookup, if
/// any. This can generally be recalculated from the context chain,
- /// but that can be fairly expensive for unqualified lookups. If we
- /// want to improve memory use here, this could go in a union
- /// against the qualified-lookup bits.
- CXXRecordDecl *NamingClass = nullptr;
-
- UnresolvedLookupExpr(const ASTContext &C,
- CXXRecordDecl *NamingClass,
+ /// but that can be fairly expensive for unqualified lookups.
+ CXXRecordDecl *NamingClass;
+
+ // UnresolvedLookupExpr is followed by several trailing objects.
+ // They are in order:
+ //
+ // * An array of getNumResults() DeclAccessPair for the results. These are
+ // undesugared, which is to say, they may include UsingShadowDecls.
+ // Access is relative to the naming class.
+ //
+ // * An optional ASTTemplateKWAndArgsInfo for the explicitly specified
+ // template keyword and arguments. Present if and only if
+ // hasTemplateKWAndArgsInfo().
+ //
+ // * An array of getNumTemplateArgs() TemplateArgumentLoc containing
+ // location information for the explicitly specified template arguments.
+
+ UnresolvedLookupExpr(const ASTContext &Context, CXXRecordDecl *NamingClass,
NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &NameInfo,
- bool RequiresADL, bool Overloaded,
+ const DeclarationNameInfo &NameInfo, bool RequiresADL,
+ bool Overloaded,
const TemplateArgumentListInfo *TemplateArgs,
- UnresolvedSetIterator Begin, UnresolvedSetIterator End)
- : OverloadExpr(UnresolvedLookupExprClass, C, QualifierLoc, TemplateKWLoc,
- NameInfo, TemplateArgs, Begin, End, false, false, false),
- RequiresADL(RequiresADL),
- Overloaded(Overloaded), NamingClass(NamingClass) {}
+ UnresolvedSetIterator Begin, UnresolvedSetIterator End);
- UnresolvedLookupExpr(EmptyShell Empty)
- : OverloadExpr(UnresolvedLookupExprClass, Empty) {}
+ UnresolvedLookupExpr(EmptyShell Empty, unsigned NumResults,
+ bool HasTemplateKWAndArgsInfo);
- size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
- return HasTemplateKWAndArgsInfo ? 1 : 0;
+ unsigned numTrailingObjects(OverloadToken<DeclAccessPair>) const {
+ return getNumDecls();
+ }
+
+ unsigned numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
+ return hasTemplateKWAndArgsInfo();
}
public:
- static UnresolvedLookupExpr *Create(const ASTContext &C,
- CXXRecordDecl *NamingClass,
- NestedNameSpecifierLoc QualifierLoc,
- const DeclarationNameInfo &NameInfo,
- bool ADL, bool Overloaded,
- UnresolvedSetIterator Begin,
- UnresolvedSetIterator End) {
- return new(C) UnresolvedLookupExpr(C, NamingClass, QualifierLoc,
- SourceLocation(), NameInfo,
- ADL, Overloaded, nullptr, Begin, End);
- }
-
- static UnresolvedLookupExpr *Create(const ASTContext &C,
- CXXRecordDecl *NamingClass,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &NameInfo,
- bool ADL,
- const TemplateArgumentListInfo *Args,
- UnresolvedSetIterator Begin,
- UnresolvedSetIterator End);
-
- static UnresolvedLookupExpr *CreateEmpty(const ASTContext &C,
+ static UnresolvedLookupExpr *
+ Create(const ASTContext &Context, CXXRecordDecl *NamingClass,
+ NestedNameSpecifierLoc QualifierLoc,
+ const DeclarationNameInfo &NameInfo, bool RequiresADL, bool Overloaded,
+ UnresolvedSetIterator Begin, UnresolvedSetIterator End);
+
+ static UnresolvedLookupExpr *
+ Create(const ASTContext &Context, CXXRecordDecl *NamingClass,
+ NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
+ const DeclarationNameInfo &NameInfo, bool RequiresADL,
+ const TemplateArgumentListInfo *Args, UnresolvedSetIterator Begin,
+ UnresolvedSetIterator End);
+
+ static UnresolvedLookupExpr *CreateEmpty(const ASTContext &Context,
+ unsigned NumResults,
bool HasTemplateKWAndArgsInfo,
unsigned NumTemplateArgs);
/// True if this declaration should be extended by
/// argument-dependent lookup.
- bool requiresADL() const { return RequiresADL; }
+ bool requiresADL() const { return UnresolvedLookupExprBits.RequiresADL; }
/// True if this lookup is overloaded.
- bool isOverloaded() const { return Overloaded; }
+ bool isOverloaded() const { return UnresolvedLookupExprBits.Overloaded; }
/// Gets the 'naming class' (in the sense of C++0x
/// [class.access.base]p5) of the lookup. This is the scope
/// that was looked in to find these results.
- CXXRecordDecl *getNamingClass() const { return NamingClass; }
+ CXXRecordDecl *getNamingClass() { return NamingClass; }
+ const CXXRecordDecl *getNamingClass() const { return NamingClass; }
- SourceLocation getLocStart() const LLVM_READONLY {
+ SourceLocation getBeginLoc() const LLVM_READONLY {
if (NestedNameSpecifierLoc l = getQualifierLoc())
return l.getBeginLoc();
- return getNameInfo().getLocStart();
+ return getNameInfo().getBeginLoc();
}
- SourceLocation getLocEnd() const LLVM_READONLY {
+ SourceLocation getEndLoc() const LLVM_READONLY {
if (hasExplicitTemplateArgs())
return getRAngleLoc();
- return getNameInfo().getLocEnd();
+ return getNameInfo().getEndLoc();
}
child_range children() {
@@ -2885,6 +2944,10 @@ class DependentScopeDeclRefExpr final
private llvm::TrailingObjects<DependentScopeDeclRefExpr,
ASTTemplateKWAndArgsInfo,
TemplateArgumentLoc> {
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+ friend TrailingObjects;
+
/// The nested-name-specifier that qualifies this unresolved
/// declaration name.
NestedNameSpecifierLoc QualifierLoc;
@@ -2892,32 +2955,26 @@ class DependentScopeDeclRefExpr final
/// The name of the entity we will be referencing.
DeclarationNameInfo NameInfo;
- /// Whether the name includes info for explicit template
- /// keyword and arguments.
- bool HasTemplateKWAndArgsInfo;
-
- DependentScopeDeclRefExpr(QualType T,
- NestedNameSpecifierLoc QualifierLoc,
+ DependentScopeDeclRefExpr(QualType Ty, NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateKWLoc,
const DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo *Args);
size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
- return HasTemplateKWAndArgsInfo ? 1 : 0;
+ return hasTemplateKWAndArgsInfo();
}
-public:
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
- friend TrailingObjects;
+ bool hasTemplateKWAndArgsInfo() const {
+ return DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo;
+ }
- static DependentScopeDeclRefExpr *Create(const ASTContext &C,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &NameInfo,
- const TemplateArgumentListInfo *TemplateArgs);
+public:
+ static DependentScopeDeclRefExpr *
+ Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc,
+ SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo,
+ const TemplateArgumentListInfo *TemplateArgs);
- static DependentScopeDeclRefExpr *CreateEmpty(const ASTContext &C,
+ static DependentScopeDeclRefExpr *CreateEmpty(const ASTContext &Context,
bool HasTemplateKWAndArgsInfo,
unsigned NumTemplateArgs);
@@ -2945,21 +3002,24 @@ public:
/// Retrieve the location of the template keyword preceding
/// this name, if any.
SourceLocation getTemplateKeywordLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+ if (!hasTemplateKWAndArgsInfo())
+ return SourceLocation();
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->TemplateKWLoc;
}
/// Retrieve the location of the left angle bracket starting the
/// explicit template argument list following the name, if any.
SourceLocation getLAngleLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+ if (!hasTemplateKWAndArgsInfo())
+ return SourceLocation();
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->LAngleLoc;
}
/// Retrieve the location of the right angle bracket ending the
/// explicit template argument list following the name, if any.
SourceLocation getRAngleLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+ if (!hasTemplateKWAndArgsInfo())
+ return SourceLocation();
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->RAngleLoc;
}
@@ -2995,13 +3055,13 @@ public:
return {getTemplateArgs(), getNumTemplateArgs()};
}
- /// Note: getLocStart() is the start of the whole DependentScopeDeclRefExpr,
+ /// Note: getBeginLoc() is the start of the whole DependentScopeDeclRefExpr,
/// and differs from getLocation().getStart().
- SourceLocation getLocStart() const LLVM_READONLY {
+ SourceLocation getBeginLoc() const LLVM_READONLY {
return QualifierLoc.getBeginLoc();
}
- SourceLocation getLocEnd() const LLVM_READONLY {
+ SourceLocation getEndLoc() const LLVM_READONLY {
if (hasExplicitTemplateArgs())
return getRAngleLoc();
return getLocation();
@@ -3027,7 +3087,7 @@ public:
/// potentially-evaluated block literal. The lifetime of a block
/// literal is the extent of the enclosing scope.
class ExprWithCleanups final
- : public Expr,
+ : public FullExpr,
private llvm::TrailingObjects<ExprWithCleanups, BlockDecl *> {
public:
/// The type of objects that are kept in the cleanup.
@@ -3040,8 +3100,6 @@ private:
friend class ASTStmtReader;
friend TrailingObjects;
- Stmt *SubExpr;
-
ExprWithCleanups(EmptyShell, unsigned NumObjects);
ExprWithCleanups(Expr *SubExpr, bool CleanupsHaveSideEffects,
ArrayRef<CleanupObject> Objects);
@@ -3066,22 +3124,17 @@ public:
return getObjects()[i];
}
- Expr *getSubExpr() { return cast<Expr>(SubExpr); }
- const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
-
bool cleanupsHaveSideEffects() const {
return ExprWithCleanupsBits.CleanupsHaveSideEffects;
}
- /// As with any mutator of the AST, be very careful
- /// when modifying an existing AST to preserve its invariants.
- void setSubExpr(Expr *E) { SubExpr = E; }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return SubExpr->getLocStart();
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return SubExpr->getBeginLoc();
}
- SourceLocation getLocEnd() const LLVM_READONLY { return SubExpr->getLocEnd();}
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return SubExpr->getEndLoc();
+ }
// Implement isa/cast/dyncast/etc.
static bool classof(const Stmt *T) {
@@ -3120,7 +3173,7 @@ class CXXUnresolvedConstructExpr final
friend TrailingObjects;
/// The type being constructed.
- TypeSourceInfo *Type = nullptr;
+ TypeSourceInfo *TSI;
/// The location of the left parentheses ('(').
SourceLocation LParenLoc;
@@ -3128,34 +3181,31 @@ class CXXUnresolvedConstructExpr final
/// The location of the right parentheses (')').
SourceLocation RParenLoc;
- /// The number of arguments used to construct the type.
- unsigned NumArgs;
-
- CXXUnresolvedConstructExpr(TypeSourceInfo *Type,
- SourceLocation LParenLoc,
- ArrayRef<Expr*> Args,
- SourceLocation RParenLoc);
+ CXXUnresolvedConstructExpr(TypeSourceInfo *TSI, SourceLocation LParenLoc,
+ ArrayRef<Expr *> Args, SourceLocation RParenLoc);
CXXUnresolvedConstructExpr(EmptyShell Empty, unsigned NumArgs)
- : Expr(CXXUnresolvedConstructExprClass, Empty), NumArgs(NumArgs) {}
+ : Expr(CXXUnresolvedConstructExprClass, Empty) {
+ CXXUnresolvedConstructExprBits.NumArgs = NumArgs;
+ }
public:
- static CXXUnresolvedConstructExpr *Create(const ASTContext &C,
+ static CXXUnresolvedConstructExpr *Create(const ASTContext &Context,
TypeSourceInfo *Type,
SourceLocation LParenLoc,
- ArrayRef<Expr*> Args,
+ ArrayRef<Expr *> Args,
SourceLocation RParenLoc);
- static CXXUnresolvedConstructExpr *CreateEmpty(const ASTContext &C,
+ static CXXUnresolvedConstructExpr *CreateEmpty(const ASTContext &Context,
unsigned NumArgs);
/// Retrieve the type that is being constructed, as specified
/// in the source code.
- QualType getTypeAsWritten() const { return Type->getType(); }
+ QualType getTypeAsWritten() const { return TSI->getType(); }
/// Retrieve the type source information for the type being
/// constructed.
- TypeSourceInfo *getTypeSourceInfo() const { return Type; }
+ TypeSourceInfo *getTypeSourceInfo() const { return TSI; }
/// Retrieve the location of the left parentheses ('(') that
/// precedes the argument list.
@@ -3173,40 +3223,43 @@ public:
bool isListInitialization() const { return LParenLoc.isInvalid(); }
/// Retrieve the number of arguments.
- unsigned arg_size() const { return NumArgs; }
+ unsigned arg_size() const { return CXXUnresolvedConstructExprBits.NumArgs; }
using arg_iterator = Expr **;
+ using arg_range = llvm::iterator_range<arg_iterator>;
arg_iterator arg_begin() { return getTrailingObjects<Expr *>(); }
- arg_iterator arg_end() { return arg_begin() + NumArgs; }
+ arg_iterator arg_end() { return arg_begin() + arg_size(); }
+ arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
using const_arg_iterator = const Expr* const *;
+ using const_arg_range = llvm::iterator_range<const_arg_iterator>;
const_arg_iterator arg_begin() const { return getTrailingObjects<Expr *>(); }
- const_arg_iterator arg_end() const {
- return arg_begin() + NumArgs;
+ const_arg_iterator arg_end() const { return arg_begin() + arg_size(); }
+ const_arg_range arguments() const {
+ return const_arg_range(arg_begin(), arg_end());
}
Expr *getArg(unsigned I) {
- assert(I < NumArgs && "Argument index out-of-range");
- return *(arg_begin() + I);
+ assert(I < arg_size() && "Argument index out-of-range");
+ return arg_begin()[I];
}
const Expr *getArg(unsigned I) const {
- assert(I < NumArgs && "Argument index out-of-range");
- return *(arg_begin() + I);
+ assert(I < arg_size() && "Argument index out-of-range");
+ return arg_begin()[I];
}
void setArg(unsigned I, Expr *E) {
- assert(I < NumArgs && "Argument index out-of-range");
- *(arg_begin() + I) = E;
+ assert(I < arg_size() && "Argument index out-of-range");
+ arg_begin()[I] = E;
}
- SourceLocation getLocStart() const LLVM_READONLY;
-
- SourceLocation getLocEnd() const LLVM_READONLY {
- if (!RParenLoc.isValid() && NumArgs > 0)
- return getArg(NumArgs - 1)->getLocEnd();
+ SourceLocation getBeginLoc() const LLVM_READONLY;
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ if (!RParenLoc.isValid() && arg_size() > 0)
+ return getArg(arg_size() - 1)->getEndLoc();
return RParenLoc;
}
@@ -3217,7 +3270,7 @@ public:
// Iterators
child_range children() {
auto **begin = reinterpret_cast<Stmt **>(arg_begin());
- return child_range(begin, begin + NumArgs);
+ return child_range(begin, begin + arg_size());
}
};
@@ -3232,7 +3285,11 @@ class CXXDependentScopeMemberExpr final
: public Expr,
private llvm::TrailingObjects<CXXDependentScopeMemberExpr,
ASTTemplateKWAndArgsInfo,
- TemplateArgumentLoc> {
+ TemplateArgumentLoc, NamedDecl *> {
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+ friend TrailingObjects;
+
/// The expression for the base pointer or class reference,
/// e.g., the \c x in x.f. Can be null in implicit accesses.
Stmt *Base;
@@ -3241,40 +3298,53 @@ class CXXDependentScopeMemberExpr final
/// implicit accesses.
QualType BaseType;
- /// Whether this member expression used the '->' operator or
- /// the '.' operator.
- bool IsArrow : 1;
-
- /// Whether this member expression has info for explicit template
- /// keyword and arguments.
- bool HasTemplateKWAndArgsInfo : 1;
-
- /// The location of the '->' or '.' operator.
- SourceLocation OperatorLoc;
-
/// The nested-name-specifier that precedes the member name, if any.
+ /// FIXME: This could be in principle store as a trailing object.
+ /// However the performance impact of doing so should be investigated first.
NestedNameSpecifierLoc QualifierLoc;
- /// In a qualified member access expression such as t->Base::f, this
- /// member stores the resolves of name lookup in the context of the member
- /// access expression, to be used at instantiation time.
- ///
- /// FIXME: This member, along with the QualifierLoc, could
- /// be stuck into a structure that is optionally allocated at the end of
- /// the CXXDependentScopeMemberExpr, to save space in the common case.
- NamedDecl *FirstQualifierFoundInScope;
-
/// The member to which this member expression refers, which
/// can be name, overloaded operator, or destructor.
///
/// FIXME: could also be a template-id
DeclarationNameInfo MemberNameInfo;
- size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
- return HasTemplateKWAndArgsInfo ? 1 : 0;
+ // CXXDependentScopeMemberExpr is followed by several trailing objects,
+ // some of which optional. They are in order:
+ //
+ // * An optional ASTTemplateKWAndArgsInfo for the explicitly specified
+ // template keyword and arguments. Present if and only if
+ // hasTemplateKWAndArgsInfo().
+ //
+ // * An array of getNumTemplateArgs() TemplateArgumentLoc containing location
+ // information for the explicitly specified template arguments.
+ //
+ // * An optional NamedDecl *. In a qualified member access expression such
+ // as t->Base::f, this member stores the resolves of name lookup in the
+ // context of the member access expression, to be used at instantiation
+ // time. Present if and only if hasFirstQualifierFoundInScope().
+
+ bool hasTemplateKWAndArgsInfo() const {
+ return CXXDependentScopeMemberExprBits.HasTemplateKWAndArgsInfo;
+ }
+
+ bool hasFirstQualifierFoundInScope() const {
+ return CXXDependentScopeMemberExprBits.HasFirstQualifierFoundInScope;
+ }
+
+ unsigned numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
+ return hasTemplateKWAndArgsInfo();
+ }
+
+ unsigned numTrailingObjects(OverloadToken<TemplateArgumentLoc>) const {
+ return getNumTemplateArgs();
}
- CXXDependentScopeMemberExpr(const ASTContext &C, Expr *Base,
+ unsigned numTrailingObjects(OverloadToken<NamedDecl *>) const {
+ return hasFirstQualifierFoundInScope();
+ }
+
+ CXXDependentScopeMemberExpr(const ASTContext &Ctx, Expr *Base,
QualType BaseType, bool IsArrow,
SourceLocation OperatorLoc,
NestedNameSpecifierLoc QualifierLoc,
@@ -3283,33 +3353,29 @@ class CXXDependentScopeMemberExpr final
DeclarationNameInfo MemberNameInfo,
const TemplateArgumentListInfo *TemplateArgs);
-public:
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
- friend TrailingObjects;
-
- CXXDependentScopeMemberExpr(const ASTContext &C, Expr *Base,
- QualType BaseType, bool IsArrow,
- SourceLocation OperatorLoc,
- NestedNameSpecifierLoc QualifierLoc,
- NamedDecl *FirstQualifierFoundInScope,
- DeclarationNameInfo MemberNameInfo);
+ CXXDependentScopeMemberExpr(EmptyShell Empty, bool HasTemplateKWAndArgsInfo,
+ bool HasFirstQualifierFoundInScope);
+public:
static CXXDependentScopeMemberExpr *
- Create(const ASTContext &C, Expr *Base, QualType BaseType, bool IsArrow,
+ Create(const ASTContext &Ctx, Expr *Base, QualType BaseType, bool IsArrow,
SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierFoundInScope,
DeclarationNameInfo MemberNameInfo,
const TemplateArgumentListInfo *TemplateArgs);
static CXXDependentScopeMemberExpr *
- CreateEmpty(const ASTContext &C, bool HasTemplateKWAndArgsInfo,
- unsigned NumTemplateArgs);
+ CreateEmpty(const ASTContext &Ctx, bool HasTemplateKWAndArgsInfo,
+ unsigned NumTemplateArgs, bool HasFirstQualifierFoundInScope);
/// True if this is an implicit access, i.e. one in which the
/// member being accessed was not written in the source. The source
/// location of the operator is invalid in this case.
- bool isImplicitAccess() const;
+ bool isImplicitAccess() const {
+ if (!Base)
+ return true;
+ return cast<Expr>(Base)->isImplicitCXXThis();
+ }
/// Retrieve the base object of this member expressions,
/// e.g., the \c x in \c x.m.
@@ -3322,13 +3388,14 @@ public:
/// Determine whether this member expression used the '->'
/// operator; otherwise, it used the '.' operator.
- bool isArrow() const { return IsArrow; }
+ bool isArrow() const { return CXXDependentScopeMemberExprBits.IsArrow; }
/// Retrieve the location of the '->' or '.' operator.
- SourceLocation getOperatorLoc() const { return OperatorLoc; }
+ SourceLocation getOperatorLoc() const {
+ return CXXDependentScopeMemberExprBits.OperatorLoc;
+ }
- /// Retrieve the nested-name-specifier that qualifies the member
- /// name.
+ /// Retrieve the nested-name-specifier that qualifies the member name.
NestedNameSpecifier *getQualifier() const {
return QualifierLoc.getNestedNameSpecifier();
}
@@ -3349,17 +3416,17 @@ public:
/// combined with the results of name lookup into the type of the object
/// expression itself (the class type of x).
NamedDecl *getFirstQualifierFoundInScope() const {
- return FirstQualifierFoundInScope;
+ if (!hasFirstQualifierFoundInScope())
+ return nullptr;
+ return *getTrailingObjects<NamedDecl *>();
}
- /// Retrieve the name of the member that this expression
- /// refers to.
+ /// Retrieve the name of the member that this expression refers to.
const DeclarationNameInfo &getMemberNameInfo() const {
return MemberNameInfo;
}
- /// Retrieve the name of the member that this expression
- /// refers to.
+ /// Retrieve the name of the member that this expression refers to.
DeclarationName getMember() const { return MemberNameInfo.getName(); }
// Retrieve the location of the name of the member that this
@@ -3369,21 +3436,24 @@ public:
/// Retrieve the location of the template keyword preceding the
/// member name, if any.
SourceLocation getTemplateKeywordLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+ if (!hasTemplateKWAndArgsInfo())
+ return SourceLocation();
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->TemplateKWLoc;
}
/// Retrieve the location of the left angle bracket starting the
/// explicit template argument list following the member name, if any.
SourceLocation getLAngleLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+ if (!hasTemplateKWAndArgsInfo())
+ return SourceLocation();
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->LAngleLoc;
}
/// Retrieve the location of the right angle bracket ending the
/// explicit template argument list following the member name, if any.
SourceLocation getRAngleLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+ if (!hasTemplateKWAndArgsInfo())
+ return SourceLocation();
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->RAngleLoc;
}
@@ -3424,15 +3494,15 @@ public:
return {getTemplateArgs(), getNumTemplateArgs()};
}
- SourceLocation getLocStart() const LLVM_READONLY {
+ SourceLocation getBeginLoc() const LLVM_READONLY {
if (!isImplicitAccess())
- return Base->getLocStart();
+ return Base->getBeginLoc();
if (getQualifier())
return getQualifierLoc().getBeginLoc();
return MemberNameInfo.getBeginLoc();
}
- SourceLocation getLocEnd() const LLVM_READONLY {
+ SourceLocation getEndLoc() const LLVM_READONLY {
if (hasExplicitTemplateArgs())
return getRAngleLoc();
return MemberNameInfo.getEndLoc();
@@ -3467,25 +3537,18 @@ public:
/// DeclRefExpr, depending on whether the member is static.
class UnresolvedMemberExpr final
: public OverloadExpr,
- private llvm::TrailingObjects<
- UnresolvedMemberExpr, ASTTemplateKWAndArgsInfo, TemplateArgumentLoc> {
+ private llvm::TrailingObjects<UnresolvedMemberExpr, DeclAccessPair,
+ ASTTemplateKWAndArgsInfo,
+ TemplateArgumentLoc> {
friend class ASTStmtReader;
friend class OverloadExpr;
friend TrailingObjects;
- /// Whether this member expression used the '->' operator or
- /// the '.' operator.
- bool IsArrow : 1;
-
- /// Whether the lookup results contain an unresolved using
- /// declaration.
- bool HasUnresolvedUsing : 1;
-
/// The expression for the base pointer or class reference,
/// e.g., the \c x in x.f.
///
/// This can be null if this is an 'unbased' member expression.
- Stmt *Base = nullptr;
+ Stmt *Base;
/// The type of the base expression; never null.
QualType BaseType;
@@ -3493,7 +3556,21 @@ class UnresolvedMemberExpr final
/// The location of the '->' or '.' operator.
SourceLocation OperatorLoc;
- UnresolvedMemberExpr(const ASTContext &C, bool HasUnresolvedUsing,
+ // UnresolvedMemberExpr is followed by several trailing objects.
+ // They are in order:
+ //
+ // * An array of getNumResults() DeclAccessPair for the results. These are
+ // undesugared, which is to say, they may include UsingShadowDecls.
+ // Access is relative to the naming class.
+ //
+ // * An optional ASTTemplateKWAndArgsInfo for the explicitly specified
+ // template keyword and arguments. Present if and only if
+ // hasTemplateKWAndArgsInfo().
+ //
+ // * An array of getNumTemplateArgs() TemplateArgumentLoc containing
+ // location information for the explicitly specified template arguments.
+
+ UnresolvedMemberExpr(const ASTContext &Context, bool HasUnresolvedUsing,
Expr *Base, QualType BaseType, bool IsArrow,
SourceLocation OperatorLoc,
NestedNameSpecifierLoc QualifierLoc,
@@ -3502,28 +3579,30 @@ class UnresolvedMemberExpr final
const TemplateArgumentListInfo *TemplateArgs,
UnresolvedSetIterator Begin, UnresolvedSetIterator End);
- UnresolvedMemberExpr(EmptyShell Empty)
- : OverloadExpr(UnresolvedMemberExprClass, Empty), IsArrow(false),
- HasUnresolvedUsing(false) {}
+ UnresolvedMemberExpr(EmptyShell Empty, unsigned NumResults,
+ bool HasTemplateKWAndArgsInfo);
- size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
- return HasTemplateKWAndArgsInfo ? 1 : 0;
+ unsigned numTrailingObjects(OverloadToken<DeclAccessPair>) const {
+ return getNumDecls();
+ }
+
+ unsigned numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
+ return hasTemplateKWAndArgsInfo();
}
public:
static UnresolvedMemberExpr *
- Create(const ASTContext &C, bool HasUnresolvedUsing,
- Expr *Base, QualType BaseType, bool IsArrow,
- SourceLocation OperatorLoc,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
+ Create(const ASTContext &Context, bool HasUnresolvedUsing, Expr *Base,
+ QualType BaseType, bool IsArrow, SourceLocation OperatorLoc,
+ NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
const DeclarationNameInfo &MemberNameInfo,
const TemplateArgumentListInfo *TemplateArgs,
UnresolvedSetIterator Begin, UnresolvedSetIterator End);
- static UnresolvedMemberExpr *
- CreateEmpty(const ASTContext &C, bool HasTemplateKWAndArgsInfo,
- unsigned NumTemplateArgs);
+ static UnresolvedMemberExpr *CreateEmpty(const ASTContext &Context,
+ unsigned NumResults,
+ bool HasTemplateKWAndArgsInfo,
+ unsigned NumTemplateArgs);
/// True if this is an implicit access, i.e., one in which the
/// member being accessed was not written in the source.
@@ -3546,46 +3625,50 @@ public:
/// Determine whether the lookup results contain an unresolved using
/// declaration.
- bool hasUnresolvedUsing() const { return HasUnresolvedUsing; }
+ bool hasUnresolvedUsing() const {
+ return UnresolvedMemberExprBits.HasUnresolvedUsing;
+ }
/// Determine whether this member expression used the '->'
/// operator; otherwise, it used the '.' operator.
- bool isArrow() const { return IsArrow; }
+ bool isArrow() const { return UnresolvedMemberExprBits.IsArrow; }
/// Retrieve the location of the '->' or '.' operator.
SourceLocation getOperatorLoc() const { return OperatorLoc; }
/// Retrieve the naming class of this lookup.
- CXXRecordDecl *getNamingClass() const;
+ CXXRecordDecl *getNamingClass();
+ const CXXRecordDecl *getNamingClass() const {
+ return const_cast<UnresolvedMemberExpr *>(this)->getNamingClass();
+ }
/// Retrieve the full name info for the member that this expression
/// refers to.
const DeclarationNameInfo &getMemberNameInfo() const { return getNameInfo(); }
- /// Retrieve the name of the member that this expression
- /// refers to.
+ /// Retrieve the name of the member that this expression refers to.
DeclarationName getMemberName() const { return getName(); }
- // Retrieve the location of the name of the member that this
- // expression refers to.
+ /// Retrieve the location of the name of the member that this
+ /// expression refers to.
SourceLocation getMemberLoc() const { return getNameLoc(); }
- // Return the preferred location (the member name) for the arrow when
- // diagnosing a problem with this expression.
+ /// Return the preferred location (the member name) for the arrow when
+ /// diagnosing a problem with this expression.
SourceLocation getExprLoc() const LLVM_READONLY { return getMemberLoc(); }
- SourceLocation getLocStart() const LLVM_READONLY {
+ SourceLocation getBeginLoc() const LLVM_READONLY {
if (!isImplicitAccess())
- return Base->getLocStart();
+ return Base->getBeginLoc();
if (NestedNameSpecifierLoc l = getQualifierLoc())
return l.getBeginLoc();
- return getMemberNameInfo().getLocStart();
+ return getMemberNameInfo().getBeginLoc();
}
- SourceLocation getLocEnd() const LLVM_READONLY {
+ SourceLocation getEndLoc() const LLVM_READONLY {
if (hasExplicitTemplateArgs())
return getRAngleLoc();
- return getMemberNameInfo().getLocEnd();
+ return getMemberNameInfo().getEndLoc();
}
static bool classof(const Stmt *T) {
@@ -3600,26 +3683,33 @@ public:
}
};
-inline ASTTemplateKWAndArgsInfo *
-OverloadExpr::getTrailingASTTemplateKWAndArgsInfo() {
- if (!HasTemplateKWAndArgsInfo)
+DeclAccessPair *OverloadExpr::getTrailingResults() {
+ if (auto *ULE = dyn_cast<UnresolvedLookupExpr>(this))
+ return ULE->getTrailingObjects<DeclAccessPair>();
+ return cast<UnresolvedMemberExpr>(this)->getTrailingObjects<DeclAccessPair>();
+}
+
+ASTTemplateKWAndArgsInfo *OverloadExpr::getTrailingASTTemplateKWAndArgsInfo() {
+ if (!hasTemplateKWAndArgsInfo())
return nullptr;
- if (isa<UnresolvedLookupExpr>(this))
- return cast<UnresolvedLookupExpr>(this)
- ->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
- else
- return cast<UnresolvedMemberExpr>(this)
- ->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
+ if (auto *ULE = dyn_cast<UnresolvedLookupExpr>(this))
+ return ULE->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
+ return cast<UnresolvedMemberExpr>(this)
+ ->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
}
-inline TemplateArgumentLoc *OverloadExpr::getTrailingTemplateArgumentLoc() {
- if (isa<UnresolvedLookupExpr>(this))
- return cast<UnresolvedLookupExpr>(this)
- ->getTrailingObjects<TemplateArgumentLoc>();
- else
- return cast<UnresolvedMemberExpr>(this)
- ->getTrailingObjects<TemplateArgumentLoc>();
+TemplateArgumentLoc *OverloadExpr::getTrailingTemplateArgumentLoc() {
+ if (auto *ULE = dyn_cast<UnresolvedLookupExpr>(this))
+ return ULE->getTrailingObjects<TemplateArgumentLoc>();
+ return cast<UnresolvedMemberExpr>(this)
+ ->getTrailingObjects<TemplateArgumentLoc>();
+}
+
+CXXRecordDecl *OverloadExpr::getNamingClass() {
+ if (auto *ULE = dyn_cast<UnresolvedLookupExpr>(this))
+ return ULE->getNamingClass();
+ return cast<UnresolvedMemberExpr>(this)->getNamingClass();
}
/// Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
@@ -3629,7 +3719,6 @@ inline TemplateArgumentLoc *OverloadExpr::getTrailingTemplateArgumentLoc() {
class CXXNoexceptExpr : public Expr {
friend class ASTStmtReader;
- bool Value : 1;
Stmt *Operand;
SourceRange Range;
@@ -3637,21 +3726,23 @@ public:
CXXNoexceptExpr(QualType Ty, Expr *Operand, CanThrowResult Val,
SourceLocation Keyword, SourceLocation RParen)
: Expr(CXXNoexceptExprClass, Ty, VK_RValue, OK_Ordinary,
- /*TypeDependent*/false,
- /*ValueDependent*/Val == CT_Dependent,
+ /*TypeDependent*/ false,
+ /*ValueDependent*/ Val == CT_Dependent,
Val == CT_Dependent || Operand->isInstantiationDependent(),
Operand->containsUnexpandedParameterPack()),
- Value(Val == CT_Cannot), Operand(Operand), Range(Keyword, RParen) {}
+ Operand(Operand), Range(Keyword, RParen) {
+ CXXNoexceptExprBits.Value = Val == CT_Cannot;
+ }
CXXNoexceptExpr(EmptyShell Empty) : Expr(CXXNoexceptExprClass, Empty) {}
- Expr *getOperand() const { return static_cast<Expr*>(Operand); }
+ Expr *getOperand() const { return static_cast<Expr *>(Operand); }
- SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
- SourceRange getSourceRange() const LLVM_READONLY { return Range; }
+ SourceLocation getBeginLoc() const { return Range.getBegin(); }
+ SourceLocation getEndLoc() const { return Range.getEnd(); }
+ SourceRange getSourceRange() const { return Range; }
- bool getValue() const { return Value; }
+ bool getValue() const { return CXXNoexceptExprBits.Value; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXNoexceptExprClass;
@@ -3725,11 +3816,11 @@ public:
return None;
}
- SourceLocation getLocStart() const LLVM_READONLY {
- return Pattern->getLocStart();
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return Pattern->getBeginLoc();
}
- SourceLocation getLocEnd() const LLVM_READONLY { return EllipsisLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return EllipsisLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == PackExpansionExprClass;
@@ -3849,8 +3940,8 @@ public:
return llvm::makeArrayRef(Args, Args + Length);
}
- SourceLocation getLocStart() const LLVM_READONLY { return OperatorLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return OperatorLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == SizeOfPackExprClass;
@@ -3874,27 +3965,27 @@ class SubstNonTypeTemplateParmExpr : public Expr {
/// The replacement expression.
Stmt *Replacement;
- /// The location of the non-type template parameter reference.
- SourceLocation NameLoc;
-
explicit SubstNonTypeTemplateParmExpr(EmptyShell Empty)
: Expr(SubstNonTypeTemplateParmExprClass, Empty) {}
public:
- SubstNonTypeTemplateParmExpr(QualType type,
- ExprValueKind valueKind,
- SourceLocation loc,
- NonTypeTemplateParmDecl *param,
- Expr *replacement)
- : Expr(SubstNonTypeTemplateParmExprClass, type, valueKind, OK_Ordinary,
- replacement->isTypeDependent(), replacement->isValueDependent(),
- replacement->isInstantiationDependent(),
- replacement->containsUnexpandedParameterPack()),
- Param(param), Replacement(replacement), NameLoc(loc) {}
-
- SourceLocation getNameLoc() const { return NameLoc; }
- SourceLocation getLocStart() const LLVM_READONLY { return NameLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return NameLoc; }
+ SubstNonTypeTemplateParmExpr(QualType Ty, ExprValueKind ValueKind,
+ SourceLocation Loc,
+ NonTypeTemplateParmDecl *Param,
+ Expr *Replacement)
+ : Expr(SubstNonTypeTemplateParmExprClass, Ty, ValueKind, OK_Ordinary,
+ Replacement->isTypeDependent(), Replacement->isValueDependent(),
+ Replacement->isInstantiationDependent(),
+ Replacement->containsUnexpandedParameterPack()),
+ Param(Param), Replacement(Replacement) {
+ SubstNonTypeTemplateParmExprBits.NameLoc = Loc;
+ }
+
+ SourceLocation getNameLoc() const {
+ return SubstNonTypeTemplateParmExprBits.NameLoc;
+ }
+ SourceLocation getBeginLoc() const { return getNameLoc(); }
+ SourceLocation getEndLoc() const { return getNameLoc(); }
Expr *getReplacement() const { return cast<Expr>(Replacement); }
@@ -3905,7 +3996,7 @@ public:
}
// Iterators
- child_range children() { return child_range(&Replacement, &Replacement+1); }
+ child_range children() { return child_range(&Replacement, &Replacement + 1); }
};
/// Represents a reference to a non-type template parameter pack that
@@ -3957,8 +4048,8 @@ public:
/// template arguments.
TemplateArgument getArgumentPack() const;
- SourceLocation getLocStart() const LLVM_READONLY { return NameLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return NameLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return NameLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return NameLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == SubstNonTypeTemplateParmPackExprClass;
@@ -4030,8 +4121,8 @@ public:
/// Get an expansion of the parameter pack by index.
ParmVarDecl *getExpansion(unsigned I) const { return begin()[I]; }
- SourceLocation getLocStart() const LLVM_READONLY { return NameLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return NameLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return NameLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return NameLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == FunctionParmPackExprClass;
@@ -4142,12 +4233,12 @@ public:
return getValueKind() == VK_LValue;
}
- SourceLocation getLocStart() const LLVM_READONLY {
- return getTemporary()->getLocStart();
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return getTemporary()->getBeginLoc();
}
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getTemporary()->getLocEnd();
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return getTemporary()->getEndLoc();
}
static bool classof(const Stmt *T) {
@@ -4217,13 +4308,9 @@ public:
SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
BinaryOperatorKind getOperator() const { return Opcode; }
- SourceLocation getLocStart() const LLVM_READONLY {
- return LParenLoc;
- }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return LParenLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return RParenLoc;
- }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXFoldExprClass;
@@ -4312,12 +4399,10 @@ public:
return static_cast<Expr*>(SubExprs[SubExpr::Resume]);
}
- SourceLocation getLocStart() const LLVM_READONLY {
- return KeywordLoc;
- }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return KeywordLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getCommonExpr()->getLocEnd();
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return getCommonExpr()->getEndLoc();
}
child_range children() {
@@ -4400,10 +4485,10 @@ public:
SourceLocation getKeywordLoc() const { return KeywordLoc; }
- SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return KeywordLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getOperand()->getLocEnd();
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return getOperand()->getEndLoc();
}
child_range children() { return child_range(SubExprs, SubExprs + 2); }
diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h
index bb0402c27080..c7b305f3304e 100644
--- a/include/clang/AST/ExprObjC.h
+++ b/include/clang/AST/ExprObjC.h
@@ -67,8 +67,8 @@ public:
SourceLocation getAtLoc() const { return AtLoc; }
void setAtLoc(SourceLocation L) { AtLoc = L; }
- SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return String->getLocEnd(); }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return String->getEndLoc(); }
// Iterators
child_range children() { return child_range(&String, &String+1); }
@@ -94,8 +94,8 @@ public:
bool getValue() const { return Value; }
void setValue(bool V) { Value = V; }
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return Loc; }
SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }
@@ -141,8 +141,8 @@ public:
SourceLocation getAtLoc() const { return Range.getBegin(); }
- SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
+ SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
SourceRange getSourceRange() const LLVM_READONLY {
return Range;
@@ -194,8 +194,8 @@ public:
static ObjCArrayLiteral *CreateEmpty(const ASTContext &C,
unsigned NumElements);
- SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
+ SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
SourceRange getSourceRange() const LLVM_READONLY { return Range; }
/// Retrieve elements of array of literals.
@@ -359,8 +359,8 @@ public:
return DictWithObjectsMethod;
}
- SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
+ SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
SourceRange getSourceRange() const LLVM_READONLY { return Range; }
// Iterators
@@ -412,8 +412,8 @@ public:
EncodedType = EncType;
}
- SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
// Iterators
child_range children() {
@@ -447,8 +447,8 @@ public:
void setAtLoc(SourceLocation L) { AtLoc = L; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
/// getNumArgs - Return the number of actual arguments to this call.
unsigned getNumArgs() const { return SelName.getNumArgs(); }
@@ -496,8 +496,8 @@ public:
void setAtLoc(SourceLocation L) { AtLoc = L; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
// Iterators
child_range children() {
@@ -556,10 +556,10 @@ public:
SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }
- SourceLocation getLocStart() const LLVM_READONLY {
- return isFreeIvar() ? Loc : getBase()->getLocStart();
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return isFreeIvar() ? Loc : getBase()->getBeginLoc();
}
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return Loc; }
SourceLocation getOpLoc() const { return OpLoc; }
void setOpLoc(SourceLocation L) { OpLoc = L; }
@@ -742,11 +742,12 @@ public:
/// Determine the type of the base, regardless of the kind of receiver.
QualType getReceiverType(const ASTContext &ctx) const;
- SourceLocation getLocStart() const LLVM_READONLY {
- return isObjectReceiver() ? getBase()->getLocStart() :getReceiverLocation();
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return isObjectReceiver() ? getBase()->getBeginLoc()
+ : getReceiverLocation();
}
- SourceLocation getLocEnd() const LLVM_READONLY { return IdLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return IdLoc; }
// Iterators
child_range children() {
@@ -838,11 +839,11 @@ public:
SourceLocation getRBracket() const { return RBracket; }
void setRBracket(SourceLocation RB) { RBracket = RB; }
- SourceLocation getLocStart() const LLVM_READONLY {
- return SubExprs[BASE]->getLocStart();
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return SubExprs[BASE]->getBeginLoc();
}
- SourceLocation getLocEnd() const LLVM_READONLY { return RBracket; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RBracket; }
Expr *getBaseExpr() const { return cast<Expr>(SubExprs[BASE]); }
void setBaseExpr(Stmt *S) { SubExprs[BASE] = S; }
@@ -1364,7 +1365,7 @@ public:
SourceLocation getSelectorStartLoc() const {
if (isImplicit())
- return getLocStart();
+ return getBeginLoc();
return getSelectorLoc(0);
}
@@ -1395,8 +1396,8 @@ public:
RBracLoc = R.getEnd();
}
- SourceLocation getLocStart() const LLVM_READONLY { return LBracLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RBracLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return LBracLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RBracLoc; }
// Iterators
child_range children();
@@ -1472,15 +1473,15 @@ public:
SourceLocation getOpLoc() const { return OpLoc; }
void setOpLoc(SourceLocation L) { OpLoc = L; }
- SourceLocation getLocStart() const LLVM_READONLY {
- return getBase()->getLocStart();
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return getBase()->getBeginLoc();
}
SourceLocation getBaseLocEnd() const LLVM_READONLY {
- return getBase()->getLocEnd();
+ return getBase()->getEndLoc();
}
- SourceLocation getLocEnd() const LLVM_READONLY { return IsaMemberLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return IsaMemberLoc; }
SourceLocation getExprLoc() const LLVM_READONLY { return IsaMemberLoc; }
@@ -1549,10 +1550,12 @@ public:
child_range children() { return child_range(&Operand, &Operand+1); }
// Source locations are determined by the subexpression.
- SourceLocation getLocStart() const LLVM_READONLY {
- return Operand->getLocStart();
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return Operand->getBeginLoc();
+ }
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return Operand->getEndLoc();
}
- SourceLocation getLocEnd() const LLVM_READONLY { return Operand->getLocEnd();}
SourceLocation getExprLoc() const LLVM_READONLY {
return getSubExpr()->getExprLoc();
@@ -1571,8 +1574,7 @@ public:
/// \endcode
class ObjCBridgedCastExpr final
: public ExplicitCastExpr,
- private llvm::TrailingObjects<
- ObjCBridgedCastExpr, CastExpr::BasePathSizeTy, CXXBaseSpecifier *> {
+ private llvm::TrailingObjects<ObjCBridgedCastExpr, CXXBaseSpecifier *> {
friend class ASTStmtReader;
friend class ASTStmtWriter;
friend class CastExpr;
@@ -1582,10 +1584,6 @@ class ObjCBridgedCastExpr final
SourceLocation BridgeKeywordLoc;
unsigned Kind : 2;
- size_t numTrailingObjects(OverloadToken<CastExpr::BasePathSizeTy>) const {
- return path_empty() ? 0 : 1;
- }
-
public:
ObjCBridgedCastExpr(SourceLocation LParenLoc, ObjCBridgeCastKind Kind,
CastKind CK, SourceLocation BridgeKeywordLoc,
@@ -1611,10 +1609,10 @@ public:
/// The location of the bridge keyword.
SourceLocation getBridgeKeywordLoc() const { return BridgeKeywordLoc; }
- SourceLocation getLocStart() const LLVM_READONLY { return LParenLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return LParenLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getSubExpr()->getLocEnd();
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return getSubExpr()->getEndLoc();
}
static bool classof(const Stmt *T) {
@@ -1651,8 +1649,8 @@ public:
explicit ObjCAvailabilityCheckExpr(EmptyShell Shell)
: Expr(ObjCAvailabilityCheckExprClass, Shell) {}
- SourceLocation getLocStart() const { return AtLoc; }
- SourceLocation getLocEnd() const { return RParen; }
+ SourceLocation getBeginLoc() const { return AtLoc; }
+ SourceLocation getEndLoc() const { return RParen; }
SourceRange getSourceRange() const { return {AtLoc, RParen}; }
/// This may be '*', in which case this should fold to true.
diff --git a/include/clang/AST/ExprOpenMP.h b/include/clang/AST/ExprOpenMP.h
index 2b4b5ec4d0e4..d88eebf5e54f 100644
--- a/include/clang/AST/ExprOpenMP.h
+++ b/include/clang/AST/ExprOpenMP.h
@@ -101,10 +101,10 @@ public:
/// Set length of the array section.
void setLength(Expr *E) { SubExprs[LENGTH] = E; }
- SourceLocation getLocStart() const LLVM_READONLY {
- return getBase()->getLocStart();
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return getBase()->getBeginLoc();
}
- SourceLocation getLocEnd() const LLVM_READONLY { return RBracketLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RBracketLoc; }
SourceLocation getColonLoc() const { return ColonLoc; }
void setColonLoc(SourceLocation L) { ColonLoc = L; }
diff --git a/include/clang/Analysis/Analyses/FormatString.h b/include/clang/AST/FormatString.h
index 598d341ac829..4a89c797b648 100644
--- a/include/clang/Analysis/Analyses/FormatString.h
+++ b/include/clang/AST/FormatString.h
@@ -303,6 +303,8 @@ public:
QualType getRepresentativeType(ASTContext &C) const;
+ ArgType makeVectorType(ASTContext &C, unsigned NumElts) const;
+
std::string getRepresentativeTypeName(ASTContext &C) const;
};
@@ -322,6 +324,10 @@ public:
: start(nullptr),length(0), hs(valid ? NotSpecified : Invalid), amt(0),
UsesPositionalArg(0), UsesDotPrefix(0) {}
+ explicit OptionalAmount(unsigned Amount)
+ : start(nullptr), length(0), hs(Constant), amt(Amount),
+ UsesPositionalArg(false), UsesDotPrefix(false) {}
+
bool isInvalid() const {
return hs == Invalid;
}
@@ -379,6 +385,8 @@ protected:
LengthModifier LM;
OptionalAmount FieldWidth;
ConversionSpecifier CS;
+ OptionalAmount VectorNumElts;
+
/// Positional arguments, an IEEE extension:
/// IEEE Std 1003.1, 2004 Edition
/// http://www.opengroup.org/onlinepubs/009695399/functions/printf.html
@@ -386,7 +394,8 @@ protected:
unsigned argIndex;
public:
FormatSpecifier(bool isPrintf)
- : CS(isPrintf), UsesPositionalArg(false), argIndex(0) {}
+ : CS(isPrintf), VectorNumElts(false),
+ UsesPositionalArg(false), argIndex(0) {}
void setLengthModifier(LengthModifier lm) {
LM = lm;
@@ -414,6 +423,14 @@ public:
return FieldWidth;
}
+ void setVectorNumElts(const OptionalAmount &Amt) {
+ VectorNumElts = Amt;
+ }
+
+ const OptionalAmount &getVectorNumElts() const {
+ return VectorNumElts;
+ }
+
void setFieldWidth(const OptionalAmount &Amt) {
FieldWidth = Amt;
}
@@ -475,13 +492,19 @@ class PrintfSpecifier : public analyze_format_string::FormatSpecifier {
OptionalFlag HasObjCTechnicalTerm; // '[tt]'
OptionalFlag IsPrivate; // '{private}'
OptionalFlag IsPublic; // '{public}'
+ OptionalFlag IsSensitive; // '{sensitive}'
OptionalAmount Precision;
+ StringRef MaskType;
+
+ ArgType getScalarArgType(ASTContext &Ctx, bool IsObjCLiteral) const;
+
public:
PrintfSpecifier()
: FormatSpecifier(/* isPrintf = */ true), HasThousandsGrouping("'"),
IsLeftJustified("-"), HasPlusPrefix("+"), HasSpacePrefix(" "),
HasAlternativeForm("#"), HasLeadingZeroes("0"),
- HasObjCTechnicalTerm("tt"), IsPrivate("private"), IsPublic("public") {}
+ HasObjCTechnicalTerm("tt"), IsPrivate("private"), IsPublic("public"),
+ IsSensitive("sensitive") {}
static PrintfSpecifier Parse(const char *beg, const char *end);
@@ -512,6 +535,9 @@ public:
}
void setIsPrivate(const char *position) { IsPrivate.setPosition(position); }
void setIsPublic(const char *position) { IsPublic.setPosition(position); }
+ void setIsSensitive(const char *position) {
+ IsSensitive.setPosition(position);
+ }
void setUsesPositionalArg() { UsesPositionalArg = true; }
// Methods for querying the format specifier.
@@ -551,8 +577,12 @@ public:
const OptionalFlag &hasObjCTechnicalTerm() const { return HasObjCTechnicalTerm; }
const OptionalFlag &isPrivate() const { return IsPrivate; }
const OptionalFlag &isPublic() const { return IsPublic; }
+ const OptionalFlag &isSensitive() const { return IsSensitive; }
bool usesPositionalArg() const { return UsesPositionalArg; }
+ StringRef getMaskType() const { return MaskType; }
+ void setMaskType(StringRef S) { MaskType = S; }
+
/// Changes the specifier and length according to a QualType, retaining any
/// flags or options. Returns true on success, or false when a conversion
/// was not successful.
@@ -685,6 +715,9 @@ public:
return true;
}
+ /// Handle mask types whose sizes are not between one and eight bytes.
+ virtual void handleInvalidMaskType(StringRef MaskType) {}
+
// Scanf-specific handlers.
virtual bool HandleInvalidScanfConversionSpecifier(
diff --git a/include/clang/AST/GlobalDecl.h b/include/clang/AST/GlobalDecl.h
index 7f017994216f..a3c0cab3799f 100644
--- a/include/clang/AST/GlobalDecl.h
+++ b/include/clang/AST/GlobalDecl.h
@@ -34,6 +34,7 @@ namespace clang {
/// a VarDecl, a FunctionDecl or a BlockDecl.
class GlobalDecl {
llvm::PointerIntPair<const Decl *, 2> Value;
+ unsigned MultiVersionIndex = 0;
void Init(const Decl *D) {
assert(!isa<CXXConstructorDecl>(D) && "Use other ctor with ctor decls!");
@@ -45,7 +46,10 @@ class GlobalDecl {
public:
GlobalDecl() = default;
GlobalDecl(const VarDecl *D) { Init(D);}
- GlobalDecl(const FunctionDecl *D) { Init(D); }
+ GlobalDecl(const FunctionDecl *D, unsigned MVIndex = 0)
+ : MultiVersionIndex(MVIndex) {
+ Init(D);
+ }
GlobalDecl(const BlockDecl *D) { Init(D); }
GlobalDecl(const CapturedDecl *D) { Init(D); }
GlobalDecl(const ObjCMethodDecl *D) { Init(D); }
@@ -57,6 +61,7 @@ public:
GlobalDecl CanonGD;
CanonGD.Value.setPointer(Value.getPointer()->getCanonicalDecl());
CanonGD.Value.setInt(Value.getInt());
+ CanonGD.MultiVersionIndex = MultiVersionIndex;
return CanonGD;
}
@@ -73,8 +78,17 @@ public:
return static_cast<CXXDtorType>(Value.getInt());
}
+ unsigned getMultiVersionIndex() const {
+ assert(isa<FunctionDecl>(getDecl()) &&
+ !isa<CXXConstructorDecl>(getDecl()) &&
+ !isa<CXXDestructorDecl>(getDecl()) &&
+ "Decl is not a plain FunctionDecl!");
+ return MultiVersionIndex;
+ }
+
friend bool operator==(const GlobalDecl &LHS, const GlobalDecl &RHS) {
- return LHS.Value == RHS.Value;
+ return LHS.Value == RHS.Value &&
+ LHS.MultiVersionIndex == RHS.MultiVersionIndex;
}
void *getAsOpaquePtr() const { return Value.getOpaqueValue(); }
@@ -90,6 +104,16 @@ public:
Result.Value.setPointer(D);
return Result;
}
+
+ GlobalDecl getWithMultiVersionIndex(unsigned Index) {
+ assert(isa<FunctionDecl>(getDecl()) &&
+ !isa<CXXConstructorDecl>(getDecl()) &&
+ !isa<CXXDestructorDecl>(getDecl()) &&
+ "Decl is not a plain FunctionDecl!");
+ GlobalDecl Result(*this);
+ Result.MultiVersionIndex = Index;
+ return Result;
+ }
};
} // namespace clang
diff --git a/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h b/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h
index 264f20f19ad5..47dac4362c8e 100644
--- a/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h
+++ b/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h
@@ -99,8 +99,8 @@ public:
LexicallyNestedDeclarations.clear();
for (++I; I != E; ++I) {
Decl *Sibling = *I;
- if (!SM.isBeforeInTranslationUnit(Sibling->getLocStart(),
- Child->getLocEnd()))
+ if (!SM.isBeforeInTranslationUnit(Sibling->getBeginLoc(),
+ Child->getEndLoc()))
break;
if (!BaseType::canIgnoreChildDeclWhileTraversingDeclContext(Sibling))
LexicallyNestedDeclarations.push_back(Sibling);
diff --git a/include/clang/AST/Mangle.h b/include/clang/AST/Mangle.h
index c42fe91b3246..309ed5a1a5d2 100644
--- a/include/clang/AST/Mangle.h
+++ b/include/clang/AST/Mangle.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_AST_MANGLE_H
#define LLVM_CLANG_AST_MANGLE_H
+#include "clang/AST/Decl.h"
#include "clang/AST/Type.h"
#include "clang/Basic/ABI.h"
#include "llvm/ADT/DenseMap.h"
diff --git a/include/clang/AST/NSAPI.h b/include/clang/AST/NSAPI.h
index bf2afe38cbca..f9340c64f3eb 100644
--- a/include/clang/AST/NSAPI.h
+++ b/include/clang/AST/NSAPI.h
@@ -166,6 +166,14 @@ public:
return getOrInitSelector(StringRef("isEqual"), isEqualSel);
}
+ Selector getNewSelector() const {
+ return getOrInitNullarySelector("new", NewSel);
+ }
+
+ Selector getInitSelector() const {
+ return getOrInitNullarySelector("init", InitSel);
+ }
+
/// Enumerates the NSNumber methods used to generate literals.
enum NSNumberLiteralMethodKind {
NSNumberWithChar,
@@ -229,6 +237,7 @@ private:
bool isObjCEnumerator(const Expr *E,
StringRef name, IdentifierInfo *&II) const;
Selector getOrInitSelector(ArrayRef<StringRef> Ids, Selector &Sel) const;
+ Selector getOrInitNullarySelector(StringRef Id, Selector &Sel) const;
ASTContext &Ctx;
@@ -251,7 +260,7 @@ private:
mutable Selector objectForKeyedSubscriptSel, objectAtIndexedSubscriptSel,
setObjectForKeyedSubscriptSel,setObjectAtIndexedSubscriptSel,
- isEqualSel;
+ isEqualSel, InitSel, NewSel;
mutable IdentifierInfo *BOOLId, *NSIntegerId, *NSUIntegerId;
mutable IdentifierInfo *NSASCIIStringEncodingId, *NSUTF8StringEncodingId;
diff --git a/include/clang/AST/NestedNameSpecifier.h b/include/clang/AST/NestedNameSpecifier.h
index 3a7b45767dac..8befe9ae4258 100644
--- a/include/clang/AST/NestedNameSpecifier.h
+++ b/include/clang/AST/NestedNameSpecifier.h
@@ -212,9 +212,12 @@ public:
/// parameter pack (for C++11 variadic templates).
bool containsUnexpandedParameterPack() const;
- /// Print this nested name specifier to the given output
- /// stream.
- void print(raw_ostream &OS, const PrintingPolicy &Policy) const;
+ /// Print this nested name specifier to the given output stream. If
+ /// `ResolveTemplateArguments` is true, we'll print actual types, e.g.
+ /// `ns::SomeTemplate<int, MyClass>` instead of
+ /// `ns::SomeTemplate<Container::value_type, T>`.
+ void print(raw_ostream &OS, const PrintingPolicy &Policy,
+ bool ResolveTemplateArguments = false) const;
void Profile(llvm::FoldingSetNodeID &ID) const {
ID.AddPointer(Prefix.getOpaqueValue());
@@ -225,6 +228,8 @@ public:
/// in debugging.
void dump(const LangOptions &LO) const;
void dump() const;
+ void dump(llvm::raw_ostream &OS) const;
+ void dump(llvm::raw_ostream &OS, const LangOptions &LO) const;
};
/// A C++ nested-name-specifier augmented with source location
diff --git a/include/clang/AST/ODRHash.h b/include/clang/AST/ODRHash.h
index 75b361789211..feaa83844a1a 100644
--- a/include/clang/AST/ODRHash.h
+++ b/include/clang/AST/ODRHash.h
@@ -13,6 +13,9 @@
///
//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_AST_ODRHASH_H
+#define LLVM_CLANG_AST_ODRHASH_H
+
#include "clang/AST/DeclarationName.h"
#include "clang/AST/Type.h"
#include "clang/AST/TemplateBase.h"
@@ -80,7 +83,7 @@ public:
void AddIdentifierInfo(const IdentifierInfo *II);
void AddNestedNameSpecifier(const NestedNameSpecifier *NNS);
void AddTemplateName(TemplateName Name);
- void AddDeclarationName(DeclarationName Name);
+ void AddDeclarationName(DeclarationName Name, bool TreatAsDecl = false);
void AddTemplateArgument(TemplateArgument TA);
void AddTemplateParameterList(const TemplateParameterList *TPL);
@@ -88,6 +91,11 @@ public:
void AddBoolean(bool value);
static bool isWhitelistedDecl(const Decl* D, const DeclContext *Parent);
+
+private:
+ void AddDeclarationNameImpl(DeclarationName Name);
};
} // end namespace clang
+
+#endif
diff --git a/include/clang/Analysis/Analyses/OSLog.h b/include/clang/AST/OSLog.h
index 1e60a237b770..2b21855e7a6e 100644
--- a/include/clang/Analysis/Analyses/OSLog.h
+++ b/include/clang/AST/OSLog.h
@@ -52,7 +52,10 @@ public:
// The item is corresponding to the '%m' format specifier, no value is
// populated in the buffer and the runtime is loading the errno value.
- ErrnoKind
+ ErrnoKind,
+
+ // The item is a mask type.
+ MaskKind
};
enum {
@@ -60,7 +63,10 @@ public:
IsPrivate = 0x1,
// The item is marked "public" in the format string.
- IsPublic = 0x2
+ IsPublic = 0x2,
+
+ // The item is marked "sensitive" in the format string.
+ IsSensitive = 0x4 | IsPrivate
};
private:
@@ -69,21 +75,24 @@ private:
CharUnits ConstValue;
CharUnits Size; // size of the data, not including the header bytes
unsigned Flags = 0;
+ StringRef MaskType;
public:
- OSLogBufferItem(Kind kind, const Expr *expr, CharUnits size, unsigned flags)
- : TheKind(kind), TheExpr(expr), Size(size), Flags(flags) {}
+ OSLogBufferItem(Kind kind, const Expr *expr, CharUnits size, unsigned flags,
+ StringRef maskType = StringRef())
+ : TheKind(kind), TheExpr(expr), Size(size), Flags(flags),
+ MaskType(maskType) {
+ assert(((Flags == 0) || (Flags == IsPrivate) || (Flags == IsPublic) ||
+ (Flags == IsSensitive)) &&
+ "unexpected privacy flag");
+ }
OSLogBufferItem(ASTContext &Ctx, CharUnits value, unsigned flags)
: TheKind(CountKind), ConstValue(value),
Size(Ctx.getTypeSizeInChars(Ctx.IntTy)), Flags(flags) {}
unsigned char getDescriptorByte() const {
- unsigned char result = 0;
- if (getIsPrivate())
- result |= IsPrivate;
- if (getIsPublic())
- result |= IsPublic;
+ unsigned char result = Flags;
result |= ((unsigned)getKind()) << 4;
return result;
}
@@ -92,11 +101,12 @@ public:
Kind getKind() const { return TheKind; }
bool getIsPrivate() const { return (Flags & IsPrivate) != 0; }
- bool getIsPublic() const { return (Flags & IsPublic) != 0; }
const Expr *getExpr() const { return TheExpr; }
CharUnits getConstValue() const { return ConstValue; }
CharUnits size() const { return Size; }
+
+ StringRef getMaskType() const { return MaskType; }
};
class OSLogBufferLayout {
@@ -120,14 +130,10 @@ public:
Items, [](const OSLogBufferItem &Item) { return Item.getIsPrivate(); });
}
- bool hasPublicItems() const {
- return llvm::any_of(
- Items, [](const OSLogBufferItem &Item) { return Item.getIsPublic(); });
- }
-
- bool hasNonScalar() const {
+ bool hasNonScalarOrMask() const {
return llvm::any_of(Items, [](const OSLogBufferItem &Item) {
- return Item.getKind() != OSLogBufferItem::ScalarKind;
+ return Item.getKind() != OSLogBufferItem::ScalarKind ||
+ !Item.getMaskType().empty();
});
}
@@ -135,7 +141,7 @@ public:
unsigned char result = 0;
if (hasPrivateItems())
result |= HasPrivateItems;
- if (hasNonScalar())
+ if (hasNonScalarOrMask())
result |= HasNonScalarItems;
return result;
}
diff --git a/include/clang/AST/OpenMPClause.h b/include/clang/AST/OpenMPClause.h
index a28609f8cdf9..bdcdf74b2630 100644
--- a/include/clang/AST/OpenMPClause.h
+++ b/include/clang/AST/OpenMPClause.h
@@ -64,10 +64,10 @@ protected:
public:
/// Returns the starting location of the clause.
- SourceLocation getLocStart() const { return StartLoc; }
+ SourceLocation getBeginLoc() const { return StartLoc; }
/// Returns the ending location of the clause.
- SourceLocation getLocEnd() const { return EndLoc; }
+ SourceLocation getEndLoc() const { return EndLoc; }
/// Sets the starting location of the clause.
void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
@@ -734,6 +734,210 @@ public:
}
};
+/// This represents 'unified_address' clause in the '#pragma omp requires'
+/// directive.
+///
+/// \code
+/// #pragma omp requires unified_address
+/// \endcode
+/// In this example directive '#pragma omp requires' has 'unified_address'
+/// clause.
+class OMPUnifiedAddressClause final : public OMPClause {
+public:
+ friend class OMPClauseReader;
+ /// Build 'unified_address' clause.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ OMPUnifiedAddressClause(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPClause(OMPC_unified_address, StartLoc, EndLoc) {}
+
+ /// Build an empty clause.
+ OMPUnifiedAddressClause()
+ : OMPClause(OMPC_unified_address, SourceLocation(), SourceLocation()) {}
+
+ child_range children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_unified_address;
+ }
+};
+
+/// This represents 'unified_shared_memory' clause in the '#pragma omp requires'
+/// directive.
+///
+/// \code
+/// #pragma omp requires unified_shared_memory
+/// \endcode
+/// In this example directive '#pragma omp requires' has 'unified_shared_memory'
+/// clause.
+class OMPUnifiedSharedMemoryClause final : public OMPClause {
+public:
+ friend class OMPClauseReader;
+ /// Build 'unified_shared_memory' clause.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ OMPUnifiedSharedMemoryClause(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPClause(OMPC_unified_shared_memory, StartLoc, EndLoc) {}
+
+ /// Build an empty clause.
+ OMPUnifiedSharedMemoryClause()
+ : OMPClause(OMPC_unified_shared_memory, SourceLocation(), SourceLocation()) {}
+
+ child_range children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_unified_shared_memory;
+ }
+};
+
+/// This represents 'reverse_offload' clause in the '#pragma omp requires'
+/// directive.
+///
+/// \code
+/// #pragma omp requires reverse_offload
+/// \endcode
+/// In this example directive '#pragma omp requires' has 'reverse_offload'
+/// clause.
+class OMPReverseOffloadClause final : public OMPClause {
+public:
+ friend class OMPClauseReader;
+ /// Build 'reverse_offload' clause.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ OMPReverseOffloadClause(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPClause(OMPC_reverse_offload, StartLoc, EndLoc) {}
+
+ /// Build an empty clause.
+ OMPReverseOffloadClause()
+ : OMPClause(OMPC_reverse_offload, SourceLocation(), SourceLocation()) {}
+
+ child_range children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_reverse_offload;
+ }
+};
+
+/// This represents 'dynamic_allocators' clause in the '#pragma omp requires'
+/// directive.
+///
+/// \code
+/// #pragma omp requires dynamic_allocators
+/// \endcode
+/// In this example directive '#pragma omp requires' has 'dynamic_allocators'
+/// clause.
+class OMPDynamicAllocatorsClause final : public OMPClause {
+public:
+ friend class OMPClauseReader;
+ /// Build 'dynamic_allocators' clause.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ OMPDynamicAllocatorsClause(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPClause(OMPC_dynamic_allocators, StartLoc, EndLoc) {}
+
+ /// Build an empty clause.
+ OMPDynamicAllocatorsClause()
+ : OMPClause(OMPC_dynamic_allocators, SourceLocation(), SourceLocation()) {
+ }
+
+ child_range children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_dynamic_allocators;
+ }
+};
+
+/// This represents 'atomic_default_mem_order' clause in the '#pragma omp
+/// requires' directive.
+///
+/// \code
+/// #pragma omp requires atomic_default_mem_order(seq_cst)
+/// \endcode
+/// In this example directive '#pragma omp requires' has simple
+/// atomic_default_mem_order' clause with kind 'seq_cst'.
+class OMPAtomicDefaultMemOrderClause final : public OMPClause {
+ friend class OMPClauseReader;
+
+ /// Location of '('
+ SourceLocation LParenLoc;
+
+ /// A kind of the 'atomic_default_mem_order' clause.
+ OpenMPAtomicDefaultMemOrderClauseKind Kind =
+ OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown;
+
+ /// Start location of the kind in source code.
+ SourceLocation KindKwLoc;
+
+ /// Set kind of the clause.
+ ///
+ /// \param K Kind of clause.
+ void setAtomicDefaultMemOrderKind(OpenMPAtomicDefaultMemOrderClauseKind K) {
+ Kind = K;
+ }
+
+ /// Set clause kind location.
+ ///
+ /// \param KLoc Kind location.
+ void setAtomicDefaultMemOrderKindKwLoc(SourceLocation KLoc) {
+ KindKwLoc = KLoc;
+ }
+
+public:
+ /// Build 'atomic_default_mem_order' clause with argument \a A ('seq_cst',
+ /// 'acq_rel' or 'relaxed').
+ ///
+ /// \param A Argument of the clause ('seq_cst', 'acq_rel' or 'relaxed').
+ /// \param ALoc Starting location of the argument.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ OMPAtomicDefaultMemOrderClause(OpenMPAtomicDefaultMemOrderClauseKind A,
+ SourceLocation ALoc, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc)
+ : OMPClause(OMPC_atomic_default_mem_order, StartLoc, EndLoc),
+ LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {}
+
+ /// Build an empty clause.
+ OMPAtomicDefaultMemOrderClause()
+ : OMPClause(OMPC_atomic_default_mem_order, SourceLocation(),
+ SourceLocation()) {}
+
+ /// Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
+ /// Returns the locaiton of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ /// Returns kind of the clause.
+ OpenMPAtomicDefaultMemOrderClauseKind getAtomicDefaultMemOrderKind() const {
+ return Kind;
+ }
+
+ /// Returns location of clause kind.
+ SourceLocation getAtomicDefaultMemOrderKindKwLoc() const { return KindKwLoc; }
+
+ child_range children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_atomic_default_mem_order;
+ }
+};
+
/// This represents 'schedule' clause in the '#pragma omp ...' directive.
///
/// \code
@@ -922,8 +1126,11 @@ public:
/// \endcode
/// In this example directive '#pragma omp for' has 'ordered' clause with
/// parameter 2.
-class OMPOrderedClause : public OMPClause {
+class OMPOrderedClause final
+ : public OMPClause,
+ private llvm::TrailingObjects<OMPOrderedClause, Expr *> {
friend class OMPClauseReader;
+ friend TrailingObjects;
/// Location of '('.
SourceLocation LParenLoc;
@@ -931,6 +1138,26 @@ class OMPOrderedClause : public OMPClause {
/// Number of for-loops.
Stmt *NumForLoops = nullptr;
+ /// Real number of loops.
+ unsigned NumberOfLoops = 0;
+
+ /// Build 'ordered' clause.
+ ///
+ /// \param Num Expression, possibly associated with this clause.
+ /// \param NumLoops Number of loops, associated with this clause.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ OMPOrderedClause(Expr *Num, unsigned NumLoops, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation EndLoc)
+ : OMPClause(OMPC_ordered, StartLoc, EndLoc), LParenLoc(LParenLoc),
+ NumForLoops(Num), NumberOfLoops(NumLoops) {}
+
+ /// Build an empty clause.
+ explicit OMPOrderedClause(unsigned NumLoops)
+ : OMPClause(OMPC_ordered, SourceLocation(), SourceLocation()),
+ NumberOfLoops(NumLoops) {}
+
/// Set the number of associated for-loops.
void setNumForLoops(Expr *Num) { NumForLoops = Num; }
@@ -938,17 +1165,17 @@ public:
/// Build 'ordered' clause.
///
/// \param Num Expression, possibly associated with this clause.
+ /// \param NumLoops Number of loops, associated with this clause.
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
- OMPOrderedClause(Expr *Num, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_ordered, StartLoc, EndLoc), LParenLoc(LParenLoc),
- NumForLoops(Num) {}
+ static OMPOrderedClause *Create(const ASTContext &C, Expr *Num,
+ unsigned NumLoops, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc);
/// Build an empty clause.
- explicit OMPOrderedClause()
- : OMPClause(OMPC_ordered, SourceLocation(), SourceLocation()) {}
+ static OMPOrderedClause* CreateEmpty(const ASTContext &C, unsigned NumLoops);
/// Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
@@ -959,6 +1186,17 @@ public:
/// Return the number of associated for-loops.
Expr *getNumForLoops() const { return cast_or_null<Expr>(NumForLoops); }
+ /// Set number of iterations for the specified loop.
+ void setLoopNumIterations(unsigned NumLoop, Expr *NumIterations);
+ /// Get number of iterations for all the loops.
+ ArrayRef<Expr *> getLoopNumIterations() const;
+
+ /// Set loop counter for the specified loop.
+ void setLoopCounter(unsigned NumLoop, Expr *Counter);
+ /// Get loops counter for the specified loop.
+ Expr *getLoopCounter(unsigned NumLoop);
+ const Expr *getLoopCounter(unsigned NumLoop) const;
+
child_range children() { return child_range(&NumForLoops, &NumForLoops + 1); }
static bool classof(const OMPClause *T) {
@@ -3087,24 +3325,32 @@ class OMPDependClause final
/// Colon location.
SourceLocation ColonLoc;
+ /// Number of loops, associated with the depend clause.
+ unsigned NumLoops = 0;
+
/// Build clause with number of variables \a N.
///
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
/// \param N Number of the variables in the clause.
+ /// \param NumLoops Number of loops that is associated with this depend
+ /// clause.
OMPDependClause(SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, unsigned N)
+ SourceLocation EndLoc, unsigned N, unsigned NumLoops)
: OMPVarListClause<OMPDependClause>(OMPC_depend, StartLoc, LParenLoc,
- EndLoc, N) {}
+ EndLoc, N), NumLoops(NumLoops) {}
/// Build an empty clause.
///
/// \param N Number of variables.
- explicit OMPDependClause(unsigned N)
+ /// \param NumLoops Number of loops that is associated with this depend
+ /// clause.
+ explicit OMPDependClause(unsigned N, unsigned NumLoops)
: OMPVarListClause<OMPDependClause>(OMPC_depend, SourceLocation(),
SourceLocation(), SourceLocation(),
- N) {}
+ N),
+ NumLoops(NumLoops) {}
/// Set dependency kind.
void setDependencyKind(OpenMPDependClauseKind K) { DepKind = K; }
@@ -3126,16 +3372,23 @@ public:
/// \param DepLoc Location of the dependency type.
/// \param ColonLoc Colon location.
/// \param VL List of references to the variables.
- static OMPDependClause *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, OpenMPDependClauseKind DepKind,
- SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL);
+ /// \param NumLoops Number of loops that is associated with this depend
+ /// clause.
+ static OMPDependClause *Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc,
+ OpenMPDependClauseKind DepKind,
+ SourceLocation DepLoc, SourceLocation ColonLoc,
+ ArrayRef<Expr *> VL, unsigned NumLoops);
/// Creates an empty clause with \a N variables.
///
/// \param C AST context.
/// \param N The number of variables.
- static OMPDependClause *CreateEmpty(const ASTContext &C, unsigned N);
+ /// \param NumLoops Number of loops that is associated with this depend
+ /// clause.
+ static OMPDependClause *CreateEmpty(const ASTContext &C, unsigned N,
+ unsigned NumLoops);
/// Get dependency type.
OpenMPDependClauseKind getDependencyKind() const { return DepKind; }
@@ -3146,15 +3399,16 @@ public:
/// Get colon location.
SourceLocation getColonLoc() const { return ColonLoc; }
- /// Set the loop counter value for the depend clauses with 'sink|source' kind
- /// of dependency. Required for codegen.
- void setCounterValue(Expr *V);
+ /// Get number of loops associated with the clause.
+ unsigned getNumLoops() const { return NumLoops; }
- /// Get the loop counter value.
- Expr *getCounterValue();
+ /// Set the loop data for the depend clauses with 'sink|source' kind of
+ /// dependency.
+ void setLoopData(unsigned NumLoop, Expr *Cnt);
- /// Get the loop counter value.
- const Expr *getCounterValue() const;
+ /// Get the loop data.
+ Expr *getLoopData(unsigned NumLoop);
+ const Expr *getLoopData(unsigned NumLoop) const;
child_range children() {
return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
@@ -3807,8 +4061,19 @@ class OMPMapClause final : public OMPMappableExprListClause<OMPMapClause>,
return getUniqueDeclarationsNum() + getTotalComponentListNum();
}
- /// Map type modifier for the 'map' clause.
- OpenMPMapClauseKind MapTypeModifier = OMPC_MAP_unknown;
+public:
+ /// Number of allowed map-type-modifiers.
+ static constexpr unsigned NumberOfModifiers =
+ OMPC_MAP_MODIFIER_last - OMPC_MAP_MODIFIER_unknown - 1;
+
+private:
+ /// Map-type-modifiers for the 'map' clause.
+ OpenMPMapModifierKind MapTypeModifiers[NumberOfModifiers] = {
+ OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown
+ };
+
+ /// Location of map-type-modifiers for the 'map' clause.
+ SourceLocation MapTypeModifiersLoc[NumberOfModifiers];
/// Map type for the 'map' clause.
OpenMPMapClauseKind MapType = OMPC_MAP_unknown;
@@ -3826,7 +4091,8 @@ class OMPMapClause final : public OMPMappableExprListClause<OMPMapClause>,
/// NumUniqueDeclarations declarations, \a NumComponentLists total component
/// lists, and \a NumComponents total expression components.
///
- /// \param MapTypeModifier Map type modifier.
+ /// \param MapModifiers Map-type-modifiers.
+ /// \param MapModifiersLoc Locations of map-type-modifiers.
/// \param MapType Map type.
/// \param MapTypeIsImplicit Map type is inferred implicitly.
/// \param MapLoc Location of the map type.
@@ -3837,7 +4103,8 @@ class OMPMapClause final : public OMPMappableExprListClause<OMPMapClause>,
/// clause.
/// \param NumComponentLists Number of component lists in this clause.
/// \param NumComponents Total number of expression components in the clause.
- explicit OMPMapClause(OpenMPMapClauseKind MapTypeModifier,
+ explicit OMPMapClause(ArrayRef<OpenMPMapModifierKind> MapModifiers,
+ ArrayRef<SourceLocation> MapModifiersLoc,
OpenMPMapClauseKind MapType, bool MapTypeIsImplicit,
SourceLocation MapLoc, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation EndLoc,
@@ -3846,8 +4113,17 @@ class OMPMapClause final : public OMPMappableExprListClause<OMPMapClause>,
: OMPMappableExprListClause(OMPC_map, StartLoc, LParenLoc, EndLoc,
NumVars, NumUniqueDeclarations,
NumComponentLists, NumComponents),
- MapTypeModifier(MapTypeModifier), MapType(MapType),
- MapTypeIsImplicit(MapTypeIsImplicit), MapLoc(MapLoc) {}
+ MapType(MapType), MapTypeIsImplicit(MapTypeIsImplicit),
+ MapLoc(MapLoc) {
+ assert(llvm::array_lengthof(MapTypeModifiers) == MapModifiers.size()
+ && "Unexpected number of map type modifiers.");
+ llvm::copy(MapModifiers, std::begin(MapTypeModifiers));
+
+ assert(llvm::array_lengthof(MapTypeModifiersLoc) ==
+ MapModifiersLoc.size() &&
+ "Unexpected number of map type modifier locations.");
+ llvm::copy(MapModifiersLoc, std::begin(MapTypeModifiersLoc));
+ }
/// Build an empty clause.
///
@@ -3862,10 +4138,25 @@ class OMPMapClause final : public OMPMappableExprListClause<OMPMapClause>,
OMPC_map, SourceLocation(), SourceLocation(), SourceLocation(),
NumVars, NumUniqueDeclarations, NumComponentLists, NumComponents) {}
- /// Set type modifier for the clause.
+ /// Set map-type-modifier for the clause.
+ ///
+ /// \param I index for map-type-modifier.
+ /// \param T map-type-modifier for the clause.
+ void setMapTypeModifier(unsigned I, OpenMPMapModifierKind T) {
+ assert(I < NumberOfModifiers &&
+ "Unexpected index to store map type modifier, exceeds array size.");
+ MapTypeModifiers[I] = T;
+ }
+
+ /// Set location for the map-type-modifier.
///
- /// \param T Type Modifier for the clause.
- void setMapTypeModifier(OpenMPMapClauseKind T) { MapTypeModifier = T; }
+ /// \param I index for map-type-modifier location.
+ /// \param TLoc map-type-modifier location.
+ void setMapTypeModifierLoc(unsigned I, SourceLocation TLoc) {
+ assert(I < NumberOfModifiers &&
+ "Index to store map type modifier location exceeds array size.");
+ MapTypeModifiersLoc[I] = TLoc;
+ }
/// Set type for the clause.
///
@@ -3889,7 +4180,8 @@ public:
/// \param Vars The original expression used in the clause.
/// \param Declarations Declarations used in the clause.
/// \param ComponentLists Component lists used in the clause.
- /// \param TypeModifier Map type modifier.
+ /// \param MapModifiers Map-type-modifiers.
+ /// \param MapModifiersLoc Location of map-type-modifiers.
/// \param Type Map type.
/// \param TypeIsImplicit Map type is inferred implicitly.
/// \param TypeLoc Location of the map type.
@@ -3898,7 +4190,8 @@ public:
ArrayRef<Expr *> Vars,
ArrayRef<ValueDecl *> Declarations,
MappableExprComponentListsRef ComponentLists,
- OpenMPMapClauseKind TypeModifier,
+ ArrayRef<OpenMPMapModifierKind> MapModifiers,
+ ArrayRef<SourceLocation> MapModifiersLoc,
OpenMPMapClauseKind Type, bool TypeIsImplicit,
SourceLocation TypeLoc);
@@ -3928,9 +4221,33 @@ public:
/// messages for some target directives.
bool isImplicitMapType() const LLVM_READONLY { return MapTypeIsImplicit; }
- /// Fetches the map type modifier for the clause.
- OpenMPMapClauseKind getMapTypeModifier() const LLVM_READONLY {
- return MapTypeModifier;
+ /// Fetches the map-type-modifier at 'Cnt' index of array of modifiers.
+ ///
+ /// \param Cnt index for map-type-modifier.
+ OpenMPMapModifierKind getMapTypeModifier(unsigned Cnt) const LLVM_READONLY {
+ assert(Cnt < NumberOfModifiers &&
+ "Requested modifier exceeds the total number of modifiers.");
+ return MapTypeModifiers[Cnt];
+ }
+
+ /// Fetches the map-type-modifier location at 'Cnt' index of array of
+ /// modifiers' locations.
+ ///
+ /// \param Cnt index for map-type-modifier location.
+ SourceLocation getMapTypeModifierLoc(unsigned Cnt) const LLVM_READONLY {
+ assert(Cnt < NumberOfModifiers &&
+ "Requested modifier location exceeds total number of modifiers.");
+ return MapTypeModifiersLoc[Cnt];
+ }
+
+ /// Fetches ArrayRef of map-type-modifiers.
+ ArrayRef<OpenMPMapModifierKind> getMapTypeModifiers() const LLVM_READONLY {
+ return llvm::makeArrayRef(MapTypeModifiers);
+ }
+
+ /// Fetches ArrayRef of location of map-type-modifiers.
+ ArrayRef<SourceLocation> getMapTypeModifiersLoc() const LLVM_READONLY {
+ return llvm::makeArrayRef(MapTypeModifiersLoc);
}
/// Fetches location of clause mapping kind.
@@ -4991,6 +5308,59 @@ public:
}
};
+/// This class implements a simple visitor for OMPClause
+/// subclasses.
+template<class ImplClass, template <typename> class Ptr, typename RetTy>
+class OMPClauseVisitorBase {
+public:
+#define PTR(CLASS) typename Ptr<CLASS>::type
+#define DISPATCH(CLASS) \
+ return static_cast<ImplClass*>(this)->Visit##CLASS(static_cast<PTR(CLASS)>(S))
+
+#define OPENMP_CLAUSE(Name, Class) \
+ RetTy Visit ## Class (PTR(Class) S) { DISPATCH(Class); }
+#include "clang/Basic/OpenMPKinds.def"
+
+ RetTy Visit(PTR(OMPClause) S) {
+ // Top switch clause: visit each OMPClause.
+ switch (S->getClauseKind()) {
+ default: llvm_unreachable("Unknown clause kind!");
+#define OPENMP_CLAUSE(Name, Class) \
+ case OMPC_ ## Name : return Visit ## Class(static_cast<PTR(Class)>(S));
+#include "clang/Basic/OpenMPKinds.def"
+ }
+ }
+ // Base case, ignore it. :)
+ RetTy VisitOMPClause(PTR(OMPClause) Node) { return RetTy(); }
+#undef PTR
+#undef DISPATCH
+};
+
+template <typename T>
+using const_ptr = typename std::add_pointer<typename std::add_const<T>::type>;
+
+template<class ImplClass, typename RetTy = void>
+class OMPClauseVisitor :
+ public OMPClauseVisitorBase <ImplClass, std::add_pointer, RetTy> {};
+template<class ImplClass, typename RetTy = void>
+class ConstOMPClauseVisitor :
+ public OMPClauseVisitorBase <ImplClass, const_ptr, RetTy> {};
+
+class OMPClausePrinter final : public OMPClauseVisitor<OMPClausePrinter> {
+ raw_ostream &OS;
+ const PrintingPolicy &Policy;
+
+ /// Process clauses with list of variables.
+ template <typename T> void VisitOMPClauseList(T *Node, char StartSym);
+
+public:
+ OMPClausePrinter(raw_ostream &OS, const PrintingPolicy &Policy)
+ : OS(OS), Policy(Policy) {}
+
+#define OPENMP_CLAUSE(Name, Class) void Visit##Class(Class *S);
+#include "clang/Basic/OpenMPKinds.def"
+};
+
} // namespace clang
#endif // LLVM_CLANG_AST_OPENMPCLAUSE_H
diff --git a/include/clang/AST/OperationKinds.def b/include/clang/AST/OperationKinds.def
index e2d65d84880c..cd19091e31d6 100644
--- a/include/clang/AST/OperationKinds.def
+++ b/include/clang/AST/OperationKinds.def
@@ -197,6 +197,14 @@ CAST_OPERATION(IntegralToBoolean)
/// float f = i;
CAST_OPERATION(IntegralToFloating)
+/// CK_FixedPointCast - Fixed point to fixed point.
+/// (_Accum) 0.5r
+CAST_OPERATION(FixedPointCast)
+
+/// CK_FixedPointToBoolean - Fixed point to boolean.
+/// (bool) 0.5r
+CAST_OPERATION(FixedPointToBoolean)
+
/// CK_FloatingToIntegral - Floating point to integral. Rounds
/// towards zero, discarding any fractional component.
/// (int) f
@@ -318,11 +326,9 @@ CAST_OPERATION(CopyAndAutoreleaseBlockObject)
// callee of a call expression.
CAST_OPERATION(BuiltinFnToFnPtr)
-// Convert a zero value for OpenCL event_t initialization.
-CAST_OPERATION(ZeroToOCLEvent)
-
-// Convert a zero value for OpenCL queue_t initialization.
-CAST_OPERATION(ZeroToOCLQueue)
+// Convert a zero value for OpenCL opaque types initialization (event_t,
+// queue_t, etc.)
+CAST_OPERATION(ZeroToOCLOpaqueType)
// Convert a pointer to a different address space.
CAST_OPERATION(AddressSpaceConversion)
diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h
index b49f5be1b1e6..3c877f5ea19c 100644
--- a/include/clang/AST/PrettyPrinter.h
+++ b/include/clang/AST/PrettyPrinter.h
@@ -38,21 +38,20 @@ public:
struct PrintingPolicy {
/// Create a default printing policy for the specified language.
PrintingPolicy(const LangOptions &LO)
- : Indentation(2), SuppressSpecifiers(false),
- SuppressTagKeyword(LO.CPlusPlus),
- IncludeTagDefinition(false), SuppressScope(false),
- SuppressUnwrittenScope(false), SuppressInitializers(false),
- ConstantArraySizeAsWritten(false), AnonymousTagLocations(true),
- SuppressStrongLifetime(false), SuppressLifetimeQualifiers(false),
- SuppressTemplateArgsInCXXConstructors(false),
- Bool(LO.Bool), Restrict(LO.C99),
- Alignof(LO.CPlusPlus11), UnderscoreAlignof(LO.C11),
- UseVoidForZeroParams(!LO.CPlusPlus),
- TerseOutput(false), PolishForDeclaration(false),
- Half(LO.Half), MSWChar(LO.MicrosoftExt && !LO.WChar),
- IncludeNewlines(true), MSVCFormatting(false),
- ConstantsAsWritten(false), SuppressImplicitBase(false),
- FullyQualifiedName(false) { }
+ : Indentation(2), SuppressSpecifiers(false),
+ SuppressTagKeyword(LO.CPlusPlus), IncludeTagDefinition(false),
+ SuppressScope(false), SuppressUnwrittenScope(false),
+ SuppressInitializers(false), ConstantArraySizeAsWritten(false),
+ AnonymousTagLocations(true), SuppressStrongLifetime(false),
+ SuppressLifetimeQualifiers(false),
+ SuppressTemplateArgsInCXXConstructors(false), Bool(LO.Bool),
+ Restrict(LO.C99), Alignof(LO.CPlusPlus11), UnderscoreAlignof(LO.C11),
+ UseVoidForZeroParams(!LO.CPlusPlus), TerseOutput(false),
+ PolishForDeclaration(false), Half(LO.Half),
+ MSWChar(LO.MicrosoftExt && !LO.WChar), IncludeNewlines(true),
+ MSVCFormatting(false), ConstantsAsWritten(false),
+ SuppressImplicitBase(false), FullyQualifiedName(false),
+ RemapFilePaths(false), PrintCanonicalTypes(false) {}
/// Adjust this printing policy for cases where it's known that we're
/// printing C++ code (for instance, if AST dumping reaches a C++-only
@@ -81,7 +80,7 @@ struct PrintingPolicy {
/// declaration for "x", so that we will print "int *x"; it will be
/// \c true when we print "y", so that we suppress printing the
/// "const int" type specifier and instead only print the "*y".
- bool SuppressSpecifiers : 1;
+ unsigned SuppressSpecifiers : 1;
/// Whether type printing should skip printing the tag keyword.
///
@@ -91,7 +90,7 @@ struct PrintingPolicy {
/// \code
/// struct Geometry::Point;
/// \endcode
- bool SuppressTagKeyword : 1;
+ unsigned SuppressTagKeyword : 1;
/// When true, include the body of a tag definition.
///
@@ -101,14 +100,14 @@ struct PrintingPolicy {
/// \code
/// typedef struct { int x, y; } Point;
/// \endcode
- bool IncludeTagDefinition : 1;
+ unsigned IncludeTagDefinition : 1;
/// Suppresses printing of scope specifiers.
- bool SuppressScope : 1;
+ unsigned SuppressScope : 1;
/// Suppress printing parts of scope specifiers that don't need
/// to be written, e.g., for inline or anonymous namespaces.
- bool SuppressUnwrittenScope : 1;
+ unsigned SuppressUnwrittenScope : 1;
/// Suppress printing of variable initializers.
///
@@ -121,7 +120,7 @@ struct PrintingPolicy {
///
/// SuppressInitializers will be true when printing "auto x", so that the
/// internal initializer constructed for x will not be printed.
- bool SuppressInitializers : 1;
+ unsigned SuppressInitializers : 1;
/// Whether we should print the sizes of constant array expressions as written
/// in the sources.
@@ -139,12 +138,12 @@ struct PrintingPolicy {
/// int a[104];
/// char a[9] = "A string";
/// \endcode
- bool ConstantArraySizeAsWritten : 1;
+ unsigned ConstantArraySizeAsWritten : 1;
/// When printing an anonymous tag name, also print the location of that
/// entity (e.g., "enum <anonymous at t.h:10:5>"). Otherwise, just prints
/// "(anonymous)" for the name.
- bool AnonymousTagLocations : 1;
+ unsigned AnonymousTagLocations : 1;
/// When true, suppress printing of the __strong lifetime qualifier in ARC.
unsigned SuppressStrongLifetime : 1;
@@ -199,7 +198,7 @@ struct PrintingPolicy {
/// Use whitespace and punctuation like MSVC does. In particular, this prints
/// anonymous namespaces as `anonymous namespace' and does not insert spaces
/// after template arguments.
- bool MSVCFormatting : 1;
+ unsigned MSVCFormatting : 1;
/// Whether we should print the constant expressions as written in the
/// sources.
@@ -217,14 +216,23 @@ struct PrintingPolicy {
/// 0x10
/// 2.5e3
/// \endcode
- bool ConstantsAsWritten : 1;
+ unsigned ConstantsAsWritten : 1;
/// When true, don't print the implicit 'self' or 'this' expressions.
- bool SuppressImplicitBase : 1;
+ unsigned SuppressImplicitBase : 1;
/// When true, print the fully qualified name of function declarations.
/// This is the opposite of SuppressScope and thus overrules it.
- bool FullyQualifiedName : 1;
+ unsigned FullyQualifiedName : 1;
+
+ /// Whether to apply -fdebug-prefix-map to any file paths.
+ unsigned RemapFilePaths : 1;
+
+ /// Whether to print types as written or canonically.
+ unsigned PrintCanonicalTypes : 1;
+
+ /// When RemapFilePaths is true, this function performs the action.
+ std::function<std::string(StringRef)> remapPath;
};
} // end namespace clang
diff --git a/include/clang/AST/RawCommentList.h b/include/clang/AST/RawCommentList.h
index 8327efc750fd..d17c9df67e41 100644
--- a/include/clang/AST/RawCommentList.h
+++ b/include/clang/AST/RawCommentList.h
@@ -101,8 +101,8 @@ public:
}
SourceRange getSourceRange() const LLVM_READONLY { return Range; }
- SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
+ SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
const char *getBriefText(const ASTContext &Context) const {
if (BriefTextValid)
@@ -180,7 +180,7 @@ public:
explicit BeforeThanCompare(const SourceManager &SM) : SM(SM) { }
bool operator()(const RawComment &LHS, const RawComment &RHS) {
- return SM.isBeforeInTranslationUnit(LHS.getLocStart(), RHS.getLocStart());
+ return SM.isBeforeInTranslationUnit(LHS.getBeginLoc(), RHS.getBeginLoc());
}
bool operator()(const RawComment *LHS, const RawComment *RHS) {
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index 0d2b670507c1..44aba6355758 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -176,6 +176,16 @@ public:
/// Return whether this visitor should traverse post-order.
bool shouldTraversePostOrder() const { return false; }
+ /// Recursively visits an entire AST, starting from the top-level Decls
+ /// in the AST traversal scope (by default, the TranslationUnitDecl).
+ /// \returns false if visitation was terminated early.
+ bool TraverseAST(ASTContext &AST) {
+ for (Decl *D : AST.getTraversalScope())
+ if (!getDerived().TraverseDecl(D))
+ return false;
+ return true;
+ }
+
/// Recursively visit a statement or expression, by
/// dispatching to Traverse*() based on the argument's dynamic type.
///
@@ -288,14 +298,6 @@ public:
bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C,
Expr *Init);
- /// Recursively visit the body of a lambda expression.
- ///
- /// This provides a hook for visitors that need more context when visiting
- /// \c LE->getBody().
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseLambdaBody(LambdaExpr *LE, DataRecursionQueue *Queue = nullptr);
-
/// Recursively visit the syntactic or semantic form of an
/// initialization list.
///
@@ -926,13 +928,6 @@ RecursiveASTVisitor<Derived>::TraverseLambdaCapture(LambdaExpr *LE,
return true;
}
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseLambdaBody(
- LambdaExpr *LE, DataRecursionQueue *Queue) {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(LE->getBody());
- return true;
-}
-
// ----------------- Type traversal -----------------
// This macro makes available a variable T, the passed-in type.
@@ -1373,9 +1368,14 @@ DEF_TRAVERSE_TYPELOC(PipeType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
template <typename Derived>
bool RecursiveASTVisitor<Derived>::canIgnoreChildDeclWhileTraversingDeclContext(
const Decl *Child) {
- // BlockDecls and CapturedDecls are traversed through BlockExprs and
- // CapturedStmts respectively.
- return isa<BlockDecl>(Child) || isa<CapturedDecl>(Child);
+ // BlockDecls are traversed through BlockExprs,
+ // CapturedDecls are traversed through CapturedStmts.
+ if (isa<BlockDecl>(Child) || isa<CapturedDecl>(Child))
+ return true;
+ // Lambda classes are traversed through LambdaExprs.
+ if (const CXXRecordDecl* Cls = dyn_cast<CXXRecordDecl>(Child))
+ return Cls->isLambda();
+ return false;
}
template <typename Derived>
@@ -1589,6 +1589,12 @@ DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, {
for (auto *I : D->varlists()) {
TRY_TO(TraverseStmt(I));
}
+ })
+
+DEF_TRAVERSE_DECL(OMPRequiresDecl, {
+ for (auto *C : D->clauselists()) {
+ TRY_TO(TraverseOMPClause(C));
+ }
})
DEF_TRAVERSE_DECL(OMPDeclareReductionDecl, {
@@ -2174,6 +2180,8 @@ DEF_TRAVERSE_STMT(ObjCAutoreleasePoolStmt, {})
DEF_TRAVERSE_STMT(CXXForRangeStmt, {
if (!getDerived().shouldVisitImplicitCode()) {
+ if (S->getInit())
+ TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getInit());
TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getLoopVarStmt());
TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getRangeInit());
TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody());
@@ -2191,6 +2199,8 @@ DEF_TRAVERSE_STMT(ReturnStmt, {})
DEF_TRAVERSE_STMT(SwitchStmt, {})
DEF_TRAVERSE_STMT(WhileStmt, {})
+DEF_TRAVERSE_STMT(ConstantExpr, {})
+
DEF_TRAVERSE_STMT(CXXDependentScopeMemberExpr, {
TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
@@ -2384,6 +2394,7 @@ DEF_TRAVERSE_STMT(CXXTemporaryObjectExpr, {
// Walk only the visible parts of lambda expressions.
DEF_TRAVERSE_STMT(LambdaExpr, {
+ // Visit the capture list.
for (unsigned I = 0, N = S->capture_size(); I != N; ++I) {
const LambdaCapture *C = S->capture_begin() + I;
if (C->isExplicit() || getDerived().shouldVisitImplicitCode()) {
@@ -2391,32 +2402,31 @@ DEF_TRAVERSE_STMT(LambdaExpr, {
}
}
- TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
- FunctionProtoTypeLoc Proto = TL.getAsAdjusted<FunctionProtoTypeLoc>();
-
- if (S->hasExplicitParameters() && S->hasExplicitResultType()) {
- // Visit the whole type.
- TRY_TO(TraverseTypeLoc(TL));
+ if (getDerived().shouldVisitImplicitCode()) {
+ // The implicit model is simple: everything else is in the lambda class.
+ TRY_TO(TraverseDecl(S->getLambdaClass()));
} else {
+ // We need to poke around to find the bits that might be explicitly written.
+ TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
+ FunctionProtoTypeLoc Proto = TL.getAsAdjusted<FunctionProtoTypeLoc>();
+
if (S->hasExplicitParameters()) {
// Visit parameters.
- for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I) {
+ for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
TRY_TO(TraverseDecl(Proto.getParam(I)));
- }
- } else if (S->hasExplicitResultType()) {
- TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
}
+ if (S->hasExplicitResultType())
+ TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
auto *T = Proto.getTypePtr();
- for (const auto &E : T->exceptions()) {
+ for (const auto &E : T->exceptions())
TRY_TO(TraverseType(E));
- }
if (Expr *NE = T->getNoexceptExpr())
TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(NE);
- }
- ReturnValue = TRAVERSE_STMT_BASE(LambdaBody, LambdaExpr, S, Queue);
+ TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody());
+ }
ShouldVisitChildren = false;
})
@@ -2854,6 +2864,36 @@ bool RecursiveASTVisitor<Derived>::VisitOMPProcBindClause(OMPProcBindClause *) {
}
template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPUnifiedAddressClause(
+ OMPUnifiedAddressClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPUnifiedSharedMemoryClause(
+ OMPUnifiedSharedMemoryClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPReverseOffloadClause(
+ OMPReverseOffloadClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPDynamicAllocatorsClause(
+ OMPDynamicAllocatorsClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPAtomicDefaultMemOrderClause(
+ OMPAtomicDefaultMemOrderClause *) {
+ return true;
+}
+
+template <typename Derived>
bool
RecursiveASTVisitor<Derived>::VisitOMPScheduleClause(OMPScheduleClause *C) {
TRY_TO(VisitOMPClauseWithPreInit(C));
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index aa0f88b71023..ff5baa21adff 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -89,6 +89,8 @@ protected:
llvm_unreachable("Stmts cannot be released with regular 'delete'.");
}
+ //===--- Statement bitfields classes ---===//
+
class StmtBitfields {
friend class Stmt;
@@ -97,22 +99,186 @@ protected:
};
enum { NumStmtBits = 8 };
+ class NullStmtBitfields {
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+ friend class NullStmt;
+
+ unsigned : NumStmtBits;
+
+ /// True if the null statement was preceded by an empty macro, e.g:
+ /// @code
+ /// #define CALL(x)
+ /// CALL(0);
+ /// @endcode
+ unsigned HasLeadingEmptyMacro : 1;
+
+ /// The location of the semi-colon.
+ SourceLocation SemiLoc;
+ };
+
class CompoundStmtBitfields {
+ friend class ASTStmtReader;
friend class CompoundStmt;
unsigned : NumStmtBits;
unsigned NumStmts : 32 - NumStmtBits;
+
+ /// The location of the opening "{".
+ SourceLocation LBraceLoc;
+ };
+
+ class LabelStmtBitfields {
+ friend class LabelStmt;
+
+ unsigned : NumStmtBits;
+
+ SourceLocation IdentLoc;
+ };
+
+ class AttributedStmtBitfields {
+ friend class ASTStmtReader;
+ friend class AttributedStmt;
+
+ unsigned : NumStmtBits;
+
+ /// Number of attributes.
+ unsigned NumAttrs : 32 - NumStmtBits;
+
+ /// The location of the attribute.
+ SourceLocation AttrLoc;
};
class IfStmtBitfields {
+ friend class ASTStmtReader;
friend class IfStmt;
unsigned : NumStmtBits;
+ /// True if this if statement is a constexpr if.
unsigned IsConstexpr : 1;
+
+ /// True if this if statement has storage for an else statement.
+ unsigned HasElse : 1;
+
+ /// True if this if statement has storage for a variable declaration.
+ unsigned HasVar : 1;
+
+ /// True if this if statement has storage for an init statement.
+ unsigned HasInit : 1;
+
+ /// The location of the "if".
+ SourceLocation IfLoc;
+ };
+
+ class SwitchStmtBitfields {
+ friend class SwitchStmt;
+
+ unsigned : NumStmtBits;
+
+ /// True if the SwitchStmt has storage for an init statement.
+ unsigned HasInit : 1;
+
+ /// True if the SwitchStmt has storage for a condition variable.
+ unsigned HasVar : 1;
+
+ /// If the SwitchStmt is a switch on an enum value, records whether all
+ /// the enum values were covered by CaseStmts. The coverage information
+ /// value is meant to be a hint for possible clients.
+ unsigned AllEnumCasesCovered : 1;
+
+ /// The location of the "switch".
+ SourceLocation SwitchLoc;
+ };
+
+ class WhileStmtBitfields {
+ friend class ASTStmtReader;
+ friend class WhileStmt;
+
+ unsigned : NumStmtBits;
+
+ /// True if the WhileStmt has storage for a condition variable.
+ unsigned HasVar : 1;
+
+ /// The location of the "while".
+ SourceLocation WhileLoc;
+ };
+
+ class DoStmtBitfields {
+ friend class DoStmt;
+
+ unsigned : NumStmtBits;
+
+ /// The location of the "do".
+ SourceLocation DoLoc;
+ };
+
+ class ForStmtBitfields {
+ friend class ForStmt;
+
+ unsigned : NumStmtBits;
+
+ /// The location of the "for".
+ SourceLocation ForLoc;
+ };
+
+ class GotoStmtBitfields {
+ friend class GotoStmt;
+ friend class IndirectGotoStmt;
+
+ unsigned : NumStmtBits;
+
+ /// The location of the "goto".
+ SourceLocation GotoLoc;
+ };
+
+ class ContinueStmtBitfields {
+ friend class ContinueStmt;
+
+ unsigned : NumStmtBits;
+
+ /// The location of the "continue".
+ SourceLocation ContinueLoc;
+ };
+
+ class BreakStmtBitfields {
+ friend class BreakStmt;
+
+ unsigned : NumStmtBits;
+
+ /// The location of the "break".
+ SourceLocation BreakLoc;
+ };
+
+ class ReturnStmtBitfields {
+ friend class ReturnStmt;
+
+ unsigned : NumStmtBits;
+
+ /// True if this ReturnStmt has storage for an NRVO candidate.
+ unsigned HasNRVOCandidate : 1;
+
+ /// The location of the "return".
+ SourceLocation RetLoc;
+ };
+
+ class SwitchCaseBitfields {
+ friend class SwitchCase;
+ friend class CaseStmt;
+
+ unsigned : NumStmtBits;
+
+ /// Used by CaseStmt to store whether it is a case statement
+ /// of the form case LHS ... RHS (a GNU extension).
+ unsigned CaseStmtIsGNURange : 1;
+
+ /// The location of the "case" or "default" keyword.
+ SourceLocation KeywordLoc;
};
+ //===--- Expression bitfields classes ---===//
+
class ExprBitfields {
friend class ASTStmtReader; // deserialization
friend class AtomicExpr; // ctor
@@ -146,14 +312,40 @@ protected:
unsigned InstantiationDependent : 1;
unsigned ContainsUnexpandedParameterPack : 1;
};
- enum { NumExprBits = 17 };
+ enum { NumExprBits = NumStmtBits + 9 };
- class CharacterLiteralBitfields {
- friend class CharacterLiteral;
+ class PredefinedExprBitfields {
+ friend class ASTStmtReader;
+ friend class PredefinedExpr;
unsigned : NumExprBits;
- unsigned Kind : 3;
+ /// The kind of this PredefinedExpr. One of the enumeration values
+ /// in PredefinedExpr::IdentKind.
+ unsigned Kind : 4;
+
+ /// True if this PredefinedExpr has a trailing "StringLiteral *"
+ /// for the predefined identifier.
+ unsigned HasFunctionName : 1;
+
+ /// The location of this PredefinedExpr.
+ SourceLocation Loc;
+ };
+
+ class DeclRefExprBitfields {
+ friend class ASTStmtReader; // deserialization
+ friend class DeclRefExpr;
+
+ unsigned : NumExprBits;
+
+ unsigned HasQualifier : 1;
+ unsigned HasTemplateKWAndArgsInfo : 1;
+ unsigned HasFoundDecl : 1;
+ unsigned HadMultipleCandidates : 1;
+ unsigned RefersToEnclosingVariableOrCapture : 1;
+
+ /// The location of the declaration name itself.
+ SourceLocation Loc;
};
enum APFloatSemantics {
@@ -174,26 +366,111 @@ protected:
unsigned IsExact : 1;
};
+ class StringLiteralBitfields {
+ friend class ASTStmtReader;
+ friend class StringLiteral;
+
+ unsigned : NumExprBits;
+
+ /// The kind of this string literal.
+ /// One of the enumeration values of StringLiteral::StringKind.
+ unsigned Kind : 3;
+
+ /// The width of a single character in bytes. Only values of 1, 2,
+ /// and 4 bytes are supported. StringLiteral::mapCharByteWidth maps
+ /// the target + string kind to the appropriate CharByteWidth.
+ unsigned CharByteWidth : 3;
+
+ unsigned IsPascal : 1;
+
+ /// The number of concatenated token this string is made of.
+ /// This is the number of trailing SourceLocation.
+ unsigned NumConcatenated;
+ };
+
+ class CharacterLiteralBitfields {
+ friend class CharacterLiteral;
+
+ unsigned : NumExprBits;
+
+ unsigned Kind : 3;
+ };
+
+ class UnaryOperatorBitfields {
+ friend class UnaryOperator;
+
+ unsigned : NumExprBits;
+
+ unsigned Opc : 5;
+ unsigned CanOverflow : 1;
+
+ SourceLocation Loc;
+ };
+
class UnaryExprOrTypeTraitExprBitfields {
friend class UnaryExprOrTypeTraitExpr;
unsigned : NumExprBits;
- unsigned Kind : 2;
+ unsigned Kind : 3;
unsigned IsType : 1; // true if operand is a type, false if an expression.
};
- class DeclRefExprBitfields {
- friend class ASTStmtReader; // deserialization
- friend class DeclRefExpr;
+ class ArraySubscriptExprBitfields {
+ friend class ArraySubscriptExpr;
unsigned : NumExprBits;
- unsigned HasQualifier : 1;
+ SourceLocation RBracketLoc;
+ };
+
+ class CallExprBitfields {
+ friend class CallExpr;
+
+ unsigned : NumExprBits;
+
+ unsigned NumPreArgs : 1;
+
+ /// True if the callee of the call expression was found using ADL.
+ unsigned UsesADL : 1;
+
+ /// Padding used to align OffsetToTrailingObjects to a byte multiple.
+ unsigned : 24 - 2 - NumExprBits;
+
+ /// The offset in bytes from the this pointer to the start of the
+ /// trailing objects belonging to CallExpr. Intentionally byte sized
+ /// for faster access.
+ unsigned OffsetToTrailingObjects : 8;
+ };
+ enum { NumCallExprBits = 32 };
+
+ class MemberExprBitfields {
+ friend class MemberExpr;
+
+ unsigned : NumExprBits;
+
+ /// IsArrow - True if this is "X->F", false if this is "X.F".
+ unsigned IsArrow : 1;
+
+ /// True if this member expression used a nested-name-specifier to
+ /// refer to the member, e.g., "x->Base::f", or found its member via
+ /// a using declaration. When true, a MemberExprNameQualifier
+ /// structure is allocated immediately after the MemberExpr.
+ unsigned HasQualifierOrFoundDecl : 1;
+
+ /// True if this member expression specified a template keyword
+ /// and/or a template argument list explicitly, e.g., x->f<int>,
+ /// x->template f, x->template f<int>.
+ /// When true, an ASTTemplateKWAndArgsInfo structure and its
+ /// TemplateArguments (if any) are present.
unsigned HasTemplateKWAndArgsInfo : 1;
- unsigned HasFoundDecl : 1;
+
+ /// True if this member expression refers to a method that
+ /// was resolved from an overloaded set having size greater than 1.
unsigned HadMultipleCandidates : 1;
- unsigned RefersToEnclosingVariableOrCapture : 1;
+
+ /// This is the location of the -> or . in the expression.
+ SourceLocation OperatorLoc;
};
class CastExprBitfields {
@@ -204,27 +481,44 @@ protected:
unsigned Kind : 6;
unsigned PartOfExplicitCast : 1; // Only set for ImplicitCastExpr.
- unsigned BasePathIsEmpty : 1;
+
+ /// The number of CXXBaseSpecifiers in the cast. 14 bits would be enough
+ /// here. ([implimits] Direct and indirect base classes [16384]).
+ unsigned BasePathSize;
};
- class CallExprBitfields {
- friend class CallExpr;
+ class BinaryOperatorBitfields {
+ friend class BinaryOperator;
unsigned : NumExprBits;
- unsigned NumPreArgs : 1;
+ unsigned Opc : 6;
+
+ /// This is only meaningful for operations on floating point
+ /// types and 0 otherwise.
+ unsigned FPFeatures : 3;
+
+ SourceLocation OpLoc;
};
- class ExprWithCleanupsBitfields {
- friend class ASTStmtReader; // deserialization
- friend class ExprWithCleanups;
+ class InitListExprBitfields {
+ friend class InitListExpr;
unsigned : NumExprBits;
- // When false, it must not have side effects.
- unsigned CleanupsHaveSideEffects : 1;
+ /// Whether this initializer list originally had a GNU array-range
+ /// designator in it. This is a temporary marker used by CodeGen.
+ unsigned HadArrayRangeDesignator : 1;
+ };
- unsigned NumObjects : 32 - 1 - NumExprBits;
+ class ParenListExprBitfields {
+ friend class ASTStmtReader;
+ friend class ParenListExpr;
+
+ unsigned : NumExprBits;
+
+ /// The number of expressions in the paren list.
+ unsigned NumExprs;
};
class PseudoObjectExprBitfields {
@@ -239,32 +533,153 @@ protected:
unsigned ResultIndex : 32 - 8 - NumExprBits;
};
- class OpaqueValueExprBitfields {
- friend class OpaqueValueExpr;
+ //===--- C++ Expression bitfields classes ---===//
+
+ class CXXOperatorCallExprBitfields {
+ friend class ASTStmtReader;
+ friend class CXXOperatorCallExpr;
+
+ unsigned : NumCallExprBits;
+
+ /// The kind of this overloaded operator. One of the enumerator
+ /// value of OverloadedOperatorKind.
+ unsigned OperatorKind : 6;
+
+ // Only meaningful for floating point types.
+ unsigned FPFeatures : 3;
+ };
+
+ class CXXBoolLiteralExprBitfields {
+ friend class CXXBoolLiteralExpr;
unsigned : NumExprBits;
- /// The OVE is a unique semantic reference to its source expressio if this
- /// bit is set to true.
- unsigned IsUnique : 1;
+ /// The value of the boolean literal.
+ unsigned Value : 1;
+
+ /// The location of the boolean literal.
+ SourceLocation Loc;
};
- class ObjCIndirectCopyRestoreExprBitfields {
- friend class ObjCIndirectCopyRestoreExpr;
+ class CXXNullPtrLiteralExprBitfields {
+ friend class CXXNullPtrLiteralExpr;
unsigned : NumExprBits;
- unsigned ShouldCopy : 1;
+ /// The location of the null pointer literal.
+ SourceLocation Loc;
};
- class InitListExprBitfields {
- friend class InitListExpr;
+ class CXXThisExprBitfields {
+ friend class CXXThisExpr;
unsigned : NumExprBits;
- /// Whether this initializer list originally had a GNU array-range
- /// designator in it. This is a temporary marker used by CodeGen.
- unsigned HadArrayRangeDesignator : 1;
+ /// Whether this is an implicit "this".
+ unsigned IsImplicit : 1;
+
+ /// The location of the "this".
+ SourceLocation Loc;
+ };
+
+ class CXXThrowExprBitfields {
+ friend class ASTStmtReader;
+ friend class CXXThrowExpr;
+
+ unsigned : NumExprBits;
+
+ /// Whether the thrown variable (if any) is in scope.
+ unsigned IsThrownVariableInScope : 1;
+
+ /// The location of the "throw".
+ SourceLocation ThrowLoc;
+ };
+
+ class CXXDefaultArgExprBitfields {
+ friend class ASTStmtReader;
+ friend class CXXDefaultArgExpr;
+
+ unsigned : NumExprBits;
+
+ /// The location where the default argument expression was used.
+ SourceLocation Loc;
+ };
+
+ class CXXDefaultInitExprBitfields {
+ friend class ASTStmtReader;
+ friend class CXXDefaultInitExpr;
+
+ unsigned : NumExprBits;
+
+ /// The location where the default initializer expression was used.
+ SourceLocation Loc;
+ };
+
+ class CXXScalarValueInitExprBitfields {
+ friend class ASTStmtReader;
+ friend class CXXScalarValueInitExpr;
+
+ unsigned : NumExprBits;
+
+ SourceLocation RParenLoc;
+ };
+
+ class CXXNewExprBitfields {
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+ friend class CXXNewExpr;
+
+ unsigned : NumExprBits;
+
+ /// Was the usage ::new, i.e. is the global new to be used?
+ unsigned IsGlobalNew : 1;
+
+ /// Do we allocate an array? If so, the first trailing "Stmt *" is the
+ /// size expression.
+ unsigned IsArray : 1;
+
+ /// Should the alignment be passed to the allocation function?
+ unsigned ShouldPassAlignment : 1;
+
+ /// If this is an array allocation, does the usual deallocation
+ /// function for the allocated type want to know the allocated size?
+ unsigned UsualArrayDeleteWantsSize : 1;
+
+ /// What kind of initializer do we have? Could be none, parens, or braces.
+ /// In storage, we distinguish between "none, and no initializer expr", and
+ /// "none, but an implicit initializer expr".
+ unsigned StoredInitializationStyle : 2;
+
+ /// True if the allocated type was expressed as a parenthesized type-id.
+ unsigned IsParenTypeId : 1;
+
+ /// The number of placement new arguments.
+ unsigned NumPlacementArgs;
+ };
+
+ class CXXDeleteExprBitfields {
+ friend class ASTStmtReader;
+ friend class CXXDeleteExpr;
+
+ unsigned : NumExprBits;
+
+ /// Is this a forced global delete, i.e. "::delete"?
+ unsigned GlobalDelete : 1;
+
+ /// Is this the array form of delete, i.e. "delete[]"?
+ unsigned ArrayForm : 1;
+
+ /// ArrayFormAsWritten can be different from ArrayForm if 'delete' is
+ /// applied to pointer-to-array type (ArrayFormAsWritten will be false
+ /// while ArrayForm will be true).
+ unsigned ArrayFormAsWritten : 1;
+
+ /// Does the usual deallocation function for the element type require
+ /// a size_t argument?
+ unsigned UsualArrayDeleteWantsSize : 1;
+
+ /// Location of the expression.
+ SourceLocation Loc;
};
class TypeTraitExprBitfields {
@@ -285,6 +700,154 @@ protected:
unsigned NumArgs : 32 - 8 - 1 - NumExprBits;
};
+ class DependentScopeDeclRefExprBitfields {
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+ friend class DependentScopeDeclRefExpr;
+
+ unsigned : NumExprBits;
+
+ /// Whether the name includes info for explicit template
+ /// keyword and arguments.
+ unsigned HasTemplateKWAndArgsInfo : 1;
+ };
+
+ class CXXConstructExprBitfields {
+ friend class ASTStmtReader;
+ friend class CXXConstructExpr;
+
+ unsigned : NumExprBits;
+
+ unsigned Elidable : 1;
+ unsigned HadMultipleCandidates : 1;
+ unsigned ListInitialization : 1;
+ unsigned StdInitListInitialization : 1;
+ unsigned ZeroInitialization : 1;
+ unsigned ConstructionKind : 3;
+
+ SourceLocation Loc;
+ };
+
+ class ExprWithCleanupsBitfields {
+ friend class ASTStmtReader; // deserialization
+ friend class ExprWithCleanups;
+
+ unsigned : NumExprBits;
+
+ // When false, it must not have side effects.
+ unsigned CleanupsHaveSideEffects : 1;
+
+ unsigned NumObjects : 32 - 1 - NumExprBits;
+ };
+
+ class CXXUnresolvedConstructExprBitfields {
+ friend class ASTStmtReader;
+ friend class CXXUnresolvedConstructExpr;
+
+ unsigned : NumExprBits;
+
+ /// The number of arguments used to construct the type.
+ unsigned NumArgs;
+ };
+
+ class CXXDependentScopeMemberExprBitfields {
+ friend class ASTStmtReader;
+ friend class CXXDependentScopeMemberExpr;
+
+ unsigned : NumExprBits;
+
+ /// Whether this member expression used the '->' operator or
+ /// the '.' operator.
+ unsigned IsArrow : 1;
+
+ /// Whether this member expression has info for explicit template
+ /// keyword and arguments.
+ unsigned HasTemplateKWAndArgsInfo : 1;
+
+ /// See getFirstQualifierFoundInScope() and the comment listing
+ /// the trailing objects.
+ unsigned HasFirstQualifierFoundInScope : 1;
+
+ /// The location of the '->' or '.' operator.
+ SourceLocation OperatorLoc;
+ };
+
+ class OverloadExprBitfields {
+ friend class ASTStmtReader;
+ friend class OverloadExpr;
+
+ unsigned : NumExprBits;
+
+ /// Whether the name includes info for explicit template
+ /// keyword and arguments.
+ unsigned HasTemplateKWAndArgsInfo : 1;
+
+ /// Padding used by the derived classes to store various bits. If you
+ /// need to add some data here, shrink this padding and add your data
+ /// above. NumOverloadExprBits also needs to be updated.
+ unsigned : 32 - NumExprBits - 1;
+
+ /// The number of results.
+ unsigned NumResults;
+ };
+ enum { NumOverloadExprBits = NumExprBits + 1 };
+
+ class UnresolvedLookupExprBitfields {
+ friend class ASTStmtReader;
+ friend class UnresolvedLookupExpr;
+
+ unsigned : NumOverloadExprBits;
+
+ /// True if these lookup results should be extended by
+ /// argument-dependent lookup if this is the operand of a function call.
+ unsigned RequiresADL : 1;
+
+ /// True if these lookup results are overloaded. This is pretty trivially
+ /// rederivable if we urgently need to kill this field.
+ unsigned Overloaded : 1;
+ };
+ static_assert(sizeof(UnresolvedLookupExprBitfields) <= 4,
+ "UnresolvedLookupExprBitfields must be <= than 4 bytes to"
+ "avoid trashing OverloadExprBitfields::NumResults!");
+
+ class UnresolvedMemberExprBitfields {
+ friend class ASTStmtReader;
+ friend class UnresolvedMemberExpr;
+
+ unsigned : NumOverloadExprBits;
+
+ /// Whether this member expression used the '->' operator or
+ /// the '.' operator.
+ unsigned IsArrow : 1;
+
+ /// Whether the lookup results contain an unresolved using declaration.
+ unsigned HasUnresolvedUsing : 1;
+ };
+ static_assert(sizeof(UnresolvedMemberExprBitfields) <= 4,
+ "UnresolvedMemberExprBitfields must be <= than 4 bytes to"
+ "avoid trashing OverloadExprBitfields::NumResults!");
+
+ class CXXNoexceptExprBitfields {
+ friend class ASTStmtReader;
+ friend class CXXNoexceptExpr;
+
+ unsigned : NumExprBits;
+
+ unsigned Value : 1;
+ };
+
+ class SubstNonTypeTemplateParmExprBitfields {
+ friend class ASTStmtReader;
+ friend class SubstNonTypeTemplateParmExpr;
+
+ unsigned : NumExprBits;
+
+ /// The location of the non-type template parameter reference.
+ SourceLocation NameLoc;
+ };
+
+ //===--- C++ Coroutines TS bitfields classes ---===//
+
class CoawaitExprBitfields {
friend class CoawaitExpr;
@@ -293,24 +856,99 @@ protected:
unsigned IsImplicit : 1;
};
+ //===--- Obj-C Expression bitfields classes ---===//
+
+ class ObjCIndirectCopyRestoreExprBitfields {
+ friend class ObjCIndirectCopyRestoreExpr;
+
+ unsigned : NumExprBits;
+
+ unsigned ShouldCopy : 1;
+ };
+
+ //===--- Clang Extensions bitfields classes ---===//
+
+ class OpaqueValueExprBitfields {
+ friend class ASTStmtReader;
+ friend class OpaqueValueExpr;
+
+ unsigned : NumExprBits;
+
+ /// The OVE is a unique semantic reference to its source expression if this
+ /// bit is set to true.
+ unsigned IsUnique : 1;
+
+ SourceLocation Loc;
+ };
+
union {
+ // Same order as in StmtNodes.td.
+ // Statements
StmtBitfields StmtBits;
+ NullStmtBitfields NullStmtBits;
CompoundStmtBitfields CompoundStmtBits;
+ LabelStmtBitfields LabelStmtBits;
+ AttributedStmtBitfields AttributedStmtBits;
IfStmtBitfields IfStmtBits;
+ SwitchStmtBitfields SwitchStmtBits;
+ WhileStmtBitfields WhileStmtBits;
+ DoStmtBitfields DoStmtBits;
+ ForStmtBitfields ForStmtBits;
+ GotoStmtBitfields GotoStmtBits;
+ ContinueStmtBitfields ContinueStmtBits;
+ BreakStmtBitfields BreakStmtBits;
+ ReturnStmtBitfields ReturnStmtBits;
+ SwitchCaseBitfields SwitchCaseBits;
+
+ // Expressions
ExprBitfields ExprBits;
- CharacterLiteralBitfields CharacterLiteralBits;
+ PredefinedExprBitfields PredefinedExprBits;
+ DeclRefExprBitfields DeclRefExprBits;
FloatingLiteralBitfields FloatingLiteralBits;
+ StringLiteralBitfields StringLiteralBits;
+ CharacterLiteralBitfields CharacterLiteralBits;
+ UnaryOperatorBitfields UnaryOperatorBits;
UnaryExprOrTypeTraitExprBitfields UnaryExprOrTypeTraitExprBits;
- DeclRefExprBitfields DeclRefExprBits;
- CastExprBitfields CastExprBits;
+ ArraySubscriptExprBitfields ArraySubscriptExprBits;
CallExprBitfields CallExprBits;
- ExprWithCleanupsBitfields ExprWithCleanupsBits;
- PseudoObjectExprBitfields PseudoObjectExprBits;
- OpaqueValueExprBitfields OpaqueValueExprBits;
- ObjCIndirectCopyRestoreExprBitfields ObjCIndirectCopyRestoreExprBits;
+ MemberExprBitfields MemberExprBits;
+ CastExprBitfields CastExprBits;
+ BinaryOperatorBitfields BinaryOperatorBits;
InitListExprBitfields InitListExprBits;
+ ParenListExprBitfields ParenListExprBits;
+ PseudoObjectExprBitfields PseudoObjectExprBits;
+
+ // C++ Expressions
+ CXXOperatorCallExprBitfields CXXOperatorCallExprBits;
+ CXXBoolLiteralExprBitfields CXXBoolLiteralExprBits;
+ CXXNullPtrLiteralExprBitfields CXXNullPtrLiteralExprBits;
+ CXXThisExprBitfields CXXThisExprBits;
+ CXXThrowExprBitfields CXXThrowExprBits;
+ CXXDefaultArgExprBitfields CXXDefaultArgExprBits;
+ CXXDefaultInitExprBitfields CXXDefaultInitExprBits;
+ CXXScalarValueInitExprBitfields CXXScalarValueInitExprBits;
+ CXXNewExprBitfields CXXNewExprBits;
+ CXXDeleteExprBitfields CXXDeleteExprBits;
TypeTraitExprBitfields TypeTraitExprBits;
+ DependentScopeDeclRefExprBitfields DependentScopeDeclRefExprBits;
+ CXXConstructExprBitfields CXXConstructExprBits;
+ ExprWithCleanupsBitfields ExprWithCleanupsBits;
+ CXXUnresolvedConstructExprBitfields CXXUnresolvedConstructExprBits;
+ CXXDependentScopeMemberExprBitfields CXXDependentScopeMemberExprBits;
+ OverloadExprBitfields OverloadExprBits;
+ UnresolvedLookupExprBitfields UnresolvedLookupExprBits;
+ UnresolvedMemberExprBitfields UnresolvedMemberExprBits;
+ CXXNoexceptExprBitfields CXXNoexceptExprBits;
+ SubstNonTypeTemplateParmExprBitfields SubstNonTypeTemplateParmExprBits;
+
+ // C++ Coroutines TS expressions
CoawaitExprBitfields CoawaitBits;
+
+ // Obj-C Expressions
+ ObjCIndirectCopyRestoreExprBitfields ObjCIndirectCopyRestoreExprBits;
+
+ // Clang Extensions
+ OpaqueValueExprBitfields OpaqueValueExprBits;
};
public:
@@ -380,7 +1018,7 @@ protected:
public:
Stmt(StmtClass SC) {
- static_assert(sizeof(*this) == sizeof(void *),
+ static_assert(sizeof(*this) <= 8,
"changing bitfields changed sizeof(Stmt)");
static_assert(sizeof(*this) % alignof(void *) == 0,
"Insufficient alignment!");
@@ -398,8 +1036,8 @@ public:
/// value objects created/interpreted by SourceManager. We assume AST
/// clients will have a pointer to the respective SourceManager.
SourceRange getSourceRange() const LLVM_READONLY;
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY;
+ SourceLocation getBeginLoc() const LLVM_READONLY;
+ SourceLocation getEndLoc() const LLVM_READONLY;
// global temp stats (until we have a per-module visitor)
static void addStmtClass(const StmtClass s);
@@ -413,6 +1051,9 @@ public:
void dump(raw_ostream &OS, SourceManager &SM) const;
void dump(raw_ostream &OS) const;
+ /// \return Unique reproducible object identifier
+ int64_t getID(const ASTContext &Context) const;
+
/// dumpColor - same as dump(), but forces color highlighting.
void dumpColor() const;
@@ -421,6 +1062,7 @@ public:
void dumpPretty(const ASTContext &Context) const;
void printPretty(raw_ostream &OS, PrinterHelper *Helper,
const PrintingPolicy &Policy, unsigned Indentation = 0,
+ StringRef NewlineSymbol = "\n",
const ASTContext *Context = nullptr) const;
/// viewAST - Visualize an AST rooted at this Stmt* using GraphViz. Only
@@ -511,9 +1153,7 @@ public:
/// isSingleDecl - This method returns true if this DeclStmt refers
/// to a single Decl.
- bool isSingleDecl() const {
- return DG.isSingleDecl();
- }
+ bool isSingleDecl() const { return DG.isSingleDecl(); }
const Decl *getSingleDecl() const { return DG.getSingleDecl(); }
Decl *getSingleDecl() { return DG.getSingleDecl(); }
@@ -522,13 +1162,11 @@ public:
DeclGroupRef getDeclGroup() { return DG; }
void setDeclGroup(DeclGroupRef DGR) { DG = DGR; }
- SourceLocation getStartLoc() const { return StartLoc; }
void setStartLoc(SourceLocation L) { StartLoc = L; }
SourceLocation getEndLoc() const { return EndLoc; }
void setEndLoc(SourceLocation L) { EndLoc = L; }
- SourceLocation getLocStart() const LLVM_READONLY { return StartLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return EndLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return StartLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == DeclStmtClass;
@@ -570,33 +1208,25 @@ public:
/// NullStmt - This is the null statement ";": C99 6.8.3p3.
///
class NullStmt : public Stmt {
- SourceLocation SemiLoc;
-
- /// True if the null statement was preceded by an empty macro, e.g:
- /// @code
- /// #define CALL(x)
- /// CALL(0);
- /// @endcode
- bool HasLeadingEmptyMacro = false;
-
public:
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-
NullStmt(SourceLocation L, bool hasLeadingEmptyMacro = false)
- : Stmt(NullStmtClass), SemiLoc(L),
- HasLeadingEmptyMacro(hasLeadingEmptyMacro) {}
+ : Stmt(NullStmtClass) {
+ NullStmtBits.HasLeadingEmptyMacro = hasLeadingEmptyMacro;
+ setSemiLoc(L);
+ }
/// Build an empty null statement.
explicit NullStmt(EmptyShell Empty) : Stmt(NullStmtClass, Empty) {}
- SourceLocation getSemiLoc() const { return SemiLoc; }
- void setSemiLoc(SourceLocation L) { SemiLoc = L; }
+ SourceLocation getSemiLoc() const { return NullStmtBits.SemiLoc; }
+ void setSemiLoc(SourceLocation L) { NullStmtBits.SemiLoc = L; }
- bool hasLeadingEmptyMacro() const { return HasLeadingEmptyMacro; }
+ bool hasLeadingEmptyMacro() const {
+ return NullStmtBits.HasLeadingEmptyMacro;
+ }
- SourceLocation getLocStart() const LLVM_READONLY { return SemiLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return SemiLoc; }
+ SourceLocation getBeginLoc() const { return getSemiLoc(); }
+ SourceLocation getEndLoc() const { return getSemiLoc(); }
static bool classof(const Stmt *T) {
return T->getStmtClass() == NullStmtClass;
@@ -613,7 +1243,8 @@ class CompoundStmt final : public Stmt,
friend class ASTStmtReader;
friend TrailingObjects;
- SourceLocation LBraceLoc, RBraceLoc;
+ /// The location of the closing "}". LBraceLoc is stored in CompoundStmtBits.
+ SourceLocation RBraceLoc;
CompoundStmt(ArrayRef<Stmt *> Stmts, SourceLocation LB, SourceLocation RB);
explicit CompoundStmt(EmptyShell Empty) : Stmt(CompoundStmtClass, Empty) {}
@@ -626,8 +1257,9 @@ public:
// Build an empty compound statement with a location.
explicit CompoundStmt(SourceLocation Loc)
- : Stmt(CompoundStmtClass), LBraceLoc(Loc), RBraceLoc(Loc) {
+ : Stmt(CompoundStmtClass), RBraceLoc(Loc) {
CompoundStmtBits.NumStmts = 0;
+ CompoundStmtBits.LBraceLoc = Loc;
}
// Build an empty compound statement.
@@ -653,7 +1285,7 @@ public:
body_begin()[size() - 1] = S;
}
- using const_body_iterator = Stmt* const *;
+ using const_body_iterator = Stmt *const *;
using body_const_range = llvm::iterator_range<const_body_iterator>;
body_const_range body() const {
@@ -695,10 +1327,10 @@ public:
return const_reverse_body_iterator(body_begin());
}
- SourceLocation getLocStart() const LLVM_READONLY { return LBraceLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RBraceLoc; }
+ SourceLocation getBeginLoc() const { return CompoundStmtBits.LBraceLoc; }
+ SourceLocation getEndLoc() const { return RBraceLoc; }
- SourceLocation getLBracLoc() const { return LBraceLoc; }
+ SourceLocation getLBracLoc() const { return CompoundStmtBits.LBraceLoc; }
SourceLocation getRBracLoc() const { return RBraceLoc; }
static bool classof(const Stmt *T) {
@@ -716,36 +1348,40 @@ public:
// SwitchCase is the base class for CaseStmt and DefaultStmt,
class SwitchCase : public Stmt {
protected:
- // A pointer to the following CaseStmt or DefaultStmt class,
- // used by SwitchStmt.
- SwitchCase *NextSwitchCase = nullptr;
- SourceLocation KeywordLoc;
+ /// The location of the ":".
SourceLocation ColonLoc;
+ // The location of the "case" or "default" keyword. Stored in SwitchCaseBits.
+ // SourceLocation KeywordLoc;
+
+ /// A pointer to the following CaseStmt or DefaultStmt class,
+ /// used by SwitchStmt.
+ SwitchCase *NextSwitchCase = nullptr;
+
SwitchCase(StmtClass SC, SourceLocation KWLoc, SourceLocation ColonLoc)
- : Stmt(SC), KeywordLoc(KWLoc), ColonLoc(ColonLoc) {}
+ : Stmt(SC), ColonLoc(ColonLoc) {
+ setKeywordLoc(KWLoc);
+ }
SwitchCase(StmtClass SC, EmptyShell) : Stmt(SC) {}
public:
const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; }
-
SwitchCase *getNextSwitchCase() { return NextSwitchCase; }
-
void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; }
- SourceLocation getKeywordLoc() const { return KeywordLoc; }
- void setKeywordLoc(SourceLocation L) { KeywordLoc = L; }
+ SourceLocation getKeywordLoc() const { return SwitchCaseBits.KeywordLoc; }
+ void setKeywordLoc(SourceLocation L) { SwitchCaseBits.KeywordLoc = L; }
SourceLocation getColonLoc() const { return ColonLoc; }
void setColonLoc(SourceLocation L) { ColonLoc = L; }
- Stmt *getSubStmt();
+ inline Stmt *getSubStmt();
const Stmt *getSubStmt() const {
- return const_cast<SwitchCase*>(this)->getSubStmt();
+ return const_cast<SwitchCase *>(this)->getSubStmt();
}
- SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY;
+ SourceLocation getBeginLoc() const { return getKeywordLoc(); }
+ inline SourceLocation getEndLoc() const LLVM_READONLY;
static bool classof(const Stmt *T) {
return T->getStmtClass() == CaseStmtClass ||
@@ -753,59 +1389,144 @@ public:
}
};
-class CaseStmt : public SwitchCase {
- SourceLocation EllipsisLoc;
- enum { LHS, RHS, SUBSTMT, END_EXPR };
- Stmt* SubExprs[END_EXPR]; // The expression for the RHS is Non-null for
- // GNU "case 1 ... 4" extension
+/// CaseStmt - Represent a case statement. It can optionally be a GNU case
+/// statement of the form LHS ... RHS representing a range of cases.
+class CaseStmt final
+ : public SwitchCase,
+ private llvm::TrailingObjects<CaseStmt, Stmt *, SourceLocation> {
+ friend TrailingObjects;
-public:
+ // CaseStmt is followed by several trailing objects, some of which optional.
+ // Note that it would be more convenient to put the optional trailing objects
+ // at the end but this would impact children().
+ // The trailing objects are in order:
+ //
+ // * A "Stmt *" for the LHS of the case statement. Always present.
+ //
+ // * A "Stmt *" for the RHS of the case statement. This is a GNU extension
+ // which allow ranges in cases statement of the form LHS ... RHS.
+ // Present if and only if caseStmtIsGNURange() is true.
+ //
+ // * A "Stmt *" for the substatement of the case statement. Always present.
+ //
+ // * A SourceLocation for the location of the ... if this is a case statement
+ // with a range. Present if and only if caseStmtIsGNURange() is true.
+ enum { LhsOffset = 0, SubStmtOffsetFromRhs = 1 };
+ enum { NumMandatoryStmtPtr = 2 };
+
+ unsigned numTrailingObjects(OverloadToken<Stmt *>) const {
+ return NumMandatoryStmtPtr + caseStmtIsGNURange();
+ }
+
+ unsigned numTrailingObjects(OverloadToken<SourceLocation>) const {
+ return caseStmtIsGNURange();
+ }
+
+ unsigned lhsOffset() const { return LhsOffset; }
+ unsigned rhsOffset() const { return LhsOffset + caseStmtIsGNURange(); }
+ unsigned subStmtOffset() const { return rhsOffset() + SubStmtOffsetFromRhs; }
+
+ /// Build a case statement assuming that the storage for the
+ /// trailing objects has been properly allocated.
CaseStmt(Expr *lhs, Expr *rhs, SourceLocation caseLoc,
SourceLocation ellipsisLoc, SourceLocation colonLoc)
- : SwitchCase(CaseStmtClass, caseLoc, colonLoc) {
- SubExprs[SUBSTMT] = nullptr;
- SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs);
- SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs);
- EllipsisLoc = ellipsisLoc;
+ : SwitchCase(CaseStmtClass, caseLoc, colonLoc) {
+ // Handle GNU case statements of the form LHS ... RHS.
+ bool IsGNURange = rhs != nullptr;
+ SwitchCaseBits.CaseStmtIsGNURange = IsGNURange;
+ setLHS(lhs);
+ setSubStmt(nullptr);
+ if (IsGNURange) {
+ setRHS(rhs);
+ setEllipsisLoc(ellipsisLoc);
+ }
}
/// Build an empty switch case statement.
- explicit CaseStmt(EmptyShell Empty) : SwitchCase(CaseStmtClass, Empty) {}
+ explicit CaseStmt(EmptyShell Empty, bool CaseStmtIsGNURange)
+ : SwitchCase(CaseStmtClass, Empty) {
+ SwitchCaseBits.CaseStmtIsGNURange = CaseStmtIsGNURange;
+ }
- SourceLocation getCaseLoc() const { return KeywordLoc; }
- void setCaseLoc(SourceLocation L) { KeywordLoc = L; }
- SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
- void setEllipsisLoc(SourceLocation L) { EllipsisLoc = L; }
- SourceLocation getColonLoc() const { return ColonLoc; }
- void setColonLoc(SourceLocation L) { ColonLoc = L; }
+public:
+ /// Build a case statement.
+ static CaseStmt *Create(const ASTContext &Ctx, Expr *lhs, Expr *rhs,
+ SourceLocation caseLoc, SourceLocation ellipsisLoc,
+ SourceLocation colonLoc);
+
+ /// Build an empty case statement.
+ static CaseStmt *CreateEmpty(const ASTContext &Ctx, bool CaseStmtIsGNURange);
+
+ /// True if this case statement is of the form case LHS ... RHS, which
+ /// is a GNU extension. In this case the RHS can be obtained with getRHS()
+ /// and the location of the ellipsis can be obtained with getEllipsisLoc().
+ bool caseStmtIsGNURange() const { return SwitchCaseBits.CaseStmtIsGNURange; }
+
+ SourceLocation getCaseLoc() const { return getKeywordLoc(); }
+ void setCaseLoc(SourceLocation L) { setKeywordLoc(L); }
+
+ /// Get the location of the ... in a case statement of the form LHS ... RHS.
+ SourceLocation getEllipsisLoc() const {
+ return caseStmtIsGNURange() ? *getTrailingObjects<SourceLocation>()
+ : SourceLocation();
+ }
- Expr *getLHS() { return reinterpret_cast<Expr*>(SubExprs[LHS]); }
- Expr *getRHS() { return reinterpret_cast<Expr*>(SubExprs[RHS]); }
- Stmt *getSubStmt() { return SubExprs[SUBSTMT]; }
+ /// Set the location of the ... in a case statement of the form LHS ... RHS.
+ /// Assert that this case statement is of this form.
+ void setEllipsisLoc(SourceLocation L) {
+ assert(
+ caseStmtIsGNURange() &&
+ "setEllipsisLoc but this is not a case stmt of the form LHS ... RHS!");
+ *getTrailingObjects<SourceLocation>() = L;
+ }
+
+ Expr *getLHS() {
+ return reinterpret_cast<Expr *>(getTrailingObjects<Stmt *>()[lhsOffset()]);
+ }
const Expr *getLHS() const {
- return reinterpret_cast<const Expr*>(SubExprs[LHS]);
+ return reinterpret_cast<Expr *>(getTrailingObjects<Stmt *>()[lhsOffset()]);
+ }
+
+ void setLHS(Expr *Val) {
+ getTrailingObjects<Stmt *>()[lhsOffset()] = reinterpret_cast<Stmt *>(Val);
+ }
+
+ Expr *getRHS() {
+ return caseStmtIsGNURange() ? reinterpret_cast<Expr *>(
+ getTrailingObjects<Stmt *>()[rhsOffset()])
+ : nullptr;
}
const Expr *getRHS() const {
- return reinterpret_cast<const Expr*>(SubExprs[RHS]);
+ return caseStmtIsGNURange() ? reinterpret_cast<Expr *>(
+ getTrailingObjects<Stmt *>()[rhsOffset()])
+ : nullptr;
}
- const Stmt *getSubStmt() const { return SubExprs[SUBSTMT]; }
+ void setRHS(Expr *Val) {
+ assert(caseStmtIsGNURange() &&
+ "setRHS but this is not a case stmt of the form LHS ... RHS!");
+ getTrailingObjects<Stmt *>()[rhsOffset()] = reinterpret_cast<Stmt *>(Val);
+ }
- void setSubStmt(Stmt *S) { SubExprs[SUBSTMT] = S; }
- void setLHS(Expr *Val) { SubExprs[LHS] = reinterpret_cast<Stmt*>(Val); }
- void setRHS(Expr *Val) { SubExprs[RHS] = reinterpret_cast<Stmt*>(Val); }
+ Stmt *getSubStmt() { return getTrailingObjects<Stmt *>()[subStmtOffset()]; }
+ const Stmt *getSubStmt() const {
+ return getTrailingObjects<Stmt *>()[subStmtOffset()];
+ }
- SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; }
+ void setSubStmt(Stmt *S) {
+ getTrailingObjects<Stmt *>()[subStmtOffset()] = S;
+ }
- SourceLocation getLocEnd() const LLVM_READONLY {
+ SourceLocation getBeginLoc() const { return getKeywordLoc(); }
+ SourceLocation getEndLoc() const LLVM_READONLY {
// Handle deeply nested case statements with iteration instead of recursion.
const CaseStmt *CS = this;
while (const auto *CS2 = dyn_cast<CaseStmt>(CS->getSubStmt()))
CS = CS2;
- return CS->getSubStmt()->getLocEnd();
+ return CS->getSubStmt()->getEndLoc();
}
static bool classof(const Stmt *T) {
@@ -814,16 +1535,18 @@ public:
// Iterators
child_range children() {
- return child_range(&SubExprs[0], &SubExprs[END_EXPR]);
+ return child_range(getTrailingObjects<Stmt *>(),
+ getTrailingObjects<Stmt *>() +
+ numTrailingObjects(OverloadToken<Stmt *>()));
}
};
class DefaultStmt : public SwitchCase {
- Stmt* SubStmt;
+ Stmt *SubStmt;
public:
- DefaultStmt(SourceLocation DL, SourceLocation CL, Stmt *substmt) :
- SwitchCase(DefaultStmtClass, DL, CL), SubStmt(substmt) {}
+ DefaultStmt(SourceLocation DL, SourceLocation CL, Stmt *substmt)
+ : SwitchCase(DefaultStmtClass, DL, CL), SubStmt(substmt) {}
/// Build an empty default statement.
explicit DefaultStmt(EmptyShell Empty)
@@ -833,59 +1556,70 @@ public:
const Stmt *getSubStmt() const { return SubStmt; }
void setSubStmt(Stmt *S) { SubStmt = S; }
- SourceLocation getDefaultLoc() const { return KeywordLoc; }
- void setDefaultLoc(SourceLocation L) { KeywordLoc = L; }
- SourceLocation getColonLoc() const { return ColonLoc; }
- void setColonLoc(SourceLocation L) { ColonLoc = L; }
+ SourceLocation getDefaultLoc() const { return getKeywordLoc(); }
+ void setDefaultLoc(SourceLocation L) { setKeywordLoc(L); }
- SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();}
+ SourceLocation getBeginLoc() const { return getKeywordLoc(); }
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return SubStmt->getEndLoc();
+ }
static bool classof(const Stmt *T) {
return T->getStmtClass() == DefaultStmtClass;
}
// Iterators
- child_range children() { return child_range(&SubStmt, &SubStmt+1); }
+ child_range children() { return child_range(&SubStmt, &SubStmt + 1); }
};
-inline SourceLocation SwitchCase::getLocEnd() const {
+SourceLocation SwitchCase::getEndLoc() const {
if (const auto *CS = dyn_cast<CaseStmt>(this))
- return CS->getLocEnd();
- return cast<DefaultStmt>(this)->getLocEnd();
+ return CS->getEndLoc();
+ else if (const auto *DS = dyn_cast<DefaultStmt>(this))
+ return DS->getEndLoc();
+ llvm_unreachable("SwitchCase is neither a CaseStmt nor a DefaultStmt!");
+}
+
+Stmt *SwitchCase::getSubStmt() {
+ if (auto *CS = dyn_cast<CaseStmt>(this))
+ return CS->getSubStmt();
+ else if (auto *DS = dyn_cast<DefaultStmt>(this))
+ return DS->getSubStmt();
+ llvm_unreachable("SwitchCase is neither a CaseStmt nor a DefaultStmt!");
}
/// LabelStmt - Represents a label, which has a substatement. For example:
/// foo: return;
class LabelStmt : public Stmt {
- SourceLocation IdentLoc;
LabelDecl *TheDecl;
Stmt *SubStmt;
public:
+ /// Build a label statement.
LabelStmt(SourceLocation IL, LabelDecl *D, Stmt *substmt)
- : Stmt(LabelStmtClass), IdentLoc(IL), TheDecl(D), SubStmt(substmt) {
- static_assert(sizeof(LabelStmt) ==
- 2 * sizeof(SourceLocation) + 2 * sizeof(void *),
- "LabelStmt too big");
+ : Stmt(LabelStmtClass), TheDecl(D), SubStmt(substmt) {
+ setIdentLoc(IL);
}
- // Build an empty label statement.
+ /// Build an empty label statement.
explicit LabelStmt(EmptyShell Empty) : Stmt(LabelStmtClass, Empty) {}
- SourceLocation getIdentLoc() const { return IdentLoc; }
+ SourceLocation getIdentLoc() const { return LabelStmtBits.IdentLoc; }
+ void setIdentLoc(SourceLocation L) { LabelStmtBits.IdentLoc = L; }
+
LabelDecl *getDecl() const { return TheDecl; }
void setDecl(LabelDecl *D) { TheDecl = D; }
+
const char *getName() const;
Stmt *getSubStmt() { return SubStmt; }
+
const Stmt *getSubStmt() const { return SubStmt; }
- void setIdentLoc(SourceLocation L) { IdentLoc = L; }
void setSubStmt(Stmt *SS) { SubStmt = SS; }
- SourceLocation getLocStart() const LLVM_READONLY { return IdentLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();}
+ SourceLocation getBeginLoc() const { return getIdentLoc(); }
+ SourceLocation getEndLoc() const LLVM_READONLY { return SubStmt->getEndLoc();}
- child_range children() { return child_range(&SubStmt, &SubStmt+1); }
+ child_range children() { return child_range(&SubStmt, &SubStmt + 1); }
static bool classof(const Stmt *T) {
return T->getStmtClass() == LabelStmtClass;
@@ -903,17 +1637,19 @@ class AttributedStmt final
friend TrailingObjects;
Stmt *SubStmt;
- SourceLocation AttrLoc;
- unsigned NumAttrs;
- AttributedStmt(SourceLocation Loc, ArrayRef<const Attr*> Attrs, Stmt *SubStmt)
- : Stmt(AttributedStmtClass), SubStmt(SubStmt), AttrLoc(Loc),
- NumAttrs(Attrs.size()) {
+ AttributedStmt(SourceLocation Loc, ArrayRef<const Attr *> Attrs,
+ Stmt *SubStmt)
+ : Stmt(AttributedStmtClass), SubStmt(SubStmt) {
+ AttributedStmtBits.NumAttrs = Attrs.size();
+ AttributedStmtBits.AttrLoc = Loc;
std::copy(Attrs.begin(), Attrs.end(), getAttrArrayPtr());
}
explicit AttributedStmt(EmptyShell Empty, unsigned NumAttrs)
- : Stmt(AttributedStmtClass, Empty), NumAttrs(NumAttrs) {
+ : Stmt(AttributedStmtClass, Empty) {
+ AttributedStmtBits.NumAttrs = NumAttrs;
+ AttributedStmtBits.AttrLoc = SourceLocation{};
std::fill_n(getAttrArrayPtr(), NumAttrs, nullptr);
}
@@ -924,21 +1660,21 @@ class AttributedStmt final
public:
static AttributedStmt *Create(const ASTContext &C, SourceLocation Loc,
- ArrayRef<const Attr*> Attrs, Stmt *SubStmt);
+ ArrayRef<const Attr *> Attrs, Stmt *SubStmt);
// Build an empty attributed statement.
static AttributedStmt *CreateEmpty(const ASTContext &C, unsigned NumAttrs);
- SourceLocation getAttrLoc() const { return AttrLoc; }
- ArrayRef<const Attr*> getAttrs() const {
- return llvm::makeArrayRef(getAttrArrayPtr(), NumAttrs);
+ SourceLocation getAttrLoc() const { return AttributedStmtBits.AttrLoc; }
+ ArrayRef<const Attr *> getAttrs() const {
+ return llvm::makeArrayRef(getAttrArrayPtr(), AttributedStmtBits.NumAttrs);
}
Stmt *getSubStmt() { return SubStmt; }
const Stmt *getSubStmt() const { return SubStmt; }
- SourceLocation getLocStart() const LLVM_READONLY { return AttrLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();}
+ SourceLocation getBeginLoc() const { return getAttrLoc(); }
+ SourceLocation getEndLoc() const LLVM_READONLY { return SubStmt->getEndLoc();}
child_range children() { return child_range(&SubStmt, &SubStmt + 1); }
@@ -948,21 +1684,117 @@ public:
};
/// IfStmt - This represents an if/then/else.
-class IfStmt : public Stmt {
- enum { INIT, VAR, COND, THEN, ELSE, END_EXPR };
- Stmt* SubExprs[END_EXPR];
+class IfStmt final
+ : public Stmt,
+ private llvm::TrailingObjects<IfStmt, Stmt *, SourceLocation> {
+ friend TrailingObjects;
- SourceLocation IfLoc;
- SourceLocation ElseLoc;
+ // IfStmt is followed by several trailing objects, some of which optional.
+ // Note that it would be more convenient to put the optional trailing
+ // objects at then end but this would change the order of the children.
+ // The trailing objects are in order:
+ //
+ // * A "Stmt *" for the init statement.
+ // Present if and only if hasInitStorage().
+ //
+ // * A "Stmt *" for the condition variable.
+ // Present if and only if hasVarStorage(). This is in fact a "DeclStmt *".
+ //
+ // * A "Stmt *" for the condition.
+ // Always present. This is in fact a "Expr *".
+ //
+ // * A "Stmt *" for the then statement.
+ // Always present.
+ //
+ // * A "Stmt *" for the else statement.
+ // Present if and only if hasElseStorage().
+ //
+ // * A "SourceLocation" for the location of the "else".
+ // Present if and only if hasElseStorage().
+ enum { InitOffset = 0, ThenOffsetFromCond = 1, ElseOffsetFromCond = 2 };
+ enum { NumMandatoryStmtPtr = 2 };
+
+ unsigned numTrailingObjects(OverloadToken<Stmt *>) const {
+ return NumMandatoryStmtPtr + hasElseStorage() + hasVarStorage() +
+ hasInitStorage();
+ }
+
+ unsigned numTrailingObjects(OverloadToken<SourceLocation>) const {
+ return hasElseStorage();
+ }
+
+ unsigned initOffset() const { return InitOffset; }
+ unsigned varOffset() const { return InitOffset + hasInitStorage(); }
+ unsigned condOffset() const {
+ return InitOffset + hasInitStorage() + hasVarStorage();
+ }
+ unsigned thenOffset() const { return condOffset() + ThenOffsetFromCond; }
+ unsigned elseOffset() const { return condOffset() + ElseOffsetFromCond; }
+
+ /// Build an if/then/else statement.
+ IfStmt(const ASTContext &Ctx, SourceLocation IL, bool IsConstexpr, Stmt *Init,
+ VarDecl *Var, Expr *Cond, Stmt *Then, SourceLocation EL, Stmt *Else);
+
+ /// Build an empty if/then/else statement.
+ explicit IfStmt(EmptyShell Empty, bool HasElse, bool HasVar, bool HasInit);
public:
- IfStmt(const ASTContext &C, SourceLocation IL,
- bool IsConstexpr, Stmt *init, VarDecl *var, Expr *cond,
- Stmt *then, SourceLocation EL = SourceLocation(),
- Stmt *elsev = nullptr);
+ /// Create an IfStmt.
+ static IfStmt *Create(const ASTContext &Ctx, SourceLocation IL,
+ bool IsConstexpr, Stmt *Init, VarDecl *Var, Expr *Cond,
+ Stmt *Then, SourceLocation EL = SourceLocation(),
+ Stmt *Else = nullptr);
+
+ /// Create an empty IfStmt optionally with storage for an else statement,
+ /// condition variable and init expression.
+ static IfStmt *CreateEmpty(const ASTContext &Ctx, bool HasElse, bool HasVar,
+ bool HasInit);
- /// Build an empty if/then/else statement
- explicit IfStmt(EmptyShell Empty) : Stmt(IfStmtClass, Empty) {}
+ /// True if this IfStmt has the storage for an init statement.
+ bool hasInitStorage() const { return IfStmtBits.HasInit; }
+
+ /// True if this IfStmt has storage for a variable declaration.
+ bool hasVarStorage() const { return IfStmtBits.HasVar; }
+
+ /// True if this IfStmt has storage for an else statement.
+ bool hasElseStorage() const { return IfStmtBits.HasElse; }
+
+ Expr *getCond() {
+ return reinterpret_cast<Expr *>(getTrailingObjects<Stmt *>()[condOffset()]);
+ }
+
+ const Expr *getCond() const {
+ return reinterpret_cast<Expr *>(getTrailingObjects<Stmt *>()[condOffset()]);
+ }
+
+ void setCond(Expr *Cond) {
+ getTrailingObjects<Stmt *>()[condOffset()] = reinterpret_cast<Stmt *>(Cond);
+ }
+
+ Stmt *getThen() { return getTrailingObjects<Stmt *>()[thenOffset()]; }
+ const Stmt *getThen() const {
+ return getTrailingObjects<Stmt *>()[thenOffset()];
+ }
+
+ void setThen(Stmt *Then) {
+ getTrailingObjects<Stmt *>()[thenOffset()] = Then;
+ }
+
+ Stmt *getElse() {
+ return hasElseStorage() ? getTrailingObjects<Stmt *>()[elseOffset()]
+ : nullptr;
+ }
+
+ const Stmt *getElse() const {
+ return hasElseStorage() ? getTrailingObjects<Stmt *>()[elseOffset()]
+ : nullptr;
+ }
+
+ void setElse(Stmt *Else) {
+ assert(hasElseStorage() &&
+ "This if statement has no storage for an else statement!");
+ getTrailingObjects<Stmt *>()[elseOffset()] = Else;
+ }
/// Retrieve the variable declared in this "if" statement, if any.
///
@@ -972,52 +1804,77 @@ public:
/// printf("x is %d", x);
/// }
/// \endcode
- VarDecl *getConditionVariable() const;
- void setConditionVariable(const ASTContext &C, VarDecl *V);
+ VarDecl *getConditionVariable();
+ const VarDecl *getConditionVariable() const {
+ return const_cast<IfStmt *>(this)->getConditionVariable();
+ }
+
+ /// Set the condition variable for this if statement.
+ /// The if statement must have storage for the condition variable.
+ void setConditionVariable(const ASTContext &Ctx, VarDecl *V);
/// If this IfStmt has a condition variable, return the faux DeclStmt
/// associated with the creation of that condition variable.
+ DeclStmt *getConditionVariableDeclStmt() {
+ return hasVarStorage() ? static_cast<DeclStmt *>(
+ getTrailingObjects<Stmt *>()[varOffset()])
+ : nullptr;
+ }
+
const DeclStmt *getConditionVariableDeclStmt() const {
- return reinterpret_cast<DeclStmt*>(SubExprs[VAR]);
+ return hasVarStorage() ? static_cast<DeclStmt *>(
+ getTrailingObjects<Stmt *>()[varOffset()])
+ : nullptr;
}
- Stmt *getInit() { return SubExprs[INIT]; }
- const Stmt *getInit() const { return SubExprs[INIT]; }
- void setInit(Stmt *S) { SubExprs[INIT] = S; }
- const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
- void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); }
- const Stmt *getThen() const { return SubExprs[THEN]; }
- void setThen(Stmt *S) { SubExprs[THEN] = S; }
- const Stmt *getElse() const { return SubExprs[ELSE]; }
- void setElse(Stmt *S) { SubExprs[ELSE] = S; }
+ Stmt *getInit() {
+ return hasInitStorage() ? getTrailingObjects<Stmt *>()[initOffset()]
+ : nullptr;
+ }
- Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
- Stmt *getThen() { return SubExprs[THEN]; }
- Stmt *getElse() { return SubExprs[ELSE]; }
+ const Stmt *getInit() const {
+ return hasInitStorage() ? getTrailingObjects<Stmt *>()[initOffset()]
+ : nullptr;
+ }
- SourceLocation getIfLoc() const { return IfLoc; }
- void setIfLoc(SourceLocation L) { IfLoc = L; }
- SourceLocation getElseLoc() const { return ElseLoc; }
- void setElseLoc(SourceLocation L) { ElseLoc = L; }
+ void setInit(Stmt *Init) {
+ assert(hasInitStorage() &&
+ "This if statement has no storage for an init statement!");
+ getTrailingObjects<Stmt *>()[initOffset()] = Init;
+ }
+
+ SourceLocation getIfLoc() const { return IfStmtBits.IfLoc; }
+ void setIfLoc(SourceLocation IfLoc) { IfStmtBits.IfLoc = IfLoc; }
+
+ SourceLocation getElseLoc() const {
+ return hasElseStorage() ? *getTrailingObjects<SourceLocation>()
+ : SourceLocation();
+ }
+
+ void setElseLoc(SourceLocation ElseLoc) {
+ assert(hasElseStorage() &&
+ "This if statement has no storage for an else statement!");
+ *getTrailingObjects<SourceLocation>() = ElseLoc;
+ }
bool isConstexpr() const { return IfStmtBits.IsConstexpr; }
void setConstexpr(bool C) { IfStmtBits.IsConstexpr = C; }
bool isObjCAvailabilityCheck() const;
- SourceLocation getLocStart() const LLVM_READONLY { return IfLoc; }
-
- SourceLocation getLocEnd() const LLVM_READONLY {
- if (SubExprs[ELSE])
- return SubExprs[ELSE]->getLocEnd();
- else
- return SubExprs[THEN]->getLocEnd();
+ SourceLocation getBeginLoc() const { return getIfLoc(); }
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ if (getElse())
+ return getElse()->getEndLoc();
+ return getThen()->getEndLoc();
}
// Iterators over subexpressions. The iterators will include iterating
// over the initialization expression referenced by the condition variable.
child_range children() {
- return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
+ return child_range(getTrailingObjects<Stmt *>(),
+ getTrailingObjects<Stmt *>() +
+ numTrailingObjects(OverloadToken<Stmt *>()));
}
static bool classof(const Stmt *T) {
@@ -1026,22 +1883,102 @@ public:
};
/// SwitchStmt - This represents a 'switch' stmt.
-class SwitchStmt : public Stmt {
- SourceLocation SwitchLoc;
- enum { INIT, VAR, COND, BODY, END_EXPR };
- Stmt* SubExprs[END_EXPR];
+class SwitchStmt final : public Stmt,
+ private llvm::TrailingObjects<SwitchStmt, Stmt *> {
+ friend TrailingObjects;
- // This points to a linked list of case and default statements and, if the
- // SwitchStmt is a switch on an enum value, records whether all the enum
- // values were covered by CaseStmts. The coverage information value is meant
- // to be a hint for possible clients.
- llvm::PointerIntPair<SwitchCase *, 1, bool> FirstCase;
+ /// Points to a linked list of case and default statements.
+ SwitchCase *FirstCase;
+
+ // SwitchStmt is followed by several trailing objects,
+ // some of which optional. Note that it would be more convenient to
+ // put the optional trailing objects at the end but this would change
+ // the order in children().
+ // The trailing objects are in order:
+ //
+ // * A "Stmt *" for the init statement.
+ // Present if and only if hasInitStorage().
+ //
+ // * A "Stmt *" for the condition variable.
+ // Present if and only if hasVarStorage(). This is in fact a "DeclStmt *".
+ //
+ // * A "Stmt *" for the condition.
+ // Always present. This is in fact an "Expr *".
+ //
+ // * A "Stmt *" for the body.
+ // Always present.
+ enum { InitOffset = 0, BodyOffsetFromCond = 1 };
+ enum { NumMandatoryStmtPtr = 2 };
+
+ unsigned numTrailingObjects(OverloadToken<Stmt *>) const {
+ return NumMandatoryStmtPtr + hasInitStorage() + hasVarStorage();
+ }
+
+ unsigned initOffset() const { return InitOffset; }
+ unsigned varOffset() const { return InitOffset + hasInitStorage(); }
+ unsigned condOffset() const {
+ return InitOffset + hasInitStorage() + hasVarStorage();
+ }
+ unsigned bodyOffset() const { return condOffset() + BodyOffsetFromCond; }
+
+ /// Build a switch statement.
+ SwitchStmt(const ASTContext &Ctx, Stmt *Init, VarDecl *Var, Expr *Cond);
+
+ /// Build a empty switch statement.
+ explicit SwitchStmt(EmptyShell Empty, bool HasInit, bool HasVar);
public:
- SwitchStmt(const ASTContext &C, Stmt *Init, VarDecl *Var, Expr *cond);
+ /// Create a switch statement.
+ static SwitchStmt *Create(const ASTContext &Ctx, Stmt *Init, VarDecl *Var,
+ Expr *Cond);
- /// Build a empty switch statement.
- explicit SwitchStmt(EmptyShell Empty) : Stmt(SwitchStmtClass, Empty) {}
+ /// Create an empty switch statement optionally with storage for
+ /// an init expression and a condition variable.
+ static SwitchStmt *CreateEmpty(const ASTContext &Ctx, bool HasInit,
+ bool HasVar);
+
+ /// True if this SwitchStmt has storage for an init statement.
+ bool hasInitStorage() const { return SwitchStmtBits.HasInit; }
+
+ /// True if this SwitchStmt has storage for a condition variable.
+ bool hasVarStorage() const { return SwitchStmtBits.HasVar; }
+
+ Expr *getCond() {
+ return reinterpret_cast<Expr *>(getTrailingObjects<Stmt *>()[condOffset()]);
+ }
+
+ const Expr *getCond() const {
+ return reinterpret_cast<Expr *>(getTrailingObjects<Stmt *>()[condOffset()]);
+ }
+
+ void setCond(Expr *Cond) {
+ getTrailingObjects<Stmt *>()[condOffset()] = reinterpret_cast<Stmt *>(Cond);
+ }
+
+ Stmt *getBody() { return getTrailingObjects<Stmt *>()[bodyOffset()]; }
+ const Stmt *getBody() const {
+ return getTrailingObjects<Stmt *>()[bodyOffset()];
+ }
+
+ void setBody(Stmt *Body) {
+ getTrailingObjects<Stmt *>()[bodyOffset()] = Body;
+ }
+
+ Stmt *getInit() {
+ return hasInitStorage() ? getTrailingObjects<Stmt *>()[initOffset()]
+ : nullptr;
+ }
+
+ const Stmt *getInit() const {
+ return hasInitStorage() ? getTrailingObjects<Stmt *>()[initOffset()]
+ : nullptr;
+ }
+
+ void setInit(Stmt *Init) {
+ assert(hasInitStorage() &&
+ "This switch statement has no storage for an init statement!");
+ getTrailingObjects<Stmt *>()[initOffset()] = Init;
+ }
/// Retrieve the variable declared in this "switch" statement, if any.
///
@@ -1052,63 +1989,69 @@ public:
/// // ...
/// }
/// \endcode
- VarDecl *getConditionVariable() const;
- void setConditionVariable(const ASTContext &C, VarDecl *V);
+ VarDecl *getConditionVariable();
+ const VarDecl *getConditionVariable() const {
+ return const_cast<SwitchStmt *>(this)->getConditionVariable();
+ }
+
+ /// Set the condition variable in this switch statement.
+ /// The switch statement must have storage for it.
+ void setConditionVariable(const ASTContext &Ctx, VarDecl *VD);
/// If this SwitchStmt has a condition variable, return the faux DeclStmt
/// associated with the creation of that condition variable.
- const DeclStmt *getConditionVariableDeclStmt() const {
- return reinterpret_cast<DeclStmt*>(SubExprs[VAR]);
+ DeclStmt *getConditionVariableDeclStmt() {
+ return hasVarStorage() ? static_cast<DeclStmt *>(
+ getTrailingObjects<Stmt *>()[varOffset()])
+ : nullptr;
}
- Stmt *getInit() { return SubExprs[INIT]; }
- const Stmt *getInit() const { return SubExprs[INIT]; }
- void setInit(Stmt *S) { SubExprs[INIT] = S; }
- const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
- const Stmt *getBody() const { return SubExprs[BODY]; }
- const SwitchCase *getSwitchCaseList() const { return FirstCase.getPointer(); }
-
- Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);}
- void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); }
- Stmt *getBody() { return SubExprs[BODY]; }
- void setBody(Stmt *S) { SubExprs[BODY] = S; }
- SwitchCase *getSwitchCaseList() { return FirstCase.getPointer(); }
+ const DeclStmt *getConditionVariableDeclStmt() const {
+ return hasVarStorage() ? static_cast<DeclStmt *>(
+ getTrailingObjects<Stmt *>()[varOffset()])
+ : nullptr;
+ }
- /// Set the case list for this switch statement.
- void setSwitchCaseList(SwitchCase *SC) { FirstCase.setPointer(SC); }
+ SwitchCase *getSwitchCaseList() { return FirstCase; }
+ const SwitchCase *getSwitchCaseList() const { return FirstCase; }
+ void setSwitchCaseList(SwitchCase *SC) { FirstCase = SC; }
- SourceLocation getSwitchLoc() const { return SwitchLoc; }
- void setSwitchLoc(SourceLocation L) { SwitchLoc = L; }
+ SourceLocation getSwitchLoc() const { return SwitchStmtBits.SwitchLoc; }
+ void setSwitchLoc(SourceLocation L) { SwitchStmtBits.SwitchLoc = L; }
void setBody(Stmt *S, SourceLocation SL) {
- SubExprs[BODY] = S;
- SwitchLoc = SL;
+ setBody(S);
+ setSwitchLoc(SL);
}
void addSwitchCase(SwitchCase *SC) {
- assert(!SC->getNextSwitchCase()
- && "case/default already added to a switch");
- SC->setNextSwitchCase(FirstCase.getPointer());
- FirstCase.setPointer(SC);
+ assert(!SC->getNextSwitchCase() &&
+ "case/default already added to a switch");
+ SC->setNextSwitchCase(FirstCase);
+ FirstCase = SC;
}
/// Set a flag in the SwitchStmt indicating that if the 'switch (X)' is a
/// switch over an enum value then all cases have been explicitly covered.
- void setAllEnumCasesCovered() { FirstCase.setInt(true); }
+ void setAllEnumCasesCovered() { SwitchStmtBits.AllEnumCasesCovered = true; }
/// Returns true if the SwitchStmt is a switch of an enum value and all cases
/// have been explicitly covered.
- bool isAllEnumCasesCovered() const { return FirstCase.getInt(); }
-
- SourceLocation getLocStart() const LLVM_READONLY { return SwitchLoc; }
+ bool isAllEnumCasesCovered() const {
+ return SwitchStmtBits.AllEnumCasesCovered;
+ }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return SubExprs[BODY] ? SubExprs[BODY]->getLocEnd() : SubExprs[COND]->getLocEnd();
+ SourceLocation getBeginLoc() const { return getSwitchLoc(); }
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return getBody() ? getBody()->getEndLoc()
+ : reinterpret_cast<const Stmt *>(getCond())->getEndLoc();
}
// Iterators
child_range children() {
- return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
+ return child_range(getTrailingObjects<Stmt *>(),
+ getTrailingObjects<Stmt *>() +
+ numTrailingObjects(OverloadToken<Stmt *>()));
}
static bool classof(const Stmt *T) {
@@ -1117,17 +2060,75 @@ public:
};
/// WhileStmt - This represents a 'while' stmt.
-class WhileStmt : public Stmt {
- SourceLocation WhileLoc;
- enum { VAR, COND, BODY, END_EXPR };
- Stmt* SubExprs[END_EXPR];
+class WhileStmt final : public Stmt,
+ private llvm::TrailingObjects<WhileStmt, Stmt *> {
+ friend TrailingObjects;
-public:
- WhileStmt(const ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body,
+ // WhileStmt is followed by several trailing objects,
+ // some of which optional. Note that it would be more
+ // convenient to put the optional trailing object at the end
+ // but this would affect children().
+ // The trailing objects are in order:
+ //
+ // * A "Stmt *" for the condition variable.
+ // Present if and only if hasVarStorage(). This is in fact a "DeclStmt *".
+ //
+ // * A "Stmt *" for the condition.
+ // Always present. This is in fact an "Expr *".
+ //
+ // * A "Stmt *" for the body.
+ // Always present.
+ //
+ enum { VarOffset = 0, BodyOffsetFromCond = 1 };
+ enum { NumMandatoryStmtPtr = 2 };
+
+ unsigned varOffset() const { return VarOffset; }
+ unsigned condOffset() const { return VarOffset + hasVarStorage(); }
+ unsigned bodyOffset() const { return condOffset() + BodyOffsetFromCond; }
+
+ unsigned numTrailingObjects(OverloadToken<Stmt *>) const {
+ return NumMandatoryStmtPtr + hasVarStorage();
+ }
+
+ /// Build a while statement.
+ WhileStmt(const ASTContext &Ctx, VarDecl *Var, Expr *Cond, Stmt *Body,
SourceLocation WL);
/// Build an empty while statement.
- explicit WhileStmt(EmptyShell Empty) : Stmt(WhileStmtClass, Empty) {}
+ explicit WhileStmt(EmptyShell Empty, bool HasVar);
+
+public:
+ /// Create a while statement.
+ static WhileStmt *Create(const ASTContext &Ctx, VarDecl *Var, Expr *Cond,
+ Stmt *Body, SourceLocation WL);
+
+ /// Create an empty while statement optionally with storage for
+ /// a condition variable.
+ static WhileStmt *CreateEmpty(const ASTContext &Ctx, bool HasVar);
+
+ /// True if this WhileStmt has storage for a condition variable.
+ bool hasVarStorage() const { return WhileStmtBits.HasVar; }
+
+ Expr *getCond() {
+ return reinterpret_cast<Expr *>(getTrailingObjects<Stmt *>()[condOffset()]);
+ }
+
+ const Expr *getCond() const {
+ return reinterpret_cast<Expr *>(getTrailingObjects<Stmt *>()[condOffset()]);
+ }
+
+ void setCond(Expr *Cond) {
+ getTrailingObjects<Stmt *>()[condOffset()] = reinterpret_cast<Stmt *>(Cond);
+ }
+
+ Stmt *getBody() { return getTrailingObjects<Stmt *>()[bodyOffset()]; }
+ const Stmt *getBody() const {
+ return getTrailingObjects<Stmt *>()[bodyOffset()];
+ }
+
+ void setBody(Stmt *Body) {
+ getTrailingObjects<Stmt *>()[bodyOffset()] = Body;
+ }
/// Retrieve the variable declared in this "while" statement, if any.
///
@@ -1137,29 +2138,35 @@ public:
/// // ...
/// }
/// \endcode
- VarDecl *getConditionVariable() const;
- void setConditionVariable(const ASTContext &C, VarDecl *V);
+ VarDecl *getConditionVariable();
+ const VarDecl *getConditionVariable() const {
+ return const_cast<WhileStmt *>(this)->getConditionVariable();
+ }
+
+ /// Set the condition variable of this while statement.
+ /// The while statement must have storage for it.
+ void setConditionVariable(const ASTContext &Ctx, VarDecl *V);
/// If this WhileStmt has a condition variable, return the faux DeclStmt
/// associated with the creation of that condition variable.
- const DeclStmt *getConditionVariableDeclStmt() const {
- return reinterpret_cast<DeclStmt*>(SubExprs[VAR]);
+ DeclStmt *getConditionVariableDeclStmt() {
+ return hasVarStorage() ? static_cast<DeclStmt *>(
+ getTrailingObjects<Stmt *>()[varOffset()])
+ : nullptr;
}
- Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
- const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
- void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
- Stmt *getBody() { return SubExprs[BODY]; }
- const Stmt *getBody() const { return SubExprs[BODY]; }
- void setBody(Stmt *S) { SubExprs[BODY] = S; }
-
- SourceLocation getWhileLoc() const { return WhileLoc; }
- void setWhileLoc(SourceLocation L) { WhileLoc = L; }
+ const DeclStmt *getConditionVariableDeclStmt() const {
+ return hasVarStorage() ? static_cast<DeclStmt *>(
+ getTrailingObjects<Stmt *>()[varOffset()])
+ : nullptr;
+ }
- SourceLocation getLocStart() const LLVM_READONLY { return WhileLoc; }
+ SourceLocation getWhileLoc() const { return WhileStmtBits.WhileLoc; }
+ void setWhileLoc(SourceLocation L) { WhileStmtBits.WhileLoc = L; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return SubExprs[BODY]->getLocEnd();
+ SourceLocation getBeginLoc() const { return getWhileLoc(); }
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return getBody()->getEndLoc();
}
static bool classof(const Stmt *T) {
@@ -1168,46 +2175,51 @@ public:
// Iterators
child_range children() {
- return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
+ return child_range(getTrailingObjects<Stmt *>(),
+ getTrailingObjects<Stmt *>() +
+ numTrailingObjects(OverloadToken<Stmt *>()));
}
};
/// DoStmt - This represents a 'do/while' stmt.
class DoStmt : public Stmt {
- SourceLocation DoLoc;
enum { BODY, COND, END_EXPR };
- Stmt* SubExprs[END_EXPR];
+ Stmt *SubExprs[END_EXPR];
SourceLocation WhileLoc;
- SourceLocation RParenLoc; // Location of final ')' in do stmt condition.
+ SourceLocation RParenLoc; // Location of final ')' in do stmt condition.
public:
- DoStmt(Stmt *body, Expr *cond, SourceLocation DL, SourceLocation WL,
+ DoStmt(Stmt *Body, Expr *Cond, SourceLocation DL, SourceLocation WL,
SourceLocation RP)
- : Stmt(DoStmtClass), DoLoc(DL), WhileLoc(WL), RParenLoc(RP) {
- SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
- SubExprs[BODY] = body;
+ : Stmt(DoStmtClass), WhileLoc(WL), RParenLoc(RP) {
+ setCond(Cond);
+ setBody(Body);
+ setDoLoc(DL);
}
/// Build an empty do-while statement.
explicit DoStmt(EmptyShell Empty) : Stmt(DoStmtClass, Empty) {}
- Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
- const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
- void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
+ Expr *getCond() { return reinterpret_cast<Expr *>(SubExprs[COND]); }
+ const Expr *getCond() const {
+ return reinterpret_cast<Expr *>(SubExprs[COND]);
+ }
+
+ void setCond(Expr *Cond) { SubExprs[COND] = reinterpret_cast<Stmt *>(Cond); }
+
Stmt *getBody() { return SubExprs[BODY]; }
const Stmt *getBody() const { return SubExprs[BODY]; }
- void setBody(Stmt *S) { SubExprs[BODY] = S; }
+ void setBody(Stmt *Body) { SubExprs[BODY] = Body; }
- SourceLocation getDoLoc() const { return DoLoc; }
- void setDoLoc(SourceLocation L) { DoLoc = L; }
+ SourceLocation getDoLoc() const { return DoStmtBits.DoLoc; }
+ void setDoLoc(SourceLocation L) { DoStmtBits.DoLoc = L; }
SourceLocation getWhileLoc() const { return WhileLoc; }
void setWhileLoc(SourceLocation L) { WhileLoc = L; }
-
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceLocation getLocStart() const LLVM_READONLY { return DoLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+ SourceLocation getBeginLoc() const { return getDoLoc(); }
+ SourceLocation getEndLoc() const { return getRParenLoc(); }
static bool classof(const Stmt *T) {
return T->getStmtClass() == DoStmtClass;
@@ -1215,7 +2227,7 @@ public:
// Iterators
child_range children() {
- return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
+ return child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
}
};
@@ -1223,7 +2235,6 @@ public:
/// the init/cond/inc parts of the ForStmt will be null if they were not
/// specified in the source.
class ForStmt : public Stmt {
- SourceLocation ForLoc;
enum { INIT, CONDVAR, COND, INC, BODY, END_EXPR };
Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt.
SourceLocation LParenLoc, RParenLoc;
@@ -1269,18 +2280,15 @@ public:
void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast<Stmt*>(E); }
void setBody(Stmt *S) { SubExprs[BODY] = S; }
- SourceLocation getForLoc() const { return ForLoc; }
- void setForLoc(SourceLocation L) { ForLoc = L; }
+ SourceLocation getForLoc() const { return ForStmtBits.ForLoc; }
+ void setForLoc(SourceLocation L) { ForStmtBits.ForLoc = L; }
SourceLocation getLParenLoc() const { return LParenLoc; }
void setLParenLoc(SourceLocation L) { LParenLoc = L; }
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceLocation getLocStart() const LLVM_READONLY { return ForLoc; }
-
- SourceLocation getLocEnd() const LLVM_READONLY {
- return SubExprs[BODY]->getLocEnd();
- }
+ SourceLocation getBeginLoc() const { return getForLoc(); }
+ SourceLocation getEndLoc() const { return getBody()->getEndLoc(); }
static bool classof(const Stmt *T) {
return T->getStmtClass() == ForStmtClass;
@@ -1295,12 +2303,13 @@ public:
/// GotoStmt - This represents a direct goto.
class GotoStmt : public Stmt {
LabelDecl *Label;
- SourceLocation GotoLoc;
SourceLocation LabelLoc;
public:
GotoStmt(LabelDecl *label, SourceLocation GL, SourceLocation LL)
- : Stmt(GotoStmtClass), Label(label), GotoLoc(GL), LabelLoc(LL) {}
+ : Stmt(GotoStmtClass), Label(label), LabelLoc(LL) {
+ setGotoLoc(GL);
+ }
/// Build an empty goto statement.
explicit GotoStmt(EmptyShell Empty) : Stmt(GotoStmtClass, Empty) {}
@@ -1308,13 +2317,13 @@ public:
LabelDecl *getLabel() const { return Label; }
void setLabel(LabelDecl *D) { Label = D; }
- SourceLocation getGotoLoc() const { return GotoLoc; }
- void setGotoLoc(SourceLocation L) { GotoLoc = L; }
+ SourceLocation getGotoLoc() const { return GotoStmtBits.GotoLoc; }
+ void setGotoLoc(SourceLocation L) { GotoStmtBits.GotoLoc = L; }
SourceLocation getLabelLoc() const { return LabelLoc; }
void setLabelLoc(SourceLocation L) { LabelLoc = L; }
- SourceLocation getLocStart() const LLVM_READONLY { return GotoLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return LabelLoc; }
+ SourceLocation getBeginLoc() const { return getGotoLoc(); }
+ SourceLocation getEndLoc() const { return getLabelLoc(); }
static bool classof(const Stmt *T) {
return T->getStmtClass() == GotoStmtClass;
@@ -1328,62 +2337,64 @@ public:
/// IndirectGotoStmt - This represents an indirect goto.
class IndirectGotoStmt : public Stmt {
- SourceLocation GotoLoc;
SourceLocation StarLoc;
Stmt *Target;
public:
- IndirectGotoStmt(SourceLocation gotoLoc, SourceLocation starLoc,
- Expr *target)
- : Stmt(IndirectGotoStmtClass), GotoLoc(gotoLoc), StarLoc(starLoc),
- Target((Stmt*)target) {}
+ IndirectGotoStmt(SourceLocation gotoLoc, SourceLocation starLoc, Expr *target)
+ : Stmt(IndirectGotoStmtClass), StarLoc(starLoc) {
+ setTarget(target);
+ setGotoLoc(gotoLoc);
+ }
/// Build an empty indirect goto statement.
explicit IndirectGotoStmt(EmptyShell Empty)
: Stmt(IndirectGotoStmtClass, Empty) {}
- void setGotoLoc(SourceLocation L) { GotoLoc = L; }
- SourceLocation getGotoLoc() const { return GotoLoc; }
+ void setGotoLoc(SourceLocation L) { GotoStmtBits.GotoLoc = L; }
+ SourceLocation getGotoLoc() const { return GotoStmtBits.GotoLoc; }
void setStarLoc(SourceLocation L) { StarLoc = L; }
SourceLocation getStarLoc() const { return StarLoc; }
- Expr *getTarget() { return reinterpret_cast<Expr*>(Target); }
- const Expr *getTarget() const {return reinterpret_cast<const Expr*>(Target);}
- void setTarget(Expr *E) { Target = reinterpret_cast<Stmt*>(E); }
+ Expr *getTarget() { return reinterpret_cast<Expr *>(Target); }
+ const Expr *getTarget() const {
+ return reinterpret_cast<const Expr *>(Target);
+ }
+ void setTarget(Expr *E) { Target = reinterpret_cast<Stmt *>(E); }
/// getConstantTarget - Returns the fixed target of this indirect
/// goto, if one exists.
LabelDecl *getConstantTarget();
const LabelDecl *getConstantTarget() const {
- return const_cast<IndirectGotoStmt*>(this)->getConstantTarget();
+ return const_cast<IndirectGotoStmt *>(this)->getConstantTarget();
}
- SourceLocation getLocStart() const LLVM_READONLY { return GotoLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Target->getLocEnd(); }
+ SourceLocation getBeginLoc() const { return getGotoLoc(); }
+ SourceLocation getEndLoc() const LLVM_READONLY { return Target->getEndLoc(); }
static bool classof(const Stmt *T) {
return T->getStmtClass() == IndirectGotoStmtClass;
}
// Iterators
- child_range children() { return child_range(&Target, &Target+1); }
+ child_range children() { return child_range(&Target, &Target + 1); }
};
/// ContinueStmt - This represents a continue.
class ContinueStmt : public Stmt {
- SourceLocation ContinueLoc;
-
public:
- ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {}
+ ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass) {
+ setContinueLoc(CL);
+ }
/// Build an empty continue statement.
explicit ContinueStmt(EmptyShell Empty) : Stmt(ContinueStmtClass, Empty) {}
- SourceLocation getContinueLoc() const { return ContinueLoc; }
- void setContinueLoc(SourceLocation L) { ContinueLoc = L; }
+ SourceLocation getContinueLoc() const { return ContinueStmtBits.ContinueLoc; }
+ void setContinueLoc(SourceLocation L) { ContinueStmtBits.ContinueLoc = L; }
- SourceLocation getLocStart() const LLVM_READONLY { return ContinueLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return ContinueLoc; }
+ SourceLocation getBeginLoc() const { return getContinueLoc(); }
+ SourceLocation getEndLoc() const { return getContinueLoc(); }
static bool classof(const Stmt *T) {
return T->getStmtClass() == ContinueStmtClass;
@@ -1397,22 +2408,19 @@ public:
/// BreakStmt - This represents a break.
class BreakStmt : public Stmt {
- SourceLocation BreakLoc;
-
public:
- BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {
- static_assert(sizeof(BreakStmt) == 2 * sizeof(SourceLocation),
- "BreakStmt too large");
+ BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass) {
+ setBreakLoc(BL);
}
/// Build an empty break statement.
explicit BreakStmt(EmptyShell Empty) : Stmt(BreakStmtClass, Empty) {}
- SourceLocation getBreakLoc() const { return BreakLoc; }
- void setBreakLoc(SourceLocation L) { BreakLoc = L; }
+ SourceLocation getBreakLoc() const { return BreakStmtBits.BreakLoc; }
+ void setBreakLoc(SourceLocation L) { BreakStmtBits.BreakLoc = L; }
- SourceLocation getLocStart() const LLVM_READONLY { return BreakLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return BreakLoc; }
+ SourceLocation getBeginLoc() const { return getBreakLoc(); }
+ SourceLocation getEndLoc() const { return getBreakLoc(); }
static bool classof(const Stmt *T) {
return T->getStmtClass() == BreakStmtClass;
@@ -1432,40 +2440,68 @@ public:
/// return a value, and it allows returning a value in functions declared to
/// return void. We explicitly model this in the AST, which means you can't
/// depend on the return type of the function and the presence of an argument.
-class ReturnStmt : public Stmt {
- SourceLocation RetLoc;
+class ReturnStmt final
+ : public Stmt,
+ private llvm::TrailingObjects<ReturnStmt, const VarDecl *> {
+ friend TrailingObjects;
+
+ /// The return expression.
Stmt *RetExpr;
- const VarDecl *NRVOCandidate;
-public:
- explicit ReturnStmt(SourceLocation RL) : ReturnStmt(RL, nullptr, nullptr) {}
+ // ReturnStmt is followed optionally by a trailing "const VarDecl *"
+ // for the NRVO candidate. Present if and only if hasNRVOCandidate().
- ReturnStmt(SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate)
- : Stmt(ReturnStmtClass), RetLoc(RL), RetExpr((Stmt *)E),
- NRVOCandidate(NRVOCandidate) {}
+ /// True if this ReturnStmt has storage for an NRVO candidate.
+ bool hasNRVOCandidate() const { return ReturnStmtBits.HasNRVOCandidate; }
- /// Build an empty return expression.
- explicit ReturnStmt(EmptyShell Empty) : Stmt(ReturnStmtClass, Empty) {}
+ unsigned numTrailingObjects(OverloadToken<const VarDecl *>) const {
+ return hasNRVOCandidate();
+ }
+
+ /// Build a return statement.
+ ReturnStmt(SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate);
+
+ /// Build an empty return statement.
+ explicit ReturnStmt(EmptyShell Empty, bool HasNRVOCandidate);
+
+public:
+ /// Create a return statement.
+ static ReturnStmt *Create(const ASTContext &Ctx, SourceLocation RL, Expr *E,
+ const VarDecl *NRVOCandidate);
- const Expr *getRetValue() const;
- Expr *getRetValue();
- void setRetValue(Expr *E) { RetExpr = reinterpret_cast<Stmt*>(E); }
+ /// Create an empty return statement, optionally with
+ /// storage for an NRVO candidate.
+ static ReturnStmt *CreateEmpty(const ASTContext &Ctx, bool HasNRVOCandidate);
- SourceLocation getReturnLoc() const { return RetLoc; }
- void setReturnLoc(SourceLocation L) { RetLoc = L; }
+ Expr *getRetValue() { return reinterpret_cast<Expr *>(RetExpr); }
+ const Expr *getRetValue() const { return reinterpret_cast<Expr *>(RetExpr); }
+ void setRetValue(Expr *E) { RetExpr = reinterpret_cast<Stmt *>(E); }
/// Retrieve the variable that might be used for the named return
/// value optimization.
///
/// The optimization itself can only be performed if the variable is
/// also marked as an NRVO object.
- const VarDecl *getNRVOCandidate() const { return NRVOCandidate; }
- void setNRVOCandidate(const VarDecl *Var) { NRVOCandidate = Var; }
+ const VarDecl *getNRVOCandidate() const {
+ return hasNRVOCandidate() ? *getTrailingObjects<const VarDecl *>()
+ : nullptr;
+ }
+
+ /// Set the variable that might be used for the named return value
+ /// optimization. The return statement must have storage for it,
+ /// which is the case if and only if hasNRVOCandidate() is true.
+ void setNRVOCandidate(const VarDecl *Var) {
+ assert(hasNRVOCandidate() &&
+ "This return statement has no storage for an NRVO candidate!");
+ *getTrailingObjects<const VarDecl *>() = Var;
+ }
- SourceLocation getLocStart() const LLVM_READONLY { return RetLoc; }
+ SourceLocation getReturnLoc() const { return ReturnStmtBits.RetLoc; }
+ void setReturnLoc(SourceLocation L) { ReturnStmtBits.RetLoc = L; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return RetExpr ? RetExpr->getLocEnd() : RetLoc;
+ SourceLocation getBeginLoc() const { return getReturnLoc(); }
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return RetExpr ? RetExpr->getEndLoc() : getReturnLoc();
}
static bool classof(const Stmt *T) {
@@ -1474,7 +2510,8 @@ public:
// Iterators
child_range children() {
- if (RetExpr) return child_range(&RetExpr, &RetExpr+1);
+ if (RetExpr)
+ return child_range(&RetExpr, &RetExpr + 1);
return child_range(child_iterator(), child_iterator());
}
};
@@ -1519,8 +2556,8 @@ public:
bool isVolatile() const { return IsVolatile; }
void setVolatile(bool V) { IsVolatile = V; }
- SourceLocation getLocStart() const LLVM_READONLY { return {}; }
- SourceLocation getLocEnd() const LLVM_READONLY { return {}; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return {}; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return {}; }
//===--- Asm String Analysis ---===//
@@ -1801,8 +2838,8 @@ public:
return Clobbers[i];
}
- SourceLocation getLocStart() const LLVM_READONLY { return AsmLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return AsmLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == GCCAsmStmtClass;
@@ -1899,8 +2936,7 @@ private:
ArrayRef<Expr*> Exprs, ArrayRef<StringRef> Clobbers);
public:
- SourceLocation getLocStart() const LLVM_READONLY { return AsmLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return EndLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return AsmLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == MSAsmStmtClass;
@@ -1929,11 +2965,10 @@ public:
Expr *FilterExpr,
Stmt *Block);
- SourceLocation getLocStart() const LLVM_READONLY { return getExceptLoc(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return getExceptLoc(); }
SourceLocation getExceptLoc() const { return Loc; }
- SourceLocation getEndLoc() const { return getBlock()->getLocEnd(); }
+ SourceLocation getEndLoc() const { return getBlock()->getEndLoc(); }
Expr *getFilterExpr() const {
return reinterpret_cast<Expr*>(Children[FILTER_EXPR]);
@@ -1967,11 +3002,10 @@ public:
SourceLocation FinallyLoc,
Stmt *Block);
- SourceLocation getLocStart() const LLVM_READONLY { return getFinallyLoc(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return getFinallyLoc(); }
SourceLocation getFinallyLoc() const { return Loc; }
- SourceLocation getEndLoc() const { return Block->getLocEnd(); }
+ SourceLocation getEndLoc() const { return Block->getEndLoc(); }
CompoundStmt *getBlock() const { return cast<CompoundStmt>(Block); }
@@ -2006,11 +3040,10 @@ public:
SourceLocation TryLoc, Stmt *TryBlock,
Stmt *Handler);
- SourceLocation getLocStart() const LLVM_READONLY { return getTryLoc(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return getTryLoc(); }
SourceLocation getTryLoc() const { return TryLoc; }
- SourceLocation getEndLoc() const { return Children[HANDLER]->getLocEnd(); }
+ SourceLocation getEndLoc() const { return Children[HANDLER]->getEndLoc(); }
bool getIsCXXTry() const { return IsCXXTry; }
@@ -2047,8 +3080,8 @@ public:
SourceLocation getLeaveLoc() const { return LeaveLoc; }
void setLeaveLoc(SourceLocation L) { LeaveLoc = L; }
- SourceLocation getLocStart() const LLVM_READONLY { return LeaveLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return LeaveLoc; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return LeaveLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return LeaveLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == SEHLeaveStmtClass;
@@ -2261,12 +3294,12 @@ public:
return capture_init_begin() + NumCaptures;
}
- SourceLocation getLocStart() const LLVM_READONLY {
- return getCapturedStmt()->getLocStart();
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return getCapturedStmt()->getBeginLoc();
}
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getCapturedStmt()->getLocEnd();
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return getCapturedStmt()->getEndLoc();
}
SourceRange getSourceRange() const LLVM_READONLY {
diff --git a/include/clang/AST/StmtCXX.h b/include/clang/AST/StmtCXX.h
index 34553741eb38..d3a3cf783c66 100644
--- a/include/clang/AST/StmtCXX.h
+++ b/include/clang/AST/StmtCXX.h
@@ -41,9 +41,9 @@ public:
CXXCatchStmt(EmptyShell Empty)
: Stmt(CXXCatchStmtClass), ExceptionDecl(nullptr), HandlerBlock(nullptr) {}
- SourceLocation getLocStart() const LLVM_READONLY { return CatchLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return HandlerBlock->getLocEnd();
+ SourceLocation getBeginLoc() const LLVM_READONLY { return CatchLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return HandlerBlock->getEndLoc();
}
SourceLocation getCatchLoc() const { return CatchLoc; }
@@ -86,12 +86,11 @@ public:
static CXXTryStmt *Create(const ASTContext &C, EmptyShell Empty,
unsigned numHandlers);
- SourceLocation getLocStart() const LLVM_READONLY { return getTryLoc(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return getTryLoc(); }
SourceLocation getTryLoc() const { return TryLoc; }
SourceLocation getEndLoc() const {
- return getStmts()[NumHandlers]->getLocEnd();
+ return getStmts()[NumHandlers]->getEndLoc();
}
CompoundStmt *getTryBlock() {
@@ -119,14 +118,15 @@ public:
};
/// CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for
-/// statement, represented as 'for (range-declarator : range-expression)'.
+/// statement, represented as 'for (range-declarator : range-expression)'
+/// or 'for (init-statement range-declarator : range-expression)'.
///
/// This is stored in a partially-desugared form to allow full semantic
/// analysis of the constituent components. The original syntactic components
/// can be extracted using getLoopVariable and getRangeInit.
class CXXForRangeStmt : public Stmt {
SourceLocation ForLoc;
- enum { RANGE, BEGINSTMT, ENDSTMT, COND, INC, LOOPVAR, BODY, END };
+ enum { INIT, RANGE, BEGINSTMT, ENDSTMT, COND, INC, LOOPVAR, BODY, END };
// SubExprs[RANGE] is an expression or declstmt.
// SubExprs[COND] and SubExprs[INC] are expressions.
Stmt *SubExprs[END];
@@ -136,16 +136,17 @@ class CXXForRangeStmt : public Stmt {
friend class ASTStmtReader;
public:
- CXXForRangeStmt(DeclStmt *Range, DeclStmt *Begin, DeclStmt *End,
- Expr *Cond, Expr *Inc, DeclStmt *LoopVar, Stmt *Body,
- SourceLocation FL, SourceLocation CAL, SourceLocation CL,
- SourceLocation RPL);
+ CXXForRangeStmt(Stmt *InitStmt, DeclStmt *Range, DeclStmt *Begin,
+ DeclStmt *End, Expr *Cond, Expr *Inc, DeclStmt *LoopVar,
+ Stmt *Body, SourceLocation FL, SourceLocation CAL,
+ SourceLocation CL, SourceLocation RPL);
CXXForRangeStmt(EmptyShell Empty) : Stmt(CXXForRangeStmtClass, Empty) { }
-
+ Stmt *getInit() { return SubExprs[INIT]; }
VarDecl *getLoopVariable();
Expr *getRangeInit();
+ const Stmt *getInit() const { return SubExprs[INIT]; }
const VarDecl *getLoopVariable() const;
const Expr *getRangeInit() const;
@@ -180,6 +181,7 @@ public:
}
const Stmt *getBody() const { return SubExprs[BODY]; }
+ void setInit(Stmt *S) { SubExprs[INIT] = S; }
void setRangeInit(Expr *E) { SubExprs[RANGE] = reinterpret_cast<Stmt*>(E); }
void setRangeStmt(Stmt *S) { SubExprs[RANGE] = S; }
void setBeginStmt(Stmt *S) { SubExprs[BEGINSTMT] = S; }
@@ -194,9 +196,9 @@ public:
SourceLocation getColonLoc() const { return ColonLoc; }
SourceLocation getRParenLoc() const { return RParenLoc; }
- SourceLocation getLocStart() const LLVM_READONLY { return ForLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return SubExprs[BODY]->getLocEnd();
+ SourceLocation getBeginLoc() const LLVM_READONLY { return ForLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return SubExprs[BODY]->getEndLoc();
}
static bool classof(const Stmt *T) {
@@ -280,8 +282,10 @@ public:
return reinterpret_cast<CompoundStmt *>(SubStmt);
}
- SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();}
+ SourceLocation getBeginLoc() const LLVM_READONLY { return KeywordLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return SubStmt->getEndLoc();
+ }
child_range children() {
return child_range(&SubStmt, &SubStmt+1);
@@ -399,12 +403,12 @@ public:
return {getStoredStmts() + SubStmt::FirstParamMove, NumParams};
}
- SourceLocation getLocStart() const LLVM_READONLY {
- return getBody() ? getBody()->getLocStart()
- : getPromiseDecl()->getLocStart();
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return getBody() ? getBody()->getBeginLoc()
+ : getPromiseDecl()->getBeginLoc();
}
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getBody() ? getBody()->getLocEnd() : getPromiseDecl()->getLocEnd();
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return getBody() ? getBody()->getEndLoc() : getPromiseDecl()->getEndLoc();
}
child_range children() {
@@ -464,9 +468,9 @@ public:
bool isImplicit() const { return IsImplicit; }
void setIsImplicit(bool value = true) { IsImplicit = value; }
- SourceLocation getLocStart() const LLVM_READONLY { return CoreturnLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getOperand() ? getOperand()->getLocEnd() : getLocStart();
+ SourceLocation getBeginLoc() const LLVM_READONLY { return CoreturnLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return getOperand() ? getOperand()->getEndLoc() : getBeginLoc();
}
child_range children() {
diff --git a/include/clang/AST/StmtDataCollectors.td b/include/clang/AST/StmtDataCollectors.td
index bf5f8c21707f..90ca08027330 100644
--- a/include/clang/AST/StmtDataCollectors.td
+++ b/include/clang/AST/StmtDataCollectors.td
@@ -3,8 +3,8 @@ class Stmt {
addData(S->getStmtClass());
// This ensures that non-macro-generated code isn't identical to
// macro-generated code.
- addData(data_collection::getMacroStack(S->getLocStart(), Context));
- addData(data_collection::getMacroStack(S->getLocEnd(), Context));
+ addData(data_collection::getMacroStack(S->getBeginLoc(), Context));
+ addData(data_collection::getMacroStack(S->getEndLoc(), Context));
}];
}
@@ -27,7 +27,7 @@ class ExpressionTraitExpr {
}
class PredefinedExpr {
code Code = [{
- addData(S->getIdentType());
+ addData(S->getIdentKind());
}];
}
class TypeTraitExpr {
diff --git a/include/clang/AST/StmtObjC.h b/include/clang/AST/StmtObjC.h
index 0b2cc78b65be..f0c0a9aeb6ac 100644
--- a/include/clang/AST/StmtObjC.h
+++ b/include/clang/AST/StmtObjC.h
@@ -55,9 +55,9 @@ public:
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }
- SourceLocation getLocStart() const LLVM_READONLY { return ForLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return SubExprs[BODY]->getLocEnd();
+ SourceLocation getBeginLoc() const LLVM_READONLY { return ForLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return SubExprs[BODY]->getEndLoc();
}
static bool classof(const Stmt *T) {
@@ -104,8 +104,8 @@ public:
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }
- SourceLocation getLocStart() const LLVM_READONLY { return AtCatchLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Body->getLocEnd(); }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return AtCatchLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return Body->getEndLoc(); }
bool hasEllipsis() const { return getCatchParamDecl() == nullptr; }
@@ -133,9 +133,9 @@ public:
Stmt *getFinallyBody() { return AtFinallyStmt; }
void setFinallyBody(Stmt *S) { AtFinallyStmt = S; }
- SourceLocation getLocStart() const LLVM_READONLY { return AtFinallyLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return AtFinallyStmt->getLocEnd();
+ SourceLocation getBeginLoc() const LLVM_READONLY { return AtFinallyLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return AtFinallyStmt->getEndLoc();
}
SourceLocation getAtFinallyLoc() const { return AtFinallyLoc; }
@@ -238,8 +238,8 @@ public:
getStmts()[1 + NumCatchStmts] = S;
}
- SourceLocation getLocStart() const LLVM_READONLY { return AtTryLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY;
+ SourceLocation getBeginLoc() const LLVM_READONLY { return AtTryLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY;
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCAtTryStmtClass;
@@ -295,9 +295,9 @@ public:
}
void setSynchExpr(Stmt *S) { SubStmts[SYNC_EXPR] = S; }
- SourceLocation getLocStart() const LLVM_READONLY { return AtSynchronizedLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getSynchBody()->getLocEnd();
+ SourceLocation getBeginLoc() const LLVM_READONLY { return AtSynchronizedLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return getSynchBody()->getEndLoc();
}
static bool classof(const Stmt *T) {
@@ -329,9 +329,9 @@ public:
SourceLocation getThrowLoc() const LLVM_READONLY { return AtThrowLoc; }
void setThrowLoc(SourceLocation Loc) { AtThrowLoc = Loc; }
- SourceLocation getLocStart() const LLVM_READONLY { return AtThrowLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return Throw ? Throw->getLocEnd() : AtThrowLoc;
+ SourceLocation getBeginLoc() const LLVM_READONLY { return AtThrowLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return Throw ? Throw->getEndLoc() : AtThrowLoc;
}
static bool classof(const Stmt *T) {
@@ -357,8 +357,10 @@ public:
Stmt *getSubStmt() { return SubStmt; }
void setSubStmt(Stmt *S) { SubStmt = S; }
- SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();}
+ SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return SubStmt->getEndLoc();
+ }
SourceLocation getAtLoc() const { return AtLoc; }
void setAtLoc(SourceLocation Loc) { AtLoc = Loc; }
diff --git a/include/clang/AST/StmtOpenMP.h b/include/clang/AST/StmtOpenMP.h
index d23375e7606b..d1eedd62b372 100644
--- a/include/clang/AST/StmtOpenMP.h
+++ b/include/clang/AST/StmtOpenMP.h
@@ -165,9 +165,9 @@ public:
}
/// Returns starting location of directive kind.
- SourceLocation getLocStart() const { return StartLoc; }
+ SourceLocation getBeginLoc() const { return StartLoc; }
/// Returns ending location of directive.
- SourceLocation getLocEnd() const { return EndLoc; }
+ SourceLocation getEndLoc() const { return EndLoc; }
/// Set starting location of directive kind.
///
@@ -392,9 +392,11 @@ class OMPLoopDirective : public OMPExecutableDirective {
CombinedConditionOffset = 25,
CombinedNextLowerBoundOffset = 26,
CombinedNextUpperBoundOffset = 27,
+ CombinedDistConditionOffset = 28,
+ CombinedParForInDistConditionOffset = 29,
// Offset to the end (and start of the following counters/updates/finals
// arrays) for combined distribute loop directives.
- CombinedDistributeEnd = 28,
+ CombinedDistributeEnd = 30,
};
/// Get the counters storage.
@@ -605,6 +607,17 @@ protected:
"expected loop bound sharing directive");
*std::next(child_begin(), CombinedNextUpperBoundOffset) = CombNUB;
}
+ void setCombinedDistCond(Expr *CombDistCond) {
+ assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
+ "expected loop bound distribute sharing directive");
+ *std::next(child_begin(), CombinedDistConditionOffset) = CombDistCond;
+ }
+ void setCombinedParForInDistCond(Expr *CombParForInDistCond) {
+ assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
+ "expected loop bound distribute sharing directive");
+ *std::next(child_begin(),
+ CombinedParForInDistConditionOffset) = CombParForInDistCond;
+ }
void setCounters(ArrayRef<Expr *> A);
void setPrivateCounters(ArrayRef<Expr *> A);
void setInits(ArrayRef<Expr *> A);
@@ -637,6 +650,13 @@ public:
/// Update of UpperBound for statically scheduled omp loops for
/// outer loop in combined constructs (e.g. 'distribute parallel for')
Expr *NUB;
+ /// Distribute Loop condition used when composing 'omp distribute'
+ /// with 'omp for' in a same construct when schedule is chunked.
+ Expr *DistCond;
+ /// 'omp parallel for' loop condition used when composed with
+ /// 'omp distribute' in the same construct and when schedule is
+ /// chunked and the chunk size is 1.
+ Expr *ParForInDistCond;
};
/// The expressions built for the OpenMP loop CodeGen for the
@@ -754,6 +774,8 @@ public:
DistCombinedFields.Cond = nullptr;
DistCombinedFields.NLB = nullptr;
DistCombinedFields.NUB = nullptr;
+ DistCombinedFields.DistCond = nullptr;
+ DistCombinedFields.ParForInDistCond = nullptr;
}
};
@@ -922,6 +944,18 @@ public:
return const_cast<Expr *>(reinterpret_cast<const Expr *>(
*std::next(child_begin(), CombinedNextUpperBoundOffset)));
}
+ Expr *getCombinedDistCond() const {
+ assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
+ "expected loop bound distribute sharing directive");
+ return const_cast<Expr *>(reinterpret_cast<const Expr *>(
+ *std::next(child_begin(), CombinedDistConditionOffset)));
+ }
+ Expr *getCombinedParForInDistCond() const {
+ assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
+ "expected loop bound distribute sharing directive");
+ return const_cast<Expr *>(reinterpret_cast<const Expr *>(
+ *std::next(child_begin(), CombinedParForInDistConditionOffset)));
+ }
const Stmt *getBody() const {
// This relies on the loop form is already checked by Sema.
const Stmt *Body =
diff --git a/include/clang/AST/StmtVisitor.h b/include/clang/AST/StmtVisitor.h
index 30bc257c7e79..ea40e0497307 100644
--- a/include/clang/AST/StmtVisitor.h
+++ b/include/clang/AST/StmtVisitor.h
@@ -22,15 +22,12 @@
#include "clang/AST/StmtObjC.h"
#include "clang/AST/StmtOpenMP.h"
#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include <utility>
namespace clang {
-
-template <typename T> struct make_ptr { using type = T *; };
-template <typename T> struct make_const_ptr { using type = const T *; };
-
/// StmtVisitorBase - This class implements a simple visitor for Stmt
/// subclasses. Since Expr derives from Stmt, this also includes support for
/// visiting Exprs.
@@ -182,53 +179,19 @@ public:
///
/// This class does not preserve constness of Stmt pointers (see also
/// ConstStmtVisitor).
-template<typename ImplClass, typename RetTy=void, typename... ParamTys>
+template <typename ImplClass, typename RetTy = void, typename... ParamTys>
class StmtVisitor
- : public StmtVisitorBase<make_ptr, ImplClass, RetTy, ParamTys...> {};
+ : public StmtVisitorBase<std::add_pointer, ImplClass, RetTy, ParamTys...> {
+};
/// ConstStmtVisitor - This class implements a simple visitor for Stmt
/// subclasses. Since Expr derives from Stmt, this also includes support for
/// visiting Exprs.
///
/// This class preserves constness of Stmt pointers (see also StmtVisitor).
-template<typename ImplClass, typename RetTy=void, typename... ParamTys>
-class ConstStmtVisitor
- : public StmtVisitorBase<make_const_ptr, ImplClass, RetTy, ParamTys...> {};
-
-/// This class implements a simple visitor for OMPClause
-/// subclasses.
-template<class ImplClass, template <typename> class Ptr, typename RetTy>
-class OMPClauseVisitorBase {
-public:
-#define PTR(CLASS) typename Ptr<CLASS>::type
-#define DISPATCH(CLASS) \
- return static_cast<ImplClass*>(this)->Visit##CLASS(static_cast<PTR(CLASS)>(S))
-
-#define OPENMP_CLAUSE(Name, Class) \
- RetTy Visit ## Class (PTR(Class) S) { DISPATCH(Class); }
-#include "clang/Basic/OpenMPKinds.def"
-
- RetTy Visit(PTR(OMPClause) S) {
- // Top switch clause: visit each OMPClause.
- switch (S->getClauseKind()) {
- default: llvm_unreachable("Unknown clause kind!");
-#define OPENMP_CLAUSE(Name, Class) \
- case OMPC_ ## Name : return Visit ## Class(static_cast<PTR(Class)>(S));
-#include "clang/Basic/OpenMPKinds.def"
- }
- }
- // Base case, ignore it. :)
- RetTy VisitOMPClause(PTR(OMPClause) Node) { return RetTy(); }
-#undef PTR
-#undef DISPATCH
-};
-
-template<class ImplClass, typename RetTy = void>
-class OMPClauseVisitor :
- public OMPClauseVisitorBase <ImplClass, make_ptr, RetTy> {};
-template<class ImplClass, typename RetTy = void>
-class ConstOMPClauseVisitor :
- public OMPClauseVisitorBase <ImplClass, make_const_ptr, RetTy> {};
+template <typename ImplClass, typename RetTy = void, typename... ParamTys>
+class ConstStmtVisitor : public StmtVisitorBase<llvm::make_const_ptr, ImplClass,
+ RetTy, ParamTys...> {};
} // namespace clang
diff --git a/include/clang/AST/TemplateArgumentVisitor.h b/include/clang/AST/TemplateArgumentVisitor.h
new file mode 100644
index 000000000000..e1cc392a1705
--- /dev/null
+++ b/include/clang/AST/TemplateArgumentVisitor.h
@@ -0,0 +1,99 @@
+//===- TemplateArgumentVisitor.h - Visitor for TArg subclasses --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the TemplateArgumentVisitor interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_TEMPLATEARGUMENTVISITOR_H
+#define LLVM_CLANG_AST_TEMPLATEARGUMENTVISITOR_H
+
+#include "clang/AST/TemplateBase.h"
+
+namespace clang {
+
+namespace templateargumentvisitor {
+
+/// A simple visitor class that helps create template argument visitors.
+template <template <typename> class Ref, typename ImplClass,
+ typename RetTy = void, typename... ParamTys>
+class Base {
+public:
+#define REF(CLASS) typename Ref<CLASS>::type
+#define DISPATCH(NAME) \
+ case TemplateArgument::NAME: \
+ return static_cast<ImplClass *>(this)->Visit##NAME##TemplateArgument( \
+ TA, std::forward<ParamTys>(P)...)
+
+ RetTy Visit(REF(TemplateArgument) TA, ParamTys... P) {
+ switch (TA.getKind()) {
+ DISPATCH(Null);
+ DISPATCH(Type);
+ DISPATCH(Declaration);
+ DISPATCH(NullPtr);
+ DISPATCH(Integral);
+ DISPATCH(Template);
+ DISPATCH(TemplateExpansion);
+ DISPATCH(Expression);
+ DISPATCH(Pack);
+ }
+ llvm_unreachable("TemplateArgument is not covered in switch!");
+ }
+
+ // If the implementation chooses not to implement a certain visit
+ // method, fall back to the parent.
+
+#define VISIT_METHOD(CATEGORY) \
+ RetTy Visit##CATEGORY##TemplateArgument(REF(TemplateArgument) TA, \
+ ParamTys... P) { \
+ return VisitTemplateArgument(TA, std::forward<ParamTys>(P)...); \
+ }
+
+ VISIT_METHOD(Null);
+ VISIT_METHOD(Type);
+ VISIT_METHOD(Declaration);
+ VISIT_METHOD(NullPtr);
+ VISIT_METHOD(Integral);
+ VISIT_METHOD(Template);
+ VISIT_METHOD(TemplateExpansion);
+ VISIT_METHOD(Expression);
+ VISIT_METHOD(Pack);
+
+ RetTy VisitTemplateArgument(REF(TemplateArgument), ParamTys...) {
+ return RetTy();
+ }
+
+#undef REF
+#undef DISPATCH
+#undef VISIT_METHOD
+};
+
+} // namespace templateargumentvisitor
+
+/// A simple visitor class that helps create template argument visitors.
+///
+/// This class does not preserve constness of TemplateArgument references (see
+/// also ConstTemplateArgumentVisitor).
+template <typename ImplClass, typename RetTy = void, typename... ParamTys>
+class TemplateArgumentVisitor
+ : public templateargumentvisitor::Base<std::add_lvalue_reference, ImplClass,
+ RetTy, ParamTys...> {};
+
+/// A simple visitor class that helps create template argument visitors.
+///
+/// This class preserves constness of TemplateArgument references (see also
+/// TemplateArgumentVisitor).
+template <typename ImplClass, typename RetTy = void, typename... ParamTys>
+class ConstTemplateArgumentVisitor
+ : public templateargumentvisitor::Base<llvm::make_const_ref, ImplClass,
+ RetTy, ParamTys...> {};
+
+} // namespace clang
+
+#endif // LLVM_CLANG_AST_TEMPLATEARGUMENTVISITOR_H
diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h
index 6898ef4e1b8a..e3a773b4e490 100644
--- a/include/clang/AST/TemplateBase.h
+++ b/include/clang/AST/TemplateBase.h
@@ -467,7 +467,7 @@ public:
: Argument(Argument), LocInfo(E) {
// Permit any kind of template argument that can be represented with an
- // expression
+ // expression.
assert(Argument.getKind() == TemplateArgument::NullPtr ||
Argument.getKind() == TemplateArgument::Integral ||
Argument.getKind() == TemplateArgument::Declaration ||
@@ -530,19 +530,22 @@ public:
}
NestedNameSpecifierLoc getTemplateQualifierLoc() const {
- assert(Argument.getKind() == TemplateArgument::Template ||
- Argument.getKind() == TemplateArgument::TemplateExpansion);
+ if (Argument.getKind() != TemplateArgument::Template &&
+ Argument.getKind() != TemplateArgument::TemplateExpansion)
+ return NestedNameSpecifierLoc();
return LocInfo.getTemplateQualifierLoc();
}
SourceLocation getTemplateNameLoc() const {
- assert(Argument.getKind() == TemplateArgument::Template ||
- Argument.getKind() == TemplateArgument::TemplateExpansion);
+ if (Argument.getKind() != TemplateArgument::Template &&
+ Argument.getKind() != TemplateArgument::TemplateExpansion)
+ return SourceLocation();
return LocInfo.getTemplateNameLoc();
}
SourceLocation getTemplateEllipsisLoc() const {
- assert(Argument.getKind() == TemplateArgument::TemplateExpansion);
+ if (Argument.getKind() != TemplateArgument::TemplateExpansion)
+ return SourceLocation();
return LocInfo.getTemplateEllipsisLoc();
}
};
@@ -617,13 +620,17 @@ public:
/// The number of template arguments in TemplateArgs.
unsigned NumTemplateArgs;
+ SourceLocation getLAngleLoc() const { return LAngleLoc; }
+ SourceLocation getRAngleLoc() const { return RAngleLoc; }
+
/// Retrieve the template arguments
const TemplateArgumentLoc *getTemplateArgs() const {
return getTrailingObjects<TemplateArgumentLoc>();
}
+ unsigned getNumTemplateArgs() const { return NumTemplateArgs; }
llvm::ArrayRef<TemplateArgumentLoc> arguments() const {
- return llvm::makeArrayRef(getTemplateArgs(), NumTemplateArgs);
+ return llvm::makeArrayRef(getTemplateArgs(), getNumTemplateArgs());
}
const TemplateArgumentLoc &operator[](unsigned I) const {
diff --git a/include/clang/AST/TemplateName.h b/include/clang/AST/TemplateName.h
index d88d58d0a2aa..48272597d4d1 100644
--- a/include/clang/AST/TemplateName.h
+++ b/include/clang/AST/TemplateName.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_AST_TEMPLATENAME_H
#define LLVM_CLANG_AST_TEMPLATENAME_H
+#include "clang/AST/NestedNameSpecifier.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/PointerIntPair.h"
diff --git a/include/clang/AST/TextNodeDumper.h b/include/clang/AST/TextNodeDumper.h
new file mode 100644
index 000000000000..794066376300
--- /dev/null
+++ b/include/clang/AST/TextNodeDumper.h
@@ -0,0 +1,298 @@
+//===--- TextNodeDumper.h - Printing of AST nodes -------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements AST dumping of components of individual AST nodes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_TEXTNODEDUMPER_H
+#define LLVM_CLANG_AST_TEXTNODEDUMPER_H
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTDumperUtils.h"
+#include "clang/AST/AttrVisitor.h"
+#include "clang/AST/CommentCommandTraits.h"
+#include "clang/AST/CommentVisitor.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/TemplateArgumentVisitor.h"
+#include "clang/AST/TypeVisitor.h"
+
+namespace clang {
+
+class TextTreeStructure {
+ raw_ostream &OS;
+ const bool ShowColors;
+
+ /// Pending[i] is an action to dump an entity at level i.
+ llvm::SmallVector<std::function<void(bool IsLastChild)>, 32> Pending;
+
+ /// Indicates whether we're at the top level.
+ bool TopLevel = true;
+
+ /// Indicates if we're handling the first child after entering a new depth.
+ bool FirstChild = true;
+
+ /// Prefix for currently-being-dumped entity.
+ std::string Prefix;
+
+public:
+ /// Add a child of the current node. Calls DoAddChild without arguments
+ template <typename Fn> void AddChild(Fn DoAddChild) {
+ return AddChild("", DoAddChild);
+ }
+
+ /// Add a child of the current node with an optional label.
+ /// Calls DoAddChild without arguments.
+ template <typename Fn> void AddChild(StringRef Label, Fn DoAddChild) {
+ // If we're at the top level, there's nothing interesting to do; just
+ // run the dumper.
+ if (TopLevel) {
+ TopLevel = false;
+ DoAddChild();
+ while (!Pending.empty()) {
+ Pending.back()(true);
+ Pending.pop_back();
+ }
+ Prefix.clear();
+ OS << "\n";
+ TopLevel = true;
+ return;
+ }
+
+ // We need to capture an owning-string in the lambda because the lambda
+ // is invoked in a deferred manner.
+ std::string LabelStr = Label;
+ auto DumpWithIndent = [this, DoAddChild, LabelStr](bool IsLastChild) {
+ // Print out the appropriate tree structure and work out the prefix for
+ // children of this node. For instance:
+ //
+ // A Prefix = ""
+ // |-B Prefix = "| "
+ // | `-C Prefix = "| "
+ // `-D Prefix = " "
+ // |-E Prefix = " | "
+ // `-F Prefix = " "
+ // G Prefix = ""
+ //
+ // Note that the first level gets no prefix.
+ {
+ OS << '\n';
+ ColorScope Color(OS, ShowColors, IndentColor);
+ OS << Prefix << (IsLastChild ? '`' : '|') << '-';
+ if (!LabelStr.empty())
+ OS << LabelStr << ": ";
+
+ this->Prefix.push_back(IsLastChild ? ' ' : '|');
+ this->Prefix.push_back(' ');
+ }
+
+ FirstChild = true;
+ unsigned Depth = Pending.size();
+
+ DoAddChild();
+
+ // If any children are left, they're the last at their nesting level.
+ // Dump those ones out now.
+ while (Depth < Pending.size()) {
+ Pending.back()(true);
+ this->Pending.pop_back();
+ }
+
+ // Restore the old prefix.
+ this->Prefix.resize(Prefix.size() - 2);
+ };
+
+ if (FirstChild) {
+ Pending.push_back(std::move(DumpWithIndent));
+ } else {
+ Pending.back()(false);
+ Pending.back() = std::move(DumpWithIndent);
+ }
+ FirstChild = false;
+ }
+
+ TextTreeStructure(raw_ostream &OS, bool ShowColors)
+ : OS(OS), ShowColors(ShowColors) {}
+};
+
+class TextNodeDumper
+ : public TextTreeStructure,
+ public comments::ConstCommentVisitor<TextNodeDumper, void,
+ const comments::FullComment *>,
+ public ConstAttrVisitor<TextNodeDumper>,
+ public ConstTemplateArgumentVisitor<TextNodeDumper>,
+ public ConstStmtVisitor<TextNodeDumper>,
+ public TypeVisitor<TextNodeDumper> {
+ raw_ostream &OS;
+ const bool ShowColors;
+
+ /// Keep track of the last location we print out so that we can
+ /// print out deltas from then on out.
+ const char *LastLocFilename = "";
+ unsigned LastLocLine = ~0U;
+
+ const SourceManager *SM;
+
+ /// The policy to use for printing; can be defaulted.
+ PrintingPolicy PrintPolicy;
+
+ const comments::CommandTraits *Traits;
+
+ const char *getCommandName(unsigned CommandID);
+
+public:
+ TextNodeDumper(raw_ostream &OS, bool ShowColors, const SourceManager *SM,
+ const PrintingPolicy &PrintPolicy,
+ const comments::CommandTraits *Traits);
+
+ void Visit(const comments::Comment *C, const comments::FullComment *FC);
+
+ void Visit(const Attr *A);
+
+ void Visit(const TemplateArgument &TA, SourceRange R,
+ const Decl *From = nullptr, StringRef Label = {});
+
+ void Visit(const Stmt *Node);
+
+ void Visit(const Type *T);
+
+ void Visit(QualType T);
+
+ void Visit(const Decl *D);
+
+ void Visit(const CXXCtorInitializer *Init);
+
+ void Visit(const OMPClause *C);
+
+ void Visit(const BlockDecl::Capture &C);
+
+ void dumpPointer(const void *Ptr);
+ void dumpLocation(SourceLocation Loc);
+ void dumpSourceRange(SourceRange R);
+ void dumpBareType(QualType T, bool Desugar = true);
+ void dumpType(QualType T);
+ void dumpBareDeclRef(const Decl *D);
+ void dumpName(const NamedDecl *ND);
+ void dumpAccessSpecifier(AccessSpecifier AS);
+
+ void dumpDeclRef(const Decl *D, StringRef Label = {});
+
+ void visitTextComment(const comments::TextComment *C,
+ const comments::FullComment *);
+ void visitInlineCommandComment(const comments::InlineCommandComment *C,
+ const comments::FullComment *);
+ void visitHTMLStartTagComment(const comments::HTMLStartTagComment *C,
+ const comments::FullComment *);
+ void visitHTMLEndTagComment(const comments::HTMLEndTagComment *C,
+ const comments::FullComment *);
+ void visitBlockCommandComment(const comments::BlockCommandComment *C,
+ const comments::FullComment *);
+ void visitParamCommandComment(const comments::ParamCommandComment *C,
+ const comments::FullComment *FC);
+ void visitTParamCommandComment(const comments::TParamCommandComment *C,
+ const comments::FullComment *FC);
+ void visitVerbatimBlockComment(const comments::VerbatimBlockComment *C,
+ const comments::FullComment *);
+ void
+ visitVerbatimBlockLineComment(const comments::VerbatimBlockLineComment *C,
+ const comments::FullComment *);
+ void visitVerbatimLineComment(const comments::VerbatimLineComment *C,
+ const comments::FullComment *);
+
+// Implements Visit methods for Attrs.
+#include "clang/AST/AttrTextNodeDump.inc"
+
+ void VisitNullTemplateArgument(const TemplateArgument &TA);
+ void VisitTypeTemplateArgument(const TemplateArgument &TA);
+ void VisitDeclarationTemplateArgument(const TemplateArgument &TA);
+ void VisitNullPtrTemplateArgument(const TemplateArgument &TA);
+ void VisitIntegralTemplateArgument(const TemplateArgument &TA);
+ void VisitTemplateTemplateArgument(const TemplateArgument &TA);
+ void VisitTemplateExpansionTemplateArgument(const TemplateArgument &TA);
+ void VisitExpressionTemplateArgument(const TemplateArgument &TA);
+ void VisitPackTemplateArgument(const TemplateArgument &TA);
+
+ void VisitIfStmt(const IfStmt *Node);
+ void VisitSwitchStmt(const SwitchStmt *Node);
+ void VisitWhileStmt(const WhileStmt *Node);
+ void VisitLabelStmt(const LabelStmt *Node);
+ void VisitGotoStmt(const GotoStmt *Node);
+ void VisitCaseStmt(const CaseStmt *Node);
+ void VisitCallExpr(const CallExpr *Node);
+ void VisitCastExpr(const CastExpr *Node);
+ void VisitImplicitCastExpr(const ImplicitCastExpr *Node);
+ void VisitDeclRefExpr(const DeclRefExpr *Node);
+ void VisitPredefinedExpr(const PredefinedExpr *Node);
+ void VisitCharacterLiteral(const CharacterLiteral *Node);
+ void VisitIntegerLiteral(const IntegerLiteral *Node);
+ void VisitFixedPointLiteral(const FixedPointLiteral *Node);
+ void VisitFloatingLiteral(const FloatingLiteral *Node);
+ void VisitStringLiteral(const StringLiteral *Str);
+ void VisitInitListExpr(const InitListExpr *ILE);
+ void VisitUnaryOperator(const UnaryOperator *Node);
+ void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Node);
+ void VisitMemberExpr(const MemberExpr *Node);
+ void VisitExtVectorElementExpr(const ExtVectorElementExpr *Node);
+ void VisitBinaryOperator(const BinaryOperator *Node);
+ void VisitCompoundAssignOperator(const CompoundAssignOperator *Node);
+ void VisitAddrLabelExpr(const AddrLabelExpr *Node);
+ void VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node);
+ void VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node);
+ void VisitCXXThisExpr(const CXXThisExpr *Node);
+ void VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node);
+ void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *Node);
+ void VisitCXXConstructExpr(const CXXConstructExpr *Node);
+ void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node);
+ void VisitCXXNewExpr(const CXXNewExpr *Node);
+ void VisitCXXDeleteExpr(const CXXDeleteExpr *Node);
+ void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Node);
+ void VisitExprWithCleanups(const ExprWithCleanups *Node);
+ void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node);
+ void VisitSizeOfPackExpr(const SizeOfPackExpr *Node);
+ void
+ VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *Node);
+ void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node);
+ void VisitObjCEncodeExpr(const ObjCEncodeExpr *Node);
+ void VisitObjCMessageExpr(const ObjCMessageExpr *Node);
+ void VisitObjCBoxedExpr(const ObjCBoxedExpr *Node);
+ void VisitObjCSelectorExpr(const ObjCSelectorExpr *Node);
+ void VisitObjCProtocolExpr(const ObjCProtocolExpr *Node);
+ void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node);
+ void VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node);
+ void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node);
+ void VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node);
+
+ void VisitRValueReferenceType(const ReferenceType *T);
+ void VisitArrayType(const ArrayType *T);
+ void VisitConstantArrayType(const ConstantArrayType *T);
+ void VisitVariableArrayType(const VariableArrayType *T);
+ void VisitDependentSizedArrayType(const DependentSizedArrayType *T);
+ void VisitDependentSizedExtVectorType(const DependentSizedExtVectorType *T);
+ void VisitVectorType(const VectorType *T);
+ void VisitFunctionType(const FunctionType *T);
+ void VisitFunctionProtoType(const FunctionProtoType *T);
+ void VisitUnresolvedUsingType(const UnresolvedUsingType *T);
+ void VisitTypedefType(const TypedefType *T);
+ void VisitUnaryTransformType(const UnaryTransformType *T);
+ void VisitTagType(const TagType *T);
+ void VisitTemplateTypeParmType(const TemplateTypeParmType *T);
+ void VisitAutoType(const AutoType *T);
+ void VisitTemplateSpecializationType(const TemplateSpecializationType *T);
+ void VisitInjectedClassNameType(const InjectedClassNameType *T);
+ void VisitObjCInterfaceType(const ObjCInterfaceType *T);
+ void VisitPackExpansionType(const PackExpansionType *T);
+
+private:
+ void dumpCXXTemporary(const CXXTemporary *Temporary);
+};
+
+} // namespace clang
+
+#endif // LLVM_CLANG_AST_TEXTNODEDUMPER_H
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index 9a8dd6faff31..d4c97b1b5efc 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -21,6 +21,7 @@
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/TemplateName.h"
#include "clang/Basic/AddressSpaces.h"
+#include "clang/Basic/AttrKinds.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/ExceptionSpecificationType.h"
#include "clang/Basic/LLVM.h"
@@ -45,6 +46,7 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
#include "llvm/Support/type_traits.h"
+#include "llvm/Support/TrailingObjects.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
@@ -100,48 +102,33 @@ namespace llvm {
namespace clang {
-class ArrayType;
class ASTContext;
-class AttributedType;
-class AutoType;
-class BuiltinType;
template <typename> class CanQual;
-class ComplexType;
class CXXRecordDecl;
class DeclContext;
-class DeducedType;
class EnumDecl;
class Expr;
class ExtQualsTypeCommonBase;
class FunctionDecl;
-class FunctionNoProtoType;
-class FunctionProtoType;
class IdentifierInfo;
-class InjectedClassNameType;
class NamedDecl;
class ObjCInterfaceDecl;
-class ObjCObjectPointerType;
-class ObjCObjectType;
class ObjCProtocolDecl;
class ObjCTypeParamDecl;
-class ParenType;
struct PrintingPolicy;
class RecordDecl;
-class RecordType;
class Stmt;
class TagDecl;
class TemplateArgument;
class TemplateArgumentListInfo;
class TemplateArgumentLoc;
-class TemplateSpecializationType;
class TemplateTypeParmDecl;
class TypedefNameDecl;
-class TypedefType;
class UnresolvedUsingTypenameDecl;
using CanQualType = CanQual<Type>;
- // Provide forward declarations for all of the *Type classes
+// Provide forward declarations for all of the *Type classes.
#define TYPE(Class, Base) class Class##Type;
#include "clang/AST/TypeNodes.def"
@@ -269,28 +256,24 @@ public:
}
bool hasConst() const { return Mask & Const; }
- void setConst(bool flag) {
- Mask = (Mask & ~Const) | (flag ? Const : 0);
- }
+ bool hasOnlyConst() const { return Mask == Const; }
void removeConst() { Mask &= ~Const; }
void addConst() { Mask |= Const; }
bool hasVolatile() const { return Mask & Volatile; }
- void setVolatile(bool flag) {
- Mask = (Mask & ~Volatile) | (flag ? Volatile : 0);
- }
+ bool hasOnlyVolatile() const { return Mask == Volatile; }
void removeVolatile() { Mask &= ~Volatile; }
void addVolatile() { Mask |= Volatile; }
bool hasRestrict() const { return Mask & Restrict; }
- void setRestrict(bool flag) {
- Mask = (Mask & ~Restrict) | (flag ? Restrict : 0);
- }
+ bool hasOnlyRestrict() const { return Mask == Restrict; }
void removeRestrict() { Mask &= ~Restrict; }
void addRestrict() { Mask |= Restrict; }
bool hasCVRQualifiers() const { return getCVRQualifiers(); }
unsigned getCVRQualifiers() const { return Mask & CVRMask; }
+ unsigned getCVRUQualifiers() const { return Mask & (CVRMask | UMask); }
+
void setCVRQualifiers(unsigned mask) {
assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits");
Mask = (Mask & ~CVRMask) | mask;
@@ -997,9 +980,7 @@ public:
void print(raw_ostream &OS, const PrintingPolicy &Policy,
const Twine &PlaceHolder = Twine(),
- unsigned Indentation = 0) const {
- print(split(), OS, Policy, PlaceHolder, Indentation);
- }
+ unsigned Indentation = 0) const;
static void print(SplitQualType split, raw_ostream &OS,
const PrintingPolicy &policy, const Twine &PlaceHolder,
@@ -1013,9 +994,7 @@ public:
unsigned Indentation = 0);
void getAsStringInternal(std::string &Str,
- const PrintingPolicy &Policy) const {
- return getAsStringInternal(split(), Str, Policy);
- }
+ const PrintingPolicy &Policy) const;
static void getAsStringInternal(SplitQualType split, std::string &out,
const PrintingPolicy &policy) {
@@ -1515,6 +1494,9 @@ protected:
unsigned Kind : 8;
};
+ /// FunctionTypeBitfields store various bits belonging to FunctionProtoType.
+ /// Only common bits are stored here. Additional uncommon bits are stored
+ /// in a trailing object after FunctionProtoType.
class FunctionTypeBitfields {
friend class FunctionProtoType;
friend class FunctionType;
@@ -1525,18 +1507,38 @@ protected:
/// regparm and the calling convention.
unsigned ExtInfo : 12;
+ /// The ref-qualifier associated with a \c FunctionProtoType.
+ ///
+ /// This is a value of type \c RefQualifierKind.
+ unsigned RefQualifier : 2;
+
/// Used only by FunctionProtoType, put here to pack with the
/// other bitfields.
/// The qualifiers are part of FunctionProtoType because...
///
/// C++ 8.3.5p4: The return type, the parameter type list and the
/// cv-qualifier-seq, [...], are part of the function type.
- unsigned TypeQuals : 4;
+ unsigned FastTypeQuals : Qualifiers::FastWidth;
+ /// Whether this function has extended Qualifiers.
+ unsigned HasExtQuals : 1;
- /// The ref-qualifier associated with a \c FunctionProtoType.
- ///
- /// This is a value of type \c RefQualifierKind.
- unsigned RefQualifier : 2;
+ /// The number of parameters this function has, not counting '...'.
+ /// According to [implimits] 8 bits should be enough here but this is
+ /// somewhat easy to exceed with metaprogramming and so we would like to
+ /// keep NumParams as wide as reasonably possible.
+ unsigned NumParams : 16;
+
+ /// The type of exception specification this function has.
+ unsigned ExceptionSpecType : 4;
+
+ /// Whether this function has extended parameter information.
+ unsigned HasExtParameterInfos : 1;
+
+ /// Whether the function is variadic.
+ unsigned Variadic : 1;
+
+ /// Whether this function has a trailing return type.
+ unsigned HasTrailingReturn : 1;
};
class ObjCObjectTypeBitfields {
@@ -1554,8 +1556,6 @@ protected:
unsigned IsKindOf : 1;
};
- static_assert(NumTypeBits + 7 + 6 + 1 <= 32, "Does not fit in an unsigned");
-
class ReferenceTypeBitfields {
friend class ReferenceType;
@@ -1588,6 +1588,18 @@ protected:
unsigned Keyword : 8;
};
+ enum { NumTypeWithKeywordBits = 8 };
+
+ class ElaboratedTypeBitfields {
+ friend class ElaboratedType;
+
+ unsigned : NumTypeBits;
+ unsigned : NumTypeWithKeywordBits;
+
+ /// Whether the ElaboratedType has a trailing OwnedTagDecl.
+ unsigned HasOwnedTagDecl : 1;
+ };
+
class VectorTypeBitfields {
friend class VectorType;
friend class DependentVectorType;
@@ -1623,6 +1635,74 @@ protected:
unsigned Keyword : 2;
};
+ class SubstTemplateTypeParmPackTypeBitfields {
+ friend class SubstTemplateTypeParmPackType;
+
+ unsigned : NumTypeBits;
+
+ /// The number of template arguments in \c Arguments, which is
+ /// expected to be able to hold at least 1024 according to [implimits].
+ /// However as this limit is somewhat easy to hit with template
+ /// metaprogramming we'd prefer to keep it as large as possible.
+ /// At the moment it has been left as a non-bitfield since this type
+ /// safely fits in 64 bits as an unsigned, so there is no reason to
+ /// introduce the performance impact of a bitfield.
+ unsigned NumArgs;
+ };
+
+ class TemplateSpecializationTypeBitfields {
+ friend class TemplateSpecializationType;
+
+ unsigned : NumTypeBits;
+
+ /// Whether this template specialization type is a substituted type alias.
+ unsigned TypeAlias : 1;
+
+ /// The number of template arguments named in this class template
+ /// specialization, which is expected to be able to hold at least 1024
+ /// according to [implimits]. However, as this limit is somewhat easy to
+ /// hit with template metaprogramming we'd prefer to keep it as large
+ /// as possible. At the moment it has been left as a non-bitfield since
+ /// this type safely fits in 64 bits as an unsigned, so there is no reason
+ /// to introduce the performance impact of a bitfield.
+ unsigned NumArgs;
+ };
+
+ class DependentTemplateSpecializationTypeBitfields {
+ friend class DependentTemplateSpecializationType;
+
+ unsigned : NumTypeBits;
+ unsigned : NumTypeWithKeywordBits;
+
+ /// The number of template arguments named in this class template
+ /// specialization, which is expected to be able to hold at least 1024
+ /// according to [implimits]. However, as this limit is somewhat easy to
+ /// hit with template metaprogramming we'd prefer to keep it as large
+ /// as possible. At the moment it has been left as a non-bitfield since
+ /// this type safely fits in 64 bits as an unsigned, so there is no reason
+ /// to introduce the performance impact of a bitfield.
+ unsigned NumArgs;
+ };
+
+ class PackExpansionTypeBitfields {
+ friend class PackExpansionType;
+
+ unsigned : NumTypeBits;
+
+ /// The number of expansions that this pack expansion will
+ /// generate when substituted (+1), which is expected to be able to
+ /// hold at least 1024 according to [implimits]. However, as this limit
+ /// is somewhat easy to hit with template metaprogramming we'd prefer to
+ /// keep it as large as possible. At the moment it has been left as a
+ /// non-bitfield since this type safely fits in 64 bits as an unsigned, so
+ /// there is no reason to introduce the performance impact of a bitfield.
+ ///
+ /// This field will only have a non-zero value when some of the parameter
+ /// packs that occur within the pattern have been substituted but others
+ /// have not.
+ unsigned NumExpansions;
+ };
+
union {
TypeBitfields TypeBits;
ArrayTypeBitfields ArrayTypeBits;
@@ -1633,7 +1713,47 @@ protected:
ObjCObjectTypeBitfields ObjCObjectTypeBits;
ReferenceTypeBitfields ReferenceTypeBits;
TypeWithKeywordBitfields TypeWithKeywordBits;
+ ElaboratedTypeBitfields ElaboratedTypeBits;
VectorTypeBitfields VectorTypeBits;
+ SubstTemplateTypeParmPackTypeBitfields SubstTemplateTypeParmPackTypeBits;
+ TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits;
+ DependentTemplateSpecializationTypeBitfields
+ DependentTemplateSpecializationTypeBits;
+ PackExpansionTypeBitfields PackExpansionTypeBits;
+
+ static_assert(sizeof(TypeBitfields) <= 8,
+ "TypeBitfields is larger than 8 bytes!");
+ static_assert(sizeof(ArrayTypeBitfields) <= 8,
+ "ArrayTypeBitfields is larger than 8 bytes!");
+ static_assert(sizeof(AttributedTypeBitfields) <= 8,
+ "AttributedTypeBitfields is larger than 8 bytes!");
+ static_assert(sizeof(AutoTypeBitfields) <= 8,
+ "AutoTypeBitfields is larger than 8 bytes!");
+ static_assert(sizeof(BuiltinTypeBitfields) <= 8,
+ "BuiltinTypeBitfields is larger than 8 bytes!");
+ static_assert(sizeof(FunctionTypeBitfields) <= 8,
+ "FunctionTypeBitfields is larger than 8 bytes!");
+ static_assert(sizeof(ObjCObjectTypeBitfields) <= 8,
+ "ObjCObjectTypeBitfields is larger than 8 bytes!");
+ static_assert(sizeof(ReferenceTypeBitfields) <= 8,
+ "ReferenceTypeBitfields is larger than 8 bytes!");
+ static_assert(sizeof(TypeWithKeywordBitfields) <= 8,
+ "TypeWithKeywordBitfields is larger than 8 bytes!");
+ static_assert(sizeof(ElaboratedTypeBitfields) <= 8,
+ "ElaboratedTypeBitfields is larger than 8 bytes!");
+ static_assert(sizeof(VectorTypeBitfields) <= 8,
+ "VectorTypeBitfields is larger than 8 bytes!");
+ static_assert(sizeof(SubstTemplateTypeParmPackTypeBitfields) <= 8,
+ "SubstTemplateTypeParmPackTypeBitfields is larger"
+ " than 8 bytes!");
+ static_assert(sizeof(TemplateSpecializationTypeBitfields) <= 8,
+ "TemplateSpecializationTypeBitfields is larger"
+ " than 8 bytes!");
+ static_assert(sizeof(DependentTemplateSpecializationTypeBitfields) <= 8,
+ "DependentTemplateSpecializationTypeBitfields is larger"
+ " than 8 bytes!");
+ static_assert(sizeof(PackExpansionTypeBitfields) <= 8,
+ "PackExpansionTypeBitfields is larger than 8 bytes");
};
private:
@@ -1866,7 +1986,16 @@ public:
bool isObjCQualifiedClassType() const; // Class<foo>
bool isObjCObjectOrInterfaceType() const;
bool isObjCIdType() const; // id
- bool isObjCInertUnsafeUnretainedType() const;
+
+ /// Was this type written with the special inert-in-ARC __unsafe_unretained
+ /// qualifier?
+ ///
+ /// This approximates the answer to the following question: if this
+ /// translation unit were compiled in ARC, would this type be qualified
+ /// with __unsafe_unretained?
+ bool isObjCInertUnsafeUnretainedType() const {
+ return hasAttr(attr::ObjCInertUnsafeUnretained);
+ }
/// Whether the type is Objective-C 'id' or a __kindof type of an
/// object type, e.g., __kindof NSView * or __kindof id
@@ -1911,6 +2040,13 @@ public:
bool isQueueT() const; // OpenCL queue_t
bool isReserveIDT() const; // OpenCL reserve_id_t
+#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
+ bool is##Id##Type() const;
+#include "clang/Basic/OpenCLExtensionTypes.def"
+ // Type defined in cl_intel_device_side_avc_motion_estimation OpenCL extension
+ bool isOCLIntelSubgroupAVCType() const;
+ bool isOCLExtOpaqueType() const; // Any OpenCL extension type
+
bool isPipeType() const; // OpenCL pipe type
bool isOpenCLSpecificType() const; // Any OpenCL specific type
@@ -1931,7 +2067,8 @@ public:
STK_Integral,
STK_Floating,
STK_IntegralComplex,
- STK_FloatingComplex
+ STK_FloatingComplex,
+ STK_FixedPoint
};
/// Given that this is a scalar type, classify it.
@@ -2080,6 +2217,10 @@ public:
/// qualifiers from the outermost type.
const ArrayType *castAsArrayTypeUnsafe() const;
+ /// Determine whether this type had the specified attribute applied to it
+ /// (looking through top-level type sugar).
+ bool hasAttr(attr::Kind AK) const;
+
/// Get the base element type of this type, potentially discarding type
/// qualifiers. This should never be used when type qualifiers
/// are meaningful.
@@ -2253,6 +2394,9 @@ public:
// OpenCL image types
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) Id,
#include "clang/Basic/OpenCLImageTypes.def"
+// OpenCL extension types
+#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) Id,
+#include "clang/Basic/OpenCLExtensionTypes.def"
// All other builtin types
#define BUILTIN_TYPE(Id, SingletonId) Id,
#define LAST_BUILTIN_TYPE(Id) LastKind = Id
@@ -3213,6 +3357,92 @@ class FunctionType : public Type {
QualType ResultType;
public:
+ /// Interesting information about a specific parameter that can't simply
+ /// be reflected in parameter's type. This is only used by FunctionProtoType
+ /// but is in FunctionType to make this class available during the
+ /// specification of the bases of FunctionProtoType.
+ ///
+ /// It makes sense to model language features this way when there's some
+ /// sort of parameter-specific override (such as an attribute) that
+ /// affects how the function is called. For example, the ARC ns_consumed
+ /// attribute changes whether a parameter is passed at +0 (the default)
+ /// or +1 (ns_consumed). This must be reflected in the function type,
+ /// but isn't really a change to the parameter type.
+ ///
+ /// One serious disadvantage of modelling language features this way is
+ /// that they generally do not work with language features that attempt
+ /// to destructure types. For example, template argument deduction will
+ /// not be able to match a parameter declared as
+ /// T (*)(U)
+ /// against an argument of type
+ /// void (*)(__attribute__((ns_consumed)) id)
+ /// because the substitution of T=void, U=id into the former will
+ /// not produce the latter.
+ class ExtParameterInfo {
+ enum {
+ ABIMask = 0x0F,
+ IsConsumed = 0x10,
+ HasPassObjSize = 0x20,
+ IsNoEscape = 0x40,
+ };
+ unsigned char Data = 0;
+
+ public:
+ ExtParameterInfo() = default;
+
+ /// Return the ABI treatment of this parameter.
+ ParameterABI getABI() const { return ParameterABI(Data & ABIMask); }
+ ExtParameterInfo withABI(ParameterABI kind) const {
+ ExtParameterInfo copy = *this;
+ copy.Data = (copy.Data & ~ABIMask) | unsigned(kind);
+ return copy;
+ }
+
+ /// Is this parameter considered "consumed" by Objective-C ARC?
+ /// Consumed parameters must have retainable object type.
+ bool isConsumed() const { return (Data & IsConsumed); }
+ ExtParameterInfo withIsConsumed(bool consumed) const {
+ ExtParameterInfo copy = *this;
+ if (consumed)
+ copy.Data |= IsConsumed;
+ else
+ copy.Data &= ~IsConsumed;
+ return copy;
+ }
+
+ bool hasPassObjectSize() const { return Data & HasPassObjSize; }
+ ExtParameterInfo withHasPassObjectSize() const {
+ ExtParameterInfo Copy = *this;
+ Copy.Data |= HasPassObjSize;
+ return Copy;
+ }
+
+ bool isNoEscape() const { return Data & IsNoEscape; }
+ ExtParameterInfo withIsNoEscape(bool NoEscape) const {
+ ExtParameterInfo Copy = *this;
+ if (NoEscape)
+ Copy.Data |= IsNoEscape;
+ else
+ Copy.Data &= ~IsNoEscape;
+ return Copy;
+ }
+
+ unsigned char getOpaqueValue() const { return Data; }
+ static ExtParameterInfo getFromOpaqueValue(unsigned char data) {
+ ExtParameterInfo result;
+ result.Data = data;
+ return result;
+ }
+
+ friend bool operator==(ExtParameterInfo lhs, ExtParameterInfo rhs) {
+ return lhs.Data == rhs.Data;
+ }
+
+ friend bool operator!=(ExtParameterInfo lhs, ExtParameterInfo rhs) {
+ return lhs.Data != rhs.Data;
+ }
+ };
+
/// A class which abstracts out some details necessary for
/// making a call.
///
@@ -3347,6 +3577,22 @@ public:
}
};
+ /// A simple holder for a QualType representing a type in an
+ /// exception specification. Unfortunately needed by FunctionProtoType
+ /// because TrailingObjects cannot handle repeated types.
+ struct ExceptionType { QualType Type; };
+
+ /// A simple holder for various uncommon bits which do not fit in
+ /// FunctionTypeBitfields. Aligned to alignof(void *) to maintain the
+ /// alignment of subsequent objects in TrailingObjects. You must update
+ /// hasExtraBitfields in FunctionProtoType after adding extra data here.
+ struct alignas(void *) FunctionTypeExtraBitfields {
+ /// The number of types in the exception specification.
+ /// A whole unsigned is not needed here and according to
+ /// [implimits] 8 bits would be enough here.
+ unsigned NumExceptionType;
+ };
+
protected:
FunctionType(TypeClass tc, QualType res,
QualType Canonical, bool Dependent,
@@ -3359,7 +3605,9 @@ protected:
FunctionTypeBits.ExtInfo = Info.Bits;
}
- unsigned getTypeQuals() const { return FunctionTypeBits.TypeQuals; }
+ Qualifiers getFastTypeQuals() const {
+ return Qualifiers::fromFastMask(FunctionTypeBits.FastTypeQuals);
+ }
public:
QualType getReturnType() const { return ResultType; }
@@ -3374,9 +3622,14 @@ public:
CallingConv getCallConv() const { return getExtInfo().getCC(); }
ExtInfo getExtInfo() const { return ExtInfo(FunctionTypeBits.ExtInfo); }
- bool isConst() const { return getTypeQuals() & Qualifiers::Const; }
- bool isVolatile() const { return getTypeQuals() & Qualifiers::Volatile; }
- bool isRestrict() const { return getTypeQuals() & Qualifiers::Restrict; }
+
+ static_assert((~Qualifiers::FastMask & Qualifiers::CVRMask) == 0,
+ "Const, volatile and restrict are assumed to be a subset of "
+ "the fast qualifiers.");
+
+ bool isConst() const { return getFastTypeQuals().hasConst(); }
+ bool isVolatile() const { return getFastTypeQuals().hasVolatile(); }
+ bool isRestrict() const { return getFastTypeQuals().hasRestrict(); }
/// Determine the type of an expression that calls a function of
/// this type.
@@ -3426,104 +3679,65 @@ public:
/// Represents a prototype with parameter type info, e.g.
/// 'int foo(int)' or 'int foo(void)'. 'void' is represented as having no
-/// parameters, not as having a single void parameter. Such a type can have an
-/// exception specification, but this specification is not part of the canonical
-/// type.
-class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
-public:
- /// Interesting information about a specific parameter that can't simply
- /// be reflected in parameter's type.
- ///
- /// It makes sense to model language features this way when there's some
- /// sort of parameter-specific override (such as an attribute) that
- /// affects how the function is called. For example, the ARC ns_consumed
- /// attribute changes whether a parameter is passed at +0 (the default)
- /// or +1 (ns_consumed). This must be reflected in the function type,
- /// but isn't really a change to the parameter type.
- ///
- /// One serious disadvantage of modelling language features this way is
- /// that they generally do not work with language features that attempt
- /// to destructure types. For example, template argument deduction will
- /// not be able to match a parameter declared as
- /// T (*)(U)
- /// against an argument of type
- /// void (*)(__attribute__((ns_consumed)) id)
- /// because the substitution of T=void, U=id into the former will
- /// not produce the latter.
- class ExtParameterInfo {
- enum {
- ABIMask = 0x0F,
- IsConsumed = 0x10,
- HasPassObjSize = 0x20,
- IsNoEscape = 0x40,
- };
- unsigned char Data = 0;
-
- public:
- ExtParameterInfo() = default;
-
- /// Return the ABI treatment of this parameter.
- ParameterABI getABI() const {
- return ParameterABI(Data & ABIMask);
- }
- ExtParameterInfo withABI(ParameterABI kind) const {
- ExtParameterInfo copy = *this;
- copy.Data = (copy.Data & ~ABIMask) | unsigned(kind);
- return copy;
- }
-
- /// Is this parameter considered "consumed" by Objective-C ARC?
- /// Consumed parameters must have retainable object type.
- bool isConsumed() const {
- return (Data & IsConsumed);
- }
- ExtParameterInfo withIsConsumed(bool consumed) const {
- ExtParameterInfo copy = *this;
- if (consumed) {
- copy.Data |= IsConsumed;
- } else {
- copy.Data &= ~IsConsumed;
- }
- return copy;
- }
-
- bool hasPassObjectSize() const {
- return Data & HasPassObjSize;
- }
- ExtParameterInfo withHasPassObjectSize() const {
- ExtParameterInfo Copy = *this;
- Copy.Data |= HasPassObjSize;
- return Copy;
- }
-
- bool isNoEscape() const {
- return Data & IsNoEscape;
- }
-
- ExtParameterInfo withIsNoEscape(bool NoEscape) const {
- ExtParameterInfo Copy = *this;
- if (NoEscape)
- Copy.Data |= IsNoEscape;
- else
- Copy.Data &= ~IsNoEscape;
- return Copy;
- }
-
- unsigned char getOpaqueValue() const { return Data; }
- static ExtParameterInfo getFromOpaqueValue(unsigned char data) {
- ExtParameterInfo result;
- result.Data = data;
- return result;
- }
+/// parameters, not as having a single void parameter. Such a type can have
+/// an exception specification, but this specification is not part of the
+/// canonical type. FunctionProtoType has several trailing objects, some of
+/// which optional. For more information about the trailing objects see
+/// the first comment inside FunctionProtoType.
+class FunctionProtoType final
+ : public FunctionType,
+ public llvm::FoldingSetNode,
+ private llvm::TrailingObjects<
+ FunctionProtoType, QualType, FunctionType::FunctionTypeExtraBitfields,
+ FunctionType::ExceptionType, Expr *, FunctionDecl *,
+ FunctionType::ExtParameterInfo, Qualifiers> {
+ friend class ASTContext; // ASTContext creates these.
+ friend TrailingObjects;
- friend bool operator==(ExtParameterInfo lhs, ExtParameterInfo rhs) {
- return lhs.Data == rhs.Data;
- }
- friend bool operator!=(ExtParameterInfo lhs, ExtParameterInfo rhs) {
- return lhs.Data != rhs.Data;
- }
- };
+ // FunctionProtoType is followed by several trailing objects, some of
+ // which optional. They are in order:
+ //
+ // * An array of getNumParams() QualType holding the parameter types.
+ // Always present. Note that for the vast majority of FunctionProtoType,
+ // these will be the only trailing objects.
+ //
+ // * Optionally if some extra data is stored in FunctionTypeExtraBitfields
+ // (see FunctionTypeExtraBitfields and FunctionTypeBitfields):
+ // a single FunctionTypeExtraBitfields. Present if and only if
+ // hasExtraBitfields() is true.
+ //
+ // * Optionally exactly one of:
+ // * an array of getNumExceptions() ExceptionType,
+ // * a single Expr *,
+ // * a pair of FunctionDecl *,
+ // * a single FunctionDecl *
+ // used to store information about the various types of exception
+ // specification. See getExceptionSpecSize for the details.
+ //
+ // * Optionally an array of getNumParams() ExtParameterInfo holding
+ // an ExtParameterInfo for each of the parameters. Present if and
+ // only if hasExtParameterInfos() is true.
+ //
+ // * Optionally a Qualifiers object to represent extra qualifiers that can't
+ // be represented by FunctionTypeBitfields.FastTypeQuals. Present if and only
+ // if hasExtQualifiers() is true.
+ //
+ // The optional FunctionTypeExtraBitfields has to be before the data
+ // related to the exception specification since it contains the number
+ // of exception types.
+ //
+ // We put the ExtParameterInfos last. If all were equal, it would make
+ // more sense to put these before the exception specification, because
+ // it's much easier to skip past them compared to the elaborate switch
+ // required to skip the exception specification. However, all is not
+ // equal; ExtParameterInfos are used to model very uncommon features,
+ // and it's better not to burden the more common paths.
+public:
+ /// Holds information about the various types of exception specification.
+ /// ExceptionSpecInfo is not stored as such in FunctionProtoType but is
+ /// used to group together the various bits of information about the
+ /// exception specification.
struct ExceptionSpecInfo {
/// The kind of exception specification this is.
ExceptionSpecificationType Type = EST_None;
@@ -3547,31 +3761,54 @@ public:
ExceptionSpecInfo(ExceptionSpecificationType EST) : Type(EST) {}
};
- /// Extra information about a function prototype.
+ /// Extra information about a function prototype. ExtProtoInfo is not
+ /// stored as such in FunctionProtoType but is used to group together
+ /// the various bits of extra information about a function prototype.
struct ExtProtoInfo {
FunctionType::ExtInfo ExtInfo;
bool Variadic : 1;
bool HasTrailingReturn : 1;
- unsigned char TypeQuals = 0;
+ Qualifiers TypeQuals;
RefQualifierKind RefQualifier = RQ_None;
ExceptionSpecInfo ExceptionSpec;
const ExtParameterInfo *ExtParameterInfos = nullptr;
- ExtProtoInfo()
- : Variadic(false), HasTrailingReturn(false) {}
+ ExtProtoInfo() : Variadic(false), HasTrailingReturn(false) {}
ExtProtoInfo(CallingConv CC)
: ExtInfo(CC), Variadic(false), HasTrailingReturn(false) {}
- ExtProtoInfo withExceptionSpec(const ExceptionSpecInfo &O) {
+ ExtProtoInfo withExceptionSpec(const ExceptionSpecInfo &ESI) {
ExtProtoInfo Result(*this);
- Result.ExceptionSpec = O;
+ Result.ExceptionSpec = ESI;
return Result;
}
};
private:
- friend class ASTContext; // ASTContext creates these.
+ unsigned numTrailingObjects(OverloadToken<QualType>) const {
+ return getNumParams();
+ }
+
+ unsigned numTrailingObjects(OverloadToken<FunctionTypeExtraBitfields>) const {
+ return hasExtraBitfields();
+ }
+
+ unsigned numTrailingObjects(OverloadToken<ExceptionType>) const {
+ return getExceptionSpecSize().NumExceptionType;
+ }
+
+ unsigned numTrailingObjects(OverloadToken<Expr *>) const {
+ return getExceptionSpecSize().NumExprPtr;
+ }
+
+ unsigned numTrailingObjects(OverloadToken<FunctionDecl *>) const {
+ return getExceptionSpecSize().NumFunctionDeclPtr;
+ }
+
+ unsigned numTrailingObjects(OverloadToken<ExtParameterInfo>) const {
+ return hasExtParameterInfos() ? getNumParams() : 0;
+ }
/// Determine whether there are any argument types that
/// contain an unexpanded parameter pack.
@@ -3587,88 +3824,71 @@ private:
FunctionProtoType(QualType result, ArrayRef<QualType> params,
QualType canonical, const ExtProtoInfo &epi);
- /// The number of parameters this function has, not counting '...'.
- unsigned NumParams : 15;
-
- /// The number of types in the exception spec, if any.
- unsigned NumExceptions : 9;
-
- /// The type of exception specification this function has.
- unsigned ExceptionSpecType : 4;
-
- /// Whether this function has extended parameter information.
- unsigned HasExtParameterInfos : 1;
-
- /// Whether the function is variadic.
- unsigned Variadic : 1;
-
- /// Whether this function has a trailing return type.
- unsigned HasTrailingReturn : 1;
-
- // ParamInfo - There is an variable size array after the class in memory that
- // holds the parameter types.
-
- // Exceptions - There is another variable size array after ArgInfo that
- // holds the exception types.
-
- // NoexceptExpr - Instead of Exceptions, there may be a single Expr* pointing
- // to the expression in the noexcept() specifier.
-
- // ExceptionSpecDecl, ExceptionSpecTemplate - Instead of Exceptions, there may
- // be a pair of FunctionDecl* pointing to the function which should be used to
- // instantiate this function type's exception specification, and the function
- // from which it should be instantiated.
-
- // ExtParameterInfos - A variable size array, following the exception
- // specification and of length NumParams, holding an ExtParameterInfo
- // for each of the parameters. This only appears if HasExtParameterInfos
- // is true.
-
- const ExtParameterInfo *getExtParameterInfosBuffer() const {
- assert(hasExtParameterInfos());
-
- // Find the end of the exception specification.
- const auto *ptr = reinterpret_cast<const char *>(exception_begin());
- ptr += getExceptionSpecSize();
-
- return reinterpret_cast<const ExtParameterInfo *>(ptr);
- }
+ /// This struct is returned by getExceptionSpecSize and is used to
+ /// translate an ExceptionSpecificationType to the number and kind
+ /// of trailing objects related to the exception specification.
+ struct ExceptionSpecSizeHolder {
+ unsigned NumExceptionType;
+ unsigned NumExprPtr;
+ unsigned NumFunctionDeclPtr;
+ };
- static size_t getExceptionSpecSize(ExceptionSpecificationType EST,
- unsigned NumExceptions) {
+ /// Return the number and kind of trailing objects
+ /// related to the exception specification.
+ static ExceptionSpecSizeHolder
+ getExceptionSpecSize(ExceptionSpecificationType EST, unsigned NumExceptions) {
switch (EST) {
case EST_None:
case EST_DynamicNone:
case EST_MSAny:
case EST_BasicNoexcept:
case EST_Unparsed:
- return 0;
+ return {0, 0, 0};
case EST_Dynamic:
- return NumExceptions * sizeof(QualType);
+ return {NumExceptions, 0, 0};
case EST_DependentNoexcept:
case EST_NoexceptFalse:
case EST_NoexceptTrue:
- return sizeof(Expr *);
+ return {0, 1, 0};
case EST_Uninstantiated:
- return 2 * sizeof(FunctionDecl *);
+ return {0, 0, 2};
case EST_Unevaluated:
- return sizeof(FunctionDecl *);
+ return {0, 0, 1};
}
llvm_unreachable("bad exception specification kind");
}
- size_t getExceptionSpecSize() const {
+
+ /// Return the number and kind of trailing objects
+ /// related to the exception specification.
+ ExceptionSpecSizeHolder getExceptionSpecSize() const {
return getExceptionSpecSize(getExceptionSpecType(), getNumExceptions());
}
+ /// Whether the trailing FunctionTypeExtraBitfields is present.
+ static bool hasExtraBitfields(ExceptionSpecificationType EST) {
+ // If the exception spec type is EST_Dynamic then we have > 0 exception
+ // types and the exact number is stored in FunctionTypeExtraBitfields.
+ return EST == EST_Dynamic;
+ }
+
+ /// Whether the trailing FunctionTypeExtraBitfields is present.
+ bool hasExtraBitfields() const {
+ return hasExtraBitfields(getExceptionSpecType());
+ }
+
+ bool hasExtQualifiers() const {
+ return FunctionTypeBits.HasExtQuals;
+ }
+
public:
- unsigned getNumParams() const { return NumParams; }
+ unsigned getNumParams() const { return FunctionTypeBits.NumParams; }
QualType getParamType(unsigned i) const {
- assert(i < NumParams && "invalid parameter index");
+ assert(i < getNumParams() && "invalid parameter index");
return param_type_begin()[i];
}
@@ -3682,7 +3902,7 @@ public:
EPI.Variadic = isVariadic();
EPI.HasTrailingReturn = hasTrailingReturn();
EPI.ExceptionSpec.Type = getExceptionSpecType();
- EPI.TypeQuals = static_cast<unsigned char>(getTypeQuals());
+ EPI.TypeQuals = getTypeQuals();
EPI.RefQualifier = getRefQualifier();
if (EPI.ExceptionSpec.Type == EST_Dynamic) {
EPI.ExceptionSpec.Exceptions = exceptions();
@@ -3694,20 +3914,18 @@ public:
} else if (EPI.ExceptionSpec.Type == EST_Unevaluated) {
EPI.ExceptionSpec.SourceDecl = getExceptionSpecDecl();
}
- if (hasExtParameterInfos())
- EPI.ExtParameterInfos = getExtParameterInfosBuffer();
+ EPI.ExtParameterInfos = getExtParameterInfosOrNull();
return EPI;
}
/// Get the kind of exception specification on this function.
ExceptionSpecificationType getExceptionSpecType() const {
- return static_cast<ExceptionSpecificationType>(ExceptionSpecType);
+ return static_cast<ExceptionSpecificationType>(
+ FunctionTypeBits.ExceptionSpecType);
}
/// Return whether this function has any kind of exception spec.
- bool hasExceptionSpec() const {
- return getExceptionSpecType() != EST_None;
- }
+ bool hasExceptionSpec() const { return getExceptionSpecType() != EST_None; }
/// Return whether this function has a dynamic (throw) exception spec.
bool hasDynamicExceptionSpec() const {
@@ -3726,16 +3944,26 @@ public:
/// spec.
bool hasInstantiationDependentExceptionSpec() const;
- unsigned getNumExceptions() const { return NumExceptions; }
+ /// Return the number of types in the exception specification.
+ unsigned getNumExceptions() const {
+ return getExceptionSpecType() == EST_Dynamic
+ ? getTrailingObjects<FunctionTypeExtraBitfields>()
+ ->NumExceptionType
+ : 0;
+ }
+
+ /// Return the ith exception type, where 0 <= i < getNumExceptions().
QualType getExceptionType(unsigned i) const {
- assert(i < NumExceptions && "Invalid exception number!");
+ assert(i < getNumExceptions() && "Invalid exception number!");
return exception_begin()[i];
}
+
+ /// Return the expression inside noexcept(expression), or a null pointer
+ /// if there is none (because the exception spec is not of this form).
Expr *getNoexceptExpr() const {
if (!isComputedNoexcept(getExceptionSpecType()))
return nullptr;
- // NoexceptExpr sits where the arguments end.
- return *reinterpret_cast<Expr *const *>(param_type_end());
+ return *getTrailingObjects<Expr *>();
}
/// If this function type has an exception specification which hasn't
@@ -3746,7 +3974,7 @@ public:
if (getExceptionSpecType() != EST_Uninstantiated &&
getExceptionSpecType() != EST_Unevaluated)
return nullptr;
- return reinterpret_cast<FunctionDecl *const *>(param_type_end())[0];
+ return getTrailingObjects<FunctionDecl *>()[0];
}
/// If this function type has an uninstantiated exception
@@ -3756,7 +3984,7 @@ public:
FunctionDecl *getExceptionSpecTemplate() const {
if (getExceptionSpecType() != EST_Uninstantiated)
return nullptr;
- return reinterpret_cast<FunctionDecl *const *>(param_type_end())[1];
+ return getTrailingObjects<FunctionDecl *>()[1];
}
/// Determine whether this function type has a non-throwing exception
@@ -3767,11 +3995,11 @@ public:
/// specification. If this depends on template arguments, returns
/// \c ResultIfDependent.
bool isNothrow(bool ResultIfDependent = false) const {
- return ResultIfDependent ? canThrow() != CT_Can
- : canThrow() == CT_Cannot;
+ return ResultIfDependent ? canThrow() != CT_Can : canThrow() == CT_Cannot;
}
- bool isVariadic() const { return Variadic; }
+ /// Whether this function prototype is variadic.
+ bool isVariadic() const { return FunctionTypeBits.Variadic; }
/// Determines whether this function prototype contains a
/// parameter pack at the end.
@@ -3781,9 +4009,15 @@ public:
/// function.
bool isTemplateVariadic() const;
- bool hasTrailingReturn() const { return HasTrailingReturn; }
+ /// Whether this function prototype has a trailing return type.
+ bool hasTrailingReturn() const { return FunctionTypeBits.HasTrailingReturn; }
- unsigned getTypeQuals() const { return FunctionType::getTypeQuals(); }
+ Qualifiers getTypeQuals() const {
+ if (hasExtQualifiers())
+ return *getTrailingObjects<Qualifiers>();
+ else
+ return getFastTypeQuals();
+ }
/// Retrieve the ref-qualifier associated with this function type.
RefQualifierKind getRefQualifier() const {
@@ -3798,11 +4032,11 @@ public:
}
param_type_iterator param_type_begin() const {
- return reinterpret_cast<const QualType *>(this+1);
+ return getTrailingObjects<QualType>();
}
param_type_iterator param_type_end() const {
- return param_type_begin() + NumParams;
+ return param_type_begin() + getNumParams();
}
using exception_iterator = const QualType *;
@@ -3812,22 +4046,23 @@ public:
}
exception_iterator exception_begin() const {
- // exceptions begin where arguments end
- return param_type_end();
+ return reinterpret_cast<exception_iterator>(
+ getTrailingObjects<ExceptionType>());
}
exception_iterator exception_end() const {
- if (getExceptionSpecType() != EST_Dynamic)
- return exception_begin();
- return exception_begin() + NumExceptions;
+ return exception_begin() + getNumExceptions();
}
/// Is there any interesting extra information for any of the parameters
/// of this function type?
- bool hasExtParameterInfos() const { return HasExtParameterInfos; }
+ bool hasExtParameterInfos() const {
+ return FunctionTypeBits.HasExtParameterInfos;
+ }
+
ArrayRef<ExtParameterInfo> getExtParameterInfos() const {
assert(hasExtParameterInfos());
- return ArrayRef<ExtParameterInfo>(getExtParameterInfosBuffer(),
+ return ArrayRef<ExtParameterInfo>(getTrailingObjects<ExtParameterInfo>(),
getNumParams());
}
@@ -3837,27 +4072,27 @@ public:
const ExtParameterInfo *getExtParameterInfosOrNull() const {
if (!hasExtParameterInfos())
return nullptr;
- return getExtParameterInfosBuffer();
+ return getTrailingObjects<ExtParameterInfo>();
}
ExtParameterInfo getExtParameterInfo(unsigned I) const {
assert(I < getNumParams() && "parameter index out of range");
if (hasExtParameterInfos())
- return getExtParameterInfosBuffer()[I];
+ return getTrailingObjects<ExtParameterInfo>()[I];
return ExtParameterInfo();
}
ParameterABI getParameterABI(unsigned I) const {
assert(I < getNumParams() && "parameter index out of range");
if (hasExtParameterInfos())
- return getExtParameterInfosBuffer()[I].getABI();
+ return getTrailingObjects<ExtParameterInfo>()[I].getABI();
return ParameterABI::Ordinary;
}
bool isParamConsumed(unsigned I) const {
assert(I < getNumParams() && "parameter index out of range");
if (hasExtParameterInfos())
- return getExtParameterInfosBuffer()[I].isConsumed();
+ return getTrailingObjects<ExtParameterInfo>()[I].isConsumed();
return false;
}
@@ -4189,56 +4424,7 @@ public:
/// - the canonical type is VectorType(16, int)
class AttributedType : public Type, public llvm::FoldingSetNode {
public:
- // It is really silly to have yet another attribute-kind enum, but
- // clang::attr::Kind doesn't currently cover the pure type attrs.
- enum Kind {
- // Expression operand.
- attr_address_space,
- attr_regparm,
- attr_vector_size,
- attr_neon_vector_type,
- attr_neon_polyvector_type,
-
- FirstExprOperandKind = attr_address_space,
- LastExprOperandKind = attr_neon_polyvector_type,
-
- // Enumerated operand (string or keyword).
- attr_objc_gc,
- attr_objc_ownership,
- attr_pcs,
- attr_pcs_vfp,
-
- FirstEnumOperandKind = attr_objc_gc,
- LastEnumOperandKind = attr_pcs_vfp,
-
- // No operand.
- attr_noreturn,
- attr_nocf_check,
- attr_cdecl,
- attr_fastcall,
- attr_stdcall,
- attr_thiscall,
- attr_regcall,
- attr_pascal,
- attr_swiftcall,
- attr_vectorcall,
- attr_inteloclbicc,
- attr_ms_abi,
- attr_sysv_abi,
- attr_preserve_most,
- attr_preserve_all,
- attr_ptr32,
- attr_ptr64,
- attr_sptr,
- attr_uptr,
- attr_nonnull,
- attr_ns_returns_retained,
- attr_nullable,
- attr_null_unspecified,
- attr_objc_kindof,
- attr_objc_inert_unsafe_unretained,
- attr_lifetimebound,
- };
+ using Kind = attr::Kind;
private:
friend class ASTContext; // ASTContext creates these
@@ -4246,7 +4432,7 @@ private:
QualType ModifiedType;
QualType EquivalentType;
- AttributedType(QualType canon, Kind attrKind, QualType modified,
+ AttributedType(QualType canon, attr::Kind attrKind, QualType modified,
QualType equivalent)
: Type(Attributed, canon, equivalent->isDependentType(),
equivalent->isInstantiationDependentType(),
@@ -4295,13 +4481,13 @@ public:
static Kind getNullabilityAttrKind(NullabilityKind kind) {
switch (kind) {
case NullabilityKind::NonNull:
- return attr_nonnull;
+ return attr::TypeNonNull;
case NullabilityKind::Nullable:
- return attr_nullable;
+ return attr::TypeNullable;
case NullabilityKind::Unspecified:
- return attr_null_unspecified;
+ return attr::TypeNullUnspecified;
}
llvm_unreachable("Unknown nullability kind.");
}
@@ -4480,9 +4666,6 @@ class SubstTemplateTypeParmPackType : public Type, public llvm::FoldingSetNode {
/// parameter pack is instantiated with.
const TemplateArgument *Arguments;
- /// The number of template arguments in \c Arguments.
- unsigned NumArguments;
-
SubstTemplateTypeParmPackType(const TemplateTypeParmType *Param,
QualType Canon,
const TemplateArgument &ArgPack);
@@ -4495,6 +4678,10 @@ public:
return Replaced;
}
+ unsigned getNumArgs() const {
+ return SubstTemplateTypeParmPackTypeBits.NumArgs;
+ }
+
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -4665,13 +4852,6 @@ class alignas(8) TemplateSpecializationType
/// replacement must, recursively, be one of these).
TemplateName Template;
- /// The number of template arguments named in this class template
- /// specialization.
- unsigned NumArgs : 31;
-
- /// Whether this template specialization type is a substituted type alias.
- unsigned TypeAlias : 1;
-
TemplateSpecializationType(TemplateName T,
ArrayRef<TemplateArgument> Args,
QualType Canon,
@@ -4706,7 +4886,7 @@ public:
/// typedef A<Ts...> type; // not a type alias
/// };
/// \endcode
- bool isTypeAlias() const { return TypeAlias; }
+ bool isTypeAlias() const { return TemplateSpecializationTypeBits.TypeAlias; }
/// Get the aliased type, if this is a specialization of a type alias
/// template.
@@ -4729,21 +4909,25 @@ public:
}
/// Retrieve the number of template arguments.
- unsigned getNumArgs() const { return NumArgs; }
+ unsigned getNumArgs() const {
+ return TemplateSpecializationTypeBits.NumArgs;
+ }
/// Retrieve a specific template argument as a type.
/// \pre \c isArgType(Arg)
const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
ArrayRef<TemplateArgument> template_arguments() const {
- return {getArgs(), NumArgs};
+ return {getArgs(), getNumArgs()};
}
bool isSugared() const {
return !isDependentType() || isCurrentInstantiation() || isTypeAlias();
}
- QualType desugar() const { return getCanonicalTypeInternal(); }
+ QualType desugar() const {
+ return isTypeAlias() ? getAliasedType() : getCanonicalTypeInternal();
+ }
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx) {
Profile(ID, Template, template_arguments(), Ctx);
@@ -4942,8 +5126,12 @@ public:
/// source code, including tag keywords and any nested-name-specifiers.
/// The type itself is always "sugar", used to express what was written
/// in the source code but containing no additional semantic information.
-class ElaboratedType : public TypeWithKeyword, public llvm::FoldingSetNode {
+class ElaboratedType final
+ : public TypeWithKeyword,
+ public llvm::FoldingSetNode,
+ private llvm::TrailingObjects<ElaboratedType, TagDecl *> {
friend class ASTContext; // ASTContext creates these
+ friend TrailingObjects;
/// The nested name specifier containing the qualifier.
NestedNameSpecifier *NNS;
@@ -4951,26 +5139,29 @@ class ElaboratedType : public TypeWithKeyword, public llvm::FoldingSetNode {
/// The type that this qualified name refers to.
QualType NamedType;
- /// The (re)declaration of this tag type owned by this occurrence, or nullptr
- /// if none.
- TagDecl *OwnedTagDecl;
+ /// The (re)declaration of this tag type owned by this occurrence is stored
+ /// as a trailing object if there is one. Use getOwnedTagDecl to obtain
+ /// it, or obtain a null pointer if there is none.
ElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
QualType NamedType, QualType CanonType, TagDecl *OwnedTagDecl)
- : TypeWithKeyword(Keyword, Elaborated, CanonType,
- NamedType->isDependentType(),
- NamedType->isInstantiationDependentType(),
- NamedType->isVariablyModifiedType(),
- NamedType->containsUnexpandedParameterPack()),
- NNS(NNS), NamedType(NamedType), OwnedTagDecl(OwnedTagDecl) {
+ : TypeWithKeyword(Keyword, Elaborated, CanonType,
+ NamedType->isDependentType(),
+ NamedType->isInstantiationDependentType(),
+ NamedType->isVariablyModifiedType(),
+ NamedType->containsUnexpandedParameterPack()),
+ NNS(NNS), NamedType(NamedType) {
+ ElaboratedTypeBits.HasOwnedTagDecl = false;
+ if (OwnedTagDecl) {
+ ElaboratedTypeBits.HasOwnedTagDecl = true;
+ *getTrailingObjects<TagDecl *>() = OwnedTagDecl;
+ }
assert(!(Keyword == ETK_None && NNS == nullptr) &&
"ElaboratedType cannot have elaborated type keyword "
"and name qualifier both null.");
}
public:
- ~ElaboratedType();
-
/// Retrieve the qualification on this type.
NestedNameSpecifier *getQualifier() const { return NNS; }
@@ -4984,11 +5175,14 @@ public:
bool isSugared() const { return true; }
/// Return the (re)declaration of this type owned by this occurrence of this
- /// type, or nullptr if none.
- TagDecl *getOwnedTagDecl() const { return OwnedTagDecl; }
+ /// type, or nullptr if there is none.
+ TagDecl *getOwnedTagDecl() const {
+ return ElaboratedTypeBits.HasOwnedTagDecl ? *getTrailingObjects<TagDecl *>()
+ : nullptr;
+ }
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getKeyword(), NNS, NamedType, OwnedTagDecl);
+ Profile(ID, getKeyword(), NNS, NamedType, getOwnedTagDecl());
}
static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
@@ -5000,9 +5194,7 @@ public:
ID.AddPointer(OwnedTagDecl);
}
- static bool classof(const Type *T) {
- return T->getTypeClass() == Elaborated;
- }
+ static bool classof(const Type *T) { return T->getTypeClass() == Elaborated; }
};
/// Represents a qualified type name for which the type name is
@@ -5080,10 +5272,6 @@ class alignas(8) DependentTemplateSpecializationType
/// The identifier of the template.
const IdentifierInfo *Name;
- /// The number of template arguments named in this class template
- /// specialization.
- unsigned NumArgs;
-
DependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
NestedNameSpecifier *NNS,
const IdentifierInfo *Name,
@@ -5108,12 +5296,14 @@ public:
}
/// Retrieve the number of template arguments.
- unsigned getNumArgs() const { return NumArgs; }
+ unsigned getNumArgs() const {
+ return DependentTemplateSpecializationTypeBits.NumArgs;
+ }
const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
ArrayRef<TemplateArgument> template_arguments() const {
- return {getArgs(), NumArgs};
+ return {getArgs(), getNumArgs()};
}
using iterator = const TemplateArgument *;
@@ -5125,7 +5315,7 @@ public:
QualType desugar() const { return QualType(this, 0); }
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
- Profile(ID, Context, getKeyword(), NNS, Name, {getArgs(), NumArgs});
+ Profile(ID, Context, getKeyword(), NNS, Name, {getArgs(), getNumArgs()});
}
static void Profile(llvm::FoldingSetNodeID &ID,
@@ -5168,22 +5358,16 @@ class PackExpansionType : public Type, public llvm::FoldingSetNode {
/// The pattern of the pack expansion.
QualType Pattern;
- /// The number of expansions that this pack expansion will
- /// generate when substituted (+1), or indicates that
- ///
- /// This field will only have a non-zero value when some of the parameter
- /// packs that occur within the pattern have been substituted but others have
- /// not.
- unsigned NumExpansions;
-
PackExpansionType(QualType Pattern, QualType Canon,
Optional<unsigned> NumExpansions)
: Type(PackExpansion, Canon, /*Dependent=*/Pattern->isDependentType(),
/*InstantiationDependent=*/true,
/*VariablyModified=*/Pattern->isVariablyModifiedType(),
/*ContainsUnexpandedParameterPack=*/false),
- Pattern(Pattern),
- NumExpansions(NumExpansions ? *NumExpansions + 1 : 0) {}
+ Pattern(Pattern) {
+ PackExpansionTypeBits.NumExpansions =
+ NumExpansions ? *NumExpansions + 1 : 0;
+ }
public:
/// Retrieve the pattern of this pack expansion, which is the
@@ -5194,9 +5378,8 @@ public:
/// Retrieve the number of expansions that this pack expansion will
/// generate, if known.
Optional<unsigned> getNumExpansions() const {
- if (NumExpansions)
- return NumExpansions - 1;
-
+ if (PackExpansionTypeBits.NumExpansions)
+ return PackExpansionTypeBits.NumExpansions - 1;
return None;
}
@@ -6295,9 +6478,30 @@ inline bool Type::isPipeType() const {
return isa<PipeType>(CanonicalType);
}
+#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
+ inline bool Type::is##Id##Type() const { \
+ return isSpecificBuiltinType(BuiltinType::Id); \
+ }
+#include "clang/Basic/OpenCLExtensionTypes.def"
+
+inline bool Type::isOCLIntelSubgroupAVCType() const {
+#define INTEL_SUBGROUP_AVC_TYPE(ExtType, Id) \
+ isOCLIntelSubgroupAVC##Id##Type() ||
+ return
+#include "clang/Basic/OpenCLExtensionTypes.def"
+ false; // end of boolean or operation
+}
+
+inline bool Type::isOCLExtOpaqueType() const {
+#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) is##Id##Type() ||
+ return
+#include "clang/Basic/OpenCLExtensionTypes.def"
+ false; // end of boolean or operation
+}
+
inline bool Type::isOpenCLSpecificType() const {
return isSamplerT() || isEventT() || isImageType() || isClkEventT() ||
- isQueueT() || isReserveIDT() || isPipeType();
+ isQueueT() || isReserveIDT() || isPipeType() || isOCLExtOpaqueType();
}
inline bool Type::isTemplateTypeParmType() const {
@@ -6497,6 +6701,24 @@ inline const Type *Type::getPointeeOrArrayElementType() const {
return type;
}
+/// Insertion operator for diagnostics. This allows sending Qualifiers into a
+/// diagnostic with <<.
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+ Qualifiers Q) {
+ DB.AddTaggedVal(Q.getAsOpaqueValue(),
+ DiagnosticsEngine::ArgumentKind::ak_qual);
+ return DB;
+}
+
+/// Insertion operator for partial diagnostics. This allows sending Qualifiers
+/// into a diagnostic with <<.
+inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+ Qualifiers Q) {
+ PD.AddTaggedVal(Q.getAsOpaqueValue(),
+ DiagnosticsEngine::ArgumentKind::ak_qual);
+ return PD;
+}
+
/// Insertion operator for diagnostics. This allows sending QualType's into a
/// diagnostic with <<.
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
@@ -6619,9 +6841,8 @@ QualType DecayedType::getPointeeType() const {
// Get the decimal string representation of a fixed point type, represented
// as a scaled integer.
-void FixedPointValueToString(SmallVectorImpl<char> &Str,
- const llvm::APSInt &Val,
- unsigned Scale, unsigned Radix);
+void FixedPointValueToString(SmallVectorImpl<char> &Str, llvm::APSInt Val,
+ unsigned Scale);
} // namespace clang
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
index c69f4aa4abcf..1e89e9386719 100644
--- a/include/clang/AST/TypeLoc.h
+++ b/include/clang/AST/TypeLoc.h
@@ -15,6 +15,7 @@
#ifndef LLVM_CLANG_AST_TYPELOC_H
#define LLVM_CLANG_AST_TYPELOC_H
+#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/TemplateBase.h"
@@ -151,8 +152,6 @@ public:
return SourceRange(getBeginLoc(), getEndLoc());
}
- SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
/// Get the local source range.
SourceRange getLocalSourceRange() const {
@@ -843,16 +842,7 @@ class SubstTemplateTypeParmPackTypeLoc :
};
struct AttributedLocInfo {
- union {
- Expr *ExprOperand;
-
- /// A raw SourceLocation.
- unsigned EnumOperandLoc;
- };
-
- SourceRange OperandParens;
-
- SourceLocation AttrLoc;
+ const Attr *TypeAttr;
};
/// Type source information for an attributed type.
@@ -861,24 +851,10 @@ class AttributedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
AttributedType,
AttributedLocInfo> {
public:
- AttributedType::Kind getAttrKind() const {
+ attr::Kind getAttrKind() const {
return getTypePtr()->getAttrKind();
}
- bool hasAttrExprOperand() const {
- return (getAttrKind() >= AttributedType::FirstExprOperandKind &&
- getAttrKind() <= AttributedType::LastExprOperandKind);
- }
-
- bool hasAttrEnumOperand() const {
- return (getAttrKind() >= AttributedType::FirstEnumOperandKind &&
- getAttrKind() <= AttributedType::LastEnumOperandKind);
- }
-
- bool hasAttrOperand() const {
- return hasAttrExprOperand() || hasAttrEnumOperand();
- }
-
bool isQualifier() const {
return getTypePtr()->isQualifier();
}
@@ -891,51 +867,16 @@ public:
return getInnerTypeLoc();
}
- /// The location of the attribute name, i.e.
- /// __attribute__((regparm(1000)))
- /// ^~~~~~~
- SourceLocation getAttrNameLoc() const {
- return getLocalData()->AttrLoc;
+ /// The type attribute.
+ const Attr *getAttr() const {
+ return getLocalData()->TypeAttr;
}
- void setAttrNameLoc(SourceLocation loc) {
- getLocalData()->AttrLoc = loc;
+ void setAttr(const Attr *A) {
+ getLocalData()->TypeAttr = A;
}
- /// The attribute's expression operand, if it has one.
- /// void *cur_thread __attribute__((address_space(21)))
- /// ^~
- Expr *getAttrExprOperand() const {
- assert(hasAttrExprOperand());
- return getLocalData()->ExprOperand;
- }
- void setAttrExprOperand(Expr *e) {
- assert(hasAttrExprOperand());
- getLocalData()->ExprOperand = e;
- }
-
- /// The location of the attribute's enumerated operand, if it has one.
- /// void * __attribute__((objc_gc(weak)))
- /// ^~~~
- SourceLocation getAttrEnumOperandLoc() const {
- assert(hasAttrEnumOperand());
- return SourceLocation::getFromRawEncoding(getLocalData()->EnumOperandLoc);
- }
- void setAttrEnumOperandLoc(SourceLocation loc) {
- assert(hasAttrEnumOperand());
- getLocalData()->EnumOperandLoc = loc.getRawEncoding();
- }
-
- /// The location of the parentheses around the operand, if there is
- /// an operand.
- /// void * __attribute__((objc_gc(weak)))
- /// ^ ^
- SourceRange getAttrOperandParensRange() const {
- assert(hasAttrOperand());
- return getLocalData()->OperandParens;
- }
- void setAttrOperandParensRange(SourceRange range) {
- assert(hasAttrOperand());
- getLocalData()->OperandParens = range;
+ template<typename T> const T *getAttrAs() {
+ return dyn_cast_or_null<T>(getAttr());
}
SourceRange getLocalSourceRange() const {
@@ -948,21 +889,11 @@ public:
// ^~ ~~
// That enclosure doesn't necessarily belong to a single attribute
// anyway.
- SourceRange range(getAttrNameLoc());
- if (hasAttrOperand())
- range.setEnd(getAttrOperandParensRange().getEnd());
- return range;
+ return getAttr() ? getAttr()->getRange() : SourceRange();
}
void initializeLocal(ASTContext &Context, SourceLocation loc) {
- setAttrNameLoc(loc);
- if (hasAttrExprOperand()) {
- setAttrOperandParensRange(SourceRange(loc));
- setAttrExprOperand(nullptr);
- } else if (hasAttrEnumOperand()) {
- setAttrOperandParensRange(SourceRange(loc));
- setAttrEnumOperandLoc(loc);
- }
+ setAttr(nullptr);
}
QualType getInnerType() const {
diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h
index 51f2ce2af75c..5cdb964a92c2 100644
--- a/include/clang/ASTMatchers/ASTMatchers.h
+++ b/include/clang/ASTMatchers/ASTMatchers.h
@@ -245,7 +245,7 @@ AST_POLYMORPHIC_MATCHER(isExpansionInMainFile,
AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, TypeLoc)) {
auto &SourceManager = Finder->getASTContext().getSourceManager();
return SourceManager.isInMainFile(
- SourceManager.getExpansionLoc(Node.getLocStart()));
+ SourceManager.getExpansionLoc(Node.getBeginLoc()));
}
/// Matches AST nodes that were expanded within system-header-files.
@@ -265,7 +265,7 @@ AST_POLYMORPHIC_MATCHER(isExpansionInMainFile,
AST_POLYMORPHIC_MATCHER(isExpansionInSystemHeader,
AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, TypeLoc)) {
auto &SourceManager = Finder->getASTContext().getSourceManager();
- auto ExpansionLoc = SourceManager.getExpansionLoc(Node.getLocStart());
+ auto ExpansionLoc = SourceManager.getExpansionLoc(Node.getBeginLoc());
if (ExpansionLoc.isInvalid()) {
return false;
}
@@ -291,7 +291,7 @@ AST_POLYMORPHIC_MATCHER_P(isExpansionInFileMatching,
AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, TypeLoc),
std::string, RegExp) {
auto &SourceManager = Finder->getASTContext().getSourceManager();
- auto ExpansionLoc = SourceManager.getExpansionLoc(Node.getLocStart());
+ auto ExpansionLoc = SourceManager.getExpansionLoc(Node.getBeginLoc());
if (ExpansionLoc.isInvalid()) {
return false;
}
@@ -420,6 +420,25 @@ extern const internal::VariadicDynCastAllOfMatcher<
Decl, ClassTemplateSpecializationDecl>
classTemplateSpecializationDecl;
+/// Matches C++ class template partial specializations.
+///
+/// Given
+/// \code
+/// template<class T1, class T2, int I>
+/// class A {};
+///
+/// template<class T, int I>
+/// class A<T, T*, I> {};
+///
+/// template<>
+/// class A<int, int, 1> {};
+/// \endcode
+/// classTemplatePartialSpecializationDecl()
+/// matches the specialization \c A<T,T*,I> but not \c A<int,int,1>
+extern const internal::VariadicDynCastAllOfMatcher<
+ Decl, ClassTemplatePartialSpecializationDecl>
+ classTemplatePartialSpecializationDecl;
+
/// Matches declarator declarations (field, variable, function
/// and non-type template parameter declarations).
///
@@ -626,12 +645,12 @@ AST_MATCHER(FunctionDecl, isMain) {
///
/// Given
/// \code
-/// tempalate<typename T> class A {};
-/// typedef A<int> B;
+/// template<typename T> class A {}; #1
+/// template<> class A<int> {}; #2
/// \endcode
/// classTemplateSpecializationDecl(hasSpecializedTemplate(classTemplateDecl()))
-/// matches 'B' with classTemplateDecl() matching the class template
-/// declaration of 'A'.
+/// matches '#2' with classTemplateDecl() matching the class template
+/// declaration of 'A' at #1.
AST_MATCHER_P(ClassTemplateSpecializationDecl, hasSpecializedTemplate,
internal::Matcher<ClassTemplateDecl>, InnerMatcher) {
const ClassTemplateDecl* Decl = Node.getSpecializedTemplate();
@@ -792,11 +811,70 @@ AST_MATCHER_P(Expr, ignoringParenImpCasts,
/// varDecl(hasType(pointerType(pointee(ignoringParens(functionType())))))
/// \endcode
/// would match the declaration for fp.
-AST_MATCHER_P(QualType, ignoringParens,
- internal::Matcher<QualType>, InnerMatcher) {
+AST_MATCHER_P_OVERLOAD(QualType, ignoringParens, internal::Matcher<QualType>,
+ InnerMatcher, 0) {
return InnerMatcher.matches(Node.IgnoreParens(), Finder, Builder);
}
+/// Overload \c ignoringParens for \c Expr.
+///
+/// Given
+/// \code
+/// const char* str = ("my-string");
+/// \endcode
+/// The matcher
+/// \code
+/// implicitCastExpr(hasSourceExpression(ignoringParens(stringLiteral())))
+/// \endcode
+/// would match the implicit cast resulting from the assignment.
+AST_MATCHER_P_OVERLOAD(Expr, ignoringParens, internal::Matcher<Expr>,
+ InnerMatcher, 1) {
+ const Expr *E = Node.IgnoreParens();
+ return InnerMatcher.matches(*E, Finder, Builder);
+}
+
+/// Matches expressions that are instantiation-dependent even if it is
+/// neither type- nor value-dependent.
+///
+/// In the following example, the expression sizeof(sizeof(T() + T()))
+/// is instantiation-dependent (since it involves a template parameter T),
+/// but is neither type- nor value-dependent, since the type of the inner
+/// sizeof is known (std::size_t) and therefore the size of the outer
+/// sizeof is known.
+/// \code
+/// template<typename T>
+/// void f(T x, T y) { sizeof(sizeof(T() + T()); }
+/// \endcode
+/// expr(isInstantiationDependent()) matches sizeof(sizeof(T() + T())
+AST_MATCHER(Expr, isInstantiationDependent) {
+ return Node.isInstantiationDependent();
+}
+
+/// Matches expressions that are type-dependent because the template type
+/// is not yet instantiated.
+///
+/// For example, the expressions "x" and "x + y" are type-dependent in
+/// the following code, but "y" is not type-dependent:
+/// \code
+/// template<typename T>
+/// void add(T x, int y) {
+/// x + y;
+/// }
+/// \endcode
+/// expr(isTypeDependent()) matches x + y
+AST_MATCHER(Expr, isTypeDependent) { return Node.isTypeDependent(); }
+
+/// Matches expression that are value-dependent because they contain a
+/// non-type template parameter.
+///
+/// For example, the array bound of "Chars" in the following example is
+/// value-dependent.
+/// \code
+/// template<int Size> int f() { return Size; }
+/// \endcode
+/// expr(isValueDependent()) matches return Size
+AST_MATCHER(Expr, isValueDependent) { return Node.isValueDependent(); }
+
/// Matches classTemplateSpecializations, templateSpecializationType and
/// functionDecl where the n'th TemplateArgument matches the given InnerMatcher.
///
@@ -868,7 +946,7 @@ AST_MATCHER_P(TemplateArgument, refersToType,
/// Given
/// \code
/// template<template <typename> class S> class X {};
-/// template<typename T> class Y {};"
+/// template<typename T> class Y {};
/// X<Y> xi;
/// \endcode
/// classTemplateSpecializationDecl(hasAnyTemplateArgument(
@@ -1080,6 +1158,17 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, VarDecl> varDecl;
/// matches 'm'.
extern const internal::VariadicDynCastAllOfMatcher<Decl, FieldDecl> fieldDecl;
+/// Matches indirect field declarations.
+///
+/// Given
+/// \code
+/// struct X { struct { int a; }; };
+/// \endcode
+/// indirectFieldDecl()
+/// matches 'a'.
+extern const internal::VariadicDynCastAllOfMatcher<Decl, IndirectFieldDecl>
+ indirectFieldDecl;
+
/// Matches function declarations.
///
/// Example matches f
@@ -1141,6 +1230,34 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, DeclStmt> declStmt;
/// matches this->x, x, y.x, a, this->b
extern const internal::VariadicDynCastAllOfMatcher<Stmt, MemberExpr> memberExpr;
+/// Matches unresolved member expressions.
+///
+/// Given
+/// \code
+/// struct X {
+/// template <class T> void f();
+/// void g();
+/// };
+/// template <class T> void h() { X x; x.f<T>(); x.g(); }
+/// \endcode
+/// unresolvedMemberExpr()
+/// matches x.f<T>
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, UnresolvedMemberExpr>
+ unresolvedMemberExpr;
+
+/// Matches member expressions where the actual member referenced could not be
+/// resolved because the base expression or the member name was dependent.
+///
+/// Given
+/// \code
+/// template <class T> void f() { T t; t.g(); }
+/// \endcode
+/// cxxDependentScopeMemberExpr()
+/// matches t.g
+extern const internal::VariadicDynCastAllOfMatcher<Stmt,
+ CXXDependentScopeMemberExpr>
+ cxxDependentScopeMemberExpr;
+
/// Matches call expressions.
///
/// Example matches x.y() and y()
@@ -1151,6 +1268,28 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, MemberExpr> memberExpr;
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CallExpr> callExpr;
+/// Matches call expressions which were resolved using ADL.
+///
+/// Example matches y(x) but not y(42) or NS::y(x).
+/// \code
+/// namespace NS {
+/// struct X {};
+/// void y(X);
+/// }
+///
+/// void y(...);
+///
+/// void test() {
+/// NS::X x;
+/// y(x); // Matches
+/// NS::y(x); // Doesn't match
+/// y(42); // Doesn't match
+/// using NS::y;
+/// y(x); // Found by both unqualified lookup and ADL, doesn't match
+// }
+/// \endcode
+AST_MATCHER(CallExpr, usesADL) { return Node.usesADL(); }
+
/// Matches lambda expressions.
///
/// Example matches [&](){return 5;}
@@ -1485,6 +1624,18 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl,
UnresolvedUsingTypenameDecl>
unresolvedUsingTypenameDecl;
+/// Matches a constant expression wrapper.
+///
+/// Example matches the constant in the case statement:
+/// (matcher = constantExpr())
+/// \code
+/// switch (a) {
+/// case 37: break;
+/// }
+/// \endcode
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, ConstantExpr>
+ constantExpr;
+
/// Matches parentheses used in expressions.
///
/// Example matches (foo() + 1)
@@ -1658,6 +1809,14 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, DeclRefExpr>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCIvarRefExpr>
objcIvarRefExpr;
+/// Matches a reference to a block.
+///
+/// Example: matches "^{}":
+/// \code
+/// void f() { ^{}(); }
+/// \endcode
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, BlockExpr> blockExpr;
+
/// Matches if statements.
///
/// Example matches 'if (x) {}'
@@ -1975,6 +2134,11 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, IntegerLiteral>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, FloatingLiteral>
floatLiteral;
+/// Matches imaginary literals, which are based on integer and floating
+/// point literals e.g.: 1i, 1.0i
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, ImaginaryLiteral>
+ imaginaryLiteral;
+
/// Matches user defined literal operator call.
///
/// Example match: "foo"_suffix
@@ -2331,8 +2495,9 @@ AST_MATCHER_P(UnaryExprOrTypeTraitExpr, ofKind, UnaryExprOrTypeTrait, Kind) {
/// alignof.
inline internal::Matcher<Stmt> alignOfExpr(
const internal::Matcher<UnaryExprOrTypeTraitExpr> &InnerMatcher) {
- return stmt(unaryExprOrTypeTraitExpr(allOf(
- ofKind(UETT_AlignOf), InnerMatcher)));
+ return stmt(unaryExprOrTypeTraitExpr(
+ allOf(anyOf(ofKind(UETT_AlignOf), ofKind(UETT_PreferredAlignOf)),
+ InnerMatcher)));
}
/// Same as unaryExprOrTypeTraitExpr, but only matching
@@ -3205,6 +3370,20 @@ AST_MATCHER_P(
InnerMatcher.matches(*Initializer, Finder, Builder));
}
+/// \brief Matches a static variable with local scope.
+///
+/// Example matches y (matcher = varDecl(isStaticLocal()))
+/// \code
+/// void f() {
+/// int x;
+/// static int y;
+/// }
+/// static int z;
+/// \endcode
+AST_MATCHER(VarDecl, isStaticLocal) {
+ return Node.isStaticLocal();
+}
+
/// Matches a variable declaration that has function scope and is a
/// non-static local variable.
///
@@ -3335,6 +3514,19 @@ AST_POLYMORPHIC_MATCHER_P2(hasArgument,
*Node.getArg(N)->IgnoreParenImpCasts(), Finder, Builder));
}
+/// Matches the n'th item of an initializer list expression.
+///
+/// Example matches y.
+/// (matcher = initListExpr(hasInit(0, expr())))
+/// \code
+/// int x{y}.
+/// \endcode
+AST_MATCHER_P2(InitListExpr, hasInit, unsigned, N,
+ ast_matchers::internal::Matcher<Expr>, InnerMatcher) {
+ return N < Node.getNumInits() &&
+ InnerMatcher.matches(*Node.getInit(N), Finder, Builder);
+}
+
/// Matches declaration statements that contain a specific number of
/// declarations.
///
@@ -3390,7 +3582,7 @@ AST_MATCHER_P2(DeclStmt, containsDeclaration, unsigned, N,
/// } catch (...) {
/// // ...
/// }
-/// /endcode
+/// \endcode
/// cxxCatchStmt(isCatchAll()) matches catch(...) but not catch(int).
AST_MATCHER(CXXCatchStmt, isCatchAll) {
return Node.getExceptionDecl() == nullptr;
@@ -3532,9 +3724,9 @@ AST_MATCHER(CXXCtorInitializer, isMemberInitializer) {
/// objcMessageExpr(hasAnyArgument(integerLiteral(equals(12))))
/// matches [i f:12]
AST_POLYMORPHIC_MATCHER_P(hasAnyArgument,
- AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr,
- CXXConstructExpr,
- ObjCMessageExpr),
+ AST_POLYMORPHIC_SUPPORTED_TYPES(
+ CallExpr, CXXConstructExpr,
+ CXXUnresolvedConstructExpr, ObjCMessageExpr),
internal::Matcher<Expr>, InnerMatcher) {
for (const Expr *Arg : Node.arguments()) {
BoundNodesTreeBuilder Result(*Builder);
@@ -4603,13 +4795,24 @@ AST_MATCHER(CXXMethodDecl, isUserProvided) {
/// \code
/// class Y {
/// void x() { this->x(); x(); Y y; y.x(); a; this->b; Y::b; }
+/// template <class T> void f() { this->f<T>(); f<T>(); }
/// int a;
/// static int b;
/// };
+/// template <class T>
+/// class Z {
+/// void x() { this->m; }
+/// };
/// \endcode
/// memberExpr(isArrow())
/// matches this->x, x, y.x, a, this->b
-AST_MATCHER(MemberExpr, isArrow) {
+/// cxxDependentScopeMemberExpr(isArrow())
+/// matches this->m
+/// unresolvedMemberExpr(isArrow())
+/// matches this->f<T>, f<T>
+AST_POLYMORPHIC_MATCHER(
+ isArrow, AST_POLYMORPHIC_SUPPORTED_TYPES(MemberExpr, UnresolvedMemberExpr,
+ CXXDependentScopeMemberExpr)) {
return Node.isArrow();
}
@@ -4773,8 +4976,17 @@ AST_MATCHER_P(MemberExpr, member,
/// matches "x.m" and "m"
/// with hasObjectExpression(...)
/// matching "x" and the implicit object expression of "m" which has type X*.
-AST_MATCHER_P(MemberExpr, hasObjectExpression,
- internal::Matcher<Expr>, InnerMatcher) {
+AST_POLYMORPHIC_MATCHER_P(
+ hasObjectExpression,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(MemberExpr, UnresolvedMemberExpr,
+ CXXDependentScopeMemberExpr),
+ internal::Matcher<Expr>, InnerMatcher) {
+ if (const auto *E = dyn_cast<UnresolvedMemberExpr>(&Node))
+ if (E->isImplicitAccess())
+ return false;
+ if (const auto *E = dyn_cast<CXXDependentScopeMemberExpr>(&Node))
+ if (E->isImplicitAccess())
+ return false;
return InnerMatcher.matches(*Node.getBase(), Finder, Builder);
}
@@ -5169,7 +5381,7 @@ AST_TYPE_TRAVERSE_MATCHER(hasDeducedType, getDeducedType,
/// decltype(2.0) b = 2.0;
/// \endcode
/// decltypeType(hasUnderlyingType(isInteger()))
-/// matches "auto a"
+/// matches the type of "a"
///
/// Usable as: Matcher<DecltypeType>
AST_TYPE_TRAVERSE_MATCHER(hasUnderlyingType, getUnderlyingType,
diff --git a/include/clang/ASTMatchers/ASTMatchersInternal.h b/include/clang/ASTMatchers/ASTMatchersInternal.h
index 9d9f867d053a..34851a907e0d 100644
--- a/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ b/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -261,7 +261,7 @@ public:
}
private:
- SmallVector<BoundNodesMap, 16> Bindings;
+ SmallVector<BoundNodesMap, 1> Bindings;
};
class ASTMatchFinder;
diff --git a/include/clang/ASTMatchers/Dynamic/Parser.h b/include/clang/ASTMatchers/Dynamic/Parser.h
index 907db69529d2..136265d32847 100644
--- a/include/clang/ASTMatchers/Dynamic/Parser.h
+++ b/include/clang/ASTMatchers/Dynamic/Parser.h
@@ -234,6 +234,7 @@ private:
const NamedValueMap *NamedValues,
Diagnostics *Error);
+ bool parseBindID(std::string &BindID);
bool parseExpressionImpl(VariantValue *Value);
bool parseMatcherExpressionImpl(const TokenInfo &NameToken,
VariantValue *Value);
diff --git a/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h b/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
new file mode 100644
index 000000000000..edc6e00f1d00
--- /dev/null
+++ b/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
@@ -0,0 +1,96 @@
+//===---------- ExprMutationAnalyzer.h ------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_EXPRMUTATIONANALYZER_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_EXPRMUTATIONANALYZER_H
+
+#include <type_traits>
+
+#include "clang/AST/AST.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "llvm/ADT/DenseMap.h"
+
+namespace clang {
+
+class FunctionParmMutationAnalyzer;
+
+/// Analyzes whether any mutative operations are applied to an expression within
+/// a given statement.
+class ExprMutationAnalyzer {
+public:
+ ExprMutationAnalyzer(const Stmt &Stm, ASTContext &Context)
+ : Stm(Stm), Context(Context) {}
+
+ bool isMutated(const Expr *Exp) { return findMutation(Exp) != nullptr; }
+ bool isMutated(const Decl *Dec) { return findMutation(Dec) != nullptr; }
+ const Stmt *findMutation(const Expr *Exp);
+ const Stmt *findMutation(const Decl *Dec);
+
+ bool isPointeeMutated(const Expr *Exp) {
+ return findPointeeMutation(Exp) != nullptr;
+ }
+ bool isPointeeMutated(const Decl *Dec) {
+ return findPointeeMutation(Dec) != nullptr;
+ }
+ const Stmt *findPointeeMutation(const Expr *Exp);
+ const Stmt *findPointeeMutation(const Decl *Dec);
+
+private:
+ using MutationFinder = const Stmt *(ExprMutationAnalyzer::*)(const Expr *);
+ using ResultMap = llvm::DenseMap<const Expr *, const Stmt *>;
+
+ const Stmt *findMutationMemoized(const Expr *Exp,
+ llvm::ArrayRef<MutationFinder> Finders,
+ ResultMap &MemoizedResults);
+ const Stmt *tryEachDeclRef(const Decl *Dec, MutationFinder Finder);
+
+ bool isUnevaluated(const Expr *Exp);
+
+ const Stmt *findExprMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
+ const Stmt *findDeclMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
+ const Stmt *
+ findExprPointeeMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
+ const Stmt *
+ findDeclPointeeMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
+
+ const Stmt *findDirectMutation(const Expr *Exp);
+ const Stmt *findMemberMutation(const Expr *Exp);
+ const Stmt *findArrayElementMutation(const Expr *Exp);
+ const Stmt *findCastMutation(const Expr *Exp);
+ const Stmt *findRangeLoopMutation(const Expr *Exp);
+ const Stmt *findReferenceMutation(const Expr *Exp);
+ const Stmt *findFunctionArgMutation(const Expr *Exp);
+
+ const Stmt &Stm;
+ ASTContext &Context;
+ llvm::DenseMap<const FunctionDecl *,
+ std::unique_ptr<FunctionParmMutationAnalyzer>>
+ FuncParmAnalyzer;
+ ResultMap Results;
+ ResultMap PointeeResults;
+};
+
+// A convenient wrapper around ExprMutationAnalyzer for analyzing function
+// params.
+class FunctionParmMutationAnalyzer {
+public:
+ FunctionParmMutationAnalyzer(const FunctionDecl &Func, ASTContext &Context);
+
+ bool isMutated(const ParmVarDecl *Parm) {
+ return findMutation(Parm) != nullptr;
+ }
+ const Stmt *findMutation(const ParmVarDecl *Parm);
+
+private:
+ ExprMutationAnalyzer BodyAnalyzer;
+ llvm::DenseMap<const ParmVarDecl *, const Stmt *> Results;
+};
+
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_ANALYSES_EXPRMUTATIONANALYZER_H
diff --git a/include/clang/Analysis/Analyses/LiveVariables.h b/include/clang/Analysis/Analyses/LiveVariables.h
index 0cb500fffb95..114597661a67 100644
--- a/include/clang/Analysis/Analyses/LiveVariables.h
+++ b/include/clang/Analysis/Analyses/LiveVariables.h
@@ -88,9 +88,13 @@ public:
/// before the given block-level expression (see runOnAllBlocks).
bool isLive(const Stmt *Loc, const Stmt *StmtVal);
- /// Print to stderr the liveness information associated with
+ /// Print to stderr the variable liveness information associated with
/// each basic block.
- void dumpBlockLiveness(const SourceManager& M);
+ void dumpBlockLiveness(const SourceManager &M);
+
+ /// Print to stderr the statement liveness information associated with
+ /// each basic block.
+ void dumpStmtLiveness(const SourceManager &M);
void runOnAllBlocks(Observer &obs);
diff --git a/include/clang/Analysis/Analyses/PseudoConstantAnalysis.h b/include/clang/Analysis/Analyses/PseudoConstantAnalysis.h
deleted file mode 100644
index c4ec2f22eca0..000000000000
--- a/include/clang/Analysis/Analyses/PseudoConstantAnalysis.h
+++ /dev/null
@@ -1,45 +0,0 @@
-//== PseudoConstantAnalysis.h - Find Pseudo-constants in the AST -*- C++ -*-==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file tracks the usage of variables in a Decl body to see if they are
-// never written to, implying that they constant. This is useful in static
-// analysis to see if a developer might have intended a variable to be const.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_PSEUDOCONSTANTANALYSIS_H
-#define LLVM_CLANG_ANALYSIS_ANALYSES_PSEUDOCONSTANTANALYSIS_H
-
-#include "clang/AST/Stmt.h"
-
-namespace clang {
-
-class PseudoConstantAnalysis {
-public:
- PseudoConstantAnalysis(const Stmt *DeclBody);
- ~PseudoConstantAnalysis();
-
- bool isPseudoConstant(const VarDecl *VD);
- bool wasReferenced(const VarDecl *VD);
-
-private:
- void RunAnalysis();
- inline static const Decl *getDecl(const Expr *E);
-
- // for storing the result of analyzed ValueDecls
- void *NonConstantsImpl;
- void *UsedVarsImpl;
-
- const Stmt *DeclBody;
- bool Analyzed;
-};
-
-}
-
-#endif
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyCommon.h b/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
index 599c164923cb..422a1db7f6fd 100644
--- a/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
+++ b/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
@@ -397,6 +397,8 @@ private:
CallingContext *Ctx) ;
til::SExpr *translateCXXThisExpr(const CXXThisExpr *TE, CallingContext *Ctx);
til::SExpr *translateMemberExpr(const MemberExpr *ME, CallingContext *Ctx);
+ til::SExpr *translateObjCIVarRefExpr(const ObjCIvarRefExpr *IVRE,
+ CallingContext *Ctx);
til::SExpr *translateCallExpr(const CallExpr *CE, CallingContext *Ctx,
const Expr *SelfE = nullptr);
til::SExpr *translateCXXMemberCallExpr(const CXXMemberCallExpr *ME,
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyTIL.h b/include/clang/Analysis/Analyses/ThreadSafetyTIL.h
index 810f2052b7a5..c106a9a42731 100644
--- a/include/clang/Analysis/Analyses/ThreadSafetyTIL.h
+++ b/include/clang/Analysis/Analyses/ThreadSafetyTIL.h
@@ -1643,10 +1643,10 @@ private:
friend class SCFG;
// assign unique ids to all instructions
- int renumberInstrs(int id);
+ unsigned renumberInstrs(unsigned id);
- int topologicalSort(SimpleArray<BasicBlock *> &Blocks, int ID);
- int topologicalFinalSort(SimpleArray<BasicBlock *> &Blocks, int ID);
+ unsigned topologicalSort(SimpleArray<BasicBlock *> &Blocks, unsigned ID);
+ unsigned topologicalFinalSort(SimpleArray<BasicBlock *> &Blocks, unsigned ID);
void computeDominator();
void computePostDominator();
@@ -1657,7 +1657,7 @@ private:
SCFG *CFGPtr = nullptr;
// Unique ID for this BB in the containing CFG. IDs are in topological order.
- int BlockID : 31;
+ unsigned BlockID : 31;
// Bit to determine if a block has been visited during a traversal.
bool Visited : 1;
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h b/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h
index 49031010a75b..32aadf526587 100644
--- a/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h
+++ b/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h
@@ -785,7 +785,26 @@ protected:
void printCast(const Cast *E, StreamType &SS) {
if (!CStyle) {
SS << "cast[";
- SS << E->castOpcode();
+ switch (E->castOpcode()) {
+ case CAST_none:
+ SS << "none";
+ break;
+ case CAST_extendNum:
+ SS << "extendNum";
+ break;
+ case CAST_truncNum:
+ SS << "truncNum";
+ break;
+ case CAST_toFloat:
+ SS << "toFloat";
+ break;
+ case CAST_toInt:
+ SS << "toInt";
+ break;
+ case CAST_objToPtr:
+ SS << "objToPtr";
+ break;
+ }
SS << "](";
self()->printSExpr(E->expr(), SS, Prec_Unary);
SS << ")";
diff --git a/include/clang/Analysis/AnalysisDeclContext.h b/include/clang/Analysis/AnalysisDeclContext.h
index 19531d92e645..490d2ce346be 100644
--- a/include/clang/Analysis/AnalysisDeclContext.h
+++ b/include/clang/Analysis/AnalysisDeclContext.h
@@ -40,7 +40,6 @@ class ImplicitParamDecl;
class LocationContext;
class LocationContextManager;
class ParentMap;
-class PseudoConstantAnalysis;
class StackFrameContext;
class Stmt;
class VarDecl;
@@ -84,7 +83,6 @@ class AnalysisDeclContext {
bool builtCFG = false;
bool builtCompleteCFG = false;
std::unique_ptr<ParentMap> PM;
- std::unique_ptr<PseudoConstantAnalysis> PCA;
std::unique_ptr<CFGReverseBlockReachabilityAnalysis> CFA;
llvm::BumpPtrAllocator A;
@@ -175,7 +173,6 @@ public:
bool isCFGBuilt() const { return builtCFG; }
ParentMap &getParentMap();
- PseudoConstantAnalysis *getPseudoConstantAnalysis();
using referenced_decls_iterator = const VarDecl * const *;
@@ -230,17 +227,23 @@ private:
AnalysisDeclContext *Ctx;
const LocationContext *Parent;
+ int64_t ID;
protected:
LocationContext(ContextKind k, AnalysisDeclContext *ctx,
- const LocationContext *parent)
- : Kind(k), Ctx(ctx), Parent(parent) {}
+ const LocationContext *parent,
+ int64_t ID)
+ : Kind(k), Ctx(ctx), Parent(parent), ID(ID) {}
public:
virtual ~LocationContext();
ContextKind getKind() const { return Kind; }
+ int64_t getID() const {
+ return ID;
+ }
+
AnalysisDeclContext *getAnalysisDeclContext() const { return Ctx; }
const LocationContext *getParent() const { return Parent; }
@@ -300,8 +303,9 @@ class StackFrameContext : public LocationContext {
StackFrameContext(AnalysisDeclContext *ctx, const LocationContext *parent,
const Stmt *s, const CFGBlock *blk,
- unsigned idx)
- : LocationContext(StackFrame, ctx, parent), CallSite(s),
+ unsigned idx,
+ int64_t ID)
+ : LocationContext(StackFrame, ctx, parent, ID), CallSite(s),
Block(blk), Index(idx) {}
public:
@@ -337,8 +341,8 @@ class ScopeContext : public LocationContext {
const Stmt *Enter;
ScopeContext(AnalysisDeclContext *ctx, const LocationContext *parent,
- const Stmt *s)
- : LocationContext(Scope, ctx, parent), Enter(s) {}
+ const Stmt *s, int64_t ID)
+ : LocationContext(Scope, ctx, parent, ID), Enter(s) {}
public:
~ScopeContext() override = default;
@@ -364,9 +368,10 @@ class BlockInvocationContext : public LocationContext {
const void *ContextData;
BlockInvocationContext(AnalysisDeclContext *ctx,
- const LocationContext *parent,
- const BlockDecl *bd, const void *contextData)
- : LocationContext(Block, ctx, parent), BD(bd), ContextData(contextData) {}
+ const LocationContext *parent, const BlockDecl *bd,
+ const void *contextData, int64_t ID)
+ : LocationContext(Block, ctx, parent, ID), BD(bd),
+ ContextData(contextData) {}
public:
~BlockInvocationContext() override = default;
@@ -392,6 +397,9 @@ public:
class LocationContextManager {
llvm::FoldingSet<LocationContext> Contexts;
+ /// ID used for generating a new location context.
+ int64_t NewID = 0;
+
public:
~LocationContextManager();
diff --git a/include/clang/Analysis/AnalysisDiagnostic.h b/include/clang/Analysis/AnalysisDiagnostic.h
index 8d28971cfe5c..087ffdcde90c 100644
--- a/include/clang/Analysis/AnalysisDiagnostic.h
+++ b/include/clang/Analysis/AnalysisDiagnostic.h
@@ -10,19 +10,6 @@
#ifndef LLVM_CLANG_ANALYSIS_ANALYSISDIAGNOSTIC_H
#define LLVM_CLANG_ANALYSIS_ANALYSISDIAGNOSTIC_H
-#include "clang/Basic/Diagnostic.h"
-
-namespace clang {
- namespace diag {
- enum {
-#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
- SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
-#define ANALYSISSTART
-#include "clang/Basic/DiagnosticAnalysisKinds.inc"
-#undef DIAG
- NUM_BUILTIN_ANALYSIS_DIAGNOSTICS
- };
- } // end namespace diag
-} // end namespace clang
+#include "clang/Basic/DiagnosticAnalysis.h"
#endif
diff --git a/include/clang/Analysis/CallGraph.h b/include/clang/Analysis/CallGraph.h
index ae0f392ed969..e230930b59e0 100644
--- a/include/clang/Analysis/CallGraph.h
+++ b/include/clang/Analysis/CallGraph.h
@@ -131,6 +131,7 @@ public:
bool TraverseStmt(Stmt *S) { return true; }
bool shouldWalkTypesOfTypeLocs() const { return false; }
+ bool shouldVisitTemplateInstantiations() const { return true; }
private:
/// Add the given declaration to the call graph.
diff --git a/include/clang/Analysis/CloneDetection.h b/include/clang/Analysis/CloneDetection.h
index 915ec58a5144..fadca137b88d 100644
--- a/include/clang/Analysis/CloneDetection.h
+++ b/include/clang/Analysis/CloneDetection.h
@@ -122,7 +122,7 @@ public:
/// Returns the start sourcelocation of the first statement in this sequence.
///
/// This method should only be called on a non-empty StmtSequence object.
- SourceLocation getStartLoc() const;
+ SourceLocation getBeginLoc() const;
/// Returns the end sourcelocation of the last statement in this sequence.
///
diff --git a/include/clang/Analysis/ConstructionContext.h b/include/clang/Analysis/ConstructionContext.h
index aee67865df25..27c1d5b9f1a5 100644
--- a/include/clang/Analysis/ConstructionContext.h
+++ b/include/clang/Analysis/ConstructionContext.h
@@ -19,6 +19,7 @@
#include "clang/Analysis/Support/BumpVector.h"
#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
namespace clang {
@@ -623,9 +624,16 @@ public:
};
class ArgumentConstructionContext : public ConstructionContext {
- const Expr *CE; // The call of which the context is an argument.
- unsigned Index; // Which argument we're constructing.
- const CXXBindTemporaryExpr *BTE; // Whether the object needs to be destroyed.
+ // The call of which the context is an argument.
+ const Expr *CE;
+
+ // Which argument we're constructing. Note that when numbering between
+ // arguments and parameters is inconsistent (eg., operator calls),
+ // this is the index of the argument, not of the parameter.
+ unsigned Index;
+
+ // Whether the object needs to be destroyed.
+ const CXXBindTemporaryExpr *BTE;
friend class ConstructionContext; // Allows to create<>() itself.
diff --git a/include/clang/Analysis/ProgramPoint.h b/include/clang/Analysis/ProgramPoint.h
index 25ae93fae6b8..d78174ecd70e 100644
--- a/include/clang/Analysis/ProgramPoint.h
+++ b/include/clang/Analysis/ProgramPoint.h
@@ -80,6 +80,7 @@ public:
CallEnterKind,
CallExitBeginKind,
CallExitEndKind,
+ FunctionExitKind,
PreImplicitCallKind,
PostImplicitCallKind,
MinImplicitCallKind = PreImplicitCallKind,
@@ -214,6 +215,10 @@ public:
ID.AddPointer(getTag());
}
+ void print(StringRef CR, llvm::raw_ostream &Out) const;
+
+ LLVM_DUMP_METHOD void dump() const;
+
static ProgramPoint getProgramPoint(const Stmt *S, ProgramPoint::Kind K,
const LocationContext *LC,
const ProgramPointTag *tag);
@@ -329,6 +334,29 @@ private:
}
};
+class FunctionExitPoint : public ProgramPoint {
+public:
+ explicit FunctionExitPoint(const ReturnStmt *S,
+ const LocationContext *LC,
+ const ProgramPointTag *tag = nullptr)
+ : ProgramPoint(S, FunctionExitKind, LC, tag) {}
+
+ const CFGBlock *getBlock() const {
+ return &getLocationContext()->getCFG()->getExit();
+ }
+
+ const ReturnStmt *getStmt() const {
+ return reinterpret_cast<const ReturnStmt *>(getData1());
+ }
+
+private:
+ friend class ProgramPoint;
+ FunctionExitPoint() = default;
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() == FunctionExitKind;
+ }
+};
+
// PostCondition represents the post program point of a branch condition.
class PostCondition : public PostStmt {
public:
diff --git a/include/clang/Analysis/SelectorExtras.h b/include/clang/Analysis/SelectorExtras.h
new file mode 100644
index 000000000000..767063e835e4
--- /dev/null
+++ b/include/clang/Analysis/SelectorExtras.h
@@ -0,0 +1,37 @@
+//=== SelectorExtras.h - Helpers for checkers using selectors -----*- C++ -*-=//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_ANALYSIS_SELECTOREXTRAS_H
+#define LLVM_CLANG_LIB_ANALYSIS_SELECTOREXTRAS_H
+
+#include "clang/AST/ASTContext.h"
+
+namespace clang {
+
+template <typename... IdentifierInfos>
+static inline Selector getKeywordSelector(ASTContext &Ctx,
+ IdentifierInfos *... IIs) {
+ static_assert(sizeof...(IdentifierInfos),
+ "keyword selectors must have at least one argument");
+ SmallVector<IdentifierInfo *, 10> II({&Ctx.Idents.get(IIs)...});
+
+ return Ctx.Selectors.getSelector(II.size(), &II[0]);
+}
+
+template <typename... IdentifierInfos>
+static inline void lazyInitKeywordSelector(Selector &Sel, ASTContext &Ctx,
+ IdentifierInfos *... IIs) {
+ if (!Sel.isNull())
+ return;
+ Sel = getKeywordSelector(Ctx, IIs...);
+}
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/AlignedAllocation.h b/include/clang/Basic/AlignedAllocation.h
index 9751f4118447..c995f47a7d74 100644
--- a/include/clang/Basic/AlignedAllocation.h
+++ b/include/clang/Basic/AlignedAllocation.h
@@ -27,8 +27,8 @@ inline llvm::VersionTuple alignedAllocMinVersion(llvm::Triple::OSType OS) {
default:
break;
case llvm::Triple::Darwin:
- case llvm::Triple::MacOSX: // Earliest supporting version is 10.13.
- return llvm::VersionTuple(10U, 13U);
+ case llvm::Triple::MacOSX: // Earliest supporting version is 10.14.
+ return llvm::VersionTuple(10U, 14U);
case llvm::Triple::IOS:
case llvm::Triple::TvOS: // Earliest supporting version is 11.0.0.
return llvm::VersionTuple(11U);
diff --git a/include/clang/Basic/AllDiagnostics.h b/include/clang/Basic/AllDiagnostics.h
index afec2d7e0f2f..6c7f95658970 100644
--- a/include/clang/Basic/AllDiagnostics.h
+++ b/include/clang/Basic/AllDiagnostics.h
@@ -15,17 +15,17 @@
#ifndef LLVM_CLANG_BASIC_ALLDIAGNOSTICS_H
#define LLVM_CLANG_BASIC_ALLDIAGNOSTICS_H
-#include "clang/AST/ASTDiagnostic.h"
-#include "clang/AST/CommentDiagnostic.h"
-#include "clang/Analysis/AnalysisDiagnostic.h"
-#include "clang/CrossTU/CrossTUDiagnostic.h"
-#include "clang/Driver/DriverDiagnostic.h"
-#include "clang/Frontend/FrontendDiagnostic.h"
-#include "clang/Lex/LexDiagnostic.h"
-#include "clang/Parse/ParseDiagnostic.h"
-#include "clang/Sema/SemaDiagnostic.h"
-#include "clang/Serialization/SerializationDiagnostic.h"
-#include "clang/Tooling/Refactoring/RefactoringDiagnostic.h"
+#include "clang/Basic/DiagnosticAST.h"
+#include "clang/Basic/DiagnosticAnalysis.h"
+#include "clang/Basic/DiagnosticComment.h"
+#include "clang/Basic/DiagnosticCrossTU.h"
+#include "clang/Basic/DiagnosticDriver.h"
+#include "clang/Basic/DiagnosticFrontend.h"
+#include "clang/Basic/DiagnosticLex.h"
+#include "clang/Basic/DiagnosticParse.h"
+#include "clang/Basic/DiagnosticSema.h"
+#include "clang/Basic/DiagnosticSerialization.h"
+#include "clang/Basic/DiagnosticRefactoring.h"
namespace clang {
template <size_t SizeOfStr, typename FieldType>
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
index fea8e129d7da..1fe1dd39948a 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -90,6 +90,15 @@ def NonBitField : SubsetSubject<Field,
[{!S->isBitField()}],
"non-bit-field non-static data members">;
+def NonStaticCXXMethod : SubsetSubject<CXXMethod,
+ [{!S->isStatic()}],
+ "non-static member functions">;
+
+def NonStaticNonConstCXXMethod
+ : SubsetSubject<CXXMethod,
+ [{!S->isStatic() && !S->isConst()}],
+ "non-static non-const member functions">;
+
def ObjCInstanceMethod : SubsetSubject<ObjCMethod,
[{S->isInstanceMethod()}],
"Objective-C instance methods">;
@@ -145,8 +154,9 @@ def HasFunctionProto : SubsetSubject<DeclBase,
// function. Accepted as a function type attribute on the type of such a
// member function.
// FIXME: This does not actually ever match currently.
-def ImplicitObjectParameter : SubsetSubject<Function, [{false}],
- "implicit object parameters">;
+def ImplicitObjectParameter
+ : SubsetSubject<Function, [{static_cast<void>(S), false}],
+ "implicit object parameters">;
// A single argument to an attribute
class Argument<string name, bit optional, bit fake = 0> {
@@ -288,8 +298,9 @@ def COnly : LangOpt<"CPlusPlus", 1>;
def CPlusPlus : LangOpt<"CPlusPlus">;
def OpenCL : LangOpt<"OpenCL">;
def RenderScript : LangOpt<"RenderScript">;
-def ObjC : LangOpt<"ObjC1">;
+def ObjC : LangOpt<"ObjC">;
def BlocksSupported : LangOpt<"Blocks">;
+def ObjCAutoRefCount : LangOpt<"ObjCAutoRefCount">;
// Defines targets for target-specific attributes. Empty lists are unchecked.
class TargetSpec {
@@ -467,13 +478,12 @@ class Attr {
// in a class template definition.
bit MeaningfulToClassTemplateDefinition = 0;
// Set to true if this attribute can be used with '#pragma clang attribute'.
- // By default, when this value is false, an attribute is supported by the
- // '#pragma clang attribute' only when:
- // - It has documentation.
+ // By default, an attribute is supported by the '#pragma clang attribute'
+ // only when:
// - It has a subject list whose subjects can be represented using subject
// match rules.
// - It has GNU/CXX11 spelling and doesn't require delayed parsing.
- bit ForcePragmaAttributeSupport = 0;
+ bit PragmaAttributeSupport;
// Lists language options, one of which is required to be true for the
// attribute to be applicable. If empty, no language options are required.
list<LangOpt> LangOpts = [];
@@ -488,10 +498,7 @@ class Attr {
}
/// A type attribute is not processed on a declaration or a statement.
-class TypeAttr : Attr {
- // By default, type attributes do not get an AST node.
- let ASTNode = 0;
-}
+class TypeAttr : Attr;
/// A stmt attribute is not processed on a declaration or a type.
class StmtAttr : Attr;
@@ -657,6 +664,7 @@ def AnalyzerNoReturn : InheritableAttr {
// vendor namespace, or should it use a vendor namespace specific to the
// analyzer?
let Spellings = [GNU<"analyzer_noreturn">];
+ // TODO: Add subject list.
let Documentation = [Undocumented];
}
@@ -665,7 +673,7 @@ def Annotate : InheritableParamAttr {
let Args = [StringArgument<"Annotation">];
// Ensure that the annotate attribute can be used with
// '#pragma clang attribute' even though it has no subject list.
- let ForcePragmaAttributeSupport = 1;
+ let PragmaAttributeSupport = 1;
let Documentation = [Undocumented];
}
@@ -720,6 +728,7 @@ def Availability : InheritableAttr {
.Case("macos_app_extension", "macOS (App Extension)")
.Case("tvos_app_extension", "tvOS (App Extension)")
.Case("watchos_app_extension", "watchOS (App Extension)")
+ .Case("swift", "Swift")
.Default(llvm::StringRef());
}
static llvm::StringRef getPlatformNameSourceSpelling(llvm::StringRef Platform) {
@@ -808,19 +817,56 @@ def CFUnknownTransfer : InheritableAttr {
def CFReturnsRetained : InheritableAttr {
let Spellings = [Clang<"cf_returns_retained">];
// let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
- let Documentation = [Undocumented];
+ let Documentation = [RetainBehaviorDocs];
}
def CFReturnsNotRetained : InheritableAttr {
let Spellings = [Clang<"cf_returns_not_retained">];
// let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
- let Documentation = [Undocumented];
+ let Documentation = [RetainBehaviorDocs];
}
def CFConsumed : InheritableParamAttr {
let Spellings = [Clang<"cf_consumed">];
let Subjects = SubjectList<[ParmVar]>;
- let Documentation = [Undocumented];
+ let Documentation = [RetainBehaviorDocs];
+}
+
+// OSObject-based attributes.
+def OSConsumed : InheritableParamAttr {
+ let Spellings = [Clang<"os_consumed">];
+ let Subjects = SubjectList<[ParmVar]>;
+ let Documentation = [RetainBehaviorDocs];
+}
+
+def OSReturnsRetained : InheritableAttr {
+ let Spellings = [Clang<"os_returns_retained">];
+ let Subjects = SubjectList<[Function, ObjCMethod, ObjCProperty, ParmVar]>;
+ let Documentation = [RetainBehaviorDocs];
+}
+
+def OSReturnsNotRetained : InheritableAttr {
+ let Spellings = [Clang<"os_returns_not_retained">];
+ let Subjects = SubjectList<[Function, ObjCMethod, ObjCProperty, ParmVar]>;
+ let Documentation = [RetainBehaviorDocs];
+}
+
+def OSReturnsRetainedOnZero : InheritableAttr {
+ let Spellings = [Clang<"os_returns_retained_on_zero">];
+ let Subjects = SubjectList<[ParmVar]>;
+ let Documentation = [RetainBehaviorDocs];
+}
+
+def OSReturnsRetainedOnNonZero : InheritableAttr {
+ let Spellings = [Clang<"os_returns_retained_on_non_zero">];
+ let Subjects = SubjectList<[ParmVar]>;
+ let Documentation = [RetainBehaviorDocs];
+}
+
+def OSConsumesThis : InheritableAttr {
+ let Spellings = [Clang<"os_consumes_this">];
+ let Subjects = SubjectList<[NonStaticCXXMethod]>;
+ let Documentation = [RetainBehaviorDocs];
}
def Cleanup : InheritableAttr {
@@ -855,21 +901,19 @@ def Constructor : InheritableAttr {
}
def CPUSpecific : InheritableAttr {
- let Spellings = [Clang<"cpu_specific">];
+ let Spellings = [Clang<"cpu_specific">, Declspec<"cpu_specific">];
let Args = [VariadicIdentifierArgument<"Cpus">];
let Subjects = SubjectList<[Function]>;
let Documentation = [CPUSpecificCPUDispatchDocs];
let AdditionalMembers = [{
- unsigned ActiveArgIndex = 0;
-
- IdentifierInfo *getCurCPUName() const {
- return *(cpus_begin() + ActiveArgIndex);
+ IdentifierInfo *getCPUName(unsigned Index) const {
+ return *(cpus_begin() + Index);
}
}];
}
def CPUDispatch : InheritableAttr {
- let Spellings = [Clang<"cpu_dispatch">];
+ let Spellings = [Clang<"cpu_dispatch">, Declspec<"cpu_dispatch">];
let Args = [VariadicIdentifierArgument<"Cpus">];
let Subjects = SubjectList<[Function]>;
let Documentation = [CPUSpecificCPUDispatchDocs];
@@ -1089,10 +1133,14 @@ def EnableIf : InheritableAttr {
def ExtVectorType : Attr {
// This is an OpenCL-related attribute and does not receive a [[]] spelling.
let Spellings = [GNU<"ext_vector_type">];
+ // FIXME: This subject list is wrong; this is a type attribute.
let Subjects = SubjectList<[TypedefName], ErrorDiag>;
let Args = [ExprArgument<"NumElements">];
let ASTNode = 0;
let Documentation = [Undocumented];
+ // This is a type attribute with an incorrect subject list, so should not be
+ // permitted by #pragma clang attribute.
+ let PragmaAttributeSupport = 0;
}
def FallThrough : StmtAttr {
@@ -1165,7 +1213,7 @@ def FormatArg : InheritableAttr {
def GNUInline : InheritableAttr {
let Spellings = [GCC<"gnu_inline">];
let Subjects = SubjectList<[Function]>;
- let Documentation = [Undocumented];
+ let Documentation = [GnuInlineDocs];
}
def Hot : InheritableAttr {
@@ -1218,7 +1266,7 @@ def LayoutVersion : InheritableAttr, TargetSpecificAttr<TargetMicrosoftCXXABI> {
let Documentation = [LayoutVersionDocs];
}
-def LifetimeBound : InheritableAttr {
+def LifetimeBound : DeclOrTypeAttr {
let Spellings = [Clang<"lifetimebound", 0>];
let Subjects = SubjectList<[ParmVar, ImplicitObjectParameter], ErrorDiag>;
let Documentation = [LifetimeBoundDocs];
@@ -1309,6 +1357,9 @@ def Mode : Attr {
let Subjects = SubjectList<[Var, Enum, TypedefName, Field], ErrorDiag>;
let Args = [IdentifierArgument<"Mode">];
let Documentation = [Undocumented];
+ // This is notionally a type attribute, which #pragma clang attribute
+ // generally does not support.
+ let PragmaAttributeSupport = 0;
}
def Naked : InheritableAttr {
@@ -1321,12 +1372,16 @@ def NeonPolyVectorType : TypeAttr {
let Spellings = [Clang<"neon_polyvector_type">];
let Args = [IntArgument<"NumElements">];
let Documentation = [Undocumented];
+ // Represented as VectorType instead.
+ let ASTNode = 0;
}
def NeonVectorType : TypeAttr {
let Spellings = [Clang<"neon_vector_type">];
let Args = [IntArgument<"NumElements">];
let Documentation = [Undocumented];
+ // Represented as VectorType instead.
+ let ASTNode = 0;
}
def ReturnsTwice : InheritableAttr {
@@ -1501,6 +1556,14 @@ def TypeNullUnspecified : TypeAttr {
let Documentation = [TypeNullUnspecifiedDocs];
}
+// This is a marker used to indicate that an __unsafe_unretained qualifier was
+// ignored because ARC is not enabled. The usual representation for this
+// qualifier is as an ObjCOwnership attribute with Kind == "none".
+def ObjCInertUnsafeUnretained : TypeAttr {
+ let Spellings = [Keyword<"__unsafe_unretained">];
+ let Documentation = [Undocumented];
+}
+
def ObjCKindOf : TypeAttr {
let Spellings = [Keyword<"__kindof">];
let Documentation = [Undocumented];
@@ -1588,34 +1651,34 @@ def ObjCBridgeRelated : InheritableAttr {
let Documentation = [Undocumented];
}
-def NSReturnsRetained : InheritableAttr {
+def NSReturnsRetained : DeclOrTypeAttr {
let Spellings = [Clang<"ns_returns_retained">];
// let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
- let Documentation = [Undocumented];
+ let Documentation = [RetainBehaviorDocs];
}
def NSReturnsNotRetained : InheritableAttr {
let Spellings = [Clang<"ns_returns_not_retained">];
// let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
- let Documentation = [Undocumented];
+ let Documentation = [RetainBehaviorDocs];
}
def NSReturnsAutoreleased : InheritableAttr {
let Spellings = [Clang<"ns_returns_autoreleased">];
// let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
- let Documentation = [Undocumented];
+ let Documentation = [RetainBehaviorDocs];
}
def NSConsumesSelf : InheritableAttr {
let Spellings = [Clang<"ns_consumes_self">];
let Subjects = SubjectList<[ObjCMethod]>;
- let Documentation = [Undocumented];
+ let Documentation = [RetainBehaviorDocs];
}
def NSConsumed : InheritableParamAttr {
let Spellings = [Clang<"ns_consumed">];
let Subjects = SubjectList<[ParmVar]>;
- let Documentation = [Undocumented];
+ let Documentation = [RetainBehaviorDocs];
}
def ObjCException : InheritableAttr {
@@ -1764,6 +1827,11 @@ def Pcs : DeclOrTypeAttr {
let Documentation = [PcsDocs];
}
+def AArch64VectorPcs: DeclOrTypeAttr {
+ let Spellings = [Clang<"aarch64_vector_pcs">];
+ let Documentation = [AArch64VectorPcsDocs];
+}
+
def Pure : InheritableAttr {
let Spellings = [GCC<"pure">];
let Documentation = [Undocumented];
@@ -1773,6 +1841,13 @@ def Regparm : TypeAttr {
let Spellings = [GCC<"regparm">];
let Args = [UnsignedArgument<"NumParams">];
let Documentation = [RegparmDocs];
+ // Represented as part of the enclosing function type.
+ let ASTNode = 0;
+}
+
+def NoDeref : TypeAttr {
+ let Spellings = [Clang<"noderef">];
+ let Documentation = [NoDerefDocs];
}
def ReqdWorkGroupSize : InheritableAttr {
@@ -1953,6 +2028,39 @@ def Target : InheritableAttr {
return parse(getFeaturesStr());
}
+ StringRef getArchitecture() const {
+ StringRef Features = getFeaturesStr();
+ if (Features == "default") return {};
+
+ SmallVector<StringRef, 1> AttrFeatures;
+ Features.split(AttrFeatures, ",");
+
+ for (auto &Feature : AttrFeatures) {
+ Feature = Feature.trim();
+ if (Feature.startswith("arch="))
+ return Feature.drop_front(sizeof("arch=") - 1);
+ }
+ return "";
+ }
+
+ // Gets the list of features as simple string-refs with no +/- or 'no-'.
+ // Only adds the items to 'Out' that are additions.
+ void getAddedFeatures(llvm::SmallVectorImpl<StringRef> &Out) const {
+ StringRef Features = getFeaturesStr();
+ if (Features == "default") return;
+
+ SmallVector<StringRef, 1> AttrFeatures;
+ Features.split(AttrFeatures, ",");
+
+ for (auto &Feature : AttrFeatures) {
+ Feature = Feature.trim();
+
+ if (!Feature.startswith("no-") && !Feature.startswith("arch=") &&
+ !Feature.startswith("fpmath=") && !Feature.startswith("tune="))
+ Out.push_back(Feature);
+ }
+ }
+
template<class Compare>
ParsedTargetAttr parse(Compare cmp) const {
ParsedTargetAttr Attrs = parse();
@@ -2061,10 +2169,9 @@ def ObjCGC : TypeAttr {
let Documentation = [Undocumented];
}
-def ObjCOwnership : InheritableAttr {
+def ObjCOwnership : DeclOrTypeAttr {
let Spellings = [Clang<"objc_ownership">];
let Args = [IdentifierArgument<"Kind">];
- let ASTNode = 0;
let Documentation = [Undocumented];
}
@@ -2102,6 +2209,8 @@ def VectorSize : TypeAttr {
let Spellings = [GCC<"vector_size">];
let Args = [ExprArgument<"NumBytes">];
let Documentation = [Undocumented];
+ // Represented as VectorType instead.
+ let ASTNode = 0;
}
def VecTypeHint : InheritableAttr {
@@ -2196,7 +2305,7 @@ def AnyX86NoCallerSavedRegisters : InheritableAttr,
let Documentation = [AnyX86NoCallerSavedRegistersDocs];
}
-def AnyX86NoCfCheck : InheritableAttr, TargetSpecificAttr<TargetAnyX86>{
+def AnyX86NoCfCheck : DeclOrTypeAttr, TargetSpecificAttr<TargetAnyX86>{
let Spellings = [GCC<"nocf_check">];
let Subjects = SubjectList<[FunctionLike]>;
let Documentation = [AnyX86NoCfCheckDocs];
@@ -2625,6 +2734,17 @@ def DLLExport : InheritableAttr, TargetSpecificAttr<TargetWindows> {
let Documentation = [DLLExportDocs];
}
+def DLLExportStaticLocal : InheritableAttr, TargetSpecificAttr<TargetWindows> {
+ // This attribute is used internally only when -fno-dllexport-inlines is
+ // passed. This attribute is added to inline function of class having
+ // dllexport attribute. And if the function has static local variables, this
+ // attribute is used to whether the variables are exported or not. Also if
+ // function has local static variables, the function is dllexported too.
+ let Spellings = [];
+ let Subjects = SubjectList<[Function]>;
+ let Documentation = [Undocumented];
+}
+
def DLLImport : InheritableAttr, TargetSpecificAttr<TargetWindows> {
let Spellings = [Declspec<"dllimport">, GCC<"dllimport">];
let Subjects = SubjectList<[Function, Var, CXXRecord, ObjCInterface]>;
@@ -2641,6 +2761,16 @@ public:
}];
}
+def DLLImportStaticLocal : InheritableAttr, TargetSpecificAttr<TargetWindows> {
+ // This attribute is used internally only when -fno-dllexport-inlines is
+ // passed. This attribute is added to inline function of class having
+ // dllimport attribute. And if the function has static local variables, this
+ // attribute is used to whether the variables are imported or not.
+ let Spellings = [];
+ let Subjects = SubjectList<[Function]>;
+ let Documentation = [Undocumented];
+}
+
def SelectAny : InheritableAttr {
let Spellings = [Declspec<"selectany">, GCC<"selectany">];
let Documentation = [SelectAnyDocs];
@@ -2748,7 +2878,11 @@ def LoopHint : Attr {
/// interleave_count: interleaves 'Value' loop iterations.
/// unroll: fully unroll loop if State == Enable.
/// unroll_count: unrolls loop 'Value' times.
- /// distribute: attempt to distribute loop if State == Enable
+ /// unroll_and_jam: attempt to unroll and jam loop if State == Enable.
+ /// unroll_and_jam_count: unroll and jams loop 'Value' times.
+ /// distribute: attempt to distribute loop if State == Enable.
+ /// pipeline: disable pipelining loop if State == Disable.
+ /// pipeline_initiation_interval: create loop schedule with initiation interval equal to 'Value'.
/// #pragma unroll <argument> directive
/// <no arg>: fully unrolls loop.
@@ -2756,14 +2890,17 @@ def LoopHint : Attr {
/// expression: unrolls loop 'Value' times.
let Spellings = [Pragma<"clang", "loop">, Pragma<"", "unroll">,
- Pragma<"", "nounroll">];
+ Pragma<"", "nounroll">, Pragma<"", "unroll_and_jam">,
+ Pragma<"", "nounroll_and_jam">];
/// State of the loop optimization specified by the spelling.
let Args = [EnumArgument<"Option", "OptionType",
["vectorize", "vectorize_width", "interleave", "interleave_count",
- "unroll", "unroll_count", "distribute"],
+ "unroll", "unroll_count", "unroll_and_jam", "unroll_and_jam_count",
+ "pipeline", "pipeline_initiation_interval", "distribute"],
["Vectorize", "VectorizeWidth", "Interleave", "InterleaveCount",
- "Unroll", "UnrollCount", "Distribute"]>,
+ "Unroll", "UnrollCount", "UnrollAndJam", "UnrollAndJamCount",
+ "PipelineDisabled", "PipelineInitiationInterval", "Distribute"]>,
EnumArgument<"State", "LoopHintState",
["enable", "disable", "numeric", "assume_safety", "full"],
["Enable", "Disable", "Numeric", "AssumeSafety", "Full"]>,
@@ -2778,6 +2915,10 @@ def LoopHint : Attr {
case InterleaveCount: return "interleave_count";
case Unroll: return "unroll";
case UnrollCount: return "unroll_count";
+ case UnrollAndJam: return "unroll_and_jam";
+ case UnrollAndJamCount: return "unroll_and_jam_count";
+ case PipelineDisabled: return "pipeline";
+ case PipelineInitiationInterval: return "pipeline_initiation_interval";
case Distribute: return "distribute";
}
llvm_unreachable("Unhandled LoopHint option.");
@@ -2787,9 +2928,9 @@ def LoopHint : Attr {
unsigned SpellingIndex = getSpellingListIndex();
// For "#pragma unroll" and "#pragma nounroll" the string "unroll" or
// "nounroll" is already emitted as the pragma name.
- if (SpellingIndex == Pragma_nounroll)
+ if (SpellingIndex == Pragma_nounroll || SpellingIndex == Pragma_nounroll_and_jam)
return;
- else if (SpellingIndex == Pragma_unroll) {
+ else if (SpellingIndex == Pragma_unroll || SpellingIndex == Pragma_unroll_and_jam) {
OS << ' ' << getValueString(Policy);
return;
}
@@ -2825,6 +2966,11 @@ def LoopHint : Attr {
return "#pragma nounroll";
else if (SpellingIndex == Pragma_unroll)
return "#pragma unroll" + (option == UnrollCount ? getValueString(Policy) : "");
+ else if (SpellingIndex == Pragma_nounroll_and_jam)
+ return "#pragma nounroll_and_jam";
+ else if (SpellingIndex == Pragma_unroll_and_jam)
+ return "#pragma unroll_and_jam" +
+ (option == UnrollAndJamCount ? getValueString(Policy) : "");
assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling");
return getOptionName(option) + getValueString(Policy);
@@ -2938,9 +3084,10 @@ def OMPDeclareSimdDecl : Attr {
}];
}
-def OMPDeclareTargetDecl : Attr {
+def OMPDeclareTargetDecl : InheritableAttr {
let Spellings = [Pragma<"omp", "declare target">];
let SemaHandler = 0;
+ let Subjects = SubjectList<[Function, SharedVar]>;
let Documentation = [OMPDeclareTargetDocs];
let Args = [
EnumArgument<"MapType", "MapTypeTy",
@@ -2953,6 +3100,15 @@ def OMPDeclareTargetDecl : Attr {
if (getMapType() != MT_To)
OS << ' ' << ConvertMapTypeTyToStr(getMapType());
}
+ static llvm::Optional<MapTypeTy>
+ isDeclareTargetDeclaration(const ValueDecl *VD) {
+ if (!VD->hasAttrs())
+ return llvm::None;
+ if (const auto *Attr = VD->getAttr<OMPDeclareTargetDeclAttr>())
+ return Attr->getMapType();
+
+ return llvm::None;
+ }
}];
}
@@ -2961,3 +3117,47 @@ def InternalLinkage : InheritableAttr {
let Subjects = SubjectList<[Var, Function, CXXRecord]>;
let Documentation = [InternalLinkageDocs];
}
+
+def ExcludeFromExplicitInstantiation : InheritableAttr {
+ let Spellings = [Clang<"exclude_from_explicit_instantiation">];
+ let Subjects = SubjectList<[Var, Function, CXXRecord]>;
+ let Documentation = [ExcludeFromExplicitInstantiationDocs];
+ let MeaningfulToClassTemplateDefinition = 1;
+}
+
+def Reinitializes : InheritableAttr {
+ let Spellings = [Clang<"reinitializes", 0>];
+ let Subjects = SubjectList<[NonStaticNonConstCXXMethod], ErrorDiag>;
+ let Documentation = [ReinitializesDocs];
+}
+
+def NoDestroy : InheritableAttr {
+ let Spellings = [Clang<"no_destroy", 0>];
+ let Subjects = SubjectList<[Var]>;
+ let Documentation = [NoDestroyDocs];
+}
+
+def AlwaysDestroy : InheritableAttr {
+ let Spellings = [Clang<"always_destroy", 0>];
+ let Subjects = SubjectList<[Var]>;
+ let Documentation = [AlwaysDestroyDocs];
+}
+
+def SpeculativeLoadHardening : InheritableAttr {
+ let Spellings = [Clang<"speculative_load_hardening">];
+ let Subjects = SubjectList<[Function, ObjCMethod], ErrorDiag>;
+ let Documentation = [SpeculativeLoadHardeningDocs];
+}
+
+def Uninitialized : InheritableAttr {
+ let Spellings = [Clang<"uninitialized", 0>];
+ let Subjects = SubjectList<[LocalVar]>;
+ let Documentation = [UninitializedDocs];
+}
+
+def ObjCExternallyRetained : InheritableAttr {
+ let LangOpts = [ObjCAutoRefCount];
+ let Spellings = [Clang<"objc_externally_retained">];
+ let Subjects = SubjectList<[NonParmVar, Function, Block, ObjCMethod]>;
+ let Documentation = [ObjCExternallyRetainedDocs];
+}
diff --git a/include/clang/Basic/AttrDocs.td b/include/clang/Basic/AttrDocs.td
index bb2993eab4bc..5773a92c9c15 100644
--- a/include/clang/Basic/AttrDocs.td
+++ b/include/clang/Basic/AttrDocs.td
@@ -38,6 +38,10 @@ Attributes in Clang
.. contents::
:local:
+.. |br| raw:: html
+
+ <br/>
+
Introduction
============
@@ -51,7 +55,7 @@ def SectionDocs : Documentation {
The ``section`` attribute allows you to specify a specific section a
global variable or function should be in after translation.
}];
- let Heading = "section (gnu::section, __declspec(allocate))";
+ let Heading = "section, __declspec(allocate)";
}
def InitSegDocs : Documentation {
@@ -270,7 +274,7 @@ that appears to be capable of returning to its caller.
def AssertCapabilityDocs : Documentation {
let Category = DocCatFunction;
- let Heading = "assert_capability (assert_shared_capability, clang::assert_capability, clang::assert_shared_capability)";
+ let Heading = "assert_capability, assert_shared_capability";
let Content = [{
Marks a function that dynamically tests whether a capability is held, and halts
the program if it is not held.
@@ -279,7 +283,7 @@ the program if it is not held.
def AcquireCapabilityDocs : Documentation {
let Category = DocCatFunction;
- let Heading = "acquire_capability (acquire_shared_capability, clang::acquire_capability, clang::acquire_shared_capability)";
+ let Heading = "acquire_capability, acquire_shared_capability";
let Content = [{
Marks a function as acquiring a capability.
}];
@@ -287,7 +291,7 @@ Marks a function as acquiring a capability.
def TryAcquireCapabilityDocs : Documentation {
let Category = DocCatFunction;
- let Heading = "try_acquire_capability (try_acquire_shared_capability, clang::try_acquire_capability, clang::try_acquire_shared_capability)";
+ let Heading = "try_acquire_capability, try_acquire_shared_capability";
let Content = [{
Marks a function that attempts to acquire a capability. This function may fail to
actually acquire the capability; they accept a Boolean value determining
@@ -298,7 +302,7 @@ the capability means success (false).
def ReleaseCapabilityDocs : Documentation {
let Category = DocCatFunction;
- let Heading = "release_capability (release_shared_capability, clang::release_capability, clang::release_shared_capability)";
+ let Heading = "release_capability, release_shared_capability";
let Content = [{
Marks a function as releasing a capability.
}];
@@ -550,9 +554,9 @@ certain user-defined criteria. For example:
.. code-block:: c
- void abs(int a)
+ int abs(int a)
__attribute__((diagnose_if(a >= 0, "Redundant abs call", "warning")));
- void must_abs(int a)
+ int must_abs(int a)
__attribute__((diagnose_if(a >= 0, "Redundant abs call", "error")));
int val = abs(1); // warning: Redundant abs call
@@ -843,6 +847,73 @@ Query for this feature with ``__has_attribute(objc_method_family)``.
}];
}
+def RetainBehaviorDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+The behavior of a function with respect to reference counting for Foundation
+(Objective-C), CoreFoundation (C) and OSObject (C++) is determined by a naming
+convention (e.g. functions starting with "get" are assumed to return at
+``+0``).
+
+It can be overriden using a family of the following attributes. In
+Objective-C, the annotation ``__attribute__((ns_returns_retained))`` applied to
+a function communicates that the object is returned at ``+1``, and the caller
+is responsible for freeing it.
+Similiarly, the annotation ``__attribute__((ns_returns_not_retained))``
+specifies that the object is returned at ``+0`` and the ownership remains with
+the callee.
+The annotation ``__attribute__((ns_consumes_self))`` specifies that
+the Objective-C method call consumes the reference to ``self``, e.g. by
+attaching it to a supplied parameter.
+Additionally, parameters can have an annotation
+``__attribute__((ns_consumed))``, which specifies that passing an owned object
+as that parameter effectively transfers the ownership, and the caller is no
+longer responsible for it.
+These attributes affect code generation when interacting with ARC code, and
+they are used by the Clang Static Analyzer.
+
+In C programs using CoreFoundation, a similar set of attributes:
+``__attribute__((cf_returns_not_retained))``,
+``__attribute__((cf_returns_retained))`` and ``__attribute__((cf_consumed))``
+have the same respective semantics when applied to CoreFoundation objects.
+These attributes affect code generation when interacting with ARC code, and
+they are used by the Clang Static Analyzer.
+
+Finally, in C++ interacting with XNU kernel (objects inheriting from OSObject),
+the same attribute family is present:
+``__attribute__((os_returns_not_retained))``,
+``__attribute__((os_returns_retained))`` and ``__attribute__((os_consumed))``,
+with the same respective semantics.
+Similar to ``__attribute__((ns_consumes_self))``,
+``__attribute__((os_consumes_this))`` specifies that the method call consumes
+the reference to "this" (e.g., when attaching it to a different object supplied
+as a parameter).
+Out parameters (parameters the function is meant to write into,
+either via pointers-to-pointers or references-to-pointers)
+may be annotated with ``__attribute__((os_returns_retained))``
+or ``__attribute__((os_returns_not_retained))`` which specifies that the object
+written into the out parameter should (or respectively should not) be released
+after use.
+Since often out parameters may or may not be written depending on the exit
+code of the function,
+annotations ``__attribute__((os_returns_retained_on_zero))``
+and ``__attribute__((os_returns_retained_on_non_zero))`` specify that
+an out parameter at ``+1`` is written if and only if the function returns a zero
+(respectively non-zero) error code.
+Observe that return-code-dependent out parameter annotations are only
+available for retained out parameters, as non-retained object do not have to be
+released by the callee.
+These attributes are only used by the Clang Static Analyzer.
+
+The family of attributes ``X_returns_X_retained`` can be added to functions,
+C++ methods, and Objective-C methods and properties.
+Attributes ``X_consumed`` can be added to parameters of methods, functions,
+and Objective-C methods.
+ }];
+}
+
+
+
def NoDebugDocs : Documentation {
let Category = DocCatVariable;
let Content = [{
@@ -1261,7 +1332,7 @@ of silently falling back on dynamic initialization.
def WarnMaybeUnusedDocs : Documentation {
let Category = DocCatVariable;
- let Heading = "maybe_unused, unused, gnu::unused";
+ let Heading = "maybe_unused, unused";
let Content = [{
When passing the ``-Wunused`` flag to Clang, entities that are unused by the
program may be diagnosed. The ``[[maybe_unused]]`` (or
@@ -1287,7 +1358,7 @@ enumerator, a non-static data member, or a label.
def WarnUnusedResultsDocs : Documentation {
let Category = DocCatFunction;
- let Heading = "nodiscard, warn_unused_result, clang::warn_unused_result, gnu::warn_unused_result";
+ let Heading = "nodiscard, warn_unused_result";
let Content = [{
Clang supports the ability to diagnose when the results of a function call
expression are discarded under suspicious circumstances. A diagnostic is
@@ -1312,7 +1383,7 @@ potentially-evaluated discarded-value expression that is not explicitly cast to
def FallthroughDocs : Documentation {
let Category = DocCatStmt;
- let Heading = "fallthrough, clang::fallthrough";
+ let Heading = "fallthrough";
let Content = [{
The ``fallthrough`` (or ``clang::fallthrough``) attribute is used
to annotate intentional fall-through
@@ -1460,7 +1531,7 @@ on the command line.
def MipsLongCallStyleDocs : Documentation {
let Category = DocCatFunction;
- let Heading = "long_call (gnu::long_call, gnu::far)";
+ let Heading = "long_call, far";
let Content = [{
Clang supports the ``__attribute__((long_call))``, ``__attribute__((far))``,
and ``__attribute__((near))`` attributes on MIPS targets. These attributes may
@@ -1481,7 +1552,7 @@ as ``-mlong-calls`` and ``-mno-long-calls``.
def MipsShortCallStyleDocs : Documentation {
let Category = DocCatFunction;
- let Heading = "short_call (gnu::short_call, gnu::near)";
+ let Heading = "short_call, near";
let Content = [{
Clang supports the ``__attribute__((long_call))``, ``__attribute__((far))``,
``__attribute__((short__call))``, and ``__attribute__((near))`` attributes
@@ -1738,6 +1809,31 @@ similar to ``stdcall`` on x86. Valid parameter values are "aapcs" and
}];
}
+def AArch64VectorPcsDocs : Documentation {
+ let Category = DocCatCallingConvs;
+ let Content = [{
+On AArch64 targets, this attribute changes the calling convention of a
+function to preserve additional floating-point and Advanced SIMD registers
+relative to the default calling convention used for AArch64.
+
+This means it is more efficient to call such functions from code that performs
+extensive floating-point and vector calculations, because fewer live SIMD and FP
+registers need to be saved. This property makes it well-suited for e.g.
+floating-point or vector math library functions, which are typically leaf
+functions that require a small number of registers.
+
+However, using this attribute also means that it is more expensive to call
+a function that adheres to the default calling convention from within such
+a function. Therefore, it is recommended that this attribute is only used
+for leaf functions.
+
+For more information, see the documentation for `aarch64_vector_pcs`_ on
+the Arm Developer website.
+
+.. _`aarch64_vector_pcs`: https://developer.arm.com/products/software-development-tools/hpc/arm-compiler-for-hpc/vector-function-abi
+ }];
+}
+
def RegparmDocs : Documentation {
let Category = DocCatCallingConvs;
let Content = [{
@@ -1940,7 +2036,7 @@ def NoSanitizeAddressDocs : Documentation {
let Category = DocCatFunction;
// This function has multiple distinct spellings, and so it requires a custom
// heading to be specified. The most common spelling is sufficient.
- let Heading = "no_sanitize_address (no_address_safety_analysis, gnu::no_address_safety_analysis, gnu::no_sanitize_address)";
+ let Heading = "no_sanitize_address, no_address_safety_analysis";
let Content = [{
.. _langext-address_sanitizer:
@@ -2497,10 +2593,10 @@ def LoopHintDocs : Documentation {
let Heading = "#pragma clang loop";
let Content = [{
The ``#pragma clang loop`` directive allows loop optimization hints to be
-specified for the subsequent loop. The directive allows vectorization,
-interleaving, and unrolling to be enabled or disabled. Vector width as well
-as interleave and unrolling count can be manually specified. See
-`language extensions
+specified for the subsequent loop. The directive allows pipelining to be
+disabled, or vectorization, interleaving, and unrolling to be enabled or disabled.
+Vector width, interleave count, unrolling count, and the initiation interval
+for pipelining can be explicitly specified. See `language extensions
<http://clang.llvm.org/docs/LanguageExtensions.html#extensions-for-loop-hint-optimizations>`_
for details.
}];
@@ -2561,9 +2657,58 @@ for further details including limitations of the unroll hints.
}];
}
+def PipelineHintDocs : Documentation {
+ let Category = DocCatStmt;
+ let Heading = "#pragma clang loop pipeline, #pragma clang loop pipeline_initiation_interval";
+ let Content = [{
+ Software Pipelining optimization is a technique used to optimize loops by
+ utilizing instruction-level parallelism. It reorders loop instructions to
+ overlap iterations. As a result, the next iteration starts before the previous
+ iteration has finished. The module scheduling technique creates a schedule for
+ one iteration such that when repeating at regular intervals, no inter-iteration
+ dependencies are violated. This constant interval(in cycles) between the start
+ of iterations is called the initiation interval. i.e. The initiation interval
+ is the number of cycles between two iterations of an unoptimized loop in the
+ newly created schedule. A new, optimized loop is created such that a single iteration
+ of the loop executes in the same number of cycles as the initiation interval.
+ For further details see <https://llvm.org/pubs/2005-06-17-LattnerMSThesis-book.pdf>.
+
+ ``#pragma clang loop pipeline and #pragma loop pipeline_initiation_interval``
+ could be used as hints for the software pipelining optimization. The pragma is
+ placed immediately before a for, while, do-while, or a C++11 range-based for
+ loop.
+
+ Using ``#pragma clang loop pipeline(disable)`` avoids the software pipelining
+ optimization. The disable state can only be specified:
+
+ .. code-block:: c++
+
+ #pragma clang loop pipeline(disable)
+ for (...) {
+ ...
+ }
+
+ Using ``#pragma loop pipeline_initiation_interval`` instructs
+ the software pipeliner to try the specified initiation interval.
+ If a schedule was found then the resulting loop iteration would have
+ the specified cycle count. If a schedule was not found then loop
+ remains unchanged. The initiation interval must be a positive number
+ greater than zero:
+
+ .. code-block:: c++
+
+ #pragma loop pipeline_initiation_interval(10)
+ for (...) {
+ ...
+ }
+
+ }];
+}
+
+
+
def OpenCLUnrollHintDocs : Documentation {
let Category = DocCatStmt;
- let Heading = "__attribute__((opencl_unroll_hint))";
let Content = [{
The opencl_unroll_hint attribute qualifier can be used to specify that a loop
(for, while and do loops) can be unrolled. This attribute qualifier can be
@@ -2576,7 +2721,6 @@ s6.11.5 for details.
def OpenCLIntelReqdSubGroupSizeDocs : Documentation {
let Category = DocCatStmt;
- let Heading = "__attribute__((intel_reqd_sub_group_size))";
let Content = [{
The optional attribute intel_reqd_sub_group_size can be used to indicate that
the kernel must be compiled and executed with the specified subgroup size. When
@@ -2973,6 +3117,68 @@ This can be used to contain the ABI of a C++ library by excluding unwanted class
}];
}
+def ExcludeFromExplicitInstantiationDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+The ``exclude_from_explicit_instantiation`` attribute opts-out a member of a
+class template from being part of explicit template instantiations of that
+class template. This means that an explicit instantiation will not instantiate
+members of the class template marked with the attribute, but also that code
+where an extern template declaration of the enclosing class template is visible
+will not take for granted that an external instantiation of the class template
+would provide those members (which would otherwise be a link error, since the
+explicit instantiation won't provide those members). For example, let's say we
+don't want the ``data()`` method to be part of libc++'s ABI. To make sure it
+is not exported from the dylib, we give it hidden visibility:
+
+ .. code-block:: c++
+
+ // in <string>
+ template <class CharT>
+ class basic_string {
+ public:
+ __attribute__((__visibility__("hidden")))
+ const value_type* data() const noexcept { ... }
+ };
+
+ template class basic_string<char>;
+
+Since an explicit template instantiation declaration for ``basic_string<char>``
+is provided, the compiler is free to assume that ``basic_string<char>::data()``
+will be provided by another translation unit, and it is free to produce an
+external call to this function. However, since ``data()`` has hidden visibility
+and the explicit template instantiation is provided in a shared library (as
+opposed to simply another translation unit), ``basic_string<char>::data()``
+won't be found and a link error will ensue. This happens because the compiler
+assumes that ``basic_string<char>::data()`` is part of the explicit template
+instantiation declaration, when it really isn't. To tell the compiler that
+``data()`` is not part of the explicit template instantiation declaration, the
+``exclude_from_explicit_instantiation`` attribute can be used:
+
+ .. code-block:: c++
+
+ // in <string>
+ template <class CharT>
+ class basic_string {
+ public:
+ __attribute__((__visibility__("hidden")))
+ __attribute__((exclude_from_explicit_instantiation))
+ const value_type* data() const noexcept { ... }
+ };
+
+ template class basic_string<char>;
+
+Now, the compiler won't assume that ``basic_string<char>::data()`` is provided
+externally despite there being an explicit template instantiation declaration:
+the compiler will implicitly instantiate ``basic_string<char>::data()`` in the
+TUs where it is used.
+
+This attribute can be used on static and non-static member functions of class
+templates, static data members of class templates and member classes of class
+templates.
+ }];
+}
+
def DisableTailCallsDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
@@ -3364,11 +3570,11 @@ def IFuncDocs : Documentation {
let Content = [{
``__attribute__((ifunc("resolver")))`` is used to mark that the address of a declaration should be resolved at runtime by calling a resolver function.
-The symbol name of the resolver function is given in quotes. A function with this name (after mangling) must be defined in the current translation unit; it may be ``static``. The resolver function should take no arguments and return a pointer.
+The symbol name of the resolver function is given in quotes. A function with this name (after mangling) must be defined in the current translation unit; it may be ``static``. The resolver function should return a pointer.
The ``ifunc`` attribute may only be used on a function declaration. A function declaration with an ``ifunc`` attribute is considered to be a definition of the declared entity. The entity must not have weak linkage; for example, in C++, it cannot be applied to a declaration if a definition at that location would be considered inline.
-Not all targets support this attribute. ELF targets support this attribute when using binutils v2.20.1 or higher and glibc v2.11.1 or higher. Non-ELF targets currently do not support this attribute.
+Not all targets support this attribute. ELF target support depends on both the linker and runtime linker, and is available in at least lld 4.0 and later, binutils 2.20.1 and later, glibc v2.11.1 and later, and FreeBSD 9.1 and later. Non-ELF targets currently do not support this attribute.
}];
}
@@ -3396,7 +3602,7 @@ See the RenderScript_ documentation for more information.
def XRayDocs : Documentation {
let Category = DocCatFunction;
- let Heading = "xray_always_instrument (clang::xray_always_instrument), xray_never_instrument (clang::xray_never_instrument), xray_log_args (clang::xray_log_args)";
+ let Heading = "xray_always_instrument, xray_never_instrument, xray_log_args";
let Content = [{
``__attribute__((xray_always_instrument))`` or ``[[clang::xray_always_instrument]]`` is used to mark member functions (in C++), methods (in Objective C), and free functions (in C, C++, and Objective C) to be instrumented with XRay. This will cause the function to always have space at the beginning and exit points to allow for runtime patching.
@@ -3458,3 +3664,206 @@ the resulting instructions with the call site, rather than with the
corresponding line within the inlined callee.
}];
}
+
+def NoDerefDocs : Documentation {
+ let Category = DocCatType;
+ let Content = [{
+The ``noderef`` attribute causes clang to diagnose dereferences of annotated pointer types.
+This is ideally used with pointers that point to special memory which cannot be read
+from or written to, but allowing for the pointer to be used in pointer arithmetic.
+The following are examples of valid expressions where dereferences are diagnosed:
+
+.. code-block:: c
+
+ int __attribute__((noderef)) *p;
+ int x = *p; // warning
+
+ int __attribute__((noderef)) **p2;
+ x = **p2; // warning
+
+ int * __attribute__((noderef)) *p3;
+ p = *p3; // warning
+
+ struct S {
+ int a;
+ };
+ struct S __attribute__((noderef)) *s;
+ x = s->a; // warning
+ x = (*s).a; // warning
+
+Not all dereferences may diagnose a warning if the value directed by the pointer may not be
+accessed. The following are examples of valid expressions where may not be diagnosed:
+
+.. code-block:: c
+
+ int *q;
+ int __attribute__((noderef)) *p;
+ q = &*p;
+ q = *&p;
+
+ struct S {
+ int a;
+ };
+ struct S __attribute__((noderef)) *s;
+ p = &s->a;
+ p = &(*s).a;
+
+``noderef`` is currently only supported for pointers and arrays and not usable for
+references or Objective-C object pointers.
+
+.. code-block: c++
+
+ int x = 2;
+ int __attribute__((noderef)) &y = x; // warning: 'noderef' can only be used on an array or pointer type
+
+.. code-block: objc
+
+ id __attribute__((noderef)) obj = [NSObject new]; // warning: 'noderef' can only be used on an array or pointer type
+}];
+}
+
+def ReinitializesDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+The ``reinitializes`` attribute can be applied to a non-static, non-const C++
+member function to indicate that this member function reinitializes the entire
+object to a known state, independent of the previous state of the object.
+
+This attribute can be interpreted by static analyzers that warn about uses of an
+object that has been left in an indeterminate state by a move operation. If a
+member function marked with the ``reinitializes`` attribute is called on a
+moved-from object, the analyzer can conclude that the object is no longer in an
+indeterminate state.
+
+A typical example where this attribute would be used is on functions that clear
+a container class:
+
+.. code-block:: c++
+
+ template <class T>
+ class Container {
+ public:
+ ...
+ [[clang::reinitializes]] void Clear();
+ ...
+ };
+ }];
+}
+
+def AlwaysDestroyDocs : Documentation {
+ let Category = DocCatVariable;
+ let Content = [{
+The ``always_destroy`` attribute specifies that a variable with static or thread
+storage duration should have its exit-time destructor run. This attribute is the
+default unless clang was invoked with -fno-c++-static-destructors.
+ }];
+}
+
+def NoDestroyDocs : Documentation {
+ let Category = DocCatVariable;
+ let Content = [{
+The ``no_destroy`` attribute specifies that a variable with static or thread
+storage duration shouldn't have its exit-time destructor run. Annotating every
+static and thread duration variable with this attribute is equivalent to
+invoking clang with -fno-c++-static-destructors.
+ }];
+}
+
+def UninitializedDocs : Documentation {
+ let Category = DocCatVariable;
+ let Content = [{
+The command-line parameter ``-ftrivial-auto-var-init=*`` can be used to
+initialize trivial automatic stack variables. By default, trivial automatic
+stack variables are uninitialized. This attribute is used to override the
+command-line parameter, forcing variables to remain uninitialized. It has no
+semantic meaning in that using uninitialized values is undefined behavior,
+it rather documents the programmer's intent.
+ }];
+}
+
+def GnuInlineDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+The ``gnu_inline`` changes the meaning of ``extern inline`` to use GNU inline
+semantics, meaning:
+
+* If any declaration that is declared ``inline`` is not declared ``extern``,
+then the ``inline`` keyword is just a hint. In particular, an out-of-line
+definition is still emitted for a function with external linkage, even if all
+call sites are inlined, unlike in C99 and C++ inline semantics.
+
+* If all declarations that are declared ``inline`` are also declared
+``extern``, then the function body is present only for inlining and no
+out-of-line version is emitted.
+
+Some important consequences: ``static inline`` emits an out-of-line
+version if needed, a plain ``inline`` definition emits an out-of-line version
+always, and an ``extern inline`` definition (in a header) followed by a
+(non-``extern``) ``inline`` declaration in a source file emits an out-of-line
+version of the function in that source file but provides the function body for
+inlining to all includers of the header.
+
+Either ``__GNUC_GNU_INLINE__`` (GNU inline semantics) or
+``__GNUC_STDC_INLINE__`` (C99 semantics) will be defined (they are mutually
+exclusive). If ``__GNUC_STDC_INLINE__`` is defined, then the ``gnu_inline``
+function attribute can be used to get GNU inline semantics on a per function
+basis. If ``__GNUC_GNU_INLINE__`` is defined, then the translation unit is
+already being compiled with GNU inline semantics as the implied default. It is
+unspecified which macro is defined in a C++ compilation.
+
+GNU inline semantics are the default behavior with ``-std=gnu89``,
+``-std=c89``, ``-std=c94``, or ``-fgnu89-inline``.
+ }];
+}
+
+def SpeculativeLoadHardeningDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+ This attribute can be applied to a function declaration in order to indicate
+ that `Speculative Load Hardening <https://llvm.org/docs/SpeculativeLoadHardening.html>`_
+ should be enabled for the function body. This can also be applied to a method
+ in Objective C.
+
+ Speculative Load Hardening is a best-effort mitigation against
+ information leak attacks that make use of control flow
+ miss-speculation - specifically miss-speculation of whether a branch
+ is taken or not. Typically vulnerabilities enabling such attacks are
+ classified as "Spectre variant #1". Notably, this does not attempt to
+ mitigate against miss-speculation of branch target, classified as
+ "Spectre variant #2" vulnerabilities.
+
+ When inlining, the attribute is sticky. Inlining a function that
+ carries this attribute will cause the caller to gain the
+ attribute. This is intended to provide a maximally conservative model
+ where the code in a function annotated with this attribute will always
+ (even after inlining) end up hardened.
+ }];
+}
+
+def ObjCExternallyRetainedDocs : Documentation {
+ let Category = DocCatVariable;
+ let Content = [{
+The ``objc_externally_retained`` attribute can be applied to strong local
+variables, functions, methods, or blocks to opt into
+`externally-retained semantics
+<https://clang.llvm.org/docs/AutomaticReferenceCounting.html#externally-retained-variables>`_.
+
+When applied to the definition of a function, method, or block, every parameter
+of the function with implicit strong retainable object pointer type is
+considered externally-retained, and becomes ``const``. By explicitly annotating
+a parameter with ``__strong``, you can opt back into the default
+non-externally-retained behaviour for that parameter. For instance,
+``first_param`` is externally-retained below, but not ``second_param``:
+
+.. code-block:: objc
+
+ __attribute__((objc_externally_retained))
+ void f(NSArray *first_param, __strong NSArray *second_param) {
+ // ...
+ }
+
+Likewise, when applied to a strong local variable, that variable becomes
+``const`` and is considered externally-retained.
+
+When compiled without ``-fobjc-arc``, this attribute is ignored.
+}]; }
diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def
index c4d11cd827c1..fa031ce09f6b 100644
--- a/include/clang/Basic/Builtins.def
+++ b/include/clang/Basic/Builtins.def
@@ -413,6 +413,9 @@ BUILTIN(__builtin_parityll, "iULLi", "nc")
BUILTIN(__builtin_popcount , "iUi" , "nc")
BUILTIN(__builtin_popcountl , "iULi" , "nc")
BUILTIN(__builtin_popcountll, "iULLi", "nc")
+BUILTIN(__builtin_clrsb , "ii" , "nc")
+BUILTIN(__builtin_clrsbl , "iLi" , "nc")
+BUILTIN(__builtin_clrsbll, "iLLi", "nc")
// FIXME: These type signatures are not correct for targets with int != 32-bits
// or with ULL != 64-bits.
@@ -425,6 +428,15 @@ BUILTIN(__builtin_bitreverse16, "UsUs", "nc")
BUILTIN(__builtin_bitreverse32, "UiUi", "nc")
BUILTIN(__builtin_bitreverse64, "ULLiULLi", "nc")
+BUILTIN(__builtin_rotateleft8, "UcUcUc", "nc")
+BUILTIN(__builtin_rotateleft16, "UsUsUs", "nc")
+BUILTIN(__builtin_rotateleft32, "UiUiUi", "nc")
+BUILTIN(__builtin_rotateleft64, "ULLiULLiULLi", "nc")
+BUILTIN(__builtin_rotateright8, "UcUcUc", "nc")
+BUILTIN(__builtin_rotateright16, "UsUsUs", "nc")
+BUILTIN(__builtin_rotateright32, "UiUiUi", "nc")
+BUILTIN(__builtin_rotateright64, "ULLiULLiULLi", "nc")
+
// Random GCC builtins
BUILTIN(__builtin_constant_p, "i.", "nctu")
BUILTIN(__builtin_classify_type, "i.", "nctu")
@@ -486,6 +498,7 @@ BUILTIN(__builtin_snprintf, "ic*zcC*.", "nFp:2:")
BUILTIN(__builtin_vsprintf, "ic*cC*a", "nFP:1:")
BUILTIN(__builtin_vsnprintf, "ic*zcC*a", "nFP:2:")
BUILTIN(__builtin_thread_pointer, "v*", "nc")
+BUILTIN(__builtin_launder, "v*v*", "nt")
// GCC exception builtins
BUILTIN(__builtin_eh_return, "vzv*", "r") // FIXME: Takes intptr_t, not size_t!
@@ -526,7 +539,7 @@ BUILTIN(__builtin_readcyclecounter, "ULLi", "n")
BUILTIN(__builtin_trap, "v", "nr")
BUILTIN(__builtin_debugtrap, "v", "n")
BUILTIN(__builtin_unreachable, "v", "nr")
-BUILTIN(__builtin_shufflevector, "v." , "nc")
+BUILTIN(__builtin_shufflevector, "v." , "nct")
BUILTIN(__builtin_convertvector, "v." , "nct")
BUILTIN(__builtin_alloca, "v*z" , "Fn")
BUILTIN(__builtin_alloca_with_align, "v*zIz", "Fn")
@@ -774,6 +787,7 @@ LANGBUILTIN(_InterlockedCompareExchange16, "ssD*ss", "n", ALL_MS_LANGUA
LANGBUILTIN(_InterlockedCompareExchange, "NiNiD*NiNi", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedCompareExchange64, "LLiLLiD*LLiLLi", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedCompareExchangePointer, "v*v*D*v*v*", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedCompareExchangePointer_nf, "v*v*D*v*v*", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedDecrement16, "ssD*", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedDecrement, "NiNiD*", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedExchange, "NiNiD*Ni", "n", ALL_MS_LANGUAGES)
@@ -805,20 +819,23 @@ LANGBUILTIN(_interlockedbittestandset_acq, "UcNiD*Ni", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_interlockedbittestandset_nf, "UcNiD*Ni", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_interlockedbittestandset_rel, "UcNiD*Ni", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__noop, "i.", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(__popcnt16, "UsUs", "nc", ALL_MS_LANGUAGES)
-LANGBUILTIN(__popcnt, "UiUi", "nc", ALL_MS_LANGUAGES)
-LANGBUILTIN(__popcnt64, "ULLiULLi", "nc", ALL_MS_LANGUAGES)
+LANGBUILTIN(__lzcnt16, "UsUs", "nc", ALL_MS_LANGUAGES)
+LANGBUILTIN(__lzcnt, "UiUi", "nc", ALL_MS_LANGUAGES)
+LANGBUILTIN(__lzcnt64, "UWiUWi", "nc", ALL_MS_LANGUAGES)
+LANGBUILTIN(__popcnt16, "UsUs", "nc", ALL_MS_LANGUAGES)
+LANGBUILTIN(__popcnt, "UiUi", "nc", ALL_MS_LANGUAGES)
+LANGBUILTIN(__popcnt64, "UWiUWi", "nc", ALL_MS_LANGUAGES)
LANGBUILTIN(_ReturnAddress, "v*", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_rotl8, "UcUcUc", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_rotl16, "UsUsUc", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_rotl, "UiUii", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_lrotl, "UNiUNii", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(_rotl64, "ULLiULLii", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_rotl64, "UWiUWii", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_rotr8, "UcUcUc", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_rotr16, "UsUsUc", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_rotr, "UiUii", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_lrotr, "UNiUNii", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(_rotr64, "ULLiULLii", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_rotr64, "UWiUWii", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__va_start, "vc**.", "nt", ALL_MS_LANGUAGES)
LANGBUILTIN(__fastfail, "vUi", "nr", ALL_MS_LANGUAGES)
@@ -1385,9 +1402,9 @@ BUILTIN(__builtin_subcl, "ULiULiCULiCULiCULi*", "n")
BUILTIN(__builtin_subcll, "ULLiULLiCULLiCULLiCULLi*", "n")
// Checked Arithmetic Builtins for Security.
-BUILTIN(__builtin_add_overflow, "v.", "nt")
-BUILTIN(__builtin_sub_overflow, "v.", "nt")
-BUILTIN(__builtin_mul_overflow, "v.", "nt")
+BUILTIN(__builtin_add_overflow, "b.", "nt")
+BUILTIN(__builtin_sub_overflow, "b.", "nt")
+BUILTIN(__builtin_mul_overflow, "b.", "nt")
BUILTIN(__builtin_uadd_overflow, "bUiCUiCUi*", "n")
BUILTIN(__builtin_uaddl_overflow, "bULiCULiCULi*", "n")
BUILTIN(__builtin_uaddll_overflow, "bULLiCULLiCULLi*", "n")
diff --git a/include/clang/Basic/BuiltinsAArch64.def b/include/clang/Basic/BuiltinsAArch64.def
index b5d971d0bc6e..1892ff11a31d 100644
--- a/include/clang/Basic/BuiltinsAArch64.def
+++ b/include/clang/Basic/BuiltinsAArch64.def
@@ -94,6 +94,7 @@ TARGET_HEADER_BUILTIN(_BitScanReverse, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LAN
TARGET_HEADER_BUILTIN(_BitScanForward64, "UcUNi*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_BitScanReverse64, "UcUNi*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAdd, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_InterlockedAnd64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_InterlockedDecrement64, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_InterlockedExchange64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
@@ -103,6 +104,110 @@ TARGET_HEADER_BUILTIN(_InterlockedIncrement64, "LLiLLiD*", "nh", "intrin.h"
TARGET_HEADER_BUILTIN(_InterlockedOr64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_InterlockedXor64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd_acq, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd_rel, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd_nf, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd8_acq, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd8_rel, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd8_nf, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd16_acq, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd16_rel, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd16_nf, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64_acq, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64_rel, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64_nf, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_InterlockedExchange8_acq, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange8_nf, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange8_rel, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange16_acq, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange16_nf, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange16_rel, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange_acq, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange_nf, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange_rel, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange64_acq, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange64_nf, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange64_rel, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange8_acq, "ccD*cc", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange8_nf, "ccD*cc", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange8_rel, "ccD*cc", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange16_acq, "ssD*ss", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange16_nf, "ssD*ss", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange16_rel, "ssD*ss", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange_acq, "LiLiD*LiLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange_nf, "LiLiD*LiLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange_rel, "LiLiD*LiLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange64_acq, "LLiLLiD*LLiLLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange64_nf, "LLiLLiD*LLiLLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange64_rel, "LLiLLiD*LLiLLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_InterlockedOr8_acq, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr8_nf, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr8_rel, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr16_acq, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr16_nf, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr16_rel, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr_acq, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr_nf, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr_rel, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr64_acq, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr64_nf, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr64_rel, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_InterlockedXor8_acq, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor8_nf, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor8_rel, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor16_acq, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor16_nf, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor16_rel, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor_acq, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor_nf, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor_rel, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor64_acq, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor64_nf, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor64_rel, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_InterlockedAnd8_acq, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd8_nf, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd8_rel, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd16_acq, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd16_nf, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd16_rel, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd_acq, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd_nf, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd_rel, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd64_acq, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd64_nf, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd64_rel, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_InterlockedIncrement16_acq, "ssD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedIncrement16_nf, "ssD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedIncrement16_rel, "ssD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedIncrement_acq, "LiLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedIncrement_nf, "LiLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedIncrement_rel, "LiLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedIncrement64_acq, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedIncrement64_nf, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedIncrement64_rel, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_InterlockedDecrement16_acq, "ssD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedDecrement16_nf, "ssD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedDecrement16_rel, "ssD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedDecrement_acq, "LiLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedDecrement_nf, "LiLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedDecrement_rel, "LiLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedDecrement64_acq, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedDecrement64_nf, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedDecrement64_rel, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_ReadWriteBarrier, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__getReg, "ULLii", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_ReadStatusReg, "ii", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_WriteStatusReg, "vii", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_AddressOfReturnAddress, "v*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+
#undef BUILTIN
#undef LANGBUILTIN
#undef TARGET_HEADER_BUILTIN
diff --git a/include/clang/Basic/BuiltinsAMDGPU.def b/include/clang/Basic/BuiltinsAMDGPU.def
index 4a447eb9f6a8..a25e45fe3fb8 100644
--- a/include/clang/Basic/BuiltinsAMDGPU.def
+++ b/include/clang/Basic/BuiltinsAMDGPU.def
@@ -21,9 +21,10 @@
// SI+ only builtins.
//===----------------------------------------------------------------------===//
-BUILTIN(__builtin_amdgcn_dispatch_ptr, "Uc*4", "nc")
-BUILTIN(__builtin_amdgcn_kernarg_segment_ptr, "Uc*4", "nc")
-BUILTIN(__builtin_amdgcn_implicitarg_ptr, "Uc*4", "nc")
+BUILTIN(__builtin_amdgcn_dispatch_ptr, "v*4", "nc")
+BUILTIN(__builtin_amdgcn_kernarg_segment_ptr, "v*4", "nc")
+BUILTIN(__builtin_amdgcn_implicitarg_ptr, "v*4", "nc")
+BUILTIN(__builtin_amdgcn_queue_ptr, "v*4", "nc")
BUILTIN(__builtin_amdgcn_workgroup_id_x, "Ui", "nc")
BUILTIN(__builtin_amdgcn_workgroup_id_y, "Ui", "nc")
@@ -45,6 +46,8 @@ BUILTIN(__builtin_amdgcn_s_barrier, "v", "n")
BUILTIN(__builtin_amdgcn_wave_barrier, "v", "n")
BUILTIN(__builtin_amdgcn_s_dcache_inv, "v", "n")
BUILTIN(__builtin_amdgcn_buffer_wbinvl1, "v", "n")
+
+// FIXME: Need to disallow constant address space.
BUILTIN(__builtin_amdgcn_div_scale, "dddbb*", "n")
BUILTIN(__builtin_amdgcn_div_scalef, "fffbb*", "n")
BUILTIN(__builtin_amdgcn_div_fmas, "ddddb", "nc")
@@ -93,9 +96,15 @@ BUILTIN(__builtin_amdgcn_ds_bpermute, "iii", "nc")
BUILTIN(__builtin_amdgcn_readfirstlane, "ii", "nc")
BUILTIN(__builtin_amdgcn_readlane, "iii", "nc")
BUILTIN(__builtin_amdgcn_fmed3f, "ffff", "nc")
-BUILTIN(__builtin_amdgcn_ds_faddf, "ff*fIiIiIb", "n")
-BUILTIN(__builtin_amdgcn_ds_fminf, "ff*fIiIiIb", "n")
-BUILTIN(__builtin_amdgcn_ds_fmaxf, "ff*fIiIiIb", "n")
+BUILTIN(__builtin_amdgcn_ds_faddf, "ff*3fIiIiIb", "n")
+BUILTIN(__builtin_amdgcn_ds_fminf, "ff*3fIiIiIb", "n")
+BUILTIN(__builtin_amdgcn_ds_fmaxf, "ff*3fIiIiIb", "n")
+
+//===----------------------------------------------------------------------===//
+// CI+ only builtins.
+//===----------------------------------------------------------------------===//
+TARGET_BUILTIN(__builtin_amdgcn_s_dcache_inv_vol, "v", "n", "ci-insts")
+TARGET_BUILTIN(__builtin_amdgcn_buffer_wbinvl1_vol, "v", "n", "ci-insts")
//===----------------------------------------------------------------------===//
// VI+ only builtins.
@@ -113,6 +122,8 @@ TARGET_BUILTIN(__builtin_amdgcn_fracth, "hh", "nc", "16-bit-insts")
TARGET_BUILTIN(__builtin_amdgcn_classh, "bhi", "nc", "16-bit-insts")
TARGET_BUILTIN(__builtin_amdgcn_s_memrealtime, "LUi", "n", "s-memrealtime")
TARGET_BUILTIN(__builtin_amdgcn_mov_dpp, "iiIiIiIiIb", "nc", "dpp")
+TARGET_BUILTIN(__builtin_amdgcn_update_dpp, "iiiIiIiIiIb", "nc", "dpp")
+TARGET_BUILTIN(__builtin_amdgcn_s_dcache_wb, "v", "n", "vi-insts")
//===----------------------------------------------------------------------===//
// GFX9+ only builtins.
@@ -124,13 +135,13 @@ TARGET_BUILTIN(__builtin_amdgcn_fmed3h, "hhhh", "nc", "gfx9-insts")
// Deep learning builtins.
//===----------------------------------------------------------------------===//
-TARGET_BUILTIN(__builtin_amdgcn_fdot2, "fV2hV2hfIb", "nc", "dl-insts")
-TARGET_BUILTIN(__builtin_amdgcn_sdot2, "SiV2SsV2SsSiIb", "nc", "dl-insts")
-TARGET_BUILTIN(__builtin_amdgcn_udot2, "UiV2UsV2UsUiIb", "nc", "dl-insts")
-TARGET_BUILTIN(__builtin_amdgcn_sdot4, "SiSiSiSiIb", "nc", "dl-insts")
-TARGET_BUILTIN(__builtin_amdgcn_udot4, "UiUiUiUiIb", "nc", "dl-insts")
-TARGET_BUILTIN(__builtin_amdgcn_sdot8, "SiSiSiSiIb", "nc", "dl-insts")
-TARGET_BUILTIN(__builtin_amdgcn_udot8, "UiUiUiUiIb", "nc", "dl-insts")
+TARGET_BUILTIN(__builtin_amdgcn_fdot2, "fV2hV2hfIb", "nc", "dot-insts")
+TARGET_BUILTIN(__builtin_amdgcn_sdot2, "SiV2SsV2SsSiIb", "nc", "dot-insts")
+TARGET_BUILTIN(__builtin_amdgcn_udot2, "UiV2UsV2UsUiIb", "nc", "dot-insts")
+TARGET_BUILTIN(__builtin_amdgcn_sdot4, "SiSiSiSiIb", "nc", "dot-insts")
+TARGET_BUILTIN(__builtin_amdgcn_udot4, "UiUiUiUiIb", "nc", "dot-insts")
+TARGET_BUILTIN(__builtin_amdgcn_sdot8, "SiSiSiSiIb", "nc", "dot-insts")
+TARGET_BUILTIN(__builtin_amdgcn_udot8, "UiUiUiUiIb", "nc", "dot-insts")
//===----------------------------------------------------------------------===//
// Special builtins.
diff --git a/include/clang/Basic/BuiltinsARM.def b/include/clang/Basic/BuiltinsARM.def
index 941d320d729f..ad778527b212 100644
--- a/include/clang/Basic/BuiltinsARM.def
+++ b/include/clang/Basic/BuiltinsARM.def
@@ -230,6 +230,104 @@ TARGET_HEADER_BUILTIN(_InterlockedIncrement64, "LLiLLiD*", "nh", "intrin.h"
TARGET_HEADER_BUILTIN(_InterlockedOr64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_InterlockedXor64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd_acq, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd_rel, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd_nf, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd8_acq, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd8_rel, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd8_nf, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd16_acq, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd16_rel, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd16_nf, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64_acq, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64_rel, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64_nf, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_InterlockedExchange8_acq, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange8_nf, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange8_rel, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange16_acq, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange16_nf, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange16_rel, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange_acq, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange_nf, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange_rel, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange64_acq, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange64_nf, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange64_rel, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange8_acq, "ccD*cc", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange8_nf, "ccD*cc", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange8_rel, "ccD*cc", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange16_acq, "ssD*ss", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange16_nf, "ssD*ss", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange16_rel, "ssD*ss", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange_acq, "LiLiD*LiLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange_nf, "LiLiD*LiLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange_rel, "LiLiD*LiLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange64_acq, "LLiLLiD*LLiLLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange64_nf, "LLiLLiD*LLiLLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange64_rel, "LLiLLiD*LLiLLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_InterlockedOr8_acq, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr8_nf, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr8_rel, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr16_acq, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr16_nf, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr16_rel, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr_acq, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr_nf, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr_rel, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr64_acq, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr64_nf, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr64_rel, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_InterlockedXor8_acq, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor8_nf, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor8_rel, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor16_acq, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor16_nf, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor16_rel, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor_acq, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor_nf, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor_rel, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor64_acq, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor64_nf, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor64_rel, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_InterlockedAnd8_acq, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd8_nf, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd8_rel, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd16_acq, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd16_nf, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd16_rel, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd_acq, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd_nf, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd_rel, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd64_acq, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd64_nf, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd64_rel, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_InterlockedIncrement16_acq, "ssD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedIncrement16_nf, "ssD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedIncrement16_rel, "ssD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedIncrement_acq, "LiLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedIncrement_nf, "LiLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedIncrement_rel, "LiLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedIncrement64_acq, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedIncrement64_nf, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedIncrement64_rel, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_InterlockedDecrement16_acq, "ssD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedDecrement16_nf, "ssD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedDecrement16_rel, "ssD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedDecrement_acq, "LiLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedDecrement_nf, "LiLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedDecrement_rel, "LiLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedDecrement64_acq, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedDecrement64_nf, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedDecrement64_rel, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+
#undef BUILTIN
#undef LANGBUILTIN
#undef TARGET_HEADER_BUILTIN
diff --git a/include/clang/Basic/BuiltinsHexagon.def b/include/clang/Basic/BuiltinsHexagon.def
index f976720d116d..bb040c06fd07 100644
--- a/include/clang/Basic/BuiltinsHexagon.def
+++ b/include/clang/Basic/BuiltinsHexagon.def
@@ -63,1676 +63,1756 @@ BUILTIN(__builtin_HEXAGON_S2_storerf_pcr, "vv*iivC*", "")
BUILTIN(__builtin_HEXAGON_S2_storeri_pcr, "vv*iivC*", "")
BUILTIN(__builtin_HEXAGON_S2_storerd_pcr, "vv*iLLivC*", "")
-// The builtins above are not autogenerated from iset.py.
-// Make sure you do not overwrite these.
+BUILTIN(__builtin_HEXAGON_prefetch,"vv*","")
+BUILTIN(__builtin_HEXAGON_Y2_dccleana,"vv*","")
+BUILTIN(__builtin_HEXAGON_Y2_dccleaninva,"vv*","")
+BUILTIN(__builtin_HEXAGON_Y2_dcinva,"vv*","")
+BUILTIN(__builtin_HEXAGON_Y2_dczeroa,"vv*","")
+BUILTIN(__builtin_HEXAGON_Y4_l2fetch,"vv*Ui","")
+BUILTIN(__builtin_HEXAGON_Y5_l2fetch,"vv*LLUi","")
-BUILTIN(__builtin_HEXAGON_C2_cmpeq,"iii","")
-BUILTIN(__builtin_HEXAGON_C2_cmpgt,"iii","")
+BUILTIN(__builtin_HEXAGON_V6_vS32b_qpred_ai,"vV16iv*V16i","")
+BUILTIN(__builtin_HEXAGON_V6_vS32b_nqpred_ai,"vV16iv*V16i","")
+BUILTIN(__builtin_HEXAGON_V6_vS32b_nt_qpred_ai,"vV16iv*V16i","")
+BUILTIN(__builtin_HEXAGON_V6_vS32b_nt_nqpred_ai,"vV16iv*V16i","")
+BUILTIN(__builtin_HEXAGON_V6_vS32b_qpred_ai_128B,"vV32iv*V32i","")
+BUILTIN(__builtin_HEXAGON_V6_vS32b_nqpred_ai_128B,"vV32iv*V32i","")
+BUILTIN(__builtin_HEXAGON_V6_vS32b_nt_qpred_ai_128B,"vV32iv*V32i","")
+BUILTIN(__builtin_HEXAGON_V6_vS32b_nt_nqpred_ai_128B,"vV32iv*V32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmaskedstoreq,"vV16iv*V16i","")
+BUILTIN(__builtin_HEXAGON_V6_vmaskedstorenq,"vV16iv*V16i","")
+BUILTIN(__builtin_HEXAGON_V6_vmaskedstorentq,"vV16iv*V16i","")
+BUILTIN(__builtin_HEXAGON_V6_vmaskedstorentnq,"vV16iv*V16i","")
+BUILTIN(__builtin_HEXAGON_V6_vmaskedstoreq_128B,"vV32iv*V32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmaskedstorenq_128B,"vV32iv*V32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmaskedstorentq_128B,"vV32iv*V32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmaskedstorentnq_128B,"vV32iv*V32i","")
+
+BUILTIN(__builtin_HEXAGON_V6_vgathermw,"vv*iiV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vgathermw_128B,"vv*iiV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vgathermh,"vv*iiV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vgathermh_128B,"vv*iiV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vgathermhw,"vv*iiV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vgathermhw_128B,"vv*iiV64i","")
+BUILTIN(__builtin_HEXAGON_V6_vgathermwq,"vv*V16iiiV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vgathermwq_128B,"vv*V32iiiV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vgathermhq,"vv*V16iiiV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vgathermhq_128B,"vv*V32iiiV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vgathermhwq,"vv*V16iiiV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vgathermhwq_128B,"vv*V32iiiV64i","")
+BUILTIN(__builtin_HEXAGON_V6_vscattermw,"viiV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vscattermw_128B,"viiV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vscattermh,"viiV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vscattermh_128B,"viiV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vscattermw_add,"viiV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vscattermw_add_128B,"viiV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vscattermh_add,"viiV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vscattermh_add_128B,"viiV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vscattermwq,"vV16iiiV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vscattermwq_128B,"vV32iiiV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vscattermhq,"vV16iiiV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vscattermhq_128B,"vV32iiiV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vscattermhw,"viiV32iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vscattermhw_128B,"viiV64iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vscattermhwq,"vV16iiiV32iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vscattermhwq_128B,"vV32iiiV64iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vscattermhw_add,"viiV32iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vscattermhw_add_128B,"viiV64iV32i","")
+
+// ---------------------------------------------------------------------
+// Auto-generated definitions.
+
+// V5 Scalar Instructions.
+
+BUILTIN(__builtin_HEXAGON_S2_asr_r_p_or,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_vsatwh,"iLLi","")
+BUILTIN(__builtin_HEXAGON_S2_tableidxd_goodsyntax,"iiiUIiUIi","")
+BUILTIN(__builtin_HEXAGON_M2_mpysu_up,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_ll_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_ll_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_cmpysc_s1,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_cmpysc_s0,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M4_cmpyi_whc,"iLLii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_lh_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_lh_s0,"iii","")
+BUILTIN(__builtin_HEXAGON_S2_tableidxb_goodsyntax,"iiiUIiUIi","")
+BUILTIN(__builtin_HEXAGON_S2_shuffoh,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_F2_sfmax,"fff","")
+BUILTIN(__builtin_HEXAGON_A2_vabswsat,"LLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_asr_i_r,"iiUIi","")
+BUILTIN(__builtin_HEXAGON_S2_asr_i_p,"LLiLLiUIi","")
+BUILTIN(__builtin_HEXAGON_A4_combineri,"LLiiIi","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_hl_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M4_vpmpyh_acc,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_vcmpy_s0_sat_i,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_notp,"LLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_hl_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_hl_s0,"iii","")
+BUILTIN(__builtin_HEXAGON_C4_or_and,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_vmac2s_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_vmac2s_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_S2_brevp,"LLiLLi","")
+BUILTIN(__builtin_HEXAGON_M4_pmpyw_acc,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_S2_cl1,"ii","")
+BUILTIN(__builtin_HEXAGON_C4_cmplte,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mmpyul_s0,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vaddws,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_maxup,"ULLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A4_vcmphgti,"iLLiIi","")
+BUILTIN(__builtin_HEXAGON_S2_interleave,"LLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vrcmpyi_s0,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_abssat,"ii","")
+BUILTIN(__builtin_HEXAGON_A2_vcmpwgtu,"iLLiLLi","")
BUILTIN(__builtin_HEXAGON_C2_cmpgtu,"iii","")
-BUILTIN(__builtin_HEXAGON_C2_cmpeqp,"iLLiLLi","")
BUILTIN(__builtin_HEXAGON_C2_cmpgtp,"iLLiLLi","")
-BUILTIN(__builtin_HEXAGON_C2_cmpgtup,"iLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A4_rcmpeqi,"iii","")
-BUILTIN(__builtin_HEXAGON_A4_rcmpneqi,"iii","")
-BUILTIN(__builtin_HEXAGON_A4_rcmpeq,"iii","")
-BUILTIN(__builtin_HEXAGON_A4_rcmpneq,"iii","")
-BUILTIN(__builtin_HEXAGON_C2_bitsset,"iii","")
-BUILTIN(__builtin_HEXAGON_C2_bitsclr,"iii","")
-BUILTIN(__builtin_HEXAGON_C4_nbitsset,"iii","")
-BUILTIN(__builtin_HEXAGON_C4_nbitsclr,"iii","")
-BUILTIN(__builtin_HEXAGON_C2_cmpeqi,"iii","")
-BUILTIN(__builtin_HEXAGON_C2_cmpgti,"iii","")
-BUILTIN(__builtin_HEXAGON_C2_cmpgtui,"iii","")
-BUILTIN(__builtin_HEXAGON_C2_cmpgei,"iii","")
-BUILTIN(__builtin_HEXAGON_C2_cmpgeui,"iii","")
-BUILTIN(__builtin_HEXAGON_C2_cmplt,"iii","")
-BUILTIN(__builtin_HEXAGON_C2_cmpltu,"iii","")
-BUILTIN(__builtin_HEXAGON_C2_bitsclri,"iii","")
-BUILTIN(__builtin_HEXAGON_C4_nbitsclri,"iii","")
-BUILTIN(__builtin_HEXAGON_C4_cmpneqi,"iii","")
-BUILTIN(__builtin_HEXAGON_C4_cmpltei,"iii","")
-BUILTIN(__builtin_HEXAGON_C4_cmplteui,"iii","")
-BUILTIN(__builtin_HEXAGON_C4_cmpneq,"iii","")
-BUILTIN(__builtin_HEXAGON_C4_cmplte,"iii","")
-BUILTIN(__builtin_HEXAGON_C4_cmplteu,"iii","")
-BUILTIN(__builtin_HEXAGON_C2_and,"iii","")
-BUILTIN(__builtin_HEXAGON_C2_or,"iii","")
-BUILTIN(__builtin_HEXAGON_C2_xor,"iii","")
-BUILTIN(__builtin_HEXAGON_C2_andn,"iii","")
+BUILTIN(__builtin_HEXAGON_A4_cmphgtui,"iiUIi","")
+BUILTIN(__builtin_HEXAGON_C2_cmpgti,"iiIi","")
+BUILTIN(__builtin_HEXAGON_M2_mpyi,"iii","")
+BUILTIN(__builtin_HEXAGON_F2_conv_df2uw_chop,"id","")
+BUILTIN(__builtin_HEXAGON_A4_cmpheq,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_lh_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_lh_s0,"iii","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_i_r_xacc,"iiiUIi","")
+BUILTIN(__builtin_HEXAGON_S2_vrcnegh,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_extractup,"LLiLLiUIiUIi","")
+BUILTIN(__builtin_HEXAGON_S2_asr_i_p_rnd_goodsyntax,"LLiLLiUIi","")
+BUILTIN(__builtin_HEXAGON_S4_ntstbit_r,"iii","")
+BUILTIN(__builtin_HEXAGON_F2_conv_w2sf,"fi","")
BUILTIN(__builtin_HEXAGON_C2_not,"ii","")
-BUILTIN(__builtin_HEXAGON_C2_orn,"iii","")
-BUILTIN(__builtin_HEXAGON_C4_and_and,"iiii","")
-BUILTIN(__builtin_HEXAGON_C4_and_or,"iiii","")
-BUILTIN(__builtin_HEXAGON_C4_or_and,"iiii","")
-BUILTIN(__builtin_HEXAGON_C4_or_or,"iiii","")
-BUILTIN(__builtin_HEXAGON_C4_and_andn,"iiii","")
-BUILTIN(__builtin_HEXAGON_C4_and_orn,"iiii","")
-BUILTIN(__builtin_HEXAGON_C4_or_andn,"iiii","")
-BUILTIN(__builtin_HEXAGON_C4_or_orn,"iiii","")
-BUILTIN(__builtin_HEXAGON_C2_pxfer_map,"ii","")
-BUILTIN(__builtin_HEXAGON_C2_any8,"ii","")
-BUILTIN(__builtin_HEXAGON_C2_all8,"ii","")
-BUILTIN(__builtin_HEXAGON_C2_vitpack,"iii","")
-BUILTIN(__builtin_HEXAGON_C2_mux,"iiii","")
-BUILTIN(__builtin_HEXAGON_C2_muxii,"iiii","")
-BUILTIN(__builtin_HEXAGON_C2_muxir,"iiii","")
-BUILTIN(__builtin_HEXAGON_C2_muxri,"iiii","")
-BUILTIN(__builtin_HEXAGON_C2_vmux,"LLiiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_C2_mask,"LLii","")
-BUILTIN(__builtin_HEXAGON_A2_vcmpbeq,"iLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A4_vcmpbeqi,"iLLii","")
-BUILTIN(__builtin_HEXAGON_A4_vcmpbeq_any,"iLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vcmpbgtu,"iLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A4_vcmpbgtui,"iLLii","")
-BUILTIN(__builtin_HEXAGON_A4_vcmpbgt,"iLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A4_vcmpbgti,"iLLii","")
-BUILTIN(__builtin_HEXAGON_A4_cmpbeq,"iii","")
-BUILTIN(__builtin_HEXAGON_A4_cmpbeqi,"iii","")
-BUILTIN(__builtin_HEXAGON_A4_cmpbgtu,"iii","")
-BUILTIN(__builtin_HEXAGON_A4_cmpbgtui,"iii","")
+BUILTIN(__builtin_HEXAGON_C2_tfrpr,"ii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_ll_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_ll_s0,"iii","")
BUILTIN(__builtin_HEXAGON_A4_cmpbgt,"iii","")
-BUILTIN(__builtin_HEXAGON_A4_cmpbgti,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_vcmpheq,"iLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vcmphgt,"iLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vcmphgtu,"iLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A4_vcmpheqi,"iLLii","")
-BUILTIN(__builtin_HEXAGON_A4_vcmphgti,"iLLii","")
-BUILTIN(__builtin_HEXAGON_A4_vcmphgtui,"iLLii","")
-BUILTIN(__builtin_HEXAGON_A4_cmpheq,"iii","")
-BUILTIN(__builtin_HEXAGON_A4_cmphgt,"iii","")
-BUILTIN(__builtin_HEXAGON_A4_cmphgtu,"iii","")
-BUILTIN(__builtin_HEXAGON_A4_cmpheqi,"iii","")
-BUILTIN(__builtin_HEXAGON_A4_cmphgti,"iii","")
-BUILTIN(__builtin_HEXAGON_A4_cmphgtui,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_vcmpweq,"iLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vcmpwgt,"iLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vcmpwgtu,"iLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A4_vcmpweqi,"iLLii","")
-BUILTIN(__builtin_HEXAGON_A4_vcmpwgti,"iLLii","")
-BUILTIN(__builtin_HEXAGON_A4_vcmpwgtui,"iLLii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_r_r_and,"iiii","")
+BUILTIN(__builtin_HEXAGON_A4_rcmpneqi,"iiIi","")
+BUILTIN(__builtin_HEXAGON_S2_asl_i_r_nac,"iiiUIi","")
+BUILTIN(__builtin_HEXAGON_M2_subacc,"iiii","")
+BUILTIN(__builtin_HEXAGON_A2_orp,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_up,"Uiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_lh_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_i_vh,"LLiLLiUIi","")
+BUILTIN(__builtin_HEXAGON_S2_asr_i_vw,"LLiLLiUIi","")
+BUILTIN(__builtin_HEXAGON_A4_cmpbgtu,"iii","")
+BUILTIN(__builtin_HEXAGON_A4_vcmpbeq_any,"iLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A4_cmpbgti,"iiIi","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_lh_s1,"LLiii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_r_p_nac,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_i_r_nac,"iiiUIi","")
+BUILTIN(__builtin_HEXAGON_A2_addsp,"LLiiLLi","")
+BUILTIN(__builtin_HEXAGON_S4_vxsubaddw,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A4_vcmpheqi,"iLLiIi","")
+BUILTIN(__builtin_HEXAGON_S4_vxsubaddh,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M4_pmpyw,"LLiii","")
+BUILTIN(__builtin_HEXAGON_S2_vsathb,"iLLi","")
+BUILTIN(__builtin_HEXAGON_S2_asr_r_p_and,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_lh_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_lh_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_lsl_r_p_acc,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_A2_pxorf,"iiii","")
+BUILTIN(__builtin_HEXAGON_C2_cmpgei,"iiIi","")
+BUILTIN(__builtin_HEXAGON_A2_vsubub,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_asl_i_p,"LLiLLiUIi","")
+BUILTIN(__builtin_HEXAGON_S2_asl_i_r,"iiUIi","")
+BUILTIN(__builtin_HEXAGON_A4_vrminuw,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_F2_sffma,"ffff","")
+BUILTIN(__builtin_HEXAGON_A2_absp,"LLiLLi","")
+BUILTIN(__builtin_HEXAGON_C2_all8,"ii","")
+BUILTIN(__builtin_HEXAGON_A4_vrminuh,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_F2_sffma_lib,"ffff","")
+BUILTIN(__builtin_HEXAGON_M4_vrmpyoh_s0,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M4_vrmpyoh_s1,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_C2_bitsset,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpysip,"iiUIi","")
+BUILTIN(__builtin_HEXAGON_M2_mpysin,"iiUIi","")
BUILTIN(__builtin_HEXAGON_A4_boundscheck,"iiLLi","")
-BUILTIN(__builtin_HEXAGON_A4_tlbmatch,"iLLii","")
-BUILTIN(__builtin_HEXAGON_C2_tfrpr,"ii","")
-BUILTIN(__builtin_HEXAGON_C2_tfrrp,"ii","")
+BUILTIN(__builtin_HEXAGON_M5_vrmpybuu,"LLiLLiLLi","")
BUILTIN(__builtin_HEXAGON_C4_fastcorner9,"iii","")
-BUILTIN(__builtin_HEXAGON_C4_fastcorner9_not,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_acc_hh_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_acc_hh_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_acc_hl_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_acc_hl_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_acc_lh_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_acc_lh_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_acc_ll_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_acc_ll_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_nac_hh_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_nac_hh_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_nac_hl_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_nac_hl_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_nac_lh_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_nac_lh_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_nac_ll_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_nac_ll_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_hh_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_hh_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_hl_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_hl_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_lh_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_lh_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_ll_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_ll_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_hh_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_hh_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_vrcmpys_s1rp,"iLLii","")
+BUILTIN(__builtin_HEXAGON_A2_neg,"ii","")
+BUILTIN(__builtin_HEXAGON_A2_subsat,"iii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_r_r,"iii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_r_p,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_A2_vnavgh,"LLiLLiLLi","")
BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_hl_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_hl_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_lh_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_lh_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_ll_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_ll_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_hh_s0,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_hh_s1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_hl_s0,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_hl_s1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_lh_s0,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_lh_s1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_ll_s0,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_ll_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_F2_conv_ud2df,"dLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vnavgw,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_asl_i_r_acc,"iiiUIi","")
+BUILTIN(__builtin_HEXAGON_S4_subi_lsr_ri,"iUIiiUIi","")
+BUILTIN(__builtin_HEXAGON_S2_vzxthw,"LLii","")
+BUILTIN(__builtin_HEXAGON_F2_sfadd,"fff","")
+BUILTIN(__builtin_HEXAGON_A2_sub,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_vmac2su_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_vmac2su_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_dpmpyss_s0,"LLiii","")
+BUILTIN(__builtin_HEXAGON_S2_insert,"iiiUIiUIi","")
+BUILTIN(__builtin_HEXAGON_S2_packhl,"LLiii","")
+BUILTIN(__builtin_HEXAGON_A4_vcmpwgti,"iLLiIi","")
+BUILTIN(__builtin_HEXAGON_A2_vavguwr,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_asl_r_r_and,"iiii","")
+BUILTIN(__builtin_HEXAGON_A2_svsubhs,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_addh_l16_hl,"iii","")
+BUILTIN(__builtin_HEXAGON_M4_and_and,"iiii","")
+BUILTIN(__builtin_HEXAGON_F2_conv_d2df,"dLLi","")
+BUILTIN(__builtin_HEXAGON_C2_cmpgtui,"iiUIi","")
+BUILTIN(__builtin_HEXAGON_A2_vconj,"LLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_r_vw,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_r_vh,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_A2_subh_l16_hl,"iii","")
+BUILTIN(__builtin_HEXAGON_S4_vxsubaddhr,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_clbp,"iLLi","")
+BUILTIN(__builtin_HEXAGON_S2_deinterleave,"LLiLLi","")
+BUILTIN(__builtin_HEXAGON_C2_any8,"ii","")
+BUILTIN(__builtin_HEXAGON_S2_togglebit_r,"iii","")
+BUILTIN(__builtin_HEXAGON_S2_togglebit_i,"iiUIi","")
+BUILTIN(__builtin_HEXAGON_F2_conv_uw2sf,"fi","")
+BUILTIN(__builtin_HEXAGON_S2_vsathb_nopack,"LLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_cmacs_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_cmacs_s1,"LLiLLiii","")
BUILTIN(__builtin_HEXAGON_M2_mpy_sat_hh_s0,"iii","")
BUILTIN(__builtin_HEXAGON_M2_mpy_sat_hh_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mmacuhs_s1,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmacuhs_s0,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_clrbit_r,"iii","")
+BUILTIN(__builtin_HEXAGON_C4_or_andn,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_r_r_nac,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_i_p_acc,"LLiLLiLLiUIi","")
+BUILTIN(__builtin_HEXAGON_A4_vcmpwgtui,"iLLiUIi","")
+BUILTIN(__builtin_HEXAGON_M4_vrmpyoh_acc_s0,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M4_vrmpyoh_acc_s1,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A4_vrmaxh,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_A2_vcmpbeq,"iLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vcmphgt,"iLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vnavgwcr,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vrcmacr_s0c,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vavgwcr,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_asl_i_p_xacc,"LLiLLiLLiUIi","")
+BUILTIN(__builtin_HEXAGON_A4_vrmaxw,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_A2_vnavghr,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M4_cmpyi_wh,"iLLii","")
+BUILTIN(__builtin_HEXAGON_A2_tfrsi,"iIi","")
+BUILTIN(__builtin_HEXAGON_S2_asr_i_r_acc,"iiiUIi","")
+BUILTIN(__builtin_HEXAGON_A2_svnavgh,"iii","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_i_r,"iiUIi","")
+BUILTIN(__builtin_HEXAGON_M2_vmac2,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_A4_vcmphgtui,"iLLiUIi","")
+BUILTIN(__builtin_HEXAGON_A2_svavgh,"iii","")
+BUILTIN(__builtin_HEXAGON_M4_vrmpyeh_acc_s0,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M4_vrmpyeh_acc_s1,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_i_p,"LLiLLiUIi","")
+BUILTIN(__builtin_HEXAGON_A2_combine_hl,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_up,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_combine_hh,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_negsat,"ii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_hl_s0,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_hl_s1,"LLiii","")
+BUILTIN(__builtin_HEXAGON_A4_bitsplit,"LLiii","")
+BUILTIN(__builtin_HEXAGON_A2_vabshsat,"LLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mpyui,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_addh_l16_sat_ll,"iii","")
+BUILTIN(__builtin_HEXAGON_S2_lsl_r_r_and,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mmpyul_rs0,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_asr_i_r_rnd_goodsyntax,"iiUIi","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_r_p_nac,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_C2_cmplt,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_cmacr_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M4_or_and,"iiii","")
+BUILTIN(__builtin_HEXAGON_M4_mpyrr_addi,"iUIiii","")
+BUILTIN(__builtin_HEXAGON_S4_or_andi,"iiiIi","")
BUILTIN(__builtin_HEXAGON_M2_mpy_sat_hl_s0,"iii","")
BUILTIN(__builtin_HEXAGON_M2_mpy_sat_hl_s1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_sat_lh_s0,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_sat_lh_s1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_sat_ll_s0,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_sat_ll_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_M4_mpyrr_addr,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mmachs_rs0,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmachs_rs1,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vrcmpyr_s0c,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_hl_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_ll_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_F2_sffixupn,"fff","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_lh_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_lh_s1,"LLiLLiii","")
BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_hh_s0,"iii","")
BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_hh_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_vadduhs,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vsubuhs,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_subh_h16_hl,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_subh_h16_hh,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_xorp,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A4_tfrpcp,"LLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_addh_h16_lh,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_addh_h16_sat_hl,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_addh_h16_ll,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_addh_h16_sat_hh,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_zxtb,"ii","")
+BUILTIN(__builtin_HEXAGON_A2_zxth,"ii","")
+BUILTIN(__builtin_HEXAGON_A2_vnavgwr,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M4_or_xor,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_hh_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_hh_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M5_vmacbsu,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_dpmpyuu_acc_s0,"LLiLLiii","")
BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_hl_s0,"iii","")
BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_hl_s1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_lh_s0,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_lh_s1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_ll_s0,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_ll_s1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_hh_s0,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_hh_s1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_hl_s0,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_hl_s1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_lh_s0,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_lh_s1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_ll_s0,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_ll_s1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_hh_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_hh_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_hl_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_hl_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_lh_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_lh_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_ll_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_ll_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_hh_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_hh_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_hl_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_hl_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_lh_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_F2_sffms_lib,"ffff","")
+BUILTIN(__builtin_HEXAGON_C4_cmpneqi,"iiIi","")
+BUILTIN(__builtin_HEXAGON_M4_and_xor,"iiii","")
+BUILTIN(__builtin_HEXAGON_A2_sat,"iLLi","")
BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_lh_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_ll_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_ll_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_hh_s0,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_hh_s1,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_hl_s0,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_hl_s1,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_lh_s0,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_lh_s1,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_ll_s0,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_ll_s1,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_hh_s0,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_hh_s1,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_hl_s0,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_hl_s1,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_lh_s0,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_lh_s1,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_ll_s0,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_ll_s1,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_hh_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_hh_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_hl_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_hl_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_lh_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_lh_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_ll_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_ll_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_hh_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_hh_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_hl_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_hl_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_lh_s0,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_lh_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_lh_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_A2_addsat,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_svavghs,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_vrsadub_acc,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_C2_bitsclri,"iiUIi","")
+BUILTIN(__builtin_HEXAGON_A2_subh_h16_sat_hh,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_subh_h16_sat_hl,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mmaculs_rs0,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmaculs_rs1,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vradduh,"iLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A4_addp_c,"LLiLLiLLiv*","")
+BUILTIN(__builtin_HEXAGON_C2_xor,"iii","")
+BUILTIN(__builtin_HEXAGON_S2_lsl_r_r_acc,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mmpyh_rs1,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmpyh_rs0,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_F2_conv_df2ud_chop,"LLid","")
+BUILTIN(__builtin_HEXAGON_C4_or_or,"iiii","")
+BUILTIN(__builtin_HEXAGON_S4_vxaddsubhr,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_vsathub,"iLLi","")
+BUILTIN(__builtin_HEXAGON_F2_conv_df2sf,"fd","")
+BUILTIN(__builtin_HEXAGON_M2_hmmpyh_rs1,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_hmmpyh_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_vavgwr,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_tableidxh_goodsyntax,"iiiUIiUIi","")
+BUILTIN(__builtin_HEXAGON_A2_sxth,"ii","")
+BUILTIN(__builtin_HEXAGON_A2_sxtb,"ii","")
+BUILTIN(__builtin_HEXAGON_C4_or_orn,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_vrcmaci_s0c,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_sxtw,"LLii","")
+BUILTIN(__builtin_HEXAGON_M2_vabsdiffh,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_acc_lh_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_acc_lh_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_hmmpyl_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_S2_cl1p,"iLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vabsdiffw,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A4_andnp,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_C2_vmux,"LLiiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_parityp,"iLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_i_p_and,"LLiLLiLLiUIi","")
+BUILTIN(__builtin_HEXAGON_S2_asr_i_r_or,"iiiUIi","")
BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_ll_s0,"iiii","")
BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_ll_s1,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_hh_s0,"Uiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_hh_s1,"Uiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_hl_s0,"Uiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_hl_s1,"Uiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_lh_s0,"Uiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_lh_s1,"Uiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_ll_s0,"Uiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_ll_s1,"Uiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_hh_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_hh_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_hl_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_hl_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_lh_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_lh_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_ll_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_ll_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_hh_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_hh_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_hl_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_F2_sfcmpeq,"iff","")
+BUILTIN(__builtin_HEXAGON_A2_vaddb_map,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_r_r_nac,"iiii","")
+BUILTIN(__builtin_HEXAGON_A2_vcmpheq,"iLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_clbnorm,"ii","")
+BUILTIN(__builtin_HEXAGON_M2_cnacsc_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_cnacsc_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_S4_subaddi,"iiIii","")
BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_hl_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_lh_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_lh_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_ll_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_ll_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_hh_s0,"ULLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_hh_s1,"ULLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_hl_s0,"ULLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_hl_s1,"ULLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_lh_s0,"ULLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_lh_s1,"ULLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_ll_s0,"ULLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyud_ll_s1,"ULLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpysmi,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_macsip,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_macsin,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_dpmpyss_s0,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_dpmpyss_acc_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_dpmpyss_nac_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_dpmpyuu_s0,"ULLiii","")
-BUILTIN(__builtin_HEXAGON_M2_dpmpyuu_acc_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_dpmpyuu_nac_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_up,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_hl_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_S5_vasrhrnd_goodsyntax,"LLiLLiUIi","")
+BUILTIN(__builtin_HEXAGON_S2_tstbit_r,"iii","")
+BUILTIN(__builtin_HEXAGON_S4_vrcrotate,"LLiLLiiUIi","")
+BUILTIN(__builtin_HEXAGON_M2_mmachs_s1,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmachs_s0,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_tstbit_i,"iiUIi","")
BUILTIN(__builtin_HEXAGON_M2_mpy_up_s1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpy_up_s1_sat,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyu_up,"Uiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpysu_up,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_dpmpyss_rnd_s0,"iii","")
-BUILTIN(__builtin_HEXAGON_M4_mac_up_s1_sat,"iiii","")
-BUILTIN(__builtin_HEXAGON_M4_nac_up_s1_sat,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyi,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mpyui,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_maci,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_acci,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_accii,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_nacci,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_naccii,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_subacc,"iiii","")
-BUILTIN(__builtin_HEXAGON_M4_mpyrr_addr,"iiii","")
-BUILTIN(__builtin_HEXAGON_M4_mpyri_addr_u2,"iiii","")
-BUILTIN(__builtin_HEXAGON_M4_mpyri_addr,"iiii","")
-BUILTIN(__builtin_HEXAGON_M4_mpyri_addi,"iiii","")
-BUILTIN(__builtin_HEXAGON_M4_mpyrr_addi,"iiii","")
-BUILTIN(__builtin_HEXAGON_M2_vmpy2s_s0,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_vmpy2s_s1,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_vmac2s_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_vmac2s_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_vmpy2su_s0,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_vmpy2su_s1,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_vmac2su_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_vmac2su_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_vmpy2s_s0pack,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_vmpy2s_s1pack,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_vmac2,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_vmpy2es_s0,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vmpy2es_s1,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vmac2es_s0,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vmac2es_s1,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vmac2es,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vrmac_s0,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vrmpy_s0,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_extractu_rp,"iiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmpyuh_rs0,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_i_vw,"LLiLLiUIi","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_ll_s0,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_ll_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_M4_or_or,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_hh_s1,"Uiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_hh_s0,"Uiii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_r_p_acc,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_lh_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_lh_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_sat_ll_s0,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_sat_ll_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_F2_conv_w2df,"di","")
+BUILTIN(__builtin_HEXAGON_A2_subh_l16_sat_hl,"iii","")
+BUILTIN(__builtin_HEXAGON_C2_cmpeqi,"iiIi","")
+BUILTIN(__builtin_HEXAGON_S2_asl_i_r_and,"iiiUIi","")
+BUILTIN(__builtin_HEXAGON_S2_vcnegh,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_A4_vcmpweqi,"iLLiIi","")
BUILTIN(__builtin_HEXAGON_M2_vdmpyrs_s0,"iLLiLLi","")
BUILTIN(__builtin_HEXAGON_M2_vdmpyrs_s1,"iLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M5_vrmpybuu,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M5_vrmacbuu,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M5_vrmpybsu,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M5_vrmacbsu,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M5_vmpybuu,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M5_vmpybsu,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M5_vmacbuu,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M5_vmacbsu,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M5_vdmpybsu,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M5_vdmacbsu,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vdmacs_s0,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vdmacs_s1,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vdmpys_s0,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M4_xor_xacc,"LLiLLiLLiLLi","")
BUILTIN(__builtin_HEXAGON_M2_vdmpys_s1,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_cmpyrs_s0,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_cmpyrs_s1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_cmpyrsc_s0,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_cmpyrsc_s1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_cmacs_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_cmacs_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_vdmpys_s0,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vavgubr,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_hl_s1,"Uiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_hl_s0,"Uiii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_r_r_acc,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_cl0p,"iLLi","")
+BUILTIN(__builtin_HEXAGON_S2_valignib,"LLiLLiLLiUIi","")
+BUILTIN(__builtin_HEXAGON_F2_sffixupd,"fff","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_hl_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_hl_s0,"iii","")
BUILTIN(__builtin_HEXAGON_M2_cmacsc_s0,"LLiLLiii","")
BUILTIN(__builtin_HEXAGON_M2_cmacsc_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_cmpys_s0,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_cmpys_s1,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_cmpysc_s0,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_cmpysc_s1,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_cnacs_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_cnacs_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_cnacsc_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_cnacsc_s1,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_vrcmpys_s1,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_M2_vrcmpys_acc_s1,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_M2_vrcmpys_s1rp,"iLLii","")
-BUILTIN(__builtin_HEXAGON_M2_mmacls_s0,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmacls_s1,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmachs_s0,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmachs_s1,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmpyl_s0,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmpyl_s1,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmpyh_s0,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmpyh_s1,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmacls_rs0,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmacls_rs1,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmachs_rs0,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmachs_rs1,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmpyl_rs0,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmpyl_rs1,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmpyh_rs0,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmpyh_rs1,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M4_vrmpyeh_s0,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M4_vrmpyeh_s1,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M4_vrmpyeh_acc_s0,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M4_vrmpyeh_acc_s1,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M4_vrmpyoh_s0,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M4_vrmpyoh_s1,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M4_vrmpyoh_acc_s0,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M4_vrmpyoh_acc_s1,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_hmmpyl_rs1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_hmmpyh_rs1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_hmmpyl_s1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_hmmpyh_s1,"iii","")
-BUILTIN(__builtin_HEXAGON_M2_mmaculs_s0,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmaculs_s1,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmacuhs_s0,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmacuhs_s1,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmpyul_s0,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmpyul_s1,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmpyuh_s0,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmpyuh_s1,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmaculs_rs0,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmaculs_rs1,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmacuhs_rs0,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmacuhs_rs1,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmpyul_rs0,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_ct1,"ii","")
+BUILTIN(__builtin_HEXAGON_S2_ct0,"ii","")
+BUILTIN(__builtin_HEXAGON_M2_dpmpyuu_nac_s0,"LLiLLiii","")
BUILTIN(__builtin_HEXAGON_M2_mmpyul_rs1,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_mmpyuh_rs0,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S4_ntstbit_i,"iiUIi","")
+BUILTIN(__builtin_HEXAGON_F2_sffixupr,"ff","")
+BUILTIN(__builtin_HEXAGON_S2_asr_r_p_xor,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_hl_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_hl_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_A2_vcmphgtu,"iLLiLLi","")
+BUILTIN(__builtin_HEXAGON_C2_andn,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_vmpy2s_s0pack,"iii","")
+BUILTIN(__builtin_HEXAGON_S4_addaddi,"iiiIi","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_ll_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_hl_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_A4_rcmpeqi,"iiIi","")
+BUILTIN(__builtin_HEXAGON_M4_xor_and,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_i_p_and,"LLiLLiLLiUIi","")
BUILTIN(__builtin_HEXAGON_M2_mmpyuh_rs1,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vrcmaci_s0,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vrcmacr_s0,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vrcmaci_s0c,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vrcmacr_s0c,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_cmaci_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_cmacr_s0,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M2_vrcmpyi_s0,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vrcmpyr_s0,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vrcmpyi_s0c,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vrcmpyr_s0c,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_cmpyi_s0,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M2_cmpyr_s0,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M4_cmpyi_wh,"iLLii","")
-BUILTIN(__builtin_HEXAGON_M4_cmpyr_wh,"iLLii","")
-BUILTIN(__builtin_HEXAGON_M4_cmpyi_whc,"iLLii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_r_r_or,"iiii","")
+BUILTIN(__builtin_HEXAGON_A4_round_ri,"iiUIi","")
+BUILTIN(__builtin_HEXAGON_A2_max,"iii","")
+BUILTIN(__builtin_HEXAGON_A4_round_rr,"iii","")
+BUILTIN(__builtin_HEXAGON_A4_combineii,"LLiIiUIi","")
+BUILTIN(__builtin_HEXAGON_A4_combineir,"LLiIii","")
+BUILTIN(__builtin_HEXAGON_C4_and_orn,"iiii","")
+BUILTIN(__builtin_HEXAGON_M5_vmacbuu,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_A4_rcmpeq,"iii","")
BUILTIN(__builtin_HEXAGON_M4_cmpyr_whc,"iLLii","")
-BUILTIN(__builtin_HEXAGON_M2_vcmpy_s0_sat_i,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vcmpy_s0_sat_r,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vcmpy_s1_sat_i,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vcmpy_s1_sat_r,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vcmac_s0_sat_i,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vcmac_s0_sat_r,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_S2_vcrotate,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S4_vrcrotate_acc,"LLiLLiLLiii","")
-BUILTIN(__builtin_HEXAGON_S4_vrcrotate,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_S2_vcnegh,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_vrcnegh,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_M4_pmpyw,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M4_vpmpyh,"LLiii","")
-BUILTIN(__builtin_HEXAGON_M4_pmpyw_acc,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_M4_vpmpyh_acc,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_A2_add,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_sub,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_addsat,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_subsat,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_addi,"iii","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_i_r_acc,"iiiUIi","")
+BUILTIN(__builtin_HEXAGON_S2_vzxtbh,"LLii","")
+BUILTIN(__builtin_HEXAGON_M2_mmacuhs_rs1,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_asr_r_r_sat,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_combinew,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_acc_ll_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_acc_ll_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_cmpyi_s0,"LLiii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_r_p_or,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S4_ori_asl_ri,"iUIiiUIi","")
+BUILTIN(__builtin_HEXAGON_C4_nbitsset,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_hh_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_hh_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_ll_s1,"Uiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_ll_s0,"Uiii","")
BUILTIN(__builtin_HEXAGON_A2_addh_l16_ll,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_addh_l16_hl,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_addh_l16_sat_ll,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_addh_l16_sat_hl,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_subh_l16_ll,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_subh_l16_hl,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_subh_l16_sat_ll,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_subh_l16_sat_hl,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_addh_h16_ll,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_addh_h16_lh,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_addh_h16_hl,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_addh_h16_hh,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_addh_h16_sat_ll,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_addh_h16_sat_lh,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_addh_h16_sat_hl,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_addh_h16_sat_hh,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_subh_h16_ll,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_subh_h16_lh,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_subh_h16_hl,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_subh_h16_hh,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_subh_h16_sat_ll,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_subh_h16_sat_lh,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_subh_h16_sat_hl,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_subh_h16_sat_hh,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_aslh,"ii","")
-BUILTIN(__builtin_HEXAGON_A2_asrh,"ii","")
-BUILTIN(__builtin_HEXAGON_A2_addp,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_addpsat,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_addsp,"LLiiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_subp,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_neg,"ii","")
-BUILTIN(__builtin_HEXAGON_A2_negsat,"ii","")
-BUILTIN(__builtin_HEXAGON_A2_abs,"ii","")
-BUILTIN(__builtin_HEXAGON_A2_abssat,"ii","")
-BUILTIN(__builtin_HEXAGON_A2_vconj,"LLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_negp,"LLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_absp,"LLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_max,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_maxu,"Uiii","")
-BUILTIN(__builtin_HEXAGON_A2_min,"iii","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_r_r_and,"iiii","")
+BUILTIN(__builtin_HEXAGON_A4_modwrapu,"iii","")
+BUILTIN(__builtin_HEXAGON_A4_rcmpneq,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_hh_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_hh_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_F2_sfimm_p,"fUIi","")
+BUILTIN(__builtin_HEXAGON_F2_sfimm_n,"fUIi","")
+BUILTIN(__builtin_HEXAGON_M4_cmpyr_wh,"iLLii","")
+BUILTIN(__builtin_HEXAGON_S2_lsl_r_p_and,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_A2_vavgub,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_F2_conv_d2sf,"fLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vavguh,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A4_cmpbeqi,"iiUIi","")
+BUILTIN(__builtin_HEXAGON_F2_sfcmpuo,"iff","")
+BUILTIN(__builtin_HEXAGON_A2_vavguw,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_asr_i_p_nac,"LLiLLiLLiUIi","")
+BUILTIN(__builtin_HEXAGON_S2_vsatwh_nopack,"LLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_hh_s0,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_hh_s1,"LLiii","")
+BUILTIN(__builtin_HEXAGON_S2_lsl_r_p_or,"LLiLLiLLii","")
BUILTIN(__builtin_HEXAGON_A2_minu,"Uiii","")
-BUILTIN(__builtin_HEXAGON_A2_maxp,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_maxup,"ULLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_minp,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_minup,"ULLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_tfr,"ii","")
-BUILTIN(__builtin_HEXAGON_A2_tfrsi,"ii","")
-BUILTIN(__builtin_HEXAGON_A2_tfrp,"LLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_tfrpi,"LLii","")
-BUILTIN(__builtin_HEXAGON_A2_zxtb,"ii","")
-BUILTIN(__builtin_HEXAGON_A2_sxtb,"ii","")
-BUILTIN(__builtin_HEXAGON_A2_zxth,"ii","")
-BUILTIN(__builtin_HEXAGON_A2_sxth,"ii","")
-BUILTIN(__builtin_HEXAGON_A2_combinew,"LLiii","")
-BUILTIN(__builtin_HEXAGON_A4_combineri,"LLiii","")
-BUILTIN(__builtin_HEXAGON_A4_combineir,"LLiii","")
-BUILTIN(__builtin_HEXAGON_A2_combineii,"LLiii","")
-BUILTIN(__builtin_HEXAGON_A2_combine_hh,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_combine_hl,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_combine_lh,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_combine_ll,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_tfril,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_tfrih,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_and,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_or,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_xor,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_not,"ii","")
-BUILTIN(__builtin_HEXAGON_M2_xor_xacc,"iiii","")
-BUILTIN(__builtin_HEXAGON_M4_xor_xacc,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A4_andn,"iii","")
-BUILTIN(__builtin_HEXAGON_A4_orn,"iii","")
-BUILTIN(__builtin_HEXAGON_A4_andnp,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A4_ornp,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_S4_addaddi,"iiii","")
-BUILTIN(__builtin_HEXAGON_S4_subaddi,"iiii","")
-BUILTIN(__builtin_HEXAGON_M4_and_and,"iiii","")
-BUILTIN(__builtin_HEXAGON_M4_and_andn,"iiii","")
-BUILTIN(__builtin_HEXAGON_M4_and_or,"iiii","")
-BUILTIN(__builtin_HEXAGON_M4_and_xor,"iiii","")
-BUILTIN(__builtin_HEXAGON_M4_or_and,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_sat_lh_s1,"iii","")
BUILTIN(__builtin_HEXAGON_M4_or_andn,"iiii","")
-BUILTIN(__builtin_HEXAGON_M4_or_or,"iiii","")
-BUILTIN(__builtin_HEXAGON_M4_or_xor,"iiii","")
-BUILTIN(__builtin_HEXAGON_S4_or_andix,"iiii","")
-BUILTIN(__builtin_HEXAGON_S4_or_andi,"iiii","")
-BUILTIN(__builtin_HEXAGON_S4_or_ori,"iiii","")
-BUILTIN(__builtin_HEXAGON_M4_xor_and,"iiii","")
-BUILTIN(__builtin_HEXAGON_M4_xor_or,"iiii","")
-BUILTIN(__builtin_HEXAGON_M4_xor_andn,"iiii","")
-BUILTIN(__builtin_HEXAGON_A2_subri,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_andir,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_orir,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_andp,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_orp,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_xorp,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_notp,"LLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_sxtw,"LLii","")
-BUILTIN(__builtin_HEXAGON_A2_sat,"iLLi","")
+BUILTIN(__builtin_HEXAGON_A2_minp,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S4_or_andix,"iiiIi","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_lh_s0,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_lh_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mmpyuh_s0,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmpyuh_s1,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_lh_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_F2_sfcmpge,"iff","")
+BUILTIN(__builtin_HEXAGON_F2_sfmin,"fff","")
+BUILTIN(__builtin_HEXAGON_F2_sfcmpgt,"iff","")
+BUILTIN(__builtin_HEXAGON_M4_vpmpyh,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mmacuhs_rs0,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_lh_s1,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_lh_s0,"LLiii","")
BUILTIN(__builtin_HEXAGON_A2_roundsat,"iLLi","")
+BUILTIN(__builtin_HEXAGON_S2_ct1p,"iLLi","")
+BUILTIN(__builtin_HEXAGON_S4_extract_rp,"iiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_lsl_r_r_or,"iiii","")
+BUILTIN(__builtin_HEXAGON_C4_cmplteui,"iiUIi","")
+BUILTIN(__builtin_HEXAGON_S4_addi_lsr_ri,"iUIiiUIi","")
+BUILTIN(__builtin_HEXAGON_A4_tfrcpp,"LLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_asr_i_svw_trun,"iLLiUIi","")
+BUILTIN(__builtin_HEXAGON_A4_cmphgti,"iiIi","")
+BUILTIN(__builtin_HEXAGON_A4_vrminh,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_A4_vrminw,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_A4_cmphgtu,"iii","")
+BUILTIN(__builtin_HEXAGON_S2_insertp_rp,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vnavghcr,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S4_subi_asl_ri,"iUIiiUIi","")
+BUILTIN(__builtin_HEXAGON_S2_lsl_r_vh,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_hh_s0,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_vsubws,"LLiLLiLLi","")
BUILTIN(__builtin_HEXAGON_A2_sath,"ii","")
-BUILTIN(__builtin_HEXAGON_A2_satuh,"ii","")
-BUILTIN(__builtin_HEXAGON_A2_satub,"ii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_r_p_xor,"LLiLLiLLii","")
BUILTIN(__builtin_HEXAGON_A2_satb,"ii","")
-BUILTIN(__builtin_HEXAGON_A2_vaddub,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vaddb_map,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vaddubs,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vaddh,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vaddhs,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vadduhs,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A5_vaddhubs,"iLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vaddw,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vaddws,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_C2_cmpltu,"iii","")
+BUILTIN(__builtin_HEXAGON_S2_insertp,"LLiLLiLLiUIiUIi","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_ll_s1,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_ll_s0,"LLiii","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_i_p_nac,"LLiLLiLLiUIi","")
+BUILTIN(__builtin_HEXAGON_S2_extractup_rp,"LLiLLiLLi","")
BUILTIN(__builtin_HEXAGON_S4_vxaddsubw,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_S4_vxsubaddw,"LLiLLiLLi","")
BUILTIN(__builtin_HEXAGON_S4_vxaddsubh,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_S4_vxsubaddh,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_S4_vxaddsubhr,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_S4_vxsubaddhr,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_svavgh,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_svavghs,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_svnavgh,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_svaddh,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_svaddhs,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_svadduhs,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_svsubh,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_svsubhs,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_svsubuhs,"iii","")
-BUILTIN(__builtin_HEXAGON_A2_vraddub,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vraddub_acc,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vraddh,"iLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vradduh,"iLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vsubub,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vsubb_map,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_asrh,"ii","")
+BUILTIN(__builtin_HEXAGON_S4_extractp_rp,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_r_r_acc,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_ll_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_ll_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_C2_or,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mmpyul_s1,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vrcmacr_s0,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_xor,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_add,"iii","")
BUILTIN(__builtin_HEXAGON_A2_vsububs,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vsubh,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vsubhs,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vsubuhs,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vsubw,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vsubws,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vabsh,"LLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vabshsat,"LLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vabsw,"LLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vabswsat,"LLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vabsdiffw,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_M2_vabsdiffh,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vmpy2s_s1,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_vmpy2s_s0,"LLiii","")
+BUILTIN(__builtin_HEXAGON_A2_vraddub_acc,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_F2_sfinvsqrta,"ff","")
+BUILTIN(__builtin_HEXAGON_S2_ct0p,"iLLi","")
+BUILTIN(__builtin_HEXAGON_A2_svaddh,"iii","")
+BUILTIN(__builtin_HEXAGON_S2_vcrotate,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_A2_aslh,"ii","")
+BUILTIN(__builtin_HEXAGON_A2_subh_h16_lh,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_subh_h16_ll,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_hmmpyl_rs1,"iii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_r_p,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_vsplatrh,"LLii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_r_r,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_addh_h16_hl,"iii","")
+BUILTIN(__builtin_HEXAGON_S2_vsplatrb,"ii","")
+BUILTIN(__builtin_HEXAGON_A2_addh_h16_hh,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_cmpyr_s0,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_dpmpyss_rnd_s0,"iii","")
+BUILTIN(__builtin_HEXAGON_C2_muxri,"iiIii","")
+BUILTIN(__builtin_HEXAGON_M2_vmac2es_s0,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vmac2es_s1,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_C2_pxfer_map,"ii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_lh_s1,"Uiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_lh_s0,"Uiii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_i_r_or,"iiiUIi","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_hl_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_hl_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_r_p_nac,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_A2_vaddw,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_asr_i_r_and,"iiiUIi","")
+BUILTIN(__builtin_HEXAGON_A2_vaddh,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_lh_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_lh_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_C2_cmpeqp,"iLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M4_mpyri_addi,"iUIiiUIi","")
+BUILTIN(__builtin_HEXAGON_A2_not,"ii","")
+BUILTIN(__builtin_HEXAGON_S4_andi_lsr_ri,"iUIiiUIi","")
+BUILTIN(__builtin_HEXAGON_M2_macsip,"iiiUIi","")
+BUILTIN(__builtin_HEXAGON_A2_tfrcrr,"ii","")
+BUILTIN(__builtin_HEXAGON_M2_macsin,"iiiUIi","")
+BUILTIN(__builtin_HEXAGON_C2_orn,"iii","")
+BUILTIN(__builtin_HEXAGON_M4_and_andn,"iiii","")
+BUILTIN(__builtin_HEXAGON_F2_sfmpy,"fff","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_hh_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_hh_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_r_p_acc,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_r_vw,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_M4_and_or,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_r_vh,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_C2_mask,"LLii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_nac_hh_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_nac_hh_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_up_s1_sat,"iii","")
+BUILTIN(__builtin_HEXAGON_A4_vcmpbgt,"iLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M5_vrmacbsu,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_tableidxw_goodsyntax,"iiiUIiUIi","")
BUILTIN(__builtin_HEXAGON_A2_vrsadub,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vrsadub_acc,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vavgub,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vavguh,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vavgh,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vnavgh,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vavgw,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vnavgw,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vavgwr,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vnavgwr,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vavgwcr,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vnavgwcr,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vavghcr,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vnavghcr,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vavguw,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vavguwr,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vavgubr,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vavguhr,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vavghr,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vnavghr,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A4_round_ri,"iii","")
-BUILTIN(__builtin_HEXAGON_A4_round_rr,"iii","")
-BUILTIN(__builtin_HEXAGON_A4_round_ri_sat,"iii","")
-BUILTIN(__builtin_HEXAGON_A4_round_rr_sat,"iii","")
-BUILTIN(__builtin_HEXAGON_A4_cround_ri,"iii","")
-BUILTIN(__builtin_HEXAGON_A4_cround_rr,"iii","")
-BUILTIN(__builtin_HEXAGON_A4_vrminh,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_A4_vrmaxh,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_A4_vrminuh,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_A4_vrmaxuh,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_A4_vrminw,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_A4_vrmaxw,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_A4_vrminuw,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_A4_vrmaxuw,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_A2_vminb,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_tfrrcr,"ii","")
+BUILTIN(__builtin_HEXAGON_M2_vrcmpys_acc_s1,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_F2_dfcmpge,"idd","")
+BUILTIN(__builtin_HEXAGON_M2_accii,"iiiIi","")
+BUILTIN(__builtin_HEXAGON_A5_vaddhubs,"iLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vmaxw,"LLiLLiLLi","")
BUILTIN(__builtin_HEXAGON_A2_vmaxb,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vminub,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vmaxub,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vminh,"LLiLLiLLi","")
BUILTIN(__builtin_HEXAGON_A2_vmaxh,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vminuh,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vmaxuh,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vminw,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vmaxw,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vminuw,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A2_vmaxuw,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_A4_modwrapu,"iii","")
-BUILTIN(__builtin_HEXAGON_F2_sfadd,"fff","")
-BUILTIN(__builtin_HEXAGON_F2_sfsub,"fff","")
-BUILTIN(__builtin_HEXAGON_F2_sfmpy,"fff","")
-BUILTIN(__builtin_HEXAGON_F2_sffma,"ffff","")
-BUILTIN(__builtin_HEXAGON_F2_sffma_sc,"ffffi","")
-BUILTIN(__builtin_HEXAGON_F2_sffms,"ffff","")
-BUILTIN(__builtin_HEXAGON_F2_sffma_lib,"ffff","")
-BUILTIN(__builtin_HEXAGON_F2_sffms_lib,"ffff","")
-BUILTIN(__builtin_HEXAGON_F2_sfcmpeq,"iff","")
-BUILTIN(__builtin_HEXAGON_F2_sfcmpgt,"iff","")
-BUILTIN(__builtin_HEXAGON_F2_sfcmpge,"iff","")
-BUILTIN(__builtin_HEXAGON_F2_sfcmpuo,"iff","")
-BUILTIN(__builtin_HEXAGON_F2_sfmax,"fff","")
-BUILTIN(__builtin_HEXAGON_F2_sfmin,"fff","")
-BUILTIN(__builtin_HEXAGON_F2_sfclass,"ifi","")
-BUILTIN(__builtin_HEXAGON_F2_sfimm_p,"fi","")
-BUILTIN(__builtin_HEXAGON_F2_sfimm_n,"fi","")
-BUILTIN(__builtin_HEXAGON_F2_sffixupn,"fff","")
-BUILTIN(__builtin_HEXAGON_F2_sffixupd,"fff","")
-BUILTIN(__builtin_HEXAGON_F2_sffixupr,"ff","")
-BUILTIN(__builtin_HEXAGON_F2_dfcmpeq,"idd","")
-BUILTIN(__builtin_HEXAGON_F2_dfcmpgt,"idd","")
-BUILTIN(__builtin_HEXAGON_F2_dfcmpge,"idd","")
-BUILTIN(__builtin_HEXAGON_F2_dfcmpuo,"idd","")
-BUILTIN(__builtin_HEXAGON_F2_dfclass,"idi","")
-BUILTIN(__builtin_HEXAGON_F2_dfimm_p,"di","")
-BUILTIN(__builtin_HEXAGON_F2_dfimm_n,"di","")
-BUILTIN(__builtin_HEXAGON_F2_conv_sf2df,"df","")
-BUILTIN(__builtin_HEXAGON_F2_conv_df2sf,"fd","")
-BUILTIN(__builtin_HEXAGON_F2_conv_uw2sf,"fi","")
-BUILTIN(__builtin_HEXAGON_F2_conv_uw2df,"di","")
-BUILTIN(__builtin_HEXAGON_F2_conv_w2sf,"fi","")
-BUILTIN(__builtin_HEXAGON_F2_conv_w2df,"di","")
-BUILTIN(__builtin_HEXAGON_F2_conv_ud2sf,"fLLi","")
-BUILTIN(__builtin_HEXAGON_F2_conv_ud2df,"dLLi","")
-BUILTIN(__builtin_HEXAGON_F2_conv_d2sf,"fLLi","")
-BUILTIN(__builtin_HEXAGON_F2_conv_d2df,"dLLi","")
-BUILTIN(__builtin_HEXAGON_F2_conv_sf2uw,"if","")
+BUILTIN(__builtin_HEXAGON_S2_vsxthw,"LLii","")
+BUILTIN(__builtin_HEXAGON_S4_andi_asl_ri,"iUIiiUIi","")
+BUILTIN(__builtin_HEXAGON_S2_asl_i_p_nac,"LLiLLiLLiUIi","")
+BUILTIN(__builtin_HEXAGON_S2_lsl_r_p_xor,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_C2_cmpgt,"iii","")
+BUILTIN(__builtin_HEXAGON_F2_conv_df2d_chop,"LLid","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_hl_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_hl_s1,"iiii","")
BUILTIN(__builtin_HEXAGON_F2_conv_sf2w,"if","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_r_p_or,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_F2_sfclass,"ifUIi","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_lh_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M4_xor_andn,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_addasl_rrri,"iiiUIi","")
+BUILTIN(__builtin_HEXAGON_M5_vdmpybsu,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_hh_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_hh_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_A2_addi,"iiIi","")
+BUILTIN(__builtin_HEXAGON_A2_addp,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vmpy2s_s1pack,"iii","")
+BUILTIN(__builtin_HEXAGON_S4_clbpnorm,"iLLi","")
+BUILTIN(__builtin_HEXAGON_A4_round_rr_sat,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_nacci,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_shuffeh,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_i_r_and,"iiiUIi","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_hh_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_hh_s0,"iii","")
+BUILTIN(__builtin_HEXAGON_F2_conv_sf2uw,"if","")
+BUILTIN(__builtin_HEXAGON_A2_vsubh,"LLiLLiLLi","")
BUILTIN(__builtin_HEXAGON_F2_conv_sf2ud,"LLif","")
-BUILTIN(__builtin_HEXAGON_F2_conv_sf2d,"LLif","")
-BUILTIN(__builtin_HEXAGON_F2_conv_df2uw,"id","")
-BUILTIN(__builtin_HEXAGON_F2_conv_df2w,"id","")
-BUILTIN(__builtin_HEXAGON_F2_conv_df2ud,"LLid","")
-BUILTIN(__builtin_HEXAGON_F2_conv_df2d,"LLid","")
+BUILTIN(__builtin_HEXAGON_A2_vsubw,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vcmpwgt,"iLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M4_xor_or,"iiii","")
BUILTIN(__builtin_HEXAGON_F2_conv_sf2uw_chop,"if","")
-BUILTIN(__builtin_HEXAGON_F2_conv_sf2w_chop,"if","")
-BUILTIN(__builtin_HEXAGON_F2_conv_sf2ud_chop,"LLif","")
-BUILTIN(__builtin_HEXAGON_F2_conv_sf2d_chop,"LLif","")
-BUILTIN(__builtin_HEXAGON_F2_conv_df2uw_chop,"id","")
-BUILTIN(__builtin_HEXAGON_F2_conv_df2w_chop,"id","")
-BUILTIN(__builtin_HEXAGON_F2_conv_df2ud_chop,"LLid","")
-BUILTIN(__builtin_HEXAGON_F2_conv_df2d_chop,"LLid","")
-BUILTIN(__builtin_HEXAGON_S2_asr_r_r,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_r_r,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_r_r,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_lsl_r_r,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_r_p,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_r_p,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_r_vw,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_vsatwuh_nopack,"LLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_asl_r_vh,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_A2_svsubuhs,"iii","")
+BUILTIN(__builtin_HEXAGON_M5_vmpybsu,"LLiii","")
+BUILTIN(__builtin_HEXAGON_A2_subh_l16_sat_ll,"iii","")
+BUILTIN(__builtin_HEXAGON_C4_and_and,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_hl_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_hl_s0,"iiii","")
BUILTIN(__builtin_HEXAGON_S2_lsr_r_p,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsl_r_p,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_r_r_acc,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_r_r_acc,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_r_r_acc,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_lsl_r_r_acc,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_r_p_acc,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_r_p_acc,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_r_p_acc,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsl_r_p_acc,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_r_r,"iii","")
+BUILTIN(__builtin_HEXAGON_A4_subp_c,"LLiLLiLLiv*","")
+BUILTIN(__builtin_HEXAGON_A2_vsubhs,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_C2_vitpack,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_vavguhr,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_vsplicerb,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_C4_nbitsclr,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_vcmpbgtu,"iLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_cmpys_s1,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_cmpys_s0,"LLiii","")
+BUILTIN(__builtin_HEXAGON_F2_dfcmpuo,"idd","")
+BUILTIN(__builtin_HEXAGON_S2_shuffob,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_C2_and,"iii","")
+BUILTIN(__builtin_HEXAGON_S5_popcountp,"iLLi","")
+BUILTIN(__builtin_HEXAGON_S4_extractp,"LLiLLiUIiUIi","")
+BUILTIN(__builtin_HEXAGON_S2_cl0,"ii","")
+BUILTIN(__builtin_HEXAGON_A4_vcmpbgti,"iLLiIi","")
+BUILTIN(__builtin_HEXAGON_M2_mmacls_s1,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmacls_s0,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_C4_cmpneq,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_vmac2es,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vdmacs_s0,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vdmacs_s1,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_ll_s0,"ULLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_ll_s1,"ULLiii","")
+BUILTIN(__builtin_HEXAGON_S2_clb,"ii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_nac_ll_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_nac_ll_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_hl_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_hl_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_maci,"iiii","")
+BUILTIN(__builtin_HEXAGON_A2_vmaxuh,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A4_bitspliti,"LLiiUIi","")
+BUILTIN(__builtin_HEXAGON_A2_vmaxub,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_hh_s0,"ULLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_hh_s1,"ULLiii","")
+BUILTIN(__builtin_HEXAGON_M2_vrmac_s0,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_sat_lh_s0,"iii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_r_r_sat,"iii","")
+BUILTIN(__builtin_HEXAGON_F2_conv_sf2d,"LLif","")
BUILTIN(__builtin_HEXAGON_S2_asr_r_r_nac,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_r_r_nac,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_r_r_nac,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_lsl_r_r_nac,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_r_p_nac,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_r_p_nac,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_r_p_nac,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_F2_dfimm_n,"dUIi","")
+BUILTIN(__builtin_HEXAGON_A4_cmphgt,"iii","")
+BUILTIN(__builtin_HEXAGON_F2_dfimm_p,"dUIi","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_lh_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_vcmpy_s1_sat_r,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M4_mpyri_addr_u2,"iiUIii","")
+BUILTIN(__builtin_HEXAGON_M2_vcmpy_s1_sat_i,"LLiLLiLLi","")
BUILTIN(__builtin_HEXAGON_S2_lsl_r_p_nac,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_r_r_and,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_r_r_and,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_r_r_and,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_lsl_r_r_and,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_r_r_or,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_r_r_or,"iiii","")
+BUILTIN(__builtin_HEXAGON_M5_vrmacbuu,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S5_asrhub_rnd_sat_goodsyntax,"iLLiUIi","")
+BUILTIN(__builtin_HEXAGON_S2_vspliceib,"LLiLLiLLiUIi","")
+BUILTIN(__builtin_HEXAGON_M2_dpmpyss_acc_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_cnacs_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_cnacs_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_A2_maxu,"Uiii","")
+BUILTIN(__builtin_HEXAGON_A2_maxp,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_andir,"iiIi","")
+BUILTIN(__builtin_HEXAGON_F2_sfrecipa,"fff","")
+BUILTIN(__builtin_HEXAGON_A2_combineii,"LLiIiIi","")
+BUILTIN(__builtin_HEXAGON_A4_orn,"iii","")
+BUILTIN(__builtin_HEXAGON_A4_cmpbgtui,"iiUIi","")
BUILTIN(__builtin_HEXAGON_S2_lsr_r_r_or,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_lsl_r_r_or,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_r_p_and,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_r_p_and,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_A4_vcmpbeqi,"iLLiUIi","")
+BUILTIN(__builtin_HEXAGON_S2_lsl_r_r,"iii","")
+BUILTIN(__builtin_HEXAGON_S2_lsl_r_p,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_A2_or,"iii","")
+BUILTIN(__builtin_HEXAGON_F2_dfcmpeq,"idd","")
+BUILTIN(__builtin_HEXAGON_C2_cmpeq,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_tfrp,"LLiLLi","")
+BUILTIN(__builtin_HEXAGON_C4_and_andn,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_vsathub_nopack,"LLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_satuh,"ii","")
+BUILTIN(__builtin_HEXAGON_A2_satub,"ii","")
+BUILTIN(__builtin_HEXAGON_M2_vrcmpys_s1,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_S4_or_ori,"iiiIi","")
+BUILTIN(__builtin_HEXAGON_C4_fastcorner9_not,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_tfrih,"iiUIi","")
+BUILTIN(__builtin_HEXAGON_A2_tfril,"iiUIi","")
+BUILTIN(__builtin_HEXAGON_M4_mpyri_addr,"iiiUIi","")
+BUILTIN(__builtin_HEXAGON_S2_vtrunehb,"iLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vabsw,"LLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vabsh,"LLiLLi","")
+BUILTIN(__builtin_HEXAGON_F2_sfsub,"fff","")
+BUILTIN(__builtin_HEXAGON_C2_muxii,"iiIiIi","")
+BUILTIN(__builtin_HEXAGON_C2_muxir,"iiiIi","")
+BUILTIN(__builtin_HEXAGON_A2_swiz,"ii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_i_p_and,"LLiLLiLLiUIi","")
+BUILTIN(__builtin_HEXAGON_M2_cmpyrsc_s0,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_cmpyrsc_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_vraddub,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A4_tlbmatch,"iLLii","")
+BUILTIN(__builtin_HEXAGON_F2_conv_df2w_chop,"id","")
+BUILTIN(__builtin_HEXAGON_A2_and,"iii","")
BUILTIN(__builtin_HEXAGON_S2_lsr_r_p_and,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsl_r_p_and,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_r_p_or,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_r_p_or,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_r_p_or,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsl_r_p_or,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_r_p_xor,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_r_p_xor,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_r_p_xor,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsl_r_p_xor,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_r_r_sat,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_r_r_sat,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_i_r,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_i_r,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_i_r,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_i_p,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_i_p,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_i_p,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_i_r_acc,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_i_r_acc,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_i_r_acc,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_i_p_acc,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_i_p_acc,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_i_p_acc,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_i_r_nac,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_i_r_nac,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_i_r_nac,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_i_p_nac,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_i_p_nac,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_i_p_nac,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_i_r_xacc,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_i_r_xacc,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_i_p_xacc,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_i_p_xacc,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_i_r_and,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_i_r_and,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_i_r_and,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_i_r_or,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_i_r_or,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_i_r_or,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_i_p_and,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_i_p_and,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_i_p_and,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_i_p_or,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_i_p_or,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_i_p_or,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_i_r_sat,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_i_r_rnd,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_i_r_rnd_goodsyntax,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_i_p_rnd,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_i_p_rnd_goodsyntax,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S4_lsli,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_addasl_rrri,"iiii","")
-BUILTIN(__builtin_HEXAGON_S4_andi_asl_ri,"iiii","")
-BUILTIN(__builtin_HEXAGON_S4_ori_asl_ri,"iiii","")
-BUILTIN(__builtin_HEXAGON_S4_addi_asl_ri,"iiii","")
-BUILTIN(__builtin_HEXAGON_S4_subi_asl_ri,"iiii","")
-BUILTIN(__builtin_HEXAGON_S4_andi_lsr_ri,"iiii","")
-BUILTIN(__builtin_HEXAGON_S4_ori_lsr_ri,"iiii","")
-BUILTIN(__builtin_HEXAGON_S4_addi_lsr_ri,"iiii","")
-BUILTIN(__builtin_HEXAGON_S4_subi_lsr_ri,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_valignib,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_valignrb,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_vspliceib,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_vsplicerb,"LLiLLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_vsplatrh,"LLii","")
-BUILTIN(__builtin_HEXAGON_S2_vsplatrb,"ii","")
-BUILTIN(__builtin_HEXAGON_S2_insert,"iiiii","")
-BUILTIN(__builtin_HEXAGON_S2_tableidxb_goodsyntax,"iiiii","")
-BUILTIN(__builtin_HEXAGON_S2_tableidxh_goodsyntax,"iiiii","")
-BUILTIN(__builtin_HEXAGON_S2_tableidxw_goodsyntax,"iiiii","")
-BUILTIN(__builtin_HEXAGON_S2_tableidxd_goodsyntax,"iiiii","")
-BUILTIN(__builtin_HEXAGON_A4_bitspliti,"LLiii","")
-BUILTIN(__builtin_HEXAGON_A4_bitsplit,"LLiii","")
-BUILTIN(__builtin_HEXAGON_S4_extract,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_extractu,"iiii","")
-BUILTIN(__builtin_HEXAGON_S2_insertp,"LLiLLiLLiii","")
-BUILTIN(__builtin_HEXAGON_S4_extractp,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_S2_extractup,"LLiLLiii","")
-BUILTIN(__builtin_HEXAGON_S2_insert_rp,"iiiLLi","")
-BUILTIN(__builtin_HEXAGON_S4_extract_rp,"iiLLi","")
-BUILTIN(__builtin_HEXAGON_S2_extractu_rp,"iiLLi","")
-BUILTIN(__builtin_HEXAGON_S2_insertp_rp,"LLiLLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_S4_extractp_rp,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_S2_extractup_rp,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_S2_tstbit_i,"iii","")
-BUILTIN(__builtin_HEXAGON_S4_ntstbit_i,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_setbit_i,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_togglebit_i,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_clrbit_i,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_tstbit_r,"iii","")
-BUILTIN(__builtin_HEXAGON_S4_ntstbit_r,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_setbit_r,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_togglebit_r,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_clrbit_r,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_i_vh,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_i_vh,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_i_vh,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_r_vh,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S5_asrhub_rnd_sat_goodsyntax,"iLLii","")
-BUILTIN(__builtin_HEXAGON_S5_asrhub_sat,"iLLii","")
-BUILTIN(__builtin_HEXAGON_S5_vasrhrnd_goodsyntax,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_r_vh,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_r_vh,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsl_r_vh,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_i_vw,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_i_svw_trun,"iLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_r_svw_trun,"iLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_i_vw,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_i_vw,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asr_r_vw,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_asl_r_vw,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsr_r_vw,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_lsl_r_vw,"LLiLLii","")
-BUILTIN(__builtin_HEXAGON_S2_vrndpackwh,"iLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_ll_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_ll_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_S4_extract,"iiUIiUIi","")
+BUILTIN(__builtin_HEXAGON_A2_vcmpweq,"iLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_acci,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_i_p_acc,"LLiLLiLLiUIi","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_i_p_or,"LLiLLiLLiUIi","")
+BUILTIN(__builtin_HEXAGON_F2_conv_ud2sf,"fLLi","")
+BUILTIN(__builtin_HEXAGON_A2_tfr,"ii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_i_p_or,"LLiLLiLLiUIi","")
+BUILTIN(__builtin_HEXAGON_A2_subri,"iIii","")
+BUILTIN(__builtin_HEXAGON_A4_vrmaxuw,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_M5_vmpybuu,"LLiii","")
+BUILTIN(__builtin_HEXAGON_A4_vrmaxuh,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_i_vw,"LLiLLiUIi","")
+BUILTIN(__builtin_HEXAGON_A2_vavgw,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_brev,"ii","")
+BUILTIN(__builtin_HEXAGON_A2_vavgh,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_clrbit_i,"iiUIi","")
+BUILTIN(__builtin_HEXAGON_S2_asl_i_vh,"LLiLLiUIi","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_i_r_or,"iiiUIi","")
+BUILTIN(__builtin_HEXAGON_S2_lsl_r_r_nac,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mmpyl_rs1,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_hl_s1,"ULLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mmpyl_s0,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmpyl_s1,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_naccii,"iiiIi","")
BUILTIN(__builtin_HEXAGON_S2_vrndpackwhs,"iLLi","")
-BUILTIN(__builtin_HEXAGON_S2_vsxtbh,"LLii","")
-BUILTIN(__builtin_HEXAGON_S2_vzxtbh,"LLii","")
-BUILTIN(__builtin_HEXAGON_S2_vsathub,"iLLi","")
-BUILTIN(__builtin_HEXAGON_S2_svsathub,"ii","")
-BUILTIN(__builtin_HEXAGON_S2_svsathb,"ii","")
-BUILTIN(__builtin_HEXAGON_S2_vsathb,"iLLi","")
-BUILTIN(__builtin_HEXAGON_S2_vtrunohb,"iLLi","")
BUILTIN(__builtin_HEXAGON_S2_vtrunewh,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_dpmpyss_nac_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_ll_s0,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_ll_s1,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M4_mac_up_s1_sat,"iiii","")
+BUILTIN(__builtin_HEXAGON_S4_vrcrotate_acc,"LLiLLiLLiiUIi","")
+BUILTIN(__builtin_HEXAGON_F2_conv_uw2df,"di","")
+BUILTIN(__builtin_HEXAGON_A2_vaddubs,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_asr_r_r_acc,"iiii","")
+BUILTIN(__builtin_HEXAGON_A2_orir,"iiIi","")
+BUILTIN(__builtin_HEXAGON_A2_andp,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_lfsp,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_min,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpysmi,"iiIi","")
+BUILTIN(__builtin_HEXAGON_M2_vcmpy_s0_sat_r,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_ll_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_ll_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_r_svw_trun,"iLLii","")
+BUILTIN(__builtin_HEXAGON_M2_mmpyh_s0,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmpyh_s1,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_F2_conv_sf2df,"df","")
+BUILTIN(__builtin_HEXAGON_S2_vtrunohb,"iLLi","")
+BUILTIN(__builtin_HEXAGON_F2_conv_sf2d_chop,"LLif","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_lh_s0,"LLiii","")
+BUILTIN(__builtin_HEXAGON_F2_conv_df2w,"id","")
+BUILTIN(__builtin_HEXAGON_S5_asrhub_sat,"iLLiUIi","")
+BUILTIN(__builtin_HEXAGON_S2_asl_i_r_xacc,"iiiUIi","")
+BUILTIN(__builtin_HEXAGON_F2_conv_df2d,"LLid","")
+BUILTIN(__builtin_HEXAGON_M2_mmaculs_s1,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmaculs_s0,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_svadduhs,"iii","")
+BUILTIN(__builtin_HEXAGON_F2_conv_sf2w_chop,"if","")
+BUILTIN(__builtin_HEXAGON_S2_svsathub,"ii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_hl_s1,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_hl_s0,"LLiii","")
+BUILTIN(__builtin_HEXAGON_S2_setbit_r,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_vavghr,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_F2_sffma_sc,"ffffi","")
+BUILTIN(__builtin_HEXAGON_F2_dfclass,"idUIi","")
+BUILTIN(__builtin_HEXAGON_F2_conv_df2ud,"LLid","")
+BUILTIN(__builtin_HEXAGON_F2_conv_df2uw,"id","")
+BUILTIN(__builtin_HEXAGON_M2_cmpyrs_s0,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_cmpyrs_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_C4_cmpltei,"iiIi","")
+BUILTIN(__builtin_HEXAGON_C4_cmplteu,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_vsubb_map,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_subh_l16_ll,"iii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_i_r_rnd,"iiUIi","")
+BUILTIN(__builtin_HEXAGON_M2_vrmpy_s0,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_hh_s1,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_hh_s0,"LLiii","")
+BUILTIN(__builtin_HEXAGON_A2_minup,"ULLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_valignrb,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_r_p_acc,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_M2_mmpyl_rs0,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vrcmaci_s0,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vaddub,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_combine_lh,"iii","")
+BUILTIN(__builtin_HEXAGON_M5_vdmacbsu,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_combine_ll,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_hl_s0,"ULLiii","")
+BUILTIN(__builtin_HEXAGON_M2_vrcmpyi_s0c,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_asr_i_p_rnd,"LLiLLiUIi","")
+BUILTIN(__builtin_HEXAGON_A2_addpsat,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_svaddhs,"iii","")
+BUILTIN(__builtin_HEXAGON_S4_ori_lsr_ri,"iUIiiUIi","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_ll_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_ll_s0,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_vminw,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vminh,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vrcmpyr_s0,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vminb,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vcmac_s0_sat_i,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_lh_s0,"ULLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_lh_s1,"ULLiii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_r_r_or,"iiii","")
+BUILTIN(__builtin_HEXAGON_S4_lsli,"iIii","")
+BUILTIN(__builtin_HEXAGON_S2_lsl_r_vw,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_hh_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_M4_vrmpyeh_s0,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M4_vrmpyeh_s1,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_nac_lh_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_nac_lh_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_vraddh,"iLLiLLi","")
+BUILTIN(__builtin_HEXAGON_C2_tfrrp,"ii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_ll_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_ll_s1,"iiii","")
BUILTIN(__builtin_HEXAGON_S2_vtrunowh,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_S2_vtrunehb,"iLLi","")
-BUILTIN(__builtin_HEXAGON_S2_vsxthw,"LLii","")
-BUILTIN(__builtin_HEXAGON_S2_vzxthw,"LLii","")
-BUILTIN(__builtin_HEXAGON_S2_vsatwh,"iLLi","")
+BUILTIN(__builtin_HEXAGON_A2_abs,"ii","")
+BUILTIN(__builtin_HEXAGON_A4_cmpbeq,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_negp,"LLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_asl_i_r_sat,"iiUIi","")
+BUILTIN(__builtin_HEXAGON_A2_addh_l16_sat_hl,"iii","")
BUILTIN(__builtin_HEXAGON_S2_vsatwuh,"iLLi","")
-BUILTIN(__builtin_HEXAGON_S2_packhl,"LLiii","")
-BUILTIN(__builtin_HEXAGON_A2_swiz,"ii","")
-BUILTIN(__builtin_HEXAGON_S2_vsathub_nopack,"LLiLLi","")
-BUILTIN(__builtin_HEXAGON_S2_vsathb_nopack,"LLiLLi","")
-BUILTIN(__builtin_HEXAGON_S2_vsatwh_nopack,"LLiLLi","")
-BUILTIN(__builtin_HEXAGON_S2_vsatwuh_nopack,"LLiLLi","")
-BUILTIN(__builtin_HEXAGON_S2_shuffob,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_F2_dfcmpgt,"idd","")
+BUILTIN(__builtin_HEXAGON_S2_svsathb,"ii","")
+BUILTIN(__builtin_HEXAGON_C2_cmpgtup,"iLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A4_cround_ri,"iiUIi","")
+BUILTIN(__builtin_HEXAGON_S4_clbpaddi,"iLLiIi","")
+BUILTIN(__builtin_HEXAGON_A4_cround_rr,"iii","")
+BUILTIN(__builtin_HEXAGON_C2_mux,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_dpmpyuu_s0,"ULLiii","")
BUILTIN(__builtin_HEXAGON_S2_shuffeb,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_S2_shuffoh,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_S2_shuffeh,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_S5_popcountp,"iLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vminuw,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vaddhs,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_insert_rp,"iiiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vminuh,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vminub,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_extractu,"iiUIiUIi","")
+BUILTIN(__builtin_HEXAGON_A2_svsubh,"iii","")
+BUILTIN(__builtin_HEXAGON_S4_clbaddi,"iiIi","")
+BUILTIN(__builtin_HEXAGON_F2_sffms,"ffff","")
+BUILTIN(__builtin_HEXAGON_S2_vsxtbh,"LLii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_ll_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_ll_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_A2_subp,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vmpy2es_s1,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vmpy2es_s0,"LLiLLiLLi","")
BUILTIN(__builtin_HEXAGON_S4_parity,"iii","")
-BUILTIN(__builtin_HEXAGON_S2_parityp,"iLLiLLi","")
-BUILTIN(__builtin_HEXAGON_S2_lfsp,"LLiLLiLLi","")
-BUILTIN(__builtin_HEXAGON_S2_clbnorm,"ii","")
-BUILTIN(__builtin_HEXAGON_S4_clbaddi,"iii","")
-BUILTIN(__builtin_HEXAGON_S4_clbpnorm,"iLLi","")
-BUILTIN(__builtin_HEXAGON_S4_clbpaddi,"iLLii","")
-BUILTIN(__builtin_HEXAGON_S2_clb,"ii","")
-BUILTIN(__builtin_HEXAGON_S2_cl0,"ii","")
-BUILTIN(__builtin_HEXAGON_S2_cl1,"ii","")
-BUILTIN(__builtin_HEXAGON_S2_clbp,"iLLi","")
-BUILTIN(__builtin_HEXAGON_S2_cl0p,"iLLi","")
-BUILTIN(__builtin_HEXAGON_S2_cl1p,"iLLi","")
-BUILTIN(__builtin_HEXAGON_S2_brev,"ii","")
-BUILTIN(__builtin_HEXAGON_S2_brevp,"LLiLLi","")
-BUILTIN(__builtin_HEXAGON_S2_ct0,"ii","")
-BUILTIN(__builtin_HEXAGON_S2_ct1,"ii","")
-BUILTIN(__builtin_HEXAGON_S2_ct0p,"iLLi","")
-BUILTIN(__builtin_HEXAGON_S2_ct1p,"iLLi","")
-BUILTIN(__builtin_HEXAGON_S2_interleave,"LLiLLi","")
-BUILTIN(__builtin_HEXAGON_S2_deinterleave,"LLiLLi","")
-BUILTIN(__builtin_HEXAGON_prefetch,"vv*","")
-BUILTIN(__builtin_HEXAGON_Y2_dccleana,"vv*","")
-BUILTIN(__builtin_HEXAGON_Y2_dccleaninva,"vv*","")
-BUILTIN(__builtin_HEXAGON_Y2_dcinva,"vv*","")
-BUILTIN(__builtin_HEXAGON_Y2_dczeroa,"vv*","")
-BUILTIN(__builtin_HEXAGON_Y4_l2fetch,"vv*Ui","")
-BUILTIN(__builtin_HEXAGON_Y5_l2fetch,"vv*LLUi","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_acc_hh_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_acc_hh_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_S4_addi_asl_ri,"iUIiiUIi","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_hh_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_hh_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_i_r_nac,"iiiUIi","")
+BUILTIN(__builtin_HEXAGON_A4_cmpheqi,"iiIi","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_r_p_xor,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_acc_hl_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_acc_hl_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_F2_conv_sf2ud_chop,"LLif","")
+BUILTIN(__builtin_HEXAGON_C2_cmpgeui,"iiUIi","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_hh_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_hh_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_r_p_and,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_A2_addh_h16_sat_lh,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_addh_h16_sat_ll,"iii","")
+BUILTIN(__builtin_HEXAGON_M4_nac_up_s1_sat,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_lh_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_lh_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_A4_round_ri_sat,"iiUIi","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_nac_hl_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_nac_hl_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_A2_vavghcr,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmacls_rs0,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmacls_rs1,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_cmaci_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_S2_setbit_i,"iiUIi","")
+BUILTIN(__builtin_HEXAGON_S2_asl_i_p_or,"LLiLLiLLiUIi","")
+BUILTIN(__builtin_HEXAGON_A4_andn,"iii","")
+BUILTIN(__builtin_HEXAGON_M5_vrmpybsu,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_vrndpackwh,"iLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vcmac_s0_sat_r,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vmaxuw,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_C2_bitsclr,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_xor_xacc,"iiii","")
+BUILTIN(__builtin_HEXAGON_A4_vcmpbgtui,"iLLiUIi","")
+BUILTIN(__builtin_HEXAGON_A4_ornp,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_tfrpi,"LLiIi","")
+BUILTIN(__builtin_HEXAGON_C4_and_or,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_hh_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_hh_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_A2_subh_h16_sat_ll,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_subh_h16_sat_lh,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_vmpy2su_s1,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_vmpy2su_s0,"LLiii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_i_p_acc,"LLiLLiLLiUIi","")
+BUILTIN(__builtin_HEXAGON_C4_nbitsclri,"iiUIi","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_i_vh,"LLiLLiUIi","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_i_p_xacc,"LLiLLiLLiUIi","")
+
+// V55 Scalar Instructions.
+
+BUILTIN(__builtin_HEXAGON_A5_ACS,"LLiLLiLLiLLi","")
+
+// V60 Scalar Instructions.
+
+BUILTIN(__builtin_HEXAGON_S6_rol_i_p_and,"LLiLLiLLiUIi","")
+BUILTIN(__builtin_HEXAGON_S6_rol_i_r_xacc,"iiiUIi","")
+BUILTIN(__builtin_HEXAGON_S6_rol_i_r_and,"iiiUIi","")
+BUILTIN(__builtin_HEXAGON_S6_rol_i_r_acc,"iiiUIi","")
+BUILTIN(__builtin_HEXAGON_S6_rol_i_p_xacc,"LLiLLiLLiUIi","")
+BUILTIN(__builtin_HEXAGON_S6_rol_i_p,"LLiLLiUIi","")
+BUILTIN(__builtin_HEXAGON_S6_rol_i_p_nac,"LLiLLiLLiUIi","")
+BUILTIN(__builtin_HEXAGON_S6_rol_i_p_acc,"LLiLLiLLiUIi","")
+BUILTIN(__builtin_HEXAGON_S6_rol_i_r_or,"iiiUIi","")
+BUILTIN(__builtin_HEXAGON_S6_rol_i_r,"iiUIi","")
+BUILTIN(__builtin_HEXAGON_S6_rol_i_r_nac,"iiiUIi","")
+BUILTIN(__builtin_HEXAGON_S6_rol_i_p_or,"LLiLLiLLiUIi","")
+
+// V62 Scalar Instructions.
+
+BUILTIN(__builtin_HEXAGON_S6_vtrunehb_ppp,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_V6_ldntnt0,"V16ii","")
+BUILTIN(__builtin_HEXAGON_M6_vabsdiffub,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S6_vtrunohb_ppp,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M6_vabsdiffb,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A6_vminub_RdP,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S6_vsplatrbp,"LLii","")
+
+// V65 Scalar Instructions.
+
+BUILTIN(__builtin_HEXAGON_A6_vcmpbeq_notany,"iLLiLLi","")
+
+// V66 Scalar Instructions.
+
+BUILTIN(__builtin_HEXAGON_F2_dfsub,"ddd","")
+BUILTIN(__builtin_HEXAGON_F2_dfadd,"ddd","")
+BUILTIN(__builtin_HEXAGON_M2_mnaci,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_mask,"iUIiUIi","")
-BUILTIN(__builtin_HEXAGON_S6_rol_i_r,"iii","v:60:")
-BUILTIN(__builtin_HEXAGON_S6_rol_i_p,"LLiLLii","v:60:")
-BUILTIN(__builtin_HEXAGON_S6_rol_i_r_acc,"iiii","v:60:")
-BUILTIN(__builtin_HEXAGON_S6_rol_i_p_acc,"LLiLLiLLii","v:60:")
-BUILTIN(__builtin_HEXAGON_S6_rol_i_r_nac,"iiii","v:60:")
-BUILTIN(__builtin_HEXAGON_S6_rol_i_p_nac,"LLiLLiLLii","v:60:")
-BUILTIN(__builtin_HEXAGON_S6_rol_i_r_xacc,"iiii","v:60:")
-BUILTIN(__builtin_HEXAGON_S6_rol_i_p_xacc,"LLiLLiLLii","v:60:")
-BUILTIN(__builtin_HEXAGON_S6_rol_i_r_and,"iiii","v:60:")
-BUILTIN(__builtin_HEXAGON_S6_rol_i_r_or,"iiii","v:60:")
-BUILTIN(__builtin_HEXAGON_S6_rol_i_p_and,"LLiLLiLLii","v:60:")
-BUILTIN(__builtin_HEXAGON_S6_rol_i_p_or,"LLiLLiLLii","v:60:")
-BUILTIN(__builtin_HEXAGON_S2_cabacencbin,"LLiLLiLLii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_valignb,"V16iV16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_valignb_128B,"V32iV32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vlalignb,"V16iV16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vlalignb_128B,"V32iV32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_valignbi,"V16iV16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_valignbi_128B,"V32iV32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vlalignbi,"V16iV16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vlalignbi_128B,"V32iV32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vror,"V16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vror_128B,"V32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vunpackub,"V32iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vunpackub_128B,"V64iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vunpackb,"V32iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vunpackb_128B,"V64iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vunpackuh,"V32iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vunpackuh_128B,"V64iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vunpackh,"V32iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vunpackh_128B,"V64iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vunpackob,"V32iV32iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vunpackob_128B,"V64iV64iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vunpackoh,"V32iV32iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vunpackoh_128B,"V64iV64iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vpackeb,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vpackeb_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vpackeh,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vpackeh_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vpackob,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vpackob_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vpackoh,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vpackoh_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vpackhub_sat,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vpackhub_sat_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vpackhb_sat,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vpackhb_sat_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vpackwuh_sat,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vpackwuh_sat_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vpackwh_sat,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vpackwh_sat_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vzb,"V32iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vzb_128B,"V64iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsb,"V32iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsb_128B,"V64iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vzh,"V32iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vzh_128B,"V64iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsh,"V32iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsh_128B,"V64iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdmpybus,"V16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdmpybus_128B,"V32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdmpybus_acc,"V16iV16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdmpybus_acc_128B,"V32iV32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdmpybus_dv,"V32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdmpybus_dv_128B,"V64iV64ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdmpybus_dv_acc,"V32iV32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdmpybus_dv_acc_128B,"V64iV64iV64ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdmpyhb,"V16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_128B,"V32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_acc,"V16iV16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_acc_128B,"V32iV32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_dv,"V32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_dv_128B,"V64iV64ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_dv_acc,"V32iV32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_dv_acc_128B,"V64iV64iV64ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdmpyhvsat,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdmpyhvsat_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdmpyhvsat_acc,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdmpyhvsat_acc_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdmpyhsat,"V16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdmpyhsat_128B,"V32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdmpyhsat_acc,"V16iV16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdmpyhsat_acc_128B,"V32iV32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdmpyhisat,"V16iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdmpyhisat_128B,"V32iV64ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdmpyhisat_acc,"V16iV16iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdmpyhisat_acc_128B,"V32iV32iV64ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdmpyhsusat,"V16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdmpyhsusat_128B,"V32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdmpyhsusat_acc,"V16iV16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdmpyhsusat_acc_128B,"V32iV32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdmpyhsuisat,"V16iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdmpyhsuisat_128B,"V32iV64ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdmpyhsuisat_acc,"V16iV16iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdmpyhsuisat_acc_128B,"V32iV32iV64ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vtmpyb,"V32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vtmpyb_128B,"V64iV64ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vtmpyb_acc,"V32iV32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vtmpyb_acc_128B,"V64iV64iV64ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vtmpybus,"V32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vtmpybus_128B,"V64iV64ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vtmpybus_acc,"V32iV32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vtmpybus_acc_128B,"V64iV64iV64ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vtmpyhb,"V32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vtmpyhb_128B,"V64iV64ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vtmpyhb_acc,"V32iV32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vtmpyhb_acc_128B,"V64iV64iV64ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vrmpyub,"V16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vrmpyub_128B,"V32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vrmpyub_acc,"V16iV16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vrmpyub_acc_128B,"V32iV32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vrmpyubv,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vrmpyubv_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vrmpyubv_acc,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vrmpyubv_acc_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vrmpybv,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vrmpybv_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vrmpybv_acc,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vrmpybv_acc_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vrmpyubi,"V32iV32iii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vrmpyubi_128B,"V64iV64iii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vrmpyubi_acc,"V32iV32iV32iii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vrmpyubi_acc_128B,"V64iV64iV64iii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vrmpybus,"V16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vrmpybus_128B,"V32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vrmpybus_acc,"V16iV16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vrmpybus_acc_128B,"V32iV32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vrmpybusi,"V32iV32iii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vrmpybusi_128B,"V64iV64iii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vrmpybusi_acc,"V32iV32iV32iii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vrmpybusi_acc_128B,"V64iV64iV64iii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vrmpybusv,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vrmpybusv_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vrmpybusv_acc,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vrmpybusv_acc_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdsaduh,"V32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdsaduh_128B,"V64iV64ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdsaduh_acc,"V32iV32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdsaduh_acc_128B,"V64iV64iV64ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vrsadubi,"V32iV32iii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vrsadubi_128B,"V64iV64iii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vrsadubi_acc,"V32iV32iV32iii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vrsadubi_acc_128B,"V64iV64iV64iii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vasrw,"V16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vasrw_128B,"V32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaslw,"V16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaslw_128B,"V32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vlsrw,"V16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vlsrw_128B,"V32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vasrwv,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vasrwv_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaslwv,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaslwv_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vlsrwv,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vlsrwv_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vasrh,"V16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vasrh_128B,"V32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaslh,"V16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaslh_128B,"V32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vlsrh,"V16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vlsrh_128B,"V32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vasrhv,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vasrhv_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaslhv,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaslhv_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vlsrhv,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vlsrhv_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vasrwh,"V16iV16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vasrwh_128B,"V32iV32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vasrwhsat,"V16iV16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vasrwhsat_128B,"V32iV32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vasrwhrndsat,"V16iV16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vasrwhrndsat_128B,"V32iV32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vasrwuhsat,"V16iV16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vasrwuhsat_128B,"V32iV32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vroundwh,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vroundwh_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vroundwuh,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vroundwuh_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vasrhubsat,"V16iV16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vasrhubsat_128B,"V32iV32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vasrhubrndsat,"V16iV16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vasrhubrndsat_128B,"V32iV32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vasrhbrndsat,"V16iV16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vasrhbrndsat_128B,"V32iV32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vroundhb,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vroundhb_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vroundhub,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vroundhub_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaslw_acc,"V16iV16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaslw_acc_128B,"V32iV32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vasrw_acc,"V16iV16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vasrw_acc_128B,"V32iV32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddb,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddb_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubb,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubb_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddb_dv,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddb_dv_128B,"V64iV64iV64i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubb_dv,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubb_dv_128B,"V64iV64iV64i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddh,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddh_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubh,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubh_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddh_dv,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddh_dv_128B,"V64iV64iV64i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubh_dv,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubh_dv_128B,"V64iV64iV64i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddw,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddw_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubw,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubw_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddw_dv,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddw_dv_128B,"V64iV64iV64i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubw_dv,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubw_dv_128B,"V64iV64iV64i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddubsat,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddubsat_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddubsat_dv,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddubsat_dv_128B,"V64iV64iV64i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsububsat,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsububsat_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsububsat_dv,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsububsat_dv_128B,"V64iV64iV64i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vadduhsat,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vadduhsat_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vadduhsat_dv,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vadduhsat_dv_128B,"V64iV64iV64i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubuhsat,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubuhsat_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubuhsat_dv,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubuhsat_dv_128B,"V64iV64iV64i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddhsat,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddhsat_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddhsat_dv,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddhsat_dv_128B,"V64iV64iV64i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubhsat,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubhsat_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubhsat_dv,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubhsat_dv_128B,"V64iV64iV64i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddwsat,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddwsat_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddwsat_dv,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddwsat_dv_128B,"V64iV64iV64i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubwsat,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubwsat_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubwsat_dv,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubwsat_dv_128B,"V64iV64iV64i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vavgub,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vavgub_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vavgubrnd,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vavgubrnd_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vavguh,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vavguh_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vavguhrnd,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vavguhrnd_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vavgh,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vavgh_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vavghrnd,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vavghrnd_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vnavgh,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vnavgh_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vavgw,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vavgw_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vavgwrnd,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vavgwrnd_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vnavgw,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vnavgw_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vabsdiffub,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vabsdiffub_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vabsdiffuh,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vabsdiffuh_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vabsdiffh,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vabsdiffh_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vabsdiffw,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vabsdiffw_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vnavgub,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vnavgub_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddubh,"V32iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddubh_128B,"V64iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsububh,"V32iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsububh_128B,"V64iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddhw,"V32iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddhw_128B,"V64iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubhw,"V32iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubhw_128B,"V64iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vadduhw,"V32iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vadduhw_128B,"V64iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubuhw,"V32iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubuhw_128B,"V64iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vd0,"V16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vd0_128B,"V32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddbq,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddbq_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubbq,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubbq_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddbnq,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddbnq_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubbnq,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubbnq_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddhq,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddhq_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubhq,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubhq_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddhnq,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddhnq_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubhnq,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubhnq_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddwq,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddwq_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubwq,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubwq_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddwnq,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vaddwnq_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubwnq,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsubwnq_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vabsh,"V16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vabsh_128B,"V32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vabsh_sat,"V16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vabsh_sat_128B,"V32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vabsw,"V16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vabsw_128B,"V32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vabsw_sat,"V16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vabsw_sat_128B,"V32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpybv,"V32iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpybv_128B,"V64iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpybv_acc,"V32iV32iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpybv_acc_128B,"V64iV64iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyubv,"V32iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyubv_128B,"V64iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyubv_acc,"V32iV32iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyubv_acc_128B,"V64iV64iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpybusv,"V32iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpybusv_128B,"V64iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpybusv_acc,"V32iV32iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpybusv_acc_128B,"V64iV64iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpabusv,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpabusv_128B,"V64iV64iV64i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpabuuv,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpabuuv_128B,"V64iV64iV64i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyhv,"V32iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyhv_128B,"V64iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyhv_acc,"V32iV32iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyhv_acc_128B,"V64iV64iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyuhv,"V32iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyuhv_128B,"V64iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyuhv_acc,"V32iV32iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyuhv_acc_128B,"V64iV64iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyhvsrs,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyhvsrs_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyhus,"V32iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyhus_128B,"V64iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyhus_acc,"V32iV32iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyhus_acc_128B,"V64iV64iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyih,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyih_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyih_acc,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyih_acc_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyewuh,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyewuh_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyowh,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyowh_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyowh_rnd,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyowh_rnd_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyowh_sacc,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyowh_sacc_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyowh_rnd_sacc,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyowh_rnd_sacc_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyieoh,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyieoh_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyiewuh,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyiewuh_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyiowh,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyiowh_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyiewh_acc,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyiewh_acc_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyiewuh_acc,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyiewuh_acc_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyub,"V32iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyub_128B,"V64iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyub_acc,"V32iV32iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyub_acc_128B,"V64iV64iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpybus,"V32iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpybus_128B,"V64iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpybus_acc,"V32iV32iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpybus_acc_128B,"V64iV64iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpabus,"V32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpabus_128B,"V64iV64ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpabus_acc,"V32iV32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpabus_acc_128B,"V64iV64iV64ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpahb,"V32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpahb_128B,"V64iV64ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpahb_acc,"V32iV32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpahb_acc_128B,"V64iV64iV64ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyh,"V32iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyh_128B,"V64iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyhsat_acc,"V32iV32iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyhsat_acc_128B,"V64iV64iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyhss,"V16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyhss_128B,"V32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyhsrs,"V16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyhsrs_128B,"V32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyuh,"V32iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyuh_128B,"V64iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyuh_acc,"V32iV32iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyuh_acc_128B,"V64iV64iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyihb,"V16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyihb_128B,"V32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyihb_acc,"V16iV16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyihb_acc_128B,"V32iV32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyiwb,"V16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyiwb_128B,"V32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyiwb_acc,"V16iV16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyiwb_acc_128B,"V32iV32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyiwh,"V16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyiwh_128B,"V32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyiwh_acc,"V16iV16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyiwh_acc_128B,"V32iV32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vand,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vand_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vor,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vor_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vxor,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vxor_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vnot,"V16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vnot_128B,"V32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vandqrt,"V16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vandqrt_128B,"V32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vandqrt_acc,"V16iV16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vandqrt_acc_128B,"V32iV32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vandvrt,"V16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vandvrt_128B,"V32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vandvrt_acc,"V16iV16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vandvrt_acc_128B,"V32iV32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtw,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtw_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtw_and,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtw_and_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtw_or,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtw_or_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtw_xor,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtw_xor_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_veqw,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_veqw_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_veqw_and,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_veqw_and_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_veqw_or,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_veqw_or_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_veqw_xor,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_veqw_xor_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgth,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgth_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgth_and,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgth_and_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgth_or,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgth_or_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgth_xor,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgth_xor_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_veqh,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_veqh_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_veqh_and,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_veqh_and_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_veqh_or,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_veqh_or_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_veqh_xor,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_veqh_xor_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtb,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtb_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtb_and,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtb_and_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtb_or,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtb_or_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtb_xor,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtb_xor_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_veqb,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_veqb_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_veqb_and,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_veqb_and_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_veqb_or,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_veqb_or_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_veqb_xor,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_veqb_xor_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtuw,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtuw_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtuw_and,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtuw_and_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtuw_or,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtuw_or_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtuw_xor,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtuw_xor_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtuh,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtuh_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtuh_and,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtuh_and_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtuh_or,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtuh_or_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtuh_xor,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtuh_xor_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtub,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtub_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtub_and,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtub_and_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtub_or,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtub_or_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtub_xor,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vgtub_xor_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_pred_or,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_pred_or_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_pred_and,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_pred_and_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_pred_not,"V16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_pred_not_128B,"V32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_pred_xor,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_pred_xor_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_pred_and_n,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_pred_and_n_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_pred_or_n,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_pred_or_n_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_pred_scalar2,"V16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_pred_scalar2_128B,"V32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmux,"V16iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmux_128B,"V32iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vswap,"V32iV16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vswap_128B,"V64iV32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmaxub,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmaxub_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vminub,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vminub_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmaxuh,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmaxuh_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vminuh,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vminuh_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmaxh,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmaxh_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vminh,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vminh_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmaxw,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmaxw_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vminw,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vminw_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsathub,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsathub_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsatwh,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vsatwh_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vshuffeb,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vshuffeb_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vshuffob,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vshuffob_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vshufeh,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vshufeh_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vshufoh,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vshufoh_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vshuffvdd,"V32iV16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vshuffvdd_128B,"V64iV32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdealvdd,"V32iV16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdealvdd_128B,"V64iV32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vshufoeh,"V32iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vshufoeh_128B,"V64iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vshufoeb,"V32iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vshufoeb_128B,"V64iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdealh,"V16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdealh_128B,"V32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdealb,"V16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdealb_128B,"V32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdealb4w,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdealb4w_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vshuffh,"V16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vshuffh_128B,"V32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vshuffb,"V16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vshuffb_128B,"V32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_extractw,"iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_extractw_128B,"iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vinsertwr,"V16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vinsertwr_128B,"V32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_lvsplatw,"V16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_lvsplatw_128B,"V32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vassign,"V16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vassign_128B,"V32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vcombine,"V32iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vcombine_128B,"V64iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdelta,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vdelta_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vrdelta,"V16iV16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vrdelta_128B,"V32iV32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vcl0w,"V16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vcl0w_128B,"V32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vcl0h,"V16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vcl0h_128B,"V32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vnormamtw,"V16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vnormamtw_128B,"V32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vnormamth,"V16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vnormamth_128B,"V32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vpopcounth,"V16iV16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vpopcounth_128B,"V32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vlutvvb,"V16iV16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vlutvvb_128B,"V32iV32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vlutvvb_oracc,"V16iV16iV16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vlutvvb_oracc_128B,"V32iV32iV32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vlutvwh,"V32iV16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vlutvwh_128B,"V64iV32iV32ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vlutvwh_oracc,"V32iV32iV16iV16ii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vlutvwh_oracc_128B,"V64iV64iV32iV32ii","v:60:")
+// V60 HVX Instructions.
-BUILTIN(__builtin_HEXAGON_V6_hi,"V16iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_lo,"V16iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_hi_128B,"V32iV64i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_lo_128B,"V32iV64i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vassignp,"V32iV32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vassignp_128B,"V64iV64i","v:60:")
+BUILTIN(__builtin_HEXAGON_V6_veqb_or,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_veqb_or_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vminub,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vminub_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vaslw_acc,"V16iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vaslw_acc_128B,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyhvsrs,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyhvsrs_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vsathub,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vsathub_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddh_dv,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddh_dv_128B,"V64iV64iV64i","")
+BUILTIN(__builtin_HEXAGON_V6_vrmpybusi,"V32iV32iiUIi","")
+BUILTIN(__builtin_HEXAGON_V6_vrmpybusi_128B,"V64iV64iiUIi","")
+BUILTIN(__builtin_HEXAGON_V6_vshufoh,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vshufoh_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vasrwv,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vasrwv_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vdmpyhsuisat,"V16iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vdmpyhsuisat_128B,"V32iV64ii","")
+BUILTIN(__builtin_HEXAGON_V6_vrsadubi_acc,"V32iV32iV32iiUIi","")
+BUILTIN(__builtin_HEXAGON_V6_vrsadubi_acc_128B,"V64iV64iV64iiUIi","")
+BUILTIN(__builtin_HEXAGON_V6_vnavgw,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vnavgw_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vnavgh,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vnavgh_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vavgub,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vavgub_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vsubb,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vsubb_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vgtw_and,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vgtw_and_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vavgubrnd,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vavgubrnd_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vrmpybusv,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vrmpybusv_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vsubbnq,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vsubbnq_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vroundhb,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vroundhb_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vadduhsat_dv,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vadduhsat_dv_128B,"V64iV64iV64i","")
+BUILTIN(__builtin_HEXAGON_V6_vsububsat,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vsububsat_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpabus_acc,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpabus_acc_128B,"V64iV64iV64ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmux,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vmux_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyhus,"V32iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyhus_128B,"V64iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vpackeb,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vpackeb_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vsubhnq,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vsubhnq_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vavghrnd,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vavghrnd_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vtran2x2_map,"V16iV16iv*i","")
+BUILTIN(__builtin_HEXAGON_V6_vtran2x2_map_128B,"V32iV32iv*i","")
+BUILTIN(__builtin_HEXAGON_V6_vdelta,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vdelta_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vgtuh_and,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vgtuh_and_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vtmpyhb,"V32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vtmpyhb_128B,"V64iV64ii","")
+BUILTIN(__builtin_HEXAGON_V6_vpackob,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vpackob_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmaxh,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vmaxh_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vtmpybus_acc,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vtmpybus_acc_128B,"V64iV64iV64ii","")
+BUILTIN(__builtin_HEXAGON_V6_vsubuhsat,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vsubuhsat_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vasrw_acc,"V16iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vasrw_acc_128B,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_pred_or,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_pred_or_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vrmpyub_acc,"V16iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vrmpyub_acc_128B,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_lo,"V16iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_lo_128B,"V32iV64i","")
+BUILTIN(__builtin_HEXAGON_V6_vsubb_dv,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vsubb_dv_128B,"V64iV64iV64i","")
+BUILTIN(__builtin_HEXAGON_V6_vsubhsat_dv,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vsubhsat_dv_128B,"V64iV64iV64i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyiwh,"V16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyiwh_128B,"V32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyiwb,"V16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyiwb_128B,"V32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_ldu0,"V16ii","")
+BUILTIN(__builtin_HEXAGON_V6_ldu0_128B,"V32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vgtuh_xor,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vgtuh_xor_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vgth_or,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vgth_or_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vavgh,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vavgh_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vlalignb,"V16iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vlalignb_128B,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vsh,"V32iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vsh_128B,"V64iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_pred_and_n,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_pred_and_n_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vsb,"V32iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vsb_128B,"V64iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vroundwuh,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vroundwuh_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vasrhv,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vasrhv_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vshuffh,"V16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vshuffh_128B,"V32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddhsat_dv,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddhsat_dv_128B,"V64iV64iV64i","")
+BUILTIN(__builtin_HEXAGON_V6_vnavgub,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vnavgub_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vrmpybv,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vrmpybv_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vnormamth,"V16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vnormamth_128B,"V32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vdmpyhb,"V16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_128B,"V32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vavguh,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vavguh_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vlsrwv,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vlsrwv_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vlsrhv,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vlsrhv_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vdmpyhisat,"V16iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vdmpyhisat_128B,"V32iV64ii","")
+BUILTIN(__builtin_HEXAGON_V6_vdmpyhvsat,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vdmpyhvsat_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddw,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddw_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vzh,"V32iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vzh_128B,"V64iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddh,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddh_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmaxub,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vmaxub_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyhv_acc,"V32iV32iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyhv_acc_128B,"V64iV64iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vadduhsat,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vadduhsat_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vshufoeh,"V32iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vshufoeh_128B,"V64iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyuhv_acc,"V32iV32iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyuhv_acc_128B,"V64iV64iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_veqh,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_veqh_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpabuuv,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpabuuv_128B,"V64iV64iV64i","")
+BUILTIN(__builtin_HEXAGON_V6_vasrwhsat,"V16iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vasrwhsat_128B,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vminuh,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vminuh_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vror,"V16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vror_128B,"V32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyowh_rnd_sacc,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyowh_rnd_sacc_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmaxuh,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vmaxuh_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vabsh_sat,"V16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vabsh_sat_128B,"V32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_pred_or_n,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_pred_or_n_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vdealb,"V16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vdealb_128B,"V32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpybusv,"V32iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpybusv_128B,"V64iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vzb,"V32iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vzb_128B,"V64iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vdmpybus_dv,"V32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vdmpybus_dv_128B,"V64iV64ii","")
+BUILTIN(__builtin_HEXAGON_V6_vaddbq,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddbq_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddb,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddb_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddwq,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddwq_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vasrhubrndsat,"V16iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vasrhubrndsat_128B,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vasrhubsat,"V16iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vasrhubsat_128B,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vshufoeb,"V32iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vshufoeb_128B,"V64iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vpackhub_sat,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vpackhub_sat_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyiwh_acc,"V16iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyiwh_acc_128B,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vtmpyb,"V32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vtmpyb_128B,"V64iV64ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpabusv,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpabusv_128B,"V64iV64iV64i","")
+BUILTIN(__builtin_HEXAGON_V6_pred_and,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_pred_and_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vsubwnq,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vsubwnq_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vpackwuh_sat,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vpackwuh_sat_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vswap,"V32iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vswap_128B,"V64iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vrmpyubv_acc,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vrmpyubv_acc_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vgtb_and,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vgtb_and_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vaslw,"V16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vaslw_128B,"V32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vpackhb_sat,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vpackhb_sat_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyih_acc,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyih_acc_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vshuffvdd,"V32iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vshuffvdd_128B,"V64iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vaddb_dv,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddb_dv_128B,"V64iV64iV64i","")
+BUILTIN(__builtin_HEXAGON_V6_vunpackub,"V32iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vunpackub_128B,"V64iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vgtuw,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vgtuw_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vlutvwh,"V32iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vlutvwh_128B,"V64iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vgtub,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vgtub_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyowh,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyowh_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyieoh,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyieoh_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_extractw,"iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_extractw_128B,"iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vavgwrnd,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vavgwrnd_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vdmpyhsat_acc,"V16iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vdmpyhsat_acc_128B,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vgtub_xor,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vgtub_xor_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyub,"V32iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyub_128B,"V64iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyuh,"V32iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyuh_128B,"V64iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vunpackob,"V32iV32iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vunpackob_128B,"V64iV64iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpahb,"V32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpahb_128B,"V64iV64ii","")
+BUILTIN(__builtin_HEXAGON_V6_veqw_or,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_veqw_or_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vandqrt,"V16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vandqrt_128B,"V32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vxor,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vxor_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vasrwhrndsat,"V16iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vasrwhrndsat_128B,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyhsat_acc,"V32iV32iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyhsat_acc_128B,"V64iV64iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vrmpybus_acc,"V16iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vrmpybus_acc_128B,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vsubhw,"V32iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vsubhw_128B,"V64iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vdealb4w,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vdealb4w_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyowh_sacc,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyowh_sacc_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpybv,"V32iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpybv_128B,"V64iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vabsdiffh,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vabsdiffh_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vshuffob,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vshuffob_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyub_acc,"V32iV32iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyub_acc_128B,"V64iV64iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vnormamtw,"V16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vnormamtw_128B,"V32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vunpackuh,"V32iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vunpackuh_128B,"V64iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vgtuh_or,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vgtuh_or_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyiewuh_acc,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyiewuh_acc_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vunpackoh,"V32iV32iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vunpackoh_128B,"V64iV64iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vdmpyhsat,"V16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vdmpyhsat_128B,"V32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyubv,"V32iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyubv_128B,"V64iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyhss,"V16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyhss_128B,"V32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_hi,"V16iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_hi_128B,"V32iV64i","")
+BUILTIN(__builtin_HEXAGON_V6_vasrwuhsat,"V16iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vasrwuhsat_128B,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_veqw,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_veqw_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vdsaduh,"V32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vdsaduh_128B,"V64iV64ii","")
+BUILTIN(__builtin_HEXAGON_V6_vsubw,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vsubw_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vsubw_dv,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vsubw_dv_128B,"V64iV64iV64i","")
+BUILTIN(__builtin_HEXAGON_V6_veqb_and,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_veqb_and_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyih,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyih_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vtmpyb_acc,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vtmpyb_acc_128B,"V64iV64iV64ii","")
+BUILTIN(__builtin_HEXAGON_V6_vrmpybus,"V16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vrmpybus_128B,"V32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpybus_acc,"V32iV32iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpybus_acc_128B,"V64iV64iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vgth_xor,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vgth_xor_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vsubhsat,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vsubhsat_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vrmpyubi_acc,"V32iV32iV32iiUIi","")
+BUILTIN(__builtin_HEXAGON_V6_vrmpyubi_acc_128B,"V64iV64iV64iiUIi","")
+BUILTIN(__builtin_HEXAGON_V6_vabsw,"V16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vabsw_128B,"V32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddwsat_dv,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddwsat_dv_128B,"V64iV64iV64i","")
+BUILTIN(__builtin_HEXAGON_V6_vlsrw,"V16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vlsrw_128B,"V32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vabsh,"V16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vabsh_128B,"V32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vlsrh,"V16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vlsrh_128B,"V32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_valignb,"V16iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_valignb_128B,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vsubhq,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vsubhq_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vpackoh,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vpackoh_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vdmpybus_acc,"V16iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vdmpybus_acc_128B,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vdmpyhvsat_acc,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vdmpyhvsat_acc_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vrmpybv_acc,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vrmpybv_acc_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddhsat,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddhsat_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vcombine,"V32iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vcombine_128B,"V64iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vandqrt_acc,"V16iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vandqrt_acc_128B,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vaslhv,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vaslhv_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vinsertwr,"V16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vinsertwr_128B,"V32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vsubh_dv,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vsubh_dv_128B,"V64iV64iV64i","")
+BUILTIN(__builtin_HEXAGON_V6_vshuffb,"V16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vshuffb_128B,"V32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vand,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vand_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyhv,"V32iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyhv_128B,"V64iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vdmpyhsuisat_acc,"V16iV16iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vdmpyhsuisat_acc_128B,"V32iV32iV64ii","")
+BUILTIN(__builtin_HEXAGON_V6_vsububsat_dv,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vsububsat_dv_128B,"V64iV64iV64i","")
+BUILTIN(__builtin_HEXAGON_V6_vgtb_xor,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vgtb_xor_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vdsaduh_acc,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vdsaduh_acc_128B,"V64iV64iV64ii","")
+BUILTIN(__builtin_HEXAGON_V6_vrmpyub,"V16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vrmpyub_128B,"V32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyuh_acc,"V32iV32iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyuh_acc_128B,"V64iV64iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vcl0h,"V16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vcl0h_128B,"V32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyhus_acc,"V32iV32iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyhus_acc_128B,"V64iV64iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpybv_acc,"V32iV32iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpybv_acc_128B,"V64iV64iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vrsadubi,"V32iV32iiUIi","")
+BUILTIN(__builtin_HEXAGON_V6_vrsadubi_128B,"V64iV64iiUIi","")
+BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_dv_acc,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_dv_acc_128B,"V64iV64iV64ii","")
+BUILTIN(__builtin_HEXAGON_V6_vshufeh,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vshufeh_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyewuh,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyewuh_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyhsrs,"V16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyhsrs_128B,"V32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vdmpybus_dv_acc,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vdmpybus_dv_acc_128B,"V64iV64iV64ii","")
+BUILTIN(__builtin_HEXAGON_V6_vaddubh,"V32iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddubh_128B,"V64iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vasrwh,"V16iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vasrwh_128B,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_ld0,"V16ii","")
+BUILTIN(__builtin_HEXAGON_V6_ld0_128B,"V32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vpopcounth,"V16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vpopcounth_128B,"V32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_ldnt0,"V16ii","")
+BUILTIN(__builtin_HEXAGON_V6_ldnt0_128B,"V32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vgth_and,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vgth_and_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddubsat_dv,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddubsat_dv_128B,"V64iV64iV64i","")
+BUILTIN(__builtin_HEXAGON_V6_vpackeh,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vpackeh_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyh,"V32iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyh_128B,"V64iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vminh,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vminh_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_pred_scalar2,"V16ii","")
+BUILTIN(__builtin_HEXAGON_V6_pred_scalar2_128B,"V32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vdealh,"V16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vdealh_128B,"V32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vpackwh_sat,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vpackwh_sat_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vaslh,"V16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vaslh_128B,"V32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vgtuw_and,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vgtuw_and_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vor,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vor_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vlutvvb,"V16iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vlutvvb_128B,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyiowh,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyiowh_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vlutvvb_oracc,"V16iV16iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vlutvvb_oracc_128B,"V32iV32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vandvrt,"V16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vandvrt_128B,"V32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_veqh_xor,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_veqh_xor_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vadduhw,"V32iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vadduhw_128B,"V64iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vcl0w,"V16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vcl0w_128B,"V32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyihb,"V16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyihb_128B,"V32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vtmpybus,"V32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vtmpybus_128B,"V64iV64ii","")
+BUILTIN(__builtin_HEXAGON_V6_vd0,"V16i","")
+BUILTIN(__builtin_HEXAGON_V6_vd0_128B,"V32i","")
+BUILTIN(__builtin_HEXAGON_V6_veqh_or,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_veqh_or_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vgtw_or,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vgtw_or_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vdmpybus,"V16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vdmpybus_128B,"V32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vgtub_or,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vgtub_or_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpybus,"V32iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpybus_128B,"V64iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_acc,"V16iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_acc_128B,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vandvrt_acc,"V16iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vandvrt_acc_128B,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vassign,"V16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vassign_128B,"V32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddwnq,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddwnq_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vgtub_and,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vgtub_and_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_dv,"V32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_dv_128B,"V64iV64ii","")
+BUILTIN(__builtin_HEXAGON_V6_vunpackb,"V32iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vunpackb_128B,"V64iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vunpackh,"V32iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vunpackh_128B,"V64iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpahb_acc,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpahb_acc_128B,"V64iV64iV64ii","")
+BUILTIN(__builtin_HEXAGON_V6_vaddbnq,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddbnq_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vlalignbi,"V16iV16iV16iUIi","")
+BUILTIN(__builtin_HEXAGON_V6_vlalignbi_128B,"V32iV32iV32iUIi","")
+BUILTIN(__builtin_HEXAGON_V6_vsatwh,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vsatwh_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vgtuh,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vgtuh_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyihb_acc,"V16iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyihb_acc_128B,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vrmpybusv_acc,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vrmpybusv_acc_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vrdelta,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vrdelta_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vroundwh,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vroundwh_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddw_dv,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddw_dv_128B,"V64iV64iV64i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyiwb_acc,"V16iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyiwb_acc_128B,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vsubbq,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vsubbq_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_veqh_and,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_veqh_and_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_valignbi,"V16iV16iV16iUIi","")
+BUILTIN(__builtin_HEXAGON_V6_valignbi_128B,"V32iV32iV32iUIi","")
+BUILTIN(__builtin_HEXAGON_V6_vaddwsat,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddwsat_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_veqw_and,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_veqw_and_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vabsdiffub,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vabsdiffub_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vshuffeb,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vshuffeb_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vabsdiffuh,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vabsdiffuh_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_veqw_xor,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_veqw_xor_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vgth,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vgth_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vgtuw_xor,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vgtuw_xor_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vgtb,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vgtb_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vgtw,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vgtw_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vsubwq,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vsubwq_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vnot,"V16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vnot_128B,"V32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vgtb_or,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vgtb_or_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vgtuw_or,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vgtuw_or_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddubsat,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddubsat_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmaxw,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vmaxw_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vaslwv,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vaslwv_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vabsw_sat,"V16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vabsw_sat_128B,"V32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vsubwsat_dv,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vsubwsat_dv_128B,"V64iV64iV64i","")
+BUILTIN(__builtin_HEXAGON_V6_vroundhub,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vroundhub_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vdmpyhisat_acc,"V16iV16iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vdmpyhisat_acc_128B,"V32iV32iV64ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpabus,"V32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpabus_128B,"V64iV64ii","")
+BUILTIN(__builtin_HEXAGON_V6_vassignp,"V32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vassignp_128B,"V64iV64i","")
+BUILTIN(__builtin_HEXAGON_V6_veqb,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_veqb_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vsububh,"V32iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vsububh_128B,"V64iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_lvsplatw,"V16ii","")
+BUILTIN(__builtin_HEXAGON_V6_lvsplatw_128B,"V32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vaddhnq,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddhnq_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vdmpyhsusat,"V16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vdmpyhsusat_128B,"V32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_pred_not,"V16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_pred_not_128B,"V32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vlutvwh_oracc,"V32iV32iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vlutvwh_oracc_128B,"V64iV64iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyiewh_acc,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyiewh_acc_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vdealvdd,"V32iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vdealvdd_128B,"V64iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vavgw,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vavgw_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vdmpyhsusat_acc,"V16iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vdmpyhsusat_acc_128B,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vgtw_xor,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vgtw_xor_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vtmpyhb_acc,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vtmpyhb_acc_128B,"V64iV64iV64ii","")
+BUILTIN(__builtin_HEXAGON_V6_vaddhw,"V32iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddhw_128B,"V64iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddhq,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddhq_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vrmpyubv,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vrmpyubv_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vsubh,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vsubh_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vrmpyubi,"V32iV32iiUIi","")
+BUILTIN(__builtin_HEXAGON_V6_vrmpyubi_128B,"V64iV64iiUIi","")
+BUILTIN(__builtin_HEXAGON_V6_vminw,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vminw_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyubv_acc,"V32iV32iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyubv_acc_128B,"V64iV64iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_pred_xor,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_pred_xor_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_veqb_xor,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_veqb_xor_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyiewuh,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyiewuh_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpybusv_acc,"V32iV32iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpybusv_acc_128B,"V64iV64iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vavguhrnd,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vavguhrnd_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyowh_rnd,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyowh_rnd_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vsubwsat,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vsubwsat_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vsubuhw,"V32iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vsubuhw_128B,"V64iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vrmpybusi_acc,"V32iV32iV32iiUIi","")
+BUILTIN(__builtin_HEXAGON_V6_vrmpybusi_acc_128B,"V64iV64iV64iiUIi","")
+BUILTIN(__builtin_HEXAGON_V6_vasrw,"V16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vasrw_128B,"V32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vasrh,"V16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vasrh_128B,"V32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyuhv,"V32iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyuhv_128B,"V64iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vasrhbrndsat,"V16iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vasrhbrndsat_128B,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vsubuhsat_dv,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vsubuhsat_dv_128B,"V64iV64iV64i","")
+BUILTIN(__builtin_HEXAGON_V6_vabsdiffw,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vabsdiffw_128B,"V32iV32iV32i","")
-BUILTIN(__builtin_HEXAGON_V6_vS32b_qpred_ai,"vV16iv*V16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vS32b_nqpred_ai,"vV16iv*V16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vS32b_nt_qpred_ai,"vV16iv*V16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vS32b_nt_nqpred_ai,"vV16iv*V16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vS32b_qpred_ai_128B,"vV32iv*V32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vS32b_nqpred_ai_128B,"vV32iv*V32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vS32b_nt_qpred_ai_128B,"vV32iv*V32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vS32b_nt_nqpred_ai_128B,"vV32iv*V32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmaskedstoreq,"vV16iv*V16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmaskedstorenq,"vV16iv*V16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmaskedstorentq,"vV16iv*V16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmaskedstorentnq,"vV16iv*V16i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmaskedstoreq_128B,"vV32iv*V32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmaskedstorenq_128B,"vV32iv*V32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmaskedstorentq_128B,"vV32iv*V32i","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vmaskedstorentnq_128B,"vV32iv*V32i","v:60:")
+// V62 HVX Instructions.
-BUILTIN(__builtin_HEXAGON_M6_vabsdiffb,"LLiLLiLLi","v:62:")
-BUILTIN(__builtin_HEXAGON_M6_vabsdiffub,"LLiLLiLLi","v:62:")
-BUILTIN(__builtin_HEXAGON_A6_vminub_RdP,"LLiLLiLLi","v:62:")
-BUILTIN(__builtin_HEXAGON_S6_vsplatrbp,"LLii","v:62:")
-BUILTIN(__builtin_HEXAGON_S6_vtrunehb_ppp,"LLiLLiLLi","v:62:")
-BUILTIN(__builtin_HEXAGON_S6_vtrunohb_ppp,"LLiLLiLLi","v:62:")
+BUILTIN(__builtin_HEXAGON_V6_vandnqrt_acc,"V16iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vandnqrt_acc_128B,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vaddclbh,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddclbh_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyowh_64_acc,"V32iV32iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyowh_64_acc_128B,"V64iV64iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyewuh_64,"V32iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyewuh_64_128B,"V64iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vsatuwuh,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vsatuwuh_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_shuffeqh,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_shuffeqh_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_shuffeqw,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_shuffeqw_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_ldcnpnt0,"V16iii","")
+BUILTIN(__builtin_HEXAGON_V6_ldcnpnt0_128B,"V32iii","")
+BUILTIN(__builtin_HEXAGON_V6_vsubcarry,"V16iV16iV16iv*","")
+BUILTIN(__builtin_HEXAGON_V6_vsubcarry_128B,"V32iV32iV32iv*","")
+BUILTIN(__builtin_HEXAGON_V6_vasrhbsat,"V16iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vasrhbsat_128B,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vminb,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vminb_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpauhb_acc,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpauhb_acc_128B,"V64iV64iV64ii","")
+BUILTIN(__builtin_HEXAGON_V6_vaddhw_acc,"V32iV32iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddhw_acc_128B,"V64iV64iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vlsrb,"V16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vlsrb_128B,"V32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vlutvwhi,"V32iV16iV16iUIi","")
+BUILTIN(__builtin_HEXAGON_V6_vlutvwhi_128B,"V64iV32iV32iUIi","")
+BUILTIN(__builtin_HEXAGON_V6_vaddububb_sat,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddububb_sat_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vsubbsat_dv,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vsubbsat_dv_128B,"V64iV64iV64i","")
+BUILTIN(__builtin_HEXAGON_V6_ldtp0,"V16iii","")
+BUILTIN(__builtin_HEXAGON_V6_ldtp0_128B,"V32iii","")
+BUILTIN(__builtin_HEXAGON_V6_vlutvvb_oracci,"V16iV16iV16iV16iUIi","")
+BUILTIN(__builtin_HEXAGON_V6_vlutvvb_oracci_128B,"V32iV32iV32iV32iUIi","")
+BUILTIN(__builtin_HEXAGON_V6_vsubuwsat_dv,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vsubuwsat_dv_128B,"V64iV64iV64i","")
+BUILTIN(__builtin_HEXAGON_V6_ldpnt0,"V16iii","")
+BUILTIN(__builtin_HEXAGON_V6_ldpnt0_128B,"V32iii","")
+BUILTIN(__builtin_HEXAGON_V6_vandvnqv,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vandvnqv_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_lvsplatb,"V16ii","")
+BUILTIN(__builtin_HEXAGON_V6_lvsplatb_128B,"V32ii","")
+BUILTIN(__builtin_HEXAGON_V6_lvsplath,"V16ii","")
+BUILTIN(__builtin_HEXAGON_V6_lvsplath_128B,"V32ii","")
+BUILTIN(__builtin_HEXAGON_V6_ldtpnt0,"V16iii","")
+BUILTIN(__builtin_HEXAGON_V6_ldtpnt0_128B,"V32iii","")
+BUILTIN(__builtin_HEXAGON_V6_vlutvwh_nm,"V32iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vlutvwh_nm_128B,"V64iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_ldnpnt0,"V16iii","")
+BUILTIN(__builtin_HEXAGON_V6_ldnpnt0_128B,"V32iii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpauhb,"V32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpauhb_128B,"V64iV64ii","")
+BUILTIN(__builtin_HEXAGON_V6_ldtnp0,"V16iii","")
+BUILTIN(__builtin_HEXAGON_V6_ldtnp0_128B,"V32iii","")
+BUILTIN(__builtin_HEXAGON_V6_vrounduhub,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vrounduhub_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vadduhw_acc,"V32iV32iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vadduhw_acc_128B,"V64iV64iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_ldcp0,"V16iii","")
+BUILTIN(__builtin_HEXAGON_V6_ldcp0_128B,"V32iii","")
+BUILTIN(__builtin_HEXAGON_V6_vadduwsat,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vadduwsat_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_ldtnpnt0,"V16iii","")
+BUILTIN(__builtin_HEXAGON_V6_ldtnpnt0_128B,"V32iii","")
+BUILTIN(__builtin_HEXAGON_V6_vaddbsat,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddbsat_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vandnqrt,"V16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vandnqrt_128B,"V32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyiwub_acc,"V16iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyiwub_acc_128B,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmaxb,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vmaxb_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vandvqv,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vandvqv_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddcarry,"V16iV16iV16iv*","")
+BUILTIN(__builtin_HEXAGON_V6_vaddcarry_128B,"V32iV32iV32iv*","")
+BUILTIN(__builtin_HEXAGON_V6_vasrwuhrndsat,"V16iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vasrwuhrndsat_128B,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vlutvvbi,"V16iV16iV16iUIi","")
+BUILTIN(__builtin_HEXAGON_V6_vlutvvbi_128B,"V32iV32iV32iUIi","")
+BUILTIN(__builtin_HEXAGON_V6_vsubuwsat,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vsubuwsat_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddbsat_dv,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddbsat_dv_128B,"V64iV64iV64i","")
+BUILTIN(__builtin_HEXAGON_V6_ldnp0,"V16iii","")
+BUILTIN(__builtin_HEXAGON_V6_ldnp0_128B,"V32iii","")
+BUILTIN(__builtin_HEXAGON_V6_vasruwuhrndsat,"V16iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vasruwuhrndsat_128B,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vrounduwuh,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vrounduwuh_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vlutvvb_nm,"V16iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vlutvvb_nm_128B,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_pred_scalar2v2,"V16ii","")
+BUILTIN(__builtin_HEXAGON_V6_pred_scalar2v2_128B,"V32ii","")
+BUILTIN(__builtin_HEXAGON_V6_ldp0,"V16iii","")
+BUILTIN(__builtin_HEXAGON_V6_ldp0_128B,"V32iii","")
+BUILTIN(__builtin_HEXAGON_V6_vaddubh_acc,"V32iV32iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddubh_acc_128B,"V64iV64iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddclbw,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddclbw_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_ldcpnt0,"V16iii","")
+BUILTIN(__builtin_HEXAGON_V6_ldcpnt0_128B,"V32iii","")
+BUILTIN(__builtin_HEXAGON_V6_vadduwsat_dv,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vadduwsat_dv_128B,"V64iV64iV64i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyiwub,"V16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyiwub_128B,"V32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vsubububb_sat,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vsubububb_sat_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_ldcnp0,"V16iii","")
+BUILTIN(__builtin_HEXAGON_V6_ldcnp0_128B,"V32iii","")
+BUILTIN(__builtin_HEXAGON_V6_vlutvwh_oracci,"V32iV32iV16iV16iUIi","")
+BUILTIN(__builtin_HEXAGON_V6_vlutvwh_oracci_128B,"V64iV64iV32iV32iUIi","")
+BUILTIN(__builtin_HEXAGON_V6_vsubbsat,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vsubbsat_128B,"V32iV32iV32i","")
-BUILTIN(__builtin_HEXAGON_V6_vlsrb,"V16iV16ii","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vlsrb_128B,"V32iV32ii","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vasrwuhrndsat,"V16iV16iV16ii","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vasrwuhrndsat_128B,"V32iV32iV32ii","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vasruwuhrndsat,"V16iV16iV16ii","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vasruwuhrndsat_128B,"V32iV32iV32ii","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vasrhbsat,"V16iV16iV16ii","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vasrhbsat_128B,"V32iV32iV32ii","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vrounduwuh,"V16iV16iV16i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vrounduwuh_128B,"V32iV32iV32i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vrounduhub,"V16iV16iV16i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vrounduhub_128B,"V32iV32iV32i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vadduwsat,"V16iV16iV16i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vadduwsat_128B,"V32iV32iV32i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vadduwsat_dv,"V32iV32iV32i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vadduwsat_dv_128B,"V64iV64iV64i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vsubuwsat,"V16iV16iV16i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vsubuwsat_128B,"V32iV32iV32i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vsubuwsat_dv,"V32iV32iV32i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vsubuwsat_dv_128B,"V64iV64iV64i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vaddbsat,"V16iV16iV16i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vaddbsat_128B,"V32iV32iV32i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vaddbsat_dv,"V32iV32iV32i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vaddbsat_dv_128B,"V64iV64iV64i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vsubbsat,"V16iV16iV16i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vsubbsat_128B,"V32iV32iV32i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vsubbsat_dv,"V32iV32iV32i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vsubbsat_dv_128B,"V64iV64iV64i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vaddububb_sat,"V16iV16iV16i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vaddububb_sat_128B,"V32iV32iV32i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vsubububb_sat,"V16iV16iV16i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vsubububb_sat_128B,"V32iV32iV32i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vaddhw_acc,"V32iV32iV16iV16i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vaddhw_acc_128B,"V64iV64iV32iV32i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vadduhw_acc,"V32iV32iV16iV16i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vadduhw_acc_128B,"V64iV64iV32iV32i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vaddubh_acc,"V32iV32iV16iV16i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vaddubh_acc_128B,"V64iV64iV32iV32i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyewuh_64,"V32iV16iV16i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyewuh_64_128B,"V64iV32iV32i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyowh_64_acc,"V32iV32iV16iV16i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyowh_64_acc_128B,"V64iV64iV32iV32i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vmpauhb,"V32iV32ii","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vmpauhb_128B,"V64iV64ii","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vmpauhb_acc,"V32iV32iV32ii","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vmpauhb_acc_128B,"V64iV64iV64ii","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyiwub,"V16iV16ii","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyiwub_128B,"V32iV32ii","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyiwub_acc,"V16iV16iV16ii","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyiwub_acc_128B,"V32iV32iV32ii","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vandnqrt,"V16iV16ii","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vandnqrt_128B,"V32iV32ii","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vandnqrt_acc,"V16iV16iV16ii","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vandnqrt_acc_128B,"V32iV32iV32ii","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vandvqv,"V16iV16iV16i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vandvqv_128B,"V32iV32iV32i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vandvnqv,"V16iV16iV16i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vandvnqv_128B,"V32iV32iV32i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_pred_scalar2v2,"V16ii","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_pred_scalar2v2_128B,"V32ii","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_shuffeqw,"V16iV16iV16i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_shuffeqw_128B,"V32iV32iV32i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_shuffeqh,"V16iV16iV16i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_shuffeqh_128B,"V32iV32iV32i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vmaxb,"V16iV16iV16i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vmaxb_128B,"V32iV32iV32i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vminb,"V16iV16iV16i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vminb_128B,"V32iV32iV32i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vsatuwuh,"V16iV16iV16i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vsatuwuh_128B,"V32iV32iV32i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_lvsplath,"V16ii","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_lvsplath_128B,"V32ii","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_lvsplatb,"V16ii","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_lvsplatb_128B,"V32ii","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vaddclbw,"V16iV16iV16i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vaddclbw_128B,"V32iV32iV32i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vaddclbh,"V16iV16iV16i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vaddclbh_128B,"V32iV32iV32i","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vlutvvbi,"V16iV16iV16ii","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vlutvvbi_128B,"V32iV32iV32ii","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vlutvvb_oracci,"V16iV16iV16iV16ii","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vlutvvb_oracci_128B,"V32iV32iV32iV32ii","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vlutvwhi,"V32iV16iV16ii","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vlutvwhi_128B,"V64iV32iV32ii","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vlutvwh_oracci,"V32iV32iV16iV16ii","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vlutvwh_oracci_128B,"V64iV64iV32iV32ii","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vlutvvb_nm,"V16iV16iV16ii","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vlutvvb_nm_128B,"V32iV32iV32ii","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vlutvwh_nm,"V32iV16iV16ii","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vlutvwh_nm_128B,"V64iV32iV32ii","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vaddcarry,"V16iV16iV16iv*","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vaddcarry_128B,"V32iV32iV32iv*","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vsubcarry,"V16iV16iV16iv*","v:62:")
-BUILTIN(__builtin_HEXAGON_V6_vsubcarry_128B,"V32iV32iV32iv*","v:62:")
+// V65 HVX Instructions.
-BUILTIN(__builtin_HEXAGON_A6_vcmpbeq_notany,"iLLiLLi","v:65:")
-BUILTIN(__builtin_HEXAGON_A6_vcmpbeq_notany_128B,"iLLiLLi","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vrmpyub_rtt,"V32iV16iLLi","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vrmpyub_rtt_128B,"V64iV32iLLi","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vrmpyub_rtt_acc,"V32iV32iV16iLLi","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vrmpyub_rtt_acc_128B,"V64iV64iV32iLLi","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vrmpybub_rtt,"V32iV16iLLi","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vrmpybub_rtt_128B,"V64iV32iLLi","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vrmpybub_rtt_acc,"V32iV32iV16iLLi","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vrmpybub_rtt_acc_128B,"V64iV64iV32iLLi","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vasruwuhsat,"V16iV16iV16ii","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vasruwuhsat_128B,"V32iV32iV32ii","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vasruhubsat,"V16iV16iV16ii","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vasruhubsat_128B,"V32iV32iV32ii","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vasruhubrndsat,"V16iV16iV16ii","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vasruhubrndsat_128B,"V32iV32iV32ii","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vaslh_acc,"V16iV16iV16ii","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vaslh_acc_128B,"V32iV32iV32ii","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vasrh_acc,"V16iV16iV16ii","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vasrh_acc_128B,"V32iV32iV32ii","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vavguw,"V16iV16iV16i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vavguw_128B,"V32iV32iV32i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vavguwrnd,"V16iV16iV16i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vavguwrnd_128B,"V32iV32iV32i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vavgb,"V16iV16iV16i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vavgb_128B,"V32iV32iV32i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vavgbrnd,"V16iV16iV16i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vavgbrnd_128B,"V32iV32iV32i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vnavgb,"V16iV16iV16i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vnavgb_128B,"V32iV32iV32i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vabsb,"V16iV16i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vabsb_128B,"V32iV32i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vabsb_sat,"V16iV16i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vabsb_sat_128B,"V32iV32i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vmpabuu,"V32iV32ii","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vmpabuu_128B,"V64iV64ii","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vmpabuu_acc,"V32iV32iV32ii","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vmpabuu_acc_128B,"V64iV64iV64ii","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyh_acc,"V32iV32iV16ii","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyh_acc_128B,"V64iV64iV32ii","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vmpahhsat,"V16iV16iV16iLLi","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vmpahhsat_128B,"V32iV32iV32iLLi","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vmpauhuhsat,"V16iV16iV16iLLi","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vmpauhuhsat_128B,"V32iV32iV32iLLi","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vmpsuhuhsat,"V16iV16iV16iLLi","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vmpsuhuhsat_128B,"V32iV32iV32iLLi","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vlut4,"V16iV16iLLi","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vlut4_128B,"V32iV32iLLi","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyuhe,"V16iV16ii","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyuhe_128B,"V32iV32ii","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyuhe_acc,"V16iV16iV16ii","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vmpyuhe_acc_128B,"V32iV32iV32ii","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vgathermw,"vv*iiV16i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vgathermw_128B,"vv*iiV32i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vgathermh,"vv*iiV16i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vgathermh_128B,"vv*iiV32i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vgathermhw,"vv*iiV32i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vgathermhw_128B,"vv*iiV64i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vgathermwq,"vv*V16iiiV16i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vgathermwq_128B,"vv*V32iiiV32i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vgathermhq,"vv*V16iiiV16i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vgathermhq_128B,"vv*V32iiiV32i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vgathermhwq,"vv*V16iiiV32i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vgathermhwq_128B,"vv*V32iiiV64i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vscattermw,"viiV16iV16i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vscattermw_128B,"viiV32iV32i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vscattermh,"viiV16iV16i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vscattermh_128B,"viiV32iV32i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vscattermw_add,"viiV16iV16i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vscattermw_add_128B,"viiV32iV32i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vscattermh_add,"viiV16iV16i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vscattermh_add_128B,"viiV32iV32i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vscattermwq,"vV16iiiV16iV16i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vscattermwq_128B,"vV32iiiV32iV32i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vscattermhq,"vV16iiiV16iV16i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vscattermhq_128B,"vV32iiiV32iV32i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vscattermhw,"viiV32iV16i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vscattermhw_128B,"viiV64iV32i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vscattermhwq,"vV16iiiV32iV16i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vscattermhwq_128B,"vV32iiiV64iV32i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vscattermhw_add,"viiV32iV16i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vscattermhw_add_128B,"viiV64iV32i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vprefixqb,"V16iV16i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vprefixqb_128B,"V32iV32i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vprefixqh,"V16iV16i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vprefixqh_128B,"V32iV32i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vprefixqw,"V16iV16i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vprefixqw_128B,"V32iV32i","v:65:")
+BUILTIN(__builtin_HEXAGON_V6_vasruhubrndsat,"V16iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vasruhubrndsat_128B,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vrmpybub_rtt,"V32iV16iLLi","")
+BUILTIN(__builtin_HEXAGON_V6_vrmpybub_rtt_128B,"V64iV32iLLi","")
+BUILTIN(__builtin_HEXAGON_V6_vmpahhsat,"V16iV16iV16iLLi","")
+BUILTIN(__builtin_HEXAGON_V6_vmpahhsat_128B,"V32iV32iV32iLLi","")
+BUILTIN(__builtin_HEXAGON_V6_vavguwrnd,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vavguwrnd_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vnavgb,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vnavgb_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vasrh_acc,"V16iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vasrh_acc_128B,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpauhuhsat,"V16iV16iV16iLLi","")
+BUILTIN(__builtin_HEXAGON_V6_vmpauhuhsat_128B,"V32iV32iV32iLLi","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyh_acc,"V32iV32iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyh_acc_128B,"V64iV64iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vrmpybub_rtt_acc,"V32iV32iV16iLLi","")
+BUILTIN(__builtin_HEXAGON_V6_vrmpybub_rtt_acc_128B,"V64iV64iV32iLLi","")
+BUILTIN(__builtin_HEXAGON_V6_vavgb,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vavgb_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vaslh_acc,"V16iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vaslh_acc_128B,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vavguw,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vavguw_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vlut4,"V16iV16iLLi","")
+BUILTIN(__builtin_HEXAGON_V6_vlut4_128B,"V32iV32iLLi","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyuhe_acc,"V16iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyuhe_acc_128B,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vrmpyub_rtt,"V32iV16iLLi","")
+BUILTIN(__builtin_HEXAGON_V6_vrmpyub_rtt_128B,"V64iV32iLLi","")
+BUILTIN(__builtin_HEXAGON_V6_vmpsuhuhsat,"V16iV16iV16iLLi","")
+BUILTIN(__builtin_HEXAGON_V6_vmpsuhuhsat_128B,"V32iV32iV32iLLi","")
+BUILTIN(__builtin_HEXAGON_V6_vasruhubsat,"V16iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vasruhubsat_128B,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyuhe,"V16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpyuhe_128B,"V32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vrmpyub_rtt_acc,"V32iV32iV16iLLi","")
+BUILTIN(__builtin_HEXAGON_V6_vrmpyub_rtt_acc_128B,"V64iV64iV32iLLi","")
+BUILTIN(__builtin_HEXAGON_V6_vasruwuhsat,"V16iV16iV16ii","")
+BUILTIN(__builtin_HEXAGON_V6_vasruwuhsat_128B,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpabuu_acc,"V32iV32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpabuu_acc_128B,"V64iV64iV64ii","")
+BUILTIN(__builtin_HEXAGON_V6_vprefixqw,"V16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vprefixqw_128B,"V32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vprefixqh,"V16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vprefixqh_128B,"V32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vprefixqb,"V16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vprefixqb_128B,"V32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vabsb,"V16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vabsb_128B,"V32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vavgbrnd,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vavgbrnd_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vdd0,"V32i","")
+BUILTIN(__builtin_HEXAGON_V6_vdd0_128B,"V64i","")
+BUILTIN(__builtin_HEXAGON_V6_vmpabuu,"V32iV32ii","")
+BUILTIN(__builtin_HEXAGON_V6_vmpabuu_128B,"V64iV64ii","")
+BUILTIN(__builtin_HEXAGON_V6_vabsb_sat,"V16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vabsb_sat_128B,"V32iV32i","")
-BUILTIN(__builtin_HEXAGON_V6_vdd0,"V32i","v:65:")
-BUILTIN(__builtin_HEXAGON_V6_vdd0_128B,"V64i","v:65:")
+// V66 HVX Instructions.
+BUILTIN(__builtin_HEXAGON_V6_vaddcarrysat,"V16iV16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vaddcarrysat_128B,"V32iV32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vasr_into,"V32iV32iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vasr_into_128B,"V64iV64iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vsatdw,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vsatdw_128B,"V32iV32iV32i","")
+BUILTIN(__builtin_HEXAGON_V6_vrotr,"V16iV16iV16i","")
+BUILTIN(__builtin_HEXAGON_V6_vrotr_128B,"V32iV32iV32i","")
#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsNios2.def b/include/clang/Basic/BuiltinsNios2.def
deleted file mode 100644
index d9697e795c44..000000000000
--- a/include/clang/Basic/BuiltinsNios2.def
+++ /dev/null
@@ -1,70 +0,0 @@
-//===-- BuiltinsNios2.def - Nios2 Builtin function database --------*- C++ -*-==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the Nios2-specific builtin function database. Users of
-// this file must define the BUILTIN macro to make use of this information.
-//
-//===----------------------------------------------------------------------===//
-
-// The format of this database matches clang/Basic/Builtins.def.
-
-#if defined(BUILTIN) && !defined(TARGET_BUILTIN)
-# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS)
-#endif
-
-// Nios2 R1 builtins:
-
-//int __builtin_ldbio(volatile const void *);
-BUILTIN(__builtin_ldbio, "ivDC*", "")
-//int __builtin_ldbuio(volatile const void *);
-BUILTIN(__builtin_ldbuio, "ivDC*", "")
-//int __builtin_ldhio(volatile const void *);
-BUILTIN(__builtin_ldhio, "ivDC*", "")
-//int __builtin_ldhuio(volatile const void *);
-BUILTIN(__builtin_ldhuio, "ivDC*", "")
-//int __builtin_ldwio(volatile const void *);
-BUILTIN(__builtin_ldwio, "ivDC*", "")
-//int __builtin_ldwuio(int);
-BUILTIN(__builtin_ldwuio, "ii", "")
-// int __builtin_rdctl(int);
-BUILTIN(__builtin_rdctl, "iIi", "")
-// void __builtin_wrctl(int, int);
-BUILTIN(__builtin_wrctl, "vIii", "")
-// int __builtin_rdprs(int, int);
-BUILTIN(__builtin_rdprs, "iii", "")
-//void __builtin_stbio(volatile void *, int);
-BUILTIN(__builtin_stbio, "vvD*i", "")
-//void __builtin_sthio(volatile void *, int);
-BUILTIN(__builtin_sthio, "vvD*i", "")
-//void __builtin_stwio(volatile void *, int);
-BUILTIN(__builtin_stwio, "vvD*i", "")
-//void __builtin_sync(void);
-BUILTIN(__builtin_sync, "v", "")
-// void __builtin_flushd(volatile void *);
-BUILTIN(__builtin_flushd, "vvD*", "")
-// void __builtin_flushda(volatile void *);
-BUILTIN(__builtin_flushda, "vvD*", "")
-
-// Nios2 R2 builtins:
-
-// int __builtin_wrpie(int);
-TARGET_BUILTIN(__builtin_wrpie, "ii", "", "nios2r2mandatory")
-// void __builtin_eni(int);
-TARGET_BUILTIN(__builtin_eni, "vi", "", "nios2r2mandatory")
-// int __builtin_ldex(volatile const void *);
-TARGET_BUILTIN(__builtin_ldex, "ivDC*", "", "nios2r2mandatory")
-// int __builtin_stex(volatile void *, int);
-TARGET_BUILTIN(__builtin_stex, "ivD*i", "", "nios2r2mandatory")
-// int __builtin_ldsex(volatile const void *);
-TARGET_BUILTIN(__builtin_ldsex, "ivDC*", "", "nios2r2mpx")
-// int __builtin_stsex(volatile void *, int);
-TARGET_BUILTIN(__builtin_stsex, "ivDC*i", "", "nios2r2mpx")
-
-#undef BUILTIN
-#undef TARGET_BUILTIN
diff --git a/include/clang/Basic/BuiltinsPPC.def b/include/clang/Basic/BuiltinsPPC.def
index 9be760853d50..d31cb06f05f5 100644
--- a/include/clang/Basic/BuiltinsPPC.def
+++ b/include/clang/Basic/BuiltinsPPC.def
@@ -431,6 +431,8 @@ BUILTIN(__builtin_mulf128_round_to_odd, "LLdLLdLLd", "")
BUILTIN(__builtin_divf128_round_to_odd, "LLdLLdLLd", "")
BUILTIN(__builtin_fmaf128_round_to_odd, "LLdLLdLLdLLd", "")
BUILTIN(__builtin_truncf128_round_to_odd, "dLLd", "")
+BUILTIN(__builtin_vsx_scalar_extract_expq, "ULLiLLd", "")
+BUILTIN(__builtin_vsx_scalar_insert_exp_qp, "LLdLLdULLi", "")
// HTM builtins
BUILTIN(__builtin_tbegin, "UiUIi", "")
@@ -470,6 +472,10 @@ BUILTIN(__builtin_divde, "SLLiSLLiSLLi", "")
BUILTIN(__builtin_divdeu, "ULLiULLiULLi", "")
BUILTIN(__builtin_bpermd, "SLLiSLLiSLLi", "")
+// Vector int128 (un)pack
+BUILTIN(__builtin_unpack_vector_int128, "ULLiV1LLLii", "")
+BUILTIN(__builtin_pack_vector_int128, "V1LLLiULLiULLi", "")
+
// FIXME: Obviously incomplete.
#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsWebAssembly.def b/include/clang/Basic/BuiltinsWebAssembly.def
index b3d877dcedf3..55931edc5ca3 100644
--- a/include/clang/Basic/BuiltinsWebAssembly.def
+++ b/include/clang/Basic/BuiltinsWebAssembly.def
@@ -16,22 +16,94 @@
// The format of this database matches clang/Basic/Builtins.def.
+#if defined(BUILTIN) && !defined(TARGET_BUILTIN)
+# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS)
+#endif
+
// Query the current memory size, and increase the current memory size.
// Note that memory.size is not "c" (readnone) because it must be sequenced
// with respect to memory.grow calls.
BUILTIN(__builtin_wasm_memory_size, "zIi", "n")
BUILTIN(__builtin_wasm_memory_grow, "zIiz", "n")
-// These are the old names.
-BUILTIN(__builtin_wasm_mem_size, "zIi", "n")
-BUILTIN(__builtin_wasm_mem_grow, "zIiz", "n")
-
-// These are the old old names. They also lack the immediate field.
-BUILTIN(__builtin_wasm_current_memory, "z", "n")
-BUILTIN(__builtin_wasm_grow_memory, "zz", "n")
+// Floating point min/max
+BUILTIN(__builtin_wasm_min_f32, "fff", "nc")
+BUILTIN(__builtin_wasm_max_f32, "fff", "nc")
+BUILTIN(__builtin_wasm_min_f64, "ddd", "nc")
+BUILTIN(__builtin_wasm_max_f64, "ddd", "nc")
// Exception handling builtins.
-BUILTIN(__builtin_wasm_throw, "vUiv*", "r")
-BUILTIN(__builtin_wasm_rethrow, "v", "r")
+TARGET_BUILTIN(__builtin_wasm_throw, "vUiv*", "r", "exception-handling")
+TARGET_BUILTIN(__builtin_wasm_rethrow, "v", "r", "exception-handling")
+
+// Atomic wait and notify.
+BUILTIN(__builtin_wasm_atomic_wait_i32, "ii*iLLi", "n")
+BUILTIN(__builtin_wasm_atomic_wait_i64, "iLLi*LLiLLi", "n")
+BUILTIN(__builtin_wasm_atomic_notify, "Uii*Ui", "n")
+
+// Saturating fp-to-int conversions
+TARGET_BUILTIN(__builtin_wasm_trunc_saturate_s_i32_f32, "if", "nc", "nontrapping-fptoint")
+TARGET_BUILTIN(__builtin_wasm_trunc_saturate_u_i32_f32, "if", "nc", "nontrapping-fptoint")
+TARGET_BUILTIN(__builtin_wasm_trunc_saturate_s_i32_f64, "id", "nc", "nontrapping-fptoint")
+TARGET_BUILTIN(__builtin_wasm_trunc_saturate_u_i32_f64, "id", "nc", "nontrapping-fptoint")
+TARGET_BUILTIN(__builtin_wasm_trunc_saturate_s_i64_f32, "LLif", "nc", "nontrapping-fptoint")
+TARGET_BUILTIN(__builtin_wasm_trunc_saturate_u_i64_f32, "LLif", "nc", "nontrapping-fptoint")
+TARGET_BUILTIN(__builtin_wasm_trunc_saturate_s_i64_f64, "LLid", "nc", "nontrapping-fptoint")
+TARGET_BUILTIN(__builtin_wasm_trunc_saturate_u_i64_f64, "LLid", "nc", "nontrapping-fptoint")
+
+// SIMD builtins
+TARGET_BUILTIN(__builtin_wasm_extract_lane_s_i8x16, "iV16cIi", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_extract_lane_u_i8x16, "iV16cIi", "nc", "unimplemented-simd128")
+TARGET_BUILTIN(__builtin_wasm_extract_lane_s_i16x8, "iV8sIi", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_extract_lane_u_i16x8, "iV8sIi", "nc", "unimplemented-simd128")
+TARGET_BUILTIN(__builtin_wasm_extract_lane_i32x4, "iV4iIi", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_extract_lane_i64x2, "LLiV2LLiIi", "nc", "unimplemented-simd128")
+TARGET_BUILTIN(__builtin_wasm_extract_lane_f32x4, "fV4fIi", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_extract_lane_f64x2, "dV2dIi", "nc", "unimplemented-simd128")
+
+TARGET_BUILTIN(__builtin_wasm_replace_lane_i8x16, "V16cV16cIii", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_replace_lane_i16x8, "V8sV8sIii", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_replace_lane_i32x4, "V4iV4iIii", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_replace_lane_i64x2, "V2LLiV2LLiIiLLi", "nc", "unimplemented-simd128")
+TARGET_BUILTIN(__builtin_wasm_replace_lane_f32x4, "V4fV4fIif", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_replace_lane_f64x2, "V2dV2dIid", "nc", "unimplemented-simd128")
+
+TARGET_BUILTIN(__builtin_wasm_add_saturate_s_i8x16, "V16cV16cV16c", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_add_saturate_u_i8x16, "V16cV16cV16c", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_add_saturate_s_i16x8, "V8sV8sV8s", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_add_saturate_u_i16x8, "V8sV8sV8s", "nc", "simd128")
+
+TARGET_BUILTIN(__builtin_wasm_sub_saturate_s_i8x16, "V16cV16cV16c", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_sub_saturate_u_i8x16, "V16cV16cV16c", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_sub_saturate_s_i16x8, "V8sV8sV8s", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_sub_saturate_u_i16x8, "V8sV8sV8s", "nc", "simd128")
+
+TARGET_BUILTIN(__builtin_wasm_bitselect, "V4iV4iV4iV4i", "nc", "simd128")
+
+TARGET_BUILTIN(__builtin_wasm_any_true_i8x16, "iV16c", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_any_true_i16x8, "iV8s", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_any_true_i32x4, "iV4i", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_any_true_i64x2, "iV2LLi", "nc", "unimplemented-simd128")
+TARGET_BUILTIN(__builtin_wasm_all_true_i8x16, "iV16c", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_all_true_i16x8, "iV8s", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_all_true_i32x4, "iV4i", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_all_true_i64x2, "iV2LLi", "nc", "unimplemented-simd128")
+
+TARGET_BUILTIN(__builtin_wasm_abs_f32x4, "V4fV4f", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_abs_f64x2, "V2dV2d", "nc", "unimplemented-simd128")
+
+TARGET_BUILTIN(__builtin_wasm_min_f32x4, "V4fV4fV4f", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_max_f32x4, "V4fV4fV4f", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_min_f64x2, "V2dV2dV2d", "nc", "unimplemented-simd128")
+TARGET_BUILTIN(__builtin_wasm_max_f64x2, "V2dV2dV2d", "nc", "unimplemented-simd128")
+
+TARGET_BUILTIN(__builtin_wasm_sqrt_f32x4, "V4fV4f", "nc", "unimplemented-simd128")
+TARGET_BUILTIN(__builtin_wasm_sqrt_f64x2, "V2dV2d", "nc", "unimplemented-simd128")
+
+TARGET_BUILTIN(__builtin_wasm_trunc_saturate_s_i32x4_f32x4, "V4iV4f", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_trunc_saturate_u_i32x4_f32x4, "V4iV4f", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_trunc_saturate_s_i64x2_f64x2, "V2LLiV2d", "nc", "unimplemented-simd128")
+TARGET_BUILTIN(__builtin_wasm_trunc_saturate_u_i64x2_f64x2, "V2LLiV2d", "nc", "unimplemented-simd128")
#undef BUILTIN
+#undef TARGET_BUILTIN
diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def
index e98f7d612c3c..b3564b957e99 100644
--- a/include/clang/Basic/BuiltinsX86.def
+++ b/include/clang/Basic/BuiltinsX86.def
@@ -719,16 +719,21 @@ TARGET_BUILTIN(__builtin_ia32_wbinvd, "v", "n", "")
TARGET_BUILTIN(__builtin_ia32_wbnoinvd, "v", "n", "wbnoinvd")
// ADX
-TARGET_BUILTIN(__builtin_ia32_addcarryx_u32, "UcUcUiUiUi*", "n", "adx")
-TARGET_BUILTIN(__builtin_ia32_addcarry_u32, "UcUcUiUiUi*", "n", "")
+TARGET_BUILTIN(__builtin_ia32_addcarryx_u32, "UcUcUiUiUi*", "n", "")
TARGET_BUILTIN(__builtin_ia32_subborrow_u32, "UcUcUiUiUi*", "n", "")
// RDSEED
TARGET_BUILTIN(__builtin_ia32_rdseed16_step, "UiUs*", "n", "rdseed")
TARGET_BUILTIN(__builtin_ia32_rdseed32_step, "UiUi*", "n", "rdseed")
+// LZCNT
+TARGET_BUILTIN(__builtin_ia32_lzcnt_u16, "UsUs", "nc", "lzcnt")
+TARGET_BUILTIN(__builtin_ia32_lzcnt_u32, "UiUi", "nc", "lzcnt")
+
// BMI
TARGET_BUILTIN(__builtin_ia32_bextr_u32, "UiUiUi", "nc", "bmi")
+TARGET_BUILTIN(__builtin_ia32_tzcnt_u16, "UsUs", "nc", "")
+TARGET_BUILTIN(__builtin_ia32_tzcnt_u32, "UiUi", "nc", "")
// BMI2
TARGET_BUILTIN(__builtin_ia32_bzhi_si, "UiUiUi", "nc", "bmi2")
@@ -963,49 +968,52 @@ TARGET_BUILTIN(__builtin_ia32_vpdpwssds128, "V4iV4iV4iV4i", "ncV:128:", "avx512v
TARGET_BUILTIN(__builtin_ia32_vpdpwssds256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl,avx512vnni")
TARGET_BUILTIN(__builtin_ia32_vpdpwssds512, "V16iV16iV16iV16i", "ncV:512:", "avx512vnni")
-TARGET_BUILTIN(__builtin_ia32_gather3div2df, "V2dV2ddC*V2LLiUcIi", "nV:128:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3div2di, "V2LLiV2LLiLLiC*V2LLiUcIi", "nV:128:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3div4df, "V4dV4ddC*V4LLiUcIi", "nV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3div4di, "V4LLiV4LLiLLiC*V4LLiUcIi", "nV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3div4sf, "V4fV4ffC*V2LLiUcIi", "nV:128:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3div4si, "V4iV4iiC*V2LLiUcIi", "nV:128:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3div8sf, "V4fV4ffC*V4LLiUcIi", "nV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3div8si, "V4iV4iiC*V4LLiUcIi", "nV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3siv2df, "V2dV2ddC*V4iUcIi", "nV:128:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3siv2di, "V2LLiV2LLiLLiC*V4iUcIi", "nV:128:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3siv4df, "V4dV4ddC*V4iUcIi", "nV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3siv4di, "V4LLiV4LLiLLiC*V4iUcIi", "nV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3siv4sf, "V4fV4ffC*V4iUcIi", "nV:128:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3siv4si, "V4iV4iiC*V4iUcIi", "nV:128:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3siv8sf, "V8fV8ffC*V8iUcIi", "nV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3siv8si, "V8iV8iiC*V8iUcIi", "nV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gathersiv8df, "V8dV8ddC*V8iUcIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_gathersiv16sf, "V16fV16ffC*V16fUsIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_gatherdiv8df, "V8dV8ddC*V8LLiUcIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_gatherdiv16sf, "V8fV8ffC*V8LLiUcIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_gathersiv8di, "V8LLiV8LLiLLiC*V8iUcIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_gathersiv16si, "V16iV16iiC*V16iUsIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_gatherdiv8di, "V8LLiV8LLiLLiC*V8LLiUcIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_gatherdiv16si, "V8iV8iiC*V8LLiUcIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scattersiv8df, "vd*UcV8iV8dIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scattersiv16sf, "vf*UsV16iV16fIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv8df, "vd*UcV8LLiV8dIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv16sf, "vf*UcV8LLiV8fIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scattersiv8di, "vLLi*UcV8iV8LLiIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scattersiv16si, "vi*UsV16iV16iIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv8di, "vLLi*UcV8LLiV8LLiIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv16si, "vi*UcV8LLiV8iIi", "nV:512:", "avx512f")
-
-TARGET_BUILTIN(__builtin_ia32_gatherpfdpd, "vUcV8iLLiC*IiIi", "nV:512:", "avx512pf")
-TARGET_BUILTIN(__builtin_ia32_gatherpfdps, "vUsV16iiC*IiIi", "nV:512:", "avx512pf")
-TARGET_BUILTIN(__builtin_ia32_gatherpfqpd, "vUcV8LLiLLiC*IiIi", "nV:512:", "avx512pf")
-TARGET_BUILTIN(__builtin_ia32_gatherpfqps, "vUcV8LLiiC*IiIi", "nV:512:", "avx512pf")
-TARGET_BUILTIN(__builtin_ia32_scatterpfdpd, "vUcV8iLLi*IiIi", "nV:512:", "avx512pf")
-TARGET_BUILTIN(__builtin_ia32_scatterpfdps, "vUsV16ii*IiIi", "nV:512:", "avx512pf")
-TARGET_BUILTIN(__builtin_ia32_scatterpfqpd, "vUcV8LLiLLi*IiIi", "nV:512:", "avx512pf")
-TARGET_BUILTIN(__builtin_ia32_scatterpfqps, "vUcV8LLii*IiIi", "nV:512:", "avx512pf")
-
+TARGET_BUILTIN(__builtin_ia32_gather3div2df, "V2dV2dvC*V2LLiUcIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3div2di, "V2LLiV2LLivC*V2LLiUcIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3div4df, "V4dV4dvC*V4LLiUcIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3div4di, "V4LLiV4LLivC*V4LLiUcIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3div4sf, "V4fV4fvC*V2LLiUcIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3div4si, "V4iV4ivC*V2LLiUcIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3div8sf, "V4fV4fvC*V4LLiUcIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3div8si, "V4iV4ivC*V4LLiUcIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3siv2df, "V2dV2dvC*V4iUcIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3siv2di, "V2LLiV2LLivC*V4iUcIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3siv4df, "V4dV4dvC*V4iUcIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3siv4di, "V4LLiV4LLivC*V4iUcIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3siv4sf, "V4fV4fvC*V4iUcIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3siv4si, "V4iV4ivC*V4iUcIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3siv8sf, "V8fV8fvC*V8iUcIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3siv8si, "V8iV8ivC*V8iUcIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gathersiv8df, "V8dV8dvC*V8iUcIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_gathersiv16sf, "V16fV16fvC*V16iUsIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_gatherdiv8df, "V8dV8dvC*V8LLiUcIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_gatherdiv16sf, "V8fV8fvC*V8LLiUcIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_gathersiv8di, "V8LLiV8LLivC*V8iUcIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_gathersiv16si, "V16iV16ivC*V16iUsIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_gatherdiv8di, "V8LLiV8LLivC*V8LLiUcIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_gatherdiv16si, "V8iV8ivC*V8LLiUcIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_scattersiv8df, "vv*UcV8iV8dIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_scattersiv16sf, "vv*UsV16iV16fIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_scatterdiv8df, "vv*UcV8LLiV8dIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_scatterdiv16sf, "vv*UcV8LLiV8fIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_scattersiv8di, "vv*UcV8iV8LLiIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_scattersiv16si, "vv*UsV16iV16iIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_scatterdiv8di, "vv*UcV8LLiV8LLiIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_scatterdiv16si, "vv*UcV8LLiV8iIi", "nV:512:", "avx512f")
+
+TARGET_BUILTIN(__builtin_ia32_gatherpfdpd, "vUcV8ivC*IiIi", "nV:512:", "avx512pf")
+TARGET_BUILTIN(__builtin_ia32_gatherpfdps, "vUsV16ivC*IiIi", "nV:512:", "avx512pf")
+TARGET_BUILTIN(__builtin_ia32_gatherpfqpd, "vUcV8LLivC*IiIi", "nV:512:", "avx512pf")
+TARGET_BUILTIN(__builtin_ia32_gatherpfqps, "vUcV8LLivC*IiIi", "nV:512:", "avx512pf")
+TARGET_BUILTIN(__builtin_ia32_scatterpfdpd, "vUcV8iv*IiIi", "nV:512:", "avx512pf")
+TARGET_BUILTIN(__builtin_ia32_scatterpfdps, "vUsV16iv*IiIi", "nV:512:", "avx512pf")
+TARGET_BUILTIN(__builtin_ia32_scatterpfqpd, "vUcV8LLiv*IiIi", "nV:512:", "avx512pf")
+TARGET_BUILTIN(__builtin_ia32_scatterpfqps, "vUcV8LLiv*IiIi", "nV:512:", "avx512pf")
+
+TARGET_BUILTIN(__builtin_ia32_knotqi, "UcUc", "nc", "avx512dq")
TARGET_BUILTIN(__builtin_ia32_knothi, "UsUs", "nc", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_knotsi, "UiUi", "nc", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_knotdi, "ULLiULLi", "nc", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_cmpb128_mask, "UsV16cV16cIiUs", "ncV:128:", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_cmpd128_mask, "UcV4iV4iIiUc", "ncV:128:", "avx512vl")
@@ -1038,10 +1046,10 @@ TARGET_BUILTIN(__builtin_ia32_packssdw512, "V32sV16iV16i", "ncV:512:", "avx512bw
TARGET_BUILTIN(__builtin_ia32_packsswb512, "V64cV32sV32s", "ncV:512:", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_packusdw512, "V32sV16iV16i", "ncV:512:", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_packuswb512, "V64cV32sV32s", "ncV:512:", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_paddsb512_mask, "V64cV64cV64cV64cULLi", "ncV:512:", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_paddsw512_mask, "V32sV32sV32sV32sUi", "ncV:512:", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_paddusb512_mask, "V64cV64cV64cV64cULLi", "ncV:512:", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_paddusw512_mask, "V32sV32sV32sV32sUi", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_paddsb512, "V64cV64cV64c", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_paddsw512, "V32sV32sV32s", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_paddusb512, "V64cV64cV64c", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_paddusw512, "V32sV32sV32s", "ncV:512:", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmaxsb512, "V64cV64cV64c", "ncV:512:", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmaxsw512, "V32sV32sV32s", "ncV:512:", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmaxub512, "V64cV64cV64c", "ncV:512:", "avx512bw")
@@ -1051,10 +1059,10 @@ TARGET_BUILTIN(__builtin_ia32_pminsw512, "V32sV32sV32s", "ncV:512:", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_pminub512, "V64cV64cV64c", "ncV:512:", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_pminuw512, "V32sV32sV32s", "ncV:512:", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_pshufb512, "V64cV64cV64c", "ncV:512:", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psubsb512_mask, "V64cV64cV64cV64cULLi", "ncV:512:", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psubsw512_mask, "V32sV32sV32sV32sUi", "ncV:512:", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psubusb512_mask, "V64cV64cV64cV64cULLi", "ncV:512:", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psubusw512_mask, "V32sV32sV32sV32sUi", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_psubsb512, "V64cV64cV64c", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_psubsw512, "V32sV32sV32s", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_psubusb512, "V64cV64cV64c", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_psubusw512, "V32sV32sV32s", "ncV:512:", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_vpconflictdi_128_mask, "V2LLiV2LLiV2LLiUc", "ncV:128:", "avx512cd,avx512vl")
TARGET_BUILTIN(__builtin_ia32_vpconflictdi_256_mask, "V4LLiV4LLiV4LLiUc", "ncV:256:", "avx512cd,avx512vl")
@@ -1202,22 +1210,22 @@ TARGET_BUILTIN(__builtin_ia32_scalefpd256_mask, "V4dV4dV4dV4dUc", "ncV:256:", "a
TARGET_BUILTIN(__builtin_ia32_scalefps128_mask, "V4fV4fV4fV4fUc", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_scalefps256_mask, "V8fV8fV8fV8fUc", "ncV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv2df, "vd*UcV2LLiV2dIi", "nV:128:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv2di, "vLLi*UcV2LLiV2LLiIi", "nV:128:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv4df, "vd*UcV4LLiV4dIi", "nV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv4di, "vLLi*UcV4LLiV4LLiIi", "nV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv4sf, "vf*UcV2LLiV4fIi", "nV:128:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv4si, "vi*UcV2LLiV4iIi", "nV:128:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv8sf, "vf*UcV4LLiV4fIi", "nV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv8si, "vi*UcV4LLiV4iIi", "nV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scattersiv2df, "vd*UcV4iV2dIi", "nV:128:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scattersiv2di, "vLLi*UcV4iV2LLiIi", "nV:128:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scattersiv4df, "vd*UcV4iV4dIi", "nV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scattersiv4di, "vLLi*UcV4iV4LLiIi", "nV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scattersiv4sf, "vf*UcV4iV4fIi", "nV:128:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scattersiv4si, "vi*UcV4iV4iIi", "nV:128:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scattersiv8sf, "vf*UcV8iV8fIi", "nV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scattersiv8si, "vi*UcV8iV8iIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scatterdiv2df, "vv*UcV2LLiV2dIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scatterdiv2di, "vv*UcV2LLiV2LLiIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scatterdiv4df, "vv*UcV4LLiV4dIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scatterdiv4di, "vv*UcV4LLiV4LLiIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scatterdiv4sf, "vv*UcV2LLiV4fIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scatterdiv4si, "vv*UcV2LLiV4iIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scatterdiv8sf, "vv*UcV4LLiV4fIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scatterdiv8si, "vv*UcV4LLiV4iIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scattersiv2df, "vv*UcV4iV2dIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scattersiv2di, "vv*UcV4iV2LLiIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scattersiv4df, "vv*UcV4iV4dIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scattersiv4di, "vv*UcV4iV4LLiIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scattersiv4sf, "vv*UcV4iV4fIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scattersiv4si, "vv*UcV4iV4iIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scattersiv8sf, "vv*UcV8iV8fIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scattersiv8si, "vv*UcV8iV8iIi", "nV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_vpermi2vard128, "V4iV4iV4iV4i", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_vpermi2vard256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl")
@@ -1248,43 +1256,25 @@ TARGET_BUILTIN(__builtin_ia32_vpshldw128, "V8sV8sV8sIi", "ncV:128:", "avx512vl,a
TARGET_BUILTIN(__builtin_ia32_vpshldw256, "V16sV16sV16sIi", "ncV:256:", "avx512vl,avx512vbmi2")
TARGET_BUILTIN(__builtin_ia32_vpshldw512, "V32sV32sV32sIi", "ncV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvd128_mask, "V4iV4iV4iV4iUc", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvd256_mask, "V8iV8iV8iV8iUc", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvd512_mask, "V16iV16iV16iV16iUs", "ncV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "ncV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvw128_mask, "V8sV8sV8sV8sUc", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvw256_mask, "V16sV16sV16sV16sUs", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvw512_mask, "V32sV32sV32sV32sUi", "ncV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvd128_maskz, "V4iV4iV4iV4iUc", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvd256_maskz, "V8iV8iV8iV8iUc", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvd512_maskz, "V16iV16iV16iV16iUs", "ncV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvq128_maskz, "V2LLiV2LLiV2LLiV2LLiUc", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvq256_maskz, "V4LLiV4LLiV4LLiV4LLiUc", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvq512_maskz, "V8LLiV8LLiV8LLiV8LLiUc", "ncV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvw128_maskz, "V8sV8sV8sV8sUc", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvw256_maskz, "V16sV16sV16sV16sUs", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvw512_maskz, "V32sV32sV32sV32sUi", "ncV:512:", "avx512vbmi2")
-
-TARGET_BUILTIN(__builtin_ia32_vpshrdvd128_mask, "V4iV4iV4iV4iUc", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvd256_mask, "V8iV8iV8iV8iUc", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvd512_mask, "V16iV16iV16iV16iUs", "ncV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "ncV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvw128_mask, "V8sV8sV8sV8sUc", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvw256_mask, "V16sV16sV16sV16sUs", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvw512_mask, "V32sV32sV32sV32sUi", "ncV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvd128_maskz, "V4iV4iV4iV4iUc", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvd256_maskz, "V8iV8iV8iV8iUc", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvd512_maskz, "V16iV16iV16iV16iUs", "ncV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvq128_maskz, "V2LLiV2LLiV2LLiV2LLiUc", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvq256_maskz, "V4LLiV4LLiV4LLiV4LLiUc", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvq512_maskz, "V8LLiV8LLiV8LLiV8LLiUc", "ncV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvw128_maskz, "V8sV8sV8sV8sUc", "ncV:128:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvw256_maskz, "V16sV16sV16sV16sUs", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvw512_maskz, "V32sV32sV32sV32sUi", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvd128, "V4iV4iV4iV4i", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvd256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvd512, "V16iV16iV16iV16i", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvq128, "V2LLiV2LLiV2LLiV2LLi", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvq256, "V4LLiV4LLiV4LLiV4LLi", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvq512, "V8LLiV8LLiV8LLiV8LLi", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvw128, "V8sV8sV8sV8s", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvw256, "V16sV16sV16sV16s", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvw512, "V32sV32sV32sV32s", "ncV:512:", "avx512vbmi2")
+
+TARGET_BUILTIN(__builtin_ia32_vpshrdvd128, "V4iV4iV4iV4i", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvd256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvd512, "V16iV16iV16iV16i", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvq128, "V2LLiV2LLiV2LLiV2LLi", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvq256, "V4LLiV4LLiV4LLiV4LLi", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvq512, "V8LLiV8LLiV8LLiV8LLi", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvw128, "V8sV8sV8sV8s", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvw256, "V16sV16sV16sV16s", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvw512, "V32sV32sV32sV32s", "ncV:512:", "avx512vbmi2")
TARGET_BUILTIN(__builtin_ia32_vpshrdd128, "V4iV4iV4iIi", "ncV:128:", "avx512vl,avx512vbmi2")
TARGET_BUILTIN(__builtin_ia32_vpshrdd256, "V8iV8iV8iIi", "ncV:256:", "avx512vl,avx512vbmi2")
@@ -1734,14 +1724,59 @@ TARGET_BUILTIN(__builtin_ia32_fpclassps512_mask, "UsV16fIiUs", "ncV:512:", "avx5
TARGET_BUILTIN(__builtin_ia32_fpclasspd512_mask, "UcV8dIiUc", "ncV:512:", "avx512dq")
TARGET_BUILTIN(__builtin_ia32_fpclasssd_mask, "UcV2dIiUc", "ncV:128:", "avx512dq")
TARGET_BUILTIN(__builtin_ia32_fpclassss_mask, "UcV4fIiUc", "ncV:128:", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_kaddqi, "UcUcUc", "nc", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_kaddhi, "UsUsUs", "nc", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_kaddsi, "UiUiUi", "nc", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_kadddi, "ULLiULLiULLi", "nc", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_kandqi, "UcUcUc", "nc", "avx512dq")
TARGET_BUILTIN(__builtin_ia32_kandhi, "UsUsUs", "nc", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_kandsi, "UiUiUi", "nc", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_kanddi, "ULLiULLiULLi", "nc", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_kandnqi, "UcUcUc", "nc", "avx512dq")
TARGET_BUILTIN(__builtin_ia32_kandnhi, "UsUsUs", "nc", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_kandnsi, "UiUiUi", "nc", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_kandndi, "ULLiULLiULLi", "nc", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_korqi, "UcUcUc", "nc", "avx512dq")
TARGET_BUILTIN(__builtin_ia32_korhi, "UsUsUs", "nc", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_korsi, "UiUiUi", "nc", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_kordi, "ULLiULLiULLi", "nc", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_kortestcqi, "iUcUc", "nc", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_kortestzqi, "iUcUc", "nc", "avx512dq")
TARGET_BUILTIN(__builtin_ia32_kortestchi, "iUsUs", "nc", "avx512f")
TARGET_BUILTIN(__builtin_ia32_kortestzhi, "iUsUs", "nc", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_kortestcsi, "iUiUi", "nc", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_kortestzsi, "iUiUi", "nc", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_kortestcdi, "iULLiULLi", "nc", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_kortestzdi, "iULLiULLi", "nc", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_ktestcqi, "iUcUc", "nc", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_ktestzqi, "iUcUc", "nc", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_ktestchi, "iUsUs", "nc", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_ktestzhi, "iUsUs", "nc", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_ktestcsi, "iUiUi", "nc", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_ktestzsi, "iUiUi", "nc", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_ktestcdi, "iULLiULLi", "nc", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_ktestzdi, "iULLiULLi", "nc", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_kunpckhi, "UsUsUs", "nc", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_kxnorqi, "UcUcUc", "nc", "avx512dq")
TARGET_BUILTIN(__builtin_ia32_kxnorhi, "UsUsUs", "nc", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_kxnorsi, "UiUiUi", "nc", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_kxnordi, "ULLiULLiULLi", "nc", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_kxorqi, "UcUcUc", "nc", "avx512dq")
TARGET_BUILTIN(__builtin_ia32_kxorhi, "UsUsUs", "nc", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_kxorsi, "UiUiUi", "nc", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_kxordi, "ULLiULLiULLi", "nc", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_kshiftliqi, "UcUcIUi", "nc", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_kshiftlihi, "UsUsIUi", "nc", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_kshiftlisi, "UiUiIUi", "nc", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_kshiftlidi, "ULLiULLiIUi", "nc", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_kshiftriqi, "UcUcIUi", "nc", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_kshiftrihi, "UsUsIUi", "nc", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_kshiftrisi, "UiUiIUi", "nc", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_kshiftridi, "ULLiULLiIUi", "nc", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_kmovb, "UcUc", "nc", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_kmovw, "UsUs", "nc", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_kmovd, "UiUi", "nc", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_kmovq, "ULLiULLi", "nc", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_palignr512, "V64cV64cV64cIi", "ncV:512:", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_dbpsadbw128, "V8sV16cV16cIi", "ncV:128:", "avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_dbpsadbw256, "V16sV32cV32cIi", "ncV:256:", "avx512bw,avx512vl")
@@ -1786,9 +1821,9 @@ TARGET_BUILTIN(__builtin_ia32_cvtsd2ss_round_mask, "V4fV4fV2dV4fUcIi", "ncV:128:
TARGET_BUILTIN(__builtin_ia32_cvtsi2ss32, "V4fV4fiIi", "ncV:128:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_cvtss2sd_round_mask, "V2dV2dV4fV2dUcIi", "ncV:128:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_cvtusi2ss32, "V4fV4fUiIi", "ncV:128:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb512_mask, "V64cV64cV64cV64cULLi", "ncV:512:", "avx512vbmi")
-TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb128_mask, "V16cV16cV16cV16cUs", "ncV:128:", "avx512vbmi,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb256_mask, "V32cV32cV32cV32cUi", "ncV:256:", "avx512vbmi,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb512, "V64cV64cV64c", "ncV:512:", "avx512vbmi")
+TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb128, "V16cV16cV16c", "ncV:128:", "avx512vbmi,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb256, "V32cV32cV32c", "ncV:256:", "avx512vbmi,avx512vl")
// generic select intrinsics
TARGET_BUILTIN(__builtin_ia32_selectb_128, "V16cUsV16cV16c", "ncV:128:", "avx512bw,avx512vl")
diff --git a/include/clang/Basic/BuiltinsX86_64.def b/include/clang/Basic/BuiltinsX86_64.def
index cc400c0697f9..5e8cce5c6e5e 100644
--- a/include/clang/Basic/BuiltinsX86_64.def
+++ b/include/clang/Basic/BuiltinsX86_64.def
@@ -31,6 +31,8 @@ TARGET_HEADER_BUILTIN(_mul128, "LLiLLiLLiLLi*", "nch", "intrin.h", ALL_MS
TARGET_HEADER_BUILTIN(_umul128, "ULLiULLiULLiULLi*", "nch", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(__faststorefence, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__shiftleft128, "ULLiULLiULLiUc", "nch", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__shiftright128, "ULLiULLiULLiUc", "nch", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_InterlockedAnd64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_InterlockedDecrement64, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
@@ -74,12 +76,13 @@ TARGET_BUILTIN(__builtin_ia32_incsspq, "vULLi", "n", "shstk")
TARGET_BUILTIN(__builtin_ia32_rdsspq, "ULLiULLi", "n", "shstk")
TARGET_BUILTIN(__builtin_ia32_wrssq, "vULLiv*", "n", "shstk")
TARGET_BUILTIN(__builtin_ia32_wrussq, "vULLiv*", "n", "shstk")
-TARGET_BUILTIN(__builtin_ia32_addcarryx_u64, "UcUcULLiULLiULLi*", "n", "adx")
-TARGET_BUILTIN(__builtin_ia32_addcarry_u64, "UcUcULLiULLiULLi*", "n", "")
+TARGET_BUILTIN(__builtin_ia32_addcarryx_u64, "UcUcULLiULLiULLi*", "n", "")
TARGET_BUILTIN(__builtin_ia32_subborrow_u64, "UcUcULLiULLiULLi*", "n", "")
TARGET_BUILTIN(__builtin_ia32_rdrand64_step, "UiULLi*", "n", "rdrnd")
TARGET_BUILTIN(__builtin_ia32_rdseed64_step, "UiULLi*", "n", "rdseed")
+TARGET_BUILTIN(__builtin_ia32_lzcnt_u64, "ULLiULLi", "nc", "lzcnt")
TARGET_BUILTIN(__builtin_ia32_bextr_u64, "ULLiULLiULLi", "nc", "bmi")
+TARGET_BUILTIN(__builtin_ia32_tzcnt_u64, "ULLiULLi", "nc", "")
TARGET_BUILTIN(__builtin_ia32_bzhi_di, "ULLiULLiULLi", "nc", "bmi2")
TARGET_BUILTIN(__builtin_ia32_pdep_di, "ULLiULLiULLi", "nc", "bmi2")
TARGET_BUILTIN(__builtin_ia32_pext_di, "ULLiULLiULLi", "nc", "bmi2")
diff --git a/include/clang/Frontend/CodeGenOptions.def b/include/clang/Basic/CodeGenOptions.def
index a7e71f7ac016..ed2387b9a2e2 100644
--- a/include/clang/Frontend/CodeGenOptions.def
+++ b/include/clang/Basic/CodeGenOptions.def
@@ -62,6 +62,8 @@ CODEGENOPT(ExperimentalNewPassManager, 1, 0) ///< Enables the new, experimental
CODEGENOPT(DebugPassManager, 1, 0) ///< Prints debug information for the new
///< pass manager.
CODEGENOPT(DisableRedZone , 1, 0) ///< Set when -mno-red-zone is enabled.
+CODEGENOPT(IndirectTlsSegRefs, 1, 0) ///< Set when -mno-tls-direct-seg-refs
+ ///< is specified.
CODEGENOPT(DisableTailCalls , 1, 0) ///< Do not emit tail calls.
CODEGENOPT(NoEscapingBlockTailCalls, 1, 0) ///< Do not emit tail calls from
///< escaping blocks.
@@ -114,6 +116,10 @@ CODEGENOPT(PrepareForThinLTO , 1, 0) ///< Set when -flto=thin is enabled on the
///< compile step.
CODEGENOPT(LTOUnit, 1, 0) ///< Emit IR to support LTO unit features (CFI, whole
///< program vtable opt).
+CODEGENOPT(EnableSplitLTOUnit, 1, 0) ///< Enable LTO unit splitting to support
+ /// CFI and traditional whole program
+ /// devirtualization that require whole
+ /// program IR support.
CODEGENOPT(IncrementalLinkerCompatible, 1, 0) ///< Emit an object file which can
///< be used with an incremental
///< linker.
@@ -147,6 +153,8 @@ CODEGENOPT(UniformWGSize , 1, 0) ///< -cl-uniform-work-group-size
CODEGENOPT(NoZeroInitializedInBSS , 1, 0) ///< -fno-zero-initialized-in-bss.
/// Method of Objective-C dispatch to use.
ENUM_CODEGENOPT(ObjCDispatchMethod, ObjCDispatchMethodKind, 2, Legacy)
+/// Replace certain message sends with calls to ObjC runtime entrypoints
+CODEGENOPT(ObjCConvertMessagesToRuntimeCalls , 1, 1)
CODEGENOPT(OmitLeafFramePointer , 1, 0) ///< Set when -momit-leaf-frame-pointer is
///< enabled.
@@ -172,11 +180,12 @@ CODEGENOPT(NewStructPathTBAA , 1, 0) ///< Whether or not to use enhanced struct-
CODEGENOPT(SaveTempLabels , 1, 0) ///< Save temporary labels.
CODEGENOPT(SanitizeAddressUseAfterScope , 1, 0) ///< Enable use-after-scope detection
///< in AddressSanitizer
-CODEGENOPT(SanitizeAddressPoisonClassMemberArrayNewCookie, 1,
+CODEGENOPT(SanitizeAddressPoisonCustomArrayCookie, 1,
0) ///< Enable poisoning operator new[] which is not a replaceable
///< global allocation function in AddressSanitizer
CODEGENOPT(SanitizeAddressGlobalsDeadStripping, 1, 0) ///< Enable linker dead stripping
///< of globals in AddressSanitizer
+CODEGENOPT(SanitizeAddressUseOdrIndicator, 1, 0) ///< Enable ODR indicator globals
CODEGENOPT(SanitizeMemoryTrackOrigins, 2, 0) ///< Enable tracking origins in
///< MemorySanitizer
CODEGENOPT(SanitizeMemoryUseAfterDtor, 1, 0) ///< Enable use-after-delete detection
@@ -211,6 +220,7 @@ CODEGENOPT(SanitizeCoverageStackDepth, 1, 0) ///< Enable max stack depth tracing
CODEGENOPT(SanitizeStats , 1, 0) ///< Collect statistics for sanitizers.
CODEGENOPT(SimplifyLibCalls , 1, 1) ///< Set when -fbuiltin is enabled.
CODEGENOPT(SoftFloat , 1, 0) ///< -soft-float.
+CODEGENOPT(SpeculativeLoadHardening, 1, 0) ///< Enable speculative load hardening.
CODEGENOPT(FineGrainedBitfieldAccesses, 1, 0) ///< Enable fine-grained bitfield accesses.
CODEGENOPT(StrictEnums , 1, 0) ///< Optimize based on strict enum definition.
CODEGENOPT(StrictVTablePointers, 1, 0) ///< Optimize based on the strict vtable pointers
@@ -249,7 +259,9 @@ CODEGENOPT(DebugTypeExtRefs, 1, 0) ///< Whether or not debug info should contain
CODEGENOPT(DebugExplicitImport, 1, 0) ///< Whether or not debug info should
///< contain explicit imports for
///< anonymous namespaces
-CODEGENOPT(EnableSplitDwarf, 1, 0) ///< Whether to enable split DWARF
+
+ENUM_CODEGENOPT(SplitDwarfMode, DwarfFissionKind, 2, NoFission) ///< DWARF fission mode to use.
+
CODEGENOPT(SplitDwarfInlining, 1, 1) ///< Whether to include inlining info in the
///< skeleton CU to allow for symbolication
///< of inline stack frames without .dwo files.
@@ -292,6 +304,9 @@ VALUE_CODEGENOPT(DwarfVersion, 3, 0)
/// CodeView and DWARF into the same object.
CODEGENOPT(EmitCodeView, 1, 0)
+/// Whether to emit the .debug$H section containing hashes of CodeView types.
+CODEGENOPT(CodeViewGHash, 1, 0)
+
/// The kind of inlining to perform.
ENUM_CODEGENOPT(Inlining, InliningMethod, 2, NormalInlining)
@@ -326,7 +341,10 @@ CODEGENOPT(DebugInfoForProfiling, 1, 0)
CODEGENOPT(PreserveVec3Type, 1, 0)
/// Whether to emit .debug_gnu_pubnames section instead of .debug_pubnames.
-CODEGENOPT(GnuPubnames, 1, 0)
+CODEGENOPT(DebugNameTable, 2, 0)
+
+/// Whether to use DWARF base address specifiers in .debug_ranges.
+CODEGENOPT(DebugRangesBaseAddress, 1, 0)
CODEGENOPT(NoPLT, 1, 0)
@@ -339,6 +357,12 @@ CODEGENOPT(ForceEmitVTables, 1, 0)
/// Whether to emit an address-significance table into the object file.
CODEGENOPT(Addrsig, 1, 0)
+ENUM_CODEGENOPT(SignReturnAddress, SignReturnAddressScope, 2, None)
+ENUM_CODEGENOPT(SignReturnAddressKey, SignReturnAddressKeyValue, 1, AKey)
+CODEGENOPT(BranchTargetEnforcement, 1, 0)
+
+/// Whether to emit unused static constants.
+CODEGENOPT(KeepStaticConsts, 1, 0)
#undef CODEGENOPT
#undef ENUM_CODEGENOPT
diff --git a/include/clang/Frontend/CodeGenOptions.h b/include/clang/Basic/CodeGenOptions.h
index a6d061acf0f4..ec6eda7fb788 100644
--- a/include/clang/Frontend/CodeGenOptions.h
+++ b/include/clang/Basic/CodeGenOptions.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_FRONTEND_CODEGENOPTIONS_H
-#define LLVM_CLANG_FRONTEND_CODEGENOPTIONS_H
+#ifndef LLVM_CLANG_BASIC_CODEGENOPTIONS_H
+#define LLVM_CLANG_BASIC_CODEGENOPTIONS_H
#include "clang/Basic/DebugInfoOptions.h"
#include "clang/Basic/Sanitizers.h"
@@ -33,12 +33,12 @@ class CodeGenOptionsBase {
public:
#define CODEGENOPT(Name, Bits, Default) unsigned Name : Bits;
#define ENUM_CODEGENOPT(Name, Type, Bits, Default)
-#include "clang/Frontend/CodeGenOptions.def"
+#include "clang/Basic/CodeGenOptions.def"
protected:
#define CODEGENOPT(Name, Bits, Default)
#define ENUM_CODEGENOPT(Name, Type, Bits, Default) unsigned Name : Bits;
-#include "clang/Frontend/CodeGenOptions.def"
+#include "clang/Basic/CodeGenOptions.def"
};
/// CodeGenOptions - Track various options which control how the code
@@ -71,6 +71,8 @@ public:
LocalExecTLSModel
};
+ enum DwarfFissionKind { NoFission, SplitFileFission, SingleFileFission };
+
/// Clang versions with different platform ABI conformance.
enum class ClangABI {
/// Attempt to be ABI-compatible with code generated by Clang 3.8.x
@@ -108,6 +110,14 @@ public:
Embed_Marker // Embed a marker as a placeholder for bitcode.
};
+ enum SignReturnAddressScope {
+ None, // No signing for any function
+ NonLeaf, // Sign the return address of functions that spill LR
+ All // Sign the return address of all functions
+ };
+
+ enum SignReturnAddressKeyValue { AKey, BKey };
+
/// The code model to use (-mcmodel).
std::string CodeModel;
@@ -119,6 +129,12 @@ public:
/// The filename with path we use for coverage notes files.
std::string CoverageNotesFile;
+ /// Regexes separated by a semi-colon to filter the files to instrument.
+ std::string ProfileFilterFiles;
+
+ /// Regexes separated by a semi-colon to filter the files to not instrument.
+ std::string ProfileExcludeFiles;
+
/// The version string to put into coverage files.
char CoverageVersion[4];
@@ -132,6 +148,10 @@ public:
/// non-empty.
std::string DwarfDebugFlags;
+ /// The string containing the commandline for the llvm.commandline metadata,
+ /// if non-empty.
+ std::string RecordCommandLine;
+
std::map<std::string, std::string> DebugPrefixMap;
/// The ABI to use for passing floating point arguments.
@@ -194,6 +214,10 @@ public:
/// Name of the profile file to use as input for -fprofile-instr-use
std::string ProfileInstrumentUsePath;
+ /// Name of the profile remapping file to apply to the profile data supplied
+ /// by -fprofile-sample-use or -fprofile-instr-use.
+ std::string ProfileRemappingFile;
+
/// Name of the function summary index file to use for ThinLTO function
/// importing.
std::string ThinLTOIndexFile;
@@ -262,13 +286,15 @@ public:
/// Set of XRay instrumentation kinds to emit.
XRayInstrSet XRayInstrumentationBundle;
+ std::vector<std::string> DefaultFunctionAttrs;
+
public:
// Define accessors/mutators for code generation options of enumeration type.
#define CODEGENOPT(Name, Bits, Default)
#define ENUM_CODEGENOPT(Name, Type, Bits, Default) \
Type get##Name() const { return static_cast<Type>(Name); } \
void set##Name(Type Value) { Name = static_cast<unsigned>(Value); }
-#include "clang/Frontend/CodeGenOptions.def"
+#include "clang/Basic/CodeGenOptions.def"
CodeGenOptions();
diff --git a/include/clang/Basic/Cuda.h b/include/clang/Basic/Cuda.h
index 24159e160f3f..0575e703338e 100644
--- a/include/clang/Basic/Cuda.h
+++ b/include/clang/Basic/Cuda.h
@@ -24,7 +24,8 @@ enum class CudaVersion {
CUDA_90,
CUDA_91,
CUDA_92,
- LATEST = CUDA_92,
+ CUDA_100,
+ LATEST = CUDA_100,
};
const char *CudaVersionToString(CudaVersion V);
@@ -47,6 +48,7 @@ enum class CudaArch {
SM_62,
SM_70,
SM_72,
+ SM_75,
GFX600,
GFX601,
GFX700,
@@ -60,6 +62,9 @@ enum class CudaArch {
GFX810,
GFX900,
GFX902,
+ GFX904,
+ GFX906,
+ GFX909,
LAST,
};
const char *CudaArchToString(CudaArch A);
@@ -82,6 +87,7 @@ enum class CudaVirtualArch {
COMPUTE_62,
COMPUTE_70,
COMPUTE_72,
+ COMPUTE_75,
COMPUTE_AMDGCN,
};
const char *CudaVirtualArchToString(CudaVirtualArch A);
diff --git a/include/clang/Basic/DebugInfoOptions.h b/include/clang/Basic/DebugInfoOptions.h
index 037c813c6114..f3be0fe52d31 100644
--- a/include/clang/Basic/DebugInfoOptions.h
+++ b/include/clang/Basic/DebugInfoOptions.h
@@ -13,6 +13,11 @@
namespace clang {
namespace codegenoptions {
+enum DebugInfoFormat {
+ DIF_DWARF,
+ DIF_CodeView,
+};
+
enum DebugInfoKind {
NoDebugInfo, /// Don't generate debug info.
LocTrackingOnly, /// Emit location information but do not generate
@@ -21,6 +26,7 @@ enum DebugInfoKind {
/// locations for instructions without actually
/// emitting debug info for them (e.g., when -Rpass
/// is used).
+ DebugDirectivesOnly, /// Emit only debug directives with the line numbers data
DebugLineTablesOnly, /// Emit only debug info necessary for generating
/// line number tables (-gline-tables-only).
LimitedDebugInfo, /// Limit generated debug info to reduce size
diff --git a/include/clang/Basic/DeclNodes.td b/include/clang/Basic/DeclNodes.td
index 67ca9e5c6c62..a184b480f7c0 100644
--- a/include/clang/Basic/DeclNodes.td
+++ b/include/clang/Basic/DeclNodes.td
@@ -97,5 +97,6 @@ def Captured : Decl, DeclContext;
def ClassScopeFunctionSpecialization : Decl;
def Import : Decl;
def OMPThreadPrivate : Decl;
+def OMPRequires : Decl;
def Empty : Decl;
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h
index d30ac14e02fe..a516721ace6d 100644
--- a/include/clang/Basic/Diagnostic.h
+++ b/include/clang/Basic/Diagnostic.h
@@ -177,6 +177,9 @@ public:
/// IdentifierInfo
ak_identifierinfo,
+ /// Qualifiers
+ ak_qual,
+
/// QualType
ak_qualtype,
@@ -486,10 +489,8 @@ public:
DiagnosticsEngine &operator=(const DiagnosticsEngine &) = delete;
~DiagnosticsEngine();
- LLVM_DUMP_METHOD void dump() const { DiagStatesByLoc.dump(*SourceMgr); }
- LLVM_DUMP_METHOD void dump(StringRef DiagName) const {
- DiagStatesByLoc.dump(*SourceMgr, DiagName);
- }
+ LLVM_DUMP_METHOD void dump() const;
+ LLVM_DUMP_METHOD void dump(StringRef DiagName) const;
const IntrusiveRefCntPtr<DiagnosticIDs> &getDiagnosticIDs() const {
return Diags;
diff --git a/include/clang/Basic/DiagnosticAST.h b/include/clang/Basic/DiagnosticAST.h
new file mode 100644
index 000000000000..b0e9178d9b0b
--- /dev/null
+++ b/include/clang/Basic/DiagnosticAST.h
@@ -0,0 +1,29 @@
+//===--- DiagnosticAST.h - Diagnostics for the AST library ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_DIAGNOSTICAST_H
+#define LLVM_CLANG_BASIC_DIAGNOSTICAST_H
+
+#include "clang/Basic/Diagnostic.h"
+
+namespace clang {
+namespace diag {
+enum {
+#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
+ SHOWINSYSHEADER, CATEGORY) \
+ ENUM,
+#define ASTSTART
+#include "clang/Basic/DiagnosticASTKinds.inc"
+#undef DIAG
+ NUM_BUILTIN_AST_DIAGNOSTICS
+};
+} // end namespace diag
+} // end namespace clang
+
+#endif // LLVM_CLANG_BASIC_DIAGNOSTICAST_H
diff --git a/include/clang/Basic/DiagnosticASTKinds.td b/include/clang/Basic/DiagnosticASTKinds.td
index 3358fc3d70c7..c39673a44ac0 100644
--- a/include/clang/Basic/DiagnosticASTKinds.td
+++ b/include/clang/Basic/DiagnosticASTKinds.td
@@ -121,6 +121,8 @@ def note_constexpr_ltor_non_const_int : Note<
"read of non-const variable %0 is not allowed in a constant expression">;
def note_constexpr_ltor_non_constexpr : Note<
"read of non-constexpr variable %0 is not allowed in a constant expression">;
+def note_constexpr_ltor_incomplete_type : Note<
+ "read of incomplete type %0 is not allowed in a constant expression">;
def note_constexpr_access_null : Note<
"%select{read of|assignment to|increment of|decrement of}0 "
"dereferenced null pointer is not allowed in a constant expression">;
@@ -163,12 +165,19 @@ def note_constexpr_unsupported_unsized_array : Note<
def note_constexpr_unsized_array_indexed : Note<
"indexing of array without known bound is not allowed "
"in a constant expression">;
+def note_constexpr_memcpy_null : Note<
+ "%select{source|destination}2 of "
+ "'%select{%select{memcpy|wmemcpy}1|%select{memmove|wmemmove}1}0' "
+ "is %3">;
def note_constexpr_memcpy_type_pun : Note<
"cannot constant evaluate '%select{memcpy|memmove}0' from object of "
"type %1 to object of type %2">;
def note_constexpr_memcpy_nontrivial : Note<
"cannot constant evaluate '%select{memcpy|memmove}0' between objects of "
"non-trivially-copyable type %1">;
+def note_constexpr_memcpy_incomplete_type : Note<
+ "cannot constant evaluate '%select{memcpy|memmove}0' between objects of "
+ "incomplete type %1">;
def note_constexpr_memcpy_overlap : Note<
"'%select{memcpy|wmemcpy}0' between overlapping memory regions">;
def note_constexpr_memcpy_unsupported : Note<
@@ -305,4 +314,34 @@ def err_odr_non_type_parameter_type_inconsistent : Error<
"non-type template parameter declared with incompatible types in different "
"translation units (%0 vs. %1)">;
def err_unsupported_ast_node: Error<"cannot import unsupported AST node %0">;
+
+def remark_sanitize_address_insert_extra_padding_accepted : Remark<
+ "-fsanitize-address-field-padding applied to %0">, ShowInSystemHeader,
+ InGroup<SanitizeAddressRemarks>;
+def remark_sanitize_address_insert_extra_padding_rejected : Remark<
+ "-fsanitize-address-field-padding ignored for %0 because it "
+ "%select{is not C++|is packed|is a union|is trivially copyable|"
+ "has trivial destructor|is standard layout|is in a blacklisted file|"
+ "is blacklisted}1">, ShowInSystemHeader,
+ InGroup<SanitizeAddressRemarks>;
+
+def warn_npot_ms_struct : Warning<
+ "ms_struct may not produce Microsoft-compatible layouts with fundamental "
+ "data types with sizes that aren't a power of two">,
+ DefaultError, InGroup<IncompatibleMSStruct>;
+
+// -Wpadded, -Wpacked
+def warn_padded_struct_field : Warning<
+ "padding %select{struct|interface|class}0 %1 with %2 "
+ "%select{byte|bit}3%s2 to align %4">,
+ InGroup<Padded>, DefaultIgnore;
+def warn_padded_struct_anon_field : Warning<
+ "padding %select{struct|interface|class}0 %1 with %2 "
+ "%select{byte|bit}3%s2 to align anonymous bit-field">,
+ InGroup<Padded>, DefaultIgnore;
+def warn_padded_struct_size : Warning<
+ "padding size of %0 with %1 %select{byte|bit}2%s1 to alignment boundary">,
+ InGroup<Padded>, DefaultIgnore;
+def warn_unnecessary_packed : Warning<
+ "packed attribute is unnecessary for %0">, InGroup<Packed>, DefaultIgnore;
}
diff --git a/include/clang/Basic/DiagnosticAnalysis.h b/include/clang/Basic/DiagnosticAnalysis.h
new file mode 100644
index 000000000000..3748b538d2d2
--- /dev/null
+++ b/include/clang/Basic/DiagnosticAnalysis.h
@@ -0,0 +1,29 @@
+//===--- DiagnosticAnalysis.h - Diagnostics for libanalysis -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_DIAGNOSTICANALYSIS_H
+#define LLVM_CLANG_BASIC_DIAGNOSTICANALYSIS_H
+
+#include "clang/Basic/Diagnostic.h"
+
+namespace clang {
+namespace diag {
+enum {
+#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
+ SHOWINSYSHEADER, CATEGORY) \
+ ENUM,
+#define ANALYSISSTART
+#include "clang/Basic/DiagnosticAnalysisKinds.inc"
+#undef DIAG
+ NUM_BUILTIN_ANALYSIS_DIAGNOSTICS
+};
+} // end namespace diag
+} // end namespace clang
+
+#endif // LLVM_CLANG_BASIC_DIAGNOSTICANALYSIS_H
diff --git a/include/clang/Basic/DiagnosticComment.h b/include/clang/Basic/DiagnosticComment.h
new file mode 100644
index 000000000000..a6c5f182cb32
--- /dev/null
+++ b/include/clang/Basic/DiagnosticComment.h
@@ -0,0 +1,29 @@
+//===--- DiagnosticComment.h - Diagnostics for the AST library --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_DIAGNOSTICCOMMENT_H
+#define LLVM_CLANG_BASIC_DIAGNOSTICCOMMENT_H
+
+#include "clang/Basic/Diagnostic.h"
+
+namespace clang {
+namespace diag {
+enum {
+#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
+ SHOWINSYSHEADER, CATEGORY) \
+ ENUM,
+#define COMMENTSTART
+#include "clang/Basic/DiagnosticCommentKinds.inc"
+#undef DIAG
+ NUM_BUILTIN_COMMENT_DIAGNOSTICS
+};
+} // end namespace diag
+} // end namespace clang
+
+#endif // LLVM_CLANG_BASIC_DIAGNOSTICCOMMENT_H
diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td
index b98b183c9d6f..34ce489e50b2 100644
--- a/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/include/clang/Basic/DiagnosticCommonKinds.td
@@ -131,6 +131,36 @@ def err_nullability_conflicting : Error<
}
+// OpenCL Section 6.8.g
+def err_opencl_unknown_type_specifier : Error<
+ "OpenCL %select{C|C++}0 version %1 does not support the '%2' "
+ "%select{type qualifier|storage class specifier}3">;
+
+def warn_unknown_attribute_ignored : Warning<
+ "unknown attribute %0 ignored">, InGroup<UnknownAttributes>;
+def err_use_of_tag_name_without_tag : Error<
+ "must use '%1' tag to refer to type %0%select{| in this scope}2">;
+
+def duplicate_declspec : TextSubstitution<
+ "duplicate '%0' declaration specifier">;
+
+def ext_duplicate_declspec : Extension<"%sub{duplicate_declspec}0">,
+ InGroup<DuplicateDeclSpecifier>;
+def ext_warn_duplicate_declspec : ExtWarn<"%sub{duplicate_declspec}0">,
+ InGroup<DuplicateDeclSpecifier>;
+def warn_duplicate_declspec : Warning<"%sub{duplicate_declspec}0">,
+ InGroup<DuplicateDeclSpecifier>;
+
+def err_friend_decl_spec : Error<"'%0' is invalid in friend declarations">;
+
+def err_invalid_member_in_interface : Error<
+ "%select{data member |non-public member function |static member function |"
+ "user-declared constructor|user-declared destructor|operator |"
+ "nested class }0%1 is not permitted within an interface type">;
+
+def err_attribute_uuid_malformed_guid : Error<
+ "uuid attribute contains a malformed GUID">;
+
// Sema && Lex
def ext_c99_longlong : Extension<
"'long long' is an extension when C99 mode is not enabled">,
@@ -172,6 +202,8 @@ def err_too_large_for_fixed_point : Error<
"this value is too large for this fixed point type">;
def err_fixed_point_not_enabled : Error<"compile with "
"'-ffixed-point' to enable fixed point types">;
+def err_unimplemented_conversion_with_fixed_point_type : Error<
+ "conversion between fixed point and %0 is not yet supported">;
// SEH
def err_seh_expected_handler : Error<
@@ -187,6 +219,16 @@ def err_seh___finally_block : Error<
def note_invalid_subexpr_in_const_expr : Note<
"subexpression not valid in a constant expression">;
+// Sema && Frontend
+let CategoryName = "Inline Assembly Issue" in {
+ def err_asm_invalid_type_in_input : Error<
+ "invalid type %0 in asm input for constraint '%1'">;
+}
+
+// Sema && Serialization
+def warn_dup_category_def : Warning<
+ "duplicate definition of category %1 on interface %0">;
+
// Targets
def err_target_unknown_triple : Error<
@@ -199,6 +241,9 @@ def err_target_unknown_abi : Error<"unknown target ABI '%0'">;
def err_target_unsupported_abi : Error<"ABI '%0' is not supported on CPU '%1'">;
def err_target_unsupported_abi_for_triple : Error<
"ABI '%0' is not supported for '%1'">;
+def err_unsupported_abi_for_opt : Error<"'%0' can only be used with the '%1' ABI">;
+def err_mips_fp64_req : Error<
+ "'%0' can only be used if the target supports the mfhc1 and mthc1 instructions">;
def err_target_unknown_fpmath : Error<"unknown FP unit '%0'">;
def err_target_unsupported_fpmath : Error<
"the '%0' unit is not supported with this instruction set">;
@@ -245,4 +290,10 @@ def err_openclcxx_not_supported : Error<
// OpenMP
def err_omp_more_one_clause : Error<
"directive '#pragma omp %0' cannot contain more than one '%1' clause%select{| with '%3' name modifier| with 'source' dependence}2">;
+
+// Static Analyzer Core
+def err_unknown_analyzer_checker : Error<
+ "no analyzer checkers are associated with '%0'">;
+def note_suggest_disabling_all_checkers : Note<
+ "use -analyzer-disable-all-checks to disable all static analyzer checkers">;
}
diff --git a/include/clang/Basic/DiagnosticCrossTU.h b/include/clang/Basic/DiagnosticCrossTU.h
new file mode 100644
index 000000000000..8cff33479f43
--- /dev/null
+++ b/include/clang/Basic/DiagnosticCrossTU.h
@@ -0,0 +1,29 @@
+//===--- DiagnosticCrossTU.h - Diagnostics for Cross TU ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_DIAGNOSTICCROSSTU_H
+#define LLVM_CLANG_BASIC_DIAGNOSTICCROSSTU_H
+
+#include "clang/Basic/Diagnostic.h"
+
+namespace clang {
+namespace diag {
+enum {
+#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
+ SHOWINSYSHEADER, CATEGORY) \
+ ENUM,
+#define CROSSTUSTART
+#include "clang/Basic/DiagnosticCrossTUKinds.inc"
+#undef DIAG
+ NUM_BUILTIN_CROSSTU_DIAGNOSTICS
+};
+} // end namespace diag
+} // end namespace clang
+
+#endif // LLVM_CLANG_BASIC_DIAGNOSTICCROSSTU_H
diff --git a/include/clang/Basic/DiagnosticCrossTUKinds.td b/include/clang/Basic/DiagnosticCrossTUKinds.td
index 8b6d8b681445..89e261c84bc6 100644
--- a/include/clang/Basic/DiagnosticCrossTUKinds.td
+++ b/include/clang/Basic/DiagnosticCrossTUKinds.td
@@ -9,10 +9,17 @@
let Component = "CrossTU" in {
-def err_fnmap_parsing : Error<
+def err_ctu_error_opening : Error<
+ "error opening '%0': required by the CrossTU functionality">;
+
+def err_extdefmap_parsing : Error<
"error parsing index file: '%0' line: %1 'UniqueID filename' format "
"expected">;
def err_multiple_def_index : Error<
"multiple definitions are found for the same key in index ">;
+
+def warn_ctu_incompat_triple : Warning<
+ "imported AST from '%0' had been generated for a different target, "
+ "current: %1, imported: %2">, InGroup<CrossTU>;
}
diff --git a/include/clang/Basic/DiagnosticDriver.h b/include/clang/Basic/DiagnosticDriver.h
new file mode 100644
index 000000000000..2ab9b3e08366
--- /dev/null
+++ b/include/clang/Basic/DiagnosticDriver.h
@@ -0,0 +1,29 @@
+//===--- DiagnosticDriver.h - Diagnostics for libdriver ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_DIAGNOSTICDRIVER_H
+#define LLVM_CLANG_BASIC_DIAGNOSTICDRIVER_H
+
+#include "clang/Basic/Diagnostic.h"
+
+namespace clang {
+namespace diag {
+enum {
+#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
+ SHOWINSYSHEADER, CATEGORY) \
+ ENUM,
+#define DRIVERSTART
+#include "clang/Basic/DiagnosticDriverKinds.inc"
+#undef DIAG
+ NUM_BUILTIN_DRIVER_DIAGNOSTICS
+};
+} // end namespace diag
+} // end namespace clang
+
+#endif // LLVM_CLANG_BASIC_DIAGNOSTICDRIVER_H
diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td
index 7f75f45c6578..5475e28ed754 100644
--- a/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/include/clang/Basic/DiagnosticDriverKinds.td
@@ -151,9 +151,6 @@ def warn_drv_unknown_argument_clang_cl_with_suggestion : Warning<
"unknown argument ignored in clang-cl '%0' (did you mean '%1'?)">,
InGroup<UnknownArgument>;
-def warn_drv_ycyu_no_arg_clang_cl : Warning<
- "support for '%0' without a filename not implemented yet; flag ignored">,
- InGroup<ClangClPch>;
def warn_drv_ycyu_different_arg_clang_cl : Warning<
"support for '/Yc' and '/Yu' with different filenames not implemented yet; flags ignored">,
InGroup<ClangClPch>;
@@ -164,6 +161,9 @@ def warn_drv_yc_multiple_inputs_clang_cl : Warning<
"support for '/Yc' with more than one source file not implemented yet; flag ignored">,
InGroup<ClangClPch>;
+def err_drv_dllexport_inlines_and_fallback : Error<
+ "option '/Zc:dllexportInlines-' is ABI-changing and not compatible with '/fallback'">;
+
def err_drv_invalid_value : Error<"invalid value '%1' in '%0'">;
def err_drv_invalid_int_value : Error<"invalid integral value '%1' in '%0'">;
def err_drv_invalid_remap_file : Error<
@@ -193,6 +193,9 @@ def err_drv_mg_requires_m_or_mm : Error<
"option '-MG' requires '-M' or '-MM'">;
def err_drv_unknown_objc_runtime : Error<
"unknown or ill-formed Objective-C runtime '%0'">;
+def err_drv_invalid_cf_runtime_abi
+ : Error<"invalid CoreFoundation Runtime ABI '%0'; must be one of "
+ "'objc', 'standalone', 'swift', 'swift-5.0', 'swift-4.2', 'swift-4.1'">;
def err_drv_gnustep_objc_runtime_incompatible_binary : Error<
"GNUstep Objective-C runtime version %0 incompatible with target binary format">;
def err_drv_emit_llvm_link : Error<
@@ -213,6 +216,8 @@ def warn_drv_omp_offload_target_duplicate : Warning<
def warn_drv_omp_offload_target_missingbcruntime : Warning<
"No library '%0' found in the default clang lib directory or in LIBRARY_PATH. Expect degraded performance due to no inlining of runtime functions on target devices.">,
InGroup<OpenMPTarget>;
+def err_drv_unsupported_embed_bitcode
+ : Error<"%0 is not supported with -fembed-bitcode">;
def err_drv_bitcode_unsupported_on_toolchain : Error<
"-fembed-bitcode is not supported on versions of iOS prior to 6.0">;
@@ -277,6 +282,8 @@ def warn_drv_disabling_vptr_no_rtti_default : Warning<
def warn_drv_object_size_disabled_O0 : Warning<
"the object size sanitizer has no effect at -O0, but is explicitly enabled: %0">,
InGroup<InvalidCommandLineArgument>, DefaultWarnNoWerror;
+def err_invalid_branch_protection: Error <
+ "invalid branch protection option '%0' in '%1'">;
def note_drv_command_failed_diag_msg : Note<
"diagnostic msg: %0">;
@@ -292,6 +299,9 @@ def err_analyzer_config_no_value : Error<
"analyzer-config option '%0' has a key but no value">;
def err_analyzer_config_multiple_values : Error<
"analyzer-config option '%0' should contain only one '='">;
+def err_analyzer_config_invalid_input : Error<
+ "invalid input for analyzer-config option '%0', that expects %1 value">;
+def err_analyzer_config_unknown : Error<"unknown analyzer-config '%0'">;
def err_drv_invalid_hvx_length : Error<
"-mhvx-length is not supported without a -mhvx/-mhvx= flag">;
@@ -299,6 +309,9 @@ def warn_drv_vectorize_needs_hvx : Warning<
"auto-vectorization requires HVX, use -mhvx to enable it">,
InGroup<OptionIgnored>;
+def err_drv_module_header_wrong_kind : Error<
+ "header file '%0' input type '%1' does not match type of prior input "
+ "in module compilation; use '-x %2' to override">;
def err_drv_modules_validate_once_requires_timestamp : Error<
"option '-fmodules-validate-once-per-build-session' requires "
"'-fbuild-session-timestamp=<seconds since Epoch>' or '-fbuild-session-file=<file>'">;
@@ -347,7 +360,7 @@ def warn_drv_unsupported_pic_with_mabicalls : Warning<
"%select{implicit usage of|}1 -mabicalls and the N64 ABI">,
InGroup<OptionIgnored>;
def err_drv_unsupported_noabicalls_pic : Error<
- "position-independent code requires ‘-mabicalls’">;
+ "position-independent code requires '-mabicalls'">;
def err_drv_unsupported_indirect_jump_opt : Error<
"'-mindirect-jump=%0' is unsupported with the '%1' architecture">;
def err_drv_unknown_indirect_jump_opt : Error<
@@ -392,4 +405,24 @@ def warn_drv_experimental_isel_incomplete_opt : Warning<
def warn_drv_moutline_unsupported_opt : Warning<
"The '%0' architecture does not support -moutline; flag ignored">,
InGroup<OptionIgnored>;
+
+def warn_drv_darwin_sdk_invalid_settings : Warning<
+ "SDK settings were ignored as 'SDKSettings.json' could not be parsed">,
+ InGroup<DiagGroup<"darwin-sdk-settings">>;
+
+def err_drv_trivial_auto_var_init_zero_disabled : Error<
+ "-ftrivial-auto-var-init=zero hasn't been enabled. Enable it at your own peril for benchmarking purpose only with "
+ "-enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang">;
+
+def warn_drv_msp430_hwmult_unsupported : Warning<"the given MCU does not "
+ "support hardware multiply, but -mhwmult is set to %0.">,
+ InGroup<InvalidCommandLineArgument>;
+def warn_drv_msp430_hwmult_mismatch : Warning<"the given MCU supports %0 "
+ "hardware multiply, but -mhwmult is set to %1.">,
+ InGroup<InvalidCommandLineArgument>;
+def warn_drv_msp430_hwmult_no_device : Warning<"no MCU device specified, but "
+ "'-mhwmult' is set to 'auto', assuming no hardware multiply. Use -mmcu to "
+ "specify a MSP430 device, or -mhwmult to set hardware multiply type "
+ "explicitly.">, InGroup<InvalidCommandLineArgument>;
+
}
diff --git a/include/clang/Basic/DiagnosticFrontend.h b/include/clang/Basic/DiagnosticFrontend.h
new file mode 100644
index 000000000000..1f066cf491ae
--- /dev/null
+++ b/include/clang/Basic/DiagnosticFrontend.h
@@ -0,0 +1,29 @@
+//===--- DiagnosticFrontend.h - Diagnostics for frontend --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_DIAGNOSTICFRONTEND_H
+#define LLVM_CLANG_BASIC_DIAGNOSTICFRONTEND_H
+
+#include "clang/Basic/Diagnostic.h"
+
+namespace clang {
+namespace diag {
+enum {
+#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
+ SHOWINSYSHEADER, CATEGORY) \
+ ENUM,
+#define FRONTENDSTART
+#include "clang/Basic/DiagnosticFrontendKinds.inc"
+#undef DIAG
+ NUM_BUILTIN_FRONTEND_DIAGNOSTICS
+};
+} // end namespace diag
+} // end namespace clang
+
+#endif // LLVM_CLANG_BASIC_DIAGNOSTICFRONTEND_H
diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td
index 66287933b7ca..927b8cbc2477 100644
--- a/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -63,16 +63,6 @@ def note_fe_backend_invalid_loc : Note<"could "
def err_fe_backend_unsupported : Error<"%0">, BackendInfo;
-def remark_sanitize_address_insert_extra_padding_accepted : Remark<
- "-fsanitize-address-field-padding applied to %0">, ShowInSystemHeader,
- InGroup<SanitizeAddressRemarks>;
-def remark_sanitize_address_insert_extra_padding_rejected : Remark<
- "-fsanitize-address-field-padding ignored for %0 because it "
- "%select{is not C++|is packed|is a union|is trivially copyable|"
- "has trivial destructor|is standard layout|is in a blacklisted file|"
- "is blacklisted}1">, ShowInSystemHeader,
- InGroup<SanitizeAddressRemarks>;
-
def err_fe_invalid_code_complete_file : Error<
"cannot locate code-completion file %0">, DefaultFatal;
def err_fe_stdout_binary : Error<"unable to change standard output to binary">,
@@ -99,8 +89,6 @@ def err_fe_unable_to_interface_with_target : Error<
"unable to interface with target machine">;
def err_fe_unable_to_open_output : Error<
"unable to open output file '%0': '%1'">;
-def err_fe_pth_file_has_no_source_header : Error<
- "PTH file '%0' does not designate an original source header file for -include-pth">;
def warn_fe_macro_contains_embedded_newline : Warning<
"macro '%0' contains embedded newline; text after the newline is ignored">;
def warn_fe_cc_print_header_failure : Warning<
@@ -172,11 +160,6 @@ def warn_unknown_warning_specifier : Warning<
"unknown %0 warning specifier: '%1'">,
InGroup<UnknownWarningOption>;
-def err_unknown_analyzer_checker : Error<
- "no analyzer checkers are associated with '%0'">;
-def note_suggest_disabling_all_checkers : Note<
- "use -analyzer-disable-all-checks to disable all static analyzer checkers">;
-
def warn_incompatible_analyzer_plugin_api : Warning<
"checker plugin '%0' is not compatible with this version of the analyzer">,
InGroup<DiagGroup<"analyzer-incompatible-plugin"> >;
@@ -187,6 +170,8 @@ def err_module_build_requires_fmodules : Error<
"module compilation requires '-fmodules'">;
def err_module_interface_requires_modules_ts : Error<
"module interface compilation requires '-fmodules-ts'">;
+def err_header_module_requires_modules : Error<
+ "header module compilation requires '-fmodules' or '-fmodules-ts'">;
def warn_module_config_mismatch : Warning<
"module file %0 cannot be loaded due to a configuration mismatch with the current "
"compilation">, InGroup<DiagGroup<"module-file-config-mismatch">>, DefaultError;
@@ -224,6 +209,10 @@ def remark_module_build_done : Remark<"finished building module '%0'">,
def err_modules_embed_file_not_found :
Error<"file '%0' specified by '-fmodules-embed-file=' not found">,
DefaultFatal;
+def err_module_header_file_not_found :
+ Error<"module header file '%0' not found">, DefaultFatal;
+def err_module_header_file_invalid :
+ Error<"unexpected module header file input '%0'">, DefaultFatal;
def err_test_module_file_extension_version : Error<
"test module file extension '%0' has different version (%1.%2) than expected "
@@ -238,7 +227,52 @@ def warn_option_invalid_ocl_version : Warning<
"OpenCL version %0 does not support the option '%1'">, InGroup<Deprecated>;
def warn_stdlibcxx_not_found : Warning<
- "include path for stdlibc++ headers not found; pass '-std=libc++' on the "
+ "include path for stdlibc++ headers not found; pass '-stdlib=libc++' on the "
"command line to use the libc++ standard library instead">,
InGroup<DiagGroup<"stdlibcxx-not-found">>;
+
+def err_builtin_needs_feature : Error<"%0 needs target feature %1">;
+def err_function_needs_feature : Error<
+ "always_inline function %1 requires target feature '%2', but would "
+ "be inlined into function %0 that is compiled without support for '%2'">;
+
+def err_alias_to_undefined : Error<
+ "%select{alias|ifunc}0 must point to a defined "
+ "%select{variable or |}1function">;
+def warn_alias_to_weak_alias : Warning<
+ "%select{alias|ifunc}2 will always resolve to %0 even if weak definition of "
+ "%1 is overridden">,
+ InGroup<IgnoredAttributes>;
+def err_duplicate_mangled_name : Error<
+ "definition with same mangled name '%0' as another definition">;
+def err_cyclic_alias : Error<
+ "%select{alias|ifunc}0 definition is part of a cycle">;
+def err_ifunc_resolver_return : Error<
+ "ifunc resolver function must return a pointer">;
+
+def warn_atomic_op_misaligned : Warning<
+ "%select{large|misaligned}0 atomic operation may incur "
+ "significant performance penalty">, InGroup<DiagGroup<"atomic-alignment">>;
+
+def warn_alias_with_section : Warning<
+ "%select{alias|ifunc}1 will not be in section '%0' but in the same section "
+ "as the %select{aliasee|resolver}2">,
+ InGroup<IgnoredAttributes>;
+
+let CategoryName = "Instrumentation Issue" in {
+def warn_profile_data_out_of_date : Warning<
+ "profile data may be out of date: of %0 function%s0, %1 %plural{1:has|:have}1"
+ " mismatched data that will be ignored">,
+ InGroup<ProfileInstrOutOfDate>;
+def warn_profile_data_missing : Warning<
+ "profile data may be incomplete: of %0 function%s0, %1 %plural{1:has|:have}1"
+ " no data">,
+ InGroup<ProfileInstrMissing>,
+ DefaultIgnore;
+def warn_profile_data_unprofiled : Warning<
+ "no profile data available for file \"%0\"">,
+ InGroup<ProfileInstrUnprofiled>;
+
+} // end of instrumentation issue category
+
}
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index 2156ef93c19f..19e187cc5d93 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -59,6 +59,8 @@ def BoolConversion : DiagGroup<"bool-conversion", [PointerBoolConversion,
UndefinedBoolConversion]>;
def IntConversion : DiagGroup<"int-conversion">;
def EnumConversion : DiagGroup<"enum-conversion">;
+def ImplicitIntConversion : DiagGroup<"implicit-int-conversion">;
+def ImplicitFloatConversion : DiagGroup<"implicit-float-conversion">;
def FloatOverflowConversion : DiagGroup<"float-overflow-conversion">;
def FloatZeroConversion : DiagGroup<"float-zero-conversion">;
@@ -102,7 +104,11 @@ def UndefinedFuncTemplate : DiagGroup<"undefined-func-template">;
def MissingNoEscape : DiagGroup<"missing-noescape">;
def DeleteIncomplete : DiagGroup<"delete-incomplete">;
-def DeleteNonVirtualDtor : DiagGroup<"delete-non-virtual-dtor">;
+def DeleteNonAbstractNonVirtualDtor : DiagGroup<"delete-non-abstract-non-virtual-dtor">;
+def DeleteAbstractNonVirtualDtor : DiagGroup<"delete-abstract-non-virtual-dtor">;
+def DeleteNonVirtualDtor : DiagGroup<"delete-non-virtual-dtor",
+ [DeleteNonAbstractNonVirtualDtor,
+ DeleteAbstractNonVirtualDtor]>;
def AbstractFinalClass : DiagGroup<"abstract-final-class">;
def CXX11CompatDeprecatedWritableStr :
@@ -160,6 +166,8 @@ def GNUEmptyStruct : DiagGroup<"gnu-empty-struct">;
def ExtraTokens : DiagGroup<"extra-tokens">;
def CXX98CompatExtraSemi : DiagGroup<"c++98-compat-extra-semi">;
def CXX11ExtraSemi : DiagGroup<"c++11-extra-semi">;
+def EmptyInitStatement : DiagGroup<"empty-init-stmt">;
+def ExtraSemiStmt : DiagGroup<"extra-semi-stmt", [EmptyInitStatement]>;
def ExtraSemi : DiagGroup<"extra-semi", [CXX98CompatExtraSemi,
CXX11ExtraSemi]>;
@@ -283,6 +291,7 @@ def ExpansionToDefined : DiagGroup<"expansion-to-defined">;
def FlagEnum : DiagGroup<"flag-enum">;
def IncrementBool : DiagGroup<"increment-bool", [DeprecatedIncrementBool]>;
def InfiniteRecursion : DiagGroup<"infinite-recursion">;
+def PureVirtualCallFromCtorDtor: DiagGroup<"call-to-pure-virtual-from-ctor-dtor">;
def GNUImaginaryConstant : DiagGroup<"gnu-imaginary-constant">;
def IgnoredQualifiers : DiagGroup<"ignored-qualifiers">;
def : DiagGroup<"import">;
@@ -356,6 +365,8 @@ def NullArithmetic : DiagGroup<"null-arithmetic">;
def NullCharacter : DiagGroup<"null-character">;
def NullDereference : DiagGroup<"null-dereference">;
def InitializerOverrides : DiagGroup<"initializer-overrides">;
+// For compatibility with GCC; -Woverride-init = -Winitializer-overrides
+def : DiagGroup<"override-init", [InitializerOverrides]>;
def NonNull : DiagGroup<"nonnull">;
def NonPODVarargs : DiagGroup<"non-pod-varargs">;
def ClassVarargs : DiagGroup<"class-varargs", [NonPODVarargs]>;
@@ -364,7 +375,6 @@ def NonVirtualDtor : DiagGroup<"non-virtual-dtor">;
def NullPointerArithmetic : DiagGroup<"null-pointer-arithmetic">;
def : DiagGroup<"effc++", [NonVirtualDtor]>;
def OveralignedType : DiagGroup<"over-aligned">;
-def AlignedAllocationUnavailable : DiagGroup<"aligned-allocation-unavailable">;
def OldStyleCast : DiagGroup<"old-style-cast">;
def : DiagGroup<"old-style-definition">;
def OutOfLineDeclaration : DiagGroup<"out-of-line-declaration">;
@@ -381,6 +391,7 @@ def FunctionDefInObjCContainer : DiagGroup<"function-def-in-objc-container">;
def BadFunctionCast : DiagGroup<"bad-function-cast">;
def ObjCPropertyImpl : DiagGroup<"objc-property-implementation">;
def ObjCPropertyNoAttribute : DiagGroup<"objc-property-no-attribute">;
+def ObjCPropertyAssignOnObjectType : DiagGroup<"objc-property-assign-on-object-type">;
def ObjCProtocolQualifiers : DiagGroup<"objc-protocol-qualifiers">;
def ObjCMissingSuperCalls : DiagGroup<"objc-missing-super-calls">;
def ObjCDesignatedInit : DiagGroup<"objc-designated-initializers">;
@@ -621,7 +632,8 @@ def DeallocInCategory:DiagGroup<"dealloc-in-category">;
def SelectorTypeMismatch : DiagGroup<"selector-type-mismatch">;
def Selector : DiagGroup<"selector", [SelectorTypeMismatch]>;
def Protocol : DiagGroup<"protocol">;
-def AtProtocol : DiagGroup<"at-protocol">;
+// No longer in use, preserve for backwards compatibility.
+def : DiagGroup<"at-protocol">;
def PropertyAccessDotSyntax: DiagGroup<"property-access-dot-syntax">;
def PropertyAttr : DiagGroup<"property-attribute-mismatch">;
def SuperSubClassMismatch : DiagGroup<"super-class-method-mismatch">;
@@ -708,6 +720,8 @@ def Conversion : DiagGroup<"conversion",
FloatConversion,
Shorten64To32,
IntConversion,
+ ImplicitIntConversion,
+ ImplicitFloatConversion,
LiteralConversion,
NonLiteralNullConversion, // (1-1)->pointer (etc)
NullConversion, // NULL->non-pointer
@@ -763,7 +777,8 @@ def Extra : DiagGroup<"extra", [
MissingMethodReturnType,
SignCompare,
UnusedParameter,
- NullPointerArithmetic
+ NullPointerArithmetic,
+ EmptyInitStatement
]>;
def Most : DiagGroup<"most", [
@@ -1030,3 +1045,8 @@ def ExperimentalISel : DiagGroup<"experimental-isel">;
// A warning group specifically for warnings related to function
// multiversioning.
def FunctionMultiVersioning : DiagGroup<"function-multiversion">;
+
+def NoDeref : DiagGroup<"noderef">;
+
+// A group for cross translation unit static analysis related warnings.
+def CrossTU : DiagGroup<"ctu">;
diff --git a/include/clang/Basic/DiagnosticIDs.h b/include/clang/Basic/DiagnosticIDs.h
index 983dcb21cfdf..876629f373a1 100644
--- a/include/clang/Basic/DiagnosticIDs.h
+++ b/include/clang/Basic/DiagnosticIDs.h
@@ -30,7 +30,7 @@ namespace clang {
enum {
DIAG_SIZE_COMMON = 300,
DIAG_SIZE_DRIVER = 200,
- DIAG_SIZE_FRONTEND = 100,
+ DIAG_SIZE_FRONTEND = 150,
DIAG_SIZE_SERIALIZATION = 120,
DIAG_SIZE_LEX = 400,
DIAG_SIZE_PARSE = 500,
diff --git a/include/clang/Basic/DiagnosticLex.h b/include/clang/Basic/DiagnosticLex.h
new file mode 100644
index 000000000000..6ec4da80338f
--- /dev/null
+++ b/include/clang/Basic/DiagnosticLex.h
@@ -0,0 +1,29 @@
+//===--- DiagnosticLex.h - Diagnostics for liblex ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_DIAGNOSTICLEX_H
+#define LLVM_CLANG_BASIC_DIAGNOSTICLEX_H
+
+#include "clang/Basic/Diagnostic.h"
+
+namespace clang {
+namespace diag {
+enum {
+#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
+ SHOWINSYSHEADER, CATEGORY) \
+ ENUM,
+#define LEXSTART
+#include "clang/Basic/DiagnosticLexKinds.inc"
+#undef DIAG
+ NUM_BUILTIN_LEX_DIAGNOSTICS
+};
+} // end namespace diag
+} // end namespace clang
+
+#endif // LLVM_CLANG_BASIC_DIAGNOSTICLEX_H
diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td
index 1c960711bccb..14e306246ba3 100644
--- a/include/clang/Basic/DiagnosticLexKinds.td
+++ b/include/clang/Basic/DiagnosticLexKinds.td
@@ -122,6 +122,9 @@ def ext_unicode_whitespace : ExtWarn<
def warn_utf8_symbol_homoglyph : Warning<
"treating Unicode character <U+%0> as identifier character rather than "
"as '%1' symbol">, InGroup<DiagGroup<"unicode-homoglyph">>;
+def warn_utf8_symbol_zero_width : Warning<
+ "identifier contains Unicode character <U+%0> that is invisible in "
+ "some environments">, InGroup<DiagGroup<"unicode-zero-width">>;
def err_hex_escape_no_digits : Error<
"\\%0 used with no following hex digits">;
@@ -255,13 +258,6 @@ def warn_bad_character_encoding : ExtWarn<
def err_lexing_string : Error<"failure when lexing a string">;
def err_placeholder_in_source : Error<"editor placeholder in source file">;
-
-//===----------------------------------------------------------------------===//
-// PTH Diagnostics
-//===----------------------------------------------------------------------===//
-def err_invalid_pth_file : Error<
- "invalid or corrupt PTH file '%0'">;
-
//===----------------------------------------------------------------------===//
// Preprocessor Diagnostics
//===----------------------------------------------------------------------===//
@@ -409,11 +405,20 @@ def err_pp_through_header_not_found : Error<
def err_pp_through_header_not_seen : Error<
"#include of '%0' not seen while attempting to "
"%select{create|use}1 precompiled header">, DefaultFatal;
+def err_pp_pragma_hdrstop_not_seen : Error<
+ "#pragma hdrstop not seen while attempting to use precompiled header">,
+ DefaultFatal;
def warn_pp_macro_def_mismatch_with_pch : Warning<
"definition of macro %0 does not match definition in precompiled header">,
InGroup<ClangClPch>;
-def err_pp_file_not_found_not_fatal : Error<
+def warn_pp_hdrstop_filename_ignored : Warning<
+ "#pragma hdrstop filename not supported, "
+ "/Fp can be used to specify precompiled header filename">,
+ InGroup<ClangClPch>;
+def err_pp_file_not_found_angled_include_not_fatal : Error<
"'%0' file not found with <angled> include; use \"quotes\" instead">;
+def err_pp_file_not_found_typo_not_fatal
+ : Error<"'%0' file not found, did you mean '%1'?">;
def err_pp_error_opening_file : Error<
"error opening file '%0': %1">, DefaultFatal;
def err_pp_empty_filename : Error<"empty filename">;
@@ -558,8 +563,6 @@ def err_pp_module_end_without_module_begin : Error<
"'#pragma clang module end'">;
def note_pp_module_begin_here : Note<
"entering module '%0' due to this pragma">;
-def err_pp_module_build_pth : Error<
- "'#pragma clang module build' not supported in pretokenized header">;
def err_pp_module_build_missing_end : Error<
"no matching '#pragma clang module endbuild' for this '#pragma clang module build'">;
diff --git a/include/clang/Basic/DiagnosticParse.h b/include/clang/Basic/DiagnosticParse.h
new file mode 100644
index 000000000000..2113b03262d7
--- /dev/null
+++ b/include/clang/Basic/DiagnosticParse.h
@@ -0,0 +1,29 @@
+//===--- DiagnosticParse.h - Diagnostics for libparse -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_DIAGNOSTICPARSE_H
+#define LLVM_CLANG_BASIC_DIAGNOSTICPARSE_H
+
+#include "clang/Basic/Diagnostic.h"
+
+namespace clang {
+namespace diag {
+enum {
+#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
+ SHOWINSYSHEADER, CATEGORY) \
+ ENUM,
+#define PARSESTART
+#include "clang/Basic/DiagnosticParseKinds.inc"
+#undef DIAG
+ NUM_BUILTIN_PARSE_DIAGNOSTICS
+};
+} // end namespace diag
+} // end namespace clang
+
+#endif // LLVM_CLANG_BASIC_DIAGNOSTICPARSE_H
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index 609dca4f075c..06281e2904c7 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -53,6 +53,10 @@ def ext_extra_semi_cxx11 : Extension<
def warn_extra_semi_after_mem_fn_def : Warning<
"extra ';' after member function definition">,
InGroup<ExtraSemi>, DefaultIgnore;
+def warn_null_statement : Warning<
+ "empty expression statement has no effect; "
+ "remove unnecessary ';' to silence this warning">,
+ InGroup<ExtraSemiStmt>, DefaultIgnore;
def ext_thread_before : Extension<"'__thread' before '%0'">;
def ext_keyword_as_ident : ExtWarn<
@@ -88,9 +92,12 @@ def err_enumerator_unnamed_no_def : Error<
def ext_cxx11_enum_fixed_underlying_type : Extension<
"enumeration types with a fixed underlying type are a C++11 extension">,
InGroup<CXX11>;
-def ext_c_enum_fixed_underlying_type : Extension<
+def ext_ms_c_enum_fixed_underlying_type : Extension<
"enumeration types with a fixed underlying type are a Microsoft extension">,
InGroup<MicrosoftFixedEnum>;
+def ext_clang_c_enum_fixed_underlying_type : Extension<
+ "enumeration types with a fixed underlying type are a Clang extension">,
+ InGroup<DiagGroup<"fixed-enum-extension">>;
def warn_cxx98_compat_enum_fixed_underlying_type : Warning<
"enumeration types with a fixed underlying type are incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
@@ -219,6 +226,11 @@ def ext_nested_namespace_definition : ExtWarn<
def warn_cxx14_compat_nested_namespace_definition : Warning<
"nested namespace definition is incompatible with C++ standards before C++17">,
InGroup<CXXPre17Compat>, DefaultIgnore;
+def ext_inline_nested_namespace_definition : ExtWarn<
+ "inline nested namespace definition is a C++2a extension">, InGroup<CXX2a>;
+def warn_cxx17_compat_inline_nested_namespace_definition : Warning<
+ "inline nested namespace definition is incompatible with C++ standards before"
+ " C++2a">, InGroup<CXXPre2aCompat>, DefaultIgnore;
def err_inline_nested_namespace_definition : Error<
"nested namespace definition cannot be 'inline'">;
def err_expected_semi_after_attribute_list : Error<
@@ -331,6 +343,10 @@ def err_expected_parentheses_around_typename : Error<
def err_expected_case_before_expression: Error<
"expected 'case' keyword before expression">;
+def ext_warn_gnu_final : ExtWarn<
+ "__final is a GNU extension, consider using C++11 final">,
+ InGroup<GccCompat>;
+
// Declarations.
def err_typename_requires_specqual : Error<
"type name requires a specifier or qualifier">;
@@ -358,6 +374,12 @@ def ext_c11_static_assert : Extension<
def warn_cxx98_compat_static_assert : Warning<
"static_assert declarations are incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
+def ext_static_assert_no_message : ExtWarn<
+ "static_assert with no message is a C++17 extension">, InGroup<CXX17>;
+def warn_cxx14_compat_static_assert_no_message : Warning<
+ "static_assert with no message is incompatible with C++ standards before "
+ "C++17">,
+ DefaultIgnore, InGroup<CXXPre17Compat>;
def err_function_definition_not_allowed : Error<
"function definition is not allowed here">;
def err_expected_end_of_enumerator : Error<
@@ -488,6 +510,13 @@ def err_dynamic_and_noexcept_specification : Error<
"cannot have both throw() and noexcept() clause on the same function">;
def err_except_spec_unparsed : Error<
"unexpected end of exception specification">;
+def ext_dynamic_exception_spec : ExtWarn<
+ "ISO C++17 does not allow dynamic exception specifications">,
+ InGroup<DynamicExceptionSpec>, DefaultError;
+def warn_exception_spec_deprecated : Warning<
+ "dynamic exception specifications are deprecated">,
+ InGroup<DeprecatedDynamicExceptionSpec>, DefaultIgnore;
+def note_exception_spec_deprecated : Note<"use '%0' instead">;
def warn_cxx98_compat_noexcept_decl : Warning<
"noexcept specifications are incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
@@ -540,6 +569,15 @@ def ext_init_statement : ExtWarn<
def warn_cxx14_compat_init_statement : Warning<
"%select{if|switch}0 initialization statements are incompatible with "
"C++ standards before C++17">, DefaultIgnore, InGroup<CXXPre17Compat>;
+def ext_for_range_init_stmt : ExtWarn<
+ "range-based for loop initialization statements are a C++2a extension">,
+ InGroup<CXX2a>;
+def warn_cxx17_compat_for_range_init_stmt : Warning<
+ "range-based for loop initialization statements are incompatible with "
+ "C++ standards before C++2a">, DefaultIgnore, InGroup<CXXPre2aCompat>;
+def warn_empty_init_statement : Warning<
+ "empty initialization statement of '%select{if|switch|range-based for}0' "
+ "has no effect">, InGroup<EmptyInitStatement>, DefaultIgnore;
// C++ derived classes
def err_dup_virtual : Error<"duplicate 'virtual' in base specifier">;
@@ -566,6 +604,9 @@ def warn_cxx98_compat_noexcept_expr : Warning<
def warn_cxx98_compat_nullptr : Warning<
"'nullptr' is incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore;
+def warn_wrong_clang_attr_namespace : Warning<
+ "'__clang__' is a predefined macro name, not an attribute scope specifier; "
+ "did you mean '_Clang' instead?">, InGroup<IgnoredAttributes>;
def ext_ns_enum_attribute : Extension<
"attributes on %select{a namespace|an enumerator}0 declaration are "
"a C++17 extension">, InGroup<CXX17>;
@@ -1023,8 +1064,8 @@ def err_pragma_optimize_invalid_argument : Error<
def err_pragma_optimize_extra_argument : Error<
"unexpected extra argument '%0' to '#pragma clang optimize'">;
// - #pragma clang attribute
-def err_pragma_attribute_expected_push_pop : Error<
- "expected 'push' or 'pop' after '#pragma clang attribute'">;
+def err_pragma_attribute_expected_push_pop_paren : Error<
+ "expected 'push', 'pop', or '(' after '#pragma clang attribute'">;
def err_pragma_attribute_invalid_argument : Error<
"unexpected argument '%0' to '#pragma clang attribute'; "
"expected 'push' or 'pop'">;
@@ -1059,6 +1100,13 @@ def err_pragma_attribute_unknown_subject_sub_rule : Error<
"sub-rules: %3}2">;
def err_pragma_attribute_duplicate_subject : Error<
"duplicate attribute subject matcher '%0'">;
+def err_pragma_attribute_expected_period : Error<
+ "expected '.' after pragma attribute namespace %0">;
+def err_pragma_attribute_namespace_on_attribute : Error<
+ "namespace can only apply to 'push' or 'pop' directives">;
+def note_pragma_attribute_namespace_on_attribute : Note<
+ "omit the namespace to add attributes to the most-recently"
+ " pushed attribute group">;
def err_opencl_unroll_hint_on_non_loop : Error<
"OpenCL only supports 'opencl_unroll_hint' attribute on for, while, and do statements">;
@@ -1116,15 +1164,19 @@ def err_omp_decl_in_declare_simd : Error<
def err_omp_unknown_map_type : Error<
"incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'">;
def err_omp_unknown_map_type_modifier : Error<
- "incorrect map type modifier, expected 'always'">;
+ "incorrect map type modifier, expected 'always' or 'close'">;
def err_omp_map_type_missing : Error<
"missing map type">;
+def err_omp_map_type_modifier_missing : Error<
+ "missing map type modifier">;
def err_omp_declare_simd_inbranch_notinbranch : Error<
"unexpected '%0' clause, '%1' is specified already">;
def err_expected_end_declare_target : Error<
"expected '#pragma omp end declare target'">;
def err_omp_declare_target_unexpected_clause: Error<
"unexpected '%0' clause, only 'to' or 'link' clauses expected">;
+def err_omp_expected_clause: Error<
+ "expected at least one clause on '#pragma omp %0' directive">;
// Pragma loop support.
def err_pragma_loop_missing_argument : Error<
@@ -1132,7 +1184,8 @@ def err_pragma_loop_missing_argument : Error<
"'enable'%select{|, 'full'}1%select{|, 'assume_safety'}2 or 'disable'}0">;
def err_pragma_loop_invalid_option : Error<
"%select{invalid|missing}0 option%select{ %1|}0; expected vectorize, "
- "vectorize_width, interleave, interleave_count, unroll, unroll_count, or distribute">;
+ "vectorize_width, interleave, interleave_count, unroll, unroll_count, "
+ "pipeline, pipeline_initiation_interval, or distribute">;
def err_pragma_fp_invalid_option : Error<
"%select{invalid|missing}0 option%select{ %1|}0; expected contract">;
@@ -1145,6 +1198,8 @@ def err_pragma_fp_scope : Error<
def err_pragma_invalid_keyword : Error<
"invalid argument; expected 'enable'%select{|, 'full'}0%select{|, 'assume_safety'}1 or 'disable'">;
+def err_pragma_pipeline_invalid_keyword : Error<
+ "invalid argument; expected 'disable'">;
// Pragma unroll support.
def warn_pragma_unroll_cuda_value_in_parens : Warning<
diff --git a/include/clang/Basic/DiagnosticRefactoring.h b/include/clang/Basic/DiagnosticRefactoring.h
new file mode 100644
index 000000000000..8d3914f25289
--- /dev/null
+++ b/include/clang/Basic/DiagnosticRefactoring.h
@@ -0,0 +1,29 @@
+//===--- DiagnosticRefactoring.h - ------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_DIAGNOSTICREFACTORING_H
+#define LLVM_CLANG_BASIC_DIAGNOSTICREFACTORING_H
+
+#include "clang/Basic/Diagnostic.h"
+
+namespace clang {
+namespace diag {
+enum {
+#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
+ SHOWINSYSHEADER, CATEGORY) \
+ ENUM,
+#define REFACTORINGSTART
+#include "clang/Basic/DiagnosticRefactoringKinds.inc"
+#undef DIAG
+ NUM_BUILTIN_REFACTORING_DIAGNOSTICS
+};
+} // end namespace diag
+} // end namespace clang
+
+#endif // LLVM_CLANG_BASIC_DIAGNOSTICREFACTORING_H
diff --git a/include/clang/Basic/DiagnosticSema.h b/include/clang/Basic/DiagnosticSema.h
new file mode 100644
index 000000000000..b05b24db5609
--- /dev/null
+++ b/include/clang/Basic/DiagnosticSema.h
@@ -0,0 +1,29 @@
+//===--- DiagnosticSema.h - Diagnostics for libsema -------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_DIAGNOSTICSEMA_H
+#define LLVM_CLANG_BASIC_DIAGNOSTICSEMA_H
+
+#include "clang/Basic/Diagnostic.h"
+
+namespace clang {
+namespace diag {
+enum {
+#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
+ SHOWINSYSHEADER, CATEGORY) \
+ ENUM,
+#define SEMASTART
+#include "clang/Basic/DiagnosticSemaKinds.inc"
+#undef DIAG
+ NUM_BUILTIN_SEMA_DIAGNOSTICS
+};
+} // end namespace diag
+} // end namespace clang
+
+#endif // LLVM_CLANG_BASIC_DIAGNOSTICSEMA_H
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 586f65e9201c..5feb877e46c5 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -192,10 +192,6 @@ def ext_flexible_array_init : Extension<
"flexible array initialization is a GNU extension">, InGroup<GNUFlexibleArrayInitializer>;
// Declarations.
-def ext_duplicate_declspec : ExtWarn<"duplicate '%0' declaration specifier">,
- InGroup<DuplicateDeclSpecifier>;
-def warn_duplicate_declspec : Warning<"duplicate '%0' declaration specifier">,
- InGroup<DuplicateDeclSpecifier>;
def ext_plain_complex : ExtWarn<
"plain '_Complex' requires a type specifier; assuming '_Complex double'">;
def ext_imaginary_constant : Extension<
@@ -209,7 +205,6 @@ def err_invalid_sign_spec : Error<"'%0' cannot be signed or unsigned">;
def err_invalid_width_spec : Error<
"'%select{|short|long|long long}0 %1' is invalid">;
def err_invalid_complex_spec : Error<"'_Complex %0' is invalid">;
-def err_friend_decl_spec : Error<"'%0' is invalid in friend declarations">;
def ext_auto_type_specifier : ExtWarn<
"'auto' type specifier is a C++11 extension">, InGroup<CXX11>;
@@ -250,9 +245,6 @@ def err_invalid_vector_long_double_decl_spec : Error<
def warn_vector_long_decl_spec_combination : Warning<
"Use of 'long' with '__vector' is deprecated">, InGroup<Deprecated>;
-def err_use_of_tag_name_without_tag : Error<
- "must use '%1' tag to refer to type %0%select{| in this scope}2">;
-
def err_redeclaration_different_type : Error<
"redeclaration of %0 with a different type%diff{: $ vs $|}1,2">;
def err_bad_variable_name : Error<
@@ -369,7 +361,7 @@ def warn_implicit_function_decl : Warning<
"implicit declaration of function %0">,
InGroup<ImplicitFunctionDeclare>, DefaultIgnore;
def ext_implicit_function_decl : ExtWarn<
- "implicit declaration of function %0 is invalid in %select{C99|OpenCL}1">,
+ "implicit declaration of function %0 is invalid in C99">,
InGroup<ImplicitFunctionDeclare>;
def note_function_suggestion : Note<"did you mean %0?">;
@@ -452,10 +444,12 @@ def err_decomp_decl_multiple_bases_with_members : Error<
"have non-static data members">;
def err_decomp_decl_ambiguous_base : Error<
"cannot decompose members of ambiguous base class %1 of %0:%2">;
-def err_decomp_decl_non_public_base : Error<
- "cannot decompose members of non-public base class %1 of %0">;
-def err_decomp_decl_non_public_member : Error<
- "cannot decompose non-public member %0 of %1">;
+def err_decomp_decl_inaccessible_base : Error<
+ "cannot decompose members of inaccessible base class %1 of %0">,
+ AccessControl;
+def err_decomp_decl_inaccessible_field : Error<
+ "cannot decompose %select{private|protected}0 member %1 of %3">,
+ AccessControl;
def err_decomp_decl_anon_union_member : Error<
"cannot decompose class type %0 because it has an anonymous "
"%select{struct|union}1 member">;
@@ -526,13 +520,6 @@ def warn_access_decl_deprecated : Warning<
def err_access_decl : Error<
"ISO C++11 does not allow access declarations; "
"use using declarations instead">;
-def ext_dynamic_exception_spec : ExtWarn<
- "ISO C++17 does not allow dynamic exception specifications">,
- InGroup<DynamicExceptionSpec>, DefaultError;
-def warn_exception_spec_deprecated : Warning<
- "dynamic exception specifications are deprecated">,
- InGroup<DeprecatedDynamicExceptionSpec>, DefaultIgnore;
-def note_exception_spec_deprecated : Note<"use '%0' instead">;
def warn_deprecated_copy_operation : Warning<
"definition of implicit copy %select{constructor|assignment operator}1 "
"for %0 is deprecated because it has a user-declared "
@@ -618,11 +605,6 @@ def err_invalid_cpu_supports : Error<"invalid cpu feature string for builtin">;
def err_invalid_cpu_is : Error<"invalid cpu name for builtin">;
def err_invalid_cpu_specific_dispatch_value : Error<
"invalid option '%0' for %select{cpu_specific|cpu_dispatch}1">;
-def err_builtin_needs_feature : Error<"%0 needs target feature %1">;
-def err_function_needs_feature
- : Error<"always_inline function %1 requires target feature '%2', but would "
- "be inlined into function %0 that is compiled without support for "
- "'%2'">;
def warn_builtin_unknown : Warning<"use of unknown builtin %0">,
InGroup<ImplicitFunctionDeclare>, DefaultError;
def warn_cstruct_memaccess : Warning<
@@ -694,7 +676,8 @@ def warn_assume_side_effects : Warning<
InGroup<DiagGroup<"assume">>;
def warn_memcpy_chk_overflow : Warning<
- "%0 will always overflow destination buffer">,
+ "'%0' will always overflow; destination buffer has size %1,"
+ " but size argument is %2">,
InGroup<DiagGroup<"builtin-memcpy-chk-size">>;
/// main()
@@ -773,7 +756,7 @@ def warn_pragma_pack_non_default_at_include : Warning<
"members in the included file">, InGroup<PragmaPackSuspiciousInclude>,
DefaultIgnore;
def warn_pragma_pack_modified_after_include : Warning<
- "the current #pragma pack aligment value is modified in the included "
+ "the current #pragma pack alignment value is modified in the included "
"file">, InGroup<PragmaPack>;
def warn_pragma_pack_no_pop_eof : Warning<"unterminated "
"'#pragma pack (push, ...)' at end of file">, InGroup<PragmaPack>;
@@ -791,10 +774,6 @@ def warn_cxx_ms_struct :
Warning<"ms_struct may not produce Microsoft-compatible layouts for classes "
"with base classes or virtual functions">,
DefaultError, InGroup<IncompatibleMSStruct>;
-def warn_npot_ms_struct :
- Warning<"ms_struct may not produce Microsoft-compatible layouts with fundamental "
- "data types with sizes that aren't a power of two">,
- DefaultError, InGroup<IncompatibleMSStruct>;
def err_section_conflict : Error<"%0 causes a section type conflict with %1">;
def err_no_base_classes : Error<"invalid use of '__super', %0 has no base classes">;
def err_invalid_super_scope : Error<"invalid use of '__super', "
@@ -836,7 +815,8 @@ def err_pragma_attribute_matcher_negated_subrule_contradicts_subrule : Error<
def err_pragma_attribute_invalid_matchers : Error<
"attribute %0 can't be applied to %1">;
def err_pragma_attribute_stack_mismatch : Error<
- "'#pragma clang attribute pop' with no matching '#pragma clang attribute push'">;
+ "'#pragma clang attribute %select{%1.|}0pop' with no matching"
+ " '#pragma clang attribute %select{%1.|}0push'">;
def warn_pragma_attribute_unused : Warning<
"unused attribute %0 in '#pragma clang attribute push' region">,
InGroup<PragmaClangAttribute>;
@@ -846,6 +826,9 @@ def err_pragma_attribute_no_pop_eof : Error<"unterminated "
"'#pragma clang attribute push' at end of file">;
def note_pragma_attribute_applied_decl_here : Note<
"when applied to this declaration">;
+def err_pragma_attr_attr_no_push : Error<
+ "'#pragma clang attribute' attribute with no matching "
+ "'#pragma clang attribute push'">;
/// Objective-C parser diagnostics
def err_duplicate_class_def : Error<
@@ -867,8 +850,8 @@ def err_protocol_has_circular_dependency : Error<
"protocol has circular dependency">;
def err_undeclared_protocol : Error<"cannot find protocol declaration for %0">;
def warn_undef_protocolref : Warning<"cannot find protocol definition for %0">;
-def warn_atprotocol_protocol : Warning<
- "@protocol is using a forward protocol declaration of %0">, InGroup<AtProtocol>;
+def err_atprotocol_protocol : Error<
+ "@protocol is using a forward protocol declaration of %0">;
def warn_readonly_property : Warning<
"attribute 'readonly' of property %0 restricts attribute "
"'readwrite' of property inherited from %1">,
@@ -920,8 +903,6 @@ def err_objc_runtime_visible_subclass : Error<
"Objective-C runtime">;
def note_objc_needs_superclass : Note<
"add a super class to fix this problem">;
-def warn_dup_category_def : Warning<
- "duplicate definition of category %1 on interface %0">;
def err_conflicting_super_class : Error<"conflicting super class name %0">;
def err_dup_implementation_class : Error<"reimplementation of class %0">;
def err_dup_implementation_category : Error<
@@ -1046,6 +1027,9 @@ def err_objc_property_attr_mutually_exclusive : Error<
"property attributes '%0' and '%1' are mutually exclusive">;
def err_objc_property_requires_object : Error<
"property with '%0' attribute must be of object type">;
+def warn_objc_property_assign_on_object : Warning<
+ "'assign' property of object type may become a dangling reference; consider using 'unsafe_unretained'">,
+ InGroup<ObjCPropertyAssignOnObjectType>, DefaultIgnore;
def warn_objc_property_no_assignment_attribute : Warning<
"no 'assign', 'retain', or 'copy' attribute is specified - "
"'assign' is assumed">,
@@ -1278,11 +1262,6 @@ def err_static_assert_expression_is_not_constant : Error<
def err_static_assert_failed : Error<"static_assert failed%select{ %1|}0">;
def err_static_assert_requirement_failed : Error<
"static_assert failed due to requirement '%0'%select{ %2|}1">;
-def ext_static_assert_no_message : ExtWarn<
- "static_assert with no message is a C++17 extension">, InGroup<CXX17>;
-def warn_cxx14_compat_static_assert_no_message : Warning<
- "static_assert with no message is incompatible with C++ standards before C++17">,
- DefaultIgnore, InGroup<CXXPre17Compat>;
def ext_inline_variable : ExtWarn<
"inline variables are a C++17 extension">, InGroup<CXX17>;
@@ -1319,8 +1298,8 @@ def ext_unelaborated_friend_type : ExtWarn<
def warn_cxx98_compat_unelaborated_friend_type : Warning<
"befriending %1 without '%select{struct|interface|union|class|enum}0' "
"keyword is incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore;
-def err_qualified_friend_not_found : Error<
- "no function named %0 with type %1 was found in the specified scope">;
+def err_qualified_friend_no_match : Error<
+ "friend declaration of %0 does not match any declaration in %1">;
def err_introducing_special_friend : Error<
"%plural{[0,2]:must use a qualified name when declaring|3:cannot declare}0"
" a %select{constructor|destructor|conversion operator|deduction guide}0 "
@@ -1355,10 +1334,6 @@ def ext_friend_tag_redecl_outside_namespace : ExtWarn<
InGroup<MicrosoftUnqualifiedFriend>;
def err_pure_friend : Error<"friend declaration cannot have a pure-specifier">;
-def err_invalid_member_in_interface : Error<
- "%select{data member |non-public member function |static member function |"
- "user-declared constructor|user-declared destructor|operator |"
- "nested class }0%1 is not permitted within an interface type">;
def err_invalid_base_in_interface : Error<
"interface type cannot inherit from "
"%select{struct|non-public interface|class}0 %1">;
@@ -1464,6 +1439,10 @@ def err_noexcept_needs_constant_expression : Error<
"argument to noexcept specifier must be a constant expression">;
def err_exception_spec_not_parsed : Error<
"exception specification is not available until end of class definition">;
+def err_exception_spec_cycle : Error<
+ "exception specification of %0 uses itself">;
+def err_exception_spec_incomplete_type : Error<
+ "exception specification needed for member of incomplete class %0">;
// C++ access checking
def err_class_redeclared_with_different_access : Error<
@@ -1644,7 +1623,7 @@ def err_member_function_call_bad_type : Error<
def warn_call_to_pure_virtual_member_function_from_ctor_dtor : Warning<
"call to pure virtual member function %0 has undefined behavior; "
"overrides of %0 in subclasses are not available in the "
- "%select{constructor|destructor}1 of %2">;
+ "%select{constructor|destructor}1 of %2">, InGroup<PureVirtualCallFromCtorDtor>;
def select_special_member_kind : TextSubstitution<
"%select{default constructor|copy constructor|move constructor|"
@@ -1809,6 +1788,10 @@ def err_destructor_expr_type_mismatch : Error<
def note_destructor_type_here : Note<
"type %0 is declared here">;
+def err_destroy_attr_on_non_static_var : Error<
+ "%select{no_destroy|always_destroy}0 attribute can only be applied to a"
+ " variable with static or thread storage duration">;
+
def err_destructor_template : Error<
"destructor cannot be declared as a template">;
@@ -1826,11 +1809,7 @@ def err_init_conversion_failed : Error<
"|: different number of parameters (%5 vs %6)"
"|: type mismatch at %ordinal5 parameter%diff{ ($ vs $)|}6,7"
"|: different return type%diff{ ($ vs $)|}5,6"
- "|: different qualifiers ("
- "%select{none|const|restrict|const and restrict|volatile|const and volatile|"
- "volatile and restrict|const, volatile, and restrict}5 vs "
- "%select{none|const|restrict|const and restrict|volatile|const and volatile|"
- "volatile and restrict|const, volatile, and restrict}6)"
+ "|: different qualifiers (%5 vs %6)"
"|: different exception specifications}4">;
def err_lvalue_to_rvalue_ref : Error<"rvalue reference %diff{to type $ cannot "
@@ -1858,6 +1837,9 @@ def err_reference_bind_init_list : Error<
def err_init_list_bad_dest_type : Error<
"%select{|non-aggregate }0type %1 cannot be initialized with an initializer "
"list">;
+def warn_cxx2a_compat_aggregate_init_with_ctors : Warning<
+ "aggregate initialization of type %0 with user-declared constructors "
+ "is incompatible with C++2a">, DefaultIgnore, InGroup<CXX2aCompat>;
def err_reference_bind_to_bitfield : Error<
"%select{non-const|volatile}0 reference cannot bind to "
@@ -2139,8 +2121,12 @@ def note_deduction_guide_template_access : Note<
"member template declared %0 here">;
def note_deduction_guide_access : Note<
"deduction guide declared %0 by intervening access specifier">;
+def warn_cxx14_compat_class_template_argument_deduction : Warning<
+ "class template argument deduction is incompatible with C++ standards "
+ "before C++17%select{|; for compatibility, use explicit type name %1}0">,
+ InGroup<CXXPre17Compat>, DefaultIgnore;
-// C++1y deduced return types
+// C++14 deduced return types
def err_auto_fn_deduction_failure : Error<
"cannot deduce return type %0 from returned value of type %1">;
def err_auto_fn_different_deductions : Error<
@@ -2156,6 +2142,9 @@ def err_auto_fn_return_init_list : Error<
"cannot deduce return type from initializer list">;
def err_auto_fn_virtual : Error<
"function with deduced return type cannot be virtual">;
+def warn_cxx11_compat_deduced_return_type : Warning<
+ "return type deduction is incompatible with C++ standards before C++14">,
+ InGroup<CXXPre14Compat>, DefaultIgnore;
// C++11 override control
def override_keyword_only_allowed_on_virtual_member_functions : Error<
@@ -2235,8 +2224,6 @@ def err_for_range_incomplete_type : Error<
"cannot use incomplete type %0 as a range">;
def err_for_range_iter_deduction_failure : Error<
"cannot use type %0 as an iterator">;
-def err_for_range_member_begin_end_mismatch : Error<
- "range type %0 has '%select{begin|end}1' member but no '%select{end|begin}1' member">;
def ext_for_range_begin_end_types_differ : ExtWarn<
"'begin' and 'end' returning different types (%0 and %1) is a C++17 extension">,
InGroup<CXX17>;
@@ -2249,6 +2236,8 @@ def note_in_for_range: Note<
def err_for_range_invalid: Error<
"invalid range expression of type %0; no viable '%select{begin|end}1' "
"function available">;
+def note_for_range_member_begin_end_ignored : Note<
+ "member is not a candidate because range type %0 has no '%select{end|begin}1' member">;
def err_range_on_array_parameter : Error<
"cannot build range expression with array function parameter %0 since "
"parameter with array type %1 is treated as pointer type %2">;
@@ -2275,6 +2264,9 @@ def warn_for_range_copy : Warning<
"loop variable %0 of type %1 creates a copy from type %2">,
InGroup<RangeLoopAnalysis>, DefaultIgnore;
def note_use_reference_type : Note<"use reference type %0 to prevent copying">;
+def err_objc_for_range_init_stmt : Error<
+ "initialization statement is not supported when iterating over Objective-C "
+ "collection">;
// C++11 constexpr
def warn_cxx98_compat_constexpr : Warning<
@@ -2330,6 +2322,13 @@ def warn_cxx11_compat_constexpr_body_invalid_stmt : Warning<
"use of this statement in a constexpr %select{function|constructor}0 "
"is incompatible with C++ standards before C++14">,
InGroup<CXXPre14Compat>, DefaultIgnore;
+def ext_constexpr_body_invalid_stmt_cxx2a : ExtWarn<
+ "use of this statement in a constexpr %select{function|constructor}0 "
+ "is a C++2a extension">, InGroup<CXX2a>;
+def warn_cxx17_compat_constexpr_body_invalid_stmt : Warning<
+ "use of this statement in a constexpr %select{function|constructor}0 "
+ "is incompatible with C++ standards before C++2a">,
+ InGroup<CXXPre2aCompat>, DefaultIgnore;
def ext_constexpr_type_definition : ExtWarn<
"type definition in a constexpr %select{function|constructor}0 "
"is a C++14 extension">, InGroup<CXX14>;
@@ -2382,6 +2381,16 @@ def note_constexpr_body_previous_return : Note<
"previous return statement is here">;
def err_constexpr_function_try_block : Error<
"function try block not allowed in constexpr %select{function|constructor}0">;
+
+// c++2a function try blocks in constexpr
+def ext_constexpr_function_try_block_cxx2a : ExtWarn<
+ "function try block in constexpr %select{function|constructor}0 is "
+ "a C++2a extension">, InGroup<CXX2a>;
+def warn_cxx17_compat_constexpr_function_try_block : Warning<
+ "function try block in constexpr %select{function|constructor}0 is "
+ "incompatible with C++ standards before C++2a">,
+ InGroup<CXXPre2aCompat>, DefaultIgnore;
+
def err_constexpr_union_ctor_no_init : Error<
"constexpr union constructor does not initialize any member">;
def err_constexpr_ctor_missing_init : Error<
@@ -2479,7 +2488,8 @@ def err_attribute_invalid_vector_type : Error<"invalid vector element type %0">;
def err_attribute_bad_neon_vector_size : Error<
"Neon vector size must be 64 or 128 bits">;
def err_attribute_requires_positive_integer : Error<
- "%0 attribute requires a positive integral compile time constant expression">;
+ "%0 attribute requires a %select{positive|non-negative}1 "
+ "integral compile time constant expression">;
def err_attribute_requires_opencl_version : Error<
"%0 attribute requires OpenCL version %1%select{| or above}2">;
def warn_unsupported_target_attribute
@@ -2521,8 +2531,6 @@ def err_attribute_argument_out_of_bounds : Error<
"%0 attribute parameter %1 is out of bounds">;
def err_attribute_only_once_per_parameter : Error<
"%0 attribute can only be applied once per parameter">;
-def err_attribute_uuid_malformed_guid : Error<
- "uuid attribute contains a malformed GUID">;
def err_mismatched_uuid : Error<"uuid does not match previous declaration">;
def note_previous_uuid : Note<"previous uuid specified here">;
def warn_attribute_pointers_only : Warning<
@@ -2599,6 +2607,10 @@ def err_arg_with_address_space : Error<
"parameter may not be qualified with an address space">;
def err_field_with_address_space : Error<
"field may not be qualified with an address space">;
+def err_compound_literal_with_address_space : Error<
+ "compound literal in function scope may not be qualified with an address space">;
+def err_address_space_mismatch_templ_inst : Error<
+ "conflicting address space qualifiers are provided between types %0 and %1">;
def err_attr_objc_ownership_redundant : Error<
"the type %0 is already explicitly ownership-qualified">;
def err_invalid_nsnumber_type : Error<
@@ -2742,8 +2754,6 @@ def warn_nocf_check_attribute_ignored :
def warn_attribute_after_definition_ignored : Warning<
"attribute %0 after definition is ignored">,
InGroup<IgnoredAttributes>;
-def warn_unknown_attribute_ignored : Warning<
- "unknown attribute %0 ignored">, InGroup<UnknownAttributes>;
def warn_cxx11_gnu_attribute_on_type : Warning<
"attribute %0 ignored, because it cannot be applied to a type">,
InGroup<IgnoredAttributes>;
@@ -2843,22 +2853,6 @@ def err_attribute_weakref_without_alias : Error<
"weakref declaration of %0 must also have an alias attribute">;
def err_alias_not_supported_on_darwin : Error <
"aliases are not supported on darwin">;
-def err_alias_to_undefined : Error<
- "%select{alias|ifunc}0 must point to a defined %select{variable or |}1function">;
-def warn_alias_to_weak_alias : Warning<
- "%select{alias|ifunc}2 will always resolve to %0 even if weak definition of %1 is overridden">,
- InGroup<IgnoredAttributes>;
-def warn_alias_with_section : Warning<
- "%select{alias|ifunc}1 will not be in section '%0' but in the same section as the %select{aliasee|resolver}2">,
- InGroup<IgnoredAttributes>;
-def err_duplicate_mangled_name : Error<
- "definition with same mangled name '%0' as another definition">;
-def err_cyclic_alias : Error<
- "%select{alias|ifunc}0 definition is part of a cycle">;
-def err_ifunc_resolver_return : Error<
- "ifunc resolver function must return a pointer">;
-def err_ifunc_resolver_params : Error<
- "ifunc resolver function must have no parameters">;
def warn_attribute_wrong_decl_type_str : Warning<
"%0 attribute only applies to %1">, InGroup<IgnoredAttributes>;
def err_attribute_wrong_decl_type_str : Error<
@@ -2960,6 +2954,9 @@ def warn_availability_on_static_initializer : Warning<
InGroup<Availability>;
def note_overridden_method : Note<
"overridden method is here">;
+def warn_availability_swift_unavailable_deprecated_only : Warning<
+ "only 'unavailable' and 'deprecated' are supported for Swift availability">,
+ InGroup<Availability>;
def note_protocol_method : Note<
"protocol method is here">;
@@ -2986,6 +2983,14 @@ def warn_invalid_capability_name : Warning<
def warn_thread_attribute_ignored : Warning<
"ignoring %0 attribute because its argument is invalid">,
InGroup<ThreadSafetyAttributes>, DefaultIgnore;
+def warn_thread_attribute_not_on_non_static_member : Warning<
+ "%0 attribute without capability arguments can only be applied to non-static "
+ "methods of a class">,
+ InGroup<ThreadSafetyAttributes>, DefaultIgnore;
+def warn_thread_attribute_not_on_capability_member : Warning<
+ "%0 attribute without capability arguments refers to 'this', but %1 isn't "
+ "annotated with 'capability' or 'scoped_lockable' attribute">,
+ InGroup<ThreadSafetyAttributes>, DefaultIgnore;
def warn_thread_attribute_argument_not_lockable : Warning<
"%0 attribute requires arguments whose type is annotated "
"with 'capability' attribute; type here is %1">,
@@ -3143,10 +3148,10 @@ def err_impcast_complex_scalar : Error<
"implicit conversion from %0 to %1 is not permitted in C++">;
def warn_impcast_float_precision : Warning<
"implicit conversion loses floating-point precision: %0 to %1">,
- InGroup<Conversion>, DefaultIgnore;
+ InGroup<ImplicitFloatConversion>, DefaultIgnore;
def warn_impcast_float_result_precision : Warning<
"implicit conversion when assigning computation result loses floating-point precision: %0 to %1">,
- InGroup<Conversion>, DefaultIgnore;
+ InGroup<ImplicitFloatConversion>, DefaultIgnore;
def warn_impcast_double_promotion : Warning<
"implicit conversion increases floating-point precision: %0 to %1">,
InGroup<DoublePromotion>, DefaultIgnore;
@@ -3158,7 +3163,13 @@ def warn_impcast_integer_sign_conditional : Warning<
InGroup<SignConversion>, DefaultIgnore;
def warn_impcast_integer_precision : Warning<
"implicit conversion loses integer precision: %0 to %1">,
- InGroup<Conversion>, DefaultIgnore;
+ InGroup<ImplicitIntConversion>, DefaultIgnore;
+def warn_impcast_high_order_zero_bits : Warning<
+ "higher order bits are zeroes after implicit conversion">,
+ InGroup<ImplicitIntConversion>, DefaultIgnore;
+def warn_impcast_nonnegative_result : Warning<
+ "the resulting value is always non-negative after implicit conversion">,
+ InGroup<SignConversion>, DefaultIgnore;
def warn_impcast_integer_64_32 : Warning<
"implicit conversion loses integer precision: %0 to %1">,
InGroup<Shorten64To32>, DefaultIgnore;
@@ -3247,6 +3258,10 @@ def warn_address_of_reference_null_compare : Warning<
InGroup<TautologicalUndefinedCompare>;
def note_reference_is_return_value : Note<"%0 returns a reference">;
+def warn_division_sizeof_ptr : Warning<
+ "'%0' will return the size of the pointer, not the array itself">,
+ InGroup<DiagGroup<"sizeof-pointer-div">>;
+
def note_function_warning_silence : Note<
"prefix with the address-of operator to silence this warning">;
def note_function_to_function_call : Note<
@@ -3410,7 +3425,7 @@ def err_ns_attribute_wrong_parameter_type : Error<
"%select{Objective-C object|pointer|pointer-to-CF-pointer}1 parameters">;
def warn_ns_attribute_wrong_parameter_type : Warning<
"%0 attribute only applies to "
- "%select{Objective-C object|pointer|pointer-to-CF-pointer}1 parameters">,
+ "%select{Objective-C object|pointer|pointer-to-CF-pointer|pointer/reference-to-OSObject-pointer}1 parameters">,
InGroup<IgnoredAttributes>;
def warn_objc_requires_super_protocol : Warning<
"%0 attribute cannot be applied to %select{methods in protocols|dealloc}1">,
@@ -3470,6 +3485,11 @@ def err_objc_bridged_related_known_method : Error<
def err_objc_attr_protocol_requires_definition : Error<
"attribute %0 can only be applied to @protocol definitions, not forward declarations">;
+def warn_ignored_objc_externally_retained : Warning<
+ "'objc_externally_retained' can only be applied to local variables "
+ "%select{of retainable type|with strong ownership}0">,
+ InGroup<IgnoredAttributes>;
+
// Function Parameter Semantic Analysis.
def err_param_with_void_type : Error<"argument may not have 'void' type">;
def err_void_only_param : Error<
@@ -3574,11 +3594,7 @@ def note_ovl_candidate : Note<
"| has type mismatch at %ordinal5 parameter"
"%diff{ (expected $ but has $)|}6,7"
"| has different return type%diff{ ($ expected but has $)|}5,6"
- "| has different qualifiers (expected "
- "%select{none|const|restrict|const and restrict|volatile|const and volatile"
- "|volatile and restrict|const, volatile, and restrict}5 but found "
- "%select{none|const|restrict|const and restrict|volatile|const and volatile"
- "|volatile and restrict|const, volatile, and restrict}6)"
+ "| has different qualifiers (expected %5 but found %6)"
"| has different exception specification}4">;
def note_ovl_candidate_inherited_constructor : Note<
@@ -3630,7 +3646,7 @@ def warn_diagnose_if_succeeded : Warning<"%0">, InGroup<UserDefinedWarnings>,
def note_ovl_candidate_disabled_by_function_cond_attr : Note<
"candidate disabled: %0">;
def note_ovl_candidate_disabled_by_extension : Note<
- "candidate disabled due to OpenCL extension">;
+ "candidate unavailable as it requires OpenCL extension '%0' to be enabled">;
def err_addrof_function_disabled_by_enable_if_attr : Error<
"cannot take address of function %0 because it has one or more "
"non-tautological enable_if conditions">;
@@ -4255,6 +4271,8 @@ def note_forward_template_decl : Note<
def note_inst_declaration_hint : Note<"add an explicit instantiation "
"declaration to suppress this warning if %q0 is explicitly instantiated in "
"another translation unit">;
+def note_evaluating_exception_spec_here : Note<
+ "in evaluation of exception specification for %q0 needed here">;
def note_default_arg_instantiation_here : Note<
"in instantiation of default argument for '%0' required here">;
@@ -4547,7 +4565,10 @@ def warn_unavailable_fwdclass_message : Warning<
InGroup<UnavailableDeclarations>;
def note_availability_specified_here : Note<
"%0 has been explicitly marked "
- "%select{unavailable|deleted|deprecated|partial}1 here">;
+ "%select{unavailable|deleted|deprecated}1 here">;
+def note_partial_availability_specified_here : Note<
+ "%0 has been marked as being introduced in %1 %2 here, "
+ "but the deployment target is %1 %3">;
def note_implicitly_deleted : Note<
"explicitly defaulted function was implicitly deleted here">;
def warn_not_enough_argument : Warning<
@@ -4750,16 +4771,18 @@ def err_nested_redefinition : Error<"nested redefinition of %0">;
def err_use_with_wrong_tag : Error<
"use of %0 with tag type that does not match previous declaration">;
def warn_struct_class_tag_mismatch : Warning<
- "%select{struct|interface|class}0%select{| template}1 %2 was previously "
- "declared as a %select{struct|interface|class}3%select{| template}1">,
- InGroup<MismatchedTags>, DefaultIgnore;
+ "%select{struct|interface|class}0%select{| template}1 %2 was previously "
+ "declared as a %select{struct|interface|class}3%select{| template}1; "
+ "this is valid, but may result in linker errors under the Microsoft C++ ABI">,
+ InGroup<MismatchedTags>, DefaultIgnore;
def warn_struct_class_previous_tag_mismatch : Warning<
- "%2 defined as %select{a struct|an interface|a class}0%select{| template}1 "
- "here but previously declared as "
- "%select{a struct|an interface|a class}3%select{| template}1">,
- InGroup<MismatchedTags>, DefaultIgnore;
+ "%2 defined as %select{a struct|an interface|a class}0%select{| template}1 "
+ "here but previously declared as "
+ "%select{a struct|an interface|a class}3%select{| template}1; "
+ "this is valid, but may result in linker errors under the Microsoft C++ ABI">,
+ InGroup<MismatchedTags>, DefaultIgnore;
def note_struct_class_suggestion : Note<
- "did you mean %select{struct|interface|class}0 here?">;
+ "did you mean %select{struct|interface|class}0 here?">;
def ext_forward_ref_enum : Extension<
"ISO C forbids forward references to 'enum' types">;
def err_forward_ref_enum : Error<
@@ -4804,21 +4827,6 @@ def err_vm_func_decl : Error<
def err_array_too_large : Error<
"array is too large (%0 elements)">;
-// -Wpadded, -Wpacked
-def warn_padded_struct_field : Warning<
- "padding %select{struct|interface|class}0 %1 with %2 "
- "%select{byte|bit}3%s2 to align %4">,
- InGroup<Padded>, DefaultIgnore;
-def warn_padded_struct_anon_field : Warning<
- "padding %select{struct|interface|class}0 %1 with %2 "
- "%select{byte|bit}3%s2 to align anonymous bit-field">,
- InGroup<Padded>, DefaultIgnore;
-def warn_padded_struct_size : Warning<
- "padding size of %0 with %1 %select{byte|bit}2%s1 to alignment boundary">,
- InGroup<Padded>, DefaultIgnore;
-def warn_unnecessary_packed : Warning<
- "packed attribute is unnecessary for %0">, InGroup<Packed>, DefaultIgnore;
-
def err_typecheck_negative_array_size : Error<"array size is negative">;
def warn_typecheck_function_qualifiers_ignored : Warning<
"'%0' qualifier on function type %1 has no effect">,
@@ -4873,7 +4881,7 @@ def warn_braces_around_scalar_init : Warning<
"braces around scalar initializer">, InGroup<DiagGroup<"braced-scalar-init">>;
def ext_many_braces_around_scalar_init : ExtWarn<
"too many braces around scalar initializer">,
- InGroup<DiagGroup<"many-braces-around-scalar-init">>;
+ InGroup<DiagGroup<"many-braces-around-scalar-init">>, SFINAEFailure;
def ext_complex_component_init : Extension<
"complex initialization specifying real and imaginary components "
"is an extension">, InGroup<DiagGroup<"complex-component-init">>;
@@ -5254,6 +5262,9 @@ def err_typecheck_arc_assign_self_class_method : Error<
def err_typecheck_arr_assign_enumeration : Error<
"fast enumeration variables cannot be modified in ARC by default; "
"declare the variable __strong to allow this">;
+def err_typecheck_arc_assign_externally_retained : Error<
+ "variable declared with 'objc_externally_retained' "
+ "cannot be modified in ARC">;
def warn_arc_retained_assign : Warning<
"assigning retained object to %select{weak|unsafe_unretained}0 "
"%select{property|variable}1"
@@ -5428,20 +5439,24 @@ def err_atomic_specifier_bad_type : Error<
"%1 %select{||||||which is not trivially copyable}0">;
// Expressions.
+def select_unary_expr_or_type_trait_kind : TextSubstitution<
+ "%select{sizeof|alignof|vec_step|__builtin_omp_required_simd_align|"
+ "__alignof}0">;
def ext_sizeof_alignof_function_type : Extension<
- "invalid application of '%select{sizeof|alignof|vec_step}0' to a "
- "function type">, InGroup<PointerArith>;
+ "invalid application of '%sub{select_unary_expr_or_type_trait_kind}0' "
+ "to a function type">, InGroup<PointerArith>;
def ext_sizeof_alignof_void_type : Extension<
- "invalid application of '%select{sizeof|alignof|vec_step}0' to a void "
- "type">, InGroup<PointerArith>;
+ "invalid application of '%sub{select_unary_expr_or_type_trait_kind}0' "
+ "to a void type">, InGroup<PointerArith>;
def err_opencl_sizeof_alignof_type : Error<
- "invalid application of '%select{sizeof|alignof|vec_step|__builtin_omp_required_simd_align}0' to a void type">;
+ "invalid application of '%sub{select_unary_expr_or_type_trait_kind}0' "
+ "to a void type">;
def err_sizeof_alignof_incomplete_type : Error<
- "invalid application of '%select{sizeof|alignof|vec_step|__builtin_omp_required_simd_align}0' to an "
- "incomplete type %1">;
+ "invalid application of '%sub{select_unary_expr_or_type_trait_kind}0' "
+ "to an incomplete type %1">;
def err_sizeof_alignof_function_type : Error<
- "invalid application of '%select{sizeof|alignof|vec_step|__builtin_omp_required_simd_align}0' to a "
- "function type">;
+ "invalid application of '%sub{select_unary_expr_or_type_trait_kind}0' "
+ "to a function type">;
def err_openmp_default_simd_align_expr : Error<
"invalid application of '__builtin_omp_required_simd_align' to an expression, only type is allowed">;
def err_sizeof_alignof_typeof_bitfield : Error<
@@ -5749,8 +5764,14 @@ def err_array_init_plain_string_into_char8_t : Error<
def note_array_init_plain_string_into_char8_t : Note<
"add 'u8' prefix to form a 'char8_t' string literal">;
def err_array_init_utf8_string_into_char : Error<
- "initialization of char array with UTF-8 string literal is not permitted "
- "by '-fchar8_t'">;
+ "%select{|ISO C++20 does not permit }0initialization of char array with "
+ "UTF-8 string literal%select{ is not permitted by '-fchar8_t'|}0">;
+def warn_cxx2a_compat_utf8_string : Warning<
+ "type of UTF-8 string literal will change from array of const char to "
+ "array of const char8_t in C++2a">, InGroup<CXX2aCompat>, DefaultIgnore;
+def note_cxx2a_compat_utf8_string_remove_u8 : Note<
+ "remove 'u8' prefix to avoid a change of behavior; "
+ "Clang encodes unprefixed narrow string literals as UTF-8">;
def err_array_init_different_type : Error<
"cannot initialize array %diff{of type $ with array of type $|"
"with different type of array}0,1">;
@@ -5857,7 +5878,8 @@ def ext_typecheck_comparison_of_fptr_to_void : Extension<
def err_typecheck_comparison_of_fptr_to_void : Error<
"equality comparison between function pointer and void pointer (%0 and %1)">;
def ext_typecheck_comparison_of_pointer_integer : ExtWarn<
- "comparison between pointer and integer (%0 and %1)">;
+ "comparison between pointer and integer (%0 and %1)">,
+ InGroup<DiagGroup<"pointer-integer-compare">>;
def err_typecheck_comparison_of_pointer_integer : Error<
"comparison between pointer and integer (%0 and %1)">;
def ext_typecheck_comparison_of_distinct_pointers : ExtWarn<
@@ -6437,12 +6459,12 @@ def warn_non_virtual_dtor : Warning<
def warn_delete_non_virtual_dtor : Warning<
"%select{delete|destructor}0 called on non-final %1 that has "
"virtual functions but non-virtual destructor">,
- InGroup<DeleteNonVirtualDtor>, DefaultIgnore, ShowInSystemHeader;
+ InGroup<DeleteNonAbstractNonVirtualDtor>, DefaultIgnore, ShowInSystemHeader;
def note_delete_non_virtual : Note<
"qualify call to silence this warning">;
def warn_delete_abstract_non_virtual_dtor : Warning<
"%select{delete|destructor}0 called on %1 that is abstract but has "
- "non-virtual destructor">, InGroup<DeleteNonVirtualDtor>, ShowInSystemHeader;
+ "non-virtual destructor">, InGroup<DeleteAbstractNonVirtualDtor>, ShowInSystemHeader;
def warn_overloaded_virtual : Warning<
"%q0 hides overloaded virtual %select{function|functions}1">,
InGroup<OverloadedVirtual>, DefaultIgnore;
@@ -6452,11 +6474,7 @@ def note_hidden_overloaded_virtual_declared_here : Note<
"|: different number of parameters (%2 vs %3)"
"|: type mismatch at %ordinal2 parameter%diff{ ($ vs $)|}3,4"
"|: different return type%diff{ ($ vs $)|}2,3"
- "|: different qualifiers ("
- "%select{none|const|restrict|const and restrict|volatile|const and volatile|"
- "volatile and restrict|const, volatile, and restrict}2 vs "
- "%select{none|const|restrict|const and restrict|volatile|const and volatile|"
- "volatile and restrict|const, volatile, and restrict}3)"
+ "|: different qualifiers (%2 vs %3)"
"|: different exception specifications}1">;
def warn_using_directive_in_header : Warning<
"using namespace directive in global context in header">,
@@ -6465,12 +6483,12 @@ def warn_overaligned_type : Warning<
"type %0 requires %1 bytes of alignment and the default allocator only "
"guarantees %2 bytes">,
InGroup<OveralignedType>, DefaultIgnore;
-def warn_aligned_allocation_unavailable :Warning<
+def err_aligned_allocation_unavailable : Error<
"aligned %select{allocation|deallocation}0 function of type '%1' is only "
- "available on %2 %3 or newer">, InGroup<AlignedAllocationUnavailable>, DefaultError;
-def note_silence_unligned_allocation_unavailable : Note<
+ "available on %2 %3 or newer">;
+def note_silence_aligned_allocation_unavailable : Note<
"if you supply your own aligned allocation functions, use "
- "-Wno-aligned-allocation-unavailable to silence this diagnostic">;
+ "-faligned-allocation to silence this diagnostic">;
def err_conditional_void_nonvoid : Error<
"%select{left|right}1 operand to ? is void, but %select{right|left}1 operand "
@@ -6572,6 +6590,11 @@ let CategoryName = "Lambda Issue" in {
def err_init_capture_deduction_failure_from_init_list : Error<
"cannot deduce type for lambda capture %0 from initializer list">;
+ // C++14 generic lambdas.
+ def warn_cxx11_compat_generic_lambda : Warning<
+ "generic lambdas are incompatible with C++11">,
+ InGroup<CXXPre14Compat>, DefaultIgnore;
+
// C++17 '*this' captures.
def warn_cxx14_compat_star_this_lambda_capture : Warning<
"by value capture of '*this' is incompatible with C++ standards before C++17">,
@@ -6579,6 +6602,10 @@ let CategoryName = "Lambda Issue" in {
def ext_star_this_lambda_capture_cxx17 : ExtWarn<
"capture of '*this' by copy is a C++17 extension">, InGroup<CXX17>;
+ // C++17 parameter shadows capture
+ def err_parameter_shadow_capture : Error<
+ "a lambda parameter cannot shadow an explicitly captured entity">;
+
// C++2a [=, this] captures.
def warn_cxx17_compat_equals_this_lambda_capture : Warning<
"explicit capture of 'this' with a capture default of '=' is incompatible "
@@ -6591,6 +6618,11 @@ let CategoryName = "Lambda Issue" in {
InGroup<DeprecatedThisCapture>, DefaultIgnore;
def note_deprecated_this_capture : Note<
"add an explicit capture of 'this' to capture '*this' by reference">;
+
+ // C++2a default constructible / assignable lambdas.
+ def warn_cxx17_compat_lambda_def_ctor_assign : Warning<
+ "%select{default construction|assignment}0 of lambda is incompatible with "
+ "C++ standards before C++2a">, InGroup<CXXPre2aCompat>, DefaultIgnore;
}
def err_return_in_captured_stmt : Error<
@@ -6716,11 +6748,7 @@ def err_typecheck_convert_incompatible : Error<
"|: different number of parameters (%5 vs %6)"
"|: type mismatch at %ordinal5 parameter%diff{ ($ vs $)|}6,7"
"|: different return type%diff{ ($ vs $)|}5,6"
- "|: different qualifiers ("
- "%select{none|const|restrict|const and restrict|volatile|const and volatile|"
- "volatile and restrict|const, volatile, and restrict}5 vs "
- "%select{none|const|restrict|const and restrict|volatile|const and volatile|"
- "volatile and restrict|const, volatile, and restrict}6)"
+ "|: different qualifiers (%5 vs %6)"
"|: different exception specifications}4">;
def err_typecheck_missing_return_type_incompatible : Error<
"%diff{return type $ must match previous return type $|"
@@ -7063,9 +7091,9 @@ def warn_atomic_op_has_invalid_memory_order : Warning<
InGroup<DiagGroup<"atomic-memory-ordering">>;
def err_atomic_op_has_invalid_synch_scope : Error<
"synchronization scope argument to atomic operation is invalid">;
-def warn_atomic_op_misaligned : Warning<
- "misaligned or large atomic operation may incur significant performance penalty">,
- InGroup<DiagGroup<"atomic-alignment">>;
+def warn_atomic_implicit_seq_cst : Warning<
+ "implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary">,
+ InGroup<DiagGroup<"atomic-implicit-seq-cst">>, DefaultIgnore;
def err_overflow_builtin_must_be_int : Error<
"operand argument to overflow builtin must be an integer (%0 invalid)">;
@@ -7326,8 +7354,6 @@ let CategoryName = "Inline Assembly Issue" in {
"invalid input constraint '%0' in asm">;
def err_asm_immediate_expected : Error<"constraint '%0' expects "
"an integer constant expression">;
- def err_asm_invalid_type_in_input : Error<
- "invalid type %0 in asm input for constraint '%1'">;
def err_asm_tying_incompatible_types : Error<
"unsupported inline asm: input with type "
"%diff{$ matching output with type $|}0,1">;
@@ -7451,8 +7477,6 @@ def note_in_class_initializer_not_yet_parsed : Note<
"default member initializer declared here">;
def err_in_class_initializer_cycle
: Error<"default member initializer for %0 uses itself">;
-def err_exception_spec_cycle
- : Error<"exception specification of %0 uses itself">;
def ext_in_class_initializer_non_constant : Extension<
"in-class initializer for static data member is not a constant expression; "
@@ -7712,9 +7736,19 @@ def err_incorrect_defaulted_exception_spec : Error<
def err_incorrect_defaulted_constexpr : Error<
"defaulted definition of %sub{select_special_member_kind}0 "
"is not constexpr">;
+def warn_defaulted_method_deleted : Warning<
+ "explicitly defaulted %sub{select_special_member_kind}0 is implicitly "
+ "deleted">, InGroup<DiagGroup<"defaulted-function-deleted">>;
def err_out_of_line_default_deletes : Error<
"defaulting this %sub{select_special_member_kind}0 "
"would delete it after its first declaration">;
+def note_deleted_type_mismatch : Note<
+ "function is implicitly deleted because its declared type does not match "
+ "the type of an implicit %sub{select_special_member_kind}0">;
+def warn_cxx17_compat_defaulted_method_type_mismatch : Warning<
+ "explicitly defaulting this %sub{select_special_member_kind}0 with a type "
+ "different from the implicit type is incompatible with C++ standards before "
+ "C++2a">, InGroup<CXXPre2aCompat>, DefaultIgnore;
def warn_vbase_moved_multiple_times : Warning<
"defaulted move assignment operator of %0 will move assign virtual base "
"class %1 multiple times">, InGroup<DiagGroup<"multiple-move-vbase">>;
@@ -7820,6 +7854,8 @@ def warn_format_non_standard: Warning<
def warn_format_non_standard_conversion_spec: Warning<
"using length modifier '%0' with conversion specifier '%1' is not supported by ISO C">,
InGroup<FormatNonStandard>, DefaultIgnore;
+def err_invalid_mask_type_size : Error<
+ "mask type size must be between 1-byte and 8-bytes">;
def warn_format_invalid_annotation : Warning<
"using '%0' format specifier annotation outside of os_log()/os_trace()">,
InGroup<Format>;
@@ -8518,6 +8554,8 @@ def err_opencl_scalar_type_rank_greater_than_vector_type : Error<
"element. (%0 and %1)">;
def err_bad_kernel_param_type : Error<
"%0 cannot be used as the type of a kernel parameter">;
+def err_opencl_implicit_function_decl : Error<
+ "implicit declaration of function %0 is invalid in OpenCL">;
def err_record_with_pointers_kernel_param : Error<
"%select{struct|union}0 kernel parameters may not contain pointers">;
def note_within_field_of_type : Note<
@@ -8575,6 +8613,10 @@ def err_opencl_variadic_function : Error<
"invalid prototype, variadic arguments are not allowed in OpenCL">;
def err_opencl_requires_extension : Error<
"use of %select{type|declaration}0 %1 requires %2 extension to be enabled">;
+def warn_opencl_generic_address_space_arg : Warning<
+ "passing non-generic address space pointer to %0"
+ " may cause dynamic conversion affecting performance">,
+ InGroup<Conversion>, DefaultIgnore;
// OpenCL v2.0 s6.13.6 -- Builtin Pipe Functions
def err_opencl_builtin_pipe_first_arg : Error<
@@ -8596,11 +8638,6 @@ def err_opencl_multiple_access_qualifiers : Error<
def note_opencl_typedef_access_qualifier : Note<
"previously declared '%0' here">;
-// OpenCL Section 6.8.g
-def err_opencl_unknown_type_specifier : Error<
- "OpenCL %select{C|C++}0 version %1 does not support the '%2' "
- "%select{type qualifier|storage class specifier}3">;
-
// OpenCL v2.0 s6.12.5 Blocks restrictions
def err_opencl_block_storage_type : Error<
"the __block storage type is not permitted">;
@@ -8685,6 +8722,8 @@ def err_omp_expected_access_to_data_field : Error<
"expected access to data field">;
def err_omp_multiple_array_items_in_map_clause : Error<
"multiple array elements associated with the same variable are not allowed in map clauses of the same construct">;
+def err_omp_duplicate_map_type_modifier : Error<
+ "same map type modifier has been specified more than once">;
def err_omp_pointer_mapped_along_with_derived_section : Error<
"pointer cannot be mapped along with a section derived from itself">;
def err_omp_original_storage_is_shared_and_does_not_contain : Error<
@@ -8743,8 +8782,10 @@ def err_omp_required_access : Error<
"%0 variable must be %1">;
def err_omp_const_variable : Error<
"const-qualified variable cannot be %0">;
-def err_omp_const_reduction_list_item : Error<
- "const-qualified list item cannot be reduction">;
+def err_omp_const_not_mutable_variable : Error<
+ "const-qualified variable without mutable fields cannot be %0">;
+def err_omp_const_list_item : Error<
+ "const-qualified list item cannot be %0">;
def err_omp_linear_incomplete_type : Error<
"a linear variable with incomplete type %0">;
def err_omp_linear_expected_int_or_ptr : Error<
@@ -8756,8 +8797,6 @@ def warn_omp_linear_step_zero : Warning<
def warn_omp_alignment_not_power_of_two : Warning<
"aligned clause will be ignored because the requested alignment is not a power of 2">,
InGroup<OpenMPClauses>;
-def err_omp_enclosed_declare_target : Error<
- "declare target region may not be enclosed within another declare target region">;
def err_omp_invalid_target_decl : Error<
"%0 used in declare target directive is not a variable or a function name">;
def err_omp_declare_target_multiple : Error<
@@ -9029,6 +9068,20 @@ def err_omp_linear_distribute_var_non_loop_iteration : Error<
def warn_omp_non_trivial_type_mapped : Warning<
"Non-trivial type %0 is mapped, only trivial types are guaranteed to be mapped correctly">,
InGroup<OpenMPTarget>;
+def err_omp_requires_clause_redeclaration : Error <
+ "Only one %0 clause can appear on a requires directive in a single translation unit">;
+def note_omp_requires_previous_clause : Note <
+ "%0 clause previously used here">;
+def err_omp_invalid_scope : Error <
+ "'#pragma omp %0' directive must appear only in file scope">;
+def note_omp_invalid_length_on_this_ptr_mapping : Note <
+ "expected length on mapping of 'this' array section expression to be '1'">;
+def note_omp_invalid_lower_bound_on_this_ptr_mapping : Note <
+ "expected lower bound on mapping of 'this' array section expression to be '0' or not specified">;
+def note_omp_invalid_subscript_on_this_ptr_map : Note <
+ "expected 'this' subscript expression on map clause to be 'this[0]'">;
+def err_omp_invalid_map_this_expr : Error <
+ "invalid 'this' expression on 'map' clause">;
} // end of OpenMP category
let CategoryName = "Related Result Type Issue" in {
@@ -9061,6 +9114,8 @@ def err_invalid_type_for_program_scope_var : Error<
let CategoryName = "Modules Issue" in {
def err_module_decl_in_module_map_module : Error<
"'module' declaration found while building module from module map">;
+def err_module_decl_in_header_module : Error<
+ "'module' declaration found while building header module">;
def err_module_interface_implementation_mismatch : Error<
"missing 'export' specifier in module declaration while "
"building module interface">;
@@ -9209,22 +9264,6 @@ def warn_not_a_doxygen_trailing_member_comment : Warning<
"not a Doxygen trailing comment">, InGroup<Documentation>, DefaultIgnore;
} // end of documentation issue category
-let CategoryName = "Instrumentation Issue" in {
-def warn_profile_data_out_of_date : Warning<
- "profile data may be out of date: of %0 function%s0, %1 %plural{1:has|:have}1"
- " mismatched data that will be ignored">,
- InGroup<ProfileInstrOutOfDate>;
-def warn_profile_data_missing : Warning<
- "profile data may be incomplete: of %0 function%s0, %1 %plural{1:has|:have}1"
- " no data">,
- InGroup<ProfileInstrMissing>,
- DefaultIgnore;
-def warn_profile_data_unprofiled : Warning<
- "no profile data available for file \"%0\"">,
- InGroup<ProfileInstrUnprofiled>;
-
-} // end of instrumentation issue category
-
let CategoryName = "Nullability Issue" in {
def warn_mismatched_nullability_attr : Warning<
@@ -9372,14 +9411,9 @@ def warn_block_literal_qualifiers_on_omitted_return_type : Warning<
"'%0' qualifier on omitted return type %1 has no effect">,
InGroup<IgnoredQualifiers>;
-def ext_warn_gnu_final : ExtWarn<
- "__final is a GNU extension, consider using C++11 final">,
- InGroup<GccCompat>;
-
-def warn_shadow_field :
- Warning<"non-static data member %0 of %1 shadows member inherited from "
- "type %2">,
- InGroup<ShadowField>, DefaultIgnore;
+def warn_shadow_field : Warning<
+ "%select{parameter|non-static data member}3 %0 %select{|of %1 }3shadows "
+ "member inherited from type %2">, InGroup<ShadowField>, DefaultIgnore;
def note_shadow_field : Note<"declared here">;
def err_multiversion_required_in_redecl : Error<
@@ -9440,4 +9474,18 @@ def err_std_compare_type_not_supported : Error<
"member '%2' is missing|"
"the type is not trivially copyable|"
"the type does not have the expected form}1">;
+
+def warn_dereference_of_noderef_type : Warning<
+ "dereferencing %0; was declared with a 'noderef' type">, InGroup<NoDeref>;
+def warn_dereference_of_noderef_type_no_decl : Warning<
+ "dereferencing expression marked as 'noderef'">, InGroup<NoDeref>;
+def warn_noderef_on_non_pointer_or_array : Warning<
+ "'noderef' can only be used on an array or pointer type">, InGroup<IgnoredAttributes>;
+def warn_noderef_to_dereferenceable_pointer : Warning<
+ "casting to dereferenceable pointer removes 'noderef' attribute">, InGroup<NoDeref>;
+
+def err_builtin_launder_invalid_arg : Error<
+ "%select{non-pointer|function pointer|void pointer}0 argument to "
+ "'__builtin_launder' is not allowed">;
+
} // end of sema component.
diff --git a/include/clang/Basic/DiagnosticSerialization.h b/include/clang/Basic/DiagnosticSerialization.h
new file mode 100644
index 000000000000..d19e638dcf13
--- /dev/null
+++ b/include/clang/Basic/DiagnosticSerialization.h
@@ -0,0 +1,29 @@
+//===--- DiagnosticSerialization.h - Serialization Diagnostics -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_DIAGNOSTICSERIALIZATION_H
+#define LLVM_CLANG_BASIC_DIAGNOSTICSERIALIZATION_H
+
+#include "clang/Basic/Diagnostic.h"
+
+namespace clang {
+namespace diag {
+enum {
+#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
+ SHOWINSYSHEADER, CATEGORY) \
+ ENUM,
+#define SERIALIZATIONSTART
+#include "clang/Basic/DiagnosticSerializationKinds.inc"
+#undef DIAG
+ NUM_BUILTIN_SERIALIZATION_DIAGNOSTICS
+};
+} // end namespace diag
+} // end namespace clang
+
+#endif // LLVM_CLANG_BASIC_DIAGNOSTICSERIALIZATION_H
diff --git a/include/clang/Basic/Features.def b/include/clang/Basic/Features.def
index a0e0ce4560ab..05464ed85f13 100644
--- a/include/clang/Basic/Features.def
+++ b/include/clang/Basic/Features.def
@@ -17,6 +17,12 @@
//
// The Predicate field dictates the conditions under which the feature or
// extension will be made available.
+//
+// FEATURE(...) should be used to advertise support for standard language
+// features, whereas EXTENSION(...) should be used for clang extensions. Note
+// that many of the identifiers in this file don't follow this rule for backward
+// compatibility reasons.
+//
//===----------------------------------------------------------------------===//
#if !defined(FEATURE) && !defined(EXTENSION)
@@ -37,6 +43,9 @@ FEATURE(address_sanitizer,
FEATURE(hwaddress_sanitizer,
LangOpts.Sanitize.hasOneOf(SanitizerKind::HWAddress |
SanitizerKind::KernelHWAddress))
+FEATURE(xray_instrument, LangOpts.XRayInstrument)
+FEATURE(undefined_behavior_sanitizer,
+ LangOpts.Sanitize.hasOneOf(SanitizerKind::Undefined))
FEATURE(assume_nonnull, true)
FEATURE(attribute_analyzer_noreturn, true)
FEATURE(attribute_availability, true)
@@ -48,6 +57,7 @@ FEATURE(attribute_availability_watchos, true)
FEATURE(attribute_availability_with_strict, true)
FEATURE(attribute_availability_with_replacement, true)
FEATURE(attribute_availability_in_templates, true)
+FEATURE(attribute_availability_swift, true)
FEATURE(attribute_cf_returns_not_retained, true)
FEATURE(attribute_cf_returns_retained, true)
FEATURE(attribute_cf_returns_on_parameters, true)
@@ -72,7 +82,9 @@ FEATURE(cxx_rtti, LangOpts.RTTI &&LangOpts.RTTIData)
FEATURE(enumerator_attributes, true)
FEATURE(nullability, true)
FEATURE(nullability_on_arrays, true)
-FEATURE(memory_sanitizer, LangOpts.Sanitize.has(SanitizerKind::Memory))
+FEATURE(memory_sanitizer,
+ LangOpts.Sanitize.hasOneOf(SanitizerKind::Memory |
+ SanitizerKind::KernelMemory))
FEATURE(thread_sanitizer, LangOpts.Sanitize.has(SanitizerKind::Thread))
FEATURE(dataflow_sanitizer, LangOpts.Sanitize.has(SanitizerKind::DataFlow))
FEATURE(efficiency_sanitizer,
@@ -83,11 +95,11 @@ FEATURE(objc_arr, LangOpts.ObjCAutoRefCount) // FIXME: REMOVE?
FEATURE(objc_arc, LangOpts.ObjCAutoRefCount)
FEATURE(objc_arc_fields, true)
FEATURE(objc_arc_weak, LangOpts.ObjCWeak)
-FEATURE(objc_default_synthesize_properties, LangOpts.ObjC2)
-FEATURE(objc_fixed_enum, LangOpts.ObjC2)
-FEATURE(objc_instancetype, LangOpts.ObjC2)
-FEATURE(objc_kindof, LangOpts.ObjC2)
-FEATURE(objc_modules, LangOpts.ObjC2 &&LangOpts.Modules)
+FEATURE(objc_default_synthesize_properties, LangOpts.ObjC)
+FEATURE(objc_fixed_enum, true)
+FEATURE(objc_instancetype, LangOpts.ObjC)
+FEATURE(objc_kindof, LangOpts.ObjC)
+FEATURE(objc_modules, LangOpts.ObjC && LangOpts.Modules)
FEATURE(objc_nonfragile_abi, LangOpts.ObjCRuntime.isNonFragile())
FEATURE(objc_property_explicit_atomic, true)
FEATURE(objc_protocol_qualifier_mangling, true)
@@ -97,16 +109,16 @@ FEATURE(ownership_returns, true)
FEATURE(ownership_takes, true)
FEATURE(objc_bool, true)
FEATURE(objc_subscripting, LangOpts.ObjCRuntime.isNonFragile())
-FEATURE(objc_array_literals, LangOpts.ObjC2)
-FEATURE(objc_dictionary_literals, LangOpts.ObjC2)
-FEATURE(objc_boxed_expressions, LangOpts.ObjC2)
-FEATURE(objc_boxed_nsvalue_expressions, LangOpts.ObjC2)
+FEATURE(objc_array_literals, LangOpts.ObjC)
+FEATURE(objc_dictionary_literals, LangOpts.ObjC)
+FEATURE(objc_boxed_expressions, LangOpts.ObjC)
+FEATURE(objc_boxed_nsvalue_expressions, LangOpts.ObjC)
FEATURE(arc_cf_code_audited, true)
FEATURE(objc_bridge_id, true)
FEATURE(objc_bridge_id_on_typedefs, true)
-FEATURE(objc_generics, LangOpts.ObjC2)
-FEATURE(objc_generics_variance, LangOpts.ObjC2)
-FEATURE(objc_class_property, LangOpts.ObjC2)
+FEATURE(objc_generics, LangOpts.ObjC)
+FEATURE(objc_generics_variance, LangOpts.ObjC)
+FEATURE(objc_class_property, LangOpts.ObjC)
// C11 features
FEATURE(c_alignas, LangOpts.C11)
FEATURE(c_alignof, LangOpts.C11)
@@ -227,12 +239,14 @@ EXTENSION(cxx_range_for, LangOpts.CPlusPlus)
EXTENSION(cxx_reference_qualified_functions, LangOpts.CPlusPlus)
EXTENSION(cxx_rvalue_references, LangOpts.CPlusPlus)
EXTENSION(cxx_variadic_templates, LangOpts.CPlusPlus)
+EXTENSION(cxx_fixed_enum, true)
// C++14 features supported by other languages as extensions.
EXTENSION(cxx_binary_literals, true)
EXTENSION(cxx_init_captures, LangOpts.CPlusPlus11)
EXTENSION(cxx_variable_templates, LangOpts.CPlusPlus)
// Miscellaneous language extensions
EXTENSION(overloadable_unmarked, true)
+EXTENSION(pragma_clang_attribute_namespaces, true)
#undef EXTENSION
#undef FEATURE
diff --git a/include/clang/Basic/FileManager.h b/include/clang/Basic/FileManager.h
index ab5dfca71639..e7891baf5304 100644
--- a/include/clang/Basic/FileManager.h
+++ b/include/clang/Basic/FileManager.h
@@ -16,7 +16,7 @@
#define LLVM_CLANG_BASIC_FILEMANAGER_H
#include "clang/Basic/FileSystemOptions.h"
-#include "clang/Basic/VirtualFileSystem.h"
+#include "clang/Basic/LLVM.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/SmallVector.h"
@@ -25,9 +25,10 @@
#include "llvm/Support/Allocator.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/VirtualFileSystem.h"
#include <ctime>
-#include <memory>
#include <map>
+#include <memory>
#include <string>
namespace llvm {
@@ -69,14 +70,15 @@ class FileEntry {
bool IsNamedPipe;
bool InPCH;
bool IsValid; // Is this \c FileEntry initialized and valid?
+ bool DeferredOpen; // Created by getFile(OpenFile=0); may open later.
/// The open file, if it is owned by the \p FileEntry.
- mutable std::unique_ptr<vfs::File> File;
+ mutable std::unique_ptr<llvm::vfs::File> File;
public:
FileEntry()
- : UniqueID(0, 0), IsNamedPipe(false), InPCH(false), IsValid(false)
- {}
+ : UniqueID(0, 0), IsNamedPipe(false), InPCH(false), IsValid(false),
+ DeferredOpen(false) {}
FileEntry(const FileEntry &) = delete;
FileEntry &operator=(const FileEntry &) = delete;
@@ -102,6 +104,10 @@ public:
void closeFile() const {
File.reset(); // rely on destructor to close File
}
+
+ // Only for use in tests to see if deferred opens are happening, rather than
+ // relying on RealPathName being empty.
+ bool isOpenForTests() const { return File != nullptr; }
};
struct FileData;
@@ -114,7 +120,7 @@ struct FileData;
/// as a single file.
///
class FileManager : public RefCountedBase<FileManager> {
- IntrusiveRefCntPtr<vfs::FileSystem> FS;
+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS;
FileSystemOptions FileSystemOpts;
/// Cache for existing real directories.
@@ -165,15 +171,18 @@ class FileManager : public RefCountedBase<FileManager> {
std::unique_ptr<FileSystemStatCache> StatCache;
bool getStatValue(StringRef Path, FileData &Data, bool isFile,
- std::unique_ptr<vfs::File> *F);
+ std::unique_ptr<llvm::vfs::File> *F);
/// Add all ancestors of the given path (pointing to either a file
/// or a directory) as virtual directories.
void addAncestorsAsVirtualDirs(StringRef Path);
+ /// Fills the RealPathName in file entry.
+ void fillRealPathName(FileEntry *UFE, llvm::StringRef FileName);
+
public:
FileManager(const FileSystemOptions &FileSystemOpts,
- IntrusiveRefCntPtr<vfs::FileSystem> FS = nullptr);
+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS = nullptr);
~FileManager();
/// Installs the provided FileSystemStatCache object within
@@ -183,18 +192,10 @@ public:
///
/// \param statCache the new stat cache to install. Ownership of this
/// object is transferred to the FileManager.
- ///
- /// \param AtBeginning whether this new stat cache must be installed at the
- /// beginning of the chain of stat caches. Otherwise, it will be added to
- /// the end of the chain.
- void addStatCache(std::unique_ptr<FileSystemStatCache> statCache,
- bool AtBeginning = false);
-
- /// Removes the specified FileSystemStatCache object from the manager.
- void removeStatCache(FileSystemStatCache *statCache);
+ void setStatCache(std::unique_ptr<FileSystemStatCache> statCache);
- /// Removes all FileSystemStatCache objects from the manager.
- void clearStatCaches();
+ /// Removes the FileSystemStatCache object from the manager.
+ void clearStatCache();
/// Lookup, cache, and verify the specified directory (real or
/// virtual).
@@ -222,7 +223,7 @@ public:
FileSystemOptions &getFileSystemOpts() { return FileSystemOpts; }
const FileSystemOptions &getFileSystemOpts() const { return FileSystemOpts; }
- IntrusiveRefCntPtr<vfs::FileSystem> getVirtualFileSystem() const {
+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> getVirtualFileSystem() const {
return FS;
}
@@ -247,8 +248,7 @@ public:
/// FileManager's FileSystemOptions.
///
/// \returns false on success, true on error.
- bool getNoncachedStatValue(StringRef Path,
- vfs::Status &Result);
+ bool getNoncachedStatValue(StringRef Path, llvm::vfs::Status &Result);
/// Remove the real file \p Entry from the cache.
void invalidateCache(const FileEntry *Entry);
diff --git a/include/clang/Basic/FileSystemStatCache.h b/include/clang/Basic/FileSystemStatCache.h
index 1ec344623a0d..f93170c754d5 100644
--- a/include/clang/Basic/FileSystemStatCache.h
+++ b/include/clang/Basic/FileSystemStatCache.h
@@ -26,7 +26,7 @@
#include <string>
#include <utility>
-namespace clang {
+namespace llvm {
namespace vfs {
@@ -34,6 +34,9 @@ class File;
class FileSystem;
} // namespace vfs
+} // namespace llvm
+
+namespace clang {
// FIXME: should probably replace this with vfs::Status
struct FileData {
@@ -57,9 +60,6 @@ struct FileData {
class FileSystemStatCache {
virtual void anchor();
-protected:
- std::unique_ptr<FileSystemStatCache> NextStatCache;
-
public:
virtual ~FileSystemStatCache() = default;
@@ -82,42 +82,16 @@ public:
/// implementation can optionally fill in \p F with a valid \p File object and
/// the client guarantees that it will close it.
static bool get(StringRef Path, FileData &Data, bool isFile,
- std::unique_ptr<vfs::File> *F, FileSystemStatCache *Cache,
- vfs::FileSystem &FS);
-
- /// Sets the next stat call cache in the chain of stat caches.
- /// Takes ownership of the given stat cache.
- void setNextStatCache(std::unique_ptr<FileSystemStatCache> Cache) {
- NextStatCache = std::move(Cache);
- }
-
- /// Retrieve the next stat call cache in the chain.
- FileSystemStatCache *getNextStatCache() { return NextStatCache.get(); }
-
- /// Retrieve the next stat call cache in the chain, transferring
- /// ownership of this cache (and, transitively, all of the remaining caches)
- /// to the caller.
- std::unique_ptr<FileSystemStatCache> takeNextStatCache() {
- return std::move(NextStatCache);
- }
+ std::unique_ptr<llvm::vfs::File> *F,
+ FileSystemStatCache *Cache, llvm::vfs::FileSystem &FS);
protected:
// FIXME: The pointer here is a non-owning/optional reference to the
// unique_ptr. Optional<unique_ptr<vfs::File>&> might be nicer, but
// Optional needs some work to support references so this isn't possible yet.
virtual LookupResult getStat(StringRef Path, FileData &Data, bool isFile,
- std::unique_ptr<vfs::File> *F,
- vfs::FileSystem &FS) = 0;
-
- LookupResult statChained(StringRef Path, FileData &Data, bool isFile,
- std::unique_ptr<vfs::File> *F, vfs::FileSystem &FS) {
- if (FileSystemStatCache *Next = getNextStatCache())
- return Next->getStat(Path, Data, isFile, F, FS);
-
- // If we hit the end of the list of stat caches to try, just compute and
- // return it without a cache.
- return get(Path, Data, isFile, F, nullptr, FS) ? CacheMissing : CacheExists;
- }
+ std::unique_ptr<llvm::vfs::File> *F,
+ llvm::vfs::FileSystem &FS) = 0;
};
/// A stat "cache" that can be used by FileManager to keep
@@ -135,8 +109,8 @@ public:
iterator end() const { return StatCalls.end(); }
LookupResult getStat(StringRef Path, FileData &Data, bool isFile,
- std::unique_ptr<vfs::File> *F,
- vfs::FileSystem &FS) override;
+ std::unique_ptr<llvm::vfs::File> *F,
+ llvm::vfs::FileSystem &FS) override;
};
} // namespace clang
diff --git a/include/clang/Basic/FixedPoint.h b/include/clang/Basic/FixedPoint.h
new file mode 100644
index 000000000000..9a9b7cc9c1fb
--- /dev/null
+++ b/include/clang/Basic/FixedPoint.h
@@ -0,0 +1,138 @@
+//===- FixedPoint.h - Fixed point constant handling -------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file
+/// Defines the fixed point number interface.
+/// This is a class for abstracting various operations performed on fixed point
+/// types described in ISO/IEC JTC1 SC22 WG14 N1169 starting at clause 4.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_FIXEDPOINT_H
+#define LLVM_CLANG_BASIC_FIXEDPOINT_H
+
+#include "llvm/ADT/APSInt.h"
+
+namespace clang {
+
+class ASTContext;
+class QualType;
+
+/// The fixed point semantics work similarly to llvm::fltSemantics. The width
+/// specifies the whole bit width of the underlying scaled integer (with padding
+/// if any). The scale represents the number of fractional bits in this type.
+/// When HasUnsignedPadding is true and this type is signed, the first bit
+/// in the value this represents is treaded as padding.
+class FixedPointSemantics {
+public:
+ FixedPointSemantics(unsigned Width, unsigned Scale, bool IsSigned,
+ bool IsSaturated, bool HasUnsignedPadding)
+ : Width(Width), Scale(Scale), IsSigned(IsSigned),
+ IsSaturated(IsSaturated), HasUnsignedPadding(HasUnsignedPadding) {
+ assert(Width >= Scale && "Not enough room for the scale");
+ }
+
+ unsigned getWidth() const { return Width; }
+ unsigned getScale() const { return Scale; }
+ bool isSigned() const { return IsSigned; }
+ bool isSaturated() const { return IsSaturated; }
+ bool hasUnsignedPadding() const { return HasUnsignedPadding; }
+
+ void setSaturated(bool Saturated) { IsSaturated = Saturated; }
+
+ unsigned getIntegralBits() const {
+ if (IsSigned || (!IsSigned && HasUnsignedPadding))
+ return Width - Scale - 1;
+ else
+ return Width - Scale;
+ }
+
+private:
+ unsigned Width;
+ unsigned Scale;
+ bool IsSigned;
+ bool IsSaturated;
+ bool HasUnsignedPadding;
+};
+
+/// The APFixedPoint class works similarly to APInt/APSInt in that it is a
+/// functional replacement for a scaled integer. It is meant to replicate the
+/// fixed point types proposed in ISO/IEC JTC1 SC22 WG14 N1169. The class carries
+/// info about the fixed point type's width, sign, scale, and saturation, and
+/// provides different operations that would normally be performed on fixed point
+/// types.
+///
+/// Semantically this does not represent any existing C type other than fixed
+/// point types and should eventually be moved to LLVM if fixed point types gain
+/// native IR support.
+class APFixedPoint {
+ public:
+ APFixedPoint(const llvm::APInt &Val, const FixedPointSemantics &Sema)
+ : Val(Val, !Sema.isSigned()), Sema(Sema) {
+ assert(Val.getBitWidth() == Sema.getWidth() &&
+ "The value should have a bit width that matches the Sema width");
+ }
+
+ APFixedPoint(uint64_t Val, const FixedPointSemantics &Sema)
+ : APFixedPoint(llvm::APInt(Sema.getWidth(), Val, Sema.isSigned()),
+ Sema) {}
+
+ llvm::APSInt getValue() const { return llvm::APSInt(Val, !Sema.isSigned()); }
+ inline unsigned getWidth() const { return Sema.getWidth(); }
+ inline unsigned getScale() const { return Sema.getScale(); }
+ inline bool isSaturated() const { return Sema.isSaturated(); }
+ inline bool isSigned() const { return Sema.isSigned(); }
+ inline bool hasPadding() const { return Sema.hasUnsignedPadding(); }
+
+ // Convert this number to match the semantics provided.
+ APFixedPoint convert(const FixedPointSemantics &DstSema) const;
+
+ APFixedPoint shr(unsigned Amt) const {
+ return APFixedPoint(Val >> Amt, Sema);
+ }
+
+ APFixedPoint shl(unsigned Amt) const {
+ return APFixedPoint(Val << Amt, Sema);
+ }
+
+ llvm::APSInt getIntPart() const {
+ if (Val < 0 && Val != -Val) // Cover the case when we have the min val
+ return -(-Val >> getScale());
+ else
+ return Val >> getScale();
+ }
+
+ // If LHS > RHS, return 1. If LHS == RHS, return 0. If LHS < RHS, return -1.
+ int compare(const APFixedPoint &Other) const;
+ bool operator==(const APFixedPoint &Other) const {
+ return compare(Other) == 0;
+ }
+ bool operator!=(const APFixedPoint &Other) const {
+ return compare(Other) != 0;
+ }
+ bool operator>(const APFixedPoint &Other) const { return compare(Other) > 0; }
+ bool operator<(const APFixedPoint &Other) const { return compare(Other) < 0; }
+ bool operator>=(const APFixedPoint &Other) const {
+ return compare(Other) >= 0;
+ }
+ bool operator<=(const APFixedPoint &Other) const {
+ return compare(Other) <= 0;
+ }
+
+ static APFixedPoint getMax(const FixedPointSemantics &Sema);
+ static APFixedPoint getMin(const FixedPointSemantics &Sema);
+
+private:
+ llvm::APSInt Val;
+ FixedPointSemantics Sema;
+};
+
+} // namespace clang
+
+#endif
diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h
index c2e9c71b0f0d..82e8c8c34951 100644
--- a/include/clang/Basic/IdentifierTable.h
+++ b/include/clang/Basic/IdentifierTable.h
@@ -34,6 +34,8 @@
namespace clang {
+class DeclarationName;
+class DeclarationNameTable;
class IdentifierInfo;
class LangOptions;
class MultiKeywordSelector;
@@ -42,52 +44,91 @@ class SourceLocation;
/// A simple pair of identifier info and location.
using IdentifierLocPair = std::pair<IdentifierInfo *, SourceLocation>;
+/// IdentifierInfo and other related classes are aligned to
+/// 8 bytes so that DeclarationName can use the lower 3 bits
+/// of a pointer to one of these classes.
+enum { IdentifierInfoAlignment = 8 };
+
/// One of these records is kept for each identifier that
/// is lexed. This contains information about whether the token was \#define'd,
/// is a language keyword, or if it is a front-end token of some sort (e.g. a
/// variable or function name). The preprocessor keeps this information in a
/// set, and all tok::identifier tokens have a pointer to one of these.
-class IdentifierInfo {
+/// It is aligned to 8 bytes because DeclarationName needs the lower 3 bits.
+class alignas(IdentifierInfoAlignment) IdentifierInfo {
friend class IdentifierTable;
- unsigned TokenID : 9; // Front-end token ID or tok::identifier.
- // Objective-C keyword ('protocol' in '@protocol') or builtin (__builtin_inf).
- // First NUM_OBJC_KEYWORDS values are for Objective-C, the remaining values
- // are for builtins.
- unsigned ObjCOrBuiltinID :13;
- bool HasMacro : 1; // True if there is a #define for this.
- bool HadMacro : 1; // True if there was a #define for this.
- bool IsExtension : 1; // True if identifier is a lang extension.
- bool IsFutureCompatKeyword : 1; // True if identifier is a keyword in a
- // newer Standard or proposed Standard.
- bool IsPoisoned : 1; // True if identifier is poisoned.
- bool IsCPPOperatorKeyword : 1; // True if ident is a C++ operator keyword.
- bool NeedsHandleIdentifier : 1; // See "RecomputeNeedsHandleIdentifier".
- bool IsFromAST : 1; // True if identifier was loaded (at least
- // partially) from an AST file.
- bool ChangedAfterLoad : 1; // True if identifier has changed from the
- // definition loaded from an AST file.
- bool FEChangedAfterLoad : 1; // True if identifier's frontend information
- // has changed from the definition loaded
- // from an AST file.
- bool RevertedTokenID : 1; // True if revertTokenIDToIdentifier was
- // called.
- bool OutOfDate : 1; // True if there may be additional
- // information about this identifier
- // stored externally.
- bool IsModulesImport : 1; // True if this is the 'import' contextual
- // keyword.
- // 29 bit left in 64-bit word.
+ // Front-end token ID or tok::identifier.
+ unsigned TokenID : 9;
+
+ // ObjC keyword ('protocol' in '@protocol') or builtin (__builtin_inf).
+ // First NUM_OBJC_KEYWORDS values are for Objective-C,
+ // the remaining values are for builtins.
+ unsigned ObjCOrBuiltinID : 13;
+
+ // True if there is a #define for this.
+ unsigned HasMacro : 1;
+
+ // True if there was a #define for this.
+ unsigned HadMacro : 1;
+
+ // True if the identifier is a language extension.
+ unsigned IsExtension : 1;
+
+ // True if the identifier is a keyword in a newer or proposed Standard.
+ unsigned IsFutureCompatKeyword : 1;
+
+ // True if the identifier is poisoned.
+ unsigned IsPoisoned : 1;
+
+ // True if the identifier is a C++ operator keyword.
+ unsigned IsCPPOperatorKeyword : 1;
+
+ // Internal bit set by the member function RecomputeNeedsHandleIdentifier.
+ // See comment about RecomputeNeedsHandleIdentifier for more info.
+ unsigned NeedsHandleIdentifier : 1;
+
+ // True if the identifier was loaded (at least partially) from an AST file.
+ unsigned IsFromAST : 1;
+
+ // True if the identifier has changed from the definition
+ // loaded from an AST file.
+ unsigned ChangedAfterLoad : 1;
+
+ // True if the identifier's frontend information has changed from the
+ // definition loaded from an AST file.
+ unsigned FEChangedAfterLoad : 1;
+
+ // True if revertTokenIDToIdentifier was called.
+ unsigned RevertedTokenID : 1;
+
+ // True if there may be additional information about
+ // this identifier stored externally.
+ unsigned OutOfDate : 1;
+
+ // True if this is the 'import' contextual keyword.
+ unsigned IsModulesImport : 1;
+
+ // 29 bits left in a 64-bit word.
// Managed by the language front-end.
void *FETokenInfo = nullptr;
llvm::StringMapEntry<IdentifierInfo *> *Entry = nullptr;
+ IdentifierInfo()
+ : TokenID(tok::identifier), ObjCOrBuiltinID(0), HasMacro(false),
+ HadMacro(false), IsExtension(false), IsFutureCompatKeyword(false),
+ IsPoisoned(false), IsCPPOperatorKeyword(false),
+ NeedsHandleIdentifier(false), IsFromAST(false), ChangedAfterLoad(false),
+ FEChangedAfterLoad(false), RevertedTokenID(false), OutOfDate(false),
+ IsModulesImport(false) {}
+
public:
- IdentifierInfo();
IdentifierInfo(const IdentifierInfo &) = delete;
IdentifierInfo &operator=(const IdentifierInfo &) = delete;
+ IdentifierInfo(IdentifierInfo &&) = delete;
+ IdentifierInfo &operator=(IdentifierInfo &&) = delete;
/// Return true if this is the identifier for the specified string.
///
@@ -106,31 +147,10 @@ public:
/// Return the beginning of the actual null-terminated string for this
/// identifier.
- const char *getNameStart() const {
- if (Entry) return Entry->getKeyData();
- // FIXME: This is gross. It would be best not to embed specific details
- // of the PTH file format here.
- // The 'this' pointer really points to a
- // std::pair<IdentifierInfo, const char*>, where internal pointer
- // points to the external string data.
- using actualtype = std::pair<IdentifierInfo, const char *>;
-
- return ((const actualtype*) this)->second;
- }
+ const char *getNameStart() const { return Entry->getKeyData(); }
/// Efficiently return the length of this identifier info.
- unsigned getLength() const {
- if (Entry) return Entry->getKeyLength();
- // FIXME: This is gross. It would be best not to embed specific details
- // of the PTH file format here.
- // The 'this' pointer really points to a
- // std::pair<IdentifierInfo, const char*>, where internal pointer
- // points to the external string data.
- using actualtype = std::pair<IdentifierInfo, const char *>;
-
- const char* p = ((const actualtype*) this)->second - 2;
- return (((unsigned) p[0]) | (((unsigned) p[1]) << 8)) - 1;
- }
+ unsigned getLength() const { return Entry->getKeyLength(); }
/// Return the actual identifier string.
StringRef getName() const {
@@ -284,10 +304,9 @@ public:
/// language.
bool isCPlusPlusKeyword(const LangOptions &LangOpts) const;
- /// getFETokenInfo/setFETokenInfo - The language front-end is allowed to
- /// associate arbitrary metadata with this token.
- template<typename T>
- T *getFETokenInfo() const { return static_cast<T*>(FETokenInfo); }
+ /// Get and set FETokenInfo. The language front-end is allowed to associate
+ /// arbitrary metadata with this token.
+ void *getFETokenInfo() const { return FETokenInfo; }
void setFETokenInfo(void *T) { FETokenInfo = T; }
/// Return true if the Preprocessor::HandleIdentifier must be called
@@ -653,16 +672,22 @@ enum ObjCStringFormatFamily {
/// accounts for 78% of all selectors in Cocoa.h.
class Selector {
friend class Diagnostic;
+ friend class SelectorTable; // only the SelectorTable can create these
+ friend class DeclarationName; // and the AST's DeclarationName.
enum IdentifierInfoFlag {
- // Empty selector = 0.
- ZeroArg = 0x1,
- OneArg = 0x2,
- MultiArg = 0x3,
- ArgFlags = ZeroArg|OneArg
+ // Empty selector = 0. Note that these enumeration values must
+ // correspond to the enumeration values of DeclarationName::StoredNameKind
+ ZeroArg = 0x01,
+ OneArg = 0x02,
+ MultiArg = 0x07,
+ ArgFlags = 0x07
};
- // a pointer to the MultiKeywordSelector or IdentifierInfo.
+ /// A pointer to the MultiKeywordSelector or IdentifierInfo. We use the low
+ /// three bits of InfoPtr to store an IdentifierInfoFlag. Note that in any
+ /// case IdentifierInfo and MultiKeywordSelector are already aligned to
+ /// 8 bytes even on 32 bits archs because of DeclarationName.
uintptr_t InfoPtr = 0;
Selector(IdentifierInfo *II, unsigned nArgs) {
@@ -697,13 +722,10 @@ class Selector {
static ObjCStringFormatFamily getStringFormatFamilyImpl(Selector sel);
public:
- friend class SelectorTable; // only the SelectorTable can create these
- friend class DeclarationName; // and the AST's DeclarationName.
-
/// The default ctor should only be used when creating data structures that
/// will contain selectors.
Selector() = default;
- Selector(uintptr_t V) : InfoPtr(V) {}
+ explicit Selector(uintptr_t V) : InfoPtr(V) {}
/// operator==/!= - Indicate whether the specified selectors are identical.
bool operator==(Selector RHS) const {
@@ -832,39 +854,68 @@ public:
static std::string getPropertyNameFromSetterSelector(Selector Sel);
};
-/// DeclarationNameExtra - Common base of the MultiKeywordSelector,
-/// CXXSpecialName, and CXXOperatorIdName classes, all of which are
-/// private classes that describe different kinds of names.
-class DeclarationNameExtra {
-public:
- /// ExtraKind - The kind of "extra" information stored in the
- /// DeclarationName. See @c ExtraKindOrNumArgs for an explanation of
- /// how these enumerator values are used.
+namespace detail {
+
+/// DeclarationNameExtra is used as a base of various uncommon special names.
+/// This class is needed since DeclarationName has not enough space to store
+/// the kind of every possible names. Therefore the kind of common names is
+/// stored directly in DeclarationName, and the kind of uncommon names is
+/// stored in DeclarationNameExtra. It is aligned to 8 bytes because
+/// DeclarationName needs the lower 3 bits to store the kind of common names.
+/// DeclarationNameExtra is tightly coupled to DeclarationName and any change
+/// here is very likely to require changes in DeclarationName(Table).
+class alignas(IdentifierInfoAlignment) DeclarationNameExtra {
+ friend class clang::DeclarationName;
+ friend class clang::DeclarationNameTable;
+
+protected:
+ /// The kind of "extra" information stored in the DeclarationName. See
+ /// @c ExtraKindOrNumArgs for an explanation of how these enumerator values
+ /// are used. Note that DeclarationName depends on the numerical values
+ /// of the enumerators in this enum. See DeclarationName::StoredNameKind
+ /// for more info.
enum ExtraKind {
- CXXConstructor = 0,
- CXXDestructor,
- CXXConversionFunction,
-#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
- CXXOperator##Name,
-#include "clang/Basic/OperatorKinds.def"
- CXXDeductionGuide,
- CXXLiteralOperator,
+ CXXDeductionGuideName,
+ CXXLiteralOperatorName,
CXXUsingDirective,
- NUM_EXTRA_KINDS
+ ObjCMultiArgSelector
};
- /// ExtraKindOrNumArgs - Either the kind of C++ special name or
- /// operator-id (if the value is one of the CXX* enumerators of
- /// ExtraKind), in which case the DeclarationNameExtra is also a
- /// CXXSpecialName, (for CXXConstructor, CXXDestructor, or
- /// CXXConversionFunction) CXXOperatorIdName, or CXXLiteralOperatorName,
- /// it may be also name common to C++ using-directives (CXXUsingDirective),
- /// otherwise it is NUM_EXTRA_KINDS+NumArgs, where NumArgs is the number of
- /// arguments in the Objective-C selector, in which case the
- /// DeclarationNameExtra is also a MultiKeywordSelector.
+ /// ExtraKindOrNumArgs has one of the following meaning:
+ /// * The kind of an uncommon C++ special name. This DeclarationNameExtra
+ /// is in this case in fact either a CXXDeductionGuideNameExtra or
+ /// a CXXLiteralOperatorIdName.
+ ///
+ /// * It may be also name common to C++ using-directives (CXXUsingDirective),
+ ///
+ /// * Otherwise it is ObjCMultiArgSelector+NumArgs, where NumArgs is
+ /// the number of arguments in the Objective-C selector, in which
+ /// case the DeclarationNameExtra is also a MultiKeywordSelector.
unsigned ExtraKindOrNumArgs;
+
+ DeclarationNameExtra(ExtraKind Kind) : ExtraKindOrNumArgs(Kind) {}
+ DeclarationNameExtra(unsigned NumArgs)
+ : ExtraKindOrNumArgs(ObjCMultiArgSelector + NumArgs) {}
+
+ /// Return the corresponding ExtraKind.
+ ExtraKind getKind() const {
+ return static_cast<ExtraKind>(ExtraKindOrNumArgs >
+ (unsigned)ObjCMultiArgSelector
+ ? (unsigned)ObjCMultiArgSelector
+ : ExtraKindOrNumArgs);
+ }
+
+ /// Return the number of arguments in an ObjC selector. Only valid when this
+ /// is indeed an ObjCMultiArgSelector.
+ unsigned getNumArgs() const {
+ assert(ExtraKindOrNumArgs >= (unsigned)ObjCMultiArgSelector &&
+ "getNumArgs called but this is not an ObjC selector!");
+ return ExtraKindOrNumArgs - (unsigned)ObjCMultiArgSelector;
+ }
};
+} // namespace detail
+
} // namespace clang
namespace llvm {
diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def
index fc38af5b03f6..49961856c965 100644
--- a/include/clang/Basic/LangOptions.def
+++ b/include/clang/Basic/LangOptions.def
@@ -92,8 +92,7 @@ LANGOPT(CPlusPlus11 , 1, 0, "C++11")
LANGOPT(CPlusPlus14 , 1, 0, "C++14")
LANGOPT(CPlusPlus17 , 1, 0, "C++17")
LANGOPT(CPlusPlus2a , 1, 0, "C++2a")
-LANGOPT(ObjC1 , 1, 0, "Objective-C 1")
-LANGOPT(ObjC2 , 1, 0, "Objective-C 2")
+LANGOPT(ObjC , 1, 0, "Objective-C")
BENIGN_LANGOPT(ObjCDefaultSynthProperties , 1, 0,
"Objective-C auto-synthesized properties")
BENIGN_LANGOPT(EncodeExtendedBlockSig , 1, 0,
@@ -139,6 +138,7 @@ LANGOPT(NoBuiltin , 1, 0, "disable builtin functions")
LANGOPT(NoMathBuiltin , 1, 0, "disable math builtin functions")
LANGOPT(GNUAsm , 1, 1, "GNU-style inline assembly")
LANGOPT(CoroutinesTS , 1, 0, "C++ coroutines TS")
+LANGOPT(DllExportInlines , 1, 1, "dllexported classes dllexport inline methods")
LANGOPT(RelaxedTemplateTemplateArgs, 1, 0, "C++17 relaxed matching of template template arguments")
LANGOPT(DoubleSquareBracketAttributes, 1, 0, "'[[]]' attributes extension for all language standard modes")
@@ -203,14 +203,18 @@ LANGOPT(OpenMPSimd , 1, 0, "Use SIMD only OpenMP support.")
LANGOPT(OpenMPUseTLS , 1, 0, "Use TLS for threadprivates or runtime calls")
LANGOPT(OpenMPIsDevice , 1, 0, "Generate code only for OpenMP target device")
LANGOPT(OpenMPCUDAMode , 1, 0, "Generate code for OpenMP pragmas in SIMT/SPMD mode")
+LANGOPT(OpenMPCUDAForceFullRuntime , 1, 0, "Force to use full runtime in all constructs when offloading to CUDA devices")
LANGOPT(OpenMPHostCXXExceptions , 1, 0, "C++ exceptions handling in the host code.")
+LANGOPT(OpenMPCUDANumSMs , 32, 0, "Number of SMs for CUDA devices.")
+LANGOPT(OpenMPCUDABlocksPerSM , 32, 0, "Number of blocks per SM for CUDA devices.")
+LANGOPT(OpenMPOptimisticCollapse , 1, 0, "Use at most 32 bits to represent the collapsed loop nest counter.")
LANGOPT(RenderScript , 1, 0, "RenderScript")
LANGOPT(CUDAIsDevice , 1, 0, "compiling for CUDA device")
LANGOPT(CUDAAllowVariadicFunctions, 1, 0, "allowing variadic functions in CUDA device code")
LANGOPT(CUDAHostDeviceConstexpr, 1, 1, "treating unattributed constexpr functions as __host__ __device__")
LANGOPT(CUDADeviceApproxTranscendentals, 1, 0, "using approximate transcendental functions")
-LANGOPT(CUDARelocatableDeviceCode, 1, 0, "generate relocatable device code")
+LANGOPT(GPURelocatableDeviceCode, 1, 0, "generate relocatable device code")
LANGOPT(SizedDeallocation , 1, 0, "sized deallocation")
LANGOPT(AlignedAllocation , 1, 0, "aligned allocation")
@@ -224,7 +228,8 @@ BENIGN_LANGOPT(DumpRecordLayouts , 1, 0, "dumping the layout of IRgen'd records"
BENIGN_LANGOPT(DumpRecordLayoutsSimple , 1, 0, "dumping the layout of IRgen'd records in a simple form")
BENIGN_LANGOPT(DumpVTableLayouts , 1, 0, "dumping the layouts of emitted vtables")
LANGOPT(NoConstantCFStrings , 1, 0, "no constant CoreFoundation strings")
-BENIGN_LANGOPT(InlineVisibilityHidden , 1, 0, "hidden default visibility for inline C++ methods")
+BENIGN_LANGOPT(InlineVisibilityHidden , 1, 0, "hidden visibility for inline C++ methods")
+LANGOPT(GlobalAllocationFunctionVisibilityHidden , 1, 0, "hidden visibility for global operator new and delete declaration")
BENIGN_LANGOPT(ParseUnknownAnytype, 1, 0, "__unknown_anytype")
BENIGN_LANGOPT(DebuggerSupport , 1, 0, "debugger support")
BENIGN_LANGOPT(DebuggerCastResultToId, 1, 0, "for 'po' in the debugger, cast the result to id if it is of unknown type")
@@ -259,6 +264,8 @@ ENUM_LANGOPT(TypeVisibilityMode, Visibility, 3, DefaultVisibility,
"type symbol visibility")
ENUM_LANGOPT(StackProtector, StackProtectorMode, 2, SSPOff,
"stack protector mode")
+ENUM_LANGOPT(TrivialAutoVarInit, TrivialAutoVarInitKind, 2, TrivialAutoVarInitKind::Uninitialized,
+ "trivial automatic variable initialization")
ENUM_LANGOPT(SignedOverflowBehavior, SignedOverflowBehaviorTy, 2, SOB_Undefined,
"signed integer overflow handling")
@@ -308,6 +315,8 @@ LANGOPT(FixedPoint, 1, 0, "fixed point types")
LANGOPT(PaddingOnUnsignedFixedPoint, 1, 0,
"unsigned fixed point types having one extra padding bit")
+LANGOPT(RegisterStaticDestructors, 1, 1, "Register C++ static destructors")
+
#undef LANGOPT
#undef COMPATIBLE_LANGOPT
#undef BENIGN_LANGOPT
diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h
index a1396f84352f..9cff7c516043 100644
--- a/include/clang/Basic/LangOptions.h
+++ b/include/clang/Basic/LangOptions.h
@@ -54,6 +54,11 @@ public:
enum GCMode { NonGC, GCOnly, HybridGC };
enum StackProtectorMode { SSPOff, SSPOn, SSPStrong, SSPReq };
+ // Automatic variables live on the stack, and when trivial they're usually
+ // uninitialized because it's undefined behavior to use them without
+ // initializing them.
+ enum class TrivialAutoVarInitKind { Uninitialized, Zero, Pattern };
+
enum SignedOverflowBehaviorTy {
// Default C standard behavior.
SOB_Undefined,
@@ -73,8 +78,11 @@ public:
/// Compiling a module from a module map.
CMK_ModuleMap,
+ /// Compiling a module from a list of header files.
+ CMK_HeaderModule,
+
/// Compiling a C++ modules TS module interface unit.
- CMK_ModuleInterface
+ CMK_ModuleInterface,
};
enum PragmaMSPointersToMembersKind {
@@ -95,11 +103,14 @@ public:
enum AddrSpaceMapMangling { ASMM_Target, ASMM_On, ASMM_Off };
+ // Corresponds to _MSC_VER
enum MSVCMajorVersion {
- MSVC2010 = 16,
- MSVC2012 = 17,
- MSVC2013 = 18,
- MSVC2015 = 19
+ MSVC2010 = 1600,
+ MSVC2012 = 1700,
+ MSVC2013 = 1800,
+ MSVC2015 = 1900,
+ MSVC2017 = 1910,
+ MSVC2017_5 = 1912
};
/// Clang versions with different platform ABI conformance.
@@ -121,11 +132,34 @@ public:
/// whether we reuse base class tail padding in some ABIs.
Ver6,
+ /// Attempt to be ABI-compatible with code generated by Clang 7.0.x
+ /// (SVN r338536). This causes alignof (C++) and _Alignof (C11) to be
+ /// compatible with __alignof (i.e., return the preferred alignment)
+ /// rather than returning the required alignment.
+ Ver7,
+
/// Conform to the underlying platform's C and C++ ABIs as closely
/// as we can.
Latest
};
+ enum class CoreFoundationABI {
+ /// No interoperability ABI has been specified
+ Unspecified,
+ /// CoreFoundation does not have any language interoperability
+ Standalone,
+ /// Interoperability with the ObjectiveC runtime
+ ObjectiveC,
+ /// Interoperability with the latest known version of the Swift runtime
+ Swift,
+ /// Interoperability with the Swift 5.0 runtime
+ Swift5_0,
+ /// Interoperability with the Swift 4.2 runtime
+ Swift4_2,
+ /// Interoperability with the Swift 4.1 runtime
+ Swift4_1,
+ };
+
enum FPContractModeKind {
// Form fused FP ops only where result will not be affected.
FPC_Off,
@@ -137,6 +171,14 @@ public:
FPC_Fast
};
+ // TODO: merge FEnvAccessModeKind and FPContractModeKind
+ enum FEnvAccessModeKind {
+ FEA_Off,
+
+ FEA_On
+ };
+
+
public:
/// Set of enabled sanitizers.
SanitizerSet Sanitize;
@@ -164,6 +206,8 @@ public:
clang::ObjCRuntime ObjCRuntime;
+ CoreFoundationABI CFRuntime = CoreFoundationABI::Unspecified;
+
std::string ObjCConstantStringClass;
/// The name of the handler function to be called when -ftrapv is
@@ -235,7 +279,7 @@ public:
}
bool isCompatibleWithMSVC(MSVCMajorVersion MajorVersion) const {
- return MSCompatibilityVersion >= MajorVersion * 10000000U;
+ return MSCompatibilityVersion >= MajorVersion * 100000U;
}
/// Reset all of the options that are not considered when building a
@@ -262,14 +306,19 @@ public:
/// Floating point control options
class FPOptions {
public:
- FPOptions() : fp_contract(LangOptions::FPC_Off) {}
+ FPOptions() : fp_contract(LangOptions::FPC_Off),
+ fenv_access(LangOptions::FEA_Off) {}
// Used for serializing.
explicit FPOptions(unsigned I)
- : fp_contract(static_cast<LangOptions::FPContractModeKind>(I)) {}
+ : fp_contract(static_cast<LangOptions::FPContractModeKind>(I & 3)),
+ fenv_access(static_cast<LangOptions::FEnvAccessModeKind>((I >> 2) & 1))
+ {}
explicit FPOptions(const LangOptions &LangOpts)
- : fp_contract(LangOpts.getDefaultFPContractMode()) {}
+ : fp_contract(LangOpts.getDefaultFPContractMode()),
+ fenv_access(LangOptions::FEA_Off) {}
+ // FIXME: Use getDefaultFEnvAccessMode() when available.
bool allowFPContractWithinStatement() const {
return fp_contract == LangOptions::FPC_On;
@@ -289,12 +338,24 @@ public:
void setDisallowFPContract() { fp_contract = LangOptions::FPC_Off; }
+ bool allowFEnvAccess() const {
+ return fenv_access == LangOptions::FEA_On;
+ }
+
+ void setAllowFEnvAccess() {
+ fenv_access = LangOptions::FEA_On;
+ }
+
+ void setDisallowFEnvAccess() { fenv_access = LangOptions::FEA_Off; }
+
/// Used to serialize this.
- unsigned getInt() const { return fp_contract; }
+ unsigned getInt() const { return fp_contract | (fenv_access << 2); }
private:
- /// Adjust BinaryOperator::FPFeatures to match the bit-field size of this.
+ /// Adjust BinaryOperator::FPFeatures to match the total bit-field size
+ /// of these two.
unsigned fp_contract : 2;
+ unsigned fenv_access : 1;
};
/// Describes the kind of translation unit being processed.
diff --git a/include/clang/Basic/MSP430Target.def b/include/clang/Basic/MSP430Target.def
new file mode 100644
index 000000000000..758113c5f575
--- /dev/null
+++ b/include/clang/Basic/MSP430Target.def
@@ -0,0 +1,247 @@
+//===--- MSP430Target.def - MSP430 Feature/Processor Database----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the MSP430 devices and their features.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MSP430_MCU_FEAT
+#define MSP430_MCU_FEAT(NAME, HWMULT) MSP430_MCU(NAME)
+#endif
+
+#ifndef MSP430_MCU
+#define MSP430_MCU(NAME)
+#endif
+
+MSP430_MCU("msp430c111")
+MSP430_MCU("msp430c1111")
+MSP430_MCU("msp430c112")
+MSP430_MCU("msp430c1121")
+MSP430_MCU("msp430c1331")
+MSP430_MCU("msp430c1351")
+MSP430_MCU("msp430e112")
+MSP430_MCU("msp430f110")
+MSP430_MCU("msp430f1101")
+MSP430_MCU("msp430f1101a")
+MSP430_MCU("msp430f1111")
+MSP430_MCU("msp430f1111a")
+MSP430_MCU("msp430f112")
+MSP430_MCU("msp430f1121")
+MSP430_MCU("msp430f1121a")
+MSP430_MCU("msp430f1122")
+MSP430_MCU("msp430f1132")
+MSP430_MCU("msp430f122")
+MSP430_MCU("msp430f1222")
+MSP430_MCU("msp430f123")
+MSP430_MCU("msp430f1232")
+MSP430_MCU("msp430f133")
+MSP430_MCU("msp430f135")
+MSP430_MCU("msp430f155")
+MSP430_MCU("msp430f156")
+MSP430_MCU("msp430f157")
+MSP430_MCU("msp430p112")
+MSP430_MCU("msp430f2001")
+MSP430_MCU("msp430f2011")
+MSP430_MCU("msp430f2002")
+MSP430_MCU("msp430f2012")
+MSP430_MCU("msp430f2003")
+MSP430_MCU("msp430f2013")
+MSP430_MCU("msp430f2101")
+MSP430_MCU("msp430f2111")
+MSP430_MCU("msp430f2121")
+MSP430_MCU("msp430f2131")
+MSP430_MCU("msp430f2112")
+MSP430_MCU("msp430f2122")
+MSP430_MCU("msp430f2132")
+MSP430_MCU("msp430f2232")
+MSP430_MCU("msp430f2252")
+MSP430_MCU("msp430f2272")
+MSP430_MCU("msp430f2234")
+MSP430_MCU("msp430f2254")
+MSP430_MCU("msp430f2274")
+MSP430_MCU("msp430g2211")
+MSP430_MCU("msp430g2201")
+MSP430_MCU("msp430g2111")
+MSP430_MCU("msp430g2101")
+MSP430_MCU("msp430g2001")
+MSP430_MCU("msp430g2231")
+MSP430_MCU("msp430g2221")
+MSP430_MCU("msp430g2131")
+MSP430_MCU("msp430g2121")
+MSP430_MCU("msp430g2102")
+MSP430_MCU("msp430g2202")
+MSP430_MCU("msp430g2302")
+MSP430_MCU("msp430g2402")
+MSP430_MCU("msp430g2132")
+MSP430_MCU("msp430g2232")
+MSP430_MCU("msp430g2332")
+MSP430_MCU("msp430g2432")
+MSP430_MCU("msp430g2112")
+MSP430_MCU("msp430g2212")
+MSP430_MCU("msp430g2312")
+MSP430_MCU("msp430g2412")
+MSP430_MCU("msp430g2152")
+MSP430_MCU("msp430g2252")
+MSP430_MCU("msp430g2352")
+MSP430_MCU("msp430g2452")
+MSP430_MCU("msp430g2113")
+MSP430_MCU("msp430g2213")
+MSP430_MCU("msp430g2313")
+MSP430_MCU("msp430g2413")
+MSP430_MCU("msp430g2513")
+MSP430_MCU("msp430g2153")
+MSP430_MCU("msp430g2253")
+MSP430_MCU("msp430g2353")
+MSP430_MCU("msp430g2453")
+MSP430_MCU("msp430g2553")
+MSP430_MCU("msp430g2203")
+MSP430_MCU("msp430g2303")
+MSP430_MCU("msp430g2403")
+MSP430_MCU("msp430g2233")
+MSP430_MCU("msp430g2333")
+MSP430_MCU("msp430g2433")
+MSP430_MCU("msp430g2533")
+MSP430_MCU("msp430tch5e")
+MSP430_MCU("msp430g2444")
+MSP430_MCU("msp430g2544")
+MSP430_MCU("msp430g2744")
+MSP430_MCU("msp430g2755")
+MSP430_MCU("msp430g2855")
+MSP430_MCU("msp430g2955")
+MSP430_MCU("msp430g2230")
+MSP430_MCU("msp430g2210")
+MSP430_MCU("msp430c311s")
+MSP430_MCU("msp430c312")
+MSP430_MCU("msp430c313")
+MSP430_MCU("msp430c314")
+MSP430_MCU("msp430c315")
+MSP430_MCU("msp430c323")
+MSP430_MCU("msp430c325")
+MSP430_MCU("msp430c412")
+MSP430_MCU("msp430c413")
+MSP430_MCU("msp430e313")
+MSP430_MCU("msp430e315")
+MSP430_MCU("msp430e325")
+MSP430_MCU("msp430p313")
+MSP430_MCU("msp430p315")
+MSP430_MCU("msp430p315s")
+MSP430_MCU("msp430p325")
+MSP430_MCU("msp430f412")
+MSP430_MCU("msp430f413")
+MSP430_MCU("msp430f415")
+MSP430_MCU("msp430f417")
+MSP430_MCU("msp430f4132")
+MSP430_MCU("msp430f4152")
+MSP430_MCU("msp430f435")
+MSP430_MCU("msp430f436")
+MSP430_MCU("msp430f437")
+MSP430_MCU("msp430f4351")
+MSP430_MCU("msp430f4361")
+MSP430_MCU("msp430f4371")
+MSP430_MCU("msp430fe423")
+MSP430_MCU("msp430fe425")
+MSP430_MCU("msp430fe427")
+MSP430_MCU("msp430fe423a")
+MSP430_MCU("msp430fe425a")
+MSP430_MCU("msp430fe427a")
+MSP430_MCU("msp430fe4232")
+MSP430_MCU("msp430fe4242")
+MSP430_MCU("msp430fe4252")
+MSP430_MCU("msp430fe4272")
+MSP430_MCU("msp430f4250")
+MSP430_MCU("msp430f4260")
+MSP430_MCU("msp430f4270")
+MSP430_MCU("msp430fg4250")
+MSP430_MCU("msp430fg4260")
+MSP430_MCU("msp430fg4270")
+MSP430_MCU("msp430fw423")
+MSP430_MCU("msp430fw425")
+MSP430_MCU("msp430fw427")
+MSP430_MCU("msp430fw428")
+MSP430_MCU("msp430fw429")
+MSP430_MCU("msp430fg437")
+MSP430_MCU("msp430fg438")
+MSP430_MCU("msp430fg439")
+MSP430_MCU("msp430f438")
+MSP430_MCU("msp430f439")
+MSP430_MCU("msp430f477")
+MSP430_MCU("msp430f478")
+MSP430_MCU("msp430f479")
+MSP430_MCU("msp430fg477")
+MSP430_MCU("msp430fg478")
+MSP430_MCU("msp430fg479")
+
+// With 16-bit hardware multiplier
+MSP430_MCU_FEAT("msp430f147", "16bit")
+MSP430_MCU_FEAT("msp430f148", "16bit")
+MSP430_MCU_FEAT("msp430f149", "16bit")
+MSP430_MCU_FEAT("msp430f1471", "16bit")
+MSP430_MCU_FEAT("msp430f1481", "16bit")
+MSP430_MCU_FEAT("msp430f1491", "16bit")
+MSP430_MCU_FEAT("msp430f167", "16bit")
+MSP430_MCU_FEAT("msp430f168", "16bit")
+MSP430_MCU_FEAT("msp430f169", "16bit")
+MSP430_MCU_FEAT("msp430f1610", "16bit")
+MSP430_MCU_FEAT("msp430f1611", "16bit")
+MSP430_MCU_FEAT("msp430f1612", "16bit")
+MSP430_MCU_FEAT("msp430c336", "16bit")
+MSP430_MCU_FEAT("msp430c337", "16bit")
+MSP430_MCU_FEAT("msp430e337", "16bit")
+MSP430_MCU_FEAT("msp430p337", "16bit")
+MSP430_MCU_FEAT("msp430f423", "16bit")
+MSP430_MCU_FEAT("msp430f425", "16bit")
+MSP430_MCU_FEAT("msp430f427", "16bit")
+MSP430_MCU_FEAT("msp430f423a", "16bit")
+MSP430_MCU_FEAT("msp430f425a", "16bit")
+MSP430_MCU_FEAT("msp430f427a", "16bit")
+MSP430_MCU_FEAT("msp430f4481", "16bit")
+MSP430_MCU_FEAT("msp430f4491", "16bit")
+MSP430_MCU_FEAT("msp430f447", "16bit")
+MSP430_MCU_FEAT("msp430f448", "16bit")
+MSP430_MCU_FEAT("msp430f449", "16bit")
+MSP430_MCU_FEAT("msp430f2330", "16bit")
+MSP430_MCU_FEAT("msp430f2350", "16bit")
+MSP430_MCU_FEAT("msp430f2370", "16bit")
+MSP430_MCU_FEAT("msp430f233", "16bit")
+MSP430_MCU_FEAT("msp430f235", "16bit")
+MSP430_MCU_FEAT("msp430f247", "16bit")
+MSP430_MCU_FEAT("msp430f248", "16bit")
+MSP430_MCU_FEAT("msp430f249", "16bit")
+MSP430_MCU_FEAT("msp430f2410", "16bit")
+MSP430_MCU_FEAT("msp430f2471", "16bit")
+MSP430_MCU_FEAT("msp430f2481", "16bit")
+MSP430_MCU_FEAT("msp430f2491", "16bit")
+MSP430_MCU_FEAT("msp430i2020", "16bit")
+MSP430_MCU_FEAT("msp430i2021", "16bit")
+MSP430_MCU_FEAT("msp430i2030", "16bit")
+MSP430_MCU_FEAT("msp430i2031", "16bit")
+MSP430_MCU_FEAT("msp430i2040", "16bit")
+MSP430_MCU_FEAT("msp430i2041", "16bit")
+MSP430_MCU_FEAT("msp430afe221", "16bit")
+MSP430_MCU_FEAT("msp430afe231", "16bit")
+MSP430_MCU_FEAT("msp430afe251", "16bit")
+MSP430_MCU_FEAT("msp430afe222", "16bit")
+MSP430_MCU_FEAT("msp430afe232", "16bit")
+MSP430_MCU_FEAT("msp430afe252", "16bit")
+MSP430_MCU_FEAT("msp430afe223", "16bit")
+MSP430_MCU_FEAT("msp430afe233", "16bit")
+MSP430_MCU_FEAT("msp430afe253", "16bit")
+
+// With 32 Bit Hardware Multiplier
+MSP430_MCU_FEAT("msp430f4783", "32bit")
+MSP430_MCU_FEAT("msp430f4793", "32bit")
+MSP430_MCU_FEAT("msp430f4784", "32bit")
+MSP430_MCU_FEAT("msp430f4794", "32bit")
+
+// Generic MSUs
+MSP430_MCU("msp430")
+MSP430_MCU("msp430i2xxgeneric")
+
+#undef MSP430_MCU
+#undef MSP430_MCU_FEAT
diff --git a/include/clang/Basic/ObjCRuntime.h b/include/clang/Basic/ObjCRuntime.h
index c307c9643390..fcfbe56b496f 100644
--- a/include/clang/Basic/ObjCRuntime.h
+++ b/include/clang/Basic/ObjCRuntime.h
@@ -173,6 +173,80 @@ public:
llvm_unreachable("bad kind");
}
+ /// Does this runtime provide ARC entrypoints that are likely to be faster
+ /// than an ordinary message send of the appropriate selector?
+ ///
+ /// The ARC entrypoints are guaranteed to be equivalent to just sending the
+ /// corresponding message. If the entrypoint is implemented naively as just a
+ /// message send, using it is a trade-off: it sacrifices a few cycles of
+ /// overhead to save a small amount of code. However, it's possible for
+ /// runtimes to detect and special-case classes that use "standard"
+ /// retain/release behavior; if that's dynamically a large proportion of all
+ /// retained objects, using the entrypoint will also be faster than using a
+ /// message send.
+ ///
+ /// When this method returns true, Clang will turn non-super message sends of
+ /// certain selectors into calls to the correspond entrypoint:
+ /// retain => objc_retain
+ /// release => objc_release
+ /// autorelease => objc_autorelease
+ bool shouldUseARCFunctionsForRetainRelease() const {
+ switch (getKind()) {
+ case FragileMacOSX:
+ return false;
+ case MacOSX:
+ return getVersion() >= VersionTuple(10, 10);
+ case iOS:
+ return getVersion() >= VersionTuple(8);
+ case WatchOS:
+ return true;
+ case GCC:
+ return false;
+ case GNUstep:
+ return false;
+ case ObjFW:
+ return false;
+ }
+ llvm_unreachable("bad kind");
+ }
+
+ /// Does this runtime provide entrypoints that are likely to be faster
+ /// than an ordinary message send of the "alloc" selector?
+ ///
+ /// The "alloc" entrypoint is guaranteed to be equivalent to just sending the
+ /// corresponding message. If the entrypoint is implemented naively as just a
+ /// message send, using it is a trade-off: it sacrifices a few cycles of
+ /// overhead to save a small amount of code. However, it's possible for
+ /// runtimes to detect and special-case classes that use "standard"
+ /// alloc behavior; if that's dynamically a large proportion of all
+ /// objects, using the entrypoint will also be faster than using a message
+ /// send.
+ ///
+ /// When this method returns true, Clang will turn non-super message sends of
+ /// certain selectors into calls to the corresponding entrypoint:
+ /// alloc => objc_alloc
+ /// allocWithZone:nil => objc_allocWithZone
+ bool shouldUseRuntimeFunctionsForAlloc() const {
+ switch (getKind()) {
+ case FragileMacOSX:
+ return false;
+ case MacOSX:
+ return getVersion() >= VersionTuple(10, 10);
+ case iOS:
+ return getVersion() >= VersionTuple(8);
+ case WatchOS:
+ return true;
+
+ case GCC:
+ return false;
+ case GNUstep:
+ return false;
+ case ObjFW:
+ return false;
+ }
+ llvm_unreachable("bad kind");
+ }
+
/// Does this runtime supports optimized setter entrypoints?
bool hasOptimizedSetter() const {
switch (getKind()) {
diff --git a/include/clang/Basic/OpenCLExtensionTypes.def b/include/clang/Basic/OpenCLExtensionTypes.def
new file mode 100644
index 000000000000..b72f7efd6f28
--- /dev/null
+++ b/include/clang/Basic/OpenCLExtensionTypes.def
@@ -0,0 +1,41 @@
+//===-- OpenCLExtensionTypes.def - Metadata about BuiltinTypes ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// This file extends builtin types database with OpenCL extension types.
+// Custom code should define this macro:
+// EXT_OPAQUE_TYPE(Name, Id, Ext)
+
+#ifdef EXT_OPAQUE_TYPE
+
+#ifndef INTEL_SUBGROUP_AVC_TYPE
+#define INTEL_SUBGROUP_AVC_TYPE(Name, Id) \
+ EXT_OPAQUE_TYPE(intel_sub_group_avc_##Name, OCLIntelSubgroupAVC##Id, \
+ cl_intel_device_side_avc_motion_estimation)
+#endif
+
+#endif
+
+#ifdef INTEL_SUBGROUP_AVC_TYPE
+INTEL_SUBGROUP_AVC_TYPE(mce_payload_t, McePayload)
+INTEL_SUBGROUP_AVC_TYPE(ime_payload_t, ImePayload)
+INTEL_SUBGROUP_AVC_TYPE(ref_payload_t, RefPayload)
+INTEL_SUBGROUP_AVC_TYPE(sic_payload_t, SicPayload)
+INTEL_SUBGROUP_AVC_TYPE(mce_result_t, MceResult)
+INTEL_SUBGROUP_AVC_TYPE(ime_result_t, ImeResult)
+INTEL_SUBGROUP_AVC_TYPE(ref_result_t, RefResult)
+INTEL_SUBGROUP_AVC_TYPE(sic_result_t, SicResult)
+INTEL_SUBGROUP_AVC_TYPE(ime_result_single_reference_streamout_t, ImeResultSingleRefStreamout)
+INTEL_SUBGROUP_AVC_TYPE(ime_result_dual_reference_streamout_t, ImeResultDualRefStreamout)
+INTEL_SUBGROUP_AVC_TYPE(ime_single_reference_streamin_t, ImeSingleRefStreamin)
+INTEL_SUBGROUP_AVC_TYPE(ime_dual_reference_streamin_t, ImeDualRefStreamin)
+
+#undef INTEL_SUBGROUP_AVC_TYPE
+#endif // INTEL_SUBGROUP_AVC_TYPE
+
+#undef EXT_OPAQUE_TYPE
+
diff --git a/include/clang/Basic/OpenCLExtensions.def b/include/clang/Basic/OpenCLExtensions.def
index 13cb12e7c581..5e7d2cb473c7 100644
--- a/include/clang/Basic/OpenCLExtensions.def
+++ b/include/clang/Basic/OpenCLExtensions.def
@@ -85,6 +85,7 @@ OPENCLEXT_INTERNAL(cl_amd_media_ops2, 100, ~0U)
// Intel OpenCL extensions
OPENCLEXT_INTERNAL(cl_intel_subgroups, 120, ~0U)
OPENCLEXT_INTERNAL(cl_intel_subgroups_short, 120, ~0U)
+OPENCLEXT_INTERNAL(cl_intel_device_side_avc_motion_estimation, 120, ~0U)
#undef OPENCLEXT_INTERNAL
diff --git a/include/clang/Basic/OpenMPKinds.def b/include/clang/Basic/OpenMPKinds.def
index 4ed7053b679b..f86721b1b07e 100644
--- a/include/clang/Basic/OpenMPKinds.def
+++ b/include/clang/Basic/OpenMPKinds.def
@@ -57,6 +57,9 @@
#ifndef OPENMP_TARGET_CLAUSE
# define OPENMP_TARGET_CLAUSE(Name)
#endif
+#ifndef OPENMP_REQUIRES_CLAUSE
+# define OPENMP_REQUIRES_CLAUSE(Name)
+#endif
#ifndef OPENMP_TARGET_DATA_CLAUSE
# define OPENMP_TARGET_DATA_CLAUSE(Name)
#endif
@@ -117,12 +120,18 @@
#ifndef OPENMP_MAP_KIND
#define OPENMP_MAP_KIND(Name)
#endif
+#ifndef OPENMP_MAP_MODIFIER_KIND
+#define OPENMP_MAP_MODIFIER_KIND(Name)
+#endif
#ifndef OPENMP_DIST_SCHEDULE_KIND
#define OPENMP_DIST_SCHEDULE_KIND(Name)
#endif
#ifndef OPENMP_DEFAULTMAP_KIND
#define OPENMP_DEFAULTMAP_KIND(Name)
#endif
+#ifndef OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND
+#define OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(Name)
+#endif
#ifndef OPENMP_DEFAULTMAP_MODIFIER
#define OPENMP_DEFAULTMAP_MODIFIER(Name)
#endif
@@ -193,6 +202,7 @@ OPENMP_DIRECTIVE(atomic)
OPENMP_DIRECTIVE(target)
OPENMP_DIRECTIVE(teams)
OPENMP_DIRECTIVE(cancel)
+OPENMP_DIRECTIVE(requires)
OPENMP_DIRECTIVE_EXT(target_data, "target data")
OPENMP_DIRECTIVE_EXT(target_enter_data, "target enter data")
OPENMP_DIRECTIVE_EXT(target_exit_data, "target exit data")
@@ -275,6 +285,11 @@ OPENMP_CLAUSE(use_device_ptr, OMPUseDevicePtrClause)
OPENMP_CLAUSE(is_device_ptr, OMPIsDevicePtrClause)
OPENMP_CLAUSE(task_reduction, OMPTaskReductionClause)
OPENMP_CLAUSE(in_reduction, OMPInReductionClause)
+OPENMP_CLAUSE(unified_address, OMPUnifiedAddressClause)
+OPENMP_CLAUSE(unified_shared_memory, OMPUnifiedSharedMemoryClause)
+OPENMP_CLAUSE(reverse_offload, OMPReverseOffloadClause)
+OPENMP_CLAUSE(dynamic_allocators, OMPDynamicAllocatorsClause)
+OPENMP_CLAUSE(atomic_default_mem_order, OMPAtomicDefaultMemOrderClause)
// Clauses allowed for OpenMP directive 'parallel'.
OPENMP_PARALLEL_CLAUSE(if)
@@ -456,6 +471,18 @@ OPENMP_TARGET_CLAUSE(firstprivate)
OPENMP_TARGET_CLAUSE(is_device_ptr)
OPENMP_TARGET_CLAUSE(reduction)
+// Clauses allowed for OpenMP directive 'requires'.
+OPENMP_REQUIRES_CLAUSE(unified_address)
+OPENMP_REQUIRES_CLAUSE(unified_shared_memory)
+OPENMP_REQUIRES_CLAUSE(reverse_offload)
+OPENMP_REQUIRES_CLAUSE(dynamic_allocators)
+OPENMP_REQUIRES_CLAUSE(atomic_default_mem_order)
+
+// Modifiers for 'atomic_default_mem_order' clause.
+OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(seq_cst)
+OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(acq_rel)
+OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(relaxed)
+
// Clauses allowed for OpenMP directive 'target data'.
OPENMP_TARGET_DATA_CLAUSE(if)
OPENMP_TARGET_DATA_CLAUSE(device)
@@ -535,14 +562,17 @@ OPENMP_ORDERED_CLAUSE(threads)
OPENMP_ORDERED_CLAUSE(simd)
OPENMP_ORDERED_CLAUSE(depend)
-// Map types and map type modifier for 'map' clause.
+// Map types for 'map' clause.
OPENMP_MAP_KIND(alloc)
OPENMP_MAP_KIND(to)
OPENMP_MAP_KIND(from)
OPENMP_MAP_KIND(tofrom)
OPENMP_MAP_KIND(delete)
OPENMP_MAP_KIND(release)
-OPENMP_MAP_KIND(always)
+
+// Map-type-modifiers for 'map' clause.
+OPENMP_MAP_MODIFIER_KIND(always)
+OPENMP_MAP_MODIFIER_KIND(close)
// Clauses allowed for OpenMP directive 'taskloop'.
OPENMP_TASKLOOP_CLAUSE(if)
@@ -883,6 +913,8 @@ OPENMP_TASKGROUP_CLAUSE(task_reduction)
#undef OPENMP_TASK_CLAUSE
#undef OPENMP_ATOMIC_CLAUSE
#undef OPENMP_TARGET_CLAUSE
+#undef OPENMP_REQUIRES_CLAUSE
+#undef OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND
#undef OPENMP_TARGET_DATA_CLAUSE
#undef OPENMP_TARGET_ENTER_DATA_CLAUSE
#undef OPENMP_TARGET_EXIT_DATA_CLAUSE
@@ -893,6 +925,7 @@ OPENMP_TASKGROUP_CLAUSE(task_reduction)
#undef OPENMP_FOR_CLAUSE
#undef OPENMP_FOR_SIMD_CLAUSE
#undef OPENMP_MAP_KIND
+#undef OPENMP_MAP_MODIFIER_KIND
#undef OPENMP_DISTRIBUTE_CLAUSE
#undef OPENMP_DIST_SCHEDULE_KIND
#undef OPENMP_DEFAULTMAP_KIND
diff --git a/include/clang/Basic/OpenMPKinds.h b/include/clang/Basic/OpenMPKinds.h
index c47973e53a8a..3e03a48cf68e 100644
--- a/include/clang/Basic/OpenMPKinds.h
+++ b/include/clang/Basic/OpenMPKinds.h
@@ -96,6 +96,15 @@ enum OpenMPMapClauseKind {
OMPC_MAP_unknown
};
+/// OpenMP modifier kind for 'map' clause.
+enum OpenMPMapModifierKind {
+ OMPC_MAP_MODIFIER_unknown = OMPC_MAP_unknown,
+#define OPENMP_MAP_MODIFIER_KIND(Name) \
+ OMPC_MAP_MODIFIER_##Name,
+#include "clang/Basic/OpenMPKinds.def"
+ OMPC_MAP_MODIFIER_last
+};
+
/// OpenMP attributes for 'dist_schedule' clause.
enum OpenMPDistScheduleClauseKind {
#define OPENMP_DIST_SCHEDULE_KIND(Name) OMPC_DIST_SCHEDULE_##Name,
@@ -120,6 +129,14 @@ enum OpenMPDefaultmapClauseModifier {
OMPC_DEFAULTMAP_MODIFIER_last
};
+/// OpenMP attributes for 'atomic_default_mem_order' clause.
+enum OpenMPAtomicDefaultMemOrderClauseKind {
+#define OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(Name) \
+ OMPC_ATOMIC_DEFAULT_MEM_ORDER_##Name,
+#include "clang/Basic/OpenMPKinds.def"
+ OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown
+};
+
/// Scheduling data for loop-based OpenMP directives.
struct OpenMPScheduleTy final {
OpenMPScheduleClauseKind Schedule = OMPC_SCHEDULE_unknown;
diff --git a/include/clang/Basic/PlistSupport.h b/include/clang/Basic/PlistSupport.h
index be92bbfde185..e41c24737798 100644
--- a/include/clang/Basic/PlistSupport.h
+++ b/include/clang/Basic/PlistSupport.h
@@ -25,24 +25,35 @@ namespace markup {
using FIDMap = llvm::DenseMap<FileID, unsigned>;
-inline void AddFID(FIDMap &FIDs, SmallVectorImpl<FileID> &V,
- const SourceManager &SM, SourceLocation L) {
- FileID FID = SM.getFileID(SM.getExpansionLoc(L));
+inline unsigned AddFID(FIDMap &FIDs, SmallVectorImpl<FileID> &V,
+ FileID FID) {
FIDMap::iterator I = FIDs.find(FID);
if (I != FIDs.end())
- return;
- FIDs[FID] = V.size();
+ return I->second;
+ unsigned NewValue = V.size();
+ FIDs[FID] = NewValue;
V.push_back(FID);
+ return NewValue;
}
-inline unsigned GetFID(const FIDMap &FIDs, const SourceManager &SM,
- SourceLocation L) {
+inline unsigned AddFID(FIDMap &FIDs, SmallVectorImpl<FileID> &V,
+ const SourceManager &SM, SourceLocation L) {
FileID FID = SM.getFileID(SM.getExpansionLoc(L));
+ return AddFID(FIDs, V, FID);
+}
+
+inline unsigned GetFID(const FIDMap &FIDs, FileID FID) {
FIDMap::const_iterator I = FIDs.find(FID);
assert(I != FIDs.end());
return I->second;
}
+inline unsigned GetFID(const FIDMap &FIDs, const SourceManager &SM,
+ SourceLocation L) {
+ FileID FID = SM.getFileID(SM.getExpansionLoc(L));
+ return GetFID(FIDs, FID);
+}
+
inline raw_ostream &Indent(raw_ostream &o, const unsigned indent) {
for (unsigned i = 0; i < indent; ++i)
o << ' ';
diff --git a/include/clang/Basic/Sanitizers.def b/include/clang/Basic/Sanitizers.def
index ae5c75fc5bbd..0287468d71f5 100644
--- a/include/clang/Basic/Sanitizers.def
+++ b/include/clang/Basic/Sanitizers.def
@@ -53,6 +53,9 @@ SANITIZER("kernel-hwaddress", KernelHWAddress)
// MemorySanitizer
SANITIZER("memory", Memory)
+// Kernel MemorySanitizer (KMSAN)
+SANITIZER("kernel-memory", KernelMemory)
+
// libFuzzer
SANITIZER("fuzzer", Fuzzer)
@@ -132,12 +135,32 @@ SANITIZER_GROUP("undefined", Undefined,
SANITIZER_GROUP("undefined-trap", UndefinedTrap, Undefined)
// ImplicitConversionSanitizer
-SANITIZER("implicit-integer-truncation", ImplicitIntegerTruncation)
+SANITIZER("implicit-unsigned-integer-truncation",
+ ImplicitUnsignedIntegerTruncation)
+SANITIZER("implicit-signed-integer-truncation", ImplicitSignedIntegerTruncation)
+SANITIZER_GROUP("implicit-integer-truncation", ImplicitIntegerTruncation,
+ ImplicitUnsignedIntegerTruncation |
+ ImplicitSignedIntegerTruncation)
+
+SANITIZER("implicit-integer-sign-change", ImplicitIntegerSignChange)
+
+SANITIZER_GROUP("implicit-integer-arithmetic-value-change",
+ ImplicitIntegerArithmeticValueChange,
+ ImplicitIntegerSignChange | ImplicitSignedIntegerTruncation)
+
+// FIXME:
+//SANITIZER_GROUP("implicit-integer-conversion", ImplicitIntegerConversion,
+// ImplicitIntegerArithmeticValueChange |
+// ImplicitUnsignedIntegerTruncation)
+//SANITIZER_GROUP("implicit-conversion", ImplicitConversion,
+// ImplicitIntegerConversion)
+
SANITIZER_GROUP("implicit-conversion", ImplicitConversion,
- ImplicitIntegerTruncation)
+ ImplicitIntegerArithmeticValueChange |
+ ImplicitUnsignedIntegerTruncation)
SANITIZER_GROUP("integer", Integer,
- ImplicitIntegerTruncation | IntegerDivideByZero | Shift |
+ ImplicitConversion | IntegerDivideByZero | Shift |
SignedIntegerOverflow | UnsignedIntegerOverflow)
SANITIZER("local-bounds", LocalBounds)
diff --git a/include/clang/Basic/Sanitizers.h b/include/clang/Basic/Sanitizers.h
index 2ecbde821599..fe9e76a1e325 100644
--- a/include/clang/Basic/Sanitizers.h
+++ b/include/clang/Basic/Sanitizers.h
@@ -66,7 +66,7 @@ struct SanitizerSet {
/// Disable the sanitizers specified in \p K.
void clear(SanitizerMask K = SanitizerKind::All) { Mask &= ~K; }
- /// Returns true if at least one sanitizer is enabled.
+ /// Returns true if no sanitizers are enabled.
bool empty() const { return Mask == 0; }
/// Bitmask of enabled sanitizers.
diff --git a/include/clang/Basic/SourceLocation.h b/include/clang/Basic/SourceLocation.h
index 488a604a452f..014bdc3f3f0b 100644
--- a/include/clang/Basic/SourceLocation.h
+++ b/include/clang/Basic/SourceLocation.h
@@ -220,6 +220,10 @@ public:
bool operator!=(const SourceRange &X) const {
return B != X.B || E != X.E;
}
+
+ void print(raw_ostream &OS, const SourceManager &SM) const;
+ std::string printToString(const SourceManager &SM) const;
+ void dump(const SourceManager &SM) const;
};
/// Represents a character-granular source range.
diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h
index af7dbbc13ca7..dcc4a37e239c 100644
--- a/include/clang/Basic/SourceManager.h
+++ b/include/clang/Basic/SourceManager.h
@@ -449,7 +449,7 @@ namespace SrcMgr {
}
static SLocEntry get(unsigned Offset, const FileInfo &FI) {
- assert(!(Offset & (1 << 31)) && "Offset is too large");
+ assert(!(Offset & (1u << 31)) && "Offset is too large");
SLocEntry E;
E.Offset = Offset;
E.IsExpansion = false;
@@ -458,7 +458,7 @@ namespace SrcMgr {
}
static SLocEntry get(unsigned Offset, const ExpansionInfo &Expansion) {
- assert(!(Offset & (1 << 31)) && "Offset is too large");
+ assert(!(Offset & (1u << 31)) && "Offset is too large");
SLocEntry E;
E.Offset = Offset;
E.IsExpansion = true;
@@ -1024,13 +1024,14 @@ public:
/// Set the number of FileIDs (files and macros) that were created
/// during preprocessing of \p FID, including it.
- void setNumCreatedFIDsForFileID(FileID FID, unsigned NumFIDs) const {
+ void setNumCreatedFIDsForFileID(FileID FID, unsigned NumFIDs,
+ bool Force = false) const {
bool Invalid = false;
const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid);
if (Invalid || !Entry.isFile())
return;
- assert(Entry.getFile().NumCreatedFIDs == 0 && "Already set!");
+ assert((Force || Entry.getFile().NumCreatedFIDs == 0) && "Already set!");
const_cast<SrcMgr::FileInfo &>(Entry.getFile()).NumCreatedFIDs = NumFIDs;
}
@@ -1428,6 +1429,18 @@ public:
return getFileID(Loc) == getMainFileID();
}
+ /// Returns whether \p Loc is located in a <built-in> file.
+ bool isWrittenInBuiltinFile(SourceLocation Loc) const {
+ StringRef Filename(getPresumedLoc(Loc).getFilename());
+ return Filename.equals("<built-in>");
+ }
+
+ /// Returns whether \p Loc is located in a <command line> file.
+ bool isWrittenInCommandLineFile(SourceLocation Loc) const {
+ StringRef Filename(getPresumedLoc(Loc).getFilename());
+ return Filename.equals("<command line>");
+ }
+
/// Returns if a SourceLocation is in a system header.
bool isInSystemHeader(SourceLocation Loc) const {
return isSystem(getFileCharacteristic(Loc));
diff --git a/include/clang/Basic/Specifiers.h b/include/clang/Basic/Specifiers.h
index cd8213f6cfd4..0af01e45437d 100644
--- a/include/clang/Basic/Specifiers.h
+++ b/include/clang/Basic/Specifiers.h
@@ -251,6 +251,7 @@ namespace clang {
CC_Swift, // __attribute__((swiftcall))
CC_PreserveMost, // __attribute__((preserve_most))
CC_PreserveAll, // __attribute__((preserve_all))
+ CC_AArch64VectorCall, // __attribute__((aarch64_vector_pcs))
};
/// Checks whether the given calling convention supports variadic
diff --git a/include/clang/Basic/StmtNodes.td b/include/clang/Basic/StmtNodes.td
index 1517d741cb3c..9054fb11a6ff 100644
--- a/include/clang/Basic/StmtNodes.td
+++ b/include/clang/Basic/StmtNodes.td
@@ -93,6 +93,10 @@ def VAArgExpr : DStmt<Expr>;
def GenericSelectionExpr : DStmt<Expr>;
def PseudoObjectExpr : DStmt<Expr>;
+// Wrapper expressions
+def FullExpr : DStmt<Expr, 1>;
+def ConstantExpr : DStmt<FullExpr>;
+
// Atomic expressions
def AtomicExpr : DStmt<Expr>;
@@ -131,7 +135,7 @@ def DependentScopeDeclRefExpr : DStmt<Expr>;
def CXXConstructExpr : DStmt<Expr>;
def CXXInheritedCtorInitExpr : DStmt<Expr>;
def CXXBindTemporaryExpr : DStmt<Expr>;
-def ExprWithCleanups : DStmt<Expr>;
+def ExprWithCleanups : DStmt<FullExpr>;
def CXXTemporaryObjectExpr : DStmt<CXXConstructExpr>;
def CXXUnresolvedConstructExpr : DStmt<Expr>;
def CXXDependentScopeMemberExpr : DStmt<Expr>;
diff --git a/include/clang/Basic/TargetBuiltins.h b/include/clang/Basic/TargetBuiltins.h
index 75a3811007cc..ab4b1c43f7cf 100644
--- a/include/clang/Basic/TargetBuiltins.h
+++ b/include/clang/Basic/TargetBuiltins.h
@@ -150,16 +150,6 @@ namespace clang {
};
}
- /// Nios2 builtins
- namespace Nios2 {
- enum {
- LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
-#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
-#include "clang/Basic/BuiltinsNios2.def"
- LastTSBuiltin
- };
- }
-
/// MIPS builtins
namespace Mips {
enum {
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
index 958b9106bc99..786b1c251ca8 100644
--- a/include/clang/Basic/TargetInfo.h
+++ b/include/clang/Basic/TargetInfo.h
@@ -312,6 +312,14 @@ public:
}
}
+ /// In the event this target uses the same number of fractional bits for its
+ /// unsigned types as it does with its signed counterparts, there will be
+ /// exactly one bit of padding.
+ /// Return true if unsigned fixed point types have padding for this target.
+ bool doUnsignedFixedPointTypesHavePadding() const {
+ return PaddingOnUnsignedFixedPoint;
+ }
+
/// Return the width (in bits) of the specified integer type enum.
///
/// For example, SignedInt -> getIntWidth().
@@ -1074,9 +1082,15 @@ public:
return false;
}
- /// Identify whether this taret supports multiversioning of functions,
+ /// Identify whether this target supports multiversioning of functions,
/// which requires support for cpu_supports and cpu_is functionality.
- virtual bool supportsMultiVersioning() const { return false; }
+ bool supportsMultiVersioning() const {
+ return getTriple().getArch() == llvm::Triple::x86 ||
+ getTriple().getArch() == llvm::Triple::x86_64;
+ }
+
+ /// Identify whether this target supports IFuncs.
+ bool supportsIFunc() const { return getTriple().isOSBinFormatELF(); }
// Validate the contents of the __builtin_cpu_supports(const char*)
// argument.
@@ -1168,6 +1182,18 @@ public:
const LangASMap &getAddressSpaceMap() const { return *AddrSpaceMap; }
+ /// Map from the address space field in builtin description strings to the
+ /// language address space.
+ virtual LangAS getOpenCLBuiltinAddressSpace(unsigned AS) const {
+ return getLangASFromTargetAS(AS);
+ }
+
+ /// Map from the address space field in builtin description strings to the
+ /// language address space.
+ virtual LangAS getCUDABuiltinAddressSpace(unsigned AS) const {
+ return getLangASFromTargetAS(AS);
+ }
+
/// Return an AST address space which can be used opportunistically
/// for constant global memory. It must be possible to convert pointers into
/// this address space to LangAS::Default. If no such address space exists,
@@ -1295,6 +1321,12 @@ public:
return None;
}
+ /// \returns The version of the SDK which was used during the compilation if
+ /// one was specified, or an empty version otherwise.
+ const llvm::VersionTuple &getSDKVersion() const {
+ return getTargetOpts().SDKVersion;
+ }
+
/// Check the target is valid after it is fully initialized.
virtual bool validateTarget(DiagnosticsEngine &Diags) const {
return true;
diff --git a/include/clang/Basic/TargetOptions.h b/include/clang/Basic/TargetOptions.h
index 31a674287915..fcccc5331a97 100644
--- a/include/clang/Basic/TargetOptions.h
+++ b/include/clang/Basic/TargetOptions.h
@@ -15,10 +15,11 @@
#ifndef LLVM_CLANG_BASIC_TARGETOPTIONS_H
#define LLVM_CLANG_BASIC_TARGETOPTIONS_H
-#include <string>
-#include <vector>
#include "clang/Basic/OpenCLOptions.h"
+#include "llvm/Support/VersionTuple.h"
#include "llvm/Target/TargetOptions.h"
+#include <string>
+#include <vector>
namespace clang {
@@ -67,6 +68,15 @@ public:
/// \brief If enabled, use 32-bit pointers for accessing const/local/shared
/// address space.
bool NVPTXUseShortPointers = false;
+
+ // The code model to be used as specified by the user. Corresponds to
+ // CodeModel::Model enum defined in include/llvm/Support/CodeGen.h, plus
+ // "default" for the case when the user has not explicitly specified a
+ // code model.
+ std::string CodeModel;
+
+ /// The version of the SDK which was used during the compilation.
+ llvm::VersionTuple SDKVersion;
};
} // end namespace clang
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
index 30cb022f1cba..e4616c9a6ab4 100644
--- a/include/clang/Basic/TokenKinds.def
+++ b/include/clang/Basic/TokenKinds.def
@@ -57,11 +57,8 @@
#ifndef CXX_KEYWORD_OPERATOR
#define CXX_KEYWORD_OPERATOR(X,Y)
#endif
-#ifndef OBJC1_AT_KEYWORD
-#define OBJC1_AT_KEYWORD(X)
-#endif
-#ifndef OBJC2_AT_KEYWORD
-#define OBJC2_AT_KEYWORD(X)
+#ifndef OBJC_AT_KEYWORD
+#define OBJC_AT_KEYWORD(X)
#endif
#ifndef TESTING_KEYWORD
#define TESTING_KEYWORD(X, L) KEYWORD(X, L)
@@ -579,15 +576,15 @@ ALIAS("__fp16", half , KEYALL)
KEYWORD(half , HALFSUPPORT)
// Objective-C ARC keywords.
-KEYWORD(__bridge , KEYARC)
-KEYWORD(__bridge_transfer , KEYARC)
-KEYWORD(__bridge_retained , KEYARC)
-KEYWORD(__bridge_retain , KEYARC)
+KEYWORD(__bridge , KEYOBJC)
+KEYWORD(__bridge_transfer , KEYOBJC)
+KEYWORD(__bridge_retained , KEYOBJC)
+KEYWORD(__bridge_retain , KEYOBJC)
// Objective-C keywords.
-KEYWORD(__covariant , KEYOBJC2)
-KEYWORD(__contravariant , KEYOBJC2)
-KEYWORD(__kindof , KEYOBJC2)
+KEYWORD(__covariant , KEYOBJC)
+KEYWORD(__contravariant , KEYOBJC)
+KEYWORD(__kindof , KEYOBJC)
// Alternate spelling for various tokens. There are GCC extensions in all
// languages, but should not be disabled in strict conformance mode.
@@ -677,34 +674,34 @@ TESTING_KEYWORD(__unknown_anytype , KEYALL)
// These have meaning after an '@' in Objective-C mode. These define enums in
// the tok::objc_* namespace.
-OBJC1_AT_KEYWORD(not_keyword)
-OBJC1_AT_KEYWORD(class)
-OBJC1_AT_KEYWORD(compatibility_alias)
-OBJC1_AT_KEYWORD(defs)
-OBJC1_AT_KEYWORD(encode)
-OBJC1_AT_KEYWORD(end)
-OBJC1_AT_KEYWORD(implementation)
-OBJC1_AT_KEYWORD(interface)
-OBJC1_AT_KEYWORD(private)
-OBJC1_AT_KEYWORD(protected)
-OBJC1_AT_KEYWORD(protocol)
-OBJC1_AT_KEYWORD(public)
-OBJC1_AT_KEYWORD(selector)
-OBJC1_AT_KEYWORD(throw)
-OBJC1_AT_KEYWORD(try)
-OBJC1_AT_KEYWORD(catch)
-OBJC1_AT_KEYWORD(finally)
-OBJC1_AT_KEYWORD(synchronized)
-OBJC1_AT_KEYWORD(autoreleasepool)
-
-OBJC2_AT_KEYWORD(property)
-OBJC2_AT_KEYWORD(package)
-OBJC2_AT_KEYWORD(required)
-OBJC2_AT_KEYWORD(optional)
-OBJC2_AT_KEYWORD(synthesize)
-OBJC2_AT_KEYWORD(dynamic)
-OBJC2_AT_KEYWORD(import)
-OBJC2_AT_KEYWORD(available)
+OBJC_AT_KEYWORD(not_keyword)
+OBJC_AT_KEYWORD(class)
+OBJC_AT_KEYWORD(compatibility_alias)
+OBJC_AT_KEYWORD(defs)
+OBJC_AT_KEYWORD(encode)
+OBJC_AT_KEYWORD(end)
+OBJC_AT_KEYWORD(implementation)
+OBJC_AT_KEYWORD(interface)
+OBJC_AT_KEYWORD(private)
+OBJC_AT_KEYWORD(protected)
+OBJC_AT_KEYWORD(protocol)
+OBJC_AT_KEYWORD(public)
+OBJC_AT_KEYWORD(selector)
+OBJC_AT_KEYWORD(throw)
+OBJC_AT_KEYWORD(try)
+OBJC_AT_KEYWORD(catch)
+OBJC_AT_KEYWORD(finally)
+OBJC_AT_KEYWORD(synchronized)
+OBJC_AT_KEYWORD(autoreleasepool)
+
+OBJC_AT_KEYWORD(property)
+OBJC_AT_KEYWORD(package)
+OBJC_AT_KEYWORD(required)
+OBJC_AT_KEYWORD(optional)
+OBJC_AT_KEYWORD(synthesize)
+OBJC_AT_KEYWORD(dynamic)
+OBJC_AT_KEYWORD(import)
+OBJC_AT_KEYWORD(available)
// TODO: What to do about context-sensitive keywords like:
// bycopy/byref/in/inout/oneway/out?
@@ -780,6 +777,11 @@ ANNOTATION(pragma_redefine_extname)
// handles them.
ANNOTATION(pragma_fp_contract)
+// Annotation for #pragma STDC FENV_ACCESS
+// The lexer produces these so that they only take effect when the parser
+// handles them.
+ANNOTATION(pragma_fenv_access)
+
// Annotation for #pragma pointers_to_members...
// The lexer produces these so that they only take effect when the parser
// handles them.
@@ -823,8 +825,7 @@ ANNOTATION(module_end)
#undef ANNOTATION
#undef TESTING_KEYWORD
-#undef OBJC2_AT_KEYWORD
-#undef OBJC1_AT_KEYWORD
+#undef OBJC_AT_KEYWORD
#undef CXX_KEYWORD_OPERATOR
#undef PPKEYWORD
#undef ALIAS
diff --git a/include/clang/Basic/TokenKinds.h b/include/clang/Basic/TokenKinds.h
index fb4b5252b70b..e046f0027044 100644
--- a/include/clang/Basic/TokenKinds.h
+++ b/include/clang/Basic/TokenKinds.h
@@ -39,8 +39,7 @@ enum PPKeywordKind {
/// Provides a namespace for Objective-C keywords which start with
/// an '@'.
enum ObjCKeywordKind {
-#define OBJC1_AT_KEYWORD(X) objc_##X,
-#define OBJC2_AT_KEYWORD(X) objc_##X,
+#define OBJC_AT_KEYWORD(X) objc_##X,
#include "clang/Basic/TokenKinds.def"
NUM_OBJC_KEYWORDS
};
diff --git a/include/clang/Basic/TypeTraits.h b/include/clang/Basic/TypeTraits.h
index bdb426834a8c..8b8b2cbbd4a7 100644
--- a/include/clang/Basic/TypeTraits.h
+++ b/include/clang/Basic/TypeTraits.h
@@ -96,9 +96,15 @@ namespace clang {
/// Names for the "expression or type" traits.
enum UnaryExprOrTypeTrait {
UETT_SizeOf,
+ /// Used for C's _Alignof and C++'s alignof.
+ /// _Alignof and alignof return the required ABI alignment.
UETT_AlignOf,
UETT_VecStep,
UETT_OpenMPRequiredSimdAlign,
+ /// Used for GCC's __alignof.
+ /// __alignof returns the preferred alignment of a type, the alignment
+ /// clang will attempt to give an object of the type if allowed by ABI.
+ UETT_PreferredAlignOf,
};
}
diff --git a/include/clang/Basic/VirtualFileSystem.h b/include/clang/Basic/VirtualFileSystem.h
deleted file mode 100644
index 2480b91123c1..000000000000
--- a/include/clang/Basic/VirtualFileSystem.h
+++ /dev/null
@@ -1,454 +0,0 @@
-//===- VirtualFileSystem.h - Virtual File System Layer ----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-/// \file
-/// Defines the virtual file system interface vfs::FileSystem.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_VIRTUALFILESYSTEM_H
-#define LLVM_CLANG_BASIC_VIRTUALFILESYSTEM_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/None.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Twine.h"
-#include "llvm/Support/Chrono.h"
-#include "llvm/Support/ErrorOr.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/SourceMgr.h"
-#include <cassert>
-#include <cstdint>
-#include <ctime>
-#include <memory>
-#include <stack>
-#include <string>
-#include <system_error>
-#include <utility>
-#include <vector>
-
-namespace llvm {
-
-class MemoryBuffer;
-
-} // namespace llvm
-
-namespace clang {
-namespace vfs {
-
-/// The result of a \p status operation.
-class Status {
- std::string Name;
- llvm::sys::fs::UniqueID UID;
- llvm::sys::TimePoint<> MTime;
- uint32_t User;
- uint32_t Group;
- uint64_t Size;
- llvm::sys::fs::file_type Type = llvm::sys::fs::file_type::status_error;
- llvm::sys::fs::perms Perms;
-
-public:
- // FIXME: remove when files support multiple names
- bool IsVFSMapped = false;
-
- Status() = default;
- Status(const llvm::sys::fs::file_status &Status);
- Status(StringRef Name, llvm::sys::fs::UniqueID UID,
- llvm::sys::TimePoint<> MTime, uint32_t User, uint32_t Group,
- uint64_t Size, llvm::sys::fs::file_type Type,
- llvm::sys::fs::perms Perms);
-
- /// Get a copy of a Status with a different name.
- static Status copyWithNewName(const Status &In, StringRef NewName);
- static Status copyWithNewName(const llvm::sys::fs::file_status &In,
- StringRef NewName);
-
- /// Returns the name that should be used for this file or directory.
- StringRef getName() const { return Name; }
-
- /// @name Status interface from llvm::sys::fs
- /// @{
- llvm::sys::fs::file_type getType() const { return Type; }
- llvm::sys::fs::perms getPermissions() const { return Perms; }
- llvm::sys::TimePoint<> getLastModificationTime() const { return MTime; }
- llvm::sys::fs::UniqueID getUniqueID() const { return UID; }
- uint32_t getUser() const { return User; }
- uint32_t getGroup() const { return Group; }
- uint64_t getSize() const { return Size; }
- /// @}
- /// @name Status queries
- /// These are static queries in llvm::sys::fs.
- /// @{
- bool equivalent(const Status &Other) const;
- bool isDirectory() const;
- bool isRegularFile() const;
- bool isOther() const;
- bool isSymlink() const;
- bool isStatusKnown() const;
- bool exists() const;
- /// @}
-};
-
-/// Represents an open file.
-class File {
-public:
- /// Destroy the file after closing it (if open).
- /// Sub-classes should generally call close() inside their destructors. We
- /// cannot do that from the base class, since close is virtual.
- virtual ~File();
-
- /// Get the status of the file.
- virtual llvm::ErrorOr<Status> status() = 0;
-
- /// Get the name of the file
- virtual llvm::ErrorOr<std::string> getName() {
- if (auto Status = status())
- return Status->getName().str();
- else
- return Status.getError();
- }
-
- /// Get the contents of the file as a \p MemoryBuffer.
- virtual llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
- getBuffer(const Twine &Name, int64_t FileSize = -1,
- bool RequiresNullTerminator = true, bool IsVolatile = false) = 0;
-
- /// Closes the file.
- virtual std::error_code close() = 0;
-};
-
-namespace detail {
-
-/// An interface for virtual file systems to provide an iterator over the
-/// (non-recursive) contents of a directory.
-struct DirIterImpl {
- virtual ~DirIterImpl();
-
- /// Sets \c CurrentEntry to the next entry in the directory on success,
- /// or returns a system-defined \c error_code.
- virtual std::error_code increment() = 0;
-
- Status CurrentEntry;
-};
-
-} // namespace detail
-
-/// An input iterator over the entries in a virtual path, similar to
-/// llvm::sys::fs::directory_iterator.
-class directory_iterator {
- std::shared_ptr<detail::DirIterImpl> Impl; // Input iterator semantics on copy
-
-public:
- directory_iterator(std::shared_ptr<detail::DirIterImpl> I)
- : Impl(std::move(I)) {
- assert(Impl.get() != nullptr && "requires non-null implementation");
- if (!Impl->CurrentEntry.isStatusKnown())
- Impl.reset(); // Normalize the end iterator to Impl == nullptr.
- }
-
- /// Construct an 'end' iterator.
- directory_iterator() = default;
-
- /// Equivalent to operator++, with an error code.
- directory_iterator &increment(std::error_code &EC) {
- assert(Impl && "attempting to increment past end");
- EC = Impl->increment();
- if (!Impl->CurrentEntry.isStatusKnown())
- Impl.reset(); // Normalize the end iterator to Impl == nullptr.
- return *this;
- }
-
- const Status &operator*() const { return Impl->CurrentEntry; }
- const Status *operator->() const { return &Impl->CurrentEntry; }
-
- bool operator==(const directory_iterator &RHS) const {
- if (Impl && RHS.Impl)
- return Impl->CurrentEntry.equivalent(RHS.Impl->CurrentEntry);
- return !Impl && !RHS.Impl;
- }
- bool operator!=(const directory_iterator &RHS) const {
- return !(*this == RHS);
- }
-};
-
-class FileSystem;
-
-/// An input iterator over the recursive contents of a virtual path,
-/// similar to llvm::sys::fs::recursive_directory_iterator.
-class recursive_directory_iterator {
- using IterState =
- std::stack<directory_iterator, std::vector<directory_iterator>>;
-
- FileSystem *FS;
- std::shared_ptr<IterState> State; // Input iterator semantics on copy.
-
-public:
- recursive_directory_iterator(FileSystem &FS, const Twine &Path,
- std::error_code &EC);
-
- /// Construct an 'end' iterator.
- recursive_directory_iterator() = default;
-
- /// Equivalent to operator++, with an error code.
- recursive_directory_iterator &increment(std::error_code &EC);
-
- const Status &operator*() const { return *State->top(); }
- const Status *operator->() const { return &*State->top(); }
-
- bool operator==(const recursive_directory_iterator &Other) const {
- return State == Other.State; // identity
- }
- bool operator!=(const recursive_directory_iterator &RHS) const {
- return !(*this == RHS);
- }
-
- /// Gets the current level. Starting path is at level 0.
- int level() const {
- assert(!State->empty() && "Cannot get level without any iteration state");
- return State->size()-1;
- }
-};
-
-/// The virtual file system interface.
-class FileSystem : public llvm::ThreadSafeRefCountedBase<FileSystem> {
-public:
- virtual ~FileSystem();
-
- /// Get the status of the entry at \p Path, if one exists.
- virtual llvm::ErrorOr<Status> status(const Twine &Path) = 0;
-
- /// Get a \p File object for the file at \p Path, if one exists.
- virtual llvm::ErrorOr<std::unique_ptr<File>>
- openFileForRead(const Twine &Path) = 0;
-
- /// This is a convenience method that opens a file, gets its content and then
- /// closes the file.
- llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
- getBufferForFile(const Twine &Name, int64_t FileSize = -1,
- bool RequiresNullTerminator = true, bool IsVolatile = false);
-
- /// Get a directory_iterator for \p Dir.
- /// \note The 'end' iterator is directory_iterator().
- virtual directory_iterator dir_begin(const Twine &Dir,
- std::error_code &EC) = 0;
-
- /// Set the working directory. This will affect all following operations on
- /// this file system and may propagate down for nested file systems.
- virtual std::error_code setCurrentWorkingDirectory(const Twine &Path) = 0;
-
- /// Get the working directory of this file system.
- virtual llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const = 0;
-
- /// Gets real path of \p Path e.g. collapse all . and .. patterns, resolve
- /// symlinks. For real file system, this uses `llvm::sys::fs::real_path`.
- /// This returns errc::operation_not_permitted if not implemented by subclass.
- virtual std::error_code getRealPath(const Twine &Path,
- SmallVectorImpl<char> &Output) const;
-
- /// Check whether a file exists. Provided for convenience.
- bool exists(const Twine &Path);
-
- /// Make \a Path an absolute path.
- ///
- /// Makes \a Path absolute using the current directory if it is not already.
- /// An empty \a Path will result in the current directory.
- ///
- /// /absolute/path => /absolute/path
- /// relative/../path => <current-directory>/relative/../path
- ///
- /// \param Path A path that is modified to be an absolute path.
- /// \returns success if \a path has been made absolute, otherwise a
- /// platform-specific error_code.
- std::error_code makeAbsolute(SmallVectorImpl<char> &Path) const;
-};
-
-/// Gets an \p vfs::FileSystem for the 'real' file system, as seen by
-/// the operating system.
-IntrusiveRefCntPtr<FileSystem> getRealFileSystem();
-
-/// A file system that allows overlaying one \p AbstractFileSystem on top
-/// of another.
-///
-/// Consists of a stack of >=1 \p FileSystem objects, which are treated as being
-/// one merged file system. When there is a directory that exists in more than
-/// one file system, the \p OverlayFileSystem contains a directory containing
-/// the union of their contents. The attributes (permissions, etc.) of the
-/// top-most (most recently added) directory are used. When there is a file
-/// that exists in more than one file system, the file in the top-most file
-/// system overrides the other(s).
-class OverlayFileSystem : public FileSystem {
- using FileSystemList = SmallVector<IntrusiveRefCntPtr<FileSystem>, 1>;
-
- /// The stack of file systems, implemented as a list in order of
- /// their addition.
- FileSystemList FSList;
-
-public:
- OverlayFileSystem(IntrusiveRefCntPtr<FileSystem> Base);
-
- /// Pushes a file system on top of the stack.
- void pushOverlay(IntrusiveRefCntPtr<FileSystem> FS);
-
- llvm::ErrorOr<Status> status(const Twine &Path) override;
- llvm::ErrorOr<std::unique_ptr<File>>
- openFileForRead(const Twine &Path) override;
- directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override;
- llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const override;
- std::error_code setCurrentWorkingDirectory(const Twine &Path) override;
- std::error_code getRealPath(const Twine &Path,
- SmallVectorImpl<char> &Output) const override;
-
- using iterator = FileSystemList::reverse_iterator;
- using const_iterator = FileSystemList::const_reverse_iterator;
-
- /// Get an iterator pointing to the most recently added file system.
- iterator overlays_begin() { return FSList.rbegin(); }
- const_iterator overlays_begin() const { return FSList.rbegin(); }
-
- /// Get an iterator pointing one-past the least recently added file
- /// system.
- iterator overlays_end() { return FSList.rend(); }
- const_iterator overlays_end() const { return FSList.rend(); }
-};
-
-namespace detail {
-
-class InMemoryDirectory;
-
-} // namespace detail
-
-/// An in-memory file system.
-class InMemoryFileSystem : public FileSystem {
- std::unique_ptr<detail::InMemoryDirectory> Root;
- std::string WorkingDirectory;
- bool UseNormalizedPaths = true;
-
-public:
- explicit InMemoryFileSystem(bool UseNormalizedPaths = true);
- ~InMemoryFileSystem() override;
-
- /// Add a file containing a buffer or a directory to the VFS with a
- /// path. The VFS owns the buffer. If present, User, Group, Type
- /// and Perms apply to the newly-created file or directory.
- /// \return true if the file or directory was successfully added,
- /// false if the file or directory already exists in the file system with
- /// different contents.
- bool addFile(const Twine &Path, time_t ModificationTime,
- std::unique_ptr<llvm::MemoryBuffer> Buffer,
- Optional<uint32_t> User = None, Optional<uint32_t> Group = None,
- Optional<llvm::sys::fs::file_type> Type = None,
- Optional<llvm::sys::fs::perms> Perms = None);
-
- /// Add a buffer to the VFS with a path. The VFS does not own the buffer.
- /// If present, User, Group, Type and Perms apply to the newly-created file
- /// or directory.
- /// \return true if the file or directory was successfully added,
- /// false if the file or directory already exists in the file system with
- /// different contents.
- bool addFileNoOwn(const Twine &Path, time_t ModificationTime,
- llvm::MemoryBuffer *Buffer,
- Optional<uint32_t> User = None,
- Optional<uint32_t> Group = None,
- Optional<llvm::sys::fs::file_type> Type = None,
- Optional<llvm::sys::fs::perms> Perms = None);
-
- std::string toString() const;
-
- /// Return true if this file system normalizes . and .. in paths.
- bool useNormalizedPaths() const { return UseNormalizedPaths; }
-
- llvm::ErrorOr<Status> status(const Twine &Path) override;
- llvm::ErrorOr<std::unique_ptr<File>>
- openFileForRead(const Twine &Path) override;
- directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override;
-
- llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const override {
- return WorkingDirectory;
- }
- /// Canonicalizes \p Path by combining with the current working
- /// directory and normalizing the path (e.g. remove dots). If the current
- /// working directory is not set, this returns errc::operation_not_permitted.
- ///
- /// This doesn't resolve symlinks as they are not supported in in-memory file
- /// system.
- std::error_code getRealPath(const Twine &Path,
- SmallVectorImpl<char> &Output) const override;
-
- std::error_code setCurrentWorkingDirectory(const Twine &Path) override;
-};
-
-/// Get a globally unique ID for a virtual file or directory.
-llvm::sys::fs::UniqueID getNextVirtualUniqueID();
-
-/// Gets a \p FileSystem for a virtual file system described in YAML
-/// format.
-IntrusiveRefCntPtr<FileSystem>
-getVFSFromYAML(std::unique_ptr<llvm::MemoryBuffer> Buffer,
- llvm::SourceMgr::DiagHandlerTy DiagHandler,
- StringRef YAMLFilePath,
- void *DiagContext = nullptr,
- IntrusiveRefCntPtr<FileSystem> ExternalFS = getRealFileSystem());
-
-struct YAMLVFSEntry {
- template <typename T1, typename T2> YAMLVFSEntry(T1 &&VPath, T2 &&RPath)
- : VPath(std::forward<T1>(VPath)), RPath(std::forward<T2>(RPath)) {}
- std::string VPath;
- std::string RPath;
-};
-
-/// Collect all pairs of <virtual path, real path> entries from the
-/// \p YAMLFilePath. This is used by the module dependency collector to forward
-/// the entries into the reproducer output VFS YAML file.
-void collectVFSFromYAML(
- std::unique_ptr<llvm::MemoryBuffer> Buffer,
- llvm::SourceMgr::DiagHandlerTy DiagHandler, StringRef YAMLFilePath,
- SmallVectorImpl<YAMLVFSEntry> &CollectedEntries,
- void *DiagContext = nullptr,
- IntrusiveRefCntPtr<FileSystem> ExternalFS = getRealFileSystem());
-
-class YAMLVFSWriter {
- std::vector<YAMLVFSEntry> Mappings;
- Optional<bool> IsCaseSensitive;
- Optional<bool> IsOverlayRelative;
- Optional<bool> UseExternalNames;
- Optional<bool> IgnoreNonExistentContents;
- std::string OverlayDir;
-
-public:
- YAMLVFSWriter() = default;
-
- void addFileMapping(StringRef VirtualPath, StringRef RealPath);
-
- void setCaseSensitivity(bool CaseSensitive) {
- IsCaseSensitive = CaseSensitive;
- }
-
- void setUseExternalNames(bool UseExtNames) {
- UseExternalNames = UseExtNames;
- }
-
- void setIgnoreNonExistentContents(bool IgnoreContents) {
- IgnoreNonExistentContents = IgnoreContents;
- }
-
- void setOverlayDir(StringRef OverlayDirectory) {
- IsOverlayRelative = true;
- OverlayDir.assign(OverlayDirectory.str());
- }
-
- void write(llvm::raw_ostream &OS);
-};
-
-} // namespace vfs
-} // namespace clang
-
-#endif // LLVM_CLANG_BASIC_VIRTUALFILESYSTEM_H
diff --git a/include/clang/Basic/X86Target.def b/include/clang/Basic/X86Target.def
index d2d2540e5005..8c203c4db21e 100644
--- a/include/clang/Basic/X86Target.def
+++ b/include/clang/Basic/X86Target.def
@@ -154,6 +154,10 @@ PROC_WITH_FEAT(SkylakeClient, "skylake", PROC_64_BIT, FEATURE_AVX2)
PROC_WITH_FEAT(SkylakeServer, "skylake-avx512", PROC_64_BIT, FEATURE_AVX512F)
PROC_ALIAS(SkylakeServer, "skx")
+/// \name Cascadelake Server
+/// Cascadelake Server microarchitecture based processors.
+PROC_WITH_FEAT(Cascadelake, "cascadelake", PROC_64_BIT, FEATURE_AVX512VNNI)
+
/// \name Cannonlake Client
/// Cannonlake client microarchitecture based processors.
PROC_WITH_FEAT(Cannonlake, "cannonlake", PROC_64_BIT, FEATURE_AVX512VBMI)
@@ -283,6 +287,11 @@ FEATURE(FEATURE_AVX512IFMA)
FEATURE(FEATURE_AVX5124VNNIW)
FEATURE(FEATURE_AVX5124FMAPS)
FEATURE(FEATURE_AVX512VPOPCNTDQ)
+FEATURE(FEATURE_AVX512VBMI2)
+FEATURE(FEATURE_GFNI)
+FEATURE(FEATURE_VPCLMULQDQ)
+FEATURE(FEATURE_AVX512VNNI)
+FEATURE(FEATURE_AVX512BITALG)
// FIXME: When commented out features are supported in LLVM, enable them here.
diff --git a/include/clang/Basic/XRayInstr.h b/include/clang/Basic/XRayInstr.h
index 13c3032a5cca..6efefcb33ac8 100644
--- a/include/clang/Basic/XRayInstr.h
+++ b/include/clang/Basic/XRayInstr.h
@@ -60,6 +60,8 @@ struct XRayInstrSet {
bool empty() const { return Mask == 0; }
+ bool full() const { return Mask == XRayInstrKind::All; }
+
XRayInstrMask Mask = 0;
};
diff --git a/include/clang/Basic/arm_neon.td b/include/clang/Basic/arm_neon.td
index c35336166c39..af049be7e295 100644
--- a/include/clang/Basic/arm_neon.td
+++ b/include/clang/Basic/arm_neon.td
@@ -206,6 +206,15 @@ def OP_DOT_LNQ
: Op<(call "vdot", $p0, $p1,
(bitcast $p1, (splat(bitcast "uint32x4_t", $p2), $p3)))>;
+def OP_FMLAL_LN : Op<(call "vfmlal_low", $p0, $p1,
+ (dup_typed $p1, (call "vget_lane", $p2, $p3)))>;
+def OP_FMLSL_LN : Op<(call "vfmlsl_low", $p0, $p1,
+ (dup_typed $p1, (call "vget_lane", $p2, $p3)))>;
+def OP_FMLAL_LN_Hi : Op<(call "vfmlal_high", $p0, $p1,
+ (dup_typed $p1, (call "vget_lane", $p2, $p3)))>;
+def OP_FMLSL_LN_Hi : Op<(call "vfmlsl_high", $p0, $p1,
+ (dup_typed $p1, (call "vget_lane", $p2, $p3)))>;
+
//===----------------------------------------------------------------------===//
// Instructions
//===----------------------------------------------------------------------===//
@@ -337,48 +346,78 @@ def VSLI_N : WInst<"vsli_n", "dddi",
////////////////////////////////////////////////////////////////////////////////
// E.3.14 Loads and stores of a single vector
def VLD1 : WInst<"vld1", "dc",
- "QUcQUsQUiQUlQcQsQiQlQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
+ "QUcQUsQUiQUlQcQsQiQlQfQPcQPsUcUsUiUlcsilfPcPs">;
def VLD1_X2 : WInst<"vld1_x2", "2c",
- "cfhilsUcUiUlUsQcQfQhQiQlQsQUcQUiQUlQUsPcPsQPcQPs">;
+ "cfilsUcUiUlUsQcQfQiQlQsQUcQUiQUlQUsPcPsQPcQPs">;
def VLD1_X3 : WInst<"vld1_x3", "3c",
- "cfhilsUcUiUlUsQcQfQhQiQlQsQUcQUiQUlQUsPcPsQPcQPs">;
+ "cfilsUcUiUlUsQcQfQiQlQsQUcQUiQUlQUsPcPsQPcQPs">;
def VLD1_X4 : WInst<"vld1_x4", "4c",
- "cfhilsUcUiUlUsQcQfQhQiQlQsQUcQUiQUlQUsPcPsQPcQPs">;
+ "cfilsUcUiUlUsQcQfQiQlQsQUcQUiQUlQUsPcPsQPcQPs">;
def VLD1_LANE : WInst<"vld1_lane", "dcdi",
- "QUcQUsQUiQUlQcQsQiQlQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
+ "QUcQUsQUiQUlQcQsQiQlQfQPcQPsUcUsUiUlcsilfPcPs">;
def VLD1_DUP : WInst<"vld1_dup", "dc",
- "QUcQUsQUiQUlQcQsQiQlQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
+ "QUcQUsQUiQUlQcQsQiQlQfQPcQPsUcUsUiUlcsilfPcPs">;
def VST1 : WInst<"vst1", "vpd",
- "QUcQUsQUiQUlQcQsQiQlQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
+ "QUcQUsQUiQUlQcQsQiQlQfQPcQPsUcUsUiUlcsilfPcPs">;
def VST1_X2 : WInst<"vst1_x2", "vp2",
- "cfhilsUcUiUlUsQcQfQhQiQlQsQUcQUiQUlQUsPcPsQPcQPs">;
+ "cfilsUcUiUlUsQcQfQiQlQsQUcQUiQUlQUsPcPsQPcQPs">;
def VST1_X3 : WInst<"vst1_x3", "vp3",
- "cfhilsUcUiUlUsQcQfQhQiQlQsQUcQUiQUlQUsPcPsQPcQPs">;
+ "cfilsUcUiUlUsQcQfQiQlQsQUcQUiQUlQUsPcPsQPcQPs">;
def VST1_X4 : WInst<"vst1_x4", "vp4",
- "cfhilsUcUiUlUsQcQfQhQiQlQsQUcQUiQUlQUsPcPsQPcQPs">;
+ "cfilsUcUiUlUsQcQfQiQlQsQUcQUiQUlQUsPcPsQPcQPs">;
def VST1_LANE : WInst<"vst1_lane", "vpdi",
- "QUcQUsQUiQUlQcQsQiQlQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
+ "QUcQUsQUiQUlQcQsQiQlQfQPcQPsUcUsUiUlcsilfPcPs">;
+let ArchGuard = "(__ARM_FP & 2)" in {
+def VLD1_F16 : WInst<"vld1", "dc", "hQh">;
+def VLD1_X2_F16 : WInst<"vld1_x2", "2c", "hQh">;
+def VLD1_X3_F16 : WInst<"vld1_x3", "3c", "hQh">;
+def VLD1_X4_F16 : WInst<"vld1_x4", "4c", "hQh">;
+def VLD1_LANE_F16 : WInst<"vld1_lane", "dcdi", "hQh">;
+def VLD1_DUP_F16 : WInst<"vld1_dup", "dc", "hQh">;
+def VST1_F16 : WInst<"vst1", "vpd", "hQh">;
+def VST1_X2_F16 : WInst<"vst1_x2", "vp2", "hQh">;
+def VST1_X3_F16 : WInst<"vst1_x3", "vp3", "hQh">;
+def VST1_X4_F16 : WInst<"vst1_x4", "vp4", "hQh">;
+def VST1_LANE_F16 : WInst<"vst1_lane", "vpdi", "hQh">;
+}
////////////////////////////////////////////////////////////////////////////////
// E.3.15 Loads and stores of an N-element structure
-def VLD2 : WInst<"vld2", "2c", "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
-def VLD3 : WInst<"vld3", "3c", "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
-def VLD4 : WInst<"vld4", "4c", "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
+def VLD2 : WInst<"vld2", "2c", "QUcQUsQUiQcQsQiQfQPcQPsUcUsUiUlcsilfPcPs">;
+def VLD3 : WInst<"vld3", "3c", "QUcQUsQUiQcQsQiQfQPcQPsUcUsUiUlcsilfPcPs">;
+def VLD4 : WInst<"vld4", "4c", "QUcQUsQUiQcQsQiQfQPcQPsUcUsUiUlcsilfPcPs">;
def VLD2_DUP : WInst<"vld2_dup", "2c",
- "UcUsUiUlcsilhfPcPsQcQfQhQiQlQsQPcQPsQUcQUiQUlQUs">;
+ "UcUsUiUlcsilfPcPsQcQfQiQlQsQPcQPsQUcQUiQUlQUs">;
def VLD3_DUP : WInst<"vld3_dup", "3c",
- "UcUsUiUlcsilhfPcPsQcQfQhQiQlQsQPcQPsQUcQUiQUlQUs">;
+ "UcUsUiUlcsilfPcPsQcQfQiQlQsQPcQPsQUcQUiQUlQUs">;
def VLD4_DUP : WInst<"vld4_dup", "4c",
- "UcUsUiUlcsilhfPcPsQcQfQhQiQlQsQPcQPsQUcQUiQUlQUs">;
-def VLD2_LANE : WInst<"vld2_lane", "2c2i", "QUsQUiQsQiQhQfQPsUcUsUicsihfPcPs">;
-def VLD3_LANE : WInst<"vld3_lane", "3c3i", "QUsQUiQsQiQhQfQPsUcUsUicsihfPcPs">;
-def VLD4_LANE : WInst<"vld4_lane", "4c4i", "QUsQUiQsQiQhQfQPsUcUsUicsihfPcPs">;
-def VST2 : WInst<"vst2", "vp2", "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
-def VST3 : WInst<"vst3", "vp3", "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
-def VST4 : WInst<"vst4", "vp4", "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
-def VST2_LANE : WInst<"vst2_lane", "vp2i", "QUsQUiQsQiQhQfQPsUcUsUicsihfPcPs">;
-def VST3_LANE : WInst<"vst3_lane", "vp3i", "QUsQUiQsQiQhQfQPsUcUsUicsihfPcPs">;
-def VST4_LANE : WInst<"vst4_lane", "vp4i", "QUsQUiQsQiQhQfQPsUcUsUicsihfPcPs">;
+ "UcUsUiUlcsilfPcPsQcQfQiQlQsQPcQPsQUcQUiQUlQUs">;
+def VLD2_LANE : WInst<"vld2_lane", "2c2i", "QUsQUiQsQiQfQPsUcUsUicsifPcPs">;
+def VLD3_LANE : WInst<"vld3_lane", "3c3i", "QUsQUiQsQiQfQPsUcUsUicsifPcPs">;
+def VLD4_LANE : WInst<"vld4_lane", "4c4i", "QUsQUiQsQiQfQPsUcUsUicsifPcPs">;
+def VST2 : WInst<"vst2", "vp2", "QUcQUsQUiQcQsQiQfQPcQPsUcUsUiUlcsilfPcPs">;
+def VST3 : WInst<"vst3", "vp3", "QUcQUsQUiQcQsQiQfQPcQPsUcUsUiUlcsilfPcPs">;
+def VST4 : WInst<"vst4", "vp4", "QUcQUsQUiQcQsQiQfQPcQPsUcUsUiUlcsilfPcPs">;
+def VST2_LANE : WInst<"vst2_lane", "vp2i", "QUsQUiQsQiQfQPsUcUsUicsifPcPs">;
+def VST3_LANE : WInst<"vst3_lane", "vp3i", "QUsQUiQsQiQfQPsUcUsUicsifPcPs">;
+def VST4_LANE : WInst<"vst4_lane", "vp4i", "QUsQUiQsQiQfQPsUcUsUicsifPcPs">;
+let ArchGuard = "(__ARM_FP & 2)" in {
+def VLD2_F16 : WInst<"vld2", "2c", "hQh">;
+def VLD3_F16 : WInst<"vld3", "3c", "hQh">;
+def VLD4_F16 : WInst<"vld4", "4c", "hQh">;
+def VLD2_DUP_F16 : WInst<"vld2_dup", "2c", "hQh">;
+def VLD3_DUP_F16 : WInst<"vld3_dup", "3c", "hQh">;
+def VLD4_DUP_F16 : WInst<"vld4_dup", "4c", "hQh">;
+def VLD2_LANE_F16 : WInst<"vld2_lane", "2c2i", "hQh">;
+def VLD3_LANE_F16 : WInst<"vld3_lane", "3c3i", "hQh">;
+def VLD4_LANE_F16 : WInst<"vld4_lane", "4c4i", "hQh">;
+def VST2_F16 : WInst<"vst2", "vp2", "hQh">;
+def VST3_F16 : WInst<"vst3", "vp3", "hQh">;
+def VST4_F16 : WInst<"vst4", "vp4", "hQh">;
+def VST2_LANE_F16 : WInst<"vst2_lane", "vp2i", "hQh">;
+def VST3_LANE_F16 : WInst<"vst3_lane", "vp3i", "hQh">;
+def VST4_LANE_F16 : WInst<"vst4_lane", "vp4i", "hQh">;
+}
////////////////////////////////////////////////////////////////////////////////
// E.3.16 Extract lanes from a vector
@@ -1610,3 +1649,21 @@ let ArchGuard = "defined(__ARM_FEATURE_DOTPROD) && defined(__aarch64__)" in {
// Variants indexing into a 128-bit vector are A64 only.
def UDOT_LANEQ : SOpInst<"vdot_laneq", "dd89i", "iUiQiQUi", OP_DOT_LNQ>;
}
+
+// v8.2-A FP16 fused multiply-add long instructions.
+let ArchGuard = "defined(__ARM_FEATURE_FP16FML) && defined(__aarch64__)" in {
+ def VFMLAL_LOW : SInst<"vfmlal_low", "ffHH", "UiQUi">;
+ def VFMLSL_LOW : SInst<"vfmlsl_low", "ffHH", "UiQUi">;
+ def VFMLAL_HIGH : SInst<"vfmlal_high", "ffHH", "UiQUi">;
+ def VFMLSL_HIGH : SInst<"vfmlsl_high", "ffHH", "UiQUi">;
+
+ def VFMLAL_LANE_LOW : SOpInst<"vfmlal_lane_low", "ffH0i", "UiQUi", OP_FMLAL_LN>;
+ def VFMLSL_LANE_LOW : SOpInst<"vfmlsl_lane_low", "ffH0i", "UiQUi", OP_FMLSL_LN>;
+ def VFMLAL_LANE_HIGH : SOpInst<"vfmlal_lane_high", "ffH0i", "UiQUi", OP_FMLAL_LN_Hi>;
+ def VFMLSL_LANE_HIGH : SOpInst<"vfmlsl_lane_high", "ffH0i", "UiQUi", OP_FMLSL_LN_Hi>;
+
+ def VFMLAL_LANEQ_LOW : SOpInst<"vfmlal_laneq_low", "ffH1i", "UiQUi", OP_FMLAL_LN>;
+ def VFMLSL_LANEQ_LOW : SOpInst<"vfmlsl_laneq_low", "ffH1i", "UiQUi", OP_FMLSL_LN>;
+ def VFMLAL_LANEQ_HIGH : SOpInst<"vfmlal_laneq_high", "ffH1i", "UiQUi", OP_FMLAL_LN_Hi>;
+ def VFMLSL_LANEQ_HIGH : SOpInst<"vfmlsl_laneq_high", "ffH1i", "UiQUi", OP_FMLSL_LN_Hi>;
+}
diff --git a/include/clang/Basic/arm_neon_incl.td b/include/clang/Basic/arm_neon_incl.td
index 5f3aa6fc0221..09df22ea5ca2 100644
--- a/include/clang/Basic/arm_neon_incl.td
+++ b/include/clang/Basic/arm_neon_incl.td
@@ -96,6 +96,11 @@ def bitcast;
// example: (dup $p1) -> "(uint32x2_t) {__p1, __p1}" (assuming the base type
// is uint32x2_t).
def dup;
+// dup_typed - Take a vector and a scalar argument, and create a new vector of
+// the same type by duplicating the scalar value into all lanes.
+// example: (dup_typed $p1, $p2) -> "(float16x4_t) {__p2, __p2, __p2, __p2}"
+// (assuming __p1 is float16x4_t, and __p2 is a compatible scalar).
+def dup_typed;
// splat - Take a vector and a lane index, and return a vector of the same type
// containing repeated instances of the source vector at the lane index.
// example: (splat $p0, $p1) ->
@@ -229,6 +234,8 @@ def OP_UNAVAILABLE : Operation {
// f: float (int args)
// F: double (int args)
// H: half (int args)
+// 0: half (int args), ignore 'Q' size modifier.
+// 1: half (int args), force 'Q' size modifier.
// d: default
// g: default, ignore 'Q' size modifier.
// j: default, force 'Q' size modifier.
diff --git a/include/clang/CodeGen/CGFunctionInfo.h b/include/clang/CodeGen/CGFunctionInfo.h
index cf64e9f3eeff..58d1f0d71c74 100644
--- a/include/clang/CodeGen/CGFunctionInfo.h
+++ b/include/clang/CodeGen/CGFunctionInfo.h
@@ -581,11 +581,11 @@ public:
typedef ArgInfo *arg_iterator;
typedef llvm::iterator_range<arg_iterator> arg_range;
- typedef llvm::iterator_range<const_arg_iterator> arg_const_range;
+ typedef llvm::iterator_range<const_arg_iterator> const_arg_range;
arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
- arg_const_range arguments() const {
- return arg_const_range(arg_begin(), arg_end());
+ const_arg_range arguments() const {
+ return const_arg_range(arg_begin(), arg_end());
}
const_arg_iterator arg_begin() const { return getArgsBuffer() + 1; }
diff --git a/include/clang/CodeGen/SwiftCallingConv.h b/include/clang/CodeGen/SwiftCallingConv.h
index 45b3145ed9f1..5aa9be2d67c1 100644
--- a/include/clang/CodeGen/SwiftCallingConv.h
+++ b/include/clang/CodeGen/SwiftCallingConv.h
@@ -114,6 +114,9 @@ private:
void addLegalTypedData(llvm::Type *type, CharUnits begin, CharUnits end);
void addEntry(llvm::Type *type, CharUnits begin, CharUnits end);
void splitVectorEntry(unsigned index);
+ static bool shouldMergeEntries(const StorageEntry &first,
+ const StorageEntry &second,
+ CharUnits chunkSize);
};
/// Should an aggregate which expands to the given type sequence
diff --git a/include/clang/CrossTU/CrossTUDiagnostic.h b/include/clang/CrossTU/CrossTUDiagnostic.h
index dad38309fd1a..56c83a5ad25c 100644
--- a/include/clang/CrossTU/CrossTUDiagnostic.h
+++ b/include/clang/CrossTU/CrossTUDiagnostic.h
@@ -10,20 +10,6 @@
#ifndef LLVM_CLANG_CROSSTU_CROSSTUDIAGNOSTIC_H
#define LLVM_CLANG_CROSSTU_CROSSTUDIAGNOSTIC_H
-#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticCrossTU.h"
-namespace clang {
-namespace diag {
-enum {
-#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
- SHOWINSYSHEADER, CATEGORY) \
- ENUM,
-#define CROSSTUSTART
-#include "clang/Basic/DiagnosticCrossTUKinds.inc"
-#undef DIAG
- NUM_BUILTIN_CROSSTU_DIAGNOSTICS
-};
-} // end namespace diag
-} // end namespace clang
-
-#endif // LLVM_CLANG_FRONTEND_FRONTENDDIAGNOSTIC_H
+#endif // LLVM_CLANG_CROSSTU_CROSSTUDIAGNOSTIC_H
diff --git a/include/clang/CrossTU/CrossTranslationUnit.h b/include/clang/CrossTU/CrossTranslationUnit.h
index 041f1a8eea59..52e3ae27490f 100644
--- a/include/clang/CrossTU/CrossTranslationUnit.h
+++ b/include/clang/CrossTU/CrossTranslationUnit.h
@@ -15,6 +15,7 @@
#ifndef LLVM_CLANG_CROSSTU_CROSSTRANSLATIONUNIT_H
#define LLVM_CLANG_CROSSTU_CROSSTRANSLATIONUNIT_H
+#include "clang/AST/ASTImporterLookupTable.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
@@ -41,7 +42,9 @@ enum class index_error_code {
missing_definition,
failed_import,
failed_to_get_external_ast,
- failed_to_generate_usr
+ failed_to_generate_usr,
+ triple_mismatch,
+ lang_mismatch
};
class IndexError : public llvm::ErrorInfo<IndexError> {
@@ -50,16 +53,25 @@ public:
IndexError(index_error_code C) : Code(C), LineNo(0) {}
IndexError(index_error_code C, std::string FileName, int LineNo = 0)
: Code(C), FileName(std::move(FileName)), LineNo(LineNo) {}
+ IndexError(index_error_code C, std::string FileName, std::string TripleToName,
+ std::string TripleFromName)
+ : Code(C), FileName(std::move(FileName)),
+ TripleToName(std::move(TripleToName)),
+ TripleFromName(std::move(TripleFromName)) {}
void log(raw_ostream &OS) const override;
std::error_code convertToErrorCode() const override;
index_error_code getCode() const { return Code; }
int getLineNum() const { return LineNo; }
std::string getFileName() const { return FileName; }
+ std::string getTripleToName() const { return TripleToName; }
+ std::string getTripleFromName() const { return TripleFromName; }
private:
index_error_code Code;
std::string FileName;
int LineNo;
+ std::string TripleToName;
+ std::string TripleFromName;
};
/// This function parses an index file that determines which
@@ -78,11 +90,11 @@ std::string createCrossTUIndexString(const llvm::StringMap<std::string> &Index);
/// This class is used for tools that requires cross translation
/// unit capability.
///
-/// This class can load function definitions from external AST files.
+/// This class can load definitions from external AST files.
/// The loaded definition will be merged back to the original AST using the
/// AST Importer.
/// In order to use this class, an index file is required that describes
-/// the locations of the AST files for each function definition.
+/// the locations of the AST files for each definition.
///
/// Note that this class also implements caching.
class CrossTranslationUnitContext {
@@ -108,7 +120,7 @@ public:
/// Note that the AST files should also be in the \p CrossTUDir.
llvm::Expected<const FunctionDecl *>
getCrossTUDefinition(const FunctionDecl *FD, StringRef CrossTUDir,
- StringRef IndexName);
+ StringRef IndexName, bool DisplayCTUProgress = false);
/// This function loads a function definition from an external AST
/// file.
@@ -118,13 +130,15 @@ public:
/// \p IndexName. In case the declaration is found in the index the
/// corresponding AST file will be loaded.
///
- /// \return Returns an ASTUnit that contains the definition of the looked up
- /// function.
+ /// \return Returns a pointer to the ASTUnit that contains the definition of
+ /// the looked up function or an Error.
+ /// The returned pointer is never a nullptr.
///
/// Note that the AST files should also be in the \p CrossTUDir.
llvm::Expected<ASTUnit *> loadExternalAST(StringRef LookupName,
StringRef CrossTUDir,
- StringRef IndexName);
+ StringRef IndexName,
+ bool DisplayCTUProgress = false);
/// This function merges a definition from a separate AST Unit into
/// the current one which was created by the compiler instance that
@@ -140,6 +154,7 @@ public:
void emitCrossTUDiagnostics(const IndexError &IE);
private:
+ void lazyInitLookupTable(TranslationUnitDecl *ToTU);
ASTImporter &getOrCreateASTImporter(ASTContext &From);
const FunctionDecl *findFunctionInDeclContext(const DeclContext *DC,
StringRef LookupFnName);
@@ -151,6 +166,7 @@ private:
ASTUnitImporterMap;
CompilerInstance &CI;
ASTContext &Context;
+ std::unique_ptr<ASTImporterLookupTable> LookupTable;
};
} // namespace cross_tu
diff --git a/include/clang/Driver/Action.h b/include/clang/Driver/Action.h
index 723fbbed3598..f4aaa6c544ac 100644
--- a/include/clang/Driver/Action.h
+++ b/include/clang/Driver/Action.h
@@ -59,6 +59,7 @@ public:
OffloadClass,
PreprocessJobClass,
PrecompileJobClass,
+ HeaderModulePrecompileJobClass,
AnalyzeJobClass,
MigrateJobClass,
CompileJobClass,
@@ -398,12 +399,36 @@ public:
class PrecompileJobAction : public JobAction {
void anchor() override;
+protected:
+ PrecompileJobAction(ActionClass Kind, Action *Input, types::ID OutputType);
+
public:
PrecompileJobAction(Action *Input, types::ID OutputType);
static bool classof(const Action *A) {
- return A->getKind() == PrecompileJobClass;
+ return A->getKind() == PrecompileJobClass ||
+ A->getKind() == HeaderModulePrecompileJobClass;
+ }
+};
+
+class HeaderModulePrecompileJobAction : public PrecompileJobAction {
+ void anchor() override;
+
+ const char *ModuleName;
+
+public:
+ HeaderModulePrecompileJobAction(Action *Input, types::ID OutputType,
+ const char *ModuleName);
+
+ static bool classof(const Action *A) {
+ return A->getKind() == HeaderModulePrecompileJobClass;
}
+
+ void addModuleHeaderInput(Action *Input) {
+ getInputs().push_back(Input);
+ }
+
+ const char *getModuleName() const { return ModuleName; }
};
class AnalyzeJobAction : public JobAction {
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index 672231e70fad..07c76884063f 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -27,6 +27,8 @@ def triple : Separate<["-"], "triple">,
HelpText<"Specify target triple (e.g. i686-apple-darwin9)">;
def target_abi : Separate<["-"], "target-abi">,
HelpText<"Target a particular ABI type">;
+def target_sdk_version_EQ : Joined<["-"], "target-sdk-version=">,
+ HelpText<"The version of target SDK used for compilation">;
}
@@ -76,14 +78,13 @@ def analyzer_display_progress : Flag<["-"], "analyzer-display-progress">,
def analyze_function : Separate<["-"], "analyze-function">,
HelpText<"Run analysis on specific function (for C++ include parameters in name)">;
def analyze_function_EQ : Joined<["-"], "analyze-function=">, Alias<analyze_function>;
-def analyzer_eagerly_assume : Flag<["-"], "analyzer-eagerly-assume">,
- HelpText<"Eagerly assume the truth/falseness of some symbolic constraints">;
def trim_egraph : Flag<["-"], "trim-egraph">,
HelpText<"Only show error-related paths in the analysis graph">;
def analyzer_viz_egraph_graphviz : Flag<["-"], "analyzer-viz-egraph-graphviz">,
HelpText<"Display exploded graph using GraphViz">;
-def analyzer_viz_egraph_ubigraph : Flag<["-"], "analyzer-viz-egraph-ubigraph">,
- HelpText<"Display exploded graph using Ubigraph">;
+def analyzer_dump_egraph : Separate<["-"], "analyzer-dump-egraph">,
+ HelpText<"Dump exploded graph to the specified file">;
+def analyzer_dump_egraph_EQ : Joined<["-"], "analyzer-dump-egraph=">, Alias<analyzer_dump_egraph>;
def analyzer_inline_max_stack_depth : Separate<["-"], "analyzer-inline-max-stack-depth">,
HelpText<"Bound on stack depth while inlining (4 by default)">;
@@ -107,11 +108,11 @@ def analyzer_checker : Separate<["-"], "analyzer-checker">,
ValuesCode<[{
const char *Values =
#define GET_CHECKERS
- #define CHECKER(FULLNAME, CLASS, DESCFILE, HT, G, H) FULLNAME ","
+ #define CHECKER(FULLNAME, CLASS, HT, DOC_URI) FULLNAME ","
#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
#undef GET_CHECKERS
#define GET_PACKAGES
- #define PACKAGE(FULLNAME, G, D) FULLNAME ","
+ #define PACKAGE(FULLNAME) FULLNAME ","
#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
#undef GET_PACKAGES
;
@@ -130,12 +131,21 @@ def analyzer_disable_all_checks : Flag<["-"], "analyzer-disable-all-checks">,
def analyzer_checker_help : Flag<["-"], "analyzer-checker-help">,
HelpText<"Display the list of analyzer checkers that are available">;
+def analyzer_config_help : Flag<["-"], "analyzer-config-help">,
+ HelpText<"Display the list of -analyzer-config options">;
+
def analyzer_list_enabled_checkers : Flag<["-"], "analyzer-list-enabled-checkers">,
HelpText<"Display the list of enabled analyzer checkers">;
def analyzer_config : Separate<["-"], "analyzer-config">,
HelpText<"Choose analyzer options to enable">;
+def analyzer_config_compatibility_mode : Separate<["-"], "analyzer-config-compatibility-mode">,
+ HelpText<"Don't emit errors on invalid analyzer-config inputs">;
+
+def analyzer_config_compatibility_mode_EQ : Joined<["-"], "analyzer-config-compatibility-mode=">,
+ Alias<analyzer_config_compatibility_mode>;
+
//===----------------------------------------------------------------------===//
// Migrator Options
//===----------------------------------------------------------------------===//
@@ -153,12 +163,16 @@ let Flags = [CC1Option, CC1AsOption, NoDriverOption] in {
def debug_info_kind_EQ : Joined<["-"], "debug-info-kind=">;
def debug_info_macro : Flag<["-"], "debug-info-macro">,
HelpText<"Emit macro debug information">;
+def default_function_attr : Separate<["-"], "default-function-attr">,
+ HelpText<"Apply given attribute to all functions">;
def dwarf_version_EQ : Joined<["-"], "dwarf-version=">;
def debugger_tuning_EQ : Joined<["-"], "debugger-tuning=">;
def fdebug_compilation_dir : Separate<["-"], "fdebug-compilation-dir">,
HelpText<"The compilation directory to embed in the debug info.">;
def dwarf_debug_flags : Separate<["-"], "dwarf-debug-flags">,
HelpText<"The string to embed in the Dwarf debug flags record.">;
+def record_command_line : Separate<["-"], "record-command-line">,
+ HelpText<"The string to embed in the .LLVM.command.line section.">;
def compress_debug_sections : Flag<["-", "--"], "compress-debug-sections">,
HelpText<"DWARF debug sections compression">;
def compress_debug_sections_EQ : Joined<["-"], "compress-debug-sections=">,
@@ -197,10 +211,6 @@ def dwarf_column_info : Flag<["-"], "dwarf-column-info">,
HelpText<"Turn on column location information.">;
def split_dwarf : Flag<["-"], "split-dwarf">,
HelpText<"Split out the dwarf .dwo sections">;
-def gnu_pubnames : Flag<["-"], "gnu-pubnames">,
- HelpText<"Emit newer GNU style pubnames">;
-def arange_sections : Flag<["-"], "arange_sections">,
- HelpText<"Emit DWARF .debug_arange sections">;
def dwarf_ext_refs : Flag<["-"], "dwarf-ext-refs">,
HelpText<"Generate debug info with external references to clang modules"
" or precompiled headers">;
@@ -253,7 +263,7 @@ def new_struct_path_tbaa : Flag<["-"], "new-struct-path-tbaa">,
def masm_verbose : Flag<["-"], "masm-verbose">,
HelpText<"Generate verbose assembly output">;
def mcode_model : Separate<["-"], "mcode-model">,
- HelpText<"The code model to use">, Values<"small,kernel,medium,large">;
+ HelpText<"The code model to use">, Values<"tiny,small,kernel,medium,large">;
def mdebug_pass : Separate<["-"], "mdebug-pass">,
HelpText<"Enable additional debug output">;
def mdisable_fp_elim : Flag<["-"], "mdisable-fp-elim">,
@@ -287,9 +297,11 @@ def mconstructor_aliases : Flag<["-"], "mconstructor-aliases">,
HelpText<"Emit complete constructors and destructors as aliases when possible">;
def mlink_bitcode_file : Separate<["-"], "mlink-bitcode-file">,
HelpText<"Link the given bitcode file before performing optimizations.">;
-def mlink_cuda_bitcode : Separate<["-"], "mlink-cuda-bitcode">,
+def mlink_builtin_bitcode : Separate<["-"], "mlink-builtin-bitcode">,
HelpText<"Link and internalize needed symbols from the given bitcode file "
"before performing optimizations.">;
+def mlink_cuda_bitcode : Separate<["-"], "mlink-cuda-bitcode">,
+ Alias<mlink_builtin_bitcode>;
def vectorize_loops : Flag<["-"], "vectorize-loops">,
HelpText<"Run the Loop vectorization passes">;
def vectorize_slp : Flag<["-"], "vectorize-slp">,
@@ -357,6 +369,13 @@ def fdebug_pass_manager : Flag<["-"], "fdebug-pass-manager">,
HelpText<"Prints debug information for the new pass manager">;
def fno_debug_pass_manager : Flag<["-"], "fno-debug-pass-manager">,
HelpText<"Disables debug printing for the new pass manager">;
+// The driver option takes the key as a parameter to the -msign-return-address=
+// and -mbranch-protection= options, but CC1 has a separate option so we
+// don't have to parse the parameter twice.
+def msign_return_address_key_EQ : Joined<["-"], "msign-return-address-key=">,
+ Values<"a_key,b_key">;
+def mbranch_target_enforce : Flag<["-"], "mbranch-target-enforce">;
+def fno_dllexport_inlines : Flag<["-"], "fno-dllexport-inlines">;
//===----------------------------------------------------------------------===//
// Dependency Output Options
@@ -543,14 +562,12 @@ def ast_dump_lookups : Flag<["-"], "ast-dump-lookups">,
HelpText<"Build ASTs and then debug dump their name lookup tables">;
def ast_view : Flag<["-"], "ast-view">,
HelpText<"Build ASTs and view them with GraphViz">;
-def print_decl_contexts : Flag<["-"], "print-decl-contexts">,
- HelpText<"Print DeclContexts and their Decls">;
def emit_module : Flag<["-"], "emit-module">,
HelpText<"Generate pre-compiled module file from a module map">;
def emit_module_interface : Flag<["-"], "emit-module-interface">,
HelpText<"Generate pre-compiled module file from a C++ module interface">;
-def emit_pth : Flag<["-"], "emit-pth">,
- HelpText<"Generate pre-tokenized header file">;
+def emit_header_module : Flag<["-"], "emit-header-module">,
+ HelpText<"Generate pre-compiled module file from a set of header files">;
def emit_pch : Flag<["-"], "emit-pch">,
HelpText<"Generate pre-compiled header file">;
def emit_llvm_bc : Flag<["-"], "emit-llvm-bc">,
@@ -610,6 +627,10 @@ def foverride_record_layout_EQ : Joined<["-"], "foverride-record-layout=">,
def pch_through_header_EQ : Joined<["-"], "pch-through-header=">,
HelpText<"Stop PCH generation after including this file. When using a PCH, "
"skip tokens until after this file is included.">;
+def pch_through_hdrstop_create : Flag<["-"], "pch-through-hdrstop-create">,
+ HelpText<"When creating a PCH, stop PCH generation after #pragma hdrstop.">;
+def pch_through_hdrstop_use : Flag<["-"], "pch-through-hdrstop-use">,
+ HelpText<"When using a PCH, skip tokens until after a #pragma hdrstop.">;
def fno_pch_timestamp : Flag<["-"], "fno-pch-timestamp">,
HelpText<"Disable inclusion of timestamp in precompiled headers">;
def building_pch_with_obj : Flag<["-"], "building-pch-with-obj">,
@@ -638,7 +659,9 @@ def fblocks_runtime_optional : Flag<["-"], "fblocks-runtime-optional">,
def fexternc_nounwind : Flag<["-"], "fexternc-nounwind">,
HelpText<"Assume all functions with C linkage do not unwind">;
def enable_split_dwarf : Flag<["-"], "enable-split-dwarf">,
- HelpText<"Use split dwarf/Fission">;
+ HelpText<"Use DWARF fission in 'split' mode">;
+def enable_split_dwarf_EQ : Joined<["-"], "enable-split-dwarf=">,
+ HelpText<"Set DWARF fission mode to either 'split' or 'single'">, Values<"split,single">;
def fno_wchar : Flag<["-"], "fno-wchar">,
HelpText<"Disable C++ builtin type wchar_t">;
def fconstant_string_class : Separate<["-"], "fconstant-string-class">,
@@ -775,15 +798,11 @@ def internal_externc_isystem : JoinedOrSeparate<["-"], "internal-externc-isystem
// Preprocessor Options
//===----------------------------------------------------------------------===//
-def include_pth : Separate<["-"], "include-pth">, MetaVarName<"<file>">,
- HelpText<"Include file before parsing">;
def chain_include : Separate<["-"], "chain-include">, MetaVarName<"<file>">,
HelpText<"Include and chain a header file after turning it into PCH">;
def preamble_bytes_EQ : Joined<["-"], "preamble-bytes=">,
HelpText<"Assume that the precompiled header is a precompiled preamble "
"covering the first N bytes of the main file">;
-def token_cache : Separate<["-"], "token-cache">, MetaVarName<"<path>">,
- HelpText<"Use specified token cache file">;
def detailed_preprocessing_record : Flag<["-"], "detailed-preprocessing-record">,
HelpText<"include a detailed record of preprocessing actions">;
diff --git a/include/clang/Driver/CLCompatOptions.td b/include/clang/Driver/CLCompatOptions.td
index 78667851ca19..3e0dc2db7d07 100644
--- a/include/clang/Driver/CLCompatOptions.td
+++ b/include/clang/Driver/CLCompatOptions.td
@@ -85,16 +85,19 @@ def _SLASH_GA : CLFlag<"GA">, Alias<ftlsmodel_EQ>, AliasArgs<["local-exec"]>,
HelpText<"Assume thread-local variables are defined in the executable">;
def _SLASH_GR : CLFlag<"GR">, HelpText<"Enable emission of RTTI data">;
def _SLASH_GR_ : CLFlag<"GR-">, HelpText<"Disable emission of RTTI data">;
+def _SLASH_GF : CLIgnoredFlag<"GF">, HelpText<"Enable string pooling (default)">;
def _SLASH_GF_ : CLFlag<"GF-">, HelpText<"Disable string pooling">,
Alias<fwritable_strings>;
-def _SLASH_GS : CLFlag<"GS">, HelpText<"Enable buffer security check">;
+def _SLASH_GS : CLFlag<"GS">, HelpText<"Enable buffer security check (default)">;
def _SLASH_GS_ : CLFlag<"GS-">, HelpText<"Disable buffer security check">;
-def _SLASH_Gs : CLJoined<"Gs">, HelpText<"Set stack probe size">,
- Alias<mstack_probe_size>;
+def : CLFlag<"Gs">, HelpText<"Use stack probes (default)">,
+ Alias<mstack_probe_size>, AliasArgs<["4096"]>;
+def _SLASH_Gs : CLJoined<"Gs">,
+ HelpText<"Set stack probe size (default 4096)">, Alias<mstack_probe_size>;
def _SLASH_Gy : CLFlag<"Gy">, HelpText<"Put each function in its own section">,
Alias<ffunction_sections>;
def _SLASH_Gy_ : CLFlag<"Gy-">,
- HelpText<"Don't put each function in its own section">,
+ HelpText<"Don't put each function in its own section (default)">,
Alias<fno_function_sections>;
def _SLASH_Gw : CLFlag<"Gw">, HelpText<"Put each data item in its own section">,
Alias<fdata_sections>;
@@ -109,18 +112,43 @@ def _SLASH_I : CLJoinedOrSeparate<"I">,
Alias<I>;
def _SLASH_J : CLFlag<"J">, HelpText<"Make char type unsigned">,
Alias<funsigned_char>;
-def _SLASH_O0 : CLFlag<"O0">, Alias<O0>;
-// /Oy- is handled by the /O option because /Oy- only has an effect on 32-bit.
-def _SLASH_O : CLJoined<"O">, HelpText<"Optimization level">;
-def _SLASH_Od : CLFlag<"Od">, HelpText<"Disable optimization">, Alias<O0>;
-def _SLASH_Oi : CLFlag<"Oi">, HelpText<"Enable use of builtin functions">,
- Alias<fbuiltin>;
-def _SLASH_Oi_ : CLFlag<"Oi-">, HelpText<"Disable use of builtin functions">,
- Alias<fno_builtin>;
-def _SLASH_Os : CLFlag<"Os">, HelpText<"Optimize for size">, Alias<O>,
- AliasArgs<["s"]>;
-def _SLASH_Ot : CLFlag<"Ot">, HelpText<"Optimize for speed">, Alias<O>,
- AliasArgs<["2"]>;
+
+// The _SLASH_O option handles all the /O flags, but we also provide separate
+// aliased options to provide separate help messages.
+def _SLASH_O : CLJoined<"O">,
+ HelpText<"Set multiple /O flags at once; e.g. '/O2y-' for '/O2 /Oy-'">,
+ MetaVarName<"<flags>">;
+// FIXME: Not sure why we have -O0 here; MSVC doesn't support that.
+def : CLFlag<"O0">, Alias<O0>, HelpText<"Disable optimization">;
+def : CLFlag<"O1">, Alias<_SLASH_O>, AliasArgs<["1"]>,
+ HelpText<"Optimize for size (same as /Og /Os /Oy /Ob2 /GF /Gy)">;
+def : CLFlag<"O2">, Alias<_SLASH_O>, AliasArgs<["2"]>,
+ HelpText<"Optimize for speed (same as /Og /Oi /Ot /Oy /Ob2 /GF /Gy)">;
+def : CLFlag<"Ob0">, Alias<_SLASH_O>, AliasArgs<["b0"]>,
+ HelpText<"Disable function inlining">;
+def : CLFlag<"Ob1">, Alias<_SLASH_O>, AliasArgs<["b1"]>,
+ HelpText<"Only inline functions which are (explicitly or implicitly) marked inline">;
+def : CLFlag<"Ob2">, Alias<_SLASH_O>, AliasArgs<["b2"]>,
+ HelpText<"Inline functions as deemed beneficial by the compiler">;
+def : CLFlag<"Od">, Alias<_SLASH_O>, AliasArgs<["d"]>,
+ HelpText<"Disable optimization">;
+def : CLFlag<"Og">, Alias<_SLASH_O>, AliasArgs<["g"]>,
+ HelpText<"No effect">;
+def : CLFlag<"Oi">, Alias<_SLASH_O>, AliasArgs<["i"]>,
+ HelpText<"Enable use of builtin functions">;
+def : CLFlag<"Oi-">, Alias<_SLASH_O>, AliasArgs<["i-"]>,
+ HelpText<"Disable use of builtin functions">;
+def : CLFlag<"Os">, Alias<_SLASH_O>, AliasArgs<["s"]>,
+ HelpText<"Optimize for size">;
+def : CLFlag<"Ot">, Alias<_SLASH_O>, AliasArgs<["t"]>,
+ HelpText<"Optimize for speed">;
+def : CLFlag<"Ox">, Alias<_SLASH_O>, AliasArgs<["x"]>,
+ HelpText<"Deprecated (same as /Og /Oi /Ot /Oy /Ob2); use /O2 instead">;
+def : CLFlag<"Oy">, Alias<_SLASH_O>, AliasArgs<["y"]>,
+ HelpText<"Enable frame pointer omission (x86 only)">;
+def : CLFlag<"Oy-">, Alias<_SLASH_O>, AliasArgs<["y-"]>,
+ HelpText<"Disable frame pointer omission (x86 only, default)">;
+
def _SLASH_QUESTION : CLFlag<"?">, Alias<help>,
HelpText<"Display available options">;
def _SLASH_Qvec : CLFlag<"Qvec">,
@@ -130,6 +158,10 @@ def _SLASH_Qvec_ : CLFlag<"Qvec-">,
def _SLASH_showIncludes : CLFlag<"showIncludes">,
HelpText<"Print info about included files to stderr">,
Alias<show_includes>;
+def _SLASH_showFilenames : CLFlag<"showFilenames">,
+ HelpText<"Print the name of each compiled file">;
+def _SLASH_showFilenames_ : CLFlag<"showFilenames-">,
+ HelpText<"Don't print the name of each compiled file (default)">;
def _SLASH_source_charset : CLCompileJoined<"source-charset:">,
HelpText<"Source encoding, supports only UTF-8">, Alias<finput_charset_EQ>;
def _SLASH_execution_charset : CLCompileJoined<"execution-charset:">,
@@ -175,6 +207,12 @@ def _SLASH_Zc_sizedDealloc : CLFlag<"Zc:sizedDealloc">,
def _SLASH_Zc_sizedDealloc_ : CLFlag<"Zc:sizedDealloc-">,
HelpText<"Disable C++14 sized global deallocation functions">,
Alias<fno_sized_deallocation>;
+def _SLASH_Zc_alignedNew : CLFlag<"Zc:alignedNew">,
+ HelpText<"Enable C++17 aligned allocation functions">,
+ Alias<faligned_allocation>;
+def _SLASH_Zc_alignedNew_ : CLFlag<"Zc:alignedNew-">,
+ HelpText<"Disable C++17 aligned allocation functions">,
+ Alias<fno_aligned_allocation>;
def _SLASH_Zc_strictStrings : CLFlag<"Zc:strictStrings">,
HelpText<"Treat string literals as const">, Alias<W_Joined>,
AliasArgs<["error=c++11-compat-deprecated-writable-strings"]>;
@@ -240,8 +278,8 @@ def _SLASH_Fi : CLCompileJoined<"Fi">,
def _SLASH_Fo : CLCompileJoined<"Fo">,
HelpText<"Set output object file, or directory (ends in / or \\) (with /c)">,
MetaVarName<"<file or directory>">;
-def _SLASH_Guard : CLJoined<"guard:">,
- HelpText<"Enable Control Flow Guard with /guard:cf">;
+def _SLASH_guard : CLJoined<"guard:">,
+ HelpText<"Enable Control Flow Guard with /guard:cf, or only the table with /guard:cf,nochecks">;
def _SLASH_GX : CLFlag<"GX">,
HelpText<"Enable exception handling">;
def _SLASH_GX_ : CLFlag<"GX-">,
@@ -289,6 +327,8 @@ def _SLASH_vmv : CLFlag<"vmv">,
def _SLASH_volatile_ms : Option<["/", "-"], "volatile:ms", KIND_FLAG>,
Group<_SLASH_volatile_Group>, Flags<[CLOption, DriverOption]>,
HelpText<"Volatile loads and stores have acquire and release semantics">;
+def _SLASH_clang : CLJoined<"clang:">,
+ HelpText<"Pass <arg> to the clang driver">, MetaVarName<"<arg>">;
def _SLASH_Zl : CLFlag<"Zl">,
HelpText<"Don't mention any default libraries in the object file">;
@@ -301,6 +341,10 @@ def _SLASH_Yu : CLJoined<"Yu">,
MetaVarName<"<filename>">;
def _SLASH_Y_ : CLFlag<"Y-">,
HelpText<"Disable precompiled headers, overrides /Yc and /Yu">;
+def _SLASH_Zc_dllexportInlines : CLFlag<"Zc:dllexportInlines">,
+ HelpText<"dllexport/dllimport inline member functions of dllexport/import classes (default)">;
+def _SLASH_Zc_dllexportInlines_ : CLFlag<"Zc:dllexportInlines-">,
+ HelpText<"Don't dllexport/dllimport inline member functions of dllexport/import classes">;
def _SLASH_Fp : CLJoined<"Fp">,
HelpText<"Set pch filename (with /Yc and /Yu)">, MetaVarName<"<filename>">;
@@ -326,10 +370,9 @@ def _SLASH_errorReport : CLIgnoredJoined<"errorReport">;
def _SLASH_FC : CLIgnoredFlag<"FC">;
def _SLASH_Fd : CLIgnoredJoined<"Fd">;
def _SLASH_FS : CLIgnoredFlag<"FS">;
-def _SLASH_GF : CLIgnoredFlag<"GF">;
+def _SLASH_JMC : CLIgnoredFlag<"JMC">;
def _SLASH_kernel_ : CLIgnoredFlag<"kernel-">;
def _SLASH_nologo : CLIgnoredFlag<"nologo">;
-def _SLASH_Og : CLIgnoredFlag<"Og">;
def _SLASH_openmp_ : CLIgnoredFlag<"openmp-">;
def _SLASH_permissive_ : CLIgnoredFlag<"permissive-">;
def _SLASH_RTC : CLIgnoredJoined<"RTC">;
diff --git a/include/clang/Driver/DarwinSDKInfo.h b/include/clang/Driver/DarwinSDKInfo.h
new file mode 100644
index 000000000000..4ffb02fea345
--- /dev/null
+++ b/include/clang/Driver/DarwinSDKInfo.h
@@ -0,0 +1,42 @@
+//===--- DarwinSDKInfo.h - SDK Information parser for darwin ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_DRIVER_DARWIN_SDK_INFO_H
+#define LLVM_CLANG_DRIVER_DARWIN_SDK_INFO_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/VersionTuple.h"
+#include "llvm/Support/VirtualFileSystem.h"
+
+namespace clang {
+namespace driver {
+
+/// The information about the darwin SDK that was used during this compilation.
+class DarwinSDKInfo {
+public:
+ DarwinSDKInfo(llvm::VersionTuple Version) : Version(Version) {}
+
+ const llvm::VersionTuple &getVersion() const { return Version; }
+
+private:
+ llvm::VersionTuple Version;
+};
+
+/// Parse the SDK information from the SDKSettings.json file.
+///
+/// \returns an error if the SDKSettings.json file is invalid, None if the
+/// SDK has no SDKSettings.json, or a valid \c DarwinSDKInfo otherwise.
+Expected<Optional<DarwinSDKInfo>> parseDarwinSDKInfo(llvm::vfs::FileSystem &VFS,
+ StringRef SDKRootPath);
+
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_DRIVER_DARWIN_SDK_INFO_H
diff --git a/include/clang/Driver/Distro.h b/include/clang/Driver/Distro.h
index 7b34a0925603..5651ebb6d42c 100644
--- a/include/clang/Driver/Distro.h
+++ b/include/clang/Driver/Distro.h
@@ -10,7 +10,7 @@
#ifndef LLVM_CLANG_DRIVER_DISTRO_H
#define LLVM_CLANG_DRIVER_DISTRO_H
-#include "clang/Basic/VirtualFileSystem.h"
+#include "llvm/Support/VirtualFileSystem.h"
namespace clang {
namespace driver {
@@ -39,6 +39,7 @@ public:
RHEL6,
RHEL7,
Fedora,
+ Gentoo,
OpenSUSE,
UbuntuHardy,
UbuntuIntrepid,
@@ -62,6 +63,7 @@ public:
UbuntuArtful,
UbuntuBionic,
UbuntuCosmic,
+ UbuntuDisco,
UnknownDistro
};
@@ -80,7 +82,7 @@ public:
Distro(DistroType D) : DistroVal(D) {}
/// Detects the distribution using specified VFS.
- explicit Distro(clang::vfs::FileSystem& VFS);
+ explicit Distro(llvm::vfs::FileSystem &VFS);
bool operator==(const Distro &Other) const {
return DistroVal == Other.DistroVal;
@@ -115,13 +117,17 @@ public:
}
bool IsUbuntu() const {
- return DistroVal >= UbuntuHardy && DistroVal <= UbuntuCosmic;
+ return DistroVal >= UbuntuHardy && DistroVal <= UbuntuDisco;
}
bool IsAlpineLinux() const {
return DistroVal == AlpineLinux;
}
+ bool IsGentoo() const {
+ return DistroVal == Gentoo;
+ }
+
/// @}
};
diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h
index b7b802221180..494336d672c2 100644
--- a/include/clang/Driver/Driver.h
+++ b/include/clang/Driver/Driver.h
@@ -28,13 +28,12 @@
namespace llvm {
class Triple;
-}
-
-namespace clang {
-
namespace vfs {
class FileSystem;
}
+} // namespace llvm
+
+namespace clang {
namespace driver {
@@ -61,7 +60,7 @@ class Driver {
DiagnosticsEngine &Diags;
- IntrusiveRefCntPtr<vfs::FileSystem> VFS;
+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS;
enum DriverMode {
GCCMode,
@@ -228,9 +227,6 @@ private:
unsigned CheckInputsExist : 1;
public:
- /// Use lazy precompiled headers for PCH support.
- unsigned CCCUsePCH : 1;
-
/// Force clang to emit reproducer for driver invocation. This is enabled
/// indirectly by setting FORCE_CLANG_DIAGNOSTICS_CRASH environment variable
/// or when using the -gen-reproducer driver flag.
@@ -284,7 +280,7 @@ private:
public:
Driver(StringRef ClangExecutable, StringRef TargetTriple,
DiagnosticsEngine &Diags,
- IntrusiveRefCntPtr<vfs::FileSystem> VFS = nullptr);
+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr);
/// @name Accessors
/// @{
@@ -298,7 +294,7 @@ public:
const DiagnosticsEngine &getDiags() const { return Diags; }
- vfs::FileSystem &getVFS() const { return *VFS; }
+ llvm::vfs::FileSystem &getVFS() const { return *VFS; }
bool getCheckInputsExist() const { return CheckInputsExist; }
@@ -363,6 +359,7 @@ public:
/// ParseArgStrings - Parse the given list of strings into an
/// ArgList.
llvm::opt::InputArgList ParseArgStrings(ArrayRef<const char *> Args,
+ bool IsClCompatMode,
bool &ContainsError);
/// BuildInputs - Construct the list of inputs and their types from
@@ -508,6 +505,10 @@ public:
/// GCC goes to extra lengths here to be a bit more robust.
std::string GetTemporaryPath(StringRef Prefix, StringRef Suffix) const;
+ /// GetTemporaryDirectory - Return the pathname of a temporary directory to
+ /// use as part of compilation; the directory will have the given prefix.
+ std::string GetTemporaryDirectory(StringRef Prefix) const;
+
/// Return the pathname of the pch file in clang-cl mode.
std::string GetClPchPath(Compilation &C, StringRef BaseName) const;
@@ -553,7 +554,7 @@ private:
/// Get bitmasks for which option flags to include and exclude based on
/// the driver mode.
- std::pair<unsigned, unsigned> getIncludeExcludeOptionFlagMasks() const;
+ std::pair<unsigned, unsigned> getIncludeExcludeOptionFlagMasks(bool IsClCompatMode) const;
/// Helper used in BuildJobsForAction. Doesn't use the cache when building
/// jobs specifically for the given action, but will use the cache when
diff --git a/include/clang/Driver/DriverDiagnostic.h b/include/clang/Driver/DriverDiagnostic.h
index 680338a2ea7a..ad160ec6c64f 100644
--- a/include/clang/Driver/DriverDiagnostic.h
+++ b/include/clang/Driver/DriverDiagnostic.h
@@ -10,19 +10,6 @@
#ifndef LLVM_CLANG_DRIVER_DRIVERDIAGNOSTIC_H
#define LLVM_CLANG_DRIVER_DRIVERDIAGNOSTIC_H
-#include "clang/Basic/Diagnostic.h"
-
-namespace clang {
- namespace diag {
- enum {
-#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
- SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
-#define DRIVERSTART
-#include "clang/Basic/DiagnosticDriverKinds.inc"
-#undef DIAG
- NUM_BUILTIN_DRIVER_DIAGNOSTICS
- };
- } // end namespace diag
-} // end namespace clang
+#include "clang/Basic/DiagnosticDriver.h"
#endif
diff --git a/include/clang/Driver/Job.h b/include/clang/Driver/Job.h
index 47d9e992ba50..870a31c52093 100644
--- a/include/clang/Driver/Job.h
+++ b/include/clang/Driver/Job.h
@@ -29,9 +29,6 @@ class Action;
class InputInfo;
class Tool;
-// Re-export this as clang::driver::ArgStringList.
-using llvm::opt::ArgStringList;
-
struct CrashReportInfo {
StringRef Filename;
StringRef VFSPath;
@@ -59,6 +56,9 @@ class Command {
/// The list of program arguments which are inputs.
llvm::opt::ArgStringList InputFilenames;
+ /// Whether to print the input filenames when executing.
+ bool PrintInputFilenames = false;
+
/// Response file name, if this command is set to use one, or nullptr
/// otherwise
const char *ResponseFile = nullptr;
@@ -128,6 +128,9 @@ public:
/// Print a command argument, and optionally quote it.
static void printArg(llvm::raw_ostream &OS, StringRef Arg, bool Quote);
+
+ /// Set whether to print the input filenames when executing.
+ void setPrintInputFilenames(bool P) { PrintInputFilenames = P; }
};
/// Like Command, but with a fallback which is executed in case
@@ -135,7 +138,8 @@ public:
class FallbackCommand : public Command {
public:
FallbackCommand(const Action &Source_, const Tool &Creator_,
- const char *Executable_, const ArgStringList &Arguments_,
+ const char *Executable_,
+ const llvm::opt::ArgStringList &Arguments_,
ArrayRef<InputInfo> Inputs,
std::unique_ptr<Command> Fallback_);
@@ -153,7 +157,8 @@ private:
class ForceSuccessCommand : public Command {
public:
ForceSuccessCommand(const Action &Source_, const Tool &Creator_,
- const char *Executable_, const ArgStringList &Arguments_,
+ const char *Executable_,
+ const llvm::opt::ArgStringList &Arguments_,
ArrayRef<InputInfo> Inputs);
void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index 2470638bec66..f02a7190f5a7 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -258,10 +258,6 @@ def rsp_quoting : Joined<["--"], "rsp-quoting=">, Group<internal_driver_Group>,
def ccc_gcc_name : Separate<["-"], "ccc-gcc-name">, InternalDriverOpt,
HelpText<"Name for native GCC compiler">,
MetaVarName<"<gcc-path>">;
-def ccc_pch_is_pch : Flag<["-"], "ccc-pch-is-pch">, InternalDriverOpt,
- HelpText<"Use lazy PCH for precompiled headers">;
-def ccc_pch_is_pth : Flag<["-"], "ccc-pch-is-pth">, InternalDriverOpt,
- HelpText<"Use pretokenized headers for precompiled headers">;
class InternalDebugOpt : Group<internal_debug_Group>,
Flags<[DriverOption, HelpHidden, CoreOption]>;
@@ -584,9 +580,11 @@ def fno_cuda_flush_denormals_to_zero : Flag<["-"], "fno-cuda-flush-denormals-to-
def fcuda_approx_transcendentals : Flag<["-"], "fcuda-approx-transcendentals">,
Flags<[CC1Option]>, HelpText<"Use approximate transcendental functions">;
def fno_cuda_approx_transcendentals : Flag<["-"], "fno-cuda-approx-transcendentals">;
-def fcuda_rdc : Flag<["-"], "fcuda-rdc">, Flags<[CC1Option]>,
+def fgpu_rdc : Flag<["-"], "fgpu-rdc">, Flags<[CC1Option]>,
HelpText<"Generate relocatable device code, also known as separate compilation mode.">;
-def fno_cuda_rdc : Flag<["-"], "fno-cuda-rdc">;
+def fno_gpu_rdc : Flag<["-"], "fno-gpu-rdc">;
+def : Flag<["-"], "fcuda-rdc">, Alias<fgpu_rdc>;
+def : Flag<["-"], "fno-cuda-rdc">, Alias<fno_gpu_rdc>;
def fcuda_short_ptr : Flag<["-"], "fcuda-short-ptr">, Flags<[CC1Option]>,
HelpText<"Use 32-bit pointers for accessing const/local/shared address spaces.">;
def fno_cuda_short_ptr : Flag<["-"], "fno-cuda-short-ptr">;
@@ -596,6 +594,8 @@ def hip_device_lib_EQ : Joined<["--"], "hip-device-lib=">, Group<Link_Group>,
HelpText<"HIP device library">;
def fhip_dump_offload_linker_script : Flag<["-"], "fhip-dump-offload-linker-script">,
Group<f_Group>, Flags<[NoArgumentUnused, HelpHidden]>;
+def libomptarget_nvptx_path_EQ : Joined<["--"], "libomptarget-nvptx-path=">, Group<i_Group>,
+ HelpText<"Path to libomptarget-nvptx libraries">;
def dA : Flag<["-"], "dA">, Group<d_Group>;
def dD : Flag<["-"], "dD">, Group<d_Group>, Flags<[CC1Option]>,
HelpText<"Print macro definitions in -E mode in addition to normal output">;
@@ -639,8 +639,10 @@ def fapple_kext : Flag<["-"], "fapple-kext">, Group<f_Group>, Flags<[CC1Option]>
HelpText<"Use Apple's kernel extensions ABI">;
def fapple_pragma_pack : Flag<["-"], "fapple-pragma-pack">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Enable Apple gcc-compatible #pragma pack handling">;
-def shared_libsan : Flag<["-"], "shared-libsan">;
-def static_libsan : Flag<["-"], "static-libsan">;
+def shared_libsan : Flag<["-"], "shared-libsan">,
+ HelpText<"Dynamically link the sanitizer runtime">;
+def static_libsan : Flag<["-"], "static-libsan">,
+ HelpText<"Statically link the sanitizer runtime">;
def : Flag<["-"], "shared-libasan">, Alias<shared_libsan>;
def fasm : Flag<["-"], "fasm">, Group<f_Group>;
@@ -673,7 +675,7 @@ def fno_coroutines_ts : Flag <["-"], "fno-coroutines-ts">, Group<f_Group>,
Flags<[DriverOption]>;
def fembed_bitcode_EQ : Joined<["-"], "fembed-bitcode=">,
- Group<f_Group>, Flags<[DriverOption, CC1Option]>, MetaVarName<"<option>">,
+ Group<f_Group>, Flags<[DriverOption, CC1Option, CC1AsOption]>, MetaVarName<"<option>">,
HelpText<"Embed LLVM bitcode (option: off, all, bitcode, marker)">;
def fembed_bitcode : Flag<["-"], "fembed-bitcode">, Group<f_Group>,
Alias<fembed_bitcode_EQ>, AliasArgs<["all"]>,
@@ -729,6 +731,11 @@ def fprofile_instr_use : Flag<["-"], "fprofile-instr-use">, Group<f_Group>,
def fprofile_instr_use_EQ : Joined<["-"], "fprofile-instr-use=">,
Group<f_Group>, Flags<[CoreOption]>,
HelpText<"Use instrumentation data for profile-guided optimization">;
+def fprofile_remapping_file_EQ : Joined<["-"], "fprofile-remapping-file=">,
+ Group<f_Group>, Flags<[CC1Option, CoreOption]>, MetaVarName<"<file>">,
+ HelpText<"Use the remappings described in <file> to match the profile data against names in the program">;
+def fprofile_remapping_file : Separate<["-"], "fprofile-remapping-file">,
+ Group<f_Group>, Flags<[CoreOption]>, Alias<fprofile_remapping_file_EQ>;
def fcoverage_mapping : Flag<["-"], "fcoverage-mapping">,
Group<f_Group>, Flags<[CC1Option, CoreOption]>,
HelpText<"Generate coverage mapping to enable code coverage analysis">;
@@ -757,6 +764,12 @@ def fno_profile_instr_use : Flag<["-"], "fno-profile-instr-use">,
HelpText<"Disable using instrumentation data for profile-guided optimization">;
def fno_profile_use : Flag<["-"], "fno-profile-use">,
Alias<fno_profile_instr_use>;
+def fprofile_filter_files_EQ : Joined<["-"], "fprofile-filter-files=">,
+ Group<f_Group>, Flags<[CC1Option, CoreOption]>,
+ HelpText<"Instrument only functions from files where names match any regex separated by a semi-colon">;
+def fprofile_exclude_files_EQ : Joined<["-"], "fprofile-exclude-files=">,
+ Group<f_Group>, Flags<[CC1Option, CoreOption]>,
+ HelpText<"Instrument only functions from files where names don't match all the regexes separated by a semi-colon">;
def faddrsig : Flag<["-"], "faddrsig">, Group<f_Group>, Flags<[CoreOption, CC1Option]>,
HelpText<"Emit an address-significance table">;
@@ -786,6 +799,12 @@ def fcomment_block_commands : CommaJoined<["-"], "fcomment-block-commands=">, Gr
HelpText<"Treat each comma separated argument in <arg> as a documentation comment block command">,
MetaVarName<"<arg>">;
def fparse_all_comments : Flag<["-"], "fparse-all-comments">, Group<f_clang_Group>, Flags<[CC1Option]>;
+def frecord_command_line : Flag<["-"], "frecord-command-line">,
+ Group<f_clang_Group>;
+def fno_record_command_line : Flag<["-"], "fno-record-command-line">,
+ Group<f_clang_Group>;
+def : Flag<["-"], "frecord-gcc-switches">, Alias<frecord_command_line>;
+def : Flag<["-"], "fno-record-gcc-switches">, Alias<fno_record_command_line>;
def fcommon : Flag<["-"], "fcommon">, Group<f_Group>;
def fcompile_resource_EQ : Joined<["-"], "fcompile-resource=">, Group<f_Group>;
def fcomplete_member_pointers : Flag<["-"], "fcomplete-member-pointers">, Group<f_clang_Group>,
@@ -794,15 +813,17 @@ def fcomplete_member_pointers : Flag<["-"], "fcomplete-member-pointers">, Group<
def fno_complete_member_pointers : Flag<["-"], "fno-complete-member-pointers">, Group<f_clang_Group>,
Flags<[CoreOption]>,
HelpText<"Do not require member pointer base types to be complete if they would be significant under the Microsoft ABI">;
+def fcf_runtime_abi_EQ : Joined<["-"], "fcf-runtime-abi=">, Group<f_Group>,
+ Flags<[CC1Option]>;
def fconstant_cfstrings : Flag<["-"], "fconstant-cfstrings">, Group<f_Group>;
def fconstant_string_class_EQ : Joined<["-"], "fconstant-string-class=">, Group<f_Group>;
def fconstexpr_depth_EQ : Joined<["-"], "fconstexpr-depth=">, Group<f_Group>;
def fconstexpr_steps_EQ : Joined<["-"], "fconstexpr-steps=">, Group<f_Group>;
def fconstexpr_backtrace_limit_EQ : Joined<["-"], "fconstexpr-backtrace-limit=">,
Group<f_Group>;
-def fno_crash_diagnostics : Flag<["-"], "fno-crash-diagnostics">, Group<f_clang_Group>, Flags<[NoArgumentUnused]>,
+def fno_crash_diagnostics : Flag<["-"], "fno-crash-diagnostics">, Group<f_clang_Group>, Flags<[NoArgumentUnused, CoreOption]>,
HelpText<"Disable auto-generation of preprocessed source files and a script for reproduction during a clang crash">;
-def fcrash_diagnostics_dir : Joined<["-"], "fcrash-diagnostics-dir=">, Group<f_clang_Group>, Flags<[NoArgumentUnused]>;
+def fcrash_diagnostics_dir : Joined<["-"], "fcrash-diagnostics-dir=">, Group<f_clang_Group>, Flags<[NoArgumentUnused, CoreOption]>;
def fcreate_profile : Flag<["-"], "fcreate-profile">, Group<f_Group>;
def fcxx_exceptions: Flag<["-"], "fcxx-exceptions">, Group<f_Group>,
HelpText<"Enable C++ exceptions">, Flags<[CC1Option]>;
@@ -893,11 +914,19 @@ def fforce_enable_int128 : Flag<["-"], "fforce-enable-int128">,
def fno_force_enable_int128 : Flag<["-"], "fno-force-enable-int128">,
Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Disable support for int128_t type">;
-
+def fkeep_static_consts : Flag<["-"], "fkeep-static-consts">, Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Keep static const variables even if unused">;
def ffixed_point : Flag<["-"], "ffixed-point">, Group<f_Group>,
Flags<[CC1Option]>, HelpText<"Enable fixed point types">;
def fno_fixed_point : Flag<["-"], "fno-fixed-point">, Group<f_Group>,
HelpText<"Disable fixed point types">;
+def fcxx_static_destructors : Flag<["-"], "fc++-static-destructors">,
+ Group<f_Group>,
+ HelpText<"Enable C++ static destructor registration (the default)">;
+def fno_cxx_static_destructors : Flag<["-"], "fno-c++-static-destructors">,
+ Group<f_Group>,
+ Flags<[CC1Option]>,
+ HelpText<"Disable C++ static destructor registration">;
// Begin sanitizer flags. These should all be core options exposed in all driver
// modes.
@@ -950,17 +979,29 @@ def fno_sanitize_address_use_after_scope : Flag<["-"], "fno-sanitize-address-use
Group<f_clang_Group>,
Flags<[CoreOption, DriverOption]>,
HelpText<"Disable use-after-scope detection in AddressSanitizer">;
-def fsanitize_address_poison_class_member_array_new_cookie
- : Flag<[ "-" ], "fsanitize-address-poison-class-member-array-new-cookie">,
+def fsanitize_address_poison_custom_array_cookie
+ : Flag<[ "-" ], "fsanitize-address-poison-custom-array-cookie">,
Group<f_clang_Group>,
- HelpText<"Enable poisoning array cookies when using class member operator new[] in AddressSanitizer">;
-def fno_sanitize_address_poison_class_member_array_new_cookie
- : Flag<[ "-" ], "fno-sanitize-address-poison-class-member-array-new-cookie">,
+ HelpText<"Enable poisoning array cookies when using custom operator new[] in AddressSanitizer">;
+def fno_sanitize_address_poison_custom_array_cookie
+ : Flag<[ "-" ], "fno-sanitize-address-poison-custom-array-cookie">,
Group<f_clang_Group>,
- HelpText<"Disable poisoning array cookies when using class member operator new[] in AddressSanitizer">;
+ HelpText<"Disable poisoning array cookies when using custom operator new[] in AddressSanitizer">;
def fsanitize_address_globals_dead_stripping : Flag<["-"], "fsanitize-address-globals-dead-stripping">,
Group<f_clang_Group>,
HelpText<"Enable linker dead stripping of globals in AddressSanitizer">;
+def fsanitize_address_use_odr_indicator
+ : Flag<["-"], "fsanitize-address-use-odr-indicator">,
+ Group<f_clang_Group>,
+ HelpText<"Enable ODR indicator globals to avoid false ODR violation reports in partially sanitized programs at the cost of an increase in binary size">;
+def fno_sanitize_address_use_odr_indicator
+ : Flag<["-"], "fno-sanitize-address-use-odr-indicator">,
+ Group<f_clang_Group>,
+ HelpText<"Disable ODR indicator globals">;
+def fsanitize_hwaddress_abi_EQ
+ : Joined<["-"], "fsanitize-hwaddress-abi=">,
+ Group<f_clang_Group>,
+ HelpText<"Select the HWAddressSanitizer ABI to target (interceptor or platform, default interceptor)">;
def fsanitize_recover : Flag<["-"], "fsanitize-recover">, Group<f_clang_Group>;
def fno_sanitize_recover : Flag<["-"], "fno-sanitize-recover">,
Flags<[CoreOption, DriverOption]>,
@@ -1442,6 +1483,10 @@ def fno_zero_initialized_in_bss : Flag<["-"], "fno-zero-initialized-in-bss">, Gr
def fobjc_arc : Flag<["-"], "fobjc-arc">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Synthesize retain and release calls for Objective-C pointers">;
def fno_objc_arc : Flag<["-"], "fno-objc-arc">, Group<f_Group>;
+def fobjc_convert_messages_to_runtime_calls :
+ Flag<["-"], "fobjc-convert-messages-to-runtime-calls">, Group<f_Group>;
+def fno_objc_convert_messages_to_runtime_calls :
+ Flag<["-"], "fno-objc-convert-messages-to-runtime-calls">, Group<f_Group>, Flags<[CC1Option]>;
def fobjc_arc_exceptions : Flag<["-"], "fobjc-arc-exceptions">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Use EH-safe code when synthesizing retains and releases in -fobjc-arc">;
def fno_objc_arc_exceptions : Flag<["-"], "fno-objc-arc-exceptions">, Group<f_Group>;
@@ -1488,7 +1533,7 @@ def fobjc_weak : Flag<["-"], "fobjc-weak">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Enable ARC-style weak references in Objective-C">;
// Objective-C ABI options.
-def fobjc_runtime_EQ : Joined<["-"], "fobjc-runtime=">, Group<f_Group>, Flags<[CC1Option]>,
+def fobjc_runtime_EQ : Joined<["-"], "fobjc-runtime=">, Group<f_Group>, Flags<[CC1Option, CoreOption]>,
HelpText<"Specify the target Objective-C runtime kind and version">;
def fobjc_abi_version_EQ : Joined<["-"], "fobjc-abi-version=">, Group<f_Group>;
def fobjc_nonfragile_abi_version_EQ : Joined<["-"], "fobjc-nonfragile-abi-version=">, Group<f_Group>;
@@ -1521,6 +1566,18 @@ def fopenmp_cuda_mode : Flag<["-"], "fopenmp-cuda-mode">, Group<f_Group>,
Flags<[CC1Option, NoArgumentUnused, HelpHidden]>;
def fno_openmp_cuda_mode : Flag<["-"], "fno-openmp-cuda-mode">, Group<f_Group>,
Flags<[NoArgumentUnused, HelpHidden]>;
+def fopenmp_cuda_force_full_runtime : Flag<["-"], "fopenmp-cuda-force-full-runtime">, Group<f_Group>,
+ Flags<[CC1Option, NoArgumentUnused, HelpHidden]>;
+def fno_openmp_cuda_force_full_runtime : Flag<["-"], "fno-openmp-cuda-force-full-runtime">, Group<f_Group>,
+ Flags<[NoArgumentUnused, HelpHidden]>;
+def fopenmp_cuda_number_of_sm_EQ : Joined<["-"], "fopenmp-cuda-number-of-sm=">, Group<f_Group>,
+ Flags<[CC1Option, NoArgumentUnused, HelpHidden]>;
+def fopenmp_cuda_blocks_per_sm_EQ : Joined<["-"], "fopenmp-cuda-blocks-per-sm=">, Group<f_Group>,
+ Flags<[CC1Option, NoArgumentUnused, HelpHidden]>;
+def fopenmp_optimistic_collapse : Flag<["-"], "fopenmp-optimistic-collapse">, Group<f_Group>,
+ Flags<[CC1Option, NoArgumentUnused, HelpHidden]>;
+def fno_openmp_optimistic_collapse : Flag<["-"], "fno-openmp-optimistic-collapse">, Group<f_Group>,
+ Flags<[NoArgumentUnused, HelpHidden]>;
def fno_optimize_sibling_calls : Flag<["-"], "fno-optimize-sibling-calls">, Group<f_Group>;
def foptimize_sibling_calls : Flag<["-"], "foptimize-sibling-calls">, Group<f_Group>;
def fno_escaping_block_tail_calls : Flag<["-"], "fno-escaping-block-tail-calls">, Group<f_Group>, Flags<[CC1Option]>;
@@ -1571,7 +1628,7 @@ def fshort_enums : Flag<["-"], "fshort-enums">, Group<f_Group>, Flags<[CC1Option
HelpText<"Allocate to an enum type only as many bytes as it needs for the declared range of possible values">;
def fchar8__t : Flag<["-"], "fchar8_t">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Enable C++ builtin type char8_t">;
-def fno_char8__t : Flag<["-"], "fno-char8_t">, Group<f_Group>,
+def fno_char8__t : Flag<["-"], "fno-char8_t">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Disable C++ builtin type char8_t">;
def fshort_wchar : Flag<["-"], "fshort-wchar">, Group<f_Group>,
HelpText<"Force wchar_t to be a short unsigned int">;
@@ -1590,11 +1647,24 @@ def fno_signed_char : Flag<["-"], "fno-signed-char">, Group<f_Group>,
Flags<[CC1Option]>, HelpText<"Char is unsigned">;
def fsplit_stack : Flag<["-"], "fsplit-stack">, Group<f_Group>;
def fstack_protector_all : Flag<["-"], "fstack-protector-all">, Group<f_Group>,
- HelpText<"Force the usage of stack protectors for all functions">;
+ HelpText<"Enable stack protectors for all functions">;
def fstack_protector_strong : Flag<["-"], "fstack-protector-strong">, Group<f_Group>,
- HelpText<"Use a strong heuristic to apply stack protectors to functions">;
+ HelpText<"Enable stack protectors for some functions vulnerable to stack smashing. "
+ "Compared to -fstack-protector, this uses a stronger heuristic "
+ "that includes functions containing arrays of any size (and any type), "
+ "as well as any calls to alloca or the taking of an address from a local variable">;
def fstack_protector : Flag<["-"], "fstack-protector">, Group<f_Group>,
- HelpText<"Enable stack protectors for functions potentially vulnerable to stack smashing">;
+ HelpText<"Enable stack protectors for some functions vulnerable to stack smashing. "
+ "This uses a loose heuristic which considers functions vulnerable "
+ "if they contain a char (or 8bit integer) array or constant sized calls to "
+ "alloca, which are of greater size than ssp-buffer-size (default: 8 bytes). "
+ "All variable sized calls to alloca are considered vulnerable">;
+def ftrivial_auto_var_init : Joined<["-"], "ftrivial-auto-var-init=">, Group<f_Group>,
+ Flags<[CC1Option]>, HelpText<"Initialize trivial automatic stack variables: uninitialized (default)"
+ " | pattern">, Values<"uninitialized,pattern">;
+def enable_trivial_var_init_zero : Joined<["-"], "enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang">,
+ Flags<[CC1Option]>,
+ HelpText<"Trivial automatic variable initialization to zero is only here for benchmarks, it'll eventually be removed, and I'm OK with that because I'm only using it to benchmark">;
def fstandalone_debug : Flag<["-"], "fstandalone-debug">, Group<f_Group>, Flags<[CoreOption]>,
HelpText<"Emit full debug info for all types used by the program">;
def fno_standalone_debug : Flag<["-"], "fno-standalone-debug">, Group<f_Group>, Flags<[CoreOption]>,
@@ -1699,11 +1769,18 @@ def fvisibility_inlines_hidden : Flag<["-"], "fvisibility-inlines-hidden">, Grou
def fvisibility_ms_compat : Flag<["-"], "fvisibility-ms-compat">, Group<f_Group>,
HelpText<"Give global types 'default' visibility and global functions and "
"variables 'hidden' visibility by default">;
+def fvisibility_global_new_delete_hidden : Flag<["-"], "fvisibility-global-new-delete-hidden">, Group<f_Group>,
+ HelpText<"Give global C++ operator new and delete declarations hidden visibility">, Flags<[CC1Option]>;
def fwhole_program_vtables : Flag<["-"], "fwhole-program-vtables">, Group<f_Group>,
Flags<[CoreOption, CC1Option]>,
HelpText<"Enables whole-program vtable optimization. Requires -flto">;
def fno_whole_program_vtables : Flag<["-"], "fno-whole-program-vtables">, Group<f_Group>,
Flags<[CoreOption]>;
+def fsplit_lto_unit : Flag<["-"], "fsplit-lto-unit">, Group<f_Group>,
+ Flags<[CoreOption, CC1Option]>,
+ HelpText<"Enables splitting of the LTO unit.">;
+def fno_split_lto_unit : Flag<["-"], "fno-split-lto-unit">, Group<f_Group>,
+ Flags<[CoreOption]>;
def fforce_emit_vtables : Flag<["-"], "fforce-emit-vtables">, Group<f_Group>,
Flags<[CC1Option]>,
HelpText<"Emits more virtual tables to improve devirtualization">;
@@ -1751,6 +1828,10 @@ def fdebug_types_section: Flag <["-"], "fdebug-types-section">, Group<f_Group>,
Flags<[CC1Option]>, HelpText<"Place debug types in their own section (ELF Only)">;
def fno_debug_types_section: Flag<["-"], "fno-debug-types-section">, Group<f_Group>,
Flags<[CC1Option]>;
+def fdebug_ranges_base_address: Flag <["-"], "fdebug-ranges-base-address">, Group<f_Group>,
+ Flags<[CC1Option]>, HelpText<"Use DWARF base address selection entries in debug_ranges">;
+def fno_debug_ranges_base_address: Flag <["-"], "fno-debug-ranges-base-address">, Group<f_Group>,
+ Flags<[CC1Option]>;
def fsplit_dwarf_inlining: Flag <["-"], "fsplit-dwarf-inlining">, Group<f_Group>,
Flags<[CC1Option]>, HelpText<"Provide minimal debug info in the object/executable to facilitate online symbolication/stack traces in the absence of .dwo/.dwp files when using Split DWARF">;
def fno_split_dwarf_inlining: Flag<["-"], "fno-split-dwarf-inlining">, Group<f_Group>,
@@ -1763,6 +1844,8 @@ def g_Flag : Flag<["-"], "g">, Group<g_Group>,
HelpText<"Generate source-level debug information">;
def gline_tables_only : Flag<["-"], "gline-tables-only">, Group<gN_Group>,
Flags<[CoreOption]>, HelpText<"Emit debug line number tables only">;
+def gline_directives_only : Flag<["-"], "gline-directives-only">, Group<gN_Group>,
+ Flags<[CoreOption]>, HelpText<"Emit debug line info directives only">;
def gmlt : Flag<["-"], "gmlt">, Alias<gline_tables_only>;
def g0 : Flag<["-"], "g0">, Group<gN_Group>;
def g1 : Flag<["-"], "g1">, Group<gN_Group>, Alias<gline_tables_only>;
@@ -1783,9 +1866,15 @@ def gdwarf_4 : Flag<["-"], "gdwarf-4">, Group<g_Group>,
HelpText<"Generate source-level debug information with dwarf version 4">;
def gdwarf_5 : Flag<["-"], "gdwarf-5">, Group<g_Group>,
HelpText<"Generate source-level debug information with dwarf version 5">;
+
def gcodeview : Flag<["-"], "gcodeview">,
HelpText<"Generate CodeView debug information">,
Flags<[CC1Option, CC1AsOption, CoreOption]>;
+def gcodeview_ghash : Flag<["-"], "gcodeview-ghash">,
+ HelpText<"Emit type record hashes in a .debug$H section">,
+ Flags<[CC1Option, CoreOption]>;
+def gno_codeview_ghash : Flag<["-"], "gno-codeview-ghash">, Flags<[CoreOption]>;
+
// Equivalent to our default dwarf version. Forces usual dwarf emission when
// CodeView is enabled.
def gdwarf : Flag<["-"], "gdwarf">, Alias<gdwarf_4>, Flags<[CoreOption]>;
@@ -1797,16 +1886,24 @@ def gcoff : Joined<["-"], "gcoff">, Group<g_Group>, Flags<[Unsupported]>;
def gxcoff : Joined<["-"], "gxcoff">, Group<g_Group>, Flags<[Unsupported]>;
def gvms : Joined<["-"], "gvms">, Group<g_Group>, Flags<[Unsupported]>;
def gtoggle : Flag<["-"], "gtoggle">, Group<g_flags_Group>, Flags<[Unsupported]>;
-def grecord_gcc_switches : Flag<["-"], "grecord-gcc-switches">, Group<g_flags_Group>;
-def gno_record_gcc_switches : Flag<["-"], "gno-record-gcc-switches">,
+def grecord_command_line : Flag<["-"], "grecord-command-line">,
+ Group<g_flags_Group>;
+def gno_record_command_line : Flag<["-"], "gno-record-command-line">,
Group<g_flags_Group>;
+def : Flag<["-"], "grecord-gcc-switches">, Alias<grecord_command_line>;
+def : Flag<["-"], "gno-record-gcc-switches">, Alias<gno_record_command_line>;
def gstrict_dwarf : Flag<["-"], "gstrict-dwarf">, Group<g_flags_Group>;
def gno_strict_dwarf : Flag<["-"], "gno-strict-dwarf">, Group<g_flags_Group>;
def gcolumn_info : Flag<["-"], "gcolumn-info">, Group<g_flags_Group>, Flags<[CoreOption]>;
def gno_column_info : Flag<["-"], "gno-column-info">, Group<g_flags_Group>, Flags<[CoreOption]>;
def gsplit_dwarf : Flag<["-"], "gsplit-dwarf">, Group<g_flags_Group>;
+def gsplit_dwarf_EQ : Joined<["-"], "gsplit-dwarf=">, Group<g_flags_Group>,
+ HelpText<"Set DWARF fission mode to either 'split' or 'single'">,
+ Values<"split,single">;
def ggnu_pubnames : Flag<["-"], "ggnu-pubnames">, Group<g_flags_Group>, Flags<[CC1Option]>;
def gno_gnu_pubnames : Flag<["-"], "gno-gnu-pubnames">, Group<g_flags_Group>, Flags<[CC1Option]>;
+def gpubnames : Flag<["-"], "gpubnames">, Group<g_flags_Group>, Flags<[CC1Option]>;
+def gno_pubnames : Flag<["-"], "gno-pubnames">, Group<g_flags_Group>, Flags<[CC1Option]>;
def gdwarf_aranges : Flag<["-"], "gdwarf-aranges">, Group<g_flags_Group>;
def gmodules : Flag <["-"], "gmodules">, Group<gN_Group>,
HelpText<"Generate debug info with external references to clang modules"
@@ -1913,7 +2010,7 @@ def mappletvsimulator_version_min_EQ : Joined<["-"], "mappletvsimulator-version-
def mwatchos_version_min_EQ : Joined<["-"], "mwatchos-version-min=">, Group<m_Group>;
def mwatchos_simulator_version_min_EQ : Joined<["-"], "mwatchos-simulator-version-min=">;
def mwatchsimulator_version_min_EQ : Joined<["-"], "mwatchsimulator-version-min=">, Alias<mwatchos_simulator_version_min_EQ>;
-def march_EQ : Joined<["-"], "march=">, Group<m_Group>;
+def march_EQ : Joined<["-"], "march=">, Group<m_Group>, Flags<[CoreOption]>;
def masm_EQ : Joined<["-"], "masm=">, Group<m_Group>, Flags<[DriverOption]>;
def mcmodel_EQ : Joined<["-"], "mcmodel=">, Group<m_Group>;
def mimplicit_it_EQ : Joined<["-"], "mimplicit-it=">, Group<m_Group>;
@@ -1938,6 +2035,7 @@ def mfloat_abi_EQ : Joined<["-"], "mfloat-abi=">, Group<m_Group>, Values<"soft,s
def mfpmath_EQ : Joined<["-"], "mfpmath=">, Group<m_Group>;
def mfpu_EQ : Joined<["-"], "mfpu=">, Group<m_Group>;
def mhwdiv_EQ : Joined<["-"], "mhwdiv=">, Group<m_Group>;
+def mhwmult_EQ : Joined<["-"], "mhwmult=">, Group<m_Group>;
def mglobal_merge : Flag<["-"], "mglobal-merge">, Group<m_Group>, Flags<[CC1Option]>,
HelpText<"Enable merging of globals">;
def mhard_float : Flag<["-"], "mhard-float">, Group<m_Group>;
@@ -1984,11 +2082,20 @@ def mno_global_merge : Flag<["-"], "mno-global-merge">, Group<m_Group>, Flags<[C
def mno_pascal_strings : Flag<["-"], "mno-pascal-strings">,
Alias<fno_pascal_strings>;
def mno_red_zone : Flag<["-"], "mno-red-zone">, Group<m_Group>;
+def mno_tls_direct_seg_refs : Flag<["-"], "mno-tls-direct-seg-refs">, Group<m_Group>, Flags<[CC1Option]>,
+ HelpText<"Disable direct TLS access through segment registers">;
def mno_relax_all : Flag<["-"], "mno-relax-all">, Group<m_Group>;
def mno_rtd: Flag<["-"], "mno-rtd">, Group<m_Group>;
def mno_soft_float : Flag<["-"], "mno-soft-float">, Group<m_Group>;
def mno_stackrealign : Flag<["-"], "mno-stackrealign">, Group<m_Group>;
+def mretpoline : Flag<["-"], "mretpoline">, Group<m_Group>, Flags<[CoreOption,DriverOption]>;
+def mno_retpoline : Flag<["-"], "mno-retpoline">, Group<m_Group>, Flags<[CoreOption,DriverOption]>;
+def mspeculative_load_hardening : Flag<["-"], "mspeculative-load-hardening">,
+ Group<m_Group>, Flags<[CoreOption,CC1Option]>;
+def mno_speculative_load_hardening : Flag<["-"], "mno-speculative-load-hardening">,
+ Group<m_Group>, Flags<[CoreOption]>;
+
def mrelax : Flag<["-"], "mrelax">, Group<m_riscv_Features_Group>,
HelpText<"Enable linker relaxation">;
def mno_relax : Flag<["-"], "mno-relax">, Group<m_riscv_Features_Group>,
@@ -2025,12 +2132,23 @@ def mfix_cortex_a53_835769 : Flag<["-"], "mfix-cortex-a53-835769">,
def mno_fix_cortex_a53_835769 : Flag<["-"], "mno-fix-cortex-a53-835769">,
Group<m_aarch64_Features_Group>,
HelpText<"Don't workaround Cortex-A53 erratum 835769 (AArch64 only)">;
-def ffixed_x18 : Flag<["-"], "ffixed-x18">, Group<m_aarch64_Features_Group>,
- HelpText<"Reserve the x18 register (AArch64 only)">;
-def ffixed_x20 : Flag<["-"], "ffixed-x20">, Group<m_aarch64_Features_Group>,
- HelpText<"Reserve the x20 register (AArch64 only)">;
+foreach i = {1-7,18,20} in
+ def ffixed_x#i : Flag<["-"], "ffixed-x"#i>, Group<m_aarch64_Features_Group>,
+ HelpText<"Reserve the "#i#" register (AArch64 only)">;
+
+foreach i = {8-15,18} in
+ def fcall_saved_x#i : Flag<["-"], "fcall-saved-x"#i>, Group<m_aarch64_Features_Group>,
+ HelpText<"Make the x"#i#" register call-saved (AArch64 only)">;
+
+def msign_return_address_EQ : Joined<["-"], "msign-return-address=">,
+ Flags<[CC1Option]>, Group<m_Group>, Values<"none,all,non-leaf">,
+ HelpText<"Select return address signing scope">;
+def mbranch_protection_EQ : Joined<["-"], "mbranch-protection=">,
+ HelpText<"Enforce targets of indirect branches and function returns">;
def msimd128 : Flag<["-"], "msimd128">, Group<m_wasm_Features_Group>;
+def munimplemented_simd128 : Flag<["-"], "munimplemented-simd128">, Group<m_wasm_Features_Group>;
+def mno_unimplemented_simd128 : Flag<["-"], "mno-unimplemented-simd128">, Group<m_wasm_Features_Group>;
def mno_simd128 : Flag<["-"], "mno-simd128">, Group<m_wasm_Features_Group>;
def mnontrapping_fptoint : Flag<["-"], "mnontrapping-fptoint">, Group<m_wasm_Features_Group>;
def mno_nontrapping_fptoint : Flag<["-"], "mno-nontrapping-fptoint">, Group<m_wasm_Features_Group>;
@@ -2044,10 +2162,19 @@ def mamdgpu_debugger_abi : Joined<["-"], "mamdgpu-debugger-abi=">,
Group<m_Group>,
HelpText<"Generate additional code for specified <version> of debugger ABI (AMDGPU only)">,
MetaVarName<"<version>">;
+
+def mcode_object_v3 : Flag<["-"], "mcode-object-v3">, Group<m_amdgpu_Features_Group>,
+ HelpText<"Enable code object v3 (AMDGPU only)">;
+def mno_code_object_v3 : Flag<["-"], "mno-code-object-v3">, Group<m_amdgpu_Features_Group>,
+ HelpText<"Disable code object v3 (AMDGPU only)">;
def mxnack : Flag<["-"], "mxnack">, Group<m_amdgpu_Features_Group>,
HelpText<"Enable XNACK (AMDGPU only)">;
def mno_xnack : Flag<["-"], "mno-xnack">, Group<m_amdgpu_Features_Group>,
HelpText<"Disable XNACK (AMDGPU only)">;
+def msram_ecc : Flag<["-"], "msram-ecc">, Group<m_amdgpu_Features_Group>,
+ HelpText<"Enable SRAM ECC (AMDGPU only)">;
+def mno_sram_ecc : Flag<["-"], "mno-sram-ecc">, Group<m_amdgpu_Features_Group>,
+ HelpText<"Disable SRAM ECC (AMDGPU only)">;
def faltivec : Flag<["-"], "faltivec">, Group<f_Group>, Flags<[DriverOption]>;
def fno_altivec : Flag<["-"], "fno-altivec">, Group<f_Group>, Flags<[DriverOption]>;
@@ -2125,6 +2252,8 @@ def momit_leaf_frame_pointer : Flag<["-"], "momit-leaf-frame-pointer">, Group<m_
def moslib_EQ : Joined<["-"], "moslib=">, Group<m_Group>;
def mpascal_strings : Flag<["-"], "mpascal-strings">, Alias<fpascal_strings>;
def mred_zone : Flag<["-"], "mred-zone">, Group<m_Group>;
+def mtls_direct_seg_refs : Flag<["-"], "mtls-direct-seg-refs">, Group<m_Group>,
+ HelpText<"Enable direct TLS access through segment registers (default)">;
def mregparm_EQ : Joined<["-"], "mregparm=">, Group<m_Group>;
def mrelax_all : Flag<["-"], "mrelax-all">, Group<m_Group>, Flags<[CC1Option,CC1AsOption]>,
HelpText<"(integrated-as) Relax all machine instructions">;
@@ -2348,6 +2477,10 @@ def print_multi_directory : Flag<["-", "--"], "print-multi-directory">;
def print_multi_lib : Flag<["-", "--"], "print-multi-lib">;
def print_multi_os_directory : Flag<["-", "--"], "print-multi-os-directory">,
Flags<[Unsupported]>;
+def print_target_triple : Flag<["-", "--"], "print-target-triple">,
+ HelpText<"Print the normalized target triple">;
+def print_effective_triple : Flag<["-", "--"], "print-effective-triple">,
+ HelpText<"Print the effective target triple">;
def print_prog_name_EQ : Joined<["-", "--"], "print-prog-name=">,
HelpText<"Print the full program path of <name>">, MetaVarName<"<name>">;
def print_resource_dir : Flag<["-", "--"], "print-resource-dir">,
@@ -2607,8 +2740,6 @@ def _ : Joined<["--"], "">, Flags<[Unsupported]>;
// Hexagon feature flags.
def mieee_rnd_near : Flag<["-"], "mieee-rnd-near">,
Group<m_hexagon_Features_Group>;
-def mv4 : Flag<["-"], "mv4">, Group<m_hexagon_Features_Group>,
- Alias<mcpu_EQ>, AliasArgs<["hexagonv4"]>;
def mv5 : Flag<["-"], "mv5">, Group<m_hexagon_Features_Group>, Alias<mcpu_EQ>,
AliasArgs<["hexagonv5"]>;
def mv55 : Flag<["-"], "mv55">, Group<m_hexagon_Features_Group>,
@@ -2619,6 +2750,8 @@ def mv62 : Flag<["-"], "mv62">, Group<m_hexagon_Features_Group>,
Alias<mcpu_EQ>, AliasArgs<["hexagonv62"]>;
def mv65 : Flag<["-"], "mv65">, Group<m_hexagon_Features_Group>,
Alias<mcpu_EQ>, AliasArgs<["hexagonv65"]>;
+def mv66 : Flag<["-"], "mv66">, Group<m_hexagon_Features_Group>,
+ Alias<mcpu_EQ>, AliasArgs<["hexagonv66"]>;
def mhexagon_hvx : Flag<["-"], "mhvx">, Group<m_hexagon_Features_HVX_Group>,
HelpText<"Enable Hexagon Vector eXtensions">;
def mhexagon_hvx_EQ : Joined<["-"], "mhvx=">,
@@ -2806,8 +2939,6 @@ def mxsaves : Flag<["-"], "mxsaves">, Group<m_x86_Features_Group>;
def mno_xsaves : Flag<["-"], "mno-xsaves">, Group<m_x86_Features_Group>;
def mshstk : Flag<["-"], "mshstk">, Group<m_x86_Features_Group>;
def mno_shstk : Flag<["-"], "mno-shstk">, Group<m_x86_Features_Group>;
-def mretpoline : Flag<["-"], "mretpoline">, Group<m_x86_Features_Group>;
-def mno_retpoline : Flag<["-"], "mno-retpoline">, Group<m_x86_Features_Group>;
def mretpoline_external_thunk : Flag<["-"], "mretpoline-external-thunk">, Group<m_x86_Features_Group>;
def mno_retpoline_external_thunk : Flag<["-"], "mno-retpoline-external-thunk">, Group<m_x86_Features_Group>;
diff --git a/include/clang/Driver/SanitizerArgs.h b/include/clang/Driver/SanitizerArgs.h
index d144e488b56b..e590a49deea3 100644
--- a/include/clang/Driver/SanitizerArgs.h
+++ b/include/clang/Driver/SanitizerArgs.h
@@ -36,7 +36,10 @@ class SanitizerArgs {
int AsanFieldPadding = 0;
bool SharedRuntime = false;
bool AsanUseAfterScope = true;
+ bool AsanPoisonCustomArrayCookie = false;
bool AsanGlobalsDeadStripping = false;
+ bool AsanUseOdrIndicator = false;
+ std::string HwasanAbi;
bool LinkCXXRuntimes = false;
bool NeedPIE = false;
bool SafeStackRuntime = false;
@@ -78,8 +81,10 @@ class SanitizerArgs {
bool requiresPIE() const;
bool needsUnwindTables() const;
+ bool needsLTO() const;
bool linkCXXRuntimes() const { return LinkCXXRuntimes; }
bool hasCrossDsoCfi() const { return CfiCrossDso; }
+ bool hasAnySanitizer() const { return !Sanitizers.empty(); }
void addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs, types::ID InputType) const;
};
diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h
index 2f9c2c190e32..d5f75b827110 100644
--- a/include/clang/Driver/ToolChain.h
+++ b/include/clang/Driver/ToolChain.h
@@ -10,7 +10,9 @@
#ifndef LLVM_CLANG_DRIVER_TOOLCHAIN_H
#define LLVM_CLANG_DRIVER_TOOLCHAIN_H
+#include "clang/Basic/DebugInfoOptions.h"
#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
#include "clang/Basic/Sanitizers.h"
#include "clang/Driver/Action.h"
#include "clang/Driver/Multilib.h"
@@ -36,17 +38,16 @@ class ArgList;
class DerivedArgList;
} // namespace opt
-} // namespace llvm
-
-namespace clang {
-
-class ObjCRuntime;
-
namespace vfs {
class FileSystem;
} // namespace vfs
+} // namespace llvm
+
+namespace clang {
+
+class ObjCRuntime;
namespace driver {
@@ -116,6 +117,9 @@ private:
const RTTIMode CachedRTTIMode;
+ /// The list of toolchain specific path prefixes to search for libraries.
+ path_list LibraryPaths;
+
/// The list of toolchain specific path prefixes to search for files.
path_list FilePaths;
@@ -146,6 +150,7 @@ private:
protected:
MultilibSet Multilibs;
+ Multilib SelectedMultilib;
ToolChain(const Driver &D, const llvm::Triple &T,
const llvm::opt::ArgList &Args);
@@ -179,7 +184,7 @@ public:
// Accessors
const Driver &getDriver() const { return D; }
- vfs::FileSystem &getVFS() const;
+ llvm::vfs::FileSystem &getVFS() const;
const llvm::Triple &getTriple() const { return Triple; }
/// Get the toolchain's aux triple, if it has one.
@@ -213,6 +218,9 @@ public:
return EffectiveTriple;
}
+ path_list &getLibraryPaths() { return LibraryPaths; }
+ const path_list &getLibraryPaths() const { return LibraryPaths; }
+
path_list &getFilePaths() { return FilePaths; }
const path_list &getFilePaths() const { return FilePaths; }
@@ -221,6 +229,8 @@ public:
const MultilibSet &getMultilibs() const { return Multilibs; }
+ const Multilib &getMultilib() const { return SelectedMultilib; }
+
const SanitizerArgs& getSanitizerArgs() const;
const XRayArgs& getXRayArgs() const;
@@ -340,6 +350,12 @@ public:
return 0;
}
+ /// Get the default trivial automatic variable initialization.
+ virtual LangOptions::TrivialAutoVarInitKind
+ GetDefaultTrivialAutoVarInit() const {
+ return LangOptions::TrivialAutoVarInitKind::Uninitialized;
+ }
+
/// GetDefaultLinker - Get the default linker to use.
virtual const char *getDefaultLinker() const { return "ld"; }
@@ -372,6 +388,9 @@ public:
/// needsProfileRT - returns true if instrumentation profile is on.
static bool needsProfileRT(const llvm::opt::ArgList &Args);
+ /// Returns true if gcov instrumentation (-fprofile-arcs or --coverage) is on.
+ static bool needsGCovInstrumentation(const llvm::opt::ArgList &Args);
+
/// IsUnwindTablesDefault - Does this tool chain use -funwind-tables
/// by default.
virtual bool IsUnwindTablesDefault(const llvm::opt::ArgList &Args) const;
@@ -394,6 +413,11 @@ public:
/// Complain if this tool chain doesn't support Objective-C ARC.
virtual void CheckObjCARC() const {}
+ /// Get the default debug info format. Typically, this is DWARF.
+ virtual codegenoptions::DebugInfoFormat getDefaultDebugFormat() const {
+ return codegenoptions::DIF_DWARF;
+ }
+
/// UseDwarfDebugFlags - Embed the compile options to clang into the Dwarf
/// compile unit information.
virtual bool UseDwarfDebugFlags() const { return false; }
@@ -418,6 +442,10 @@ public:
return true;
}
+ /// Adjust debug information kind considering all passed options.
+ virtual void adjustDebugInfoKind(codegenoptions::DebugInfoKind &DebugInfoKind,
+ const llvm::opt::ArgList &Args) const {}
+
/// GetExceptionModel - Return the tool chain exception model.
virtual llvm::ExceptionHandling
GetExceptionModel(const llvm::opt::ArgList &Args) const;
diff --git a/include/clang/Driver/Types.def b/include/clang/Driver/Types.def
index c23f1f13361f..c25bc4b08084 100644
--- a/include/clang/Driver/Types.def
+++ b/include/clang/Driver/Types.def
@@ -101,4 +101,5 @@ TYPE("image", Image, INVALID, "out", "")
TYPE("dSYM", dSYM, INVALID, "dSYM", "A")
TYPE("dependencies", Dependencies, INVALID, "d", "")
TYPE("cuda-fatbin", CUDA_FATBIN, INVALID, "fatbin","A")
+TYPE("hip-fatbin", HIP_FATBIN, INVALID, "hipfb", "A")
TYPE("none", Nothing, INVALID, nullptr, "u")
diff --git a/include/clang/Format/Format.h b/include/clang/Format/Format.h
index 85dda948c11f..cb37b0c890c3 100644
--- a/include/clang/Format/Format.h
+++ b/include/clang/Format/Format.h
@@ -22,16 +22,18 @@
#include "llvm/Support/Regex.h"
#include <system_error>
+namespace llvm {
+namespace vfs {
+class FileSystem;
+}
+} // namespace llvm
+
namespace clang {
class Lexer;
class SourceManager;
class DiagnosticConsumer;
-namespace vfs {
-class FileSystem;
-}
-
namespace format {
enum class ParseError { Success = 0, Error, Unsuitable };
@@ -531,20 +533,17 @@ struct FormatStyle {
/// \code
/// try {
/// foo();
- /// } catch () {
+ /// }
+ /// catch () {
/// }
/// void foo() { bar(); }
- /// class foo
- /// {
+ /// class foo {
/// };
/// if (foo()) {
- /// } else {
/// }
- /// enum X : int
- /// {
- /// A,
- /// B
- /// };
+ /// else {
+ /// }
+ /// enum X : int { A, B };
/// \endcode
BS_Stroustrup,
/// Always break before braces.
@@ -1051,6 +1050,16 @@ struct FormatStyle {
/// For example: BOOST_FOREACH.
std::vector<std::string> ForEachMacros;
+ /// A vector of macros that should be interpreted as complete
+ /// statements.
+ ///
+ /// Typical macros are expressions, and require a semi-colon to be
+ /// added; sometimes this is not the case, and this allows to make
+ /// clang-format aware of such cases.
+ ///
+ /// For example: Q_UNUSED
+ std::vector<std::string> StatementMacros;
+
tooling::IncludeStyle IncludeStyle;
/// Indent case labels one level from the switch statement.
@@ -1120,6 +1129,37 @@ struct FormatStyle {
/// \endcode
bool IndentWrappedFunctionNames;
+ /// A vector of prefixes ordered by the desired groups for Java imports.
+ ///
+ /// Each group is seperated by a newline. Static imports will also follow the
+ /// same grouping convention above all non-static imports. One group's prefix
+ /// can be a subset of another - the longest prefix is always matched. Within
+ /// a group, the imports are ordered lexicographically.
+ ///
+ /// In the .clang-format configuration file, this can be configured like
+ /// in the following yaml example. This will result in imports being
+ /// formatted as in the Java example below.
+ /// \code{.yaml}
+ /// JavaImportGroups: ['com.example', 'com', 'org']
+ /// \endcode
+ ///
+ /// \code{.java}
+ /// import static com.example.function1;
+ ///
+ /// import static com.test.function2;
+ ///
+ /// import static org.example.function3;
+ ///
+ /// import com.example.ClassA;
+ /// import com.example.Test;
+ /// import com.example.a.ClassB;
+ ///
+ /// import com.test.ClassC;
+ ///
+ /// import org.example.ClassD;
+ /// \endcode
+ std::vector<std::string> JavaImportGroups;
+
/// Quotation styles for JavaScript strings. Does not affect template
/// strings.
enum JavaScriptQuoteStyle {
@@ -1724,6 +1764,7 @@ struct FormatStyle {
IndentPPDirectives == R.IndentPPDirectives &&
IndentWidth == R.IndentWidth && Language == R.Language &&
IndentWrappedFunctionNames == R.IndentWrappedFunctionNames &&
+ JavaImportGroups == R.JavaImportGroups &&
JavaScriptQuotes == R.JavaScriptQuotes &&
JavaScriptWrapImports == R.JavaScriptWrapImports &&
KeepEmptyLinesAtTheStartOfBlocks ==
@@ -1766,7 +1807,7 @@ struct FormatStyle {
SpacesInParentheses == R.SpacesInParentheses &&
SpacesInSquareBrackets == R.SpacesInSquareBrackets &&
Standard == R.Standard && TabWidth == R.TabWidth &&
- UseTab == R.UseTab;
+ StatementMacros == R.StatementMacros && UseTab == R.UseTab;
}
llvm::Optional<FormatStyle> GetLanguageStyle(LanguageKind Language) const;
@@ -1999,7 +2040,7 @@ extern const char *DefaultFallbackStyle;
llvm::Expected<FormatStyle> getStyle(StringRef StyleName, StringRef FileName,
StringRef FallbackStyle,
StringRef Code = "",
- vfs::FileSystem *FS = nullptr);
+ llvm::vfs::FileSystem *FS = nullptr);
// Guesses the language from the ``FileName`` and ``Code`` to be formatted.
// Defaults to FormatStyle::LK_Cpp.
diff --git a/include/clang/Frontend/ASTConsumers.h b/include/clang/Frontend/ASTConsumers.h
index 2a13527df135..c2144da054f0 100644
--- a/include/clang/Frontend/ASTConsumers.h
+++ b/include/clang/Frontend/ASTConsumers.h
@@ -50,10 +50,6 @@ std::unique_ptr<ASTConsumer> CreateASTDeclNodeLister();
// function declarations to stderr.
std::unique_ptr<ASTConsumer> CreateASTViewer();
-// DeclContext printer: prints out the DeclContext tree in human-readable form
-// to stderr; this is intended for debugging.
-std::unique_ptr<ASTConsumer> CreateDeclContextPrinter();
-
} // end clang namespace
#endif
diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h
index ba145965462f..d0b532cf2d34 100644
--- a/include/clang/Frontend/ASTUnit.h
+++ b/include/clang/Frontend/ASTUnit.h
@@ -51,6 +51,11 @@ namespace llvm {
class MemoryBuffer;
+namespace vfs {
+
+class FileSystem;
+
+} // namespace vfs
} // namespace llvm
namespace clang {
@@ -75,12 +80,6 @@ class PreprocessorOptions;
class Sema;
class TargetInfo;
-namespace vfs {
-
-class FileSystem;
-
-} // namespace vfs
-
/// \brief Enumerates the available scopes for skipping function bodies.
enum class SkipFunctionBodiesScope { None, Preamble, PreambleAndMainFile };
@@ -365,12 +364,12 @@ private:
bool Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer,
- IntrusiveRefCntPtr<vfs::FileSystem> VFS);
+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS);
std::unique_ptr<llvm::MemoryBuffer> getMainBufferWithPrecompiledPreamble(
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
CompilerInvocation &PreambleInvocationIn,
- IntrusiveRefCntPtr<vfs::FileSystem> VFS, bool AllowRebuild = true,
+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, bool AllowRebuild = true,
unsigned MaxLines = 0);
void RealizeTopLevelDeclsFromPreamble();
@@ -698,17 +697,17 @@ private:
/// of this translation unit should be precompiled, to improve the performance
/// of reparsing. Set to zero to disable preambles.
///
- /// \param VFS - A vfs::FileSystem to be used for all file accesses. Note that
- /// preamble is saved to a temporary directory on a RealFileSystem, so in order
- /// for it to be loaded correctly, VFS should have access to it(i.e., be an
- /// overlay over RealFileSystem).
+ /// \param VFS - A llvm::vfs::FileSystem to be used for all file accesses.
+ /// Note that preamble is saved to a temporary directory on a RealFileSystem,
+ /// so in order for it to be loaded correctly, VFS should have access to
+ /// it(i.e., be an overlay over RealFileSystem).
///
/// \returns \c true if a catastrophic failure occurred (which means that the
/// \c ASTUnit itself is invalid), or \c false otherwise.
bool LoadFromCompilerInvocation(
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
unsigned PrecompilePreambleAfterNParses,
- IntrusiveRefCntPtr<vfs::FileSystem> VFS);
+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS);
public:
/// Create an ASTUnit from a source file, via a CompilerInvocation
@@ -798,10 +797,11 @@ public:
/// (e.g. because the PCH could not be loaded), this accepts the ASTUnit
/// mainly to allow the caller to see the diagnostics.
///
- /// \param VFS - A vfs::FileSystem to be used for all file accesses. Note that
- /// preamble is saved to a temporary directory on a RealFileSystem, so in order
- /// for it to be loaded correctly, VFS should have access to it(i.e., be an
- /// overlay over RealFileSystem). RealFileSystem will be used if \p VFS is nullptr.
+ /// \param VFS - A llvm::vfs::FileSystem to be used for all file accesses.
+ /// Note that preamble is saved to a temporary directory on a RealFileSystem,
+ /// so in order for it to be loaded correctly, VFS should have access to
+ /// it(i.e., be an overlay over RealFileSystem). RealFileSystem will be used
+ /// if \p VFS is nullptr.
///
// FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we
// shouldn't need to specify them at construction time.
@@ -823,22 +823,22 @@ public:
bool ForSerialization = false,
llvm::Optional<StringRef> ModuleFormat = llvm::None,
std::unique_ptr<ASTUnit> *ErrAST = nullptr,
- IntrusiveRefCntPtr<vfs::FileSystem> VFS = nullptr);
+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr);
/// Reparse the source files using the same command-line options that
/// were originally used to produce this translation unit.
///
- /// \param VFS - A vfs::FileSystem to be used for all file accesses. Note that
- /// preamble is saved to a temporary directory on a RealFileSystem, so in order
- /// for it to be loaded correctly, VFS should give an access to this(i.e. be an
- /// overlay over RealFileSystem). FileMgr->getVirtualFileSystem() will be used if
- /// \p VFS is nullptr.
+ /// \param VFS - A llvm::vfs::FileSystem to be used for all file accesses.
+ /// Note that preamble is saved to a temporary directory on a RealFileSystem,
+ /// so in order for it to be loaded correctly, VFS should give an access to
+ /// this(i.e. be an overlay over RealFileSystem).
+ /// FileMgr->getVirtualFileSystem() will be used if \p VFS is nullptr.
///
/// \returns True if a failure occurred that causes the ASTUnit not to
/// contain any translation-unit information, false otherwise.
bool Reparse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
ArrayRef<RemappedFile> RemappedFiles = None,
- IntrusiveRefCntPtr<vfs::FileSystem> VFS = nullptr);
+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr);
/// Free data that will be re-generated on the next parse.
///
diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h
index 818c733982d9..83ce079d5e23 100644
--- a/include/clang/Frontend/CompilerInstance.h
+++ b/include/clang/Frontend/CompilerInstance.h
@@ -22,6 +22,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/BuryPointer.h"
#include <cassert>
#include <list>
#include <memory>
@@ -83,7 +84,7 @@ class CompilerInstance : public ModuleLoader {
IntrusiveRefCntPtr<TargetInfo> AuxTarget;
/// The virtual file system.
- IntrusiveRefCntPtr<vfs::FileSystem> VirtualFileSystem;
+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> VirtualFileSystem;
/// The file manager.
IntrusiveRefCntPtr<FileManager> FileMgr;
@@ -384,7 +385,7 @@ public:
bool hasVirtualFileSystem() const { return VirtualFileSystem != nullptr; }
- vfs::FileSystem &getVirtualFileSystem() const {
+ llvm::vfs::FileSystem &getVirtualFileSystem() const {
assert(hasVirtualFileSystem() &&
"Compiler instance has no virtual file system");
return *VirtualFileSystem;
@@ -394,7 +395,7 @@ public:
///
/// \note Most clients should use setFileManager, which will implicitly reset
/// the virtual file system to the one contained in the file manager.
- void setVirtualFileSystem(IntrusiveRefCntPtr<vfs::FileSystem> FS) {
+ void setVirtualFileSystem(IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS) {
VirtualFileSystem = std::move(FS);
}
@@ -411,7 +412,7 @@ public:
}
void resetAndLeakFileManager() {
- BuryPointer(FileMgr.get());
+ llvm::BuryPointer(FileMgr.get());
FileMgr.resetWithoutRelease();
}
@@ -431,7 +432,7 @@ public:
}
void resetAndLeakSourceManager() {
- BuryPointer(SourceMgr.get());
+ llvm::BuryPointer(SourceMgr.get());
SourceMgr.resetWithoutRelease();
}
@@ -453,7 +454,7 @@ public:
std::shared_ptr<Preprocessor> getPreprocessorPtr() { return PP; }
void resetAndLeakPreprocessor() {
- BuryPointer(new std::shared_ptr<Preprocessor>(PP));
+ llvm::BuryPointer(new std::shared_ptr<Preprocessor>(PP));
}
/// Replace the current preprocessor.
@@ -471,7 +472,7 @@ public:
}
void resetAndLeakASTContext() {
- BuryPointer(Context.get());
+ llvm::BuryPointer(Context.get());
Context.resetWithoutRelease();
}
diff --git a/include/clang/Frontend/CompilerInvocation.h b/include/clang/Frontend/CompilerInvocation.h
index 1d421f09fdcc..a1874655b040 100644
--- a/include/clang/Frontend/CompilerInvocation.h
+++ b/include/clang/Frontend/CompilerInvocation.h
@@ -10,11 +10,11 @@
#ifndef LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H
#define LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H
+#include "clang/Basic/CodeGenOptions.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/FileSystemOptions.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/LangOptions.h"
-#include "clang/Frontend/CodeGenOptions.h"
#include "clang/Frontend/DependencyOutputOptions.h"
#include "clang/Frontend/FrontendOptions.h"
#include "clang/Frontend/LangStandard.h"
@@ -35,6 +35,12 @@ class ArgList;
} // namespace opt
+namespace vfs {
+
+class FileSystem;
+
+} // namespace vfs
+
} // namespace llvm
namespace clang {
@@ -217,20 +223,13 @@ public:
/// @}
};
-namespace vfs {
-
-class FileSystem;
-
-} // namespace vfs
-
-IntrusiveRefCntPtr<vfs::FileSystem>
+IntrusiveRefCntPtr<llvm::vfs::FileSystem>
createVFSFromCompilerInvocation(const CompilerInvocation &CI,
DiagnosticsEngine &Diags);
-IntrusiveRefCntPtr<vfs::FileSystem>
-createVFSFromCompilerInvocation(const CompilerInvocation &CI,
- DiagnosticsEngine &Diags,
- IntrusiveRefCntPtr<vfs::FileSystem> BaseFS);
+IntrusiveRefCntPtr<llvm::vfs::FileSystem> createVFSFromCompilerInvocation(
+ const CompilerInvocation &CI, DiagnosticsEngine &Diags,
+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS);
} // namespace clang
diff --git a/include/clang/Frontend/FrontendAction.h b/include/clang/Frontend/FrontendAction.h
index 2a4077d34391..22314386e060 100644
--- a/include/clang/Frontend/FrontendAction.h
+++ b/include/clang/Frontend/FrontendAction.h
@@ -48,6 +48,12 @@ protected:
/// @name Implementation Action Interface
/// @{
+ /// Prepare to execute the action on the given CompilerInstance.
+ ///
+ /// This is called before executing the action on any inputs, and can modify
+ /// the configuration as needed (including adjusting the input list).
+ virtual bool PrepareToExecuteAction(CompilerInstance &CI) { return true; }
+
/// Create the AST consumer object for this action, if supported.
///
/// This routine is called as part of BeginSourceFile(), which will
@@ -130,11 +136,18 @@ public:
return CurrentInput;
}
- const StringRef getCurrentFile() const {
+ StringRef getCurrentFile() const {
assert(!CurrentInput.isEmpty() && "No current file!");
return CurrentInput.getFile();
}
+ StringRef getCurrentFileOrBufferName() const {
+ assert(!CurrentInput.isEmpty() && "No current file!");
+ return CurrentInput.isFile()
+ ? CurrentInput.getFile()
+ : CurrentInput.getBuffer()->getBufferIdentifier();
+ }
+
InputKind getCurrentFileKind() const {
assert(!CurrentInput.isEmpty() && "No current file!");
return CurrentInput.getKind();
@@ -190,6 +203,11 @@ public:
/// @name Public Action Interface
/// @{
+ /// Prepare the action to execute on the given compiler instance.
+ bool PrepareToExecute(CompilerInstance &CI) {
+ return PrepareToExecuteAction(CI);
+ }
+
/// Prepare the action for processing the input file \p Input.
///
/// This is run after the options and frontend have been initialized,
diff --git a/include/clang/Frontend/FrontendActions.h b/include/clang/Frontend/FrontendActions.h
index 54539a5b3cee..eb1cd688429d 100644
--- a/include/clang/Frontend/FrontendActions.h
+++ b/include/clang/Frontend/FrontendActions.h
@@ -142,6 +142,19 @@ private:
CreateOutputFile(CompilerInstance &CI, StringRef InFile) override;
};
+class GenerateHeaderModuleAction : public GenerateModuleAction {
+ /// The synthesized module input buffer for the current compilation.
+ std::unique_ptr<llvm::MemoryBuffer> Buffer;
+ std::vector<std::string> ModuleHeaders;
+
+private:
+ bool PrepareToExecuteAction(CompilerInstance &CI) override;
+ bool BeginSourceFileAction(CompilerInstance &CI) override;
+
+ std::unique_ptr<raw_pwrite_stream>
+ CreateOutputFile(CompilerInstance &CI, StringRef InFile) override;
+};
+
class SyntaxOnlyAction : public ASTFrontendAction {
protected:
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
@@ -248,11 +261,6 @@ protected:
void ExecuteAction() override;
};
-class GeneratePTHAction : public PreprocessorFrontendAction {
-protected:
- void ExecuteAction() override;
-};
-
class PreprocessOnlyAction : public PreprocessorFrontendAction {
protected:
void ExecuteAction() override;
diff --git a/include/clang/Frontend/FrontendDiagnostic.h b/include/clang/Frontend/FrontendDiagnostic.h
index 0f37b7ece7e0..14a28845d45a 100644
--- a/include/clang/Frontend/FrontendDiagnostic.h
+++ b/include/clang/Frontend/FrontendDiagnostic.h
@@ -10,19 +10,6 @@
#ifndef LLVM_CLANG_FRONTEND_FRONTENDDIAGNOSTIC_H
#define LLVM_CLANG_FRONTEND_FRONTENDDIAGNOSTIC_H
-#include "clang/Basic/Diagnostic.h"
-
-namespace clang {
- namespace diag {
- enum {
-#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
- SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
-#define FRONTENDSTART
-#include "clang/Basic/DiagnosticFrontendKinds.inc"
-#undef DIAG
- NUM_BUILTIN_FRONTEND_DIAGNOSTICS
- };
- } // end namespace diag
-} // end namespace clang
+#include "clang/Basic/DiagnosticFrontend.h"
#endif
diff --git a/include/clang/Frontend/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h
index 668df83274eb..92191ebd12a6 100644
--- a/include/clang/Frontend/FrontendOptions.h
+++ b/include/clang/Frontend/FrontendOptions.h
@@ -82,12 +82,12 @@ enum ActionKind {
/// Generate pre-compiled module from a C++ module interface file.
GenerateModuleInterface,
+ /// Generate pre-compiled module from a set of header files.
+ GenerateHeaderModule,
+
/// Generate pre-compiled header.
GeneratePCH,
- /// Generate pre-tokenized header.
- GeneratePTH,
-
/// Only execute frontend initialization.
InitOnly,
@@ -103,9 +103,6 @@ enum ActionKind {
/// Run a plugin action, \see ActionName.
PluginAction,
- /// Print DeclContext and their Decls.
- PrintDeclContext,
-
/// Print the "preamble" of the input file
PrintPreamble,
diff --git a/include/clang/Frontend/LangStandards.def b/include/clang/Frontend/LangStandards.def
index 1e895d785d15..0fdd35f32034 100644
--- a/include/clang/Frontend/LangStandards.def
+++ b/include/clang/Frontend/LangStandards.def
@@ -82,9 +82,12 @@ LANGSTANDARD(c17, "c17",
C, "ISO C 2017",
LineComment | C99 | C11 | C17 | Digraphs | HexFloat)
LANGSTANDARD_ALIAS(c17, "iso9899:2017")
+LANGSTANDARD_ALIAS(c17, "c18")
+LANGSTANDARD_ALIAS(c17, "iso9899:2018")
LANGSTANDARD(gnu17, "gnu17",
C, "ISO C 2017 with GNU extensions",
LineComment | C99 | C11 | C17 | Digraphs | GNUMode | HexFloat)
+LANGSTANDARD_ALIAS(gnu17, "gnu18")
// C++ modes
LANGSTANDARD(cxx98, "c++98",
diff --git a/include/clang/Frontend/PCHContainerOperations.h b/include/clang/Frontend/PCHContainerOperations.h
index 7a12ebc862e7..675efbaf56eb 100644
--- a/include/clang/Frontend/PCHContainerOperations.h
+++ b/include/clang/Frontend/PCHContainerOperations.h
@@ -10,110 +10,6 @@
#ifndef LLVM_CLANG_PCH_CONTAINER_OPERATIONS_H
#define LLVM_CLANG_PCH_CONTAINER_OPERATIONS_H
-#include "clang/Basic/Module.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include <memory>
-
-namespace llvm {
-class raw_pwrite_stream;
-}
-
-using llvm::StringRef;
-
-namespace clang {
-
-class ASTConsumer;
-class CodeGenOptions;
-class DiagnosticsEngine;
-class CompilerInstance;
-
-struct PCHBuffer {
- ASTFileSignature Signature;
- llvm::SmallVector<char, 0> Data;
- bool IsComplete;
-};
-
-/// This abstract interface provides operations for creating
-/// containers for serialized ASTs (precompiled headers and clang
-/// modules).
-class PCHContainerWriter {
-public:
- virtual ~PCHContainerWriter() = 0;
- virtual StringRef getFormat() const = 0;
-
- /// Return an ASTConsumer that can be chained with a
- /// PCHGenerator that produces a wrapper file format containing a
- /// serialized AST bitstream.
- virtual std::unique_ptr<ASTConsumer>
- CreatePCHContainerGenerator(CompilerInstance &CI,
- const std::string &MainFileName,
- const std::string &OutputFileName,
- std::unique_ptr<llvm::raw_pwrite_stream> OS,
- std::shared_ptr<PCHBuffer> Buffer) const = 0;
-};
-
-/// This abstract interface provides operations for unwrapping
-/// containers for serialized ASTs (precompiled headers and clang
-/// modules).
-class PCHContainerReader {
-public:
- virtual ~PCHContainerReader() = 0;
- /// Equivalent to the format passed to -fmodule-format=
- virtual StringRef getFormat() const = 0;
-
- /// Returns the serialized AST inside the PCH container Buffer.
- virtual StringRef ExtractPCH(llvm::MemoryBufferRef Buffer) const = 0;
-};
-
-/// Implements write operations for a raw pass-through PCH container.
-class RawPCHContainerWriter : public PCHContainerWriter {
- StringRef getFormat() const override { return "raw"; }
-
- /// Return an ASTConsumer that can be chained with a
- /// PCHGenerator that writes the module to a flat file.
- std::unique_ptr<ASTConsumer>
- CreatePCHContainerGenerator(CompilerInstance &CI,
- const std::string &MainFileName,
- const std::string &OutputFileName,
- std::unique_ptr<llvm::raw_pwrite_stream> OS,
- std::shared_ptr<PCHBuffer> Buffer) const override;
-};
-
-/// Implements read operations for a raw pass-through PCH container.
-class RawPCHContainerReader : public PCHContainerReader {
- StringRef getFormat() const override { return "raw"; }
-
- /// Simply returns the buffer contained in Buffer.
- StringRef ExtractPCH(llvm::MemoryBufferRef Buffer) const override;
-};
-
-/// A registry of PCHContainerWriter and -Reader objects for different formats.
-class PCHContainerOperations {
- llvm::StringMap<std::unique_ptr<PCHContainerWriter>> Writers;
- llvm::StringMap<std::unique_ptr<PCHContainerReader>> Readers;
-public:
- /// Automatically registers a RawPCHContainerWriter and
- /// RawPCHContainerReader.
- PCHContainerOperations();
- void registerWriter(std::unique_ptr<PCHContainerWriter> Writer) {
- Writers[Writer->getFormat()] = std::move(Writer);
- }
- void registerReader(std::unique_ptr<PCHContainerReader> Reader) {
- Readers[Reader->getFormat()] = std::move(Reader);
- }
- const PCHContainerWriter *getWriterOrNull(StringRef Format) {
- return Writers[Format].get();
- }
- const PCHContainerReader *getReaderOrNull(StringRef Format) {
- return Readers[Format].get();
- }
- const PCHContainerReader &getRawReader() {
- return *getReaderOrNull("raw");
- }
-};
-
-}
+#include "clang/Serialization/PCHContainerOperations.h"
#endif
diff --git a/include/clang/Frontend/PrecompiledPreamble.h b/include/clang/Frontend/PrecompiledPreamble.h
index 6abdbe3a1e1b..6c79895ce1b9 100644
--- a/include/clang/Frontend/PrecompiledPreamble.h
+++ b/include/clang/Frontend/PrecompiledPreamble.h
@@ -26,13 +26,12 @@
namespace llvm {
class MemoryBuffer;
-}
-
-namespace clang {
namespace vfs {
class FileSystem;
}
+} // namespace llvm
+namespace clang {
class CompilerInstance;
class CompilerInvocation;
class DeclGroupRef;
@@ -80,7 +79,8 @@ public:
static llvm::ErrorOr<PrecompiledPreamble>
Build(const CompilerInvocation &Invocation,
const llvm::MemoryBuffer *MainFileBuffer, PreambleBounds Bounds,
- DiagnosticsEngine &Diagnostics, IntrusiveRefCntPtr<vfs::FileSystem> VFS,
+ DiagnosticsEngine &Diagnostics,
+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
bool StoreInMemory, PreambleCallbacks &Callbacks);
@@ -99,7 +99,7 @@ public:
/// MainFileBuffer) of the main file.
bool CanReuse(const CompilerInvocation &Invocation,
const llvm::MemoryBuffer *MainFileBuffer, PreambleBounds Bounds,
- vfs::FileSystem *VFS) const;
+ llvm::vfs::FileSystem *VFS) const;
/// Changes options inside \p CI to use PCH from this preamble. Also remaps
/// main file to \p MainFileBuffer and updates \p VFS to ensure the preamble
@@ -110,14 +110,14 @@ public:
/// responsible for making sure the PrecompiledPreamble instance outlives the
/// compiler run and the AST that will be using the PCH.
void AddImplicitPreamble(CompilerInvocation &CI,
- IntrusiveRefCntPtr<vfs::FileSystem> &VFS,
+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> &VFS,
llvm::MemoryBuffer *MainFileBuffer) const;
/// Configure \p CI to use this preamble.
/// Like AddImplicitPreamble, but doesn't assume CanReuse() is true.
/// If this preamble does not match the file, it may parse differently.
void OverridePreamble(CompilerInvocation &CI,
- IntrusiveRefCntPtr<vfs::FileSystem> &VFS,
+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> &VFS,
llvm::MemoryBuffer *MainFileBuffer) const;
private:
@@ -233,15 +233,16 @@ private:
/// Helper function to set up PCH for the preamble into \p CI and \p VFS to
/// with the specified \p Bounds.
void configurePreamble(PreambleBounds Bounds, CompilerInvocation &CI,
- IntrusiveRefCntPtr<vfs::FileSystem> &VFS,
+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> &VFS,
llvm::MemoryBuffer *MainFileBuffer) const;
/// Sets up the PreprocessorOptions and changes VFS, so that PCH stored in \p
/// Storage is accessible to clang. This method is an implementation detail of
/// AddImplicitPreamble.
- static void setupPreambleStorage(const PCHStorage &Storage,
- PreprocessorOptions &PreprocessorOpts,
- IntrusiveRefCntPtr<vfs::FileSystem> &VFS);
+ static void
+ setupPreambleStorage(const PCHStorage &Storage,
+ PreprocessorOptions &PreprocessorOpts,
+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> &VFS);
/// Manages the memory buffer or temporary file that stores the PCH.
PCHStorage Storage;
@@ -286,8 +287,7 @@ public:
};
enum class BuildPreambleError {
- PreambleIsEmpty = 1,
- CouldntCreateTempFile,
+ CouldntCreateTempFile = 1,
CouldntCreateTargetInfo,
BeginSourceFileFailed,
CouldntEmitPCH
diff --git a/include/clang/Frontend/Utils.h b/include/clang/Frontend/Utils.h
index 67912a8dfcdd..89a6b90f293f 100644
--- a/include/clang/Frontend/Utils.h
+++ b/include/clang/Frontend/Utils.h
@@ -16,13 +16,13 @@
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/LLVM.h"
-#include "clang/Basic/VirtualFileSystem.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Option/OptSpecifier.h"
+#include "llvm/Support/VirtualFileSystem.h"
#include <cstdint>
#include <memory>
#include <string>
@@ -134,7 +134,7 @@ class ModuleDependencyCollector : public DependencyCollector {
std::string DestDir;
bool HasErrors = false;
llvm::StringSet<> Seen;
- vfs::YAMLVFSWriter VFSWriter;
+ llvm::vfs::YAMLVFSWriter VFSWriter;
llvm::StringMap<std::string> SymLinkMap;
bool getRealPath(StringRef SrcPath, SmallVectorImpl<char> &Result);
@@ -183,9 +183,6 @@ void AttachHeaderIncludeGen(Preprocessor &PP,
StringRef OutputPath = {},
bool ShowDepth = true, bool MSStyle = false);
-/// Cache tokens for use with PCH. Note that this requires a seekable stream.
-void CacheTokens(Preprocessor &PP, raw_pwrite_stream *OS);
-
/// The ChainedIncludesSource class converts headers to chained PCHs in
/// memory, mainly for testing.
IntrusiveRefCntPtr<ExternalSemaSource>
@@ -201,7 +198,7 @@ std::unique_ptr<CompilerInvocation> createInvocationFromCommandLine(
ArrayRef<const char *> Args,
IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
IntrusiveRefCntPtr<DiagnosticsEngine>(),
- IntrusiveRefCntPtr<vfs::FileSystem> VFS = nullptr);
+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr);
/// Return the value of the last argument as an integer, or a default. If Diags
/// is non-null, emits an error if the argument is given, but non-integral.
@@ -226,14 +223,6 @@ inline uint64_t getLastArgUInt64Value(const llvm::opt::ArgList &Args,
return getLastArgUInt64Value(Args, Id, Default, &Diags);
}
-// When Clang->getFrontendOpts().DisableFree is set we don't delete some of the
-// global objects, but we don't want LeakDetectors to complain, so we bury them
-// in a globally visible array.
-void BuryPointer(const void *Ptr);
-template <typename T> void BuryPointer(std::unique_ptr<T> Ptr) {
- BuryPointer(Ptr.release());
-}
-
// Frontend timing utils
/// If the user specifies the -ftime-report argument on an Clang command line
diff --git a/include/clang/Index/IndexDataConsumer.h b/include/clang/Index/IndexDataConsumer.h
index 6e11455661a0..c79f6be3e13b 100644
--- a/include/clang/Index/IndexDataConsumer.h
+++ b/include/clang/Index/IndexDataConsumer.h
@@ -50,7 +50,12 @@ public:
SourceLocation Loc);
/// \returns true to continue indexing, or false to abort.
+ ///
+ /// This will be called for each module reference in an import decl.
+ /// For "@import MyMod.SubMod", there will be a call for 'MyMod' with the
+ /// 'reference' role, and a call for 'SubMod' with the 'declaration' role.
virtual bool handleModuleOccurence(const ImportDecl *ImportD,
+ const Module *Mod,
SymbolRoleSet Roles, SourceLocation Loc);
virtual void finish() {}
diff --git a/include/clang/Index/IndexSymbol.h b/include/clang/Index/IndexSymbol.h
index 068796141df8..8aaaa695456c 100644
--- a/include/clang/Index/IndexSymbol.h
+++ b/include/clang/Index/IndexSymbol.h
@@ -75,7 +75,7 @@ enum class SymbolSubKind : uint8_t {
UsingValue,
};
-typedef uint8_t SymbolPropertySet;
+typedef uint16_t SymbolPropertySet;
/// Set of properties that provide additional info about a symbol.
enum class SymbolProperty : SymbolPropertySet {
Generic = 1 << 0,
@@ -86,8 +86,10 @@ enum class SymbolProperty : SymbolPropertySet {
IBOutletCollection = 1 << 5,
GKInspectable = 1 << 6,
Local = 1 << 7,
+ /// Symbol is part of a protocol interface.
+ ProtocolInterface = 1 << 8,
};
-static const unsigned SymbolPropertyBitNum = 8;
+static const unsigned SymbolPropertyBitNum = 9;
/// Set of roles that are attributed to symbol occurrences.
///
diff --git a/include/clang/Index/IndexingAction.h b/include/clang/Index/IndexingAction.h
index 0d09c403483d..63e38975ce16 100644
--- a/include/clang/Index/IndexingAction.h
+++ b/include/clang/Index/IndexingAction.h
@@ -12,6 +12,7 @@
#include "clang/Basic/LLVM.h"
#include "clang/Lex/PPCallbacks.h"
+#include "clang/Lex/Preprocessor.h"
#include "llvm/ADT/ArrayRef.h"
#include <memory>
@@ -40,6 +41,10 @@ struct IndexingOptions {
= SystemSymbolFilterKind::DeclarationsOnly;
bool IndexFunctionLocals = false;
bool IndexImplicitInstantiation = false;
+ // Whether to index macro definitions in the Preprocesor when preprocessor
+ // callback is not available (e.g. after parsing has finished). Note that
+ // macro references are not available in Proprocessor.
+ bool IndexMacrosInPreprocessor = false;
};
/// Creates a frontend action that indexes all symbols (macros and AST decls).
@@ -50,13 +55,12 @@ createIndexingAction(std::shared_ptr<IndexDataConsumer> DataConsumer,
std::unique_ptr<FrontendAction> WrappedAction);
/// Recursively indexes all decls in the AST.
-/// Note that this does not index macros.
void indexASTUnit(ASTUnit &Unit, IndexDataConsumer &DataConsumer,
IndexingOptions Opts);
/// Recursively indexes \p Decls.
-/// Note that this does not index macros.
-void indexTopLevelDecls(ASTContext &Ctx, ArrayRef<const Decl *> Decls,
+void indexTopLevelDecls(ASTContext &Ctx, Preprocessor &PP,
+ ArrayRef<const Decl *> Decls,
IndexDataConsumer &DataConsumer, IndexingOptions Opts);
/// Creates a PPCallbacks that indexes macros and feeds macros to \p Consumer.
@@ -65,7 +69,6 @@ std::unique_ptr<PPCallbacks> indexMacrosCallback(IndexDataConsumer &Consumer,
IndexingOptions Opts);
/// Recursively indexes all top-level decls in the module.
-/// FIXME: make this index macros as well.
void indexModuleFile(serialization::ModuleFile &Mod, ASTReader &Reader,
IndexDataConsumer &DataConsumer, IndexingOptions Opts);
diff --git a/include/clang/Index/USRGeneration.h b/include/clang/Index/USRGeneration.h
index 1ece321746a6..f1389ecc9593 100644
--- a/include/clang/Index/USRGeneration.h
+++ b/include/clang/Index/USRGeneration.h
@@ -14,10 +14,13 @@
#include "llvm/ADT/StringRef.h"
namespace clang {
+class ASTContext;
class Decl;
class MacroDefinitionRecord;
+class Module;
class SourceLocation;
class SourceManager;
+class QualType;
namespace index {
@@ -70,8 +73,30 @@ bool generateUSRForMacro(const MacroDefinitionRecord *MD,
bool generateUSRForMacro(StringRef MacroName, SourceLocation Loc,
const SourceManager &SM, SmallVectorImpl<char> &Buf);
+/// Generates a USR for a type.
+///
+/// \return true on error, false on success.
+bool generateUSRForType(QualType T, ASTContext &Ctx, SmallVectorImpl<char> &Buf);
+
+/// Generate a USR for a module, including the USR prefix.
+/// \returns true on error, false on success.
+bool generateFullUSRForModule(const Module *Mod, raw_ostream &OS);
+
+/// Generate a USR for a top-level module name, including the USR prefix.
+/// \returns true on error, false on success.
+bool generateFullUSRForTopLevelModuleName(StringRef ModName, raw_ostream &OS);
+
+/// Generate a USR fragment for a module.
+/// \returns true on error, false on success.
+bool generateUSRFragmentForModule(const Module *Mod, raw_ostream &OS);
+
+/// Generate a USR fragment for a module name.
+/// \returns true on error, false on success.
+bool generateUSRFragmentForModuleName(StringRef ModName, raw_ostream &OS);
+
+
} // namespace index
} // namespace clang
-#endif // LLVM_CLANG_IDE_USRGENERATION_H
+#endif // LLVM_CLANG_INDEX_USRGENERATION_H
diff --git a/include/clang/Lex/CodeCompletionHandler.h b/include/clang/Lex/CodeCompletionHandler.h
index 87089fd7d50b..bef804beed00 100644
--- a/include/clang/Lex/CodeCompletionHandler.h
+++ b/include/clang/Lex/CodeCompletionHandler.h
@@ -14,6 +14,8 @@
#ifndef LLVM_CLANG_LEX_CODECOMPLETIONHANDLER_H
#define LLVM_CLANG_LEX_CODECOMPLETIONHANDLER_H
+#include "llvm/ADT/StringRef.h"
+
namespace clang {
class IdentifierInfo;
@@ -60,6 +62,11 @@ public:
MacroInfo *MacroInfo,
unsigned ArgumentIndex) { }
+ /// Callback invoked when performing code completion inside the filename
+ /// part of an #include directive. (Also #import, #include_next, etc).
+ /// \p Dir is the directory relative to the include path.
+ virtual void CodeCompleteIncludedFile(llvm::StringRef Dir, bool IsAngled) {}
+
/// Callback invoked when performing code completion in a part of the
/// file where we expect natural language, e.g., a comment, string, or
/// \#error directive.
diff --git a/include/clang/Lex/DirectoryLookup.h b/include/clang/Lex/DirectoryLookup.h
index 55065b7d8547..bfb496be5072 100644
--- a/include/clang/Lex/DirectoryLookup.h
+++ b/include/clang/Lex/DirectoryLookup.h
@@ -191,7 +191,7 @@ private:
SmallVectorImpl<char> *RelativePath,
Module *RequestingModule,
ModuleMap::KnownHeader *SuggestedModule,
- bool &InUserSpecifiedSystemHeader) const;
+ bool &InUserSpecifiedSystemFramework) const;
};
diff --git a/include/clang/Lex/HeaderMap.h b/include/clang/Lex/HeaderMap.h
index 58bf79579a6a..793e7edc2752 100644
--- a/include/clang/Lex/HeaderMap.h
+++ b/include/clang/Lex/HeaderMap.h
@@ -71,7 +71,8 @@ class HeaderMap : private HeaderMapImpl {
public:
/// This attempts to load the specified file as a header map. If it doesn't
/// look like a HeaderMap, it gives up and returns null.
- static const HeaderMap *Create(const FileEntry *FE, FileManager &FM);
+ static std::unique_ptr<HeaderMap> Create(const FileEntry *FE,
+ FileManager &FM);
/// Check to see if the specified relative filename is located in this
/// HeaderMap. If so, open it and return its FileEntry. If RawPath is not
diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h
index 6bb0f58f2db9..7c69e219cb57 100644
--- a/include/clang/Lex/HeaderSearch.h
+++ b/include/clang/Lex/HeaderSearch.h
@@ -17,6 +17,7 @@
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/DirectoryLookup.h"
+#include "clang/Lex/HeaderMap.h"
#include "clang/Lex/ModuleMap.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
@@ -38,7 +39,6 @@ class DirectoryEntry;
class ExternalPreprocessorSource;
class FileEntry;
class FileManager;
-class HeaderMap;
class HeaderSearchOptions;
class IdentifierInfo;
class LangOptions;
@@ -55,7 +55,7 @@ struct HeaderFileInfo {
/// True if this is a \#pragma once file.
unsigned isPragmaOnce : 1;
- /// DirInfo - Keep track of whether this is a system header, and if so,
+ /// Keep track of whether this is a system header, and if so,
/// whether it is C++ clean or not. This can be set by the include paths or
/// by \#pragma gcc system_header. This is an instance of
/// SrcMgr::CharacteristicKind.
@@ -219,16 +219,15 @@ class HeaderSearch {
/// name like "Carbon" to the Carbon.framework directory.
llvm::StringMap<FrameworkCacheEntry, llvm::BumpPtrAllocator> FrameworkMap;
- /// IncludeAliases - maps include file names (including the quotes or
+ /// Maps include file names (including the quotes or
/// angle brackets) to other include file names. This is used to support the
/// include_alias pragma for Microsoft compatibility.
using IncludeAliasMap =
llvm::StringMap<std::string, llvm::BumpPtrAllocator>;
std::unique_ptr<IncludeAliasMap> IncludeAliases;
- /// HeaderMaps - This is a mapping from FileEntry -> HeaderMap, uniquing
- /// headermaps. This vector owns the headermap.
- std::vector<std::pair<const FileEntry *, const HeaderMap *>> HeaderMaps;
+ /// This is a mapping from FileEntry -> HeaderMap, uniquing headermaps.
+ std::vector<std::pair<const FileEntry *, std::unique_ptr<HeaderMap>>> HeaderMaps;
/// The mapping between modules and headers.
mutable ModuleMap ModMap;
@@ -264,7 +263,6 @@ public:
const LangOptions &LangOpts, const TargetInfo *Target);
HeaderSearch(const HeaderSearch &) = delete;
HeaderSearch &operator=(const HeaderSearch &) = delete;
- ~HeaderSearch();
/// Retrieve the header-search options with which this header search
/// was initialized.
@@ -314,7 +312,7 @@ public:
(*IncludeAliases)[Source] = Dest;
}
- /// MapHeaderToIncludeAlias - Maps one header file name to a different header
+ /// Maps one header file name to a different header
/// file name, for use with the include_alias pragma. Note that the source
/// file name should include the angle brackets or quotes. Returns StringRef
/// as null if the header cannot be mapped.
@@ -408,7 +406,7 @@ public:
/// HIToolbox is a subframework within Carbon.framework. If so, return
/// the FileEntry for the designated file, otherwise return null.
const FileEntry *LookupSubframeworkHeader(
- StringRef Filename, const FileEntry *RelativeFileEnt,
+ StringRef Filename, const FileEntry *ContextFileEnt,
SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule);
@@ -425,7 +423,7 @@ public:
/// if we should include it.
bool ShouldEnterIncludeFile(Preprocessor &PP, const FileEntry *File,
bool isImport, bool ModulesEnabled,
- Module *CorrespondingModule);
+ Module *M);
/// Return whether the specified file is a normal header,
/// a system header, or a C++ friendly system header.
@@ -448,9 +446,9 @@ public:
}
/// Mark the specified file as part of a module.
- void MarkFileModuleHeader(const FileEntry *File,
+ void MarkFileModuleHeader(const FileEntry *FE,
ModuleMap::ModuleHeaderRole Role,
- bool IsCompiledModuleHeader);
+ bool isCompilingModuleHeader);
/// Increment the count for the number of times the specified
/// FileEntry has been entered.
@@ -479,7 +477,7 @@ public:
/// This routine does not consider the effect of \#import
bool isFileMultipleIncludeGuarded(const FileEntry *File);
- /// CreateHeaderMap - This method returns a HeaderMap for the specified
+ /// This method returns a HeaderMap for the specified
/// FileEntry, uniquing them through the 'HeaderMaps' datastructure.
const HeaderMap *CreateHeaderMap(const FileEntry *FE);
@@ -641,7 +639,7 @@ private:
/// \return \c true if the file can be used, \c false if we are not permitted to
/// find this file due to requirements from \p RequestingModule.
bool findUsableModuleForFrameworkHeader(
- const FileEntry *File, StringRef FrameworkDir, Module *RequestingModule,
+ const FileEntry *File, StringRef FrameworkName, Module *RequestingModule,
ModuleMap::KnownHeader *SuggestedModule, bool IsSystemFramework);
/// Look up the file with the specified name and determine its owning
diff --git a/include/clang/Lex/LexDiagnostic.h b/include/clang/Lex/LexDiagnostic.h
index 5d724c0de879..3a677b834543 100644
--- a/include/clang/Lex/LexDiagnostic.h
+++ b/include/clang/Lex/LexDiagnostic.h
@@ -10,19 +10,6 @@
#ifndef LLVM_CLANG_LEX_LEXDIAGNOSTIC_H
#define LLVM_CLANG_LEX_LEXDIAGNOSTIC_H
-#include "clang/Basic/Diagnostic.h"
-
-namespace clang {
- namespace diag {
- enum {
-#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
- SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
-#define LEXSTART
-#include "clang/Basic/DiagnosticLexKinds.inc"
-#undef DIAG
- NUM_BUILTIN_LEX_DIAGNOSTICS
- };
- } // end namespace diag
-} // end namespace clang
+#include "clang/Basic/DiagnosticLex.h"
#endif
diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h
index 624151ef877b..a9b10b627320 100644
--- a/include/clang/Lex/Lexer.h
+++ b/include/clang/Lex/Lexer.h
@@ -139,7 +139,7 @@ public:
/// with the specified preprocessor managing the lexing process. This lexer
/// assumes that the associated file buffer and Preprocessor objects will
/// outlive it, so it doesn't take ownership of either of them.
- Lexer(FileID FID, const llvm::MemoryBuffer *InputBuffer, Preprocessor &PP);
+ Lexer(FileID FID, const llvm::MemoryBuffer *InputFile, Preprocessor &PP);
/// Lexer constructor - Create a new raw lexer object. This object is only
/// suitable for calls to 'LexFromRawLexer'. This lexer assumes that the
@@ -150,7 +150,7 @@ public:
/// Lexer constructor - Create a new raw lexer object. This object is only
/// suitable for calls to 'LexFromRawLexer'. This lexer assumes that the
/// text range will outlive it, so it doesn't take ownership of it.
- Lexer(FileID FID, const llvm::MemoryBuffer *InputBuffer,
+ Lexer(FileID FID, const llvm::MemoryBuffer *FromFile,
const SourceManager &SM, const LangOptions &LangOpts);
Lexer(const Lexer &) = delete;
@@ -310,8 +310,8 @@ public:
/// location.
static StringRef getSpelling(SourceLocation loc,
SmallVectorImpl<char> &buffer,
- const SourceManager &SourceMgr,
- const LangOptions &LangOpts,
+ const SourceManager &SM,
+ const LangOptions &options,
bool *invalid = nullptr);
/// MeasureTokenLength - Relex the token at the specified location and return
@@ -339,7 +339,7 @@ public:
/// Get the physical length (including trigraphs and escaped newlines) of the
/// first \p Characters characters of the token starting at TokStart.
static unsigned getTokenPrefixLength(SourceLocation TokStart,
- unsigned Characters,
+ unsigned CharNo,
const SourceManager &SM,
const LangOptions &LangOpts);
@@ -711,20 +711,22 @@ private:
bool isHexaLiteral(const char *Start, const LangOptions &LangOpts);
+ void codeCompleteIncludedFile(const char *PathStart,
+ const char *CompletionPoint, bool IsAngled);
/// Read a universal character name.
///
- /// \param CurPtr The position in the source buffer after the initial '\'.
- /// If the UCN is syntactically well-formed (but not necessarily
- /// valid), this parameter will be updated to point to the
- /// character after the UCN.
+ /// \param StartPtr The position in the source buffer after the initial '\'.
+ /// If the UCN is syntactically well-formed (but not
+ /// necessarily valid), this parameter will be updated to
+ /// point to the character after the UCN.
/// \param SlashLoc The position in the source buffer of the '\'.
- /// \param Tok The token being formed. Pass \c nullptr to suppress diagnostics
- /// and handle token formation in the caller.
+ /// \param Result The token being formed. Pass \c nullptr to suppress
+ /// diagnostics and handle token formation in the caller.
///
/// \return The Unicode codepoint specified by the UCN, or 0 if the UCN is
/// invalid.
- uint32_t tryReadUCN(const char *&CurPtr, const char *SlashLoc, Token *Tok);
+ uint32_t tryReadUCN(const char *&StartPtr, const char *SlashLoc, Token *Result);
/// Try to consume a UCN as part of an identifier at the current
/// location.
diff --git a/include/clang/Lex/MacroInfo.h b/include/clang/Lex/MacroInfo.h
index 0cc1cb92e67e..a06de132b496 100644
--- a/include/clang/Lex/MacroInfo.h
+++ b/include/clang/Lex/MacroInfo.h
@@ -395,7 +395,8 @@ public:
/// Find macro definition active in the specified source location. If
/// this macro was not defined there, return NULL.
- const DefInfo findDirectiveAtLoc(SourceLocation L, SourceManager &SM) const;
+ const DefInfo findDirectiveAtLoc(SourceLocation L,
+ const SourceManager &SM) const;
void dump() const;
diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h
index aa519891c1ce..a38c8d7819db 100644
--- a/include/clang/Lex/ModuleMap.h
+++ b/include/clang/Lex/ModuleMap.h
@@ -45,6 +45,8 @@ class SourceManager;
/// A mechanism to observe the actions of the module map parser as it
/// reads module map files.
class ModuleMapCallbacks {
+ virtual void anchor();
+
public:
virtual ~ModuleMapCallbacks() = default;
@@ -92,9 +94,9 @@ class ModuleMap {
/// named LangOpts::CurrentModule, if we've loaded it).
Module *SourceModule = nullptr;
- /// The global module for the current TU, if we still own it. (Ownership is
- /// transferred if/when we create an enclosing module.
- std::unique_ptr<Module> PendingGlobalModule;
+ /// Submodules of the current module that have not yet been attached to it.
+ /// (Ownership is transferred if/when we create an enclosing module.)
+ llvm::SmallVector<std::unique_ptr<Module>, 8> PendingSubmodules;
/// The top-level modules that are known.
llvm::StringMap<Module *> Modules;
@@ -519,8 +521,7 @@ public:
bool IsFramework,
bool IsExplicit);
- /// Create a 'global module' for a C++ Modules TS module interface
- /// unit.
+ /// Create a 'global module' for a C++ Modules TS module interface unit.
///
/// We model the global module as a submodule of the module interface unit.
/// Unfortunately, we can't create the module interface unit's Module until
@@ -537,6 +538,9 @@ public:
Module *createModuleForInterfaceUnit(SourceLocation Loc, StringRef Name,
Module *GlobalModule);
+ /// Create a header module from the specified list of headers.
+ Module *createHeaderModule(StringRef Name, ArrayRef<Module::Header> Headers);
+
/// Infer the contents of a framework module map from the given
/// framework directory.
Module *inferFrameworkModule(const DirectoryEntry *FrameworkDir,
@@ -580,7 +584,7 @@ public:
/// getContainingModuleMapFile().
const FileEntry *getModuleMapFileForUniquing(const Module *M) const;
- void setInferredModuleAllowedBy(Module *M, const FileEntry *ModuleMap);
+ void setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap);
/// Get any module map files other than getModuleMapFileForUniquing(M)
/// that define submodules of a top-level module \p M. This is cheaper than
diff --git a/include/clang/Lex/PPCallbacks.h b/include/clang/Lex/PPCallbacks.h
index 45c2d18da6e2..2448b34c8af4 100644
--- a/include/clang/Lex/PPCallbacks.h
+++ b/include/clang/Lex/PPCallbacks.h
@@ -276,6 +276,12 @@ public:
SourceRange Range) {
}
+ /// Hook called when a '__has_include' or '__has_include_next' directive is
+ /// read.
+ virtual void HasInclude(SourceLocation Loc, StringRef FileName, bool IsAngled,
+ const FileEntry *File,
+ SrcMgr::CharacteristicKind FileType) {}
+
/// Hook called when a source range is skipped.
/// \param Range The SourceRange that was skipped. The range begins at the
/// \#if/\#else directive and ends after the \#endif/\#else directive.
@@ -443,6 +449,13 @@ public:
Second->PragmaDiagnostic(Loc, Namespace, mapping, Str);
}
+ void HasInclude(SourceLocation Loc, StringRef FileName, bool IsAngled,
+ const FileEntry *File,
+ SrcMgr::CharacteristicKind FileType) override {
+ First->HasInclude(Loc, FileName, IsAngled, File, FileType);
+ Second->HasInclude(Loc, FileName, IsAngled, File, FileType);
+ }
+
void PragmaOpenCLExtension(SourceLocation NameLoc, const IdentifierInfo *Name,
SourceLocation StateLoc, unsigned State) override {
First->PragmaOpenCLExtension(NameLoc, Name, StateLoc, State);
diff --git a/include/clang/Lex/PTHLexer.h b/include/clang/Lex/PTHLexer.h
deleted file mode 100644
index 0b84df1434ae..000000000000
--- a/include/clang/Lex/PTHLexer.h
+++ /dev/null
@@ -1,107 +0,0 @@
-//===- PTHLexer.h - Lexer based on Pre-tokenized input ----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the PTHLexer interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LEX_PTHLEXER_H
-#define LLVM_CLANG_LEX_PTHLEXER_H
-
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/TokenKinds.h"
-#include "clang/Lex/PreprocessorLexer.h"
-#include "clang/Lex/Token.h"
-
-namespace clang {
-
-class Preprocessor;
-class PTHManager;
-
-class PTHLexer : public PreprocessorLexer {
- SourceLocation FileStartLoc;
-
- /// TokBuf - Buffer from PTH file containing raw token data.
- const unsigned char* TokBuf;
-
- /// CurPtr - Pointer into current offset of the token buffer where
- /// the next token will be read.
- const unsigned char* CurPtr;
-
- /// LastHashTokPtr - Pointer into TokBuf of the last processed '#'
- /// token that appears at the start of a line.
- const unsigned char* LastHashTokPtr = nullptr;
-
- /// PPCond - Pointer to a side table in the PTH file that provides a
- /// a concise summary of the preprocessor conditional block structure.
- /// This is used to perform quick skipping of conditional blocks.
- const unsigned char* PPCond;
-
- /// CurPPCondPtr - Pointer inside PPCond that refers to the next entry
- /// to process when doing quick skipping of preprocessor blocks.
- const unsigned char* CurPPCondPtr;
-
- /// ReadToken - Used by PTHLexer to read tokens TokBuf.
- void ReadToken(Token &T);
-
- bool LexEndOfFile(Token &Result);
-
- /// PTHMgr - The PTHManager object that created this PTHLexer.
- PTHManager& PTHMgr;
-
- Token EofToken;
-
-protected:
- friend class PTHManager;
-
- /// Create a PTHLexer for the specified token stream.
- PTHLexer(Preprocessor &pp, FileID FID, const unsigned char *D,
- const unsigned char* ppcond, PTHManager &PM);
-
-public:
- PTHLexer(const PTHLexer &) = delete;
- PTHLexer &operator=(const PTHLexer &) = delete;
- ~PTHLexer() override = default;
-
- /// Lex - Return the next token.
- bool Lex(Token &Tok);
-
- void getEOF(Token &Tok);
-
- /// DiscardToEndOfLine - Read the rest of the current preprocessor line as an
- /// uninterpreted string. This switches the lexer out of directive mode.
- void DiscardToEndOfLine();
-
- /// isNextPPTokenLParen - Return 1 if the next unexpanded token will return a
- /// tok::l_paren token, 0 if it is something else and 2 if there are no more
- /// tokens controlled by this lexer.
- unsigned isNextPPTokenLParen() {
- // isNextPPTokenLParen is not on the hot path, and all we care about is
- // whether or not we are at a token with kind tok::eof or tok::l_paren.
- // Just read the first byte from the current token pointer to determine
- // its kind.
- tok::TokenKind x = (tok::TokenKind)*CurPtr;
- return x == tok::eof ? 2 : x == tok::l_paren;
- }
-
- /// IndirectLex - An indirect call to 'Lex' that can be invoked via
- /// the PreprocessorLexer interface.
- void IndirectLex(Token &Result) override { Lex(Result); }
-
- /// getSourceLocation - Return a source location for the token in
- /// the current file.
- SourceLocation getSourceLocation() override;
-
- /// SkipBlock - Used by Preprocessor to skip the current conditional block.
- bool SkipBlock();
-};
-
-} // namespace clang
-
-#endif // LLVM_CLANG_LEX_PTHLEXER_H
diff --git a/include/clang/Lex/PTHManager.h b/include/clang/Lex/PTHManager.h
deleted file mode 100644
index 483b69f23a9c..000000000000
--- a/include/clang/Lex/PTHManager.h
+++ /dev/null
@@ -1,149 +0,0 @@
-//===- PTHManager.h - Manager object for PTH processing ---------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the PTHManager interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LEX_PTHMANAGER_H
-#define LLVM_CLANG_LEX_PTHMANAGER_H
-
-#include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/OnDiskHashTable.h"
-#include <memory>
-
-namespace llvm {
-
-class MemoryBuffer;
-
-} // namespace llvm
-
-namespace clang {
-
-class DiagnosticsEngine;
-class FileSystemStatCache;
-class Preprocessor;
-class PTHLexer;
-
-class PTHManager : public IdentifierInfoLookup {
- friend class PTHLexer;
- friend class PTHStatCache;
-
- class PTHFileLookupTrait;
- class PTHStringLookupTrait;
-
- using PTHStringIdLookup = llvm::OnDiskChainedHashTable<PTHStringLookupTrait>;
- using PTHFileLookup = llvm::OnDiskChainedHashTable<PTHFileLookupTrait>;
-
- /// The memory mapped PTH file.
- std::unique_ptr<const llvm::MemoryBuffer> Buf;
-
- /// Alloc - Allocator used for IdentifierInfo objects.
- llvm::BumpPtrAllocator Alloc;
-
- /// IdMap - A lazily generated cache mapping from persistent identifiers to
- /// IdentifierInfo*.
- std::unique_ptr<IdentifierInfo *[], llvm::FreeDeleter> PerIDCache;
-
- /// FileLookup - Abstract data structure used for mapping between files
- /// and token data in the PTH file.
- std::unique_ptr<PTHFileLookup> FileLookup;
-
- /// IdDataTable - Array representing the mapping from persistent IDs to the
- /// data offset within the PTH file containing the information to
- /// reconsitute an IdentifierInfo.
- const unsigned char* const IdDataTable;
-
- /// SortedIdTable - Abstract data structure mapping from strings to
- /// persistent IDs. This is used by get().
- std::unique_ptr<PTHStringIdLookup> StringIdLookup;
-
- /// NumIds - The number of identifiers in the PTH file.
- const unsigned NumIds;
-
- /// PP - The Preprocessor object that will use this PTHManager to create
- /// PTHLexer objects.
- Preprocessor* PP = nullptr;
-
- /// SpellingBase - The base offset within the PTH memory buffer that
- /// contains the cached spellings for literals.
- const unsigned char* const SpellingBase;
-
- /// OriginalSourceFile - A null-terminated C-string that specifies the name
- /// if the file (if any) that was to used to generate the PTH cache.
- const char* OriginalSourceFile;
-
- /// This constructor is intended to only be called by the static 'Create'
- /// method.
- PTHManager(std::unique_ptr<const llvm::MemoryBuffer> buf,
- std::unique_ptr<PTHFileLookup> fileLookup,
- const unsigned char *idDataTable,
- std::unique_ptr<IdentifierInfo *[], llvm::FreeDeleter> perIDCache,
- std::unique_ptr<PTHStringIdLookup> stringIdLookup, unsigned numIds,
- const unsigned char *spellingBase, const char *originalSourceFile);
-
- /// getSpellingAtPTHOffset - Used by PTHLexer classes to get the cached
- /// spelling for a token.
- unsigned getSpellingAtPTHOffset(unsigned PTHOffset, const char*& Buffer);
-
- /// GetIdentifierInfo - Used to reconstruct IdentifierInfo objects from the
- /// PTH file.
- IdentifierInfo *GetIdentifierInfo(unsigned PersistentID) {
- // Check if the IdentifierInfo has already been resolved.
- if (IdentifierInfo* II = PerIDCache[PersistentID])
- return II;
- return LazilyCreateIdentifierInfo(PersistentID);
- }
- IdentifierInfo* LazilyCreateIdentifierInfo(unsigned PersistentID);
-
-public:
- // The current PTH version.
- enum { Version = 10 };
-
- PTHManager(const PTHManager &) = delete;
- PTHManager &operator=(const PTHManager &) = delete;
- ~PTHManager() override;
-
- /// getOriginalSourceFile - Return the full path to the original header
- /// file name that was used to generate the PTH cache.
- const char* getOriginalSourceFile() const {
- return OriginalSourceFile;
- }
-
- /// get - Return the identifier token info for the specified named identifier.
- /// Unlike the version in IdentifierTable, this returns a pointer instead
- /// of a reference. If the pointer is nullptr then the IdentifierInfo cannot
- /// be found.
- IdentifierInfo *get(StringRef Name) override;
-
- /// Create - This method creates PTHManager objects. The 'file' argument
- /// is the name of the PTH file. This method returns nullptr upon failure.
- static PTHManager *Create(StringRef file, DiagnosticsEngine &Diags);
-
- void setPreprocessor(Preprocessor *pp) { PP = pp; }
-
- /// CreateLexer - Return a PTHLexer that "lexes" the cached tokens for the
- /// specified file. This method returns nullptr if no cached tokens exist.
- /// It is the responsibility of the caller to 'delete' the returned object.
- PTHLexer *CreateLexer(FileID FID);
-
- /// createStatCache - Returns a FileSystemStatCache object for use with
- /// FileManager objects. These objects use the PTH data to speed up
- /// calls to stat by memoizing their results from when the PTH file
- /// was generated.
- std::unique_ptr<FileSystemStatCache> createStatCache();
-};
-
-} // namespace clang
-
-#endif // LLVM_CLANG_LEX_PTHMANAGER_H
diff --git a/include/clang/Lex/Pragma.h b/include/clang/Lex/Pragma.h
index 4d74face5275..fb2942f0916b 100644
--- a/include/clang/Lex/Pragma.h
+++ b/include/clang/Lex/Pragma.h
@@ -113,7 +113,7 @@ public:
bool IsEmpty() const { return Handlers.empty(); }
void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
- Token &FirstToken) override;
+ Token &Tok) override;
PragmaNamespace *getIfNamespace() override { return this; }
};
diff --git a/include/clang/Lex/PreprocessingRecord.h b/include/clang/Lex/PreprocessingRecord.h
index 44d79d9b6229..027dd3ac5d55 100644
--- a/include/clang/Lex/PreprocessingRecord.h
+++ b/include/clang/Lex/PreprocessingRecord.h
@@ -15,6 +15,7 @@
#ifndef LLVM_CLANG_LEX_PREPROCESSINGRECORD_H
#define LLVM_CLANG_LEX_PREPROCESSINGRECORD_H
+#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Lex/PPCallbacks.h"
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index e718f5b6bbd0..64ddb5307fb0 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -29,7 +29,6 @@
#include "clang/Lex/ModuleLoader.h"
#include "clang/Lex/ModuleMap.h"
#include "clang/Lex/PPCallbacks.h"
-#include "clang/Lex/PTHLexer.h"
#include "clang/Lex/Token.h"
#include "clang/Lex/TokenLexer.h"
#include "llvm/ADT/ArrayRef.h"
@@ -79,7 +78,6 @@ class PragmaNamespace;
class PreprocessingRecord;
class PreprocessorLexer;
class PreprocessorOptions;
-class PTHManager;
class ScratchBuffer;
class TargetInfo;
@@ -143,10 +141,6 @@ class Preprocessor {
/// External source of macros.
ExternalPreprocessorSource *ExternalSource;
- /// An optional PTHManager object used for getting tokens from
- /// a token cache rather than lexing the original source file.
- std::unique_ptr<PTHManager> PTH;
-
/// A BumpPtrAllocator object used to quickly allocate and release
/// objects internal to the Preprocessor.
llvm::BumpPtrAllocator BP;
@@ -310,6 +304,9 @@ class Preprocessor {
/// on the stem that is to be code completed.
IdentifierInfo *CodeCompletionII = nullptr;
+ /// Range for the code completion token.
+ SourceRange CodeCompletionTokenRange;
+
/// The directory that the main file should be considered to occupy,
/// if it does not correspond to a real file (as happens when building a
/// module).
@@ -322,6 +319,10 @@ class Preprocessor {
/// This is used when loading a precompiled preamble.
std::pair<int, bool> SkipMainFilePreamble;
+ /// Whether we hit an error due to reaching max allowed include depth. Allows
+ /// to avoid hitting the same error over and over again.
+ bool HasReachedMaxIncludeDepth = false;
+
public:
struct PreambleSkipInfo {
SourceLocation HashTokenLoc;
@@ -389,19 +390,13 @@ private:
/// The current top of the stack that we're lexing from if
/// not expanding a macro and we are lexing directly from source code.
///
- /// Only one of CurLexer, CurPTHLexer, or CurTokenLexer will be non-null.
+ /// Only one of CurLexer, or CurTokenLexer will be non-null.
std::unique_ptr<Lexer> CurLexer;
- /// The current top of stack that we're lexing from if
- /// not expanding from a macro and we are lexing from a PTH cache.
- ///
- /// Only one of CurLexer, CurPTHLexer, or CurTokenLexer will be non-null.
- std::unique_ptr<PTHLexer> CurPTHLexer;
-
/// The current top of the stack what we're lexing from
/// if not expanding a macro.
///
- /// This is an alias for either CurLexer or CurPTHLexer.
+ /// This is an alias for CurLexer.
PreprocessorLexer *CurPPLexer = nullptr;
/// Used to find the current FileEntry, if CurLexer is non-null
@@ -419,7 +414,6 @@ private:
/// The kind of lexer we're currently working with.
enum CurLexerKind {
CLK_Lexer,
- CLK_PTHLexer,
CLK_TokenLexer,
CLK_CachingLexer,
CLK_LexAfterModuleImport
@@ -436,7 +430,6 @@ private:
enum CurLexerKind CurLexerKind;
Module *TheSubmodule;
std::unique_ptr<Lexer> TheLexer;
- std::unique_ptr<PTHLexer> ThePTHLexer;
PreprocessorLexer *ThePPLexer;
std::unique_ptr<TokenLexer> TheTokenLexer;
const DirectoryLookup *TheDirLookup;
@@ -445,13 +438,11 @@ private:
// versions, only needed to pacify MSVC.
IncludeStackInfo(enum CurLexerKind CurLexerKind, Module *TheSubmodule,
std::unique_ptr<Lexer> &&TheLexer,
- std::unique_ptr<PTHLexer> &&ThePTHLexer,
PreprocessorLexer *ThePPLexer,
std::unique_ptr<TokenLexer> &&TheTokenLexer,
const DirectoryLookup *TheDirLookup)
: CurLexerKind(std::move(CurLexerKind)),
TheSubmodule(std::move(TheSubmodule)), TheLexer(std::move(TheLexer)),
- ThePTHLexer(std::move(ThePTHLexer)),
ThePPLexer(std::move(ThePPLexer)),
TheTokenLexer(std::move(TheTokenLexer)),
TheDirLookup(std::move(TheDirLookup)) {}
@@ -723,6 +714,9 @@ private:
/// The file ID for the PCH through header.
FileID PCHThroughHeaderFileID;
+ /// Whether tokens are being skipped until a #pragma hdrstop is seen.
+ bool SkippingUntilPragmaHdrStop = false;
+
/// Whether tokens are being skipped until the through header is seen.
bool SkippingUntilPCHThroughHeader = false;
@@ -832,10 +826,6 @@ public:
Builtin::Context &getBuiltinInfo() { return BuiltinInfo; }
llvm::BumpPtrAllocator &getPreprocessorAllocator() { return BP; }
- void setPTHManager(PTHManager* pm);
-
- PTHManager *getPTHManager() { return PTH.get(); }
-
void setExternalSource(ExternalPreprocessorSource *Source) {
ExternalSource = Source;
}
@@ -1122,6 +1112,10 @@ public:
CodeComplete = nullptr;
}
+ /// Hook used by the lexer to invoke the "included file" code
+ /// completion point.
+ void CodeCompleteIncludedFile(llvm::StringRef Dir, bool IsAngled);
+
/// Hook used by the lexer to invoke the "natural language" code
/// completion point.
void CodeCompleteNaturalLanguage();
@@ -1131,6 +1125,16 @@ public:
CodeCompletionII = Filter;
}
+ /// Set the code completion token range for detecting replacement range later
+ /// on.
+ void setCodeCompletionTokenRange(const SourceLocation Start,
+ const SourceLocation End) {
+ CodeCompletionTokenRange = {Start, End};
+ }
+ SourceRange getCodeCompletionTokenRange() const {
+ return CodeCompletionTokenRange;
+ }
+
/// Get the code completion token for filtering purposes.
StringRef getCodeCompletionFilter() {
if (CodeCompletionII)
@@ -1147,7 +1151,7 @@ public:
void createPreprocessingRecord();
/// Returns true if the FileEntry is the PCH through header.
- bool isPCHThroughHeader(const FileEntry *File);
+ bool isPCHThroughHeader(const FileEntry *FE);
/// True if creating a PCH with a through header.
bool creatingPCHWithThroughHeader();
@@ -1155,11 +1159,19 @@ public:
/// True if using a PCH with a through header.
bool usingPCHWithThroughHeader();
- /// Skip tokens until after the #include of the through header.
- void SkipTokensUntilPCHThroughHeader();
+ /// True if creating a PCH with a #pragma hdrstop.
+ bool creatingPCHWithPragmaHdrStop();
+
+ /// True if using a PCH with a #pragma hdrstop.
+ bool usingPCHWithPragmaHdrStop();
- /// Process directives while skipping until the through header is found.
- void HandleSkippedThroughHeaderDirective(Token &Result,
+ /// Skip tokens until after the #include of the through header or
+ /// until after a #pragma hdrstop.
+ void SkipTokensWhileUsingPCH();
+
+ /// Process directives while skipping until the through header or
+ /// #pragma hdrstop is found.
+ void HandleSkippedDirectiveWhileUsingPCH(Token &Result,
SourceLocation HashLoc);
/// Enter the specified FileID as the main source file,
@@ -1173,7 +1185,7 @@ public:
/// start lexing tokens from it instead of the current buffer.
///
/// Emits a diagnostic, doesn't enter the file, and returns true on error.
- bool EnterSourceFile(FileID CurFileID, const DirectoryLookup *Dir,
+ bool EnterSourceFile(FileID FID, const DirectoryLookup *Dir,
SourceLocation Loc);
/// Add a Macro to the top of the include stack and start lexing
@@ -1182,7 +1194,7 @@ public:
/// \param Args specifies the tokens input to a function-like macro.
/// \param ILEnd specifies the location of the ')' for a function-like macro
/// or the identifier for an object-like macro.
- void EnterMacro(Token &Identifier, SourceLocation ILEnd, MacroInfo *Macro,
+ void EnterMacro(Token &Tok, SourceLocation ILEnd, MacroInfo *Macro,
MacroArgs *Args);
/// Add a "macro" context to the top of the include stack,
@@ -1428,7 +1440,7 @@ public:
CachedTokens[CachedLexPos-1] = Tok;
}
- /// Recompute the current lexer kind based on the CurLexer/CurPTHLexer/
+ /// Recompute the current lexer kind based on the CurLexer/
/// CurTokenLexer pointers.
void recomputeCurLexerKind();
@@ -1736,7 +1748,7 @@ public:
void SetPoisonReason(IdentifierInfo *II, unsigned DiagID);
/// Display reason for poisoned identifier.
- void HandlePoisonedIdentifier(Token & Tok);
+ void HandlePoisonedIdentifier(Token & Identifier);
void MaybeHandlePoisonedIdentifier(Token & Identifier) {
if(IdentifierInfo * II = Identifier.getIdentifierInfo()) {
@@ -1801,7 +1813,7 @@ public:
/// If not, emit a diagnostic and consume up until the eod.
/// If \p EnableMacros is true, then we consider macros that expand to zero
/// tokens as being ok.
- void CheckEndOfDirective(const char *Directive, bool EnableMacros = false);
+ void CheckEndOfDirective(const char *DirType, bool EnableMacros = false);
/// Read and discard all tokens remaining on the current line until
/// the tok::eod token is found.
@@ -1830,7 +1842,7 @@ public:
///
/// \returns true if the input filename was in <>'s or false if it was
/// in ""'s.
- bool GetIncludeFilenameSpelling(SourceLocation Loc,StringRef &Filename);
+ bool GetIncludeFilenameSpelling(SourceLocation Loc,StringRef &Buffer);
/// Given a "foo" or \<foo> reference, look up the indicated file.
///
@@ -1873,7 +1885,7 @@ public:
/// Lex an on-off-switch (C99 6.10.6p2) and verify that it is
/// followed by EOD. Return true if the token is not a valid on-off-switch.
- bool LexOnOffSwitch(tok::OnOffSwitch &OOS);
+ bool LexOnOffSwitch(tok::OnOffSwitch &Result);
bool CheckMacroName(Token &MacroNameTok, MacroUse isDefineUndef,
bool *ShadowFlag = nullptr);
@@ -1887,15 +1899,13 @@ private:
void PushIncludeMacroStack() {
assert(CurLexerKind != CLK_CachingLexer && "cannot push a caching lexer");
IncludeMacroStack.emplace_back(CurLexerKind, CurLexerSubmodule,
- std::move(CurLexer), std::move(CurPTHLexer),
- CurPPLexer, std::move(CurTokenLexer),
- CurDirLookup);
+ std::move(CurLexer), CurPPLexer,
+ std::move(CurTokenLexer), CurDirLookup);
CurPPLexer = nullptr;
}
void PopIncludeMacroStack() {
CurLexer = std::move(IncludeMacroStack.back().TheLexer);
- CurPTHLexer = std::move(IncludeMacroStack.back().ThePTHLexer);
CurPPLexer = IncludeMacroStack.back().ThePPLexer;
CurTokenLexer = std::move(IncludeMacroStack.back().TheTokenLexer);
CurDirLookup = IncludeMacroStack.back().TheDirLookup;
@@ -1964,9 +1974,6 @@ private:
bool FoundNonSkipPortion, bool FoundElse,
SourceLocation ElseLoc = SourceLocation());
- /// A fast PTH version of SkipExcludedConditionalBlock.
- void PTHSkipExcludedConditionalBlock();
-
/// Information about the result for evaluating an expression for a
/// preprocessor directive.
struct DirectiveEvalResult {
@@ -1993,7 +2000,7 @@ private:
/// If an identifier token is read that is to be expanded as a macro, handle
/// it and return the next token as 'Tok'. If we lexed a token, return true;
/// otherwise the caller should lex again.
- bool HandleMacroExpandedIdentifier(Token &Tok, const MacroDefinition &MD);
+ bool HandleMacroExpandedIdentifier(Token &Identifier, const MacroDefinition &MD);
/// Cache macro expanded tokens for TokenLexers.
//
@@ -2013,7 +2020,7 @@ private:
/// After reading "MACRO(", this method is invoked to read all of the formal
/// arguments specified for the macro invocation. Returns null on error.
MacroArgs *ReadMacroCallArgumentList(Token &MacroName, MacroInfo *MI,
- SourceLocation &ExpansionEnd);
+ SourceLocation &MacroEnd);
/// If an identifier token is read that is to be expanded
/// as a builtin macro, handle it and return the next token as 'Tok'.
@@ -2032,10 +2039,6 @@ private:
/// start lexing tokens from it instead of the current buffer.
void EnterSourceFileWithLexer(Lexer *TheLexer, const DirectoryLookup *Dir);
- /// Add a lexer to the top of the include stack and
- /// start getting tokens from it using the PTH cache.
- void EnterSourceFileWithPTH(PTHLexer *PL, const DirectoryLookup *Dir);
-
/// Set the FileID for the preprocessor predefines.
void setPredefinesFileID(FileID FID) {
assert(PredefinesFileID.isInvalid() && "PredefinesFileID already set!");
@@ -2066,8 +2069,7 @@ private:
bool InCachingLexMode() const {
// If the Lexer pointers are 0 and IncludeMacroStack is empty, it means
// that we are past EOF, not that we are in CachingLex mode.
- return !CurPPLexer && !CurTokenLexer && !CurPTHLexer &&
- !IncludeMacroStack.empty();
+ return !CurPPLexer && !CurTokenLexer && !IncludeMacroStack.empty();
}
void EnterCachingLexMode();
@@ -2164,17 +2166,17 @@ private:
void replayPreambleConditionalStack();
// Macro handling.
- void HandleDefineDirective(Token &Tok, bool ImmediatelyAfterTopLevelIfndef);
+ void HandleDefineDirective(Token &Tok, bool ImmediatelyAfterHeaderGuard);
void HandleUndefDirective();
// Conditional Inclusion.
- void HandleIfdefDirective(Token &Tok, const Token &HashToken,
+ void HandleIfdefDirective(Token &Result, const Token &HashToken,
bool isIfndef, bool ReadAnyTokensBeforeDirective);
- void HandleIfDirective(Token &Tok, const Token &HashToken,
+ void HandleIfDirective(Token &IfToken, const Token &HashToken,
bool ReadAnyTokensBeforeDirective);
- void HandleEndifDirective(Token &Tok);
- void HandleElseDirective(Token &Tok, const Token &HashToken);
- void HandleElifDirective(Token &Tok, const Token &HashToken);
+ void HandleEndifDirective(Token &EndifToken);
+ void HandleElseDirective(Token &Result, const Token &HashToken);
+ void HandleElifDirective(Token &ElifToken, const Token &HashToken);
// Pragmas.
void HandlePragmaDirective(SourceLocation IntroducerLoc,
@@ -2190,11 +2192,12 @@ public:
void HandlePragmaPopMacro(Token &Tok);
void HandlePragmaIncludeAlias(Token &Tok);
void HandlePragmaModuleBuild(Token &Tok);
+ void HandlePragmaHdrstop(Token &Tok);
IdentifierInfo *ParsePragmaPushOrPopMacro(Token &Tok);
// Return true and store the first token only if any CommentHandler
// has inserted some tokens and getCommentRetentionState() is false.
- bool HandleComment(Token &Token, SourceRange Comment);
+ bool HandleComment(Token &result, SourceRange Comment);
/// A macro is used, update information about macros that need unused
/// warnings.
diff --git a/include/clang/Lex/PreprocessorLexer.h b/include/clang/Lex/PreprocessorLexer.h
index b619f192f530..de918a215302 100644
--- a/include/clang/Lex/PreprocessorLexer.h
+++ b/include/clang/Lex/PreprocessorLexer.h
@@ -135,7 +135,7 @@ public:
///
/// If the sequence parsed is not lexically legal, emit a diagnostic and
/// return a result EOD token.
- void LexIncludeFilename(Token &Result);
+ void LexIncludeFilename(Token &FilenameTok);
/// Inform the lexer whether or not we are currently lexing a
/// preprocessor directive.
diff --git a/include/clang/Lex/PreprocessorOptions.h b/include/clang/Lex/PreprocessorOptions.h
index 5134aeaa6a29..f1ac72c47428 100644
--- a/include/clang/Lex/PreprocessorOptions.h
+++ b/include/clang/Lex/PreprocessorOptions.h
@@ -54,6 +54,16 @@ public:
/// definitions and expansions.
bool DetailedRecord = false;
+ /// When true, we are creating or using a PCH where a #pragma hdrstop is
+ /// expected to indicate the beginning or end of the PCH.
+ bool PCHWithHdrStop = false;
+
+ /// When true, we are creating a PCH or creating the PCH object while
+ /// expecting a #pragma hdrstop to separate the two. Allow for a
+ /// missing #pragma hdrstop, which generates a PCH for the whole file,
+ /// and creates an empty PCH object.
+ bool PCHWithHdrStopCreate = false;
+
/// If non-empty, the filename used in an #include directive in the primary
/// source file (or command-line preinclude) that is used to implement
/// MSVC-style precompiled headers. When creating a PCH, after the #include
@@ -100,13 +110,6 @@ public:
/// clients don't use them.
bool WriteCommentListToPCH = true;
- /// The implicit PTH input included at the start of the translation unit, or
- /// empty.
- std::string ImplicitPTHInclude;
-
- /// If given, a PTH cache file to use for speeding up header parsing.
- std::string TokenCache;
-
/// When enabled, preprocessor is in a mode for parsing a single file only.
///
/// Disables #includes of other files and if there are unresolved identifiers
@@ -194,8 +197,6 @@ public:
ChainedIncludes.clear();
DumpDeserializedPCHDecls = false;
ImplicitPCHInclude.clear();
- ImplicitPTHInclude.clear();
- TokenCache.clear();
SingleFileParseMode = false;
LexEditorPlaceholders = true;
RetainRemappedFileBuffers = true;
diff --git a/include/clang/Lex/TokenConcatenation.h b/include/clang/Lex/TokenConcatenation.h
index 60c182b509a4..3199e36f0d26 100644
--- a/include/clang/Lex/TokenConcatenation.h
+++ b/include/clang/Lex/TokenConcatenation.h
@@ -29,7 +29,7 @@ namespace clang {
/// and ")" next to each other is safe.
///
class TokenConcatenation {
- Preprocessor &PP;
+ const Preprocessor &PP;
enum AvoidConcatInfo {
/// By default, a token never needs to avoid concatenation. Most tokens
@@ -56,7 +56,7 @@ namespace clang {
/// method.
char TokenInfo[tok::NUM_TOKENS];
public:
- TokenConcatenation(Preprocessor &PP);
+ TokenConcatenation(const Preprocessor &PP);
bool AvoidConcat(const Token &PrevPrevTok,
const Token &PrevTok,
diff --git a/include/clang/Lex/TokenLexer.h b/include/clang/Lex/TokenLexer.h
index 98935ad9c4fa..6aae9eec7bfa 100644
--- a/include/clang/Lex/TokenLexer.h
+++ b/include/clang/Lex/TokenLexer.h
@@ -31,18 +31,17 @@ class VAOptExpansionContext;
class TokenLexer {
friend class Preprocessor;
- /// Macro - The macro we are expanding from. This is null if expanding a
- /// token stream.
+ /// The macro we are expanding from. This is null if expanding a token stream.
MacroInfo *Macro = nullptr;
- /// ActualArgs - The actual arguments specified for a function-like macro, or
- /// null. The TokenLexer owns the pointed-to object.
+ /// The actual arguments specified for a function-like macro, or null. The
+ /// TokenLexer owns the pointed-to object.
MacroArgs *ActualArgs = nullptr;
- /// PP - The current preprocessor object we are expanding for.
+ /// The current preprocessor object we are expanding for.
Preprocessor &PP;
- /// Tokens - This is the pointer to an array of tokens that the macro is
+ /// This is the pointer to an array of tokens that the macro is
/// defined to, with arguments expanded for function-like macros. If this is
/// a token stream, these are the tokens we are returning. This points into
/// the macro definition we are lexing from, a cache buffer that is owned by
@@ -52,14 +51,13 @@ class TokenLexer {
/// may update the pointer as needed.
const Token *Tokens;
- /// NumTokens - This is the length of the Tokens array.
+ /// This is the length of the Tokens array.
unsigned NumTokens;
/// This is the index of the next token that Lex will return.
unsigned CurTokenIdx;
- /// ExpandLocStart/End - The source location range where this macro was
- /// expanded.
+ /// The source location range where this macro was expanded.
SourceLocation ExpandLocStart, ExpandLocEnd;
/// Source location pointing at the source location entry chunk that
@@ -81,7 +79,7 @@ class TokenLexer {
bool AtStartOfLine : 1;
bool HasLeadingSpace : 1;
- // NextTokGetsSpace - When this is true, the next token appended to the
+ // When this is true, the next token appended to the
// output list during function argument expansion will get a leading space,
// regardless of whether it had one to begin with or not. This is used for
// placemarker support. If still true after function argument expansion, the
@@ -89,13 +87,13 @@ class TokenLexer {
// expansion.
bool NextTokGetsSpace : 1;
- /// OwnsTokens - This is true if this TokenLexer allocated the Tokens
+ /// This is true if this TokenLexer allocated the Tokens
/// array, and thus needs to free it when destroyed. For simple object-like
/// macros (for example) we just point into the token buffer of the macro
/// definition, we don't make a copy of it.
bool OwnsTokens : 1;
- /// DisableMacroExpansion - This is true when tokens lexed from the TokenLexer
+ /// This is true when tokens lexed from the TokenLexer
/// should not be subject to further macro expansion.
bool DisableMacroExpansion : 1;
@@ -123,14 +121,14 @@ public:
TokenLexer &operator=(const TokenLexer &) = delete;
~TokenLexer() { destroy(); }
- /// Init - Initialize this TokenLexer to expand from the specified macro
+ /// Initialize this TokenLexer to expand from the specified macro
/// with the specified argument information. Note that this ctor takes
/// ownership of the ActualArgs pointer. ILEnd specifies the location of the
/// ')' for a function-like macro or the identifier for an object-like macro.
- void Init(Token &Tok, SourceLocation ILEnd, MacroInfo *MI,
- MacroArgs *ActualArgs);
+ void Init(Token &Tok, SourceLocation ELEnd, MacroInfo *MI,
+ MacroArgs *Actuals);
- /// Init - Initialize this TokenLexer with the specified token stream.
+ /// Initialize this TokenLexer with the specified token stream.
/// This does not take ownership of the specified token vector.
///
/// DisableExpansion is true when macro expansion of tokens lexed from this
@@ -138,12 +136,12 @@ public:
void Init(const Token *TokArray, unsigned NumToks,
bool DisableMacroExpansion, bool OwnsTokens);
- /// isNextTokenLParen - If the next token lexed will pop this macro off the
+ /// If the next token lexed will pop this macro off the
/// expansion stack, return 2. If the next unexpanded token is a '(', return
/// 1, otherwise return 0.
unsigned isNextTokenLParen() const;
- /// Lex - Lex and return a token from this macro stream.
+ /// Lex and return a token from this macro stream.
bool Lex(Token &Tok);
/// isParsingPreprocessorDirective - Return true if we are in the middle of a
@@ -153,8 +151,8 @@ public:
private:
void destroy();
- /// isAtEnd - Return true if the next lex call will pop this macro off the
- /// include stack.
+ /// Return true if the next lex call will pop this macro off the include
+ /// stack.
bool isAtEnd() const {
return CurTokenIdx == NumTokens;
}
@@ -193,7 +191,7 @@ private:
/// them into a string. \p VCtx is used to determine which token represents
/// the first __VA_OPT__ replacement token.
///
- /// \param[in,out] ReplacementToks - Contains the current Replacement Tokens
+ /// \param[in,out] ResultToks - Contains the current Replacement Tokens
/// (prior to rescanning and token pasting), the tail end of which represents
/// the tokens just expanded through __VA_OPT__ processing. These (sub)
/// sequence of tokens are folded into one stringified token.
@@ -201,7 +199,7 @@ private:
/// \param[in] VCtx - contains relevant contextual information about the
/// state of the tokens around and including the __VA_OPT__ token, necessary
/// for stringification.
- void stringifyVAOPTContents(SmallVectorImpl<Token> &ReplacementToks,
+ void stringifyVAOPTContents(SmallVectorImpl<Token> &ResultToks,
const VAOptExpansionContext &VCtx,
SourceLocation VAOPTClosingParenLoc);
@@ -209,7 +207,7 @@ private:
/// return preexpanded tokens from Tokens.
void ExpandFunctionArguments();
- /// HandleMicrosoftCommentPaste - In microsoft compatibility mode, /##/ pastes
+ /// In microsoft compatibility mode, /##/ pastes
/// together to form a comment that comments out everything in the current
/// macro, other active macros, and anything left on the current physical
/// source line of the expanded buffer. Handle this by returning the
diff --git a/include/clang/Sema/LoopHint.h b/include/clang/Parse/LoopHint.h
index 171435e69bc8..be133703268d 100644
--- a/include/clang/Sema/LoopHint.h
+++ b/include/clang/Parse/LoopHint.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SEMA_LOOPHINT_H
-#define LLVM_CLANG_SEMA_LOOPHINT_H
+#ifndef LLVM_CLANG_PARSE_LOOPHINT_H
+#define LLVM_CLANG_PARSE_LOOPHINT_H
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/SourceLocation.h"
@@ -42,4 +42,4 @@ struct LoopHint {
} // end namespace clang
-#endif // LLVM_CLANG_SEMA_LOOPHINT_H
+#endif // LLVM_CLANG_PARSE_LOOPHINT_H
diff --git a/include/clang/Parse/ParseDiagnostic.h b/include/clang/Parse/ParseDiagnostic.h
index f3a7f3b7a8d7..c7c62688cbaa 100644
--- a/include/clang/Parse/ParseDiagnostic.h
+++ b/include/clang/Parse/ParseDiagnostic.h
@@ -10,19 +10,6 @@
#ifndef LLVM_CLANG_PARSE_PARSEDIAGNOSTIC_H
#define LLVM_CLANG_PARSE_PARSEDIAGNOSTIC_H
-#include "clang/Basic/Diagnostic.h"
-
-namespace clang {
- namespace diag {
- enum {
-#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
- SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
-#define PARSESTART
-#include "clang/Basic/DiagnosticParseKinds.inc"
-#undef DIAG
- NUM_BUILTIN_PARSE_DIAGNOSTICS
- };
- } // end namespace diag
-} // end namespace clang
+#include "clang/Basic/DiagnosticParse.h"
#endif
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index 69bf88a371db..438ff0e2ed45 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_PARSE_PARSER_H
#define LLVM_CLANG_PARSE_PARSER_H
+#include "clang/AST/OpenMPClause.h"
#include "clang/AST/Availability.h"
#include "clang/Basic/BitmaskEnum.h"
#include "clang/Basic/OpenMPKinds.h"
@@ -22,7 +23,6 @@
#include "clang/Lex/CodeCompletionHandler.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/DeclSpec.h"
-#include "clang/Sema/LoopHint.h"
#include "clang/Sema/Sema.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Compiler.h"
@@ -38,6 +38,7 @@ namespace clang {
class CorrectionCandidateCallback;
class DeclGroupRef;
class DiagnosticBuilder;
+ struct LoopHint;
class Parser;
class ParsingDeclRAIIObject;
class ParsingDeclSpec;
@@ -119,7 +120,7 @@ class Parser : public CodeCompletionHandler {
IdentifierInfo *Ident_pixel;
/// Objective-C contextual keywords.
- mutable IdentifierInfo *Ident_instancetype;
+ IdentifierInfo *Ident_instancetype;
/// Identifier for "introduced".
IdentifierInfo *Ident_introduced;
@@ -185,6 +186,8 @@ class Parser : public CodeCompletionHandler {
std::unique_ptr<PragmaHandler> LoopHintHandler;
std::unique_ptr<PragmaHandler> UnrollHintHandler;
std::unique_ptr<PragmaHandler> NoUnrollHintHandler;
+ std::unique_ptr<PragmaHandler> UnrollAndJamHintHandler;
+ std::unique_ptr<PragmaHandler> NoUnrollAndJamHintHandler;
std::unique_ptr<PragmaHandler> FPHandler;
std::unique_ptr<PragmaHandler> STDCFENVHandler;
std::unique_ptr<PragmaHandler> STDCCXLIMITHandler;
@@ -212,6 +215,11 @@ class Parser : public CodeCompletionHandler {
/// should not be set directly.
bool InMessageExpression;
+ /// Gets set to true after calling ProduceSignatureHelp, it is for a
+ /// workaround to make sure ProduceSignatureHelp is only called at the deepest
+ /// function call.
+ bool CalledSignatureHelp = false;
+
/// The "depth" of the template parameters currently being parsed.
unsigned TemplateParameterDepth;
@@ -352,6 +360,11 @@ class Parser : public CodeCompletionHandler {
/// just a regular sub-expression.
SourceLocation ExprStatementTokLoc;
+ /// Tests whether an expression value is discarded based on token lookahead.
+ /// It will return true if the lexer is currently processing the })
+ /// terminating a GNU statement expression and false otherwise.
+ bool isExprValueDiscarded();
+
public:
Parser(Preprocessor &PP, Sema &Actions, bool SkipFunctionBodies);
~Parser() override;
@@ -668,6 +681,10 @@ private:
void HandlePragmaFPContract();
/// Handle the annotation token produced for
+ /// #pragma STDC FENV_ACCESS...
+ void HandlePragmaFEnvAccess();
+
+ /// \brief Handle the annotation token produced for
/// #pragma clang fp ...
void HandlePragmaFP();
@@ -793,7 +810,7 @@ private:
///
/// Should only be used in Objective-C language modes.
bool isObjCInstancetype() {
- assert(getLangOpts().ObjC1);
+ assert(getLangOpts().ObjC);
if (Tok.isAnnotation())
return false;
if (!Ident_instancetype)
@@ -1782,10 +1799,12 @@ private:
SourceLocation Start);
//===--------------------------------------------------------------------===//
- // C++ if/switch/while condition expression.
+ // C++ if/switch/while/for condition expression.
+ struct ForRangeInfo;
Sema::ConditionResult ParseCXXCondition(StmtResult *InitStmt,
SourceLocation Loc,
- Sema::ConditionKind CK);
+ Sema::ConditionKind CK,
+ ForRangeInfo *FRI = nullptr);
//===--------------------------------------------------------------------===//
// C++ Coroutines
@@ -1875,6 +1894,7 @@ private:
StmtResult ParseCompoundStatement(bool isStmtExpr,
unsigned ScopeFlags);
void ParseCompoundStatementLeadingPragmas();
+ bool ConsumeNullStmt(StmtVector &Stmts);
StmtResult ParseCompoundStatementBody(bool isStmtExpr = false);
bool ParseParenExprOrCondition(StmtResult *InitStmt,
Sema::ConditionResult &CondResult,
@@ -2034,6 +2054,9 @@ private:
bool ParsedForRangeDecl() { return !ColonLoc.isInvalid(); }
};
+ struct ForRangeInfo : ForRangeInit {
+ StmtResult LoopVar;
+ };
DeclGroupPtrTy ParseDeclaration(DeclaratorContext Context,
SourceLocation &DeclEnd,
@@ -2128,6 +2151,8 @@ private:
// 'for-init-statement' part of a 'for' statement.
/// Returns true for declaration, false for expression.
bool isForInitDeclaration() {
+ if (getLangOpts().OpenMP)
+ Actions.startOpenMPLoop();
if (getLangOpts().CPlusPlus)
return isCXXSimpleDeclaration(/*AllowForRangeDecl=*/true);
return isDeclarationSpecifier(true);
@@ -2204,13 +2229,15 @@ private:
Expression, ///< Disambiguated as an expression (either kind).
ConditionDecl, ///< Disambiguated as the declaration form of condition.
InitStmtDecl, ///< Disambiguated as a simple-declaration init-statement.
+ ForRangeDecl, ///< Disambiguated as a for-range declaration.
Error ///< Can't be any of the above!
};
/// Disambiguates between the different kinds of things that can happen
/// after 'if (' or 'switch ('. This could be one of two different kinds of
/// declaration (depending on whether there is a ';' later) or an expression.
ConditionOrInitStatement
- isCXXConditionDeclarationOrInitStatement(bool CanBeInitStmt);
+ isCXXConditionDeclarationOrInitStatement(bool CanBeInitStmt,
+ bool CanBeForRangeDecl);
bool isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous);
bool isCXXTypeId(TentativeCXXTypeIdContext Context) {
@@ -2639,9 +2666,16 @@ private:
DeclGroupPtrTy ParseNamespace(DeclaratorContext Context,
SourceLocation &DeclEnd,
SourceLocation InlineLoc = SourceLocation());
- void ParseInnerNamespace(std::vector<SourceLocation> &IdentLoc,
- std::vector<IdentifierInfo *> &Ident,
- std::vector<SourceLocation> &NamespaceLoc,
+
+ struct InnerNamespaceInfo {
+ SourceLocation NamespaceLoc;
+ SourceLocation InlineLoc;
+ SourceLocation IdentLoc;
+ IdentifierInfo *Ident;
+ };
+ using InnerNamespaceInfoList = llvm::SmallVector<InnerNamespaceInfo, 4>;
+
+ void ParseInnerNamespace(const InnerNamespaceInfoList &InnerNSs,
unsigned int index, SourceLocation &InlineLoc,
ParsedAttributes &attrs,
BalancedDelimiterTracker &Tracker);
@@ -2747,6 +2781,11 @@ private:
DeclGroupPtrTy ParseOMPDeclareSimdClauses(DeclGroupPtrTy Ptr,
CachedTokens &Toks,
SourceLocation Loc);
+ /// Parse clauses for '#pragma omp declare target'.
+ DeclGroupPtrTy ParseOMPDeclareTargetClauses();
+ /// Parse '#pragma omp end declare target'.
+ void ParseOMPEndDeclareTargetDirective(OpenMPDirectiveKind DKind,
+ SourceLocation Loc);
/// Parses declarative OpenMP directives.
DeclGroupPtrTy ParseOpenMPDeclarativeDirectiveWithExtDecl(
AccessSpecifier &AS, ParsedAttributesWithRange &Attrs,
@@ -2843,7 +2882,10 @@ public:
DeclarationNameInfo ReductionId;
OpenMPDependClauseKind DepKind = OMPC_DEPEND_unknown;
OpenMPLinearClauseKind LinKind = OMPC_LINEAR_val;
- OpenMPMapClauseKind MapTypeModifier = OMPC_MAP_unknown;
+ SmallVector<OpenMPMapModifierKind, OMPMapClause::NumberOfModifiers>
+ MapTypeModifiers;
+ SmallVector<SourceLocation, OMPMapClause::NumberOfModifiers>
+ MapTypeModifiersLoc;
OpenMPMapClauseKind MapType = OMPC_MAP_unknown;
bool IsMapTypeImplicit = false;
SourceLocation DepLinMapLoc;
@@ -2958,6 +3000,7 @@ private:
void CodeCompletePreprocessorExpression() override;
void CodeCompleteMacroArgument(IdentifierInfo *Macro, MacroInfo *MacroInfo,
unsigned ArgumentIndex) override;
+ void CodeCompleteIncludedFile(llvm::StringRef Dir, bool IsAngled) override;
void CodeCompleteNaturalLanguage() override;
};
diff --git a/include/clang/Sema/CodeCompleteConsumer.h b/include/clang/Sema/CodeCompleteConsumer.h
index ede3ddf91993..5e46a84128d5 100644
--- a/include/clang/Sema/CodeCompleteConsumer.h
+++ b/include/clang/Sema/CodeCompleteConsumer.h
@@ -17,6 +17,7 @@
#include "clang-c/Index.h"
#include "clang/AST/Type.h"
#include "clang/Basic/LLVM.h"
+#include "clang/Lex/MacroInfo.h"
#include "clang/Sema/CodeCompleteOptions.h"
#include "clang/Sema/DeclSpec.h"
#include "llvm/ADT/ArrayRef.h"
@@ -271,11 +272,15 @@ public:
CCC_Type,
/// Code completion occurred where a new name is expected.
- CCC_Name,
+ CCC_NewName,
- /// Code completion occurred where a new name is expected and a
- /// qualified name is permissible.
- CCC_PotentiallyQualifiedName,
+ /// Code completion occurred where both a new name and an existing symbol is
+ /// permissible.
+ CCC_SymbolOrNewName,
+
+ /// Code completion occurred where an existing name(such as type, function
+ /// or variable) is expected.
+ CCC_Symbol,
/// Code completion occurred where an macro is being defined.
CCC_MacroName,
@@ -322,6 +327,9 @@ public:
/// Code completion where an Objective-C category name is expected.
CCC_ObjCCategoryName,
+ /// Code completion inside the filename part of a #include directive.
+ CCC_IncludedFile,
+
/// An unknown context, in which we are recovering from a parsing
/// error and don't know which completions we should give.
CCC_Recovery
@@ -817,6 +825,9 @@ public:
/// Whether this result is hidden by another name.
bool Hidden : 1;
+ /// Whether this is a class member from base class.
+ bool InBaseClass : 1;
+
/// Whether this result was found via lookup into a base class.
bool QualifierIsInformative : 1;
@@ -843,6 +854,11 @@ public:
/// corresponding `using decl::qualified::name;` nearby.
const UsingShadowDecl *ShadowDecl = nullptr;
+ /// If the result is RK_Macro, this can store the information about the macro
+ /// definition. This should be set in most cases but can be missing when
+ /// the macro has been undefined.
+ const MacroInfo *MacroDefInfo = nullptr;
+
/// Build a result that refers to a declaration.
CodeCompletionResult(const NamedDecl *Declaration, unsigned Priority,
NestedNameSpecifier *Qualifier = nullptr,
@@ -850,7 +866,7 @@ public:
bool Accessible = true,
std::vector<FixItHint> FixIts = std::vector<FixItHint>())
: Declaration(Declaration), Priority(Priority), Kind(RK_Declaration),
- FixIts(std::move(FixIts)), Hidden(false),
+ FixIts(std::move(FixIts)), Hidden(false), InBaseClass(false),
QualifierIsInformative(QualifierIsInformative),
StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
DeclaringEntity(false), Qualifier(Qualifier) {
@@ -861,35 +877,38 @@ public:
/// Build a result that refers to a keyword or symbol.
CodeCompletionResult(const char *Keyword, unsigned Priority = CCP_Keyword)
: Keyword(Keyword), Priority(Priority), Kind(RK_Keyword),
- CursorKind(CXCursor_NotImplemented), Hidden(false),
+ CursorKind(CXCursor_NotImplemented), Hidden(false), InBaseClass(false),
QualifierIsInformative(false), StartsNestedNameSpecifier(false),
AllParametersAreInformative(false), DeclaringEntity(false) {}
/// Build a result that refers to a macro.
CodeCompletionResult(const IdentifierInfo *Macro,
+ const MacroInfo *MI = nullptr,
unsigned Priority = CCP_Macro)
: Macro(Macro), Priority(Priority), Kind(RK_Macro),
- CursorKind(CXCursor_MacroDefinition), Hidden(false),
+ CursorKind(CXCursor_MacroDefinition), Hidden(false), InBaseClass(false),
QualifierIsInformative(false), StartsNestedNameSpecifier(false),
- AllParametersAreInformative(false), DeclaringEntity(false) {}
+ AllParametersAreInformative(false), DeclaringEntity(false),
+ MacroDefInfo(MI) {}
/// Build a result that refers to a pattern.
- CodeCompletionResult(CodeCompletionString *Pattern,
- unsigned Priority = CCP_CodePattern,
- CXCursorKind CursorKind = CXCursor_NotImplemented,
- CXAvailabilityKind Availability = CXAvailability_Available,
- const NamedDecl *D = nullptr)
+ CodeCompletionResult(
+ CodeCompletionString *Pattern, unsigned Priority = CCP_CodePattern,
+ CXCursorKind CursorKind = CXCursor_NotImplemented,
+ CXAvailabilityKind Availability = CXAvailability_Available,
+ const NamedDecl *D = nullptr)
: Declaration(D), Pattern(Pattern), Priority(Priority), Kind(RK_Pattern),
CursorKind(CursorKind), Availability(Availability), Hidden(false),
- QualifierIsInformative(false), StartsNestedNameSpecifier(false),
- AllParametersAreInformative(false), DeclaringEntity(false) {}
+ InBaseClass(false), QualifierIsInformative(false),
+ StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
+ DeclaringEntity(false) {}
/// Build a result that refers to a pattern with an associated
/// declaration.
CodeCompletionResult(CodeCompletionString *Pattern, const NamedDecl *D,
unsigned Priority)
: Declaration(D), Pattern(Pattern), Priority(Priority), Kind(RK_Pattern),
- Hidden(false), QualifierIsInformative(false),
+ Hidden(false), InBaseClass(false), QualifierIsInformative(false),
StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
DeclaringEntity(false) {
computeCursorKindAndAvailability();
@@ -935,6 +954,16 @@ public:
CodeCompletionAllocator &Allocator,
CodeCompletionTUInfo &CCTUInfo);
+ CodeCompletionString *createCodeCompletionStringForDecl(
+ Preprocessor &PP, ASTContext &Ctx, CodeCompletionBuilder &Result,
+ bool IncludeBriefComments, const CodeCompletionContext &CCContext,
+ PrintingPolicy &Policy);
+
+ CodeCompletionString *createCodeCompletionStringForOverride(
+ Preprocessor &PP, ASTContext &Ctx, CodeCompletionBuilder &Result,
+ bool IncludeBriefComments, const CodeCompletionContext &CCContext,
+ PrintingPolicy &Policy);
+
/// Retrieve the name that should be used to order a result.
///
/// If the name needs to be constructed as a string, that string will be
@@ -1114,9 +1143,13 @@ public:
/// \param Candidates an array of overload candidates.
///
/// \param NumCandidates the number of overload candidates
+ ///
+ /// \param OpenParLoc location of the opening parenthesis of the argument
+ /// list.
virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
OverloadCandidate *Candidates,
- unsigned NumCandidates) {}
+ unsigned NumCandidates,
+ SourceLocation OpenParLoc) {}
//@}
/// Retrieve the allocator that will be used to allocate
@@ -1166,7 +1199,8 @@ public:
void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
OverloadCandidate *Candidates,
- unsigned NumCandidates) override;
+ unsigned NumCandidates,
+ SourceLocation OpenParLoc) override;
bool isResultFilteredOut(StringRef Filter, CodeCompletionResult Results) override;
diff --git a/include/clang/Sema/CodeCompleteOptions.h b/include/clang/Sema/CodeCompleteOptions.h
index 1d3bbb4e585d..26f7f9d19f8e 100644
--- a/include/clang/Sema/CodeCompleteOptions.h
+++ b/include/clang/Sema/CodeCompleteOptions.h
@@ -36,7 +36,8 @@ public:
unsigned IncludeBriefComments : 1;
/// Hint whether to load data from the external AST to provide full results.
- /// If false, namespace-level declarations from the preamble may be omitted.
+ /// If false, namespace-level declarations and macros from the preamble may be
+ /// omitted.
unsigned LoadExternal : 1;
/// Include results after corrections (small fix-its), e.g. change '.' to '->'
diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h
index 2e70203c6cc0..8d6f0bc9148b 100644
--- a/include/clang/Sema/DeclSpec.h
+++ b/include/clang/Sema/DeclSpec.h
@@ -505,8 +505,8 @@ public:
const CXXScopeSpec &getTypeSpecScope() const { return TypeScope; }
SourceRange getSourceRange() const LLVM_READONLY { return Range; }
- SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
+ SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
SourceLocation getTypeSpecWidthLoc() const { return TSWRange.getBegin(); }
SourceRange getTypeSpecWidthRange() const { return TSWRange; }
@@ -593,6 +593,18 @@ public:
FS_noreturnLoc = SourceLocation();
}
+ /// This method calls the passed in handler on each CVRU qual being
+ /// set.
+ /// Handle - a handler to be invoked.
+ void forEachCVRUQualifier(
+ llvm::function_ref<void(TQ, StringRef, SourceLocation)> Handle);
+
+ /// This method calls the passed in handler on each qual being
+ /// set.
+ /// Handle - a handler to be invoked.
+ void forEachQualifier(
+ llvm::function_ref<void(TQ, StringRef, SourceLocation)> Handle);
+
/// Return true if any type-specifier has been found.
bool hasTypeSpecifier() const {
return getTypeSpecType() != DeclSpec::TST_unspecified ||
@@ -683,6 +695,8 @@ public:
ExprRep = Rep;
}
+ bool SetTypeQual(TQ T, SourceLocation Loc);
+
bool SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec,
unsigned &DiagID, const LangOptions &Lang);
@@ -1120,8 +1134,8 @@ public:
SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(StartLocation, EndLocation);
}
- SourceLocation getLocStart() const LLVM_READONLY { return StartLocation; }
- SourceLocation getLocEnd() const LLVM_READONLY { return EndLocation; }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return StartLocation; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return EndLocation; }
};
/// A set of tokens that has been cached for later parsing.
@@ -1250,10 +1264,6 @@ struct DeclaratorChunk {
/// Otherwise, it's an rvalue reference.
unsigned RefQualifierIsLValueRef : 1;
- /// The type qualifiers: const/volatile/restrict/__unaligned
- /// The qualifier bitmask values are the same as in QualType.
- unsigned TypeQuals : 4;
-
/// ExceptionSpecType - An ExceptionSpecificationType value.
unsigned ExceptionSpecType : 4;
@@ -1287,21 +1297,6 @@ struct DeclaratorChunk {
/// If this is an invalid location, there is no ref-qualifier.
unsigned RefQualifierLoc;
- /// The location of the const-qualifier, if any.
- ///
- /// If this is an invalid location, there is no const-qualifier.
- unsigned ConstQualifierLoc;
-
- /// The location of the volatile-qualifier, if any.
- ///
- /// If this is an invalid location, there is no volatile-qualifier.
- unsigned VolatileQualifierLoc;
-
- /// The location of the restrict-qualifier, if any.
- ///
- /// If this is an invalid location, there is no restrict-qualifier.
- unsigned RestrictQualifierLoc;
-
/// The location of the 'mutable' qualifer in a lambda-declarator, if
/// any.
unsigned MutableLoc;
@@ -1317,6 +1312,12 @@ struct DeclaratorChunk {
/// there are no parameters specified.
ParamInfo *Params;
+ /// DeclSpec for the function with the qualifier related info.
+ DeclSpec *MethodQualifiers;
+
+ /// AtttibuteFactory for the MethodQualifiers.
+ AttributeFactory *QualAttrFactory;
+
union {
/// Pointer to a new[]'d array of TypeAndRange objects that
/// contain the types in the function's dynamic exception specification
@@ -1356,6 +1357,8 @@ struct DeclaratorChunk {
void destroy() {
freeParams();
+ delete QualAttrFactory;
+ delete MethodQualifiers;
switch (getExceptionSpecType()) {
default:
break;
@@ -1372,6 +1375,14 @@ struct DeclaratorChunk {
}
}
+ DeclSpec &getOrCreateMethodQualifiers() {
+ if (!MethodQualifiers) {
+ QualAttrFactory = new AttributeFactory();
+ MethodQualifiers = new DeclSpec(*QualAttrFactory);
+ }
+ return *MethodQualifiers;
+ }
+
/// isKNRPrototype - Return true if this is a K&R style identifier list,
/// like "void foo(a,b,c)". In a function definition, this will be followed
/// by the parameter type definitions.
@@ -1406,19 +1417,22 @@ struct DeclaratorChunk {
return SourceLocation::getFromRawEncoding(RefQualifierLoc);
}
- /// Retrieve the location of the 'const' qualifier, if any.
+ /// Retrieve the location of the 'const' qualifier.
SourceLocation getConstQualifierLoc() const {
- return SourceLocation::getFromRawEncoding(ConstQualifierLoc);
+ assert(MethodQualifiers);
+ return MethodQualifiers->getConstSpecLoc();
}
- /// Retrieve the location of the 'volatile' qualifier, if any.
+ /// Retrieve the location of the 'volatile' qualifier.
SourceLocation getVolatileQualifierLoc() const {
- return SourceLocation::getFromRawEncoding(VolatileQualifierLoc);
+ assert(MethodQualifiers);
+ return MethodQualifiers->getVolatileSpecLoc();
}
- /// Retrieve the location of the 'restrict' qualifier, if any.
+ /// Retrieve the location of the 'restrict' qualifier.
SourceLocation getRestrictQualifierLoc() const {
- return SourceLocation::getFromRawEncoding(RestrictQualifierLoc);
+ assert(MethodQualifiers);
+ return MethodQualifiers->getRestrictSpecLoc();
}
/// Retrieve the location of the 'mutable' qualifier, if any.
@@ -1434,6 +1448,12 @@ struct DeclaratorChunk {
/// qualifier.
bool hasMutableQualifier() const { return getMutableLoc().isValid(); }
+ /// Determine whether this method has qualifiers.
+ bool hasMethodTypeQualifiers() const {
+ return MethodQualifiers && (MethodQualifiers->getTypeQualifiers() ||
+ MethodQualifiers->getAttributes().size());
+ }
+
/// Get the type of exception specification this function has.
ExceptionSpecificationType getExceptionSpecType() const {
return static_cast<ExceptionSpecificationType>(ExceptionSpecType);
@@ -1574,12 +1594,8 @@ struct DeclaratorChunk {
ParamInfo *Params, unsigned NumParams,
SourceLocation EllipsisLoc,
SourceLocation RParenLoc,
- unsigned TypeQuals,
bool RefQualifierIsLvalueRef,
SourceLocation RefQualifierLoc,
- SourceLocation ConstQualifierLoc,
- SourceLocation VolatileQualifierLoc,
- SourceLocation RestrictQualifierLoc,
SourceLocation MutableLoc,
ExceptionSpecificationType ESpecType,
SourceRange ESpecRange,
@@ -1593,7 +1609,8 @@ struct DeclaratorChunk {
SourceLocation LocalRangeEnd,
Declarator &TheDeclarator,
TypeResult TrailingReturnType =
- TypeResult());
+ TypeResult(),
+ DeclSpec *MethodQualifiers = nullptr);
/// Return a DeclaratorChunk for a block.
static DeclaratorChunk getBlockPointer(unsigned TypeQuals,
@@ -1870,8 +1887,8 @@ public:
/// Get the source range that spans this declarator.
SourceRange getSourceRange() const LLVM_READONLY { return Range; }
- SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
+ SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
+ SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
void SetSourceRange(SourceRange R) { Range = R; }
/// SetRangeBegin - Set the start of the source range to Loc, unless it's
diff --git a/include/clang/Sema/Initialization.h b/include/clang/Sema/Initialization.h
index 8582e971d0b6..3a2d6275650d 100644
--- a/include/clang/Sema/Initialization.h
+++ b/include/clang/Sema/Initialization.h
@@ -671,10 +671,11 @@ public:
static InitializationKind CreateForInit(SourceLocation Loc, bool DirectInit,
Expr *Init) {
if (!Init) return CreateDefault(Loc);
- if (!DirectInit) return CreateCopy(Loc, Init->getLocStart());
+ if (!DirectInit)
+ return CreateCopy(Loc, Init->getBeginLoc());
if (isa<InitListExpr>(Init))
- return CreateDirectList(Loc, Init->getLocStart(), Init->getLocEnd());
- return CreateDirect(Loc, Init->getLocStart(), Init->getLocEnd());
+ return CreateDirectList(Loc, Init->getBeginLoc(), Init->getEndLoc());
+ return CreateDirect(Loc, Init->getBeginLoc(), Init->getEndLoc());
}
/// Determine the initialization kind.
@@ -892,11 +893,8 @@ public:
/// Initialize an OpenCL sampler from an integer.
SK_OCLSamplerInit,
- /// Initialize queue_t from 0.
- SK_OCLZeroQueue,
-
- /// Passing zero to a function where OpenCL event_t is expected.
- SK_OCLZeroEvent
+ /// Initialize an opaque OpenCL type (event_t, queue_t, etc.) with zero
+ SK_OCLZeroOpaqueType
};
/// A single step in the initialization sequence.
@@ -1333,12 +1331,13 @@ public:
/// constant.
void AddOCLSamplerInitStep(QualType T);
- /// Add a step to initialize an OpenCL event_t from a NULL
- /// constant.
- void AddOCLZeroEventStep(QualType T);
+ /// Add a step to initialzie an OpenCL opaque type (event_t, queue_t, etc.)
+ /// from a zero constant.
+ void AddOCLZeroOpaqueTypeStep(QualType T);
- /// Add a step to initialize an OpenCL queue_t from 0.
- void AddOCLZeroQueueStep(QualType T);
+ /// Add a step to initialize by zero types defined in the
+ /// cl_intel_device_side_avc_motion_estimation OpenCL extension
+ void AddOCLIntelSubgroupAVCZeroInitStep(QualType T);
/// Add steps to unwrap a initializer list for a reference around a
/// single element and rewrap it at the end.
diff --git a/include/clang/Sema/Lookup.h b/include/clang/Sema/Lookup.h
index e28b847f4ae5..4f7da851e232 100644
--- a/include/clang/Sema/Lookup.h
+++ b/include/clang/Sema/Lookup.h
@@ -540,7 +540,7 @@ public:
}
/// Clears out any current state.
- void clear() {
+ LLVM_ATTRIBUTE_REINITIALIZES void clear() {
ResultKind = NotFound;
Decls.clear();
if (Paths) deletePaths(Paths);
@@ -709,7 +709,9 @@ private:
// Results.
LookupResultKind ResultKind = NotFound;
- AmbiguityKind Ambiguity; // ill-defined unless ambiguous
+ // ill-defined unless ambiguous. Still need to be initialized it will be
+ // copied/moved.
+ AmbiguityKind Ambiguity = {};
UnresolvedSet<8> Decls;
CXXBasePaths *Paths = nullptr;
CXXRecordDecl *NamingClass = nullptr;
diff --git a/include/clang/Sema/Overload.h b/include/clang/Sema/Overload.h
index 6ded010ee8ed..96fd5892daae 100644
--- a/include/clang/Sema/Overload.h
+++ b/include/clang/Sema/Overload.h
@@ -755,12 +755,12 @@ class Sema;
ConversionFixItGenerator Fix;
/// Viable - True to indicate that this overload candidate is viable.
- bool Viable;
+ bool Viable : 1;
/// IsSurrogate - True to indicate that this candidate is a
/// surrogate for a conversion to a function pointer or reference
/// (C++ [over.call.object]).
- bool IsSurrogate;
+ bool IsSurrogate : 1;
/// IgnoreObjectArgument - True to indicate that the first
/// argument's conversion, which for this function represents the
@@ -769,7 +769,10 @@ class Sema;
/// implicit object argument is just a placeholder) or a
/// non-static member function when the call doesn't have an
/// object argument.
- bool IgnoreObjectArgument;
+ bool IgnoreObjectArgument : 1;
+
+ /// True if the candidate was found using ADL.
+ CallExpr::ADLCallKind IsADLCandidate : 1;
/// FailureKind - The reason why this candidate is not viable.
/// Actually an OverloadFailureKind.
@@ -823,6 +826,10 @@ class Sema;
return Function->getNumParams();
return ExplicitCallArguments;
}
+
+ private:
+ friend class OverloadCandidateSet;
+ OverloadCandidate() : IsADLCandidate(CallExpr::NotADL) {}
};
/// OverloadCandidateSet - A set of overload candidates, used in C++
diff --git a/include/clang/Sema/ParsedAttr.h b/include/clang/Sema/ParsedAttr.h
index cfb91af78370..11202cb137b5 100644
--- a/include/clang/Sema/ParsedAttr.h
+++ b/include/clang/Sema/ParsedAttr.h
@@ -16,6 +16,7 @@
#define LLVM_CLANG_SEMA_ATTRIBUTELIST_H
#include "clang/Basic/AttrSubjectMatchRules.h"
+#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Sema/Ownership.h"
@@ -54,8 +55,7 @@ struct AvailabilityChange {
bool isValid() const { return !Version.empty(); }
};
-namespace {
-
+namespace detail {
enum AvailabilitySlot {
IntroducedSlot, DeprecatedSlot, ObsoletedSlot, NumAvailabilitySlots
};
@@ -77,6 +77,18 @@ struct AvailabilityData {
}
};
+struct TypeTagForDatatypeData {
+ ParsedType MatchingCType;
+ unsigned LayoutCompatible : 1;
+ unsigned MustBeNull : 1;
+};
+struct PropertyData {
+ IdentifierInfo *GetterId, *SetterId;
+
+ PropertyData(IdentifierInfo *getterId, IdentifierInfo *setterId)
+ : GetterId(getterId), SetterId(setterId) {}
+};
+
} // namespace
/// Wraps an identifier and optional source location for the identifier.
@@ -102,7 +114,27 @@ using ArgsVector = llvm::SmallVector<ArgsUnion, 12U>;
/// 3: __attribute__(( format(printf, 1, 2) )). ParmName/Args/NumArgs all used.
/// 4: __attribute__(( aligned(16) )). ParmName is unused, Args/Num used.
///
-class ParsedAttr { // TODO: This should really be called ParsedAttribute
+class ParsedAttr final
+ : private llvm::TrailingObjects<
+ ParsedAttr, ArgsUnion, detail::AvailabilityData,
+ detail::TypeTagForDatatypeData, ParsedType, detail::PropertyData> {
+ friend TrailingObjects;
+
+ size_t numTrailingObjects(OverloadToken<ArgsUnion>) const { return NumArgs; }
+ size_t numTrailingObjects(OverloadToken<detail::AvailabilityData>) const {
+ return IsAvailability;
+ }
+ size_t
+ numTrailingObjects(OverloadToken<detail::TypeTagForDatatypeData>) const {
+ return IsTypeTagForDatatype;
+ }
+ size_t numTrailingObjects(OverloadToken<ParsedType>) const {
+ return HasParsedType;
+ }
+ size_t numTrailingObjects(OverloadToken<detail::PropertyData>) const {
+ return IsProperty;
+ }
+
public:
/// The style used to specify an attribute.
enum Syntax {
@@ -182,34 +214,18 @@ private:
const Expr *MessageExpr;
- /// Arguments, if any, are stored immediately following the object.
- ArgsUnion *getArgsBuffer() { return reinterpret_cast<ArgsUnion *>(this + 1); }
+ ArgsUnion *getArgsBuffer() { return getTrailingObjects<ArgsUnion>(); }
ArgsUnion const *getArgsBuffer() const {
- return reinterpret_cast<ArgsUnion const *>(this + 1);
+ return getTrailingObjects<ArgsUnion>();
}
- /// Availability information is stored immediately following the arguments,
- /// if any, at the end of the object.
- AvailabilityData *getAvailabilityData() {
- return reinterpret_cast<AvailabilityData*>(getArgsBuffer() + NumArgs);
+ detail::AvailabilityData *getAvailabilityData() {
+ return getTrailingObjects<detail::AvailabilityData>();
}
- const AvailabilityData *getAvailabilityData() const {
- return reinterpret_cast<const AvailabilityData*>(getArgsBuffer() + NumArgs);
+ const detail::AvailabilityData *getAvailabilityData() const {
+ return getTrailingObjects<detail::AvailabilityData>();
}
-public:
- struct TypeTagForDatatypeData {
- ParsedType *MatchingCType;
- unsigned LayoutCompatible : 1;
- unsigned MustBeNull : 1;
- };
- struct PropertyData {
- IdentifierInfo *GetterId, *SetterId;
-
- PropertyData(IdentifierInfo *getterId, IdentifierInfo *setterId)
- : GetterId(getterId), SetterId(setterId) {}
- };
-
private:
friend class AttributeFactory;
friend class AttributePool;
@@ -244,7 +260,7 @@ private:
MessageExpr(messageExpr) {
ArgsUnion PVal(Parm);
memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
- new (getAvailabilityData()) AvailabilityData(
+ new (getAvailabilityData()) detail::AvailabilityData(
introduced, deprecated, obsoleted, strict, replacementExpr);
AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
}
@@ -278,7 +294,7 @@ private:
HasProcessingCache(false) {
ArgsUnion PVal(ArgKind);
memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
- TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot();
+ detail::TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot();
new (&ExtraData.MatchingCType) ParsedType(matchingCType);
ExtraData.LayoutCompatible = layoutCompatible;
ExtraData.MustBeNull = mustBeNull;
@@ -308,46 +324,45 @@ private:
UsedAsTypeAttr(false), IsAvailability(false),
IsTypeTagForDatatype(false), IsProperty(true), HasParsedType(false),
HasProcessingCache(false) {
- new (&getPropertyDataBuffer()) PropertyData(getterId, setterId);
+ new (&getPropertyDataBuffer()) detail::PropertyData(getterId, setterId);
AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
}
/// Type tag information is stored immediately following the arguments, if
/// any, at the end of the object. They are mutually exclusive with
/// availability slots.
- TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() {
- return *reinterpret_cast<TypeTagForDatatypeData*>(getArgsBuffer()+NumArgs);
+ detail::TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() {
+ return *getTrailingObjects<detail::TypeTagForDatatypeData>();
}
- const TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() const {
- return *reinterpret_cast<const TypeTagForDatatypeData*>(getArgsBuffer()
- + NumArgs);
+ const detail::TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() const {
+ return *getTrailingObjects<detail::TypeTagForDatatypeData>();
}
/// The type buffer immediately follows the object and are mutually exclusive
/// with arguments.
- ParsedType &getTypeBuffer() {
- return *reinterpret_cast<ParsedType *>(this + 1);
- }
+ ParsedType &getTypeBuffer() { return *getTrailingObjects<ParsedType>(); }
const ParsedType &getTypeBuffer() const {
- return *reinterpret_cast<const ParsedType *>(this + 1);
+ return *getTrailingObjects<ParsedType>();
}
/// The property data immediately follows the object is is mutually exclusive
/// with arguments.
- PropertyData &getPropertyDataBuffer() {
+ detail::PropertyData &getPropertyDataBuffer() {
assert(IsProperty);
- return *reinterpret_cast<PropertyData*>(this + 1);
+ return *getTrailingObjects<detail::PropertyData>();
}
- const PropertyData &getPropertyDataBuffer() const {
+ const detail::PropertyData &getPropertyDataBuffer() const {
assert(IsProperty);
- return *reinterpret_cast<const PropertyData*>(this + 1);
+ return *getTrailingObjects<detail::PropertyData>();
}
size_t allocated_size() const;
public:
ParsedAttr(const ParsedAttr &) = delete;
+ ParsedAttr(ParsedAttr &&) = delete;
ParsedAttr &operator=(const ParsedAttr &) = delete;
+ ParsedAttr &operator=(ParsedAttr &&) = delete;
~ParsedAttr() = delete;
void operator delete(void *) = delete;
@@ -368,6 +383,11 @@ public:
IdentifierInfo *getScopeName() const { return ScopeName; }
SourceLocation getScopeLoc() const { return ScopeLoc; }
+ bool isGNUScope() const {
+ return ScopeName &&
+ (ScopeName->isStr("gnu") || ScopeName->isStr("__gnu__"));
+ }
+
bool hasParsedType() const { return HasParsedType; }
/// Is this the Microsoft __declspec(property) attribute?
@@ -451,17 +471,17 @@ public:
const AvailabilityChange &getAvailabilityIntroduced() const {
assert(getKind() == AT_Availability && "Not an availability attribute");
- return getAvailabilityData()->Changes[IntroducedSlot];
+ return getAvailabilityData()->Changes[detail::IntroducedSlot];
}
const AvailabilityChange &getAvailabilityDeprecated() const {
assert(getKind() == AT_Availability && "Not an availability attribute");
- return getAvailabilityData()->Changes[DeprecatedSlot];
+ return getAvailabilityData()->Changes[detail::DeprecatedSlot];
}
const AvailabilityChange &getAvailabilityObsoleted() const {
assert(getKind() == AT_Availability && "Not an availability attribute");
- return getAvailabilityData()->Changes[ObsoletedSlot];
+ return getAvailabilityData()->Changes[detail::ObsoletedSlot];
}
SourceLocation getStrictLoc() const {
@@ -487,7 +507,7 @@ public:
const ParsedType &getMatchingCType() const {
assert(getKind() == AT_TypeTagForDatatype &&
"Not a type_tag_for_datatype attribute");
- return *getTypeTagForDatatypeDataSlot().MatchingCType;
+ return getTypeTagForDatatypeDataSlot().MatchingCType;
}
bool getLayoutCompatible() const {
@@ -507,9 +527,16 @@ public:
return getTypeBuffer();
}
- const PropertyData &getPropertyData() const {
- assert(isDeclspecPropertyAttribute() && "Not a __delcspec(property) attribute");
- return getPropertyDataBuffer();
+ IdentifierInfo *getPropertyDataGetter() const {
+ assert(isDeclspecPropertyAttribute() &&
+ "Not a __delcspec(property) attribute");
+ return getPropertyDataBuffer().GetterId;
+ }
+
+ IdentifierInfo *getPropertyDataSetter() const {
+ assert(isDeclspecPropertyAttribute() &&
+ "Not a __delcspec(property) attribute");
+ return getPropertyDataBuffer().SetterId;
}
/// Get an index into the attribute spelling list
@@ -552,20 +579,18 @@ class AttributePool;
class AttributeFactory {
public:
enum {
- /// The required allocation size of an availability attribute,
- /// which we want to ensure is a multiple of sizeof(void*).
AvailabilityAllocSize =
- sizeof(ParsedAttr) +
- ((sizeof(AvailabilityData) + sizeof(void *) + sizeof(ArgsUnion) - 1) /
- sizeof(void *) * sizeof(void *)),
- TypeTagForDatatypeAllocSize = sizeof(ParsedAttr) +
- (sizeof(ParsedAttr::TypeTagForDatatypeData) +
- sizeof(void *) + sizeof(ArgsUnion) - 1) /
- sizeof(void *) * sizeof(void *),
+ ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
+ detail::TypeTagForDatatypeData, ParsedType,
+ detail::PropertyData>(1, 1, 0, 0, 0),
+ TypeTagForDatatypeAllocSize =
+ ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
+ detail::TypeTagForDatatypeData, ParsedType,
+ detail::PropertyData>(1, 0, 1, 0, 0),
PropertyAllocSize =
- sizeof(ParsedAttr) +
- (sizeof(ParsedAttr::PropertyData) + sizeof(void *) - 1) /
- sizeof(void *) * sizeof(void *)
+ ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
+ detail::TypeTagForDatatypeData, ParsedType,
+ detail::PropertyData>(0, 0, 0, 0, 1),
};
private:
@@ -656,7 +681,16 @@ public:
ArgsUnion *args, unsigned numArgs,
ParsedAttr::Syntax syntax,
SourceLocation ellipsisLoc = SourceLocation()) {
- void *memory = allocate(sizeof(ParsedAttr) + numArgs * sizeof(ArgsUnion));
+ size_t temp =
+ ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
+ detail::TypeTagForDatatypeData, ParsedType,
+ detail::PropertyData>(numArgs, 0, 0, 0, 0);
+ (void)temp;
+ void *memory = allocate(
+ ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
+ detail::TypeTagForDatatypeData, ParsedType,
+ detail::PropertyData>(numArgs, 0, 0, 0,
+ 0));
return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
args, numArgs, syntax, ellipsisLoc));
}
@@ -679,8 +713,10 @@ public:
IdentifierInfo *scopeName, SourceLocation scopeLoc,
IdentifierLoc *Param1, IdentifierLoc *Param2,
IdentifierLoc *Param3, ParsedAttr::Syntax syntax) {
- size_t size = sizeof(ParsedAttr) + 3 * sizeof(ArgsUnion);
- void *memory = allocate(size);
+ void *memory = allocate(
+ ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
+ detail::TypeTagForDatatypeData, ParsedType,
+ detail::PropertyData>(3, 0, 0, 0, 0));
return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
Param1, Param2, Param3, syntax));
}
@@ -702,7 +738,10 @@ public:
IdentifierInfo *scopeName,
SourceLocation scopeLoc, ParsedType typeArg,
ParsedAttr::Syntax syntaxUsed) {
- void *memory = allocate(sizeof(ParsedAttr) + sizeof(void *));
+ void *memory = allocate(
+ ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
+ detail::TypeTagForDatatypeData, ParsedType,
+ detail::PropertyData>(0, 0, 0, 1, 0));
return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
typeArg, syntaxUsed));
}
@@ -728,10 +767,6 @@ public:
ParsedAttr &operator[](SizeType pos) { return *AttrList[pos]; }
const ParsedAttr &operator[](SizeType pos) const { return *AttrList[pos]; }
- void addAtStart(ParsedAttr *newAttr) {
- assert(newAttr);
- AttrList.insert(AttrList.begin(), newAttr);
- }
void addAtEnd(ParsedAttr *newAttr) {
assert(newAttr);
AttrList.push_back(newAttr);
@@ -785,6 +820,23 @@ public:
iterator end() { return iterator(AttrList.end()); }
const_iterator end() const { return const_iterator(AttrList.end()); }
+ ParsedAttr &front() {
+ assert(!empty());
+ return *AttrList.front();
+ }
+ const ParsedAttr &front() const {
+ assert(!empty());
+ return *AttrList.front();
+ }
+ ParsedAttr &back() {
+ assert(!empty());
+ return *AttrList.back();
+ }
+ const ParsedAttr &back() const {
+ assert(!empty());
+ return *AttrList.back();
+ }
+
bool hasAttribute(ParsedAttr::Kind K) const {
return llvm::any_of(
AttrList, [K](const ParsedAttr *AL) { return AL->getKind() == K; });
@@ -826,7 +878,7 @@ public:
SourceLocation ellipsisLoc = SourceLocation()) {
ParsedAttr *attr = pool.create(attrName, attrRange, scopeName, scopeLoc,
args, numArgs, syntax, ellipsisLoc);
- addAtStart(attr);
+ addAtEnd(attr);
return attr;
}
@@ -842,7 +894,7 @@ public:
ParsedAttr *attr = pool.create(
attrName, attrRange, scopeName, scopeLoc, Param, introduced, deprecated,
obsoleted, unavailable, MessageExpr, syntax, strict, ReplacementExpr);
- addAtStart(attr);
+ addAtEnd(attr);
return attr;
}
@@ -853,7 +905,7 @@ public:
IdentifierLoc *Param3, ParsedAttr::Syntax syntax) {
ParsedAttr *attr = pool.create(attrName, attrRange, scopeName, scopeLoc,
Param1, Param2, Param3, syntax);
- addAtStart(attr);
+ addAtEnd(attr);
return attr;
}
@@ -867,7 +919,7 @@ public:
ParsedAttr *attr = pool.createTypeTagForDatatype(
attrName, attrRange, scopeName, scopeLoc, argumentKind, matchingCType,
layoutCompatible, mustBeNull, syntax);
- addAtStart(attr);
+ addAtEnd(attr);
return attr;
}
@@ -878,7 +930,7 @@ public:
ParsedAttr::Syntax syntaxUsed) {
ParsedAttr *attr = pool.createTypeAttribute(attrName, attrRange, scopeName,
scopeLoc, typeArg, syntaxUsed);
- addAtStart(attr);
+ addAtEnd(attr);
return attr;
}
@@ -891,7 +943,7 @@ public:
ParsedAttr *attr =
pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc,
getterId, setterId, syntaxUsed);
- addAtStart(attr);
+ addAtEnd(attr);
return attr;
}
@@ -926,6 +978,34 @@ enum AttributeDeclKind {
ExpectedFunctionWithProtoType,
};
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+ const ParsedAttr &At) {
+ DB.AddTaggedVal(reinterpret_cast<intptr_t>(At.getName()),
+ DiagnosticsEngine::ak_identifierinfo);
+ return DB;
+}
+
+inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+ const ParsedAttr &At) {
+ PD.AddTaggedVal(reinterpret_cast<intptr_t>(At.getName()),
+ DiagnosticsEngine::ak_identifierinfo);
+ return PD;
+}
+
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+ const ParsedAttr *At) {
+ DB.AddTaggedVal(reinterpret_cast<intptr_t>(At->getName()),
+ DiagnosticsEngine::ak_identifierinfo);
+ return DB;
+}
+
+inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+ const ParsedAttr *At) {
+ PD.AddTaggedVal(reinterpret_cast<intptr_t>(At->getName()),
+ DiagnosticsEngine::ak_identifierinfo);
+ return PD;
+}
+
} // namespace clang
#endif // LLVM_CLANG_SEMA_ATTRIBUTELIST_H
diff --git a/include/clang/Sema/Scope.h b/include/clang/Sema/Scope.h
index 11fa0362124b..9d9ab0514fb5 100644
--- a/include/clang/Sema/Scope.h
+++ b/include/clang/Sema/Scope.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_SEMA_SCOPE_H
#define LLVM_CLANG_SEMA_SCOPE_H
+#include "clang/AST/Decl.h"
#include "clang/Basic/Diagnostic.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallPtrSet.h"
diff --git a/include/clang/Sema/ScopeInfo.h b/include/clang/Sema/ScopeInfo.h
index 5925fd6ccead..e09a68aba707 100644
--- a/include/clang/Sema/ScopeInfo.h
+++ b/include/clang/Sema/ScopeInfo.h
@@ -31,6 +31,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include <algorithm>
@@ -202,6 +203,12 @@ public:
/// function.
SmallVector<CompoundScopeInfo, 4> CompoundScopes;
+ /// The set of blocks that are introduced in this function.
+ llvm::SmallPtrSet<const BlockDecl *, 1> Blocks;
+
+ /// The set of __block variables that are introduced in this function.
+ llvm::TinyPtrVector<VarDecl *> ByrefBlockVars;
+
/// A list of PartialDiagnostics created but delayed within the
/// current function scope. These diagnostics are vetted for reachability
/// prior to being emitted.
@@ -426,6 +433,16 @@ public:
(HasBranchProtectedScope && HasBranchIntoScope));
}
+ // Add a block introduced in this function.
+ void addBlock(const BlockDecl *BD) {
+ Blocks.insert(BD);
+ }
+
+ // Add a __block variable introduced in this function.
+ void addByrefBlockVar(VarDecl *VD) {
+ ByrefBlockVars.push_back(VD);
+ }
+
bool isCoroutine() const { return !FirstCoroutineStmtLoc.isInvalid(); }
void setFirstCoroutineStmt(SourceLocation Loc, StringRef Keyword) {
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index b1077c620f8a..e5b7465820a9 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -153,6 +153,7 @@ namespace clang {
class ObjCPropertyDecl;
class ObjCProtocolDecl;
class OMPThreadPrivateDecl;
+ class OMPRequiresDecl;
class OMPDeclareReductionDecl;
class OMPDeclareSimdDecl;
class OMPClause;
@@ -306,6 +307,10 @@ class Sema {
}
bool shouldLinkPossiblyHiddenDecl(LookupResult &Old, const NamedDecl *New);
+ void setupImplicitSpecialMemberType(CXXMethodDecl *SpecialMem,
+ QualType ResultTy,
+ ArrayRef<QualType> Args);
+
public:
typedef OpaquePtr<DeclGroupRef> DeclGroupPtrTy;
typedef OpaquePtr<TemplateName> TemplateTy;
@@ -490,15 +495,24 @@ public:
/// VisContext - Manages the stack for \#pragma GCC visibility.
void *VisContext; // Really a "PragmaVisStack*"
- /// This represents the stack of attributes that were pushed by
- /// \#pragma clang attribute.
+ /// This an attribute introduced by \#pragma clang attribute.
struct PragmaAttributeEntry {
SourceLocation Loc;
ParsedAttr *Attribute;
SmallVector<attr::SubjectMatchRule, 4> MatchRules;
bool IsUsed;
};
- SmallVector<PragmaAttributeEntry, 2> PragmaAttributeStack;
+
+ /// A push'd group of PragmaAttributeEntries.
+ struct PragmaAttributeGroup {
+ /// The location of the push attribute.
+ SourceLocation Loc;
+ /// The namespace of this push group.
+ const IdentifierInfo *Namespace;
+ SmallVector<PragmaAttributeEntry, 2> Entries;
+ };
+
+ SmallVector<PragmaAttributeGroup, 2> PragmaAttributeStack;
/// The declaration that is currently receiving an attribute from the
/// #pragma attribute stack.
@@ -608,7 +622,15 @@ public:
/// that had their exception spec checks delayed, plus the overridden
/// function.
SmallVector<std::pair<const CXXMethodDecl*, const CXXMethodDecl*>, 2>
- DelayedExceptionSpecChecks;
+ DelayedOverridingExceptionSpecChecks;
+
+ /// All the function redeclarations seen during a class definition that had
+ /// their exception spec checks delayed, plus the prior declaration they
+ /// should be checked against. Except during error recovery, the new decl
+ /// should always be a friend declaration, as that's the only valid way to
+ /// redeclare a special member before its class is complete.
+ SmallVector<std::pair<FunctionDecl*, FunctionDecl*>, 2>
+ DelayedEquivalentExceptionSpecChecks;
/// All the members seen during a class definition which were both
/// explicitly defaulted and had explicitly-specified exception
@@ -983,6 +1005,8 @@ public:
/// expressions for which we have deferred checking the destructor.
SmallVector<CXXBindTemporaryExpr *, 8> DelayedDecltypeBinds;
+ llvm::SmallPtrSet<const Expr *, 8> PossibleDerefs;
+
/// \brief Describes whether we are in an expression constext which we have
/// to handle differently.
enum ExpressionKind {
@@ -1016,6 +1040,9 @@ public:
/// A stack of expression evaluation contexts.
SmallVector<ExpressionEvaluationContextRecord, 8> ExprEvalContexts;
+ /// Emit a warning for all pending noderef expressions that we recorded.
+ void WarnOnPendingNoDerefs(ExpressionEvaluationContextRecord &Rec);
+
/// Compute the mangling number context for a lambda expression or
/// block literal.
///
@@ -1342,6 +1369,7 @@ public:
void PopCompoundScope();
sema::CompoundScopeInfo &getCurCompoundScope() const;
+ bool isCurCompoundStmtAStmtExpr() const;
bool hasAnyUnrecoverableErrorsInThisFunction() const;
@@ -1435,8 +1463,6 @@ public:
TypeSourceInfo *GetTypeForDeclarator(Declarator &D, Scope *S);
TypeSourceInfo *GetTypeForDeclaratorCast(Declarator &D, QualType FromTy);
- TypeSourceInfo *GetTypeSourceInfoForDeclarator(Declarator &D, QualType T,
- TypeSourceInfo *ReturnTypeInfo);
/// Package the given type and TSI into a ParsedType.
ParsedType CreateParsedType(QualType T, TypeSourceInfo *TInfo);
@@ -1530,6 +1556,17 @@ public:
};
private:
+ /// Methods for marking which expressions involve dereferencing a pointer
+ /// marked with the 'noderef' attribute. Expressions are checked bottom up as
+ /// they are parsed, meaning that a noderef pointer may not be accessed. For
+ /// example, in `&*p` where `p` is a noderef pointer, we will first parse the
+ /// `*p`, but need to check that `address of` is called on it. This requires
+ /// keeping a container of all pending expressions and checking if the address
+ /// of them are eventually taken.
+ void CheckSubscriptAccessOfNoDeref(const ArraySubscriptExpr *E);
+ void CheckAddressOfNoDeref(const Expr *E);
+ void CheckMemberAccessOfNoDeref(const MemberExpr *E);
+
bool RequireCompleteTypeImpl(SourceLocation Loc, QualType T,
TypeDiagnoser *Diagnoser);
@@ -1556,7 +1593,7 @@ public:
/// visible at the specified location.
void makeMergedDefinitionVisible(NamedDecl *ND);
- bool isModuleVisible(const Module *M) { return VisibleModules.isVisible(M); }
+ bool isModuleVisible(const Module *M, bool ModulePrivate = false);
/// Determine whether a declaration is visible to name lookup.
bool isVisible(const NamedDecl *D) {
@@ -1613,6 +1650,8 @@ public:
SourceLocation Loc, const NamedDecl *D,
ArrayRef<const NamedDecl *> Equiv);
+ bool isUsualDeallocationFunction(const CXXMethodDecl *FD);
+
bool isCompleteType(SourceLocation Loc, QualType T) {
return !RequireCompleteTypeImpl(Loc, T, nullptr);
}
@@ -1925,7 +1964,7 @@ public:
bool CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous);
void CheckVariableDeclarationType(VarDecl *NewVD);
bool DeduceVariableDeclarationType(VarDecl *VDecl, bool DirectInit,
- Expr *Init);
+ Expr *&Init);
void CheckCompleteVariableDeclaration(VarDecl *VD);
void CheckCompleteDecompositionDeclaration(DecompositionDecl *DD);
void MaybeSuggestAddingStaticToDecl(const FunctionDecl *D);
@@ -1950,6 +1989,8 @@ public:
FunctionDecl *NewFD, LookupResult &Previous,
bool IsMemberSpecialization);
bool shouldLinkDependentDeclWithPrevious(Decl *D, Decl *OldDecl);
+ bool canFullyTypeCheckRedeclaration(ValueDecl *NewD, ValueDecl *OldD,
+ QualType NewT, QualType OldT);
void CheckMain(FunctionDecl *FD, const DeclSpec &D);
void CheckMSVCRTEntryPoint(FunctionDecl *FD);
Attr *getImplicitCodeSegOrSectionAttrForFunction(const FunctionDecl *FD, bool IsDefinition);
@@ -1983,6 +2024,7 @@ public:
SourceLocation AttrEnd);
void SetDeclDeleted(Decl *dcl, SourceLocation DelLoc);
void SetDeclDefaulted(Decl *dcl, SourceLocation DefaultLoc);
+ void CheckStaticLocalForDllExport(VarDecl *VD);
void FinalizeDeclaration(Decl *D);
DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
ArrayRef<Decl *> Group);
@@ -2456,11 +2498,11 @@ public:
unsigned AttrSpellingListIndex);
OptimizeNoneAttr *mergeOptimizeNoneAttr(Decl *D, SourceRange Range,
unsigned AttrSpellingListIndex);
- InternalLinkageAttr *mergeInternalLinkageAttr(Decl *D, SourceRange Range,
- IdentifierInfo *Ident,
- unsigned AttrSpellingListIndex);
- CommonAttr *mergeCommonAttr(Decl *D, SourceRange Range, IdentifierInfo *Ident,
- unsigned AttrSpellingListIndex);
+ InternalLinkageAttr *mergeInternalLinkageAttr(Decl *D, const ParsedAttr &AL);
+ InternalLinkageAttr *mergeInternalLinkageAttr(Decl *D,
+ const InternalLinkageAttr &AL);
+ CommonAttr *mergeCommonAttr(Decl *D, const ParsedAttr &AL);
+ CommonAttr *mergeCommonAttr(Decl *D, const CommonAttr &AL);
void mergeDeclAttributes(NamedDecl *New, Decl *Old,
AvailabilityMergeKind AMK = AMK_Redeclaration);
@@ -2714,13 +2756,15 @@ public:
typedef llvm::SmallSetVector<DeclContext *, 16> AssociatedNamespaceSet;
typedef llvm::SmallSetVector<CXXRecordDecl *, 16> AssociatedClassSet;
- void AddOverloadCandidate(FunctionDecl *Function,
- DeclAccessPair FoundDecl,
+ using ADLCallKind = CallExpr::ADLCallKind;
+
+ void AddOverloadCandidate(FunctionDecl *Function, DeclAccessPair FoundDecl,
ArrayRef<Expr *> Args,
OverloadCandidateSet &CandidateSet,
bool SuppressUserConversions = false,
bool PartialOverloading = false,
bool AllowExplicit = false,
+ ADLCallKind IsADLCandidate = ADLCallKind::NotADL,
ConversionSequenceList EarlyConversions = None);
void AddFunctionCandidates(const UnresolvedSetImpl &Functions,
ArrayRef<Expr *> Args,
@@ -2754,13 +2798,12 @@ public:
OverloadCandidateSet& CandidateSet,
bool SuppressUserConversions = false,
bool PartialOverloading = false);
- void AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
- DeclAccessPair FoundDecl,
- TemplateArgumentListInfo *ExplicitTemplateArgs,
- ArrayRef<Expr *> Args,
- OverloadCandidateSet& CandidateSet,
- bool SuppressUserConversions = false,
- bool PartialOverloading = false);
+ void AddTemplateOverloadCandidate(
+ FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl,
+ TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef<Expr *> Args,
+ OverloadCandidateSet &CandidateSet, bool SuppressUserConversions = false,
+ bool PartialOverloading = false,
+ ADLCallKind IsADLCandidate = ADLCallKind::NotADL);
bool CheckNonDependentConversions(FunctionTemplateDecl *FunctionTemplate,
ArrayRef<QualType> ParamTypes,
ArrayRef<Expr *> Args,
@@ -2826,11 +2869,7 @@ public:
/// Find the failed Boolean condition within a given Boolean
/// constant expression, and describe it with a string.
- ///
- /// \param AllowTopLevelCond Whether to allow the result to be the
- /// complete top-level condition.
- std::pair<Expr *, std::string>
- findFailedBooleanCondition(Expr *Cond, bool AllowTopLevelCond);
+ std::pair<Expr *, std::string> findFailedBooleanCondition(Expr *Cond);
/// Emit diagnostics for the diagnose_if attributes on Function, ignoring any
/// non-ArgDependent DiagnoseIfAttrs.
@@ -3378,30 +3417,6 @@ public:
/// Valid types should not have multiple attributes with different CCs.
const AttributedType *getCallingConvAttributedType(QualType T) const;
- /// Check whether a nullability type specifier can be added to the given
- /// type.
- ///
- /// \param type The type to which the nullability specifier will be
- /// added. On success, this type will be updated appropriately.
- ///
- /// \param nullability The nullability specifier to add.
- ///
- /// \param nullabilityLoc The location of the nullability specifier.
- ///
- /// \param isContextSensitive Whether this nullability specifier was
- /// written as a context-sensitive keyword (in an Objective-C
- /// method) or an Objective-C property attribute, rather than as an
- /// underscored type specifier.
- ///
- /// \param allowArrayTypes Whether to accept nullability specifiers on an
- /// array type (e.g., because it will decay to a pointer).
- ///
- /// \returns true if nullability cannot be applied, false otherwise.
- bool checkNullabilityTypeSpecifier(QualType &type, NullabilityKind nullability,
- SourceLocation nullabilityLoc,
- bool isContextSensitive,
- bool allowArrayTypes);
-
/// Stmt attributes - this routine is the top level dispatcher.
StmtResult ProcessStmtAttributes(Stmt *Stmt,
const ParsedAttributesView &Attrs,
@@ -3675,16 +3690,17 @@ public:
return MakeFullExpr(Arg, Arg ? Arg->getExprLoc() : SourceLocation());
}
FullExprArg MakeFullExpr(Expr *Arg, SourceLocation CC) {
- return FullExprArg(ActOnFinishFullExpr(Arg, CC).get());
+ return FullExprArg(
+ ActOnFinishFullExpr(Arg, CC, /*DiscardedValue*/ false).get());
}
FullExprArg MakeFullDiscardedValueExpr(Expr *Arg) {
ExprResult FE =
- ActOnFinishFullExpr(Arg, Arg ? Arg->getExprLoc() : SourceLocation(),
- /*DiscardedValue*/ true);
+ ActOnFinishFullExpr(Arg, Arg ? Arg->getExprLoc() : SourceLocation(),
+ /*DiscardedValue*/ true);
return FullExprArg(FE.get());
}
- StmtResult ActOnExprStmt(ExprResult Arg);
+ StmtResult ActOnExprStmt(ExprResult Arg, bool DiscardedValue = true);
StmtResult ActOnExprStmtError();
StmtResult ActOnNullStmt(SourceLocation SemiLoc,
@@ -3790,12 +3806,14 @@ public:
StmtResult ActOnCXXForRangeStmt(Scope *S, SourceLocation ForLoc,
SourceLocation CoawaitLoc,
+ Stmt *InitStmt,
Stmt *LoopVar,
SourceLocation ColonLoc, Expr *Collection,
SourceLocation RParenLoc,
BuildForRangeKind Kind);
StmtResult BuildCXXForRangeStmt(SourceLocation ForLoc,
SourceLocation CoawaitLoc,
+ Stmt *InitStmt,
SourceLocation ColonLoc,
Stmt *RangeDecl, Stmt *Begin, Stmt *End,
Expr *Cond, Expr *Inc,
@@ -3983,7 +4001,8 @@ public:
void DiagnoseAvailabilityOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs,
const ObjCInterfaceDecl *UnknownObjCClass,
bool ObjCPropertyAccess,
- bool AvoidPartialAvailabilityChecks = false);
+ bool AvoidPartialAvailabilityChecks = false,
+ ObjCInterfaceDecl *ClassReceiver = nullptr);
bool makeUnavailableInSystemHeader(SourceLocation loc,
UnavailableAttr::ImplicitReason reason);
@@ -3998,7 +4017,8 @@ public:
bool DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs,
const ObjCInterfaceDecl *UnknownObjCClass = nullptr,
bool ObjCPropertyAccess = false,
- bool AvoidPartialAvailabilityChecks = false);
+ bool AvoidPartialAvailabilityChecks = false,
+ ObjCInterfaceDecl *ClassReciever = nullptr);
void NoteDeletedFunction(FunctionDecl *FD);
void NoteDeletedInheritingConstructor(CXXConstructorDecl *CD);
std::string getDeletedOrUnavailableSuffix(const FunctionDecl *FD);
@@ -4223,7 +4243,7 @@ public:
TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr);
ExprResult BuildPredefinedExpr(SourceLocation Loc,
- PredefinedExpr::IdentType IT);
+ PredefinedExpr::IdentKind IK);
ExprResult ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind);
ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val);
@@ -4376,12 +4396,11 @@ public:
MultiExprArg ArgExprs, SourceLocation RParenLoc,
Expr *ExecConfig = nullptr,
bool IsExecConfig = false);
- ExprResult BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
- SourceLocation LParenLoc,
- ArrayRef<Expr *> Arg,
- SourceLocation RParenLoc,
- Expr *Config = nullptr,
- bool IsExecConfig = false);
+ ExprResult
+ BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, SourceLocation LParenLoc,
+ ArrayRef<Expr *> Arg, SourceLocation RParenLoc,
+ Expr *Config = nullptr, bool IsExecConfig = false,
+ ADLCallKind UsesADL = ADLCallKind::NotADL);
ExprResult ActOnCUDAExecConfigExpr(Scope *S, SourceLocation LLLLoc,
MultiExprArg ExecConfig,
@@ -4582,6 +4601,11 @@ private:
// of a ComparisonCategoryType enumerator.
llvm::SmallBitVector FullyCheckedComparisonCategories;
+ ValueDecl *tryLookupCtorInitMemberDecl(CXXRecordDecl *ClassDecl,
+ CXXScopeSpec &SS,
+ ParsedType TemplateTypeTy,
+ IdentifierInfo *MemberOrBase);
+
public:
/// Lookup the specified comparison category types in the standard
/// library, an check the VarDecls possibly returned by the operator<=>
@@ -4799,7 +4823,7 @@ public:
ImplicitExceptionSpecification
ComputeDefaultedCopyCtorExceptionSpec(CXXMethodDecl *MD);
- /// Determine what sort of exception specification a defautled
+ /// Determine what sort of exception specification a defaulted
/// copy assignment operator of a class will have, and whether the
/// parameter will be const.
ImplicitExceptionSpecification
@@ -4898,8 +4922,7 @@ public:
///
/// C++11 says that user-defined destructors with no exception spec get one
/// that looks as if the destructor was implicitly declared.
- void AdjustDestructorExceptionSpec(CXXRecordDecl *ClassDecl,
- CXXDestructorDecl *Destructor);
+ void AdjustDestructorExceptionSpec(CXXDestructorDecl *Destructor);
/// Define the specified inheriting constructor.
void DefineInheritingConstructor(SourceLocation UseLoc,
@@ -5100,7 +5123,7 @@ public:
/// using the given declaration (which is either a class template or a
/// class) along with the given qualifiers.
/// along with the qualifiers placed on '*this'.
- CXXThisScopeRAII(Sema &S, Decl *ContextDecl, unsigned CXXThisTypeQuals,
+ CXXThisScopeRAII(Sema &S, Decl *ContextDecl, Qualifiers CXXThisTypeQuals,
bool Enabled = true);
~CXXThisScopeRAII();
@@ -5185,6 +5208,15 @@ public:
SourceRange DirectInitRange,
Expr *Initializer);
+ /// Determine whether \p FD is an aligned allocation or deallocation
+ /// function that is unavailable.
+ bool isUnavailableAlignedAllocationFunction(const FunctionDecl &FD) const;
+
+ /// Produce diagnostics if \p FD is an aligned allocation or deallocation
+ /// function that is unavailable.
+ void diagnoseUnavailableAlignedAllocation(const FunctionDecl &FD,
+ SourceLocation Loc);
+
bool CheckAllocatedType(QualType AllocType, SourceLocation Loc,
SourceRange R);
@@ -5314,14 +5346,12 @@ public:
CreateMaterializeTemporaryExpr(QualType T, Expr *Temporary,
bool BoundToLvalueReference);
- ExprResult ActOnFinishFullExpr(Expr *Expr) {
- return ActOnFinishFullExpr(Expr, Expr ? Expr->getExprLoc()
- : SourceLocation());
+ ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue) {
+ return ActOnFinishFullExpr(
+ Expr, Expr ? Expr->getExprLoc() : SourceLocation(), DiscardedValue);
}
ExprResult ActOnFinishFullExpr(Expr *Expr, SourceLocation CC,
- bool DiscardedValue = false,
- bool IsConstexpr = false,
- bool IsLambdaInitCaptureInitializer = false);
+ bool DiscardedValue, bool IsConstexpr = false);
StmtResult ActOnFinishFullStmt(Stmt *Stmt);
// Marks SS invalid if it represents an incomplete type.
@@ -5586,7 +5616,9 @@ public:
void finishLambdaExplicitCaptures(sema::LambdaScopeInfo *LSI);
/// Introduce the lambda parameters into scope.
- void addLambdaParameters(CXXMethodDecl *CallOperator, Scope *CurScope);
+ void addLambdaParameters(
+ ArrayRef<LambdaIntroducer::LambdaCapture> Captures,
+ CXXMethodDecl *CallOperator, Scope *CurScope);
/// Deduce a block or lambda's return type based on the return
/// statements present in the body.
@@ -6044,6 +6076,10 @@ public:
AccessResult CheckMemberAccess(SourceLocation UseLoc,
CXXRecordDecl *NamingClass,
DeclAccessPair Found);
+ AccessResult
+ CheckStructuredBindingMemberAccess(SourceLocation UseLoc,
+ CXXRecordDecl *DecomposedClass,
+ DeclAccessPair Field);
AccessResult CheckMemberOperatorAccess(SourceLocation Loc,
Expr *ObjectExpr,
Expr *ArgExpr,
@@ -6057,7 +6093,8 @@ public:
bool ForceCheck = false,
bool ForceUnprivileged = false);
void CheckLookupAccess(const LookupResult &R);
- bool IsSimplyAccessible(NamedDecl *decl, DeclContext *Ctx);
+ bool IsSimplyAccessible(NamedDecl *Decl, CXXRecordDecl *NamingClass,
+ QualType BaseType);
bool isSpecialMemberAccessibleForDeletion(CXXMethodDecl *decl,
AccessSpecifier access,
QualType objectType);
@@ -6202,7 +6239,8 @@ public:
bool CheckTemplateParameterList(TemplateParameterList *NewParams,
TemplateParameterList *OldParams,
- TemplateParamListContext TPC);
+ TemplateParamListContext TPC,
+ SkipBodyInfo *SkipBody = nullptr);
TemplateParameterList *MatchTemplateParametersToScopeSpecifier(
SourceLocation DeclStartLoc, SourceLocation DeclLoc,
const CXXScopeSpec &SS, TemplateIdAnnotation *TemplateId,
@@ -6322,9 +6360,9 @@ public:
const TemplateArgumentListInfo &ExplicitTemplateArgs,
LookupResult &Previous);
- bool CheckFunctionTemplateSpecialization(FunctionDecl *FD,
- TemplateArgumentListInfo *ExplicitTemplateArgs,
- LookupResult &Previous);
+ bool CheckFunctionTemplateSpecialization(
+ FunctionDecl *FD, TemplateArgumentListInfo *ExplicitTemplateArgs,
+ LookupResult &Previous, bool QualifiedFriend = false);
bool CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous);
void CompleteMemberSpecialization(NamedDecl *Member, LookupResult &Previous);
@@ -7061,7 +7099,7 @@ public:
QualType deduceVarTypeFromInitializer(VarDecl *VDecl, DeclarationName Name,
QualType Type, TypeSourceInfo *TSI,
SourceRange Range, bool DirectInit,
- Expr *Init);
+ Expr *&Init);
TypeLoc getReturnTypeLoc(FunctionDecl *FD) const;
@@ -7168,6 +7206,10 @@ public:
/// has been used when naming a template-id.
DefaultTemplateArgumentChecking,
+ /// We are computing the exception specification for a defaulted special
+ /// member function.
+ ExceptionSpecEvaluation,
+
/// We are instantiating the exception specification for a function
/// template which was deferred until it was needed.
ExceptionSpecInstantiation,
@@ -7726,7 +7768,7 @@ public:
SourceLocation Loc,
DeclarationName Entity,
CXXRecordDecl *ThisContext,
- unsigned ThisTypeQuals);
+ Qualifiers ThisTypeQuals);
void SubstExceptionSpec(FunctionDecl *New, const FunctionProtoType *Proto,
const MultiLevelTemplateArgumentList &Args);
bool SubstExceptionSpec(SourceLocation Loc,
@@ -8071,10 +8113,6 @@ public:
SourceLocation ProtocolRAngleLoc,
bool FailOnError = false);
- /// Check the application of the Objective-C '__kindof' qualifier to
- /// the given type.
- bool checkObjCKindOfType(QualType &type, SourceLocation loc);
-
/// Ensure attributes are consistent with type.
/// \param [in, out] Attributes The attributes to check; they will
/// be modified to be consistent with \p PropertyTy.
@@ -8434,6 +8472,10 @@ public:
/// \#pragma clang fp contract
void ActOnPragmaFPContract(LangOptions::FPContractModeKind FPC);
+ /// ActOnPragmaFenvAccess - Called on well formed
+ /// \#pragma STDC FENV_ACCESS
+ void ActOnPragmaFEnvAccess(LangOptions::FEnvAccessModeKind FPC);
+
/// AddAlignmentAttributesForRecord - Adds any needed alignment attributes to
/// a the record decl, to handle '\#pragma pack' and '\#pragma options align'.
void AddAlignmentAttributesForRecord(RecordDecl *RD);
@@ -8465,12 +8507,15 @@ public:
/// the appropriate attribute.
void AddCFAuditedAttribute(Decl *D);
- /// Called on well-formed '\#pragma clang attribute push'.
- void ActOnPragmaAttributePush(ParsedAttr &Attribute, SourceLocation PragmaLoc,
- attr::ParsedSubjectMatchRuleSet Rules);
+ void ActOnPragmaAttributeAttribute(ParsedAttr &Attribute,
+ SourceLocation PragmaLoc,
+ attr::ParsedSubjectMatchRuleSet Rules);
+ void ActOnPragmaAttributeEmptyPush(SourceLocation PragmaLoc,
+ const IdentifierInfo *Namespace);
/// Called on well-formed '\#pragma clang attribute pop'.
- void ActOnPragmaAttributePop(SourceLocation PragmaLoc);
+ void ActOnPragmaAttributePop(SourceLocation PragmaLoc,
+ const IdentifierInfo *Namespace);
/// Adds the attributes that have been specified using the
/// '\#pragma clang attribute push' directives to the given declaration.
@@ -8530,9 +8575,9 @@ public:
void AddParameterABIAttr(SourceRange AttrRange, Decl *D,
ParameterABI ABI, unsigned SpellingListIndex);
- void AddNSConsumedAttr(SourceRange AttrRange, Decl *D,
- unsigned SpellingListIndex, bool isNSConsumed,
- bool isTemplateInstantiation);
+ enum class RetainOwnershipKind {NS, CF, OS};
+ void AddXConsumedAttr(Decl *D, SourceRange SR, unsigned SpellingIndex,
+ RetainOwnershipKind K, bool IsTemplateInstantiation);
bool checkNSReturnsRetainedReturnType(SourceLocation loc, QualType type);
@@ -8572,6 +8617,21 @@ public:
llvm::StringRef getCurrentOpenCLExtension() const {
return CurrOpenCLExtension;
}
+
+ /// Check if a function declaration \p FD associates with any
+ /// extensions present in OpenCLDeclExtMap and if so return the
+ /// extension(s) name(s).
+ std::string getOpenCLExtensionsFromDeclExtMap(FunctionDecl *FD);
+
+ /// Check if a function type \p FT associates with any
+ /// extensions present in OpenCLTypeExtMap and if so return the
+ /// extension(s) name(s).
+ std::string getOpenCLExtensionsFromTypeExtMap(FunctionType *FT);
+
+ /// Find an extension in an appropriate extension map and return its name
+ template<typename T, typename MapT>
+ std::string getOpenCLExtensionsFromExtMap(T* FT, MapT &Map);
+
void setCurrentOpenCLExtension(llvm::StringRef Ext) {
CurrOpenCLExtension = Ext;
}
@@ -8616,8 +8676,8 @@ public:
//
private:
void *VarDataSharingAttributesStack;
- /// Set to true inside '#pragma omp declare target' region.
- bool IsInOpenMPDeclareTargetContext = false;
+ /// Number of nested '#pragma omp declare target' directives.
+ unsigned DeclareTargetNestingLevel = 0;
/// Initialization of data-sharing attributes stack.
void InitDataSharingAttributesStack();
void DestroyDataSharingAttributesStack();
@@ -8662,10 +8722,14 @@ public:
/// Check if the specified variable is used in one of the private
/// clauses (private, firstprivate, lastprivate, reduction etc.) in OpenMP
/// constructs.
- VarDecl *isOpenMPCapturedDecl(ValueDecl *D) const;
+ VarDecl *isOpenMPCapturedDecl(ValueDecl *D);
ExprResult getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
ExprObjectKind OK, SourceLocation Loc);
+ /// If the current region is a loop-based region, mark the start of the loop
+ /// construct.
+ void startOpenMPLoop();
+
/// Check if the specified variable is used in 'private' clause.
/// \param Level Relative level of nested OpenMP construct for that the check
/// is performed.
@@ -8713,6 +8777,12 @@ public:
/// Builds a new OpenMPThreadPrivateDecl and checks its correctness.
OMPThreadPrivateDecl *CheckOMPThreadPrivateDecl(SourceLocation Loc,
ArrayRef<Expr *> VarList);
+ /// Called on well-formed '#pragma omp requires'.
+ DeclGroupPtrTy ActOnOpenMPRequiresDirective(SourceLocation Loc,
+ ArrayRef<OMPClause *> ClauseList);
+ /// Check restrictions on Requires directive
+ OMPRequiresDecl *CheckOMPRequiresDecl(SourceLocation Loc,
+ ArrayRef<OMPClause *> Clauses);
/// Check if the specified type is allowed to be used in 'omp declare
/// reduction' construct.
QualType ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
@@ -8746,11 +8816,12 @@ public:
OMPDeclareTargetDeclAttr::MapTypeTy MT,
NamedDeclSetType &SameDirectiveDecls);
/// Check declaration inside target region.
- void checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
- SourceLocation IdLoc = SourceLocation());
+ void
+ checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
+ SourceLocation IdLoc = SourceLocation());
/// Return true inside OpenMP declare target region.
bool isInOpenMPDeclareTargetContext() const {
- return IsInOpenMPDeclareTargetContext;
+ return DeclareTargetNestingLevel > 0;
}
/// Return true inside OpenMP target region.
bool isInOpenMPTargetExecutionDirective() const;
@@ -9105,7 +9176,7 @@ public:
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
-
+
OMPClause *ActOnOpenMPSingleExprWithArgClause(
OpenMPClauseKind Kind, ArrayRef<unsigned> Arguments, Expr *Expr,
SourceLocation StartLoc, SourceLocation LParenLoc,
@@ -9153,6 +9224,26 @@ public:
/// Called on well-formed 'nogroup' clause.
OMPClause *ActOnOpenMPNogroupClause(SourceLocation StartLoc,
SourceLocation EndLoc);
+ /// Called on well-formed 'unified_address' clause.
+ OMPClause *ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,
+ SourceLocation EndLoc);
+
+ /// Called on well-formed 'unified_address' clause.
+ OMPClause *ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,
+ SourceLocation EndLoc);
+
+ /// Called on well-formed 'reverse_offload' clause.
+ OMPClause *ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,
+ SourceLocation EndLoc);
+
+ /// Called on well-formed 'dynamic_allocators' clause.
+ OMPClause *ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,
+ SourceLocation EndLoc);
+
+ /// Called on well-formed 'atomic_default_mem_order' clause.
+ OMPClause *ActOnOpenMPAtomicDefaultMemOrderClause(
+ OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindLoc,
+ SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc);
OMPClause *ActOnOpenMPVarListClause(
OpenMPClauseKind Kind, ArrayRef<Expr *> Vars, Expr *TailExpr,
@@ -9160,7 +9251,9 @@ public:
SourceLocation ColonLoc, SourceLocation EndLoc,
CXXScopeSpec &ReductionIdScopeSpec,
const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind,
- OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier,
+ OpenMPLinearClauseKind LinKind,
+ ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
+ ArrayRef<SourceLocation> MapTypeModifiersLoc,
OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
SourceLocation DepLinMapLoc);
/// Called on well-formed 'private' clause.
@@ -9244,7 +9337,8 @@ public:
SourceLocation EndLoc);
/// Called on well-formed 'map' clause.
OMPClause *
- ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier,
+ ActOnOpenMPMapClause(ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
+ ArrayRef<SourceLocation> MapTypeModifiersLoc,
OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
SourceLocation MapLoc, SourceLocation ColonLoc,
ArrayRef<Expr *> VarList, SourceLocation StartLoc,
@@ -9571,6 +9665,10 @@ public:
AssignmentAction Action,
CheckedConversionKind CCK);
+ ExprResult PerformQualificationConversion(
+ Expr *E, QualType Ty, ExprValueKind VK = VK_RValue,
+ CheckedConversionKind CCK = CCK_ImplicitConversion);
+
/// the following "Check" methods will return a valid/converted QualType
/// or a null QualType (indicating an error diagnostic was issued).
@@ -9762,21 +9860,20 @@ public:
/// \param Method - May be null.
/// \param [out] ReturnType - The return type of the send.
/// \return true iff there were any incompatible types.
- bool CheckMessageArgumentTypes(QualType ReceiverType,
+ bool CheckMessageArgumentTypes(const Expr *Receiver, QualType ReceiverType,
MultiExprArg Args, Selector Sel,
ArrayRef<SourceLocation> SelectorLocs,
ObjCMethodDecl *Method, bool isClassMessage,
- bool isSuperMessage,
- SourceLocation lbrac, SourceLocation rbrac,
- SourceRange RecRange,
+ bool isSuperMessage, SourceLocation lbrac,
+ SourceLocation rbrac, SourceRange RecRange,
QualType &ReturnType, ExprValueKind &VK);
/// Determine the result of a message send expression based on
/// the type of the receiver, the method expected to receive the message,
/// and the form of the message send.
- QualType getMessageSendResultType(QualType ReceiverType,
- ObjCMethodDecl *Method,
- bool isClassMessage, bool isSuperMessage);
+ QualType getMessageSendResultType(const Expr *Receiver, QualType ReceiverType,
+ ObjCMethodDecl *Method, bool isClassMessage,
+ bool isSuperMessage);
/// If the given expression involves a message send to a method
/// with a related result type, emit a note describing what happened.
@@ -10245,6 +10342,7 @@ public:
struct CodeCompleteExpressionData;
void CodeCompleteExpression(Scope *S,
const CodeCompleteExpressionData &Data);
+ void CodeCompleteExpression(Scope *S, QualType PreferredType);
void CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base, Expr *OtherOpBase,
SourceLocation OpLoc, bool IsArrow,
bool IsBaseExprStatement);
@@ -10255,16 +10353,27 @@ public:
const VirtSpecifiers *VS = nullptr);
void CodeCompleteBracketDeclarator(Scope *S);
void CodeCompleteCase(Scope *S);
- void CodeCompleteCall(Scope *S, Expr *Fn, ArrayRef<Expr *> Args);
- void CodeCompleteConstructor(Scope *S, QualType Type, SourceLocation Loc,
- ArrayRef<Expr *> Args);
+ /// Reports signatures for a call to CodeCompleteConsumer and returns the
+ /// preferred type for the current argument. Returned type can be null.
+ QualType ProduceCallSignatureHelp(Scope *S, Expr *Fn, ArrayRef<Expr *> Args,
+ SourceLocation OpenParLoc);
+ QualType ProduceConstructorSignatureHelp(Scope *S, QualType Type,
+ SourceLocation Loc,
+ ArrayRef<Expr *> Args,
+ SourceLocation OpenParLoc);
+ QualType ProduceCtorInitMemberSignatureHelp(Scope *S, Decl *ConstructorDecl,
+ CXXScopeSpec SS,
+ ParsedType TemplateTypeTy,
+ ArrayRef<Expr *> ArgExprs,
+ IdentifierInfo *II,
+ SourceLocation OpenParLoc);
void CodeCompleteInitializer(Scope *S, Decl *D);
void CodeCompleteReturn(Scope *S);
void CodeCompleteAfterIf(Scope *S);
- void CodeCompleteAssignmentRHS(Scope *S, Expr *LHS);
+ void CodeCompleteBinaryRHS(Scope *S, Expr *LHS, tok::TokenKind Op);
void CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
- bool EnteringContext);
+ bool EnteringContext, QualType BaseType);
void CodeCompleteUsing(Scope *S);
void CodeCompleteUsingDirective(Scope *S);
void CodeCompleteNamespaceDecl(Scope *S);
@@ -10337,6 +10446,7 @@ public:
IdentifierInfo *Macro,
MacroInfo *MacroInfo,
unsigned Argument);
+ void CodeCompleteIncludedFile(llvm::StringRef Dir, bool IsAngled);
void CodeCompleteNaturalLanguage();
void CodeCompleteAvailabilityPlatformName();
void GatherGlobalCodeCompletions(CodeCompletionAllocator &Allocator,
@@ -10515,7 +10625,8 @@ private:
/// Check if there is a field shadowing.
void CheckShadowInheritedFields(const SourceLocation &Loc,
DeclarationName FieldName,
- const CXXRecordDecl *RD);
+ const CXXRecordDecl *RD,
+ bool DeclIsField = true);
/// Check if the given expression contains 'break' or 'continue'
/// statement that produces control flow different from GCC.
@@ -10658,7 +10769,9 @@ private:
SavePendingParsedClassStateRAII(Sema &S) : S(S) { swapSavedState(); }
~SavePendingParsedClassStateRAII() {
- assert(S.DelayedExceptionSpecChecks.empty() &&
+ assert(S.DelayedOverridingExceptionSpecChecks.empty() &&
+ "there shouldn't be any pending delayed exception spec checks");
+ assert(S.DelayedEquivalentExceptionSpecChecks.empty() &&
"there shouldn't be any pending delayed exception spec checks");
assert(S.DelayedDefaultedMemberExceptionSpecs.empty() &&
"there shouldn't be any pending delayed defaulted member "
@@ -10670,13 +10783,19 @@ private:
private:
Sema &S;
- decltype(DelayedExceptionSpecChecks) SavedExceptionSpecChecks;
+ decltype(DelayedOverridingExceptionSpecChecks)
+ SavedOverridingExceptionSpecChecks;
+ decltype(DelayedEquivalentExceptionSpecChecks)
+ SavedEquivalentExceptionSpecChecks;
decltype(DelayedDefaultedMemberExceptionSpecs)
SavedDefaultedMemberExceptionSpecs;
decltype(DelayedDllExportClasses) SavedDllExportClasses;
void swapSavedState() {
- SavedExceptionSpecChecks.swap(S.DelayedExceptionSpecChecks);
+ SavedOverridingExceptionSpecChecks.swap(
+ S.DelayedOverridingExceptionSpecChecks);
+ SavedEquivalentExceptionSpecChecks.swap(
+ S.DelayedEquivalentExceptionSpecChecks);
SavedDefaultedMemberExceptionSpecs.swap(
S.DelayedDefaultedMemberExceptionSpecs);
SavedDllExportClasses.swap(S.DelayedDllExportClasses);
@@ -10790,7 +10909,6 @@ struct LateParsedTemplate {
/// The template function declaration to be late parsed.
Decl *D;
};
-
} // end namespace clang
namespace llvm {
diff --git a/include/clang/Sema/SemaDiagnostic.h b/include/clang/Sema/SemaDiagnostic.h
index 7740d5e29c00..30a2497a3e87 100644
--- a/include/clang/Sema/SemaDiagnostic.h
+++ b/include/clang/Sema/SemaDiagnostic.h
@@ -10,19 +10,6 @@
#ifndef LLVM_CLANG_SEMA_SEMADIAGNOSTIC_H
#define LLVM_CLANG_SEMA_SEMADIAGNOSTIC_H
-#include "clang/Basic/Diagnostic.h"
-
-namespace clang {
- namespace diag {
- enum {
-#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
- SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
-#define SEMASTART
-#include "clang/Basic/DiagnosticSemaKinds.inc"
-#undef DIAG
- NUM_BUILTIN_SEMA_DIAGNOSTICS
- };
- } // end namespace diag
-} // end namespace clang
+#include "clang/Basic/DiagnosticSema.h"
#endif
diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h
index 430fc48379fe..ec752fb7c796 100644
--- a/include/clang/Serialization/ASTBitCodes.h
+++ b/include/clang/Serialization/ASTBitCodes.h
@@ -1015,6 +1015,10 @@ namespace serialization {
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
PREDEF_TYPE_##Id##_ID,
#include "clang/Basic/OpenCLImageTypes.def"
+ /// \brief OpenCL extension types with auto numeration
+#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
+ PREDEF_TYPE_##Id##_ID,
+#include "clang/Basic/OpenCLExtensionTypes.def"
};
/// The number of predefined type IDs that are reserved for
@@ -1516,6 +1520,9 @@ namespace serialization {
/// An OMPThreadPrivateDecl record.
DECL_OMP_THREADPRIVATE,
+ /// An OMPRequiresDecl record.
+ DECL_OMP_REQUIRES,
+
/// An EmptyDecl record.
DECL_EMPTY,
@@ -1533,6 +1540,8 @@ namespace serialization {
/// An OMPDeclareReductionDecl record.
DECL_OMP_DECLARE_REDUCTION,
+
+ DECL_LAST = DECL_OMP_DECLARE_REDUCTION
};
/// Record codes for each kind of statement or expression.
@@ -1545,7 +1554,7 @@ namespace serialization {
enum StmtCode {
/// A marker record that indicates that we are at the end
/// of an expression.
- STMT_STOP = 128,
+ STMT_STOP = DECL_LAST + 1,
/// A NULL expression.
STMT_NULL_PTR,
@@ -1613,6 +1622,9 @@ namespace serialization {
/// A MS-style AsmStmt record.
STMT_MSASM,
+ /// A constant expression context.
+ EXPR_CONSTANT,
+
/// A PredefinedExpr record.
EXPR_PREDEFINED,
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h
index 0eecb6f5d65a..f97f545852f4 100644
--- a/include/clang/Serialization/ASTReader.h
+++ b/include/clang/Serialization/ASTReader.h
@@ -18,6 +18,7 @@
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/OpenMPClause.h"
#include "clang/AST/TemplateBase.h"
#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
@@ -232,7 +233,7 @@ public:
/// If needsImportVisitation returns \c true, this is called for each
/// AST file imported by this AST file.
- virtual void visitImport(StringRef Filename) {}
+ virtual void visitImport(StringRef ModuleName, StringRef Filename) {}
/// Indicates that a particular module file extension has been read.
virtual void readModuleFileExtension(
@@ -539,6 +540,11 @@ private:
/// declaration that has an exception specification.
llvm::SmallMapVector<Decl *, FunctionDecl *, 4> PendingExceptionSpecUpdates;
+ /// Deduced return type updates that have been loaded but not yet propagated
+ /// across the relevant redeclaration chain. The map key is the canonical
+ /// declaration and the value is the deduced return type.
+ llvm::SmallMapVector<FunctionDecl *, QualType, 4> PendingDeducedTypeUpdates;
+
/// Declarations that have been imported and have typedef names for
/// linkage purposes.
llvm::DenseMap<std::pair<DeclContext *, IdentifierInfo *>, NamedDecl *>
@@ -1056,6 +1062,12 @@ private:
/// Objective-C protocols.
std::deque<InterestingDecl> PotentiallyInterestingDecls;
+ /// The list of deduced function types that we have not yet read, because
+ /// they might contain a deduced return type that refers to a local type
+ /// declared within the function.
+ SmallVector<std::pair<FunctionDecl *, serialization::TypeID>, 16>
+ PendingFunctionTypes;
+
/// The list of redeclaration chains that still need to be
/// reconstructed, and the local offset to the corresponding list
/// of redeclarations.
@@ -2234,6 +2246,9 @@ public:
CXXTemporary *ReadCXXTemporary(ModuleFile &F, const RecordData &Record,
unsigned &Idx);
+ /// Reads one attribute from the current stream position.
+ Attr *ReadAttr(ModuleFile &M, const RecordData &Record, unsigned &Idx);
+
/// Reads attributes from the current stream position.
void ReadAttributes(ASTRecordReader &Record, AttrVec &Attrs);
@@ -2619,6 +2634,11 @@ public:
return ASTReader::ReadVersionTuple(Record, Idx);
}
+ /// Reads one attribute from the current stream position, advancing Idx.
+ Attr *readAttr() {
+ return Reader->ReadAttr(*F, Record, Idx);
+ }
+
/// Reads attributes from the current stream position, advancing Idx.
void readAttributes(AttrVec &Attrs) {
return Reader->ReadAttributes(*this, Attrs);
@@ -2658,6 +2678,21 @@ inline void PCHValidator::Error(const char *Msg) {
Reader.Error(Msg);
}
+class OMPClauseReader : public OMPClauseVisitor<OMPClauseReader> {
+ ASTRecordReader &Record;
+ ASTContext &Context;
+
+public:
+ OMPClauseReader(ASTRecordReader &Record)
+ : Record(Record), Context(Record.getContext()) {}
+
+#define OPENMP_CLAUSE(Name, Class) void Visit##Class(Class *C);
+#include "clang/Basic/OpenMPKinds.def"
+ OMPClause *readClause();
+ void VisitOMPClauseWithPreInit(OMPClauseWithPreInit *C);
+ void VisitOMPClauseWithPostUpdate(OMPClauseWithPostUpdate *C);
+};
+
} // namespace clang
#endif // LLVM_CLANG_SERIALIZATION_ASTREADER_H
diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h
index 7ff5d65bd7d0..11af30ac8373 100644
--- a/include/clang/Serialization/ASTWriter.h
+++ b/include/clang/Serialization/ASTWriter.h
@@ -19,16 +19,17 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/OpenMPClause.h"
#include "clang/AST/TemplateBase.h"
#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
-#include "clang/Frontend/PCHContainerOperations.h"
#include "clang/Sema/SemaConsumer.h"
#include "clang/Serialization/ASTBitCodes.h"
#include "clang/Serialization/ASTDeserializationListener.h"
+#include "clang/Serialization/PCHContainerOperations.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
@@ -955,6 +956,9 @@ public:
return Writer->AddVersionTuple(Version, *Record);
}
+ // Emit an attribute.
+ void AddAttr(const Attr *A);
+
/// Emit a list of attributes.
void AddAttributes(ArrayRef<const Attr*> Attrs);
};
@@ -990,6 +994,18 @@ public:
bool hasEmittedPCH() const { return Buffer->IsComplete; }
};
+class OMPClauseWriter : public OMPClauseVisitor<OMPClauseWriter> {
+ ASTRecordWriter &Record;
+
+public:
+ OMPClauseWriter(ASTRecordWriter &Record) : Record(Record) {}
+#define OPENMP_CLAUSE(Name, Class) void Visit##Class(Class *S);
+#include "clang/Basic/OpenMPKinds.def"
+ void writeClause(OMPClause *C);
+ void VisitOMPClauseWithPreInit(OMPClauseWithPreInit *C);
+ void VisitOMPClauseWithPostUpdate(OMPClauseWithPostUpdate *C);
+};
+
} // namespace clang
#endif // LLVM_CLANG_SERIALIZATION_ASTWRITER_H
diff --git a/include/clang/Serialization/ContinuousRangeMap.h b/include/clang/Serialization/ContinuousRangeMap.h
index 73bf2ed10f04..ad827e37db2d 100644
--- a/include/clang/Serialization/ContinuousRangeMap.h
+++ b/include/clang/Serialization/ContinuousRangeMap.h
@@ -118,7 +118,7 @@ public:
Builder &operator=(const Builder&) = delete;
~Builder() {
- llvm::sort(Self.Rep.begin(), Self.Rep.end(), Compare());
+ llvm::sort(Self.Rep, Compare());
std::unique(Self.Rep.begin(), Self.Rep.end(),
[](const_reference A, const_reference B) {
// FIXME: we should not allow any duplicate keys, but there are a lot of
diff --git a/include/clang/Serialization/GlobalModuleIndex.h b/include/clang/Serialization/GlobalModuleIndex.h
index d47fe9517d76..5791fc024a32 100644
--- a/include/clang/Serialization/GlobalModuleIndex.h
+++ b/include/clang/Serialization/GlobalModuleIndex.h
@@ -42,11 +42,6 @@ namespace serialization {
class ModuleFile;
}
-using llvm::SmallVector;
-using llvm::SmallVectorImpl;
-using llvm::StringRef;
-using serialization::ModuleFile;
-
/// A global index for a set of module files, providing information about
/// the identifiers within those module files.
///
@@ -59,6 +54,8 @@ using serialization::ModuleFile;
/// imported, and can be queried to determine which modules the current
/// translation could or should load to fix a problem.
class GlobalModuleIndex {
+ using ModuleFile = serialization::ModuleFile;
+
/// Buffer containing the index file, which is lazily accessed so long
/// as the global module index is live.
std::unique_ptr<llvm::MemoryBuffer> Buffer;
@@ -147,7 +144,7 @@ public:
/// \returns A pair containing the global module index (if it exists) and
/// the error code.
static std::pair<GlobalModuleIndex *, ErrorCode>
- readIndex(StringRef Path);
+ readIndex(llvm::StringRef Path);
/// Returns an iterator for identifiers stored in the index table.
///
@@ -158,12 +155,12 @@ public:
///
/// \param ModuleFiles Will be populated with the set of module files that
/// have been indexed.
- void getKnownModules(SmallVectorImpl<ModuleFile *> &ModuleFiles);
+ void getKnownModules(llvm::SmallVectorImpl<ModuleFile *> &ModuleFiles);
/// Retrieve the set of module files on which the given module file
/// directly depends.
void getModuleDependencies(ModuleFile *File,
- SmallVectorImpl<ModuleFile *> &Dependencies);
+ llvm::SmallVectorImpl<ModuleFile *> &Dependencies);
/// A set of module files in which we found a result.
typedef llvm::SmallPtrSet<ModuleFile *, 4> HitSet;
@@ -177,7 +174,7 @@ public:
/// information about this name.
///
/// \returns true if the identifier is known to the index, false otherwise.
- bool lookupIdentifier(StringRef Name, HitSet &Hits);
+ bool lookupIdentifier(llvm::StringRef Name, HitSet &Hits);
/// Note that the given module file has been loaded.
///
@@ -200,7 +197,7 @@ public:
/// which the global index will be written.
static ErrorCode writeIndex(FileManager &FileMgr,
const PCHContainerReader &PCHContainerRdr,
- StringRef Path);
+ llvm::StringRef Path);
};
}
diff --git a/include/clang/Serialization/PCHContainerOperations.h b/include/clang/Serialization/PCHContainerOperations.h
new file mode 100644
index 000000000000..2a91d9830af3
--- /dev/null
+++ b/include/clang/Serialization/PCHContainerOperations.h
@@ -0,0 +1,117 @@
+//===--- Serialization/PCHContainerOperations.h - PCH Containers --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SERIALIZATION_PCHCONTAINEROPERATIONS_H
+#define LLVM_CLANG_SERIALIZATION_PCHCONTAINEROPERATIONS_H
+
+#include "clang/Basic/Module.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include <memory>
+
+namespace llvm {
+class raw_pwrite_stream;
+}
+
+namespace clang {
+
+class ASTConsumer;
+class CodeGenOptions;
+class DiagnosticsEngine;
+class CompilerInstance;
+
+struct PCHBuffer {
+ ASTFileSignature Signature;
+ llvm::SmallVector<char, 0> Data;
+ bool IsComplete;
+};
+
+/// This abstract interface provides operations for creating
+/// containers for serialized ASTs (precompiled headers and clang
+/// modules).
+class PCHContainerWriter {
+public:
+ virtual ~PCHContainerWriter() = 0;
+ virtual llvm::StringRef getFormat() const = 0;
+
+ /// Return an ASTConsumer that can be chained with a
+ /// PCHGenerator that produces a wrapper file format containing a
+ /// serialized AST bitstream.
+ virtual std::unique_ptr<ASTConsumer>
+ CreatePCHContainerGenerator(CompilerInstance &CI,
+ const std::string &MainFileName,
+ const std::string &OutputFileName,
+ std::unique_ptr<llvm::raw_pwrite_stream> OS,
+ std::shared_ptr<PCHBuffer> Buffer) const = 0;
+};
+
+/// This abstract interface provides operations for unwrapping
+/// containers for serialized ASTs (precompiled headers and clang
+/// modules).
+class PCHContainerReader {
+public:
+ virtual ~PCHContainerReader() = 0;
+ /// Equivalent to the format passed to -fmodule-format=
+ virtual llvm::StringRef getFormat() const = 0;
+
+ /// Returns the serialized AST inside the PCH container Buffer.
+ virtual llvm::StringRef ExtractPCH(llvm::MemoryBufferRef Buffer) const = 0;
+};
+
+/// Implements write operations for a raw pass-through PCH container.
+class RawPCHContainerWriter : public PCHContainerWriter {
+ llvm::StringRef getFormat() const override { return "raw"; }
+
+ /// Return an ASTConsumer that can be chained with a
+ /// PCHGenerator that writes the module to a flat file.
+ std::unique_ptr<ASTConsumer>
+ CreatePCHContainerGenerator(CompilerInstance &CI,
+ const std::string &MainFileName,
+ const std::string &OutputFileName,
+ std::unique_ptr<llvm::raw_pwrite_stream> OS,
+ std::shared_ptr<PCHBuffer> Buffer) const override;
+};
+
+/// Implements read operations for a raw pass-through PCH container.
+class RawPCHContainerReader : public PCHContainerReader {
+ llvm::StringRef getFormat() const override { return "raw"; }
+
+ /// Simply returns the buffer contained in Buffer.
+ llvm::StringRef ExtractPCH(llvm::MemoryBufferRef Buffer) const override;
+};
+
+/// A registry of PCHContainerWriter and -Reader objects for different formats.
+class PCHContainerOperations {
+ llvm::StringMap<std::unique_ptr<PCHContainerWriter>> Writers;
+ llvm::StringMap<std::unique_ptr<PCHContainerReader>> Readers;
+public:
+ /// Automatically registers a RawPCHContainerWriter and
+ /// RawPCHContainerReader.
+ PCHContainerOperations();
+ void registerWriter(std::unique_ptr<PCHContainerWriter> Writer) {
+ Writers[Writer->getFormat()] = std::move(Writer);
+ }
+ void registerReader(std::unique_ptr<PCHContainerReader> Reader) {
+ Readers[Reader->getFormat()] = std::move(Reader);
+ }
+ const PCHContainerWriter *getWriterOrNull(llvm::StringRef Format) {
+ return Writers[Format].get();
+ }
+ const PCHContainerReader *getReaderOrNull(llvm::StringRef Format) {
+ return Readers[Format].get();
+ }
+ const PCHContainerReader &getRawReader() {
+ return *getReaderOrNull("raw");
+ }
+};
+
+}
+
+#endif
diff --git a/include/clang/Serialization/SerializationDiagnostic.h b/include/clang/Serialization/SerializationDiagnostic.h
index d50422aa466c..2decd1c2f67b 100644
--- a/include/clang/Serialization/SerializationDiagnostic.h
+++ b/include/clang/Serialization/SerializationDiagnostic.h
@@ -10,19 +10,6 @@
#ifndef LLVM_CLANG_SERIALIZATION_SERIALIZATIONDIAGNOSTIC_H
#define LLVM_CLANG_SERIALIZATION_SERIALIZATIONDIAGNOSTIC_H
-#include "clang/Basic/Diagnostic.h"
-
-namespace clang {
- namespace diag {
- enum {
-#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
- SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
-#define SERIALIZATIONSTART
-#include "clang/Basic/DiagnosticSerializationKinds.inc"
-#undef DIAG
- NUM_BUILTIN_SERIALIZATION_DIAGNOSTICS
- };
- } // end namespace diag
-} // end namespace clang
+#include "clang/Basic/DiagnosticSerialization.h"
#endif
diff --git a/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h b/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h
new file mode 100644
index 000000000000..192ac1261c76
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h
@@ -0,0 +1,37 @@
+//===--- ClangSACheckers.h - Registration functions for Checkers *- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Declares the registation functions for the checkers defined in
+// libclangStaticAnalyzerCheckers.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_CLANGSACHECKERS_H
+#define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_CLANGSACHECKERS_H
+
+#include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h"
+
+namespace clang {
+
+namespace ento {
+class CheckerManager;
+class CheckerRegistry;
+
+#define GET_CHECKERS
+#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI) \
+ void register##CLASS(CheckerManager &mgr);
+#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
+#undef CHECKER
+#undef GET_CHECKERS
+
+} // end ento namespace
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Checkers/CheckerBase.td b/include/clang/StaticAnalyzer/Checkers/CheckerBase.td
index 11f1e5d4bd51..453e189fccb0 100644
--- a/include/clang/StaticAnalyzer/Checkers/CheckerBase.td
+++ b/include/clang/StaticAnalyzer/Checkers/CheckerBase.td
@@ -11,29 +11,47 @@
//
//===----------------------------------------------------------------------===//
-class CheckerGroup<string name> {
- string GroupName = name;
-}
-class InGroup<CheckerGroup G> { CheckerGroup Group = G; }
-
+/// Describes a package. Every checker is a part of a package, for example,
+/// 'NullDereference' is part of the 'core' package, hence it's full name is
+/// 'core.NullDereference'.
+/// Example:
+/// def Core : Package<"core">;
class Package<string name> {
string PackageName = name;
- bit Hidden = 0;
Package ParentPackage;
- CheckerGroup Group;
}
-class InPackage<Package P> { Package ParentPackage = P; }
-// All checkers are an indirect subclass of this.
+/// Describes a 'super' package that holds another package inside it. This is
+/// used to nest packages in one another. One may, for example, create the
+/// 'builtin' package inside 'core', thus creating the package 'core.builtin'.
+/// Example:
+/// def CoreBuiltin : Package<"builtin">, ParentPackage<Core>;
+class ParentPackage<Package P> { Package ParentPackage = P; }
+
+/// A description. May be displayed to the user when clang is invoked with
+/// a '-help'-like command line option.
+class HelpText<string text> { string HelpText = text; }
+
+/// Describes what kind of documentation exists for the checker.
+class DocumentationEnum<bits<2> val> {
+ bits<2> Documentation = val;
+}
+def NotDocumented : DocumentationEnum<0>;
+def HasDocumentation : DocumentationEnum<1>;
+def HasAlphaDocumentation : DocumentationEnum<2>;
+
+class Documentation<DocumentationEnum val> {
+ bits<2> Documentation = val.Documentation;
+}
+
+/// Describes a checker. Every builtin checker has to be registered with the use
+/// of this class (out-of-trunk checkers loaded from plugins obviously don't).
+/// Note that a checker has a name (e.g.: 'NullDereference'), and a fullname,
+/// that is autogenerated with the help of the ParentPackage field, that also
+/// includes package names (e.g.: 'core.NullDereference').
class Checker<string name = ""> {
string CheckerName = name;
- string DescFile;
string HelpText;
- bit Hidden = 0;
+ bits<2> Documentation;
Package ParentPackage;
- CheckerGroup Group;
}
-
-class DescFile<string filename> { string DescFile = filename; }
-class HelpText<string text> { string HelpText = text; }
-class Hidden { bit Hidden = 1; }
diff --git a/include/clang/StaticAnalyzer/Checkers/Checkers.td b/include/clang/StaticAnalyzer/Checkers/Checkers.td
index 9e53460f6e93..1bb3da7a2458 100644
--- a/include/clang/StaticAnalyzer/Checkers/Checkers.td
+++ b/include/clang/StaticAnalyzer/Checkers/Checkers.td
@@ -21,9 +21,9 @@ include "CheckerBase.td"
def Alpha : Package<"alpha">;
def Core : Package<"core">;
-def CoreBuiltin : Package<"builtin">, InPackage<Core>;
-def CoreUninitialized : Package<"uninitialized">, InPackage<Core>;
-def CoreAlpha : Package<"core">, InPackage<Alpha>, Hidden;
+def CoreBuiltin : Package<"builtin">, ParentPackage<Core>;
+def CoreUninitialized : Package<"uninitialized">, ParentPackage<Core>;
+def CoreAlpha : Package<"core">, ParentPackage<Alpha>;
// The OptIn package is for checkers that are not alpha and that would normally
// be on by default but where the driver does not have enough information to
@@ -41,58 +41,59 @@ def OptIn : Package<"optin">;
// In the Portability package reside checkers for finding code that relies on
// implementation-defined behavior. Such checks are wanted for cross-platform
// development, but unwanted for developers who target only a single platform.
-def PortabilityOptIn : Package<"portability">, InPackage<OptIn>;
+def PortabilityOptIn : Package<"portability">, ParentPackage<OptIn>;
def Nullability : Package<"nullability">;
def Cplusplus : Package<"cplusplus">;
-def CplusplusAlpha : Package<"cplusplus">, InPackage<Alpha>, Hidden;
-def CplusplusOptIn : Package<"cplusplus">, InPackage<OptIn>;
+def CplusplusAlpha : Package<"cplusplus">, ParentPackage<Alpha>;
+def CplusplusOptIn : Package<"cplusplus">, ParentPackage<OptIn>;
def Valist : Package<"valist">;
def DeadCode : Package<"deadcode">;
-def DeadCodeAlpha : Package<"deadcode">, InPackage<Alpha>, Hidden;
+def DeadCodeAlpha : Package<"deadcode">, ParentPackage<Alpha>;
-def Performance : Package<"performance">, InPackage<OptIn>;
+def Performance : Package<"performance">, ParentPackage<OptIn>;
def Security : Package <"security">;
-def InsecureAPI : Package<"insecureAPI">, InPackage<Security>;
-def SecurityAlpha : Package<"security">, InPackage<Alpha>, Hidden;
-def Taint : Package<"taint">, InPackage<SecurityAlpha>, Hidden;
+def InsecureAPI : Package<"insecureAPI">, ParentPackage<Security>;
+def SecurityAlpha : Package<"security">, ParentPackage<Alpha>;
+def Taint : Package<"taint">, ParentPackage<SecurityAlpha>;
def Unix : Package<"unix">;
-def UnixAlpha : Package<"unix">, InPackage<Alpha>, Hidden;
-def CString : Package<"cstring">, InPackage<Unix>, Hidden;
-def CStringAlpha : Package<"cstring">, InPackage<UnixAlpha>, Hidden;
+def UnixAlpha : Package<"unix">, ParentPackage<Alpha>;
+def CString : Package<"cstring">, ParentPackage<Unix>;
+def CStringAlpha : Package<"cstring">, ParentPackage<UnixAlpha>;
def OSX : Package<"osx">;
-def OSXAlpha : Package<"osx">, InPackage<Alpha>, Hidden;
-def OSXOptIn : Package<"osx">, InPackage<OptIn>;
+def OSXAlpha : Package<"osx">, ParentPackage<Alpha>;
+def OSXOptIn : Package<"osx">, ParentPackage<OptIn>;
-def Cocoa : Package<"cocoa">, InPackage<OSX>;
-def CocoaAlpha : Package<"cocoa">, InPackage<OSXAlpha>, Hidden;
-def CocoaOptIn : Package<"cocoa">, InPackage<OSXOptIn>;
+def Cocoa : Package<"cocoa">, ParentPackage<OSX>;
+def CocoaAlpha : Package<"cocoa">, ParentPackage<OSXAlpha>;
+def CocoaOptIn : Package<"cocoa">, ParentPackage<OSXOptIn>;
-def CoreFoundation : Package<"coreFoundation">, InPackage<OSX>;
-def Containers : Package<"containers">, InPackage<CoreFoundation>;
+def CoreFoundation : Package<"coreFoundation">, ParentPackage<OSX>;
+def Containers : Package<"containers">, ParentPackage<CoreFoundation>;
-def LocalizabilityAlpha : Package<"localizability">, InPackage<CocoaAlpha>;
-def LocalizabilityOptIn : Package<"localizability">, InPackage<CocoaOptIn>;
+def LocalizabilityAlpha : Package<"localizability">, ParentPackage<CocoaAlpha>;
+def LocalizabilityOptIn : Package<"localizability">, ParentPackage<CocoaOptIn>;
-def MPI : Package<"mpi">, InPackage<OptIn>;
+def MPI : Package<"mpi">, ParentPackage<OptIn>;
def LLVM : Package<"llvm">;
+def LLVMAlpha : Package<"llvm">, ParentPackage<Alpha>;
// The APIModeling package is for checkers that model APIs and don't perform
// any diagnostics. These checkers are always turned on; this package is
// intended for API modeling that is not controlled by the target triple.
-def APIModeling : Package<"apiModeling">, Hidden;
-def GoogleAPIModeling : Package<"google">, InPackage<APIModeling>;
+def APIModeling : Package<"apiModeling">;
+def GoogleAPIModeling : Package<"google">, ParentPackage<APIModeling>;
def Debug : Package<"debug">;
-def CloneDetectionAlpha : Package<"clone">, InPackage<Alpha>, Hidden;
+def CloneDetectionAlpha : Package<"clone">, ParentPackage<Alpha>;
//===----------------------------------------------------------------------===//
// Core Checkers.
@@ -102,39 +103,42 @@ let ParentPackage = Core in {
def DereferenceChecker : Checker<"NullDereference">,
HelpText<"Check for dereferences of null pointers">,
- DescFile<"DereferenceChecker.cpp">;
+ Documentation<HasDocumentation>;
def CallAndMessageChecker : Checker<"CallAndMessage">,
- HelpText<"Check for logical errors for function calls and Objective-C message expressions (e.g., uninitialized arguments, null function pointers)">,
- DescFile<"CallAndMessageChecker.cpp">;
+ HelpText<"Check for logical errors for function calls and Objective-C "
+ "message expressions (e.g., uninitialized arguments, null function "
+ "pointers)">,
+ Documentation<HasDocumentation>;
def NonNullParamChecker : Checker<"NonNullParamChecker">,
- HelpText<"Check for null pointers passed as arguments to a function whose arguments are references or marked with the 'nonnull' attribute">,
- DescFile<"NonNullParamChecker.cpp">;
+ HelpText<"Check for null pointers passed as arguments to a function whose "
+ "arguments are references or marked with the 'nonnull' attribute">,
+ Documentation<HasDocumentation>;
def VLASizeChecker : Checker<"VLASize">,
HelpText<"Check for declarations of VLA of undefined or zero size">,
- DescFile<"VLASizeChecker.cpp">;
+ Documentation<HasDocumentation>;
def DivZeroChecker : Checker<"DivideZero">,
HelpText<"Check for division by zero">,
- DescFile<"DivZeroChecker.cpp">;
+ Documentation<HasDocumentation>;
def UndefResultChecker : Checker<"UndefinedBinaryOperatorResult">,
HelpText<"Check for undefined results of binary operators">,
- DescFile<"UndefResultChecker.cpp">;
+ Documentation<HasDocumentation>;
def StackAddrEscapeChecker : Checker<"StackAddressEscape">,
HelpText<"Check that addresses to stack memory do not escape the function">,
- DescFile<"StackAddrEscapeChecker.cpp">;
+ Documentation<HasDocumentation>;
def DynamicTypePropagation : Checker<"DynamicTypePropagation">,
HelpText<"Generate dynamic type information">,
- DescFile<"DynamicTypePropagation.cpp">;
+ Documentation<NotDocumented>;
def NonnullGlobalConstantsChecker: Checker<"NonnilStringConstants">,
HelpText<"Assume that const string-like globals are non-null">,
- DescFile<"NonilStringConstantsChecker.cpp">;
+ Documentation<NotDocumented>;
} // end "core"
@@ -142,89 +146,105 @@ let ParentPackage = CoreAlpha in {
def BoolAssignmentChecker : Checker<"BoolAssignment">,
HelpText<"Warn about assigning non-{0,1} values to Boolean variables">,
- DescFile<"BoolAssignmentChecker.cpp">;
+ Documentation<HasAlphaDocumentation>;
def CastSizeChecker : Checker<"CastSize">,
- HelpText<"Check when casting a malloc'ed type T, whether the size is a multiple of the size of T">,
- DescFile<"CastSizeChecker.cpp">;
+ HelpText<"Check when casting a malloc'ed type T, whether the size is a "
+ "multiple of the size of T">,
+ Documentation<HasAlphaDocumentation>;
def CastToStructChecker : Checker<"CastToStruct">,
HelpText<"Check for cast from non-struct pointer to struct pointer">,
- DescFile<"CastToStructChecker.cpp">;
+ Documentation<HasAlphaDocumentation>;
def ConversionChecker : Checker<"Conversion">,
HelpText<"Loss of sign/precision in implicit conversions">,
- DescFile<"ConversionChecker.cpp">;
+ Documentation<HasAlphaDocumentation>;
def IdenticalExprChecker : Checker<"IdenticalExpr">,
HelpText<"Warn about unintended use of identical expressions in operators">,
- DescFile<"IdenticalExprChecker.cpp">;
+ Documentation<HasAlphaDocumentation>;
def FixedAddressChecker : Checker<"FixedAddr">,
HelpText<"Check for assignment of a fixed address to a pointer">,
- DescFile<"FixedAddressChecker.cpp">;
+ Documentation<HasAlphaDocumentation>;
def PointerArithChecker : Checker<"PointerArithm">,
- HelpText<"Check for pointer arithmetic on locations other than array elements">,
- DescFile<"PointerArithChecker">;
+ HelpText<"Check for pointer arithmetic on locations other than array "
+ "elements">,
+ Documentation<HasAlphaDocumentation>;
def PointerSubChecker : Checker<"PointerSub">,
- HelpText<"Check for pointer subtractions on two pointers pointing to different memory chunks">,
- DescFile<"PointerSubChecker">;
+ HelpText<"Check for pointer subtractions on two pointers pointing to "
+ "different memory chunks">,
+ Documentation<HasAlphaDocumentation>;
def SizeofPointerChecker : Checker<"SizeofPtr">,
HelpText<"Warn about unintended use of sizeof() on pointer expressions">,
- DescFile<"CheckSizeofPointer.cpp">;
+ Documentation<HasAlphaDocumentation>;
def CallAndMessageUnInitRefArg : Checker<"CallAndMessageUnInitRefArg">,
- HelpText<"Check for logical errors for function calls and Objective-C message expressions (e.g., uninitialized arguments, null function pointers, and pointer to undefined variables)">,
- DescFile<"CallAndMessageChecker.cpp">;
+ HelpText<"Check for logical errors for function calls and Objective-C "
+ "message expressions (e.g., uninitialized arguments, null function "
+ "pointers, and pointer to undefined variables)">,
+ Documentation<HasAlphaDocumentation>;
def TestAfterDivZeroChecker : Checker<"TestAfterDivZero">,
- HelpText<"Check for division by variable that is later compared against 0. Either the comparison is useless or there is division by zero.">,
- DescFile<"TestAfterDivZeroChecker.cpp">;
+ HelpText<"Check for division by variable that is later compared against 0. "
+ "Either the comparison is useless or there is division by zero.">,
+ Documentation<HasAlphaDocumentation>;
def DynamicTypeChecker : Checker<"DynamicTypeChecker">,
- HelpText<"Check for cases where the dynamic and the static type of an object are unrelated.">,
- DescFile<"DynamicTypeChecker.cpp">;
+ HelpText<"Check for cases where the dynamic and the static type of an object "
+ "are unrelated.">,
+ Documentation<HasAlphaDocumentation>;
def StackAddrAsyncEscapeChecker : Checker<"StackAddressAsyncEscape">,
HelpText<"Check that addresses to stack memory do not escape the function">,
- DescFile<"StackAddrEscapeChecker.cpp">;
+ Documentation<HasAlphaDocumentation>;
} // end "alpha.core"
let ParentPackage = Nullability in {
def NullPassedToNonnullChecker : Checker<"NullPassedToNonnull">,
- HelpText<"Warns when a null pointer is passed to a pointer which has a _Nonnull type.">,
- DescFile<"NullabilityChecker.cpp">;
+ HelpText<"Warns when a null pointer is passed to a pointer which has a "
+ "_Nonnull type.">,
+ Documentation<HasDocumentation>;
def NullReturnedFromNonnullChecker : Checker<"NullReturnedFromNonnull">,
- HelpText<"Warns when a null pointer is returned from a function that has _Nonnull return type.">,
- DescFile<"NullabilityChecker.cpp">;
+ HelpText<"Warns when a null pointer is returned from a function that has "
+ "_Nonnull return type.">,
+ Documentation<HasDocumentation>;
def NullableDereferencedChecker : Checker<"NullableDereferenced">,
HelpText<"Warns when a nullable pointer is dereferenced.">,
- DescFile<"NullabilityChecker.cpp">;
+ Documentation<HasDocumentation>;
def NullablePassedToNonnullChecker : Checker<"NullablePassedToNonnull">,
- HelpText<"Warns when a nullable pointer is passed to a pointer which has a _Nonnull type.">,
- DescFile<"NullabilityChecker.cpp">;
+ HelpText<"Warns when a nullable pointer is passed to a pointer which has a "
+ "_Nonnull type.">,
+ Documentation<HasDocumentation>;
def NullableReturnedFromNonnullChecker : Checker<"NullableReturnedFromNonnull">,
- HelpText<"Warns when a nullable pointer is returned from a function that has _Nonnull return type.">,
- DescFile<"NullabilityChecker.cpp">;
+ HelpText<"Warns when a nullable pointer is returned from a function that has "
+ "_Nonnull return type.">,
+ Documentation<NotDocumented>;
} // end "nullability"
let ParentPackage = APIModeling in {
+def StdCLibraryFunctionsChecker : Checker<"StdCLibraryFunctions">,
+ HelpText<"Improve modeling of the C standard library functions">,
+ Documentation<NotDocumented>;
+
def TrustNonnullChecker : Checker<"TrustNonnull">,
- HelpText<"Trust that returns from framework methods annotated with _Nonnull are not null">,
- DescFile<"TrustNonnullChecker.cpp">;
+ HelpText<"Trust that returns from framework methods annotated with _Nonnull "
+ "are not null">,
+ Documentation<NotDocumented>;
-}
+} // end "apiModeling"
//===----------------------------------------------------------------------===//
// Evaluate "builtin" functions.
@@ -233,12 +253,13 @@ def TrustNonnullChecker : Checker<"TrustNonnull">,
let ParentPackage = CoreBuiltin in {
def NoReturnFunctionChecker : Checker<"NoReturnFunctions">,
- HelpText<"Evaluate \"panic\" functions that are known to not return to the caller">,
- DescFile<"NoReturnFunctionChecker.cpp">;
+ HelpText<"Evaluate \"panic\" functions that are known to not return to the "
+ "caller">,
+ Documentation<NotDocumented>;
def BuiltinFunctionChecker : Checker<"BuiltinFunctions">,
HelpText<"Evaluate compiler builtin functions (e.g., alloca())">,
- DescFile<"BuiltinFunctionChecker.cpp">;
+ Documentation<NotDocumented>;
} // end "core.builtin"
@@ -250,23 +271,23 @@ let ParentPackage = CoreUninitialized in {
def UndefinedArraySubscriptChecker : Checker<"ArraySubscript">,
HelpText<"Check for uninitialized values used as array subscripts">,
- DescFile<"UndefinedArraySubscriptChecker.cpp">;
+ Documentation<HasDocumentation>;
def UndefinedAssignmentChecker : Checker<"Assign">,
HelpText<"Check for assigning uninitialized values">,
- DescFile<"UndefinedAssignmentChecker.cpp">;
+ Documentation<HasDocumentation>;
def UndefBranchChecker : Checker<"Branch">,
HelpText<"Check for uninitialized values used as branch conditions">,
- DescFile<"UndefBranchChecker.cpp">;
+ Documentation<HasDocumentation>;
def UndefCapturedBlockVarChecker : Checker<"CapturedBlockVariable">,
HelpText<"Check for blocks that capture uninitialized values">,
- DescFile<"UndefCapturedBlockVarChecker.cpp">;
+ Documentation<NotDocumented>;
def ReturnUndefChecker : Checker<"UndefReturn">,
HelpText<"Check for uninitialized values being returned to the caller">,
- DescFile<"ReturnUndefChecker.cpp">;
+ Documentation<HasDocumentation>;
} // end "core.uninitialized"
@@ -277,20 +298,26 @@ def ReturnUndefChecker : Checker<"UndefReturn">,
let ParentPackage = Cplusplus in {
def InnerPointerChecker : Checker<"InnerPointer">,
- HelpText<"Check for inner pointers of C++ containers used after re/deallocation">,
- DescFile<"InnerPointerChecker.cpp">;
+ HelpText<"Check for inner pointers of C++ containers used after "
+ "re/deallocation">,
+ Documentation<NotDocumented>;
def NewDeleteChecker : Checker<"NewDelete">,
- HelpText<"Check for double-free and use-after-free problems. Traces memory managed by new/delete.">,
- DescFile<"MallocChecker.cpp">;
+ HelpText<"Check for double-free and use-after-free problems. Traces memory "
+ "managed by new/delete.">,
+ Documentation<HasDocumentation>;
def NewDeleteLeaksChecker : Checker<"NewDeleteLeaks">,
HelpText<"Check for memory leaks. Traces memory managed by new/delete.">,
- DescFile<"MallocChecker.cpp">;
+ Documentation<HasDocumentation>;
def CXXSelfAssignmentChecker : Checker<"SelfAssignment">,
HelpText<"Checks C++ copy and move assignment operators for self assignment">,
- DescFile<"CXXSelfAssignmentChecker.cpp">;
+ Documentation<NotDocumented>;
+
+def MoveChecker: Checker<"Move">,
+ HelpText<"Find use-after-move bugs in C++">,
+ Documentation<HasDocumentation>;
} // end: "cplusplus"
@@ -298,7 +325,7 @@ let ParentPackage = CplusplusOptIn in {
def VirtualCallChecker : Checker<"VirtualCall">,
HelpText<"Check virtual function calls during construction or destruction">,
- DescFile<"VirtualCallChecker.cpp">;
+ Documentation<HasDocumentation>;
} // end: "optin.cplusplus"
@@ -307,20 +334,28 @@ let ParentPackage = CplusplusAlpha in {
def DeleteWithNonVirtualDtorChecker : Checker<"DeleteWithNonVirtualDtor">,
HelpText<"Reports destructions of polymorphic objects with a non-virtual "
"destructor in their base class">,
- DescFile<"DeleteWithNonVirtualDtorChecker.cpp">;
+ Documentation<HasAlphaDocumentation>;
+
+def EnumCastOutOfRangeChecker : Checker<"EnumCastOutOfRange">,
+ HelpText<"Check integer to enumeration casts for out of range values">,
+ Documentation<HasAlphaDocumentation>;
+
+def InvalidatedIteratorChecker : Checker<"InvalidatedIterator">,
+ HelpText<"Check for use of invalidated iterators">,
+ Documentation<HasAlphaDocumentation>;
def IteratorRangeChecker : Checker<"IteratorRange">,
HelpText<"Check for iterators used outside their valid ranges">,
- DescFile<"IteratorChecker.cpp">;
+ Documentation<HasAlphaDocumentation>;
-def MisusedMovedObjectChecker: Checker<"MisusedMovedObject">,
- HelpText<"Method calls on a moved-from object and copying a moved-from "
- "object will be reported">,
- DescFile<"MisusedMovedObjectChecker.cpp">;
+def MismatchedIteratorChecker : Checker<"MismatchedIterator">,
+ HelpText<"Check for use of iterators of different containers where iterators "
+ "of the same container are expected">,
+ Documentation<HasAlphaDocumentation>;
def UninitializedObjectChecker: Checker<"UninitializedObject">,
HelpText<"Reports uninitialized fields after object construction">,
- DescFile<"UninitializedObjectChecker.cpp">;
+ Documentation<HasAlphaDocumentation>;
} // end: "alpha.cplusplus"
@@ -333,15 +368,15 @@ let ParentPackage = Valist in {
def UninitializedChecker : Checker<"Uninitialized">,
HelpText<"Check for usages of uninitialized (or already released) va_lists.">,
- DescFile<"ValistChecker.cpp">;
+ Documentation<NotDocumented>;
def UnterminatedChecker : Checker<"Unterminated">,
HelpText<"Check for va_lists which are not released by a va_end call.">,
- DescFile<"ValistChecker.cpp">;
+ Documentation<NotDocumented>;
def CopyToSelfChecker : Checker<"CopyToSelf">,
HelpText<"Check for va_lists which are copied onto itself.">,
- DescFile<"ValistChecker.cpp">;
+ Documentation<NotDocumented>;
} // end : "valist"
@@ -352,15 +387,17 @@ def CopyToSelfChecker : Checker<"CopyToSelf">,
let ParentPackage = DeadCode in {
def DeadStoresChecker : Checker<"DeadStores">,
- HelpText<"Check for values stored to variables that are never read afterwards">,
- DescFile<"DeadStoresChecker.cpp">;
+ HelpText<"Check for values stored to variables that are never read "
+ "afterwards">,
+ Documentation<HasDocumentation>;
+
} // end DeadCode
let ParentPackage = DeadCodeAlpha in {
def UnreachableCodeChecker : Checker<"UnreachableCode">,
HelpText<"Check unreachable code">,
- DescFile<"UnreachableCodeChecker.cpp">;
+ Documentation<HasAlphaDocumentation>;
} // end "alpha.deadcode"
@@ -372,7 +409,7 @@ let ParentPackage = Performance in {
def PaddingChecker : Checker<"Padding">,
HelpText<"Check for excessively padded structs.">,
- DescFile<"PaddingChecker.cpp">;
+ Documentation<NotDocumented>;
} // end: "padding"
@@ -381,70 +418,78 @@ def PaddingChecker : Checker<"Padding">,
//===----------------------------------------------------------------------===//
let ParentPackage = InsecureAPI in {
- def bcmp : Checker<"bcmp">,
- HelpText<"Warn on uses of the 'bcmp' function">,
- DescFile<"CheckSecuritySyntaxOnly.cpp">;
- def bcopy : Checker<"bcopy">,
- HelpText<"Warn on uses of the 'bcopy' function">,
- DescFile<"CheckSecuritySyntaxOnly.cpp">;
- def bzero : Checker<"bzero">,
- HelpText<"Warn on uses of the 'bzero' function">,
- DescFile<"CheckSecuritySyntaxOnly.cpp">;
- def gets : Checker<"gets">,
- HelpText<"Warn on uses of the 'gets' function">,
- DescFile<"CheckSecuritySyntaxOnly.cpp">;
- def getpw : Checker<"getpw">,
- HelpText<"Warn on uses of the 'getpw' function">,
- DescFile<"CheckSecuritySyntaxOnly.cpp">;
- def mktemp : Checker<"mktemp">,
- HelpText<"Warn on uses of the 'mktemp' function">,
- DescFile<"CheckSecuritySyntaxOnly.cpp">;
- def mkstemp : Checker<"mkstemp">,
- HelpText<"Warn when 'mkstemp' is passed fewer than 6 X's in the format string">,
- DescFile<"CheckSecuritySyntaxOnly.cpp">;
- def rand : Checker<"rand">,
- HelpText<"Warn on uses of the 'rand', 'random', and related functions">,
- DescFile<"CheckSecuritySyntaxOnly.cpp">;
- def strcpy : Checker<"strcpy">,
- HelpText<"Warn on uses of the 'strcpy' and 'strcat' functions">,
- DescFile<"CheckSecuritySyntaxOnly.cpp">;
- def vfork : Checker<"vfork">,
- HelpText<"Warn on uses of the 'vfork' function">,
- DescFile<"CheckSecuritySyntaxOnly.cpp">;
- def UncheckedReturn : Checker<"UncheckedReturn">,
- HelpText<"Warn on uses of functions whose return values must be always checked">,
- DescFile<"CheckSecuritySyntaxOnly.cpp">;
-}
+
+def bcmp : Checker<"bcmp">,
+ HelpText<"Warn on uses of the 'bcmp' function">,
+ Documentation<HasDocumentation>;
+def bcopy : Checker<"bcopy">,
+ HelpText<"Warn on uses of the 'bcopy' function">,
+ Documentation<HasDocumentation>;
+def bzero : Checker<"bzero">,
+ HelpText<"Warn on uses of the 'bzero' function">,
+ Documentation<HasDocumentation>;
+def gets : Checker<"gets">,
+ HelpText<"Warn on uses of the 'gets' function">,
+ Documentation<HasDocumentation>;
+def getpw : Checker<"getpw">,
+ HelpText<"Warn on uses of the 'getpw' function">,
+ Documentation<HasDocumentation>;
+def mktemp : Checker<"mktemp">,
+ HelpText<"Warn on uses of the 'mktemp' function">,
+ Documentation<HasDocumentation>;
+def mkstemp : Checker<"mkstemp">,
+ HelpText<"Warn when 'mkstemp' is passed fewer than 6 X's in the format "
+ "string">,
+ Documentation<HasDocumentation>;
+def rand : Checker<"rand">,
+ HelpText<"Warn on uses of the 'rand', 'random', and related functions">,
+ Documentation<HasDocumentation>;
+def strcpy : Checker<"strcpy">,
+ HelpText<"Warn on uses of the 'strcpy' and 'strcat' functions">,
+ Documentation<HasDocumentation>;
+def vfork : Checker<"vfork">,
+ HelpText<"Warn on uses of the 'vfork' function">,
+ Documentation<HasDocumentation>;
+def UncheckedReturn : Checker<"UncheckedReturn">,
+ HelpText<"Warn on uses of functions whose return values must be always "
+ "checked">,
+ Documentation<HasDocumentation>;
+
+} // end "security.insecureAPI"
+
let ParentPackage = Security in {
- def FloatLoopCounter : Checker<"FloatLoopCounter">,
- HelpText<"Warn on using a floating point value as a loop counter (CERT: FLP30-C, FLP30-CPP)">,
- DescFile<"CheckSecuritySyntaxOnly.cpp">;
-}
+
+def FloatLoopCounter : Checker<"FloatLoopCounter">,
+ HelpText<"Warn on using a floating point value as a loop counter (CERT: "
+ "FLP30-C, FLP30-CPP)">,
+ Documentation<HasDocumentation>;
+
+} // end "security"
let ParentPackage = SecurityAlpha in {
def ArrayBoundChecker : Checker<"ArrayBound">,
HelpText<"Warn about buffer overflows (older checker)">,
- DescFile<"ArrayBoundChecker.cpp">;
+ Documentation<HasAlphaDocumentation>;
def ArrayBoundCheckerV2 : Checker<"ArrayBoundV2">,
HelpText<"Warn about buffer overflows (newer checker)">,
- DescFile<"ArrayBoundCheckerV2.cpp">;
+ Documentation<HasAlphaDocumentation>;
def ReturnPointerRangeChecker : Checker<"ReturnPtrRange">,
HelpText<"Check for an out-of-bound pointer being returned to callers">,
- DescFile<"ReturnPointerRangeChecker.cpp">;
+ Documentation<HasAlphaDocumentation>;
def MallocOverflowSecurityChecker : Checker<"MallocOverflow">,
HelpText<"Check for overflows in the arguments to malloc()">,
- DescFile<"MallocOverflowSecurityChecker.cpp">;
+ Documentation<HasAlphaDocumentation>;
// Operating systems specific PROT_READ/PROT_WRITE values is not implemented,
// the defaults are correct for several common operating systems though,
// but may need to be overridden via the related analyzer-config flags.
def MmapWriteExecChecker : Checker<"MmapWriteExec">,
HelpText<"Warn on mmap() calls that are both writable and executable">,
- DescFile<"MmapWriteExecChecker.cpp">;
+ Documentation<HasAlphaDocumentation>;
} // end "alpha.security"
@@ -456,7 +501,7 @@ let ParentPackage = Taint in {
def GenericTaintChecker : Checker<"TaintPropagation">,
HelpText<"Generate taint information used by other checkers">,
- DescFile<"GenericTaintChecker.cpp">;
+ Documentation<HasAlphaDocumentation>;
} // end "alpha.security.taint"
@@ -468,27 +513,24 @@ let ParentPackage = Unix in {
def UnixAPIMisuseChecker : Checker<"API">,
HelpText<"Check calls to various UNIX/Posix functions">,
- DescFile<"UnixAPIChecker.cpp">;
+ Documentation<HasDocumentation>;
def MallocChecker: Checker<"Malloc">,
- HelpText<"Check for memory leaks, double free, and use-after-free problems. Traces memory managed by malloc()/free().">,
- DescFile<"MallocChecker.cpp">;
+ HelpText<"Check for memory leaks, double free, and use-after-free problems. "
+ "Traces memory managed by malloc()/free().">,
+ Documentation<HasDocumentation>;
def MallocSizeofChecker : Checker<"MallocSizeof">,
HelpText<"Check for dubious malloc arguments involving sizeof">,
- DescFile<"MallocSizeofChecker.cpp">;
+ Documentation<HasDocumentation>;
def MismatchedDeallocatorChecker : Checker<"MismatchedDeallocator">,
HelpText<"Check for mismatched deallocators.">,
- DescFile<"MallocChecker.cpp">;
+ Documentation<HasDocumentation>;
def VforkChecker : Checker<"Vfork">,
HelpText<"Check for proper usage of vfork">,
- DescFile<"VforkChecker.cpp">;
-
-def StdCLibraryFunctionsChecker : Checker<"StdCLibraryFunctions">,
- HelpText<"Improve modeling of the C standard library functions">,
- DescFile<"StdLibraryFunctionsChecker.cpp">;
+ Documentation<HasDocumentation>;
} // end "unix"
@@ -496,51 +538,55 @@ let ParentPackage = UnixAlpha in {
def ChrootChecker : Checker<"Chroot">,
HelpText<"Check improper use of chroot">,
- DescFile<"ChrootChecker.cpp">;
+ Documentation<HasAlphaDocumentation>;
def PthreadLockChecker : Checker<"PthreadLock">,
HelpText<"Simple lock -> unlock checker">,
- DescFile<"PthreadLockChecker.cpp">;
+ Documentation<HasAlphaDocumentation>;
def StreamChecker : Checker<"Stream">,
HelpText<"Check stream handling functions">,
- DescFile<"StreamChecker.cpp">;
+ Documentation<HasAlphaDocumentation>;
def SimpleStreamChecker : Checker<"SimpleStream">,
HelpText<"Check for misuses of stream APIs">,
- DescFile<"SimpleStreamChecker.cpp">;
+ Documentation<HasAlphaDocumentation>;
def BlockInCriticalSectionChecker : Checker<"BlockInCriticalSection">,
HelpText<"Check for calls to blocking functions inside a critical section">,
- DescFile<"BlockInCriticalSectionChecker.cpp">;
+ Documentation<HasAlphaDocumentation>;
} // end "alpha.unix"
let ParentPackage = CString in {
def CStringNullArg : Checker<"NullArg">,
- HelpText<"Check for null pointers being passed as arguments to C string functions">,
- DescFile<"CStringChecker.cpp">;
+ HelpText<"Check for null pointers being passed as arguments to C string "
+ "functions">,
+ Documentation<HasDocumentation>;
def CStringSyntaxChecker : Checker<"BadSizeArg">,
- HelpText<"Check the size argument passed into C string functions for common erroneous patterns">,
- DescFile<"CStringSyntaxChecker.cpp">;
-}
+ HelpText<"Check the size argument passed into C string functions for common "
+ "erroneous patterns">,
+ Documentation<HasDocumentation>;
+
+} // end "unix.cstring"
let ParentPackage = CStringAlpha in {
def CStringOutOfBounds : Checker<"OutOfBounds">,
HelpText<"Check for out-of-bounds access in string functions">,
- DescFile<"CStringChecker.cpp">;
+ Documentation<HasAlphaDocumentation>;
def CStringBufferOverlap : Checker<"BufferOverlap">,
HelpText<"Checks for overlap in two buffer arguments">,
- DescFile<"CStringChecker.cpp">;
+ Documentation<HasAlphaDocumentation>;
def CStringNotNullTerm : Checker<"NotNullTerminated">,
HelpText<"Check for arguments which are not null-terminating strings">,
- DescFile<"CStringChecker.cpp">;
-}
+ Documentation<HasAlphaDocumentation>;
+
+} // end "alpha.unix.cstring"
//===----------------------------------------------------------------------===//
// Mac OS X, Cocoa, and Core Foundation checkers.
@@ -549,123 +595,142 @@ def CStringNotNullTerm : Checker<"NotNullTerminated">,
let ParentPackage = OSX in {
def NumberObjectConversionChecker : Checker<"NumberObjectConversion">,
- HelpText<"Check for erroneous conversions of objects representing numbers into numbers">,
- DescFile<"NumberObjectConversionChecker.cpp">;
+ HelpText<"Check for erroneous conversions of objects representing numbers "
+ "into numbers">,
+ Documentation<NotDocumented>;
def MacOSXAPIChecker : Checker<"API">,
HelpText<"Check for proper uses of various Apple APIs">,
- DescFile<"MacOSXAPIChecker.cpp">;
+ Documentation<HasDocumentation>;
def MacOSKeychainAPIChecker : Checker<"SecKeychainAPI">,
HelpText<"Check for proper uses of Secure Keychain APIs">,
- DescFile<"MacOSKeychainAPIChecker.cpp">;
+ Documentation<HasDocumentation>;
def ObjCPropertyChecker : Checker<"ObjCProperty">,
HelpText<"Check for proper uses of Objective-C properties">,
- DescFile<"ObjCPropertyChecker.cpp">;
+ Documentation<NotDocumented>;
+
+def OSObjectRetainCountChecker : Checker<"OSObjectRetainCount">,
+ HelpText<"Check for leaks and improper reference count management for OSObject">,
+ Documentation<NotDocumented>;
} // end "osx"
let ParentPackage = Cocoa in {
def RunLoopAutoreleaseLeakChecker : Checker<"RunLoopAutoreleaseLeak">,
- HelpText<"Check for leaked memory in autorelease pools that will never be drained">,
- DescFile<"RunLoopAutoreleaseLeakChecker.cpp">;
+ HelpText<"Check for leaked memory in autorelease pools that will never be "
+ "drained">,
+ Documentation<NotDocumented>;
def ObjCAtSyncChecker : Checker<"AtSync">,
HelpText<"Check for nil pointers used as mutexes for @synchronized">,
- DescFile<"ObjCAtSyncChecker.cpp">;
+ Documentation<HasDocumentation>;
def NilArgChecker : Checker<"NilArg">,
HelpText<"Check for prohibited nil arguments to ObjC method calls">,
- DescFile<"BasicObjCFoundationChecks.cpp">;
+ Documentation<HasDocumentation>;
def ClassReleaseChecker : Checker<"ClassRelease">,
- HelpText<"Check for sending 'retain', 'release', or 'autorelease' directly to a Class">,
- DescFile<"BasicObjCFoundationChecks.cpp">;
+ HelpText<"Check for sending 'retain', 'release', or 'autorelease' directly "
+ "to a Class">,
+ Documentation<HasDocumentation>;
def VariadicMethodTypeChecker : Checker<"VariadicMethodTypes">,
HelpText<"Check for passing non-Objective-C types to variadic collection "
"initialization methods that expect only Objective-C types">,
- DescFile<"BasicObjCFoundationChecks.cpp">;
+ Documentation<HasDocumentation>;
def NSAutoreleasePoolChecker : Checker<"NSAutoreleasePool">,
- HelpText<"Warn for suboptimal uses of NSAutoreleasePool in Objective-C GC mode">,
- DescFile<"NSAutoreleasePoolChecker.cpp">;
+ HelpText<"Warn for suboptimal uses of NSAutoreleasePool in Objective-C GC "
+ "mode">,
+ Documentation<HasDocumentation>;
def ObjCMethSigsChecker : Checker<"IncompatibleMethodTypes">,
- HelpText<"Warn about Objective-C method signatures with type incompatibilities">,
- DescFile<"CheckObjCInstMethSignature.cpp">;
+ HelpText<"Warn about Objective-C method signatures with type "
+ "incompatibilities">,
+ Documentation<HasDocumentation>;
def ObjCUnusedIvarsChecker : Checker<"UnusedIvars">,
HelpText<"Warn about private ivars that are never used">,
- DescFile<"ObjCUnusedIVarsChecker.cpp">;
+ Documentation<HasDocumentation>;
def ObjCSelfInitChecker : Checker<"SelfInit">,
- HelpText<"Check that 'self' is properly initialized inside an initializer method">,
- DescFile<"ObjCSelfInitChecker.cpp">;
+ HelpText<"Check that 'self' is properly initialized inside an initializer "
+ "method">,
+ Documentation<HasDocumentation>;
def ObjCLoopChecker : Checker<"Loops">,
HelpText<"Improved modeling of loops using Cocoa collection types">,
- DescFile<"BasicObjCFoundationChecks.cpp">;
+ Documentation<NotDocumented>;
def ObjCNonNilReturnValueChecker : Checker<"NonNilReturnValue">,
HelpText<"Model the APIs that are guaranteed to return a non-nil value">,
- DescFile<"BasicObjCFoundationChecks.cpp">;
+ Documentation<NotDocumented>;
def ObjCSuperCallChecker : Checker<"MissingSuperCall">,
- HelpText<"Warn about Objective-C methods that lack a necessary call to super">,
- DescFile<"ObjCMissingSuperCallChecker.cpp">;
+ HelpText<"Warn about Objective-C methods that lack a necessary call to "
+ "super">,
+ Documentation<NotDocumented>;
def NSErrorChecker : Checker<"NSError">,
HelpText<"Check usage of NSError** parameters">,
- DescFile<"NSErrorChecker.cpp">;
+ Documentation<HasDocumentation>;
def RetainCountChecker : Checker<"RetainCount">,
HelpText<"Check for leaks and improper reference count management">,
- DescFile<"RetainCountChecker.cpp">;
+ Documentation<HasDocumentation>;
def ObjCGenericsChecker : Checker<"ObjCGenerics">,
HelpText<"Check for type errors when using Objective-C generics">,
- DescFile<"DynamicTypePropagation.cpp">;
+ Documentation<HasDocumentation>;
def ObjCDeallocChecker : Checker<"Dealloc">,
- HelpText<"Warn about Objective-C classes that lack a correct implementation of -dealloc">,
- DescFile<"CheckObjCDealloc.cpp">;
+ HelpText<"Warn about Objective-C classes that lack a correct implementation "
+ "of -dealloc">,
+ Documentation<HasDocumentation>;
def ObjCSuperDeallocChecker : Checker<"SuperDealloc">,
HelpText<"Warn about improper use of '[super dealloc]' in Objective-C">,
- DescFile<"ObjCSuperDeallocChecker.cpp">;
+ Documentation<HasDocumentation>;
def AutoreleaseWriteChecker : Checker<"AutoreleaseWrite">,
- HelpText<"Warn about potentially crashing writes to autoreleasing objects from different autoreleasing pools in Objective-C">,
- DescFile<"ObjCAutoreleaseWriteChecker.cpp">;
+ HelpText<"Warn about potentially crashing writes to autoreleasing objects "
+ "from different autoreleasing pools in Objective-C">,
+ Documentation<NotDocumented>;
+
} // end "osx.cocoa"
let ParentPackage = Performance in {
def GCDAntipattern : Checker<"GCDAntipattern">,
- HelpText<"Check for performance anti-patterns when using Grand Central Dispatch">,
- DescFile<"GCDAntipatternChecker.cpp">;
+ HelpText<"Check for performance anti-patterns when using Grand Central "
+ "Dispatch">,
+ Documentation<NotDocumented>;
} // end "optin.performance"
let ParentPackage = CocoaAlpha in {
def InstanceVariableInvalidation : Checker<"InstanceVariableInvalidation">,
- HelpText<"Check that the invalidatable instance variables are invalidated in the methods annotated with objc_instance_variable_invalidator">,
- DescFile<"IvarInvalidationChecker.cpp">;
+ HelpText<"Check that the invalidatable instance variables are invalidated in "
+ "the methods annotated with objc_instance_variable_invalidator">,
+ Documentation<HasAlphaDocumentation>;
def MissingInvalidationMethod : Checker<"MissingInvalidationMethod">,
- HelpText<"Check that the invalidation methods are present in classes that contain invalidatable instance variables">,
- DescFile<"IvarInvalidationChecker.cpp">;
+ HelpText<"Check that the invalidation methods are present in classes that "
+ "contain invalidatable instance variables">,
+ Documentation<HasAlphaDocumentation>;
def DirectIvarAssignment : Checker<"DirectIvarAssignment">,
HelpText<"Check for direct assignments to instance variables">,
- DescFile<"DirectIvarAssignment.cpp">;
+ Documentation<HasAlphaDocumentation>;
-def DirectIvarAssignmentForAnnotatedFunctions : Checker<"DirectIvarAssignmentForAnnotatedFunctions">,
- HelpText<"Check for direct assignments to instance variables in the methods annotated with objc_no_direct_instance_variable_assignment">,
- DescFile<"DirectIvarAssignment.cpp">;
+def DirectIvarAssignmentForAnnotatedFunctions :
+ Checker<"DirectIvarAssignmentForAnnotatedFunctions">,
+ HelpText<"Check for direct assignments to instance variables in the methods "
+ "annotated with objc_no_direct_instance_variable_assignment">,
+ Documentation<HasAlphaDocumentation>;
} // end "alpha.osx.cocoa"
@@ -673,69 +738,85 @@ let ParentPackage = CoreFoundation in {
def CFNumberChecker : Checker<"CFNumber">,
HelpText<"Check for proper uses of CFNumber APIs">,
- DescFile<"BasicObjCFoundationChecks.cpp">;
+ Documentation<HasDocumentation>;
def CFRetainReleaseChecker : Checker<"CFRetainRelease">,
HelpText<"Check for null arguments to CFRetain/CFRelease/CFMakeCollectable">,
- DescFile<"BasicObjCFoundationChecks.cpp">;
+ Documentation<HasDocumentation>;
def CFErrorChecker : Checker<"CFError">,
HelpText<"Check usage of CFErrorRef* parameters">,
- DescFile<"NSErrorChecker.cpp">;
-}
+ Documentation<HasDocumentation>;
+
+} // end "osx.coreFoundation"
let ParentPackage = Containers in {
+
def ObjCContainersASTChecker : Checker<"PointerSizedValues">,
- HelpText<"Warns if 'CFArray', 'CFDictionary', 'CFSet' are created with non-pointer-size values">,
- DescFile<"ObjCContainersASTChecker.cpp">;
+ HelpText<"Warns if 'CFArray', 'CFDictionary', 'CFSet' are created with "
+ "non-pointer-size values">,
+ Documentation<HasDocumentation>;
def ObjCContainersChecker : Checker<"OutOfBounds">,
HelpText<"Checks for index out-of-bounds when using 'CFArray' API">,
- DescFile<"ObjCContainersChecker.cpp">;
+ Documentation<HasDocumentation>;
-}
+} // end "osx.coreFoundation.containers"
let ParentPackage = LocalizabilityOptIn in {
+
def NonLocalizedStringChecker : Checker<"NonLocalizedStringChecker">,
- HelpText<"Warns about uses of non-localized NSStrings passed to UI methods expecting localized NSStrings">,
- DescFile<"LocalizationChecker.cpp">;
+ HelpText<"Warns about uses of non-localized NSStrings passed to UI methods "
+ "expecting localized NSStrings">,
+ Documentation<HasDocumentation>;
-def EmptyLocalizationContextChecker : Checker<"EmptyLocalizationContextChecker">,
+def EmptyLocalizationContextChecker :
+ Checker<"EmptyLocalizationContextChecker">,
HelpText<"Check that NSLocalizedString macros include a comment for context">,
- DescFile<"LocalizationChecker.cpp">;
-}
+ Documentation<HasDocumentation>;
+
+} // end "optin.osx.cocoa.localizability"
let ParentPackage = LocalizabilityAlpha in {
+
def PluralMisuseChecker : Checker<"PluralMisuseChecker">,
- HelpText<"Warns against using one vs. many plural pattern in code when generating localized strings.">,
- DescFile<"LocalizationChecker.cpp">;
-}
+ HelpText<"Warns against using one vs. many plural pattern in code when "
+ "generating localized strings.">,
+ Documentation<HasAlphaDocumentation>;
+
+} // end "alpha.osx.cocoa.localizability"
let ParentPackage = MPI in {
- def MPIChecker : Checker<"MPI-Checker">,
+
+def MPIChecker : Checker<"MPI-Checker">,
HelpText<"Checks MPI code">,
- DescFile<"MPIChecker.cpp">;
-}
+ Documentation<HasDocumentation>;
+
+} // end "optin.mpi"
//===----------------------------------------------------------------------===//
// Checkers for LLVM development.
//===----------------------------------------------------------------------===//
+let ParentPackage = LLVMAlpha in {
+
def LLVMConventionsChecker : Checker<"Conventions">,
- InPackage<LLVM>,
HelpText<"Check code for LLVM codebase conventions">,
- DescFile<"LLVMConventionsChecker.cpp">;
-
+ Documentation<HasAlphaDocumentation>;
+} // end "llvm"
//===----------------------------------------------------------------------===//
// Checkers modeling Google APIs.
//===----------------------------------------------------------------------===//
+let ParentPackage = GoogleAPIModeling in {
+
def GTestChecker : Checker<"GTest">,
- InPackage<GoogleAPIModeling>,
HelpText<"Model gtest assertion APIs">,
- DescFile<"GTestChecker.cpp">;
+ Documentation<NotDocumented>;
+
+} // end "apiModeling.google"
//===----------------------------------------------------------------------===//
// Debugging checkers (for analyzer development).
@@ -745,59 +826,63 @@ let ParentPackage = Debug in {
def AnalysisOrderChecker : Checker<"AnalysisOrder">,
HelpText<"Print callbacks that are called during analysis in order">,
- DescFile<"AnalysisOrder.cpp">;
+ Documentation<NotDocumented>;
def DominatorsTreeDumper : Checker<"DumpDominators">,
HelpText<"Print the dominance tree for a given CFG">,
- DescFile<"DebugCheckers.cpp">;
+ Documentation<NotDocumented>;
def LiveVariablesDumper : Checker<"DumpLiveVars">,
HelpText<"Print results of live variable analysis">,
- DescFile<"DebugCheckers.cpp">;
+ Documentation<NotDocumented>;
+
+def LiveStatementsDumper : Checker<"DumpLiveStmts">,
+ HelpText<"Print results of live statement analysis">,
+ Documentation<NotDocumented>;
def CFGViewer : Checker<"ViewCFG">,
HelpText<"View Control-Flow Graphs using GraphViz">,
- DescFile<"DebugCheckers.cpp">;
+ Documentation<NotDocumented>;
def CFGDumper : Checker<"DumpCFG">,
HelpText<"Display Control-Flow Graphs">,
- DescFile<"DebugCheckers.cpp">;
+ Documentation<NotDocumented>;
def CallGraphViewer : Checker<"ViewCallGraph">,
HelpText<"View Call Graph using GraphViz">,
- DescFile<"DebugCheckers.cpp">;
+ Documentation<NotDocumented>;
def CallGraphDumper : Checker<"DumpCallGraph">,
HelpText<"Display Call Graph">,
- DescFile<"DebugCheckers.cpp">;
+ Documentation<NotDocumented>;
def ConfigDumper : Checker<"ConfigDumper">,
HelpText<"Dump config table">,
- DescFile<"DebugCheckers.cpp">;
+ Documentation<NotDocumented>;
def TraversalDumper : Checker<"DumpTraversal">,
HelpText<"Print branch conditions as they are traversed by the engine">,
- DescFile<"TraversalChecker.cpp">;
+ Documentation<NotDocumented>;
def CallDumper : Checker<"DumpCalls">,
HelpText<"Print calls as they are traversed by the engine">,
- DescFile<"TraversalChecker.cpp">;
+ Documentation<NotDocumented>;
def AnalyzerStatsChecker : Checker<"Stats">,
HelpText<"Emit warnings with analyzer statistics">,
- DescFile<"AnalyzerStatsChecker.cpp">;
+ Documentation<NotDocumented>;
def TaintTesterChecker : Checker<"TaintTest">,
HelpText<"Mark tainted symbols as such.">,
- DescFile<"TaintTesterChecker.cpp">;
+ Documentation<NotDocumented>;
def ExprInspectionChecker : Checker<"ExprInspection">,
HelpText<"Check the analyzer's understanding of expressions">,
- DescFile<"ExprInspectionChecker.cpp">;
+ Documentation<NotDocumented>;
def ExplodedGraphViewer : Checker<"ViewExplodedGraph">,
HelpText<"View Exploded Graphs using GraphViz">,
- DescFile<"DebugCheckers.cpp">;
+ Documentation<NotDocumented>;
} // end "debug"
@@ -810,7 +895,7 @@ let ParentPackage = CloneDetectionAlpha in {
def CloneChecker : Checker<"CloneChecker">,
HelpText<"Reports similar pieces of code.">,
- DescFile<"CloneChecker.cpp">;
+ Documentation<HasAlphaDocumentation>;
} // end "clone"
@@ -822,6 +907,6 @@ let ParentPackage = PortabilityOptIn in {
def UnixAPIPortabilityChecker : Checker<"UnixAPI">,
HelpText<"Finds implementation-defined behavior in UNIX/Posix functions">,
- DescFile<"UnixAPIChecker.cpp">;
+ Documentation<NotDocumented>;
} // end optin.portability
diff --git a/include/clang/StaticAnalyzer/Checkers/ClangCheckers.h b/include/clang/StaticAnalyzer/Checkers/ClangCheckers.h
deleted file mode 100644
index cf0a30a73d8c..000000000000
--- a/include/clang/StaticAnalyzer/Checkers/ClangCheckers.h
+++ /dev/null
@@ -1,22 +0,0 @@
-//===--- ClangCheckers.h - Provides builtin checkers ------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CHECKERS_CLANGCHECKERS_H
-#define LLVM_CLANG_STATICANALYZER_CHECKERS_CLANGCHECKERS_H
-
-namespace clang {
-namespace ento {
-class CheckerRegistry;
-
-void registerBuiltinCheckers(CheckerRegistry &registry);
-
-} // end namespace ento
-} // end namespace clang
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h b/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h
deleted file mode 100644
index f5a06394b187..000000000000
--- a/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h
+++ /dev/null
@@ -1,232 +0,0 @@
-//==-- ObjCRetainCount.h - Retain count summaries for Cocoa -------*- C++ -*--//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the core data structures for retain count "summaries"
-// for Objective-C and Core Foundation APIs. These summaries are used
-// by the static analyzer to summarize the retain/release effects of
-// function and method calls. This drives a path-sensitive typestate
-// analysis in the static analyzer, but can also potentially be used by
-// other clients.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CHECKERS_OBJCRETAINCOUNT_H
-#define LLVM_CLANG_STATICANALYZER_CHECKERS_OBJCRETAINCOUNT_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/SmallVector.h"
-
-namespace clang {
-class FunctionDecl;
-class ObjCMethodDecl;
-
-namespace ento { namespace objc_retain {
-
-/// An ArgEffect summarizes the retain count behavior on an argument or receiver
-/// to a function or method.
-enum ArgEffect {
- /// There is no effect.
- DoNothing,
-
- /// The argument is treated as if an -autorelease message had been sent to
- /// the referenced object.
- Autorelease,
-
- /// The argument is treated as if an -dealloc message had been sent to
- /// the referenced object.
- Dealloc,
-
- /// The argument has its reference count decreased by 1. This is as
- /// if CFRelease has been called on the argument.
- DecRef,
-
- /// The argument has its reference count decreased by 1. This is as
- /// if a -release message has been sent to the argument. This differs
- /// in behavior from DecRef when GC is enabled.
- DecRefMsg,
-
- /// The argument has its reference count decreased by 1 to model
- /// a transferred bridge cast under ARC.
- DecRefBridgedTransferred,
-
- /// The argument has its reference count increased by 1. This is as
- /// if a -retain message has been sent to the argument. This differs
- /// in behavior from IncRef when GC is enabled.
- IncRefMsg,
-
- /// The argument has its reference count increased by 1. This is as
- /// if CFRetain has been called on the argument.
- IncRef,
-
- /// The argument acts as if has been passed to CFMakeCollectable, which
- /// transfers the object to the Garbage Collector under GC.
- MakeCollectable,
-
- /// The argument is a pointer to a retain-counted object; on exit, the new
- /// value of the pointer is a +0 value or NULL.
- UnretainedOutParameter,
-
- /// The argument is a pointer to a retain-counted object; on exit, the new
- /// value of the pointer is a +1 value or NULL.
- RetainedOutParameter,
-
- /// The argument is treated as potentially escaping, meaning that
- /// even when its reference count hits 0 it should be treated as still
- /// possibly being alive as someone else *may* be holding onto the object.
- MayEscape,
-
- /// All typestate tracking of the object ceases. This is usually employed
- /// when the effect of the call is completely unknown.
- StopTracking,
-
- /// All typestate tracking of the object ceases. Unlike StopTracking,
- /// this is also enforced when the method body is inlined.
- ///
- /// In some cases, we obtain a better summary for this checker
- /// by looking at the call site than by inlining the function.
- /// Signifies that we should stop tracking the symbol even if
- /// the function is inlined.
- StopTrackingHard,
-
- /// Performs the combined functionality of DecRef and StopTrackingHard.
- ///
- /// The models the effect that the called function decrements the reference
- /// count of the argument and all typestate tracking on that argument
- /// should cease.
- DecRefAndStopTrackingHard,
-
- /// Performs the combined functionality of DecRefMsg and StopTrackingHard.
- ///
- /// The models the effect that the called function decrements the reference
- /// count of the argument and all typestate tracking on that argument
- /// should cease.
- DecRefMsgAndStopTrackingHard
-};
-
-/// RetEffect summarizes a call's retain/release behavior with respect
-/// to its return value.
-class RetEffect {
-public:
- enum Kind {
- /// Indicates that no retain count information is tracked for
- /// the return value.
- NoRet,
- /// Indicates that the returned value is an owned (+1) symbol.
- OwnedSymbol,
- /// Indicates that the returned value is an object with retain count
- /// semantics but that it is not owned (+0). This is the default
- /// for getters, etc.
- NotOwnedSymbol,
- /// Indicates that the object is not owned and controlled by the
- /// Garbage collector.
- GCNotOwnedSymbol,
- /// Indicates that the return value is an owned object when the
- /// receiver is also a tracked object.
- OwnedWhenTrackedReceiver,
- // Treat this function as returning a non-tracked symbol even if
- // the function has been inlined. This is used where the call
- // site summary is more presise than the summary indirectly produced
- // by inlining the function
- NoRetHard
- };
-
- /// Determines the object kind of a tracked object.
- enum ObjKind {
- /// Indicates that the tracked object is a CF object. This is
- /// important between GC and non-GC code.
- CF,
- /// Indicates that the tracked object is an Objective-C object.
- ObjC,
- /// Indicates that the tracked object could be a CF or Objective-C object.
- AnyObj,
- /// Indicates that the tracked object is a generalized object.
- Generalized
- };
-
-private:
- Kind K;
- ObjKind O;
-
- RetEffect(Kind k, ObjKind o = AnyObj) : K(k), O(o) {}
-
-public:
- Kind getKind() const { return K; }
-
- ObjKind getObjKind() const { return O; }
-
- bool isOwned() const {
- return K == OwnedSymbol || K == OwnedWhenTrackedReceiver;
- }
-
- bool notOwned() const {
- return K == NotOwnedSymbol;
- }
-
- bool operator==(const RetEffect &Other) const {
- return K == Other.K && O == Other.O;
- }
-
- static RetEffect MakeOwnedWhenTrackedReceiver() {
- return RetEffect(OwnedWhenTrackedReceiver, ObjC);
- }
-
- static RetEffect MakeOwned(ObjKind o) {
- return RetEffect(OwnedSymbol, o);
- }
- static RetEffect MakeNotOwned(ObjKind o) {
- return RetEffect(NotOwnedSymbol, o);
- }
- static RetEffect MakeGCNotOwned() {
- return RetEffect(GCNotOwnedSymbol, ObjC);
- }
- static RetEffect MakeNoRet() {
- return RetEffect(NoRet);
- }
- static RetEffect MakeNoRetHard() {
- return RetEffect(NoRetHard);
- }
-};
-
-/// Encapsulates the retain count semantics on the arguments, return value,
-/// and receiver (if any) of a function/method call.
-///
-/// Note that construction of these objects is not highly efficient. That
-/// is okay for clients where creating these objects isn't really a bottleneck.
-/// The purpose of the API is to provide something simple. The actual
-/// static analyzer checker that implements retain/release typestate
-/// tracking uses something more efficient.
-class CallEffects {
- llvm::SmallVector<ArgEffect, 10> Args;
- RetEffect Ret;
- ArgEffect Receiver;
-
- CallEffects(const RetEffect &R) : Ret(R) {}
-
-public:
- /// Returns the argument effects for a call.
- ArrayRef<ArgEffect> getArgs() const { return Args; }
-
- /// Returns the effects on the receiver.
- ArgEffect getReceiver() const { return Receiver; }
-
- /// Returns the effect on the return value.
- RetEffect getReturnValue() const { return Ret; }
-
- /// Return the CallEfect for a given Objective-C method.
- static CallEffects getEffect(const ObjCMethodDecl *MD);
-
- /// Return the CallEfect for a given C/C++ function.
- static CallEffects getEffect(const FunctionDecl *FD);
-};
-
-}}}
-
-#endif
-
diff --git a/include/clang/StaticAnalyzer/Core/Analyses.def b/include/clang/StaticAnalyzer/Core/Analyses.def
index 281a2ac3a66f..99e26c75e1c2 100644
--- a/include/clang/StaticAnalyzer/Core/Analyses.def
+++ b/include/clang/StaticAnalyzer/Core/Analyses.def
@@ -33,6 +33,7 @@ ANALYSIS_DIAGNOSTICS(HTML_SINGLE_FILE, "html-single-file", "Output analysis resu
ANALYSIS_DIAGNOSTICS(PLIST, "plist", "Output analysis results using Plists", createPlistDiagnosticConsumer)
ANALYSIS_DIAGNOSTICS(PLIST_MULTI_FILE, "plist-multi-file", "Output analysis results using Plists (allowing for multi-file bugs)", createPlistMultiFileDiagnosticConsumer)
ANALYSIS_DIAGNOSTICS(PLIST_HTML, "plist-html", "Output analysis results using HTML wrapped with Plists", createPlistHTMLDiagnosticConsumer)
+ANALYSIS_DIAGNOSTICS(SARIF, "sarif", "Output analysis results in a SARIF file", createSarifDiagnosticConsumer)
ANALYSIS_DIAGNOSTICS(TEXT, "text", "Text output of analysis results", createTextPathDiagnosticConsumer)
#ifndef ANALYSIS_PURGE
diff --git a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
new file mode 100644
index 000000000000..3cd54df7b179
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
@@ -0,0 +1,377 @@
+//===-- AnalyzerOptions.def - Metadata about Static Analyses ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the analyzer options avaible with -analyzer-config.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_STRINGREF_H
+#error This .def file is expected to be included in translation units where \
+"llvm/ADT/StringRef.h" is already included!
+#endif
+
+#ifdef ANALYZER_OPTION
+#ifndef ANALYZER_OPTION_DEPENDS_ON_USER_MODE
+#error If you didnt include this file with the intent of generating methods, \
+define both 'ANALYZER_OPTION' and 'ANALYZER_OPTION_DEPENDS_ON_USER_MODE' macros!
+#endif
+#endif
+
+#ifndef ANALYZER_OPTION_DEPENDS_ON_USER_MODE
+#ifdef ANALYZER_OPTION
+#error If you didnt include this file with the intent of generating methods, \
+define both 'ANALYZER_OPTION' and 'ANALYZER_OPTION_DEPENDS_ON_USER_MODE' macros!
+#endif
+#endif
+
+#ifndef ANALYZER_OPTION
+/// Create a new analyzer option, but dont generate a method for it in
+/// AnalyzerOptions.
+///
+/// TYPE - The type of the option object that will be stored in
+/// AnalyzerOptions. This file is expected to be icluded in translation
+/// units where AnalyzerOptions.h is included, so types from that
+/// header should be used.
+/// NAME - The name of the option object.
+/// CMDFLAG - The command line flag for the option.
+/// (-analyzer-config CMDFLAG=VALUE)
+/// DESC - Description of the flag.
+/// DEFAULT_VAL - The default value for CMDFLAG.
+#define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL)
+#endif
+
+#ifndef ANALYZER_OPTION_DEPENDS_ON_USER_MODE
+/// Create a new analyzer option, but dont generate a method for it in
+/// AnalyzerOptions. It's value depends on the option "user-mode".
+///
+/// TYPE - The type of the option object that will be stored in
+/// AnalyzerOptions. This file is expected to be icluded in translation
+/// units where AnalyzerOptions.h is included, so types from that
+/// header should be used.
+/// NAME - The name of the option object.
+/// CMDFLAG - The command line flag for the option.
+/// (-analyzer-config CMDFLAG=VALUE)
+/// DESC - Description of the flag.
+/// SHALLOW_VAL - The default value for CMDFLAG, when "user-mode" was set to
+/// "shallow".
+/// DEEP_VAL - The default value for CMDFLAG, when "user-mode" was set to
+/// "deep".
+#define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC, \
+ SHALLOW_VAL, DEEP_VAL)
+#endif
+
+//===----------------------------------------------------------------------===//
+// The "mode" option. Since some options depend on this, we list it on top of
+// this file in order to make sure that the generated field for it is
+// initialized before the rest.
+//===----------------------------------------------------------------------===//
+
+ANALYZER_OPTION(
+ StringRef, UserMode, "mode",
+ "(string) Controls the high-level analyzer mode, which influences the "
+ "default settings for some of the lower-level config options (such as "
+ "IPAMode). Value: \"deep\", \"shallow\".",
+ "deep")
+
+//===----------------------------------------------------------------------===//
+// Boolean analyzer options.
+//===----------------------------------------------------------------------===//
+
+ANALYZER_OPTION(bool, ShouldIncludeImplicitDtorsInCFG, "cfg-implicit-dtors",
+ "Whether or not implicit destructors for C++ objects "
+ "should be included in the CFG.",
+ true)
+
+ANALYZER_OPTION(bool, ShouldIncludeTemporaryDtorsInCFG, "cfg-temporary-dtors",
+ "Whether or not the destructors for C++ temporary "
+ "objects should be included in the CFG.",
+ true)
+
+ANALYZER_OPTION(
+ bool, ShouldIncludeLifetimeInCFG, "cfg-lifetime",
+ "Whether or not end-of-lifetime information should be included in the CFG.",
+ false)
+
+ANALYZER_OPTION(bool, ShouldIncludeLoopExitInCFG, "cfg-loopexit",
+ "Whether or not the end of the loop information should "
+ "be included in the CFG.",
+ false)
+
+ANALYZER_OPTION(bool, ShouldIncludeRichConstructorsInCFG,
+ "cfg-rich-constructors",
+ "Whether or not construction site information should be "
+ "included in the CFG C++ constructor elements.",
+ true)
+
+ANALYZER_OPTION(
+ bool, ShouldIncludeScopesInCFG, "cfg-scopes",
+ "Whether or not scope information should be included in the CFG.", false)
+
+ANALYZER_OPTION(
+ bool, MayInlineTemplateFunctions, "c++-template-inlining",
+ "Whether or not templated functions may be considered for inlining.", true)
+
+ANALYZER_OPTION(bool, MayInlineCXXStandardLibrary, "c++-stdlib-inlining",
+ "Whether or not C++ standard library functions may be "
+ "considered for inlining.",
+ true)
+
+ANALYZER_OPTION(bool, MayInlineCXXAllocator, "c++-allocator-inlining",
+ "Whether or not allocator call may be considered for inlining.",
+ true)
+
+ANALYZER_OPTION(
+ bool, MayInlineCXXSharedPtrDtor, "c++-shared_ptr-inlining",
+ "Whether or not the destructor of C++ 'shared_ptr' may be considered for "
+ "inlining. This covers std::shared_ptr, std::tr1::shared_ptr, and "
+ "boost::shared_ptr, and indeed any destructor named '~shared_ptr'.",
+ false)
+
+ANALYZER_OPTION(bool, MayInlineCXXTemporaryDtors, "c++-temp-dtor-inlining",
+ "Whether C++ temporary destructors should be inlined "
+ "during analysis. If temporary destructors are disabled "
+ "in the CFG via the 'cfg-temporary-dtors' option, "
+ "temporary destructors would not be inlined anyway.",
+ true)
+
+ANALYZER_OPTION(
+ bool, ShouldSuppressNullReturnPaths, "suppress-null-return-paths",
+ "Whether or not paths that go through null returns should be suppressed. "
+ "This is a heuristic for avoiding bug reports with paths that go through "
+ "inlined functions that are more defensive than their callers.",
+ true)
+
+ANALYZER_OPTION(
+ bool, ShouldAvoidSuppressingNullArgumentPaths,
+ "avoid-suppressing-null-argument-paths",
+ "Whether a bug report should not be suppressed if its path includes a call "
+ "with a null argument, even if that call has a null return. This option "
+ "has no effect when ShouldSuppressNullReturnPaths is false. This is a "
+ "counter-heuristic to avoid false negatives.",
+ false)
+
+ANALYZER_OPTION(bool, ShouldSuppressInlinedDefensiveChecks,
+ "suppress-inlined-defensive-checks",
+ "Whether or not diagnostics containing inlined "
+ "defensive NULL checks should be suppressed.",
+ true)
+
+ANALYZER_OPTION(bool, MayInlineCXXContainerMethods, "c++-container-inlining",
+ "Whether or not methods of C++ container objects may be "
+ "considered for inlining.",
+ false)
+
+ANALYZER_OPTION(bool, ShouldSuppressFromCXXStandardLibrary,
+ "suppress-c++-stdlib",
+ "Whether or not diagnostics reported within the C++ "
+ "standard library should be suppressed.",
+ true)
+
+ANALYZER_OPTION(bool, ShouldCrosscheckWithZ3, "crosscheck-with-z3",
+ "Whether bug reports should be crosschecked with the Z3 "
+ "constraint manager backend.",
+ false)
+
+ANALYZER_OPTION(bool, ShouldReportIssuesInMainSourceFile,
+ "report-in-main-source-file",
+ "Whether or not the diagnostic report should be always "
+ "reported in the main source file and not the headers.",
+ false)
+
+ANALYZER_OPTION(bool, ShouldWriteStableReportFilename, "stable-report-filename",
+ "Whether or not the report filename should be random or not.",
+ false)
+
+ANALYZER_OPTION(
+ bool, ShouldSerializeStats, "serialize-stats",
+ "Whether the analyzer should serialize statistics to plist output. "
+ "Statistics would be serialized in JSON format inside the main dictionary "
+ "under the statistics key. Available only if compiled in assert mode or "
+ "with LLVM statistics explicitly enabled.",
+ false)
+
+ANALYZER_OPTION(bool, MayInlineObjCMethod, "objc-inlining",
+ "Whether ObjectiveC inlining is enabled, false otherwise.",
+ true)
+
+ANALYZER_OPTION(bool, ShouldPrunePaths, "prune-paths",
+ "Whether irrelevant parts of a bug report path should "
+ "be pruned out of the final output.",
+ true)
+
+ANALYZER_OPTION(
+ bool, ShouldConditionalizeStaticInitializers,
+ "cfg-conditional-static-initializers",
+ "Whether 'static' initializers should be in conditional logic in the CFG.",
+ true)
+
+ANALYZER_OPTION(bool, ShouldSynthesizeBodies, "faux-bodies",
+ "Whether the analyzer engine should synthesize fake "
+ "bodies for well-known functions.",
+ true)
+
+ANALYZER_OPTION(
+ bool, ShouldElideConstructors, "elide-constructors",
+ "Whether elidable C++ copy-constructors and move-constructors should be "
+ "actually elided during analysis. Both behaviors are allowed by the C++ "
+ "standard, and the analyzer, like CodeGen, defaults to eliding. Starting "
+ "with C++17 some elisions become mandatory, and in these cases the option "
+ "will be ignored.",
+ true)
+
+ANALYZER_OPTION(
+ bool, ShouldInlineLambdas, "inline-lambdas",
+ "Whether lambdas should be inlined. Otherwise a sink node will be "
+ "generated each time a LambdaExpr is visited.",
+ true)
+
+ANALYZER_OPTION(bool, ShouldWidenLoops, "widen-loops",
+ "Whether the analysis should try to widen loops.", false)
+
+ANALYZER_OPTION(
+ bool, ShouldUnrollLoops, "unroll-loops",
+ "Whether the analysis should try to unroll loops with known bounds.", false)
+
+ANALYZER_OPTION(
+ bool, ShouldDisplayNotesAsEvents, "notes-as-events",
+ "Whether the bug reporter should transparently treat extra note diagnostic "
+ "pieces as event diagnostic pieces. Useful when the diagnostic consumer "
+ "doesn't support the extra note pieces.",
+ false)
+
+ANALYZER_OPTION(
+ bool, ShouldAggressivelySimplifyBinaryOperation,
+ "aggressive-binary-operation-simplification",
+ "Whether SValBuilder should rearrange comparisons and additive operations "
+ "of symbolic expressions which consist of a sum of a symbol and a concrete "
+ "integer into the format where symbols are on the left-hand side and the "
+ "integer is on the right. This is only done if both symbols and both "
+ "concrete integers are signed, greater than or equal to the quarter of the "
+ "minimum value of the type and less than or equal to the quarter of the "
+ "maximum value of that type. A + n <OP> B + m becomes A - B <OP> m - n, "
+ "where A and B symbolic, n and m are integers. <OP> is any of '==', '!=', "
+ "'<', '<=', '>', '>=', '+' or '-'. The rearrangement also happens with '-' "
+ "instead of '+' on either or both side and also if any or both integers "
+ "are missing.",
+ false)
+
+ANALYZER_OPTION(
+ bool, ShouldEagerlyAssume, "eagerly-assume",
+ "Whether we should eagerly assume evaluations of conditionals, thus, "
+ "bifurcating the path. This indicates how the engine should handle "
+ "expressions such as: 'x = (y != 0)'. When this is true then the "
+ "subexpression 'y != 0' will be eagerly assumed to be true or false, thus "
+ "evaluating it to the integers 0 or 1 respectively. The upside is that "
+ "this can increase analysis precision until we have a better way to lazily "
+ "evaluate such logic. The downside is that it eagerly bifurcates paths.",
+ true)
+
+ANALYZER_OPTION(
+ bool, IsNaiveCTUEnabled, "experimental-enable-naive-ctu-analysis",
+ "Whether naive cross translation unit analysis is enabled. This is an "
+ "experimental feature to inline functions from other translation units.",
+ false)
+
+ANALYZER_OPTION(bool, ShouldDisplayMacroExpansions, "expand-macros",
+ "Whether macros related to the bugpath should be "
+ "expanded and included in the plist output.",
+ false)
+
+ANALYZER_OPTION(bool, DisplayCTUProgress, "display-ctu-progress",
+ "Whether to emit verbose output about "
+ "the analyzer's progress related to ctu.",
+ false)
+
+//===----------------------------------------------------------------------===//
+// Unsinged analyzer options.
+//===----------------------------------------------------------------------===//
+
+ANALYZER_OPTION(
+ unsigned, AlwaysInlineSize, "ipa-always-inline-size",
+ "The size of the functions (in basic blocks), which should be considered "
+ "to be small enough to always inline.",
+ 3)
+
+ANALYZER_OPTION(
+ unsigned, GraphTrimInterval, "graph-trim-interval",
+ "How often nodes in the ExplodedGraph should be recycled to save memory. "
+ "To disable node reclamation, set the option to 0.",
+ 1000)
+
+ANALYZER_OPTION(
+ unsigned, MinCFGSizeTreatFunctionsAsLarge,
+ "min-cfg-size-treat-functions-as-large",
+ "The number of basic blocks a function needs to have to be considered "
+ "large for the 'max-times-inline-large' config option.",
+ 14)
+
+ANALYZER_OPTION(unsigned, MaxSymbolComplexity, "max-symbol-complexity",
+ "The maximum complexity of symbolic constraint.", 35)
+
+ANALYZER_OPTION(unsigned, MaxTimesInlineLarge, "max-times-inline-large",
+ "The maximum times a large function could be inlined.", 32)
+
+ANALYZER_OPTION_DEPENDS_ON_USER_MODE(
+ unsigned, MaxInlinableSize, "max-inlinable-size",
+ "The bound on the number of basic blocks in an inlined function.",
+ /* SHALLOW_VAL */ 4, /* DEEP_VAL */ 100)
+
+ANALYZER_OPTION_DEPENDS_ON_USER_MODE(
+ unsigned, MaxNodesPerTopLevelFunction, "max-nodes",
+ "The maximum number of nodes the analyzer can generate while exploring a "
+ "top level function (for each exploded graph). 0 means no limit.",
+ /* SHALLOW_VAL */ 75000, /* DEEP_VAL */ 225000)
+
+ANALYZER_OPTION(
+ unsigned, RegionStoreSmallStructLimit, "region-store-small-struct-limit",
+ "The largest number of fields a struct can have and still be considered "
+ "small This is currently used to decide whether or not it is worth forcing "
+ "a LazyCompoundVal on bind. To disable all small-struct-dependent "
+ "behavior, set the option to 0.",
+ 2)
+
+//===----------------------------------------------------------------------===//
+// String analyzer options.
+//===----------------------------------------------------------------------===//
+
+ANALYZER_OPTION(StringRef, CTUDir, "ctu-dir",
+ "The directory containing the CTU related files.", "")
+
+ANALYZER_OPTION(StringRef, CTUIndexName, "ctu-index-name",
+ "the name of the file containing the CTU index of definitions.",
+ "externalDefMap.txt")
+
+ANALYZER_OPTION(
+ StringRef, ModelPath, "model-path",
+ "The analyzer can inline an alternative implementation written in C at the "
+ "call site if the called function's body is not available. This is a path "
+ "where to look for those alternative implementations (called models).",
+ "")
+
+ANALYZER_OPTION(
+ StringRef, CXXMemberInliningMode, "c++-inlining",
+ "Controls which C++ member functions will be considered for inlining. "
+ "Value: \"constructors\", \"destructors\", \"methods\".",
+ "destructors")
+
+ANALYZER_OPTION_DEPENDS_ON_USER_MODE(
+ StringRef, IPAMode, "ipa",
+ "Controls the mode of inter-procedural analysis. Value: \"none\", "
+ "\"basic-inlining\", \"inlining\", \"dynamic\", \"dynamic-bifurcate\".",
+ /* SHALLOW_VAL */ "inlining", /* DEEP_VAL */ "dynamic-bifurcate")
+
+ANALYZER_OPTION(
+ StringRef, ExplorationStrategy, "exploration_strategy",
+ "Value: \"dfs\", \"bfs\", \"unexplored_first\", "
+ "\"unexplored_first_queue\", \"unexplored_first_location_queue\", "
+ "\"bfs_block_dfs_contents\".",
+ "unexplored_first_queue")
+
+#undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE
+#undef ANALYZER_OPTION
diff --git a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
index 7586f7e0835b..7745e459e19b 100644
--- a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
+++ b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
@@ -20,6 +20,7 @@
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSwitch.h"
#include <string>
#include <utility>
#include <vector>
@@ -85,7 +86,7 @@ enum CXXInlineableMemberKind {
// Uninitialized = 0,
/// A dummy mode in which no C++ inlining is enabled.
- CIMK_None = 1,
+ CIMK_None,
/// Refers to regular member function and operator calls.
CIMK_MemberFunctions,
@@ -102,8 +103,6 @@ enum CXXInlineableMemberKind {
/// Describes the different modes of inter-procedural analysis.
enum IPAKind {
- IPAK_NotSet = 0,
-
/// Perform only intra-procedural analysis.
IPAK_None = 1,
@@ -121,6 +120,46 @@ enum IPAKind {
IPAK_DynamicDispatchBifurcate = 5
};
+enum class ExplorationStrategyKind {
+ DFS,
+ BFS,
+ UnexploredFirst,
+ UnexploredFirstQueue,
+ UnexploredFirstLocationQueue,
+ BFSBlockDFSContents,
+};
+
+/// Describes the kinds for high-level analyzer mode.
+enum UserModeKind {
+ /// Perform shallow but fast analyzes.
+ UMK_Shallow = 1,
+
+ /// Perform deep analyzes.
+ UMK_Deep = 2
+};
+
+/// Stores options for the analyzer from the command line.
+///
+/// Some options are frontend flags (e.g.: -analyzer-output), but some are
+/// analyzer configuration options, which are preceded by -analyzer-config
+/// (e.g.: -analyzer-config notes-as-events=true).
+///
+/// If you'd like to add a new frontend flag, add it to
+/// include/clang/Driver/CC1Options.td, add a new field to store the value of
+/// that flag in this class, and initialize it in
+/// lib/Frontend/CompilerInvocation.cpp.
+///
+/// If you'd like to add a new non-checker configuration, register it in
+/// include/clang/StaticAnalyzer/Core/AnalyzerOptions.def, and refer to the
+/// top of the file for documentation.
+///
+/// If you'd like to add a new checker option, call getChecker*Option()
+/// whenever.
+///
+/// Some of the options are controlled by raw frontend flags for no good reason,
+/// and should be eventually converted into -analyzer-config flags. New analyzer
+/// options should not be implemented as frontend flags. Frontend flags still
+/// make sense for things that do not affect the actual analysis.
class AnalyzerOptions : public RefCountedBase<AnalyzerOptions> {
public:
using ConfigTable = llvm::StringMap<std::string>;
@@ -132,6 +171,7 @@ public:
std::vector<std::pair<std::string, bool>> CheckersControlList;
/// A key-value table of use-specified configuration values.
+ // TODO: This shouldn't be public.
ConfigTable Config;
AnalysisStores AnalysisStoreOpt = RegionStoreModel;
AnalysisConstraints AnalysisConstraintsOpt = RangeConstraintsModel;
@@ -140,6 +180,9 @@ public:
std::string AnalyzeSpecificFunction;
+ /// File path to which the exploded graph should be dumped.
+ std::string DumpExplodedGraphTo;
+
/// Store full compiler invocation for reproducible instructions in the
/// generated report.
std::string FullCompilerInvocation;
@@ -156,24 +199,16 @@ public:
unsigned ShowCheckerHelp : 1;
unsigned ShowEnabledCheckerList : 1;
+ unsigned ShowConfigOptionsList : 1;
+ unsigned ShouldEmitErrorsOnInvalidConfigValue : 1;
unsigned AnalyzeAll : 1;
unsigned AnalyzerDisplayProgress : 1;
unsigned AnalyzeNestedBlocks : 1;
- /// The flag regulates if we should eagerly assume evaluations of
- /// conditionals, thus, bifurcating the path.
- ///
- /// This flag indicates how the engine should handle expressions such as: 'x =
- /// (y != 0)'. When this flag is true then the subexpression 'y != 0' will be
- /// eagerly assumed to be true or false, thus evaluating it to the integers 0
- /// or 1 respectively. The upside is that this can increase analysis
- /// precision until we have a better way to lazily evaluate such logic. The
- /// downside is that it eagerly bifurcates paths.
unsigned eagerlyAssumeBinOpBifurcation : 1;
unsigned TrimGraph : 1;
unsigned visualizeExplodedGraphWithGraphViz : 1;
- unsigned visualizeExplodedGraphWithUbiGraph : 1;
unsigned UnoptimizedCFG : 1;
unsigned PrintStats : 1;
@@ -188,187 +223,51 @@ public:
/// The mode of function selection used during inlining.
AnalysisInliningMode InliningMode = NoRedundancy;
- enum class ExplorationStrategyKind {
- DFS,
- BFS,
- UnexploredFirst,
- UnexploredFirstQueue,
- BFSBlockDFSContents,
- NotSet
- };
-
-private:
- ExplorationStrategyKind ExplorationStrategy = ExplorationStrategyKind::NotSet;
-
- /// Describes the kinds for high-level analyzer mode.
- enum UserModeKind {
- UMK_NotSet = 0,
-
- /// Perform shallow but fast analyzes.
- UMK_Shallow = 1,
-
- /// Perform deep analyzes.
- UMK_Deep = 2
- };
-
- /// Controls the high-level analyzer mode, which influences the default
- /// settings for some of the lower-level config options (such as IPAMode).
- /// \sa getUserMode
- UserModeKind UserMode = UMK_NotSet;
-
- /// Controls the mode of inter-procedural analysis.
- IPAKind IPAMode = IPAK_NotSet;
-
- /// Controls which C++ member functions will be considered for inlining.
- CXXInlineableMemberKind CXXMemberInliningMode;
-
- /// \sa includeImplicitDtorsInCFG
- Optional<bool> IncludeImplicitDtorsInCFG;
-
- /// \sa includeTemporaryDtorsInCFG
- Optional<bool> IncludeTemporaryDtorsInCFG;
-
- /// \sa IncludeLifetimeInCFG
- Optional<bool> IncludeLifetimeInCFG;
-
- /// \sa IncludeLoopExitInCFG
- Optional<bool> IncludeLoopExitInCFG;
-
- /// \sa IncludeRichConstructorsInCFG
- Optional<bool> IncludeRichConstructorsInCFG;
-
- /// \sa mayInlineCXXStandardLibrary
- Optional<bool> InlineCXXStandardLibrary;
-
- /// \sa includeScopesInCFG
- Optional<bool> IncludeScopesInCFG;
-
- /// \sa mayInlineTemplateFunctions
- Optional<bool> InlineTemplateFunctions;
-
- /// \sa mayInlineCXXAllocator
- Optional<bool> InlineCXXAllocator;
-
- /// \sa mayInlineCXXContainerMethods
- Optional<bool> InlineCXXContainerMethods;
-
- /// \sa mayInlineCXXSharedPtrDtor
- Optional<bool> InlineCXXSharedPtrDtor;
-
- /// \sa mayInlineCXXTemporaryDtors
- Optional<bool> InlineCXXTemporaryDtors;
+ // Create a field for each -analyzer-config option.
+#define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC, \
+ SHALLOW_VAL, DEEP_VAL) \
+ ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, SHALLOW_VAL)
- /// \sa mayInlineObjCMethod
- Optional<bool> ObjCInliningMode;
+#define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL) \
+ TYPE NAME;
- // Cache of the "ipa-always-inline-size" setting.
- // \sa getAlwaysInlineSize
- Optional<unsigned> AlwaysInlineSize;
+#include "clang/StaticAnalyzer/Core/AnalyzerOptions.def"
+#undef ANALYZER_OPTION
+#undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE
- /// \sa shouldSuppressNullReturnPaths
- Optional<bool> SuppressNullReturnPaths;
+ // Create an array of all -analyzer-config command line options. Sort it in
+ // the constructor.
+ std::vector<StringRef> AnalyzerConfigCmdFlags = {
+#define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC, \
+ SHALLOW_VAL, DEEP_VAL) \
+ ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, SHALLOW_VAL)
- // \sa getMaxInlinableSize
- Optional<unsigned> MaxInlinableSize;
+#define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL) \
+ CMDFLAG,
- /// \sa shouldAvoidSuppressingNullArgumentPaths
- Optional<bool> AvoidSuppressingNullArgumentPaths;
-
- /// \sa shouldSuppressInlinedDefensiveChecks
- Optional<bool> SuppressInlinedDefensiveChecks;
-
- /// \sa shouldSuppressFromCXXStandardLibrary
- Optional<bool> SuppressFromCXXStandardLibrary;
-
- /// \sa shouldCrosscheckWithZ3
- Optional<bool> CrosscheckWithZ3;
-
- /// \sa reportIssuesInMainSourceFile
- Optional<bool> ReportIssuesInMainSourceFile;
-
- /// \sa StableReportFilename
- Optional<bool> StableReportFilename;
-
- Optional<bool> SerializeStats;
-
- /// \sa getGraphTrimInterval
- Optional<unsigned> GraphTrimInterval;
-
- /// \sa getMaxSymbolComplexity
- Optional<unsigned> MaxSymbolComplexity;
-
- /// \sa getMaxTimesInlineLarge
- Optional<unsigned> MaxTimesInlineLarge;
-
- /// \sa getMinCFGSizeTreatFunctionsAsLarge
- Optional<unsigned> MinCFGSizeTreatFunctionsAsLarge;
-
- /// \sa getMaxNodesPerTopLevelFunction
- Optional<unsigned> MaxNodesPerTopLevelFunction;
-
- /// \sa shouldInlineLambdas
- Optional<bool> InlineLambdas;
-
- /// \sa shouldWidenLoops
- Optional<bool> WidenLoops;
-
- /// \sa shouldUnrollLoops
- Optional<bool> UnrollLoops;
-
- /// \sa shouldDisplayNotesAsEvents
- Optional<bool> DisplayNotesAsEvents;
-
- /// \sa shouldAggressivelySimplifyBinaryOperation
- Optional<bool> AggressiveBinaryOperationSimplification;
-
- /// \sa getCTUDir
- Optional<StringRef> CTUDir;
-
- /// \sa getCTUIndexName
- Optional<StringRef> CTUIndexName;
-
- /// \sa naiveCTUEnabled
- Optional<bool> NaiveCTU;
+#include "clang/StaticAnalyzer/Core/AnalyzerOptions.def"
+#undef ANALYZER_OPTION
+#undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE
+ };
- /// \sa shouldElideConstructors
- Optional<bool> ElideConstructors;
+ bool isUnknownAnalyzerConfig(StringRef Name) const {
+ assert(std::is_sorted(AnalyzerConfigCmdFlags.begin(),
+ AnalyzerConfigCmdFlags.end()));
- /// A helper function that retrieves option for a given full-qualified
- /// checker name.
- /// Options for checkers can be specified via 'analyzer-config' command-line
- /// option.
- /// Example:
- /// @code-analyzer-config unix.Malloc:OptionName=CheckerOptionValue @endcode
- /// or @code-analyzer-config unix:OptionName=GroupOptionValue @endcode
- /// for groups of checkers.
- /// @param [in] CheckerName Full-qualified checker name, like
- /// alpha.unix.StreamChecker.
- /// @param [in] OptionName Name of the option to get.
- /// @param [in] Default Default value if no option is specified.
- /// @param [in] SearchInParents If set to true and the searched option was not
- /// specified for the given checker the options for the parent packages will
- /// be searched as well. The inner packages take precedence over the outer
- /// ones.
- /// @retval CheckerOptionValue An option for a checker if it was specified.
- /// @retval GroupOptionValue An option for group if it was specified and no
- /// checker-specific options were found. The closer group to checker,
- /// the more priority it has. For example, @c coregroup.subgroup has more
- /// priority than @c coregroup for @c coregroup.subgroup.CheckerName checker.
- /// @retval Default If nor checker option, nor group option was found.
- StringRef getCheckerOption(StringRef CheckerName, StringRef OptionName,
- StringRef Default,
- bool SearchInParents = false);
+ return !std::binary_search(AnalyzerConfigCmdFlags.begin(),
+ AnalyzerConfigCmdFlags.end(), Name);
+ }
-public:
AnalyzerOptions()
: DisableAllChecks(false), ShowCheckerHelp(false),
- ShowEnabledCheckerList(false), AnalyzeAll(false),
- AnalyzerDisplayProgress(false), AnalyzeNestedBlocks(false),
- eagerlyAssumeBinOpBifurcation(false), TrimGraph(false),
- visualizeExplodedGraphWithGraphViz(false),
- visualizeExplodedGraphWithUbiGraph(false), UnoptimizedCFG(false),
- PrintStats(false), NoRetryExhausted(false), CXXMemberInliningMode() {}
+ ShowEnabledCheckerList(false), ShowConfigOptionsList(false),
+ AnalyzeAll(false), AnalyzerDisplayProgress(false),
+ AnalyzeNestedBlocks(false), eagerlyAssumeBinOpBifurcation(false),
+ TrimGraph(false), visualizeExplodedGraphWithGraphViz(false),
+ UnoptimizedCFG(false), PrintStats(false), NoRetryExhausted(false) {
+ llvm::sort(AnalyzerConfigCmdFlags);
+ }
/// Interprets an option's string value as a boolean. The "true" string is
/// interpreted as true and the "false" string is interpreted as false.
@@ -377,34 +276,17 @@ public:
/// @param [in] Name Name for option to retrieve.
/// @param [in] DefaultVal Default value returned if no such option was
/// specified.
- /// @param [in] C The optional checker parameter that can be used to restrict
- /// the search to the options of this particular checker (and its parents
- /// depending on search mode).
+ /// @param [in] C The checker object the option belongs to. Checker options
+ /// are retrieved in the following format:
+ /// `-analyzer-config <package and checker name>:OptionName=Value.
/// @param [in] SearchInParents If set to true and the searched option was not
/// specified for the given checker the options for the parent packages will
/// be searched as well. The inner packages take precedence over the outer
/// ones.
- bool getBooleanOption(StringRef Name, bool DefaultVal,
- const ento::CheckerBase *C = nullptr,
- bool SearchInParents = false);
+ bool getCheckerBooleanOption(StringRef Name, bool DefaultVal,
+ const ento::CheckerBase *C,
+ bool SearchInParents = false) const;
- /// Variant that accepts a Optional value to cache the result.
- ///
- /// @param [in,out] V Return value storage, returned if parameter contains
- /// an existing valid option, else it is used to store a return value
- /// @param [in] Name Name for option to retrieve.
- /// @param [in] DefaultVal Default value returned if no such option was
- /// specified.
- /// @param [in] C The optional checker parameter that can be used to restrict
- /// the search to the options of this particular checker (and its parents
- /// depending on search mode).
- /// @param [in] SearchInParents If set to true and the searched option was not
- /// specified for the given checker the options for the parent packages will
- /// be searched as well. The inner packages take precedence over the outer
- /// ones.
- bool getBooleanOption(Optional<bool> &V, StringRef Name, bool DefaultVal,
- const ento::CheckerBase *C = nullptr,
- bool SearchInParents = false);
/// Interprets an option's string value as an integer value.
///
@@ -412,16 +294,16 @@ public:
/// @param [in] Name Name for option to retrieve.
/// @param [in] DefaultVal Default value returned if no such option was
/// specified.
- /// @param [in] C The optional checker parameter that can be used to restrict
- /// the search to the options of this particular checker (and its parents
- /// depending on search mode).
+ /// @param [in] C The checker object the option belongs to. Checker options
+ /// are retrieved in the following format:
+ /// `-analyzer-config <package and checker name>:OptionName=Value.
/// @param [in] SearchInParents If set to true and the searched option was not
/// specified for the given checker the options for the parent packages will
/// be searched as well. The inner packages take precedence over the outer
/// ones.
- int getOptionAsInteger(StringRef Name, int DefaultVal,
- const ento::CheckerBase *C = nullptr,
- bool SearchInParents = false);
+ int getCheckerIntegerOption(StringRef Name, int DefaultVal,
+ const ento::CheckerBase *C,
+ bool SearchInParents = false) const;
/// Query an option's string value.
///
@@ -429,26 +311,26 @@ public:
/// @param [in] Name Name for option to retrieve.
/// @param [in] DefaultVal Default value returned if no such option was
/// specified.
- /// @param [in] C The optional checker parameter that can be used to restrict
- /// the search to the options of this particular checker (and its parents
- /// depending on search mode).
+ /// @param [in] C The checker object the option belongs to. Checker options
+ /// are retrieved in the following format:
+ /// `-analyzer-config <package and checker name>:OptionName=Value.
/// @param [in] SearchInParents If set to true and the searched option was not
/// specified for the given checker the options for the parent packages will
/// be searched as well. The inner packages take precedence over the outer
/// ones.
- StringRef getOptionAsString(StringRef Name, StringRef DefaultVal,
- const ento::CheckerBase *C = nullptr,
- bool SearchInParents = false);
+ StringRef getCheckerStringOption(StringRef Name, StringRef DefaultVal,
+ const ento::CheckerBase *C,
+ bool SearchInParents = false) const;
/// Retrieves and sets the UserMode. This is a high-level option,
/// which is used to set other low-level options. It is not accessible
/// outside of AnalyzerOptions.
- UserModeKind getUserMode();
+ UserModeKind getUserMode() const;
- ExplorationStrategyKind getExplorationStrategy();
+ ExplorationStrategyKind getExplorationStrategy() const;
/// Returns the inter-procedural analysis mode.
- IPAKind getIPAMode();
+ IPAKind getIPAMode() const;
/// Returns the option controlling which C++ member functions will be
/// considered for inlining.
@@ -456,275 +338,28 @@ public:
/// This is controlled by the 'c++-inlining' config option.
///
/// \sa CXXMemberInliningMode
- bool mayInlineCXXMemberFunction(CXXInlineableMemberKind K);
-
- /// Returns true if ObjectiveC inlining is enabled, false otherwise.
- bool mayInlineObjCMethod();
-
- /// Returns whether or not the destructors for C++ temporary objects should
- /// be included in the CFG.
- ///
- /// This is controlled by the 'cfg-temporary-dtors' config option, which
- /// accepts the values "true" and "false".
- bool includeTemporaryDtorsInCFG();
-
- /// Returns whether or not implicit destructors for C++ objects should
- /// be included in the CFG.
- ///
- /// This is controlled by the 'cfg-implicit-dtors' config option, which
- /// accepts the values "true" and "false".
- bool includeImplicitDtorsInCFG();
-
- /// Returns whether or not end-of-lifetime information should be included in
- /// the CFG.
- ///
- /// This is controlled by the 'cfg-lifetime' config option, which accepts
- /// the values "true" and "false".
- bool includeLifetimeInCFG();
-
- /// Returns whether or not the end of the loop information should be included
- /// in the CFG.
- ///
- /// This is controlled by the 'cfg-loopexit' config option, which accepts
- /// the values "true" and "false".
- bool includeLoopExitInCFG();
-
- /// Returns whether or not construction site information should be included
- /// in the CFG C++ constructor elements.
- ///
- /// This is controlled by the 'cfg-rich-constructors' config options,
- /// which accepts the values "true" and "false".
- bool includeRichConstructorsInCFG();
-
- /// Returns whether or not scope information should be included in the CFG.
- ///
- /// This is controlled by the 'cfg-scope-info' config option, which accepts
- /// the values "true" and "false".
- bool includeScopesInCFG();
-
- /// Returns whether or not C++ standard library functions may be considered
- /// for inlining.
- ///
- /// This is controlled by the 'c++-stdlib-inlining' config option, which
- /// accepts the values "true" and "false".
- bool mayInlineCXXStandardLibrary();
-
- /// Returns whether or not templated functions may be considered for inlining.
- ///
- /// This is controlled by the 'c++-template-inlining' config option, which
- /// accepts the values "true" and "false".
- bool mayInlineTemplateFunctions();
-
- /// Returns whether or not allocator call may be considered for inlining.
- ///
- /// This is controlled by the 'c++-allocator-inlining' config option, which
- /// accepts the values "true" and "false".
- bool mayInlineCXXAllocator();
-
- /// Returns whether or not methods of C++ container objects may be considered
- /// for inlining.
- ///
- /// This is controlled by the 'c++-container-inlining' config option, which
- /// accepts the values "true" and "false".
- bool mayInlineCXXContainerMethods();
-
- /// Returns whether or not the destructor of C++ 'shared_ptr' may be
- /// considered for inlining.
- ///
- /// This covers std::shared_ptr, std::tr1::shared_ptr, and boost::shared_ptr,
- /// and indeed any destructor named "~shared_ptr".
- ///
- /// This is controlled by the 'c++-shared_ptr-inlining' config option, which
- /// accepts the values "true" and "false".
- bool mayInlineCXXSharedPtrDtor();
-
- /// Returns true if C++ temporary destructors should be inlined during
- /// analysis.
- ///
- /// If temporary destructors are disabled in the CFG via the
- /// 'cfg-temporary-dtors' option, temporary destructors would not be
- /// inlined anyway.
- ///
- /// This is controlled by the 'c++-temp-dtor-inlining' config option, which
- /// accepts the values "true" and "false".
- bool mayInlineCXXTemporaryDtors();
-
- /// Returns whether or not paths that go through null returns should be
- /// suppressed.
- ///
- /// This is a heuristic for avoiding bug reports with paths that go through
- /// inlined functions that are more defensive than their callers.
- ///
- /// This is controlled by the 'suppress-null-return-paths' config option,
- /// which accepts the values "true" and "false".
- bool shouldSuppressNullReturnPaths();
-
- /// Returns whether a bug report should \em not be suppressed if its path
- /// includes a call with a null argument, even if that call has a null return.
- ///
- /// This option has no effect when #shouldSuppressNullReturnPaths() is false.
- ///
- /// This is a counter-heuristic to avoid false negatives.
- ///
- /// This is controlled by the 'avoid-suppressing-null-argument-paths' config
- /// option, which accepts the values "true" and "false".
- bool shouldAvoidSuppressingNullArgumentPaths();
-
- /// Returns whether or not diagnostics containing inlined defensive NULL
- /// checks should be suppressed.
- ///
- /// This is controlled by the 'suppress-inlined-defensive-checks' config
- /// option, which accepts the values "true" and "false".
- bool shouldSuppressInlinedDefensiveChecks();
-
- /// Returns whether or not diagnostics reported within the C++ standard
- /// library should be suppressed.
- ///
- /// This is controlled by the 'suppress-c++-stdlib' config option,
- /// which accepts the values "true" and "false".
- bool shouldSuppressFromCXXStandardLibrary();
-
- /// Returns whether bug reports should be crosschecked with the Z3
- /// constraint manager backend.
- ///
- /// This is controlled by the 'crosscheck-with-z3' config option,
- /// which accepts the values "true" and "false".
- bool shouldCrosscheckWithZ3();
-
- /// Returns whether or not the diagnostic report should be always reported
- /// in the main source file and not the headers.
- ///
- /// This is controlled by the 'report-in-main-source-file' config option,
- /// which accepts the values "true" and "false".
- bool shouldReportIssuesInMainSourceFile();
-
- /// Returns whether or not the report filename should be random or not.
- ///
- /// This is controlled by the 'stable-report-filename' config option,
- /// which accepts the values "true" and "false". Default = false
- bool shouldWriteStableReportFilename();
-
- /// \return Whether the analyzer should
- /// serialize statistics to plist output.
- /// Statistics would be serialized in JSON format inside the main dictionary
- /// under the \c statistics key.
- /// Available only if compiled in assert mode or with LLVM statistics
- /// explicitly enabled.
- bool shouldSerializeStats();
-
- /// Returns whether irrelevant parts of a bug report path should be pruned
- /// out of the final output.
- ///
- /// This is controlled by the 'prune-paths' config option, which accepts the
- /// values "true" and "false".
- bool shouldPrunePaths();
-
- /// Returns true if 'static' initializers should be in conditional logic
- /// in the CFG.
- bool shouldConditionalizeStaticInitializers();
-
- // Returns the size of the functions (in basic blocks), which should be
- // considered to be small enough to always inline.
- //
- // This is controlled by "ipa-always-inline-size" analyzer-config option.
- unsigned getAlwaysInlineSize();
-
- // Returns the bound on the number of basic blocks in an inlined function
- // (50 by default).
- //
- // This is controlled by "-analyzer-config max-inlinable-size" option.
- unsigned getMaxInlinableSize();
-
- /// Returns true if the analyzer engine should synthesize fake bodies
- /// for well-known functions.
- bool shouldSynthesizeBodies();
-
- /// Returns how often nodes in the ExplodedGraph should be recycled to save
- /// memory.
- ///
- /// This is controlled by the 'graph-trim-interval' config option. To disable
- /// node reclamation, set the option to "0".
- unsigned getGraphTrimInterval();
-
- /// Returns the maximum complexity of symbolic constraint (50 by default).
- ///
- /// This is controlled by "-analyzer-config max-symbol-complexity" option.
- unsigned getMaxSymbolComplexity();
-
- /// Returns the maximum times a large function could be inlined.
- ///
- /// This is controlled by the 'max-times-inline-large' config option.
- unsigned getMaxTimesInlineLarge();
-
- /// Returns the number of basic blocks a function needs to have to be
- /// considered large for the 'max-times-inline-large' config option.
- ///
- /// This is controlled by the 'min-cfg-size-treat-functions-as-large' config
- /// option.
- unsigned getMinCFGSizeTreatFunctionsAsLarge();
-
- /// Returns the maximum number of nodes the analyzer can generate while
- /// exploring a top level function (for each exploded graph).
- /// 150000 is default; 0 means no limit.
- ///
- /// This is controlled by the 'max-nodes' config option.
- unsigned getMaxNodesPerTopLevelFunction();
-
- /// Returns true if lambdas should be inlined. Otherwise a sink node will be
- /// generated each time a LambdaExpr is visited.
- bool shouldInlineLambdas();
-
- /// Returns true if the analysis should try to widen loops.
- /// This is controlled by the 'widen-loops' config option.
- bool shouldWidenLoops();
-
- /// Returns true if the analysis should try to unroll loops with known bounds.
- /// This is controlled by the 'unroll-loops' config option.
- bool shouldUnrollLoops();
-
- /// Returns true if the bug reporter should transparently treat extra note
- /// diagnostic pieces as event diagnostic pieces. Useful when the diagnostic
- /// consumer doesn't support the extra note pieces.
- ///
- /// This is controlled by the 'extra-notes-as-events' option, which defaults
- /// to false when unset.
- bool shouldDisplayNotesAsEvents();
-
- /// Returns true if SValBuilder should rearrange comparisons and additive
- /// operations of symbolic expressions which consist of a sum of a symbol and
- /// a concrete integer into the format where symbols are on the left-hand
- /// side and the integer is on the right. This is only done if both symbols
- /// and both concrete integers are signed, greater than or equal to the
- /// quarter of the minimum value of the type and less than or equal to the
- /// quarter of the maximum value of that type.
- ///
- /// A + n <OP> B + m becomes A - B <OP> m - n, where A and B symbolic,
- /// n and m are integers. <OP> is any of '==', '!=', '<', '<=', '>', '>=',
- /// '+' or '-'. The rearrangement also happens with '-' instead of '+' on
- // either or both side and also if any or both integers are missing.
- bool shouldAggressivelySimplifyBinaryOperation();
-
- /// Returns the directory containing the CTU related files.
- StringRef getCTUDir();
-
- /// Returns the name of the file containing the CTU index of functions.
- StringRef getCTUIndexName();
-
- /// Returns true when naive cross translation unit analysis is enabled.
- /// This is an experimental feature to inline functions from another
- /// translation units.
- bool naiveCTUEnabled();
-
- /// Returns true if elidable C++ copy-constructors and move-constructors
- /// should be actually elided during analysis. Both behaviors are allowed
- /// by the C++ standard, and the analyzer, like CodeGen, defaults to eliding.
- /// Starting with C++17 some elisions become mandatory, and in these cases
- /// the option will be ignored.
- bool shouldElideConstructors();
+ bool mayInlineCXXMemberFunction(CXXInlineableMemberKind K) const;
};
using AnalyzerOptionsRef = IntrusiveRefCntPtr<AnalyzerOptions>;
+//===----------------------------------------------------------------------===//
+// We'll use AnalyzerOptions in the frontend, but we can't link the frontend
+// with clangStaticAnalyzerCore, because clangStaticAnalyzerCore depends on
+// clangFrontend.
+//
+// For this reason, implement some methods in this header file.
+//===----------------------------------------------------------------------===//
+
+inline UserModeKind AnalyzerOptions::getUserMode() const {
+ auto K = llvm::StringSwitch<llvm::Optional<UserModeKind>>(UserMode)
+ .Case("shallow", UMK_Shallow)
+ .Case("deep", UMK_Deep)
+ .Default(None);
+ assert(K.hasValue() && "User mode is invalid.");
+ return K.getValue();
+}
+
} // namespace clang
#endif // LLVM_CLANG_STATICANALYZER_CORE_ANALYZEROPTIONS_H
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h
index da019f83c214..c023ed5641a3 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h
@@ -58,7 +58,7 @@ public:
/// The last parameter can be used to register a new visitor with the given
/// BugReport while processing a node.
virtual std::shared_ptr<PathDiagnosticPiece>
- VisitNode(const ExplodedNode *Succ, const ExplodedNode *Pred,
+ VisitNode(const ExplodedNode *Succ,
BugReporterContext &BRC, BugReport &BR) = 0;
/// Last function called on the visitor, no further calls to VisitNode
@@ -83,6 +83,8 @@ public:
BugReport &BR);
};
+/// Finds last store into the given region,
+/// which is different from a given symbolic value.
class FindLastStoreBRVisitor final : public BugReporterVisitor {
const MemRegion *R;
SVal V;
@@ -105,7 +107,6 @@ public:
void Profile(llvm::FoldingSetNodeID &ID) const override;
std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
- const ExplodedNode *PrevN,
BugReporterContext &BRC,
BugReport &BR) override;
};
@@ -132,7 +133,6 @@ public:
static const char *getTag();
std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
- const ExplodedNode *PrevN,
BugReporterContext &BRC,
BugReport &BR) override;
@@ -151,7 +151,6 @@ public:
}
std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
- const ExplodedNode *PrevN,
BugReporterContext &BRC,
BugReport &BR) override;
@@ -177,12 +176,10 @@ public:
static const char *getTag();
std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
- const ExplodedNode *Prev,
BugReporterContext &BRC,
BugReport &BR) override;
std::shared_ptr<PathDiagnosticPiece> VisitNodeImpl(const ExplodedNode *N,
- const ExplodedNode *Prev,
BugReporterContext &BRC,
BugReport &BR);
@@ -235,10 +232,9 @@ public:
ID.AddPointer(getTag());
}
- std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
- const ExplodedNode *Prev,
- BugReporterContext &BRC,
- BugReport &BR) override {
+ std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *,
+ BugReporterContext &,
+ BugReport &) override {
return nullptr;
}
@@ -265,7 +261,6 @@ public:
}
std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
- const ExplodedNode *PrevN,
BugReporterContext &BRC,
BugReport &BR) override;
};
@@ -295,7 +290,6 @@ public:
static const char *getTag();
std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *Succ,
- const ExplodedNode *Pred,
BugReporterContext &BRC,
BugReport &BR) override;
};
@@ -309,7 +303,6 @@ public:
void Profile(llvm::FoldingSetNodeID &ID) const override {}
std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *Succ,
- const ExplodedNode *Pred,
BugReporterContext &BRC,
BugReport &BR) override;
};
@@ -325,7 +318,6 @@ public:
void Profile(llvm::FoldingSetNodeID &ID) const override { ID.Add(V); }
std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
- const ExplodedNode *PrevN,
BugReporterContext &BRC,
BugReport &BR) override;
};
@@ -344,7 +336,6 @@ public:
void Profile(llvm::FoldingSetNodeID &ID) const override;
std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
- const ExplodedNode *PrevN,
BugReporterContext &BRC,
BugReport &BR) override;
@@ -354,30 +345,22 @@ public:
namespace bugreporter {
-/// Attempts to add visitors to trace a null or undefined value back to its
-/// point of origin, whether it is a symbol constrained to null or an explicit
-/// assignment.
+/// Attempts to add visitors to track expression value back to its point of
+/// origin.
///
/// \param N A node "downstream" from the evaluation of the statement.
-/// \param S The statement whose value is null or undefined.
+/// \param E The expression value which we are tracking
/// \param R The bug report to which visitors should be attached.
-/// \param IsArg Whether the statement is an argument to an inlined function.
-/// If this is the case, \p N \em must be the CallEnter node for
-/// the function.
/// \param EnableNullFPSuppression Whether we should employ false positive
/// suppression (inlined defensive checks, returned null).
///
/// \return Whether or not the function was able to add visitors for this
/// statement. Note that returning \c true does not actually imply
/// that any visitors were added.
-bool trackNullOrUndefValue(const ExplodedNode *N, const Stmt *S, BugReport &R,
- bool IsArg = false,
- bool EnableNullFPSuppression = true);
+bool trackExpressionValue(const ExplodedNode *N, const Expr *E, BugReport &R,
+ bool EnableNullFPSuppression = true);
const Expr *getDerefExpr(const Stmt *S);
-const Stmt *GetDenomExpr(const ExplodedNode *N);
-const Stmt *GetRetValExpr(const ExplodedNode *N);
-bool isDeclRefExprToReference(const Expr *E);
} // namespace bugreporter
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
index 3c1f8f718a3b..727ec7c66a89 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
@@ -65,8 +65,6 @@ public:
/// by a sink node.
bool isSuppressOnSink() const { return SuppressOnSink; }
void setSuppressOnSink(bool x) { SuppressOnSink = x; }
-
- virtual void FlushReports(BugReporter& BR);
};
class BuiltinBug : public BugType {
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h b/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h
index 0e80e7bc19ba..d07525661a6c 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h
@@ -16,7 +16,7 @@ namespace clang {
namespace categories {
extern const char * const CoreFoundationObjectiveC;
extern const char * const LogicError;
- extern const char * const MemoryCoreFoundationObjectiveC;
+ extern const char * const MemoryRefCount;
extern const char * const MemoryError;
extern const char * const UnixAPI;
}
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
index b0bb12feba20..e9c682d7986c 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
@@ -118,7 +118,7 @@ public:
/// Only runs visitors, no output generated.
None,
- /// Used for HTML and text output.
+ /// Used for HTML, SARIF, and text output.
Minimal,
/// Used for plist output, used for "arrows" generation.
@@ -178,10 +178,9 @@ public:
PathDiagnosticLocation() = default;
/// Create a location corresponding to the given statement.
- PathDiagnosticLocation(const Stmt *s,
- const SourceManager &sm,
+ PathDiagnosticLocation(const Stmt *s, const SourceManager &sm,
LocationOrAnalysisDeclContext lac)
- : K(s->getLocStart().isValid() ? StmtK : SingleLocK),
+ : K(s->getBeginLoc().isValid() ? StmtK : SingleLocK),
S(K == StmtK ? s : nullptr), SM(&sm),
Loc(genLocation(SourceLocation(), lac)), Range(genRange(lac)) {
assert(K == SingleLocK || S);
@@ -633,7 +632,7 @@ public:
}
static std::shared_ptr<PathDiagnosticCallPiece>
- construct(const ExplodedNode *N, const CallExitEnd &CE,
+ construct(const CallExitEnd &CE,
const SourceManager &SM);
static PathDiagnosticCallPiece *construct(PathPieces &pieces,
@@ -760,7 +759,7 @@ public:
};
/// File IDs mapped to sets of line numbers.
-using FilesToLineNumsMap = std::map<unsigned, std::set<unsigned>>;
+using FilesToLineNumsMap = std::map<FileID, std::set<unsigned>>;
/// PathDiagnostic - PathDiagnostic objects represent a single path-sensitive
/// diagnostic. It represents an ordered-collection of PathDiagnosticPieces,
@@ -859,13 +858,13 @@ public:
meta_iterator meta_end() const { return OtherDesc.end(); }
void addMeta(StringRef s) { OtherDesc.push_back(s); }
- using filesmap_iterator = FilesToLineNumsMap::const_iterator;
-
- filesmap_iterator executedLines_begin() const {
- return ExecutedLines->begin();
+ const FilesToLineNumsMap &getExecutedLines() const {
+ return *ExecutedLines;
}
- filesmap_iterator executedLines_end() const { return ExecutedLines->end(); }
+ FilesToLineNumsMap &getExecutedLines() {
+ return *ExecutedLines;
+ }
PathDiagnosticLocation getLocation() const {
return Loc;
diff --git a/include/clang/StaticAnalyzer/Core/Checker.h b/include/clang/StaticAnalyzer/Core/Checker.h
index 8484cfe4c956..786465cee855 100644
--- a/include/clang/StaticAnalyzer/Core/Checker.h
+++ b/include/clang/StaticAnalyzer/Core/Checker.h
@@ -558,6 +558,8 @@ struct ImplicitNullDerefEvent {
// dereference might happen later (for example pointer passed to a parameter
// that is marked with nonnull attribute.)
bool IsDirectDereference;
+
+ static int Tag;
};
/// A helper class which wraps a boolean value set to false by default.
diff --git a/include/clang/StaticAnalyzer/Core/CheckerManager.h b/include/clang/StaticAnalyzer/Core/CheckerManager.h
index 7c353326be46..538ed19f7eef 100644
--- a/include/clang/StaticAnalyzer/Core/CheckerManager.h
+++ b/include/clang/StaticAnalyzer/Core/CheckerManager.h
@@ -115,13 +115,14 @@ enum class ObjCMessageVisitKind {
};
class CheckerManager {
+ ASTContext &Context;
const LangOptions LangOpts;
AnalyzerOptions &AOptions;
CheckName CurrentCheckName;
public:
- CheckerManager(const LangOptions &langOpts, AnalyzerOptions &AOptions)
- : LangOpts(langOpts), AOptions(AOptions) {}
+ CheckerManager(ASTContext &Context, AnalyzerOptions &AOptions)
+ : Context(Context), LangOpts(Context.getLangOpts()), AOptions(AOptions) {}
~CheckerManager();
@@ -134,6 +135,7 @@ public:
const LangOptions &getLangOpts() const { return LangOpts; }
AnalyzerOptions &getAnalyzerOptions() { return AOptions; }
+ ASTContext &getASTContext() { return Context; }
using CheckerRef = CheckerBase *;
using CheckerTag = const void *;
@@ -149,13 +151,13 @@ public:
///
/// \returns a pointer to the checker object.
template <typename CHECKER, typename... AT>
- CHECKER *registerChecker(AT... Args) {
+ CHECKER *registerChecker(AT &&... Args) {
CheckerTag tag = getTag<CHECKER>();
CheckerRef &ref = CheckerTags[tag];
if (ref)
return static_cast<CHECKER *>(ref); // already registered.
- CHECKER *checker = new CHECKER(Args...);
+ CHECKER *checker = new CHECKER(std::forward<AT>(Args)...);
checker->Name = CurrentCheckName;
CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
CHECKER::_register(checker, *this);
@@ -530,19 +532,19 @@ public:
template <typename EVENT>
void _registerListenerForEvent(CheckEventFunc checkfn) {
- EventInfo &info = Events[getTag<EVENT>()];
+ EventInfo &info = Events[&EVENT::Tag];
info.Checkers.push_back(checkfn);
}
template <typename EVENT>
void _registerDispatcherForEvent() {
- EventInfo &info = Events[getTag<EVENT>()];
+ EventInfo &info = Events[&EVENT::Tag];
info.HasDispatcher = true;
}
template <typename EVENT>
void _dispatchEvent(const EVENT &event) const {
- EventsTy::const_iterator I = Events.find(getTag<EVENT>());
+ EventsTy::const_iterator I = Events.find(&EVENT::Tag);
if (I == Events.end())
return;
const EventInfo &info = I->second;
diff --git a/include/clang/StaticAnalyzer/Core/CheckerOptInfo.h b/include/clang/StaticAnalyzer/Core/CheckerOptInfo.h
deleted file mode 100644
index 2d13bf34cd15..000000000000
--- a/include/clang/StaticAnalyzer/Core/CheckerOptInfo.h
+++ /dev/null
@@ -1,44 +0,0 @@
-//===--- CheckerOptInfo.h - Specifies which checkers to use -----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_CHECKEROPTINFO_H
-#define LLVM_CLANG_STATICANALYZER_CORE_CHECKEROPTINFO_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/StringRef.h"
-
-namespace clang {
-namespace ento {
-
-/// Represents a request to include or exclude a checker or package from a
-/// specific analysis run.
-///
-/// \sa CheckerRegistry::initializeManager
-class CheckerOptInfo {
- StringRef Name;
- bool Enable;
- bool Claimed;
-
-public:
- CheckerOptInfo(StringRef name, bool enable)
- : Name(name), Enable(enable), Claimed(false) { }
-
- StringRef getName() const { return Name; }
- bool isEnabled() const { return Enable; }
- bool isDisabled() const { return !isEnabled(); }
-
- bool isClaimed() const { return Claimed; }
- bool isUnclaimed() const { return !isClaimed(); }
- void claim() { Claimed = true; }
-};
-
-} // end namespace ento
-} // end namespace clang
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
index 85369509efcd..50b9b566edc3 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
@@ -46,14 +46,12 @@ class AnalysisManager : public BugReporterData {
public:
AnalyzerOptions &options;
- AnalysisManager(ASTContext &ctx,DiagnosticsEngine &diags,
- const LangOptions &lang,
+ AnalysisManager(ASTContext &ctx, DiagnosticsEngine &diags,
const PathDiagnosticConsumers &Consumers,
StoreManagerCreator storemgr,
ConstraintManagerCreator constraintmgr,
- CheckerManager *checkerMgr,
- AnalyzerOptions &Options,
- CodeInjector* injector = nullptr);
+ CheckerManager *checkerMgr, AnalyzerOptions &Options,
+ CodeInjector *injector = nullptr);
~AnalysisManager() override;
@@ -102,8 +100,7 @@ public:
void FlushDiagnostics();
bool shouldVisualize() const {
- return options.visualizeExplodedGraphWithGraphViz ||
- options.visualizeExplodedGraphWithUbiGraph;
+ return options.visualizeExplodedGraphWithGraphViz;
}
bool shouldInlineCall() const {
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h b/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
index b72b158194c7..1c5d4eb2de32 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
@@ -211,7 +211,8 @@ public:
}
const llvm::APSInt &getTruthValue(bool b, QualType T) {
- return getValue(b ? 1 : 0, Ctx.getIntWidth(T), true);
+ return getValue(b ? 1 : 0, Ctx.getIntWidth(T),
+ T->isUnsignedIntegerOrEnumerationType());
}
const llvm::APSInt &getTruthValue(bool b) {
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
index 9078fb94d282..81dd83fc1071 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
@@ -80,7 +80,9 @@ class CallDescription {
mutable IdentifierInfo *II = nullptr;
mutable bool IsLookupDone = false;
- StringRef FuncName;
+ // The list of the qualified names used to identify the specified CallEvent,
+ // e.g. "{a, b}" represent the qualified names, like "a::b".
+ std::vector<const char *> QualifiedName;
unsigned RequiredArgs;
public:
@@ -88,16 +90,20 @@ public:
/// Constructs a CallDescription object.
///
- /// @param FuncName The name of the function that will be matched.
+ /// @param QualifiedName The list of the name qualifiers of the function that
+ /// will be matched. The user is allowed to skip any of the qualifiers.
+ /// For example, {"std", "basic_string", "c_str"} would match both
+ /// std::basic_string<...>::c_str() and std::__1::basic_string<...>::c_str().
///
/// @param RequiredArgs The number of arguments that is expected to match a
/// call. Omit this parameter to match every occurrence of call with a given
/// name regardless the number of arguments.
- CallDescription(StringRef FuncName, unsigned RequiredArgs = NoArgRequirement)
- : FuncName(FuncName), RequiredArgs(RequiredArgs) {}
+ CallDescription(ArrayRef<const char *> QualifiedName,
+ unsigned RequiredArgs = NoArgRequirement)
+ : QualifiedName(QualifiedName), RequiredArgs(RequiredArgs) {}
/// Get the name of the function that this object matches.
- StringRef getFunctionName() const { return FuncName; }
+ StringRef getFunctionName() const { return QualifiedName.back(); }
};
template<typename T = CallEvent>
@@ -428,21 +434,23 @@ public:
bool isArgumentConstructedDirectly(unsigned Index) const {
// This assumes that the object was not yet removed from the state.
return ExprEngine::getObjectUnderConstruction(
- getState(), {getOriginExpr(), Index}, getCalleeStackFrame()).hasValue();
+ getState(), {getOriginExpr(), Index}, getLocationContext()).hasValue();
}
/// Some calls have parameter numbering mismatched from argument numbering.
/// This function converts an argument index to the corresponding
/// parameter index. Returns None is the argument doesn't correspond
/// to any parameter variable.
- Optional<unsigned> getAdjustedParameterIndex(unsigned ArgumentIndex) const {
- if (dyn_cast_or_null<CXXOperatorCallExpr>(getOriginExpr()) &&
- dyn_cast_or_null<CXXMethodDecl>(getDecl())) {
- // For member operator calls argument 0 on the expression corresponds
- // to implicit this-parameter on the declaration.
- return (ArgumentIndex > 0) ? Optional<unsigned>(ArgumentIndex - 1) : None;
- }
- return ArgumentIndex;
+ virtual Optional<unsigned>
+ getAdjustedParameterIndex(unsigned ASTArgumentIndex) const {
+ return ASTArgumentIndex;
+ }
+
+ /// Some call event sub-classes conveniently adjust mismatching AST indices
+ /// to match parameter indices. This function converts an argument index
+ /// as understood by CallEvent to the argument index as understood by the AST.
+ virtual unsigned getASTArgumentIndex(unsigned CallArgumentIndex) const {
+ return CallArgumentIndex;
}
// Iterator access to formal parameters and their types.
@@ -769,6 +777,20 @@ public:
static bool classof(const CallEvent *CA) {
return CA->getKind() == CE_CXXMemberOperator;
}
+
+ Optional<unsigned>
+ getAdjustedParameterIndex(unsigned ASTArgumentIndex) const override {
+ // For member operator calls argument 0 on the expression corresponds
+ // to implicit this-parameter on the declaration.
+ return (ASTArgumentIndex > 0) ? Optional<unsigned>(ASTArgumentIndex - 1)
+ : None;
+ }
+
+ unsigned getASTArgumentIndex(unsigned CallArgumentIndex) const override {
+ // For member operator calls argument 0 on the expression corresponds
+ // to implicit this-parameter on the declaration.
+ return CallArgumentIndex + 1;
+ }
};
/// Represents an implicit call to a C++ destructor.
@@ -793,7 +815,7 @@ protected:
ProgramStateRef St, const LocationContext *LCtx)
: CXXInstanceCall(DD, St, LCtx) {
Data = DtorDataTy(Target, IsBaseDestructor).getOpaqueValue();
- Location = Trigger->getLocEnd();
+ Location = Trigger->getEndLoc();
}
CXXDestructorCall(const CXXDestructorCall &Other) = default;
@@ -899,15 +921,30 @@ public:
return getOriginExpr()->getOperatorNew();
}
+ /// Number of non-placement arguments to the call. It is equal to 2 for
+ /// C++17 aligned operator new() calls that have alignment implicitly
+ /// passed as the second argument, and to 1 for other operator new() calls.
+ unsigned getNumImplicitArgs() const {
+ return getOriginExpr()->passAlignment() ? 2 : 1;
+ }
+
unsigned getNumArgs() const override {
- return getOriginExpr()->getNumPlacementArgs() + 1;
+ return getOriginExpr()->getNumPlacementArgs() + getNumImplicitArgs();
}
const Expr *getArgExpr(unsigned Index) const override {
// The first argument of an allocator call is the size of the allocation.
- if (Index == 0)
+ if (Index < getNumImplicitArgs())
return nullptr;
- return getOriginExpr()->getPlacementArg(Index - 1);
+ return getOriginExpr()->getPlacementArg(Index - getNumImplicitArgs());
+ }
+
+ /// Number of placement arguments to the operator new() call. For example,
+ /// standard std::nothrow operator new and standard placement new both have
+ /// 1 implicit argument (size) and 1 placement argument, while regular
+ /// operator new() has 1 implicit argument and 0 placement arguments.
+ const Expr *getPlacementArgExpr(unsigned Index) const {
+ return getOriginExpr()->getPlacementArg(Index);
}
Kind getKind() const override { return CE_CXXAllocator; }
@@ -1101,9 +1138,16 @@ class CallEventManager {
public:
CallEventManager(llvm::BumpPtrAllocator &alloc) : Alloc(alloc) {}
+ /// Gets an outside caller given a callee context.
CallEventRef<>
getCaller(const StackFrameContext *CalleeCtx, ProgramStateRef State);
+ /// Gets a call event for a function call, Objective-C method call,
+ /// or a 'new' call.
+ CallEventRef<>
+ getCall(const Stmt *S, ProgramStateRef State,
+ const LocationContext *LC);
+
CallEventRef<>
getSimpleCall(const CallExpr *E, ProgramStateRef State,
const LocationContext *LCtx);
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
index ce2b711a4a1b..6ee75b738465 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
@@ -21,52 +21,6 @@
namespace clang {
namespace ento {
- /// Declares an immutable map of type \p NameTy, suitable for placement into
- /// the ProgramState. This is implementing using llvm::ImmutableMap.
- ///
- /// \code
- /// State = State->set<Name>(K, V);
- /// const Value *V = State->get<Name>(K); // Returns NULL if not in the map.
- /// State = State->remove<Name>(K);
- /// NameTy Map = State->get<Name>();
- /// \endcode
- ///
- /// The macro should not be used inside namespaces, or for traits that must
- /// be accessible from more than one translation unit.
- #define REGISTER_MAP_WITH_PROGRAMSTATE(Name, Key, Value) \
- REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, \
- CLANG_ENTO_PROGRAMSTATE_MAP(Key, Value))
-
- /// Declares an immutable set of type \p NameTy, suitable for placement into
- /// the ProgramState. This is implementing using llvm::ImmutableSet.
- ///
- /// \code
- /// State = State->add<Name>(E);
- /// State = State->remove<Name>(E);
- /// bool Present = State->contains<Name>(E);
- /// NameTy Set = State->get<Name>();
- /// \endcode
- ///
- /// The macro should not be used inside namespaces, or for traits that must
- /// be accessible from more than one translation unit.
- #define REGISTER_SET_WITH_PROGRAMSTATE(Name, Elem) \
- REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, llvm::ImmutableSet<Elem>)
-
- /// Declares an immutable list of type \p NameTy, suitable for placement into
- /// the ProgramState. This is implementing using llvm::ImmutableList.
- ///
- /// \code
- /// State = State->add<Name>(E); // Adds to the /end/ of the list.
- /// bool Present = State->contains<Name>(E);
- /// NameTy List = State->get<Name>();
- /// \endcode
- ///
- /// The macro should not be used inside namespaces, or for traits that must
- /// be accessible from more than one translation unit.
- #define REGISTER_LIST_WITH_PROGRAMSTATE(Name, Elem) \
- REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, llvm::ImmutableList<Elem>)
-
-
class CheckerContext {
ExprEngine &Eng;
/// The current exploded(symbolic execution) graph node.
@@ -162,10 +116,6 @@ public:
return getSValBuilder().getSymbolManager();
}
- bool isObjCGCEnabled() const {
- return Eng.isObjCGCEnabled();
- }
-
ProgramStateManager &getStateManager() {
return Eng.getStateManager();
}
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h b/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h
index 2f8ead0746ca..b0d514dc2863 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h
@@ -36,10 +36,7 @@ using DynamicTypeMapImpl =
template <>
struct ProgramStateTrait<DynamicTypeMap>
: public ProgramStatePartialTrait<DynamicTypeMapImpl> {
- static void *GDMIndex() {
- static int index = 0;
- return &index;
- }
+ static void *GDMIndex();
};
/// Get dynamic type information for a region.
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
index 77e35398077c..6d498031bea0 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
@@ -93,6 +93,7 @@ public:
}
void print(raw_ostream &Out, const char *NL, const char *Sep,
+ const ASTContext &Context,
const LocationContext *WithLC = nullptr) const;
};
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
index 4e0c02e6d65b..bf460df278aa 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
@@ -210,10 +210,14 @@ public:
return const_cast<ExplodedNode*>(this)->getFirstPred();
}
- const ExplodedNode *getFirstSucc() const {
+ ExplodedNode *getFirstSucc() {
return succ_empty() ? nullptr : *(succ_begin());
}
+ const ExplodedNode *getFirstSucc() const {
+ return const_cast<ExplodedNode*>(this)->getFirstSucc();
+ }
+
// Iterators over successor and predecessor vertices.
using succ_iterator = ExplodedNode * const *;
using const_succ_iterator = const ExplodedNode * const *;
@@ -240,17 +244,14 @@ public:
return const_cast<ExplodedNode*>(this)->succ_end();
}
- // For debugging.
-
-public:
- class Auditor {
- public:
- virtual ~Auditor();
-
- virtual void AddEdge(ExplodedNode *Src, ExplodedNode *Dst) = 0;
- };
+ int64_t getID(ExplodedGraph *G) const;
- static void SetAuditor(Auditor* A);
+ /// The node is trivial if it has only one successor, only one predecessor,
+ /// it's predecessor has only one successor,
+ /// and its program state is the same as the program state of the previous
+ /// node.
+ /// Trivial nodes may be skipped while printing exploded graph.
+ bool isTrivial() const;
private:
void replaceSuccessor(ExplodedNode *node) { Succs.replaceNode(node); }
@@ -465,39 +466,40 @@ public:
// GraphTraits
namespace llvm {
-
- template<> struct GraphTraits<clang::ento::ExplodedNode*> {
+ template <> struct GraphTraits<clang::ento::ExplodedGraph *> {
+ using GraphTy = clang::ento::ExplodedGraph *;
using NodeRef = clang::ento::ExplodedNode *;
using ChildIteratorType = clang::ento::ExplodedNode::succ_iterator;
- using nodes_iterator = llvm::df_iterator<NodeRef>;
-
- static NodeRef getEntryNode(NodeRef N) { return N; }
-
- static ChildIteratorType child_begin(NodeRef N) { return N->succ_begin(); }
+ using nodes_iterator = llvm::df_iterator<GraphTy>;
- static ChildIteratorType child_end(NodeRef N) { return N->succ_end(); }
-
- static nodes_iterator nodes_begin(NodeRef N) { return df_begin(N); }
-
- static nodes_iterator nodes_end(NodeRef N) { return df_end(N); }
- };
-
- template<> struct GraphTraits<const clang::ento::ExplodedNode*> {
- using NodeRef = const clang::ento::ExplodedNode *;
- using ChildIteratorType = clang::ento::ExplodedNode::const_succ_iterator;
- using nodes_iterator = llvm::df_iterator<NodeRef>;
+ static NodeRef getEntryNode(const GraphTy G) {
+ return *G->roots_begin();
+ }
- static NodeRef getEntryNode(NodeRef N) { return N; }
+ static bool predecessorOfTrivial(NodeRef N) {
+ return N->succ_size() == 1 && N->getFirstSucc()->isTrivial();
+ }
- static ChildIteratorType child_begin(NodeRef N) { return N->succ_begin(); }
+ static ChildIteratorType child_begin(NodeRef N) {
+ if (predecessorOfTrivial(N))
+ return child_begin(*N->succ_begin());
+ return N->succ_begin();
+ }
- static ChildIteratorType child_end(NodeRef N) { return N->succ_end(); }
+ static ChildIteratorType child_end(NodeRef N) {
+ if (predecessorOfTrivial(N))
+ return child_end(N->getFirstSucc());
+ return N->succ_end();
+ }
- static nodes_iterator nodes_begin(NodeRef N) { return df_begin(N); }
+ static nodes_iterator nodes_begin(const GraphTy G) {
+ return df_begin(G);
+ }
- static nodes_iterator nodes_end(NodeRef N) { return df_end(N); }
+ static nodes_iterator nodes_end(const GraphTy G) {
+ return df_end(G);
+ }
};
-
} // namespace llvm
#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPLODEDGRAPH_H
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
index 06a90fa847a6..86b776afb822 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -141,9 +141,6 @@ private:
/// implicitly never returns.
ObjCNoReturn ObjCNoRet;
- /// Whether or not GC is enabled in this analysis.
- bool ObjCGCEnabled;
-
/// The BugReporter associated with this engine. It is important that
/// this object be placed at the very end of member variables so that its
/// destructor is called before the rest of the ExprEngine is destroyed.
@@ -158,7 +155,7 @@ private:
public:
ExprEngine(cross_tu::CrossTranslationUnitContext &CTU, AnalysisManager &mgr,
- bool gcEnabled, SetOfConstDecls *VisitedCalleesIn,
+ SetOfConstDecls *VisitedCalleesIn,
FunctionSummariesTy *FS, InliningModes HowToInlineIn);
~ExprEngine() override;
@@ -201,14 +198,24 @@ public:
return *currBldrCtx;
}
- bool isObjCGCEnabled() { return ObjCGCEnabled; }
-
const Stmt *getStmt() const;
void GenerateAutoTransition(ExplodedNode *N);
void enqueueEndOfPath(ExplodedNodeSet &S);
void GenerateCallExitNode(ExplodedNode *N);
+
+ /// Dump graph to the specified filename.
+ /// If filename is empty, generate a temporary one.
+ /// \return The filename the graph is written into.
+ std::string DumpGraph(bool trim = false, StringRef Filename="");
+
+ /// Dump the graph consisting of the given nodes to a specified filename.
+ /// Generate a temporary filename if it's not provided.
+ /// \return The filename the graph is written into.
+ std::string DumpGraph(ArrayRef<const ExplodedNode *> Nodes,
+ StringRef Filename = "");
+
/// Visualize the ExplodedGraph created by executing the simulation.
void ViewGraph(bool trim = false);
@@ -286,7 +293,7 @@ public:
/// ProcessBranch - Called by CoreEngine. Used to generate successor
/// nodes by processing the 'effects' of a branch condition.
- void processBranch(const Stmt *Condition, const Stmt *Term,
+ void processBranch(const Stmt *Condition,
NodeBuilderContext& BuilderCtx,
ExplodedNode *Pred,
ExplodedNodeSet &Dst,
@@ -345,7 +352,7 @@ public:
void processCallExit(ExplodedNode *Pred) override;
/// Called by CoreEngine when the analysis worklist has terminated.
- void processEndWorklist(bool hasWorkRemaining) override;
+ void processEndWorklist() override;
/// evalAssume - Callback function invoked by the ConstraintManager when
/// making assumptions about state values.
@@ -608,7 +615,6 @@ protected:
ProgramStateRef State,
const InvalidatedSymbols *Invalidated,
ArrayRef<const MemRegion *> ExplicitRegions,
- ArrayRef<const MemRegion *> Regions,
const CallEvent *Call,
RegionAndSymbolInvalidationTraits &ITraits) override;
@@ -662,6 +668,11 @@ public:
const EvalCallOptions &CallOpts = {});
private:
+ ProgramStateRef finishArgumentConstruction(ProgramStateRef State,
+ const CallEvent &Call);
+ void finishArgumentConstruction(ExplodedNodeSet &Dst, ExplodedNode *Pred,
+ const CallEvent &Call);
+
void evalLoadCommon(ExplodedNodeSet &Dst,
const Expr *NodeEx, /* Eventually will be a CFGStmt */
const Expr *BoundEx,
@@ -671,14 +682,13 @@ private:
const ProgramPointTag *tag,
QualType LoadTy);
- // FIXME: 'tag' should be removed, and a LocationContext should be used
- // instead.
void evalLocation(ExplodedNodeSet &Dst,
const Stmt *NodeEx, /* This will eventually be a CFGStmt */
const Stmt *BoundEx,
ExplodedNode *Pred,
- ProgramStateRef St, SVal location,
- const ProgramPointTag *tag, bool isLoad);
+ ProgramStateRef St,
+ SVal location,
+ bool isLoad);
/// Count the stack depth and determine if the call is recursive.
void examineStackFrames(const Decl *D, const LocationContext *LCtx,
@@ -729,10 +739,14 @@ private:
///
/// If \p Result is provided, the new region will be bound to this expression
/// instead of \p InitWithAdjustments.
- ProgramStateRef createTemporaryRegionIfNeeded(ProgramStateRef State,
- const LocationContext *LC,
- const Expr *InitWithAdjustments,
- const Expr *Result = nullptr);
+ ///
+ /// Returns the temporary region with adjustments into the optional
+ /// OutRegionWithAdjustments out-parameter if a new region was indeed needed,
+ /// otherwise sets it to nullptr.
+ ProgramStateRef createTemporaryRegionIfNeeded(
+ ProgramStateRef State, const LocationContext *LC,
+ const Expr *InitWithAdjustments, const Expr *Result = nullptr,
+ const SubRegion **OutRegionWithAdjustments = nullptr);
/// Returns a region representing the first element of a (possibly
/// multi-dimensional) array, for the purposes of element construction or
@@ -818,7 +832,7 @@ struct ReplayWithoutInlining{};
template <>
struct ProgramStateTrait<ReplayWithoutInlining> :
public ProgramStatePartialTrait<const void*> {
- static void *GDMIndex() { static int index = 0; return &index; }
+ static void *GDMIndex();
};
} // namespace ento
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
index 3a93aae5a9bc..3d0ff4efa1d7 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
@@ -24,6 +24,7 @@
#include "clang/AST/Expr.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/Type.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
@@ -118,11 +119,15 @@ public:
const MemRegion *getBaseRegion() const;
+ /// Recursively retrieve the region of the most derived class instance of
+ /// regions of C++ base class instances.
+ const MemRegion *getMostDerivedObjectRegion() const;
+
/// Check if the region is a subregion of the given region.
/// Each region is a subregion of itself.
virtual bool isSubRegionOf(const MemRegion *R) const;
- const MemRegion *StripCasts(bool StripBaseCasts = true) const;
+ const MemRegion *StripCasts(bool StripBaseAndDerivedCasts = true) const;
/// If this is a symbolic region, returns the region. Otherwise,
/// goes up the base chain looking for the first symbolic base region.
@@ -763,10 +768,15 @@ class SymbolicRegion : public SubRegion {
SymbolicRegion(const SymbolRef s, const MemSpaceRegion *sreg)
: SubRegion(sreg, SymbolicRegionKind), sym(s) {
- assert(s);
+ // Because pointer arithmetic is represented by ElementRegion layers,
+ // the base symbol here should not contain any arithmetic.
+ assert(s && isa<SymbolData>(s));
assert(s->getType()->isAnyPointerType() ||
s->getType()->isReferenceType() ||
s->getType()->isBlockPointerType());
+
+ // populateWorklistFromSymbol() relies on this assertion, and needs to be
+ // updated if more cases are introduced.
assert(isa<UnknownSpaceRegion>(sreg) || isa<HeapSpaceRegion>(sreg));
}
@@ -1072,7 +1082,7 @@ public:
void dump() const;
};
-/// ElementRegin is used to represent both array elements and casts.
+/// ElementRegion is used to represent both array elements and casts.
class ElementRegion : public TypedValueRegion {
friend class MemRegionManager;
@@ -1176,6 +1186,47 @@ public:
}
};
+// CXXDerivedObjectRegion represents a derived-class object that surrounds
+// a C++ object. It is identified by the derived class declaration and the
+// region of its parent object. It is a bit counter-intuitive (but not otherwise
+// unseen) that this region represents a larger segment of memory that its
+// super-region.
+class CXXDerivedObjectRegion : public TypedValueRegion {
+ friend class MemRegionManager;
+
+ const CXXRecordDecl *DerivedD;
+
+ CXXDerivedObjectRegion(const CXXRecordDecl *DerivedD, const SubRegion *SReg)
+ : TypedValueRegion(SReg, CXXDerivedObjectRegionKind), DerivedD(DerivedD) {
+ assert(DerivedD);
+ // In case of a concrete region, it should always be possible to model
+ // the base-to-derived cast by undoing a previous derived-to-base cast,
+ // otherwise the cast is most likely ill-formed.
+ assert(SReg->getSymbolicBase() &&
+ "Should have unwrapped a base region instead!");
+ }
+
+ static void ProfileRegion(llvm::FoldingSetNodeID &ID, const CXXRecordDecl *RD,
+ const MemRegion *SReg);
+
+public:
+ const CXXRecordDecl *getDecl() const { return DerivedD; }
+
+ QualType getValueType() const override;
+
+ void dumpToStream(raw_ostream &os) const override;
+
+ void Profile(llvm::FoldingSetNodeID &ID) const override;
+
+ bool canPrintPrettyAsExpr() const override;
+
+ void printPrettyAsExpr(raw_ostream &os) const override;
+
+ static bool classof(const MemRegion *region) {
+ return region->getKind() == CXXDerivedObjectRegionKind;
+ }
+};
+
template<typename RegionTy>
const RegionTy* MemRegion::getAs() const {
if (const auto *RT = dyn_cast<RegionTy>(this))
@@ -1326,6 +1377,14 @@ public:
baseReg->isVirtual());
}
+ /// Create a CXXDerivedObjectRegion with the given derived class for region
+ /// \p Super. This should not be used for casting an existing
+ /// CXXBaseObjectRegion back to the derived type; instead, CXXBaseObjectRegion
+ /// should be removed.
+ const CXXDerivedObjectRegion *
+ getCXXDerivedObjectRegion(const CXXRecordDecl *BaseClass,
+ const SubRegion *Super);
+
const FunctionCodeRegion *getFunctionCodeRegion(const NamedDecl *FD);
const BlockCodeRegion *getBlockCodeRegion(const BlockDecl *BD,
CanQualType locTy,
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
index b86301a03470..c3a7028d8755 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
@@ -107,6 +107,8 @@ public:
~ProgramState();
+ int64_t getID() const;
+
/// Return the ProgramStateManager associated with this state.
ProgramStateManager &getStateManager() const {
return *stateMgr;
@@ -346,6 +348,8 @@ public:
/// a value of such type.
SVal getSValAsScalarOrLoc(const MemRegion *R) const;
+ using region_iterator = const MemRegion **;
+
/// Visits the symbols reachable from the given SVal using the provided
/// SymbolVisitor.
///
@@ -355,24 +359,14 @@ public:
/// \sa ScanReachableSymbols
bool scanReachableSymbols(SVal val, SymbolVisitor& visitor) const;
- /// Visits the symbols reachable from the SVals in the given range
- /// using the provided SymbolVisitor.
- bool scanReachableSymbols(const SVal *I, const SVal *E,
- SymbolVisitor &visitor) const;
-
/// Visits the symbols reachable from the regions in the given
/// MemRegions range using the provided SymbolVisitor.
- bool scanReachableSymbols(const MemRegion * const *I,
- const MemRegion * const *E,
+ bool scanReachableSymbols(llvm::iterator_range<region_iterator> Reachable,
SymbolVisitor &visitor) const;
template <typename CB> CB scanReachableSymbols(SVal val) const;
- template <typename CB> CB scanReachableSymbols(const SVal *beg,
- const SVal *end) const;
-
template <typename CB> CB
- scanReachableSymbols(const MemRegion * const *beg,
- const MemRegion * const *end) const;
+ scanReachableSymbols(llvm::iterator_range<region_iterator> Reachable) const;
/// Create a new state in which the statement is marked as tainted.
LLVM_NODISCARD ProgramStateRef
@@ -469,8 +463,7 @@ public:
const LocationContext *CurrentLC = nullptr) const;
void printDOT(raw_ostream &Out,
const LocationContext *CurrentLC = nullptr) const;
- void printTaint(raw_ostream &Out, const char *nl = "\n",
- const char *sep = "") const;
+ void printTaint(raw_ostream &Out, const char *nl = "\n") const;
void dump() const;
void dumpTaint() const;
@@ -562,15 +555,15 @@ public:
MemRegionManager& getRegionManager() {
return svalBuilder->getRegionManager();
}
- const MemRegionManager& getRegionManager() const {
+ const MemRegionManager &getRegionManager() const {
return svalBuilder->getRegionManager();
}
CallEventManager &getCallEventManager() { return *CallEventMgr; }
- StoreManager& getStoreManager() { return *StoreMgr; }
- ConstraintManager& getConstraintManager() { return *ConstraintMgr; }
- SubEngine* getOwningEngine() { return Eng; }
+ StoreManager &getStoreManager() { return *StoreMgr; }
+ ConstraintManager &getConstraintManager() { return *ConstraintMgr; }
+ SubEngine &getOwningEngine() { return *Eng; }
ProgramStateRef removeDeadBindings(ProgramStateRef St,
const StackFrameContext *LCtx,
@@ -882,17 +875,10 @@ CB ProgramState::scanReachableSymbols(SVal val) const {
}
template <typename CB>
-CB ProgramState::scanReachableSymbols(const SVal *beg, const SVal *end) const {
- CB cb(this);
- scanReachableSymbols(beg, end, cb);
- return cb;
-}
-
-template <typename CB>
-CB ProgramState::scanReachableSymbols(const MemRegion * const *beg,
- const MemRegion * const *end) const {
+CB ProgramState::scanReachableSymbols(
+ llvm::iterator_range<region_iterator> Reachable) const {
CB cb(this);
- scanReachableSymbols(beg, end, cb);
+ scanReachableSymbols(Reachable, cb);
return cb;
}
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h
index 5555b292534c..64de736c7e9f 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h
@@ -30,8 +30,7 @@ namespace ento {
/// Declares a program state trait for type \p Type called \p Name, and
/// introduce a type named \c NameTy.
- /// The macro should not be used inside namespaces, or for traits that must
- /// be accessible from more than one translation unit.
+ /// The macro should not be used inside namespaces.
#define REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, Type) \
namespace { \
class Name {}; \
@@ -47,6 +46,102 @@ namespace ento {
} \
}
+ /// Declares a factory for objects of type \p Type in the program state
+ /// manager. The type must provide a ::Factory sub-class. Commonly used for
+ /// ImmutableMap, ImmutableSet, ImmutableList. The macro should not be used
+ /// inside namespaces.
+ #define REGISTER_FACTORY_WITH_PROGRAMSTATE(Type) \
+ namespace clang { \
+ namespace ento { \
+ template <> \
+ struct ProgramStateTrait<Type> \
+ : public ProgramStatePartialTrait<Type> { \
+ static void *GDMIndex() { static int Index; return &Index; } \
+ }; \
+ } \
+ }
+
+ /// Helper for registering a map trait.
+ ///
+ /// If the map type were written directly in the invocation of
+ /// REGISTER_TRAIT_WITH_PROGRAMSTATE, the comma in the template arguments
+ /// would be treated as a macro argument separator, which is wrong.
+ /// This allows the user to specify a map type in a way that the preprocessor
+ /// can deal with.
+ #define CLANG_ENTO_PROGRAMSTATE_MAP(Key, Value) llvm::ImmutableMap<Key, Value>
+
+ /// Declares an immutable map of type \p NameTy, suitable for placement into
+ /// the ProgramState. This is implementing using llvm::ImmutableMap.
+ ///
+ /// \code
+ /// State = State->set<Name>(K, V);
+ /// const Value *V = State->get<Name>(K); // Returns NULL if not in the map.
+ /// State = State->remove<Name>(K);
+ /// NameTy Map = State->get<Name>();
+ /// \endcode
+ ///
+ /// The macro should not be used inside namespaces, or for traits that must
+ /// be accessible from more than one translation unit.
+ #define REGISTER_MAP_WITH_PROGRAMSTATE(Name, Key, Value) \
+ REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, \
+ CLANG_ENTO_PROGRAMSTATE_MAP(Key, Value))
+
+ /// Declares an immutable map type \p Name and registers the factory
+ /// for such maps in the program state, but does not add the map itself
+ /// to the program state. Useful for managing lifetime of maps that are used
+ /// as elements of other program state data structures.
+ #define REGISTER_MAP_FACTORY_WITH_PROGRAMSTATE(Name, Key, Value) \
+ using Name = llvm::ImmutableMap<Key, Value>; \
+ REGISTER_FACTORY_WITH_PROGRAMSTATE(Name)
+
+
+ /// Declares an immutable set of type \p NameTy, suitable for placement into
+ /// the ProgramState. This is implementing using llvm::ImmutableSet.
+ ///
+ /// \code
+ /// State = State->add<Name>(E);
+ /// State = State->remove<Name>(E);
+ /// bool Present = State->contains<Name>(E);
+ /// NameTy Set = State->get<Name>();
+ /// \endcode
+ ///
+ /// The macro should not be used inside namespaces, or for traits that must
+ /// be accessible from more than one translation unit.
+ #define REGISTER_SET_WITH_PROGRAMSTATE(Name, Elem) \
+ REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, llvm::ImmutableSet<Elem>)
+
+ /// Declares an immutable set type \p Name and registers the factory
+ /// for such sets in the program state, but does not add the set itself
+ /// to the program state. Useful for managing lifetime of sets that are used
+ /// as elements of other program state data structures.
+ #define REGISTER_SET_FACTORY_WITH_PROGRAMSTATE(Name, Elem) \
+ using Name = llvm::ImmutableSet<Elem>; \
+ REGISTER_FACTORY_WITH_PROGRAMSTATE(Name)
+
+
+ /// Declares an immutable list type \p NameTy, suitable for placement into
+ /// the ProgramState. This is implementing using llvm::ImmutableList.
+ ///
+ /// \code
+ /// State = State->add<Name>(E); // Adds to the /end/ of the list.
+ /// bool Present = State->contains<Name>(E);
+ /// NameTy List = State->get<Name>();
+ /// \endcode
+ ///
+ /// The macro should not be used inside namespaces, or for traits that must
+ /// be accessible from more than one translation unit.
+ #define REGISTER_LIST_WITH_PROGRAMSTATE(Name, Elem) \
+ REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, llvm::ImmutableList<Elem>)
+
+ /// Declares an immutable list of type \p Name and registers the factory
+ /// for such lists in the program state, but does not add the list itself
+ /// to the program state. Useful for managing lifetime of lists that are used
+ /// as elements of other program state data structures.
+ #define REGISTER_LIST_FACTORY_WITH_PROGRAMSTATE(Name, Elem) \
+ using Name = llvm::ImmutableList<Elem>; \
+ REGISTER_FACTORY_WITH_PROGRAMSTATE(Name)
+
+
// Partial-specialization for ImmutableMap.
template <typename Key, typename Data, typename Info>
struct ProgramStatePartialTrait<llvm::ImmutableMap<Key, Data, Info>> {
@@ -95,15 +190,6 @@ namespace ento {
}
};
- /// Helper for registering a map trait.
- ///
- /// If the map type were written directly in the invocation of
- /// REGISTER_TRAIT_WITH_PROGRAMSTATE, the comma in the template arguments
- /// would be treated as a macro argument separator, which is wrong.
- /// This allows the user to specify a map type in a way that the preprocessor
- /// can deal with.
- #define CLANG_ENTO_PROGRAMSTATE_MAP(Key, Value) llvm::ImmutableMap<Key, Value>
-
// Partial-specialization for ImmutableSet.
template <typename Key, typename Info>
struct ProgramStatePartialTrait<llvm::ImmutableSet<Key, Info>> {
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h
index d2ba1f7c9529..1b12a4edc205 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h
@@ -131,7 +131,7 @@ using ConstraintRangeTy = llvm::ImmutableMap<SymbolRef, RangeSet>;
template <>
struct ProgramStateTrait<ConstraintRange>
: public ProgramStatePartialTrait<ConstraintRangeTy> {
- static void *GDMIndex() { static int Index; return &Index; }
+ static void *GDMIndex();
};
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Regions.def b/include/clang/StaticAnalyzer/Core/PathSensitive/Regions.def
index c84a1ff13f8b..10f89ecc55a5 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/Regions.def
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Regions.def
@@ -68,6 +68,7 @@ ABSTRACT_REGION(SubRegion, MemRegion)
ABSTRACT_REGION(TypedValueRegion, TypedRegion)
REGION(CompoundLiteralRegion, TypedValueRegion)
REGION(CXXBaseObjectRegion, TypedValueRegion)
+ REGION(CXXDerivedObjectRegion, TypedValueRegion)
REGION(CXXTempObjectRegion, TypedValueRegion)
REGION(CXXThisRegion, TypedValueRegion)
ABSTRACT_REGION(DeclRegion, TypedValueRegion)
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h
index 19d3d5973e0f..8eaa9365be1d 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h
@@ -16,11 +16,12 @@
#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SMTCONSTRAINTMANAGER_H
#include "clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/SMTSolver.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h"
namespace clang {
namespace ento {
+template <typename ConstraintSMT, typename SMTExprTy>
class SMTConstraintManager : public clang::ento::SimpleConstraintManager {
SMTSolverRef &Solver;
@@ -34,25 +35,234 @@ public:
// Implementation for interface from SimpleConstraintManager.
//===------------------------------------------------------------------===//
- ProgramStateRef assumeSym(ProgramStateRef state, SymbolRef Sym,
- bool Assumption) override;
+ ProgramStateRef assumeSym(ProgramStateRef State, SymbolRef Sym,
+ bool Assumption) override {
+ ASTContext &Ctx = getBasicVals().getContext();
+
+ QualType RetTy;
+ bool hasComparison;
+
+ SMTExprRef Exp = SMTConv::getExpr(Solver, Ctx, Sym, &RetTy, &hasComparison);
+
+ // Create zero comparison for implicit boolean cast, with reversed
+ // assumption
+ if (!hasComparison && !RetTy->isBooleanType())
+ return assumeExpr(
+ State, Sym,
+ SMTConv::getZeroExpr(Solver, Ctx, Exp, RetTy, !Assumption));
+
+ return assumeExpr(State, Sym, Assumption ? Exp : Solver->mkNot(Exp));
+ }
ProgramStateRef assumeSymInclusiveRange(ProgramStateRef State, SymbolRef Sym,
const llvm::APSInt &From,
const llvm::APSInt &To,
- bool InRange) override;
+ bool InRange) override {
+ ASTContext &Ctx = getBasicVals().getContext();
+ return assumeExpr(
+ State, Sym, SMTConv::getRangeExpr(Solver, Ctx, Sym, From, To, InRange));
+ }
ProgramStateRef assumeSymUnsupported(ProgramStateRef State, SymbolRef Sym,
- bool Assumption) override;
+ bool Assumption) override {
+ // Skip anything that is unsupported
+ return State;
+ }
//===------------------------------------------------------------------===//
// Implementation for interface from ConstraintManager.
//===------------------------------------------------------------------===//
- ConditionTruthVal checkNull(ProgramStateRef State, SymbolRef Sym) override;
+ ConditionTruthVal checkNull(ProgramStateRef State, SymbolRef Sym) override {
+ ASTContext &Ctx = getBasicVals().getContext();
+
+ QualType RetTy;
+ // The expression may be casted, so we cannot call getZ3DataExpr() directly
+ SMTExprRef VarExp = SMTConv::getExpr(Solver, Ctx, Sym, &RetTy);
+ SMTExprRef Exp =
+ SMTConv::getZeroExpr(Solver, Ctx, VarExp, RetTy, /*Assumption=*/true);
+
+ // Negate the constraint
+ SMTExprRef NotExp =
+ SMTConv::getZeroExpr(Solver, Ctx, VarExp, RetTy, /*Assumption=*/false);
+
+ ConditionTruthVal isSat = checkModel(State, Sym, Exp);
+ ConditionTruthVal isNotSat = checkModel(State, Sym, NotExp);
+
+ // Zero is the only possible solution
+ if (isSat.isConstrainedTrue() && isNotSat.isConstrainedFalse())
+ return true;
+
+ // Zero is not a solution
+ if (isSat.isConstrainedFalse() && isNotSat.isConstrainedTrue())
+ return false;
+
+ // Zero may be a solution
+ return ConditionTruthVal();
+ }
const llvm::APSInt *getSymVal(ProgramStateRef State,
- SymbolRef Sym) const override;
+ SymbolRef Sym) const override {
+ BasicValueFactory &BVF = getBasicVals();
+ ASTContext &Ctx = BVF.getContext();
+
+ if (const SymbolData *SD = dyn_cast<SymbolData>(Sym)) {
+ QualType Ty = Sym->getType();
+ assert(!Ty->isRealFloatingType());
+ llvm::APSInt Value(Ctx.getTypeSize(Ty),
+ !Ty->isSignedIntegerOrEnumerationType());
+
+ // TODO: this should call checkModel so we can use the cache, however,
+ // this method tries to get the interpretation (the actual value) from
+ // the solver, which is currently not cached.
+
+ SMTExprRef Exp =
+ SMTConv::fromData(Solver, SD->getSymbolID(), Ty, Ctx.getTypeSize(Ty));
+
+ Solver->reset();
+ addStateConstraints(State);
+
+ // Constraints are unsatisfiable
+ Optional<bool> isSat = Solver->check();
+ if (!isSat.hasValue() || !isSat.getValue())
+ return nullptr;
+
+ // Model does not assign interpretation
+ if (!Solver->getInterpretation(Exp, Value))
+ return nullptr;
+
+ // A value has been obtained, check if it is the only value
+ SMTExprRef NotExp = SMTConv::fromBinOp(
+ Solver, Exp, BO_NE,
+ Ty->isBooleanType() ? Solver->mkBoolean(Value.getBoolValue())
+ : Solver->mkBitvector(Value, Value.getBitWidth()),
+ /*isSigned=*/false);
+
+ Solver->addConstraint(NotExp);
+
+ Optional<bool> isNotSat = Solver->check();
+ if (!isSat.hasValue() || isNotSat.getValue())
+ return nullptr;
+
+ // This is the only solution, store it
+ return &BVF.getValue(Value);
+ }
+
+ if (const SymbolCast *SC = dyn_cast<SymbolCast>(Sym)) {
+ SymbolRef CastSym = SC->getOperand();
+ QualType CastTy = SC->getType();
+ // Skip the void type
+ if (CastTy->isVoidType())
+ return nullptr;
+
+ const llvm::APSInt *Value;
+ if (!(Value = getSymVal(State, CastSym)))
+ return nullptr;
+ return &BVF.Convert(SC->getType(), *Value);
+ }
+
+ if (const BinarySymExpr *BSE = dyn_cast<BinarySymExpr>(Sym)) {
+ const llvm::APSInt *LHS, *RHS;
+ if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(BSE)) {
+ LHS = getSymVal(State, SIE->getLHS());
+ RHS = &SIE->getRHS();
+ } else if (const IntSymExpr *ISE = dyn_cast<IntSymExpr>(BSE)) {
+ LHS = &ISE->getLHS();
+ RHS = getSymVal(State, ISE->getRHS());
+ } else if (const SymSymExpr *SSM = dyn_cast<SymSymExpr>(BSE)) {
+ // Early termination to avoid expensive call
+ LHS = getSymVal(State, SSM->getLHS());
+ RHS = LHS ? getSymVal(State, SSM->getRHS()) : nullptr;
+ } else {
+ llvm_unreachable("Unsupported binary expression to get symbol value!");
+ }
+
+ if (!LHS || !RHS)
+ return nullptr;
+
+ llvm::APSInt ConvertedLHS, ConvertedRHS;
+ QualType LTy, RTy;
+ std::tie(ConvertedLHS, LTy) = SMTConv::fixAPSInt(Ctx, *LHS);
+ std::tie(ConvertedRHS, RTy) = SMTConv::fixAPSInt(Ctx, *RHS);
+ SMTConv::doIntTypeConversion<llvm::APSInt, &SMTConv::castAPSInt>(
+ Solver, Ctx, ConvertedLHS, LTy, ConvertedRHS, RTy);
+ return BVF.evalAPSInt(BSE->getOpcode(), ConvertedLHS, ConvertedRHS);
+ }
+
+ llvm_unreachable("Unsupported expression to get symbol value!");
+ }
+
+ ProgramStateRef removeDeadBindings(ProgramStateRef State,
+ SymbolReaper &SymReaper) override {
+ auto CZ = State->get<ConstraintSMT>();
+ auto &CZFactory = State->get_context<ConstraintSMT>();
+
+ for (auto I = CZ.begin(), E = CZ.end(); I != E; ++I) {
+ if (SymReaper.isDead(I->first))
+ CZ = CZFactory.remove(CZ, *I);
+ }
+
+ return State->set<ConstraintSMT>(CZ);
+ }
+
+ void print(ProgramStateRef St, raw_ostream &OS, const char *nl,
+ const char *sep) override {
+
+ auto CZ = St->get<ConstraintSMT>();
+
+ OS << nl << sep << "Constraints:";
+ for (auto I = CZ.begin(), E = CZ.end(); I != E; ++I) {
+ OS << nl << ' ' << I->first << " : ";
+ I->second.print(OS);
+ }
+ OS << nl;
+ }
+
+ bool canReasonAbout(SVal X) const override {
+ const TargetInfo &TI = getBasicVals().getContext().getTargetInfo();
+
+ Optional<nonloc::SymbolVal> SymVal = X.getAs<nonloc::SymbolVal>();
+ if (!SymVal)
+ return true;
+
+ const SymExpr *Sym = SymVal->getSymbol();
+ QualType Ty = Sym->getType();
+
+ // Complex types are not modeled
+ if (Ty->isComplexType() || Ty->isComplexIntegerType())
+ return false;
+
+ // Non-IEEE 754 floating-point types are not modeled
+ if ((Ty->isSpecificBuiltinType(BuiltinType::LongDouble) &&
+ (&TI.getLongDoubleFormat() == &llvm::APFloat::x87DoubleExtended() ||
+ &TI.getLongDoubleFormat() == &llvm::APFloat::PPCDoubleDouble())))
+ return false;
+
+ if (Ty->isRealFloatingType())
+ return Solver->isFPSupported();
+
+ if (isa<SymbolData>(Sym))
+ return true;
+
+ SValBuilder &SVB = getSValBuilder();
+
+ if (const SymbolCast *SC = dyn_cast<SymbolCast>(Sym))
+ return canReasonAbout(SVB.makeSymbolVal(SC->getOperand()));
+
+ if (const BinarySymExpr *BSE = dyn_cast<BinarySymExpr>(Sym)) {
+ if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(BSE))
+ return canReasonAbout(SVB.makeSymbolVal(SIE->getLHS()));
+
+ if (const IntSymExpr *ISE = dyn_cast<IntSymExpr>(BSE))
+ return canReasonAbout(SVB.makeSymbolVal(ISE->getRHS()));
+
+ if (const SymSymExpr *SSE = dyn_cast<SymSymExpr>(BSE))
+ return canReasonAbout(SVB.makeSymbolVal(SSE->getLHS())) &&
+ canReasonAbout(SVB.makeSymbolVal(SSE->getRHS()));
+ }
+
+ llvm_unreachable("Unsupported expression to reason about!");
+ }
/// Dumps SMT formula
LLVM_DUMP_METHOD void dump() const { Solver->dump(); }
@@ -60,15 +270,64 @@ public:
protected:
// Check whether a new model is satisfiable, and update the program state.
virtual ProgramStateRef assumeExpr(ProgramStateRef State, SymbolRef Sym,
- const SMTExprRef &Exp) = 0;
+ const SMTExprRef &Exp) {
+ // Check the model, avoid simplifying AST to save time
+ if (checkModel(State, Sym, Exp).isConstrainedTrue())
+ return State->add<ConstraintSMT>(
+ std::make_pair(Sym, static_cast<const SMTExprTy &>(*Exp)));
+
+ return nullptr;
+ }
/// Given a program state, construct the logical conjunction and add it to
/// the solver
- virtual void addStateConstraints(ProgramStateRef State) const = 0;
+ virtual void addStateConstraints(ProgramStateRef State) const {
+ // TODO: Don't add all the constraints, only the relevant ones
+ auto CZ = State->get<ConstraintSMT>();
+ auto I = CZ.begin(), IE = CZ.end();
+
+ // Construct the logical AND of all the constraints
+ if (I != IE) {
+ std::vector<SMTExprRef> ASTs;
+
+ SMTExprRef Constraint = Solver->newExprRef(I++->second);
+ while (I != IE) {
+ Constraint = Solver->mkAnd(Constraint, Solver->newExprRef(I++->second));
+ }
+
+ Solver->addConstraint(Constraint);
+ }
+ }
// Generate and check a Z3 model, using the given constraint.
- ConditionTruthVal checkModel(ProgramStateRef State,
- const SMTExprRef &Exp) const;
+ ConditionTruthVal checkModel(ProgramStateRef State, SymbolRef Sym,
+ const SMTExprRef &Exp) const {
+ ProgramStateRef NewState = State->add<ConstraintSMT>(
+ std::make_pair(Sym, static_cast<const SMTExprTy &>(*Exp)));
+
+ llvm::FoldingSetNodeID ID;
+ NewState->get<ConstraintSMT>().Profile(ID);
+
+ unsigned hash = ID.ComputeHash();
+ auto I = Cached.find(hash);
+ if (I != Cached.end())
+ return I->second;
+
+ Solver->reset();
+ addStateConstraints(NewState);
+
+ Optional<bool> res = Solver->check();
+ if (!res.hasValue())
+ Cached[hash] = ConditionTruthVal();
+ else
+ Cached[hash] = ConditionTruthVal(res.getValue());
+
+ return Cached[hash];
+ }
+
+ // Cache the result of an SMT query (true, false, unknown). The key is the
+ // hash of the constraints in a state
+ mutable llvm::DenseMap<unsigned, ConditionTruthVal> Cached;
}; // end class SMTConstraintManager
} // namespace ento
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SMTContext.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SMTContext.h
deleted file mode 100644
index 45c9df4ef401..000000000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SMTContext.h
+++ /dev/null
@@ -1,31 +0,0 @@
-//== SMTContext.h -----------------------------------------------*- C++ -*--==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines a SMT generic Context API, which will be the base class
-// for every SMT solver context specific class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SMTCONTEXT_H
-#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SMTCONTEXT_H
-
-namespace clang {
-namespace ento {
-
-/// Generic base class for SMT contexts
-class SMTContext {
-public:
- SMTContext() = default;
- virtual ~SMTContext() = default;
-};
-
-} // namespace ento
-} // namespace clang
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h
new file mode 100644
index 000000000000..cdca2a09700d
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h
@@ -0,0 +1,753 @@
+//== SMTConv.h --------------------------------------------------*- C++ -*--==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a set of functions to create SMT expressions
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SMTCONV_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SMTCONV_H
+
+#include "clang/AST/Expr.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SMTSolver.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
+
+namespace clang {
+namespace ento {
+
+class SMTConv {
+public:
+ // Returns an appropriate sort, given a QualType and it's bit width.
+ static inline SMTSortRef mkSort(SMTSolverRef &Solver, const QualType &Ty,
+ unsigned BitWidth) {
+ if (Ty->isBooleanType())
+ return Solver->getBoolSort();
+
+ if (Ty->isRealFloatingType())
+ return Solver->getFloatSort(BitWidth);
+
+ return Solver->getBitvectorSort(BitWidth);
+ }
+
+ /// Constructs an SMTExprRef from an unary operator.
+ static inline SMTExprRef fromUnOp(SMTSolverRef &Solver,
+ const UnaryOperator::Opcode Op,
+ const SMTExprRef &Exp) {
+ switch (Op) {
+ case UO_Minus:
+ return Solver->mkBVNeg(Exp);
+
+ case UO_Not:
+ return Solver->mkBVNot(Exp);
+
+ case UO_LNot:
+ return Solver->mkNot(Exp);
+
+ default:;
+ }
+ llvm_unreachable("Unimplemented opcode");
+ }
+
+ /// Constructs an SMTExprRef from a floating-point unary operator.
+ static inline SMTExprRef fromFloatUnOp(SMTSolverRef &Solver,
+ const UnaryOperator::Opcode Op,
+ const SMTExprRef &Exp) {
+ switch (Op) {
+ case UO_Minus:
+ return Solver->mkFPNeg(Exp);
+
+ case UO_LNot:
+ return fromUnOp(Solver, Op, Exp);
+
+ default:;
+ }
+ llvm_unreachable("Unimplemented opcode");
+ }
+
+ /// Construct an SMTExprRef from a n-ary binary operator.
+ static inline SMTExprRef fromNBinOp(SMTSolverRef &Solver,
+ const BinaryOperator::Opcode Op,
+ const std::vector<SMTExprRef> &ASTs) {
+ assert(!ASTs.empty());
+
+ if (Op != BO_LAnd && Op != BO_LOr)
+ llvm_unreachable("Unimplemented opcode");
+
+ SMTExprRef res = ASTs.front();
+ for (std::size_t i = 1; i < ASTs.size(); ++i)
+ res = (Op == BO_LAnd) ? Solver->mkAnd(res, ASTs[i])
+ : Solver->mkOr(res, ASTs[i]);
+ return res;
+ }
+
+ /// Construct an SMTExprRef from a binary operator.
+ static inline SMTExprRef fromBinOp(SMTSolverRef &Solver,
+ const SMTExprRef &LHS,
+ const BinaryOperator::Opcode Op,
+ const SMTExprRef &RHS, bool isSigned) {
+ assert(*Solver->getSort(LHS) == *Solver->getSort(RHS) &&
+ "AST's must have the same sort!");
+
+ switch (Op) {
+ // Multiplicative operators
+ case BO_Mul:
+ return Solver->mkBVMul(LHS, RHS);
+
+ case BO_Div:
+ return isSigned ? Solver->mkBVSDiv(LHS, RHS) : Solver->mkBVUDiv(LHS, RHS);
+
+ case BO_Rem:
+ return isSigned ? Solver->mkBVSRem(LHS, RHS) : Solver->mkBVURem(LHS, RHS);
+
+ // Additive operators
+ case BO_Add:
+ return Solver->mkBVAdd(LHS, RHS);
+
+ case BO_Sub:
+ return Solver->mkBVSub(LHS, RHS);
+
+ // Bitwise shift operators
+ case BO_Shl:
+ return Solver->mkBVShl(LHS, RHS);
+
+ case BO_Shr:
+ return isSigned ? Solver->mkBVAshr(LHS, RHS) : Solver->mkBVLshr(LHS, RHS);
+
+ // Relational operators
+ case BO_LT:
+ return isSigned ? Solver->mkBVSlt(LHS, RHS) : Solver->mkBVUlt(LHS, RHS);
+
+ case BO_GT:
+ return isSigned ? Solver->mkBVSgt(LHS, RHS) : Solver->mkBVUgt(LHS, RHS);
+
+ case BO_LE:
+ return isSigned ? Solver->mkBVSle(LHS, RHS) : Solver->mkBVUle(LHS, RHS);
+
+ case BO_GE:
+ return isSigned ? Solver->mkBVSge(LHS, RHS) : Solver->mkBVUge(LHS, RHS);
+
+ // Equality operators
+ case BO_EQ:
+ return Solver->mkEqual(LHS, RHS);
+
+ case BO_NE:
+ return fromUnOp(Solver, UO_LNot,
+ fromBinOp(Solver, LHS, BO_EQ, RHS, isSigned));
+
+ // Bitwise operators
+ case BO_And:
+ return Solver->mkBVAnd(LHS, RHS);
+
+ case BO_Xor:
+ return Solver->mkBVXor(LHS, RHS);
+
+ case BO_Or:
+ return Solver->mkBVOr(LHS, RHS);
+
+ // Logical operators
+ case BO_LAnd:
+ return Solver->mkAnd(LHS, RHS);
+
+ case BO_LOr:
+ return Solver->mkOr(LHS, RHS);
+
+ default:;
+ }
+ llvm_unreachable("Unimplemented opcode");
+ }
+
+ /// Construct an SMTExprRef from a special floating-point binary operator.
+ static inline SMTExprRef
+ fromFloatSpecialBinOp(SMTSolverRef &Solver, const SMTExprRef &LHS,
+ const BinaryOperator::Opcode Op,
+ const llvm::APFloat::fltCategory &RHS) {
+ switch (Op) {
+ // Equality operators
+ case BO_EQ:
+ switch (RHS) {
+ case llvm::APFloat::fcInfinity:
+ return Solver->mkFPIsInfinite(LHS);
+
+ case llvm::APFloat::fcNaN:
+ return Solver->mkFPIsNaN(LHS);
+
+ case llvm::APFloat::fcNormal:
+ return Solver->mkFPIsNormal(LHS);
+
+ case llvm::APFloat::fcZero:
+ return Solver->mkFPIsZero(LHS);
+ }
+ break;
+
+ case BO_NE:
+ return fromFloatUnOp(Solver, UO_LNot,
+ fromFloatSpecialBinOp(Solver, LHS, BO_EQ, RHS));
+
+ default:;
+ }
+
+ llvm_unreachable("Unimplemented opcode");
+ }
+
+ /// Construct an SMTExprRef from a floating-point binary operator.
+ static inline SMTExprRef fromFloatBinOp(SMTSolverRef &Solver,
+ const SMTExprRef &LHS,
+ const BinaryOperator::Opcode Op,
+ const SMTExprRef &RHS) {
+ assert(*Solver->getSort(LHS) == *Solver->getSort(RHS) &&
+ "AST's must have the same sort!");
+
+ switch (Op) {
+ // Multiplicative operators
+ case BO_Mul:
+ return Solver->mkFPMul(LHS, RHS);
+
+ case BO_Div:
+ return Solver->mkFPDiv(LHS, RHS);
+
+ case BO_Rem:
+ return Solver->mkFPRem(LHS, RHS);
+
+ // Additive operators
+ case BO_Add:
+ return Solver->mkFPAdd(LHS, RHS);
+
+ case BO_Sub:
+ return Solver->mkFPSub(LHS, RHS);
+
+ // Relational operators
+ case BO_LT:
+ return Solver->mkFPLt(LHS, RHS);
+
+ case BO_GT:
+ return Solver->mkFPGt(LHS, RHS);
+
+ case BO_LE:
+ return Solver->mkFPLe(LHS, RHS);
+
+ case BO_GE:
+ return Solver->mkFPGe(LHS, RHS);
+
+ // Equality operators
+ case BO_EQ:
+ return Solver->mkFPEqual(LHS, RHS);
+
+ case BO_NE:
+ return fromFloatUnOp(Solver, UO_LNot,
+ fromFloatBinOp(Solver, LHS, BO_EQ, RHS));
+
+ // Logical operators
+ case BO_LAnd:
+ case BO_LOr:
+ return fromBinOp(Solver, LHS, Op, RHS, /*isSigned=*/false);
+
+ default:;
+ }
+
+ llvm_unreachable("Unimplemented opcode");
+ }
+
+ /// Construct an SMTExprRef from a QualType FromTy to a QualType ToTy, and
+ /// their bit widths.
+ static inline SMTExprRef fromCast(SMTSolverRef &Solver, const SMTExprRef &Exp,
+ QualType ToTy, uint64_t ToBitWidth,
+ QualType FromTy, uint64_t FromBitWidth) {
+ if ((FromTy->isIntegralOrEnumerationType() &&
+ ToTy->isIntegralOrEnumerationType()) ||
+ (FromTy->isAnyPointerType() ^ ToTy->isAnyPointerType()) ||
+ (FromTy->isBlockPointerType() ^ ToTy->isBlockPointerType()) ||
+ (FromTy->isReferenceType() ^ ToTy->isReferenceType())) {
+
+ if (FromTy->isBooleanType()) {
+ assert(ToBitWidth > 0 && "BitWidth must be positive!");
+ return Solver->mkIte(
+ Exp, Solver->mkBitvector(llvm::APSInt("1"), ToBitWidth),
+ Solver->mkBitvector(llvm::APSInt("0"), ToBitWidth));
+ }
+
+ if (ToBitWidth > FromBitWidth)
+ return FromTy->isSignedIntegerOrEnumerationType()
+ ? Solver->mkBVSignExt(ToBitWidth - FromBitWidth, Exp)
+ : Solver->mkBVZeroExt(ToBitWidth - FromBitWidth, Exp);
+
+ if (ToBitWidth < FromBitWidth)
+ return Solver->mkBVExtract(ToBitWidth - 1, 0, Exp);
+
+ // Both are bitvectors with the same width, ignore the type cast
+ return Exp;
+ }
+
+ if (FromTy->isRealFloatingType() && ToTy->isRealFloatingType()) {
+ if (ToBitWidth != FromBitWidth)
+ return Solver->mkFPtoFP(Exp, Solver->getFloatSort(ToBitWidth));
+
+ return Exp;
+ }
+
+ if (FromTy->isIntegralOrEnumerationType() && ToTy->isRealFloatingType()) {
+ SMTSortRef Sort = Solver->getFloatSort(ToBitWidth);
+ return FromTy->isSignedIntegerOrEnumerationType()
+ ? Solver->mkSBVtoFP(Exp, Sort)
+ : Solver->mkUBVtoFP(Exp, Sort);
+ }
+
+ if (FromTy->isRealFloatingType() && ToTy->isIntegralOrEnumerationType())
+ return ToTy->isSignedIntegerOrEnumerationType()
+ ? Solver->mkFPtoSBV(Exp, ToBitWidth)
+ : Solver->mkFPtoUBV(Exp, ToBitWidth);
+
+ llvm_unreachable("Unsupported explicit type cast!");
+ }
+
+ // Callback function for doCast parameter on APSInt type.
+ static inline llvm::APSInt castAPSInt(SMTSolverRef &Solver,
+ const llvm::APSInt &V, QualType ToTy,
+ uint64_t ToWidth, QualType FromTy,
+ uint64_t FromWidth) {
+ APSIntType TargetType(ToWidth, !ToTy->isSignedIntegerOrEnumerationType());
+ return TargetType.convert(V);
+ }
+
+ /// Construct an SMTExprRef from a SymbolData.
+ static inline SMTExprRef fromData(SMTSolverRef &Solver, const SymbolID ID,
+ const QualType &Ty, uint64_t BitWidth) {
+ llvm::Twine Name = "$" + llvm::Twine(ID);
+ return Solver->mkSymbol(Name.str().c_str(), mkSort(Solver, Ty, BitWidth));
+ }
+
+ // Wrapper to generate SMTExprRef from SymbolCast data.
+ static inline SMTExprRef getCastExpr(SMTSolverRef &Solver, ASTContext &Ctx,
+ const SMTExprRef &Exp, QualType FromTy,
+ QualType ToTy) {
+ return fromCast(Solver, Exp, ToTy, Ctx.getTypeSize(ToTy), FromTy,
+ Ctx.getTypeSize(FromTy));
+ }
+
+ // Wrapper to generate SMTExprRef from unpacked binary symbolic expression.
+ // Sets the RetTy parameter. See getSMTExprRef().
+ static inline SMTExprRef getBinExpr(SMTSolverRef &Solver, ASTContext &Ctx,
+ const SMTExprRef &LHS, QualType LTy,
+ BinaryOperator::Opcode Op,
+ const SMTExprRef &RHS, QualType RTy,
+ QualType *RetTy) {
+ SMTExprRef NewLHS = LHS;
+ SMTExprRef NewRHS = RHS;
+ doTypeConversion(Solver, Ctx, NewLHS, NewRHS, LTy, RTy);
+
+ // Update the return type parameter if the output type has changed.
+ if (RetTy) {
+ // A boolean result can be represented as an integer type in C/C++, but at
+ // this point we only care about the SMT sorts. Set it as a boolean type
+ // to avoid subsequent SMT errors.
+ if (BinaryOperator::isComparisonOp(Op) ||
+ BinaryOperator::isLogicalOp(Op)) {
+ *RetTy = Ctx.BoolTy;
+ } else {
+ *RetTy = LTy;
+ }
+
+ // If the two operands are pointers and the operation is a subtraction,
+ // the result is of type ptrdiff_t, which is signed
+ if (LTy->isAnyPointerType() && RTy->isAnyPointerType() && Op == BO_Sub) {
+ *RetTy = Ctx.getPointerDiffType();
+ }
+ }
+
+ return LTy->isRealFloatingType()
+ ? fromFloatBinOp(Solver, NewLHS, Op, NewRHS)
+ : fromBinOp(Solver, NewLHS, Op, NewRHS,
+ LTy->isSignedIntegerOrEnumerationType());
+ }
+
+ // Wrapper to generate SMTExprRef from BinarySymExpr.
+ // Sets the hasComparison and RetTy parameters. See getSMTExprRef().
+ static inline SMTExprRef getSymBinExpr(SMTSolverRef &Solver, ASTContext &Ctx,
+ const BinarySymExpr *BSE,
+ bool *hasComparison, QualType *RetTy) {
+ QualType LTy, RTy;
+ BinaryOperator::Opcode Op = BSE->getOpcode();
+
+ if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(BSE)) {
+ SMTExprRef LHS =
+ getSymExpr(Solver, Ctx, SIE->getLHS(), &LTy, hasComparison);
+ llvm::APSInt NewRInt;
+ std::tie(NewRInt, RTy) = fixAPSInt(Ctx, SIE->getRHS());
+ SMTExprRef RHS = Solver->mkBitvector(NewRInt, NewRInt.getBitWidth());
+ return getBinExpr(Solver, Ctx, LHS, LTy, Op, RHS, RTy, RetTy);
+ }
+
+ if (const IntSymExpr *ISE = dyn_cast<IntSymExpr>(BSE)) {
+ llvm::APSInt NewLInt;
+ std::tie(NewLInt, LTy) = fixAPSInt(Ctx, ISE->getLHS());
+ SMTExprRef LHS = Solver->mkBitvector(NewLInt, NewLInt.getBitWidth());
+ SMTExprRef RHS =
+ getSymExpr(Solver, Ctx, ISE->getRHS(), &RTy, hasComparison);
+ return getBinExpr(Solver, Ctx, LHS, LTy, Op, RHS, RTy, RetTy);
+ }
+
+ if (const SymSymExpr *SSM = dyn_cast<SymSymExpr>(BSE)) {
+ SMTExprRef LHS =
+ getSymExpr(Solver, Ctx, SSM->getLHS(), &LTy, hasComparison);
+ SMTExprRef RHS =
+ getSymExpr(Solver, Ctx, SSM->getRHS(), &RTy, hasComparison);
+ return getBinExpr(Solver, Ctx, LHS, LTy, Op, RHS, RTy, RetTy);
+ }
+
+ llvm_unreachable("Unsupported BinarySymExpr type!");
+ }
+
+ // Recursive implementation to unpack and generate symbolic expression.
+ // Sets the hasComparison and RetTy parameters. See getExpr().
+ static inline SMTExprRef getSymExpr(SMTSolverRef &Solver, ASTContext &Ctx,
+ SymbolRef Sym, QualType *RetTy,
+ bool *hasComparison) {
+ if (const SymbolData *SD = dyn_cast<SymbolData>(Sym)) {
+ if (RetTy)
+ *RetTy = Sym->getType();
+
+ return fromData(Solver, SD->getSymbolID(), Sym->getType(),
+ Ctx.getTypeSize(Sym->getType()));
+ }
+
+ if (const SymbolCast *SC = dyn_cast<SymbolCast>(Sym)) {
+ if (RetTy)
+ *RetTy = Sym->getType();
+
+ QualType FromTy;
+ SMTExprRef Exp =
+ getSymExpr(Solver, Ctx, SC->getOperand(), &FromTy, hasComparison);
+
+ // Casting an expression with a comparison invalidates it. Note that this
+ // must occur after the recursive call above.
+ // e.g. (signed char) (x > 0)
+ if (hasComparison)
+ *hasComparison = false;
+ return getCastExpr(Solver, Ctx, Exp, FromTy, Sym->getType());
+ }
+
+ if (const BinarySymExpr *BSE = dyn_cast<BinarySymExpr>(Sym)) {
+ SMTExprRef Exp = getSymBinExpr(Solver, Ctx, BSE, hasComparison, RetTy);
+ // Set the hasComparison parameter, in post-order traversal order.
+ if (hasComparison)
+ *hasComparison = BinaryOperator::isComparisonOp(BSE->getOpcode());
+ return Exp;
+ }
+
+ llvm_unreachable("Unsupported SymbolRef type!");
+ }
+
+ // Generate an SMTExprRef that represents the given symbolic expression.
+ // Sets the hasComparison parameter if the expression has a comparison
+ // operator. Sets the RetTy parameter to the final return type after
+ // promotions and casts.
+ static inline SMTExprRef getExpr(SMTSolverRef &Solver, ASTContext &Ctx,
+ SymbolRef Sym, QualType *RetTy = nullptr,
+ bool *hasComparison = nullptr) {
+ if (hasComparison) {
+ *hasComparison = false;
+ }
+
+ return getSymExpr(Solver, Ctx, Sym, RetTy, hasComparison);
+ }
+
+ // Generate an SMTExprRef that compares the expression to zero.
+ static inline SMTExprRef getZeroExpr(SMTSolverRef &Solver, ASTContext &Ctx,
+ const SMTExprRef &Exp, QualType Ty,
+ bool Assumption) {
+
+ if (Ty->isRealFloatingType()) {
+ llvm::APFloat Zero =
+ llvm::APFloat::getZero(Ctx.getFloatTypeSemantics(Ty));
+ return fromFloatBinOp(Solver, Exp, Assumption ? BO_EQ : BO_NE,
+ Solver->mkFloat(Zero));
+ }
+
+ if (Ty->isIntegralOrEnumerationType() || Ty->isAnyPointerType() ||
+ Ty->isBlockPointerType() || Ty->isReferenceType()) {
+
+ // Skip explicit comparison for boolean types
+ bool isSigned = Ty->isSignedIntegerOrEnumerationType();
+ if (Ty->isBooleanType())
+ return Assumption ? fromUnOp(Solver, UO_LNot, Exp) : Exp;
+
+ return fromBinOp(
+ Solver, Exp, Assumption ? BO_EQ : BO_NE,
+ Solver->mkBitvector(llvm::APSInt("0"), Ctx.getTypeSize(Ty)),
+ isSigned);
+ }
+
+ llvm_unreachable("Unsupported type for zero value!");
+ }
+
+ // Wrapper to generate SMTExprRef from a range. If From == To, an equality
+ // will be created instead.
+ static inline SMTExprRef getRangeExpr(SMTSolverRef &Solver, ASTContext &Ctx,
+ SymbolRef Sym, const llvm::APSInt &From,
+ const llvm::APSInt &To, bool InRange) {
+ // Convert lower bound
+ QualType FromTy;
+ llvm::APSInt NewFromInt;
+ std::tie(NewFromInt, FromTy) = fixAPSInt(Ctx, From);
+ SMTExprRef FromExp =
+ Solver->mkBitvector(NewFromInt, NewFromInt.getBitWidth());
+
+ // Convert symbol
+ QualType SymTy;
+ SMTExprRef Exp = getExpr(Solver, Ctx, Sym, &SymTy);
+
+ // Construct single (in)equality
+ if (From == To)
+ return getBinExpr(Solver, Ctx, Exp, SymTy, InRange ? BO_EQ : BO_NE,
+ FromExp, FromTy, /*RetTy=*/nullptr);
+
+ QualType ToTy;
+ llvm::APSInt NewToInt;
+ std::tie(NewToInt, ToTy) = fixAPSInt(Ctx, To);
+ SMTExprRef ToExp = Solver->mkBitvector(NewToInt, NewToInt.getBitWidth());
+ assert(FromTy == ToTy && "Range values have different types!");
+
+ // Construct two (in)equalities, and a logical and/or
+ SMTExprRef LHS =
+ getBinExpr(Solver, Ctx, Exp, SymTy, InRange ? BO_GE : BO_LT, FromExp,
+ FromTy, /*RetTy=*/nullptr);
+ SMTExprRef RHS = getBinExpr(Solver, Ctx, Exp, SymTy,
+ InRange ? BO_LE : BO_GT, ToExp, ToTy,
+ /*RetTy=*/nullptr);
+
+ return fromBinOp(Solver, LHS, InRange ? BO_LAnd : BO_LOr, RHS,
+ SymTy->isSignedIntegerOrEnumerationType());
+ }
+
+ // Recover the QualType of an APSInt.
+ // TODO: Refactor to put elsewhere
+ static inline QualType getAPSIntType(ASTContext &Ctx,
+ const llvm::APSInt &Int) {
+ return Ctx.getIntTypeForBitwidth(Int.getBitWidth(), Int.isSigned());
+ }
+
+ // Get the QualTy for the input APSInt, and fix it if it has a bitwidth of 1.
+ static inline std::pair<llvm::APSInt, QualType>
+ fixAPSInt(ASTContext &Ctx, const llvm::APSInt &Int) {
+ llvm::APSInt NewInt;
+
+ // FIXME: This should be a cast from a 1-bit integer type to a boolean type,
+ // but the former is not available in Clang. Instead, extend the APSInt
+ // directly.
+ if (Int.getBitWidth() == 1 && getAPSIntType(Ctx, Int).isNull()) {
+ NewInt = Int.extend(Ctx.getTypeSize(Ctx.BoolTy));
+ } else
+ NewInt = Int;
+
+ return std::make_pair(NewInt, getAPSIntType(Ctx, NewInt));
+ }
+
+ // Perform implicit type conversion on binary symbolic expressions.
+ // May modify all input parameters.
+ // TODO: Refactor to use built-in conversion functions
+ static inline void doTypeConversion(SMTSolverRef &Solver, ASTContext &Ctx,
+ SMTExprRef &LHS, SMTExprRef &RHS,
+ QualType &LTy, QualType &RTy) {
+ assert(!LTy.isNull() && !RTy.isNull() && "Input type is null!");
+
+ // Perform type conversion
+ if ((LTy->isIntegralOrEnumerationType() &&
+ RTy->isIntegralOrEnumerationType()) &&
+ (LTy->isArithmeticType() && RTy->isArithmeticType())) {
+ SMTConv::doIntTypeConversion<SMTExprRef, &fromCast>(Solver, Ctx, LHS, LTy,
+ RHS, RTy);
+ return;
+ }
+
+ if (LTy->isRealFloatingType() || RTy->isRealFloatingType()) {
+ SMTConv::doFloatTypeConversion<SMTExprRef, &fromCast>(Solver, Ctx, LHS,
+ LTy, RHS, RTy);
+ return;
+ }
+
+ if ((LTy->isAnyPointerType() || RTy->isAnyPointerType()) ||
+ (LTy->isBlockPointerType() || RTy->isBlockPointerType()) ||
+ (LTy->isReferenceType() || RTy->isReferenceType())) {
+ // TODO: Refactor to Sema::FindCompositePointerType(), and
+ // Sema::CheckCompareOperands().
+
+ uint64_t LBitWidth = Ctx.getTypeSize(LTy);
+ uint64_t RBitWidth = Ctx.getTypeSize(RTy);
+
+ // Cast the non-pointer type to the pointer type.
+ // TODO: Be more strict about this.
+ if ((LTy->isAnyPointerType() ^ RTy->isAnyPointerType()) ||
+ (LTy->isBlockPointerType() ^ RTy->isBlockPointerType()) ||
+ (LTy->isReferenceType() ^ RTy->isReferenceType())) {
+ if (LTy->isNullPtrType() || LTy->isBlockPointerType() ||
+ LTy->isReferenceType()) {
+ LHS = fromCast(Solver, LHS, RTy, RBitWidth, LTy, LBitWidth);
+ LTy = RTy;
+ } else {
+ RHS = fromCast(Solver, RHS, LTy, LBitWidth, RTy, RBitWidth);
+ RTy = LTy;
+ }
+ }
+
+ // Cast the void pointer type to the non-void pointer type.
+ // For void types, this assumes that the casted value is equal to the
+ // value of the original pointer, and does not account for alignment
+ // requirements.
+ if (LTy->isVoidPointerType() ^ RTy->isVoidPointerType()) {
+ assert((Ctx.getTypeSize(LTy) == Ctx.getTypeSize(RTy)) &&
+ "Pointer types have different bitwidths!");
+ if (RTy->isVoidPointerType())
+ RTy = LTy;
+ else
+ LTy = RTy;
+ }
+
+ if (LTy == RTy)
+ return;
+ }
+
+ // Fallback: for the solver, assume that these types don't really matter
+ if ((LTy.getCanonicalType() == RTy.getCanonicalType()) ||
+ (LTy->isObjCObjectPointerType() && RTy->isObjCObjectPointerType())) {
+ LTy = RTy;
+ return;
+ }
+
+ // TODO: Refine behavior for invalid type casts
+ }
+
+ // Perform implicit integer type conversion.
+ // May modify all input parameters.
+ // TODO: Refactor to use Sema::handleIntegerConversion()
+ template <typename T, T (*doCast)(SMTSolverRef &Solver, const T &, QualType,
+ uint64_t, QualType, uint64_t)>
+ static inline void doIntTypeConversion(SMTSolverRef &Solver, ASTContext &Ctx,
+ T &LHS, QualType &LTy, T &RHS,
+ QualType &RTy) {
+
+ uint64_t LBitWidth = Ctx.getTypeSize(LTy);
+ uint64_t RBitWidth = Ctx.getTypeSize(RTy);
+
+ assert(!LTy.isNull() && !RTy.isNull() && "Input type is null!");
+ // Always perform integer promotion before checking type equality.
+ // Otherwise, e.g. (bool) a + (bool) b could trigger a backend assertion
+ if (LTy->isPromotableIntegerType()) {
+ QualType NewTy = Ctx.getPromotedIntegerType(LTy);
+ uint64_t NewBitWidth = Ctx.getTypeSize(NewTy);
+ LHS = (*doCast)(Solver, LHS, NewTy, NewBitWidth, LTy, LBitWidth);
+ LTy = NewTy;
+ LBitWidth = NewBitWidth;
+ }
+ if (RTy->isPromotableIntegerType()) {
+ QualType NewTy = Ctx.getPromotedIntegerType(RTy);
+ uint64_t NewBitWidth = Ctx.getTypeSize(NewTy);
+ RHS = (*doCast)(Solver, RHS, NewTy, NewBitWidth, RTy, RBitWidth);
+ RTy = NewTy;
+ RBitWidth = NewBitWidth;
+ }
+
+ if (LTy == RTy)
+ return;
+
+ // Perform integer type conversion
+ // Note: Safe to skip updating bitwidth because this must terminate
+ bool isLSignedTy = LTy->isSignedIntegerOrEnumerationType();
+ bool isRSignedTy = RTy->isSignedIntegerOrEnumerationType();
+
+ int order = Ctx.getIntegerTypeOrder(LTy, RTy);
+ if (isLSignedTy == isRSignedTy) {
+ // Same signedness; use the higher-ranked type
+ if (order == 1) {
+ RHS = (*doCast)(Solver, RHS, LTy, LBitWidth, RTy, RBitWidth);
+ RTy = LTy;
+ } else {
+ LHS = (*doCast)(Solver, LHS, RTy, RBitWidth, LTy, LBitWidth);
+ LTy = RTy;
+ }
+ } else if (order != (isLSignedTy ? 1 : -1)) {
+ // The unsigned type has greater than or equal rank to the
+ // signed type, so use the unsigned type
+ if (isRSignedTy) {
+ RHS = (*doCast)(Solver, RHS, LTy, LBitWidth, RTy, RBitWidth);
+ RTy = LTy;
+ } else {
+ LHS = (*doCast)(Solver, LHS, RTy, RBitWidth, LTy, LBitWidth);
+ LTy = RTy;
+ }
+ } else if (LBitWidth != RBitWidth) {
+ // The two types are different widths; if we are here, that
+ // means the signed type is larger than the unsigned type, so
+ // use the signed type.
+ if (isLSignedTy) {
+ RHS = (doCast)(Solver, RHS, LTy, LBitWidth, RTy, RBitWidth);
+ RTy = LTy;
+ } else {
+ LHS = (*doCast)(Solver, LHS, RTy, RBitWidth, LTy, LBitWidth);
+ LTy = RTy;
+ }
+ } else {
+ // The signed type is higher-ranked than the unsigned type,
+ // but isn't actually any bigger (like unsigned int and long
+ // on most 32-bit systems). Use the unsigned type corresponding
+ // to the signed type.
+ QualType NewTy =
+ Ctx.getCorrespondingUnsignedType(isLSignedTy ? LTy : RTy);
+ RHS = (*doCast)(Solver, RHS, LTy, LBitWidth, RTy, RBitWidth);
+ RTy = NewTy;
+ LHS = (doCast)(Solver, LHS, RTy, RBitWidth, LTy, LBitWidth);
+ LTy = NewTy;
+ }
+ }
+
+ // Perform implicit floating-point type conversion.
+ // May modify all input parameters.
+ // TODO: Refactor to use Sema::handleFloatConversion()
+ template <typename T, T (*doCast)(SMTSolverRef &Solver, const T &, QualType,
+ uint64_t, QualType, uint64_t)>
+ static inline void
+ doFloatTypeConversion(SMTSolverRef &Solver, ASTContext &Ctx, T &LHS,
+ QualType &LTy, T &RHS, QualType &RTy) {
+
+ uint64_t LBitWidth = Ctx.getTypeSize(LTy);
+ uint64_t RBitWidth = Ctx.getTypeSize(RTy);
+
+ // Perform float-point type promotion
+ if (!LTy->isRealFloatingType()) {
+ LHS = (*doCast)(Solver, LHS, RTy, RBitWidth, LTy, LBitWidth);
+ LTy = RTy;
+ LBitWidth = RBitWidth;
+ }
+ if (!RTy->isRealFloatingType()) {
+ RHS = (*doCast)(Solver, RHS, LTy, LBitWidth, RTy, RBitWidth);
+ RTy = LTy;
+ RBitWidth = LBitWidth;
+ }
+
+ if (LTy == RTy)
+ return;
+
+ // If we have two real floating types, convert the smaller operand to the
+ // bigger result
+ // Note: Safe to skip updating bitwidth because this must terminate
+ int order = Ctx.getFloatingTypeOrder(LTy, RTy);
+ if (order > 0) {
+ RHS = (*doCast)(Solver, RHS, LTy, LBitWidth, RTy, RBitWidth);
+ RTy = LTy;
+ } else if (order == 0) {
+ LHS = (*doCast)(Solver, LHS, RTy, RBitWidth, LTy, LBitWidth);
+ LTy = RTy;
+ } else {
+ llvm_unreachable("Unsupported floating-point type cast!");
+ }
+ }
+};
+} // namespace ento
+} // namespace clang
+
+#endif \ No newline at end of file
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SMTSolver.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SMTSolver.h
index a43ca486901b..2abe5fc98744 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SMTSolver.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SMTSolver.h
@@ -15,12 +15,9 @@
#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SMTSOLVER_H
#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SMTSOLVER_H
-#include "clang/AST/Expr.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SMTExpr.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SMTSort.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
+#include "llvm/ADT/APSInt.h"
namespace clang {
namespace ento {
@@ -53,683 +50,6 @@ public:
llvm_unreachable("Unsupported floating-point bitwidth!");
}
- // Returns an appropriate sort, given a QualType and it's bit width.
- SMTSortRef mkSort(const QualType &Ty, unsigned BitWidth) {
- if (Ty->isBooleanType())
- return getBoolSort();
-
- if (Ty->isRealFloatingType())
- return getFloatSort(BitWidth);
-
- return getBitvectorSort(BitWidth);
- }
-
- /// Constructs an SMTExprRef from an unary operator.
- SMTExprRef fromUnOp(const UnaryOperator::Opcode Op, const SMTExprRef &Exp) {
- switch (Op) {
- case UO_Minus:
- return mkBVNeg(Exp);
-
- case UO_Not:
- return mkBVNot(Exp);
-
- case UO_LNot:
- return mkNot(Exp);
-
- default:;
- }
- llvm_unreachable("Unimplemented opcode");
- }
-
- /// Constructs an SMTExprRef from a floating-point unary operator.
- SMTExprRef fromFloatUnOp(const UnaryOperator::Opcode Op,
- const SMTExprRef &Exp) {
- switch (Op) {
- case UO_Minus:
- return mkFPNeg(Exp);
-
- case UO_LNot:
- return fromUnOp(Op, Exp);
-
- default:;
- }
- llvm_unreachable("Unimplemented opcode");
- }
-
- /// Construct an SMTExprRef from a n-ary binary operator.
- SMTExprRef fromNBinOp(const BinaryOperator::Opcode Op,
- const std::vector<SMTExprRef> &ASTs) {
- assert(!ASTs.empty());
-
- if (Op != BO_LAnd && Op != BO_LOr)
- llvm_unreachable("Unimplemented opcode");
-
- SMTExprRef res = ASTs.front();
- for (std::size_t i = 1; i < ASTs.size(); ++i)
- res = (Op == BO_LAnd) ? mkAnd(res, ASTs[i]) : mkOr(res, ASTs[i]);
- return res;
- }
-
- /// Construct an SMTExprRef from a binary operator.
- SMTExprRef fromBinOp(const SMTExprRef &LHS, const BinaryOperator::Opcode Op,
- const SMTExprRef &RHS, bool isSigned) {
- assert(*getSort(LHS) == *getSort(RHS) && "AST's must have the same sort!");
-
- switch (Op) {
- // Multiplicative operators
- case BO_Mul:
- return mkBVMul(LHS, RHS);
-
- case BO_Div:
- return isSigned ? mkBVSDiv(LHS, RHS) : mkBVUDiv(LHS, RHS);
-
- case BO_Rem:
- return isSigned ? mkBVSRem(LHS, RHS) : mkBVURem(LHS, RHS);
-
- // Additive operators
- case BO_Add:
- return mkBVAdd(LHS, RHS);
-
- case BO_Sub:
- return mkBVSub(LHS, RHS);
-
- // Bitwise shift operators
- case BO_Shl:
- return mkBVShl(LHS, RHS);
-
- case BO_Shr:
- return isSigned ? mkBVAshr(LHS, RHS) : mkBVLshr(LHS, RHS);
-
- // Relational operators
- case BO_LT:
- return isSigned ? mkBVSlt(LHS, RHS) : mkBVUlt(LHS, RHS);
-
- case BO_GT:
- return isSigned ? mkBVSgt(LHS, RHS) : mkBVUgt(LHS, RHS);
-
- case BO_LE:
- return isSigned ? mkBVSle(LHS, RHS) : mkBVUle(LHS, RHS);
-
- case BO_GE:
- return isSigned ? mkBVSge(LHS, RHS) : mkBVUge(LHS, RHS);
-
- // Equality operators
- case BO_EQ:
- return mkEqual(LHS, RHS);
-
- case BO_NE:
- return fromUnOp(UO_LNot, fromBinOp(LHS, BO_EQ, RHS, isSigned));
-
- // Bitwise operators
- case BO_And:
- return mkBVAnd(LHS, RHS);
-
- case BO_Xor:
- return mkBVXor(LHS, RHS);
-
- case BO_Or:
- return mkBVOr(LHS, RHS);
-
- // Logical operators
- case BO_LAnd:
- return mkAnd(LHS, RHS);
-
- case BO_LOr:
- return mkOr(LHS, RHS);
-
- default:;
- }
- llvm_unreachable("Unimplemented opcode");
- }
-
- /// Construct an SMTExprRef from a special floating-point binary operator.
- SMTExprRef fromFloatSpecialBinOp(const SMTExprRef &LHS,
- const BinaryOperator::Opcode Op,
- const llvm::APFloat::fltCategory &RHS) {
- switch (Op) {
- // Equality operators
- case BO_EQ:
- switch (RHS) {
- case llvm::APFloat::fcInfinity:
- return mkFPIsInfinite(LHS);
-
- case llvm::APFloat::fcNaN:
- return mkFPIsNaN(LHS);
-
- case llvm::APFloat::fcNormal:
- return mkFPIsNormal(LHS);
-
- case llvm::APFloat::fcZero:
- return mkFPIsZero(LHS);
- }
- break;
-
- case BO_NE:
- return fromFloatUnOp(UO_LNot, fromFloatSpecialBinOp(LHS, BO_EQ, RHS));
-
- default:;
- }
-
- llvm_unreachable("Unimplemented opcode");
- }
-
- /// Construct an SMTExprRef from a floating-point binary operator.
- SMTExprRef fromFloatBinOp(const SMTExprRef &LHS,
- const BinaryOperator::Opcode Op,
- const SMTExprRef &RHS) {
- assert(*getSort(LHS) == *getSort(RHS) && "AST's must have the same sort!");
-
- switch (Op) {
- // Multiplicative operators
- case BO_Mul:
- return mkFPMul(LHS, RHS);
-
- case BO_Div:
- return mkFPDiv(LHS, RHS);
-
- case BO_Rem:
- return mkFPRem(LHS, RHS);
-
- // Additive operators
- case BO_Add:
- return mkFPAdd(LHS, RHS);
-
- case BO_Sub:
- return mkFPSub(LHS, RHS);
-
- // Relational operators
- case BO_LT:
- return mkFPLt(LHS, RHS);
-
- case BO_GT:
- return mkFPGt(LHS, RHS);
-
- case BO_LE:
- return mkFPLe(LHS, RHS);
-
- case BO_GE:
- return mkFPGe(LHS, RHS);
-
- // Equality operators
- case BO_EQ:
- return mkFPEqual(LHS, RHS);
-
- case BO_NE:
- return fromFloatUnOp(UO_LNot, fromFloatBinOp(LHS, BO_EQ, RHS));
-
- // Logical operators
- case BO_LAnd:
- case BO_LOr:
- return fromBinOp(LHS, Op, RHS, false);
-
- default:;
- }
-
- llvm_unreachable("Unimplemented opcode");
- }
-
- /// Construct an SMTExprRef from a QualType FromTy to a QualType ToTy, and
- /// their bit widths.
- SMTExprRef fromCast(const SMTExprRef &Exp, QualType ToTy, uint64_t ToBitWidth,
- QualType FromTy, uint64_t FromBitWidth) {
- if ((FromTy->isIntegralOrEnumerationType() &&
- ToTy->isIntegralOrEnumerationType()) ||
- (FromTy->isAnyPointerType() ^ ToTy->isAnyPointerType()) ||
- (FromTy->isBlockPointerType() ^ ToTy->isBlockPointerType()) ||
- (FromTy->isReferenceType() ^ ToTy->isReferenceType())) {
-
- if (FromTy->isBooleanType()) {
- assert(ToBitWidth > 0 && "BitWidth must be positive!");
- return mkIte(Exp, mkBitvector(llvm::APSInt("1"), ToBitWidth),
- mkBitvector(llvm::APSInt("0"), ToBitWidth));
- }
-
- if (ToBitWidth > FromBitWidth)
- return FromTy->isSignedIntegerOrEnumerationType()
- ? mkBVSignExt(ToBitWidth - FromBitWidth, Exp)
- : mkBVZeroExt(ToBitWidth - FromBitWidth, Exp);
-
- if (ToBitWidth < FromBitWidth)
- return mkBVExtract(ToBitWidth - 1, 0, Exp);
-
- // Both are bitvectors with the same width, ignore the type cast
- return Exp;
- }
-
- if (FromTy->isRealFloatingType() && ToTy->isRealFloatingType()) {
- if (ToBitWidth != FromBitWidth)
- return mkFPtoFP(Exp, getFloatSort(ToBitWidth));
-
- return Exp;
- }
-
- if (FromTy->isIntegralOrEnumerationType() && ToTy->isRealFloatingType()) {
- SMTSortRef Sort = getFloatSort(ToBitWidth);
- return FromTy->isSignedIntegerOrEnumerationType() ? mkFPtoSBV(Exp, Sort)
- : mkFPtoUBV(Exp, Sort);
- }
-
- if (FromTy->isRealFloatingType() && ToTy->isIntegralOrEnumerationType())
- return ToTy->isSignedIntegerOrEnumerationType()
- ? mkSBVtoFP(Exp, ToBitWidth)
- : mkUBVtoFP(Exp, ToBitWidth);
-
- llvm_unreachable("Unsupported explicit type cast!");
- }
-
- // Callback function for doCast parameter on APSInt type.
- llvm::APSInt castAPSInt(const llvm::APSInt &V, QualType ToTy,
- uint64_t ToWidth, QualType FromTy,
- uint64_t FromWidth) {
- APSIntType TargetType(ToWidth, !ToTy->isSignedIntegerOrEnumerationType());
- return TargetType.convert(V);
- }
-
- // Generate an SMTExprRef that represents the given symbolic expression.
- // Sets the hasComparison parameter if the expression has a comparison
- // operator.
- // Sets the RetTy parameter to the final return type after promotions and
- // casts.
- SMTExprRef getExpr(ASTContext &Ctx, SymbolRef Sym, QualType *RetTy = nullptr,
- bool *hasComparison = nullptr) {
- if (hasComparison) {
- *hasComparison = false;
- }
-
- return getSymExpr(Ctx, Sym, RetTy, hasComparison);
- }
-
- // Generate an SMTExprRef that compares the expression to zero.
- SMTExprRef getZeroExpr(ASTContext &Ctx, const SMTExprRef &Exp, QualType Ty,
- bool Assumption) {
-
- if (Ty->isRealFloatingType()) {
- llvm::APFloat Zero =
- llvm::APFloat::getZero(Ctx.getFloatTypeSemantics(Ty));
- return fromFloatBinOp(Exp, Assumption ? BO_EQ : BO_NE, fromAPFloat(Zero));
- }
-
- if (Ty->isIntegralOrEnumerationType() || Ty->isAnyPointerType() ||
- Ty->isBlockPointerType() || Ty->isReferenceType()) {
-
- // Skip explicit comparison for boolean types
- bool isSigned = Ty->isSignedIntegerOrEnumerationType();
- if (Ty->isBooleanType())
- return Assumption ? fromUnOp(UO_LNot, Exp) : Exp;
-
- return fromBinOp(Exp, Assumption ? BO_EQ : BO_NE,
- fromInt("0", Ctx.getTypeSize(Ty)), isSigned);
- }
-
- llvm_unreachable("Unsupported type for zero value!");
- }
-
- // Recursive implementation to unpack and generate symbolic expression.
- // Sets the hasComparison and RetTy parameters. See getExpr().
- SMTExprRef getSymExpr(ASTContext &Ctx, SymbolRef Sym, QualType *RetTy,
- bool *hasComparison) {
- if (const SymbolData *SD = dyn_cast<SymbolData>(Sym)) {
- if (RetTy)
- *RetTy = Sym->getType();
-
- return fromData(SD->getSymbolID(), Sym->getType(),
- Ctx.getTypeSize(Sym->getType()));
- }
-
- if (const SymbolCast *SC = dyn_cast<SymbolCast>(Sym)) {
- if (RetTy)
- *RetTy = Sym->getType();
-
- QualType FromTy;
- SMTExprRef Exp =
- getSymExpr(Ctx, SC->getOperand(), &FromTy, hasComparison);
- // Casting an expression with a comparison invalidates it. Note that this
- // must occur after the recursive call above.
- // e.g. (signed char) (x > 0)
- if (hasComparison)
- *hasComparison = false;
- return getCastExpr(Ctx, Exp, FromTy, Sym->getType());
- }
-
- if (const BinarySymExpr *BSE = dyn_cast<BinarySymExpr>(Sym)) {
- SMTExprRef Exp = getSymBinExpr(Ctx, BSE, hasComparison, RetTy);
- // Set the hasComparison parameter, in post-order traversal order.
- if (hasComparison)
- *hasComparison = BinaryOperator::isComparisonOp(BSE->getOpcode());
- return Exp;
- }
-
- llvm_unreachable("Unsupported SymbolRef type!");
- }
-
- // Wrapper to generate SMTExprRef from SymbolCast data.
- SMTExprRef getCastExpr(ASTContext &Ctx, const SMTExprRef &Exp,
- QualType FromTy, QualType ToTy) {
- return fromCast(Exp, ToTy, Ctx.getTypeSize(ToTy), FromTy,
- Ctx.getTypeSize(FromTy));
- }
-
- // Wrapper to generate SMTExprRef from BinarySymExpr.
- // Sets the hasComparison and RetTy parameters. See getSMTExprRef().
- SMTExprRef getSymBinExpr(ASTContext &Ctx, const BinarySymExpr *BSE,
- bool *hasComparison, QualType *RetTy) {
- QualType LTy, RTy;
- BinaryOperator::Opcode Op = BSE->getOpcode();
-
- if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(BSE)) {
- SMTExprRef LHS = getSymExpr(Ctx, SIE->getLHS(), &LTy, hasComparison);
- llvm::APSInt NewRInt;
- std::tie(NewRInt, RTy) = fixAPSInt(Ctx, SIE->getRHS());
- SMTExprRef RHS = fromAPSInt(NewRInt);
- return getBinExpr(Ctx, LHS, LTy, Op, RHS, RTy, RetTy);
- }
-
- if (const IntSymExpr *ISE = dyn_cast<IntSymExpr>(BSE)) {
- llvm::APSInt NewLInt;
- std::tie(NewLInt, LTy) = fixAPSInt(Ctx, ISE->getLHS());
- SMTExprRef LHS = fromAPSInt(NewLInt);
- SMTExprRef RHS = getSymExpr(Ctx, ISE->getRHS(), &RTy, hasComparison);
- return getBinExpr(Ctx, LHS, LTy, Op, RHS, RTy, RetTy);
- }
-
- if (const SymSymExpr *SSM = dyn_cast<SymSymExpr>(BSE)) {
- SMTExprRef LHS = getSymExpr(Ctx, SSM->getLHS(), &LTy, hasComparison);
- SMTExprRef RHS = getSymExpr(Ctx, SSM->getRHS(), &RTy, hasComparison);
- return getBinExpr(Ctx, LHS, LTy, Op, RHS, RTy, RetTy);
- }
-
- llvm_unreachable("Unsupported BinarySymExpr type!");
- }
-
- // Wrapper to generate SMTExprRef from unpacked binary symbolic expression.
- // Sets the RetTy parameter. See getSMTExprRef().
- SMTExprRef getBinExpr(ASTContext &Ctx, const SMTExprRef &LHS, QualType LTy,
- BinaryOperator::Opcode Op, const SMTExprRef &RHS,
- QualType RTy, QualType *RetTy) {
- SMTExprRef NewLHS = LHS;
- SMTExprRef NewRHS = RHS;
- doTypeConversion(Ctx, NewLHS, NewRHS, LTy, RTy);
-
- // Update the return type parameter if the output type has changed.
- if (RetTy) {
- // A boolean result can be represented as an integer type in C/C++, but at
- // this point we only care about the SMT sorts. Set it as a boolean type
- // to avoid subsequent SMT errors.
- if (BinaryOperator::isComparisonOp(Op) ||
- BinaryOperator::isLogicalOp(Op)) {
- *RetTy = Ctx.BoolTy;
- } else {
- *RetTy = LTy;
- }
-
- // If the two operands are pointers and the operation is a subtraction,
- // the result is of type ptrdiff_t, which is signed
- if (LTy->isAnyPointerType() && RTy->isAnyPointerType() && Op == BO_Sub) {
- *RetTy = Ctx.getPointerDiffType();
- }
- }
-
- return LTy->isRealFloatingType()
- ? fromFloatBinOp(NewLHS, Op, NewRHS)
- : fromBinOp(NewLHS, Op, NewRHS,
- LTy->isSignedIntegerOrEnumerationType());
- }
-
- // Wrapper to generate SMTExprRef from a range. If From == To, an equality
- // will be created instead.
- SMTExprRef getRangeExpr(ASTContext &Ctx, SymbolRef Sym,
- const llvm::APSInt &From, const llvm::APSInt &To,
- bool InRange) {
- // Convert lower bound
- QualType FromTy;
- llvm::APSInt NewFromInt;
- std::tie(NewFromInt, FromTy) = fixAPSInt(Ctx, From);
- SMTExprRef FromExp = fromAPSInt(NewFromInt);
-
- // Convert symbol
- QualType SymTy;
- SMTExprRef Exp = getExpr(Ctx, Sym, &SymTy);
-
- // Construct single (in)equality
- if (From == To)
- return getBinExpr(Ctx, Exp, SymTy, InRange ? BO_EQ : BO_NE, FromExp,
- FromTy, /*RetTy=*/nullptr);
-
- QualType ToTy;
- llvm::APSInt NewToInt;
- std::tie(NewToInt, ToTy) = fixAPSInt(Ctx, To);
- SMTExprRef ToExp = fromAPSInt(NewToInt);
- assert(FromTy == ToTy && "Range values have different types!");
-
- // Construct two (in)equalities, and a logical and/or
- SMTExprRef LHS = getBinExpr(Ctx, Exp, SymTy, InRange ? BO_GE : BO_LT,
- FromExp, FromTy, /*RetTy=*/nullptr);
- SMTExprRef RHS =
- getBinExpr(Ctx, Exp, SymTy, InRange ? BO_LE : BO_GT, ToExp, ToTy,
- /*RetTy=*/nullptr);
-
- return fromBinOp(LHS, InRange ? BO_LAnd : BO_LOr, RHS,
- SymTy->isSignedIntegerOrEnumerationType());
- }
-
- // Recover the QualType of an APSInt.
- // TODO: Refactor to put elsewhere
- QualType getAPSIntType(ASTContext &Ctx, const llvm::APSInt &Int) {
- return Ctx.getIntTypeForBitwidth(Int.getBitWidth(), Int.isSigned());
- }
-
- // Get the QualTy for the input APSInt, and fix it if it has a bitwidth of 1.
- std::pair<llvm::APSInt, QualType> fixAPSInt(ASTContext &Ctx,
- const llvm::APSInt &Int) {
- llvm::APSInt NewInt;
-
- // FIXME: This should be a cast from a 1-bit integer type to a boolean type,
- // but the former is not available in Clang. Instead, extend the APSInt
- // directly.
- if (Int.getBitWidth() == 1 && getAPSIntType(Ctx, Int).isNull()) {
- NewInt = Int.extend(Ctx.getTypeSize(Ctx.BoolTy));
- } else
- NewInt = Int;
-
- return std::make_pair(NewInt, getAPSIntType(Ctx, NewInt));
- }
-
- // Perform implicit type conversion on binary symbolic expressions.
- // May modify all input parameters.
- // TODO: Refactor to use built-in conversion functions
- void doTypeConversion(ASTContext &Ctx, SMTExprRef &LHS, SMTExprRef &RHS,
- QualType &LTy, QualType &RTy) {
- assert(!LTy.isNull() && !RTy.isNull() && "Input type is null!");
-
- // Perform type conversion
- if ((LTy->isIntegralOrEnumerationType() &&
- RTy->isIntegralOrEnumerationType()) &&
- (LTy->isArithmeticType() && RTy->isArithmeticType())) {
- doIntTypeConversion<SMTExprRef, &SMTSolver::fromCast>(Ctx, LHS, LTy, RHS,
- RTy);
- return;
- }
-
- if (LTy->isRealFloatingType() || RTy->isRealFloatingType()) {
- doFloatTypeConversion<SMTExprRef, &SMTSolver::fromCast>(Ctx, LHS, LTy,
- RHS, RTy);
- return;
- }
-
- if ((LTy->isAnyPointerType() || RTy->isAnyPointerType()) ||
- (LTy->isBlockPointerType() || RTy->isBlockPointerType()) ||
- (LTy->isReferenceType() || RTy->isReferenceType())) {
- // TODO: Refactor to Sema::FindCompositePointerType(), and
- // Sema::CheckCompareOperands().
-
- uint64_t LBitWidth = Ctx.getTypeSize(LTy);
- uint64_t RBitWidth = Ctx.getTypeSize(RTy);
-
- // Cast the non-pointer type to the pointer type.
- // TODO: Be more strict about this.
- if ((LTy->isAnyPointerType() ^ RTy->isAnyPointerType()) ||
- (LTy->isBlockPointerType() ^ RTy->isBlockPointerType()) ||
- (LTy->isReferenceType() ^ RTy->isReferenceType())) {
- if (LTy->isNullPtrType() || LTy->isBlockPointerType() ||
- LTy->isReferenceType()) {
- LHS = fromCast(LHS, RTy, RBitWidth, LTy, LBitWidth);
- LTy = RTy;
- } else {
- RHS = fromCast(RHS, LTy, LBitWidth, RTy, RBitWidth);
- RTy = LTy;
- }
- }
-
- // Cast the void pointer type to the non-void pointer type.
- // For void types, this assumes that the casted value is equal to the
- // value of the original pointer, and does not account for alignment
- // requirements.
- if (LTy->isVoidPointerType() ^ RTy->isVoidPointerType()) {
- assert((Ctx.getTypeSize(LTy) == Ctx.getTypeSize(RTy)) &&
- "Pointer types have different bitwidths!");
- if (RTy->isVoidPointerType())
- RTy = LTy;
- else
- LTy = RTy;
- }
-
- if (LTy == RTy)
- return;
- }
-
- // Fallback: for the solver, assume that these types don't really matter
- if ((LTy.getCanonicalType() == RTy.getCanonicalType()) ||
- (LTy->isObjCObjectPointerType() && RTy->isObjCObjectPointerType())) {
- LTy = RTy;
- return;
- }
-
- // TODO: Refine behavior for invalid type casts
- }
-
- // Perform implicit integer type conversion.
- // May modify all input parameters.
- // TODO: Refactor to use Sema::handleIntegerConversion()
- template <typename T, T (SMTSolver::*doCast)(const T &, QualType, uint64_t,
- QualType, uint64_t)>
- void doIntTypeConversion(ASTContext &Ctx, T &LHS, QualType &LTy, T &RHS,
- QualType &RTy) {
-
- uint64_t LBitWidth = Ctx.getTypeSize(LTy);
- uint64_t RBitWidth = Ctx.getTypeSize(RTy);
-
- assert(!LTy.isNull() && !RTy.isNull() && "Input type is null!");
- // Always perform integer promotion before checking type equality.
- // Otherwise, e.g. (bool) a + (bool) b could trigger a backend assertion
- if (LTy->isPromotableIntegerType()) {
- QualType NewTy = Ctx.getPromotedIntegerType(LTy);
- uint64_t NewBitWidth = Ctx.getTypeSize(NewTy);
- LHS = (this->*doCast)(LHS, NewTy, NewBitWidth, LTy, LBitWidth);
- LTy = NewTy;
- LBitWidth = NewBitWidth;
- }
- if (RTy->isPromotableIntegerType()) {
- QualType NewTy = Ctx.getPromotedIntegerType(RTy);
- uint64_t NewBitWidth = Ctx.getTypeSize(NewTy);
- RHS = (this->*doCast)(RHS, NewTy, NewBitWidth, RTy, RBitWidth);
- RTy = NewTy;
- RBitWidth = NewBitWidth;
- }
-
- if (LTy == RTy)
- return;
-
- // Perform integer type conversion
- // Note: Safe to skip updating bitwidth because this must terminate
- bool isLSignedTy = LTy->isSignedIntegerOrEnumerationType();
- bool isRSignedTy = RTy->isSignedIntegerOrEnumerationType();
-
- int order = Ctx.getIntegerTypeOrder(LTy, RTy);
- if (isLSignedTy == isRSignedTy) {
- // Same signedness; use the higher-ranked type
- if (order == 1) {
- RHS = (this->*doCast)(RHS, LTy, LBitWidth, RTy, RBitWidth);
- RTy = LTy;
- } else {
- LHS = (this->*doCast)(LHS, RTy, RBitWidth, LTy, LBitWidth);
- LTy = RTy;
- }
- } else if (order != (isLSignedTy ? 1 : -1)) {
- // The unsigned type has greater than or equal rank to the
- // signed type, so use the unsigned type
- if (isRSignedTy) {
- RHS = (this->*doCast)(RHS, LTy, LBitWidth, RTy, RBitWidth);
- RTy = LTy;
- } else {
- LHS = (this->*doCast)(LHS, RTy, RBitWidth, LTy, LBitWidth);
- LTy = RTy;
- }
- } else if (LBitWidth != RBitWidth) {
- // The two types are different widths; if we are here, that
- // means the signed type is larger than the unsigned type, so
- // use the signed type.
- if (isLSignedTy) {
- RHS = (this->*doCast)(RHS, LTy, LBitWidth, RTy, RBitWidth);
- RTy = LTy;
- } else {
- LHS = (this->*doCast)(LHS, RTy, RBitWidth, LTy, LBitWidth);
- LTy = RTy;
- }
- } else {
- // The signed type is higher-ranked than the unsigned type,
- // but isn't actually any bigger (like unsigned int and long
- // on most 32-bit systems). Use the unsigned type corresponding
- // to the signed type.
- QualType NewTy =
- Ctx.getCorrespondingUnsignedType(isLSignedTy ? LTy : RTy);
- RHS = (this->*doCast)(RHS, LTy, LBitWidth, RTy, RBitWidth);
- RTy = NewTy;
- LHS = (this->*doCast)(LHS, RTy, RBitWidth, LTy, LBitWidth);
- LTy = NewTy;
- }
- }
-
- // Perform implicit floating-point type conversion.
- // May modify all input parameters.
- // TODO: Refactor to use Sema::handleFloatConversion()
- template <typename T, T (SMTSolver::*doCast)(const T &, QualType, uint64_t,
- QualType, uint64_t)>
- void doFloatTypeConversion(ASTContext &Ctx, T &LHS, QualType &LTy, T &RHS,
- QualType &RTy) {
-
- uint64_t LBitWidth = Ctx.getTypeSize(LTy);
- uint64_t RBitWidth = Ctx.getTypeSize(RTy);
-
- // Perform float-point type promotion
- if (!LTy->isRealFloatingType()) {
- LHS = (this->*doCast)(LHS, RTy, RBitWidth, LTy, LBitWidth);
- LTy = RTy;
- LBitWidth = RBitWidth;
- }
- if (!RTy->isRealFloatingType()) {
- RHS = (this->*doCast)(RHS, LTy, LBitWidth, RTy, RBitWidth);
- RTy = LTy;
- RBitWidth = LBitWidth;
- }
-
- if (LTy == RTy)
- return;
-
- // If we have two real floating types, convert the smaller operand to the
- // bigger result
- // Note: Safe to skip updating bitwidth because this must terminate
- int order = Ctx.getFloatingTypeOrder(LTy, RTy);
- if (order > 0) {
- RHS = (this->*doCast)(RHS, LTy, LBitWidth, RTy, RBitWidth);
- RTy = LTy;
- } else if (order == 0) {
- LHS = (this->*doCast)(LHS, RTy, RBitWidth, LTy, LBitWidth);
- LTy = RTy;
- } else {
- llvm_unreachable("Unsupported floating-point type cast!");
- }
- }
-
// Returns a boolean sort.
virtual SMTSortRef getBoolSort() = 0;
@@ -906,23 +226,23 @@ public:
/// operation
virtual SMTExprRef mkFPtoFP(const SMTExprRef &From, const SMTSortRef &To) = 0;
- /// Creates a floating-point conversion from floatint-point to signed
- /// bitvector operation
- virtual SMTExprRef mkFPtoSBV(const SMTExprRef &From,
- const SMTSortRef &To) = 0;
-
- /// Creates a floating-point conversion from floatint-point to unsigned
- /// bitvector operation
- virtual SMTExprRef mkFPtoUBV(const SMTExprRef &From,
- const SMTSortRef &To) = 0;
-
/// Creates a floating-point conversion from signed bitvector to
/// floatint-point operation
- virtual SMTExprRef mkSBVtoFP(const SMTExprRef &From, unsigned ToWidth) = 0;
+ virtual SMTExprRef mkSBVtoFP(const SMTExprRef &From,
+ const SMTSortRef &To) = 0;
/// Creates a floating-point conversion from unsigned bitvector to
/// floatint-point operation
- virtual SMTExprRef mkUBVtoFP(const SMTExprRef &From, unsigned ToWidth) = 0;
+ virtual SMTExprRef mkUBVtoFP(const SMTExprRef &From,
+ const SMTSortRef &To) = 0;
+
+ /// Creates a floating-point conversion from floatint-point to signed
+ /// bitvector operation
+ virtual SMTExprRef mkFPtoSBV(const SMTExprRef &From, unsigned ToWidth) = 0;
+
+ /// Creates a floating-point conversion from floatint-point to unsigned
+ /// bitvector operation
+ virtual SMTExprRef mkFPtoUBV(const SMTExprRef &From, unsigned ToWidth) = 0;
/// Creates a new symbol, given a name and a sort
virtual SMTExprRef mkSymbol(const char *Name, SMTSortRef Sort) = 0;
@@ -953,24 +273,8 @@ public:
virtual bool getInterpretation(const SMTExprRef &Exp,
llvm::APFloat &Float) = 0;
- /// Construct an SMTExprRef value from a boolean.
- virtual SMTExprRef fromBoolean(const bool Bool) = 0;
-
- /// Construct an SMTExprRef value from a finite APFloat.
- virtual SMTExprRef fromAPFloat(const llvm::APFloat &Float) = 0;
-
- /// Construct an SMTExprRef value from an APSInt.
- virtual SMTExprRef fromAPSInt(const llvm::APSInt &Int) = 0;
-
- /// Construct an SMTExprRef value from an integer.
- virtual SMTExprRef fromInt(const char *Int, uint64_t BitWidth) = 0;
-
- /// Construct an SMTExprRef from a SymbolData.
- virtual SMTExprRef fromData(const SymbolID ID, const QualType &Ty,
- uint64_t BitWidth) = 0;
-
/// Check if the constraints are satisfiable
- virtual ConditionTruthVal check() const = 0;
+ virtual Optional<bool> check() const = 0;
/// Push the current solver state
virtual void push() = 0;
@@ -979,7 +283,10 @@ public:
virtual void pop(unsigned NumStates = 1) = 0;
/// Reset the solver and remove all constraints.
- virtual void reset() const = 0;
+ virtual void reset() = 0;
+
+ /// Checks if the solver supports floating-points.
+ virtual bool isFPSupported() = 0;
virtual void print(raw_ostream &OS) const = 0;
};
@@ -988,7 +295,7 @@ public:
using SMTSolverRef = std::shared_ptr<SMTSolver>;
/// Convenience method to create and Z3Solver object
-std::unique_ptr<SMTSolver> CreateZ3Solver();
+SMTSolverRef CreateZ3Solver();
} // namespace ento
} // namespace clang
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
index 865014b22830..c9e284a1a3e8 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
@@ -139,8 +139,8 @@ public:
virtual SVal simplifySVal(ProgramStateRef State, SVal Val) = 0;
/// Constructs a symbolic expression for two non-location values.
- SVal makeSymExprValNN(ProgramStateRef state, BinaryOperator::Opcode op,
- NonLoc lhs, NonLoc rhs, QualType resultTy);
+ SVal makeSymExprValNN(BinaryOperator::Opcode op,
+ NonLoc lhs, NonLoc rhs, QualType resultTy);
SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op,
SVal lhs, SVal rhs, QualType type);
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
index 1b79bfc3f8cf..0efe96f67f8e 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
@@ -530,9 +530,7 @@ public:
return PTMDataType::getFromOpaqueValue(const_cast<void *>(Data));
}
- bool isNullMemberPointer() const {
- return getPTMData().isNull();
- }
+ bool isNullMemberPointer() const;
const DeclaratorDecl *getDecl() const;
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
index fc072a380074..f49f761c77eb 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
@@ -130,6 +130,8 @@ public:
/// used to query and manipulate MemRegion objects.
MemRegionManager& getRegionManager() { return MRMgr; }
+ SValBuilder& getSValBuilder() { return svalBuilder; }
+
virtual Loc getLValueVar(const VarDecl *VD, const LocationContext *LC) {
return svalBuilder.makeLoc(MRMgr.getVarRegion(VD, LC));
}
@@ -252,19 +254,18 @@ public:
virtual bool scanReachableSymbols(Store S, const MemRegion *R,
ScanReachableSymbols &Visitor) = 0;
- virtual void print(Store store, raw_ostream &Out,
- const char* nl, const char *sep) = 0;
+ virtual void print(Store store, raw_ostream &Out, const char* nl) = 0;
class BindingsHandler {
public:
virtual ~BindingsHandler();
+ /// \return whether the iteration should continue.
virtual bool HandleBinding(StoreManager& SMgr, Store store,
const MemRegion *region, SVal val) = 0;
};
- class FindUniqueBinding :
- public BindingsHandler {
+ class FindUniqueBinding : public BindingsHandler {
SymbolRef Sym;
const MemRegion* Binding = nullptr;
bool First = true;
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
index d6aa4feddff2..d745b0f51ab0 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
@@ -72,7 +72,7 @@ public:
/// Called by CoreEngine. Used to generate successor
/// nodes by processing the 'effects' of a branch condition.
- virtual void processBranch(const Stmt *Condition, const Stmt *Term,
+ virtual void processBranch(const Stmt *Condition,
NodeBuilderContext& BuilderCtx,
ExplodedNode *Pred,
ExplodedNodeSet &Dst,
@@ -156,7 +156,6 @@ public:
notifyCheckersOfPointerEscape(ProgramStateRef State,
const InvalidatedSymbols *Invalidated,
ArrayRef<const MemRegion *> ExplicitRegions,
- ArrayRef<const MemRegion *> Regions,
const CallEvent *Call,
RegionAndSymbolInvalidationTraits &HTraits) = 0;
@@ -167,7 +166,7 @@ public:
/// Called by CoreEngine when the analysis worklist is either empty or the
// maximum number of analysis steps have been reached.
- virtual void processEndWorklist(bool hasWorkRemaining) = 0;
+ virtual void processEndWorklist() = 0;
};
} // end GR namespace
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
index 074551962607..d02a8abd1148 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
@@ -309,7 +309,10 @@ protected:
BinarySymExpr(Kind k, BinaryOperator::Opcode op, QualType t)
: SymExpr(k), Op(op), T(t) {
assert(classof(this));
- assert(isValidTypeForSymbol(t));
+ // Binary expressions are results of arithmetic. Pointer arithmetic is not
+ // handled by binary expressions, but it is instead handled by applying
+ // sub-regions to regions.
+ assert(isValidTypeForSymbol(t) && !Loc::isLocType(t));
}
public:
@@ -555,7 +558,6 @@ class SymbolReaper {
SymbolMapTy TheLiving;
SymbolSetTy MetadataInUse;
- SymbolSetTy TheDead;
RegionSetTy RegionRoots;
@@ -600,21 +602,6 @@ public:
/// symbol marking has occurred, i.e. in the MarkLiveSymbols callback.
void markInUse(SymbolRef sym);
- /// If a symbol is known to be live, marks the symbol as live.
- ///
- /// Otherwise, if the symbol cannot be proven live, it is marked as dead.
- /// Returns true if the symbol is dead, false if live.
- bool maybeDead(SymbolRef sym);
-
- using dead_iterator = SymbolSetTy::const_iterator;
-
- dead_iterator dead_begin() const { return TheDead.begin(); }
- dead_iterator dead_end() const { return TheDead.end(); }
-
- bool hasDeadSymbols() const {
- return !TheDead.empty();
- }
-
using region_iterator = RegionSetTy::const_iterator;
region_iterator region_begin() const { return RegionRoots.begin(); }
@@ -623,9 +610,9 @@ public:
/// Returns whether or not a symbol has been confirmed dead.
///
/// This should only be called once all marking of dead symbols has completed.
- /// (For checkers, this means only in the evalDeadSymbols callback.)
- bool isDead(SymbolRef sym) const {
- return TheDead.count(sym);
+ /// (For checkers, this means only in the checkDeadSymbols callback.)
+ bool isDead(SymbolRef sym) {
+ return !isLive(sym);
}
void markLive(const MemRegion *region);
@@ -654,7 +641,7 @@ public:
/// The method returns \c true if symbols should continue be scanned and \c
/// false otherwise.
virtual bool VisitSymbol(SymbolRef sym) = 0;
- virtual bool VisitMemRegion(const MemRegion *region) { return true; }
+ virtual bool VisitMemRegion(const MemRegion *) { return true; }
};
} // namespace ento
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h
index ce19b7131d42..8218fb1eeafe 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h
@@ -34,10 +34,7 @@ using TaintMapImpl = llvm::ImmutableMap<SymbolRef, TaintTagType>;
template<> struct ProgramStateTrait<TaintMap>
: public ProgramStatePartialTrait<TaintMapImpl> {
- static void *GDMIndex() {
- static int index = 0;
- return &index;
- }
+ static void *GDMIndex();
};
/// The GDM component mapping derived symbols' parent symbols to their
@@ -49,10 +46,7 @@ using DerivedSymTaintImpl = llvm::ImmutableMap<SymbolRef, TaintedSubRegions>;
template<> struct ProgramStateTrait<DerivedSymTaint>
: public ProgramStatePartialTrait<DerivedSymTaintImpl> {
- static void *GDMIndex() {
- static int index;
- return &index;
- }
+ static void *GDMIndex();
};
class TaintManager {
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h b/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h
index 07edd35ff944..ef3c2694b283 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h
@@ -85,6 +85,7 @@ public:
static std::unique_ptr<WorkList> makeBFSBlockDFSContents();
static std::unique_ptr<WorkList> makeUnexploredFirst();
static std::unique_ptr<WorkList> makeUnexploredFirstPriorityQueue();
+ static std::unique_ptr<WorkList> makeUnexploredFirstPriorityLocationQueue();
};
} // end ento namespace
diff --git a/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h b/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
new file mode 100644
index 000000000000..4fcaa794c17b
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
@@ -0,0 +1,798 @@
+//=== RetainSummaryManager.h - Summaries for reference counting ---*- C++ -*--//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines summaries implementation for retain counting, which
+// implements a reference count checker for Core Foundation and Cocoa
+// on (Mac OS X).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYZER_CORE_RETAINSUMMARYMANAGER
+#define LLVM_CLANG_ANALYZER_CORE_RETAINSUMMARYMANAGER
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "clang/AST/Attr.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/ParentMap.h"
+#include "clang/Analysis/SelectorExtras.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "llvm/ADT/STLExtras.h"
+
+//===----------------------------------------------------------------------===//
+// Adapters for FoldingSet.
+//===----------------------------------------------------------------------===//
+
+using namespace clang;
+using namespace ento;
+
+namespace clang {
+namespace ento {
+
+/// Determines the object kind of a tracked object.
+enum class ObjKind {
+ /// Indicates that the tracked object is a CF object.
+ CF,
+
+ /// Indicates that the tracked object is an Objective-C object.
+ ObjC,
+
+ /// Indicates that the tracked object could be a CF or Objective-C object.
+ AnyObj,
+
+ /// Indicates that the tracked object is a generalized object.
+ Generalized,
+
+ /// Indicates that the tracking object is a descendant of a
+ /// referenced-counted OSObject, used in the Darwin kernel.
+ OS
+};
+
+enum ArgEffectKind {
+ /// There is no effect.
+ DoNothing,
+
+ /// The argument is treated as if an -autorelease message had been sent to
+ /// the referenced object.
+ Autorelease,
+
+ /// The argument is treated as if the referenced object was deallocated.
+ Dealloc,
+
+ /// The argument has its reference count decreased by 1.
+ DecRef,
+
+ /// The argument has its reference count decreased by 1 to model
+ /// a transferred bridge cast under ARC.
+ DecRefBridgedTransferred,
+
+ /// The argument has its reference count increased by 1.
+ IncRef,
+
+ /// The argument is a pointer to a retain-counted object; on exit, the new
+ /// value of the pointer is a +0 value.
+ UnretainedOutParameter,
+
+ /// The argument is a pointer to a retain-counted object; on exit, the new
+ /// value of the pointer is a +1 value.
+ RetainedOutParameter,
+
+ /// The argument is a pointer to a retain-counted object; on exit, the new
+ /// value of the pointer is a +1 value iff the return code is zero.
+ RetainedOutParameterOnZero,
+
+ /// The argument is a pointer to a retain-counted object; on exit, the new
+ /// value of the pointer is a +1 value iff the return code is non-zero.
+ RetainedOutParameterOnNonZero,
+
+ /// The argument is treated as potentially escaping, meaning that
+ /// even when its reference count hits 0 it should be treated as still
+ /// possibly being alive as someone else *may* be holding onto the object.
+ MayEscape,
+
+ /// All typestate tracking of the object ceases. This is usually employed
+ /// when the effect of the call is completely unknown.
+ StopTracking,
+
+ /// All typestate tracking of the object ceases. Unlike StopTracking,
+ /// this is also enforced when the method body is inlined.
+ ///
+ /// In some cases, we obtain a better summary for this checker
+ /// by looking at the call site than by inlining the function.
+ /// Signifies that we should stop tracking the symbol even if
+ /// the function is inlined.
+ StopTrackingHard,
+
+ /// Performs the combined functionality of DecRef and StopTrackingHard.
+ ///
+ /// The models the effect that the called function decrements the reference
+ /// count of the argument and all typestate tracking on that argument
+ /// should cease.
+ DecRefAndStopTrackingHard,
+};
+
+/// An ArgEffect summarizes the retain count behavior on an argument or receiver
+/// to a function or method.
+class ArgEffect {
+ ArgEffectKind K;
+ ObjKind O;
+public:
+ explicit ArgEffect(ArgEffectKind K = DoNothing, ObjKind O = ObjKind::AnyObj)
+ : K(K), O(O) {}
+
+ ArgEffectKind getKind() const { return K; }
+ ObjKind getObjKind() const { return O; }
+
+ ArgEffect withKind(ArgEffectKind NewK) {
+ return ArgEffect(NewK, O);
+ }
+
+ bool operator==(const ArgEffect &Other) const {
+ return K == Other.K && O == Other.O;
+ }
+};
+
+/// RetEffect summarizes a call's retain/release behavior with respect
+/// to its return value.
+class RetEffect {
+public:
+ enum Kind {
+ /// Indicates that no retain count information is tracked for
+ /// the return value.
+ NoRet,
+
+ /// Indicates that the returned value is an owned (+1) symbol.
+ OwnedSymbol,
+
+ /// Indicates that the returned value is an object with retain count
+ /// semantics but that it is not owned (+0). This is the default
+ /// for getters, etc.
+ NotOwnedSymbol,
+
+ /// Indicates that the return value is an owned object when the
+ /// receiver is also a tracked object.
+ OwnedWhenTrackedReceiver,
+
+ // Treat this function as returning a non-tracked symbol even if
+ // the function has been inlined. This is used where the call
+ // site summary is more precise than the summary indirectly produced
+ // by inlining the function
+ NoRetHard
+ };
+
+private:
+ Kind K;
+ ObjKind O;
+
+ RetEffect(Kind k, ObjKind o = ObjKind::AnyObj) : K(k), O(o) {}
+
+public:
+ Kind getKind() const { return K; }
+
+ ObjKind getObjKind() const { return O; }
+
+ bool isOwned() const {
+ return K == OwnedSymbol || K == OwnedWhenTrackedReceiver;
+ }
+
+ bool notOwned() const {
+ return K == NotOwnedSymbol;
+ }
+
+ bool operator==(const RetEffect &Other) const {
+ return K == Other.K && O == Other.O;
+ }
+
+ static RetEffect MakeOwnedWhenTrackedReceiver() {
+ return RetEffect(OwnedWhenTrackedReceiver, ObjKind::ObjC);
+ }
+
+ static RetEffect MakeOwned(ObjKind o) {
+ return RetEffect(OwnedSymbol, o);
+ }
+ static RetEffect MakeNotOwned(ObjKind o) {
+ return RetEffect(NotOwnedSymbol, o);
+ }
+ static RetEffect MakeNoRet() {
+ return RetEffect(NoRet);
+ }
+ static RetEffect MakeNoRetHard() {
+ return RetEffect(NoRetHard);
+ }
+};
+
+/// Encapsulates the retain count semantics on the arguments, return value,
+/// and receiver (if any) of a function/method call.
+///
+/// Note that construction of these objects is not highly efficient. That
+/// is okay for clients where creating these objects isn't really a bottleneck.
+/// The purpose of the API is to provide something simple. The actual
+/// static analyzer checker that implements retain/release typestate
+/// tracking uses something more efficient.
+class CallEffects {
+ llvm::SmallVector<ArgEffect, 10> Args;
+ RetEffect Ret;
+ ArgEffect Receiver;
+
+ CallEffects(const RetEffect &R,
+ ArgEffect Receiver = ArgEffect(DoNothing, ObjKind::AnyObj))
+ : Ret(R), Receiver(Receiver) {}
+
+public:
+ /// Returns the argument effects for a call.
+ ArrayRef<ArgEffect> getArgs() const { return Args; }
+
+ /// Returns the effects on the receiver.
+ ArgEffect getReceiver() const { return Receiver; }
+
+ /// Returns the effect on the return value.
+ RetEffect getReturnValue() const { return Ret; }
+
+ /// Return the CallEfect for a given Objective-C method.
+ static CallEffects getEffect(const ObjCMethodDecl *MD);
+
+ /// Return the CallEfect for a given C/C++ function.
+ static CallEffects getEffect(const FunctionDecl *FD);
+};
+
+/// A key identifying a summary.
+class ObjCSummaryKey {
+ IdentifierInfo* II;
+ Selector S;
+public:
+ ObjCSummaryKey(IdentifierInfo* ii, Selector s)
+ : II(ii), S(s) {}
+
+ ObjCSummaryKey(const ObjCInterfaceDecl *d, Selector s)
+ : II(d ? d->getIdentifier() : nullptr), S(s) {}
+
+ ObjCSummaryKey(Selector s)
+ : II(nullptr), S(s) {}
+
+ IdentifierInfo *getIdentifier() const { return II; }
+ Selector getSelector() const { return S; }
+};
+
+} // end namespace ento
+} // end namespace clang
+
+
+namespace llvm {
+
+template <> struct FoldingSetTrait<ArgEffect> {
+static inline void Profile(const ArgEffect X, FoldingSetNodeID &ID) {
+ ID.AddInteger((unsigned) X.getKind());
+ ID.AddInteger((unsigned) X.getObjKind());
+}
+};
+template <> struct FoldingSetTrait<RetEffect> {
+ static inline void Profile(const RetEffect &X, FoldingSetNodeID &ID) {
+ ID.AddInteger((unsigned) X.getKind());
+ ID.AddInteger((unsigned) X.getObjKind());
+}
+};
+
+template <> struct DenseMapInfo<ObjCSummaryKey> {
+ static inline ObjCSummaryKey getEmptyKey() {
+ return ObjCSummaryKey(DenseMapInfo<IdentifierInfo*>::getEmptyKey(),
+ DenseMapInfo<Selector>::getEmptyKey());
+ }
+
+ static inline ObjCSummaryKey getTombstoneKey() {
+ return ObjCSummaryKey(DenseMapInfo<IdentifierInfo*>::getTombstoneKey(),
+ DenseMapInfo<Selector>::getTombstoneKey());
+ }
+
+ static unsigned getHashValue(const ObjCSummaryKey &V) {
+ typedef std::pair<IdentifierInfo*, Selector> PairTy;
+ return DenseMapInfo<PairTy>::getHashValue(PairTy(V.getIdentifier(),
+ V.getSelector()));
+ }
+
+ static bool isEqual(const ObjCSummaryKey& LHS, const ObjCSummaryKey& RHS) {
+ return LHS.getIdentifier() == RHS.getIdentifier() &&
+ LHS.getSelector() == RHS.getSelector();
+ }
+
+};
+
+} // end llvm namespace
+
+
+namespace clang {
+namespace ento {
+
+/// ArgEffects summarizes the effects of a function/method call on all of
+/// its arguments.
+typedef llvm::ImmutableMap<unsigned, ArgEffect> ArgEffects;
+
+/// Summary for a function with respect to ownership changes.
+class RetainSummary {
+ /// Args - a map of (index, ArgEffect) pairs, where index
+ /// specifies the argument (starting from 0). This can be sparsely
+ /// populated; arguments with no entry in Args use 'DefaultArgEffect'.
+ ArgEffects Args;
+
+ /// DefaultArgEffect - The default ArgEffect to apply to arguments that
+ /// do not have an entry in Args.
+ ArgEffect DefaultArgEffect;
+
+ /// Receiver - If this summary applies to an Objective-C message expression,
+ /// this is the effect applied to the state of the receiver.
+ ArgEffect Receiver;
+
+ /// Effect on "this" pointer - applicable only to C++ method calls.
+ ArgEffect This;
+
+ /// Ret - The effect on the return value. Used to indicate if the
+ /// function/method call returns a new tracked symbol.
+ RetEffect Ret;
+
+public:
+ RetainSummary(ArgEffects A,
+ RetEffect R,
+ ArgEffect defaultEff,
+ ArgEffect ReceiverEff,
+ ArgEffect ThisEff)
+ : Args(A), DefaultArgEffect(defaultEff), Receiver(ReceiverEff),
+ This(ThisEff), Ret(R) {}
+
+ /// getArg - Return the argument effect on the argument specified by
+ /// idx (starting from 0).
+ ArgEffect getArg(unsigned idx) const {
+ if (const ArgEffect *AE = Args.lookup(idx))
+ return *AE;
+
+ return DefaultArgEffect;
+ }
+
+ void addArg(ArgEffects::Factory &af, unsigned idx, ArgEffect e) {
+ Args = af.add(Args, idx, e);
+ }
+
+ /// setDefaultArgEffect - Set the default argument effect.
+ void setDefaultArgEffect(ArgEffect E) {
+ DefaultArgEffect = E;
+ }
+
+ /// getRetEffect - Returns the effect on the return value of the call.
+ RetEffect getRetEffect() const { return Ret; }
+
+ /// setRetEffect - Set the effect of the return value of the call.
+ void setRetEffect(RetEffect E) { Ret = E; }
+
+
+ /// Sets the effect on the receiver of the message.
+ void setReceiverEffect(ArgEffect e) { Receiver = e; }
+
+ /// getReceiverEffect - Returns the effect on the receiver of the call.
+ /// This is only meaningful if the summary applies to an ObjCMessageExpr*.
+ ArgEffect getReceiverEffect() const { return Receiver; }
+
+ /// \return the effect on the "this" receiver of the method call.
+ /// This is only meaningful if the summary applies to CXXMethodDecl*.
+ ArgEffect getThisEffect() const { return This; }
+
+ /// Set the effect of the method on "this".
+ void setThisEffect(ArgEffect e) { This = e; }
+
+ bool isNoop() const {
+ return Ret == RetEffect::MakeNoRet() && Receiver.getKind() == DoNothing
+ && DefaultArgEffect.getKind() == MayEscape && This.getKind() == DoNothing
+ && Args.isEmpty();
+ }
+
+ /// Test if two retain summaries are identical. Note that merely equivalent
+ /// summaries are not necessarily identical (for example, if an explicit
+ /// argument effect matches the default effect).
+ bool operator==(const RetainSummary &Other) const {
+ return Args == Other.Args && DefaultArgEffect == Other.DefaultArgEffect &&
+ Receiver == Other.Receiver && This == Other.This && Ret == Other.Ret;
+ }
+
+ /// Profile this summary for inclusion in a FoldingSet.
+ void Profile(llvm::FoldingSetNodeID& ID) const {
+ ID.Add(Args);
+ ID.Add(DefaultArgEffect);
+ ID.Add(Receiver);
+ ID.Add(This);
+ ID.Add(Ret);
+ }
+
+ /// A retain summary is simple if it has no ArgEffects other than the default.
+ bool isSimple() const {
+ return Args.isEmpty();
+ }
+
+ ArgEffects getArgEffects() const { return Args; }
+
+private:
+ ArgEffect getDefaultArgEffect() const { return DefaultArgEffect; }
+
+ friend class RetainSummaryManager;
+};
+
+class ObjCSummaryCache {
+ typedef llvm::DenseMap<ObjCSummaryKey, const RetainSummary *> MapTy;
+ MapTy M;
+public:
+ ObjCSummaryCache() {}
+
+ const RetainSummary * find(const ObjCInterfaceDecl *D, Selector S) {
+ // Do a lookup with the (D,S) pair. If we find a match return
+ // the iterator.
+ ObjCSummaryKey K(D, S);
+ MapTy::iterator I = M.find(K);
+
+ if (I != M.end())
+ return I->second;
+ if (!D)
+ return nullptr;
+
+ // Walk the super chain. If we find a hit with a parent, we'll end
+ // up returning that summary. We actually allow that key (null,S), as
+ // we cache summaries for the null ObjCInterfaceDecl* to allow us to
+ // generate initial summaries without having to worry about NSObject
+ // being declared.
+ // FIXME: We may change this at some point.
+ for (ObjCInterfaceDecl *C=D->getSuperClass() ;; C=C->getSuperClass()) {
+ if ((I = M.find(ObjCSummaryKey(C, S))) != M.end())
+ break;
+
+ if (!C)
+ return nullptr;
+ }
+
+ // Cache the summary with original key to make the next lookup faster
+ // and return the iterator.
+ const RetainSummary *Summ = I->second;
+ M[K] = Summ;
+ return Summ;
+ }
+
+ const RetainSummary *find(IdentifierInfo* II, Selector S) {
+ // FIXME: Class method lookup. Right now we don't have a good way
+ // of going between IdentifierInfo* and the class hierarchy.
+ MapTy::iterator I = M.find(ObjCSummaryKey(II, S));
+
+ if (I == M.end())
+ I = M.find(ObjCSummaryKey(S));
+
+ return I == M.end() ? nullptr : I->second;
+ }
+
+ const RetainSummary *& operator[](ObjCSummaryKey K) {
+ return M[K];
+ }
+
+ const RetainSummary *& operator[](Selector S) {
+ return M[ ObjCSummaryKey(S) ];
+ }
+};
+
+class RetainSummaryTemplate;
+
+class RetainSummaryManager {
+ typedef llvm::DenseMap<const FunctionDecl*, const RetainSummary *>
+ FuncSummariesTy;
+
+ typedef ObjCSummaryCache ObjCMethodSummariesTy;
+
+ typedef llvm::FoldingSetNodeWrapper<RetainSummary> CachedSummaryNode;
+
+ /// Ctx - The ASTContext object for the analyzed ASTs.
+ ASTContext &Ctx;
+
+ /// Records whether or not the analyzed code runs in ARC mode.
+ const bool ARCEnabled;
+
+ /// Track Objective-C and CoreFoundation objects.
+ const bool TrackObjCAndCFObjects;
+
+ /// Track sublcasses of OSObject.
+ const bool TrackOSObjects;
+
+ /// FuncSummaries - A map from FunctionDecls to summaries.
+ FuncSummariesTy FuncSummaries;
+
+ /// ObjCClassMethodSummaries - A map from selectors (for instance methods)
+ /// to summaries.
+ ObjCMethodSummariesTy ObjCClassMethodSummaries;
+
+ /// ObjCMethodSummaries - A map from selectors to summaries.
+ ObjCMethodSummariesTy ObjCMethodSummaries;
+
+ /// BPAlloc - A BumpPtrAllocator used for allocating summaries, ArgEffects,
+ /// and all other data used by the checker.
+ llvm::BumpPtrAllocator BPAlloc;
+
+ /// AF - A factory for ArgEffects objects.
+ ArgEffects::Factory AF;
+
+ /// ObjCAllocRetE - Default return effect for methods returning Objective-C
+ /// objects.
+ RetEffect ObjCAllocRetE;
+
+ /// ObjCInitRetE - Default return effect for init methods returning
+ /// Objective-C objects.
+ RetEffect ObjCInitRetE;
+
+ /// SimpleSummaries - Used for uniquing summaries that don't have special
+ /// effects.
+ llvm::FoldingSet<CachedSummaryNode> SimpleSummaries;
+
+ /// Create an OS object at +1.
+ const RetainSummary *getOSSummaryCreateRule(const FunctionDecl *FD);
+
+ /// Get an OS object at +0.
+ const RetainSummary *getOSSummaryGetRule(const FunctionDecl *FD);
+
+ /// Increment the reference count on OS object.
+ const RetainSummary *getOSSummaryRetainRule(const FunctionDecl *FD);
+
+ /// Decrement the reference count on OS object.
+ const RetainSummary *getOSSummaryReleaseRule(const FunctionDecl *FD);
+
+ /// Free the OS object.
+ const RetainSummary *getOSSummaryFreeRule(const FunctionDecl *FD);
+
+ const RetainSummary *getUnarySummary(const FunctionType* FT,
+ ArgEffectKind AE);
+
+ const RetainSummary *getCFSummaryCreateRule(const FunctionDecl *FD);
+ const RetainSummary *getCFSummaryGetRule(const FunctionDecl *FD);
+ const RetainSummary *getCFCreateGetRuleSummary(const FunctionDecl *FD);
+
+ const RetainSummary *getPersistentSummary(const RetainSummary &OldSumm);
+
+ const RetainSummary *
+ getPersistentSummary(RetEffect RetEff, ArgEffects ScratchArgs,
+ ArgEffect ReceiverEff = ArgEffect(DoNothing),
+ ArgEffect DefaultEff = ArgEffect(MayEscape),
+ ArgEffect ThisEff = ArgEffect(DoNothing)) {
+ RetainSummary Summ(ScratchArgs, RetEff, DefaultEff, ReceiverEff, ThisEff);
+ return getPersistentSummary(Summ);
+ }
+
+ const RetainSummary *getDoNothingSummary() {
+ return getPersistentSummary(RetEffect::MakeNoRet(),
+ ArgEffects(AF.getEmptyMap()),
+ ArgEffect(DoNothing), ArgEffect(DoNothing));
+ }
+
+ const RetainSummary *getDefaultSummary() {
+ return getPersistentSummary(RetEffect::MakeNoRet(),
+ ArgEffects(AF.getEmptyMap()),
+ ArgEffect(DoNothing), ArgEffect(MayEscape));
+ }
+
+ const RetainSummary *getPersistentStopSummary() {
+ return getPersistentSummary(
+ RetEffect::MakeNoRet(), ArgEffects(AF.getEmptyMap()),
+ ArgEffect(StopTracking), ArgEffect(StopTracking));
+ }
+
+ void InitializeClassMethodSummaries();
+ void InitializeMethodSummaries();
+
+ void addNSObjectClsMethSummary(Selector S, const RetainSummary *Summ) {
+ ObjCClassMethodSummaries[S] = Summ;
+ }
+
+ void addNSObjectMethSummary(Selector S, const RetainSummary *Summ) {
+ ObjCMethodSummaries[S] = Summ;
+ }
+
+ void addClassMethSummary(const char* Cls, const char* name,
+ const RetainSummary *Summ, bool isNullary = true) {
+ IdentifierInfo* ClsII = &Ctx.Idents.get(Cls);
+ Selector S = isNullary ? GetNullarySelector(name, Ctx)
+ : GetUnarySelector(name, Ctx);
+ ObjCClassMethodSummaries[ObjCSummaryKey(ClsII, S)] = Summ;
+ }
+
+ void addInstMethSummary(const char* Cls, const char* nullaryName,
+ const RetainSummary *Summ) {
+ IdentifierInfo* ClsII = &Ctx.Idents.get(Cls);
+ Selector S = GetNullarySelector(nullaryName, Ctx);
+ ObjCMethodSummaries[ObjCSummaryKey(ClsII, S)] = Summ;
+ }
+
+ template <typename... Keywords>
+ void addMethodSummary(IdentifierInfo *ClsII, ObjCMethodSummariesTy &Summaries,
+ const RetainSummary *Summ, Keywords *... Kws) {
+ Selector S = getKeywordSelector(Ctx, Kws...);
+ Summaries[ObjCSummaryKey(ClsII, S)] = Summ;
+ }
+
+ template <typename... Keywords>
+ void addInstMethSummary(const char *Cls, const RetainSummary *Summ,
+ Keywords *... Kws) {
+ addMethodSummary(&Ctx.Idents.get(Cls), ObjCMethodSummaries, Summ, Kws...);
+ }
+
+ template <typename... Keywords>
+ void addClsMethSummary(const char *Cls, const RetainSummary *Summ,
+ Keywords *... Kws) {
+ addMethodSummary(&Ctx.Idents.get(Cls), ObjCClassMethodSummaries, Summ,
+ Kws...);
+ }
+
+ template <typename... Keywords>
+ void addClsMethSummary(IdentifierInfo *II, const RetainSummary *Summ,
+ Keywords *... Kws) {
+ addMethodSummary(II, ObjCClassMethodSummaries, Summ, Kws...);
+ }
+
+ const RetainSummary * generateSummary(const FunctionDecl *FD,
+ bool &AllowAnnotations);
+
+ /// Return a summary for OSObject, or nullptr if not found.
+ const RetainSummary *getSummaryForOSObject(const FunctionDecl *FD,
+ StringRef FName, QualType RetTy);
+
+ /// Return a summary for Objective-C or CF object, or nullptr if not found.
+ const RetainSummary *getSummaryForObjCOrCFObject(
+ const FunctionDecl *FD,
+ StringRef FName,
+ QualType RetTy,
+ const FunctionType *FT,
+ bool &AllowAnnotations);
+
+ /// Apply the annotation of {@code pd} in function {@code FD}
+ /// to the resulting summary stored in out-parameter {@code Template}.
+ /// \return whether an annotation was applied.
+ bool applyParamAnnotationEffect(const ParmVarDecl *pd, unsigned parm_idx,
+ const NamedDecl *FD,
+ RetainSummaryTemplate &Template);
+
+public:
+ RetainSummaryManager(ASTContext &ctx,
+ bool usesARC,
+ bool trackObjCAndCFObjects,
+ bool trackOSObjects)
+ : Ctx(ctx),
+ ARCEnabled(usesARC),
+ TrackObjCAndCFObjects(trackObjCAndCFObjects),
+ TrackOSObjects(trackOSObjects),
+ AF(BPAlloc),
+ ObjCAllocRetE(usesARC ? RetEffect::MakeNotOwned(ObjKind::ObjC)
+ : RetEffect::MakeOwned(ObjKind::ObjC)),
+ ObjCInitRetE(usesARC ? RetEffect::MakeNotOwned(ObjKind::ObjC)
+ : RetEffect::MakeOwnedWhenTrackedReceiver()) {
+ InitializeClassMethodSummaries();
+ InitializeMethodSummaries();
+ }
+
+ enum class BehaviorSummary {
+ // Function does not return.
+ NoOp,
+
+ // Function returns the first argument.
+ Identity,
+
+ // Function either returns zero, or the input parameter.
+ IdentityOrZero
+ };
+
+ Optional<BehaviorSummary> canEval(const CallExpr *CE, const FunctionDecl *FD,
+ bool &hasTrustedImplementationAnnotation);
+
+ bool isTrustedReferenceCountImplementation(const FunctionDecl *FD);
+
+ const RetainSummary *getSummary(const CallEvent &Call,
+ QualType ReceiverType=QualType());
+
+ const RetainSummary *getFunctionSummary(const FunctionDecl *FD);
+
+ const RetainSummary *getMethodSummary(Selector S, const ObjCInterfaceDecl *ID,
+ const ObjCMethodDecl *MD,
+ QualType RetTy,
+ ObjCMethodSummariesTy &CachedSummaries);
+
+ const RetainSummary *
+ getInstanceMethodSummary(const ObjCMethodCall &M,
+ QualType ReceiverType);
+
+ const RetainSummary *getClassMethodSummary(const ObjCMethodCall &M) {
+ assert(!M.isInstanceMessage());
+ const ObjCInterfaceDecl *Class = M.getReceiverInterface();
+
+ return getMethodSummary(M.getSelector(), Class, M.getDecl(),
+ M.getResultType(), ObjCClassMethodSummaries);
+ }
+
+ /// getMethodSummary - This version of getMethodSummary is used to query
+ /// the summary for the current method being analyzed.
+ const RetainSummary *getMethodSummary(const ObjCMethodDecl *MD) {
+ const ObjCInterfaceDecl *ID = MD->getClassInterface();
+ Selector S = MD->getSelector();
+ QualType ResultTy = MD->getReturnType();
+
+ ObjCMethodSummariesTy *CachedSummaries;
+ if (MD->isInstanceMethod())
+ CachedSummaries = &ObjCMethodSummaries;
+ else
+ CachedSummaries = &ObjCClassMethodSummaries;
+
+ return getMethodSummary(S, ID, MD, ResultTy, *CachedSummaries);
+ }
+
+ const RetainSummary *getStandardMethodSummary(const ObjCMethodDecl *MD,
+ Selector S, QualType RetTy);
+
+ /// Determine if there is a special return effect for this function or method.
+ Optional<RetEffect> getRetEffectFromAnnotations(QualType RetTy,
+ const Decl *D);
+
+ void updateSummaryFromAnnotations(const RetainSummary *&Summ,
+ const ObjCMethodDecl *MD);
+
+ void updateSummaryFromAnnotations(const RetainSummary *&Summ,
+ const FunctionDecl *FD);
+
+
+ void updateSummaryForCall(const RetainSummary *&Summ,
+ const CallEvent &Call);
+
+ bool isARCEnabled() const { return ARCEnabled; }
+
+ RetEffect getObjAllocRetEffect() const { return ObjCAllocRetE; }
+
+ /// Determine whether a declaration {@code D} of correspondent type (return
+ /// type for functions/methods) {@code QT} has any of the given attributes,
+ /// provided they pass necessary validation checks AND tracking the given
+ /// attribute is enabled.
+ /// Returns the object kind corresponding to the present attribute, or None,
+ /// if none of the specified attributes are present.
+ /// Crashes if passed an attribute which is not explicitly handled.
+ template <class T>
+ Optional<ObjKind> hasAnyEnabledAttrOf(const Decl *D, QualType QT);
+
+ template <class T1, class T2, class... Others>
+ Optional<ObjKind> hasAnyEnabledAttrOf(const Decl *D, QualType QT);
+
+ friend class RetainSummaryTemplate;
+};
+
+
+// Used to avoid allocating long-term (BPAlloc'd) memory for default retain
+// summaries. If a function or method looks like it has a default summary, but
+// it has annotations, the annotations are added to the stack-based template
+// and then copied into managed memory.
+class RetainSummaryTemplate {
+ RetainSummaryManager &Manager;
+ const RetainSummary *&RealSummary;
+ RetainSummary ScratchSummary;
+ bool Accessed;
+public:
+ RetainSummaryTemplate(const RetainSummary *&real, RetainSummaryManager &mgr)
+ : Manager(mgr), RealSummary(real), ScratchSummary(*real), Accessed(false) {}
+
+ ~RetainSummaryTemplate() {
+ if (Accessed)
+ RealSummary = Manager.getPersistentSummary(ScratchSummary);
+ }
+
+ RetainSummary &operator*() {
+ Accessed = true;
+ return ScratchSummary;
+ }
+
+ RetainSummary *operator->() {
+ Accessed = true;
+ return &ScratchSummary;
+ }
+};
+
+} // end namespace ento
+} // end namespace clang
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h b/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h
index 216a2359efba..61709548aed1 100644
--- a/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h
+++ b/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h
@@ -10,6 +10,7 @@
#ifndef LLVM_CLANG_STATICANALYZER_FRONTEND_CHECKERREGISTRATION_H
#define LLVM_CLANG_STATICANALYZER_FRONTEND_CHECKERREGISTRATION_H
+#include "clang/AST/ASTContext.h"
#include "clang/Basic/LLVM.h"
#include <functional>
#include <memory>
@@ -25,7 +26,8 @@ namespace ento {
class CheckerRegistry;
std::unique_ptr<CheckerManager> createCheckerManager(
- AnalyzerOptions &opts, const LangOptions &langOpts,
+ ASTContext &context,
+ AnalyzerOptions &opts,
ArrayRef<std::string> plugins,
ArrayRef<std::function<void(CheckerRegistry &)>> checkerRegistrationFns,
DiagnosticsEngine &diags);
diff --git a/include/clang/StaticAnalyzer/Core/CheckerRegistry.h b/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
index d580dda73488..966234492fe0 100644
--- a/include/clang/StaticAnalyzer/Core/CheckerRegistry.h
+++ b/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
@@ -73,8 +73,6 @@ class DiagnosticsEngine;
namespace ento {
-class CheckerOptInfo;
-
/// Manages a set of available checkers for running a static analysis.
/// The checkers are organized into packages by full name, where including
/// a package will recursively include all subpackages and checkers within it.
@@ -83,6 +81,8 @@ class CheckerOptInfo;
/// "core.builtin", or the full name "core.builtin.NoReturnFunctionChecker".
class CheckerRegistry {
public:
+ CheckerRegistry(ArrayRef<std::string> plugins, DiagnosticsEngine &diags);
+
/// Initialization functions perform any necessary setup for a checker.
/// They should include a call to CheckerManager::registerChecker.
using InitializationFunction = void (*)(CheckerManager &);
@@ -91,12 +91,16 @@ public:
InitializationFunction Initialize;
StringRef FullName;
StringRef Desc;
+ StringRef DocumentationUri;
- CheckerInfo(InitializationFunction fn, StringRef name, StringRef desc)
- : Initialize(fn), FullName(name), Desc(desc) {}
+ CheckerInfo(InitializationFunction Fn, StringRef Name, StringRef Desc,
+ StringRef DocsUri)
+ : Initialize(Fn), FullName(Name), Desc(Desc),
+ DocumentationUri(DocsUri) {}
};
using CheckerInfoList = std::vector<CheckerInfo>;
+ using CheckerInfoSet = llvm::SetVector<const CheckerRegistry::CheckerInfo *>;
private:
template <typename T>
@@ -107,16 +111,16 @@ private:
public:
/// Adds a checker to the registry. Use this non-templated overload when your
/// checker requires custom initialization.
- void addChecker(InitializationFunction fn, StringRef fullName,
- StringRef desc);
+ void addChecker(InitializationFunction Fn, StringRef FullName, StringRef Desc,
+ StringRef DocsUri);
/// Adds a checker to the registry. Use this templated overload when your
/// checker does not require any custom initialization.
template <class T>
- void addChecker(StringRef fullName, StringRef desc) {
+ void addChecker(StringRef FullName, StringRef Desc, StringRef DocsUri) {
// Avoid MSVC's Compiler Error C2276:
// http://msdn.microsoft.com/en-us/library/850cstw1(v=VS.80).aspx
- addChecker(&CheckerRegistry::initializeManager<T>, fullName, desc);
+ addChecker(&CheckerRegistry::initializeManager<T>, FullName, Desc, DocsUri);
}
/// Initializes a CheckerManager by calling the initialization functions for
@@ -124,21 +128,22 @@ public:
/// list is significant; later options can be used to reverse earlier ones.
/// This can be used to exclude certain checkers in an included package.
void initializeManager(CheckerManager &mgr,
- SmallVectorImpl<CheckerOptInfo> &opts) const;
+ const AnalyzerOptions &Opts) const;
/// Check if every option corresponds to a specific checker or package.
- void validateCheckerOptions(const AnalyzerOptions &opts,
- DiagnosticsEngine &diags) const;
+ void validateCheckerOptions(const AnalyzerOptions &opts) const;
/// Prints the name and description of all checkers in this registry.
/// This output is not intended to be machine-parseable.
void printHelp(raw_ostream &out, size_t maxNameChars = 30) const;
- void printList(raw_ostream &out,
- SmallVectorImpl<CheckerOptInfo> &opts) const;
+ void printList(raw_ostream &out, const AnalyzerOptions &opts) const;
private:
+ CheckerInfoSet getEnabledCheckers(const AnalyzerOptions &Opts) const;
+
mutable CheckerInfoList Checkers;
mutable llvm::StringMap<size_t> Packages;
+ DiagnosticsEngine &Diags;
};
} // namespace ento
diff --git a/include/clang/StaticAnalyzer/Frontend/FrontendActions.h b/include/clang/StaticAnalyzer/Frontend/FrontendActions.h
index ba37b7f59a02..2e9d0502e6f3 100644
--- a/include/clang/StaticAnalyzer/Frontend/FrontendActions.h
+++ b/include/clang/StaticAnalyzer/Frontend/FrontendActions.h
@@ -52,9 +52,12 @@ private:
llvm::StringMap<Stmt *> &Bodies;
};
-void printCheckerHelp(raw_ostream &OS, ArrayRef<std::string> plugins);
+void printCheckerHelp(raw_ostream &OS, ArrayRef<std::string> plugins,
+ DiagnosticsEngine &diags);
void printEnabledCheckerList(raw_ostream &OS, ArrayRef<std::string> plugins,
- const AnalyzerOptions &opts);
+ const AnalyzerOptions &opts,
+ DiagnosticsEngine &diags);
+void printAnalyzerConfigList(raw_ostream &OS);
} // end GR namespace
diff --git a/include/clang/Tooling/AllTUsExecution.h b/include/clang/Tooling/AllTUsExecution.h
index f199365dc815..94bf01632fb4 100644
--- a/include/clang/Tooling/AllTUsExecution.h
+++ b/include/clang/Tooling/AllTUsExecution.h
@@ -45,6 +45,8 @@ public:
StringRef getExecutorName() const override { return ExecutorName; }
+ bool isSingleProcess() const override { return true; }
+
using ToolExecutor::execute;
llvm::Error
@@ -70,6 +72,8 @@ private:
unsigned ThreadCount;
};
+extern llvm::cl::opt<std::string> Filter;
+
} // end namespace tooling
} // end namespace clang
diff --git a/include/clang/Tooling/CompilationDatabase.h b/include/clang/Tooling/CompilationDatabase.h
index 37e515fdc09e..aa07cc30e5f5 100644
--- a/include/clang/Tooling/CompilationDatabase.h
+++ b/include/clang/Tooling/CompilationDatabase.h
@@ -141,27 +141,6 @@ public:
virtual std::vector<CompileCommand> getAllCompileCommands() const;
};
-/// Interface for compilation database plugins.
-///
-/// A compilation database plugin allows the user to register custom compilation
-/// databases that are picked up as compilation database if the corresponding
-/// library is linked in. To register a plugin, declare a static variable like:
-///
-/// \code
-/// static CompilationDatabasePluginRegistry::Add<MyDatabasePlugin>
-/// X("my-compilation-database", "Reads my own compilation database");
-/// \endcode
-class CompilationDatabasePlugin {
-public:
- virtual ~CompilationDatabasePlugin();
-
- /// Loads a compilation database from a build directory.
- ///
- /// \see CompilationDatabase::loadFromDirectory().
- virtual std::unique_ptr<CompilationDatabase>
- loadFromDirectory(StringRef Directory, std::string &ErrorMessage) = 0;
-};
-
/// A compilation database that returns a single compile command line.
///
/// Useful when we want a tool to behave more like a compiler invocation.
diff --git a/include/clang/Tooling/CompilationDatabasePluginRegistry.h b/include/clang/Tooling/CompilationDatabasePluginRegistry.h
index 051a08e2a91e..748ddbcf9d8d 100644
--- a/include/clang/Tooling/CompilationDatabasePluginRegistry.h
+++ b/include/clang/Tooling/CompilationDatabasePluginRegistry.h
@@ -16,6 +16,27 @@
namespace clang {
namespace tooling {
+/// Interface for compilation database plugins.
+///
+/// A compilation database plugin allows the user to register custom compilation
+/// databases that are picked up as compilation database if the corresponding
+/// library is linked in. To register a plugin, declare a static variable like:
+///
+/// \code
+/// static CompilationDatabasePluginRegistry::Add<MyDatabasePlugin>
+/// X("my-compilation-database", "Reads my own compilation database");
+/// \endcode
+class CompilationDatabasePlugin {
+public:
+ virtual ~CompilationDatabasePlugin();
+
+ /// Loads a compilation database from a build directory.
+ ///
+ /// \see CompilationDatabase::loadFromDirectory().
+ virtual std::unique_ptr<CompilationDatabase>
+ loadFromDirectory(StringRef Directory, std::string &ErrorMessage) = 0;
+};
+
using CompilationDatabasePluginRegistry =
llvm::Registry<CompilationDatabasePlugin>;
diff --git a/include/clang/Tooling/DiagnosticsYaml.h b/include/clang/Tooling/DiagnosticsYaml.h
index bf0732bf0042..d869450529bc 100644
--- a/include/clang/Tooling/DiagnosticsYaml.h
+++ b/include/clang/Tooling/DiagnosticsYaml.h
@@ -22,10 +22,19 @@
#include <string>
LLVM_YAML_IS_SEQUENCE_VECTOR(clang::tooling::Diagnostic)
+LLVM_YAML_IS_SEQUENCE_VECTOR(clang::tooling::DiagnosticMessage)
namespace llvm {
namespace yaml {
+template <> struct MappingTraits<clang::tooling::DiagnosticMessage> {
+ static void mapping(IO &Io, clang::tooling::DiagnosticMessage &M) {
+ Io.mapRequired("Message", M.Message);
+ Io.mapOptional("FilePath", M.FilePath);
+ Io.mapOptional("FileOffset", M.FileOffset);
+ }
+};
+
template <> struct MappingTraits<clang::tooling::Diagnostic> {
/// Helper to (de)serialize a Diagnostic since we don't have direct
/// access to its data members.
@@ -59,6 +68,7 @@ template <> struct MappingTraits<clang::tooling::Diagnostic> {
Io.mapRequired("Message", Keys->Message.Message);
Io.mapRequired("FileOffset", Keys->Message.FileOffset);
Io.mapRequired("FilePath", Keys->Message.FilePath);
+ Io.mapOptional("Notes", Keys->Notes);
// FIXME: Export properly all the different fields.
diff --git a/include/clang/Tooling/Execution.h b/include/clang/Tooling/Execution.h
index 68aef53cb58f..6bf1cf391b75 100644
--- a/include/clang/Tooling/Execution.h
+++ b/include/clang/Tooling/Execution.h
@@ -37,6 +37,8 @@
namespace clang {
namespace tooling {
+extern llvm::cl::opt<std::string> ExecutorName;
+
/// An abstraction for the result of a tool execution. For example, the
/// underlying result can be in-memory or on-disk.
///
@@ -114,6 +116,13 @@ public:
/// Returns the name of a specific executor.
virtual StringRef getExecutorName() const = 0;
+ /// Should return true iff executor runs all actions in a single process.
+ /// Clients can use this signal to find out if they can collect results
+ /// in-memory (e.g. to avoid serialization costs of using ToolResults).
+ /// The single-process executors can still run multiple threads, but all
+ /// executions are guaranteed to share the same memory.
+ virtual bool isSingleProcess() const = 0;
+
/// Executes each action with a corresponding arguments adjuster.
virtual llvm::Error
execute(llvm::ArrayRef<
diff --git a/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h b/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h
index d2d47ddc2c61..bd314f03cd3a 100644
--- a/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h
+++ b/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h
@@ -74,7 +74,7 @@ public:
for (unsigned I = 0, E = S->getNumComponents(); I != E; ++I) {
const OffsetOfNode &Component = S->getComponent(I);
if (Component.getKind() == OffsetOfNode::Field) {
- if (!visit(Component.getField(), Component.getLocEnd()))
+ if (!visit(Component.getField(), Component.getEndLoc()))
return false;
}
// FIXME: Try to resolve dependent field references.
diff --git a/include/clang/Tooling/Refactoring/RefactoringDiagnostic.h b/include/clang/Tooling/Refactoring/RefactoringDiagnostic.h
index 6767dc708e01..dc1d998396db 100644
--- a/include/clang/Tooling/Refactoring/RefactoringDiagnostic.h
+++ b/include/clang/Tooling/Refactoring/RefactoringDiagnostic.h
@@ -10,21 +10,6 @@
#ifndef LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGDIAGNOSTIC_H
#define LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGDIAGNOSTIC_H
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/PartialDiagnostic.h"
-
-namespace clang {
-namespace diag {
-enum {
-#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
- SHOWINSYSHEADER, CATEGORY) \
- ENUM,
-#define REFACTORINGSTART
-#include "clang/Basic/DiagnosticRefactoringKinds.inc"
-#undef DIAG
- NUM_BUILTIN_REFACTORING_DIAGNOSTICS
-};
-} // end namespace diag
-} // end namespace clang
+#include "clang/Basic/DiagnosticRefactoring.h"
#endif // LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGDIAGNOSTIC_H
diff --git a/include/clang/Tooling/StandaloneExecution.h b/include/clang/Tooling/StandaloneExecution.h
index 572330e4cc22..96487b4bb1dd 100644
--- a/include/clang/Tooling/StandaloneExecution.h
+++ b/include/clang/Tooling/StandaloneExecution.h
@@ -37,7 +37,8 @@ public:
StandaloneToolExecutor(
const CompilationDatabase &Compilations,
llvm::ArrayRef<std::string> SourcePaths,
- IntrusiveRefCntPtr<vfs::FileSystem> BaseFS = vfs::getRealFileSystem(),
+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS =
+ llvm::vfs::getRealFileSystem(),
std::shared_ptr<PCHContainerOperations> PCHContainerOps =
std::make_shared<PCHContainerOperations>());
@@ -52,6 +53,8 @@ public:
StringRef getExecutorName() const override { return ExecutorName; }
+ bool isSingleProcess() const override { return true; }
+
using ToolExecutor::execute;
llvm::Error
diff --git a/include/clang/Tooling/Tooling.h b/include/clang/Tooling/Tooling.h
index c056894b1a7a..662a980547df 100644
--- a/include/clang/Tooling/Tooling.h
+++ b/include/clang/Tooling/Tooling.h
@@ -33,7 +33,6 @@
#include "clang/AST/ASTConsumer.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/LLVM.h"
-#include "clang/Basic/VirtualFileSystem.h"
#include "clang/Frontend/FrontendAction.h"
#include "clang/Frontend/PCHContainerOperations.h"
#include "clang/Tooling/ArgumentsAdjusters.h"
@@ -44,6 +43,7 @@
#include "llvm/ADT/StringSet.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Option/Option.h"
+#include "llvm/Support/VirtualFileSystem.h"
#include <memory>
#include <string>
#include <utility>
@@ -190,7 +190,7 @@ bool runToolOnCodeWithArgs(
// Similar to the overload except this takes a VFS.
bool runToolOnCodeWithArgs(
FrontendAction *ToolAction, const Twine &Code,
- llvm::IntrusiveRefCntPtr<vfs::FileSystem> VFS,
+ llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
const std::vector<std::string> &Args, const Twine &FileName = "input.cc",
const Twine &ToolName = "clang-tool",
std::shared_ptr<PCHContainerOperations> PCHContainerOps =
@@ -205,7 +205,7 @@ bool runToolOnCodeWithArgs(
///
/// \return The resulting AST or null if an error occurred.
std::unique_ptr<ASTUnit>
-buildASTFromCode(const Twine &Code, const Twine &FileName = "input.cc",
+buildASTFromCode(StringRef Code, StringRef FileName = "input.cc",
std::shared_ptr<PCHContainerOperations> PCHContainerOps =
std::make_shared<PCHContainerOperations>());
@@ -223,10 +223,10 @@ buildASTFromCode(const Twine &Code, const Twine &FileName = "input.cc",
///
/// \return The resulting AST or null if an error occurred.
std::unique_ptr<ASTUnit> buildASTFromCodeWithArgs(
- const Twine &Code, const std::vector<std::string> &Args,
- const Twine &FileName = "input.cc", const Twine &ToolName = "clang-tool",
+ StringRef Code, const std::vector<std::string> &Args,
+ StringRef FileName = "input.cc", StringRef ToolName = "clang-tool",
std::shared_ptr<PCHContainerOperations> PCHContainerOps =
- std::make_shared<PCHContainerOperations>(),
+ std::make_shared<PCHContainerOperations>(),
ArgumentsAdjuster Adjuster = getClangStripDependencyFileAdjuster());
/// Utility to run a FrontendAction in a single clang invocation.
@@ -319,8 +319,8 @@ public:
ArrayRef<std::string> SourcePaths,
std::shared_ptr<PCHContainerOperations> PCHContainerOps =
std::make_shared<PCHContainerOperations>(),
- IntrusiveRefCntPtr<vfs::FileSystem> BaseFS =
- vfs::getRealFileSystem());
+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS =
+ llvm::vfs::getRealFileSystem());
~ClangTool();
@@ -356,6 +356,11 @@ public:
/// append them to ASTs.
int buildASTs(std::vector<std::unique_ptr<ASTUnit>> &ASTs);
+ /// Sets whether working directory should be restored after calling run(). By
+ /// default, working directory is restored. However, it could be useful to
+ /// turn this off when running on multiple threads to avoid the raciness.
+ void setRestoreWorkingDir(bool RestoreCWD);
+
/// Returns the file manager used in the tool.
///
/// The file manager is shared between all translation units.
@@ -368,8 +373,8 @@ private:
std::vector<std::string> SourcePaths;
std::shared_ptr<PCHContainerOperations> PCHContainerOps;
- llvm::IntrusiveRefCntPtr<vfs::OverlayFileSystem> OverlayFileSystem;
- llvm::IntrusiveRefCntPtr<vfs::InMemoryFileSystem> InMemoryFileSystem;
+ llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFileSystem;
+ llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem;
llvm::IntrusiveRefCntPtr<FileManager> Files;
// Contains a list of pairs (<file name>, <file content>).
@@ -380,6 +385,8 @@ private:
ArgumentsAdjuster ArgsAdjuster;
DiagnosticConsumer *DiagConsumer = nullptr;
+
+ bool RestoreCWD = true;
};
template <typename T>
@@ -459,6 +466,10 @@ inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory(
/// \param File Either an absolute or relative path.
std::string getAbsolutePath(StringRef File);
+/// An overload of getAbsolutePath that works over the provided \p FS.
+llvm::Expected<std::string> getAbsolutePath(llvm::vfs::FileSystem &FS,
+ StringRef File);
+
/// Changes CommandLine to contain implicit flags that would have been
/// defined had the compiler driver been invoked through the path InvokedAs.
///
diff --git a/include/clang/module.modulemap b/include/clang/module.modulemap
index 8d525c5ffbac..1f32ffe0c159 100644
--- a/include/clang/module.modulemap
+++ b/include/clang/module.modulemap
@@ -5,6 +5,12 @@ module Clang_Analysis {
textual header "Analysis/Analyses/ThreadSafetyOps.def"
module * { export * }
+
+ // FIXME: Exclude these headers to avoid pulling all of the AST matchers
+ // library into clang. Due to inline key functions in the headers,
+ // importing the AST matchers library gives a link dependency on the AST
+ // matchers (and thus the AST), which clang-format should not have.
+ exclude header "Analysis/Analyses/ExprMutationAnalyzer.h"
}
module Clang_AST {
@@ -33,7 +39,6 @@ module Clang_Basic {
textual header "Basic/BuiltinsLe64.def"
textual header "Basic/BuiltinsMips.def"
textual header "Basic/BuiltinsNEON.def"
- textual header "Basic/BuiltinsNios2.def"
textual header "Basic/BuiltinsNVPTX.def"
textual header "Basic/BuiltinsPPC.def"
textual header "Basic/BuiltinsSystemZ.def"
@@ -41,11 +46,14 @@ module Clang_Basic {
textual header "Basic/BuiltinsX86.def"
textual header "Basic/BuiltinsX86_64.def"
textual header "Basic/BuiltinsXCore.def"
+ textual header "Basic/CodeGenOptions.def"
textual header "Basic/DiagnosticOptions.def"
textual header "Basic/Features.def"
+ textual header "Basic/MSP430Target.def"
textual header "Basic/LangOptions.def"
textual header "Basic/OpenCLExtensions.def"
textual header "Basic/OpenCLImageTypes.def"
+ textual header "Basic/OpenCLExtensionTypes.def"
textual header "Basic/OpenMPKinds.def"
textual header "Basic/OperatorKinds.def"
textual header "Basic/Sanitizers.def"
@@ -95,17 +103,6 @@ module Clang_Frontend {
textual header "Frontend/LangStandards.def"
module * { export * }
-
- // FIXME: This violates layers.
- exclude header "Frontend/PCHContainerOperations.h"
-}
-
-// Used in clangBasic
-module Clang_Frontend_CodeGenOptions {
- requires cplusplus
- header "Frontend/CodeGenOptions.h"
- textual header "Frontend/CodeGenOptions.def"
- export *
}
module Clang_FrontendTool { requires cplusplus umbrella "FrontendTool" module * { export * } }
@@ -122,6 +119,7 @@ module Clang_StaticAnalyzer_Core {
umbrella "StaticAnalyzer/Core"
textual header "StaticAnalyzer/Core/Analyses.def"
+ textual header "StaticAnalyzer/Core/AnalyzerOptions.def"
textual header "StaticAnalyzer/Core/PathSensitive/SVals.def"
textual header "StaticAnalyzer/Core/PathSensitive/Symbols.def"
textual header "StaticAnalyzer/Core/PathSensitive/Regions.def"