aboutsummaryrefslogtreecommitdiff
path: root/include/clang
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang')
-rw-r--r--include/clang/AST/ASTContext.h394
-rw-r--r--include/clang/AST/ASTMutationListener.h14
-rw-r--r--include/clang/AST/ASTUnresolvedSet.h25
-rw-r--r--include/clang/AST/ASTVector.h53
-rw-r--r--include/clang/AST/AttrIterator.h37
-rw-r--r--include/clang/AST/BaseSubobject.h24
-rw-r--r--include/clang/AST/BuiltinTypes.def3
-rw-r--r--include/clang/AST/CMakeLists.txt3
-rw-r--r--include/clang/AST/CXXInheritance.h93
-rw-r--r--include/clang/AST/CanonicalType.h71
-rw-r--r--include/clang/AST/CharUnits.h4
-rw-r--r--include/clang/AST/CommentVisitor.h12
-rw-r--r--include/clang/AST/DataCollection.h65
-rw-r--r--include/clang/AST/Decl.h667
-rw-r--r--include/clang/AST/DeclBase.h286
-rw-r--r--include/clang/AST/DeclCXX.h534
-rw-r--r--include/clang/AST/DeclContextInternals.h29
-rw-r--r--include/clang/AST/DeclFriend.h77
-rw-r--r--include/clang/AST/DeclGroup.h40
-rw-r--r--include/clang/AST/DeclLookups.h23
-rw-r--r--include/clang/AST/DeclObjC.h658
-rw-r--r--include/clang/AST/DeclOpenMP.h20
-rw-r--r--include/clang/AST/DeclTemplate.h480
-rw-r--r--include/clang/AST/DeclVisitor.h19
-rw-r--r--include/clang/AST/DeclarationName.h137
-rw-r--r--include/clang/AST/DependentDiagnostic.h30
-rw-r--r--include/clang/AST/Expr.h81
-rw-r--r--include/clang/AST/ExprCXX.h902
-rw-r--r--include/clang/AST/ExprObjC.h477
-rw-r--r--include/clang/AST/ExternalASTMerger.h139
-rw-r--r--include/clang/AST/ExternalASTSource.h103
-rw-r--r--include/clang/AST/GlobalDecl.h29
-rw-r--r--include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h164
-rw-r--r--include/clang/AST/NestedNameSpecifier.h60
-rw-r--r--include/clang/AST/OpenMPClause.h1582
-rw-r--r--include/clang/AST/OperationKinds.def10
-rw-r--r--include/clang/AST/OperationKinds.h2
-rw-r--r--include/clang/AST/PrettyPrinter.h103
-rw-r--r--include/clang/AST/QualTypeNames.h (renamed from include/clang/Tooling/Core/QualTypeNames.h)25
-rw-r--r--include/clang/AST/RecordLayout.h48
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h76
-rw-r--r--include/clang/AST/Redeclarable.h68
-rw-r--r--include/clang/AST/Stmt.h425
-rw-r--r--include/clang/AST/StmtDataCollectors.td242
-rw-r--r--include/clang/AST/StmtGraphTraits.h27
-rw-r--r--include/clang/AST/StmtIterator.h60
-rw-r--r--include/clang/AST/StmtOpenMP.h122
-rw-r--r--include/clang/AST/StmtVisitor.h46
-rw-r--r--include/clang/AST/TemplateBase.h76
-rw-r--r--include/clang/AST/TemplateName.h73
-rw-r--r--include/clang/AST/Type.h1154
-rw-r--r--include/clang/AST/TypeLoc.h237
-rw-r--r--include/clang/AST/TypeNodes.def3
-rw-r--r--include/clang/AST/UnresolvedSet.h20
-rw-r--r--include/clang/AST/VTTBuilder.h44
-rw-r--r--include/clang/ASTMatchers/ASTMatchers.h858
-rw-r--r--include/clang/ASTMatchers/ASTMatchersInternal.h248
-rw-r--r--include/clang/ASTMatchers/ASTMatchersMacros.h45
-rw-r--r--include/clang/ASTMatchers/Dynamic/Parser.h31
-rw-r--r--include/clang/ASTMatchers/Dynamic/Registry.h16
-rw-r--r--include/clang/Analysis/Analyses/Consumed.h2
-rw-r--r--include/clang/Analysis/Analyses/Dominators.h2
-rw-r--r--include/clang/Analysis/Analyses/LiveVariables.h2
-rw-r--r--include/clang/Analysis/Analyses/PostOrderCFGView.h2
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafety.h2
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafetyCommon.h2
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafetyTIL.h24
-rw-r--r--include/clang/Analysis/AnalysisDeclContext.h (renamed from include/clang/Analysis/AnalysisContext.h)24
-rw-r--r--include/clang/Analysis/BodyFarm.h54
-rw-r--r--include/clang/Analysis/CFG.h358
-rw-r--r--include/clang/Analysis/CallGraph.h93
-rw-r--r--include/clang/Analysis/CloneDetection.h245
-rw-r--r--include/clang/Analysis/ProgramPoint.h26
-rw-r--r--include/clang/Analysis/Support/BumpVector.h53
-rw-r--r--include/clang/Basic/AddressSpaces.h32
-rw-r--r--include/clang/Basic/AlignedAllocation.h44
-rw-r--r--include/clang/Basic/AllDiagnostics.h2
-rw-r--r--include/clang/Basic/Attr.td566
-rw-r--r--include/clang/Basic/AttrDocs.td198
-rw-r--r--include/clang/Basic/Attributes.h2
-rw-r--r--include/clang/Basic/Builtins.def515
-rw-r--r--include/clang/Basic/Builtins.h7
-rw-r--r--include/clang/Basic/BuiltinsAArch64.def9
-rw-r--r--include/clang/Basic/BuiltinsAMDGPU.def3
-rw-r--r--include/clang/Basic/BuiltinsARM.def1
-rw-r--r--include/clang/Basic/BuiltinsHexagon.def222
-rw-r--r--include/clang/Basic/BuiltinsNVPTX.def48
-rw-r--r--include/clang/Basic/BuiltinsX86.def128
-rw-r--r--include/clang/Basic/BuiltinsX86_64.def8
-rw-r--r--include/clang/Basic/CMakeLists.txt2
-rw-r--r--include/clang/Basic/CharInfo.h42
-rw-r--r--include/clang/Basic/Cuda.h7
-rw-r--r--include/clang/Basic/DeclNodes.td59
-rw-r--r--include/clang/Basic/Diagnostic.h8
-rw-r--r--include/clang/Basic/Diagnostic.td2
-rw-r--r--include/clang/Basic/DiagnosticASTKinds.td9
-rw-r--r--include/clang/Basic/DiagnosticCommonKinds.td2
-rw-r--r--include/clang/Basic/DiagnosticCrossTUKinds.td18
-rw-r--r--include/clang/Basic/DiagnosticDriverKinds.td50
-rw-r--r--include/clang/Basic/DiagnosticError.h61
-rw-r--r--include/clang/Basic/DiagnosticFrontendKinds.td2
-rw-r--r--include/clang/Basic/DiagnosticGroups.td82
-rw-r--r--include/clang/Basic/DiagnosticIDs.h43
-rw-r--r--include/clang/Basic/DiagnosticLexKinds.td47
-rw-r--r--include/clang/Basic/DiagnosticOptions.h4
-rw-r--r--include/clang/Basic/DiagnosticParseKinds.td47
-rw-r--r--include/clang/Basic/DiagnosticRefactoringKinds.td34
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td336
-rw-r--r--include/clang/Basic/DiagnosticSerializationKinds.td41
-rw-r--r--include/clang/Basic/IdentifierTable.h92
-rw-r--r--include/clang/Basic/LLVM.h4
-rw-r--r--include/clang/Basic/LangOptions.def13
-rw-r--r--include/clang/Basic/LangOptions.h7
-rw-r--r--include/clang/Basic/Module.h81
-rw-r--r--include/clang/Basic/OpenCLExtensions.def4
-rw-r--r--include/clang/Basic/OpenMPKinds.def8
-rw-r--r--include/clang/Basic/OperatorKinds.def1
-rw-r--r--include/clang/Basic/OperatorPrecedence.h9
-rw-r--r--include/clang/Basic/SanitizerBlacklist.h15
-rw-r--r--include/clang/Basic/SanitizerSpecialCaseList.h54
-rw-r--r--include/clang/Basic/Sanitizers.def20
-rw-r--r--include/clang/Basic/Sanitizers.h2
-rw-r--r--include/clang/Basic/SourceLocation.h32
-rw-r--r--include/clang/Basic/SourceManager.h105
-rw-r--r--include/clang/Basic/SourceManagerInternals.h22
-rw-r--r--include/clang/Basic/Specifiers.h1
-rw-r--r--include/clang/Basic/SyncScope.h154
-rw-r--r--include/clang/Basic/TargetInfo.h76
-rw-r--r--include/clang/Basic/TargetOptions.h2
-rw-r--r--include/clang/Basic/TokenKinds.def18
-rw-r--r--include/clang/Basic/TypeTraits.h3
-rw-r--r--include/clang/Basic/VirtualFileSystem.h28
-rw-r--r--include/clang/Basic/X86Target.def232
-rw-r--r--include/clang/CodeGen/CodeGenABITypes.h9
-rw-r--r--include/clang/CodeGen/ConstantInitFuture.h6
-rw-r--r--include/clang/CodeGen/ModuleBuilder.h4
-rw-r--r--include/clang/Config/config.h.cmake12
-rw-r--r--include/clang/CrossTU/CrossTUDiagnostic.h29
-rw-r--r--include/clang/CrossTU/CrossTranslationUnit.h159
-rw-r--r--include/clang/Driver/CC1Options.td50
-rw-r--r--include/clang/Driver/CLCompatOptions.td7
-rw-r--r--include/clang/Driver/Compilation.h14
-rw-r--r--include/clang/Driver/Distro.h11
-rw-r--r--include/clang/Driver/Driver.h12
-rw-r--r--include/clang/Driver/Job.h8
-rw-r--r--include/clang/Driver/Options.td418
-rw-r--r--include/clang/Driver/SanitizerArgs.h20
-rw-r--r--include/clang/Driver/ToolChain.h69
-rw-r--r--include/clang/Driver/XRayArgs.h1
-rw-r--r--include/clang/Format/Format.h144
-rw-r--r--include/clang/Frontend/ASTUnit.h20
-rw-r--r--include/clang/Frontend/CodeGenOptions.def26
-rw-r--r--include/clang/Frontend/CodeGenOptions.h7
-rw-r--r--include/clang/Frontend/CommandLineSourceLoc.h46
-rw-r--r--include/clang/Frontend/CompilerInstance.h4
-rw-r--r--include/clang/Frontend/FrontendActions.h13
-rw-r--r--include/clang/Frontend/FrontendOptions.h15
-rw-r--r--include/clang/Frontend/LangStandard.h28
-rw-r--r--include/clang/Frontend/LangStandards.def17
-rw-r--r--include/clang/Frontend/PrecompiledPreamble.h92
-rw-r--r--include/clang/Frontend/TextDiagnosticBuffer.h5
-rw-r--r--include/clang/Frontend/VerifyDiagnosticConsumer.h3
-rw-r--r--include/clang/Index/IndexDataConsumer.h3
-rw-r--r--include/clang/Index/IndexSymbol.h3
-rw-r--r--include/clang/Lex/HeaderSearch.h126
-rw-r--r--include/clang/Lex/HeaderSearchOptions.h89
-rw-r--r--include/clang/Lex/Lexer.h127
-rw-r--r--include/clang/Lex/LiteralSupport.h1
-rw-r--r--include/clang/Lex/MacroArgs.h22
-rw-r--r--include/clang/Lex/MacroInfo.h88
-rw-r--r--include/clang/Lex/ModuleLoader.h31
-rw-r--r--include/clang/Lex/ModuleMap.h75
-rw-r--r--include/clang/Lex/MultipleIncludeOpt.h2
-rw-r--r--include/clang/Lex/PPCallbacks.h40
-rw-r--r--include/clang/Lex/PTHLexer.h25
-rw-r--r--include/clang/Lex/PTHManager.h42
-rw-r--r--include/clang/Lex/Pragma.h29
-rw-r--r--include/clang/Lex/PreprocessingRecord.h70
-rw-r--r--include/clang/Lex/Preprocessor.h294
-rw-r--r--include/clang/Lex/PreprocessorLexer.h47
-rw-r--r--include/clang/Lex/PreprocessorOptions.h55
-rw-r--r--include/clang/Lex/TokenLexer.h111
-rw-r--r--include/clang/Lex/VariadicMacroSupport.h226
-rw-r--r--include/clang/Parse/ParseAST.h7
-rw-r--r--include/clang/Parse/Parser.h106
-rw-r--r--include/clang/Sema/AttributeList.h44
-rw-r--r--include/clang/Sema/CodeCompleteConsumer.h34
-rw-r--r--include/clang/Sema/CodeCompleteOptions.h17
-rw-r--r--include/clang/Sema/DeclSpec.h55
-rw-r--r--include/clang/Sema/Lookup.h25
-rw-r--r--include/clang/Sema/Overload.h30
-rw-r--r--include/clang/Sema/Ownership.h3
-rw-r--r--include/clang/Sema/Scope.h11
-rw-r--r--include/clang/Sema/ScopeInfo.h7
-rw-r--r--include/clang/Sema/Sema.h237
-rw-r--r--include/clang/Sema/SemaInternal.h3
-rw-r--r--include/clang/Serialization/ASTBitCodes.h420
-rw-r--r--include/clang/Serialization/ASTReader.h341
-rw-r--r--include/clang/Serialization/ASTWriter.h117
-rw-r--r--include/clang/Serialization/ContinuousRangeMap.h34
-rw-r--r--include/clang/Serialization/ModuleManager.h77
-rw-r--r--include/clang/StaticAnalyzer/Checkers/Checkers.td17
-rw-r--r--include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h6
-rw-r--r--include/clang/StaticAnalyzer/Core/Analyses.def5
-rw-r--r--include/clang/StaticAnalyzer/Core/AnalyzerOptions.h17
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h2
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h (renamed from include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h)6
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h2
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h17
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h7
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h2
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h2
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h8
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h8
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h50
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h17
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h11
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h12
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/Store.h10
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h6
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h9
-rw-r--r--include/clang/Tooling/ASTDiff/ASTDiff.h127
-rw-r--r--include/clang/Tooling/ASTDiff/ASTDiffInternal.h48
-rw-r--r--include/clang/Tooling/CommonOptionsParser.h50
-rw-r--r--include/clang/Tooling/CompilationDatabase.h39
-rw-r--r--include/clang/Tooling/Core/Replacement.h2
-rw-r--r--include/clang/Tooling/Execution.h175
-rw-r--r--include/clang/Tooling/Refactoring/ASTSelection.h155
-rw-r--r--include/clang/Tooling/Refactoring/AtomicChange.h44
-rw-r--r--include/clang/Tooling/Refactoring/Extract/Extract.h53
-rw-r--r--include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h12
-rw-r--r--include/clang/Tooling/Refactoring/RefactoringAction.h64
-rw-r--r--include/clang/Tooling/Refactoring/RefactoringActionRule.h74
-rw-r--r--include/clang/Tooling/Refactoring/RefactoringActionRuleRequirements.h123
-rw-r--r--include/clang/Tooling/Refactoring/RefactoringActionRules.h94
-rw-r--r--include/clang/Tooling/Refactoring/RefactoringActionRulesInternal.h158
-rw-r--r--include/clang/Tooling/Refactoring/RefactoringDiagnostic.h30
-rw-r--r--include/clang/Tooling/Refactoring/RefactoringOption.h64
-rw-r--r--include/clang/Tooling/Refactoring/RefactoringOptionVisitor.h62
-rw-r--r--include/clang/Tooling/Refactoring/RefactoringOptions.h58
-rw-r--r--include/clang/Tooling/Refactoring/RefactoringResultConsumer.h52
-rw-r--r--include/clang/Tooling/Refactoring/RefactoringRuleContext.h90
-rw-r--r--include/clang/Tooling/Refactoring/Rename/RenamingAction.h52
-rw-r--r--include/clang/Tooling/Refactoring/Rename/SymbolName.h49
-rw-r--r--include/clang/Tooling/Refactoring/Rename/SymbolOccurrences.h91
-rw-r--r--include/clang/Tooling/Refactoring/Rename/USRFindingAction.h14
-rw-r--r--include/clang/Tooling/Refactoring/Rename/USRLocFinder.h12
-rw-r--r--include/clang/Tooling/StandaloneExecution.h97
-rw-r--r--include/clang/Tooling/ToolExecutorPluginRegistry.h24
-rw-r--r--include/clang/Tooling/Tooling.h6
-rw-r--r--include/clang/module.modulemap22
251 files changed, 15225 insertions, 7200 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 703f588c5663..a5d080035df0 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -1,4 +1,4 @@
-//===--- ASTContext.h - Context to hold long-lived AST nodes ----*- C++ -*-===//
+//===- ASTContext.h - Context to hold long-lived AST nodes ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,10 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-///
+//
/// \file
/// \brief Defines the clang::ASTContext interface.
-///
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_ASTCONTEXT_H
@@ -19,8 +19,8 @@
#include "clang/AST/CanonicalType.h"
#include "clang/AST/CommentCommandTraits.h"
#include "clang/AST/Decl.h"
-#include "clang/AST/DeclarationName.h"
#include "clang/AST/DeclBase.h"
+#include "clang/AST/DeclarationName.h"
#include "clang/AST/ExternalASTSource.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/PrettyPrinter.h"
@@ -30,32 +30,32 @@
#include "clang/AST/Type.h"
#include "clang/Basic/AddressSpaces.h"
#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LLVM.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/Linkage.h"
-#include "clang/Basic/LLVM.h"
-#include "clang/Basic/Module.h"
#include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/SanitizerBlacklist.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
+#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/XRayLists.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h"
-#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/TinyPtrVector.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Casting.h"
@@ -65,7 +65,6 @@
#include <cstdint>
#include <iterator>
#include <memory>
-#include <new>
#include <string>
#include <type_traits>
#include <utility>
@@ -75,50 +74,72 @@ namespace llvm {
struct fltSemantics;
-} // end namespace llvm
+} // namespace llvm
namespace clang {
+class APValue;
class ASTMutationListener;
class ASTRecordLayout;
class AtomicExpr;
class BlockExpr;
+class BuiltinTemplateDecl;
class CharUnits;
class CXXABI;
+class CXXConstructorDecl;
+class CXXMethodDecl;
+class CXXRecordDecl;
class DiagnosticsEngine;
class Expr;
+class MangleContext;
class MangleNumberingContext;
class MaterializeTemporaryExpr;
-class TargetInfo;
-// Decls
-class MangleContext;
+class MemberSpecializationInfo;
+class Module;
+class ObjCCategoryDecl;
+class ObjCCategoryImplDecl;
+class ObjCContainerDecl;
+class ObjCImplDecl;
+class ObjCImplementationDecl;
+class ObjCInterfaceDecl;
class ObjCIvarDecl;
+class ObjCMethodDecl;
class ObjCPropertyDecl;
+class ObjCPropertyImplDecl;
+class ObjCProtocolDecl;
+class ObjCTypeParamDecl;
+class Preprocessor;
+class Stmt;
+class StoredDeclsMap;
+class TemplateDecl;
+class TemplateParameterList;
+class TemplateTemplateParmDecl;
+class TemplateTypeParmDecl;
class UnresolvedSetIterator;
-class UsingDecl;
class UsingShadowDecl;
+class VarTemplateDecl;
class VTableContextBase;
namespace Builtin {
- class Context;
+class Context;
-} // end namespace Builtin
+} // namespace Builtin
enum BuiltinTemplateKind : int;
namespace comments {
- class FullComment;
+class FullComment;
-} // end namespace comments
+} // namespace comments
struct TypeInfo {
- uint64_t Width;
- unsigned Align;
+ uint64_t Width = 0;
+ unsigned Align = 0;
bool AlignIsRequired : 1;
- TypeInfo() : Width(0), Align(0), AlignIsRequired(false) {}
+ TypeInfo() : AlignIsRequired(false) {}
TypeInfo(uint64_t Width, unsigned Align, bool AlignIsRequired)
: Width(Width), Align(Align), AlignIsRequired(AlignIsRequired) {}
};
@@ -126,7 +147,7 @@ struct TypeInfo {
/// \brief 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> {
- ASTContext &this_() { return *this; }
+ friend class NestedNameSpecifier;
mutable SmallVector<Type *, 0> Types;
mutable llvm::FoldingSet<ExtQuals> ExtQualNodes;
@@ -143,6 +164,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
mutable llvm::FoldingSet<DependentSizedArrayType> DependentSizedArrayTypes;
mutable llvm::FoldingSet<DependentSizedExtVectorType>
DependentSizedExtVectorTypes;
+ mutable llvm::FoldingSet<DependentAddressSpaceType>
+ DependentAddressSpaceTypes;
mutable llvm::FoldingSet<VectorType> VectorTypes;
mutable llvm::FoldingSet<FunctionNoProtoType> FunctionNoProtoTypes;
mutable llvm::ContextualFoldingSet<FunctionProtoType, ASTContext&>
@@ -187,8 +210,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
///
/// This set is managed by the NestedNameSpecifier class.
mutable llvm::FoldingSet<NestedNameSpecifier> NestedNameSpecifiers;
- mutable NestedNameSpecifier *GlobalNestedNameSpecifier;
- friend class NestedNameSpecifier;
+ mutable NestedNameSpecifier *GlobalNestedNameSpecifier = nullptr;
/// \brief A cache mapping from RecordDecls to ASTRecordLayouts.
///
@@ -199,7 +221,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
ObjCLayouts;
/// \brief A cache from types to size and alignment information.
- typedef llvm::DenseMap<const Type *, struct TypeInfo> TypeInfoMap;
+ using TypeInfoMap = llvm::DenseMap<const Type *, struct TypeInfo>;
mutable TypeInfoMap MemoizedTypeInfo;
/// \brief A cache mapping from CXXRecordDecls to key functions.
@@ -233,7 +255,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
public:
CanonicalTemplateTemplateParm(TemplateTemplateParmDecl *Parm)
- : Parm(Parm) { }
+ : Parm(Parm) {}
TemplateTemplateParmDecl *getParam() const { return Parm; }
@@ -249,32 +271,32 @@ class ASTContext : public RefCountedBase<ASTContext> {
getCanonicalTemplateTemplateParmDecl(TemplateTemplateParmDecl *TTP) const;
/// \brief The typedef for the __int128_t type.
- mutable TypedefDecl *Int128Decl;
+ mutable TypedefDecl *Int128Decl = nullptr;
/// \brief The typedef for the __uint128_t type.
- mutable TypedefDecl *UInt128Decl;
+ mutable TypedefDecl *UInt128Decl = nullptr;
/// \brief The typedef for the target specific predefined
/// __builtin_va_list type.
- mutable TypedefDecl *BuiltinVaListDecl;
+ mutable TypedefDecl *BuiltinVaListDecl = nullptr;
/// The typedef for the predefined \c __builtin_ms_va_list type.
- mutable TypedefDecl *BuiltinMSVaListDecl;
+ mutable TypedefDecl *BuiltinMSVaListDecl = nullptr;
/// \brief The typedef for the predefined \c id type.
- mutable TypedefDecl *ObjCIdDecl;
+ mutable TypedefDecl *ObjCIdDecl = nullptr;
/// \brief The typedef for the predefined \c SEL type.
- mutable TypedefDecl *ObjCSelDecl;
+ mutable TypedefDecl *ObjCSelDecl = nullptr;
/// \brief The typedef for the predefined \c Class type.
- mutable TypedefDecl *ObjCClassDecl;
+ mutable TypedefDecl *ObjCClassDecl = nullptr;
/// \brief The typedef for the predefined \c Protocol class in Objective-C.
- mutable ObjCInterfaceDecl *ObjCProtocolClassDecl;
+ mutable ObjCInterfaceDecl *ObjCProtocolClassDecl = nullptr;
/// \brief The typedef for the predefined 'BOOL' type.
- mutable TypedefDecl *BOOLDecl;
+ mutable TypedefDecl *BOOLDecl = nullptr;
// Typedefs which may be provided defining the structure of Objective-C
// pseudo-builtins
@@ -298,42 +320,42 @@ class ASTContext : public RefCountedBase<ASTContext> {
mutable IdentifierInfo *TypePackElementName = nullptr;
QualType ObjCConstantStringType;
- mutable RecordDecl *CFConstantStringTagDecl;
- mutable TypedefDecl *CFConstantStringTypeDecl;
+ mutable RecordDecl *CFConstantStringTagDecl = nullptr;
+ mutable TypedefDecl *CFConstantStringTypeDecl = nullptr;
mutable QualType ObjCSuperType;
QualType ObjCNSStringType;
/// \brief The typedef declaration for the Objective-C "instancetype" type.
- TypedefDecl *ObjCInstanceTypeDecl;
+ TypedefDecl *ObjCInstanceTypeDecl = nullptr;
/// \brief The type for the C FILE type.
- TypeDecl *FILEDecl;
+ TypeDecl *FILEDecl = nullptr;
/// \brief The type for the C jmp_buf type.
- TypeDecl *jmp_bufDecl;
+ TypeDecl *jmp_bufDecl = nullptr;
/// \brief The type for the C sigjmp_buf type.
- TypeDecl *sigjmp_bufDecl;
+ TypeDecl *sigjmp_bufDecl = nullptr;
/// \brief The type for the C ucontext_t type.
- TypeDecl *ucontext_tDecl;
+ TypeDecl *ucontext_tDecl = nullptr;
/// \brief Type for the Block descriptor for Blocks CodeGen.
///
/// Since this is only used for generation of debug info, it is not
/// serialized.
- mutable RecordDecl *BlockDescriptorType;
+ mutable RecordDecl *BlockDescriptorType = nullptr;
/// \brief Type for the Block descriptor for Blocks CodeGen.
///
/// Since this is only used for generation of debug info, it is not
/// serialized.
- mutable RecordDecl *BlockDescriptorExtendedType;
+ mutable RecordDecl *BlockDescriptorExtendedType = nullptr;
/// \brief Declaration for the CUDA cudaConfigureCall function.
- FunctionDecl *cudaConfigureCallDecl;
+ FunctionDecl *cudaConfigureCallDecl = nullptr;
/// \brief Keeps track of all declaration attributes.
///
@@ -363,12 +385,19 @@ class ASTContext : public RefCountedBase<ASTContext> {
};
llvm::DenseMap<Module*, PerModuleInitializers*> ModuleInitializers;
+ ASTContext &this_() { return *this; }
+
public:
/// \brief A type synonym for the TemplateOrInstantiation mapping.
- typedef llvm::PointerUnion<VarTemplateDecl *, MemberSpecializationInfo *>
- TemplateOrSpecializationInfo;
+ using TemplateOrSpecializationInfo =
+ llvm::PointerUnion<VarTemplateDecl *, MemberSpecializationInfo *>;
private:
+ friend class ASTDeclReader;
+ friend class ASTReader;
+ friend class ASTWriter;
+ friend class CXXRecordDecl;
+
/// \brief A mapping to contain the template or declaration that
/// a variable declaration describes or was instantiated from,
/// respectively.
@@ -438,7 +467,7 @@ private:
/// Since most C++ member functions aren't virtual and therefore
/// don't override anything, we store the overridden functions in
/// this map on the side rather than within the CXXMethodDecl structure.
- typedef llvm::TinyPtrVector<const CXXMethodDecl*> CXXMethodVector;
+ using CXXMethodVector = llvm::TinyPtrVector<const CXXMethodDecl *>;
llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector> OverriddenMethods;
/// \brief Mapping from each declaration context to its corresponding
@@ -454,18 +483,18 @@ private:
/// \brief Mapping that stores parameterIndex values for ParmVarDecls when
/// that value exceeds the bitfield size of ParmVarDeclBits.ParameterIndex.
- typedef llvm::DenseMap<const VarDecl *, unsigned> ParameterIndexTable;
+ using ParameterIndexTable = llvm::DenseMap<const VarDecl *, unsigned>;
ParameterIndexTable ParamIndices;
- ImportDecl *FirstLocalImport;
- ImportDecl *LastLocalImport;
+ ImportDecl *FirstLocalImport = nullptr;
+ ImportDecl *LastLocalImport = nullptr;
TranslationUnitDecl *TUDecl;
- mutable ExternCContextDecl *ExternCContext;
- mutable BuiltinTemplateDecl *MakeIntegerSeqDecl;
- mutable BuiltinTemplateDecl *TypePackElementDecl;
+ mutable ExternCContextDecl *ExternCContext = nullptr;
+ mutable BuiltinTemplateDecl *MakeIntegerSeqDecl = nullptr;
+ mutable BuiltinTemplateDecl *TypePackElementDecl = nullptr;
- /// \brief The associated SourceManager object.a
+ /// \brief The associated SourceManager object.
SourceManager &SourceMgr;
/// \brief The language options used to create the AST associated with
@@ -494,19 +523,14 @@ private:
CXXABI *createCXXABI(const TargetInfo &T);
/// \brief The logical -> physical address space map.
- const LangAS::Map *AddrSpaceMap;
+ const LangASMap *AddrSpaceMap = nullptr;
/// \brief Address space map mangling must be used with language specific
/// address spaces (e.g. OpenCL/CUDA)
bool AddrSpaceMapMangling;
- friend class ASTDeclReader;
- friend class ASTReader;
- friend class ASTWriter;
- friend class CXXRecordDecl;
-
- const TargetInfo *Target;
- const TargetInfo *AuxTarget;
+ const TargetInfo *Target = nullptr;
+ const TargetInfo *AuxTarget = nullptr;
clang::PrintingPolicy PrintingPolicy;
public:
@@ -515,31 +539,33 @@ public:
Builtin::Context &BuiltinInfo;
mutable DeclarationNameTable DeclarationNames;
IntrusiveRefCntPtr<ExternalASTSource> ExternalSource;
- ASTMutationListener *Listener;
+ ASTMutationListener *Listener = nullptr;
/// \brief Contains parents of a node.
- typedef llvm::SmallVector<ast_type_traits::DynTypedNode, 2> ParentVector;
+ using ParentVector = llvm::SmallVector<ast_type_traits::DynTypedNode, 2>;
/// \brief 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.
- typedef llvm::DenseMap<const void *,
- llvm::PointerUnion4<const Decl *, const Stmt *,
- ast_type_traits::DynTypedNode *,
- ParentVector *>> ParentMapPointers;
+ 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.
- typedef llvm::DenseMap<
- ast_type_traits::DynTypedNode,
- llvm::PointerUnion4<const Decl *, const Stmt *,
- ast_type_traits::DynTypedNode *, ParentVector *>>
- ParentMapOtherNodes;
+ 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 {
- typedef ast_type_traits::DynTypedNode DynTypedNode;
+ using DynTypedNode = ast_type_traits::DynTypedNode;
+
llvm::AlignedCharArrayUnion<ast_type_traits::DynTypedNode,
ArrayRef<DynTypedNode>> Storage;
bool IsSingleNode;
@@ -548,6 +574,7 @@ public:
DynTypedNodeList(const DynTypedNode &N) : IsSingleNode(true) {
new (Storage.buffer) DynTypedNode(N);
}
+
DynTypedNodeList(ArrayRef<DynTypedNode> A) : IsSingleNode(false) {
new (Storage.buffer) ArrayRef<DynTypedNode>(A);
}
@@ -626,13 +653,14 @@ public:
template <typename T> T *Allocate(size_t Num = 1) const {
return static_cast<T *>(Allocate(Num * sizeof(T), alignof(T)));
}
- void Deallocate(void *Ptr) const { }
+ void Deallocate(void *Ptr) const {}
/// Return the total amount of physical memory allocated for representing
/// AST nodes and type information.
size_t getASTAllocatedMemory() const {
return BumpAlloc.getTotalMemory();
}
+
/// Return the total memory used for various side tables.
size_t getSideTableAllocatedMemory() const;
@@ -649,6 +677,7 @@ public:
/// Returns empty type if there is no appropriate target types.
QualType getIntTypeForBitwidth(unsigned DestWidth,
unsigned Signed) const;
+
/// getRealTypeForBitwidth -
/// sets floating point QualTy according to specified bitwidth.
/// Returns empty type if there is no appropriate target types.
@@ -676,7 +705,7 @@ public:
RawCommentList Comments;
/// \brief True if comments are already loaded from ExternalASTSource.
- mutable bool CommentsLoaded;
+ mutable bool CommentsLoaded = false;
class RawCommentAndCacheFlags {
public:
@@ -759,24 +788,24 @@ public:
}
/// \brief Return the documentation comment attached to a given declaration.
- /// Returns NULL if no comment is attached.
+ /// Returns nullptr if no comment is attached.
///
- /// \param OriginalDecl if not NULL, is set to declaration AST node that had
- /// the comment, if the comment we found comes from a redeclaration.
+ /// \param OriginalDecl if not nullptr, is set to declaration AST node that
+ /// had the comment, if the comment we found comes from a redeclaration.
const RawComment *
getRawCommentForAnyRedecl(const Decl *D,
const Decl **OriginalDecl = nullptr) const;
/// Return parsed documentation comment attached to a given declaration.
- /// Returns NULL if no comment is attached.
+ /// Returns nullptr if no comment is attached.
///
- /// \param PP the Preprocessor used with this TU. Could be NULL if
+ /// \param PP the Preprocessor used with this TU. Could be nullptr if
/// preprocessor is not available.
comments::FullComment *getCommentForDecl(const Decl *D,
const Preprocessor *PP) const;
/// Return parsed documentation comment attached to a given declaration.
- /// Returns NULL if no comment is attached. Does not look at any
+ /// Returns nullptr if no comment is attached. Does not look at any
/// redeclarations of the declaration.
comments::FullComment *getLocalCommentForDeclUncached(const Decl *D) const;
@@ -788,16 +817,16 @@ private:
/// \brief Iterator that visits import declarations.
class import_iterator {
- ImportDecl *Import;
+ ImportDecl *Import = nullptr;
public:
- typedef ImportDecl *value_type;
- typedef ImportDecl *reference;
- typedef ImportDecl *pointer;
- typedef int difference_type;
- typedef std::forward_iterator_tag iterator_category;
+ using value_type = ImportDecl *;
+ using reference = ImportDecl *;
+ using pointer = ImportDecl *;
+ using difference_type = int;
+ using iterator_category = std::forward_iterator_tag;
- import_iterator() : Import() {}
+ import_iterator() = default;
explicit import_iterator(ImportDecl *Import) : Import(Import) {}
reference operator*() const { return Import; }
@@ -876,7 +905,7 @@ public:
void setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst, FieldDecl *Tmpl);
// Access to the set of methods overridden by the given C++ method.
- typedef CXXMethodVector::const_iterator overridden_cxx_method_iterator;
+ using overridden_cxx_method_iterator = CXXMethodVector::const_iterator;
overridden_cxx_method_iterator
overridden_methods_begin(const CXXMethodDecl *Method) const;
@@ -884,8 +913,10 @@ public:
overridden_methods_end(const CXXMethodDecl *Method) const;
unsigned overridden_methods_size(const CXXMethodDecl *Method) const;
- typedef llvm::iterator_range<overridden_cxx_method_iterator>
- overridden_method_range;
+
+ using overridden_method_range =
+ llvm::iterator_range<overridden_cxx_method_iterator>;
+
overridden_method_range overridden_methods(const CXXMethodDecl *Method) const;
/// \brief Note that the given C++ \p Method overrides the given \p
@@ -912,7 +943,8 @@ public:
return Import->NextLocalImport;
}
- typedef llvm::iterator_range<import_iterator> import_range;
+ using import_range = llvm::iterator_range<import_iterator>;
+
import_range local_imports() const {
return import_range(import_iterator(FirstLocalImport), import_iterator());
}
@@ -929,6 +961,7 @@ public:
/// and should be visible whenever \p M is visible.
void mergeDefinitionIntoModule(NamedDecl *ND, Module *M,
bool NotifyListeners = true);
+
/// \brief Clean up the merged definition list. Call this if you might have
/// added duplicates into the list.
void deduplicateMergedDefinitonsFor(NamedDecl *ND);
@@ -973,6 +1006,7 @@ public:
CanQualType UnsignedLongLongTy, UnsignedInt128Ty;
CanQualType FloatTy, DoubleTy, LongDoubleTy, Float128Ty;
CanQualType HalfTy; // [OpenCL 6.1.1.1], ARM NEON
+ CanQualType Float16Ty; // C11 extension ISO/IEC TS 18661-3
CanQualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy;
CanQualType Float128ComplexTy;
CanQualType VoidPtrTy, NullPtrTy;
@@ -1067,7 +1101,14 @@ public:
/// The resulting type has a union of the qualifiers from T and the address
/// space. If T already has an address space specifier, it is silently
/// replaced.
- QualType getAddrSpaceQualType(QualType T, unsigned AddressSpace) const;
+ QualType getAddrSpaceQualType(QualType T, LangAS AddressSpace) const;
+
+ /// \brief Remove any existing address space on the type and returns the type
+ /// with qualifiers intact (or that's the idea anyway)
+ ///
+ /// The return type should be T with all prior qualifiers minus the address
+ /// space.
+ QualType removeAddrSpaceQualType(QualType T) const;
/// \brief Apply Objective-C protocol qualifiers to the given type.
/// \param allowOnPointerType specifies if we can apply protocol
@@ -1175,6 +1216,7 @@ public:
/// \brief Return a read_only pipe type for the specified type.
QualType getReadPipeType(QualType T) const;
+
/// \brief Return a write_only pipe type for the specified type.
QualType getWritePipeType(QualType T) const;
@@ -1182,9 +1224,16 @@ public:
/// pointer to blocks.
QualType getBlockDescriptorExtendedType() const;
+ /// Map an AST Type to an OpenCLTypeKind enum value.
+ TargetInfo::OpenCLTypeKind getOpenCLTypeKind(const Type *T) const;
+
+ /// Get address space for OpenCL type.
+ LangAS getOpenCLTypeAddrSpace(const Type *T) const;
+
void setcudaConfigureCallDecl(FunctionDecl *FD) {
cudaConfigureCallDecl = FD;
}
+
FunctionDecl *getcudaConfigureCallDecl() {
return cudaConfigureCallDecl;
}
@@ -1192,7 +1241,6 @@ public:
/// Returns true iff we need copy/dispose helpers for the given type.
bool BlockRequiresCopying(QualType Ty, const VarDecl *D);
-
/// Returns true, if given type has a known lifetime. HasByrefExtendedLayout is set
/// to false in this case. If HasByrefExtendedLayout returns true, byref variable
/// has extended lifetime.
@@ -1269,6 +1317,10 @@ public:
Expr *SizeExpr,
SourceLocation AttrLoc) const;
+ QualType getDependentAddressSpaceType(QualType PointeeType,
+ Expr *AddrSpaceExpr,
+ SourceLocation AttrLoc) const;
+
/// \brief Return a K&R style C function type like 'int()'.
QualType getFunctionNoProtoType(QualType ResultTy,
const FunctionType::ExtInfo &Info) const;
@@ -1396,6 +1448,7 @@ public:
QualType Canonical = QualType()) const;
bool ObjCObjectAdoptsQTypeProtocols(QualType QT, ObjCInterfaceDecl *Decl);
+
/// QIdProtocolsAdoptObjCObjectProtocols - Checks that protocols in
/// QT's qualified-id protocol list adopt all protocols in IDecl's list
/// of protocols.
@@ -1426,7 +1479,7 @@ public:
/// \brief C++11 deduction pattern for 'auto &&' type.
QualType getAutoRRefDeductType() const;
- /// \brief C++1z deduced class template specialization type.
+ /// \brief C++17 deduced class template specialization type.
QualType getDeducedTemplateSpecializationType(TemplateName Template,
QualType DeducedType,
bool IsDependent) const;
@@ -1488,6 +1541,11 @@ public:
/// <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9).
QualType getPointerDiffType() const;
+ /// \brief Return the unique unsigned counterpart of "ptrdiff_t"
+ /// integer type. The standard (C11 7.21.6.1p7) refers to this type
+ /// in the definition of %tu format specifier.
+ QualType getUnsignedPointerDiffType() const;
+
/// \brief Return the unique type for "pid_t" defined in
/// <sys/types.h>. We need this to compute the correct type for vfork().
QualType getProcessIDType() const;
@@ -1581,6 +1639,24 @@ public:
return NSCopyingName;
}
+ CanQualType getNSUIntegerType() const {
+ assert(Target && "Expected target to be initialized");
+ const llvm::Triple &T = Target->getTriple();
+ // Windows is LLP64 rather than LP64
+ if (T.isOSWindows() && T.isArch64Bit())
+ return UnsignedLongLongTy;
+ return UnsignedLongTy;
+ }
+
+ CanQualType getNSIntegerType() const {
+ assert(Target && "Expected target to be initialized");
+ const llvm::Triple &T = Target->getTriple();
+ // Windows is LLP64 rather than LP64
+ if (T.isOSWindows() && T.isArch64Bit())
+ return LongLongTy;
+ return LongTy;
+ }
+
/// Retrieve the identifier 'bool'.
IdentifierInfo *getBoolName() const {
if (!BoolName)
@@ -1865,10 +1941,17 @@ public:
const TemplateArgument &ArgPack) const;
enum GetBuiltinTypeError {
- GE_None, ///< No error
- GE_Missing_stdio, ///< Missing a type from <stdio.h>
- GE_Missing_setjmp, ///< Missing a type from <setjmp.h>
- GE_Missing_ucontext ///< Missing a type from <ucontext.h>
+ /// No error
+ GE_None,
+
+ /// Missing a type from <stdio.h>
+ GE_Missing_stdio,
+
+ /// Missing a type from <setjmp.h>
+ GE_Missing_setjmp,
+
+ /// Missing a type from <ucontext.h>
+ GE_Missing_ucontext
};
/// \brief Return the type for the specified builtin.
@@ -2019,7 +2102,7 @@ public:
getASTObjCImplementationLayout(const ObjCImplementationDecl *D) const;
/// \brief Get our current best idea for the key function of the
- /// given record decl, or NULL if there isn't one.
+ /// given record decl, or nullptr if there isn't one.
///
/// The key function is, according to the Itanium C++ ABI section 5.2.3:
/// ...the first non-pure virtual function that is not inline at the
@@ -2072,6 +2155,10 @@ public:
void CollectInheritedProtocols(const Decl *CDecl,
llvm::SmallPtrSet<ObjCProtocolDecl*, 8> &Protocols);
+ /// \brief Return true if the specified type has unique object representations
+ /// according to (C++17 [meta.unary.prop]p9)
+ bool hasUniqueObjectRepresentations(QualType Ty) const;
+
//===--------------------------------------------------------------------===//
// Type Operators
//===--------------------------------------------------------------------===//
@@ -2103,7 +2190,6 @@ public:
bool hasSameType(QualType T1, QualType T2) const {
return getCanonicalType(T1) == getCanonicalType(T2);
}
-
bool hasSameType(const Type *T1, const Type *T2) const {
return getCanonicalType(T1) == getCanonicalType(T2);
}
@@ -2192,7 +2278,7 @@ public:
getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const;
/// \brief Retrieves the default calling convention for the current target.
- CallingConv getDefaultCallingConvention(bool isVariadic,
+ CallingConv getDefaultCallingConvention(bool IsVariadic,
bool IsCXXMethod) const;
/// \brief Retrieves the "canonical" template name that refers to a
@@ -2326,14 +2412,14 @@ public:
return getTargetAddressSpace(Q.getAddressSpace());
}
- unsigned getTargetAddressSpace(unsigned AS) const;
+ unsigned getTargetAddressSpace(LangAS AS) const;
/// Get target-dependent integer value for null pointer which is used for
/// constant folding.
uint64_t getTargetNullPointerValue(QualType QT) const;
- bool addressSpaceMapManglingFor(unsigned AS) const {
- return AddrSpaceMapMangling || AS >= LangAS::FirstTargetAddressSpace;
+ bool addressSpaceMapManglingFor(LangAS AS) const {
+ return AddrSpaceMapMangling || isTargetAddressSpace(AS);
}
private:
@@ -2355,12 +2441,15 @@ public:
bool isObjCIdType(QualType T) const {
return T == getObjCIdType();
}
+
bool isObjCClassType(QualType T) const {
return T == getObjCClassType();
}
+
bool isObjCSelType(QualType T) const {
return T == getObjCSelType();
}
+
bool ObjCQualifiedIdTypesAreCompatible(QualType LHS, QualType RHS,
bool ForCompare);
@@ -2394,9 +2483,30 @@ public:
QualType mergeObjCGCQualifiers(QualType, QualType);
- bool doFunctionTypesMatchOnExtParameterInfos(
- const FunctionProtoType *FromFunctionType,
- const FunctionProtoType *ToFunctionType);
+ /// This function merges the ExtParameterInfo lists of two functions. It
+ /// returns true if the lists are compatible. The merged list is returned in
+ /// NewParamInfos.
+ ///
+ /// \param FirstFnType The type of the first function.
+ ///
+ /// \param SecondFnType The type of the second function.
+ ///
+ /// \param CanUseFirst This flag is set to true if the first function's
+ /// ExtParameterInfo list can be used as the composite list of
+ /// ExtParameterInfo.
+ ///
+ /// \param CanUseSecond This flag is set to true if the second function's
+ /// ExtParameterInfo list can be used as the composite list of
+ /// ExtParameterInfo.
+ ///
+ /// \param NewParamInfos The composite list of ExtParameterInfo. The list is
+ /// empty if none of the flags are set.
+ ///
+ bool mergeExtParameterInfo(
+ const FunctionProtoType *FirstFnType,
+ const FunctionProtoType *SecondFnType,
+ bool &CanUseFirst, bool &CanUseSecond,
+ SmallVectorImpl<FunctionProtoType::ExtParameterInfo> &NewParamInfos);
void ResetObjCLayout(const ObjCContainerDecl *CD);
@@ -2432,12 +2542,13 @@ public:
bool isSentinelNullExpr(const Expr *E);
- /// \brief Get the implementation of the ObjCInterfaceDecl \p D, or NULL if
+ /// \brief Get the implementation of the ObjCInterfaceDecl \p D, or nullptr if
/// none exists.
ObjCImplementationDecl *getObjCImplementation(ObjCInterfaceDecl *D);
- /// \brief Get the implementation of the ObjCCategoryDecl \p D, or NULL if
+
+ /// \brief Get the implementation of the ObjCCategoryDecl \p D, or nullptr if
/// none exists.
- ObjCCategoryImplDecl *getObjCImplementation(ObjCCategoryDecl *D);
+ ObjCCategoryImplDecl *getObjCImplementation(ObjCCategoryDecl *D);
/// \brief Return true if there is at least one \@implementation in the TU.
bool AnyObjCImplementation() {
@@ -2447,6 +2558,7 @@ public:
/// \brief Set the implementation of ObjCInterfaceDecl.
void setObjCImplementation(ObjCInterfaceDecl *IFaceD,
ObjCImplementationDecl *ImplD);
+
/// \brief Set the implementation of ObjCCategoryDecl.
void setObjCImplementation(ObjCCategoryDecl *CatD,
ObjCCategoryImplDecl *ImplD);
@@ -2466,8 +2578,9 @@ public:
/// \brief Set the copy inialization expression of a block var decl.
void setBlockVarCopyInits(VarDecl*VD, Expr* Init);
+
/// \brief Get the copy initialization expression of the VarDecl \p VD, or
- /// NULL if none exists.
+ /// nullptr if none exists.
Expr *getBlockVarCopyInits(const VarDecl* VD);
/// \brief Allocate an uninitialized TypeSourceInfo.
@@ -2636,6 +2749,7 @@ private:
const FieldDecl *Field,
bool includeVBases = true,
QualType *NotEncodedT=nullptr) const;
+
public:
// Adds the encoding of a method parameter or return type.
void getObjCEncodingForMethodParameter(Decl::ObjCDeclQualifier QT,
@@ -2647,11 +2761,19 @@ public:
bool isMSStaticDataMemberInlineDefinition(const VarDecl *VD) const;
enum class InlineVariableDefinitionKind {
- None, ///< Not an inline variable.
- Weak, ///< Weak definition of inline variable.
- WeakUnknown, ///< Weak for now, might become strong later in this TU.
- Strong ///< Strong definition.
+ /// Not an inline variable.
+ None,
+
+ /// Weak definition of inline variable.
+ Weak,
+
+ /// Weak for now, might become strong later in this TU.
+ WeakUnknown,
+
+ /// Strong definition.
+ Strong
};
+
/// \brief Determine whether a definition of this inline variable should
/// be treated as a weak or strong definition. For compatibility with
/// C++14 and before, for a constexpr static data member, if there is an
@@ -2661,6 +2783,9 @@ public:
getInlineVariableDefinitionKind(const VarDecl *VD) const;
private:
+ friend class DeclarationNameTable;
+ friend class DeclContext;
+
const ASTRecordLayout &
getObjCLayout(const ObjCInterfaceDecl *D,
const ObjCImplementationDecl *Impl) const;
@@ -2673,26 +2798,23 @@ private:
// into the datastructures which avoids this mess during deallocation but is
// wasteful of memory, and here we require a lot of error prone book keeping
// in order to track and run destructors while we're tearing things down.
- typedef llvm::SmallVector<std::pair<void (*)(void *), void *>, 16>
- DeallocationFunctionsAndArguments;
+ using DeallocationFunctionsAndArguments =
+ llvm::SmallVector<std::pair<void (*)(void *), void *>, 16>;
DeallocationFunctionsAndArguments Deallocations;
// FIXME: This currently contains the set of StoredDeclMaps used
// by DeclContext objects. This probably should not be in ASTContext,
// but we include it here so that ASTContext can quickly deallocate them.
- llvm::PointerIntPair<StoredDeclsMap*,1> LastSDM;
-
- friend class DeclContext;
- friend class DeclarationNameTable;
-
- void ReleaseDeclContextMaps();
- void ReleaseParentMapEntries();
+ llvm::PointerIntPair<StoredDeclsMap *, 1> LastSDM;
std::unique_ptr<ParentMapPointers> PointerParents;
std::unique_ptr<ParentMapOtherNodes> OtherParents;
std::unique_ptr<VTableContextBase> VTContext;
+ void ReleaseDeclContextMaps();
+ void ReleaseParentMapEntries();
+
public:
enum PragmaSectionFlag : unsigned {
PSF_None = 0,
@@ -2712,27 +2834,26 @@ public:
SectionInfo(DeclaratorDecl *Decl,
SourceLocation PragmaSectionLocation,
int SectionFlags)
- : Decl(Decl),
- PragmaSectionLocation(PragmaSectionLocation),
- SectionFlags(SectionFlags) {}
+ : Decl(Decl), PragmaSectionLocation(PragmaSectionLocation),
+ SectionFlags(SectionFlags) {}
};
llvm::StringMap<SectionInfo> SectionInfos;
};
/// \brief Utility function for constructing a nullary selector.
-static inline Selector GetNullarySelector(StringRef name, ASTContext& Ctx) {
+inline Selector GetNullarySelector(StringRef name, ASTContext &Ctx) {
IdentifierInfo* II = &Ctx.Idents.get(name);
return Ctx.Selectors.getSelector(0, &II);
}
/// \brief Utility function for constructing an unary selector.
-static inline Selector GetUnarySelector(StringRef name, ASTContext& Ctx) {
+inline Selector GetUnarySelector(StringRef name, ASTContext &Ctx) {
IdentifierInfo* II = &Ctx.Idents.get(name);
return Ctx.Selectors.getSelector(1, &II);
}
-} // end namespace clang
+} // namespace clang
// operator new and delete aren't allowed inside namespaces.
@@ -2763,11 +2884,12 @@ static inline Selector GetUnarySelector(StringRef name, ASTContext& Ctx) {
/// @param C The ASTContext that provides the allocator.
/// @param Alignment The alignment of the allocated memory (if the underlying
/// allocator supports it).
-/// @return The allocated memory. Could be NULL.
+/// @return The allocated memory. Could be nullptr.
inline void *operator new(size_t Bytes, const clang::ASTContext &C,
size_t Alignment) {
return C.Allocate(Bytes, Alignment);
}
+
/// @brief Placement delete companion to the new above.
///
/// This operator is just a companion to the new above. There is no way of
@@ -2800,7 +2922,7 @@ inline void operator delete(void *Ptr, const clang::ASTContext &C, size_t) {
/// @param C The ASTContext that provides the allocator.
/// @param Alignment The alignment of the allocated memory (if the underlying
/// allocator supports it).
-/// @return The allocated memory. Could be NULL.
+/// @return The allocated memory. Could be nullptr.
inline void *operator new[](size_t Bytes, const clang::ASTContext& C,
size_t Alignment = 8) {
return C.Allocate(Bytes, Alignment);
diff --git a/include/clang/AST/ASTMutationListener.h b/include/clang/AST/ASTMutationListener.h
index a8eff1a2fcbb..9395d36d87e5 100644
--- a/include/clang/AST/ASTMutationListener.h
+++ b/include/clang/AST/ASTMutationListener.h
@@ -22,6 +22,7 @@ namespace clang {
class CXXRecordDecl;
class Decl;
class DeclContext;
+ class Expr;
class FieldDecl;
class FunctionDecl;
class FunctionTemplateDecl;
@@ -35,6 +36,7 @@ namespace clang {
class QualType;
class RecordDecl;
class TagDecl;
+ class ValueDecl;
class VarDecl;
class VarTemplateDecl;
class VarTemplateSpecializationDecl;
@@ -80,13 +82,19 @@ public:
/// \brief A virtual destructor's operator delete has been resolved.
virtual void ResolvedOperatorDelete(const CXXDestructorDecl *DD,
- const FunctionDecl *Delete) {}
+ const FunctionDecl *Delete,
+ Expr *ThisArg) {}
/// \brief An implicit member got a definition.
virtual void CompletedImplicitDefinition(const FunctionDecl *D) {}
- /// \brief A static data member was implicitly instantiated.
- virtual void StaticDataMemberInstantiated(const VarDecl *D) {}
+ /// \brief The instantiation of a templated function or variable was
+ /// requested. In particular, the point of instantiation and template
+ /// specialization kind of \p D may have changed.
+ virtual void InstantiationRequested(const ValueDecl *D) {}
+
+ /// \brief A templated variable's definition was implicitly instantiated.
+ virtual void VariableDefinitionInstantiated(const VarDecl *D) {}
/// \brief A function template's definition was instantiated.
virtual void FunctionDefinitionInstantiated(const FunctionDecl *D) {}
diff --git a/include/clang/AST/ASTUnresolvedSet.h b/include/clang/AST/ASTUnresolvedSet.h
index 9078a0e80299..3693aeccfe14 100644
--- a/include/clang/AST/ASTUnresolvedSet.h
+++ b/include/clang/AST/ASTUnresolvedSet.h
@@ -1,4 +1,4 @@
-//===-- ASTUnresolvedSet.h - Unresolved sets of declarations ---*- C++ -*-===//
+//===- ASTUnresolvedSet.h - Unresolved sets of declarations -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,14 +16,22 @@
#define LLVM_CLANG_AST_ASTUNRESOLVEDSET_H
#include "clang/AST/ASTVector.h"
+#include "clang/AST/DeclAccessPair.h"
#include "clang/AST/UnresolvedSet.h"
+#include "clang/Basic/Specifiers.h"
+#include <cassert>
+#include <cstdint>
namespace clang {
+class NamedDecl;
+
/// \brief An UnresolvedSet-like class which uses the ASTContext's allocator.
class ASTUnresolvedSet {
+ friend class LazyASTUnresolvedSet;
+
struct DeclsTy : ASTVector<DeclAccessPair> {
- DeclsTy() {}
+ DeclsTy() = default;
DeclsTy(ASTContext &C, unsigned N) : ASTVector<DeclAccessPair>(C, N) {}
bool isLazy() const { return getTag(); }
@@ -32,14 +40,12 @@ class ASTUnresolvedSet {
DeclsTy Decls;
- friend class LazyASTUnresolvedSet;
-
public:
- ASTUnresolvedSet() {}
+ ASTUnresolvedSet() = default;
ASTUnresolvedSet(ASTContext &C, unsigned N) : Decls(C, N) {}
- typedef UnresolvedSetIterator iterator;
- typedef UnresolvedSetIterator const_iterator;
+ using iterator = UnresolvedSetIterator;
+ using const_iterator = UnresolvedSetIterator;
iterator begin() { return iterator(Decls.begin()); }
iterator end() { return iterator(Decls.end()); }
@@ -98,13 +104,14 @@ public:
}
void reserve(ASTContext &C, unsigned N) { Impl.reserve(C, N); }
+
void addLazyDecl(ASTContext &C, uintptr_t ID, AccessSpecifier AS) {
assert(Impl.empty() || Impl.Decls.isLazy());
Impl.Decls.setLazy(true);
- Impl.addDecl(C, reinterpret_cast<NamedDecl*>(ID << 2), AS);
+ Impl.addDecl(C, reinterpret_cast<NamedDecl *>(ID << 2), AS);
}
};
} // namespace clang
-#endif
+#endif // LLVM_CLANG_AST_ASTUNRESOLVEDSET_H
diff --git a/include/clang/AST/ASTVector.h b/include/clang/AST/ASTVector.h
index 717a9e9dff34..80cd6b7007a6 100644
--- a/include/clang/AST/ASTVector.h
+++ b/include/clang/AST/ASTVector.h
@@ -1,4 +1,4 @@
-//===- ASTVector.h - Vector that uses ASTContext for allocation --*- C++ -*-=//
+//===- ASTVector.h - Vector that uses ASTContext for allocation ---*- C++ -*-=//
//
// The LLVM Compiler Infrastructure
//
@@ -18,22 +18,26 @@
#ifndef LLVM_CLANG_AST_ASTVECTOR_H
#define LLVM_CLANG_AST_ASTVECTOR_H
-#include "clang/AST/AttrIterator.h"
#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/Support/type_traits.h"
#include <algorithm>
+#include <cassert>
#include <cstddef>
#include <cstring>
+#include <iterator>
#include <memory>
+#include <type_traits>
+#include <utility>
namespace clang {
- class ASTContext;
+
+class ASTContext;
template<typename T>
class ASTVector {
private:
- T *Begin, *End;
- llvm::PointerIntPair<T*, 1, bool> Capacity;
+ T *Begin = nullptr;
+ T *End = nullptr;
+ llvm::PointerIntPair<T *, 1, bool> Capacity;
void setEnd(T *P) { this->End = P; }
@@ -45,7 +49,7 @@ protected:
public:
// Default ctor - Initialize to empty.
- ASTVector() : Begin(nullptr), End(nullptr), Capacity(nullptr, false) {}
+ ASTVector() : Capacity(nullptr, false) {}
ASTVector(ASTVector &&O) : Begin(O.Begin), End(O.End), Capacity(O.Capacity) {
O.Begin = O.End = nullptr;
@@ -53,14 +57,15 @@ public:
O.Capacity.setInt(false);
}
- ASTVector(const ASTContext &C, unsigned N)
- : Begin(nullptr), End(nullptr), Capacity(nullptr, false) {
+ ASTVector(const ASTContext &C, unsigned N) : Capacity(nullptr, false) {
reserve(C, N);
}
ASTVector &operator=(ASTVector &&RHS) {
ASTVector O(std::move(RHS));
+
using std::swap;
+
swap(Begin, O.Begin);
swap(End, O.End);
swap(Capacity, O.Capacity);
@@ -74,19 +79,19 @@ public:
}
}
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
- typedef T value_type;
- typedef T* iterator;
- typedef const T* const_iterator;
+ using size_type = size_t;
+ using difference_type = ptrdiff_t;
+ using value_type = T;
+ using iterator = T *;
+ using const_iterator = const T *;
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
- typedef std::reverse_iterator<iterator> reverse_iterator;
+ using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+ using reverse_iterator = std::reverse_iterator<iterator>;
- typedef T& reference;
- typedef const T& const_reference;
- typedef T* pointer;
- typedef const T* const_pointer;
+ using reference = T &;
+ using const_reference = const T &;
+ using pointer = T *;
+ using const_pointer = const T *;
// forward iterator creation methods.
iterator begin() { return Begin; }
@@ -175,7 +180,6 @@ public:
size_t capacity() const { return this->capacity_ptr() - Begin; }
/// append - Add the specified range to the end of the SmallVector.
- ///
template<typename in_iter>
void append(const ASTContext &C, in_iter in_start, in_iter in_end) {
size_type NumInputs = std::distance(in_start, in_end);
@@ -195,7 +199,6 @@ public:
}
/// append - Add the specified range to the end of the SmallVector.
- ///
void append(const ASTContext &C, size_type NumInputs, const T &Elt) {
// Grow allocated space if needed.
if (NumInputs > size_type(this->capacity_ptr()-this->end()))
@@ -368,6 +371,7 @@ protected:
const_iterator capacity_ptr() const {
return (iterator) Capacity.getPointer();
}
+
iterator capacity_ptr() { return (iterator)Capacity.getPointer(); }
};
@@ -401,5 +405,6 @@ void ASTVector<T>::grow(const ASTContext &C, size_t MinSize) {
Capacity.setPointer(Begin+NewCapacity);
}
-} // end: clang namespace
-#endif
+} // namespace clang
+
+#endif // LLVM_CLANG_AST_ASTVECTOR_H
diff --git a/include/clang/AST/AttrIterator.h b/include/clang/AST/AttrIterator.h
index fb9b049e5d6b..56807b4590d3 100644
--- a/include/clang/AST/AttrIterator.h
+++ b/include/clang/AST/AttrIterator.h
@@ -1,4 +1,4 @@
-//===--- AttrIterator.h - Classes for attribute iteration -------*- C++ -*-===//
+//===- AttrIterator.h - Classes for attribute iteration ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,16 +15,23 @@
#define LLVM_CLANG_AST_ATTRITERATOR_H
#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Casting.h"
+#include <cassert>
+#include <cstddef>
#include <iterator>
namespace clang {
- class ASTContext;
- class Attr;
-}
+
+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,
@@ -39,13 +46,13 @@ 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.
-typedef SmallVector<Attr *, 4> AttrVec;
+using AttrVec = SmallVector<Attr *, 4>;
/// specific_attr_iterator - Iterates over a subrange of an AttrVec, only
/// providing attributes that are of a specific type.
template <typename SpecificAttr, typename Container = AttrVec>
class specific_attr_iterator {
- typedef typename Container::const_iterator Iterator;
+ using Iterator = typename Container::const_iterator;
/// Current - The current, underlying iterator.
/// In order to ensure we don't dereference an invalid iterator unless
@@ -67,14 +74,14 @@ class specific_attr_iterator {
}
public:
- typedef SpecificAttr* value_type;
- typedef SpecificAttr* reference;
- typedef SpecificAttr* pointer;
- typedef std::forward_iterator_tag iterator_category;
- typedef std::ptrdiff_t difference_type;
+ using value_type = SpecificAttr *;
+ using reference = SpecificAttr *;
+ using pointer = SpecificAttr *;
+ using iterator_category = std::forward_iterator_tag;
+ using difference_type = std::ptrdiff_t;
- specific_attr_iterator() : Current() { }
- explicit specific_attr_iterator(Iterator i) : Current(i) { }
+ specific_attr_iterator() = default;
+ explicit specific_attr_iterator(Iterator i) : Current(i) {}
reference operator*() const {
AdvanceToNext();
@@ -136,6 +143,6 @@ inline SpecificAttr *getSpecificAttr(const Container& container) {
return nullptr;
}
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_AST_ATTRITERATOR_H
diff --git a/include/clang/AST/BaseSubobject.h b/include/clang/AST/BaseSubobject.h
index 66af023c828e..fdb7e718fe9e 100644
--- a/include/clang/AST/BaseSubobject.h
+++ b/include/clang/AST/BaseSubobject.h
@@ -1,4 +1,4 @@
-//===--- BaseSubobject.h - BaseSubobject class ----------------------------===//
+//===- BaseSubobject.h - BaseSubobject class --------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,12 +15,15 @@
#define LLVM_CLANG_AST_BASESUBOBJECT_H
#include "clang/AST/CharUnits.h"
-#include "clang/AST/DeclCXX.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/Support/DataTypes.h"
+#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/Support/type_traits.h"
+#include <cstdint>
+#include <utility>
namespace clang {
+
+class CXXRecordDecl;
+
// BaseSubobject - Uniquely identifies a direct or indirect base class.
// Stores both the base class decl and the offset from the most derived class to
// the base class. Used for vtable and VTT generation.
@@ -32,9 +35,9 @@ class BaseSubobject {
CharUnits BaseOffset;
public:
- BaseSubobject() { }
+ BaseSubobject() = default;
BaseSubobject(const CXXRecordDecl *Base, CharUnits BaseOffset)
- : Base(Base), BaseOffset(BaseOffset) { }
+ : Base(Base), BaseOffset(BaseOffset) {}
/// getBase - Returns the base class declaration.
const CXXRecordDecl *getBase() const { return Base; }
@@ -47,7 +50,7 @@ public:
}
};
-} // end namespace clang
+} // namespace clang
namespace llvm {
@@ -65,7 +68,8 @@ template<> struct DenseMapInfo<clang::BaseSubobject> {
}
static unsigned getHashValue(const clang::BaseSubobject &Base) {
- typedef std::pair<const clang::CXXRecordDecl *, clang::CharUnits> PairTy;
+ using PairTy = std::pair<const clang::CXXRecordDecl *, clang::CharUnits>;
+
return DenseMapInfo<PairTy>::getHashValue(PairTy(Base.getBase(),
Base.getBaseOffset()));
}
@@ -81,6 +85,6 @@ template <> struct isPodLike<clang::BaseSubobject> {
static const bool value = true;
};
-}
+} // namespace llvm
-#endif
+#endif // LLVM_CLANG_AST_BASESUBOBJECT_H
diff --git a/include/clang/AST/BuiltinTypes.def b/include/clang/AST/BuiltinTypes.def
index 181131aba07f..e4f5f7db2f73 100644
--- a/include/clang/AST/BuiltinTypes.def
+++ b/include/clang/AST/BuiltinTypes.def
@@ -133,6 +133,9 @@ FLOATING_TYPE(Double, DoubleTy)
// 'long double'
FLOATING_TYPE(LongDouble, LongDoubleTy)
+// '_Float16'
+FLOATING_TYPE(Float16, HalfTy)
+
// '__float128'
FLOATING_TYPE(Float128, Float128Ty)
diff --git a/include/clang/AST/CMakeLists.txt b/include/clang/AST/CMakeLists.txt
index 260734f2200a..942d08d585fe 100644
--- a/include/clang/AST/CMakeLists.txt
+++ b/include/clang/AST/CMakeLists.txt
@@ -50,3 +50,6 @@ clang_tablegen(CommentCommandList.inc -gen-clang-comment-command-list
SOURCE CommentCommands.td
TARGET ClangCommentCommandList)
+clang_tablegen(StmtDataCollectors.inc -gen-clang-data-collectors
+ SOURCE StmtDataCollectors.td
+ TARGET StmtDataCollectors)
diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h
index 980608570fd6..11fb229f0c09 100644
--- a/include/clang/AST/CXXInheritance.h
+++ b/include/clang/AST/CXXInheritance.h
@@ -1,4 +1,4 @@
-//===------ CXXInheritance.h - C++ Inheritance ------------------*- C++ -*-===//
+//===- CXXInheritance.h - C++ Inheritance -----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,19 +16,23 @@
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclarationName.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeOrdering.h"
+#include "clang/Basic/Specifiers.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
-#include <cassert>
+#include "llvm/ADT/iterator_range.h"
#include <list>
+#include <memory>
+#include <utility>
namespace clang {
-
-class CXXBaseSpecifier;
-class CXXMethodDecl;
-class CXXRecordDecl;
+
+class ASTContext;
class NamedDecl;
/// \brief Represents an element in a path from a derived class to a
@@ -66,12 +70,12 @@ struct CXXBasePathElement {
/// subobject is being used.
class CXXBasePath : public SmallVector<CXXBasePathElement, 4> {
public:
- CXXBasePath() : Access(AS_public) {}
-
/// \brief The access along this inheritance path. This is only
/// calculated when recording paths. AS_none is a special value
/// used to indicate a path which permits no legal access.
- AccessSpecifier Access;
+ AccessSpecifier Access = AS_public;
+
+ CXXBasePath() = default;
/// \brief The set of declarations found inside this base class
/// subobject.
@@ -113,8 +117,10 @@ public:
/// refer to the same base class subobject of type A (the virtual
/// one), there is no ambiguity.
class CXXBasePaths {
+ friend class CXXRecordDecl;
+
/// \brief The type from which this search originated.
- CXXRecordDecl *Origin;
+ CXXRecordDecl *Origin = nullptr;
/// Paths - The actual set of paths that can be taken from the
/// derived class to the same base class.
@@ -152,15 +158,13 @@ class CXXBasePaths {
CXXBasePath ScratchPath;
/// DetectedVirtual - The base class that is virtual.
- const RecordType *DetectedVirtual;
+ const RecordType *DetectedVirtual = nullptr;
/// \brief Array of the declarations that have been found. This
/// array is constructed only if needed, e.g., to iterate over the
/// results within LookupResult.
std::unique_ptr<NamedDecl *[]> DeclsFound;
- unsigned NumDeclsFound;
-
- friend class CXXRecordDecl;
+ unsigned NumDeclsFound = 0;
void ComputeDeclsFound();
@@ -169,17 +173,16 @@ class CXXBasePaths {
bool LookupInDependent = false);
public:
- typedef std::list<CXXBasePath>::iterator paths_iterator;
- typedef std::list<CXXBasePath>::const_iterator const_paths_iterator;
- typedef NamedDecl **decl_iterator;
+ using paths_iterator = std::list<CXXBasePath>::iterator;
+ using const_paths_iterator = std::list<CXXBasePath>::const_iterator;
+ using decl_iterator = NamedDecl **;
/// BasePaths - Construct a new BasePaths structure to record the
/// paths for a derived-to-base search.
explicit CXXBasePaths(bool FindAmbiguities = true, bool RecordPaths = true,
bool DetectVirtual = true)
- : Origin(), FindAmbiguities(FindAmbiguities), RecordPaths(RecordPaths),
- DetectVirtual(DetectVirtual), DetectedVirtual(nullptr),
- NumDeclsFound(0) {}
+ : FindAmbiguities(FindAmbiguities), RecordPaths(RecordPaths),
+ DetectVirtual(DetectVirtual) {}
paths_iterator begin() { return Paths.begin(); }
paths_iterator end() { return Paths.end(); }
@@ -189,7 +192,8 @@ public:
CXXBasePath& front() { return Paths.front(); }
const CXXBasePath& front() const { return Paths.front(); }
- typedef llvm::iterator_range<decl_iterator> decl_range;
+ using decl_range = llvm::iterator_range<decl_iterator>;
+
decl_range found_decls();
/// \brief Determine whether the path from the most-derived type to the
@@ -231,25 +235,24 @@ public:
/// \brief Uniquely identifies a virtual method within a class
/// hierarchy by the method itself and a class subobject number.
struct UniqueVirtualMethod {
- UniqueVirtualMethod()
- : Method(nullptr), Subobject(0), InVirtualSubobject(nullptr) { }
-
- UniqueVirtualMethod(CXXMethodDecl *Method, unsigned Subobject,
- const CXXRecordDecl *InVirtualSubobject)
- : Method(Method), Subobject(Subobject),
- InVirtualSubobject(InVirtualSubobject) { }
-
/// \brief The overriding virtual method.
- CXXMethodDecl *Method;
+ CXXMethodDecl *Method = nullptr;
/// \brief The subobject in which the overriding virtual method
/// resides.
- unsigned Subobject;
+ unsigned Subobject = 0;
/// \brief The virtual base class subobject of which this overridden
/// virtual method is a part. Note that this records the closest
/// derived virtual base class subobject.
- const CXXRecordDecl *InVirtualSubobject;
+ const CXXRecordDecl *InVirtualSubobject = nullptr;
+
+ UniqueVirtualMethod() = default;
+
+ UniqueVirtualMethod(CXXMethodDecl *Method, unsigned Subobject,
+ const CXXRecordDecl *InVirtualSubobject)
+ : Method(Method), Subobject(Subobject),
+ InVirtualSubobject(InVirtualSubobject) {}
friend bool operator==(const UniqueVirtualMethod &X,
const UniqueVirtualMethod &Y) {
@@ -271,14 +274,16 @@ struct UniqueVirtualMethod {
/// pair is the virtual method that overrides it (including the
/// subobject in which that virtual function occurs).
class OverridingMethods {
- typedef SmallVector<UniqueVirtualMethod, 4> ValuesT;
- typedef llvm::MapVector<unsigned, ValuesT> MapType;
+ using ValuesT = SmallVector<UniqueVirtualMethod, 4>;
+ using MapType = llvm::MapVector<unsigned, ValuesT>;
+
MapType Overrides;
public:
// Iterate over the set of subobjects that have overriding methods.
- typedef MapType::iterator iterator;
- typedef MapType::const_iterator const_iterator;
+ using iterator = MapType::iterator;
+ using const_iterator = MapType::const_iterator;
+
iterator begin() { return Overrides.begin(); }
const_iterator begin() const { return Overrides.begin(); }
iterator end() { return Overrides.end(); }
@@ -287,10 +292,10 @@ public:
// Iterate over the set of overriding virtual methods in a given
// subobject.
- typedef SmallVectorImpl<UniqueVirtualMethod>::iterator
- overriding_iterator;
- typedef SmallVectorImpl<UniqueVirtualMethod>::const_iterator
- overriding_const_iterator;
+ using overriding_iterator =
+ SmallVectorImpl<UniqueVirtualMethod>::iterator;
+ using overriding_const_iterator =
+ SmallVectorImpl<UniqueVirtualMethod>::const_iterator;
// Add a new overriding method for a particular subobject.
void add(unsigned OverriddenSubobject, UniqueVirtualMethod Overriding);
@@ -357,12 +362,12 @@ public:
/// subobject numbers greater than 0 refer to non-virtual base class
/// subobjects of that type.
class CXXFinalOverriderMap
- : public llvm::MapVector<const CXXMethodDecl *, OverridingMethods> { };
+ : public llvm::MapVector<const CXXMethodDecl *, OverridingMethods> {};
/// \brief A set of all the primary bases for a class.
class CXXIndirectPrimaryBaseSet
- : public llvm::SmallSet<const CXXRecordDecl*, 32> { };
+ : public llvm::SmallSet<const CXXRecordDecl*, 32> {};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_AST_CXXINHERITANCE_H
diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h
index 25f6172be9b1..6487613200de 100644
--- a/include/clang/AST/CanonicalType.h
+++ b/include/clang/AST/CanonicalType.h
@@ -1,4 +1,4 @@
-//===-- CanonicalType.h - C Language Family Type Representation -*- C++ -*-===//
+//===- CanonicalType.h - C Language Family Type Representation --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,13 +16,29 @@
#define LLVM_CLANG_AST_CANONICALTYPE_H
#include "clang/AST/Type.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/iterator.h"
#include "llvm/Support/Casting.h"
+#include "llvm/Support/PointerLikeTypeTraits.h"
+#include <cassert>
+#include <iterator>
+#include <type_traits>
namespace clang {
template<typename T> class CanProxy;
template<typename T> struct CanProxyAdaptor;
+class CXXRecordDecl;
+class EnumDecl;
+class Expr;
+class IdentifierInfo;
+class ObjCInterfaceDecl;
+class RecordDecl;
+class TagDecl;
+class TemplateTypeParmDecl;
//----------------------------------------------------------------------------//
// Canonical, qualified type template
@@ -46,8 +62,6 @@ template<typename T> struct CanProxyAdaptor;
/// converted to @c CanQual<ReferenceType>. Note that any @c CanQual type can
/// be implicitly converted to a QualType, but the reverse operation requires
/// a call to ASTContext::getCanonicalType().
-///
-///
template<typename T = Type>
class CanQual {
/// \brief The actual, canonical type.
@@ -55,7 +69,7 @@ class CanQual {
public:
/// \brief Constructs a NULL canonical type.
- CanQual() : Stored() { }
+ CanQual() = default;
/// \brief Converting constructor that permits implicit upcasting of
/// canonical type pointers.
@@ -66,12 +80,11 @@ public:
/// \brief Retrieve the underlying type pointer, which refers to a
/// canonical type.
///
- /// The underlying pointer must not be NULL.
+ /// The underlying pointer must not be nullptr.
const T *getTypePtr() const { return cast<T>(Stored.getTypePtr()); }
/// \brief Retrieve the underlying type pointer, which refers to a
- /// canonical type, or NULL.
- ///
+ /// canonical type, or nullptr.
const T *getTypePtrOrNull() const {
return cast_or_null<T>(Stored.getTypePtrOrNull());
}
@@ -125,9 +138,11 @@ public:
bool isConstQualified() const {
return Stored.isLocalConstQualified();
}
+
bool isVolatileQualified() const {
return Stored.isLocalVolatileQualified();
}
+
bool isRestrictQualified() const {
return Stored.isLocalRestrictQualified();
}
@@ -195,7 +210,7 @@ inline bool operator!=(CanQual<T> x, CanQual<U> y) {
}
/// \brief Represents a canonical, potentially-qualified type.
-typedef CanQual<Type> CanQualType;
+using CanQualType = CanQual<Type>;
inline CanQualType Type::getCanonicalTypeUnqualified() const {
return CanQualType::CreateUnsafe(getCanonicalTypeInternal());
@@ -320,7 +335,7 @@ public:
/// than the more typical @c QualType, to propagate the notion of "canonical"
/// through the system.
template<typename T>
-struct CanProxyAdaptor : CanProxyBase<T> { };
+struct CanProxyAdaptor : CanProxyBase<T> {};
/// \brief Canonical proxy type returned when retrieving the members of a
/// canonical type or as the result of the @c CanQual<T>::getAs member
@@ -333,7 +348,7 @@ template<typename T>
class CanProxy : public CanProxyAdaptor<T> {
public:
/// \brief Build a NULL proxy.
- CanProxy() { }
+ CanProxy() = default;
/// \brief Build a proxy to the given canonical type.
CanProxy(CanQual<T> Stored) { this->Stored = Stored; }
@@ -342,7 +357,7 @@ public:
operator CanQual<T>() const { return this->Stored; }
};
-} // end namespace clang
+} // namespace clang
namespace llvm {
@@ -350,8 +365,9 @@ namespace llvm {
/// CanQual<T> to a specific Type class. We're prefer isa/dyn_cast/cast/etc.
/// to return smart pointer (proxies?).
template<typename T>
-struct simplify_type< ::clang::CanQual<T> > {
- typedef const T *SimpleType;
+struct simplify_type< ::clang::CanQual<T>> {
+ using SimpleType = const T *;
+
static SimpleType getSimplifiedValue(::clang::CanQual<T> Val) {
return Val.getTypePtr();
}
@@ -359,19 +375,20 @@ struct simplify_type< ::clang::CanQual<T> > {
// Teach SmallPtrSet that CanQual<T> is "basically a pointer".
template<typename T>
-class PointerLikeTypeTraits<clang::CanQual<T> > {
-public:
- static inline void *getAsVoidPointer(clang::CanQual<T> P) {
+struct PointerLikeTypeTraits<clang::CanQual<T>> {
+ static void *getAsVoidPointer(clang::CanQual<T> P) {
return P.getAsOpaquePtr();
}
- static inline clang::CanQual<T> getFromVoidPointer(void *P) {
+
+ static clang::CanQual<T> getFromVoidPointer(void *P) {
return clang::CanQual<T>::getFromOpaquePtr(P);
}
+
// qualifier information is encoded in the low bits.
enum { NumLowBitsAvailable = 0 };
};
-} // end namespace llvm
+} // namespace llvm
namespace clang {
@@ -389,7 +406,7 @@ struct CanTypeIterator
CanQualType,
typename std::iterator_traits<InputIterator>::difference_type,
CanProxy<Type>, CanQualType> {
- CanTypeIterator() {}
+ CanTypeIterator() = default;
explicit CanTypeIterator(InputIterator Iter)
: CanTypeIterator::iterator_adaptor_base(std::move(Iter)) {}
@@ -487,6 +504,7 @@ struct CanProxyAdaptor<FunctionProtoType>
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasExtParameterInfos)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(
ArrayRef<FunctionProtoType::ExtParameterInfo>, getExtParameterInfos)
+
CanQualType getParamType(unsigned i) const {
return CanQualType::CreateUnsafe(this->getTypePtr()->getParamType(i));
}
@@ -494,8 +512,8 @@ struct CanProxyAdaptor<FunctionProtoType>
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariadic)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getTypeQuals)
- typedef CanTypeIterator<FunctionProtoType::param_type_iterator>
- param_type_iterator;
+ using param_type_iterator =
+ CanTypeIterator<FunctionProtoType::param_type_iterator>;
param_type_iterator param_type_begin() const {
return param_type_iterator(this->getTypePtr()->param_type_begin());
@@ -567,7 +585,8 @@ struct CanProxyAdaptor<ObjCObjectType>
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedId)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClass)
- typedef ObjCObjectPointerType::qual_iterator qual_iterator;
+ using qual_iterator = ObjCObjectPointerType::qual_iterator;
+
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
@@ -585,7 +604,8 @@ struct CanProxyAdaptor<ObjCObjectPointerType>
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedIdType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClassType)
- typedef ObjCObjectPointerType::qual_iterator qual_iterator;
+ using qual_iterator = ObjCObjectPointerType::qual_iterator;
+
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
@@ -662,7 +682,6 @@ CanProxy<Type> CanTypeIterator<InputIterator>::operator->() const {
return CanProxy<Type>(*this);
}
-}
-
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_AST_CANONICALTYPE_H
diff --git a/include/clang/AST/CharUnits.h b/include/clang/AST/CharUnits.h
index 564c8ec9b9ea..ddead6046a14 100644
--- a/include/clang/AST/CharUnits.h
+++ b/include/clang/AST/CharUnits.h
@@ -40,14 +40,14 @@ namespace clang {
typedef int64_t QuantityType;
private:
- QuantityType Quantity;
+ QuantityType Quantity = 0;
explicit CharUnits(QuantityType C) : Quantity(C) {}
public:
/// CharUnits - A default constructor.
- CharUnits() : Quantity(0) {}
+ CharUnits() = default;
/// Zero - Construct a CharUnits quantity of zero.
static CharUnits Zero() {
diff --git a/include/clang/AST/CommentVisitor.h b/include/clang/AST/CommentVisitor.h
index 21641bfeb89f..d1cc2d0a4e5e 100644
--- a/include/clang/AST/CommentVisitor.h
+++ b/include/clang/AST/CommentVisitor.h
@@ -1,4 +1,4 @@
-//===--- CommentVisitor.h - Visitor for Comment subclasses ------*- C++ -*-===//
+//===- CommentVisitor.h - Visitor for Comment subclasses --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,8 +16,8 @@
namespace clang {
namespace comments {
-template <typename T> struct make_ptr { typedef T *type; };
-template <typename T> struct make_const_ptr { typedef const T *type; };
+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>
class CommentVisitorBase {
@@ -64,7 +64,7 @@ template<typename ImplClass, typename RetTy=void>
class ConstCommentVisitor :
public CommentVisitorBase<make_const_ptr, ImplClass, RetTy> {};
-} // end namespace comments
-} // end namespace clang
+} // namespace comments
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_AST_COMMENTVISITOR_H
diff --git a/include/clang/AST/DataCollection.h b/include/clang/AST/DataCollection.h
new file mode 100644
index 000000000000..229ac2bd0f22
--- /dev/null
+++ b/include/clang/AST/DataCollection.h
@@ -0,0 +1,65 @@
+//===--- DatatCollection.h --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// \brief This file declares helper methods for collecting data from AST nodes.
+///
+/// To collect data from Stmt nodes, subclass ConstStmtVisitor and include
+/// StmtDataCollectors.inc after defining the macros that you need. This
+/// provides data collection implementations for most Stmt kinds. Note
+/// that that code requires some conditions to be met:
+///
+/// - There must be a method addData(const T &Data) that accepts strings,
+/// integral types as well as QualType. All data is forwarded using
+/// to this method.
+/// - The ASTContext of the Stmt must be accessible by the name Context.
+///
+/// It is also possible to override individual visit methods. Have a look at
+/// the DataCollector in lib/Analysis/CloneDetection.cpp for a usage example.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_DATACOLLECTION_H
+#define LLVM_CLANG_AST_DATACOLLECTION_H
+
+#include "clang/AST/ASTContext.h"
+
+namespace clang {
+namespace data_collection {
+
+/// Returns a string that represents all macro expansions that expanded into the
+/// given SourceLocation.
+///
+/// If 'getMacroStack(A) == getMacroStack(B)' is true, then the SourceLocations
+/// A and B are expanded from the same macros in the same order.
+std::string getMacroStack(SourceLocation Loc, ASTContext &Context);
+
+/// Utility functions for implementing addData() for a consumer that has a
+/// method update(StringRef)
+template <class T>
+void addDataToConsumer(T &DataConsumer, llvm::StringRef Str) {
+ DataConsumer.update(Str);
+}
+
+template <class T> void addDataToConsumer(T &DataConsumer, const QualType &QT) {
+ addDataToConsumer(DataConsumer, QT.getAsString());
+}
+
+template <class T, class Type>
+typename std::enable_if<
+ std::is_integral<Type>::value || std::is_enum<Type>::value ||
+ std::is_convertible<Type, size_t>::value // for llvm::hash_code
+ >::type
+addDataToConsumer(T &DataConsumer, Type Data) {
+ DataConsumer.update(StringRef(reinterpret_cast<char *>(&Data), sizeof(Data)));
+}
+
+} // end namespace data_collection
+} // end namespace clang
+
+#endif // LLVM_CLANG_AST_DATACOLLECTION_H
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 54e6ebcd8af2..4db0b1ef949b 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -1,4 +1,4 @@
-//===--- Decl.h - Classes for representing declarations ---------*- C++ -*-===//
+//===- Decl.h - Classes for representing declarations -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -18,33 +18,58 @@
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/ExternalASTSource.h"
+#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/Redeclarable.h"
#include "clang/AST/Type.h"
+#include "clang/Basic/AddressSpaces.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LLVM.h"
#include "clang/Basic/Linkage.h"
-#include "clang/Basic/Module.h"
#include "clang/Basic/OperatorKinds.h"
+#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/PragmaKinds.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/Specifiers.h"
+#include "clang/Basic/Visibility.h"
+#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/TrailingObjects.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <string>
+#include <utility>
namespace clang {
+
+class ASTContext;
struct ASTTemplateArgumentListInfo;
-class CXXTemporary;
+class Attr;
class CompoundStmt;
class DependentFunctionTemplateSpecializationInfo;
+class EnumDecl;
class Expr;
class FunctionTemplateDecl;
class FunctionTemplateSpecializationInfo;
class LabelStmt;
class MemberSpecializationInfo;
-class NestedNameSpecifier;
+class Module;
+class NamespaceDecl;
class ParmVarDecl;
+class RecordDecl;
class Stmt;
class StringLiteral;
+class TagDecl;
class TemplateArgumentList;
+class TemplateArgumentListInfo;
class TemplateParameterList;
class TypeAliasTemplateDecl;
class TypeLoc;
@@ -58,13 +83,15 @@ class VarTemplateDecl;
/// TypeLoc TL = TypeSourceInfo->getTypeLoc();
/// TL.getStartLoc().print(OS, SrcMgr);
/// @endcode
-///
class TypeSourceInfo {
- QualType Ty;
// Contains a memory block after the class, used for type source information,
// allocated by ASTContext.
friend class ASTContext;
- TypeSourceInfo(QualType ty) : Ty(ty) { }
+
+ QualType Ty;
+
+ TypeSourceInfo(QualType ty) : Ty(ty) {}
+
public:
/// \brief Return the type wrapped by this type source info.
QualType getType() const { return Ty; }
@@ -78,14 +105,16 @@ public:
/// TranslationUnitDecl - The top declaration context.
class TranslationUnitDecl : public Decl, public DeclContext {
- virtual void anchor();
ASTContext &Ctx;
/// The (most recently entered) anonymous namespace for this
/// translation unit, if one has been created.
- NamespaceDecl *AnonymousNamespace;
+ NamespaceDecl *AnonymousNamespace = nullptr;
explicit TranslationUnitDecl(ASTContext &ctx);
+
+ virtual void anchor();
+
public:
ASTContext &getASTContext() const { return Ctx; }
@@ -93,6 +122,7 @@ public:
void setAnonymousNamespace(NamespaceDecl *D) { AnonymousNamespace = D; }
static TranslationUnitDecl *Create(ASTContext &C);
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == TranslationUnit; }
@@ -109,18 +139,18 @@ public:
class PragmaCommentDecl final
: public Decl,
private llvm::TrailingObjects<PragmaCommentDecl, char> {
- virtual void anchor();
-
- PragmaMSCommentKind CommentKind;
-
- friend TrailingObjects;
friend class ASTDeclReader;
friend class ASTDeclWriter;
+ friend TrailingObjects;
+
+ PragmaMSCommentKind CommentKind;
PragmaCommentDecl(TranslationUnitDecl *TU, SourceLocation CommentLoc,
PragmaMSCommentKind CommentKind)
: Decl(PragmaComment, TU, CommentLoc), CommentKind(CommentKind) {}
+ virtual void anchor();
+
public:
static PragmaCommentDecl *Create(const ASTContext &C, TranslationUnitDecl *DC,
SourceLocation CommentLoc,
@@ -143,18 +173,18 @@ public:
class PragmaDetectMismatchDecl final
: public Decl,
private llvm::TrailingObjects<PragmaDetectMismatchDecl, char> {
- virtual void anchor();
-
- size_t ValueStart;
-
- friend TrailingObjects;
friend class ASTDeclReader;
friend class ASTDeclWriter;
+ friend TrailingObjects;
+
+ size_t ValueStart;
PragmaDetectMismatchDecl(TranslationUnitDecl *TU, SourceLocation Loc,
size_t ValueStart)
: Decl(PragmaDetectMismatch, TU, Loc), ValueStart(ValueStart) {}
+ virtual void anchor();
+
public:
static PragmaDetectMismatchDecl *Create(const ASTContext &C,
TranslationUnitDecl *DC,
@@ -189,14 +219,16 @@ public:
/// The declaration at #3 finds it is a redeclaration of \c N::f through
/// lookup in the extern "C" context.
class ExternCContextDecl : public Decl, public DeclContext {
- virtual void anchor();
-
explicit ExternCContextDecl(TranslationUnitDecl *TU)
: Decl(ExternCContext, TU, SourceLocation()),
DeclContext(ExternCContext) {}
+
+ virtual void anchor();
+
public:
static ExternCContextDecl *Create(const ASTContext &C,
TranslationUnitDecl *TU);
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == ExternCContext; }
@@ -211,18 +243,19 @@ public:
/// NamedDecl - This represents a decl with a name. Many decls have names such
/// as ObjCMethodDecl, but not \@class, etc.
class NamedDecl : public Decl {
- virtual void anchor();
/// Name - The name of this declaration, which is typically a normal
/// identifier but may also be a special kind of name (C++
/// constructor, Objective-C selector, etc.)
DeclarationName Name;
+ virtual void anchor();
+
private:
NamedDecl *getUnderlyingDeclImpl() LLVM_READONLY;
protected:
NamedDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N)
- : Decl(DK, DC, L), Name(N) { }
+ : Decl(DK, DC, L), Name(N) {}
public:
/// getIdentifier - Get the identifier that names this declaration,
@@ -272,8 +305,7 @@ public:
// FIXME: Remove string version.
std::string getQualifiedNameAsString() const;
- /// getNameForDiagnostic - Appends a human-readable name for this
- /// declaration into the given stream.
+ /// Appends a human-readable name for this declaration into the given stream.
///
/// This is the method invoked by Sema when displaying a NamedDecl
/// in a diagnostic. It does not necessarily produce the same
@@ -339,6 +371,12 @@ public:
return clang::isExternallyVisible(getLinkageInternal());
}
+ /// Determine whether this declaration can be redeclared in a
+ /// different translation unit.
+ bool isExternallyDeclarable() const {
+ return isExternallyVisible() && !getOwningModuleForLinkage();
+ }
+
/// \brief Determines the visibility of this entity.
Visibility getVisibility() const {
return getLinkageAndVisibility().getVisibility();
@@ -349,7 +387,14 @@ public:
/// Kinds of explicit visibility.
enum ExplicitVisibilityKind {
+ /// Do an LV computation for, ultimately, a type.
+ /// Visibility may be restricted by type visibility settings and
+ /// the visibility of template arguments.
VisibilityForType,
+
+ /// Do an LV computation for, ultimately, a non-type declaration.
+ /// Visibility may be restricted by value visibility settings and
+ /// the visibility of template arguments.
VisibilityForValue
};
@@ -412,10 +457,10 @@ inline raw_ostream &operator<<(raw_ostream &OS, const NamedDecl &ND) {
/// location of the statement. For GNU local labels (__label__), the decl
/// location is where the __label__ is.
class LabelDecl : public NamedDecl {
- void anchor() override;
LabelStmt *TheStmt;
StringRef MSAsmName;
- bool MSAsmNameResolved;
+ bool MSAsmNameResolved = false;
+
/// LocStart - For normal labels, this is the same as the main declaration
/// label, i.e., the location of the identifier; for GNU local labels,
/// this is the location of the __label__ keyword.
@@ -423,10 +468,9 @@ class LabelDecl : public NamedDecl {
LabelDecl(DeclContext *DC, SourceLocation IdentL, IdentifierInfo *II,
LabelStmt *S, SourceLocation StartL)
- : NamedDecl(Label, DC, IdentL, II),
- TheStmt(S),
- MSAsmNameResolved(false),
- LocStart(StartL) {}
+ : NamedDecl(Label, DC, IdentL, II), TheStmt(S), LocStart(StartL) {}
+
+ void anchor() override;
public:
static LabelDecl *Create(ASTContext &C, DeclContext *DC,
@@ -446,7 +490,7 @@ public:
return SourceRange(LocStart, getLocation());
}
- bool isMSAsmLabel() const { return MSAsmName.size() != 0; }
+ bool isMSAsmLabel() const { return !MSAsmName.empty(); }
bool isResolvedMSAsmLabel() const { return isMSAsmLabel() && MSAsmNameResolved; }
void setMSAsmLabel(StringRef Name);
StringRef getMSAsmLabel() const { return MSAsmName; }
@@ -464,6 +508,7 @@ class NamespaceDecl : public NamedDecl, public DeclContext,
/// LocStart - The starting location of the source range, pointing
/// to either the namespace or the inline keyword.
SourceLocation LocStart;
+
/// RBraceLoc - The ending location of the source range.
SourceLocation RBraceLoc;
@@ -477,12 +522,16 @@ class NamespaceDecl : public NamedDecl, public DeclContext,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, NamespaceDecl *PrevDecl);
- typedef Redeclarable<NamespaceDecl> redeclarable_base;
+ using redeclarable_base = Redeclarable<NamespaceDecl>;
+
NamespaceDecl *getNextRedeclarationImpl() override;
NamespaceDecl *getPreviousDeclImpl() override;
NamespaceDecl *getMostRecentDeclImpl() override;
public:
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+
static NamespaceDecl *Create(ASTContext &C, DeclContext *DC,
bool Inline, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
@@ -490,8 +539,9 @@ public:
static NamespaceDecl *CreateDeserialized(ASTContext &C, unsigned ID);
- typedef redeclarable_base::redecl_range redecl_range;
- typedef redeclarable_base::redecl_iterator redecl_iterator;
+ using redecl_range = redeclarable_base::redecl_range;
+ using redecl_iterator = redeclarable_base::redecl_iterator;
+
using redeclarable_base::redecls_begin;
using redeclarable_base::redecls_end;
using redeclarable_base::redecls;
@@ -569,22 +619,21 @@ public:
static NamespaceDecl *castFromDeclContext(const DeclContext *DC) {
return static_cast<NamespaceDecl *>(const_cast<DeclContext*>(DC));
}
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
};
/// ValueDecl - Represent the declaration of a variable (in which case it is
/// an lvalue) a function (in which case it is a function designator) or
/// an enum constant.
class ValueDecl : public NamedDecl {
- void anchor() override;
QualType DeclType;
+ void anchor() override;
+
protected:
ValueDecl(Kind DK, DeclContext *DC, SourceLocation L,
DeclarationName N, QualType T)
: NamedDecl(DK, DC, L, N), DeclType(T) {}
+
public:
QualType getType() const { return DeclType; }
void setType(QualType newType) { DeclType = newType; }
@@ -607,28 +656,23 @@ struct QualifierInfo {
/// The count includes all of the template parameter lists that were matched
/// against the template-ids occurring into the NNS and possibly (in the
/// case of an explicit specialization) a final "template <>".
- unsigned NumTemplParamLists;
+ unsigned NumTemplParamLists = 0;
/// TemplParamLists - A new-allocated array of size NumTemplParamLists,
/// containing pointers to the "outer" template parameter lists.
/// It includes all of the template parameter lists that were matched
/// against the template-ids occurring into the NNS and possibly (in the
/// case of an explicit specialization) a final "template <>".
- TemplateParameterList** TemplParamLists;
+ TemplateParameterList** TemplParamLists = nullptr;
- /// Default constructor.
- QualifierInfo()
- : QualifierLoc(), NumTemplParamLists(0), TemplParamLists(nullptr) {}
+ QualifierInfo() = default;
+ QualifierInfo(const QualifierInfo &) = delete;
+ QualifierInfo& operator=(const QualifierInfo &) = delete;
/// setTemplateParameterListsInfo - Sets info about "outer" template
/// parameter lists.
void setTemplateParameterListsInfo(ASTContext &Context,
ArrayRef<TemplateParameterList *> TPLists);
-
-private:
- // Copy constructor and copy assignment are disabled.
- QualifierInfo(const QualifierInfo&) = delete;
- QualifierInfo& operator=(const QualifierInfo&) = delete;
};
/// \brief Represents a ValueDecl that came out of a declarator.
@@ -640,7 +684,7 @@ class DeclaratorDecl : public ValueDecl {
TypeSourceInfo *TInfo;
};
- llvm::PointerUnion<TypeSourceInfo*, ExtInfo*> DeclInfo;
+ llvm::PointerUnion<TypeSourceInfo *, ExtInfo *> DeclInfo;
/// InnerLocStart - The start of the source range for this declaration,
/// ignoring outer template declarations.
@@ -654,15 +698,18 @@ protected:
DeclaratorDecl(Kind DK, DeclContext *DC, SourceLocation L,
DeclarationName N, QualType T, TypeSourceInfo *TInfo,
SourceLocation StartL)
- : ValueDecl(DK, DC, L, N, T), DeclInfo(TInfo), InnerLocStart(StartL) {
- }
+ : ValueDecl(DK, DC, L, N, T), DeclInfo(TInfo), InnerLocStart(StartL) {}
public:
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+
TypeSourceInfo *getTypeSourceInfo() const {
return hasExtInfo()
? getExtInfo()->TInfo
: DeclInfo.get<TypeSourceInfo*>();
}
+
void setTypeSourceInfo(TypeSourceInfo *TI) {
if (hasExtInfo())
getExtInfo()->TInfo = TI;
@@ -680,6 +727,7 @@ public:
SourceLocation getOuterLocStart() const;
SourceRange getSourceRange() const override LLVM_READONLY;
+
SourceLocation getLocStart() const LLVM_READONLY {
return getOuterLocStart();
}
@@ -704,10 +752,12 @@ public:
unsigned getNumTemplateParameterLists() const {
return hasExtInfo() ? getExtInfo()->NumTemplParamLists : 0;
}
+
TemplateParameterList *getTemplateParameterList(unsigned index) const {
assert(index < getNumTemplateParameterLists());
return getExtInfo()->TemplParamLists[index];
}
+
void setTemplateParameterListsInfo(ASTContext &Context,
ArrayRef<TemplateParameterList *> TPLists);
@@ -718,18 +768,12 @@ public:
static bool classofKind(Kind K) {
return K >= firstDeclarator && K <= lastDeclarator;
}
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
};
/// \brief Structure used to store a statement, the constant value to
/// which it was evaluated (if any), and whether or not the statement
/// is an integral constant expression (if known).
struct EvaluatedStmt {
- EvaluatedStmt() : WasEvaluated(false), IsEvaluating(false), CheckedICE(false),
- CheckingICE(false), IsICE(false) { }
-
/// \brief Whether this statement was already evaluated.
bool WasEvaluated : 1;
@@ -751,32 +795,46 @@ struct EvaluatedStmt {
Stmt *Value;
APValue Evaluated;
+
+ EvaluatedStmt() : WasEvaluated(false), IsEvaluating(false), CheckedICE(false),
+ CheckingICE(false), IsICE(false) {}
+
};
/// VarDecl - An instance of this class is created to represent a variable
/// declaration or definition.
class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
public:
- /// getStorageClassSpecifierString - Return the string used to
- /// specify the storage class \p SC.
- ///
- /// It is illegal to call this function with SC == None.
- static const char *getStorageClassSpecifierString(StorageClass SC);
-
/// \brief Initialization styles.
enum InitializationStyle {
- CInit, ///< C-style initialization with assignment
- CallInit, ///< Call-style initialization (C++98)
- ListInit ///< Direct list-initialization (C++11)
+ /// C-style initialization with assignment
+ CInit,
+
+ /// Call-style initialization (C++98)
+ CallInit,
+
+ /// Direct list-initialization (C++11)
+ ListInit
};
/// \brief Kinds of thread-local storage.
enum TLSKind {
- TLS_None, ///< Not a TLS variable.
- TLS_Static, ///< TLS with a known-constant initializer.
- TLS_Dynamic ///< TLS with a dynamic initializer.
+ /// Not a TLS variable.
+ TLS_None,
+
+ /// TLS with a known-constant initializer.
+ TLS_Static,
+
+ /// TLS with a dynamic initializer.
+ TLS_Dynamic
};
+ /// getStorageClassSpecifierString - Return the string used to
+ /// specify the storage class \p SC.
+ ///
+ /// It is illegal to call this function with SC == None.
+ static const char *getStorageClassSpecifierString(StorageClass SC);
+
protected:
// A pointer union of Stmt * and EvaluatedStmt *. When an EvaluatedStmt, we
// have allocated the auxiliary struct of information there.
@@ -785,16 +843,20 @@ protected:
// this as *many* VarDecls are ParmVarDecls that don't have default
// arguments. We could save some space by moving this pointer union to be
// allocated in trailing space when necessary.
- typedef llvm::PointerUnion<Stmt *, EvaluatedStmt *> InitType;
+ using InitType = llvm::PointerUnion<Stmt *, EvaluatedStmt *>;
/// \brief The initializer for this variable or, for a ParmVarDecl, the
/// C++ default argument.
mutable InitType Init;
private:
+ friend class ASTDeclReader;
+ friend class ASTNodeImporter;
+ friend class StmtIteratorBase;
+
class VarDeclBitfields {
- friend class VarDecl;
friend class ASTDeclReader;
+ friend class VarDecl;
unsigned SClass : 3;
unsigned TSCSpec : 2;
@@ -802,10 +864,6 @@ private:
};
enum { NumVarDeclBits = 7 };
- friend class ASTDeclReader;
- friend class StmtIteratorBase;
- friend class ASTNodeImporter;
-
protected:
enum { NumParameterIndexBits = 8 };
@@ -817,8 +875,8 @@ protected:
};
class ParmVarDeclBitfields {
- friend class ParmVarDecl;
friend class ASTDeclReader;
+ friend class ParmVarDecl;
unsigned : NumVarDeclBits;
@@ -850,9 +908,9 @@ protected:
};
class NonParmVarDeclBitfields {
- friend class VarDecl;
- friend class ImplicitParamDecl;
friend class ASTDeclReader;
+ friend class ImplicitParamDecl;
+ friend class VarDecl;
unsigned : NumVarDeclBits;
@@ -912,20 +970,24 @@ protected:
SourceLocation IdLoc, IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo, StorageClass SC);
- typedef Redeclarable<VarDecl> redeclarable_base;
+ using redeclarable_base = Redeclarable<VarDecl>;
+
VarDecl *getNextRedeclarationImpl() override {
return getNextRedeclaration();
}
+
VarDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
}
+
VarDecl *getMostRecentDeclImpl() override {
return getMostRecentDecl();
}
public:
- typedef redeclarable_base::redecl_range redecl_range;
- typedef redeclarable_base::redecl_iterator redecl_iterator;
+ using redecl_range = redeclarable_base::redecl_range;
+ using redecl_iterator = redeclarable_base::redecl_iterator;
+
using redeclarable_base::redecls_begin;
using redeclarable_base::redecls_end;
using redeclarable_base::redecls;
@@ -1030,7 +1092,6 @@ public:
/// inside of functions. It also includes variables inside blocks.
///
/// void foo() { int x; static int y; extern int z; }
- ///
bool isLocalVarDecl() const {
if (getKind() != Decl::Var && getKind() != Decl::Decomposition)
return false;
@@ -1073,9 +1134,14 @@ public:
}
enum DefinitionKind {
- DeclarationOnly, ///< This declaration is only a declaration.
- TentativeDefinition, ///< This declaration is a tentative definition.
- Definition ///< This declaration is definitely a definition.
+ /// This declaration is only a declaration.
+ DeclarationOnly,
+
+ /// This declaration is a tentative definition.
+ TentativeDefinition,
+
+ /// This declaration is definitely a definition.
+ Definition
};
/// \brief Check whether this declaration is a definition. If this could be
@@ -1205,6 +1271,7 @@ public:
InitializationStyle getInitStyle() const {
return static_cast<InitializationStyle>(VarDeclBits.InitStyle);
}
+
/// \brief Whether the initializer is a direct-initializer (list or call).
bool isDirectInit() const {
return getInitStyle() != CInit;
@@ -1222,8 +1289,8 @@ public:
/// definitions one of which needs to be demoted to a declaration to keep
/// the AST invariants.
void demoteThisDefinitionToDeclaration() {
- assert (isThisDeclarationADefinition() && "Not a definition!");
- assert (!isa<ParmVarDecl>(this) && "Cannot demote ParmVarDecls!");
+ assert(isThisDeclarationADefinition() && "Not a definition!");
+ assert(!isa<ParmVarDecl>(this) && "Cannot demote ParmVarDecls!");
NonParmVarDeclBits.IsThisDeclarationADemotedDefinition = 1;
}
@@ -1387,12 +1454,23 @@ public:
/// with pointer to 'this', 'self', '_cmd', virtual table pointers, captured
/// context or something else.
enum ImplicitParamKind : unsigned {
- ObjCSelf, /// Parameter for Objective-C 'self' argument
- ObjCCmd, /// Parameter for Objective-C '_cmd' argument
- CXXThis, /// Parameter for C++ 'this' argument
- CXXVTT, /// Parameter for C++ virtual table pointers
- CapturedContext, /// Parameter for captured context
- Other, /// Other implicit parameter
+ /// Parameter for Objective-C 'self' argument
+ ObjCSelf,
+
+ /// Parameter for Objective-C '_cmd' argument
+ ObjCCmd,
+
+ /// Parameter for C++ 'this' argument
+ CXXThis,
+
+ /// Parameter for C++ virtual table pointers
+ CXXVTT,
+
+ /// Parameter for captured context
+ CapturedContext,
+
+ /// Other implicit parameter
+ Other,
};
/// Create implicit parameter.
@@ -1425,6 +1503,7 @@ public:
ImplicitParamKind getParameterKind() const {
return static_cast<ImplicitParamKind>(NonParmVarDeclBits.ImplicitParamKind);
}
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == ImplicitParam; }
@@ -1604,8 +1683,8 @@ private:
unsigned getParameterIndexLarge() const;
};
-/// FunctionDecl - An instance of this class is created to represent a
-/// function declaration or definition.
+/// An instance of this class is created to represent a function declaration or
+/// definition.
///
/// Since a given function can be declared several times in a program,
/// there may be several FunctionDecls that correspond to that
@@ -1631,7 +1710,7 @@ private:
/// ParamInfo - new[]'d array of pointers to VarDecls for the formal
/// parameters of this function. This is null if a prototype or if there are
/// no formals.
- ParmVarDecl **ParamInfo;
+ ParmVarDecl **ParamInfo = nullptr;
LazyDeclStmtPtr Body;
@@ -1640,10 +1719,12 @@ private:
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;
@@ -1656,7 +1737,7 @@ private:
unsigned HasImplicitReturnZero : 1;
unsigned IsLateTemplateParsed : 1;
unsigned IsConstexpr : 1;
- unsigned InstantiationIsPending:1;
+ unsigned InstantiationIsPending : 1;
/// \brief Indicates if the function uses __try.
unsigned UsesSEHTry : 1;
@@ -1669,6 +1750,15 @@ private:
/// parsing it.
unsigned WillHaveBody : 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:
/// \brief End part of this FunctionDecl's source range.
///
/// We could compute the full range in getSourceRange(). However, when we're
@@ -1696,8 +1786,8 @@ private:
DependentFunctionTemplateSpecializationInfo *>
TemplateOrSpecialization;
- /// DNLoc - Provides source/type location info for the
- /// declaration name embedded in the DeclaratorDecl base class.
+ /// Provides source/type location info for the declaration name embedded in
+ /// the DeclaratorDecl base class.
DeclarationNameLoc DNLoc;
/// \brief Specify that this function declaration is actually a function
@@ -1743,33 +1833,38 @@ protected:
bool isConstexprSpecified)
: DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo,
StartLoc),
- DeclContext(DK), redeclarable_base(C), ParamInfo(nullptr), Body(),
- SClass(S), IsInline(isInlineSpecified),
- IsInlineSpecified(isInlineSpecified), IsExplicitSpecified(false),
- IsVirtualAsWritten(false), IsPure(false),
+ 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), IsDefaulted(false),
IsExplicitlyDefaulted(false), HasImplicitReturnZero(false),
IsLateTemplateParsed(false), IsConstexpr(isConstexprSpecified),
- InstantiationIsPending(false),
- UsesSEHTry(false), HasSkippedBody(false), WillHaveBody(false),
- EndRangeLoc(NameInfo.getEndLoc()), TemplateOrSpecialization(),
- DNLoc(NameInfo.getInfo()) {}
+ InstantiationIsPending(false), UsesSEHTry(false), HasSkippedBody(false),
+ WillHaveBody(false), IsCopyDeductionCandidate(false),
+ EndRangeLoc(NameInfo.getEndLoc()), DNLoc(NameInfo.getInfo()) {}
+
+ using redeclarable_base = Redeclarable<FunctionDecl>;
- typedef Redeclarable<FunctionDecl> redeclarable_base;
FunctionDecl *getNextRedeclarationImpl() override {
return getNextRedeclaration();
}
+
FunctionDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
}
+
FunctionDecl *getMostRecentDeclImpl() override {
return getMostRecentDecl();
}
public:
- typedef redeclarable_base::redecl_range redecl_range;
- typedef redeclarable_base::redecl_iterator redecl_iterator;
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+
+ using redecl_range = redeclarable_base::redecl_range;
+ using redecl_iterator = redeclarable_base::redecl_iterator;
+
using redeclarable_base::redecls_begin;
using redeclarable_base::redecls_end;
using redeclarable_base::redecls;
@@ -1826,13 +1921,13 @@ public:
return hasBody(Definition);
}
- /// hasTrivialBody - Returns whether the function has a trivial body that does
- /// not require any specific codegen.
+ /// Returns whether the function has a trivial body that does not require any
+ /// specific codegen.
bool hasTrivialBody() const;
- /// isDefined - Returns true if the function is defined at all, including
- /// a deleted definition. Except for the behavior when the function is
- /// deleted, behaves like hasBody.
+ /// Returns true if the function is defined at all, including a deleted
+ /// definition. Except for the behavior when the function is deleted, behaves
+ /// like hasBody.
bool isDefined(const FunctionDecl *&Definition) const;
virtual bool isDefined() const {
@@ -1851,11 +1946,10 @@ public:
return const_cast<FunctionDecl *>(this)->getDefinition();
}
- /// getBody - Retrieve the body (definition) of the function. The
- /// function body might be in any of the (re-)declarations of this
- /// function. The variant that accepts a FunctionDecl pointer will
- /// set that function declaration to the actual declaration
- /// containing the body (if there is one).
+ /// Retrieve the body (definition) of the function. The function body might be
+ /// in any of the (re-)declarations of this function. The variant that accepts
+ /// a FunctionDecl pointer will set that function declaration to the actual
+ /// declaration containing the body (if there is one).
/// NOTE: For checking if there is a body, use hasBody() instead, to avoid
/// unnecessary AST de-serialization of the body.
Stmt *getBody(const FunctionDecl *&Definition) const;
@@ -1870,15 +1964,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 || IsLateTemplateParsed ||
- WillHaveBody || hasDefiningAttr();
+ return IsDeleted || IsDefaulted || Body || HasSkippedBody ||
+ IsLateTemplateParsed || WillHaveBody || hasDefiningAttr();
}
- /// doesThisDeclarationHaveABody - Returns whether this specific
- /// declaration of the function has a body - that is, if it is a non-
- /// deleted definition.
+ /// Returns whether this specific declaration of the function has a body -
+ /// that is, if it is a non-deleted definition.
bool doesThisDeclarationHaveABody() const {
return Body || IsLateTemplateParsed;
}
@@ -2023,6 +2115,9 @@ public:
/// true through IsAligned.
bool isReplaceableGlobalAllocationFunction(bool *IsAligned = nullptr) const;
+ /// \brief Determine whether this is a destroying operator delete.
+ bool isDestroyingOperatorDelete() const;
+
/// Compute the language linkage.
LanguageLinkage getLanguageLinkage() const;
@@ -2071,8 +2166,9 @@ public:
}
// Iterator access to formal parameters.
- typedef MutableArrayRef<ParmVarDecl *>::iterator param_iterator;
- typedef ArrayRef<ParmVarDecl *>::const_iterator param_const_iterator;
+ using param_iterator = MutableArrayRef<ParmVarDecl *>::iterator;
+ using param_const_iterator = ArrayRef<ParmVarDecl *>::const_iterator;
+
bool param_empty() const { return parameters().empty(); }
param_iterator param_begin() { return parameters().begin(); }
param_iterator param_end() { return parameters().end(); }
@@ -2080,9 +2176,9 @@ public:
param_const_iterator param_end() const { return parameters().end(); }
size_t param_size() const { return parameters().size(); }
- /// getNumParams - Return the number of parameters this function must have
- /// based on its FunctionType. This is the length of the ParamInfo array
- /// after it has been created.
+ /// Return the number of parameters this function must have based on its
+ /// FunctionType. This is the length of the ParamInfo array after it has been
+ /// created.
unsigned getNumParams() const;
const ParmVarDecl *getParamDecl(unsigned i) const {
@@ -2097,10 +2193,9 @@ public:
setParams(getASTContext(), NewParamInfo);
}
- /// getMinRequiredArguments - Returns the minimum number of arguments
- /// needed to call this function. This may be fewer than the number of
- /// function parameters, if some of the parameters have default
- /// arguments (in C++).
+ /// Returns the minimum number of arguments needed to call this function. This
+ /// may be fewer than the number of function parameters, if some of the
+ /// parameters have default arguments (in C++).
unsigned getMinRequiredArguments() const;
QualType getReturnType() const {
@@ -2355,18 +2450,14 @@ public:
static FunctionDecl *castFromDeclContext(const DeclContext *DC) {
return static_cast<FunctionDecl *>(const_cast<DeclContext*>(DC));
}
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
};
-
/// FieldDecl - An instance of this class is created by Sema::ActOnField to
/// represent a member of a struct/union/class.
class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> {
- // FIXME: This can be packed into the bitfields in Decl.
+ unsigned BitField : 1;
unsigned Mutable : 1;
- mutable unsigned CachedFieldIndex : 31;
+ mutable unsigned CachedFieldIndex : 30;
/// The kinds of value we can store in InitializerOrBitWidth.
///
@@ -2376,7 +2467,7 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> {
/// If the pointer is null, there's nothing special. Otherwise,
/// this is a bitfield and the pointer is the Expr* storing the
/// bit-width.
- ISK_BitWidthOrNothing = (unsigned) ICIS_NoInit,
+ ISK_NoInit = (unsigned) ICIS_NoInit,
/// The pointer is an (optional due to delayed parsing) Expr*
/// holding the copy-initializer.
@@ -2391,30 +2482,40 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> {
ISK_CapturedVLAType,
};
- /// \brief Storage for either the bit-width, the in-class
- /// initializer, or the captured variable length array bound.
- ///
- /// We can safely combine these because in-class initializers are
- /// not permitted for bit-fields, and both are exclusive with VLA
- /// captures.
+ /// If this is a bitfield with a default member initializer, this
+ /// structure is used to represent the two expressions.
+ struct InitAndBitWidth {
+ Expr *Init;
+ Expr *BitWidth;
+ };
+
+ /// \brief Storage for either the bit-width, the in-class initializer, or
+ /// both (via InitAndBitWidth), or the captured variable length array bound.
///
/// If the storage kind is ISK_InClassCopyInit or
/// ISK_InClassListInit, but the initializer is null, then this
- /// field has an in-class initializer which has not yet been parsed
+ /// field has an in-class initializer that has not yet been parsed
/// and attached.
+ // FIXME: Tail-allocate this to reduce the size of FieldDecl in the
+ // overwhelmingly common case that we have none of these things.
llvm::PointerIntPair<void *, 2, InitStorageKind> InitStorage;
+
protected:
FieldDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
QualType T, TypeSourceInfo *TInfo, Expr *BW, bool Mutable,
InClassInitStyle InitStyle)
: DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc),
- Mutable(Mutable), CachedFieldIndex(0),
- InitStorage(BW, (InitStorageKind) InitStyle) {
- assert((!BW || InitStyle == ICIS_NoInit) && "got initializer for bitfield");
+ BitField(false), Mutable(Mutable), CachedFieldIndex(0),
+ InitStorage(nullptr, (InitStorageKind) InitStyle) {
+ if (BW)
+ setBitWidth(BW);
}
public:
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+
static FieldDecl *Create(const ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, QualType T,
@@ -2431,10 +2532,7 @@ public:
bool isMutable() const { return Mutable; }
/// \brief Determines whether this field is a bitfield.
- bool isBitField() const {
- return InitStorage.getInt() == ISK_BitWidthOrNothing &&
- InitStorage.getPointer() != nullptr;
- }
+ bool isBitField() const { return BitField; }
/// @brief Determines whether this is an unnamed bitfield.
bool isUnnamedBitfield() const { return isBitField() && !getDeclName(); }
@@ -2446,66 +2544,77 @@ public:
bool isAnonymousStructOrUnion() const;
Expr *getBitWidth() const {
- return isBitField()
- ? static_cast<Expr *>(InitStorage.getPointer())
- : nullptr;
+ if (!BitField)
+ return nullptr;
+ void *Ptr = InitStorage.getPointer();
+ if (getInClassInitStyle())
+ return static_cast<InitAndBitWidth*>(Ptr)->BitWidth;
+ return static_cast<Expr*>(Ptr);
}
+
unsigned getBitWidthValue(const ASTContext &Ctx) const;
/// setBitWidth - Set the bit-field width for this member.
// Note: used by some clients (i.e., do not remove it).
void setBitWidth(Expr *Width) {
- assert(InitStorage.getInt() == ISK_BitWidthOrNothing &&
- InitStorage.getPointer() == nullptr &&
- "bit width, initializer or captured type already set");
- InitStorage.setPointerAndInt(Width, ISK_BitWidthOrNothing);
+ assert(!hasCapturedVLAType() && !BitField &&
+ "bit width or captured type already set");
+ assert(Width && "no bit width specified");
+ InitStorage.setPointer(
+ InitStorage.getInt()
+ ? new (getASTContext())
+ InitAndBitWidth{getInClassInitializer(), Width}
+ : static_cast<void*>(Width));
+ BitField = true;
}
/// removeBitWidth - Remove the bit-field width from this member.
// Note: used by some clients (i.e., do not remove it).
void removeBitWidth() {
assert(isBitField() && "no bitfield width to remove");
- InitStorage.setPointerAndInt(nullptr, ISK_BitWidthOrNothing);
+ InitStorage.setPointer(getInClassInitializer());
+ BitField = false;
}
- /// getInClassInitStyle - Get the kind of (C++11) in-class initializer which
- /// this field has.
+ /// Get the kind of (C++11) default member initializer that this field has.
InClassInitStyle getInClassInitStyle() const {
InitStorageKind storageKind = InitStorage.getInt();
return (storageKind == ISK_CapturedVLAType
? ICIS_NoInit : (InClassInitStyle) storageKind);
}
- /// hasInClassInitializer - Determine whether this member has a C++11 in-class
- /// initializer.
+ /// Determine whether this member has a C++11 default member initializer.
bool hasInClassInitializer() const {
return getInClassInitStyle() != ICIS_NoInit;
}
- /// getInClassInitializer - Get the C++11 in-class initializer for this
- /// member, or null if one has not been set. If a valid declaration has an
- /// in-class initializer, but this returns null, then we have not parsed and
- /// attached it yet.
+ /// Get the C++11 default member initializer for this member, or null if one
+ /// has not been set. If a valid declaration has a default member initializer,
+ /// but this returns null, then we have not parsed and attached it yet.
Expr *getInClassInitializer() const {
- return hasInClassInitializer()
- ? static_cast<Expr *>(InitStorage.getPointer())
- : nullptr;
+ if (!hasInClassInitializer())
+ return nullptr;
+ void *Ptr = InitStorage.getPointer();
+ if (BitField)
+ return static_cast<InitAndBitWidth*>(Ptr)->Init;
+ return static_cast<Expr*>(Ptr);
}
/// setInClassInitializer - Set the C++11 in-class initializer for this
/// member.
void setInClassInitializer(Expr *Init) {
- assert(hasInClassInitializer() &&
- InitStorage.getPointer() == nullptr &&
- "bit width, initializer or captured type already set");
- InitStorage.setPointer(Init);
+ assert(hasInClassInitializer() && !getInClassInitializer());
+ if (BitField)
+ static_cast<InitAndBitWidth*>(InitStorage.getPointer())->Init = Init;
+ else
+ InitStorage.setPointer(Init);
}
/// removeInClassInitializer - Remove the C++11 in-class initializer from this
/// member.
void removeInClassInitializer() {
assert(hasInClassInitializer() && "no initializer to remove");
- InitStorage.setPointerAndInt(nullptr, ISK_BitWidthOrNothing);
+ InitStorage.setPointerAndInt(getBitWidth(), ISK_NoInit);
}
/// \brief Determine whether this member captures the variable length array
@@ -2520,6 +2629,7 @@ public:
InitStorage.getPointer())
: nullptr;
}
+
/// \brief Set the captured variable length array type for this field.
void setCapturedVLAType(const VariableArrayType *VLAType);
@@ -2542,9 +2652,6 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K >= firstField && K <= lastField; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
};
/// EnumConstantDecl - An instance of this object exists for each enum constant
@@ -2554,6 +2661,7 @@ public:
class EnumConstantDecl : public ValueDecl, public Mergeable<EnumConstantDecl> {
Stmt *Init; // an integer constant expression
llvm::APSInt Val; // The value.
+
protected:
EnumConstantDecl(DeclContext *DC, SourceLocation L,
IdentifierInfo *Id, QualType T, Expr *E,
@@ -2561,6 +2669,7 @@ protected:
: ValueDecl(EnumConstant, DC, L, Id, T), Init((Stmt*)E), Val(V) {}
public:
+ friend class StmtIteratorBase;
static EnumConstantDecl *Create(ASTContext &C, EnumDecl *DC,
SourceLocation L, IdentifierInfo *Id,
@@ -2584,8 +2693,6 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == EnumConstant; }
-
- friend class StmtIteratorBase;
};
/// IndirectFieldDecl - An instance of this class is created to represent a
@@ -2593,7 +2700,6 @@ public:
/// IndirectFieldDecl are always implicit.
class IndirectFieldDecl : public ValueDecl,
public Mergeable<IndirectFieldDecl> {
- void anchor() override;
NamedDecl **Chaining;
unsigned ChainingSize;
@@ -2601,14 +2707,18 @@ class IndirectFieldDecl : public ValueDecl,
DeclarationName N, QualType T,
MutableArrayRef<NamedDecl *> CH);
+ void anchor() override;
+
public:
+ friend class ASTDeclReader;
+
static IndirectFieldDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
QualType T, llvm::MutableArrayRef<NamedDecl *> CH);
static IndirectFieldDecl *CreateDeserialized(ASTContext &C, unsigned ID);
- typedef ArrayRef<NamedDecl *>::const_iterator chain_iterator;
+ using chain_iterator = ArrayRef<NamedDecl *>::const_iterator;
ArrayRef<NamedDecl *> chain() const {
return llvm::makeArrayRef(Chaining, ChainingSize);
@@ -2634,26 +2744,27 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == IndirectField; }
- friend class ASTDeclReader;
};
/// TypeDecl - Represents a declaration of a type.
-///
class TypeDecl : public NamedDecl {
- void anchor() override;
+ friend class ASTContext;
+
/// TypeForDecl - This indicates the Type object that represents
/// this TypeDecl. It is a cache maintained by
/// ASTContext::getTypedefType, ASTContext::getTagDeclType, and
/// ASTContext::getTemplateTypeParmType, and TemplateTypeParmDecl.
- mutable const Type *TypeForDecl;
+ mutable const Type *TypeForDecl = nullptr;
+
/// LocStart - The start of the source range for this declaration.
SourceLocation LocStart;
- friend class ASTContext;
+
+ void anchor() override;
protected:
TypeDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
SourceLocation StartL = SourceLocation())
- : NamedDecl(DK, DC, L, Id), TypeForDecl(nullptr), LocStart(StartL) {}
+ : NamedDecl(DK, DC, L, Id), LocStart(StartL) {}
public:
// Low-level accessor. If you just want the type defined by this node,
@@ -2677,18 +2788,18 @@ public:
static bool classofKind(Kind K) { return K >= firstType && K <= lastType; }
};
-
/// Base class for declarations which introduce a typedef-name.
class TypedefNameDecl : public TypeDecl, public Redeclarable<TypedefNameDecl> {
- void anchor() override;
- typedef std::pair<TypeSourceInfo*, QualType> ModedTInfo;
- llvm::PointerUnion<TypeSourceInfo*, ModedTInfo*> MaybeModedTInfo;
+ using ModedTInfo = std::pair<TypeSourceInfo *, QualType>;
+ llvm::PointerUnion<TypeSourceInfo *, ModedTInfo *> MaybeModedTInfo;
// FIXME: This can be packed into the bitfields in Decl.
/// If 0, we have not computed IsTransparentTag.
/// Otherwise, IsTransparentTag is (CacheIsTransparentTag >> 1).
mutable unsigned CacheIsTransparentTag : 2;
+ void anchor() override;
+
protected:
TypedefNameDecl(Kind DK, ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
@@ -2696,20 +2807,24 @@ protected:
: TypeDecl(DK, DC, IdLoc, Id, StartLoc), redeclarable_base(C),
MaybeModedTInfo(TInfo), CacheIsTransparentTag(0) {}
- typedef Redeclarable<TypedefNameDecl> redeclarable_base;
+ using redeclarable_base = Redeclarable<TypedefNameDecl>;
+
TypedefNameDecl *getNextRedeclarationImpl() override {
return getNextRedeclaration();
}
+
TypedefNameDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
}
+
TypedefNameDecl *getMostRecentDeclImpl() override {
return getMostRecentDecl();
}
public:
- typedef redeclarable_base::redecl_range redecl_range;
- typedef redeclarable_base::redecl_iterator redecl_iterator;
+ using redecl_range = redeclarable_base::redecl_range;
+ using redecl_iterator = redeclarable_base::redecl_iterator;
+
using redeclarable_base::redecls_begin;
using redeclarable_base::redecls_end;
using redeclarable_base::redecls;
@@ -2724,14 +2839,17 @@ public:
? MaybeModedTInfo.get<ModedTInfo*>()->first
: MaybeModedTInfo.get<TypeSourceInfo*>();
}
+
QualType getUnderlyingType() const {
return isModed()
? MaybeModedTInfo.get<ModedTInfo*>()->second
: MaybeModedTInfo.get<TypeSourceInfo*>()->getType();
}
+
void setTypeSourceInfo(TypeSourceInfo *newType) {
MaybeModedTInfo = newType;
}
+
void setModedTypeSourceInfo(TypeSourceInfo *unmodedTSI, QualType modedTy) {
MaybeModedTInfo = new (getASTContext()) ModedTInfo(unmodedTSI, modedTy);
}
@@ -2817,7 +2935,7 @@ class TagDecl
: public TypeDecl, public DeclContext, public Redeclarable<TagDecl> {
public:
// This is really ugly.
- typedef TagTypeKind TagKind;
+ using TagKind = TagTypeKind;
private:
// FIXME: This can be packed into the bitfields in Decl.
@@ -2850,6 +2968,7 @@ protected:
/// IsScoped - True if this tag declaration is a scoped enumeration. Only
/// possible in C++11 mode.
unsigned IsScoped : 1;
+
/// IsScopedUsingClassTag - 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
@@ -2869,12 +2988,13 @@ protected:
/// 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,
// to be used for the (uncommon) case of out-of-line declarations.
- typedef QualifierInfo ExtInfo;
+ using ExtInfo = QualifierInfo;
/// \brief If the (out-of-line) tag declaration name
/// is qualified, it points to the qualifier info (nns and range);
@@ -2906,13 +3026,16 @@ protected:
setPreviousDecl(PrevDecl);
}
- typedef Redeclarable<TagDecl> redeclarable_base;
+ using redeclarable_base = Redeclarable<TagDecl>;
+
TagDecl *getNextRedeclarationImpl() override {
return getNextRedeclaration();
}
+
TagDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
}
+
TagDecl *getMostRecentDeclImpl() override {
return getMostRecentDecl();
}
@@ -2923,8 +3046,12 @@ protected:
void completeDefinition();
public:
- typedef redeclarable_base::redecl_range redecl_range;
- typedef redeclarable_base::redecl_iterator redecl_iterator;
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+
+ using redecl_range = redeclarable_base::redecl_range;
+ using redecl_iterator = redeclarable_base::redecl_iterator;
+
using redeclarable_base::redecls_begin;
using redeclarable_base::redecls_end;
using redeclarable_base::redecls;
@@ -3074,10 +3201,12 @@ public:
unsigned getNumTemplateParameterLists() const {
return hasExtInfo() ? getExtInfo()->NumTemplParamLists : 0;
}
+
TemplateParameterList *getTemplateParameterList(unsigned i) const {
assert(i < getNumTemplateParameterLists());
return getExtInfo()->TemplParamLists[i];
}
+
void setTemplateParameterListsInfo(ASTContext &Context,
ArrayRef<TemplateParameterList *> TPLists);
@@ -3088,19 +3217,16 @@ public:
static DeclContext *castToDeclContext(const TagDecl *D) {
return static_cast<DeclContext *>(const_cast<TagDecl*>(D));
}
+
static TagDecl *castFromDeclContext(const DeclContext *DC) {
return static_cast<TagDecl *>(const_cast<DeclContext*>(DC));
}
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
};
/// EnumDecl - Represents an enum. In C++11, enums can be forward-declared
/// 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 {
- void anchor() override;
/// IntegerType - 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.
@@ -3115,8 +3241,7 @@ class EnumDecl : public TagDecl {
/// The underlying type of an enumeration never has any qualifiers, so
/// we can get away with just storing a raw Type*, and thus save an
/// extra pointer when TypeSourceInfo is needed.
-
- llvm::PointerUnion<const Type*, TypeSourceInfo*> IntegerType;
+ llvm::PointerUnion<const Type *, TypeSourceInfo *> IntegerType;
/// PromotionType - The integer type that values of this type should
/// promote to. In C, enumerators are generally of an integer type
@@ -3127,13 +3252,12 @@ class EnumDecl : public TagDecl {
/// \brief If this enumeration is an instantiation of a member enumeration
/// of a class template specialization, this is the member specialization
/// information.
- MemberSpecializationInfo *SpecializationInfo;
+ MemberSpecializationInfo *SpecializationInfo = nullptr;
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),
- SpecializationInfo(nullptr) {
+ : TagDecl(Enum, TTK_Enum, C, DC, IdLoc, Id, PrevDecl, StartLoc) {
assert(Scoped || !ScopedUsingClassTag);
IntegerType = (const Type *)nullptr;
NumNegativeBits = 0;
@@ -3143,9 +3267,13 @@ class EnumDecl : public TagDecl {
IsFixed = Fixed;
}
+ void anchor() override;
+
void setInstantiationOfMemberEnum(ASTContext &C, EnumDecl *ED,
TemplateSpecializationKind TSK);
public:
+ friend class ASTDeclReader;
+
EnumDecl *getCanonicalDecl() override {
return cast<EnumDecl>(TagDecl::getCanonicalDecl());
}
@@ -3191,9 +3319,9 @@ public:
// enumerator_iterator - Iterates through the enumerators of this
// enumeration.
- typedef specific_decl_iterator<EnumConstantDecl> enumerator_iterator;
- typedef llvm::iterator_range<specific_decl_iterator<EnumConstantDecl>>
- enumerator_range;
+ using enumerator_iterator = specific_decl_iterator<EnumConstantDecl>;
+ using enumerator_range =
+ llvm::iterator_range<specific_decl_iterator<EnumConstantDecl>>;
enumerator_range enumerators() const {
return enumerator_range(enumerator_begin(), enumerator_end());
@@ -3341,17 +3469,15 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == Enum; }
-
- friend class ASTDeclReader;
};
-
/// RecordDecl - Represents a struct/union/class. For example:
/// struct X; // Forward declaration, no "body".
/// 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 {
+ friend class DeclContext;
+
// FIXME: This can be packed into the bitfields in Decl.
/// HasFlexibleArrayMember - 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.
@@ -3375,7 +3501,6 @@ class RecordDecl : public TagDecl {
/// methods/nested types we allow deserialization of just the fields
/// when needed.
mutable bool LoadedFieldsFromExternalStorage : 1;
- friend class DeclContext;
protected:
RecordDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC,
@@ -3458,6 +3583,7 @@ public:
/// \brief Determine whether this record is a record for captured variables in
/// CapturedStmt construct.
bool isCapturedRecord() const;
+
/// \brief Mark the record as a record for captured variables in CapturedStmt
/// construct.
void setCapturedRecord();
@@ -3477,8 +3603,8 @@ public:
// Iterator access to field members. The field iterator only visits
// the non-static data members of this class, ignoring any static
// data members, functions, constructors, destructors, etc.
- typedef specific_decl_iterator<FieldDecl> field_iterator;
- typedef llvm::iterator_range<specific_decl_iterator<FieldDecl>> field_range;
+ using field_iterator = specific_decl_iterator<FieldDecl>;
+ using field_range = llvm::iterator_range<specific_decl_iterator<FieldDecl>>;
field_range fields() const { return field_range(field_begin(), field_end()); }
field_iterator field_begin() const;
@@ -3502,7 +3628,7 @@ public:
return K >= firstRecord && K <= lastRecord;
}
- /// isMsStrust - Get whether or not this is an ms_struct which can
+ /// \brief Get whether or not this is an ms_struct which can
/// be turned on with an attribute, pragma, or -mms-bitfields
/// commandline option.
bool isMsStruct(const ASTContext &C) const;
@@ -3522,12 +3648,15 @@ private:
};
class FileScopeAsmDecl : public Decl {
- virtual void anchor();
StringLiteral *AsmString;
SourceLocation RParenLoc;
+
FileScopeAsmDecl(DeclContext *DC, StringLiteral *asmstring,
SourceLocation StartL, SourceLocation EndL)
: Decl(FileScopeAsm, DC, StartL), AsmString(asmstring), RParenLoc(EndL) {}
+
+ virtual void anchor();
+
public:
static FileScopeAsmDecl *Create(ASTContext &C, DeclContext *DC,
StringLiteral *Str, SourceLocation AsmLoc,
@@ -3553,7 +3682,6 @@ public:
/// BlockDecl - This represents a block literal declaration, which is like an
/// unnamed FunctionDecl. For example:
/// ^{ statement-body } or ^(int arg1, float arg2){ statement-body }
-///
class BlockDecl : public Decl, public DeclContext {
public:
/// A class which contains all the information about a particular
@@ -3600,29 +3728,27 @@ private:
bool CapturesCXXThis : 1;
bool BlockMissingReturnType : 1;
bool IsConversionFromLambda : 1;
+
/// ParamInfo - 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.
- ParmVarDecl **ParamInfo;
- unsigned NumParams;
+ ParmVarDecl **ParamInfo = nullptr;
+ unsigned NumParams = 0;
- Stmt *Body;
- TypeSourceInfo *SignatureAsWritten;
+ Stmt *Body = nullptr;
+ TypeSourceInfo *SignatureAsWritten = nullptr;
- const Capture *Captures;
- unsigned NumCaptures;
+ const Capture *Captures = nullptr;
+ unsigned NumCaptures = 0;
- unsigned ManglingNumber;
- Decl *ManglingContextDecl;
+ unsigned ManglingNumber = 0;
+ Decl *ManglingContextDecl = nullptr;
protected:
BlockDecl(DeclContext *DC, SourceLocation CaretLoc)
- : Decl(Block, DC, CaretLoc), DeclContext(Block),
- IsVariadic(false), CapturesCXXThis(false),
- BlockMissingReturnType(true), IsConversionFromLambda(false),
- ParamInfo(nullptr), NumParams(0), Body(nullptr),
- SignatureAsWritten(nullptr), Captures(nullptr), NumCaptures(0),
- ManglingNumber(0), ManglingContextDecl(nullptr) {}
+ : Decl(Block, DC, CaretLoc), DeclContext(Block), IsVariadic(false),
+ CapturesCXXThis(false), BlockMissingReturnType(true),
+ IsConversionFromLambda(false) {}
public:
static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L);
@@ -3649,8 +3775,9 @@ public:
}
// Iterator access to formal parameters.
- typedef MutableArrayRef<ParmVarDecl *>::iterator param_iterator;
- typedef ArrayRef<ParmVarDecl *>::const_iterator param_const_iterator;
+ using param_iterator = MutableArrayRef<ParmVarDecl *>::iterator;
+ using param_const_iterator = ArrayRef<ParmVarDecl *>::const_iterator;
+
bool param_empty() const { return parameters().empty(); }
param_iterator param_begin() { return parameters().begin(); }
param_iterator param_end() { return parameters().end(); }
@@ -3659,6 +3786,7 @@ public:
size_t param_size() const { return parameters().size(); }
unsigned getNumParams() const { return NumParams; }
+
const ParmVarDecl *getParamDecl(unsigned i) const {
assert(i < getNumParams() && "Illegal param #");
return ParamInfo[i];
@@ -3667,6 +3795,7 @@ public:
assert(i < getNumParams() && "Illegal param #");
return ParamInfo[i];
}
+
void setParams(ArrayRef<ParmVarDecl *> NewParamInfo);
/// hasCaptures - True if this block (or its nested blocks) captures
@@ -3677,7 +3806,7 @@ public:
/// Does not include an entry for 'this'.
unsigned getNumCaptures() const { return NumCaptures; }
- typedef ArrayRef<Capture>::const_iterator capture_const_iterator;
+ using capture_const_iterator = ArrayRef<Capture>::const_iterator;
ArrayRef<Capture> captures() const { return {Captures, NumCaptures}; }
@@ -3699,6 +3828,7 @@ public:
unsigned getBlockManglingNumber() const {
return ManglingNumber;
}
+
Decl *getBlockManglingContextDecl() const {
return ManglingContextDecl;
}
@@ -3735,8 +3865,10 @@ protected:
private:
/// \brief The number of parameters to the outlined function.
unsigned NumParams;
+
/// \brief The position of context parameter in list of parameters.
unsigned ContextParam;
+
/// \brief The body of the outlined function.
llvm::PointerIntPair<Stmt *, 1, bool> BodyAndNothrow;
@@ -3751,6 +3883,10 @@ private:
}
public:
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+ friend TrailingObjects;
+
static CapturedDecl *Create(ASTContext &C, DeclContext *DC,
unsigned NumParams);
static CapturedDecl *CreateDeserialized(ASTContext &C, unsigned ID,
@@ -3793,8 +3929,8 @@ public:
}
unsigned getContextParamPosition() const { return ContextParam; }
- typedef ImplicitParamDecl *const *param_iterator;
- typedef llvm::iterator_range<param_iterator> param_range;
+ using param_iterator = ImplicitParamDecl *const *;
+ using param_range = llvm::iterator_range<param_iterator>;
/// \brief Retrieve an iterator pointing to the first parameter decl.
param_iterator param_begin() const { return getParams(); }
@@ -3810,10 +3946,6 @@ public:
static CapturedDecl *castFromDeclContext(const DeclContext *DC) {
return static_cast<CapturedDecl *>(const_cast<DeclContext *>(DC));
}
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
- friend TrailingObjects;
};
/// \brief Describes a module import declaration, which makes the contents
@@ -3828,6 +3960,11 @@ public:
/// \#include/\#import directives.
class ImportDecl final : public Decl,
llvm::TrailingObjects<ImportDecl, SourceLocation> {
+ friend class ASTContext;
+ friend class ASTDeclReader;
+ friend class ASTReader;
+ friend TrailingObjects;
+
/// \brief The imported module, along with a bit that indicates whether
/// we have source-location information for each identifier in the module
/// name.
@@ -3838,20 +3975,15 @@ class ImportDecl final : public Decl,
/// \brief The next import in the list of imports local to the translation
/// unit being parsed (not loaded from an AST file).
- ImportDecl *NextLocalImport;
+ ImportDecl *NextLocalImport = nullptr;
- friend class ASTReader;
- friend class ASTDeclReader;
- friend class ASTContext;
- friend TrailingObjects;
-
ImportDecl(DeclContext *DC, SourceLocation StartLoc, Module *Imported,
ArrayRef<SourceLocation> IdentifierLocs);
ImportDecl(DeclContext *DC, SourceLocation StartLoc, Module *Imported,
SourceLocation EndLoc);
- ImportDecl(EmptyShell Empty) : Decl(Import, Empty), NextLocalImport() { }
+ ImportDecl(EmptyShell Empty) : Decl(Import, Empty) {}
public:
/// \brief Create a new module import declaration.
@@ -3893,15 +4025,16 @@ public:
/// \endcode
class ExportDecl final : public Decl, public DeclContext {
virtual void anchor();
+
private:
+ friend class ASTDeclReader;
+
/// \brief The source location for the right brace (if valid).
SourceLocation RBraceLoc;
ExportDecl(DeclContext *DC, SourceLocation ExportLoc)
- : Decl(Export, DC, ExportLoc), DeclContext(Export),
- RBraceLoc(SourceLocation()) { }
-
- friend class ASTDeclReader;
+ : Decl(Export, DC, ExportLoc), DeclContext(Export),
+ RBraceLoc(SourceLocation()) {}
public:
static ExportDecl *Create(ASTContext &C, DeclContext *DC,
@@ -3936,9 +4069,9 @@ public:
/// \brief Represents an empty-declaration.
class EmptyDecl : public Decl {
+ EmptyDecl(DeclContext *DC, SourceLocation L) : Decl(Empty, DC, L) {}
+
virtual void anchor();
- EmptyDecl(DeclContext *DC, SourceLocation L)
- : Decl(Empty, DC, L) { }
public:
static EmptyDecl *Create(ASTContext &C, DeclContext *DC,
@@ -4015,6 +4148,6 @@ inline bool IsEnumDeclScoped(EnumDecl *ED) {
return ED->isScoped();
}
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_AST_DECL_H
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index 041f0fd484d4..f93c9f0b9aaa 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -1,4 +1,4 @@
-//===-- DeclBase.h - Base Classes for representing declarations -*- C++ -*-===//
+//===- DeclBase.h - Base Classes for representing declarations --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,33 +16,40 @@
#include "clang/AST/AttrIterator.h"
#include "clang/AST/DeclarationName.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Basic/VersionTuple.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/PrettyStackTrace.h"
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <iterator>
+#include <string>
+#include <type_traits>
+#include <utility>
namespace clang {
+
+class ASTContext;
class ASTMutationListener;
-class BlockDecl;
-class CXXRecordDecl;
-class CompoundStmt;
+class Attr;
class DeclContext;
-class DeclarationName;
-class DependentDiagnostic;
-class EnumDecl;
-class ExportDecl;
class ExternalSourceSymbolAttr;
class FunctionDecl;
class FunctionType;
+class IdentifierInfo;
enum Linkage : unsigned char;
-class LinkageComputer;
class LinkageSpecDecl;
class Module;
class NamedDecl;
-class NamespaceDecl;
class ObjCCategoryDecl;
class ObjCCategoryImplDecl;
class ObjCContainerDecl;
@@ -53,23 +60,21 @@ class ObjCMethodDecl;
class ObjCProtocolDecl;
struct PrintingPolicy;
class RecordDecl;
+class SourceManager;
class Stmt;
class StoredDeclsMap;
class TemplateDecl;
class TranslationUnitDecl;
class UsingDirectiveDecl;
-}
-
-namespace clang {
- /// \brief Captures the result of checking the availability of a
- /// declaration.
- enum AvailabilityResult {
- AR_Available = 0,
- AR_NotYetIntroduced,
- AR_Deprecated,
- AR_Unavailable
- };
+/// \brief Captures the result of checking the availability of a
+/// declaration.
+enum AvailabilityResult {
+ AR_Available = 0,
+ AR_NotYetIntroduced,
+ AR_Deprecated,
+ AR_Unavailable
+};
/// Decl - This represents one declaration (or definition), e.g. a variable,
/// typedef, function, struct, etc.
@@ -94,7 +99,7 @@ public:
/// \brief A placeholder type used to construct an empty shell of a
/// decl-derived type that will be filled in later (e.g., by some
/// deserialization method).
- struct EmptyShell { };
+ struct EmptyShell {};
/// IdentifierNamespace - The different namespaces in which
/// declarations may appear. According to C99 6.2.3, there are
@@ -208,15 +213,18 @@ public:
enum class ModuleOwnershipKind : unsigned {
/// This declaration is not owned by a module.
Unowned,
+
/// This declaration has an owning module, but is globally visible
/// (typically because its owning module is visible and we know that
/// modules cannot later become hidden in this compilation).
/// After serialization and deserialization, this will be converted
/// to VisibleWhenImported.
Visible,
+
/// This declaration has an owning module, and is visible when that
/// module is imported.
VisibleWhenImported,
+
/// This declaration has an owning module, but is only visible to
/// lookups that occur within that module.
ModulePrivate
@@ -238,7 +246,6 @@ private:
DeclContext *LexicalDC;
};
-
/// DeclCtx - Holds either a DeclContext* or a MultipleDC*.
/// For declarations that don't contain C++ scope specifiers, it contains
/// the DeclContext where the Decl was declared.
@@ -254,12 +261,14 @@ private:
/// // LexicalDC == global namespace
llvm::PointerUnion<DeclContext*, MultipleDC*> DeclCtx;
- inline bool isInSemaDC() const { return DeclCtx.is<DeclContext*>(); }
- inline bool isOutOfSemaDC() const { return DeclCtx.is<MultipleDC*>(); }
- inline MultipleDC *getMultipleDC() const {
+ bool isInSemaDC() const { return DeclCtx.is<DeclContext*>(); }
+ bool isOutOfSemaDC() const { return DeclCtx.is<MultipleDC*>(); }
+
+ MultipleDC *getMultipleDC() const {
return DeclCtx.get<MultipleDC*>();
}
- inline DeclContext *getSemanticDC() const {
+
+ DeclContext *getSemanticDC() const {
return DeclCtx.get<DeclContext*>();
}
@@ -298,10 +307,16 @@ private:
static bool StatisticsEnabled;
protected:
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+ friend class ASTReader;
+ friend class CXXClassMemberWrapper;
+ friend class LinkageComputer;
+ template<typename decl_type> friend class Redeclarable;
+
/// Access - Used by C++ decls for the access specifier.
// NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum
unsigned Access : 2;
- friend class CXXClassMemberWrapper;
/// \brief Whether this declaration was loaded from an AST file.
unsigned FromASTFile : 1;
@@ -313,13 +328,6 @@ protected:
/// Otherwise, it is the linkage + 1.
mutable unsigned CacheValidAndLinkage : 3;
- friend class ASTDeclWriter;
- friend class ASTDeclReader;
- friend class ASTReader;
- friend class LinkageComputer;
-
- template<typename decl_type> friend class Redeclarable;
-
/// \brief Allocate memory for a deserialized declaration.
///
/// This routine must be used to allocate memory for any declaration that is
@@ -357,7 +365,7 @@ private:
protected:
Decl(Kind DK, DeclContext *DC, SourceLocation L)
: NextInContextAndBits(nullptr, getModuleOwnershipKindForChildOf(DC)),
- DeclCtx(DC), Loc(L), DeclKind(DK), InvalidDecl(0), HasAttrs(false),
+ DeclCtx(DC), Loc(L), DeclKind(DK), InvalidDecl(false), HasAttrs(false),
Implicit(false), Used(false), Referenced(false),
TopLevelDeclInObjCContainer(false), Access(AS_none), FromASTFile(0),
IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
@@ -366,9 +374,9 @@ protected:
}
Decl(Kind DK, EmptyShell Empty)
- : NextInContextAndBits(), DeclKind(DK), InvalidDecl(0), HasAttrs(false),
- Implicit(false), Used(false), Referenced(false),
- TopLevelDeclInObjCContainer(false), Access(AS_none), FromASTFile(0),
+ : DeclKind(DK), InvalidDecl(false), HasAttrs(false), Implicit(false),
+ Used(false), Referenced(false), TopLevelDeclInObjCContainer(false),
+ Access(AS_none), FromASTFile(0),
IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
CacheValidAndLinkage(0) {
if (StatisticsEnabled) add(DK);
@@ -392,14 +400,15 @@ protected:
}
public:
-
/// \brief Source range that this declaration covers.
virtual SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(getLocation(), getLocation());
}
+
SourceLocation getLocStart() const LLVM_READONLY {
return getSourceRange().getBegin();
}
+
SourceLocation getLocEnd() const LLVM_READONLY {
return getSourceRange().getEnd();
}
@@ -460,12 +469,15 @@ public:
}
bool hasAttrs() const { return HasAttrs; }
+
void setAttrs(const AttrVec& Attrs) {
return setAttrsImpl(Attrs, getASTContext());
}
+
AttrVec &getAttrs() {
return const_cast<AttrVec&>(const_cast<const Decl*>(this)->getAttrs());
}
+
const AttrVec &getAttrs() const;
void dropAttrs();
@@ -476,8 +488,8 @@ public:
setAttrs(AttrVec(1, A));
}
- typedef AttrVec::const_iterator attr_iterator;
- typedef llvm::iterator_range<attr_iterator> attr_range;
+ using attr_iterator = AttrVec::const_iterator;
+ using attr_range = llvm::iterator_range<attr_iterator>;
attr_range attrs() const {
return attr_range(attr_begin(), attr_end());
@@ -510,6 +522,7 @@ public:
specific_attr_iterator<T> specific_attr_begin() const {
return specific_attr_iterator<T>(attr_begin());
}
+
template <typename T>
specific_attr_iterator<T> specific_attr_end() const {
return specific_attr_iterator<T>(attr_end());
@@ -518,6 +531,7 @@ public:
template<typename T> T *getAttr() const {
return hasAttrs() ? getSpecificAttr<T>(getAttrs()) : nullptr;
}
+
template<typename T> bool hasAttr() const {
return hasAttrs() && hasSpecificAttr<T>(getAttrs());
}
@@ -616,7 +630,6 @@ protected:
}
public:
-
/// \brief Determine the availability of the given declaration.
///
/// This routine will determine the most restrictive availability of
@@ -698,6 +711,7 @@ public:
private:
Module *getOwningModuleSlow() const;
+
protected:
bool hasLocalOwningModuleStorage() const;
@@ -733,11 +747,18 @@ public:
return getModuleOwnershipKind() != ModuleOwnershipKind::Unowned;
}
- /// Get the module that owns this declaration.
+ /// Get the module that owns this declaration (for visibility purposes).
Module *getOwningModule() const {
return isFromASTFile() ? getImportedOwningModule() : getLocalOwningModule();
}
+ /// Get the module that owns this declaration for linkage purposes.
+ /// There only ever is such a module under the C++ Modules TS.
+ ///
+ /// \param IgnoreLinkage Ignore the linkage of the entity; assume that
+ /// all declarations in a global module fragment are unowned.
+ Module *getOwningModuleForLinkage(bool IgnoreLinkage = false) const;
+
/// \brief Determine whether this declaration might be hidden from name
/// lookup. Note that the declaration might be visible even if this returns
/// \c false, if the owning module is visible within the query context.
@@ -770,14 +791,17 @@ public:
unsigned getIdentifierNamespace() const {
return IdentifierNamespace;
}
+
bool isInIdentifierNamespace(unsigned NS) const {
return getIdentifierNamespace() & NS;
}
+
static unsigned getIdentifierNamespaceForKind(Kind DK);
bool hasTagIdentifierNamespace() const {
return isTagIdentifierNamespace(getIdentifierNamespace());
}
+
static bool isTagIdentifierNamespace(unsigned NS) {
// TagDecls have Tag and Type set and may also have TagFriend.
return (NS & ~IDNS_TagFriend) == (IDNS_Tag | IDNS_Type);
@@ -865,18 +889,18 @@ public:
/// \brief Iterates through all the redeclarations of the same decl.
class redecl_iterator {
/// Current - The current declaration.
- Decl *Current;
+ Decl *Current = nullptr;
Decl *Starter;
public:
- typedef Decl *value_type;
- typedef const value_type &reference;
- typedef const value_type *pointer;
- typedef std::forward_iterator_tag iterator_category;
- typedef std::ptrdiff_t difference_type;
+ using value_type = Decl *;
+ using reference = const value_type &;
+ using pointer = const value_type *;
+ using iterator_category = std::forward_iterator_tag;
+ using difference_type = std::ptrdiff_t;
- redecl_iterator() : Current(nullptr) { }
- explicit redecl_iterator(Decl *C) : Current(C), Starter(C) { }
+ redecl_iterator() = default;
+ explicit redecl_iterator(Decl *C) : Current(C), Starter(C) {}
reference operator*() const { return Current; }
value_type operator->() const { return Current; }
@@ -899,12 +923,13 @@ public:
friend bool operator==(redecl_iterator x, redecl_iterator y) {
return x.Current == y.Current;
}
+
friend bool operator!=(redecl_iterator x, redecl_iterator y) {
return x.Current != y.Current;
}
};
- typedef llvm::iterator_range<redecl_iterator> redecl_range;
+ using redecl_range = llvm::iterator_range<redecl_iterator>;
/// \brief Returns an iterator range for all the redeclarations of the same
/// decl. It will iterate at least once (when this decl is the only one).
@@ -915,6 +940,7 @@ public:
redecl_iterator redecls_begin() const {
return redecl_iterator(const_cast<Decl *>(this));
}
+
redecl_iterator redecls_end() const { return redecl_iterator(); }
/// \brief Retrieve the previous declaration that declares the same entity
@@ -1002,13 +1028,15 @@ public:
/// declaration, but in the semantic context of the enclosing namespace
/// scope.
void setLocalExternDecl() {
- assert((IdentifierNamespace == IDNS_Ordinary ||
- IdentifierNamespace == IDNS_OrdinaryFriend) &&
- "namespace is not ordinary");
-
Decl *Prev = getPreviousDecl();
IdentifierNamespace &= ~IDNS_Ordinary;
+ // It's OK for the declaration to still have the "invisible friend" flag or
+ // the "conflicts with tag declarations in this scope" flag for the outer
+ // scope.
+ assert((IdentifierNamespace & ~(IDNS_OrdinaryFriend | IDNS_Tag)) == 0 &&
+ "namespace is not ordinary");
+
IdentifierNamespace |= IDNS_LocalExtern;
if (Prev && Prev->getIdentifierNamespace() & IDNS_Ordinary)
IdentifierNamespace |= IDNS_Ordinary;
@@ -1094,10 +1122,13 @@ public:
static void printGroup(Decl** Begin, unsigned NumDecls,
raw_ostream &Out, const PrintingPolicy &Policy,
unsigned Indentation = 0);
+
// Debuggers don't usually respect default arguments.
void dump() const;
+
// Same as dump(), but forces color printing.
void dumpColor() const;
+
void dump(raw_ostream &Out, bool Deserialize = false) const;
/// \brief Looks through the Decl's underlying type to extract a FunctionType
@@ -1132,10 +1163,11 @@ class PrettyStackTraceDecl : public llvm::PrettyStackTraceEntry {
SourceLocation Loc;
SourceManager &SM;
const char *Message;
+
public:
PrettyStackTraceDecl(const Decl *theDecl, SourceLocation L,
SourceManager &sm, const char *Msg)
- : TheDecl(theDecl), Loc(L), SM(sm), Message(Msg) {}
+ : TheDecl(theDecl), Loc(L), SM(sm), Message(Msg) {}
void print(raw_ostream &OS) const override;
};
@@ -1144,30 +1176,35 @@ public:
/// single result (with no stable storage) or a collection of results (with
/// stable storage provided by the lookup table).
class DeclContextLookupResult {
- typedef ArrayRef<NamedDecl *> ResultTy;
+ using ResultTy = ArrayRef<NamedDecl *>;
+
ResultTy Result;
+
// If there is only one lookup result, it would be invalidated by
// reallocations of the name table, so store it separately.
- NamedDecl *Single;
+ NamedDecl *Single = nullptr;
static NamedDecl *const SingleElementDummyList;
public:
- DeclContextLookupResult() : Result(), Single() {}
+ DeclContextLookupResult() = default;
DeclContextLookupResult(ArrayRef<NamedDecl *> Result)
- : Result(Result), Single() {}
+ : Result(Result) {}
DeclContextLookupResult(NamedDecl *Single)
: Result(SingleElementDummyList), Single(Single) {}
class iterator;
- typedef llvm::iterator_adaptor_base<iterator, ResultTy::iterator,
- std::random_access_iterator_tag,
- NamedDecl *const> IteratorBase;
+
+ using IteratorBase =
+ llvm::iterator_adaptor_base<iterator, ResultTy::iterator,
+ std::random_access_iterator_tag,
+ NamedDecl *const>;
+
class iterator : public IteratorBase {
value_type SingleElement;
public:
- iterator() : IteratorBase(), SingleElement() {}
+ iterator() = default;
explicit iterator(pointer Pos, value_type Single = nullptr)
: IteratorBase(Pos), SingleElement(Single) {}
@@ -1175,9 +1212,10 @@ public:
return SingleElement ? SingleElement : IteratorBase::operator*();
}
};
- typedef iterator const_iterator;
- typedef iterator::pointer pointer;
- typedef iterator::reference reference;
+
+ using const_iterator = iterator;
+ using pointer = iterator::pointer;
+ using reference = iterator::reference;
iterator begin() const { return iterator(Result.begin(), Single); }
iterator end() const { return iterator(Result.end(), Single); }
@@ -1211,7 +1249,6 @@ public:
/// ExportDecl
/// BlockDecl
/// OMPDeclareReductionDecl
-///
class DeclContext {
/// DeclKind - This indicates which class this is.
unsigned DeclKind : 8;
@@ -1251,22 +1288,22 @@ class DeclContext {
/// contains an entry for a DeclarationName (and we haven't lazily
/// omitted anything), then it contains all relevant entries for that
/// name (modulo the hasExternalDecls() flag).
- mutable StoredDeclsMap *LookupPtr;
+ mutable StoredDeclsMap *LookupPtr = nullptr;
protected:
+ friend class ASTDeclReader;
+ friend class ASTWriter;
+ friend class ExternalASTSource;
+
/// FirstDecl - The first declaration stored within this declaration
/// context.
- mutable Decl *FirstDecl;
+ mutable Decl *FirstDecl = nullptr;
/// LastDecl - The last declaration stored within this declaration
/// context. FIXME: We could probably cache this value somewhere
/// outside of the DeclContext, to reduce the size of DeclContext by
/// another pointer.
- mutable Decl *LastDecl;
-
- friend class ExternalASTSource;
- friend class ASTDeclReader;
- friend class ASTWriter;
+ mutable Decl *LastDecl = nullptr;
/// \brief Build up a chain of declarations.
///
@@ -1279,8 +1316,7 @@ protected:
ExternalVisibleStorage(false),
NeedToReconcileExternalVisibleStorage(false),
HasLazyLocalLexicalLookups(false), HasLazyExternalLexicalLookups(false),
- UseQualifiedLookup(false),
- LookupPtr(nullptr), FirstDecl(nullptr), LastDecl(nullptr) {}
+ UseQualifiedLookup(false) {}
public:
~DeclContext();
@@ -1288,6 +1324,7 @@ public:
Decl::Kind getDeclKind() const {
return static_cast<Decl::Kind>(DeclKind);
}
+
const char *getDeclKindName() const;
/// getParent - Returns the containing DeclContext.
@@ -1495,19 +1532,20 @@ public:
/// within this context.
class decl_iterator {
/// Current - The current declaration.
- Decl *Current;
+ Decl *Current = nullptr;
public:
- typedef Decl *value_type;
- typedef const value_type &reference;
- typedef const value_type *pointer;
- typedef std::forward_iterator_tag iterator_category;
- typedef std::ptrdiff_t difference_type;
+ using value_type = Decl *;
+ using reference = const value_type &;
+ using pointer = const value_type *;
+ using iterator_category = std::forward_iterator_tag;
+ using difference_type = std::ptrdiff_t;
- decl_iterator() : Current(nullptr) { }
- explicit decl_iterator(Decl *C) : Current(C) { }
+ decl_iterator() = default;
+ explicit decl_iterator(Decl *C) : Current(C) {}
reference operator*() const { return Current; }
+
// This doesn't meet the iterator requirements, but it's convenient
value_type operator->() const { return Current; }
@@ -1525,12 +1563,13 @@ public:
friend bool operator==(decl_iterator x, decl_iterator y) {
return x.Current == y.Current;
}
+
friend bool operator!=(decl_iterator x, decl_iterator y) {
return x.Current != y.Current;
}
};
- typedef llvm::iterator_range<decl_iterator> decl_range;
+ using decl_range = llvm::iterator_range<decl_iterator>;
/// decls_begin/decls_end - Iterate over the declarations stored in
/// this context.
@@ -1569,16 +1608,16 @@ public:
}
public:
- typedef SpecificDecl *value_type;
- // TODO: Add reference and pointer typedefs (with some appropriate proxy
- // type) if we ever have a need for them.
- typedef void reference;
- typedef void pointer;
- typedef std::iterator_traits<DeclContext::decl_iterator>::difference_type
- difference_type;
- typedef std::forward_iterator_tag iterator_category;
+ using value_type = SpecificDecl *;
+ // TODO: Add reference and pointer types (with some appropriate proxy type)
+ // if we ever have a need for them.
+ using reference = void;
+ using pointer = void;
+ using difference_type =
+ std::iterator_traits<DeclContext::decl_iterator>::difference_type;
+ using iterator_category = std::forward_iterator_tag;
- specific_decl_iterator() : Current() { }
+ specific_decl_iterator() = default;
/// specific_decl_iterator - Construct a new iterator over a
/// subset of the declarations the range [C,
@@ -1593,6 +1632,7 @@ public:
}
value_type operator*() const { return cast<SpecificDecl>(*Current); }
+
// This doesn't meet the iterator requirements, but it's convenient
value_type operator->() const { return **this; }
@@ -1646,16 +1686,16 @@ public:
}
public:
- typedef SpecificDecl *value_type;
- // TODO: Add reference and pointer typedefs (with some appropriate proxy
- // type) if we ever have a need for them.
- typedef void reference;
- typedef void pointer;
- typedef std::iterator_traits<DeclContext::decl_iterator>::difference_type
- difference_type;
- typedef std::forward_iterator_tag iterator_category;
+ using value_type = SpecificDecl *;
+ // TODO: Add reference and pointer types (with some appropriate proxy type)
+ // if we ever have a need for them.
+ using reference = void;
+ using pointer = void;
+ using difference_type =
+ std::iterator_traits<DeclContext::decl_iterator>::difference_type;
+ using iterator_category = std::forward_iterator_tag;
- filtered_decl_iterator() : Current() { }
+ filtered_decl_iterator() = default;
/// filtered_decl_iterator - Construct a new iterator over a
/// subset of the declarations the range [C,
@@ -1733,8 +1773,8 @@ public:
/// @brief Checks whether a declaration is in this context.
bool containsDecl(Decl *D) const;
- typedef DeclContextLookupResult lookup_result;
- typedef lookup_result::iterator lookup_iterator;
+ using lookup_result = DeclContextLookupResult;
+ using lookup_iterator = lookup_result::iterator;
/// lookup - Find the declarations (if any) with the given Name in
/// this context. Returns a range of iterators that contains all of
@@ -1780,7 +1820,7 @@ public:
/// of looking up every possible name.
class all_lookups_iterator;
- typedef llvm::iterator_range<all_lookups_iterator> lookups_range;
+ using lookups_range = llvm::iterator_range<all_lookups_iterator>;
lookups_range lookups() const;
lookups_range noload_lookups() const;
@@ -1796,21 +1836,26 @@ public:
all_lookups_iterator noload_lookups_end() const;
struct udir_iterator;
- typedef llvm::iterator_adaptor_base<udir_iterator, lookup_iterator,
- std::random_access_iterator_tag,
- UsingDirectiveDecl *> udir_iterator_base;
+
+ using udir_iterator_base =
+ llvm::iterator_adaptor_base<udir_iterator, lookup_iterator,
+ std::random_access_iterator_tag,
+ UsingDirectiveDecl *>;
+
struct udir_iterator : udir_iterator_base {
udir_iterator(lookup_iterator I) : udir_iterator_base(I) {}
+
UsingDirectiveDecl *operator*() const;
};
- typedef llvm::iterator_range<udir_iterator> udir_range;
+ using udir_range = llvm::iterator_range<udir_iterator>;
udir_range using_directives() const;
// These are all defined in DependentDiagnostic.h.
class ddiag_iterator;
- typedef llvm::iterator_range<DeclContext::ddiag_iterator> ddiag_range;
+
+ using ddiag_range = llvm::iterator_range<DeclContext::ddiag_iterator>;
inline ddiag_range ddiags() const;
@@ -1883,6 +1928,8 @@ public:
bool Deserialize = false) const;
private:
+ friend class DependentDiagnostic;
+
void reconcileExternalVisibleStorage() const;
bool LoadLexicalDeclsFromExternalStorage() const;
@@ -1894,7 +1941,6 @@ private:
/// use of addDeclInternal().
void makeDeclVisibleInContextInternal(NamedDecl *D);
- friend class DependentDiagnostic;
StoredDeclsMap *CreateStoredDeclsMap(ASTContext &C) const;
void buildLookupImpl(DeclContext *DCtx, bool Internal);
@@ -1933,8 +1979,7 @@ struct cast_convert_decl_context<ToTy, true> {
}
};
-
-} // end clang.
+} // namespace clang
namespace llvm {
@@ -1954,12 +1999,14 @@ struct cast_convert_val<ToTy,
return *::clang::cast_convert_decl_context<ToTy>::doit(&Val);
}
};
+
template<class ToTy>
struct cast_convert_val<ToTy, ::clang::DeclContext, ::clang::DeclContext> {
static ToTy &doit(::clang::DeclContext &Val) {
return *::clang::cast_convert_decl_context<ToTy>::doit(&Val);
}
};
+
template<class ToTy>
struct cast_convert_val<ToTy,
const ::clang::DeclContext*, const ::clang::DeclContext*> {
@@ -1967,6 +2014,7 @@ struct cast_convert_val<ToTy,
return ::clang::cast_convert_decl_context<ToTy>::doit(Val);
}
};
+
template<class ToTy>
struct cast_convert_val<ToTy, ::clang::DeclContext*, ::clang::DeclContext*> {
static ToTy *doit(::clang::DeclContext *Val) {
@@ -2003,6 +2051,6 @@ struct cast_convert_val< const ::clang::DeclContext, FromTy*, FromTy*> {
}
};
-} // end namespace llvm
+} // namespace llvm
-#endif
+#endif // LLVM_CLANG_AST_DECLBASE_H
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 2f735c5506c4..88dc9a655917 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -1,4 +1,4 @@
-//===-- DeclCXX.h - Classes for representing C++ declarations -*- C++ -*-=====//
+//===- DeclCXX.h - Classes for representing C++ declarations --*- C++ -*-=====//
//
// The LLVM Compiler Infrastructure
//
@@ -6,11 +6,11 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-///
+//
/// \file
/// \brief Defines the C++ Decl subclasses, other than those for templates
/// (found in DeclTemplate.h) and friends (in DeclFriend.h).
-///
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_DECLCXX_H
@@ -20,29 +20,56 @@
#include "clang/AST/ASTUnresolvedSet.h"
#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
+#include "clang/AST/DeclarationName.h"
#include "clang/AST/Expr.h"
+#include "clang/AST/ExternalASTSource.h"
#include "clang/AST/LambdaCapture.h"
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/Redeclarable.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/TypeLoc.h"
+#include "clang/AST/UnresolvedSet.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/Lambda.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/OperatorKinds.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/Specifiers.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/PointerLikeTypeTraits.h"
+#include "llvm/Support/TrailingObjects.h"
+#include <cassert>
+#include <cstddef>
+#include <iterator>
+#include <memory>
+#include <vector>
namespace clang {
class ClassTemplateDecl;
-class ClassTemplateSpecializationDecl;
class ConstructorUsingShadowDecl;
class CXXBasePath;
class CXXBasePaths;
class CXXConstructorDecl;
-class CXXConversionDecl;
class CXXDestructorDecl;
-class CXXMethodDecl;
-class CXXRecordDecl;
-class CXXMemberLookupCriteria;
class CXXFinalOverriderMap;
class CXXIndirectPrimaryBaseSet;
+class CXXMethodDecl;
+class DiagnosticBuilder;
class FriendDecl;
-class LambdaExpr;
+class FunctionTemplateDecl;
+class IdentifierInfo;
+class MemberSpecializationInfo;
+class TemplateDecl;
+class TemplateParameterList;
class UsingDecl;
/// \brief Represents any kind of function declaration, whether it is a
@@ -50,10 +77,10 @@ class UsingDecl;
class AnyFunctionDecl {
NamedDecl *Function;
- AnyFunctionDecl(NamedDecl *ND) : Function(ND) { }
+ AnyFunctionDecl(NamedDecl *ND) : Function(ND) {}
public:
- AnyFunctionDecl(FunctionDecl *FD) : Function(FD) { }
+ AnyFunctionDecl(FunctionDecl *FD) : Function(FD) {}
AnyFunctionDecl(FunctionTemplateDecl *FTD);
/// \brief Implicily converts any function or function template into a
@@ -68,17 +95,18 @@ public:
}
};
-} // end namespace clang
+} // namespace clang
namespace llvm {
+
// Provide PointerLikeTypeTraits for non-cvr pointers.
template<>
- class PointerLikeTypeTraits< ::clang::AnyFunctionDecl> {
- public:
- static inline void *getAsVoidPointer(::clang::AnyFunctionDecl F) {
+ struct PointerLikeTypeTraits< ::clang::AnyFunctionDecl> {
+ static void *getAsVoidPointer(::clang::AnyFunctionDecl F) {
return F.get();
}
- static inline ::clang::AnyFunctionDecl getFromVoidPointer(void *P) {
+
+ static ::clang::AnyFunctionDecl getFromVoidPointer(void *P) {
return ::clang::AnyFunctionDecl::getFromNamedDecl(
static_cast< ::clang::NamedDecl*>(P));
}
@@ -86,7 +114,7 @@ namespace llvm {
enum { NumLowBitsAvailable = 2 };
};
-} // end namespace llvm
+} // namespace llvm
namespace clang {
@@ -101,7 +129,6 @@ namespace clang {
/// Also note that this class has nothing to do with so-called
/// "access declarations" (C++98 11.3 [class.access.dcl]).
class AccessSpecDecl : public Decl {
- virtual void anchor();
/// \brief The location of the ':'.
SourceLocation ColonLoc;
@@ -110,16 +137,21 @@ class AccessSpecDecl : public Decl {
: Decl(AccessSpec, DC, ASLoc), ColonLoc(ColonLoc) {
setAccess(AS);
}
- AccessSpecDecl(EmptyShell Empty)
- : Decl(AccessSpec, Empty) { }
+
+ AccessSpecDecl(EmptyShell Empty) : Decl(AccessSpec, Empty) {}
+
+ virtual void anchor();
+
public:
/// \brief The location of the access specifier.
SourceLocation getAccessSpecifierLoc() const { return getLocation(); }
+
/// \brief Sets the location of the access specifier.
void setAccessSpecifierLoc(SourceLocation ASLoc) { setLocation(ASLoc); }
/// \brief The location of the colon following the access specifier.
SourceLocation getColonLoc() const { return ColonLoc; }
+
/// \brief Sets the location of the colon.
void setColonLoc(SourceLocation CLoc) { ColonLoc = CLoc; }
@@ -132,6 +164,7 @@ public:
SourceLocation ColonLoc) {
return new (C, DC) AccessSpecDecl(AS, DC, ASLoc, ColonLoc);
}
+
static AccessSpecDecl *CreateDeserialized(ASTContext &C, unsigned ID);
// Implement isa/cast/dyncast/etc.
@@ -191,12 +224,11 @@ class CXXBaseSpecifier {
TypeSourceInfo *BaseTypeInfo;
public:
- CXXBaseSpecifier() { }
-
+ CXXBaseSpecifier() = default;
CXXBaseSpecifier(SourceRange R, bool V, bool BC, AccessSpecifier A,
TypeSourceInfo *TInfo, SourceLocation EllipsisLoc)
: Range(R), EllipsisLoc(EllipsisLoc), Virtual(V), BaseOfClass(BC),
- Access(A), InheritConstructors(false), BaseTypeInfo(TInfo) { }
+ Access(A), InheritConstructors(false), BaseTypeInfo(TInfo) {}
/// \brief Retrieves the source range that contains the entire base specifier.
SourceRange getSourceRange() const LLVM_READONLY { return Range; }
@@ -265,7 +297,16 @@ public:
/// \brief Represents a C++ struct/union/class.
class CXXRecordDecl : public RecordDecl {
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+ friend class ASTNodeImporter;
+ friend class ASTReader;
+ friend class ASTRecordWriter;
+ friend class ASTWriter;
+ friend class DeclContext;
+ friend class LambdaExpr;
+ friend void FunctionDecl::setPure(bool);
friend void TagDecl::startDefinition();
/// Values used in DefinitionData fields to represent special members.
@@ -280,8 +321,6 @@ class CXXRecordDecl : public RecordDecl {
};
struct DefinitionData {
- DefinitionData(CXXRecordDecl *D);
-
/// \brief True if this class has any user-declared constructors.
unsigned UserDeclaredConstructor : 1;
@@ -475,13 +514,13 @@ class CXXRecordDecl : public RecordDecl {
unsigned HasODRHash : 1;
/// \brief A hash of parts of the class to help in ODR checking.
- unsigned ODRHash;
+ unsigned ODRHash = 0;
/// \brief The number of base class specifiers in Bases.
- unsigned NumBases;
+ unsigned NumBases = 0;
/// \brief The number of virtual base class specifiers in VBases.
- unsigned NumVBases;
+ unsigned NumVBases = 0;
/// \brief Base classes of this class.
///
@@ -513,6 +552,8 @@ class CXXRecordDecl : public RecordDecl {
/// This is actually currently stored in reverse order.
LazyDeclPtr FirstFriend;
+ DefinitionData(CXXRecordDecl *D);
+
/// \brief Retrieve the set of direct base classes.
CXXBaseSpecifier *getBases() const {
if (!Bases.isOffset())
@@ -530,6 +571,7 @@ class CXXRecordDecl : public RecordDecl {
ArrayRef<CXXBaseSpecifier> bases() const {
return llvm::makeArrayRef(getBases(), NumBases);
}
+
ArrayRef<CXXBaseSpecifier> vbases() const {
return llvm::makeArrayRef(getVBases(), NumVBases);
}
@@ -543,22 +585,7 @@ class CXXRecordDecl : public RecordDecl {
/// \brief Describes a C++ closure type (generated by a lambda expression).
struct LambdaDefinitionData : public DefinitionData {
- typedef LambdaCapture Capture;
-
- LambdaDefinitionData(CXXRecordDecl *D, TypeSourceInfo *Info,
- bool Dependent, bool IsGeneric,
- LambdaCaptureDefault CaptureDefault)
- : DefinitionData(D), Dependent(Dependent), IsGenericLambda(IsGeneric),
- CaptureDefault(CaptureDefault), NumCaptures(0), NumExplicitCaptures(0),
- ManglingNumber(0), ContextDecl(nullptr), Captures(nullptr),
- MethodTyInfo(Info) {
- IsLambda = true;
-
- // C++1z [expr.prim.lambda]p4:
- // This class type is not an aggregate type.
- Aggregate = false;
- PlainOldData = false;
- }
+ using Capture = LambdaCapture;
/// \brief Whether this lambda is known to be dependent, even if its
/// context isn't dependent.
@@ -584,7 +611,7 @@ class CXXRecordDecl : public RecordDecl {
/// \brief The number used to indicate this lambda expression for name
/// mangling in the Itanium C++ ABI.
- unsigned ManglingNumber;
+ unsigned ManglingNumber = 0;
/// \brief The declaration that provides context for this lambda, if the
/// actual DeclContext does not suffice. This is used for lambdas that
@@ -594,11 +621,24 @@ class CXXRecordDecl : public RecordDecl {
/// \brief The list of captures, both explicit and implicit, for this
/// lambda.
- Capture *Captures;
+ Capture *Captures = nullptr;
/// \brief The type of the call method.
TypeSourceInfo *MethodTyInfo;
-
+
+ LambdaDefinitionData(CXXRecordDecl *D, TypeSourceInfo *Info,
+ bool Dependent, bool IsGeneric,
+ LambdaCaptureDefault CaptureDefault)
+ : DefinitionData(D), Dependent(Dependent), IsGenericLambda(IsGeneric),
+ CaptureDefault(CaptureDefault), NumCaptures(0), NumExplicitCaptures(0),
+ MethodTyInfo(Info) {
+ IsLambda = true;
+
+ // C++1z [expr.prim.lambda]p4:
+ // This class type is not an aggregate type.
+ Aggregate = false;
+ PlainOldData = false;
+ }
};
struct DefinitionData *dataPtr() const {
@@ -630,11 +670,8 @@ class CXXRecordDecl : public RecordDecl {
/// classes of class template specializations, this will be the
/// MemberSpecializationInfo referring to the member class that was
/// instantiated or specialized.
- llvm::PointerUnion<ClassTemplateDecl*, MemberSpecializationInfo*>
- TemplateOrInstantiation;
-
- friend class DeclContext;
- friend class LambdaExpr;
+ llvm::PointerUnion<ClassTemplateDecl *, MemberSpecializationInfo *>
+ TemplateOrInstantiation;
/// \brief Called from setBases and addedMember to notify the class that a
/// direct or virtual base class or a member of class type has been added.
@@ -648,9 +685,6 @@ class CXXRecordDecl : public RecordDecl {
void addedMember(Decl *D);
void markedVirtualFunctionPure();
- friend void FunctionDecl::setPure(bool);
-
- friend class ASTNodeImporter;
/// \brief Get the head of our list of friend declarations, possibly
/// deserializing the friends from an external AST source.
@@ -663,14 +697,15 @@ protected:
public:
/// \brief Iterator that traverses the base classes of a class.
- typedef CXXBaseSpecifier* base_class_iterator;
+ using base_class_iterator = CXXBaseSpecifier *;
/// \brief Iterator that traverses the base classes of a class.
- typedef const CXXBaseSpecifier* base_class_const_iterator;
+ using base_class_const_iterator = const CXXBaseSpecifier *;
CXXRecordDecl *getCanonicalDecl() override {
return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl());
}
+
const CXXRecordDecl *getCanonicalDecl() const {
return const_cast<CXXRecordDecl*>(this)->getCanonicalDecl();
}
@@ -679,6 +714,7 @@ public:
return cast_or_null<CXXRecordDecl>(
static_cast<RecordDecl *>(this)->getPreviousDecl());
}
+
const CXXRecordDecl *getPreviousDecl() const {
return const_cast<CXXRecordDecl*>(this)->getPreviousDecl();
}
@@ -730,9 +766,9 @@ public:
/// \brief Retrieves the number of base classes of this class.
unsigned getNumBases() const { return data().NumBases; }
- typedef llvm::iterator_range<base_class_iterator> base_class_range;
- typedef llvm::iterator_range<base_class_const_iterator>
- base_class_const_range;
+ using base_class_range = llvm::iterator_range<base_class_iterator>;
+ using base_class_const_range =
+ llvm::iterator_range<base_class_const_iterator>;
base_class_range bases() {
return base_class_range(bases_begin(), bases_end());
@@ -772,9 +808,9 @@ public:
/// Iterator access to method members. The method iterator visits
/// all method members of the class, including non-instance methods,
/// special methods, etc.
- typedef specific_decl_iterator<CXXMethodDecl> method_iterator;
- typedef llvm::iterator_range<specific_decl_iterator<CXXMethodDecl>>
- method_range;
+ using method_iterator = specific_decl_iterator<CXXMethodDecl>;
+ using method_range =
+ llvm::iterator_range<specific_decl_iterator<CXXMethodDecl>>;
method_range methods() const {
return method_range(method_begin(), method_end());
@@ -785,21 +821,23 @@ public:
method_iterator method_begin() const {
return method_iterator(decls_begin());
}
+
/// \brief Method past-the-end iterator.
method_iterator method_end() const {
return method_iterator(decls_end());
}
/// Iterator access to constructor members.
- typedef specific_decl_iterator<CXXConstructorDecl> ctor_iterator;
- typedef llvm::iterator_range<specific_decl_iterator<CXXConstructorDecl>>
- ctor_range;
+ using ctor_iterator = specific_decl_iterator<CXXConstructorDecl>;
+ using ctor_range =
+ llvm::iterator_range<specific_decl_iterator<CXXConstructorDecl>>;
ctor_range ctors() const { return ctor_range(ctor_begin(), ctor_end()); }
ctor_iterator ctor_begin() const {
return ctor_iterator(decls_begin());
}
+
ctor_iterator ctor_end() const {
return ctor_iterator(decls_end());
}
@@ -807,7 +845,7 @@ public:
/// An iterator over friend declarations. All of these are defined
/// in DeclFriend.h.
class friend_iterator;
- typedef llvm::iterator_range<friend_iterator> friend_range;
+ using friend_range = llvm::iterator_range<friend_iterator>;
friend_range friends() const;
friend_iterator friend_begin() const;
@@ -839,7 +877,10 @@ public:
/// \brief \c true if a defaulted destructor for this class would be deleted.
bool defaultedDestructorIsDeleted() const {
- return !data().DefaultedDestructorIsDeleted;
+ assert((!needsOverloadResolutionForDestructor() ||
+ (data().DeclaredSpecialMembers & SMF_Destructor)) &&
+ "this property has not yet been computed by Sema");
+ return data().DefaultedDestructorIsDeleted;
}
/// \brief \c true if we know for sure that this class has a single,
@@ -986,6 +1027,15 @@ public:
data().DefaultedMoveConstructorIsDeleted = true;
}
+ /// \brief Set that we attempted to declare an implicit destructor,
+ /// but overload resolution failed so we deleted it.
+ void setImplicitDestructorIsDeleted() {
+ assert((data().DefaultedDestructorIsDeleted ||
+ needsOverloadResolutionForDestructor()) &&
+ "destructor should not be deleted");
+ data().DefaultedDestructorIsDeleted = true;
+ }
+
/// \brief Determine whether this class should get an implicit move
/// constructor or if any existing special member function inhibits this.
bool needsImplicitMoveConstructor() const {
@@ -1144,24 +1194,28 @@ public:
void getCaptureFields(llvm::DenseMap<const VarDecl *, FieldDecl *> &Captures,
FieldDecl *&ThisCapture) const;
- typedef const LambdaCapture *capture_const_iterator;
- typedef llvm::iterator_range<capture_const_iterator> capture_const_range;
+ using capture_const_iterator = const LambdaCapture *;
+ using capture_const_range = llvm::iterator_range<capture_const_iterator>;
capture_const_range captures() const {
return capture_const_range(captures_begin(), captures_end());
}
+
capture_const_iterator captures_begin() const {
return isLambda() ? getLambdaData().Captures : nullptr;
}
+
capture_const_iterator captures_end() const {
return isLambda() ? captures_begin() + getLambdaData().NumCaptures
: nullptr;
}
- typedef UnresolvedSetIterator conversion_iterator;
+ using conversion_iterator = UnresolvedSetIterator;
+
conversion_iterator conversion_begin() const {
return data().Conversions.get(getASTContext()).begin();
}
+
conversion_iterator conversion_end() const {
return data().Conversions.get(getASTContext()).end();
}
@@ -1433,10 +1487,10 @@ public:
/// We resolve DR1361 by ignoring the second bullet. We resolve DR1452 by
/// treating types with trivial default constructors as literal types.
///
- /// Only in C++1z and beyond, are lambdas literal types.
+ /// Only in C++17 and beyond, are lambdas literal types.
bool isLiteral() const {
return hasTrivialDestructor() &&
- (!isLambda() || getASTContext().getLangOpts().CPlusPlus1z) &&
+ (!isLambda() || getASTContext().getLangOpts().CPlusPlus17) &&
!hasNonLiteralTypeFieldsOrBases() &&
(isAggregate() || isLambda() ||
hasConstexprNonCopyMoveConstructor() ||
@@ -1585,8 +1639,8 @@ public:
/// \param BaseDefinition the definition of the base class
///
/// \returns true if this base matched the search criteria
- typedef llvm::function_ref<bool(const CXXRecordDecl *BaseDefinition)>
- ForallBasesCallback;
+ using ForallBasesCallback =
+ llvm::function_ref<bool(const CXXRecordDecl *BaseDefinition)>;
/// \brief Determines if the given callback holds for all the direct
/// or indirect base classes of this type.
@@ -1614,8 +1668,9 @@ public:
/// base named by the \p Specifier.
///
/// \returns true if this base matched the search criteria, false otherwise.
- typedef llvm::function_ref<bool(const CXXBaseSpecifier *Specifier,
- CXXBasePath &Path)> BaseMatchesCallback;
+ using BaseMatchesCallback =
+ llvm::function_ref<bool(const CXXBaseSpecifier *Specifier,
+ CXXBasePath &Path)>;
/// \brief Look for entities within the base classes of this C++ class,
/// transitively searching all base class subobjects.
@@ -1794,6 +1849,7 @@ public:
/// \brief Returns the inheritance model used for this record.
MSInheritanceAttr::Spelling getMSInheritanceModel() const;
+
/// \brief Calculate what the inheritance model would be for this class.
MSInheritanceAttr::Spelling calculateInheritanceModel() const;
@@ -1832,16 +1888,14 @@ public:
return getLambdaData().MethodTyInfo;
}
+ // \brief Determine whether this type is an Interface Like type for
+ // __interface inheritence purposes.
+ bool isInterfaceLike() const;
+
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) {
return K >= firstCXXRecord && K <= lastCXXRecord;
}
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
- friend class ASTRecordWriter;
- friend class ASTReader;
- friend class ASTWriter;
};
/// \brief Represents a C++ deduction guide declaration.
@@ -1856,6 +1910,7 @@ public:
/// the constructors of \c A.
class CXXDeductionGuideDecl : public FunctionDecl {
void anchor() override;
+
private:
CXXDeductionGuideDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
bool IsExplicit, const DeclarationNameInfo &NameInfo,
@@ -1869,6 +1924,9 @@ private:
}
public:
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+
static CXXDeductionGuideDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, bool IsExplicit,
const DeclarationNameInfo &NameInfo,
@@ -1888,12 +1946,15 @@ public:
return getDeclName().getCXXDeductionGuideTemplate();
}
+ void setIsCopyDeductionCandidate() {
+ IsCopyDeductionCandidate = true;
+ }
+
+ bool isCopyDeductionCandidate() const { return IsCopyDeductionCandidate; }
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == CXXDeductionGuide; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
};
/// \brief Represents a static or instance method of a struct/union/class.
@@ -1902,6 +1963,7 @@ public:
/// non-static) member functions, whether virtual or not.
class CXXMethodDecl : public FunctionDecl {
void anchor() override;
+
protected:
CXXMethodDecl(Kind DK, ASTContext &C, CXXRecordDecl *RD,
SourceLocation StartLoc, const DeclarationNameInfo &NameInfo,
@@ -1953,7 +2015,7 @@ public:
if (CD->isVirtualAsWritten() || CD->isPure())
return true;
- return (CD->begin_overridden_methods() != CD->end_overridden_methods());
+ return CD->size_overridden_methods() != 0;
}
/// If it's possible to devirtualize a call to this method, return the called
@@ -1999,18 +2061,23 @@ public:
/// True if this method is user-declared and was not
/// deleted or defaulted on its first declaration.
bool isUserProvided() const {
- return !(isDeleted() || getCanonicalDecl()->isDefaulted());
+ auto *DeclAsWritten = this;
+ if (auto *Pattern = getTemplateInstantiationPattern())
+ DeclAsWritten = cast<CXXMethodDecl>(Pattern);
+ return !(DeclAsWritten->isDeleted() ||
+ DeclAsWritten->getCanonicalDecl()->isDefaulted());
}
- ///
void addOverriddenMethod(const CXXMethodDecl *MD);
- typedef const CXXMethodDecl *const* method_iterator;
+ using method_iterator = const CXXMethodDecl *const *;
method_iterator begin_overridden_methods() const;
method_iterator end_overridden_methods() const;
unsigned size_overridden_methods() const;
- typedef ASTContext::overridden_method_range overridden_method_range;
+
+ using overridden_method_range= ASTContext::overridden_method_range;
+
overridden_method_range overridden_methods() const;
/// Returns the parent of this method declaration, which
@@ -2240,6 +2307,7 @@ public:
return Initializee.get<FieldDecl*>();
return nullptr;
}
+
FieldDecl *getAnyMember() const {
if (isMemberInitializer())
return Initializee.get<FieldDecl*>();
@@ -2301,11 +2369,11 @@ public:
/// Description of a constructor that was inherited from a base class.
class InheritedConstructor {
- ConstructorUsingShadowDecl *Shadow;
- CXXConstructorDecl *BaseCtor;
+ ConstructorUsingShadowDecl *Shadow = nullptr;
+ CXXConstructorDecl *BaseCtor = nullptr;
public:
- InheritedConstructor() : Shadow(), BaseCtor() {}
+ InheritedConstructor() = default;
InheritedConstructor(ConstructorUsingShadowDecl *Shadow,
CXXConstructorDecl *BaseCtor)
: Shadow(Shadow), BaseCtor(BaseCtor) {}
@@ -2329,8 +2397,6 @@ public:
class CXXConstructorDecl final
: public CXXMethodDecl,
private llvm::TrailingObjects<CXXConstructorDecl, InheritedConstructor> {
- void anchor() override;
-
/// \name Support for base and member initializers.
/// \{
/// \brief The arguments used to initialize the base or member.
@@ -2350,15 +2416,20 @@ class CXXConstructorDecl final
InheritedConstructor Inherited)
: CXXMethodDecl(CXXConstructor, C, RD, StartLoc, NameInfo, T, TInfo,
SC_None, isInline, isConstexpr, SourceLocation()),
- CtorInitializers(nullptr), NumCtorInitializers(0),
- IsInheritingConstructor((bool)Inherited) {
+ NumCtorInitializers(0), IsInheritingConstructor((bool)Inherited) {
setImplicit(isImplicitlyDeclared);
if (Inherited)
*getTrailingObjects<InheritedConstructor>() = Inherited;
IsExplicitSpecified = isExplicitSpecified;
}
+ void anchor() override;
+
public:
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+ friend TrailingObjects;
+
static CXXConstructorDecl *CreateDeserialized(ASTContext &C, unsigned ID,
bool InheritsConstructor);
static CXXConstructorDecl *
@@ -2369,13 +2440,13 @@ public:
InheritedConstructor Inherited = InheritedConstructor());
/// \brief Iterates through the member/base initializer list.
- typedef CXXCtorInitializer **init_iterator;
+ using init_iterator = CXXCtorInitializer **;
/// \brief Iterates through the member/base initializer list.
- typedef CXXCtorInitializer *const *init_const_iterator;
+ using init_const_iterator = CXXCtorInitializer *const *;
- typedef llvm::iterator_range<init_iterator> init_range;
- typedef llvm::iterator_range<init_const_iterator> init_const_range;
+ using init_range = llvm::iterator_range<init_iterator>;
+ using init_const_range = llvm::iterator_range<init_const_iterator>;
init_range inits() { return init_range(init_begin(), init_end()); }
init_const_range inits() const {
@@ -2387,6 +2458,7 @@ public:
const auto *ConstThis = this;
return const_cast<init_iterator>(ConstThis->init_begin());
}
+
/// \brief Retrieve an iterator to the first initializer.
init_const_iterator init_begin() const;
@@ -2394,14 +2466,15 @@ public:
init_iterator init_end() {
return init_begin() + NumCtorInitializers;
}
+
/// \brief Retrieve an iterator past the last initializer.
init_const_iterator init_end() const {
return init_begin() + NumCtorInitializers;
}
- typedef std::reverse_iterator<init_iterator> init_reverse_iterator;
- typedef std::reverse_iterator<init_const_iterator>
- init_const_reverse_iterator;
+ using init_reverse_iterator = std::reverse_iterator<init_iterator>;
+ using init_const_reverse_iterator =
+ std::reverse_iterator<init_const_iterator>;
init_reverse_iterator init_rbegin() {
return init_reverse_iterator(init_end());
@@ -2532,10 +2605,6 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == CXXConstructor; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
- friend TrailingObjects;
};
/// \brief Represents a C++ destructor within a class.
@@ -2549,20 +2618,26 @@ public:
/// };
/// \endcode
class CXXDestructorDecl : public CXXMethodDecl {
- void anchor() override;
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
- FunctionDecl *OperatorDelete;
+ // FIXME: Don't allocate storage for these except in the first declaration
+ // of a virtual destructor.
+ FunctionDecl *OperatorDelete = nullptr;
+ Expr *OperatorDeleteThisArg = nullptr;
CXXDestructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
bool isInline, bool isImplicitlyDeclared)
: CXXMethodDecl(CXXDestructor, C, RD, StartLoc, NameInfo, T, TInfo,
- SC_None, isInline, /*isConstexpr=*/false, SourceLocation()),
- OperatorDelete(nullptr) {
+ SC_None, isInline, /*isConstexpr=*/false, SourceLocation())
+ {
setImplicit(isImplicitlyDeclared);
}
+ void anchor() override;
+
public:
static CXXDestructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation StartLoc,
@@ -2572,11 +2647,16 @@ public:
bool isImplicitlyDeclared);
static CXXDestructorDecl *CreateDeserialized(ASTContext & C, unsigned ID);
- void setOperatorDelete(FunctionDecl *OD);
+ void setOperatorDelete(FunctionDecl *OD, Expr *ThisArg);
+
const FunctionDecl *getOperatorDelete() const {
return getCanonicalDecl()->OperatorDelete;
}
+ Expr *getOperatorDeleteThisArg() const {
+ return getCanonicalDecl()->OperatorDeleteThisArg;
+ }
+
CXXDestructorDecl *getCanonicalDecl() override {
return cast<CXXDestructorDecl>(FunctionDecl::getCanonicalDecl());
}
@@ -2587,9 +2667,6 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == CXXDestructor; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
};
/// \brief Represents a C++ conversion function within a class.
@@ -2603,8 +2680,6 @@ public:
/// };
/// \endcode
class CXXConversionDecl : public CXXMethodDecl {
- void anchor() override;
-
CXXConversionDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, QualType T,
TypeSourceInfo *TInfo, bool isInline,
@@ -2615,7 +2690,12 @@ class CXXConversionDecl : public CXXMethodDecl {
IsExplicitSpecified = isExplicitSpecified;
}
+ void anchor() override;
+
public:
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+
static CXXConversionDecl *Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
@@ -2652,9 +2732,6 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == CXXConversion; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
};
/// \brief Represents a linkage specification.
@@ -2665,6 +2742,7 @@ public:
/// \endcode
class LinkageSpecDecl : public Decl, public DeclContext {
virtual void anchor();
+
public:
/// \brief Represents the language in a linkage specification.
///
@@ -2676,25 +2754,29 @@ public:
lang_c = /* DW_LANG_C */ 0x0002,
lang_cxx = /* DW_LANG_C_plus_plus */ 0x0004
};
+
private:
/// \brief The language for this linkage specification.
unsigned Language : 3;
+
/// \brief 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;
+
/// \brief The source location for the extern keyword.
SourceLocation ExternLoc;
+
/// \brief The source location for the right brace (if valid).
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()) { }
+ : Decl(LinkageSpec, DC, LangLoc), DeclContext(LinkageSpec),
+ Language(lang), HasBraces(HasBraces), ExternLoc(ExternLoc),
+ RBraceLoc(SourceLocation()) {}
public:
static LinkageSpecDecl *Create(ASTContext &C, DeclContext *DC,
@@ -2705,6 +2787,7 @@ public:
/// \brief Return the language specified by this linkage specification.
LanguageIDs getLanguage() const { return LanguageIDs(Language); }
+
/// \brief Set the language specified by this linkage specification.
void setLanguage(LanguageIDs L) { Language = L; }
@@ -2737,9 +2820,11 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == LinkageSpec; }
+
static DeclContext *castToDeclContext(const LinkageSpecDecl *D) {
return static_cast<DeclContext *>(const_cast<LinkageSpecDecl*>(D));
}
+
static LinkageSpecDecl *castFromDeclContext(const DeclContext *DC) {
return static_cast<LinkageSpecDecl *>(const_cast<DeclContext*>(DC));
}
@@ -2756,7 +2841,6 @@ public:
/// artificial names for all using-directives in order to store
/// them in DeclContext effectively.
class UsingDirectiveDecl : public NamedDecl {
- void anchor() override;
/// \brief The location of the \c using keyword.
SourceLocation UsingLoc;
@@ -2773,6 +2857,16 @@ class UsingDirectiveDecl : public NamedDecl {
/// namespace.
DeclContext *CommonAncestor;
+ UsingDirectiveDecl(DeclContext *DC, SourceLocation UsingLoc,
+ SourceLocation NamespcLoc,
+ NestedNameSpecifierLoc QualifierLoc,
+ SourceLocation IdentLoc,
+ NamedDecl *Nominated,
+ DeclContext *CommonAncestor)
+ : NamedDecl(UsingDirective, DC, IdentLoc, getName()), UsingLoc(UsingLoc),
+ NamespaceLoc(NamespcLoc), QualifierLoc(QualifierLoc),
+ NominatedNamespace(Nominated), CommonAncestor(CommonAncestor) {}
+
/// \brief Returns special DeclarationName used by using-directives.
///
/// This is only used by DeclContext for storing UsingDirectiveDecls in
@@ -2781,17 +2875,14 @@ class UsingDirectiveDecl : public NamedDecl {
return DeclarationName::getUsingDirectiveName();
}
- UsingDirectiveDecl(DeclContext *DC, SourceLocation UsingLoc,
- SourceLocation NamespcLoc,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation IdentLoc,
- NamedDecl *Nominated,
- DeclContext *CommonAncestor)
- : NamedDecl(UsingDirective, DC, IdentLoc, getName()), UsingLoc(UsingLoc),
- NamespaceLoc(NamespcLoc), QualifierLoc(QualifierLoc),
- NominatedNamespace(Nominated), CommonAncestor(CommonAncestor) { }
+ void anchor() override;
public:
+ friend class ASTDeclReader;
+
+ // Friend for getUsingDirectiveName.
+ friend class DeclContext;
+
/// \brief Retrieve the nested-name-specifier that qualifies the
/// name of the namespace, with source-location information.
NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
@@ -2844,11 +2935,6 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == UsingDirective; }
-
- // Friend for getUsingDirectiveName.
- friend class DeclContext;
-
- friend class ASTDeclReader;
};
/// \brief Represents a C++ namespace alias.
@@ -2860,7 +2946,7 @@ public:
/// \endcode
class NamespaceAliasDecl : public NamedDecl,
public Redeclarable<NamespaceAliasDecl> {
- void anchor() override;
+ friend class ASTDeclReader;
/// \brief The location of the \c namespace keyword.
SourceLocation NamespaceLoc;
@@ -2885,13 +2971,14 @@ class NamespaceAliasDecl : public NamedDecl,
NamespaceLoc(NamespaceLoc), IdentLoc(IdentLoc),
QualifierLoc(QualifierLoc), Namespace(Namespace) {}
- typedef Redeclarable<NamespaceAliasDecl> redeclarable_base;
+ void anchor() override;
+
+ using redeclarable_base = Redeclarable<NamespaceAliasDecl>;
+
NamespaceAliasDecl *getNextRedeclarationImpl() override;
NamespaceAliasDecl *getPreviousDeclImpl() override;
NamespaceAliasDecl *getMostRecentDeclImpl() override;
- friend class ASTDeclReader;
-
public:
static NamespaceAliasDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation NamespaceLoc,
@@ -2903,8 +2990,9 @@ public:
static NamespaceAliasDecl *CreateDeserialized(ASTContext &C, unsigned ID);
- typedef redeclarable_base::redecl_range redecl_range;
- typedef redeclarable_base::redecl_iterator redecl_iterator;
+ using redecl_range = redeclarable_base::redecl_range;
+ using redecl_iterator = redeclarable_base::redecl_iterator;
+
using redeclarable_base::redecls_begin;
using redeclarable_base::redecls_end;
using redeclarable_base::redecls;
@@ -2976,23 +3064,27 @@ public:
/// }
/// \endcode
class UsingShadowDecl : public NamedDecl, public Redeclarable<UsingShadowDecl> {
- void anchor() override;
+ friend class UsingDecl;
/// The referenced declaration.
- NamedDecl *Underlying;
+ NamedDecl *Underlying = nullptr;
/// \brief The using declaration which introduced this decl or the next using
/// shadow declaration contained in the aforementioned using declaration.
- NamedDecl *UsingOrNextShadow;
- friend class UsingDecl;
+ NamedDecl *UsingOrNextShadow = nullptr;
+
+ void anchor() override;
+
+ using redeclarable_base = Redeclarable<UsingShadowDecl>;
- typedef Redeclarable<UsingShadowDecl> redeclarable_base;
UsingShadowDecl *getNextRedeclarationImpl() override {
return getNextRedeclaration();
}
+
UsingShadowDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
}
+
UsingShadowDecl *getMostRecentDeclImpl() override {
return getMostRecentDecl();
}
@@ -3003,6 +3095,9 @@ protected:
UsingShadowDecl(Kind K, ASTContext &C, EmptyShell);
public:
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+
static UsingShadowDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation Loc, UsingDecl *Using,
NamedDecl *Target) {
@@ -3011,8 +3106,9 @@ public:
static UsingShadowDecl *CreateDeserialized(ASTContext &C, unsigned ID);
- typedef redeclarable_base::redecl_range redecl_range;
- typedef redeclarable_base::redecl_iterator redecl_iterator;
+ using redecl_range = redeclarable_base::redecl_range;
+ using redecl_iterator = redeclarable_base::redecl_iterator;
+
using redeclarable_base::redecls_begin;
using redeclarable_base::redecls_end;
using redeclarable_base::redecls;
@@ -3052,9 +3148,6 @@ public:
static bool classofKind(Kind K) {
return K == Decl::UsingShadow || K == Decl::ConstructorUsingShadow;
}
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
};
/// \brief Represents a shadow constructor declaration introduced into a
@@ -3068,18 +3161,16 @@ public:
/// };
/// \endcode
class ConstructorUsingShadowDecl final : public UsingShadowDecl {
- void anchor() override;
-
/// \brief If this constructor using declaration inherted the constructor
/// from an indirect base class, this is the ConstructorUsingShadowDecl
/// in the named direct base class from which the declaration was inherited.
- ConstructorUsingShadowDecl *NominatedBaseClassShadowDecl;
+ ConstructorUsingShadowDecl *NominatedBaseClassShadowDecl = nullptr;
/// \brief If this constructor using declaration inherted the constructor
/// from an indirect base class, this is the ConstructorUsingShadowDecl
/// that will be used to construct the unique direct or virtual base class
/// that receives the constructor arguments.
- ConstructorUsingShadowDecl *ConstructedBaseClassShadowDecl;
+ ConstructorUsingShadowDecl *ConstructedBaseClassShadowDecl = nullptr;
/// \brief \c true if the constructor ultimately named by this using shadow
/// declaration is within a virtual base class subobject of the class that
@@ -3105,12 +3196,16 @@ class ConstructorUsingShadowDecl final : public UsingShadowDecl {
IsVirtual = true;
}
}
+
ConstructorUsingShadowDecl(ASTContext &C, EmptyShell Empty)
- : UsingShadowDecl(ConstructorUsingShadow, C, Empty),
- NominatedBaseClassShadowDecl(), ConstructedBaseClassShadowDecl(),
- IsVirtual(false) {}
+ : UsingShadowDecl(ConstructorUsingShadow, C, Empty), IsVirtual(false) {}
+
+ void anchor() override;
public:
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+
static ConstructorUsingShadowDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation Loc,
UsingDecl *Using, NamedDecl *Target,
@@ -3169,9 +3264,6 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == ConstructorUsingShadow; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
};
/// \brief Represents a C++ using-declaration.
@@ -3181,8 +3273,6 @@ public:
/// using someNameSpace::someIdentifier;
/// \endcode
class UsingDecl : public NamedDecl, public Mergeable<UsingDecl> {
- void anchor() override;
-
/// \brief The source location of the 'using' keyword itself.
SourceLocation UsingLocation;
@@ -3208,7 +3298,12 @@ class UsingDecl : public NamedDecl, public Mergeable<UsingDecl> {
DNLoc(NameInfo.getInfo()), FirstUsingShadow(nullptr, HasTypenameKeyword) {
}
+ void anchor() override;
+
public:
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+
/// \brief Return the source location of the 'using' keyword.
SourceLocation getUsingLoc() const { return UsingLocation; }
@@ -3241,17 +3336,17 @@ public:
/// this using declaration.
class shadow_iterator {
/// \brief The current using shadow declaration.
- UsingShadowDecl *Current;
+ UsingShadowDecl *Current = nullptr;
public:
- typedef UsingShadowDecl* value_type;
- typedef UsingShadowDecl* reference;
- typedef UsingShadowDecl* pointer;
- typedef std::forward_iterator_tag iterator_category;
- typedef std::ptrdiff_t difference_type;
+ using value_type = UsingShadowDecl *;
+ using reference = UsingShadowDecl *;
+ using pointer = UsingShadowDecl *;
+ using iterator_category = std::forward_iterator_tag;
+ using difference_type = std::ptrdiff_t;
- shadow_iterator() : Current(nullptr) { }
- explicit shadow_iterator(UsingShadowDecl *C) : Current(C) { }
+ shadow_iterator() = default;
+ explicit shadow_iterator(UsingShadowDecl *C) : Current(C) {}
reference operator*() const { return Current; }
pointer operator->() const { return Current; }
@@ -3275,14 +3370,16 @@ public:
}
};
- typedef llvm::iterator_range<shadow_iterator> shadow_range;
+ using shadow_range = llvm::iterator_range<shadow_iterator>;
shadow_range shadows() const {
return shadow_range(shadow_begin(), shadow_end());
}
+
shadow_iterator shadow_begin() const {
return shadow_iterator(FirstUsingShadow.getPointer());
}
+
shadow_iterator shadow_end() const { return shadow_iterator(); }
/// \brief Return the number of shadowed declarations associated with this
@@ -3310,9 +3407,6 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == Using; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
};
/// Represents a pack of using declarations that a single
@@ -3331,8 +3425,6 @@ public:
class UsingPackDecl final
: public NamedDecl, public Mergeable<UsingPackDecl>,
private llvm::TrailingObjects<UsingPackDecl, NamedDecl *> {
- void anchor() override;
-
/// The UnresolvedUsingValueDecl or UnresolvedUsingTypenameDecl from
/// which this waas instantiated.
NamedDecl *InstantiatedFrom;
@@ -3352,7 +3444,13 @@ class UsingPackDecl final
getTrailingObjects<NamedDecl *>());
}
+ void anchor() override;
+
public:
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+ friend TrailingObjects;
+
/// Get the using declaration from which this was instantiated. This will
/// always be an UnresolvedUsingValueDecl or an UnresolvedUsingTypenameDecl
/// that is a pack expansion.
@@ -3380,10 +3478,6 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == UsingPack; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
- friend TrailingObjects;
};
/// \brief Represents a dependent using declaration which was not marked with
@@ -3399,8 +3493,6 @@ public:
/// \endcode
class UnresolvedUsingValueDecl : public ValueDecl,
public Mergeable<UnresolvedUsingValueDecl> {
- void anchor() override;
-
/// \brief The source location of the 'using' keyword
SourceLocation UsingLocation;
@@ -3419,13 +3511,17 @@ class UnresolvedUsingValueDecl : public ValueDecl,
NestedNameSpecifierLoc QualifierLoc,
const DeclarationNameInfo &NameInfo,
SourceLocation EllipsisLoc)
- : ValueDecl(UnresolvedUsingValue, DC,
- NameInfo.getLoc(), NameInfo.getName(), Ty),
- UsingLocation(UsingLoc), EllipsisLoc(EllipsisLoc),
- QualifierLoc(QualifierLoc), DNLoc(NameInfo.getInfo())
- { }
+ : ValueDecl(UnresolvedUsingValue, DC,
+ NameInfo.getLoc(), NameInfo.getName(), Ty),
+ UsingLocation(UsingLoc), EllipsisLoc(EllipsisLoc),
+ QualifierLoc(QualifierLoc), DNLoc(NameInfo.getInfo()) {}
+
+ void anchor() override;
public:
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+
/// \brief Returns the source location of the 'using' keyword.
SourceLocation getUsingLoc() const { return UsingLocation; }
@@ -3478,9 +3574,6 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == UnresolvedUsingValue; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
};
/// \brief Represents a dependent using declaration which was marked with
@@ -3497,7 +3590,7 @@ public:
class UnresolvedUsingTypenameDecl
: public TypeDecl,
public Mergeable<UnresolvedUsingTypenameDecl> {
- void anchor() override;
+ friend class ASTDeclReader;
/// \brief The source location of the 'typename' keyword
SourceLocation TypenameLocation;
@@ -3517,9 +3610,9 @@ class UnresolvedUsingTypenameDecl
: TypeDecl(UnresolvedUsingTypename, DC, TargetNameLoc, TargetName,
UsingLoc),
TypenameLocation(TypenameLoc), EllipsisLoc(EllipsisLoc),
- QualifierLoc(QualifierLoc) { }
+ QualifierLoc(QualifierLoc) {}
- friend class ASTDeclReader;
+ void anchor() override;
public:
/// \brief Returns the source location of the 'using' keyword.
@@ -3574,7 +3667,6 @@ public:
/// \brief Represents a C++11 static_assert declaration.
class StaticAssertDecl : public Decl {
- virtual void anchor();
llvm::PointerIntPair<Expr *, 1, bool> AssertExprAndFailed;
StringLiteral *Message;
SourceLocation RParenLoc;
@@ -3582,11 +3674,15 @@ class StaticAssertDecl : public Decl {
StaticAssertDecl(DeclContext *DC, SourceLocation StaticAssertLoc,
Expr *AssertExpr, StringLiteral *Message,
SourceLocation RParenLoc, bool Failed)
- : Decl(StaticAssert, DC, StaticAssertLoc),
- AssertExprAndFailed(AssertExpr, Failed), Message(Message),
- RParenLoc(RParenLoc) { }
+ : Decl(StaticAssert, DC, StaticAssertLoc),
+ AssertExprAndFailed(AssertExpr, Failed), Message(Message),
+ RParenLoc(RParenLoc) {}
+
+ virtual void anchor();
public:
+ friend class ASTDeclReader;
+
static StaticAssertDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation StaticAssertLoc,
Expr *AssertExpr, StringLiteral *Message,
@@ -3609,8 +3705,6 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == StaticAssert; }
-
- friend class ASTDeclReader;
};
/// A binding in a decomposition declaration. For instance, given:
@@ -3622,18 +3716,20 @@ public:
/// x[0], x[1], and x[2] respectively, where x is the implicit
/// DecompositionDecl of type 'int (&)[3]'.
class BindingDecl : public ValueDecl {
- void anchor() override;
-
/// The binding represented by this declaration. References to this
/// declaration are effectively equivalent to this expression (except
/// that it is only evaluated once at the point of declaration of the
/// binding).
- Expr *Binding;
+ Expr *Binding = nullptr;
BindingDecl(DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id)
- : ValueDecl(Decl::Binding, DC, IdLoc, Id, QualType()), Binding(nullptr) {}
+ : ValueDecl(Decl::Binding, DC, IdLoc, Id, QualType()) {}
+
+ void anchor() override;
public:
+ friend class ASTDeclReader;
+
static BindingDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation IdLoc, IdentifierInfo *Id);
static BindingDecl *CreateDeserialized(ASTContext &C, unsigned ID);
@@ -3657,8 +3753,6 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == Decl::Binding; }
-
- friend class ASTDeclReader;
};
/// A decomposition declaration. For instance, given:
@@ -3672,8 +3766,6 @@ public:
class DecompositionDecl final
: public VarDecl,
private llvm::TrailingObjects<DecompositionDecl, BindingDecl *> {
- void anchor() override;
-
/// The number of BindingDecl*s following this object.
unsigned NumBindings;
@@ -3688,7 +3780,12 @@ class DecompositionDecl final
getTrailingObjects<BindingDecl *>());
}
+ void anchor() override;
+
public:
+ friend class ASTDeclReader;
+ friend TrailingObjects;
+
static DecompositionDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc,
SourceLocation LSquareLoc,
@@ -3706,9 +3803,6 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == Decomposition; }
-
- friend TrailingObjects;
- friend class ASTDeclReader;
};
/// An instance of this class represents the declaration of a property
@@ -3748,6 +3842,8 @@ class MSPropertyDecl : public DeclaratorDecl {
GetterId(Getter), SetterId(Setter) {}
public:
+ friend class ASTDeclReader;
+
static MSPropertyDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, DeclarationName N, QualType T,
TypeSourceInfo *TInfo, SourceLocation StartL,
@@ -3760,8 +3856,6 @@ public:
IdentifierInfo* getGetterId() const { return GetterId; }
bool hasSetter() const { return SetterId != nullptr; }
IdentifierInfo* getSetterId() const { return SetterId; }
-
- friend class ASTDeclReader;
};
/// Insertion operator for diagnostics. This allows sending an AccessSpecifier
@@ -3772,6 +3866,6 @@ const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
const PartialDiagnostic &operator<<(const PartialDiagnostic &DB,
AccessSpecifier AS);
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_AST_DECLCXX_H
diff --git a/include/clang/AST/DeclContextInternals.h b/include/clang/AST/DeclContextInternals.h
index eb86526e8eca..6545f70f70b5 100644
--- a/include/clang/AST/DeclContextInternals.h
+++ b/include/clang/AST/DeclContextInternals.h
@@ -1,4 +1,4 @@
-//===-- DeclContextInternals.h - DeclContext Representation -----*- C++ -*-===//
+//===- DeclContextInternals.h - DeclContext Representation ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,10 +11,12 @@
// of DeclContext.
//
//===----------------------------------------------------------------------===//
+
#ifndef LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H
#define LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H
#include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclarationName.h"
#include "llvm/ADT/DenseMap.h"
@@ -22,6 +24,7 @@
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallVector.h"
#include <algorithm>
+#include <cassert>
namespace clang {
@@ -30,21 +33,20 @@ class DependentDiagnostic;
/// \brief An array of decls optimized for the common case of only containing
/// one entry.
struct StoredDeclsList {
-
/// \brief When in vector form, this is what the Data pointer points to.
- typedef SmallVector<NamedDecl *, 4> DeclsTy;
+ using DeclsTy = SmallVector<NamedDecl *, 4>;
/// \brief A collection of declarations, with a flag to indicate if we have
/// further external declarations.
- typedef llvm::PointerIntPair<DeclsTy *, 1, bool> DeclsAndHasExternalTy;
+ using DeclsAndHasExternalTy = llvm::PointerIntPair<DeclsTy *, 1, bool>;
/// \brief The stored data, which will be either a pointer to a NamedDecl,
/// or a pointer to a vector with a flag to indicate if there are further
/// external declarations.
- llvm::PointerUnion<NamedDecl*, DeclsAndHasExternalTy> Data;
+ llvm::PointerUnion<NamedDecl *, DeclsAndHasExternalTy> Data;
public:
- StoredDeclsList() {}
+ StoredDeclsList() = default;
StoredDeclsList(StoredDeclsList &&RHS) : Data(RHS.Data) {
RHS.Data = (NamedDecl *)nullptr;
@@ -186,7 +188,6 @@ public:
/// AddSubsequentDecl - This is called on the second and later decl when it is
/// not a redeclaration to merge it into the appropriate place in our list.
- ///
void AddSubsequentDecl(NamedDecl *D) {
assert(!isNull() && "don't AddSubsequentDecl when we have no decls");
@@ -237,28 +238,28 @@ public:
};
class StoredDeclsMap
- : public llvm::SmallDenseMap<DeclarationName, StoredDeclsList, 4> {
-
+ : public llvm::SmallDenseMap<DeclarationName, StoredDeclsList, 4> {
public:
static void DestroyAll(StoredDeclsMap *Map, bool Dependent);
private:
friend class ASTContext; // walks the chain deleting these
friend class DeclContext;
+
llvm::PointerIntPair<StoredDeclsMap*, 1> Previous;
};
class DependentStoredDeclsMap : public StoredDeclsMap {
public:
- DependentStoredDeclsMap() : FirstDiagnostic(nullptr) {}
+ DependentStoredDeclsMap() = default;
private:
- friend class DependentDiagnostic;
friend class DeclContext; // iterates over diagnostics
+ friend class DependentDiagnostic;
- DependentDiagnostic *FirstDiagnostic;
+ DependentDiagnostic *FirstDiagnostic = nullptr;
};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H
diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h
index 172c46a44ac1..5d1c6b86fe11 100644
--- a/include/clang/AST/DeclFriend.h
+++ b/include/clang/AST/DeclFriend.h
@@ -1,4 +1,4 @@
-//===-- DeclFriend.h - Classes for C++ friend declarations -*- C++ -*------===//
+//===- DeclFriend.h - Classes for C++ friend declarations -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,16 +15,30 @@
#ifndef LLVM_CLANG_AST_DECLFRIEND_H
#define LLVM_CLANG_AST_DECLFRIEND_H
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/ExternalASTSource.h"
#include "clang/AST/TypeLoc.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/TrailingObjects.h"
+#include <cassert>
+#include <iterator>
namespace clang {
+class ASTContext;
+
/// FriendDecl - Represents the declaration of a friend entity,
/// which can be a function, a type, or a templated function or type.
-// For example:
+/// For example:
///
/// @code
/// template <typename T> class A {
@@ -41,10 +55,14 @@ class FriendDecl final
: public Decl,
private llvm::TrailingObjects<FriendDecl, TemplateParameterList *> {
virtual void anchor();
+
public:
- typedef llvm::PointerUnion<NamedDecl*,TypeSourceInfo*> FriendUnion;
+ using FriendUnion = llvm::PointerUnion<NamedDecl *, TypeSourceInfo *>;
private:
+ friend class CXXRecordDecl;
+ friend class CXXRecordDecl::friend_iterator;
+
// The declaration that's a friend of this class.
FriendUnion Friend;
@@ -64,35 +82,33 @@ private:
// template <class T> friend class A<T>::B;
unsigned NumTPLists : 31;
- friend class CXXRecordDecl::friend_iterator;
- friend class CXXRecordDecl;
-
FriendDecl(DeclContext *DC, SourceLocation L, FriendUnion Friend,
SourceLocation FriendL,
- ArrayRef<TemplateParameterList*> FriendTypeTPLists)
- : Decl(Decl::Friend, DC, L),
- Friend(Friend),
- NextFriend(),
- FriendLoc(FriendL),
- UnsupportedFriend(false),
- NumTPLists(FriendTypeTPLists.size()) {
+ ArrayRef<TemplateParameterList *> FriendTypeTPLists)
+ : Decl(Decl::Friend, DC, L), Friend(Friend), FriendLoc(FriendL),
+ UnsupportedFriend(false), NumTPLists(FriendTypeTPLists.size()) {
for (unsigned i = 0; i < NumTPLists; ++i)
getTrailingObjects<TemplateParameterList *>()[i] = FriendTypeTPLists[i];
}
FriendDecl(EmptyShell Empty, unsigned NumFriendTypeTPLists)
- : Decl(Decl::Friend, Empty), NextFriend(),
- UnsupportedFriend(false),
- NumTPLists(NumFriendTypeTPLists) { }
+ : Decl(Decl::Friend, Empty), UnsupportedFriend(false),
+ NumTPLists(NumFriendTypeTPLists) {}
FriendDecl *getNextFriend() {
if (!NextFriend.isOffset())
return cast_or_null<FriendDecl>(NextFriend.get(nullptr));
return getNextFriendSlowCase();
}
+
FriendDecl *getNextFriendSlowCase();
public:
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+ friend class ASTNodeImporter;
+ friend TrailingObjects;
+
static FriendDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, FriendUnion Friend_,
SourceLocation FriendL,
@@ -108,9 +124,11 @@ public:
TypeSourceInfo *getFriendType() const {
return Friend.dyn_cast<TypeSourceInfo*>();
}
+
unsigned getFriendTypeNumTemplateParameterLists() const {
return NumTPLists;
}
+
TemplateParameterList *getFriendTypeTemplateParameterList(unsigned N) const {
assert(N < NumTPLists);
return getTrailingObjects<TemplateParameterList *>()[N];
@@ -119,7 +137,7 @@ public:
/// If this friend declaration doesn't name a type, return the inner
/// declaration.
NamedDecl *getFriendDecl() const {
- return Friend.dyn_cast<NamedDecl*>();
+ return Friend.dyn_cast<NamedDecl *>();
}
/// Retrieves the location of the 'friend' keyword.
@@ -164,27 +182,24 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == Decl::Friend; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
- friend class ASTNodeImporter;
- friend TrailingObjects;
};
/// An iterator over the friend declarations of a class.
class CXXRecordDecl::friend_iterator {
+ friend class CXXRecordDecl;
+
FriendDecl *Ptr;
- friend class CXXRecordDecl;
explicit friend_iterator(FriendDecl *Ptr) : Ptr(Ptr) {}
+
public:
- friend_iterator() {}
+ friend_iterator() = default;
- typedef FriendDecl *value_type;
- typedef FriendDecl *reference;
- typedef FriendDecl *pointer;
- typedef int difference_type;
- typedef std::forward_iterator_tag iterator_category;
+ using value_type = FriendDecl *;
+ using reference = FriendDecl *;
+ using pointer = FriendDecl *;
+ using difference_type = int;
+ using iterator_category = std::forward_iterator_tag;
reference operator*() const { return Ptr; }
@@ -240,6 +255,6 @@ inline void CXXRecordDecl::pushFriendDecl(FriendDecl *FD) {
data().FirstFriend = FD;
}
-}
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_AST_DECLFRIEND_H
diff --git a/include/clang/AST/DeclGroup.h b/include/clang/AST/DeclGroup.h
index 6353b26f7bf5..6d5aaadf529c 100644
--- a/include/clang/AST/DeclGroup.h
+++ b/include/clang/AST/DeclGroup.h
@@ -1,4 +1,4 @@
-//===--- DeclGroup.h - Classes for representing groups of Decls -*- C++ -*-===//
+//===- DeclGroup.h - Classes for representing groups of Decls ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,26 +14,26 @@
#ifndef LLVM_CLANG_AST_DECLGROUP_H
#define LLVM_CLANG_AST_DECLGROUP_H
-#include "llvm/Support/DataTypes.h"
#include "llvm/Support/TrailingObjects.h"
#include <cassert>
+#include <cstdint>
namespace clang {
class ASTContext;
class Decl;
-class DeclGroup;
-class DeclGroupIterator;
class DeclGroup final : private llvm::TrailingObjects<DeclGroup, Decl *> {
// FIXME: Include a TypeSpecifier object.
- unsigned NumDecls;
+ unsigned NumDecls = 0;
private:
- DeclGroup() : NumDecls(0) {}
+ DeclGroup() = default;
DeclGroup(unsigned numdecls, Decl** decls);
public:
+ friend TrailingObjects;
+
static DeclGroup *Create(ASTContext &C, Decl **Decls, unsigned NumDecls);
unsigned size() const { return NumDecls; }
@@ -47,23 +47,21 @@ public:
assert (i < NumDecls && "Out-of-bounds access.");
return getTrailingObjects<Decl *>()[i];
}
-
- friend TrailingObjects;
};
class DeclGroupRef {
// Note this is not a PointerIntPair because we need the address of the
// non-group case to be valid as a Decl** for iteration.
enum Kind { SingleDeclKind=0x0, DeclGroupKind=0x1, Mask=0x1 };
- Decl* D;
+
+ Decl* D = nullptr;
Kind getKind() const {
return (Kind) (reinterpret_cast<uintptr_t>(D) & Mask);
}
public:
- DeclGroupRef() : D(nullptr) {}
-
+ DeclGroupRef() = default;
explicit DeclGroupRef(Decl* d) : D(d) {}
explicit DeclGroupRef(DeclGroup* dg)
: D((Decl*) (reinterpret_cast<uintptr_t>(dg) | DeclGroupKind)) {}
@@ -76,8 +74,8 @@ public:
return DeclGroupRef(DeclGroup::Create(C, Decls, NumDecls));
}
- typedef Decl** iterator;
- typedef Decl* const * const_iterator;
+ using iterator = Decl **;
+ using const_iterator = Decl * const *;
bool isNull() const { return D == nullptr; }
bool isSingleDecl() const { return getKind() == SingleDeclKind; }
@@ -133,22 +131,26 @@ public:
}
};
-} // end clang namespace
+} // namespace clang
namespace llvm {
+
// DeclGroupRef is "like a pointer", implement PointerLikeTypeTraits.
template <typename T>
- class PointerLikeTypeTraits;
+ struct PointerLikeTypeTraits;
template <>
- class PointerLikeTypeTraits<clang::DeclGroupRef> {
- public:
+ struct PointerLikeTypeTraits<clang::DeclGroupRef> {
static inline void *getAsVoidPointer(clang::DeclGroupRef P) {
return P.getAsOpaquePtr();
}
+
static inline clang::DeclGroupRef getFromVoidPointer(void *P) {
return clang::DeclGroupRef::getFromOpaquePtr(P);
}
+
enum { NumLowBitsAvailable = 0 };
};
-}
-#endif
+
+} // namespace llvm
+
+#endif // LLVM_CLANG_AST_DECLGROUP_H
diff --git a/include/clang/AST/DeclLookups.h b/include/clang/AST/DeclLookups.h
index eba2266724fd..2fff05582563 100644
--- a/include/clang/AST/DeclLookups.h
+++ b/include/clang/AST/DeclLookups.h
@@ -1,4 +1,4 @@
-//===-- DeclLookups.h - Low-level interface to all names in a DC-*- C++ -*-===//
+//===- DeclLookups.h - Low-level interface to all names in a DC -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -18,6 +18,9 @@
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclContextInternals.h"
#include "clang/AST/DeclarationName.h"
+#include "clang/AST/ExternalASTSource.h"
+#include <cstddef>
+#include <iterator>
namespace clang {
@@ -25,14 +28,15 @@ namespace clang {
/// of looking up every possible name.
class DeclContext::all_lookups_iterator {
StoredDeclsMap::iterator It, End;
+
public:
- typedef lookup_result value_type;
- typedef lookup_result reference;
- typedef lookup_result pointer;
- typedef std::forward_iterator_tag iterator_category;
- typedef std::ptrdiff_t difference_type;
+ using value_type = lookup_result;
+ using reference = lookup_result;
+ using pointer = lookup_result;
+ using iterator_category = std::forward_iterator_tag;
+ using difference_type = std::ptrdiff_t;
- all_lookups_iterator() {}
+ all_lookups_iterator() = default;
all_lookups_iterator(StoredDeclsMap::iterator It,
StoredDeclsMap::iterator End)
: It(It), End(End) {}
@@ -63,6 +67,7 @@ public:
friend bool operator==(all_lookups_iterator x, all_lookups_iterator y) {
return x.It == y.It;
}
+
friend bool operator!=(all_lookups_iterator x, all_lookups_iterator y) {
return x.It != y.It;
}
@@ -110,6 +115,6 @@ DeclContext::all_lookups_iterator DeclContext::noload_lookups_end() const {
return noload_lookups().end();
}
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_AST_DECLLOOKUPS_H
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index 1cd6e004f751..cef7d935370a 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -1,4 +1,4 @@
-//===--- DeclObjC.h - Classes for representing declarations -----*- C++ -*-===//
+//===- DeclObjC.h - Classes for representing declarations -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,33 +15,59 @@
#define LLVM_CLANG_AST_DECLOBJC_H
#include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
+#include "clang/AST/ExternalASTSource.h"
+#include "clang/AST/Redeclarable.h"
#include "clang/AST/SelectorLocationsKind.h"
+#include "clang/AST/Type.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/Specifiers.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/TrailingObjects.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <iterator>
+#include <string>
+#include <utility>
namespace clang {
+
+class ASTContext;
+class CompoundStmt;
+class CXXCtorInitializer;
class Expr;
-class Stmt;
-class FunctionDecl;
-class RecordDecl;
-class ObjCIvarDecl;
-class ObjCMethodDecl;
-class ObjCProtocolDecl;
class ObjCCategoryDecl;
+class ObjCCategoryImplDecl;
+class ObjCImplementationDecl;
+class ObjCInterfaceDecl;
+class ObjCIvarDecl;
class ObjCPropertyDecl;
class ObjCPropertyImplDecl;
-class CXXCtorInitializer;
+class ObjCProtocolDecl;
+class Stmt;
class ObjCListBase {
- ObjCListBase(const ObjCListBase &) = delete;
- void operator=(const ObjCListBase &) = delete;
protected:
/// List is an array of pointers to objects that are not owned by this object.
- void **List;
- unsigned NumElts;
+ void **List = nullptr;
+ unsigned NumElts = 0;
public:
- ObjCListBase() : List(nullptr), NumElts(0) {}
+ ObjCListBase() = default;
+ ObjCListBase(const ObjCListBase &) = delete;
+ ObjCListBase &operator=(const ObjCListBase &) = delete;
+
unsigned size() const { return NumElts; }
bool empty() const { return NumElts == 0; }
@@ -49,7 +75,6 @@ protected:
void set(void *const* InList, unsigned Elts, ASTContext &Ctx);
};
-
/// ObjCList - This is a simple template class used to hold various lists of
/// decls etc, which is heavily used by the ObjC front-end. This only use case
/// this supports is setting the list all at once and then reading elements out
@@ -61,7 +86,8 @@ public:
ObjCListBase::set(reinterpret_cast<void*const*>(InList), Elts, Ctx);
}
- typedef T* const * iterator;
+ using iterator = T* const *;
+
iterator begin() const { return (iterator)List; }
iterator end() const { return (iterator)List+NumElts; }
@@ -74,14 +100,15 @@ public:
/// \brief A list of Objective-C protocols, along with the source
/// locations at which they were referenced.
class ObjCProtocolList : public ObjCList<ObjCProtocolDecl> {
- SourceLocation *Locations;
+ SourceLocation *Locations = nullptr;
using ObjCList<ObjCProtocolDecl>::set;
public:
- ObjCProtocolList() : ObjCList<ObjCProtocolDecl>(), Locations(nullptr) { }
+ ObjCProtocolList() = default;
+
+ using loc_iterator = const SourceLocation *;
- typedef const SourceLocation *loc_iterator;
loc_iterator loc_begin() const { return Locations; }
loc_iterator loc_end() const { return Locations + size(); }
@@ -89,7 +116,6 @@ public:
const SourceLocation *Locs, ASTContext &Ctx);
};
-
/// ObjCMethodDecl - Represents an instance or class method declaration.
/// ObjC methods can be declared within 4 contexts: class interfaces,
/// categories, protocols, and class implementations. While C++ member
@@ -113,6 +139,7 @@ public:
class ObjCMethodDecl : public NamedDecl, public DeclContext {
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
@@ -170,8 +197,8 @@ private:
/// \brief Array of ParmVarDecls for the formal parameters of this method
/// and optionally followed by selector locations.
- void *ParamsAndSelLocs;
- unsigned NumParams;
+ void *ParamsAndSelLocs = nullptr;
+ unsigned NumParams = 0;
/// List of attributes for this method declaration.
SourceLocation DeclEndLoc; // the location of the ';' or '{'.
@@ -181,14 +208,35 @@ private:
/// SelfDecl - Decl for the implicit self parameter. This is lazily
/// constructed by createImplicitParams.
- ImplicitParamDecl *SelfDecl;
+ ImplicitParamDecl *SelfDecl = nullptr;
+
/// CmdDecl - Decl for the implicit _cmd parameter. This is lazily
/// constructed by createImplicitParams.
- ImplicitParamDecl *CmdDecl;
+ ImplicitParamDecl *CmdDecl = nullptr;
+
+ ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc,
+ Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo,
+ DeclContext *contextDecl, bool isInstance = true,
+ 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);
+ }
SelectorLocationsKind getSelLocsKind() const {
return (SelectorLocationsKind)SelLocsKind;
}
+
bool hasStandardSelLocs() const {
return getSelLocsKind() != SelLoc_NonStandard;
}
@@ -223,33 +271,15 @@ private:
ArrayRef<ParmVarDecl*> Params,
ArrayRef<SourceLocation> SelLocs);
- ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc,
- Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo,
- DeclContext *contextDecl, bool isInstance = true,
- 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), ParamsAndSelLocs(nullptr),
- NumParams(0), DeclEndLoc(endLoc), Body(), SelfDecl(nullptr),
- CmdDecl(nullptr) {
- setImplicit(isImplicitlyDeclared);
- }
-
/// \brief A definition will return its interface declaration.
/// An interface declaration will return its definition.
/// Otherwise it will return itself.
ObjCMethodDecl *getNextRedeclarationImpl() override;
public:
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+
static ObjCMethodDecl *
Create(ASTContext &C, SourceLocation beginLoc, SourceLocation endLoc,
Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo,
@@ -299,6 +329,7 @@ public:
return getLocStart();
return getSelectorLoc(0);
}
+
SourceLocation getSelectorLoc(unsigned Index) const {
assert(Index < getNumSelectorLocs() && "Index out of range!");
if (hasStandardSelLocs())
@@ -346,17 +377,20 @@ public:
// Iterator access to formal parameters.
unsigned param_size() const { return NumParams; }
- typedef const ParmVarDecl *const *param_const_iterator;
- typedef ParmVarDecl *const *param_iterator;
- typedef llvm::iterator_range<param_iterator> param_range;
- typedef llvm::iterator_range<param_const_iterator> param_const_range;
+
+ using param_const_iterator = const ParmVarDecl *const *;
+ using param_iterator = ParmVarDecl *const *;
+ using param_range = llvm::iterator_range<param_iterator>;
+ using param_const_range = llvm::iterator_range<param_const_iterator>;
param_const_iterator param_begin() const {
return param_const_iterator(getParams());
}
+
param_const_iterator param_end() const {
return param_const_iterator(getParams() + NumParams);
}
+
param_iterator param_begin() { return param_iterator(getParams()); }
param_iterator param_end() { return param_iterator(getParams() + NumParams); }
@@ -384,12 +418,14 @@ public:
struct GetTypeFn {
QualType operator()(const ParmVarDecl *PD) const { return PD->getType(); }
};
- typedef llvm::mapped_iterator<param_const_iterator, GetTypeFn>
- param_type_iterator;
+
+ using param_type_iterator =
+ llvm::mapped_iterator<param_const_iterator, GetTypeFn>;
param_type_iterator param_type_begin() const {
return llvm::map_iterator(param_begin(), GetTypeFn());
}
+
param_type_iterator param_type_end() const {
return llvm::map_iterator(param_end(), GetTypeFn());
}
@@ -462,9 +498,11 @@ public:
void setDeclImplementation(ImplementationControl ic) {
DeclImplementation = ic;
}
+
ImplementationControl getImplementationControl() const {
return ImplementationControl(DeclImplementation);
}
+
bool isOptional() const {
return getImplementationControl() == Optional;
}
@@ -499,24 +537,25 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == ObjCMethod; }
+
static DeclContext *castToDeclContext(const ObjCMethodDecl *D) {
return static_cast<DeclContext *>(const_cast<ObjCMethodDecl*>(D));
}
+
static ObjCMethodDecl *castFromDeclContext(const DeclContext *DC) {
return static_cast<ObjCMethodDecl *>(const_cast<DeclContext*>(DC));
}
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
};
/// Describes the variance of a given generic parameter.
enum class ObjCTypeParamVariance : uint8_t {
/// The parameter is invariant: must match exactly.
Invariant,
+
/// The parameter is covariant, e.g., X<T> is a subtype of X<U> when
/// the type parameter is covariant and T is a subtype of U.
Covariant,
+
/// The parameter is contravariant, e.g., X<T> is a subtype of X<U>
/// when the type parameter is covariant and U is a subtype of T.
Contravariant,
@@ -535,8 +574,6 @@ enum class ObjCTypeParamVariance : uint8_t {
///
/// Objective-C type parameters are typedef-names in the grammar,
class ObjCTypeParamDecl : public TypedefNameDecl {
- void anchor() override;
-
/// Index of this type parameter in the type parameter list.
unsigned Index : 14;
@@ -555,12 +592,17 @@ class ObjCTypeParamDecl : public TypedefNameDecl {
unsigned index,
SourceLocation nameLoc, IdentifierInfo *name,
SourceLocation colonLoc, TypeSourceInfo *boundInfo)
- : TypedefNameDecl(ObjCTypeParam, ctx, dc, nameLoc, nameLoc, name,
- boundInfo),
- Index(index), Variance(static_cast<unsigned>(variance)),
- VarianceLoc(varianceLoc), ColonLoc(colonLoc) { }
+ : TypedefNameDecl(ObjCTypeParam, ctx, dc, nameLoc, nameLoc, name,
+ boundInfo),
+ Index(index), Variance(static_cast<unsigned>(variance)),
+ VarianceLoc(varianceLoc), ColonLoc(colonLoc) {}
+
+ void anchor() override;
public:
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+
static ObjCTypeParamDecl *Create(ASTContext &ctx, DeclContext *dc,
ObjCTypeParamVariance variance,
SourceLocation varianceLoc,
@@ -600,9 +642,6 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == ObjCTypeParam; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
};
/// Stores a list of Objective-C type parameters for a parameterized class
@@ -636,6 +675,8 @@ class ObjCTypeParamList final
SourceLocation rAngleLoc);
public:
+ friend TrailingObjects;
+
/// Create a new Objective-C type parameter list.
static ObjCTypeParamList *create(ASTContext &ctx,
SourceLocation lAngleLoc,
@@ -643,7 +684,7 @@ public:
SourceLocation rAngleLoc);
/// Iterate through the type parameters in the list.
- typedef ObjCTypeParamDecl **iterator;
+ using iterator = ObjCTypeParamDecl **;
iterator begin() { return getTrailingObjects<ObjCTypeParamDecl *>(); }
@@ -653,7 +694,7 @@ public:
unsigned size() const { return NumParams; }
// Iterate through the type parameters in the list.
- typedef ObjCTypeParamDecl * const *const_iterator;
+ using const_iterator = ObjCTypeParamDecl * const *;
const_iterator begin() const {
return getTrailingObjects<ObjCTypeParamDecl *>();
@@ -676,9 +717,11 @@ public:
SourceLocation getLAngleLoc() const {
return SourceLocation::getFromRawEncoding(Brackets.Begin);
}
+
SourceLocation getRAngleLoc() const {
return SourceLocation::getFromRawEncoding(Brackets.End);
}
+
SourceRange getSourceRange() const {
return SourceRange(getLAngleLoc(), getRAngleLoc());
}
@@ -686,7 +729,6 @@ public:
/// Gather the default set of type arguments to be substituted for
/// these type parameters when dealing with an unspecialized type.
void gatherDefaultTypeArgs(SmallVectorImpl<QualType> &typeArgs) const;
- friend TrailingObjects;
};
enum class ObjCPropertyQueryKind : uint8_t {
@@ -703,6 +745,7 @@ enum class ObjCPropertyQueryKind : uint8_t {
/// \endcode
class ObjCPropertyDecl : public NamedDecl {
void anchor() override;
+
public:
enum PropertyAttributeKind {
OBJC_PR_noattr = 0x00,
@@ -733,24 +776,42 @@ public:
enum SetterKind { Assign, Retain, Copy, Weak };
enum PropertyControl { None, Required, Optional };
+
private:
- SourceLocation AtLoc; // location of \@property
- SourceLocation LParenLoc; // location of '(' starting attribute list or null.
+ // location of \@property
+ SourceLocation AtLoc;
+
+ // location of '(' starting attribute list or null.
+ SourceLocation LParenLoc;
+
QualType DeclType;
TypeSourceInfo *DeclTypeSourceInfo;
unsigned PropertyAttributes : NumPropertyAttrsBits;
unsigned PropertyAttributesAsWritten : NumPropertyAttrsBits;
+
// \@required/\@optional
unsigned PropertyImplementation : 2;
- Selector GetterName; // getter name of NULL if no getter
- Selector SetterName; // setter name of NULL if no setter
- SourceLocation GetterNameLoc; // location of the getter attribute's value
- SourceLocation SetterNameLoc; // location of the setter attribute's value
+ // getter name of NULL if no getter
+ Selector GetterName;
+
+ // setter name of NULL if no setter
+ Selector SetterName;
+
+ // location of the getter attribute's value
+ SourceLocation GetterNameLoc;
+
+ // location of the setter attribute's value
+ SourceLocation SetterNameLoc;
+
+ // Declaration of getter instance method
+ ObjCMethodDecl *GetterMethodDecl = nullptr;
+
+ // Declaration of setter instance method
+ ObjCMethodDecl *SetterMethodDecl = nullptr;
- ObjCMethodDecl *GetterMethodDecl; // Declaration of getter instance method
- ObjCMethodDecl *SetterMethodDecl; // Declaration of setter instance method
- ObjCIvarDecl *PropertyIvarDecl; // Synthesize ivar for this property
+ // Synthesize ivar for this property
+ ObjCIvarDecl *PropertyIvarDecl = nullptr;
ObjCPropertyDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
SourceLocation AtLocation, SourceLocation LParenLocation,
@@ -760,11 +821,8 @@ private:
LParenLoc(LParenLocation), DeclType(T), DeclTypeSourceInfo(TSI),
PropertyAttributes(OBJC_PR_noattr),
PropertyAttributesAsWritten(OBJC_PR_noattr),
- PropertyImplementation(propControl),
- GetterName(Selector()),
- SetterName(Selector()),
- GetterMethodDecl(nullptr), SetterMethodDecl(nullptr),
- PropertyIvarDecl(nullptr) {}
+ PropertyImplementation(propControl), GetterName(Selector()),
+ SetterName(Selector()) {}
public:
static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC,
@@ -799,9 +857,11 @@ public:
PropertyAttributeKind getPropertyAttributes() const {
return PropertyAttributeKind(PropertyAttributes);
}
+
void setPropertyAttributes(PropertyAttributeKind PRVal) {
PropertyAttributes |= PRVal;
}
+
void overwritePropertyAttributes(unsigned PRVal) {
PropertyAttributes = PRVal;
}
@@ -834,10 +894,12 @@ public:
bool isInstanceProperty() const { return !isClassProperty(); }
bool isClassProperty() const { return PropertyAttributes & OBJC_PR_class; }
+
ObjCPropertyQueryKind getQueryKind() const {
return isClassProperty() ? ObjCPropertyQueryKind::OBJC_PR_query_class :
ObjCPropertyQueryKind::OBJC_PR_query_instance;
}
+
static ObjCPropertyQueryKind getQueryKind(bool isClassProperty) {
return isClassProperty ? ObjCPropertyQueryKind::OBJC_PR_query_class :
ObjCPropertyQueryKind::OBJC_PR_query_instance;
@@ -860,6 +922,7 @@ public:
Selector getGetterName() const { return GetterName; }
SourceLocation getGetterNameLoc() const { return GetterNameLoc; }
+
void setGetterName(Selector Sel, SourceLocation Loc = SourceLocation()) {
GetterName = Sel;
GetterNameLoc = Loc;
@@ -867,6 +930,7 @@ public:
Selector getSetterName() const { return SetterName; }
SourceLocation getSetterNameLoc() const { return SetterNameLoc; }
+
void setSetterName(Selector Sel, SourceLocation Loc = SourceLocation()) {
SetterName = Sel;
SetterNameLoc = Loc;
@@ -882,9 +946,11 @@ public:
void setPropertyImplementation(PropertyControl pc) {
PropertyImplementation = pc;
}
+
PropertyControl getPropertyImplementation() const {
return PropertyControl(PropertyImplementation);
}
+
bool isOptional() const {
return getPropertyImplementation() == PropertyControl::Optional;
}
@@ -892,6 +958,7 @@ public:
void setPropertyIvarDecl(ObjCIvarDecl *Ivar) {
PropertyIvarDecl = Ivar;
}
+
ObjCIvarDecl *getPropertyIvarDecl() const {
return PropertyIvarDecl;
}
@@ -917,104 +984,116 @@ public:
/// ObjCProtocolDecl, and ObjCImplDecl.
///
class ObjCContainerDecl : public NamedDecl, public DeclContext {
- void anchor() override;
-
SourceLocation AtStart;
// 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.
SourceRange AtEnd;
-public:
+ void anchor() override;
+
+public:
ObjCContainerDecl(Kind DK, DeclContext *DC,
IdentifierInfo *Id, SourceLocation nameLoc,
SourceLocation atStartLoc)
- : NamedDecl(DK, DC, nameLoc, Id), DeclContext(DK), AtStart(atStartLoc) {}
+ : NamedDecl(DK, DC, nameLoc, Id), DeclContext(DK), AtStart(atStartLoc) {}
// Iterator access to instance/class properties.
- typedef specific_decl_iterator<ObjCPropertyDecl> prop_iterator;
- typedef llvm::iterator_range<specific_decl_iterator<ObjCPropertyDecl>>
- prop_range;
+ using prop_iterator = specific_decl_iterator<ObjCPropertyDecl>;
+ using prop_range =
+ llvm::iterator_range<specific_decl_iterator<ObjCPropertyDecl>>;
prop_range properties() const { return prop_range(prop_begin(), prop_end()); }
+
prop_iterator prop_begin() const {
return prop_iterator(decls_begin());
}
+
prop_iterator prop_end() const {
return prop_iterator(decls_end());
}
- typedef filtered_decl_iterator<ObjCPropertyDecl,
- &ObjCPropertyDecl::isInstanceProperty>
- instprop_iterator;
- typedef llvm::iterator_range<instprop_iterator> instprop_range;
+ using instprop_iterator =
+ filtered_decl_iterator<ObjCPropertyDecl,
+ &ObjCPropertyDecl::isInstanceProperty>;
+ using instprop_range = llvm::iterator_range<instprop_iterator>;
instprop_range instance_properties() const {
return instprop_range(instprop_begin(), instprop_end());
}
+
instprop_iterator instprop_begin() const {
return instprop_iterator(decls_begin());
}
+
instprop_iterator instprop_end() const {
return instprop_iterator(decls_end());
}
- typedef filtered_decl_iterator<ObjCPropertyDecl,
- &ObjCPropertyDecl::isClassProperty>
- classprop_iterator;
- typedef llvm::iterator_range<classprop_iterator> classprop_range;
+ using classprop_iterator =
+ filtered_decl_iterator<ObjCPropertyDecl,
+ &ObjCPropertyDecl::isClassProperty>;
+ using classprop_range = llvm::iterator_range<classprop_iterator>;
classprop_range class_properties() const {
return classprop_range(classprop_begin(), classprop_end());
}
+
classprop_iterator classprop_begin() const {
return classprop_iterator(decls_begin());
}
+
classprop_iterator classprop_end() const {
return classprop_iterator(decls_end());
}
// Iterator access to instance/class methods.
- typedef specific_decl_iterator<ObjCMethodDecl> method_iterator;
- typedef llvm::iterator_range<specific_decl_iterator<ObjCMethodDecl>>
- method_range;
+ using method_iterator = specific_decl_iterator<ObjCMethodDecl>;
+ using method_range =
+ llvm::iterator_range<specific_decl_iterator<ObjCMethodDecl>>;
method_range methods() const {
return method_range(meth_begin(), meth_end());
}
+
method_iterator meth_begin() const {
return method_iterator(decls_begin());
}
+
method_iterator meth_end() const {
return method_iterator(decls_end());
}
- typedef filtered_decl_iterator<ObjCMethodDecl,
- &ObjCMethodDecl::isInstanceMethod>
- instmeth_iterator;
- typedef llvm::iterator_range<instmeth_iterator> instmeth_range;
+ using instmeth_iterator =
+ filtered_decl_iterator<ObjCMethodDecl,
+ &ObjCMethodDecl::isInstanceMethod>;
+ using instmeth_range = llvm::iterator_range<instmeth_iterator>;
instmeth_range instance_methods() const {
return instmeth_range(instmeth_begin(), instmeth_end());
}
+
instmeth_iterator instmeth_begin() const {
return instmeth_iterator(decls_begin());
}
+
instmeth_iterator instmeth_end() const {
return instmeth_iterator(decls_end());
}
- typedef filtered_decl_iterator<ObjCMethodDecl,
- &ObjCMethodDecl::isClassMethod>
- classmeth_iterator;
- typedef llvm::iterator_range<classmeth_iterator> classmeth_range;
+ using classmeth_iterator =
+ filtered_decl_iterator<ObjCMethodDecl,
+ &ObjCMethodDecl::isClassMethod>;
+ using classmeth_range = llvm::iterator_range<classmeth_iterator>;
classmeth_range class_methods() const {
return classmeth_range(classmeth_begin(), classmeth_end());
}
+
classmeth_iterator classmeth_begin() const {
return classmeth_iterator(decls_begin());
}
+
classmeth_iterator classmeth_end() const {
return classmeth_iterator(decls_end());
}
@@ -1022,13 +1101,16 @@ public:
// Get the local instance/class method declared in this interface.
ObjCMethodDecl *getMethod(Selector Sel, bool isInstance,
bool AllowHidden = false) const;
+
ObjCMethodDecl *getInstanceMethod(Selector Sel,
bool AllowHidden = false) const {
return getMethod(Sel, true/*isInstance*/, AllowHidden);
}
+
ObjCMethodDecl *getClassMethod(Selector Sel, bool AllowHidden = false) const {
return getMethod(Sel, false/*isInstance*/, AllowHidden);
}
+
bool HasUserDeclaredSetterMethod(const ObjCPropertyDecl *P) const;
ObjCIvarDecl *getIvarDecl(IdentifierInfo *Id) const;
@@ -1036,13 +1118,11 @@ public:
FindPropertyDeclaration(const IdentifierInfo *PropertyId,
ObjCPropertyQueryKind QueryKind) const;
- typedef llvm::DenseMap<std::pair<IdentifierInfo*,
- unsigned/*isClassProperty*/>,
- ObjCPropertyDecl*> PropertyMap;
-
- typedef llvm::SmallDenseSet<const ObjCProtocolDecl *, 8> ProtocolPropertySet;
-
- typedef llvm::SmallVector<ObjCPropertyDecl*, 8> PropertyDeclOrder;
+ using PropertyMap =
+ llvm::DenseMap<std::pair<IdentifierInfo *, unsigned/*isClassProperty*/>,
+ ObjCPropertyDecl *>;
+ using ProtocolPropertySet = llvm::SmallDenseSet<const ObjCProtocolDecl *, 8>;
+ using PropertyDeclOrder = llvm::SmallVector<ObjCPropertyDecl *, 8>;
/// This routine collects list of properties to be implemented in the class.
/// This includes, class's and its conforming protocols' properties.
@@ -1057,6 +1137,7 @@ public:
SourceRange getAtEndRange() const {
return AtEnd;
}
+
void setAtEndRange(SourceRange atEnd) {
AtEnd = atEnd;
}
@@ -1067,6 +1148,7 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+
static bool classofKind(Kind K) {
return K >= firstObjCContainer &&
K <= lastObjCContainer;
@@ -1075,6 +1157,7 @@ public:
static DeclContext *castToDeclContext(const ObjCContainerDecl *D) {
return static_cast<DeclContext *>(const_cast<ObjCContainerDecl*>(D));
}
+
static ObjCContainerDecl *castFromDeclContext(const DeclContext *DC) {
return static_cast<ObjCContainerDecl *>(const_cast<DeclContext*>(DC));
}
@@ -1107,20 +1190,19 @@ public:
///
class ObjCInterfaceDecl : public ObjCContainerDecl
, public Redeclarable<ObjCInterfaceDecl> {
- void anchor() override;
+ friend class ASTContext;
/// TypeForDecl - This indicates the Type object that represents this
/// TypeDecl. It is a cache maintained by ASTContext::getObjCInterfaceType
- mutable const Type *TypeForDecl;
- friend class ASTContext;
+ mutable const Type *TypeForDecl = nullptr;
struct DefinitionData {
/// \brief The definition of this class, for quick access from any
/// declaration.
- ObjCInterfaceDecl *Definition;
+ ObjCInterfaceDecl *Definition = nullptr;
/// When non-null, this is always an ObjCObjectType.
- TypeSourceInfo *SuperClassTInfo;
+ TypeSourceInfo *SuperClassTInfo = nullptr;
/// Protocols referenced in the \@interface declaration
ObjCProtocolList ReferencedProtocols;
@@ -1133,11 +1215,11 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
/// Categories are stored as a linked list in the AST, since the categories
/// and class extensions come long after the initial interface declaration,
/// and we avoid dynamically-resized arrays in the AST wherever possible.
- ObjCCategoryDecl *CategoryList;
+ ObjCCategoryDecl *CategoryList = nullptr;
/// IvarList - List of all ivars defined by this class; including class
/// extensions and implementation. This list is built lazily.
- ObjCIvarDecl *IvarList;
+ ObjCIvarDecl *IvarList = nullptr;
/// \brief Indicates that the contents of this Objective-C class will be
/// completed by the external AST source when required.
@@ -1155,11 +1237,14 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
/// We didn't calculate whether the designated initializers should be
/// inherited or not.
IDI_Unknown = 0,
+
/// Designated initializers are inherited for the super class.
IDI_Inherited = 1,
+
/// The class does not inherit designated initializers.
IDI_NotInherited = 2
};
+
/// One of the \c InheritedDesignatedInitializersState enumeratos.
mutable unsigned InheritedDesignatedInitializers : 2;
@@ -1168,22 +1253,14 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
/// identifier,
SourceLocation EndLoc;
- DefinitionData() : Definition(), SuperClassTInfo(), CategoryList(), IvarList(),
- ExternallyCompleted(),
- IvarListMissingImplementation(true),
- HasDesignatedInitializers(),
- InheritedDesignatedInitializers(IDI_Unknown) { }
+ DefinitionData()
+ : ExternallyCompleted(false), IvarListMissingImplementation(true),
+ HasDesignatedInitializers(false),
+ InheritedDesignatedInitializers(IDI_Unknown) {}
};
- ObjCInterfaceDecl(const ASTContext &C, DeclContext *DC, SourceLocation AtLoc,
- IdentifierInfo *Id, ObjCTypeParamList *typeParamList,
- SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl,
- bool IsInternal);
-
- void LoadExternalDefinition() const;
-
/// The type parameters associated with this class, if any.
- ObjCTypeParamList *TypeParamList;
+ ObjCTypeParamList *TypeParamList = nullptr;
/// \brief Contains a pointer to the data associated with this class,
/// which will be NULL if this class has not yet been defined.
@@ -1192,6 +1269,15 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
/// declarations. It will be set unless modules are enabled.
llvm::PointerIntPair<DefinitionData *, 1, bool> Data;
+ ObjCInterfaceDecl(const ASTContext &C, DeclContext *DC, SourceLocation AtLoc,
+ IdentifierInfo *Id, ObjCTypeParamList *typeParamList,
+ SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl,
+ bool IsInternal);
+
+ void anchor() override;
+
+ void LoadExternalDefinition() const;
+
DefinitionData &data() const {
assert(Data.getPointer() && "Declaration has no definition!");
return *Data.getPointer();
@@ -1200,13 +1286,16 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
/// \brief Allocate the definition data for this class.
void allocateDefinitionData();
- typedef Redeclarable<ObjCInterfaceDecl> redeclarable_base;
+ using redeclarable_base = Redeclarable<ObjCInterfaceDecl>;
+
ObjCInterfaceDecl *getNextRedeclarationImpl() override {
return getNextRedeclaration();
}
+
ObjCInterfaceDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
}
+
ObjCInterfaceDecl *getMostRecentDeclImpl() override {
return getMostRecentDecl();
}
@@ -1284,17 +1373,19 @@ public:
// Get the local instance/class method declared in a category.
ObjCMethodDecl *getCategoryInstanceMethod(Selector Sel) const;
ObjCMethodDecl *getCategoryClassMethod(Selector Sel) const;
+
ObjCMethodDecl *getCategoryMethod(Selector Sel, bool isInstance) const {
return isInstance ? getCategoryInstanceMethod(Sel)
: getCategoryClassMethod(Sel);
}
- typedef ObjCProtocolList::iterator protocol_iterator;
- typedef llvm::iterator_range<protocol_iterator> protocol_range;
+ using protocol_iterator = ObjCProtocolList::iterator;
+ using protocol_range = llvm::iterator_range<protocol_iterator>;
protocol_range protocols() const {
return protocol_range(protocol_begin(), protocol_end());
}
+
protocol_iterator protocol_begin() const {
// FIXME: Should make sure no callers ever do this.
if (!hasDefinition())
@@ -1305,6 +1396,7 @@ public:
return data().ReferencedProtocols.begin();
}
+
protocol_iterator protocol_end() const {
// FIXME: Should make sure no callers ever do this.
if (!hasDefinition())
@@ -1316,12 +1408,13 @@ public:
return data().ReferencedProtocols.end();
}
- typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
- typedef llvm::iterator_range<protocol_loc_iterator> protocol_loc_range;
+ using protocol_loc_iterator = ObjCProtocolList::loc_iterator;
+ using protocol_loc_range = llvm::iterator_range<protocol_loc_iterator>;
protocol_loc_range protocol_locs() const {
return protocol_loc_range(protocol_loc_begin(), protocol_loc_end());
}
+
protocol_loc_iterator protocol_loc_begin() const {
// FIXME: Should make sure no callers ever do this.
if (!hasDefinition())
@@ -1344,13 +1437,14 @@ public:
return data().ReferencedProtocols.loc_end();
}
- typedef ObjCList<ObjCProtocolDecl>::iterator all_protocol_iterator;
- typedef llvm::iterator_range<all_protocol_iterator> all_protocol_range;
+ using all_protocol_iterator = ObjCList<ObjCProtocolDecl>::iterator;
+ using all_protocol_range = llvm::iterator_range<all_protocol_iterator>;
all_protocol_range all_referenced_protocols() const {
return all_protocol_range(all_referenced_protocol_begin(),
all_referenced_protocol_end());
}
+
all_protocol_iterator all_referenced_protocol_begin() const {
// FIXME: Should make sure no callers ever do this.
if (!hasDefinition())
@@ -1363,6 +1457,7 @@ public:
? protocol_begin()
: data().AllReferencedProtocols.begin();
}
+
all_protocol_iterator all_referenced_protocol_end() const {
// FIXME: Should make sure no callers ever do this.
if (!hasDefinition())
@@ -1376,10 +1471,11 @@ public:
: data().AllReferencedProtocols.end();
}
- typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
- typedef llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>> ivar_range;
+ using ivar_iterator = specific_decl_iterator<ObjCIvarDecl>;
+ using ivar_range = llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>>;
ivar_range ivars() const { return ivar_range(ivar_begin(), ivar_end()); }
+
ivar_iterator ivar_begin() const {
if (const ObjCInterfaceDecl *Def = getDefinition())
return ivar_iterator(Def->decls_begin());
@@ -1387,6 +1483,7 @@ public:
// FIXME: Should make sure no callers ever do this.
return ivar_iterator();
}
+
ivar_iterator ivar_end() const {
if (const ObjCInterfaceDecl *Def = getDefinition())
return ivar_iterator(Def->decls_end());
@@ -1518,21 +1615,20 @@ public:
/// and extension iterators.
template<bool (*Filter)(ObjCCategoryDecl *)>
class filtered_category_iterator {
- ObjCCategoryDecl *Current;
+ ObjCCategoryDecl *Current = nullptr;
void findAcceptableCategory();
public:
- typedef ObjCCategoryDecl * value_type;
- typedef value_type reference;
- typedef value_type pointer;
- typedef std::ptrdiff_t difference_type;
- typedef std::input_iterator_tag iterator_category;
+ using value_type = ObjCCategoryDecl *;
+ using reference = value_type;
+ using pointer = value_type;
+ using difference_type = std::ptrdiff_t;
+ using iterator_category = std::input_iterator_tag;
- filtered_category_iterator() : Current(nullptr) { }
+ filtered_category_iterator() = default;
explicit filtered_category_iterator(ObjCCategoryDecl *Current)
- : Current(Current)
- {
+ : Current(Current) {
findAcceptableCategory();
}
@@ -1567,11 +1663,11 @@ private:
public:
/// \brief Iterator that walks over the list of categories and extensions
/// that are visible, i.e., not hidden in a non-imported submodule.
- typedef filtered_category_iterator<isVisibleCategory>
- visible_categories_iterator;
+ using visible_categories_iterator =
+ filtered_category_iterator<isVisibleCategory>;
- typedef llvm::iterator_range<visible_categories_iterator>
- visible_categories_range;
+ using visible_categories_range =
+ llvm::iterator_range<visible_categories_iterator>;
visible_categories_range visible_categories() const {
return visible_categories_range(visible_categories_begin(),
@@ -1603,9 +1699,9 @@ private:
public:
/// \brief Iterator that walks over all of the known categories and
/// extensions, including those that are hidden.
- typedef filtered_category_iterator<isKnownCategory> known_categories_iterator;
- typedef llvm::iterator_range<known_categories_iterator>
- known_categories_range;
+ using known_categories_iterator = filtered_category_iterator<isKnownCategory>;
+ using known_categories_range =
+ llvm::iterator_range<known_categories_iterator>;
known_categories_range known_categories() const {
return known_categories_range(known_categories_begin(),
@@ -1637,11 +1733,11 @@ private:
public:
/// \brief Iterator that walks over all of the visible extensions, skipping
/// any that are known but hidden.
- typedef filtered_category_iterator<isVisibleExtension>
- visible_extensions_iterator;
+ using visible_extensions_iterator =
+ filtered_category_iterator<isVisibleExtension>;
- typedef llvm::iterator_range<visible_extensions_iterator>
- visible_extensions_range;
+ using visible_extensions_range =
+ llvm::iterator_range<visible_extensions_iterator>;
visible_extensions_range visible_extensions() const {
return visible_extensions_range(visible_extensions_begin(),
@@ -1671,11 +1767,15 @@ private:
static bool isKnownExtension(ObjCCategoryDecl *Cat);
public:
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+ friend class ASTReader;
+
/// \brief Iterator that walks over all of the known extensions.
- typedef filtered_category_iterator<isKnownExtension>
- known_extensions_iterator;
- typedef llvm::iterator_range<known_extensions_iterator>
- known_extensions_range;
+ using known_extensions_iterator =
+ filtered_category_iterator<isKnownExtension>;
+ using known_extensions_range =
+ llvm::iterator_range<known_extensions_iterator>;
known_extensions_range known_extensions() const {
return known_extensions_range(known_extensions_begin(),
@@ -1771,6 +1871,7 @@ public:
ObjCMethodDecl *lookupClassMethod(Selector Sel) const {
return lookupMethod(Sel, false/*isInstance*/);
}
+
ObjCInterfaceDecl *lookupInheritedClass(const IdentifierInfo *ICName);
/// \brief Lookup a method in the classes implementation hierarchy.
@@ -1819,8 +1920,9 @@ public:
bool lookupCategory,
bool RHSIsQualifiedID = false);
- typedef redeclarable_base::redecl_range redecl_range;
- typedef redeclarable_base::redecl_iterator redecl_iterator;
+ using redecl_range = redeclarable_base::redecl_range;
+ using redecl_iterator = redeclarable_base::redecl_iterator;
+
using redeclarable_base::redecls_begin;
using redeclarable_base::redecls_end;
using redeclarable_base::redecls;
@@ -1839,10 +1941,6 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == ObjCInterface; }
- friend class ASTReader;
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-
private:
const ObjCInterfaceDecl *findInterfaceWithDesignatedInitializers() const;
bool inheritsDesignatedInitializers() const;
@@ -1876,9 +1974,9 @@ private:
SourceLocation IdLoc, IdentifierInfo *Id,
QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW,
bool synthesized)
- : FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW,
- /*Mutable=*/false, /*HasInit=*/ICIS_NoInit),
- NextIvar(nullptr), DeclAccess(ac), Synthesized(synthesized) {}
+ : FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW,
+ /*Mutable=*/false, /*HasInit=*/ICIS_NoInit),
+ DeclAccess(ac), Synthesized(synthesized) {}
public:
static ObjCIvarDecl *Create(ASTContext &C, ObjCContainerDecl *DC,
@@ -1918,26 +2016,27 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == ObjCIvar; }
+
private:
/// NextIvar - Next Ivar in the list of ivars declared in class; class's
/// extensions and class's implementation
- ObjCIvarDecl *NextIvar;
+ ObjCIvarDecl *NextIvar = nullptr;
// NOTE: VC++ treats enums as signed, avoid using the AccessControl enum
unsigned DeclAccess : 3;
unsigned Synthesized : 1;
};
-
/// \brief Represents a field declaration created by an \@defs(...).
class ObjCAtDefsFieldDecl : public FieldDecl {
- void anchor() override;
ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
QualType T, Expr *BW)
- : FieldDecl(ObjCAtDefsField, DC, StartLoc, IdLoc, Id, T,
- /*TInfo=*/nullptr, // FIXME: Do ObjCAtDefs have declarators ?
- BW, /*Mutable=*/false, /*HasInit=*/ICIS_NoInit) {}
+ : FieldDecl(ObjCAtDefsField, DC, StartLoc, IdLoc, Id, T,
+ /*TInfo=*/nullptr, // FIXME: Do ObjCAtDefs have declarators ?
+ BW, /*Mutable=*/false, /*HasInit=*/ICIS_NoInit) {}
+
+ void anchor() override;
public:
static ObjCAtDefsFieldDecl *Create(ASTContext &C, DeclContext *DC,
@@ -1981,11 +2080,8 @@ public:
/// protocols are referenced using angle brackets as follows:
///
/// id \<NSDraggingInfo> anyObjectThatImplementsNSDraggingInfo;
-///
class ObjCProtocolDecl : public ObjCContainerDecl,
public Redeclarable<ObjCProtocolDecl> {
- void anchor() override;
-
struct DefinitionData {
// \brief The declaration that defines this protocol.
ObjCProtocolDecl *Definition;
@@ -2001,29 +2097,38 @@ class ObjCProtocolDecl : public ObjCContainerDecl,
/// declarations. It will be set unless modules are enabled.
llvm::PointerIntPair<DefinitionData *, 1, bool> Data;
+ ObjCProtocolDecl(ASTContext &C, DeclContext *DC, IdentifierInfo *Id,
+ SourceLocation nameLoc, SourceLocation atStartLoc,
+ ObjCProtocolDecl *PrevDecl);
+
+ void anchor() override;
+
DefinitionData &data() const {
assert(Data.getPointer() && "Objective-C protocol has no definition!");
return *Data.getPointer();
}
- ObjCProtocolDecl(ASTContext &C, DeclContext *DC, IdentifierInfo *Id,
- SourceLocation nameLoc, SourceLocation atStartLoc,
- ObjCProtocolDecl *PrevDecl);
-
void allocateDefinitionData();
- typedef Redeclarable<ObjCProtocolDecl> redeclarable_base;
+ using redeclarable_base = Redeclarable<ObjCProtocolDecl>;
+
ObjCProtocolDecl *getNextRedeclarationImpl() override {
return getNextRedeclaration();
}
+
ObjCProtocolDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
}
+
ObjCProtocolDecl *getMostRecentDeclImpl() override {
return getMostRecentDecl();
}
public:
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+ friend class ASTReader;
+
static ObjCProtocolDecl *Create(ASTContext &C, DeclContext *DC,
IdentifierInfo *Id,
SourceLocation nameLoc,
@@ -2036,42 +2141,49 @@ public:
assert(hasDefinition() && "No definition available!");
return data().ReferencedProtocols;
}
- typedef ObjCProtocolList::iterator protocol_iterator;
- typedef llvm::iterator_range<protocol_iterator> protocol_range;
+
+ using protocol_iterator = ObjCProtocolList::iterator;
+ using protocol_range = llvm::iterator_range<protocol_iterator>;
protocol_range protocols() const {
return protocol_range(protocol_begin(), protocol_end());
}
+
protocol_iterator protocol_begin() const {
if (!hasDefinition())
return protocol_iterator();
return data().ReferencedProtocols.begin();
}
+
protocol_iterator protocol_end() const {
if (!hasDefinition())
return protocol_iterator();
return data().ReferencedProtocols.end();
}
- typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
- typedef llvm::iterator_range<protocol_loc_iterator> protocol_loc_range;
+
+ using protocol_loc_iterator = ObjCProtocolList::loc_iterator;
+ using protocol_loc_range = llvm::iterator_range<protocol_loc_iterator>;
protocol_loc_range protocol_locs() const {
return protocol_loc_range(protocol_loc_begin(), protocol_loc_end());
}
+
protocol_loc_iterator protocol_loc_begin() const {
if (!hasDefinition())
return protocol_loc_iterator();
return data().ReferencedProtocols.loc_begin();
}
+
protocol_loc_iterator protocol_loc_end() const {
if (!hasDefinition())
return protocol_loc_iterator();
return data().ReferencedProtocols.loc_end();
}
+
unsigned protocol_size() const {
if (!hasDefinition())
return 0;
@@ -2092,9 +2204,11 @@ public:
// Lookup a method. First, we search locally. If a method isn't
// found, we search referenced protocols and class categories.
ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance) const;
+
ObjCMethodDecl *lookupInstanceMethod(Selector Sel) const {
return lookupMethod(Sel, true/*isInstance*/);
}
+
ObjCMethodDecl *lookupClassMethod(Selector Sel) const {
return lookupMethod(Sel, false/*isInstance*/);
}
@@ -2141,8 +2255,9 @@ public:
return SourceRange(getAtStartLoc(), getLocation());
}
- typedef redeclarable_base::redecl_range redecl_range;
- typedef redeclarable_base::redecl_iterator redecl_iterator;
+ using redecl_range = redeclarable_base::redecl_range;
+ using redecl_iterator = redeclarable_base::redecl_iterator;
+
using redeclarable_base::redecls_begin;
using redeclarable_base::redecls_end;
using redeclarable_base::redecls;
@@ -2163,10 +2278,6 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == ObjCProtocol; }
-
- friend class ASTReader;
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
};
/// ObjCCategoryDecl - Represents a category declaration. A category allows
@@ -2185,22 +2296,19 @@ public:
/// Categories were originally inspired by dynamic languages such as Common
/// Lisp and Smalltalk. More traditional class-based languages (C++, Java)
/// don't support this level of dynamism, which is both powerful and dangerous.
-///
class ObjCCategoryDecl : public ObjCContainerDecl {
- void anchor() override;
-
/// Interface belonging to this category
ObjCInterfaceDecl *ClassInterface;
/// The type parameters associated with this category, if any.
- ObjCTypeParamList *TypeParamList;
+ ObjCTypeParamList *TypeParamList = nullptr;
/// referenced protocols in this category.
ObjCProtocolList ReferencedProtocols;
/// Next category belonging to this class.
/// FIXME: this should not be a singly-linked list. Move storage elsewhere.
- ObjCCategoryDecl *NextClassCategory;
+ ObjCCategoryDecl *NextClassCategory = nullptr;
/// \brief The location of the category name in this declaration.
SourceLocation CategoryNameLoc;
@@ -2213,10 +2321,14 @@ class ObjCCategoryDecl : public ObjCContainerDecl {
SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc,
IdentifierInfo *Id, ObjCInterfaceDecl *IDecl,
ObjCTypeParamList *typeParamList,
- SourceLocation IvarLBraceLoc=SourceLocation(),
- SourceLocation IvarRBraceLoc=SourceLocation());
+ SourceLocation IvarLBraceLoc = SourceLocation(),
+ SourceLocation IvarRBraceLoc = SourceLocation());
+
+ void anchor() override;
public:
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
static ObjCCategoryDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation AtLoc,
@@ -2257,26 +2369,31 @@ public:
return ReferencedProtocols;
}
- typedef ObjCProtocolList::iterator protocol_iterator;
- typedef llvm::iterator_range<protocol_iterator> protocol_range;
+ using protocol_iterator = ObjCProtocolList::iterator;
+ using protocol_range = llvm::iterator_range<protocol_iterator>;
protocol_range protocols() const {
return protocol_range(protocol_begin(), protocol_end());
}
+
protocol_iterator protocol_begin() const {
return ReferencedProtocols.begin();
}
+
protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
unsigned protocol_size() const { return ReferencedProtocols.size(); }
- typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
- typedef llvm::iterator_range<protocol_loc_iterator> protocol_loc_range;
+
+ using protocol_loc_iterator = ObjCProtocolList::loc_iterator;
+ using protocol_loc_range = llvm::iterator_range<protocol_loc_iterator>;
protocol_loc_range protocol_locs() const {
return protocol_loc_range(protocol_loc_begin(), protocol_loc_end());
}
+
protocol_loc_iterator protocol_loc_begin() const {
return ReferencedProtocols.loc_begin();
}
+
protocol_loc_iterator protocol_loc_end() const {
return ReferencedProtocols.loc_end();
}
@@ -2291,19 +2408,23 @@ public:
bool IsClassExtension() const { return getIdentifier() == nullptr; }
- typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
- typedef llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>> ivar_range;
+ using ivar_iterator = specific_decl_iterator<ObjCIvarDecl>;
+ using ivar_range = llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>>;
ivar_range ivars() const { return ivar_range(ivar_begin(), ivar_end()); }
+
ivar_iterator ivar_begin() const {
return ivar_iterator(decls_begin());
}
+
ivar_iterator ivar_end() const {
return ivar_iterator(decls_end());
}
+
unsigned ivar_size() const {
return std::distance(ivar_begin(), ivar_end());
}
+
bool ivar_empty() const {
return ivar_begin() == ivar_end();
}
@@ -2318,24 +2439,21 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == ObjCCategory; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
};
class ObjCImplDecl : public ObjCContainerDecl {
- void anchor() override;
-
/// Class interface for this class/category implementation
ObjCInterfaceDecl *ClassInterface;
+ void anchor() override;
+
protected:
ObjCImplDecl(Kind DK, DeclContext *DC,
ObjCInterfaceDecl *classInterface,
IdentifierInfo *Id,
SourceLocation nameLoc, SourceLocation atStartLoc)
- : ObjCContainerDecl(DK, DC, Id, nameLoc, atStartLoc),
- ClassInterface(classInterface) {}
+ : ObjCContainerDecl(DK, DC, Id, nameLoc, atStartLoc),
+ ClassInterface(classInterface) {}
public:
const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
@@ -2347,6 +2465,7 @@ public:
method->setLexicalDeclContext(this);
addDecl(method);
}
+
void addClassMethod(ObjCMethodDecl *method) {
// FIXME: Context should be set correctly before we get here.
method->setLexicalDeclContext(this);
@@ -2360,21 +2479,24 @@ public:
ObjCPropertyImplDecl *FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const;
// Iterator access to properties.
- typedef specific_decl_iterator<ObjCPropertyImplDecl> propimpl_iterator;
- typedef llvm::iterator_range<specific_decl_iterator<ObjCPropertyImplDecl>>
- propimpl_range;
+ using propimpl_iterator = specific_decl_iterator<ObjCPropertyImplDecl>;
+ using propimpl_range =
+ llvm::iterator_range<specific_decl_iterator<ObjCPropertyImplDecl>>;
propimpl_range property_impls() const {
return propimpl_range(propimpl_begin(), propimpl_end());
}
+
propimpl_iterator propimpl_begin() const {
return propimpl_iterator(decls_begin());
}
+
propimpl_iterator propimpl_end() const {
return propimpl_iterator(decls_end());
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+
static bool classofKind(Kind K) {
return K >= firstObjCImpl && K <= lastObjCImpl;
}
@@ -2394,8 +2516,6 @@ public:
///
/// ObjCCategoryImplDecl
class ObjCCategoryImplDecl : public ObjCImplDecl {
- void anchor() override;
-
// Category name location
SourceLocation CategoryNameLoc;
@@ -2403,10 +2523,16 @@ class ObjCCategoryImplDecl : public ObjCImplDecl {
ObjCInterfaceDecl *classInterface,
SourceLocation nameLoc, SourceLocation atStartLoc,
SourceLocation CategoryNameLoc)
- : ObjCImplDecl(ObjCCategoryImpl, DC, classInterface, Id,
- nameLoc, atStartLoc),
- CategoryNameLoc(CategoryNameLoc) {}
+ : ObjCImplDecl(ObjCCategoryImpl, DC, classInterface, Id,
+ nameLoc, atStartLoc),
+ CategoryNameLoc(CategoryNameLoc) {}
+
+ void anchor() override;
+
public:
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+
static ObjCCategoryImplDecl *Create(ASTContext &C, DeclContext *DC,
IdentifierInfo *Id,
ObjCInterfaceDecl *classInterface,
@@ -2421,9 +2547,6 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == ObjCCategoryImpl;}
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
};
raw_ostream &operator<<(raw_ostream &OS, const ObjCCategoryImplDecl &CID);
@@ -2446,7 +2569,6 @@ raw_ostream &operator<<(raw_ostream &OS, const ObjCCategoryImplDecl &CID);
/// we allow instance variables to be specified in the implementation. When
/// specified, they need to be \em identical to the interface.
class ObjCImplementationDecl : public ObjCImplDecl {
- void anchor() override;
/// Implementation Class's super class.
ObjCInterfaceDecl *SuperClass;
SourceLocation SuperLoc;
@@ -2458,7 +2580,7 @@ class ObjCImplementationDecl : public ObjCImplDecl {
/// Support for ivar initialization.
/// \brief The arguments used to initialize the ivars
LazyCXXCtorInitializersPtr IvarInitializers;
- unsigned NumIvarInitializers;
+ unsigned NumIvarInitializers = 0;
/// Do the ivars of this class require initialization other than
/// zero-initialization?
@@ -2474,15 +2596,20 @@ class ObjCImplementationDecl : public ObjCImplDecl {
SourceLocation superLoc = SourceLocation(),
SourceLocation IvarLBraceLoc=SourceLocation(),
SourceLocation IvarRBraceLoc=SourceLocation())
- : ObjCImplDecl(ObjCImplementation, DC, classInterface,
- classInterface ? classInterface->getIdentifier()
- : nullptr,
- nameLoc, atStartLoc),
- SuperClass(superDecl), SuperLoc(superLoc), IvarLBraceLoc(IvarLBraceLoc),
- IvarRBraceLoc(IvarRBraceLoc),
- IvarInitializers(nullptr), NumIvarInitializers(0),
- HasNonZeroConstructors(false), HasDestructors(false) {}
+ : ObjCImplDecl(ObjCImplementation, DC, classInterface,
+ classInterface ? classInterface->getIdentifier()
+ : nullptr,
+ nameLoc, atStartLoc),
+ SuperClass(superDecl), SuperLoc(superLoc),
+ IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc),
+ HasNonZeroConstructors(false), HasDestructors(false) {}
+
+ void anchor() override;
+
public:
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+
static ObjCImplementationDecl *Create(ASTContext &C, DeclContext *DC,
ObjCInterfaceDecl *classInterface,
ObjCInterfaceDecl *superDecl,
@@ -2495,15 +2622,16 @@ public:
static ObjCImplementationDecl *CreateDeserialized(ASTContext &C, unsigned ID);
/// init_iterator - Iterates through the ivar initializer list.
- typedef CXXCtorInitializer **init_iterator;
+ using init_iterator = CXXCtorInitializer **;
/// init_const_iterator - Iterates through the ivar initializer list.
- typedef CXXCtorInitializer * const * init_const_iterator;
+ using init_const_iterator = CXXCtorInitializer * const *;
- typedef llvm::iterator_range<init_iterator> init_range;
- typedef llvm::iterator_range<init_const_iterator> init_const_range;
+ using init_range = llvm::iterator_range<init_iterator>;
+ using init_const_range = llvm::iterator_range<init_const_iterator>;
init_range inits() { return init_range(init_begin(), init_end()); }
+
init_const_range inits() const {
return init_const_range(init_begin(), init_end());
}
@@ -2513,6 +2641,7 @@ public:
const auto *ConstThis = this;
return const_cast<init_iterator>(ConstThis->init_begin());
}
+
/// begin() - Retrieve an iterator to the first initializer.
init_const_iterator init_begin() const;
@@ -2520,10 +2649,12 @@ public:
init_iterator init_end() {
return init_begin() + NumIvarInitializers;
}
+
/// end() - Retrieve an iterator past the last initializer.
init_const_iterator init_end() const {
return init_begin() + NumIvarInitializers;
}
+
/// getNumArgs - Number of ivars which must be initialized.
unsigned getNumIvarInitializers() const {
return NumIvarInitializers;
@@ -2585,28 +2716,29 @@ public:
void setIvarRBraceLoc(SourceLocation Loc) { IvarRBraceLoc = Loc; }
SourceLocation getIvarRBraceLoc() const { return IvarRBraceLoc; }
- typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
- typedef llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>> ivar_range;
+ using ivar_iterator = specific_decl_iterator<ObjCIvarDecl>;
+ using ivar_range = llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>>;
ivar_range ivars() const { return ivar_range(ivar_begin(), ivar_end()); }
+
ivar_iterator ivar_begin() const {
return ivar_iterator(decls_begin());
}
+
ivar_iterator ivar_end() const {
return ivar_iterator(decls_end());
}
+
unsigned ivar_size() const {
return std::distance(ivar_begin(), ivar_end());
}
+
bool ivar_empty() const {
return ivar_begin() == ivar_end();
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == ObjCImplementation; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
};
raw_ostream &operator<<(raw_ostream &OS, const ObjCImplementationDecl &ID);
@@ -2614,13 +2746,15 @@ raw_ostream &operator<<(raw_ostream &OS, const ObjCImplementationDecl &ID);
/// ObjCCompatibleAliasDecl - Represents alias of a class. This alias is
/// declared as \@compatibility_alias alias class.
class ObjCCompatibleAliasDecl : public NamedDecl {
- void anchor() override;
/// Class that this is an alias of.
ObjCInterfaceDecl *AliasedClass;
ObjCCompatibleAliasDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
ObjCInterfaceDecl* aliasedClass)
- : NamedDecl(ObjCCompatibleAlias, DC, L, Id), AliasedClass(aliasedClass) {}
+ : NamedDecl(ObjCCompatibleAlias, DC, L, Id), AliasedClass(aliasedClass) {}
+
+ void anchor() override;
+
public:
static ObjCCompatibleAliasDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
@@ -2635,7 +2769,6 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == ObjCCompatibleAlias; }
-
};
/// ObjCPropertyImplDecl - Represents implementation declaration of a property
@@ -2648,6 +2781,7 @@ public:
Synthesize,
Dynamic
};
+
private:
SourceLocation AtLoc; // location of \@synthesize or \@dynamic
@@ -2667,24 +2801,25 @@ private:
/// Null for \@dynamic. Non-null if property must be copy-constructed in
/// getter.
- Expr *GetterCXXConstructor;
+ Expr *GetterCXXConstructor = nullptr;
/// Null for \@dynamic. Non-null if property has assignment operator to call
/// in Setter synthesis.
- Expr *SetterCXXAssignment;
+ Expr *SetterCXXAssignment = nullptr;
ObjCPropertyImplDecl(DeclContext *DC, SourceLocation atLoc, SourceLocation L,
ObjCPropertyDecl *property,
Kind PK,
ObjCIvarDecl *ivarDecl,
SourceLocation ivarLoc)
- : Decl(ObjCPropertyImpl, DC, L), AtLoc(atLoc),
- IvarLoc(ivarLoc), PropertyDecl(property), PropertyIvarDecl(ivarDecl),
- GetterCXXConstructor(nullptr), SetterCXXAssignment(nullptr) {
- assert (PK == Dynamic || PropertyIvarDecl);
+ : Decl(ObjCPropertyImpl, DC, L), AtLoc(atLoc),
+ IvarLoc(ivarLoc), PropertyDecl(property), PropertyIvarDecl(ivarDecl) {
+ assert(PK == Dynamic || PropertyIvarDecl);
}
public:
+ friend class ASTDeclReader;
+
static ObjCPropertyImplDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation atLoc, SourceLocation L,
ObjCPropertyDecl *property,
@@ -2733,6 +2868,7 @@ public:
Expr *getGetterCXXConstructor() const {
return GetterCXXConstructor;
}
+
void setGetterCXXConstructor(Expr *getterCXXConstructor) {
GetterCXXConstructor = getterCXXConstructor;
}
@@ -2740,14 +2876,13 @@ public:
Expr *getSetterCXXAssignment() const {
return SetterCXXAssignment;
}
+
void setSetterCXXAssignment(Expr *setterCXXAssignment) {
SetterCXXAssignment = setterCXXAssignment;
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Decl::Kind K) { return K == ObjCPropertyImpl; }
-
- friend class ASTDeclReader;
};
template<bool (*Filter)(ObjCCategoryDecl *)>
@@ -2778,5 +2913,6 @@ inline bool ObjCInterfaceDecl::isKnownExtension(ObjCCategoryDecl *Cat) {
return Cat->IsClassExtension();
}
-} // end namespace clang
-#endif
+} // namespace clang
+
+#endif // LLVM_CLANG_AST_DECLOBJC_H
diff --git a/include/clang/AST/DeclOpenMP.h b/include/clang/AST/DeclOpenMP.h
index 30ca79e9d005..2a329c3732cb 100644
--- a/include/clang/AST/DeclOpenMP.h
+++ b/include/clang/AST/DeclOpenMP.h
@@ -100,12 +100,22 @@ public:
///
/// Here 'omp_out += omp_in' is a combiner and 'omp_priv = 0' is an initializer.
class OMPDeclareReductionDecl final : public ValueDecl, public DeclContext {
+public:
+ enum InitKind {
+ CallInit, // Initialized by function call.
+ DirectInit, // omp_priv(<expr>)
+ CopyInit // omp_priv = <expr>
+ };
+
private:
friend class ASTDeclReader;
/// \brief Combiner for declare reduction construct.
Expr *Combiner;
/// \brief Initializer for declare reduction construct.
Expr *Initializer;
+ /// Kind of initializer - function call or omp_priv<init_expr> initializtion.
+ InitKind InitializerKind = CallInit;
+
/// \brief Reference to the previous declare reduction construct in the same
/// scope with the same name. Required for proper templates instantiation if
/// the declare reduction construct is declared inside compound statement.
@@ -117,7 +127,8 @@ private:
DeclarationName Name, QualType Ty,
OMPDeclareReductionDecl *PrevDeclInScope)
: ValueDecl(DK, DC, L, Name, Ty), DeclContext(DK), Combiner(nullptr),
- Initializer(nullptr), PrevDeclInScope(PrevDeclInScope) {}
+ Initializer(nullptr), InitializerKind(CallInit),
+ PrevDeclInScope(PrevDeclInScope) {}
void setPrevDeclInScope(OMPDeclareReductionDecl *Prev) {
PrevDeclInScope = Prev;
@@ -142,8 +153,13 @@ public:
/// construct.
Expr *getInitializer() { return Initializer; }
const Expr *getInitializer() const { return Initializer; }
+ /// Get initializer kind.
+ InitKind getInitializerKind() const { return InitializerKind; }
/// \brief Set initializer expression for the declare reduction construct.
- void setInitializer(Expr *E) { Initializer = E; }
+ void setInitializer(Expr *E, InitKind IK) {
+ Initializer = E;
+ InitializerKind = IK;
+ }
/// \brief Get reference to previous declare reduction construct in the same
/// scope with the same name.
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index 2879452f2404..7842d7097174 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -1,4 +1,4 @@
-//===-- DeclTemplate.h - Classes for representing C++ templates -*- C++ -*-===//
+//===- DeclTemplate.h - Classes for representing C++ templates --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,42 +6,60 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-///
+//
/// \file
/// \brief Defines the C++ template declaration subclasses.
-///
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_DECLTEMPLATE_H
#define LLVM_CLANG_AST_DECLTEMPLATE_H
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclarationName.h"
#include "clang/AST/Redeclarable.h"
#include "clang/AST/TemplateBase.h"
+#include "clang/AST/Type.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/Specifiers.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/iterator.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/TrailingObjects.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <iterator>
#include <utility>
namespace clang {
enum BuiltinTemplateKind : int;
-class TemplateParameterList;
-class TemplateDecl;
-class RedeclarableTemplateDecl;
-class FunctionTemplateDecl;
class ClassTemplateDecl;
class ClassTemplatePartialSpecializationDecl;
-class TemplateTypeParmDecl;
+class Expr;
+class FunctionTemplateDecl;
+class IdentifierInfo;
class NonTypeTemplateParmDecl;
+class TemplateDecl;
class TemplateTemplateParmDecl;
-class TypeAliasTemplateDecl;
+class TemplateTypeParmDecl;
+class UnresolvedSetImpl;
class VarTemplateDecl;
class VarTemplatePartialSpecializationDecl;
/// \brief Stores a template parameter of any kind.
-typedef llvm::PointerUnion3<TemplateTypeParmDecl*, NonTypeTemplateParmDecl*,
- TemplateTemplateParmDecl*> TemplateParameter;
+using TemplateParameter =
+ llvm::PointerUnion3<TemplateTypeParmDecl *, NonTypeTemplateParmDecl *,
+ TemplateTemplateParmDecl *>;
NamedDecl *getAsNamedDecl(TemplateParameter P);
@@ -50,7 +68,6 @@ NamedDecl *getAsNamedDecl(TemplateParameter P);
class TemplateParameterList final
: private llvm::TrailingObjects<TemplateParameterList, NamedDecl *,
Expr *> {
-
/// The location of the 'template' keyword.
SourceLocation TemplateLoc;
@@ -69,6 +86,10 @@ class TemplateParameterList final
unsigned HasRequiresClause : 1;
protected:
+ TemplateParameterList(SourceLocation TemplateLoc, SourceLocation LAngleLoc,
+ ArrayRef<NamedDecl *> Params, SourceLocation RAngleLoc,
+ Expr *RequiresClause);
+
size_t numTrailingObjects(OverloadToken<NamedDecl *>) const {
return NumParams;
}
@@ -77,11 +98,11 @@ protected:
return HasRequiresClause;
}
- TemplateParameterList(SourceLocation TemplateLoc, SourceLocation LAngleLoc,
- ArrayRef<NamedDecl *> Params, SourceLocation RAngleLoc,
- Expr *RequiresClause);
-
public:
+ template <size_t N, bool HasRequiresClause>
+ friend class FixedSizeTemplateParameterListStorage;
+ friend TrailingObjects;
+
static TemplateParameterList *Create(const ASTContext &C,
SourceLocation TemplateLoc,
SourceLocation LAngleLoc,
@@ -90,10 +111,10 @@ public:
Expr *RequiresClause);
/// \brief Iterates through the template parameters in this list.
- typedef NamedDecl** iterator;
+ using iterator = NamedDecl **;
/// \brief Iterates through the template parameters in this list.
- typedef NamedDecl* const* const_iterator;
+ using const_iterator = NamedDecl * const *;
iterator begin() { return getTrailingObjects<NamedDecl *>(); }
const_iterator begin() const { return getTrailingObjects<NamedDecl *>(); }
@@ -113,7 +134,6 @@ public:
assert(Idx < size() && "Template parameter index out-of-range");
return begin()[Idx];
}
-
const NamedDecl* getParam(unsigned Idx) const {
assert(Idx < size() && "Template parameter index out-of-range");
return begin()[Idx];
@@ -157,11 +177,6 @@ public:
return SourceRange(TemplateLoc, RAngleLoc);
}
- friend TrailingObjects;
-
- template <size_t N, bool HasRequiresClause>
- friend class FixedSizeTemplateParameterListStorage;
-
public:
// FIXME: workaround for MSVC 2013; remove when no longer needed
using FixedSizeStorageOwner = TrailingObjects::FixedSizeStorageOwner;
@@ -201,14 +216,16 @@ class TemplateArgumentList final
/// argument list.
unsigned NumArguments;
- TemplateArgumentList(const TemplateArgumentList &Other) = delete;
- void operator=(const TemplateArgumentList &Other) = delete;
-
// Constructs an instance with an internal Argument list, containing
// a copy of the Args array. (Called by CreateCopy)
TemplateArgumentList(ArrayRef<TemplateArgument> Args);
public:
+ friend TrailingObjects;
+
+ TemplateArgumentList(const TemplateArgumentList &) = delete;
+ TemplateArgumentList &operator=(const TemplateArgumentList &) = delete;
+
/// \brief Type used to indicate that the template argument list itself is a
/// stack object. It does not own its template arguments.
enum OnStackType { OnStack };
@@ -254,8 +271,6 @@ public:
/// \brief Retrieve a pointer to the template argument list.
const TemplateArgument *data() const { return Arguments; }
-
- friend TrailingObjects;
};
void *allocateDefaultArgStorageChain(const ASTContext &C);
@@ -297,9 +312,11 @@ public:
/// Determine whether there is a default argument for this parameter.
bool isSet() const { return !ValueOrInherited.isNull(); }
+
/// Determine whether the default argument for this parameter was inherited
/// from a previous declaration of the same entity.
bool isInherited() const { return ValueOrInherited.template is<ParmDecl*>(); }
+
/// Get the default argument's value. This does not consider whether the
/// default argument is visible.
ArgType get() const {
@@ -310,6 +327,7 @@ public:
return C->Value;
return Storage->ValueOrInherited.template get<ArgType>();
}
+
/// Get the parameter from which we inherit the default argument, if any.
/// This is the parameter on which the default argument was actually written.
const ParmDecl *getInheritedFrom() const {
@@ -319,11 +337,13 @@ public:
return C->PrevDeclWithDefaultArg;
return nullptr;
}
+
/// Set the default argument.
void set(ArgType Arg) {
assert(!isSet() && "default argument already set");
ValueOrInherited = Arg;
}
+
/// Set that the default argument was inherited from another parameter.
void setInherited(const ASTContext &C, ParmDecl *InheritedFrom) {
assert(!isInherited() && "default argument already inherited");
@@ -334,6 +354,7 @@ public:
ValueOrInherited = new (allocateDefaultArgStorageChain(C))
Chain{InheritedFrom, ValueOrInherited.template get<ArgType>()};
}
+
/// Remove the default argument, even if it was inherited.
void clear() {
ValueOrInherited = ArgType();
@@ -350,7 +371,7 @@ class ConstrainedTemplateDeclInfo {
friend TemplateDecl;
public:
- ConstrainedTemplateDeclInfo() : TemplateParams(), AssociatedConstraints() {}
+ ConstrainedTemplateDeclInfo() = default;
TemplateParameterList *getTemplateParameters() const {
return TemplateParams;
@@ -365,8 +386,8 @@ protected:
void setAssociatedConstraints(Expr *AC) { AssociatedConstraints = AC; }
- TemplateParameterList *TemplateParams;
- Expr *AssociatedConstraints;
+ TemplateParameterList *TemplateParams = nullptr;
+ Expr *AssociatedConstraints = nullptr;
};
@@ -377,13 +398,14 @@ protected:
/// reference to the templated scoped declaration: the underlying AST node.
class TemplateDecl : public NamedDecl {
void anchor() override;
+
protected:
// Construct a template decl with the given name and parameters.
// Used when there is no templated element (e.g., for tt-params).
TemplateDecl(ConstrainedTemplateDeclInfo *CTDI, Kind DK, DeclContext *DC,
SourceLocation L, DeclarationName Name,
TemplateParameterList *Params)
- : NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr, false),
+ : NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr),
TemplateParams(CTDI) {
this->setTemplateParameters(Params);
}
@@ -396,7 +418,7 @@ protected:
TemplateDecl(ConstrainedTemplateDeclInfo *CTDI, Kind DK, DeclContext *DC,
SourceLocation L, DeclarationName Name,
TemplateParameterList *Params, NamedDecl *Decl)
- : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl, false),
+ : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl),
TemplateParams(CTDI) {
this->setTemplateParameters(Params);
}
@@ -428,31 +450,22 @@ public:
}
/// Get the underlying, templated declaration.
- NamedDecl *getTemplatedDecl() const { return TemplatedDecl.getPointer(); }
+ NamedDecl *getTemplatedDecl() const { return TemplatedDecl; }
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+
static bool classofKind(Kind K) {
return K >= firstTemplate && K <= lastTemplate;
}
SourceRange getSourceRange() const override LLVM_READONLY {
return SourceRange(getTemplateParameters()->getTemplateLoc(),
- TemplatedDecl.getPointer()->getSourceRange().getEnd());
+ TemplatedDecl->getSourceRange().getEnd());
}
- /// Whether this is a (C++ Concepts TS) function or variable concept.
- bool isConcept() const { return TemplatedDecl.getInt(); }
- void setConcept() { TemplatedDecl.setInt(true); }
-
protected:
- /// \brief The named declaration from which this template was instantiated.
- /// (or null).
- ///
- /// The boolean value will be true to indicate that this template
- /// (function or variable) is a concept.
- llvm::PointerIntPair<NamedDecl *, 1, bool> TemplatedDecl;
-
+ NamedDecl *TemplatedDecl;
/// \brief The template parameter list and optional requires-clause
/// associated with this declaration; alternatively, a
/// \c ConstrainedTemplateDeclInfo if the associated constraints of the
@@ -481,9 +494,9 @@ public:
/// \brief Initialize the underlying templated declaration and
/// template parameters.
void init(NamedDecl *templatedDecl, TemplateParameterList* templateParams) {
- assert(!TemplatedDecl.getPointer() && "TemplatedDecl already set!");
+ assert(!TemplatedDecl && "TemplatedDecl already set!");
assert(!TemplateParams && "TemplateParams already set!");
- TemplatedDecl.setPointer(templatedDecl);
+ TemplatedDecl = templatedDecl;
TemplateParams = templateParams;
}
};
@@ -498,11 +511,10 @@ class FunctionTemplateSpecializationInfo : public llvm::FoldingSetNode {
const TemplateArgumentList *TemplateArgs,
const ASTTemplateArgumentListInfo *TemplateArgsAsWritten,
SourceLocation POI)
- : Function(FD),
- Template(Template, TSK - 1),
- TemplateArguments(TemplateArgs),
- TemplateArgumentsAsWritten(TemplateArgsAsWritten),
- PointOfInstantiation(POI) { }
+ : Function(FD), Template(Template, TSK - 1),
+ TemplateArguments(TemplateArgs),
+ TemplateArgumentsAsWritten(TemplateArgsAsWritten),
+ PointOfInstantiation(POI) {}
public:
static FunctionTemplateSpecializationInfo *
@@ -604,7 +616,7 @@ public:
explicit
MemberSpecializationInfo(NamedDecl *IF, TemplateSpecializationKind TSK,
SourceLocation POI = SourceLocation())
- : MemberAndTSK(IF, TSK - 1), PointOfInstantiation(POI) {
+ : MemberAndTSK(IF, TSK - 1), PointOfInstantiation(POI) {
assert(TSK != TSK_Undeclared &&
"Cannot encode undeclared template specializations for members");
}
@@ -681,6 +693,8 @@ class DependentFunctionTemplateSpecializationInfo final
const TemplateArgumentListInfo &TemplateArgs);
public:
+ friend TrailingObjects;
+
static DependentFunctionTemplateSpecializationInfo *
Create(ASTContext &Context, const UnresolvedSetImpl &Templates,
const TemplateArgumentListInfo &TemplateArgs);
@@ -716,32 +730,34 @@ public:
SourceLocation getRAngleLoc() const {
return AngleLocs.getEnd();
}
-
- friend TrailingObjects;
};
/// Declaration of a redeclarable template.
class RedeclarableTemplateDecl : public TemplateDecl,
public Redeclarable<RedeclarableTemplateDecl>
{
- typedef Redeclarable<RedeclarableTemplateDecl> redeclarable_base;
+ using redeclarable_base = Redeclarable<RedeclarableTemplateDecl>;
+
RedeclarableTemplateDecl *getNextRedeclarationImpl() override {
return getNextRedeclaration();
}
+
RedeclarableTemplateDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
}
+
RedeclarableTemplateDecl *getMostRecentDeclImpl() override {
return getMostRecentDecl();
}
protected:
template <typename EntryType> struct SpecEntryTraits {
- typedef EntryType DeclType;
+ using DeclType = EntryType;
static DeclType *getDecl(EntryType *D) {
return D;
}
+
static ArrayRef<TemplateArgument> getTemplateArgs(EntryType *D) {
return D->getTemplateArgs().asArray();
}
@@ -756,7 +772,7 @@ protected:
typename std::iterator_traits<typename llvm::FoldingSetVector<
EntryType>::iterator>::iterator_category,
DeclType *, ptrdiff_t, DeclType *, DeclType *> {
- SpecIterator() {}
+ SpecIterator() = default;
explicit SpecIterator(
typename llvm::FoldingSetVector<EntryType>::iterator SetIter)
: SpecIterator::iterator_adaptor_base(std::move(SetIter)) {}
@@ -764,6 +780,7 @@ protected:
DeclType *operator*() const {
return SETraits::getDecl(&*this->I)->getMostRecentDecl();
}
+
DeclType *operator->() const { return **this; }
};
@@ -773,6 +790,8 @@ protected:
return SpecIterator<EntryType>(isEnd ? Specs.end() : Specs.begin());
}
+ void loadLazySpecializationsImpl() const;
+
template <class EntryType> typename SpecEntryTraits<EntryType>::DeclType*
findSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
ArrayRef<TemplateArgument> Args, void *&InsertPos);
@@ -782,7 +801,7 @@ protected:
EntryType *Entry, void *InsertPos);
struct CommonBase {
- CommonBase() : InstantiatedFromMember(nullptr, false) { }
+ CommonBase() : InstantiatedFromMember(nullptr, false) {}
/// \brief The template from which this was most
/// directly instantiated (or null).
@@ -791,11 +810,18 @@ protected:
/// was explicitly specialized.
llvm::PointerIntPair<RedeclarableTemplateDecl*, 1, bool>
InstantiatedFromMember;
+
+ /// \brief If non-null, points to an array of specializations (including
+ /// partial specializations) known only by their external declaration IDs.
+ ///
+ /// The first value in the array is the number of specializations/partial
+ /// specializations that follow.
+ uint32_t *LazySpecializations = nullptr;
};
/// \brief Pointer to the common data shared by all declarations of this
/// template.
- mutable CommonBase *Common;
+ mutable CommonBase *Common = nullptr;
/// \brief Retrieves the "common" pointer shared by all (re-)declarations of
/// the same template. Calling this routine may implicitly allocate memory
@@ -809,8 +835,8 @@ protected:
ASTContext &C, DeclContext *DC, SourceLocation L,
DeclarationName Name, TemplateParameterList *Params,
NamedDecl *Decl)
- : TemplateDecl(CTDI, DK, DC, L, Name, Params, Decl), redeclarable_base(C),
- Common() {}
+ : TemplateDecl(CTDI, DK, DC, L, Name, Params, Decl), redeclarable_base(C)
+ {}
RedeclarableTemplateDecl(Kind DK, ASTContext &C, DeclContext *DC,
SourceLocation L, DeclarationName Name,
@@ -818,6 +844,9 @@ protected:
: RedeclarableTemplateDecl(nullptr, DK, C, DC, L, Name, Params, Decl) {}
public:
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+ friend class ASTReader;
template <class decl_type> friend class RedeclarableTemplate;
/// \brief Retrieves the canonical declaration of this template.
@@ -858,7 +887,7 @@ public:
}
/// \brief Retrieve the member template from which this template was
- /// instantiated, or NULL if this template was not instantiated from a
+ /// instantiated, or nullptr if this template was not instantiated from a
/// member template.
///
/// A template is instantiated from a member template when the member
@@ -902,8 +931,9 @@ public:
getCommonPtr()->InstantiatedFromMember.setPointer(TD);
}
- typedef redeclarable_base::redecl_range redecl_range;
- typedef redeclarable_base::redecl_iterator redecl_iterator;
+ using redecl_range = redeclarable_base::redecl_range;
+ using redecl_iterator = redeclarable_base::redecl_iterator;
+
using redeclarable_base::redecls_begin;
using redeclarable_base::redecls_end;
using redeclarable_base::redecls;
@@ -913,22 +943,20 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+
static bool classofKind(Kind K) {
return K >= firstRedeclarableTemplate && K <= lastRedeclarableTemplate;
}
-
- friend class ASTReader;
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
};
template <> struct RedeclarableTemplateDecl::
SpecEntryTraits<FunctionTemplateSpecializationInfo> {
- typedef FunctionDecl DeclType;
+ using DeclType = FunctionDecl;
static DeclType *getDecl(FunctionTemplateSpecializationInfo *I) {
return I->Function;
}
+
static ArrayRef<TemplateArgument>
getTemplateArgs(FunctionTemplateSpecializationInfo *I) {
return I->TemplateArguments->asArray();
@@ -938,11 +966,11 @@ SpecEntryTraits<FunctionTemplateSpecializationInfo> {
/// Declaration of a template function.
class FunctionTemplateDecl : public RedeclarableTemplateDecl {
protected:
+ friend class FunctionDecl;
+
/// \brief Data that is common to all of the declarations of a given
/// function template.
struct Common : CommonBase {
- Common() : InjectedArgs(), LazySpecializations() { }
-
/// \brief The function template specializations for this function
/// template, including explicit specializations and instantiations.
llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> Specializations;
@@ -954,14 +982,9 @@ protected:
/// many template arguments as template parameaters) for the function
/// template, and is allocated lazily, since most function templates do not
/// require the use of this information.
- TemplateArgument *InjectedArgs;
+ TemplateArgument *InjectedArgs = nullptr;
- /// \brief If non-null, points to an array of specializations known only
- /// by their external declaration IDs.
- ///
- /// The first value in the array is the number of of specializations
- /// that follow.
- uint32_t *LazySpecializations;
+ Common() = default;
};
FunctionTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
@@ -976,8 +999,6 @@ protected:
return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
}
- friend class FunctionDecl;
-
/// \brief Retrieve the set of function template specializations of this
/// function template.
llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
@@ -991,12 +1012,15 @@ protected:
void *InsertPos);
public:
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+
/// \brief Load any lazily-loaded specializations from the external source.
void LoadLazySpecializations() const;
/// Get the underlying function declaration of the template.
FunctionDecl *getTemplatedDecl() const {
- return static_cast<FunctionDecl *>(TemplatedDecl.getPointer());
+ return static_cast<FunctionDecl *>(TemplatedDecl);
}
/// Returns whether this template declaration defines the primary
@@ -1020,14 +1044,11 @@ public:
}
/// \brief Retrieve the previous declaration of this function template, or
- /// NULL if no such declaration exists.
+ /// nullptr if no such declaration exists.
FunctionTemplateDecl *getPreviousDecl() {
return cast_or_null<FunctionTemplateDecl>(
static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
}
-
- /// \brief Retrieve the previous declaration of this function template, or
- /// NULL if no such declaration exists.
const FunctionTemplateDecl *getPreviousDecl() const {
return cast_or_null<FunctionTemplateDecl>(
static_cast<const RedeclarableTemplateDecl *>(this)->getPreviousDecl());
@@ -1047,12 +1068,13 @@ public:
RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
}
- typedef SpecIterator<FunctionTemplateSpecializationInfo> spec_iterator;
- typedef llvm::iterator_range<spec_iterator> spec_range;
+ using spec_iterator = SpecIterator<FunctionTemplateSpecializationInfo>;
+ using spec_range = llvm::iterator_range<spec_iterator>;
spec_range specializations() const {
return spec_range(spec_begin(), spec_end());
}
+
spec_iterator spec_begin() const {
return makeSpecIterator(getSpecializations(), false);
}
@@ -1083,9 +1105,6 @@ public:
// Implement isa/cast/dyncast support
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == FunctionTemplate; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
};
//===----------------------------------------------------------------------===//
@@ -1102,19 +1121,17 @@ public:
/// This class is inheritedly privately by different kinds of template
/// parameters and is not part of the Decl hierarchy. Just a facility.
class TemplateParmPosition {
- TemplateParmPosition() = delete;
-
protected:
- TemplateParmPosition(unsigned D, unsigned P)
- : Depth(D), Position(P)
- { }
-
// FIXME: These probably don't need to be ints. int:5 for depth, int:8 for
// position? Maybe?
unsigned Depth;
unsigned Position;
+ TemplateParmPosition(unsigned D, unsigned P) : Depth(D), Position(P) {}
+
public:
+ TemplateParmPosition() = delete;
+
/// Get the nesting depth of the template parameter.
unsigned getDepth() const { return Depth; }
void setDepth(unsigned D) { Depth = D; }
@@ -1134,6 +1151,9 @@ public:
/// template<typename T> class vector;
/// \endcode
class TemplateTypeParmDecl : public TypeDecl {
+ /// Sema creates these on the stack during auto type deduction.
+ friend class Sema;
+
/// \brief Whether this template type parameter was declaration with
/// the 'typename' keyword.
///
@@ -1141,18 +1161,14 @@ class TemplateTypeParmDecl : public TypeDecl {
bool Typename : 1;
/// \brief The default template argument, if any.
- typedef DefaultArgStorage<TemplateTypeParmDecl, TypeSourceInfo *>
- DefArgStorage;
+ using DefArgStorage =
+ DefaultArgStorage<TemplateTypeParmDecl, TypeSourceInfo *>;
DefArgStorage DefaultArgument;
TemplateTypeParmDecl(DeclContext *DC, SourceLocation KeyLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
bool Typename)
- : TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename),
- DefaultArgument() { }
-
- /// Sema creates these on the stack during auto type deduction.
- friend class Sema;
+ : TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename) {}
public:
static TemplateTypeParmDecl *Create(const ASTContext &C, DeclContext *DC,
@@ -1199,6 +1215,7 @@ public:
void setDefaultArgument(TypeSourceInfo *DefArg) {
DefaultArgument.set(DefArg);
}
+
/// \brief Set that this default argument was inherited from another
/// parameter.
void setInheritedDefaultArgument(const ASTContext &C,
@@ -1241,9 +1258,12 @@ class NonTypeTemplateParmDecl final
protected TemplateParmPosition,
private llvm::TrailingObjects<NonTypeTemplateParmDecl,
std::pair<QualType, TypeSourceInfo *>> {
+ friend class ASTDeclReader;
+ friend TrailingObjects;
+
/// \brief The default template argument, if any, and whether or not
/// it was inherited.
- typedef DefaultArgStorage<NonTypeTemplateParmDecl, Expr*> DefArgStorage;
+ using DefArgStorage = DefaultArgStorage<NonTypeTemplateParmDecl, Expr *>;
DefArgStorage DefaultArgument;
// FIXME: Collapse this into TemplateParamPosition; or, just move depth/index
@@ -1255,10 +1275,10 @@ class NonTypeTemplateParmDecl final
/// \brief Whether this non-type template parameter is an "expanded"
/// parameter pack, meaning that its type is a pack expansion and we
/// already know the set of types that expansion expands to.
- bool ExpandedParameterPack;
+ bool ExpandedParameterPack = false;
/// \brief The number of types in an expanded parameter pack.
- unsigned NumExpandedTypes;
+ unsigned NumExpandedTypes = 0;
size_t numTrailingObjects(
OverloadToken<std::pair<QualType, TypeSourceInfo *>>) const {
@@ -1269,10 +1289,8 @@ class NonTypeTemplateParmDecl final
SourceLocation IdLoc, unsigned D, unsigned P,
IdentifierInfo *Id, QualType T,
bool ParameterPack, TypeSourceInfo *TInfo)
- : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
- TemplateParmPosition(D, P), ParameterPack(ParameterPack),
- ExpandedParameterPack(false), NumExpandedTypes(0)
- { }
+ : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
+ TemplateParmPosition(D, P), ParameterPack(ParameterPack) {}
NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, unsigned D, unsigned P,
@@ -1281,9 +1299,6 @@ class NonTypeTemplateParmDecl final
ArrayRef<QualType> ExpandedTypes,
ArrayRef<TypeSourceInfo *> ExpandedTInfos);
- friend class ASTDeclReader;
- friend TrailingObjects;
-
public:
static NonTypeTemplateParmDecl *
Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
@@ -1428,11 +1443,9 @@ class TemplateTemplateParmDecl final
protected TemplateParmPosition,
private llvm::TrailingObjects<TemplateTemplateParmDecl,
TemplateParameterList *> {
- void anchor() override;
-
/// \brief The default template argument, if any.
- typedef DefaultArgStorage<TemplateTemplateParmDecl, TemplateArgumentLoc *>
- DefArgStorage;
+ using DefArgStorage =
+ DefaultArgStorage<TemplateTemplateParmDecl, TemplateArgumentLoc *>;
DefArgStorage DefaultArgument;
/// \brief Whether this parameter is a parameter pack.
@@ -1441,25 +1454,29 @@ class TemplateTemplateParmDecl final
/// \brief Whether this template template parameter is an "expanded"
/// parameter pack, meaning that it is a pack expansion and we
/// already know the set of template parameters that expansion expands to.
- bool ExpandedParameterPack;
+ bool ExpandedParameterPack = false;
/// \brief The number of parameters in an expanded parameter pack.
- unsigned NumExpandedParams;
+ unsigned NumExpandedParams = 0;
TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
unsigned D, unsigned P, bool ParameterPack,
IdentifierInfo *Id, TemplateParameterList *Params)
- : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
- TemplateParmPosition(D, P), ParameterPack(ParameterPack),
- ExpandedParameterPack(false), NumExpandedParams(0)
- { }
+ : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
+ TemplateParmPosition(D, P), ParameterPack(ParameterPack) {}
TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
unsigned D, unsigned P,
IdentifierInfo *Id, TemplateParameterList *Params,
ArrayRef<TemplateParameterList *> Expansions);
+ void anchor() override;
+
public:
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+ friend TrailingObjects;
+
static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC,
SourceLocation L, unsigned D,
unsigned P, bool ParameterPack,
@@ -1579,22 +1596,18 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == TemplateTemplateParm; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
- friend TrailingObjects;
};
/// \brief Represents the builtin template declaration which is used to
/// implement __make_integer_seq and other builtin templates. It serves
/// no real purpose beyond existing as a place to hold template parameters.
class BuiltinTemplateDecl : public TemplateDecl {
- void anchor() override;
+ BuiltinTemplateKind BTK;
BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
DeclarationName Name, BuiltinTemplateKind BTK);
- BuiltinTemplateKind BTK;
+ void anchor() override;
public:
// Implement isa/cast/dyncast support
@@ -1629,7 +1642,6 @@ public:
/// \endcode
class ClassTemplateSpecializationDecl
: public CXXRecordDecl, public llvm::FoldingSetNode {
-
/// \brief Structure that stores information about a class template
/// specialization that was instantiated from a class template partial
/// specialization.
@@ -1650,19 +1662,20 @@ class ClassTemplateSpecializationDecl
/// \brief Further info for explicit template specialization/instantiation.
struct ExplicitSpecializationInfo {
/// \brief The type-as-written.
- TypeSourceInfo *TypeAsWritten;
+ TypeSourceInfo *TypeAsWritten = nullptr;
+
/// \brief The location of the extern keyword.
SourceLocation ExternLoc;
+
/// \brief The location of the template keyword.
SourceLocation TemplateKeywordLoc;
- ExplicitSpecializationInfo()
- : TypeAsWritten(nullptr), ExternLoc(), TemplateKeywordLoc() {}
+ ExplicitSpecializationInfo() = default;
};
/// \brief Further info for explicit template specialization/instantiation.
/// Does not apply to implicit specializations.
- ExplicitSpecializationInfo *ExplicitInfo;
+ ExplicitSpecializationInfo *ExplicitInfo = nullptr;
/// \brief The template arguments used to describe this specialization.
const TemplateArgumentList *TemplateArgs;
@@ -1685,6 +1698,9 @@ protected:
explicit ClassTemplateSpecializationDecl(ASTContext &C, Kind DK);
public:
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+
static ClassTemplateSpecializationDecl *
Create(ASTContext &Context, TagKind TK, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
@@ -1828,6 +1844,7 @@ public:
ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
ExplicitInfo->TypeAsWritten = T;
}
+
/// \brief Gets the type of this specialization as it was written by
/// the user, if it was so written.
TypeSourceInfo *getTypeAsWritten() const {
@@ -1838,6 +1855,7 @@ public:
SourceLocation getExternLoc() const {
return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation();
}
+
/// \brief Sets the location of the extern keyword.
void setExternLoc(SourceLocation Loc) {
if (!ExplicitInfo)
@@ -1851,6 +1869,7 @@ public:
ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
ExplicitInfo->TemplateKeywordLoc = Loc;
}
+
/// \brief Gets the location of the template keyword, if present.
SourceLocation getTemplateKeywordLoc() const {
return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
@@ -1871,25 +1890,21 @@ public:
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+
static bool classofKind(Kind K) {
return K >= firstClassTemplateSpecialization &&
K <= lastClassTemplateSpecialization;
}
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
};
class ClassTemplatePartialSpecializationDecl
: public ClassTemplateSpecializationDecl {
- void anchor() override;
-
/// \brief The list of template parameters
- TemplateParameterList* TemplateParams;
+ TemplateParameterList* TemplateParams = nullptr;
/// \brief The source info for the template arguments as written.
/// FIXME: redundant with TypeAsWritten?
- const ASTTemplateArgumentListInfo *ArgsAsWritten;
+ const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
/// \brief The class template partial specialization from which this
/// class template partial specialization was instantiated.
@@ -1911,10 +1926,14 @@ class ClassTemplatePartialSpecializationDecl
ClassTemplatePartialSpecializationDecl(ASTContext &C)
: ClassTemplateSpecializationDecl(C, ClassTemplatePartialSpecialization),
- TemplateParams(nullptr), ArgsAsWritten(nullptr),
InstantiatedFromMember(nullptr, false) {}
+ void anchor() override;
+
public:
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+
static ClassTemplatePartialSpecializationDecl *
Create(ASTContext &Context, TagKind TK, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
@@ -2024,12 +2043,10 @@ public:
// FIXME: Add Profile support!
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+
static bool classofKind(Kind K) {
return K == ClassTemplatePartialSpecialization;
}
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
};
/// Declaration of a class template.
@@ -2038,8 +2055,6 @@ protected:
/// \brief Data that is common to all of the declarations of a given
/// class template.
struct Common : CommonBase {
- Common() : LazySpecializations() { }
-
/// \brief The class template specializations for this class
/// template, including explicit specializations and instantiations.
llvm::FoldingSetVector<ClassTemplateSpecializationDecl> Specializations;
@@ -2052,12 +2067,7 @@ protected:
/// \brief The injected-class-name type for this class template.
QualType InjectedClassNameType;
- /// \brief If non-null, points to an array of specializations (including
- /// partial specializations) known only by their external declaration IDs.
- ///
- /// The first value in the array is the number of of specializations/
- /// partial specializations that follow.
- uint32_t *LazySpecializations;
+ Common() = default;
};
/// \brief Retrieve the set of specializations of this class template.
@@ -2087,12 +2097,15 @@ protected:
}
public:
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+
/// \brief Load any lazily-loaded specializations from the external source.
void LoadLazySpecializations() const;
/// \brief Get the underlying class declarations of the template.
CXXRecordDecl *getTemplatedDecl() const {
- return static_cast<CXXRecordDecl *>(TemplatedDecl.getPointer());
+ return static_cast<CXXRecordDecl *>(TemplatedDecl);
}
/// \brief Returns whether this template declaration defines the primary
@@ -2132,14 +2145,11 @@ public:
}
/// \brief Retrieve the previous declaration of this class template, or
- /// NULL if no such declaration exists.
+ /// nullptr if no such declaration exists.
ClassTemplateDecl *getPreviousDecl() {
return cast_or_null<ClassTemplateDecl>(
static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
}
-
- /// \brief Retrieve the previous declaration of this class template, or
- /// NULL if no such declaration exists.
const ClassTemplateDecl *getPreviousDecl() const {
return cast_or_null<ClassTemplateDecl>(
static_cast<const RedeclarableTemplateDecl *>(
@@ -2180,7 +2190,7 @@ public:
/// template.
///
/// \returns the class template partial specialization that exactly matches
- /// the type \p T, or NULL if no such partial specialization exists.
+ /// the type \p T, or nullptr if no such partial specialization exists.
ClassTemplatePartialSpecializationDecl *findPartialSpecialization(QualType T);
/// \brief Find a class template partial specialization which was instantiated
@@ -2189,8 +2199,8 @@ public:
/// \param D a member class template partial specialization.
///
/// \returns the class template partial specialization which was instantiated
- /// from the given member partial specialization, or NULL if no such partial
- /// specialization exists.
+ /// from the given member partial specialization, or nullptr if no such
+ /// partial specialization exists.
ClassTemplatePartialSpecializationDecl *
findPartialSpecInstantiatedFromMember(
ClassTemplatePartialSpecializationDecl *D);
@@ -2211,8 +2221,8 @@ public:
/// \endcode
QualType getInjectedClassNameSpecialization();
- typedef SpecIterator<ClassTemplateSpecializationDecl> spec_iterator;
- typedef llvm::iterator_range<spec_iterator> spec_range;
+ using spec_iterator = SpecIterator<ClassTemplateSpecializationDecl>;
+ using spec_range = llvm::iterator_range<spec_iterator>;
spec_range specializations() const {
return spec_range(spec_begin(), spec_end());
@@ -2229,9 +2239,6 @@ public:
// Implement isa/cast/dyncast support
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == ClassTemplate; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
};
/// \brief Declaration of a friend template.
@@ -2249,15 +2256,16 @@ public:
/// will yield a FriendDecl, not a FriendTemplateDecl.
class FriendTemplateDecl : public Decl {
virtual void anchor();
+
public:
- typedef llvm::PointerUnion<NamedDecl*,TypeSourceInfo*> FriendUnion;
+ using FriendUnion = llvm::PointerUnion<NamedDecl *,TypeSourceInfo *>;
private:
// The number of template parameters; always non-zero.
- unsigned NumParams;
+ unsigned NumParams = 0;
// The parameter list.
- TemplateParameterList **Params;
+ TemplateParameterList **Params = nullptr;
// The declaration that's a friend of this class.
FriendUnion Friend;
@@ -2271,13 +2279,11 @@ private:
: Decl(Decl::FriendTemplate, DC, Loc), NumParams(Params.size()),
Params(Params.data()), Friend(Friend), FriendLoc(FriendLoc) {}
- FriendTemplateDecl(EmptyShell Empty)
- : Decl(Decl::FriendTemplate, Empty),
- NumParams(0),
- Params(nullptr)
- {}
+ FriendTemplateDecl(EmptyShell Empty) : Decl(Decl::FriendTemplate, Empty) {}
public:
+ friend class ASTDeclReader;
+
static FriendTemplateDecl *
Create(ASTContext &Context, DeclContext *DC, SourceLocation Loc,
MutableArrayRef<TemplateParameterList *> Params, FriendUnion Friend,
@@ -2316,8 +2322,6 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == Decl::FriendTemplate; }
-
- friend class ASTDeclReader;
};
/// \brief Declaration of an alias template.
@@ -2328,7 +2332,7 @@ public:
/// \endcode
class TypeAliasTemplateDecl : public RedeclarableTemplateDecl {
protected:
- typedef CommonBase Common;
+ using Common = CommonBase;
TypeAliasTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
DeclarationName Name, TemplateParameterList *Params,
@@ -2343,9 +2347,12 @@ protected:
}
public:
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+
/// Get the underlying function declaration of the template.
TypeAliasDecl *getTemplatedDecl() const {
- return static_cast<TypeAliasDecl *>(TemplatedDecl.getPointer());
+ return static_cast<TypeAliasDecl *>(TemplatedDecl);
}
@@ -2359,14 +2366,11 @@ public:
}
/// \brief Retrieve the previous declaration of this function template, or
- /// NULL if no such declaration exists.
+ /// nullptr if no such declaration exists.
TypeAliasTemplateDecl *getPreviousDecl() {
return cast_or_null<TypeAliasTemplateDecl>(
static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
}
-
- /// \brief Retrieve the previous declaration of this function template, or
- /// NULL if no such declaration exists.
const TypeAliasTemplateDecl *getPreviousDecl() const {
return cast_or_null<TypeAliasTemplateDecl>(
static_cast<const RedeclarableTemplateDecl *>(
@@ -2378,7 +2382,6 @@ public:
RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
}
-
/// \brief Create a function template node.
static TypeAliasTemplateDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
@@ -2392,9 +2395,6 @@ public:
// Implement isa/cast/dyncast support
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == TypeAliasTemplate; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
};
/// \brief Declaration of a function specialization at template class scope.
@@ -2414,7 +2414,9 @@ public:
/// CXXMethodDecl. Then during an instantiation of class A, it will be
/// transformed into an actual function specialization.
class ClassScopeFunctionSpecializationDecl : public Decl {
- virtual void anchor();
+ CXXMethodDecl *Specialization;
+ bool HasExplicitTemplateArgs;
+ TemplateArgumentListInfo TemplateArgs;
ClassScopeFunctionSpecializationDecl(DeclContext *DC, SourceLocation Loc,
CXXMethodDecl *FD, bool Args,
@@ -2424,13 +2426,14 @@ class ClassScopeFunctionSpecializationDecl : public Decl {
TemplateArgs(std::move(TemplArgs)) {}
ClassScopeFunctionSpecializationDecl(EmptyShell Empty)
- : Decl(Decl::ClassScopeFunctionSpecialization, Empty) {}
+ : Decl(Decl::ClassScopeFunctionSpecialization, Empty) {}
- CXXMethodDecl *Specialization;
- bool HasExplicitTemplateArgs;
- TemplateArgumentListInfo TemplateArgs;
+ virtual void anchor();
public:
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+
CXXMethodDecl *getSpecialization() const { return Specialization; }
bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; }
const TemplateArgumentListInfo& templateArgs() const { return TemplateArgs; }
@@ -2450,17 +2453,15 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+
static bool classofKind(Kind K) {
return K == Decl::ClassScopeFunctionSpecialization;
}
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
};
/// Implementation of inline functions that require the template declarations
inline AnyFunctionDecl::AnyFunctionDecl(FunctionTemplateDecl *FTD)
- : Function(FTD) { }
+ : Function(FTD) {}
/// \brief Represents a variable template specialization, which refers to
/// a variable template with a given set of template arguments.
@@ -2498,19 +2499,20 @@ class VarTemplateSpecializationDecl : public VarDecl,
/// \brief Further info for explicit template specialization/instantiation.
struct ExplicitSpecializationInfo {
/// \brief The type-as-written.
- TypeSourceInfo *TypeAsWritten;
+ TypeSourceInfo *TypeAsWritten = nullptr;
+
/// \brief The location of the extern keyword.
SourceLocation ExternLoc;
+
/// \brief The location of the template keyword.
SourceLocation TemplateKeywordLoc;
- ExplicitSpecializationInfo()
- : TypeAsWritten(nullptr), ExternLoc(), TemplateKeywordLoc() {}
+ ExplicitSpecializationInfo() = default;
};
/// \brief Further info for explicit template specialization/instantiation.
/// Does not apply to implicit specializations.
- ExplicitSpecializationInfo *ExplicitInfo;
+ ExplicitSpecializationInfo *ExplicitInfo = nullptr;
/// \brief The template arguments used to describe this specialization.
const TemplateArgumentList *TemplateArgs;
@@ -2523,6 +2525,12 @@ class VarTemplateSpecializationDecl : public VarDecl,
/// Really a value of type TemplateSpecializationKind.
unsigned SpecializationKind : 3;
+ /// \brief Whether this declaration is a complete definition of the
+ /// variable template specialization. We can't otherwise tell apart
+ /// an instantiated declaration from an instantiated definition with
+ /// no initializer.
+ unsigned IsCompleteDefinition : 1;
+
protected:
VarTemplateSpecializationDecl(Kind DK, ASTContext &Context, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
@@ -2534,6 +2542,10 @@ protected:
explicit VarTemplateSpecializationDecl(Kind DK, ASTContext &Context);
public:
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+ friend class VarDecl;
+
static VarTemplateSpecializationDecl *
Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
@@ -2596,6 +2608,8 @@ public:
PointOfInstantiation = Loc;
}
+ void setCompleteDefinition() { IsCompleteDefinition = true; }
+
/// \brief If this variable template specialization is an instantiation of
/// a template (rather than an explicit specialization), return the
/// variable template or variable template partial specialization from which
@@ -2668,6 +2682,7 @@ public:
ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
ExplicitInfo->TypeAsWritten = T;
}
+
/// \brief Gets the type of this specialization as it was written by
/// the user, if it was so written.
TypeSourceInfo *getTypeAsWritten() const {
@@ -2678,6 +2693,7 @@ public:
SourceLocation getExternLoc() const {
return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation();
}
+
/// \brief Sets the location of the extern keyword.
void setExternLoc(SourceLocation Loc) {
if (!ExplicitInfo)
@@ -2691,6 +2707,7 @@ public:
ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
ExplicitInfo->TemplateKeywordLoc = Loc;
}
+
/// \brief Gets the location of the template keyword, if present.
SourceLocation getTemplateKeywordLoc() const {
return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
@@ -2709,25 +2726,21 @@ public:
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+
static bool classofKind(Kind K) {
return K >= firstVarTemplateSpecialization &&
K <= lastVarTemplateSpecialization;
}
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
};
class VarTemplatePartialSpecializationDecl
: public VarTemplateSpecializationDecl {
- void anchor() override;
-
/// \brief The list of template parameters
- TemplateParameterList *TemplateParams;
+ TemplateParameterList *TemplateParams = nullptr;
/// \brief The source info for the template arguments as written.
/// FIXME: redundant with TypeAsWritten?
- const ASTTemplateArgumentListInfo *ArgsAsWritten;
+ const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
/// \brief The variable template partial specialization from which this
/// variable template partial specialization was instantiated.
@@ -2745,11 +2758,16 @@ class VarTemplatePartialSpecializationDecl
const ASTTemplateArgumentListInfo *ArgInfos);
VarTemplatePartialSpecializationDecl(ASTContext &Context)
- : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context),
- TemplateParams(nullptr), ArgsAsWritten(nullptr),
- InstantiatedFromMember(nullptr, false) {}
+ : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization,
+ Context),
+ InstantiatedFromMember(nullptr, false) {}
+
+ void anchor() override;
public:
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+
static VarTemplatePartialSpecializationDecl *
Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, TemplateParameterList *Params,
@@ -2841,12 +2859,10 @@ public:
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+
static bool classofKind(Kind K) {
return K == VarTemplatePartialSpecialization;
}
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
};
/// Declaration of a variable template.
@@ -2855,8 +2871,6 @@ protected:
/// \brief Data that is common to all of the declarations of a given
/// variable template.
struct Common : CommonBase {
- Common() : LazySpecializations() {}
-
/// \brief The variable template specializations for this variable
/// template, including explicit specializations and instantiations.
llvm::FoldingSetVector<VarTemplateSpecializationDecl> Specializations;
@@ -2866,12 +2880,7 @@ protected:
llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>
PartialSpecializations;
- /// \brief If non-null, points to an array of specializations (including
- /// partial specializations) known ownly by their external declaration IDs.
- ///
- /// The first value in the array is the number of of specializations/
- /// partial specializations that follow.
- uint32_t *LazySpecializations;
+ Common() = default;
};
/// \brief Retrieve the set of specializations of this variable template.
@@ -2895,12 +2904,15 @@ protected:
}
public:
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+
/// \brief Load any lazily-loaded specializations from the external source.
void LoadLazySpecializations() const;
/// \brief Get the underlying variable declarations of the template.
VarDecl *getTemplatedDecl() const {
- return static_cast<VarDecl *>(TemplatedDecl.getPointer());
+ return static_cast<VarDecl *>(TemplatedDecl);
}
/// \brief Returns whether this template declaration defines the primary
@@ -2937,14 +2949,11 @@ public:
}
/// \brief Retrieve the previous declaration of this variable template, or
- /// NULL if no such declaration exists.
+ /// nullptr if no such declaration exists.
VarTemplateDecl *getPreviousDecl() {
return cast_or_null<VarTemplateDecl>(
static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
}
-
- /// \brief Retrieve the previous declaration of this variable template, or
- /// NULL if no such declaration exists.
const VarTemplateDecl *getPreviousDecl() const {
return cast_or_null<VarTemplateDecl>(
static_cast<const RedeclarableTemplateDecl *>(
@@ -2986,13 +2995,13 @@ public:
///
/// \returns the variable template partial specialization which was
/// instantiated
- /// from the given member partial specialization, or NULL if no such partial
- /// specialization exists.
+ /// from the given member partial specialization, or nullptr if no such
+ /// partial specialization exists.
VarTemplatePartialSpecializationDecl *findPartialSpecInstantiatedFromMember(
VarTemplatePartialSpecializationDecl *D);
- typedef SpecIterator<VarTemplateSpecializationDecl> spec_iterator;
- typedef llvm::iterator_range<spec_iterator> spec_range;
+ using spec_iterator = SpecIterator<VarTemplateSpecializationDecl>;
+ using spec_range = llvm::iterator_range<spec_iterator>;
spec_range specializations() const {
return spec_range(spec_begin(), spec_end());
@@ -3009,9 +3018,6 @@ public:
// Implement isa/cast/dyncast support
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == VarTemplate; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
};
inline NamedDecl *getAsNamedDecl(TemplateParameter P) {
@@ -3032,6 +3038,6 @@ inline TemplateDecl *getAsTypeTemplateDecl(Decl *D) {
: nullptr;
}
-} /* end of namespace clang */
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_AST_DECLTEMPLATE_H
diff --git a/include/clang/AST/DeclVisitor.h b/include/clang/AST/DeclVisitor.h
index 4eaae35778b9..3ff274bd6a7a 100644
--- a/include/clang/AST/DeclVisitor.h
+++ b/include/clang/AST/DeclVisitor.h
@@ -1,4 +1,4 @@
-//===--- DeclVisitor.h - Visitor for Decl subclasses ------------*- C++ -*-===//
+//===- DeclVisitor.h - Visitor for Decl subclasses --------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,27 +10,30 @@
// This file defines the DeclVisitor interface.
//
//===----------------------------------------------------------------------===//
+
#ifndef LLVM_CLANG_AST_DECLVISITOR_H
#define LLVM_CLANG_AST_DECLVISITOR_H
#include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclFriend.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclOpenMP.h"
#include "clang/AST/DeclTemplate.h"
+#include "llvm/Support/ErrorHandling.h"
namespace clang {
+
namespace declvisitor {
-template <typename T> struct make_ptr { typedef T *type; };
-template <typename T> struct make_const_ptr { typedef const T *type; };
+template <typename T> struct make_ptr { using type = T *; };
+template <typename T> struct make_const_ptr { using type = const T *; };
/// \brief A simple visitor class that helps create declaration visitors.
template<template <typename> class Ptr, typename ImplClass, typename RetTy=void>
class Base {
public:
-
#define PTR(CLASS) typename Ptr<CLASS>::type
#define DISPATCH(NAME, CLASS) \
return static_cast<ImplClass*>(this)->Visit##NAME(static_cast<PTR(CLASS)>(D))
@@ -57,23 +60,23 @@ public:
#undef DISPATCH
};
-} // end namespace declvisitor
+} // namespace declvisitor
/// \brief A simple visitor class that helps create declaration visitors.
///
/// 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> {};
/// \brief 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> {};
-} // end namespace clang
+} // namespace clang
#endif // LLVM_CLANG_AST_DECLVISITOR_H
diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h
index 5e773c968384..467b02c52b0c 100644
--- a/include/clang/AST/DeclarationName.h
+++ b/include/clang/AST/DeclarationName.h
@@ -1,4 +1,4 @@
-//===-- DeclarationName.h - Representation of declaration names -*- C++ -*-===//
+//===- DeclarationName.h - Representation of declaration names --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,36 +10,42 @@
// This file declares the DeclarationName and DeclarationNameTable classes.
//
//===----------------------------------------------------------------------===//
+
#ifndef LLVM_CLANG_AST_DECLARATIONNAME_H
#define LLVM_CLANG_AST_DECLARATIONNAME_H
+#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/Support/Compiler.h"
-
-namespace llvm {
- template <typename T> struct DenseMapInfo;
-}
+#include "llvm/Support/type_traits.h"
+#include <cassert>
+#include <cstdint>
+#include <cstring>
+#include <string>
namespace clang {
- class ASTContext;
- class CXXDeductionGuideNameExtra;
- class CXXLiteralOperatorIdName;
- class CXXOperatorIdName;
- class CXXSpecialName;
- class DeclarationNameExtra;
- class IdentifierInfo;
- class MultiKeywordSelector;
- enum OverloadedOperatorKind : int;
- struct PrintingPolicy;
- class QualType;
- class TemplateDecl;
- class Type;
- class TypeSourceInfo;
- class UsingDirectiveDecl;
-
- template <typename> class CanQual;
- typedef CanQual<Type> CanQualType;
+
+class ASTContext;
+template <typename> class CanQual;
+class CXXDeductionGuideNameExtra;
+class CXXLiteralOperatorIdName;
+class CXXOperatorIdName;
+class CXXSpecialName;
+class DeclarationNameExtra;
+class IdentifierInfo;
+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
@@ -63,9 +69,13 @@ public:
CXXLiteralOperatorName,
CXXUsingDirective
};
+
static const unsigned NumNameKinds = CXXUsingDirective + 1;
private:
+ friend class DeclarationNameTable;
+ friend class NamedDecl;
+
/// StoredNameKind - The kind of name that is actually stored in the
/// upper bits of the Ptr field. This is only used internally.
///
@@ -99,7 +109,18 @@ private:
/// DeclarationNameExtra structure, whose first value will tell us
/// whether this is an Objective-C selector, C++ operator-id name,
/// or special C++ name.
- uintptr_t Ptr;
+ 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;
+ }
+
+ /// Construct a declaration name from a raw pointer.
+ DeclarationName(uintptr_t Ptr) : Ptr(Ptr) {}
/// getStoredNameKind - Return the kind of object that is stored in
/// Ptr.
@@ -146,36 +167,22 @@ private:
return nullptr;
}
- // 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;
- }
-
- /// Construct a declaration name from a raw pointer.
- DeclarationName(uintptr_t Ptr) : Ptr(Ptr) { }
-
- friend class DeclarationNameTable;
- friend class NamedDecl;
-
/// getFETokenInfoAsVoidSlow - Retrieves the front end-specified pointer
/// for this name as a void pointer if it's not an identifier.
void *getFETokenInfoAsVoidSlow() const;
public:
/// DeclarationName - Used to create an empty selector.
- DeclarationName() : Ptr(0) { }
+ DeclarationName() = default;
// Construct a declaration name from an IdentifierInfo *.
DeclarationName(const IdentifierInfo *II)
- : Ptr(reinterpret_cast<uintptr_t>(II)) {
+ : Ptr(reinterpret_cast<uintptr_t>(II)) {
assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
}
// Construct a declaration name from an Objective-C selector.
- DeclarationName(Selector Sel) : Ptr(Sel.InfoPtr) { }
+ DeclarationName(Selector Sel) : Ptr(Sel.InfoPtr) {}
/// getUsingDirectiveName - Return name for all using-directives.
static DeclarationName getUsingDirectiveName();
@@ -344,16 +351,24 @@ inline bool operator>=(DeclarationName LHS, DeclarationName RHS) {
/// getCXXConstructorName).
class DeclarationNameTable {
const ASTContext &Ctx;
- void *CXXSpecialNamesImpl; // Actually a FoldingSet<CXXSpecialName> *
- CXXOperatorIdName *CXXOperatorNames; // Operator names
- void *CXXLiteralOperatorNames; // Actually a CXXOperatorIdName*
- void *CXXDeductionGuideNames; // FoldingSet<CXXDeductionGuideNameExtra> *
- DeclarationNameTable(const DeclarationNameTable&) = delete;
- void operator=(const DeclarationNameTable&) = delete;
+ // Actually a FoldingSet<CXXSpecialName> *
+ void *CXXSpecialNamesImpl;
+
+ // Operator names
+ CXXOperatorIdName *CXXOperatorNames;
+
+ // Actually a CXXOperatorIdName*
+ void *CXXLiteralOperatorNames;
+
+ // FoldingSet<CXXDeductionGuideNameExtra> *
+ void *CXXDeductionGuideNames;
public:
DeclarationNameTable(const ASTContext &C);
+ DeclarationNameTable(const DeclarationNameTable &) = delete;
+ DeclarationNameTable &operator=(const DeclarationNameTable &) = delete;
+
~DeclarationNameTable();
/// getIdentifier - Create a declaration name that is a simple
@@ -428,10 +443,10 @@ struct DeclarationNameLoc {
};
DeclarationNameLoc(DeclarationName Name);
+
// FIXME: this should go away once all DNLocs are properly initialized.
DeclarationNameLoc() { memset((void*) this, 0, sizeof(*this)); }
-}; // struct DeclarationNameLoc
-
+};
/// DeclarationNameInfo - A collector data type for bundling together
/// a DeclarationName and the correspnding source/type location info.
@@ -439,29 +454,33 @@ struct DeclarationNameInfo {
private:
/// Name - The declaration name, also encoding name kind.
DeclarationName Name;
+
/// Loc - The main source location for the declaration name.
SourceLocation NameLoc;
+
/// Info - Further source/type location info for special kinds of names.
DeclarationNameLoc LocInfo;
public:
// FIXME: remove it.
- DeclarationNameInfo() {}
+ DeclarationNameInfo() = default;
DeclarationNameInfo(DeclarationName Name, SourceLocation NameLoc)
- : Name(Name), NameLoc(NameLoc), LocInfo(Name) {}
+ : Name(Name), NameLoc(NameLoc), LocInfo(Name) {}
DeclarationNameInfo(DeclarationName Name, SourceLocation NameLoc,
DeclarationNameLoc LocInfo)
- : Name(Name), NameLoc(NameLoc), LocInfo(LocInfo) {}
+ : Name(Name), NameLoc(NameLoc), LocInfo(LocInfo) {}
/// getName - Returns the embedded declaration name.
DeclarationName getName() const { return Name; }
+
/// setName - Sets the embedded declaration name.
void setName(DeclarationName N) { Name = N; }
/// getLoc - Returns the main location of the declaration name.
SourceLocation getLoc() const { return NameLoc; }
+
/// setLoc - Sets the main location of the declaration name.
void setLoc(SourceLocation L) { NameLoc = L; }
@@ -477,6 +496,7 @@ public:
Name.getNameKind() == DeclarationName::CXXConversionFunctionName);
return LocInfo.NamedType.TInfo;
}
+
/// setNamedTypeInfo - Sets the source type info associated to
/// the name. Assumes it is a constructor, destructor or conversion.
void setNamedTypeInfo(TypeSourceInfo *TInfo) {
@@ -495,6 +515,7 @@ public:
SourceLocation::getFromRawEncoding(LocInfo.CXXOperatorName.EndOpNameLoc)
);
}
+
/// setCXXOperatorNameRange - Sets the range of the operator name
/// (without the operator keyword). Assumes it is a C++ operator.
void setCXXOperatorNameRange(SourceRange R) {
@@ -511,6 +532,7 @@ public:
return SourceLocation::
getFromRawEncoding(LocInfo.CXXLiteralOperatorName.OpNameLoc);
}
+
/// setCXXLiteralOperatorNameLoc - Sets the location of the literal
/// operator name (not the operator keyword).
/// Assumes it is a literal operator.
@@ -534,15 +556,19 @@ 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;
+
/// getSourceRange - The range of the declaration name.
SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(getLocStart(), getLocEnd());
}
+
SourceLocation getLocStart() const LLVM_READONLY {
return getBeginLoc();
}
+
SourceLocation getLocEnd() const LLVM_READONLY {
SourceLocation EndLoc = getEndLoc();
return EndLoc.isValid() ? EndLoc : getLocStart();
@@ -573,9 +599,10 @@ inline raw_ostream &operator<<(raw_ostream &OS,
return OS;
}
-} // end namespace clang
+} // namespace clang
namespace llvm {
+
/// Define DenseMapInfo so that DeclarationNames can be used as keys
/// in DenseMap and DenseSets.
template<>
@@ -601,6 +628,6 @@ struct DenseMapInfo<clang::DeclarationName> {
template <>
struct isPodLike<clang::DeclarationName> { static const bool value = true; };
-} // end namespace llvm
+} // namespace llvm
-#endif
+#endif // LLVM_CLANG_AST_DECLARATIONNAME_H
diff --git a/include/clang/AST/DependentDiagnostic.h b/include/clang/AST/DependentDiagnostic.h
index 8e038c83c989..a514326c6cb1 100644
--- a/include/clang/AST/DependentDiagnostic.h
+++ b/include/clang/AST/DependentDiagnostic.h
@@ -1,4 +1,4 @@
-//===-- DependentDiagnostic.h - Dependently-generated diagnostics -*- C++ -*-=//
+//==- DependentDiagnostic.h - Dependently-generated diagnostics --*- C++ -*-==//
//
// The LLVM Compiler Infrastructure
//
@@ -23,6 +23,9 @@
#include "clang/AST/Type.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/Specifiers.h"
+#include <cassert>
+#include <iterator>
namespace clang {
@@ -94,6 +97,9 @@ public:
}
private:
+ friend class DeclContext::ddiag_iterator;
+ friend class DependentStoredDeclsMap;
+
DependentDiagnostic(const PartialDiagnostic &PDiag,
PartialDiagnostic::Storage *Storage)
: Diag(PDiag, Storage) {}
@@ -102,8 +108,6 @@ private:
DeclContext *Parent,
const PartialDiagnostic &PDiag);
- friend class DependentStoredDeclsMap;
- friend class DeclContext::ddiag_iterator;
DependentDiagnostic *NextDiagnostic;
PartialDiagnostic Diag;
@@ -118,19 +122,17 @@ private:
} AccessData;
};
-///
-
/// An iterator over the dependent diagnostics in a dependent context.
class DeclContext::ddiag_iterator {
public:
- ddiag_iterator() : Ptr(nullptr) {}
+ ddiag_iterator() = default;
explicit ddiag_iterator(DependentDiagnostic *Ptr) : Ptr(Ptr) {}
- typedef DependentDiagnostic *value_type;
- typedef DependentDiagnostic *reference;
- typedef DependentDiagnostic *pointer;
- typedef int difference_type;
- typedef std::forward_iterator_tag iterator_category;
+ using value_type = DependentDiagnostic *;
+ using reference = DependentDiagnostic *;
+ using pointer = DependentDiagnostic *;
+ using difference_type = int;
+ using iterator_category = std::forward_iterator_tag;
reference operator*() const { return Ptr; }
@@ -168,7 +170,7 @@ public:
}
private:
- DependentDiagnostic *Ptr;
+ DependentDiagnostic *Ptr = nullptr;
};
inline DeclContext::ddiag_range DeclContext::ddiags() const {
@@ -184,6 +186,6 @@ inline DeclContext::ddiag_range DeclContext::ddiags() const {
return ddiag_range(ddiag_iterator(Map->FirstDiagnostic), ddiag_iterator());
}
-}
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_AST_DEPENDENTDIAGNOSTIC_H
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 0cdbd2a97ee4..f2770940372f 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -24,6 +24,7 @@
#include "clang/AST/Type.h"
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SyncScope.h"
#include "clang/Basic/TypeTraits.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APSInt.h"
@@ -274,6 +275,7 @@ public:
MLV_LValueCast, // Specialized form of MLV_InvalidExpression.
MLV_IncompleteType,
MLV_ConstQualified,
+ MLV_ConstQualifiedField,
MLV_ConstAddrSpace,
MLV_ArrayType,
MLV_NoSetterProperty,
@@ -323,6 +325,7 @@ public:
CM_LValueCast, // Same as CM_RValue, but indicates GCC cast-as-lvalue ext
CM_NoSetterProperty,// Implicit assignment to ObjC property without setter
CM_ConstQualified,
+ CM_ConstQualifiedField,
CM_ConstAddrSpace,
CM_ArrayType,
CM_IncompleteType
@@ -2345,6 +2348,12 @@ public:
SourceLocation getLocStart() const LLVM_READONLY;
SourceLocation getLocEnd() const LLVM_READONLY;
+ bool isCallToStdMove() const {
+ const FunctionDecl* FD = getDirectCallee();
+ return getNumArgs() == 1 && FD && FD->isInStdNamespace() &&
+ FD->getIdentifier() && FD->getIdentifier()->isStr("move");
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() >= firstCallExprConstant &&
T->getStmtClass() <= lastCallExprConstant;
@@ -2733,7 +2742,6 @@ protected:
ty->containsUnexpandedParameterPack()) ||
(op && op->containsUnexpandedParameterPack()))),
Op(op) {
- assert(kind != CK_Invalid && "creating cast with invalid cast kind");
CastExprBits.Kind = kind;
setBasePathSize(BasePathSize);
assert(CastConsistency());
@@ -2771,6 +2779,16 @@ public:
path_const_iterator path_begin() const { return path_buffer(); }
path_const_iterator path_end() const { return path_buffer() + path_size(); }
+ const FieldDecl *getTargetUnionField() const {
+ assert(getCastKind() == CK_ToUnion);
+ return getTargetFieldForToUnionCast(getType(), getSubExpr()->getType());
+ }
+
+ static const FieldDecl *getTargetFieldForToUnionCast(QualType unionType,
+ QualType opType);
+ static const FieldDecl *getTargetFieldForToUnionCast(const RecordDecl *RD,
+ QualType opType);
+
static bool classof(const Stmt *T) {
return T->getStmtClass() >= firstCastExprConstant &&
T->getStmtClass() <= lastCastExprConstant;
@@ -3054,7 +3072,7 @@ public:
static bool isEqualityOp(Opcode Opc) { return Opc == BO_EQ || Opc == BO_NE; }
bool isEqualityOp() const { return isEqualityOp(getOpcode()); }
- static bool isComparisonOp(Opcode Opc) { return Opc >= BO_LT && Opc<=BO_NE; }
+ static bool isComparisonOp(Opcode Opc) { return Opc >= BO_Cmp && Opc<=BO_NE; }
bool isComparisonOp() const { return isComparisonOp(getOpcode()); }
static Opcode negateComparisonOp(Opcode Opc) {
@@ -3113,6 +3131,12 @@ public:
return isShiftAssignOp(getOpcode());
}
+ // Return true if a binary operator using the specified opcode and operands
+ // would match the 'p = (i8*)nullptr + n' idiom for casting a pointer-sized
+ // integer to a pointer.
+ static bool isNullPointerArithmeticExtension(ASTContext &Ctx, Opcode Opc,
+ Expr *LHS, Expr *RHS);
+
static bool classof(const Stmt *S) {
return S->getStmtClass() >= firstBinaryOperatorConstant &&
S->getStmtClass() <= lastBinaryOperatorConstant;
@@ -3986,6 +4010,10 @@ public:
/// initializer)?
bool isTransparent() const;
+ /// Is this the zero initializer {0} in a language which considers it
+ /// idiomatic?
+ bool isIdiomaticZeroInitializer(const LangOptions &LangOpts) const;
+
SourceLocation getLBraceLoc() const { return LBraceLoc; }
void setLBraceLoc(SourceLocation Loc) { LBraceLoc = Loc; }
SourceLocation getRBraceLoc() const { return RBraceLoc; }
@@ -3995,6 +4023,9 @@ public:
InitListExpr *getSemanticForm() const {
return isSemanticForm() ? nullptr : AltForm.getPointer();
}
+ bool isSyntacticForm() const {
+ return !AltForm.getInt() || !AltForm.getPointer();
+ }
InitListExpr *getSyntacticForm() const {
return isSemanticForm() ? AltForm.getPointer() : nullptr;
}
@@ -5064,9 +5095,11 @@ public:
/// AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*,
/// __atomic_load, __atomic_store, and __atomic_compare_exchange_*, for the
-/// similarly-named C++11 instructions, and __c11 variants for <stdatomic.h>.
-/// All of these instructions take one primary pointer and at least one memory
-/// order.
+/// similarly-named C++11 instructions, and __c11 variants for <stdatomic.h>,
+/// and corresponding __opencl_atomic_* for OpenCL 2.0.
+/// All of these instructions take one primary pointer, at least one memory
+/// order. The instructions for which getScopeModel returns non-null value
+/// take one synch scope.
class AtomicExpr : public Expr {
public:
enum AtomicOp {
@@ -5078,14 +5111,16 @@ public:
};
private:
+ /// \brief Location of sub-expressions.
+ /// The location of Scope sub-expression is NumSubExprs - 1, which is
+ /// not fixed, therefore is not defined in enum.
enum { PTR, ORDER, VAL1, ORDER_FAIL, VAL2, WEAK, END_EXPR };
- Stmt* SubExprs[END_EXPR];
+ Stmt *SubExprs[END_EXPR + 1];
unsigned NumSubExprs;
SourceLocation BuiltinLoc, RParenLoc;
AtomicOp Op;
friend class ASTStmtReader;
-
public:
AtomicExpr(SourceLocation BLoc, ArrayRef<Expr*> args, QualType t,
AtomicOp op, SourceLocation RP);
@@ -5103,8 +5138,12 @@ public:
Expr *getOrder() const {
return cast<Expr>(SubExprs[ORDER]);
}
+ Expr *getScope() const {
+ assert(getScopeModel() && "No scope");
+ return cast<Expr>(SubExprs[NumSubExprs - 1]);
+ }
Expr *getVal1() const {
- if (Op == AO__c11_atomic_init)
+ if (Op == AO__c11_atomic_init || Op == AO__opencl_atomic_init)
return cast<Expr>(SubExprs[ORDER]);
assert(NumSubExprs > VAL1);
return cast<Expr>(SubExprs[VAL1]);
@@ -5123,6 +5162,7 @@ public:
assert(NumSubExprs > WEAK);
return cast<Expr>(SubExprs[WEAK]);
}
+ QualType getValueType() const;
AtomicOp getOp() const { return Op; }
unsigned getNumSubExprs() const { return NumSubExprs; }
@@ -5139,10 +5179,17 @@ public:
bool isCmpXChg() const {
return getOp() == AO__c11_atomic_compare_exchange_strong ||
getOp() == AO__c11_atomic_compare_exchange_weak ||
+ getOp() == AO__opencl_atomic_compare_exchange_strong ||
+ getOp() == AO__opencl_atomic_compare_exchange_weak ||
getOp() == AO__atomic_compare_exchange ||
getOp() == AO__atomic_compare_exchange_n;
}
+ bool isOpenCL() const {
+ return getOp() >= AO__opencl_atomic_init &&
+ getOp() <= AO__opencl_atomic_fetch_max;
+ }
+
SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
SourceLocation getRParenLoc() const { return RParenLoc; }
@@ -5160,6 +5207,24 @@ public:
const_child_range children() const {
return const_child_range(SubExprs, SubExprs + NumSubExprs);
}
+
+ /// \brief Get atomic scope model for the atomic op code.
+ /// \return empty atomic scope model if the atomic op code does not have
+ /// scope operand.
+ static std::unique_ptr<AtomicScopeModel> getScopeModel(AtomicOp Op) {
+ auto Kind =
+ (Op >= AO__opencl_atomic_load && Op <= AO__opencl_atomic_fetch_max)
+ ? AtomicScopeModelKind::OpenCL
+ : AtomicScopeModelKind::None;
+ return AtomicScopeModel::create(Kind);
+ }
+
+ /// \brief Get atomic scope model.
+ /// \return empty atomic scope model if this atomic expression does not have
+ /// scope operand.
+ std::unique_ptr<AtomicScopeModel> getScopeModel() const {
+ return getScopeModel(getOp());
+ }
};
/// TypoExpr - Internal placeholder for expressions where typo correction
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 79d2c58099c4..58054dda31aa 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -1,4 +1,4 @@
-//===--- ExprCXX.h - Classes for representing expressions -------*- C++ -*-===//
+//===- ExprCXX.h - Classes for representing expressions ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,31 +6,57 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-///
+//
/// \file
/// \brief Defines the clang::Expr interface and subclasses for C++ expressions.
-///
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_EXPRCXX_H
#define LLVM_CLANG_AST_EXPRCXX_H
#include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclarationName.h"
#include "clang/AST/Expr.h"
-#include "clang/AST/LambdaCapture.h"
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/OperationKinds.h"
+#include "clang/AST/Stmt.h"
#include "clang/AST/TemplateBase.h"
+#include "clang/AST/Type.h"
#include "clang/AST/UnresolvedSet.h"
+#include "clang/Basic/ExceptionSpecificationType.h"
#include "clang/Basic/ExpressionTraits.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/Lambda.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/OperatorKinds.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/Specifiers.h"
#include "clang/Basic/TypeTraits.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/TrailingObjects.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <memory>
namespace clang {
-class CXXTemporary;
-class MSPropertyDecl;
-class TemplateArgumentListInfo;
-class UuidAttr;
+class ASTContext;
+class DeclAccessPair;
+class IdentifierInfo;
+class LambdaCapture;
+class NonTypeTemplateParmDecl;
+class TemplateParameterList;
//===--------------------------------------------------------------------===//
// C++ Expressions.
@@ -52,23 +78,28 @@ class UuidAttr;
class CXXOperatorCallExpr : public CallExpr {
/// \brief The overloaded operator.
OverloadedOperatorKind Operator;
+
SourceRange Range;
// Only meaningful for floating point types.
FPOptions FPFeatures;
SourceRange getSourceRangeImpl() const LLVM_READONLY;
+
public:
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+
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) {
+ : CallExpr(C, CXXOperatorCallExprClass, fn, args, t, VK, operatorloc),
+ Operator(Op), FPFeatures(FPFeatures) {
Range = getSourceRangeImpl();
}
- explicit CXXOperatorCallExpr(ASTContext& C, EmptyShell Empty) :
- CallExpr(C, CXXOperatorCallExprClass, Empty) { }
+ explicit CXXOperatorCallExpr(ASTContext& C, EmptyShell Empty)
+ : CallExpr(C, CXXOperatorCallExprClass, Empty) {}
/// \brief Returns the kind of overloaded operator that this
/// expression refers to.
@@ -120,9 +151,6 @@ public:
bool isFPContractableWithinStatement() const {
return FPFeatures.allowFPContractWithinStatement();
}
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
};
/// Represents a call to a member function that
@@ -137,10 +165,10 @@ class CXXMemberCallExpr : public CallExpr {
public:
CXXMemberCallExpr(ASTContext &C, Expr *fn, ArrayRef<Expr*> args,
QualType t, ExprValueKind VK, SourceLocation RP)
- : CallExpr(C, CXXMemberCallExprClass, fn, args, t, VK, RP) {}
+ : CallExpr(C, CXXMemberCallExprClass, fn, args, t, VK, RP) {}
CXXMemberCallExpr(ASTContext &C, EmptyShell Empty)
- : CallExpr(C, CXXMemberCallExprClass, Empty) { }
+ : CallExpr(C, CXXMemberCallExprClass, Empty) {}
/// \brief Retrieves the implicit object argument for the member call.
///
@@ -183,7 +211,7 @@ public:
: CallExpr(C, CUDAKernelCallExprClass, fn, Config, args, t, VK, RP) {}
CUDAKernelCallExpr(ASTContext &C, EmptyShell Empty)
- : CallExpr(C, CUDAKernelCallExprClass, END_PREARG, Empty) { }
+ : CallExpr(C, CUDAKernelCallExprClass, END_PREARG, Empty) {}
const CallExpr *getConfig() const {
return cast_or_null<CallExpr>(getPreArg(CONFIG));
@@ -217,23 +245,28 @@ public:
/// reinterpret_cast, and CXXConstCastExpr for \c const_cast.
class CXXNamedCastExpr : public ExplicitCastExpr {
private:
- SourceLocation Loc; // the location of the casting op
- SourceLocation RParenLoc; // the location of the right parenthesis
- SourceRange AngleBrackets; // range for '<' '>'
+ // the location of the casting op
+ SourceLocation Loc;
+
+ // the location of the right parenthesis
+ SourceLocation RParenLoc;
+
+ // range for '<' '>'
+ SourceRange AngleBrackets;
protected:
+ friend class ASTStmtReader;
+
CXXNamedCastExpr(StmtClass SC, QualType ty, ExprValueKind VK,
CastKind kind, Expr *op, unsigned PathSize,
TypeSourceInfo *writtenTy, SourceLocation l,
SourceLocation RParenLoc,
SourceRange AngleBrackets)
- : ExplicitCastExpr(SC, ty, VK, kind, op, PathSize, writtenTy), Loc(l),
- RParenLoc(RParenLoc), AngleBrackets(AngleBrackets) {}
+ : ExplicitCastExpr(SC, ty, VK, kind, op, PathSize, writtenTy), Loc(l),
+ RParenLoc(RParenLoc), AngleBrackets(AngleBrackets) {}
explicit CXXNamedCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize)
- : ExplicitCastExpr(SC, Shell, PathSize) { }
-
- friend class ASTStmtReader;
+ : ExplicitCastExpr(SC, Shell, PathSize) {}
public:
const char *getCastName() const;
@@ -273,13 +306,16 @@ class CXXStaticCastExpr final
unsigned pathSize, TypeSourceInfo *writtenTy,
SourceLocation l, SourceLocation RParenLoc,
SourceRange AngleBrackets)
- : CXXNamedCastExpr(CXXStaticCastExprClass, ty, vk, kind, op, pathSize,
- writtenTy, l, RParenLoc, AngleBrackets) {}
+ : CXXNamedCastExpr(CXXStaticCastExprClass, ty, vk, kind, op, pathSize,
+ writtenTy, l, RParenLoc, AngleBrackets) {}
explicit CXXStaticCastExpr(EmptyShell Empty, unsigned PathSize)
- : CXXNamedCastExpr(CXXStaticCastExprClass, Empty, PathSize) { }
+ : CXXNamedCastExpr(CXXStaticCastExprClass, Empty, PathSize) {}
public:
+ friend class CastExpr;
+ friend TrailingObjects;
+
static CXXStaticCastExpr *Create(const ASTContext &Context, QualType T,
ExprValueKind VK, CastKind K, Expr *Op,
const CXXCastPath *Path,
@@ -292,9 +328,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXStaticCastExprClass;
}
-
- friend TrailingObjects;
- friend class CastExpr;
};
/// \brief A C++ @c dynamic_cast expression (C++ [expr.dynamic.cast]).
@@ -309,13 +342,16 @@ class CXXDynamicCastExpr final
Expr *op, unsigned pathSize, TypeSourceInfo *writtenTy,
SourceLocation l, SourceLocation RParenLoc,
SourceRange AngleBrackets)
- : CXXNamedCastExpr(CXXDynamicCastExprClass, ty, VK, kind, op, pathSize,
- writtenTy, l, RParenLoc, AngleBrackets) {}
+ : CXXNamedCastExpr(CXXDynamicCastExprClass, ty, VK, kind, op, pathSize,
+ writtenTy, l, RParenLoc, AngleBrackets) {}
explicit CXXDynamicCastExpr(EmptyShell Empty, unsigned pathSize)
- : CXXNamedCastExpr(CXXDynamicCastExprClass, Empty, pathSize) { }
+ : CXXNamedCastExpr(CXXDynamicCastExprClass, Empty, pathSize) {}
public:
+ friend class CastExpr;
+ friend TrailingObjects;
+
static CXXDynamicCastExpr *Create(const ASTContext &Context, QualType T,
ExprValueKind VK, CastKind Kind, Expr *Op,
const CXXCastPath *Path,
@@ -331,9 +367,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXDynamicCastExprClass;
}
-
- friend TrailingObjects;
- friend class CastExpr;
};
/// \brief A C++ @c reinterpret_cast expression (C++ [expr.reinterpret.cast]).
@@ -353,13 +386,16 @@ class CXXReinterpretCastExpr final
TypeSourceInfo *writtenTy, SourceLocation l,
SourceLocation RParenLoc,
SourceRange AngleBrackets)
- : CXXNamedCastExpr(CXXReinterpretCastExprClass, ty, vk, kind, op,
- pathSize, writtenTy, l, RParenLoc, AngleBrackets) {}
+ : CXXNamedCastExpr(CXXReinterpretCastExprClass, ty, vk, kind, op,
+ pathSize, writtenTy, l, RParenLoc, AngleBrackets) {}
CXXReinterpretCastExpr(EmptyShell Empty, unsigned pathSize)
- : CXXNamedCastExpr(CXXReinterpretCastExprClass, Empty, pathSize) { }
+ : CXXNamedCastExpr(CXXReinterpretCastExprClass, Empty, pathSize) {}
public:
+ friend class CastExpr;
+ friend TrailingObjects;
+
static CXXReinterpretCastExpr *Create(const ASTContext &Context, QualType T,
ExprValueKind VK, CastKind Kind,
Expr *Op, const CXXCastPath *Path,
@@ -372,9 +408,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXReinterpretCastExprClass;
}
-
- friend TrailingObjects;
- friend class CastExpr;
};
/// \brief A C++ \c const_cast expression (C++ [expr.const.cast]).
@@ -390,13 +423,16 @@ class CXXConstCastExpr final
CXXConstCastExpr(QualType ty, ExprValueKind VK, Expr *op,
TypeSourceInfo *writtenTy, SourceLocation l,
SourceLocation RParenLoc, SourceRange AngleBrackets)
- : CXXNamedCastExpr(CXXConstCastExprClass, ty, VK, CK_NoOp, op,
- 0, writtenTy, l, RParenLoc, AngleBrackets) {}
+ : CXXNamedCastExpr(CXXConstCastExprClass, ty, VK, CK_NoOp, op,
+ 0, writtenTy, l, RParenLoc, AngleBrackets) {}
explicit CXXConstCastExpr(EmptyShell Empty)
- : CXXNamedCastExpr(CXXConstCastExprClass, Empty, 0) { }
+ : CXXNamedCastExpr(CXXConstCastExprClass, Empty, 0) {}
public:
+ friend class CastExpr;
+ friend TrailingObjects;
+
static CXXConstCastExpr *Create(const ASTContext &Context, QualType T,
ExprValueKind VK, Expr *Op,
TypeSourceInfo *WrittenTy, SourceLocation L,
@@ -407,9 +443,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXConstCastExprClass;
}
-
- friend TrailingObjects;
- friend class CastExpr;
};
/// \brief A call to a literal operator (C++11 [over.literal])
@@ -426,22 +459,37 @@ class UserDefinedLiteral : public CallExpr {
SourceLocation UDSuffixLoc;
public:
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+
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) {}
+ : CallExpr(C, UserDefinedLiteralClass, Fn, Args, T, VK, LitEndLoc),
+ UDSuffixLoc(SuffixLoc) {}
+
explicit UserDefinedLiteral(const ASTContext &C, EmptyShell Empty)
- : CallExpr(C, UserDefinedLiteralClass, Empty) {}
+ : CallExpr(C, UserDefinedLiteralClass, Empty) {}
/// The kind of literal operator which is invoked.
enum LiteralOperatorKind {
- LOK_Raw, ///< Raw form: operator "" X (const char *)
- LOK_Template, ///< Raw form: operator "" X<cs...> ()
- LOK_Integer, ///< operator "" X (unsigned long long)
- LOK_Floating, ///< operator "" X (long double)
- LOK_String, ///< operator "" X (const CharT *, size_t)
- LOK_Character ///< operator "" X (CharT)
+ /// Raw form: operator "" X (const char *)
+ LOK_Raw,
+
+ /// Raw form: operator "" X<cs...> ()
+ LOK_Template,
+
+ /// operator "" X (unsigned long long)
+ LOK_Integer,
+
+ /// operator "" X (long double)
+ LOK_Floating,
+
+ /// operator "" X (const CharT *, size_t)
+ LOK_String,
+
+ /// operator "" X (CharT)
+ LOK_Character
};
/// \brief Returns the kind of literal operator invocation
@@ -461,8 +509,8 @@ public:
return getRParenLoc();
return getArg(0)->getLocStart();
}
- SourceLocation getLocEnd() const { return getRParenLoc(); }
+ SourceLocation getLocEnd() const { return getRParenLoc(); }
/// \brief Returns the location of a ud-suffix in the expression.
///
@@ -476,24 +524,21 @@ public:
static bool classof(const Stmt *S) {
return S->getStmtClass() == UserDefinedLiteralClass;
}
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
};
/// \brief 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) :
- Expr(CXXBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
- false, false),
- Value(val), Loc(l) {}
+ CXXBoolLiteralExpr(bool val, QualType Ty, SourceLocation l)
+ : Expr(CXXBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
+ false, false),
+ Value(val), Loc(l) {}
explicit CXXBoolLiteralExpr(EmptyShell Empty)
- : Expr(CXXBoolLiteralExprClass, Empty) { }
+ : Expr(CXXBoolLiteralExprClass, Empty) {}
bool getValue() const { return Value; }
void setValue(bool V) { Value = V; }
@@ -519,14 +564,15 @@ 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) :
- Expr(CXXNullPtrLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
- false, false),
- Loc(l) {}
+ CXXNullPtrLiteralExpr(QualType Ty, SourceLocation l)
+ : Expr(CXXNullPtrLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false,
+ false, false, false),
+ Loc(l) {}
explicit CXXNullPtrLiteralExpr(EmptyShell Empty)
- : Expr(CXXNullPtrLiteralExprClass, Empty) { }
+ : Expr(CXXNullPtrLiteralExprClass, Empty) {}
SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
@@ -546,18 +592,21 @@ public:
/// \brief Implicit construction of a std::initializer_list<T> object from an
/// array temporary within list-initialization (C++11 [dcl.init.list]p5).
class CXXStdInitializerListExpr : public Expr {
- Stmt *SubExpr;
+ Stmt *SubExpr = nullptr;
CXXStdInitializerListExpr(EmptyShell Empty)
- : Expr(CXXStdInitializerListExprClass, Empty), SubExpr(nullptr) {}
+ : Expr(CXXStdInitializerListExprClass, Empty) {}
public:
+ friend class ASTReader;
+ friend class ASTStmtReader;
+
CXXStdInitializerListExpr(QualType Ty, Expr *SubExpr)
- : Expr(CXXStdInitializerListExprClass, Ty, VK_RValue, OK_Ordinary,
- Ty->isDependentType(), SubExpr->isValueDependent(),
- SubExpr->isInstantiationDependent(),
- SubExpr->containsUnexpandedParameterPack()),
- SubExpr(SubExpr) {}
+ : Expr(CXXStdInitializerListExprClass, Ty, VK_RValue, OK_Ordinary,
+ Ty->isDependentType(), SubExpr->isValueDependent(),
+ SubExpr->isInstantiationDependent(),
+ SubExpr->containsUnexpandedParameterPack()),
+ SubExpr(SubExpr) {}
Expr *getSubExpr() { return static_cast<Expr*>(SubExpr); }
const Expr *getSubExpr() const { return static_cast<const Expr*>(SubExpr); }
@@ -565,9 +614,11 @@ public:
SourceLocation getLocStart() const LLVM_READONLY {
return SubExpr->getLocStart();
}
+
SourceLocation getLocEnd() const LLVM_READONLY {
return SubExpr->getLocEnd();
}
+
SourceRange getSourceRange() const LLVM_READONLY {
return SubExpr->getSourceRange();
}
@@ -577,9 +628,6 @@ public:
}
child_range children() { return child_range(&SubExpr, &SubExpr + 1); }
-
- friend class ASTReader;
- friend class ASTStmtReader;
};
/// A C++ \c typeid expression (C++ [expr.typeid]), which gets
@@ -594,27 +642,29 @@ private:
public:
CXXTypeidExpr(QualType Ty, TypeSourceInfo *Operand, SourceRange R)
- : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary,
- // typeid is never type-dependent (C++ [temp.dep.expr]p4)
- false,
- // typeid is value-dependent if the type or expression are dependent
- Operand->getType()->isDependentType(),
- Operand->getType()->isInstantiationDependentType(),
- Operand->getType()->containsUnexpandedParameterPack()),
- Operand(Operand), Range(R) { }
+ : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary,
+ // typeid is never type-dependent (C++ [temp.dep.expr]p4)
+ false,
+ // typeid is value-dependent if the type or expression are
+ // dependent
+ Operand->getType()->isDependentType(),
+ Operand->getType()->isInstantiationDependentType(),
+ Operand->getType()->containsUnexpandedParameterPack()),
+ Operand(Operand), Range(R) {}
CXXTypeidExpr(QualType Ty, Expr *Operand, SourceRange R)
- : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary,
- // typeid is never type-dependent (C++ [temp.dep.expr]p4)
- false,
- // typeid is value-dependent if the type or expression are dependent
- Operand->isTypeDependent() || Operand->isValueDependent(),
- Operand->isInstantiationDependent(),
- Operand->containsUnexpandedParameterPack()),
- Operand(Operand), Range(R) { }
+ : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary,
+ // typeid is never type-dependent (C++ [temp.dep.expr]p4)
+ false,
+ // typeid is value-dependent if the type or expression are
+ // dependent
+ Operand->isTypeDependent() || Operand->isValueDependent(),
+ Operand->isInstantiationDependent(),
+ Operand->containsUnexpandedParameterPack()),
+ Operand(Operand), Range(R) {}
CXXTypeidExpr(EmptyShell Empty, bool isExpr)
- : Expr(CXXTypeidExprClass, Empty) {
+ : Expr(CXXTypeidExprClass, Empty) {
if (isExpr)
Operand = (Expr*)nullptr;
else
@@ -683,26 +733,30 @@ class MSPropertyRefExpr : public Expr {
NestedNameSpecifierLoc QualifierLoc;
public:
+ friend class ASTStmtReader;
+
MSPropertyRefExpr(Expr *baseExpr, MSPropertyDecl *decl, bool isArrow,
QualType ty, ExprValueKind VK,
NestedNameSpecifierLoc qualifierLoc,
SourceLocation nameLoc)
- : Expr(MSPropertyRefExprClass, ty, VK, OK_Ordinary,
- /*type-dependent*/ false, baseExpr->isValueDependent(),
- baseExpr->isInstantiationDependent(),
- baseExpr->containsUnexpandedParameterPack()),
- BaseExpr(baseExpr), TheDecl(decl),
- MemberLoc(nameLoc), IsArrow(isArrow),
- QualifierLoc(qualifierLoc) {}
+ : Expr(MSPropertyRefExprClass, ty, VK, OK_Ordinary,
+ /*type-dependent*/ false, baseExpr->isValueDependent(),
+ baseExpr->isInstantiationDependent(),
+ baseExpr->containsUnexpandedParameterPack()),
+ BaseExpr(baseExpr), TheDecl(decl),
+ MemberLoc(nameLoc), IsArrow(isArrow),
+ QualifierLoc(qualifierLoc) {}
MSPropertyRefExpr(EmptyShell Empty) : Expr(MSPropertyRefExprClass, Empty) {}
SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(getLocStart(), getLocEnd());
}
+
bool isImplicitAccess() const {
return getBaseExpr() && getBaseExpr()->isImplicitCXXThis();
}
+
SourceLocation getLocStart() const {
if (!isImplicitAccess())
return BaseExpr->getLocStart();
@@ -711,11 +765,13 @@ public:
else
return MemberLoc;
}
+
SourceLocation getLocEnd() const { return getMemberLoc(); }
child_range children() {
return child_range((Stmt**)&BaseExpr, (Stmt**)&BaseExpr + 1);
}
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == MSPropertyRefExprClass;
}
@@ -725,8 +781,6 @@ public:
bool isArrow() const { return IsArrow; }
SourceLocation getMemberLoc() const { return MemberLoc; }
NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
-
- friend class ASTStmtReader;
};
/// MS property subscript expression.
@@ -742,7 +796,9 @@ public:
/// This is a syntactic pseudo-object expression.
class MSPropertySubscriptExpr : public Expr {
friend class ASTStmtReader;
+
enum { BASE_EXPR, IDX_EXPR, NUM_SUBEXPRS = 2 };
+
Stmt *SubExprs[NUM_SUBEXPRS];
SourceLocation RBracketLoc;
@@ -773,6 +829,7 @@ public:
SourceLocation getLocStart() const LLVM_READONLY {
return getBase()->getLocStart();
}
+
SourceLocation getLocEnd() const LLVM_READONLY { return RBracketLoc; }
SourceLocation getRBracketLoc() const { return RBracketLoc; }
@@ -891,13 +948,13 @@ class CXXThisExpr : public Expr {
public:
CXXThisExpr(SourceLocation L, QualType Type, bool isImplicit)
- : Expr(CXXThisExprClass, Type, 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) { }
+ : Expr(CXXThisExprClass, Type, 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) {}
CXXThisExpr(EmptyShell Empty) : Expr(CXXThisExprClass, Empty) {}
@@ -926,23 +983,25 @@ public:
/// 'throw' assignment-expression. When assignment-expression isn't
/// present, Op will be null.
class CXXThrowExpr : public Expr {
+ friend class ASTStmtReader;
+
Stmt *Op;
SourceLocation ThrowLoc;
+
/// \brief Whether the thrown variable (if any) is in scope.
unsigned IsThrownVariableInScope : 1;
- friend class ASTStmtReader;
-
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,
- bool IsThrownVariableInScope) :
- Expr(CXXThrowExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
- expr && expr->isInstantiationDependent(),
- expr && expr->containsUnexpandedParameterPack()),
- Op(expr), ThrowLoc(l), IsThrownVariableInScope(IsThrownVariableInScope) {}
+ bool IsThrownVariableInScope)
+ : Expr(CXXThrowExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
+ expr && expr->isInstantiationDependent(),
+ expr && expr->containsUnexpandedParameterPack()),
+ Op(expr), ThrowLoc(l),
+ IsThrownVariableInScope(IsThrownVariableInScope) {}
CXXThrowExpr(EmptyShell Empty) : Expr(CXXThrowExprClass, Empty) {}
const Expr *getSubExpr() const { return cast_or_null<Expr>(Op); }
@@ -958,6 +1017,7 @@ public:
bool isThrownVariableInScope() const { return IsThrownVariableInScope; }
SourceLocation getLocStart() const LLVM_READONLY { return ThrowLoc; }
+
SourceLocation getLocEnd() const LLVM_READONLY {
if (!getSubExpr())
return ThrowLoc;
@@ -987,15 +1047,19 @@ class CXXDefaultArgExpr final : public Expr {
SourceLocation Loc;
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, false),
- Param(param), Loc(Loc) { }
+ : Expr(SC,
+ param->hasUnparsedDefaultArg()
+ ? param->getType().getNonReferenceType()
+ : param->getDefaultArg()->getType(),
+ param->getDefaultArg()->getValueKind(),
+ param->getDefaultArg()->getObjectKind(), false, false, false,
+ false),
+ Param(param), 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
@@ -1036,9 +1100,6 @@ public:
child_range children() {
return child_range(child_iterator(), child_iterator());
}
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
};
/// \brief A use of a default initializer in a constructor or in aggregate
@@ -1062,6 +1123,9 @@ class CXXDefaultInitExpr : public Expr {
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,
@@ -1094,9 +1158,6 @@ public:
child_range children() {
return child_range(child_iterator(), child_iterator());
}
-
- friend class ASTReader;
- friend class ASTStmtReader;
};
/// \brief Represents a C++ temporary.
@@ -1105,13 +1166,14 @@ class CXXTemporary {
const CXXDestructorDecl *Destructor;
explicit CXXTemporary(const CXXDestructorDecl *destructor)
- : Destructor(destructor) { }
+ : Destructor(destructor) {}
public:
static CXXTemporary *Create(const ASTContext &C,
const CXXDestructorDecl *Destructor);
const CXXDestructorDecl *getDestructor() const { return Destructor; }
+
void setDestructor(const CXXDestructorDecl *Dtor) {
Destructor = Dtor;
}
@@ -1132,21 +1194,20 @@ public:
/// }
/// \endcode
class CXXBindTemporaryExpr : public Expr {
- CXXTemporary *Temp;
-
- Stmt *SubExpr;
+ CXXTemporary *Temp = nullptr;
+ Stmt *SubExpr = nullptr;
CXXBindTemporaryExpr(CXXTemporary *temp, Expr* SubExpr)
- : Expr(CXXBindTemporaryExprClass, SubExpr->getType(),
- VK_RValue, OK_Ordinary, SubExpr->isTypeDependent(),
- SubExpr->isValueDependent(),
- SubExpr->isInstantiationDependent(),
- SubExpr->containsUnexpandedParameterPack()),
- Temp(temp), SubExpr(SubExpr) { }
+ : Expr(CXXBindTemporaryExprClass, SubExpr->getType(),
+ VK_RValue, OK_Ordinary, SubExpr->isTypeDependent(),
+ SubExpr->isValueDependent(),
+ SubExpr->isInstantiationDependent(),
+ SubExpr->containsUnexpandedParameterPack()),
+ Temp(temp), SubExpr(SubExpr) {}
public:
CXXBindTemporaryExpr(EmptyShell Empty)
- : Expr(CXXBindTemporaryExprClass, Empty), Temp(nullptr), SubExpr(nullptr) {}
+ : Expr(CXXBindTemporaryExprClass, Empty) {}
static CXXBindTemporaryExpr *Create(const ASTContext &C, CXXTemporary *Temp,
Expr* SubExpr);
@@ -1162,6 +1223,7 @@ public:
SourceLocation getLocStart() const LLVM_READONLY {
return SubExpr->getLocStart();
}
+
SourceLocation getLocEnd() const LLVM_READONLY { return SubExpr->getLocEnd();}
// Implement isa/cast/dyncast/etc.
@@ -1184,8 +1246,7 @@ public:
};
private:
- CXXConstructorDecl *Constructor;
-
+ CXXConstructorDecl *Constructor = nullptr;
SourceLocation Loc;
SourceRange ParenOrBraceRange;
unsigned NumArgs : 16;
@@ -1195,7 +1256,7 @@ private:
unsigned StdInitListInitialization : 1;
unsigned ZeroInitialization : 1;
unsigned ConstructKind : 2;
- Stmt **Args;
+ Stmt **Args = nullptr;
void setConstructor(CXXConstructorDecl *C) { Constructor = C; }
@@ -1214,15 +1275,16 @@ protected:
/// \brief Construct an empty C++ construction expression.
CXXConstructExpr(StmtClass SC, EmptyShell Empty)
- : Expr(SC, Empty), Constructor(nullptr), NumArgs(0), Elidable(false),
- HadMultipleCandidates(false), ListInitialization(false),
- ZeroInitialization(false), ConstructKind(0), Args(nullptr)
- { }
+ : Expr(SC, Empty), NumArgs(0), Elidable(false),
+ HadMultipleCandidates(false), ListInitialization(false),
+ ZeroInitialization(false), ConstructKind(0) {}
public:
+ friend class ASTStmtReader;
+
/// \brief Construct an empty C++ construction expression.
explicit CXXConstructExpr(EmptyShell Empty)
- : CXXConstructExpr(CXXConstructExprClass, Empty) {}
+ : CXXConstructExpr(CXXConstructExprClass, Empty) {}
static CXXConstructExpr *Create(const ASTContext &C, QualType T,
SourceLocation Loc,
@@ -1278,10 +1340,10 @@ public:
ConstructKind = CK;
}
- 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;
+ 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>;
arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
arg_const_range arguments() const {
@@ -1329,8 +1391,6 @@ public:
child_range children() {
return child_range(&Args[0], &Args[0]+NumArgs);
}
-
- friend class ASTStmtReader;
};
/// \brief Represents a call to an inherited base class constructor from an
@@ -1339,7 +1399,7 @@ public:
/// base class constructor.
class CXXInheritedCtorInitExpr : public Expr {
private:
- CXXConstructorDecl *Constructor;
+ CXXConstructorDecl *Constructor = nullptr;
/// The location of the using declaration.
SourceLocation Loc;
@@ -1352,6 +1412,8 @@ private:
unsigned InheritedFromVirtualBase : 1;
public:
+ friend class ASTStmtReader;
+
/// \brief Construct a C++ inheriting construction expression.
CXXInheritedCtorInitExpr(SourceLocation Loc, QualType T,
CXXConstructorDecl *Ctor, bool ConstructsVirtualBase,
@@ -1366,7 +1428,7 @@ public:
/// \brief Construct an empty C++ inheriting construction expression.
explicit CXXInheritedCtorInitExpr(EmptyShell Empty)
- : Expr(CXXInheritedCtorInitExprClass, Empty), Constructor(nullptr),
+ : Expr(CXXInheritedCtorInitExprClass, Empty),
ConstructsVirtualBase(false), InheritedFromVirtualBase(false) {}
/// \brief Get the constructor that this expression will call.
@@ -1393,11 +1455,10 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXInheritedCtorInitExprClass;
}
+
child_range children() {
return child_range(child_iterator(), child_iterator());
}
-
- friend class ASTStmtReader;
};
/// \brief Represents an explicit C++ type conversion that uses "functional"
@@ -1417,14 +1478,17 @@ class CXXFunctionalCastExpr final
TypeSourceInfo *writtenTy,
CastKind kind, Expr *castExpr, unsigned pathSize,
SourceLocation lParenLoc, SourceLocation rParenLoc)
- : ExplicitCastExpr(CXXFunctionalCastExprClass, ty, VK, kind,
- castExpr, pathSize, writtenTy),
- LParenLoc(lParenLoc), RParenLoc(rParenLoc) {}
+ : ExplicitCastExpr(CXXFunctionalCastExprClass, ty, VK, kind,
+ castExpr, pathSize, writtenTy),
+ LParenLoc(lParenLoc), RParenLoc(rParenLoc) {}
explicit CXXFunctionalCastExpr(EmptyShell Shell, unsigned PathSize)
- : ExplicitCastExpr(CXXFunctionalCastExprClass, Shell, PathSize) { }
+ : ExplicitCastExpr(CXXFunctionalCastExprClass, Shell, PathSize) {}
public:
+ friend class CastExpr;
+ friend TrailingObjects;
+
static CXXFunctionalCastExpr *Create(const ASTContext &Context, QualType T,
ExprValueKind VK,
TypeSourceInfo *Written,
@@ -1446,9 +1510,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXFunctionalCastExprClass;
}
-
- friend TrailingObjects;
- friend class CastExpr;
};
/// @brief Represents a C++ functional cast expression that builds a
@@ -1467,9 +1528,11 @@ public:
/// };
/// \endcode
class CXXTemporaryObjectExpr : public CXXConstructExpr {
- TypeSourceInfo *Type;
+ TypeSourceInfo *Type = nullptr;
public:
+ friend class ASTStmtReader;
+
CXXTemporaryObjectExpr(const ASTContext &C,
CXXConstructorDecl *Cons,
QualType Type,
@@ -1481,7 +1544,7 @@ public:
bool StdInitListInitialization,
bool ZeroInitialization);
explicit CXXTemporaryObjectExpr(EmptyShell Empty)
- : CXXConstructExpr(CXXTemporaryObjectExprClass, Empty), Type() { }
+ : CXXConstructExpr(CXXTemporaryObjectExprClass, Empty) {}
TypeSourceInfo *getTypeSourceInfo() const { return Type; }
@@ -1491,8 +1554,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXTemporaryObjectExprClass;
}
-
- friend class ASTStmtReader;
};
/// \brief A C++ lambda expression, which produces a function object
@@ -1558,9 +1619,9 @@ class LambdaExpr final : public Expr,
/// \brief Construct an empty lambda expression.
LambdaExpr(EmptyShell Empty, unsigned NumCaptures)
- : Expr(LambdaExprClass, Empty),
- NumCaptures(NumCaptures), CaptureDefault(LCD_None), ExplicitParams(false),
- ExplicitResultType(false) {
+ : Expr(LambdaExprClass, Empty), NumCaptures(NumCaptures),
+ CaptureDefault(LCD_None), ExplicitParams(false),
+ ExplicitResultType(false) {
getStoredStmts()[NumCaptures] = nullptr;
}
@@ -1569,6 +1630,10 @@ class LambdaExpr final : public Expr,
Stmt *const *getStoredStmts() const { return getTrailingObjects<Stmt *>(); }
public:
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+ friend TrailingObjects;
+
/// \brief Construct a new lambda expression.
static LambdaExpr *
Create(const ASTContext &C, CXXRecordDecl *Class, SourceRange IntroducerRange,
@@ -1597,10 +1662,10 @@ public:
/// \brief An iterator that walks over the captures of the lambda,
/// both implicit and explicit.
- typedef const LambdaCapture *capture_iterator;
+ using capture_iterator = const LambdaCapture *;
/// \brief An iterator over a range of lambda captures.
- typedef llvm::iterator_range<capture_iterator> capture_range;
+ using capture_range = llvm::iterator_range<capture_iterator>;
/// \brief Retrieve this lambda's captures.
capture_range captures() const;
@@ -1639,11 +1704,11 @@ public:
/// \brief Iterator that walks over the capture initialization
/// arguments.
- typedef Expr **capture_init_iterator;
+ using capture_init_iterator = Expr **;
/// \brief Const iterator that walks over the capture initialization
/// arguments.
- typedef Expr *const *const_capture_init_iterator;
+ using const_capture_init_iterator = Expr *const *;
/// \brief Retrieve the initialization expressions for this lambda's captures.
llvm::iterator_range<capture_init_iterator> capture_inits() {
@@ -1723,26 +1788,23 @@ public:
SourceLocation getLocStart() const LLVM_READONLY {
return IntroducerRange.getBegin();
}
+
SourceLocation getLocEnd() const LLVM_READONLY { return ClosingBrace; }
child_range children() {
// Includes initialization exprs plus body stmt
return child_range(getStoredStmts(), getStoredStmts() + NumCaptures + 1);
}
-
- friend TrailingObjects;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
};
/// An expression "T()" which creates a value-initialized rvalue of type
/// T, which is a non-class type. See (C++98 [5.2.3p2]).
class CXXScalarValueInitExpr : public Expr {
+ friend class ASTStmtReader;
+
SourceLocation RParenLoc;
TypeSourceInfo *TypeInfo;
- friend class ASTStmtReader;
-
public:
/// \brief Create an explicitly-written scalar-value initialization
/// expression.
@@ -1754,7 +1816,7 @@ public:
RParenLoc(rParenLoc), TypeInfo(TypeInfo) {}
explicit CXXScalarValueInitExpr(EmptyShell Shell)
- : Expr(CXXScalarValueInitExprClass, Shell) { }
+ : Expr(CXXScalarValueInitExprClass, Shell) {}
TypeSourceInfo *getTypeSourceInfo() const {
return TypeInfo;
@@ -1778,11 +1840,16 @@ public:
/// \brief Represents a new-expression for memory allocation and constructor
/// calls, e.g: "new CXXNewExpr(foo)".
class CXXNewExpr : public Expr {
+ 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;
+ Stmt **SubExprs = nullptr;
+
/// \brief Points to the allocation function used.
FunctionDecl *OperatorNew;
+
/// \brief Points to the deallocation function used in case of error. May be
/// null.
FunctionDecl *OperatorDelete;
@@ -1802,27 +1869,35 @@ class CXXNewExpr : public Expr {
/// 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;
+
/// The number of placement new arguments.
unsigned NumPlacementArgs : 26;
+
/// 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;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
public:
enum InitializationStyle {
- NoInit, ///< New-expression has no initializer as written.
- CallInit, ///< New-expression has a C++98 paren-delimited initializer.
- ListInit ///< New-expression has a C++11 list-initializer.
+ /// New-expression has no initializer as written.
+ NoInit,
+
+ /// New-expression has a C++98 paren-delimited initializer.
+ CallInit,
+
+ /// New-expression has a C++11 list-initializer.
+ ListInit
};
CXXNewExpr(const ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
@@ -1833,7 +1908,7 @@ public:
QualType ty, TypeSourceInfo *AllocatedTypeInfo,
SourceRange Range, SourceRange directInitRange);
explicit CXXNewExpr(EmptyShell Shell)
- : Expr(CXXNewExprClass, Shell), SubExprs(nullptr) { }
+ : Expr(CXXNewExprClass, Shell) {}
void AllocateArgsArray(const ASTContext &C, bool isArray,
unsigned numPlaceArgs, bool hasInitializer);
@@ -1870,6 +1945,7 @@ public:
void setOperatorDelete(FunctionDecl *D) { OperatorDelete = D; }
bool isArray() const { return Array; }
+
Expr *getArraySize() {
return Array ? cast<Expr>(SubExprs[0]) : nullptr;
}
@@ -1878,6 +1954,7 @@ public:
}
unsigned getNumPlacementArgs() const { return NumPlacementArgs; }
+
Expr **getPlacementArgs() {
return reinterpret_cast<Expr **>(SubExprs + Array + hasInitializer());
}
@@ -1932,8 +2009,8 @@ public:
return UsualArrayDeleteWantsSize;
}
- typedef ExprIterator arg_iterator;
- typedef ConstExprIterator const_arg_iterator;
+ using arg_iterator = ExprIterator;
+ using const_arg_iterator = ConstExprIterator;
llvm::iterator_range<arg_iterator> placement_arguments() {
return llvm::make_range(placement_arg_begin(), placement_arg_end());
@@ -1956,7 +2033,8 @@ public:
return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
}
- typedef Stmt **raw_arg_iterator;
+ using raw_arg_iterator = Stmt **;
+
raw_arg_iterator raw_arg_begin() { return SubExprs; }
raw_arg_iterator raw_arg_end() {
return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
@@ -1974,6 +2052,7 @@ public:
SourceRange getSourceRange() const LLVM_READONLY {
return Range;
}
+
SourceLocation getLocStart() const LLVM_READONLY { return getStartLoc(); }
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
@@ -1991,36 +2070,43 @@ public:
/// destructor calls, e.g. "delete[] pArray".
class CXXDeleteExpr : public Expr {
/// Points to the operator delete overload that is used. Could be a member.
- FunctionDecl *OperatorDelete;
+ FunctionDecl *OperatorDelete = nullptr;
+
/// The pointer expression to be deleted.
- Stmt *Argument;
+ 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), Loc(loc),
- GlobalDelete(globalDelete),
- ArrayForm(arrayForm), ArrayFormAsWritten(arrayFormAsWritten),
- UsualArrayDeleteWantsSize(usualArrayDeleteWantsSize) { }
- explicit CXXDeleteExpr(EmptyShell Shell)
- : Expr(CXXDeleteExprClass, Shell), OperatorDelete(nullptr),
- Argument(nullptr) {}
+ : 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; }
@@ -2054,8 +2140,6 @@ public:
// Iterators
child_range children() { return child_range(&Argument, &Argument+1); }
-
- friend class ASTStmtReader;
};
/// \brief Stores the type being destroyed by a pseudo-destructor expression.
@@ -2068,10 +2152,10 @@ class PseudoDestructorTypeStorage {
SourceLocation Location;
public:
- PseudoDestructorTypeStorage() { }
+ PseudoDestructorTypeStorage() = default;
PseudoDestructorTypeStorage(IdentifierInfo *II, SourceLocation Loc)
- : Type(II), Location(Loc) { }
+ : Type(II), Location(Loc) {}
PseudoDestructorTypeStorage(TypeSourceInfo *Info);
@@ -2111,8 +2195,10 @@ public:
/// for scalar types. A pseudo-destructor expression has no run-time semantics
/// beyond evaluating the base expression.
class CXXPseudoDestructorExpr : public Expr {
+ friend class ASTStmtReader;
+
/// \brief The base expression (that is being destroyed).
- Stmt *Base;
+ Stmt *Base = nullptr;
/// \brief Whether the operator was an arrow ('->'); otherwise, it was a
/// period ('.').
@@ -2126,7 +2212,7 @@ class CXXPseudoDestructorExpr : public Expr {
/// \brief The type that precedes the '::' in a qualified pseudo-destructor
/// expression.
- TypeSourceInfo *ScopeType;
+ TypeSourceInfo *ScopeType = nullptr;
/// \brief The location of the '::' in a qualified pseudo-destructor
/// expression.
@@ -2139,8 +2225,6 @@ class CXXPseudoDestructorExpr : public Expr {
/// resolve the name.
PseudoDestructorTypeStorage DestroyedType;
- friend class ASTStmtReader;
-
public:
CXXPseudoDestructorExpr(const ASTContext &Context,
Expr *Base, bool isArrow, SourceLocation OperatorLoc,
@@ -2151,8 +2235,7 @@ public:
PseudoDestructorTypeStorage DestroyedType);
explicit CXXPseudoDestructorExpr(EmptyShell Shell)
- : Expr(CXXPseudoDestructorExprClass, Shell),
- Base(nullptr), IsArrow(false), QualifierLoc(), ScopeType(nullptr) { }
+ : Expr(CXXPseudoDestructorExprClass, Shell), IsArrow(false) {}
Expr *getBase() const { return cast<Expr>(Base); }
@@ -2270,13 +2353,17 @@ class TypeTraitExpr final
SourceLocation RParenLoc,
bool Value);
- TypeTraitExpr(EmptyShell Empty) : Expr(TypeTraitExprClass, Empty) { }
+ TypeTraitExpr(EmptyShell Empty) : Expr(TypeTraitExprClass, Empty) {}
size_t numTrailingObjects(OverloadToken<TypeSourceInfo *>) const {
return getNumArgs();
}
public:
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+ friend TrailingObjects;
+
/// \brief Create a new type trait expression.
static TypeTraitExpr *Create(const ASTContext &C, QualType T,
SourceLocation Loc, TypeTrait Kind,
@@ -2323,10 +2410,6 @@ public:
child_range children() {
return child_range(child_iterator(), child_iterator());
}
-
- friend TrailingObjects;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
};
/// \brief An Embarcadero array type trait, as used in the implementation of
@@ -2338,13 +2421,11 @@ public:
/// __array_extent(int, 1) == 20
/// \endcode
class ArrayTypeTraitExpr : public Expr {
- virtual void anchor();
-
/// \brief The trait. An ArrayTypeTrait enum in MSVC compat unsigned.
unsigned ATT : 2;
/// \brief The value of the type trait. Unspecified if dependent.
- uint64_t Value;
+ uint64_t Value = 0;
/// \brief The array dimension being queried, or -1 if not used.
Expr *Dimension;
@@ -2356,26 +2437,28 @@ class ArrayTypeTraitExpr : public Expr {
SourceLocation RParen;
/// \brief The type being queried.
- TypeSourceInfo *QueriedType;
+ TypeSourceInfo *QueriedType = nullptr;
+
+ virtual void anchor();
public:
+ friend class ASTStmtReader;
+
ArrayTypeTraitExpr(SourceLocation loc, ArrayTypeTrait att,
TypeSourceInfo *queried, uint64_t value,
Expr *dimension, SourceLocation rparen, QualType ty)
- : Expr(ArrayTypeTraitExprClass, ty, VK_RValue, OK_Ordinary,
- false, queried->getType()->isDependentType(),
- (queried->getType()->isInstantiationDependentType() ||
- (dimension && dimension->isInstantiationDependent())),
- queried->getType()->containsUnexpandedParameterPack()),
- ATT(att), Value(value), Dimension(dimension),
- Loc(loc), RParen(rparen), QueriedType(queried) { }
-
+ : Expr(ArrayTypeTraitExprClass, ty, VK_RValue, OK_Ordinary,
+ false, queried->getType()->isDependentType(),
+ (queried->getType()->isInstantiationDependentType() ||
+ (dimension && dimension->isInstantiationDependent())),
+ queried->getType()->containsUnexpandedParameterPack()),
+ ATT(att), Value(value), Dimension(dimension),
+ Loc(loc), RParen(rparen), QueriedType(queried) {}
explicit ArrayTypeTraitExpr(EmptyShell Empty)
- : Expr(ArrayTypeTraitExprClass, Empty), ATT(0), Value(false),
- QueriedType() { }
+ : Expr(ArrayTypeTraitExprClass, Empty), ATT(0) {}
- virtual ~ArrayTypeTraitExpr() { }
+ virtual ~ArrayTypeTraitExpr() = default;
SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
SourceLocation getLocEnd() const LLVM_READONLY { return RParen; }
@@ -2398,8 +2481,6 @@ public:
child_range children() {
return child_range(child_iterator(), child_iterator());
}
-
- friend class ASTStmtReader;
};
/// \brief An expression trait intrinsic.
@@ -2412,6 +2493,7 @@ public:
class ExpressionTraitExpr : public Expr {
/// \brief The trait. A ExpressionTrait enum in MSVC compatible unsigned.
unsigned ET : 31;
+
/// \brief The value of the type trait. Unspecified if dependent.
unsigned Value : 1;
@@ -2422,23 +2504,25 @@ class ExpressionTraitExpr : public Expr {
SourceLocation RParen;
/// \brief The expression being queried.
- Expr* QueriedExpression;
+ Expr* QueriedExpression = nullptr;
+
public:
+ friend class ASTStmtReader;
+
ExpressionTraitExpr(SourceLocation loc, ExpressionTrait et,
Expr *queried, bool value,
SourceLocation rparen, QualType resultType)
- : Expr(ExpressionTraitExprClass, resultType, VK_RValue, OK_Ordinary,
- false, // Not type-dependent
- // Value-dependent if the argument is type-dependent.
- queried->isTypeDependent(),
- queried->isInstantiationDependent(),
- queried->containsUnexpandedParameterPack()),
- ET(et), Value(value), Loc(loc), RParen(rparen),
- QueriedExpression(queried) { }
+ : Expr(ExpressionTraitExprClass, resultType, VK_RValue, OK_Ordinary,
+ false, // Not type-dependent
+ // Value-dependent if the argument is type-dependent.
+ queried->isTypeDependent(),
+ queried->isInstantiationDependent(),
+ queried->containsUnexpandedParameterPack()),
+ ET(et), Value(value), Loc(loc), RParen(rparen),
+ QueriedExpression(queried) {}
explicit ExpressionTraitExpr(EmptyShell Empty)
- : Expr(ExpressionTraitExprClass, Empty), ET(0), Value(false),
- QueriedExpression() { }
+ : Expr(ExpressionTraitExprClass, Empty), ET(0), Value(false) {}
SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
SourceLocation getLocEnd() const LLVM_READONLY { return RParen; }
@@ -2457,11 +2541,8 @@ public:
child_range children() {
return child_range(child_iterator(), child_iterator());
}
-
- friend class ASTStmtReader;
};
-
/// \brief A reference to an overloaded function set, either an
/// \c UnresolvedLookupExpr or an \c UnresolvedMemberExpr.
class OverloadExpr : public Expr {
@@ -2475,13 +2556,26 @@ class OverloadExpr : public Expr {
/// include UsingShadowDecls. Access is relative to the naming
/// class.
// FIXME: Allocate this data after the OverloadExpr subclass.
- DeclAccessPair *Results;
- unsigned NumResults;
+ DeclAccessPair *Results = nullptr;
+
+ unsigned NumResults = 0;
protected:
/// \brief Whether the name includes info for explicit template
/// keyword and arguments.
- bool HasTemplateKWAndArgsInfo;
+ bool HasTemplateKWAndArgsInfo = false;
+
+ OverloadExpr(StmtClass K, const ASTContext &C,
+ NestedNameSpecifierLoc QualifierLoc,
+ SourceLocation TemplateKWLoc,
+ const DeclarationNameInfo &NameInfo,
+ const TemplateArgumentListInfo *TemplateArgs,
+ UnresolvedSetIterator Begin, UnresolvedSetIterator End,
+ bool KnownDependent,
+ bool KnownInstantiationDependent,
+ bool KnownContainsUnexpandedParameterPack);
+
+ OverloadExpr(StmtClass K, EmptyShell Empty) : Expr(K, Empty) {}
/// \brief Return the optional template keyword and arguments info.
ASTTemplateKWAndArgsInfo *
@@ -2496,25 +2590,14 @@ protected:
/// Return the optional template arguments.
TemplateArgumentLoc *getTrailingTemplateArgumentLoc(); // defined far below
- OverloadExpr(StmtClass K, const ASTContext &C,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &NameInfo,
- const TemplateArgumentListInfo *TemplateArgs,
- UnresolvedSetIterator Begin, UnresolvedSetIterator End,
- bool KnownDependent,
- bool KnownInstantiationDependent,
- bool KnownContainsUnexpandedParameterPack);
-
- OverloadExpr(StmtClass K, EmptyShell Empty)
- : Expr(K, Empty), QualifierLoc(), Results(nullptr), NumResults(0),
- HasTemplateKWAndArgsInfo(false) { }
-
void initializeResults(const ASTContext &C,
UnresolvedSetIterator Begin,
UnresolvedSetIterator End);
public:
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+
struct FindResult {
OverloadExpr *Expression;
bool IsAddressOfOperand;
@@ -2552,7 +2635,8 @@ public:
/// \brief Gets the naming class of this lookup, if any.
CXXRecordDecl *getNamingClass() const;
- typedef UnresolvedSetImpl::iterator decls_iterator;
+ using decls_iterator = UnresolvedSetImpl::iterator;
+
decls_iterator decls_begin() const { return UnresolvedSetIterator(Results); }
decls_iterator decls_end() const {
return UnresolvedSetIterator(Results + NumResults);
@@ -2636,9 +2720,6 @@ public:
return T->getStmtClass() == UnresolvedLookupExprClass ||
T->getStmtClass() == UnresolvedMemberExprClass;
}
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
};
/// \brief A reference to a name which we were able to look up during
@@ -2656,25 +2737,25 @@ class UnresolvedLookupExpr final
: public OverloadExpr,
private llvm::TrailingObjects<
UnresolvedLookupExpr, 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;
+ 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;
+ 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;
-
- size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
- return HasTemplateKWAndArgsInfo ? 1 : 0;
- }
+ CXXRecordDecl *NamingClass = nullptr;
UnresolvedLookupExpr(const ASTContext &C,
CXXRecordDecl *NamingClass,
@@ -2684,20 +2765,17 @@ class UnresolvedLookupExpr final
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)
- {}
+ : OverloadExpr(UnresolvedLookupExprClass, C, QualifierLoc, TemplateKWLoc,
+ NameInfo, TemplateArgs, Begin, End, false, false, false),
+ RequiresADL(RequiresADL),
+ Overloaded(Overloaded), NamingClass(NamingClass) {}
UnresolvedLookupExpr(EmptyShell Empty)
- : OverloadExpr(UnresolvedLookupExprClass, Empty),
- RequiresADL(false), Overloaded(false), NamingClass(nullptr)
- {}
+ : OverloadExpr(UnresolvedLookupExprClass, Empty) {}
- friend TrailingObjects;
- friend class OverloadExpr;
- friend class ASTStmtReader;
+ size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
+ return HasTemplateKWAndArgsInfo ? 1 : 0;
+ }
public:
static UnresolvedLookupExpr *Create(const ASTContext &C,
@@ -2743,6 +2821,7 @@ public:
return l.getBeginLoc();
return getNameInfo().getLocStart();
}
+
SourceLocation getLocEnd() const LLVM_READONLY {
if (hasExplicitTemplateArgs())
return getRAngleLoc();
@@ -2788,17 +2867,21 @@ class DependentScopeDeclRefExpr final
/// keyword and arguments.
bool HasTemplateKWAndArgsInfo;
- size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
- return HasTemplateKWAndArgsInfo ? 1 : 0;
- }
-
DependentScopeDeclRefExpr(QualType T,
NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateKWLoc,
const DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo *Args);
+ size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
+ return HasTemplateKWAndArgsInfo ? 1 : 0;
+ }
+
public:
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+ friend TrailingObjects;
+
static DependentScopeDeclRefExpr *Create(const ASTContext &C,
NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateKWLoc,
@@ -2888,6 +2971,7 @@ public:
SourceLocation getLocStart() const LLVM_READONLY {
return QualifierLoc.getBeginLoc();
}
+
SourceLocation getLocEnd() const LLVM_READONLY {
if (hasExplicitTemplateArgs())
return getRAngleLoc();
@@ -2901,10 +2985,6 @@ public:
child_range children() {
return child_range(child_iterator(), child_iterator());
}
-
- friend TrailingObjects;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
};
/// Represents an expression -- generally a full-expression -- that
@@ -2925,18 +3005,18 @@ public:
/// It's useful to remember the set of blocks; we could also
/// remember the set of temporaries, but there's currently
/// no need.
- typedef BlockDecl *CleanupObject;
+ using CleanupObject = BlockDecl *;
private:
+ friend class ASTStmtReader;
+ friend TrailingObjects;
+
Stmt *SubExpr;
ExprWithCleanups(EmptyShell, unsigned NumObjects);
ExprWithCleanups(Expr *SubExpr, bool CleanupsHaveSideEffects,
ArrayRef<CleanupObject> Objects);
- friend TrailingObjects;
- friend class ASTStmtReader;
-
public:
static ExprWithCleanups *Create(const ASTContext &C, EmptyShell empty,
unsigned numObjects);
@@ -2959,6 +3039,7 @@ public:
Expr *getSubExpr() { return cast<Expr>(SubExpr); }
const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
+
bool cleanupsHaveSideEffects() const {
return ExprWithCleanupsBits.CleanupsHaveSideEffects;
}
@@ -2970,6 +3051,7 @@ public:
SourceLocation getLocStart() const LLVM_READONLY {
return SubExpr->getLocStart();
}
+
SourceLocation getLocEnd() const LLVM_READONLY { return SubExpr->getLocEnd();}
// Implement isa/cast/dyncast/etc.
@@ -3005,8 +3087,11 @@ public:
class CXXUnresolvedConstructExpr final
: public Expr,
private llvm::TrailingObjects<CXXUnresolvedConstructExpr, Expr *> {
+ friend class ASTStmtReader;
+ friend TrailingObjects;
+
/// \brief The type being constructed.
- TypeSourceInfo *Type;
+ TypeSourceInfo *Type = nullptr;
/// \brief The location of the left parentheses ('(').
SourceLocation LParenLoc;
@@ -3023,10 +3108,7 @@ class CXXUnresolvedConstructExpr final
SourceLocation RParenLoc);
CXXUnresolvedConstructExpr(EmptyShell Empty, unsigned NumArgs)
- : Expr(CXXUnresolvedConstructExprClass, Empty), Type(), NumArgs(NumArgs) { }
-
- friend TrailingObjects;
- friend class ASTStmtReader;
+ : Expr(CXXUnresolvedConstructExprClass, Empty), NumArgs(NumArgs) {}
public:
static CXXUnresolvedConstructExpr *Create(const ASTContext &C,
@@ -3056,14 +3138,21 @@ public:
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+ /// Determine whether this expression models list-initialization.
+ /// If so, there will be exactly one subexpression, which will be
+ /// an InitListExpr.
+ bool isListInitialization() const { return LParenLoc.isInvalid(); }
+
/// \brief Retrieve the number of arguments.
unsigned arg_size() const { return NumArgs; }
- typedef Expr** arg_iterator;
+ using arg_iterator = Expr **;
+
arg_iterator arg_begin() { return getTrailingObjects<Expr *>(); }
arg_iterator arg_end() { return arg_begin() + NumArgs; }
- typedef const Expr* const * const_arg_iterator;
+ using const_arg_iterator = const Expr* const *;
+
const_arg_iterator arg_begin() const { return getTrailingObjects<Expr *>(); }
const_arg_iterator arg_end() const {
return arg_begin() + NumArgs;
@@ -3085,6 +3174,7 @@ public:
}
SourceLocation getLocStart() const LLVM_READONLY;
+
SourceLocation getLocEnd() const LLVM_READONLY {
if (!RParenLoc.isValid() && NumArgs > 0)
return getArg(NumArgs - 1)->getLocEnd();
@@ -3165,6 +3255,10 @@ class CXXDependentScopeMemberExpr final
const TemplateArgumentListInfo *TemplateArgs);
public:
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+ friend TrailingObjects;
+
CXXDependentScopeMemberExpr(const ASTContext &C, Expr *Base,
QualType BaseType, bool IsArrow,
SourceLocation OperatorLoc,
@@ -3214,7 +3308,6 @@ public:
/// name, with source location information.
NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
-
/// \brief Retrieve the first part of the nested-name-specifier that was
/// found in the scope of the member access expression when the member access
/// was initially parsed.
@@ -3326,10 +3419,6 @@ public:
return child_range(child_iterator(), child_iterator());
return child_range(&Base, &Base + 1);
}
-
- friend TrailingObjects;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
};
/// \brief Represents a C++ member access expression for which lookup
@@ -3351,6 +3440,10 @@ class UnresolvedMemberExpr final
: public OverloadExpr,
private llvm::TrailingObjects<
UnresolvedMemberExpr, ASTTemplateKWAndArgsInfo, TemplateArgumentLoc> {
+ friend class ASTStmtReader;
+ friend class OverloadExpr;
+ friend TrailingObjects;
+
/// \brief Whether this member expression used the '->' operator or
/// the '.' operator.
bool IsArrow : 1;
@@ -3363,7 +3456,7 @@ class UnresolvedMemberExpr final
/// e.g., the \c x in x.f.
///
/// This can be null if this is an 'unbased' member expression.
- Stmt *Base;
+ Stmt *Base = nullptr;
/// \brief The type of the base expression; never null.
QualType BaseType;
@@ -3371,10 +3464,6 @@ class UnresolvedMemberExpr final
/// \brief The location of the '->' or '.' operator.
SourceLocation OperatorLoc;
- size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
- return HasTemplateKWAndArgsInfo ? 1 : 0;
- }
-
UnresolvedMemberExpr(const ASTContext &C, bool HasUnresolvedUsing,
Expr *Base, QualType BaseType, bool IsArrow,
SourceLocation OperatorLoc,
@@ -3385,12 +3474,12 @@ class UnresolvedMemberExpr final
UnresolvedSetIterator Begin, UnresolvedSetIterator End);
UnresolvedMemberExpr(EmptyShell Empty)
- : OverloadExpr(UnresolvedMemberExprClass, Empty), IsArrow(false),
- HasUnresolvedUsing(false), Base(nullptr) { }
+ : OverloadExpr(UnresolvedMemberExprClass, Empty), IsArrow(false),
+ HasUnresolvedUsing(false) {}
- friend TrailingObjects;
- friend class OverloadExpr;
- friend class ASTStmtReader;
+ size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
+ return HasTemplateKWAndArgsInfo ? 1 : 0;
+ }
public:
static UnresolvedMemberExpr *
@@ -3463,6 +3552,7 @@ public:
return l.getBeginLoc();
return getMemberNameInfo().getLocStart();
}
+
SourceLocation getLocEnd() const LLVM_READONLY {
if (hasExplicitTemplateArgs())
return getRAngleLoc();
@@ -3508,26 +3598,23 @@ inline TemplateArgumentLoc *OverloadExpr::getTrailingTemplateArgumentLoc() {
/// The noexcept expression tests whether a given expression might throw. Its
/// result is a boolean constant.
class CXXNoexceptExpr : public Expr {
+ friend class ASTStmtReader;
+
bool Value : 1;
Stmt *Operand;
SourceRange Range;
- friend class ASTStmtReader;
-
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,
- Val == CT_Dependent || Operand->isInstantiationDependent(),
- Operand->containsUnexpandedParameterPack()),
- Value(Val == CT_Cannot), Operand(Operand), Range(Keyword, RParen)
- { }
-
- CXXNoexceptExpr(EmptyShell Empty)
- : Expr(CXXNoexceptExprClass, Empty)
- { }
+ : Expr(CXXNoexceptExprClass, Ty, VK_RValue, OK_Ordinary,
+ /*TypeDependent*/false,
+ /*ValueDependent*/Val == CT_Dependent,
+ Val == CT_Dependent || Operand->isInstantiationDependent(),
+ Operand->containsUnexpandedParameterPack()),
+ Value(Val == CT_Cannot), Operand(Operand), Range(Keyword, RParen) {}
+
+ CXXNoexceptExpr(EmptyShell Empty) : Expr(CXXNoexceptExprClass, Empty) {}
Expr *getOperand() const { return static_cast<Expr*>(Operand); }
@@ -3563,6 +3650,9 @@ public:
/// template is instantiated, the pack expansion will instantiate to zero or
/// or more function arguments to the function object \c f.
class PackExpansionExpr : public Expr {
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+
SourceLocation EllipsisLoc;
/// \brief The number of expansions that will be produced by this pack
@@ -3574,21 +3664,18 @@ class PackExpansionExpr : public Expr {
Stmt *Pattern;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-
public:
PackExpansionExpr(QualType T, Expr *Pattern, SourceLocation EllipsisLoc,
Optional<unsigned> NumExpansions)
- : Expr(PackExpansionExprClass, T, Pattern->getValueKind(),
- Pattern->getObjectKind(), /*TypeDependent=*/true,
- /*ValueDependent=*/true, /*InstantiationDependent=*/true,
- /*ContainsUnexpandedParameterPack=*/false),
- EllipsisLoc(EllipsisLoc),
- NumExpansions(NumExpansions? *NumExpansions + 1 : 0),
- Pattern(Pattern) { }
+ : Expr(PackExpansionExprClass, T, Pattern->getValueKind(),
+ Pattern->getObjectKind(), /*TypeDependent=*/true,
+ /*ValueDependent=*/true, /*InstantiationDependent=*/true,
+ /*ContainsUnexpandedParameterPack=*/false),
+ EllipsisLoc(EllipsisLoc),
+ NumExpansions(NumExpansions ? *NumExpansions + 1 : 0),
+ Pattern(Pattern) {}
- PackExpansionExpr(EmptyShell Empty) : Expr(PackExpansionExprClass, Empty) { }
+ PackExpansionExpr(EmptyShell Empty) : Expr(PackExpansionExprClass, Empty) {}
/// \brief Retrieve the pattern of the pack expansion.
Expr *getPattern() { return reinterpret_cast<Expr *>(Pattern); }
@@ -3612,6 +3699,7 @@ public:
SourceLocation getLocStart() const LLVM_READONLY {
return Pattern->getLocStart();
}
+
SourceLocation getLocEnd() const LLVM_READONLY { return EllipsisLoc; }
static bool classof(const Stmt *T) {
@@ -3624,7 +3712,6 @@ public:
}
};
-
/// \brief Represents an expression that computes the length of a parameter
/// pack.
///
@@ -3637,6 +3724,10 @@ public:
class SizeOfPackExpr final
: public Expr,
private llvm::TrailingObjects<SizeOfPackExpr, TemplateArgument> {
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+ friend TrailingObjects;
+
/// \brief The location of the \c sizeof keyword.
SourceLocation OperatorLoc;
@@ -3659,11 +3750,7 @@ class SizeOfPackExpr final
unsigned Length;
/// \brief The parameter pack.
- NamedDecl *Pack;
-
- friend TrailingObjects;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
+ NamedDecl *Pack = nullptr;
/// \brief Create an expression that computes the length of
/// the given parameter pack.
@@ -3684,7 +3771,7 @@ class SizeOfPackExpr final
/// \brief Create an empty expression.
SizeOfPackExpr(EmptyShell Empty, unsigned NumPartialArgs)
- : Expr(SizeOfPackExprClass, Empty), Length(NumPartialArgs), Pack() {}
+ : Expr(SizeOfPackExprClass, Empty), Length(NumPartialArgs) {}
public:
static SizeOfPackExpr *Create(ASTContext &Context, SourceLocation OperatorLoc,
@@ -3749,6 +3836,9 @@ public:
/// \brief Represents a reference to a non-type template parameter
/// that has been substituted with a template argument.
class SubstNonTypeTemplateParmExpr : public Expr {
+ friend class ASTReader;
+ friend class ASTStmtReader;
+
/// \brief The replaced parameter.
NonTypeTemplateParmDecl *Param;
@@ -3758,10 +3848,8 @@ class SubstNonTypeTemplateParmExpr : public Expr {
/// \brief The location of the non-type template parameter reference.
SourceLocation NameLoc;
- friend class ASTReader;
- friend class ASTStmtReader;
explicit SubstNonTypeTemplateParmExpr(EmptyShell Empty)
- : Expr(SubstNonTypeTemplateParmExprClass, Empty) { }
+ : Expr(SubstNonTypeTemplateParmExprClass, Empty) {}
public:
SubstNonTypeTemplateParmExpr(QualType type,
@@ -3769,11 +3857,11 @@ public:
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) {}
+ : 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; }
@@ -3804,6 +3892,9 @@ public:
/// arguments), this type will be replaced with the appropriate underlying
/// expression at the current pack substitution index.
class SubstNonTypeTemplateParmPackExpr : public Expr {
+ friend class ASTReader;
+ friend class ASTStmtReader;
+
/// \brief The non-type template parameter pack itself.
NonTypeTemplateParmDecl *Param;
@@ -3817,10 +3908,8 @@ class SubstNonTypeTemplateParmPackExpr : public Expr {
/// \brief The location of the non-type template parameter pack reference.
SourceLocation NameLoc;
- friend class ASTReader;
- friend class ASTStmtReader;
explicit SubstNonTypeTemplateParmPackExpr(EmptyShell Empty)
- : Expr(SubstNonTypeTemplateParmPackExprClass, Empty) { }
+ : Expr(SubstNonTypeTemplateParmPackExprClass, Empty) {}
public:
SubstNonTypeTemplateParmPackExpr(QualType T,
@@ -3868,6 +3957,10 @@ public:
class FunctionParmPackExpr final
: public Expr,
private llvm::TrailingObjects<FunctionParmPackExpr, ParmVarDecl *> {
+ friend class ASTReader;
+ friend class ASTStmtReader;
+ friend TrailingObjects;
+
/// \brief The function parameter pack which was referenced.
ParmVarDecl *ParamPack;
@@ -3881,10 +3974,6 @@ class FunctionParmPackExpr final
SourceLocation NameLoc, unsigned NumParams,
ParmVarDecl *const *Params);
- friend TrailingObjects;
- friend class ASTReader;
- friend class ASTStmtReader;
-
public:
static FunctionParmPackExpr *Create(const ASTContext &Context, QualType T,
ParmVarDecl *ParamPack,
@@ -3901,7 +3990,7 @@ public:
/// \brief Iterators over the parameters which the parameter pack expanded
/// into.
- typedef ParmVarDecl * const *iterator;
+ using iterator = ParmVarDecl * const *;
iterator begin() const { return getTrailingObjects<ParmVarDecl *>(); }
iterator end() const { return begin() + NumParameters; }
@@ -3945,6 +4034,9 @@ public:
/// declaration which is responsible for the lifetime extension.
class MaterializeTemporaryExpr : public Expr {
private:
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+
struct ExtraState {
/// \brief The temporary-generating expression whose value will be
/// materialized.
@@ -3958,24 +4050,21 @@ private:
};
llvm::PointerUnion<Stmt *, ExtraState *> State;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-
void initializeExtraState(const ValueDecl *ExtendedBy,
unsigned ManglingNumber);
public:
MaterializeTemporaryExpr(QualType T, Expr *Temporary,
bool BoundToLvalueReference)
- : Expr(MaterializeTemporaryExprClass, T,
- BoundToLvalueReference? VK_LValue : VK_XValue, OK_Ordinary,
- Temporary->isTypeDependent(), Temporary->isValueDependent(),
- Temporary->isInstantiationDependent(),
- Temporary->containsUnexpandedParameterPack()),
+ : Expr(MaterializeTemporaryExprClass, T,
+ BoundToLvalueReference? VK_LValue : VK_XValue, OK_Ordinary,
+ Temporary->isTypeDependent(), Temporary->isValueDependent(),
+ Temporary->isInstantiationDependent(),
+ Temporary->containsUnexpandedParameterPack()),
State(Temporary) {}
MaterializeTemporaryExpr(EmptyShell Empty)
- : Expr(MaterializeTemporaryExprClass, Empty) { }
+ : Expr(MaterializeTemporaryExprClass, Empty) {}
Stmt *getTemporary() const {
return State.is<Stmt *>() ? State.get<Stmt *>()
@@ -4026,6 +4115,7 @@ public:
SourceLocation getLocStart() const LLVM_READONLY {
return getTemporary()->getLocStart();
}
+
SourceLocation getLocEnd() const LLVM_READONLY {
return getTemporary()->getLocEnd();
}
@@ -4053,14 +4143,15 @@ public:
/// ( ... op expr )
/// ( expr op ... op expr )
class CXXFoldExpr : public Expr {
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+
SourceLocation LParenLoc;
SourceLocation EllipsisLoc;
SourceLocation RParenLoc;
Stmt *SubExprs[2];
BinaryOperatorKind Opcode;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
public:
CXXFoldExpr(QualType T, SourceLocation LParenLoc, Expr *LHS,
BinaryOperatorKind Opcode, SourceLocation EllipsisLoc, Expr *RHS,
@@ -4073,6 +4164,7 @@ public:
SubExprs[0] = LHS;
SubExprs[1] = RHS;
}
+
CXXFoldExpr(EmptyShell Empty) : Expr(CXXFoldExprClass, Empty) {}
Expr *getLHS() const { return static_cast<Expr*>(SubExprs[0]); }
@@ -4082,10 +4174,13 @@ public:
bool isRightFold() const {
return getLHS() && getLHS()->containsUnexpandedParameterPack();
}
+
/// Does this produce a left-associated sequence of operators?
bool isLeftFold() const { return !isRightFold(); }
+
/// Get the pattern, that is, the operand that contains an unexpanded pack.
Expr *getPattern() const { return isLeftFold() ? getRHS() : getLHS(); }
+
/// Get the operand that doesn't contain a pack, for a binary fold.
Expr *getInit() const { return isLeftFold() ? getLHS() : getRHS(); }
@@ -4095,6 +4190,7 @@ public:
SourceLocation getLocStart() const LLVM_READONLY {
return LParenLoc;
}
+
SourceLocation getLocEnd() const LLVM_READONLY {
return RParenLoc;
}
@@ -4121,13 +4217,15 @@ public:
/// expression is evaluated, and its result is the result of the overall
/// expression.
class CoroutineSuspendExpr : public Expr {
+ friend class ASTStmtReader;
+
SourceLocation KeywordLoc;
enum SubExpr { Common, Ready, Suspend, Resume, Count };
+
Stmt *SubExprs[SubExpr::Count];
OpaqueValueExpr *OpaqueValue = nullptr;
- friend class ASTStmtReader;
public:
CoroutineSuspendExpr(StmtClass SC, SourceLocation KeywordLoc, Expr *Common,
Expr *Ready, Expr *Suspend, Expr *Resume,
@@ -4142,6 +4240,7 @@ public:
SubExprs[SubExpr::Suspend] = Suspend;
SubExprs[SubExpr::Resume] = Resume;
}
+
CoroutineSuspendExpr(StmtClass SC, SourceLocation KeywordLoc, QualType Ty,
Expr *Common)
: Expr(SC, Ty, VK_RValue, OK_Ordinary, true, true, true,
@@ -4154,6 +4253,7 @@ public:
SubExprs[SubExpr::Suspend] = nullptr;
SubExprs[SubExpr::Resume] = nullptr;
}
+
CoroutineSuspendExpr(StmtClass SC, EmptyShell Empty) : Expr(SC, Empty) {
SubExprs[SubExpr::Common] = nullptr;
SubExprs[SubExpr::Ready] = nullptr;
@@ -4162,18 +4262,22 @@ public:
}
SourceLocation getKeywordLoc() const { return KeywordLoc; }
+
Expr *getCommonExpr() const {
return static_cast<Expr*>(SubExprs[SubExpr::Common]);
}
+
/// \brief getOpaqueValue - Return the opaque value placeholder.
OpaqueValueExpr *getOpaqueValue() const { return OpaqueValue; }
Expr *getReadyExpr() const {
return static_cast<Expr*>(SubExprs[SubExpr::Ready]);
}
+
Expr *getSuspendExpr() const {
return static_cast<Expr*>(SubExprs[SubExpr::Suspend]);
}
+
Expr *getResumeExpr() const {
return static_cast<Expr*>(SubExprs[SubExpr::Resume]);
}
@@ -4181,6 +4285,7 @@ public:
SourceLocation getLocStart() const LLVM_READONLY {
return KeywordLoc;
}
+
SourceLocation getLocEnd() const LLVM_READONLY {
return getCommonExpr()->getLocEnd();
}
@@ -4198,6 +4303,7 @@ public:
/// \brief Represents a 'co_await' expression.
class CoawaitExpr : public CoroutineSuspendExpr {
friend class ASTStmtReader;
+
public:
CoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand, Expr *Ready,
Expr *Suspend, Expr *Resume, OpaqueValueExpr *OpaqueValue,
@@ -4206,11 +4312,13 @@ public:
Suspend, Resume, OpaqueValue) {
CoawaitBits.IsImplicit = IsImplicit;
}
+
CoawaitExpr(SourceLocation CoawaitLoc, QualType Ty, Expr *Operand,
bool IsImplicit = false)
: CoroutineSuspendExpr(CoawaitExprClass, CoawaitLoc, Ty, Operand) {
CoawaitBits.IsImplicit = IsImplicit;
}
+
CoawaitExpr(EmptyShell Empty)
: CoroutineSuspendExpr(CoawaitExprClass, Empty) {}
@@ -4230,11 +4338,11 @@ public:
/// \brief Represents a 'co_await' expression while the type of the promise
/// is dependent.
class DependentCoawaitExpr : public Expr {
+ friend class ASTStmtReader;
+
SourceLocation KeywordLoc;
Stmt *SubExprs[2];
- friend class ASTStmtReader;
-
public:
DependentCoawaitExpr(SourceLocation KeywordLoc, QualType Ty, Expr *Op,
UnresolvedLookupExpr *OpCoawait)
@@ -4255,12 +4363,15 @@ public:
: Expr(DependentCoawaitExprClass, Empty) {}
Expr *getOperand() const { return cast<Expr>(SubExprs[0]); }
+
UnresolvedLookupExpr *getOperatorCoawaitLookup() const {
return cast<UnresolvedLookupExpr>(SubExprs[1]);
}
+
SourceLocation getKeywordLoc() const { return KeywordLoc; }
SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; }
+
SourceLocation getLocEnd() const LLVM_READONLY {
return getOperand()->getLocEnd();
}
@@ -4275,6 +4386,7 @@ public:
/// \brief Represents a 'co_yield' expression.
class CoyieldExpr : public CoroutineSuspendExpr {
friend class ASTStmtReader;
+
public:
CoyieldExpr(SourceLocation CoyieldLoc, Expr *Operand, Expr *Ready,
Expr *Suspend, Expr *Resume, OpaqueValueExpr *OpaqueValue)
@@ -4295,6 +4407,6 @@ public:
}
};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_AST_EXPRCXX_H
diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h
index cd9381758618..ab2df8a34819 100644
--- a/include/clang/AST/ExprObjC.h
+++ b/include/clang/AST/ExprObjC.h
@@ -1,4 +1,4 @@
-//===--- ExprObjC.h - Classes for representing ObjC expressions -*- C++ -*-===//
+//===- ExprObjC.h - Classes for representing ObjC expressions ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,28 +14,51 @@
#ifndef LLVM_CLANG_AST_EXPROBJC_H
#define LLVM_CLANG_AST_EXPROBJC_H
+#include "clang/AST/Decl.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/Expr.h"
+#include "clang/AST/OperationKinds.h"
#include "clang/AST/SelectorLocationsKind.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/Type.h"
#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/Specifiers.h"
+#include "clang/Basic/VersionTuple.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/TrailingObjects.h"
+#include "llvm/Support/type_traits.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
namespace clang {
- class IdentifierInfo;
- class ASTContext;
+
+class ASTContext;
+class CXXBaseSpecifier;
/// ObjCStringLiteral, used for Objective-C string literals
/// i.e. @"foo".
class ObjCStringLiteral : public Expr {
Stmt *String;
SourceLocation AtLoc;
+
public:
ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L)
- : Expr(ObjCStringLiteralClass, T, VK_RValue, OK_Ordinary, false, false,
- false, false),
- String(SL), AtLoc(L) {}
+ : Expr(ObjCStringLiteralClass, T, VK_RValue, OK_Ordinary, false, false,
+ false, false),
+ String(SL), AtLoc(L) {}
explicit ObjCStringLiteral(EmptyShell Empty)
- : Expr(ObjCStringLiteralClass, Empty) {}
+ : Expr(ObjCStringLiteralClass, Empty) {}
StringLiteral *getString() { return cast<StringLiteral>(String); }
const StringLiteral *getString() const { return cast<StringLiteral>(String); }
@@ -47,26 +70,26 @@ public:
SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
SourceLocation getLocEnd() const LLVM_READONLY { return String->getLocEnd(); }
+ // Iterators
+ child_range children() { return child_range(&String, &String+1); }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCStringLiteralClass;
}
-
- // Iterators
- child_range children() { return child_range(&String, &String+1); }
};
/// ObjCBoolLiteralExpr - Objective-C Boolean Literal.
-///
class ObjCBoolLiteralExpr : public Expr {
bool Value;
SourceLocation Loc;
+
public:
- ObjCBoolLiteralExpr(bool val, QualType Ty, SourceLocation l) :
- Expr(ObjCBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
- false, false), Value(val), Loc(l) {}
-
+ ObjCBoolLiteralExpr(bool val, QualType Ty, SourceLocation l)
+ : Expr(ObjCBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
+ false, false),
+ Value(val), Loc(l) {}
explicit ObjCBoolLiteralExpr(EmptyShell Empty)
- : Expr(ObjCBoolLiteralExprClass, Empty) { }
+ : Expr(ObjCBoolLiteralExprClass, Empty) {}
bool getValue() const { return Value; }
void setValue(bool V) { Value = V; }
@@ -77,14 +100,14 @@ public:
SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCBoolLiteralExprClass;
- }
-
// Iterators
child_range children() {
return child_range(child_iterator(), child_iterator());
}
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCBoolLiteralExprClass;
+ }
};
/// ObjCBoxedExpr - used for generalized expression boxing.
@@ -95,15 +118,19 @@ class ObjCBoxedExpr : public Expr {
Stmt *SubExpr;
ObjCMethodDecl *BoxingMethod;
SourceRange Range;
+
public:
+ friend class ASTStmtReader;
+
ObjCBoxedExpr(Expr *E, QualType T, ObjCMethodDecl *method,
SourceRange R)
- : Expr(ObjCBoxedExprClass, T, VK_RValue, OK_Ordinary,
- E->isTypeDependent(), E->isValueDependent(),
- E->isInstantiationDependent(), E->containsUnexpandedParameterPack()),
- SubExpr(E), BoxingMethod(method), Range(R) {}
+ : Expr(ObjCBoxedExprClass, T, VK_RValue, OK_Ordinary,
+ E->isTypeDependent(), E->isValueDependent(),
+ E->isInstantiationDependent(),
+ E->containsUnexpandedParameterPack()),
+ SubExpr(E), BoxingMethod(method), Range(R) {}
explicit ObjCBoxedExpr(EmptyShell Empty)
- : Expr(ObjCBoxedExprClass, Empty) {}
+ : Expr(ObjCBoxedExprClass, Empty) {}
Expr *getSubExpr() { return cast<Expr>(SubExpr); }
const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
@@ -116,27 +143,27 @@ public:
SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
+
SourceRange getSourceRange() const LLVM_READONLY {
return Range;
}
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCBoxedExprClass;
- }
-
// Iterators
child_range children() { return child_range(&SubExpr, &SubExpr+1); }
- typedef ConstExprIterator const_arg_iterator;
+ using const_arg_iterator = ConstExprIterator;
const_arg_iterator arg_begin() const {
return reinterpret_cast<Stmt const * const*>(&SubExpr);
}
+
const_arg_iterator arg_end() const {
return reinterpret_cast<Stmt const * const*>(&SubExpr + 1);
}
-
- friend class ASTStmtReader;
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCBoxedExprClass;
+ }
};
/// ObjCArrayLiteral - used for objective-c array containers; as in:
@@ -153,9 +180,12 @@ class ObjCArrayLiteral final
SourceRange SR);
explicit ObjCArrayLiteral(EmptyShell Empty, unsigned NumElements)
- : Expr(ObjCArrayLiteralClass, Empty), NumElements(NumElements) {}
+ : Expr(ObjCArrayLiteralClass, Empty), NumElements(NumElements) {}
public:
+ friend class ASTStmtReader;
+ friend TrailingObjects;
+
static ObjCArrayLiteral *Create(const ASTContext &C,
ArrayRef<Expr *> Elements,
QualType T, ObjCMethodDecl * Method,
@@ -168,10 +198,6 @@ public:
SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
SourceRange getSourceRange() const LLVM_READONLY { return Range; }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCArrayLiteralClass;
- }
-
/// \brief Retrieve elements of array of literals.
Expr **getElements() { return getTrailingObjects<Expr *>(); }
@@ -183,7 +209,7 @@ public:
/// getNumElements - Return number of elements of objective-c array literal.
unsigned getNumElements() const { return NumElements; }
- /// getExpr - Return the Expr at the specified index.
+ /// getElement - Return the Element at the specified index.
Expr *getElement(unsigned Index) {
assert((Index < NumElements) && "Arg access out of range!");
return cast<Expr>(getElements()[Index]);
@@ -203,8 +229,9 @@ public:
reinterpret_cast<Stmt **>(getElements()) + NumElements);
}
- friend TrailingObjects;
- friend class ASTStmtReader;
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCArrayLiteralClass;
+ }
};
/// \brief An element in an Objective-C dictionary literal.
@@ -226,13 +253,17 @@ struct ObjCDictionaryElement {
/// \brief Determines whether this dictionary element is a pack expansion.
bool isPackExpansion() const { return EllipsisLoc.isValid(); }
};
-} // end namespace clang
+
+} // namespace clang
namespace llvm {
+
template <> struct isPodLike<clang::ObjCDictionaryElement> : std::true_type {};
-}
+
+} // namespace llvm
namespace clang {
+
/// \brief Internal struct for storing Key/value pair.
struct ObjCDictionaryLiteral_KeyValuePair {
Expr *Key;
@@ -274,12 +305,8 @@ class ObjCDictionaryLiteral final
SourceRange Range;
ObjCMethodDecl *DictWithObjectsMethod;
- typedef ObjCDictionaryLiteral_KeyValuePair KeyValuePair;
- typedef ObjCDictionaryLiteral_ExpansionData ExpansionData;
-
- size_t numTrailingObjects(OverloadToken<KeyValuePair>) const {
- return NumElements;
- }
+ using KeyValuePair = ObjCDictionaryLiteral_KeyValuePair;
+ using ExpansionData = ObjCDictionaryLiteral_ExpansionData;
ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK,
bool HasPackExpansions,
@@ -288,10 +315,18 @@ class ObjCDictionaryLiteral final
explicit ObjCDictionaryLiteral(EmptyShell Empty, unsigned NumElements,
bool HasPackExpansions)
- : Expr(ObjCDictionaryLiteralClass, Empty), NumElements(NumElements),
- HasPackExpansions(HasPackExpansions) {}
+ : Expr(ObjCDictionaryLiteralClass, Empty), NumElements(NumElements),
+ HasPackExpansions(HasPackExpansions) {}
+
+ size_t numTrailingObjects(OverloadToken<KeyValuePair>) const {
+ return NumElements;
+ }
public:
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+ friend TrailingObjects;
+
static ObjCDictionaryLiteral *Create(const ASTContext &C,
ArrayRef<ObjCDictionaryElement> VK,
bool HasPackExpansions,
@@ -320,17 +355,14 @@ public:
return Result;
}
- ObjCMethodDecl *getDictWithObjectsMethod() const
- { return DictWithObjectsMethod; }
+ ObjCMethodDecl *getDictWithObjectsMethod() const {
+ return DictWithObjectsMethod;
+ }
SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
SourceRange getSourceRange() const LLVM_READONLY { return Range; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCDictionaryLiteralClass;
- }
-
+
// Iterators
child_range children() {
// Note: we're taking advantage of the layout of the KeyValuePair struct
@@ -342,12 +374,11 @@ public:
reinterpret_cast<Stmt **>(getTrailingObjects<KeyValuePair>()) +
NumElements * 2);
}
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
- friend TrailingObjects;
-};
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCDictionaryLiteralClass;
+ }
+};
/// ObjCEncodeExpr, used for \@encode in Objective-C. \@encode has the same
/// type and behavior as StringLiteral except that the string initializer is
@@ -355,19 +386,19 @@ public:
class ObjCEncodeExpr : public Expr {
TypeSourceInfo *EncodedType;
SourceLocation AtLoc, RParenLoc;
+
public:
ObjCEncodeExpr(QualType T, TypeSourceInfo *EncodedType,
SourceLocation at, SourceLocation rp)
- : Expr(ObjCEncodeExprClass, T, VK_LValue, OK_Ordinary,
- EncodedType->getType()->isDependentType(),
- EncodedType->getType()->isDependentType(),
- EncodedType->getType()->isInstantiationDependentType(),
- EncodedType->getType()->containsUnexpandedParameterPack()),
- EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {}
+ : Expr(ObjCEncodeExprClass, T, VK_LValue, OK_Ordinary,
+ EncodedType->getType()->isDependentType(),
+ EncodedType->getType()->isDependentType(),
+ EncodedType->getType()->isInstantiationDependentType(),
+ EncodedType->getType()->containsUnexpandedParameterPack()),
+ EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {}
explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){}
-
SourceLocation getAtLoc() const { return AtLoc; }
void setAtLoc(SourceLocation L) { AtLoc = L; }
SourceLocation getRParenLoc() const { return RParenLoc; }
@@ -376,6 +407,7 @@ public:
QualType getEncodedType() const { return EncodedType->getType(); }
TypeSourceInfo *getEncodedTypeSourceInfo() const { return EncodedType; }
+
void setEncodedTypeSourceInfo(TypeSourceInfo *EncType) {
EncodedType = EncType;
}
@@ -383,28 +415,29 @@ public:
SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCEncodeExprClass;
- }
-
// Iterators
child_range children() {
return child_range(child_iterator(), child_iterator());
}
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCEncodeExprClass;
+ }
};
/// ObjCSelectorExpr used for \@selector in Objective-C.
class ObjCSelectorExpr : public Expr {
Selector SelName;
SourceLocation AtLoc, RParenLoc;
+
public:
ObjCSelectorExpr(QualType T, Selector selInfo,
SourceLocation at, SourceLocation rp)
- : Expr(ObjCSelectorExprClass, T, VK_RValue, OK_Ordinary, false, false,
- false, false),
- SelName(selInfo), AtLoc(at), RParenLoc(rp){}
+ : Expr(ObjCSelectorExprClass, T, VK_RValue, OK_Ordinary, false, false,
+ false, false),
+ SelName(selInfo), AtLoc(at), RParenLoc(rp) {}
explicit ObjCSelectorExpr(EmptyShell Empty)
- : Expr(ObjCSelectorExprClass, Empty) {}
+ : Expr(ObjCSelectorExprClass, Empty) {}
Selector getSelector() const { return SelName; }
void setSelector(Selector S) { SelName = S; }
@@ -420,14 +453,14 @@ public:
/// getNumArgs - Return the number of actual arguments to this call.
unsigned getNumArgs() const { return SelName.getNumArgs(); }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCSelectorExprClass;
- }
-
// Iterators
child_range children() {
return child_range(child_iterator(), child_iterator());
}
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCSelectorExprClass;
+ }
};
/// ObjCProtocolExpr used for protocol expression in Objective-C.
@@ -441,14 +474,18 @@ public:
class ObjCProtocolExpr : public Expr {
ObjCProtocolDecl *TheProtocol;
SourceLocation AtLoc, ProtoLoc, RParenLoc;
+
public:
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+
ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol,
SourceLocation at, SourceLocation protoLoc, SourceLocation rp)
- : Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary, false, false,
- false, false),
- TheProtocol(protocol), AtLoc(at), ProtoLoc(protoLoc), RParenLoc(rp) {}
+ : Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary, false, false,
+ false, false),
+ TheProtocol(protocol), AtLoc(at), ProtoLoc(protoLoc), RParenLoc(rp) {}
explicit ObjCProtocolExpr(EmptyShell Empty)
- : Expr(ObjCProtocolExprClass, Empty) {}
+ : Expr(ObjCProtocolExprClass, Empty) {}
ObjCProtocolDecl *getProtocol() const { return TheProtocol; }
void setProtocol(ObjCProtocolDecl *P) { TheProtocol = P; }
@@ -462,17 +499,14 @@ public:
SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCProtocolExprClass;
- }
-
// Iterators
child_range children() {
return child_range(child_iterator(), child_iterator());
}
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCProtocolExprClass;
+ }
};
/// ObjCIvarRefExpr - A reference to an ObjC instance variable.
@@ -480,27 +514,31 @@ class ObjCIvarRefExpr : public Expr {
ObjCIvarDecl *D;
Stmt *Base;
SourceLocation Loc;
+
/// OpLoc - This is the location of '.' or '->'
SourceLocation OpLoc;
-
- bool IsArrow:1; // True if this is "X->F", false if this is "X.F".
- bool IsFreeIvar:1; // True if ivar reference has no base (self assumed).
+
+ // True if this is "X->F", false if this is "X.F".
+ bool IsArrow : 1;
+
+ // True if ivar reference has no base (self assumed).
+ bool IsFreeIvar : 1;
public:
ObjCIvarRefExpr(ObjCIvarDecl *d, QualType t,
SourceLocation l, SourceLocation oploc,
Expr *base,
- bool arrow = false, bool freeIvar = false) :
- Expr(ObjCIvarRefExprClass, t, VK_LValue,
- d->isBitField() ? OK_BitField : OK_Ordinary,
- /*TypeDependent=*/false, base->isValueDependent(),
- base->isInstantiationDependent(),
- base->containsUnexpandedParameterPack()),
- D(d), Base(base), Loc(l), OpLoc(oploc),
- IsArrow(arrow), IsFreeIvar(freeIvar) {}
+ bool arrow = false, bool freeIvar = false)
+ : Expr(ObjCIvarRefExprClass, t, VK_LValue,
+ d->isBitField() ? OK_BitField : OK_Ordinary,
+ /*TypeDependent=*/false, base->isValueDependent(),
+ base->isInstantiationDependent(),
+ base->containsUnexpandedParameterPack()),
+ D(d), Base(base), Loc(l), OpLoc(oploc), IsArrow(arrow),
+ IsFreeIvar(freeIvar) {}
explicit ObjCIvarRefExpr(EmptyShell Empty)
- : Expr(ObjCIvarRefExprClass, Empty) {}
+ : Expr(ObjCIvarRefExprClass, Empty) {}
ObjCIvarDecl *getDecl() { return D; }
const ObjCIvarDecl *getDecl() const { return D; }
@@ -526,12 +564,12 @@ public:
SourceLocation getOpLoc() const { return OpLoc; }
void setOpLoc(SourceLocation L) { OpLoc = L; }
+ // Iterators
+ child_range children() { return child_range(&Base, &Base+1); }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCIvarRefExprClass;
}
-
- // Iterators
- child_range children() { return child_range(&Base, &Base+1); }
};
/// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC
@@ -542,7 +580,7 @@ private:
/// pointer is an (optional) ObjCMethodDecl and Setter may be set.
/// if the bool is false, this is an explicit property reference;
/// the pointer is an ObjCPropertyDecl and Setter is always null.
- llvm::PointerIntPair<NamedDecl*, 1, bool> PropertyOrGetter;
+ llvm::PointerIntPair<NamedDecl *, 1, bool> PropertyOrGetter;
/// \brief Indicates whether the property reference will result in a message
/// to the getter, the setter, or both.
@@ -567,40 +605,39 @@ private:
/// the location of the 'super' keyword. When it's an interface,
/// this is that interface.
SourceLocation ReceiverLoc;
- llvm::PointerUnion3<Stmt*, const Type*, ObjCInterfaceDecl*> Receiver;
+ llvm::PointerUnion3<Stmt *, const Type *, ObjCInterfaceDecl *> Receiver;
public:
ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
ExprValueKind VK, ExprObjectKind OK,
SourceLocation l, Expr *base)
- : Expr(ObjCPropertyRefExprClass, t, VK, OK,
- /*TypeDependent=*/false, base->isValueDependent(),
- base->isInstantiationDependent(),
- base->containsUnexpandedParameterPack()),
- PropertyOrGetter(PD, false), SetterAndMethodRefFlags(),
- IdLoc(l), ReceiverLoc(), Receiver(base) {
+ : Expr(ObjCPropertyRefExprClass, t, VK, OK,
+ /*TypeDependent=*/false, base->isValueDependent(),
+ base->isInstantiationDependent(),
+ base->containsUnexpandedParameterPack()),
+ PropertyOrGetter(PD, false), IdLoc(l), Receiver(base) {
assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject));
}
ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
ExprValueKind VK, ExprObjectKind OK,
SourceLocation l, SourceLocation sl, QualType st)
- : Expr(ObjCPropertyRefExprClass, t, VK, OK,
- /*TypeDependent=*/false, false, st->isInstantiationDependentType(),
- st->containsUnexpandedParameterPack()),
- PropertyOrGetter(PD, false), SetterAndMethodRefFlags(),
- IdLoc(l), ReceiverLoc(sl), Receiver(st.getTypePtr()) {
+ : Expr(ObjCPropertyRefExprClass, t, VK, OK,
+ /*TypeDependent=*/false, false, st->isInstantiationDependentType(),
+ st->containsUnexpandedParameterPack()),
+ PropertyOrGetter(PD, false), IdLoc(l), ReceiverLoc(sl),
+ Receiver(st.getTypePtr()) {
assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject));
}
ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
QualType T, ExprValueKind VK, ExprObjectKind OK,
SourceLocation IdLoc, Expr *Base)
- : Expr(ObjCPropertyRefExprClass, T, VK, OK, false,
- Base->isValueDependent(), Base->isInstantiationDependent(),
- Base->containsUnexpandedParameterPack()),
- PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
- IdLoc(IdLoc), ReceiverLoc(), Receiver(Base) {
+ : Expr(ObjCPropertyRefExprClass, T, VK, OK, false,
+ Base->isValueDependent(), Base->isInstantiationDependent(),
+ Base->containsUnexpandedParameterPack()),
+ PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
+ IdLoc(IdLoc), Receiver(Base) {
assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
}
@@ -608,9 +645,9 @@ public:
QualType T, ExprValueKind VK, ExprObjectKind OK,
SourceLocation IdLoc,
SourceLocation SuperLoc, QualType SuperTy)
- : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false),
- PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
- IdLoc(IdLoc), ReceiverLoc(SuperLoc), Receiver(SuperTy.getTypePtr()) {
+ : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false),
+ PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
+ IdLoc(IdLoc), ReceiverLoc(SuperLoc), Receiver(SuperTy.getTypePtr()) {
assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
}
@@ -618,14 +655,14 @@ public:
QualType T, ExprValueKind VK, ExprObjectKind OK,
SourceLocation IdLoc,
SourceLocation ReceiverLoc, ObjCInterfaceDecl *Receiver)
- : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false),
- PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
- IdLoc(IdLoc), ReceiverLoc(ReceiverLoc), Receiver(Receiver) {
+ : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false),
+ PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
+ IdLoc(IdLoc), ReceiverLoc(ReceiverLoc), Receiver(Receiver) {
assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
}
explicit ObjCPropertyRefExpr(EmptyShell Empty)
- : Expr(ObjCPropertyRefExprClass, Empty) {}
+ : Expr(ObjCPropertyRefExprClass, Empty) {}
bool isImplicitProperty() const { return PropertyOrGetter.getInt(); }
bool isExplicitProperty() const { return !PropertyOrGetter.getInt(); }
@@ -689,6 +726,7 @@ public:
SourceLocation getLocation() const { return IdLoc; }
SourceLocation getReceiverLocation() const { return ReceiverLoc; }
+
QualType getSuperReceiverType() const {
return QualType(Receiver.get<const Type*>(), 0);
}
@@ -696,6 +734,7 @@ public:
ObjCInterfaceDecl *getClassReceiver() const {
return Receiver.get<ObjCInterfaceDecl*>();
}
+
bool isObjectReceiver() const { return Receiver.is<Stmt*>(); }
bool isSuperReceiver() const { return Receiver.is<const Type*>(); }
bool isClassReceiver() const { return Receiver.is<ObjCInterfaceDecl*>(); }
@@ -706,11 +745,8 @@ public:
SourceLocation getLocStart() const LLVM_READONLY {
return isObjectReceiver() ? getBase()->getLocStart() :getReceiverLocation();
}
- SourceLocation getLocEnd() const LLVM_READONLY { return IdLoc; }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCPropertyRefExprClass;
- }
+ SourceLocation getLocEnd() const LLVM_READONLY { return IdLoc; }
// Iterators
child_range children() {
@@ -721,15 +757,21 @@ public:
return child_range(child_iterator(), child_iterator());
}
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCPropertyRefExprClass;
+ }
+
private:
friend class ASTStmtReader;
friend class ASTStmtWriter;
+
void setExplicitProperty(ObjCPropertyDecl *D, unsigned methRefFlags) {
PropertyOrGetter.setPointer(D);
PropertyOrGetter.setInt(false);
SetterAndMethodRefFlags.setPointer(nullptr);
SetterAndMethodRefFlags.setInt(methRefFlags);
}
+
void setImplicitProperty(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
unsigned methRefFlags) {
PropertyOrGetter.setPointer(Getter);
@@ -737,6 +779,7 @@ private:
SetterAndMethodRefFlags.setPointer(Setter);
SetterAndMethodRefFlags.setInt(methRefFlags);
}
+
void setBase(Expr *Base) { Receiver = Base; }
void setSuperReceiver(QualType T) { Receiver = T.getTypePtr(); }
void setClassReceiver(ObjCInterfaceDecl *D) { Receiver = D; }
@@ -756,10 +799,10 @@ private:
/// ObjCSubscriptRefExpr - used for array and dictionary subscripting.
/// array[4] = array[3]; dictionary[key] = dictionary[alt_key];
-///
class ObjCSubscriptRefExpr : public Expr {
// Location of ']' in an indexing expression.
SourceLocation RBracket;
+
// array/dictionary base expression.
// for arrays, this is a numeric expression. For dictionaries, this is
// an objective-c object pointer expression.
@@ -773,24 +816,24 @@ class ObjCSubscriptRefExpr : public Expr {
ObjCMethodDecl *SetAtIndexMethodDecl;
public:
-
ObjCSubscriptRefExpr(Expr *base, Expr *key, QualType T,
ExprValueKind VK, ExprObjectKind OK,
ObjCMethodDecl *getMethod,
ObjCMethodDecl *setMethod, SourceLocation RB)
- : Expr(ObjCSubscriptRefExprClass, T, VK, OK,
- base->isTypeDependent() || key->isTypeDependent(),
- base->isValueDependent() || key->isValueDependent(),
- base->isInstantiationDependent() || key->isInstantiationDependent(),
- (base->containsUnexpandedParameterPack() ||
- key->containsUnexpandedParameterPack())),
- RBracket(RB),
- GetAtIndexMethodDecl(getMethod),
- SetAtIndexMethodDecl(setMethod)
- {SubExprs[BASE] = base; SubExprs[KEY] = key;}
+ : Expr(ObjCSubscriptRefExprClass, T, VK, OK,
+ base->isTypeDependent() || key->isTypeDependent(),
+ base->isValueDependent() || key->isValueDependent(),
+ (base->isInstantiationDependent() ||
+ key->isInstantiationDependent()),
+ (base->containsUnexpandedParameterPack() ||
+ key->containsUnexpandedParameterPack())),
+ RBracket(RB), GetAtIndexMethodDecl(getMethod),
+ SetAtIndexMethodDecl(setMethod) {
+ SubExprs[BASE] = base; SubExprs[KEY] = key;
+ }
explicit ObjCSubscriptRefExpr(EmptyShell Empty)
- : Expr(ObjCSubscriptRefExprClass, Empty) {}
+ : Expr(ObjCSubscriptRefExprClass, Empty) {}
SourceLocation getRBracket() const { return RBracket; }
void setRBracket(SourceLocation RB) { RBracket = RB; }
@@ -798,11 +841,8 @@ public:
SourceLocation getLocStart() const LLVM_READONLY {
return SubExprs[BASE]->getLocStart();
}
- SourceLocation getLocEnd() const LLVM_READONLY { return RBracket; }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCSubscriptRefExprClass;
- }
+ SourceLocation getLocEnd() const LLVM_READONLY { return RBracket; }
Expr *getBaseExpr() const { return cast<Expr>(SubExprs[BASE]); }
void setBaseExpr(Stmt *S) { SubExprs[BASE] = S; }
@@ -825,10 +865,14 @@ public:
child_range children() {
return child_range(SubExprs, SubExprs+END_EXPR);
}
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCSubscriptRefExprClass;
+ }
+
private:
friend class ASTStmtReader;
};
-
/// \brief An expression that sends a message to the given Objective-C
/// object or class.
@@ -856,14 +900,13 @@ private:
/// The "void *" trailing objects are actually ONE void * (the
/// receiver pointer), and NumArgs Expr *. But due to the
/// implementation of children(), these must be together contiguously.
-
class ObjCMessageExpr final
: public Expr,
private llvm::TrailingObjects<ObjCMessageExpr, void *, SourceLocation> {
/// \brief Stores either the selector that this message is sending
/// to (when \c HasMethod is zero) or an \c ObjCMethodDecl pointer
/// referring to the method that we type-checked against.
- uintptr_t SelectorOrMethod;
+ uintptr_t SelectorOrMethod = 0;
enum { NumArgsBitWidth = 16 };
@@ -904,16 +947,9 @@ class ObjCMessageExpr final
/// brackets ('[' and ']', respectively).
SourceLocation LBracLoc, RBracLoc;
- size_t numTrailingObjects(OverloadToken<void *>) const { return NumArgs + 1; }
-
- void setNumArgs(unsigned Num) {
- assert((Num >> NumArgsBitWidth) == 0 && "Num of args is out of range!");
- NumArgs = Num;
- }
-
ObjCMessageExpr(EmptyShell Empty, unsigned NumArgs)
- : Expr(ObjCMessageExprClass, Empty), SelectorOrMethod(0), Kind(0),
- HasMethod(0), IsDelegateInitCall(0), IsImplicit(0), SelLocsKind(0) {
+ : Expr(ObjCMessageExprClass, Empty), Kind(0), HasMethod(false),
+ IsDelegateInitCall(false), IsImplicit(false), SelLocsKind(0) {
setNumArgs(NumArgs);
}
@@ -950,6 +986,13 @@ class ObjCMessageExpr final
SourceLocation RBracLoc,
bool isImplicit);
+ size_t numTrailingObjects(OverloadToken<void *>) const { return NumArgs + 1; }
+
+ void setNumArgs(unsigned Num) {
+ assert((Num >> NumArgsBitWidth) == 0 && "Num of args is out of range!");
+ NumArgs = Num;
+ }
+
void initArgsAndSelLocs(ArrayRef<Expr *> Args,
ArrayRef<SourceLocation> SelLocs,
SelectorLocationsKind SelLocsK);
@@ -965,6 +1008,7 @@ class ObjCMessageExpr final
SelectorLocationsKind getSelLocsKind() const {
return (SelectorLocationsKind)SelLocsKind;
}
+
bool hasStandardSelLocs() const {
return getSelLocsKind() != SelLoc_NonStandard;
}
@@ -997,14 +1041,21 @@ class ObjCMessageExpr final
unsigned NumStoredSelLocs);
public:
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+ friend TrailingObjects;
+
/// \brief The kind of receiver this message is sending to.
enum ReceiverKind {
/// \brief The receiver is a class.
Class = 0,
+
/// \brief The receiver is an object instance.
Instance,
+
/// \brief The receiver is a superclass.
SuperClass,
+
/// \brief The receiver is the instance of the superclass object.
SuperInstance
};
@@ -1029,7 +1080,7 @@ public:
/// \param Sel The selector used to determine which method gets called.
///
/// \param Method The Objective-C method against which this message
- /// send was type-checked. May be NULL.
+ /// send was type-checked. May be nullptr.
///
/// \param Args The message send arguments.
///
@@ -1065,7 +1116,7 @@ public:
/// \param Sel The selector used to determine which method gets called.
///
/// \param Method The Objective-C method against which this message
- /// send was type-checked. May be NULL.
+ /// send was type-checked. May be nullptr.
///
/// \param Args The message send arguments.
///
@@ -1099,7 +1150,7 @@ public:
/// \param Sel The selector used to determine which method gets called.
///
/// \param Method The Objective-C method against which this message
- /// send was type-checked. May be NULL.
+ /// send was type-checked. May be nullptr.
///
/// \param Args The message send arguments.
///
@@ -1175,11 +1226,11 @@ public:
if (TypeSourceInfo *TSInfo = getClassReceiverTypeInfo())
return TSInfo->getType();
- return QualType();
+ return {};
}
/// \brief Returns a type-source information of a class message
- /// send, or NULL if the message is not a class message.
+ /// send, or nullptr if the message is not a class message.
TypeSourceInfo *getClassReceiverTypeInfo() const {
if (getReceiverKind() == Class)
return reinterpret_cast<TypeSourceInfo *>(getReceiverPointer());
@@ -1220,7 +1271,7 @@ public:
/// whether the message is a class or an instance method, whether it
/// is a send to super or not, etc.
///
- /// \returns The Objective-C interface if known, otherwise NULL.
+ /// \returns The Objective-C interface if known, otherwise nullptr.
ObjCInterfaceDecl *getReceiverInterface() const;
/// \brief Retrieve the type referred to by 'super'.
@@ -1295,6 +1346,7 @@ public:
assert(Arg < NumArgs && "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!");
@@ -1315,6 +1367,7 @@ public:
return getLocStart();
return getSelectorLoc(0);
}
+
SourceLocation getSelectorLoc(unsigned Index) const {
assert(Index < getNumSelectorLocs() && "Index out of range!");
if (hasStandardSelLocs())
@@ -1341,18 +1394,15 @@ public:
LBracLoc = R.getBegin();
RBracLoc = R.getEnd();
}
+
SourceLocation getLocStart() const LLVM_READONLY { return LBracLoc; }
SourceLocation getLocEnd() const LLVM_READONLY { return RBracLoc; }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCMessageExprClass;
- }
-
// Iterators
child_range children();
- typedef ExprIterator arg_iterator;
- typedef ConstExprIterator const_arg_iterator;
+ using arg_iterator = ExprIterator;
+ using const_arg_iterator = ConstExprIterator;
llvm::iterator_range<arg_iterator> arguments() {
return llvm::make_range(arg_begin(), arg_end());
@@ -1363,19 +1413,22 @@ public:
}
arg_iterator arg_begin() { return reinterpret_cast<Stmt **>(getArgs()); }
+
arg_iterator arg_end() {
return reinterpret_cast<Stmt **>(getArgs() + NumArgs);
}
+
const_arg_iterator arg_begin() const {
return reinterpret_cast<Stmt const * const*>(getArgs());
}
+
const_arg_iterator arg_end() const {
return reinterpret_cast<Stmt const * const*>(getArgs() + NumArgs);
}
- friend TrailingObjects;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCMessageExprClass;
+ }
};
/// ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
@@ -1392,17 +1445,18 @@ class ObjCIsaExpr : public Expr {
/// IsArrow - True if this is "X->F", false if this is "X.F".
bool IsArrow;
+
public:
ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, SourceLocation oploc,
QualType ty)
- : Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary,
- /*TypeDependent=*/false, base->isValueDependent(),
- base->isInstantiationDependent(),
- /*ContainsUnexpandedParameterPack=*/false),
- Base(base), IsaMemberLoc(l), OpLoc(oploc), IsArrow(isarrow) {}
+ : Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary,
+ /*TypeDependent=*/false, base->isValueDependent(),
+ base->isInstantiationDependent(),
+ /*ContainsUnexpandedParameterPack=*/false),
+ Base(base), IsaMemberLoc(l), OpLoc(oploc), IsArrow(isarrow) {}
/// \brief Build an empty expression.
- explicit ObjCIsaExpr(EmptyShell Empty) : Expr(ObjCIsaExprClass, Empty) { }
+ explicit ObjCIsaExpr(EmptyShell Empty) : Expr(ObjCIsaExprClass, Empty) {}
void setBase(Expr *E) { Base = E; }
Expr *getBase() const { return cast<Expr>(Base); }
@@ -1430,15 +1484,14 @@ public:
SourceLocation getExprLoc() const LLVM_READONLY { return IsaMemberLoc; }
+ // Iterators
+ child_range children() { return child_range(&Base, &Base+1); }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCIsaExprClass;
}
-
- // Iterators
- child_range children() { return child_range(&Base, &Base+1); }
};
-
/// ObjCIndirectCopyRestoreExpr - Represents the passing of a function
/// argument by indirect copy-restore in ARC. This is used to support
/// passing indirect arguments with the wrong lifetime, e.g. when
@@ -1462,27 +1515,27 @@ public:
/// __autoreleasing; this qualifier is ignored when initializing
/// the value.
class ObjCIndirectCopyRestoreExpr : public Expr {
+ friend class ASTReader;
+ friend class ASTStmtReader;
+
Stmt *Operand;
// unsigned ObjCIndirectCopyRestoreBits.ShouldCopy : 1;
- friend class ASTReader;
- friend class ASTStmtReader;
+ explicit ObjCIndirectCopyRestoreExpr(EmptyShell Empty)
+ : Expr(ObjCIndirectCopyRestoreExprClass, Empty) {}
void setShouldCopy(bool shouldCopy) {
ObjCIndirectCopyRestoreExprBits.ShouldCopy = shouldCopy;
}
- explicit ObjCIndirectCopyRestoreExpr(EmptyShell Empty)
- : Expr(ObjCIndirectCopyRestoreExprClass, Empty) { }
-
public:
ObjCIndirectCopyRestoreExpr(Expr *operand, QualType type, bool shouldCopy)
- : Expr(ObjCIndirectCopyRestoreExprClass, type, VK_LValue, OK_Ordinary,
- operand->isTypeDependent(), operand->isValueDependent(),
- operand->isInstantiationDependent(),
- operand->containsUnexpandedParameterPack()),
- Operand(operand) {
+ : Expr(ObjCIndirectCopyRestoreExprClass, type, VK_LValue, OK_Ordinary,
+ operand->isTypeDependent(), operand->isValueDependent(),
+ operand->isInstantiationDependent(),
+ operand->containsUnexpandedParameterPack()),
+ Operand(operand) {
setShouldCopy(shouldCopy);
}
@@ -1519,26 +1572,26 @@ public:
class ObjCBridgedCastExpr final
: public ExplicitCastExpr,
private llvm::TrailingObjects<ObjCBridgedCastExpr, CXXBaseSpecifier *> {
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+ friend class CastExpr;
+ friend TrailingObjects;
+
SourceLocation LParenLoc;
SourceLocation BridgeKeywordLoc;
unsigned Kind : 2;
- friend TrailingObjects;
- friend class CastExpr;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-
public:
ObjCBridgedCastExpr(SourceLocation LParenLoc, ObjCBridgeCastKind Kind,
CastKind CK, SourceLocation BridgeKeywordLoc,
TypeSourceInfo *TSInfo, Expr *Operand)
- : ExplicitCastExpr(ObjCBridgedCastExprClass, TSInfo->getType(), VK_RValue,
- CK, Operand, 0, TSInfo),
- LParenLoc(LParenLoc), BridgeKeywordLoc(BridgeKeywordLoc), Kind(Kind) { }
+ : ExplicitCastExpr(ObjCBridgedCastExprClass, TSInfo->getType(), VK_RValue,
+ CK, Operand, 0, TSInfo),
+ LParenLoc(LParenLoc), BridgeKeywordLoc(BridgeKeywordLoc), Kind(Kind) {}
/// \brief Construct an empty Objective-C bridged cast.
explicit ObjCBridgedCastExpr(EmptyShell Shell)
- : ExplicitCastExpr(ObjCBridgedCastExprClass, Shell, 0) { }
+ : ExplicitCastExpr(ObjCBridgedCastExprClass, Shell, 0) {}
SourceLocation getLParenLoc() const { return LParenLoc; }
@@ -1554,6 +1607,7 @@ public:
SourceLocation getBridgeKeywordLoc() const { return BridgeKeywordLoc; }
SourceLocation getLocStart() const LLVM_READONLY { return LParenLoc; }
+
SourceLocation getLocEnd() const LLVM_READONLY {
return getSubExpr()->getLocEnd();
}
@@ -1577,10 +1631,11 @@ public:
/// expressions.
///
class ObjCAvailabilityCheckExpr : public Expr {
+ friend class ASTStmtReader;
+
VersionTuple VersionToCheck;
SourceLocation AtLoc, RParen;
- friend class ASTStmtReader;
public:
ObjCAvailabilityCheckExpr(VersionTuple VersionToCheck, SourceLocation AtLoc,
SourceLocation RParen, QualType Ty)
@@ -1608,6 +1663,6 @@ public:
}
};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_AST_EXPROBJC_H
diff --git a/include/clang/AST/ExternalASTMerger.h b/include/clang/AST/ExternalASTMerger.h
index 51d0c30ad23b..81492aec6e13 100644
--- a/include/clang/AST/ExternalASTMerger.h
+++ b/include/clang/AST/ExternalASTMerger.h
@@ -16,34 +16,159 @@
#include "clang/AST/ASTImporter.h"
#include "clang/AST/ExternalASTSource.h"
+#include "llvm/Support/raw_ostream.h"
namespace clang {
+/// ExternalASTSource implementation that merges information from several
+/// ASTContexts.
+///
+/// ExtermalASTMerger maintains a vector of ASTImporters that it uses to import
+/// (potentially incomplete) Decls and DeclContexts from the source ASTContexts
+/// in response to ExternalASTSource API calls.
+///
+/// When lookup occurs in the resulting imported DeclContexts, the original
+/// DeclContexts need to be queried. Roughly, there are three cases here:
+///
+/// - The DeclContext of origin can be found by simple name lookup. In this
+/// case, no additional state is required.
+///
+/// - The DeclContext of origin is different from what would be found by name
+/// lookup. In this case, Origins contains an entry overriding lookup and
+/// specifying the correct pair of DeclContext/ASTContext.
+///
+/// - The DeclContext of origin was determined by another ExterenalASTMerger.
+/// (This is possible when the source ASTContext for one of the Importers has
+/// its own ExternalASTMerger). The origin must be properly forwarded in this
+/// case.
+///
+/// ExternalASTMerger's job is to maintain the data structures necessary to
+/// allow this. The data structures themselves can be extracted (read-only) and
+/// copied for re-use.
class ExternalASTMerger : public ExternalASTSource {
public:
- struct ImporterPair {
- std::unique_ptr<ASTImporter> Forward;
- std::unique_ptr<ASTImporter> Reverse;
+ /// A single origin for a DeclContext. Unlike Decls, DeclContexts do
+ /// not allow their containing ASTContext to be determined in all cases.
+ struct DCOrigin {
+ DeclContext *DC;
+ ASTContext *AST;
};
+ typedef std::map<const DeclContext *, DCOrigin> OriginMap;
+ typedef std::vector<std::unique_ptr<ASTImporter>> ImporterVector;
private:
- std::vector<ImporterPair> Importers;
+ /// One importer exists for each source.
+ ImporterVector Importers;
+ /// Overrides in case name lookup would return nothing or would return
+ /// the wrong thing.
+ OriginMap Origins;
+ /// The installed log stream.
+ llvm::raw_ostream *LogStream;
public:
- struct ImporterEndpoint {
+ /// The target for an ExternalASTMerger.
+ ///
+ /// ASTImporters require both ASTContext and FileManager to be able to
+ /// import SourceLocations properly.
+ struct ImporterTarget {
ASTContext &AST;
FileManager &FM;
};
- ExternalASTMerger(const ImporterEndpoint &Target,
- llvm::ArrayRef<ImporterEndpoint> Sources);
+ /// A source for an ExternalASTMerger.
+ ///
+ /// ASTImporters require both ASTContext and FileManager to be able to
+ /// import SourceLocations properly. Additionally, when import occurs for
+ /// a DeclContext whose origin has been overridden, then this
+ /// ExternalASTMerger must be able to determine that.
+ struct ImporterSource {
+ ASTContext &AST;
+ FileManager &FM;
+ const OriginMap &OM;
+ };
+private:
+ /// The target for this ExtenralASTMerger.
+ ImporterTarget Target;
+
+public:
+ ExternalASTMerger(const ImporterTarget &Target,
+ llvm::ArrayRef<ImporterSource> Sources);
+
+ /// Add a set of ASTContexts as possible origins.
+ ///
+ /// Usually the set will be initialized in the constructor, but long-lived
+ /// ExternalASTMergers may neeed to import from new sources (for example,
+ /// newly-parsed source files).
+ ///
+ /// Ensures that Importers does not gain duplicate entries as a result.
+ void AddSources(llvm::ArrayRef<ImporterSource> Sources);
+
+ /// Remove a set of ASTContexts as possible origins.
+ ///
+ /// Sometimes an origin goes away (for example, if a source file gets
+ /// superseded by a newer version).
+ ///
+ /// The caller is responsible for ensuring that this doesn't leave
+ /// DeclContexts that can't be completed.
+ void RemoveSources(llvm::ArrayRef<ImporterSource> Sources);
+
+ /// Implementation of the ExternalASTSource API.
bool FindExternalVisibleDeclsByName(const DeclContext *DC,
DeclarationName Name) override;
+ /// Implementation of the ExternalASTSource API.
void
FindExternalLexicalDecls(const DeclContext *DC,
llvm::function_ref<bool(Decl::Kind)> IsKindWeWant,
SmallVectorImpl<Decl *> &Result) override;
+
+ /// Implementation of the ExternalASTSource API.
+ void CompleteType(TagDecl *Tag) override;
+
+ /// Implementation of the ExternalASTSource API.
+ void CompleteType(ObjCInterfaceDecl *Interface) override;
+
+ /// Returns true if DC can be found in any source AST context.
+ bool CanComplete(DeclContext *DC);
+
+ /// Records an origin in Origins only if name lookup would find
+ /// something different or nothing at all.
+ void MaybeRecordOrigin(const DeclContext *ToDC, DCOrigin Origin);
+
+ /// Regardless of any checks, override the Origin for a DeclContext.
+ void ForceRecordOrigin(const DeclContext *ToDC, DCOrigin Origin);
+
+ /// Get a read-only view of the Origins map, for use in constructing
+ /// an ImporterSource for another ExternalASTMerger.
+ const OriginMap &GetOrigins() { return Origins; }
+
+ /// Returns true if Importers contains an ASTImporter whose source is
+ /// OriginContext.
+ bool HasImporterForOrigin(ASTContext &OriginContext);
+
+ /// Returns a reference to the ASTRImporter from Importers whose origin
+ /// is OriginContext. This allows manual import of ASTs while preserving the
+ /// OriginMap correctly.
+ ASTImporter &ImporterForOrigin(ASTContext &OriginContext);
+
+ /// Sets the current log stream.
+ void SetLogStream(llvm::raw_string_ostream &Stream) { LogStream = &Stream; }
+private:
+ /// Records and origin in Origins.
+ void RecordOriginImpl(const DeclContext *ToDC, DCOrigin Origin,
+ ASTImporter &importer);
+
+ /// Performs an action for every DeclContext that is identified as
+ /// corresponding (either by forced origin or by name lookup) to DC.
+ template <typename CallbackType>
+ void ForEachMatchingDC(const DeclContext *DC, CallbackType Callback);
+
+public:
+ /// Log something if there is a logging callback installed.
+ llvm::raw_ostream &logs() { return *LogStream; }
+
+ /// True if the log stream is not llvm::nulls();
+ bool LoggingEnabled() { return LogStream != &llvm::nulls(); }
};
} // end namespace clang
diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h
index d8dd18ecb8d3..be013c5d6b6a 100644
--- a/include/clang/AST/ExternalASTSource.h
+++ b/include/clang/AST/ExternalASTSource.h
@@ -1,4 +1,4 @@
-//===--- ExternalASTSource.h - Abstract External AST Interface --*- C++ -*-===//
+//===- ExternalASTSource.h - Abstract External AST Interface ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,24 +11,44 @@
// construction of AST nodes from some external source.
//
//===----------------------------------------------------------------------===//
+
#ifndef LLVM_CLANG_AST_EXTERNALASTSOURCE_H
#define LLVM_CLANG_AST_EXTERNALASTSOURCE_H
#include "clang/AST/CharUnits.h"
#include "clang/AST/DeclBase.h"
+#include "clang/Basic/LLVM.h"
#include "clang/Basic/Module.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator.h"
+#include "llvm/Support/PointerLikeTypeTraits.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <iterator>
+#include <string>
+#include <utility>
namespace clang {
class ASTConsumer;
+class ASTContext;
class CXXBaseSpecifier;
class CXXCtorInitializer;
+class CXXRecordDecl;
class DeclarationName;
-class ExternalSemaSource; // layering violation required for downcasting
class FieldDecl;
-class Module;
+class IdentifierInfo;
class NamedDecl;
+class ObjCInterfaceDecl;
class RecordDecl;
class Selector;
class Stmt;
@@ -42,30 +62,31 @@ class TagDecl;
/// actual type and declaration nodes, and read parts of declaration
/// contexts.
class ExternalASTSource : public RefCountedBase<ExternalASTSource> {
+ friend class ExternalSemaSource;
+
/// Generation number for this external AST source. Must be increased
/// whenever we might have added new redeclarations for existing decls.
- uint32_t CurrentGeneration;
+ uint32_t CurrentGeneration = 0;
/// \brief Whether this AST source also provides information for
/// semantic analysis.
- bool SemaSource;
-
- friend class ExternalSemaSource;
+ bool SemaSource = false;
public:
- ExternalASTSource() : CurrentGeneration(0), SemaSource(false) { }
-
+ ExternalASTSource() = default;
virtual ~ExternalASTSource();
/// \brief RAII class for safely pairing a StartedDeserializing call
/// with FinishedDeserializing.
class Deserializing {
ExternalASTSource *Source;
+
public:
explicit Deserializing(ExternalASTSource *source) : Source(source) {
assert(Source);
Source->StartedDeserializing();
}
+
~Deserializing() {
Source->FinishedDeserializing();
}
@@ -122,7 +143,7 @@ public:
virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset);
/// \brief Update an out-of-date identifier.
- virtual void updateOutOfDateIdentifier(IdentifierInfo &II) { }
+ virtual void updateOutOfDateIdentifier(IdentifierInfo &II) {}
/// \brief Find all declarations with the given name in the given context,
/// and add them to the context by calling SetExternalVisibleDeclsForName
@@ -154,12 +175,13 @@ public:
const Module *ClangModule = nullptr;
public:
- ASTSourceDescriptor(){};
+ ASTSourceDescriptor() = default;
ASTSourceDescriptor(StringRef Name, StringRef Path, StringRef ASTFile,
ASTFileSignature Signature)
: PCHModuleName(std::move(Name)), Path(std::move(Path)),
- ASTFile(std::move(ASTFile)), Signature(Signature){};
+ ASTFile(std::move(ASTFile)), Signature(Signature) {}
ASTSourceDescriptor(const Module &M);
+
std::string getModuleName() const;
StringRef getPath() const { return Path; }
StringRef getASTFile() const { return ASTFile; }
@@ -246,7 +268,6 @@ public:
/// The default implementation of this method is a no-op.
virtual void PrintStats();
-
/// \brief Perform layout on the given record.
///
/// This routine allows the external AST source to provide an specific
@@ -289,7 +310,7 @@ public:
size_t mmap_bytes;
MemoryBufferSizes(size_t malloc_bytes, size_t mmap_bytes)
- : malloc_bytes(malloc_bytes), mmap_bytes(mmap_bytes) {}
+ : malloc_bytes(malloc_bytes), mmap_bytes(mmap_bytes) {}
};
/// Return the amount of memory used by memory buffers, breaking down
@@ -329,12 +350,12 @@ struct LazyOffsetPtr {
///
/// If the low bit is clear, a pointer to the AST node. If the low
/// bit is set, the upper 63 bits are the offset.
- mutable uint64_t Ptr;
+ mutable uint64_t Ptr = 0;
public:
- LazyOffsetPtr() : Ptr(0) { }
+ LazyOffsetPtr() = default;
+ explicit LazyOffsetPtr(T *Ptr) : Ptr(reinterpret_cast<uint64_t>(Ptr)) {}
- explicit LazyOffsetPtr(T *Ptr) : Ptr(reinterpret_cast<uint64_t>(Ptr)) { }
explicit LazyOffsetPtr(uint64_t Offset) : Ptr((Offset << 1) | 0x01) {
assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits");
if (Offset == 0)
@@ -392,15 +413,16 @@ struct LazyGenerationalUpdatePtr {
/// A cache of the value of this pointer, in the most recent generation in
/// which we queried it.
struct LazyData {
- LazyData(ExternalASTSource *Source, T Value)
- : ExternalSource(Source), LastGeneration(0), LastValue(Value) {}
ExternalASTSource *ExternalSource;
- uint32_t LastGeneration;
+ uint32_t LastGeneration = 0;
T LastValue;
+
+ LazyData(ExternalASTSource *Source, T Value)
+ : ExternalSource(Source), LastValue(Value) {}
};
// Our value is represented as simply T if there is no external AST source.
- typedef llvm::PointerUnion<T, LazyData*> ValueType;
+ using ValueType = llvm::PointerUnion<T, LazyData*>;
ValueType Value;
LazyGenerationalUpdatePtr(ValueType V) : Value(V) {}
@@ -459,25 +481,31 @@ public:
return LazyGenerationalUpdatePtr(ValueType::getFromOpaqueValue(Ptr));
}
};
-} // end namespace clang
+
+} // namespace clang
/// Specialize PointerLikeTypeTraits to allow LazyGenerationalUpdatePtr to be
/// placed into a PointerUnion.
namespace llvm {
+
template<typename Owner, typename T,
void (clang::ExternalASTSource::*Update)(Owner)>
struct PointerLikeTypeTraits<
clang::LazyGenerationalUpdatePtr<Owner, T, Update>> {
- typedef clang::LazyGenerationalUpdatePtr<Owner, T, Update> Ptr;
+ using Ptr = clang::LazyGenerationalUpdatePtr<Owner, T, Update>;
+
static void *getAsVoidPointer(Ptr P) { return P.getOpaqueValue(); }
static Ptr getFromVoidPointer(void *P) { return Ptr::getFromOpaqueValue(P); }
+
enum {
NumLowBitsAvailable = PointerLikeTypeTraits<T>::NumLowBitsAvailable - 1
};
};
-}
+
+} // namespace llvm
namespace clang {
+
/// \brief Represents a lazily-loaded vector of data.
///
/// The lazily-loaded vector of data contains data that is partially loaded
@@ -511,13 +539,14 @@ public:
class iterator
: public llvm::iterator_adaptor_base<
iterator, int, std::random_access_iterator_tag, T, int, T *, T &> {
+ friend class LazyVector;
+
LazyVector *Self;
iterator(LazyVector *Self, int Position)
: iterator::iterator_adaptor_base(Position), Self(Self) {}
bool isLoaded() const { return this->I < 0; }
- friend class LazyVector;
public:
iterator() : iterator(nullptr, 0) {}
@@ -562,23 +591,23 @@ public:
};
/// \brief A lazy pointer to a statement.
-typedef LazyOffsetPtr<Stmt, uint64_t, &ExternalASTSource::GetExternalDeclStmt>
- LazyDeclStmtPtr;
+using LazyDeclStmtPtr =
+ LazyOffsetPtr<Stmt, uint64_t, &ExternalASTSource::GetExternalDeclStmt>;
/// \brief A lazy pointer to a declaration.
-typedef LazyOffsetPtr<Decl, uint32_t, &ExternalASTSource::GetExternalDecl>
- LazyDeclPtr;
+using LazyDeclPtr =
+ LazyOffsetPtr<Decl, uint32_t, &ExternalASTSource::GetExternalDecl>;
/// \brief A lazy pointer to a set of CXXCtorInitializers.
-typedef LazyOffsetPtr<CXXCtorInitializer *, uint64_t,
- &ExternalASTSource::GetExternalCXXCtorInitializers>
- LazyCXXCtorInitializersPtr;
+using LazyCXXCtorInitializersPtr =
+ LazyOffsetPtr<CXXCtorInitializer *, uint64_t,
+ &ExternalASTSource::GetExternalCXXCtorInitializers>;
/// \brief A lazy pointer to a set of CXXBaseSpecifiers.
-typedef LazyOffsetPtr<CXXBaseSpecifier, uint64_t,
- &ExternalASTSource::GetExternalCXXBaseSpecifiers>
- LazyCXXBaseSpecifiersPtr;
+using LazyCXXBaseSpecifiersPtr =
+ LazyOffsetPtr<CXXBaseSpecifier, uint64_t,
+ &ExternalASTSource::GetExternalCXXBaseSpecifiers>;
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_AST_EXTERNALASTSOURCE_H
diff --git a/include/clang/AST/GlobalDecl.h b/include/clang/AST/GlobalDecl.h
index adf63a3aea69..3b3e4367d56c 100644
--- a/include/clang/AST/GlobalDecl.h
+++ b/include/clang/AST/GlobalDecl.h
@@ -1,4 +1,4 @@
-//===--- GlobalDecl.h - Global declaration holder ---------------*- C++ -*-===//
+//===- GlobalDecl.h - Global declaration holder -----------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -19,6 +19,12 @@
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclOpenMP.h"
#include "clang/Basic/ABI.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/type_traits.h"
+#include <cassert>
namespace clang {
@@ -27,7 +33,7 @@ namespace clang {
/// a CXXDestructorDecl and the destructor type (Base, Complete) or
/// a VarDecl, a FunctionDecl or a BlockDecl.
class GlobalDecl {
- llvm::PointerIntPair<const Decl*, 2> Value;
+ llvm::PointerIntPair<const Decl *, 2> Value;
void Init(const Decl *D) {
assert(!isa<CXXConstructorDecl>(D) && "Use other ctor with ctor decls!");
@@ -37,19 +43,15 @@ class GlobalDecl {
}
public:
- GlobalDecl() {}
-
+ GlobalDecl() = default;
GlobalDecl(const VarDecl *D) { Init(D);}
GlobalDecl(const FunctionDecl *D) { Init(D); }
GlobalDecl(const BlockDecl *D) { Init(D); }
GlobalDecl(const CapturedDecl *D) { Init(D); }
GlobalDecl(const ObjCMethodDecl *D) { Init(D); }
GlobalDecl(const OMPDeclareReductionDecl *D) { Init(D); }
-
- GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type)
- : Value(D, Type) {}
- GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type)
- : Value(D, Type) {}
+ GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type) : Value(D, Type) {}
+ GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type) : Value(D, Type) {}
GlobalDecl getCanonicalDecl() const {
GlobalDecl CanonGD;
@@ -90,10 +92,9 @@ public:
}
};
-} // end namespace clang
+} // namespace clang
namespace llvm {
- template<class> struct DenseMapInfo;
template<> struct DenseMapInfo<clang::GlobalDecl> {
static inline clang::GlobalDecl getEmptyKey() {
@@ -113,7 +114,6 @@ namespace llvm {
clang::GlobalDecl RHS) {
return LHS == RHS;
}
-
};
// GlobalDecl isn't *technically* a POD type. However, its copy constructor,
@@ -122,6 +122,7 @@ namespace llvm {
struct isPodLike<clang::GlobalDecl> {
static const bool value = true;
};
-} // end namespace llvm
-#endif
+} // namespace llvm
+
+#endif // LLVM_CLANG_AST_GLOBALDECL_H
diff --git a/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h b/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h
new file mode 100644
index 000000000000..264f20f19ad5
--- /dev/null
+++ b/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h
@@ -0,0 +1,164 @@
+//===--- LexicallyOrderedRecursiveASTVisitor.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 the LexicallyOrderedRecursiveASTVisitor interface, which
+// recursively traverses the entire AST in a lexical order.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_LEXICALLY_ORDERED_RECURSIVEASTVISITOR_H
+#define LLVM_CLANG_AST_LEXICALLY_ORDERED_RECURSIVEASTVISITOR_H
+
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/Support/SaveAndRestore.h"
+
+namespace clang {
+
+/// A RecursiveASTVisitor subclass that guarantees that AST traversal is
+/// performed in a lexical order (i.e. the order in which declarations are
+/// written in the source).
+///
+/// RecursiveASTVisitor doesn't guarantee lexical ordering because there are
+/// some declarations, like Objective-C @implementation declarations
+/// that might be represented in the AST differently to how they were written
+/// in the source.
+/// In particular, Objective-C @implementation declarations may contain
+/// non-Objective-C declarations, like functions:
+///
+/// @implementation MyClass
+///
+/// - (void) method { }
+/// void normalFunction() { }
+///
+/// @end
+///
+/// Clang's AST stores these declarations outside of the @implementation
+/// declaration, so the example above would be represented using the following
+/// AST:
+/// |-ObjCImplementationDecl ... MyClass
+/// | `-ObjCMethodDecl ... method
+/// | ...
+/// `-FunctionDecl ... normalFunction
+/// ...
+///
+/// This class ensures that these declarations are traversed before the
+/// corresponding TraverseDecl for the @implementation returns. This ensures
+/// that the lexical parent relationship between these declarations and the
+/// @implementation is preserved while traversing the AST. Note that the
+/// current implementation doesn't mix these declarations with the declarations
+/// contained in the @implementation, so the traversal of all of the
+/// declarations in the @implementation still doesn't follow the lexical order.
+template <typename Derived>
+class LexicallyOrderedRecursiveASTVisitor
+ : public RecursiveASTVisitor<Derived> {
+ using BaseType = RecursiveASTVisitor<Derived>;
+
+public:
+ LexicallyOrderedRecursiveASTVisitor(const SourceManager &SM) : SM(SM) {}
+
+ bool TraverseObjCImplementationDecl(ObjCImplementationDecl *D) {
+ // Objective-C @implementation declarations should not trigger early exit
+ // until the additional decls are traversed as their children are not
+ // lexically ordered.
+ bool Result = BaseType::TraverseObjCImplementationDecl(D);
+ return TraverseAdditionalLexicallyNestedDeclarations() ? Result : false;
+ }
+
+ bool TraverseObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
+ bool Result = BaseType::TraverseObjCCategoryImplDecl(D);
+ return TraverseAdditionalLexicallyNestedDeclarations() ? Result : false;
+ }
+
+ bool TraverseDeclContextHelper(DeclContext *DC) {
+ if (!DC)
+ return true;
+
+ for (auto I = DC->decls_begin(), E = DC->decls_end(); I != E;) {
+ Decl *Child = *I;
+ if (BaseType::canIgnoreChildDeclWhileTraversingDeclContext(Child)) {
+ ++I;
+ continue;
+ }
+ if (!isa<ObjCImplementationDecl>(Child) &&
+ !isa<ObjCCategoryImplDecl>(Child)) {
+ if (!BaseType::getDerived().TraverseDecl(Child))
+ return false;
+ ++I;
+ continue;
+ }
+ // Gather declarations that follow the Objective-C implementation
+ // declarations but are lexically contained in the implementation.
+ LexicallyNestedDeclarations.clear();
+ for (++I; I != E; ++I) {
+ Decl *Sibling = *I;
+ if (!SM.isBeforeInTranslationUnit(Sibling->getLocStart(),
+ Child->getLocEnd()))
+ break;
+ if (!BaseType::canIgnoreChildDeclWhileTraversingDeclContext(Sibling))
+ LexicallyNestedDeclarations.push_back(Sibling);
+ }
+ if (!BaseType::getDerived().TraverseDecl(Child))
+ return false;
+ }
+ return true;
+ }
+
+ Stmt::child_range getStmtChildren(Stmt *S) { return S->children(); }
+
+ SmallVector<Stmt *, 8> getStmtChildren(CXXOperatorCallExpr *CE) {
+ SmallVector<Stmt *, 8> Children(CE->children());
+ bool Swap;
+ // Switch the operator and the first operand for all infix and postfix
+ // operations.
+ switch (CE->getOperator()) {
+ case OO_Arrow:
+ case OO_Call:
+ case OO_Subscript:
+ Swap = true;
+ break;
+ case OO_PlusPlus:
+ case OO_MinusMinus:
+ // These are postfix unless there is exactly one argument.
+ Swap = Children.size() != 2;
+ break;
+ default:
+ Swap = CE->isInfixBinaryOp();
+ break;
+ }
+ if (Swap && Children.size() > 1)
+ std::swap(Children[0], Children[1]);
+ return Children;
+ }
+
+private:
+ bool TraverseAdditionalLexicallyNestedDeclarations() {
+ // FIXME: Ideally the gathered declarations and the declarations in the
+ // @implementation should be mixed and sorted to get a true lexical order,
+ // but right now we only care about getting the correct lexical parent, so
+ // we can traverse the gathered nested declarations after the declarations
+ // in the decl context.
+ assert(!BaseType::getDerived().shouldTraversePostOrder() &&
+ "post-order traversal is not supported for lexically ordered "
+ "recursive ast visitor");
+ for (Decl *D : LexicallyNestedDeclarations) {
+ if (!BaseType::getDerived().TraverseDecl(D))
+ return false;
+ }
+ return true;
+ }
+
+ const SourceManager &SM;
+ llvm::SmallVector<Decl *, 8> LexicallyNestedDeclarations;
+};
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_AST_LEXICALLY_ORDERED_RECURSIVEASTVISITOR_H
diff --git a/include/clang/AST/NestedNameSpecifier.h b/include/clang/AST/NestedNameSpecifier.h
index b1ff9bdff589..e2cb45c36de6 100644
--- a/include/clang/AST/NestedNameSpecifier.h
+++ b/include/clang/AST/NestedNameSpecifier.h
@@ -1,4 +1,4 @@
-//===--- NestedNameSpecifier.h - C++ nested name specifiers -----*- C++ -*-===//
+//===- NestedNameSpecifier.h - C++ nested name specifiers -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,38 +11,42 @@
// a C++ nested-name-specifier.
//
//===----------------------------------------------------------------------===//
+
#ifndef LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
#define LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/Support/Compiler.h"
+#include <cstdint>
+#include <cstdlib>
+#include <utility>
namespace clang {
class ASTContext;
class CXXRecordDecl;
+class IdentifierInfo;
+class LangOptions;
class NamespaceAliasDecl;
class NamespaceDecl;
-class IdentifierInfo;
struct PrintingPolicy;
class Type;
class TypeLoc;
-class LangOptions;
/// \brief Represents a C++ nested name specifier, such as
/// "\::std::vector<int>::".
///
/// C++ nested name specifiers are the prefixes to qualified
-/// namespaces. For example, "foo::" in "foo::x" is a nested name
+/// names. For example, "foo::" in "foo::x" is a nested name
/// specifier. Nested name specifiers are made up of a sequence of
/// specifiers, each of which can be a namespace, type, identifier
/// (for dependent names), decltype specifier, or the global specifier ('::').
/// The last two specifiers can only appear at the start of a
/// nested-namespace-specifier.
class NestedNameSpecifier : public llvm::FoldingSetNode {
-
/// \brief Enumeration describing
enum StoredSpecifierKind {
StoredIdentifier = 0,
@@ -66,7 +70,7 @@ class NestedNameSpecifier : public llvm::FoldingSetNode {
/// specifier '::'. Otherwise, the pointer is one of
/// IdentifierInfo*, Namespace*, or Type*, depending on the kind of
/// specifier as encoded within the prefix.
- void* Specifier;
+ void* Specifier = nullptr;
public:
/// \brief The kind of specifier that completes this nested name
@@ -74,17 +78,23 @@ public:
enum SpecifierKind {
/// \brief An identifier, stored as an IdentifierInfo*.
Identifier,
+
/// \brief A namespace, stored as a NamespaceDecl*.
Namespace,
+
/// \brief A namespace alias, stored as a NamespaceAliasDecl*.
NamespaceAlias,
+
/// \brief A type, stored as a Type*.
TypeSpec,
+
/// \brief A type that was preceded by the 'template' keyword,
/// stored as a Type*.
TypeSpecWithTemplate,
+
/// \brief The global specifier '::'. There is no stored value.
Global,
+
/// \brief Microsoft's '__super' specifier, stored as a CXXRecordDecl* of
/// the class it appeared in.
Super
@@ -92,17 +102,11 @@ public:
private:
/// \brief Builds the global specifier.
- NestedNameSpecifier()
- : Prefix(nullptr, StoredIdentifier), Specifier(nullptr) {}
+ NestedNameSpecifier() : Prefix(nullptr, StoredIdentifier) {}
/// \brief Copy constructor used internally to clone nested name
/// specifiers.
- NestedNameSpecifier(const NestedNameSpecifier &Other)
- : llvm::FoldingSetNode(Other), Prefix(Other.Prefix),
- Specifier(Other.Specifier) {
- }
-
- void operator=(const NestedNameSpecifier &) = delete;
+ NestedNameSpecifier(const NestedNameSpecifier &Other) = default;
/// \brief Either find or insert the given nested name specifier
/// mockup in the given context.
@@ -110,6 +114,8 @@ private:
const NestedNameSpecifier &Mockup);
public:
+ NestedNameSpecifier &operator=(const NestedNameSpecifier &) = delete;
+
/// \brief Builds a specifier combining a prefix and an identifier.
///
/// The prefix must be dependent, since nested name specifiers
@@ -224,8 +230,8 @@ public:
/// \brief A C++ nested-name-specifier augmented with source location
/// information.
class NestedNameSpecifierLoc {
- NestedNameSpecifier *Qualifier;
- void *Data;
+ NestedNameSpecifier *Qualifier = nullptr;
+ void *Data = nullptr;
/// \brief Determines the data length for the last component in the
/// given nested-name-specifier.
@@ -237,12 +243,12 @@ class NestedNameSpecifierLoc {
public:
/// \brief Construct an empty nested-name-specifier.
- NestedNameSpecifierLoc() : Qualifier(nullptr), Data(nullptr) { }
+ NestedNameSpecifierLoc() = default;
/// \brief Construct a nested-name-specifier with source location information
/// from
NestedNameSpecifierLoc(NestedNameSpecifier *Qualifier, void *Data)
- : Qualifier(Qualifier), Data(Data) { }
+ : Qualifier(Qualifier), Data(Data) {}
/// \brief Evalutes true when this nested-name-specifier location is
/// non-empty.
@@ -339,7 +345,7 @@ public:
class NestedNameSpecifierLocBuilder {
/// \brief The current representation of the nested-name-specifier we're
/// building.
- NestedNameSpecifier *Representation;
+ NestedNameSpecifier *Representation = nullptr;
/// \brief Buffer used to store source-location information for the
/// nested-name-specifier.
@@ -347,21 +353,18 @@ class NestedNameSpecifierLocBuilder {
/// Note that we explicitly manage the buffer (rather than using a
/// SmallVector) because \c Declarator expects it to be possible to memcpy()
/// a \c CXXScopeSpec, and CXXScopeSpec uses a NestedNameSpecifierLocBuilder.
- char *Buffer;
+ char *Buffer = nullptr;
/// \brief The size of the buffer used to store source-location information
/// for the nested-name-specifier.
- unsigned BufferSize;
+ unsigned BufferSize = 0;
/// \brief The capacity of the buffer used to store source-location
/// information for the nested-name-specifier.
- unsigned BufferCapacity;
+ unsigned BufferCapacity = 0;
public:
- NestedNameSpecifierLocBuilder()
- : Representation(nullptr), Buffer(nullptr), BufferSize(0),
- BufferCapacity(0) {}
-
+ NestedNameSpecifierLocBuilder() = default;
NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other);
NestedNameSpecifierLocBuilder &
@@ -451,6 +454,7 @@ public:
/// \param ColonColonLoc The location of the trailing '::'.
void MakeSuper(ASTContext &Context, CXXRecordDecl *RD,
SourceLocation SuperLoc, SourceLocation ColonColonLoc);
+
/// \brief Make a new nested-name-specifier from incomplete source-location
/// information.
///
@@ -511,6 +515,6 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
return DB;
}
-}
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
diff --git a/include/clang/AST/OpenMPClause.h b/include/clang/AST/OpenMPClause.h
index a1cae8e18f84..1f732f67517a 100644
--- a/include/clang/AST/OpenMPClause.h
+++ b/include/clang/AST/OpenMPClause.h
@@ -6,35 +6,55 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
/// \file
/// \brief This file defines OpenMP AST classes for clauses.
/// There are clauses for executable directives, clauses for declarative
/// directives and clauses which can be used in both kinds of directives.
-///
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_OPENMPCLAUSE_H
#define LLVM_CLANG_AST_OPENMPCLAUSE_H
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclarationName.h"
#include "clang/AST/Expr.h"
+#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtIterator.h"
+#include "clang/Basic/LLVM.h"
#include "clang/Basic/OpenMPKinds.h"
#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/iterator.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/TrailingObjects.h"
+#include <cassert>
+#include <cstddef>
+#include <iterator>
+#include <utility>
namespace clang {
+class ASTContext;
+
//===----------------------------------------------------------------------===//
// AST classes for clauses.
//===----------------------------------------------------------------------===//
/// \brief This is a basic class for representing single OpenMP clause.
-///
class OMPClause {
/// \brief Starting location of the clause (the clause keyword).
SourceLocation StartLoc;
+
/// \brief Ending location of the clause.
SourceLocation EndLoc;
+
/// \brief Kind of the clause.
OpenMPClauseKind Kind;
@@ -45,11 +65,13 @@ protected:
public:
/// \brief Returns the starting location of the clause.
SourceLocation getLocStart() const { return StartLoc; }
+
/// \brief Returns the ending location of the clause.
SourceLocation getLocEnd() const { return EndLoc; }
/// \brief Sets the starting location of the clause.
void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
+
/// \brief Sets the ending location of the clause.
void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
@@ -58,16 +80,17 @@ public:
bool isImplicit() const { return StartLoc.isInvalid(); }
- typedef StmtIterator child_iterator;
- typedef ConstStmtIterator const_child_iterator;
- typedef llvm::iterator_range<child_iterator> child_range;
- typedef llvm::iterator_range<const_child_iterator> const_child_range;
+ using child_iterator = StmtIterator;
+ using const_child_iterator = ConstStmtIterator;
+ using child_range = llvm::iterator_range<child_iterator>;
+ using const_child_range = llvm::iterator_range<const_child_iterator>;
child_range children();
const_child_range children() const {
auto Children = const_cast<OMPClause *>(this)->children();
return const_child_range(Children.begin(), Children.end());
}
+
static bool classof(const OMPClause *) { return true; }
};
@@ -75,29 +98,34 @@ public:
/// 'shedule', 'firstprivate' etc.
class OMPClauseWithPreInit {
friend class OMPClauseReader;
+
/// Pre-initialization statement for the clause.
- Stmt *PreInit;
+ Stmt *PreInit = nullptr;
+
/// Region that captures the associated stmt.
- OpenMPDirectiveKind CaptureRegion;
+ OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
protected:
+ OMPClauseWithPreInit(const OMPClause *This) {
+ assert(get(This) && "get is not tuned for pre-init.");
+ }
+
/// Set pre-initialization statement for the clause.
void setPreInitStmt(Stmt *S, OpenMPDirectiveKind ThisRegion = OMPD_unknown) {
PreInit = S;
CaptureRegion = ThisRegion;
}
- OMPClauseWithPreInit(const OMPClause *This)
- : PreInit(nullptr), CaptureRegion(OMPD_unknown) {
- assert(get(This) && "get is not tuned for pre-init.");
- }
public:
/// Get pre-initialization statement for the clause.
const Stmt *getPreInitStmt() const { return PreInit; }
+
/// Get pre-initialization statement for the clause.
Stmt *getPreInitStmt() { return PreInit; }
+
/// Get capture region for the stmt in the clause.
OpenMPDirectiveKind getCaptureRegion() { return CaptureRegion; }
+
static OMPClauseWithPreInit *get(OMPClause *C);
static const OMPClauseWithPreInit *get(const OMPClause *C);
};
@@ -106,21 +134,25 @@ public:
/// 'lastprivate', 'reduction' etc.
class OMPClauseWithPostUpdate : public OMPClauseWithPreInit {
friend class OMPClauseReader;
+
/// Post-update expression for the clause.
- Expr *PostUpdate;
+ Expr *PostUpdate = nullptr;
+
protected:
- /// Set pre-initialization statement for the clause.
- void setPostUpdateExpr(Expr *S) { PostUpdate = S; }
- OMPClauseWithPostUpdate(const OMPClause *This)
- : OMPClauseWithPreInit(This), PostUpdate(nullptr) {
+ OMPClauseWithPostUpdate(const OMPClause *This) : OMPClauseWithPreInit(This) {
assert(get(This) && "get is not tuned for post-update.");
}
+ /// Set pre-initialization statement for the clause.
+ void setPostUpdateExpr(Expr *S) { PostUpdate = S; }
+
public:
/// Get post-update expression for the clause.
const Expr *getPostUpdateExpr() const { return PostUpdate; }
+
/// Get post-update expression for the clause.
Expr *getPostUpdateExpr() { return PostUpdate; }
+
static OMPClauseWithPostUpdate *get(OMPClause *C);
static const OMPClauseWithPostUpdate *get(const OMPClause *C);
};
@@ -130,12 +162,25 @@ public:
/// '#pragma omp ...' directives.
template <class T> class OMPVarListClause : public OMPClause {
friend class OMPClauseReader;
+
/// \brief Location of '('.
SourceLocation LParenLoc;
+
/// \brief Number of variables in the list.
unsigned NumVars;
protected:
+ /// \brief Build a clause with \a N variables
+ ///
+ /// \param K Kind of the clause.
+ /// \param StartLoc Starting location of the clause (the clause keyword).
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param N Number of the variables in the clause.
+ OMPVarListClause(OpenMPClauseKind K, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N)
+ : OMPClause(K, StartLoc, EndLoc), LParenLoc(LParenLoc), NumVars(N) {}
+
/// \brief Fetches list of variables associated with this clause.
MutableArrayRef<Expr *> getVarRefs() {
return MutableArrayRef<Expr *>(
@@ -150,23 +195,11 @@ protected:
static_cast<T *>(this)->template getTrailingObjects<Expr *>());
}
- /// \brief Build a clause with \a N variables
- ///
- /// \param K Kind of the clause.
- /// \param StartLoc Starting location of the clause (the clause keyword).
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param N Number of the variables in the clause.
- ///
- OMPVarListClause(OpenMPClauseKind K, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N)
- : OMPClause(K, StartLoc, EndLoc), LParenLoc(LParenLoc), NumVars(N) {}
-
public:
- typedef MutableArrayRef<Expr *>::iterator varlist_iterator;
- typedef ArrayRef<const Expr *>::iterator varlist_const_iterator;
- typedef llvm::iterator_range<varlist_iterator> varlist_range;
- typedef llvm::iterator_range<varlist_const_iterator> varlist_const_range;
+ using varlist_iterator = MutableArrayRef<Expr *>::iterator;
+ using varlist_const_iterator = ArrayRef<const Expr *>::iterator;
+ using varlist_range = llvm::iterator_range<varlist_iterator>;
+ using varlist_const_range = llvm::iterator_range<varlist_const_iterator>;
unsigned varlist_size() const { return NumVars; }
bool varlist_empty() const { return NumVars == 0; }
@@ -185,6 +218,7 @@ public:
/// \brief Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
/// \brief Returns the location of '('.
SourceLocation getLParenLoc() const { return LParenLoc; }
@@ -203,31 +237,34 @@ public:
/// \endcode
/// In this example directive '#pragma omp parallel' has simple 'if' clause with
/// condition 'a > 5' and directive name modifier 'parallel'.
-///
class OMPIfClause : public OMPClause, public OMPClauseWithPreInit {
friend class OMPClauseReader;
+
/// \brief Location of '('.
SourceLocation LParenLoc;
+
/// \brief Condition of the 'if' clause.
- Stmt *Condition;
+ Stmt *Condition = nullptr;
+
/// \brief Location of ':' (if any).
SourceLocation ColonLoc;
+
/// \brief Directive name modifier for the clause.
- OpenMPDirectiveKind NameModifier;
+ OpenMPDirectiveKind NameModifier = OMPD_unknown;
+
/// \brief Name modifier location.
SourceLocation NameModifierLoc;
/// \brief Set condition.
- ///
void setCondition(Expr *Cond) { Condition = Cond; }
+
/// \brief Set directive name modifier for the clause.
- ///
void setNameModifier(OpenMPDirectiveKind NM) { NameModifier = NM; }
+
/// \brief Set location of directive name modifier for the clause.
- ///
void setNameModifierLoc(SourceLocation Loc) { NameModifierLoc = Loc; }
+
/// \brief Set location of ':'.
- ///
void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
public:
@@ -243,7 +280,6 @@ public:
/// \param NameModifierLoc Location of directive name modifier.
/// \param ColonLoc [OpenMP 4.1] Location of ':'.
/// \param EndLoc Ending location of the clause.
- ///
OMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Cond, Stmt *HelperCond,
OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation NameModifierLoc,
@@ -255,14 +291,13 @@ public:
}
/// \brief Build an empty clause.
- ///
OMPIfClause()
: OMPClause(OMPC_if, SourceLocation(), SourceLocation()),
- OMPClauseWithPreInit(this), LParenLoc(), Condition(nullptr), ColonLoc(),
- NameModifier(OMPD_unknown), NameModifierLoc() {}
+ OMPClauseWithPreInit(this) {}
/// \brief Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
/// \brief Returns the location of '('.
SourceLocation getLParenLoc() const { return LParenLoc; }
@@ -271,17 +306,18 @@ public:
/// \brief Returns condition.
Expr *getCondition() const { return cast_or_null<Expr>(Condition); }
+
/// \brief Return directive name modifier associated with the clause.
OpenMPDirectiveKind getNameModifier() const { return NameModifier; }
/// \brief Return the location of directive name modifier.
SourceLocation getNameModifierLoc() const { return NameModifierLoc; }
+ child_range children() { return child_range(&Condition, &Condition + 1); }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_if;
}
-
- child_range children() { return child_range(&Condition, &Condition + 1); }
};
/// \brief This represents 'final' clause in the '#pragma omp ...' directive.
@@ -291,16 +327,16 @@ public:
/// \endcode
/// In this example directive '#pragma omp task' has simple 'final'
/// clause with condition 'a > 5'.
-///
class OMPFinalClause : public OMPClause {
friend class OMPClauseReader;
+
/// \brief Location of '('.
SourceLocation LParenLoc;
+
/// \brief Condition of the 'if' clause.
- Stmt *Condition;
+ Stmt *Condition = nullptr;
/// \brief Set condition.
- ///
void setCondition(Expr *Cond) { Condition = Cond; }
public:
@@ -310,31 +346,29 @@ public:
/// \param LParenLoc Location of '('.
/// \param Cond Condition of the clause.
/// \param EndLoc Ending location of the clause.
- ///
OMPFinalClause(Expr *Cond, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
: OMPClause(OMPC_final, StartLoc, EndLoc), LParenLoc(LParenLoc),
Condition(Cond) {}
/// \brief Build an empty clause.
- ///
OMPFinalClause()
- : OMPClause(OMPC_final, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), Condition(nullptr) {}
+ : OMPClause(OMPC_final, SourceLocation(), SourceLocation()) {}
/// \brief Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
/// \brief Returns the location of '('.
SourceLocation getLParenLoc() const { return LParenLoc; }
/// \brief Returns condition.
Expr *getCondition() const { return cast_or_null<Expr>(Condition); }
+ child_range children() { return child_range(&Condition, &Condition + 1); }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_final;
}
-
- child_range children() { return child_range(&Condition, &Condition + 1); }
};
/// \brief This represents 'num_threads' clause in the '#pragma omp ...'
@@ -345,16 +379,16 @@ public:
/// \endcode
/// In this example directive '#pragma omp parallel' has simple 'num_threads'
/// clause with number of threads '6'.
-///
class OMPNumThreadsClause : public OMPClause, public OMPClauseWithPreInit {
friend class OMPClauseReader;
+
/// \brief Location of '('.
SourceLocation LParenLoc;
+
/// \brief Condition of the 'num_threads' clause.
- Stmt *NumThreads;
+ Stmt *NumThreads = nullptr;
/// \brief Set condition.
- ///
void setNumThreads(Expr *NThreads) { NumThreads = NThreads; }
public:
@@ -367,7 +401,6 @@ public:
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
- ///
OMPNumThreadsClause(Expr *NumThreads, Stmt *HelperNumThreads,
OpenMPDirectiveKind CaptureRegion,
SourceLocation StartLoc, SourceLocation LParenLoc,
@@ -379,25 +412,24 @@ public:
}
/// \brief Build an empty clause.
- ///
OMPNumThreadsClause()
: OMPClause(OMPC_num_threads, SourceLocation(), SourceLocation()),
- OMPClauseWithPreInit(this), LParenLoc(SourceLocation()),
- NumThreads(nullptr) {}
+ OMPClauseWithPreInit(this) {}
/// \brief Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
/// \brief Returns the location of '('.
SourceLocation getLParenLoc() const { return LParenLoc; }
/// \brief Returns number of threads.
Expr *getNumThreads() const { return cast_or_null<Expr>(NumThreads); }
+ child_range children() { return child_range(&NumThreads, &NumThreads + 1); }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_num_threads;
}
-
- child_range children() { return child_range(&NumThreads, &NumThreads + 1); }
};
/// \brief This represents 'safelen' clause in the '#pragma omp ...'
@@ -412,13 +444,14 @@ public:
/// concurrently with SIMD instructions can have a greater distance
/// in the logical iteration space than its value. The parameter of
/// the safelen clause must be a constant positive integer expression.
-///
class OMPSafelenClause : public OMPClause {
friend class OMPClauseReader;
+
/// \brief Location of '('.
SourceLocation LParenLoc;
+
/// \brief Safe iteration space distance.
- Stmt *Safelen;
+ Stmt *Safelen = nullptr;
/// \brief Set safelen.
void setSafelen(Expr *Len) { Safelen = Len; }
@@ -429,31 +462,29 @@ public:
/// \param Len Expression associated with this clause.
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
- ///
OMPSafelenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
: OMPClause(OMPC_safelen, StartLoc, EndLoc), LParenLoc(LParenLoc),
Safelen(Len) {}
/// \brief Build an empty clause.
- ///
explicit OMPSafelenClause()
- : OMPClause(OMPC_safelen, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), Safelen(nullptr) {}
+ : OMPClause(OMPC_safelen, SourceLocation(), SourceLocation()) {}
/// \brief Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
/// \brief Returns the location of '('.
SourceLocation getLParenLoc() const { return LParenLoc; }
/// \brief Return safe iteration space distance.
Expr *getSafelen() const { return cast_or_null<Expr>(Safelen); }
+ child_range children() { return child_range(&Safelen, &Safelen + 1); }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_safelen;
}
-
- child_range children() { return child_range(&Safelen, &Safelen + 1); }
};
/// \brief This represents 'simdlen' clause in the '#pragma omp ...'
@@ -467,13 +498,14 @@ public:
/// If the 'simdlen' clause is used then it specifies the preferred number of
/// iterations to be executed concurrently. The parameter of the 'simdlen'
/// clause must be a constant positive integer expression.
-///
class OMPSimdlenClause : public OMPClause {
friend class OMPClauseReader;
+
/// \brief Location of '('.
SourceLocation LParenLoc;
+
/// \brief Safe iteration space distance.
- Stmt *Simdlen;
+ Stmt *Simdlen = nullptr;
/// \brief Set simdlen.
void setSimdlen(Expr *Len) { Simdlen = Len; }
@@ -484,31 +516,29 @@ public:
/// \param Len Expression associated with this clause.
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
- ///
OMPSimdlenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
: OMPClause(OMPC_simdlen, StartLoc, EndLoc), LParenLoc(LParenLoc),
Simdlen(Len) {}
/// \brief Build an empty clause.
- ///
explicit OMPSimdlenClause()
- : OMPClause(OMPC_simdlen, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), Simdlen(nullptr) {}
+ : OMPClause(OMPC_simdlen, SourceLocation(), SourceLocation()) {}
/// \brief Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
/// \brief Returns the location of '('.
SourceLocation getLParenLoc() const { return LParenLoc; }
/// \brief Return safe iteration space distance.
Expr *getSimdlen() const { return cast_or_null<Expr>(Simdlen); }
+ child_range children() { return child_range(&Simdlen, &Simdlen + 1); }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_simdlen;
}
-
- child_range children() { return child_range(&Simdlen, &Simdlen + 1); }
};
/// \brief This represents 'collapse' clause in the '#pragma omp ...'
@@ -522,13 +552,14 @@ public:
/// The parameter must be a constant positive integer expression, it specifies
/// the number of nested loops that should be collapsed into a single iteration
/// space.
-///
class OMPCollapseClause : public OMPClause {
friend class OMPClauseReader;
+
/// \brief Location of '('.
SourceLocation LParenLoc;
+
/// \brief Number of for-loops.
- Stmt *NumForLoops;
+ Stmt *NumForLoops = nullptr;
/// \brief Set the number of associated for-loops.
void setNumForLoops(Expr *Num) { NumForLoops = Num; }
@@ -540,31 +571,29 @@ public:
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
- ///
OMPCollapseClause(Expr *Num, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation EndLoc)
: OMPClause(OMPC_collapse, StartLoc, EndLoc), LParenLoc(LParenLoc),
NumForLoops(Num) {}
/// \brief Build an empty clause.
- ///
explicit OMPCollapseClause()
- : OMPClause(OMPC_collapse, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), NumForLoops(nullptr) {}
+ : OMPClause(OMPC_collapse, SourceLocation(), SourceLocation()) {}
/// \brief Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
/// \brief Returns the location of '('.
SourceLocation getLParenLoc() const { return LParenLoc; }
/// \brief Return the number of associated for-loops.
Expr *getNumForLoops() const { return cast_or_null<Expr>(NumForLoops); }
+ child_range children() { return child_range(&NumForLoops, &NumForLoops + 1); }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_collapse;
}
-
- child_range children() { return child_range(&NumForLoops, &NumForLoops + 1); }
};
/// \brief This represents 'default' clause in the '#pragma omp ...' directive.
@@ -574,26 +603,26 @@ public:
/// \endcode
/// In this example directive '#pragma omp parallel' has simple 'default'
/// clause with kind 'shared'.
-///
class OMPDefaultClause : public OMPClause {
friend class OMPClauseReader;
+
/// \brief Location of '('.
SourceLocation LParenLoc;
+
/// \brief A kind of the 'default' clause.
- OpenMPDefaultClauseKind Kind;
+ OpenMPDefaultClauseKind Kind = OMPC_DEFAULT_unknown;
+
/// \brief Start location of the kind in source code.
SourceLocation KindKwLoc;
/// \brief Set kind of the clauses.
///
/// \param K Argument of clause.
- ///
void setDefaultKind(OpenMPDefaultClauseKind K) { Kind = K; }
/// \brief Set argument location.
///
/// \param KLoc Argument location.
- ///
void setDefaultKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; }
public:
@@ -604,7 +633,6 @@ public:
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
- ///
OMPDefaultClause(OpenMPDefaultClauseKind A, SourceLocation ALoc,
SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
@@ -612,14 +640,12 @@ public:
Kind(A), KindKwLoc(ALoc) {}
/// \brief Build an empty clause.
- ///
OMPDefaultClause()
- : OMPClause(OMPC_default, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), Kind(OMPC_DEFAULT_unknown),
- KindKwLoc(SourceLocation()) {}
+ : OMPClause(OMPC_default, SourceLocation(), SourceLocation()) {}
/// \brief Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
/// \brief Returns the location of '('.
SourceLocation getLParenLoc() const { return LParenLoc; }
@@ -629,13 +655,13 @@ public:
/// \brief Returns location of clause kind.
SourceLocation getDefaultKindKwLoc() const { return KindKwLoc; }
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_default;
- }
-
child_range children() {
return child_range(child_iterator(), child_iterator());
}
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_default;
+ }
};
/// \brief This represents 'proc_bind' clause in the '#pragma omp ...'
@@ -646,26 +672,26 @@ public:
/// \endcode
/// In this example directive '#pragma omp parallel' has simple 'proc_bind'
/// clause with kind 'master'.
-///
class OMPProcBindClause : public OMPClause {
friend class OMPClauseReader;
+
/// \brief Location of '('.
SourceLocation LParenLoc;
+
/// \brief A kind of the 'proc_bind' clause.
- OpenMPProcBindClauseKind Kind;
+ OpenMPProcBindClauseKind Kind = OMPC_PROC_BIND_unknown;
+
/// \brief Start location of the kind in source code.
SourceLocation KindKwLoc;
/// \brief Set kind of the clause.
///
/// \param K Kind of clause.
- ///
void setProcBindKind(OpenMPProcBindClauseKind K) { Kind = K; }
/// \brief Set clause kind location.
///
/// \param KLoc Kind location.
- ///
void setProcBindKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; }
public:
@@ -677,7 +703,6 @@ public:
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
- ///
OMPProcBindClause(OpenMPProcBindClauseKind A, SourceLocation ALoc,
SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
@@ -685,14 +710,12 @@ public:
Kind(A), KindKwLoc(ALoc) {}
/// \brief Build an empty clause.
- ///
OMPProcBindClause()
- : OMPClause(OMPC_proc_bind, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), Kind(OMPC_PROC_BIND_unknown),
- KindKwLoc(SourceLocation()) {}
+ : OMPClause(OMPC_proc_bind, SourceLocation(), SourceLocation()) {}
/// \brief Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
/// \brief Returns the location of '('.
SourceLocation getLParenLoc() const { return LParenLoc; }
@@ -702,13 +725,13 @@ public:
/// \brief Returns location of clause kind.
SourceLocation getProcBindKindKwLoc() const { return KindKwLoc; }
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_proc_bind;
- }
-
child_range children() {
return child_range(child_iterator(), child_iterator());
}
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_proc_bind;
+ }
};
/// \brief This represents 'schedule' clause in the '#pragma omp ...' directive.
@@ -718,58 +741,63 @@ public:
/// \endcode
/// In this example directive '#pragma omp for' has 'schedule' clause with
/// arguments 'static' and '3'.
-///
class OMPScheduleClause : public OMPClause, public OMPClauseWithPreInit {
friend class OMPClauseReader;
+
/// \brief Location of '('.
SourceLocation LParenLoc;
+
/// \brief A kind of the 'schedule' clause.
- OpenMPScheduleClauseKind Kind;
+ OpenMPScheduleClauseKind Kind = OMPC_SCHEDULE_unknown;
+
/// \brief Modifiers for 'schedule' clause.
enum {FIRST, SECOND, NUM_MODIFIERS};
OpenMPScheduleClauseModifier Modifiers[NUM_MODIFIERS];
+
/// \brief Locations of modifiers.
SourceLocation ModifiersLoc[NUM_MODIFIERS];
+
/// \brief Start location of the schedule ind in source code.
SourceLocation KindLoc;
+
/// \brief Location of ',' (if any).
SourceLocation CommaLoc;
+
/// \brief Chunk size.
- Expr *ChunkSize;
+ Expr *ChunkSize = nullptr;
/// \brief Set schedule kind.
///
/// \param K Schedule kind.
- ///
void setScheduleKind(OpenMPScheduleClauseKind K) { Kind = K; }
+
/// \brief Set the first schedule modifier.
///
/// \param M Schedule modifier.
- ///
void setFirstScheduleModifier(OpenMPScheduleClauseModifier M) {
Modifiers[FIRST] = M;
}
+
/// \brief Set the second schedule modifier.
///
/// \param M Schedule modifier.
- ///
void setSecondScheduleModifier(OpenMPScheduleClauseModifier M) {
Modifiers[SECOND] = M;
}
+
/// \brief Set location of the first schedule modifier.
- ///
void setFirstScheduleModifierLoc(SourceLocation Loc) {
ModifiersLoc[FIRST] = Loc;
}
+
/// \brief Set location of the second schedule modifier.
- ///
void setSecondScheduleModifierLoc(SourceLocation Loc) {
ModifiersLoc[SECOND] = Loc;
}
+
/// \brief Set schedule modifier location.
///
/// \param M Schedule modifier location.
- ///
void setScheduleModifer(OpenMPScheduleClauseModifier M) {
if (Modifiers[FIRST] == OMPC_SCHEDULE_MODIFIER_unknown)
Modifiers[FIRST] = M;
@@ -778,25 +806,25 @@ class OMPScheduleClause : public OMPClause, public OMPClauseWithPreInit {
Modifiers[SECOND] = M;
}
}
+
/// \brief Sets the location of '('.
///
/// \param Loc Location of '('.
- ///
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
/// \brief Set schedule kind start location.
///
/// \param KLoc Schedule kind location.
- ///
void setScheduleKindLoc(SourceLocation KLoc) { KindLoc = KLoc; }
+
/// \brief Set location of ','.
///
/// \param Loc Location of ','.
- ///
void setCommaLoc(SourceLocation Loc) { CommaLoc = Loc; }
+
/// \brief Set chunk size.
///
/// \param E Chunk size.
- ///
void setChunkSize(Expr *E) { ChunkSize = E; }
public:
@@ -815,7 +843,6 @@ public:
/// \param M1Loc Location of the first modifier
/// \param M2 The second modifier applied to 'schedule' clause.
/// \param M2Loc Location of the second modifier
- ///
OMPScheduleClause(SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation KLoc, SourceLocation CommaLoc,
SourceLocation EndLoc, OpenMPScheduleClauseKind Kind,
@@ -833,62 +860,59 @@ public:
}
/// \brief Build an empty clause.
- ///
explicit OMPScheduleClause()
: OMPClause(OMPC_schedule, SourceLocation(), SourceLocation()),
- OMPClauseWithPreInit(this), Kind(OMPC_SCHEDULE_unknown),
- ChunkSize(nullptr) {
+ OMPClauseWithPreInit(this) {
Modifiers[FIRST] = OMPC_SCHEDULE_MODIFIER_unknown;
Modifiers[SECOND] = OMPC_SCHEDULE_MODIFIER_unknown;
}
/// \brief Get kind of the clause.
- ///
OpenMPScheduleClauseKind getScheduleKind() const { return Kind; }
+
/// \brief Get the first modifier of the clause.
- ///
OpenMPScheduleClauseModifier getFirstScheduleModifier() const {
return Modifiers[FIRST];
}
+
/// \brief Get the second modifier of the clause.
- ///
OpenMPScheduleClauseModifier getSecondScheduleModifier() const {
return Modifiers[SECOND];
}
+
/// \brief Get location of '('.
- ///
SourceLocation getLParenLoc() { return LParenLoc; }
+
/// \brief Get kind location.
- ///
SourceLocation getScheduleKindLoc() { return KindLoc; }
+
/// \brief Get the first modifier location.
- ///
SourceLocation getFirstScheduleModifierLoc() const {
return ModifiersLoc[FIRST];
}
+
/// \brief Get the second modifier location.
- ///
SourceLocation getSecondScheduleModifierLoc() const {
return ModifiersLoc[SECOND];
}
+
/// \brief Get location of ','.
- ///
SourceLocation getCommaLoc() { return CommaLoc; }
+
/// \brief Get chunk size.
- ///
Expr *getChunkSize() { return ChunkSize; }
+
/// \brief Get chunk size.
- ///
const Expr *getChunkSize() const { return ChunkSize; }
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_schedule;
- }
-
child_range children() {
return child_range(reinterpret_cast<Stmt **>(&ChunkSize),
reinterpret_cast<Stmt **>(&ChunkSize) + 1);
}
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_schedule;
+ }
};
/// \brief This represents 'ordered' clause in the '#pragma omp ...' directive.
@@ -898,13 +922,14 @@ public:
/// \endcode
/// In this example directive '#pragma omp for' has 'ordered' clause with
/// parameter 2.
-///
class OMPOrderedClause : public OMPClause {
friend class OMPClauseReader;
+
/// \brief Location of '('.
SourceLocation LParenLoc;
+
/// \brief Number of for-loops.
- Stmt *NumForLoops;
+ Stmt *NumForLoops = nullptr;
/// \brief Set the number of associated for-loops.
void setNumForLoops(Expr *Num) { NumForLoops = Num; }
@@ -916,31 +941,29 @@ public:
/// \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) {}
/// \brief Build an empty clause.
- ///
explicit OMPOrderedClause()
- : OMPClause(OMPC_ordered, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), NumForLoops(nullptr) {}
+ : OMPClause(OMPC_ordered, SourceLocation(), SourceLocation()) {}
/// \brief Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
/// \brief Returns the location of '('.
SourceLocation getLParenLoc() const { return LParenLoc; }
/// \brief Return the number of associated for-loops.
Expr *getNumForLoops() const { return cast_or_null<Expr>(NumForLoops); }
+ child_range children() { return child_range(&NumForLoops, &NumForLoops + 1); }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_ordered;
}
-
- child_range children() { return child_range(&NumForLoops, &NumForLoops + 1); }
};
/// \brief This represents 'nowait' clause in the '#pragma omp ...' directive.
@@ -949,29 +972,26 @@ public:
/// #pragma omp for nowait
/// \endcode
/// In this example directive '#pragma omp for' has 'nowait' clause.
-///
class OMPNowaitClause : public OMPClause {
public:
/// \brief Build 'nowait' clause.
///
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
- ///
OMPNowaitClause(SourceLocation StartLoc, SourceLocation EndLoc)
: OMPClause(OMPC_nowait, StartLoc, EndLoc) {}
/// \brief Build an empty clause.
- ///
OMPNowaitClause()
: OMPClause(OMPC_nowait, SourceLocation(), SourceLocation()) {}
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_nowait;
- }
-
child_range children() {
return child_range(child_iterator(), child_iterator());
}
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_nowait;
+ }
};
/// \brief This represents 'untied' clause in the '#pragma omp ...' directive.
@@ -980,29 +1000,26 @@ public:
/// #pragma omp task untied
/// \endcode
/// In this example directive '#pragma omp task' has 'untied' clause.
-///
class OMPUntiedClause : public OMPClause {
public:
/// \brief Build 'untied' clause.
///
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
- ///
OMPUntiedClause(SourceLocation StartLoc, SourceLocation EndLoc)
: OMPClause(OMPC_untied, StartLoc, EndLoc) {}
/// \brief Build an empty clause.
- ///
OMPUntiedClause()
: OMPClause(OMPC_untied, SourceLocation(), SourceLocation()) {}
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_untied;
- }
-
child_range children() {
return child_range(child_iterator(), child_iterator());
}
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_untied;
+ }
};
/// \brief This represents 'mergeable' clause in the '#pragma omp ...'
@@ -1012,29 +1029,26 @@ public:
/// #pragma omp task mergeable
/// \endcode
/// In this example directive '#pragma omp task' has 'mergeable' clause.
-///
class OMPMergeableClause : public OMPClause {
public:
/// \brief Build 'mergeable' clause.
///
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
- ///
OMPMergeableClause(SourceLocation StartLoc, SourceLocation EndLoc)
: OMPClause(OMPC_mergeable, StartLoc, EndLoc) {}
/// \brief Build an empty clause.
- ///
OMPMergeableClause()
: OMPClause(OMPC_mergeable, SourceLocation(), SourceLocation()) {}
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_mergeable;
- }
-
child_range children() {
return child_range(child_iterator(), child_iterator());
}
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_mergeable;
+ }
};
/// \brief This represents 'read' clause in the '#pragma omp atomic' directive.
@@ -1043,28 +1057,25 @@ public:
/// #pragma omp atomic read
/// \endcode
/// In this example directive '#pragma omp atomic' has 'read' clause.
-///
class OMPReadClause : public OMPClause {
public:
/// \brief Build 'read' clause.
///
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
- ///
OMPReadClause(SourceLocation StartLoc, SourceLocation EndLoc)
: OMPClause(OMPC_read, StartLoc, EndLoc) {}
/// \brief Build an empty clause.
- ///
OMPReadClause() : OMPClause(OMPC_read, SourceLocation(), SourceLocation()) {}
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_read;
- }
-
child_range children() {
return child_range(child_iterator(), child_iterator());
}
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_read;
+ }
};
/// \brief This represents 'write' clause in the '#pragma omp atomic' directive.
@@ -1073,29 +1084,26 @@ public:
/// #pragma omp atomic write
/// \endcode
/// In this example directive '#pragma omp atomic' has 'write' clause.
-///
class OMPWriteClause : public OMPClause {
public:
/// \brief Build 'write' clause.
///
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
- ///
OMPWriteClause(SourceLocation StartLoc, SourceLocation EndLoc)
: OMPClause(OMPC_write, StartLoc, EndLoc) {}
/// \brief Build an empty clause.
- ///
OMPWriteClause()
: OMPClause(OMPC_write, SourceLocation(), SourceLocation()) {}
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_write;
- }
-
child_range children() {
return child_range(child_iterator(), child_iterator());
}
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_write;
+ }
};
/// \brief This represents 'update' clause in the '#pragma omp atomic'
@@ -1105,29 +1113,26 @@ public:
/// #pragma omp atomic update
/// \endcode
/// In this example directive '#pragma omp atomic' has 'update' clause.
-///
class OMPUpdateClause : public OMPClause {
public:
/// \brief Build 'update' clause.
///
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
- ///
OMPUpdateClause(SourceLocation StartLoc, SourceLocation EndLoc)
: OMPClause(OMPC_update, StartLoc, EndLoc) {}
/// \brief Build an empty clause.
- ///
OMPUpdateClause()
: OMPClause(OMPC_update, SourceLocation(), SourceLocation()) {}
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_update;
- }
-
child_range children() {
return child_range(child_iterator(), child_iterator());
}
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_update;
+ }
};
/// \brief This represents 'capture' clause in the '#pragma omp atomic'
@@ -1137,29 +1142,26 @@ public:
/// #pragma omp atomic capture
/// \endcode
/// In this example directive '#pragma omp atomic' has 'capture' clause.
-///
class OMPCaptureClause : public OMPClause {
public:
/// \brief Build 'capture' clause.
///
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
- ///
OMPCaptureClause(SourceLocation StartLoc, SourceLocation EndLoc)
: OMPClause(OMPC_capture, StartLoc, EndLoc) {}
/// \brief Build an empty clause.
- ///
OMPCaptureClause()
: OMPClause(OMPC_capture, SourceLocation(), SourceLocation()) {}
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_capture;
- }
-
child_range children() {
return child_range(child_iterator(), child_iterator());
}
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_capture;
+ }
};
/// \brief This represents 'seq_cst' clause in the '#pragma omp atomic'
@@ -1169,29 +1171,26 @@ public:
/// #pragma omp atomic seq_cst
/// \endcode
/// In this example directive '#pragma omp atomic' has 'seq_cst' clause.
-///
class OMPSeqCstClause : public OMPClause {
public:
/// \brief Build 'seq_cst' clause.
///
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
- ///
OMPSeqCstClause(SourceLocation StartLoc, SourceLocation EndLoc)
: OMPClause(OMPC_seq_cst, StartLoc, EndLoc) {}
/// \brief Build an empty clause.
- ///
OMPSeqCstClause()
: OMPClause(OMPC_seq_cst, SourceLocation(), SourceLocation()) {}
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_seq_cst;
- }
-
child_range children() {
return child_range(child_iterator(), child_iterator());
}
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_seq_cst;
+ }
};
/// \brief This represents clause 'private' in the '#pragma omp ...' directives.
@@ -1201,20 +1200,19 @@ public:
/// \endcode
/// In this example directive '#pragma omp parallel' has clause 'private'
/// with the variables 'a' and 'b'.
-///
class OMPPrivateClause final
: public OMPVarListClause<OMPPrivateClause>,
private llvm::TrailingObjects<OMPPrivateClause, Expr *> {
- friend TrailingObjects;
- friend OMPVarListClause;
friend class OMPClauseReader;
+ friend OMPVarListClause;
+ friend TrailingObjects;
+
/// \brief 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.
- ///
OMPPrivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, unsigned N)
: OMPVarListClause<OMPPrivateClause>(OMPC_private, StartLoc, LParenLoc,
@@ -1223,7 +1221,6 @@ class OMPPrivateClause final
/// \brief Build an empty clause.
///
/// \param N Number of variables.
- ///
explicit OMPPrivateClause(unsigned N)
: OMPVarListClause<OMPPrivateClause>(OMPC_private, SourceLocation(),
SourceLocation(), SourceLocation(),
@@ -1252,28 +1249,28 @@ public:
/// \param EndLoc Ending location of the clause.
/// \param VL List of references to the variables.
/// \param PrivateVL List of references to private copies with initializers.
- ///
static OMPPrivateClause *Create(const ASTContext &C, SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc, ArrayRef<Expr *> VL,
ArrayRef<Expr *> PrivateVL);
+
/// \brief Creates an empty clause with the place for \a N variables.
///
/// \param C AST context.
/// \param N The number of variables.
- ///
static OMPPrivateClause *CreateEmpty(const ASTContext &C, unsigned N);
- typedef MutableArrayRef<Expr *>::iterator private_copies_iterator;
- typedef ArrayRef<const Expr *>::iterator private_copies_const_iterator;
- typedef llvm::iterator_range<private_copies_iterator> private_copies_range;
- typedef llvm::iterator_range<private_copies_const_iterator>
- private_copies_const_range;
+ using private_copies_iterator = MutableArrayRef<Expr *>::iterator;
+ using private_copies_const_iterator = ArrayRef<const Expr *>::iterator;
+ using private_copies_range = llvm::iterator_range<private_copies_iterator>;
+ using private_copies_const_range =
+ llvm::iterator_range<private_copies_const_iterator>;
private_copies_range private_copies() {
return private_copies_range(getPrivateCopies().begin(),
getPrivateCopies().end());
}
+
private_copies_const_range private_copies() const {
return private_copies_const_range(getPrivateCopies().begin(),
getPrivateCopies().end());
@@ -1297,14 +1294,13 @@ public:
/// \endcode
/// In this example directive '#pragma omp parallel' has clause 'firstprivate'
/// with the variables 'a' and 'b'.
-///
class OMPFirstprivateClause final
: public OMPVarListClause<OMPFirstprivateClause>,
public OMPClauseWithPreInit,
private llvm::TrailingObjects<OMPFirstprivateClause, Expr *> {
- friend TrailingObjects;
- friend OMPVarListClause;
friend class OMPClauseReader;
+ friend OMPVarListClause;
+ friend TrailingObjects;
/// \brief Build clause with number of variables \a N.
///
@@ -1312,7 +1308,6 @@ class OMPFirstprivateClause final
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
/// \param N Number of the variables in the clause.
- ///
OMPFirstprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, unsigned N)
: OMPVarListClause<OMPFirstprivateClause>(OMPC_firstprivate, StartLoc,
@@ -1322,12 +1317,12 @@ class OMPFirstprivateClause final
/// \brief Build an empty clause.
///
/// \param N Number of variables.
- ///
explicit OMPFirstprivateClause(unsigned N)
: OMPVarListClause<OMPFirstprivateClause>(
OMPC_firstprivate, SourceLocation(), SourceLocation(),
SourceLocation(), N),
OMPClauseWithPreInit(this) {}
+
/// \brief Sets the list of references to private copies with initializers for
/// new private variables.
/// \param VL List of references.
@@ -1370,23 +1365,22 @@ public:
/// of array type.
/// \param PreInit Statement that must be executed before entering the OpenMP
/// region with this clause.
- ///
static OMPFirstprivateClause *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> PrivateVL,
ArrayRef<Expr *> InitVL, Stmt *PreInit);
+
/// \brief Creates an empty clause with the place for \a N variables.
///
/// \param C AST context.
/// \param N The number of variables.
- ///
static OMPFirstprivateClause *CreateEmpty(const ASTContext &C, unsigned N);
- typedef MutableArrayRef<Expr *>::iterator private_copies_iterator;
- typedef ArrayRef<const Expr *>::iterator private_copies_const_iterator;
- typedef llvm::iterator_range<private_copies_iterator> private_copies_range;
- typedef llvm::iterator_range<private_copies_const_iterator>
- private_copies_const_range;
+ using private_copies_iterator = MutableArrayRef<Expr *>::iterator;
+ using private_copies_const_iterator = ArrayRef<const Expr *>::iterator;
+ using private_copies_range = llvm::iterator_range<private_copies_iterator>;
+ using private_copies_const_range =
+ llvm::iterator_range<private_copies_const_iterator>;
private_copies_range private_copies() {
return private_copies_range(getPrivateCopies().begin(),
@@ -1397,10 +1391,10 @@ public:
getPrivateCopies().end());
}
- typedef MutableArrayRef<Expr *>::iterator inits_iterator;
- typedef ArrayRef<const Expr *>::iterator inits_const_iterator;
- typedef llvm::iterator_range<inits_iterator> inits_range;
- typedef llvm::iterator_range<inits_const_iterator> inits_const_range;
+ using inits_iterator = MutableArrayRef<Expr *>::iterator;
+ using inits_const_iterator = ArrayRef<const Expr *>::iterator;
+ using inits_range = llvm::iterator_range<inits_iterator>;
+ using inits_const_range = llvm::iterator_range<inits_const_iterator>;
inits_range inits() {
return inits_range(getInits().begin(), getInits().end());
@@ -1447,10 +1441,9 @@ class OMPLastprivateClause final
// \endcode
// Required for proper codegen of final assignment performed by the
// lastprivate clause.
- //
- friend TrailingObjects;
- friend OMPVarListClause;
friend class OMPClauseReader;
+ friend OMPVarListClause;
+ friend TrailingObjects;
/// \brief Build clause with number of variables \a N.
///
@@ -1458,7 +1451,6 @@ class OMPLastprivateClause final
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
/// \param N Number of the variables in the clause.
- ///
OMPLastprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, unsigned N)
: OMPVarListClause<OMPLastprivateClause>(OMPC_lastprivate, StartLoc,
@@ -1468,7 +1460,6 @@ class OMPLastprivateClause final
/// \brief Build an empty clause.
///
/// \param N Number of variables.
- ///
explicit OMPLastprivateClause(unsigned N)
: OMPVarListClause<OMPLastprivateClause>(
OMPC_lastprivate, SourceLocation(), SourceLocation(),
@@ -1550,24 +1541,23 @@ public:
/// region with this clause.
/// \param PostUpdate Expression that must be executed after exit from the
/// OpenMP region with this clause.
- ///
static OMPLastprivateClause *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps,
Stmt *PreInit, Expr *PostUpdate);
+
/// \brief Creates an empty clause with the place for \a N variables.
///
/// \param C AST context.
/// \param N The number of variables.
- ///
static OMPLastprivateClause *CreateEmpty(const ASTContext &C, unsigned N);
- typedef MutableArrayRef<Expr *>::iterator helper_expr_iterator;
- typedef ArrayRef<const Expr *>::iterator helper_expr_const_iterator;
- typedef llvm::iterator_range<helper_expr_iterator> helper_expr_range;
- typedef llvm::iterator_range<helper_expr_const_iterator>
- helper_expr_const_range;
+ using helper_expr_iterator = MutableArrayRef<Expr *>::iterator;
+ using helper_expr_const_iterator = ArrayRef<const Expr *>::iterator;
+ using helper_expr_range = llvm::iterator_range<helper_expr_iterator>;
+ using helper_expr_const_range =
+ llvm::iterator_range<helper_expr_const_iterator>;
/// \brief Set list of helper expressions, required for generation of private
/// copies of original lastprivate variables.
@@ -1577,29 +1567,36 @@ public:
return helper_expr_const_range(getPrivateCopies().begin(),
getPrivateCopies().end());
}
+
helper_expr_range private_copies() {
return helper_expr_range(getPrivateCopies().begin(),
getPrivateCopies().end());
}
+
helper_expr_const_range source_exprs() const {
return helper_expr_const_range(getSourceExprs().begin(),
getSourceExprs().end());
}
+
helper_expr_range source_exprs() {
return helper_expr_range(getSourceExprs().begin(), getSourceExprs().end());
}
+
helper_expr_const_range destination_exprs() const {
return helper_expr_const_range(getDestinationExprs().begin(),
getDestinationExprs().end());
}
+
helper_expr_range destination_exprs() {
return helper_expr_range(getDestinationExprs().begin(),
getDestinationExprs().end());
}
+
helper_expr_const_range assignment_ops() const {
return helper_expr_const_range(getAssignmentOps().begin(),
getAssignmentOps().end());
}
+
helper_expr_range assignment_ops() {
return helper_expr_range(getAssignmentOps().begin(),
getAssignmentOps().end());
@@ -1622,19 +1619,18 @@ public:
/// \endcode
/// In this example directive '#pragma omp parallel' has clause 'shared'
/// with the variables 'a' and 'b'.
-///
class OMPSharedClause final
: public OMPVarListClause<OMPSharedClause>,
private llvm::TrailingObjects<OMPSharedClause, Expr *> {
- friend TrailingObjects;
friend OMPVarListClause;
+ friend TrailingObjects;
+
/// \brief 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.
- ///
OMPSharedClause(SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, unsigned N)
: OMPVarListClause<OMPSharedClause>(OMPC_shared, StartLoc, LParenLoc,
@@ -1643,7 +1639,6 @@ class OMPSharedClause final
/// \brief Build an empty clause.
///
/// \param N Number of variables.
- ///
explicit OMPSharedClause(unsigned N)
: OMPVarListClause<OMPSharedClause>(OMPC_shared, SourceLocation(),
SourceLocation(), SourceLocation(),
@@ -1657,15 +1652,14 @@ public:
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
/// \param VL List of references to the variables.
- ///
static OMPSharedClause *Create(const ASTContext &C, SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc, ArrayRef<Expr *> VL);
+
/// \brief Creates an empty clause with \a N variables.
///
/// \param C AST context.
/// \param N The number of variables.
- ///
static OMPSharedClause *CreateEmpty(const ASTContext &C, unsigned N);
child_range children() {
@@ -1686,18 +1680,20 @@ public:
/// \endcode
/// In this example directive '#pragma omp parallel' has clause 'reduction'
/// with operator '+' and the variables 'a' and 'b'.
-///
class OMPReductionClause final
: public OMPVarListClause<OMPReductionClause>,
public OMPClauseWithPostUpdate,
private llvm::TrailingObjects<OMPReductionClause, Expr *> {
- friend TrailingObjects;
- friend OMPVarListClause;
friend class OMPClauseReader;
+ friend OMPVarListClause;
+ friend TrailingObjects;
+
/// \brief Location of ':'.
SourceLocation ColonLoc;
+
/// \brief Nested name specifier for C++.
NestedNameSpecifierLoc QualifierLoc;
+
/// \brief Name of custom operator.
DeclarationNameInfo NameInfo;
@@ -1710,7 +1706,6 @@ class OMPReductionClause final
/// \param N Number of the variables in the clause.
/// \param QualifierLoc The nested-name qualifier with location information
/// \param NameInfo The full name info for reduction identifier.
- ///
OMPReductionClause(SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation ColonLoc, SourceLocation EndLoc, unsigned N,
NestedNameSpecifierLoc QualifierLoc,
@@ -1723,17 +1718,18 @@ class OMPReductionClause final
/// \brief Build an empty clause.
///
/// \param N Number of variables.
- ///
explicit OMPReductionClause(unsigned N)
: OMPVarListClause<OMPReductionClause>(OMPC_reduction, SourceLocation(),
SourceLocation(), SourceLocation(),
N),
- OMPClauseWithPostUpdate(this), ColonLoc(), QualifierLoc(), NameInfo() {}
+ OMPClauseWithPostUpdate(this) {}
/// \brief Sets location of ':' symbol in clause.
void setColonLoc(SourceLocation CL) { ColonLoc = CL; }
+
/// \brief Sets the name info for specified reduction identifier.
void setNameInfo(DeclarationNameInfo DNI) { NameInfo = DNI; }
+
/// \brief Sets the nested name specifier.
void setQualifierLoc(NestedNameSpecifierLoc NSL) { QualifierLoc = NSL; }
@@ -1825,7 +1821,6 @@ public:
/// region with this clause.
/// \param PostUpdate Expression that must be executed after exit from the
/// OpenMP region with this clause.
- ///
static OMPReductionClause *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL,
@@ -1833,48 +1828,57 @@ public:
const DeclarationNameInfo &NameInfo, ArrayRef<Expr *> Privates,
ArrayRef<Expr *> LHSExprs, ArrayRef<Expr *> RHSExprs,
ArrayRef<Expr *> ReductionOps, Stmt *PreInit, Expr *PostUpdate);
+
/// \brief Creates an empty clause with the place for \a N variables.
///
/// \param C AST context.
/// \param N The number of variables.
- ///
static OMPReductionClause *CreateEmpty(const ASTContext &C, unsigned N);
/// \brief Gets location of ':' symbol in clause.
SourceLocation getColonLoc() const { return ColonLoc; }
+
/// \brief Gets the name info for specified reduction identifier.
const DeclarationNameInfo &getNameInfo() const { return NameInfo; }
+
/// \brief Gets the nested name specifier.
NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
- typedef MutableArrayRef<Expr *>::iterator helper_expr_iterator;
- typedef ArrayRef<const Expr *>::iterator helper_expr_const_iterator;
- typedef llvm::iterator_range<helper_expr_iterator> helper_expr_range;
- typedef llvm::iterator_range<helper_expr_const_iterator>
- helper_expr_const_range;
+ using helper_expr_iterator = MutableArrayRef<Expr *>::iterator;
+ using helper_expr_const_iterator = ArrayRef<const Expr *>::iterator;
+ using helper_expr_range = llvm::iterator_range<helper_expr_iterator>;
+ using helper_expr_const_range =
+ llvm::iterator_range<helper_expr_const_iterator>;
helper_expr_const_range privates() const {
return helper_expr_const_range(getPrivates().begin(), getPrivates().end());
}
+
helper_expr_range privates() {
return helper_expr_range(getPrivates().begin(), getPrivates().end());
}
+
helper_expr_const_range lhs_exprs() const {
return helper_expr_const_range(getLHSExprs().begin(), getLHSExprs().end());
}
+
helper_expr_range lhs_exprs() {
return helper_expr_range(getLHSExprs().begin(), getLHSExprs().end());
}
+
helper_expr_const_range rhs_exprs() const {
return helper_expr_const_range(getRHSExprs().begin(), getRHSExprs().end());
}
+
helper_expr_range rhs_exprs() {
return helper_expr_range(getRHSExprs().begin(), getRHSExprs().end());
}
+
helper_expr_const_range reduction_ops() const {
return helper_expr_const_range(getReductionOps().begin(),
getReductionOps().end());
}
+
helper_expr_range reduction_ops() {
return helper_expr_range(getReductionOps().begin(),
getReductionOps().end());
@@ -1898,18 +1902,20 @@ public:
/// \endcode
/// In this example directive '#pragma omp taskgroup' has clause
/// 'task_reduction' with operator '+' and the variables 'a' and 'b'.
-///
class OMPTaskReductionClause final
: public OMPVarListClause<OMPTaskReductionClause>,
public OMPClauseWithPostUpdate,
private llvm::TrailingObjects<OMPTaskReductionClause, Expr *> {
- friend TrailingObjects;
- friend OMPVarListClause;
friend class OMPClauseReader;
+ friend OMPVarListClause;
+ friend TrailingObjects;
+
/// Location of ':'.
SourceLocation ColonLoc;
+
/// Nested name specifier for C++.
NestedNameSpecifierLoc QualifierLoc;
+
/// Name of custom operator.
DeclarationNameInfo NameInfo;
@@ -1922,7 +1928,6 @@ class OMPTaskReductionClause final
/// \param N Number of the variables in the clause.
/// \param QualifierLoc The nested-name qualifier with location information
/// \param NameInfo The full name info for reduction identifier.
- ///
OMPTaskReductionClause(SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation ColonLoc, SourceLocation EndLoc,
unsigned N, NestedNameSpecifierLoc QualifierLoc,
@@ -1935,17 +1940,18 @@ class OMPTaskReductionClause final
/// Build an empty clause.
///
/// \param N Number of variables.
- ///
explicit OMPTaskReductionClause(unsigned N)
: OMPVarListClause<OMPTaskReductionClause>(
OMPC_task_reduction, SourceLocation(), SourceLocation(),
SourceLocation(), N),
- OMPClauseWithPostUpdate(this), ColonLoc(), QualifierLoc(), NameInfo() {}
+ OMPClauseWithPostUpdate(this) {}
/// Sets location of ':' symbol in clause.
void setColonLoc(SourceLocation CL) { ColonLoc = CL; }
+
/// Sets the name info for specified reduction identifier.
void setNameInfo(DeclarationNameInfo DNI) { NameInfo = DNI; }
+
/// Sets the nested name specifier.
void setQualifierLoc(NestedNameSpecifierLoc NSL) { QualifierLoc = NSL; }
@@ -2035,7 +2041,6 @@ public:
/// region with this clause.
/// \param PostUpdate Expression that must be executed after exit from the
/// OpenMP region with this clause.
- ///
static OMPTaskReductionClause *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL,
@@ -2048,44 +2053,52 @@ public:
///
/// \param C AST context.
/// \param N The number of variables.
- ///
static OMPTaskReductionClause *CreateEmpty(const ASTContext &C, unsigned N);
/// Gets location of ':' symbol in clause.
SourceLocation getColonLoc() const { return ColonLoc; }
+
/// Gets the name info for specified reduction identifier.
const DeclarationNameInfo &getNameInfo() const { return NameInfo; }
+
/// Gets the nested name specifier.
NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
- typedef MutableArrayRef<Expr *>::iterator helper_expr_iterator;
- typedef ArrayRef<const Expr *>::iterator helper_expr_const_iterator;
- typedef llvm::iterator_range<helper_expr_iterator> helper_expr_range;
- typedef llvm::iterator_range<helper_expr_const_iterator>
- helper_expr_const_range;
+ using helper_expr_iterator = MutableArrayRef<Expr *>::iterator;
+ using helper_expr_const_iterator = ArrayRef<const Expr *>::iterator;
+ using helper_expr_range = llvm::iterator_range<helper_expr_iterator>;
+ using helper_expr_const_range =
+ llvm::iterator_range<helper_expr_const_iterator>;
helper_expr_const_range privates() const {
return helper_expr_const_range(getPrivates().begin(), getPrivates().end());
}
+
helper_expr_range privates() {
return helper_expr_range(getPrivates().begin(), getPrivates().end());
}
+
helper_expr_const_range lhs_exprs() const {
return helper_expr_const_range(getLHSExprs().begin(), getLHSExprs().end());
}
+
helper_expr_range lhs_exprs() {
return helper_expr_range(getLHSExprs().begin(), getLHSExprs().end());
}
+
helper_expr_const_range rhs_exprs() const {
return helper_expr_const_range(getRHSExprs().begin(), getRHSExprs().end());
}
+
helper_expr_range rhs_exprs() {
return helper_expr_range(getRHSExprs().begin(), getRHSExprs().end());
}
+
helper_expr_const_range reduction_ops() const {
return helper_expr_const_range(getReductionOps().begin(),
getReductionOps().end());
}
+
helper_expr_range reduction_ops() {
return helper_expr_range(getReductionOps().begin(),
getReductionOps().end());
@@ -2101,6 +2114,249 @@ public:
}
};
+/// This represents clause 'in_reduction' in the '#pragma omp task' directives.
+///
+/// \code
+/// #pragma omp task in_reduction(+:a,b)
+/// \endcode
+/// In this example directive '#pragma omp task' has clause 'in_reduction' with
+/// operator '+' and the variables 'a' and 'b'.
+class OMPInReductionClause final
+ : public OMPVarListClause<OMPInReductionClause>,
+ public OMPClauseWithPostUpdate,
+ private llvm::TrailingObjects<OMPInReductionClause, Expr *> {
+ friend class OMPClauseReader;
+ friend OMPVarListClause;
+ friend TrailingObjects;
+
+ /// Location of ':'.
+ SourceLocation ColonLoc;
+
+ /// Nested name specifier for C++.
+ NestedNameSpecifierLoc QualifierLoc;
+
+ /// Name of custom operator.
+ DeclarationNameInfo NameInfo;
+
+ /// 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 ColonLoc Location of ':'.
+ /// \param N Number of the variables in the clause.
+ /// \param QualifierLoc The nested-name qualifier with location information
+ /// \param NameInfo The full name info for reduction identifier.
+ OMPInReductionClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation ColonLoc, SourceLocation EndLoc,
+ unsigned N, NestedNameSpecifierLoc QualifierLoc,
+ const DeclarationNameInfo &NameInfo)
+ : OMPVarListClause<OMPInReductionClause>(OMPC_in_reduction, StartLoc,
+ LParenLoc, EndLoc, N),
+ OMPClauseWithPostUpdate(this), ColonLoc(ColonLoc),
+ QualifierLoc(QualifierLoc), NameInfo(NameInfo) {}
+
+ /// Build an empty clause.
+ ///
+ /// \param N Number of variables.
+ explicit OMPInReductionClause(unsigned N)
+ : OMPVarListClause<OMPInReductionClause>(
+ OMPC_in_reduction, SourceLocation(), SourceLocation(),
+ SourceLocation(), N),
+ OMPClauseWithPostUpdate(this) {}
+
+ /// Sets location of ':' symbol in clause.
+ void setColonLoc(SourceLocation CL) { ColonLoc = CL; }
+
+ /// Sets the name info for specified reduction identifier.
+ void setNameInfo(DeclarationNameInfo DNI) { NameInfo = DNI; }
+
+ /// Sets the nested name specifier.
+ void setQualifierLoc(NestedNameSpecifierLoc NSL) { QualifierLoc = NSL; }
+
+ /// Set list of helper expressions, required for proper codegen of the clause.
+ /// These expressions represent private copy of the reduction variable.
+ void setPrivates(ArrayRef<Expr *> Privates);
+
+ /// Get the list of helper privates.
+ MutableArrayRef<Expr *> getPrivates() {
+ return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
+ }
+ ArrayRef<const Expr *> getPrivates() const {
+ return llvm::makeArrayRef(varlist_end(), varlist_size());
+ }
+
+ /// Set list of helper expressions, required for proper codegen of the clause.
+ /// These expressions represent LHS expression in the final reduction
+ /// expression performed by the reduction clause.
+ void setLHSExprs(ArrayRef<Expr *> LHSExprs);
+
+ /// Get the list of helper LHS expressions.
+ MutableArrayRef<Expr *> getLHSExprs() {
+ return MutableArrayRef<Expr *>(getPrivates().end(), varlist_size());
+ }
+ ArrayRef<const Expr *> getLHSExprs() const {
+ return llvm::makeArrayRef(getPrivates().end(), varlist_size());
+ }
+
+ /// Set list of helper expressions, required for proper codegen of the clause.
+ /// These expressions represent RHS expression in the final reduction
+ /// expression performed by the reduction clause. Also, variables in these
+ /// expressions are used for proper initialization of reduction copies.
+ void setRHSExprs(ArrayRef<Expr *> RHSExprs);
+
+ /// Get the list of helper destination expressions.
+ MutableArrayRef<Expr *> getRHSExprs() {
+ return MutableArrayRef<Expr *>(getLHSExprs().end(), varlist_size());
+ }
+ ArrayRef<const Expr *> getRHSExprs() const {
+ return llvm::makeArrayRef(getLHSExprs().end(), varlist_size());
+ }
+
+ /// Set list of helper reduction expressions, required for proper
+ /// codegen of the clause. These expressions are binary expressions or
+ /// operator/custom reduction call that calculates new value from source
+ /// helper expressions to destination helper expressions.
+ void setReductionOps(ArrayRef<Expr *> ReductionOps);
+
+ /// Get the list of helper reduction expressions.
+ MutableArrayRef<Expr *> getReductionOps() {
+ return MutableArrayRef<Expr *>(getRHSExprs().end(), varlist_size());
+ }
+ ArrayRef<const Expr *> getReductionOps() const {
+ return llvm::makeArrayRef(getRHSExprs().end(), varlist_size());
+ }
+
+ /// Set list of helper reduction taskgroup descriptors.
+ void setTaskgroupDescriptors(ArrayRef<Expr *> ReductionOps);
+
+ /// Get the list of helper reduction taskgroup descriptors.
+ MutableArrayRef<Expr *> getTaskgroupDescriptors() {
+ return MutableArrayRef<Expr *>(getReductionOps().end(), varlist_size());
+ }
+ ArrayRef<const Expr *> getTaskgroupDescriptors() const {
+ return llvm::makeArrayRef(getReductionOps().end(), varlist_size());
+ }
+
+public:
+ /// Creates clause with a list of variables \a VL.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param ColonLoc Location of ':'.
+ /// \param EndLoc Ending location of the clause.
+ /// \param VL The variables in the clause.
+ /// \param QualifierLoc The nested-name qualifier with location information
+ /// \param NameInfo The full name info for reduction identifier.
+ /// \param Privates List of helper expressions for proper generation of
+ /// private copies.
+ /// \param LHSExprs List of helper expressions for proper generation of
+ /// assignment operation required for copyprivate clause. This list represents
+ /// LHSs of the reduction expressions.
+ /// \param RHSExprs List of helper expressions for proper generation of
+ /// assignment operation required for copyprivate clause. This list represents
+ /// RHSs of the reduction expressions.
+ /// Also, variables in these expressions are used for proper initialization of
+ /// reduction copies.
+ /// \param ReductionOps List of helper expressions that represents reduction
+ /// expressions:
+ /// \code
+ /// LHSExprs binop RHSExprs;
+ /// operator binop(LHSExpr, RHSExpr);
+ /// <CutomReduction>(LHSExpr, RHSExpr);
+ /// \endcode
+ /// Required for proper codegen of final reduction operation performed by the
+ /// reduction clause.
+ /// \param TaskgroupDescriptors List of helper taskgroup descriptors for
+ /// corresponding items in parent taskgroup task_reduction clause.
+ /// \param PreInit Statement that must be executed before entering the OpenMP
+ /// region with this clause.
+ /// \param PostUpdate Expression that must be executed after exit from the
+ /// OpenMP region with this clause.
+ static OMPInReductionClause *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL,
+ NestedNameSpecifierLoc QualifierLoc,
+ const DeclarationNameInfo &NameInfo, ArrayRef<Expr *> Privates,
+ ArrayRef<Expr *> LHSExprs, ArrayRef<Expr *> RHSExprs,
+ ArrayRef<Expr *> ReductionOps, ArrayRef<Expr *> TaskgroupDescriptors,
+ Stmt *PreInit, Expr *PostUpdate);
+
+ /// Creates an empty clause with the place for \a N variables.
+ ///
+ /// \param C AST context.
+ /// \param N The number of variables.
+ static OMPInReductionClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+ /// Gets location of ':' symbol in clause.
+ SourceLocation getColonLoc() const { return ColonLoc; }
+
+ /// Gets the name info for specified reduction identifier.
+ const DeclarationNameInfo &getNameInfo() const { return NameInfo; }
+
+ /// Gets the nested name specifier.
+ NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
+
+ using helper_expr_iterator = MutableArrayRef<Expr *>::iterator;
+ using helper_expr_const_iterator = ArrayRef<const Expr *>::iterator;
+ using helper_expr_range = llvm::iterator_range<helper_expr_iterator>;
+ using helper_expr_const_range =
+ llvm::iterator_range<helper_expr_const_iterator>;
+
+ helper_expr_const_range privates() const {
+ return helper_expr_const_range(getPrivates().begin(), getPrivates().end());
+ }
+
+ helper_expr_range privates() {
+ return helper_expr_range(getPrivates().begin(), getPrivates().end());
+ }
+
+ helper_expr_const_range lhs_exprs() const {
+ return helper_expr_const_range(getLHSExprs().begin(), getLHSExprs().end());
+ }
+
+ helper_expr_range lhs_exprs() {
+ return helper_expr_range(getLHSExprs().begin(), getLHSExprs().end());
+ }
+
+ helper_expr_const_range rhs_exprs() const {
+ return helper_expr_const_range(getRHSExprs().begin(), getRHSExprs().end());
+ }
+
+ helper_expr_range rhs_exprs() {
+ return helper_expr_range(getRHSExprs().begin(), getRHSExprs().end());
+ }
+
+ helper_expr_const_range reduction_ops() const {
+ return helper_expr_const_range(getReductionOps().begin(),
+ getReductionOps().end());
+ }
+
+ helper_expr_range reduction_ops() {
+ return helper_expr_range(getReductionOps().begin(),
+ getReductionOps().end());
+ }
+
+ helper_expr_const_range taskgroup_descriptors() const {
+ return helper_expr_const_range(getTaskgroupDescriptors().begin(),
+ getTaskgroupDescriptors().end());
+ }
+
+ helper_expr_range taskgroup_descriptors() {
+ return helper_expr_range(getTaskgroupDescriptors().begin(),
+ getTaskgroupDescriptors().end());
+ }
+
+ child_range children() {
+ return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
+ reinterpret_cast<Stmt **>(varlist_end()));
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_in_reduction;
+ }
+};
+
/// \brief This represents clause 'linear' in the '#pragma omp ...'
/// directives.
///
@@ -2109,18 +2365,20 @@ public:
/// \endcode
/// In this example directive '#pragma omp simd' has clause 'linear'
/// with variables 'a', 'b' and linear step '2'.
-///
class OMPLinearClause final
: public OMPVarListClause<OMPLinearClause>,
public OMPClauseWithPostUpdate,
private llvm::TrailingObjects<OMPLinearClause, Expr *> {
- friend TrailingObjects;
- friend OMPVarListClause;
friend class OMPClauseReader;
+ friend OMPVarListClause;
+ friend TrailingObjects;
+
/// \brief Modifier of 'linear' clause.
- OpenMPLinearClauseKind Modifier;
+ OpenMPLinearClauseKind Modifier = OMPC_LINEAR_val;
+
/// \brief Location of linear modifier if any.
SourceLocation ModifierLoc;
+
/// \brief Location of ':'.
SourceLocation ColonLoc;
@@ -2137,7 +2395,6 @@ class OMPLinearClause final
/// \param ColonLoc Location of ':'.
/// \param EndLoc Ending location of the clause.
/// \param NumVars Number of variables.
- ///
OMPLinearClause(SourceLocation StartLoc, SourceLocation LParenLoc,
OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc,
SourceLocation ColonLoc, SourceLocation EndLoc,
@@ -2150,13 +2407,11 @@ class OMPLinearClause final
/// \brief Build an empty clause.
///
/// \param NumVars Number of variables.
- ///
explicit OMPLinearClause(unsigned NumVars)
: OMPVarListClause<OMPLinearClause>(OMPC_linear, SourceLocation(),
SourceLocation(), SourceLocation(),
NumVars),
- OMPClauseWithPostUpdate(this), Modifier(OMPC_LINEAR_val), ModifierLoc(),
- ColonLoc() {}
+ OMPClauseWithPostUpdate(this) {}
/// \brief Gets the list of initial values for linear variables.
///
@@ -2170,7 +2425,6 @@ class OMPLinearClause final
///
/// { Vars[] /* in OMPVarListClause */; Privates[]; Inits[]; Updates[];
/// Finals[]; Step; CalcStep; }
- ///
MutableArrayRef<Expr *> getPrivates() {
return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
}
@@ -2240,30 +2494,35 @@ public:
///
/// \param C AST context.
/// \param NumVars Number of variables.
- ///
static OMPLinearClause *CreateEmpty(const ASTContext &C, unsigned NumVars);
/// \brief Set modifier.
void setModifier(OpenMPLinearClauseKind Kind) { Modifier = Kind; }
+
/// \brief Return modifier.
OpenMPLinearClauseKind getModifier() const { return Modifier; }
/// \brief Set modifier location.
void setModifierLoc(SourceLocation Loc) { ModifierLoc = Loc; }
+
/// \brief Return modifier location.
SourceLocation getModifierLoc() const { return ModifierLoc; }
/// \brief Sets the location of ':'.
void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
+
/// \brief Returns the location of ':'.
SourceLocation getColonLoc() const { return ColonLoc; }
/// \brief Returns linear step.
Expr *getStep() { return *(getFinals().end()); }
+
/// \brief Returns linear step.
const Expr *getStep() const { return *(getFinals().end()); }
+
/// \brief Returns expression to calculate linear step.
Expr *getCalcStep() { return *(getFinals().end() + 1); }
+
/// \brief Returns expression to calculate linear step.
const Expr *getCalcStep() const { return *(getFinals().end() + 1); }
@@ -2275,50 +2534,54 @@ public:
/// \param FL List of expressions.
void setFinals(ArrayRef<Expr *> FL);
- typedef MutableArrayRef<Expr *>::iterator privates_iterator;
- typedef ArrayRef<const Expr *>::iterator privates_const_iterator;
- typedef llvm::iterator_range<privates_iterator> privates_range;
- typedef llvm::iterator_range<privates_const_iterator> privates_const_range;
+ using privates_iterator = MutableArrayRef<Expr *>::iterator;
+ using privates_const_iterator = ArrayRef<const Expr *>::iterator;
+ using privates_range = llvm::iterator_range<privates_iterator>;
+ using privates_const_range = llvm::iterator_range<privates_const_iterator>;
privates_range privates() {
return privates_range(getPrivates().begin(), getPrivates().end());
}
+
privates_const_range privates() const {
return privates_const_range(getPrivates().begin(), getPrivates().end());
}
- typedef MutableArrayRef<Expr *>::iterator inits_iterator;
- typedef ArrayRef<const Expr *>::iterator inits_const_iterator;
- typedef llvm::iterator_range<inits_iterator> inits_range;
- typedef llvm::iterator_range<inits_const_iterator> inits_const_range;
+ using inits_iterator = MutableArrayRef<Expr *>::iterator;
+ using inits_const_iterator = ArrayRef<const Expr *>::iterator;
+ using inits_range = llvm::iterator_range<inits_iterator>;
+ using inits_const_range = llvm::iterator_range<inits_const_iterator>;
inits_range inits() {
return inits_range(getInits().begin(), getInits().end());
}
+
inits_const_range inits() const {
return inits_const_range(getInits().begin(), getInits().end());
}
- typedef MutableArrayRef<Expr *>::iterator updates_iterator;
- typedef ArrayRef<const Expr *>::iterator updates_const_iterator;
- typedef llvm::iterator_range<updates_iterator> updates_range;
- typedef llvm::iterator_range<updates_const_iterator> updates_const_range;
+ using updates_iterator = MutableArrayRef<Expr *>::iterator;
+ using updates_const_iterator = ArrayRef<const Expr *>::iterator;
+ using updates_range = llvm::iterator_range<updates_iterator>;
+ using updates_const_range = llvm::iterator_range<updates_const_iterator>;
updates_range updates() {
return updates_range(getUpdates().begin(), getUpdates().end());
}
+
updates_const_range updates() const {
return updates_const_range(getUpdates().begin(), getUpdates().end());
}
- typedef MutableArrayRef<Expr *>::iterator finals_iterator;
- typedef ArrayRef<const Expr *>::iterator finals_const_iterator;
- typedef llvm::iterator_range<finals_iterator> finals_range;
- typedef llvm::iterator_range<finals_const_iterator> finals_const_range;
+ using finals_iterator = MutableArrayRef<Expr *>::iterator;
+ using finals_const_iterator = ArrayRef<const Expr *>::iterator;
+ using finals_range = llvm::iterator_range<finals_iterator>;
+ using finals_const_range = llvm::iterator_range<finals_const_iterator>;
finals_range finals() {
return finals_range(getFinals().begin(), getFinals().end());
}
+
finals_const_range finals() const {
return finals_const_range(getFinals().begin(), getFinals().end());
}
@@ -2341,13 +2604,13 @@ public:
/// \endcode
/// In this example directive '#pragma omp simd' has clause 'aligned'
/// with variables 'a', 'b' and alignment '8'.
-///
class OMPAlignedClause final
: public OMPVarListClause<OMPAlignedClause>,
private llvm::TrailingObjects<OMPAlignedClause, Expr *> {
- friend TrailingObjects;
- friend OMPVarListClause;
friend class OMPClauseReader;
+ friend OMPVarListClause;
+ friend TrailingObjects;
+
/// \brief Location of ':'.
SourceLocation ColonLoc;
@@ -2361,7 +2624,6 @@ class OMPAlignedClause final
/// \param ColonLoc Location of ':'.
/// \param EndLoc Ending location of the clause.
/// \param NumVars Number of variables.
- ///
OMPAlignedClause(SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation ColonLoc, SourceLocation EndLoc,
unsigned NumVars)
@@ -2372,12 +2634,10 @@ class OMPAlignedClause final
/// \brief Build an empty clause.
///
/// \param NumVars Number of variables.
- ///
explicit OMPAlignedClause(unsigned NumVars)
: OMPVarListClause<OMPAlignedClause>(OMPC_aligned, SourceLocation(),
SourceLocation(), SourceLocation(),
- NumVars),
- ColonLoc(SourceLocation()) {}
+ NumVars) {}
public:
/// \brief Creates clause with a list of variables \a VL and alignment \a A.
@@ -2399,16 +2659,17 @@ public:
///
/// \param C AST context.
/// \param NumVars Number of variables.
- ///
static OMPAlignedClause *CreateEmpty(const ASTContext &C, unsigned NumVars);
/// \brief Sets the location of ':'.
void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
+
/// \brief Returns the location of ':'.
SourceLocation getColonLoc() const { return ColonLoc; }
/// \brief Returns alignment.
Expr *getAlignment() { return *varlist_end(); }
+
/// \brief Returns alignment.
const Expr *getAlignment() const { return *varlist_end(); }
@@ -2429,7 +2690,6 @@ public:
/// \endcode
/// In this example directive '#pragma omp parallel' has clause 'copyin'
/// with the variables 'a' and 'b'.
-///
class OMPCopyinClause final
: public OMPVarListClause<OMPCopyinClause>,
private llvm::TrailingObjects<OMPCopyinClause, Expr *> {
@@ -2446,16 +2706,16 @@ class OMPCopyinClause final
// threadprivate variables to local instances of that variables in other
// implicit threads.
- friend TrailingObjects;
- friend OMPVarListClause;
friend class OMPClauseReader;
+ friend OMPVarListClause;
+ friend TrailingObjects;
+
/// \brief 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.
- ///
OMPCopyinClause(SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, unsigned N)
: OMPVarListClause<OMPCopyinClause>(OMPC_copyin, StartLoc, LParenLoc,
@@ -2464,7 +2724,6 @@ class OMPCopyinClause final
/// \brief Build an empty clause.
///
/// \param N Number of variables.
- ///
explicit OMPCopyinClause(unsigned N)
: OMPVarListClause<OMPCopyinClause>(OMPC_copyin, SourceLocation(),
SourceLocation(), SourceLocation(),
@@ -2532,43 +2791,47 @@ public:
/// Required for proper codegen of propagation of master's thread values of
/// threadprivate variables to local instances of that variables in other
/// implicit threads.
- ///
static OMPCopyinClause *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps);
+
/// \brief Creates an empty clause with \a N variables.
///
/// \param C AST context.
/// \param N The number of variables.
- ///
static OMPCopyinClause *CreateEmpty(const ASTContext &C, unsigned N);
- typedef MutableArrayRef<Expr *>::iterator helper_expr_iterator;
- typedef ArrayRef<const Expr *>::iterator helper_expr_const_iterator;
- typedef llvm::iterator_range<helper_expr_iterator> helper_expr_range;
- typedef llvm::iterator_range<helper_expr_const_iterator>
- helper_expr_const_range;
+ using helper_expr_iterator = MutableArrayRef<Expr *>::iterator;
+ using helper_expr_const_iterator = ArrayRef<const Expr *>::iterator;
+ using helper_expr_range = llvm::iterator_range<helper_expr_iterator>;
+ using helper_expr_const_range =
+ llvm::iterator_range<helper_expr_const_iterator>;
helper_expr_const_range source_exprs() const {
return helper_expr_const_range(getSourceExprs().begin(),
getSourceExprs().end());
}
+
helper_expr_range source_exprs() {
return helper_expr_range(getSourceExprs().begin(), getSourceExprs().end());
}
+
helper_expr_const_range destination_exprs() const {
return helper_expr_const_range(getDestinationExprs().begin(),
getDestinationExprs().end());
}
+
helper_expr_range destination_exprs() {
return helper_expr_range(getDestinationExprs().begin(),
getDestinationExprs().end());
}
+
helper_expr_const_range assignment_ops() const {
return helper_expr_const_range(getAssignmentOps().begin(),
getAssignmentOps().end());
}
+
helper_expr_range assignment_ops() {
return helper_expr_range(getAssignmentOps().begin(),
getAssignmentOps().end());
@@ -2592,20 +2855,19 @@ public:
/// \endcode
/// In this example directive '#pragma omp single' has clause 'copyprivate'
/// with the variables 'a' and 'b'.
-///
class OMPCopyprivateClause final
: public OMPVarListClause<OMPCopyprivateClause>,
private llvm::TrailingObjects<OMPCopyprivateClause, Expr *> {
- friend TrailingObjects;
- friend OMPVarListClause;
friend class OMPClauseReader;
+ friend OMPVarListClause;
+ friend TrailingObjects;
+
/// \brief 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.
- ///
OMPCopyprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, unsigned N)
: OMPVarListClause<OMPCopyprivateClause>(OMPC_copyprivate, StartLoc,
@@ -2614,7 +2876,6 @@ class OMPCopyprivateClause final
/// \brief Build an empty clause.
///
/// \param N Number of variables.
- ///
explicit OMPCopyprivateClause(unsigned N)
: OMPVarListClause<OMPCopyprivateClause>(
OMPC_copyprivate, SourceLocation(), SourceLocation(),
@@ -2681,43 +2942,47 @@ public:
/// \endcode
/// Required for proper codegen of final assignment performed by the
/// copyprivate clause.
- ///
static OMPCopyprivateClause *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps);
+
/// \brief Creates an empty clause with \a N variables.
///
/// \param C AST context.
/// \param N The number of variables.
- ///
static OMPCopyprivateClause *CreateEmpty(const ASTContext &C, unsigned N);
- typedef MutableArrayRef<Expr *>::iterator helper_expr_iterator;
- typedef ArrayRef<const Expr *>::iterator helper_expr_const_iterator;
- typedef llvm::iterator_range<helper_expr_iterator> helper_expr_range;
- typedef llvm::iterator_range<helper_expr_const_iterator>
- helper_expr_const_range;
+ using helper_expr_iterator = MutableArrayRef<Expr *>::iterator;
+ using helper_expr_const_iterator = ArrayRef<const Expr *>::iterator;
+ using helper_expr_range = llvm::iterator_range<helper_expr_iterator>;
+ using helper_expr_const_range =
+ llvm::iterator_range<helper_expr_const_iterator>;
helper_expr_const_range source_exprs() const {
return helper_expr_const_range(getSourceExprs().begin(),
getSourceExprs().end());
}
+
helper_expr_range source_exprs() {
return helper_expr_range(getSourceExprs().begin(), getSourceExprs().end());
}
+
helper_expr_const_range destination_exprs() const {
return helper_expr_const_range(getDestinationExprs().begin(),
getDestinationExprs().end());
}
+
helper_expr_range destination_exprs() {
return helper_expr_range(getDestinationExprs().begin(),
getDestinationExprs().end());
}
+
helper_expr_const_range assignment_ops() const {
return helper_expr_const_range(getAssignmentOps().begin(),
getAssignmentOps().end());
}
+
helper_expr_range assignment_ops() {
return helper_expr_range(getAssignmentOps().begin(),
getAssignmentOps().end());
@@ -2745,19 +3010,18 @@ public:
/// \endcode
/// In this example directive '#pragma omp flush' has implicit clause 'flush'
/// with the variables 'a' and 'b'.
-///
class OMPFlushClause final
: public OMPVarListClause<OMPFlushClause>,
private llvm::TrailingObjects<OMPFlushClause, Expr *> {
- friend TrailingObjects;
friend OMPVarListClause;
+ friend TrailingObjects;
+
/// \brief 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.
- ///
OMPFlushClause(SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, unsigned N)
: OMPVarListClause<OMPFlushClause>(OMPC_flush, StartLoc, LParenLoc,
@@ -2766,7 +3030,6 @@ class OMPFlushClause final
/// \brief Build an empty clause.
///
/// \param N Number of variables.
- ///
explicit OMPFlushClause(unsigned N)
: OMPVarListClause<OMPFlushClause>(OMPC_flush, SourceLocation(),
SourceLocation(), SourceLocation(),
@@ -2780,15 +3043,14 @@ public:
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
/// \param VL List of references to the variables.
- ///
static OMPFlushClause *Create(const ASTContext &C, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation EndLoc,
ArrayRef<Expr *> VL);
+
/// \brief Creates an empty clause with \a N variables.
///
/// \param C AST context.
/// \param N The number of variables.
- ///
static OMPFlushClause *CreateEmpty(const ASTContext &C, unsigned N);
child_range children() {
@@ -2809,41 +3071,41 @@ public:
/// \endcode
/// In this example directive '#pragma omp task' with clause 'depend' with the
/// variables 'a' and 'b' with dependency 'in'.
-///
class OMPDependClause final
: public OMPVarListClause<OMPDependClause>,
private llvm::TrailingObjects<OMPDependClause, Expr *> {
- friend TrailingObjects;
- friend OMPVarListClause;
friend class OMPClauseReader;
+ friend OMPVarListClause;
+ friend TrailingObjects;
+
/// \brief Dependency type (one of in, out, inout).
- OpenMPDependClauseKind DepKind;
+ OpenMPDependClauseKind DepKind = OMPC_DEPEND_unknown;
+
/// \brief Dependency type location.
SourceLocation DepLoc;
+
/// \brief Colon location.
SourceLocation ColonLoc;
+
/// \brief 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.
- ///
OMPDependClause(SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, unsigned N)
: OMPVarListClause<OMPDependClause>(OMPC_depend, StartLoc, LParenLoc,
- EndLoc, N),
- DepKind(OMPC_DEPEND_unknown) {}
+ EndLoc, N) {}
/// \brief Build an empty clause.
///
/// \param N Number of variables.
- ///
explicit OMPDependClause(unsigned N)
: OMPVarListClause<OMPDependClause>(OMPC_depend, SourceLocation(),
SourceLocation(), SourceLocation(),
- N),
- DepKind(OMPC_DEPEND_unknown) {}
+ N) {}
+
/// \brief Set dependency kind.
void setDependencyKind(OpenMPDependClauseKind K) { DepKind = K; }
@@ -2868,25 +3130,29 @@ public:
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, OpenMPDependClauseKind DepKind,
SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL);
+
/// \brief 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);
/// \brief Get dependency type.
OpenMPDependClauseKind getDependencyKind() const { return DepKind; }
+
/// \brief Get dependency type location.
SourceLocation getDependencyLoc() const { return DepLoc; }
+
/// \brief 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 the loop counter value.
Expr *getCounterValue();
+
/// Get the loop counter value.
const Expr *getCounterValue() const;
@@ -2908,17 +3174,18 @@ public:
/// \endcode
/// In this example directive '#pragma omp target' has clause 'device'
/// with single expression 'a'.
-///
-class OMPDeviceClause : public OMPClause {
+class OMPDeviceClause : public OMPClause, public OMPClauseWithPreInit {
friend class OMPClauseReader;
+
/// \brief Location of '('.
SourceLocation LParenLoc;
+
/// \brief Device number.
- Stmt *Device;
+ Stmt *Device = nullptr;
+
/// \brief Set the device number.
///
/// \param E Device number.
- ///
void setDevice(Expr *E) { Device = E; }
public:
@@ -2928,31 +3195,35 @@ public:
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
- ///
- OMPDeviceClause(Expr *E, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc)
- : OMPClause(OMPC_device, StartLoc, EndLoc), LParenLoc(LParenLoc),
- Device(E) {}
+ OMPDeviceClause(Expr *E, Stmt *HelperE, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation EndLoc)
+ : OMPClause(OMPC_device, StartLoc, EndLoc), OMPClauseWithPreInit(this),
+ LParenLoc(LParenLoc), Device(E) {
+ setPreInitStmt(HelperE);
+ }
/// \brief Build an empty clause.
- ///
OMPDeviceClause()
- : OMPClause(OMPC_device, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), Device(nullptr) {}
+ : OMPClause(OMPC_device, SourceLocation(), SourceLocation()),
+ OMPClauseWithPreInit(this) {}
+
/// \brief Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
/// \brief Returns the location of '('.
SourceLocation getLParenLoc() const { return LParenLoc; }
+
/// \brief Return device number.
Expr *getDevice() { return cast<Expr>(Device); }
+
/// \brief Return device number.
Expr *getDevice() const { return cast<Expr>(Device); }
+ child_range children() { return child_range(&Device, &Device + 1); }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_device;
}
-
- child_range children() { return child_range(&Device, &Device + 1); }
};
/// \brief This represents 'threads' clause in the '#pragma omp ...' directive.
@@ -2961,29 +3232,26 @@ public:
/// #pragma omp ordered threads
/// \endcode
/// In this example directive '#pragma omp ordered' has simple 'threads' clause.
-///
class OMPThreadsClause : public OMPClause {
public:
/// \brief Build 'threads' clause.
///
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
- ///
OMPThreadsClause(SourceLocation StartLoc, SourceLocation EndLoc)
: OMPClause(OMPC_threads, StartLoc, EndLoc) {}
/// \brief Build an empty clause.
- ///
OMPThreadsClause()
: OMPClause(OMPC_threads, SourceLocation(), SourceLocation()) {}
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_threads;
- }
-
child_range children() {
return child_range(child_iterator(), child_iterator());
}
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_threads;
+ }
};
/// \brief This represents 'simd' clause in the '#pragma omp ...' directive.
@@ -2992,28 +3260,25 @@ public:
/// #pragma omp ordered simd
/// \endcode
/// In this example directive '#pragma omp ordered' has simple 'simd' clause.
-///
class OMPSIMDClause : public OMPClause {
public:
/// \brief Build 'simd' clause.
///
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
- ///
OMPSIMDClause(SourceLocation StartLoc, SourceLocation EndLoc)
: OMPClause(OMPC_simd, StartLoc, EndLoc) {}
/// \brief Build an empty clause.
- ///
OMPSIMDClause() : OMPClause(OMPC_simd, SourceLocation(), SourceLocation()) {}
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_simd;
- }
-
child_range children() {
return child_range(child_iterator(), child_iterator());
}
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_simd;
+ }
};
/// \brief Struct that defines common infrastructure to handle mappable
@@ -3029,13 +3294,14 @@ public:
class MappableComponent {
// \brief Expression associated with the component.
Expr *AssociatedExpression = nullptr;
+
// \brief Declaration associated with the declaration. If the component does
// not have a declaration (e.g. array subscripts or section), this is set to
// nullptr.
ValueDecl *AssociatedDeclaration = nullptr;
public:
- explicit MappableComponent() {}
+ explicit MappableComponent() = default;
explicit MappableComponent(Expr *AssociatedExpression,
ValueDecl *AssociatedDeclaration)
: AssociatedExpression(AssociatedExpression),
@@ -3045,6 +3311,7 @@ public:
: nullptr) {}
Expr *getAssociatedExpression() const { return AssociatedExpression; }
+
ValueDecl *getAssociatedDeclaration() const {
return AssociatedDeclaration;
}
@@ -3052,14 +3319,14 @@ public:
// \brief List of components of an expression. This first one is the whole
// expression and the last one is the base expression.
- typedef SmallVector<MappableComponent, 8> MappableExprComponentList;
- typedef ArrayRef<MappableComponent> MappableExprComponentListRef;
+ using MappableExprComponentList = SmallVector<MappableComponent, 8>;
+ using MappableExprComponentListRef = ArrayRef<MappableComponent>;
// \brief List of all component lists associated to the same base declaration.
// E.g. if both 'S.a' and 'S.b' are a mappable expressions, each will have
// their component list but the same base declaration 'S'.
- typedef SmallVector<MappableExprComponentList, 8> MappableExprComponentLists;
- typedef ArrayRef<MappableExprComponentList> MappableExprComponentListsRef;
+ using MappableExprComponentLists = SmallVector<MappableExprComponentList, 8>;
+ using MappableExprComponentListsRef = ArrayRef<MappableExprComponentList>;
protected:
// \brief Return the total number of elements in a list of component lists.
@@ -3091,6 +3358,28 @@ class OMPMappableExprListClause : public OMPVarListClause<T>,
unsigned NumComponents;
protected:
+ /// \brief Build a clause for \a NumUniqueDeclarations declarations, \a
+ /// NumComponentLists total component lists, and \a NumComponents total
+ /// components.
+ ///
+ /// \param K Kind of the clause.
+ /// \param StartLoc Starting location of the clause (the clause keyword).
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param NumVars Number of expressions listed in the clause.
+ /// \param NumUniqueDeclarations Number of unique base declarations in this
+ /// clause.
+ /// \param NumComponentLists Number of component lists in this clause - one
+ /// list for each expression in the clause.
+ /// \param NumComponents Total number of expression components in the clause.
+ OMPMappableExprListClause(OpenMPClauseKind K, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation EndLoc,
+ unsigned NumVars, unsigned NumUniqueDeclarations,
+ unsigned NumComponentLists, unsigned NumComponents)
+ : OMPVarListClause<T>(K, StartLoc, LParenLoc, EndLoc, NumVars),
+ NumUniqueDeclarations(NumUniqueDeclarations),
+ NumComponentLists(NumComponentLists), NumComponents(NumComponents) {}
+
/// \brief Get the unique declarations that are in the trailing objects of the
/// class.
MutableArrayRef<ValueDecl *> getUniqueDeclsRef() {
@@ -3270,34 +3559,13 @@ protected:
}
}
- /// \brief Build a clause for \a NumUniqueDeclarations declarations, \a
- /// NumComponentLists total component lists, and \a NumComponents total
- /// components.
- ///
- /// \param K Kind of the clause.
- /// \param StartLoc Starting location of the clause (the clause keyword).
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param NumVars Number of expressions listed in the clause.
- /// \param NumUniqueDeclarations Number of unique base declarations in this
- /// clause.
- /// \param NumComponentLists Number of component lists in this clause - one
- /// list for each expression in the clause.
- /// \param NumComponents Total number of expression components in the clause.
- ///
- OMPMappableExprListClause(OpenMPClauseKind K, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc,
- unsigned NumVars, unsigned NumUniqueDeclarations,
- unsigned NumComponentLists, unsigned NumComponents)
- : OMPVarListClause<T>(K, StartLoc, LParenLoc, EndLoc, NumVars),
- NumUniqueDeclarations(NumUniqueDeclarations),
- NumComponentLists(NumComponentLists), NumComponents(NumComponents) {}
-
public:
/// \brief Return the number of unique base declarations in this clause.
unsigned getUniqueDeclarationsNum() const { return NumUniqueDeclarations; }
+
/// \brief Return the number of lists derived from the clause expressions.
unsigned getTotalComponentListNum() const { return NumComponentLists; }
+
/// \brief Return the total number of components in all lists derived from the
/// clause.
unsigned getTotalComponentsNum() const { return NumComponents; }
@@ -3317,11 +3585,11 @@ public:
ArrayRef<unsigned>::iterator NumListsCur;
// Remaining lists for the current declaration.
- unsigned RemainingLists;
+ unsigned RemainingLists = 0;
// The cumulative size of the previous list, or zero if there is no previous
// list.
- unsigned PrevListSize;
+ unsigned PrevListSize = 0;
// The cumulative sizes of the current list - it will delimit the remaining
// range of interest.
@@ -3340,7 +3608,6 @@ public:
: const_component_lists_iterator::iterator_adaptor_base(
Components.begin()),
DeclCur(UniqueDecls.begin()), NumListsCur(DeclsListNum.begin()),
- RemainingLists(0u), PrevListSize(0u),
ListSizeCur(CumulativeListSizes.begin()),
ListSizeEnd(CumulativeListSizes.end()), End(Components.end()) {
assert(UniqueDecls.size() == DeclsListNum.size() &&
@@ -3357,7 +3624,6 @@ public:
MappableExprComponentListRef Components)
: const_component_lists_iterator(UniqueDecls, DeclsListNum,
CumulativeListSizes, Components) {
-
// Look for the desired declaration. While we are looking for it, we
// update the state so that we know the component where a given list
// starts.
@@ -3437,8 +3703,8 @@ public:
}
};
- typedef llvm::iterator_range<const_component_lists_iterator>
- const_component_lists_range;
+ using const_component_lists_range =
+ llvm::iterator_range<const_component_lists_iterator>;
/// \brief Iterators for all component lists.
const_component_lists_iterator component_lists_begin() const {
@@ -3473,32 +3739,36 @@ public:
/// Iterators to access all the declarations, number of lists, list sizes, and
/// components.
- typedef ArrayRef<ValueDecl *>::iterator const_all_decls_iterator;
- typedef llvm::iterator_range<const_all_decls_iterator> const_all_decls_range;
+ using const_all_decls_iterator = ArrayRef<ValueDecl *>::iterator;
+ using const_all_decls_range = llvm::iterator_range<const_all_decls_iterator>;
+
const_all_decls_range all_decls() const {
auto A = getUniqueDeclsRef();
return const_all_decls_range(A.begin(), A.end());
}
- typedef ArrayRef<unsigned>::iterator const_all_num_lists_iterator;
- typedef llvm::iterator_range<const_all_num_lists_iterator>
- const_all_num_lists_range;
+ using const_all_num_lists_iterator = ArrayRef<unsigned>::iterator;
+ using const_all_num_lists_range =
+ llvm::iterator_range<const_all_num_lists_iterator>;
+
const_all_num_lists_range all_num_lists() const {
auto A = getDeclNumListsRef();
return const_all_num_lists_range(A.begin(), A.end());
}
- typedef ArrayRef<unsigned>::iterator const_all_lists_sizes_iterator;
- typedef llvm::iterator_range<const_all_lists_sizes_iterator>
- const_all_lists_sizes_range;
+ using const_all_lists_sizes_iterator = ArrayRef<unsigned>::iterator;
+ using const_all_lists_sizes_range =
+ llvm::iterator_range<const_all_lists_sizes_iterator>;
+
const_all_lists_sizes_range all_lists_sizes() const {
auto A = getComponentListSizesRef();
return const_all_lists_sizes_range(A.begin(), A.end());
}
- typedef ArrayRef<MappableComponent>::iterator const_all_components_iterator;
- typedef llvm::iterator_range<const_all_components_iterator>
- const_all_components_range;
+ using const_all_components_iterator = ArrayRef<MappableComponent>::iterator;
+ using const_all_components_range =
+ llvm::iterator_range<const_all_components_iterator>;
+
const_all_components_range all_components() const {
auto A = getComponentsRef();
return const_all_components_range(A.begin(), A.end());
@@ -3513,15 +3783,14 @@ public:
/// \endcode
/// In this example directive '#pragma omp target' has clause 'map'
/// with the variables 'a' and 'b'.
-///
class OMPMapClause final : public OMPMappableExprListClause<OMPMapClause>,
private llvm::TrailingObjects<
OMPMapClause, Expr *, ValueDecl *, unsigned,
OMPClauseMappableExprCommon::MappableComponent> {
- friend TrailingObjects;
- friend OMPVarListClause;
- friend OMPMappableExprListClause;
friend class OMPClauseReader;
+ friend OMPMappableExprListClause;
+ friend OMPVarListClause;
+ friend TrailingObjects;
/// Define the sizes of each trailing object array except the last one. This
/// is required for TrailingObjects to work properly.
@@ -3536,37 +3805,20 @@ class OMPMapClause final : public OMPMappableExprListClause<OMPMapClause>,
}
/// \brief Map type modifier for the 'map' clause.
- OpenMPMapClauseKind MapTypeModifier;
+ OpenMPMapClauseKind MapTypeModifier = OMPC_MAP_unknown;
+
/// \brief Map type for the 'map' clause.
- OpenMPMapClauseKind MapType;
+ OpenMPMapClauseKind MapType = OMPC_MAP_unknown;
+
/// \brief Is this an implicit map type or not.
- bool MapTypeIsImplicit;
+ bool MapTypeIsImplicit = false;
+
/// \brief Location of the map type.
SourceLocation MapLoc;
+
/// \brief Colon location.
SourceLocation ColonLoc;
- /// \brief Set type modifier for the clause.
- ///
- /// \param T Type Modifier for the clause.
- ///
- void setMapTypeModifier(OpenMPMapClauseKind T) { MapTypeModifier = T; }
-
- /// \brief Set type for the clause.
- ///
- /// \param T Type for the clause.
- ///
- void setMapType(OpenMPMapClauseKind T) { MapType = T; }
-
- /// \brief Set type location.
- ///
- /// \param TLoc Type location.
- ///
- void setMapLoc(SourceLocation TLoc) { MapLoc = TLoc; }
-
- /// \brief Set colon location.
- void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
-
/// \brief Build a clause for \a NumVars listed expressions, \a
/// NumUniqueDeclarations declarations, \a NumComponentLists total component
/// lists, and \a NumComponents total expression components.
@@ -3582,7 +3834,6 @@ 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,
OpenMPMapClauseKind MapType, bool MapTypeIsImplicit,
SourceLocation MapLoc, SourceLocation StartLoc,
@@ -3602,14 +3853,29 @@ 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(unsigned NumVars, unsigned NumUniqueDeclarations,
unsigned NumComponentLists, unsigned NumComponents)
: OMPMappableExprListClause(
OMPC_map, SourceLocation(), SourceLocation(), SourceLocation(),
- NumVars, NumUniqueDeclarations, NumComponentLists, NumComponents),
- MapTypeModifier(OMPC_MAP_unknown), MapType(OMPC_MAP_unknown),
- MapTypeIsImplicit(false), MapLoc() {}
+ NumVars, NumUniqueDeclarations, NumComponentLists, NumComponents) {}
+
+ /// \brief Set type modifier for the clause.
+ ///
+ /// \param T Type Modifier for the clause.
+ void setMapTypeModifier(OpenMPMapClauseKind T) { MapTypeModifier = T; }
+
+ /// \brief Set type for the clause.
+ ///
+ /// \param T Type for the clause.
+ void setMapType(OpenMPMapClauseKind T) { MapType = T; }
+
+ /// \brief Set type location.
+ ///
+ /// \param TLoc Type location.
+ void setMapLoc(SourceLocation TLoc) { MapLoc = TLoc; }
+
+ /// \brief Set colon location.
+ void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
public:
/// \brief Creates clause with a list of variables \a VL.
@@ -3624,7 +3890,6 @@ public:
/// \param Type Map type.
/// \param TypeIsImplicit Map type is inferred implicitly.
/// \param TypeLoc Location of the map type.
- ///
static OMPMapClause *Create(const ASTContext &C, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation EndLoc,
ArrayRef<Expr *> Vars,
@@ -3633,6 +3898,7 @@ public:
OpenMPMapClauseKind TypeModifier,
OpenMPMapClauseKind Type, bool TypeIsImplicit,
SourceLocation TypeLoc);
+
/// \brief Creates an empty clause with the place for for \a NumVars original
/// expressions, \a NumUniqueDeclarations declarations, \NumComponentLists
/// lists, and \a NumComponents expression components.
@@ -3644,7 +3910,6 @@ public:
/// \param NumComponentLists Number of unique base declarations in this
/// clause.
/// \param NumComponents Total number of expression components in the clause.
- ///
static OMPMapClause *CreateEmpty(const ASTContext &C, unsigned NumVars,
unsigned NumUniqueDeclarations,
unsigned NumComponentLists,
@@ -3671,15 +3936,15 @@ public:
/// \brief Get colon location.
SourceLocation getColonLoc() const { return ColonLoc; }
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_map;
- }
-
child_range children() {
return child_range(
reinterpret_cast<Stmt **>(varlist_begin()),
reinterpret_cast<Stmt **>(varlist_end()));
}
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_map;
+ }
};
/// \brief This represents 'num_teams' clause in the '#pragma omp ...'
@@ -3690,17 +3955,18 @@ public:
/// \endcode
/// In this example directive '#pragma omp teams' has clause 'num_teams'
/// with single expression 'n'.
-///
class OMPNumTeamsClause : public OMPClause, public OMPClauseWithPreInit {
friend class OMPClauseReader;
+
/// \brief Location of '('.
SourceLocation LParenLoc;
+
/// \brief NumTeams number.
- Stmt *NumTeams;
+ Stmt *NumTeams = nullptr;
+
/// \brief Set the NumTeams number.
///
/// \param E NumTeams number.
- ///
void setNumTeams(Expr *E) { NumTeams = E; }
public:
@@ -3713,7 +3979,6 @@ public:
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
- ///
OMPNumTeamsClause(Expr *E, Stmt *HelperE, OpenMPDirectiveKind CaptureRegion,
SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
@@ -3723,25 +3988,27 @@ public:
}
/// \brief Build an empty clause.
- ///
OMPNumTeamsClause()
: OMPClause(OMPC_num_teams, SourceLocation(), SourceLocation()),
- OMPClauseWithPreInit(this), LParenLoc(SourceLocation()),
- NumTeams(nullptr) {}
+ OMPClauseWithPreInit(this) {}
+
/// \brief Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
/// \brief Returns the location of '('.
SourceLocation getLParenLoc() const { return LParenLoc; }
+
/// \brief Return NumTeams number.
Expr *getNumTeams() { return cast<Expr>(NumTeams); }
+
/// \brief Return NumTeams number.
Expr *getNumTeams() const { return cast<Expr>(NumTeams); }
+ child_range children() { return child_range(&NumTeams, &NumTeams + 1); }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_num_teams;
}
-
- child_range children() { return child_range(&NumTeams, &NumTeams + 1); }
};
/// \brief This represents 'thread_limit' clause in the '#pragma omp ...'
@@ -3752,17 +4019,18 @@ public:
/// \endcode
/// In this example directive '#pragma omp teams' has clause 'thread_limit'
/// with single expression 'n'.
-///
class OMPThreadLimitClause : public OMPClause, public OMPClauseWithPreInit {
friend class OMPClauseReader;
+
/// \brief Location of '('.
SourceLocation LParenLoc;
+
/// \brief ThreadLimit number.
- Stmt *ThreadLimit;
+ Stmt *ThreadLimit = nullptr;
+
/// \brief Set the ThreadLimit number.
///
/// \param E ThreadLimit number.
- ///
void setThreadLimit(Expr *E) { ThreadLimit = E; }
public:
@@ -3775,7 +4043,6 @@ public:
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
- ///
OMPThreadLimitClause(Expr *E, Stmt *HelperE,
OpenMPDirectiveKind CaptureRegion,
SourceLocation StartLoc, SourceLocation LParenLoc,
@@ -3786,25 +4053,27 @@ public:
}
/// \brief Build an empty clause.
- ///
OMPThreadLimitClause()
: OMPClause(OMPC_thread_limit, SourceLocation(), SourceLocation()),
- OMPClauseWithPreInit(this), LParenLoc(SourceLocation()),
- ThreadLimit(nullptr) {}
+ OMPClauseWithPreInit(this) {}
+
/// \brief Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
/// \brief Returns the location of '('.
SourceLocation getLParenLoc() const { return LParenLoc; }
+
/// \brief Return ThreadLimit number.
Expr *getThreadLimit() { return cast<Expr>(ThreadLimit); }
+
/// \brief Return ThreadLimit number.
Expr *getThreadLimit() const { return cast<Expr>(ThreadLimit); }
+ child_range children() { return child_range(&ThreadLimit, &ThreadLimit + 1); }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_thread_limit;
}
-
- child_range children() { return child_range(&ThreadLimit, &ThreadLimit + 1); }
};
/// \brief This represents 'priority' clause in the '#pragma omp ...'
@@ -3815,17 +4084,18 @@ public:
/// \endcode
/// In this example directive '#pragma omp teams' has clause 'priority' with
/// single expression 'n'.
-///
class OMPPriorityClause : public OMPClause {
friend class OMPClauseReader;
+
/// \brief Location of '('.
SourceLocation LParenLoc;
+
/// \brief Priority number.
- Stmt *Priority;
+ Stmt *Priority = nullptr;
+
/// \brief Set the Priority number.
///
/// \param E Priority number.
- ///
void setPriority(Expr *E) { Priority = E; }
public:
@@ -3835,31 +4105,32 @@ public:
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
- ///
OMPPriorityClause(Expr *E, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
: OMPClause(OMPC_priority, StartLoc, EndLoc), LParenLoc(LParenLoc),
Priority(E) {}
/// \brief Build an empty clause.
- ///
OMPPriorityClause()
- : OMPClause(OMPC_priority, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), Priority(nullptr) {}
+ : OMPClause(OMPC_priority, SourceLocation(), SourceLocation()) {}
+
/// \brief Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
/// \brief Returns the location of '('.
SourceLocation getLParenLoc() const { return LParenLoc; }
+
/// \brief Return Priority number.
Expr *getPriority() { return cast<Expr>(Priority); }
+
/// \brief Return Priority number.
Expr *getPriority() const { return cast<Expr>(Priority); }
+ child_range children() { return child_range(&Priority, &Priority + 1); }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_priority;
}
-
- child_range children() { return child_range(&Priority, &Priority + 1); }
};
/// \brief This represents 'grainsize' clause in the '#pragma omp ...'
@@ -3870,13 +4141,14 @@ public:
/// \endcode
/// In this example directive '#pragma omp taskloop' has clause 'grainsize'
/// with single expression '4'.
-///
class OMPGrainsizeClause : public OMPClause {
friend class OMPClauseReader;
+
/// \brief Location of '('.
SourceLocation LParenLoc;
+
/// \brief Safe iteration space distance.
- Stmt *Grainsize;
+ Stmt *Grainsize = nullptr;
/// \brief Set safelen.
void setGrainsize(Expr *Size) { Grainsize = Size; }
@@ -3887,31 +4159,29 @@ public:
/// \param Size Expression associated with this clause.
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
- ///
OMPGrainsizeClause(Expr *Size, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation EndLoc)
: OMPClause(OMPC_grainsize, StartLoc, EndLoc), LParenLoc(LParenLoc),
Grainsize(Size) {}
/// \brief Build an empty clause.
- ///
explicit OMPGrainsizeClause()
- : OMPClause(OMPC_grainsize, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), Grainsize(nullptr) {}
+ : OMPClause(OMPC_grainsize, SourceLocation(), SourceLocation()) {}
/// \brief Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
/// \brief Returns the location of '('.
SourceLocation getLParenLoc() const { return LParenLoc; }
/// \brief Return safe iteration space distance.
Expr *getGrainsize() const { return cast_or_null<Expr>(Grainsize); }
+ child_range children() { return child_range(&Grainsize, &Grainsize + 1); }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_grainsize;
}
-
- child_range children() { return child_range(&Grainsize, &Grainsize + 1); }
};
/// \brief This represents 'nogroup' clause in the '#pragma omp ...' directive.
@@ -3920,29 +4190,26 @@ public:
/// #pragma omp taskloop nogroup
/// \endcode
/// In this example directive '#pragma omp taskloop' has 'nogroup' clause.
-///
class OMPNogroupClause : public OMPClause {
public:
/// \brief Build 'nogroup' clause.
///
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
- ///
OMPNogroupClause(SourceLocation StartLoc, SourceLocation EndLoc)
: OMPClause(OMPC_nogroup, StartLoc, EndLoc) {}
/// \brief Build an empty clause.
- ///
OMPNogroupClause()
: OMPClause(OMPC_nogroup, SourceLocation(), SourceLocation()) {}
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_nogroup;
- }
-
child_range children() {
return child_range(child_iterator(), child_iterator());
}
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_nogroup;
+ }
};
/// \brief This represents 'num_tasks' clause in the '#pragma omp ...'
@@ -3953,13 +4220,14 @@ public:
/// \endcode
/// In this example directive '#pragma omp taskloop' has clause 'num_tasks'
/// with single expression '4'.
-///
class OMPNumTasksClause : public OMPClause {
friend class OMPClauseReader;
+
/// \brief Location of '('.
SourceLocation LParenLoc;
+
/// \brief Safe iteration space distance.
- Stmt *NumTasks;
+ Stmt *NumTasks = nullptr;
/// \brief Set safelen.
void setNumTasks(Expr *Size) { NumTasks = Size; }
@@ -3970,31 +4238,29 @@ public:
/// \param Size Expression associated with this clause.
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
- ///
OMPNumTasksClause(Expr *Size, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation EndLoc)
: OMPClause(OMPC_num_tasks, StartLoc, EndLoc), LParenLoc(LParenLoc),
NumTasks(Size) {}
/// \brief Build an empty clause.
- ///
explicit OMPNumTasksClause()
- : OMPClause(OMPC_num_tasks, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), NumTasks(nullptr) {}
+ : OMPClause(OMPC_num_tasks, SourceLocation(), SourceLocation()) {}
/// \brief Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
/// \brief Returns the location of '('.
SourceLocation getLParenLoc() const { return LParenLoc; }
/// \brief Return safe iteration space distance.
Expr *getNumTasks() const { return cast_or_null<Expr>(NumTasks); }
+ child_range children() { return child_range(&NumTasks, &NumTasks + 1); }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_num_tasks;
}
-
- child_range children() { return child_range(&NumTasks, &NumTasks + 1); }
};
/// \brief This represents 'hint' clause in the '#pragma omp ...' directive.
@@ -4004,16 +4270,16 @@ public:
/// \endcode
/// In this example directive '#pragma omp critical' has name 'name' and clause
/// 'hint' with argument '6'.
-///
class OMPHintClause : public OMPClause {
friend class OMPClauseReader;
+
/// \brief Location of '('.
SourceLocation LParenLoc;
+
/// \brief Hint expression of the 'hint' clause.
- Stmt *Hint;
+ Stmt *Hint = nullptr;
/// \brief Set hint expression.
- ///
void setHint(Expr *H) { Hint = H; }
public:
@@ -4023,31 +4289,28 @@ public:
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
- ///
OMPHintClause(Expr *Hint, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
: OMPClause(OMPC_hint, StartLoc, EndLoc), LParenLoc(LParenLoc),
Hint(Hint) {}
/// \brief Build an empty clause.
- ///
- OMPHintClause()
- : OMPClause(OMPC_hint, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), Hint(nullptr) {}
+ OMPHintClause() : OMPClause(OMPC_hint, SourceLocation(), SourceLocation()) {}
/// \brief Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
/// \brief Returns the location of '('.
SourceLocation getLParenLoc() const { return LParenLoc; }
/// \brief Returns number of threads.
Expr *getHint() const { return cast_or_null<Expr>(Hint); }
+ child_range children() { return child_range(&Hint, &Hint + 1); }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_hint;
}
-
- child_range children() { return child_range(&Hint, &Hint + 1); }
};
/// \brief This represents 'dist_schedule' clause in the '#pragma omp ...'
@@ -4058,44 +4321,47 @@ public:
/// \endcode
/// In this example directive '#pragma omp distribute' has 'dist_schedule'
/// clause with arguments 'static' and '3'.
-///
class OMPDistScheduleClause : public OMPClause, public OMPClauseWithPreInit {
friend class OMPClauseReader;
+
/// \brief Location of '('.
SourceLocation LParenLoc;
+
/// \brief A kind of the 'schedule' clause.
- OpenMPDistScheduleClauseKind Kind;
+ OpenMPDistScheduleClauseKind Kind = OMPC_DIST_SCHEDULE_unknown;
+
/// \brief Start location of the schedule kind in source code.
SourceLocation KindLoc;
+
/// \brief Location of ',' (if any).
SourceLocation CommaLoc;
+
/// \brief Chunk size.
- Expr *ChunkSize;
+ Expr *ChunkSize = nullptr;
/// \brief Set schedule kind.
///
/// \param K Schedule kind.
- ///
void setDistScheduleKind(OpenMPDistScheduleClauseKind K) { Kind = K; }
+
/// \brief Sets the location of '('.
///
/// \param Loc Location of '('.
- ///
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
/// \brief Set schedule kind start location.
///
/// \param KLoc Schedule kind location.
- ///
void setDistScheduleKindLoc(SourceLocation KLoc) { KindLoc = KLoc; }
+
/// \brief Set location of ','.
///
/// \param Loc Location of ','.
- ///
void setCommaLoc(SourceLocation Loc) { CommaLoc = Loc; }
+
/// \brief Set chunk size.
///
/// \param E Chunk size.
- ///
void setChunkSize(Expr *E) { ChunkSize = E; }
public:
@@ -4110,7 +4376,6 @@ public:
/// \param Kind DistSchedule kind.
/// \param ChunkSize Chunk size.
/// \param HelperChunkSize Helper chunk size for combined directives.
- ///
OMPDistScheduleClause(SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation KLoc, SourceLocation CommaLoc,
SourceLocation EndLoc,
@@ -4123,39 +4388,36 @@ public:
}
/// \brief Build an empty clause.
- ///
explicit OMPDistScheduleClause()
: OMPClause(OMPC_dist_schedule, SourceLocation(), SourceLocation()),
- OMPClauseWithPreInit(this), Kind(OMPC_DIST_SCHEDULE_unknown),
- ChunkSize(nullptr) {}
+ OMPClauseWithPreInit(this) {}
/// \brief Get kind of the clause.
- ///
OpenMPDistScheduleClauseKind getDistScheduleKind() const { return Kind; }
+
/// \brief Get location of '('.
- ///
SourceLocation getLParenLoc() { return LParenLoc; }
+
/// \brief Get kind location.
- ///
SourceLocation getDistScheduleKindLoc() { return KindLoc; }
+
/// \brief Get location of ','.
- ///
SourceLocation getCommaLoc() { return CommaLoc; }
+
/// \brief Get chunk size.
- ///
Expr *getChunkSize() { return ChunkSize; }
+
/// \brief Get chunk size.
- ///
const Expr *getChunkSize() const { return ChunkSize; }
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_dist_schedule;
- }
-
child_range children() {
return child_range(reinterpret_cast<Stmt **>(&ChunkSize),
reinterpret_cast<Stmt **>(&ChunkSize) + 1);
}
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_dist_schedule;
+ }
};
/// \brief This represents 'defaultmap' clause in the '#pragma omp ...' directive.
@@ -4165,46 +4427,49 @@ public:
/// \endcode
/// In this example directive '#pragma omp target' has 'defaultmap' clause of kind
/// 'scalar' with modifier 'tofrom'.
-///
class OMPDefaultmapClause : public OMPClause {
friend class OMPClauseReader;
+
/// \brief Location of '('.
SourceLocation LParenLoc;
+
/// \brief Modifiers for 'defaultmap' clause.
- OpenMPDefaultmapClauseModifier Modifier;
+ OpenMPDefaultmapClauseModifier Modifier = OMPC_DEFAULTMAP_MODIFIER_unknown;
+
/// \brief Locations of modifiers.
SourceLocation ModifierLoc;
+
/// \brief A kind of the 'defaultmap' clause.
- OpenMPDefaultmapClauseKind Kind;
+ OpenMPDefaultmapClauseKind Kind = OMPC_DEFAULTMAP_unknown;
+
/// \brief Start location of the defaultmap kind in source code.
SourceLocation KindLoc;
/// \brief Set defaultmap kind.
///
/// \param K Defaultmap kind.
- ///
void setDefaultmapKind(OpenMPDefaultmapClauseKind K) { Kind = K; }
+
/// \brief Set the defaultmap modifier.
///
/// \param M Defaultmap modifier.
- ///
void setDefaultmapModifier(OpenMPDefaultmapClauseModifier M) {
Modifier = M;
}
+
/// \brief Set location of the defaultmap modifier.
- ///
void setDefaultmapModifierLoc(SourceLocation Loc) {
ModifierLoc = Loc;
}
+
/// \brief Sets the location of '('.
///
/// \param Loc Location of '('.
- ///
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
/// \brief Set defaultmap kind start location.
///
/// \param KLoc Defaultmap kind location.
- ///
void setDefaultmapKindLoc(SourceLocation KLoc) { KindLoc = KLoc; }
public:
@@ -4217,7 +4482,6 @@ public:
/// \param Kind Defaultmap kind.
/// \param M The modifier applied to 'defaultmap' clause.
/// \param MLoc Location of the modifier
- ///
OMPDefaultmapClause(SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation MLoc, SourceLocation KLoc,
SourceLocation EndLoc, OpenMPDefaultmapClauseKind Kind,
@@ -4226,39 +4490,35 @@ public:
Modifier(M), ModifierLoc(MLoc), Kind(Kind), KindLoc(KLoc) {}
/// \brief Build an empty clause.
- ///
explicit OMPDefaultmapClause()
- : OMPClause(OMPC_defaultmap, SourceLocation(), SourceLocation()),
- Modifier(OMPC_DEFAULTMAP_MODIFIER_unknown),
- Kind(OMPC_DEFAULTMAP_unknown) {}
+ : OMPClause(OMPC_defaultmap, SourceLocation(), SourceLocation()) {}
/// \brief Get kind of the clause.
- ///
OpenMPDefaultmapClauseKind getDefaultmapKind() const { return Kind; }
+
/// \brief Get the modifier of the clause.
- ///
OpenMPDefaultmapClauseModifier getDefaultmapModifier() const {
return Modifier;
}
+
/// \brief Get location of '('.
- ///
SourceLocation getLParenLoc() { return LParenLoc; }
+
/// \brief Get kind location.
- ///
SourceLocation getDefaultmapKindLoc() { return KindLoc; }
+
/// \brief Get the modifier location.
- ///
SourceLocation getDefaultmapModifierLoc() const {
return ModifierLoc;
}
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_defaultmap;
- }
-
child_range children() {
return child_range(child_iterator(), child_iterator());
}
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_defaultmap;
+ }
};
/// \brief This represents clause 'to' in the '#pragma omp ...'
@@ -4269,27 +4529,14 @@ public:
/// \endcode
/// In this example directive '#pragma omp target update' has clause 'to'
/// with the variables 'a' and 'b'.
-///
class OMPToClause final : public OMPMappableExprListClause<OMPToClause>,
private llvm::TrailingObjects<
OMPToClause, Expr *, ValueDecl *, unsigned,
OMPClauseMappableExprCommon::MappableComponent> {
- friend TrailingObjects;
- friend OMPVarListClause;
- friend OMPMappableExprListClause;
friend class OMPClauseReader;
-
- /// Define the sizes of each trailing object array except the last one. This
- /// is required for TrailingObjects to work properly.
- size_t numTrailingObjects(OverloadToken<Expr *>) const {
- return varlist_size();
- }
- size_t numTrailingObjects(OverloadToken<ValueDecl *>) const {
- return getUniqueDeclarationsNum();
- }
- size_t numTrailingObjects(OverloadToken<unsigned>) const {
- return getUniqueDeclarationsNum() + getTotalComponentListNum();
- }
+ friend OMPMappableExprListClause;
+ friend OMPVarListClause;
+ friend TrailingObjects;
/// \brief Build clause with number of variables \a NumVars.
///
@@ -4300,7 +4547,6 @@ class OMPToClause final : public OMPMappableExprListClause<OMPToClause>,
/// clause.
/// \param NumComponentLists Number of component lists in this clause.
/// \param NumComponents Total number of expression components in the clause.
- ///
explicit OMPToClause(SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, unsigned NumVars,
unsigned NumUniqueDeclarations,
@@ -4316,13 +4562,24 @@ class OMPToClause final : public OMPMappableExprListClause<OMPToClause>,
/// clause.
/// \param NumComponentLists Number of component lists in this clause.
/// \param NumComponents Total number of expression components in the clause.
- ///
explicit OMPToClause(unsigned NumVars, unsigned NumUniqueDeclarations,
unsigned NumComponentLists, unsigned NumComponents)
: OMPMappableExprListClause(
OMPC_to, SourceLocation(), SourceLocation(), SourceLocation(),
NumVars, NumUniqueDeclarations, NumComponentLists, NumComponents) {}
+ /// Define the sizes of each trailing object array except the last one. This
+ /// is required for TrailingObjects to work properly.
+ size_t numTrailingObjects(OverloadToken<Expr *>) const {
+ return varlist_size();
+ }
+ size_t numTrailingObjects(OverloadToken<ValueDecl *>) const {
+ return getUniqueDeclarationsNum();
+ }
+ size_t numTrailingObjects(OverloadToken<unsigned>) const {
+ return getUniqueDeclarationsNum() + getTotalComponentListNum();
+ }
+
public:
/// \brief Creates clause with a list of variables \a Vars.
///
@@ -4332,7 +4589,6 @@ 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.
- ///
static OMPToClause *Create(const ASTContext &C, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation EndLoc,
ArrayRef<Expr *> Vars,
@@ -4348,20 +4604,19 @@ public:
/// \param NumComponentLists Number of unique base declarations in this
/// clause.
/// \param NumComponents Total number of expression components in the clause.
- ///
static OMPToClause *CreateEmpty(const ASTContext &C, unsigned NumVars,
unsigned NumUniqueDeclarations,
unsigned NumComponentLists,
unsigned NumComponents);
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_to;
- }
-
child_range children() {
return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
reinterpret_cast<Stmt **>(varlist_end()));
}
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_to;
+ }
};
/// \brief This represents clause 'from' in the '#pragma omp ...'
@@ -4372,28 +4627,15 @@ public:
/// \endcode
/// In this example directive '#pragma omp target update' has clause 'from'
/// with the variables 'a' and 'b'.
-///
class OMPFromClause final
: public OMPMappableExprListClause<OMPFromClause>,
private llvm::TrailingObjects<
OMPFromClause, Expr *, ValueDecl *, unsigned,
OMPClauseMappableExprCommon::MappableComponent> {
- friend TrailingObjects;
- friend OMPVarListClause;
- friend OMPMappableExprListClause;
friend class OMPClauseReader;
-
- /// Define the sizes of each trailing object array except the last one. This
- /// is required for TrailingObjects to work properly.
- size_t numTrailingObjects(OverloadToken<Expr *>) const {
- return varlist_size();
- }
- size_t numTrailingObjects(OverloadToken<ValueDecl *>) const {
- return getUniqueDeclarationsNum();
- }
- size_t numTrailingObjects(OverloadToken<unsigned>) const {
- return getUniqueDeclarationsNum() + getTotalComponentListNum();
- }
+ friend OMPMappableExprListClause;
+ friend OMPVarListClause;
+ friend TrailingObjects;
/// \brief Build clause with number of variables \a NumVars.
///
@@ -4404,7 +4646,6 @@ class OMPFromClause final
/// clause.
/// \param NumComponentLists Number of component lists in this clause.
/// \param NumComponents Total number of expression components in the clause.
- ///
explicit OMPFromClause(SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, unsigned NumVars,
unsigned NumUniqueDeclarations,
@@ -4420,13 +4661,24 @@ class OMPFromClause final
/// clause.
/// \param NumComponentLists Number of component lists in this clause.
/// \param NumComponents Total number of expression components in the clause.
- ///
explicit OMPFromClause(unsigned NumVars, unsigned NumUniqueDeclarations,
unsigned NumComponentLists, unsigned NumComponents)
: OMPMappableExprListClause(
OMPC_from, SourceLocation(), SourceLocation(), SourceLocation(),
NumVars, NumUniqueDeclarations, NumComponentLists, NumComponents) {}
+ /// Define the sizes of each trailing object array except the last one. This
+ /// is required for TrailingObjects to work properly.
+ size_t numTrailingObjects(OverloadToken<Expr *>) const {
+ return varlist_size();
+ }
+ size_t numTrailingObjects(OverloadToken<ValueDecl *>) const {
+ return getUniqueDeclarationsNum();
+ }
+ size_t numTrailingObjects(OverloadToken<unsigned>) const {
+ return getUniqueDeclarationsNum() + getTotalComponentListNum();
+ }
+
public:
/// \brief Creates clause with a list of variables \a Vars.
///
@@ -4436,7 +4688,6 @@ 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.
- ///
static OMPFromClause *Create(const ASTContext &C, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation EndLoc,
ArrayRef<Expr *> Vars,
@@ -4452,20 +4703,19 @@ public:
/// \param NumComponentLists Number of unique base declarations in this
/// clause.
/// \param NumComponents Total number of expression components in the clause.
- ///
static OMPFromClause *CreateEmpty(const ASTContext &C, unsigned NumVars,
unsigned NumUniqueDeclarations,
unsigned NumComponentLists,
unsigned NumComponents);
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_from;
- }
-
child_range children() {
return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
reinterpret_cast<Stmt **>(varlist_end()));
}
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_from;
+ }
};
/// This represents clause 'use_device_ptr' in the '#pragma omp ...'
@@ -4476,28 +4726,15 @@ public:
/// \endcode
/// In this example directive '#pragma omp target data' has clause
/// 'use_device_ptr' with the variables 'a' and 'b'.
-///
class OMPUseDevicePtrClause final
: public OMPMappableExprListClause<OMPUseDevicePtrClause>,
private llvm::TrailingObjects<
OMPUseDevicePtrClause, Expr *, ValueDecl *, unsigned,
OMPClauseMappableExprCommon::MappableComponent> {
- friend TrailingObjects;
- friend OMPVarListClause;
- friend OMPMappableExprListClause;
friend class OMPClauseReader;
-
- /// Define the sizes of each trailing object array except the last one. This
- /// is required for TrailingObjects to work properly.
- size_t numTrailingObjects(OverloadToken<Expr *>) const {
- return 3 * varlist_size();
- }
- size_t numTrailingObjects(OverloadToken<ValueDecl *>) const {
- return getUniqueDeclarationsNum();
- }
- size_t numTrailingObjects(OverloadToken<unsigned>) const {
- return getUniqueDeclarationsNum() + getTotalComponentListNum();
- }
+ friend OMPMappableExprListClause;
+ friend OMPVarListClause;
+ friend TrailingObjects;
/// Build clause with number of variables \a NumVars.
///
@@ -4508,7 +4745,6 @@ class OMPUseDevicePtrClause final
/// clause.
/// \param NumComponentLists Number of component lists in this clause.
/// \param NumComponents Total number of expression components in the clause.
- ///
explicit OMPUseDevicePtrClause(SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc, unsigned NumVars,
@@ -4526,7 +4762,6 @@ class OMPUseDevicePtrClause final
/// clause.
/// \param NumComponentLists Number of component lists in this clause.
/// \param NumComponents Total number of expression components in the clause.
- ///
explicit OMPUseDevicePtrClause(unsigned NumVars,
unsigned NumUniqueDeclarations,
unsigned NumComponentLists,
@@ -4536,6 +4771,18 @@ class OMPUseDevicePtrClause final
NumUniqueDeclarations, NumComponentLists,
NumComponents) {}
+ /// Define the sizes of each trailing object array except the last one. This
+ /// is required for TrailingObjects to work properly.
+ size_t numTrailingObjects(OverloadToken<Expr *>) const {
+ return 3 * varlist_size();
+ }
+ size_t numTrailingObjects(OverloadToken<ValueDecl *>) const {
+ return getUniqueDeclarationsNum();
+ }
+ size_t numTrailingObjects(OverloadToken<unsigned>) const {
+ return getUniqueDeclarationsNum() + getTotalComponentListNum();
+ }
+
/// Sets the list of references to private copies with initializers for new
/// private variables.
/// \param VL List of references.
@@ -4575,7 +4822,6 @@ public:
/// \param Inits Expressions referring to private copy initializers.
/// \param Declarations Declarations used in the clause.
/// \param ComponentLists Component lists used in the clause.
- ///
static OMPUseDevicePtrClause *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, ArrayRef<Expr *> Vars,
@@ -4592,36 +4838,37 @@ public:
/// \param NumComponentLists Number of unique base declarations in this
/// clause.
/// \param NumComponents Total number of expression components in the clause.
- ///
static OMPUseDevicePtrClause *CreateEmpty(const ASTContext &C,
unsigned NumVars,
unsigned NumUniqueDeclarations,
unsigned NumComponentLists,
unsigned NumComponents);
- typedef MutableArrayRef<Expr *>::iterator private_copies_iterator;
- typedef ArrayRef<const Expr *>::iterator private_copies_const_iterator;
- typedef llvm::iterator_range<private_copies_iterator> private_copies_range;
- typedef llvm::iterator_range<private_copies_const_iterator>
- private_copies_const_range;
+ using private_copies_iterator = MutableArrayRef<Expr *>::iterator;
+ using private_copies_const_iterator = ArrayRef<const Expr *>::iterator;
+ using private_copies_range = llvm::iterator_range<private_copies_iterator>;
+ using private_copies_const_range =
+ llvm::iterator_range<private_copies_const_iterator>;
private_copies_range private_copies() {
return private_copies_range(getPrivateCopies().begin(),
getPrivateCopies().end());
}
+
private_copies_const_range private_copies() const {
return private_copies_const_range(getPrivateCopies().begin(),
getPrivateCopies().end());
}
- typedef MutableArrayRef<Expr *>::iterator inits_iterator;
- typedef ArrayRef<const Expr *>::iterator inits_const_iterator;
- typedef llvm::iterator_range<inits_iterator> inits_range;
- typedef llvm::iterator_range<inits_const_iterator> inits_const_range;
+ using inits_iterator = MutableArrayRef<Expr *>::iterator;
+ using inits_const_iterator = ArrayRef<const Expr *>::iterator;
+ using inits_range = llvm::iterator_range<inits_iterator>;
+ using inits_const_range = llvm::iterator_range<inits_const_iterator>;
inits_range inits() {
return inits_range(getInits().begin(), getInits().end());
}
+
inits_const_range inits() const {
return inits_const_range(getInits().begin(), getInits().end());
}
@@ -4644,28 +4891,16 @@ public:
/// \endcode
/// In this example directive '#pragma omp target' has clause
/// 'is_device_ptr' with the variables 'a' and 'b'.
-///
class OMPIsDevicePtrClause final
: public OMPMappableExprListClause<OMPIsDevicePtrClause>,
private llvm::TrailingObjects<
OMPIsDevicePtrClause, Expr *, ValueDecl *, unsigned,
OMPClauseMappableExprCommon::MappableComponent> {
- friend TrailingObjects;
- friend OMPVarListClause;
- friend OMPMappableExprListClause;
friend class OMPClauseReader;
+ friend OMPMappableExprListClause;
+ friend OMPVarListClause;
+ friend TrailingObjects;
- /// Define the sizes of each trailing object array except the last one. This
- /// is required for TrailingObjects to work properly.
- size_t numTrailingObjects(OverloadToken<Expr *>) const {
- return varlist_size();
- }
- size_t numTrailingObjects(OverloadToken<ValueDecl *>) const {
- return getUniqueDeclarationsNum();
- }
- size_t numTrailingObjects(OverloadToken<unsigned>) const {
- return getUniqueDeclarationsNum() + getTotalComponentListNum();
- }
/// Build clause with number of variables \a NumVars.
///
/// \param StartLoc Starting location of the clause.
@@ -4675,7 +4910,6 @@ class OMPIsDevicePtrClause final
/// clause.
/// \param NumComponentLists Number of component lists in this clause.
/// \param NumComponents Total number of expression components in the clause.
- ///
explicit OMPIsDevicePtrClause(SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation EndLoc,
unsigned NumVars,
@@ -4693,7 +4927,6 @@ class OMPIsDevicePtrClause final
/// clause.
/// \param NumComponentLists Number of component lists in this clause.
/// \param NumComponents Total number of expression components in the clause.
- ///
explicit OMPIsDevicePtrClause(unsigned NumVars,
unsigned NumUniqueDeclarations,
unsigned NumComponentLists,
@@ -4703,6 +4936,18 @@ class OMPIsDevicePtrClause final
NumUniqueDeclarations, NumComponentLists,
NumComponents) {}
+ /// Define the sizes of each trailing object array except the last one. This
+ /// is required for TrailingObjects to work properly.
+ size_t numTrailingObjects(OverloadToken<Expr *>) const {
+ return varlist_size();
+ }
+ size_t numTrailingObjects(OverloadToken<ValueDecl *>) const {
+ return getUniqueDeclarationsNum();
+ }
+ size_t numTrailingObjects(OverloadToken<unsigned>) const {
+ return getUniqueDeclarationsNum() + getTotalComponentListNum();
+ }
+
public:
/// Creates clause with a list of variables \a Vars.
///
@@ -4712,7 +4957,6 @@ 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.
- ///
static OMPIsDevicePtrClause *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, ArrayRef<Expr *> Vars,
@@ -4728,7 +4972,6 @@ public:
/// \param NumComponentLists Number of unique base declarations in this
/// clause.
/// \param NumComponents Total number of expression components in the clause.
- ///
static OMPIsDevicePtrClause *CreateEmpty(const ASTContext &C,
unsigned NumVars,
unsigned NumUniqueDeclarations,
@@ -4744,6 +4987,7 @@ public:
return T->getClauseKind() == OMPC_is_device_ptr;
}
};
-} // end namespace clang
+
+} // namespace clang
#endif // LLVM_CLANG_AST_OPENMPCLAUSE_H
diff --git a/include/clang/AST/OperationKinds.def b/include/clang/AST/OperationKinds.def
index 2d48a7df47b7..b13cf3b63276 100644
--- a/include/clang/AST/OperationKinds.def
+++ b/include/clang/AST/OperationKinds.def
@@ -327,12 +327,13 @@ CAST_OPERATION(ZeroToOCLQueue)
// Convert a pointer to a different address space.
CAST_OPERATION(AddressSpaceConversion)
-// Convert an integer initializer to an OpenCL sampler.
+// Convert an integer initializer to an OpenCL sampler.
CAST_OPERATION(IntToOCLSampler)
//===- Binary Operations -------------------------------------------------===//
// Operators listed in order of precedence.
-// Note that additions to this should also update the StmtVisitor class.
+// Note that additions to this should also update the StmtVisitor class and
+// BinaryOperator::getOverloadedOperator.
// [C++ 5.5] Pointer-to-member operators.
BINARY_OPERATION(PtrMemD, ".*")
@@ -347,6 +348,8 @@ BINARY_OPERATION(Sub, "-")
// [C99 6.5.7] Bitwise shift operators.
BINARY_OPERATION(Shl, "<<")
BINARY_OPERATION(Shr, ">>")
+// C++20 [expr.spaceship] Three-way comparison operator.
+BINARY_OPERATION(Cmp, "<=>")
// [C99 6.5.8] Relational operators.
BINARY_OPERATION(LT, "<")
BINARY_OPERATION(GT, ">")
@@ -382,7 +385,8 @@ BINARY_OPERATION(Comma, ",")
//===- Unary Operations ---------------------------------------------------===//
-// Note that additions to this should also update the StmtVisitor class.
+// Note that additions to this should also update the StmtVisitor class and
+// UnaryOperator::getOverloadedOperator.
// [C99 6.5.2.4] Postfix increment and decrement
UNARY_OPERATION(PostInc, "++")
diff --git a/include/clang/AST/OperationKinds.h b/include/clang/AST/OperationKinds.h
index 00f060fe9e3d..e3832689d64b 100644
--- a/include/clang/AST/OperationKinds.h
+++ b/include/clang/AST/OperationKinds.h
@@ -23,8 +23,6 @@ enum CastKind {
#include "clang/AST/OperationKinds.def"
};
-static const CastKind CK_Invalid = static_cast<CastKind>(-1);
-
enum BinaryOperatorKind {
#define BINARY_OPERATION(Name, Spelling) BO_##Name,
#include "clang/AST/OperationKinds.def"
diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h
index 274df220e160..e831b903cbae 100644
--- a/include/clang/AST/PrettyPrinter.h
+++ b/include/clang/AST/PrettyPrinter.h
@@ -30,8 +30,8 @@ public:
virtual bool handledStmt(Stmt* E, raw_ostream& OS) = 0;
};
-/// \brief Describes how types, statements, expressions, and
-/// declarations should be printed.
+/// Describes how types, statements, expressions, and declarations should be
+/// printed.
///
/// This type is intended to be small and suitable for passing by value.
/// It is very frequently copied.
@@ -50,22 +50,24 @@ struct PrintingPolicy {
UseVoidForZeroParams(!LO.CPlusPlus),
TerseOutput(false), PolishForDeclaration(false),
Half(LO.Half), MSWChar(LO.MicrosoftExt && !LO.WChar),
- IncludeNewlines(true), MSVCFormatting(false) { }
-
- /// \brief 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 construct). This should not be used if a real LangOptions
- /// object is available.
+ IncludeNewlines(true), MSVCFormatting(false),
+ ConstantsAsWritten(false), SuppressImplicitBase(false),
+ FullyQualifiedName(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
+ /// construct). This should not be used if a real LangOptions object is
+ /// available.
void adjustForCPlusPlus() {
SuppressTagKeyword = true;
Bool = true;
UseVoidForZeroParams = false;
}
- /// \brief The number of spaces to use to indent each line.
+ /// The number of spaces to use to indent each line.
unsigned Indentation : 8;
- /// \brief Whether we should suppress printing of the actual specifiers for
+ /// Whether we should suppress printing of the actual specifiers for
/// the given type or declaration.
///
/// This flag is only used when we are printing declarators beyond
@@ -81,7 +83,7 @@ struct PrintingPolicy {
/// "const int" type specifier and instead only print the "*y".
bool SuppressSpecifiers : 1;
- /// \brief Whether type printing should skip printing the tag keyword.
+ /// Whether type printing should skip printing the tag keyword.
///
/// This is used when printing the inner type of elaborated types,
/// (as the tag keyword is part of the elaborated type):
@@ -91,7 +93,7 @@ struct PrintingPolicy {
/// \endcode
bool SuppressTagKeyword : 1;
- /// \brief When true, include the body of a tag definition.
+ /// When true, include the body of a tag definition.
///
/// This is used to place the definition of a struct
/// in the middle of another declaration as with:
@@ -101,14 +103,14 @@ struct PrintingPolicy {
/// \endcode
bool IncludeTagDefinition : 1;
- /// \brief Suppresses printing of scope specifiers.
+ /// Suppresses printing of scope specifiers.
bool SuppressScope : 1;
- /// \brief Suppress printing parts of scope specifiers that don't need
+ /// Suppress printing parts of scope specifiers that don't need
/// to be written, e.g., for inline or anonymous namespaces.
bool SuppressUnwrittenScope : 1;
- /// \brief Suppress printing of variable initializers.
+ /// Suppress printing of variable initializers.
///
/// This flag is used when printing the loop variable in a for-range
/// statement. For example, given:
@@ -121,8 +123,8 @@ struct PrintingPolicy {
/// internal initializer constructed for x will not be printed.
bool SuppressInitializers : 1;
- /// \brief Whether we should print the sizes of constant array expressions
- /// as written in the sources.
+ /// Whether we should print the sizes of constant array expressions as written
+ /// in the sources.
///
/// This flag determines whether array types declared as
///
@@ -139,67 +141,90 @@ struct PrintingPolicy {
/// \endcode
bool ConstantArraySizeAsWritten : 1;
- /// \brief 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.
+ /// 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;
- /// \brief When true, suppress printing of the __strong lifetime qualifier in
- /// ARC.
+ /// When true, suppress printing of the __strong lifetime qualifier in ARC.
unsigned SuppressStrongLifetime : 1;
- /// \brief When true, suppress printing of lifetime qualifier in
- /// ARC.
+ /// When true, suppress printing of lifetime qualifier in ARC.
unsigned SuppressLifetimeQualifiers : 1;
/// When true, suppresses printing template arguments in names of C++
/// constructors.
unsigned SuppressTemplateArgsInCXXConstructors : 1;
- /// \brief Whether we can use 'bool' rather than '_Bool' (even if the language
+ /// Whether we can use 'bool' rather than '_Bool' (even if the language
/// doesn't actually have 'bool', because, e.g., it is defined as a macro).
unsigned Bool : 1;
- /// \brief Whether we can use 'restrict' rather than '__restrict'.
+ /// Whether we can use 'restrict' rather than '__restrict'.
unsigned Restrict : 1;
- /// \brief Whether we can use 'alignof' rather than '__alignof'.
+ /// Whether we can use 'alignof' rather than '__alignof'.
unsigned Alignof : 1;
- /// \brief Whether we can use '_Alignof' rather than '__alignof'.
+ /// Whether we can use '_Alignof' rather than '__alignof'.
unsigned UnderscoreAlignof : 1;
- /// \brief Whether we should use '(void)' rather than '()' for a function
- /// prototype with zero parameters.
+ /// Whether we should use '(void)' rather than '()' for a function prototype
+ /// with zero parameters.
unsigned UseVoidForZeroParams : 1;
- /// \brief Provide a 'terse' output.
+ /// Provide a 'terse' output.
///
/// For example, in this mode we don't print function bodies, class members,
/// declarations inside namespaces etc. Effectively, this should print
/// only the requested declaration.
unsigned TerseOutput : 1;
- /// \brief When true, do certain refinement needed for producing proper
- /// declaration tag; such as, do not print attributes attached to the declaration.
+ /// When true, do certain refinement needed for producing proper declaration
+ /// tag; such as, do not print attributes attached to the declaration.
///
unsigned PolishForDeclaration : 1;
- /// \brief When true, print the half-precision floating-point type as 'half'
+ /// When true, print the half-precision floating-point type as 'half'
/// instead of '__fp16'
unsigned Half : 1;
- /// \brief When true, print the built-in wchar_t type as __wchar_t. For use in
+ /// When true, print the built-in wchar_t type as __wchar_t. For use in
/// Microsoft mode when wchar_t is not available.
unsigned MSWChar : 1;
- /// \brief When true, include newlines after statements like "break", etc.
+ /// When true, include newlines after statements like "break", etc.
unsigned IncludeNewlines : 1;
- /// \brief Use whitespace and punctuation like MSVC does. In particular, this
- /// prints anonymous namespaces as `anonymous namespace' and does not insert
- /// spaces after template arguments.
+ /// 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;
+
+ /// Whether we should print the constant expressions as written in the
+ /// sources.
+ ///
+ /// This flag determines whether constants expressions like
+ ///
+ /// \code
+ /// 0x10
+ /// 2.5e3
+ /// \endcode
+ ///
+ /// will be printed as written or as follows:
+ ///
+ /// \code
+ /// 0x10
+ /// 2.5e3
+ /// \endcode
+ bool ConstantsAsWritten : 1;
+
+ /// When true, don't print the implicit 'self' or 'this' expressions.
+ bool 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;
};
} // end namespace clang
diff --git a/include/clang/Tooling/Core/QualTypeNames.h b/include/clang/AST/QualTypeNames.h
index 7248356e748e..86d805feeed7 100644
--- a/include/clang/Tooling/Core/QualTypeNames.h
+++ b/include/clang/AST/QualTypeNames.h
@@ -56,8 +56,8 @@
//
// ===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_TOOLING_CORE_QUALTYPENAMES_H
-#define LLVM_CLANG_TOOLING_CORE_QUALTYPENAMES_H
+#ifndef LLVM_CLANG_AST_QUALTYPENAMES_H
+#define LLVM_CLANG_AST_QUALTYPENAMES_H
#include "clang/AST/ASTContext.h"
@@ -71,9 +71,20 @@ namespace TypeName {
/// \param[in] Ctx - the ASTContext to be used.
/// \param[in] WithGlobalNsPrefix - If true, then the global namespace
/// specifier "::" will be prepended to the fully qualified name.
-std::string getFullyQualifiedName(QualType QT,
- const ASTContext &Ctx,
+std::string getFullyQualifiedName(QualType QT, const ASTContext &Ctx,
bool WithGlobalNsPrefix = false);
-} // end namespace TypeName
-} // end namespace clang
-#endif // LLVM_CLANG_TOOLING_CORE_QUALTYPENAMES_H
+
+/// \brief Generates a QualType that can be used to name the same type
+/// if used at the end of the current translation unit. This ignores
+/// issues such as type shadowing.
+///
+/// \param[in] QT - the type for which the fully qualified type will be
+/// returned.
+/// \param[in] Ctx - the ASTContext to be used.
+/// \param[in] WithGlobalNsPrefix - Indicate whether the global namespace
+/// specifier "::" should be prepended or not.
+QualType getFullyQualifiedType(QualType QT, const ASTContext &Ctx,
+ bool WithGlobalNsPrefix = false);
+} // end namespace TypeName
+} // end namespace clang
+#endif // LLVM_CLANG_TOOLING_CORE_QUALTYPENAMES_H
diff --git a/include/clang/AST/RecordLayout.h b/include/clang/AST/RecordLayout.h
index 7a39c3b2539d..696d44efa0d9 100644
--- a/include/clang/AST/RecordLayout.h
+++ b/include/clang/AST/RecordLayout.h
@@ -1,4 +1,4 @@
-//===--- RecordLayout.h - Layout information for a struct/union -*- C++ -*-===//
+//===- RecordLayout.h - Layout information for a struct/union ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,15 +14,20 @@
#ifndef LLVM_CLANG_AST_RECORDLAYOUT_H
#define LLVM_CLANG_AST_RECORDLAYOUT_H
+#include "clang/AST/ASTVector.h"
#include "clang/AST/CharUnits.h"
#include "clang/AST/DeclCXX.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include <cassert>
+#include <cstdint>
namespace clang {
- class ASTContext;
- class FieldDecl;
- class RecordDecl;
- class CXXRecordDecl;
+
+class ASTContext;
+class CXXRecordDecl;
/// ASTRecordLayout -
/// This class contains layout information for one RecordDecl,
@@ -42,21 +47,21 @@ public:
/// Whether this virtual base requires a vtordisp field in the
/// Microsoft ABI. These fields are required for certain operations
/// in constructors and destructors.
- bool HasVtorDisp;
+ bool HasVtorDisp = false;
public:
- bool hasVtorDisp() const { return HasVtorDisp; }
-
- VBaseInfo() : HasVtorDisp(false) {}
+ VBaseInfo() = default;
+ VBaseInfo(CharUnits VBaseOffset, bool hasVtorDisp)
+ : VBaseOffset(VBaseOffset), HasVtorDisp(hasVtorDisp) {}
- VBaseInfo(CharUnits VBaseOffset, bool hasVtorDisp) :
- VBaseOffset(VBaseOffset), HasVtorDisp(hasVtorDisp) {}
+ bool hasVtorDisp() const { return HasVtorDisp; }
};
- typedef llvm::DenseMap<const CXXRecordDecl *, VBaseInfo>
- VBaseOffsetsMapTy;
+ using VBaseOffsetsMapTy = llvm::DenseMap<const CXXRecordDecl *, VBaseInfo>;
private:
+ friend class ASTContext;
+
/// Size - Size of record in characters.
CharUnits Size;
@@ -117,7 +122,7 @@ private:
const CXXRecordDecl *BaseSharingVBPtr;
/// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :)
- typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetsMapTy;
+ using BaseOffsetsMapTy = llvm::DenseMap<const CXXRecordDecl *, CharUnits>;
/// BaseOffsets - Contains a map from base classes to their offset.
BaseOffsetsMapTy BaseOffsets;
@@ -128,16 +133,15 @@ private:
/// CXXInfo - If the record layout is for a C++ record, this will have
/// C++ specific information about the record.
- CXXRecordLayoutInfo *CXXInfo;
-
- friend class ASTContext;
+ CXXRecordLayoutInfo *CXXInfo = nullptr;
ASTRecordLayout(const ASTContext &Ctx, CharUnits size, CharUnits alignment,
CharUnits requiredAlignment, CharUnits datasize,
ArrayRef<uint64_t> fieldoffsets);
+ using BaseOffsetsMapTy = CXXRecordLayoutInfo::BaseOffsetsMapTy;
+
// Constructor for C++ records.
- typedef CXXRecordLayoutInfo::BaseOffsetsMapTy BaseOffsetsMapTy;
ASTRecordLayout(const ASTContext &Ctx,
CharUnits size, CharUnits alignment,
CharUnits requiredAlignment,
@@ -159,9 +163,9 @@ private:
void Destroy(ASTContext &Ctx);
- ASTRecordLayout(const ASTRecordLayout &) = delete;
- void operator=(const ASTRecordLayout &) = delete;
public:
+ ASTRecordLayout(const ASTRecordLayout &) = delete;
+ ASTRecordLayout &operator=(const ASTRecordLayout &) = delete;
/// getAlignment - Get the record alignment in characters.
CharUnits getAlignment() const { return Alignment; }
@@ -305,6 +309,6 @@ public:
}
};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_AST_RECORDLAYOUT_H
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index e7f271cc0812..ba76ea0a0df5 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -63,8 +63,8 @@
OPERATOR(PtrMemD) OPERATOR(PtrMemI) OPERATOR(Mul) OPERATOR(Div) \
OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) OPERATOR(Shl) OPERATOR(Shr) \
OPERATOR(LT) OPERATOR(GT) OPERATOR(LE) OPERATOR(GE) OPERATOR(EQ) \
- OPERATOR(NE) OPERATOR(And) OPERATOR(Xor) OPERATOR(Or) OPERATOR(LAnd) \
- OPERATOR(LOr) OPERATOR(Assign) OPERATOR(Comma)
+ OPERATOR(NE) OPERATOR(Cmp) OPERATOR(And) OPERATOR(Xor) OPERATOR(Or) \
+ OPERATOR(LAnd) OPERATOR(LOr) OPERATOR(Assign) OPERATOR(Comma)
// All compound assign operators.
#define CAO_LIST() \
@@ -83,7 +83,7 @@ namespace clang {
return false; \
} while (false)
-/// \brief A class that does preordor or postorder
+/// \brief A class that does preorder or postorder
/// depth-first traversal on the entire Clang AST and visits each node.
///
/// This class performs three distinct tasks:
@@ -267,6 +267,12 @@ public:
bool TraverseTemplateArguments(const TemplateArgument *Args,
unsigned NumArgs);
+ /// \brief Recursively visit a base specifier. This can be overridden by a
+ /// subclass.
+ ///
+ /// \returns false if the visitation was terminated early, true otherwise.
+ bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &Base);
+
/// \brief Recursively visit a constructor initializer. This
/// automatically dispatches to another visitor for the initializer
/// expression, but not for the name of the initializer, so may
@@ -309,6 +315,8 @@ public:
// ---- Methods on Stmts ----
+ Stmt::child_range getStmtChildren(Stmt *S) { return S->children(); }
+
private:
template<typename T, typename U>
struct has_same_member_pointer_type : std::false_type {};
@@ -491,6 +499,8 @@ public:
bool Visit##CLASS##Decl(CLASS##Decl *D) { return true; }
#include "clang/AST/DeclNodes.inc"
+ bool canIgnoreChildDeclWhileTraversingDeclContext(const Decl *Child);
+
private:
// These are helper methods used by more than one Traverse* method.
bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL);
@@ -978,6 +988,11 @@ DEF_TRAVERSE_TYPE(DependentSizedArrayType, {
TRY_TO(TraverseStmt(T->getSizeExpr()));
})
+DEF_TRAVERSE_TYPE(DependentAddressSpaceType, {
+ TRY_TO(TraverseStmt(T->getAddrSpaceExpr()));
+ TRY_TO(TraverseType(T->getPointeeType()));
+})
+
DEF_TRAVERSE_TYPE(DependentSizedExtVectorType, {
if (T->getSizeExpr())
TRY_TO(TraverseStmt(T->getSizeExpr()));
@@ -1188,6 +1203,11 @@ DEF_TRAVERSE_TYPELOC(DependentSizedArrayType, {
return TraverseArrayTypeLocHelper(TL);
})
+DEF_TRAVERSE_TYPELOC(DependentAddressSpaceType, {
+ TRY_TO(TraverseStmt(TL.getTypePtr()->getAddrSpaceExpr()));
+ TRY_TO(TraverseType(TL.getTypePtr()->getPointeeType()));
+})
+
// FIXME: order? why not size expr first?
// FIXME: base VectorTypeLoc is unfinished
DEF_TRAVERSE_TYPELOC(DependentSizedExtVectorType, {
@@ -1339,14 +1359,20 @@ DEF_TRAVERSE_TYPELOC(PipeType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
// than those.
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);
+}
+
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseDeclContextHelper(DeclContext *DC) {
if (!DC)
return true;
for (auto *Child : DC->decls()) {
- // BlockDecls and CapturedDecls are traversed through BlockExprs and
- // CapturedStmts respectively.
- if (!isa<BlockDecl>(Child) && !isa<CapturedDecl>(Child))
+ if (!canIgnoreChildDeclWhileTraversingDeclContext(Child))
TRY_TO(TraverseDecl(Child));
}
@@ -1674,8 +1700,8 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations(
// template declarations.
#define DEF_TRAVERSE_TMPL_DECL(TMPLDECLKIND) \
DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateDecl, { \
- TRY_TO(TraverseDecl(D->getTemplatedDecl())); \
TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); \
+ TRY_TO(TraverseDecl(D->getTemplatedDecl())); \
\
/* By default, we do not traverse the instantiations of \
class templates since they do not appear in the user code. The \
@@ -1769,12 +1795,19 @@ bool RecursiveASTVisitor<Derived>::TraverseRecordHelper(RecordDecl *D) {
}
template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseCXXBaseSpecifier(
+ const CXXBaseSpecifier &Base) {
+ TRY_TO(TraverseTypeLoc(Base.getTypeSourceInfo()->getTypeLoc()));
+ return true;
+}
+
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseCXXRecordHelper(CXXRecordDecl *D) {
if (!TraverseRecordHelper(D))
return false;
if (D->isCompleteDefinition()) {
for (const auto &I : D->bases()) {
- TRY_TO(TraverseTypeLoc(I.getTypeSourceInfo()->getTypeLoc()));
+ TRY_TO(TraverseCXXBaseSpecifier(I));
}
// We don't traverse the friends or the conversions, as they are
// already in decls_begin()/decls_end().
@@ -2057,7 +2090,7 @@ DEF_TRAVERSE_DECL(ParmVarDecl, {
TRY_TO(WalkUpFrom##STMT(S)); \
{ CODE; } \
if (ShouldVisitChildren) { \
- for (Stmt *SubStmt : S->children()) { \
+ for (Stmt * SubStmt : getDerived().getStmtChildren(S)) { \
TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(SubStmt); \
} \
} \
@@ -3039,6 +3072,30 @@ bool RecursiveASTVisitor<Derived>::VisitOMPTaskReductionClause(
}
template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPInReductionClause(
+ OMPInReductionClause *C) {
+ TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));
+ TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo()));
+ TRY_TO(VisitOMPClauseList(C));
+ TRY_TO(VisitOMPClauseWithPostUpdate(C));
+ for (auto *E : C->privates()) {
+ TRY_TO(TraverseStmt(E));
+ }
+ for (auto *E : C->lhs_exprs()) {
+ TRY_TO(TraverseStmt(E));
+ }
+ for (auto *E : C->rhs_exprs()) {
+ TRY_TO(TraverseStmt(E));
+ }
+ for (auto *E : C->reduction_ops()) {
+ TRY_TO(TraverseStmt(E));
+ }
+ for (auto *E : C->taskgroup_descriptors())
+ TRY_TO(TraverseStmt(E));
+ return true;
+}
+
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPFlushClause(OMPFlushClause *C) {
TRY_TO(VisitOMPClauseList(C));
return true;
@@ -3052,6 +3109,7 @@ bool RecursiveASTVisitor<Derived>::VisitOMPDependClause(OMPDependClause *C) {
template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPDeviceClause(OMPDeviceClause *C) {
+ TRY_TO(VisitOMPClauseWithPreInit(C));
TRY_TO(TraverseStmt(C->getDevice()));
return true;
}
diff --git a/include/clang/AST/Redeclarable.h b/include/clang/AST/Redeclarable.h
index 89a9d3c4cc21..86b0f356e7b5 100644
--- a/include/clang/AST/Redeclarable.h
+++ b/include/clang/AST/Redeclarable.h
@@ -1,4 +1,4 @@
-//===-- Redeclarable.h - Base for Decls that can be redeclared -*- C++ -*-====//
+//===- Redeclarable.h - Base for Decls that can be redeclared --*- C++ -*-====//
//
// The LLVM Compiler Infrastructure
//
@@ -15,11 +15,18 @@
#define LLVM_CLANG_AST_REDECLARABLE_H
#include "clang/AST/ExternalASTSource.h"
+#include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Casting.h"
+#include <cassert>
+#include <cstddef>
#include <iterator>
namespace clang {
+
class ASTContext;
+class Decl;
// Some notes on redeclarables:
//
@@ -82,21 +89,21 @@ protected:
class DeclLink {
/// A pointer to a known latest declaration, either statically known or
/// generationally updated as decls are added by an external source.
- typedef LazyGenerationalUpdatePtr<const Decl*, Decl*,
- &ExternalASTSource::CompleteRedeclChain>
- KnownLatest;
+ using KnownLatest =
+ LazyGenerationalUpdatePtr<const Decl *, Decl *,
+ &ExternalASTSource::CompleteRedeclChain>;
/// We store a pointer to the ASTContext in the UninitializedLatest
/// pointer, but to avoid circular type dependencies when we steal the low
/// bits of this pointer, we use a raw void* here.
- typedef const void *UninitializedLatest;
+ using UninitializedLatest = const void *;
- typedef Decl *Previous;
+ using Previous = Decl *;
/// A pointer to either an uninitialized latest declaration (where either
/// we've not yet set the previous decl or there isn't one), or to a known
/// previous declaration.
- typedef llvm::PointerUnion<Previous, UninitializedLatest> NotKnownLatest;
+ using NotKnownLatest = llvm::PointerUnion<Previous, UninitializedLatest>;
mutable llvm::PointerUnion<NotKnownLatest, KnownLatest> Next;
@@ -106,8 +113,7 @@ protected:
DeclLink(LatestTag, const ASTContext &Ctx)
: Next(NotKnownLatest(reinterpret_cast<UninitializedLatest>(&Ctx))) {}
- DeclLink(PreviousTag, decl_type *D)
- : Next(NotKnownLatest(Previous(D))) {}
+ DeclLink(PreviousTag, decl_type *D) : Next(NotKnownLatest(Previous(D))) {}
bool NextIsPrevious() const {
return Next.is<NotKnownLatest>() &&
@@ -182,6 +188,7 @@ protected:
///
/// If there is only one declaration, it is <pointer to self, true>
DeclLink RedeclLink;
+
decl_type *First;
decl_type *getNextRedeclaration() const {
@@ -189,8 +196,12 @@ protected:
}
public:
- Redeclarable(const ASTContext &Ctx)
- : RedeclLink(LatestDeclLink(Ctx)), First(static_cast<decl_type *>(this)) {}
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+
+ Redeclarable(const ASTContext &Ctx)
+ : RedeclLink(LatestDeclLink(Ctx)),
+ First(static_cast<decl_type *>(this)) {}
/// \brief Return the previous declaration of this declaration or NULL if this
/// is the first declaration.
@@ -232,20 +243,19 @@ public:
/// \brief Iterates through all the redeclarations of the same decl.
class redecl_iterator {
/// Current - The current declaration.
- decl_type *Current;
+ decl_type *Current = nullptr;
decl_type *Starter;
- bool PassedFirst;
+ bool PassedFirst = false;
public:
- typedef decl_type* value_type;
- typedef decl_type* reference;
- typedef decl_type* pointer;
- typedef std::forward_iterator_tag iterator_category;
- typedef std::ptrdiff_t difference_type;
+ using value_type = decl_type *;
+ using reference = decl_type *;
+ using pointer = decl_type *;
+ using iterator_category = std::forward_iterator_tag;
+ using difference_type = std::ptrdiff_t;
- redecl_iterator() : Current(nullptr) { }
- explicit redecl_iterator(decl_type *C)
- : Current(C), Starter(C), PassedFirst(false) { }
+ redecl_iterator() = default;
+ explicit redecl_iterator(decl_type *C) : Current(C), Starter(C) {}
reference operator*() const { return Current; }
pointer operator->() const { return Current; }
@@ -282,7 +292,7 @@ public:
}
};
- typedef llvm::iterator_range<redecl_iterator> redecl_range;
+ using redecl_range = llvm::iterator_range<redecl_iterator>;
/// \brief Returns an iterator range for all the redeclarations of the same
/// decl. It will iterate at least once (when this decl is the only one).
@@ -294,9 +304,6 @@ public:
redecl_iterator redecls_begin() const { return redecls().begin(); }
redecl_iterator redecls_end() const { return redecls().end(); }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
};
/// \brief Get the primary declaration for a declaration from an AST file. That
@@ -309,7 +316,7 @@ Decl *getPrimaryMergedDecl(Decl *D);
template<typename decl_type>
class Mergeable {
public:
- Mergeable() {}
+ Mergeable() = default;
/// \brief Return the first declaration of this declaration or itself if this
/// is the only declaration.
@@ -344,7 +351,7 @@ public:
/// remember to call getCanonicalDecl() everywhere.
template <typename decl_type> class CanonicalDeclPtr {
public:
- CanonicalDeclPtr() : Ptr(nullptr) {}
+ CanonicalDeclPtr() = default;
CanonicalDeclPtr(decl_type *Ptr)
: Ptr(Ptr ? Ptr->getCanonicalDecl() : nullptr) {}
CanonicalDeclPtr(const CanonicalDeclPtr &) = default;
@@ -362,11 +369,13 @@ public:
private:
friend struct llvm::DenseMapInfo<CanonicalDeclPtr<decl_type>>;
- decl_type *Ptr;
+ decl_type *Ptr = nullptr;
};
+
} // namespace clang
namespace llvm {
+
template <typename decl_type>
struct DenseMapInfo<clang::CanonicalDeclPtr<decl_type>> {
using CanonicalDeclPtr = clang::CanonicalDeclPtr<decl_type>;
@@ -395,6 +404,7 @@ struct DenseMapInfo<clang::CanonicalDeclPtr<decl_type>> {
return BaseInfo::isEqual(LHS, RHS);
}
};
+
} // namespace llvm
-#endif
+#endif // LLVM_CLANG_AST_REDECLARABLE_H
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index c210bd1cec2e..6bd07af1affa 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -1,4 +1,4 @@
-//===--- Stmt.h - Classes for representing statements -----------*- C++ -*-===//
+//===- Stmt.h - Classes for representing statements -------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -22,34 +22,40 @@
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <iterator>
#include <string>
namespace llvm {
- class FoldingSetNodeID;
-}
+
+class FoldingSetNodeID;
+
+} // namespace llvm
namespace clang {
- class ASTContext;
- class Attr;
- class CapturedDecl;
- class Decl;
- class Expr;
- class IdentifierInfo;
- class LabelDecl;
- class ODRHash;
- class ParmVarDecl;
- class PrinterHelper;
- struct PrintingPolicy;
- class QualType;
- class RecordDecl;
- class SourceManager;
- class StringLiteral;
- class SwitchStmt;
- class Token;
- class VarDecl;
+
+class ASTContext;
+class Attr;
+class CapturedDecl;
+class Decl;
+class Expr;
+class LabelDecl;
+class ODRHash;
+class PrinterHelper;
+struct PrintingPolicy;
+class RecordDecl;
+class SourceManager;
+class StringLiteral;
+class Token;
+class VarDecl;
//===----------------------------------------------------------------------===//
// AST classes for statements.
@@ -72,9 +78,13 @@ public:
// Make vanilla 'new' and 'delete' illegal for Stmts.
protected:
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+
void *operator new(size_t bytes) noexcept {
llvm_unreachable("Stmts cannot be allocated with regular 'new'.");
}
+
void operator delete(void *data) noexcept {
llvm_unreachable("Stmts cannot be released with regular 'delete'.");
}
@@ -89,6 +99,7 @@ protected:
class CompoundStmtBitfields {
friend class CompoundStmt;
+
unsigned : NumStmtBits;
unsigned NumStmts : 32 - NumStmtBits;
@@ -96,34 +107,36 @@ protected:
class IfStmtBitfields {
friend class IfStmt;
+
unsigned : NumStmtBits;
unsigned IsConstexpr : 1;
};
class ExprBitfields {
- friend class Expr;
- friend class DeclRefExpr; // computeDependence
- friend class InitListExpr; // ctor
- friend class DesignatedInitExpr; // ctor
- friend class BlockDeclRefExpr; // ctor
friend class ASTStmtReader; // deserialization
+ friend class AtomicExpr; // ctor
+ friend class BlockDeclRefExpr; // ctor
+ friend class CallExpr; // ctor
+ friend class CXXConstructExpr; // ctor
+ friend class CXXDependentScopeMemberExpr; // ctor
friend class CXXNewExpr; // ctor
+ friend class CXXUnresolvedConstructExpr; // ctor
+ friend class DeclRefExpr; // computeDependence
friend class DependentScopeDeclRefExpr; // ctor
- friend class CXXConstructExpr; // ctor
- friend class CallExpr; // ctor
- friend class OffsetOfExpr; // ctor
- friend class ObjCMessageExpr; // ctor
+ friend class DesignatedInitExpr; // ctor
+ friend class Expr;
+ friend class InitListExpr; // ctor
friend class ObjCArrayLiteral; // ctor
friend class ObjCDictionaryLiteral; // ctor
- friend class ShuffleVectorExpr; // ctor
- friend class ParenListExpr; // ctor
- friend class CXXUnresolvedConstructExpr; // ctor
- friend class CXXDependentScopeMemberExpr; // ctor
+ friend class ObjCMessageExpr; // ctor
+ friend class OffsetOfExpr; // ctor
+ friend class OpaqueValueExpr; // ctor
friend class OverloadExpr; // ctor
+ friend class ParenListExpr; // ctor
friend class PseudoObjectExpr; // ctor
- friend class AtomicExpr; // ctor
- friend class OpaqueValueExpr; // ctor
+ friend class ShuffleVectorExpr; // ctor
+
unsigned : NumStmtBits;
unsigned ValueKind : 2;
@@ -137,6 +150,7 @@ protected:
class CharacterLiteralBitfields {
friend class CharacterLiteral;
+
unsigned : NumExprBits;
unsigned Kind : 3;
@@ -153,6 +167,7 @@ protected:
class FloatingLiteralBitfields {
friend class FloatingLiteral;
+
unsigned : NumExprBits;
unsigned Semantics : 3; // Provides semantics for APFloat construction
@@ -161,6 +176,7 @@ protected:
class UnaryExprOrTypeTraitExprBitfields {
friend class UnaryExprOrTypeTraitExpr;
+
unsigned : NumExprBits;
unsigned Kind : 2;
@@ -168,8 +184,9 @@ protected:
};
class DeclRefExprBitfields {
- friend class DeclRefExpr;
friend class ASTStmtReader; // deserialization
+ friend class DeclRefExpr;
+
unsigned : NumExprBits;
unsigned HasQualifier : 1;
@@ -181,6 +198,7 @@ protected:
class CastExprBitfields {
friend class CastExpr;
+
unsigned : NumExprBits;
unsigned Kind : 6;
@@ -189,14 +207,15 @@ protected:
class CallExprBitfields {
friend class CallExpr;
+
unsigned : NumExprBits;
unsigned NumPreArgs : 1;
};
class ExprWithCleanupsBitfields {
- friend class ExprWithCleanups;
friend class ASTStmtReader; // deserialization
+ friend class ExprWithCleanups;
unsigned : NumExprBits;
@@ -207,8 +226,8 @@ protected:
};
class PseudoObjectExprBitfields {
- friend class PseudoObjectExpr;
friend class ASTStmtReader; // deserialization
+ friend class PseudoObjectExpr;
unsigned : NumExprBits;
@@ -220,6 +239,7 @@ protected:
class ObjCIndirectCopyRestoreExprBitfields {
friend class ObjCIndirectCopyRestoreExpr;
+
unsigned : NumExprBits;
unsigned ShouldCopy : 1;
@@ -236,9 +256,9 @@ protected:
};
class TypeTraitExprBitfields {
- friend class TypeTraitExpr;
friend class ASTStmtReader;
friend class ASTStmtWriter;
+ friend class TypeTraitExpr;
unsigned : NumExprBits;
@@ -280,9 +300,6 @@ protected:
CoawaitExprBitfields CoawaitBits;
};
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-
public:
// Only allow allocation of Stmts using the allocator in ASTContext
// or by doing a placement new.
@@ -305,7 +322,7 @@ public:
/// \brief A placeholder type used to construct an empty shell of a
/// type, that will be filled in later (e.g., by some
/// de-serialization).
- struct EmptyShell { };
+ struct EmptyShell {};
protected:
/// Iterator for iterating over Stmt * arrays that contain only Expr *
@@ -361,6 +378,7 @@ public:
StmtClass getStmtClass() const {
return static_cast<StmtClass>(StmtBits.sClass);
}
+
const char *getStmtClassName() const;
/// SourceLocation tokens are not useful in isolation - they are low level
@@ -389,8 +407,8 @@ public:
/// back to its original source language syntax.
void dumpPretty(const ASTContext &Context) const;
void printPretty(raw_ostream &OS, PrinterHelper *Helper,
- const PrintingPolicy &Policy,
- unsigned Indentation = 0) const;
+ const PrintingPolicy &Policy, unsigned Indentation = 0,
+ const ASTContext *Context = nullptr) const;
/// viewAST - Visualize an AST rooted at this Stmt* using GraphViz. Only
/// works on systems with GraphViz (Mac OS X) or dot+gv installed.
@@ -406,6 +424,9 @@ public:
/// \brief Skip no-op (attributed, compound) container stmts and skip captured
/// stmt at the top, if \a IgnoreCaptured is true.
Stmt *IgnoreContainers(bool IgnoreCaptured = false);
+ const Stmt *IgnoreContainers(bool IgnoreCaptured = false) const {
+ return const_cast<Stmt *>(this)->IgnoreContainers(IgnoreCaptured);
+ }
const Stmt *stripLabelLikeStatements() const;
Stmt *stripLabelLikeStatements() {
@@ -416,11 +437,11 @@ public:
/// Child Iterators: All subclasses must implement 'children'
/// to permit easy iteration over the substatements/subexpessions of an
/// AST node. This permits easy iteration over all nodes in the AST.
- typedef StmtIterator child_iterator;
- typedef ConstStmtIterator const_child_iterator;
+ using child_iterator = StmtIterator;
+ using const_child_iterator = ConstStmtIterator;
- typedef llvm::iterator_range<child_iterator> child_range;
- typedef llvm::iterator_range<const_child_iterator> const_child_range;
+ using child_range = llvm::iterator_range<child_iterator>;
+ using const_child_range = llvm::iterator_range<const_child_iterator>;
child_range children();
const_child_range children() const {
@@ -463,18 +484,16 @@ public:
/// expressions. For example, CompoundStmt mixes statements, expressions
/// and declarations (variables, types). Another example is ForStmt, where
/// the first statement can be an expression or a declaration.
-///
class DeclStmt : public Stmt {
DeclGroupRef DG;
SourceLocation StartLoc, EndLoc;
public:
- DeclStmt(DeclGroupRef dg, SourceLocation startLoc,
- SourceLocation endLoc) : Stmt(DeclStmtClass), DG(dg),
- StartLoc(startLoc), EndLoc(endLoc) {}
+ DeclStmt(DeclGroupRef dg, SourceLocation startLoc, SourceLocation endLoc)
+ : Stmt(DeclStmtClass), DG(dg), StartLoc(startLoc), EndLoc(endLoc) {}
/// \brief Build an empty declaration statement.
- explicit DeclStmt(EmptyShell Empty) : Stmt(DeclStmtClass, Empty) { }
+ explicit DeclStmt(EmptyShell Empty) : Stmt(DeclStmtClass, Empty) {}
/// isSingleDecl - This method returns true if this DeclStmt refers
/// to a single Decl.
@@ -507,10 +526,10 @@ public:
child_iterator(DG.end(), DG.end()));
}
- typedef DeclGroupRef::iterator decl_iterator;
- typedef DeclGroupRef::const_iterator const_decl_iterator;
- typedef llvm::iterator_range<decl_iterator> decl_range;
- typedef llvm::iterator_range<const_decl_iterator> decl_const_range;
+ using decl_iterator = DeclGroupRef::iterator;
+ using const_decl_iterator = DeclGroupRef::const_iterator;
+ using decl_range = llvm::iterator_range<decl_iterator>;
+ using decl_const_range = llvm::iterator_range<const_decl_iterator>;
decl_range decls() { return decl_range(decl_begin(), decl_end()); }
decl_const_range decls() const {
@@ -521,10 +540,12 @@ public:
const_decl_iterator decl_begin() const { return DG.begin(); }
const_decl_iterator decl_end() const { return DG.end(); }
- typedef std::reverse_iterator<decl_iterator> reverse_decl_iterator;
+ using reverse_decl_iterator = std::reverse_iterator<decl_iterator>;
+
reverse_decl_iterator decl_rbegin() {
return reverse_decl_iterator(decl_end());
}
+
reverse_decl_iterator decl_rend() {
return reverse_decl_iterator(decl_begin());
}
@@ -540,15 +561,18 @@ class NullStmt : public Stmt {
/// #define CALL(x)
/// CALL(0);
/// @endcode
- bool HasLeadingEmptyMacro;
+ bool HasLeadingEmptyMacro = false;
+
public:
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+
NullStmt(SourceLocation L, bool hasLeadingEmptyMacro = false)
- : Stmt(NullStmtClass), SemiLoc(L),
- HasLeadingEmptyMacro(hasLeadingEmptyMacro) {}
+ : Stmt(NullStmtClass), SemiLoc(L),
+ HasLeadingEmptyMacro(hasLeadingEmptyMacro) {}
/// \brief Build an empty null statement.
- explicit NullStmt(EmptyShell Empty) : Stmt(NullStmtClass, Empty),
- HasLeadingEmptyMacro(false) { }
+ explicit NullStmt(EmptyShell Empty) : Stmt(NullStmtClass, Empty) {}
SourceLocation getSemiLoc() const { return SemiLoc; }
void setSemiLoc(SourceLocation L) { SemiLoc = L; }
@@ -565,32 +589,27 @@ public:
child_range children() {
return child_range(child_iterator(), child_iterator());
}
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
};
/// CompoundStmt - This represents a group of statements like { stmt stmt }.
-///
class CompoundStmt : public Stmt {
- Stmt** Body;
- SourceLocation LBraceLoc, RBraceLoc;
-
friend class ASTStmtReader;
+ Stmt** Body = nullptr;
+ SourceLocation LBraceLoc, RBraceLoc;
+
public:
CompoundStmt(const ASTContext &C, ArrayRef<Stmt*> Stmts,
SourceLocation LB, SourceLocation RB);
// \brief Build an empty compound statement with a location.
explicit CompoundStmt(SourceLocation Loc)
- : Stmt(CompoundStmtClass), Body(nullptr), LBraceLoc(Loc), RBraceLoc(Loc) {
+ : Stmt(CompoundStmtClass), LBraceLoc(Loc), RBraceLoc(Loc) {
CompoundStmtBits.NumStmts = 0;
}
// \brief Build an empty compound statement.
- explicit CompoundStmt(EmptyShell Empty)
- : Stmt(CompoundStmtClass, Empty), Body(nullptr) {
+ explicit CompoundStmt(EmptyShell Empty) : Stmt(CompoundStmtClass, Empty) {
CompoundStmtBits.NumStmts = 0;
}
@@ -599,8 +618,8 @@ public:
bool body_empty() const { return CompoundStmtBits.NumStmts == 0; }
unsigned size() const { return CompoundStmtBits.NumStmts; }
- typedef Stmt** body_iterator;
- typedef llvm::iterator_range<body_iterator> body_range;
+ using body_iterator = Stmt **;
+ using body_range = llvm::iterator_range<body_iterator>;
body_range body() { return body_range(body_begin(), body_end()); }
body_iterator body_begin() { return Body; }
@@ -613,31 +632,36 @@ public:
Body[size()-1] = S;
}
- typedef Stmt* const * const_body_iterator;
- typedef llvm::iterator_range<const_body_iterator> body_const_range;
+ using const_body_iterator = Stmt* const *;
+ using body_const_range = llvm::iterator_range<const_body_iterator>;
body_const_range body() const {
return body_const_range(body_begin(), body_end());
}
+
const_body_iterator body_begin() const { return Body; }
const_body_iterator body_end() const { return Body + size(); }
+
const Stmt *body_front() const {
return !body_empty() ? Body[0] : nullptr;
}
+
const Stmt *body_back() const {
return !body_empty() ? Body[size() - 1] : nullptr;
}
- typedef std::reverse_iterator<body_iterator> reverse_body_iterator;
+ using reverse_body_iterator = std::reverse_iterator<body_iterator>;
+
reverse_body_iterator body_rbegin() {
return reverse_body_iterator(body_end());
}
+
reverse_body_iterator body_rend() {
return reverse_body_iterator(body_begin());
}
- typedef std::reverse_iterator<const_body_iterator>
- const_reverse_body_iterator;
+ using const_reverse_body_iterator =
+ std::reverse_iterator<const_body_iterator>;
const_reverse_body_iterator body_rbegin() const {
return const_reverse_body_iterator(body_end());
@@ -673,16 +697,14 @@ class SwitchCase : public Stmt {
protected:
// A pointer to the following CaseStmt or DefaultStmt class,
// used by SwitchStmt.
- SwitchCase *NextSwitchCase;
+ SwitchCase *NextSwitchCase = nullptr;
SourceLocation KeywordLoc;
SourceLocation ColonLoc;
SwitchCase(StmtClass SC, SourceLocation KWLoc, SourceLocation ColonLoc)
- : Stmt(SC), NextSwitchCase(nullptr), KeywordLoc(KWLoc), ColonLoc(ColonLoc) {
- }
+ : Stmt(SC), KeywordLoc(KWLoc), ColonLoc(ColonLoc) {}
- SwitchCase(StmtClass SC, EmptyShell)
- : Stmt(SC), NextSwitchCase(nullptr) {}
+ SwitchCase(StmtClass SC, EmptyShell) : Stmt(SC) {}
public:
const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; }
@@ -715,6 +737,7 @@ class CaseStmt : public SwitchCase {
enum { LHS, RHS, SUBSTMT, END_EXPR };
Stmt* SubExprs[END_EXPR]; // The expression for the RHS is Non-null for
// GNU "case 1 ... 4" extension
+
public:
CaseStmt(Expr *lhs, Expr *rhs, SourceLocation caseLoc,
SourceLocation ellipsisLoc, SourceLocation colonLoc)
@@ -726,7 +749,7 @@ public:
}
/// \brief Build an empty switch case statement.
- explicit CaseStmt(EmptyShell Empty) : SwitchCase(CaseStmtClass, Empty) { }
+ explicit CaseStmt(EmptyShell Empty) : SwitchCase(CaseStmtClass, Empty) {}
SourceLocation getCaseLoc() const { return KeywordLoc; }
void setCaseLoc(SourceLocation L) { KeywordLoc = L; }
@@ -742,9 +765,11 @@ public:
const Expr *getLHS() const {
return reinterpret_cast<const Expr*>(SubExprs[LHS]);
}
+
const Expr *getRHS() const {
return reinterpret_cast<const Expr*>(SubExprs[RHS]);
}
+
const Stmt *getSubStmt() const { return SubExprs[SUBSTMT]; }
void setSubStmt(Stmt *S) { SubExprs[SUBSTMT] = S; }
@@ -752,6 +777,7 @@ public:
void setRHS(Expr *Val) { SubExprs[RHS] = reinterpret_cast<Stmt*>(Val); }
SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; }
+
SourceLocation getLocEnd() const LLVM_READONLY {
// Handle deeply nested case statements with iteration instead of recursion.
const CaseStmt *CS = this;
@@ -773,13 +799,14 @@ public:
class DefaultStmt : public SwitchCase {
Stmt* SubStmt;
+
public:
DefaultStmt(SourceLocation DL, SourceLocation CL, Stmt *substmt) :
SwitchCase(DefaultStmtClass, DL, CL), SubStmt(substmt) {}
/// \brief Build an empty default statement.
explicit DefaultStmt(EmptyShell Empty)
- : SwitchCase(DefaultStmtClass, Empty) { }
+ : SwitchCase(DefaultStmtClass, Empty) {}
Stmt *getSubStmt() { return SubStmt; }
const Stmt *getSubStmt() const { return SubStmt; }
@@ -809,7 +836,6 @@ inline SourceLocation SwitchCase::getLocEnd() const {
/// LabelStmt - Represents a label, which has a substatement. For example:
/// foo: return;
-///
class LabelStmt : public Stmt {
SourceLocation IdentLoc;
LabelDecl *TheDecl;
@@ -824,7 +850,7 @@ public:
}
// \brief Build an empty label statement.
- explicit LabelStmt(EmptyShell Empty) : Stmt(LabelStmtClass, Empty) { }
+ explicit LabelStmt(EmptyShell Empty) : Stmt(LabelStmtClass, Empty) {}
SourceLocation getIdentLoc() const { return IdentLoc; }
LabelDecl *getDecl() const { return TheDecl; }
@@ -845,19 +871,17 @@ public:
}
};
-
/// \brief Represents an attribute applied to a statement.
///
/// Represents an attribute applied to a statement. For example:
/// [[omp::for(...)]] for (...) { ... }
-///
class AttributedStmt : public Stmt {
+ friend class ASTStmtReader;
+
Stmt *SubStmt;
SourceLocation AttrLoc;
unsigned NumAttrs;
- friend class ASTStmtReader;
-
AttributedStmt(SourceLocation Loc, ArrayRef<const Attr*> Attrs, Stmt *SubStmt)
: Stmt(AttributedStmtClass), SubStmt(SubStmt), AttrLoc(Loc),
NumAttrs(Attrs.size()) {
@@ -879,6 +903,7 @@ class AttributedStmt : public Stmt {
public:
static AttributedStmt *Create(const ASTContext &C, SourceLocation Loc,
ArrayRef<const Attr*> Attrs, Stmt *SubStmt);
+
// \brief Build an empty attributed statement.
static AttributedStmt *CreateEmpty(const ASTContext &C, unsigned NumAttrs);
@@ -886,6 +911,7 @@ public:
ArrayRef<const Attr*> getAttrs() const {
return llvm::makeArrayRef(getAttrArrayPtr(), NumAttrs);
}
+
Stmt *getSubStmt() { return SubStmt; }
const Stmt *getSubStmt() const { return SubStmt; }
@@ -899,9 +925,7 @@ public:
}
};
-
/// IfStmt - This represents an if/then/else.
-///
class IfStmt : public Stmt {
enum { INIT, VAR, COND, THEN, ELSE, END_EXPR };
Stmt* SubExprs[END_EXPR];
@@ -916,7 +940,7 @@ public:
Stmt *elsev = nullptr);
/// \brief Build an empty if/then/else statement
- explicit IfStmt(EmptyShell Empty) : Stmt(IfStmtClass, Empty) { }
+ explicit IfStmt(EmptyShell Empty) : Stmt(IfStmtClass, Empty) {}
/// \brief Retrieve the variable declared in this "if" statement, if any.
///
@@ -960,6 +984,7 @@ public:
bool isObjCAvailabilityCheck() const;
SourceLocation getLocStart() const LLVM_READONLY { return IfLoc; }
+
SourceLocation getLocEnd() const LLVM_READONLY {
if (SubExprs[ELSE])
return SubExprs[ELSE]->getLocEnd();
@@ -979,11 +1004,11 @@ public:
};
/// SwitchStmt - This represents a 'switch' stmt.
-///
class SwitchStmt : public Stmt {
SourceLocation SwitchLoc;
enum { INIT, VAR, COND, BODY, END_EXPR };
Stmt* SubExprs[END_EXPR];
+
// 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
@@ -994,7 +1019,7 @@ public:
SwitchStmt(const ASTContext &C, Stmt *Init, VarDecl *Var, Expr *cond);
/// \brief Build a empty switch statement.
- explicit SwitchStmt(EmptyShell Empty) : Stmt(SwitchStmtClass, Empty) { }
+ explicit SwitchStmt(EmptyShell Empty) : Stmt(SwitchStmtClass, Empty) {}
/// \brief Retrieve the variable declared in this "switch" statement, if any.
///
@@ -1037,6 +1062,7 @@ public:
SubExprs[BODY] = S;
SwitchLoc = SL;
}
+
void addSwitchCase(SwitchCase *SC) {
assert(!SC->getNextSwitchCase()
&& "case/default already added to a switch");
@@ -1053,6 +1079,7 @@ public:
bool isAllEnumCasesCovered() const { return FirstCase.getInt(); }
SourceLocation getLocStart() const LLVM_READONLY { return SwitchLoc; }
+
SourceLocation getLocEnd() const LLVM_READONLY {
return SubExprs[BODY] ? SubExprs[BODY]->getLocEnd() : SubExprs[COND]->getLocEnd();
}
@@ -1067,19 +1094,18 @@ public:
}
};
-
/// WhileStmt - This represents a 'while' stmt.
-///
class WhileStmt : public Stmt {
SourceLocation WhileLoc;
enum { VAR, COND, BODY, END_EXPR };
Stmt* SubExprs[END_EXPR];
+
public:
WhileStmt(const ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body,
SourceLocation WL);
/// \brief Build an empty while statement.
- explicit WhileStmt(EmptyShell Empty) : Stmt(WhileStmtClass, Empty) { }
+ explicit WhileStmt(EmptyShell Empty) : Stmt(WhileStmtClass, Empty) {}
/// \brief Retrieve the variable declared in this "while" statement, if any.
///
@@ -1109,6 +1135,7 @@ public:
void setWhileLoc(SourceLocation L) { WhileLoc = L; }
SourceLocation getLocStart() const LLVM_READONLY { return WhileLoc; }
+
SourceLocation getLocEnd() const LLVM_READONLY {
return SubExprs[BODY]->getLocEnd();
}
@@ -1124,7 +1151,6 @@ public:
};
/// DoStmt - This represents a 'do/while' stmt.
-///
class DoStmt : public Stmt {
SourceLocation DoLoc;
enum { BODY, COND, END_EXPR };
@@ -1141,7 +1167,7 @@ public:
}
/// \brief Build an empty do-while statement.
- explicit DoStmt(EmptyShell Empty) : Stmt(DoStmtClass, Empty) { }
+ 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]);}
@@ -1171,11 +1197,9 @@ public:
}
};
-
/// ForStmt - This represents a 'for (init;cond;inc)' stmt. Note that any of
/// 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 };
@@ -1188,7 +1212,7 @@ public:
SourceLocation RP);
/// \brief Build an empty for statement.
- explicit ForStmt(EmptyShell Empty) : Stmt(ForStmtClass, Empty) { }
+ explicit ForStmt(EmptyShell Empty) : Stmt(ForStmtClass, Empty) {}
Stmt *getInit() { return SubExprs[INIT]; }
@@ -1231,6 +1255,7 @@ public:
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
SourceLocation getLocStart() const LLVM_READONLY { return ForLoc; }
+
SourceLocation getLocEnd() const LLVM_READONLY {
return SubExprs[BODY]->getLocEnd();
}
@@ -1246,17 +1271,17 @@ 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), GotoLoc(GL), LabelLoc(LL) {}
/// \brief Build an empty goto statement.
- explicit GotoStmt(EmptyShell Empty) : Stmt(GotoStmtClass, Empty) { }
+ explicit GotoStmt(EmptyShell Empty) : Stmt(GotoStmtClass, Empty) {}
LabelDecl *getLabel() const { return Label; }
void setLabel(LabelDecl *D) { Label = D; }
@@ -1280,11 +1305,11 @@ 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)
@@ -1293,7 +1318,7 @@ public:
/// \brief Build an empty indirect goto statement.
explicit IndirectGotoStmt(EmptyShell Empty)
- : Stmt(IndirectGotoStmtClass, Empty) { }
+ : Stmt(IndirectGotoStmtClass, Empty) {}
void setGotoLoc(SourceLocation L) { GotoLoc = L; }
SourceLocation getGotoLoc() const { return GotoLoc; }
@@ -1322,16 +1347,15 @@ public:
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) {}
/// \brief Build an empty continue statement.
- explicit ContinueStmt(EmptyShell Empty) : Stmt(ContinueStmtClass, Empty) { }
+ explicit ContinueStmt(EmptyShell Empty) : Stmt(ContinueStmtClass, Empty) {}
SourceLocation getContinueLoc() const { return ContinueLoc; }
void setContinueLoc(SourceLocation L) { ContinueLoc = L; }
@@ -1350,7 +1374,6 @@ public:
};
/// BreakStmt - This represents a break.
-///
class BreakStmt : public Stmt {
SourceLocation BreakLoc;
@@ -1361,7 +1384,7 @@ public:
}
/// \brief Build an empty break statement.
- explicit BreakStmt(EmptyShell Empty) : Stmt(BreakStmtClass, Empty) { }
+ explicit BreakStmt(EmptyShell Empty) : Stmt(BreakStmtClass, Empty) {}
SourceLocation getBreakLoc() const { return BreakLoc; }
void setBreakLoc(SourceLocation L) { BreakLoc = L; }
@@ -1379,7 +1402,6 @@ public:
}
};
-
/// ReturnStmt - This represents a return, optionally of an expression:
/// return;
/// return 4;
@@ -1388,7 +1410,6 @@ 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;
Stmt *RetExpr;
@@ -1402,7 +1423,7 @@ public:
NRVOCandidate(NRVOCandidate) {}
/// \brief Build an empty return expression.
- explicit ReturnStmt(EmptyShell Empty) : Stmt(ReturnStmtClass, Empty) { }
+ explicit ReturnStmt(EmptyShell Empty) : Stmt(ReturnStmtClass, Empty) {}
const Expr *getRetValue() const;
Expr *getRetValue();
@@ -1420,6 +1441,7 @@ public:
void setNRVOCandidate(const VarDecl *Var) { NRVOCandidate = Var; }
SourceLocation getLocStart() const LLVM_READONLY { return RetLoc; }
+
SourceLocation getLocEnd() const LLVM_READONLY {
return RetExpr ? RetExpr->getLocEnd() : RetLoc;
}
@@ -1436,10 +1458,12 @@ public:
};
/// AsmStmt is the base class for GCCAsmStmt and MSAsmStmt.
-///
class AsmStmt : public Stmt {
protected:
+ friend class ASTStmtReader;
+
SourceLocation AsmLoc;
+
/// \brief True if the assembly statement does not have any input or output
/// operands.
bool IsSimple;
@@ -1452,19 +1476,17 @@ protected:
unsigned NumInputs;
unsigned NumClobbers;
- Stmt **Exprs;
+ Stmt **Exprs = nullptr;
AsmStmt(StmtClass SC, SourceLocation asmloc, bool issimple, bool isvolatile,
- unsigned numoutputs, unsigned numinputs, unsigned numclobbers) :
- Stmt (SC), AsmLoc(asmloc), IsSimple(issimple), IsVolatile(isvolatile),
- NumOutputs(numoutputs), NumInputs(numinputs), NumClobbers(numclobbers) { }
-
- friend class ASTStmtReader;
+ unsigned numoutputs, unsigned numinputs, unsigned numclobbers)
+ : Stmt (SC), AsmLoc(asmloc), IsSimple(issimple), IsVolatile(isvolatile),
+ NumOutputs(numoutputs), NumInputs(numinputs),
+ NumClobbers(numclobbers) {}
public:
/// \brief Build an empty inline-assembly statement.
- explicit AsmStmt(StmtClass SC, EmptyShell Empty) :
- Stmt(SC, Empty), Exprs(nullptr) { }
+ explicit AsmStmt(StmtClass SC, EmptyShell Empty) : Stmt(SC, Empty) {}
SourceLocation getAsmLoc() const { return AsmLoc; }
void setAsmLoc(SourceLocation L) { AsmLoc = L; }
@@ -1527,10 +1549,10 @@ public:
// Input expr iterators.
- typedef ExprIterator inputs_iterator;
- typedef ConstExprIterator const_inputs_iterator;
- typedef llvm::iterator_range<inputs_iterator> inputs_range;
- typedef llvm::iterator_range<const_inputs_iterator> inputs_const_range;
+ using inputs_iterator = ExprIterator;
+ using const_inputs_iterator = ConstExprIterator;
+ using inputs_range = llvm::iterator_range<inputs_iterator>;
+ using inputs_const_range = llvm::iterator_range<const_inputs_iterator>;
inputs_iterator begin_inputs() {
return &Exprs[0] + NumOutputs;
@@ -1556,17 +1578,19 @@ public:
// Output expr iterators.
- typedef ExprIterator outputs_iterator;
- typedef ConstExprIterator const_outputs_iterator;
- typedef llvm::iterator_range<outputs_iterator> outputs_range;
- typedef llvm::iterator_range<const_outputs_iterator> outputs_const_range;
+ using outputs_iterator = ExprIterator;
+ using const_outputs_iterator = ConstExprIterator;
+ using outputs_range = llvm::iterator_range<outputs_iterator>;
+ using outputs_const_range = llvm::iterator_range<const_outputs_iterator>;
outputs_iterator begin_outputs() {
return &Exprs[0];
}
+
outputs_iterator end_outputs() {
return &Exprs[0] + NumOutputs;
}
+
outputs_range outputs() {
return outputs_range(begin_outputs(), end_outputs());
}
@@ -1574,9 +1598,11 @@ public:
const_outputs_iterator begin_outputs() const {
return &Exprs[0];
}
+
const_outputs_iterator end_outputs() const {
return &Exprs[0] + NumOutputs;
}
+
outputs_const_range outputs() const {
return outputs_const_range(begin_outputs(), end_outputs());
}
@@ -1587,17 +1613,16 @@ public:
};
/// This represents a GCC inline-assembly statement extension.
-///
class GCCAsmStmt : public AsmStmt {
+ friend class ASTStmtReader;
+
SourceLocation RParenLoc;
StringLiteral *AsmStr;
// FIXME: If we wanted to, we could allocate all of these in one big array.
- StringLiteral **Constraints;
- StringLiteral **Clobbers;
- IdentifierInfo **Names;
-
- friend class ASTStmtReader;
+ StringLiteral **Constraints = nullptr;
+ StringLiteral **Clobbers = nullptr;
+ IdentifierInfo **Names = nullptr;
public:
GCCAsmStmt(const ASTContext &C, SourceLocation asmloc, bool issimple,
@@ -1607,8 +1632,7 @@ public:
StringLiteral **clobbers, SourceLocation rparenloc);
/// \brief Build an empty inline-assembly statement.
- explicit GCCAsmStmt(EmptyShell Empty) : AsmStmt(GCCAsmStmtClass, Empty),
- Constraints(nullptr), Clobbers(nullptr), Names(nullptr) { }
+ explicit GCCAsmStmt(EmptyShell Empty) : AsmStmt(GCCAsmStmtClass, Empty) {}
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
@@ -1628,6 +1652,7 @@ public:
String, // String in .ll asm string form, "$" -> "$$" and "%%" -> "%".
Operand // Operand reference, with optional modifier %c4.
};
+
private:
Kind MyKind;
std::string Str;
@@ -1635,13 +1660,13 @@ public:
// Source range for operand references.
CharSourceRange Range;
+
public:
AsmStringPiece(const std::string &S) : MyKind(String), Str(S) {}
AsmStringPiece(unsigned OpNo, const std::string &S, SourceLocation Begin,
SourceLocation End)
- : MyKind(Operand), Str(S), OperandNo(OpNo),
- Range(CharSourceRange::getCharRange(Begin, End)) {
- }
+ : MyKind(Operand), Str(S), OperandNo(OpNo),
+ Range(CharSourceRange::getCharRange(Begin, End)) {}
bool isString() const { return MyKind == String; }
bool isOperand() const { return MyKind == Operand; }
@@ -1742,8 +1767,8 @@ private:
unsigned NumInputs,
StringLiteral **Clobbers,
unsigned NumClobbers);
-public:
+public:
//===--- Other ---===//
/// getNamedOperand - Given a symbolic operand reference like %[foo],
@@ -1752,6 +1777,7 @@ public:
int getNamedOperand(StringRef SymbolicName) const;
StringRef getClobber(unsigned i) const;
+
StringLiteral *getClobberStringLiteral(unsigned i) { return Clobbers[i]; }
const StringLiteral *getClobberStringLiteral(unsigned i) const {
return Clobbers[i];
@@ -1766,18 +1792,17 @@ public:
};
/// This represents a Microsoft inline-assembly statement extension.
-///
class MSAsmStmt : public AsmStmt {
+ friend class ASTStmtReader;
+
SourceLocation LBraceLoc, EndLoc;
StringRef AsmStr;
- unsigned NumAsmToks;
-
- Token *AsmToks;
- StringRef *Constraints;
- StringRef *Clobbers;
+ unsigned NumAsmToks = 0;
- friend class ASTStmtReader;
+ Token *AsmToks = nullptr;
+ StringRef *Constraints = nullptr;
+ StringRef *Clobbers = nullptr;
public:
MSAsmStmt(const ASTContext &C, SourceLocation asmloc,
@@ -1788,8 +1813,7 @@ public:
ArrayRef<StringRef> clobbers, SourceLocation endloc);
/// \brief Build an empty MS-style inline-assembly statement.
- explicit MSAsmStmt(EmptyShell Empty) : AsmStmt(MSAsmStmtClass, Empty),
- NumAsmToks(0), AsmToks(nullptr), Constraints(nullptr), Clobbers(nullptr) { }
+ explicit MSAsmStmt(EmptyShell Empty) : AsmStmt(MSAsmStmtClass, Empty) {}
SourceLocation getLBraceLoc() const { return LBraceLoc; }
void setLBraceLoc(SourceLocation L) { LBraceLoc = L; }
@@ -1839,9 +1863,11 @@ public:
ArrayRef<StringRef> getAllConstraints() const {
return llvm::makeArrayRef(Constraints, NumInputs + NumOutputs);
}
+
ArrayRef<StringRef> getClobbers() const {
return llvm::makeArrayRef(Clobbers, NumClobbers);
}
+
ArrayRef<Expr*> getAllExprs() const {
return llvm::makeArrayRef(reinterpret_cast<Expr**>(Exprs),
NumInputs + NumOutputs);
@@ -1853,8 +1879,8 @@ private:
void initialize(const ASTContext &C, StringRef AsmString,
ArrayRef<Token> AsmToks, ArrayRef<StringRef> Constraints,
ArrayRef<Expr*> Exprs, ArrayRef<StringRef> Clobbers);
-public:
+public:
SourceLocation getLocStart() const LLVM_READONLY { return AsmLoc; }
SourceLocation getLocEnd() const LLVM_READONLY { return EndLoc; }
@@ -1868,18 +1894,16 @@ public:
};
class SEHExceptStmt : public Stmt {
+ friend class ASTReader;
+ friend class ASTStmtReader;
+
SourceLocation Loc;
- Stmt *Children[2];
+ Stmt *Children[2];
enum { FILTER_EXPR, BLOCK };
- SEHExceptStmt(SourceLocation Loc,
- Expr *FilterExpr,
- Stmt *Block);
-
- friend class ASTReader;
- friend class ASTStmtReader;
- explicit SEHExceptStmt(EmptyShell E) : Stmt(SEHExceptStmtClass, E) { }
+ SEHExceptStmt(SourceLocation Loc, Expr *FilterExpr, Stmt *Block);
+ explicit SEHExceptStmt(EmptyShell E) : Stmt(SEHExceptStmtClass, E) {}
public:
static SEHExceptStmt* Create(const ASTContext &C,
@@ -1908,19 +1932,17 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == SEHExceptStmtClass;
}
-
};
class SEHFinallyStmt : public Stmt {
- SourceLocation Loc;
- Stmt *Block;
-
- SEHFinallyStmt(SourceLocation Loc,
- Stmt *Block);
-
friend class ASTReader;
friend class ASTStmtReader;
- explicit SEHFinallyStmt(EmptyShell E) : Stmt(SEHFinallyStmtClass, E) { }
+
+ SourceLocation Loc;
+ Stmt *Block;
+
+ SEHFinallyStmt(SourceLocation Loc, Stmt *Block);
+ explicit SEHFinallyStmt(EmptyShell E) : Stmt(SEHFinallyStmtClass, E) {}
public:
static SEHFinallyStmt* Create(const ASTContext &C,
@@ -1942,13 +1964,15 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == SEHFinallyStmtClass;
}
-
};
class SEHTryStmt : public Stmt {
- bool IsCXXTry;
+ friend class ASTReader;
+ friend class ASTStmtReader;
+
+ bool IsCXXTry;
SourceLocation TryLoc;
- Stmt *Children[2];
+ Stmt *Children[2];
enum { TRY = 0, HANDLER = 1 };
@@ -1957,9 +1981,7 @@ class SEHTryStmt : public Stmt {
Stmt *TryBlock,
Stmt *Handler);
- friend class ASTReader;
- friend class ASTStmtReader;
- explicit SEHTryStmt(EmptyShell E) : Stmt(SEHTryStmtClass, E) { }
+ explicit SEHTryStmt(EmptyShell E) : Stmt(SEHTryStmtClass, E) {}
public:
static SEHTryStmt* Create(const ASTContext &C, bool isCXXTry,
@@ -1994,15 +2016,15 @@ public:
};
/// Represents a __leave statement.
-///
class SEHLeaveStmt : public Stmt {
SourceLocation LeaveLoc;
+
public:
explicit SEHLeaveStmt(SourceLocation LL)
: Stmt(SEHLeaveStmtClass), LeaveLoc(LL) {}
/// \brief Build an empty __leave statement.
- explicit SEHLeaveStmt(EmptyShell Empty) : Stmt(SEHLeaveStmtClass, Empty) { }
+ explicit SEHLeaveStmt(EmptyShell Empty) : Stmt(SEHLeaveStmtClass, Empty) {}
SourceLocation getLeaveLoc() const { return LeaveLoc; }
void setLeaveLoc(SourceLocation L) { LeaveLoc = L; }
@@ -2047,6 +2069,8 @@ public:
SourceLocation Loc;
public:
+ friend class ASTStmtReader;
+
/// \brief Create a new capture.
///
/// \param Loc The source location associated with this capture.
@@ -2054,7 +2078,6 @@ public:
/// \param Kind The kind of capture (this, ByRef, ...).
///
/// \param Var The variable being captured, or null if capturing this.
- ///
Capture(SourceLocation Loc, VariableCaptureKind Kind,
VarDecl *Var = nullptr);
@@ -2086,8 +2109,6 @@ public:
///
/// This operation is only valid if this capture captures a variable.
VarDecl *getCapturedVar() const;
-
- friend class ASTStmtReader;
};
private:
@@ -2099,7 +2120,7 @@ private:
llvm::PointerIntPair<CapturedDecl *, 1, CapturedRegionKind> CapDeclAndKind;
/// \brief The record for captured variables, a RecordDecl or CXXRecordDecl.
- RecordDecl *TheRecordDecl;
+ RecordDecl *TheRecordDecl = nullptr;
/// \brief Construct a captured statement.
CapturedStmt(Stmt *S, CapturedRegionKind Kind, ArrayRef<Capture> Captures,
@@ -2119,6 +2140,8 @@ private:
void setCapturedStmt(Stmt *S) { getStoredStmts()[NumCaptures] = S; }
public:
+ friend class ASTStmtReader;
+
static CapturedStmt *Create(const ASTContext &Context, Stmt *S,
CapturedRegionKind Kind,
ArrayRef<Capture> Captures,
@@ -2158,10 +2181,10 @@ public:
bool capturesVariable(const VarDecl *Var) const;
/// \brief An iterator that walks over the captures.
- typedef Capture *capture_iterator;
- typedef const Capture *const_capture_iterator;
- typedef llvm::iterator_range<capture_iterator> capture_range;
- typedef llvm::iterator_range<const_capture_iterator> capture_const_range;
+ using capture_iterator = Capture *;
+ using const_capture_iterator = const Capture *;
+ using capture_range = llvm::iterator_range<capture_iterator>;
+ using capture_const_range = llvm::iterator_range<const_capture_iterator>;
capture_range captures() {
return capture_range(capture_begin(), capture_end());
@@ -2184,14 +2207,14 @@ public:
unsigned capture_size() const { return NumCaptures; }
/// \brief Iterator that walks over the capture initialization arguments.
- typedef Expr **capture_init_iterator;
- typedef llvm::iterator_range<capture_init_iterator> capture_init_range;
+ using capture_init_iterator = Expr **;
+ using capture_init_range = llvm::iterator_range<capture_init_iterator>;
/// \brief Const iterator that walks over the capture initialization
/// arguments.
- typedef Expr *const *const_capture_init_iterator;
- typedef llvm::iterator_range<const_capture_init_iterator>
- const_capture_init_range;
+ using const_capture_init_iterator = Expr *const *;
+ using const_capture_init_range =
+ llvm::iterator_range<const_capture_init_iterator>;
capture_init_range capture_inits() {
return capture_init_range(capture_init_begin(), capture_init_end());
@@ -2223,9 +2246,11 @@ public:
SourceLocation getLocStart() const LLVM_READONLY {
return getCapturedStmt()->getLocStart();
}
+
SourceLocation getLocEnd() const LLVM_READONLY {
return getCapturedStmt()->getLocEnd();
}
+
SourceRange getSourceRange() const LLVM_READONLY {
return getCapturedStmt()->getSourceRange();
}
@@ -2235,10 +2260,8 @@ public:
}
child_range children();
-
- friend class ASTStmtReader;
};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_AST_STMT_H
diff --git a/include/clang/AST/StmtDataCollectors.td b/include/clang/AST/StmtDataCollectors.td
new file mode 100644
index 000000000000..bf5f8c21707f
--- /dev/null
+++ b/include/clang/AST/StmtDataCollectors.td
@@ -0,0 +1,242 @@
+class Stmt {
+ code Code = [{
+ 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));
+ }];
+}
+
+class Expr {
+ code Code = [{
+ addData(S->getType());
+ }];
+}
+
+//--- Builtin functionality ----------------------------------------------//
+class ArrayTypeTraitExpr {
+ code Code = [{
+ addData(S->getTrait());
+ }];
+}
+class ExpressionTraitExpr {
+ code Code = [{
+ addData(S->getTrait());
+ }];
+}
+class PredefinedExpr {
+ code Code = [{
+ addData(S->getIdentType());
+ }];
+}
+class TypeTraitExpr {
+ code Code = [{
+ addData(S->getTrait());
+ for (unsigned i = 0; i < S->getNumArgs(); ++i)
+ addData(S->getArg(i)->getType());
+ }];
+}
+
+//--- Calls --------------------------------------------------------------//
+class CallExpr {
+ code Code = [{
+ // Function pointers don't have a callee and we just skip hashing it.
+ if (const FunctionDecl *D = S->getDirectCallee()) {
+ // If the function is a template specialization, we also need to handle
+ // the template arguments as they are not included in the qualified name.
+ if (auto Args = D->getTemplateSpecializationArgs()) {
+ std::string ArgString;
+
+ // Print all template arguments into ArgString
+ llvm::raw_string_ostream OS(ArgString);
+ for (unsigned i = 0; i < Args->size(); ++i) {
+ Args->get(i).print(Context.getLangOpts(), OS);
+ // Add a padding character so that 'foo<X, XX>()' != 'foo<XX, X>()'.
+ OS << '\n';
+ }
+ OS.flush();
+
+ addData(ArgString);
+ }
+ addData(D->getQualifiedNameAsString());
+ }
+ }];
+}
+
+//--- Value references ---------------------------------------------------//
+class DeclRefExpr {
+ code Code = [{
+ addData(S->getDecl()->getQualifiedNameAsString());
+ }];
+}
+class MemberExpr {
+ code Code = [{
+ addData(S->getMemberDecl()->getName());
+ }];
+}
+
+//--- Literals -----------------------------------------------------------//
+class IntegerLiteral {
+ code Code = [{
+ addData(llvm::hash_value(S->getValue()));
+ }];
+}
+class FloatingLiteral {
+ code Code = [{
+ addData(llvm::hash_value(S->getValue()));
+ }];
+}
+class StringLiteral {
+ code Code = [{
+ addData(S->getString());
+}];
+}
+class CXXBoolLiteralExpr {
+ code Code = [{
+ addData(S->getValue());
+ }];
+}
+class CharacterLiteral {
+ code Code = [{
+ addData(S->getValue());
+ }];
+}
+
+//--- Exceptions ---------------------------------------------------------//
+class CXXCatchStmt {
+ code Code = [{
+ addData(S->getCaughtType());
+ }];
+}
+
+//--- C++ OOP Stmts ------------------------------------------------------//
+class CXXDeleteExpr {
+ code Code = [{
+ addData(S->isArrayFormAsWritten()); addData(S->isGlobalDelete());
+ }];
+}
+
+//--- Casts --------------------------------------------------------------//
+class ObjCBridgedCastExpr {
+ code Code = [{
+ addData(S->getBridgeKind());
+ }];
+}
+
+//--- Miscellaneous Exprs ------------------------------------------------//
+class BinaryOperator {
+ code Code = [{
+ addData(S->getOpcode());
+ }];
+}
+class UnaryOperator {
+ code Code = [{
+ addData(S->getOpcode());
+ }];
+}
+
+//--- Control flow -------------------------------------------------------//
+class GotoStmt {
+ code Code = [{
+ addData(S->getLabel()->getName());
+ }];
+}
+class IndirectGotoStmt {
+ code Code = [{
+ if (S->getConstantTarget())
+ addData(S->getConstantTarget()->getName());
+ }];
+}
+class LabelStmt {
+ code Code = [{
+ addData(S->getDecl()->getName());
+ }];
+}
+class MSDependentExistsStmt {
+ code Code = [{
+ addData(S->isIfExists());
+ }];
+}
+class AddrLabelExpr {
+ code Code = [{
+ addData(S->getLabel()->getName());
+ }];
+}
+
+//--- Objective-C --------------------------------------------------------//
+class ObjCIndirectCopyRestoreExpr {
+ code Code = [{
+ addData(S->shouldCopy());
+ }];
+}
+class ObjCPropertyRefExpr {
+ code Code = [{
+ addData(S->isSuperReceiver()); addData(S->isImplicitProperty());
+ }];
+}
+class ObjCAtCatchStmt {
+ code Code = [{
+ addData(S->hasEllipsis());
+ }];
+}
+
+//--- Miscellaneous Stmts ------------------------------------------------//
+class CXXFoldExpr {
+ code Code = [{
+ addData(S->isRightFold()); addData(S->getOperator());
+ }];
+}
+class GenericSelectionExpr {
+ code Code = [{
+ for (unsigned i = 0; i < S->getNumAssocs(); ++i) {
+ addData(S->getAssocType(i));
+ }
+ }];
+}
+class LambdaExpr {
+ code Code = [{
+ for (const LambdaCapture &C : S->captures()) {
+ addData(C.isPackExpansion());
+ addData(C.getCaptureKind());
+ if (C.capturesVariable())
+ addData(C.getCapturedVar()->getType());
+ }
+ addData(S->isGenericLambda());
+ addData(S->isMutable());
+ }];
+}
+class DeclStmt {
+ code Code = [{
+ auto numDecls = std::distance(S->decl_begin(), S->decl_end());
+ addData(static_cast<unsigned>(numDecls));
+ for (const Decl *D : S->decls()) {
+ if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+ addData(VD->getType());
+ }
+ }
+ }];
+}
+class AsmStmt {
+ code Code = [{
+ addData(S->isSimple());
+ addData(S->isVolatile());
+ addData(S->generateAsmString(Context));
+ for (unsigned i = 0; i < S->getNumInputs(); ++i) {
+ addData(S->getInputConstraint(i));
+ }
+ for (unsigned i = 0; i < S->getNumOutputs(); ++i) {
+ addData(S->getOutputConstraint(i));
+ }
+ for (unsigned i = 0; i < S->getNumClobbers(); ++i) {
+ addData(S->getClobber(i));
+ }
+ }];
+}
+class AttributedStmt {
+ code Code = [{
+ for (const Attr *A : S->getAttrs()) {
+ addData(std::string(A->getSpelling()));
+ }
+ }];
+}
diff --git a/include/clang/AST/StmtGraphTraits.h b/include/clang/AST/StmtGraphTraits.h
index 92eb64430f73..02c77b242c7c 100644
--- a/include/clang/AST/StmtGraphTraits.h
+++ b/include/clang/AST/StmtGraphTraits.h
@@ -1,4 +1,4 @@
-//===--- StmtGraphTraits.h - Graph Traits for the class Stmt ----*- C++ -*-===//
+//===- StmtGraphTraits.h - Graph Traits for the class Stmt ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -21,13 +21,10 @@
namespace llvm {
-//template <typename T> struct GraphTraits;
-
-
-template <> struct GraphTraits<clang::Stmt*> {
- typedef clang::Stmt * NodeRef;
- typedef clang::Stmt::child_iterator ChildIteratorType;
- typedef llvm::df_iterator<clang::Stmt*> nodes_iterator;
+template <> struct GraphTraits<clang::Stmt *> {
+ using NodeRef = clang::Stmt *;
+ using ChildIteratorType = clang::Stmt::child_iterator;
+ using nodes_iterator = llvm::df_iterator<clang::Stmt *>;
static NodeRef getEntryNode(clang::Stmt *S) { return S; }
@@ -50,11 +47,10 @@ template <> struct GraphTraits<clang::Stmt*> {
}
};
-
-template <> struct GraphTraits<const clang::Stmt*> {
- typedef const clang::Stmt * NodeRef;
- typedef clang::Stmt::const_child_iterator ChildIteratorType;
- typedef llvm::df_iterator<const clang::Stmt*> nodes_iterator;
+template <> struct GraphTraits<const clang::Stmt *> {
+ using NodeRef = const clang::Stmt *;
+ using ChildIteratorType = clang::Stmt::const_child_iterator;
+ using nodes_iterator = llvm::df_iterator<const clang::Stmt *>;
static NodeRef getEntryNode(const clang::Stmt *S) { return S; }
@@ -77,7 +73,6 @@ template <> struct GraphTraits<const clang::Stmt*> {
}
};
+} // namespace llvm
-} // end namespace llvm
-
-#endif
+#endif // LLVM_CLANG_AST_STMTGRAPHTRAITS_H
diff --git a/include/clang/AST/StmtIterator.h b/include/clang/AST/StmtIterator.h
index 5d3bce8d83ba..33aab08bbb71 100644
--- a/include/clang/AST/StmtIterator.h
+++ b/include/clang/AST/StmtIterator.h
@@ -1,4 +1,4 @@
-//===--- StmtIterator.h - Iterators for Statements --------------*- C++ -*-===//
+//===- StmtIterator.h - Iterators for Statements ----------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,31 +14,38 @@
#ifndef LLVM_CLANG_AST_STMTITERATOR_H
#define LLVM_CLANG_AST_STMTITERATOR_H
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/DataTypes.h"
#include <cassert>
#include <cstddef>
+#include <cstdint>
#include <iterator>
-#include <utility>
namespace clang {
-class Stmt;
class Decl;
+class Stmt;
class VariableArrayType;
class StmtIteratorBase {
protected:
- enum { StmtMode = 0x0, SizeOfTypeVAMode = 0x1, DeclGroupMode = 0x2,
- Flags = 0x3 };
+ enum {
+ StmtMode = 0x0,
+ SizeOfTypeVAMode = 0x1,
+ DeclGroupMode = 0x2,
+ Flags = 0x3
+ };
union {
Stmt **stmt;
Decl **DGI;
};
- uintptr_t RawVAPtr;
+ uintptr_t RawVAPtr = 0;
Decl **DGE;
+ StmtIteratorBase(Stmt **s) : stmt(s) {}
+ StmtIteratorBase(const VariableArrayType *t);
+ StmtIteratorBase(Decl **dgi, Decl **dge);
+ StmtIteratorBase() : stmt(nullptr) {}
+
bool inDeclGroup() const {
return (RawVAPtr & Flags) == DeclGroupMode;
}
@@ -56,7 +63,7 @@ protected:
}
void setVAPtr(const VariableArrayType *P) {
- assert (inDeclGroup() || inSizeOfTypeVA());
+ assert(inDeclGroup() || inSizeOfTypeVA());
RawVAPtr = reinterpret_cast<uintptr_t>(P) | (RawVAPtr & Flags);
}
@@ -65,14 +72,8 @@ protected:
void NextVA();
Stmt*& GetDeclExpr() const;
-
- StmtIteratorBase(Stmt **s) : stmt(s), RawVAPtr(0) {}
- StmtIteratorBase(const VariableArrayType *t);
- StmtIteratorBase(Decl **dgi, Decl **dge);
- StmtIteratorBase() : stmt(nullptr), RawVAPtr(0) {}
};
-
template <typename DERIVED, typename REFERENCE>
class StmtIteratorImpl : public StmtIteratorBase,
public std::iterator<std::forward_iterator_tag,
@@ -80,8 +81,9 @@ class StmtIteratorImpl : public StmtIteratorBase,
REFERENCE, REFERENCE> {
protected:
StmtIteratorImpl(const StmtIteratorBase& RHS) : StmtIteratorBase(RHS) {}
+
public:
- StmtIteratorImpl() {}
+ StmtIteratorImpl() = default;
StmtIteratorImpl(Stmt **s) : StmtIteratorBase(s) {}
StmtIteratorImpl(Decl **dgi, Decl **dge) : StmtIteratorBase(dgi, dge) {}
StmtIteratorImpl(const VariableArrayType *t) : StmtIteratorBase(t) {}
@@ -120,16 +122,13 @@ public:
struct ConstStmtIterator;
-struct StmtIterator : public StmtIteratorImpl<StmtIterator,Stmt*&> {
- explicit StmtIterator() : StmtIteratorImpl<StmtIterator,Stmt*&>() {}
-
- StmtIterator(Stmt** S) : StmtIteratorImpl<StmtIterator,Stmt*&>(S) {}
-
+struct StmtIterator : public StmtIteratorImpl<StmtIterator, Stmt*&> {
+ explicit StmtIterator() = default;
+ StmtIterator(Stmt** S) : StmtIteratorImpl<StmtIterator, Stmt*&>(S) {}
StmtIterator(Decl** dgi, Decl** dge)
- : StmtIteratorImpl<StmtIterator,Stmt*&>(dgi, dge) {}
-
+ : StmtIteratorImpl<StmtIterator, Stmt*&>(dgi, dge) {}
StmtIterator(const VariableArrayType *t)
- : StmtIteratorImpl<StmtIterator,Stmt*&>(t) {}
+ : StmtIteratorImpl<StmtIterator, Stmt*&>(t) {}
private:
StmtIterator(const StmtIteratorBase &RHS)
@@ -141,11 +140,9 @@ private:
struct ConstStmtIterator : public StmtIteratorImpl<ConstStmtIterator,
const Stmt*> {
- explicit ConstStmtIterator() :
- StmtIteratorImpl<ConstStmtIterator,const Stmt*>() {}
-
- ConstStmtIterator(const StmtIterator& RHS) :
- StmtIteratorImpl<ConstStmtIterator,const Stmt*>(RHS) {}
+ explicit ConstStmtIterator() = default;
+ ConstStmtIterator(const StmtIterator& RHS)
+ : StmtIteratorImpl<ConstStmtIterator, const Stmt*>(RHS) {}
ConstStmtIterator(Stmt * const *S)
: StmtIteratorImpl<ConstStmtIterator, const Stmt *>(
@@ -155,6 +152,7 @@ struct ConstStmtIterator : public StmtIteratorImpl<ConstStmtIterator,
inline StmtIterator cast_away_const(const ConstStmtIterator &RHS) {
return RHS;
}
-} // end namespace clang
-#endif
+} // namespace clang
+
+#endif // LLVM_CLANG_AST_STMTITERATOR_H
diff --git a/include/clang/AST/StmtOpenMP.h b/include/clang/AST/StmtOpenMP.h
index 09dd87fdc8bc..66fb037fc33c 100644
--- a/include/clang/AST/StmtOpenMP.h
+++ b/include/clang/AST/StmtOpenMP.h
@@ -899,7 +899,9 @@ public:
}
const Stmt *getBody() const {
// This relies on the loop form is already checked by Sema.
- Stmt *Body = getAssociatedStmt()->IgnoreContainers(true);
+ const Stmt *Body = getAssociatedStmt()->IgnoreContainers(true);
+ while(const auto *CS = dyn_cast<CapturedStmt>(Body))
+ Body = CS->getCapturedStmt();
Body = cast<ForStmt>(Body)->getBody();
for (unsigned Cnt = 1; Cnt < CollapsedNum; ++Cnt) {
Body = Body->IgnoreContainers();
@@ -955,8 +957,15 @@ public:
T->getStmtClass() == OMPTargetSimdDirectiveClass ||
T->getStmtClass() == OMPTeamsDistributeDirectiveClass ||
T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass ||
- T->getStmtClass() == OMPTeamsDistributeParallelForSimdDirectiveClass ||
- T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass;
+ T->getStmtClass() ==
+ OMPTeamsDistributeParallelForSimdDirectiveClass ||
+ T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass ||
+ T->getStmtClass() ==
+ OMPTargetTeamsDistributeParallelForDirectiveClass ||
+ T->getStmtClass() ==
+ OMPTargetTeamsDistributeParallelForSimdDirectiveClass ||
+ T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass ||
+ T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass;
}
};
@@ -1912,7 +1921,7 @@ class OMPTaskgroupDirective : public OMPExecutableDirective {
OMPTaskgroupDirective(SourceLocation StartLoc, SourceLocation EndLoc,
unsigned NumClauses)
: OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
- StartLoc, EndLoc, NumClauses, 1) {}
+ StartLoc, EndLoc, NumClauses, 2) {}
/// Build an empty directive.
/// \param NumClauses Number of clauses.
@@ -1920,7 +1929,12 @@ class OMPTaskgroupDirective : public OMPExecutableDirective {
explicit OMPTaskgroupDirective(unsigned NumClauses)
: OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
SourceLocation(), SourceLocation(), NumClauses,
- 1) {}
+ 2) {}
+
+ /// Sets the task_reduction return variable.
+ void setReductionRef(Expr *RR) {
+ *std::next(child_begin(), 1) = RR;
+ }
public:
/// Creates directive.
@@ -1930,10 +1944,12 @@ public:
/// \param EndLoc Ending Location of the directive.
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
+ /// \param ReductionRef Reference to the task_reduction return variable.
///
static OMPTaskgroupDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
+ Expr *ReductionRef);
/// Creates an empty directive.
///
@@ -1943,6 +1959,15 @@ public:
static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C,
unsigned NumClauses, EmptyShell);
+
+ /// Returns reference to the task_reduction return variable.
+ const Expr *getReductionRef() const {
+ return static_cast<const Expr *>(*std::next(child_begin(), 1));
+ }
+ Expr *getReductionRef() {
+ return static_cast<Expr *>(*std::next(child_begin(), 1));
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPTaskgroupDirectiveClass;
}
@@ -2330,7 +2355,7 @@ class OMPTargetEnterDataDirective : public OMPExecutableDirective {
unsigned NumClauses)
: OMPExecutableDirective(this, OMPTargetEnterDataDirectiveClass,
OMPD_target_enter_data, StartLoc, EndLoc,
- NumClauses, /*NumChildren=*/0) {}
+ NumClauses, /*NumChildren=*/1) {}
/// \brief Build an empty directive.
///
@@ -2340,7 +2365,7 @@ class OMPTargetEnterDataDirective : public OMPExecutableDirective {
: OMPExecutableDirective(this, OMPTargetEnterDataDirectiveClass,
OMPD_target_enter_data, SourceLocation(),
SourceLocation(), NumClauses,
- /*NumChildren=*/0) {}
+ /*NumChildren=*/1) {}
public:
/// \brief Creates directive with a list of \a Clauses.
@@ -2349,11 +2374,11 @@ public:
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending Location of the directive.
/// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
///
- static OMPTargetEnterDataDirective *Create(const ASTContext &C,
- SourceLocation StartLoc,
- SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses);
+ static OMPTargetEnterDataDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
/// \brief Creates an empty directive with the place for \a N clauses.
///
@@ -2389,7 +2414,7 @@ class OMPTargetExitDataDirective : public OMPExecutableDirective {
unsigned NumClauses)
: OMPExecutableDirective(this, OMPTargetExitDataDirectiveClass,
OMPD_target_exit_data, StartLoc, EndLoc,
- NumClauses, /*NumChildren=*/0) {}
+ NumClauses, /*NumChildren=*/1) {}
/// \brief Build an empty directive.
///
@@ -2399,7 +2424,7 @@ class OMPTargetExitDataDirective : public OMPExecutableDirective {
: OMPExecutableDirective(this, OMPTargetExitDataDirectiveClass,
OMPD_target_exit_data, SourceLocation(),
SourceLocation(), NumClauses,
- /*NumChildren=*/0) {}
+ /*NumChildren=*/1) {}
public:
/// \brief Creates directive with a list of \a Clauses.
@@ -2408,11 +2433,11 @@ public:
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending Location of the directive.
/// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
///
- static OMPTargetExitDataDirective *Create(const ASTContext &C,
- SourceLocation StartLoc,
- SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses);
+ static OMPTargetExitDataDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
/// \brief Creates an empty directive with the place for \a N clauses.
///
@@ -2966,7 +2991,7 @@ class OMPTargetUpdateDirective : public OMPExecutableDirective {
unsigned NumClauses)
: OMPExecutableDirective(this, OMPTargetUpdateDirectiveClass,
OMPD_target_update, StartLoc, EndLoc, NumClauses,
- 0) {}
+ 1) {}
/// \brief Build an empty directive.
///
@@ -2975,7 +3000,7 @@ class OMPTargetUpdateDirective : public OMPExecutableDirective {
explicit OMPTargetUpdateDirective(unsigned NumClauses)
: OMPExecutableDirective(this, OMPTargetUpdateDirectiveClass,
OMPD_target_update, SourceLocation(),
- SourceLocation(), NumClauses, 0) {}
+ SourceLocation(), NumClauses, 1) {}
public:
/// \brief Creates directive with a list of \a Clauses.
@@ -2984,11 +3009,11 @@ public:
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending Location of the directive.
/// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
///
- static OMPTargetUpdateDirective *Create(const ASTContext &C,
- SourceLocation StartLoc,
- SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses);
+ static OMPTargetUpdateDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
/// \brief Creates an empty directive with the place for \a NumClauses
/// clauses.
@@ -3015,6 +3040,8 @@ public:
///
class OMPDistributeParallelForDirective : public OMPLoopDirective {
friend class ASTStmtReader;
+ /// true if the construct has inner cancel directive.
+ bool HasCancel = false;
/// \brief Build directive with the given start and end location.
///
@@ -3028,7 +3055,7 @@ class OMPDistributeParallelForDirective : public OMPLoopDirective {
unsigned CollapsedNum, unsigned NumClauses)
: OMPLoopDirective(this, OMPDistributeParallelForDirectiveClass,
OMPD_distribute_parallel_for, StartLoc, EndLoc,
- CollapsedNum, NumClauses) {}
+ CollapsedNum, NumClauses), HasCancel(false) {}
/// \brief Build an empty directive.
///
@@ -3039,7 +3066,11 @@ class OMPDistributeParallelForDirective : public OMPLoopDirective {
unsigned NumClauses)
: OMPLoopDirective(this, OMPDistributeParallelForDirectiveClass,
OMPD_distribute_parallel_for, SourceLocation(),
- SourceLocation(), CollapsedNum, NumClauses) {}
+ SourceLocation(), CollapsedNum, NumClauses),
+ HasCancel(false) {}
+
+ /// Set cancel state.
+ void setHasCancel(bool Has) { HasCancel = Has; }
public:
/// \brief Creates directive with a list of \a Clauses.
@@ -3051,11 +3082,12 @@ public:
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
/// \param Exprs Helper expressions for CodeGen.
+ /// \param HasCancel true if this directive has inner cancel directive.
///
static OMPDistributeParallelForDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt, const HelperExprs &Exprs);
+ Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
/// \brief Creates an empty directive with the place
/// for \a NumClauses clauses.
@@ -3069,6 +3101,9 @@ public:
unsigned CollapsedNum,
EmptyShell);
+ /// Return true if current directive has inner cancel directive.
+ bool hasCancel() const { return HasCancel; }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPDistributeParallelForDirectiveClass;
}
@@ -3565,6 +3600,8 @@ public:
///
class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective {
friend class ASTStmtReader;
+ /// true if the construct has inner cancel directive.
+ bool HasCancel = false;
/// Build directive with the given start and end location.
///
@@ -3579,7 +3616,7 @@ class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective {
unsigned NumClauses)
: OMPLoopDirective(this, OMPTeamsDistributeParallelForDirectiveClass,
OMPD_teams_distribute_parallel_for, StartLoc, EndLoc,
- CollapsedNum, NumClauses) {}
+ CollapsedNum, NumClauses), HasCancel(false) {}
/// Build an empty directive.
///
@@ -3590,7 +3627,11 @@ class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective {
unsigned NumClauses)
: OMPLoopDirective(this, OMPTeamsDistributeParallelForDirectiveClass,
OMPD_teams_distribute_parallel_for, SourceLocation(),
- SourceLocation(), CollapsedNum, NumClauses) {}
+ SourceLocation(), CollapsedNum, NumClauses),
+ HasCancel(false) {}
+
+ /// Set cancel state.
+ void setHasCancel(bool Has) { HasCancel = Has; }
public:
/// Creates directive with a list of \a Clauses.
@@ -3602,11 +3643,12 @@ public:
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
/// \param Exprs Helper expressions for CodeGen.
+ /// \param HasCancel true if this directive has inner cancel directive.
///
static OMPTeamsDistributeParallelForDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt, const HelperExprs &Exprs);
+ Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
/// Creates an empty directive with the place for \a NumClauses clauses.
///
@@ -3618,6 +3660,9 @@ public:
CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
EmptyShell);
+ /// Return true if current directive has inner cancel directive.
+ bool hasCancel() const { return HasCancel; }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass;
}
@@ -3761,6 +3806,8 @@ public:
class OMPTargetTeamsDistributeParallelForDirective final
: public OMPLoopDirective {
friend class ASTStmtReader;
+ /// true if the construct has inner cancel directive.
+ bool HasCancel = false;
/// Build directive with the given start and end location.
///
@@ -3776,7 +3823,8 @@ class OMPTargetTeamsDistributeParallelForDirective final
: OMPLoopDirective(this,
OMPTargetTeamsDistributeParallelForDirectiveClass,
OMPD_target_teams_distribute_parallel_for, StartLoc,
- EndLoc, CollapsedNum, NumClauses) {}
+ EndLoc, CollapsedNum, NumClauses),
+ HasCancel(false) {}
/// Build an empty directive.
///
@@ -3788,7 +3836,11 @@ class OMPTargetTeamsDistributeParallelForDirective final
: OMPLoopDirective(
this, OMPTargetTeamsDistributeParallelForDirectiveClass,
OMPD_target_teams_distribute_parallel_for, SourceLocation(),
- SourceLocation(), CollapsedNum, NumClauses) {}
+ SourceLocation(), CollapsedNum, NumClauses),
+ HasCancel(false) {}
+
+ /// Set cancel state.
+ void setHasCancel(bool Has) { HasCancel = Has; }
public:
/// Creates directive with a list of \a Clauses.
@@ -3800,11 +3852,12 @@ public:
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
/// \param Exprs Helper expressions for CodeGen.
+ /// \param HasCancel true if this directive has inner cancel directive.
///
static OMPTargetTeamsDistributeParallelForDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt, const HelperExprs &Exprs);
+ Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
/// Creates an empty directive with the place for \a NumClauses clauses.
///
@@ -3816,6 +3869,9 @@ public:
CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
EmptyShell);
+ /// Return true if current directive has inner cancel directive.
+ bool hasCancel() const { return HasCancel; }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() ==
OMPTargetTeamsDistributeParallelForDirectiveClass;
diff --git a/include/clang/AST/StmtVisitor.h b/include/clang/AST/StmtVisitor.h
index df4a2d8bc3d7..98fa11327406 100644
--- a/include/clang/AST/StmtVisitor.h
+++ b/include/clang/AST/StmtVisitor.h
@@ -1,4 +1,4 @@
-//===--- StmtVisitor.h - Visitor for Stmt subclasses ------------*- C++ -*-===//
+//===- StmtVisitor.h - Visitor for Stmt subclasses --------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -17,28 +17,33 @@
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/ExprOpenMP.h"
+#include "clang/AST/Stmt.h"
#include "clang/AST/StmtCXX.h"
#include "clang/AST/StmtObjC.h"
#include "clang/AST/StmtOpenMP.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <utility>
namespace clang {
-template <typename T> struct make_ptr { typedef T *type; };
-template <typename T> struct make_const_ptr { typedef const T *type; };
+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.
-template<template <typename> class Ptr, typename ImplClass, typename RetTy=void>
+template<template <typename> class Ptr, typename ImplClass, typename RetTy=void,
+ class... ParamTys>
class StmtVisitorBase {
public:
-
#define PTR(CLASS) typename Ptr<CLASS>::type
#define DISPATCH(NAME, CLASS) \
- return static_cast<ImplClass*>(this)->Visit ## NAME(static_cast<PTR(CLASS)>(S))
-
- RetTy Visit(PTR(Stmt) S) {
+ return static_cast<ImplClass*>(this)->Visit ## NAME( \
+ static_cast<PTR(CLASS)>(S), std::forward<ParamTys>(P)...)
+ RetTy Visit(PTR(Stmt) S, ParamTys... P) {
// If we have a binary expr, dispatch to the subcode of the binop. A smart
// optimizer (e.g. LLVM) will fold this comparison into the switch stmt
// below.
@@ -60,6 +65,7 @@ public:
case BO_GE: DISPATCH(BinGE, BinaryOperator);
case BO_EQ: DISPATCH(BinEQ, BinaryOperator);
case BO_NE: DISPATCH(BinNE, BinaryOperator);
+ case BO_Cmp: DISPATCH(BinCmp, BinaryOperator);
case BO_And: DISPATCH(BinAnd, BinaryOperator);
case BO_Xor: DISPATCH(BinXor, BinaryOperator);
@@ -111,13 +117,13 @@ public:
// If the implementation chooses not to implement a certain visit method, fall
// back on VisitExpr or whatever else is the superclass.
#define STMT(CLASS, PARENT) \
- RetTy Visit ## CLASS(PTR(CLASS) S) { DISPATCH(PARENT, PARENT); }
+ RetTy Visit ## CLASS(PTR(CLASS) S, ParamTys... P) { DISPATCH(PARENT, PARENT); }
#include "clang/AST/StmtNodes.inc"
// If the implementation doesn't implement binary operator methods, fall back
// on VisitBinaryOperator.
#define BINOP_FALLBACK(NAME) \
- RetTy VisitBin ## NAME(PTR(BinaryOperator) S) { \
+ RetTy VisitBin ## NAME(PTR(BinaryOperator) S, ParamTys... P) { \
DISPATCH(BinaryOperator, BinaryOperator); \
}
BINOP_FALLBACK(PtrMemD) BINOP_FALLBACK(PtrMemI)
@@ -127,6 +133,8 @@ public:
BINOP_FALLBACK(LT) BINOP_FALLBACK(GT) BINOP_FALLBACK(LE)
BINOP_FALLBACK(GE) BINOP_FALLBACK(EQ) BINOP_FALLBACK(NE)
+ BINOP_FALLBACK(Cmp)
+
BINOP_FALLBACK(And) BINOP_FALLBACK(Xor) BINOP_FALLBACK(Or)
BINOP_FALLBACK(LAnd) BINOP_FALLBACK(LOr)
@@ -137,7 +145,7 @@ public:
// If the implementation doesn't implement compound assignment operator
// methods, fall back on VisitCompoundAssignOperator.
#define CAO_FALLBACK(NAME) \
- RetTy VisitBin ## NAME(PTR(CompoundAssignOperator) S) { \
+ RetTy VisitBin ## NAME(PTR(CompoundAssignOperator) S, ParamTys... P) { \
DISPATCH(CompoundAssignOperator, CompoundAssignOperator); \
}
CAO_FALLBACK(MulAssign) CAO_FALLBACK(DivAssign) CAO_FALLBACK(RemAssign)
@@ -149,7 +157,7 @@ public:
// If the implementation doesn't implement unary operator methods, fall back
// on VisitUnaryOperator.
#define UNARYOP_FALLBACK(NAME) \
- RetTy VisitUnary ## NAME(PTR(UnaryOperator) S) { \
+ RetTy VisitUnary ## NAME(PTR(UnaryOperator) S, ParamTys... P) { \
DISPATCH(UnaryOperator, UnaryOperator); \
}
UNARYOP_FALLBACK(PostInc) UNARYOP_FALLBACK(PostDec)
@@ -163,7 +171,7 @@ public:
#undef UNARYOP_FALLBACK
// Base case, ignore it. :)
- RetTy VisitStmt(PTR(Stmt) Node) { return RetTy(); }
+ RetTy VisitStmt(PTR(Stmt) Node, ParamTys... P) { return RetTy(); }
#undef PTR
#undef DISPATCH
@@ -174,18 +182,18 @@ public:
///
/// This class does not preserve constness of Stmt pointers (see also
/// ConstStmtVisitor).
-template<typename ImplClass, typename RetTy=void>
+template<typename ImplClass, typename RetTy=void, typename... ParamTys>
class StmtVisitor
- : public StmtVisitorBase<make_ptr, ImplClass, RetTy> {};
+ : public StmtVisitorBase<make_ptr, 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>
+template<typename ImplClass, typename RetTy=void, typename... ParamTys>
class ConstStmtVisitor
- : public StmtVisitorBase<make_const_ptr, ImplClass, RetTy> {};
+ : public StmtVisitorBase<make_const_ptr, ImplClass, RetTy, ParamTys...> {};
/// \brief This class implements a simple visitor for OMPClause
/// subclasses.
@@ -222,6 +230,6 @@ template<class ImplClass, typename RetTy = void>
class ConstOMPClauseVisitor :
public OMPClauseVisitorBase <ImplClass, make_const_ptr, RetTy> {};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_AST_STMTVISITOR_H
diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h
index 84fbcda6e087..850250b9c0a2 100644
--- a/include/clang/AST/TemplateBase.h
+++ b/include/clang/AST/TemplateBase.h
@@ -1,4 +1,4 @@
-//===-- TemplateBase.h - Core classes for C++ templates ---------*- C++ -*-===//
+//===- TemplateBase.h - Core classes for C++ templates ----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,21 +15,32 @@
#ifndef LLVM_CLANG_AST_TEMPLATEBASE_H
#define LLVM_CLANG_AST_TEMPLATEBASE_H
+#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/APInt.h"
#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Compiler.h"
-#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TrailingObjects.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
namespace llvm {
- class FoldingSetNodeID;
-}
+
+class FoldingSetNodeID;
+
+} // namespace llvm
namespace clang {
+class ASTContext;
class DiagnosticBuilder;
class Expr;
struct PrintingPolicy;
@@ -44,29 +55,37 @@ public:
/// \brief Represents an empty template argument, e.g., one that has not
/// been deduced.
Null = 0,
+
/// The template argument is a type.
Type,
+
/// The template argument is a declaration that was provided for a pointer,
/// reference, or pointer to member non-type template parameter.
Declaration,
+
/// The template argument is a null pointer or null pointer to member that
/// was provided for a non-type template parameter.
NullPtr,
+
/// The template argument is an integral value stored in an llvm::APSInt
/// that was provided for an integral non-type template parameter.
Integral,
+
/// The template argument is a template name that was provided for a
/// template template parameter.
Template,
+
/// The template argument is a pack expansion of a template name that was
/// provided for a template template parameter.
TemplateExpansion,
+
/// The template argument is an expression, and we've not resolved it to one
/// of the other forms yet, either because it's dependent or because we're
/// representing a non-canonical template argument (for instance, in a
/// TemplateSpecializationType). Also used to represent a non-dependent
/// __uuidof expression (a Microsoft extension).
Expression,
+
/// The template argument is actually a parameter pack. Arguments are stored
/// in the Args struct.
Pack
@@ -88,8 +107,11 @@ private:
unsigned BitWidth : 31;
unsigned IsUnsigned : 1;
union {
- uint64_t VAL; ///< Used to store the <= 64 bits integer value.
- const uint64_t *pVal; ///< Used to store the >64 bits integer value.
+ /// Used to store the <= 64 bits integer value.
+ uint64_t VAL;
+
+ /// Used to store the >64 bits integer value.
+ const uint64_t *pVal;
};
void *Type;
};
@@ -115,8 +137,6 @@ private:
struct TV TypeOrValue;
};
- TemplateArgument(TemplateName, bool) = delete;
-
public:
/// \brief Construct an empty, invalid template argument.
constexpr TemplateArgument() : TypeOrValue({Null, 0}) {}
@@ -202,6 +222,8 @@ public:
this->Args.NumArgs = Args.size();
}
+ TemplateArgument(TemplateName, bool) = delete;
+
static TemplateArgument getEmptyPack() { return TemplateArgument(None); }
/// \brief Create a new template argument pack by copying the given set of
@@ -278,7 +300,9 @@ public:
// FIXME: Provide a way to read the integral data without copying the value.
llvm::APSInt getAsIntegral() const {
assert(getKind() == Integral && "Unexpected kind");
+
using namespace llvm;
+
if (Integer.BitWidth <= 64)
return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned);
@@ -309,7 +333,7 @@ public:
}
/// \brief Iterator that traverses the elements of a template argument pack.
- typedef const TemplateArgument * pack_iterator;
+ using pack_iterator = const TemplateArgument *;
/// \brief Iterator referencing the first argument of a template argument
/// pack.
@@ -368,7 +392,6 @@ public:
/// Location information for a TemplateArgument.
struct TemplateArgumentLocInfo {
private:
-
struct T {
// FIXME: We'd like to just use the qualifier in the TemplateName,
// but template arguments get canonicalized too quickly.
@@ -393,8 +416,7 @@ public:
TemplateArgumentLocInfo(NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateNameLoc,
- SourceLocation EllipsisLoc)
- {
+ SourceLocation EllipsisLoc) {
Template.Qualifier = QualifierLoc.getNestedNameSpecifier();
Template.QualifierLocData = QualifierLoc.getOpaqueData();
Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding();
@@ -434,16 +456,15 @@ public:
TemplateArgumentLoc(const TemplateArgument &Argument,
TemplateArgumentLocInfo Opaque)
- : Argument(Argument), LocInfo(Opaque) {
- }
+ : Argument(Argument), LocInfo(Opaque) {}
TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo)
- : Argument(Argument), LocInfo(TInfo) {
+ : Argument(Argument), LocInfo(TInfo) {
assert(Argument.getKind() == TemplateArgument::Type);
}
TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E)
- : Argument(Argument), LocInfo(E) {
+ : Argument(Argument), LocInfo(E) {
assert(Argument.getKind() == TemplateArgument::Expression);
}
@@ -451,7 +472,8 @@ public:
NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateNameLoc,
SourceLocation EllipsisLoc = SourceLocation())
- : Argument(Argument), LocInfo(QualifierLoc, TemplateNameLoc, EllipsisLoc) {
+ : Argument(Argument),
+ LocInfo(QualifierLoc, TemplateNameLoc, EllipsisLoc) {
assert(Argument.getKind() == TemplateArgument::Template ||
Argument.getKind() == TemplateArgument::TemplateExpansion);
}
@@ -526,16 +548,16 @@ class TemplateArgumentListInfo {
SourceLocation LAngleLoc;
SourceLocation RAngleLoc;
- // This can leak if used in an AST node, use ASTTemplateArgumentListInfo
- // instead.
- void *operator new(size_t bytes, ASTContext &C) = delete;
-
public:
- TemplateArgumentListInfo() {}
+ TemplateArgumentListInfo() = default;
TemplateArgumentListInfo(SourceLocation LAngleLoc,
SourceLocation RAngleLoc)
- : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {}
+ : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {}
+
+ // This can leak if used in an AST node, use ASTTemplateArgumentListInfo
+ // instead.
+ void *operator new(size_t bytes, ASTContext &C) = delete;
SourceLocation getLAngleLoc() const { return LAngleLoc; }
SourceLocation getRAngleLoc() const { return RAngleLoc; }
@@ -574,8 +596,8 @@ struct ASTTemplateArgumentListInfo final
: private llvm::TrailingObjects<ASTTemplateArgumentListInfo,
TemplateArgumentLoc> {
private:
- friend TrailingObjects;
friend class ASTNodeImporter;
+ friend TrailingObjects;
ASTTemplateArgumentListInfo(const TemplateArgumentListInfo &List);
@@ -668,6 +690,6 @@ inline const TemplateArgument &
return getArgs()[Idx];
}
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_AST_TEMPLATEBASE_H
diff --git a/include/clang/AST/TemplateName.h b/include/clang/AST/TemplateName.h
index bf4d008ee807..fb33cf58d796 100644
--- a/include/clang/AST/TemplateName.h
+++ b/include/clang/AST/TemplateName.h
@@ -1,4 +1,4 @@
-//===--- TemplateName.h - C++ Template Name Representation-------*- C++ -*-===//
+//===- TemplateName.h - C++ Template Name Representation --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,10 +14,12 @@
#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"
#include "llvm/ADT/PointerUnion.h"
+#include "llvm/Support/PointerLikeTypeTraits.h"
+#include <cassert>
namespace clang {
@@ -94,7 +96,7 @@ class OverloadedTemplateStorage : public UncommonTemplateNameStorage {
friend class ASTContext;
OverloadedTemplateStorage(unsigned size)
- : UncommonTemplateNameStorage(Overloaded, size) { }
+ : UncommonTemplateNameStorage(Overloaded, size) {}
NamedDecl **getStorage() {
return reinterpret_cast<NamedDecl **>(this + 1);
@@ -104,7 +106,7 @@ class OverloadedTemplateStorage : public UncommonTemplateNameStorage {
}
public:
- typedef NamedDecl *const *iterator;
+ using iterator = NamedDecl *const *;
iterator begin() const { return getStorage(); }
iterator end() const { return getStorage() + size(); }
@@ -126,8 +128,8 @@ public:
SubstTemplateTemplateParmPackStorage(TemplateTemplateParmDecl *Parameter,
unsigned Size,
const TemplateArgument *Arguments)
- : UncommonTemplateNameStorage(SubstTemplateTemplateParmPack, Size),
- Parameter(Parameter), Arguments(Arguments) { }
+ : UncommonTemplateNameStorage(SubstTemplateTemplateParmPack, Size),
+ Parameter(Parameter), Arguments(Arguments) {}
/// \brief Retrieve the template template parameter pack being substituted.
TemplateTemplateParmDecl *getParameterPack() const {
@@ -174,10 +176,9 @@ public:
/// specifier in the typedef. "apply" is a nested template, and can
/// only be understood in the context of
class TemplateName {
- typedef llvm::PointerUnion4<TemplateDecl *,
- UncommonTemplateNameStorage *,
- QualifiedTemplateName *,
- DependentTemplateName *> StorageType;
+ using StorageType =
+ llvm::PointerUnion4<TemplateDecl *, UncommonTemplateNameStorage *,
+ QualifiedTemplateName *, DependentTemplateName *>;
StorageType Storage;
@@ -188,24 +189,29 @@ public:
enum NameKind {
/// \brief A single template declaration.
Template,
+
/// \brief A set of overloaded template declarations.
OverloadedTemplate,
+
/// \brief A qualified template name, where the qualification is kept
/// to describe the source code as written.
QualifiedTemplate,
+
/// \brief A dependent template name that has not been resolved to a
/// template (or set of templates).
DependentTemplate,
+
/// \brief A template template parameter that has been substituted
/// for some other template name.
SubstTemplateTemplateParm,
+
/// \brief A template template parameter pack that has been substituted for
/// a template template argument pack, but has not yet been expanded into
/// individual arguments.
SubstTemplateTemplateParmPack
};
- TemplateName() : Storage() { }
+ TemplateName() = default;
explicit TemplateName(TemplateDecl *Template);
explicit TemplateName(OverloadedTemplateStorage *Storage);
explicit TemplateName(SubstTemplateTemplateParmStorage *Storage);
@@ -262,6 +268,11 @@ public:
TemplateName getUnderlying() const;
+ /// Get the template name to substitute when this template name is used as a
+ /// template template argument. This refers to the most recent declaration of
+ /// the template, including any default template arguments.
+ TemplateName getNameToSubstitute() const;
+
/// \brief Determines whether this is a dependent template name.
bool isDependent() const;
@@ -320,8 +331,8 @@ class SubstTemplateTemplateParmStorage
SubstTemplateTemplateParmStorage(TemplateTemplateParmDecl *parameter,
TemplateName replacement)
- : UncommonTemplateNameStorage(SubstTemplateTemplateParm, 0),
- Parameter(parameter), Replacement(replacement) {}
+ : UncommonTemplateNameStorage(SubstTemplateTemplateParm, 0),
+ Parameter(parameter), Replacement(replacement) {}
public:
TemplateTemplateParmDecl *getParameter() const { return Parameter; }
@@ -353,6 +364,8 @@ inline TemplateName TemplateName::getUnderlying() const {
/// manner, it is to TemplateName what ElaboratedType is to Type,
/// providing extra syntactic sugar for downstream clients.
class QualifiedTemplateName : public llvm::FoldingSetNode {
+ friend class ASTContext;
+
/// \brief The nested name specifier that qualifies the template name.
///
/// The bit is used to indicate whether the "template" keyword was
@@ -366,12 +379,9 @@ class QualifiedTemplateName : public llvm::FoldingSetNode {
/// that this qualified name refers to.
TemplateDecl *Template;
- friend class ASTContext;
-
QualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword,
TemplateDecl *Template)
- : Qualifier(NNS, TemplateKeyword? 1 : 0),
- Template(Template) { }
+ : Qualifier(NNS, TemplateKeyword? 1 : 0), Template(Template) {}
public:
/// \brief Return the nested name specifier that qualifies this name.
@@ -410,6 +420,8 @@ public:
/// where "MetaFun::" is the nested name specifier and "apply" is the
/// template name referenced. The "template" keyword is implied.
class DependentTemplateName : public llvm::FoldingSetNode {
+ friend class ASTContext;
+
/// \brief The nested name specifier that qualifies the template
/// name.
///
@@ -439,29 +451,27 @@ class DependentTemplateName : public llvm::FoldingSetNode {
/// canonical.
TemplateName CanonicalTemplateName;
- friend class ASTContext;
-
DependentTemplateName(NestedNameSpecifier *Qualifier,
const IdentifierInfo *Identifier)
- : Qualifier(Qualifier, false), Identifier(Identifier),
- CanonicalTemplateName(this) { }
+ : Qualifier(Qualifier, false), Identifier(Identifier),
+ CanonicalTemplateName(this) {}
DependentTemplateName(NestedNameSpecifier *Qualifier,
const IdentifierInfo *Identifier,
TemplateName Canon)
- : Qualifier(Qualifier, false), Identifier(Identifier),
- CanonicalTemplateName(Canon) { }
+ : Qualifier(Qualifier, false), Identifier(Identifier),
+ CanonicalTemplateName(Canon) {}
DependentTemplateName(NestedNameSpecifier *Qualifier,
OverloadedOperatorKind Operator)
- : Qualifier(Qualifier, true), Operator(Operator),
- CanonicalTemplateName(this) { }
+ : Qualifier(Qualifier, true), Operator(Operator),
+ CanonicalTemplateName(this) {}
DependentTemplateName(NestedNameSpecifier *Qualifier,
OverloadedOperatorKind Operator,
TemplateName Canon)
- : Qualifier(Qualifier, true), Operator(Operator),
- CanonicalTemplateName(Canon) { }
+ : Qualifier(Qualifier, true), Operator(Operator),
+ CanonicalTemplateName(Canon) {}
public:
/// \brief Return the nested name specifier that qualifies this name.
@@ -509,14 +519,13 @@ public:
}
};
-} // end namespace clang.
+} // namespace clang.
namespace llvm {
/// \brief The clang::TemplateName class is effectively a pointer.
template<>
-class PointerLikeTypeTraits<clang::TemplateName> {
-public:
+struct PointerLikeTypeTraits<clang::TemplateName> {
static inline void *getAsVoidPointer(clang::TemplateName TN) {
return TN.getAsVoidPointer();
}
@@ -529,6 +538,6 @@ public:
enum { NumLowBitsAvailable = 0 };
};
-} // end namespace llvm.
+} // namespace llvm.
-#endif
+#endif // LLVM_CLANG_AST_TEMPLATENAME_H
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index 984096ffa987..7247838947a2 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -1,4 +1,4 @@
-//===--- Type.h - C Language Family Type Representation ---------*- C++ -*-===//
+//===- Type.h - C Language Family Type Representation -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,12 +6,13 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
/// \file
/// \brief C Language Family Type Representation
///
/// This file defines the clang::Type interface and subclasses, used to
/// represent types for languages in the C family.
-///
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_TYPE_H
@@ -25,85 +26,118 @@
#include "clang/Basic/LLVM.h"
#include "clang/Basic/Linkage.h"
#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Basic/Visibility.h"
#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/ADT/iterator_range.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/PointerLikeTypeTraits.h"
+#include "llvm/Support/type_traits.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <cstring>
+#include <string>
+#include <type_traits>
+#include <utility>
namespace clang {
- enum {
- TypeAlignmentInBits = 4,
- TypeAlignment = 1 << TypeAlignmentInBits
- };
- class Type;
- class ExtQuals;
- class QualType;
-}
+
+class ExtQuals;
+class QualType;
+class Type;
+
+enum {
+ TypeAlignmentInBits = 4,
+ TypeAlignment = 1 << TypeAlignmentInBits
+};
+
+} // namespace clang
namespace llvm {
+
template <typename T>
- class PointerLikeTypeTraits;
+ struct PointerLikeTypeTraits;
template<>
- class PointerLikeTypeTraits< ::clang::Type*> {
- public:
+ struct PointerLikeTypeTraits< ::clang::Type*> {
static inline void *getAsVoidPointer(::clang::Type *P) { return P; }
+
static inline ::clang::Type *getFromVoidPointer(void *P) {
return static_cast< ::clang::Type*>(P);
}
+
enum { NumLowBitsAvailable = clang::TypeAlignmentInBits };
};
+
template<>
- class PointerLikeTypeTraits< ::clang::ExtQuals*> {
- public:
+ struct PointerLikeTypeTraits< ::clang::ExtQuals*> {
static inline void *getAsVoidPointer(::clang::ExtQuals *P) { return P; }
+
static inline ::clang::ExtQuals *getFromVoidPointer(void *P) {
return static_cast< ::clang::ExtQuals*>(P);
}
+
enum { NumLowBitsAvailable = clang::TypeAlignmentInBits };
};
template <>
struct isPodLike<clang::QualType> { static const bool value = true; };
-}
+
+} // namespace llvm
namespace clang {
- class ASTContext;
- class TypedefNameDecl;
- class TemplateDecl;
- class TemplateTypeParmDecl;
- class NonTypeTemplateParmDecl;
- class TemplateTemplateParmDecl;
- class TagDecl;
- class RecordDecl;
- class CXXRecordDecl;
- class EnumDecl;
- class FieldDecl;
- class FunctionDecl;
- class ObjCInterfaceDecl;
- class ObjCProtocolDecl;
- class ObjCMethodDecl;
- class ObjCTypeParamDecl;
- class UnresolvedUsingTypenameDecl;
- class Expr;
- class Stmt;
- class SourceLocation;
- class StmtIteratorBase;
- class TemplateArgument;
- class TemplateArgumentLoc;
- class TemplateArgumentListInfo;
- class ElaboratedType;
- class ExtQuals;
- class ExtQualsTypeCommonBase;
- struct PrintingPolicy;
-
- template <typename> class CanQual;
- typedef CanQual<Type> CanQualType;
+
+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
#define TYPE(Class, Base) class Class##Type;
@@ -164,8 +198,6 @@ public:
FastMask = (1 << FastWidth) - 1
};
- Qualifiers() : Mask(0) {}
-
/// Returns the common set of qualifiers while removing them from
/// the given sets.
static Qualifiers removeCommonQualifiers(Qualifiers &L, Qualifiers &R) {
@@ -332,9 +364,11 @@ public:
}
bool hasAddressSpace() const { return Mask & AddressSpaceMask; }
- unsigned getAddressSpace() const { return Mask >> AddressSpaceShift; }
+ LangAS getAddressSpace() const {
+ return static_cast<LangAS>(Mask >> AddressSpaceShift);
+ }
bool hasTargetSpecificAddressSpace() const {
- return getAddressSpace() >= LangAS::FirstTargetAddressSpace;
+ return isTargetAddressSpace(getAddressSpace());
}
/// Get the address space attribute value to be printed by diagnostics.
unsigned getAddressSpaceAttributePrintValue() const {
@@ -342,22 +376,22 @@ public:
// This function is not supposed to be used with language specific
// address spaces. If that happens, the diagnostic message should consider
// printing the QualType instead of the address space value.
- assert(Addr == 0 || hasTargetSpecificAddressSpace());
- if (Addr)
- return Addr - LangAS::FirstTargetAddressSpace;
+ assert(Addr == LangAS::Default || hasTargetSpecificAddressSpace());
+ if (Addr != LangAS::Default)
+ return toTargetAddressSpace(Addr);
// TODO: The diagnostic messages where Addr may be 0 should be fixed
// since it cannot differentiate the situation where 0 denotes the default
// address space or user specified __attribute__((address_space(0))).
return 0;
}
- void setAddressSpace(unsigned space) {
- assert(space <= MaxAddressSpace);
+ void setAddressSpace(LangAS space) {
+ assert((unsigned)space <= MaxAddressSpace);
Mask = (Mask & ~AddressSpaceMask)
| (((uint32_t) space) << AddressSpaceShift);
}
- void removeAddressSpace() { setAddressSpace(0); }
- void addAddressSpace(unsigned space) {
- assert(space);
+ void removeAddressSpace() { setAddressSpace(LangAS::Default); }
+ void addAddressSpace(LangAS space) {
+ assert(space != LangAS::Default);
setAddressSpace(space);
}
@@ -538,10 +572,9 @@ public:
}
private:
-
// bits: |0 1 2|3|4 .. 5|6 .. 8|9 ... 31|
// |C R V|U|GCAttr|Lifetime|AddressSpace|
- uint32_t Mask;
+ uint32_t Mask = 0;
static const uint32_t UMask = 0x8;
static const uint32_t UShift = 3;
@@ -558,12 +591,12 @@ private:
/// into its local qualifiers and its locally-unqualified type.
struct SplitQualType {
/// The locally-unqualified type.
- const Type *Ty;
+ const Type *Ty = nullptr;
/// The local qualifiers.
Qualifiers Quals;
- SplitQualType() : Ty(nullptr), Quals() {}
+ SplitQualType() = default;
SplitQualType(const Type *ty, Qualifiers qs) : Ty(ty), Quals(qs) {}
SplitQualType getSingleStepDesugaredType() const; // end of this file
@@ -589,12 +622,16 @@ struct SplitQualType {
enum class ObjCSubstitutionContext {
/// An ordinary type.
Ordinary,
+
/// The result type of a method or function.
Result,
+
/// The parameter type of a method or function.
Parameter,
+
/// The type of a property.
Property,
+
/// The superclass of a type.
Superclass,
};
@@ -614,8 +651,10 @@ enum class ObjCSubstitutionContext {
/// indicates whether there are extended qualifiers present, in which
/// case the pointer points to a special structure.
class QualType {
+ friend class QualifierCollector;
+
// Thankfully, these are efficiently composable.
- llvm::PointerIntPair<llvm::PointerUnion<const Type*,const ExtQuals*>,
+ llvm::PointerIntPair<llvm::PointerUnion<const Type *, const ExtQuals *>,
Qualifiers::FastWidth> Value;
const ExtQuals *getExtQualsUnsafe() const {
@@ -634,14 +673,10 @@ class QualType {
return reinterpret_cast<ExtQualsTypeCommonBase*>(CommonPtrVal);
}
- friend class QualifierCollector;
public:
- QualType() {}
-
- QualType(const Type *Ptr, unsigned Quals)
- : Value(Ptr, Quals) {}
- QualType(const ExtQuals *Ptr, unsigned Quals)
- : Value(Ptr, Quals) {}
+ QualType() = default;
+ QualType(const Type *Ptr, unsigned Quals) : Value(Ptr, Quals) {}
+ QualType(const ExtQuals *Ptr, unsigned Quals) : Value(Ptr, Quals) {}
unsigned getLocalFastQualifiers() const { return Value.getInt(); }
void setLocalFastQualifiers(unsigned Quals) { Value.setInt(Quals); }
@@ -662,6 +697,7 @@ public:
SplitQualType split() const;
void *getAsOpaquePtr() const { return Value.getOpaqueValue(); }
+
static QualType getFromOpaquePtr(const void *Ptr) {
QualType T;
T.Value.setFromOpaqueValue(const_cast<void*>(Ptr));
@@ -939,12 +975,15 @@ public:
friend bool operator!=(const QualType &LHS, const QualType &RHS) {
return LHS.Value != RHS.Value;
}
+
std::string getAsString() const {
return getAsString(split());
}
+
static std::string getAsString(SplitQualType split) {
return getAsString(split.Ty, split.Quals);
}
+
static std::string getAsString(const Type *ty, Qualifiers qs);
std::string getAsString(const PrintingPolicy &Policy) const;
@@ -954,11 +993,13 @@ public:
unsigned Indentation = 0) const {
print(split(), OS, Policy, PlaceHolder, Indentation);
}
+
static void print(SplitQualType split, raw_ostream &OS,
const PrintingPolicy &policy, const Twine &PlaceHolder,
unsigned Indentation = 0) {
return print(split.Ty, split.Quals, OS, policy, PlaceHolder, Indentation);
}
+
static void print(const Type *ty, Qualifiers qs,
raw_ostream &OS, const PrintingPolicy &policy,
const Twine &PlaceHolder,
@@ -968,10 +1009,12 @@ public:
const PrintingPolicy &Policy) const {
return getAsStringInternal(split(), Str, Policy);
}
+
static void getAsStringInternal(SplitQualType split, std::string &out,
const PrintingPolicy &policy) {
return getAsStringInternal(split.Ty, split.Quals, out, policy);
}
+
static void getAsStringInternal(const Type *ty, Qualifiers qs,
std::string &out,
const PrintingPolicy &policy);
@@ -981,11 +1024,12 @@ public:
const PrintingPolicy &Policy;
const Twine &PlaceHolder;
unsigned Indentation;
+
public:
StreamedQualTypeHelper(const QualType &T, const PrintingPolicy &Policy,
const Twine &PlaceHolder, unsigned Indentation)
- : T(T), Policy(Policy), PlaceHolder(PlaceHolder),
- Indentation(Indentation) { }
+ : T(T), Policy(Policy), PlaceHolder(PlaceHolder),
+ Indentation(Indentation) {}
friend raw_ostream &operator<<(raw_ostream &OS,
const StreamedQualTypeHelper &SQT) {
@@ -1009,7 +1053,7 @@ public:
}
/// Return the address space of this type.
- inline unsigned getAddressSpace() const;
+ inline LangAS getAddressSpace() const;
/// Returns gc attribute of this type.
inline Qualifiers::GC getObjCGCAttr() const;
@@ -1129,13 +1173,15 @@ private:
static DestructionKind isDestructedTypeImpl(QualType type);
};
-} // end clang.
+} // namespace clang
namespace llvm {
+
/// Implement simplify_type for QualType, so that we can dyn_cast from QualType
/// to a specific Type class.
template<> struct simplify_type< ::clang::QualType> {
- typedef const ::clang::Type *SimpleType;
+ using SimpleType = const ::clang::Type *;
+
static SimpleType getSimplifiedValue(::clang::QualType Val) {
return Val.getTypePtr();
}
@@ -1143,29 +1189,30 @@ template<> struct simplify_type< ::clang::QualType> {
// Teach SmallPtrSet that QualType is "basically a pointer".
template<>
-class PointerLikeTypeTraits<clang::QualType> {
-public:
+struct PointerLikeTypeTraits<clang::QualType> {
static inline void *getAsVoidPointer(clang::QualType P) {
return P.getAsOpaquePtr();
}
+
static inline clang::QualType getFromVoidPointer(void *P) {
return clang::QualType::getFromOpaquePtr(P);
}
+
// Various qualifiers go in low bits.
enum { NumLowBitsAvailable = 0 };
};
-} // end namespace llvm
+} // namespace llvm
namespace clang {
/// \brief Base class that is common to both the \c ExtQuals and \c Type
/// classes, which allows \c QualType to access the common fields between the
/// two.
-///
class ExtQualsTypeCommonBase {
- ExtQualsTypeCommonBase(const Type *baseType, QualType canon)
- : BaseType(baseType), CanonicalType(canon) {}
+ friend class ExtQuals;
+ friend class QualType;
+ friend class Type;
/// \brief The "base" type of an extended qualifiers type (\c ExtQuals) or
/// a self-referential pointer (for \c Type).
@@ -1177,9 +1224,8 @@ class ExtQualsTypeCommonBase {
/// \brief The canonical type of this type. A QualType.
QualType CanonicalType;
- friend class QualType;
- friend class Type;
- friend class ExtQuals;
+ ExtQualsTypeCommonBase(const Type *baseType, QualType canon)
+ : BaseType(baseType), CanonicalType(canon) {}
};
/// We can encode up to four bits in the low bits of a
@@ -1214,10 +1260,9 @@ class ExtQuals : public ExtQualsTypeCommonBase, public llvm::FoldingSetNode {
public:
ExtQuals(const Type *baseType, QualType canon, Qualifiers quals)
- : ExtQualsTypeCommonBase(baseType,
- canon.isNull() ? QualType(this_(), 0) : canon),
- Quals(quals)
- {
+ : ExtQualsTypeCommonBase(baseType,
+ canon.isNull() ? QualType(this_(), 0) : canon),
+ Quals(quals) {
assert(Quals.hasNonFastQualifiers()
&& "ExtQuals created with no fast qualifiers");
assert(!Quals.hasFastQualifiers()
@@ -1235,7 +1280,7 @@ public:
}
bool hasAddressSpace() const { return Quals.hasAddressSpace(); }
- unsigned getAddressSpace() const { return Quals.getAddressSpace(); }
+ LangAS getAddressSpace() const { return Quals.getAddressSpace(); }
const Type *getBaseType() const { return BaseType; }
@@ -1243,6 +1288,7 @@ public:
void Profile(llvm::FoldingSetNodeID &ID) const {
Profile(ID, getBaseType(), Quals);
}
+
static void Profile(llvm::FoldingSetNodeID &ID,
const Type *BaseType,
Qualifiers Quals) {
@@ -1258,8 +1304,10 @@ public:
enum RefQualifierKind {
/// \brief No ref-qualifier was provided.
RQ_None = 0,
+
/// \brief An lvalue ref-qualifier was provided (\c &).
RQ_LValue,
+
/// \brief An rvalue ref-qualifier was provided (\c &&).
RQ_RValue
};
@@ -1268,8 +1316,10 @@ enum RefQualifierKind {
enum class AutoTypeKeyword {
/// \brief auto
Auto,
+
/// \brief decltype(auto)
DecltypeAuto,
+
/// \brief __auto_type (GNU extension)
GNUAutoType
};
@@ -1311,9 +1361,6 @@ public:
};
private:
- Type(const Type &) = delete;
- void operator=(const Type &) = delete;
-
/// Bitfields required by the Type class.
class TypeBitfields {
friend class Type;
@@ -1352,10 +1399,12 @@ private:
bool isCacheValid() const {
return CacheValid;
}
+
Linkage getLinkage() const {
assert(isCacheValid() && "getting linkage from invalid cache");
return static_cast<Linkage>(CachedLinkage);
}
+
bool hasLocalOrUnnamedType() const {
assert(isCacheValid() && "getting linkage from invalid cache");
return CachedLocalOrUnnamed;
@@ -1392,8 +1441,8 @@ protected:
};
class FunctionTypeBitfields {
- friend class FunctionType;
friend class FunctionProtoType;
+ friend class FunctionType;
unsigned : NumTypeBits;
@@ -1429,6 +1478,7 @@ protected:
/// Whether this is a "kindof" type.
unsigned IsKindOf : 1;
};
+
static_assert(NumTypeBits + 7 + 6 + 1 <= 32, "Does not fit in an unsigned");
class ReferenceTypeBitfields {
@@ -1511,21 +1561,21 @@ protected:
};
private:
+ template <class T> friend class TypePropertyCache;
+
/// \brief Set whether this type comes from an AST file.
void setFromAST(bool V = true) const {
TypeBits.FromAST = V;
}
- template <class T> friend class TypePropertyCache;
-
protected:
- // silence VC++ warning C4355: 'this' : used in base member initializer list
- Type *this_() { return this; }
+ friend class ASTContext;
+
Type(TypeClass tc, QualType canon, bool Dependent,
bool InstantiationDependent, bool VariablyModified,
bool ContainsUnexpandedParameterPack)
- : ExtQualsTypeCommonBase(this,
- canon.isNull() ? QualType(this_(), 0) : canon) {
+ : ExtQualsTypeCommonBase(this,
+ canon.isNull() ? QualType(this_(), 0) : canon) {
TypeBits.TC = tc;
TypeBits.Dependent = Dependent;
TypeBits.InstantiationDependent = Dependent || InstantiationDependent;
@@ -1536,22 +1586,32 @@ protected:
TypeBits.CachedLinkage = NoLinkage;
TypeBits.FromAST = false;
}
- friend class ASTContext;
+
+ // silence VC++ warning C4355: 'this' : used in base member initializer list
+ Type *this_() { return this; }
void setDependent(bool D = true) {
TypeBits.Dependent = D;
if (D)
TypeBits.InstantiationDependent = true;
}
+
void setInstantiationDependent(bool D = true) {
TypeBits.InstantiationDependent = D; }
- void setVariablyModified(bool VM = true) { TypeBits.VariablyModified = VM;
- }
+
+ void setVariablyModified(bool VM = true) { TypeBits.VariablyModified = VM; }
+
void setContainsUnexpandedParameterPack(bool PP = true) {
TypeBits.ContainsUnexpandedParameterPack = PP;
}
public:
+ friend class ASTReader;
+ friend class ASTWriter;
+
+ Type(const Type &) = delete;
+ Type &operator=(const Type &) = delete;
+
TypeClass getTypeClass() const { return static_cast<TypeClass>(TypeBits.TC); }
/// \brief Whether this type comes from an AST file.
@@ -1658,6 +1718,7 @@ public:
/// Determine whether this type is an integral or enumeration type.
bool isIntegralOrEnumerationType() const;
+
/// Determine whether this type is an integral or unscoped enumeration type.
bool isIntegralOrUnscopedEnumerationType() const;
@@ -1708,6 +1769,7 @@ public:
bool isComplexIntegerType() const; // GCC _Complex integer type.
bool isVectorType() const; // GCC vector type.
bool isExtVectorType() const; // Extended vector type.
+ bool isDependentAddressSpaceType() const; // value-dependent address space qualifier
bool isObjCObjectPointerType() const; // pointer to ObjC object
bool isObjCRetainableType() const; // ObjC object or block pointer
bool isObjCLifetimeType() const; // (array of)* retainable type
@@ -1789,6 +1851,7 @@ public:
STK_IntegralComplex,
STK_FloatingComplex
};
+
/// Given that this is a scalar type, classify it.
ScalarTypeKind getScalarTypeKind() const;
@@ -1859,6 +1922,7 @@ public:
const RecordType *getAsUnionType() const;
const ComplexType *getAsComplexIntegerType() const; // GCC complex int type.
const ObjCObjectType *getAsObjCInterfaceType() const;
+
// The following is a convenience method that returns an ObjCObjectPointerType
// for object declared using an interface.
const ObjCObjectPointerType *getAsObjCInterfacePointerType() const;
@@ -2045,12 +2109,10 @@ public:
QualType getCanonicalTypeInternal() const {
return CanonicalType;
}
+
CanQualType getCanonicalTypeUnqualified() const; // in CanonicalType.h
void dump() const;
void dump(llvm::raw_ostream &OS) const;
-
- friend class ASTReader;
- friend class ASTWriter;
};
/// \brief This will check for a TypedefType by removing any existing sugar
@@ -2078,7 +2140,6 @@ template <> inline const Class##Type *Type::castAs() const { \
}
#include "clang/AST/TypeNodes.def"
-
/// This class is used for builtin types like 'int'. Builtin
/// types are always canonical and have a literal name field.
class BuiltinType : public Type {
@@ -2095,15 +2156,16 @@ public:
public:
BuiltinType(Kind K)
- : Type(Builtin, QualType(), /*Dependent=*/(K == Dependent),
- /*InstantiationDependent=*/(K == Dependent),
- /*VariablyModified=*/false,
- /*Unexpanded parameter pack=*/false) {
+ : Type(Builtin, QualType(), /*Dependent=*/(K == Dependent),
+ /*InstantiationDependent=*/(K == Dependent),
+ /*VariablyModified=*/false,
+ /*Unexpanded parameter pack=*/false) {
BuiltinTypeBits.Kind = K;
}
Kind getKind() const { return static_cast<Kind>(BuiltinTypeBits.Kind); }
StringRef getName(const PrintingPolicy &Policy) const;
+
const char *getNameAsCString(const PrintingPolicy &Policy) const {
// The StringRef is null-terminated.
StringRef str = getName(Policy);
@@ -2160,17 +2222,17 @@ public:
/// Complex values, per C99 6.2.5p11. This supports the C99 complex
/// types (_Complex float etc) as well as the GCC integer complex extensions.
-///
class ComplexType : public Type, public llvm::FoldingSetNode {
+ friend class ASTContext; // ASTContext creates these.
+
QualType ElementType;
- ComplexType(QualType Element, QualType CanonicalPtr) :
- Type(Complex, CanonicalPtr, Element->isDependentType(),
- Element->isInstantiationDependentType(),
- Element->isVariablyModifiedType(),
- Element->containsUnexpandedParameterPack()),
- ElementType(Element) {
- }
- friend class ASTContext; // ASTContext creates these.
+
+ ComplexType(QualType Element, QualType CanonicalPtr)
+ : Type(Complex, CanonicalPtr, Element->isDependentType(),
+ Element->isInstantiationDependentType(),
+ Element->isVariablyModifiedType(),
+ Element->containsUnexpandedParameterPack()),
+ ElementType(Element) {}
public:
QualType getElementType() const { return ElementType; }
@@ -2181,6 +2243,7 @@ public:
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, getElementType());
}
+
static void Profile(llvm::FoldingSetNodeID &ID, QualType Element) {
ID.AddPointer(Element.getAsOpaquePtr());
}
@@ -2189,21 +2252,19 @@ public:
};
/// Sugar for parentheses used when specifying types.
-///
class ParenType : public Type, public llvm::FoldingSetNode {
+ friend class ASTContext; // ASTContext creates these.
+
QualType Inner;
- ParenType(QualType InnerType, QualType CanonType) :
- Type(Paren, CanonType, InnerType->isDependentType(),
- InnerType->isInstantiationDependentType(),
- InnerType->isVariablyModifiedType(),
- InnerType->containsUnexpandedParameterPack()),
- Inner(InnerType) {
- }
- friend class ASTContext; // ASTContext creates these.
+ ParenType(QualType InnerType, QualType CanonType)
+ : Type(Paren, CanonType, InnerType->isDependentType(),
+ InnerType->isInstantiationDependentType(),
+ InnerType->isVariablyModifiedType(),
+ InnerType->containsUnexpandedParameterPack()),
+ Inner(InnerType) {}
public:
-
QualType getInnerType() const { return Inner; }
bool isSugared() const { return true; }
@@ -2212,6 +2273,7 @@ public:
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, getInnerType());
}
+
static void Profile(llvm::FoldingSetNodeID &ID, QualType Inner) {
Inner.Profile(ID);
}
@@ -2220,21 +2282,19 @@ public:
};
/// PointerType - C99 6.7.5.1 - Pointer Declarators.
-///
class PointerType : public Type, public llvm::FoldingSetNode {
+ friend class ASTContext; // ASTContext creates these.
+
QualType PointeeType;
- PointerType(QualType Pointee, QualType CanonicalPtr) :
- Type(Pointer, CanonicalPtr, Pointee->isDependentType(),
- Pointee->isInstantiationDependentType(),
- Pointee->isVariablyModifiedType(),
- Pointee->containsUnexpandedParameterPack()),
- PointeeType(Pointee) {
- }
- friend class ASTContext; // ASTContext creates these.
+ PointerType(QualType Pointee, QualType CanonicalPtr)
+ : Type(Pointer, CanonicalPtr, Pointee->isDependentType(),
+ Pointee->isInstantiationDependentType(),
+ Pointee->isVariablyModifiedType(),
+ Pointee->containsUnexpandedParameterPack()),
+ PointeeType(Pointee) {}
public:
-
QualType getPointeeType() const { return PointeeType; }
/// Returns true if address spaces of pointers overlap.
@@ -2259,6 +2319,7 @@ public:
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, getPointeeType());
}
+
static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) {
ID.AddPointer(Pointee.getAsOpaquePtr());
}
@@ -2274,6 +2335,8 @@ class AdjustedType : public Type, public llvm::FoldingSetNode {
QualType AdjustedTy;
protected:
+ friend class ASTContext; // ASTContext creates these.
+
AdjustedType(TypeClass TC, QualType OriginalTy, QualType AdjustedTy,
QualType CanonicalPtr)
: Type(TC, CanonicalPtr, OriginalTy->isDependentType(),
@@ -2282,8 +2345,6 @@ protected:
OriginalTy->containsUnexpandedParameterPack()),
OriginalTy(OriginalTy), AdjustedTy(AdjustedTy) {}
- friend class ASTContext; // ASTContext creates these.
-
public:
QualType getOriginalType() const { return OriginalTy; }
QualType getAdjustedType() const { return AdjustedTy; }
@@ -2294,6 +2355,7 @@ public:
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, OriginalTy, AdjustedTy);
}
+
static void Profile(llvm::FoldingSetNodeID &ID, QualType Orig, QualType New) {
ID.AddPointer(Orig.getAsOpaquePtr());
ID.AddPointer(New.getAsOpaquePtr());
@@ -2306,12 +2368,11 @@ public:
/// Represents a pointer type decayed from an array or function type.
class DecayedType : public AdjustedType {
+ friend class ASTContext; // ASTContext creates these.
inline
DecayedType(QualType OriginalType, QualType Decayed, QualType Canonical);
- friend class ASTContext; // ASTContext creates these.
-
public:
QualType getDecayedType() const { return getAdjustedType(); }
@@ -2323,20 +2384,20 @@ public:
/// Pointer to a block type.
/// This type is to represent types syntactically represented as
/// "void (^)(int)", etc. Pointee is required to always be a function type.
-///
class BlockPointerType : public Type, public llvm::FoldingSetNode {
- QualType PointeeType; // Block is some kind of pointer type
- BlockPointerType(QualType Pointee, QualType CanonicalCls) :
- Type(BlockPointer, CanonicalCls, Pointee->isDependentType(),
- Pointee->isInstantiationDependentType(),
- Pointee->isVariablyModifiedType(),
- Pointee->containsUnexpandedParameterPack()),
- PointeeType(Pointee) {
- }
- friend class ASTContext; // ASTContext creates these.
+ friend class ASTContext; // ASTContext creates these.
-public:
+ // Block is some kind of pointer type
+ QualType PointeeType;
+ BlockPointerType(QualType Pointee, QualType CanonicalCls)
+ : Type(BlockPointer, CanonicalCls, Pointee->isDependentType(),
+ Pointee->isInstantiationDependentType(),
+ Pointee->isVariablyModifiedType(),
+ Pointee->containsUnexpandedParameterPack()),
+ PointeeType(Pointee) {}
+
+public:
// Get the pointee type. Pointee is required to always be a function type.
QualType getPointeeType() const { return PointeeType; }
@@ -2346,6 +2407,7 @@ public:
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, getPointeeType());
}
+
static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) {
ID.AddPointer(Pointee.getAsOpaquePtr());
}
@@ -2356,19 +2418,17 @@ public:
};
/// Base for LValueReferenceType and RValueReferenceType
-///
class ReferenceType : public Type, public llvm::FoldingSetNode {
QualType PointeeType;
protected:
ReferenceType(TypeClass tc, QualType Referencee, QualType CanonicalRef,
- bool SpelledAsLValue) :
- Type(tc, CanonicalRef, Referencee->isDependentType(),
- Referencee->isInstantiationDependentType(),
- Referencee->isVariablyModifiedType(),
- Referencee->containsUnexpandedParameterPack()),
- PointeeType(Referencee)
- {
+ bool SpelledAsLValue)
+ : Type(tc, CanonicalRef, Referencee->isDependentType(),
+ Referencee->isInstantiationDependentType(),
+ Referencee->isVariablyModifiedType(),
+ Referencee->containsUnexpandedParameterPack()),
+ PointeeType(Referencee) {
ReferenceTypeBits.SpelledAsLValue = SpelledAsLValue;
ReferenceTypeBits.InnerRef = Referencee->isReferenceType();
}
@@ -2378,6 +2438,7 @@ public:
bool isInnerRef() const { return ReferenceTypeBits.InnerRef; }
QualType getPointeeTypeAsWritten() const { return PointeeType; }
+
QualType getPointeeType() const {
// FIXME: this might strip inner qualifiers; okay?
const ReferenceType *T = this;
@@ -2389,6 +2450,7 @@ public:
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, PointeeType, isSpelledAsLValue());
}
+
static void Profile(llvm::FoldingSetNodeID &ID,
QualType Referencee,
bool SpelledAsLValue) {
@@ -2403,13 +2465,14 @@ public:
};
/// An lvalue reference type, per C++11 [dcl.ref].
-///
class LValueReferenceType : public ReferenceType {
- LValueReferenceType(QualType Referencee, QualType CanonicalRef,
- bool SpelledAsLValue) :
- ReferenceType(LValueReference, Referencee, CanonicalRef, SpelledAsLValue)
- {}
friend class ASTContext; // ASTContext creates these
+
+ LValueReferenceType(QualType Referencee, QualType CanonicalRef,
+ bool SpelledAsLValue)
+ : ReferenceType(LValueReference, Referencee, CanonicalRef,
+ SpelledAsLValue) {}
+
public:
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -2420,12 +2483,12 @@ public:
};
/// An rvalue reference type, per C++11 [dcl.ref].
-///
class RValueReferenceType : public ReferenceType {
- RValueReferenceType(QualType Referencee, QualType CanonicalRef) :
- ReferenceType(RValueReference, Referencee, CanonicalRef, false) {
- }
friend class ASTContext; // ASTContext creates these
+
+ RValueReferenceType(QualType Referencee, QualType CanonicalRef)
+ : ReferenceType(RValueReference, Referencee, CanonicalRef, false) {}
+
public:
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -2438,24 +2501,24 @@ public:
/// A pointer to member type per C++ 8.3.3 - Pointers to members.
///
/// This includes both pointers to data members and pointer to member functions.
-///
class MemberPointerType : public Type, public llvm::FoldingSetNode {
+ friend class ASTContext; // ASTContext creates these.
+
QualType PointeeType;
+
/// The class of which the pointee is a member. Must ultimately be a
/// RecordType, but could be a typedef or a template parameter too.
const Type *Class;
- MemberPointerType(QualType Pointee, const Type *Cls, QualType CanonicalPtr) :
- Type(MemberPointer, CanonicalPtr,
- Cls->isDependentType() || Pointee->isDependentType(),
- (Cls->isInstantiationDependentType() ||
- Pointee->isInstantiationDependentType()),
- Pointee->isVariablyModifiedType(),
- (Cls->containsUnexpandedParameterPack() ||
- Pointee->containsUnexpandedParameterPack())),
- PointeeType(Pointee), Class(Cls) {
- }
- friend class ASTContext; // ASTContext creates these.
+ MemberPointerType(QualType Pointee, const Type *Cls, QualType CanonicalPtr)
+ : Type(MemberPointer, CanonicalPtr,
+ Cls->isDependentType() || Pointee->isDependentType(),
+ (Cls->isInstantiationDependentType() ||
+ Pointee->isInstantiationDependentType()),
+ Pointee->isVariablyModifiedType(),
+ (Cls->containsUnexpandedParameterPack() ||
+ Pointee->containsUnexpandedParameterPack())),
+ PointeeType(Pointee), Class(Cls) {}
public:
QualType getPointeeType() const { return PointeeType; }
@@ -2481,6 +2544,7 @@ public:
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, getPointeeType(), getClass());
}
+
static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee,
const Type *Class) {
ID.AddPointer(Pointee.getAsOpaquePtr());
@@ -2493,7 +2557,6 @@ public:
};
/// Represents an array type, per C99 6.7.5.2 - Array Declarators.
-///
class ArrayType : public Type, public llvm::FoldingSetNode {
public:
/// Capture whether this is a normal array (e.g. int X[4])
@@ -2503,11 +2566,14 @@ public:
enum ArraySizeModifier {
Normal, Static, Star
};
+
private:
/// The element type of the array.
QualType ElementType;
protected:
+ friend class ASTContext; // ASTContext creates these.
+
// C++ [temp.dep.type]p1:
// A type is dependent if it is...
// - an array type constructed from any dependent type or whose
@@ -2516,25 +2582,26 @@ protected:
ArrayType(TypeClass tc, QualType et, QualType can,
ArraySizeModifier sm, unsigned tq,
bool ContainsUnexpandedParameterPack)
- : Type(tc, can, et->isDependentType() || tc == DependentSizedArray,
- et->isInstantiationDependentType() || tc == DependentSizedArray,
- (tc == VariableArray || et->isVariablyModifiedType()),
- ContainsUnexpandedParameterPack),
- ElementType(et) {
+ : Type(tc, can, et->isDependentType() || tc == DependentSizedArray,
+ et->isInstantiationDependentType() || tc == DependentSizedArray,
+ (tc == VariableArray || et->isVariablyModifiedType()),
+ ContainsUnexpandedParameterPack),
+ ElementType(et) {
ArrayTypeBits.IndexTypeQuals = tq;
ArrayTypeBits.SizeModifier = sm;
}
- friend class ASTContext; // ASTContext creates these.
-
public:
QualType getElementType() const { return ElementType; }
+
ArraySizeModifier getSizeModifier() const {
return ArraySizeModifier(ArrayTypeBits.SizeModifier);
}
+
Qualifiers getIndexTypeQualifiers() const {
return Qualifiers::fromCVRMask(getIndexTypeCVRQualifiers());
}
+
unsigned getIndexTypeCVRQualifiers() const {
return ArrayTypeBits.IndexTypeQuals;
}
@@ -2555,21 +2622,23 @@ class ConstantArrayType : public ArrayType {
ConstantArrayType(QualType et, QualType can, const llvm::APInt &size,
ArraySizeModifier sm, unsigned tq)
- : ArrayType(ConstantArray, et, can, sm, tq,
- et->containsUnexpandedParameterPack()),
- Size(size) {}
+ : ArrayType(ConstantArray, et, can, sm, tq,
+ et->containsUnexpandedParameterPack()),
+ Size(size) {}
+
protected:
+ friend class ASTContext; // ASTContext creates these.
+
ConstantArrayType(TypeClass tc, QualType et, QualType can,
const llvm::APInt &size, ArraySizeModifier sm, unsigned tq)
- : ArrayType(tc, et, can, sm, tq, et->containsUnexpandedParameterPack()),
- Size(size) {}
- friend class ASTContext; // ASTContext creates these.
+ : ArrayType(tc, et, can, sm, tq, et->containsUnexpandedParameterPack()),
+ Size(size) {}
+
public:
const llvm::APInt &getSize() const { return Size; }
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
-
/// \brief Determine the number of bits required to address a member of
// an array with the given element type and number of elements.
static unsigned getNumAddressingBits(const ASTContext &Context,
@@ -2584,6 +2653,7 @@ public:
Profile(ID, getElementType(), getSize(),
getSizeModifier(), getIndexTypeCVRQualifiers());
}
+
static void Profile(llvm::FoldingSetNodeID &ID, QualType ET,
const llvm::APInt &ArraySize, ArraySizeModifier SizeMod,
unsigned TypeQuals) {
@@ -2592,6 +2662,7 @@ public:
ID.AddInteger(SizeMod);
ID.AddInteger(TypeQuals);
}
+
static bool classof(const Type *T) {
return T->getTypeClass() == ConstantArray;
}
@@ -2601,13 +2672,16 @@ public:
/// an IncompleteArrayType where the element type is 'int' and the size is
/// unspecified.
class IncompleteArrayType : public ArrayType {
+ friend class ASTContext; // ASTContext creates these.
IncompleteArrayType(QualType et, QualType can,
ArraySizeModifier sm, unsigned tq)
- : ArrayType(IncompleteArray, et, can, sm, tq,
- et->containsUnexpandedParameterPack()) {}
- friend class ASTContext; // ASTContext creates these.
+ : ArrayType(IncompleteArray, et, can, sm, tq,
+ et->containsUnexpandedParameterPack()) {}
+
public:
+ friend class StmtIteratorBase;
+
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -2615,8 +2689,6 @@ public:
return T->getTypeClass() == IncompleteArray;
}
- friend class StmtIteratorBase;
-
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, getElementType(), getSizeModifier(),
getIndexTypeCVRQualifiers());
@@ -2644,28 +2716,32 @@ public:
/// ++x;
/// int Z[x];
/// }
-///
class VariableArrayType : public ArrayType {
+ friend class ASTContext; // ASTContext creates these.
+
/// An assignment-expression. VLA's are only permitted within
/// a function block.
Stmt *SizeExpr;
+
/// The range spanned by the left and right array brackets.
SourceRange Brackets;
VariableArrayType(QualType et, QualType can, Expr *e,
ArraySizeModifier sm, unsigned tq,
SourceRange brackets)
- : ArrayType(VariableArray, et, can, sm, tq,
- et->containsUnexpandedParameterPack()),
- SizeExpr((Stmt*) e), Brackets(brackets) {}
- friend class ASTContext; // ASTContext creates these.
+ : ArrayType(VariableArray, et, can, sm, tq,
+ et->containsUnexpandedParameterPack()),
+ SizeExpr((Stmt*) e), Brackets(brackets) {}
public:
+ friend class StmtIteratorBase;
+
Expr *getSizeExpr() const {
// We use C-style casts instead of cast<> here because we do not wish
// to have a dependency of Type.h on Stmt.h/Expr.h.
return (Expr*) SizeExpr;
}
+
SourceRange getBracketsRange() const { return Brackets; }
SourceLocation getLBracketLoc() const { return Brackets.getBegin(); }
SourceLocation getRBracketLoc() const { return Brackets.getEnd(); }
@@ -2677,8 +2753,6 @@ public:
return T->getTypeClass() == VariableArray;
}
- friend class StmtIteratorBase;
-
void Profile(llvm::FoldingSetNodeID &ID) {
llvm_unreachable("Cannot unique VariableArrayTypes.");
}
@@ -2698,6 +2772,8 @@ public:
/// until template instantiation occurs, at which point this will
/// become either a ConstantArrayType or a VariableArrayType.
class DependentSizedArrayType : public ArrayType {
+ friend class ASTContext; // ASTContext creates these.
+
const ASTContext &Context;
/// \brief An assignment expression that will instantiate to the
@@ -2714,14 +2790,15 @@ class DependentSizedArrayType : public ArrayType {
Expr *e, ArraySizeModifier sm, unsigned tq,
SourceRange brackets);
- friend class ASTContext; // ASTContext creates these.
-
public:
+ friend class StmtIteratorBase;
+
Expr *getSizeExpr() const {
// We use C-style casts instead of cast<> here because we do not wish
// to have a dependency of Type.h on Stmt.h/Expr.h.
return (Expr*) SizeExpr;
}
+
SourceRange getBracketsRange() const { return Brackets; }
SourceLocation getLBracketLoc() const { return Brackets.getBegin(); }
SourceLocation getRBracketLoc() const { return Brackets.getEnd(); }
@@ -2733,9 +2810,6 @@ public:
return T->getTypeClass() == DependentSizedArray;
}
- friend class StmtIteratorBase;
-
-
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, Context, getElementType(),
getSizeModifier(), getIndexTypeCVRQualifiers(), getSizeExpr());
@@ -2746,6 +2820,49 @@ public:
unsigned TypeQuals, Expr *E);
};
+/// Represents an extended address space qualifier where the input address space
+/// value is dependent. Non-dependent address spaces are not represented with a
+/// special Type subclass; they are stored on an ExtQuals node as part of a QualType.
+///
+/// For example:
+/// \code
+/// template<typename T, int AddrSpace>
+/// class AddressSpace {
+/// typedef T __attribute__((address_space(AddrSpace))) type;
+/// }
+/// \endcode
+class DependentAddressSpaceType : public Type, public llvm::FoldingSetNode {
+ friend class ASTContext;
+
+ const ASTContext &Context;
+ Expr *AddrSpaceExpr;
+ QualType PointeeType;
+ SourceLocation loc;
+
+ DependentAddressSpaceType(const ASTContext &Context, QualType PointeeType,
+ QualType can, Expr *AddrSpaceExpr,
+ SourceLocation loc);
+
+public:
+ Expr *getAddrSpaceExpr() const { return AddrSpaceExpr; }
+ QualType getPointeeType() const { return PointeeType; }
+ SourceLocation getAttributeLoc() const { return loc; }
+
+ bool isSugared() const { return false; }
+ QualType desugar() const { return QualType(this, 0); }
+
+ static bool classof(const Type *T) {
+ return T->getTypeClass() == DependentAddressSpace;
+ }
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, Context, getPointeeType(), getAddrSpaceExpr());
+ }
+
+ static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
+ QualType PointeeType, Expr *AddrSpaceExpr);
+};
+
/// Represents an extended vector type where either the type or size is
/// dependent.
///
@@ -2757,17 +2874,19 @@ public:
/// }
/// \endcode
class DependentSizedExtVectorType : public Type, public llvm::FoldingSetNode {
+ friend class ASTContext;
+
const ASTContext &Context;
Expr *SizeExpr;
+
/// The element type of the array.
QualType ElementType;
+
SourceLocation loc;
DependentSizedExtVectorType(const ASTContext &Context, QualType ElementType,
QualType can, Expr *SizeExpr, SourceLocation loc);
- friend class ASTContext;
-
public:
Expr *getSizeExpr() const { return SizeExpr; }
QualType getElementType() const { return ElementType; }
@@ -2797,14 +2916,28 @@ public:
class VectorType : public Type, public llvm::FoldingSetNode {
public:
enum VectorKind {
- GenericVector, ///< not a target-specific vector type
- AltiVecVector, ///< is AltiVec vector
- AltiVecPixel, ///< is AltiVec 'vector Pixel'
- AltiVecBool, ///< is AltiVec 'vector bool ...'
- NeonVector, ///< is ARM Neon vector
- NeonPolyVector ///< is ARM Neon polynomial vector
+ /// not a target-specific vector type
+ GenericVector,
+
+ /// is AltiVec vector
+ AltiVecVector,
+
+ /// is AltiVec 'vector Pixel'
+ AltiVecPixel,
+
+ /// is AltiVec 'vector bool ...'
+ AltiVecBool,
+
+ /// is ARM Neon vector
+ NeonVector,
+
+ /// is ARM Neon polynomial vector
+ NeonPolyVector
};
+
protected:
+ friend class ASTContext; // ASTContext creates these.
+
/// The element type of the vector.
QualType ElementType;
@@ -2814,12 +2947,10 @@ protected:
VectorType(TypeClass tc, QualType vecType, unsigned nElements,
QualType canonType, VectorKind vecKind);
- friend class ASTContext; // ASTContext creates these.
-
public:
-
QualType getElementType() const { return ElementType; }
unsigned getNumElements() const { return VectorTypeBits.NumElements; }
+
static bool isVectorSizeTooLarge(unsigned NumElements) {
return NumElements > VectorTypeBitfields::MaxNumElements;
}
@@ -2835,6 +2966,7 @@ public:
Profile(ID, getElementType(), getNumElements(),
getTypeClass(), getVectorKind());
}
+
static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType,
unsigned NumElements, TypeClass TypeClass,
VectorKind VecKind) {
@@ -2856,9 +2988,11 @@ public:
/// points (as .xyzw), colors (as .rgba), and textures (modeled after OpenGL
/// Shading Language).
class ExtVectorType : public VectorType {
- ExtVectorType(QualType vecType, unsigned nElements, QualType canonType) :
- VectorType(ExtVector, vecType, nElements, canonType, GenericVector) {}
- friend class ASTContext; // ASTContext creates these.
+ friend class ASTContext; // ASTContext creates these.
+
+ ExtVectorType(QualType vecType, unsigned nElements, QualType canonType)
+ : VectorType(ExtVector, vecType, nElements, canonType, GenericVector) {}
+
public:
static int getPointAccessorIdx(char c) {
switch (c) {
@@ -2869,6 +3003,7 @@ public:
case 'w': case 'a': return 3;
}
}
+
static int getNumericAccessorIdx(char c) {
switch (c) {
default: return -1;
@@ -2909,6 +3044,7 @@ public:
return unsigned(idx-1) < getNumElements();
return false;
}
+
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -2919,12 +3055,11 @@ public:
/// FunctionType - C99 6.7.5.3 - Function Declarators. This is the common base
/// class of FunctionNoProtoType and FunctionProtoType.
-///
class FunctionType : public Type {
// The type returned by the function.
QualType ResultType;
- public:
+public:
/// A class which abstracts out some details necessary for
/// making a call.
///
@@ -2946,6 +3081,8 @@ class FunctionType : public Type {
// * AST read and write
// * Codegen
class ExtInfo {
+ friend class FunctionType;
+
// Feel free to rearrange or add bits, but if you go over 11,
// you'll need to adjust both the Bits field below and
// Type::FunctionTypeBitfields.
@@ -2964,15 +3101,13 @@ class FunctionType : public Type {
RegParmOffset = 8
}; // Assumed to be the last field
- uint16_t Bits;
+ uint16_t Bits = CC_C;
ExtInfo(unsigned Bits) : Bits(static_cast<uint16_t>(Bits)) {}
- friend class FunctionType;
-
public:
- // Constructor with no defaults. Use this when you know that you
- // have all the elements (when reading an AST file for example).
+ // Constructor with no defaults. Use this when you know that you
+ // have all the elements (when reading an AST file for example).
ExtInfo(bool noReturn, bool hasRegParm, unsigned regParm, CallingConv cc,
bool producesResult, bool noCallerSavedRegs) {
assert((!hasRegParm || regParm < 7) && "Invalid regparm value");
@@ -2984,22 +3119,24 @@ class FunctionType : public Type {
// Constructor with all defaults. Use when for example creating a
// function known to use defaults.
- ExtInfo() : Bits(CC_C) { }
+ ExtInfo() = default;
// Constructor with just the calling convention, which is an important part
// of the canonical type.
- ExtInfo(CallingConv CC) : Bits(CC) { }
+ ExtInfo(CallingConv CC) : Bits(CC) {}
bool getNoReturn() const { return Bits & NoReturnMask; }
bool getProducesResult() const { return Bits & ProducesResultMask; }
bool getNoCallerSavedRegs() const { return Bits & NoCallerSavedRegsMask; }
bool getHasRegParm() const { return (Bits >> RegParmOffset) != 0; }
+
unsigned getRegParm() const {
unsigned RegParm = Bits >> RegParmOffset;
if (RegParm > 0)
--RegParm;
return RegParm;
}
+
CallingConv getCC() const { return CallingConv(Bits & CallConvMask); }
bool operator==(ExtInfo Other) const {
@@ -3054,11 +3191,12 @@ protected:
bool InstantiationDependent,
bool VariablyModified, bool ContainsUnexpandedParameterPack,
ExtInfo Info)
- : Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified,
- ContainsUnexpandedParameterPack),
- ResultType(res) {
+ : Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified,
+ ContainsUnexpandedParameterPack),
+ ResultType(res) {
FunctionTypeBits.ExtInfo = Info.Bits;
}
+
unsigned getTypeQuals() const { return FunctionTypeBits.TypeQuals; }
public:
@@ -3066,10 +3204,12 @@ public:
bool getHasRegParm() const { return getExtInfo().getHasRegParm(); }
unsigned getRegParmType() const { return getExtInfo().getRegParm(); }
+
/// Determine whether this function type includes the GNU noreturn
/// attribute. The C++11 [[noreturn]] attribute does not affect the function
/// type.
bool getNoReturnAttr() const { return getExtInfo().getNoReturn(); }
+
CallingConv getCallConv() const { return getExtInfo().getCC(); }
ExtInfo getExtInfo() const { return ExtInfo(FunctionTypeBits.ExtInfo); }
bool isConst() const { return getTypeQuals() & Qualifiers::Const; }
@@ -3093,13 +3233,13 @@ public:
/// Represents a K&R-style 'int foo()' function, which has
/// no information available about its arguments.
class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode {
- FunctionNoProtoType(QualType Result, QualType Canonical, ExtInfo Info)
- : FunctionType(FunctionNoProto, Result, Canonical,
- /*Dependent=*/false, /*InstantiationDependent=*/false,
- Result->isVariablyModifiedType(),
- /*ContainsUnexpandedParameterPack=*/false, Info) {}
+ friend class ASTContext; // ASTContext creates these.
- friend class ASTContext; // ASTContext creates these.
+ FunctionNoProtoType(QualType Result, QualType Canonical, ExtInfo Info)
+ : FunctionType(FunctionNoProto, Result, Canonical,
+ /*Dependent=*/false, /*InstantiationDependent=*/false,
+ Result->isVariablyModifiedType(),
+ /*ContainsUnexpandedParameterPack=*/false, Info) {}
public:
// No additional state past what FunctionType provides.
@@ -3110,6 +3250,7 @@ public:
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, getReturnType(), getExtInfo());
}
+
static void Profile(llvm::FoldingSetNodeID &ID, QualType ResultType,
ExtInfo Info) {
Info.Profile(ID);
@@ -3152,11 +3293,12 @@ public:
ABIMask = 0x0F,
IsConsumed = 0x10,
HasPassObjSize = 0x20,
+ IsNoEscape = 0x40,
};
- unsigned char Data;
+ unsigned char Data = 0;
public:
- ExtParameterInfo() : Data(0) {}
+ ExtParameterInfo() = default;
/// Return the ABI treatment of this parameter.
ParameterABI getABI() const {
@@ -3192,6 +3334,19 @@ public:
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;
@@ -3208,54 +3363,54 @@ public:
};
struct ExceptionSpecInfo {
- ExceptionSpecInfo()
- : Type(EST_None), NoexceptExpr(nullptr),
- SourceDecl(nullptr), SourceTemplate(nullptr) {}
-
- ExceptionSpecInfo(ExceptionSpecificationType EST)
- : Type(EST), NoexceptExpr(nullptr), SourceDecl(nullptr),
- SourceTemplate(nullptr) {}
-
/// The kind of exception specification this is.
- ExceptionSpecificationType Type;
+ ExceptionSpecificationType Type = EST_None;
+
/// Explicitly-specified list of exception types.
ArrayRef<QualType> Exceptions;
+
/// Noexcept expression, if this is EST_ComputedNoexcept.
- Expr *NoexceptExpr;
+ Expr *NoexceptExpr = nullptr;
+
/// The function whose exception specification this is, for
/// EST_Unevaluated and EST_Uninstantiated.
- FunctionDecl *SourceDecl;
+ FunctionDecl *SourceDecl = nullptr;
+
/// The function template whose exception specification this is instantiated
/// from, for EST_Uninstantiated.
- FunctionDecl *SourceTemplate;
+ FunctionDecl *SourceTemplate = nullptr;
+
+ ExceptionSpecInfo() = default;
+
+ ExceptionSpecInfo(ExceptionSpecificationType EST) : Type(EST) {}
};
/// Extra information about a function prototype.
struct ExtProtoInfo {
+ FunctionType::ExtInfo ExtInfo;
+ bool Variadic : 1;
+ bool HasTrailingReturn : 1;
+ unsigned char TypeQuals = 0;
+ RefQualifierKind RefQualifier = RQ_None;
+ ExceptionSpecInfo ExceptionSpec;
+ const ExtParameterInfo *ExtParameterInfos = nullptr;
+
ExtProtoInfo()
- : Variadic(false), HasTrailingReturn(false), TypeQuals(0),
- RefQualifier(RQ_None), ExtParameterInfos(nullptr) {}
+ : Variadic(false), HasTrailingReturn(false) {}
ExtProtoInfo(CallingConv CC)
- : ExtInfo(CC), Variadic(false), HasTrailingReturn(false), TypeQuals(0),
- RefQualifier(RQ_None), ExtParameterInfos(nullptr) {}
+ : ExtInfo(CC), Variadic(false), HasTrailingReturn(false) {}
ExtProtoInfo withExceptionSpec(const ExceptionSpecInfo &O) {
ExtProtoInfo Result(*this);
Result.ExceptionSpec = O;
return Result;
}
-
- FunctionType::ExtInfo ExtInfo;
- bool Variadic : 1;
- bool HasTrailingReturn : 1;
- unsigned char TypeQuals;
- RefQualifierKind RefQualifier;
- ExceptionSpecInfo ExceptionSpec;
- const ExtParameterInfo *ExtParameterInfos;
};
private:
+ friend class ASTContext; // ASTContext creates these.
+
/// \brief Determine whether there are any argument types that
/// contain an unexpanded parameter pack.
static bool containsAnyUnexpandedParameterPack(const QualType *ArgArray,
@@ -3307,8 +3462,6 @@ private:
// for each of the parameters. This only appears if HasExtParameterInfos
// is true.
- friend class ASTContext; // ASTContext creates these.
-
const ExtParameterInfo *getExtParameterInfosBuffer() const {
assert(hasExtParameterInfos());
@@ -3336,10 +3489,12 @@ private:
public:
unsigned getNumParams() const { return NumParams; }
+
QualType getParamType(unsigned i) const {
assert(i < NumParams && "invalid parameter index");
return param_type_begin()[i];
}
+
ArrayRef<QualType> getParamTypes() const {
return llvm::makeArrayRef(param_type_begin(), param_type_end());
}
@@ -3371,31 +3526,47 @@ public:
ExceptionSpecificationType getExceptionSpecType() const {
return static_cast<ExceptionSpecificationType>(ExceptionSpecType);
}
+
/// Return whether this function has any kind of exception spec.
bool hasExceptionSpec() const {
return getExceptionSpecType() != EST_None;
}
+
/// Return whether this function has a dynamic (throw) exception spec.
bool hasDynamicExceptionSpec() const {
return isDynamicExceptionSpec(getExceptionSpecType());
}
+
/// Return whether this function has a noexcept exception spec.
bool hasNoexceptExceptionSpec() const {
return isNoexceptExceptionSpec(getExceptionSpecType());
}
+
/// Return whether this function has a dependent exception spec.
bool hasDependentExceptionSpec() const;
+
/// Return whether this function has an instantiation-dependent exception
/// spec.
bool hasInstantiationDependentExceptionSpec() const;
+
/// Result type of getNoexceptSpec().
enum NoexceptResult {
- NR_NoNoexcept, ///< There is no noexcept specifier.
- NR_BadNoexcept, ///< The noexcept specifier has a bad expression.
- NR_Dependent, ///< The noexcept specifier is dependent.
- NR_Throw, ///< The noexcept specifier evaluates to false.
- NR_Nothrow ///< The noexcept specifier evaluates to true.
+ /// There is no noexcept specifier.
+ NR_NoNoexcept,
+
+ /// The noexcept specifier has a bad expression.
+ NR_BadNoexcept,
+
+ /// The noexcept specifier is dependent.
+ NR_Dependent,
+
+ /// The noexcept specifier evaluates to false.
+ NR_Throw,
+
+ /// The noexcept specifier evaluates to true.
+ NR_Nothrow
};
+
/// Get the meaning of the noexcept spec on this function, if any.
NoexceptResult getNoexceptSpec(const ASTContext &Ctx) const;
unsigned getNumExceptions() const { return NumExceptions; }
@@ -3409,6 +3580,7 @@ public:
// NoexceptExpr sits where the arguments end.
return *reinterpret_cast<Expr *const *>(param_type_end());
}
+
/// \brief If this function type has an exception specification which hasn't
/// been determined yet (either because it has not been evaluated or because
/// it has not been instantiated), this is the function whose exception
@@ -3419,6 +3591,7 @@ public:
return nullptr;
return reinterpret_cast<FunctionDecl *const *>(param_type_end())[0];
}
+
/// \brief If this function type has an uninstantiated exception
/// specification, this is the function whose exception specification
/// should be instantiated to find the exception specification for
@@ -3428,9 +3601,11 @@ public:
return nullptr;
return reinterpret_cast<FunctionDecl *const *>(param_type_end())[1];
}
+
/// Determine whether this function type has a non-throwing exception
/// specification.
CanThrowResult canThrow(const ASTContext &Ctx) const;
+
/// Determine whether this function type has a non-throwing exception
/// specification. If this depends on template arguments, returns
/// \c ResultIfDependent.
@@ -3453,34 +3628,37 @@ public:
unsigned getTypeQuals() const { return FunctionType::getTypeQuals(); }
-
/// Retrieve the ref-qualifier associated with this function type.
RefQualifierKind getRefQualifier() const {
return static_cast<RefQualifierKind>(FunctionTypeBits.RefQualifier);
}
- typedef const QualType *param_type_iterator;
- typedef llvm::iterator_range<param_type_iterator> param_type_range;
+ using param_type_iterator = const QualType *;
+ using param_type_range = llvm::iterator_range<param_type_iterator>;
param_type_range param_types() const {
return param_type_range(param_type_begin(), param_type_end());
}
+
param_type_iterator param_type_begin() const {
return reinterpret_cast<const QualType *>(this+1);
}
+
param_type_iterator param_type_end() const {
return param_type_begin() + NumParams;
}
- typedef const QualType *exception_iterator;
+ using exception_iterator = const QualType *;
ArrayRef<QualType> exceptions() const {
return llvm::makeArrayRef(exception_begin(), exception_end());
}
+
exception_iterator exception_begin() const {
// exceptions begin where arguments end
return param_type_end();
}
+
exception_iterator exception_end() const {
if (getExceptionSpecType() != EST_Dynamic)
return exception_begin();
@@ -3495,6 +3673,7 @@ public:
return ArrayRef<ExtParameterInfo>(getExtParameterInfosBuffer(),
getNumParams());
}
+
/// Return a pointer to the beginning of the array of extra parameter
/// information, if present, or else null if none of the parameters
/// carry it. This is equivalent to getExtProtoInfo().ExtParameterInfos.
@@ -3548,15 +3727,16 @@ public:
///
/// Template instantiation turns these into the underlying type.
class UnresolvedUsingType : public Type {
+ friend class ASTContext; // ASTContext creates these.
+
UnresolvedUsingTypenameDecl *Decl;
UnresolvedUsingType(const UnresolvedUsingTypenameDecl *D)
- : Type(UnresolvedUsing, QualType(), true, true, false,
- /*ContainsUnexpandedParameterPack=*/false),
- Decl(const_cast<UnresolvedUsingTypenameDecl*>(D)) {}
- friend class ASTContext; // ASTContext creates these.
-public:
+ : Type(UnresolvedUsing, QualType(), true, true, false,
+ /*ContainsUnexpandedParameterPack=*/false),
+ Decl(const_cast<UnresolvedUsingTypenameDecl*>(D)) {}
+public:
UnresolvedUsingTypenameDecl *getDecl() const { return Decl; }
bool isSugared() const { return false; }
@@ -3569,27 +3749,29 @@ public:
void Profile(llvm::FoldingSetNodeID &ID) {
return Profile(ID, Decl);
}
+
static void Profile(llvm::FoldingSetNodeID &ID,
UnresolvedUsingTypenameDecl *D) {
ID.AddPointer(D);
}
};
-
class TypedefType : public Type {
TypedefNameDecl *Decl;
+
protected:
+ friend class ASTContext; // ASTContext creates these.
+
TypedefType(TypeClass tc, const TypedefNameDecl *D, QualType can)
- : Type(tc, can, can->isDependentType(),
- can->isInstantiationDependentType(),
- can->isVariablyModifiedType(),
- /*ContainsUnexpandedParameterPack=*/false),
- Decl(const_cast<TypedefNameDecl*>(D)) {
+ : Type(tc, can, can->isDependentType(),
+ can->isInstantiationDependentType(),
+ can->isVariablyModifiedType(),
+ /*ContainsUnexpandedParameterPack=*/false),
+ Decl(const_cast<TypedefNameDecl*>(D)) {
assert(!isa<TypedefType>(can) && "Invalid canonical type");
}
- friend class ASTContext; // ASTContext creates these.
-public:
+public:
TypedefNameDecl *getDecl() const { return Decl; }
bool isSugared() const { return true; }
@@ -3603,8 +3785,10 @@ class TypeOfExprType : public Type {
Expr *TOExpr;
protected:
+ friend class ASTContext; // ASTContext creates these.
+
TypeOfExprType(Expr *E, QualType can = QualType());
- friend class ASTContext; // ASTContext creates these.
+
public:
Expr *getUnderlyingExpr() const { return TOExpr; }
@@ -3629,7 +3813,7 @@ class DependentTypeOfExprType
public:
DependentTypeOfExprType(const ASTContext &Context, Expr *E)
- : TypeOfExprType(E), Context(Context) { }
+ : TypeOfExprType(E), Context(Context) {}
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, Context, getUnderlyingExpr());
@@ -3641,16 +3825,19 @@ public:
/// Represents `typeof(type)`, a GCC extension.
class TypeOfType : public Type {
+ friend class ASTContext; // ASTContext creates these.
+
QualType TOType;
+
TypeOfType(QualType T, QualType can)
- : Type(TypeOf, can, T->isDependentType(),
- T->isInstantiationDependentType(),
- T->isVariablyModifiedType(),
- T->containsUnexpandedParameterPack()),
- TOType(T) {
+ : Type(TypeOf, can, T->isDependentType(),
+ T->isInstantiationDependentType(),
+ T->isVariablyModifiedType(),
+ T->containsUnexpandedParameterPack()),
+ TOType(T) {
assert(!isa<TypedefType>(can) && "Invalid canonical type");
}
- friend class ASTContext; // ASTContext creates these.
+
public:
QualType getUnderlyingType() const { return TOType; }
@@ -3669,8 +3856,10 @@ class DecltypeType : public Type {
QualType UnderlyingType;
protected:
+ friend class ASTContext; // ASTContext creates these.
+
DecltypeType(Expr *E, QualType underlyingType, QualType can = QualType());
- friend class ASTContext; // ASTContext creates these.
+
public:
Expr *getUnderlyingExpr() const { return E; }
QualType getUnderlyingType() const { return UnderlyingType; }
@@ -3714,14 +3903,18 @@ public:
private:
/// The untransformed type.
QualType BaseType;
+
/// The transformed type if not dependent, otherwise the same as BaseType.
QualType UnderlyingType;
UTTKind UKind;
+
protected:
+ friend class ASTContext;
+
UnaryTransformType(QualType BaseTy, QualType UnderlyingTy, UTTKind UKind,
QualType CanonicalTy);
- friend class ASTContext;
+
public:
bool isSugared() const { return !isDependentType(); }
QualType desugar() const { return UnderlyingType; }
@@ -3747,6 +3940,7 @@ class DependentUnaryTransformType : public UnaryTransformType,
public:
DependentUnaryTransformType(const ASTContext &C, QualType BaseType,
UTTKind UKind);
+
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, getBaseType(), getUTTKind());
}
@@ -3759,11 +3953,11 @@ public:
};
class TagType : public Type {
+ friend class ASTReader;
+
/// Stores the TagDecl associated with this type. The decl may point to any
/// TagDecl that declares the entity.
- TagDecl * decl;
-
- friend class ASTReader;
+ TagDecl *decl;
protected:
TagType(TypeClass TC, const TagDecl *D, QualType can);
@@ -3783,21 +3977,21 @@ public:
/// to detect TagType objects of structs/unions/classes.
class RecordType : public TagType {
protected:
+ friend class ASTContext; // ASTContext creates these.
+
explicit RecordType(const RecordDecl *D)
- : TagType(Record, reinterpret_cast<const TagDecl*>(D), QualType()) { }
+ : TagType(Record, reinterpret_cast<const TagDecl*>(D), QualType()) {}
explicit RecordType(TypeClass TC, RecordDecl *D)
- : TagType(TC, reinterpret_cast<const TagDecl*>(D), QualType()) { }
- friend class ASTContext; // ASTContext creates these.
-public:
+ : TagType(TC, reinterpret_cast<const TagDecl*>(D), QualType()) {}
+public:
RecordDecl *getDecl() const {
return reinterpret_cast<RecordDecl*>(TagType::getDecl());
}
- // FIXME: This predicate is a helper to QualType/Type. It needs to
- // recursively check all fields for const-ness. If any field is declared
- // const, it needs to return false.
- bool hasConstFields() const { return false; }
+ /// Recursively check all fields in the record for const-ness. If any field
+ /// is declared const, return true. Otherwise, return false.
+ bool hasConstFields() const;
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -3808,11 +4002,12 @@ public:
/// A helper class that allows the use of isa/cast/dyncast
/// to detect TagType objects of enums.
class EnumType : public TagType {
+ friend class ASTContext; // ASTContext creates these.
+
explicit EnumType(const EnumDecl *D)
- : TagType(Enum, reinterpret_cast<const TagDecl*>(D), QualType()) { }
- friend class ASTContext; // ASTContext creates these.
-public:
+ : TagType(Enum, reinterpret_cast<const TagDecl*>(D), QualType()) {}
+public:
EnumDecl *getDecl() const {
return reinterpret_cast<EnumDecl*>(TagType::getDecl());
}
@@ -3887,11 +4082,11 @@ public:
};
private:
+ friend class ASTContext; // ASTContext creates these
+
QualType ModifiedType;
QualType EquivalentType;
- friend class ASTContext; // creates these
-
AttributedType(QualType canon, Kind attrKind, QualType modified,
QualType equivalent)
: Type(Attributed, canon, equivalent->isDependentType(),
@@ -3980,6 +4175,8 @@ public:
};
class TemplateTypeParmType : public Type, public llvm::FoldingSetNode {
+ friend class ASTContext; // ASTContext creates these
+
// Helper data collector for canonical types.
struct CanonicalTTPTInfo {
unsigned Depth : 15;
@@ -3990,31 +4187,30 @@ class TemplateTypeParmType : public Type, public llvm::FoldingSetNode {
union {
// Info for the canonical type.
CanonicalTTPTInfo CanTTPTInfo;
+
// Info for the non-canonical type.
TemplateTypeParmDecl *TTPDecl;
};
/// Build a non-canonical type.
TemplateTypeParmType(TemplateTypeParmDecl *TTPDecl, QualType Canon)
- : Type(TemplateTypeParm, Canon, /*Dependent=*/true,
- /*InstantiationDependent=*/true,
- /*VariablyModified=*/false,
- Canon->containsUnexpandedParameterPack()),
- TTPDecl(TTPDecl) { }
+ : Type(TemplateTypeParm, Canon, /*Dependent=*/true,
+ /*InstantiationDependent=*/true,
+ /*VariablyModified=*/false,
+ Canon->containsUnexpandedParameterPack()),
+ TTPDecl(TTPDecl) {}
/// Build the canonical type.
TemplateTypeParmType(unsigned D, unsigned I, bool PP)
- : Type(TemplateTypeParm, QualType(this, 0),
- /*Dependent=*/true,
- /*InstantiationDependent=*/true,
- /*VariablyModified=*/false, PP) {
+ : Type(TemplateTypeParm, QualType(this, 0),
+ /*Dependent=*/true,
+ /*InstantiationDependent=*/true,
+ /*VariablyModified=*/false, PP) {
CanTTPTInfo.Depth = D;
CanTTPTInfo.Index = I;
CanTTPTInfo.ParameterPack = PP;
}
- friend class ASTContext; // ASTContext creates these
-
const CanonicalTTPTInfo& getCanTTPTInfo() const {
QualType Can = getCanonicalTypeInternal();
return Can->castAs<TemplateTypeParmType>()->CanTTPTInfo;
@@ -4060,17 +4256,17 @@ public:
/// type was originally written as a template type parameter;
/// therefore they are never canonical.
class SubstTemplateTypeParmType : public Type, public llvm::FoldingSetNode {
+ friend class ASTContext;
+
// The original type parameter.
const TemplateTypeParmType *Replaced;
SubstTemplateTypeParmType(const TemplateTypeParmType *Param, QualType Canon)
- : Type(SubstTemplateTypeParm, Canon, Canon->isDependentType(),
- Canon->isInstantiationDependentType(),
- Canon->isVariablyModifiedType(),
- Canon->containsUnexpandedParameterPack()),
- Replaced(Param) { }
-
- friend class ASTContext;
+ : Type(SubstTemplateTypeParm, Canon, Canon->isDependentType(),
+ Canon->isInstantiationDependentType(),
+ Canon->isVariablyModifiedType(),
+ Canon->containsUnexpandedParameterPack()),
+ Replaced(Param) {}
public:
/// Gets the template parameter that was substituted for.
@@ -4090,6 +4286,7 @@ public:
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, getReplacedParameter(), getReplacementType());
}
+
static void Profile(llvm::FoldingSetNodeID &ID,
const TemplateTypeParmType *Replaced,
QualType Replacement) {
@@ -4115,6 +4312,8 @@ public:
/// arguments), this type will be replaced with the \c SubstTemplateTypeParmType
/// at the current pack substitution index.
class SubstTemplateTypeParmPackType : public Type, public llvm::FoldingSetNode {
+ friend class ASTContext;
+
/// \brief The original type parameter.
const TemplateTypeParmType *Replaced;
@@ -4129,8 +4328,6 @@ class SubstTemplateTypeParmPackType : public Type, public llvm::FoldingSetNode {
QualType Canon,
const TemplateArgument &ArgPack);
- friend class ASTContext;
-
public:
IdentifierInfo *getIdentifier() const { return Replaced->getIdentifier(); }
@@ -4204,6 +4401,8 @@ public:
/// \brief Represents a C++11 auto or C++14 decltype(auto) type.
class AutoType : public DeducedType, public llvm::FoldingSetNode {
+ friend class ASTContext; // ASTContext creates these
+
AutoType(QualType DeducedAsType, AutoTypeKeyword Keyword,
bool IsDeducedAsDependent)
: DeducedType(Auto, DeducedAsType, IsDeducedAsDependent,
@@ -4211,12 +4410,11 @@ class AutoType : public DeducedType, public llvm::FoldingSetNode {
AutoTypeBits.Keyword = (unsigned)Keyword;
}
- friend class ASTContext; // ASTContext creates these
-
public:
bool isDecltypeAuto() const {
return getKeyword() == AutoTypeKeyword::DecltypeAuto;
}
+
AutoTypeKeyword getKeyword() const {
return (AutoTypeKeyword)AutoTypeBits.Keyword;
}
@@ -4240,6 +4438,8 @@ public:
/// \brief Represents a C++17 deduced template specialization type.
class DeducedTemplateSpecializationType : public DeducedType,
public llvm::FoldingSetNode {
+ friend class ASTContext; // ASTContext creates these
+
/// The name of the template whose arguments will be deduced.
TemplateName Template;
@@ -4252,8 +4452,6 @@ class DeducedTemplateSpecializationType : public DeducedType,
Template.containsUnexpandedParameterPack()),
Template(Template) {}
- friend class ASTContext; // ASTContext creates these
-
public:
/// Retrieve the name of the template that we are deducing.
TemplateName getTemplateName() const { return Template;}
@@ -4297,6 +4495,8 @@ public:
class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) TemplateSpecializationType
: public Type,
public llvm::FoldingSetNode {
+ friend class ASTContext; // ASTContext creates these
+
/// The name of the template being specialized. This is
/// either a TemplateName::Template (in which case it is a
/// ClassTemplateDecl*, a TemplateTemplateParmDecl*, or a
@@ -4318,8 +4518,6 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) TemplateSpecializationType
QualType Canon,
QualType Aliased);
- friend class ASTContext; // ASTContext creates these
-
public:
/// Determine whether any of the given template arguments are dependent.
static bool anyDependentTemplateArguments(ArrayRef<TemplateArgumentLoc> Args,
@@ -4328,21 +4526,6 @@ public:
static bool anyDependentTemplateArguments(const TemplateArgumentListInfo &,
bool &InstantiationDependent);
- /// \brief Print a template argument list, including the '<' and '>'
- /// enclosing the template arguments.
- static void PrintTemplateArgumentList(raw_ostream &OS,
- ArrayRef<TemplateArgument> Args,
- const PrintingPolicy &Policy,
- bool SkipBrackets = false);
-
- static void PrintTemplateArgumentList(raw_ostream &OS,
- ArrayRef<TemplateArgumentLoc> Args,
- const PrintingPolicy &Policy);
-
- static void PrintTemplateArgumentList(raw_ostream &OS,
- const TemplateArgumentListInfo &,
- const PrintingPolicy &Policy);
-
/// True if this template specialization type matches a current
/// instantiation in the context in which it is found.
bool isCurrentInstantiation() const {
@@ -4373,7 +4556,7 @@ public:
return *reinterpret_cast<const QualType*>(end());
}
- typedef const TemplateArgument * iterator;
+ using iterator = const TemplateArgument *;
iterator begin() const { return getArgs(); }
iterator end() const; // defined inline in TemplateBase.h
@@ -4400,6 +4583,7 @@ public:
bool isSugared() const {
return !isDependentType() || isCurrentInstantiation() || isTypeAlias();
}
+
QualType desugar() const { return getCanonicalTypeInternal(); }
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx) {
@@ -4417,6 +4601,20 @@ public:
}
};
+/// \brief Print a template argument list, including the '<' and '>'
+/// enclosing the template arguments.
+void printTemplateArgumentList(raw_ostream &OS,
+ ArrayRef<TemplateArgument> Args,
+ const PrintingPolicy &Policy);
+
+void printTemplateArgumentList(raw_ostream &OS,
+ ArrayRef<TemplateArgumentLoc> Args,
+ const PrintingPolicy &Policy);
+
+void printTemplateArgumentList(raw_ostream &OS,
+ const TemplateArgumentListInfo &Args,
+ const PrintingPolicy &Policy);
+
/// The injected class name of a C++ class template or class
/// template partial specialization. Used to record that a type was
/// spelled with a bare identifier rather than as a template-id; the
@@ -4435,6 +4633,12 @@ public:
/// will canonicalize to the injected class name (when appropriate
/// according to the rules of the language).
class InjectedClassNameType : public Type {
+ friend class ASTContext; // ASTContext creates these.
+ friend class ASTNodeImporter;
+ friend class ASTReader; // FIXME: ASTContext::getInjectedClassNameType is not
+ // currently suitable for AST reading, too much
+ // interdependencies.
+
CXXRecordDecl *Decl;
/// The template specialization which this type represents.
@@ -4448,18 +4652,12 @@ class InjectedClassNameType : public Type {
/// and always dependent.
QualType InjectedType;
- friend class ASTContext; // ASTContext creates these.
- friend class ASTReader; // FIXME: ASTContext::getInjectedClassNameType is not
- // currently suitable for AST reading, too much
- // interdependencies.
- friend class ASTNodeImporter;
-
InjectedClassNameType(CXXRecordDecl *D, QualType TST)
- : Type(InjectedClassName, QualType(), /*Dependent=*/true,
- /*InstantiationDependent=*/true,
- /*VariablyModified=*/false,
- /*ContainsUnexpandedParameterPack=*/false),
- Decl(D), InjectedType(TST) {
+ : Type(InjectedClassName, QualType(), /*Dependent=*/true,
+ /*InstantiationDependent=*/true,
+ /*VariablyModified=*/false,
+ /*ContainsUnexpandedParameterPack=*/false),
+ Decl(D), InjectedType(TST) {
assert(isa<TemplateSpecializationType>(TST));
assert(!TST.hasQualifiers());
assert(TST->isDependentType());
@@ -4467,9 +4665,11 @@ class InjectedClassNameType : public Type {
public:
QualType getInjectedSpecializationType() const { return InjectedType; }
+
const TemplateSpecializationType *getInjectedTST() const {
return cast<TemplateSpecializationType>(InjectedType.getTypePtr());
}
+
TemplateName getTemplateName() const {
return getInjectedTST()->getTemplateName();
}
@@ -4488,12 +4688,16 @@ public:
enum TagTypeKind {
/// \brief The "struct" keyword.
TTK_Struct,
+
/// \brief The "__interface" keyword.
TTK_Interface,
+
/// \brief The "union" keyword.
TTK_Union,
+
/// \brief The "class" keyword.
TTK_Class,
+
/// \brief The "enum" keyword.
TTK_Enum
};
@@ -4503,17 +4707,23 @@ enum TagTypeKind {
enum ElaboratedTypeKeyword {
/// \brief The "struct" keyword introduces the elaborated-type-specifier.
ETK_Struct,
+
/// \brief The "__interface" keyword introduces the elaborated-type-specifier.
ETK_Interface,
+
/// \brief The "union" keyword introduces the elaborated-type-specifier.
ETK_Union,
+
/// \brief The "class" keyword introduces the elaborated-type-specifier.
ETK_Class,
+
/// \brief The "enum" keyword introduces the elaborated-type-specifier.
ETK_Enum,
+
/// \brief The "typename" keyword precedes the qualified type name, e.g.,
/// \c typename T::type.
ETK_Typename,
+
/// \brief No keyword precedes the qualified type name.
ETK_None
};
@@ -4528,8 +4738,8 @@ protected:
QualType Canonical, bool Dependent,
bool InstantiationDependent, bool VariablyModified,
bool ContainsUnexpandedParameterPack)
- : Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified,
- ContainsUnexpandedParameterPack) {
+ : Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified,
+ ContainsUnexpandedParameterPack) {
TypeWithKeywordBits.Keyword = Keyword;
}
@@ -4574,6 +4784,7 @@ public:
/// 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 {
+ friend class ASTContext; // ASTContext creates these
/// The nested name specifier containing the qualifier.
NestedNameSpecifier *NNS;
@@ -4594,8 +4805,6 @@ class ElaboratedType : public TypeWithKeyword, public llvm::FoldingSetNode {
"and name qualifier both null.");
}
- friend class ASTContext; // ASTContext creates these
-
public:
~ElaboratedType();
@@ -4640,6 +4849,7 @@ public:
/// mode, this type is used with non-dependent names to delay name lookup until
/// instantiation.
class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode {
+ friend class ASTContext; // ASTContext creates these
/// \brief The nested name specifier containing the qualifier.
NestedNameSpecifier *NNS;
@@ -4649,13 +4859,11 @@ class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode {
DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
const IdentifierInfo *Name, QualType CanonType)
- : TypeWithKeyword(Keyword, DependentName, CanonType, /*Dependent=*/true,
- /*InstantiationDependent=*/true,
- /*VariablyModified=*/false,
- NNS->containsUnexpandedParameterPack()),
- NNS(NNS), Name(Name) {}
-
- friend class ASTContext; // ASTContext creates these
+ : TypeWithKeyword(Keyword, DependentName, CanonType, /*Dependent=*/true,
+ /*InstantiationDependent=*/true,
+ /*VariablyModified=*/false,
+ NNS->containsUnexpandedParameterPack()),
+ NNS(NNS), Name(Name) {}
public:
/// Retrieve the qualification on this type.
@@ -4695,6 +4903,7 @@ public:
class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) DependentTemplateSpecializationType
: public TypeWithKeyword,
public llvm::FoldingSetNode {
+ friend class ASTContext; // ASTContext creates these
/// The nested name specifier containing the qualifier.
NestedNameSpecifier *NNS;
@@ -4706,20 +4915,19 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) DependentTemplateSpecializationType
/// specialization.
unsigned NumArgs;
- const TemplateArgument *getArgBuffer() const {
- return reinterpret_cast<const TemplateArgument*>(this+1);
- }
- TemplateArgument *getArgBuffer() {
- return reinterpret_cast<TemplateArgument*>(this+1);
- }
-
DependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
NestedNameSpecifier *NNS,
const IdentifierInfo *Name,
ArrayRef<TemplateArgument> Args,
QualType Canon);
- friend class ASTContext; // ASTContext creates these
+ const TemplateArgument *getArgBuffer() const {
+ return reinterpret_cast<const TemplateArgument*>(this+1);
+ }
+
+ TemplateArgument *getArgBuffer() {
+ return reinterpret_cast<TemplateArgument*>(this+1);
+ }
public:
NestedNameSpecifier *getQualifier() const { return NNS; }
@@ -4739,7 +4947,8 @@ public:
return {getArgs(), NumArgs};
}
- typedef const TemplateArgument * iterator;
+ using iterator = const TemplateArgument *;
+
iterator begin() const { return getArgs(); }
iterator end() const; // inline in TemplateBase.h
@@ -4785,6 +4994,8 @@ public:
/// Here, the pack expansion \c Types&... is represented via a
/// PackExpansionType whose pattern is Types&.
class PackExpansionType : public Type, public llvm::FoldingSetNode {
+ friend class ASTContext; // ASTContext creates these
+
/// \brief The pattern of the pack expansion.
QualType Pattern;
@@ -4798,14 +5009,12 @@ class PackExpansionType : public Type, public llvm::FoldingSetNode {
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) { }
-
- friend class ASTContext; // ASTContext creates these
+ : Type(PackExpansion, Canon, /*Dependent=*/Pattern->isDependentType(),
+ /*InstantiationDependent=*/true,
+ /*VariablyModified=*/Pattern->isVariablyModifiedType(),
+ /*ContainsUnexpandedParameterPack=*/false),
+ Pattern(Pattern),
+ NumExpansions(NumExpansions ? *NumExpansions + 1 : 0) {}
public:
/// \brief Retrieve the pattern of this pack expansion, which is the
@@ -4847,7 +5056,8 @@ public:
template <class T>
class ObjCProtocolQualifiers {
protected:
- ObjCProtocolQualifiers() {}
+ ObjCProtocolQualifiers() = default;
+
ObjCProtocolDecl * const *getProtocolStorage() const {
return const_cast<ObjCProtocolQualifiers*>(this)->getProtocolStorage();
}
@@ -4855,9 +5065,11 @@ protected:
ObjCProtocolDecl **getProtocolStorage() {
return static_cast<T*>(this)->getProtocolStorageImpl();
}
+
void setNumProtocols(unsigned N) {
static_cast<T*>(this)->setNumProtocolsImpl(N);
}
+
void initialize(ArrayRef<ObjCProtocolDecl *> protocols) {
setNumProtocols(protocols.size());
assert(getNumProtocols() == protocols.size() &&
@@ -4868,8 +5080,8 @@ protected:
}
public:
- typedef ObjCProtocolDecl * const *qual_iterator;
- typedef llvm::iterator_range<qual_iterator> qual_range;
+ using qual_iterator = ObjCProtocolDecl * const *;
+ using qual_range = llvm::iterator_range<qual_iterator>;
qual_range quals() const { return qual_range(qual_begin(), qual_end()); }
qual_iterator qual_begin() const { return getProtocolStorage(); }
@@ -4907,21 +5119,26 @@ class ObjCTypeParamType : public Type,
unsigned NumProtocols : 6;
ObjCTypeParamDecl *OTPDecl;
+
/// The protocols are stored after the ObjCTypeParamType node. In the
/// canonical type, the list of protocols are sorted alphabetically
/// and uniqued.
ObjCProtocolDecl **getProtocolStorageImpl();
+
/// Return the number of qualifying protocols in this interface type,
/// or 0 if there are none.
unsigned getNumProtocolsImpl() const {
return NumProtocols;
}
+
void setNumProtocolsImpl(unsigned N) {
NumProtocols = N;
}
+
ObjCTypeParamType(const ObjCTypeParamDecl *D,
QualType can,
ArrayRef<ObjCProtocolDecl *> protocols);
+
public:
bool isSugared() const { return true; }
QualType desugar() const { return getCanonicalTypeInternal(); }
@@ -4969,6 +5186,7 @@ public:
class ObjCObjectType : public Type,
public ObjCProtocolQualifiers<ObjCObjectType> {
friend class ObjCProtocolQualifiers<ObjCObjectType>;
+
// ObjCObjectType.NumTypeArgs - the number of type arguments stored
// after the ObjCObjectPointerType node.
// ObjCObjectType.NumProtocols - the number of protocols stored
@@ -5004,15 +5222,16 @@ class ObjCObjectType : public Type,
}
protected:
+ enum Nonce_ObjCInterface { Nonce_ObjCInterface };
+
ObjCObjectType(QualType Canonical, QualType Base,
ArrayRef<QualType> typeArgs,
ArrayRef<ObjCProtocolDecl *> protocols,
bool isKindOf);
- enum Nonce_ObjCInterface { Nonce_ObjCInterface };
ObjCObjectType(enum Nonce_ObjCInterface)
: Type(ObjCInterface, QualType(), false, false, false, false),
- BaseType(QualType(this_(), 0)) {
+ BaseType(QualType(this_(), 0)) {
ObjCObjectTypeBits.NumProtocols = 0;
ObjCObjectTypeBits.NumTypeArgs = 0;
ObjCObjectTypeBits.IsKindOf = 0;
@@ -5032,9 +5251,11 @@ public:
bool isObjCId() const {
return getBaseType()->isSpecificBuiltinType(BuiltinType::ObjCId);
}
+
bool isObjCClass() const {
return getBaseType()->isSpecificBuiltinType(BuiltinType::ObjCClass);
}
+
bool isObjCUnqualifiedId() const { return qual_empty() && isObjCId(); }
bool isObjCUnqualifiedClass() const { return qual_empty() && isObjCClass(); }
bool isObjCUnqualifiedIdOrClass() const {
@@ -5125,7 +5346,7 @@ class ObjCObjectTypeImpl : public ObjCObjectType, public llvm::FoldingSetNode {
ArrayRef<QualType> typeArgs,
ArrayRef<ObjCProtocolDecl *> protocols,
bool isKindOf)
- : ObjCObjectType(Canonical, Base, typeArgs, protocols, isKindOf) {}
+ : ObjCObjectType(Canonical, Base, typeArgs, protocols, isKindOf) {}
public:
void Profile(llvm::FoldingSetNodeID &ID);
@@ -5163,14 +5384,15 @@ inline ObjCProtocolDecl **ObjCTypeParamType::getProtocolStorageImpl() {
/// - It is its own base type. That is, if T is an ObjCInterfaceType*,
/// T->getBaseType() == QualType(T, 0).
class ObjCInterfaceType : public ObjCObjectType {
+ friend class ASTContext; // ASTContext creates these.
+ friend class ASTReader;
+ friend class ObjCInterfaceDecl;
+
mutable ObjCInterfaceDecl *Decl;
ObjCInterfaceType(const ObjCInterfaceDecl *D)
- : ObjCObjectType(Nonce_ObjCInterface),
- Decl(const_cast<ObjCInterfaceDecl*>(D)) {}
- friend class ASTContext; // ASTContext creates these.
- friend class ASTReader;
- friend class ObjCInterfaceDecl;
+ : ObjCObjectType(Nonce_ObjCInterface),
+ Decl(const_cast<ObjCInterfaceDecl*>(D)) {}
public:
/// Get the declaration of this interface.
@@ -5218,16 +5440,17 @@ inline ObjCInterfaceDecl *ObjCObjectType::getInterface() const {
/// Pointers to pointers to Objective C objects are still PointerTypes;
/// only the first level of pointer gets it own type implementation.
class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode {
+ friend class ASTContext; // ASTContext creates these.
+
QualType PointeeType;
ObjCObjectPointerType(QualType Canonical, QualType Pointee)
- : Type(ObjCObjectPointer, Canonical,
- Pointee->isDependentType(),
- Pointee->isInstantiationDependentType(),
- Pointee->isVariablyModifiedType(),
- Pointee->containsUnexpandedParameterPack()),
- PointeeType(Pointee) {}
- friend class ASTContext; // ASTContext creates these.
+ : Type(ObjCObjectPointer, Canonical,
+ Pointee->isDependentType(),
+ Pointee->isInstantiationDependentType(),
+ Pointee->isVariablyModifiedType(),
+ Pointee->containsUnexpandedParameterPack()),
+ PointeeType(Pointee) {}
public:
/// Gets the type pointed to by this ObjC pointer.
@@ -5336,16 +5559,19 @@ public:
/// An iterator over the qualifiers on the object type. Provided
/// for convenience. This will always iterate over the full set of
/// protocols on a type, not just those provided directly.
- typedef ObjCObjectType::qual_iterator qual_iterator;
- typedef llvm::iterator_range<qual_iterator> qual_range;
+ using qual_iterator = ObjCObjectType::qual_iterator;
+ using qual_range = llvm::iterator_range<qual_iterator>;
qual_range quals() const { return qual_range(qual_begin(), qual_end()); }
+
qual_iterator qual_begin() const {
return getObjectType()->qual_begin();
}
+
qual_iterator qual_end() const {
return getObjectType()->qual_end();
}
+
bool qual_empty() const { return getObjectType()->qual_empty(); }
/// Return the number of qualifying protocols on the object type.
@@ -5377,26 +5603,29 @@ public:
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, getPointeeType());
}
+
static void Profile(llvm::FoldingSetNodeID &ID, QualType T) {
ID.AddPointer(T.getAsOpaquePtr());
}
+
static bool classof(const Type *T) {
return T->getTypeClass() == ObjCObjectPointer;
}
};
class AtomicType : public Type, public llvm::FoldingSetNode {
+ friend class ASTContext; // ASTContext creates these.
+
QualType ValueType;
AtomicType(QualType ValTy, QualType Canonical)
- : Type(Atomic, Canonical, ValTy->isDependentType(),
- ValTy->isInstantiationDependentType(),
- ValTy->isVariablyModifiedType(),
- ValTy->containsUnexpandedParameterPack()),
- ValueType(ValTy) {}
- friend class ASTContext; // ASTContext creates these.
+ : Type(Atomic, Canonical, ValTy->isDependentType(),
+ ValTy->isInstantiationDependentType(),
+ ValTy->isVariablyModifiedType(),
+ ValTy->containsUnexpandedParameterPack()),
+ ValueType(ValTy) {}
- public:
+public:
/// Gets the type contained by this atomic type, i.e.
/// the type returned by performing an atomic load of this atomic type.
QualType getValueType() const { return ValueType; }
@@ -5407,9 +5636,11 @@ class AtomicType : public Type, public llvm::FoldingSetNode {
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, getValueType());
}
+
static void Profile(llvm::FoldingSetNodeID &ID, QualType T) {
ID.AddPointer(T.getAsOpaquePtr());
}
+
static bool classof(const Type *T) {
return T->getTypeClass() == Atomic;
}
@@ -5417,16 +5648,17 @@ class AtomicType : public Type, public llvm::FoldingSetNode {
/// PipeType - OpenCL20.
class PipeType : public Type, public llvm::FoldingSetNode {
+ friend class ASTContext; // ASTContext creates these.
+
QualType ElementType;
bool isRead;
- PipeType(QualType elemType, QualType CanonicalPtr, bool isRead) :
- Type(Pipe, CanonicalPtr, elemType->isDependentType(),
- elemType->isInstantiationDependentType(),
- elemType->isVariablyModifiedType(),
- elemType->containsUnexpandedParameterPack()),
- ElementType(elemType), isRead(isRead) {}
- friend class ASTContext; // ASTContext creates these.
+ PipeType(QualType elemType, QualType CanonicalPtr, bool isRead)
+ : Type(Pipe, CanonicalPtr, elemType->isDependentType(),
+ elemType->isInstantiationDependentType(),
+ elemType->isVariablyModifiedType(),
+ elemType->containsUnexpandedParameterPack()),
+ ElementType(elemType), isRead(isRead) {}
public:
QualType getElementType() const { return ElementType; }
@@ -5476,7 +5708,6 @@ public:
QualType apply(const ASTContext &Context, const Type* T) const;
};
-
// Inline function definitions.
inline SplitQualType SplitQualType::getSingleStepDesugaredType() const {
@@ -5602,7 +5833,7 @@ inline void QualType::removeLocalCVRQualifiers(unsigned Mask) {
}
/// Return the address space of this type.
-inline unsigned QualType::getAddressSpace() const {
+inline LangAS QualType::getAddressSpace() const {
return getQualifiers().getAddressSpace();
}
@@ -5709,88 +5940,117 @@ inline bool Type::isCompoundType() const {
inline bool Type::isFunctionType() const {
return isa<FunctionType>(CanonicalType);
}
+
inline bool Type::isPointerType() const {
return isa<PointerType>(CanonicalType);
}
+
inline bool Type::isAnyPointerType() const {
return isPointerType() || isObjCObjectPointerType();
}
+
inline bool Type::isBlockPointerType() const {
return isa<BlockPointerType>(CanonicalType);
}
+
inline bool Type::isReferenceType() const {
return isa<ReferenceType>(CanonicalType);
}
+
inline bool Type::isLValueReferenceType() const {
return isa<LValueReferenceType>(CanonicalType);
}
+
inline bool Type::isRValueReferenceType() const {
return isa<RValueReferenceType>(CanonicalType);
}
+
inline bool Type::isFunctionPointerType() const {
if (const PointerType *T = getAs<PointerType>())
return T->getPointeeType()->isFunctionType();
else
return false;
}
+
inline bool Type::isMemberPointerType() const {
return isa<MemberPointerType>(CanonicalType);
}
+
inline bool Type::isMemberFunctionPointerType() const {
if (const MemberPointerType* T = getAs<MemberPointerType>())
return T->isMemberFunctionPointer();
else
return false;
}
+
inline bool Type::isMemberDataPointerType() const {
if (const MemberPointerType* T = getAs<MemberPointerType>())
return T->isMemberDataPointer();
else
return false;
}
+
inline bool Type::isArrayType() const {
return isa<ArrayType>(CanonicalType);
}
+
inline bool Type::isConstantArrayType() const {
return isa<ConstantArrayType>(CanonicalType);
}
+
inline bool Type::isIncompleteArrayType() const {
return isa<IncompleteArrayType>(CanonicalType);
}
+
inline bool Type::isVariableArrayType() const {
return isa<VariableArrayType>(CanonicalType);
}
+
inline bool Type::isDependentSizedArrayType() const {
return isa<DependentSizedArrayType>(CanonicalType);
}
+
inline bool Type::isBuiltinType() const {
return isa<BuiltinType>(CanonicalType);
}
+
inline bool Type::isRecordType() const {
return isa<RecordType>(CanonicalType);
}
+
inline bool Type::isEnumeralType() const {
return isa<EnumType>(CanonicalType);
}
+
inline bool Type::isAnyComplexType() const {
return isa<ComplexType>(CanonicalType);
}
+
inline bool Type::isVectorType() const {
return isa<VectorType>(CanonicalType);
}
+
inline bool Type::isExtVectorType() const {
return isa<ExtVectorType>(CanonicalType);
}
+
+inline bool Type::isDependentAddressSpaceType() const {
+ return isa<DependentAddressSpaceType>(CanonicalType);
+}
+
inline bool Type::isObjCObjectPointerType() const {
return isa<ObjCObjectPointerType>(CanonicalType);
}
+
inline bool Type::isObjCObjectType() const {
return isa<ObjCObjectType>(CanonicalType);
}
+
inline bool Type::isObjCObjectOrInterfaceType() const {
return isa<ObjCInterfaceType>(CanonicalType) ||
isa<ObjCObjectType>(CanonicalType);
}
+
inline bool Type::isAtomicType() const {
return isa<AtomicType>(CanonicalType);
}
@@ -5800,26 +6060,31 @@ inline bool Type::isObjCQualifiedIdType() const {
return OPT->isObjCQualifiedIdType();
return false;
}
+
inline bool Type::isObjCQualifiedClassType() const {
if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
return OPT->isObjCQualifiedClassType();
return false;
}
+
inline bool Type::isObjCIdType() const {
if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
return OPT->isObjCIdType();
return false;
}
+
inline bool Type::isObjCClassType() const {
if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
return OPT->isObjCClassType();
return false;
}
+
inline bool Type::isObjCSelType() const {
if (const PointerType *OPT = getAs<PointerType>())
return OPT->getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCSel);
return false;
}
+
inline bool Type::isObjCBuiltinType() const {
return isObjCIdType() || isObjCClassType() || isObjCSelType();
}
@@ -5854,7 +6119,7 @@ inline bool Type::isImageType() const {
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) is##Id##Type() ||
return
#include "clang/Basic/OpenCLImageTypes.def"
- 0; // end boolean or operation
+ false; // end boolean or operation
}
inline bool Type::isPipeType() const {
@@ -6133,7 +6398,6 @@ QualType DecayedType::getPointeeType() const {
return cast<PointerType>(Decayed)->getPointeeType();
}
+} // namespace clang
-} // end namespace clang
-
-#endif
+#endif // LLVM_CLANG_AST_TYPE_H
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
index ad95f6f8effa..b805160a2780 100644
--- a/include/clang/AST/TypeLoc.h
+++ b/include/clang/AST/TypeLoc.h
@@ -1,4 +1,4 @@
-//===--- TypeLoc.h - Type Source Info Wrapper -------------------*- C++ -*-===//
+//===- TypeLoc.h - Type Source Info Wrapper ---------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,26 +6,42 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-///
+//
/// \file
/// \brief Defines the clang::TypeLoc interface and its subclasses.
-///
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_TYPELOC_H
#define LLVM_CLANG_AST_TYPELOC_H
#include "clang/AST/Decl.h"
+#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/TemplateBase.h"
#include "clang/AST/Type.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/MathExtras.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <cstring>
namespace clang {
- class ASTContext;
- class ParmVarDecl;
- class TypeSourceInfo;
- class UnqualTypeLoc;
+
+class ASTContext;
+class CXXRecordDecl;
+class Expr;
+class ObjCInterfaceDecl;
+class ObjCProtocolDecl;
+class ObjCTypeParamDecl;
+class TemplateTypeParmDecl;
+class UnqualTypeLoc;
+class UnresolvedUsingTypenameDecl;
// Predeclare all the type nodes.
#define ABSTRACT_TYPELOC(Class, Base)
@@ -41,10 +57,16 @@ class TypeLoc {
protected:
// The correctness of this relies on the property that, for Type *Ty,
// QualType(Ty, 0).getAsOpaquePtr() == (void*) Ty
- const void *Ty;
- void *Data;
+ const void *Ty = nullptr;
+ void *Data = nullptr;
public:
+ TypeLoc() = default;
+ TypeLoc(QualType ty, void *opaqueData)
+ : Ty(ty.getAsOpaquePtr()), Data(opaqueData) {}
+ TypeLoc(const Type *ty, void *opaqueData)
+ : Ty(ty), Data(opaqueData) {}
+
/// \brief Convert to the specified TypeLoc type, asserting that this TypeLoc
/// is of the desired type.
///
@@ -88,12 +110,6 @@ public:
Qualified
};
- TypeLoc() : Ty(nullptr), Data(nullptr) { }
- TypeLoc(QualType ty, void *opaqueData)
- : Ty(ty.getAsOpaquePtr()), Data(opaqueData) { }
- TypeLoc(const Type *ty, void *opaqueData)
- : Ty(ty), Data(opaqueData) { }
-
TypeLocClass getTypeLocClass() const {
if (getType().hasLocalQualifiers()) return Qualified;
return (TypeLocClass) getType()->getTypeClass();
@@ -134,6 +150,7 @@ public:
SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(getBeginLoc(), getEndLoc());
}
+
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
@@ -228,7 +245,7 @@ inline TypeLoc TypeSourceInfo::getTypeLoc() const {
/// no direct qualifiers.
class UnqualTypeLoc : public TypeLoc {
public:
- UnqualTypeLoc() {}
+ UnqualTypeLoc() = default;
UnqualTypeLoc(const Type *Ty, void *Data) : TypeLoc(Ty, Data) {}
const Type *getTypePtr() const {
@@ -241,6 +258,7 @@ public:
private:
friend class TypeLoc;
+
static bool isKind(const TypeLoc &TL) {
return !TL.getType().hasLocalQualifiers();
}
@@ -253,9 +271,7 @@ private:
/// type qualifiers.
class QualifiedTypeLoc : public TypeLoc {
public:
- SourceRange getLocalSourceRange() const {
- return SourceRange();
- }
+ SourceRange getLocalSourceRange() const { return {}; }
UnqualTypeLoc getUnqualifiedLoc() const {
unsigned align =
@@ -296,6 +312,7 @@ public:
private:
friend class TypeLoc;
+
static bool isKind(const TypeLoc &TL) {
return TL.getType().hasLocalQualifiers();
}
@@ -337,12 +354,12 @@ inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const {
/// InheritingConcreteTypeLoc instead.
template <class Base, class Derived, class TypeClass, class LocalData>
class ConcreteTypeLoc : public Base {
+ friend class TypeLoc;
const Derived *asDerived() const {
return static_cast<const Derived*>(this);
}
- friend class TypeLoc;
static bool isKind(const TypeLoc &TL) {
return !TL.getType().hasLocalQualifiers() &&
Derived::classofType(TL.getTypePtr());
@@ -357,6 +374,7 @@ public:
return std::max(unsigned(alignof(LocalData)),
asDerived()->getExtraLocalDataAlignment());
}
+
unsigned getLocalDataSize() const {
unsigned size = sizeof(LocalData);
unsigned extraAlign = asDerived()->getExtraLocalDataAlignment();
@@ -449,9 +467,7 @@ private:
return TypeLoc::getLocalAlignmentForType(T);
}
- TypeLoc getNextTypeLoc(HasNoInnerType _) const {
- return TypeLoc();
- }
+ TypeLoc getNextTypeLoc(HasNoInnerType _) const { return {}; }
TypeLoc getNextTypeLoc(QualType T) const {
return TypeLoc(T, getNonLocalData());
@@ -464,6 +480,7 @@ private:
template <class Base, class Derived, class TypeClass>
class InheritingConcreteTypeLoc : public Base {
friend class TypeLoc;
+
static bool classofType(const Type *Ty) {
return TypeClass::classof(Ty);
}
@@ -482,7 +499,6 @@ public:
}
};
-
struct TypeSpecLocInfo {
SourceLocation NameLoc;
};
@@ -502,22 +518,25 @@ public:
SourceLocation getNameLoc() const {
return this->getLocalData()->NameLoc;
}
+
void setNameLoc(SourceLocation Loc) {
this->getLocalData()->NameLoc = Loc;
}
+
SourceRange getLocalSourceRange() const {
return SourceRange(getNameLoc(), getNameLoc());
}
+
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setNameLoc(Loc);
}
private:
friend class TypeLoc;
+
static bool isKind(const TypeLoc &TL);
};
-
struct BuiltinLocInfo {
SourceRange BuiltinRange;
};
@@ -531,9 +550,11 @@ public:
SourceLocation getBuiltinLoc() const {
return getLocalData()->BuiltinRange.getBegin();
}
+
void setBuiltinLoc(SourceLocation Loc) {
getLocalData()->BuiltinRange = Loc;
}
+
void expandBuiltinRange(SourceRange Range) {
SourceRange &BuiltinRange = getLocalData()->BuiltinRange;
if (!BuiltinRange.getBegin().isValid()) {
@@ -579,9 +600,11 @@ public:
else
return TSS_unspecified;
}
+
bool hasWrittenSignSpec() const {
return getWrittenSignSpec() != TSS_unspecified;
}
+
void setWrittenSignSpec(TypeSpecifierSign written) {
if (needsExtraLocalData())
getWrittenBuiltinSpecs().Sign = written;
@@ -593,18 +616,22 @@ public:
else
return TSW_unspecified;
}
+
bool hasWrittenWidthSpec() const {
return getWrittenWidthSpec() != TSW_unspecified;
}
+
void setWrittenWidthSpec(TypeSpecifierWidth written) {
if (needsExtraLocalData())
getWrittenBuiltinSpecs().Width = written;
}
TypeSpecifierType getWrittenTypeSpec() const;
+
bool hasWrittenTypeSpec() const {
return getWrittenTypeSpec() != TST_unspecified;
}
+
void setWrittenTypeSpec(TypeSpecifierType written) {
if (needsExtraLocalData())
getWrittenBuiltinSpecs().Type = written;
@@ -616,6 +643,7 @@ public:
else
return false;
}
+
void setModeAttr(bool written) {
if (needsExtraLocalData())
getWrittenBuiltinSpecs().ModeAttr = written;
@@ -633,7 +661,6 @@ public:
}
};
-
/// \brief Wrapper for source info for typedefs.
class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
TypedefTypeLoc,
@@ -742,6 +769,7 @@ public:
*((SourceLocation*)this->getExtraLocalData()) :
SourceLocation();
}
+
void setProtocolLAngleLoc(SourceLocation Loc) {
*((SourceLocation*)this->getExtraLocalData()) = Loc;
}
@@ -751,6 +779,7 @@ public:
*((SourceLocation*)this->getExtraLocalData() + 1) :
SourceLocation();
}
+
void setProtocolRAngleLoc(SourceLocation Loc) {
*((SourceLocation*)this->getExtraLocalData() + 1) = Loc;
}
@@ -763,6 +792,7 @@ public:
assert(i < getNumProtocols() && "Index is out of bounds!");
return getProtocolLocArray()[i];
}
+
void setProtocolLoc(unsigned i, SourceLocation Loc) {
assert(i < getNumProtocols() && "Index is out of bounds!");
getProtocolLocArray()[i] = Loc;
@@ -785,9 +815,11 @@ public:
// as well.
return (this->getNumProtocols() + 2) * sizeof(SourceLocation) ;
}
+
unsigned getExtraLocalDataAlignment() const {
return alignof(SourceLocation);
}
+
SourceRange getLocalSourceRange() const {
SourceLocation start = getNameLoc();
SourceLocation end = getProtocolRAngleLoc();
@@ -938,7 +970,6 @@ public:
}
};
-
struct ObjCObjectTypeLocInfo {
SourceLocation TypeArgsLAngleLoc;
SourceLocation TypeArgsRAngleLoc;
@@ -971,6 +1002,7 @@ public:
SourceLocation getTypeArgsLAngleLoc() const {
return this->getLocalData()->TypeArgsLAngleLoc;
}
+
void setTypeArgsLAngleLoc(SourceLocation Loc) {
this->getLocalData()->TypeArgsLAngleLoc = Loc;
}
@@ -978,6 +1010,7 @@ public:
SourceLocation getTypeArgsRAngleLoc() const {
return this->getLocalData()->TypeArgsRAngleLoc;
}
+
void setTypeArgsRAngleLoc(SourceLocation Loc) {
this->getLocalData()->TypeArgsRAngleLoc = Loc;
}
@@ -999,6 +1032,7 @@ public:
SourceLocation getProtocolLAngleLoc() const {
return this->getLocalData()->ProtocolLAngleLoc;
}
+
void setProtocolLAngleLoc(SourceLocation Loc) {
this->getLocalData()->ProtocolLAngleLoc = Loc;
}
@@ -1006,6 +1040,7 @@ public:
SourceLocation getProtocolRAngleLoc() const {
return this->getLocalData()->ProtocolRAngleLoc;
}
+
void setProtocolRAngleLoc(SourceLocation Loc) {
this->getLocalData()->ProtocolRAngleLoc = Loc;
}
@@ -1018,6 +1053,7 @@ public:
assert(i < getNumProtocols() && "Index is out of bounds!");
return getProtocolLocArray()[i];
}
+
void setProtocolLoc(unsigned i, SourceLocation Loc) {
assert(i < getNumProtocols() && "Index is out of bounds!");
getProtocolLocArray()[i] = Loc;
@@ -1073,7 +1109,6 @@ public:
}
};
-
struct ObjCInterfaceLocInfo {
SourceLocation NameLoc;
SourceLocation NameEndLoc;
@@ -1127,12 +1162,15 @@ public:
SourceLocation getLParenLoc() const {
return this->getLocalData()->LParenLoc;
}
+
SourceLocation getRParenLoc() const {
return this->getLocalData()->RParenLoc;
}
+
void setLParenLoc(SourceLocation Loc) {
this->getLocalData()->LParenLoc = Loc;
}
+
void setRParenLoc(SourceLocation Loc) {
this->getLocalData()->RParenLoc = Loc;
}
@@ -1161,8 +1199,7 @@ inline TypeLoc TypeLoc::IgnoreParens() const {
return *this;
}
-
-struct AdjustedLocInfo { }; // Nothing.
+struct AdjustedLocInfo {}; // Nothing.
class AdjustedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AdjustedTypeLoc,
AdjustedType, AdjustedLocInfo> {
@@ -1181,9 +1218,7 @@ public:
return getTypePtr()->getOriginalType();
}
- SourceRange getLocalSourceRange() const {
- return SourceRange();
- }
+ SourceRange getLocalSourceRange() const { return {}; }
unsigned getLocalDataSize() const {
// sizeof(AdjustedLocInfo) is 1, but we don't need its address to be unique
@@ -1210,6 +1245,7 @@ public:
SourceLocation getSigilLoc() const {
return this->getLocalData()->StarLoc;
}
+
void setSigilLoc(SourceLocation Loc) {
this->getLocalData()->StarLoc = Loc;
}
@@ -1231,7 +1267,6 @@ public:
}
};
-
/// \brief Wrapper for source info for pointers.
class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc,
PointerType> {
@@ -1239,12 +1274,12 @@ public:
SourceLocation getStarLoc() const {
return getSigilLoc();
}
+
void setStarLoc(SourceLocation Loc) {
setSigilLoc(Loc);
}
};
-
/// \brief Wrapper for source info for block pointers.
class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
BlockPointerType> {
@@ -1252,6 +1287,7 @@ public:
SourceLocation getCaretLoc() const {
return getSigilLoc();
}
+
void setCaretLoc(SourceLocation Loc) {
setSigilLoc(Loc);
}
@@ -1269,6 +1305,7 @@ public:
SourceLocation getStarLoc() const {
return getSigilLoc();
}
+
void setStarLoc(SourceLocation Loc) {
setSigilLoc(Loc);
}
@@ -1276,9 +1313,11 @@ public:
const Type *getClass() const {
return getTypePtr()->getClass();
}
+
TypeSourceInfo *getClassTInfo() const {
return getLocalData()->ClassTInfo;
}
+
void setClassTInfo(TypeSourceInfo* TI) {
getLocalData()->ClassTInfo = TI;
}
@@ -1310,7 +1349,6 @@ public:
}
};
-
class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
ReferenceType> {
public:
@@ -1327,6 +1365,7 @@ public:
SourceLocation getAmpLoc() const {
return getSigilLoc();
}
+
void setAmpLoc(SourceLocation Loc) {
setSigilLoc(Loc);
}
@@ -1340,12 +1379,12 @@ public:
SourceLocation getAmpAmpLoc() const {
return getSigilLoc();
}
+
void setAmpAmpLoc(SourceLocation Loc) {
setSigilLoc(Loc);
}
};
-
struct FunctionLocInfo {
SourceLocation LocalRangeBegin;
SourceLocation LParenLoc;
@@ -1371,10 +1410,12 @@ class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
// exception specification information.
return (SourceRange *)(getParmArray() + getNumParams());
}
+
public:
SourceLocation getLocalRangeBegin() const {
return getLocalData()->LocalRangeBegin;
}
+
void setLocalRangeBegin(SourceLocation L) {
getLocalData()->LocalRangeBegin = L;
}
@@ -1382,6 +1423,7 @@ public:
SourceLocation getLocalRangeEnd() const {
return getLocalData()->LocalRangeEnd;
}
+
void setLocalRangeEnd(SourceLocation L) {
getLocalData()->LocalRangeEnd = L;
}
@@ -1389,6 +1431,7 @@ public:
SourceLocation getLParenLoc() const {
return this->getLocalData()->LParenLoc;
}
+
void setLParenLoc(SourceLocation Loc) {
this->getLocalData()->LParenLoc = Loc;
}
@@ -1396,6 +1439,7 @@ public:
SourceLocation getRParenLoc() const {
return this->getLocalData()->RParenLoc;
}
+
void setRParenLoc(SourceLocation Loc) {
this->getLocalData()->RParenLoc = Loc;
}
@@ -1407,8 +1451,9 @@ public:
SourceRange getExceptionSpecRange() const {
if (hasExceptionSpec())
return *getExceptionSpecRangePtr();
- return SourceRange();
+ return {};
}
+
void setExceptionSpecRange(SourceRange R) {
if (hasExceptionSpec())
*getExceptionSpecRangePtr() = R;
@@ -1428,6 +1473,7 @@ public:
return 0;
return cast<FunctionProtoType>(getTypePtr())->getNumParams();
}
+
ParmVarDecl *getParam(unsigned i) const { return getParmArray()[i]; }
void setParam(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
@@ -1474,7 +1520,6 @@ class FunctionNoProtoTypeLoc :
FunctionNoProtoType> {
};
-
struct ArrayLocInfo {
SourceLocation LBracketLoc, RBracketLoc;
Expr *Size;
@@ -1489,6 +1534,7 @@ public:
SourceLocation getLBracketLoc() const {
return getLocalData()->LBracketLoc;
}
+
void setLBracketLoc(SourceLocation Loc) {
getLocalData()->LBracketLoc = Loc;
}
@@ -1496,6 +1542,7 @@ public:
SourceLocation getRBracketLoc() const {
return getLocalData()->RBracketLoc;
}
+
void setRBracketLoc(SourceLocation Loc) {
getLocalData()->RBracketLoc = Loc;
}
@@ -1507,6 +1554,7 @@ public:
Expr *getSizeExpr() const {
return getLocalData()->Size;
}
+
void setSizeExpr(Expr *Size) {
getLocalData()->Size = Size;
}
@@ -1557,7 +1605,6 @@ class VariableArrayTypeLoc :
VariableArrayType> {
};
-
// Location information for a TemplateName. Rudimentary for now.
struct TemplateNameLocInfo {
SourceLocation NameLoc;
@@ -1578,6 +1625,7 @@ public:
SourceLocation getTemplateKeywordLoc() const {
return getLocalData()->TemplateKWLoc;
}
+
void setTemplateKeywordLoc(SourceLocation Loc) {
getLocalData()->TemplateKWLoc = Loc;
}
@@ -1585,6 +1633,7 @@ public:
SourceLocation getLAngleLoc() const {
return getLocalData()->LAngleLoc;
}
+
void setLAngleLoc(SourceLocation Loc) {
getLocalData()->LAngleLoc = Loc;
}
@@ -1592,6 +1641,7 @@ public:
SourceLocation getRAngleLoc() const {
return getLocalData()->RAngleLoc;
}
+
void setRAngleLoc(SourceLocation Loc) {
getLocalData()->RAngleLoc = Loc;
}
@@ -1599,9 +1649,11 @@ public:
unsigned getNumArgs() const {
return getTypePtr()->getNumArgs();
}
+
void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
getArgInfos()[i] = AI;
}
+
TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
return getArgInfos()[i];
}
@@ -1613,6 +1665,7 @@ public:
SourceLocation getTemplateNameLoc() const {
return getLocalData()->NameLoc;
}
+
void setTemplateNameLoc(SourceLocation Loc) {
getLocalData()->NameLoc = Loc;
}
@@ -1664,6 +1717,74 @@ private:
}
};
+struct DependentAddressSpaceLocInfo {
+ Expr *ExprOperand;
+ SourceRange OperandParens;
+ SourceLocation AttrLoc;
+};
+
+class DependentAddressSpaceTypeLoc
+ : public ConcreteTypeLoc<UnqualTypeLoc,
+ DependentAddressSpaceTypeLoc,
+ DependentAddressSpaceType,
+ DependentAddressSpaceLocInfo> {
+public:
+ /// The location of the attribute name, i.e.
+ /// int * __attribute__((address_space(11)))
+ /// ^~~~~~~~~~~~~
+ SourceLocation getAttrNameLoc() const {
+ return getLocalData()->AttrLoc;
+ }
+ void setAttrNameLoc(SourceLocation loc) {
+ getLocalData()->AttrLoc = loc;
+ }
+
+ /// The attribute's expression operand, if it has one.
+ /// int * __attribute__((address_space(11)))
+ /// ^~
+ Expr *getAttrExprOperand() const {
+ return getLocalData()->ExprOperand;
+ }
+ void setAttrExprOperand(Expr *e) {
+ getLocalData()->ExprOperand = e;
+ }
+
+ /// The location of the parentheses around the operand, if there is
+ /// an operand.
+ /// int * __attribute__((address_space(11)))
+ /// ^ ^
+ SourceRange getAttrOperandParensRange() const {
+ return getLocalData()->OperandParens;
+ }
+ void setAttrOperandParensRange(SourceRange range) {
+ getLocalData()->OperandParens = range;
+ }
+
+ SourceRange getLocalSourceRange() const {
+ SourceRange range(getAttrNameLoc());
+ range.setEnd(getAttrOperandParensRange().getEnd());
+ return range;
+ }
+
+ /// Returns the type before the address space attribute application
+ /// area.
+ /// int * __attribute__((address_space(11))) *
+ /// ^ ^
+ QualType getInnerType() const {
+ return this->getTypePtr()->getPointeeType();
+ }
+
+ TypeLoc getPointeeTypeLoc() const {
+ return this->getInnerTypeLoc();
+ }
+
+ void initializeLocal(ASTContext &Context, SourceLocation loc) {
+ setAttrNameLoc(loc);
+ setAttrOperandParensRange(SourceRange(loc));
+ setAttrExprOperand(getTypePtr()->getAddrSpaceExpr());
+ }
+};
+
//===----------------------------------------------------------------------===//
//
// All of these need proper implementations.
@@ -1717,6 +1838,7 @@ public:
SourceLocation getTypeofLoc() const {
return this->getLocalData()->TypeofLoc;
}
+
void setTypeofLoc(SourceLocation Loc) {
this->getLocalData()->TypeofLoc = Loc;
}
@@ -1724,6 +1846,7 @@ public:
SourceLocation getLParenLoc() const {
return this->getLocalData()->LParenLoc;
}
+
void setLParenLoc(SourceLocation Loc) {
this->getLocalData()->LParenLoc = Loc;
}
@@ -1731,6 +1854,7 @@ public:
SourceLocation getRParenLoc() const {
return this->getLocalData()->RParenLoc;
}
+
void setRParenLoc(SourceLocation Loc) {
this->getLocalData()->RParenLoc = Loc;
}
@@ -1738,6 +1862,7 @@ public:
SourceRange getParensRange() const {
return SourceRange(getLParenLoc(), getRParenLoc());
}
+
void setParensRange(SourceRange range) {
setLParenLoc(range.getBegin());
setRParenLoc(range.getEnd());
@@ -1761,6 +1886,7 @@ public:
Expr* getUnderlyingExpr() const {
return getTypePtr()->getUnderlyingExpr();
}
+
// Reimplemented to account for GNU/C++ extension
// typeof unary-expression
// where there are no parentheses.
@@ -1773,9 +1899,11 @@ public:
QualType getUnderlyingType() const {
return this->getTypePtr()->getUnderlyingType();
}
+
TypeSourceInfo* getUnderlyingTInfo() const {
return this->getLocalData()->UnderlyingTInfo;
}
+
void setUnderlyingTInfo(TypeSourceInfo* TI) const {
this->getLocalData()->UnderlyingTInfo = TI;
}
@@ -1815,6 +1943,7 @@ public:
TypeSourceInfo* getUnderlyingTInfo() const {
return getLocalData()->UnderlyingTInfo;
}
+
void setUnderlyingTInfo(TypeSourceInfo *TInfo) {
getLocalData()->UnderlyingTInfo = TInfo;
}
@@ -1826,16 +1955,13 @@ public:
SourceRange getParensRange() const {
return SourceRange(getLParenLoc(), getRParenLoc());
}
+
void setParensRange(SourceRange Range) {
setLParenLoc(Range.getBegin());
setRParenLoc(Range.getEnd());
}
- void initializeLocal(ASTContext &Context, SourceLocation Loc) {
- setKWLoc(Loc);
- setRParenLoc(Loc);
- setLParenLoc(Loc);
- }
+ void initializeLocal(ASTContext &Context, SourceLocation Loc);
};
class DeducedTypeLoc
@@ -1854,6 +1980,7 @@ public:
SourceLocation getTemplateNameLoc() const {
return getNameLoc();
}
+
void setTemplateNameLoc(SourceLocation Loc) {
setNameLoc(Loc);
}
@@ -1861,6 +1988,7 @@ public:
struct ElaboratedLocInfo {
SourceLocation ElaboratedKWLoc;
+
/// \brief Data associated with the nested-name-specifier location.
void *QualifierData;
};
@@ -1873,6 +2001,7 @@ public:
SourceLocation getElaboratedKeywordLoc() const {
return this->getLocalData()->ElaboratedKWLoc;
}
+
void setElaboratedKeywordLoc(SourceLocation Loc) {
this->getLocalData()->ElaboratedKWLoc = Loc;
}
@@ -1931,6 +2060,7 @@ public:
SourceLocation getElaboratedKeywordLoc() const {
return this->getLocalData()->ElaboratedKWLoc;
}
+
void setElaboratedKeywordLoc(SourceLocation Loc) {
this->getLocalData()->ElaboratedKWLoc = Loc;
}
@@ -1950,6 +2080,7 @@ public:
SourceLocation getNameLoc() const {
return this->getLocalData()->NameLoc;
}
+
void setNameLoc(SourceLocation Loc) {
this->getLocalData()->NameLoc = Loc;
}
@@ -1986,6 +2117,7 @@ public:
SourceLocation getElaboratedKeywordLoc() const {
return this->getLocalData()->ElaboratedKWLoc;
}
+
void setElaboratedKeywordLoc(SourceLocation Loc) {
this->getLocalData()->ElaboratedKWLoc = Loc;
}
@@ -2017,6 +2149,7 @@ public:
SourceLocation getTemplateKeywordLoc() const {
return getLocalData()->TemplateKWLoc;
}
+
void setTemplateKeywordLoc(SourceLocation Loc) {
getLocalData()->TemplateKWLoc = Loc;
}
@@ -2024,6 +2157,7 @@ public:
SourceLocation getTemplateNameLoc() const {
return this->getLocalData()->NameLoc;
}
+
void setTemplateNameLoc(SourceLocation Loc) {
this->getLocalData()->NameLoc = Loc;
}
@@ -2031,6 +2165,7 @@ public:
SourceLocation getLAngleLoc() const {
return this->getLocalData()->LAngleLoc;
}
+
void setLAngleLoc(SourceLocation Loc) {
this->getLocalData()->LAngleLoc = Loc;
}
@@ -2038,6 +2173,7 @@ public:
SourceLocation getRAngleLoc() const {
return this->getLocalData()->RAngleLoc;
}
+
void setRAngleLoc(SourceLocation Loc) {
this->getLocalData()->RAngleLoc = Loc;
}
@@ -2049,6 +2185,7 @@ public:
void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
getArgInfos()[i] = AI;
}
+
TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
return getArgInfos()[i];
}
@@ -2090,7 +2227,6 @@ private:
}
};
-
struct PackExpansionTypeLocInfo {
SourceLocation EllipsisLoc;
};
@@ -2142,6 +2278,7 @@ public:
SourceLocation getKWLoc() const {
return this->getLocalData()->KWLoc;
}
+
void setKWLoc(SourceLocation Loc) {
this->getLocalData()->KWLoc = Loc;
}
@@ -2149,6 +2286,7 @@ public:
SourceLocation getLParenLoc() const {
return this->getLocalData()->LParenLoc;
}
+
void setLParenLoc(SourceLocation Loc) {
this->getLocalData()->LParenLoc = Loc;
}
@@ -2156,6 +2294,7 @@ public:
SourceLocation getRParenLoc() const {
return this->getLocalData()->RParenLoc;
}
+
void setRParenLoc(SourceLocation Loc) {
this->getLocalData()->RParenLoc = Loc;
}
@@ -2163,6 +2302,7 @@ public:
SourceRange getParensRange() const {
return SourceRange(getLParenLoc(), getRParenLoc());
}
+
void setParensRange(SourceRange Range) {
setLParenLoc(Range.getBegin());
setRParenLoc(Range.getEnd());
@@ -2217,6 +2357,7 @@ inline T TypeLoc::getAsAdjusted() const {
}
return Cur.getAs<T>();
}
-}
-#endif
+} // namespace clang
+
+#endif // LLVM_CLANG_AST_TYPELOC_H
diff --git a/include/clang/AST/TypeNodes.def b/include/clang/AST/TypeNodes.def
index 9d1d09e2cc66..66697fa0d0fa 100644
--- a/include/clang/AST/TypeNodes.def
+++ b/include/clang/AST/TypeNodes.def
@@ -23,7 +23,7 @@
// NON_CANONICAL_TYPE(Class, Base) - A type that can show up
// anywhere in the AST but will never be a part of a canonical
// type. Clients that only need to deal with canonical types
-// (ignoring, e.g., typedefs and other type alises used for
+// (ignoring, e.g., typedefs and other type aliases used for
// pretty-printing) can ignore these types.
//
// DEPENDENT_TYPE(Class, Base) - A type that will only show up
@@ -73,6 +73,7 @@ TYPE(IncompleteArray, ArrayType)
TYPE(VariableArray, ArrayType)
DEPENDENT_TYPE(DependentSizedArray, ArrayType)
DEPENDENT_TYPE(DependentSizedExtVector, Type)
+DEPENDENT_TYPE(DependentAddressSpace, Type)
TYPE(Vector, Type)
TYPE(ExtVector, VectorType)
ABSTRACT_TYPE(Function, Type)
diff --git a/include/clang/AST/UnresolvedSet.h b/include/clang/AST/UnresolvedSet.h
index b63c6eb21769..614ff9bf2efd 100644
--- a/include/clang/AST/UnresolvedSet.h
+++ b/include/clang/AST/UnresolvedSet.h
@@ -1,4 +1,4 @@
-//===-- UnresolvedSet.h - Unresolved sets of declarations ------*- C++ -*-===//
+//===- UnresolvedSet.h - Unresolved sets of declarations --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -17,20 +17,25 @@
#include "clang/AST/DeclAccessPair.h"
#include "clang/Basic/LLVM.h"
+#include "clang/Basic/Specifiers.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/iterator.h"
+#include <cstddef>
+#include <iterator>
namespace clang {
+class NamedDecl;
+
/// The iterator over UnresolvedSets. Serves as both the const and
/// non-const iterator.
class UnresolvedSetIterator : public llvm::iterator_adaptor_base<
UnresolvedSetIterator, DeclAccessPair *,
std::random_access_iterator_tag, NamedDecl *,
std::ptrdiff_t, NamedDecl *, NamedDecl *> {
- friend class UnresolvedSetImpl;
friend class ASTUnresolvedSet;
friend class OverloadExpr;
+ friend class UnresolvedSetImpl;
explicit UnresolvedSetIterator(DeclAccessPair *Iter)
: iterator_adaptor_base(Iter) {}
@@ -54,12 +59,13 @@ public:
/// \brief A set of unresolved declarations.
class UnresolvedSetImpl {
- typedef SmallVectorImpl<DeclAccessPair> DeclsTy;
+ using DeclsTy = SmallVectorImpl<DeclAccessPair>;
// Don't allow direct construction, and only permit subclassing by
// UnresolvedSet.
private:
template <unsigned N> friend class UnresolvedSet;
+
UnresolvedSetImpl() = default;
UnresolvedSetImpl(const UnresolvedSetImpl &) = default;
UnresolvedSetImpl &operator=(const UnresolvedSetImpl &) = default;
@@ -71,8 +77,8 @@ private:
public:
// We don't currently support assignment through this iterator, so we might
// as well use the same implementation twice.
- typedef UnresolvedSetIterator iterator;
- typedef UnresolvedSetIterator const_iterator;
+ using iterator = UnresolvedSetIterator;
+ using const_iterator = UnresolvedSetIterator;
iterator begin() { return iterator(decls().begin()); }
iterator end() { return iterator(decls().end()); }
@@ -140,7 +146,7 @@ template <unsigned InlineCapacity> class UnresolvedSet :
SmallVector<DeclAccessPair, InlineCapacity> Decls;
};
-
+
} // namespace clang
-#endif
+#endif // LLVM_CLANG_AST_UNRESOLVEDSET_H
diff --git a/include/clang/AST/VTTBuilder.h b/include/clang/AST/VTTBuilder.h
index b4a6fe3bdb94..178139477d00 100644
--- a/include/clang/AST/VTTBuilder.h
+++ b/include/clang/AST/VTTBuilder.h
@@ -1,4 +1,4 @@
-//===--- VTTBuilder.h - C++ VTT layout builder --------------------*- C++ -*-=//
+//===- VTTBuilder.h - C++ VTT layout builder --------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,25 +16,31 @@
#define LLVM_CLANG_AST_VTTBUILDER_H
#include "clang/AST/BaseSubobject.h"
-#include "clang/AST/CXXInheritance.h"
-#include "clang/AST/GlobalDecl.h"
-#include "clang/AST/RecordLayout.h"
-#include "clang/Basic/ABI.h"
-#include <utility>
+#include "clang/AST/CharUnits.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include <cstdint>
namespace clang {
+class ASTContext;
+class ASTRecordLayout;
+class CXXRecordDecl;
+
class VTTVTable {
llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> BaseAndIsVirtual;
CharUnits BaseOffset;
public:
- VTTVTable() {}
+ VTTVTable() = default;
VTTVTable(const CXXRecordDecl *Base, CharUnits BaseOffset, bool BaseIsVirtual)
- : BaseAndIsVirtual(Base, BaseIsVirtual), BaseOffset(BaseOffset) {}
+ : BaseAndIsVirtual(Base, BaseIsVirtual), BaseOffset(BaseOffset) {}
VTTVTable(BaseSubobject Base, bool BaseIsVirtual)
- : BaseAndIsVirtual(Base.getBase(), BaseIsVirtual),
- BaseOffset(Base.getBaseOffset()) {}
+ : BaseAndIsVirtual(Base.getBase(), BaseIsVirtual),
+ BaseOffset(Base.getBaseOffset()) {}
const CXXRecordDecl *getBase() const {
return BaseAndIsVirtual.getPointer();
@@ -57,25 +63,24 @@ struct VTTComponent {
uint64_t VTableIndex;
BaseSubobject VTableBase;
- VTTComponent() {}
+ VTTComponent() = default;
VTTComponent(uint64_t VTableIndex, BaseSubobject VTableBase)
- : VTableIndex(VTableIndex), VTableBase(VTableBase) {}
+ : VTableIndex(VTableIndex), VTableBase(VTableBase) {}
};
/// \brief Class for building VTT layout information.
class VTTBuilder {
-
ASTContext &Ctx;
/// \brief The most derived class for which we're building this vtable.
const CXXRecordDecl *MostDerivedClass;
- typedef SmallVector<VTTVTable, 64> VTTVTablesVectorTy;
+ using VTTVTablesVectorTy = SmallVector<VTTVTable, 64>;
/// \brief The VTT vtables.
VTTVTablesVectorTy VTTVTables;
- typedef SmallVector<VTTComponent, 64> VTTComponentsVectorTy;
+ using VTTComponentsVectorTy = SmallVector<VTTComponent, 64>;
/// \brief The VTT components.
VTTComponentsVectorTy VTTComponents;
@@ -83,9 +88,9 @@ class VTTBuilder {
/// \brief The AST record layout of the most derived class.
const ASTRecordLayout &MostDerivedClassLayout;
- typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy;
+ using VisitedVirtualBasesSetTy = llvm::SmallPtrSet<const CXXRecordDecl *, 4>;
- typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy;
+ using AddressPointsMapTy = llvm::DenseMap<BaseSubobject, uint64_t>;
/// \brief The sub-VTT indices for the bases of the most derived class.
llvm::DenseMap<BaseSubobject, uint64_t> SubVTTIndicies;
@@ -153,9 +158,8 @@ public:
getSecondaryVirtualPointerIndices() const {
return SecondaryVirtualPointerIndices;
}
-
};
-}
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_AST_VTTBUILDER_H
diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h
index c9b496df33f7..64e7e908d51e 100644
--- a/include/clang/ASTMatchers/ASTMatchers.h
+++ b/include/clang/ASTMatchers/ASTMatchers.h
@@ -1,4 +1,4 @@
-//===--- ASTMatchers.h - Structural query framework -------------*- C++ -*-===//
+//===- ASTMatchers.h - Structural query framework ---------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -25,7 +25,7 @@
//
// For example, when we're interested in child classes of a certain class, we
// would write:
-// cxxRecordDecl(hasName("MyClass"), hasChild(id("child", recordDecl())))
+// cxxRecordDecl(hasName("MyClass"), has(id("child", recordDecl())))
// When the match is found via the MatchFinder, a user provided callback will
// be called with a BoundNodes instance that contains a mapping from the
// strings that we provided for the id(...) calls to the nodes that were
@@ -46,13 +46,48 @@
#define LLVM_CLANG_ASTMATCHERS_ASTMATCHERS_H
#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTTypeTraits.h"
+#include "clang/AST/Attr.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclFriend.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/OperationKinds.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtCXX.h"
+#include "clang/AST/StmtObjC.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/AST/TemplateName.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/TypeLoc.h"
#include "clang/ASTMatchers/ASTMatchersInternal.h"
#include "clang/ASTMatchers/ASTMatchersMacros.h"
+#include "clang/Basic/AttrKinds.h"
+#include "clang/Basic/ExceptionSpecificationType.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/Specifiers.h"
+#include "clang/Basic/TypeTraits.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Regex.h"
+#include <cassert>
+#include <cstddef>
#include <iterator>
+#include <limits>
+#include <string>
+#include <utility>
+#include <vector>
namespace clang {
namespace ast_matchers {
@@ -78,7 +113,7 @@ public:
/// \brief Type of mapping from binding identifiers to bound nodes. This type
/// is an associative container with a key type of \c std::string and a value
/// type of \c clang::ast_type_traits::DynTypedNode
- typedef internal::BoundNodesMap::IDToNodeMap IDToNodeMap;
+ using IDToNodeMap = internal::BoundNodesMap::IDToNodeMap;
/// \brief Retrieve mapping from binding identifiers to bound nodes.
const IDToNodeMap &getMap() const {
@@ -86,13 +121,13 @@ public:
}
private:
+ friend class internal::BoundNodesTreeBuilder;
+
/// \brief Create BoundNodes from a pre-filled map of bindings.
BoundNodes(internal::BoundNodesMap &MyBoundNodes)
: MyBoundNodes(MyBoundNodes) {}
internal::BoundNodesMap MyBoundNodes;
-
- friend class internal::BoundNodesTreeBuilder;
};
/// \brief If the provided matcher matches a node, binds the node to \c ID.
@@ -107,13 +142,13 @@ internal::Matcher<T> id(StringRef ID,
/// \brief Types of matchers for the top-level classes in the AST class
/// hierarchy.
/// @{
-typedef internal::Matcher<Decl> DeclarationMatcher;
-typedef internal::Matcher<Stmt> StatementMatcher;
-typedef internal::Matcher<QualType> TypeMatcher;
-typedef internal::Matcher<TypeLoc> TypeLocMatcher;
-typedef internal::Matcher<NestedNameSpecifier> NestedNameSpecifierMatcher;
-typedef internal::Matcher<NestedNameSpecifierLoc> NestedNameSpecifierLocMatcher;
-typedef internal::Matcher<CXXCtorInitializer> CXXCtorInitializerMatcher;
+using DeclarationMatcher = internal::Matcher<Decl>;
+using StatementMatcher = internal::Matcher<Stmt>;
+using TypeMatcher = internal::Matcher<QualType>;
+using TypeLocMatcher = internal::Matcher<TypeLoc>;
+using NestedNameSpecifierMatcher = internal::Matcher<NestedNameSpecifier>;
+using NestedNameSpecifierLocMatcher = internal::Matcher<NestedNameSpecifierLoc>;
+using CXXCtorInitializerMatcher = internal::Matcher<CXXCtorInitializer>;
/// @}
/// \brief Matches any node.
@@ -143,7 +178,7 @@ inline internal::TrueMatcher anything() { return internal::TrueMatcher(); }
/// \endcode
/// decl(hasDeclContext(translationUnitDecl()))
/// matches "int X", but not "int Y".
-const internal::VariadicDynCastAllOfMatcher<Decl, TranslationUnitDecl>
+extern const internal::VariadicDynCastAllOfMatcher<Decl, TranslationUnitDecl>
translationUnitDecl;
/// \brief Matches typedef declarations.
@@ -155,7 +190,8 @@ const internal::VariadicDynCastAllOfMatcher<Decl, TranslationUnitDecl>
/// \endcode
/// typedefDecl()
/// matches "typedef int X", but not "using Y = int"
-const internal::VariadicDynCastAllOfMatcher<Decl, TypedefDecl> typedefDecl;
+extern const internal::VariadicDynCastAllOfMatcher<Decl, TypedefDecl>
+ typedefDecl;
/// \brief Matches typedef name declarations.
///
@@ -166,7 +202,7 @@ const internal::VariadicDynCastAllOfMatcher<Decl, TypedefDecl> typedefDecl;
/// \endcode
/// typedefNameDecl()
/// matches "typedef int X" and "using Y = int"
-const internal::VariadicDynCastAllOfMatcher<Decl, TypedefNameDecl>
+extern const internal::VariadicDynCastAllOfMatcher<Decl, TypedefNameDecl>
typedefNameDecl;
/// \brief Matches type alias declarations.
@@ -178,7 +214,8 @@ const internal::VariadicDynCastAllOfMatcher<Decl, TypedefNameDecl>
/// \endcode
/// typeAliasDecl()
/// matches "using Y = int", but not "typedef int X"
-const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasDecl> typeAliasDecl;
+extern const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasDecl>
+ typeAliasDecl;
/// \brief Matches type alias template declarations.
///
@@ -187,7 +224,7 @@ const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasDecl> typeAliasDecl;
/// template <typename T>
/// using Y = X<T>;
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasTemplateDecl>
+extern const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasTemplateDecl>
typeAliasTemplateDecl;
/// \brief Matches AST nodes that were expanded within the main-file.
@@ -278,7 +315,7 @@ AST_POLYMORPHIC_MATCHER_P(isExpansionInFileMatching,
/// friend X;
/// };
/// \endcode
-const internal::VariadicAllOfMatcher<Decl> decl;
+extern const internal::VariadicAllOfMatcher<Decl> decl;
/// \brief Matches a declaration of a linkage specification.
///
@@ -288,7 +325,7 @@ const internal::VariadicAllOfMatcher<Decl> decl;
/// \endcode
/// linkageSpecDecl()
/// matches "extern "C" {}"
-const internal::VariadicDynCastAllOfMatcher<Decl, LinkageSpecDecl>
+extern const internal::VariadicDynCastAllOfMatcher<Decl, LinkageSpecDecl>
linkageSpecDecl;
/// \brief Matches a declaration of anything that could have a name.
@@ -302,7 +339,7 @@ const internal::VariadicDynCastAllOfMatcher<Decl, LinkageSpecDecl>
/// } U;
/// };
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Decl, NamedDecl> namedDecl;
+extern const internal::VariadicDynCastAllOfMatcher<Decl, NamedDecl> namedDecl;
/// \brief Matches a declaration of label.
///
@@ -313,7 +350,7 @@ const internal::VariadicDynCastAllOfMatcher<Decl, NamedDecl> namedDecl;
/// \endcode
/// labelDecl()
/// matches 'FOO:'
-const internal::VariadicDynCastAllOfMatcher<Decl, LabelDecl> labelDecl;
+extern const internal::VariadicDynCastAllOfMatcher<Decl, LabelDecl> labelDecl;
/// \brief Matches a declaration of a namespace.
///
@@ -324,7 +361,8 @@ const internal::VariadicDynCastAllOfMatcher<Decl, LabelDecl> labelDecl;
/// \endcode
/// namespaceDecl()
/// matches "namespace {}" and "namespace test {}"
-const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceDecl> namespaceDecl;
+extern const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceDecl>
+ namespaceDecl;
/// \brief Matches a declaration of a namespace alias.
///
@@ -335,7 +373,7 @@ const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceDecl> namespaceDecl;
/// \endcode
/// namespaceAliasDecl()
/// matches "namespace alias" but not "namespace test"
-const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceAliasDecl>
+extern const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceAliasDecl>
namespaceAliasDecl;
/// \brief Matches class, struct, and union declarations.
@@ -347,9 +385,7 @@ const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceAliasDecl>
/// struct S {};
/// union U {};
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Decl,
- RecordDecl> recordDecl;
+extern const internal::VariadicDynCastAllOfMatcher<Decl, RecordDecl> recordDecl;
/// \brief Matches C++ class declarations.
///
@@ -358,9 +394,8 @@ const internal::VariadicDynCastAllOfMatcher<
/// class X;
/// template<class T> class Z {};
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Decl,
- CXXRecordDecl> cxxRecordDecl;
+extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXRecordDecl>
+ cxxRecordDecl;
/// \brief Matches C++ class template declarations.
///
@@ -368,9 +403,8 @@ const internal::VariadicDynCastAllOfMatcher<
/// \code
/// template<class T> class Z {};
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Decl,
- ClassTemplateDecl> classTemplateDecl;
+extern const internal::VariadicDynCastAllOfMatcher<Decl, ClassTemplateDecl>
+ classTemplateDecl;
/// \brief Matches C++ class template specializations.
///
@@ -382,9 +416,9 @@ const internal::VariadicDynCastAllOfMatcher<
/// \endcode
/// classTemplateSpecializationDecl()
/// matches the specializations \c A<int> and \c A<double>
-const internal::VariadicDynCastAllOfMatcher<
- Decl,
- ClassTemplateSpecializationDecl> classTemplateSpecializationDecl;
+extern const internal::VariadicDynCastAllOfMatcher<
+ Decl, ClassTemplateSpecializationDecl>
+ classTemplateSpecializationDecl;
/// \brief Matches declarator declarations (field, variable, function
/// and non-type template parameter declarations).
@@ -395,7 +429,7 @@ const internal::VariadicDynCastAllOfMatcher<
/// \endcode
/// declaratorDecl()
/// matches \c int y.
-const internal::VariadicDynCastAllOfMatcher<Decl, DeclaratorDecl>
+extern const internal::VariadicDynCastAllOfMatcher<Decl, DeclaratorDecl>
declaratorDecl;
/// \brief Matches parameter variable declarations.
@@ -406,7 +440,8 @@ const internal::VariadicDynCastAllOfMatcher<Decl, DeclaratorDecl>
/// \endcode
/// parmVarDecl()
/// matches \c int x.
-const internal::VariadicDynCastAllOfMatcher<Decl, ParmVarDecl> parmVarDecl;
+extern const internal::VariadicDynCastAllOfMatcher<Decl, ParmVarDecl>
+ parmVarDecl;
/// \brief Matches C++ access specifier declarations.
///
@@ -419,9 +454,8 @@ const internal::VariadicDynCastAllOfMatcher<Decl, ParmVarDecl> parmVarDecl;
/// \endcode
/// accessSpecDecl()
/// matches 'public:'
-const internal::VariadicDynCastAllOfMatcher<
- Decl,
- AccessSpecDecl> accessSpecDecl;
+extern const internal::VariadicDynCastAllOfMatcher<Decl, AccessSpecDecl>
+ accessSpecDecl;
/// \brief Matches constructor initializers.
///
@@ -432,7 +466,8 @@ const internal::VariadicDynCastAllOfMatcher<
/// int i;
/// };
/// \endcode
-const internal::VariadicAllOfMatcher<CXXCtorInitializer> cxxCtorInitializer;
+extern const internal::VariadicAllOfMatcher<CXXCtorInitializer>
+ cxxCtorInitializer;
/// \brief Matches template arguments.
///
@@ -443,7 +478,7 @@ const internal::VariadicAllOfMatcher<CXXCtorInitializer> cxxCtorInitializer;
/// \endcode
/// templateArgument()
/// matches 'int' in C<int>.
-const internal::VariadicAllOfMatcher<TemplateArgument> templateArgument;
+extern const internal::VariadicAllOfMatcher<TemplateArgument> templateArgument;
/// \brief Matches template name.
///
@@ -454,7 +489,7 @@ const internal::VariadicAllOfMatcher<TemplateArgument> templateArgument;
/// \endcode
/// templateName()
/// matches 'X' in X<int>.
-const internal::VariadicAllOfMatcher<TemplateName> templateName;
+extern const internal::VariadicAllOfMatcher<TemplateName> templateName;
/// \brief Matches non-type template parameter declarations.
///
@@ -464,9 +499,9 @@ const internal::VariadicAllOfMatcher<TemplateName> templateName;
/// \endcode
/// nonTypeTemplateParmDecl()
/// matches 'N', but not 'T'.
-const internal::VariadicDynCastAllOfMatcher<
- Decl,
- NonTypeTemplateParmDecl> nonTypeTemplateParmDecl;
+extern const internal::VariadicDynCastAllOfMatcher<Decl,
+ NonTypeTemplateParmDecl>
+ nonTypeTemplateParmDecl;
/// \brief Matches template type parameter declarations.
///
@@ -476,9 +511,8 @@ const internal::VariadicDynCastAllOfMatcher<
/// \endcode
/// templateTypeParmDecl()
/// matches 'T', but not 'N'.
-const internal::VariadicDynCastAllOfMatcher<
- Decl,
- TemplateTypeParmDecl> templateTypeParmDecl;
+extern const internal::VariadicDynCastAllOfMatcher<Decl, TemplateTypeParmDecl>
+ templateTypeParmDecl;
/// \brief Matches public C++ declarations.
///
@@ -582,6 +616,23 @@ AST_MATCHER_P(FieldDecl, hasInClassInitializer, internal::Matcher<Expr>,
InnerMatcher.matches(*Initializer, Finder, Builder));
}
+/// \brief Matches the specialized template of a specialization declaration.
+///
+/// Given
+/// \code
+/// tempalate<typename T> class A {};
+/// typedef A<int> B;
+/// \endcode
+/// classTemplateSpecializationDecl(hasSpecializedTemplate(classTemplateDecl()))
+/// matches 'B' with classTemplateDecl() matching the class template
+/// declaration of 'A'.
+AST_MATCHER_P(ClassTemplateSpecializationDecl, hasSpecializedTemplate,
+ internal::Matcher<ClassTemplateDecl>, InnerMatcher) {
+ const ClassTemplateDecl* Decl = Node.getSpecializedTemplate();
+ return (Decl != nullptr &&
+ InnerMatcher.matches(*Decl, Finder, Builder));
+}
+
/// \brief Matches a declaration that has been implicitly added
/// by the compiler (eg. implicit default/copy constructors).
AST_MATCHER(Decl, isImplicit) {
@@ -922,7 +973,7 @@ AST_MATCHER_P(TemplateArgument, equalsIntegralValue,
/// enum X { A, B, C };
/// void F();
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Decl, ValueDecl> valueDecl;
+extern const internal::VariadicDynCastAllOfMatcher<Decl, ValueDecl> valueDecl;
/// \brief Matches C++ constructor declarations.
///
@@ -935,9 +986,8 @@ const internal::VariadicDynCastAllOfMatcher<Decl, ValueDecl> valueDecl;
/// int DoSomething();
/// };
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Decl,
- CXXConstructorDecl> cxxConstructorDecl;
+extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXConstructorDecl>
+ cxxConstructorDecl;
/// \brief Matches explicit C++ destructor declarations.
///
@@ -948,9 +998,8 @@ const internal::VariadicDynCastAllOfMatcher<
/// virtual ~Foo();
/// };
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Decl,
- CXXDestructorDecl> cxxDestructorDecl;
+extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXDestructorDecl>
+ cxxDestructorDecl;
/// \brief Matches enum declarations.
///
@@ -960,7 +1009,7 @@ const internal::VariadicDynCastAllOfMatcher<
/// A, B, C
/// };
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Decl, EnumDecl> enumDecl;
+extern const internal::VariadicDynCastAllOfMatcher<Decl, EnumDecl> enumDecl;
/// \brief Matches enum constants.
///
@@ -970,9 +1019,8 @@ const internal::VariadicDynCastAllOfMatcher<Decl, EnumDecl> enumDecl;
/// A, B, C
/// };
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Decl,
- EnumConstantDecl> enumConstantDecl;
+extern const internal::VariadicDynCastAllOfMatcher<Decl, EnumConstantDecl>
+ enumConstantDecl;
/// \brief Matches method declarations.
///
@@ -980,7 +1028,8 @@ const internal::VariadicDynCastAllOfMatcher<
/// \code
/// class X { void y(); };
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Decl, CXXMethodDecl> cxxMethodDecl;
+extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXMethodDecl>
+ cxxMethodDecl;
/// \brief Matches conversion operator declarations.
///
@@ -988,7 +1037,7 @@ const internal::VariadicDynCastAllOfMatcher<Decl, CXXMethodDecl> cxxMethodDecl;
/// \code
/// class X { operator int() const; };
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Decl, CXXConversionDecl>
+extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXConversionDecl>
cxxConversionDecl;
/// \brief Matches variable declarations.
@@ -1000,7 +1049,7 @@ const internal::VariadicDynCastAllOfMatcher<Decl, CXXConversionDecl>
/// \code
/// int a;
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Decl, VarDecl> varDecl;
+extern const internal::VariadicDynCastAllOfMatcher<Decl, VarDecl> varDecl;
/// \brief Matches field declarations.
///
@@ -1010,7 +1059,7 @@ const internal::VariadicDynCastAllOfMatcher<Decl, VarDecl> varDecl;
/// \endcode
/// fieldDecl()
/// matches 'm'.
-const internal::VariadicDynCastAllOfMatcher<Decl, FieldDecl> fieldDecl;
+extern const internal::VariadicDynCastAllOfMatcher<Decl, FieldDecl> fieldDecl;
/// \brief Matches function declarations.
///
@@ -1018,7 +1067,8 @@ const internal::VariadicDynCastAllOfMatcher<Decl, FieldDecl> fieldDecl;
/// \code
/// void f();
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Decl, FunctionDecl> functionDecl;
+extern const internal::VariadicDynCastAllOfMatcher<Decl, FunctionDecl>
+ functionDecl;
/// \brief Matches C++ function template declarations.
///
@@ -1026,9 +1076,8 @@ const internal::VariadicDynCastAllOfMatcher<Decl, FunctionDecl> functionDecl;
/// \code
/// template<class T> void f(T t) {}
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Decl,
- FunctionTemplateDecl> functionTemplateDecl;
+extern const internal::VariadicDynCastAllOfMatcher<Decl, FunctionTemplateDecl>
+ functionTemplateDecl;
/// \brief Matches friend declarations.
///
@@ -1038,7 +1087,7 @@ const internal::VariadicDynCastAllOfMatcher<
/// \endcode
/// friendDecl()
/// matches 'friend void foo()'.
-const internal::VariadicDynCastAllOfMatcher<Decl, FriendDecl> friendDecl;
+extern const internal::VariadicDynCastAllOfMatcher<Decl, FriendDecl> friendDecl;
/// \brief Matches statements.
///
@@ -1048,7 +1097,7 @@ const internal::VariadicDynCastAllOfMatcher<Decl, FriendDecl> friendDecl;
/// \endcode
/// stmt()
/// matches both the compound statement '{ ++a; }' and '++a'.
-const internal::VariadicAllOfMatcher<Stmt> stmt;
+extern const internal::VariadicAllOfMatcher<Stmt> stmt;
/// \brief Matches declaration statements.
///
@@ -1058,9 +1107,7 @@ const internal::VariadicAllOfMatcher<Stmt> stmt;
/// \endcode
/// declStmt()
/// matches 'int a'.
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- DeclStmt> declStmt;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, DeclStmt> declStmt;
/// \brief Matches member expressions.
///
@@ -1073,7 +1120,7 @@ const internal::VariadicDynCastAllOfMatcher<
/// \endcode
/// memberExpr()
/// matches this->x, x, y.x, a, this->b
-const internal::VariadicDynCastAllOfMatcher<Stmt, MemberExpr> memberExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, MemberExpr> memberExpr;
/// \brief Matches call expressions.
///
@@ -1083,7 +1130,7 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, MemberExpr> memberExpr;
/// x.y();
/// y();
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Stmt, CallExpr> callExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, CallExpr> callExpr;
/// \brief Matches lambda expressions.
///
@@ -1091,7 +1138,7 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, CallExpr> callExpr;
/// \code
/// [&](){return 5;}
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Stmt, LambdaExpr> lambdaExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, LambdaExpr> lambdaExpr;
/// \brief Matches member call expressions.
///
@@ -1100,9 +1147,8 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, LambdaExpr> lambdaExpr;
/// X x;
/// x.y();
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CXXMemberCallExpr> cxxMemberCallExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXMemberCallExpr>
+ cxxMemberCallExpr;
/// \brief Matches ObjectiveC Message invocation expressions.
///
@@ -1113,9 +1159,8 @@ const internal::VariadicDynCastAllOfMatcher<
/// \code
/// [[NSString alloc] initWithString:@"Hello"]
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- ObjCMessageExpr> objcMessageExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCMessageExpr>
+ objcMessageExpr;
/// \brief Matches Objective-C interface declarations.
///
@@ -1124,9 +1169,18 @@ const internal::VariadicDynCastAllOfMatcher<
/// @interface Foo
/// @end
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Decl,
- ObjCInterfaceDecl> objcInterfaceDecl;
+extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCInterfaceDecl>
+ objcInterfaceDecl;
+
+/// \brief Matches Objective-C implementation declarations.
+///
+/// Example matches Foo
+/// \code
+/// @implementation Foo
+/// @end
+/// \endcode
+extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCImplementationDecl>
+ objcImplementationDecl;
/// \brief Matches Objective-C protocol declarations.
///
@@ -1135,9 +1189,8 @@ const internal::VariadicDynCastAllOfMatcher<
/// @protocol FooDelegate
/// @end
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Decl,
- ObjCProtocolDecl> objcProtocolDecl;
+extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCProtocolDecl>
+ objcProtocolDecl;
/// \brief Matches Objective-C category declarations.
///
@@ -1146,9 +1199,18 @@ const internal::VariadicDynCastAllOfMatcher<
/// @interface Foo (Additions)
/// @end
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Decl,
- ObjCCategoryDecl> objcCategoryDecl;
+extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCCategoryDecl>
+ objcCategoryDecl;
+
+/// \brief Matches Objective-C category definitions.
+///
+/// Example matches Foo (Additions)
+/// \code
+/// @implementation Foo (Additions)
+/// @end
+/// \endcode
+extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCCategoryImplDecl>
+ objcCategoryImplDecl;
/// \brief Matches Objective-C method declarations.
///
@@ -1162,9 +1224,8 @@ const internal::VariadicDynCastAllOfMatcher<
/// - (void)method {}
/// @end
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Decl,
- ObjCMethodDecl> objcMethodDecl;
+extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCMethodDecl>
+ objcMethodDecl;
/// \brief Matches Objective-C instance variable declarations.
///
@@ -1175,9 +1236,8 @@ const internal::VariadicDynCastAllOfMatcher<
/// }
/// @end
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Decl,
- ObjCIvarDecl> objcIvarDecl;
+extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCIvarDecl>
+ objcIvarDecl;
/// \brief Matches Objective-C property declarations.
///
@@ -1187,9 +1247,47 @@ const internal::VariadicDynCastAllOfMatcher<
/// @property BOOL enabled;
/// @end
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Decl,
- ObjCPropertyDecl> objcPropertyDecl;
+extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCPropertyDecl>
+ objcPropertyDecl;
+
+/// \brief Matches Objective-C \@throw statements.
+///
+/// Example matches \@throw
+/// \code
+/// @throw obj;
+/// \endcode
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtThrowStmt>
+ objcThrowStmt;
+
+/// \brief Matches Objective-C @try statements.
+///
+/// Example matches @try
+/// \code
+/// @try {}
+/// @catch (...) {}
+/// \endcode
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtTryStmt>
+ objcTryStmt;
+
+/// \brief Matches Objective-C @catch statements.
+///
+/// Example matches @catch
+/// \code
+/// @try {}
+/// @catch (...) {}
+/// \endcode
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtCatchStmt>
+ objcCatchStmt;
+
+/// \brief Matches Objective-C @finally statements.
+///
+/// Example matches @finally
+/// \code
+/// @try {}
+/// @finally {}
+/// \endcode
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtFinallyStmt>
+ objcFinallyStmt;
/// \brief Matches expressions that introduce cleanups to be run at the end
/// of the sub-expression's evaluation.
@@ -1198,9 +1296,8 @@ const internal::VariadicDynCastAllOfMatcher<
/// \code
/// const std::string str = std::string();
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- ExprWithCleanups> exprWithCleanups;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, ExprWithCleanups>
+ exprWithCleanups;
/// \brief Matches init list expressions.
///
@@ -1212,7 +1309,8 @@ const internal::VariadicDynCastAllOfMatcher<
/// \endcode
/// initListExpr()
/// matches "{ 1, 2 }" and "{ 5, 6 }"
-const internal::VariadicDynCastAllOfMatcher<Stmt, InitListExpr> initListExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, InitListExpr>
+ initListExpr;
/// \brief Matches the syntactic form of init list expressions
/// (if expression have it).
@@ -1234,8 +1332,9 @@ AST_MATCHER_P(InitListExpr, hasSyntacticForm,
/// \endcode
/// cxxStdInitializerListExpr()
/// matches "{ 1, 2, 3 }" and "{ 4, 5 }"
-const internal::VariadicDynCastAllOfMatcher<Stmt,
- CXXStdInitializerListExpr> cxxStdInitializerListExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt,
+ CXXStdInitializerListExpr>
+ cxxStdInitializerListExpr;
/// \brief Matches implicit initializers of init list expressions.
///
@@ -1245,8 +1344,8 @@ const internal::VariadicDynCastAllOfMatcher<Stmt,
/// \endcode
/// implicitValueInitExpr()
/// matches "[0].y" (implicitly)
-const internal::VariadicDynCastAllOfMatcher<Stmt, ImplicitValueInitExpr>
-implicitValueInitExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, ImplicitValueInitExpr>
+ implicitValueInitExpr;
/// \brief Matches paren list expressions.
/// ParenListExprs don't have a predefined type and are used for late parsing.
@@ -1263,7 +1362,8 @@ implicitValueInitExpr;
/// \endcode
/// parenListExpr() matches "*this" but NOT matches (a, b) because (a, b)
/// has a predefined type and is a ParenExpr, not a ParenListExpr.
-const internal::VariadicDynCastAllOfMatcher<Stmt, ParenListExpr> parenListExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, ParenListExpr>
+ parenListExpr;
/// \brief Matches substitutions of non-type template parameters.
///
@@ -1275,9 +1375,9 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, ParenListExpr> parenListExpr;
/// \endcode
/// substNonTypeTemplateParmExpr()
/// matches "N" in the right-hand side of "static const int n = N;"
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- SubstNonTypeTemplateParmExpr> substNonTypeTemplateParmExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt,
+ SubstNonTypeTemplateParmExpr>
+ substNonTypeTemplateParmExpr;
/// \brief Matches using declarations.
///
@@ -1288,7 +1388,7 @@ const internal::VariadicDynCastAllOfMatcher<
/// \endcode
/// usingDecl()
/// matches \code using X::x \endcode
-const internal::VariadicDynCastAllOfMatcher<Decl, UsingDecl> usingDecl;
+extern const internal::VariadicDynCastAllOfMatcher<Decl, UsingDecl> usingDecl;
/// \brief Matches using namespace declarations.
///
@@ -1299,9 +1399,8 @@ const internal::VariadicDynCastAllOfMatcher<Decl, UsingDecl> usingDecl;
/// \endcode
/// usingDirectiveDecl()
/// matches \code using namespace X \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Decl,
- UsingDirectiveDecl> usingDirectiveDecl;
+extern const internal::VariadicDynCastAllOfMatcher<Decl, UsingDirectiveDecl>
+ usingDirectiveDecl;
/// \brief Matches reference to a name that can be looked up during parsing
/// but could not be resolved to a specific declaration.
@@ -1317,9 +1416,8 @@ const internal::VariadicDynCastAllOfMatcher<
/// \endcode
/// unresolvedLookupExpr()
/// matches \code foo<T>() \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- UnresolvedLookupExpr> unresolvedLookupExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, UnresolvedLookupExpr>
+ unresolvedLookupExpr;
/// \brief Matches unresolved using value declarations.
///
@@ -1332,9 +1430,9 @@ const internal::VariadicDynCastAllOfMatcher<
/// \endcode
/// unresolvedUsingValueDecl()
/// matches \code using X::x \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Decl,
- UnresolvedUsingValueDecl> unresolvedUsingValueDecl;
+extern const internal::VariadicDynCastAllOfMatcher<Decl,
+ UnresolvedUsingValueDecl>
+ unresolvedUsingValueDecl;
/// \brief Matches unresolved using value declarations that involve the
/// typename.
@@ -1351,9 +1449,9 @@ const internal::VariadicDynCastAllOfMatcher<
/// \endcode
/// unresolvedUsingTypenameDecl()
/// matches \code using Base<T>::Foo \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Decl,
- UnresolvedUsingTypenameDecl> unresolvedUsingTypenameDecl;
+extern const internal::VariadicDynCastAllOfMatcher<Decl,
+ UnresolvedUsingTypenameDecl>
+ unresolvedUsingTypenameDecl;
/// \brief Matches parentheses used in expressions.
///
@@ -1362,9 +1460,7 @@ const internal::VariadicDynCastAllOfMatcher<
/// int foo() { return 1; }
/// int a = (foo() + 1);
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- ParenExpr> parenExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, ParenExpr> parenExpr;
/// \brief Matches constructor call expressions (including implicit ones).
///
@@ -1376,9 +1472,8 @@ const internal::VariadicDynCastAllOfMatcher<
/// int n;
/// f(string(ptr, n), ptr);
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CXXConstructExpr> cxxConstructExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXConstructExpr>
+ cxxConstructExpr;
/// \brief Matches unresolved constructor call expressions.
///
@@ -1388,9 +1483,9 @@ const internal::VariadicDynCastAllOfMatcher<
/// template <typename T>
/// void f(const T& t) { return T(t); }
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CXXUnresolvedConstructExpr> cxxUnresolvedConstructExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt,
+ CXXUnresolvedConstructExpr>
+ cxxUnresolvedConstructExpr;
/// \brief Matches implicit and explicit this expressions.
///
@@ -1402,7 +1497,8 @@ const internal::VariadicDynCastAllOfMatcher<
/// int f() { return i; }
/// };
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThisExpr> cxxThisExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThisExpr>
+ cxxThisExpr;
/// \brief Matches nodes where temporaries are created.
///
@@ -1412,9 +1508,8 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThisExpr> cxxThisExpr;
/// FunctionTakesString(GetStringByValue());
/// FunctionTakesStringByPointer(GetStringPointer());
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CXXBindTemporaryExpr> cxxBindTemporaryExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXBindTemporaryExpr>
+ cxxBindTemporaryExpr;
/// \brief Matches nodes where temporaries are materialized.
///
@@ -1434,9 +1529,9 @@ const internal::VariadicDynCastAllOfMatcher<
/// f();
/// f().func();
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- MaterializeTemporaryExpr> materializeTemporaryExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt,
+ MaterializeTemporaryExpr>
+ materializeTemporaryExpr;
/// \brief Matches new expressions.
///
@@ -1446,7 +1541,7 @@ const internal::VariadicDynCastAllOfMatcher<
/// \endcode
/// cxxNewExpr()
/// matches 'new X'.
-const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNewExpr> cxxNewExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNewExpr> cxxNewExpr;
/// \brief Matches delete expressions.
///
@@ -1456,7 +1551,8 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNewExpr> cxxNewExpr;
/// \endcode
/// cxxDeleteExpr()
/// matches 'delete X'.
-const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDeleteExpr> cxxDeleteExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDeleteExpr>
+ cxxDeleteExpr;
/// \brief Matches array subscript expressions.
///
@@ -1466,9 +1562,8 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDeleteExpr> cxxDeleteExpr;
/// \endcode
/// arraySubscriptExpr()
/// matches "a[1]"
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- ArraySubscriptExpr> arraySubscriptExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, ArraySubscriptExpr>
+ arraySubscriptExpr;
/// \brief Matches the value of a default argument at the call site.
///
@@ -1479,9 +1574,8 @@ const internal::VariadicDynCastAllOfMatcher<
/// void f(int x, int y = 0);
/// f(42);
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CXXDefaultArgExpr> cxxDefaultArgExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDefaultArgExpr>
+ cxxDefaultArgExpr;
/// \brief Matches overloaded operator calls.
///
@@ -1497,9 +1591,8 @@ const internal::VariadicDynCastAllOfMatcher<
/// ostream &o; int b = 1, c = 1;
/// o << b << c;
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CXXOperatorCallExpr> cxxOperatorCallExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXOperatorCallExpr>
+ cxxOperatorCallExpr;
/// \brief Matches expressions.
///
@@ -1507,7 +1600,7 @@ const internal::VariadicDynCastAllOfMatcher<
/// \code
/// void f() { x(); }
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Stmt, Expr> expr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, Expr> expr;
/// \brief Matches expressions that refer to declarations.
///
@@ -1516,7 +1609,8 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, Expr> expr;
/// bool x;
/// if (x) {}
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Stmt, DeclRefExpr> declRefExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, DeclRefExpr>
+ declRefExpr;
/// \brief Matches if statements.
///
@@ -1524,7 +1618,7 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, DeclRefExpr> declRefExpr;
/// \code
/// if (x) {}
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Stmt, IfStmt> ifStmt;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, IfStmt> ifStmt;
/// \brief Matches for statements.
///
@@ -1533,7 +1627,7 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, IfStmt> ifStmt;
/// for (;;) {}
/// int i[] = {1, 2, 3}; for (auto a : i);
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Stmt, ForStmt> forStmt;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, ForStmt> forStmt;
/// \brief Matches the increment statement of a for loop.
///
@@ -1571,9 +1665,8 @@ AST_MATCHER_P(ForStmt, hasLoopInit, internal::Matcher<Stmt>,
/// int i[] = {1, 2, 3}; for (auto a : i);
/// for(int j = 0; j < 5; ++j);
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CXXForRangeStmt> cxxForRangeStmt;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXForRangeStmt>
+ cxxForRangeStmt;
/// \brief Matches the initialization statement of a for loop.
///
@@ -1611,7 +1704,7 @@ AST_MATCHER_P(CXXForRangeStmt, hasRangeInit, internal::Matcher<Expr>,
/// \endcode
/// whileStmt()
/// matches 'while (true) {}'.
-const internal::VariadicDynCastAllOfMatcher<Stmt, WhileStmt> whileStmt;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, WhileStmt> whileStmt;
/// \brief Matches do statements.
///
@@ -1621,7 +1714,7 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, WhileStmt> whileStmt;
/// \endcode
/// doStmt()
/// matches 'do {} while(true)'
-const internal::VariadicDynCastAllOfMatcher<Stmt, DoStmt> doStmt;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, DoStmt> doStmt;
/// \brief Matches break statements.
///
@@ -1631,7 +1724,7 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, DoStmt> doStmt;
/// \endcode
/// breakStmt()
/// matches 'break'
-const internal::VariadicDynCastAllOfMatcher<Stmt, BreakStmt> breakStmt;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, BreakStmt> breakStmt;
/// \brief Matches continue statements.
///
@@ -1641,7 +1734,8 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, BreakStmt> breakStmt;
/// \endcode
/// continueStmt()
/// matches 'continue'
-const internal::VariadicDynCastAllOfMatcher<Stmt, ContinueStmt> continueStmt;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, ContinueStmt>
+ continueStmt;
/// \brief Matches return statements.
///
@@ -1651,7 +1745,7 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, ContinueStmt> continueStmt;
/// \endcode
/// returnStmt()
/// matches 'return 1'
-const internal::VariadicDynCastAllOfMatcher<Stmt, ReturnStmt> returnStmt;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, ReturnStmt> returnStmt;
/// \brief Matches goto statements.
///
@@ -1662,7 +1756,7 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, ReturnStmt> returnStmt;
/// \endcode
/// gotoStmt()
/// matches 'goto FOO'
-const internal::VariadicDynCastAllOfMatcher<Stmt, GotoStmt> gotoStmt;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, GotoStmt> gotoStmt;
/// \brief Matches label statements.
///
@@ -1673,7 +1767,7 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, GotoStmt> gotoStmt;
/// \endcode
/// labelStmt()
/// matches 'FOO:'
-const internal::VariadicDynCastAllOfMatcher<Stmt, LabelStmt> labelStmt;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, LabelStmt> labelStmt;
/// \brief Matches address of label statements (GNU extension).
///
@@ -1685,7 +1779,8 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, LabelStmt> labelStmt;
/// \endcode
/// addrLabelExpr()
/// matches '&&FOO'
-const internal::VariadicDynCastAllOfMatcher<Stmt, AddrLabelExpr> addrLabelExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, AddrLabelExpr>
+ addrLabelExpr;
/// \brief Matches switch statements.
///
@@ -1695,7 +1790,7 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, AddrLabelExpr> addrLabelExpr;
/// \endcode
/// switchStmt()
/// matches 'switch(a)'.
-const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchStmt> switchStmt;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchStmt> switchStmt;
/// \brief Matches case and default statements inside switch statements.
///
@@ -1705,7 +1800,7 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchStmt> switchStmt;
/// \endcode
/// switchCase()
/// matches 'case 42: break;' and 'default: break;'.
-const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchCase> switchCase;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchCase> switchCase;
/// \brief Matches case statements inside switch statements.
///
@@ -1715,7 +1810,7 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchCase> switchCase;
/// \endcode
/// caseStmt()
/// matches 'case 42: break;'.
-const internal::VariadicDynCastAllOfMatcher<Stmt, CaseStmt> caseStmt;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, CaseStmt> caseStmt;
/// \brief Matches default statements inside switch statements.
///
@@ -1725,7 +1820,8 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, CaseStmt> caseStmt;
/// \endcode
/// defaultStmt()
/// matches 'default: break;'.
-const internal::VariadicDynCastAllOfMatcher<Stmt, DefaultStmt> defaultStmt;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, DefaultStmt>
+ defaultStmt;
/// \brief Matches compound statements.
///
@@ -1733,7 +1829,8 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, DefaultStmt> defaultStmt;
/// \code
/// for (;;) {{}}
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundStmt> compoundStmt;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundStmt>
+ compoundStmt;
/// \brief Matches catch statements.
///
@@ -1742,7 +1839,8 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundStmt> compoundStmt;
/// \endcode
/// cxxCatchStmt()
/// matches 'catch(int i)'
-const internal::VariadicDynCastAllOfMatcher<Stmt, CXXCatchStmt> cxxCatchStmt;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXCatchStmt>
+ cxxCatchStmt;
/// \brief Matches try statements.
///
@@ -1751,7 +1849,7 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, CXXCatchStmt> cxxCatchStmt;
/// \endcode
/// cxxTryStmt()
/// matches 'try {}'
-const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTryStmt> cxxTryStmt;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTryStmt> cxxTryStmt;
/// \brief Matches throw expressions.
///
@@ -1760,7 +1858,8 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTryStmt> cxxTryStmt;
/// \endcode
/// cxxThrowExpr()
/// matches 'throw 5'
-const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThrowExpr> cxxThrowExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThrowExpr>
+ cxxThrowExpr;
/// \brief Matches null statements.
///
@@ -1769,7 +1868,7 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThrowExpr> cxxThrowExpr;
/// \endcode
/// nullStmt()
/// matches the second ';'
-const internal::VariadicDynCastAllOfMatcher<Stmt, NullStmt> nullStmt;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, NullStmt> nullStmt;
/// \brief Matches asm statements.
///
@@ -1779,7 +1878,7 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, NullStmt> nullStmt;
/// \endcode
/// asmStmt()
/// matches '__asm("mov al, 2")'
-const internal::VariadicDynCastAllOfMatcher<Stmt, AsmStmt> asmStmt;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, AsmStmt> asmStmt;
/// \brief Matches bool literals.
///
@@ -1787,9 +1886,8 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, AsmStmt> asmStmt;
/// \code
/// true
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CXXBoolLiteralExpr> cxxBoolLiteral;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXBoolLiteralExpr>
+ cxxBoolLiteral;
/// \brief Matches string literals (also matches wide string literals).
///
@@ -1798,9 +1896,8 @@ const internal::VariadicDynCastAllOfMatcher<
/// char *s = "abcd";
/// wchar_t *ws = L"abcd";
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- StringLiteral> stringLiteral;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, StringLiteral>
+ stringLiteral;
/// \brief Matches character literals (also matches wchar_t).
///
@@ -1812,17 +1909,15 @@ const internal::VariadicDynCastAllOfMatcher<
/// char ch = 'a';
/// wchar_t chw = L'a';
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CharacterLiteral> characterLiteral;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, CharacterLiteral>
+ characterLiteral;
/// \brief Matches integer literals of all sizes / encodings, e.g.
/// 1, 1L, 0x1 and 1U.
///
/// Does not match character-encoded integers such as L'a'.
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- IntegerLiteral> integerLiteral;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, IntegerLiteral>
+ integerLiteral;
/// \brief Matches float literals of all sizes / encodings, e.g.
/// 1.0, 1.0f, 1.0L and 1e10.
@@ -1831,16 +1926,14 @@ const internal::VariadicDynCastAllOfMatcher<
/// \code
/// float a = 10;
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- FloatingLiteral> floatLiteral;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, FloatingLiteral>
+ floatLiteral;
/// \brief Matches user defined literal operator call.
///
/// Example match: "foo"_suffix
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- UserDefinedLiteral> userDefinedLiteral;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, UserDefinedLiteral>
+ userDefinedLiteral;
/// \brief Matches compound (i.e. non-scalar) literals
///
@@ -1849,24 +1942,23 @@ const internal::VariadicDynCastAllOfMatcher<
/// int array[4] = {1};
/// vector int myvec = (vector int)(1, 2);
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CompoundLiteralExpr> compoundLiteralExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundLiteralExpr>
+ compoundLiteralExpr;
/// \brief Matches nullptr literal.
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CXXNullPtrLiteralExpr> cxxNullPtrLiteralExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNullPtrLiteralExpr>
+ cxxNullPtrLiteralExpr;
/// \brief Matches GNU __null expression.
-const internal::VariadicDynCastAllOfMatcher<Stmt, GNUNullExpr> gnuNullExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, GNUNullExpr>
+ gnuNullExpr;
/// \brief Matches atomic builtins.
/// Example matches __atomic_load_n(ptr, 1)
/// \code
/// void foo() { int *ptr; __atomic_load_n(ptr, 1); }
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Stmt, AtomicExpr> atomicExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, AtomicExpr> atomicExpr;
/// \brief Matches statement expression (GNU extension).
///
@@ -1874,7 +1966,7 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, AtomicExpr> atomicExpr;
/// \code
/// int C = ({ int X = 4; X; });
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Stmt, StmtExpr> stmtExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, StmtExpr> stmtExpr;
/// \brief Matches binary operator expressions.
///
@@ -1882,9 +1974,8 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, StmtExpr> stmtExpr;
/// \code
/// !(a || b)
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- BinaryOperator> binaryOperator;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, BinaryOperator>
+ binaryOperator;
/// \brief Matches unary operator expressions.
///
@@ -1892,9 +1983,8 @@ const internal::VariadicDynCastAllOfMatcher<
/// \code
/// !a || b
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- UnaryOperator> unaryOperator;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, UnaryOperator>
+ unaryOperator;
/// \brief Matches conditional operator expressions.
///
@@ -1902,9 +1992,8 @@ const internal::VariadicDynCastAllOfMatcher<
/// \code
/// (a ? b : c) + 42
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- ConditionalOperator> conditionalOperator;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, ConditionalOperator>
+ conditionalOperator;
/// \brief Matches binary conditional operator expressions (GNU extension).
///
@@ -1912,9 +2001,9 @@ const internal::VariadicDynCastAllOfMatcher<
/// \code
/// (a ?: b) + 42;
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- BinaryConditionalOperator> binaryConditionalOperator;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt,
+ BinaryConditionalOperator>
+ binaryConditionalOperator;
/// \brief Matches opaque value expressions. They are used as helpers
/// to reference another expressions and can be met
@@ -1924,9 +2013,8 @@ const internal::VariadicDynCastAllOfMatcher<
/// \code
/// (a ?: c) + 42;
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- OpaqueValueExpr> opaqueValueExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, OpaqueValueExpr>
+ opaqueValueExpr;
/// \brief Matches a C++ static_assert declaration.
///
@@ -1941,9 +2029,8 @@ const internal::VariadicDynCastAllOfMatcher<
/// };
/// static_assert(sizeof(S) == sizeof(int));
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Decl,
- StaticAssertDecl> staticAssertDecl;
+extern const internal::VariadicDynCastAllOfMatcher<Decl, StaticAssertDecl>
+ staticAssertDecl;
/// \brief Matches a reinterpret_cast expression.
///
@@ -1955,9 +2042,8 @@ const internal::VariadicDynCastAllOfMatcher<
/// \code
/// void* p = reinterpret_cast<char*>(&p);
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CXXReinterpretCastExpr> cxxReinterpretCastExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXReinterpretCastExpr>
+ cxxReinterpretCastExpr;
/// \brief Matches a C++ static_cast expression.
///
@@ -1972,9 +2058,8 @@ const internal::VariadicDynCastAllOfMatcher<
/// \code
/// long eight(static_cast<long>(8));
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CXXStaticCastExpr> cxxStaticCastExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXStaticCastExpr>
+ cxxStaticCastExpr;
/// \brief Matches a dynamic_cast expression.
///
@@ -1988,9 +2073,8 @@ const internal::VariadicDynCastAllOfMatcher<
/// B b;
/// D* p = dynamic_cast<D*>(&b);
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CXXDynamicCastExpr> cxxDynamicCastExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDynamicCastExpr>
+ cxxDynamicCastExpr;
/// \brief Matches a const_cast expression.
///
@@ -2000,9 +2084,8 @@ const internal::VariadicDynCastAllOfMatcher<
/// const int &r(n);
/// int* p = const_cast<int*>(&r);
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CXXConstCastExpr> cxxConstCastExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXConstCastExpr>
+ cxxConstCastExpr;
/// \brief Matches a C-style cast expression.
///
@@ -2010,9 +2093,8 @@ const internal::VariadicDynCastAllOfMatcher<
/// \code
/// int i = (int) 2.2f;
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CStyleCastExpr> cStyleCastExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, CStyleCastExpr>
+ cStyleCastExpr;
/// \brief Matches explicit cast expressions.
///
@@ -2035,17 +2117,15 @@ const internal::VariadicDynCastAllOfMatcher<
/// \code
/// long ell = 42;
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- ExplicitCastExpr> explicitCastExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, ExplicitCastExpr>
+ explicitCastExpr;
/// \brief Matches the implicit cast nodes of Clang's AST.
///
/// This matches many different places, including function call return value
/// eliding, as well as any type conversions.
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- ImplicitCastExpr> implicitCastExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, ImplicitCastExpr>
+ implicitCastExpr;
/// \brief Matches any cast nodes of Clang's AST.
///
@@ -2060,7 +2140,7 @@ const internal::VariadicDynCastAllOfMatcher<
/// int i = (0);
/// int k = 0;
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Stmt, CastExpr> castExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, CastExpr> castExpr;
/// \brief Matches functional cast expressions
///
@@ -2070,9 +2150,8 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, CastExpr> castExpr;
/// Foo g = (Foo) bar;
/// Foo h = Foo(bar);
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CXXFunctionalCastExpr> cxxFunctionalCastExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXFunctionalCastExpr>
+ cxxFunctionalCastExpr;
/// \brief Matches functional cast expressions having N != 1 arguments
///
@@ -2080,9 +2159,8 @@ const internal::VariadicDynCastAllOfMatcher<
/// \code
/// Foo h = Foo(bar, bar);
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CXXTemporaryObjectExpr> cxxTemporaryObjectExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTemporaryObjectExpr>
+ cxxTemporaryObjectExpr;
/// \brief Matches predefined identifier expressions [C99 6.4.2.2].
///
@@ -2090,9 +2168,8 @@ const internal::VariadicDynCastAllOfMatcher<
/// \code
/// printf("%s", __func__);
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- PredefinedExpr> predefinedExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, PredefinedExpr>
+ predefinedExpr;
/// \brief Matches C99 designated initializer expressions [C99 6.7.8].
///
@@ -2100,9 +2177,8 @@ const internal::VariadicDynCastAllOfMatcher<
/// \code
/// point ptarray[10] = { [2].y = 1.0, [0].x = 1.0 };
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- DesignatedInitExpr> designatedInitExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, DesignatedInitExpr>
+ designatedInitExpr;
/// \brief Matches designated initializer expressions that contain
/// a specific number of designators.
@@ -2120,13 +2196,13 @@ AST_MATCHER_P(DesignatedInitExpr, designatorCountIs, unsigned, N) {
}
/// \brief Matches \c QualTypes in the clang AST.
-const internal::VariadicAllOfMatcher<QualType> qualType;
+extern const internal::VariadicAllOfMatcher<QualType> qualType;
/// \brief Matches \c Types in the clang AST.
-const internal::VariadicAllOfMatcher<Type> type;
+extern const internal::VariadicAllOfMatcher<Type> type;
/// \brief Matches \c TypeLocs in the clang AST.
-const internal::VariadicAllOfMatcher<TypeLoc> typeLoc;
+extern const internal::VariadicAllOfMatcher<TypeLoc> typeLoc;
/// \brief Matches if any of the given matchers matches.
///
@@ -2147,23 +2223,23 @@ const internal::VariadicAllOfMatcher<TypeLoc> typeLoc;
/// \c b.
///
/// Usable as: Any Matcher
-const internal::VariadicOperatorMatcherFunc<2, UINT_MAX> eachOf = {
- internal::DynTypedMatcher::VO_EachOf
-};
+extern const internal::VariadicOperatorMatcherFunc<
+ 2, std::numeric_limits<unsigned>::max()>
+ eachOf;
/// \brief Matches if any of the given matchers matches.
///
/// Usable as: Any Matcher
-const internal::VariadicOperatorMatcherFunc<2, UINT_MAX> anyOf = {
- internal::DynTypedMatcher::VO_AnyOf
-};
+extern const internal::VariadicOperatorMatcherFunc<
+ 2, std::numeric_limits<unsigned>::max()>
+ anyOf;
/// \brief Matches if all given matchers match.
///
/// Usable as: Any Matcher
-const internal::VariadicOperatorMatcherFunc<2, UINT_MAX> allOf = {
- internal::DynTypedMatcher::VO_AllOf
-};
+extern const internal::VariadicOperatorMatcherFunc<
+ 2, std::numeric_limits<unsigned>::max()>
+ allOf;
/// \brief Matches sizeof (C99), alignof (C++11) and vec_step (OpenCL)
///
@@ -2174,9 +2250,9 @@ const internal::VariadicOperatorMatcherFunc<2, UINT_MAX> allOf = {
/// \endcode
/// unaryExprOrTypeTraitExpr()
/// matches \c sizeof(x) and \c alignof(x)
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- UnaryExprOrTypeTraitExpr> unaryExprOrTypeTraitExpr;
+extern const internal::VariadicDynCastAllOfMatcher<Stmt,
+ UnaryExprOrTypeTraitExpr>
+ unaryExprOrTypeTraitExpr;
/// \brief Matches unary expressions that have a specific type of argument.
///
@@ -2252,9 +2328,9 @@ inline internal::Matcher<NamedDecl> hasName(const std::string &Name) {
/// \code
/// anyOf(hasName(a), hasName(b), hasName(c))
/// \endcode
-const internal::VariadicFunction<internal::Matcher<NamedDecl>, StringRef,
- internal::hasAnyNameFunc>
- hasAnyName = {};
+extern const internal::VariadicFunction<internal::Matcher<NamedDecl>, StringRef,
+ internal::hasAnyNameFunc>
+ hasAnyName;
/// \brief Matches NamedDecl nodes whose fully qualified names contain
/// a substring matched by the given RegExp.
@@ -2403,8 +2479,7 @@ AST_MATCHER(CXXRecordDecl, isLambda) {
/// casts and paren casts. If you are matching with expr then you should
/// probably consider using ignoringParenImpCasts like:
/// has(ignoringParenImpCasts(expr())).
-const internal::ArgumentAdaptingMatcherFunc<internal::HasMatcher>
-LLVM_ATTRIBUTE_UNUSED has = {};
+extern const internal::ArgumentAdaptingMatcherFunc<internal::HasMatcher> has;
/// \brief Matches AST nodes that have descendant AST nodes that match the
/// provided matcher.
@@ -2420,8 +2495,9 @@ LLVM_ATTRIBUTE_UNUSED has = {};
/// DescendantT must be an AST base type.
///
/// Usable as: Any Matcher
-const internal::ArgumentAdaptingMatcherFunc<internal::HasDescendantMatcher>
-LLVM_ATTRIBUTE_UNUSED hasDescendant = {};
+extern const internal::ArgumentAdaptingMatcherFunc<
+ internal::HasDescendantMatcher>
+ hasDescendant;
/// \brief Matches AST nodes that have child AST nodes that match the
/// provided matcher.
@@ -2440,8 +2516,8 @@ LLVM_ATTRIBUTE_UNUSED hasDescendant = {};
/// matches instead of only on the first one.
///
/// Usable as: Any Matcher
-const internal::ArgumentAdaptingMatcherFunc<internal::ForEachMatcher>
-LLVM_ATTRIBUTE_UNUSED forEach = {};
+extern const internal::ArgumentAdaptingMatcherFunc<internal::ForEachMatcher>
+ forEach;
/// \brief Matches AST nodes that have descendant AST nodes that match the
/// provided matcher.
@@ -2469,8 +2545,9 @@ LLVM_ATTRIBUTE_UNUSED forEach = {};
/// \endcode
///
/// Usable as: Any Matcher
-const internal::ArgumentAdaptingMatcherFunc<internal::ForEachDescendantMatcher>
-LLVM_ATTRIBUTE_UNUSED forEachDescendant = {};
+extern const internal::ArgumentAdaptingMatcherFunc<
+ internal::ForEachDescendantMatcher>
+ forEachDescendant;
/// \brief Matches if the node or any descendant matches.
///
@@ -2503,11 +2580,11 @@ internal::Matcher<T> findAll(const internal::Matcher<T> &Matcher) {
/// \c compoundStmt(hasParent(ifStmt())) matches "{ int x = 43; }".
///
/// Usable as: Any Matcher
-const internal::ArgumentAdaptingMatcherFunc<
+extern const internal::ArgumentAdaptingMatcherFunc<
internal::HasParentMatcher,
internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>,
internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>>
- LLVM_ATTRIBUTE_UNUSED hasParent = {};
+ hasParent;
/// \brief Matches AST nodes that have an ancestor that matches the provided
/// matcher.
@@ -2520,11 +2597,11 @@ const internal::ArgumentAdaptingMatcherFunc<
/// \c expr(integerLiteral(hasAncestor(ifStmt()))) matches \c 42, but not 43.
///
/// Usable as: Any Matcher
-const internal::ArgumentAdaptingMatcherFunc<
+extern const internal::ArgumentAdaptingMatcherFunc<
internal::HasAncestorMatcher,
internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>,
internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>>
- LLVM_ATTRIBUTE_UNUSED hasAncestor = {};
+ hasAncestor;
/// \brief Matches if the provided matcher does not match.
///
@@ -2535,9 +2612,7 @@ const internal::ArgumentAdaptingMatcherFunc<
/// \endcode
///
/// Usable as: Any Matcher
-const internal::VariadicOperatorMatcherFunc<1, 1> unless = {
- internal::DynTypedMatcher::VO_UnaryNot
-};
+extern const internal::VariadicOperatorMatcherFunc<1, 1> unless;
/// \brief Matches a node if the declaration associated with that node
/// matches the given matcher.
@@ -2549,8 +2624,21 @@ const internal::VariadicOperatorMatcherFunc<1, 1> unless = {
/// - for CXXConstructExpr, the declaration of the constructor
/// - for CXXNewExpr, the declaration of the operator new
///
-/// Also usable as Matcher<T> for any T supporting the getDecl() member
-/// function. e.g. various subtypes of clang::Type and various expressions.
+/// For type nodes, hasDeclaration will generally match the declaration of the
+/// sugared type. Given
+/// \code
+/// class X {};
+/// typedef X Y;
+/// Y y;
+/// \endcode
+/// in varDecl(hasType(hasDeclaration(decl()))) the decl will match the
+/// typedefDecl. A common use case is to match the underlying, desugared type.
+/// This can be achieved by using the hasUnqualifiedDesugaredType matcher:
+/// \code
+/// varDecl(hasType(hasUnqualifiedDesugaredType(
+/// recordType(hasDeclaration(decl())))))
+/// \endcode
+/// In this matcher, the decl will match the CXXRecordDecl of class X.
///
/// Usable as: Matcher<AddrLabelExpr>, Matcher<CallExpr>,
/// Matcher<CXXConstructExpr>, Matcher<CXXNewExpr>, Matcher<DeclRefExpr>,
@@ -2843,7 +2931,7 @@ AST_MATCHER_P_OVERLOAD(QualType, pointsTo, internal::Matcher<Decl>,
/// class A {};
/// using B = A;
/// \endcode
-/// The matcher type(hasUniqualifeidDesugaredType(recordType())) matches
+/// The matcher type(hasUnqualifeidDesugaredType(recordType())) matches
/// both B and A.
AST_MATCHER_P(Type, hasUnqualifiedDesugaredType, internal::Matcher<Type>,
InnerMatcher) {
@@ -3237,7 +3325,7 @@ AST_MATCHER_P(CXXConstructorDecl, hasAnyConstructorInitializer,
/// with forField matching foo_
AST_MATCHER_P(CXXCtorInitializer, forField,
internal::Matcher<FieldDecl>, InnerMatcher) {
- const FieldDecl *NodeAsDecl = Node.getMember();
+ const FieldDecl *NodeAsDecl = Node.getAnyMember();
return (NodeAsDecl != nullptr &&
InnerMatcher.matches(*NodeAsDecl, Finder, Builder));
}
@@ -3492,16 +3580,21 @@ AST_MATCHER_P(FunctionDecl, returns,
return InnerMatcher.matches(Node.getReturnType(), Finder, Builder);
}
-/// \brief Matches extern "C" function declarations.
+/// \brief Matches extern "C" function or variable declarations.
///
/// Given:
/// \code
/// extern "C" void f() {}
/// extern "C" { void g() {} }
/// void h() {}
+/// extern "C" int x = 1;
+/// extern "C" int y = 2;
+/// int z = 3;
/// \endcode
/// functionDecl(isExternC())
-/// matches the declaration of f and g, but not the declaration h
+/// matches the declaration of f and g, but not the declaration of h.
+/// varDecl(isExternC())
+/// matches the declaration of x and y, but not the declaration of z.
AST_POLYMORPHIC_MATCHER(isExternC, AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,
VarDecl)) {
return Node.isExternC();
@@ -3947,7 +4040,6 @@ AST_MATCHER_P(UnaryOperator, hasUnaryOperand,
/// \code
/// int a = b ?: 1;
/// \endcode
-
AST_POLYMORPHIC_MATCHER_P(hasSourceExpression,
AST_POLYMORPHIC_SUPPORTED_TYPES(CastExpr,
OpaqueValueExpr),
@@ -4067,11 +4159,19 @@ AST_MATCHER_P(AbstractConditionalOperator, hasFalseExpression,
/// extern int vb; // Doesn't match, as it doesn't define the variable.
/// void fa() {}
/// void fb(); // Doesn't match, as it has no body.
+/// @interface X
+/// - (void)ma; // Doesn't match, interface is declaration.
+/// @end
+/// @implementation X
+/// - (void)ma {}
+/// @end
/// \endcode
///
-/// Usable as: Matcher<TagDecl>, Matcher<VarDecl>, Matcher<FunctionDecl>
+/// Usable as: Matcher<TagDecl>, Matcher<VarDecl>, Matcher<FunctionDecl>,
+/// Matcher<ObjCMethodDecl>
AST_POLYMORPHIC_MATCHER(isDefinition,
AST_POLYMORPHIC_SUPPORTED_TYPES(TagDecl, VarDecl,
+ ObjCMethodDecl,
FunctionDecl)) {
return Node.isThisDeclarationADefinition();
}
@@ -4638,6 +4738,9 @@ AST_MATCHER(Type, voidType) {
return Node.isVoidType();
}
+template <typename NodeType>
+using AstTypeMatcher = internal::VariadicDynCastAllOfMatcher<Type, NodeType>;
+
/// \brief Matches builtin Types.
///
/// Given
@@ -4650,7 +4753,7 @@ AST_MATCHER(Type, voidType) {
/// \endcode
/// builtinType()
/// matches "int b", "float c" and "bool d"
-AST_TYPE_MATCHER(BuiltinType, builtinType);
+extern const AstTypeMatcher<BuiltinType> builtinType;
/// \brief Matches all kinds of arrays.
///
@@ -4662,7 +4765,7 @@ AST_TYPE_MATCHER(BuiltinType, builtinType);
/// \endcode
/// arrayType()
/// matches "int a[]", "int b[4]" and "int c[a[0]]";
-AST_TYPE_MATCHER(ArrayType, arrayType);
+extern const AstTypeMatcher<ArrayType> arrayType;
/// \brief Matches C99 complex types.
///
@@ -4672,7 +4775,7 @@ AST_TYPE_MATCHER(ArrayType, arrayType);
/// \endcode
/// complexType()
/// matches "_Complex float f"
-AST_TYPE_MATCHER(ComplexType, complexType);
+extern const AstTypeMatcher<ComplexType> complexType;
/// \brief Matches any real floating-point type (float, double, long double).
///
@@ -4700,9 +4803,9 @@ AST_MATCHER(Type, realFloatingPointType) {
/// matches "int b[7]"
///
/// Usable as: Matcher<ArrayType>, Matcher<ComplexType>
-AST_TYPELOC_TRAVERSE_MATCHER(hasElementType, getElement,
- AST_POLYMORPHIC_SUPPORTED_TYPES(ArrayType,
- ComplexType));
+AST_TYPELOC_TRAVERSE_MATCHER_DECL(hasElementType, getElement,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(ArrayType,
+ ComplexType));
/// \brief Matches C arrays with a specified constant size.
///
@@ -4716,7 +4819,7 @@ AST_TYPELOC_TRAVERSE_MATCHER(hasElementType, getElement,
/// \endcode
/// constantArrayType()
/// matches "int a[2]"
-AST_TYPE_MATCHER(ConstantArrayType, constantArrayType);
+extern const AstTypeMatcher<ConstantArrayType> constantArrayType;
/// \brief Matches nodes that have the specified size.
///
@@ -4751,7 +4854,7 @@ AST_POLYMORPHIC_MATCHER_P(hasSize,
/// \endcode
/// dependentSizedArrayType
/// matches "T data[Size]"
-AST_TYPE_MATCHER(DependentSizedArrayType, dependentSizedArrayType);
+extern const AstTypeMatcher<DependentSizedArrayType> dependentSizedArrayType;
/// \brief Matches C arrays with unspecified size.
///
@@ -4763,7 +4866,7 @@ AST_TYPE_MATCHER(DependentSizedArrayType, dependentSizedArrayType);
/// \endcode
/// incompleteArrayType()
/// matches "int a[]" and "int c[]"
-AST_TYPE_MATCHER(IncompleteArrayType, incompleteArrayType);
+extern const AstTypeMatcher<IncompleteArrayType> incompleteArrayType;
/// \brief Matches C arrays with a specified size that is not an
/// integer-constant-expression.
@@ -4778,7 +4881,7 @@ AST_TYPE_MATCHER(IncompleteArrayType, incompleteArrayType);
/// \endcode
/// variableArrayType()
/// matches "int c[a[0]]"
-AST_TYPE_MATCHER(VariableArrayType, variableArrayType);
+extern const AstTypeMatcher<VariableArrayType> variableArrayType;
/// \brief Matches \c VariableArrayType nodes that have a specific size
/// expression.
@@ -4805,7 +4908,7 @@ AST_MATCHER_P(VariableArrayType, hasSizeExpr,
/// \endcode
/// atomicType()
/// matches "_Atomic(int) i"
-AST_TYPE_MATCHER(AtomicType, atomicType);
+extern const AstTypeMatcher<AtomicType> atomicType;
/// \brief Matches atomic types with a specific value type.
///
@@ -4818,8 +4921,8 @@ AST_TYPE_MATCHER(AtomicType, atomicType);
/// matches "_Atomic(int) i"
///
/// Usable as: Matcher<AtomicType>
-AST_TYPELOC_TRAVERSE_MATCHER(hasValueType, getValue,
- AST_POLYMORPHIC_SUPPORTED_TYPES(AtomicType));
+AST_TYPELOC_TRAVERSE_MATCHER_DECL(hasValueType, getValue,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(AtomicType));
/// \brief Matches types nodes representing C++11 auto types.
///
@@ -4831,7 +4934,7 @@ AST_TYPELOC_TRAVERSE_MATCHER(hasValueType, getValue,
/// \endcode
/// autoType()
/// matches "auto n" and "auto i"
-AST_TYPE_MATCHER(AutoType, autoType);
+extern const AstTypeMatcher<AutoType> autoType;
/// \brief Matches \c AutoType nodes where the deduced type is a specific type.
///
@@ -4859,7 +4962,7 @@ AST_TYPE_TRAVERSE_MATCHER(hasDeducedType, getDeducedType,
/// \endcode
/// functionType()
/// matches "int (*f)(int)" and the type of "g".
-AST_TYPE_MATCHER(FunctionType, functionType);
+extern const AstTypeMatcher<FunctionType> functionType;
/// \brief Matches \c FunctionProtoType nodes.
///
@@ -4871,7 +4974,7 @@ AST_TYPE_MATCHER(FunctionType, functionType);
/// functionProtoType()
/// matches "int (*f)(int)" and the type of "g" in C++ mode.
/// In C mode, "g" is not matched because it does not contain a prototype.
-AST_TYPE_MATCHER(FunctionProtoType, functionProtoType);
+extern const AstTypeMatcher<FunctionProtoType> functionProtoType;
/// \brief Matches \c ParenType nodes.
///
@@ -4883,7 +4986,7 @@ AST_TYPE_MATCHER(FunctionProtoType, functionProtoType);
///
/// \c varDecl(hasType(pointsTo(parenType()))) matches \c ptr_to_array but not
/// \c array_of_ptrs.
-AST_TYPE_MATCHER(ParenType, parenType);
+extern const AstTypeMatcher<ParenType> parenType;
/// \brief Matches \c ParenType nodes where the inner type is a specific type.
///
@@ -4904,7 +5007,7 @@ AST_TYPE_TRAVERSE_MATCHER(innerType, getInnerType,
/// "void (^)(int)".
///
/// The \c pointee is always required to be a \c FunctionType.
-AST_TYPE_MATCHER(BlockPointerType, blockPointerType);
+extern const AstTypeMatcher<BlockPointerType> blockPointerType;
/// \brief Matches member pointer types.
/// Given
@@ -4914,7 +5017,7 @@ AST_TYPE_MATCHER(BlockPointerType, blockPointerType);
/// \endcode
/// memberPointerType()
/// matches "A::* ptr"
-AST_TYPE_MATCHER(MemberPointerType, memberPointerType);
+extern const AstTypeMatcher<MemberPointerType> memberPointerType;
/// \brief Matches pointer types, but does not match Objective-C object pointer
/// types.
@@ -4931,7 +5034,7 @@ AST_TYPE_MATCHER(MemberPointerType, memberPointerType);
/// \endcode
/// pointerType()
/// matches "int *a", but does not match "Foo *f".
-AST_TYPE_MATCHER(PointerType, pointerType);
+extern const AstTypeMatcher<PointerType> pointerType;
/// \brief Matches an Objective-C object pointer type, which is different from
/// a pointer type, despite being syntactically similar.
@@ -4946,7 +5049,7 @@ AST_TYPE_MATCHER(PointerType, pointerType);
/// \endcode
/// pointerType()
/// matches "Foo *f", but does not match "int *a".
-AST_TYPE_MATCHER(ObjCObjectPointerType, objcObjectPointerType);
+extern const AstTypeMatcher<ObjCObjectPointerType> objcObjectPointerType;
/// \brief Matches both lvalue and rvalue reference types.
///
@@ -4962,7 +5065,7 @@ AST_TYPE_MATCHER(ObjCObjectPointerType, objcObjectPointerType);
/// \endcode
///
/// \c referenceType() matches the types of \c b, \c c, \c d, \c e, and \c f.
-AST_TYPE_MATCHER(ReferenceType, referenceType);
+extern const AstTypeMatcher<ReferenceType> referenceType;
/// \brief Matches lvalue reference types.
///
@@ -4979,7 +5082,7 @@ AST_TYPE_MATCHER(ReferenceType, referenceType);
///
/// \c lValueReferenceType() matches the types of \c b, \c d, and \c e. \c e is
/// matched since the type is deduced as int& by reference collapsing rules.
-AST_TYPE_MATCHER(LValueReferenceType, lValueReferenceType);
+extern const AstTypeMatcher<LValueReferenceType> lValueReferenceType;
/// \brief Matches rvalue reference types.
///
@@ -4996,7 +5099,7 @@ AST_TYPE_MATCHER(LValueReferenceType, lValueReferenceType);
///
/// \c rValueReferenceType() matches the types of \c c and \c f. \c e is not
/// matched as it is deduced to int& by reference collapsing rules.
-AST_TYPE_MATCHER(RValueReferenceType, rValueReferenceType);
+extern const AstTypeMatcher<RValueReferenceType> rValueReferenceType;
/// \brief Narrows PointerType (and similar) matchers to those where the
/// \c pointee matches a given matcher.
@@ -5012,11 +5115,10 @@ AST_TYPE_MATCHER(RValueReferenceType, rValueReferenceType);
///
/// Usable as: Matcher<BlockPointerType>, Matcher<MemberPointerType>,
/// Matcher<PointerType>, Matcher<ReferenceType>
-AST_TYPELOC_TRAVERSE_MATCHER(pointee, getPointee,
- AST_POLYMORPHIC_SUPPORTED_TYPES(BlockPointerType,
- MemberPointerType,
- PointerType,
- ReferenceType));
+AST_TYPELOC_TRAVERSE_MATCHER_DECL(
+ pointee, getPointee,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(BlockPointerType, MemberPointerType,
+ PointerType, ReferenceType));
/// \brief Matches typedef types.
///
@@ -5026,7 +5128,7 @@ AST_TYPELOC_TRAVERSE_MATCHER(pointee, getPointee,
/// \endcode
/// typedefType()
/// matches "typedef int X"
-AST_TYPE_MATCHER(TypedefType, typedefType);
+extern const AstTypeMatcher<TypedefType> typedefType;
/// \brief Matches enum types.
///
@@ -5041,7 +5143,7 @@ AST_TYPE_MATCHER(TypedefType, typedefType);
//
/// \c enumType() matches the type of the variable declarations of both \c c and
/// \c s.
-AST_TYPE_MATCHER(EnumType, enumType);
+extern const AstTypeMatcher<EnumType> enumType;
/// \brief Matches template specialization types.
///
@@ -5056,7 +5158,8 @@ AST_TYPE_MATCHER(EnumType, enumType);
///
/// \c templateSpecializationType() matches the type of the explicit
/// instantiation in \c A and the type of the variable declaration in \c B.
-AST_TYPE_MATCHER(TemplateSpecializationType, templateSpecializationType);
+extern const AstTypeMatcher<TemplateSpecializationType>
+ templateSpecializationType;
/// \brief Matches types nodes representing unary type transformations.
///
@@ -5066,7 +5169,7 @@ AST_TYPE_MATCHER(TemplateSpecializationType, templateSpecializationType);
/// \endcode
/// unaryTransformType()
/// matches "__underlying_type(T)"
-AST_TYPE_MATCHER(UnaryTransformType, unaryTransformType);
+extern const AstTypeMatcher<UnaryTransformType> unaryTransformType;
/// \brief Matches record types (e.g. structs, classes).
///
@@ -5081,7 +5184,22 @@ AST_TYPE_MATCHER(UnaryTransformType, unaryTransformType);
///
/// \c recordType() matches the type of the variable declarations of both \c c
/// and \c s.
-AST_TYPE_MATCHER(RecordType, recordType);
+extern const AstTypeMatcher<RecordType> recordType;
+
+/// \brief Matches tag types (record and enum types).
+///
+/// Given
+/// \code
+/// enum E {};
+/// class C {};
+///
+/// E e;
+/// C c;
+/// \endcode
+///
+/// \c tagType() matches the type of the variable declarations of both \c e
+/// and \c c.
+extern const AstTypeMatcher<TagType> tagType;
/// \brief Matches types specified with an elaborated type keyword or with a
/// qualified name.
@@ -5101,7 +5219,7 @@ AST_TYPE_MATCHER(RecordType, recordType);
///
/// \c elaboratedType() matches the type of the variable declarations of both
/// \c c and \c d.
-AST_TYPE_MATCHER(ElaboratedType, elaboratedType);
+extern const AstTypeMatcher<ElaboratedType> elaboratedType;
/// \brief Matches ElaboratedTypes whose qualifier, a NestedNameSpecifier,
/// matches \c InnerMatcher if the qualifier exists.
@@ -5158,7 +5276,8 @@ AST_MATCHER_P(ElaboratedType, namesType, internal::Matcher<QualType>,
/// \endcode
///
/// \c substTemplateTypeParmType() matches the type of 't' but not '1'
-AST_TYPE_MATCHER(SubstTemplateTypeParmType, substTemplateTypeParmType);
+extern const AstTypeMatcher<SubstTemplateTypeParmType>
+ substTemplateTypeParmType;
/// \brief Matches template type parameter substitutions that have a replacement
/// type that matches the provided matcher.
@@ -5183,7 +5302,7 @@ AST_TYPE_TRAVERSE_MATCHER(
/// \code
/// template <typename T> void f(int i);
/// \endcode
-AST_TYPE_MATCHER(TemplateTypeParmType, templateTypeParmType);
+extern const AstTypeMatcher<TemplateTypeParmType> templateTypeParmType;
/// \brief Matches injected class name types.
///
@@ -5195,7 +5314,7 @@ AST_TYPE_MATCHER(TemplateTypeParmType, templateTypeParmType);
/// void g(S<T> s);
/// };
/// \endcode
-AST_TYPE_MATCHER(InjectedClassNameType, injectedClassNameType);
+extern const AstTypeMatcher<InjectedClassNameType> injectedClassNameType;
/// \brief Matches decayed type
/// Example matches i[] in declaration of f.
@@ -5207,7 +5326,7 @@ AST_TYPE_MATCHER(InjectedClassNameType, injectedClassNameType);
/// i[1] = 0;
/// }
/// \endcode
-AST_TYPE_MATCHER(DecayedType, decayedType);
+extern const AstTypeMatcher<DecayedType> decayedType;
/// \brief Matches the decayed type, whos decayed type matches \c InnerMatcher
AST_MATCHER_P(DecayedType, hasDecayedType, internal::Matcher<QualType>,
@@ -5248,11 +5367,12 @@ AST_MATCHER_P(Decl, hasDeclContext, internal::Matcher<Decl>, InnerMatcher) {
/// \endcode
/// nestedNameSpecifier()
/// matches "ns::" and both "A::"
-const internal::VariadicAllOfMatcher<NestedNameSpecifier> nestedNameSpecifier;
+extern const internal::VariadicAllOfMatcher<NestedNameSpecifier>
+ nestedNameSpecifier;
/// \brief Same as \c nestedNameSpecifier but matches \c NestedNameSpecifierLoc.
-const internal::VariadicAllOfMatcher<
- NestedNameSpecifierLoc> nestedNameSpecifierLoc;
+extern const internal::VariadicAllOfMatcher<NestedNameSpecifierLoc>
+ nestedNameSpecifierLoc;
/// \brief Matches \c NestedNameSpecifierLocs for which the given inner
/// NestedNameSpecifier-matcher matches.
@@ -5605,17 +5725,14 @@ AST_MATCHER_P(ReturnStmt, hasReturnValue, internal::Matcher<Expr>,
return false;
}
-
/// \brief Matches CUDA kernel call expression.
///
/// Example matches,
/// \code
/// kernel<<<i,j>>>();
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CUDAKernelCallExpr> cudaKernelCallExpr;
-
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, CUDAKernelCallExpr>
+ cudaKernelCallExpr;
/// \brief Matches expressions that resolve to a null pointer constant, such as
/// GNU's __null, C++11's nullptr, or C's NULL macro.
@@ -5700,7 +5817,54 @@ AST_MATCHER(NamedDecl, hasExternalFormalLinkage) {
return Node.hasExternalFormalLinkage();
}
-} // end namespace ast_matchers
-} // end namespace clang
+/// \brief Matches a declaration that has default arguments.
+///
+/// Example matches y (matcher = parmVarDecl(hasDefaultArgument()))
+/// \code
+/// void x(int val) {}
+/// void y(int val = 0) {}
+/// \endcode
+AST_MATCHER(ParmVarDecl, hasDefaultArgument) {
+ return Node.hasDefaultArg();
+}
+
+/// \brief Matches array new expressions.
+///
+/// Given:
+/// \code
+/// MyClass *p1 = new MyClass[10];
+/// \endcode
+/// cxxNewExpr(isArray())
+/// matches the expression 'new MyClass[10]'.
+AST_MATCHER(CXXNewExpr, isArray) {
+ return Node.isArray();
+}
+
+/// \brief Matches array new expressions with a given array size.
+///
+/// Given:
+/// \code
+/// MyClass *p1 = new MyClass[10];
+/// \endcode
+/// cxxNewExpr(hasArraySize(intgerLiteral(equals(10))))
+/// matches the expression 'new MyClass[10]'.
+AST_MATCHER_P(CXXNewExpr, hasArraySize, internal::Matcher<Expr>, InnerMatcher) {
+ return Node.isArray() &&
+ InnerMatcher.matches(*Node.getArraySize(), Finder, Builder);
+}
+
+/// \brief Matches a class declaration that is defined.
+///
+/// Example matches x (matcher = cxxRecordDecl(hasDefinition()))
+/// \code
+/// class x {};
+/// class y;
+/// \endcode
+AST_MATCHER(CXXRecordDecl, hasDefinition) {
+ return Node.hasDefinition();
+}
+
+} // namespace ast_matchers
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_ASTMATCHERS_ASTMATCHERS_H
diff --git a/include/clang/ASTMatchers/ASTMatchersInternal.h b/include/clang/ASTMatchers/ASTMatchersInternal.h
index bc75e807ced9..8bd61a76e185 100644
--- a/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ b/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -1,4 +1,4 @@
-//===--- ASTMatchersInternal.h - Structural query framework -----*- C++ -*-===//
+//===- ASTMatchersInternal.h - Structural query framework -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -38,23 +38,42 @@
#include "clang/AST/ASTTypeTraits.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
-#include "clang/AST/ExprObjC.h"
+#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/Stmt.h"
-#include "clang/AST/StmtCXX.h"
-#include "clang/AST/StmtObjC.h"
+#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
+#include "clang/AST/TypeLoc.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/OperatorKinds.h"
+#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/ManagedStatic.h"
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
#include <map>
#include <string>
+#include <tuple>
+#include <type_traits>
+#include <utility>
#include <vector>
namespace clang {
+
+class ASTContext;
+
namespace ast_matchers {
class BoundNodes;
@@ -158,7 +177,7 @@ public:
/// Note that we're using std::map here, as for memoization:
/// - we need a comparison operator
/// - we need an assignment operator
- typedef std::map<std::string, ast_type_traits::DynTypedNode> IDToNodeMap;
+ using IDToNodeMap = std::map<std::string, ast_type_traits::DynTypedNode>;
const IDToNodeMap &getMap() const {
return NodeMap;
@@ -188,7 +207,7 @@ public:
/// BoundNodesTree.
class Visitor {
public:
- virtual ~Visitor() {}
+ virtual ~Visitor() = default;
/// \brief Called multiple times during a single call to VisitMatches(...).
///
@@ -248,7 +267,7 @@ class ASTMatchFinder;
class DynMatcherInterface
: public llvm::ThreadSafeRefCountedBase<DynMatcherInterface> {
public:
- virtual ~DynMatcherInterface() {}
+ virtual ~DynMatcherInterface() = default;
/// \brief Returns true if \p DynNode can be matched.
///
@@ -317,26 +336,29 @@ public:
/// \brief Takes ownership of the provided implementation pointer.
template <typename T>
DynTypedMatcher(MatcherInterface<T> *Implementation)
- : AllowBind(false),
- SupportedKind(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()),
+ : SupportedKind(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()),
RestrictKind(SupportedKind), Implementation(Implementation) {}
/// \brief Construct from a variadic function.
enum VariadicOperator {
/// \brief Matches nodes for which all provided matchers match.
VO_AllOf,
+
/// \brief Matches nodes for which at least one of the provided matchers
/// matches.
VO_AnyOf,
+
/// \brief Matches nodes for which at least one of the provided matchers
/// matches, but doesn't stop at the first match.
VO_EachOf,
+
/// \brief Matches nodes that do not match the provided matcher.
///
/// Uses the variadic matcher interface, but fails if
/// InnerMatchers.size() != 1.
VO_UnaryNot
};
+
static DynTypedMatcher
constructVariadic(VariadicOperator Op,
ast_type_traits::ASTNodeKind SupportedKind,
@@ -382,7 +404,7 @@ public:
/// include both in the ID to make it unique.
///
/// \c MatcherIDType supports operator< and provides strict weak ordering.
- typedef std::pair<ast_type_traits::ASTNodeKind, uint64_t> MatcherIDType;
+ using MatcherIDType = std::pair<ast_type_traits::ASTNodeKind, uint64_t>;
MatcherIDType getID() const {
/// FIXME: Document the requirements this imposes on matcher
/// implementations (no new() implementation_ during a Matches()).
@@ -428,13 +450,12 @@ private:
DynTypedMatcher(ast_type_traits::ASTNodeKind SupportedKind,
ast_type_traits::ASTNodeKind RestrictKind,
IntrusiveRefCntPtr<DynMatcherInterface> Implementation)
- : AllowBind(false),
- SupportedKind(SupportedKind),
- RestrictKind(RestrictKind),
+ : SupportedKind(SupportedKind), RestrictKind(RestrictKind),
Implementation(std::move(Implementation)) {}
- bool AllowBind;
+ bool AllowBind = false;
ast_type_traits::ASTNodeKind SupportedKind;
+
/// \brief A potentially stricter node kind.
///
/// It allows to perform implicit and dynamic cast of matchers without
@@ -545,6 +566,7 @@ public:
private:
// For Matcher<T> <=> Matcher<U> conversions.
template <typename U> friend class Matcher;
+
// For DynTypedMatcher::unconditionalConvertTo<T>.
friend class DynTypedMatcher;
@@ -618,8 +640,8 @@ bool matchesFirstInPointerRange(const MatcherT &Matcher, IteratorT Start,
// Metafunction to determine if type T has a member called getDecl.
template <typename Ty>
class has_getDecl {
- typedef char yes[1];
- typedef char no[2];
+ using yes = char[1];
+ using no = char[2];
template <typename Inner>
static yes& test(Inner *I, decltype(I->getDecl()) * = nullptr);
@@ -728,48 +750,94 @@ public:
}
private:
- /// \brief If getDecl exists as a member of U, returns whether the inner
- /// matcher matches Node.getDecl().
- template <typename U>
- bool matchesSpecialized(
- const U &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
- typename std::enable_if<has_getDecl<U>::value, int>::type = 0) const {
- return matchesDecl(Node.getDecl(), Finder, Builder);
- }
-
- /// \brief Extracts the TagDecl of a QualType and returns whether the inner
- /// matcher matches on it.
+ /// \brief Forwards to matching on the underlying type of the QualType.
bool matchesSpecialized(const QualType &Node, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const {
if (Node.isNull())
return false;
- if (auto *TD = Node->getAsTagDecl())
- return matchesDecl(TD, Finder, Builder);
- else if (auto *TT = Node->getAs<TypedefType>())
- return matchesDecl(TT->getDecl(), Finder, Builder);
- // Do not use getAs<TemplateTypeParmType> instead of the direct dyn_cast.
- // Calling getAs will return the canonical type, but that type does not
- // store a TemplateTypeParmDecl. We *need* the uncanonical type, if it is
- // available, and using dyn_cast ensures that.
- else if (auto *TTP = dyn_cast<TemplateTypeParmType>(Node.getTypePtr()))
- return matchesDecl(TTP->getDecl(), Finder, Builder);
- else if (auto *OCIT = Node->getAs<ObjCInterfaceType>())
- return matchesDecl(OCIT->getDecl(), Finder, Builder);
- else if (auto *UUT = Node->getAs<UnresolvedUsingType>())
- return matchesDecl(UUT->getDecl(), Finder, Builder);
- else if (auto *ICNT = Node->getAs<InjectedClassNameType>())
- return matchesDecl(ICNT->getDecl(), Finder, Builder);
+ return matchesSpecialized(*Node, Finder, Builder);
+ }
+
+ /// \brief Finds the best declaration for a type and returns whether the inner
+ /// matcher matches on it.
+ bool matchesSpecialized(const Type &Node, ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const {
+ // DeducedType does not have declarations of its own, so
+ // match the deduced type instead.
+ const Type *EffectiveType = &Node;
+ if (const auto *S = dyn_cast<DeducedType>(&Node)) {
+ EffectiveType = S->getDeducedType().getTypePtrOrNull();
+ if (!EffectiveType)
+ return false;
+ }
+
+ // First, for any types that have a declaration, extract the declaration and
+ // match on it.
+ if (const auto *S = dyn_cast<TagType>(EffectiveType)) {
+ return matchesDecl(S->getDecl(), Finder, Builder);
+ }
+ if (const auto *S = dyn_cast<InjectedClassNameType>(EffectiveType)) {
+ return matchesDecl(S->getDecl(), Finder, Builder);
+ }
+ if (const auto *S = dyn_cast<TemplateTypeParmType>(EffectiveType)) {
+ return matchesDecl(S->getDecl(), Finder, Builder);
+ }
+ if (const auto *S = dyn_cast<TypedefType>(EffectiveType)) {
+ return matchesDecl(S->getDecl(), Finder, Builder);
+ }
+ if (const auto *S = dyn_cast<UnresolvedUsingType>(EffectiveType)) {
+ return matchesDecl(S->getDecl(), Finder, Builder);
+ }
+ if (const auto *S = dyn_cast<ObjCObjectType>(EffectiveType)) {
+ return matchesDecl(S->getInterface(), Finder, Builder);
+ }
+
+ // A SubstTemplateTypeParmType exists solely to mark a type substitution
+ // on the instantiated template. As users usually want to match the
+ // template parameter on the uninitialized template, we can always desugar
+ // one level without loss of expressivness.
+ // For example, given:
+ // template<typename T> struct X { T t; } class A {}; X<A> a;
+ // The following matcher will match, which otherwise would not:
+ // fieldDecl(hasType(pointerType())).
+ if (const auto *S = dyn_cast<SubstTemplateTypeParmType>(EffectiveType)) {
+ return matchesSpecialized(S->getReplacementType(), Finder, Builder);
+ }
+
+ // For template specialization types, we want to match the template
+ // declaration, as long as the type is still dependent, and otherwise the
+ // declaration of the instantiated tag type.
+ if (const auto *S = dyn_cast<TemplateSpecializationType>(EffectiveType)) {
+ if (!S->isTypeAlias() && S->isSugared()) {
+ // If the template is non-dependent, we want to match the instantiated
+ // tag type.
+ // For example, given:
+ // template<typename T> struct X {}; X<int> a;
+ // The following matcher will match, which otherwise would not:
+ // templateSpecializationType(hasDeclaration(cxxRecordDecl())).
+ return matchesSpecialized(*S->desugar(), Finder, Builder);
+ }
+ // If the template is dependent or an alias, match the template
+ // declaration.
+ return matchesDecl(S->getTemplateName().getAsTemplateDecl(), Finder,
+ Builder);
+ }
+
+ // FIXME: We desugar elaborated types. This makes the assumption that users
+ // do never want to match on whether a type is elaborated - there are
+ // arguments for both sides; for now, continue desugaring.
+ if (const auto *S = dyn_cast<ElaboratedType>(EffectiveType)) {
+ return matchesSpecialized(S->desugar(), Finder, Builder);
+ }
return false;
}
- /// \brief Gets the TemplateDecl from a TemplateSpecializationType
- /// and returns whether the inner matches on it.
- bool matchesSpecialized(const TemplateSpecializationType &Node,
- ASTMatchFinder *Finder,
+ /// \brief Extracts the Decl the DeclRefExpr references and returns whether
+ /// the inner matcher matches on it.
+ bool matchesSpecialized(const DeclRefExpr &Node, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const {
- return matchesDecl(Node.getTemplateName().getAsTemplateDecl(),
- Finder, Builder);
+ return matchesDecl(Node.getDecl(), Finder, Builder);
}
/// \brief Extracts the Decl of the callee of a CallExpr and returns whether
@@ -811,6 +879,13 @@ private:
return matchesDecl(Node.getLabel(), Finder, Builder);
}
+ /// \brief Extracts the declaration of a LabelStmt and returns whether the
+ /// inner matcher matches on it.
+ bool matchesSpecialized(const LabelStmt &Node, ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const {
+ return matchesDecl(Node.getDecl(), Finder, Builder);
+ }
+
/// \brief Returns whether the inner matcher \c Node. Returns false if \c Node
/// is \c NULL.
bool matchesDecl(const Decl *Node, ASTMatchFinder *Finder,
@@ -863,6 +938,7 @@ public:
enum TraversalKind {
/// Will traverse any child nodes.
TK_AsIs,
+
/// Will not traverse implicit casts and parentheses.
TK_IgnoreImplicitCastsAndParentheses
};
@@ -871,6 +947,7 @@ public:
enum BindKind {
/// Stop at the first match and only bind the first match.
BK_First,
+
/// Create results for all combinations of bindings that match.
BK_All
};
@@ -879,11 +956,12 @@ public:
enum AncestorMatchMode {
/// All ancestors.
AMM_All,
+
/// Direct parent only.
AMM_ParentOnly
};
- virtual ~ASTMatchFinder() {}
+ virtual ~ASTMatchFinder() = default;
/// \brief Returns true if the given class is directly or indirectly derived
/// from a base type matching \c base.
@@ -906,7 +984,7 @@ public:
std::is_base_of<TypeLoc, T>::value ||
std::is_base_of<QualType, T>::value,
"unsupported type for recursive matching");
- return matchesChildOf(ast_type_traits::DynTypedNode::create(Node),
+ return matchesChildOf(ast_type_traits::DynTypedNode::create(Node),
Matcher, Builder, Traverse, Bind);
}
@@ -969,17 +1047,17 @@ template <typename... Ts> struct TypeList {}; // Empty sentinel type list.
template <typename T1, typename... Ts> struct TypeList<T1, Ts...> {
/// \brief The first type on the list.
- typedef T1 head;
+ using head = T1;
/// \brief A sublist with the tail. ie everything but the head.
///
/// This type is used to do recursion. TypeList<>/EmptyTypeList indicates the
/// end of the list.
- typedef TypeList<Ts...> tail;
+ using tail = TypeList<Ts...>;
};
/// \brief The empty type list.
-typedef TypeList<> EmptyTypeList;
+using EmptyTypeList = TypeList<>;
/// \brief Helper meta-function to determine if some type \c T is present or
/// a parent type in the list.
@@ -997,8 +1075,9 @@ struct TypeListContainsSuperOf<EmptyTypeList, T> {
/// \brief A "type list" that contains all types.
///
/// Useful for matchers like \c anything and \c unless.
-typedef TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc,
- QualType, Type, TypeLoc, CXXCtorInitializer> AllNodeBaseTypes;
+using AllNodeBaseTypes =
+ TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc, QualType,
+ Type, TypeLoc, CXXCtorInitializer>;
/// \brief Helper meta-function to extract the argument out of a function of
/// type void(Arg).
@@ -1006,20 +1085,22 @@ typedef TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc,
/// See AST_POLYMORPHIC_SUPPORTED_TYPES for details.
template <class T> struct ExtractFunctionArgMeta;
template <class T> struct ExtractFunctionArgMeta<void(T)> {
- typedef T type;
+ using type = T;
};
/// \brief Default type lists for ArgumentAdaptingMatcher matchers.
-typedef AllNodeBaseTypes AdaptativeDefaultFromTypes;
-typedef TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc,
- TypeLoc, QualType> AdaptativeDefaultToTypes;
+using AdaptativeDefaultFromTypes = AllNodeBaseTypes;
+using AdaptativeDefaultToTypes =
+ TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc, TypeLoc,
+ QualType>;
/// \brief All types that are supported by HasDeclarationMatcher above.
-typedef TypeList<CallExpr, CXXConstructExpr, CXXNewExpr, DeclRefExpr, EnumType,
- InjectedClassNameType, LabelStmt, AddrLabelExpr, MemberExpr,
- QualType, RecordType, TagType, TemplateSpecializationType,
- TemplateTypeParmType, TypedefType, UnresolvedUsingType>
- HasDeclarationSupportedTypes;
+using HasDeclarationSupportedTypes =
+ TypeList<CallExpr, CXXConstructExpr, CXXNewExpr, DeclRefExpr, EnumType,
+ ElaboratedType, InjectedClassNameType, LabelStmt, AddrLabelExpr,
+ MemberExpr, QualType, RecordType, TagType,
+ TemplateSpecializationType, TemplateTypeParmType, TypedefType,
+ UnresolvedUsingType>;
/// \brief Converts a \c Matcher<T> to a matcher of desired type \c To by
/// "adapting" a \c To into a \c T.
@@ -1043,7 +1124,7 @@ struct ArgumentAdaptingMatcherFunc {
explicit Adaptor(const Matcher<T> &InnerMatcher)
: InnerMatcher(InnerMatcher) {}
- typedef ToTypes ReturnTypes;
+ using ReturnTypes = ToTypes;
template <typename To> operator Matcher<To>() const {
return Matcher<To>(new ArgumentAdapterT<To, T>(InnerMatcher));
@@ -1080,7 +1161,8 @@ template <template <typename T> class MatcherT,
typename ReturnTypesF = void(AllNodeBaseTypes)>
class PolymorphicMatcherWithParam0 {
public:
- typedef typename ExtractFunctionArgMeta<ReturnTypesF>::type ReturnTypes;
+ using ReturnTypes = typename ExtractFunctionArgMeta<ReturnTypesF>::type;
+
template <typename T>
operator Matcher<T>() const {
static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
@@ -1097,7 +1179,7 @@ public:
explicit PolymorphicMatcherWithParam1(const P1 &Param1)
: Param1(Param1) {}
- typedef typename ExtractFunctionArgMeta<ReturnTypesF>::type ReturnTypes;
+ using ReturnTypes = typename ExtractFunctionArgMeta<ReturnTypesF>::type;
template <typename T>
operator Matcher<T>() const {
@@ -1118,7 +1200,7 @@ public:
PolymorphicMatcherWithParam2(const P1 &Param1, const P2 &Param2)
: Param1(Param1), Param2(Param2) {}
- typedef typename ExtractFunctionArgMeta<ReturnTypesF>::type ReturnTypes;
+ using ReturnTypes = typename ExtractFunctionArgMeta<ReturnTypesF>::type;
template <typename T>
operator Matcher<T>() const {
@@ -1137,8 +1219,8 @@ private:
/// This is useful when a matcher syntactically requires a child matcher,
/// but the context doesn't care. See for example: anything().
class TrueMatcher {
- public:
- typedef AllNodeBaseTypes ReturnTypes;
+public:
+ using ReturnTypes = AllNodeBaseTypes;
template <typename T>
operator Matcher<T>() const {
@@ -1184,7 +1266,6 @@ public:
/// ChildT must be an AST base type.
template <typename T, typename ChildT>
class HasMatcher : public WrapperMatcherInterface<T> {
-
public:
explicit HasMatcher(const Matcher<ChildT> &ChildMatcher)
: HasMatcher::WrapperMatcherInterface(ChildMatcher) {}
@@ -1278,7 +1359,7 @@ template<typename T>
BindableMatcher<T> makeAllOfComposite(
ArrayRef<const Matcher<T> *> InnerMatchers) {
// For the size() == 0 case, we return a "true" matcher.
- if (InnerMatchers.size() == 0) {
+ if (InnerMatchers.empty()) {
return BindableMatcher<T>(TrueMatcher());
}
// For the size() == 1 case, we simply return that one matcher.
@@ -1287,7 +1368,8 @@ BindableMatcher<T> makeAllOfComposite(
return BindableMatcher<T>(*InnerMatchers[0]);
}
- typedef llvm::pointee_iterator<const Matcher<T> *const *> PI;
+ using PI = llvm::pointee_iterator<const Matcher<T> *const *>;
+
std::vector<DynTypedMatcher> DynMatchers(PI(InnerMatchers.begin()),
PI(InnerMatchers.end()));
return BindableMatcher<T>(
@@ -1580,12 +1662,13 @@ template <typename InnerTBase,
typename ReturnTypesF>
class TypeTraversePolymorphicMatcher {
private:
- typedef TypeTraversePolymorphicMatcher<InnerTBase, Getter, MatcherImpl,
- ReturnTypesF> Self;
+ using Self = TypeTraversePolymorphicMatcher<InnerTBase, Getter, MatcherImpl,
+ ReturnTypesF>;
+
static Self create(ArrayRef<const Matcher<InnerTBase> *> InnerMatchers);
public:
- typedef typename ExtractFunctionArgMeta<ReturnTypesF>::type ReturnTypes;
+ using ReturnTypes = typename ExtractFunctionArgMeta<ReturnTypesF>::type;
explicit TypeTraversePolymorphicMatcher(
ArrayRef<const Matcher<InnerTBase> *> InnerMatchers)
@@ -1612,6 +1695,7 @@ private:
template <typename Matcher, Matcher (*Func)()> class MemoizedMatcher {
struct Wrapper {
Wrapper() : M(Func()) {}
+
Matcher M;
};
@@ -1657,6 +1741,7 @@ struct NotEqualsBoundNodePredicate {
bool operator()(const internal::BoundNodesMap &Nodes) const {
return Nodes.getNode(ID) != Node;
}
+
std::string ID;
ast_type_traits::DynTypedNode Node;
};
@@ -1712,9 +1797,10 @@ CompoundStmtMatcher<StmtExpr>::get(const StmtExpr &Node) {
return Node.getSubStmt();
}
+} // namespace internal
+
+} // namespace ast_matchers
-} // end namespace internal
-} // end namespace ast_matchers
-} // end namespace clang
+} // namespace clang
#endif // LLVM_CLANG_ASTMATCHERS_ASTMATCHERSINTERNAL_H
diff --git a/include/clang/ASTMatchers/ASTMatchersMacros.h b/include/clang/ASTMatchers/ASTMatchersMacros.h
index ddc48378e714..6a48da821a53 100644
--- a/include/clang/ASTMatchers/ASTMatchersMacros.h
+++ b/include/clang/ASTMatchers/ASTMatchersMacros.h
@@ -367,6 +367,27 @@
// FIXME: add a matcher for TypeLoc derived classes using its custom casting
// API (no longer dyn_cast) if/when we need such matching
+#define AST_TYPE_TRAVERSE_MATCHER_DECL(MatcherName, FunctionName, \
+ ReturnTypesF) \
+ namespace internal { \
+ template <typename T> struct TypeMatcher##MatcherName##Getter { \
+ static QualType (T::*value())() const { return &T::FunctionName; } \
+ }; \
+ } \
+ extern const ::clang::ast_matchers::internal:: \
+ TypeTraversePolymorphicMatcher< \
+ QualType, \
+ ::clang::ast_matchers::internal::TypeMatcher##MatcherName##Getter, \
+ ::clang::ast_matchers::internal::TypeTraverseMatcher, \
+ ReturnTypesF>::Func MatcherName
+
+#define AST_TYPE_TRAVERSE_MATCHER_DEF(MatcherName, ReturnTypesF) \
+ const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher< \
+ QualType, \
+ ::clang::ast_matchers::internal::TypeMatcher##MatcherName##Getter, \
+ ::clang::ast_matchers::internal::TypeTraverseMatcher, \
+ ReturnTypesF>::Func MatcherName
+
/// \brief AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) defines
/// the matcher \c MatcherName that can be used to traverse from one \c Type
/// to another.
@@ -386,6 +407,30 @@
::clang::ast_matchers::internal::TypeTraverseMatcher, \
ReturnTypesF>::Func MatcherName
+#define AST_TYPELOC_TRAVERSE_MATCHER_DECL(MatcherName, FunctionName, \
+ ReturnTypesF) \
+ namespace internal { \
+ template <typename T> struct TypeLocMatcher##MatcherName##Getter { \
+ static TypeLoc (T::*value())() const { return &T::FunctionName##Loc; } \
+ }; \
+ } \
+ extern const ::clang::ast_matchers::internal:: \
+ TypeTraversePolymorphicMatcher< \
+ TypeLoc, \
+ ::clang::ast_matchers::internal:: \
+ TypeLocMatcher##MatcherName##Getter, \
+ ::clang::ast_matchers::internal::TypeLocTraverseMatcher, \
+ ReturnTypesF>::Func MatcherName##Loc; \
+ AST_TYPE_TRAVERSE_MATCHER_DECL(MatcherName, FunctionName##Type, ReturnTypesF)
+
+#define AST_TYPELOC_TRAVERSE_MATCHER_DEF(MatcherName, ReturnTypesF) \
+ const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher< \
+ TypeLoc, \
+ ::clang::ast_matchers::internal::TypeLocMatcher##MatcherName##Getter, \
+ ::clang::ast_matchers::internal::TypeLocTraverseMatcher, \
+ ReturnTypesF>::Func MatcherName##Loc; \
+ AST_TYPE_TRAVERSE_MATCHER_DEF(MatcherName, ReturnTypesF)
+
/// \brief AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName) works
/// identical to \c AST_TYPE_TRAVERSE_MATCHER but operates on \c TypeLocs.
#define AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF) \
diff --git a/include/clang/ASTMatchers/Dynamic/Parser.h b/include/clang/ASTMatchers/Dynamic/Parser.h
index 5ec4a9abf4bf..e8fcf0a9d6cc 100644
--- a/include/clang/ASTMatchers/Dynamic/Parser.h
+++ b/include/clang/ASTMatchers/Dynamic/Parser.h
@@ -1,4 +1,4 @@
-//===--- Parser.h - Matcher expression parser -----*- C++ -*-===//
+//===- Parser.h - Matcher expression parser ---------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,7 +6,7 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-///
+//
/// \file
/// \brief Simple matcher expression parser.
///
@@ -30,24 +30,28 @@
/// <Identifier> := [a-zA-Z]+
/// <ArgumentList> := <Expression> | <Expression>,<ArgumentList>
/// \endcode
-///
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_ASTMATCHERS_DYNAMIC_PARSER_H
#define LLVM_CLANG_ASTMATCHERS_DYNAMIC_PARSER_H
-#include "clang/ASTMatchers/Dynamic/Diagnostics.h"
+#include "clang/ASTMatchers/ASTMatchersInternal.h"
#include "clang/ASTMatchers/Dynamic/Registry.h"
#include "clang/ASTMatchers/Dynamic/VariantValue.h"
-#include "clang/Basic/LLVM.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
+#include <utility>
+#include <vector>
namespace clang {
namespace ast_matchers {
namespace dynamic {
+class Diagnostics;
+
/// \brief Matcher expression parser.
class Parser {
public:
@@ -124,8 +128,8 @@ public:
/// \brief Sema implementation that uses the matcher registry to process the
/// tokens.
class RegistrySema : public Parser::Sema {
- public:
- ~RegistrySema() override;
+ public:
+ ~RegistrySema() override;
llvm::Optional<MatcherCtor>
lookupMatcherCtor(StringRef MatcherName) override;
@@ -143,7 +147,7 @@ public:
getMatcherCompletions(llvm::ArrayRef<ArgKind> AcceptedTypes) override;
};
- typedef llvm::StringMap<VariantValue> NamedValueMap;
+ using NamedValueMap = llvm::StringMap<VariantValue>;
/// \brief Parse a matcher expression.
///
@@ -247,13 +251,14 @@ private:
const NamedValueMap *const NamedValues;
Diagnostics *const Error;
- typedef std::vector<std::pair<MatcherCtor, unsigned> > ContextStackTy;
+ using ContextStackTy = std::vector<std::pair<MatcherCtor, unsigned>>;
+
ContextStackTy ContextStack;
std::vector<MatcherCompletion> Completions;
};
-} // namespace dynamic
-} // namespace ast_matchers
-} // namespace clang
+} // namespace dynamic
+} // namespace ast_matchers
+} // namespace clang
-#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_PARSER_H
+#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_PARSER_H
diff --git a/include/clang/ASTMatchers/Dynamic/Registry.h b/include/clang/ASTMatchers/Dynamic/Registry.h
index 7bba95dbffea..277491250db8 100644
--- a/include/clang/ASTMatchers/Dynamic/Registry.h
+++ b/include/clang/ASTMatchers/Dynamic/Registry.h
@@ -1,4 +1,4 @@
-//===--- Registry.h - Matcher registry --------------------------*- C++ -*-===//
+//===- Registry.h - Matcher registry ----------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,12 +6,12 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-///
+//
/// \file
/// \brief Registry of all known matchers.
///
/// The registry provides a generic interface to construct any matcher by name.
-///
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_ASTMATCHERS_DYNAMIC_REGISTRY_H
@@ -34,9 +34,9 @@ namespace internal {
class MatcherDescriptor;
-} // end namespace internal
+} // namespace internal
-typedef const internal::MatcherDescriptor *MatcherCtor;
+using MatcherCtor = const internal::MatcherDescriptor *;
struct MatcherCompletion {
MatcherCompletion() = default;
@@ -129,8 +129,8 @@ public:
Diagnostics *Error);
};
-} // end namespace dynamic
-} // end namespace ast_matchers
-} // end namespace clang
+} // namespace dynamic
+} // namespace ast_matchers
+} // namespace clang
#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_REGISTRY_H
diff --git a/include/clang/Analysis/Analyses/Consumed.h b/include/clang/Analysis/Analyses/Consumed.h
index c0fc02724f09..5ba42b475c83 100644
--- a/include/clang/Analysis/Analyses/Consumed.h
+++ b/include/clang/Analysis/Analyses/Consumed.h
@@ -19,7 +19,7 @@
#include "clang/AST/ExprCXX.h"
#include "clang/AST/StmtCXX.h"
#include "clang/Analysis/Analyses/PostOrderCFGView.h"
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
#include "clang/Basic/SourceLocation.h"
namespace clang {
diff --git a/include/clang/Analysis/Analyses/Dominators.h b/include/clang/Analysis/Analyses/Dominators.h
index 38010e1ee1d8..6cb161ab37c8 100644
--- a/include/clang/Analysis/Analyses/Dominators.h
+++ b/include/clang/Analysis/Analyses/Dominators.h
@@ -14,7 +14,7 @@
#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_DOMINATORS_H
#define LLVM_CLANG_ANALYSIS_ANALYSES_DOMINATORS_H
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
#include "clang/Analysis/CFG.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/Support/GenericDomTree.h"
diff --git a/include/clang/Analysis/Analyses/LiveVariables.h b/include/clang/Analysis/Analyses/LiveVariables.h
index 8db4b0a58f86..6a1222386bae 100644
--- a/include/clang/Analysis/Analyses/LiveVariables.h
+++ b/include/clang/Analysis/Analyses/LiveVariables.h
@@ -15,7 +15,7 @@
#define LLVM_CLANG_ANALYSIS_ANALYSES_LIVEVARIABLES_H
#include "clang/AST/Decl.h"
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
#include "llvm/ADT/ImmutableSet.h"
namespace clang {
diff --git a/include/clang/Analysis/Analyses/PostOrderCFGView.h b/include/clang/Analysis/Analyses/PostOrderCFGView.h
index a1c650427588..c0a93528373e 100644
--- a/include/clang/Analysis/Analyses/PostOrderCFGView.h
+++ b/include/clang/Analysis/Analyses/PostOrderCFGView.h
@@ -21,7 +21,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/BitVector.h"
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
#include "clang/Analysis/CFG.h"
namespace clang {
diff --git a/include/clang/Analysis/Analyses/ThreadSafety.h b/include/clang/Analysis/Analyses/ThreadSafety.h
index 22694a7a225a..7e403b1f4090 100644
--- a/include/clang/Analysis/Analyses/ThreadSafety.h
+++ b/include/clang/Analysis/Analyses/ThreadSafety.h
@@ -19,7 +19,7 @@
#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETY_H
#define LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETY_H
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/StringRef.h"
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyCommon.h b/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
index 8c1d1da554bd..414645b7231b 100644
--- a/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
+++ b/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
@@ -25,7 +25,7 @@
#include "clang/Analysis/Analyses/PostOrderCFGView.h"
#include "clang/Analysis/Analyses/ThreadSafetyTIL.h"
#include "clang/Analysis/Analyses/ThreadSafetyTraverse.h"
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
#include "clang/Basic/OperatorKinds.h"
#include <memory>
#include <ostream>
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyTIL.h b/include/clang/Analysis/Analyses/ThreadSafetyTIL.h
index be8a7105d783..0a58d2a80250 100644
--- a/include/clang/Analysis/Analyses/ThreadSafetyTIL.h
+++ b/include/clang/Analysis/Analyses/ThreadSafetyTIL.h
@@ -92,6 +92,7 @@ enum TIL_BinaryOpcode : unsigned char {
BOP_Neq, // !=
BOP_Lt, // <
BOP_Leq, // <=
+ BOP_Cmp, // <=>
BOP_LogicAnd, // && (no short-circuit)
BOP_LogicOr // || (no short-circuit)
};
@@ -909,15 +910,10 @@ class Project : public SExpr {
public:
static bool classof(const SExpr *E) { return E->opcode() == COP_Project; }
- Project(SExpr *R, StringRef SName)
- : SExpr(COP_Project), Rec(R), SlotName(SName), Cvdecl(nullptr)
- { }
Project(SExpr *R, const clang::ValueDecl *Cvd)
- : SExpr(COP_Project), Rec(R), SlotName(Cvd->getName()), Cvdecl(Cvd)
- { }
- Project(const Project &P, SExpr *R)
- : SExpr(P), Rec(R), SlotName(P.SlotName), Cvdecl(P.Cvdecl)
- { }
+ : SExpr(COP_Project), Rec(R), Cvdecl(Cvd) {
+ assert(Cvd && "ValueDecl must not be null");
+ }
SExpr *record() { return Rec; }
const SExpr *record() const { return Rec; }
@@ -931,10 +927,14 @@ public:
}
StringRef slotName() const {
- if (Cvdecl)
+ if (Cvdecl->getDeclName().isIdentifier())
return Cvdecl->getName();
- else
- return SlotName;
+ if (!SlotName) {
+ SlotName = "";
+ llvm::raw_string_ostream OS(*SlotName);
+ Cvdecl->printName(OS);
+ }
+ return *SlotName;
}
template <class V>
@@ -953,7 +953,7 @@ public:
private:
SExpr* Rec;
- StringRef SlotName;
+ mutable llvm::Optional<std::string> SlotName;
const clang::ValueDecl *Cvdecl;
};
diff --git a/include/clang/Analysis/AnalysisContext.h b/include/clang/Analysis/AnalysisDeclContext.h
index ec7549d4535c..03ff4a9516da 100644
--- a/include/clang/Analysis/AnalysisContext.h
+++ b/include/clang/Analysis/AnalysisDeclContext.h
@@ -1,4 +1,4 @@
-//=== AnalysisContext.h - Analysis context for Path Sens analysis --*- C++ -*-//
+//=== AnalysisDeclContext.h - Analysis context for Path Sens analysis --*- C++ -*-//
//
// The LLVM Compiler Infrastructure
//
@@ -12,10 +12,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H
-#define LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSISDECLCONTEXT_H
+#define LLVM_CLANG_ANALYSIS_ANALYSISDECLCONTEXT_H
#include "clang/AST/Decl.h"
+#include "clang/Analysis/BodyFarm.h"
#include "clang/Analysis/CFG.h"
#include "clang/Analysis/CodeInjector.h"
#include "llvm/ADT/DenseMap.h"
@@ -416,23 +417,25 @@ class AnalysisDeclContextManager {
/// Pointer to an interface that can provide function bodies for
/// declarations from external source.
std::unique_ptr<CodeInjector> Injector;
-
+
+ /// A factory for creating and caching implementations for common
+ /// methods during the analysis.
+ BodyFarm FunctionBodyFarm;
+
/// Flag to indicate whether or not bodies should be synthesized
/// for well-known functions.
bool SynthesizeBodies;
public:
- AnalysisDeclContextManager(bool useUnoptimizedCFG = false,
+ AnalysisDeclContextManager(ASTContext &ASTCtx, bool useUnoptimizedCFG = false,
bool addImplicitDtors = false,
bool addInitializers = false,
bool addTemporaryDtors = false,
- bool addLifetime = false,
+ bool addLifetime = false, bool addLoopExit = false,
bool synthesizeBodies = false,
bool addStaticInitBranches = false,
bool addCXXNewAllocator = true,
- CodeInjector* injector = nullptr);
-
- ~AnalysisDeclContextManager();
+ CodeInjector *injector = nullptr);
AnalysisDeclContext *getContext(const Decl *D);
@@ -471,6 +474,9 @@ public:
return LocContexts.getStackFrame(getContext(D), Parent, S, Blk, Idx);
}
+ /// Get a reference to {@code BodyFarm} instance.
+ BodyFarm &getBodyFarm();
+
/// Discard all previously created AnalysisDeclContexts.
void clear();
diff --git a/include/clang/Analysis/BodyFarm.h b/include/clang/Analysis/BodyFarm.h
new file mode 100644
index 000000000000..ff0859bc662d
--- /dev/null
+++ b/include/clang/Analysis/BodyFarm.h
@@ -0,0 +1,54 @@
+//== BodyFarm.h - Factory for conjuring up fake bodies -------------*- C++ -*-//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// BodyFarm is a factory for creating faux implementations for functions/methods
+// for analysis purposes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_ANALYSIS_BODYFARM_H
+#define LLVM_CLANG_LIB_ANALYSIS_BODYFARM_H
+
+#include "clang/AST/DeclBase.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Optional.h"
+
+namespace clang {
+
+class ASTContext;
+class FunctionDecl;
+class ObjCMethodDecl;
+class ObjCPropertyDecl;
+class Stmt;
+class CodeInjector;
+
+class BodyFarm {
+public:
+ BodyFarm(ASTContext &C, CodeInjector *injector) : C(C), Injector(injector) {}
+
+ /// Factory method for creating bodies for ordinary functions.
+ Stmt *getBody(const FunctionDecl *D);
+
+ /// Factory method for creating bodies for Objective-C properties.
+ Stmt *getBody(const ObjCMethodDecl *D);
+
+ /// Remove copy constructor to avoid accidental copying.
+ BodyFarm(const BodyFarm &other) = delete;
+
+private:
+ typedef llvm::DenseMap<const Decl *, Optional<Stmt *>> BodyMap;
+
+ ASTContext &C;
+ BodyMap Bodies;
+ CodeInjector *Injector;
+};
+} // namespace clang
+
+#endif
diff --git a/include/clang/Analysis/CFG.h b/include/clang/Analysis/CFG.h
index 97639bbfade2..cfedb2aa8ed5 100644
--- a/include/clang/Analysis/CFG.h
+++ b/include/clang/Analysis/CFG.h
@@ -1,4 +1,4 @@
-//===--- CFG.h - Classes for representing and building CFGs------*- C++ -*-===//
+//===- CFG.h - Classes for representing and building CFGs -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -17,38 +17,38 @@
#include "clang/AST/Stmt.h"
#include "clang/Analysis/Support/BumpVector.h"
-#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/LLVM.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Allocator.h"
-#include "llvm/Support/Casting.h"
#include "llvm/Support/raw_ostream.h"
#include <bitset>
#include <cassert>
+#include <cstddef>
#include <iterator>
#include <memory>
+#include <vector>
namespace clang {
- class CXXDestructorDecl;
- class Decl;
- class Stmt;
- class Expr;
- class FieldDecl;
- class VarDecl;
- class CXXCtorInitializer;
- class CXXBaseSpecifier;
- class CXXBindTemporaryExpr;
- class CFG;
- class PrinterHelper;
- class LangOptions;
- class ASTContext;
- class CXXRecordDecl;
- class CXXDeleteExpr;
- class CXXNewExpr;
- class BinaryOperator;
+
+class ASTContext;
+class BinaryOperator;
+class CFG;
+class CXXBaseSpecifier;
+class CXXBindTemporaryExpr;
+class CXXCtorInitializer;
+class CXXDeleteExpr;
+class CXXDestructorDecl;
+class CXXNewExpr;
+class CXXRecordDecl;
+class Decl;
+class FieldDecl;
+class LangOptions;
+class VarDecl;
/// CFGElement - Represents a top-level expression in a basic block.
class CFGElement {
@@ -59,6 +59,7 @@ public:
Initializer,
NewAllocator,
LifetimeEnds,
+ LoopExit,
// dtor kind
AutomaticObjectDtor,
DeleteDtor,
@@ -75,14 +76,14 @@ protected:
llvm::PointerIntPair<void *, 2> Data2;
CFGElement(Kind kind, const void *Ptr1, const void *Ptr2 = nullptr)
- : Data1(const_cast<void*>(Ptr1), ((unsigned) kind) & 0x3),
- Data2(const_cast<void*>(Ptr2), (((unsigned) kind) >> 2) & 0x3) {
+ : Data1(const_cast<void*>(Ptr1), ((unsigned) kind) & 0x3),
+ Data2(const_cast<void*>(Ptr2), (((unsigned) kind) >> 2) & 0x3) {
assert(getKind() == kind);
}
- CFGElement() {}
-public:
+ CFGElement() = default;
+public:
/// \brief Convert to the specified CFGElement type, asserting that this
/// CFGElement is of the desired type.
template<typename T>
@@ -124,7 +125,9 @@ public:
private:
friend class CFGElement;
- CFGStmt() {}
+
+ CFGStmt() = default;
+
static bool isKind(const CFGElement &E) {
return E.getKind() == Statement;
}
@@ -143,7 +146,9 @@ public:
private:
friend class CFGElement;
- CFGInitializer() {}
+
+ CFGInitializer() = default;
+
static bool isKind(const CFGElement &E) {
return E.getKind() == Initializer;
}
@@ -162,12 +167,38 @@ public:
private:
friend class CFGElement;
- CFGNewAllocator() {}
+
+ CFGNewAllocator() = default;
+
static bool isKind(const CFGElement &elem) {
return elem.getKind() == NewAllocator;
}
};
+/// Represents the point where a loop ends.
+/// This element is is only produced when building the CFG for the static
+/// analyzer and hidden behind the 'cfg-loopexit' analyzer config flag.
+///
+/// Note: a loop exit element can be reached even when the loop body was never
+/// entered.
+class CFGLoopExit : public CFGElement {
+public:
+ explicit CFGLoopExit(const Stmt *stmt) : CFGElement(LoopExit, stmt) {}
+
+ const Stmt *getLoopStmt() const {
+ return static_cast<Stmt *>(Data1.getPointer());
+ }
+
+private:
+ friend class CFGElement;
+
+ CFGLoopExit() = default;
+
+ static bool isKind(const CFGElement &elem) {
+ return elem.getKind() == LoopExit;
+ }
+};
+
/// Represents the point where the lifetime of an automatic object ends
class CFGLifetimeEnds : public CFGElement {
public:
@@ -184,7 +215,9 @@ public:
private:
friend class CFGElement;
- CFGLifetimeEnds() {}
+
+ CFGLifetimeEnds() = default;
+
static bool isKind(const CFGElement &elem) {
return elem.getKind() == LifetimeEnds;
}
@@ -194,7 +227,8 @@ private:
/// by compiler on various occasions.
class CFGImplicitDtor : public CFGElement {
protected:
- CFGImplicitDtor() {}
+ CFGImplicitDtor() = default;
+
CFGImplicitDtor(Kind kind, const void *data1, const void *data2 = nullptr)
: CFGElement(kind, data1, data2) {
assert(kind >= DTOR_BEGIN && kind <= DTOR_END);
@@ -206,6 +240,7 @@ public:
private:
friend class CFGElement;
+
static bool isKind(const CFGElement &E) {
Kind kind = E.getKind();
return kind >= DTOR_BEGIN && kind <= DTOR_END;
@@ -231,7 +266,9 @@ public:
private:
friend class CFGElement;
- CFGAutomaticObjDtor() {}
+
+ CFGAutomaticObjDtor() = default;
+
static bool isKind(const CFGElement &elem) {
return elem.getKind() == AutomaticObjectDtor;
}
@@ -255,7 +292,9 @@ public:
private:
friend class CFGElement;
- CFGDeleteDtor() {}
+
+ CFGDeleteDtor() = default;
+
static bool isKind(const CFGElement &elem) {
return elem.getKind() == DeleteDtor;
}
@@ -274,7 +313,9 @@ public:
private:
friend class CFGElement;
- CFGBaseDtor() {}
+
+ CFGBaseDtor() = default;
+
static bool isKind(const CFGElement &E) {
return E.getKind() == BaseDtor;
}
@@ -293,7 +334,9 @@ public:
private:
friend class CFGElement;
- CFGMemberDtor() {}
+
+ CFGMemberDtor() = default;
+
static bool isKind(const CFGElement &E) {
return E.getKind() == MemberDtor;
}
@@ -312,7 +355,9 @@ public:
private:
friend class CFGElement;
- CFGTemporaryDtor() {}
+
+ CFGTemporaryDtor() = default;
+
static bool isKind(const CFGElement &E) {
return E.getKind() == TemporaryDtor;
}
@@ -326,8 +371,9 @@ private:
/// of matching full expression.
class CFGTerminator {
llvm::PointerIntPair<Stmt *, 1> Data;
+
public:
- CFGTerminator() {}
+ CFGTerminator() = default;
CFGTerminator(Stmt *S, bool TemporaryDtorsBranch = false)
: Data(S, TemporaryDtorsBranch) {}
@@ -373,21 +419,23 @@ public:
/// &&, || expression that uses result of && or ||, RHS
///
/// But note that any of that may be NULL in case of optimized-out edges.
-///
class CFGBlock {
class ElementList {
- typedef BumpVector<CFGElement> ImplTy;
+ using ImplTy = BumpVector<CFGElement>;
+
ImplTy Impl;
+
public:
ElementList(BumpVectorContext &C) : Impl(C, 4) {}
- typedef std::reverse_iterator<ImplTy::iterator> iterator;
- typedef std::reverse_iterator<ImplTy::const_iterator> const_iterator;
- typedef ImplTy::iterator reverse_iterator;
- typedef ImplTy::const_iterator const_reverse_iterator;
- typedef ImplTy::const_reference const_reference;
+ using iterator = std::reverse_iterator<ImplTy::iterator>;
+ using const_iterator = std::reverse_iterator<ImplTy::const_iterator>;
+ using reverse_iterator = ImplTy::iterator;
+ using const_reverse_iterator = ImplTy::const_iterator;
+ using const_reference = ImplTy::const_reference;
void push_back(CFGElement e, BumpVectorContext &C) { Impl.push_back(e, C); }
+
reverse_iterator insert(reverse_iterator I, size_t Cnt, CFGElement E,
BumpVectorContext &C) {
return Impl.insert(I, Cnt, E, C);
@@ -405,10 +453,10 @@ class CFGBlock {
const_reverse_iterator rbegin() const { return Impl.begin(); }
const_reverse_iterator rend() const { return Impl.end(); }
- CFGElement operator[](size_t i) const {
- assert(i < Impl.size());
- return Impl[Impl.size() - 1 - i];
- }
+ CFGElement operator[](size_t i) const {
+ assert(i < Impl.size());
+ return Impl[Impl.size() - 1 - i];
+ }
size_t size() const { return Impl.size(); }
bool empty() const { return Impl.empty(); }
@@ -420,7 +468,7 @@ class CFGBlock {
/// Label - An (optional) label that prefixes the executable
/// statements in the block. When this variable is non-NULL, it is
/// either an instance of LabelStmt, SwitchCase or CXXCatchStmt.
- Stmt *Label;
+ Stmt *Label = nullptr;
/// Terminator - The terminator for a basic block that
/// indicates the type of control-flow that occurs between a block
@@ -430,7 +478,7 @@ class CFGBlock {
/// LoopTarget - Some blocks are used to represent the "loop edge" to
/// the start of a loop from within the loop body. This Stmt* will be
/// refer to the loop statement for such blocks (and be null otherwise).
- const Stmt *LoopTarget;
+ const Stmt *LoopTarget = nullptr;
/// BlockID - A numerical ID assigned to a CFGBlock during construction
/// of the CFG.
@@ -450,7 +498,7 @@ public:
};
CFGBlock *ReachableBlock;
- llvm::PointerIntPair<CFGBlock*, 2> UnreachableBlock;
+ llvm::PointerIntPair<CFGBlock *, 2> UnreachableBlock;
public:
/// Construct an AdjacentBlock with a possibly unreachable block.
@@ -493,7 +541,7 @@ public:
private:
/// Predecessors/Successors - Keep track of the predecessor / successor
/// CFG blocks.
- typedef BumpVector<AdjacentBlock> AdjacentBlocks;
+ using AdjacentBlocks = BumpVector<AdjacentBlock>;
AdjacentBlocks Preds;
AdjacentBlocks Succs;
@@ -513,15 +561,14 @@ private:
public:
explicit CFGBlock(unsigned blockid, BumpVectorContext &C, CFG *parent)
- : Elements(C), Label(nullptr), Terminator(nullptr), LoopTarget(nullptr),
- BlockID(blockid), Preds(C, 1), Succs(C, 1), HasNoReturnElement(false),
- Parent(parent) {}
+ : Elements(C), Terminator(nullptr), BlockID(blockid), Preds(C, 1),
+ Succs(C, 1), HasNoReturnElement(false), Parent(parent) {}
// Statement iterators
- typedef ElementList::iterator iterator;
- typedef ElementList::const_iterator const_iterator;
- typedef ElementList::reverse_iterator reverse_iterator;
- typedef ElementList::const_reverse_iterator const_reverse_iterator;
+ using iterator = ElementList::iterator;
+ using const_iterator = ElementList::const_iterator;
+ using reverse_iterator = ElementList::reverse_iterator;
+ using const_reverse_iterator = ElementList::const_reverse_iterator;
CFGElement front() const { return Elements.front(); }
CFGElement back() const { return Elements.back(); }
@@ -542,19 +589,19 @@ public:
CFGElement operator[](size_t i) const { return Elements[i]; }
// CFG iterators
- typedef AdjacentBlocks::iterator pred_iterator;
- typedef AdjacentBlocks::const_iterator const_pred_iterator;
- typedef AdjacentBlocks::reverse_iterator pred_reverse_iterator;
- typedef AdjacentBlocks::const_reverse_iterator const_pred_reverse_iterator;
- typedef llvm::iterator_range<pred_iterator> pred_range;
- typedef llvm::iterator_range<const_pred_iterator> pred_const_range;
-
- typedef AdjacentBlocks::iterator succ_iterator;
- typedef AdjacentBlocks::const_iterator const_succ_iterator;
- typedef AdjacentBlocks::reverse_iterator succ_reverse_iterator;
- typedef AdjacentBlocks::const_reverse_iterator const_succ_reverse_iterator;
- typedef llvm::iterator_range<succ_iterator> succ_range;
- typedef llvm::iterator_range<const_succ_iterator> succ_const_range;
+ using pred_iterator = AdjacentBlocks::iterator;
+ using const_pred_iterator = AdjacentBlocks::const_iterator;
+ using pred_reverse_iterator = AdjacentBlocks::reverse_iterator;
+ using const_pred_reverse_iterator = AdjacentBlocks::const_reverse_iterator;
+ using pred_range = llvm::iterator_range<pred_iterator>;
+ using pred_const_range = llvm::iterator_range<const_pred_iterator>;
+
+ using succ_iterator = AdjacentBlocks::iterator;
+ using const_succ_iterator = AdjacentBlocks::const_iterator;
+ using succ_reverse_iterator = AdjacentBlocks::reverse_iterator;
+ using const_succ_reverse_iterator = AdjacentBlocks::const_reverse_iterator;
+ using succ_range = llvm::iterator_range<succ_iterator>;
+ using succ_const_range = llvm::iterator_range<const_succ_iterator>;
pred_iterator pred_begin() { return Preds.begin(); }
pred_iterator pred_end() { return Preds.end(); }
@@ -566,10 +613,11 @@ public:
const_pred_reverse_iterator pred_rbegin() const { return Preds.rbegin(); }
const_pred_reverse_iterator pred_rend() const { return Preds.rend(); }
- pred_range preds() {
+ pred_range preds() {
return pred_range(pred_begin(), pred_end());
}
- pred_const_range preds() const {
+
+ pred_const_range preds() const {
return pred_const_range(pred_begin(), pred_end());
}
@@ -583,10 +631,11 @@ public:
const_succ_reverse_iterator succ_rbegin() const { return Succs.rbegin(); }
const_succ_reverse_iterator succ_rend() const { return Succs.rend(); }
- succ_range succs() {
+ succ_range succs() {
return succ_range(succ_begin(), succ_end());
}
- succ_const_range succs() const {
+
+ succ_const_range succs() const {
return succ_const_range(succ_begin(), succ_end());
}
@@ -599,13 +648,11 @@ public:
class FilterOptions {
public:
- FilterOptions() {
- IgnoreNullPredecessors = 1;
- IgnoreDefaultsWithCoveredEnums = 0;
- }
-
unsigned IgnoreNullPredecessors : 1;
unsigned IgnoreDefaultsWithCoveredEnums : 1;
+
+ FilterOptions()
+ : IgnoreNullPredecessors(1), IgnoreDefaultsWithCoveredEnums(0) {}
};
static bool FilterEdge(const FilterOptions &F, const CFGBlock *Src,
@@ -617,6 +664,7 @@ public:
IMPL I, E;
const FilterOptions F;
const CFGBlock *From;
+
public:
explicit FilteredCFGBlockIterator(const IMPL &i, const IMPL &e,
const CFGBlock *from,
@@ -634,17 +682,18 @@ public:
}
const CFGBlock *operator*() const { return *I; }
+
private:
bool Filter(const CFGBlock *To) {
return IsPred ? FilterEdge(F, To, From) : FilterEdge(F, From, To);
}
};
- typedef FilteredCFGBlockIterator<const_pred_iterator, true>
- filtered_pred_iterator;
+ using filtered_pred_iterator =
+ FilteredCFGBlockIterator<const_pred_iterator, true>;
- typedef FilteredCFGBlockIterator<const_succ_iterator, false>
- filtered_succ_iterator;
+ using filtered_succ_iterator =
+ FilteredCFGBlockIterator<const_succ_iterator, false>;
filtered_pred_iterator filtered_pred_start_end(const FilterOptions &f) const {
return filtered_pred_iterator(pred_begin(), pred_end(), this, f);
@@ -728,6 +777,10 @@ public:
Elements.push_back(CFGLifetimeEnds(VD, S), C);
}
+ void appendLoopExit(const Stmt *LoopStmt, BumpVectorContext &C) {
+ Elements.push_back(CFGLoopExit(LoopStmt), C);
+ }
+
void appendDeleteDtor(CXXRecordDecl *RD, CXXDeleteExpr *DE, BumpVectorContext &C) {
Elements.push_back(CFGDeleteDtor(RD, DE), C);
}
@@ -763,11 +816,12 @@ public:
/// operator error is found when building the CFG.
class CFGCallback {
public:
- CFGCallback() {}
+ CFGCallback() = default;
+ virtual ~CFGCallback() = default;
+
virtual void compareAlwaysTrue(const BinaryOperator *B, bool isAlwaysTrue) {}
virtual void compareBitwiseEquality(const BinaryOperator *B,
bool isAlwaysTrue) {}
- virtual ~CFGCallback() {}
};
/// CFG - Represents a source-level, intra-procedural CFG that represents the
@@ -785,19 +839,24 @@ public:
class BuildOptions {
std::bitset<Stmt::lastStmtConstant> alwaysAddMask;
+
public:
- typedef llvm::DenseMap<const Stmt *, const CFGBlock*> ForcedBlkExprs;
- ForcedBlkExprs **forcedBlkExprs;
- CFGCallback *Observer;
- bool PruneTriviallyFalseEdges;
- bool AddEHEdges;
- bool AddInitializers;
- bool AddImplicitDtors;
- bool AddLifetime;
- bool AddTemporaryDtors;
- bool AddStaticInitBranches;
- bool AddCXXNewAllocator;
- bool AddCXXDefaultInitExprInCtors;
+ using ForcedBlkExprs = llvm::DenseMap<const Stmt *, const CFGBlock *>;
+
+ ForcedBlkExprs **forcedBlkExprs = nullptr;
+ CFGCallback *Observer = nullptr;
+ bool PruneTriviallyFalseEdges = true;
+ bool AddEHEdges = false;
+ bool AddInitializers = false;
+ bool AddImplicitDtors = false;
+ bool AddLifetime = false;
+ bool AddLoopExit = false;
+ bool AddTemporaryDtors = false;
+ bool AddStaticInitBranches = false;
+ bool AddCXXNewAllocator = false;
+ bool AddCXXDefaultInitExprInCtors = false;
+
+ BuildOptions() = default;
bool alwaysAdd(const Stmt *stmt) const {
return alwaysAddMask[stmt->getStmtClass()];
@@ -812,15 +871,6 @@ public:
alwaysAddMask.set();
return *this;
}
-
- BuildOptions()
- : forcedBlkExprs(nullptr), Observer(nullptr),
- PruneTriviallyFalseEdges(true),
- AddEHEdges(false),
- AddInitializers(false), AddImplicitDtors(false),
- AddLifetime(false),
- AddTemporaryDtors(false), AddStaticInitBranches(false),
- AddCXXNewAllocator(false), AddCXXDefaultInitExprInCtors(false) {}
};
/// buildCFG - Builds a CFG from an AST.
@@ -844,11 +894,11 @@ public:
// Block Iterators
//===--------------------------------------------------------------------===//
- typedef BumpVector<CFGBlock*> CFGBlockListTy;
- typedef CFGBlockListTy::iterator iterator;
- typedef CFGBlockListTy::const_iterator const_iterator;
- typedef std::reverse_iterator<iterator> reverse_iterator;
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ using CFGBlockListTy = BumpVector<CFGBlock *>;
+ using iterator = CFGBlockListTy::iterator;
+ using const_iterator = CFGBlockListTy::const_iterator;
+ using reverse_iterator = std::reverse_iterator<iterator>;
+ using const_reverse_iterator = std::reverse_iterator<const_iterator>;
CFGBlock & front() { return *Blocks.front(); }
CFGBlock & back() { return *Blocks.back(); }
@@ -876,10 +926,12 @@ public:
CFGBlock * getIndirectGotoBlock() { return IndirectGotoBlock; }
const CFGBlock * getIndirectGotoBlock() const { return IndirectGotoBlock; }
- typedef std::vector<const CFGBlock*>::const_iterator try_block_iterator;
+ using try_block_iterator = std::vector<const CFGBlock *>::const_iterator;
+
try_block_iterator try_blocks_begin() const {
return TryDispatchBlocks.begin();
}
+
try_block_iterator try_blocks_end() const {
return TryDispatchBlocks.end();
}
@@ -900,9 +952,9 @@ public:
SyntheticDeclStmts[Synthetic] = Source;
}
- typedef llvm::DenseMap<const DeclStmt *, const DeclStmt *>::const_iterator
- synthetic_stmt_iterator;
- typedef llvm::iterator_range<synthetic_stmt_iterator> synthetic_stmt_range;
+ using synthetic_stmt_iterator =
+ llvm::DenseMap<const DeclStmt *, const DeclStmt *>::const_iterator;
+ using synthetic_stmt_range = llvm::iterator_range<synthetic_stmt_iterator>;
/// Iterates over synthetic DeclStmts in the CFG.
///
@@ -962,9 +1014,7 @@ public:
// Internal: constructors and data.
//===--------------------------------------------------------------------===//
- CFG()
- : Entry(nullptr), Exit(nullptr), IndirectGotoBlock(nullptr), NumBlockIDs(0),
- Blocks(BlkBVC, 10) {}
+ CFG() : Blocks(BlkBVC, 10) {}
llvm::BumpPtrAllocator& getAllocator() {
return BlkBVC.getAllocator();
@@ -975,11 +1025,13 @@ public:
}
private:
- CFGBlock *Entry;
- CFGBlock *Exit;
- CFGBlock* IndirectGotoBlock; // Special block to contain collective dispatch
- // for indirect gotos
- unsigned NumBlockIDs;
+ CFGBlock *Entry = nullptr;
+ CFGBlock *Exit = nullptr;
+
+ // Special block to contain collective dispatch for indirect gotos
+ CFGBlock* IndirectGotoBlock = nullptr;
+
+ unsigned NumBlockIDs = 0;
BumpVectorContext BlkBVC;
@@ -993,7 +1045,8 @@ private:
/// source DeclStmt.
llvm::DenseMap<const DeclStmt *, const DeclStmt *> SyntheticDeclStmts;
};
-} // end namespace clang
+
+} // namespace clang
//===----------------------------------------------------------------------===//
// GraphTraits specializations for CFG basic block graphs (source-level CFGs)
@@ -1004,7 +1057,8 @@ namespace llvm {
/// Implement simplify_type for CFGTerminator, so that we can dyn_cast from
/// CFGTerminator to a specific Stmt class.
template <> struct simplify_type< ::clang::CFGTerminator> {
- typedef ::clang::Stmt *SimpleType;
+ using SimpleType = ::clang::Stmt *;
+
static SimpleType getSimplifiedValue(::clang::CFGTerminator Val) {
return Val.getStmt();
}
@@ -1013,50 +1067,44 @@ template <> struct simplify_type< ::clang::CFGTerminator> {
// Traits for: CFGBlock
template <> struct GraphTraits< ::clang::CFGBlock *> {
- typedef ::clang::CFGBlock *NodeRef;
- typedef ::clang::CFGBlock::succ_iterator ChildIteratorType;
+ using NodeRef = ::clang::CFGBlock *;
+ using ChildIteratorType = ::clang::CFGBlock::succ_iterator;
static NodeRef getEntryNode(::clang::CFGBlock *BB) { return BB; }
-
static ChildIteratorType child_begin(NodeRef N) { return N->succ_begin(); }
-
static ChildIteratorType child_end(NodeRef N) { return N->succ_end(); }
};
template <> struct GraphTraits< const ::clang::CFGBlock *> {
- typedef const ::clang::CFGBlock *NodeRef;
- typedef ::clang::CFGBlock::const_succ_iterator ChildIteratorType;
+ using NodeRef = const ::clang::CFGBlock *;
+ using ChildIteratorType = ::clang::CFGBlock::const_succ_iterator;
static NodeRef getEntryNode(const clang::CFGBlock *BB) { return BB; }
-
static ChildIteratorType child_begin(NodeRef N) { return N->succ_begin(); }
-
static ChildIteratorType child_end(NodeRef N) { return N->succ_end(); }
};
-template <> struct GraphTraits<Inverse< ::clang::CFGBlock*> > {
- typedef ::clang::CFGBlock *NodeRef;
- typedef ::clang::CFGBlock::const_pred_iterator ChildIteratorType;
+template <> struct GraphTraits<Inverse< ::clang::CFGBlock *>> {
+ using NodeRef = ::clang::CFGBlock *;
+ using ChildIteratorType = ::clang::CFGBlock::const_pred_iterator;
static NodeRef getEntryNode(Inverse<::clang::CFGBlock *> G) {
return G.Graph;
}
static ChildIteratorType child_begin(NodeRef N) { return N->pred_begin(); }
-
static ChildIteratorType child_end(NodeRef N) { return N->pred_end(); }
};
-template <> struct GraphTraits<Inverse<const ::clang::CFGBlock*> > {
- typedef const ::clang::CFGBlock *NodeRef;
- typedef ::clang::CFGBlock::const_pred_iterator ChildIteratorType;
+template <> struct GraphTraits<Inverse<const ::clang::CFGBlock *>> {
+ using NodeRef = const ::clang::CFGBlock *;
+ using ChildIteratorType = ::clang::CFGBlock::const_pred_iterator;
static NodeRef getEntryNode(Inverse<const ::clang::CFGBlock *> G) {
return G.Graph;
}
static ChildIteratorType child_begin(NodeRef N) { return N->pred_begin(); }
-
static ChildIteratorType child_end(NodeRef N) { return N->pred_end(); }
};
@@ -1064,8 +1112,7 @@ template <> struct GraphTraits<Inverse<const ::clang::CFGBlock*> > {
template <> struct GraphTraits< ::clang::CFG* >
: public GraphTraits< ::clang::CFGBlock *> {
-
- typedef ::clang::CFG::iterator nodes_iterator;
+ using nodes_iterator = ::clang::CFG::iterator;
static NodeRef getEntryNode(::clang::CFG *F) { return &F->getEntry(); }
static nodes_iterator nodes_begin(::clang::CFG* F) { return F->nodes_begin();}
@@ -1075,44 +1122,47 @@ template <> struct GraphTraits< ::clang::CFG* >
template <> struct GraphTraits<const ::clang::CFG* >
: public GraphTraits<const ::clang::CFGBlock *> {
-
- typedef ::clang::CFG::const_iterator nodes_iterator;
+ using nodes_iterator = ::clang::CFG::const_iterator;
static NodeRef getEntryNode(const ::clang::CFG *F) { return &F->getEntry(); }
+
static nodes_iterator nodes_begin( const ::clang::CFG* F) {
return F->nodes_begin();
}
+
static nodes_iterator nodes_end( const ::clang::CFG* F) {
return F->nodes_end();
}
+
static unsigned size(const ::clang::CFG* F) {
return F->size();
}
};
-template <> struct GraphTraits<Inverse< ::clang::CFG*> >
- : public GraphTraits<Inverse< ::clang::CFGBlock*> > {
-
- typedef ::clang::CFG::iterator nodes_iterator;
+template <> struct GraphTraits<Inverse< ::clang::CFG *>>
+ : public GraphTraits<Inverse< ::clang::CFGBlock *>> {
+ using nodes_iterator = ::clang::CFG::iterator;
static NodeRef getEntryNode(::clang::CFG *F) { return &F->getExit(); }
static nodes_iterator nodes_begin( ::clang::CFG* F) {return F->nodes_begin();}
static nodes_iterator nodes_end( ::clang::CFG* F) { return F->nodes_end(); }
};
-template <> struct GraphTraits<Inverse<const ::clang::CFG*> >
- : public GraphTraits<Inverse<const ::clang::CFGBlock*> > {
-
- typedef ::clang::CFG::const_iterator nodes_iterator;
+template <> struct GraphTraits<Inverse<const ::clang::CFG *>>
+ : public GraphTraits<Inverse<const ::clang::CFGBlock *>> {
+ using nodes_iterator = ::clang::CFG::const_iterator;
static NodeRef getEntryNode(const ::clang::CFG *F) { return &F->getExit(); }
+
static nodes_iterator nodes_begin(const ::clang::CFG* F) {
return F->nodes_begin();
}
+
static nodes_iterator nodes_end(const ::clang::CFG* F) {
return F->nodes_end();
}
};
-} // end llvm namespace
+
+} // namespace llvm
#endif // LLVM_CLANG_ANALYSIS_CFG_H
diff --git a/include/clang/Analysis/CallGraph.h b/include/clang/Analysis/CallGraph.h
index a2a27a8e47c7..bdcdfecddc3e 100644
--- a/include/clang/Analysis/CallGraph.h
+++ b/include/clang/Analysis/CallGraph.h
@@ -1,4 +1,4 @@
-//== CallGraph.h - AST-based Call graph ------------------------*- C++ -*--==//
+//===- CallGraph.h - AST-based Call graph -----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,19 +12,27 @@
// A call graph for functions whose definitions/bodies are available in the
// current translation unit. The graph has a "virtual" root node that contains
// edges to all externally available functions.
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_ANALYSIS_CALLGRAPH_H
#define LLVM_CLANG_ANALYSIS_CALLGRAPH_H
-#include "clang/AST/DeclBase.h"
+#include "clang/AST/Decl.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallVector.h"
+#include <memory>
namespace clang {
+
class CallGraphNode;
+class Decl;
+class DeclContext;
+class Stmt;
/// \brief The AST-based call graph.
///
@@ -34,8 +42,8 @@ class CallGraphNode;
class CallGraph : public RecursiveASTVisitor<CallGraph> {
friend class CallGraphNode;
- typedef llvm::DenseMap<const Decl *, std::unique_ptr<CallGraphNode>>
- FunctionMapTy;
+ using FunctionMapTy =
+ llvm::DenseMap<const Decl *, std::unique_ptr<CallGraphNode>>;
/// FunctionMap owns all CallGraphNodes.
FunctionMapTy FunctionMap;
@@ -65,10 +73,11 @@ public:
/// one into the graph.
CallGraphNode *getOrInsertNode(Decl *);
+ using iterator = FunctionMapTy::iterator;
+ using const_iterator = FunctionMapTy::const_iterator;
+
/// Iterators through all the elements in the graph. Note, this gives
/// non-deterministic order.
- typedef FunctionMapTy::iterator iterator;
- typedef FunctionMapTy::const_iterator const_iterator;
iterator begin() { return FunctionMap.begin(); }
iterator end() { return FunctionMap.end(); }
const_iterator begin() const { return FunctionMap.begin(); }
@@ -84,8 +93,8 @@ public:
/// Iterators through all the nodes of the graph that have no parent. These
/// are the unreachable nodes, which are either unused or are due to us
/// failing to add a call edge due to the analysis imprecision.
- typedef llvm::SetVector<CallGraphNode *>::iterator nodes_iterator;
- typedef llvm::SetVector<CallGraphNode *>::const_iterator const_nodes_iterator;
+ using nodes_iterator = llvm::SetVector<CallGraphNode *>::iterator;
+ using const_nodes_iterator = llvm::SetVector<CallGraphNode *>::const_iterator;
void print(raw_ostream &os) const;
void dump() const;
@@ -133,7 +142,7 @@ private:
class CallGraphNode {
public:
- typedef CallGraphNode* CallRecord;
+ using CallRecord = CallGraphNode *;
private:
/// \brief The function/method declaration.
@@ -145,17 +154,17 @@ private:
public:
CallGraphNode(Decl *D) : FD(D) {}
- typedef SmallVectorImpl<CallRecord>::iterator iterator;
- typedef SmallVectorImpl<CallRecord>::const_iterator const_iterator;
+ using iterator = SmallVectorImpl<CallRecord>::iterator;
+ using const_iterator = SmallVectorImpl<CallRecord>::const_iterator;
/// Iterators through all the callees/children of the node.
- inline iterator begin() { return CalledFunctions.begin(); }
- inline iterator end() { return CalledFunctions.end(); }
- inline const_iterator begin() const { return CalledFunctions.begin(); }
- inline const_iterator end() const { return CalledFunctions.end(); }
+ iterator begin() { return CalledFunctions.begin(); }
+ iterator end() { return CalledFunctions.end(); }
+ const_iterator begin() const { return CalledFunctions.begin(); }
+ const_iterator end() const { return CalledFunctions.end(); }
- inline bool empty() const {return CalledFunctions.empty(); }
- inline unsigned size() const {return CalledFunctions.size(); }
+ bool empty() const { return CalledFunctions.empty(); }
+ unsigned size() const { return CalledFunctions.size(); }
void addCallee(CallGraphNode *N) {
CalledFunctions.push_back(N);
@@ -167,35 +176,33 @@ public:
void dump() const;
};
-} // end clang namespace
+} // namespace clang
// Graph traits for iteration, viewing.
namespace llvm {
+
template <> struct GraphTraits<clang::CallGraphNode*> {
- typedef clang::CallGraphNode NodeType;
- typedef clang::CallGraphNode *NodeRef;
- typedef NodeType::iterator ChildIteratorType;
+ using NodeType = clang::CallGraphNode;
+ using NodeRef = clang::CallGraphNode *;
+ using ChildIteratorType = NodeType::iterator;
static NodeType *getEntryNode(clang::CallGraphNode *CGN) { return CGN; }
- static inline ChildIteratorType child_begin(NodeType *N) {
- return N->begin();
- }
- static inline ChildIteratorType child_end(NodeType *N) { return N->end(); }
+ static ChildIteratorType child_begin(NodeType *N) { return N->begin(); }
+ static ChildIteratorType child_end(NodeType *N) { return N->end(); }
};
template <> struct GraphTraits<const clang::CallGraphNode*> {
- typedef const clang::CallGraphNode NodeType;
- typedef const clang::CallGraphNode *NodeRef;
- typedef NodeType::const_iterator ChildIteratorType;
+ using NodeType = const clang::CallGraphNode;
+ using NodeRef = const clang::CallGraphNode *;
+ using ChildIteratorType = NodeType::const_iterator;
static NodeType *getEntryNode(const clang::CallGraphNode *CGN) { return CGN; }
- static inline ChildIteratorType child_begin(NodeType *N) { return N->begin();}
- static inline ChildIteratorType child_end(NodeType *N) { return N->end(); }
+ static ChildIteratorType child_begin(NodeType *N) { return N->begin();}
+ static ChildIteratorType child_end(NodeType *N) { return N->end(); }
};
template <> struct GraphTraits<clang::CallGraph*>
: public GraphTraits<clang::CallGraphNode*> {
-
static NodeType *getEntryNode(clang::CallGraph *CGN) {
return CGN->getRoot(); // Start at the external node!
}
@@ -206,19 +213,18 @@ template <> struct GraphTraits<clang::CallGraph*>
}
// nodes_iterator/begin/end - Allow iteration over all nodes in the graph
- typedef mapped_iterator<clang::CallGraph::iterator, decltype(&CGGetValue)>
- nodes_iterator;
+ using nodes_iterator =
+ mapped_iterator<clang::CallGraph::iterator, decltype(&CGGetValue)>;
static nodes_iterator nodes_begin(clang::CallGraph *CG) {
return nodes_iterator(CG->begin(), &CGGetValue);
}
+
static nodes_iterator nodes_end (clang::CallGraph *CG) {
return nodes_iterator(CG->end(), &CGGetValue);
}
- static unsigned size(clang::CallGraph *CG) {
- return CG->size();
- }
+ static unsigned size(clang::CallGraph *CG) { return CG->size(); }
};
template <> struct GraphTraits<const clang::CallGraph*> :
@@ -233,21 +239,20 @@ template <> struct GraphTraits<const clang::CallGraph*> :
}
// nodes_iterator/begin/end - Allow iteration over all nodes in the graph
- typedef mapped_iterator<clang::CallGraph::const_iterator,
- decltype(&CGGetValue)>
- nodes_iterator;
+ using nodes_iterator =
+ mapped_iterator<clang::CallGraph::const_iterator, decltype(&CGGetValue)>;
static nodes_iterator nodes_begin(const clang::CallGraph *CG) {
return nodes_iterator(CG->begin(), &CGGetValue);
}
+
static nodes_iterator nodes_end(const clang::CallGraph *CG) {
return nodes_iterator(CG->end(), &CGGetValue);
}
- static unsigned size(const clang::CallGraph *CG) {
- return CG->size();
- }
+
+ static unsigned size(const clang::CallGraph *CG) { return CG->size(); }
};
-} // end llvm namespace
+} // namespace llvm
-#endif
+#endif // LLVM_CLANG_ANALYSIS_CALLGRAPH_H
diff --git a/include/clang/Analysis/CloneDetection.h b/include/clang/Analysis/CloneDetection.h
index 6339deef41bd..051b9236658c 100644
--- a/include/clang/Analysis/CloneDetection.h
+++ b/include/clang/Analysis/CloneDetection.h
@@ -7,19 +7,15 @@
//
//===----------------------------------------------------------------------===//
///
-/// /file
-/// This file defines classes for searching and anlyzing source code clones.
+/// \file
+/// This file defines classes for searching and analyzing source code clones.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_CLONEDETECTION_H
#define LLVM_CLANG_AST_CLONEDETECTION_H
-#include "clang/AST/DeclTemplate.h"
#include "clang/AST/StmtVisitor.h"
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Regex.h"
#include <vector>
@@ -31,192 +27,6 @@ class VarDecl;
class ASTContext;
class CompoundStmt;
-namespace clone_detection {
-
-/// Returns a string that represents all macro expansions that expanded into the
-/// given SourceLocation.
-///
-/// If 'getMacroStack(A) == getMacroStack(B)' is true, then the SourceLocations
-/// A and B are expanded from the same macros in the same order.
-std::string getMacroStack(SourceLocation Loc, ASTContext &Context);
-
-/// Collects the data of a single Stmt.
-///
-/// This class defines what a code clone is: If it collects for two statements
-/// the same data, then those two statements are considered to be clones of each
-/// other.
-///
-/// All collected data is forwarded to the given data consumer of the type T.
-/// The data consumer class needs to provide a member method with the signature:
-/// update(StringRef Str)
-template <typename T>
-class StmtDataCollector : public ConstStmtVisitor<StmtDataCollector<T>> {
-
- ASTContext &Context;
- /// The data sink to which all data is forwarded.
- T &DataConsumer;
-
-public:
- /// Collects data of the given Stmt.
- /// \param S The given statement.
- /// \param Context The ASTContext of S.
- /// \param DataConsumer The data sink to which all data is forwarded.
- StmtDataCollector(const Stmt *S, ASTContext &Context, T &DataConsumer)
- : Context(Context), DataConsumer(DataConsumer) {
- this->Visit(S);
- }
-
- typedef unsigned DataPiece;
-
- // Below are utility methods for appending different data to the vector.
-
- void addData(DataPiece Integer) {
- DataConsumer.update(
- StringRef(reinterpret_cast<char *>(&Integer), sizeof(Integer)));
- }
-
- void addData(llvm::StringRef Str) { DataConsumer.update(Str); }
-
- void addData(const QualType &QT) { addData(QT.getAsString()); }
-
-// The functions below collect the class specific data of each Stmt subclass.
-
-// Utility macro for defining a visit method for a given class. This method
-// calls back to the ConstStmtVisitor to visit all parent classes.
-#define DEF_ADD_DATA(CLASS, CODE) \
- void Visit##CLASS(const CLASS *S) { \
- CODE; \
- ConstStmtVisitor<StmtDataCollector>::Visit##CLASS(S); \
- }
-
- DEF_ADD_DATA(Stmt, {
- addData(S->getStmtClass());
- // This ensures that macro generated code isn't identical to macro-generated
- // code.
- addData(getMacroStack(S->getLocStart(), Context));
- addData(getMacroStack(S->getLocEnd(), Context));
- })
- DEF_ADD_DATA(Expr, { addData(S->getType()); })
-
- //--- Builtin functionality ----------------------------------------------//
- DEF_ADD_DATA(ArrayTypeTraitExpr, { addData(S->getTrait()); })
- DEF_ADD_DATA(ExpressionTraitExpr, { addData(S->getTrait()); })
- DEF_ADD_DATA(PredefinedExpr, { addData(S->getIdentType()); })
- DEF_ADD_DATA(TypeTraitExpr, {
- addData(S->getTrait());
- for (unsigned i = 0; i < S->getNumArgs(); ++i)
- addData(S->getArg(i)->getType());
- })
-
- //--- Calls --------------------------------------------------------------//
- DEF_ADD_DATA(CallExpr, {
- // Function pointers don't have a callee and we just skip hashing it.
- if (const FunctionDecl *D = S->getDirectCallee()) {
- // If the function is a template specialization, we also need to handle
- // the template arguments as they are not included in the qualified name.
- if (auto Args = D->getTemplateSpecializationArgs()) {
- std::string ArgString;
-
- // Print all template arguments into ArgString
- llvm::raw_string_ostream OS(ArgString);
- for (unsigned i = 0; i < Args->size(); ++i) {
- Args->get(i).print(Context.getLangOpts(), OS);
- // Add a padding character so that 'foo<X, XX>()' != 'foo<XX, X>()'.
- OS << '\n';
- }
- OS.flush();
-
- addData(ArgString);
- }
- addData(D->getQualifiedNameAsString());
- }
- })
-
- //--- Exceptions ---------------------------------------------------------//
- DEF_ADD_DATA(CXXCatchStmt, { addData(S->getCaughtType()); })
-
- //--- C++ OOP Stmts ------------------------------------------------------//
- DEF_ADD_DATA(CXXDeleteExpr, {
- addData(S->isArrayFormAsWritten());
- addData(S->isGlobalDelete());
- })
-
- //--- Casts --------------------------------------------------------------//
- DEF_ADD_DATA(ObjCBridgedCastExpr, { addData(S->getBridgeKind()); })
-
- //--- Miscellaneous Exprs ------------------------------------------------//
- DEF_ADD_DATA(BinaryOperator, { addData(S->getOpcode()); })
- DEF_ADD_DATA(UnaryOperator, { addData(S->getOpcode()); })
-
- //--- Control flow -------------------------------------------------------//
- DEF_ADD_DATA(GotoStmt, { addData(S->getLabel()->getName()); })
- DEF_ADD_DATA(IndirectGotoStmt, {
- if (S->getConstantTarget())
- addData(S->getConstantTarget()->getName());
- })
- DEF_ADD_DATA(LabelStmt, { addData(S->getDecl()->getName()); })
- DEF_ADD_DATA(MSDependentExistsStmt, { addData(S->isIfExists()); })
- DEF_ADD_DATA(AddrLabelExpr, { addData(S->getLabel()->getName()); })
-
- //--- Objective-C --------------------------------------------------------//
- DEF_ADD_DATA(ObjCIndirectCopyRestoreExpr, { addData(S->shouldCopy()); })
- DEF_ADD_DATA(ObjCPropertyRefExpr, {
- addData(S->isSuperReceiver());
- addData(S->isImplicitProperty());
- })
- DEF_ADD_DATA(ObjCAtCatchStmt, { addData(S->hasEllipsis()); })
-
- //--- Miscellaneous Stmts ------------------------------------------------//
- DEF_ADD_DATA(CXXFoldExpr, {
- addData(S->isRightFold());
- addData(S->getOperator());
- })
- DEF_ADD_DATA(GenericSelectionExpr, {
- for (unsigned i = 0; i < S->getNumAssocs(); ++i) {
- addData(S->getAssocType(i));
- }
- })
- DEF_ADD_DATA(LambdaExpr, {
- for (const LambdaCapture &C : S->captures()) {
- addData(C.isPackExpansion());
- addData(C.getCaptureKind());
- if (C.capturesVariable())
- addData(C.getCapturedVar()->getType());
- }
- addData(S->isGenericLambda());
- addData(S->isMutable());
- })
- DEF_ADD_DATA(DeclStmt, {
- auto numDecls = std::distance(S->decl_begin(), S->decl_end());
- addData(static_cast<DataPiece>(numDecls));
- for (const Decl *D : S->decls()) {
- if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
- addData(VD->getType());
- }
- }
- })
- DEF_ADD_DATA(AsmStmt, {
- addData(S->isSimple());
- addData(S->isVolatile());
- addData(S->generateAsmString(Context));
- for (unsigned i = 0; i < S->getNumInputs(); ++i) {
- addData(S->getInputConstraint(i));
- }
- for (unsigned i = 0; i < S->getNumOutputs(); ++i) {
- addData(S->getOutputConstraint(i));
- }
- for (unsigned i = 0; i < S->getNumClobbers(); ++i) {
- addData(S->getClobber(i));
- }
- })
- DEF_ADD_DATA(AttributedStmt, {
- for (const Attr *A : S->getAttrs()) {
- addData(std::string(A->getSpelling()));
- }
- })
-};
-} // namespace clone_detection
-
/// Identifies a list of statements.
///
/// Can either identify a single arbitrary Stmt object, a continuous sequence of
@@ -423,9 +233,9 @@ public:
/// filtered.
/// \param Filter The filter function that should return true for all groups
/// that should be removed from the list.
- static void
- filterGroups(std::vector<CloneDetector::CloneGroup> &CloneGroups,
- std::function<bool(const CloneDetector::CloneGroup &)> Filter) {
+ static void filterGroups(
+ std::vector<CloneDetector::CloneGroup> &CloneGroups,
+ llvm::function_ref<bool(const CloneDetector::CloneGroup &)> Filter) {
CloneGroups.erase(
std::remove_if(CloneGroups.begin(), CloneGroups.end(), Filter),
CloneGroups.end());
@@ -439,25 +249,29 @@ public:
/// to the same CloneGroup.
static void splitCloneGroups(
std::vector<CloneDetector::CloneGroup> &CloneGroups,
- std::function<bool(const StmtSequence &, const StmtSequence &)> Compare);
+ llvm::function_ref<bool(const StmtSequence &, const StmtSequence &)>
+ Compare);
};
-/// Searches all children of the given clones for type II clones (i.e. they are
-/// identical in every aspect beside the used variable names).
-class RecursiveCloneTypeIIConstraint {
-
- /// Generates and saves a hash code for the given Stmt.
- /// \param S The given Stmt.
- /// \param D The Decl containing S.
- /// \param StmtsByHash Output parameter that will contain the hash codes for
- /// each StmtSequence in the given Stmt.
- /// \return The hash code of the given Stmt.
- ///
- /// If the given Stmt is a CompoundStmt, this method will also generate
- /// hashes for all possible StmtSequences in the children of this Stmt.
- size_t saveHash(const Stmt *S, const Decl *D,
- std::vector<std::pair<size_t, StmtSequence>> &StmtsByHash);
+/// This constraint moves clones into clone groups of type II via hashing.
+///
+/// Clones with different hash values are moved into separate clone groups.
+/// Collisions are possible, and this constraint does nothing to address this
+/// them. Add the slower RecursiveCloneTypeIIVerifyConstraint later in the
+/// constraint chain, not necessarily immediately, to eliminate hash collisions
+/// through a more detailed analysis.
+class RecursiveCloneTypeIIHashConstraint {
+public:
+ void constrain(std::vector<CloneDetector::CloneGroup> &Sequences);
+};
+/// This constraint moves clones into clone groups of type II by comparing them.
+///
+/// Clones that aren't type II clones are moved into separate clone groups.
+/// In contrast to the RecursiveCloneTypeIIHashConstraint, all clones in a clone
+/// group are guaranteed to be be type II clones of each other, but it is too
+/// slow to efficiently handle large amounts of clones.
+class RecursiveCloneTypeIIVerifyConstraint {
public:
void constrain(std::vector<CloneDetector::CloneGroup> &Sequences);
};
@@ -474,14 +288,19 @@ public:
MinComplexityConstraint(unsigned MinComplexity)
: MinComplexity(MinComplexity) {}
- size_t calculateStmtComplexity(const StmtSequence &Seq,
+ /// Calculates the complexity of the given StmtSequence.
+ /// \param Limit The limit of complexity we probe for. After reaching
+ /// this limit during calculation, this method is exiting
+ /// early to improve performance and returns this limit.
+ size_t calculateStmtComplexity(const StmtSequence &Seq, std::size_t Limit,
const std::string &ParentMacroStack = "");
void constrain(std::vector<CloneDetector::CloneGroup> &CloneGroups) {
CloneConstraint::filterGroups(
CloneGroups, [this](const CloneDetector::CloneGroup &A) {
if (!A.empty())
- return calculateStmtComplexity(A.front()) < MinComplexity;
+ return calculateStmtComplexity(A.front(), MinComplexity) <
+ MinComplexity;
else
return false;
});
diff --git a/include/clang/Analysis/ProgramPoint.h b/include/clang/Analysis/ProgramPoint.h
index be5adfb29423..2d59dec48a88 100644
--- a/include/clang/Analysis/ProgramPoint.h
+++ b/include/clang/Analysis/ProgramPoint.h
@@ -15,7 +15,7 @@
#ifndef LLVM_CLANG_ANALYSIS_PROGRAMPOINT_H
#define LLVM_CLANG_ANALYSIS_PROGRAMPOINT_H
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
#include "clang/Analysis/CFG.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
@@ -83,6 +83,7 @@ public:
PostImplicitCallKind,
MinImplicitCallKind = PreImplicitCallKind,
MaxImplicitCallKind = PostImplicitCallKind,
+ LoopExitKind,
EpsilonKind};
private:
@@ -654,6 +655,29 @@ private:
}
};
+/// Represents a point when we exit a loop.
+/// When this ProgramPoint is encountered we can be sure that the symbolic
+/// execution of the corresponding LoopStmt is finished on the given path.
+/// Note: It is possible to encounter a LoopExit element when we haven't even
+/// encountered the loop itself. At the current state not all loop exits will
+/// result in a LoopExit program point.
+class LoopExit : public ProgramPoint {
+public:
+ LoopExit(const Stmt *LoopStmt, const LocationContext *LC)
+ : ProgramPoint(LoopStmt, nullptr, LoopExitKind, LC) {}
+
+ const Stmt *getLoopStmt() const {
+ return static_cast<const Stmt *>(getData1());
+ }
+
+private:
+ friend class ProgramPoint;
+ LoopExit() {}
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() == LoopExitKind;
+ }
+};
+
/// This is a meta program point, which should be skipped by all the diagnostic
/// reasoning etc.
class EpsilonPoint : public ProgramPoint {
diff --git a/include/clang/Analysis/Support/BumpVector.h b/include/clang/Analysis/Support/BumpVector.h
index 591d17b9bc03..5940520855ef 100644
--- a/include/clang/Analysis/Support/BumpVector.h
+++ b/include/clang/Analysis/Support/BumpVector.h
@@ -1,4 +1,4 @@
-//===-- BumpVector.h - Vector-like ADT that uses bump allocation --*- C++ -*-=//
+//===- BumpVector.h - Vector-like ADT that uses bump allocation -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -21,16 +21,18 @@
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/Support/Allocator.h"
-#include "llvm/Support/type_traits.h"
-#include <algorithm>
+#include <cassert>
+#include <cstddef>
#include <cstring>
#include <iterator>
#include <memory>
+#include <type_traits>
namespace clang {
class BumpVectorContext {
llvm::PointerIntPair<llvm::BumpPtrAllocator*, 1> Alloc;
+
public:
/// Construct a new BumpVectorContext that creates a new BumpPtrAllocator
/// and destroys it when the BumpVectorContext object is destroyed.
@@ -56,11 +58,13 @@ public:
template<typename T>
class BumpVector {
- T *Begin, *End, *Capacity;
+ T *Begin = nullptr;
+ T *End = nullptr;
+ T *Capacity = nullptr;
+
public:
// Default ctor - Initialize to empty.
- explicit BumpVector(BumpVectorContext &C, unsigned N)
- : Begin(nullptr), End(nullptr), Capacity(nullptr) {
+ explicit BumpVector(BumpVectorContext &C, unsigned N) {
reserve(C, N);
}
@@ -71,19 +75,19 @@ public:
}
}
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
- typedef T value_type;
- typedef T* iterator;
- typedef const T* const_iterator;
+ using size_type = size_t;
+ using difference_type = ptrdiff_t;
+ using value_type = T;
+ using iterator = T *;
+ using const_iterator = const T *;
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
- typedef std::reverse_iterator<iterator> reverse_iterator;
+ using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+ using reverse_iterator = std::reverse_iterator<iterator>;
- typedef T& reference;
- typedef const T& const_reference;
- typedef T* pointer;
- typedef const T* const_pointer;
+ using reference = T &;
+ using const_reference = const T &;
+ using pointer = T *;
+ using const_pointer = const T *;
// forward iterator creation methods.
iterator begin() { return Begin; }
@@ -92,10 +96,12 @@ public:
const_iterator end() const { return End; }
// reverse iterator creation methods.
- reverse_iterator rbegin() { return reverse_iterator(end()); }
+ reverse_iterator rbegin() { return reverse_iterator(end()); }
const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
- reverse_iterator rend() { return reverse_iterator(begin()); }
- const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
+ reverse_iterator rend() { return reverse_iterator(begin()); }
+ const_reverse_iterator rend() const {
+ return const_reverse_iterator(begin());
+ }
bool empty() const { return Begin == End; }
size_type size() const { return End-Begin; }
@@ -166,7 +172,7 @@ public:
/// iterator to position after last inserted copy.
iterator insert(iterator I, size_t Cnt, const_reference E,
BumpVectorContext &C) {
- assert (I >= Begin && I <= End && "Iterator out of bounds.");
+ assert(I >= Begin && I <= End && "Iterator out of bounds.");
if (End + Cnt <= Capacity) {
Retry:
move_range_right(I, End, Cnt);
@@ -246,5 +252,6 @@ void BumpVector<T>::grow(BumpVectorContext &C, size_t MinSize) {
Capacity = Begin+NewCapacity;
}
-} // end: clang namespace
-#endif
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_SUPPORT_BUMPVECTOR_H
diff --git a/include/clang/Basic/AddressSpaces.h b/include/clang/Basic/AddressSpaces.h
index 95b9b9c7d0b3..6b0090813e9b 100644
--- a/include/clang/Basic/AddressSpaces.h
+++ b/include/clang/Basic/AddressSpaces.h
@@ -16,25 +16,26 @@
#ifndef LLVM_CLANG_BASIC_ADDRESSSPACES_H
#define LLVM_CLANG_BASIC_ADDRESSSPACES_H
-namespace clang {
+#include <assert.h>
-namespace LangAS {
+namespace clang {
/// \brief Defines the address space values used by the address space qualifier
/// of QualType.
///
-enum ID {
+enum class LangAS : unsigned {
// The default value 0 is the value used in QualType for the the situation
- // where there is no address space qualifier. For most languages, this also
- // corresponds to the situation where there is no address space qualifier in
- // the source code, except for OpenCL, where the address space value 0 in
- // QualType represents private address space in OpenCL source code.
+ // where there is no address space qualifier.
Default = 0,
// OpenCL specific address spaces.
+ // In OpenCL each l-value must have certain non-default address space, each
+ // r-value must have no address space (i.e. the default address space). The
+ // pointee of a pointer must have non-default address space.
opencl_global,
opencl_local,
opencl_constant,
+ opencl_private,
opencl_generic,
// CUDA specific address spaces.
@@ -50,9 +51,24 @@ enum ID {
/// The type of a lookup table which maps from language-specific address spaces
/// to target-specific ones.
-typedef unsigned Map[FirstTargetAddressSpace];
+typedef unsigned LangASMap[(unsigned)LangAS::FirstTargetAddressSpace];
+
+/// \return whether \p AS is a target-specific address space rather than a
+/// clang AST address space
+inline bool isTargetAddressSpace(LangAS AS) {
+ return (unsigned)AS >= (unsigned)LangAS::FirstTargetAddressSpace;
}
+inline unsigned toTargetAddressSpace(LangAS AS) {
+ assert(isTargetAddressSpace(AS));
+ return (unsigned)AS - (unsigned)LangAS::FirstTargetAddressSpace;
}
+inline LangAS getLangASFromTargetAS(unsigned TargetAS) {
+ return static_cast<LangAS>((TargetAS) +
+ (unsigned)LangAS::FirstTargetAddressSpace);
+}
+
+} // namespace clang
+
#endif
diff --git a/include/clang/Basic/AlignedAllocation.h b/include/clang/Basic/AlignedAllocation.h
new file mode 100644
index 000000000000..b3496949f39a
--- /dev/null
+++ b/include/clang/Basic/AlignedAllocation.h
@@ -0,0 +1,44 @@
+//===--- AlignedAllocation.h - Aligned Allocation ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines a function that returns the minimum OS versions supporting
+/// C++17's aligned allocation functions.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_ALIGNED_ALLOCATION_H
+#define LLVM_CLANG_BASIC_ALIGNED_ALLOCATION_H
+
+#include "clang/Basic/VersionTuple.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace clang {
+
+inline VersionTuple alignedAllocMinVersion(llvm::Triple::OSType OS) {
+ switch (OS) {
+ default:
+ break;
+ case llvm::Triple::Darwin:
+ case llvm::Triple::MacOSX: // Earliest supporting version is 10.13.
+ return VersionTuple(10U, 13U);
+ case llvm::Triple::IOS:
+ case llvm::Triple::TvOS: // Earliest supporting version is 11.0.0.
+ return VersionTuple(11U);
+ case llvm::Triple::WatchOS: // Earliest supporting version is 4.0.0.
+ return VersionTuple(4U);
+ }
+
+ llvm_unreachable("Unexpected OS");
+}
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_BASIC_ALIGNED_ALLOCATION_H
diff --git a/include/clang/Basic/AllDiagnostics.h b/include/clang/Basic/AllDiagnostics.h
index fc861a1952a5..1c83e2d0f8a0 100644
--- a/include/clang/Basic/AllDiagnostics.h
+++ b/include/clang/Basic/AllDiagnostics.h
@@ -18,12 +18,14 @@
#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"
namespace clang {
template <size_t SizeOfStr, typename FieldType>
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
index 5c69635b9492..d926fdde4eee 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -69,44 +69,47 @@ include "clang/Basic/StmtNodes.td"
//
// The code fragment is a boolean expression that will confirm that the subject
// meets the requirements; the subject will have the name S, and will have the
-// type specified by the base. It should be a simple boolean expression.
-class SubsetSubject<AttrSubject base, code check> : AttrSubject {
+// type specified by the base. It should be a simple boolean expression. The
+// diagnostic string should be a comma-separated list of subject names.
+class SubsetSubject<AttrSubject base, code check, string diag> : AttrSubject {
AttrSubject Base = base;
code CheckCode = check;
+ string DiagSpelling = diag;
}
-// This is the type of a variable which C++11 allows alignas(...) to appertain
-// to.
-def NormalVar : SubsetSubject<Var,
- [{S->getStorageClass() != VarDecl::Register &&
- S->getKind() != Decl::ImplicitParam &&
- S->getKind() != Decl::ParmVar &&
- S->getKind() != Decl::NonTypeTemplateParm}]>;
+def LocalVar : SubsetSubject<Var,
+ [{S->hasLocalStorage() && !isa<ParmVarDecl>(S)}],
+ "local variables">;
def NonParmVar : SubsetSubject<Var,
- [{S->getKind() != Decl::ParmVar}]>;
+ [{S->getKind() != Decl::ParmVar}],
+ "variables">;
def NonBitField : SubsetSubject<Field,
- [{!S->isBitField()}]>;
+ [{!S->isBitField()}],
+ "non-bit-field non-static data members">;
def ObjCInstanceMethod : SubsetSubject<ObjCMethod,
- [{S->isInstanceMethod()}]>;
+ [{S->isInstanceMethod()}],
+ "Objective-C instance methods">;
def ObjCInterfaceDeclInitMethod : SubsetSubject<ObjCMethod,
[{S->getMethodFamily() == OMF_init &&
(isa<ObjCInterfaceDecl>(S->getDeclContext()) ||
(isa<ObjCCategoryDecl>(S->getDeclContext()) &&
- cast<ObjCCategoryDecl>(S->getDeclContext())->IsClassExtension()))}]>;
+ cast<ObjCCategoryDecl>(S->getDeclContext())->IsClassExtension()))}],
+ "init methods of interface or class extension declarations">;
def Struct : SubsetSubject<Record,
- [{!S->isUnion()}]>;
+ [{!S->isUnion()}], "structs">;
def TLSVar : SubsetSubject<Var,
- [{S->getTLSKind() != 0}]>;
+ [{S->getTLSKind() != 0}], "thread-local variables">;
def SharedVar : SubsetSubject<Var,
- [{S->hasGlobalStorage() && !S->getTLSKind()}]>;
+ [{S->hasGlobalStorage() && !S->getTLSKind()}],
+ "global variables">;
def GlobalVar : SubsetSubject<Var,
- [{S->hasGlobalStorage()}]>;
+ [{S->hasGlobalStorage()}], "global variables">;
// FIXME: this hack is needed because DeclNodes.td defines the base Decl node
// type to be a class, not a definition. This makes it impossible to create an
@@ -115,11 +118,12 @@ def GlobalVar : SubsetSubject<Var,
// the case of a SubsetSubject, there's no way to express it without this hack.
def DeclBase : AttrSubject;
def FunctionLike : SubsetSubject<DeclBase,
- [{S->getFunctionType(false) != nullptr}]>;
+ [{S->getFunctionType(false) != nullptr}],
+ "functions, function pointers">;
-def OpenCLKernelFunction : SubsetSubject<Function, [{
- S->hasAttr<OpenCLKernelAttr>()
-}]>;
+def OpenCLKernelFunction
+ : SubsetSubject<Function, [{S->hasAttr<OpenCLKernelAttr>()}],
+ "kernel functions">;
// HasFunctionProto is a more strict version of FunctionLike, so it should
// never be specified in a Subjects list along with FunctionLike (due to the
@@ -128,7 +132,8 @@ def HasFunctionProto : SubsetSubject<DeclBase,
[{(S->getFunctionType(true) != nullptr &&
isa<FunctionProtoType>(S->getFunctionType())) ||
isa<ObjCMethodDecl>(S) ||
- isa<BlockDecl>(S)}]>;
+ isa<BlockDecl>(S)}],
+ "non-K&R-style functions">;
// A single argument to an attribute
class Argument<string name, bit optional, bit fake = 0> {
@@ -210,18 +215,26 @@ class CXX11<string namespace, string name, int version = 1>
string Namespace = namespace;
int Version = version;
}
+class C2x<string namespace, string name> : Spelling<name, "C2x"> {
+ string Namespace = namespace;
+}
+
class Keyword<string name> : Spelling<name, "Keyword">;
class Pragma<string namespace, string name> : Spelling<name, "Pragma"> {
string Namespace = namespace;
}
-// The GCC spelling implies GNU<name, "GNU"> and CXX11<"gnu", name> and also
-// sets KnownToGCC to 1. This spelling should be used for any GCC-compatible
+// The GCC spelling implies GNU<name> and CXX11<"gnu", name> and also sets
+// KnownToGCC to 1. This spelling should be used for any GCC-compatible
// attributes.
class GCC<string name> : Spelling<name, "GCC"> {
let KnownToGCC = 1;
}
+// The Clang spelling implies GNU<name> and CXX11<"clang", name>. This spelling
+// should be used for any Clang-specific attributes.
+class Clang<string name> : Spelling<name, "Clang">;
+
class Accessor<string name, list<Spelling> spellings> {
string Name = name;
list<Spelling> Spellings = spellings;
@@ -264,14 +277,15 @@ class TargetArch<list<string> arches> {
}
def TargetARM : TargetArch<["arm", "thumb", "armeb", "thumbeb"]>;
def TargetAVR : TargetArch<["avr"]>;
-def TargetMips : TargetArch<["mips", "mipsel"]>;
+def TargetMips32 : TargetArch<["mips", "mipsel"]>;
+def TargetAnyMips : TargetArch<["mips", "mipsel", "mips64", "mips64el"]>;
def TargetMSP430 : TargetArch<["msp430"]>;
def TargetX86 : TargetArch<["x86"]>;
def TargetAnyX86 : TargetArch<["x86", "x86_64"]>;
-def TargetWindows : TargetArch<["x86", "x86_64", "arm", "thumb"]> {
+def TargetWindows : TargetArch<["x86", "x86_64", "arm", "thumb", "aarch64"]> {
let OSes = ["Win32"];
}
-def TargetMicrosoftCXXABI : TargetArch<["x86", "x86_64", "arm", "thumb"]> {
+def TargetMicrosoftCXXABI : TargetArch<["x86", "x86_64", "arm", "thumb", "aarch64"]> {
let CXXABIs = ["Microsoft"];
}
@@ -493,14 +507,13 @@ class IgnoredAttr : Attr {
def AbiTag : Attr {
let Spellings = [GCC<"abi_tag">];
let Args = [VariadicStringArgument<"Tags">];
- let Subjects = SubjectList<[Struct, Var, Function, Namespace], ErrorDiag,
- "ExpectedStructClassVariableFunctionOrInlineNamespace">;
+ let Subjects = SubjectList<[Struct, Var, Function, Namespace], ErrorDiag>;
let MeaningfulToClassTemplateDefinition = 1;
let Documentation = [AbiTagsDocs];
}
def AddressSpace : TypeAttr {
- let Spellings = [GNU<"address_space">];
+ let Spellings = [Clang<"address_space">];
let Args = [IntArgument<"AddressSpace">];
let Documentation = [Undocumented];
}
@@ -508,15 +521,13 @@ def AddressSpace : TypeAttr {
def Alias : Attr {
let Spellings = [GCC<"alias">];
let Args = [StringArgument<"Aliasee">];
- let Subjects = SubjectList<[Function, GlobalVar], ErrorDiag,
- "ExpectedFunctionOrGlobalVar">;
+ let Subjects = SubjectList<[Function, GlobalVar], ErrorDiag>;
let Documentation = [Undocumented];
}
def Aligned : InheritableAttr {
let Spellings = [GCC<"aligned">, Declspec<"align">, Keyword<"alignas">,
Keyword<"_Alignas">];
-// let Subjects = SubjectList<[NonBitField, NormalVar, Tag]>;
let Args = [AlignedArgument<"Alignment", 1>];
let Accessors = [Accessor<"isGNU", [GCC<"aligned">]>,
Accessor<"isC11", [Keyword<"_Alignas">]>,
@@ -534,13 +545,15 @@ def AlignValue : Attr {
// the future (and a corresponding C++ attribute), but this can be done
// later once we decide if we also want them to have slightly-different
// semantics than Intel's align_value.
+ //
+ // Does not get a [[]] spelling because the attribute is not exposed as such
+ // by Intel.
GNU<"align_value">
// Intel's compiler on Windows also supports:
// , Declspec<"align_value">
];
let Args = [ExprArgument<"Alignment">];
- let Subjects = SubjectList<[Var, TypedefName], WarnDiag,
- "ExpectedVariableOrTypedef">;
+ let Subjects = SubjectList<[Var, TypedefName]>;
let Documentation = [AlignValueDocs];
}
@@ -558,44 +571,40 @@ def AlwaysInline : InheritableAttr {
}
def XRayInstrument : InheritableAttr {
- let Spellings = [GNU<"xray_always_instrument">,
- CXX11<"clang", "xray_always_instrument">,
- GNU<"xray_never_instrument">,
- CXX11<"clang", "xray_never_instrument">];
- let Subjects = SubjectList<[CXXMethod, ObjCMethod, Function], WarnDiag,
- "ExpectedFunctionOrMethod">;
+ let Spellings = [Clang<"xray_always_instrument">,
+ Clang<"xray_never_instrument">];
+ let Subjects = SubjectList<[Function, ObjCMethod]>;
let Accessors = [Accessor<"alwaysXRayInstrument",
- [GNU<"xray_always_instrument">,
- CXX11<"clang", "xray_always_instrument">]>,
+ [Clang<"xray_always_instrument">]>,
Accessor<"neverXRayInstrument",
- [GNU<"xray_never_instrument">,
- CXX11<"clang", "xray_never_instrument">]>];
+ [Clang<"xray_never_instrument">]>];
let Documentation = [XRayDocs];
}
def XRayLogArgs : InheritableAttr {
- let Spellings = [GNU<"xray_log_args">, CXX11<"clang", "xray_log_args">];
- let Subjects = SubjectList<
- [CXXMethod, ObjCMethod, Function], WarnDiag, "ExpectedFunctionOrMethod"
- >;
+ let Spellings = [Clang<"xray_log_args">];
+ let Subjects = SubjectList<[Function, ObjCMethod]>;
let Args = [UnsignedArgument<"ArgumentCount">];
let Documentation = [XRayDocs];
}
def TLSModel : InheritableAttr {
let Spellings = [GCC<"tls_model">];
- let Subjects = SubjectList<[TLSVar], ErrorDiag, "ExpectedTLSVar">;
+ let Subjects = SubjectList<[TLSVar], ErrorDiag>;
let Args = [StringArgument<"Model">];
let Documentation = [TLSModelDocs];
}
def AnalyzerNoReturn : InheritableAttr {
+ // TODO: should this attribute be exposed with a [[]] spelling under the clang
+ // vendor namespace, or should it use a vendor namespace specific to the
+ // analyzer?
let Spellings = [GNU<"analyzer_noreturn">];
let Documentation = [Undocumented];
}
def Annotate : InheritableParamAttr {
- let Spellings = [GNU<"annotate">];
+ let Spellings = [Clang<"annotate">];
let Args = [StringArgument<"Annotation">];
// Ensure that the annotate attribute can be used with
// '#pragma clang attribute' even though it has no subject list.
@@ -606,7 +615,7 @@ def Annotate : InheritableParamAttr {
def ARMInterrupt : InheritableAttr, TargetSpecificAttr<TargetARM> {
// NOTE: If you add any additional spellings, MSP430Interrupt's,
// MipsInterrupt's and AnyX86Interrupt's spellings must match.
- let Spellings = [GNU<"interrupt">];
+ let Spellings = [GCC<"interrupt">];
let Args = [EnumArgument<"Interrupt", "InterruptType",
["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", ""],
["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", "Generic"],
@@ -617,14 +626,14 @@ def ARMInterrupt : InheritableAttr, TargetSpecificAttr<TargetARM> {
}
def AVRInterrupt : InheritableAttr, TargetSpecificAttr<TargetAVR> {
- let Spellings = [GNU<"interrupt">];
+ let Spellings = [GCC<"interrupt">];
let Subjects = SubjectList<[Function]>;
let ParseKind = "Interrupt";
let Documentation = [AVRInterruptDocs];
}
def AVRSignal : InheritableAttr, TargetSpecificAttr<TargetAVR> {
- let Spellings = [GNU<"signal">];
+ let Spellings = [GCC<"signal">];
let Subjects = SubjectList<[Function]>;
let Documentation = [AVRSignalDocs];
}
@@ -637,6 +646,8 @@ def AsmLabel : InheritableAttr {
}
def Availability : InheritableAttr {
+ // TODO: does not have a [[]] spelling because it requires custom parsing
+ // support.
let Spellings = [GNU<"availability">];
let Args = [IdentifierArgument<"platform">, VersionArgument<"introduced">,
VersionArgument<"deprecated">, VersionArgument<"obsoleted">,
@@ -687,8 +698,7 @@ static llvm::StringRef canonicalizePlatformName(llvm::StringRef Platform) {
}
def ExternalSourceSymbol : InheritableAttr {
- let Spellings = [GNU<"external_source_symbol">,
- CXX11<"clang", "external_source_symbol">];
+ let Spellings = [Clang<"external_source_symbol">];
let Args = [StringArgument<"language", 1>,
StringArgument<"definedIn", 1>,
BoolArgument<"generatedDeclaration", 1>];
@@ -698,12 +708,13 @@ def ExternalSourceSymbol : InheritableAttr {
}
def Blocks : InheritableAttr {
- let Spellings = [GNU<"blocks">];
+ let Spellings = [Clang<"blocks">];
let Args = [EnumArgument<"Type", "BlockType", ["byref"], ["ByRef"]>];
let Documentation = [Undocumented];
}
def Bounded : IgnoredAttr {
+ // Does not have a [[]] spelling because the attribute is ignored.
let Spellings = [GNU<"bounded">];
}
@@ -725,7 +736,7 @@ def CDecl : InheritableAttr {
// cf_returns_retained attributes. It is generally applied by
// '#pragma clang arc_cf_code_audited' rather than explicitly.
def CFAuditedTransfer : InheritableAttr {
- let Spellings = [GNU<"cf_audited_transfer">];
+ let Spellings = [Clang<"cf_audited_transfer">];
let Subjects = SubjectList<[Function], ErrorDiag>;
let Documentation = [Undocumented];
}
@@ -734,25 +745,25 @@ def CFAuditedTransfer : InheritableAttr {
// It indicates that the function has unknown or unautomatable
// transfer semantics.
def CFUnknownTransfer : InheritableAttr {
- let Spellings = [GNU<"cf_unknown_transfer">];
+ let Spellings = [Clang<"cf_unknown_transfer">];
let Subjects = SubjectList<[Function], ErrorDiag>;
let Documentation = [Undocumented];
}
def CFReturnsRetained : InheritableAttr {
- let Spellings = [GNU<"cf_returns_retained">];
+ let Spellings = [Clang<"cf_returns_retained">];
// let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
let Documentation = [Undocumented];
}
def CFReturnsNotRetained : InheritableAttr {
- let Spellings = [GNU<"cf_returns_not_retained">];
+ let Spellings = [Clang<"cf_returns_not_retained">];
// let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
let Documentation = [Undocumented];
}
def CFConsumed : InheritableParamAttr {
- let Spellings = [GNU<"cf_consumed">];
+ let Spellings = [Clang<"cf_consumed">];
let Subjects = SubjectList<[ParmVar]>;
let Documentation = [Undocumented];
}
@@ -760,7 +771,7 @@ def CFConsumed : InheritableParamAttr {
def Cleanup : InheritableAttr {
let Spellings = [GCC<"cleanup">];
let Args = [FunctionArgument<"FunctionDecl">];
- let Subjects = SubjectList<[Var]>;
+ let Subjects = SubjectList<[LocalVar]>;
let Documentation = [Undocumented];
}
@@ -788,8 +799,8 @@ def Constructor : InheritableAttr {
let Documentation = [Undocumented];
}
-// CUDA attributes are spelled __attribute__((attr)) or __declspec(__attr__).
-
+// CUDA attributes are spelled __attribute__((attr)) or __declspec(__attr__),
+// and they do not receive a [[]] spelling.
def CUDAConstant : InheritableAttr {
let Spellings = [GNU<"constant">, Declspec<"__constant__">];
let Subjects = SubjectList<[Var]>;
@@ -851,8 +862,7 @@ def CUDALaunchBounds : InheritableAttr {
let Spellings = [GNU<"launch_bounds">, Declspec<"__launch_bounds__">];
let Args = [ExprArgument<"MaxThreads">, ExprArgument<"MinBlocks", 1>];
let LangOpts = [CUDA];
- let Subjects = SubjectList<[ObjCMethod, FunctionLike], WarnDiag,
- "ExpectedFunctionOrMethod">;
+ let Subjects = SubjectList<[ObjCMethod, FunctionLike]>;
// An AST node is created for this attribute, but is not used by other parts
// of the compiler. However, this node needs to exist in the AST because
// non-LLVM backends may be relying on the attribute's presence.
@@ -874,11 +884,13 @@ def C11NoReturn : InheritableAttr {
}
def CXX11NoReturn : InheritableAttr {
- let Spellings = [CXX11<"","noreturn", 200809>];
+ let Spellings = [CXX11<"", "noreturn", 200809>];
let Subjects = SubjectList<[Function], ErrorDiag>;
let Documentation = [CXX11NoReturnDocs];
}
+// Similar to CUDA, OpenCL attributes do not receive a [[]] spelling because
+// the specification does not expose them with one currently.
def OpenCLKernel : InheritableAttr {
let Spellings = [Keyword<"__kernel">, Keyword<"kernel">];
let Subjects = SubjectList<[Function], ErrorDiag>;
@@ -904,8 +916,7 @@ def OpenCLAccess : Attr {
let Spellings = [Keyword<"__read_only">, Keyword<"read_only">,
Keyword<"__write_only">, Keyword<"write_only">,
Keyword<"__read_write">, Keyword<"read_write">];
- let Subjects = SubjectList<[ParmVar, TypedefName], ErrorDiag,
- "ExpectedParameterOrTypedef">;
+ let Subjects = SubjectList<[ParmVar, TypedefName], ErrorDiag>;
let Accessors = [Accessor<"isReadOnly", [Keyword<"__read_only">,
Keyword<"read_only">]>,
Accessor<"isReadWrite", [Keyword<"__read_write">,
@@ -957,7 +968,7 @@ def RenderScriptKernel : Attr {
def Deprecated : InheritableAttr {
let Spellings = [GCC<"deprecated">, Declspec<"deprecated">,
- CXX11<"","deprecated", 201309>];
+ CXX11<"","deprecated", 201309>, C2x<"", "deprecated">];
let Args = [StringArgument<"Message", 1>,
// An optional string argument that enables us to provide a
// Fix-It.
@@ -988,6 +999,9 @@ def AllocSize : InheritableAttr {
}
def EnableIf : InheritableAttr {
+ // Does not have a [[]] spelling because this attribute requires the ability
+ // to parse function arguments but the attribute is not written in the type
+ // position.
let Spellings = [GNU<"enable_if">];
let Subjects = SubjectList<[Function]>;
let Args = [ExprArgument<"Cond">, StringArgument<"Message">];
@@ -996,6 +1010,7 @@ def EnableIf : InheritableAttr {
}
def ExtVectorType : Attr {
+ // This is an OpenCL-related attribute and does not receive a [[]] spelling.
let Spellings = [GNU<"ext_vector_type">];
let Subjects = SubjectList<[TypedefName], ErrorDiag>;
let Args = [ExprArgument<"NumElements">];
@@ -1004,7 +1019,7 @@ def ExtVectorType : Attr {
}
def FallThrough : StmtAttr {
- let Spellings = [CXX11<"", "fallthrough", 201603>,
+ let Spellings = [CXX11<"", "fallthrough", 201603>, C2x<"", "fallthrough">,
CXX11<"clang", "fallthrough">];
// let Subjects = [NullStmt];
let Documentation = [FallthroughDocs];
@@ -1030,20 +1045,19 @@ def Final : InheritableAttr {
}
def MinSize : InheritableAttr {
- let Spellings = [GNU<"minsize">];
+ let Spellings = [Clang<"minsize">];
let Subjects = SubjectList<[Function, ObjCMethod], ErrorDiag>;
let Documentation = [Undocumented];
}
def FlagEnum : InheritableAttr {
- let Spellings = [GNU<"flag_enum">];
+ let Spellings = [Clang<"flag_enum">];
let Subjects = SubjectList<[Enum]>;
let Documentation = [FlagEnumDocs];
}
def EnumExtensibility : InheritableAttr {
- let Spellings = [GNU<"enum_extensibility">,
- CXX11<"clang", "enum_extensibility">];
+ let Spellings = [Clang<"enum_extensibility">];
let Subjects = SubjectList<[Enum]>;
let Args = [EnumArgument<"Extensibility", "Kind",
["closed", "open"], ["Closed", "Open"]>];
@@ -1060,16 +1074,14 @@ def Format : InheritableAttr {
let Spellings = [GCC<"format">];
let Args = [IdentifierArgument<"Type">, IntArgument<"FormatIdx">,
IntArgument<"FirstArg">];
- let Subjects = SubjectList<[ObjCMethod, Block, HasFunctionProto], WarnDiag,
- "ExpectedFunctionWithProtoType">;
+ let Subjects = SubjectList<[ObjCMethod, Block, HasFunctionProto]>;
let Documentation = [FormatDocs];
}
def FormatArg : InheritableAttr {
let Spellings = [GCC<"format_arg">];
let Args = [IntArgument<"FormatIdx">];
- let Subjects = SubjectList<[ObjCMethod, HasFunctionProto], WarnDiag,
- "ExpectedFunctionWithProtoType">;
+ let Subjects = SubjectList<[ObjCMethod, HasFunctionProto]>;
let Documentation = [Undocumented];
}
@@ -1088,9 +1100,8 @@ def Hot : InheritableAttr {
}
def IBAction : InheritableAttr {
- let Spellings = [GNU<"ibaction">];
- let Subjects = SubjectList<[ObjCInstanceMethod], WarnDiag,
- "ExpectedObjCInstanceMethod">;
+ let Spellings = [Clang<"ibaction">];
+ let Subjects = SubjectList<[ObjCInstanceMethod]>;
// An AST node is created for this attribute, but is not used by other parts
// of the compiler. However, this node needs to exist in the AST because
// external tools rely on it.
@@ -1098,13 +1109,13 @@ def IBAction : InheritableAttr {
}
def IBOutlet : InheritableAttr {
- let Spellings = [GNU<"iboutlet">];
+ let Spellings = [Clang<"iboutlet">];
// let Subjects = [ObjCIvar, ObjCProperty];
let Documentation = [Undocumented];
}
def IBOutletCollection : InheritableAttr {
- let Spellings = [GNU<"iboutletcollection">];
+ let Spellings = [Clang<"iboutletcollection">];
let Args = [TypeArgument<"Interface", 1>];
// let Subjects = [ObjCIvar, ObjCProperty];
let Documentation = [Undocumented];
@@ -1153,23 +1164,23 @@ def MSABI : InheritableAttr {
def MSP430Interrupt : InheritableAttr, TargetSpecificAttr<TargetMSP430> {
// NOTE: If you add any additional spellings, ARMInterrupt's, MipsInterrupt's
// and AnyX86Interrupt's spellings must match.
- let Spellings = [GNU<"interrupt">];
+ let Spellings = [GCC<"interrupt">];
let Args = [UnsignedArgument<"Number">];
let ParseKind = "Interrupt";
let HasCustomParsing = 1;
let Documentation = [Undocumented];
}
-def Mips16 : InheritableAttr, TargetSpecificAttr<TargetMips> {
+def Mips16 : InheritableAttr, TargetSpecificAttr<TargetMips32> {
let Spellings = [GCC<"mips16">];
let Subjects = SubjectList<[Function], ErrorDiag>;
let Documentation = [Undocumented];
}
-def MipsInterrupt : InheritableAttr, TargetSpecificAttr<TargetMips> {
+def MipsInterrupt : InheritableAttr, TargetSpecificAttr<TargetMips32> {
// NOTE: If you add any additional spellings, ARMInterrupt's,
// MSP430Interrupt's and AnyX86Interrupt's spellings must match.
- let Spellings = [GNU<"interrupt">];
+ let Spellings = [GCC<"interrupt">];
let Subjects = SubjectList<[Function]>;
let Args = [EnumArgument<"Interrupt", "InterruptType",
["vector=sw0", "vector=sw1", "vector=hw0",
@@ -1182,16 +1193,27 @@ def MipsInterrupt : InheritableAttr, TargetSpecificAttr<TargetMips> {
let Documentation = [MipsInterruptDocs];
}
-def MicroMips : InheritableAttr, TargetSpecificAttr<TargetMips> {
+def MicroMips : InheritableAttr, TargetSpecificAttr<TargetMips32> {
let Spellings = [GCC<"micromips">];
let Subjects = SubjectList<[Function], ErrorDiag>;
let Documentation = [MicroMipsDocs];
}
+def MipsLongCall : InheritableAttr, TargetSpecificAttr<TargetAnyMips> {
+ let Spellings = [GCC<"long_call">, GCC<"far">];
+ let Subjects = SubjectList<[Function]>;
+ let Documentation = [MipsLongCallStyleDocs];
+}
+
+def MipsShortCall : InheritableAttr, TargetSpecificAttr<TargetAnyMips> {
+ let Spellings = [GCC<"short_call">, GCC<"near">];
+ let Subjects = SubjectList<[Function]>;
+ let Documentation = [MipsShortCallStyleDocs];
+}
+
def Mode : Attr {
let Spellings = [GCC<"mode">];
- let Subjects = SubjectList<[Var, Enum, TypedefName, Field], ErrorDiag,
- "ExpectedVariableEnumFieldOrTypedef">;
+ let Subjects = SubjectList<[Var, Enum, TypedefName, Field], ErrorDiag>;
let Args = [IdentifierArgument<"Mode">];
let Documentation = [Undocumented];
}
@@ -1203,13 +1225,13 @@ def Naked : InheritableAttr {
}
def NeonPolyVectorType : TypeAttr {
- let Spellings = [GNU<"neon_polyvector_type">];
+ let Spellings = [Clang<"neon_polyvector_type">];
let Args = [IntArgument<"NumElements">];
let Documentation = [Undocumented];
}
def NeonVectorType : TypeAttr {
- let Spellings = [GNU<"neon_vector_type">];
+ let Spellings = [Clang<"neon_vector_type">];
let Args = [IntArgument<"NumElements">];
let Documentation = [Undocumented];
}
@@ -1221,8 +1243,7 @@ def ReturnsTwice : InheritableAttr {
}
def DisableTailCalls : InheritableAttr {
- let Spellings = [GNU<"disable_tail_calls">,
- CXX11<"clang", "disable_tail_calls">];
+ let Spellings = [Clang<"disable_tail_calls">];
let Subjects = SubjectList<[Function, ObjCMethod]>;
let Documentation = [DisableTailCallsDocs];
}
@@ -1241,19 +1262,18 @@ def NoCommon : InheritableAttr {
def NoDebug : InheritableAttr {
let Spellings = [GCC<"nodebug">];
- let Subjects = SubjectList<[FunctionLike, ObjCMethod, NonParmVar], WarnDiag,
- "ExpectedVariableOrFunction">;
+ let Subjects = SubjectList<[FunctionLike, ObjCMethod, NonParmVar]>;
let Documentation = [NoDebugDocs];
}
def NoDuplicate : InheritableAttr {
- let Spellings = [GNU<"noduplicate">, CXX11<"clang", "noduplicate">];
+ let Spellings = [Clang<"noduplicate">];
let Subjects = SubjectList<[Function]>;
let Documentation = [NoDuplicateDocs];
}
def Convergent : InheritableAttr {
- let Spellings = [GNU<"convergent">, CXX11<"clang", "convergent">];
+ let Spellings = [Clang<"convergent">];
let Subjects = SubjectList<[Function]>;
let Documentation = [ConvergentDocs];
}
@@ -1264,13 +1284,13 @@ def NoInline : InheritableAttr {
let Documentation = [Undocumented];
}
-def NoMips16 : InheritableAttr, TargetSpecificAttr<TargetMips> {
+def NoMips16 : InheritableAttr, TargetSpecificAttr<TargetMips32> {
let Spellings = [GCC<"nomips16">];
let Subjects = SubjectList<[Function], ErrorDiag>;
let Documentation = [Undocumented];
}
-def NoMicroMips : InheritableAttr, TargetSpecificAttr<TargetMips> {
+def NoMicroMips : InheritableAttr, TargetSpecificAttr<TargetMips32> {
let Spellings = [GCC<"nomicromips">];
let Subjects = SubjectList<[Function], ErrorDiag>;
let Documentation = [MicroMipsDocs];
@@ -1294,31 +1314,31 @@ def NoMicroMips : InheritableAttr, TargetSpecificAttr<TargetMips> {
// this should be rejected on non-kernels.
def AMDGPUFlatWorkGroupSize : InheritableAttr {
- let Spellings = [GNU<"amdgpu_flat_work_group_size">];
+ let Spellings = [Clang<"amdgpu_flat_work_group_size">];
let Args = [UnsignedArgument<"Min">, UnsignedArgument<"Max">];
let Documentation = [AMDGPUFlatWorkGroupSizeDocs];
- let Subjects = SubjectList<[Function], ErrorDiag, "ExpectedKernelFunction">;
+ let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">;
}
def AMDGPUWavesPerEU : InheritableAttr {
- let Spellings = [GNU<"amdgpu_waves_per_eu">];
+ let Spellings = [Clang<"amdgpu_waves_per_eu">];
let Args = [UnsignedArgument<"Min">, UnsignedArgument<"Max", 1>];
let Documentation = [AMDGPUWavesPerEUDocs];
- let Subjects = SubjectList<[Function], ErrorDiag, "ExpectedKernelFunction">;
+ let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">;
}
def AMDGPUNumSGPR : InheritableAttr {
- let Spellings = [GNU<"amdgpu_num_sgpr">];
+ let Spellings = [Clang<"amdgpu_num_sgpr">];
let Args = [UnsignedArgument<"NumSGPR">];
let Documentation = [AMDGPUNumSGPRNumVGPRDocs];
- let Subjects = SubjectList<[Function], ErrorDiag, "ExpectedKernelFunction">;
+ let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">;
}
def AMDGPUNumVGPR : InheritableAttr {
- let Spellings = [GNU<"amdgpu_num_vgpr">];
+ let Spellings = [Clang<"amdgpu_num_vgpr">];
let Args = [UnsignedArgument<"NumVGPR">];
let Documentation = [AMDGPUNumSGPRNumVGPRDocs];
- let Subjects = SubjectList<[Function], ErrorDiag, "ExpectedKernelFunction">;
+ let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">;
}
def NoSplitStack : InheritableAttr {
@@ -1330,7 +1350,7 @@ def NoSplitStack : InheritableAttr {
def NonNull : InheritableParamAttr {
let Spellings = [GCC<"nonnull">];
let Subjects = SubjectList<[ObjCMethod, HasFunctionProto, ParmVar], WarnDiag,
- "ExpectedFunctionMethodOrParameter">;
+ "functions, methods, and parameters">;
let Args = [VariadicUnsignedArgument<"Args">];
let AdditionalMembers =
[{bool isNonNull(unsigned idx) const {
@@ -1348,15 +1368,14 @@ def NonNull : InheritableParamAttr {
def ReturnsNonNull : InheritableAttr {
let Spellings = [GCC<"returns_nonnull">];
- let Subjects = SubjectList<[ObjCMethod, Function], WarnDiag,
- "ExpectedFunctionOrMethod">;
+ let Subjects = SubjectList<[ObjCMethod, Function]>;
let Documentation = [ReturnsNonNullDocs];
}
// pass_object_size(N) indicates that the parameter should have
// __builtin_object_size with Type=N evaluated on the parameter at the callsite.
def PassObjectSize : InheritableParamAttr {
- let Spellings = [GNU<"pass_object_size">];
+ let Spellings = [Clang<"pass_object_size">];
let Args = [IntArgument<"Type">];
let Subjects = SubjectList<[ParmVar]>;
let Documentation = [PassObjectSizeDocs];
@@ -1383,6 +1402,12 @@ def ObjCKindOf : TypeAttr {
let Documentation = [Undocumented];
}
+def NoEscape : Attr {
+ let Spellings = [Clang<"noescape">];
+ let Subjects = SubjectList<[ParmVar]>;
+ let Documentation = [NoEscapeDocs];
+}
+
def AssumeAligned : InheritableAttr {
let Spellings = [GCC<"assume_aligned">];
let Subjects = SubjectList<[ObjCMethod, Function]>;
@@ -1392,8 +1417,7 @@ def AssumeAligned : InheritableAttr {
def AllocAlign : InheritableAttr {
let Spellings = [GCC<"alloc_align">];
- let Subjects = SubjectList<[HasFunctionProto], WarnDiag,
- "ExpectedFunctionWithProtoType">;
+ let Subjects = SubjectList<[HasFunctionProto]>;
let Args = [IntArgument<"ParamIndex">];
let Documentation = [AllocAlignDocs];
}
@@ -1411,39 +1435,42 @@ def NoInstrumentFunction : InheritableAttr {
}
def NotTailCalled : InheritableAttr {
- let Spellings = [GNU<"not_tail_called">, CXX11<"clang", "not_tail_called">];
+ let Spellings = [Clang<"not_tail_called">];
let Subjects = SubjectList<[Function]>;
let Documentation = [NotTailCalledDocs];
}
def NoThrow : InheritableAttr {
let Spellings = [GCC<"nothrow">, Declspec<"nothrow">];
- let Documentation = [Undocumented];
+ let Subjects = SubjectList<[Function]>;
+ let Documentation = [NoThrowDocs];
}
def NvWeak : IgnoredAttr {
// No Declspec spelling of this attribute; the CUDA headers use
- // __attribute__((nv_weak)) unconditionally.
+ // __attribute__((nv_weak)) unconditionally. Does not receive an [[]]
+ // spelling because it is a CUDA attribute.
let Spellings = [GNU<"nv_weak">];
let LangOpts = [CUDA];
}
def ObjCBridge : InheritableAttr {
- let Spellings = [GNU<"objc_bridge">];
- let Subjects = SubjectList<[Record, TypedefName], ErrorDiag,
- "ExpectedStructOrUnionOrTypedef">;
+ let Spellings = [Clang<"objc_bridge">];
+ let Subjects = SubjectList<[Record, TypedefName], ErrorDiag>;
let Args = [IdentifierArgument<"BridgedType">];
let Documentation = [Undocumented];
}
def ObjCBridgeMutable : InheritableAttr {
- let Spellings = [GNU<"objc_bridge_mutable">];
+ let Spellings = [Clang<"objc_bridge_mutable">];
let Subjects = SubjectList<[Record], ErrorDiag>;
let Args = [IdentifierArgument<"BridgedType">];
let Documentation = [Undocumented];
}
def ObjCBridgeRelated : InheritableAttr {
+ // TODO: this attribute does not have a [[]] spelling because it requires
+ // custom parsing support.
let Spellings = [GNU<"objc_bridge_related">];
let Subjects = SubjectList<[Record], ErrorDiag>;
let Args = [IdentifierArgument<"RelatedClass">,
@@ -1454,43 +1481,43 @@ def ObjCBridgeRelated : InheritableAttr {
}
def NSReturnsRetained : InheritableAttr {
- let Spellings = [GNU<"ns_returns_retained">];
+ let Spellings = [Clang<"ns_returns_retained">];
// let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
let Documentation = [Undocumented];
}
def NSReturnsNotRetained : InheritableAttr {
- let Spellings = [GNU<"ns_returns_not_retained">];
+ let Spellings = [Clang<"ns_returns_not_retained">];
// let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
let Documentation = [Undocumented];
}
def NSReturnsAutoreleased : InheritableAttr {
- let Spellings = [GNU<"ns_returns_autoreleased">];
+ let Spellings = [Clang<"ns_returns_autoreleased">];
// let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
let Documentation = [Undocumented];
}
def NSConsumesSelf : InheritableAttr {
- let Spellings = [GNU<"ns_consumes_self">];
+ let Spellings = [Clang<"ns_consumes_self">];
let Subjects = SubjectList<[ObjCMethod]>;
let Documentation = [Undocumented];
}
def NSConsumed : InheritableParamAttr {
- let Spellings = [GNU<"ns_consumed">];
+ let Spellings = [Clang<"ns_consumed">];
let Subjects = SubjectList<[ParmVar]>;
let Documentation = [Undocumented];
}
def ObjCException : InheritableAttr {
- let Spellings = [GNU<"objc_exception">];
+ let Spellings = [Clang<"objc_exception">];
let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
let Documentation = [Undocumented];
}
def ObjCMethodFamily : InheritableAttr {
- let Spellings = [GNU<"objc_method_family">];
+ let Spellings = [Clang<"objc_method_family">];
let Subjects = SubjectList<[ObjCMethod], ErrorDiag>;
let Args = [EnumArgument<"Family", "FamilyKind",
["none", "alloc", "copy", "init", "mutableCopy", "new"],
@@ -1500,85 +1527,84 @@ def ObjCMethodFamily : InheritableAttr {
}
def ObjCNSObject : InheritableAttr {
- let Spellings = [GNU<"NSObject">];
+ let Spellings = [Clang<"NSObject">];
let Documentation = [Undocumented];
}
def ObjCIndependentClass : InheritableAttr {
- let Spellings = [GNU<"objc_independent_class">];
+ let Spellings = [Clang<"objc_independent_class">];
let Documentation = [Undocumented];
}
def ObjCPreciseLifetime : InheritableAttr {
- let Spellings = [GNU<"objc_precise_lifetime">];
+ let Spellings = [Clang<"objc_precise_lifetime">];
let Subjects = SubjectList<[Var], ErrorDiag>;
let Documentation = [Undocumented];
}
def ObjCReturnsInnerPointer : InheritableAttr {
- let Spellings = [GNU<"objc_returns_inner_pointer">];
+ let Spellings = [Clang<"objc_returns_inner_pointer">];
let Subjects = SubjectList<[ObjCMethod, ObjCProperty], ErrorDiag>;
let Documentation = [Undocumented];
}
def ObjCRequiresSuper : InheritableAttr {
- let Spellings = [GNU<"objc_requires_super">];
+ let Spellings = [Clang<"objc_requires_super">];
let Subjects = SubjectList<[ObjCMethod], ErrorDiag>;
let Documentation = [ObjCRequiresSuperDocs];
}
def ObjCRootClass : InheritableAttr {
- let Spellings = [GNU<"objc_root_class">];
+ let Spellings = [Clang<"objc_root_class">];
let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
let Documentation = [Undocumented];
}
def ObjCSubclassingRestricted : InheritableAttr {
- let Spellings = [GNU<"objc_subclassing_restricted">];
+ let Spellings = [Clang<"objc_subclassing_restricted">];
let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
let Documentation = [ObjCSubclassingRestrictedDocs];
}
def ObjCExplicitProtocolImpl : InheritableAttr {
- let Spellings = [GNU<"objc_protocol_requires_explicit_implementation">];
+ let Spellings = [Clang<"objc_protocol_requires_explicit_implementation">];
let Subjects = SubjectList<[ObjCProtocol], ErrorDiag>;
let Documentation = [Undocumented];
}
def ObjCDesignatedInitializer : Attr {
- let Spellings = [GNU<"objc_designated_initializer">];
- let Subjects = SubjectList<[ObjCInterfaceDeclInitMethod], ErrorDiag,
- "ExpectedObjCInterfaceDeclInitMethod">;
+ let Spellings = [Clang<"objc_designated_initializer">];
+ let Subjects = SubjectList<[ObjCInterfaceDeclInitMethod], ErrorDiag>;
let Documentation = [Undocumented];
}
def ObjCRuntimeName : Attr {
- let Spellings = [GNU<"objc_runtime_name">];
+ let Spellings = [Clang<"objc_runtime_name">];
let Subjects = SubjectList<[ObjCInterface, ObjCProtocol], ErrorDiag>;
let Args = [StringArgument<"MetadataName">];
let Documentation = [ObjCRuntimeNameDocs];
}
def ObjCRuntimeVisible : Attr {
- let Spellings = [GNU<"objc_runtime_visible">];
+ let Spellings = [Clang<"objc_runtime_visible">];
let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
let Documentation = [ObjCRuntimeVisibleDocs];
}
def ObjCBoxable : Attr {
- let Spellings = [GNU<"objc_boxable">];
- let Subjects = SubjectList<[Record], ErrorDiag, "ExpectedStructOrUnion">;
+ let Spellings = [Clang<"objc_boxable">];
+ let Subjects = SubjectList<[Record], ErrorDiag>;
let Documentation = [ObjCBoxableDocs];
}
def OptimizeNone : InheritableAttr {
- let Spellings = [GNU<"optnone">, CXX11<"clang", "optnone">];
+ let Spellings = [Clang<"optnone">];
let Subjects = SubjectList<[Function, ObjCMethod]>;
let Documentation = [OptnoneDocs];
}
def Overloadable : Attr {
- let Spellings = [GNU<"overloadable">];
+ let Spellings = [Clang<"overloadable">];
let Subjects = SubjectList<[Function], ErrorDiag>;
let Documentation = [OverloadableDocs];
}
@@ -1590,11 +1616,11 @@ def Override : InheritableAttr {
}
def Ownership : InheritableAttr {
- let Spellings = [GNU<"ownership_holds">, GNU<"ownership_returns">,
- GNU<"ownership_takes">];
- let Accessors = [Accessor<"isHolds", [GNU<"ownership_holds">]>,
- Accessor<"isReturns", [GNU<"ownership_returns">]>,
- Accessor<"isTakes", [GNU<"ownership_takes">]>];
+ let Spellings = [Clang<"ownership_holds">, Clang<"ownership_returns">,
+ Clang<"ownership_takes">];
+ let Accessors = [Accessor<"isHolds", [Clang<"ownership_holds">]>,
+ Accessor<"isReturns", [Clang<"ownership_returns">]>,
+ Accessor<"isTakes", [Clang<"ownership_takes">]>];
let AdditionalMembers = [{
enum OwnershipKind { Holds, Returns, Takes };
OwnershipKind getOwnKind() const {
@@ -1604,8 +1630,7 @@ def Ownership : InheritableAttr {
}
}];
let Args = [IdentifierArgument<"Module">, VariadicUnsignedArgument<"Args">];
- let Subjects = SubjectList<[HasFunctionProto], WarnDiag,
- "ExpectedFunctionWithProtoType">;
+ let Subjects = SubjectList<[HasFunctionProto]>;
let Documentation = [Undocumented];
}
@@ -1616,7 +1641,7 @@ def Packed : InheritableAttr {
}
def IntelOclBicc : InheritableAttr {
- let Spellings = [GNU<"intel_ocl_bicc">];
+ let Spellings = [Clang<"intel_ocl_bicc">];
// let Subjects = [Function, ObjCMethod];
let Documentation = [Undocumented];
}
@@ -1642,6 +1667,7 @@ def Regparm : TypeAttr {
}
def ReqdWorkGroupSize : InheritableAttr {
+ // Does not have a [[]] spelling because it is an OpenCL-related attribute.
let Spellings = [GNU<"reqd_work_group_size">];
let Args = [UnsignedArgument<"XDim">, UnsignedArgument<"YDim">,
UnsignedArgument<"ZDim">];
@@ -1650,15 +1676,14 @@ def ReqdWorkGroupSize : InheritableAttr {
}
def RequireConstantInit : InheritableAttr {
- let Spellings = [GNU<"require_constant_initialization">,
- CXX11<"clang", "require_constant_initialization">];
- let Subjects = SubjectList<[GlobalVar], ErrorDiag,
- "ExpectedStaticOrTLSVar">;
+ let Spellings = [Clang<"require_constant_initialization">];
+ let Subjects = SubjectList<[GlobalVar], ErrorDiag>;
let Documentation = [RequireConstantInitDocs];
let LangOpts = [CPlusPlus];
}
def WorkGroupSizeHint : InheritableAttr {
+ // Does not have a [[]] spelling because it is an OpenCL-related attribute.
let Spellings = [GNU<"work_group_size_hint">];
let Args = [UnsignedArgument<"XDim">,
UnsignedArgument<"YDim">,
@@ -1668,7 +1693,7 @@ def WorkGroupSizeHint : InheritableAttr {
}
def InitPriority : InheritableAttr {
- let Spellings = [GNU<"init_priority">];
+ let Spellings = [GCC<"init_priority">];
let Args = [UnsignedArgument<"Priority">];
let Subjects = SubjectList<[Var], ErrorDiag>;
let Documentation = [Undocumented];
@@ -1677,9 +1702,8 @@ def InitPriority : InheritableAttr {
def Section : InheritableAttr {
let Spellings = [GCC<"section">, Declspec<"allocate">];
let Args = [StringArgument<"Name">];
- let Subjects = SubjectList<[Function, GlobalVar,
- ObjCMethod, ObjCProperty], ErrorDiag,
- "ExpectedFunctionGlobalVarMethodOrProperty">;
+ let Subjects =
+ SubjectList<[ Function, GlobalVar, ObjCMethod, ObjCProperty ], ErrorDiag>;
let Documentation = [SectionDocs];
}
@@ -1687,8 +1711,7 @@ def PragmaClangBSSSection : InheritableAttr {
// This attribute has no spellings as it is only ever created implicitly.
let Spellings = [];
let Args = [StringArgument<"Name">];
- let Subjects = SubjectList<[GlobalVar], ErrorDiag,
- "ExpectedFunctionMethodOrGlobalVar">;
+ let Subjects = SubjectList<[GlobalVar], ErrorDiag>;
let Documentation = [Undocumented];
}
@@ -1696,8 +1719,7 @@ def PragmaClangDataSection : InheritableAttr {
// This attribute has no spellings as it is only ever created implicitly.
let Spellings = [];
let Args = [StringArgument<"Name">];
- let Subjects = SubjectList<[GlobalVar], ErrorDiag,
- "ExpectedFunctionMethodOrGlobalVar">;
+ let Subjects = SubjectList<[GlobalVar], ErrorDiag>;
let Documentation = [Undocumented];
}
@@ -1705,8 +1727,7 @@ def PragmaClangRodataSection : InheritableAttr {
// This attribute has no spellings as it is only ever created implicitly.
let Spellings = [];
let Args = [StringArgument<"Name">];
- let Subjects = SubjectList<[GlobalVar], ErrorDiag,
- "ExpectedFunctionMethodOrGlobalVar">;
+ let Subjects = SubjectList<[GlobalVar], ErrorDiag>;
let Documentation = [Undocumented];
}
@@ -1714,8 +1735,7 @@ def PragmaClangTextSection : InheritableAttr {
// This attribute has no spellings as it is only ever created implicitly.
let Spellings = [];
let Args = [StringArgument<"Name">];
- let Subjects = SubjectList<[Function], ErrorDiag,
- "ExpectedFunctionMethodOrGlobalVar">;
+ let Subjects = SubjectList<[Function], ErrorDiag>;
let Documentation = [Undocumented];
}
@@ -1734,23 +1754,23 @@ def StdCall : InheritableAttr {
}
def SwiftCall : InheritableAttr {
- let Spellings = [GCC<"swiftcall">];
+ let Spellings = [Clang<"swiftcall">];
// let Subjects = SubjectList<[Function]>;
let Documentation = [SwiftCallDocs];
}
def SwiftContext : ParameterABIAttr {
- let Spellings = [GCC<"swift_context">];
+ let Spellings = [Clang<"swift_context">];
let Documentation = [SwiftContextDocs];
}
def SwiftErrorResult : ParameterABIAttr {
- let Spellings = [GCC<"swift_error_result">];
+ let Spellings = [Clang<"swift_error_result">];
let Documentation = [SwiftErrorResultDocs];
}
def SwiftIndirectResult : ParameterABIAttr {
- let Spellings = [GCC<"swift_indirect_result">];
+ let Spellings = [Clang<"swift_indirect_result">];
let Documentation = [SwiftIndirectResultDocs];
}
@@ -1774,25 +1794,25 @@ def ThisCall : InheritableAttr {
}
def VectorCall : InheritableAttr {
- let Spellings = [GNU<"vectorcall">, Keyword<"__vectorcall">,
+ let Spellings = [Clang<"vectorcall">, Keyword<"__vectorcall">,
Keyword<"_vectorcall">];
// let Subjects = [Function, ObjCMethod];
let Documentation = [VectorCallDocs];
}
def Pascal : InheritableAttr {
- let Spellings = [GNU<"pascal">, Keyword<"__pascal">, Keyword<"_pascal">];
+ let Spellings = [Clang<"pascal">, Keyword<"__pascal">, Keyword<"_pascal">];
// let Subjects = [Function, ObjCMethod];
let Documentation = [Undocumented];
}
def PreserveMost : InheritableAttr {
- let Spellings = [GNU<"preserve_most">];
+ let Spellings = [Clang<"preserve_most">];
let Documentation = [PreserveMostDocs];
}
def PreserveAll : InheritableAttr {
- let Spellings = [GNU<"preserve_all">];
+ let Spellings = [Clang<"preserve_all">];
let Documentation = [PreserveAllDocs];
}
@@ -1853,7 +1873,7 @@ def TransparentUnion : InheritableAttr {
}
def Unavailable : InheritableAttr {
- let Spellings = [GNU<"unavailable">];
+ let Spellings = [Clang<"unavailable">];
let Args = [StringArgument<"Message", 1>,
EnumArgument<"ImplicitReason", "ImplicitReason",
["", "", "", ""],
@@ -1867,6 +1887,9 @@ def Unavailable : InheritableAttr {
}
def DiagnoseIf : InheritableAttr {
+ // Does not have a [[]] spelling because this attribute requires the ability
+ // to parse function arguments but the attribute is not written in the type
+ // position.
let Spellings = [GNU<"diagnose_if">];
let Subjects = SubjectList<[Function, ObjCMethod, ObjCProperty]>;
let Args = [ExprArgument<"Cond">, StringArgument<"Message">,
@@ -1887,35 +1910,35 @@ def DiagnoseIf : InheritableAttr {
}
def ArcWeakrefUnavailable : InheritableAttr {
- let Spellings = [GNU<"objc_arc_weak_reference_unavailable">];
+ let Spellings = [Clang<"objc_arc_weak_reference_unavailable">];
let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
let Documentation = [Undocumented];
}
def ObjCGC : TypeAttr {
- let Spellings = [GNU<"objc_gc">];
+ let Spellings = [Clang<"objc_gc">];
let Args = [IdentifierArgument<"Kind">];
let Documentation = [Undocumented];
}
def ObjCOwnership : InheritableAttr {
- let Spellings = [GNU<"objc_ownership">];
+ let Spellings = [Clang<"objc_ownership">];
let Args = [IdentifierArgument<"Kind">];
let ASTNode = 0;
let Documentation = [Undocumented];
}
def ObjCRequiresPropertyDefs : InheritableAttr {
- let Spellings = [GNU<"objc_requires_property_definitions">];
+ let Spellings = [Clang<"objc_requires_property_definitions">];
let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
let Documentation = [Undocumented];
}
def Unused : InheritableAttr {
- let Spellings = [CXX11<"", "maybe_unused", 201603>, GCC<"unused">];
+ let Spellings = [CXX11<"", "maybe_unused", 201603>, GCC<"unused">,
+ C2x<"", "maybe_unused">];
let Subjects = SubjectList<[Var, ObjCIvar, Type, Enum, EnumConstant, Label,
- Field, ObjCMethod, FunctionLike], WarnDiag,
- "ExpectedForMaybeUnused">;
+ Field, ObjCMethod, FunctionLike]>;
let Documentation = [WarnMaybeUnusedDocs];
}
@@ -1927,7 +1950,7 @@ def Used : InheritableAttr {
def Uuid : InheritableAttr {
let Spellings = [Declspec<"uuid">, Microsoft<"uuid">];
let Args = [StringArgument<"Guid">];
- let Subjects = SubjectList<[Record, Enum], WarnDiag, "ExpectedEnumOrClass">;
+ let Subjects = SubjectList<[Record, Enum]>;
// FIXME: Allow expressing logical AND for LangOpts. Our condition should be:
// CPlusPlus && (MicrosoftExt || Borland)
let LangOpts = [MicrosoftExt, Borland];
@@ -1941,6 +1964,7 @@ def VectorSize : TypeAttr {
}
def VecTypeHint : InheritableAttr {
+ // Does not have a [[]] spelling because it is an OpenCL-related attribute.
let Spellings = [GNU<"vec_type_hint">];
let Args = [TypeArgument<"TypeHint">];
let Subjects = SubjectList<[Function], ErrorDiag>;
@@ -1959,7 +1983,7 @@ def Visibility : InheritableAttr {
def TypeVisibility : InheritableAttr {
let Clone = 0;
- let Spellings = [GNU<"type_visibility">, CXX11<"clang", "type_visibility">];
+ let Spellings = [Clang<"type_visibility">];
let Args = [EnumArgument<"Visibility", "VisibilityType",
["default", "hidden", "internal", "protected"],
["Default", "Hidden", "Hidden", "Protected"]>];
@@ -1968,23 +1992,22 @@ def TypeVisibility : InheritableAttr {
}
def VecReturn : InheritableAttr {
- let Spellings = [GNU<"vecreturn">];
+ let Spellings = [Clang<"vecreturn">];
let Subjects = SubjectList<[CXXRecord], ErrorDiag>;
let Documentation = [Undocumented];
}
def WarnUnused : InheritableAttr {
- let Spellings = [GNU<"warn_unused">];
+ let Spellings = [GCC<"warn_unused">];
let Subjects = SubjectList<[Record]>;
let Documentation = [Undocumented];
}
def WarnUnusedResult : InheritableAttr {
- let Spellings = [CXX11<"", "nodiscard", 201603>,
+ let Spellings = [CXX11<"", "nodiscard", 201603>, C2x<"", "nodiscard">,
CXX11<"clang", "warn_unused_result">,
GCC<"warn_unused_result">];
- let Subjects = SubjectList<[ObjCMethod, Enum, CXXRecord, FunctionLike],
- WarnDiag, "ExpectedFunctionMethodEnumOrClass">;
+ let Subjects = SubjectList<[ObjCMethod, Enum, Record, FunctionLike]>;
let Documentation = [WarnUnusedResultsDocs];
}
@@ -1995,7 +2018,7 @@ def Weak : InheritableAttr {
}
def WeakImport : InheritableAttr {
- let Spellings = [GNU<"weak_import">];
+ let Spellings = [Clang<"weak_import">];
let Documentation = [Undocumented];
}
@@ -2008,7 +2031,7 @@ def WeakRef : InheritableAttr {
}
def LTOVisibilityPublic : InheritableAttr {
- let Spellings = [CXX11<"clang", "lto_visibility_public">];
+ let Spellings = [Clang<"lto_visibility_public">];
let Subjects = SubjectList<[Record]>;
let Documentation = [LTOVisibilityDocs];
}
@@ -2016,11 +2039,11 @@ def LTOVisibilityPublic : InheritableAttr {
def AnyX86Interrupt : InheritableAttr, TargetSpecificAttr<TargetAnyX86> {
// NOTE: If you add any additional spellings, ARMInterrupt's,
// MSP430Interrupt's and MipsInterrupt's spellings must match.
- let Spellings = [GNU<"interrupt">];
+ let Spellings = [GCC<"interrupt">];
let Subjects = SubjectList<[HasFunctionProto]>;
let ParseKind = "Interrupt";
let HasCustomParsing = 1;
- let Documentation = [AnyX86InterruptDocs];
+ let Documentation = [Undocumented];
}
def AnyX86NoCallerSavedRegisters : InheritableAttr,
@@ -2029,19 +2052,18 @@ def AnyX86NoCallerSavedRegisters : InheritableAttr,
let Documentation = [AnyX86NoCallerSavedRegistersDocs];
}
-def X86ForceAlignArgPointer : InheritableAttr, TargetSpecificAttr<TargetX86> {
- let Spellings = [GNU<"force_align_arg_pointer">];
+def X86ForceAlignArgPointer : InheritableAttr, TargetSpecificAttr<TargetAnyX86> {
+ let Spellings = [GCC<"force_align_arg_pointer">];
// Technically, this appertains to a FunctionDecl, but the target-specific
// code silently allows anything function-like (such as typedefs or function
// pointers), but does not apply the attribute to them.
- let Documentation = [Undocumented];
+ let Documentation = [X86ForceAlignArgPointerDocs];
}
def NoSanitize : InheritableAttr {
- let Spellings = [GNU<"no_sanitize">, CXX11<"clang", "no_sanitize">];
+ let Spellings = [Clang<"no_sanitize">];
let Args = [VariadicStringArgument<"Sanitizers">];
- let Subjects = SubjectList<[Function, ObjCMethod, GlobalVar], ErrorDiag,
- "ExpectedFunctionMethodOrGlobalVar">;
+ let Subjects = SubjectList<[Function, ObjCMethod, GlobalVar], ErrorDiag>;
let Documentation = [NoSanitizeDocs];
let AdditionalMembers = [{
SanitizerMask getMask() const {
@@ -2062,27 +2084,28 @@ def NoSanitizeSpecific : InheritableAttr {
let Spellings = [GCC<"no_address_safety_analysis">,
GCC<"no_sanitize_address">,
GCC<"no_sanitize_thread">,
- GNU<"no_sanitize_memory">];
- let Subjects = SubjectList<[Function, GlobalVar], ErrorDiag,
- "ExpectedFunctionOrGlobalVar">;
+ Clang<"no_sanitize_memory">];
+ let Subjects = SubjectList<[Function, GlobalVar], ErrorDiag>;
let Documentation = [NoSanitizeAddressDocs, NoSanitizeThreadDocs,
NoSanitizeMemoryDocs];
let ASTNode = 0;
}
// C/C++ Thread safety attributes (e.g. for deadlock, data race checking)
-
+// Not all of these attributes will be given a [[]] spelling. The attributes
+// which require access to function parameter names cannot use the [[]] spelling
+// because they are not written in the type position. Some attributes are given
+// an updated captability-based name and the older name will only be supported
+// under the GNU-style spelling.
def GuardedVar : InheritableAttr {
- let Spellings = [GNU<"guarded_var">];
- let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
- "ExpectedFieldOrGlobalVar">;
+ let Spellings = [Clang<"guarded_var">];
+ let Subjects = SubjectList<[Field, SharedVar]>;
let Documentation = [Undocumented];
}
def PtGuardedVar : InheritableAttr {
- let Spellings = [GNU<"pt_guarded_var">];
- let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
- "ExpectedFieldOrGlobalVar">;
+ let Spellings = [Clang<"pt_guarded_var">];
+ let Subjects = SubjectList<[Field, SharedVar]>;
let Documentation = [Undocumented];
}
@@ -2094,21 +2117,17 @@ def Lockable : InheritableAttr {
}
def ScopedLockable : InheritableAttr {
- let Spellings = [GNU<"scoped_lockable">];
+ let Spellings = [Clang<"scoped_lockable">];
let Subjects = SubjectList<[Record]>;
let Documentation = [Undocumented];
}
def Capability : InheritableAttr {
- let Spellings = [GNU<"capability">, CXX11<"clang", "capability">,
- GNU<"shared_capability">,
- CXX11<"clang", "shared_capability">];
- let Subjects = SubjectList<[Record, TypedefName], ErrorDiag,
- "ExpectedStructOrUnionOrTypedef">;
+ let Spellings = [Clang<"capability">, Clang<"shared_capability">];
+ let Subjects = SubjectList<[Record, TypedefName], ErrorDiag>;
let Args = [StringArgument<"Name">];
let Accessors = [Accessor<"isShared",
- [GNU<"shared_capability">,
- CXX11<"clang","shared_capability">]>];
+ [Clang<"shared_capability">]>];
let Documentation = [Undocumented];
let AdditionalMembers = [{
bool isMutex() const { return getName().equals_lower("mutex"); }
@@ -2117,27 +2136,22 @@ def Capability : InheritableAttr {
}
def AssertCapability : InheritableAttr {
- let Spellings = [GNU<"assert_capability">,
- CXX11<"clang", "assert_capability">,
- GNU<"assert_shared_capability">,
- CXX11<"clang", "assert_shared_capability">];
+ let Spellings = [Clang<"assert_capability">,
+ Clang<"assert_shared_capability">];
let Subjects = SubjectList<[Function]>;
let LateParsed = 1;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
let DuplicatesAllowedWhileMerging = 1;
- let Args = [ExprArgument<"Expr">];
+ let Args = [VariadicExprArgument<"Args">];
let Accessors = [Accessor<"isShared",
- [GNU<"assert_shared_capability">,
- CXX11<"clang", "assert_shared_capability">]>];
+ [Clang<"assert_shared_capability">]>];
let Documentation = [AssertCapabilityDocs];
}
def AcquireCapability : InheritableAttr {
- let Spellings = [GNU<"acquire_capability">,
- CXX11<"clang", "acquire_capability">,
- GNU<"acquire_shared_capability">,
- CXX11<"clang", "acquire_shared_capability">,
+ let Spellings = [Clang<"acquire_capability">,
+ Clang<"acquire_shared_capability">,
GNU<"exclusive_lock_function">,
GNU<"shared_lock_function">];
let Subjects = SubjectList<[Function]>;
@@ -2147,17 +2161,14 @@ def AcquireCapability : InheritableAttr {
let DuplicatesAllowedWhileMerging = 1;
let Args = [VariadicExprArgument<"Args">];
let Accessors = [Accessor<"isShared",
- [GNU<"acquire_shared_capability">,
- CXX11<"clang", "acquire_shared_capability">,
+ [Clang<"acquire_shared_capability">,
GNU<"shared_lock_function">]>];
let Documentation = [AcquireCapabilityDocs];
}
def TryAcquireCapability : InheritableAttr {
- let Spellings = [GNU<"try_acquire_capability">,
- CXX11<"clang", "try_acquire_capability">,
- GNU<"try_acquire_shared_capability">,
- CXX11<"clang", "try_acquire_shared_capability">];
+ let Spellings = [Clang<"try_acquire_capability">,
+ Clang<"try_acquire_shared_capability">];
let Subjects = SubjectList<[Function],
ErrorDiag>;
let LateParsed = 1;
@@ -2166,19 +2177,15 @@ def TryAcquireCapability : InheritableAttr {
let DuplicatesAllowedWhileMerging = 1;
let Args = [ExprArgument<"SuccessValue">, VariadicExprArgument<"Args">];
let Accessors = [Accessor<"isShared",
- [GNU<"try_acquire_shared_capability">,
- CXX11<"clang", "try_acquire_shared_capability">]>];
+ [Clang<"try_acquire_shared_capability">]>];
let Documentation = [TryAcquireCapabilityDocs];
}
def ReleaseCapability : InheritableAttr {
- let Spellings = [GNU<"release_capability">,
- CXX11<"clang", "release_capability">,
- GNU<"release_shared_capability">,
- CXX11<"clang", "release_shared_capability">,
- GNU<"release_generic_capability">,
- CXX11<"clang", "release_generic_capability">,
- GNU<"unlock_function">];
+ let Spellings = [Clang<"release_capability">,
+ Clang<"release_shared_capability">,
+ Clang<"release_generic_capability">,
+ Clang<"unlock_function">];
let Subjects = SubjectList<[Function]>;
let LateParsed = 1;
let TemplateDependent = 1;
@@ -2186,36 +2193,31 @@ def ReleaseCapability : InheritableAttr {
let DuplicatesAllowedWhileMerging = 1;
let Args = [VariadicExprArgument<"Args">];
let Accessors = [Accessor<"isShared",
- [GNU<"release_shared_capability">,
- CXX11<"clang", "release_shared_capability">]>,
+ [Clang<"release_shared_capability">]>,
Accessor<"isGeneric",
- [GNU<"release_generic_capability">,
- CXX11<"clang", "release_generic_capability">,
- GNU<"unlock_function">]>];
+ [Clang<"release_generic_capability">,
+ Clang<"unlock_function">]>];
let Documentation = [ReleaseCapabilityDocs];
}
def RequiresCapability : InheritableAttr {
- let Spellings = [GNU<"requires_capability">,
- CXX11<"clang", "requires_capability">,
- GNU<"exclusive_locks_required">,
- GNU<"requires_shared_capability">,
- CXX11<"clang", "requires_shared_capability">,
- GNU<"shared_locks_required">];
+ let Spellings = [Clang<"requires_capability">,
+ Clang<"exclusive_locks_required">,
+ Clang<"requires_shared_capability">,
+ Clang<"shared_locks_required">];
let Args = [VariadicExprArgument<"Args">];
let LateParsed = 1;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
let DuplicatesAllowedWhileMerging = 1;
let Subjects = SubjectList<[Function]>;
- let Accessors = [Accessor<"isShared", [GNU<"requires_shared_capability">,
- GNU<"shared_locks_required">,
- CXX11<"clang","requires_shared_capability">]>];
+ let Accessors = [Accessor<"isShared", [Clang<"requires_shared_capability">,
+ Clang<"shared_locks_required">]>];
let Documentation = [Undocumented];
}
def NoThreadSafetyAnalysis : InheritableAttr {
- let Spellings = [GNU<"no_thread_safety_analysis">];
+ let Spellings = [Clang<"no_thread_safety_analysis">];
let Subjects = SubjectList<[Function]>;
let Documentation = [Undocumented];
}
@@ -2227,8 +2229,7 @@ def GuardedBy : InheritableAttr {
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
let DuplicatesAllowedWhileMerging = 1;
- let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
- "ExpectedFieldOrGlobalVar">;
+ let Subjects = SubjectList<[Field, SharedVar]>;
let Documentation = [Undocumented];
}
@@ -2239,8 +2240,7 @@ def PtGuardedBy : InheritableAttr {
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
let DuplicatesAllowedWhileMerging = 1;
- let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
- "ExpectedFieldOrGlobalVar">;
+ let Subjects = SubjectList<[Field, SharedVar]>;
let Documentation = [Undocumented];
}
@@ -2251,8 +2251,7 @@ def AcquiredAfter : InheritableAttr {
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
let DuplicatesAllowedWhileMerging = 1;
- let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
- "ExpectedFieldOrGlobalVar">;
+ let Subjects = SubjectList<[Field, SharedVar]>;
let Documentation = [Undocumented];
}
@@ -2263,8 +2262,7 @@ def AcquiredBefore : InheritableAttr {
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
let DuplicatesAllowedWhileMerging = 1;
- let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
- "ExpectedFieldOrGlobalVar">;
+ let Subjects = SubjectList<[Field, SharedVar]>;
let Documentation = [Undocumented];
}
@@ -2340,7 +2338,7 @@ def LocksExcluded : InheritableAttr {
// C/C++ consumed attributes.
def Consumable : InheritableAttr {
- let Spellings = [GNU<"consumable">];
+ let Spellings = [Clang<"consumable">];
let Subjects = SubjectList<[CXXRecord]>;
let Args = [EnumArgument<"DefaultState", "ConsumedState",
["unknown", "consumed", "unconsumed"],
@@ -2349,19 +2347,19 @@ def Consumable : InheritableAttr {
}
def ConsumableAutoCast : InheritableAttr {
- let Spellings = [GNU<"consumable_auto_cast_state">];
+ let Spellings = [Clang<"consumable_auto_cast_state">];
let Subjects = SubjectList<[CXXRecord]>;
let Documentation = [Undocumented];
}
def ConsumableSetOnRead : InheritableAttr {
- let Spellings = [GNU<"consumable_set_state_on_read">];
+ let Spellings = [Clang<"consumable_set_state_on_read">];
let Subjects = SubjectList<[CXXRecord]>;
let Documentation = [Undocumented];
}
def CallableWhen : InheritableAttr {
- let Spellings = [GNU<"callable_when">];
+ let Spellings = [Clang<"callable_when">];
let Subjects = SubjectList<[CXXMethod]>;
let Args = [VariadicEnumArgument<"CallableStates", "ConsumedState",
["unknown", "consumed", "unconsumed"],
@@ -2370,7 +2368,7 @@ def CallableWhen : InheritableAttr {
}
def ParamTypestate : InheritableAttr {
- let Spellings = [GNU<"param_typestate">];
+ let Spellings = [Clang<"param_typestate">];
let Subjects = SubjectList<[ParmVar]>;
let Args = [EnumArgument<"ParamState", "ConsumedState",
["unknown", "consumed", "unconsumed"],
@@ -2379,7 +2377,7 @@ def ParamTypestate : InheritableAttr {
}
def ReturnTypestate : InheritableAttr {
- let Spellings = [GNU<"return_typestate">];
+ let Spellings = [Clang<"return_typestate">];
let Subjects = SubjectList<[Function, ParmVar]>;
let Args = [EnumArgument<"State", "ConsumedState",
["unknown", "consumed", "unconsumed"],
@@ -2388,7 +2386,7 @@ def ReturnTypestate : InheritableAttr {
}
def SetTypestate : InheritableAttr {
- let Spellings = [GNU<"set_typestate">];
+ let Spellings = [Clang<"set_typestate">];
let Subjects = SubjectList<[CXXMethod]>;
let Args = [EnumArgument<"NewState", "ConsumedState",
["unknown", "consumed", "unconsumed"],
@@ -2397,7 +2395,7 @@ def SetTypestate : InheritableAttr {
}
def TestTypestate : InheritableAttr {
- let Spellings = [GNU<"test_typestate">];
+ let Spellings = [Clang<"test_typestate">];
let Subjects = SubjectList<[CXXMethod]>;
let Args = [EnumArgument<"TestState", "ConsumedState",
["consumed", "unconsumed"],
@@ -2673,6 +2671,14 @@ def OMPCaptureNoInit : InheritableAttr {
let Documentation = [Undocumented];
}
+def OMPCaptureKind : Attr {
+ // This attribute has no spellings as it is only ever created implicitly.
+ let Spellings = [];
+ let SemaHandler = 0;
+ let Args = [UnsignedArgument<"CaptureKind">];
+ let Documentation = [Undocumented];
+}
+
def OMPDeclareSimdDecl : Attr {
let Spellings = [Pragma<"omp", "declare simd">];
let Subjects = SubjectList<[Function]>;
@@ -2759,7 +2765,7 @@ def OMPDeclareTargetDecl : Attr {
}
def InternalLinkage : InheritableAttr {
- let Spellings = [GNU<"internal_linkage">, CXX11<"clang", "internal_linkage">];
+ let Spellings = [Clang<"internal_linkage">];
let Subjects = SubjectList<[Var, Function, CXXRecord]>;
let Documentation = [InternalLinkageDocs];
}
diff --git a/include/clang/Basic/AttrDocs.td b/include/clang/Basic/AttrDocs.td
index 567c7a3a53b0..ecff329c4ccb 100644
--- a/include/clang/Basic/AttrDocs.td
+++ b/include/clang/Basic/AttrDocs.td
@@ -7,6 +7,24 @@
//
//===---------------------------------------------------------------------===//
+// To test that the documentation builds cleanly, you must run clang-tblgen to
+// convert the .td file into a .rst file, and then run sphinx to convert the
+// .rst file into an HTML file. After completing testing, you should revert the
+// generated .rst file so that the modified version does not get checked in to
+// version control.
+//
+// To run clang-tblgen to generate the .rst file:
+// clang-tblgen -gen-attr-docs -I <root>/llvm/tools/clang/include
+// <root>/llvm/tools/clang/include/clang/Basic/Attr.td -o
+// <root>/llvm/tools/clang/docs/AttributeReference.rst
+//
+// To run sphinx to generate the .html files (note that sphinx-build must be
+// available on the PATH):
+// Windows (from within the clang\docs directory):
+// make.bat html
+// Non-Windows (from within the clang\docs directory):
+// make -f Makefile.sphinx html
+
def GlobalDocumentation {
code Intro =[{..
-------------------------------------------------------------------
@@ -112,6 +130,50 @@ members, and static locals.
}];
}
+def NoEscapeDocs : Documentation {
+ let Category = DocCatVariable;
+ let Content = [{
+``noescape`` placed on a function parameter of a pointer type is used to inform
+the compiler that the pointer cannot escape: that is, no reference to the object
+the pointer points to that is derived from the parameter value will survive
+after the function returns. Users are responsible for making sure parameters
+annotated with ``noescape`` do not actuallly escape.
+
+For example:
+
+.. code-block:: c
+
+ int *gp;
+
+ void nonescapingFunc(__attribute__((noescape)) int *p) {
+ *p += 100; // OK.
+ }
+
+ void escapingFunc(__attribute__((noescape)) int *p) {
+ gp = p; // Not OK.
+ }
+
+Additionally, when the parameter is a `block pointer
+<https://clang.llvm.org/docs/BlockLanguageSpec.html>`, the same restriction
+applies to copies of the block. For example:
+
+.. code-block:: c
+
+ typedef void (^BlockTy)();
+ BlockTy g0, g1;
+
+ void nonescapingFunc(__attribute__((noescape)) BlockTy block) {
+ block(); // OK.
+ }
+
+ void escapingFunc(__attribute__((noescape)) BlockTy block) {
+ g0 = block; // Not OK.
+ g1 = Block_copy(block); // Not OK either.
+ }
+
+ }];
+}
+
def CarriesDependencyDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
@@ -1231,6 +1293,7 @@ Here is an example:
def ARMInterruptDocs : Documentation {
let Category = DocCatFunction;
+ let Heading = "interrupt (ARM)";
let Content = [{
Clang supports the GNU style ``__attribute__((interrupt("TYPE")))`` attribute on
ARM targets. This attribute may be attached to a function definition and
@@ -1272,6 +1335,7 @@ The semantics are as follows:
def MipsInterruptDocs : Documentation {
let Category = DocCatFunction;
+ let Heading = "interrupt (MIPS)";
let Content = [{
Clang supports the GNU style ``__attribute__((interrupt("ARGUMENT")))`` attribute on
MIPS targets. This attribute may be attached to a function definition and instructs
@@ -1323,8 +1387,52 @@ on the command line.
}];
}
+def MipsLongCallStyleDocs : Documentation {
+ let Category = DocCatFunction;
+ let Heading = "long_call (gnu::long_call, gnu::far)";
+ let Content = [{
+Clang supports the ``__attribute__((long_call))``, ``__attribute__((far))``,
+and ``__attribute__((near))`` attributes on MIPS targets. These attributes may
+only be added to function declarations and change the code generated
+by the compiler when directly calling the function. The ``near`` attribute
+allows calls to the function to be made using the ``jal`` instruction, which
+requires the function to be located in the same naturally aligned 256MB
+segment as the caller. The ``long_call`` and ``far`` attributes are synonyms
+and require the use of a different call sequence that works regardless
+of the distance between the functions.
+
+These attributes have no effect for position-independent code.
+
+These attributes take priority over command line switches such
+as ``-mlong-calls`` and ``-mno-long-calls``.
+ }];
+}
+
+def MipsShortCallStyleDocs : Documentation {
+ let Category = DocCatFunction;
+ let Heading = "short_call (gnu::short_call, gnu::near)";
+ let Content = [{
+Clang supports the ``__attribute__((long_call))``, ``__attribute__((far))``,
+``__attribute__((short__call))``, and ``__attribute__((near))`` attributes
+on MIPS targets. These attributes may only be added to function declarations
+and change the code generated by the compiler when directly calling
+the function. The ``short_call`` and ``near`` attributes are synonyms and
+allow calls to the function to be made using the ``jal`` instruction, which
+requires the function to be located in the same naturally aligned 256MB segment
+as the caller. The ``long_call`` and ``far`` attributes are synonyms and
+require the use of a different call sequence that works regardless
+of the distance between the functions.
+
+These attributes have no effect for position-independent code.
+
+These attributes take priority over command line switches such
+as ``-mlong-calls`` and ``-mno-long-calls``.
+ }];
+}
+
def AVRInterruptDocs : Documentation {
let Category = DocCatFunction;
+ let Heading = "interrupt (AVR)";
let Content = [{
Clang supports the GNU style ``__attribute__((interrupt))`` attribute on
AVR targets. This attribute may be attached to a function definition and instructs
@@ -2625,6 +2733,18 @@ Marking virtual functions as ``not_tail_called`` is an error:
}];
}
+def NoThrowDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+Clang supports the GNU style ``__attribute__((nothrow))`` and Microsoft style
+``__declspec(nothrow)`` attribute as an equivilent of `noexcept` on function
+declarations. This attribute informs the compiler that the annotated function
+does not throw an exception. This prevents exception-unwinding. This attribute
+is particularly useful on functions in the C Standard Library that are
+guaranteed to not throw an exception.
+ }];
+}
+
def InternalLinkageDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
@@ -2673,59 +2793,6 @@ Marking virtual functions as ``disable_tail_calls`` is legal.
}];
}
-def AnyX86InterruptDocs : Documentation {
- let Category = DocCatFunction;
- let Content = [{
-Clang supports the GNU style ``__attribute__((interrupt))`` attribute on
-x86/x86-64 targets.The compiler generates function entry and exit sequences
-suitable for use in an interrupt handler when this attribute is present.
-The 'IRET' instruction, instead of the 'RET' instruction, is used to return
-from interrupt or exception handlers. All registers, except for the EFLAGS
-register which is restored by the 'IRET' instruction, are preserved by the
-compiler.
-
-Any interruptible-without-stack-switch code must be compiled with
--mno-red-zone since interrupt handlers can and will, because of the
-hardware design, touch the red zone.
-
-1. interrupt handler must be declared with a mandatory pointer argument:
-
- .. code-block:: c
-
- struct interrupt_frame
- {
- uword_t ip;
- uword_t cs;
- uword_t flags;
- uword_t sp;
- uword_t ss;
- };
-
- __attribute__ ((interrupt))
- void f (struct interrupt_frame *frame) {
- ...
- }
-
-2. exception handler:
-
- The exception handler is very similar to the interrupt handler with
- a different mandatory function signature:
-
- .. code-block:: c
-
- __attribute__ ((interrupt))
- void f (struct interrupt_frame *frame, uword_t error_code) {
- ...
- }
-
- and compiler pops 'ERROR_CODE' off stack before the 'IRET' instruction.
-
- The exception handler should only be used for exceptions which push an
- error code and all other exceptions must use the interrupt handler.
- The system will crash if the wrong handler is used.
- }];
-}
-
def AnyX86NoCallerSavedRegistersDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
@@ -2760,6 +2827,31 @@ For example:
}];
}
+def X86ForceAlignArgPointerDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+Use this attribute to force stack alignment.
+
+Legacy x86 code uses 4-byte stack alignment. Newer aligned SSE instructions
+(like 'movaps') that work with the stack require operands to be 16-byte aligned.
+This attribute realigns the stack in the function prologue to make sure the
+stack can be used with SSE instructions.
+
+Note that the x86_64 ABI forces 16-byte stack alignment at the call site.
+Because of this, 'force_align_arg_pointer' is not needed on x86_64, except in
+rare cases where the caller does not align the stack properly (e.g. flow
+jumps from i386 arch code).
+
+ .. code-block:: c
+
+ __attribute__ ((force_align_arg_pointer))
+ void f () {
+ ...
+ }
+
+ }];
+}
+
def SwiftCallDocs : Documentation {
let Category = DocCatVariable;
let Content = [{
diff --git a/include/clang/Basic/Attributes.h b/include/clang/Basic/Attributes.h
index ea9e28ae681a..c651abacd482 100644
--- a/include/clang/Basic/Attributes.h
+++ b/include/clang/Basic/Attributes.h
@@ -26,6 +26,8 @@ enum class AttrSyntax {
Microsoft,
// Is the identifier known as a C++-style attribute?
CXX,
+ // Is the identifier known as a C-style attribute?
+ C,
// Is the identifier known as a pragma attribute?
Pragma
};
diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def
index 1ddb9beaf913..3d4deb5ed306 100644
--- a/include/clang/Basic/Builtins.def
+++ b/include/clang/Basic/Builtins.def
@@ -103,9 +103,9 @@
#endif
// Standard libc/libm functions:
-BUILTIN(__builtin_atan2 , "ddd" , "Fnc")
-BUILTIN(__builtin_atan2f, "fff" , "Fnc")
-BUILTIN(__builtin_atan2l, "LdLdLd", "Fnc")
+BUILTIN(__builtin_atan2 , "ddd" , "Fne")
+BUILTIN(__builtin_atan2f, "fff" , "Fne")
+BUILTIN(__builtin_atan2l, "LdLdLd", "Fne")
BUILTIN(__builtin_abs , "ii" , "ncF")
BUILTIN(__builtin_copysign, "ddd", "ncF")
BUILTIN(__builtin_copysignf, "fff", "ncF")
@@ -113,9 +113,9 @@ BUILTIN(__builtin_copysignl, "LdLdLd", "ncF")
BUILTIN(__builtin_fabs , "dd" , "ncF")
BUILTIN(__builtin_fabsf, "ff" , "ncF")
BUILTIN(__builtin_fabsl, "LdLd", "ncF")
-BUILTIN(__builtin_fmod , "ddd" , "Fnc")
-BUILTIN(__builtin_fmodf, "fff" , "Fnc")
-BUILTIN(__builtin_fmodl, "LdLdLd", "Fnc")
+BUILTIN(__builtin_fmod , "ddd" , "Fne")
+BUILTIN(__builtin_fmodf, "fff" , "Fne")
+BUILTIN(__builtin_fmodl, "LdLdLd", "Fne")
BUILTIN(__builtin_frexp , "ddi*" , "Fn")
BUILTIN(__builtin_frexpf, "ffi*" , "Fn")
BUILTIN(__builtin_frexpl, "LdLdi*", "Fn")
@@ -127,9 +127,9 @@ BUILTIN(__builtin_inff , "f" , "nc")
BUILTIN(__builtin_infl , "Ld" , "nc")
BUILTIN(__builtin_labs , "LiLi" , "Fnc")
BUILTIN(__builtin_llabs, "LLiLLi", "Fnc")
-BUILTIN(__builtin_ldexp , "ddi" , "Fnc")
-BUILTIN(__builtin_ldexpf, "ffi" , "Fnc")
-BUILTIN(__builtin_ldexpl, "LdLdi", "Fnc")
+BUILTIN(__builtin_ldexp , "ddi" , "Fne")
+BUILTIN(__builtin_ldexpf, "ffi" , "Fne")
+BUILTIN(__builtin_ldexpl, "LdLdi", "Fne")
BUILTIN(__builtin_modf , "ddd*" , "Fn")
BUILTIN(__builtin_modff, "fff*" , "Fn")
BUILTIN(__builtin_modfl, "LdLdLd*", "Fn")
@@ -142,119 +142,119 @@ BUILTIN(__builtin_nansl, "LdcC*", "ncF")
BUILTIN(__builtin_powi , "ddi" , "Fnc")
BUILTIN(__builtin_powif, "ffi" , "Fnc")
BUILTIN(__builtin_powil, "LdLdi", "Fnc")
-BUILTIN(__builtin_pow , "ddd" , "Fnc")
-BUILTIN(__builtin_powf, "fff" , "Fnc")
-BUILTIN(__builtin_powl, "LdLdLd", "Fnc")
+BUILTIN(__builtin_pow , "ddd" , "Fne")
+BUILTIN(__builtin_powf, "fff" , "Fne")
+BUILTIN(__builtin_powl, "LdLdLd", "Fne")
// Standard unary libc/libm functions with double/float/long double variants:
-BUILTIN(__builtin_acos , "dd" , "Fnc")
-BUILTIN(__builtin_acosf, "ff" , "Fnc")
-BUILTIN(__builtin_acosl, "LdLd", "Fnc")
-BUILTIN(__builtin_acosh , "dd" , "Fnc")
-BUILTIN(__builtin_acoshf, "ff" , "Fnc")
-BUILTIN(__builtin_acoshl, "LdLd", "Fnc")
-BUILTIN(__builtin_asin , "dd" , "Fnc")
-BUILTIN(__builtin_asinf, "ff" , "Fnc")
-BUILTIN(__builtin_asinl, "LdLd", "Fnc")
-BUILTIN(__builtin_asinh , "dd" , "Fnc")
-BUILTIN(__builtin_asinhf, "ff" , "Fnc")
-BUILTIN(__builtin_asinhl, "LdLd", "Fnc")
-BUILTIN(__builtin_atan , "dd" , "Fnc")
-BUILTIN(__builtin_atanf, "ff" , "Fnc")
-BUILTIN(__builtin_atanl, "LdLd", "Fnc")
-BUILTIN(__builtin_atanh , "dd", "Fnc")
-BUILTIN(__builtin_atanhf, "ff", "Fnc")
-BUILTIN(__builtin_atanhl, "LdLd", "Fnc")
+BUILTIN(__builtin_acos , "dd" , "Fne")
+BUILTIN(__builtin_acosf, "ff" , "Fne")
+BUILTIN(__builtin_acosl, "LdLd", "Fne")
+BUILTIN(__builtin_acosh , "dd" , "Fne")
+BUILTIN(__builtin_acoshf, "ff" , "Fne")
+BUILTIN(__builtin_acoshl, "LdLd", "Fne")
+BUILTIN(__builtin_asin , "dd" , "Fne")
+BUILTIN(__builtin_asinf, "ff" , "Fne")
+BUILTIN(__builtin_asinl, "LdLd", "Fne")
+BUILTIN(__builtin_asinh , "dd" , "Fne")
+BUILTIN(__builtin_asinhf, "ff" , "Fne")
+BUILTIN(__builtin_asinhl, "LdLd", "Fne")
+BUILTIN(__builtin_atan , "dd" , "Fne")
+BUILTIN(__builtin_atanf, "ff" , "Fne")
+BUILTIN(__builtin_atanl, "LdLd", "Fne")
+BUILTIN(__builtin_atanh , "dd", "Fne")
+BUILTIN(__builtin_atanhf, "ff", "Fne")
+BUILTIN(__builtin_atanhl, "LdLd", "Fne")
BUILTIN(__builtin_cbrt , "dd", "Fnc")
BUILTIN(__builtin_cbrtf, "ff", "Fnc")
BUILTIN(__builtin_cbrtl, "LdLd", "Fnc")
BUILTIN(__builtin_ceil , "dd" , "Fnc")
BUILTIN(__builtin_ceilf, "ff" , "Fnc")
BUILTIN(__builtin_ceill, "LdLd", "Fnc")
-BUILTIN(__builtin_cos , "dd" , "Fnc")
-BUILTIN(__builtin_cosf, "ff" , "Fnc")
-BUILTIN(__builtin_cosh , "dd" , "Fnc")
-BUILTIN(__builtin_coshf, "ff" , "Fnc")
-BUILTIN(__builtin_coshl, "LdLd", "Fnc")
-BUILTIN(__builtin_cosl, "LdLd", "Fnc")
-BUILTIN(__builtin_erf , "dd", "Fnc")
-BUILTIN(__builtin_erff, "ff", "Fnc")
-BUILTIN(__builtin_erfl, "LdLd", "Fnc")
-BUILTIN(__builtin_erfc , "dd", "Fnc")
-BUILTIN(__builtin_erfcf, "ff", "Fnc")
-BUILTIN(__builtin_erfcl, "LdLd", "Fnc")
-BUILTIN(__builtin_exp , "dd" , "Fnc")
-BUILTIN(__builtin_expf, "ff" , "Fnc")
-BUILTIN(__builtin_expl, "LdLd", "Fnc")
-BUILTIN(__builtin_exp2 , "dd" , "Fnc")
-BUILTIN(__builtin_exp2f, "ff" , "Fnc")
-BUILTIN(__builtin_exp2l, "LdLd", "Fnc")
-BUILTIN(__builtin_expm1 , "dd", "Fnc")
-BUILTIN(__builtin_expm1f, "ff", "Fnc")
-BUILTIN(__builtin_expm1l, "LdLd", "Fnc")
-BUILTIN(__builtin_fdim, "ddd", "Fnc")
-BUILTIN(__builtin_fdimf, "fff", "Fnc")
-BUILTIN(__builtin_fdiml, "LdLdLd", "Fnc")
+BUILTIN(__builtin_cos , "dd" , "Fne")
+BUILTIN(__builtin_cosf, "ff" , "Fne")
+BUILTIN(__builtin_cosh , "dd" , "Fne")
+BUILTIN(__builtin_coshf, "ff" , "Fne")
+BUILTIN(__builtin_coshl, "LdLd", "Fne")
+BUILTIN(__builtin_cosl, "LdLd", "Fne")
+BUILTIN(__builtin_erf , "dd", "Fne")
+BUILTIN(__builtin_erff, "ff", "Fne")
+BUILTIN(__builtin_erfl, "LdLd", "Fne")
+BUILTIN(__builtin_erfc , "dd", "Fne")
+BUILTIN(__builtin_erfcf, "ff", "Fne")
+BUILTIN(__builtin_erfcl, "LdLd", "Fne")
+BUILTIN(__builtin_exp , "dd" , "Fne")
+BUILTIN(__builtin_expf, "ff" , "Fne")
+BUILTIN(__builtin_expl, "LdLd", "Fne")
+BUILTIN(__builtin_exp2 , "dd" , "Fne")
+BUILTIN(__builtin_exp2f, "ff" , "Fne")
+BUILTIN(__builtin_exp2l, "LdLd", "Fne")
+BUILTIN(__builtin_expm1 , "dd", "Fne")
+BUILTIN(__builtin_expm1f, "ff", "Fne")
+BUILTIN(__builtin_expm1l, "LdLd", "Fne")
+BUILTIN(__builtin_fdim, "ddd", "Fne")
+BUILTIN(__builtin_fdimf, "fff", "Fne")
+BUILTIN(__builtin_fdiml, "LdLdLd", "Fne")
BUILTIN(__builtin_floor , "dd" , "Fnc")
BUILTIN(__builtin_floorf, "ff" , "Fnc")
BUILTIN(__builtin_floorl, "LdLd", "Fnc")
-BUILTIN(__builtin_fma, "dddd", "Fnc")
-BUILTIN(__builtin_fmaf, "ffff", "Fnc")
-BUILTIN(__builtin_fmal, "LdLdLdLd", "Fnc")
+BUILTIN(__builtin_fma, "dddd", "Fne")
+BUILTIN(__builtin_fmaf, "ffff", "Fne")
+BUILTIN(__builtin_fmal, "LdLdLdLd", "Fne")
BUILTIN(__builtin_fmax, "ddd", "Fnc")
BUILTIN(__builtin_fmaxf, "fff", "Fnc")
BUILTIN(__builtin_fmaxl, "LdLdLd", "Fnc")
BUILTIN(__builtin_fmin, "ddd", "Fnc")
BUILTIN(__builtin_fminf, "fff", "Fnc")
BUILTIN(__builtin_fminl, "LdLdLd", "Fnc")
-BUILTIN(__builtin_hypot , "ddd" , "Fnc")
-BUILTIN(__builtin_hypotf, "fff" , "Fnc")
-BUILTIN(__builtin_hypotl, "LdLdLd", "Fnc")
-BUILTIN(__builtin_ilogb , "id", "Fnc")
-BUILTIN(__builtin_ilogbf, "if", "Fnc")
-BUILTIN(__builtin_ilogbl, "iLd", "Fnc")
-BUILTIN(__builtin_lgamma , "dd", "Fnc")
-BUILTIN(__builtin_lgammaf, "ff", "Fnc")
-BUILTIN(__builtin_lgammal, "LdLd", "Fnc")
-BUILTIN(__builtin_llrint, "LLid", "Fnc")
-BUILTIN(__builtin_llrintf, "LLif", "Fnc")
-BUILTIN(__builtin_llrintl, "LLiLd", "Fnc")
-BUILTIN(__builtin_llround , "LLid", "Fnc")
-BUILTIN(__builtin_llroundf, "LLif", "Fnc")
-BUILTIN(__builtin_llroundl, "LLiLd", "Fnc")
-BUILTIN(__builtin_log , "dd" , "Fnc")
-BUILTIN(__builtin_log10 , "dd" , "Fnc")
-BUILTIN(__builtin_log10f, "ff" , "Fnc")
-BUILTIN(__builtin_log10l, "LdLd", "Fnc")
-BUILTIN(__builtin_log1p , "dd" , "Fnc")
-BUILTIN(__builtin_log1pf, "ff" , "Fnc")
-BUILTIN(__builtin_log1pl, "LdLd", "Fnc")
-BUILTIN(__builtin_log2, "dd" , "Fnc")
-BUILTIN(__builtin_log2f, "ff" , "Fnc")
-BUILTIN(__builtin_log2l, "LdLd" , "Fnc")
-BUILTIN(__builtin_logb , "dd", "Fnc")
-BUILTIN(__builtin_logbf, "ff", "Fnc")
-BUILTIN(__builtin_logbl, "LdLd", "Fnc")
-BUILTIN(__builtin_logf, "ff" , "Fnc")
-BUILTIN(__builtin_logl, "LdLd", "Fnc")
-BUILTIN(__builtin_lrint , "Lid", "Fnc")
-BUILTIN(__builtin_lrintf, "Lif", "Fnc")
-BUILTIN(__builtin_lrintl, "LiLd", "Fnc")
-BUILTIN(__builtin_lround , "Lid", "Fnc")
-BUILTIN(__builtin_lroundf, "Lif", "Fnc")
-BUILTIN(__builtin_lroundl, "LiLd", "Fnc")
+BUILTIN(__builtin_hypot , "ddd" , "Fne")
+BUILTIN(__builtin_hypotf, "fff" , "Fne")
+BUILTIN(__builtin_hypotl, "LdLdLd", "Fne")
+BUILTIN(__builtin_ilogb , "id", "Fne")
+BUILTIN(__builtin_ilogbf, "if", "Fne")
+BUILTIN(__builtin_ilogbl, "iLd", "Fne")
+BUILTIN(__builtin_lgamma , "dd", "Fn")
+BUILTIN(__builtin_lgammaf, "ff", "Fn")
+BUILTIN(__builtin_lgammal, "LdLd", "Fn")
+BUILTIN(__builtin_llrint, "LLid", "Fne")
+BUILTIN(__builtin_llrintf, "LLif", "Fne")
+BUILTIN(__builtin_llrintl, "LLiLd", "Fne")
+BUILTIN(__builtin_llround , "LLid", "Fne")
+BUILTIN(__builtin_llroundf, "LLif", "Fne")
+BUILTIN(__builtin_llroundl, "LLiLd", "Fne")
+BUILTIN(__builtin_log , "dd" , "Fne")
+BUILTIN(__builtin_log10 , "dd" , "Fne")
+BUILTIN(__builtin_log10f, "ff" , "Fne")
+BUILTIN(__builtin_log10l, "LdLd", "Fne")
+BUILTIN(__builtin_log1p , "dd" , "Fne")
+BUILTIN(__builtin_log1pf, "ff" , "Fne")
+BUILTIN(__builtin_log1pl, "LdLd", "Fne")
+BUILTIN(__builtin_log2, "dd" , "Fne")
+BUILTIN(__builtin_log2f, "ff" , "Fne")
+BUILTIN(__builtin_log2l, "LdLd" , "Fne")
+BUILTIN(__builtin_logb , "dd", "Fne")
+BUILTIN(__builtin_logbf, "ff", "Fne")
+BUILTIN(__builtin_logbl, "LdLd", "Fne")
+BUILTIN(__builtin_logf, "ff" , "Fne")
+BUILTIN(__builtin_logl, "LdLd", "Fne")
+BUILTIN(__builtin_lrint , "Lid", "Fne")
+BUILTIN(__builtin_lrintf, "Lif", "Fne")
+BUILTIN(__builtin_lrintl, "LiLd", "Fne")
+BUILTIN(__builtin_lround , "Lid", "Fne")
+BUILTIN(__builtin_lroundf, "Lif", "Fne")
+BUILTIN(__builtin_lroundl, "LiLd", "Fne")
BUILTIN(__builtin_nearbyint , "dd", "Fnc")
BUILTIN(__builtin_nearbyintf, "ff", "Fnc")
BUILTIN(__builtin_nearbyintl, "LdLd", "Fnc")
-BUILTIN(__builtin_nextafter , "ddd", "Fnc")
-BUILTIN(__builtin_nextafterf, "fff", "Fnc")
-BUILTIN(__builtin_nextafterl, "LdLdLd", "Fnc")
-BUILTIN(__builtin_nexttoward , "ddLd", "Fnc")
-BUILTIN(__builtin_nexttowardf, "ffLd", "Fnc")
-BUILTIN(__builtin_nexttowardl, "LdLdLd", "Fnc")
-BUILTIN(__builtin_remainder , "ddd", "Fnc")
-BUILTIN(__builtin_remainderf, "fff", "Fnc")
-BUILTIN(__builtin_remainderl, "LdLdLd", "Fnc")
+BUILTIN(__builtin_nextafter , "ddd", "Fne")
+BUILTIN(__builtin_nextafterf, "fff", "Fne")
+BUILTIN(__builtin_nextafterl, "LdLdLd", "Fne")
+BUILTIN(__builtin_nexttoward , "ddLd", "Fne")
+BUILTIN(__builtin_nexttowardf, "ffLd", "Fne")
+BUILTIN(__builtin_nexttowardl, "LdLdLd", "Fne")
+BUILTIN(__builtin_remainder , "ddd", "Fne")
+BUILTIN(__builtin_remainderf, "fff", "Fne")
+BUILTIN(__builtin_remainderl, "LdLdLd", "Fne")
BUILTIN(__builtin_remquo , "dddi*", "Fn")
BUILTIN(__builtin_remquof, "fffi*", "Fn")
BUILTIN(__builtin_remquol, "LdLdLdi*", "Fn")
@@ -264,101 +264,101 @@ BUILTIN(__builtin_rintl, "LdLd", "Fnc")
BUILTIN(__builtin_round, "dd" , "Fnc")
BUILTIN(__builtin_roundf, "ff" , "Fnc")
BUILTIN(__builtin_roundl, "LdLd" , "Fnc")
-BUILTIN(__builtin_scalbln , "ddLi", "Fnc")
-BUILTIN(__builtin_scalblnf, "ffLi", "Fnc")
-BUILTIN(__builtin_scalblnl, "LdLdLi", "Fnc")
-BUILTIN(__builtin_scalbn , "ddi", "Fnc")
-BUILTIN(__builtin_scalbnf, "ffi", "Fnc")
-BUILTIN(__builtin_scalbnl, "LdLdi", "Fnc")
-BUILTIN(__builtin_sin , "dd" , "Fnc")
-BUILTIN(__builtin_sinf, "ff" , "Fnc")
-BUILTIN(__builtin_sinh , "dd" , "Fnc")
-BUILTIN(__builtin_sinhf, "ff" , "Fnc")
-BUILTIN(__builtin_sinhl, "LdLd", "Fnc")
-BUILTIN(__builtin_sinl, "LdLd", "Fnc")
-BUILTIN(__builtin_sqrt , "dd" , "Fnc")
-BUILTIN(__builtin_sqrtf, "ff" , "Fnc")
-BUILTIN(__builtin_sqrtl, "LdLd", "Fnc")
-BUILTIN(__builtin_tan , "dd" , "Fnc")
-BUILTIN(__builtin_tanf, "ff" , "Fnc")
-BUILTIN(__builtin_tanh , "dd" , "Fnc")
-BUILTIN(__builtin_tanhf, "ff" , "Fnc")
-BUILTIN(__builtin_tanhl, "LdLd", "Fnc")
-BUILTIN(__builtin_tanl, "LdLd", "Fnc")
-BUILTIN(__builtin_tgamma , "dd", "Fnc")
-BUILTIN(__builtin_tgammaf, "ff", "Fnc")
-BUILTIN(__builtin_tgammal, "LdLd", "Fnc")
+BUILTIN(__builtin_scalbln , "ddLi", "Fne")
+BUILTIN(__builtin_scalblnf, "ffLi", "Fne")
+BUILTIN(__builtin_scalblnl, "LdLdLi", "Fne")
+BUILTIN(__builtin_scalbn , "ddi", "Fne")
+BUILTIN(__builtin_scalbnf, "ffi", "Fne")
+BUILTIN(__builtin_scalbnl, "LdLdi", "Fne")
+BUILTIN(__builtin_sin , "dd" , "Fne")
+BUILTIN(__builtin_sinf, "ff" , "Fne")
+BUILTIN(__builtin_sinh , "dd" , "Fne")
+BUILTIN(__builtin_sinhf, "ff" , "Fne")
+BUILTIN(__builtin_sinhl, "LdLd", "Fne")
+BUILTIN(__builtin_sinl, "LdLd", "Fne")
+BUILTIN(__builtin_sqrt , "dd" , "Fne")
+BUILTIN(__builtin_sqrtf, "ff" , "Fne")
+BUILTIN(__builtin_sqrtl, "LdLd", "Fne")
+BUILTIN(__builtin_tan , "dd" , "Fne")
+BUILTIN(__builtin_tanf, "ff" , "Fne")
+BUILTIN(__builtin_tanh , "dd" , "Fne")
+BUILTIN(__builtin_tanhf, "ff" , "Fne")
+BUILTIN(__builtin_tanhl, "LdLd", "Fne")
+BUILTIN(__builtin_tanl, "LdLd", "Fne")
+BUILTIN(__builtin_tgamma , "dd", "Fne")
+BUILTIN(__builtin_tgammaf, "ff", "Fne")
+BUILTIN(__builtin_tgammal, "LdLd", "Fne")
BUILTIN(__builtin_trunc , "dd", "Fnc")
BUILTIN(__builtin_truncf, "ff", "Fnc")
BUILTIN(__builtin_truncl, "LdLd", "Fnc")
// C99 complex builtins
-BUILTIN(__builtin_cabs, "dXd", "Fnc")
-BUILTIN(__builtin_cabsf, "fXf", "Fnc")
-BUILTIN(__builtin_cabsl, "LdXLd", "Fnc")
-BUILTIN(__builtin_cacos, "XdXd", "Fnc")
-BUILTIN(__builtin_cacosf, "XfXf", "Fnc")
-BUILTIN(__builtin_cacosh, "XdXd", "Fnc")
-BUILTIN(__builtin_cacoshf, "XfXf", "Fnc")
-BUILTIN(__builtin_cacoshl, "XLdXLd", "Fnc")
-BUILTIN(__builtin_cacosl, "XLdXLd", "Fnc")
-BUILTIN(__builtin_carg, "dXd", "Fnc")
-BUILTIN(__builtin_cargf, "fXf", "Fnc")
-BUILTIN(__builtin_cargl, "LdXLd", "Fnc")
-BUILTIN(__builtin_casin, "XdXd", "Fnc")
-BUILTIN(__builtin_casinf, "XfXf", "Fnc")
-BUILTIN(__builtin_casinh, "XdXd", "Fnc")
-BUILTIN(__builtin_casinhf, "XfXf", "Fnc")
-BUILTIN(__builtin_casinhl, "XLdXLd", "Fnc")
-BUILTIN(__builtin_casinl, "XLdXLd", "Fnc")
-BUILTIN(__builtin_catan, "XdXd", "Fnc")
-BUILTIN(__builtin_catanf, "XfXf", "Fnc")
-BUILTIN(__builtin_catanh, "XdXd", "Fnc")
-BUILTIN(__builtin_catanhf, "XfXf", "Fnc")
-BUILTIN(__builtin_catanhl, "XLdXLd", "Fnc")
-BUILTIN(__builtin_catanl, "XLdXLd", "Fnc")
-BUILTIN(__builtin_ccos, "XdXd", "Fnc")
-BUILTIN(__builtin_ccosf, "XfXf", "Fnc")
-BUILTIN(__builtin_ccosl, "XLdXLd", "Fnc")
-BUILTIN(__builtin_ccosh, "XdXd", "Fnc")
-BUILTIN(__builtin_ccoshf, "XfXf", "Fnc")
-BUILTIN(__builtin_ccoshl, "XLdXLd", "Fnc")
-BUILTIN(__builtin_cexp, "XdXd", "Fnc")
-BUILTIN(__builtin_cexpf, "XfXf", "Fnc")
-BUILTIN(__builtin_cexpl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_cabs, "dXd", "Fne")
+BUILTIN(__builtin_cabsf, "fXf", "Fne")
+BUILTIN(__builtin_cabsl, "LdXLd", "Fne")
+BUILTIN(__builtin_cacos, "XdXd", "Fne")
+BUILTIN(__builtin_cacosf, "XfXf", "Fne")
+BUILTIN(__builtin_cacosh, "XdXd", "Fne")
+BUILTIN(__builtin_cacoshf, "XfXf", "Fne")
+BUILTIN(__builtin_cacoshl, "XLdXLd", "Fne")
+BUILTIN(__builtin_cacosl, "XLdXLd", "Fne")
+BUILTIN(__builtin_carg, "dXd", "Fne")
+BUILTIN(__builtin_cargf, "fXf", "Fne")
+BUILTIN(__builtin_cargl, "LdXLd", "Fne")
+BUILTIN(__builtin_casin, "XdXd", "Fne")
+BUILTIN(__builtin_casinf, "XfXf", "Fne")
+BUILTIN(__builtin_casinh, "XdXd", "Fne")
+BUILTIN(__builtin_casinhf, "XfXf", "Fne")
+BUILTIN(__builtin_casinhl, "XLdXLd", "Fne")
+BUILTIN(__builtin_casinl, "XLdXLd", "Fne")
+BUILTIN(__builtin_catan, "XdXd", "Fne")
+BUILTIN(__builtin_catanf, "XfXf", "Fne")
+BUILTIN(__builtin_catanh, "XdXd", "Fne")
+BUILTIN(__builtin_catanhf, "XfXf", "Fne")
+BUILTIN(__builtin_catanhl, "XLdXLd", "Fne")
+BUILTIN(__builtin_catanl, "XLdXLd", "Fne")
+BUILTIN(__builtin_ccos, "XdXd", "Fne")
+BUILTIN(__builtin_ccosf, "XfXf", "Fne")
+BUILTIN(__builtin_ccosl, "XLdXLd", "Fne")
+BUILTIN(__builtin_ccosh, "XdXd", "Fne")
+BUILTIN(__builtin_ccoshf, "XfXf", "Fne")
+BUILTIN(__builtin_ccoshl, "XLdXLd", "Fne")
+BUILTIN(__builtin_cexp, "XdXd", "Fne")
+BUILTIN(__builtin_cexpf, "XfXf", "Fne")
+BUILTIN(__builtin_cexpl, "XLdXLd", "Fne")
BUILTIN(__builtin_cimag, "dXd", "Fnc")
BUILTIN(__builtin_cimagf, "fXf", "Fnc")
BUILTIN(__builtin_cimagl, "LdXLd", "Fnc")
BUILTIN(__builtin_conj, "XdXd", "Fnc")
BUILTIN(__builtin_conjf, "XfXf", "Fnc")
BUILTIN(__builtin_conjl, "XLdXLd", "Fnc")
-BUILTIN(__builtin_clog, "XdXd", "Fnc")
-BUILTIN(__builtin_clogf, "XfXf", "Fnc")
-BUILTIN(__builtin_clogl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_clog, "XdXd", "Fne")
+BUILTIN(__builtin_clogf, "XfXf", "Fne")
+BUILTIN(__builtin_clogl, "XLdXLd", "Fne")
BUILTIN(__builtin_cproj, "XdXd", "Fnc")
BUILTIN(__builtin_cprojf, "XfXf", "Fnc")
BUILTIN(__builtin_cprojl, "XLdXLd", "Fnc")
-BUILTIN(__builtin_cpow, "XdXdXd", "Fnc")
-BUILTIN(__builtin_cpowf, "XfXfXf", "Fnc")
-BUILTIN(__builtin_cpowl, "XLdXLdXLd", "Fnc")
+BUILTIN(__builtin_cpow, "XdXdXd", "Fne")
+BUILTIN(__builtin_cpowf, "XfXfXf", "Fne")
+BUILTIN(__builtin_cpowl, "XLdXLdXLd", "Fne")
BUILTIN(__builtin_creal, "dXd", "Fnc")
BUILTIN(__builtin_crealf, "fXf", "Fnc")
BUILTIN(__builtin_creall, "LdXLd", "Fnc")
-BUILTIN(__builtin_csin, "XdXd", "Fnc")
-BUILTIN(__builtin_csinf, "XfXf", "Fnc")
-BUILTIN(__builtin_csinl, "XLdXLd", "Fnc")
-BUILTIN(__builtin_csinh, "XdXd", "Fnc")
-BUILTIN(__builtin_csinhf, "XfXf", "Fnc")
-BUILTIN(__builtin_csinhl, "XLdXLd", "Fnc")
-BUILTIN(__builtin_csqrt, "XdXd", "Fnc")
-BUILTIN(__builtin_csqrtf, "XfXf", "Fnc")
-BUILTIN(__builtin_csqrtl, "XLdXLd", "Fnc")
-BUILTIN(__builtin_ctan, "XdXd", "Fnc")
-BUILTIN(__builtin_ctanf, "XfXf", "Fnc")
-BUILTIN(__builtin_ctanl, "XLdXLd", "Fnc")
-BUILTIN(__builtin_ctanh, "XdXd", "Fnc")
-BUILTIN(__builtin_ctanhf, "XfXf", "Fnc")
-BUILTIN(__builtin_ctanhl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_csin, "XdXd", "Fne")
+BUILTIN(__builtin_csinf, "XfXf", "Fne")
+BUILTIN(__builtin_csinl, "XLdXLd", "Fne")
+BUILTIN(__builtin_csinh, "XdXd", "Fne")
+BUILTIN(__builtin_csinhf, "XfXf", "Fne")
+BUILTIN(__builtin_csinhl, "XLdXLd", "Fne")
+BUILTIN(__builtin_csqrt, "XdXd", "Fne")
+BUILTIN(__builtin_csqrtf, "XfXf", "Fne")
+BUILTIN(__builtin_csqrtl, "XLdXLd", "Fne")
+BUILTIN(__builtin_ctan, "XdXd", "Fne")
+BUILTIN(__builtin_ctanf, "XfXf", "Fne")
+BUILTIN(__builtin_ctanl, "XLdXLd", "Fne")
+BUILTIN(__builtin_ctanh, "XdXd", "Fne")
+BUILTIN(__builtin_ctanhf, "XfXf", "Fne")
+BUILTIN(__builtin_ctanhl, "XLdXLd", "Fne")
// FP Comparisons.
BUILTIN(__builtin_isgreater , "i.", "Fnc")
@@ -700,6 +700,21 @@ BUILTIN(__atomic_signal_fence, "vi", "n")
BUILTIN(__atomic_always_lock_free, "izvCD*", "n")
BUILTIN(__atomic_is_lock_free, "izvCD*", "n")
+// OpenCL 2.0 atomic builtins.
+ATOMIC_BUILTIN(__opencl_atomic_init, "v.", "t")
+ATOMIC_BUILTIN(__opencl_atomic_load, "v.", "t")
+ATOMIC_BUILTIN(__opencl_atomic_store, "v.", "t")
+ATOMIC_BUILTIN(__opencl_atomic_exchange, "v.", "t")
+ATOMIC_BUILTIN(__opencl_atomic_compare_exchange_strong, "v.", "t")
+ATOMIC_BUILTIN(__opencl_atomic_compare_exchange_weak, "v.", "t")
+ATOMIC_BUILTIN(__opencl_atomic_fetch_add, "v.", "t")
+ATOMIC_BUILTIN(__opencl_atomic_fetch_sub, "v.", "t")
+ATOMIC_BUILTIN(__opencl_atomic_fetch_and, "v.", "t")
+ATOMIC_BUILTIN(__opencl_atomic_fetch_or, "v.", "t")
+ATOMIC_BUILTIN(__opencl_atomic_fetch_xor, "v.", "t")
+ATOMIC_BUILTIN(__opencl_atomic_fetch_min, "v.", "t")
+ATOMIC_BUILTIN(__opencl_atomic_fetch_max, "v.", "t")
+
#undef ATOMIC_BUILTIN
// Non-overloaded atomic builtins.
@@ -717,6 +732,7 @@ BUILTIN(__builtin_rindex, "c*cC*i", "Fn")
// Microsoft builtins. These are only active with -fms-extensions.
LANGBUILTIN(_alloca, "v*z", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__annotation, "wC*.","n", ALL_MS_LANGUAGES)
LANGBUILTIN(__assume, "vb", "n", ALL_MS_LANGUAGES)
LIBBUILTIN(_byteswap_ushort, "UsUs", "fnc", "stdlib.h", ALL_MS_LANGUAGES)
LIBBUILTIN(_byteswap_ulong, "UNiUNi", "fnc", "stdlib.h", ALL_MS_LANGUAGES)
@@ -992,9 +1008,9 @@ LIBBUILTIN(modf, "ddd*", "fn", "math.h", ALL_LANGUAGES)
LIBBUILTIN(modff, "fff*", "fn", "math.h", ALL_LANGUAGES)
LIBBUILTIN(modfl, "LdLdLd*", "fn", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(nan, "dcC*", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(nanf, "fcC*", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(nanl, "LdcC*", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(nan, "dcC*", "fUn", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(nanf, "fcC*", "fUn", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(nanl, "LdcC*", "fUn", "math.h", ALL_LANGUAGES)
LIBBUILTIN(pow, "ddd", "fne", "math.h", ALL_LANGUAGES)
LIBBUILTIN(powf, "fff", "fne", "math.h", ALL_LANGUAGES)
@@ -1024,9 +1040,9 @@ LIBBUILTIN(atanh, "dd", "fne", "math.h", ALL_LANGUAGES)
LIBBUILTIN(atanhf, "ff", "fne", "math.h", ALL_LANGUAGES)
LIBBUILTIN(atanhl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(cbrt, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(cbrtf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(cbrtl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(cbrt, "dd", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(cbrtf, "ff", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(cbrtl, "LdLd", "fnc", "math.h", ALL_LANGUAGES)
LIBBUILTIN(ceil, "dd", "fnc", "math.h", ALL_LANGUAGES)
LIBBUILTIN(ceilf, "ff", "fnc", "math.h", ALL_LANGUAGES)
@@ -1146,6 +1162,10 @@ LIBBUILTIN(remainder, "ddd", "fne", "math.h", ALL_LANGUAGES)
LIBBUILTIN(remainderf, "fff", "fne", "math.h", ALL_LANGUAGES)
LIBBUILTIN(remainderl, "LdLdLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(remquo, "dddi*", "fn", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(remquof, "fffi*", "fn", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(remquol, "LdLdLdi*", "fn", "math.h", ALL_LANGUAGES)
+
LIBBUILTIN(rint, "dd", "fnc", "math.h", ALL_LANGUAGES)
LIBBUILTIN(rintf, "ff", "fnc", "math.h", ALL_LANGUAGES)
LIBBUILTIN(rintl, "LdLd", "fnc", "math.h", ALL_LANGUAGES)
@@ -1190,49 +1210,49 @@ LIBBUILTIN(trunc, "dd", "fnc", "math.h", ALL_LANGUAGES)
LIBBUILTIN(truncf, "ff", "fnc", "math.h", ALL_LANGUAGES)
LIBBUILTIN(truncl, "LdLd", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(cabs, "dXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cabsf, "fXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cabsl, "LdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cabs, "dXd", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cabsf, "fXf", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cabsl, "LdXLd", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cacos, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cacosf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cacosl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cacos, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cacosf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cacosl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cacosh, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cacoshf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cacoshl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cacosh, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cacoshf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cacoshl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(carg, "dXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cargf, "fXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cargl, "LdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(carg, "dXd", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cargf, "fXf", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cargl, "LdXLd", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(casin, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(casinf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(casinl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(casin, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(casinf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(casinl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(casinh, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(casinhf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(casinhl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(casinh, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(casinhf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(casinhl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(catan, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(catanf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(catanl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(catan, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(catanf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(catanl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(catanh, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(catanhf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(catanhl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(catanh, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(catanhf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(catanhl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(ccos, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(ccosf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(ccosl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(ccos, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(ccosf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(ccosl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(ccosh, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(ccoshf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(ccoshl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(ccosh, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(ccoshf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(ccoshl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cexp, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cexpf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cexpl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cexp, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cexpf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cexpl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(cimag, "dXd", "fnc", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(cimagf, "fXf", "fnc", "complex.h", ALL_LANGUAGES)
@@ -1242,41 +1262,41 @@ LIBBUILTIN(conj, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(conjf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(conjl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(clog, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(clogf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(clogl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(clog, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(clogf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(clogl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(cproj, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(cprojf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(cprojl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cpow, "XdXdXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cpowf, "XfXfXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cpowl, "XLdXLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cpow, "XdXdXd", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cpowf, "XfXfXf", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cpowl, "XLdXLdXLd", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(creal, "dXd", "fnc", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(crealf, "fXf", "fnc", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(creall, "LdXLd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(csin, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(csinf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(csinl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(csin, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(csinf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(csinl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(csinh, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(csinhf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(csinhl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(csinh, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(csinhf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(csinhl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(csqrt, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(csqrtf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(csqrtl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(csqrt, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(csqrtf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(csqrtl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(ctan, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(ctanf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(ctanl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(ctan, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(ctanf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(ctanl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(ctanh, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(ctanhf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(ctanhl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(ctanh, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(ctanhf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(ctanhl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
// __sinpi and friends are OS X specific library functions, but otherwise much
// like the standard (non-complex) sin (etc).
@@ -1398,18 +1418,29 @@ LANGBUILTIN(get_pipe_max_packets, "Ui.", "tn", OCLC20_LANG)
// OpenCL v2.0 s6.13.17 - Enqueue kernel functions.
// Custom builtin check allows to perform special check of passed block arguments.
LANGBUILTIN(enqueue_kernel, "i.", "tn", OCLC20_LANG)
-LANGBUILTIN(get_kernel_work_group_size, "i.", "tn", OCLC20_LANG)
-LANGBUILTIN(get_kernel_preferred_work_group_size_multiple, "i.", "tn", OCLC20_LANG)
+LANGBUILTIN(get_kernel_work_group_size, "Ui.", "tn", OCLC20_LANG)
+LANGBUILTIN(get_kernel_preferred_work_group_size_multiple, "Ui.", "tn", OCLC20_LANG)
+LANGBUILTIN(get_kernel_max_sub_group_size_for_ndrange, "Ui.", "tn", OCLC20_LANG)
+LANGBUILTIN(get_kernel_sub_group_count_for_ndrange, "Ui.", "tn", OCLC20_LANG)
// OpenCL v2.0 s6.13.9 - Address space qualifier functions.
LANGBUILTIN(to_global, "v*v*", "tn", OCLC20_LANG)
LANGBUILTIN(to_local, "v*v*", "tn", OCLC20_LANG)
LANGBUILTIN(to_private, "v*v*", "tn", OCLC20_LANG)
+// OpenCL half load/store builtin
+LANGBUILTIN(__builtin_store_half, "vdh*", "n", ALL_OCLC_LANGUAGES)
+LANGBUILTIN(__builtin_store_halff, "vfh*", "n", ALL_OCLC_LANGUAGES)
+LANGBUILTIN(__builtin_load_half, "dhC*", "nc", ALL_OCLC_LANGUAGES)
+LANGBUILTIN(__builtin_load_halff, "fhC*", "nc", ALL_OCLC_LANGUAGES)
+
// Builtins for os_log/os_trace
BUILTIN(__builtin_os_log_format_buffer_size, "zcC*.", "p:0:nut")
BUILTIN(__builtin_os_log_format, "v*v*cC*.", "p:0:nt")
+// OpenMP 4.0
+LANGBUILTIN(omp_is_initial_device, "i", "nc", OMP_LANG)
+
// Builtins for XRay
BUILTIN(__xray_customevent, "vcC*z", "")
diff --git a/include/clang/Basic/Builtins.h b/include/clang/Basic/Builtins.h
index 87c1f93eedef..963c72ea82e0 100644
--- a/include/clang/Basic/Builtins.h
+++ b/include/clang/Basic/Builtins.h
@@ -36,10 +36,13 @@ enum LanguageID {
CXX_LANG = 0x4, // builtin for cplusplus only.
OBJC_LANG = 0x8, // builtin for objective-c and objective-c++
MS_LANG = 0x10, // builtin requires MS mode.
- OCLC20_LANG = 0x20, // builtin for OpenCL C only.
+ OCLC20_LANG = 0x20, // builtin for OpenCL C 2.0 only.
+ OCLC1X_LANG = 0x40, // builtin for OpenCL C 1.x only.
+ OMP_LANG = 0x80, // builtin requires OpenMP.
ALL_LANGUAGES = C_LANG | CXX_LANG | OBJC_LANG, // builtin for all languages.
ALL_GNU_LANGUAGES = ALL_LANGUAGES | GNU_LANG, // builtin requires GNU mode.
- ALL_MS_LANGUAGES = ALL_LANGUAGES | MS_LANG // builtin requires MS mode.
+ ALL_MS_LANGUAGES = ALL_LANGUAGES | MS_LANG, // builtin requires MS mode.
+ ALL_OCLC_LANGUAGES = OCLC1X_LANG | OCLC20_LANG // builtin for OCLC languages.
};
namespace Builtin {
diff --git a/include/clang/Basic/BuiltinsAArch64.def b/include/clang/Basic/BuiltinsAArch64.def
index 1db4c1471029..55a4f70176d0 100644
--- a/include/clang/Basic/BuiltinsAArch64.def
+++ b/include/clang/Basic/BuiltinsAArch64.def
@@ -14,6 +14,10 @@
// The format of this database matches clang/Basic/Builtins.def.
+#if defined(BUILTIN) && !defined(LANGBUILTIN)
+# define LANGBUILTIN(ID, TYPE, ATTRS, BUILTIN_LANG) BUILTIN(ID, TYPE, ATTRS)
+#endif
+
// In libgcc
BUILTIN(__clear_cache, "vv*v*", "i")
@@ -61,4 +65,9 @@ BUILTIN(__builtin_arm_wsr, "vcC*Ui", "nc")
BUILTIN(__builtin_arm_wsr64, "vcC*LUi", "nc")
BUILTIN(__builtin_arm_wsrp, "vcC*vC*", "nc")
+LANGBUILTIN(__dmb, "vUi", "nc", ALL_MS_LANGUAGES)
+LANGBUILTIN(__dsb, "vUi", "nc", ALL_MS_LANGUAGES)
+LANGBUILTIN(__isb, "vUi", "nc", ALL_MS_LANGUAGES)
+
#undef BUILTIN
+#undef LANGBUILTIN
diff --git a/include/clang/Basic/BuiltinsAMDGPU.def b/include/clang/Basic/BuiltinsAMDGPU.def
index 6542acafe48a..ec6a0fb91765 100644
--- a/include/clang/Basic/BuiltinsAMDGPU.def
+++ b/include/clang/Basic/BuiltinsAMDGPU.def
@@ -21,6 +21,7 @@
// SI+ only builtins.
//===----------------------------------------------------------------------===//
+BUILTIN(__builtin_amdgcn_dispatch_ptr, "Uc*2", "nc")
BUILTIN(__builtin_amdgcn_kernarg_segment_ptr, "Uc*2", "nc")
BUILTIN(__builtin_amdgcn_implicitarg_ptr, "Uc*2", "nc")
@@ -120,6 +121,8 @@ TARGET_BUILTIN(__builtin_amdgcn_fmed3h, "hhhh", "nc", "gfx9-insts")
// Special builtins.
//===----------------------------------------------------------------------===//
BUILTIN(__builtin_amdgcn_read_exec, "LUi", "nc")
+BUILTIN(__builtin_amdgcn_read_exec_lo, "Ui", "nc")
+BUILTIN(__builtin_amdgcn_read_exec_hi, "Ui", "nc")
//===----------------------------------------------------------------------===//
// R600-NI only builtins.
diff --git a/include/clang/Basic/BuiltinsARM.def b/include/clang/Basic/BuiltinsARM.def
index 4e277f8a5a6b..941d320d729f 100644
--- a/include/clang/Basic/BuiltinsARM.def
+++ b/include/clang/Basic/BuiltinsARM.def
@@ -36,6 +36,7 @@ BUILTIN(__builtin_arm_smulwt, "iii", "nc")
// Saturating arithmetic
BUILTIN(__builtin_arm_qadd, "iii", "nc")
BUILTIN(__builtin_arm_qsub, "iii", "nc")
+BUILTIN(__builtin_arm_qdbl, "ii", "nc")
BUILTIN(__builtin_arm_ssat, "iiUi", "nc")
BUILTIN(__builtin_arm_usat, "UiiUi", "nc")
diff --git a/include/clang/Basic/BuiltinsHexagon.def b/include/clang/Basic/BuiltinsHexagon.def
index 14fc4adc25bc..fda50b53589b 100644
--- a/include/clang/Basic/BuiltinsHexagon.def
+++ b/include/clang/Basic/BuiltinsHexagon.def
@@ -17,7 +17,6 @@
// The builtins below are not autogenerated from iset.py.
// Make sure you do not overwrite these.
-BUILTIN(__builtin_SI_to_SXTHI_asrh, "ii", "")
BUILTIN(__builtin_brev_ldd, "LLi*LLi*LLi*i", "")
BUILTIN(__builtin_brev_ldw, "i*i*i*i", "")
BUILTIN(__builtin_brev_ldh, "s*s*s*i", "")
@@ -882,6 +881,7 @@ 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*","")
@@ -1470,14 +1470,6 @@ 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_vlutb,"V16iV16iLLii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vlutb_128B,"V32iV32iLLii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vlutb_acc,"V16iV16iV16iLLii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vlutb_acc_128B,"V32iV32iV32iLLii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vlutb_dv,"V32iV32iLLii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vlutb_dv_128B,"V64iV64iLLii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vlutb_dv_acc,"V32iV32iV32iLLii","v:60:")
-BUILTIN(__builtin_HEXAGON_V6_vlutb_dv_acc_128B,"V64iV64iV64iLLii","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:")
@@ -1508,4 +1500,216 @@ 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_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:")
+
+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_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:")
+
+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_vdd0,"V32i","v:65:")
+BUILTIN(__builtin_HEXAGON_V6_vdd0_128B,"V64i","v:65:")
+
+
#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsNVPTX.def b/include/clang/Basic/BuiltinsNVPTX.def
index afea6cb0f1b2..7bab73a3b110 100644
--- a/include/clang/Basic/BuiltinsNVPTX.def
+++ b/include/clang/Basic/BuiltinsNVPTX.def
@@ -371,6 +371,9 @@ BUILTIN(__nvvm_bitcast_i2f, "fi", "")
BUILTIN(__nvvm_bitcast_ll2d, "dLLi", "")
BUILTIN(__nvvm_bitcast_d2ll, "LLid", "")
+// FNS
+TARGET_BUILTIN(__nvvm_fns, "UiUiUii", "n", "ptx60")
+
// Sync
BUILTIN(__syncthreads, "v", "")
@@ -378,6 +381,9 @@ BUILTIN(__nvvm_bar0_popc, "ii", "")
BUILTIN(__nvvm_bar0_and, "ii", "")
BUILTIN(__nvvm_bar0_or, "ii", "")
BUILTIN(__nvvm_bar_sync, "vi", "n")
+TARGET_BUILTIN(__nvvm_bar_warp_sync, "vUi", "n", "ptx60")
+TARGET_BUILTIN(__nvvm_barrier_sync, "vUi", "n", "ptx60")
+TARGET_BUILTIN(__nvvm_barrier_sync_cnt, "vUiUi", "n", "ptx60")
// Shuffle
@@ -390,6 +396,33 @@ BUILTIN(__nvvm_shfl_bfly_f32, "ffii", "")
BUILTIN(__nvvm_shfl_idx_i32, "iiii", "")
BUILTIN(__nvvm_shfl_idx_f32, "ffii", "")
+TARGET_BUILTIN(__nvvm_shfl_sync_down_i32, "iUiiii", "", "ptx60")
+TARGET_BUILTIN(__nvvm_shfl_sync_down_f32, "fUifii", "", "ptx60")
+TARGET_BUILTIN(__nvvm_shfl_sync_up_i32, "iUiiii", "", "ptx60")
+TARGET_BUILTIN(__nvvm_shfl_sync_up_f32, "fUifii", "", "ptx60")
+TARGET_BUILTIN(__nvvm_shfl_sync_bfly_i32, "iUiiii", "", "ptx60")
+TARGET_BUILTIN(__nvvm_shfl_sync_bfly_f32, "fUifii", "", "ptx60")
+TARGET_BUILTIN(__nvvm_shfl_sync_idx_i32, "iUiiii", "", "ptx60")
+TARGET_BUILTIN(__nvvm_shfl_sync_idx_f32, "fUifii", "", "ptx60")
+
+// Vote
+BUILTIN(__nvvm_vote_all, "bb", "")
+BUILTIN(__nvvm_vote_any, "bb", "")
+BUILTIN(__nvvm_vote_uni, "bb", "")
+BUILTIN(__nvvm_vote_ballot, "Uib", "")
+
+TARGET_BUILTIN(__nvvm_vote_all_sync, "bUib", "", "ptx60")
+TARGET_BUILTIN(__nvvm_vote_any_sync, "bUib", "", "ptx60")
+TARGET_BUILTIN(__nvvm_vote_uni_sync, "bUib", "", "ptx60")
+TARGET_BUILTIN(__nvvm_vote_ballot_sync, "UiUib", "", "ptx60")
+
+// Match
+TARGET_BUILTIN(__nvvm_match_any_sync_i32, "UiUiUi", "", "ptx60")
+TARGET_BUILTIN(__nvvm_match_any_sync_i64, "WiUiWi", "", "ptx60")
+// These return a pair {value, predicate}, which requires custom lowering.
+TARGET_BUILTIN(__nvvm_match_all_sync_i32p, "UiUiUii*", "", "ptx60")
+TARGET_BUILTIN(__nvvm_match_all_sync_i64p, "WiUiWii*", "", "ptx60")
+
// Membar
BUILTIN(__nvvm_membar_cta, "v", "")
@@ -451,7 +484,7 @@ TARGET_BUILTIN(__nvvm_atom_cta_add_gen_f, "ffD*f", "n", "satom")
TARGET_BUILTIN(__nvvm_atom_sys_add_gen_f, "ffD*f", "n", "satom")
BUILTIN(__nvvm_atom_add_g_d, "ddD*1d", "n")
BUILTIN(__nvvm_atom_add_s_d, "ddD*3d", "n")
-BUILTIN(__nvvm_atom_add_gen_d, "ddD*d", "n")
+TARGET_BUILTIN(__nvvm_atom_add_gen_d, "ddD*d", "n", "satom")
TARGET_BUILTIN(__nvvm_atom_cta_add_gen_d, "ddD*d", "n", "satom")
TARGET_BUILTIN(__nvvm_atom_sys_add_gen_d, "ddD*d", "n", "satom")
@@ -658,5 +691,18 @@ BUILTIN(__nvvm_ldg_f2, "E2fE2fC*", "")
BUILTIN(__nvvm_ldg_f4, "E4fE4fC*", "")
BUILTIN(__nvvm_ldg_d2, "E2dE2dC*", "")
+// Builtins to support WMMA instructions on sm_70
+TARGET_BUILTIN(__hmma_m16n16k16_ld_a, "vi*iC*UiIi", "", "ptx60")
+TARGET_BUILTIN(__hmma_m16n16k16_ld_b, "vi*iC*UiIi", "", "ptx60")
+TARGET_BUILTIN(__hmma_m16n16k16_ld_c_f16, "vi*iC*UiIi", "", "ptx60")
+TARGET_BUILTIN(__hmma_m16n16k16_ld_c_f32, "vf*fC*UiIi", "", "ptx60")
+TARGET_BUILTIN(__hmma_m16n16k16_st_c_f16, "vi*i*UiIi", "", "ptx60")
+TARGET_BUILTIN(__hmma_m16n16k16_st_c_f32, "vf*f*UiIi", "", "ptx60")
+
+TARGET_BUILTIN(__hmma_m16n16k16_mma_f16f16, "vi*iC*iC*iC*IiIi", "", "ptx60")
+TARGET_BUILTIN(__hmma_m16n16k16_mma_f32f16, "vf*iC*iC*iC*IiIi", "", "ptx60")
+TARGET_BUILTIN(__hmma_m16n16k16_mma_f32f32, "vf*iC*iC*fC*IiIi", "", "ptx60")
+TARGET_BUILTIN(__hmma_m16n16k16_mma_f16f32, "vi*iC*iC*fC*IiIi", "", "ptx60")
+
#undef BUILTIN
#undef TARGET_BUILTIN
diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def
index 2f8f8919e5b3..d0be48467f1f 100644
--- a/include/clang/Basic/BuiltinsX86.def
+++ b/include/clang/Basic/BuiltinsX86.def
@@ -32,7 +32,9 @@
// Miscellaneous builtin for checking x86 cpu features.
// TODO: Make this somewhat generic so that other backends
// can use it?
+BUILTIN(__builtin_cpu_init, "v", "n")
BUILTIN(__builtin_cpu_supports, "bcC*", "nc")
+BUILTIN(__builtin_cpu_is, "bcC*", "nc")
// Undefined Values
//
@@ -264,8 +266,6 @@ TARGET_BUILTIN(__builtin_ia32_paddusw128, "V8sV8sV8s", "", "sse2")
TARGET_BUILTIN(__builtin_ia32_psubusb128, "V16cV16cV16c", "", "sse2")
TARGET_BUILTIN(__builtin_ia32_psubusw128, "V8sV8sV8s", "", "sse2")
TARGET_BUILTIN(__builtin_ia32_pmulhw128, "V8sV8sV8s", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_pavgb128, "V16cV16cV16c", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_pavgw128, "V8sV8sV8s", "", "sse2")
TARGET_BUILTIN(__builtin_ia32_pmaxub128, "V16cV16cV16c", "", "sse2")
TARGET_BUILTIN(__builtin_ia32_pmaxsw128, "V8sV8sV8s", "", "sse2")
TARGET_BUILTIN(__builtin_ia32_pminub128, "V16cV16cV16c", "", "sse2")
@@ -520,8 +520,6 @@ TARGET_BUILTIN(__builtin_ia32_paddusw256, "V16sV16sV16s", "", "avx2")
TARGET_BUILTIN(__builtin_ia32_psubusb256, "V32cV32cV32c", "", "avx2")
TARGET_BUILTIN(__builtin_ia32_psubusw256, "V16sV16sV16s", "", "avx2")
TARGET_BUILTIN(__builtin_ia32_palignr256, "V32cV32cV32cIi", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pavgb256, "V32cV32cV32c", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pavgw256, "V16sV16sV16s", "", "avx2")
TARGET_BUILTIN(__builtin_ia32_pblendvb256, "V32cV32cV32cV32c", "", "avx2")
TARGET_BUILTIN(__builtin_ia32_phaddw256, "V16sV16sV16s", "", "avx2")
TARGET_BUILTIN(__builtin_ia32_phaddd256, "V8iV8iV8i", "", "avx2")
@@ -640,8 +638,21 @@ TARGET_BUILTIN(__builtin_ia32_xrstors, "vv*ULLi", "", "xsaves")
TARGET_BUILTIN(__builtin_ia32_xsavec, "vv*ULLi", "", "xsavec")
TARGET_BUILTIN(__builtin_ia32_xsaves, "vv*ULLi", "", "xsaves")
+// SHSTK
+TARGET_BUILTIN(__builtin_ia32_incsspd, "vUi", "u", "shstk")
+TARGET_BUILTIN(__builtin_ia32_rdsspd, "UiUi", "Un", "shstk")
+TARGET_BUILTIN(__builtin_ia32_saveprevssp, "v", "", "shstk")
+TARGET_BUILTIN(__builtin_ia32_rstorssp, "vv*", "", "shstk")
+TARGET_BUILTIN(__builtin_ia32_wrssd, "vUiv*", "", "shstk")
+TARGET_BUILTIN(__builtin_ia32_wrussd, "vUiv*", "", "shstk")
+TARGET_BUILTIN(__builtin_ia32_setssbsy, "v", "", "shstk")
+TARGET_BUILTIN(__builtin_ia32_clrssbsy, "vv*", "", "shstk")
+
//CLFLUSHOPT
-TARGET_BUILTIN(__builtin_ia32_clflushopt, "vc*", "", "clflushopt")
+TARGET_BUILTIN(__builtin_ia32_clflushopt, "vvC*", "", "clflushopt")
+
+//CLWB
+TARGET_BUILTIN(__builtin_ia32_clwb, "vvC*", "", "clwb")
// ADX
TARGET_BUILTIN(__builtin_ia32_addcarryx_u32, "UcUcUiUiUi*", "", "adx")
@@ -681,36 +692,18 @@ TARGET_BUILTIN(__builtin_ia32_sha256msg2, "V4iV4iV4i", "", "sha")
// FMA
TARGET_BUILTIN(__builtin_ia32_vfmaddps, "V4fV4fV4fV4f", "", "fma|fma4")
TARGET_BUILTIN(__builtin_ia32_vfmaddpd, "V2dV2dV2dV2d", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmaddss, "V4fV4fV4fV4f", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmaddsd, "V2dV2dV2dV2d", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmsubps, "V4fV4fV4fV4f", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmsubpd, "V2dV2dV2dV2d", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmsubss, "V4fV4fV4fV4f", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmsubsd, "V2dV2dV2dV2d", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfnmaddps, "V4fV4fV4fV4f", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfnmaddpd, "V2dV2dV2dV2d", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfnmaddss, "V4fV4fV4fV4f", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfnmaddsd, "V2dV2dV2dV2d", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfnmsubps, "V4fV4fV4fV4f", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfnmsubpd, "V2dV2dV2dV2d", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfnmsubss, "V4fV4fV4fV4f", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfnmsubsd, "V2dV2dV2dV2d", "", "fma|fma4")
+TARGET_BUILTIN(__builtin_ia32_vfmaddss3, "V4fV4fV4fV4f", "", "fma")
+TARGET_BUILTIN(__builtin_ia32_vfmaddsd3, "V2dV2dV2dV2d", "", "fma")
+TARGET_BUILTIN(__builtin_ia32_vfmaddss, "V4fV4fV4fV4f", "", "fma4")
+TARGET_BUILTIN(__builtin_ia32_vfmaddsd, "V2dV2dV2dV2d", "", "fma4")
TARGET_BUILTIN(__builtin_ia32_vfmaddsubps, "V4fV4fV4fV4f", "", "fma|fma4")
TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd, "V2dV2dV2dV2d", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmsubaddps, "V4fV4fV4fV4f", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmsubaddpd, "V2dV2dV2dV2d", "", "fma|fma4")
TARGET_BUILTIN(__builtin_ia32_vfmaddps256, "V8fV8fV8fV8f", "", "fma|fma4")
TARGET_BUILTIN(__builtin_ia32_vfmaddpd256, "V4dV4dV4dV4d", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmsubps256, "V8fV8fV8fV8f", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmsubpd256, "V4dV4dV4dV4d", "", "fma|fma4")
TARGET_BUILTIN(__builtin_ia32_vfnmaddps256, "V8fV8fV8fV8f", "", "fma|fma4")
TARGET_BUILTIN(__builtin_ia32_vfnmaddpd256, "V4dV4dV4dV4d", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfnmsubps256, "V8fV8fV8fV8f", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfnmsubpd256, "V4dV4dV4dV4d", "", "fma|fma4")
TARGET_BUILTIN(__builtin_ia32_vfmaddsubps256, "V8fV8fV8fV8f", "", "fma|fma4")
TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd256, "V4dV4dV4dV4d", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmsubaddps256, "V8fV8fV8fV8f", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmsubaddpd256, "V4dV4dV4dV4d", "", "fma|fma4")
TARGET_BUILTIN(__builtin_ia32_vfmaddpd128_mask, "V2dV2dV2dV2dUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_vfmaddpd128_mask3, "V2dV2dV2dV2dUc", "", "avx512vl")
@@ -909,39 +902,10 @@ TARGET_BUILTIN(__builtin_ia32_cvttps2dq512_mask, "V16iV16fV16iUsIi", "", "avx512
TARGET_BUILTIN(__builtin_ia32_cvttps2udq512_mask, "V16iV16fV16iUsIi", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_cvttpd2dq512_mask, "V8iV8dV8iUcIi", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_cvttpd2udq512_mask, "V8iV8dV8iUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_cmpps512_mask, "UsV16fV16fIiUsIi", "", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_cmpps512_mask, "UsV16fV16fIiUsIi", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_cmpps256_mask, "UcV8fV8fIiUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_cmpps128_mask, "UcV4fV4fIiUc", "", "avx512vl")
-
-TARGET_BUILTIN(__builtin_ia32_pcmpeqb512_mask, "LLiV64cV64cLLi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pcmpeqd512_mask, "sV16iV16is", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pcmpeqq512_mask, "cV8LLiV8LLic", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pcmpeqw512_mask, "iV32sV32si", "", "avx512bw")
-
-TARGET_BUILTIN(__builtin_ia32_pcmpeqb256_mask, "iV32cV32ci", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pcmpeqd256_mask, "cV8iV8ic", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pcmpeqq256_mask, "cV4LLiV4LLic", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pcmpeqw256_mask, "sV16sV16ss", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pcmpeqb128_mask, "sV16cV16cs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pcmpeqd128_mask, "cV4iV4ic", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pcmpeqq128_mask, "cV2LLiV2LLic", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pcmpeqw128_mask, "cV8sV8sc", "", "avx512vl,avx512bw")
-
-TARGET_BUILTIN(__builtin_ia32_pcmpgtb512_mask, "LLiV64cV64cLLi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pcmpgtd512_mask, "sV16iV16is", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pcmpgtq512_mask, "cV8LLiV8LLic", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pcmpgtw512_mask, "iV32sV32si", "", "avx512bw")
-
-TARGET_BUILTIN(__builtin_ia32_pcmpgtb256_mask, "iV32cV32ci", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pcmpgtd256_mask, "cV8iV8ic", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pcmpgtq256_mask, "cV4LLiV4LLic", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pcmpgtw256_mask, "sV16sV16ss", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pcmpgtb128_mask, "sV16cV16cs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pcmpgtd128_mask, "cV4iV4ic", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pcmpgtq128_mask, "cV2LLiV2LLic", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pcmpgtw128_mask, "cV8sV8sc", "", "avx512vl,avx512bw")
-
TARGET_BUILTIN(__builtin_ia32_cmppd512_mask, "UcV8dV8dIiUcIi", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_cmppd256_mask, "UcV4dV4dIiUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_cmppd128_mask, "UcV2dV2dIiUc", "", "avx512vl")
@@ -973,9 +937,6 @@ TARGET_BUILTIN(__builtin_ia32_pminud512_mask, "V16iV16iV16iV16iUs", "", "avx512f
TARGET_BUILTIN(__builtin_ia32_pminuq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_pmuldq512, "V8LLiV16iV16i", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_pmuludq512, "V8LLiV16iV16i", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_ptestmd512, "UsV16iV16iUs", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_ptestmq512, "UcV8LLiV8LLiUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pbroadcastd512_gpr_mask, "V16iiV16iUs", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_loaddqusi512_mask, "V16iiC*V16iUs", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_loaddqudi512_mask, "V8LLiLLiC*V8LLiUc", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_loadups512_mask, "V16ffC*V16fUs", "", "avx512f")
@@ -1072,8 +1033,6 @@ TARGET_BUILTIN(__builtin_ia32_paddsb512_mask, "V64cV64cV64cV64cULLi", "", "avx51
TARGET_BUILTIN(__builtin_ia32_paddsw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_paddusb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_paddusw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pavgb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pavgw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmaxsb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmaxsw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmaxub512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
@@ -1101,6 +1060,10 @@ TARGET_BUILTIN(__builtin_ia32_vpconflictsi_512_mask, "V16iV16iV16iUs", "", "avx5
TARGET_BUILTIN(__builtin_ia32_vplzcntd_512_mask, "V16iV16iV16iUs", "", "avx512cd")
TARGET_BUILTIN(__builtin_ia32_vplzcntq_512_mask, "V8LLiV8LLiV8LLiUc", "", "avx512cd")
+TARGET_BUILTIN(__builtin_ia32_vpopcntd_128, "V4iV4i", "", "avx512vpopcntdq,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vpopcntq_128, "V2LLiV2LLi", "", "avx512vpopcntdq,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vpopcntd_256, "V8iV8i", "", "avx512vpopcntdq,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vpopcntq_256, "V4LLiV4LLi", "", "avx512vpopcntdq,avx512vl")
TARGET_BUILTIN(__builtin_ia32_vpopcntd_512, "V16iV16i", "", "avx512vpopcntdq")
TARGET_BUILTIN(__builtin_ia32_vpopcntq_512, "V8LLiV8LLi", "", "avx512vpopcntdq")
@@ -1378,11 +1341,6 @@ TARGET_BUILTIN(__builtin_ia32_movdqa64load128_mask, "V2LLiV2LLiC*V2LLiUc","","av
TARGET_BUILTIN(__builtin_ia32_movdqa64load256_mask, "V4LLiV4LLiC*V4LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_movdqa64store128_mask, "vV2LLi*V2LLiUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_movdqa64store256_mask, "vV4LLi*V4LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pbroadcastb512_gpr_mask, "V64ccV64cULLi","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pbroadcastb128_gpr_mask, "V16ccV16cUs","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pbroadcastb256_gpr_mask, "V32ccV32cUi","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pbroadcastd128_gpr_mask, "V4iiV4iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pbroadcastd256_gpr_mask, "V8iiV8iUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_vpmadd52huq512_mask, "V8LLiV8LLiV8LLiV8LLiUc","","avx512ifma")
TARGET_BUILTIN(__builtin_ia32_vpmadd52huq512_maskz, "V8LLiV8LLiV8LLiV8LLiUc","","avx512ifma")
TARGET_BUILTIN(__builtin_ia32_vpmadd52luq512_mask, "V8LLiV8LLiV8LLiV8LLiUc","","avx512ifma")
@@ -1494,28 +1452,6 @@ TARGET_BUILTIN(__builtin_ia32_vpermt2vard512_maskz, "V16iV16iV16iV16iUs","","avx
TARGET_BUILTIN(__builtin_ia32_vpermt2varpd512_maskz, "V8dV8LLiV8dV8dUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vpermt2varps512_maskz, "V16fV16iV16fV16fUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vpermt2varq512_maskz, "V8LLiV8LLiV8LLiV8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_ptestmb512, "ULLiV64cV64cULLi","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_ptestmw512, "UiV32sV32sUi","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_ptestnmb512, "ULLiV64cV64cULLi","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_ptestnmw512, "UiV32sV32sUi","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_ptestmb128, "UsV16cV16cUs","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_ptestmb256, "UiV32cV32cUi","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_ptestmw128, "UcV8sV8sUc","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_ptestmw256, "UsV16sV16sUs","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_ptestnmb128, "UsV16cV16cUs","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_ptestnmb256, "UiV32cV32cUi","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_ptestnmw128, "UcV8sV8sUc","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_ptestnmw256, "UsV16sV16sUs","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_ptestmd128, "UcV4iV4iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_ptestmd256, "UcV8iV8iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_ptestmq128, "UcV2LLiV2LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_ptestmq256, "UcV4LLiV4LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_ptestnmd128, "UcV4iV4iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_ptestnmd256, "UcV8iV8iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_ptestnmq128, "UcV2LLiV2LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_ptestnmq256, "UcV4LLiV4LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_ptestnmd512, "UsV16iV16iUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_ptestnmq512, "UcV8LLiV8LLiUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_rndscalesd_round_mask, "V2dV2dV2dV2dUcIiIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_rndscaless_round_mask, "V4fV4fV4fV4fUcIiIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_scalefpd512_mask, "V8dV8dV8dV8dUcIi","","avx512f")
@@ -1587,20 +1523,6 @@ TARGET_BUILTIN(__builtin_ia32_cvtmask2q128, "V2LLiUc","","avx512dq,avx512vl")
TARGET_BUILTIN(__builtin_ia32_cvtmask2q256, "V4LLiUc","","avx512dq,avx512vl")
TARGET_BUILTIN(__builtin_ia32_cvtq2mask128, "UcV2LLi","","avx512dq,avx512vl")
TARGET_BUILTIN(__builtin_ia32_cvtq2mask256, "UcV4LLi","","avx512dq,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_broadcastmb512, "V8LLiUc","","avx512cd")
-TARGET_BUILTIN(__builtin_ia32_broadcastmw512, "V16iUs","","avx512cd")
-TARGET_BUILTIN(__builtin_ia32_broadcastmb128, "V2LLiUc","","avx512cd,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_broadcastmb256, "V4LLiUc","","avx512cd,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_broadcastmw128, "V4iUs","","avx512cd,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_broadcastmw256, "V8iUs","","avx512cd,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_broadcastf32x2_512_mask, "V16fV4fV16fUs","","avx512dq")
-TARGET_BUILTIN(__builtin_ia32_broadcasti32x2_512_mask, "V16iV4iV16iUs","","avx512dq")
-TARGET_BUILTIN(__builtin_ia32_broadcastf32x2_256_mask, "V8fV4fV8fUc","","avx512dq,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_broadcasti32x2_128_mask, "V4iV4iV4iUc","","avx512dq,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_broadcasti32x2_256_mask, "V8iV4iV8iUc","","avx512dq,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pbroadcastw512_gpr_mask, "V32shV32sUi","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pbroadcastw256_gpr_mask, "V16shV16sUs","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pbroadcastw128_gpr_mask, "V8ssV8sUc","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmovsdb512_mask, "V16cV16iV16cUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_pmovsdb512mem_mask, "vV16c*V16iUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_pmovswb512mem_mask, "vV32c*V32sUi","","avx512bw")
diff --git a/include/clang/Basic/BuiltinsX86_64.def b/include/clang/Basic/BuiltinsX86_64.def
index 4cde153d8372..fe2c887c7e0f 100644
--- a/include/clang/Basic/BuiltinsX86_64.def
+++ b/include/clang/Basic/BuiltinsX86_64.def
@@ -40,6 +40,7 @@ TARGET_HEADER_BUILTIN(_InterlockedExchangeSub64, "LLiLLiD*LLi", "nh", "intrin.h"
TARGET_HEADER_BUILTIN(_InterlockedIncrement64, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
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(_InterlockedCompareExchange128, "UcLLiD*LLiLLiLLi*", "nh", "intrin.h", ALL_MS_LANGUAGES, "cx16")
TARGET_BUILTIN(__builtin_ia32_readeflags_u64, "ULLi", "n", "")
TARGET_BUILTIN(__builtin_ia32_writeeflags_u64, "vULLi", "n", "")
@@ -60,6 +61,10 @@ TARGET_BUILTIN(__builtin_ia32_xsaveopt64, "vv*ULLi", "", "xsaveopt")
TARGET_BUILTIN(__builtin_ia32_xrstors64, "vv*ULLi", "", "xsaves")
TARGET_BUILTIN(__builtin_ia32_xsavec64, "vv*ULLi", "", "xsavec")
TARGET_BUILTIN(__builtin_ia32_xsaves64, "vv*ULLi", "", "xsaves")
+TARGET_BUILTIN(__builtin_ia32_incsspq, "vULLi", "u", "shstk")
+TARGET_BUILTIN(__builtin_ia32_rdsspq, "ULLiULLi", "Un", "shstk")
+TARGET_BUILTIN(__builtin_ia32_wrssq, "vULLiv*", "", "shstk")
+TARGET_BUILTIN(__builtin_ia32_wrussq, "vULLiv*", "", "shstk")
TARGET_BUILTIN(__builtin_ia32_addcarryx_u64, "UcUcULLiULLiULLi*", "", "adx")
TARGET_BUILTIN(__builtin_ia32_addcarry_u64, "UcUcULLiULLiULLi*", "", "")
TARGET_BUILTIN(__builtin_ia32_subborrow_u64, "UcUcULLiULLiULLi*", "", "")
@@ -71,9 +76,6 @@ TARGET_BUILTIN(__builtin_ia32_pext_di, "ULLiULLiULLi", "", "bmi2")
TARGET_BUILTIN(__builtin_ia32_bextri_u64, "ULLiULLiIULLi", "", "tbm")
TARGET_BUILTIN(__builtin_ia32_lwpins64, "UcULLiUiUi", "", "lwp")
TARGET_BUILTIN(__builtin_ia32_lwpval64, "vULLiUiUi", "", "lwp")
-TARGET_BUILTIN(__builtin_ia32_pbroadcastq512_gpr_mask, "V8LLiLLiV8LLiUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pbroadcastq128_gpr_mask, "V2LLiULLiV2LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pbroadcastq256_gpr_mask, "V4LLiULLiV4LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_vcvtsd2si64, "LLiV2dIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvtsd2usi64, "ULLiV2dIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvtss2si64, "LLiV4fIi","","avx512f")
diff --git a/include/clang/Basic/CMakeLists.txt b/include/clang/Basic/CMakeLists.txt
index 3e0fb8728c48..821c405913c8 100644
--- a/include/clang/Basic/CMakeLists.txt
+++ b/include/clang/Basic/CMakeLists.txt
@@ -9,10 +9,12 @@ clang_diag_gen(Analysis)
clang_diag_gen(AST)
clang_diag_gen(Comment)
clang_diag_gen(Common)
+clang_diag_gen(CrossTU)
clang_diag_gen(Driver)
clang_diag_gen(Frontend)
clang_diag_gen(Lex)
clang_diag_gen(Parse)
+clang_diag_gen(Refactoring)
clang_diag_gen(Sema)
clang_diag_gen(Serialization)
clang_tablegen(DiagnosticGroups.inc -gen-clang-diag-groups
diff --git a/include/clang/Basic/CharInfo.h b/include/clang/Basic/CharInfo.h
index dd9c55431e01..cc27bbb48e0d 100644
--- a/include/clang/Basic/CharInfo.h
+++ b/include/clang/Basic/CharInfo.h
@@ -40,14 +40,14 @@ namespace charinfo {
} // end namespace charinfo
/// Returns true if this is an ASCII character.
-LLVM_READNONE static inline bool isASCII(char c) {
+LLVM_READNONE inline bool isASCII(char c) {
return static_cast<unsigned char>(c) <= 127;
}
/// Returns true if this is a valid first character of a C identifier,
/// which is [a-zA-Z_].
-LLVM_READONLY static inline bool isIdentifierHead(unsigned char c,
- bool AllowDollar = false) {
+LLVM_READONLY inline bool isIdentifierHead(unsigned char c,
+ bool AllowDollar = false) {
using namespace charinfo;
if (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER|CHAR_UNDER))
return true;
@@ -56,8 +56,8 @@ LLVM_READONLY static inline bool isIdentifierHead(unsigned char c,
/// Returns true if this is a body character of a C identifier,
/// which is [a-zA-Z0-9_].
-LLVM_READONLY static inline bool isIdentifierBody(unsigned char c,
- bool AllowDollar = false) {
+LLVM_READONLY inline bool isIdentifierBody(unsigned char c,
+ bool AllowDollar = false) {
using namespace charinfo;
if (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER|CHAR_DIGIT|CHAR_UNDER))
return true;
@@ -68,7 +68,7 @@ LLVM_READONLY static inline bool isIdentifierBody(unsigned char c,
/// ' ', '\\t', '\\f', '\\v'.
///
/// Note that this returns false for '\\0'.
-LLVM_READONLY static inline bool isHorizontalWhitespace(unsigned char c) {
+LLVM_READONLY inline bool isHorizontalWhitespace(unsigned char c) {
using namespace charinfo;
return (InfoTable[c] & (CHAR_HORZ_WS|CHAR_SPACE)) != 0;
}
@@ -76,7 +76,7 @@ LLVM_READONLY static inline bool isHorizontalWhitespace(unsigned char c) {
/// Returns true if this character is vertical ASCII whitespace: '\\n', '\\r'.
///
/// Note that this returns false for '\\0'.
-LLVM_READONLY static inline bool isVerticalWhitespace(unsigned char c) {
+LLVM_READONLY inline bool isVerticalWhitespace(unsigned char c) {
using namespace charinfo;
return (InfoTable[c] & CHAR_VERT_WS) != 0;
}
@@ -85,43 +85,43 @@ LLVM_READONLY static inline bool isVerticalWhitespace(unsigned char c) {
/// ' ', '\\t', '\\f', '\\v', '\\n', '\\r'.
///
/// Note that this returns false for '\\0'.
-LLVM_READONLY static inline bool isWhitespace(unsigned char c) {
+LLVM_READONLY inline bool isWhitespace(unsigned char c) {
using namespace charinfo;
return (InfoTable[c] & (CHAR_HORZ_WS|CHAR_VERT_WS|CHAR_SPACE)) != 0;
}
/// Return true if this character is an ASCII digit: [0-9]
-LLVM_READONLY static inline bool isDigit(unsigned char c) {
+LLVM_READONLY inline bool isDigit(unsigned char c) {
using namespace charinfo;
return (InfoTable[c] & CHAR_DIGIT) != 0;
}
/// Return true if this character is a lowercase ASCII letter: [a-z]
-LLVM_READONLY static inline bool isLowercase(unsigned char c) {
+LLVM_READONLY inline bool isLowercase(unsigned char c) {
using namespace charinfo;
return (InfoTable[c] & CHAR_LOWER) != 0;
}
/// Return true if this character is an uppercase ASCII letter: [A-Z]
-LLVM_READONLY static inline bool isUppercase(unsigned char c) {
+LLVM_READONLY inline bool isUppercase(unsigned char c) {
using namespace charinfo;
return (InfoTable[c] & CHAR_UPPER) != 0;
}
/// Return true if this character is an ASCII letter: [a-zA-Z]
-LLVM_READONLY static inline bool isLetter(unsigned char c) {
+LLVM_READONLY inline bool isLetter(unsigned char c) {
using namespace charinfo;
return (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER)) != 0;
}
/// Return true if this character is an ASCII letter or digit: [a-zA-Z0-9]
-LLVM_READONLY static inline bool isAlphanumeric(unsigned char c) {
+LLVM_READONLY inline bool isAlphanumeric(unsigned char c) {
using namespace charinfo;
return (InfoTable[c] & (CHAR_DIGIT|CHAR_UPPER|CHAR_LOWER)) != 0;
}
/// Return true if this character is an ASCII hex digit: [0-9a-fA-F]
-LLVM_READONLY static inline bool isHexDigit(unsigned char c) {
+LLVM_READONLY inline bool isHexDigit(unsigned char c) {
using namespace charinfo;
return (InfoTable[c] & (CHAR_DIGIT|CHAR_XLETTER)) != 0;
}
@@ -129,7 +129,7 @@ LLVM_READONLY static inline bool isHexDigit(unsigned char c) {
/// Return true if this character is an ASCII punctuation character.
///
/// Note that '_' is both a punctuation character and an identifier character!
-LLVM_READONLY static inline bool isPunctuation(unsigned char c) {
+LLVM_READONLY inline bool isPunctuation(unsigned char c) {
using namespace charinfo;
return (InfoTable[c] & (CHAR_UNDER|CHAR_PERIOD|CHAR_RAWDEL|CHAR_PUNCT)) != 0;
}
@@ -137,7 +137,7 @@ LLVM_READONLY static inline bool isPunctuation(unsigned char c) {
/// Return true if this character is an ASCII printable character; that is, a
/// character that should take exactly one column to print in a fixed-width
/// terminal.
-LLVM_READONLY static inline bool isPrintable(unsigned char c) {
+LLVM_READONLY inline bool isPrintable(unsigned char c) {
using namespace charinfo;
return (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER|CHAR_PERIOD|CHAR_PUNCT|
CHAR_DIGIT|CHAR_UNDER|CHAR_RAWDEL|CHAR_SPACE)) != 0;
@@ -145,14 +145,14 @@ LLVM_READONLY static inline bool isPrintable(unsigned char c) {
/// Return true if this is the body character of a C preprocessing number,
/// which is [a-zA-Z0-9_.].
-LLVM_READONLY static inline bool isPreprocessingNumberBody(unsigned char c) {
+LLVM_READONLY inline bool isPreprocessingNumberBody(unsigned char c) {
using namespace charinfo;
return (InfoTable[c] &
(CHAR_UPPER|CHAR_LOWER|CHAR_DIGIT|CHAR_UNDER|CHAR_PERIOD)) != 0;
}
/// Return true if this is the body character of a C++ raw string delimiter.
-LLVM_READONLY static inline bool isRawStringDelimBody(unsigned char c) {
+LLVM_READONLY inline bool isRawStringDelimBody(unsigned char c) {
using namespace charinfo;
return (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER|CHAR_PERIOD|
CHAR_DIGIT|CHAR_UNDER|CHAR_RAWDEL)) != 0;
@@ -162,7 +162,7 @@ LLVM_READONLY static inline bool isRawStringDelimBody(unsigned char c) {
/// Converts the given ASCII character to its lowercase equivalent.
///
/// If the character is not an uppercase character, it is returned as is.
-LLVM_READONLY static inline char toLowercase(char c) {
+LLVM_READONLY inline char toLowercase(char c) {
if (isUppercase(c))
return c + 'a' - 'A';
return c;
@@ -171,7 +171,7 @@ LLVM_READONLY static inline char toLowercase(char c) {
/// Converts the given ASCII character to its uppercase equivalent.
///
/// If the character is not a lowercase character, it is returned as is.
-LLVM_READONLY static inline char toUppercase(char c) {
+LLVM_READONLY inline char toUppercase(char c) {
if (isLowercase(c))
return c + 'A' - 'a';
return c;
@@ -182,7 +182,7 @@ LLVM_READONLY static inline char toUppercase(char c) {
///
/// Note that this is a very simple check; it does not accept '$' or UCNs as
/// valid identifier characters.
-LLVM_READONLY static inline bool isValidIdentifier(StringRef S) {
+LLVM_READONLY inline bool isValidIdentifier(StringRef S) {
if (S.empty() || !isIdentifierHead(S[0]))
return false;
diff --git a/include/clang/Basic/Cuda.h b/include/clang/Basic/Cuda.h
index ad1139b8c197..1a0731c37a35 100644
--- a/include/clang/Basic/Cuda.h
+++ b/include/clang/Basic/Cuda.h
@@ -21,6 +21,8 @@ enum class CudaVersion {
CUDA_70,
CUDA_75,
CUDA_80,
+ CUDA_90,
+ LATEST = CUDA_90,
};
const char *CudaVersionToString(CudaVersion V);
@@ -41,6 +43,7 @@ enum class CudaArch {
SM_60,
SM_61,
SM_62,
+ SM_70,
};
const char *CudaArchToString(CudaArch A);
@@ -60,6 +63,7 @@ enum class CudaVirtualArch {
COMPUTE_60,
COMPUTE_61,
COMPUTE_62,
+ COMPUTE_70,
};
const char *CudaVirtualArchToString(CudaVirtualArch A);
@@ -72,6 +76,9 @@ CudaVirtualArch VirtualArchForCudaArch(CudaArch A);
/// Get the earliest CudaVersion that supports the given CudaArch.
CudaVersion MinVersionForCudaArch(CudaArch A);
+/// Get the latest CudaVersion that supports the given CudaArch.
+CudaVersion MaxVersionForCudaArch(CudaArch A);
+
} // namespace clang
#endif
diff --git a/include/clang/Basic/DeclNodes.td b/include/clang/Basic/DeclNodes.td
index 3298a80e5134..67ca9e5c6c62 100644
--- a/include/clang/Basic/DeclNodes.td
+++ b/include/clang/Basic/DeclNodes.td
@@ -1,66 +1,68 @@
class AttrSubject;
-class Decl<bit abstract = 0> : AttrSubject {
+class Decl<string diagSpelling = "", bit abstract = 0> : AttrSubject {
bit Abstract = abstract;
+ string DiagSpelling = diagSpelling;
}
-class DDecl<Decl base, bit abstract = 0> : Decl<abstract> {
+class DDecl<Decl base, string diagSpelling = "", bit abstract = 0>
+ : Decl<diagSpelling, abstract> {
Decl Base = base;
}
-class DeclContext { }
+class DeclContext {}
def TranslationUnit : Decl, DeclContext;
def PragmaComment : Decl;
def PragmaDetectMismatch : Decl;
def ExternCContext : Decl, DeclContext;
-def Named : Decl<1>;
- def Namespace : DDecl<Named>, DeclContext;
+def Named : Decl<"named declarations", 1>;
+ def Namespace : DDecl<Named, "namespaces">, DeclContext;
def UsingDirective : DDecl<Named>;
def NamespaceAlias : DDecl<Named>;
- def Label : DDecl<Named>;
- def Type : DDecl<Named, 1>;
- def TypedefName : DDecl<Type, 1>;
+ def Label : DDecl<Named, "labels">;
+ def Type : DDecl<Named, "types", 1>;
+ def TypedefName : DDecl<Type, "typedefs", 1>;
def Typedef : DDecl<TypedefName>;
def TypeAlias : DDecl<TypedefName>;
def ObjCTypeParam : DDecl<TypedefName>;
def UnresolvedUsingTypename : DDecl<Type>;
- def Tag : DDecl<Type, 1>, DeclContext;
- def Enum : DDecl<Tag>;
- def Record : DDecl<Tag>;
- def CXXRecord : DDecl<Record>;
+ def Tag : DDecl<Type, "tag types", 1>, DeclContext;
+ def Enum : DDecl<Tag, "enums">;
+ def Record : DDecl<Tag, "structs, unions, classes">;
+ def CXXRecord : DDecl<Record, "classes">;
def ClassTemplateSpecialization : DDecl<CXXRecord>;
def ClassTemplatePartialSpecialization
: DDecl<ClassTemplateSpecialization>;
def TemplateTypeParm : DDecl<Type>;
- def Value : DDecl<Named, 1>;
- def EnumConstant : DDecl<Value>;
+ def Value : DDecl<Named, "value declarations", 1>;
+ def EnumConstant : DDecl<Value, "enumerators">;
def UnresolvedUsingValue : DDecl<Value>;
def IndirectField : DDecl<Value>;
def Binding : DDecl<Value>;
def OMPDeclareReduction : DDecl<Value>, DeclContext;
- def Declarator : DDecl<Value, 1>;
- def Field : DDecl<Declarator>;
+ def Declarator : DDecl<Value, "declarators", 1>;
+ def Field : DDecl<Declarator, "non-static data members">;
def ObjCIvar : DDecl<Field>;
def ObjCAtDefsField : DDecl<Field>;
def MSProperty : DDecl<Declarator>;
- def Function : DDecl<Declarator>, DeclContext;
+ def Function : DDecl<Declarator, "functions">, DeclContext;
def CXXDeductionGuide : DDecl<Function>;
def CXXMethod : DDecl<Function>;
def CXXConstructor : DDecl<CXXMethod>;
def CXXDestructor : DDecl<CXXMethod>;
def CXXConversion : DDecl<CXXMethod>;
- def Var : DDecl<Declarator>;
+ def Var : DDecl<Declarator, "variables">;
def VarTemplateSpecialization : DDecl<Var>;
def VarTemplatePartialSpecialization
: DDecl<VarTemplateSpecialization>;
def ImplicitParam : DDecl<Var>;
- def ParmVar : DDecl<Var>;
+ def ParmVar : DDecl<Var, "parameters">;
def Decomposition : DDecl<Var>;
def OMPCapturedExpr : DDecl<Var>;
def NonTypeTemplateParm : DDecl<Declarator>;
- def Template : DDecl<Named, 1>;
- def RedeclarableTemplate : DDecl<Template, 1>;
+ def Template : DDecl<Named, "templates", 1>;
+ def RedeclarableTemplate : DDecl<Template, "redeclarable templates", 1>;
def FunctionTemplate : DDecl<RedeclarableTemplate>;
def ClassTemplate : DDecl<RedeclarableTemplate>;
def VarTemplate : DDecl<RedeclarableTemplate>;
@@ -71,15 +73,16 @@ def Named : Decl<1>;
def UsingPack : DDecl<Named>;
def UsingShadow : DDecl<Named>;
def ConstructorUsingShadow : DDecl<UsingShadow>;
- def ObjCMethod : DDecl<Named>, DeclContext;
- def ObjCContainer : DDecl<Named, 1>, DeclContext;
+ def ObjCMethod : DDecl<Named, "Objective-C methods">, DeclContext;
+ def ObjCContainer : DDecl<Named, "Objective-C containers", 1>, DeclContext;
def ObjCCategory : DDecl<ObjCContainer>;
- def ObjCProtocol : DDecl<ObjCContainer>;
- def ObjCInterface : DDecl<ObjCContainer>;
- def ObjCImpl : DDecl<ObjCContainer, 1>;
+ def ObjCProtocol : DDecl<ObjCContainer, "Objective-C protocols">;
+ def ObjCInterface : DDecl<ObjCContainer, "Objective-C interfaces">;
+ def ObjCImpl
+ : DDecl<ObjCContainer, "Objective-C implementation declarations", 1>;
def ObjCCategoryImpl : DDecl<ObjCImpl>;
def ObjCImplementation : DDecl<ObjCImpl>;
- def ObjCProperty : DDecl<Named>;
+ def ObjCProperty : DDecl<Named, "Objective-C properties">;
def ObjCCompatibleAlias : DDecl<Named>;
def LinkageSpec : Decl, DeclContext;
def Export : Decl, DeclContext;
@@ -89,7 +92,7 @@ def AccessSpec : Decl;
def Friend : Decl;
def FriendTemplate : Decl;
def StaticAssert : Decl;
-def Block : Decl, DeclContext;
+def Block : Decl<"blocks">, DeclContext;
def Captured : Decl, DeclContext;
def ClassScopeFunctionSpecialization : Decl;
def Import : Decl;
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h
index 22cded21c12d..a7458d45618e 100644
--- a/include/clang/Basic/Diagnostic.h
+++ b/include/clang/Basic/Diagnostic.h
@@ -575,13 +575,15 @@ public:
OverloadsShown getShowOverloads() const { return ShowOverloads; }
/// \brief Pretend that the last diagnostic issued was ignored, so any
- /// subsequent notes will be suppressed.
+ /// subsequent notes will be suppressed, or restore a prior ignoring
+ /// state after ignoring some diagnostics and their notes, possibly in
+ /// the middle of another diagnostic.
///
/// This can be used by clients who suppress diagnostics themselves.
- void setLastDiagnosticIgnored() {
+ void setLastDiagnosticIgnored(bool Ignored = true) {
if (LastDiagLevel == DiagnosticIDs::Fatal)
FatalErrorOccurred = true;
- LastDiagLevel = DiagnosticIDs::Ignored;
+ LastDiagLevel = Ignored ? DiagnosticIDs::Ignored : DiagnosticIDs::Warning;
}
/// \brief Determine whether the previous diagnostic was ignored. This can
diff --git a/include/clang/Basic/Diagnostic.td b/include/clang/Basic/Diagnostic.td
index f25068eca132..52ccf350e651 100644
--- a/include/clang/Basic/Diagnostic.td
+++ b/include/clang/Basic/Diagnostic.td
@@ -133,10 +133,12 @@ include "DiagnosticASTKinds.td"
include "DiagnosticAnalysisKinds.td"
include "DiagnosticCommentKinds.td"
include "DiagnosticCommonKinds.td"
+include "DiagnosticCrossTUKinds.td"
include "DiagnosticDriverKinds.td"
include "DiagnosticFrontendKinds.td"
include "DiagnosticLexKinds.td"
include "DiagnosticParseKinds.td"
+include "DiagnosticRefactoringKinds.td"
include "DiagnosticSemaKinds.td"
include "DiagnosticSerializationKinds.td"
diff --git a/include/clang/Basic/DiagnosticASTKinds.td b/include/clang/Basic/DiagnosticASTKinds.td
index b3cba2066edd..215580b2e9b6 100644
--- a/include/clang/Basic/DiagnosticASTKinds.td
+++ b/include/clang/Basic/DiagnosticASTKinds.td
@@ -127,6 +127,10 @@ def note_constexpr_access_null : Note<
def note_constexpr_access_past_end : Note<
"%select{read of|assignment to|increment of|decrement of}0 "
"dereferenced one-past-the-end pointer is not allowed in a constant expression">;
+def note_constexpr_access_unsized_array : Note<
+ "%select{read of|assignment to|increment of|decrement of}0 "
+ "pointer to element of array without known bound "
+ "is not allowed in a constant expression">;
def note_constexpr_access_inactive_union_member : Note<
"%select{read of|assignment to|increment of|decrement of}0 "
"member %1 of union with %select{active member %3|no active member}2 "
@@ -154,6 +158,11 @@ def note_constexpr_baa_insufficient_alignment : Note<
def note_constexpr_baa_value_insufficient_alignment : Note<
"value of the aligned pointer (%0) is not a multiple of the asserted %1 "
"%plural{1:byte|:bytes}1">;
+def note_constexpr_unsupported_unsized_array : Note<
+ "array-to-pointer decay of array member without known bound is not supported">;
+def note_constexpr_unsized_array_indexed : Note<
+ "indexing of array without known bound is not allowed "
+ "in a constant expression">;
def warn_integer_constant_overflow : Warning<
"overflow in expression; result is %0 with type %1">,
diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td
index 98fd3c4d57ac..82ca27b7345e 100644
--- a/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/include/clang/Basic/DiagnosticCommonKinds.td
@@ -185,6 +185,8 @@ def note_invalid_subexpr_in_const_expr : Note<
def err_target_unknown_triple : Error<
"unknown target triple '%0', please use -triple or -arch">;
def err_target_unknown_cpu : Error<"unknown target CPU '%0'">;
+def err_target_unsupported_cpu_for_micromips : Error<
+ "micromips is not supported for target CPU '%0'">;
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<
diff --git a/include/clang/Basic/DiagnosticCrossTUKinds.td b/include/clang/Basic/DiagnosticCrossTUKinds.td
new file mode 100644
index 000000000000..8b6d8b681445
--- /dev/null
+++ b/include/clang/Basic/DiagnosticCrossTUKinds.td
@@ -0,0 +1,18 @@
+//==--- DiagnosticCrossTUKinds.td - Cross Translation Unit diagnostics ----===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+let Component = "CrossTU" in {
+
+def err_fnmap_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 ">;
+}
diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td
index fcef881fa0ae..41b5e42b4432 100644
--- a/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/include/clang/Basic/DiagnosticDriverKinds.td
@@ -29,9 +29,10 @@ def err_drv_no_cuda_installation : Error<
def err_drv_no_cuda_libdevice : Error<
"cannot find libdevice for %0. Provide path to different CUDA installation "
"via --cuda-path, or pass -nocudalib to build without linking with libdevice.">;
-def err_drv_cuda_version_too_low : Error<
- "GPU arch %1 requires CUDA version at least %3, but installation at %0 is %2. "
- "Use --cuda-path to specify a different CUDA install, or pass "
+def err_drv_cuda_version_unsupported : Error<
+ "GPU arch %0 is supported by CUDA versions between %1 and %2 (inclusive), "
+ "but installation at %3 is %4. Use --cuda-path to specify a different CUDA "
+ "install, pass a different GPU arch with --cuda-gpu-arch, or pass "
"--no-cuda-version-check.">;
def err_drv_cuda_nvptx_host : Error<"unsupported use of NVPTX for host compilation.">;
def err_drv_invalid_thread_model_for_target : Error<
@@ -69,6 +70,10 @@ def err_drv_invalid_Xarch_argument_with_args : Error<
"invalid Xarch argument: '%0', options requiring arguments are unsupported">;
def err_drv_invalid_Xarch_argument_isdriver : Error<
"invalid Xarch argument: '%0', cannot change driver behavior inside Xarch argument">;
+def err_drv_Xopenmp_target_missing_triple : Error<
+ "cannot deduce implicit triple value for -Xopenmp-target, specify triple using -Xopenmp-target=<triple>">;
+def err_drv_invalid_Xopenmp_target_with_args : Error<
+ "invalid -Xopenmp-target argument: '%0', options requiring arguments are unsupported">;
def err_drv_argument_only_allowed_with : Error<
"invalid argument '%0' only allowed with '%1'">;
def err_drv_argument_not_allowed_with : Error<
@@ -97,6 +102,10 @@ def err_drv_force_crash : Error<
"failing because %select{environment variable 'FORCE_CLANG_DIAGNOSTICS_CRASH' is set|'-gen-reproducer' is used}0">;
def err_drv_invalid_mfloat_abi : Error<
"invalid float ABI '%0'">;
+def err_drv_invalid_mtp : Error<
+ "invalid thread pointer reading mode '%0'">;
+def err_drv_missing_arg_mtp : Error<
+ "missing argument to '%0'">;
def err_drv_invalid_libcxx_deployment : Error<
"invalid deployment target for -stdlib=libc++ (requires %0 or later)">;
def err_drv_invalid_argument_to_fdebug_prefix_map : Error<
@@ -106,6 +115,10 @@ def err_drv_malformed_sanitizer_blacklist : Error<
def err_target_unsupported_arch
: Error<"the target architecture '%0' is not supported by the target '%1'">;
+def err_cpu_unsupported_isa
+ : Error<"CPU '%0' does not support '%1' execution mode">;
+def err_arch_unsupported_isa
+ : Error<"Architecture '%0' does not support '%1' execution mode">;
def err_drv_I_dash_not_supported : Error<
"'%0' not supported, please use -iquote instead">;
@@ -231,7 +244,7 @@ def warn_drv_enabling_rtti_with_exceptions : Warning<
InGroup<DiagGroup<"rtti-for-exceptions">>;
def warn_drv_disabling_vptr_no_rtti_default : Warning<
"implicitly disabling vptr sanitizer because rtti wasn't enabled">,
- InGroup<DiagGroup<"auto-disable-vptr-sanitizer">>;
+ InGroup<AutoDisableVptrSanitizer>;
def warn_drv_object_size_disabled_O0 : Warning<
"the object size sanitizer has no effect at -O0, but is explicitly enabled: %0">,
InGroup<InvalidCommandLineArgument>;
@@ -251,6 +264,9 @@ def err_analyzer_config_no_value : Error<
def err_analyzer_config_multiple_values : Error<
"analyzer-config option '%0' should contain only one '='">;
+def err_drv_invalid_hvx_length : Error<
+ "-mhvx-length is not supported without a -mhvx/-mhvx= flag">;
+
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>'">;
@@ -277,9 +293,27 @@ def warn_target_unsupported_nan2008 : Warning<
def warn_target_unsupported_nanlegacy : Warning<
"ignoring '-mnan=legacy' option because the '%0' architecture does not support it">,
InGroup<UnsupportedNan>;
+def warn_target_unsupported_abslegacy : Warning<
+ "ignoring '-mabs=legacy' option because the '%0' architecture does not support it">,
+ InGroup<UnsupportedAbs>;
+def warn_target_unsupported_abs2008 : Warning<
+ "ignoring '-mabs=2008' option because the '%0' architecture does not support it">,
+ InGroup<UnsupportedAbs>;
def warn_target_unsupported_compact_branches : Warning<
"ignoring '-mcompact-branches=' option because the '%0' architecture does not"
" support it">, InGroup<UnsupportedCB>;
+def warn_drv_unsupported_gpopt : Warning<
+ "ignoring '-mgpopt' option as it cannot be used with %select{|the implicit"
+ " usage of }0-mabicalls">,
+ InGroup<UnsupportedGPOpt>;
+def warn_drv_unsupported_longcalls : Warning<
+ "ignoring '-mlong-calls' option as it is not currently supported with "
+ "%select{|the implicit usage of }0-mabicalls">,
+ InGroup<OptionIgnored>;
+def warn_drv_unsupported_abicalls : Warning<
+ "ignoring '-mabicalls' option as it cannot be used with "
+ "non position-independent code and the N64 ABI">,
+ InGroup<OptionIgnored>;
def warn_drv_unable_to_find_directory_expected : Warning<
"unable to find %0 directory, expected to be in '%1'">,
@@ -300,4 +334,12 @@ def warn_drv_msvc_not_found : Warning<
"unable to find a Visual Studio installation; "
"try running Clang from a developer command prompt">,
InGroup<DiagGroup<"msvc-not-found">>;
+
+def warn_drv_fine_grained_bitfield_accesses_ignored : Warning<
+ "option '-ffine-grained-bitfield-accesses' cannot be enabled together with a sanitizer; flag ignored">,
+ InGroup<OptionIgnored>;
+
+def note_drv_verify_prefix_spelling : Note<
+ "-verify prefixes must start with a letter and contain only alphanumeric"
+ " characters, hyphens, and underscores">;
}
diff --git a/include/clang/Basic/DiagnosticError.h b/include/clang/Basic/DiagnosticError.h
new file mode 100644
index 000000000000..6b4b073736a8
--- /dev/null
+++ b/include/clang/Basic/DiagnosticError.h
@@ -0,0 +1,61 @@
+//===--- DiagnosticError.h - Diagnostic payload for llvm::Error -*- 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_DIAGNOSTIC_ERROR_H
+#define LLVM_CLANG_BASIC_DIAGNOSTIC_ERROR_H
+
+#include "clang/Basic/PartialDiagnostic.h"
+#include "llvm/Support/Error.h"
+
+namespace clang {
+
+/// \brief Carries a Clang diagnostic in an llvm::Error.
+///
+/// Users should emit the stored diagnostic using the DiagnosticsEngine.
+class DiagnosticError : public llvm::ErrorInfo<DiagnosticError> {
+public:
+ DiagnosticError(PartialDiagnosticAt Diag) : Diag(std::move(Diag)) {}
+
+ void log(raw_ostream &OS) const override { OS << "clang diagnostic"; }
+
+ PartialDiagnosticAt &getDiagnostic() { return Diag; }
+ const PartialDiagnosticAt &getDiagnostic() const { return Diag; }
+
+ /// Creates a new \c DiagnosticError that contains the given diagnostic at
+ /// the given location.
+ static llvm::Error create(SourceLocation Loc, PartialDiagnostic Diag) {
+ return llvm::make_error<DiagnosticError>(
+ PartialDiagnosticAt(Loc, std::move(Diag)));
+ }
+
+ /// Extracts and returns the diagnostic payload from the given \c Error if
+ /// the error is a \c DiagnosticError. Returns none if the given error is not
+ /// a \c DiagnosticError.
+ static Optional<PartialDiagnosticAt> take(llvm::Error &Err) {
+ Optional<PartialDiagnosticAt> Result;
+ Err = llvm::handleErrors(std::move(Err), [&](DiagnosticError &E) {
+ Result = std::move(E.getDiagnostic());
+ });
+ return Result;
+ }
+
+ static char ID;
+
+private:
+ // Users are not expected to use error_code.
+ std::error_code convertToErrorCode() const override {
+ return llvm::inconvertibleErrorCode();
+ }
+
+ PartialDiagnosticAt Diag;
+};
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_BASIC_DIAGNOSTIC_ERROR_H
diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td
index 57c24e9be73a..392a340a3bb7 100644
--- a/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -116,6 +116,8 @@ def err_fe_action_not_available : Error<
"action %0 not compiled in">;
def err_fe_invalid_alignment : Error<
"invalid value '%1' in '%0'; alignment must be a power of 2">;
+def err_fe_invalid_wchar_type
+ : Error<"invalid wchar_t type '%0'; must be one of 'char', 'short', 'int'">;
def warn_fe_serialized_diag_merge_failure : Warning<
"unable to merge a subprocess's serialized diagnostics">,
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index 23e4d4633ae2..c23183c81ac8 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -27,11 +27,16 @@ def GNUAnonymousStruct : DiagGroup<"gnu-anonymous-struct">;
def GNUAutoType : DiagGroup<"gnu-auto-type">;
def ArrayBounds : DiagGroup<"array-bounds">;
def ArrayBoundsPointerArithmetic : DiagGroup<"array-bounds-pointer-arithmetic">;
+def AutoDisableVptrSanitizer : DiagGroup<"auto-disable-vptr-sanitizer">;
def Availability : DiagGroup<"availability">;
def Section : DiagGroup<"section">;
def AutoImport : DiagGroup<"auto-import">;
def CXX14BinaryLiteral : DiagGroup<"c++14-binary-literal">;
+def CXXPre14CompatBinaryLiteral : DiagGroup<"c++98-c++11-compat-binary-literal">;
def GNUBinaryLiteral : DiagGroup<"gnu-binary-literal">;
+def BinaryLiteral : DiagGroup<"binary-literal", [CXX14BinaryLiteral,
+ CXXPre14CompatBinaryLiteral,
+ GNUBinaryLiteral]>;
def GNUCompoundLiteralInitializer : DiagGroup<"gnu-compound-literal-initializer">;
def BitFieldConstantConversion : DiagGroup<"bitfield-constant-conversion">;
def BitFieldEnumConversion : DiagGroup<"bitfield-enum-conversion">;
@@ -60,7 +65,9 @@ def FloatConversion :
def DoublePromotion : DiagGroup<"double-promotion">;
def EnumTooLarge : DiagGroup<"enum-too-large">;
def UnsupportedNan : DiagGroup<"unsupported-nan">;
+def UnsupportedAbs : DiagGroup<"unsupported-abs">;
def UnsupportedCB : DiagGroup<"unsupported-cb">;
+def UnsupportedGPOpt : DiagGroup<"unsupported-gpopt">;
def NonLiteralNullConversion : DiagGroup<"non-literal-null-conversion">;
def NullConversion : DiagGroup<"null-conversion">;
def ImplicitConversionFloatingPointToBool :
@@ -87,6 +94,7 @@ def GNUStringLiteralOperatorTemplate :
DiagGroup<"gnu-string-literal-operator-template">;
def UndefinedVarTemplate : DiagGroup<"undefined-var-template">;
def UndefinedFuncTemplate : DiagGroup<"undefined-func-template">;
+def MissingNoEscape : DiagGroup<"missing-noescape">;
def DeleteIncomplete : DiagGroup<"delete-incomplete">;
def DeleteNonVirtualDtor : DiagGroup<"delete-non-virtual-dtor">;
@@ -162,10 +170,14 @@ def NoexceptType : DiagGroup<"noexcept-type", [CXX17CompatMangling]>;
// Warnings for C++1y code which is not compatible with prior C++ standards.
def CXXPre14Compat : DiagGroup<"c++98-c++11-compat">;
def CXXPre14CompatPedantic : DiagGroup<"c++98-c++11-compat-pedantic",
- [CXXPre14Compat]>;
-def CXXPre1zCompat : DiagGroup<"c++98-c++11-c++14-compat">;
-def CXXPre1zCompatPedantic : DiagGroup<"c++98-c++11-c++14-compat-pedantic",
- [CXXPre1zCompat]>;
+ [CXXPre14Compat,
+ CXXPre14CompatBinaryLiteral]>;
+def CXXPre17Compat : DiagGroup<"c++98-c++11-c++14-compat">;
+def CXXPre17CompatPedantic : DiagGroup<"c++98-c++11-c++14-compat-pedantic",
+ [CXXPre17Compat]>;
+def CXXPre2aCompat : DiagGroup<"c++98-c++11-c++14-c++17-compat">;
+def CXXPre2aCompatPedantic : DiagGroup<"c++98-c++11-c++14-c++17-compat-pedantic",
+ [CXXPre2aCompat]>;
def CXX98CompatBindToTemporaryCopy :
DiagGroup<"c++98-compat-bind-to-temporary-copy">;
@@ -178,13 +190,15 @@ def CXX98Compat : DiagGroup<"c++98-compat",
[CXX98CompatLocalTypeTemplateArgs,
CXX98CompatUnnamedTypeTemplateArgs,
CXXPre14Compat,
- CXXPre1zCompat]>;
+ CXXPre17Compat,
+ CXXPre2aCompat]>;
// Warnings for C++11 features which are Extensions in C++98 mode.
def CXX98CompatPedantic : DiagGroup<"c++98-compat-pedantic",
[CXX98Compat,
CXX98CompatBindToTemporaryCopy,
CXXPre14CompatPedantic,
- CXXPre1zCompatPedantic]>;
+ CXXPre17CompatPedantic,
+ CXXPre2aCompatPedantic]>;
def CXX11Narrowing : DiagGroup<"c++11-narrowing">;
@@ -209,21 +223,35 @@ def CXX11Compat : DiagGroup<"c++11-compat",
CXX11CompatReservedUserDefinedLiteral,
CXX11CompatDeprecatedWritableStr,
CXXPre14Compat,
- CXXPre1zCompat]>;
+ CXXPre17Compat,
+ CXXPre2aCompat]>;
def : DiagGroup<"c++0x-compat", [CXX11Compat]>;
def CXX11CompatPedantic : DiagGroup<"c++11-compat-pedantic",
- [CXXPre14CompatPedantic,
- CXXPre1zCompatPedantic]>;
+ [CXX11Compat,
+ CXXPre14CompatPedantic,
+ CXXPre17CompatPedantic,
+ CXXPre2aCompatPedantic]>;
-def CXX14Compat : DiagGroup<"c++14-compat", [CXXPre1zCompat]>;
+def CXX14Compat : DiagGroup<"c++14-compat", [CXXPre17Compat,
+ CXXPre2aCompat]>;
def CXX14CompatPedantic : DiagGroup<"c++14-compat-pedantic",
- [CXXPre1zCompatPedantic]>;
+ [CXX14Compat,
+ CXXPre17CompatPedantic,
+ CXXPre2aCompatPedantic]>;
def CXX17Compat : DiagGroup<"c++17-compat", [DeprecatedRegister,
DeprecatedIncrementBool,
- CXX17CompatMangling]>;
+ CXX17CompatMangling,
+ CXXPre2aCompat]>;
+def CXX17CompatPedantic : DiagGroup<"c++17-compat-pedantic",
+ [CXX17Compat,
+ CXXPre2aCompatPedantic]>;
def : DiagGroup<"c++1z-compat", [CXX17Compat]>;
+def CXX2aCompat : DiagGroup<"c++2a-compat">;
+def CXX2aCompatPedantic : DiagGroup<"c++2a-compat-pedantic",
+ [CXX2aCompat]>;
+
def ExitTimeDestructors : DiagGroup<"exit-time-destructors">;
def FlexibleArrayExtensions : DiagGroup<"flexible-array-extensions">;
def FourByteMultiChar : DiagGroup<"four-char-constants">;
@@ -316,6 +344,7 @@ def NonPODVarargs : DiagGroup<"non-pod-varargs">;
def ClassVarargs : DiagGroup<"class-varargs", [NonPODVarargs]>;
def : DiagGroup<"nonportable-cfstrings">;
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">;
@@ -345,6 +374,7 @@ def ObjCRootClass : DiagGroup<"objc-root-class">;
def ObjCPointerIntrospectPerformSelector : DiagGroup<"deprecated-objc-pointer-introspection-performSelector">;
def ObjCPointerIntrospect : DiagGroup<"deprecated-objc-pointer-introspection", [ObjCPointerIntrospectPerformSelector]>;
def ObjCMultipleMethodNames : DiagGroup<"objc-multiple-method-names">;
+def ObjCFlexibleArray : DiagGroup<"objc-flexible-array">;
def OpenCLUnsupportedRGBA: DiagGroup<"opencl-unsupported-rgba">;
def DeprecatedObjCIsaUsage : DiagGroup<"deprecated-objc-isa-usage">;
def ExplicitInitializeCall : DiagGroup<"explicit-initialize-call">;
@@ -405,12 +435,18 @@ def StringCompare : DiagGroup<"string-compare">;
def StringPlusInt : DiagGroup<"string-plus-int">;
def StringPlusChar : DiagGroup<"string-plus-char">;
def StrncatSize : DiagGroup<"strncat-size">;
+def TautologicalUnsignedZeroCompare : DiagGroup<"tautological-unsigned-zero-compare">;
+def TautologicalUnsignedEnumZeroCompare : DiagGroup<"tautological-unsigned-enum-zero-compare">;
def TautologicalOutOfRangeCompare : DiagGroup<"tautological-constant-out-of-range-compare">;
+def TautologicalConstantCompare : DiagGroup<"tautological-constant-compare",
+ [TautologicalUnsignedZeroCompare,
+ TautologicalUnsignedEnumZeroCompare,
+ TautologicalOutOfRangeCompare]>;
def TautologicalPointerCompare : DiagGroup<"tautological-pointer-compare">;
def TautologicalOverlapCompare : DiagGroup<"tautological-overlap-compare">;
def TautologicalUndefinedCompare : DiagGroup<"tautological-undefined-compare">;
def TautologicalCompare : DiagGroup<"tautological-compare",
- [TautologicalOutOfRangeCompare,
+ [TautologicalConstantCompare,
TautologicalPointerCompare,
TautologicalOverlapCompare,
TautologicalUndefinedCompare]>;
@@ -454,6 +490,8 @@ def CoveredSwitchDefault : DiagGroup<"covered-switch-default">;
def SwitchBool : DiagGroup<"switch-bool">;
def SwitchEnum : DiagGroup<"switch-enum">;
def Switch : DiagGroup<"switch">;
+def EnumCompareSwitch : DiagGroup<"enum-compare-switch">;
+def EnumCompare : DiagGroup<"enum-compare", [EnumCompareSwitch]>;
def ImplicitFallthroughPerFunction :
DiagGroup<"implicit-fallthrough-per-function">;
def ImplicitFallthrough : DiagGroup<"implicit-fallthrough",
@@ -474,10 +512,15 @@ def IgnoredPragmaIntrinsic : DiagGroup<"ignored-pragma-intrinsic">;
def UnknownPragmas : DiagGroup<"unknown-pragmas">;
def IgnoredPragmas : DiagGroup<"ignored-pragmas", [IgnoredPragmaIntrinsic]>;
def PragmaClangAttribute : DiagGroup<"pragma-clang-attribute">;
+def PragmaPackSuspiciousInclude : DiagGroup<"pragma-pack-suspicious-include">;
+def PragmaPack : DiagGroup<"pragma-pack", [PragmaPackSuspiciousInclude]>;
def Pragmas : DiagGroup<"pragmas", [UnknownPragmas, IgnoredPragmas,
- PragmaClangAttribute]>;
+ PragmaClangAttribute, PragmaPack]>;
def UnknownWarningOption : DiagGroup<"unknown-warning-option">;
def NSobjectAttribute : DiagGroup<"NSObject-attribute">;
+def NSConsumedMismatch : DiagGroup<"nsconsumed-mismatch">;
+def NSReturnsMismatch : DiagGroup<"nsreturns-mismatch">;
+
def IndependentClassAttribute : DiagGroup<"IndependentClass-attribute">;
def UnknownAttributes : DiagGroup<"unknown-attributes">;
def IgnoredAttributes : DiagGroup<"ignored-attributes">;
@@ -678,7 +721,8 @@ def Extra : DiagGroup<"extra", [
SemiBeforeMethodBody,
MissingMethodReturnType,
SignCompare,
- UnusedParameter
+ UnusedParameter,
+ NullPointerArithmetic
]>;
def Most : DiagGroup<"most", [
@@ -707,6 +751,7 @@ def Most : DiagGroup<"most", [
VolatileRegisterVar,
ObjCMissingSuperCalls,
ObjCDesignatedInit,
+ ObjCFlexibleArray,
OverloadedVirtual,
PrivateExtern,
SelTypeCast,
@@ -772,10 +817,14 @@ def CXX11 : DiagGroup<"c++11-extensions", [CXX11ExtraSemi, CXX11InlineNamespace,
// earlier C++ versions.
def CXX14 : DiagGroup<"c++14-extensions", [CXX14BinaryLiteral]>;
-// A warning group for warnings about using C++1z features as extensions in
+// A warning group for warnings about using C++17 features as extensions in
// earlier C++ versions.
def CXX17 : DiagGroup<"c++17-extensions">;
+// A warning group for warnings about using C++2a features as extensions in
+// earlier C++ versions.
+def CXX2a : DiagGroup<"c++2a-extensions">;
+
def : DiagGroup<"c++0x-extensions", [CXX11]>;
def : DiagGroup<"c++1y-extensions", [CXX14]>;
def : DiagGroup<"c++1z-extensions", [CXX17]>;
@@ -841,6 +890,7 @@ def MicrosoftVoidPseudoDtor : DiagGroup<"microsoft-void-pseudo-dtor">;
def MicrosoftAnonTag : DiagGroup<"microsoft-anon-tag">;
def MicrosoftCommentPaste : DiagGroup<"microsoft-comment-paste">;
def MicrosoftEndOfFile : DiagGroup<"microsoft-end-of-file">;
+def MicrosoftInaccessibleBase : DiagGroup<"microsoft-inaccessible-base">;
// Aliases.
def : DiagGroup<"msvc-include", [MicrosoftInclude]>;
// -Wmsvc-include = -Wmicrosoft-include
diff --git a/include/clang/Basic/DiagnosticIDs.h b/include/clang/Basic/DiagnosticIDs.h
index cdd358542a0d..43183a120bb9 100644
--- a/include/clang/Basic/DiagnosticIDs.h
+++ b/include/clang/Basic/DiagnosticIDs.h
@@ -26,19 +26,36 @@ namespace clang {
// Import the diagnostic enums themselves.
namespace diag {
+ // Size of each of the diagnostic categories.
+ enum {
+ DIAG_SIZE_COMMON = 300,
+ DIAG_SIZE_DRIVER = 200,
+ DIAG_SIZE_FRONTEND = 100,
+ DIAG_SIZE_SERIALIZATION = 120,
+ DIAG_SIZE_LEX = 400,
+ DIAG_SIZE_PARSE = 500,
+ DIAG_SIZE_AST = 150,
+ DIAG_SIZE_COMMENT = 100,
+ DIAG_SIZE_CROSSTU = 100,
+ DIAG_SIZE_SEMA = 3500,
+ DIAG_SIZE_ANALYSIS = 100,
+ DIAG_SIZE_REFACTORING = 1000,
+ };
// Start position for diagnostics.
enum {
- DIAG_START_COMMON = 0,
- DIAG_START_DRIVER = DIAG_START_COMMON + 300,
- DIAG_START_FRONTEND = DIAG_START_DRIVER + 200,
- DIAG_START_SERIALIZATION = DIAG_START_FRONTEND + 100,
- DIAG_START_LEX = DIAG_START_SERIALIZATION + 120,
- DIAG_START_PARSE = DIAG_START_LEX + 400,
- DIAG_START_AST = DIAG_START_PARSE + 500,
- DIAG_START_COMMENT = DIAG_START_AST + 110,
- DIAG_START_SEMA = DIAG_START_COMMENT + 100,
- DIAG_START_ANALYSIS = DIAG_START_SEMA + 3500,
- DIAG_UPPER_LIMIT = DIAG_START_ANALYSIS + 100
+ DIAG_START_COMMON = 0,
+ DIAG_START_DRIVER = DIAG_START_COMMON + DIAG_SIZE_COMMON,
+ DIAG_START_FRONTEND = DIAG_START_DRIVER + DIAG_SIZE_DRIVER,
+ DIAG_START_SERIALIZATION = DIAG_START_FRONTEND + DIAG_SIZE_FRONTEND,
+ DIAG_START_LEX = DIAG_START_SERIALIZATION + DIAG_SIZE_SERIALIZATION,
+ DIAG_START_PARSE = DIAG_START_LEX + DIAG_SIZE_LEX,
+ DIAG_START_AST = DIAG_START_PARSE + DIAG_SIZE_PARSE,
+ DIAG_START_COMMENT = DIAG_START_AST + DIAG_SIZE_AST,
+ DIAG_START_CROSSTU = DIAG_START_COMMENT + DIAG_SIZE_CROSSTU,
+ DIAG_START_SEMA = DIAG_START_CROSSTU + DIAG_SIZE_COMMENT,
+ DIAG_START_ANALYSIS = DIAG_START_SEMA + DIAG_SIZE_SEMA,
+ DIAG_START_REFACTORING = DIAG_START_ANALYSIS + DIAG_SIZE_ANALYSIS,
+ DIAG_UPPER_LIMIT = DIAG_START_REFACTORING + DIAG_SIZE_REFACTORING
};
class CustomDiagInfo;
@@ -279,8 +296,8 @@ public:
SmallVectorImpl<diag::kind> &Diags) const;
/// \brief Get the set of all diagnostic IDs.
- void getAllDiagnostics(diag::Flavor Flavor,
- SmallVectorImpl<diag::kind> &Diags) const;
+ static void getAllDiagnostics(diag::Flavor Flavor,
+ SmallVectorImpl<diag::kind> &Diags);
/// \brief Get the diagnostic option with the closest edit distance to the
/// given group name.
diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td
index 706881bfdc5d..c664281ffcd4 100644
--- a/include/clang/Basic/DiagnosticLexKinds.td
+++ b/include/clang/Basic/DiagnosticLexKinds.td
@@ -31,6 +31,14 @@ def warn_cxx98_compat_less_colon_colon : Warning<
"'<::' is treated as digraph '<:' (aka '[') followed by ':' in C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
+def warn_cxx17_compat_spaceship : Warning<
+ "'<=>' operator is incompatible with C++ standards before C++2a">,
+ InGroup<CXXPre2aCompat>, DefaultIgnore;
+def warn_cxx2a_compat_spaceship : Warning<
+ "'<=>' is a single token in C++2a; "
+ "add a space to avoid a change in behavior">,
+ InGroup<CXX2aCompat>;
+
// Trigraphs.
def trigraph_ignored : Warning<"trigraph ignored">, InGroup<Trigraphs>;
def trigraph_ignored_block_comment : Warning<
@@ -71,6 +79,8 @@ def ext_token_used : Extension<"extension used">,
def warn_cxx11_keyword : Warning<"'%0' is a keyword in C++11">,
InGroup<CXX11Compat>, DefaultIgnore;
+def warn_cxx2a_keyword : Warning<"'%0' is a keyword in C++2a">,
+ InGroup<CXX2aCompat>, DefaultIgnore;
def ext_unterminated_char_or_string : ExtWarn<
"missing terminating %select{'|'\"'}0 character">, InGroup<InvalidPPToken>;
@@ -109,6 +119,9 @@ def err_non_ascii : Error<
def ext_unicode_whitespace : ExtWarn<
"treating Unicode character as whitespace">,
InGroup<DiagGroup<"unicode-whitespace">>;
+def warn_utf8_symbol_homoglyph : Warning<
+ "treating Unicode character <U+%0> as identifier character rather than "
+ "as '%1' symbol">, InGroup<DiagGroup<"unicode-homoglyph">>;
def err_hex_escape_no_digits : Error<
"\\%0 used with no following hex digits">;
@@ -173,8 +186,6 @@ def warn_char_constant_too_large : Warning<
def err_multichar_utf_character_literal : Error<
"Unicode character literals may not contain multiple characters">;
def err_exponent_has_no_digits : Error<"exponent has no digits">;
-def ext_imaginary_constant : Extension<
- "imaginary constants are a GNU extension">, InGroup<GNUImaginaryConstant>;
def err_hex_constant_requires : Error<
"hexadecimal floating %select{constant|literal}0 requires "
"%select{an exponent|a significand}1">;
@@ -182,17 +193,17 @@ def ext_hex_constant_invalid : Extension<
"hexadecimal floating constants are a C99 feature">, InGroup<C99>;
def ext_hex_literal_invalid : Extension<
"hexadecimal floating literals are a C++17 feature">, InGroup<CXX17>;
-def warn_cxx1z_hex_literal : Warning<
+def warn_cxx17_hex_literal : Warning<
"hexadecimal floating literals are incompatible with "
"C++ standards before C++17">,
- InGroup<CXXPre1zCompatPedantic>, DefaultIgnore;
+ InGroup<CXXPre17CompatPedantic>, DefaultIgnore;
def ext_binary_literal : Extension<
"binary integer literals are a GNU extension">, InGroup<GNUBinaryLiteral>;
def ext_binary_literal_cxx14 : Extension<
"binary integer literals are a C++14 extension">, InGroup<CXX14BinaryLiteral>;
def warn_cxx11_compat_binary_literal : Warning<
"binary integer literals are incompatible with C++ standards before C++14">,
- InGroup<CXXPre14CompatPedantic>, DefaultIgnore;
+ InGroup<CXXPre14CompatBinaryLiteral>, DefaultIgnore;
def err_pascal_string_too_long : Error<"Pascal string is too long">;
def err_escape_too_large : Error<
"%select{hex|octal}0 escape sequence out of range">;
@@ -209,7 +220,7 @@ def warn_cxx98_compat_unicode_literal : Warning<
InGroup<CXX98Compat>, DefaultIgnore;
def warn_cxx14_compat_u8_character_literal : Warning<
"unicode literals are incompatible with C++ standards before C++17">,
- InGroup<CXXPre1zCompat>, DefaultIgnore;
+ InGroup<CXXPre17Compat>, DefaultIgnore;
def warn_cxx11_compat_user_defined_literal : Warning<
"identifier after literal will be treated as a user-defined literal suffix "
"in C++11">, InGroup<CXX11Compat>, DefaultIgnore;
@@ -346,6 +357,23 @@ def ext_pp_extra_tokens_at_eol : ExtWarn<
def ext_pp_comma_expr : Extension<"comma operator in operand of #if">;
def ext_pp_bad_vaargs_use : Extension<
"__VA_ARGS__ can only appear in the expansion of a C99 variadic macro">;
+
+def ext_pp_bad_vaopt_use
+ : ExtWarn<
+ "__VA_OPT__ can only appear in the expansion of a variadic macro">,
+ InGroup<VariadicMacros>;
+
+def err_pp_missing_lparen_in_vaopt_use : Error<
+ "missing '(' following __VA_OPT__">;
+def err_pp_vaopt_nested_use : Error<
+ "__VA_OPT__ cannot be nested within its own replacement tokens">;
+
+def err_vaopt_paste_at_start : Error<
+ "'##' cannot appear at start of __VA_OPT__ argument">;
+
+def err_vaopt_paste_at_end
+ : Error<"'##' cannot appear at end of __VA_OPT__ argument">;
+
def ext_pp_macro_redef : ExtWarn<"%0 macro redefined">, InGroup<MacroRedefined>;
def ext_variadic_macro : Extension<"variadic macros are a C99 feature">,
InGroup<VariadicMacros>;
@@ -674,6 +702,13 @@ def err_mmap_invalid_header_attribute_value : Error<
"expected integer literal as value for header attribute '%0'">;
def err_mmap_expected_header_attribute : Error<
"expected a header attribute name ('size' or 'mtime')">;
+def err_mmap_conflicting_export_as : Error<
+ "conflicting re-export of module '%0' as '%1' or '%2'">;
+def warn_mmap_redundant_export_as : Warning<
+ "module '%0' already re-exported as '%1'">,
+ InGroup<PrivateModule>;
+def err_mmap_submodule_export_as : Error<
+ "only top-level modules can be re-exported as public">;
def warn_auto_module_import : Warning<
"treating #%select{include|import|include_next|__include_macros}0 as an "
diff --git a/include/clang/Basic/DiagnosticOptions.h b/include/clang/Basic/DiagnosticOptions.h
index c195003de5c4..3844eb63f0ea 100644
--- a/include/clang/Basic/DiagnosticOptions.h
+++ b/include/clang/Basic/DiagnosticOptions.h
@@ -100,6 +100,10 @@ public:
/// prefixes removed.
std::vector<std::string> Remarks;
+ /// The prefixes for comment directives sought by -verify ("expected" by
+ /// default).
+ std::vector<std::string> VerifyPrefixes;
+
public:
// Define accessors/mutators for diagnostic options of enumeration type.
#define DIAGOPT(Name, Bits, Default)
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index 5170c07bf666..a8d6955da3c0 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -215,7 +215,7 @@ def ext_nested_namespace_definition : ExtWarn<
"define each namespace separately">, InGroup<CXX17>;
def warn_cxx14_compat_nested_namespace_definition : Warning<
"nested namespace definition is incompatible with C++ standards before C++17">,
- InGroup<CXXPre1zCompat>, DefaultIgnore;
+ InGroup<CXXPre17Compat>, DefaultIgnore;
def err_inline_nested_namespace_definition : Error<
"nested namespace definition cannot be 'inline'">;
def err_expected_semi_after_attribute_list : Error<
@@ -525,13 +525,13 @@ def ext_constexpr_if : ExtWarn<
"constexpr if is a C++17 extension">, InGroup<CXX17>;
def warn_cxx14_compat_constexpr_if : Warning<
"constexpr if is incompatible with C++ standards before C++17">,
- DefaultIgnore, InGroup<CXXPre1zCompat>;
+ DefaultIgnore, InGroup<CXXPre17Compat>;
def ext_init_statement : ExtWarn<
"'%select{if|switch}0' initialization statements are a C++17 extension">,
InGroup<CXX17>;
def warn_cxx14_compat_init_statement : Warning<
"%select{if|switch}0 initialization statements are incompatible with "
- "C++ standards before C++17">, DefaultIgnore, InGroup<CXXPre1zCompat>;
+ "C++ standards before C++17">, DefaultIgnore, InGroup<CXXPre17Compat>;
// C++ derived classes
def err_dup_virtual : Error<"duplicate 'virtual' in base specifier">;
@@ -558,10 +558,13 @@ def warn_cxx98_compat_noexcept_expr : Warning<
def warn_cxx98_compat_nullptr : Warning<
"'nullptr' is incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore;
-def warn_cxx14_compat_attribute : Warning<
+def ext_ns_enum_attribute : Extension<
+ "attributes on %select{a namespace|an enumerator}0 declaration are "
+ "a C++17 extension">, InGroup<CXX17>;
+def warn_cxx14_compat_ns_enum_attribute : Warning<
"attributes on %select{a namespace|an enumerator}0 declaration are "
"incompatible with C++ standards before C++17">,
- InGroup<CXXPre1zCompat>, DefaultIgnore;
+ InGroup<CXXPre17CompatPedantic>, DefaultIgnore;
def warn_cxx98_compat_alignas : Warning<"'alignas' is incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
def warn_cxx98_compat_attribute : Warning<
@@ -577,7 +580,7 @@ def err_cxx11_attribute_repeated : Error<
"attribute %0 cannot appear multiple times in an attribute specifier">;
def warn_cxx14_compat_using_attribute_ns : Warning<
"default scope specifier for attributes is incompatible with C++ standards "
- "before C++17">, InGroup<CXXPre1zCompat>, DefaultIgnore;
+ "before C++17">, InGroup<CXXPre17Compat>, DefaultIgnore;
def ext_using_attribute_ns : ExtWarn<
"default scope specifier for attributes is a C++17 extension">,
InGroup<CXX17>;
@@ -622,7 +625,7 @@ def ext_template_template_param_typename : ExtWarn<
def warn_cxx14_compat_template_template_param_typename : Warning<
"template template parameter using 'typename' is "
"incompatible with C++ standards before C++17">,
- InGroup<CXXPre1zCompat>, DefaultIgnore;
+ InGroup<CXXPre17Compat>, DefaultIgnore;
def err_template_spec_syntax_non_template : Error<
"identifier followed by '<' indicates a class template specialization but "
"%0 %select{does not refer to a template|refers to a function template|"
@@ -699,7 +702,7 @@ def ext_fold_expression : ExtWarn<
InGroup<CXX17>;
def warn_cxx14_compat_fold_expression : Warning<
"pack fold expression is incompatible with C++ standards before C++17">,
- InGroup<CXXPre1zCompat>, DefaultIgnore;
+ InGroup<CXXPre17Compat>, DefaultIgnore;
def err_expected_fold_operator : Error<
"expected a foldable binary operator in fold expression">;
def err_fold_operator_mismatch : Error<
@@ -730,8 +733,12 @@ def ext_nonstatic_member_init : ExtWarn<
def warn_cxx98_compat_nonstatic_member_init : Warning<
"in-class initialization of non-static data members is incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
-def err_bitfield_member_init: Error<
- "bit-field member cannot have an in-class initializer">;
+def ext_bitfield_member_init: ExtWarn<
+ "default member initializer for bit-field is a C++2a extension">,
+ InGroup<CXX2a>;
+def warn_cxx17_compat_bitfield_member_init: Warning<
+ "default member initializer for bit-field is incompatible with "
+ "C++ standards before C++2a">, InGroup<CXXPre2aCompat>, DefaultIgnore;
def err_incomplete_array_member_init: Error<
"array bound cannot be deduced from an in-class initializer">;
@@ -748,19 +755,19 @@ def err_alias_declaration_specialization : Error<
def err_alias_declaration_pack_expansion : Error<
"alias declaration cannot be a pack expansion">;
-// C++1z using-declaration pack expansions
+// C++17 using-declaration pack expansions
def ext_multi_using_declaration : ExtWarn<
"use of multiple declarators in a single using declaration is "
"a C++17 extension">, InGroup<CXX17>;
-def warn_cxx1z_compat_multi_using_declaration : Warning<
+def warn_cxx17_compat_multi_using_declaration : Warning<
"use of multiple declarators in a single using declaration is "
"incompatible with C++ standards before C++17">,
- InGroup<CXXPre1zCompat>, DefaultIgnore;
+ InGroup<CXXPre17Compat>, DefaultIgnore;
def ext_using_declaration_pack : ExtWarn<
"pack expansion of using declaration is a C++17 extension">, InGroup<CXX17>;
-def warn_cxx1z_compat_using_declaration_pack : Warning<
+def warn_cxx17_compat_using_declaration_pack : Warning<
"pack expansion using declaration is incompatible with C++ standards "
- "before C++17">, InGroup<CXXPre1zCompat>, DefaultIgnore;
+ "before C++17">, InGroup<CXXPre17Compat>, DefaultIgnore;
// C++11 override control
def ext_override_control_keyword : ExtWarn<
@@ -811,15 +818,15 @@ def err_lambda_missing_parens : Error<
"attribute specifier|'constexpr'}0">;
def err_lambda_decl_specifier_repeated : Error<
"%select{'mutable'|'constexpr'}0 cannot appear multiple times in a lambda declarator">;
-// C++1z lambda expressions
+// C++17 lambda expressions
def err_expected_star_this_capture : Error<
"expected 'this' following '*' in lambda capture list">;
-// C++1z constexpr lambda expressions
+// C++17 constexpr lambda expressions
def warn_cxx14_compat_constexpr_on_lambda : Warning<
"constexpr on lambda expressions is incompatible with C++ standards before C++17">,
- InGroup<CXXPre1zCompat>, DefaultIgnore;
-def ext_constexpr_on_lambda_cxx1z : ExtWarn<
+ InGroup<CXXPre17Compat>, DefaultIgnore;
+def ext_constexpr_on_lambda_cxx17 : ExtWarn<
"'constexpr' on lambda expressions is a C++17 extension">, InGroup<CXX17>;
// Availability attribute
@@ -893,8 +900,6 @@ def err_pragma_expected_clang_section_name : Error<
"expected one of [bss|data|rodata|text] section kind in '#pragma %0'">;
def err_pragma_clang_section_expected_equal : Error<
"expected '=' following '#pragma clang section %select{invalid|bss|data|rodata|text}0'">;
-def err_pragma_clang_section_expected_name_or_clear : Error<
- "expected section name or '\"\"' following '#pragma clang section %select{invalid|bss|data|rodata|text}0'">;
def warn_pragma_expected_section_name : Warning<
"expected a string literal for the section name in '#pragma %0' - ignored">,
InGroup<IgnoredPragmas>;
diff --git a/include/clang/Basic/DiagnosticRefactoringKinds.td b/include/clang/Basic/DiagnosticRefactoringKinds.td
new file mode 100644
index 000000000000..ee396b930729
--- /dev/null
+++ b/include/clang/Basic/DiagnosticRefactoringKinds.td
@@ -0,0 +1,34 @@
+//==--- DiagnosticRefactoringKinds.td - refactoring diagnostics -----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Refactoring Diagnostics
+//===----------------------------------------------------------------------===//
+
+let Component = "Refactoring" in {
+
+let CategoryName = "Refactoring Invocation Issue" in {
+
+def err_refactor_no_selection : Error<"refactoring action can't be initiated "
+ "without a selection">;
+def err_refactor_selection_no_symbol : Error<"there is no symbol at the given "
+ "location">;
+def err_refactor_selection_invalid_ast : Error<"the provided selection does "
+ "not overlap with the AST nodes of interest">;
+
+def err_refactor_code_outside_of_function : Error<"the selected code is not a "
+ "part of a function's / method's body">;
+def err_refactor_extract_simple_expression : Error<"the selected expression "
+ "is too simple to extract">;
+def err_refactor_extract_prohibited_expression : Error<"the selected "
+ "expression can't be extracted">;
+
+}
+
+} // end of Refactoring diagnostics
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 8dc6e7b460e8..29236eab5446 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -141,6 +141,10 @@ def err_vla_decl_has_extern_linkage : Error<
"variable length array declaration cannot have 'extern' linkage">;
def ext_vla_folded_to_constant : Extension<
"variable length array folded to constant array as an extension">, InGroup<GNUFoldingConstant>;
+def err_vla_unsupported : Error<
+ "variable length arrays are not supported for the current target">;
+def note_vla_unsupported : Note<
+ "variable length arrays are not supported for the current target">;
// C99 variably modified types
def err_variably_modified_template_arg : Error<
@@ -194,6 +198,8 @@ 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<
+ "imaginary constants are a GNU extension">, InGroup<GNUImaginaryConstant>;
def ext_integer_complex : Extension<
"complex integer types are a GNU extension">, InGroup<GNUComplexInteger>;
@@ -293,8 +299,20 @@ def warn_empty_parens_are_function_decl : Warning<
def warn_parens_disambiguated_as_function_declaration : Warning<
"parentheses were disambiguated as a function declaration">,
InGroup<VexingParse>;
+def warn_parens_disambiguated_as_variable_declaration : Warning<
+ "parentheses were disambiguated as redundant parentheses around declaration "
+ "of variable named %0">, InGroup<VexingParse>;
+def warn_redundant_parens_around_declarator : Warning<
+ "redundant parentheses surrounding declarator">,
+ InGroup<DiagGroup<"redundant-parens">>, DefaultIgnore;
def note_additional_parens_for_variable_declaration : Note<
"add a pair of parentheses to declare a variable">;
+def note_raii_guard_add_name : Note<
+ "add a variable name to declare a %0 initialized with %1">;
+def note_function_style_cast_add_parentheses : Note<
+ "add enclosing parentheses to perform a function-style cast">;
+def note_remove_parens_for_variable_declaration : Note<
+ "remove parentheses to silence this warning">;
def note_empty_parens_function_call : Note<
"change this ',' to a ';' to call %0">;
def note_empty_parens_default_ctor : Note<
@@ -341,7 +359,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 C99">,
+ "implicit declaration of function %0 is invalid in %select{C99|OpenCL}1">,
InGroup<ImplicitFunctionDeclare>;
def note_function_suggestion : Note<"did you mean %0?">;
@@ -352,8 +370,10 @@ def err_language_linkage_spec_unknown : Error<"unknown linkage language">;
def err_language_linkage_spec_not_ascii : Error<
"string literal in language linkage specifier cannot have an "
"encoding-prefix">;
-def warn_use_out_of_scope_declaration : Warning<
- "use of out-of-scope declaration of %0">;
+def ext_use_out_of_scope_declaration : ExtWarn<
+ "use of out-of-scope declaration of %0%select{| whose type is not "
+ "compatible with that of an implicit declaration}1">,
+ InGroup<DiagGroup<"out-of-scope-function">>;
def err_inline_non_function : Error<
"'inline' can only appear on functions%select{| and non-local variables}0">;
def err_noreturn_non_function : Error<
@@ -391,9 +411,12 @@ def err_decomp_decl_context : Error<
"decomposition declaration not permitted in this context">;
def warn_cxx14_compat_decomp_decl : Warning<
"decomposition declarations are incompatible with "
- "C++ standards before C++17">, DefaultIgnore, InGroup<CXXPre1zCompat>;
+ "C++ standards before C++17">, DefaultIgnore, InGroup<CXXPre17Compat>;
def ext_decomp_decl : ExtWarn<
"decomposition declarations are a C++17 extension">, InGroup<CXX17>;
+def ext_decomp_decl_cond : ExtWarn<
+ "ISO C++17 does not permit structured binding declaration in a condition">,
+ InGroup<DiagGroup<"binding-in-condition">>;
def err_decomp_decl_spec : Error<
"decomposition declaration cannot be declared "
"%plural{1:'%1'|:with '%1' specifiers}0">;
@@ -505,7 +528,7 @@ def warn_deprecated_copy_operation : Warning<
"for %0 is deprecated because it has a user-declared "
"%select{copy %select{assignment operator|constructor}1|destructor}2">,
InGroup<Deprecated>, DefaultIgnore;
-def warn_cxx1z_compat_exception_spec_in_signature : Warning<
+def warn_cxx17_compat_exception_spec_in_signature : Warning<
"mangled name of %0 will change in C++17 due to non-throwing exception "
"specification in function signature">, InGroup<CXX17CompatMangling>;
@@ -581,6 +604,7 @@ def warn_redecl_library_builtin : Warning<
def err_builtin_definition : Error<"definition of builtin function %0">;
def err_arm_invalid_specialreg : Error<"invalid special register for builtin">;
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_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 "
@@ -712,6 +736,19 @@ def err_pragma_options_align_mac68k_target_unsupported : Error<
def warn_pragma_pack_invalid_alignment : Warning<
"expected #pragma pack parameter to be '1', '2', '4', '8', or '16'">,
InGroup<IgnoredPragmas>;
+def warn_pragma_pack_non_default_at_include : Warning<
+ "non-default #pragma pack value changes the alignment of struct or union "
+ "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 "
+ "file">, InGroup<PragmaPack>;
+def warn_pragma_pack_no_pop_eof : Warning<"unterminated "
+ "'#pragma pack (push, ...)' at end of file">, InGroup<PragmaPack>;
+def note_pragma_pack_here : Note<
+ "previous '#pragma pack' directive that modifies alignment is here">;
+def note_pragma_pack_pop_instead_reset : Note<
+ "did you intend to use '#pragma pack (pop)' instead of '#pragma pack()'?">;
// Follow the Microsoft implementation.
def warn_pragma_pack_show : Warning<"value of #pragma pack(show) == %0">;
def warn_pragma_pack_pop_identifer_and_alignment : Warning<
@@ -1195,21 +1232,27 @@ def err_objc_method_unsupported_param_ret_type : Error<
"%0 %select{parameter|return}1 type is unsupported; "
"support for vector types for this target is introduced in %2">;
+def warn_messaging_unqualified_id : Warning<
+ "messaging unqualified id">, DefaultIgnore,
+ InGroup<DiagGroup<"objc-messaging-id">>;
+
// C++ declarations
def err_static_assert_expression_is_not_constant : Error<
"static_assert expression is not an integral constant expression">;
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<CXXPre1zCompat>;
+ DefaultIgnore, InGroup<CXXPre17Compat>;
def ext_inline_variable : ExtWarn<
"inline variables are a C++17 extension">, InGroup<CXX17>;
def warn_cxx14_compat_inline_variable : Warning<
"inline variables are incompatible with C++ standards before C++17">,
- DefaultIgnore, InGroup<CXXPre1zCompat>;
+ DefaultIgnore, InGroup<CXXPre17Compat>;
def warn_inline_namespace_reopened_noninline : Warning<
"inline namespace reopened as a non-inline namespace">;
@@ -1313,6 +1356,8 @@ def err_type_defined_in_alias_template : Error<
"%0 cannot be defined in a type alias template">;
def err_type_defined_in_condition : Error<
"%0 cannot be defined in a condition">;
+def err_type_defined_in_enum : Error<
+ "%0 cannot be defined in an enumeration">;
def note_pure_virtual_function : Note<
"unimplemented pure virtual method %0 in %1">;
@@ -1637,6 +1682,11 @@ def err_conflicting_overriding_cc_attributes : Error<
"virtual function %0 has different calling convention attributes "
"%diff{($) than the function it overrides (which has calling convention $)|"
"than the function it overrides}1,2">;
+def warn_overriding_method_missing_noescape : Warning<
+ "parameter of overriding method should be annotated with "
+ "__attribute__((noescape))">, InGroup<MissingNoEscape>;
+def note_overridden_marked_noescape : Note<
+ "parameter of overridden method is annotated with __attribute__((noescape))">;
def err_covariant_return_inaccessible_base : Error<
"invalid covariant return for virtual function: %1 is a "
@@ -1938,8 +1988,9 @@ def err_auto_var_requires_init : Error<
"declaration of variable %0 with deduced type %1 requires an initializer">;
def err_auto_new_requires_ctor_arg : Error<
"new expression for type %0 requires a constructor argument">;
-def err_auto_new_list_init : Error<
- "new expression for type %0 cannot use list-initialization">;
+def ext_auto_new_list_init : Extension<
+ "ISO C++ standards before C++17 do not allow new expression for "
+ "type %0 to use list-initialization">, InGroup<CXX17>;
def err_auto_var_init_no_expression : Error<
"initializer for variable %0 with type %1 is empty">;
def err_auto_var_init_multiple_expressions : Error<
@@ -1964,6 +2015,9 @@ def err_auto_var_deduction_failure_from_init_list : Error<
"cannot deduce actual type for variable %0 with type %1 from initializer list">;
def err_auto_new_deduction_failure : Error<
"new expression for type %0 has incompatible constructor argument of type %1">;
+def err_auto_inconsistent_deduction : Error<
+ "deduced conflicting types %diff{($ vs $) |}0,1"
+ "for initializer list element type">;
def err_auto_different_deductions : Error<
"%select{'auto'|'decltype(auto)'|'__auto_type'|template arguments}0 "
"deduced as %1 in declaration of %2 and "
@@ -1999,7 +2053,7 @@ def err_decltype_auto_compound_type : Error<
def err_decltype_auto_initializer_list : Error<
"cannot deduce 'decltype(auto)' from initializer list">;
-// C++1z deduced class template specialization types
+// C++17 deduced class template specialization types
def err_deduced_class_template_compound_type : Error<
"cannot %select{form pointer to|form reference to|form array of|"
"form function returning|use parentheses when declaring variable with}0 "
@@ -2151,7 +2205,7 @@ def ext_for_range_begin_end_types_differ : ExtWarn<
InGroup<CXX17>;
def warn_for_range_begin_end_types_differ : Warning<
"'begin' and 'end' returning different types (%0 and %1) is incompatible "
- "with C++ standards before C++17">, InGroup<CXXPre1zCompat>, DefaultIgnore;
+ "with C++ standards before C++17">, InGroup<CXXPre17Compat>, DefaultIgnore;
def note_in_for_range: Note<
"when looking up '%select{begin|end}0' function for range expression "
"of type %1">;
@@ -2387,8 +2441,9 @@ def err_attribute_requires_positive_integer : Error<
def err_attribute_requires_opencl_version : Error<
"%0 attribute requires OpenCL version %1%select{| or above}2">;
def warn_unsupported_target_attribute
- : Warning<"Ignoring unsupported '%0' in the target attribute string">,
- InGroup<IgnoredAttributes>;
+ : Warning<"ignoring %select{unsupported|duplicate}0"
+ "%select{| architecture}1 '%2' in the target attribute string">,
+ InGroup<IgnoredAttributes>;
def err_attribute_unsupported
: Error<"%0 attribute is not supported for this target">;
// The err_*_attribute_argument_not_int are separate because they're used by
@@ -2587,6 +2642,8 @@ def err_attribute_section_invalid_for_target : Error<
"argument to 'section' attribute is not valid for this target: %0">;
def warn_mismatched_section : Warning<
"section does not match previous declaration">, InGroup<Section>;
+def warn_attribute_section_on_redeclaration : Warning<
+ "section attribute is specified on redeclared variable">, InGroup<Section>;
def err_anonymous_property: Error<
"anonymous property is not supported">;
@@ -2729,7 +2786,7 @@ def err_attribute_weakref_not_global_context : Error<
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 <
- "only weak aliases are supported on darwin">;
+ "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<
@@ -2746,55 +2803,26 @@ 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<
+ warn_attribute_wrong_decl_type_str.Text>;
def warn_attribute_wrong_decl_type : Warning<
"%0 attribute only applies to %select{"
"functions"
"|unions"
"|variables and functions"
- "|functions and global variables"
- "|functions, variables, and Objective-C interfaces"
"|functions and methods"
- "|parameters"
"|functions, methods and blocks"
- "|functions, methods, and classes"
"|functions, methods, and parameters"
- "|functions, methods, and global variables"
- "|classes"
- "|enums"
"|variables"
- "|methods"
- "|fields and global variables"
- "|structs"
- "|parameters and typedefs"
- "|variables and typedefs"
- "|thread-local variables"
"|variables and fields"
"|variables, data members and tag types"
"|types and namespaces"
- "|Objective-C interfaces"
- "|methods and properties"
- "|functions, methods, and properties"
- "|struct or union"
- "|struct, union or class"
- "|types"
- "|Objective-C instance methods"
- "|init methods of interface or class extension declarations"
"|variables, functions and classes"
- "|functions, variables, classes, and Objective-C interfaces"
- "|Objective-C protocols"
- "|variables with static or thread storage duration"
- "|functions, methods, properties, and global variables"
- "|structs, unions, and typedefs"
- "|structs and typedefs"
- "|interface or protocol declarations"
"|kernel functions"
"|non-K&R-style functions"
- "|variables, enums, fields and typedefs"
- "|functions, methods, enums, and classes"
- "|structs, classes, variables, functions, and inline namespaces"
- "|variables, functions, methods, types, enumerations, enumerators, labels, and non-static data members"
- "|classes and enumerations"
- "|named declarations}1">,
+ "|variables, functions, methods, types, enumerations, enumerators, labels, and non-static data members}1">,
InGroup<IgnoredAttributes>;
def err_attribute_wrong_decl_type : Error<warn_attribute_wrong_decl_type.Text>;
def warn_type_attribute_wrong_type : Warning<
@@ -2879,25 +2907,11 @@ def warn_unguarded_availability :
def warn_unguarded_availability_new :
Warning<warn_unguarded_availability.Text>,
InGroup<UnguardedAvailabilityNew>;
-def warn_partial_availability : Warning<"%0 is only available conditionally">,
- InGroup<UnguardedAvailability>, DefaultIgnore;
-def warn_partial_availability_new : Warning<warn_partial_availability.Text>,
- InGroup<UnguardedAvailabilityNew>;
-def note_partial_availability_silence : Note<
- "annotate %select{%1|anonymous %1}0 with an availability attribute to silence">;
+def note_decl_unguarded_availability_silence : Note<
+ "annotate %select{%1|anonymous %1}0 with an availability attribute to silence this warning">;
def note_unguarded_available_silence : Note<
"enclose %0 in %select{an @available|a __builtin_available}1 check to silence"
" this warning">;
-def warn_partial_message : Warning<"%0 is partial: %1">,
- InGroup<UnguardedAvailability>, DefaultIgnore;
-def warn_partial_message_new : Warning<warn_partial_message.Text>,
- InGroup<UnguardedAvailabilityNew>;
-def warn_partial_fwdclass_message : Warning<
- "%0 may be partial because the receiver type is unknown">,
- InGroup<UnguardedAvailability>, DefaultIgnore;
-def warn_partial_fwdclass_message_new :
- Warning<warn_partial_fwdclass_message.Text>,
- InGroup<UnguardedAvailabilityNew>;
def warn_at_available_unchecked_use : Warning<
"%select{@available|__builtin_available}0 does not guard availability here; "
"use if (%select{@available|__builtin_available}0) instead">,
@@ -3063,6 +3077,8 @@ def warn_impcast_vector_scalar : Warning<
def warn_impcast_complex_scalar : Warning<
"implicit conversion discards imaginary component: %0 to %1">,
InGroup<Conversion>, DefaultIgnore;
+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;
@@ -3188,6 +3204,9 @@ def warn_int_to_void_pointer_cast : Warning<
"cast to %1 from smaller integer type %0">,
InGroup<IntToVoidPointerCast>;
+def warn_attribute_ignored_for_field_of_type : Warning<
+ "%0 attribute ignored for field of type %1">,
+ InGroup<IgnoredAttributes>;
def warn_no_underlying_type_specified_for_enum_bitfield : Warning<
"enums in the Microsoft ABI are signed integers by default; consider giving "
"the enum %0 an unsigned underlying type to make this code portable">,
@@ -3906,7 +3925,7 @@ def err_template_nontype_parm_bad_type : Error<
def warn_cxx14_compat_template_nontype_parm_auto_type : Warning<
"non-type template parameters declared with %0 are incompatible with C++ "
"standards before C++17">,
- DefaultIgnore, InGroup<CXXPre1zCompat>;
+ DefaultIgnore, InGroup<CXXPre17Compat>;
def err_template_param_default_arg_redefinition : Error<
"template parameter redefines default argument">;
def note_template_param_prev_default_arg : Note<
@@ -4080,6 +4099,13 @@ def err_pointer_to_member_call_drops_quals : Error<
def err_pointer_to_member_oper_value_classify: Error<
"pointer-to-member function type %0 can only be called on an "
"%select{rvalue|lvalue}1">;
+def ext_pointer_to_const_ref_member_on_rvalue : Extension<
+ "invoking a pointer to a 'const &' member function on an rvalue is a C++2a extension">,
+ InGroup<CXX2a>, SFINAEFailure;
+def warn_cxx17_compat_pointer_to_const_ref_member_on_rvalue : Warning<
+ "invoking a pointer to a 'const &' member function on an rvalue is "
+ "incompatible with C++ standards before C++2a">,
+ InGroup<CXXPre2aCompatPedantic>, DefaultIgnore;
def ext_ms_deref_template_argument: ExtWarn<
"non-type template argument containing a dereference operation is a "
"Microsoft extension">, InGroup<MicrosoftTemplate>;
@@ -4681,6 +4707,14 @@ def note_deleted_assign_field : Note<
def warn_undefined_internal : Warning<
"%select{function|variable}0 %q1 has internal linkage but is not defined">,
InGroup<DiagGroup<"undefined-internal">>;
+def err_undefined_internal_type : Error<
+ "%select{function|variable}0 %q1 is used but not defined in this "
+ "translation unit, and cannot be defined in any other translation unit "
+ "because its type does not have linkage">;
+def ext_undefined_internal_type : Extension<
+ "ISO C++ requires a definition in this translation unit for "
+ "%select{function|variable}0 %q1 because its type does not have linkage">,
+ InGroup<DiagGroup<"undefined-internal-type">>;
def warn_undefined_inline : Warning<"inline function %q0 is not defined">,
InGroup<DiagGroup<"undefined-inline">>;
def err_undefined_inline_var : Error<"inline variable %q0 is not defined">;
@@ -4746,6 +4780,9 @@ def err_thread_non_thread : Error<
def err_thread_thread_different_kind : Error<
"thread-local declaration of %0 with %select{static|dynamic}1 initialization "
"follows declaration with %select{dynamic|static}1 initialization">;
+def err_mismatched_owning_module : Error<
+ "declaration of %0 in %select{the global module|module %2}1 follows "
+ "declaration in %select{the global module|module %4}3">;
def err_redefinition_different_type : Error<
"redefinition of %0 with a different type%diff{: $ vs $|}1,2">;
def err_redefinition_different_kind : Error<
@@ -5164,6 +5201,28 @@ def ext_flexible_array_empty_aggregate_gnu : Extension<
def ext_flexible_array_union_gnu : Extension<
"flexible array member %0 in a union is a GNU extension">, InGroup<GNUFlexibleArrayUnionMember>;
+def err_flexible_array_not_at_end : Error<
+ "flexible array member %0 with type %1 is not at the end of"
+ " %select{struct|interface|union|class|enum}2">;
+def err_objc_variable_sized_type_not_at_end : Error<
+ "field %0 with variable sized type %1 is not at the end of class">;
+def note_next_field_declaration : Note<
+ "next field declaration is here">;
+def note_next_ivar_declaration : Note<
+ "next %select{instance variable declaration|synthesized instance variable}0"
+ " is here">;
+def err_synthesize_variable_sized_ivar : Error<
+ "synthesized property with variable size type %0"
+ " requires an existing instance variable">;
+def err_flexible_array_arc_retainable : Error<
+ "ARC forbids flexible array members with retainable object type">;
+def warn_variable_sized_ivar_visibility : Warning<
+ "field %0 with variable sized type %1 is not visible to subclasses and"
+ " can conflict with their instance variables">, InGroup<ObjCFlexibleArray>;
+def warn_superclass_variable_sized_type_not_at_end : Warning<
+ "field %0 can overwrite instance variable %1 with variable sized type %2"
+ " in superclass %3">, InGroup<ObjCFlexibleArray>;
+
let CategoryName = "ARC Semantic Issue" in {
// ARC-mode diagnostics.
@@ -5462,9 +5521,6 @@ def err_offsetof_incomplete_type : Error<
def err_offsetof_record_type : Error<
"offsetof requires struct, union, or class type, %0 invalid">;
def err_offsetof_array_type : Error<"offsetof requires array type, %0 invalid">;
-def ext_offsetof_extended_field_designator : Extension<
- "using extended field designator is an extension">,
- InGroup<DiagGroup<"extended-offsetof">>;
def ext_offsetof_non_pod_type : ExtWarn<"offset of on non-POD type %0">,
InGroup<InvalidOffsetof>;
def ext_offsetof_non_standardlayout_type : ExtWarn<
@@ -5475,6 +5531,12 @@ def err_offsetof_field_of_virtual_base : Error<
def warn_sub_ptr_zero_size_types : Warning<
"subtraction of pointers to type %0 of zero size has undefined behavior">,
InGroup<PointerArith>;
+def warn_pointer_arith_null_ptr : Warning<
+ "performing pointer arithmetic on a null pointer has undefined behavior%select{| if the offset is nonzero}0">,
+ InGroup<NullPointerArithmetic>, DefaultIgnore;
+def warn_gnu_null_ptr_arith : Warning<
+ "arithmetic on a null pointer treated as a cast from integer to pointer is a GNU extension">,
+ InGroup<NullPointerArithmetic>, DefaultIgnore;
def warn_floatingpoint_eq : Warning<
"comparing floating point with == or != is unsafe">,
@@ -5862,6 +5924,8 @@ def err_typecheck_assign_const : Error<
"cannot assign to %select{non-|}1static data member %2 "
"with const-qualified type %3|"
"cannot assign to non-static data member within const member function %1|"
+ "cannot assign to %select{variable %2|non-static data member %2|lvalue}1 "
+ "with %select{|nested }3const-qualified data member %4|"
"read-only variable is not assignable}0">;
def note_typecheck_assign_const : Note<
@@ -5869,25 +5933,39 @@ def note_typecheck_assign_const : Note<
"function %1 which returns const-qualified type %2 declared here|"
"variable %1 declared const here|"
"%select{non-|}1static data member %2 declared const here|"
- "member function %q1 is declared const here}0">;
+ "member function %q1 is declared const here|"
+ "%select{|nested }1data member %2 declared const here}0">;
+
+def warn_unsigned_always_true_comparison : Warning<
+ "result of comparison of %select{%3|unsigned expression}0 %2 "
+ "%select{unsigned expression|%3}0 is always %4">,
+ InGroup<TautologicalUnsignedZeroCompare>;
+def warn_unsigned_enum_always_true_comparison : Warning<
+ "result of comparison of %select{%3|unsigned enum expression}0 %2 "
+ "%select{unsigned enum expression|%3}0 is always %4">,
+ InGroup<TautologicalUnsignedEnumZeroCompare>;
+def warn_tautological_constant_compare : Warning<
+ "result of comparison %select{%3|%1}0 %2 "
+ "%select{%1|%3}0 is always %4">,
+ InGroup<TautologicalConstantCompare>;
def warn_mixed_sign_comparison : Warning<
"comparison of integers of different signs: %0 and %1">,
InGroup<SignCompare>, DefaultIgnore;
-def warn_lunsigned_always_true_comparison : Warning<
- "comparison of unsigned%select{| enum}2 expression %0 is always %1">,
- InGroup<TautologicalCompare>;
def warn_out_of_range_compare : Warning<
- "comparison of %select{constant %0|true|false}1 with "
- "%select{expression of type %2|boolean expression}3 is always "
- "%select{false|true}4">, InGroup<TautologicalOutOfRangeCompare>;
-def warn_runsigned_always_true_comparison : Warning<
- "comparison of %0 unsigned%select{| enum}2 expression is always %1">,
- InGroup<TautologicalCompare>;
+ "result of comparison of %select{constant %0|true|false}1 with "
+ "%select{expression of type %2|boolean expression}3 is always %4">,
+ InGroup<TautologicalOutOfRangeCompare>;
+def warn_tautological_bool_compare : Warning<warn_out_of_range_compare.Text>,
+ InGroup<TautologicalConstantCompare>;
def warn_comparison_of_mixed_enum_types : Warning<
"comparison of two values with different enumeration types"
"%diff{ ($ and $)|}0,1">,
- InGroup<DiagGroup<"enum-compare">>;
+ InGroup<EnumCompare>;
+def warn_comparison_of_mixed_enum_types_switch : Warning<
+ "comparison of two values with different enumeration types in switch statement"
+ "%diff{ ($ and $)|}0,1">,
+ InGroup<EnumCompareSwitch>;
def warn_null_in_arithmetic_operation : Warning<
"use of NULL in arithmetic operation">,
InGroup<NullArithmetic>;
@@ -6391,12 +6469,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;
+ InGroup<DeleteNonVirtualDtor>, 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>;
+ "non-virtual destructor">, InGroup<DeleteNonVirtualDtor>, ShowInSystemHeader;
def warn_overloaded_virtual : Warning<
"%q0 hides overloaded virtual %select{function|functions}1">,
InGroup<OverloadedVirtual>, DefaultIgnore;
@@ -6420,8 +6498,8 @@ def warn_overaligned_type : Warning<
"guarantees %2 bytes">,
InGroup<OveralignedType>, DefaultIgnore;
def warn_aligned_allocation_unavailable :Warning<
- "aligned %select{allocation|deallocation}0 function of type '%1' possibly "
- "unavailable on %2">, InGroup<AlignedAllocationUnavailable>, DefaultError;
+ "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<
"if you supply your own aligned allocation functions, use "
"-Wno-aligned-allocation-unavailable to silence this diagnostic">;
@@ -6458,8 +6536,6 @@ let CategoryName = "Lambda Issue" in {
"%0 can appear only once in a capture list">;
def err_reference_capture_with_reference_default : Error<
"'&' cannot precede a capture when the capture default is '&'">;
- def err_this_capture_with_copy_default : Error<
- "'this' cannot be explicitly captured when the capture default is '='">;
def err_copy_capture_with_copy_default : Error<
"'&' must precede a capture when the capture default is '='">;
def err_capture_does_not_name_variable : Error<
@@ -6526,12 +6602,20 @@ 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++1z '*this' captures.
+ // 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">,
- InGroup<CXXPre1zCompat>, DefaultIgnore;
- def ext_star_this_lambda_capture_cxx1z : ExtWarn<
+ InGroup<CXXPre17Compat>, DefaultIgnore;
+ def ext_star_this_lambda_capture_cxx17 : ExtWarn<
"capture of '*this' by copy is a C++17 extension">, InGroup<CXX17>;
+
+ // C++2a [=, this] captures.
+ def warn_cxx17_compat_equals_this_lambda_capture : Warning<
+ "explicit capture of 'this' with a capture default of '=' is incompatible "
+ "with C++ standards before C++2a">, InGroup<CXXPre2aCompat>, DefaultIgnore;
+ def ext_equals_this_lambda_capture_cxx2a : ExtWarn<
+ "explicit capture of 'this' with a capture default of '=' "
+ "is a C++2a extension">, InGroup<CXX2a>;
}
def err_return_in_captured_stmt : Error<
@@ -6981,8 +7065,8 @@ def err_atomic_op_needs_atomic : Error<
"address argument to atomic operation must be a pointer to _Atomic "
"type (%0 invalid)">;
def err_atomic_op_needs_non_const_atomic : Error<
- "address argument to atomic operation must be a pointer to non-const _Atomic "
- "type (%0 invalid)">;
+ "address argument to atomic operation must be a pointer to non-%select{const|constant}0 _Atomic "
+ "type (%1 invalid)">;
def err_atomic_op_needs_non_const_pointer : Error<
"address argument to atomic operation must be a pointer to non-const "
"type (%0 invalid)">;
@@ -6998,6 +7082,8 @@ def err_atomic_op_bitwise_needs_atomic_int : Error<
def warn_atomic_op_has_invalid_memory_order : Warning<
"memory order argument to atomic operation is invalid">,
InGroup<DiagGroup<"atomic-memory-ordering">>;
+def err_atomic_op_has_invalid_synch_scope : Error<
+ "synchronization scope argument to atomic operation is invalid">;
def err_overflow_builtin_must_be_int : Error<
"operand argument to overflow builtin must be an integer (%0 invalid)">;
@@ -7199,11 +7285,11 @@ def warn_unused_volatile : Warning<
def ext_cxx14_attr : Extension<
"use of the %0 attribute is a C++14 extension">, InGroup<CXX14>;
-def ext_cxx1z_attr : Extension<
+def ext_cxx17_attr : Extension<
"use of the %0 attribute is a C++17 extension">, InGroup<CXX17>;
def warn_unused_comparison : Warning<
- "%select{%select{|in}1equality|relational}0 comparison result unused">,
+ "%select{equality|inequality|relational|three-way}0 comparison result unused">,
InGroup<UnusedComparison>;
def note_inequality_comparison_to_or_assign : Note<
"use '|=' to turn this inequality comparison into an or-assignment">;
@@ -7315,8 +7401,8 @@ def err_invalid_conversion_between_vector_and_integer : Error<
def err_opencl_function_pointer : Error<
"pointers to functions are not allowed">;
-def err_opencl_taking_function_address : Error<
- "taking address of function is not allowed">;
+def err_opencl_taking_address_capture : Error<
+ "taking address of a capture is not allowed">;
def err_invalid_conversion_between_vector_and_scalar : Error<
"invalid conversion between vector type %0 and scalar type %1">;
@@ -7457,6 +7543,9 @@ def err_ambiguous_derived_to_base_conv : Error<
def err_ambiguous_memptr_conv : Error<
"ambiguous conversion from pointer to member of %select{base|derived}0 "
"class %1 to pointer to member of %select{derived|base}0 class %2:%3">;
+def ext_ms_ambiguous_direct_base : ExtWarn<
+ "accessing inaccessible direct base %0 of %1 is a Microsoft extension">,
+ InGroup<MicrosoftInaccessibleBase>;
def err_memptr_conv_via_virtual : Error<
"conversion from pointer to member of class %0 to pointer to member "
@@ -7526,6 +7615,11 @@ def err_operator_delete_dependent_param_type : Error<
"%0 cannot take a dependent type as first parameter; use %1 instead">;
def err_operator_delete_param_type : Error<
"first parameter of %0 must have type %1">;
+def err_destroying_operator_delete_not_usual : Error<
+ "destroying operator delete can have only an optional size and optional "
+ "alignment parameter">;
+def note_implicit_delete_this_in_destructor_here : Note<
+ "while checking implicit 'delete this' for virtual destructor">;
// C++ literal operators
def err_literal_operator_outside_namespace : Error<
@@ -7831,6 +7925,8 @@ def err_type_tag_for_datatype_too_large : Error<
"'type_tag_for_datatype' attribute requires the initializer to be "
"an %select{integer|integral}0 constant expression "
"that can be represented by a 64 bit integer">;
+def err_tag_index_out_of_range : Error<
+ "%select{type tag|argument}0 index %1 is greater than the number of arguments specified">;
def warn_type_tag_for_datatype_wrong_kind : Warning<
"this type tag was not designed to be used with this function">,
InGroup<TypeSafety>;
@@ -7868,6 +7964,8 @@ def err_builtin_annotation_first_arg : Error<
"first argument to __builtin_annotation must be an integer">;
def err_builtin_annotation_second_arg : Error<
"second argument to __builtin_annotation must be a non-wide string constant">;
+def err_msvc_annotation_wide_str : Error<
+ "arguments to __annotation must be wide string constants">;
// CFString checking
def err_cfstring_literal_not_string_constant : Error<
@@ -8195,12 +8293,12 @@ def err_c99_array_usage_cxx : Error<
"feature, not permitted in C++">;
def err_type_unsupported : Error<
"%0 is not supported on this target">;
-def err_nsconsumed_attribute_mismatch : Error<
+def warn_nsconsumed_attribute_mismatch : Warning<
"overriding method has mismatched ns_consumed attribute on its"
- " parameter">;
-def err_nsreturns_retained_attribute_mismatch : Error<
+ " parameter">, InGroup<NSConsumedMismatch>;
+def warn_nsreturns_retained_attribute_mismatch : Warning<
"overriding method has mismatched ns_returns_%select{not_retained|retained}0"
- " attributes">;
+ " attributes">, InGroup<NSReturnsMismatch>;
def note_getter_unavailable : Note<
"or because setter is declared here, but no getter method %0 is found">;
@@ -8364,8 +8462,6 @@ 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<
@@ -8518,6 +8614,8 @@ def err_omp_expected_var_name_member_expr : Error<
"expected variable name%select{| or data member of current class}0">;
def err_omp_expected_var_name_member_expr_or_array_item : Error<
"expected variable name%select{|, data member of current class}0, array element or array section">;
+def err_omp_expected_addressable_lvalue_or_array_item : Error<
+ "expected addressable lvalue expression, array element or array section">;
def err_omp_expected_named_var_member_or_array_expression: Error<
"expected expression containing only member accesses and/or array sections based on named variables">;
def err_omp_bit_fields_forbidden_in_clause : Error<
@@ -8525,7 +8623,7 @@ def err_omp_bit_fields_forbidden_in_clause : Error<
def err_array_section_does_not_specify_contiguous_storage : Error<
"array section does not specify contiguous storage">;
def err_omp_union_type_not_allowed : Error<
- "mapped storage cannot be derived from a union">;
+ "mapping of union members is not allowed">;
def err_omp_expected_access_to_data_field : Error<
"expected access to data field">;
def err_omp_multiple_array_items_in_map_clause : Error<
@@ -8612,6 +8710,8 @@ def err_omp_declare_target_to_and_link : Error<
def warn_omp_not_in_target_context : Warning<
"declaration is not declared in any declare target region">,
InGroup<OpenMPTarget>;
+def err_omp_function_in_link_clause : Error<
+ "function name is not allowed in 'link' clause">;
def err_omp_aligned_expected_array_or_ptr : Error<
"argument of aligned clause should be array"
"%select{ or pointer|, pointer, reference to array or reference to pointer}1"
@@ -8670,6 +8770,12 @@ def err_omp_reduction_in_task : Error<
"reduction variables may not be accessed in an explicit task">;
def err_omp_reduction_id_not_compatible : Error<
"list item of type %0 is not valid for specified reduction operation: unable to provide default initialization value">;
+def err_omp_in_reduction_not_task_reduction : Error<
+ "in_reduction variable must appear in a task_reduction clause">;
+def err_omp_reduction_identifier_mismatch : Error<
+ "in_reduction variable must have the same reduction operation as in a task_reduction clause">;
+def note_omp_previous_reduction_identifier : Note<
+ "previously marked as task_reduction with different reduction operation">;
def err_omp_prohibited_region : Error<
"region cannot be%select{| closely}0 nested inside '%1' region"
"%select{|; perhaps you forget to enclose 'omp %3' directive into a parallel region?|"
@@ -8746,9 +8852,9 @@ def err_omp_function_expected : Error<
def err_omp_wrong_cancel_region : Error<
"one of 'for', 'parallel', 'sections' or 'taskgroup' is expected">;
def err_omp_parent_cancel_region_nowait : Error<
- "parent region for 'omp %select{cancellation point/cancel}0' construct cannot be nowait">;
+ "parent region for 'omp %select{cancellation point|cancel}0' construct cannot be nowait">;
def err_omp_parent_cancel_region_ordered : Error<
- "parent region for 'omp %select{cancellation point/cancel}0' construct cannot be ordered">;
+ "parent region for 'omp %select{cancellation point|cancel}0' construct cannot be ordered">;
def err_omp_reduction_wrong_type : Error<"reduction type cannot be %select{qualified with 'const', 'volatile' or 'restrict'|a function|a reference|an array}0 type">;
def err_omp_wrong_var_in_declare_reduction : Error<"only %select{'omp_priv' or 'omp_orig'|'omp_in' or 'omp_out'}0 variables are allowed in %select{initializer|combiner}0 expression">;
def err_omp_declare_reduction_redefinition : Error<"redefinition of user-defined reduction for type %0">;
@@ -8793,16 +8899,10 @@ def err_omp_expected_base_var_name : Error<
"expected variable name as a base of the array %select{subscript|section}0">;
def err_omp_map_shared_storage : Error<
"variable already marked as mapped in current construct">;
-def err_omp_not_mappable_type : Error<
- "type %0 is not mappable to target">;
def err_omp_invalid_map_type_for_directive : Error<
"%select{map type '%1' is not allowed|map type must be specified}0 for '#pragma omp %2'">;
def err_omp_no_clause_for_directive : Error<
"expected at least one %0 clause for '#pragma omp %1'">;
-def note_omp_polymorphic_in_target : Note<
- "mappable type cannot be polymorphic">;
-def note_omp_static_member_in_target : Note<
- "mappable type cannot contain static members">;
def err_omp_threadprivate_in_clause : Error<
"threadprivate variables are not allowed in '%0' clause">;
def err_omp_wrong_ordered_loop_count : Error<
@@ -8821,12 +8921,6 @@ def note_omp_critical_hint_here : Note<
"%select{|previous }0'hint' clause with value '%1'">;
def note_omp_critical_no_hint : Note<
"%select{|previous }0directive with no 'hint' clause specified">;
-def err_omp_firstprivate_distribute_private_teams : Error<
- "private variable in '#pragma omp teams' cannot be firstprivate in '#pragma omp distribute'">;
-def err_omp_firstprivate_and_lastprivate_in_distribute : Error<
- "lastprivate variable cannot be firstprivate in '#pragma omp distribute'">;
-def err_omp_firstprivate_distribute_in_teams_reduction : Error<
- "reduction variable in '#pragma omp teams' cannot be firstprivate in '#pragma omp distribute'">;
def err_omp_depend_clause_thread_simd : Error<
"'depend' clauses cannot be mixed with '%0' clause">;
def err_omp_depend_sink_expected_loop_iteration : Error<
@@ -8871,6 +8965,10 @@ def err_omp_reduction_non_addressable_expression : Error<
"expected addressable reduction item for the task-based directives">;
def err_omp_reduction_with_nogroup : Error<
"'reduction' clause cannot be used with 'nogroup' clause">;
+def err_omp_reduction_vla_unsupported : Error<
+ "cannot generate code for reduction on %select{|array section, which requires a }0variable length array">;
+def err_omp_linear_distribute_var_non_loop_iteration : Error<
+ "only loop iteration variables are allowed in 'linear' clause in distribute directives">;
} // end of OpenMP category
let CategoryName = "Related Result Type Issue" in {
@@ -8912,6 +9010,14 @@ def err_module_redefinition : Error<
"redefinition of module '%0'">;
def note_prev_module_definition : Note<"previously defined here">;
def note_prev_module_definition_from_ast_file : Note<"module loaded from '%0'">;
+def err_module_not_defined : Error<
+ "definition of module '%0' is not available; use -fmodule-file= to specify "
+ "path to precompiled module interface">;
+def err_module_redeclaration : Error<
+ "translation unit contains multiple module declarations">;
+def note_prev_module_declaration : Note<"previous module declaration is here">;
+def err_module_declaration_missing : Error<
+ "missing 'export module' declaration in module interface unit">;
def err_module_private_specialization : Error<
"%select{template|partial|member}0 specialization cannot be "
"declared __module_private__">;
diff --git a/include/clang/Basic/DiagnosticSerializationKinds.td b/include/clang/Basic/DiagnosticSerializationKinds.td
index 420ccebbfaf0..3949bc2146f6 100644
--- a/include/clang/Basic/DiagnosticSerializationKinds.td
+++ b/include/clang/Basic/DiagnosticSerializationKinds.td
@@ -77,6 +77,8 @@ def err_imported_module_not_found : Error<
"module '%0' in AST file '%1' (imported by AST file '%2') "
"is not defined in any loaded module map file; "
"maybe you need to load '%3'?">, DefaultFatal;
+def note_imported_by_pch_module_not_found : Note<
+ "consider adding '%0' to the header search path">;
def err_imported_module_modmap_changed : Error<
"module '%0' imported by AST file '%1' found in a different module map file"
" (%2) than when the importing AST file was built (%3)">, DefaultFatal;
@@ -122,6 +124,45 @@ def note_second_module_difference : Note<
def err_module_odr_violation_different_instantiations : Error<
"instantiation of %q0 is different in different modules">;
+def err_module_odr_violation_definition_data : Error <
+ "%q0 has different definitions in different modules; first difference is "
+ "%select{definition in module '%2'|defined here}1 found "
+ "%select{"
+ "%4 base %plural{1:class|:classes}4|"
+ "%4 virtual base %plural{1:class|:classes}4|"
+ "%ordinal4 base class with type %5|"
+ "%ordinal4 %select{non-virtual|virtual}5 base class %6|"
+ "%ordinal4 base class %5 with "
+ "%select{public|protected|private|no}6 access specifier}3">;
+
+def note_module_odr_violation_definition_data : Note <
+ "but in '%0' found "
+ "%select{"
+ "%2 base %plural{1:class|:classes}2|"
+ "%2 virtual base %plural{1:class|:classes}2|"
+ "%ordinal2 base class with different type %3|"
+ "%ordinal2 %select{non-virtual|virtual}3 base class %4|"
+ "%ordinal2 base class %3 with "
+ "%select{public|protected|private|no}4 access specifier}1">;
+
+def err_module_odr_violation_template_parameter : Error <
+ "%q0 has different definitions in different modules; first difference is "
+ "%select{definition in module '%2'|defined here}1 found "
+ "%select{"
+ "unnamed template parameter|"
+ "template parameter %4|"
+ "template parameter with %select{no |}4default argument|"
+ "template parameter with default argument}3">;
+
+
+def note_module_odr_violation_template_parameter : Note <
+ "but in '%0' found "
+ "%select{"
+ "unnamed template parameter %2|"
+ "template parameter %2|"
+ "template parameter with %select{no |}2default argument|"
+ "template parameter with different default argument}1">;
+
def err_module_odr_violation_mismatch_decl : Error<
"%q0 has different definitions in different modules; first difference is "
"%select{definition in module '%2'|defined here}1 found "
diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h
index f94b2c9b2f42..8e3c15afbfcd 100644
--- a/include/clang/Basic/IdentifierTable.h
+++ b/include/clang/Basic/IdentifierTable.h
@@ -1,4 +1,4 @@
-//===--- IdentifierTable.h - Hash table for identifier lookup ---*- C++ -*-===//
+//===- IdentifierTable.h - Hash table for identifier lookup -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,11 +6,11 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-///
+//
/// \file
/// \brief Defines the clang::IdentifierInfo, clang::IdentifierTable, and
/// clang::Selector interfaces.
-///
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
@@ -18,35 +18,29 @@
#include "clang/Basic/LLVM.h"
#include "clang/Basic/TokenKinds.h"
+#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
+#include "llvm/Support/PointerLikeTypeTraits.h"
+#include "llvm/Support/type_traits.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <cstring>
-#include <new>
#include <string>
#include <utility>
-namespace llvm {
-
- template <typename T> struct DenseMapInfo;
-
-} // end namespace llvm
-
namespace clang {
- class LangOptions;
- class IdentifierInfo;
- class IdentifierTable;
- class SourceLocation;
- class MultiKeywordSelector; // private class used by Selector
- class DeclarationName; // AST class that stores declaration names
+class IdentifierInfo;
+class LangOptions;
+class MultiKeywordSelector;
+class SourceLocation;
- /// \brief A simple pair of identifier info and location.
- typedef std::pair<IdentifierInfo*, SourceLocation> IdentifierLocPair;
+/// \brief A simple pair of identifier info and location.
+using IdentifierLocPair = std::pair<IdentifierInfo *, SourceLocation>;
/// One of these records is kept for each identifier that
/// is lexed. This contains information about whether the token was \#define'd,
@@ -85,8 +79,10 @@ class IdentifierInfo {
// keyword.
// 29 bit left in 64-bit word.
- void *FETokenInfo; // Managed by the language front-end.
- llvm::StringMapEntry<IdentifierInfo*> *Entry;
+ // Managed by the language front-end.
+ void *FETokenInfo = nullptr;
+
+ llvm::StringMapEntry<IdentifierInfo *> *Entry = nullptr;
public:
IdentifierInfo();
@@ -104,7 +100,6 @@ public:
/// \brief 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
@@ -112,12 +107,12 @@ public:
// The 'this' pointer really points to a
// std::pair<IdentifierInfo, const char*>, where internal pointer
// points to the external string data.
- typedef std::pair<IdentifierInfo, const char*> actualtype;
+ using actualtype = std::pair<IdentifierInfo, const char *>;
+
return ((const actualtype*) this)->second;
}
/// \brief 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
@@ -125,7 +120,8 @@ public:
// The 'this' pointer really points to a
// std::pair<IdentifierInfo, const char*>, where internal pointer
// points to the external string data.
- typedef std::pair<IdentifierInfo, const char*> actualtype;
+ using actualtype = std::pair<IdentifierInfo, const char *>;
+
const char* p = ((const actualtype*) this)->second - 2;
return (((unsigned) p[0]) | (((unsigned) p[1]) << 8)) - 1;
}
@@ -465,7 +461,7 @@ public:
class IdentifierTable {
// Shark shows that using MallocAllocator is *much* slower than using this
// BumpPtrAllocator!
- typedef llvm::StringMap<IdentifierInfo*, llvm::BumpPtrAllocator> HashTableTy;
+ using HashTableTy = llvm::StringMap<IdentifierInfo *, llvm::BumpPtrAllocator>;
HashTableTy HashTable;
IdentifierInfoLookup* ExternalLookup;
@@ -551,8 +547,8 @@ public:
return *II;
}
- typedef HashTableTy::const_iterator iterator;
- typedef HashTableTy::const_iterator const_iterator;
+ using iterator = HashTableTy::const_iterator;
+ using const_iterator = HashTableTy::const_iterator;
iterator begin() const { return HashTable.begin(); }
iterator end() const { return HashTable.end(); }
@@ -654,7 +650,9 @@ class Selector {
MultiArg = 0x3,
ArgFlags = ZeroArg|OneArg
};
- uintptr_t InfoPtr; // a pointer to the MultiKeywordSelector or IdentifierInfo.
+
+ // a pointer to the MultiKeywordSelector or IdentifierInfo.
+ uintptr_t InfoPtr = 0;
Selector(IdentifierInfo *II, unsigned nArgs) {
InfoPtr = reinterpret_cast<uintptr_t>(II);
@@ -662,6 +660,7 @@ class Selector {
assert(nArgs < 2 && "nArgs not equal to 0/1");
InfoPtr |= nArgs+1;
}
+
Selector(MultiKeywordSelector *SI) {
InfoPtr = reinterpret_cast<uintptr_t>(SI);
assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo");
@@ -692,7 +691,7 @@ public:
/// The default ctor should only be used when creating data structures that
/// will contain selectors.
- Selector() : InfoPtr(0) {}
+ Selector() = default;
Selector(uintptr_t V) : InfoPtr(V) {}
/// operator==/!= - Indicate whether the specified selectors are identical.
@@ -776,7 +775,8 @@ public:
/// \brief This table allows us to fully hide how we implement
/// multi-keyword caching.
class SelectorTable {
- void *Impl; // Actually a SelectorTableImpl
+ // Actually a SelectorTableImpl
+ void *Impl;
public:
SelectorTable();
@@ -793,6 +793,7 @@ public:
Selector getUnarySelector(IdentifierInfo *ID) {
return Selector(ID, 1);
}
+
Selector getNullarySelector(IdentifierInfo *ID) {
return Selector(ID, 0);
}
@@ -848,7 +849,7 @@ public:
unsigned ExtraKindOrNumArgs;
};
-} // end namespace clang
+} // namespace clang
namespace llvm {
@@ -856,11 +857,11 @@ namespace llvm {
/// DenseSets.
template <>
struct DenseMapInfo<clang::Selector> {
- static inline clang::Selector getEmptyKey() {
+ static clang::Selector getEmptyKey() {
return clang::Selector::getEmptyMarker();
}
- static inline clang::Selector getTombstoneKey() {
+ static clang::Selector getTombstoneKey() {
return clang::Selector::getTombstoneMarker();
}
@@ -874,16 +875,13 @@ struct DenseMapInfo<clang::Selector> {
template <>
struct isPodLike<clang::Selector> { static const bool value = true; };
-template <typename T> class PointerLikeTypeTraits;
-
template<>
-class PointerLikeTypeTraits<clang::Selector> {
-public:
- static inline const void *getAsVoidPointer(clang::Selector P) {
+struct PointerLikeTypeTraits<clang::Selector> {
+ static const void *getAsVoidPointer(clang::Selector P) {
return P.getAsOpaquePtr();
}
- static inline clang::Selector getFromVoidPointer(const void *P) {
+ static clang::Selector getFromVoidPointer(const void *P) {
return clang::Selector(reinterpret_cast<uintptr_t>(P));
}
@@ -893,13 +891,12 @@ public:
// Provide PointerLikeTypeTraits for IdentifierInfo pointers, which
// are not guaranteed to be 8-byte aligned.
template<>
-class PointerLikeTypeTraits<clang::IdentifierInfo*> {
-public:
- static inline void *getAsVoidPointer(clang::IdentifierInfo* P) {
+struct PointerLikeTypeTraits<clang::IdentifierInfo*> {
+ static void *getAsVoidPointer(clang::IdentifierInfo* P) {
return P;
}
- static inline clang::IdentifierInfo *getFromVoidPointer(void *P) {
+ static clang::IdentifierInfo *getFromVoidPointer(void *P) {
return static_cast<clang::IdentifierInfo*>(P);
}
@@ -907,19 +904,18 @@ public:
};
template<>
-class PointerLikeTypeTraits<const clang::IdentifierInfo*> {
-public:
- static inline const void *getAsVoidPointer(const clang::IdentifierInfo* P) {
+struct PointerLikeTypeTraits<const clang::IdentifierInfo*> {
+ static const void *getAsVoidPointer(const clang::IdentifierInfo* P) {
return P;
}
- static inline const clang::IdentifierInfo *getFromVoidPointer(const void *P) {
+ static const clang::IdentifierInfo *getFromVoidPointer(const void *P) {
return static_cast<const clang::IdentifierInfo*>(P);
}
enum { NumLowBitsAvailable = 1 };
};
-} // end namespace llvm
+} // namespace llvm
#endif // LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
diff --git a/include/clang/Basic/LLVM.h b/include/clang/Basic/LLVM.h
index f32ab5e11bd4..e60284d1b445 100644
--- a/include/clang/Basic/LLVM.h
+++ b/include/clang/Basic/LLVM.h
@@ -35,6 +35,7 @@ namespace llvm {
template<typename T, unsigned N> class SmallVector;
template<typename T> class SmallVectorImpl;
template<typename T> class Optional;
+ template <class T> class Expected;
template<typename T>
struct SaveAndRestore;
@@ -71,6 +72,9 @@ namespace clang {
using llvm::SmallVectorImpl;
using llvm::SaveAndRestore;
+ // Error handling.
+ using llvm::Expected;
+
// Reference counting.
using llvm::IntrusiveRefCntPtr;
using llvm::IntrusiveRefCntPtrInfo;
diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def
index c9230e0aaa6f..ca3a0e349d62 100644
--- a/include/clang/Basic/LangOptions.def
+++ b/include/clang/Basic/LangOptions.def
@@ -82,6 +82,7 @@
// FIXME: A lot of the BENIGN_ options should be COMPATIBLE_ instead.
LANGOPT(C99 , 1, 0, "C99")
LANGOPT(C11 , 1, 0, "C11")
+LANGOPT(C17 , 1, 0, "C17")
LANGOPT(MSVCCompat , 1, 0, "Microsoft Visual C++ full compatibility mode")
LANGOPT(MicrosoftExt , 1, 0, "Microsoft C++ extensions")
LANGOPT(AsmBlocks , 1, 0, "Microsoft inline asm blocks")
@@ -89,7 +90,7 @@ LANGOPT(Borland , 1, 0, "Borland extensions")
LANGOPT(CPlusPlus , 1, 0, "C++")
LANGOPT(CPlusPlus11 , 1, 0, "C++11")
LANGOPT(CPlusPlus14 , 1, 0, "C++14")
-LANGOPT(CPlusPlus1z , 1, 0, "C++1z")
+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")
@@ -124,7 +125,9 @@ LANGOPT(ZVector , 1, 0, "System z vector extensions")
LANGOPT(Exceptions , 1, 0, "exception handling")
LANGOPT(ObjCExceptions , 1, 0, "Objective-C exceptions")
LANGOPT(CXXExceptions , 1, 0, "C++ exceptions")
+LANGOPT(DWARFExceptions , 1, 0, "dwarf exception handling")
LANGOPT(SjLjExceptions , 1, 0, "setjmp-longjump exception handling")
+LANGOPT(SEHExceptions , 1, 0, "SEH .xdata exception handling")
LANGOPT(ExternCNoUnwind , 1, 0, "Assume extern C functions don't unwind")
LANGOPT(TraditionalCPP , 1, 0, "traditional CPP emulation")
LANGOPT(RTTI , 1, 1, "run-time type information")
@@ -137,6 +140,8 @@ LANGOPT(GNUAsm , 1, 1, "GNU-style inline assembly")
LANGOPT(CoroutinesTS , 1, 0, "C++ coroutines TS")
LANGOPT(RelaxedTemplateTemplateArgs, 1, 0, "C++17 relaxed matching of template template arguments")
+LANGOPT(DoubleSquareBracketAttributes, 1, 0, "'[[]]' attributes extension for all language standard modes")
+
BENIGN_LANGOPT(ThreadsafeStatics , 1, 1, "thread-safe static initializers")
LANGOPT(POSIXThreads , 1, 0, "POSIX thread support")
LANGOPT(Blocks , 1, 0, "blocks extension to C")
@@ -175,7 +180,8 @@ BENIGN_LANGOPT(ObjCGCBitmapPrint , 1, 0, "printing of GC's bitmap layout for __w
BENIGN_LANGOPT(AccessControl , 1, 1, "C++ access control")
LANGOPT(CharIsSigned , 1, 1, "signed char")
-LANGOPT(ShortWChar , 1, 0, "unsigned short wchar_t")
+LANGOPT(WCharSize , 4, 0, "width of wchar_t")
+LANGOPT(WCharIsSigned , 1, 0, "signed or unsigned wchar_t")
ENUM_LANGOPT(MSPointerToMemberRepresentationMethod, PragmaMSPointersToMembersKind, 2, PPTMK_BestCase, "member-pointer representation method")
ENUM_LANGOPT(DefaultCallingConv, DefaultCallingConvention, 3, DCC_None, "default calling convention")
@@ -267,6 +273,9 @@ LANGOPT(SanitizeAddressFieldPadding, 2, 0, "controls how aggressive is ASan "
"aggressive, 2: more aggressive)")
LANGOPT(XRayInstrument, 1, 0, "controls whether to do XRay instrumentation")
+LANGOPT(XRayAlwaysEmitCustomEvents, 1, 0,
+ "controls whether to always emit intrinsic calls to "
+ "__xray_customevent(...) builtin.")
BENIGN_LANGOPT(AllowEditorPlaceholders, 1, 0,
"allow editor placeholders in source")
diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h
index 8488515d2b67..f7a43adefad0 100644
--- a/include/clang/Basic/LangOptions.h
+++ b/include/clang/Basic/LangOptions.h
@@ -77,7 +77,8 @@ public:
DCC_CDecl,
DCC_FastCall,
DCC_StdCall,
- DCC_VectorCall
+ DCC_VectorCall,
+ DCC_RegCall
};
enum AddrSpaceMapMangling { ASMM_Target, ASMM_On, ASMM_Off };
@@ -197,6 +198,10 @@ public:
bool allowsNonTrivialObjCLifetimeQualifiers() const {
return ObjCAutoRefCount || ObjCWeak;
}
+
+ bool assumeFunctionsAreConvergent() const {
+ return (CUDA && CUDAIsDevice) || OpenCL;
+ }
};
/// \brief Floating point control options
diff --git a/include/clang/Basic/Module.h b/include/clang/Basic/Module.h
index 177175eae965..6631721e3531 100644
--- a/include/clang/Basic/Module.h
+++ b/include/clang/Basic/Module.h
@@ -1,4 +1,4 @@
-//===--- Module.h - Describe a module ---------------------------*- C++ -*-===//
+//===- Module.h - Describe a module -----------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,12 +6,13 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-///
+//
/// \file
/// \brief Defines the clang::Module class, which describes a module in the
/// source code.
-///
+//
//===----------------------------------------------------------------------===//
+
#ifndef LLVM_CLANG_BASIC_MODULE_H
#define LLVM_CLANG_BASIC_MODULE_H
@@ -19,6 +20,7 @@
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SetVector.h"
@@ -26,22 +28,28 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
+#include <array>
+#include <cassert>
+#include <cstdint>
+#include <ctime>
#include <string>
#include <utility>
#include <vector>
namespace llvm {
- class raw_ostream;
-}
+
+class raw_ostream;
+
+} // namespace llvm
namespace clang {
class LangOptions;
class TargetInfo;
-class IdentifierInfo;
-
+
/// \brief Describes the name of a module.
-typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
+using ModuleId = SmallVector<std::pair<std::string, SourceLocation>, 2>;
/// The signature of a module, which is a hash of the AST content.
struct ASTFileSignature : std::array<uint32_t, 5> {
@@ -68,7 +76,11 @@ public:
ModuleMapModule,
/// \brief This is a C++ Modules TS module interface unit.
- ModuleInterfaceUnit
+ ModuleInterfaceUnit,
+
+ /// \brief This is a fragment of the global module within some C++ Modules
+ /// TS module.
+ GlobalModuleFragment,
};
/// \brief The kind of this module.
@@ -81,7 +93,7 @@ public:
/// \brief The build directory of this module. This is the directory in
/// which the module is notionally built, and relative to which its headers
/// are found.
- const DirectoryEntry *Directory;
+ const DirectoryEntry *Directory = nullptr;
/// \brief The presumed file name for the module map defining this module.
/// Only non-empty when building from preprocessed source.
@@ -95,6 +107,10 @@ public:
/// \brief The name of the umbrella entry, as written in the module map.
std::string UmbrellaAsWritten;
+
+ /// \brief The module through which entities defined in this module will
+ /// eventually be exposed, for use in "private" modules.
+ std::string ExportAsModule;
private:
/// \brief The submodules of this module, indexed by name.
@@ -106,7 +122,7 @@ private:
/// \brief The AST file if this is a top-level module which has a
/// corresponding serialized AST file, or null otherwise.
- const FileEntry *ASTFile;
+ const FileEntry *ASTFile = nullptr;
/// \brief The top-level headers associated with this module.
llvm::SmallSetVector<const FileEntry *, 2> TopHeaders;
@@ -173,7 +189,7 @@ public:
/// \brief An individual requirement: a feature name and a flag indicating
/// the required state of that feature.
- typedef std::pair<std::string, bool> Requirement;
+ using Requirement = std::pair<std::string, bool>;
/// \brief The set of language features required to use this module.
///
@@ -262,7 +278,7 @@ public:
///
/// The pointer is the module being re-exported, while the bit will be true
/// to indicate that this is a wildcard export.
- typedef llvm::PointerIntPair<Module *, 1, bool> ExportDecl;
+ using ExportDecl = llvm::PointerIntPair<Module *, 1, bool>;
/// \brief The set of export declarations.
SmallVector<ExportDecl, 2> Exports;
@@ -294,9 +310,9 @@ public:
/// \brief A library or framework to link against when an entity from this
/// module is used.
struct LinkLibrary {
- LinkLibrary() : IsFramework(false) { }
+ LinkLibrary() = default;
LinkLibrary(const std::string &Library, bool IsFramework)
- : Library(Library), IsFramework(IsFramework) { }
+ : Library(Library), IsFramework(IsFramework) {}
/// \brief The library to link against.
///
@@ -305,7 +321,7 @@ public:
std::string Library;
/// \brief Whether this is a framework rather than a library.
- bool IsFramework;
+ bool IsFramework = false;
};
/// \brief The set of libraries or frameworks to link against when
@@ -391,6 +407,15 @@ public:
return IsFramework && Parent && Parent->isPartOfFramework();
}
+ /// Set the parent of this module. This should only be used if the parent
+ /// could not be set during module creation.
+ void setParent(Module *M) {
+ assert(!Parent);
+ Parent = M;
+ Parent->SubModuleIndex[Name] = Parent->SubModules.size();
+ Parent->SubModules.push_back(this);
+ }
+
/// \brief Retrieve the full name of this module, including the path from
/// its top-level module.
/// \param AllowStringLiterals If \c true, components that might not be
@@ -415,7 +440,6 @@ public:
const Module *getTopLevelModule() const;
/// \brief Retrieve the name of the top-level module.
- ///
StringRef getTopLevelModuleName() const {
return getTopLevelModule()->Name;
}
@@ -508,8 +532,8 @@ public:
unsigned getVisibilityID() const { return VisibilityID; }
- typedef std::vector<Module *>::iterator submodule_iterator;
- typedef std::vector<Module *>::const_iterator submodule_const_iterator;
+ using submodule_iterator = std::vector<Module *>::iterator;
+ using submodule_const_iterator = std::vector<Module *>::const_iterator;
submodule_iterator submodule_begin() { return SubModules.begin(); }
submodule_const_iterator submodule_begin() const {return SubModules.begin();}
@@ -534,7 +558,6 @@ public:
}
/// \brief Print the module map for this module to the given stream.
- ///
void print(raw_ostream &OS, unsigned Indent = 0) const;
/// \brief Dump the contents of this module to the given output stream.
@@ -547,7 +570,7 @@ private:
/// \brief A set of visible modules.
class VisibleModuleSet {
public:
- VisibleModuleSet() : Generation(0) {}
+ VisibleModuleSet() = default;
VisibleModuleSet(VisibleModuleSet &&O)
: ImportLocs(std::move(O.ImportLocs)), Generation(O.Generation ? 1 : 0) {
O.ImportLocs.clear();
@@ -582,13 +605,15 @@ public:
/// \brief A callback to call when a module is made visible (directly or
/// indirectly) by a call to \ref setVisible.
- typedef llvm::function_ref<void(Module *M)> VisibleCallback;
+ using VisibleCallback = llvm::function_ref<void(Module *M)>;
+
/// \brief A callback to call when a module conflict is found. \p Path
/// consists of a sequence of modules from the conflicting module to the one
/// made visible, where each was exported by the next.
- typedef llvm::function_ref<void(ArrayRef<Module *> Path,
- Module *Conflict, StringRef Message)>
- ConflictCallback;
+ using ConflictCallback =
+ llvm::function_ref<void(ArrayRef<Module *> Path, Module *Conflict,
+ StringRef Message)>;
+
/// \brief Make a specific module visible.
void setVisible(Module *M, SourceLocation Loc,
VisibleCallback Vis = [](Module *) {},
@@ -599,11 +624,11 @@ private:
/// Import locations for each visible module. Indexed by the module's
/// VisibilityID.
std::vector<SourceLocation> ImportLocs;
+
/// Visibility generation, bumped every time the visibility state changes.
- unsigned Generation;
+ unsigned Generation = 0;
};
-} // end namespace clang
-
+} // namespace clang
#endif // LLVM_CLANG_BASIC_MODULE_H
diff --git a/include/clang/Basic/OpenCLExtensions.def b/include/clang/Basic/OpenCLExtensions.def
index 360fec4281ac..c3319d2d808b 100644
--- a/include/clang/Basic/OpenCLExtensions.def
+++ b/include/clang/Basic/OpenCLExtensions.def
@@ -79,6 +79,10 @@ OPENCLEXT_INTERNAL(cl_clang_storage_class_specifiers, 100, ~0U)
OPENCLEXT_INTERNAL(cl_amd_media_ops, 100, ~0U)
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)
+
#undef OPENCLEXT_INTERNAL
#ifdef OPENCLEXT
diff --git a/include/clang/Basic/OpenMPKinds.def b/include/clang/Basic/OpenMPKinds.def
index 645ed52b59ca..6a0bed7ab15f 100644
--- a/include/clang/Basic/OpenMPKinds.def
+++ b/include/clang/Basic/OpenMPKinds.def
@@ -274,6 +274,7 @@ OPENMP_CLAUSE(from, OMPFromClause)
OPENMP_CLAUSE(use_device_ptr, OMPUseDevicePtrClause)
OPENMP_CLAUSE(is_device_ptr, OMPIsDevicePtrClause)
OPENMP_CLAUSE(task_reduction, OMPTaskReductionClause)
+OPENMP_CLAUSE(in_reduction, OMPInReductionClause)
// Clauses allowed for OpenMP directive 'parallel'.
OPENMP_PARALLEL_CLAUSE(if)
@@ -434,6 +435,7 @@ OPENMP_TASK_CLAUSE(untied)
OPENMP_TASK_CLAUSE(mergeable)
OPENMP_TASK_CLAUSE(depend)
OPENMP_TASK_CLAUSE(priority)
+OPENMP_TASK_CLAUSE(in_reduction)
// Clauses allowed for OpenMP directive 'atomic'.
OPENMP_ATOMIC_CLAUSE(read)
@@ -452,6 +454,7 @@ OPENMP_TARGET_CLAUSE(depend)
OPENMP_TARGET_CLAUSE(defaultmap)
OPENMP_TARGET_CLAUSE(firstprivate)
OPENMP_TARGET_CLAUSE(is_device_ptr)
+OPENMP_TARGET_CLAUSE(reduction)
// Clauses allowed for OpenMP directive 'target data'.
OPENMP_TARGET_DATA_CLAUSE(if)
@@ -557,6 +560,7 @@ OPENMP_TASKLOOP_CLAUSE(grainsize)
OPENMP_TASKLOOP_CLAUSE(nogroup)
OPENMP_TASKLOOP_CLAUSE(num_tasks)
OPENMP_TASKLOOP_CLAUSE(reduction)
+OPENMP_TASKLOOP_CLAUSE(in_reduction)
// Clauses allowed for OpenMP directive 'taskloop simd'.
OPENMP_TASKLOOP_SIMD_CLAUSE(if)
@@ -578,6 +582,7 @@ OPENMP_TASKLOOP_SIMD_CLAUSE(grainsize)
OPENMP_TASKLOOP_SIMD_CLAUSE(nogroup)
OPENMP_TASKLOOP_SIMD_CLAUSE(num_tasks)
OPENMP_TASKLOOP_SIMD_CLAUSE(reduction)
+OPENMP_TASKLOOP_SIMD_CLAUSE(in_reduction)
// Clauses allowed for OpenMP directive 'critical'.
OPENMP_CRITICAL_CLAUSE(hint)
@@ -741,9 +746,9 @@ OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(private)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(shared)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(reduction)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(schedule)
-OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(linear)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(num_teams)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(thread_limit)
+OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(copyin)
// Clauses allowed for OpenMP directive 'target teams'.
OPENMP_TARGET_TEAMS_CLAUSE(if)
@@ -801,7 +806,6 @@ OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(dist_schedule)
OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(num_threads)
OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(proc_bind)
OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(schedule)
-OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(linear)
// Clauses allowed for OpenMP directive
// 'target teams distribute parallel for simd'.
diff --git a/include/clang/Basic/OperatorKinds.def b/include/clang/Basic/OperatorKinds.def
index 34ad7644cd2b..d86294bac902 100644
--- a/include/clang/Basic/OperatorKinds.def
+++ b/include/clang/Basic/OperatorKinds.def
@@ -89,6 +89,7 @@ OVERLOADED_OPERATOR(EqualEqual , "==" , equalequal , false, t
OVERLOADED_OPERATOR(ExclaimEqual , "!=" , exclaimequal , false, true , false)
OVERLOADED_OPERATOR(LessEqual , "<=" , lessequal , false, true , false)
OVERLOADED_OPERATOR(GreaterEqual , ">=" , greaterequal , false, true , false)
+OVERLOADED_OPERATOR(Spaceship , "<=>" , spaceship , false, true , false)
OVERLOADED_OPERATOR(AmpAmp , "&&" , ampamp , false, true , false)
OVERLOADED_OPERATOR(PipePipe , "||" , pipepipe , false, true , false)
OVERLOADED_OPERATOR(PlusPlus , "++" , plusplus , true , true , false)
diff --git a/include/clang/Basic/OperatorPrecedence.h b/include/clang/Basic/OperatorPrecedence.h
index 640749fdd10d..94978f81e543 100644
--- a/include/clang/Basic/OperatorPrecedence.h
+++ b/include/clang/Basic/OperatorPrecedence.h
@@ -36,10 +36,11 @@ namespace prec {
And = 8, // &
Equality = 9, // ==, !=
Relational = 10, // >=, <=, >, <
- Shift = 11, // <<, >>
- Additive = 12, // -, +
- Multiplicative = 13, // *, /, %
- PointerToMember = 14 // .*, ->*
+ Spaceship = 11, // <=>
+ Shift = 12, // <<, >>
+ Additive = 13, // -, +
+ Multiplicative = 14, // *, /, %
+ PointerToMember = 15 // .*, ->*
};
}
diff --git a/include/clang/Basic/SanitizerBlacklist.h b/include/clang/Basic/SanitizerBlacklist.h
index e651e1831683..1ae5c36eea99 100644
--- a/include/clang/Basic/SanitizerBlacklist.h
+++ b/include/clang/Basic/SanitizerBlacklist.h
@@ -15,29 +15,30 @@
#define LLVM_CLANG_BASIC_SANITIZERBLACKLIST_H
#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SanitizerSpecialCaseList.h"
+#include "clang/Basic/Sanitizers.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/SpecialCaseList.h"
#include <memory>
namespace clang {
class SanitizerBlacklist {
- std::unique_ptr<llvm::SpecialCaseList> SCL;
+ std::unique_ptr<SanitizerSpecialCaseList> SSCL;
SourceManager &SM;
public:
SanitizerBlacklist(const std::vector<std::string> &BlacklistPaths,
SourceManager &SM);
- bool isBlacklistedGlobal(StringRef GlobalName,
+ bool isBlacklistedGlobal(SanitizerMask Mask, StringRef GlobalName,
StringRef Category = StringRef()) const;
- bool isBlacklistedType(StringRef MangledTypeName,
+ bool isBlacklistedType(SanitizerMask Mask, StringRef MangledTypeName,
StringRef Category = StringRef()) const;
- bool isBlacklistedFunction(StringRef FunctionName) const;
- bool isBlacklistedFile(StringRef FileName,
+ bool isBlacklistedFunction(SanitizerMask Mask, StringRef FunctionName) const;
+ bool isBlacklistedFile(SanitizerMask Mask, StringRef FileName,
StringRef Category = StringRef()) const;
- bool isBlacklistedLocation(SourceLocation Loc,
+ bool isBlacklistedLocation(SanitizerMask Mask, SourceLocation Loc,
StringRef Category = StringRef()) const;
};
diff --git a/include/clang/Basic/SanitizerSpecialCaseList.h b/include/clang/Basic/SanitizerSpecialCaseList.h
new file mode 100644
index 000000000000..e3252022a44f
--- /dev/null
+++ b/include/clang/Basic/SanitizerSpecialCaseList.h
@@ -0,0 +1,54 @@
+//===--- SanitizerSpecialCaseList.h - SCL for sanitizers --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// An extension of SpecialCaseList to allowing querying sections by
+// SanitizerMask.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_BASIC_SANITIZERSPECIALCASELIST_H
+#define LLVM_CLANG_BASIC_SANITIZERSPECIALCASELIST_H
+
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/Sanitizers.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/SpecialCaseList.h"
+#include <memory>
+
+namespace clang {
+
+class SanitizerSpecialCaseList : public llvm::SpecialCaseList {
+public:
+ static std::unique_ptr<SanitizerSpecialCaseList>
+ create(const std::vector<std::string> &Paths, std::string &Error);
+
+ static std::unique_ptr<SanitizerSpecialCaseList>
+ createOrDie(const std::vector<std::string> &Paths);
+
+ // Query blacklisted entries if any bit in Mask matches the entry's section.
+ bool inSection(SanitizerMask Mask, StringRef Prefix, StringRef Query,
+ StringRef Category = StringRef()) const;
+
+protected:
+ // Initialize SanitizerSections.
+ void createSanitizerSections();
+
+ struct SanitizerSection {
+ SanitizerSection(SanitizerMask SM, SectionEntries &E)
+ : Mask(SM), Entries(E){};
+
+ SanitizerMask Mask;
+ SectionEntries &Entries;
+ };
+
+ std::vector<SanitizerSection> SanitizerSections;
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/Sanitizers.def b/include/clang/Basic/Sanitizers.def
index 71b11974dbfd..30d5cc8166dc 100644
--- a/include/clang/Basic/Sanitizers.def
+++ b/include/clang/Basic/Sanitizers.def
@@ -44,12 +44,17 @@ SANITIZER("address", Address)
// Kernel AddressSanitizer (KASan)
SANITIZER("kernel-address", KernelAddress)
+SANITIZER("hwaddress", HWAddress)
+
// MemorySanitizer
SANITIZER("memory", Memory)
// libFuzzer
SANITIZER("fuzzer", Fuzzer)
+// libFuzzer-required instrumentation, no linking.
+SANITIZER("fuzzer-no-link", FuzzerNoLink)
+
// ThreadSanitizer
SANITIZER("thread", Thread)
@@ -60,6 +65,7 @@ SANITIZER("leak", Leak)
SANITIZER("alignment", Alignment)
SANITIZER("array-bounds", ArrayBounds)
SANITIZER("bool", Bool)
+SANITIZER("builtin", Builtin)
SANITIZER("enum", Enum)
SANITIZER("float-cast-overflow", FloatCastOverflow)
SANITIZER("float-divide-by-zero", FloatDivideByZero)
@@ -107,11 +113,12 @@ SANITIZER("safe-stack", SafeStack)
// -fsanitize=undefined includes all the sanitizers which have low overhead, no
// ABI or address space layout implications, and only catch undefined behavior.
SANITIZER_GROUP("undefined", Undefined,
- Alignment | Bool | ArrayBounds | Enum | FloatCastOverflow |
- FloatDivideByZero | IntegerDivideByZero | NonnullAttribute |
- Null | ObjectSize | PointerOverflow | Return |
- ReturnsNonnullAttribute | Shift | SignedIntegerOverflow |
- Unreachable | VLABound | Function | Vptr)
+ Alignment | Bool | Builtin | ArrayBounds | Enum |
+ FloatCastOverflow | FloatDivideByZero |
+ IntegerDivideByZero | NonnullAttribute | Null | ObjectSize |
+ PointerOverflow | Return | ReturnsNonnullAttribute | Shift |
+ SignedIntegerOverflow | Unreachable | VLABound | Function |
+ Vptr)
// -fsanitize=undefined-trap is an alias for -fsanitize=undefined.
SANITIZER_GROUP("undefined-trap", UndefinedTrap, Undefined)
@@ -130,6 +137,9 @@ SANITIZER("efficiency-working-set", EfficiencyWorkingSet)
SANITIZER_GROUP("efficiency-all", Efficiency,
EfficiencyCacheFrag | EfficiencyWorkingSet)
+// Scudo hardened allocator
+SANITIZER("scudo", Scudo)
+
// Magic group, containing all sanitizers. For example, "-fno-sanitize=all"
// can be used to disable all the sanitizers.
SANITIZER_GROUP("all", All, ~0ULL)
diff --git a/include/clang/Basic/Sanitizers.h b/include/clang/Basic/Sanitizers.h
index 5317720095e0..1b936c7d115c 100644
--- a/include/clang/Basic/Sanitizers.h
+++ b/include/clang/Basic/Sanitizers.h
@@ -80,7 +80,7 @@ SanitizerMask parseSanitizerValue(StringRef Value, bool AllowGroups);
SanitizerMask expandSanitizerGroups(SanitizerMask Kinds);
/// Return the sanitizers which do not affect preprocessing.
-static inline SanitizerMask getPPTransparentSanitizers() {
+inline SanitizerMask getPPTransparentSanitizers() {
return SanitizerKind::CFI | SanitizerKind::Integer |
SanitizerKind::Nullability | SanitizerKind::Undefined;
}
diff --git a/include/clang/Basic/SourceLocation.h b/include/clang/Basic/SourceLocation.h
index 12aa0e4f5717..7418b50f9d83 100644
--- a/include/clang/Basic/SourceLocation.h
+++ b/include/clang/Basic/SourceLocation.h
@@ -39,10 +39,9 @@ class SourceManager;
class FileID {
/// \brief A mostly-opaque identifier, where 0 is "invalid", >0 is
/// this module, and <-1 is something loaded from another module.
- int ID;
-public:
- FileID() : ID(0) {}
+ int ID = 0;
+public:
bool isValid() const { return ID != 0; }
bool isInvalid() const { return ID == 0; }
@@ -86,17 +85,15 @@ private:
///
/// It is important that this type remains small. It is currently 32 bits wide.
class SourceLocation {
- unsigned ID;
+ unsigned ID = 0;
friend class SourceManager;
friend class ASTReader;
friend class ASTWriter;
enum : unsigned {
MacroIDBit = 1U << 31
};
-public:
-
- SourceLocation() : ID(0) {}
+public:
bool isFileID() const { return (ID & MacroIDBit) == 0; }
bool isMacroID() const { return (ID & MacroIDBit) != 0; }
@@ -172,6 +169,11 @@ public:
return getFromRawEncoding((unsigned)(uintptr_t)Encoding);
}
+ static bool isPairOfFileLocations(SourceLocation Start, SourceLocation End) {
+ return Start.isValid() && Start.isFileID() && End.isValid() &&
+ End.isFileID();
+ }
+
void print(raw_ostream &OS, const SourceManager &SM) const;
std::string printToString(const SourceManager &SM) const;
void dump(const SourceManager &SM) const;
@@ -193,8 +195,9 @@ inline bool operator<(const SourceLocation &LHS, const SourceLocation &RHS) {
class SourceRange {
SourceLocation B;
SourceLocation E;
+
public:
- SourceRange(): B(SourceLocation()), E(SourceLocation()) {}
+ SourceRange() = default;
SourceRange(SourceLocation loc) : B(loc), E(loc) {}
SourceRange(SourceLocation begin, SourceLocation end) : B(begin), E(end) {}
@@ -225,9 +228,10 @@ public:
/// range.
class CharSourceRange {
SourceRange Range;
- bool IsTokenRange;
+ bool IsTokenRange = false;
+
public:
- CharSourceRange() : IsTokenRange(false) {}
+ CharSourceRange() = default;
CharSourceRange(SourceRange R, bool ITR) : Range(R), IsTokenRange(ITR) {}
static CharSourceRange getTokenRange(SourceRange R) {
@@ -325,10 +329,11 @@ class FileEntry;
///
/// This is useful for argument passing to functions that expect both objects.
class FullSourceLoc : public SourceLocation {
- const SourceManager *SrcMgr;
+ const SourceManager *SrcMgr = nullptr;
+
public:
/// \brief Creates a FullSourceLoc where isValid() returns \c false.
- explicit FullSourceLoc() : SrcMgr(nullptr) {}
+ FullSourceLoc() = default;
explicit FullSourceLoc(SourceLocation Loc, const SourceManager &SM)
: SourceLocation(Loc), SrcMgr(&SM) {}
@@ -455,8 +460,7 @@ namespace llvm {
// Teach SmallPtrSet how to handle SourceLocation.
template<>
- class PointerLikeTypeTraits<clang::SourceLocation> {
- public:
+ struct PointerLikeTypeTraits<clang::SourceLocation> {
static inline void *getAsVoidPointer(clang::SourceLocation L) {
return L.getPtrEncoding();
}
diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h
index ed3f8dfa86e7..397ad2e77fb5 100644
--- a/include/clang/Basic/SourceManager.h
+++ b/include/clang/Basic/SourceManager.h
@@ -1,4 +1,4 @@
-//===--- SourceManager.h - Track and cache source files ---------*- C++ -*-===//
+//===- SourceManager.h - Track and cache source files -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,7 +6,7 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-///
+//
/// \file
/// \brief Defines the SourceManager interface.
///
@@ -29,14 +29,13 @@
/// location in the source where the macro was originally defined,
/// and the presumed location is where the line directive states that
/// the line is 17, or any other line.
-///
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_SOURCEMANAGER_H
#define LLVM_CLANG_BASIC_SOURCEMANAGER_H
#include "clang/Basic/FileManager.h"
-#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitVector.h"
@@ -49,10 +48,8 @@
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/MemoryBuffer.h"
-#include <algorithm>
#include <cassert>
#include <cstddef>
-#include <cstdint>
#include <map>
#include <memory>
#include <string>
@@ -69,7 +66,6 @@ class SourceManager;
/// \brief Public enums and private classes that are part of the
/// SourceManager implementation.
-///
namespace SrcMgr {
/// \brief Indicates whether a file or directory holds normal user code,
@@ -100,6 +96,7 @@ namespace SrcMgr {
enum CCFlags {
/// \brief Whether the buffer is invalid.
InvalidFlag = 0x01,
+
/// \brief Whether the buffer should not be freed on destruction.
DoNotFreeFlag = 0x02
};
@@ -130,12 +127,12 @@ namespace SrcMgr {
///
/// This is lazily computed. This is owned by the SourceManager
/// BumpPointerAllocator object.
- unsigned *SourceLineCache;
+ unsigned *SourceLineCache = nullptr;
/// \brief The number of lines in this ContentCache.
///
/// This is only valid if SourceLineCache is non-null.
- unsigned NumLines;
+ unsigned NumLines = 0;
/// \brief Indicates whether the buffer itself was provided to override
/// the actual file contents.
@@ -157,15 +154,14 @@ namespace SrcMgr {
ContentCache(const FileEntry *Ent, const FileEntry *contentEnt)
: Buffer(nullptr, false), OrigEntry(Ent), ContentsEntry(contentEnt),
- SourceLineCache(nullptr), NumLines(0), BufferOverridden(false),
- IsSystemFile(false), IsTransient(false) {}
+ BufferOverridden(false), IsSystemFile(false), IsTransient(false) {}
/// The copy ctor does not allow copies where source object has either
/// a non-NULL Buffer or SourceLineCache. Ownership of allocated memory
/// is not transferred, so this is a logical error.
ContentCache(const ContentCache &RHS)
- : Buffer(nullptr, false), SourceLineCache(nullptr),
- BufferOverridden(false), IsSystemFile(false), IsTransient(false) {
+ : Buffer(nullptr, false), BufferOverridden(false), IsSystemFile(false),
+ IsTransient(false) {
OrigEntry = RHS.OrigEntry;
ContentsEntry = RHS.ContentsEntry;
@@ -212,12 +208,6 @@ namespace SrcMgr {
/// this content cache. This is used for performance analysis.
llvm::MemoryBuffer::BufferKind getMemoryBufferKind() const;
- void setBuffer(std::unique_ptr<llvm::MemoryBuffer> B) {
- assert(!Buffer.getPointer() && "MemoryBuffer already set.");
- Buffer.setPointer(B.release());
- Buffer.setInt(0);
- }
-
/// \brief Get the underlying buffer, returning NULL if the buffer is not
/// yet available.
llvm::MemoryBuffer *getRawBuffer() const { return Buffer.getPointer(); }
@@ -252,6 +242,10 @@ namespace SrcMgr {
/// FileInfos contain a "ContentCache *", with the contents of the file.
///
class FileInfo {
+ friend class clang::SourceManager;
+ friend class clang::ASTWriter;
+ friend class clang::ASTReader;
+
/// \brief The location of the \#include that brought in this file.
///
/// This is an invalid SLOC for the main file (top of the \#include chain).
@@ -270,10 +264,6 @@ namespace SrcMgr {
llvm::PointerIntPair<const ContentCache*, 3, CharacteristicKind>
ContentAndKind;
- friend class clang::SourceManager;
- friend class clang::ASTWriter;
- friend class clang::ASTReader;
-
public:
/// \brief Return a FileInfo object.
static FileInfo get(SourceLocation IL, const ContentCache *Con,
@@ -454,7 +444,7 @@ namespace SrcMgr {
}
};
-} // end SrcMgr namespace.
+} // namespace SrcMgr
/// \brief External source of source location entries.
class ExternalSLocEntrySource {
@@ -552,7 +542,7 @@ public:
/// \brief The stack used when building modules on demand, which is used
/// to provide a link between the source managers of the different compiler
/// instances.
-typedef ArrayRef<std::pair<std::string, FullSourceLoc>> ModuleBuildStack;
+using ModuleBuildStack = ArrayRef<std::pair<std::string, FullSourceLoc>>;
/// \brief This class handles loading and caching of source files into memory.
///
@@ -584,7 +574,7 @@ class SourceManager : public RefCountedBase<SourceManager> {
/// \brief True if the ContentCache for files that are overridden by other
/// files, should report the original file name. Defaults to true.
- bool OverridenFilesKeepOriginalName;
+ bool OverridenFilesKeepOriginalName = true;
/// \brief True if non-system source files should be treated as volatile
/// (likely to change while trying to use them). Defaults to false.
@@ -593,12 +583,13 @@ class SourceManager : public RefCountedBase<SourceManager> {
/// \brief True if all files read during this compilation should be treated
/// as transient (may not be present in later compilations using a module
/// file created from this compilation). Defaults to false.
- bool FilesAreTransient;
+ bool FilesAreTransient = false;
struct OverriddenFilesInfoTy {
/// \brief Files that have been overridden with the contents from another
/// file.
llvm::DenseMap<const FileEntry *, const FileEntry *> OverriddenFiles;
+
/// \brief Files that were overridden with a memory buffer.
llvm::DenseSet<const FileEntry *> OverriddenFilesWithBuffer;
};
@@ -653,7 +644,7 @@ class SourceManager : public RefCountedBase<SourceManager> {
llvm::BitVector SLocEntryLoaded;
/// \brief An external source for source location entries.
- ExternalSLocEntrySource *ExternalSLocEntries;
+ ExternalSLocEntrySource *ExternalSLocEntries = nullptr;
/// \brief A one-entry cache to speed up getFileID.
///
@@ -664,7 +655,7 @@ class SourceManager : public RefCountedBase<SourceManager> {
/// \brief Holds information for \#line directives.
///
/// This is referenced by indices from SLocEntryTable.
- LineTableInfo *LineTable;
+ LineTableInfo *LineTable = nullptr;
/// \brief These ivars serve as a cache used in the getLineNumber
/// method which is used to speedup getLineNumber calls to nearby locations.
@@ -680,7 +671,8 @@ class SourceManager : public RefCountedBase<SourceManager> {
FileID PreambleFileID;
// Statistics for -print-stats.
- mutable unsigned NumLinearScans, NumBinaryProbes;
+ mutable unsigned NumLinearScans = 0;
+ mutable unsigned NumBinaryProbes = 0;
/// \brief Associates a FileID with its "included/expanded in" decomposed
/// location.
@@ -690,12 +682,12 @@ class SourceManager : public RefCountedBase<SourceManager> {
mutable llvm::DenseMap<FileID, std::pair<FileID, unsigned>> IncludedLocMap;
/// The key value into the IsBeforeInTUCache table.
- typedef std::pair<FileID, FileID> IsBeforeInTUCacheKey;
+ using IsBeforeInTUCacheKey = std::pair<FileID, FileID>;
/// The IsBeforeInTranslationUnitCache is a mapping from FileID pairs
/// to cache results.
- typedef llvm::DenseMap<IsBeforeInTUCacheKey, InBeforeInTUCacheEntry>
- InBeforeInTUCache;
+ using InBeforeInTUCache =
+ llvm::DenseMap<IsBeforeInTUCacheKey, InBeforeInTUCacheEntry>;
/// Cache results for the isBeforeInTranslationUnit method.
mutable InBeforeInTUCache IBTUCache;
@@ -712,7 +704,7 @@ class SourceManager : public RefCountedBase<SourceManager> {
/// \brief Lazily computed map of macro argument chunks to their expanded
/// source location.
- typedef std::map<unsigned, SourceLocation> MacroArgsMap;
+ using MacroArgsMap = std::map<unsigned, SourceLocation>;
mutable llvm::DenseMap<FileID, std::unique_ptr<MacroArgsMap>>
MacroArgsCacheMap;
@@ -816,7 +808,22 @@ public:
SrcMgr::CharacteristicKind FileCharacter = SrcMgr::C_User,
int LoadedID = 0, unsigned LoadedOffset = 0,
SourceLocation IncludeLoc = SourceLocation()) {
- return createFileID(createMemBufferContentCache(std::move(Buffer)),
+ return createFileID(
+ createMemBufferContentCache(Buffer.release(), /*DoNotFree*/ false),
+ IncludeLoc, FileCharacter, LoadedID, LoadedOffset);
+ }
+
+ enum UnownedTag { Unowned };
+
+ /// \brief Create a new FileID that represents the specified memory buffer.
+ ///
+ /// This does no caching of the buffer and takes ownership of the
+ /// MemoryBuffer, so only pass a MemoryBuffer to this once.
+ FileID createFileID(UnownedTag, llvm::MemoryBuffer *Buffer,
+ SrcMgr::CharacteristicKind FileCharacter = SrcMgr::C_User,
+ int LoadedID = 0, unsigned LoadedOffset = 0,
+ SourceLocation IncludeLoc = SourceLocation()) {
+ return createFileID(createMemBufferContentCache(Buffer, /*DoNotFree*/true),
IncludeLoc, FileCharacter, LoadedID, LoadedOffset);
}
@@ -1408,7 +1415,6 @@ public:
//===--------------------------------------------------------------------===//
/// \brief Return the uniqued ID for the specified filename.
- ///
unsigned getLineTableFilenameID(StringRef Str);
/// \brief Add a line note to the line table for the FileID and offset
@@ -1520,9 +1526,18 @@ public:
return LHSLoaded;
}
+ /// Return true if the Point is within Start and End.
+ bool isPointWithin(SourceLocation Location, SourceLocation Start,
+ SourceLocation End) const {
+ return Location == Start || Location == End ||
+ (isBeforeInTranslationUnit(Start, Location) &&
+ isBeforeInTranslationUnit(Location, End));
+ }
+
// Iterators over FileInfos.
- typedef llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*>
- ::const_iterator fileinfo_iterator;
+ using fileinfo_iterator =
+ llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*>::const_iterator;
+
fileinfo_iterator fileinfo_begin() const { return FileInfos.begin(); }
fileinfo_iterator fileinfo_end() const { return FileInfos.end(); }
bool hasFileInfo(const FileEntry *File) const {
@@ -1530,7 +1545,6 @@ public:
}
/// \brief Print statistics to stderr.
- ///
void PrintStats() const;
void dump() const;
@@ -1621,6 +1635,9 @@ public:
}
private:
+ friend class ASTReader;
+ friend class ASTWriter;
+
llvm::MemoryBuffer *getFakeBufferForRecovery() const;
const SrcMgr::ContentCache *getFakeContentCacheForRecovery() const;
@@ -1691,7 +1708,7 @@ private:
/// \brief Create a new ContentCache for the specified memory buffer.
const SrcMgr::ContentCache *
- createMemBufferContentCache(std::unique_ptr<llvm::MemoryBuffer> Buf);
+ createMemBufferContentCache(llvm::MemoryBuffer *Buf, bool DoNotFree);
FileID getFileIDSlow(unsigned SLocOffset) const;
FileID getFileIDLocal(unsigned SLocOffset) const;
@@ -1712,8 +1729,6 @@ private:
SourceLocation SpellLoc,
SourceLocation ExpansionLoc,
unsigned ExpansionLength) const;
- friend class ASTReader;
- friend class ASTWriter;
};
/// \brief Comparison function object.
@@ -1726,7 +1741,7 @@ class BeforeThanCompare<SourceLocation> {
SourceManager &SM;
public:
- explicit BeforeThanCompare(SourceManager &SM) : SM(SM) { }
+ explicit BeforeThanCompare(SourceManager &SM) : SM(SM) {}
bool operator()(SourceLocation LHS, SourceLocation RHS) const {
return SM.isBeforeInTranslationUnit(LHS, RHS);
@@ -1739,13 +1754,13 @@ class BeforeThanCompare<SourceRange> {
SourceManager &SM;
public:
- explicit BeforeThanCompare(SourceManager &SM) : SM(SM) { }
+ explicit BeforeThanCompare(SourceManager &SM) : SM(SM) {}
bool operator()(SourceRange LHS, SourceRange RHS) const {
return SM.isBeforeInTranslationUnit(LHS.getBegin(), RHS.getBegin());
}
};
-} // end namespace clang
+} // namespace clang
#endif // LLVM_CLANG_BASIC_SOURCEMANAGER_H
diff --git a/include/clang/Basic/SourceManagerInternals.h b/include/clang/Basic/SourceManagerInternals.h
index 9403dea8889c..edd910e70412 100644
--- a/include/clang/Basic/SourceManagerInternals.h
+++ b/include/clang/Basic/SourceManagerInternals.h
@@ -1,4 +1,4 @@
-//===--- SourceManagerInternals.h - SourceManager Internals -----*- C++ -*-===//
+//===- SourceManagerInternals.h - SourceManager Internals -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,10 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-///
+//
/// \file
/// \brief Defines implementation details of the clang::SourceManager class.
-///
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_SOURCEMANAGERINTERNALS_H
@@ -18,7 +18,11 @@
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Allocator.h"
+#include <cassert>
#include <map>
+#include <vector>
namespace clang {
@@ -86,7 +90,8 @@ class LineTableInfo {
/// \brief Map from FileIDs to a list of line entries (sorted by the offset
/// at which they occur in the file).
- std::map<FileID, std::vector<LineEntry> > LineEntries;
+ std::map<FileID, std::vector<LineEntry>> LineEntries;
+
public:
void clear() {
FilenameIDs.clear();
@@ -95,10 +100,12 @@ public:
}
unsigned getLineTableFilenameID(StringRef Str);
+
StringRef getFilename(unsigned ID) const {
assert(ID < FilenamesByID.size() && "Invalid FilenameID");
return FilenamesByID[ID]->getKey();
}
+
unsigned getNumFilenames() const { return FilenamesByID.size(); }
void AddLineNote(FileID FID, unsigned Offset,
@@ -112,7 +119,8 @@ public:
const LineEntry *FindNearestLineEntry(FileID FID, unsigned Offset);
// Low-level access
- typedef std::map<FileID, std::vector<LineEntry> >::iterator iterator;
+ using iterator = std::map<FileID, std::vector<LineEntry>>::iterator;
+
iterator begin() { return LineEntries.begin(); }
iterator end() { return LineEntries.end(); }
@@ -121,6 +129,6 @@ public:
void AddEntry(FileID FID, const std::vector<LineEntry> &Entries);
};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_BASIC_SOURCEMANAGERINTERNALS_H
diff --git a/include/clang/Basic/Specifiers.h b/include/clang/Basic/Specifiers.h
index 50fb936e01d1..377534baab06 100644
--- a/include/clang/Basic/Specifiers.h
+++ b/include/clang/Basic/Specifiers.h
@@ -52,6 +52,7 @@ namespace clang {
TST_int,
TST_int128,
TST_half, // OpenCL half, ARM NEON __fp16
+ TST_Float16, // C11 extension ISO/IEC TS 18661-3
TST_float,
TST_double,
TST_float128,
diff --git a/include/clang/Basic/SyncScope.h b/include/clang/Basic/SyncScope.h
new file mode 100644
index 000000000000..09ac0052185a
--- /dev/null
+++ b/include/clang/Basic/SyncScope.h
@@ -0,0 +1,154 @@
+//===--- SyncScope.h - Atomic synchronization scopes ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Provides definitions for the atomic synchronization scopes.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_SYNCSCOPE_H
+#define LLVM_CLANG_BASIC_SYNCSCOPE_H
+
+#include "clang/Basic/LangOptions.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include <memory>
+
+namespace clang {
+
+/// \brief Defines synch scope values used internally by clang.
+///
+/// The enum values start from 0 and are contiguous. They are mainly used for
+/// enumerating all supported synch scope values and mapping them to LLVM
+/// synch scopes. Their numerical values may be different from the corresponding
+/// synch scope enums used in source languages.
+///
+/// In atomic builtin and expressions, language-specific synch scope enums are
+/// used. Currently only OpenCL memory scope enums are supported and assumed
+/// to be used by all languages. However, in the future, other languages may
+/// define their own set of synch scope enums. The language-specific synch scope
+/// values are represented by class AtomicScopeModel and its derived classes.
+///
+/// To add a new enum value:
+/// Add the enum value to enum class SyncScope.
+/// Update enum value Last if necessary.
+/// Update getAsString.
+///
+enum class SyncScope {
+ OpenCLWorkGroup,
+ OpenCLDevice,
+ OpenCLAllSVMDevices,
+ OpenCLSubGroup,
+ Last = OpenCLSubGroup
+};
+
+inline llvm::StringRef getAsString(SyncScope S) {
+ switch (S) {
+ case SyncScope::OpenCLWorkGroup:
+ return "opencl_workgroup";
+ case SyncScope::OpenCLDevice:
+ return "opencl_device";
+ case SyncScope::OpenCLAllSVMDevices:
+ return "opencl_allsvmdevices";
+ case SyncScope::OpenCLSubGroup:
+ return "opencl_subgroup";
+ }
+ llvm_unreachable("Invalid synch scope");
+}
+
+/// \brief Defines the kind of atomic scope models.
+enum class AtomicScopeModelKind { None, OpenCL };
+
+/// \brief Defines the interface for synch scope model.
+class AtomicScopeModel {
+public:
+ virtual ~AtomicScopeModel() {}
+ /// \brief Maps language specific synch scope values to internal
+ /// SyncScope enum.
+ virtual SyncScope map(unsigned S) const = 0;
+
+ /// \brief Check if the compile-time constant synch scope value
+ /// is valid.
+ virtual bool isValid(unsigned S) const = 0;
+
+ /// \brief Get all possible synch scope values that might be
+ /// encountered at runtime for the current language.
+ virtual ArrayRef<unsigned> getRuntimeValues() const = 0;
+
+ /// \brief If atomic builtin function is called with invalid
+ /// synch scope value at runtime, it will fall back to a valid
+ /// synch scope value returned by this function.
+ virtual unsigned getFallBackValue() const = 0;
+
+ /// \brief Create an atomic scope model by AtomicScopeModelKind.
+ /// \return an empty std::unique_ptr for AtomicScopeModelKind::None.
+ static std::unique_ptr<AtomicScopeModel> create(AtomicScopeModelKind K);
+};
+
+/// \brief Defines the synch scope model for OpenCL.
+class AtomicScopeOpenCLModel : public AtomicScopeModel {
+public:
+ /// The enum values match the pre-defined macros
+ /// __OPENCL_MEMORY_SCOPE_*, which are used to define memory_scope_*
+ /// enums in opencl-c.h.
+ enum ID {
+ WorkGroup = 1,
+ Device = 2,
+ AllSVMDevices = 3,
+ SubGroup = 4,
+ Last = SubGroup
+ };
+
+ AtomicScopeOpenCLModel() {}
+
+ SyncScope map(unsigned S) const override {
+ switch (static_cast<ID>(S)) {
+ case WorkGroup:
+ return SyncScope::OpenCLWorkGroup;
+ case Device:
+ return SyncScope::OpenCLDevice;
+ case AllSVMDevices:
+ return SyncScope::OpenCLAllSVMDevices;
+ case SubGroup:
+ return SyncScope::OpenCLSubGroup;
+ }
+ llvm_unreachable("Invalid language synch scope value");
+ }
+
+ bool isValid(unsigned S) const override {
+ return S >= static_cast<unsigned>(WorkGroup) &&
+ S <= static_cast<unsigned>(Last);
+ }
+
+ ArrayRef<unsigned> getRuntimeValues() const override {
+ static_assert(Last == SubGroup, "Does not include all synch scopes");
+ static const unsigned Scopes[] = {
+ static_cast<unsigned>(WorkGroup), static_cast<unsigned>(Device),
+ static_cast<unsigned>(AllSVMDevices), static_cast<unsigned>(SubGroup)};
+ return llvm::makeArrayRef(Scopes);
+ }
+
+ unsigned getFallBackValue() const override {
+ return static_cast<unsigned>(AllSVMDevices);
+ }
+};
+
+inline std::unique_ptr<AtomicScopeModel>
+AtomicScopeModel::create(AtomicScopeModelKind K) {
+ switch (K) {
+ case AtomicScopeModelKind::None:
+ return std::unique_ptr<AtomicScopeModel>{};
+ case AtomicScopeModelKind::OpenCL:
+ return llvm::make_unique<AtomicScopeOpenCLModel>();
+ }
+ llvm_unreachable("Invalid atomic scope model kind");
+}
+}
+
+#endif
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
index d1a9ea85dbe9..6ba58779114f 100644
--- a/include/clang/Basic/TargetInfo.h
+++ b/include/clang/Basic/TargetInfo.h
@@ -59,6 +59,7 @@ protected:
// values are specified by the TargetInfo constructor.
bool BigEndian;
bool TLSSupported;
+ bool VLASupported;
bool NoAsmVariants; // True if {|} are normal characters.
bool HasFloat128;
unsigned char PointerWidth, PointerAlign;
@@ -85,7 +86,7 @@ protected:
*LongDoubleFormat, *Float128Format;
unsigned char RegParmMax, SSERegParmMax;
TargetCXXABI TheCXXABI;
- const LangAS::Map *AddrSpaceMap;
+ const LangASMap *AddrSpaceMap;
mutable StringRef PlatformName;
mutable VersionTuple PlatformMinVersion;
@@ -247,6 +248,9 @@ public:
IntType getPtrDiffType(unsigned AddrSpace) const {
return AddrSpace == 0 ? PtrDiffType : getPtrDiffTypeV(AddrSpace);
}
+ IntType getUnsignedPtrDiffType(unsigned AddrSpace) const {
+ return getCorrespondingUnsignedType(getPtrDiffType(AddrSpace));
+ }
IntType getIntPtrType() const { return IntPtrType; }
IntType getUIntPtrType() const {
return getCorrespondingUnsignedType(IntPtrType);
@@ -318,9 +322,7 @@ public:
/// \brief Get integer value for null pointer.
/// \param AddrSpace address space of pointee in source language.
- virtual uint64_t getNullPointerValue(unsigned AddrSpace) const {
- return 0;
- }
+ virtual uint64_t getNullPointerValue(LangAS AddrSpace) const { return 0; }
/// \brief Return the size of '_Bool' and C++ 'bool' for this target, in bits.
unsigned getBoolWidth() const { return BoolWidth; }
@@ -447,6 +449,9 @@ public:
/// \brief Return the maximum width lock-free atomic operation which can be
/// inlined given the supported features of the given target.
unsigned getMaxAtomicInlineWidth() const { return MaxAtomicInlineWidth; }
+ /// \brief Set the maximum inline or promote width lock-free atomic operation
+ /// for the given target.
+ virtual void setMaxAtomicWidth() {}
/// \brief Returns true if the given target supports lock-free atomic
/// operations at the specified width and alignment.
virtual bool hasBuiltinAtomic(uint64_t AtomicSizeInBits,
@@ -464,21 +469,6 @@ public:
/// types for the given target.
unsigned getSimdDefaultAlign() const { return SimdDefaultAlign; }
- /// Return the alignment (in bits) of the thrown exception object. This is
- /// only meaningful for targets that allocate C++ exceptions in a system
- /// runtime, such as those using the Itanium C++ ABI.
- virtual unsigned getExnObjectAlignment() const {
- // Itanium says that an _Unwind_Exception has to be "double-word"
- // aligned (and thus the end of it is also so-aligned), meaning 16
- // bytes. Of course, that was written for the actual Itanium,
- // which is a 64-bit platform. Classically, the ABI doesn't really
- // specify the alignment on other platforms, but in practice
- // libUnwind declares the struct with __attribute__((aligned)), so
- // we assume that alignment here. (It's generally 16 bytes, but
- // some targets overwrite it.)
- return getDefaultAlignForAttributeAligned();
- }
-
/// \brief Return the size of intmax_t and uintmax_t for this target, in bits.
unsigned getIntMaxTWidth() const {
return getTypeWidth(IntMaxType);
@@ -569,6 +559,14 @@ public:
return ComplexLongDoubleUsesFP2Ret;
}
+ /// Check whether llvm intrinsics such as llvm.convert.to.fp16 should be used
+ /// to convert to and from __fp16.
+ /// FIXME: This function should be removed once all targets stop using the
+ /// conversion intrinsics.
+ virtual bool useFP16ConversionIntrinsics() const {
+ return true;
+ }
+
/// \brief Specify if mangling based on address space map should be used or
/// not for language specific address spaces
bool useAddressSpaceMapMangling() const {
@@ -869,6 +867,11 @@ public:
return false;
}
+ /// brief Determine whether this TargetInfo supports the given CPU name.
+ virtual bool isValidCPUName(StringRef Name) const {
+ return true;
+ }
+
/// \brief Use the specified ABI.
///
/// \return False on error (invalid ABI name).
@@ -891,6 +894,11 @@ public:
Features[Name] = Enabled;
}
+ /// \brief Determine whether this TargetInfo supports the given feature.
+ virtual bool isValidFeatureName(StringRef Feature) const {
+ return true;
+ }
+
/// \brief Perform initialization based on the user configured
/// set of features (e.g., +sse4).
///
@@ -916,6 +924,10 @@ public:
// argument.
virtual bool validateCpuSupports(StringRef Name) const { return false; }
+ // \brief Validate the contents of the __builtin_cpu_is(const char*)
+ // argument.
+ virtual bool validateCpuIs(StringRef Name) const { return false; }
+
// \brief Returns maximal number of args passed in registers.
unsigned getRegParmMax() const {
assert(RegParmMax < 7 && "RegParmMax value is larger than AST can handle");
@@ -935,6 +947,9 @@ public:
return MaxTLSAlign;
}
+ /// \brief Whether target supports variable-length arrays.
+ bool isVLASupported() const { return VLASupported; }
+
/// \brief Whether the target supports SEH __try.
bool isSEHTrySupported() const {
return getTriple().isOSWindows() &&
@@ -965,15 +980,13 @@ public:
return nullptr;
}
- const LangAS::Map &getAddressSpaceMap() const {
- return *AddrSpaceMap;
- }
+ const LangASMap &getAddressSpaceMap() const { return *AddrSpaceMap; }
/// \brief 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,
/// this may return None, and such optimizations will be disabled.
- virtual llvm::Optional<unsigned> getConstantAddressSpace() const {
+ virtual llvm::Optional<LangAS> getConstantAddressSpace() const {
return LangAS::Default;
}
@@ -1051,10 +1064,19 @@ public:
return getTargetOpts().SupportedOpenCLOptions;
}
- /// \brief Get OpenCL image type address space.
- virtual LangAS::ID getOpenCLImageAddrSpace() const {
- return LangAS::opencl_global;
- }
+ enum OpenCLTypeKind {
+ OCLTK_Default,
+ OCLTK_ClkEvent,
+ OCLTK_Event,
+ OCLTK_Image,
+ OCLTK_Pipe,
+ OCLTK_Queue,
+ OCLTK_ReserveID,
+ OCLTK_Sampler,
+ };
+
+ /// \brief Get address space for OpenCL type.
+ virtual LangAS getOpenCLTypeAddrSpace(OpenCLTypeKind TK) const;
/// \returns Target specific vtbl ptr address space.
virtual unsigned getVtblPtrAddressSpace() const {
diff --git a/include/clang/Basic/TargetOptions.h b/include/clang/Basic/TargetOptions.h
index 9bb19c7b79df..60becfb8ee76 100644
--- a/include/clang/Basic/TargetOptions.h
+++ b/include/clang/Basic/TargetOptions.h
@@ -54,8 +54,6 @@ public:
/// be a list of strings starting with by '+' or '-'.
std::vector<std::string> Features;
- std::vector<std::string> Reciprocals;
-
/// Supported OpenCL extensions and optional core features.
OpenCLOptions SupportedOpenCLOptions;
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
index be67663a1015..6ae8821a834d 100644
--- a/include/clang/Basic/TokenKinds.def
+++ b/include/clang/Basic/TokenKinds.def
@@ -27,8 +27,11 @@
#ifndef CXX11_KEYWORD
#define CXX11_KEYWORD(X,Y) KEYWORD(X,KEYCXX11|(Y))
#endif
+#ifndef CXX2A_KEYWORD
+#define CXX2A_KEYWORD(X,Y) KEYWORD(X,KEYCXX2A|(Y))
+#endif
#ifndef CONCEPTS_KEYWORD
-#define CONCEPTS_KEYWORD(X) KEYWORD(X,KEYCONCEPTS)
+#define CONCEPTS_KEYWORD(X) CXX2A_KEYWORD(X,KEYCONCEPTS)
#endif
#ifndef MODULES_KEYWORD
#define MODULES_KEYWORD(X) KEYWORD(X,KEYMODULES)
@@ -142,7 +145,7 @@ TOK(numeric_constant) // 0x123
TOK(char_constant) // 'a'
TOK(wide_char_constant) // L'b'
-// C++1z Character Constants
+// C++17 Character Constants
TOK(utf8_char_constant) // u8'a'
// C++11 Character Constants
@@ -191,6 +194,7 @@ PUNCTUATOR(less, "<")
PUNCTUATOR(lessless, "<<")
PUNCTUATOR(lessequal, "<=")
PUNCTUATOR(lesslessequal, "<<=")
+PUNCTUATOR(spaceship, "<=>")
PUNCTUATOR(greater, ">")
PUNCTUATOR(greatergreater, ">>")
PUNCTUATOR(greaterequal, ">=")
@@ -236,6 +240,7 @@ PUNCTUATOR(caretcaret, "^^")
// implementation namespace
// KEYNOCXX - This is a keyword in every non-C++ dialect.
// KEYCXX11 - This is a C++ keyword introduced to C++ in C++11
+// KEYCXX2A - This is a C++ keyword introduced to C++ in C++2a
// KEYCONCEPTS - This is a keyword if the C++ extensions for concepts
// are enabled.
// KEYMODULES - This is a keyword if the C++ extensions for modules
@@ -362,7 +367,7 @@ CXX11_KEYWORD(nullptr , 0)
CXX11_KEYWORD(static_assert , 0)
CXX11_KEYWORD(thread_local , 0)
-// C++ concepts TS keywords
+// C++2a / concepts TS keywords
CONCEPTS_KEYWORD(concept)
CONCEPTS_KEYWORD(requires)
@@ -375,6 +380,9 @@ KEYWORD(co_yield , KEYCOROUTINES)
MODULES_KEYWORD(module)
MODULES_KEYWORD(import)
+// C11 Extension
+KEYWORD(_Float16 , KEYALL)
+
// GNU Extensions (in impl-reserved namespace)
KEYWORD(_Decimal32 , KEYALL)
KEYWORD(_Decimal64 , KEYALL)
@@ -390,6 +398,7 @@ TYPE_TRAIT_2(__builtin_types_compatible_p, TypeCompatible, KEYNOCXX)
KEYWORD(__builtin_va_arg , KEYALL)
KEYWORD(__extension__ , KEYALL)
KEYWORD(__float128 , KEYALL)
+ALIAS("_Float128", __float128 , KEYNOCXX)
KEYWORD(__imag , KEYALL)
KEYWORD(__int128 , KEYALL)
KEYWORD(__label__ , KEYALL)
@@ -448,6 +457,8 @@ TYPE_TRAIT_1(__is_pod, IsPOD, KEYCXX)
TYPE_TRAIT_1(__is_polymorphic, IsPolymorphic, KEYCXX)
TYPE_TRAIT_1(__is_trivial, IsTrivial, KEYCXX)
TYPE_TRAIT_1(__is_union, IsUnion, KEYCXX)
+TYPE_TRAIT_1(__has_unique_object_representations,
+ HasUniqueObjectRepresentations, KEYCXX)
// Clang-only C++ Type Traits
TYPE_TRAIT_N(__is_trivially_constructible, IsTriviallyConstructible, KEYCXX)
@@ -810,6 +821,7 @@ ANNOTATION(module_end)
#undef TYPE_TRAIT_1
#undef TYPE_TRAIT
#undef CONCEPTS_KEYWORD
+#undef CXX2A_KEYWORD
#undef CXX11_KEYWORD
#undef KEYWORD
#undef PUNCTUATOR
diff --git a/include/clang/Basic/TypeTraits.h b/include/clang/Basic/TypeTraits.h
index 6aadf795d82e..8ecd63f9c3cb 100644
--- a/include/clang/Basic/TypeTraits.h
+++ b/include/clang/Basic/TypeTraits.h
@@ -70,7 +70,8 @@ namespace clang {
UTT_IsUnsigned,
UTT_IsVoid,
UTT_IsVolatile,
- UTT_Last = UTT_IsVolatile,
+ UTT_HasUniqueObjectRepresentations,
+ UTT_Last = UTT_HasUniqueObjectRepresentations,
BTT_IsBaseOf,
BTT_IsConvertible,
BTT_IsConvertibleTo,
diff --git a/include/clang/Basic/VirtualFileSystem.h b/include/clang/Basic/VirtualFileSystem.h
index e52b345e286c..245452dd12b5 100644
--- a/include/clang/Basic/VirtualFileSystem.h
+++ b/include/clang/Basic/VirtualFileSystem.h
@@ -319,16 +319,30 @@ public:
explicit InMemoryFileSystem(bool UseNormalizedPaths = true);
~InMemoryFileSystem() override;
- /// Add a buffer to the VFS with a path. The VFS owns the buffer.
- /// \return true if the file was successfully added, false if the file already
- /// exists in the file system with different contents.
+ /// 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);
+ 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.
- /// \return true if the file was successfully added, false if the file already
- /// exists in the file system with different contents.
+ /// 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);
+ 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; }
diff --git a/include/clang/Basic/X86Target.def b/include/clang/Basic/X86Target.def
new file mode 100644
index 000000000000..21550fe2dd55
--- /dev/null
+++ b/include/clang/Basic/X86Target.def
@@ -0,0 +1,232 @@
+//===--- X86Target.def - X86 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 X86-specific Features and Processors, as used by
+// the X86 Targets.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef PROC
+#define PROC(ENUM, STRING, IS64BIT)
+#endif
+
+#ifndef PROC_ALIAS
+#define PROC_ALIAS(ENUM, ALIAS)
+#endif
+
+#define PROC_64_BIT true
+#define PROC_32_BIT false
+
+/// \name i386
+/// i386-generation processors.
+//@{
+PROC(i386, "i386", PROC_32_BIT)
+//@}
+
+/// \name i486
+/// i486-generation processors.
+//@{
+PROC(i486, "i486", PROC_32_BIT)
+PROC(WinChipC6, "winchip-c6", PROC_32_BIT)
+PROC(WinChip2, "winchip2", PROC_32_BIT)
+PROC(C3, "c3", PROC_32_BIT)
+//@}
+
+/// \name i586
+/// i586-generation processors, P5 microarchitecture based.
+//@{
+PROC(i586, "i586", PROC_32_BIT)
+PROC(Pentium, "pentium", PROC_32_BIT)
+PROC(PentiumMMX, "pentium-mmx", PROC_32_BIT)
+//@}
+
+/// \name i686
+/// i686-generation processors, P6 / Pentium M microarchitecture based.
+//@{
+PROC(PentiumPro, "pentiumpro", PROC_32_BIT)
+PROC_ALIAS(PentiumPro, "i686")
+PROC(Pentium2, "pentium2", PROC_32_BIT)
+PROC(Pentium3, "pentium3", PROC_32_BIT)
+PROC_ALIAS(Pentium3, "pentium3m")
+PROC(PentiumM, "pentium-m", PROC_32_BIT)
+PROC(C3_2, "c3-2", PROC_32_BIT)
+
+/// This enumerator is a bit odd, as GCC no longer accepts -march=yonah.
+/// Clang however has some logic to support this.
+// FIXME: Warn, deprecate, and potentially remove this.
+PROC(Yonah, "yonah", PROC_32_BIT)
+//@}
+
+/// \name Netburst
+/// Netburst microarchitecture based processors.
+//@{
+PROC(Pentium4, "pentium4", PROC_32_BIT)
+PROC_ALIAS(Pentium4, "pentium4m")
+
+PROC(Prescott, "prescott", PROC_32_BIT)
+PROC(Nocona, "nocona", PROC_64_BIT)
+//@}
+
+/// \name Core
+/// Core microarchitecture based processors.
+//@{
+PROC(Core2, "core2", PROC_64_BIT)
+
+/// This enumerator, like Yonah, is a bit odd. It is another
+/// codename which GCC no longer accepts as an option to -march, but Clang
+/// has some logic for recognizing it.
+// FIXME: Warn, deprecate, and potentially remove this.
+PROC(Penryn, "penryn", PROC_64_BIT)
+//@}
+
+/// \name Atom
+/// Atom processors
+//@{
+PROC(Bonnell, "bonnell", PROC_64_BIT)
+PROC_ALIAS(Bonnell, "atom")
+
+PROC(Silvermont, "silvermont", PROC_64_BIT)
+PROC_ALIAS(Silvermont, "slm")
+
+PROC(Goldmont, "goldmont", PROC_64_BIT)
+//@}
+
+/// \name Nehalem
+/// Nehalem microarchitecture based processors.
+PROC(Nehalem, "nehalem", PROC_64_BIT)
+PROC_ALIAS(Nehalem, "corei7")
+
+/// \name Westmere
+/// Westmere microarchitecture based processors.
+PROC(Westmere, "westmere", PROC_64_BIT)
+
+/// \name Sandy Bridge
+/// Sandy Bridge microarchitecture based processors.
+PROC(SandyBridge, "sandybridge", PROC_64_BIT)
+PROC_ALIAS(SandyBridge, "corei7-avx")
+
+/// \name Ivy Bridge
+/// Ivy Bridge microarchitecture based processors.
+PROC(IvyBridge, "ivybridge", PROC_64_BIT)
+PROC_ALIAS(IvyBridge, "core-avx-i")
+
+/// \name Haswell
+/// Haswell microarchitecture based processors.
+PROC(Haswell, "haswell", PROC_64_BIT)
+PROC_ALIAS(Haswell, "core-avx2")
+
+/// \name Broadwell
+/// Broadwell microarchitecture based processors.
+PROC(Broadwell, "broadwell", PROC_64_BIT)
+
+/// \name Skylake Client
+/// Skylake client microarchitecture based processors.
+PROC(SkylakeClient, "skylake", PROC_64_BIT)
+
+/// \name Skylake Server
+/// Skylake server microarchitecture based processors.
+PROC(SkylakeServer, "skylake-avx512", PROC_64_BIT)
+PROC_ALIAS(SkylakeServer, "skx")
+
+/// \name Cannonlake Client
+/// Cannonlake client microarchitecture based processors.
+PROC(Cannonlake, "cannonlake", PROC_64_BIT)
+
+/// \name Icelake Client
+/// Icelake client microarchitecture based processors.
+PROC(Icelake, "icelake", PROC_64_BIT)
+
+/// \name Knights Landing
+/// Knights Landing processor.
+PROC(KNL, "knl", PROC_64_BIT)
+
+/// \name Knights Mill
+/// Knights Mill processor.
+PROC(KNM, "knm", PROC_64_BIT)
+
+/// \name Lakemont
+/// Lakemont microarchitecture based processors.
+PROC(Lakemont, "lakemont", PROC_32_BIT)
+
+/// \name K6
+/// K6 architecture processors.
+//@{
+PROC(K6, "k6", PROC_32_BIT)
+PROC(K6_2, "k6-2", PROC_32_BIT)
+PROC(K6_3, "k6-3", PROC_32_BIT)
+//@}
+
+/// \name K7
+/// K7 architecture processors.
+//@{
+PROC(Athlon, "athlon", PROC_32_BIT)
+PROC_ALIAS(Athlon, "athlon-tbird")
+
+PROC(AthlonXP, "athlon-xp", PROC_32_BIT)
+PROC_ALIAS(AthlonXP, "athlon-mp")
+PROC_ALIAS(AthlonXP, "athlon-4")
+//@}
+
+/// \name K8
+/// K8 architecture processors.
+//@{
+PROC(K8, "k8", PROC_64_BIT)
+PROC_ALIAS(K8, "athlon64")
+PROC_ALIAS(K8, "athlon-fx")
+PROC_ALIAS(K8, "opteron")
+
+PROC(K8SSE3, "k8-sse3", PROC_64_BIT)
+PROC_ALIAS(K8SSE3, "athlon64-sse3")
+PROC_ALIAS(K8SSE3, "opteron-sse3")
+
+PROC(AMDFAM10, "amdfam10", PROC_64_BIT)
+PROC_ALIAS(AMDFAM10, "barcelona")
+//@}
+
+/// \name Bobcat
+/// Bobcat architecture processors.
+//@{
+PROC(BTVER1, "btver1", PROC_64_BIT)
+PROC(BTVER2, "btver2", PROC_64_BIT)
+//@}
+
+/// \name Bulldozer
+/// Bulldozer architecture processors.
+//@{
+PROC(BDVER1, "bdver1", PROC_64_BIT)
+PROC(BDVER2, "bdver2", PROC_64_BIT)
+PROC(BDVER3, "bdver3", PROC_64_BIT)
+PROC(BDVER4, "bdver4", PROC_64_BIT)
+//@}
+
+/// \name zen
+/// Zen architecture processors.
+//@{
+PROC(ZNVER1, "znver1", PROC_64_BIT)
+//@}
+
+/// This specification is deprecated and will be removed in the future.
+/// Users should prefer K8.
+// FIXME: Warn on this when the CPU is set to it.
+//@{
+PROC(x86_64, "x86-64", PROC_64_BIT)
+//@}
+
+/// \name Geode
+/// Geode processors.
+//@{
+PROC(Geode, "geode", PROC_32_BIT)
+//@}
+
+
+#undef PROC_64_BIT
+#undef PROC_32_BIT
+#undef PROC
+#undef PROC_ALIAS
diff --git a/include/clang/CodeGen/CodeGenABITypes.h b/include/clang/CodeGen/CodeGenABITypes.h
index 615e55c8b69f..53619fa8ef65 100644
--- a/include/clang/CodeGen/CodeGenABITypes.h
+++ b/include/clang/CodeGen/CodeGenABITypes.h
@@ -72,12 +72,19 @@ const CGFunctionInfo &arrangeFreeFunctionCall(CodeGenModule &CGM,
FunctionType::ExtInfo info,
RequiredArgs args);
-// Returns null if the function type is incomplete and can't be lowered.
+/// Returns null if the function type is incomplete and can't be lowered.
llvm::FunctionType *convertFreeFunctionType(CodeGenModule &CGM,
const FunctionDecl *FD);
llvm::Type *convertTypeForMemory(CodeGenModule &CGM, QualType T);
+/// Given a non-bitfield struct field, return its index within the elements of
+/// the struct's converted type. The returned index refers to a field number in
+/// the complete object type which is returned by convertTypeForMemory. FD must
+/// be a field in RD directly (i.e. not an inherited field).
+unsigned getLLVMFieldNumber(CodeGenModule &CGM,
+ const RecordDecl *RD, const FieldDecl *FD);
+
} // end namespace CodeGen
} // end namespace clang
diff --git a/include/clang/CodeGen/ConstantInitFuture.h b/include/clang/CodeGen/ConstantInitFuture.h
index ef1a5d2f49af..f1a7e2264fc6 100644
--- a/include/clang/CodeGen/ConstantInitFuture.h
+++ b/include/clang/CodeGen/ConstantInitFuture.h
@@ -31,8 +31,7 @@ class ConstantInitBuilderBase;
}
namespace llvm {
template <>
-class PointerLikeTypeTraits< ::clang::CodeGen::ConstantInitBuilderBase*> {
-public:
+struct PointerLikeTypeTraits< ::clang::CodeGen::ConstantInitBuilderBase*> {
using T = ::clang::CodeGen::ConstantInitBuilderBase*;
static inline void *getAsVoidPointer(T p) { return p; }
@@ -93,8 +92,7 @@ public:
namespace llvm {
template <>
-class PointerLikeTypeTraits< ::clang::CodeGen::ConstantInitFuture> {
-public:
+struct PointerLikeTypeTraits< ::clang::CodeGen::ConstantInitFuture> {
using T = ::clang::CodeGen::ConstantInitFuture;
static inline void *getAsVoidPointer(T future) {
diff --git a/include/clang/CodeGen/ModuleBuilder.h b/include/clang/CodeGen/ModuleBuilder.h
index 6f81ea9d6370..e110f6fd30c1 100644
--- a/include/clang/CodeGen/ModuleBuilder.h
+++ b/include/clang/CodeGen/ModuleBuilder.h
@@ -84,6 +84,10 @@ public:
/// code generator will schedule the entity for emission if a
/// definition has been registered with this code generator.
llvm::Constant *GetAddrOfGlobal(GlobalDecl decl, bool isForDefinition);
+
+ /// Create a new \c llvm::Module after calling HandleTranslationUnit. This
+ /// enable codegen in interactive processing environments.
+ llvm::Module* StartModule(llvm::StringRef ModuleName, llvm::LLVMContext &C);
};
/// CreateLLVMCodeGen - Create a CodeGenerator instance.
diff --git a/include/clang/Config/config.h.cmake b/include/clang/Config/config.h.cmake
index b138b5fcd828..daac9b7b45d1 100644
--- a/include/clang/Config/config.h.cmake
+++ b/include/clang/Config/config.h.cmake
@@ -17,9 +17,15 @@
/* Default runtime library to use. */
#define CLANG_DEFAULT_RTLIB "${CLANG_DEFAULT_RTLIB}"
+/* Default objcopy to use */
+#define CLANG_DEFAULT_OBJCOPY "${CLANG_DEFAULT_OBJCOPY}"
+
/* Default OpenMP runtime used by -fopenmp. */
#define CLANG_DEFAULT_OPENMP_RUNTIME "${CLANG_DEFAULT_OPENMP_RUNTIME}"
+/* Default architecture for OpenMP offloading to Nvidia GPUs. */
+#define CLANG_OPENMP_NVPTX_DEFAULT_ARCH "${CLANG_OPENMP_NVPTX_DEFAULT_ARCH}"
+
/* Multilib suffix for libdir. */
#define CLANG_LIBDIR_SUFFIX "${CLANG_LIBDIR_SUFFIX}"
@@ -57,8 +63,8 @@
#cmakedefine01 ENABLE_X86_RELAX_RELOCATIONS
/* Enable each functionality of modules */
-#cmakedefine CLANG_ENABLE_ARCMT
-#cmakedefine CLANG_ENABLE_OBJC_REWRITER
-#cmakedefine CLANG_ENABLE_STATIC_ANALYZER
+#cmakedefine01 CLANG_ENABLE_ARCMT
+#cmakedefine01 CLANG_ENABLE_OBJC_REWRITER
+#cmakedefine01 CLANG_ENABLE_STATIC_ANALYZER
#endif
diff --git a/include/clang/CrossTU/CrossTUDiagnostic.h b/include/clang/CrossTU/CrossTUDiagnostic.h
new file mode 100644
index 000000000000..dad38309fd1a
--- /dev/null
+++ b/include/clang/CrossTU/CrossTUDiagnostic.h
@@ -0,0 +1,29 @@
+//===--- CrossTUDiagnostic.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_CROSSTU_CROSSTUDIAGNOSTIC_H
+#define LLVM_CLANG_CROSSTU_CROSSTUDIAGNOSTIC_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_FRONTEND_FRONTENDDIAGNOSTIC_H
diff --git a/include/clang/CrossTU/CrossTranslationUnit.h b/include/clang/CrossTU/CrossTranslationUnit.h
new file mode 100644
index 000000000000..f2a169025009
--- /dev/null
+++ b/include/clang/CrossTU/CrossTranslationUnit.h
@@ -0,0 +1,159 @@
+//===--- CrossTranslationUnit.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 provides an interface to load binary AST dumps on demand. This
+// feature can be utilized for tools that require cross translation unit
+// support.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_CROSSTU_CROSSTRANSLATIONUNIT_H
+#define LLVM_CLANG_CROSSTU_CROSSTRANSLATIONUNIT_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/Error.h"
+
+namespace clang {
+class CompilerInstance;
+class ASTContext;
+class ASTImporter;
+class ASTUnit;
+class DeclContext;
+class FunctionDecl;
+class NamedDecl;
+class TranslationUnitDecl;
+
+namespace cross_tu {
+
+enum class index_error_code {
+ unspecified = 1,
+ missing_index_file,
+ invalid_index_format,
+ multiple_definitions,
+ missing_definition,
+ failed_import,
+ failed_to_get_external_ast,
+ failed_to_generate_usr
+};
+
+class IndexError : public llvm::ErrorInfo<IndexError> {
+public:
+ static char ID;
+ 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) {}
+ 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; }
+
+private:
+ index_error_code Code;
+ std::string FileName;
+ int LineNo;
+};
+
+/// \brief This function parses an index file that determines which
+/// translation unit contains which definition.
+///
+/// The index file format is the following:
+/// each line consists of an USR and a filepath separated by a space.
+///
+/// \return Returns a map where the USR is the key and the filepath is the value
+/// or an error.
+llvm::Expected<llvm::StringMap<std::string>>
+parseCrossTUIndex(StringRef IndexPath, StringRef CrossTUDir);
+
+std::string createCrossTUIndexString(const llvm::StringMap<std::string> &Index);
+
+/// \brief This class is used for tools that requires cross translation
+/// unit capability.
+///
+/// This class can load function 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.
+///
+/// Note that this class also implements caching.
+class CrossTranslationUnitContext {
+public:
+ CrossTranslationUnitContext(CompilerInstance &CI);
+ ~CrossTranslationUnitContext();
+
+ /// \brief This function loads a function definition from an external AST
+ /// file and merge it into the original AST.
+ ///
+ /// This method should only be used on functions that have no definitions in
+ /// the current translation unit. A function definition with the same
+ /// declaration will be looked up in the index file which should be in the
+ /// \p CrossTUDir directory, called \p IndexName. In case the declaration is
+ /// found in the index the corresponding AST file will be loaded and the
+ /// definition of the function will be merged into the original AST using
+ /// the AST Importer.
+ ///
+ /// \return The declaration with the definition will be returned.
+ /// If no suitable definition is found in the index file or multiple
+ /// definitions found error will be returned.
+ ///
+ /// Note that the AST files should also be in the \p CrossTUDir.
+ llvm::Expected<const FunctionDecl *>
+ getCrossTUDefinition(const FunctionDecl *FD, StringRef CrossTUDir,
+ StringRef IndexName);
+
+ /// \brief This function loads a function definition from an external AST
+ /// file.
+ ///
+ /// A function definition with the same declaration will be looked up in the
+ /// index file which should be in the \p CrossTUDir directory, called
+ /// \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.
+ ///
+ /// Note that the AST files should also be in the \p CrossTUDir.
+ llvm::Expected<ASTUnit *> loadExternalAST(StringRef LookupName,
+ StringRef CrossTUDir,
+ StringRef IndexName);
+
+ /// \brief This function merges a definition from a separate AST Unit into
+ /// the current one which was created by the compiler instance that
+ /// was passed to the constructor.
+ ///
+ /// \return Returns the resulting definition or an error.
+ llvm::Expected<const FunctionDecl *> importDefinition(const FunctionDecl *FD);
+
+ /// \brief Get a name to identify a function.
+ static std::string getLookupName(const NamedDecl *ND);
+
+ /// \brief Emit diagnostics for the user for potential configuration errors.
+ void emitCrossTUDiagnostics(const IndexError &IE);
+
+private:
+ ASTImporter &getOrCreateASTImporter(ASTContext &From);
+ const FunctionDecl *findFunctionInDeclContext(const DeclContext *DC,
+ StringRef LookupFnName);
+
+ llvm::StringMap<std::unique_ptr<clang::ASTUnit>> FileASTUnitMap;
+ llvm::StringMap<clang::ASTUnit *> FunctionASTUnitMap;
+ llvm::StringMap<std::string> FunctionFileMap;
+ llvm::DenseMap<TranslationUnitDecl *, std::unique_ptr<ASTImporter>>
+ ASTUnitImporterMap;
+ CompilerInstance &CI;
+ ASTContext &Context;
+};
+
+} // namespace cross_tu
+} // namespace clang
+
+#endif // LLVM_CLANG_CROSSTU_CROSSTRANSLATIONUNIT_H
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index 205f36b723c8..7dea88b62cc1 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -70,7 +70,7 @@ def analyzer_opt_analyze_nested_blocks : Flag<["-"], "analyzer-opt-analyze-neste
def analyzer_display_progress : Flag<["-"], "analyzer-display-progress">,
HelpText<"Emit verbose output about the analyzer's progress">;
def analyze_function : Separate<["-"], "analyze-function">,
- HelpText<"Run analysis on specific 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">;
@@ -99,7 +99,19 @@ def analyzer_stats : Flag<["-"], "analyzer-stats">,
HelpText<"Print internal analyzer statistics.">;
def analyzer_checker : Separate<["-"], "analyzer-checker">,
- HelpText<"Choose analyzer checkers to enable">;
+ HelpText<"Choose analyzer checkers to enable">,
+ ValuesCode<[{
+ const char *Values =
+ #define GET_CHECKERS
+ #define CHECKER(FULLNAME, CLASS, DESCFILE, HT, G, H) FULLNAME ","
+ #include "clang/StaticAnalyzer/Checkers/Checkers.inc"
+ #undef GET_CHECKERS
+ #define GET_PACKAGES
+ #define PACKAGE(FULLNAME, G, D) FULLNAME ","
+ #include "clang/StaticAnalyzer/Checkers/Checkers.inc"
+ #undef GET_PACKAGES
+ ;
+ }]>;
def analyzer_checker_EQ : Joined<["-"], "analyzer-checker=">,
Alias<analyzer_checker>;
@@ -188,6 +200,12 @@ def arange_sections : Flag<["-"], "arange_sections">,
def dwarf_ext_refs : Flag<["-"], "dwarf-ext-refs">,
HelpText<"Generate debug info with external references to clang modules"
" or precompiled headers">;
+def dwarf_explicit_import : Flag<["-"], "dwarf-explicit-import">,
+ HelpText<"Generate explicit import from anonymous namespace to containing"
+ " scope">;
+def debug_forward_template_params : Flag<["-"], "debug-forward-template-params">,
+ HelpText<"Emit complete descriptions of template parameters in forward"
+ " declarations">;
def fforbid_guard_variables : Flag<["-"], "fforbid-guard-variables">,
HelpText<"Emit an error if a C++ static local initializer would need a guard variable">;
def no_implicit_float : Flag<["-"], "no-implicit-float">,
@@ -226,6 +244,8 @@ def relaxed_aliasing : Flag<["-"], "relaxed-aliasing">,
HelpText<"Turn off Type Based Alias Analysis">;
def no_struct_path_tbaa : Flag<["-"], "no-struct-path-tbaa">,
HelpText<"Turn off struct-path aware Type Based Alias Analysis">;
+def new_struct_path_tbaa : Flag<["-"], "new-struct-path-tbaa">,
+ HelpText<"Enable enhanced struct-path aware Type Based Alias Analysis">;
def masm_verbose : Flag<["-"], "masm-verbose">,
HelpText<"Generate verbose assembly output">;
def mcode_model : Separate<["-"], "mcode-model">,
@@ -243,8 +263,12 @@ def menable_no_nans : Flag<["-"], "menable-no-nans">,
def menable_unsafe_fp_math : Flag<["-"], "menable-unsafe-fp-math">,
HelpText<"Allow unsafe floating-point math optimizations which may decrease "
"precision">;
+def mreassociate : Flag<["-"], "mreassociate">,
+ HelpText<"Allow reassociation transformations for floating-point instructions">;
def mfloat_abi : Separate<["-"], "mfloat-abi">,
HelpText<"The float ABI to use">;
+def mtp : Separate<["-"], "mtp">,
+ HelpText<"Mode for reading thread pointer">;
def mlimit_float_precision : Separate<["-"], "mlimit-float-precision">,
HelpText<"Limit float precision to the given value">;
def split_stacks : Flag<["-"], "split-stacks">,
@@ -295,6 +319,9 @@ def fsanitize_coverage_8bit_counters
def fsanitize_coverage_inline_8bit_counters
: Flag<["-"], "fsanitize-coverage-inline-8bit-counters">,
HelpText<"Enable inline 8-bit counters in sanitizer coverage">;
+def fsanitize_coverage_pc_table
+ : Flag<["-"], "fsanitize-coverage-pc-table">,
+ HelpText<"Create a table of coverage-instrumented PCs">;
def fsanitize_coverage_trace_pc
: Flag<["-"], "fsanitize-coverage-trace-pc">,
HelpText<"Enable PC tracing in sanitizer coverage">;
@@ -304,6 +331,9 @@ def fsanitize_coverage_trace_pc_guard
def fsanitize_coverage_no_prune
: Flag<["-"], "fsanitize-coverage-no-prune">,
HelpText<"Disable coverage pruning (i.e. instrument all blocks/edges)">;
+def fsanitize_coverage_stack_depth
+ : Flag<["-"], "fsanitize-coverage-stack-depth">,
+ HelpText<"Enable max stack depth tracing">;
def fprofile_instrument_EQ : Joined<["-"], "fprofile-instrument=">,
HelpText<"Enable PGO instrumentation. The accepted value is clang, llvm, "
"or none">, Values<"none,clang,llvm">;
@@ -372,8 +402,12 @@ def fcaret_diagnostics_max_lines :
HelpText<"Set the maximum number of source lines to show in a caret diagnostic">;
def fmessage_length : Separate<["-"], "fmessage-length">, MetaVarName<"<N>">,
HelpText<"Format message diagnostics so that they fit within N columns or fewer, when possible.">;
+def verify_EQ : CommaJoined<["-"], "verify=">,
+ MetaVarName<"<prefixes>">,
+ HelpText<"Verify diagnostic output using comment directives that start with"
+ " prefixes in the comma-separated sequence <prefixes>">;
def verify : Flag<["-"], "verify">,
- HelpText<"Verify diagnostic output using comment directives">;
+ HelpText<"Equivalent to -verify=expected">;
def verify_ignore_unexpected : Flag<["-"], "verify-ignore-unexpected">,
HelpText<"Ignore unexpected diagnostic messages">;
def verify_ignore_unexpected_EQ : CommaJoined<["-"], "verify-ignore-unexpected=">,
@@ -409,6 +443,8 @@ def code_completion_patterns : Flag<["-"], "code-completion-patterns">,
HelpText<"Include code patterns in code-completion results">;
def no_code_completion_globals : Flag<["-"], "no-code-completion-globals">,
HelpText<"Do not include global declarations in code-completion results.">;
+def no_code_completion_ns_level_decls : Flag<["-"], "no-code-completion-ns-level-decls">,
+ HelpText<"Do not include declarations inside namespaces (incl. global namespace) in the code-completion results.">;
def code_completion_brief_comments : Flag<["-"], "code-completion-brief-comments">,
HelpText<"Include brief documentation comments in code-completion results.">;
def disable_free : Flag<["-"], "disable-free">,
@@ -678,11 +714,17 @@ def fnative_half_arguments_and_returns : Flag<["-"], "fnative-half-arguments-and
def fallow_half_arguments_and_returns : Flag<["-"], "fallow-half-arguments-and-returns">,
HelpText<"Allow function arguments and returns of type half">;
def fdefault_calling_conv_EQ : Joined<["-"], "fdefault-calling-conv=">,
- HelpText<"Set default MS calling convention">, Values<"cdecl,fastcall,stdcall,vectorcall">;
+ HelpText<"Set default calling convention">, Values<"cdecl,fastcall,stdcall,vectorcall,regcall">;
def finclude_default_header : Flag<["-"], "finclude-default-header">,
HelpText<"Include the default header file for OpenCL">;
def fpreserve_vec3_type : Flag<["-"], "fpreserve-vec3-type">,
HelpText<"Preserve 3-component vector type">;
+def fwchar_type_EQ : Joined<["-"], "fwchar-type=">,
+ HelpText<"Select underlying type for wchar_t">, Values<"char,short,int">;
+def fsigned_wchar : Flag<["-"], "fsigned-wchar">,
+ HelpText<"Use a signed type for wchar_t">;
+def fno_signed_wchar : Flag<["-"], "fno-signed-wchar">,
+ HelpText<"Use an unsigned type for wchar_t">;
// FIXME: Remove these entirely once functionality/tests have been excised.
def fobjc_gc_only : Flag<["-"], "fobjc-gc-only">, Group<f_Group>,
diff --git a/include/clang/Driver/CLCompatOptions.td b/include/clang/Driver/CLCompatOptions.td
index aebb36ed0e2b..c1f0a89b5dc8 100644
--- a/include/clang/Driver/CLCompatOptions.td
+++ b/include/clang/Driver/CLCompatOptions.td
@@ -145,7 +145,8 @@ def _SLASH_W1 : CLFlag<"W1">, HelpText<"Enable -Wall">, Alias<Wall>;
def _SLASH_W2 : CLFlag<"W2">, HelpText<"Enable -Wall">, Alias<Wall>;
def _SLASH_W3 : CLFlag<"W3">, HelpText<"Enable -Wall">, Alias<Wall>;
def _SLASH_W4 : CLFlag<"W4">, HelpText<"Enable -Wall and -Wextra">, Alias<WCL4>;
-def _SLASH_Wall : CLFlag<"Wall">, HelpText<"Enable -Wall and -Wextra">, Alias<WCL4>;
+def _SLASH_Wall : CLFlag<"Wall">, HelpText<"Enable -Weverything">,
+ Alias<W_Joined>, AliasArgs<["everything"]>;
def _SLASH_WX : CLFlag<"WX">, HelpText<"Treat warnings as errors">,
Alias<W_Joined>, AliasArgs<["error"]>;
def _SLASH_WX_ : CLFlag<"WX-">, HelpText<"Do not treat warnings as errors">,
@@ -153,6 +154,8 @@ def _SLASH_WX_ : CLFlag<"WX-">, HelpText<"Do not treat warnings as errors">,
def _SLASH_w_flag : CLFlag<"w">, HelpText<"Disable all warnings">, Alias<w>;
def _SLASH_wd4005 : CLFlag<"wd4005">, Alias<W_Joined>,
AliasArgs<["no-macro-redefined"]>;
+def _SLASH_wd4018 : CLFlag<"wd4018">, Alias<W_Joined>,
+ AliasArgs<["no-sign-compare"]>;
def _SLASH_wd4100 : CLFlag<"wd4100">, Alias<W_Joined>,
AliasArgs<["no-unused-parameter"]>;
def _SLASH_wd4910 : CLFlag<"wd4910">, Alias<W_Joined>,
@@ -302,6 +305,8 @@ def _SLASH_Gz : CLFlag<"Gz">,
HelpText<"Set __stdcall as a default calling convention">;
def _SLASH_Gv : CLFlag<"Gv">,
HelpText<"Set __vectorcall as a default calling convention">;
+def _SLASH_Gregcall : CLFlag<"Gregcall">,
+ HelpText<"Set __regcall as a default calling convention">;
// Ignored:
diff --git a/include/clang/Driver/Compilation.h b/include/clang/Driver/Compilation.h
index 036b04605ac7..89c0def6c57a 100644
--- a/include/clang/Driver/Compilation.h
+++ b/include/clang/Driver/Compilation.h
@@ -99,8 +99,8 @@ class Compilation {
/// only be removed if we crash.
ArgStringMap FailureResultFiles;
- /// Redirection for stdout, stderr, etc.
- const StringRef **Redirects;
+ /// Optional redirection for stdin, stdout, stderr.
+ std::vector<Optional<StringRef>> Redirects;
/// Whether we're compiling for diagnostic purposes.
bool ForDiagnostics;
@@ -283,12 +283,10 @@ public:
/// Redirect - Redirect output of this compilation. Can only be done once.
///
- /// \param Redirects - array of pointers to paths. The array
- /// should have a size of three. The inferior process's
- /// stdin(0), stdout(1), and stderr(2) will be redirected to the
- /// corresponding paths. This compilation instance becomes
- /// the owner of Redirects and will delete the array and StringRef's.
- void Redirect(const StringRef** Redirects);
+ /// \param Redirects - array of optional paths. The array should have a size
+ /// of three. The inferior process's stdin(0), stdout(1), and stderr(2) will
+ /// be redirected to the corresponding paths, if provided (not llvm::None).
+ void Redirect(ArrayRef<Optional<StringRef>> Redirects);
};
} // end namespace driver
diff --git a/include/clang/Driver/Distro.h b/include/clang/Driver/Distro.h
index fab49862a442..4ab4e2ae9937 100644
--- a/include/clang/Driver/Distro.h
+++ b/include/clang/Driver/Distro.h
@@ -26,12 +26,14 @@ public:
// NB: Releases of a particular Linux distro should be kept together
// in this enum, because some tests are done by integer comparison against
// the first and last known member in the family, e.g. IsRedHat().
+ AlpineLinux,
ArchLinux,
DebianLenny,
DebianSqueeze,
DebianWheezy,
DebianJessie,
DebianStretch,
+ DebianBuster,
Exherbo,
RHEL5,
RHEL6,
@@ -58,6 +60,7 @@ public:
UbuntuYakkety,
UbuntuZesty,
UbuntuArtful,
+ UbuntuBionic,
UnknownDistro
};
@@ -107,11 +110,15 @@ public:
}
bool IsDebian() const {
- return DistroVal >= DebianLenny && DistroVal <= DebianStretch;
+ return DistroVal >= DebianLenny && DistroVal <= DebianBuster;
}
bool IsUbuntu() const {
- return DistroVal >= UbuntuHardy && DistroVal <= UbuntuArtful;
+ return DistroVal >= UbuntuHardy && DistroVal <= UbuntuBionic;
+ }
+
+ bool IsAlpineLinux() const {
+ return DistroVal == AlpineLinux;
}
/// @}
diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h
index 5a087eea1b4e..a3662872a953 100644
--- a/include/clang/Driver/Driver.h
+++ b/include/clang/Driver/Driver.h
@@ -129,6 +129,9 @@ public:
/// The original path to the clang executable.
std::string ClangExecutable;
+ /// Target and driver mode components extracted from clang executable name.
+ ParsedClangName ClangNameParts;
+
/// The path to the installed clang directory, if any.
std::string InstalledDir;
@@ -148,9 +151,6 @@ public:
/// Dynamic loader prefix, if present
std::string DyldPrefix;
- /// If the standard library is used
- bool UseStdLib;
-
/// Driver title to use with help.
std::string DriverTitle;
@@ -287,6 +287,8 @@ public:
void setCheckInputsExist(bool Value) { CheckInputsExist = Value; }
+ void setTargetAndMode(const ParsedClangName &TM) { ClangNameParts = TM; }
+
const std::string &getTitle() { return DriverTitle; }
void setTitle(std::string Value) { DriverTitle = std::move(Value); }
@@ -423,6 +425,10 @@ public:
// FIXME: This should be in CompilationInfo.
std::string GetProgramPath(StringRef Name, const ToolChain &TC) const;
+ /// handleAutocompletions - Handle --autocomplete by searching and printing
+ /// possible flags, descriptions, and its arguments.
+ void handleAutocompletions(StringRef PassedFlags) const;
+
/// HandleImmediateArgs - Handle any arguments which should be
/// treated before building actions or binding tools.
///
diff --git a/include/clang/Driver/Job.h b/include/clang/Driver/Job.h
index ff88256b8c0d..b74b3b4b35e1 100644
--- a/include/clang/Driver/Job.h
+++ b/include/clang/Driver/Job.h
@@ -97,8 +97,8 @@ public:
virtual void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
CrashReportInfo *CrashInfo = nullptr) const;
- virtual int Execute(const StringRef **Redirects, std::string *ErrMsg,
- bool *ExecutionFailed) const;
+ virtual int Execute(ArrayRef<Optional<StringRef>> Redirects,
+ std::string *ErrMsg, bool *ExecutionFailed) const;
/// getSource - Return the Action which caused the creation of this job.
const Action &getSource() const { return Source; }
@@ -141,7 +141,7 @@ public:
void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
CrashReportInfo *CrashInfo = nullptr) const override;
- int Execute(const StringRef **Redirects, std::string *ErrMsg,
+ int Execute(ArrayRef<Optional<StringRef>> Redirects, std::string *ErrMsg,
bool *ExecutionFailed) const override;
private:
@@ -158,7 +158,7 @@ public:
void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
CrashReportInfo *CrashInfo = nullptr) const override;
- int Execute(const StringRef **Redirects, std::string *ErrMsg,
+ int Execute(ArrayRef<Optional<StringRef>> Redirects, std::string *ErrMsg,
bool *ExecutionFailed) const override;
};
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index 05dc9d7eb3ad..d36e1a63220e 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -139,6 +139,10 @@ def m_arm_Features_Group : OptionGroup<"<arm features group>">,
Group<m_Group>, DocName<"ARM">;
def m_hexagon_Features_Group : OptionGroup<"<hexagon features group>">,
Group<m_Group>, DocName<"Hexagon">;
+// The features added by this group will not be added to target features.
+// These are explicitly handled.
+def m_hexagon_Features_HVX_Group : OptionGroup<"<hexagon features group>">,
+ Group<m_Group>, DocName<"Hexagon">;
def m_ppc_Features_Group : OptionGroup<"<ppc features group>">,
Group<m_Group>, DocName<"PowerPC">;
def m_wasm_Features_Group : OptionGroup<"<wasm features group>">,
@@ -459,6 +463,10 @@ def Xcuda_fatbinary : Separate<["-"], "Xcuda-fatbinary">,
HelpText<"Pass <arg> to fatbinary invocation">, MetaVarName<"<arg>">;
def Xcuda_ptxas : Separate<["-"], "Xcuda-ptxas">,
HelpText<"Pass <arg> to the ptxas assembler">, MetaVarName<"<arg>">;
+def Xopenmp_target : Separate<["-"], "Xopenmp-target">,
+ HelpText<"Pass <arg> to the target offloading toolchain.">, MetaVarName<"<arg>">;
+def Xopenmp_target_EQ : JoinedAndSeparate<["-"], "Xopenmp-target=">,
+ HelpText<"Pass <arg> to the specified target offloading toolchain. The triple that identifies the toolchain must be provided after the equals sign.">, MetaVarName<"<arg>">;
def z : Separate<["-"], "z">, Flags<[LinkerInput, RenderAsInput]>,
HelpText<"Pass -z <arg> to the linker">, MetaVarName<"<arg>">,
Group<Link_Group>;
@@ -511,7 +519,7 @@ def cl_fp32_correctly_rounded_divide_sqrt : Flag<["-"], "cl-fp32-correctly-round
def client__name : JoinedOrSeparate<["-"], "client_name">;
def combine : Flag<["-", "--"], "combine">, Flags<[DriverOption, Unsupported]>;
def compatibility__version : JoinedOrSeparate<["-"], "compatibility_version">;
-def coverage : Flag<["-", "--"], "coverage">;
+def coverage : Flag<["-", "--"], "coverage">, Flags<[CoreOption]>;
def cpp_precomp : Flag<["-"], "cpp-precomp">, Group<clang_ignored_f_Group>;
def current__version : JoinedOrSeparate<["-"], "current_version">;
def cxx_isystem : JoinedOrSeparate<["-"], "cxx-isystem">, Group<clang_i_Group>,
@@ -588,7 +596,9 @@ 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_libasan : Flag<["-"], "shared-libasan">;
+def shared_libsan : Flag<["-"], "shared-libsan">;
+def static_libsan : Flag<["-"], "static-libsan">;
+def : Flag<["-"], "shared-libasan">, Alias<shared_libsan>;
def fasm : Flag<["-"], "fasm">, Group<f_Group>;
def fasm_blocks : Flag<["-"], "fasm-blocks">, Group<f_Group>, Flags<[CC1Option]>;
@@ -600,6 +610,13 @@ def fastf : Flag<["-"], "fastf">, Group<f_Group>;
def fast : Flag<["-"], "fast">, Group<f_Group>;
def fasynchronous_unwind_tables : Flag<["-"], "fasynchronous-unwind-tables">, Group<f_Group>;
+def fdouble_square_bracket_attributes : Flag<[ "-" ], "fdouble-square-bracket-attributes">,
+ Group<f_Group>, Flags<[DriverOption, CC1Option]>,
+ HelpText<"Enable '[[]]' attributes in all C and C++ language modes">;
+def fno_double_square_bracket_attributes : Flag<[ "-" ], "fno-double-square-bracket-attributes">,
+ Group<f_Group>, Flags<[DriverOption, CC1Option]>,
+ HelpText<"Disable '[[]]' attributes in all C and C++ language modes">;
+
def fautolink : Flag <["-"], "fautolink">, Group<f_Group>;
def fno_autolink : Flag <["-"], "fno-autolink">, Group<f_Group>,
Flags<[DriverOption, CC1Option]>,
@@ -633,12 +650,25 @@ def fno_profile_sample_use : Flag<["-"], "fno-profile-sample-use">, Group<f_Grou
def fprofile_sample_use_EQ : Joined<["-"], "fprofile-sample-use=">,
Group<f_Group>, Flags<[DriverOption, CC1Option]>,
HelpText<"Enable sample-based profile guided optimizations">;
+def fprofile_sample_accurate : Flag<["-"], "fprofile-sample-accurate">,
+ Group<f_Group>, Flags<[DriverOption, CC1Option]>,
+ HelpText<"Specifies that the sample profile is accurate">,
+ DocBrief<[{Specifies that the sample profile is accurate. If the sample
+ profile is accurate, callsites without profile samples are marked
+ as cold. Otherwise, treat callsites without profile samples as if
+ we have no profile}]>;
+def fno_profile_sample_accurate : Flag<["-"], "fno-profile-sample-accurate">,
+ Group<f_Group>, Flags<[DriverOption]>;
def fauto_profile : Flag<["-"], "fauto-profile">, Group<f_Group>,
Alias<fprofile_sample_use>;
def fno_auto_profile : Flag<["-"], "fno-auto-profile">, Group<f_Group>,
Alias<fno_profile_sample_use>;
def fauto_profile_EQ : Joined<["-"], "fauto-profile=">,
Alias<fprofile_sample_use_EQ>;
+def fauto_profile_accurate : Flag<["-"], "fauto-profile-accurate">,
+ Group<f_Group>, Alias<fprofile_sample_accurate>;
+def fno_auto_profile_accurate : Flag<["-"], "fno-auto-profile-accurate">,
+ Group<f_Group>, Alias<fno_profile_sample_accurate>;
def fdebug_info_for_profiling : Flag<["-"], "fdebug-info-for-profiling">, Group<f_Group>,
Flags<[CC1Option]>,
HelpText<"Emit extra debug info to make sample profile more accurate.">;
@@ -770,8 +800,12 @@ def fencoding_EQ : Joined<["-"], "fencoding=">, Group<f_Group>;
def ferror_limit_EQ : Joined<["-"], "ferror-limit=">, Group<f_Group>, Flags<[CoreOption]>;
def fexceptions : Flag<["-"], "fexceptions">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Enable support for exception handling">;
+def fdwarf_exceptions : Flag<["-"], "fdwarf-exceptions">, Group<f_Group>,
+ Flags<[CC1Option]>, HelpText<"Use DWARF style exceptions">;
def fsjlj_exceptions : Flag<["-"], "fsjlj-exceptions">, Group<f_Group>,
Flags<[CC1Option]>, HelpText<"Use SjLj style exceptions">;
+def fseh_exceptions : Flag<["-"], "fseh-exceptions">, Group<f_Group>,
+ Flags<[CC1Option]>, HelpText<"Use SEH style exceptions">;
def fexcess_precision_EQ : Joined<["-"], "fexcess-precision=">,
Group<clang_ignored_gcc_optimization_f_Group>;
def : Flag<["-"], "fexpensive-optimizations">, Group<clang_ignored_gcc_optimization_f_Group>;
@@ -834,6 +868,9 @@ def fno_sanitize_memory_track_origins : Flag<["-"], "fno-sanitize-memory-track-o
def fsanitize_memory_use_after_dtor : Flag<["-"], "fsanitize-memory-use-after-dtor">,
Group<f_clang_Group>,
HelpText<"Enable use-after-destroy detection in MemorySanitizer">;
+def fno_sanitize_memory_use_after_dtor : Flag<["-"], "fno-sanitize-memory-use-after-dtor">,
+ Group<f_clang_Group>,
+ HelpText<"Disable use-after-destroy detection in MemorySanitizer">;
def fsanitize_address_field_padding : Joined<["-"], "fsanitize-address-field-padding=">,
Group<f_clang_Group>,
HelpText<"Level of field padding for AddressSanitizer">;
@@ -868,6 +905,10 @@ def fsanitize_undefined_trap_on_error : Flag<["-"], "fsanitize-undefined-trap-on
Group<f_clang_Group>;
def fno_sanitize_undefined_trap_on_error : Flag<["-"], "fno-sanitize-undefined-trap-on-error">,
Group<f_clang_Group>;
+def fsanitize_minimal_runtime : Flag<["-"], "fsanitize-minimal-runtime">,
+ Group<f_clang_Group>;
+def fno_sanitize_minimal_runtime : Flag<["-"], "fno-sanitize-minimal-runtime">,
+ Group<f_clang_Group>;
def fsanitize_link_cxx_runtime : Flag<["-"], "fsanitize-link-c++-runtime">,
Group<f_clang_Group>;
def fsanitize_cfi_cross_dso : Flag<["-"], "fsanitize-cfi-cross-dso">,
@@ -877,6 +918,9 @@ def fno_sanitize_cfi_cross_dso : Flag<["-"], "fno-sanitize-cfi-cross-dso">,
Flags<[CoreOption, DriverOption]>,
Group<f_clang_Group>,
HelpText<"Disable control flow integrity (CFI) checks for cross-DSO calls.">;
+def fsanitize_cfi_icall_generalize_pointers : Flag<["-"], "fsanitize-cfi-icall-generalize-pointers">,
+ Group<f_clang_Group>,
+ HelpText<"Generalize pointers in CFI indirect call type signature checks">;
def fsanitize_stats : Flag<["-"], "fsanitize-stats">,
Group<f_clang_Group>,
HelpText<"Enable sanitizer statistics gathering.">;
@@ -988,6 +1032,10 @@ def finput_charset_EQ : Joined<["-"], "finput-charset=">, Group<f_Group>;
def fexec_charset_EQ : Joined<["-"], "fexec-charset=">, Group<f_Group>;
def finstrument_functions : Flag<["-"], "finstrument-functions">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Generate calls to instrument function entry and exit">;
+def finstrument_functions_after_inlining : Flag<["-"], "finstrument-functions-after-inlining">, Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Like -finstrument-functions, but insert the calls after inlining">;
+def finstrument_function_entry_bare : Flag<["-"], "finstrument-function-entry-bare">, Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Instrument function entry only, after inlining, without arguments to the instrumentation call">;
def fxray_instrument : Flag<["-"], "fxray-instrument">, Group<f_Group>,
Flags<[CC1Option]>,
@@ -1012,6 +1060,19 @@ def fxray_never_instrument :
Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Filename defining the whitelist for imbuing the 'never instrument' XRay attribute.">;
+def fxray_always_emit_customevents : Flag<["-"], "fxray-always-emit-customevents">, Group<f_Group>,
+ Flags<[CC1Option]>,
+ HelpText<"Determine whether to always emit __xray_customevent(...) calls even if the function it appears in is not always instrumented.">;
+def fnoxray_always_emit_customevents : Flag<["-"], "fno-xray-always-emit-customevents">, Group<f_Group>,
+ Flags<[CC1Option]>;
+
+def ffine_grained_bitfield_accesses : Flag<["-"],
+ "ffine-grained-bitfield-accesses">, Group<f_clang_Group>, Flags<[CC1Option]>,
+ HelpText<"Use separate accesses for bitfields with legal widths and alignments.">;
+def fno_fine_grained_bitfield_accesses : Flag<["-"],
+ "fno-fine-grained-bitfield-accesses">, Group<f_clang_Group>, Flags<[CC1Option]>,
+ HelpText<"Use large-integer access for consecutive bitfield runs.">;
+
def flat__namespace : Flag<["-"], "flat_namespace">;
def flax_vector_conversions : Flag<["-"], "flax-vector-conversions">, Group<f_Group>;
def flimited_precision_EQ : Joined<["-"], "flimited-precision=">, Group<f_Group>;
@@ -1104,8 +1165,8 @@ def fmodule_map_file : Joined<["-"], "fmodule-map-file=">,
Group<f_Group>, Flags<[DriverOption,CC1Option]>, MetaVarName<"<file>">,
HelpText<"Load this module map file">;
def fmodule_file : Joined<["-"], "fmodule-file=">,
- Group<f_Group>, Flags<[DriverOption,CC1Option]>,
- HelpText<"Load this precompiled module file">, MetaVarName<"<file>">;
+ Group<i_Group>, Flags<[DriverOption,CC1Option]>, MetaVarName<"[<name>=]<file>">,
+ HelpText<"Specify the mapping of module name to precompiled module file, or load a module file if name is omitted.">;
def fmodules_ignore_macro : Joined<["-"], "fmodules-ignore-macro=">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Ignore the definition of the given macro when building and loading modules">;
def fmodules_decluse : Flag <["-"], "fmodules-decluse">, Group<f_Group>,
@@ -1310,6 +1371,10 @@ def fopenmp_targets_EQ : CommaJoined<["-"], "fopenmp-targets=">, Flags<[DriverOp
HelpText<"Specify comma-separated list of triples OpenMP offloading targets to be supported">;
def fopenmp_dump_offload_linker_script : Flag<["-"], "fopenmp-dump-offload-linker-script">, Group<f_Group>,
Flags<[NoArgumentUnused]>;
+def fopenmp_relocatable_target : Flag<["-"], "fopenmp-relocatable-target">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>,
+ HelpText<"OpenMP target code is compiled as relocatable using the -c flag. For OpenMP targets the code is relocatable by default.">;
+def fnoopenmp_relocatable_target : Flag<["-"], "fnoopenmp-relocatable-target">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>,
+ HelpText<"Do not compile OpenMP target code as relocatable.">;
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 force__cpusubtype__ALL : Flag<["-"], "force_cpusubtype_ALL">;
@@ -1333,6 +1398,10 @@ def fpic : Flag<["-"], "fpic">, Group<f_Group>;
def fno_pic : Flag<["-"], "fno-pic">, Group<f_Group>;
def fpie : Flag<["-"], "fpie">, Group<f_Group>;
def fno_pie : Flag<["-"], "fno-pie">, Group<f_Group>;
+def fplt : Flag<["-"], "fplt">, Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Use the PLT to make function calls">;
+def fno_plt : Flag<["-"], "fno-plt">, Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Do not use the PLT to make function calls">;
def fropi : Flag<["-"], "fropi">, Group<f_Group>;
def fno_ropi : Flag<["-"], "fno-ropi">, Group<f_Group>;
def frwpi : Flag<["-"], "frwpi">, Group<f_Group>;
@@ -1352,9 +1421,9 @@ def frtti : Flag<["-"], "frtti">, Group<f_Group>;
def : Flag<["-"], "fsched-interblock">, Group<clang_ignored_f_Group>;
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 fshort_wchar : Flag<["-"], "fshort-wchar">, Group<f_Group>, Flags<[CC1Option]>,
+def fshort_wchar : Flag<["-"], "fshort-wchar">, Group<f_Group>,
HelpText<"Force wchar_t to be a short unsigned int">;
-def fno_short_wchar : Flag<["-"], "fno-short-wchar">, Group<f_Group>, Flags<[CC1Option]>,
+def fno_short_wchar : Flag<["-"], "fno-short-wchar">, Group<f_Group>,
HelpText<"Force wchar_t to be an unsigned int">;
def fshow_overloads_EQ : Joined<["-"], "fshow-overloads=">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Which overload candidates to show when overload resolution fails: "
@@ -1477,9 +1546,10 @@ 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 fwhole_program_vtables : Flag<["-"], "fwhole-program-vtables">, Group<f_Group>,
- Flags<[CC1Option]>,
+ Flags<[CoreOption, CC1Option]>,
HelpText<"Enables whole-program vtable optimization. Requires -flto">;
-def fno_whole_program_vtables : Flag<["-"], "fno-whole-program-vtables">, Group<f_Group>;
+def fno_whole_program_vtables : Flag<["-"], "fno-whole-program-vtables">, Group<f_Group>,
+ Flags<[CoreOption]>;
def fwrapv : Flag<["-"], "fwrapv">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Treat signed integer overflow as two's complement">;
def fwritable_strings : Flag<["-"], "fwritable-strings">, Group<f_Group>, Flags<[CC1Option]>,
@@ -1571,7 +1641,7 @@ 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 ggnu_pubnames : Flag<["-"], "ggnu-pubnames">, Group<g_flags_Group>;
+def ggnu_pubnames : Flag<["-"], "ggnu-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"
@@ -1644,8 +1714,6 @@ def m16 : Flag<["-"], "m16">, Group<m_Group>, Flags<[DriverOption, CoreOption]>;
def m32 : Flag<["-"], "m32">, Group<m_Group>, Flags<[DriverOption, CoreOption]>;
def mqdsp6_compat : Flag<["-"], "mqdsp6-compat">, Group<m_Group>, Flags<[DriverOption,CC1Option]>,
HelpText<"Enable hexagon-qdsp6 backward compatibility">;
-def m3dnowa : Flag<["-"], "m3dnowa">, Group<m_x86_Features_Group>;
-def m3dnow : Flag<["-"], "m3dnow">, Group<m_x86_Features_Group>;
def m64 : Flag<["-"], "m64">, Group<m_Group>, Flags<[DriverOption, CoreOption]>;
def mx32 : Flag<["-"], "mx32">, Group<m_Group>, Flags<[DriverOption, CoreOption]>;
def mabi_EQ : Joined<["-"], "mabi=">, Group<m_Group>;
@@ -1664,6 +1732,8 @@ def mexecute_only : Flag<["-"], "mexecute-only">, Group<m_arm_Features_Group>,
HelpText<"Disallow generation of data access to code sections (ARM only)">;
def mno_execute_only : Flag<["-"], "mno-execute-only">, Group<m_arm_Features_Group>,
HelpText<"Allow generation of data access to code sections (ARM only)">;
+def mtp_mode_EQ : Joined<["-"], "mtp=">, Group<m_arm_Features_Group>, Values<"soft, cp15">,
+ HelpText<"Read thread pointer from coprocessor register (ARM only)">;
def mpure_code : Flag<["-"], "mpure-code">, Alias<mexecute_only>; // Alias for GCC compatibility
def mno_pure_code : Flag<["-"], "mno-pure-code">, Alias<mno_execute_only>;
def mtvos_version_min_EQ : Joined<["-"], "mtvos-version-min=">, Group<m_Group>;
@@ -1730,13 +1800,9 @@ def mthread_model : Separate<["-"], "mthread-model">, Group<m_Group>, Flags<[CC1
def meabi : Separate<["-"], "meabi">, Group<m_Group>, Flags<[CC1Option]>,
HelpText<"Set EABI type, e.g. 4, 5 or gnu (default depends on triple)">, Values<"default,4,5,gnu">;
-def mmmx : Flag<["-"], "mmmx">, Group<m_x86_Features_Group>;
-def mno_3dnowa : Flag<["-"], "mno-3dnowa">, Group<m_x86_Features_Group>;
-def mno_3dnow : Flag<["-"], "mno-3dnow">, Group<m_x86_Features_Group>;
def mno_constant_cfstrings : Flag<["-"], "mno-constant-cfstrings">, Group<m_Group>;
def mno_global_merge : Flag<["-"], "mno-global-merge">, Group<m_Group>, Flags<[CC1Option]>,
HelpText<"Disable merging of globals">;
-def mno_mmx : Flag<["-"], "mno-mmx">, Group<m_x86_Features_Group>;
def mno_pascal_strings : Flag<["-"], "mno-pascal-strings">,
Alias<fno_pascal_strings>;
def mno_red_zone : Flag<["-"], "mno-red-zone">, Group<m_Group>;
@@ -1744,65 +1810,6 @@ 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 mno_x87 : Flag<["-"], "mno-x87">, Group<m_x86_Features_Group>;
-def mno_80387 : Flag<["-"], "mno-80387">, Alias<mno_x87>;
-def mno_sse2 : Flag<["-"], "mno-sse2">, Group<m_x86_Features_Group>;
-def mno_sse3 : Flag<["-"], "mno-sse3">, Group<m_x86_Features_Group>;
-def mno_sse4a : Flag<["-"], "mno-sse4a">, Group<m_x86_Features_Group>;
-def mno_sse4_1 : Flag<["-"], "mno-sse4.1">, Group<m_x86_Features_Group>;
-def mno_sse4_2 : Flag<["-"], "mno-sse4.2">, Group<m_x86_Features_Group>;
-// -mno-sse4 turns off sse4.1 which has the effect of turning off everything
-// later than 4.1. -msse4 turns on 4.2 which has the effect of turning on
-// everything earlier than 4.2.
-def mno_sse4 : Flag<["-"], "mno-sse4">, Alias<mno_sse4_1>;
-def mno_sse : Flag<["-"], "mno-sse">, Group<m_x86_Features_Group>;
-def mno_ssse3 : Flag<["-"], "mno-ssse3">, Group<m_x86_Features_Group>;
-def mno_aes : Flag<["-"], "mno-aes">, Group<m_x86_Features_Group>;
-def mno_avx : Flag<["-"], "mno-avx">, Group<m_x86_Features_Group>;
-def mno_avx2 : Flag<["-"], "mno-avx2">, Group<m_x86_Features_Group>;
-def mno_avx512f : Flag<["-"], "mno-avx512f">, Group<m_x86_Features_Group>;
-def mno_avx512cd : Flag<["-"], "mno-avx512cd">, Group<m_x86_Features_Group>;
-def mno_avx512vpopcntdq : Flag<["-"], "mno-avx512vpopcntdq">, Group<m_x86_Features_Group>;
-def mno_avx512er : Flag<["-"], "mno-avx512er">, Group<m_x86_Features_Group>;
-def mno_avx512pf : Flag<["-"], "mno-avx512pf">, Group<m_x86_Features_Group>;
-def mno_avx512dq : Flag<["-"], "mno-avx512dq">, Group<m_x86_Features_Group>;
-def mno_avx512bw : Flag<["-"], "mno-avx512bw">, Group<m_x86_Features_Group>;
-def mno_avx512vl : Flag<["-"], "mno-avx512vl">, Group<m_x86_Features_Group>;
-def mno_avx512vbmi : Flag<["-"], "mno-avx512vbmi">, Group<m_x86_Features_Group>;
-def mno_avx512ifma : Flag<["-"], "mno-avx512ifma">, Group<m_x86_Features_Group>;
-def mno_pclmul : Flag<["-"], "mno-pclmul">, Group<m_x86_Features_Group>;
-def mno_lzcnt : Flag<["-"], "mno-lzcnt">, Group<m_x86_Features_Group>;
-def mno_rdrnd : Flag<["-"], "mno-rdrnd">, Group<m_x86_Features_Group>;
-def mno_fsgsbase : Flag<["-"], "mno-fsgsbase">, Group<m_x86_Features_Group>;
-def mno_bmi : Flag<["-"], "mno-bmi">, Group<m_x86_Features_Group>;
-def mno_bmi2 : Flag<["-"], "mno-bmi2">, Group<m_x86_Features_Group>;
-def mno_popcnt : Flag<["-"], "mno-popcnt">, Group<m_x86_Features_Group>;
-def mno_tbm : Flag<["-"], "mno-tbm">, Group<m_x86_Features_Group>;
-def mno_lwp : Flag<["-"], "mno-lwp">, Group<m_x86_Features_Group>;
-def mno_fma4 : Flag<["-"], "mno-fma4">, Group<m_x86_Features_Group>;
-def mno_fma : Flag<["-"], "mno-fma">, Group<m_x86_Features_Group>;
-def mno_xop : Flag<["-"], "mno-xop">, Group<m_x86_Features_Group>;
-def mno_f16c : Flag<["-"], "mno-f16c">, Group<m_x86_Features_Group>;
-def mno_rtm : Flag<["-"], "mno-rtm">, Group<m_x86_Features_Group>;
-def mno_prfchw : Flag<["-"], "mno-prfchw">, Group<m_x86_Features_Group>;
-def mno_rdseed : Flag<["-"], "mno-rdseed">, Group<m_x86_Features_Group>;
-def mno_adx : Flag<["-"], "mno-adx">, Group<m_x86_Features_Group>;
-def mno_sha : Flag<["-"], "mno-sha">, Group<m_x86_Features_Group>;
-def mno_cx16 : Flag<["-"], "mno-cx16">, Group<m_x86_Features_Group>;
-def mno_fxsr : Flag<["-"], "mno-fxsr">, Group<m_x86_Features_Group>;
-def mno_xsave : Flag<["-"], "mno-xsave">, Group<m_x86_Features_Group>;
-def mno_xsaveopt : Flag<["-"], "mno-xsaveopt">, Group<m_x86_Features_Group>;
-def mno_xsavec : Flag<["-"], "mno-xsavec">, Group<m_x86_Features_Group>;
-def mno_xsaves : Flag<["-"], "mno-xsaves">, Group<m_x86_Features_Group>;
-def mno_mwaitx : Flag<["-"], "mno-mwaitx">, Group<m_x86_Features_Group>;
-def mno_clzero : Flag<["-"], "mno-clzero">, Group<m_x86_Features_Group>;
-def mno_pku : Flag<["-"], "mno-pku">, Group<m_x86_Features_Group>;
-def mno_clflushopt : Flag<["-"], "mno-clflushopt">, Group<m_x86_Features_Group>;
-def mno_clwb : Flag<["-"], "mno-clwb">, Group<m_x86_Features_Group>;
-def mno_movbe : Flag<["-"], "mno-movbe">, Group<m_x86_Features_Group>;
-def mno_mpx : Flag<["-"], "mno-mpx">, Group<m_x86_Features_Group>;
-def mno_sgx : Flag<["-"], "mno-sgx">, Group<m_x86_Features_Group>;
-def mno_prefetchwt1 : Flag<["-"], "mno-prefetchwt1">, Group<m_x86_Features_Group>;
def munaligned_access : Flag<["-"], "munaligned-access">, Group<m_arm_Features_Group>,
HelpText<"Allow memory accesses to be unaligned (AArch32/AArch64 only)">;
@@ -1829,7 +1836,6 @@ def mno_neg_immediates: Flag<["-"], "mno-neg-immediates">, Group<m_arm_Features_
def mgeneral_regs_only : Flag<["-"], "mgeneral-regs-only">, Group<m_aarch64_Features_Group>,
HelpText<"Generate code which only uses the general purpose registers (AArch64 only)">;
-
def mfix_cortex_a53_835769 : Flag<["-"], "mfix-cortex-a53-835769">,
Group<m_aarch64_Features_Group>,
HelpText<"Workaround Cortex-A53 erratum 835769 (AArch64 only)">;
@@ -1841,12 +1847,18 @@ def ffixed_x18 : Flag<["-"], "ffixed-x18">, Group<m_aarch64_Features_Group>,
def msimd128 : Flag<["-"], "msimd128">, 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>;
def mamdgpu_debugger_abi : Joined<["-"], "mamdgpu-debugger-abi=">,
Flags<[HelpHidden]>,
Group<m_Group>,
HelpText<"Generate additional code for specified <version> of debugger ABI (AMDGPU only)">,
MetaVarName<"<version>">;
+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 faltivec : Flag<["-"], "faltivec">, Group<f_Group>, Flags<[DriverOption]>;
def fno_altivec : Flag<["-"], "fno-altivec">, Group<f_Group>, Flags<[DriverOption]>;
@@ -1942,68 +1954,14 @@ def mno_implicit_float : Flag<["-"], "mno-implicit-float">, Group<m_Group>,
def mimplicit_float : Flag<["-"], "mimplicit-float">, Group<m_Group>;
def mrecip : Flag<["-"], "mrecip">, Group<m_Group>;
def mrecip_EQ : CommaJoined<["-"], "mrecip=">, Group<m_Group>, Flags<[CC1Option]>;
+def mprefer_vector_width_EQ : Joined<["-"], "mprefer-vector-width=">, Group<m_Group>, Flags<[CC1Option]>,
+ HelpText<"Specifies preferred vector width for auto-vectorization. Defaults to 'none' which allows target specific decisions.">;
def mpie_copy_relocations : Flag<["-"], "mpie-copy-relocations">, Group<m_Group>,
Flags<[CC1Option]>,
HelpText<"Use copy relocations support for PIE builds">;
def mno_pie_copy_relocations : Flag<["-"], "mno-pie-copy-relocations">, Group<m_Group>;
def mfentry : Flag<["-"], "mfentry">, HelpText<"Insert calls to fentry at function entry (x86 only)">,
Flags<[CC1Option]>, Group<m_Group>;
-def mx87 : Flag<["-"], "mx87">, Group<m_x86_Features_Group>;
-def m80387 : Flag<["-"], "m80387">, Alias<mx87>;
-def msse2 : Flag<["-"], "msse2">, Group<m_x86_Features_Group>;
-def msse3 : Flag<["-"], "msse3">, Group<m_x86_Features_Group>;
-def msse4a : Flag<["-"], "msse4a">, Group<m_x86_Features_Group>;
-def msse4_1 : Flag<["-"], "msse4.1">, Group<m_x86_Features_Group>;
-def msse4_2 : Flag<["-"], "msse4.2">, Group<m_x86_Features_Group>;
-def msse4 : Flag<["-"], "msse4">, Alias<msse4_2>;
-def msse : Flag<["-"], "msse">, Group<m_x86_Features_Group>;
-def mssse3 : Flag<["-"], "mssse3">, Group<m_x86_Features_Group>;
-def maes : Flag<["-"], "maes">, Group<m_x86_Features_Group>;
-def mavx : Flag<["-"], "mavx">, Group<m_x86_Features_Group>;
-def mavx2 : Flag<["-"], "mavx2">, Group<m_x86_Features_Group>;
-def mavx512f : Flag<["-"], "mavx512f">, Group<m_x86_Features_Group>;
-def mavx512cd : Flag<["-"], "mavx512cd">, Group<m_x86_Features_Group>;
-def mavx512vpopcntdq : Flag<["-"], "mavx512vpopcntdq">, Group<m_x86_Features_Group>;
-def mavx512er : Flag<["-"], "mavx512er">, Group<m_x86_Features_Group>;
-def mavx512pf : Flag<["-"], "mavx512pf">, Group<m_x86_Features_Group>;
-def mavx512dq : Flag<["-"], "mavx512dq">, Group<m_x86_Features_Group>;
-def mavx512bw : Flag<["-"], "mavx512bw">, Group<m_x86_Features_Group>;
-def mavx512vl : Flag<["-"], "mavx512vl">, Group<m_x86_Features_Group>;
-def mavx512vbmi : Flag<["-"], "mavx512vbmi">, Group<m_x86_Features_Group>;
-def mavx512ifma : Flag<["-"], "mavx512ifma">, Group<m_x86_Features_Group>;
-def mpclmul : Flag<["-"], "mpclmul">, Group<m_x86_Features_Group>;
-def mlzcnt : Flag<["-"], "mlzcnt">, Group<m_x86_Features_Group>;
-def mrdrnd : Flag<["-"], "mrdrnd">, Group<m_x86_Features_Group>;
-def mfsgsbase : Flag<["-"], "mfsgsbase">, Group<m_x86_Features_Group>;
-def mbmi : Flag<["-"], "mbmi">, Group<m_x86_Features_Group>;
-def mbmi2 : Flag<["-"], "mbmi2">, Group<m_x86_Features_Group>;
-def mpopcnt : Flag<["-"], "mpopcnt">, Group<m_x86_Features_Group>;
-def mtbm : Flag<["-"], "mtbm">, Group<m_x86_Features_Group>;
-def mlwp : Flag<["-"], "mlwp">, Group<m_x86_Features_Group>;
-def mfma4 : Flag<["-"], "mfma4">, Group<m_x86_Features_Group>;
-def mfma : Flag<["-"], "mfma">, Group<m_x86_Features_Group>;
-def mxop : Flag<["-"], "mxop">, Group<m_x86_Features_Group>;
-def mf16c : Flag<["-"], "mf16c">, Group<m_x86_Features_Group>;
-def mrtm : Flag<["-"], "mrtm">, Group<m_x86_Features_Group>;
-def mprfchw : Flag<["-"], "mprfchw">, Group<m_x86_Features_Group>;
-def mrdseed : Flag<["-"], "mrdseed">, Group<m_x86_Features_Group>;
-def mpku : Flag<["-"], "mpku">, Group<m_x86_Features_Group>;
-def madx : Flag<["-"], "madx">, Group<m_x86_Features_Group>;
-def msha : Flag<["-"], "msha">, Group<m_x86_Features_Group>;
-def mcx16 : Flag<["-"], "mcx16">, Group<m_x86_Features_Group>;
-def mfxsr : Flag<["-"], "mfxsr">, Group<m_x86_Features_Group>;
-def mxsave : Flag<["-"], "mxsave">, Group<m_x86_Features_Group>;
-def mxsaveopt : Flag<["-"], "mxsaveopt">, Group<m_x86_Features_Group>;
-def mxsavec : Flag<["-"], "mxsavec">, Group<m_x86_Features_Group>;
-def mxsaves : Flag<["-"], "mxsaves">, Group<m_x86_Features_Group>;
-def mmwaitx : Flag<["-"], "mmwaitx">, Group<m_x86_Features_Group>;
-def mclzero : Flag<["-"], "mclzero">, Group<m_x86_Features_Group>;
-def mclflushopt : Flag<["-"], "mclflushopt">, Group<m_x86_Features_Group>;
-def mclwb : Flag<["-"], "mclwb">, Group<m_x86_Features_Group>;
-def mmovbe : Flag<["-"], "mmovbe">, Group<m_x86_Features_Group>;
-def mmpx : Flag<["-"], "mmpx">, Group<m_x86_Features_Group>;
-def msgx : Flag<["-"], "msgx">, Group<m_x86_Features_Group>;
-def mprefetchwt1 : Flag<["-"], "mprefetchwt1">, Group<m_x86_Features_Group>;
def mips16 : Flag<["-"], "mips16">, Group<m_Group>;
def mno_mips16 : Flag<["-"], "mno-mips16">, Group<m_Group>;
def mmicromips : Flag<["-"], "mmicromips">, Group<m_Group>;
@@ -2016,6 +1974,10 @@ def mcheck_zero_division : Flag<["-"], "mcheck-zero-division">, Group<m_Group>;
def mno_check_zero_division : Flag<["-"], "mno-check-zero-division">,
Group<m_Group>;
def mcompact_branches_EQ : Joined<["-"], "mcompact-branches=">, Group<m_Group>;
+def mbranch_likely : Flag<["-"], "mbranch-likely">, Group<m_Group>,
+ IgnoredGCCCompat;
+def mno_branch_likely : Flag<["-"], "mno-branch-likely">, Group<m_Group>,
+ IgnoredGCCCompat;
def mdsp : Flag<["-"], "mdsp">, Group<m_Group>;
def mno_dsp : Flag<["-"], "mno-dsp">, Group<m_Group>;
def mdspr2 : Flag<["-"], "mdspr2">, Group<m_Group>;
@@ -2038,7 +2000,30 @@ def mfp64 : Flag<["-"], "mfp64">, Group<m_Group>,
HelpText<"Use 64-bit floating point registers (MIPS only)">;
def mfp32 : Flag<["-"], "mfp32">, Group<m_Group>,
HelpText<"Use 32-bit floating point registers (MIPS only)">;
+def mgpopt : Flag<["-"], "mgpopt">, Group<m_Group>,
+ HelpText<"Use GP relative accesses for symbols known to be in a small"
+ " data section (MIPS)">;
+def mno_gpopt : Flag<["-"], "mno-gpopt">, Group<m_Group>,
+ HelpText<"Do not use GP relative accesses for symbols known to be in a small"
+ " data section (MIPS)">;
+def mlocal_sdata : Flag<["-"], "mlocal-sdata">, Group<m_Group>,
+ HelpText<"Extend the -G behaviour to object local data (MIPS)">;
+def mno_local_sdata : Flag<["-"], "mno-local-sdata">, Group<m_Group>,
+ HelpText<"Do not extend the -G behaviour to object local data (MIPS)">;
+def mextern_sdata : Flag<["-"], "mextern-sdata">, Group<m_Group>,
+ HelpText<"Assume that externally defined data is in the small data if it"
+ " meets the -G <size> threshold (MIPS)">;
+def mno_extern_sdata : Flag<["-"], "mno-extern-sdata">, Group<m_Group>,
+ HelpText<"Do not assume that externally defined data is in the small data if"
+ " it meets the -G <size> threshold (MIPS)">;
+def membedded_data : Flag<["-"], "membedded-data">, Group<m_Group>,
+ HelpText<"Place constants in the .rodata section instead of the .sdata "
+ "section even if they meet the -G <size> threshold (MIPS)">;
+def mno_embedded_data : Flag<["-"], "mno-embedded-data">, Group<m_Group>,
+ HelpText<"Do not place constants in the .rodata section instead of the "
+ ".sdata if they meet the -G <size> threshold (MIPS)">;
def mnan_EQ : Joined<["-"], "mnan=">, Group<m_Group>;
+def mabs_EQ : Joined<["-"], "mabs=">, Group<m_Group>;
def mabicalls : Flag<["-"], "mabicalls">, Group<m_Group>,
HelpText<"Enable SVR4-style position-independent code (Mips only)">;
def mno_abicalls : Flag<["-"], "mno-abicalls">, Group<m_Group>,
@@ -2131,6 +2116,7 @@ def nostdlibinc : Flag<["-"], "nostdlibinc">;
def nostdincxx : Flag<["-"], "nostdinc++">, Flags<[CC1Option]>,
HelpText<"Disable standard #include directories for the C++ standard library">;
def nostdlib : Flag<["-"], "nostdlib">;
+def nostdlibxx : Flag<["-"], "nostdlib++">;
def object : Flag<["-"], "object">;
def o : JoinedOrSeparate<["-"], "o">, Flags<[DriverOption, RenderAsInput, CC1Option, CC1AsOption]>,
HelpText<"Write output to <file>">, MetaVarName<"<file>">;
@@ -2225,7 +2211,14 @@ def static_libstdcxx : Flag<["-"], "static-libstdc++">;
def static : Flag<["-", "--"], "static">, Flags<[NoArgumentUnused]>;
def std_default_EQ : Joined<["-"], "std-default=">;
def std_EQ : Joined<["-", "--"], "std=">, Flags<[CC1Option]>,
- Group<CompileOnly_Group>, HelpText<"Language standard to compile for">;
+ Group<CompileOnly_Group>, HelpText<"Language standard to compile for">,
+ ValuesCode<[{
+ const char *Values =
+ #define LANGSTANDARD(id, name, lang, desc, features) name ","
+ #define LANGSTANDARD_ALIAS(id, alias) alias ","
+ #include "clang/Frontend/LangStandards.def"
+ ;
+ }]>;
def stdlib_EQ : Joined<["-", "--"], "stdlib=">, Flags<[CC1Option]>,
HelpText<"C++ standard library to use">, Values<"libc++,libstdc++,platform">;
def sub__library : JoinedOrSeparate<["-"], "sub_library">;
@@ -2383,7 +2376,8 @@ def _rtlib : Separate<["--"], "rtlib">, Alias<rtlib_EQ>;
def _serialize_diags : Separate<["-", "--"], "serialize-diagnostics">, Flags<[DriverOption]>,
HelpText<"Serialize compiler diagnostics to a file">;
// We give --version different semantics from -version.
-def _version : Flag<["--"], "version">, Flags<[CC1Option]>;
+def _version : Flag<["--"], "version">, Flags<[CoreOption, CC1Option]>,
+ HelpText<"Print version information">;
def _signed_char : Flag<["--"], "signed-char">, Alias<fsigned_char>;
def _std : Separate<["--"], "std">, Alias<std_EQ>;
def _stdlib : Separate<["--"], "stdlib">, Alias<stdlib_EQ>;
@@ -2413,14 +2407,156 @@ def mv60 : Flag<["-"], "mv60">, Group<m_hexagon_Features_Group>,
Alias<mcpu_EQ>, AliasArgs<["hexagonv60"]>;
def mv62 : Flag<["-"], "mv62">, Group<m_hexagon_Features_Group>,
Alias<mcpu_EQ>, AliasArgs<["hexagonv62"]>;
-def mhexagon_hvx : Flag<["-"], "mhvx">, Group<m_hexagon_Features_Group>,
- Flags<[CC1Option]>, HelpText<"Enable Hexagon Vector eXtensions">;
-def mno_hexagon_hvx : Flag<["-"], "mno-hvx">, Group<m_hexagon_Features_Group>,
- Flags<[CC1Option]>, HelpText<"Disable Hexagon Vector eXtensions">;
-def mhexagon_hvx_double : Flag<["-"], "mhvx-double">, Group<m_hexagon_Features_Group>,
- Flags<[CC1Option]>, HelpText<"Enable Hexagon Double Vector eXtensions">;
-def mno_hexagon_hvx_double : Flag<["-"], "mno-hvx-double">, Group<m_hexagon_Features_Group>,
- Flags<[CC1Option]>, HelpText<"Disable Hexagon Double Vector eXtensions">;
+def mv65 : Flag<["-"], "mv65">, Group<m_hexagon_Features_Group>,
+ Alias<mcpu_EQ>, AliasArgs<["hexagonv65"]>;
+def mhexagon_hvx : Flag<[ "-" ], "mhvx">,
+ Group<m_hexagon_Features_HVX_Group>,
+ HelpText<"Enable Hexagon Vector eXtensions">;
+def mhexagon_hvx_EQ : Joined<[ "-" ], "mhvx=">,
+ Group<m_hexagon_Features_HVX_Group>,
+ HelpText<"Enable Hexagon Vector eXtensions">;
+def mno_hexagon_hvx : Flag<[ "-" ], "mno-hvx">,
+ Group<m_hexagon_Features_HVX_Group>,
+ HelpText<"Disable Hexagon Vector eXtensions">;
+def mhexagon_hvx_length_EQ : Joined<[ "-" ], "mhvx-length=">,
+ Group<m_hexagon_Features_HVX_Group>,
+ HelpText<"Set Hexagon Vector Length">, Values<"64B,128B">;
+// hvx-double deprecrated flag.
+def mhexagon_hvx_double : Flag<[ "-" ], "mhvx-double">,
+ Group<m_hexagon_Features_HVX_Group>,
+ HelpText<"Enable Hexagon Double Vector eXtensions">;
+def mno_hexagon_hvx_double
+ : Flag<[ "-" ], "mno-hvx-double">,
+ Group<m_hexagon_Features_HVX_Group>,
+ HelpText<"Disable Hexagon Double Vector eXtensions">;
+
+
+// X86 feature flags
+def mx87 : Flag<["-"], "mx87">, Group<m_x86_Features_Group>;
+def mno_x87 : Flag<["-"], "mno-x87">, Group<m_x86_Features_Group>;
+def m80387 : Flag<["-"], "m80387">, Alias<mx87>;
+def mno_80387 : Flag<["-"], "mno-80387">, Alias<mno_x87>;
+def mmmx : Flag<["-"], "mmmx">, Group<m_x86_Features_Group>;
+def mno_mmx : Flag<["-"], "mno-mmx">, Group<m_x86_Features_Group>;
+def m3dnow : Flag<["-"], "m3dnow">, Group<m_x86_Features_Group>;
+def mno_3dnow : Flag<["-"], "mno-3dnow">, Group<m_x86_Features_Group>;
+def m3dnowa : Flag<["-"], "m3dnowa">, Group<m_x86_Features_Group>;
+def mno_3dnowa : Flag<["-"], "mno-3dnowa">, Group<m_x86_Features_Group>;
+def msse : Flag<["-"], "msse">, Group<m_x86_Features_Group>;
+def mno_sse : Flag<["-"], "mno-sse">, Group<m_x86_Features_Group>;
+def msse2 : Flag<["-"], "msse2">, Group<m_x86_Features_Group>;
+def mno_sse2 : Flag<["-"], "mno-sse2">, Group<m_x86_Features_Group>;
+def msse3 : Flag<["-"], "msse3">, Group<m_x86_Features_Group>;
+def mno_sse3 : Flag<["-"], "mno-sse3">, Group<m_x86_Features_Group>;
+def mssse3 : Flag<["-"], "mssse3">, Group<m_x86_Features_Group>;
+def mno_ssse3 : Flag<["-"], "mno-ssse3">, Group<m_x86_Features_Group>;
+def msse4_1 : Flag<["-"], "msse4.1">, Group<m_x86_Features_Group>;
+def mno_sse4_1 : Flag<["-"], "mno-sse4.1">, Group<m_x86_Features_Group>;
+def msse4_2 : Flag<["-"], "msse4.2">, Group<m_x86_Features_Group>;
+def mno_sse4_2 : Flag<["-"], "mno-sse4.2">, Group<m_x86_Features_Group>;
+def msse4 : Flag<["-"], "msse4">, Alias<msse4_2>;
+// -mno-sse4 turns off sse4.1 which has the effect of turning off everything
+// later than 4.1. -msse4 turns on 4.2 which has the effect of turning on
+// everything earlier than 4.2.
+def mno_sse4 : Flag<["-"], "mno-sse4">, Alias<mno_sse4_1>;
+def msse4a : Flag<["-"], "msse4a">, Group<m_x86_Features_Group>;
+def mno_sse4a : Flag<["-"], "mno-sse4a">, Group<m_x86_Features_Group>;
+def mavx : Flag<["-"], "mavx">, Group<m_x86_Features_Group>;
+def mno_avx : Flag<["-"], "mno-avx">, Group<m_x86_Features_Group>;
+def mavx2 : Flag<["-"], "mavx2">, Group<m_x86_Features_Group>;
+def mno_avx2 : Flag<["-"], "mno-avx2">, Group<m_x86_Features_Group>;
+def mavx512f : Flag<["-"], "mavx512f">, Group<m_x86_Features_Group>;
+def mno_avx512f : Flag<["-"], "mno-avx512f">, Group<m_x86_Features_Group>;
+def mavx512bw : Flag<["-"], "mavx512bw">, Group<m_x86_Features_Group>;
+def mno_avx512bw : Flag<["-"], "mno-avx512bw">, Group<m_x86_Features_Group>;
+def mavx512cd : Flag<["-"], "mavx512cd">, Group<m_x86_Features_Group>;
+def mno_avx512cd : Flag<["-"], "mno-avx512cd">, Group<m_x86_Features_Group>;
+def mavx512dq : Flag<["-"], "mavx512dq">, Group<m_x86_Features_Group>;
+def mno_avx512dq : Flag<["-"], "mno-avx512dq">, Group<m_x86_Features_Group>;
+def mavx512er : Flag<["-"], "mavx512er">, Group<m_x86_Features_Group>;
+def mno_avx512er : Flag<["-"], "mno-avx512er">, Group<m_x86_Features_Group>;
+def mavx512ifma : Flag<["-"], "mavx512ifma">, Group<m_x86_Features_Group>;
+def mno_avx512ifma : Flag<["-"], "mno-avx512ifma">, Group<m_x86_Features_Group>;
+def mavx512pf : Flag<["-"], "mavx512pf">, Group<m_x86_Features_Group>;
+def mno_avx512pf : Flag<["-"], "mno-avx512pf">, Group<m_x86_Features_Group>;
+def mavx512vbmi : Flag<["-"], "mavx512vbmi">, Group<m_x86_Features_Group>;
+def mno_avx512vbmi : Flag<["-"], "mno-avx512vbmi">, Group<m_x86_Features_Group>;
+def mavx512vl : Flag<["-"], "mavx512vl">, Group<m_x86_Features_Group>;
+def mno_avx512vl : Flag<["-"], "mno-avx512vl">, Group<m_x86_Features_Group>;
+def mavx512vpopcntdq : Flag<["-"], "mavx512vpopcntdq">, Group<m_x86_Features_Group>;
+def mno_avx512vpopcntdq : Flag<["-"], "mno-avx512vpopcntdq">, Group<m_x86_Features_Group>;
+def madx : Flag<["-"], "madx">, Group<m_x86_Features_Group>;
+def mno_adx : Flag<["-"], "mno-adx">, Group<m_x86_Features_Group>;
+def maes : Flag<["-"], "maes">, Group<m_x86_Features_Group>;
+def mno_aes : Flag<["-"], "mno-aes">, Group<m_x86_Features_Group>;
+def mbmi : Flag<["-"], "mbmi">, Group<m_x86_Features_Group>;
+def mno_bmi : Flag<["-"], "mno-bmi">, Group<m_x86_Features_Group>;
+def mbmi2 : Flag<["-"], "mbmi2">, Group<m_x86_Features_Group>;
+def mno_bmi2 : Flag<["-"], "mno-bmi2">, Group<m_x86_Features_Group>;
+def mclflushopt : Flag<["-"], "mclflushopt">, Group<m_x86_Features_Group>;
+def mno_clflushopt : Flag<["-"], "mno-clflushopt">, Group<m_x86_Features_Group>;
+def mclwb : Flag<["-"], "mclwb">, Group<m_x86_Features_Group>;
+def mno_clwb : Flag<["-"], "mno-clwb">, Group<m_x86_Features_Group>;
+def mclzero : Flag<["-"], "mclzero">, Group<m_x86_Features_Group>;
+def mno_clzero : Flag<["-"], "mno-clzero">, Group<m_x86_Features_Group>;
+def mcx16 : Flag<["-"], "mcx16">, Group<m_x86_Features_Group>;
+def mno_cx16 : Flag<["-"], "mno-cx16">, Group<m_x86_Features_Group>;
+def mf16c : Flag<["-"], "mf16c">, Group<m_x86_Features_Group>;
+def mno_f16c : Flag<["-"], "mno-f16c">, Group<m_x86_Features_Group>;
+def mfma : Flag<["-"], "mfma">, Group<m_x86_Features_Group>;
+def mno_fma : Flag<["-"], "mno-fma">, Group<m_x86_Features_Group>;
+def mfma4 : Flag<["-"], "mfma4">, Group<m_x86_Features_Group>;
+def mno_fma4 : Flag<["-"], "mno-fma4">, Group<m_x86_Features_Group>;
+def mfsgsbase : Flag<["-"], "mfsgsbase">, Group<m_x86_Features_Group>;
+def mno_fsgsbase : Flag<["-"], "mno-fsgsbase">, Group<m_x86_Features_Group>;
+def mfxsr : Flag<["-"], "mfxsr">, Group<m_x86_Features_Group>;
+def mno_fxsr : Flag<["-"], "mno-fxsr">, Group<m_x86_Features_Group>;
+def mlwp : Flag<["-"], "mlwp">, Group<m_x86_Features_Group>;
+def mno_lwp : Flag<["-"], "mno-lwp">, Group<m_x86_Features_Group>;
+def mlzcnt : Flag<["-"], "mlzcnt">, Group<m_x86_Features_Group>;
+def mno_lzcnt : Flag<["-"], "mno-lzcnt">, Group<m_x86_Features_Group>;
+def mmovbe : Flag<["-"], "mmovbe">, Group<m_x86_Features_Group>;
+def mno_movbe : Flag<["-"], "mno-movbe">, Group<m_x86_Features_Group>;
+def mmpx : Flag<["-"], "mmpx">, Group<m_x86_Features_Group>;
+def mno_mpx : Flag<["-"], "mno-mpx">, Group<m_x86_Features_Group>;
+def mmwaitx : Flag<["-"], "mmwaitx">, Group<m_x86_Features_Group>;
+def mno_mwaitx : Flag<["-"], "mno-mwaitx">, Group<m_x86_Features_Group>;
+def mpku : Flag<["-"], "mpku">, Group<m_x86_Features_Group>;
+def mno_pku : Flag<["-"], "mno-pku">, Group<m_x86_Features_Group>;
+def mpclmul : Flag<["-"], "mpclmul">, Group<m_x86_Features_Group>;
+def mno_pclmul : Flag<["-"], "mno-pclmul">, Group<m_x86_Features_Group>;
+def mpopcnt : Flag<["-"], "mpopcnt">, Group<m_x86_Features_Group>;
+def mno_popcnt : Flag<["-"], "mno-popcnt">, Group<m_x86_Features_Group>;
+def mprefetchwt1 : Flag<["-"], "mprefetchwt1">, Group<m_x86_Features_Group>;
+def mno_prefetchwt1 : Flag<["-"], "mno-prefetchwt1">, Group<m_x86_Features_Group>;
+def mprfchw : Flag<["-"], "mprfchw">, Group<m_x86_Features_Group>;
+def mno_prfchw : Flag<["-"], "mno-prfchw">, Group<m_x86_Features_Group>;
+def mrdrnd : Flag<["-"], "mrdrnd">, Group<m_x86_Features_Group>;
+def mno_rdrnd : Flag<["-"], "mno-rdrnd">, Group<m_x86_Features_Group>;
+def mrtm : Flag<["-"], "mrtm">, Group<m_x86_Features_Group>;
+def mno_rtm : Flag<["-"], "mno-rtm">, Group<m_x86_Features_Group>;
+def mrdseed : Flag<["-"], "mrdseed">, Group<m_x86_Features_Group>;
+def mno_rdseed : Flag<["-"], "mno-rdseed">, Group<m_x86_Features_Group>;
+def msgx : Flag<["-"], "msgx">, Group<m_x86_Features_Group>;
+def mno_sgx : Flag<["-"], "mno-sgx">, Group<m_x86_Features_Group>;
+def msha : Flag<["-"], "msha">, Group<m_x86_Features_Group>;
+def mno_sha : Flag<["-"], "mno-sha">, Group<m_x86_Features_Group>;
+def mtbm : Flag<["-"], "mtbm">, Group<m_x86_Features_Group>;
+def mno_tbm : Flag<["-"], "mno-tbm">, Group<m_x86_Features_Group>;
+def mxop : Flag<["-"], "mxop">, Group<m_x86_Features_Group>;
+def mno_xop : Flag<["-"], "mno-xop">, Group<m_x86_Features_Group>;
+def mxsave : Flag<["-"], "mxsave">, Group<m_x86_Features_Group>;
+def mno_xsave : Flag<["-"], "mno-xsave">, Group<m_x86_Features_Group>;
+def mxsavec : Flag<["-"], "mxsavec">, Group<m_x86_Features_Group>;
+def mno_xsavec : Flag<["-"], "mno-xsavec">, Group<m_x86_Features_Group>;
+def mxsaveopt : Flag<["-"], "mxsaveopt">, Group<m_x86_Features_Group>;
+def mno_xsaveopt : Flag<["-"], "mno-xsaveopt">, Group<m_x86_Features_Group>;
+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 mibt : Flag<["-"], "mibt">, Group<m_x86_Features_Group>;
+def mno_ibt : Flag<["-"], "mno-ibt">, Group<m_x86_Features_Group>;
// These are legacy user-facing driver-level option spellings. They are always
// aliases for options that are spelled using the more common Unix / GNU flag
diff --git a/include/clang/Driver/SanitizerArgs.h b/include/clang/Driver/SanitizerArgs.h
index a9645d463fa1..a31ac05afc1b 100644
--- a/include/clang/Driver/SanitizerArgs.h
+++ b/include/clang/Driver/SanitizerArgs.h
@@ -32,41 +32,49 @@ class SanitizerArgs {
int MsanTrackOrigins = 0;
bool MsanUseAfterDtor = false;
bool CfiCrossDso = false;
+ bool CfiICallGeneralizePointers = false;
int AsanFieldPadding = 0;
- bool AsanSharedRuntime = false;
+ bool SharedRuntime = false;
bool AsanUseAfterScope = true;
bool AsanGlobalsDeadStripping = false;
bool LinkCXXRuntimes = false;
bool NeedPIE = false;
+ bool SafeStackRuntime = false;
bool Stats = false;
bool TsanMemoryAccess = true;
bool TsanFuncEntryExit = true;
bool TsanAtomics = true;
+ bool MinimalRuntime = false;
+ // True if cross-dso CFI support if provided by the system (i.e. Android).
+ bool ImplicitCfiRuntime = false;
public:
/// Parses the sanitizer arguments from an argument list.
SanitizerArgs(const ToolChain &TC, const llvm::opt::ArgList &Args);
+ bool needsSharedRt() const { return SharedRuntime; }
+
bool needsAsanRt() const { return Sanitizers.has(SanitizerKind::Address); }
- bool needsSharedAsanRt() const { return AsanSharedRuntime; }
+ bool needsHwasanRt() const { return Sanitizers.has(SanitizerKind::HWAddress); }
bool needsTsanRt() const { return Sanitizers.has(SanitizerKind::Thread); }
bool needsMsanRt() const { return Sanitizers.has(SanitizerKind::Memory); }
bool needsFuzzer() const { return Sanitizers.has(SanitizerKind::Fuzzer); }
bool needsLsanRt() const {
return Sanitizers.has(SanitizerKind::Leak) &&
- !Sanitizers.has(SanitizerKind::Address);
+ !Sanitizers.has(SanitizerKind::Address) &&
+ !Sanitizers.has(SanitizerKind::HWAddress);
}
bool needsUbsanRt() const;
+ bool requiresMinimalRuntime() const { return MinimalRuntime; }
bool needsDfsanRt() const { return Sanitizers.has(SanitizerKind::DataFlow); }
- bool needsSafeStackRt() const {
- return Sanitizers.has(SanitizerKind::SafeStack);
- }
+ bool needsSafeStackRt() const { return SafeStackRuntime; }
bool needsCfiRt() const;
bool needsCfiDiagRt() const;
bool needsStatsRt() const { return Stats; }
bool needsEsanRt() const {
return Sanitizers.hasOneOf(SanitizerKind::Efficiency);
}
+ bool needsScudoRt() const { return Sanitizers.has(SanitizerKind::Scudo); }
bool requiresPIE() const;
bool needsUnwindTables() const;
diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h
index 6651491e5b27..13f54d3718b4 100644
--- a/include/clang/Driver/ToolChain.h
+++ b/include/clang/Driver/ToolChain.h
@@ -40,12 +40,35 @@ namespace driver {
class Compilation;
class CudaInstallationDetector;
class Driver;
+ class InputInfo;
class JobAction;
class RegisterEffectiveTriple;
class SanitizerArgs;
class Tool;
class XRayArgs;
+/// Helper structure used to pass information extracted from clang executable
+/// name such as `i686-linux-android-g++`.
+///
+struct ParsedClangName {
+ /// Target part of the executable name, as `i686-linux-android`.
+ std::string TargetPrefix;
+ /// Driver mode part of the executable name, as `g++`.
+ std::string ModeSuffix;
+ /// Corresponding driver mode argument, as '--driver-mode=g++'
+ const char *DriverMode;
+ /// True if TargetPrefix is recognized as a registered target name.
+ bool TargetIsValid;
+
+ ParsedClangName() : DriverMode(nullptr), TargetIsValid(false) {}
+ ParsedClangName(std::string Suffix, const char *Mode)
+ : ModeSuffix(Suffix), DriverMode(Mode), TargetIsValid(false) {}
+ ParsedClangName(std::string Target, std::string Suffix, const char *Mode,
+ bool IsRegistered)
+ : TargetPrefix(Target), ModeSuffix(Suffix), DriverMode(Mode),
+ TargetIsValid(IsRegistered) {}
+};
+
/// ToolChain - Access to tools for a single platform.
class ToolChain {
public:
@@ -70,7 +93,7 @@ public:
private:
const Driver &D;
- const llvm::Triple Triple;
+ llvm::Triple Triple;
const llvm::opt::ArgList &Args;
// We need to initialize CachedRTTIArg before CachedRTTIMode
const llvm::opt::Arg *const CachedRTTIArg;
@@ -113,6 +136,8 @@ protected:
ToolChain(const Driver &D, const llvm::Triple &T,
const llvm::opt::ArgList &Args);
+ void setTripleEnvironment(llvm::Triple::EnvironmentType Env);
+
virtual Tool *buildAssembler() const;
virtual Tool *buildLinker() const;
virtual Tool *getTool(Action::ActionClass AC) const;
@@ -150,6 +175,11 @@ public:
/// while the aux triple is the host (CPU) toolchain, e.g. x86-linux-gnu.
virtual const llvm::Triple *getAuxTriple() const { return nullptr; }
+ /// Some toolchains need to modify the file name, for example to replace the
+ /// extension for object files with .cubin for OpenMP offloading to Nvidia
+ /// GPUs.
+ virtual std::string getInputFilename(const InputInfo &Input) const;
+
llvm::Triple::ArchType getArch() const { return Triple.getArch(); }
StringRef getArchName() const { return Triple.getArchName(); }
StringRef getPlatform() const { return Triple.getVendorName(); }
@@ -193,13 +223,16 @@ public:
/// For example, when called with i686-linux-android-g++, the first element
/// of the return value will be set to `"i686-linux-android"` and the second
/// will be set to "--driver-mode=g++"`.
+ /// It is OK if the target name is not registered. In this case the return
+ /// value contains false in the field TargetIsValid.
///
/// \pre `llvm::InitializeAllTargets()` has been called.
/// \param ProgName The name the Clang driver was invoked with (from,
- /// e.g., argv[0])
- /// \return A pair of (`target`, `mode-flag`), where one or both may be empty.
- static std::pair<std::string, std::string>
- getTargetAndModeFromProgramName(StringRef ProgName);
+ /// e.g., argv[0]).
+ /// \return A structure of type ParsedClangName that contains the executable
+ /// name parts.
+ ///
+ static ParsedClangName getTargetAndModeFromProgramName(StringRef ProgName);
// Tool access.
@@ -217,6 +250,13 @@ public:
return nullptr;
}
+ /// TranslateOpenMPTargetArgs - Create a new derived argument list for
+ /// that contains the OpenMP target specific flags passed via
+ /// -Xopenmp-target -opt=val OR -Xopenmp-target=<triple> -opt=val
+ virtual llvm::opt::DerivedArgList *TranslateOpenMPTargetArgs(
+ const llvm::opt::DerivedArgList &Args, bool SameTripleAsHost,
+ SmallVectorImpl<llvm::opt::Arg *> &AllocatedArgs) const;
+
/// Choose a tool to use to handle the action \p JA.
///
/// This can be overridden when a particular ToolChain needs to use
@@ -278,6 +318,9 @@ public:
/// mixed dispatch method be used?
virtual bool UseObjCMixedDispatch() const { return false; }
+ /// \brief Check whether to enable x86 relax relocations by default.
+ virtual bool useRelaxRelocations() const;
+
/// GetDefaultStackProtectorLevel - Get the default stack protector level for
/// this tool chain (0=off, 1=on, 2=strong, 3=all).
virtual unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const {
@@ -298,6 +341,8 @@ public:
return ToolChain::CST_Libstdcxx;
}
+ virtual std::string getCompilerRTPath() const;
+
virtual std::string getCompilerRT(const llvm::opt::ArgList &Args,
StringRef Component,
bool Shared = false) const;
@@ -332,9 +377,6 @@ public:
/// SupportsProfiling - Does this tool chain support -pg.
virtual bool SupportsProfiling() const { return true; }
- /// Does this tool chain support Objective-C garbage collection.
- virtual bool SupportsObjCGC() const { return true; }
-
/// Complain if this tool chain doesn't support Objective-C ARC.
virtual void CheckObjCARC() const {}
@@ -357,10 +399,9 @@ public:
return llvm::DebuggerKind::GDB;
}
- /// UseSjLjExceptions - Does this tool chain use SjLj exceptions.
- virtual bool UseSjLjExceptions(const llvm::opt::ArgList &Args) const {
- return false;
- }
+ /// GetExceptionModel - Return the tool chain exception model.
+ virtual llvm::ExceptionHandling
+ GetExceptionModel(const llvm::opt::ArgList &Args) const;
/// SupportsEmbeddedBitcode - Does this tool chain support embedded bitcode.
virtual bool SupportsEmbeddedBitcode() const {
@@ -432,6 +473,10 @@ public:
AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const;
+ /// Returns if the C++ standard library should be linked in.
+ /// Note that e.g. -lm should still be linked even if this returns false.
+ bool ShouldLinkCXXStdlib(const llvm::opt::ArgList &Args) const;
+
/// AddCXXStdlibLibArgs - Add the system specific linker arguments to use
/// for the given C++ standard library type.
virtual void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
diff --git a/include/clang/Driver/XRayArgs.h b/include/clang/Driver/XRayArgs.h
index 83210d100a12..e5b76162de8e 100644
--- a/include/clang/Driver/XRayArgs.h
+++ b/include/clang/Driver/XRayArgs.h
@@ -24,6 +24,7 @@ class XRayArgs {
std::vector<std::string> ExtraDeps;
bool XRayInstrument = false;
int InstructionThreshold = 200;
+ bool XRayAlwaysEmitCustomEvents = false;
public:
/// Parses the XRay arguments from an argument list.
diff --git a/include/clang/Format/Format.h b/include/clang/Format/Format.h
index 99d54e55e828..d27d934f7679 100644
--- a/include/clang/Format/Format.h
+++ b/include/clang/Format/Format.h
@@ -151,13 +151,20 @@ struct FormatStyle {
/// \endcode
bool AlignTrailingComments;
- /// \brief Allow putting all parameters of a function declaration onto
+ /// \brief If the function declaration doesn't fit on a line,
+ /// allow putting all parameters of a function declaration onto
/// the next line even if ``BinPackParameters`` is ``false``.
/// \code
- /// true: false:
- /// myFunction(foo, vs. myFunction(foo, bar, plop);
- /// bar,
- /// plop);
+ /// true:
+ /// void myFunction(
+ /// int a, int b, int c, int d, int e);
+ ///
+ /// false:
+ /// void myFunction(int a,
+ /// int b,
+ /// int c,
+ /// int d,
+ /// int e);
/// \endcode
bool AllowAllParametersOfDeclarationOnNextLine;
@@ -674,6 +681,20 @@ struct FormatStyle {
/// }
/// \endcode
bool AfterUnion;
+ /// \brief Wrap extern blocks.
+ /// \code
+ /// true:
+ /// extern "C"
+ /// {
+ /// int foo();
+ /// }
+ ///
+ /// false:
+ /// extern "C" {
+ /// int foo();
+ /// }
+ /// \endcode
+ bool AfterExternBlock;
/// \brief Wrap before ``catch``.
/// \code
/// true:
@@ -746,6 +767,14 @@ struct FormatStyle {
///
/// If ``BreakBeforeBraces`` is set to ``BS_Custom``, use this to specify how
/// each individual brace case should be handled. Otherwise, this is ignored.
+ /// \code{.yaml}
+ /// # Example of usage:
+ /// BreakBeforeBraces: Custom
+ /// BraceWrapping:
+ /// AfterEnum: true
+ /// AfterStruct: false
+ /// SplitEmptyFunction: false
+ /// \endcode
BraceWrappingFlags BraceWrapping;
/// \brief If ``true``, ternary operators will be placed after line breaks.
@@ -956,6 +985,40 @@ struct FormatStyle {
/// For example: BOOST_FOREACH.
std::vector<std::string> ForEachMacros;
+ /// \brief Styles for sorting multiple ``#include`` blocks.
+ enum IncludeBlocksStyle {
+ /// \brief Sort each ``#include`` block separately.
+ /// \code
+ /// #include "b.h" into #include "b.h"
+ ///
+ /// #include <lib/main.h> #include "a.h"
+ /// #include "a.h" #include <lib/main.h>
+ /// \endcode
+ IBS_Preserve,
+ /// \brief Merge multiple ``#include`` blocks together and sort as one.
+ /// \code
+ /// #include "b.h" into #include "a.h"
+ /// #include "b.h"
+ /// #include <lib/main.h> #include <lib/main.h>
+ /// #include "a.h"
+ /// \endcode
+ IBS_Merge,
+ /// \brief Merge multiple ``#include`` blocks together and sort as one.
+ /// Then split into groups based on category priority. See
+ /// ``IncludeCategories``.
+ /// \code
+ /// #include "b.h" into #include "a.h"
+ /// #include "b.h"
+ /// #include <lib/main.h>
+ /// #include "a.h" #include <lib/main.h>
+ /// \endcode
+ IBS_Regroup,
+ };
+
+ /// \brief Dependent on the value, multiple ``#include`` blocks can be sorted
+ /// as one and divided based on category.
+ IncludeBlocksStyle IncludeBlocks;
+
/// \brief See documentation of ``IncludeCategories``.
struct IncludeCategory {
/// \brief The regular expression that this category matches.
@@ -1024,6 +1087,31 @@ struct FormatStyle {
/// \endcode
bool IndentCaseLabels;
+ /// \brief Options for indenting preprocessor directives.
+ enum PPDirectiveIndentStyle {
+ /// Does not indent any directives.
+ /// \code
+ /// #if FOO
+ /// #if BAR
+ /// #include <foo>
+ /// #endif
+ /// #endif
+ /// \endcode
+ PPDIS_None,
+ /// Indents directives after the hash.
+ /// \code
+ /// #if FOO
+ /// # if BAR
+ /// # include <foo>
+ /// # endif
+ /// #endif
+ /// \endcode
+ PPDIS_AfterHash
+ };
+
+ /// \brief The preprocessor directive indenting style to use.
+ PPDirectiveIndentStyle IndentPPDirectives;
+
/// \brief The number of columns to use for indentation.
/// \code
/// IndentWidth: 3
@@ -1273,6 +1361,41 @@ struct FormatStyle {
/// \brief Pointer and reference alignment style.
PointerAlignmentStyle PointerAlignment;
+ /// See documentation of ``RawStringFormats``.
+ struct RawStringFormat {
+ /// \brief The delimiter that this raw string format matches.
+ std::string Delimiter;
+ /// \brief The language of this raw string.
+ LanguageKind Language;
+ /// \brief The style name on which this raw string format is based on.
+ /// If not specified, the raw string format is based on the style that this
+ /// format is based on.
+ std::string BasedOnStyle;
+ bool operator==(const RawStringFormat &Other) const {
+ return Delimiter == Other.Delimiter && Language == Other.Language &&
+ BasedOnStyle == Other.BasedOnStyle;
+ }
+ };
+
+ /// \brief Raw string delimiters denoting that the raw string contents are
+ /// code in a particular language and can be reformatted.
+ ///
+ /// A raw string with a matching delimiter will be reformatted assuming the
+ /// specified language based on a predefined style given by 'BasedOnStyle'.
+ /// If 'BasedOnStyle' is not found, the formatting is based on llvm style.
+ ///
+ /// To configure this in the .clang-format file, use:
+ /// \code{.yaml}
+ /// RawStringFormats:
+ /// - Delimiter: 'pb'
+ /// Language: TextProto
+ /// BasedOnStyle: llvm
+ /// - Delimiter: 'proto'
+ /// Language: TextProto
+ /// BasedOnStyle: google
+ /// \endcode
+ std::vector<RawStringFormat> RawStringFormats;
+
/// \brief If ``true``, clang-format will attempt to re-flow comments.
/// \code
/// false:
@@ -1296,6 +1419,14 @@ struct FormatStyle {
bool SortIncludes;
/// \brief If ``true``, clang-format will sort using declarations.
+ ///
+ /// The order of using declarations is defined as follows:
+ /// Split the strings by "::" and discard any initial empty strings. The last
+ /// element of each list is a non-namespace name; all others are namespace
+ /// names. Sort the lists of names lexicographically, where the sort order of
+ /// individual names is that all non-namespace names come before all namespace
+ /// names, and within those groups, names are in case-insensitive
+ /// lexicographic order.
/// \code
/// false: true:
/// using std::cout; vs. using std::cin;
@@ -1512,8 +1643,10 @@ struct FormatStyle {
R.ExperimentalAutoDetectBinPacking &&
FixNamespaceComments == R.FixNamespaceComments &&
ForEachMacros == R.ForEachMacros &&
+ IncludeBlocks == R.IncludeBlocks &&
IncludeCategories == R.IncludeCategories &&
IndentCaseLabels == R.IndentCaseLabels &&
+ IndentPPDirectives == R.IndentPPDirectives &&
IndentWidth == R.IndentWidth && Language == R.Language &&
IndentWrappedFunctionNames == R.IndentWrappedFunctionNames &&
JavaScriptQuotes == R.JavaScriptQuotes &&
@@ -1537,6 +1670,7 @@ struct FormatStyle {
PenaltyExcessCharacter == R.PenaltyExcessCharacter &&
PenaltyReturnTypeOnItsOwnLine == R.PenaltyReturnTypeOnItsOwnLine &&
PointerAlignment == R.PointerAlignment &&
+ RawStringFormats == R.RawStringFormats &&
SpaceAfterCStyleCast == R.SpaceAfterCStyleCast &&
SpaceAfterTemplateKeyword == R.SpaceAfterTemplateKeyword &&
SpaceBeforeAssignmentOperators == R.SpaceBeforeAssignmentOperators &&
diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h
index 1ac4f07a3549..5d04dcd19119 100644
--- a/include/clang/Frontend/ASTUnit.h
+++ b/include/clang/Frontend/ASTUnit.h
@@ -448,7 +448,7 @@ public:
IntrusiveRefCntPtr<ASTReader> getASTReader() const;
- StringRef getOriginalSourceFileName() {
+ StringRef getOriginalSourceFileName() const {
return OriginalSourceFile;
}
@@ -524,26 +524,26 @@ public:
/// \brief If \p Loc is a loaded location from the preamble, returns
/// the corresponding local location of the main file, otherwise it returns
/// \p Loc.
- SourceLocation mapLocationFromPreamble(SourceLocation Loc);
+ SourceLocation mapLocationFromPreamble(SourceLocation Loc) const;
/// \brief If \p Loc is a local location of the main file but inside the
/// preamble chunk, returns the corresponding loaded location from the
/// preamble, otherwise it returns \p Loc.
- SourceLocation mapLocationToPreamble(SourceLocation Loc);
+ SourceLocation mapLocationToPreamble(SourceLocation Loc) const;
- bool isInPreambleFileID(SourceLocation Loc);
- bool isInMainFileID(SourceLocation Loc);
- SourceLocation getStartOfMainFileID();
- SourceLocation getEndOfPreambleFileID();
+ bool isInPreambleFileID(SourceLocation Loc) const;
+ bool isInMainFileID(SourceLocation Loc) const;
+ SourceLocation getStartOfMainFileID() const;
+ SourceLocation getEndOfPreambleFileID() const;
/// \see mapLocationFromPreamble.
- SourceRange mapRangeFromPreamble(SourceRange R) {
+ SourceRange mapRangeFromPreamble(SourceRange R) const {
return SourceRange(mapLocationFromPreamble(R.getBegin()),
mapLocationFromPreamble(R.getEnd()));
}
/// \see mapLocationToPreamble.
- SourceRange mapRangeToPreamble(SourceRange R) {
+ SourceRange mapRangeToPreamble(SourceRange R) const {
return SourceRange(mapLocationToPreamble(R.getBegin()),
mapLocationToPreamble(R.getEnd()));
}
@@ -607,7 +607,7 @@ public:
/// \brief Returns true if the ASTUnit was constructed from a serialized
/// module file.
- bool isModuleFile();
+ bool isModuleFile() const;
std::unique_ptr<llvm::MemoryBuffer>
getBufferForFile(StringRef Filename, std::string *ErrorStr = nullptr);
diff --git a/include/clang/Frontend/CodeGenOptions.def b/include/clang/Frontend/CodeGenOptions.def
index 4002415adc45..bb91cf5f742b 100644
--- a/include/clang/Frontend/CodeGenOptions.def
+++ b/include/clang/Frontend/CodeGenOptions.def
@@ -76,10 +76,17 @@ CODEGENOPT(ForbidGuardVariables , 1, 0) ///< Issue errors if C++ guard variables
CODEGENOPT(FunctionSections , 1, 0) ///< Set when -ffunction-sections is enabled.
CODEGENOPT(InstrumentFunctions , 1, 0) ///< Set when -finstrument-functions is
///< enabled.
+CODEGENOPT(InstrumentFunctionsAfterInlining , 1, 0) ///< Set when
+ ///< -finstrument-functions-after-inlining is enabled.
+CODEGENOPT(InstrumentFunctionEntryBare , 1, 0) ///< Set when
+ ///< -finstrument-function-entry-bare is enabled.
CODEGENOPT(XRayInstrumentFunctions , 1, 0) ///< Set when -fxray-instrument is
///< enabled.
+///< Set when -fxray-always-emit-customevents is enabled.
+CODEGENOPT(XRayAlwaysEmitCustomEvents , 1, 0)
+
///< Set the minimum number of instructions in a function to determine selective
///< XRay instrumentation.
VALUE_CODEGENOPT(XRayInstructionThreshold , 32, 200)
@@ -110,6 +117,7 @@ CODEGENOPT(EnableSegmentedStacks , 1, 0) ///< Set when -fsplit-stack is enabled.
CODEGENOPT(NoImplicitFloat , 1, 0) ///< Set when -mno-implicit-float is enabled.
CODEGENOPT(NoInfsFPMath , 1, 0) ///< Assume FP arguments, results not +-Inf.
CODEGENOPT(NoSignedZeros , 1, 0) ///< Allow ignoring the signedness of FP zero
+CODEGENOPT(Reassociate , 1, 0) ///< Allow reassociation of FP math ops
CODEGENOPT(ReciprocalMath , 1, 0) ///< Allow FP divisions to be reassociated.
CODEGENOPT(NoTrappingMath , 1, 0) ///< Set when -fno-trapping-math is enabled.
CODEGENOPT(NoNaNsFPMath , 1, 0) ///< Assume FP arguments, results not NaN.
@@ -142,6 +150,7 @@ ENUM_CODEGENOPT(StructReturnConvention, StructReturnConventionKind, 2, SRCK_Defa
CODEGENOPT(RelaxAll , 1, 0) ///< Relax all machine code instructions.
CODEGENOPT(RelaxedAliasing , 1, 0) ///< Set when -fno-strict-aliasing is enabled.
CODEGENOPT(StructPathTBAA , 1, 0) ///< Whether or not to use struct-path TBAA.
+CODEGENOPT(NewStructPathTBAA , 1, 0) ///< Whether or not to use enhanced struct-path TBAA.
CODEGENOPT(SaveTempLabels , 1, 0) ///< Save temporary labels.
CODEGENOPT(SanitizeAddressUseAfterScope , 1, 0) ///< Enable use-after-scope detection
///< in AddressSanitizer
@@ -152,6 +161,10 @@ CODEGENOPT(SanitizeMemoryTrackOrigins, 2, 0) ///< Enable tracking origins in
CODEGENOPT(SanitizeMemoryUseAfterDtor, 1, 0) ///< Enable use-after-delete detection
///< in MemorySanitizer
CODEGENOPT(SanitizeCfiCrossDso, 1, 0) ///< Enable cross-dso support in CFI.
+CODEGENOPT(SanitizeMinimalRuntime, 1, 0) ///< Use "_minimal" sanitizer runtime for
+ ///< diagnostics.
+CODEGENOPT(SanitizeCfiICallGeneralizePointers, 1, 0) ///< Generalize pointer types in
+ ///< CFI icall function signatures
CODEGENOPT(SanitizeCoverageType, 2, 0) ///< Type of sanitizer coverage
///< instrumentation.
CODEGENOPT(SanitizeCoverageIndirectCalls, 1, 0) ///< Enable sanitizer coverage
@@ -171,10 +184,13 @@ CODEGENOPT(SanitizeCoverageTracePC, 1, 0) ///< Enable PC tracing
CODEGENOPT(SanitizeCoverageTracePCGuard, 1, 0) ///< Enable PC tracing with guard
///< in sanitizer coverage.
CODEGENOPT(SanitizeCoverageInline8bitCounters, 1, 0) ///< Use inline 8bit counters.
+CODEGENOPT(SanitizeCoveragePCTable, 1, 0) ///< Create a PC Table.
CODEGENOPT(SanitizeCoverageNoPrune, 1, 0) ///< Disable coverage pruning.
+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(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
CODEGENOPT(TimePasses , 1, 0) ///< Set when -ftime-report is enabled.
@@ -185,6 +201,7 @@ CODEGENOPT(UnsafeFPMath , 1, 0) ///< Allow unsafe floating point optzns.
CODEGENOPT(UnwindTables , 1, 0) ///< Emit unwind tables.
CODEGENOPT(VectorizeLoop , 1, 0) ///< Run loop vectorizer.
CODEGENOPT(VectorizeSLP , 1, 0) ///< Run SLP vectorizer.
+CODEGENOPT(ProfileSampleAccurate, 1, 0) ///< Sample profile is accurate.
/// Attempt to use register sized accesses to bit-fields in structures, when
/// possible.
@@ -214,6 +231,10 @@ CODEGENOPT(EnableSplitDwarf, 1, 0) ///< Whether to enable split DWARF
CODEGENOPT(SplitDwarfInlining, 1, 1) ///< Whether to include inlining info in the
///< skeleton CU to allow for symbolication
///< of inline stack frames without .dwo files.
+CODEGENOPT(DebugFwdTemplateParams, 1, 0) ///< Whether to emit complete
+ ///< template parameter descriptions in
+ ///< forward declarations (versus just
+ ///< including them in the name).
CODEGENOPT(EmitLLVMUseLists, 1, 0) ///< Control whether to serialize use-lists.
@@ -282,6 +303,11 @@ CODEGENOPT(DebugInfoForProfiling, 1, 0)
/// Whether 3-component vector type is preserved.
CODEGENOPT(PreserveVec3Type, 1, 0)
+/// Whether to emit .debug_gnu_pubnames section instead of .debug_pubnames.
+CODEGENOPT(GnuPubnames, 1, 0)
+
+CODEGENOPT(NoPLT, 1, 0)
+
#undef CODEGENOPT
#undef ENUM_CODEGENOPT
#undef VALUE_CODEGENOPT
diff --git a/include/clang/Frontend/CodeGenOptions.h b/include/clang/Frontend/CodeGenOptions.h
index 71730a21dbe2..6b8d2b935fdd 100644
--- a/include/clang/Frontend/CodeGenOptions.h
+++ b/include/clang/Frontend/CodeGenOptions.h
@@ -251,6 +251,13 @@ public:
/// \brief A list of all -fno-builtin-* function names (e.g., memset).
std::vector<std::string> NoBuiltinFuncs;
+ std::vector<std::string> Reciprocals;
+
+ /// The preferred width for auto-vectorization transforms. This is intended to
+ /// override default transforms based on the width of the architected vector
+ /// registers.
+ std::string PreferVectorWidth;
+
public:
// Define accessors/mutators for code generation options of enumeration type.
#define CODEGENOPT(Name, Bits, Default)
diff --git a/include/clang/Frontend/CommandLineSourceLoc.h b/include/clang/Frontend/CommandLineSourceLoc.h
index a78c96d23afa..f5c1e1a8a67d 100644
--- a/include/clang/Frontend/CommandLineSourceLoc.h
+++ b/include/clang/Frontend/CommandLineSourceLoc.h
@@ -51,6 +51,52 @@ public:
}
};
+/// A source range that has been parsed on the command line.
+struct ParsedSourceRange {
+ std::string FileName;
+ /// The starting location of the range. The first element is the line and
+ /// the second element is the column.
+ std::pair<unsigned, unsigned> Begin;
+ /// The ending location of the range. The first element is the line and the
+ /// second element is the column.
+ std::pair<unsigned, unsigned> End;
+
+ /// Returns a parsed source range from a string or None if the string is
+ /// invalid.
+ ///
+ /// These source string has the following format:
+ ///
+ /// file:start_line:start_column[-end_line:end_column]
+ ///
+ /// If the end line and column are omitted, the starting line and columns
+ /// are used as the end values.
+ static Optional<ParsedSourceRange> fromString(StringRef Str) {
+ std::pair<StringRef, StringRef> RangeSplit = Str.rsplit('-');
+ unsigned EndLine, EndColumn;
+ bool HasEndLoc = false;
+ if (!RangeSplit.second.empty()) {
+ std::pair<StringRef, StringRef> Split = RangeSplit.second.rsplit(':');
+ if (Split.first.getAsInteger(10, EndLine) ||
+ Split.second.getAsInteger(10, EndColumn)) {
+ // The string does not end in end_line:end_column, so the '-'
+ // probably belongs to the filename which menas the whole
+ // string should be parsed.
+ RangeSplit.first = Str;
+ } else
+ HasEndLoc = true;
+ }
+ auto Begin = ParsedSourceLocation::FromString(RangeSplit.first);
+ if (Begin.FileName.empty())
+ return None;
+ if (!HasEndLoc) {
+ EndLine = Begin.Line;
+ EndColumn = Begin.Column;
+ }
+ return ParsedSourceRange{std::move(Begin.FileName),
+ {Begin.Line, Begin.Column},
+ {EndLine, EndColumn}};
+ }
+};
}
namespace llvm {
diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h
index 5b5c75298a31..90a9501475b5 100644
--- a/include/clang/Frontend/CompilerInstance.h
+++ b/include/clang/Frontend/CompilerInstance.h
@@ -640,7 +640,9 @@ public:
const CodeGenOptions *CodeGenOpts = nullptr);
/// Create the file manager and replace any existing one with it.
- void createFileManager();
+ ///
+ /// \return The new file manager on success, or null on failure.
+ FileManager *createFileManager();
/// Create the source manager and replace any existing one with it.
void createSourceManager(FileManager &FileMgr);
diff --git a/include/clang/Frontend/FrontendActions.h b/include/clang/Frontend/FrontendActions.h
index c45aeaa208c8..fa1529a3d65d 100644
--- a/include/clang/Frontend/FrontendActions.h
+++ b/include/clang/Frontend/FrontendActions.h
@@ -86,10 +86,15 @@ public:
/// \brief Compute the AST consumer arguments that will be used to
/// create the PCHGenerator instance returned by CreateASTConsumer.
///
- /// \returns true if an error occurred, false otherwise.
- static std::unique_ptr<raw_pwrite_stream>
- ComputeASTConsumerArguments(CompilerInstance &CI, StringRef InFile,
- std::string &Sysroot, std::string &OutputFile);
+ /// \returns false if an error occurred, true otherwise.
+ static bool ComputeASTConsumerArguments(CompilerInstance &CI,
+ std::string &Sysroot);
+
+ /// \brief Creates file to write the PCH into and returns a stream to write it
+ /// into. On error, returns null.
+ static std::unique_ptr<llvm::raw_pwrite_stream>
+ CreateOutputFile(CompilerInstance &CI, StringRef InFile,
+ std::string &OutputFile);
bool BeginSourceFileAction(CompilerInstance &CI) override;
};
diff --git a/include/clang/Frontend/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h
index e757a7e397e3..5192a3774cc1 100644
--- a/include/clang/Frontend/FrontendOptions.h
+++ b/include/clang/Frontend/FrontendOptions.h
@@ -128,21 +128,24 @@ class FrontendInputFile {
/// \brief The file name, or "-" to read from standard input.
std::string File;
- llvm::MemoryBuffer *Buffer;
+ /// The input, if it comes from a buffer rather than a file. This object
+ /// does not own the buffer, and the caller is responsible for ensuring
+ /// that it outlives any users.
+ llvm::MemoryBuffer *Buffer = nullptr;
/// \brief The kind of input, e.g., C source, AST file, LLVM IR.
InputKind Kind;
/// \brief Whether we're dealing with a 'system' input (vs. a 'user' input).
- bool IsSystem;
+ bool IsSystem = false;
public:
- FrontendInputFile() : Buffer(nullptr), Kind(), IsSystem(false) { }
+ FrontendInputFile() { }
FrontendInputFile(StringRef File, InputKind Kind, bool IsSystem = false)
- : File(File.str()), Buffer(nullptr), Kind(Kind), IsSystem(IsSystem) { }
- FrontendInputFile(llvm::MemoryBuffer *buffer, InputKind Kind,
+ : File(File.str()), Kind(Kind), IsSystem(IsSystem) { }
+ FrontendInputFile(llvm::MemoryBuffer *Buffer, InputKind Kind,
bool IsSystem = false)
- : Buffer(buffer), Kind(Kind), IsSystem(IsSystem) { }
+ : Buffer(Buffer), Kind(Kind), IsSystem(IsSystem) { }
InputKind getKind() const { return Kind; }
bool isSystem() const { return IsSystem; }
diff --git a/include/clang/Frontend/LangStandard.h b/include/clang/Frontend/LangStandard.h
index 6731e08bcae8..83e452d884b6 100644
--- a/include/clang/Frontend/LangStandard.h
+++ b/include/clang/Frontend/LangStandard.h
@@ -22,16 +22,17 @@ enum LangFeatures {
LineComment = (1 << 0),
C99 = (1 << 1),
C11 = (1 << 2),
- CPlusPlus = (1 << 3),
- CPlusPlus11 = (1 << 4),
- CPlusPlus14 = (1 << 5),
- CPlusPlus1z = (1 << 6),
- CPlusPlus2a = (1 << 7),
- Digraphs = (1 << 8),
- GNUMode = (1 << 9),
- HexFloat = (1 << 10),
- ImplicitInt = (1 << 11),
- OpenCL = (1 << 12)
+ C17 = (1 << 3),
+ CPlusPlus = (1 << 4),
+ CPlusPlus11 = (1 << 5),
+ CPlusPlus14 = (1 << 6),
+ CPlusPlus17 = (1 << 7),
+ CPlusPlus2a = (1 << 8),
+ Digraphs = (1 << 9),
+ GNUMode = (1 << 10),
+ HexFloat = (1 << 11),
+ ImplicitInt = (1 << 12),
+ OpenCL = (1 << 13)
};
}
@@ -70,6 +71,9 @@ public:
/// isC11 - Language is a superset of C11.
bool isC11() const { return Flags & frontend::C11; }
+ /// isC17 - Language is a superset of C17.
+ bool isC17() const { return Flags & frontend::C17; }
+
/// isCPlusPlus - Language is a C++ variant.
bool isCPlusPlus() const { return Flags & frontend::CPlusPlus; }
@@ -79,8 +83,8 @@ public:
/// isCPlusPlus14 - Language is a C++14 variant (or later).
bool isCPlusPlus14() const { return Flags & frontend::CPlusPlus14; }
- /// isCPlusPlus1z - Language is a C++17 variant (or later).
- bool isCPlusPlus1z() const { return Flags & frontend::CPlusPlus1z; }
+ /// isCPlusPlus17 - Language is a C++17 variant (or later).
+ bool isCPlusPlus17() const { return Flags & frontend::CPlusPlus17; }
/// isCPlusPlus2a - Language is a post-C++17 variant (or later).
bool isCPlusPlus2a() const { return Flags & frontend::CPlusPlus2a; }
diff --git a/include/clang/Frontend/LangStandards.def b/include/clang/Frontend/LangStandards.def
index a019d6392214..e7a081dc2aa7 100644
--- a/include/clang/Frontend/LangStandards.def
+++ b/include/clang/Frontend/LangStandards.def
@@ -77,6 +77,15 @@ LANGSTANDARD(gnu11, "gnu11",
LineComment | C99 | C11 | Digraphs | GNUMode | HexFloat)
LANGSTANDARD_ALIAS_DEPR(gnu11, "gnu1x")
+// C17 modes
+LANGSTANDARD(c17, "c17",
+ C, "ISO C 2017",
+ LineComment | C99 | C11 | C17 | Digraphs | HexFloat)
+LANGSTANDARD_ALIAS(c17, "iso9899:2017")
+LANGSTANDARD(gnu17, "gnu17",
+ C, "ISO C 2017 with GNU extensions",
+ LineComment | C99 | C11 | C17 | Digraphs | GNUMode | HexFloat)
+
// C++ modes
LANGSTANDARD(cxx98, "c++98",
CXX, "ISO C++ 1998 with amendments",
@@ -111,24 +120,24 @@ LANGSTANDARD_ALIAS_DEPR(gnucxx14, "gnu++1y")
LANGSTANDARD(cxx17, "c++17",
CXX, "ISO C++ 2017 with amendments",
- LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus1z |
+ LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 |
Digraphs | HexFloat)
LANGSTANDARD_ALIAS_DEPR(cxx17, "c++1z")
LANGSTANDARD(gnucxx17, "gnu++17",
CXX, "ISO C++ 2017 with amendments and GNU extensions",
- LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus1z |
+ LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 |
Digraphs | HexFloat | GNUMode)
LANGSTANDARD_ALIAS_DEPR(gnucxx17, "gnu++1z")
LANGSTANDARD(cxx2a, "c++2a",
CXX, "Working draft for ISO C++ 2020",
- LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus1z |
+ LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 |
CPlusPlus2a | Digraphs | HexFloat)
LANGSTANDARD(gnucxx2a, "gnu++2a",
CXX, "Working draft for ISO C++ 2020 with GNU extensions",
- LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus1z |
+ LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 |
CPlusPlus2a | Digraphs | HexFloat | GNUMode)
// OpenCL
diff --git a/include/clang/Frontend/PrecompiledPreamble.h b/include/clang/Frontend/PrecompiledPreamble.h
index 8307392e7feb..64342b1dffa8 100644
--- a/include/clang/Frontend/PrecompiledPreamble.h
+++ b/include/clang/Frontend/PrecompiledPreamble.h
@@ -17,6 +17,7 @@
#include "clang/Lex/Lexer.h"
#include "clang/Lex/Preprocessor.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/Support/AlignOf.h"
#include "llvm/Support/MD5.h"
#include <memory>
#include <system_error>
@@ -36,21 +37,6 @@ class CompilerInvocation;
class DeclGroupRef;
class PCHContainerOperations;
-/// A size of the preamble and a flag required by
-/// PreprocessorOptions::PrecompiledPreambleBytes.
-struct PreambleBounds {
- PreambleBounds(unsigned Size, bool PreambleEndsAtStartOfLine)
- : Size(Size), PreambleEndsAtStartOfLine(PreambleEndsAtStartOfLine) {}
-
- /// \brief Size of the preamble in bytes.
- unsigned Size;
- /// \brief Whether the preamble ends at the start of a new line.
- ///
- /// Used to inform the lexer as to whether it's starting at the beginning of
- /// a line after skipping the preamble.
- bool PreambleEndsAtStartOfLine;
-};
-
/// \brief Runs lexer to compute suggested preamble bounds.
PreambleBounds ComputePreambleBounds(const LangOptions &LangOpts,
llvm::MemoryBuffer *Buffer,
@@ -62,7 +48,7 @@ class PreambleCallbacks;
/// reuse the PCH for the subsequent runs. Use BuildPreamble to create PCH and
/// CanReusePreamble + AddImplicitPreamble to make use of it.
class PrecompiledPreamble {
- class TempPCHFile;
+ class PCHStorage;
struct PreambleFileHash;
public:
@@ -85,6 +71,9 @@ public:
///
/// \param PCHContainerOps An instance of PCHContainerOperations.
///
+ /// \param StoreInMemory Store PCH in memory. If false, PCH will be stored in
+ /// a temporary file.
+ ///
/// \param Callbacks A set of callbacks to be executed when building
/// the preamble.
static llvm::ErrorOr<PrecompiledPreamble>
@@ -92,12 +81,12 @@ public:
const llvm::MemoryBuffer *MainFileBuffer, PreambleBounds Bounds,
DiagnosticsEngine &Diagnostics, IntrusiveRefCntPtr<vfs::FileSystem> VFS,
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
- PreambleCallbacks &Callbacks);
+ bool StoreInMemory, PreambleCallbacks &Callbacks);
PrecompiledPreamble(PrecompiledPreamble &&) = default;
PrecompiledPreamble &operator=(PrecompiledPreamble &&) = default;
- /// PreambleBounds used to build the preamble
+ /// PreambleBounds used to build the preamble.
PreambleBounds getBounds() const;
/// Check whether PrecompiledPreamble can be reused for the new contents(\p
@@ -107,12 +96,18 @@ public:
vfs::FileSystem *VFS) const;
/// Changes options inside \p CI to use PCH from this preamble. Also remaps
- /// main file to \p MainFileBuffer.
+ /// main file to \p MainFileBuffer and updates \p VFS to ensure the preamble
+ /// is accessible.
+ /// For in-memory preambles, PrecompiledPreamble instance continues to own
+ /// the MemoryBuffer with the Preamble after this method returns. The caller
+ /// is reponsible 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,
llvm::MemoryBuffer *MainFileBuffer) const;
private:
- PrecompiledPreamble(TempPCHFile PCHFile, std::vector<char> PreambleBytes,
+ PrecompiledPreamble(PCHStorage Storage, std::vector<char> PreambleBytes,
bool PreambleEndsAtStartOfLine,
llvm::StringMap<PreambleFileHash> FilesInPreamble);
@@ -154,6 +149,44 @@ private:
llvm::Optional<std::string> FilePath;
};
+ class InMemoryPreamble {
+ public:
+ std::string Data;
+ };
+
+ class PCHStorage {
+ public:
+ enum class Kind { Empty, InMemory, TempFile };
+
+ PCHStorage() = default;
+ PCHStorage(TempPCHFile File);
+ PCHStorage(InMemoryPreamble Memory);
+
+ PCHStorage(const PCHStorage &) = delete;
+ PCHStorage &operator=(const PCHStorage &) = delete;
+
+ PCHStorage(PCHStorage &&Other);
+ PCHStorage &operator=(PCHStorage &&Other);
+
+ ~PCHStorage();
+
+ Kind getKind() const;
+
+ TempPCHFile &asFile();
+ const TempPCHFile &asFile() const;
+
+ InMemoryPreamble &asMemory();
+ const InMemoryPreamble &asMemory() const;
+
+ private:
+ void destroy();
+ void setEmpty();
+
+ private:
+ Kind StorageKind = Kind::Empty;
+ llvm::AlignedCharArrayUnion<TempPCHFile, InMemoryPreamble> Storage = {};
+ };
+
/// Data used to determine if a file used in the preamble has been changed.
struct PreambleFileHash {
/// All files have size set.
@@ -183,8 +216,15 @@ private:
}
};
- /// Manages the lifetime of temporary file that stores a PCH.
- TempPCHFile PCHFile;
+ /// 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);
+
+ /// Manages the memory buffer or temporary file that stores the PCH.
+ PCHStorage Storage;
/// Keeps track of the files that were used when computing the
/// preamble, with both their buffer size and their modification time.
///
@@ -215,11 +255,9 @@ public:
/// NOTE: To allow more flexibility a custom ASTConsumer could probably be
/// used instead, but having only this method allows a simpler API.
virtual void HandleTopLevelDecl(DeclGroupRef DG);
- /// Called for each macro defined in the Preamble.
- /// NOTE: To allow more flexibility a custom PPCallbacks could probably be
- /// used instead, but having only this method allows a simpler API.
- virtual void HandleMacroDefined(const Token &MacroNameTok,
- const MacroDirective *MD);
+ /// Creates wrapper class for PPCallbacks so we can also process information
+ /// about includes that are inside of a preamble
+ virtual std::unique_ptr<PPCallbacks> createPPCallbacks();
};
enum class BuildPreambleError {
diff --git a/include/clang/Frontend/TextDiagnosticBuffer.h b/include/clang/Frontend/TextDiagnosticBuffer.h
index 3bcf824455e2..23f168e2232d 100644
--- a/include/clang/Frontend/TextDiagnosticBuffer.h
+++ b/include/clang/Frontend/TextDiagnosticBuffer.h
@@ -29,6 +29,11 @@ public:
typedef DiagList::const_iterator const_iterator;
private:
DiagList Errors, Warnings, Remarks, Notes;
+ /// All - All diagnostics in the order in which they were generated. That
+ /// order likely doesn't correspond to user input order, but it at least
+ /// keeps notes in the right places. Each pair in the vector is a diagnostic
+ /// level and an index into the corresponding DiagList above.
+ std::vector<std::pair<DiagnosticsEngine::Level, size_t>> All;
public:
const_iterator err_begin() const { return Errors.begin(); }
const_iterator err_end() const { return Errors.end(); }
diff --git a/include/clang/Frontend/VerifyDiagnosticConsumer.h b/include/clang/Frontend/VerifyDiagnosticConsumer.h
index 475f07f9dc06..8d71fb98b0bb 100644
--- a/include/clang/Frontend/VerifyDiagnosticConsumer.h
+++ b/include/clang/Frontend/VerifyDiagnosticConsumer.h
@@ -176,7 +176,8 @@ public:
: DirectiveLoc(DirectiveLoc), DiagnosticLoc(DiagnosticLoc),
Text(Text), Min(Min), Max(Max), MatchAnyLine(MatchAnyLine) {
assert(!DirectiveLoc.isInvalid() && "DirectiveLoc is invalid!");
- assert(!DiagnosticLoc.isInvalid() && "DiagnosticLoc is invalid!");
+ assert((!DiagnosticLoc.isInvalid() || MatchAnyLine) &&
+ "DiagnosticLoc is invalid!");
}
private:
diff --git a/include/clang/Index/IndexDataConsumer.h b/include/clang/Index/IndexDataConsumer.h
index 315437048345..080f4cb4d097 100644
--- a/include/clang/Index/IndexDataConsumer.h
+++ b/include/clang/Index/IndexDataConsumer.h
@@ -11,6 +11,7 @@
#define LLVM_CLANG_INDEX_INDEXDATACONSUMER_H
#include "clang/Index/IndexSymbol.h"
+#include "clang/Lex/Preprocessor.h"
namespace clang {
class ASTContext;
@@ -36,6 +37,8 @@ public:
virtual void initialize(ASTContext &Ctx) {}
+ virtual void setPreprocessor(std::shared_ptr<Preprocessor> PP) {}
+
/// \returns true to continue indexing, or false to abort.
virtual bool handleDeclOccurence(const Decl *D, SymbolRoleSet Roles,
ArrayRef<SymbolRelation> Relations,
diff --git a/include/clang/Index/IndexSymbol.h b/include/clang/Index/IndexSymbol.h
index abb132f9e4ce..ae591364f229 100644
--- a/include/clang/Index/IndexSymbol.h
+++ b/include/clang/Index/IndexSymbol.h
@@ -53,6 +53,7 @@ enum class SymbolKind : uint8_t {
ConversionFunction,
Parameter,
+ Using,
};
enum class SymbolLanguage {
@@ -69,6 +70,8 @@ enum class SymbolSubKind {
CXXMoveConstructor,
AccessorGetter,
AccessorSetter,
+ UsingTypename,
+ UsingValue,
};
/// Set of properties that provide additional info about a symbol.
diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h
index 1b7f80c87ff1..6b9dbfcd1e93 100644
--- a/include/clang/Lex/HeaderSearch.h
+++ b/include/clang/Lex/HeaderSearch.h
@@ -1,4 +1,4 @@
-//===--- HeaderSearch.h - Resolve Header File Locations ---------*- C++ -*-===//
+//===- HeaderSearch.h - Resolve Header File Locations -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,25 +14,37 @@
#ifndef LLVM_CLANG_LEX_HEADERSEARCH_H
#define LLVM_CLANG_LEX_HEADERSEARCH_H
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
#include "clang/Lex/DirectoryLookup.h"
#include "clang/Lex/ModuleMap.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringSet.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
+#include <cassert>
+#include <cstddef>
#include <memory>
+#include <string>
+#include <utility>
#include <vector>
namespace clang {
-
-class DiagnosticsEngine;
+
+class DiagnosticsEngine;
+class DirectoryEntry;
class ExternalPreprocessorSource;
class FileEntry;
class FileManager;
+class HeaderMap;
class HeaderSearchOptions;
class IdentifierInfo;
+class LangOptions;
+class Module;
class Preprocessor;
+class TargetInfo;
/// \brief The preprocessor keeps track of this information for each
/// file that is \#included.
@@ -76,14 +88,14 @@ struct HeaderFileInfo {
unsigned IsValid : 1;
/// \brief The number of times the file has been included already.
- unsigned short NumIncludes;
+ unsigned short NumIncludes = 0;
/// \brief The ID number of the controlling macro.
///
/// This ID number will be non-zero when there is a controlling
/// macro whose IdentifierInfo may not yet have been loaded from
/// external storage.
- unsigned ControllingMacroID;
+ unsigned ControllingMacroID = 0;
/// If this file has a \#ifndef XXX (or equivalent) guard that
/// protects the entire contents of the file, this is the identifier
@@ -93,17 +105,16 @@ struct HeaderFileInfo {
/// the controlling macro of this header, since
/// getControllingMacro() is able to load a controlling macro from
/// external storage.
- const IdentifierInfo *ControllingMacro;
+ const IdentifierInfo *ControllingMacro = nullptr;
/// \brief If this header came from a framework include, this is the name
/// of the framework.
StringRef Framework;
HeaderFileInfo()
- : isImport(false), isPragmaOnce(false), DirInfo(SrcMgr::C_User),
- External(false), isModuleHeader(false), isCompilingModuleHeader(false),
- Resolved(false), IndexHeaderMapHeader(false), IsValid(0),
- NumIncludes(0), ControllingMacroID(0), ControllingMacro(nullptr) {}
+ : isImport(false), isPragmaOnce(false), DirInfo(SrcMgr::C_User),
+ External(false), isModuleHeader(false), isCompilingModuleHeader(false),
+ Resolved(false), IndexHeaderMapHeader(false), IsValid(false) {}
/// \brief Retrieve the controlling macro for this header file, if
/// any.
@@ -135,6 +146,8 @@ public:
/// \brief Encapsulates the information needed to find the file referenced
/// by a \#include or \#include_next, (sub-)framework lookup, etc.
class HeaderSearch {
+ friend class DirectoryLookup;
+
/// This structure is used to record entries in our framework cache.
struct FrameworkCacheEntry {
/// The directory entry which should be used for the cached framework.
@@ -151,6 +164,7 @@ class HeaderSearch {
DiagnosticsEngine &Diags;
FileManager &FileMgr;
+
/// \#include search path information. Requests for \#include "x" search the
/// directory of the \#including file first, then each directory in SearchDirs
/// consecutively. Requests for <x> search the current dir first, then each
@@ -158,9 +172,9 @@ class HeaderSearch {
/// NoCurDirSearch is true, then the check for the file in the current
/// directory is suppressed.
std::vector<DirectoryLookup> SearchDirs;
- unsigned AngledDirIdx;
- unsigned SystemDirIdx;
- bool NoCurDirSearch;
+ unsigned AngledDirIdx = 0;
+ unsigned SystemDirIdx = 0;
+ bool NoCurDirSearch = false;
/// \brief \#include prefixes for which the 'system header' property is
/// overridden.
@@ -168,7 +182,7 @@ class HeaderSearch {
/// For a \#include "x" or \#include \<x> directive, the last string in this
/// list which is a prefix of 'x' determines whether the file is treated as
/// a system header.
- std::vector<std::pair<std::string, bool> > SystemHeaderPrefixes;
+ std::vector<std::pair<std::string, bool>> SystemHeaderPrefixes;
/// \brief The path to the module cache.
std::string ModuleCachePath;
@@ -182,15 +196,17 @@ class HeaderSearch {
/// Starting index in SearchDirs that the cached search was performed from.
/// If there is a hit and this value doesn't match the current query, the
/// cache has to be ignored.
- unsigned StartIdx;
+ unsigned StartIdx = 0;
+
/// The entry in SearchDirs that satisfied the query.
- unsigned HitIdx;
+ unsigned HitIdx = 0;
+
/// This is non-null if the original filename was mapped to a framework
/// include via a headermap.
- const char *MappedName;
+ const char *MappedName = nullptr;
/// Default constructor -- Initialize all members with zero.
- LookupFileCacheInfo(): StartIdx(0), HitIdx(0), MappedName(nullptr) {}
+ LookupFileCacheInfo() = default;
void reset(unsigned StartIdx) {
this->StartIdx = StartIdx;
@@ -206,13 +222,13 @@ class HeaderSearch {
/// IncludeAliases - 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.
- typedef llvm::StringMap<std::string, llvm::BumpPtrAllocator>
- IncludeAliasMap;
+ 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;
+ std::vector<std::pair<const FileEntry *, const HeaderMap *>> HeaderMaps;
/// \brief The mapping between modules and headers.
mutable ModuleMap ModMap;
@@ -231,26 +247,23 @@ class HeaderSearch {
/// \brief Entity used to resolve the identifier IDs of controlling
/// macros into IdentifierInfo pointers, and keep the identifire up to date,
/// as needed.
- ExternalPreprocessorSource *ExternalLookup;
+ ExternalPreprocessorSource *ExternalLookup = nullptr;
/// \brief Entity used to look up stored header file information.
- ExternalHeaderFileInfoSource *ExternalSource;
+ ExternalHeaderFileInfoSource *ExternalSource = nullptr;
// Various statistics we track for performance analysis.
- unsigned NumIncluded;
- unsigned NumMultiIncludeFileOptzn;
- unsigned NumFrameworkLookups, NumSubFrameworkLookups;
+ unsigned NumIncluded = 0;
+ unsigned NumMultiIncludeFileOptzn = 0;
+ unsigned NumFrameworkLookups = 0;
+ unsigned NumSubFrameworkLookups = 0;
- // HeaderSearch doesn't support default or copy construction.
- HeaderSearch(const HeaderSearch&) = delete;
- void operator=(const HeaderSearch&) = delete;
-
- friend class DirectoryLookup;
-
public:
HeaderSearch(std::shared_ptr<HeaderSearchOptions> HSOpts,
SourceManager &SourceMgr, DiagnosticsEngine &Diags,
const LangOptions &LangOpts, const TargetInfo *Target);
+ HeaderSearch(const HeaderSearch &) = delete;
+ HeaderSearch &operator=(const HeaderSearch &) = delete;
~HeaderSearch();
/// \brief Retrieve the header-search options with which this header search
@@ -282,7 +295,7 @@ public:
}
/// \brief Set the list of system header prefixes.
- void SetSystemHeaderPrefixes(ArrayRef<std::pair<std::string, bool> > P) {
+ void SetSystemHeaderPrefixes(ArrayRef<std::pair<std::string, bool>> P) {
SystemHeaderPrefixes.assign(P.begin(), P.end());
}
@@ -310,7 +323,7 @@ public:
IncludeAliasMap::const_iterator Iter = IncludeAliases->find(Source);
if (Iter != IncludeAliases->end())
return Iter->second;
- return StringRef();
+ return {};
}
/// \brief Set the path to the module cache.
@@ -471,29 +484,40 @@ public:
/// \brief Get filenames for all registered header maps.
void getHeaderMapFileNames(SmallVectorImpl<std::string> &Names) const;
- /// \brief Retrieve the name of the module file that should be used to
- /// load the given module.
+ /// \brief Retrieve the name of the cached module file that should be used
+ /// to load the given module.
///
/// \param Module The module whose module file name will be returned.
///
/// \returns The name of the module file that corresponds to this module,
/// or an empty string if this module does not correspond to any module file.
- std::string getModuleFileName(Module *Module);
+ std::string getCachedModuleFileName(Module *Module);
+
+ /// \brief Retrieve the name of the prebuilt module file that should be used
+ /// to load a module with the given name.
+ ///
+ /// \param ModuleName The module whose module file name will be returned.
+ ///
+ /// \param FileMapOnly If true, then only look in the explicit module name
+ // to file name map and skip the directory search.
+ ///
+ /// \returns The name of the module file that corresponds to this module,
+ /// or an empty string if this module does not correspond to any module file.
+ std::string getPrebuiltModuleFileName(StringRef ModuleName,
+ bool FileMapOnly = false);
- /// \brief Retrieve the name of the module file that should be used to
- /// load a module with the given name.
+ /// \brief Retrieve the name of the (to-be-)cached module file that should
+ /// be used to load a module with the given name.
///
/// \param ModuleName The module whose module file name will be returned.
///
/// \param ModuleMapPath A path that when combined with \c ModuleName
/// uniquely identifies this module. See Module::ModuleMap.
///
- /// \param UsePrebuiltPath Whether we should use the prebuilt module path.
- ///
/// \returns The name of the module file that corresponds to this module,
/// or an empty string if this module does not correspond to any module file.
- std::string getModuleFileName(StringRef ModuleName, StringRef ModuleMapPath,
- bool UsePrebuiltPath);
+ std::string getCachedModuleFileName(StringRef ModuleName,
+ StringRef ModuleMapPath);
/// \brief Lookup a module Search for a module with the given name.
///
@@ -560,7 +584,6 @@ public:
void loadTopLevelSystemModules();
private:
-
/// \brief Lookup a module with the given module name and search-name.
///
/// \param ModuleName The name of the module we're looking for.
@@ -640,7 +663,8 @@ public:
bool WantExternal = true) const;
// Used by external tools
- typedef std::vector<DirectoryLookup>::const_iterator search_dir_iterator;
+ using search_dir_iterator = std::vector<DirectoryLookup>::const_iterator;
+
search_dir_iterator search_dir_begin() const { return SearchDirs.begin(); }
search_dir_iterator search_dir_end() const { return SearchDirs.end(); }
unsigned search_dir_size() const { return SearchDirs.size(); }
@@ -648,6 +672,7 @@ public:
search_dir_iterator quoted_dir_begin() const {
return SearchDirs.begin();
}
+
search_dir_iterator quoted_dir_end() const {
return SearchDirs.begin() + AngledDirIdx;
}
@@ -655,6 +680,7 @@ public:
search_dir_iterator angled_dir_begin() const {
return SearchDirs.begin() + AngledDirIdx;
}
+
search_dir_iterator angled_dir_end() const {
return SearchDirs.begin() + SystemDirIdx;
}
@@ -662,6 +688,7 @@ public:
search_dir_iterator system_dir_begin() const {
return SearchDirs.begin() + SystemDirIdx;
}
+
search_dir_iterator system_dir_end() const { return SearchDirs.end(); }
/// \brief Retrieve a uniqued framework name.
@@ -684,10 +711,13 @@ private:
enum LoadModuleMapResult {
/// \brief The module map file had already been loaded.
LMM_AlreadyLoaded,
+
/// \brief The module map file was loaded by this invocation.
LMM_NewlyLoaded,
+
/// \brief There is was directory with the given name.
LMM_NoDirectory,
+
/// \brief There was either no module map file or the module map file was
/// invalid.
LMM_InvalidModuleMap
@@ -723,6 +753,6 @@ private:
bool IsSystem, bool IsFramework);
};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_LEX_HEADERSEARCH_H
diff --git a/include/clang/Lex/HeaderSearchOptions.h b/include/clang/Lex/HeaderSearchOptions.h
index ca3a84e75e18..937ad9863db3 100644
--- a/include/clang/Lex/HeaderSearchOptions.h
+++ b/include/clang/Lex/HeaderSearchOptions.h
@@ -1,4 +1,4 @@
-//===--- HeaderSearchOptions.h ----------------------------------*- C++ -*-===//
+//===- HeaderSearchOptions.h ------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,35 +12,55 @@
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/CachedHashString.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/StringRef.h"
+#include <cstdint>
#include <string>
#include <vector>
+#include <map>
namespace clang {
namespace frontend {
- /// IncludeDirGroup - Identifies the group an include Entry belongs to,
- /// representing its relative positive in the search list.
- /// \#include directives whose paths are enclosed by string quotes ("")
- /// start searching at the Quoted group (specified by '-iquote'),
- /// then search the Angled group, then the System group, etc.
- enum IncludeDirGroup {
- Quoted = 0, ///< '\#include ""' paths, added by 'gcc -iquote'.
- Angled, ///< Paths for '\#include <>' added by '-I'.
- IndexHeaderMap, ///< Like Angled, but marks header maps used when
- /// building frameworks.
- System, ///< Like Angled, but marks system directories.
- ExternCSystem, ///< Like System, but headers are implicitly wrapped in
- /// extern "C".
- CSystem, ///< Like System, but only used for C.
- CXXSystem, ///< Like System, but only used for C++.
- ObjCSystem, ///< Like System, but only used for ObjC.
- ObjCXXSystem, ///< Like System, but only used for ObjC++.
- After ///< Like System, but searched after the system directories.
- };
-}
+
+/// IncludeDirGroup - Identifies the group an include Entry belongs to,
+/// representing its relative positive in the search list.
+/// \#include directives whose paths are enclosed by string quotes ("")
+/// start searching at the Quoted group (specified by '-iquote'),
+/// then search the Angled group, then the System group, etc.
+enum IncludeDirGroup {
+ /// '\#include ""' paths, added by 'gcc -iquote'.
+ Quoted = 0,
+
+ /// Paths for '\#include <>' added by '-I'.
+ Angled,
+
+ /// Like Angled, but marks header maps used when building frameworks.
+ IndexHeaderMap,
+
+ /// Like Angled, but marks system directories.
+ System,
+
+ /// Like System, but headers are implicitly wrapped in extern "C".
+ ExternCSystem,
+
+ /// Like System, but only used for C.
+ CSystem,
+
+ /// Like System, but only used for C++.
+ CXXSystem,
+
+ /// Like System, but only used for ObjC.
+ ObjCSystem,
+
+ /// Like System, but only used for ObjC++.
+ ObjCXXSystem,
+
+ /// Like System, but searched after the system directories.
+ After
+};
+
+} // namespace frontend
/// HeaderSearchOptions - Helper class for storing options related to the
/// initialization of the HeaderSearch object.
@@ -58,8 +78,8 @@ public:
Entry(StringRef path, frontend::IncludeDirGroup group, bool isFramework,
bool ignoreSysRoot)
- : Path(path), Group(group), IsFramework(isFramework),
- IgnoreSysRoot(ignoreSysRoot) {}
+ : Path(path), Group(group), IsFramework(isFramework),
+ IgnoreSysRoot(ignoreSysRoot) {}
};
struct SystemHeaderPrefix {
@@ -71,7 +91,7 @@ public:
bool IsSystemHeader;
SystemHeaderPrefix(StringRef Prefix, bool IsSystemHeader)
- : Prefix(Prefix), IsSystemHeader(IsSystemHeader) {}
+ : Prefix(Prefix), IsSystemHeader(IsSystemHeader) {}
};
/// If non-empty, the directory to use as a "virtual system root" for include
@@ -94,6 +114,9 @@ public:
/// \brief The directory used for a user build.
std::string ModuleUserBuildPath;
+ /// \brief The mapping of module names to prebuilt module files.
+ std::map<std::string, std::string> PrebuiltModuleFiles;
+
/// \brief The directories used to load prebuilt module files.
std::vector<std::string> PrebuiltModulePaths;
@@ -126,7 +149,7 @@ public:
/// files.
///
/// The default value is large, e.g., the operation runs once a week.
- unsigned ModuleCachePruneInterval;
+ unsigned ModuleCachePruneInterval = 7 * 24 * 60 * 60;
/// \brief The time (in seconds) after which an unused module file will be
/// considered unused and will, therefore, be pruned.
@@ -135,13 +158,13 @@ public:
/// accessed in this many seconds will be removed. The default value is
/// large, e.g., a month, to avoid forcing infrequently-used modules to be
/// regenerated often.
- unsigned ModuleCachePruneAfter;
+ unsigned ModuleCachePruneAfter = 31 * 24 * 60 * 60;
/// \brief The time in seconds when the build session started.
///
/// This time is used by other optimizations in header search and module
/// loading.
- uint64_t BuildSessionTimestamp;
+ uint64_t BuildSessionTimestamp = 0;
/// \brief The set of macro names that should be ignored for the purposes
/// of computing the module hash.
@@ -181,10 +204,8 @@ public:
unsigned ModulesHashContent : 1;
HeaderSearchOptions(StringRef _Sysroot = "/")
- : Sysroot(_Sysroot), ModuleFormat("raw"), DisableModuleHash(0),
- ImplicitModuleMaps(0), ModuleMapFileHomeIsCwd(0),
- ModuleCachePruneInterval(7 * 24 * 60 * 60),
- ModuleCachePruneAfter(31 * 24 * 60 * 60), BuildSessionTimestamp(0),
+ : Sysroot(_Sysroot), ModuleFormat("raw"), DisableModuleHash(false),
+ ImplicitModuleMaps(false), ModuleMapFileHomeIsCwd(false),
UseBuiltinIncludes(true), UseStandardSystemIncludes(true),
UseStandardCXXIncludes(true), UseLibcxx(false), Verbose(false),
ModulesValidateOncePerBuildSession(false),
@@ -213,6 +234,6 @@ public:
}
};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_LEX_HEADERSEARCHOPTIONS_H
diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h
index 3be733167e5c..d58849654cb8 100644
--- a/include/clang/Lex/Lexer.h
+++ b/include/clang/Lex/Lexer.h
@@ -1,4 +1,4 @@
-//===--- Lexer.h - C Language Family Lexer ----------------------*- C++ -*-===//
+//===- Lexer.h - C Language Family Lexer ------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,45 +15,88 @@
#define LLVM_CLANG_LEX_LEXER_H
#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/TokenKinds.h"
#include "clang/Lex/PreprocessorLexer.h"
+#include "clang/Lex/Token.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include <cassert>
+#include <cstdint>
#include <string>
+namespace llvm {
+
+class MemoryBuffer;
+
+} // namespace llvm
+
namespace clang {
-class DiagnosticsEngine;
-class SourceManager;
-class Preprocessor;
+
class DiagnosticBuilder;
+class Preprocessor;
+class SourceManager;
/// ConflictMarkerKind - Kinds of conflict marker which the lexer might be
/// recovering from.
enum ConflictMarkerKind {
/// Not within a conflict marker.
CMK_None,
+
/// A normal or diff3 conflict marker, initiated by at least 7 "<"s,
/// separated by at least 7 "="s or "|"s, and terminated by at least 7 ">"s.
CMK_Normal,
+
/// A Perforce-style conflict marker, initiated by 4 ">"s,
/// separated by 4 "="s, and terminated by 4 "<"s.
CMK_Perforce
};
+/// Describes the bounds (start, size) of the preamble and a flag required by
+/// PreprocessorOptions::PrecompiledPreambleBytes.
+/// The preamble includes the BOM, if any.
+struct PreambleBounds {
+ /// \brief Size of the preamble in bytes.
+ unsigned Size;
+
+ /// \brief Whether the preamble ends at the start of a new line.
+ ///
+ /// Used to inform the lexer as to whether it's starting at the beginning of
+ /// a line after skipping the preamble.
+ bool PreambleEndsAtStartOfLine;
+
+ PreambleBounds(unsigned Size, bool PreambleEndsAtStartOfLine)
+ : Size(Size), PreambleEndsAtStartOfLine(PreambleEndsAtStartOfLine) {}
+};
+
/// Lexer - This provides a simple interface that turns a text buffer into a
/// stream of tokens. This provides no support for file reading or buffering,
/// or buffering/seeking of tokens, only forward lexing is supported. It relies
/// on the specified Preprocessor object to handle preprocessor directives, etc.
class Lexer : public PreprocessorLexer {
+ friend class Preprocessor;
+
void anchor() override;
//===--------------------------------------------------------------------===//
// Constant configuration values for this lexer.
- const char *BufferStart; // Start of the buffer.
- const char *BufferEnd; // End of the buffer.
- SourceLocation FileLoc; // Location for start of file.
- LangOptions LangOpts; // LangOpts enabled by this language (cache).
- bool Is_PragmaLexer; // True if lexer for _Pragma handling.
-
+
+ // Start of the buffer.
+ const char *BufferStart;
+
+ // End of the buffer.
+ const char *BufferEnd;
+
+ // Location for start of file.
+ SourceLocation FileLoc;
+
+ // LangOpts enabled by this language (cache).
+ LangOptions LangOpts;
+
+ // True if lexer for _Pragma handling.
+ bool Is_PragmaLexer;
+
//===--------------------------------------------------------------------===//
// Context-specific lexing flags set by the preprocessor.
//
@@ -89,13 +132,9 @@ class Lexer : public PreprocessorLexer {
// CurrentConflictMarkerState - The kind of conflict marker we are handling.
ConflictMarkerKind CurrentConflictMarkerState;
- Lexer(const Lexer &) = delete;
- void operator=(const Lexer &) = delete;
- friend class Preprocessor;
-
void InitLexer(const char *BufStart, const char *BufPtr, const char *BufEnd);
-public:
+public:
/// Lexer constructor - Create a new lexer object for the specified buffer
/// with the specified preprocessor managing the lexing process. This lexer
/// assumes that the associated file buffer and Preprocessor objects will
@@ -114,6 +153,9 @@ public:
Lexer(FileID FID, const llvm::MemoryBuffer *InputBuffer,
const SourceManager &SM, const LangOptions &LangOpts);
+ Lexer(const Lexer &) = delete;
+ Lexer &operator=(const Lexer &) = delete;
+
/// Create_PragmaLexer: Lexer constructor - Create a new lexer object for
/// _Pragma expansion. This has a variety of magic semantics that this method
/// sets up. It returns a new'd Lexer that must be delete'd when done.
@@ -122,7 +164,6 @@ public:
SourceLocation ExpansionLocEnd,
unsigned TokLen, Preprocessor &PP);
-
/// getLangOpts - Return the language features currently enabled.
/// NOTE: this lexer modifies features as a file is parsed!
const LangOptions &getLangOpts() const { return LangOpts; }
@@ -224,17 +265,16 @@ public:
/// \brief Return the current location in the buffer.
const char *getBufferLocation() const { return BufferPtr; }
-
- /// Stringify - Convert the specified string into a C string by escaping '\'
- /// and " characters. This does not add surrounding ""'s to the string.
+
+ /// Stringify - Convert the specified string into a C string by i) escaping
+ /// '\\' and " characters and ii) replacing newline character(s) with "\\n".
/// If Charify is true, this escapes the ' character instead of ".
static std::string Stringify(StringRef Str, bool Charify = false);
- /// Stringify - Convert the specified string into a C string by escaping '\'
- /// and " characters. This does not add surrounding ""'s to the string.
+ /// Stringify - Convert the specified string into a C string by i) escaping
+ /// '\\' and " characters and ii) replacing newline character(s) with "\\n".
static void Stringify(SmallVectorImpl<char> &Str);
-
/// getSpelling - This method is used to get the spelling of a token into a
/// preallocated buffer, instead of as an std::string. The caller is required
/// to allocate enough space for the token, which is guaranteed to be at least
@@ -245,11 +285,11 @@ public:
/// to point to a constant buffer with the data already in it (avoiding a
/// copy). The caller is not allowed to modify the returned buffer pointer
/// if an internal buffer is returned.
- static unsigned getSpelling(const Token &Tok, const char *&Buffer,
+ static unsigned getSpelling(const Token &Tok, const char *&Buffer,
const SourceManager &SourceMgr,
const LangOptions &LangOpts,
bool *Invalid = nullptr);
-
+
/// getSpelling() - Return the 'spelling' of the Tok token. The spelling of a
/// token is the characters used to represent the token in the source file
/// after trigraph expansion and escaped-newline folding. In particular, this
@@ -257,7 +297,7 @@ public:
/// UCNs, etc.
static std::string getSpelling(const Token &Tok,
const SourceManager &SourceMgr,
- const LangOptions &LangOpts,
+ const LangOptions &LangOpts,
bool *Invalid = nullptr);
/// getSpelling - This method is used to get the spelling of the
@@ -273,7 +313,7 @@ public:
const SourceManager &SourceMgr,
const LangOptions &LangOpts,
bool *invalid = nullptr);
-
+
/// MeasureTokenLength - Relex the token at the specified location and return
/// its length in bytes in the input file. If the token needs cleaning (e.g.
/// includes a trigraph or an escaped newline) then this count includes bytes
@@ -295,7 +335,7 @@ public:
static SourceLocation GetBeginningOfToken(SourceLocation Loc,
const SourceManager &SM,
const LangOptions &LangOpts);
-
+
/// AdvanceToTokenCharacter - If the current SourceLocation specifies a
/// location at the start of a token, return a new location that specifies a
/// character within the token. This handles trigraphs and escaped newlines.
@@ -303,7 +343,7 @@ public:
unsigned Character,
const SourceManager &SM,
const LangOptions &LangOpts);
-
+
/// \brief Computes the source location just past the end of the
/// token at this source location.
///
@@ -443,11 +483,18 @@ public:
/// to fewer than this number of lines.
///
/// \returns The offset into the file where the preamble ends and the rest
- /// of the file begins along with a boolean value indicating whether
+ /// of the file begins along with a boolean value indicating whether
/// the preamble ends at the beginning of a new line.
- static std::pair<unsigned, bool> ComputePreamble(StringRef Buffer,
- const LangOptions &LangOpts,
- unsigned MaxLines = 0);
+ static PreambleBounds ComputePreamble(StringRef Buffer,
+ const LangOptions &LangOpts,
+ unsigned MaxLines = 0);
+
+ /// Finds the token that comes right after the given location.
+ ///
+ /// Returns the next token, or none if the location is inside a macro.
+ static Optional<Token> findNextToken(SourceLocation Loc,
+ const SourceManager &SM,
+ const LangOptions &LangOpts);
/// \brief Checks that the given token is the first token that occurs after
/// the given location (this excludes comments and whitespace). Returns the
@@ -463,6 +510,10 @@ public:
/// \brief Returns true if the given character could appear in an identifier.
static bool isIdentifierBodyChar(char c, const LangOptions &LangOpts);
+ /// \brief Checks whether new line pointed by Str is preceded by escape
+ /// sequence.
+ static bool isNewLineEscaped(const char *BufferStart, const char *Str);
+
/// getCharAndSizeNoWarn - Like the getCharAndSize method, but does not ever
/// emit a warning.
static inline char getCharAndSizeNoWarn(const char *Ptr, unsigned &Size,
@@ -483,9 +534,9 @@ public:
static StringRef getIndentationForLine(SourceLocation Loc,
const SourceManager &SM);
+private:
//===--------------------------------------------------------------------===//
// Internal implementation interfaces.
-private:
/// LexTokenInternal - Internal interface to lex a preprocessing token. Called
/// by Lex.
@@ -614,7 +665,7 @@ private:
//===--------------------------------------------------------------------===//
// Other lexer functions.
- void SkipBytes(unsigned Bytes, bool StartOfLine);
+ void SetByteOffset(unsigned Offset, bool StartOfLine);
void PropagateLineStartLeadingSpaceInfo(Token &Result);
@@ -639,7 +690,7 @@ private:
bool SkipBlockComment (Token &Result, const char *CurPtr,
bool &TokAtPhysicalStartOfLine);
bool SaveLineComment (Token &Result, const char *CurPtr);
-
+
bool IsStartOfConflictMarker(const char *CurPtr);
bool HandleEndOfConflictMarker(const char *CurPtr);
@@ -658,7 +709,7 @@ private:
/// 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 NULL to suppress diagnostics
+ /// \param Tok 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
@@ -687,6 +738,6 @@ private:
bool tryConsumeIdentifierUTF8Char(const char *&CurPtr);
};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_LEX_LEXER_H
diff --git a/include/clang/Lex/LiteralSupport.h b/include/clang/Lex/LiteralSupport.h
index b66581b428b1..cc9223eb7dbb 100644
--- a/include/clang/Lex/LiteralSupport.h
+++ b/include/clang/Lex/LiteralSupport.h
@@ -65,6 +65,7 @@ public:
bool isHalf : 1; // 1.0h
bool isFloat : 1; // 1.0f
bool isImaginary : 1; // 1.0i
+ bool isFloat16 : 1; // 1.0f16
bool isFloat128 : 1; // 1.0q
uint8_t MicrosoftInteger; // Microsoft suffix extension i8, i16, i32, or i64.
diff --git a/include/clang/Lex/MacroArgs.h b/include/clang/Lex/MacroArgs.h
index cfe46ceb0979..a202550da3b3 100644
--- a/include/clang/Lex/MacroArgs.h
+++ b/include/clang/Lex/MacroArgs.h
@@ -17,6 +17,7 @@
#include "clang/Basic/LLVM.h"
#include "clang/Lex/Token.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/TrailingObjects.h"
#include <vector>
namespace clang {
@@ -26,7 +27,10 @@ namespace clang {
/// MacroArgs - An instance of this class captures information about
/// the formal arguments specified to a function-like macro invocation.
-class MacroArgs {
+class MacroArgs final
+ : private llvm::TrailingObjects<MacroArgs, Token> {
+
+ friend TrailingObjects;
/// NumUnexpArgTokens - The number of raw, unexpanded tokens for the
/// arguments. All of the actual argument tokens are allocated immediately
/// after the MacroArgs object in memory. This is all of the arguments
@@ -89,7 +93,7 @@ public:
/// getPreExpArgument - Return the pre-expanded form of the specified
/// argument.
const std::vector<Token> &
- getPreExpArgument(unsigned Arg, const MacroInfo *MI, Preprocessor &PP);
+ getPreExpArgument(unsigned Arg, Preprocessor &PP);
/// getStringifiedArgument - Compute, cache, and return the specified argument
/// that has been 'stringified' as required by the # operator.
@@ -108,6 +112,20 @@ public:
/// argument, this returns false.
bool isVarargsElidedUse() const { return VarargsElided; }
+ /// Returns true if the macro was defined with a variadic (ellipsis) parameter
+ /// AND was invoked with at least one token supplied as a variadic argument.
+ ///
+ /// \code
+ /// #define F(a) a
+ /// #define V(a, ...) __VA_OPT__(a)
+ /// F() <-- returns false on this invocation.
+ /// V(,a) <-- returns true on this invocation.
+ /// V(,) <-- returns false on this invocation.
+ /// \endcode
+ ///
+
+ bool invokedWithVariadicArgument(const MacroInfo *const MI) const;
+
/// StringifyArgument - Implement C99 6.10.3.2p2, converting a sequence of
/// tokens into the literal string token that should be produced by the C #
/// preprocessor operator. If Charify is true, then it should be turned into
diff --git a/include/clang/Lex/MacroInfo.h b/include/clang/Lex/MacroInfo.h
index d25431b55fdc..3029294209ec 100644
--- a/include/clang/Lex/MacroInfo.h
+++ b/include/clang/Lex/MacroInfo.h
@@ -1,4 +1,4 @@
-//===--- MacroInfo.h - Information about #defined identifiers ---*- C++ -*-===//
+//===- MacroInfo.h - Information about #defined identifiers -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,27 +6,33 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-///
+//
/// \file
/// \brief Defines the clang::MacroInfo and clang::MacroDirective classes.
-///
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_LEX_MACROINFO_H
#define LLVM_CLANG_LEX_MACROINFO_H
#include "clang/Lex/Token.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Allocator.h"
+#include <algorithm>
#include <cassert>
namespace clang {
+
+class DefMacroDirective;
+class IdentifierInfo;
class Module;
-class ModuleMacro;
class Preprocessor;
+class SourceManager;
/// \brief Encapsulates the data about a macro definition (e.g. its tokens).
///
@@ -37,6 +43,7 @@ class MacroInfo {
/// \brief The location the macro is defined.
SourceLocation Location;
+
/// \brief The location of the last token in the macro.
SourceLocation EndLocation;
@@ -46,10 +53,10 @@ class MacroInfo {
///
/// This can be empty, for, e.g. "#define X()". In a C99-style variadic
/// macro, this includes the \c __VA_ARGS__ identifier on the list.
- IdentifierInfo **ParameterList;
+ IdentifierInfo **ParameterList = nullptr;
/// \see ParameterList
- unsigned NumParameters;
+ unsigned NumParameters = 0;
/// \brief This is the list of tokens that the macro is defined to.
SmallVector<Token, 8> ReplacementTokens;
@@ -169,7 +176,7 @@ public:
/// Parameters - The list of parameters for a function-like macro. This can
/// be empty, for, e.g. "#define X()".
- typedef IdentifierInfo *const *param_iterator;
+ using param_iterator = IdentifierInfo *const *;
bool param_empty() const { return NumParameters == 0; }
param_iterator param_begin() const { return ParameterList; }
param_iterator param_end() const { return ParameterList + NumParameters; }
@@ -224,7 +231,6 @@ public:
bool isWarnIfUnused() const { return IsWarnIfUnused; }
/// \brief Return the number of tokens that this macro expands to.
- ///
unsigned getNumTokens() const { return ReplacementTokens.size(); }
const Token &getReplacementToken(unsigned Tok) const {
@@ -232,7 +238,8 @@ public:
return ReplacementTokens[Tok];
}
- typedef SmallVectorImpl<Token>::const_iterator tokens_iterator;
+ using tokens_iterator = SmallVectorImpl<Token>::const_iterator;
+
tokens_iterator tokens_begin() const { return ReplacementTokens.begin(); }
tokens_iterator tokens_end() const { return ReplacementTokens.end(); }
bool tokens_empty() const { return ReplacementTokens.empty(); }
@@ -269,12 +276,10 @@ public:
void dump() const;
private:
- unsigned getDefinitionLengthSlow(const SourceManager &SM) const;
-
friend class Preprocessor;
-};
-class DefMacroDirective;
+ unsigned getDefinitionLengthSlow(const SourceManager &SM) const;
+};
/// \brief Encapsulates changes to the "macros namespace" (the location where
/// the macro name became active, the location where it was undefined, etc.).
@@ -285,11 +290,15 @@ class DefMacroDirective;
/// create additional DefMacroDirectives for the same MacroInfo.
class MacroDirective {
public:
- enum Kind { MD_Define, MD_Undefine, MD_Visibility };
+ enum Kind {
+ MD_Define,
+ MD_Undefine,
+ MD_Visibility
+ };
protected:
- /// \brief Previous macro directive for the same identifier, or NULL.
- MacroDirective *Previous;
+ /// \brief Previous macro directive for the same identifier, or nullptr.
+ MacroDirective *Previous = nullptr;
SourceLocation Loc;
@@ -306,8 +315,7 @@ protected:
unsigned IsPublic : 1;
MacroDirective(Kind K, SourceLocation Loc)
- : Previous(nullptr), Loc(Loc), MDKind(K), IsFromPCH(false),
- IsPublic(true) {}
+ : Loc(Loc), MDKind(K), IsFromPCH(false), IsPublic(true) {}
public:
Kind getKind() const { return Kind(MDKind); }
@@ -329,13 +337,12 @@ public:
void setIsFromPCH() { IsFromPCH = true; }
class DefInfo {
- DefMacroDirective *DefDirective;
+ DefMacroDirective *DefDirective = nullptr;
SourceLocation UndefLoc;
- bool IsPublic;
+ bool IsPublic = true;
public:
- DefInfo() : DefDirective(nullptr), IsPublic(true) {}
-
+ DefInfo() = default;
DefInfo(DefMacroDirective *DefDirective, SourceLocation UndefLoc,
bool isPublic)
: DefDirective(DefDirective), UndefLoc(UndefLoc), IsPublic(isPublic) {}
@@ -345,6 +352,7 @@ public:
inline SourceLocation getLocation() const;
inline MacroInfo *getMacroInfo();
+
const MacroInfo *getMacroInfo() const {
return const_cast<DefInfo *>(this)->getMacroInfo();
}
@@ -360,6 +368,7 @@ public:
explicit operator bool() const { return isValid(); }
inline DefInfo getPreviousDefinition();
+
const DefInfo getPreviousDefinition() const {
return const_cast<DefInfo *>(this)->getPreviousDefinition();
}
@@ -412,6 +421,7 @@ public:
static bool classof(const MacroDirective *MD) {
return MD->getKind() == MD_Define;
}
+
static bool classof(const DefMacroDirective *) { return true; }
};
@@ -426,6 +436,7 @@ public:
static bool classof(const MacroDirective *MD) {
return MD->getKind() == MD_Undefine;
}
+
static bool classof(const UndefMacroDirective *) { return true; }
};
@@ -444,12 +455,13 @@ public:
static bool classof(const MacroDirective *MD) {
return MD->getKind() == MD_Visibility;
}
+
static bool classof(const VisibilityMacroDirective *) { return true; }
};
inline SourceLocation MacroDirective::DefInfo::getLocation() const {
if (isInvalid())
- return SourceLocation();
+ return {};
return DefDirective->getLocation();
}
@@ -462,7 +474,7 @@ inline MacroInfo *MacroDirective::DefInfo::getMacroInfo() {
inline MacroDirective::DefInfo
MacroDirective::DefInfo::getPreviousDefinition() {
if (isInvalid() || DefDirective->getPrevious() == nullptr)
- return DefInfo();
+ return {};
return DefDirective->getPrevious()->getDefinition();
}
@@ -474,23 +486,26 @@ MacroDirective::DefInfo::getPreviousDefinition() {
///
/// These are stored in a FoldingSet in the preprocessor.
class ModuleMacro : public llvm::FoldingSetNode {
+ friend class Preprocessor;
+
/// The name defined by the macro.
IdentifierInfo *II;
+
/// The body of the #define, or nullptr if this is a #undef.
MacroInfo *Macro;
+
/// The module that exports this macro.
Module *OwningModule;
+
/// The number of module macros that override this one.
- unsigned NumOverriddenBy;
+ unsigned NumOverriddenBy = 0;
+
/// The number of modules whose macros are directly overridden by this one.
unsigned NumOverrides;
- // ModuleMacro *OverriddenMacros[NumOverrides];
-
- friend class Preprocessor;
ModuleMacro(Module *OwningModule, IdentifierInfo *II, MacroInfo *Macro,
ArrayRef<ModuleMacro *> Overrides)
- : II(II), Macro(Macro), OwningModule(OwningModule), NumOverriddenBy(0),
+ : II(II), Macro(Macro), OwningModule(OwningModule),
NumOverrides(Overrides.size()) {
std::copy(Overrides.begin(), Overrides.end(),
reinterpret_cast<ModuleMacro **>(this + 1));
@@ -504,12 +519,16 @@ public:
void Profile(llvm::FoldingSetNodeID &ID) const {
return Profile(ID, OwningModule, II);
}
+
static void Profile(llvm::FoldingSetNodeID &ID, Module *OwningModule,
IdentifierInfo *II) {
ID.AddPointer(OwningModule);
ID.AddPointer(II);
}
+ /// Get the name of the macro.
+ IdentifierInfo *getName() const { return II; }
+
/// Get the ID of the module that exports this macro.
Module *getOwningModule() const { return OwningModule; }
@@ -519,13 +538,16 @@ public:
/// Iterators over the overridden module IDs.
/// \{
- typedef ModuleMacro *const *overrides_iterator;
+ using overrides_iterator = ModuleMacro *const *;
+
overrides_iterator overrides_begin() const {
return reinterpret_cast<overrides_iterator>(this + 1);
}
+
overrides_iterator overrides_end() const {
return overrides_begin() + NumOverrides;
}
+
ArrayRef<ModuleMacro *> overrides() const {
return llvm::makeArrayRef(overrides_begin(), overrides_end());
}
@@ -544,7 +566,7 @@ class MacroDefinition {
ArrayRef<ModuleMacro *> ModuleMacros;
public:
- MacroDefinition() : LatestLocalAndAmbiguous(), ModuleMacros() {}
+ MacroDefinition() = default;
MacroDefinition(DefMacroDirective *MD, ArrayRef<ModuleMacro *> MMs,
bool IsAmbiguous)
: LatestLocalAndAmbiguous(MD, IsAmbiguous), ModuleMacros(MMs) {}
@@ -583,6 +605,6 @@ public:
}
};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_LEX_MACROINFO_H
diff --git a/include/clang/Lex/ModuleLoader.h b/include/clang/Lex/ModuleLoader.h
index ee0638b57f87..30ea583b71e0 100644
--- a/include/clang/Lex/ModuleLoader.h
+++ b/include/clang/Lex/ModuleLoader.h
@@ -1,4 +1,4 @@
-//===--- ModuleLoader.h - Module Loader Interface ---------------*- C++ -*-===//
+//===- ModuleLoader.h - Module Loader Interface -----------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,23 +11,26 @@
// loading named modules.
//
//===----------------------------------------------------------------------===//
+
#ifndef LLVM_CLANG_LEX_MODULELOADER_H
#define LLVM_CLANG_LEX_MODULELOADER_H
+#include "clang/Basic/LLVM.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/StringRef.h"
+#include <utility>
namespace clang {
class GlobalModuleIndex;
class IdentifierInfo;
-class Module;
/// \brief A sequence of identifier/location pairs used to describe a particular
/// module or submodule, e.g., std.vector.
-typedef ArrayRef<std::pair<IdentifierInfo *, SourceLocation> > ModuleIdPath;
+using ModuleIdPath = ArrayRef<std::pair<IdentifierInfo *, SourceLocation>>;
/// \brief Describes the result of attempting to load a module.
class ModuleLoadResult {
@@ -35,16 +38,18 @@ public:
enum LoadResultKind {
// We either succeeded or failed to load the named module.
Normal,
+
// The module exists, but does not actually contain the named submodule.
// This should only happen if the named submodule was inferred from an
// umbrella directory, but not actually part of the umbrella header.
MissingExpected,
+
// The module exists but cannot be imported due to a configuration mismatch.
ConfigMismatch
};
llvm::PointerIntPair<Module *, 2, LoadResultKind> Storage;
- ModuleLoadResult() : Storage() { }
+ ModuleLoadResult() = default;
ModuleLoadResult(Module *M) : Storage(M, Normal) {}
ModuleLoadResult(LoadResultKind Kind) : Storage(nullptr, Kind) {}
@@ -69,10 +74,10 @@ public:
class ModuleLoader {
// Building a module if true.
bool BuildingModule;
+
public:
- explicit ModuleLoader(bool BuildingModule = false) :
- BuildingModule(BuildingModule),
- HadFatalFailure(false) {}
+ explicit ModuleLoader(bool BuildingModule = false)
+ : BuildingModule(BuildingModule) {}
virtual ~ModuleLoader();
@@ -80,6 +85,7 @@ public:
bool buildingModule() const {
return BuildingModule;
}
+
/// \brief Flag indicating whether this instance is building a module.
void setBuildingModule(bool BuildingModuleFlag) {
BuildingModule = BuildingModuleFlag;
@@ -144,7 +150,7 @@ public:
virtual bool lookupMissingImports(StringRef Name,
SourceLocation TriggerLoc) = 0;
- bool HadFatalFailure;
+ bool HadFatalFailure = false;
};
/// A module loader that doesn't know how to load modules.
@@ -153,7 +159,7 @@ public:
ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path,
Module::NameVisibilityKind Visibility,
bool IsInclusionDirective) override {
- return ModuleLoadResult();
+ return {};
}
void loadModuleFromSource(SourceLocation ImportLoc, StringRef ModuleName,
@@ -165,12 +171,13 @@ public:
GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override {
return nullptr;
}
+
bool lookupMissingImports(StringRef Name,
SourceLocation TriggerLoc) override {
- return 0;
+ return false;
}
};
-}
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_LEX_MODULELOADER_H
diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h
index 11506939f9b1..41ed8e49b6c1 100644
--- a/include/clang/Lex/ModuleMap.h
+++ b/include/clang/Lex/ModuleMap.h
@@ -1,4 +1,4 @@
-//===--- ModuleMap.h - Describe the layout of modules -----------*- C++ -*-===//
+//===- ModuleMap.h - Describe the layout of modules -------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -18,7 +18,6 @@
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerIntPair.h"
@@ -28,20 +27,19 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/ADT/Twine.h"
-#include <algorithm>
+#include <ctime>
#include <memory>
#include <string>
#include <utility>
namespace clang {
+class DiagnosticsEngine;
class DirectoryEntry;
class FileEntry;
class FileManager;
-class DiagnosticConsumer;
-class DiagnosticsEngine;
class HeaderSearch;
-class ModuleMapParser;
+class SourceManager;
/// \brief A mechanism to observe the actions of the module map parser as it
/// reads module map files.
@@ -82,33 +80,40 @@ class ModuleMap {
/// \brief The directory used for Clang-supplied, builtin include headers,
/// such as "stdint.h".
- const DirectoryEntry *BuiltinIncludeDir;
+ const DirectoryEntry *BuiltinIncludeDir = nullptr;
/// \brief Language options used to parse the module map itself.
///
/// These are always simple C language options.
LangOptions MMapLangOpts;
- // The module that the main source file is associated with (the module
- // named LangOpts::CurrentModule, if we've loaded it).
- Module *SourceModule;
+ /// The module that the main source file is associated with (the module
+ /// 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;
/// \brief The top-level modules that are known.
llvm::StringMap<Module *> Modules;
/// \brief The number of modules we have created in total.
- unsigned NumCreatedModules;
+ unsigned NumCreatedModules = 0;
public:
/// \brief Flags describing the role of a module header.
enum ModuleHeaderRole {
/// \brief This header is normally included in the module.
NormalHeader = 0x0,
+
/// \brief This header is included but private.
PrivateHeader = 0x1,
+
/// \brief This header is part of the module (for layering purposes) but
/// should be textually included.
TextualHeader = 0x2,
+
// Caution: Adding an enumerator needs other changes.
// Adjust the number of bits for KnownHeader::Storage.
// Adjust the bitfield HeaderFileInfo::HeaderRole size.
@@ -119,6 +124,7 @@ public:
/// Convert a header kind to a role. Requires Kind to not be HK_Excluded.
static ModuleHeaderRole headerKindToRole(Module::HeaderKind Kind);
+
/// Convert a header role to a kind.
static Module::HeaderKind headerRoleToKind(ModuleHeaderRole Role);
@@ -128,8 +134,8 @@ public:
llvm::PointerIntPair<Module *, 2, ModuleHeaderRole> Storage;
public:
- KnownHeader() : Storage(nullptr, NormalHeader) { }
- KnownHeader(Module *M, ModuleHeaderRole Role) : Storage(M, Role) { }
+ KnownHeader() : Storage(nullptr, NormalHeader) {}
+ KnownHeader(Module *M, ModuleHeaderRole Role) : Storage(M, Role) {}
friend bool operator==(const KnownHeader &A, const KnownHeader &B) {
return A.Storage == B.Storage;
@@ -162,11 +168,13 @@ public:
}
};
- typedef llvm::SmallPtrSet<const FileEntry *, 1> AdditionalModMapsSet;
+ using AdditionalModMapsSet = llvm::SmallPtrSet<const FileEntry *, 1>;
private:
- typedef llvm::DenseMap<const FileEntry *, SmallVector<KnownHeader, 1>>
- HeadersMap;
+ friend class ModuleMapParser;
+
+ using HeadersMap =
+ llvm::DenseMap<const FileEntry *, SmallVector<KnownHeader, 1>>;
/// \brief Mapping from each header to the module that owns the contents of
/// that header.
@@ -174,6 +182,7 @@ private:
/// Map from file sizes to modules with lazy header directives of that size.
mutable llvm::DenseMap<off_t, llvm::TinyPtrVector<Module*>> LazyHeadersBySize;
+
/// Map from mtimes to modules with lazy header directives with those mtimes.
mutable llvm::DenseMap<time_t, llvm::TinyPtrVector<Module*>>
LazyHeadersByModTime;
@@ -188,9 +197,6 @@ private:
/// \brief The set of attributes that can be attached to a module.
struct Attributes {
- Attributes()
- : IsSystem(), IsExternC(), IsExhaustive(), NoUndeclaredIncludes() {}
-
/// \brief Whether this is a system module.
unsigned IsSystem : 1;
@@ -203,12 +209,14 @@ private:
/// \brief Whether files in this module can only include non-modular headers
/// and headers from used modules.
unsigned NoUndeclaredIncludes : 1;
+
+ Attributes()
+ : IsSystem(false), IsExternC(false), IsExhaustive(false),
+ NoUndeclaredIncludes(false) {}
};
/// \brief A directory for which framework modules can be inferred.
struct InferredDirectory {
- InferredDirectory() : InferModules() {}
-
/// \brief Whether to infer modules from this directory.
unsigned InferModules : 1;
@@ -222,6 +230,8 @@ private:
/// \brief The names of modules that cannot be inferred within this
/// directory.
SmallVector<std::string, 2> ExcludedModules;
+
+ InferredDirectory() : InferModules(false) {}
};
/// \brief A mapping from directories to information about inferring
@@ -238,8 +248,6 @@ private:
/// map.
llvm::DenseMap<const FileEntry *, bool> ParsedModuleMap;
- friend class ModuleMapParser;
-
/// \brief Resolve the given export declaration into an actual export
/// declaration.
///
@@ -341,7 +349,6 @@ public:
HeaderSearch &HeaderInfo);
/// \brief Destroy the module map.
- ///
~ModuleMap();
/// \brief Set the target information.
@@ -460,7 +467,7 @@ public:
/// \param Name The name of the module to find or create.
///
/// \param Parent The module that will act as the parent of this submodule,
- /// or NULL to indicate that this is a top-level module.
+ /// or nullptr to indicate that this is a top-level module.
///
/// \param IsFramework Whether this is a framework module.
///
@@ -472,6 +479,14 @@ public:
bool IsFramework,
bool IsExplicit);
+ /// \brief 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
+ /// later, because we don't know what it will be called.
+ Module *createGlobalModuleForInterfaceUnit(SourceLocation Loc);
+
/// \brief Create a new module for a C++ Modules TS module interface unit.
/// The module must not already exist, and will be configured for the current
/// compilation.
@@ -479,7 +494,8 @@ public:
/// Note that this also sets the current module to the newly-created module.
///
/// \returns The newly-created module.
- Module *createModuleForInterfaceUnit(SourceLocation Loc, StringRef Name);
+ Module *createModuleForInterfaceUnit(SourceLocation Loc, StringRef Name,
+ Module *GlobalModule);
/// \brief Infer the contents of a framework module map from the given
/// framework directory.
@@ -492,7 +508,7 @@ public:
/// \param Module The module whose module map file will be returned, if known.
///
/// \returns The file entry for the module map file containing the given
- /// module, or NULL if the module definition was inferred.
+ /// module, or nullptr if the module definition was inferred.
const FileEntry *getContainingModuleMapFile(const Module *Module) const;
/// \brief Get the module map file that (along with the module name) uniquely
@@ -599,11 +615,12 @@ public:
/// \brief Dump the contents of the module map, for debugging purposes.
void dump();
- typedef llvm::StringMap<Module *>::const_iterator module_iterator;
+ using module_iterator = llvm::StringMap<Module *>::const_iterator;
+
module_iterator module_begin() const { return Modules.begin(); }
module_iterator module_end() const { return Modules.end(); }
};
-} // end namespace clang
+} // namespace clang
#endif // LLVM_CLANG_LEX_MODULEMAP_H
diff --git a/include/clang/Lex/MultipleIncludeOpt.h b/include/clang/Lex/MultipleIncludeOpt.h
index 83e6f99078df..3967f8688966 100644
--- a/include/clang/Lex/MultipleIncludeOpt.h
+++ b/include/clang/Lex/MultipleIncludeOpt.h
@@ -92,7 +92,7 @@ public:
TheMacro = nullptr;
}
- /// getHasReadAnyTokensVal - This is used for the \#ifndef hande-shake at the
+ /// getHasReadAnyTokensVal - This is used for the \#ifndef handshake at the
/// top of the file when reading preprocessor directives. Otherwise, reading
/// the "ifndef x" would count as reading tokens.
bool getHasReadAnyTokensVal() const { return ReadAnyTokens; }
diff --git a/include/clang/Lex/PPCallbacks.h b/include/clang/Lex/PPCallbacks.h
index 81c3bd7d14ec..19bce4dd32e8 100644
--- a/include/clang/Lex/PPCallbacks.h
+++ b/include/clang/Lex/PPCallbacks.h
@@ -235,6 +235,14 @@ public:
virtual void PragmaWarningPop(SourceLocation Loc) {
}
+ /// \brief Callback invoked when a \#pragma clang assume_nonnull begin directive
+ /// is read.
+ virtual void PragmaAssumeNonNullBegin(SourceLocation Loc) {}
+
+ /// \brief Callback invoked when a \#pragma clang assume_nonnull end directive
+ /// is read.
+ virtual void PragmaAssumeNonNullEnd(SourceLocation Loc) {}
+
/// \brief Called by Preprocessor::HandleMacroExpandedIdentifier when a
/// macro invocation is found.
virtual void MacroExpands(const Token &MacroNameTok,
@@ -266,7 +274,10 @@ public:
/// \brief 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.
- virtual void SourceRangeSkipped(SourceRange Range) {
+ /// \param EndifLoc The end location of the 'endif' token, which may precede
+ /// the range skipped by the directive (e.g excluding comments after an
+ /// 'endif').
+ virtual void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) {
}
enum ConditionValueKind {
@@ -381,6 +392,12 @@ public:
Second->Ident(Loc, str);
}
+ void PragmaDirective(SourceLocation Loc,
+ PragmaIntroducerKind Introducer) override {
+ First->PragmaDirective(Loc, Introducer);
+ Second->PragmaDirective(Loc, Introducer);
+ }
+
void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
StringRef Str) override {
First->PragmaComment(Loc, Kind, Str);
@@ -393,6 +410,11 @@ public:
Second->PragmaDetectMismatch(Loc, Name, Value);
}
+ void PragmaDebug(SourceLocation Loc, StringRef DebugType) override {
+ First->PragmaDebug(Loc, DebugType);
+ Second->PragmaDebug(Loc, DebugType);
+ }
+
void PragmaMessage(SourceLocation Loc, StringRef Namespace,
PragmaMessageKind Kind, StringRef Str) override {
First->PragmaMessage(Loc, Namespace, Kind, Str);
@@ -437,6 +459,16 @@ public:
Second->PragmaWarningPop(Loc);
}
+ void PragmaAssumeNonNullBegin(SourceLocation Loc) override {
+ First->PragmaAssumeNonNullBegin(Loc);
+ Second->PragmaAssumeNonNullBegin(Loc);
+ }
+
+ void PragmaAssumeNonNullEnd(SourceLocation Loc) override {
+ First->PragmaAssumeNonNullEnd(Loc);
+ Second->PragmaAssumeNonNullEnd(Loc);
+ }
+
void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD,
SourceRange Range, const MacroArgs *Args) override {
First->MacroExpands(MacroNameTok, MD, Range, Args);
@@ -462,9 +494,9 @@ public:
Second->Defined(MacroNameTok, MD, Range);
}
- void SourceRangeSkipped(SourceRange Range) override {
- First->SourceRangeSkipped(Range);
- Second->SourceRangeSkipped(Range);
+ void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) override {
+ First->SourceRangeSkipped(Range, EndifLoc);
+ Second->SourceRangeSkipped(Range, EndifLoc);
}
/// \brief Hook called whenever an \#if is seen.
diff --git a/include/clang/Lex/PTHLexer.h b/include/clang/Lex/PTHLexer.h
index f96af665b157..f122a008e4aa 100644
--- a/include/clang/Lex/PTHLexer.h
+++ b/include/clang/Lex/PTHLexer.h
@@ -1,4 +1,4 @@
-//===--- PTHLexer.h - Lexer based on Pre-tokenized input --------*- C++ -*-===//
+//===- PTHLexer.h - Lexer based on Pre-tokenized input ----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,12 +14,15 @@
#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 PTHSpellingSearch;
class PTHLexer : public PreprocessorLexer {
SourceLocation FileStartLoc;
@@ -33,7 +36,7 @@ class PTHLexer : public PreprocessorLexer {
/// LastHashTokPtr - Pointer into TokBuf of the last processed '#'
/// token that appears at the start of a line.
- const unsigned char* LastHashTokPtr;
+ 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.
@@ -44,11 +47,8 @@ class PTHLexer : public PreprocessorLexer {
/// to process when doing quick skipping of preprocessor blocks.
const unsigned char* CurPPCondPtr;
- PTHLexer(const PTHLexer &) = delete;
- void operator=(const PTHLexer &) = delete;
-
/// ReadToken - Used by PTHLexer to read tokens TokBuf.
- void ReadToken(Token& T);
+ void ReadToken(Token &T);
bool LexEndOfFile(Token &Result);
@@ -61,10 +61,13 @@ protected:
friend class PTHManager;
/// Create a PTHLexer for the specified token stream.
- PTHLexer(Preprocessor& pp, FileID FID, const unsigned char *D,
+ PTHLexer(Preprocessor &pp, FileID FID, const unsigned char *D,
const unsigned char* ppcond, PTHManager &PM);
+
public:
- ~PTHLexer() override {}
+ PTHLexer(const PTHLexer &) = delete;
+ PTHLexer &operator=(const PTHLexer &) = delete;
+ ~PTHLexer() override = default;
/// Lex - Return the next token.
bool Lex(Token &Tok);
@@ -99,6 +102,6 @@ public:
bool SkipBlock();
};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_LEX_PTHLEXER_H
diff --git a/include/clang/Lex/PTHManager.h b/include/clang/Lex/PTHManager.h
index f4e4774429f9..483b69f23a9c 100644
--- a/include/clang/Lex/PTHManager.h
+++ b/include/clang/Lex/PTHManager.h
@@ -1,4 +1,4 @@
-//===--- PTHManager.h - Manager object for PTH processing -------*- C++ -*-===//
+//===- PTHManager.h - Manager object for PTH processing ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -17,30 +17,33 @@
#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;
-}
+
+class MemoryBuffer;
+
+} // namespace llvm
namespace clang {
-class FileEntry;
-class Preprocessor;
-class PTHLexer;
class DiagnosticsEngine;
class FileSystemStatCache;
+class Preprocessor;
+class PTHLexer;
class PTHManager : public IdentifierInfoLookup {
friend class PTHLexer;
-
friend class PTHStatCache;
- class PTHStringLookupTrait;
class PTHFileLookupTrait;
- typedef llvm::OnDiskChainedHashTable<PTHStringLookupTrait> PTHStringIdLookup;
- typedef llvm::OnDiskChainedHashTable<PTHFileLookupTrait> PTHFileLookup;
+ class PTHStringLookupTrait;
+
+ using PTHStringIdLookup = llvm::OnDiskChainedHashTable<PTHStringLookupTrait>;
+ using PTHFileLookup = llvm::OnDiskChainedHashTable<PTHFileLookupTrait>;
/// The memory mapped PTH file.
std::unique_ptr<const llvm::MemoryBuffer> Buf;
@@ -70,7 +73,7 @@ class PTHManager : public IdentifierInfoLookup {
/// PP - The Preprocessor object that will use this PTHManager to create
/// PTHLexer objects.
- Preprocessor* PP;
+ Preprocessor* PP = nullptr;
/// SpellingBase - The base offset within the PTH memory buffer that
/// contains the cached spellings for literals.
@@ -89,16 +92,13 @@ class PTHManager : public IdentifierInfoLookup {
std::unique_ptr<PTHStringIdLookup> stringIdLookup, unsigned numIds,
const unsigned char *spellingBase, const char *originalSourceFile);
- PTHManager(const PTHManager &) = delete;
- void operator=(const PTHManager &) = delete;
-
/// 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.
- inline IdentifierInfo* GetIdentifierInfo(unsigned PersistentID) {
+ IdentifierInfo *GetIdentifierInfo(unsigned PersistentID) {
// Check if the IdentifierInfo has already been resolved.
if (IdentifierInfo* II = PerIDCache[PersistentID])
return II;
@@ -110,6 +110,8 @@ 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
@@ -120,18 +122,18 @@ public:
/// 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 NULL then the IdentifierInfo cannot
+ /// 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 NULL upon failure.
+ /// 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 NULL if no cached tokens exist.
+ /// 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);
@@ -142,6 +144,6 @@ public:
std::unique_ptr<FileSystemStatCache> createStatCache();
};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_LEX_PTHMANAGER_H
diff --git a/include/clang/Lex/Pragma.h b/include/clang/Lex/Pragma.h
index 274f0dad3dd0..090ae2a98236 100644
--- a/include/clang/Lex/Pragma.h
+++ b/include/clang/Lex/Pragma.h
@@ -1,4 +1,4 @@
-//===--- Pragma.h - Pragma registration and handling ------------*- C++ -*-===//
+//===- Pragma.h - Pragma registration and handling --------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -17,13 +17,13 @@
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
-#include <cassert>
+#include <string>
namespace clang {
- class Preprocessor;
- class Token;
- class IdentifierInfo;
- class PragmaNamespace;
+
+class PragmaNamespace;
+class Preprocessor;
+class Token;
/**
* \brief Describes how the pragma was introduced, e.g., with \#pragma,
@@ -58,9 +58,10 @@ namespace clang {
/// pragmas.
class PragmaHandler {
std::string Name;
+
public:
+ PragmaHandler() = default;
explicit PragmaHandler(StringRef name) : Name(name) {}
- PragmaHandler() {}
virtual ~PragmaHandler();
StringRef getName() const { return Name; }
@@ -89,8 +90,8 @@ public:
class PragmaNamespace : public PragmaHandler {
/// Handlers - This is a map of the handlers in this namespace with their name
/// as key.
- ///
- llvm::StringMap<PragmaHandler*> Handlers;
+ llvm::StringMap<PragmaHandler *> Handlers;
+
public:
explicit PragmaNamespace(StringRef Name) : PragmaHandler(Name) {}
~PragmaNamespace() override;
@@ -103,16 +104,13 @@ public:
bool IgnoreNull = true) const;
/// AddPragma - Add a pragma to this namespace.
- ///
void AddPragma(PragmaHandler *Handler);
/// RemovePragmaHandler - Remove the given handler from the
/// namespace.
void RemovePragmaHandler(PragmaHandler *Handler);
- bool IsEmpty() {
- return Handlers.empty();
- }
+ bool IsEmpty() const { return Handlers.empty(); }
void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
Token &FirstToken) override;
@@ -120,7 +118,6 @@ public:
PragmaNamespace *getIfNamespace() override { return this; }
};
+} // namespace clang
-} // end namespace clang
-
-#endif
+#endif // LLVM_CLANG_LEX_PRAGMA_H
diff --git a/include/clang/Lex/PreprocessingRecord.h b/include/clang/Lex/PreprocessingRecord.h
index fc2c50700400..5f7a6efcef10 100644
--- a/include/clang/Lex/PreprocessingRecord.h
+++ b/include/clang/Lex/PreprocessingRecord.h
@@ -1,4 +1,4 @@
-//===--- PreprocessingRecord.h - Record of Preprocessing --------*- C++ -*-===//
+//===- PreprocessingRecord.h - Record of Preprocessing ----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,24 +11,33 @@
// of what occurred during preprocessing.
//
//===----------------------------------------------------------------------===//
+
#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"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Compiler.h"
+#include <cassert>
+#include <cstddef>
+#include <iterator>
+#include <utility>
#include <vector>
namespace clang {
- class IdentifierInfo;
- class MacroInfo;
- class PreprocessingRecord;
-}
+
+class PreprocessingRecord;
+
+} // namespace clang
/// \brief Allocates memory within a Clang preprocessing record.
void *operator new(size_t bytes, clang::PreprocessingRecord &PR,
@@ -39,8 +48,12 @@ void operator delete(void *ptr, clang::PreprocessingRecord &PR,
unsigned) noexcept;
namespace clang {
- class MacroDefinitionRecord;
- class FileEntry;
+
+class FileEntry;
+class IdentifierInfo;
+class MacroInfo;
+class SourceManager;
+class Token;
/// \brief Base class that describes a preprocessed entity, which may be a
/// preprocessor directive or macro expansion.
@@ -78,11 +91,11 @@ namespace clang {
SourceRange Range;
protected:
- PreprocessedEntity(EntityKind Kind, SourceRange Range)
- : Kind(Kind), Range(Range) { }
-
friend class PreprocessingRecord;
+ PreprocessedEntity(EntityKind Kind, SourceRange Range)
+ : Kind(Kind), Range(Range) {}
+
public:
/// \brief Retrieve the kind of preprocessed entity stored in this object.
EntityKind getKind() const { return Kind; }
@@ -122,7 +135,7 @@ namespace clang {
class PreprocessingDirective : public PreprocessedEntity {
public:
PreprocessingDirective(EntityKind Kind, SourceRange Range)
- : PreprocessedEntity(Kind, Range) { }
+ : PreprocessedEntity(Kind, Range) {}
// Implement isa/cast/dyncast/etc.
static bool classof(const PreprocessedEntity *PD) {
@@ -199,10 +212,13 @@ namespace clang {
enum InclusionKind {
/// \brief An \c \#include directive.
Include,
+
/// \brief An Objective-C \c \#import directive.
Import,
+
/// \brief A GNU \c \#include_next directive.
IncludeNext,
+
/// \brief A Clang \c \#__include_macros directive.
IncludeMacros
};
@@ -316,11 +332,14 @@ namespace clang {
/// value 1 corresponds to element 0 in the local entities vector,
/// value 2 corresponds to element 1 in the local entities vector, etc.
class PPEntityID {
- int ID;
- explicit PPEntityID(int ID) : ID(ID) {}
friend class PreprocessingRecord;
+
+ int ID = 0;
+
+ explicit PPEntityID(int ID) : ID(ID) {}
+
public:
- PPEntityID() : ID(0) {}
+ PPEntityID() = default;
};
static PPEntityID getPPEntityID(unsigned Index, bool isLoaded) {
@@ -331,7 +350,7 @@ namespace clang {
llvm::DenseMap<const MacroInfo *, MacroDefinitionRecord *> MacroDefinitions;
/// \brief External source of preprocessed entities.
- ExternalPreprocessingRecordSource *ExternalSource;
+ ExternalPreprocessingRecordSource *ExternalSource = nullptr;
/// \brief Retrieve the preprocessed entity at the given ID.
PreprocessedEntity *getPreprocessedEntity(PPEntityID PPID);
@@ -371,7 +390,7 @@ namespace clang {
}
/// \brief Deallocate memory in the preprocessing record.
- void Deallocate(void *Ptr) { }
+ void Deallocate(void *Ptr) {}
size_t getTotalMemory() const;
@@ -397,11 +416,12 @@ namespace clang {
iterator, int, std::random_access_iterator_tag,
PreprocessedEntity *, int, PreprocessedEntity *,
PreprocessedEntity *> {
+ friend class PreprocessingRecord;
+
PreprocessingRecord *Self;
iterator(PreprocessingRecord *Self, int Position)
: iterator::iterator_adaptor_base(Position), Self(Self) {}
- friend class PreprocessingRecord;
public:
iterator() : iterator(nullptr, 0) {}
@@ -451,7 +471,6 @@ namespace clang {
/// encompasses.
///
/// \param R the range to look for preprocessed entities.
- ///
llvm::iterator_range<iterator>
getPreprocessedEntitiesInRange(SourceRange R);
@@ -485,6 +504,9 @@ namespace clang {
}
private:
+ friend class ASTReader;
+ friend class ASTWriter;
+
void MacroExpands(const Token &Id, const MacroDefinition &MD,
SourceRange Range, const MacroArgs *Args) override;
void MacroDefined(const Token &Id, const MacroDirective *MD) override;
@@ -500,11 +522,13 @@ namespace clang {
const MacroDefinition &MD) override;
void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
const MacroDefinition &MD) override;
+
/// \brief Hook called whenever the 'defined' operator is seen.
void Defined(const Token &MacroNameTok, const MacroDefinition &MD,
SourceRange Range) override;
- void SourceRangeSkipped(SourceRange Range) override;
+ void SourceRangeSkipped(SourceRange Range,
+ SourceLocation EndifLoc) override;
void addMacroExpansion(const Token &Id, const MacroInfo *MI,
SourceRange Range);
@@ -517,11 +541,9 @@ namespace clang {
} CachedRangeQuery;
std::pair<int, int> getPreprocessedEntitiesInRangeSlow(SourceRange R);
-
- friend class ASTReader;
- friend class ASTWriter;
};
-} // end namespace clang
+
+} // namespace clang
inline void *operator new(size_t bytes, clang::PreprocessingRecord &PR,
unsigned alignment) noexcept {
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index dba4b80f6071..485600f12232 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -1,4 +1,4 @@
-//===--- Preprocessor.h - C Language Family Preprocessor --------*- C++ -*-===//
+//===- Preprocessor.h - C Language Family Preprocessor ----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,10 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-///
+//
/// \file
/// \brief Defines the clang::Preprocessor interface.
-///
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_LEX_PREPROCESSOR_H
@@ -18,48 +18,70 @@
#include "clang/Basic/Builtins.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/Module.h"
#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/TokenKinds.h"
#include "clang/Lex/Lexer.h"
#include "clang/Lex/MacroInfo.h"
+#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"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/TinyPtrVector.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/Registry.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
#include <memory>
+#include <map>
+#include <string>
+#include <utility>
#include <vector>
namespace llvm {
- template<unsigned InternalLen> class SmallString;
-}
+
+template<unsigned InternalLen> class SmallString;
+
+} // namespace llvm
namespace clang {
-class SourceManager;
+class CodeCompletionHandler;
+class CommentHandler;
+class DirectoryEntry;
+class DirectoryLookup;
class ExternalPreprocessorSource;
-class FileManager;
class FileEntry;
+class FileManager;
class HeaderSearch;
+class MacroArgs;
class MemoryBufferCache;
-class PragmaNamespace;
class PragmaHandler;
-class CommentHandler;
-class ScratchBuffer;
-class TargetInfo;
-class PPCallbacks;
-class CodeCompletionHandler;
-class DirectoryLookup;
+class PragmaNamespace;
class PreprocessingRecord;
-class ModuleLoader;
-class PTHManager;
+class PreprocessorLexer;
class PreprocessorOptions;
+class PTHManager;
+class ScratchBuffer;
+class TargetInfo;
/// \brief Stores token information for comparing actual tokens with
/// predefined values. Only handles simple tokens and identifiers.
@@ -75,7 +97,9 @@ public:
assert(!tok::isLiteral(Kind) && "Literals are not supported.");
assert(!tok::isAnnotation(Kind) && "Annotations are not supported.");
}
+
TokenValue(IdentifierInfo *II) : Kind(tok::identifier), II(II) {}
+
bool operator==(const Token &Tok) const {
return Tok.getKind() == Kind &&
(!II || II == Tok.getIdentifierInfo());
@@ -84,9 +108,14 @@ public:
/// \brief Context in which macro name is used.
enum MacroUse {
- MU_Other = 0, // other than #define or #undef
- MU_Define = 1, // macro name specified in #define
- MU_Undef = 2 // macro name specified in #undef
+ // other than #define or #undef
+ MU_Other = 0,
+
+ // macro name specified in #define
+ MU_Define = 1,
+
+ // macro name specified in #undef
+ MU_Undef = 2
};
/// \brief Engages in a tight little dance with the lexer to efficiently
@@ -96,11 +125,14 @@ enum MacroUse {
/// know anything about preprocessor-level issues like the \#include stack,
/// token expansion, etc.
class Preprocessor {
+ friend class VAOptDefinitionContext;
+ friend class VariadicMacroScopeGuard;
+
std::shared_ptr<PreprocessorOptions> PPOpts;
DiagnosticsEngine *Diags;
LangOptions &LangOpts;
- const TargetInfo *Target;
- const TargetInfo *AuxTarget;
+ const TargetInfo *Target = nullptr;
+ const TargetInfo *AuxTarget = nullptr;
FileManager &FileMgr;
SourceManager &SourceMgr;
MemoryBufferCache &PCMCache;
@@ -111,7 +143,6 @@ class Preprocessor {
/// \brief 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;
@@ -130,6 +161,7 @@ class Preprocessor {
IdentifierInfo *Ident_Pragma, *Ident__pragma; // _Pragma, __pragma
IdentifierInfo *Ident__identifier; // __identifier
IdentifierInfo *Ident__VA_ARGS__; // __VA_ARGS__
+ IdentifierInfo *Ident__VA_OPT__; // __VA_OPT__
IdentifierInfo *Ident__has_feature; // __has_feature
IdentifierInfo *Ident__has_extension; // __has_extension
IdentifierInfo *Ident__has_builtin; // __has_builtin
@@ -141,10 +173,17 @@ class Preprocessor {
IdentifierInfo *Ident__building_module; // __building_module
IdentifierInfo *Ident__MODULE__; // __MODULE__
IdentifierInfo *Ident__has_cpp_attribute; // __has_cpp_attribute
+ IdentifierInfo *Ident__has_c_attribute; // __has_c_attribute
IdentifierInfo *Ident__has_declspec; // __has_declspec_attribute
+ IdentifierInfo *Ident__is_target_arch; // __is_target_arch
+ IdentifierInfo *Ident__is_target_vendor; // __is_target_vendor
+ IdentifierInfo *Ident__is_target_os; // __is_target_os
+ IdentifierInfo *Ident__is_target_environment; // __is_target_environment
SourceLocation DATELoc, TIMELoc;
- unsigned CounterValue; // Next __COUNTER__ value.
+
+ // Next __COUNTER__ value, starts at 0.
+ unsigned CounterValue = 0;
enum {
/// \brief Maximum depth of \#includes.
@@ -218,19 +257,19 @@ class Preprocessor {
/// \brief True if we want to ignore EOF token and continue later on (thus
/// avoid tearing the Lexer and etc. down).
- bool IncrementalProcessing;
+ bool IncrementalProcessing = false;
/// The kind of translation unit we are processing.
TranslationUnitKind TUKind;
/// \brief The code-completion handler.
- CodeCompletionHandler *CodeComplete;
+ CodeCompletionHandler *CodeComplete = nullptr;
/// \brief The file that we're performing code-completion for, if any.
- const FileEntry *CodeCompletionFile;
+ const FileEntry *CodeCompletionFile = nullptr;
/// \brief The offset in file for the code-completion point.
- unsigned CodeCompletionOffset;
+ unsigned CodeCompletionOffset = 0;
/// \brief The location for the code-completion point. This gets instantiated
/// when the CodeCompletionFile gets \#include'ed for preprocessing.
@@ -250,11 +289,11 @@ class Preprocessor {
SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> ModuleImportPath;
/// \brief Whether the last token we lexed was an '@'.
- bool LastTokenWasAt;
+ bool LastTokenWasAt = false;
/// \brief Whether the module import expects an identifier next. Otherwise,
/// it expects a '.' or ';'.
- bool ModuleImportExpectsIdentifier;
+ bool ModuleImportExpectsIdentifier = false;
/// \brief The source location of the currently-active
/// \#pragma clang arc_cf_code_audited begin.
@@ -265,16 +304,16 @@ class Preprocessor {
SourceLocation PragmaAssumeNonNullLoc;
/// \brief True if we hit the code-completion point.
- bool CodeCompletionReached;
+ bool CodeCompletionReached = false;
/// \brief The code completion token containing the information
/// on the stem that is to be code completed.
- IdentifierInfo *CodeCompletionII;
+ IdentifierInfo *CodeCompletionII = nullptr;
/// \brief 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).
- const DirectoryEntry *MainFileDir;
+ const DirectoryEntry *MainFileDir = nullptr;
/// \brief The number of bytes that we will initially skip when entering the
/// main file, along with a flag that indicates whether skipping this number
@@ -283,6 +322,26 @@ class Preprocessor {
/// This is used when loading a precompiled preamble.
std::pair<int, bool> SkipMainFilePreamble;
+public:
+ struct PreambleSkipInfo {
+ SourceLocation HashTokenLoc;
+ SourceLocation IfTokenLoc;
+ bool FoundNonSkipPortion;
+ bool FoundElse;
+ SourceLocation ElseLoc;
+
+ PreambleSkipInfo(SourceLocation HashTokenLoc, SourceLocation IfTokenLoc,
+ bool FoundNonSkipPortion, bool FoundElse,
+ SourceLocation ElseLoc)
+ : HashTokenLoc(HashTokenLoc), IfTokenLoc(IfTokenLoc),
+ FoundNonSkipPortion(FoundNonSkipPortion), FoundElse(FoundElse),
+ ElseLoc(ElseLoc) {}
+ };
+
+private:
+ friend class ASTReader;
+ friend class MacroArgs;
+
class PreambleConditionalStackStore {
enum State {
Off = 0,
@@ -291,7 +350,7 @@ class Preprocessor {
};
public:
- PreambleConditionalStackStore() : ConditionalStackState(Off) {}
+ PreambleConditionalStackStore() = default;
void startRecording() { ConditionalStackState = Recording; }
void startReplaying() { ConditionalStackState = Replaying; }
@@ -316,9 +375,15 @@ class Preprocessor {
bool hasRecordedPreamble() const { return !ConditionalStack.empty(); }
+ bool reachedEOFWhileSkipping() const { return SkipInfo.hasValue(); }
+
+ void clearSkipInfo() { SkipInfo.reset(); }
+
+ llvm::Optional<PreambleSkipInfo> SkipInfo;
+
private:
SmallVector<PPConditionalInfo, 4> ConditionalStack;
- State ConditionalStackState;
+ State ConditionalStackState = Off;
} PreambleConditionalStack;
/// \brief The current top of the stack that we're lexing from if
@@ -337,14 +402,14 @@ class Preprocessor {
/// if not expanding a macro.
///
/// This is an alias for either CurLexer or CurPTHLexer.
- PreprocessorLexer *CurPPLexer;
+ PreprocessorLexer *CurPPLexer = nullptr;
/// \brief Used to find the current FileEntry, if CurLexer is non-null
/// and if applicable.
///
/// This allows us to implement \#include_next and find directory-specific
/// properties.
- const DirectoryLookup *CurDirLookup;
+ const DirectoryLookup *CurDirLookup = nullptr;
/// \brief The current macro we are expanding, if we are expanding a macro.
///
@@ -358,11 +423,11 @@ class Preprocessor {
CLK_TokenLexer,
CLK_CachingLexer,
CLK_LexAfterModuleImport
- } CurLexerKind;
+ } CurLexerKind = CLK_Lexer;
/// \brief If the current lexer is for a submodule that is being built, this
/// is that submodule.
- Module *CurLexerSubmodule;
+ Module *CurLexerSubmodule = nullptr;
/// \brief Keeps track of the stack of files currently
/// \#included, and macros currently being expanded from, not counting
@@ -401,27 +466,31 @@ class Preprocessor {
Token Tok;
MacroDefinition MD;
SourceRange Range;
+
MacroExpandsInfo(Token Tok, MacroDefinition MD, SourceRange Range)
- : Tok(Tok), MD(MD), Range(Range) { }
+ : Tok(Tok), MD(MD), Range(Range) {}
};
SmallVector<MacroExpandsInfo, 2> DelayedMacroExpandsCallbacks;
/// Information about a name that has been used to define a module macro.
struct ModuleMacroInfo {
- ModuleMacroInfo(MacroDirective *MD)
- : MD(MD), ActiveModuleMacrosGeneration(0), IsAmbiguous(false) {}
-
/// The most recent macro directive for this identifier.
MacroDirective *MD;
+
/// The active module macros for this identifier.
- llvm::TinyPtrVector<ModuleMacro*> ActiveModuleMacros;
+ llvm::TinyPtrVector<ModuleMacro *> ActiveModuleMacros;
+
/// The generation number at which we last updated ActiveModuleMacros.
/// \see Preprocessor::VisibleModules.
- unsigned ActiveModuleMacrosGeneration;
+ unsigned ActiveModuleMacrosGeneration = 0;
+
/// Whether this macro name is ambiguous.
- bool IsAmbiguous;
+ bool IsAmbiguous = false;
+
/// The module macros that are overridden by this macro.
- llvm::TinyPtrVector<ModuleMacro*> OverriddenMacros;
+ llvm::TinyPtrVector<ModuleMacro *> OverriddenMacros;
+
+ ModuleMacroInfo(MacroDirective *MD) : MD(MD) {}
};
/// The state of a macro for an identifier.
@@ -456,15 +525,18 @@ class Preprocessor {
public:
MacroState() : MacroState(nullptr) {}
MacroState(MacroDirective *MD) : State(MD) {}
+
MacroState(MacroState &&O) noexcept : State(O.State) {
O.State = (MacroDirective *)nullptr;
}
+
MacroState &operator=(MacroState &&O) noexcept {
auto S = O.State;
O.State = (MacroDirective *)nullptr;
State = S;
return *this;
}
+
~MacroState() {
if (auto *Info = State.dyn_cast<ModuleMacroInfo*>())
Info->~ModuleMacroInfo();
@@ -475,6 +547,7 @@ class Preprocessor {
return Info->MD;
return State.get<MacroDirective*>();
}
+
void setLatest(MacroDirective *MD) {
if (auto *Info = State.dyn_cast<ModuleMacroInfo*>())
Info->MD = MD;
@@ -486,6 +559,7 @@ class Preprocessor {
auto *Info = getModuleInfo(PP, II);
return Info ? Info->IsAmbiguous : false;
}
+
ArrayRef<ModuleMacro *>
getActiveModuleMacros(Preprocessor &PP, const IdentifierInfo *II) const {
if (auto *Info = getModuleInfo(PP, II))
@@ -498,7 +572,7 @@ class Preprocessor {
// FIXME: Incorporate module macros into the result of this.
if (auto *Latest = getLatest())
return Latest->findDirectiveAtLoc(Loc, SourceMgr);
- return MacroDirective::DefInfo();
+ return {};
}
void overrideActiveModuleMacros(Preprocessor &PP, IdentifierInfo *II) {
@@ -510,11 +584,13 @@ class Preprocessor {
Info->IsAmbiguous = false;
}
}
+
ArrayRef<ModuleMacro*> getOverriddenMacros() const {
if (auto *Info = State.dyn_cast<ModuleMacroInfo*>())
return Info->OverriddenMacros;
return None;
}
+
void setOverriddenMacros(Preprocessor &PP,
ArrayRef<ModuleMacro *> Overrides) {
auto *Info = State.dyn_cast<ModuleMacroInfo*>();
@@ -537,31 +613,33 @@ class Preprocessor {
/// the reverse order (the latest one is in the head of the list).
///
/// This mapping lives within the \p CurSubmoduleState.
- typedef llvm::DenseMap<const IdentifierInfo *, MacroState> MacroMap;
-
- friend class ASTReader;
+ using MacroMap = llvm::DenseMap<const IdentifierInfo *, MacroState>;
struct SubmoduleState;
/// \brief Information about a submodule that we're currently building.
struct BuildingSubmoduleInfo {
- BuildingSubmoduleInfo(Module *M, SourceLocation ImportLoc, bool IsPragma,
- SubmoduleState *OuterSubmoduleState,
- unsigned OuterPendingModuleMacroNames)
- : M(M), ImportLoc(ImportLoc), IsPragma(IsPragma),
- OuterSubmoduleState(OuterSubmoduleState),
- OuterPendingModuleMacroNames(OuterPendingModuleMacroNames) {}
-
/// The module that we are building.
Module *M;
+
/// The location at which the module was included.
SourceLocation ImportLoc;
+
/// Whether we entered this submodule via a pragma.
bool IsPragma;
+
/// The previous SubmoduleState.
SubmoduleState *OuterSubmoduleState;
+
/// The number of pending module macro names when we started building this.
unsigned OuterPendingModuleMacroNames;
+
+ BuildingSubmoduleInfo(Module *M, SourceLocation ImportLoc, bool IsPragma,
+ SubmoduleState *OuterSubmoduleState,
+ unsigned OuterPendingModuleMacroNames)
+ : M(M), ImportLoc(ImportLoc), IsPragma(IsPragma),
+ OuterSubmoduleState(OuterSubmoduleState),
+ OuterPendingModuleMacroNames(OuterPendingModuleMacroNames) {}
};
SmallVector<BuildingSubmoduleInfo, 8> BuildingSubmoduleStack;
@@ -569,12 +647,14 @@ class Preprocessor {
struct SubmoduleState {
/// The macros for the submodule.
MacroMap Macros;
+
/// The set of modules that are visible within the submodule.
VisibleModuleSet VisibleModules;
+
// FIXME: CounterValue?
// FIXME: PragmaPushMacroInfo?
};
- std::map<Module*, SubmoduleState> Submodules;
+ std::map<Module *, SubmoduleState> Submodules;
/// The preprocessor state for preprocessing outside of any submodule.
SubmoduleState NullSubmoduleState;
@@ -587,11 +667,11 @@ class Preprocessor {
llvm::FoldingSet<ModuleMacro> ModuleMacros;
/// The names of potential module macros that we've not yet processed.
- llvm::SmallVector<const IdentifierInfo*, 32> PendingModuleMacroNames;
+ llvm::SmallVector<const IdentifierInfo *, 32> PendingModuleMacroNames;
/// The list of module macros, for each identifier, that are not overridden by
/// any other module macro.
- llvm::DenseMap<const IdentifierInfo *, llvm::TinyPtrVector<ModuleMacro*>>
+ llvm::DenseMap<const IdentifierInfo *, llvm::TinyPtrVector<ModuleMacro *>>
LeafModuleMacros;
/// \brief Macros that we want to warn because they are not used at the end
@@ -603,25 +683,35 @@ class Preprocessor {
/// just so that we can report that they are unused, we just warn using
/// the SourceLocations of this set (that will be filled by the ASTReader).
/// We are using SmallPtrSet instead of a vector for faster removal.
- typedef llvm::SmallPtrSet<SourceLocation, 32> WarnUnusedMacroLocsTy;
+ using WarnUnusedMacroLocsTy = llvm::SmallPtrSet<SourceLocation, 32>;
WarnUnusedMacroLocsTy WarnUnusedMacroLocs;
/// \brief A "freelist" of MacroArg objects that can be
/// reused for quick allocation.
- MacroArgs *MacroArgCache;
- friend class MacroArgs;
+ MacroArgs *MacroArgCache = nullptr;
/// For each IdentifierInfo used in a \#pragma push_macro directive,
/// we keep a MacroInfo stack used to restore the previous macro value.
- llvm::DenseMap<IdentifierInfo*, std::vector<MacroInfo*> > PragmaPushMacroInfo;
+ llvm::DenseMap<IdentifierInfo *, std::vector<MacroInfo *>>
+ PragmaPushMacroInfo;
// Various statistics we track for performance analysis.
- unsigned NumDirectives, NumDefined, NumUndefined, NumPragma;
- unsigned NumIf, NumElse, NumEndif;
- unsigned NumEnteredSourceFiles, MaxIncludeStackDepth;
- unsigned NumMacroExpanded, NumFnMacroExpanded, NumBuiltinMacroExpanded;
- unsigned NumFastMacroExpanded, NumTokenPaste, NumFastTokenPaste;
- unsigned NumSkipped;
+ unsigned NumDirectives = 0;
+ unsigned NumDefined = 0;
+ unsigned NumUndefined = 0;
+ unsigned NumPragma = 0;
+ unsigned NumIf = 0;
+ unsigned NumElse = 0;
+ unsigned NumEndif = 0;
+ unsigned NumEnteredSourceFiles = 0;
+ unsigned MaxIncludeStackDepth = 0;
+ unsigned NumMacroExpanded = 0;
+ unsigned NumFnMacroExpanded = 0;
+ unsigned NumBuiltinMacroExpanded = 0;
+ unsigned NumFastMacroExpanded = 0;
+ unsigned NumTokenPaste = 0;
+ unsigned NumFastTokenPaste = 0;
+ unsigned NumSkipped = 0;
/// \brief The predefined macros that preprocessor should use from the
/// command line etc.
@@ -643,17 +733,17 @@ class Preprocessor {
/// going to lex in the cache and when it finishes the tokens are removed
/// from the end of the cache.
SmallVector<Token, 16> MacroExpandedTokens;
- std::vector<std::pair<TokenLexer *, size_t> > MacroExpandingLexersStack;
+ std::vector<std::pair<TokenLexer *, size_t>> MacroExpandingLexersStack;
/// \brief A record of the macro definitions and expansions that
/// occurred during preprocessing.
///
/// This is an optional side structure that can be enabled with
/// \c createPreprocessingRecord() prior to preprocessing.
- PreprocessingRecord *Record;
+ PreprocessingRecord *Record = nullptr;
/// Cached tokens state.
- typedef SmallVector<Token, 1> CachedTokensTy;
+ using CachedTokensTy = SmallVector<Token, 1>;
/// \brief Cached tokens are stored here when we do backtracking or
/// lookahead. They are "lexed" by the CachingLex() method.
@@ -664,7 +754,7 @@ class Preprocessor {
///
/// If it points beyond the CachedTokens vector, it means that a normal
/// Lex() should be invoked.
- CachedTokensTy::size_type CachedLexPos;
+ CachedTokensTy::size_type CachedLexPos = 0;
/// \brief Stack of backtrack positions, allowing nested backtracks.
///
@@ -680,7 +770,7 @@ class Preprocessor {
/// MacroInfos are managed as a chain for easy disposal. This is the head
/// of that list.
- MacroInfoChain *MIChainHead;
+ MacroInfoChain *MIChainHead = nullptr;
void updateOutOfDateIdentifier(IdentifierInfo &II) const;
@@ -853,7 +943,7 @@ public:
MacroDefinition getMacroDefinition(const IdentifierInfo *II) {
if (!II->hasMacroDefinition())
- return MacroDefinition();
+ return {};
MacroState &S = CurSubmoduleState->Macros[II];
auto *MD = S.getLatest();
@@ -867,7 +957,7 @@ public:
MacroDefinition getMacroDefinitionAtLoc(const IdentifierInfo *II,
SourceLocation Loc) {
if (!II->hadMacroDefinition())
- return MacroDefinition();
+ return {};
MacroState &S = CurSubmoduleState->Macros[II];
MacroDirective::DefInfo DI;
@@ -923,6 +1013,7 @@ public:
MacroInfo *MI) {
return appendDefMacroDirective(II, MI, MI->getDefinitionLoc());
}
+
/// \brief Set a MacroDirective that was loaded from a PCH file.
void setLoadedMacroDirective(IdentifierInfo *II, MacroDirective *ED,
MacroDirective *MD);
@@ -946,10 +1037,12 @@ public:
/// Iterators for the macro history table. Currently defined macros have
/// IdentifierInfo::hasMacroDefinition() set and an empty
/// MacroInfo::getUndefLoc() at the head of the list.
- typedef MacroMap::const_iterator macro_iterator;
+ using macro_iterator = MacroMap::const_iterator;
+
macro_iterator macro_begin(bool IncludeExternalMacros = true) const;
macro_iterator macro_end(bool IncludeExternalMacros = true) const;
llvm::iterator_range<macro_iterator>
+
macros(bool IncludeExternalMacros = true) const {
return llvm::make_range(macro_begin(IncludeExternalMacros),
macro_end(IncludeExternalMacros));
@@ -963,6 +1056,7 @@ public:
ArrayRef<TokenValue> Tokens) const;
const std::string &getPredefines() const { return Predefines; }
+
/// \brief Set the predefines for this Preprocessor.
///
/// These predefines are automatically injected when parsing the main file.
@@ -1087,6 +1181,7 @@ public:
bool DisableMacroExpansion) {
EnterTokenStream(Toks.release(), NumToks, DisableMacroExpansion, true);
}
+
void EnterTokenStream(ArrayRef<Token> Toks, bool DisableMacroExpansion) {
EnterTokenStream(Toks.data(), Toks.size(), DisableMacroExpansion, false);
}
@@ -1605,7 +1700,6 @@ private:
llvm::DenseMap<IdentifierInfo*,unsigned> PoisonReasons;
public:
-
/// \brief Specifies the reason for poisoning an identifier.
///
/// If that identifier is accessed while poisoned, then this reason will be
@@ -1655,7 +1749,6 @@ public:
/// lex again.
bool HandleIdentifier(Token &Identifier);
-
/// \brief Callback invoked when the lexer hits the end of the current file.
///
/// This either returns the EOF token and returns true, or
@@ -1760,6 +1853,8 @@ public:
Module *LeaveSubmodule(bool ForPragma);
private:
+ friend void TokenLexer::ExpandFunctionArguments();
+
void PushIncludeMacroStack() {
assert(CurLexerKind != CLK_CachingLexer && "cannot push a caching lexer");
IncludeMacroStack.emplace_back(CurLexerKind, CurLexerSubmodule,
@@ -1818,7 +1913,6 @@ private:
///
/// Either returns a pointer to a MacroInfo object OR emits a diagnostic and
/// returns a nullptr if an invalid sequence of tokens is encountered.
-
MacroInfo *ReadOptionalMacroParameterListAndBody(
const Token &MacroNameTok, bool ImmediatelyAfterHeaderGuard);
@@ -1836,7 +1930,8 @@ private:
/// \p FoundElse is false, then \#else directives are ok, if not, then we have
/// already seen one so a \#else directive is a duplicate. When this returns,
/// the caller can lex the first valid token.
- void SkipExcludedConditionalBlock(SourceLocation IfTokenLoc,
+ void SkipExcludedConditionalBlock(SourceLocation HashTokenLoc,
+ SourceLocation IfTokenLoc,
bool FoundNonSkipPortion, bool FoundElse,
SourceLocation ElseLoc = SourceLocation());
@@ -1848,6 +1943,7 @@ private:
struct DirectiveEvalResult {
/// Whether the expression was evaluated as true or not.
bool Conditional;
+
/// True if the expression contained identifiers that were undefined.
bool IncludedUndefinedIds;
};
@@ -1877,8 +1973,8 @@ private:
/// from the end of the cache.
Token *cacheMacroExpandedTokens(TokenLexer *tokLexer,
ArrayRef<Token> tokens);
+
void removeCachedMacroExpandedTokensOfLastLexer();
- friend void TokenLexer::ExpandFunctionArguments();
/// Determine whether the next preprocessor token to be
/// lexed is a '('. If so, consume the token and return true, if not, this
@@ -1934,17 +2030,21 @@ private:
//===--------------------------------------------------------------------===//
// Caching stuff.
void CachingLex(Token &Result);
+
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();
}
+
void EnterCachingLexMode();
+
void ExitCachingLexMode() {
if (InCachingLexMode())
RemoveTopOfLexerStack();
}
+
const Token &PeekAhead(unsigned N);
void AnnotatePreviousCachedTokens(const Token &Tok);
@@ -2015,9 +2115,15 @@ public:
PreambleConditionalStack.setStack(s);
}
- void setReplayablePreambleConditionalStack(ArrayRef<PPConditionalInfo> s) {
+ void setReplayablePreambleConditionalStack(ArrayRef<PPConditionalInfo> s,
+ llvm::Optional<PreambleSkipInfo> SkipInfo) {
PreambleConditionalStack.startReplaying();
PreambleConditionalStack.setStack(s);
+ PreambleConditionalStack.SkipInfo = SkipInfo;
+ }
+
+ llvm::Optional<PreambleSkipInfo> getPreambleSkipInfo() const {
+ return PreambleConditionalStack.SkipInfo;
}
private:
@@ -2030,16 +2136,18 @@ private:
void HandleUndefDirective();
// Conditional Inclusion.
- void HandleIfdefDirective(Token &Tok, bool isIfndef,
- bool ReadAnyTokensBeforeDirective);
- void HandleIfDirective(Token &Tok, bool ReadAnyTokensBeforeDirective);
+ void HandleIfdefDirective(Token &Tok, const Token &HashToken,
+ bool isIfndef, bool ReadAnyTokensBeforeDirective);
+ void HandleIfDirective(Token &Tok, const Token &HashToken,
+ bool ReadAnyTokensBeforeDirective);
void HandleEndifDirective(Token &Tok);
- void HandleElseDirective(Token &Tok);
- void HandleElifDirective(Token &Tok);
+ void HandleElseDirective(Token &Tok, const Token &HashToken);
+ void HandleElifDirective(Token &Tok, const Token &HashToken);
// Pragmas.
void HandlePragmaDirective(SourceLocation IntroducerLoc,
PragmaIntroducerKind Introducer);
+
public:
void HandlePragmaOnce(Token &OnceTok);
void HandlePragmaMark();
@@ -2073,8 +2181,8 @@ public:
};
/// \brief Registry of pragma handlers added by plugins
-typedef llvm::Registry<PragmaHandler> PragmaHandlerRegistry;
+using PragmaHandlerRegistry = llvm::Registry<PragmaHandler>;
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_LEX_PREPROCESSOR_H
diff --git a/include/clang/Lex/PreprocessorLexer.h b/include/clang/Lex/PreprocessorLexer.h
index 5c2e4d41454b..ff71d11b4511 100644
--- a/include/clang/Lex/PreprocessorLexer.h
+++ b/include/clang/Lex/PreprocessorLexer.h
@@ -1,4 +1,4 @@
-//===--- PreprocessorLexer.h - C Language Family Lexer ----------*- C++ -*-===//
+//===- PreprocessorLexer.h - C Language Family Lexer ------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,10 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-///
+//
/// \file
/// \brief Defines the PreprocessorLexer interface.
-///
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_LEX_PREPROCESSORLEXER_H
@@ -17,8 +17,10 @@
#include "clang/Lex/MultipleIncludeOpt.h"
#include "clang/Lex/Token.h"
+#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
+#include <cassert>
namespace clang {
@@ -27,25 +29,29 @@ class Preprocessor;
class PreprocessorLexer {
virtual void anchor();
+
protected:
- Preprocessor *PP; // Preprocessor object controlling lexing.
+ friend class Preprocessor;
+
+ // Preprocessor object controlling lexing.
+ Preprocessor *PP = nullptr;
/// The SourceManager FileID corresponding to the file being lexed.
const FileID FID;
/// \brief Number of SLocEntries before lexing the file.
- unsigned InitialNumSLocEntries;
+ unsigned InitialNumSLocEntries = 0;
//===--------------------------------------------------------------------===//
// Context-specific lexing flags set by the preprocessor.
//===--------------------------------------------------------------------===//
/// \brief True when parsing \#XXX; turns '\\n' into a tok::eod token.
- bool ParsingPreprocessorDirective;
+ bool ParsingPreprocessorDirective = false;
/// \brief True after \#include; turns \<xx> into a tok::angle_string_literal
/// token.
- bool ParsingFilename;
+ bool ParsingFilename = false;
/// \brief True if in raw mode.
///
@@ -60,7 +66,7 @@ protected:
/// 5. No callbacks are made into the preprocessor.
///
/// Note that in raw mode that the PP pointer may be null.
- bool LexingRawMode;
+ bool LexingRawMode = false;
/// \brief A state machine that detects the \#ifndef-wrapping a file
/// idiom for the multiple-include optimization.
@@ -70,19 +76,9 @@ protected:
/// we are currently in.
SmallVector<PPConditionalInfo, 4> ConditionalStack;
- PreprocessorLexer(const PreprocessorLexer &) = delete;
- void operator=(const PreprocessorLexer &) = delete;
- friend class Preprocessor;
-
+ PreprocessorLexer() : FID() {}
PreprocessorLexer(Preprocessor *pp, FileID fid);
-
- PreprocessorLexer()
- : PP(nullptr), InitialNumSLocEntries(0),
- ParsingPreprocessorDirective(false),
- ParsingFilename(false),
- LexingRawMode(false) {}
-
- virtual ~PreprocessorLexer() {}
+ virtual ~PreprocessorLexer() = default;
virtual void IndirectLex(Token& Result) = 0;
@@ -128,6 +124,8 @@ protected:
unsigned getConditionalStackDepth() const { return ConditionalStack.size(); }
public:
+ PreprocessorLexer(const PreprocessorLexer &) = delete;
+ PreprocessorLexer &operator=(const PreprocessorLexer &) = delete;
//===--------------------------------------------------------------------===//
// Misc. lexing methods.
@@ -168,12 +166,13 @@ public:
/// \brief Iterator that traverses the current stack of preprocessor
/// conditional directives (\#if/\#ifdef/\#ifndef).
- typedef SmallVectorImpl<PPConditionalInfo>::const_iterator
- conditional_iterator;
+ using conditional_iterator =
+ SmallVectorImpl<PPConditionalInfo>::const_iterator;
conditional_iterator conditional_begin() const {
return ConditionalStack.begin();
}
+
conditional_iterator conditional_end() const {
return ConditionalStack.end();
}
@@ -184,6 +183,6 @@ public:
}
};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_LEX_PREPROCESSORLEXER_H
diff --git a/include/clang/Lex/PreprocessorOptions.h b/include/clang/Lex/PreprocessorOptions.h
index d91c665cf1dd..55fc305dc295 100644
--- a/include/clang/Lex/PreprocessorOptions.h
+++ b/include/clang/Lex/PreprocessorOptions.h
@@ -1,4 +1,4 @@
-//===--- PreprocessorOptions.h ----------------------------------*- C++ -*-===//
+//===- PreprocessorOptions.h ------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,30 +10,30 @@
#ifndef LLVM_CLANG_LEX_PREPROCESSOROPTIONS_H_
#define LLVM_CLANG_LEX_PREPROCESSOROPTIONS_H_
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "clang/Basic/LLVM.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
-#include <cassert>
+#include <memory>
#include <set>
#include <string>
#include <utility>
#include <vector>
namespace llvm {
- class MemoryBuffer;
-}
-namespace clang {
+class MemoryBuffer;
+
+} // namespace llvm
-class Preprocessor;
-class LangOptions;
+namespace clang {
/// \brief Enumerate the kinds of standard library that
enum ObjCXXARCStandardLibraryKind {
ARCXX_nolib,
+
/// \brief libc++
ARCXX_libcxx,
+
/// \brief libstdc++
ARCXX_libstdcxx
};
@@ -42,17 +42,17 @@ enum ObjCXXARCStandardLibraryKind {
/// used in preprocessor initialization to InitializePreprocessor().
class PreprocessorOptions {
public:
- std::vector<std::pair<std::string, bool/*isUndef*/> > Macros;
+ std::vector<std::pair<std::string, bool/*isUndef*/>> Macros;
std::vector<std::string> Includes;
std::vector<std::string> MacroIncludes;
/// \brief Initialize the preprocessor with the compiler and target specific
/// predefines.
- unsigned UsePredefines : 1;
+ bool UsePredefines = true;
/// \brief Whether we should maintain a detailed record of all macro
/// definitions and expansions.
- unsigned DetailedRecord : 1;
+ bool DetailedRecord = false;
/// The implicit PCH included at the start of the translation unit, or empty.
std::string ImplicitPCHInclude;
@@ -62,13 +62,13 @@ public:
/// \brief When true, disables most of the normal validation performed on
/// precompiled headers.
- bool DisablePCHValidation;
+ bool DisablePCHValidation = false;
/// \brief When true, a PCH with compiler errors will not be rejected.
- bool AllowPCHWithCompilerErrors;
+ bool AllowPCHWithCompilerErrors = false;
/// \brief Dump declarations that are deserialized from PCH, for testing.
- bool DumpDeserializedPCHDecls;
+ bool DumpDeserializedPCHDecls = false;
/// \brief This is a set of names for decls that we do not want to be
/// deserialized, and we emit an error if they are; for testing purposes.
@@ -86,7 +86,7 @@ public:
/// When the lexer is done, one of the things that need to be preserved is the
/// conditional #if stack, so the ASTWriter/ASTReader can save/restore it when
/// processing the rest of the file.
- bool GeneratePreamble;
+ bool GeneratePreamble = false;
/// The implicit PTH input included at the start of the translation unit, or
/// empty.
@@ -107,7 +107,7 @@ public:
/// \brief True if the SourceManager should report the original file name for
/// contents of files that were remapped to other files. Defaults to true.
- bool RemappedFilesKeepOriginalName;
+ bool RemappedFilesKeepOriginalName = true;
/// \brief The set of file remappings, which take existing files on
/// the system (the first part of each pair) and gives them the
@@ -126,12 +126,12 @@ public:
/// This flag defaults to false; it can be set true only through direct
/// manipulation of the compiler invocation object, in cases where the
/// compiler invocation and its buffers will be reused.
- bool RetainRemappedFileBuffers;
+ bool RetainRemappedFileBuffers = false;
/// \brief The Objective-C++ ARC standard library that we should support,
/// by providing appropriate definitions to retrofit the standard library
/// with support for lifetime-qualified pointers.
- ObjCXXARCStandardLibraryKind ObjCXXARCStandardLibrary;
+ ObjCXXARCStandardLibraryKind ObjCXXARCStandardLibrary = ARCXX_nolib;
/// \brief Records the set of modules
class FailedModulesSet {
@@ -156,18 +156,11 @@ public:
std::shared_ptr<FailedModulesSet> FailedModules;
public:
- PreprocessorOptions() : UsePredefines(true), DetailedRecord(false),
- DisablePCHValidation(false),
- AllowPCHWithCompilerErrors(false),
- DumpDeserializedPCHDecls(false),
- PrecompiledPreambleBytes(0, true),
- GeneratePreamble(false),
- RemappedFilesKeepOriginalName(true),
- RetainRemappedFileBuffers(false),
- ObjCXXARCStandardLibrary(ARCXX_nolib) { }
+ PreprocessorOptions() : PrecompiledPreambleBytes(0, false) {}
void addMacroDef(StringRef Name) { Macros.emplace_back(Name, false); }
void addMacroUndef(StringRef Name) { Macros.emplace_back(Name, true); }
+
void addRemappedFile(StringRef From, StringRef To) {
RemappedFiles.emplace_back(From, To);
}
@@ -195,10 +188,10 @@ public:
LexEditorPlaceholders = true;
RetainRemappedFileBuffers = true;
PrecompiledPreambleBytes.first = 0;
- PrecompiledPreambleBytes.second = 0;
+ PrecompiledPreambleBytes.second = false;
}
};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_LEX_PREPROCESSOROPTIONS_H_
diff --git a/include/clang/Lex/TokenLexer.h b/include/clang/Lex/TokenLexer.h
index fdeed44d8f9b..b8b0beabf2ba 100644
--- a/include/clang/Lex/TokenLexer.h
+++ b/include/clang/Lex/TokenLexer.h
@@ -1,4 +1,4 @@
-//===--- TokenLexer.h - Lex from a token buffer -----------------*- C++ -*-===//
+//===- TokenLexer.h - Lex from a token buffer -------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,29 +15,31 @@
#define LLVM_CLANG_LEX_TOKENLEXER_H
#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/ArrayRef.h"
namespace clang {
- class MacroInfo;
- class Preprocessor;
- class Token;
- class MacroArgs;
+
+class MacroArgs;
+class MacroInfo;
+class Preprocessor;
+class Token;
+class VAOptExpansionContext;
/// TokenLexer - This implements a lexer that returns tokens from a macro body
/// or token stream instead of lexing from a character buffer. This is used for
/// macro expansion and _Pragma handling, for example.
-///
class TokenLexer {
+ friend class Preprocessor;
+
/// Macro - The macro we are expanding from. This is null if expanding a
/// token stream.
- ///
- MacroInfo *Macro;
+ MacroInfo *Macro = nullptr;
/// ActualArgs - The actual arguments specified for a function-like macro, or
/// null. The TokenLexer owns the pointed-to object.
- MacroArgs *ActualArgs;
+ MacroArgs *ActualArgs = nullptr;
/// PP - The current preprocessor object we are expanding for.
- ///
Preprocessor &PP;
/// Tokens - This is the pointer to an array of tokens that the macro is
@@ -49,15 +51,12 @@ class TokenLexer {
/// Note that if it points into Preprocessor's cache buffer, the Preprocessor
/// may update the pointer as needed.
const Token *Tokens;
- friend class Preprocessor;
/// NumTokens - This is the length of the Tokens array.
- ///
unsigned NumTokens;
- /// CurToken - This is the next token that Lex will return.
- ///
- unsigned CurToken;
+ /// 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.
@@ -73,6 +72,7 @@ class TokenLexer {
/// \brief Location of the macro definition.
SourceLocation MacroDefStart;
+
/// \brief Length of the macro definition.
unsigned MacroDefLength;
@@ -99,8 +99,6 @@ class TokenLexer {
/// should not be subject to further macro expansion.
bool DisableMacroExpansion : 1;
- TokenLexer(const TokenLexer &) = delete;
- void operator=(const TokenLexer &) = delete;
public:
/// Create a TokenLexer for the specified macro with the specified actual
/// arguments. Note that this ctor takes ownership of the ActualArgs pointer.
@@ -108,26 +106,30 @@ public:
/// identifier for an object-like macro.
TokenLexer(Token &Tok, SourceLocation ILEnd, MacroInfo *MI,
MacroArgs *ActualArgs, Preprocessor &pp)
- : Macro(nullptr), ActualArgs(nullptr), PP(pp), OwnsTokens(false) {
+ : PP(pp), OwnsTokens(false) {
Init(Tok, ILEnd, MI, ActualArgs);
}
- /// Init - 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);
-
/// Create a TokenLexer for the specified token stream. If 'OwnsTokens' is
/// specified, this takes ownership of the tokens and delete[]'s them when
/// the token lexer is empty.
TokenLexer(const Token *TokArray, unsigned NumToks, bool DisableExpansion,
bool ownsTokens, Preprocessor &pp)
- : Macro(nullptr), ActualArgs(nullptr), PP(pp), OwnsTokens(false) {
+ : PP(pp), OwnsTokens(false) {
Init(TokArray, NumToks, DisableExpansion, ownsTokens);
}
+ TokenLexer(const TokenLexer &) = delete;
+ TokenLexer &operator=(const TokenLexer &) = delete;
+ ~TokenLexer() { destroy(); }
+
+ /// Init - 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);
+
/// Init - Initialize this TokenLexer with the specified token stream.
/// This does not take ownership of the specified token vector.
///
@@ -136,8 +138,6 @@ public:
void Init(const Token *TokArray, unsigned NumToks,
bool DisableMacroExpansion, bool OwnsTokens);
- ~TokenLexer() { destroy(); }
-
/// isNextTokenLParen - 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.
@@ -156,15 +156,54 @@ private:
/// isAtEnd - Return true if the next lex call will pop this macro off the
/// include stack.
bool isAtEnd() const {
- return CurToken == NumTokens;
+ return CurTokenIdx == NumTokens;
}
- /// PasteTokens - Tok is the LHS of a ## operator, and CurToken is the ##
- /// operator. Read the ## and RHS, and paste the LHS/RHS together. If there
- /// are is another ## after it, chomp it iteratively. Return the result as
- /// Tok. If this returns true, the caller should immediately return the
+ /// Concatenates the next (sub-)sequence of \p Tokens separated by '##'
+ /// starting with LHSTok - stopping when we encounter a token that is neither
+ /// '##' nor preceded by '##'. Places the result back into \p LHSTok and sets
+ /// \p CurIdx to point to the token following the last one that was pasted.
+ ///
+ /// Also performs the MSVC extension wide-literal token pasting involved with:
+ /// \code L #macro-arg. \endcode
+ ///
+ /// \param[in,out] LHSTok - Contains the token to the left of '##' in \p
+ /// Tokens upon entry and will contain the resulting concatenated Token upon
+ /// exit.
+ ///
+ /// \param[in] TokenStream - The stream of Tokens we are lexing from.
+ ///
+ /// \param[in,out] CurIdx - Upon entry, \pTokens[\pCurIdx] must equal '##'
+ /// (with the exception of the MSVC extension mentioned above). Upon exit, it
+ /// is set to the index of the token following the last token that was
+ /// concatenated together.
+ ///
+ /// \returns If this returns true, the caller should immediately return the
/// token.
- bool PasteTokens(Token &Tok);
+ bool pasteTokens(Token &LHSTok, ArrayRef<Token> TokenStream,
+ unsigned int &CurIdx);
+
+ /// Calls pasteTokens above, passing in the '*this' object's Tokens and
+ /// CurTokenIdx data members.
+ bool pasteTokens(Token &Tok);
+
+
+ /// Takes the tail sequence of tokens within ReplacementToks that represent
+ /// the just expanded __VA_OPT__ tokens (possibly zero tokens) and transforms
+ /// 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
+ /// (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.
+ ///
+ /// \param[in] VCtx - contains relevent contextual information about the
+ /// state of the tokens around and including the __VA_OPT__ token, necessary
+ /// for stringification.
+ void stringifyVAOPTContents(SmallVectorImpl<Token> &ReplacementToks,
+ const VAOptExpansionContext &VCtx,
+ SourceLocation VAOPTClosingParenLoc);
/// Expand the arguments of a function-like macro so that we can quickly
/// return preexpanded tokens from Tokens.
@@ -200,6 +239,6 @@ private:
void PropagateLineStartLeadingSpaceInfo(Token &Result);
};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_LEX_TOKENLEXER_H
diff --git a/include/clang/Lex/VariadicMacroSupport.h b/include/clang/Lex/VariadicMacroSupport.h
new file mode 100644
index 000000000000..cebaf15187de
--- /dev/null
+++ b/include/clang/Lex/VariadicMacroSupport.h
@@ -0,0 +1,226 @@
+//===- VariadicMacroSupport.h - state machines and scope guards -*- 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 support types to help with preprocessing variadic macro
+// (i.e. macros that use: ellipses __VA_ARGS__ ) definitions and
+// expansions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LEX_VARIADICMACROSUPPORT_H
+#define LLVM_CLANG_LEX_VARIADICMACROSUPPORT_H
+
+#include "clang/Lex/Preprocessor.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+ class Preprocessor;
+
+ /// An RAII class that tracks when the Preprocessor starts and stops lexing
+ /// the definition of a (ISO C/C++) variadic macro. As an example, this is
+ /// useful for unpoisoning and repoisoning certain identifiers (such as
+ /// __VA_ARGS__) that are only allowed in this context. Also, being a friend
+ /// of the Preprocessor class allows it to access PP's cached identifiers
+ /// directly (as opposed to performing a lookup each time).
+ class VariadicMacroScopeGuard {
+ const Preprocessor &PP;
+ IdentifierInfo *const Ident__VA_ARGS__;
+ IdentifierInfo *const Ident__VA_OPT__;
+
+ public:
+ VariadicMacroScopeGuard(const Preprocessor &P)
+ : PP(P), Ident__VA_ARGS__(PP.Ident__VA_ARGS__),
+ Ident__VA_OPT__(PP.Ident__VA_OPT__) {
+ assert(Ident__VA_ARGS__->isPoisoned() && "__VA_ARGS__ should be poisoned "
+ "outside an ISO C/C++ variadic "
+ "macro definition!");
+ assert(
+ !Ident__VA_OPT__ ||
+ (Ident__VA_OPT__->isPoisoned() && "__VA_OPT__ should be poisoned!"));
+ }
+
+ /// Client code should call this function just before the Preprocessor is
+ /// about to Lex tokens from the definition of a variadic (ISO C/C++) macro.
+ void enterScope() {
+ Ident__VA_ARGS__->setIsPoisoned(false);
+ if (Ident__VA_OPT__)
+ Ident__VA_OPT__->setIsPoisoned(false);
+ }
+
+ /// Client code should call this function as soon as the Preprocessor has
+ /// either completed lexing the macro's definition tokens, or an error
+ /// occured and the context is being exited. This function is idempotent
+ /// (might be explicitly called, and then reinvoked via the destructor).
+ void exitScope() {
+ Ident__VA_ARGS__->setIsPoisoned(true);
+ if (Ident__VA_OPT__)
+ Ident__VA_OPT__->setIsPoisoned(true);
+ }
+
+ ~VariadicMacroScopeGuard() { exitScope(); }
+ };
+
+ /// \brief A class for tracking whether we're inside a VA_OPT during a
+ /// traversal of the tokens of a variadic macro definition.
+ class VAOptDefinitionContext {
+ /// Contains all the locations of so far unmatched lparens.
+ SmallVector<SourceLocation, 8> UnmatchedOpeningParens;
+
+ const IdentifierInfo *const Ident__VA_OPT__;
+
+
+ public:
+ VAOptDefinitionContext(Preprocessor &PP)
+ : Ident__VA_OPT__(PP.Ident__VA_OPT__) {}
+
+ bool isVAOptToken(const Token &T) const {
+ return Ident__VA_OPT__ && T.getIdentifierInfo() == Ident__VA_OPT__;
+ }
+
+ /// Returns true if we have seen the __VA_OPT__ and '(' but before having
+ /// seen the matching ')'.
+ bool isInVAOpt() const { return UnmatchedOpeningParens.size(); }
+
+ /// Call this function as soon as you see __VA_OPT__ and '('.
+ void sawVAOptFollowedByOpeningParens(const SourceLocation LParenLoc) {
+ assert(!isInVAOpt() && "Must NOT be within VAOPT context to call this");
+ UnmatchedOpeningParens.push_back(LParenLoc);
+
+ }
+
+ SourceLocation getUnmatchedOpeningParenLoc() const {
+ assert(isInVAOpt() && "Must be within VAOPT context to call this");
+ return UnmatchedOpeningParens.back();
+ }
+
+ /// Call this function each time an rparen is seen. It returns true only if
+ /// the rparen that was just seen was the eventual (non-nested) closing
+ /// paren for VAOPT, and ejects us out of the VAOPT context.
+ bool sawClosingParen() {
+ assert(isInVAOpt() && "Must be within VAOPT context to call this");
+ UnmatchedOpeningParens.pop_back();
+ return !UnmatchedOpeningParens.size();
+ }
+
+ /// Call this function each time an lparen is seen.
+ void sawOpeningParen(SourceLocation LParenLoc) {
+ assert(isInVAOpt() && "Must be within VAOPT context to call this");
+ UnmatchedOpeningParens.push_back(LParenLoc);
+ }
+
+ };
+
+ /// \brief A class for tracking whether we're inside a VA_OPT during a
+ /// traversal of the tokens of a macro during macro expansion.
+ class VAOptExpansionContext : VAOptDefinitionContext {
+
+ Token SyntheticEOFToken;
+
+ // The (spelling) location of the current __VA_OPT__ in the replacement list
+ // of the function-like macro being expanded.
+ SourceLocation VAOptLoc;
+
+ // NumOfTokensPriorToVAOpt : when != -1, contains the index *of* the first
+ // token of the current VAOPT contents (so we know where to start eager
+ // token-pasting and stringification) *within* the substituted tokens of
+ // the function-like macro's new replacement list.
+ int NumOfTokensPriorToVAOpt = -1;
+
+ unsigned LeadingSpaceForStringifiedToken : 1;
+
+ unsigned StringifyBefore : 1;
+ unsigned CharifyBefore : 1;
+
+
+ bool hasStringifyBefore() const {
+ assert(!isReset() &&
+ "Must only be called if the state has not been reset");
+ return StringifyBefore;
+ }
+
+ bool isReset() const {
+ return NumOfTokensPriorToVAOpt == -1 ||
+ VAOptLoc.isInvalid();
+ }
+
+ public:
+ VAOptExpansionContext(Preprocessor &PP)
+ : VAOptDefinitionContext(PP), LeadingSpaceForStringifiedToken(false),
+ StringifyBefore(false), CharifyBefore(false) {
+ SyntheticEOFToken.startToken();
+ SyntheticEOFToken.setKind(tok::eof);
+ }
+
+ void reset() {
+ VAOptLoc = SourceLocation();
+ NumOfTokensPriorToVAOpt = -1;
+ LeadingSpaceForStringifiedToken = false;
+ StringifyBefore = false;
+ CharifyBefore = false;
+ }
+
+ const Token &getEOFTok() const { return SyntheticEOFToken; }
+
+ void sawHashOrHashAtBefore(const bool HasLeadingSpace,
+ const bool IsHashAt) {
+
+ StringifyBefore = !IsHashAt;
+ CharifyBefore = IsHashAt;
+ LeadingSpaceForStringifiedToken = HasLeadingSpace;
+ }
+
+
+
+ bool hasCharifyBefore() const {
+ assert(!isReset() &&
+ "Must only be called if the state has not been reset");
+ return CharifyBefore;
+ }
+ bool hasStringifyOrCharifyBefore() const {
+ return hasStringifyBefore() || hasCharifyBefore();
+ }
+
+ unsigned int getNumberOfTokensPriorToVAOpt() const {
+ assert(!isReset() &&
+ "Must only be called if the state has not been reset");
+ return NumOfTokensPriorToVAOpt;
+ }
+
+ bool getLeadingSpaceForStringifiedToken() const {
+ assert(hasStringifyBefore() &&
+ "Must only be called if this has been marked for stringification");
+ return LeadingSpaceForStringifiedToken;
+ }
+
+ void sawVAOptFollowedByOpeningParens(const SourceLocation VAOptLoc,
+ const unsigned int NumPriorTokens) {
+ assert(VAOptLoc.isFileID() && "Must not come from a macro expansion");
+ assert(isReset() && "Must only be called if the state has been reset");
+ VAOptDefinitionContext::sawVAOptFollowedByOpeningParens(SourceLocation());
+ this->VAOptLoc = VAOptLoc;
+ NumOfTokensPriorToVAOpt = NumPriorTokens;
+ assert(NumOfTokensPriorToVAOpt > -1 &&
+ "Too many prior tokens");
+ }
+
+ SourceLocation getVAOptLoc() const {
+ assert(!isReset() &&
+ "Must only be called if the state has not been reset");
+ assert(VAOptLoc.isValid() && "__VA_OPT__ location must be valid");
+ return VAOptLoc;
+ }
+ using VAOptDefinitionContext::isVAOptToken;
+ using VAOptDefinitionContext::isInVAOpt;
+ using VAOptDefinitionContext::sawClosingParen;
+ using VAOptDefinitionContext::sawOpeningParen;
+
+ };
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Parse/ParseAST.h b/include/clang/Parse/ParseAST.h
index 21f9701c3ed8..34c96816ebdf 100644
--- a/include/clang/Parse/ParseAST.h
+++ b/include/clang/Parse/ParseAST.h
@@ -29,10 +29,13 @@ namespace clang {
/// This operation inserts the parsed decls into the translation
/// unit held by Ctx.
///
+ /// \param PrintStats Whether to print LLVM statistics related to parsing.
/// \param TUKind The kind of translation unit being parsed.
- ///
/// \param CompletionConsumer If given, an object to consume code completion
/// results.
+ /// \param SkipFunctionBodies Whether to skip parsing of function bodies.
+ /// This option can be used, for example, to speed up searches for
+ /// declarations/definitions when indexing.
void ParseAST(Preprocessor &pp, ASTConsumer *C,
ASTContext &Ctx, bool PrintStats = false,
TranslationUnitKind TUKind = TU_Complete,
@@ -43,7 +46,7 @@ namespace clang {
/// abstract syntax tree.
void ParseAST(Sema &S, bool PrintStats = false,
bool SkipFunctionBodies = false);
-
+
} // end namespace clang
#endif
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index 21d699ec402e..396b5a9aa394 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -253,6 +253,10 @@ class Parser : public CodeCompletionHandler {
/// be NULL.
bool ParsingInObjCContainer;
+ /// Whether to skip parsing of function bodies.
+ ///
+ /// This option can be used, for example, to speed up searches for
+ /// declarations/definitions when indexing.
bool SkipFunctionBodies;
/// The location of the expression statement that is being parsed right now.
@@ -334,6 +338,27 @@ public:
return true;
}
+ /// ConsumeAnyToken - Dispatch to the right Consume* method based on the
+ /// current token type. This should only be used in cases where the type of
+ /// the token really isn't known, e.g. in error recovery.
+ SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok = false) {
+ if (isTokenParen())
+ return ConsumeParen();
+ if (isTokenBracket())
+ return ConsumeBracket();
+ if (isTokenBrace())
+ return ConsumeBrace();
+ if (isTokenStringLiteral())
+ return ConsumeStringToken();
+ if (Tok.is(tok::code_completion))
+ return ConsumeCodeCompletionTok ? ConsumeCodeCompletionToken()
+ : handleUnexpectedCodeCompletionToken();
+ if (Tok.isAnnotation())
+ return ConsumeAnnotationToken();
+ return ConsumeToken();
+ }
+
+
SourceLocation getEndOfPreviousToken() {
return PP.getLocForEndOfToken(PrevTokLocation);
}
@@ -384,26 +409,6 @@ private:
PP.EnterToken(Next);
}
- /// ConsumeAnyToken - Dispatch to the right Consume* method based on the
- /// current token type. This should only be used in cases where the type of
- /// the token really isn't known, e.g. in error recovery.
- SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok = false) {
- if (isTokenParen())
- return ConsumeParen();
- if (isTokenBracket())
- return ConsumeBracket();
- if (isTokenBrace())
- return ConsumeBrace();
- if (isTokenStringLiteral())
- return ConsumeStringToken();
- if (Tok.is(tok::code_completion))
- return ConsumeCodeCompletionTok ? ConsumeCodeCompletionToken()
- : handleUnexpectedCodeCompletionToken();
- if (Tok.isAnnotation())
- return ConsumeAnnotationToken();
- return ConsumeToken();
- }
-
SourceLocation ConsumeAnnotationToken() {
assert(Tok.isAnnotation() && "wrong consume method");
SourceLocation Loc = Tok.getLocation();
@@ -501,6 +506,12 @@ private:
Kind == tok::annot_module_end || Kind == tok::annot_module_include;
}
+ /// \brief Checks if the \p Level is valid for use in a fold expression.
+ bool isFoldOperator(prec::Level Level) const;
+
+ /// \brief Checks if the \p Kind is a valid operator for fold expressions.
+ bool isFoldOperator(tok::TokenKind Kind) const;
+
/// \brief Initialize all pragma handlers.
void initializePragmaHandlers();
@@ -1470,7 +1481,6 @@ public:
ExprResult ParseMSAsmIdentifier(llvm::SmallVectorImpl<Token> &LineToks,
unsigned &NumLineToksConsumed,
- void *Info,
bool IsUnevaluated);
private:
@@ -1517,9 +1527,10 @@ private:
typedef SmallVector<SourceLocation, 20> CommaLocsTy;
/// ParseExpressionList - Used for C/C++ (argument-)expression-list.
- bool ParseExpressionList(SmallVectorImpl<Expr *> &Exprs,
- SmallVectorImpl<SourceLocation> &CommaLocs,
- std::function<void()> Completer = nullptr);
+ bool ParseExpressionList(
+ SmallVectorImpl<Expr *> &Exprs,
+ SmallVectorImpl<SourceLocation> &CommaLocs,
+ llvm::function_ref<void()> Completer = llvm::function_ref<void()>());
/// ParseSimpleExpressionList - A simple comma-separated list of expressions,
/// used for misc language extensions.
@@ -2159,18 +2170,25 @@ public:
private:
void ParseBlockId(SourceLocation CaretLoc);
- // Check for the start of a C++11 attribute-specifier-seq in a context where
- // an attribute is not allowed.
+ /// Are [[]] attributes enabled?
+ bool standardAttributesAllowed() const {
+ const LangOptions &LO = getLangOpts();
+ return LO.DoubleSquareBracketAttributes;
+ }
+
+ // Check for the start of an attribute-specifier-seq in a context where an
+ // attribute is not allowed.
bool CheckProhibitedCXX11Attribute() {
assert(Tok.is(tok::l_square));
- if (!getLangOpts().CPlusPlus11 || NextToken().isNot(tok::l_square))
+ if (!standardAttributesAllowed() || NextToken().isNot(tok::l_square))
return false;
return DiagnoseProhibitedCXX11Attribute();
}
+
bool DiagnoseProhibitedCXX11Attribute();
void CheckMisplacedCXX11Attribute(ParsedAttributesWithRange &Attrs,
SourceLocation CorrectLocation) {
- if (!getLangOpts().CPlusPlus11)
+ if (!standardAttributesAllowed())
return;
if ((Tok.isNot(tok::l_square) || NextToken().isNot(tok::l_square)) &&
Tok.isNot(tok::kw_alignas))
@@ -2190,17 +2208,18 @@ private:
}
void DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs);
- // Forbid C++11 attributes that appear on certain syntactic
- // locations which standard permits but we don't supported yet,
- // for example, attributes appertain to decl specifiers.
+ // Forbid C++11 and C2x attributes that appear on certain syntactic locations
+ // which standard permits but we don't supported yet, for example, attributes
+ // appertain to decl specifiers.
void ProhibitCXX11Attributes(ParsedAttributesWithRange &Attrs,
unsigned DiagID);
- /// \brief Skip C++11 attributes and return the end location of the last one.
+ /// \brief Skip C++11 and C2x attributes and return the end location of the
+ /// last one.
/// \returns SourceLocation() if there are no attributes.
SourceLocation SkipCXX11Attributes();
- /// \brief Diagnose and skip C++11 attributes that appear in syntactic
+ /// \brief Diagnose and skip C++11 and C2x attributes that appear in syntactic
/// locations where attributes are not allowed.
void DiagnoseAndSkipCXX11Attributes();
@@ -2250,7 +2269,7 @@ private:
AttributeList::Syntax Syntax);
void MaybeParseCXX11Attributes(Declarator &D) {
- if (getLangOpts().CPlusPlus11 && isCXX11AttributeSpecifier()) {
+ if (standardAttributesAllowed() && isCXX11AttributeSpecifier()) {
ParsedAttributesWithRange attrs(AttrFactory);
SourceLocation endLoc;
ParseCXX11Attributes(attrs, &endLoc);
@@ -2259,7 +2278,7 @@ private:
}
void MaybeParseCXX11Attributes(ParsedAttributes &attrs,
SourceLocation *endLoc = nullptr) {
- if (getLangOpts().CPlusPlus11 && isCXX11AttributeSpecifier()) {
+ if (standardAttributesAllowed() && isCXX11AttributeSpecifier()) {
ParsedAttributesWithRange attrsWithRange(AttrFactory);
ParseCXX11Attributes(attrsWithRange, endLoc);
attrs.takeAllFrom(attrsWithRange);
@@ -2268,8 +2287,8 @@ private:
void MaybeParseCXX11Attributes(ParsedAttributesWithRange &attrs,
SourceLocation *endLoc = nullptr,
bool OuterMightBeMessageSend = false) {
- if (getLangOpts().CPlusPlus11 &&
- isCXX11AttributeSpecifier(false, OuterMightBeMessageSend))
+ if (standardAttributesAllowed() &&
+ isCXX11AttributeSpecifier(false, OuterMightBeMessageSend))
ParseCXX11Attributes(attrs, endLoc);
}
@@ -2277,8 +2296,8 @@ private:
SourceLocation *EndLoc = nullptr);
void ParseCXX11Attributes(ParsedAttributesWithRange &attrs,
SourceLocation *EndLoc = nullptr);
- /// \brief Parses a C++-style attribute argument list. Returns true if this
- /// results in adding an attribute to the ParsedAttributes list.
+ /// \brief Parses a C++11 (or C2x)-style attribute argument list. Returns true
+ /// if this results in adding an attribute to the ParsedAttributes list.
bool ParseCXX11AttributeArgs(IdentifierInfo *AttrName,
SourceLocation AttrNameLoc,
ParsedAttributes &Attrs, SourceLocation *EndLoc,
@@ -2608,6 +2627,9 @@ private:
Decl *TagDecl = nullptr);
/// \brief Parse 'omp declare reduction' construct.
DeclGroupPtrTy ParseOpenMPDeclareReductionDirective(AccessSpecifier AS);
+ /// Parses initializer for provided omp_priv declaration inside the reduction
+ /// initializer.
+ void ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm);
/// \brief Parses simple list of variables.
///
@@ -2720,11 +2742,11 @@ private:
AccessSpecifier AS=AS_none,
AttributeList *AccessAttrs = nullptr);
bool ParseTemplateParameters(unsigned Depth,
- SmallVectorImpl<Decl*> &TemplateParams,
+ SmallVectorImpl<NamedDecl *> &TemplateParams,
SourceLocation &LAngleLoc,
SourceLocation &RAngleLoc);
bool ParseTemplateParameterList(unsigned Depth,
- SmallVectorImpl<Decl*> &TemplateParams);
+ SmallVectorImpl<NamedDecl*> &TemplateParams);
bool isStartOfTemplateTypeParameter();
Decl *ParseTemplateParameter(unsigned Depth, unsigned Position);
Decl *ParseTypeParameter(unsigned Depth, unsigned Position);
@@ -2766,7 +2788,7 @@ private:
//===--------------------------------------------------------------------===//
// Modules
DeclGroupPtrTy ParseModuleDecl();
- DeclGroupPtrTy ParseModuleImport(SourceLocation AtLoc);
+ Decl *ParseModuleImport(SourceLocation AtLoc);
bool parseMisplacedModuleImport();
bool tryParseMisplacedModuleImport() {
tok::TokenKind Kind = Tok.getKind();
diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h
index 6bdd9d5fcdb6..4e806116c4d9 100644
--- a/include/clang/Sema/AttributeList.h
+++ b/include/clang/Sema/AttributeList.h
@@ -100,16 +100,20 @@ public:
AS_GNU,
/// [[...]]
AS_CXX11,
+ /// [[...]]
+ AS_C2x,
/// __declspec(...)
AS_Declspec,
/// [uuid("...")] class Foo
AS_Microsoft,
/// __ptr16, alignas(...), etc.
AS_Keyword,
- /// Context-sensitive version of a keyword attribute.
- AS_ContextSensitiveKeyword,
/// #pragma ...
AS_Pragma,
+ // Note TableGen depends on the order above. Do not add or change the order
+ // without adding related code to TableGen/ClangAttrEmitter.cpp.
+ /// Context-sensitive version of a keyword attribute.
+ AS_ContextSensitiveKeyword,
};
private:
@@ -376,6 +380,9 @@ public:
bool isCXX11Attribute() const {
return SyntaxUsed == AS_CXX11 || isAlignasAttribute();
}
+ bool isC2xAttribute() const {
+ return SyntaxUsed == AS_C2x;
+ }
bool isKeywordAttribute() const {
return SyntaxUsed == AS_Keyword || SyntaxUsed == AS_ContextSensitiveKeyword;
}
@@ -893,50 +900,17 @@ enum AttributeDeclKind {
ExpectedFunction,
ExpectedUnion,
ExpectedVariableOrFunction,
- ExpectedFunctionOrGlobalVar,
- ExpectedFunctionVariableOrObjCInterface,
ExpectedFunctionOrMethod,
- ExpectedParameter,
ExpectedFunctionMethodOrBlock,
- ExpectedFunctionMethodOrClass,
ExpectedFunctionMethodOrParameter,
- ExpectedFunctionMethodOrGlobalVar,
- ExpectedClass,
- ExpectedEnum,
ExpectedVariable,
- ExpectedMethod,
- ExpectedFieldOrGlobalVar,
- ExpectedStruct,
- ExpectedParameterOrTypedef,
- ExpectedVariableOrTypedef,
- ExpectedTLSVar,
ExpectedVariableOrField,
ExpectedVariableFieldOrTag,
ExpectedTypeOrNamespace,
- ExpectedObjectiveCInterface,
- ExpectedMethodOrProperty,
- ExpectedFunctionOrMethodOrProperty,
- ExpectedStructOrUnion,
- ExpectedStructOrUnionOrClass,
- ExpectedType,
- ExpectedObjCInstanceMethod,
- ExpectedObjCInterfaceDeclInitMethod,
ExpectedFunctionVariableOrClass,
- ExpectedFunctionVariableClassOrObjCInterface,
- ExpectedObjectiveCProtocol,
- ExpectedStaticOrTLSVar,
- ExpectedFunctionGlobalVarMethodOrProperty,
- ExpectedStructOrUnionOrTypedef,
- ExpectedStructOrTypedef,
- ExpectedObjectiveCInterfaceOrProtocol,
ExpectedKernelFunction,
ExpectedFunctionWithProtoType,
- ExpectedVariableEnumFieldOrTypedef,
- ExpectedFunctionMethodEnumOrClass,
- ExpectedStructClassVariableFunctionOrInlineNamespace,
ExpectedForMaybeUnused,
- ExpectedEnumOrClass,
- ExpectedNamedDecl,
};
} // end namespace clang
diff --git a/include/clang/Sema/CodeCompleteConsumer.h b/include/clang/Sema/CodeCompleteConsumer.h
index dee53dc14a8c..5d280b5608e7 100644
--- a/include/clang/Sema/CodeCompleteConsumer.h
+++ b/include/clang/Sema/CodeCompleteConsumer.h
@@ -18,6 +18,7 @@
#include "clang/AST/DeclBase.h"
#include "clang/AST/Type.h"
#include "clang/Sema/CodeCompleteOptions.h"
+#include "clang/Sema/DeclSpec.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
@@ -280,6 +281,10 @@ private:
/// \brief The identifiers for Objective-C selector parts.
ArrayRef<IdentifierInfo *> SelIdents;
+ /// \brief The scope specifier that comes before the completion token e.g.
+ /// "a::b::"
+ llvm::Optional<CXXScopeSpec> ScopeSpecifier;
+
public:
/// \brief Construct a new code-completion context of the given kind.
CodeCompletionContext(enum Kind Kind) : Kind(Kind), SelIdents(None) { }
@@ -315,8 +320,20 @@ public:
/// \brief Determines whether we want C++ constructors as results within this
/// context.
bool wantConstructorResults() const;
-};
+ /// \brief Sets the scope specifier that comes before the completion token.
+ /// This is expected to be set in code completions on qualfied specifiers
+ /// (e.g. "a::b::").
+ void setCXXScopeSpecifier(CXXScopeSpec SS) {
+ this->ScopeSpecifier = std::move(SS);
+ }
+
+ llvm::Optional<const CXXScopeSpec *> getCXXScopeSpecifier() {
+ if (ScopeSpecifier)
+ return ScopeSpecifier.getPointer();
+ return llvm::None;
+ }
+};
/// \brief A "string" used to describe how code completion can
/// be performed for an entity.
@@ -777,6 +794,12 @@ public:
CodeCompletionTUInfo &CCTUInfo,
bool IncludeBriefComments);
+ /// \brief 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
+ /// saved into Saved and the returned StringRef will refer to it.
+ StringRef getOrderedName(std::string &Saved) const;
+
private:
void computeCursorKindAndAvailability(bool Accessible = true);
};
@@ -896,8 +919,13 @@ public:
}
/// \brief Whether to include global (top-level) declaration results.
- bool includeGlobals() const {
- return CodeCompleteOpts.IncludeGlobals;
+ bool includeGlobals() const { return CodeCompleteOpts.IncludeGlobals; }
+
+ /// \brief Whether to include declarations in namespace contexts (including
+ /// the global namespace). If this is false, `includeGlobals()` will be
+ /// ignored.
+ bool includeNamespaceLevelDecls() const {
+ return CodeCompleteOpts.IncludeNamespaceLevelDecls;
}
/// \brief Whether to include brief documentation comments within the set of
diff --git a/include/clang/Sema/CodeCompleteOptions.h b/include/clang/Sema/CodeCompleteOptions.h
index fc7713c79571..091d8ca60505 100644
--- a/include/clang/Sema/CodeCompleteOptions.h
+++ b/include/clang/Sema/CodeCompleteOptions.h
@@ -24,15 +24,20 @@ public:
/// Show top-level decls in code completion results.
unsigned IncludeGlobals : 1;
+ /// Show decls in namespace (including the global namespace) in code
+ /// completion results. If this is 0, `IncludeGlobals` will be ignored.
+ ///
+ /// Currently, this only works when completing qualified IDs (i.e.
+ /// `Sema::CodeCompleteQualifiedId`).
+ /// FIXME: consider supporting more completion cases with this option.
+ unsigned IncludeNamespaceLevelDecls : 1;
+
/// Show brief documentation comments in code completion results.
unsigned IncludeBriefComments : 1;
- CodeCompleteOptions() :
- IncludeMacros(0),
- IncludeCodePatterns(0),
- IncludeGlobals(1),
- IncludeBriefComments(0)
- { }
+ CodeCompleteOptions()
+ : IncludeMacros(0), IncludeCodePatterns(0), IncludeGlobals(1),
+ IncludeNamespaceLevelDecls(1), IncludeBriefComments(0) {}
};
} // namespace clang
diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h
index bc817150ab82..760a04d3c8d2 100644
--- a/include/clang/Sema/DeclSpec.h
+++ b/include/clang/Sema/DeclSpec.h
@@ -280,6 +280,7 @@ public:
static const TST TST_half = clang::TST_half;
static const TST TST_float = clang::TST_float;
static const TST TST_double = clang::TST_double;
+ static const TST TST_float16 = clang::TST_Float16;
static const TST TST_float128 = clang::TST_float128;
static const TST TST_bool = clang::TST_bool;
static const TST TST_decimal32 = clang::TST_decimal32;
@@ -360,9 +361,6 @@ private:
// constexpr-specifier
unsigned Constexpr_specified : 1;
- // concept-specifier
- unsigned Concept_specified : 1;
-
union {
UnionParsedType TypeRep;
Decl *DeclRep;
@@ -392,7 +390,7 @@ private:
TQ_unalignedLoc;
SourceLocation FS_inlineLoc, FS_virtualLoc, FS_explicitLoc, FS_noreturnLoc;
SourceLocation FS_forceinlineLoc;
- SourceLocation FriendLoc, ModulePrivateLoc, ConstexprLoc, ConceptLoc;
+ SourceLocation FriendLoc, ModulePrivateLoc, ConstexprLoc;
SourceLocation TQ_pipeLoc;
WrittenBuiltinSpecs writtenBS;
@@ -438,7 +436,6 @@ public:
FS_noreturn_specified(false),
Friend_specified(false),
Constexpr_specified(false),
- Concept_specified(false),
Attrs(attrFactory),
writtenBS(),
ObjCQualifiers(nullptr) {
@@ -696,8 +693,6 @@ public:
unsigned &DiagID);
bool SetConstexprSpec(SourceLocation Loc, const char *&PrevSpec,
unsigned &DiagID);
- bool SetConceptSpec(SourceLocation Loc, const char *&PrevSpec,
- unsigned &DiagID);
bool isFriendSpecified() const { return Friend_specified; }
SourceLocation getFriendSpecLoc() const { return FriendLoc; }
@@ -708,19 +703,11 @@ public:
bool isConstexprSpecified() const { return Constexpr_specified; }
SourceLocation getConstexprSpecLoc() const { return ConstexprLoc; }
- bool isConceptSpecified() const { return Concept_specified; }
- SourceLocation getConceptSpecLoc() const { return ConceptLoc; }
-
void ClearConstexprSpec() {
Constexpr_specified = false;
ConstexprLoc = SourceLocation();
}
- void ClearConceptSpec() {
- Concept_specified = false;
- ConceptLoc = SourceLocation();
- }
-
AttributePool &getAttributePool() const {
return Attrs.getPool();
}
@@ -2008,9 +1995,9 @@ public:
case BlockContext:
case ForContext:
case InitStmtContext:
+ case ConditionContext:
return true;
- case ConditionContext:
case MemberContext:
case PrototypeContext:
case TemplateParamContext:
@@ -2300,6 +2287,42 @@ public:
}
llvm_unreachable("unknown context kind!");
}
+
+ /// Determine whether this declaration appears in a context where an
+ /// expression could appear.
+ bool isExpressionContext() const {
+ switch (Context) {
+ case FileContext:
+ case KNRTypeListContext:
+ case MemberContext:
+ case TypeNameContext: // FIXME: sizeof(...) permits an expression.
+ case FunctionalCastContext:
+ case AliasDeclContext:
+ case AliasTemplateContext:
+ case PrototypeContext:
+ case LambdaExprParameterContext:
+ case ObjCParameterContext:
+ case ObjCResultContext:
+ case TemplateParamContext:
+ case CXXNewContext:
+ case CXXCatchContext:
+ case ObjCCatchContext:
+ case BlockLiteralContext:
+ case LambdaExprContext:
+ case ConversionIdContext:
+ case TrailingReturnContext:
+ return false;
+
+ case BlockContext:
+ case ForContext:
+ case InitStmtContext:
+ case ConditionContext:
+ case TemplateTypeArgContext:
+ return true;
+ }
+
+ llvm_unreachable("unknown context kind!");
+ }
/// \brief Return true if a function declarator at this position would be a
/// function declaration.
diff --git a/include/clang/Sema/Lookup.h b/include/clang/Sema/Lookup.h
index ea32997d4066..546df8842a35 100644
--- a/include/clang/Sema/Lookup.h
+++ b/include/clang/Sema/Lookup.h
@@ -139,6 +139,7 @@ public:
LookupKind(LookupKind),
IDNS(0),
Redecl(Redecl != Sema::NotForRedeclaration),
+ ExternalRedecl(Redecl == Sema::ForExternalRedeclaration),
HideTags(true),
Diagnose(Redecl == Sema::NotForRedeclaration),
AllowHidden(false),
@@ -161,6 +162,7 @@ public:
LookupKind(LookupKind),
IDNS(0),
Redecl(Redecl != Sema::NotForRedeclaration),
+ ExternalRedecl(Redecl == Sema::ForExternalRedeclaration),
HideTags(true),
Diagnose(Redecl == Sema::NotForRedeclaration),
AllowHidden(false),
@@ -181,6 +183,7 @@ public:
LookupKind(Other.LookupKind),
IDNS(Other.IDNS),
Redecl(Other.Redecl),
+ ExternalRedecl(Other.ExternalRedecl),
HideTags(Other.HideTags),
Diagnose(false),
AllowHidden(Other.AllowHidden),
@@ -201,7 +204,9 @@ public:
SemaPtr(std::move(Other.SemaPtr)), NameInfo(std::move(Other.NameInfo)),
NameContextRange(std::move(Other.NameContextRange)),
LookupKind(std::move(Other.LookupKind)), IDNS(std::move(Other.IDNS)),
- Redecl(std::move(Other.Redecl)), HideTags(std::move(Other.HideTags)),
+ Redecl(std::move(Other.Redecl)),
+ ExternalRedecl(std::move(Other.ExternalRedecl)),
+ HideTags(std::move(Other.HideTags)),
Diagnose(std::move(Other.Diagnose)),
AllowHidden(std::move(Other.AllowHidden)),
Shadowed(std::move(Other.Shadowed)) {
@@ -221,6 +226,7 @@ public:
LookupKind = std::move(Other.LookupKind);
IDNS = std::move(Other.IDNS);
Redecl = std::move(Other.Redecl);
+ ExternalRedecl = std::move(Other.ExternalRedecl);
HideTags = std::move(Other.HideTags);
Diagnose = std::move(Other.Diagnose);
AllowHidden = std::move(Other.AllowHidden);
@@ -265,6 +271,17 @@ public:
return Redecl;
}
+ /// True if this lookup is just looking for an existing declaration to link
+ /// against a declaration with external linkage.
+ bool isForExternalRedeclaration() const {
+ return ExternalRedecl;
+ }
+
+ Sema::RedeclarationKind redeclarationKind() const {
+ return ExternalRedecl ? Sema::ForExternalRedeclaration :
+ Redecl ? Sema::ForVisibleRedeclaration : Sema::NotForRedeclaration;
+ }
+
/// \brief Specify whether hidden declarations are visible, e.g.,
/// for recovery reasons.
void setAllowHidden(bool AH) {
@@ -275,7 +292,7 @@ public:
/// declarations, such as those in modules that have not yet been imported.
bool isHiddenDeclarationVisible(NamedDecl *ND) const {
return AllowHidden ||
- (isForRedeclaration() && ND->hasExternalFormalLinkage());
+ (isForExternalRedeclaration() && ND->isExternallyDeclarable());
}
/// Sets whether tag declarations should be hidden by non-tag
@@ -556,7 +573,8 @@ public:
/// \brief Change this lookup's redeclaration kind.
void setRedeclarationKind(Sema::RedeclarationKind RK) {
- Redecl = RK;
+ Redecl = (RK != Sema::NotForRedeclaration);
+ ExternalRedecl = (RK == Sema::ForExternalRedeclaration);
configure();
}
@@ -719,6 +737,7 @@ private:
unsigned IDNS; // set by configure()
bool Redecl;
+ bool ExternalRedecl;
/// \brief True if tag declarations should be hidden if non-tags
/// are present
diff --git a/include/clang/Sema/Overload.h b/include/clang/Sema/Overload.h
index ffdf011d1dcb..05cfe53666ca 100644
--- a/include/clang/Sema/Overload.h
+++ b/include/clang/Sema/Overload.h
@@ -726,11 +726,20 @@ namespace clang {
enum CandidateSetKind {
/// Normal lookup.
CSK_Normal,
- /// Lookup for candidates for a call using operator syntax. Candidates
- /// that have no parameters of class type will be skipped unless there
- /// is a parameter of (reference to) enum type and the corresponding
- /// argument is of the same enum type.
- CSK_Operator
+ /// C++ [over.match.oper]:
+ /// Lookup of operator function candidates in a call using operator
+ /// syntax. Candidates that have no parameters of class type will be
+ /// skipped unless there is a parameter of (reference to) enum type and
+ /// the corresponding argument is of the same enum type.
+ CSK_Operator,
+ /// C++ [over.match.copy]:
+ /// Copy-initialization of an object of class type by user-defined
+ /// conversion.
+ CSK_InitByUserDefinedConversion,
+ /// C++ [over.match.ctor], [over.match.list]
+ /// Initialization of an object of class type by constructor,
+ /// using either a parenthesized or braced list of arguments.
+ CSK_InitByConstructor,
};
private:
@@ -795,7 +804,7 @@ namespace clang {
}
/// \brief Clear out all of the candidates.
- void clear();
+ void clear(CandidateSetKind CSK);
typedef SmallVectorImpl<OverloadCandidate>::iterator iterator;
iterator begin() { return Candidates.begin(); }
@@ -835,8 +844,7 @@ namespace clang {
/// Find the best viable function on this overload set, if it exists.
OverloadingResult BestViableFunction(Sema &S, SourceLocation Loc,
- OverloadCandidateSet::iterator& Best,
- bool UserDefinedConversion = false);
+ OverloadCandidateSet::iterator& Best);
void NoteCandidates(Sema &S,
OverloadCandidateDisplayKind OCD,
@@ -848,10 +856,10 @@ namespace clang {
};
bool isBetterOverloadCandidate(Sema &S,
- const OverloadCandidate& Cand1,
- const OverloadCandidate& Cand2,
+ const OverloadCandidate &Cand1,
+ const OverloadCandidate &Cand2,
SourceLocation Loc,
- bool UserDefinedConversion = false);
+ OverloadCandidateSet::CandidateSetKind Kind);
struct ConstructorInfo {
DeclAccessPair FoundDecl;
diff --git a/include/clang/Sema/Ownership.h b/include/clang/Sema/Ownership.h
index 848837a1decc..1e35316fd5dd 100644
--- a/include/clang/Sema/Ownership.h
+++ b/include/clang/Sema/Ownership.h
@@ -107,8 +107,7 @@ namespace clang {
namespace llvm {
template <class T>
- class PointerLikeTypeTraits<clang::OpaquePtr<T> > {
- public:
+ struct PointerLikeTypeTraits<clang::OpaquePtr<T> > {
static inline void *getAsVoidPointer(clang::OpaquePtr<T> P) {
// FIXME: Doesn't work? return P.getAs< void >();
return P.getAsOpaquePtr();
diff --git a/include/clang/Sema/Scope.h b/include/clang/Sema/Scope.h
index d0b006b82ec6..cd58a9910f98 100644
--- a/include/clang/Sema/Scope.h
+++ b/include/clang/Sema/Scope.h
@@ -124,6 +124,12 @@ public:
/// We are currently in the filter expression of an SEH except block.
SEHFilterScope = 0x200000,
+
+ /// This is a compound statement scope.
+ CompoundStmtScope = 0x400000,
+
+ /// We are between inheritance colon and the real class/struct definition scope.
+ ClassInheritanceScope = 0x800000,
};
private:
/// The parent scope for this scope. This is null for the translation-unit
@@ -429,6 +435,11 @@ public:
/// \brief Determine whether this scope is a SEH '__except' block.
bool isSEHExceptScope() const { return getFlags() & Scope::SEHExceptScope; }
+ /// \brief Determine whether this scope is a compound statement scope.
+ bool isCompoundStmtScope() const {
+ return getFlags() & Scope::CompoundStmtScope;
+ }
+
/// \brief Returns if rhs has a higher scope depth than this.
///
/// The caller is responsible for calling this only if one of the two scopes
diff --git a/include/clang/Sema/ScopeInfo.h b/include/clang/Sema/ScopeInfo.h
index 4251fa649a82..c707a3e8ef07 100644
--- a/include/clang/Sema/ScopeInfo.h
+++ b/include/clang/Sema/ScopeInfo.h
@@ -560,6 +560,7 @@ public:
void markUsed(bool IsODRUse) { (IsODRUse ? ODRUsed : NonODRUsed) = true; }
VarDecl *getVariable() const {
+ assert(isVariableCapture());
return VarAndNestedAndThis.getPointer();
}
@@ -833,6 +834,12 @@ public:
return FSI->Kind == SK_Lambda;
}
+ /// Is this scope known to be for a generic lambda? (This will be false until
+ /// we parse the first 'auto'-typed parameter.
+ bool isGenericLambda() const {
+ return !AutoTemplateParams.empty() || GLTemplateParameterList;
+ }
+
///
/// \brief Add a variable that might potentially be captured by the
/// lambda and therefore the enclosing lambdas.
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 5a708545705c..47cea3029bd9 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -64,7 +64,7 @@ namespace llvm {
template <typename ValueT> struct DenseMapInfo;
template <typename ValueT, typename ValueInfoT> class DenseSet;
class SmallBitVector;
- class InlineAsmIdentifierInfo;
+ struct InlineAsmIdentifierInfo;
}
namespace clang {
@@ -208,6 +208,7 @@ namespace sema {
class FunctionScopeInfo;
class LambdaScopeInfo;
class PossiblyUnreachableDiag;
+ class SemaPPCallbacks;
class TemplateDeductionInfo;
}
@@ -228,6 +229,10 @@ struct FileNullability {
/// not have a corresponding nullability annotation.
SourceLocation PointerLoc;
+ /// The end location for the first pointer declarator in the file. Used for
+ /// placing fix-its.
+ SourceLocation PointerEndLoc;
+
/// Which kind of pointer declarator we saw.
uint8_t PointerKind;
@@ -280,15 +285,21 @@ class Sema {
bool isVisibleSlow(const NamedDecl *D);
+ /// Determine whether two declarations should be linked together, given that
+ /// the old declaration might not be visible and the new declaration might
+ /// not have external linkage.
bool shouldLinkPossiblyHiddenDecl(const NamedDecl *Old,
const NamedDecl *New) {
- // We are about to link these. It is now safe to compute the linkage of
- // the new decl. If the new decl has external linkage, we will
- // link it with the hidden decl (which also has external linkage) and
- // it will keep having external linkage. If it has internal linkage, we
- // will not link it. Since it has no previous decls, it will remain
- // with internal linkage.
- return isVisible(Old) || New->isExternallyVisible();
+ if (isVisible(Old))
+ return true;
+ // See comment in below overload for why it's safe to compute the linkage
+ // of the new declaration here.
+ if (New->isExternallyDeclarable()) {
+ assert(Old->isExternallyDeclarable() &&
+ "should not have found a non-externally-declarable previous decl");
+ return true;
+ }
+ return false;
}
bool shouldLinkPossiblyHiddenDecl(LookupResult &Old, const NamedDecl *New);
@@ -381,11 +392,12 @@ public:
llvm::StringRef StackSlotLabel;
ValueType Value;
SourceLocation PragmaLocation;
- Slot(llvm::StringRef StackSlotLabel,
- ValueType Value,
- SourceLocation PragmaLocation)
- : StackSlotLabel(StackSlotLabel), Value(Value),
- PragmaLocation(PragmaLocation) {}
+ SourceLocation PragmaPushLocation;
+ Slot(llvm::StringRef StackSlotLabel, ValueType Value,
+ SourceLocation PragmaLocation, SourceLocation PragmaPushLocation)
+ : StackSlotLabel(StackSlotLabel), Value(Value),
+ PragmaLocation(PragmaLocation),
+ PragmaPushLocation(PragmaPushLocation) {}
};
void Act(SourceLocation PragmaLocation,
PragmaMsStackAction Action,
@@ -416,6 +428,8 @@ public:
explicit PragmaStack(const ValueType &Default)
: DefaultValue(Default), CurrentValue(Default) {}
+ bool hasValue() const { return CurrentValue != DefaultValue; }
+
SmallVector<Slot, 2> Stack;
ValueType DefaultValue; // Value used for PSK_Reset action.
ValueType CurrentValue;
@@ -437,6 +451,13 @@ public:
// Sentinel to represent when the stack is set to mac68k alignment.
static const unsigned kMac68kAlignmentSentinel = ~0U;
PragmaStack<unsigned> PackStack;
+ // The current #pragma pack values and locations at each #include.
+ struct PackIncludeState {
+ unsigned CurrentValue;
+ SourceLocation CurrentPragmaLocation;
+ bool HasNonDefaultValue, ShouldWarnOnInclude;
+ };
+ SmallVector<PackIncludeState, 8> PackIncludeStack;
// Segment #pragmas.
PragmaStack<StringLiteral *> DataSegStack;
PragmaStack<StringLiteral *> BSSSegStack;
@@ -1075,6 +1096,11 @@ public:
/// definition in this translation unit.
llvm::MapVector<NamedDecl *, SourceLocation> UndefinedButUsed;
+ /// Determine if VD, which must be a variable or function, is an external
+ /// symbol that nonetheless can't be referenced from outside this translation
+ /// unit because its type has no linkage and it's not extern "C".
+ bool isExternalWithNoLinkageType(ValueDecl *VD);
+
/// Obtain a sorted list of functions that are undefined but ODR-used.
void getUndefinedButUsed(
SmallVectorImpl<std::pair<NamedDecl *, SourceLocation> > &Undefined);
@@ -1110,12 +1136,13 @@ public:
CXXInvalid
};
- typedef std::pair<CXXRecordDecl*, CXXSpecialMember> SpecialMemberDecl;
+ typedef llvm::PointerIntPair<CXXRecordDecl *, 3, CXXSpecialMember>
+ SpecialMemberDecl;
/// The C++ special members which we are currently in the process of
/// declaring. If this process recursively triggers the declaration of the
/// same special member, we should act as if it is not yet declared.
- llvm::SmallSet<SpecialMemberDecl, 4> SpecialMembersBeingDeclared;
+ llvm::SmallPtrSet<SpecialMemberDecl, 4> SpecialMembersBeingDeclared;
/// The function definitions which were renamed as part of typo-correction
/// to match their respective declarations. We want to keep track of them
@@ -1357,6 +1384,8 @@ public:
SourceRange Brackets, DeclarationName Entity);
QualType BuildExtVectorType(QualType T, Expr *ArraySize,
SourceLocation AttrLoc);
+ QualType BuildAddressSpaceAttr(QualType &T, Expr *AddrSpace,
+ SourceLocation AttrLoc);
bool CheckFunctionReturnType(QualType T, SourceLocation Loc);
@@ -1504,7 +1533,8 @@ private:
TypeDiagnoser *Diagnoser);
struct ModuleScope {
- clang::Module *Module;
+ clang::Module *Module = nullptr;
+ bool ModuleInterface = false;
VisibleModuleSet OuterVisibleModules;
};
/// The modules we're currently parsing.
@@ -1525,7 +1555,7 @@ public:
/// visible at the specified location.
void makeMergedDefinitionVisible(NamedDecl *ND);
- bool isModuleVisible(Module *M) { return VisibleModules.isVisible(M); }
+ bool isModuleVisible(const Module *M) { return VisibleModules.isVisible(M); }
/// Determine whether a declaration is visible to name lookup.
bool isVisible(const NamedDecl *D) {
@@ -1694,7 +1724,6 @@ public:
ExprResult Expr;
TemplateName Template;
ParsedType Type;
- const IdentifierInfo *Keyword;
explicit NameClassification(NameClassificationKind Kind) : Kind(Kind) {}
@@ -1703,8 +1732,7 @@ public:
NameClassification(ParsedType Type) : Kind(NC_Type), Type(Type) {}
- NameClassification(const IdentifierInfo *Keyword)
- : Kind(NC_Keyword), Keyword(Keyword) { }
+ NameClassification(const IdentifierInfo *Keyword) : Kind(NC_Keyword) {}
static NameClassification Error() {
return NameClassification(NC_Error);
@@ -2022,9 +2050,9 @@ public:
SourceLocation SemiLoc);
enum class ModuleDeclKind {
- Module, ///< 'module X;'
+ Interface, ///< 'export module X;'
+ Implementation, ///< 'module X;'
Partition, ///< 'module partition X;'
- Implementation, ///< 'module implementation X;'
};
/// The parser has processed a module-declaration that begins the definition
@@ -2677,7 +2705,8 @@ public:
OverloadCandidateSet &CandidateSet,
TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr,
bool SuppressUserConversions = false,
- bool PartialOverloading = false);
+ bool PartialOverloading = false,
+ bool FirstArgumentIsBase = false);
void AddMethodCandidate(DeclAccessPair FoundDecl,
QualType ObjectType,
Expr::Classification ObjectClassification,
@@ -2725,13 +2754,15 @@ public:
CXXRecordDecl *ActingContext,
Expr *From, QualType ToType,
OverloadCandidateSet& CandidateSet,
- bool AllowObjCConversionOnExplicit);
+ bool AllowObjCConversionOnExplicit,
+ bool AllowResultConversion = true);
void AddTemplateConversionCandidate(FunctionTemplateDecl *FunctionTemplate,
DeclAccessPair FoundDecl,
CXXRecordDecl *ActingContext,
Expr *From, QualType ToType,
OverloadCandidateSet &CandidateSet,
- bool AllowObjCConversionOnExplicit);
+ bool AllowObjCConversionOnExplicit,
+ bool AllowResultConversion = true);
void AddSurrogateCandidate(CXXConversionDecl *Conversion,
DeclAccessPair FoundDecl,
CXXRecordDecl *ActingContext,
@@ -2771,6 +2802,14 @@ public:
EnableIfAttr *CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args,
bool MissingImplicitThis = false);
+ /// 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);
+
/// Emit diagnostics for the diagnose_if attributes on Function, ignoring any
/// non-ArgDependent DiagnoseIfAttrs.
///
@@ -2881,12 +2920,13 @@ public:
ExprResult CreateOverloadedUnaryOp(SourceLocation OpLoc,
UnaryOperatorKind Opc,
const UnresolvedSetImpl &Fns,
- Expr *input);
+ Expr *input, bool RequiresADL = true);
ExprResult CreateOverloadedBinOp(SourceLocation OpLoc,
BinaryOperatorKind Opc,
const UnresolvedSetImpl &Fns,
- Expr *LHS, Expr *RHS);
+ Expr *LHS, Expr *RHS,
+ bool RequiresADL = true);
ExprResult CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
SourceLocation RLoc,
@@ -3001,14 +3041,31 @@ public:
/// purpose of redeclaring the name.
NotForRedeclaration = 0,
/// \brief The lookup results will be used for redeclaration of a name,
- /// if an entity by that name already exists.
- ForRedeclaration
+ /// if an entity by that name already exists and is visible.
+ ForVisibleRedeclaration,
+ /// \brief The lookup results will be used for redeclaration of a name
+ /// with external linkage; non-visible lookup results with external linkage
+ /// may also be found.
+ ForExternalRedeclaration
};
+ RedeclarationKind forRedeclarationInCurContext() {
+ // A declaration with an owning module for linkage can never link against
+ // anything that is not visible. We don't need to check linkage here; if
+ // the context has internal linkage, redeclaration lookup won't find things
+ // from other TUs, and we can't safely compute linkage yet in general.
+ if (cast<Decl>(CurContext)
+ ->getOwningModuleForLinkage(/*IgnoreLinkage*/true))
+ return ForVisibleRedeclaration;
+ return ForExternalRedeclaration;
+ }
+
/// \brief The possible outcomes of name lookup for a literal operator.
enum LiteralOperatorLookupResult {
/// \brief The lookup resulted in an error.
LOLR_Error,
+ /// \brief The lookup found no match but no diagnostic was issued.
+ LOLR_ErrorNoDiagnostic,
/// \brief The lookup found a single 'cooked' literal operator, which
/// expects a normal literal to be built and passed to it.
LOLR_Cooked,
@@ -3133,7 +3190,8 @@ public:
ArrayRef<QualType> ArgTys,
bool AllowRaw,
bool AllowTemplate,
- bool AllowStringTemplate);
+ bool AllowStringTemplate,
+ bool DiagnoseMissing);
bool isKnownName(StringRef name);
void ArgumentDependentLookup(DeclarationName Name, SourceLocation Loc,
@@ -3229,6 +3287,8 @@ public:
void FilterLookupForScope(LookupResult &R, DeclContext *Ctx, Scope *S,
bool ConsiderLinkage, bool AllowInlineNamespace);
+ bool CheckRedeclarationModuleOwnership(NamedDecl *New, NamedDecl *Old);
+
void DiagnoseAmbiguousLookup(LookupResult &Result);
//@}
@@ -3271,7 +3331,7 @@ public:
unsigned ArgNum, StringRef &Str,
SourceLocation *ArgLocation = nullptr);
bool checkSectionName(SourceLocation LiteralLoc, StringRef Str);
- void checkTargetAttr(SourceLocation LiteralLoc, StringRef Str);
+ bool checkTargetAttr(SourceLocation LiteralLoc, StringRef Str);
bool checkMSInheritanceAttrOnDefinition(
CXXRecordDecl *RD, SourceRange Range, bool BestCase,
MSInheritanceAttr::Spelling SemanticSpelling);
@@ -3754,15 +3814,15 @@ public:
Expr *AsmString, MultiExprArg Clobbers,
SourceLocation RParenLoc);
+ void FillInlineAsmIdentifierInfo(Expr *Res,
+ llvm::InlineAsmIdentifierInfo &Info);
ExprResult LookupInlineAsmIdentifier(CXXScopeSpec &SS,
SourceLocation TemplateKWLoc,
UnqualifiedId &Id,
- llvm::InlineAsmIdentifierInfo &Info,
bool IsUnevaluatedContext);
bool LookupInlineAsmField(StringRef Base, StringRef Member,
unsigned &Offset, SourceLocation AsmLoc);
ExprResult LookupInlineAsmVarDeclField(Expr *RefExpr, StringRef Member,
- llvm::InlineAsmIdentifierInfo &Info,
SourceLocation AsmLoc);
StmtResult ActOnMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
ArrayRef<Token> AsmToks,
@@ -6038,7 +6098,7 @@ public:
SourceLocation ExportLoc,
SourceLocation TemplateLoc,
SourceLocation LAngleLoc,
- ArrayRef<Decl *> Params,
+ ArrayRef<NamedDecl *> Params,
SourceLocation RAngleLoc,
Expr *RequiresClause);
@@ -7368,13 +7428,16 @@ public:
unsigned PrevSFINAEErrors;
bool PrevInNonInstantiationSFINAEContext;
bool PrevAccessCheckingSFINAE;
+ bool PrevLastDiagnosticIgnored;
public:
explicit SFINAETrap(Sema &SemaRef, bool AccessCheckingSFINAE = false)
: SemaRef(SemaRef), PrevSFINAEErrors(SemaRef.NumSFINAEErrors),
PrevInNonInstantiationSFINAEContext(
SemaRef.InNonInstantiationSFINAEContext),
- PrevAccessCheckingSFINAE(SemaRef.AccessCheckingSFINAE)
+ PrevAccessCheckingSFINAE(SemaRef.AccessCheckingSFINAE),
+ PrevLastDiagnosticIgnored(
+ SemaRef.getDiagnostics().isLastDiagnosticIgnored())
{
if (!SemaRef.isSFINAEContext())
SemaRef.InNonInstantiationSFINAEContext = true;
@@ -7386,6 +7449,8 @@ public:
SemaRef.InNonInstantiationSFINAEContext
= PrevInNonInstantiationSFINAEContext;
SemaRef.AccessCheckingSFINAE = PrevAccessCheckingSFINAE;
+ SemaRef.getDiagnostics().setLastDiagnosticIgnored(
+ PrevLastDiagnosticIgnored);
}
/// \brief Determine whether any SFINAE errors have been trapped.
@@ -7725,11 +7790,6 @@ public:
VarDecl *Var, bool Recursive = false,
bool DefinitionRequired = false,
bool AtEndOfTU = false);
- void InstantiateStaticDataMemberDefinition(
- SourceLocation PointOfInstantiation,
- VarDecl *Var,
- bool Recursive = false,
- bool DefinitionRequired = false);
void InstantiateMemInitializers(CXXConstructorDecl *New,
const CXXConstructorDecl *Tmpl,
@@ -8182,6 +8242,15 @@ public:
void ActOnPragmaPack(SourceLocation PragmaLoc, PragmaMsStackAction Action,
StringRef SlotLabel, Expr *Alignment);
+ enum class PragmaPackDiagnoseKind {
+ NonDefaultStateAtInclude,
+ ChangedStateAtExit
+ };
+
+ void DiagnoseNonDefaultPragmaPack(PragmaPackDiagnoseKind Kind,
+ SourceLocation IncludeLoc);
+ void DiagnoseUnterminatedPragmaPack();
+
/// ActOnPragmaMSStruct - Called on well formed \#pragma ms_struct [on|off].
void ActOnPragmaMSStruct(PragmaMSStructKind Kind);
@@ -8467,6 +8536,10 @@ private:
/// Returns OpenMP nesting level for current directive.
unsigned getOpenMPNestingLevel() const;
+ /// Adjusts the function scopes index for the target-based regions.
+ void adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
+ unsigned Level) const;
+
/// Push new OpenMP function region for non-capturing function.
void pushOpenMPFunctionRegion();
@@ -8507,6 +8580,11 @@ public:
/// is performed.
bool isOpenMPPrivateDecl(ValueDecl *D, unsigned Level);
+ /// Sets OpenMP capture kind (OMPC_private, OMPC_firstprivate, OMPC_map etc.)
+ /// for \p FD based on DSA for the provided corresponding captured declaration
+ /// \p D.
+ void setOpenMPCaptureKind(FieldDecl *FD, ValueDecl *D, unsigned Level);
+
/// \brief Check if the specified variable is captured by 'target' directive.
/// \param Level Relative level of nested OpenMP construct for that the check
/// is performed.
@@ -8559,9 +8637,11 @@ public:
/// \brief Finish current declare reduction construct initializer.
void ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner);
/// \brief Initialize declare reduction construct initializer.
- void ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D);
+ /// \return omp_priv variable.
+ VarDecl *ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D);
/// \brief Finish current declare reduction construct initializer.
- void ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer);
+ void ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer,
+ VarDecl *OmpPrivParm);
/// \brief Called at the end of '#pragma omp declare reduction'.
DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveEnd(
Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid);
@@ -8576,11 +8656,20 @@ public:
OMPDeclareTargetDeclAttr::MapTypeTy MT,
NamedDeclSetType &SameDirectiveDecls);
/// Check declaration inside target region.
- void checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D);
- /// Return true inside OpenMP target region.
+ void checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
+ SourceLocation IdLoc = SourceLocation());
+ /// Return true inside OpenMP declare target region.
bool isInOpenMPDeclareTargetContext() const {
return IsInOpenMPDeclareTargetContext;
}
+ /// Return true inside OpenMP target region.
+ bool isInOpenMPTargetExecutionDirective() const;
+ /// Return true if (un)supported features for the current target should be
+ /// diagnosed if OpenMP (offloading) is enabled.
+ bool shouldDiagnoseTargetSupportFromOpenMP() const {
+ return !getLangOpts().OpenMPIsDevice || isInOpenMPDeclareTargetContext() ||
+ isInOpenMPTargetExecutionDirective();
+ }
/// Return the number of captured regions created for an OpenMP directive.
static int getOpenMPCaptureLevels(OpenMPDirectiveKind Kind);
@@ -8710,12 +8799,14 @@ public:
/// parsing of the associated statement.
StmtResult ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
SourceLocation StartLoc,
- SourceLocation EndLoc);
+ SourceLocation EndLoc,
+ Stmt *AStmt);
/// \brief Called on well-formed '\#pragma omp target exit data' after
/// parsing of the associated statement.
StmtResult ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
SourceLocation StartLoc,
- SourceLocation EndLoc);
+ SourceLocation EndLoc,
+ Stmt *AStmt);
/// \brief Called on well-formed '\#pragma omp target parallel' after
/// parsing of the associated statement.
StmtResult ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
@@ -8764,7 +8855,8 @@ public:
/// \brief Called on well-formed '\#pragma omp target update'.
StmtResult ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
SourceLocation StartLoc,
- SourceLocation EndLoc);
+ SourceLocation EndLoc,
+ Stmt *AStmt);
/// \brief Called on well-formed '\#pragma omp distribute parallel for' after
/// parsing of the associated statement.
StmtResult ActOnOpenMPDistributeParallelForDirective(
@@ -9029,6 +9121,13 @@ public:
CXXScopeSpec &ReductionIdScopeSpec,
const DeclarationNameInfo &ReductionId,
ArrayRef<Expr *> UnresolvedReductions = llvm::None);
+ /// Called on well-formed 'in_reduction' clause.
+ OMPClause *ActOnOpenMPInReductionClause(
+ ArrayRef<Expr *> VarList, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
+ CXXScopeSpec &ReductionIdScopeSpec,
+ const DeclarationNameInfo &ReductionId,
+ ArrayRef<Expr *> UnresolvedReductions = llvm::None);
/// \brief Called on well-formed 'linear' clause.
OMPClause *
ActOnOpenMPLinearClause(ArrayRef<Expr *> VarList, Expr *Step,
@@ -10126,8 +10225,7 @@ public:
void CodeCompleteObjCPropertyDefinition(Scope *S);
void CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
IdentifierInfo *PropertyName);
- void CodeCompleteObjCMethodDecl(Scope *S,
- bool IsInstanceMethod,
+ void CodeCompleteObjCMethodDecl(Scope *S, Optional<bool> IsInstanceMethod,
ParsedType ReturnType);
void CodeCompleteObjCMethodDeclSelector(Scope *S,
bool IsInstanceMethod,
@@ -10211,7 +10309,7 @@ private:
bool CheckPPCBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
bool SemaBuiltinVAStart(unsigned BuiltinID, CallExpr *TheCall);
- bool SemaBuiltinVAStartARM(CallExpr *Call);
+ bool SemaBuiltinVAStartARMMicrosoft(CallExpr *Call);
bool SemaBuiltinUnorderedCompare(CallExpr *TheCall);
bool SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs);
bool SemaBuiltinVSX(CallExpr *TheCall);
@@ -10362,7 +10460,8 @@ private:
/// \brief Peform checks on a call of a function with argument_with_type_tag
/// or pointer_with_type_tag attributes.
void CheckArgumentWithTypeTag(const ArgumentWithTypeTagAttr *Attr,
- const Expr * const *ExprArgs);
+ const ArrayRef<const Expr *> ExprArgs,
+ SourceLocation CallSiteLoc);
/// \brief Check if we are taking the address of a packed field
/// as this may be a problem if the pointer value is dereferenced.
@@ -10383,6 +10482,12 @@ private:
IdentifierInfo *Ident_NSError = nullptr;
+ /// \brief The handler for the FileChanged preprocessor events.
+ ///
+ /// Used for diagnostics that implement custom semantic analysis for #include
+ /// directives, like -Wpragma-pack.
+ sema::SemaPPCallbacks *SemaPPCallbackHandler;
+
protected:
friend class Parser;
friend class InitializationSequence;
@@ -10446,6 +10551,36 @@ public:
SmallVector<CXXRecordDecl*, 4> DelayedDllExportClasses;
private:
+ class SavePendingParsedClassStateRAII {
+ public:
+ SavePendingParsedClassStateRAII(Sema &S) : S(S) { swapSavedState(); }
+
+ ~SavePendingParsedClassStateRAII() {
+ assert(S.DelayedExceptionSpecChecks.empty() &&
+ "there shouldn't be any pending delayed exception spec checks");
+ assert(S.DelayedDefaultedMemberExceptionSpecs.empty() &&
+ "there shouldn't be any pending delayed defaulted member "
+ "exception specs");
+ assert(S.DelayedDllExportClasses.empty() &&
+ "there shouldn't be any pending delayed DLL export classes");
+ swapSavedState();
+ }
+
+ private:
+ Sema &S;
+ decltype(DelayedExceptionSpecChecks) SavedExceptionSpecChecks;
+ decltype(DelayedDefaultedMemberExceptionSpecs)
+ SavedDefaultedMemberExceptionSpecs;
+ decltype(DelayedDllExportClasses) SavedDllExportClasses;
+
+ void swapSavedState() {
+ SavedExceptionSpecChecks.swap(S.DelayedExceptionSpecChecks);
+ SavedDefaultedMemberExceptionSpecs.swap(
+ S.DelayedDefaultedMemberExceptionSpecs);
+ SavedDllExportClasses.swap(S.DelayedDllExportClasses);
+ }
+ };
+
/// \brief Helper class that collects misaligned member designations and
/// their location info for delayed diagnostics.
struct MisalignedMember {
diff --git a/include/clang/Sema/SemaInternal.h b/include/clang/Sema/SemaInternal.h
index a01e8d639f60..4dc215ba21cb 100644
--- a/include/clang/Sema/SemaInternal.h
+++ b/include/clang/Sema/SemaInternal.h
@@ -73,7 +73,8 @@ inline void MarkVarDeclODRUsed(VarDecl *Var,
// Keep track of used but undefined variables.
// FIXME: We shouldn't suppress this warning for static data members.
if (Var->hasDefinition(SemaRef.Context) == VarDecl::DeclarationOnly &&
- (!Var->isExternallyVisible() || Var->isInline()) &&
+ (!Var->isExternallyVisible() || Var->isInline() ||
+ SemaRef.isExternalWithNoLinkageType(Var)) &&
!(Var->isStaticDataMember() && Var->hasInit())) {
SourceLocation &old = SemaRef.UndefinedButUsed[Var->getCanonicalDecl()];
if (old.isInvalid())
diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h
index 9227b33d2c53..34a7bb330174 100644
--- a/include/clang/Serialization/ASTBitCodes.h
+++ b/include/clang/Serialization/ASTBitCodes.h
@@ -14,17 +14,23 @@
// respective lists.
//
//===----------------------------------------------------------------------===//
+
#ifndef LLVM_CLANG_SERIALIZATION_ASTBITCODES_H
#define LLVM_CLANG_SERIALIZATION_ASTBITCODES_H
#include "clang/AST/DeclarationName.h"
#include "clang/AST/Type.h"
-#include "llvm/ADT/DenseMap.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/OperatorKinds.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/Bitcode/BitCodes.h"
-#include "llvm/Support/DataTypes.h"
+#include <cassert>
+#include <cstdint>
namespace clang {
- namespace serialization {
+namespace serialization {
+
/// \brief AST file major version number supported by this version of
/// Clang.
///
@@ -52,7 +58,7 @@ namespace clang {
///
/// The ID numbers of identifiers are consecutive (in order of discovery)
/// and start at 1. 0 is reserved for NULL.
- typedef uint32_t IdentifierID;
+ using IdentifierID = uint32_t;
/// \brief An ID number that refers to a declaration in an AST file.
///
@@ -60,12 +66,12 @@ namespace clang {
/// discovery), with values below NUM_PREDEF_DECL_IDS being reserved.
/// At the start of a chain of precompiled headers, declaration ID 1 is
/// used for the translation unit declaration.
- typedef uint32_t DeclID;
+ using DeclID = uint32_t;
// FIXME: Turn these into classes so we can have some type safety when
// we go from local ID to global and vice-versa.
- typedef DeclID LocalDeclID;
- typedef DeclID GlobalDeclID;
+ using LocalDeclID = DeclID;
+ using GlobalDeclID = DeclID;
/// \brief An ID number that refers to a type in an AST file.
///
@@ -77,22 +83,25 @@ namespace clang {
/// IDs (based on the PREDEF_TYPE_*_ID constants), with 0 as a
/// placeholder for "no type". Values from NUM_PREDEF_TYPE_IDs are
/// other types that have serialized representations.
- typedef uint32_t TypeID;
+ using TypeID = uint32_t;
/// \brief A type index; the type ID with the qualifier bits removed.
class TypeIdx {
- uint32_t Idx;
+ uint32_t Idx = 0;
+
public:
- TypeIdx() : Idx(0) { }
- explicit TypeIdx(uint32_t index) : Idx(index) { }
+ TypeIdx() = default;
+ explicit TypeIdx(uint32_t index) : Idx(index) {}
uint32_t getIndex() const { return Idx; }
+
TypeID asTypeID(unsigned FastQuals) const {
if (Idx == uint32_t(-1))
return TypeID(-1);
return (Idx << Qualifiers::FastWidth) | FastQuals;
}
+
static TypeIdx fromTypeID(TypeID ID) {
if (ID == TypeID(-1))
return TypeIdx(-1);
@@ -104,14 +113,17 @@ namespace clang {
/// A structure for putting "fast"-unqualified QualTypes into a
/// DenseMap. This uses the standard pointer hash function.
struct UnsafeQualTypeDenseMapInfo {
- static inline bool isEqual(QualType A, QualType B) { return A == B; }
- static inline QualType getEmptyKey() {
+ static bool isEqual(QualType A, QualType B) { return A == B; }
+
+ static QualType getEmptyKey() {
return QualType::getFromOpaquePtr((void*) 1);
}
- static inline QualType getTombstoneKey() {
+
+ static QualType getTombstoneKey() {
return QualType::getFromOpaquePtr((void*) 2);
}
- static inline unsigned getHashValue(QualType T) {
+
+ static unsigned getHashValue(QualType T) {
assert(!T.getLocalFastQualifiers() &&
"hash invalid for types with fast quals");
uintptr_t v = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
@@ -120,44 +132,44 @@ namespace clang {
};
/// \brief An ID number that refers to an identifier in an AST file.
- typedef uint32_t IdentID;
+ using IdentID = uint32_t;
/// \brief The number of predefined identifier IDs.
const unsigned int NUM_PREDEF_IDENT_IDS = 1;
/// \brief An ID number that refers to a macro in an AST file.
- typedef uint32_t MacroID;
+ using MacroID = uint32_t;
/// \brief A global ID number that refers to a macro in an AST file.
- typedef uint32_t GlobalMacroID;
+ using GlobalMacroID = uint32_t;
/// \brief A local to a module ID number that refers to a macro in an
/// AST file.
- typedef uint32_t LocalMacroID;
+ using LocalMacroID = uint32_t;
/// \brief The number of predefined macro IDs.
const unsigned int NUM_PREDEF_MACRO_IDS = 1;
/// \brief An ID number that refers to an ObjC selector in an AST file.
- typedef uint32_t SelectorID;
+ using SelectorID = uint32_t;
/// \brief The number of predefined selector IDs.
const unsigned int NUM_PREDEF_SELECTOR_IDS = 1;
/// \brief An ID number that refers to a set of CXXBaseSpecifiers in an
/// AST file.
- typedef uint32_t CXXBaseSpecifiersID;
+ using CXXBaseSpecifiersID = uint32_t;
/// \brief An ID number that refers to a list of CXXCtorInitializers in an
/// AST file.
- typedef uint32_t CXXCtorInitializersID;
+ using CXXCtorInitializersID = uint32_t;
/// \brief An ID number that refers to an entity in the detailed
/// preprocessing record.
- typedef uint32_t PreprocessedEntityID;
+ using PreprocessedEntityID = uint32_t;
/// \brief An ID number that refers to a submodule in a module file.
- typedef uint32_t SubmoduleID;
+ using SubmoduleID = uint32_t;
/// \brief The number of predefined submodule IDs.
const unsigned int NUM_PREDEF_SUBMODULE_IDS = 1;
@@ -166,18 +178,21 @@ namespace clang {
struct PPEntityOffset {
/// \brief Raw source location of beginning of range.
unsigned Begin;
+
/// \brief Raw source location of end of range.
unsigned End;
+
/// \brief Offset in the AST file.
uint32_t BitOffset;
PPEntityOffset(SourceRange R, uint32_t BitOffset)
: Begin(R.getBegin().getRawEncoding()),
- End(R.getEnd().getRawEncoding()),
- BitOffset(BitOffset) { }
+ End(R.getEnd().getRawEncoding()), BitOffset(BitOffset) {}
+
SourceLocation getBegin() const {
return SourceLocation::getFromRawEncoding(Begin);
}
+
SourceLocation getEnd() const {
return SourceLocation::getFromRawEncoding(End);
}
@@ -186,17 +201,19 @@ namespace clang {
/// \brief Source range/offset of a preprocessed entity.
struct DeclOffset {
/// \brief Raw source location.
- unsigned Loc;
+ unsigned Loc = 0;
+
/// \brief Offset in the AST file.
- uint32_t BitOffset;
+ uint32_t BitOffset = 0;
- DeclOffset() : Loc(0), BitOffset(0) { }
+ DeclOffset() = default;
DeclOffset(SourceLocation Loc, uint32_t BitOffset)
- : Loc(Loc.getRawEncoding()),
- BitOffset(BitOffset) { }
+ : Loc(Loc.getRawEncoding()), BitOffset(BitOffset) {}
+
void setLocation(SourceLocation L) {
Loc = L.getRawEncoding();
}
+
SourceLocation getLocation() const {
return SourceLocation::getFromRawEncoding(Loc);
}
@@ -617,17 +634,21 @@ namespace clang {
/// \brief Describes a source location entry (SLocEntry) for a
/// file.
SM_SLOC_FILE_ENTRY = 1,
+
/// \brief Describes a source location entry (SLocEntry) for a
/// buffer.
SM_SLOC_BUFFER_ENTRY = 2,
+
/// \brief Describes a blob that contains the data for a buffer
/// entry. This kind of record always directly follows a
/// SM_SLOC_BUFFER_ENTRY record or a SM_SLOC_FILE_ENTRY with an
/// overridden buffer.
SM_SLOC_BUFFER_BLOB = 3,
+
/// \brief Describes a zlib-compressed blob that contains the data for
/// a buffer entry.
SM_SLOC_BUFFER_BLOB_COMPRESSED = 4,
+
/// \brief Describes a source location entry (SLocEntry) for a
/// macro expansion.
SM_SLOC_EXPANSION_ENTRY = 5
@@ -676,46 +697,66 @@ namespace clang {
enum SubmoduleRecordTypes {
/// \brief Metadata for submodules as a whole.
SUBMODULE_METADATA = 0,
+
/// \brief Defines the major attributes of a submodule, including its
/// name and parent.
SUBMODULE_DEFINITION = 1,
+
/// \brief Specifies the umbrella header used to create this module,
/// if any.
SUBMODULE_UMBRELLA_HEADER = 2,
+
/// \brief Specifies a header that falls into this (sub)module.
SUBMODULE_HEADER = 3,
+
/// \brief Specifies a top-level header that falls into this (sub)module.
SUBMODULE_TOPHEADER = 4,
+
/// \brief Specifies an umbrella directory.
SUBMODULE_UMBRELLA_DIR = 5,
+
/// \brief Specifies the submodules that are imported by this
/// submodule.
SUBMODULE_IMPORTS = 6,
+
/// \brief Specifies the submodules that are re-exported from this
/// submodule.
SUBMODULE_EXPORTS = 7,
+
/// \brief Specifies a required feature.
SUBMODULE_REQUIRES = 8,
+
/// \brief Specifies a header that has been explicitly excluded
/// from this submodule.
SUBMODULE_EXCLUDED_HEADER = 9,
+
/// \brief Specifies a library or framework to link against.
SUBMODULE_LINK_LIBRARY = 10,
+
/// \brief Specifies a configuration macro for this module.
SUBMODULE_CONFIG_MACRO = 11,
+
/// \brief Specifies a conflict with another module.
SUBMODULE_CONFLICT = 12,
+
/// \brief Specifies a header that is private to this submodule.
SUBMODULE_PRIVATE_HEADER = 13,
+
/// \brief Specifies a header that is part of the module but must be
/// textually included.
SUBMODULE_TEXTUAL_HEADER = 14,
+
/// \brief Specifies a header that is private to this submodule but
/// must be textually included.
SUBMODULE_PRIVATE_TEXTUAL_HEADER = 15,
+
/// \brief Specifies some declarations with initializers that must be
/// emitted to initialize the module.
SUBMODULE_INITIALIZERS = 16,
+
+ /// \brief Specifies the name of the module that will eventually
+ /// re-export the entities in this module.
+ SUBMODULE_EXPORT_AS = 17,
};
/// \brief Record types used within a comments block.
@@ -740,92 +781,139 @@ namespace clang {
enum PredefinedTypeIDs {
/// \brief The NULL type.
PREDEF_TYPE_NULL_ID = 0,
+
/// \brief The void type.
PREDEF_TYPE_VOID_ID = 1,
+
/// \brief The 'bool' or '_Bool' type.
PREDEF_TYPE_BOOL_ID = 2,
+
/// \brief The 'char' type, when it is unsigned.
PREDEF_TYPE_CHAR_U_ID = 3,
+
/// \brief The 'unsigned char' type.
PREDEF_TYPE_UCHAR_ID = 4,
+
/// \brief The 'unsigned short' type.
PREDEF_TYPE_USHORT_ID = 5,
+
/// \brief The 'unsigned int' type.
PREDEF_TYPE_UINT_ID = 6,
+
/// \brief The 'unsigned long' type.
PREDEF_TYPE_ULONG_ID = 7,
+
/// \brief The 'unsigned long long' type.
PREDEF_TYPE_ULONGLONG_ID = 8,
+
/// \brief The 'char' type, when it is signed.
PREDEF_TYPE_CHAR_S_ID = 9,
+
/// \brief The 'signed char' type.
PREDEF_TYPE_SCHAR_ID = 10,
+
/// \brief The C++ 'wchar_t' type.
PREDEF_TYPE_WCHAR_ID = 11,
+
/// \brief The (signed) 'short' type.
PREDEF_TYPE_SHORT_ID = 12,
+
/// \brief The (signed) 'int' type.
PREDEF_TYPE_INT_ID = 13,
+
/// \brief The (signed) 'long' type.
PREDEF_TYPE_LONG_ID = 14,
+
/// \brief The (signed) 'long long' type.
PREDEF_TYPE_LONGLONG_ID = 15,
+
/// \brief The 'float' type.
PREDEF_TYPE_FLOAT_ID = 16,
+
/// \brief The 'double' type.
PREDEF_TYPE_DOUBLE_ID = 17,
+
/// \brief The 'long double' type.
PREDEF_TYPE_LONGDOUBLE_ID = 18,
+
/// \brief The placeholder type for overloaded function sets.
PREDEF_TYPE_OVERLOAD_ID = 19,
+
/// \brief The placeholder type for dependent types.
PREDEF_TYPE_DEPENDENT_ID = 20,
+
/// \brief The '__uint128_t' type.
PREDEF_TYPE_UINT128_ID = 21,
+
/// \brief The '__int128_t' type.
PREDEF_TYPE_INT128_ID = 22,
+
/// \brief The type of 'nullptr'.
PREDEF_TYPE_NULLPTR_ID = 23,
+
/// \brief The C++ 'char16_t' type.
PREDEF_TYPE_CHAR16_ID = 24,
+
/// \brief The C++ 'char32_t' type.
PREDEF_TYPE_CHAR32_ID = 25,
+
/// \brief The ObjC 'id' type.
PREDEF_TYPE_OBJC_ID = 26,
+
/// \brief The ObjC 'Class' type.
PREDEF_TYPE_OBJC_CLASS = 27,
+
/// \brief The ObjC 'SEL' type.
PREDEF_TYPE_OBJC_SEL = 28,
+
/// \brief The 'unknown any' placeholder type.
PREDEF_TYPE_UNKNOWN_ANY = 29,
+
/// \brief The placeholder type for bound member functions.
PREDEF_TYPE_BOUND_MEMBER = 30,
+
/// \brief The "auto" deduction type.
PREDEF_TYPE_AUTO_DEDUCT = 31,
+
/// \brief The "auto &&" deduction type.
PREDEF_TYPE_AUTO_RREF_DEDUCT = 32,
+
/// \brief The OpenCL 'half' / ARM NEON __fp16 type.
PREDEF_TYPE_HALF_ID = 33,
+
/// \brief ARC's unbridged-cast placeholder type.
PREDEF_TYPE_ARC_UNBRIDGED_CAST = 34,
+
/// \brief The pseudo-object placeholder type.
PREDEF_TYPE_PSEUDO_OBJECT = 35,
+
/// \brief The placeholder type for builtin functions.
PREDEF_TYPE_BUILTIN_FN = 36,
+
/// \brief OpenCL event type.
PREDEF_TYPE_EVENT_ID = 37,
+
/// \brief OpenCL clk event type.
PREDEF_TYPE_CLK_EVENT_ID = 38,
+
/// \brief OpenCL sampler type.
PREDEF_TYPE_SAMPLER_ID = 39,
+
/// \brief OpenCL queue type.
PREDEF_TYPE_QUEUE_ID = 40,
+
/// \brief OpenCL reserve_id type.
PREDEF_TYPE_RESERVE_ID_ID = 41,
+
/// \brief The placeholder type for OpenMP array section.
PREDEF_TYPE_OMP_ARRAY_SECTION = 42,
+
/// \brief The '__float128' type
PREDEF_TYPE_FLOAT128_ID = 43,
+
+ /// \brief The '_Float16' type
+ PREDEF_TYPE_FLOAT16_ID = 44,
+
/// \brief OpenCL image types with auto numeration
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
PREDEF_TYPE_##Id##_ID,
@@ -848,94 +936,141 @@ namespace clang {
enum TypeCode {
/// \brief An ExtQualType record.
TYPE_EXT_QUAL = 1,
+
/// \brief A ComplexType record.
TYPE_COMPLEX = 3,
+
/// \brief A PointerType record.
TYPE_POINTER = 4,
+
/// \brief A BlockPointerType record.
TYPE_BLOCK_POINTER = 5,
+
/// \brief An LValueReferenceType record.
TYPE_LVALUE_REFERENCE = 6,
+
/// \brief An RValueReferenceType record.
TYPE_RVALUE_REFERENCE = 7,
+
/// \brief A MemberPointerType record.
TYPE_MEMBER_POINTER = 8,
+
/// \brief A ConstantArrayType record.
TYPE_CONSTANT_ARRAY = 9,
+
/// \brief An IncompleteArrayType record.
TYPE_INCOMPLETE_ARRAY = 10,
+
/// \brief A VariableArrayType record.
TYPE_VARIABLE_ARRAY = 11,
+
/// \brief A VectorType record.
TYPE_VECTOR = 12,
+
/// \brief An ExtVectorType record.
TYPE_EXT_VECTOR = 13,
+
/// \brief A FunctionNoProtoType record.
TYPE_FUNCTION_NO_PROTO = 14,
+
/// \brief A FunctionProtoType record.
TYPE_FUNCTION_PROTO = 15,
+
/// \brief A TypedefType record.
TYPE_TYPEDEF = 16,
+
/// \brief A TypeOfExprType record.
TYPE_TYPEOF_EXPR = 17,
+
/// \brief A TypeOfType record.
TYPE_TYPEOF = 18,
+
/// \brief A RecordType record.
TYPE_RECORD = 19,
+
/// \brief An EnumType record.
TYPE_ENUM = 20,
+
/// \brief An ObjCInterfaceType record.
TYPE_OBJC_INTERFACE = 21,
+
/// \brief An ObjCObjectPointerType record.
TYPE_OBJC_OBJECT_POINTER = 22,
+
/// \brief a DecltypeType record.
TYPE_DECLTYPE = 23,
+
/// \brief An ElaboratedType record.
TYPE_ELABORATED = 24,
+
/// \brief A SubstTemplateTypeParmType record.
TYPE_SUBST_TEMPLATE_TYPE_PARM = 25,
+
/// \brief An UnresolvedUsingType record.
TYPE_UNRESOLVED_USING = 26,
+
/// \brief An InjectedClassNameType record.
TYPE_INJECTED_CLASS_NAME = 27,
+
/// \brief An ObjCObjectType record.
TYPE_OBJC_OBJECT = 28,
+
/// \brief An TemplateTypeParmType record.
TYPE_TEMPLATE_TYPE_PARM = 29,
+
/// \brief An TemplateSpecializationType record.
TYPE_TEMPLATE_SPECIALIZATION = 30,
+
/// \brief A DependentNameType record.
TYPE_DEPENDENT_NAME = 31,
+
/// \brief A DependentTemplateSpecializationType record.
TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION = 32,
+
/// \brief A DependentSizedArrayType record.
TYPE_DEPENDENT_SIZED_ARRAY = 33,
+
/// \brief A ParenType record.
TYPE_PAREN = 34,
+
/// \brief A PackExpansionType record.
TYPE_PACK_EXPANSION = 35,
+
/// \brief An AttributedType record.
TYPE_ATTRIBUTED = 36,
+
/// \brief A SubstTemplateTypeParmPackType record.
TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK = 37,
+
/// \brief A AutoType record.
TYPE_AUTO = 38,
+
/// \brief A UnaryTransformType record.
TYPE_UNARY_TRANSFORM = 39,
+
/// \brief An AtomicType record.
TYPE_ATOMIC = 40,
+
/// \brief A DecayedType record.
TYPE_DECAYED = 41,
+
/// \brief An AdjustedType record.
TYPE_ADJUSTED = 42,
+
/// \brief A PipeType record.
TYPE_PIPE = 43,
+
/// \brief An ObjCTypeParamType record.
TYPE_OBJC_TYPE_PARAM = 44,
+
/// \brief A DeducedTemplateSpecializationType record.
TYPE_DEDUCED_TEMPLATE_SPECIALIZATION = 45,
+
/// \brief A DependentSizedExtVectorType record.
- TYPE_DEPENDENT_SIZED_EXT_VECTOR = 46
+ TYPE_DEPENDENT_SIZED_EXT_VECTOR = 46,
+
+ /// \brief A DependentAddressSpaceType record.
+ TYPE_DEPENDENT_ADDRESS_SPACE = 47
};
/// \brief The type IDs for special types constructed by semantic
@@ -946,18 +1081,25 @@ namespace clang {
enum SpecialTypeIDs {
/// \brief CFConstantString type
SPECIAL_TYPE_CF_CONSTANT_STRING = 0,
+
/// \brief C FILE typedef type
SPECIAL_TYPE_FILE = 1,
+
/// \brief C jmp_buf typedef type
SPECIAL_TYPE_JMP_BUF = 2,
+
/// \brief C sigjmp_buf typedef type
SPECIAL_TYPE_SIGJMP_BUF = 3,
+
/// \brief Objective-C "id" redefinition type
SPECIAL_TYPE_OBJC_ID_REDEFINITION = 4,
+
/// \brief Objective-C "Class" redefinition type
SPECIAL_TYPE_OBJC_CLASS_REDEFINITION = 5,
+
/// \brief Objective-C "SEL" redefinition type
SPECIAL_TYPE_OBJC_SEL_REDEFINITION = 6,
+
/// \brief C ucontext_t typedef type
SPECIAL_TYPE_UCONTEXT_T = 7
};
@@ -1048,57 +1190,84 @@ namespace clang {
/// \brief A TypedefDecl record.
DECL_TYPEDEF = 51,
/// \brief A TypeAliasDecl record.
+
DECL_TYPEALIAS,
+
/// \brief An EnumDecl record.
DECL_ENUM,
+
/// \brief A RecordDecl record.
DECL_RECORD,
+
/// \brief An EnumConstantDecl record.
DECL_ENUM_CONSTANT,
+
/// \brief A FunctionDecl record.
DECL_FUNCTION,
+
/// \brief A ObjCMethodDecl record.
DECL_OBJC_METHOD,
+
/// \brief A ObjCInterfaceDecl record.
DECL_OBJC_INTERFACE,
+
/// \brief A ObjCProtocolDecl record.
DECL_OBJC_PROTOCOL,
+
/// \brief A ObjCIvarDecl record.
DECL_OBJC_IVAR,
+
/// \brief A ObjCAtDefsFieldDecl record.
DECL_OBJC_AT_DEFS_FIELD,
+
/// \brief A ObjCCategoryDecl record.
DECL_OBJC_CATEGORY,
+
/// \brief A ObjCCategoryImplDecl record.
DECL_OBJC_CATEGORY_IMPL,
+
/// \brief A ObjCImplementationDecl record.
DECL_OBJC_IMPLEMENTATION,
+
/// \brief A ObjCCompatibleAliasDecl record.
DECL_OBJC_COMPATIBLE_ALIAS,
+
/// \brief A ObjCPropertyDecl record.
DECL_OBJC_PROPERTY,
+
/// \brief A ObjCPropertyImplDecl record.
DECL_OBJC_PROPERTY_IMPL,
+
/// \brief A FieldDecl record.
DECL_FIELD,
+
/// \brief A MSPropertyDecl record.
DECL_MS_PROPERTY,
+
/// \brief A VarDecl record.
DECL_VAR,
+
/// \brief An ImplicitParamDecl record.
DECL_IMPLICIT_PARAM,
+
/// \brief A ParmVarDecl record.
DECL_PARM_VAR,
+
/// \brief A DecompositionDecl record.
DECL_DECOMPOSITION,
+
/// \brief A BindingDecl record.
DECL_BINDING,
+
/// \brief A FileScopeAsmDecl record.
DECL_FILE_SCOPE_ASM,
+
/// \brief A BlockDecl record.
DECL_BLOCK,
+
/// \brief A CapturedDecl record.
DECL_CAPTURED,
+
/// \brief A record that stores the set of declarations that are
/// lexically stored within a given DeclContext.
///
@@ -1108,6 +1277,7 @@ namespace clang {
/// the contents of a DeclContext, e.g., via
/// DeclContext::decls_begin() and DeclContext::decls_end().
DECL_CONTEXT_LEXICAL,
+
/// \brief A record that stores the set of declarations that are
/// visible from a given DeclContext.
///
@@ -1116,104 +1286,151 @@ namespace clang {
/// IDs. This data is used when performing qualified name lookup
/// into a DeclContext via DeclContext::lookup.
DECL_CONTEXT_VISIBLE,
+
/// \brief A LabelDecl record.
DECL_LABEL,
+
/// \brief A NamespaceDecl record.
DECL_NAMESPACE,
+
/// \brief A NamespaceAliasDecl record.
DECL_NAMESPACE_ALIAS,
+
/// \brief A UsingDecl record.
DECL_USING,
+
/// \brief A UsingPackDecl record.
DECL_USING_PACK,
+
/// \brief A UsingShadowDecl record.
DECL_USING_SHADOW,
+
/// \brief A ConstructorUsingShadowDecl record.
DECL_CONSTRUCTOR_USING_SHADOW,
+
/// \brief A UsingDirecitveDecl record.
DECL_USING_DIRECTIVE,
+
/// \brief An UnresolvedUsingValueDecl record.
DECL_UNRESOLVED_USING_VALUE,
+
/// \brief An UnresolvedUsingTypenameDecl record.
DECL_UNRESOLVED_USING_TYPENAME,
+
/// \brief A LinkageSpecDecl record.
DECL_LINKAGE_SPEC,
+
/// \brief An ExportDecl record.
DECL_EXPORT,
+
/// \brief A CXXRecordDecl record.
DECL_CXX_RECORD,
+
/// \brief A CXXDeductionGuideDecl record.
DECL_CXX_DEDUCTION_GUIDE,
+
/// \brief A CXXMethodDecl record.
DECL_CXX_METHOD,
+
/// \brief A CXXConstructorDecl record.
DECL_CXX_CONSTRUCTOR,
+
/// \brief A CXXConstructorDecl record for an inherited constructor.
DECL_CXX_INHERITED_CONSTRUCTOR,
+
/// \brief A CXXDestructorDecl record.
DECL_CXX_DESTRUCTOR,
+
/// \brief A CXXConversionDecl record.
DECL_CXX_CONVERSION,
+
/// \brief An AccessSpecDecl record.
DECL_ACCESS_SPEC,
/// \brief A FriendDecl record.
DECL_FRIEND,
+
/// \brief A FriendTemplateDecl record.
DECL_FRIEND_TEMPLATE,
+
/// \brief A ClassTemplateDecl record.
DECL_CLASS_TEMPLATE,
+
/// \brief A ClassTemplateSpecializationDecl record.
DECL_CLASS_TEMPLATE_SPECIALIZATION,
+
/// \brief A ClassTemplatePartialSpecializationDecl record.
DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION,
+
/// \brief A VarTemplateDecl record.
DECL_VAR_TEMPLATE,
+
/// \brief A VarTemplateSpecializationDecl record.
DECL_VAR_TEMPLATE_SPECIALIZATION,
+
/// \brief A VarTemplatePartialSpecializationDecl record.
DECL_VAR_TEMPLATE_PARTIAL_SPECIALIZATION,
+
/// \brief A FunctionTemplateDecl record.
DECL_FUNCTION_TEMPLATE,
+
/// \brief A TemplateTypeParmDecl record.
DECL_TEMPLATE_TYPE_PARM,
+
/// \brief A NonTypeTemplateParmDecl record.
DECL_NON_TYPE_TEMPLATE_PARM,
+
/// \brief A TemplateTemplateParmDecl record.
DECL_TEMPLATE_TEMPLATE_PARM,
+
/// \brief A TypeAliasTemplateDecl record.
DECL_TYPE_ALIAS_TEMPLATE,
+
/// \brief A StaticAssertDecl record.
DECL_STATIC_ASSERT,
+
/// \brief A record containing CXXBaseSpecifiers.
DECL_CXX_BASE_SPECIFIERS,
+
/// \brief A record containing CXXCtorInitializers.
DECL_CXX_CTOR_INITIALIZERS,
+
/// \brief A IndirectFieldDecl record.
DECL_INDIRECTFIELD,
+
/// \brief A NonTypeTemplateParmDecl record that stores an expanded
/// non-type template parameter pack.
DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK,
+
/// \brief A TemplateTemplateParmDecl record that stores an expanded
/// template template parameter pack.
DECL_EXPANDED_TEMPLATE_TEMPLATE_PARM_PACK,
+
/// \brief A ClassScopeFunctionSpecializationDecl record a class scope
/// function specialization. (Microsoft extension).
DECL_CLASS_SCOPE_FUNCTION_SPECIALIZATION,
+
/// \brief An ImportDecl recording a module import.
DECL_IMPORT,
+
/// \brief An OMPThreadPrivateDecl record.
DECL_OMP_THREADPRIVATE,
+
/// \brief An EmptyDecl record.
DECL_EMPTY,
+
/// \brief An ObjCTypeParamDecl record.
DECL_OBJC_TYPE_PARAM,
+
/// \brief An OMPCapturedExprDecl record.
DECL_OMP_CAPTUREDEXPR,
+
/// \brief A PragmaCommentDecl record.
DECL_PRAGMA_COMMENT,
+
/// \brief A PragmaDetectMismatchDecl record.
DECL_PRAGMA_DETECT_MISMATCH,
+
/// \brief An OMPDeclareReductionDecl record.
DECL_OMP_DECLARE_REDUCTION,
};
@@ -1229,128 +1446,190 @@ namespace clang {
/// \brief A marker record that indicates that we are at the end
/// of an expression.
STMT_STOP = 128,
+
/// \brief A NULL expression.
STMT_NULL_PTR,
+
/// \brief A reference to a previously [de]serialized Stmt record.
STMT_REF_PTR,
+
/// \brief A NullStmt record.
STMT_NULL,
+
/// \brief A CompoundStmt record.
STMT_COMPOUND,
+
/// \brief A CaseStmt record.
STMT_CASE,
+
/// \brief A DefaultStmt record.
STMT_DEFAULT,
+
/// \brief A LabelStmt record.
STMT_LABEL,
+
/// \brief An AttributedStmt record.
STMT_ATTRIBUTED,
+
/// \brief An IfStmt record.
STMT_IF,
+
/// \brief A SwitchStmt record.
STMT_SWITCH,
+
/// \brief A WhileStmt record.
STMT_WHILE,
+
/// \brief A DoStmt record.
STMT_DO,
+
/// \brief A ForStmt record.
STMT_FOR,
+
/// \brief A GotoStmt record.
STMT_GOTO,
+
/// \brief An IndirectGotoStmt record.
STMT_INDIRECT_GOTO,
+
/// \brief A ContinueStmt record.
STMT_CONTINUE,
+
/// \brief A BreakStmt record.
STMT_BREAK,
+
/// \brief A ReturnStmt record.
STMT_RETURN,
+
/// \brief A DeclStmt record.
STMT_DECL,
+
/// \brief A CapturedStmt record.
STMT_CAPTURED,
+
/// \brief A GCC-style AsmStmt record.
STMT_GCCASM,
+
/// \brief A MS-style AsmStmt record.
STMT_MSASM,
+
/// \brief A PredefinedExpr record.
EXPR_PREDEFINED,
+
/// \brief A DeclRefExpr record.
EXPR_DECL_REF,
+
/// \brief An IntegerLiteral record.
EXPR_INTEGER_LITERAL,
+
/// \brief A FloatingLiteral record.
EXPR_FLOATING_LITERAL,
+
/// \brief An ImaginaryLiteral record.
EXPR_IMAGINARY_LITERAL,
+
/// \brief A StringLiteral record.
EXPR_STRING_LITERAL,
+
/// \brief A CharacterLiteral record.
EXPR_CHARACTER_LITERAL,
+
/// \brief A ParenExpr record.
EXPR_PAREN,
+
/// \brief A ParenListExpr record.
EXPR_PAREN_LIST,
+
/// \brief A UnaryOperator record.
EXPR_UNARY_OPERATOR,
+
/// \brief An OffsetOfExpr record.
EXPR_OFFSETOF,
+
/// \brief A SizefAlignOfExpr record.
EXPR_SIZEOF_ALIGN_OF,
+
/// \brief An ArraySubscriptExpr record.
EXPR_ARRAY_SUBSCRIPT,
+
/// \brief A CallExpr record.
EXPR_CALL,
+
/// \brief A MemberExpr record.
EXPR_MEMBER,
+
/// \brief A BinaryOperator record.
EXPR_BINARY_OPERATOR,
+
/// \brief A CompoundAssignOperator record.
EXPR_COMPOUND_ASSIGN_OPERATOR,
+
/// \brief A ConditionOperator record.
EXPR_CONDITIONAL_OPERATOR,
+
/// \brief An ImplicitCastExpr record.
EXPR_IMPLICIT_CAST,
+
/// \brief A CStyleCastExpr record.
EXPR_CSTYLE_CAST,
+
/// \brief A CompoundLiteralExpr record.
EXPR_COMPOUND_LITERAL,
+
/// \brief An ExtVectorElementExpr record.
EXPR_EXT_VECTOR_ELEMENT,
+
/// \brief An InitListExpr record.
EXPR_INIT_LIST,
+
/// \brief A DesignatedInitExpr record.
EXPR_DESIGNATED_INIT,
+
/// \brief A DesignatedInitUpdateExpr record.
EXPR_DESIGNATED_INIT_UPDATE,
+
/// \brief An NoInitExpr record.
EXPR_NO_INIT,
+
/// \brief An ArrayInitLoopExpr record.
EXPR_ARRAY_INIT_LOOP,
+
/// \brief An ArrayInitIndexExpr record.
EXPR_ARRAY_INIT_INDEX,
+
/// \brief An ImplicitValueInitExpr record.
EXPR_IMPLICIT_VALUE_INIT,
+
/// \brief A VAArgExpr record.
EXPR_VA_ARG,
+
/// \brief An AddrLabelExpr record.
EXPR_ADDR_LABEL,
+
/// \brief A StmtExpr record.
EXPR_STMT,
+
/// \brief A ChooseExpr record.
EXPR_CHOOSE,
+
/// \brief A GNUNullExpr record.
EXPR_GNU_NULL,
+
/// \brief A ShuffleVectorExpr record.
EXPR_SHUFFLE_VECTOR,
+
/// \brief A ConvertVectorExpr record.
EXPR_CONVERT_VECTOR,
+
/// \brief BlockExpr
EXPR_BLOCK,
+
/// \brief A GenericSelectionExpr record.
EXPR_GENERIC_SELECTION,
+
/// \brief A PseudoObjectExpr record.
EXPR_PSEUDO_OBJECT,
+
/// \brief An AtomicExpr record.
EXPR_ATOMIC,
@@ -1362,45 +1641,61 @@ namespace clang {
EXPR_OBJC_BOXED_EXPRESSION,
EXPR_OBJC_ARRAY_LITERAL,
EXPR_OBJC_DICTIONARY_LITERAL,
-
-
+
/// \brief An ObjCEncodeExpr record.
EXPR_OBJC_ENCODE,
+
/// \brief An ObjCSelectorExpr record.
EXPR_OBJC_SELECTOR_EXPR,
+
/// \brief An ObjCProtocolExpr record.
EXPR_OBJC_PROTOCOL_EXPR,
+
/// \brief An ObjCIvarRefExpr record.
EXPR_OBJC_IVAR_REF_EXPR,
+
/// \brief An ObjCPropertyRefExpr record.
EXPR_OBJC_PROPERTY_REF_EXPR,
+
/// \brief An ObjCSubscriptRefExpr record.
EXPR_OBJC_SUBSCRIPT_REF_EXPR,
+
/// \brief UNUSED
EXPR_OBJC_KVC_REF_EXPR,
+
/// \brief An ObjCMessageExpr record.
EXPR_OBJC_MESSAGE_EXPR,
+
/// \brief An ObjCIsa Expr record.
EXPR_OBJC_ISA,
+
/// \brief An ObjCIndirectCopyRestoreExpr record.
EXPR_OBJC_INDIRECT_COPY_RESTORE,
/// \brief An ObjCForCollectionStmt record.
STMT_OBJC_FOR_COLLECTION,
+
/// \brief An ObjCAtCatchStmt record.
STMT_OBJC_CATCH,
+
/// \brief An ObjCAtFinallyStmt record.
STMT_OBJC_FINALLY,
+
/// \brief An ObjCAtTryStmt record.
STMT_OBJC_AT_TRY,
+
/// \brief An ObjCAtSynchronizedStmt record.
STMT_OBJC_AT_SYNCHRONIZED,
+
/// \brief An ObjCAtThrowStmt record.
STMT_OBJC_AT_THROW,
+
/// \brief An ObjCAutoreleasePoolStmt record.
STMT_OBJC_AUTORELEASE_POOL,
+
/// \brief An ObjCBoolLiteralExpr record.
EXPR_OBJC_BOOL_LITERAL,
+
/// \brief An ObjCAvailabilityCheckExpr record.
EXPR_OBJC_AVAILABILITY_CHECK,
@@ -1408,37 +1703,52 @@ namespace clang {
/// \brief A CXXCatchStmt record.
STMT_CXX_CATCH,
+
/// \brief A CXXTryStmt record.
STMT_CXX_TRY,
/// \brief A CXXForRangeStmt record.
+
STMT_CXX_FOR_RANGE,
/// \brief A CXXOperatorCallExpr record.
EXPR_CXX_OPERATOR_CALL,
+
/// \brief A CXXMemberCallExpr record.
EXPR_CXX_MEMBER_CALL,
+
/// \brief A CXXConstructExpr record.
EXPR_CXX_CONSTRUCT,
+
/// \brief A CXXInheritedCtorInitExpr record.
EXPR_CXX_INHERITED_CTOR_INIT,
+
/// \brief A CXXTemporaryObjectExpr record.
EXPR_CXX_TEMPORARY_OBJECT,
+
/// \brief A CXXStaticCastExpr record.
EXPR_CXX_STATIC_CAST,
+
/// \brief A CXXDynamicCastExpr record.
EXPR_CXX_DYNAMIC_CAST,
+
/// \brief A CXXReinterpretCastExpr record.
EXPR_CXX_REINTERPRET_CAST,
+
/// \brief A CXXConstCastExpr record.
EXPR_CXX_CONST_CAST,
+
/// \brief A CXXFunctionalCastExpr record.
EXPR_CXX_FUNCTIONAL_CAST,
+
/// \brief A UserDefinedLiteral record.
EXPR_USER_DEFINED_LITERAL,
+
/// \brief A CXXStdInitializerListExpr record.
EXPR_CXX_STD_INITIALIZER_LIST,
+
/// \brief A CXXBoolLiteralExpr record.
EXPR_CXX_BOOL_LITERAL,
+
EXPR_CXX_NULL_PTR_LITERAL, // CXXNullPtrLiteralExpr
EXPR_CXX_TYPEID_EXPR, // CXXTypeidExpr (of expr).
EXPR_CXX_TYPEID_TYPE, // CXXTypeidExpr (of type).
@@ -1560,11 +1870,14 @@ namespace clang {
enum DesignatorTypes {
/// \brief Field designator where only the field name is known.
DESIG_FIELD_NAME = 0,
+
/// \brief Field designator where the field has been resolved to
/// a declaration.
DESIG_FIELD_DECL = 1,
+
/// \brief Array designator.
DESIG_ARRAY = 2,
+
/// \brief GNU array range designator.
DESIG_ARRAY_RANGE = 3
};
@@ -1580,8 +1893,11 @@ namespace clang {
/// \brief Describes the redeclarations of a declaration.
struct LocalRedeclarationsInfo {
- DeclID FirstID; // The ID of the first declaration
- unsigned Offset; // Offset into the array of redeclaration chains.
+ // The ID of the first declaration
+ DeclID FirstID;
+
+ // Offset into the array of redeclaration chains.
+ unsigned Offset;
friend bool operator<(const LocalRedeclarationsInfo &X,
const LocalRedeclarationsInfo &Y) {
@@ -1606,8 +1922,11 @@ namespace clang {
/// \brief Describes the categories of an Objective-C class.
struct ObjCCategoriesInfo {
- DeclID DefinitionID; // The ID of the definition
- unsigned Offset; // Offset into the array of category lists.
+ // The ID of the definition
+ DeclID DefinitionID;
+
+ // Offset into the array of category lists.
+ unsigned Offset;
friend bool operator<(const ObjCCategoriesInfo &X,
const ObjCCategoriesInfo &Y) {
@@ -1636,15 +1955,14 @@ namespace clang {
/// same key can occasionally represent multiple names (for names that
/// contain types, in particular).
class DeclarationNameKey {
- typedef unsigned NameKind;
+ using NameKind = unsigned;
- NameKind Kind;
- uint64_t Data;
+ NameKind Kind = 0;
+ uint64_t Data = 0;
public:
- DeclarationNameKey() : Kind(), Data() {}
+ DeclarationNameKey() = default;
DeclarationNameKey(DeclarationName Name);
-
DeclarationNameKey(NameKind Kind, uint64_t Data)
: Kind(Kind), Data(Data) {}
@@ -1656,12 +1974,14 @@ namespace clang {
Kind == DeclarationName::CXXDeductionGuideName);
return (IdentifierInfo *)Data;
}
+
Selector getSelector() const {
assert(Kind == DeclarationName::ObjCZeroArgSelector ||
Kind == DeclarationName::ObjCOneArgSelector ||
Kind == DeclarationName::ObjCMultiArgSelector);
return Selector(Data);
}
+
OverloadedOperatorKind getOperatorKind() const {
assert(Kind == DeclarationName::CXXOperatorName);
return (OverloadedOperatorKind)Data;
@@ -1677,26 +1997,32 @@ namespace clang {
};
/// @}
- }
-} // end namespace clang
+
+} // namespace serialization
+} // namespace clang
namespace llvm {
+
template <> struct DenseMapInfo<clang::serialization::DeclarationNameKey> {
static clang::serialization::DeclarationNameKey getEmptyKey() {
return clang::serialization::DeclarationNameKey(-1, 1);
}
+
static clang::serialization::DeclarationNameKey getTombstoneKey() {
return clang::serialization::DeclarationNameKey(-1, 2);
}
+
static unsigned
getHashValue(const clang::serialization::DeclarationNameKey &Key) {
return Key.getHash();
}
+
static bool isEqual(const clang::serialization::DeclarationNameKey &L,
const clang::serialization::DeclarationNameKey &R) {
return L == R;
}
};
-}
-#endif
+} // namespace llvm
+
+#endif // LLVM_CLANG_SERIALIZATION_ASTBITCODES_H
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h
index eafa05175832..7b71fee95de2 100644
--- a/include/clang/Serialization/ASTReader.h
+++ b/include/clang/Serialization/ASTReader.h
@@ -1,4 +1,4 @@
-//===--- ASTReader.h - AST File Reader --------------------------*- C++ -*-===//
+//===- ASTReader.h - AST File Reader ----------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -17,13 +17,21 @@
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/TemplateBase.h"
+#include "clang/AST/TemplateName.h"
+#include "clang/AST/Type.h"
#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/FileSystemOptions.h"
#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/Module.h"
+#include "clang/Basic/OpenCLOptions.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Version.h"
+#include "clang/Basic/VersionTuple.h"
#include "clang/Lex/ExternalPreprocessorSource.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/PreprocessingRecord.h"
+#include "clang/Lex/Token.h"
#include "clang/Sema/ExternalSemaSource.h"
#include "clang/Sema/IdentifierResolver.h"
#include "clang/Serialization/ASTBitCodes.h"
@@ -31,70 +39,86 @@
#include "clang/Serialization/Module.h"
#include "clang/Serialization/ModuleFileExtension.h"
#include "clang/Serialization/ModuleManager.h"
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/TinyPtrVector.h"
-#include "llvm/Support/DataTypes.h"
+#include "llvm/ADT/iterator.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/Bitcode/BitstreamReader.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Timer.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <ctime>
#include <deque>
#include <memory>
+#include <set>
#include <string>
#include <utility>
#include <vector>
-namespace llvm {
- class BitstreamCursor;
- class MemoryBuffer;
- class APInt;
- class APSInt;
- class APFloat;
-}
-
namespace clang {
-class SourceManager;
-class HeaderSearchOptions;
-class FileManager;
-class AddrLabelExpr;
class ASTConsumer;
class ASTContext;
-class ASTIdentifierIterator;
-class ASTUnit; // FIXME: Layering violation and egregious hack.
-class Attr;
-class Decl;
-class DeclContext;
-class DefMacroDirective;
-class DiagnosticOptions;
-class NestedNameSpecifier;
+class ASTDeserializationListener;
+class ASTReader;
+class ASTRecordReader;
class CXXBaseSpecifier;
class CXXConstructorDecl;
class CXXCtorInitializer;
+class CXXTemporary;
+class Decl;
+class DeclaratorDecl;
+class DeclContext;
+class EnumDecl;
+class Expr;
+class FieldDecl;
+class FileEntry;
+class FileManager;
+class FileSystemOptions;
+class FunctionDecl;
class GlobalModuleIndex;
-class GotoStmt;
-class MacroDefinition;
-class MacroDirective;
-class ModuleMacro;
+struct HeaderFileInfo;
+class HeaderSearchOptions;
+class LangOptions;
+class LazyASTUnresolvedSet;
+class MacroInfo;
+class MemoryBufferCache;
class NamedDecl;
-class OpaqueValueExpr;
+class NamespaceDecl;
+class NestedNameSpecifier;
+class ObjCCategoryDecl;
+class ObjCInterfaceDecl;
+class PCHContainerReader;
class Preprocessor;
class PreprocessorOptions;
+struct QualifierInfo;
class Sema;
+class SourceManager;
+class Stmt;
class SwitchCase;
-class ASTDeserializationListener;
-class ASTWriter;
-class ASTReader;
-class ASTDeclReader;
-class ASTStmtReader;
-class ASTRecordReader;
-class TypeLocReader;
-struct HeaderFileInfo;
-class VersionTuple;
class TargetOptions;
-class LazyASTUnresolvedSet;
+class TemplateParameterList;
+class TypedefNameDecl;
+class TypeSourceInfo;
+class ValueDecl;
+class VarDecl;
/// \brief Abstract interface for callback invocations by the ASTReader.
///
@@ -189,9 +213,11 @@ public:
/// \brief Returns true if this \c ASTReaderListener wants to receive the
/// input files of the AST file via \c visitInputFile, false otherwise.
virtual bool needsInputFileVisitation() { return false; }
+
/// \brief Returns true if this \c ASTReaderListener wants to receive the
/// system input files of the AST file via \c visitInputFile, false otherwise.
virtual bool needsSystemInputFileVisitation() { return false; }
+
/// \brief if \c needsInputFileVisitation returns true, this is called for
/// each non-system input file of the AST File. If
/// \c needsSystemInputFileVisitation is true, then it is called for all
@@ -206,6 +232,7 @@ public:
/// \brief Returns true if this \c ASTReaderListener wants to receive the
/// imports of the AST file via \c visitImport, false otherwise.
virtual bool needsImportVisitation() const { return false; }
+
/// \brief If needsImportVisitation returns \c true, this is called for each
/// AST file imported by this AST file.
virtual void visitImport(StringRef Filename) {}
@@ -306,12 +333,15 @@ namespace serialization {
class ReadMethodPoolVisitor;
namespace reader {
- class ASTIdentifierLookupTrait;
- /// \brief The on-disk hash table(s) used for DeclContext name lookup.
- struct DeclContextLookupTable;
-}
-} // end namespace serialization
+class ASTIdentifierLookupTrait;
+
+/// \brief The on-disk hash table(s) used for DeclContext name lookup.
+struct DeclContextLookupTable;
+
+} // namespace reader
+
+} // namespace serialization
/// \brief Reads an AST files chain containing the contents of a translation
/// unit.
@@ -334,8 +364,20 @@ class ASTReader
public ExternalSLocEntrySource
{
public:
- typedef SmallVector<uint64_t, 64> RecordData;
- typedef SmallVectorImpl<uint64_t> RecordDataImpl;
+ /// \brief Types of AST files.
+ friend class ASTDeclReader;
+ friend class ASTIdentifierIterator;
+ friend class ASTRecordReader;
+ friend class ASTStmtReader;
+ friend class ASTUnit; // ASTUnit needs to remap source locations.
+ friend class ASTWriter;
+ friend class PCHValidator;
+ friend class serialization::reader::ASTIdentifierLookupTrait;
+ friend class serialization::ReadMethodPoolVisitor;
+ friend class TypeLocReader;
+
+ using RecordData = SmallVector<uint64_t, 64>;
+ using RecordDataImpl = SmallVectorImpl<uint64_t>;
/// \brief The result of reading the control block of an AST file, which
/// can fail for various reasons.
@@ -343,41 +385,34 @@ public:
/// \brief The control block was read successfully. Aside from failures,
/// the AST file is safe to read into the current context.
Success,
+
/// \brief The AST file itself appears corrupted.
Failure,
+
/// \brief The AST file was missing.
Missing,
+
/// \brief The AST file is out-of-date relative to its input files,
/// and needs to be regenerated.
OutOfDate,
+
/// \brief The AST file was written by a different version of Clang.
VersionMismatch,
+
/// \brief The AST file was writtten with a different language/target
/// configuration.
ConfigurationMismatch,
+
/// \brief The AST file has errors.
HadErrors
};
- /// \brief Types of AST files.
- friend class PCHValidator;
- friend class ASTDeclReader;
- friend class ASTStmtReader;
- friend class ASTIdentifierIterator;
- friend class serialization::reader::ASTIdentifierLookupTrait;
- friend class TypeLocReader;
- friend class ASTRecordReader;
- friend class ASTWriter;
- friend class ASTUnit; // ASTUnit needs to remap source locations.
- friend class serialization::ReadMethodPoolVisitor;
-
- typedef serialization::ModuleFile ModuleFile;
- typedef serialization::ModuleKind ModuleKind;
- typedef serialization::ModuleManager ModuleManager;
-
- typedef ModuleManager::ModuleIterator ModuleIterator;
- typedef ModuleManager::ModuleConstIterator ModuleConstIterator;
- typedef ModuleManager::ModuleReverseIterator ModuleReverseIterator;
+ using ModuleFile = serialization::ModuleFile;
+ using ModuleKind = serialization::ModuleKind;
+ using ModuleManager = serialization::ModuleManager;
+ using ModuleIterator = ModuleManager::ModuleIterator;
+ using ModuleConstIterator = ModuleManager::ModuleConstIterator;
+ using ModuleReverseIterator = ModuleManager::ModuleReverseIterator;
private:
/// \brief The receiver of some callbacks invoked by ASTReader.
@@ -385,6 +420,7 @@ private:
/// \brief The receiver of deserialization events.
ASTDeserializationListener *DeserializationListener = nullptr;
+
bool OwnsDeserializationListener = false;
SourceManager &SourceMgr;
@@ -436,7 +472,8 @@ private:
/// \brief A map of negated SLocEntryIDs to the modules containing them.
ContinuousRangeMap<unsigned, ModuleFile*, 64> GlobalSLocEntryMap;
- typedef ContinuousRangeMap<unsigned, ModuleFile*, 64> GlobalSLocOffsetMapType;
+ using GlobalSLocOffsetMapType =
+ ContinuousRangeMap<unsigned, ModuleFile *, 64>;
/// \brief A map of reversed (SourceManager::MaxLoadedOffset - SLocOffset)
/// SourceLocation offsets to the modules containing them.
@@ -448,8 +485,8 @@ private:
/// ID = (I + 1) << FastQual::Width has already been loaded
std::vector<QualType> TypesLoaded;
- typedef ContinuousRangeMap<serialization::TypeID, ModuleFile *, 4>
- GlobalTypeMapType;
+ using GlobalTypeMapType =
+ ContinuousRangeMap<serialization::TypeID, ModuleFile *, 4>;
/// \brief Mapping from global type IDs to the module in which the
/// type resides along with the offset that should be added to the
@@ -462,17 +499,17 @@ private:
/// = I + 1 has already been loaded.
std::vector<Decl *> DeclsLoaded;
- typedef ContinuousRangeMap<serialization::DeclID, ModuleFile *, 4>
- GlobalDeclMapType;
+ using GlobalDeclMapType =
+ ContinuousRangeMap<serialization::DeclID, ModuleFile *, 4>;
/// \brief Mapping from global declaration IDs to the module in which the
/// declaration resides.
GlobalDeclMapType GlobalDeclMap;
- typedef std::pair<ModuleFile *, uint64_t> FileOffset;
- typedef SmallVector<FileOffset, 2> FileOffsetsTy;
- typedef llvm::DenseMap<serialization::DeclID, FileOffsetsTy>
- DeclUpdateOffsetsMap;
+ using FileOffset = std::pair<ModuleFile *, uint64_t>;
+ using FileOffsetsTy = SmallVector<FileOffset, 2>;
+ using DeclUpdateOffsetsMap =
+ llvm::DenseMap<serialization::DeclID, FileOffsetsTy>;
/// \brief Declarations that have modifications residing in a later file
/// in the chain.
@@ -481,12 +518,15 @@ private:
struct PendingUpdateRecord {
Decl *D;
serialization::GlobalDeclID ID;
+
// Whether the declaration was just deserialized.
bool JustLoaded;
+
PendingUpdateRecord(serialization::GlobalDeclID ID, Decl *D,
bool JustLoaded)
: D(D), ID(ID), JustLoaded(JustLoaded) {}
};
+
/// \brief Declaration updates for already-loaded declarations that we need
/// to apply once we finish processing an import.
llvm::SmallVector<PendingUpdateRecord, 16> PendingUpdateRecords;
@@ -505,7 +545,7 @@ private:
/// \brief Declarations that have been imported and have typedef names for
/// linkage purposes.
- llvm::DenseMap<std::pair<DeclContext*, IdentifierInfo*>, NamedDecl*>
+ llvm::DenseMap<std::pair<DeclContext *, IdentifierInfo *>, NamedDecl *>
ImportedTypedefNamesForLinkage;
/// \brief Mergeable declaration contexts that have anonymous declarations
@@ -514,10 +554,10 @@ private:
AnonymousDeclarationsForMerging;
struct FileDeclsInfo {
- ModuleFile *Mod;
+ ModuleFile *Mod = nullptr;
ArrayRef<serialization::LocalDeclID> Decls;
- FileDeclsInfo() : Mod(nullptr) {}
+ FileDeclsInfo() = default;
FileDeclsInfo(ModuleFile *Mod, ArrayRef<serialization::LocalDeclID> Decls)
: Mod(Mod), Decls(Decls) {}
};
@@ -527,7 +567,7 @@ private:
/// \brief An array of lexical contents of a declaration context, as a sequence of
/// Decl::Kind, DeclID pairs.
- typedef ArrayRef<llvm::support::unaligned_uint32_t> LexicalContents;
+ using LexicalContents = ArrayRef<llvm::support::unaligned_uint32_t>;
/// \brief Map from a DeclContext to its lexical contents.
llvm::DenseMap<const DeclContext*, std::pair<ModuleFile*, LexicalContents>>
@@ -548,7 +588,7 @@ private:
ModuleFile *Mod;
const unsigned char *Data;
};
- typedef SmallVector<PendingVisibleUpdate, 1> DeclContextVisibleUpdates;
+ using DeclContextVisibleUpdates = SmallVector<PendingVisibleUpdate, 1>;
/// \brief Updates to the visible declarations of declaration contexts that
/// haven't been loaded yet.
@@ -559,22 +599,23 @@ private:
/// declarations that have not yet been linked to their definitions.
llvm::SmallPtrSet<Decl *, 4> PendingDefinitions;
- typedef llvm::MapVector<Decl *, uint64_t,
- llvm::SmallDenseMap<Decl *, unsigned, 4>,
- SmallVector<std::pair<Decl *, uint64_t>, 4> >
- PendingBodiesMap;
+ using PendingBodiesMap =
+ llvm::MapVector<Decl *, uint64_t,
+ llvm::SmallDenseMap<Decl *, unsigned, 4>,
+ SmallVector<std::pair<Decl *, uint64_t>, 4>>;
/// \brief Functions or methods that have bodies that will be attached.
PendingBodiesMap PendingBodies;
/// \brief Definitions for which we have added merged definitions but not yet
/// performed deduplication.
- llvm::SetVector<NamedDecl*> PendingMergedDefinitionsToDeduplicate;
+ llvm::SetVector<NamedDecl *> PendingMergedDefinitionsToDeduplicate;
/// \brief Read the record that describes the lexical contents of a DC.
bool ReadLexicalDeclContextStorage(ModuleFile &M,
llvm::BitstreamCursor &Cursor,
uint64_t Offset, DeclContext *DC);
+
/// \brief Read the record that describes the visible contents of a DC.
bool ReadVisibleDeclContextStorage(ModuleFile &M,
llvm::BitstreamCursor &Cursor,
@@ -588,8 +629,8 @@ private:
/// been loaded.
std::vector<IdentifierInfo *> IdentifiersLoaded;
- typedef ContinuousRangeMap<serialization::IdentID, ModuleFile *, 4>
- GlobalIdentifierMapType;
+ using GlobalIdentifierMapType =
+ ContinuousRangeMap<serialization::IdentID, ModuleFile *, 4>;
/// \brief Mapping from global identifier IDs to the module in which the
/// identifier resides along with the offset that should be added to the
@@ -604,16 +645,16 @@ private:
/// been loaded.
std::vector<MacroInfo *> MacrosLoaded;
- typedef std::pair<IdentifierInfo *, serialization::SubmoduleID>
- LoadedMacroInfo;
+ using LoadedMacroInfo =
+ std::pair<IdentifierInfo *, serialization::SubmoduleID>;
/// \brief A set of #undef directives that we have loaded; used to
/// deduplicate the same #undef information coming from multiple module
/// files.
llvm::DenseSet<LoadedMacroInfo> LoadedUndefs;
- typedef ContinuousRangeMap<serialization::MacroID, ModuleFile *, 4>
- GlobalMacroMapType;
+ using GlobalMacroMapType =
+ ContinuousRangeMap<serialization::MacroID, ModuleFile *, 4>;
/// \brief Mapping from global macro IDs to the module in which the
/// macro resides along with the offset that should be added to the
@@ -626,8 +667,8 @@ private:
/// indicate that the particular submodule ID has not yet been loaded.
SmallVector<Module *, 2> SubmodulesLoaded;
- typedef ContinuousRangeMap<serialization::SubmoduleID, ModuleFile *, 4>
- GlobalSubmoduleMapType;
+ using GlobalSubmoduleMapType =
+ ContinuousRangeMap<serialization::SubmoduleID, ModuleFile *, 4>;
/// \brief Mapping from global submodule IDs to the module file in which the
/// submodule resides along with the offset that should be added to the
@@ -635,14 +676,13 @@ private:
GlobalSubmoduleMapType GlobalSubmoduleMap;
/// \brief A set of hidden declarations.
- typedef SmallVector<Decl*, 2> HiddenNames;
- typedef llvm::DenseMap<Module *, HiddenNames> HiddenNamesMapType;
+ using HiddenNames = SmallVector<Decl *, 2>;
+ using HiddenNamesMapType = llvm::DenseMap<Module *, HiddenNames>;
/// \brief A mapping from each of the hidden submodules to the deserialized
/// declarations in that submodule that could be made visible.
HiddenNamesMapType HiddenNamesMap;
-
/// \brief A module import, export, or conflict that hasn't yet been resolved.
struct UnresolvedModuleRef {
/// \brief The file in which this module resides.
@@ -675,11 +715,10 @@ private:
/// been loaded.
SmallVector<Selector, 16> SelectorsLoaded;
- typedef ContinuousRangeMap<serialization::SelectorID, ModuleFile *, 4>
- GlobalSelectorMapType;
+ using GlobalSelectorMapType =
+ ContinuousRangeMap<serialization::SelectorID, ModuleFile *, 4>;
/// \brief Mapping from global selector IDs to the module in which the
-
/// global selector ID to produce a local ID.
GlobalSelectorMapType GlobalSelectorMap;
@@ -699,15 +738,15 @@ private:
: M(M), MacroDirectivesOffset(MacroDirectivesOffset) {}
};
- typedef llvm::MapVector<IdentifierInfo *, SmallVector<PendingMacroInfo, 2> >
- PendingMacroIDsMap;
+ using PendingMacroIDsMap =
+ llvm::MapVector<IdentifierInfo *, SmallVector<PendingMacroInfo, 2>>;
/// \brief Mapping from identifiers that have a macro history to the global
/// IDs have not yet been deserialized to the global IDs of those macros.
PendingMacroIDsMap PendingMacroIDs;
- typedef ContinuousRangeMap<unsigned, ModuleFile *, 4>
- GlobalPreprocessedEntityMapType;
+ using GlobalPreprocessedEntityMapType =
+ ContinuousRangeMap<unsigned, ModuleFile *, 4>;
/// \brief Mapping from global preprocessing entity IDs to the module in
/// which the preprocessed entity resides along with the offset that should be
@@ -825,6 +864,7 @@ private:
struct PragmaPackStackEntry {
unsigned Value;
SourceLocation Location;
+ SourceLocation PushLocation;
StringRef SlotLabel;
};
llvm::SmallVector<PragmaPackStackEntry, 2> PragmaPackStack;
@@ -867,9 +907,6 @@ private:
SmallVector<ImportedSubmodule, 2> ImportedModules;
//@}
- /// \brief The directory that the PCH we are reading is stored in.
- std::string CurrentDir;
-
/// \brief The system include root to be used when loading the
/// precompiled header.
std::string isysroot;
@@ -897,7 +934,8 @@ private:
///\brief Whether we are currently processing update records.
bool ProcessingUpdateRecords = false;
- typedef llvm::DenseMap<unsigned, SwitchCase *> SwitchCaseMapTy;
+ using SwitchCaseMapTy = llvm::DenseMap<unsigned, SwitchCase *>;
+
/// \brief Mapping from switch-case IDs in the chain to switch-case statements
///
/// Statements usually don't have IDs, but switch cases need them, so that the
@@ -981,7 +1019,7 @@ private:
///
/// The declarations on the identifier chain for these identifiers will be
/// loaded once the recursive loading has completed.
- llvm::MapVector<IdentifierInfo *, SmallVector<uint32_t, 4> >
+ llvm::MapVector<IdentifierInfo *, SmallVector<uint32_t, 4>>
PendingIdentifierInfos;
/// \brief The set of lookup results that we have faked in order to support
@@ -1000,7 +1038,9 @@ private:
public:
InterestingDecl(Decl *D, bool HasBody)
: D(D), DeclHasPendingBody(HasBody) {}
+
Decl *getDecl() { return D; }
+
/// Whether the declaration has a pending body.
bool hasPendingBody() { return DeclHasPendingBody; }
};
@@ -1045,8 +1085,11 @@ private:
/// once recursing loading has been completed.
llvm::SmallVector<NamedDecl *, 16> PendingOdrMergeChecks;
+ using DataPointers =
+ std::pair<CXXRecordDecl *, struct CXXRecordDecl::DefinitionData *>;
+
/// \brief Record definitions in which we found an ODR violation.
- llvm::SmallDenseMap<CXXRecordDecl *, llvm::TinyPtrVector<CXXRecordDecl *>, 2>
+ llvm::SmallDenseMap<CXXRecordDecl *, llvm::SmallVector<DataPointers, 2>, 2>
PendingOdrMergeFailures;
/// \brief DeclContexts in which we have diagnosed an ODR violation.
@@ -1061,8 +1104,8 @@ private:
/// module is loaded.
SmallVector<ObjCInterfaceDecl *, 16> ObjCClassesLoaded;
- typedef llvm::DenseMap<Decl *, SmallVector<serialization::DeclID, 2> >
- KeyDeclsMap;
+ using KeyDeclsMap =
+ llvm::DenseMap<Decl *, SmallVector<serialization::DeclID, 2>>;
/// \brief A mapping from canonical declarations to the set of global
/// declaration IDs for key declaration that have been merged with that
@@ -1096,15 +1139,14 @@ private:
ASTReader &Reader;
enum ReadingKind PrevKind;
- ReadingKindTracker(const ReadingKindTracker &) = delete;
- void operator=(const ReadingKindTracker &) = delete;
-
public:
ReadingKindTracker(enum ReadingKind newKind, ASTReader &reader)
: Reader(reader), PrevKind(Reader.ReadingKind) {
Reader.ReadingKind = newKind;
}
+ ReadingKindTracker(const ReadingKindTracker &) = delete;
+ ReadingKindTracker &operator=(const ReadingKindTracker &) = delete;
~ReadingKindTracker() { Reader.ReadingKind = PrevKind; }
};
@@ -1113,15 +1155,15 @@ private:
ASTReader &Reader;
bool PrevState;
- ProcessingUpdatesRAIIObj(const ProcessingUpdatesRAIIObj &) = delete;
- void operator=(const ProcessingUpdatesRAIIObj &) = delete;
-
public:
ProcessingUpdatesRAIIObj(ASTReader &reader)
: Reader(reader), PrevState(Reader.ProcessingUpdateRecords) {
Reader.ProcessingUpdateRecords = true;
}
+ ProcessingUpdatesRAIIObj(const ProcessingUpdatesRAIIObj &) = delete;
+ ProcessingUpdatesRAIIObj &
+ operator=(const ProcessingUpdatesRAIIObj &) = delete;
~ProcessingUpdatesRAIIObj() { Reader.ProcessingUpdateRecords = PrevState; }
};
@@ -1135,7 +1177,7 @@ private:
/// predefines buffer may contain additional definitions.
std::string SuggestedPredefines;
- llvm::DenseMap<const Decl *, bool> BodySource;
+ llvm::DenseMap<const Decl *, bool> DefinitionSource;
/// \brief Reads a statement from the specified cursor.
Stmt *ReadStmtFromStream(ModuleFile &F);
@@ -1204,7 +1246,7 @@ private:
ImportedModule(ModuleFile *Mod,
ModuleFile *ImportedBy,
SourceLocation ImportLoc)
- : Mod(Mod), ImportedBy(ImportedBy), ImportLoc(ImportLoc) { }
+ : Mod(Mod), ImportedBy(ImportedBy), ImportLoc(ImportLoc) {}
};
ASTReadResult ReadASTCore(StringRef FileName, ModuleKind Type,
@@ -1265,10 +1307,11 @@ private:
std::string &SuggestedPredefines);
struct RecordLocation {
- RecordLocation(ModuleFile *M, uint64_t O)
- : F(M), Offset(O) {}
ModuleFile *F;
uint64_t Offset;
+
+ RecordLocation(ModuleFile *M, uint64_t O)
+ : F(M), Offset(O) {}
};
QualType readTypeRecord(unsigned Index);
@@ -1327,12 +1370,11 @@ public:
ModuleDeclIterator, const serialization::LocalDeclID *,
std::random_access_iterator_tag, const Decl *, ptrdiff_t,
const Decl *, const Decl *> {
- ASTReader *Reader;
- ModuleFile *Mod;
+ ASTReader *Reader = nullptr;
+ ModuleFile *Mod = nullptr;
public:
- ModuleDeclIterator()
- : iterator_adaptor_base(nullptr), Reader(nullptr), Mod(nullptr) {}
+ ModuleDeclIterator() : iterator_adaptor_base(nullptr) {}
ModuleDeclIterator(ASTReader *Reader, ModuleFile *Mod,
const serialization::LocalDeclID *Pos)
@@ -1341,6 +1383,7 @@ public:
value_type operator*() const {
return Reader->GetDecl(Reader->getGlobalDeclID(*Mod, *I));
}
+
value_type operator->() const { return **this; }
bool operator==(const ModuleDeclIterator &RHS) const {
@@ -1377,8 +1420,6 @@ private:
void Error(unsigned DiagID, StringRef Arg1 = StringRef(),
StringRef Arg2 = StringRef()) const;
- ASTReader(const ASTReader &) = delete;
- void operator=(const ASTReader &) = delete;
public:
/// \brief Load the AST file and validate its contents against the given
/// Preprocessor.
@@ -1427,7 +1468,8 @@ public:
bool AllowConfigurationMismatch = false,
bool ValidateSystemInputs = false, bool UseGlobalIndex = true,
std::unique_ptr<llvm::Timer> ReadTimer = {});
-
+ ASTReader(const ASTReader &) = delete;
+ ASTReader &operator=(const ASTReader &) = delete;
~ASTReader() override;
SourceManager &getSourceManager() const { return SourceMgr; }
@@ -1442,15 +1484,19 @@ public:
enum LoadFailureCapabilities {
/// \brief The client can't handle any AST loading failures.
ARR_None = 0,
+
/// \brief The client can handle an AST file that cannot load because it
/// is missing.
ARR_Missing = 0x1,
+
/// \brief The client can handle an AST file that cannot load because it
/// is out-of-date relative to its input files.
ARR_OutOfDate = 0x2,
+
/// \brief The client can handle an AST file that cannot load because it
/// was built with a different version of Clang.
ARR_VersionMismatch = 0x4,
+
/// \brief The client can handle an AST file that cannot load because it's
/// compiled configuration doesn't match that of the context it was
/// loaded into.
@@ -1521,11 +1567,11 @@ public:
/// RAII object to temporarily add an AST callback listener.
class ListenerScope {
ASTReader &Reader;
- bool Chained;
+ bool Chained = false;
public:
ListenerScope(ASTReader &Reader, std::unique_ptr<ASTReaderListener> L)
- : Reader(Reader), Chained(false) {
+ : Reader(Reader) {
auto Old = Reader.takeListener();
if (Old) {
Chained = true;
@@ -1534,6 +1580,7 @@ public:
}
Reader.setListener(std::move(L));
}
+
~ListenerScope() {
auto New = Reader.takeListener();
if (Chained)
@@ -1932,16 +1979,16 @@ public:
llvm::SmallSetVector<const TypedefNameDecl *, 4> &Decls) override;
void ReadReferencedSelectors(
- SmallVectorImpl<std::pair<Selector, SourceLocation> > &Sels) override;
+ SmallVectorImpl<std::pair<Selector, SourceLocation>> &Sels) override;
void ReadWeakUndeclaredIdentifiers(
- SmallVectorImpl<std::pair<IdentifierInfo *, WeakInfo> > &WI) override;
+ SmallVectorImpl<std::pair<IdentifierInfo *, WeakInfo>> &WI) override;
void ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables) override;
void ReadPendingInstantiations(
- SmallVectorImpl<std::pair<ValueDecl *,
- SourceLocation> > &Pending) override;
+ SmallVectorImpl<std::pair<ValueDecl *,
+ SourceLocation>> &Pending) override;
void ReadLateParsedTemplates(
llvm::MapVector<const FunctionDecl *, std::unique_ptr<LateParsedTemplate>>
@@ -2144,9 +2191,19 @@ public:
// \brief Read a string
static std::string ReadString(const RecordData &Record, unsigned &Idx);
+ // \brief Skip a string
+ static void SkipString(const RecordData &Record, unsigned &Idx) {
+ Idx += Record[Idx] + 1;
+ }
+
// \brief Read a path
std::string ReadPath(ModuleFile &F, const RecordData &Record, unsigned &Idx);
+ // \brief Skip a path
+ static void SkipPath(const RecordData &Record, unsigned &Idx) {
+ SkipString(Record, Idx);
+ }
+
/// \brief Read a version tuple.
static VersionTuple ReadVersionTuple(const RecordData &Record, unsigned &Idx);
@@ -2264,20 +2321,19 @@ public:
/// \brief An object for streaming information from a record.
class ASTRecordReader {
- typedef serialization::ModuleFile ModuleFile;
+ using ModuleFile = serialization::ModuleFile;
ASTReader *Reader;
ModuleFile *F;
unsigned Idx = 0;
ASTReader::RecordData Record;
- typedef ASTReader::RecordData RecordData;
- typedef ASTReader::RecordDataImpl RecordDataImpl;
+ using RecordData = ASTReader::RecordData;
+ using RecordDataImpl = ASTReader::RecordDataImpl;
public:
/// Construct an ASTRecordReader that uses the default encoding scheme.
- ASTRecordReader(ASTReader &Reader, ModuleFile &F)
- : Reader(&Reader), F(&F) {}
+ ASTRecordReader(ASTReader &Reader, ModuleFile &F) : Reader(&Reader), F(&F) {}
/// \brief Reads a record with id AbbrevID from Cursor, resetting the
/// internal state.
@@ -2291,17 +2347,20 @@ public:
/// \brief The current position in this record.
unsigned getIdx() const { return Idx; }
+
/// \brief The length of this record.
size_t size() const { return Record.size(); }
/// \brief An arbitrary index in this record.
const uint64_t &operator[](size_t N) { return Record[N]; }
+
/// \brief The last element in this record.
const uint64_t &back() const { return Record.back(); }
/// \brief Returns the current value in this record, and advances to the
/// next value.
const uint64_t &readInt() { return Record[Idx++]; }
+
/// \brief Returns the current value in this record, without advancing.
const uint64_t &peekInt() { return Record[Idx]; }
@@ -2555,7 +2614,7 @@ public:
/// then restores it when destroyed.
struct SavedStreamPosition {
explicit SavedStreamPosition(llvm::BitstreamCursor &Cursor)
- : Cursor(Cursor), Offset(Cursor.GetCurrentBitNo()) { }
+ : Cursor(Cursor), Offset(Cursor.GetCurrentBitNo()) {}
~SavedStreamPosition() {
Cursor.JumpToBit(Offset);
@@ -2570,6 +2629,6 @@ inline void PCHValidator::Error(const char *Msg) {
Reader.Error(Msg);
}
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_SERIALIZATION_ASTREADER_H
diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h
index f14dfc73baa9..9437bf7f2c9f 100644
--- a/include/clang/Serialization/ASTWriter.h
+++ b/include/clang/Serialization/ASTWriter.h
@@ -1,4 +1,4 @@
-//===--- ASTWriter.h - AST File Writer --------------------------*- C++ -*-===//
+//===- ASTWriter.h - AST File Writer ----------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,67 +11,89 @@
// containing a serialized representation of a translation unit.
//
//===----------------------------------------------------------------------===//
+
#ifndef LLVM_CLANG_SERIALIZATION_ASTWRITER_H
#define LLVM_CLANG_SERIALIZATION_ASTWRITER_H
#include "clang/AST/ASTMutationListener.h"
#include "clang/AST/Decl.h"
+#include "clang/AST/DeclarationName.h"
+#include "clang/AST/NestedNameSpecifier.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 "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Bitcode/BitstreamWriter.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <ctime>
+#include <memory>
#include <queue>
+#include <string>
+#include <utility>
#include <vector>
namespace llvm {
- class APFloat;
- class APInt;
-}
+
+class APFloat;
+class APInt;
+class APSInt;
+
+} // namespace llvm
namespace clang {
-class DeclarationName;
class ASTContext;
+class ASTReader;
+class ASTUnresolvedSet;
class Attr;
-class NestedNameSpecifier;
class CXXBaseSpecifier;
class CXXCtorInitializer;
+class CXXRecordDecl;
+class CXXTemporary;
class FileEntry;
class FPOptions;
+class FunctionDecl;
class HeaderSearch;
class HeaderSearchOptions;
class IdentifierResolver;
+class LangOptions;
class MacroDefinitionRecord;
-class MacroDirective;
class MacroInfo;
-class OpaqueValueExpr;
-class OpenCLOptions;
-class ASTReader;
class MemoryBufferCache;
class Module;
class ModuleFileExtension;
class ModuleFileExtensionWriter;
-class PreprocessedEntity;
+class NamedDecl;
+class NestedNameSpecifier;
+class ObjCInterfaceDecl;
class PreprocessingRecord;
class Preprocessor;
+struct QualifierInfo;
class RecordDecl;
class Sema;
class SourceManager;
+class Stmt;
struct StoredDeclsList;
class SwitchCase;
-class TargetInfo;
+class TemplateParameterList;
class Token;
+class TypeSourceInfo;
class VersionTuple;
-class ASTUnresolvedSet;
-
-namespace SrcMgr { class SLocEntry; }
/// \brief Writes an AST file containing the contents of a translation unit.
///
@@ -82,14 +104,15 @@ namespace SrcMgr { class SLocEntry; }
class ASTWriter : public ASTDeserializationListener,
public ASTMutationListener {
public:
- typedef SmallVector<uint64_t, 64> RecordData;
- typedef SmallVectorImpl<uint64_t> RecordDataImpl;
- typedef ArrayRef<uint64_t> RecordDataRef;
-
friend class ASTDeclWriter;
+ friend class ASTRecordWriter;
friend class ASTStmtWriter;
friend class ASTTypeWriter;
- friend class ASTRecordWriter;
+
+ using RecordData = SmallVector<uint64_t, 64>;
+ using RecordDataImpl = SmallVectorImpl<uint64_t>;
+ using RecordDataRef = ArrayRef<uint64_t>;
+
private:
/// \brief Map that provides the ID numbers of each type within the
/// output stream, plus those deserialized from a chained PCH.
@@ -100,9 +123,8 @@ private:
/// allow for the const/volatile qualifiers.
///
/// Keys in the map never have const/volatile qualifiers.
- typedef llvm::DenseMap<QualType, serialization::TypeIdx,
- serialization::UnsafeQualTypeDenseMapInfo>
- TypeIdxMap;
+ using TypeIdxMap = llvm::DenseMap<QualType, serialization::TypeIdx,
+ serialization::UnsafeQualTypeDenseMapInfo>;
/// \brief The bitstream writer used to emit this precompiled header.
llvm::BitstreamWriter &Stream;
@@ -152,8 +174,8 @@ private:
/// \brief Stores a declaration or a type to be written to the AST file.
class DeclOrType {
public:
- DeclOrType(Decl *D) : Stored(D), IsType(false) { }
- DeclOrType(QualType T) : Stored(T.getAsOpaquePtr()), IsType(true) { }
+ DeclOrType(Decl *D) : Stored(D), IsType(false) {}
+ DeclOrType(QualType T) : Stored(T.getAsOpaquePtr()), IsType(true) {}
bool isType() const { return IsType; }
bool isDecl() const { return !IsType; }
@@ -195,15 +217,16 @@ private:
std::vector<serialization::DeclOffset> DeclOffsets;
/// \brief Sorted (by file offset) vector of pairs of file offset/DeclID.
- typedef SmallVector<std::pair<unsigned, serialization::DeclID>, 64>
- LocDeclIDsTy;
+ using LocDeclIDsTy =
+ SmallVector<std::pair<unsigned, serialization::DeclID>, 64>;
struct DeclIDInFileInfo {
LocDeclIDsTy DeclIDs;
+
/// \brief Set when the DeclIDs vectors from all files are joined, this
/// indicates the index that this particular vector has in the global one.
unsigned FirstDeclIndex;
};
- typedef llvm::DenseMap<FileID, DeclIDInFileInfo *> FileDeclIDsTy;
+ using FileDeclIDsTy = llvm::DenseMap<FileID, DeclIDInFileInfo *>;
/// \brief Map from file SLocEntries to info about the file-level declarations
/// that it contains.
@@ -260,6 +283,7 @@ private:
MacroInfo *MI;
serialization::MacroID ID;
};
+
/// \brief The macro infos to emit.
std::vector<MacroInfoToEmitData> MacroInfosToEmit;
@@ -331,31 +355,33 @@ private:
: Kind(Kind), Type(Type.getAsOpaquePtr()) {}
DeclUpdate(unsigned Kind, SourceLocation Loc)
: Kind(Kind), Loc(Loc.getRawEncoding()) {}
- DeclUpdate(unsigned Kind, unsigned Val)
- : Kind(Kind), Val(Val) {}
- DeclUpdate(unsigned Kind, Module *M)
- : Kind(Kind), Mod(M) {}
+ DeclUpdate(unsigned Kind, unsigned Val) : Kind(Kind), Val(Val) {}
+ DeclUpdate(unsigned Kind, Module *M) : Kind(Kind), Mod(M) {}
DeclUpdate(unsigned Kind, const Attr *Attribute)
: Kind(Kind), Attribute(Attribute) {}
unsigned getKind() const { return Kind; }
const Decl *getDecl() const { return Dcl; }
QualType getType() const { return QualType::getFromOpaquePtr(Type); }
+
SourceLocation getLoc() const {
return SourceLocation::getFromRawEncoding(Loc);
}
+
unsigned getNumber() const { return Val; }
Module *getModule() const { return Mod; }
const Attr *getAttr() const { return Attribute; }
};
- typedef SmallVector<DeclUpdate, 1> UpdateRecord;
- typedef llvm::MapVector<const Decl *, UpdateRecord> DeclUpdateMap;
+ using UpdateRecord = SmallVector<DeclUpdate, 1>;
+ using DeclUpdateMap = llvm::MapVector<const Decl *, UpdateRecord>;
+
/// \brief Mapping from declarations that came from a chained PCH to the
/// record containing modifications to them.
DeclUpdateMap DeclUpdates;
- typedef llvm::DenseMap<Decl *, Decl *> FirstLatestDeclMap;
+ using FirstLatestDeclMap = llvm::DenseMap<Decl *, Decl *>;
+
/// \brief Map of first declarations from a chained PCH that point to the
/// most recent declarations in another PCH.
FirstLatestDeclMap FirstLatestDecls;
@@ -600,7 +626,6 @@ public:
/// \brief Emit a reference to a declaration.
void AddDeclRef(const Decl *D, RecordDataImpl &Record);
-
/// \brief Force a declaration to be emitted and get its ID.
serialization::DeclID GetDeclRef(const Decl *D);
@@ -651,6 +676,7 @@ public:
unsigned getTypeExtQualAbbrev() const {
return TypeExtQualAbbrev;
}
+
unsigned getTypeFunctionProtoAbbrev() const {
return TypeFunctionProtoAbbrev;
}
@@ -698,12 +724,14 @@ private:
void ResolvedExceptionSpec(const FunctionDecl *FD) override;
void DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) override;
void ResolvedOperatorDelete(const CXXDestructorDecl *DD,
- const FunctionDecl *Delete) override;
+ const FunctionDecl *Delete,
+ Expr *ThisArg) override;
void CompletedImplicitDefinition(const FunctionDecl *D) override;
- void StaticDataMemberInstantiated(const VarDecl *D) override;
+ void InstantiationRequested(const ValueDecl *D) override;
+ void VariableDefinitionInstantiated(const VarDecl *D) override;
+ void FunctionDefinitionInstantiated(const FunctionDecl *D) override;
void DefaultArgumentInstantiated(const ParmVarDecl *D) override;
void DefaultMemberInitializerInstantiated(const FieldDecl *D) override;
- void FunctionDefinitionInstantiated(const FunctionDecl *D) override;
void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
const ObjCInterfaceDecl *IFD) override;
void DeclarationMarkedUsed(const Decl *D) override;
@@ -756,8 +784,8 @@ public:
: Writer(Parent.Writer), Record(&Record) {}
/// Copying an ASTRecordWriter is almost certainly a bug.
- ASTRecordWriter(const ASTRecordWriter&) = delete;
- void operator=(const ASTRecordWriter&) = delete;
+ ASTRecordWriter(const ASTRecordWriter &) = delete;
+ ASTRecordWriter &operator=(const ASTRecordWriter &) = delete;
/// \brief Extract the underlying record storage.
ASTWriter::RecordDataImpl &getRecordData() const { return *Record; }
@@ -909,7 +937,7 @@ public:
void AddUnresolvedSet(const ASTUnresolvedSet &Set);
/// \brief Emit a CXXCtorInitializer array.
- void AddCXXCtorInitializers(ArrayRef<CXXCtorInitializer*> CtorInits);
+ void AddCXXCtorInitializers(ArrayRef<CXXCtorInitializer *> CtorInits);
void AddCXXDefinitionData(const CXXRecordDecl *D);
@@ -955,6 +983,7 @@ public:
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
bool AllowASTWithErrors = false, bool IncludeTimestamps = true);
~PCHGenerator() override;
+
void InitializeSema(Sema &S) override { SemaPtr = &S; }
void HandleTranslationUnit(ASTContext &Ctx) override;
ASTMutationListener *GetASTMutationListener() override;
@@ -962,6 +991,6 @@ public:
bool hasEmittedPCH() const { return Buffer->IsComplete; }
};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_SERIALIZATION_ASTWRITER_H
diff --git a/include/clang/Serialization/ContinuousRangeMap.h b/include/clang/Serialization/ContinuousRangeMap.h
index 244b01b22aa1..24bfadd0f867 100644
--- a/include/clang/Serialization/ContinuousRangeMap.h
+++ b/include/clang/Serialization/ContinuousRangeMap.h
@@ -1,4 +1,4 @@
-//===--- ContinuousRangeMap.h - Map with int range as key -------*- C++ -*-===//
+//===- ContinuousRangeMap.h - Map with int range as key ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -18,6 +18,7 @@
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/SmallVector.h"
#include <algorithm>
+#include <cassert>
#include <utility>
namespace clang {
@@ -35,14 +36,15 @@ namespace clang {
template <typename Int, typename V, unsigned InitialCapacity>
class ContinuousRangeMap {
public:
- typedef std::pair<Int, V> value_type;
- typedef value_type &reference;
- typedef const value_type &const_reference;
- typedef value_type *pointer;
- typedef const value_type *const_pointer;
+ using value_type = std::pair<Int, V>;
+ using reference = value_type &;
+ using const_reference = const value_type &;
+ using pointer = value_type *;
+ using const_pointer = const value_type *;
private:
- typedef SmallVector<value_type, InitialCapacity> Representation;
+ using Representation = SmallVector<value_type, InitialCapacity>;
+
Representation Rep;
struct Compare {
@@ -52,7 +54,7 @@ private:
bool operator ()(Int L, const_reference R) const {
return L < R.first;
}
- bool operator ()(Int L, Int R) const {
+ bool operator ()(Int L, Int R) const {
return L < R;
}
bool operator ()(const_reference L, const_reference R) const {
@@ -80,8 +82,8 @@ public:
Rep.insert(I, Val);
}
- typedef typename Representation::iterator iterator;
- typedef typename Representation::const_iterator const_iterator;
+ using iterator = typename Representation::iterator;
+ using const_iterator = typename Representation::const_iterator;
iterator begin() { return Rep.begin(); }
iterator end() { return Rep.end(); }
@@ -108,13 +110,12 @@ public:
/// from a set of values.
class Builder {
ContinuousRangeMap &Self;
-
+
+ public:
+ explicit Builder(ContinuousRangeMap &Self) : Self(Self) {}
Builder(const Builder&) = delete;
Builder &operator=(const Builder&) = delete;
- public:
- explicit Builder(ContinuousRangeMap &Self) : Self(Self) { }
-
~Builder() {
std::sort(Self.Rep.begin(), Self.Rep.end(), Compare());
std::unique(Self.Rep.begin(), Self.Rep.end(),
@@ -131,9 +132,10 @@ public:
Self.Rep.push_back(Val);
}
};
+
friend class Builder;
};
-}
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_SERIALIZATION_CONTINUOUSRANGEMAP_H
diff --git a/include/clang/Serialization/ModuleManager.h b/include/clang/Serialization/ModuleManager.h
index fae387cac7e2..147a6910aa29 100644
--- a/include/clang/Serialization/ModuleManager.h
+++ b/include/clang/Serialization/ModuleManager.h
@@ -1,4 +1,4 @@
-//===--- ModuleManager.cpp - Module Manager ---------------------*- C++ -*-===//
+//===- ModuleManager.cpp - Module Manager -----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,15 +15,30 @@
#ifndef LLVM_CLANG_SERIALIZATION_MODULEMANAGER_H
#define LLVM_CLANG_SERIALIZATION_MODULEMANAGER_H
-#include "clang/Basic/FileManager.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/Module.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Serialization/Module.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator.h"
+#include "llvm/ADT/iterator_range.h"
+#include <cstdint>
+#include <ctime>
+#include <memory>
+#include <string>
+#include <utility>
-namespace clang {
+namespace clang {
+class FileEntry;
+class FileManager;
class GlobalModuleIndex;
+class HeaderSearch;
class MemoryBufferCache;
class ModuleMap;
class PCHContainerReader;
@@ -58,6 +73,9 @@ class ModuleManager {
/// \brief Knows how to unwrap module containers.
const PCHContainerReader &PCHContainerRdr;
+ /// \brief Preprocessor's HeaderSearchInfo containing the module map.
+ const HeaderSearch &HeaderSearchInfo;
+
/// \brief A lookup of in-memory (virtual file) buffers
llvm::DenseMap<const FileEntry *, std::unique_ptr<llvm::MemoryBuffer>>
InMemoryBuffers;
@@ -79,14 +97,12 @@ class ModuleManager {
///
/// The global module index will actually be owned by the ASTReader; this is
/// just an non-owning pointer.
- GlobalModuleIndex *GlobalIndex;
+ GlobalModuleIndex *GlobalIndex = nullptr;
/// \brief State used by the "visit" operation to avoid malloc traffic in
/// calls to visit().
struct VisitState {
- explicit VisitState(unsigned N)
- : VisitNumber(N, 0), NextVisitNumber(1), NextState(nullptr)
- {
+ explicit VisitState(unsigned N) : VisitNumber(N, 0) {
Stack.reserve(N);
}
@@ -103,46 +119,47 @@ class ModuleManager {
SmallVector<unsigned, 4> VisitNumber;
/// \brief The next visit number to use to mark visited module files.
- unsigned NextVisitNumber;
+ unsigned NextVisitNumber = 1;
/// \brief The next visit state.
- VisitState *NextState;
+ VisitState *NextState = nullptr;
};
/// \brief The first visit() state in the chain.
- VisitState *FirstVisitState;
+ VisitState *FirstVisitState = nullptr;
VisitState *allocateVisitState();
void returnVisitState(VisitState *State);
public:
- typedef llvm::pointee_iterator<
- SmallVectorImpl<std::unique_ptr<ModuleFile>>::iterator>
- ModuleIterator;
- typedef llvm::pointee_iterator<
- SmallVectorImpl<std::unique_ptr<ModuleFile>>::const_iterator>
- ModuleConstIterator;
- typedef llvm::pointee_iterator<
- SmallVectorImpl<std::unique_ptr<ModuleFile>>::reverse_iterator>
- ModuleReverseIterator;
- typedef std::pair<uint32_t, StringRef> ModuleOffset;
+ using ModuleIterator = llvm::pointee_iterator<
+ SmallVectorImpl<std::unique_ptr<ModuleFile>>::iterator>;
+ using ModuleConstIterator = llvm::pointee_iterator<
+ SmallVectorImpl<std::unique_ptr<ModuleFile>>::const_iterator>;
+ using ModuleReverseIterator = llvm::pointee_iterator<
+ SmallVectorImpl<std::unique_ptr<ModuleFile>>::reverse_iterator>;
+ using ModuleOffset = std::pair<uint32_t, StringRef>;
explicit ModuleManager(FileManager &FileMgr, MemoryBufferCache &PCMCache,
- const PCHContainerReader &PCHContainerRdr);
+ const PCHContainerReader &PCHContainerRdr,
+ const HeaderSearch &HeaderSearchInfo);
~ModuleManager();
/// \brief Forward iterator to traverse all loaded modules.
ModuleIterator begin() { return Chain.begin(); }
+
/// \brief Forward iterator end-point to traverse all loaded modules
ModuleIterator end() { return Chain.end(); }
/// \brief Const forward iterator to traverse all loaded modules.
ModuleConstIterator begin() const { return Chain.begin(); }
+
/// \brief Const forward iterator end-point to traverse all loaded modules
ModuleConstIterator end() const { return Chain.end(); }
/// \brief Reverse iterator to traverse all loaded modules.
ModuleReverseIterator rbegin() { return Chain.rbegin(); }
+
/// \brief Reverse iterator end-point to traverse all loaded modules.
ModuleReverseIterator rend() { return Chain.rend(); }
@@ -163,8 +180,11 @@ public:
/// \brief Returns the module associated with the given index
ModuleFile &operator[](unsigned Index) const { return *Chain[Index]; }
- /// \brief Returns the module associated with the given name
- ModuleFile *lookup(StringRef Name) const;
+ /// \brief Returns the module associated with the given file name.
+ ModuleFile *lookupByFileName(StringRef FileName) const;
+
+ /// \brief Returns the module associated with the given module name.
+ ModuleFile *lookupByModuleName(StringRef ModName) const;
/// \brief Returns the module associated with the given module file.
ModuleFile *lookup(const FileEntry *File) const;
@@ -179,15 +199,18 @@ public:
enum AddModuleResult {
/// \brief The module file had already been loaded.
AlreadyLoaded,
+
/// \brief The module file was just loaded in response to this call.
NewlyLoaded,
+
/// \brief The module file is missing.
Missing,
+
/// \brief The module file is out-of-date.
OutOfDate
};
- typedef ASTFileSignature(*ASTFileSignatureReader)(StringRef);
+ using ASTFileSignatureReader = ASTFileSignature (*)(StringRef);
/// \brief Attempts to create a new module and add it to the list of known
/// modules.
@@ -298,6 +321,8 @@ public:
MemoryBufferCache &getPCMCache() const { return *PCMCache; }
};
-} } // end namespace clang::serialization
+} // namespace serialization
+
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_SERIALIZATION_MODULEMANAGER_H
diff --git a/include/clang/StaticAnalyzer/Checkers/Checkers.td b/include/clang/StaticAnalyzer/Checkers/Checkers.td
index 82ab720af8dc..e510e84e938a 100644
--- a/include/clang/StaticAnalyzer/Checkers/Checkers.td
+++ b/include/clang/StaticAnalyzer/Checkers/Checkers.td
@@ -132,6 +132,10 @@ def DynamicTypePropagation : Checker<"DynamicTypePropagation">,
HelpText<"Generate dynamic type information">,
DescFile<"DynamicTypePropagation.cpp">;
+def NonnullGlobalConstantsChecker: Checker<"NonnilStringConstants">,
+ HelpText<"Assume that const string-like globals are non-null">,
+ DescFile<"NonilStringConstantsChecker.cpp">;
+
} // end "core"
let ParentPackage = CoreAlpha in {
@@ -184,6 +188,10 @@ def DynamicTypeChecker : Checker<"DynamicTypeChecker">,
HelpText<"Check for cases where the dynamic and the static type of an object are unrelated.">,
DescFile<"DynamicTypeChecker.cpp">;
+def StackAddrAsyncEscapeChecker : Checker<"StackAddressAsyncEscape">,
+ HelpText<"Check that addresses to stack memory do not escape the function">,
+ DescFile<"StackAddrEscapeChecker.cpp">;
+
} // end "alpha.core"
let ParentPackage = Nullability in {
@@ -284,6 +292,11 @@ def VirtualCallChecker : Checker<"VirtualCall">,
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">;
+
def IteratorRangeChecker : Checker<"IteratorRange">,
HelpText<"Check for iterators used outside their valid ranges">,
DescFile<"IteratorChecker.cpp">;
@@ -740,10 +753,6 @@ def ExplodedGraphViewer : Checker<"ViewExplodedGraph">,
HelpText<"View Exploded Graphs using GraphViz">,
DescFile<"DebugCheckers.cpp">;
-def BugHashDumper : Checker<"DumpBugHash">,
- HelpText<"Dump the bug hash for all statements.">,
- DescFile<"DebugCheckers.cpp">;
-
} // end "debug"
diff --git a/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h b/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h
index 25886545e2f7..e5e857e97029 100644
--- a/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h
+++ b/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h
@@ -145,9 +145,11 @@ public:
/// 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
+ AnyObj,
+ /// Indicates that the tracked object is a generalized object.
+ Generalized
};
-
+
private:
Kind K;
ObjKind O;
diff --git a/include/clang/StaticAnalyzer/Core/Analyses.def b/include/clang/StaticAnalyzer/Core/Analyses.def
index 04bf41bfde4f..281a2ac3a66f 100644
--- a/include/clang/StaticAnalyzer/Core/Analyses.def
+++ b/include/clang/StaticAnalyzer/Core/Analyses.def
@@ -28,9 +28,10 @@ ANALYSIS_CONSTRAINTS(Z3Constraints, "z3", "Use Z3 contraint solver", CreateZ3Con
#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN)
#endif
-ANALYSIS_DIAGNOSTICS(HTML, "html", "Output analysis results using HTML", createHTMLDiagnosticConsumer)
+ANALYSIS_DIAGNOSTICS(HTML, "html", "Output analysis results using HTML", createHTMLDiagnosticConsumer)
+ANALYSIS_DIAGNOSTICS(HTML_SINGLE_FILE, "html-single-file", "Output analysis results using HTML (not allowing for multi-file bugs)", createHTMLSingleFileDiagnosticConsumer)
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 mult-file bugs)", createPlistMultiFileDiagnosticConsumer)
+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(TEXT, "text", "Text output of analysis results", createTextPathDiagnosticConsumer)
diff --git a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
index 5dd6bdf38496..ce50cc582d1e 100644
--- a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
+++ b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
@@ -214,6 +214,9 @@ private:
/// \sa IncludeLifetimeInCFG
Optional<bool> IncludeLifetimeInCFG;
+ /// \sa IncludeLoopExitInCFG
+ Optional<bool> IncludeLoopExitInCFG;
+
/// \sa mayInlineCXXStandardLibrary
Optional<bool> InlineCXXStandardLibrary;
@@ -275,6 +278,9 @@ private:
/// \sa shouldWidenLoops
Optional<bool> WidenLoops;
+ /// \sa shouldUnrollLoops
+ Optional<bool> UnrollLoops;
+
/// \sa shouldDisplayNotesAsEvents
Optional<bool> DisplayNotesAsEvents;
@@ -415,6 +421,13 @@ public:
/// 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 C++ standard library functions may be considered
/// for inlining.
///
@@ -560,6 +573,10 @@ public:
/// 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.
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
index 0f1eb096c495..cd1355d03b63 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
@@ -17,7 +17,7 @@
#include "clang/Basic/SourceLocation.h"
#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
-#include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h"
#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h
index b72bce5fc9f8..2043896fd26f 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h
@@ -1,4 +1,4 @@
-//===--- BugReporterVisitor.h - Generate PathDiagnostics -------*- C++ -*-===//
+//===--- BugReporterVisitors.h - Generate PathDiagnostics -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTERVISITOR_H
-#define LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTERVISITOR_H
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTERVISITORS_H
+#define LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTERVISITORS_H
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
#include "llvm/ADT/FoldingSet.h"
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
index 3e0913ec4eea..15b930bc3f1e 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
@@ -15,7 +15,7 @@
#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_ANALYSISMANAGER_H
#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_ANALYSISMANAGER_H
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
index fa7ee62ab704..9fec217aca72 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
@@ -19,7 +19,7 @@
#include "clang/AST/DeclCXX.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
#include "clang/Basic/SourceManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
@@ -436,20 +436,7 @@ public:
return cast<FunctionDecl>(CallEvent::getDecl());
}
- RuntimeDefinition getRuntimeDefinition() const override {
- const FunctionDecl *FD = getDecl();
- // Note that the AnalysisDeclContext will have the FunctionDecl with
- // the definition (if one exists).
- if (FD) {
- AnalysisDeclContext *AD =
- getLocationContext()->getAnalysisDeclContext()->
- getManager()->getContext(FD);
- if (AD->getBody())
- return RuntimeDefinition(AD->getDecl());
- }
-
- return RuntimeDefinition();
- }
+ RuntimeDefinition getRuntimeDefinition() const override;
bool argumentsMayEscape() const override;
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
index e380982d43ea..78d38a3d598d 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
@@ -196,6 +196,13 @@ public:
return getState()->getSVal(S, getLocationContext());
}
+ /// \brief Returns true if the value of \p E is greater than or equal to \p
+ /// Val under unsigned comparison
+ bool isGreaterOrEqual(const Expr *E, unsigned long long Val);
+
+ /// Returns true if the value of \p E is negative.
+ bool isNegative(const Expr *E);
+
/// \brief Generates a new transition in the program state graph
/// (ExplodedGraph). Uses the default CheckerContext predecessor node.
///
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
index 12ec5b6c64a4..7472a7147fca 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
@@ -16,7 +16,7 @@
#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_COREENGINE_H
#include "clang/AST/Expr.h"
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h"
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
index a66e1a1aed01..c63ed4a013aa 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
@@ -14,7 +14,7 @@
#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_ENVIRONMENT_H
#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_ENVIRONMENT_H
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
#include "llvm/ADT/ImmutableMap.h"
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
index a710ae68be60..dcea5e461d27 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
@@ -20,14 +20,14 @@
#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPLODEDGRAPH_H
#include "clang/AST/Decl.h"
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
#include "clang/Analysis/ProgramPoint.h"
#include "clang/Analysis/Support/BumpVector.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/GraphTraits.h"
-#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SetVector.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Casting.h"
#include <memory>
@@ -404,7 +404,7 @@ private:
};
class ExplodedNodeSet {
- typedef llvm::SmallPtrSet<ExplodedNode*,5> ImplTy;
+ typedef llvm::SmallSetVector<ExplodedNode*, 4> ImplTy;
ImplTy Impl;
public:
@@ -424,7 +424,7 @@ public:
unsigned size() const { return Impl.size(); }
bool empty() const { return Impl.empty(); }
- bool erase(ExplodedNode *N) { return Impl.erase(N); }
+ bool erase(ExplodedNode *N) { return Impl.remove(N); }
void clear() { Impl.clear(); }
void insert(const ExplodedNodeSet &S) {
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
index 067d70610868..712cd6361e11 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -196,6 +196,8 @@ public:
void ProcessStmt(const CFGStmt S, ExplodedNode *Pred);
+ void ProcessLoopExit(const Stmt* S, ExplodedNode *Pred);
+
void ProcessInitializer(const CFGInitializer I, ExplodedNode *Pred);
void ProcessImplicitDtor(const CFGImplicitDtor D, ExplodedNode *Pred);
@@ -330,9 +332,9 @@ public:
void Visit(const Stmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst);
/// VisitArraySubscriptExpr - Transfer function for array accesses.
- void VisitLvalArraySubscriptExpr(const ArraySubscriptExpr *Ex,
- ExplodedNode *Pred,
- ExplodedNodeSet &Dst);
+ void VisitArraySubscriptExpr(const ArraySubscriptExpr *Ex,
+ ExplodedNode *Pred,
+ ExplodedNodeSet &Dst);
/// VisitGCCAsmStmt - Transfer function logic for inline asm.
void VisitGCCAsmStmt(const GCCAsmStmt *A, ExplodedNode *Pred,
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h b/include/clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h
new file mode 100644
index 000000000000..a4c505ce5f23
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h
@@ -0,0 +1,50 @@
+//===--- LoopUnrolling.h - Unroll loops -------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// This header contains the declarations of functions which are used to decide
+/// which loops should be completely unrolled and mark their corresponding
+/// CFGBlocks. It is done by tracking a stack of loops in the ProgramState. This
+/// way specific loops can be marked as completely unrolled. For considering a
+/// loop to be completely unrolled it has to fulfill the following requirements:
+/// - Currently only forStmts can be considered.
+/// - The bound has to be known.
+/// - The counter variable has not escaped before/in the body of the loop and
+/// changed only in the increment statement corresponding to the loop. It also
+/// has to be initialized by a literal in the corresponding initStmt.
+/// - Does not contain goto, switch and returnStmt.
+///
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_LOOPUNROLLING_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_LOOPUNROLLING_H
+
+#include "clang/Analysis/CFG.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
+namespace clang {
+namespace ento {
+class AnalysisManager;
+
+/// Returns if the given State indicates that is inside a completely unrolled
+/// loop.
+bool isUnrolledState(ProgramStateRef State);
+
+/// Updates the stack of loops contained by the ProgramState.
+ProgramStateRef updateLoopStack(const Stmt *LoopStmt, ASTContext &ASTCtx,
+ ExplodedNode* Pred, unsigned maxVisitOnPath);
+
+/// Updates the given ProgramState. In current implementation it removes the top
+/// element of the stack of loops.
+ProgramStateRef processLoopEnd(const Stmt *LoopStmt, ProgramStateRef State);
+
+} // end namespace ento
+} // end namespace clang
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
index 29b1c4cdca04..8ab665623088 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
@@ -21,7 +21,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/ExprObjC.h"
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
#include "clang/Basic/LLVM.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
#include "llvm/ADT/FoldingSet.h"
@@ -1412,21 +1412,18 @@ public:
bool hasTrait(SymbolRef Sym, InvalidationKinds IK) const;
bool hasTrait(const MemRegion *MR, InvalidationKinds IK) const;
};
-
-} // end GR namespace
-
-} // end clang namespace
//===----------------------------------------------------------------------===//
// Pretty-printing regions.
//===----------------------------------------------------------------------===//
-
-namespace llvm {
-static inline raw_ostream &operator<<(raw_ostream &os,
- const clang::ento::MemRegion* R) {
+inline raw_ostream &operator<<(raw_ostream &os,
+ const clang::ento::MemRegion *R) {
R->dumpToStream(os);
return os;
}
-} // end llvm namespace
+
+} // namespace ento
+
+} // namespace clang
#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
index e3a2164b11ff..dd2564b0a3c3 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
@@ -308,8 +308,12 @@ public:
/// \brief Return the value bound to the specified location.
/// Returns UnknownVal() if none found.
- SVal getSVal(const MemRegion* R) const;
+ SVal getSVal(const MemRegion* R, QualType T = QualType()) const;
+ /// \brief Return the value bound to the specified location, assuming
+ /// that the value is a scalar integer or an enumeration or a pointer.
+ /// Returns UnknownVal() if none found or the region is not known to hold
+ /// a value of such type.
SVal getSValAsScalarOrLoc(const MemRegion *R) const;
/// \brief Visits the symbols reachable from the given SVal using the provided
@@ -758,9 +762,10 @@ inline SVal ProgramState::getRawSVal(Loc LV, QualType T) const {
return getStateManager().StoreMgr->getBinding(getStore(), LV, T);
}
-inline SVal ProgramState::getSVal(const MemRegion* R) const {
+inline SVal ProgramState::getSVal(const MemRegion* R, QualType T) const {
return getStateManager().StoreMgr->getBinding(getStore(),
- loc::MemRegionVal(R));
+ loc::MemRegionVal(R),
+ T);
}
inline BasicValueFactory &ProgramState::getBasicVals() const {
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
index 935f0018324a..06132587b4aa 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
@@ -103,9 +103,6 @@ public:
return *static_cast<const T *>(this);
}
- /// BufferTy - A temporary buffer to hold a set of SVals.
- typedef SmallVector<SVal,5> BufferTy;
-
inline unsigned getRawKind() const { return Kind; }
inline BaseKind getBaseKind() const { return (BaseKind) (Kind & BaseMask); }
inline unsigned getSubKind() const { return (Kind & ~BaseMask) >> BaseBits; }
@@ -198,6 +195,10 @@ public:
}
};
+inline raw_ostream &operator<<(raw_ostream &os, clang::ento::SVal V) {
+ V.dumpToStream(os);
+ return os;
+}
class UndefinedVal : public SVal {
public:
@@ -622,11 +623,6 @@ private:
} // end clang namespace
namespace llvm {
-static inline raw_ostream &operator<<(raw_ostream &os,
- clang::ento::SVal V) {
- V.dumpToStream(os);
- return os;
-}
template <typename T> struct isPodLike;
template <> struct isPodLike<clang::ento::SVal> {
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
index 7619f22f4013..25d20a17afaa 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
@@ -51,7 +51,7 @@ public:
virtual ~StoreManager() {}
/// Return the value bound to specified location in a given state.
- /// \param[in] store The analysis state.
+ /// \param[in] store The store in which to make the lookup.
/// \param[in] loc The symbolic memory location.
/// \param[in] T An optional type that provides a hint indicating the
/// expected type of the returned value. This is used if the value is
@@ -83,12 +83,12 @@ public:
return getDefaultBinding(lcv.getStore(), lcv.getRegion());
}
- /// Return a state with the specified value bound to the given location.
- /// \param[in] store The analysis state.
+ /// Return a store with the specified value bound to the given location.
+ /// \param[in] store The store in which to make the binding.
/// \param[in] loc The symbolic memory location.
/// \param[in] val The value to bind to location \c loc.
- /// \return A pointer to a ProgramState object that contains the same
- /// bindings as \c state with the addition of having the value specified
+ /// \return A StoreRef object that contains the same
+ /// bindings as \c store with the addition of having the value specified
/// by \c val bound to the location given for \c loc.
virtual StoreRef Bind(Store store, Loc loc, SVal val) = 0;
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h
index f72033955ec3..9780d0144746 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h
@@ -98,6 +98,12 @@ public:
virtual const MemRegion *getOriginRegion() const { return nullptr; }
};
+inline raw_ostream &operator<<(raw_ostream &os,
+ const clang::ento::SymExpr *SE) {
+ SE->dumpToStream(os);
+ return os;
+}
+
typedef const SymExpr *SymbolRef;
typedef SmallVector<SymbolRef, 2> SymbolRefSmallVectorTy;
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
index e9701142cd9e..7d2e5ad8ba91 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
@@ -17,7 +17,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
#include "clang/Basic/LLVM.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h"
@@ -633,11 +633,4 @@ public:
} // end clang namespace
-namespace llvm {
-static inline raw_ostream &operator<<(raw_ostream &os,
- const clang::ento::SymExpr *SE) {
- SE->dumpToStream(os);
- return os;
-}
-} // end llvm namespace
#endif
diff --git a/include/clang/Tooling/ASTDiff/ASTDiff.h b/include/clang/Tooling/ASTDiff/ASTDiff.h
new file mode 100644
index 000000000000..dd11c91ac0dd
--- /dev/null
+++ b/include/clang/Tooling/ASTDiff/ASTDiff.h
@@ -0,0 +1,127 @@
+//===- ASTDiff.h - AST differencing API -----------------------*- C++ -*- -===//
+//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file specifies an interface that can be used to compare C++ syntax
+// trees.
+//
+// We use the gumtree algorithm which combines a heuristic top-down search that
+// is able to match large subtrees that are equivalent, with an optimal
+// algorithm to match small subtrees.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_ASTDIFF_ASTDIFF_H
+#define LLVM_CLANG_TOOLING_ASTDIFF_ASTDIFF_H
+
+#include "clang/Tooling/ASTDiff/ASTDiffInternal.h"
+
+namespace clang {
+namespace diff {
+
+enum ChangeKind {
+ None,
+ Delete, // (Src): delete node Src.
+ Update, // (Src, Dst): update the value of node Src to match Dst.
+ Insert, // (Src, Dst, Pos): insert Src as child of Dst at offset Pos.
+ Move, // (Src, Dst, Pos): move Src to be a child of Dst at offset Pos.
+ UpdateMove // Same as Move plus Update.
+};
+
+/// Represents a Clang AST node, alongside some additional information.
+struct Node {
+ NodeId Parent, LeftMostDescendant, RightMostDescendant;
+ int Depth, Height, Shift = 0;
+ ast_type_traits::DynTypedNode ASTNode;
+ SmallVector<NodeId, 4> Children;
+ ChangeKind Change = None;
+
+ ast_type_traits::ASTNodeKind getType() const;
+ StringRef getTypeLabel() const;
+ bool isLeaf() const { return Children.empty(); }
+ llvm::Optional<StringRef> getIdentifier() const;
+ llvm::Optional<std::string> getQualifiedIdentifier() const;
+};
+
+class ASTDiff {
+public:
+ ASTDiff(SyntaxTree &Src, SyntaxTree &Dst, const ComparisonOptions &Options);
+ ~ASTDiff();
+
+ // Returns the ID of the node that is mapped to the given node in SourceTree.
+ NodeId getMapped(const SyntaxTree &SourceTree, NodeId Id) const;
+
+ class Impl;
+
+private:
+ std::unique_ptr<Impl> DiffImpl;
+};
+
+/// SyntaxTree objects represent subtrees of the AST.
+/// They can be constructed from any Decl or Stmt.
+class SyntaxTree {
+public:
+ /// Constructs a tree from a translation unit.
+ SyntaxTree(ASTContext &AST);
+ /// Constructs a tree from any AST node.
+ template <class T>
+ SyntaxTree(T *Node, ASTContext &AST)
+ : TreeImpl(llvm::make_unique<Impl>(this, Node, AST)) {}
+ SyntaxTree(SyntaxTree &&Other) = default;
+ ~SyntaxTree();
+
+ const ASTContext &getASTContext() const;
+ StringRef getFilename() const;
+
+ int getSize() const;
+ NodeId getRootId() const;
+ using PreorderIterator = NodeId;
+ PreorderIterator begin() const;
+ PreorderIterator end() const;
+
+ const Node &getNode(NodeId Id) const;
+ int findPositionInParent(NodeId Id) const;
+
+ // Returns the starting and ending offset of the node in its source file.
+ std::pair<unsigned, unsigned> getSourceRangeOffsets(const Node &N) const;
+
+ /// Serialize the node attributes to a string representation. This should
+ /// uniquely distinguish nodes of the same kind. Note that this function just
+ /// returns a representation of the node value, not considering descendants.
+ std::string getNodeValue(NodeId Id) const;
+ std::string getNodeValue(const Node &Node) const;
+
+ class Impl;
+ std::unique_ptr<Impl> TreeImpl;
+};
+
+struct ComparisonOptions {
+ /// During top-down matching, only consider nodes of at least this height.
+ int MinHeight = 2;
+
+ /// During bottom-up matching, match only nodes with at least this value as
+ /// the ratio of their common descendants.
+ double MinSimilarity = 0.5;
+
+ /// Whenever two subtrees are matched in the bottom-up phase, the optimal
+ /// mapping is computed, unless the size of either subtrees exceeds this.
+ int MaxSize = 100;
+
+ bool StopAfterTopDown = false;
+
+ /// Returns false if the nodes should never be matched.
+ bool isMatchingAllowed(const Node &N1, const Node &N2) const {
+ return N1.getType().isSame(N2.getType());
+ }
+};
+
+} // end namespace diff
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Tooling/ASTDiff/ASTDiffInternal.h b/include/clang/Tooling/ASTDiff/ASTDiffInternal.h
new file mode 100644
index 000000000000..a76ad37336a6
--- /dev/null
+++ b/include/clang/Tooling/ASTDiff/ASTDiffInternal.h
@@ -0,0 +1,48 @@
+//===- ASTDiffInternal.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_TOOLING_ASTDIFF_ASTDIFFINTERNAL_H
+#define LLVM_CLANG_TOOLING_ASTDIFF_ASTDIFFINTERNAL_H
+
+#include "clang/AST/ASTTypeTraits.h"
+
+namespace clang {
+namespace diff {
+
+using DynTypedNode = ast_type_traits::DynTypedNode;
+
+class SyntaxTree;
+class SyntaxTreeImpl;
+struct ComparisonOptions;
+
+/// Within a tree, this identifies a node by its preorder offset.
+struct NodeId {
+private:
+ static constexpr int InvalidNodeId = -1;
+
+public:
+ int Id;
+
+ NodeId() : Id(InvalidNodeId) {}
+ NodeId(int Id) : Id(Id) {}
+
+ operator int() const { return Id; }
+ NodeId &operator++() { return ++Id, *this; }
+ NodeId &operator--() { return --Id, *this; }
+ // Support defining iterators on NodeId.
+ NodeId &operator*() { return *this; }
+
+ bool isValid() const { return Id != InvalidNodeId; }
+ bool isInvalid() const { return Id == InvalidNodeId; }
+};
+
+} // end namespace diff
+} // end namespace clang
+#endif
diff --git a/include/clang/Tooling/CommonOptionsParser.h b/include/clang/Tooling/CommonOptionsParser.h
index 3d630c5f7609..15e8161dd76f 100644
--- a/include/clang/Tooling/CommonOptionsParser.h
+++ b/include/clang/Tooling/CommonOptionsParser.h
@@ -27,8 +27,10 @@
#ifndef LLVM_CLANG_TOOLING_COMMONOPTIONSPARSER_H
#define LLVM_CLANG_TOOLING_COMMONOPTIONSPARSER_H
+#include "clang/Tooling/ArgumentsAdjusters.h"
#include "clang/Tooling/CompilationDatabase.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Error.h"
namespace clang {
namespace tooling {
@@ -84,14 +86,19 @@ public:
///
/// All options not belonging to \p Category become hidden.
///
- /// I also allows calls to set the required number of positional parameters.
- ///
- /// This constructor exits program in case of error.
+ /// It also allows calls to set the required number of positional parameters.
CommonOptionsParser(int &argc, const char **argv,
llvm::cl::OptionCategory &Category,
llvm::cl::NumOccurrencesFlag OccurrencesFlag,
const char *Overview = nullptr);
+ /// \brief A factory method that is similar to the above constructor, except
+ /// this returns an error instead exiting the program on error.
+ static llvm::Expected<CommonOptionsParser>
+ create(int &argc, const char **argv, llvm::cl::OptionCategory &Category,
+ llvm::cl::NumOccurrencesFlag OccurrencesFlag,
+ const char *Overview = nullptr);
+
/// Returns a reference to the loaded compilations database.
CompilationDatabase &getCompilations() {
return *Compilations;
@@ -102,13 +109,46 @@ public:
return SourcePathList;
}
+ /// Returns the argument adjuster calculated from "--extra-arg" and
+ //"--extra-arg-before" options.
+ ArgumentsAdjuster getArgumentsAdjuster() { return Adjuster; }
+
static const char *const HelpMessage;
private:
+ CommonOptionsParser() = default;
+
+ llvm::Error init(int &argc, const char **argv,
+ llvm::cl::OptionCategory &Category,
+ llvm::cl::NumOccurrencesFlag OccurrencesFlag,
+ const char *Overview);
+
std::unique_ptr<CompilationDatabase> Compilations;
std::vector<std::string> SourcePathList;
- std::vector<std::string> ExtraArgsBefore;
- std::vector<std::string> ExtraArgsAfter;
+ ArgumentsAdjuster Adjuster;
+};
+
+class ArgumentsAdjustingCompilations : public CompilationDatabase {
+public:
+ ArgumentsAdjustingCompilations(
+ std::unique_ptr<CompilationDatabase> Compilations)
+ : Compilations(std::move(Compilations)) {}
+
+ void appendArgumentsAdjuster(ArgumentsAdjuster Adjuster);
+
+ std::vector<CompileCommand>
+ getCompileCommands(StringRef FilePath) const override;
+
+ std::vector<std::string> getAllFiles() const override;
+
+ std::vector<CompileCommand> getAllCompileCommands() const override;
+
+private:
+ std::unique_ptr<CompilationDatabase> Compilations;
+ std::vector<ArgumentsAdjuster> Adjusters;
+
+ std::vector<CompileCommand>
+ adjustCommands(std::vector<CompileCommand> Commands) const;
};
} // namespace tooling
diff --git a/include/clang/Tooling/CompilationDatabase.h b/include/clang/Tooling/CompilationDatabase.h
index e988b84b6eae..bc3e67b77de2 100644
--- a/include/clang/Tooling/CompilationDatabase.h
+++ b/include/clang/Tooling/CompilationDatabase.h
@@ -64,10 +64,12 @@ struct CompileCommand {
/// \brief Interface for compilation databases.
///
-/// A compilation database allows the user to retrieve all compile command lines
-/// that a specified file is compiled with in a project.
-/// The retrieved compile command lines can be used to run clang tools over
-/// a subset of the files in a project.
+/// A compilation database allows the user to retrieve compile command lines
+/// for the files in a project.
+///
+/// Many implementations are enumerable, allowing all command lines to be
+/// retrieved. These can be used to run clang tools over a subset of the files
+/// in a project.
class CompilationDatabase {
public:
virtual ~CompilationDatabase();
@@ -104,7 +106,7 @@ public:
/// \brief Returns all compile commands in which the specified file was
/// compiled.
///
- /// This includes compile comamnds that span multiple source files.
+ /// This includes compile commands that span multiple source files.
/// For example, consider a project with the following compilations:
/// $ clang++ -o test a.cc b.cc t.cc
/// $ clang++ -o production a.cc b.cc -DPRODUCTION
@@ -114,7 +116,10 @@ public:
StringRef FilePath) const = 0;
/// \brief Returns the list of all files available in the compilation database.
- virtual std::vector<std::string> getAllFiles() const = 0;
+ ///
+ /// By default, returns nothing. Implementations should override this if they
+ /// can enumerate their source files.
+ virtual std::vector<std::string> getAllFiles() const { return {}; }
/// \brief Returns all compile commands for all the files in the compilation
/// database.
@@ -122,7 +127,10 @@ public:
/// FIXME: Add a layer in Tooling that provides an interface to run a tool
/// over all files in a compilation database. Not all build systems have the
/// ability to provide a feasible implementation for \c getAllCompileCommands.
- virtual std::vector<CompileCommand> getAllCompileCommands() const = 0;
+ ///
+ /// By default, this is implemented in terms of getAllFiles() and
+ /// getCompileCommands(). Subclasses may override this for efficiency.
+ virtual std::vector<CompileCommand> getAllCompileCommands() const;
};
/// \brief Interface for compilation database plugins.
@@ -149,6 +157,7 @@ public:
/// \brief A compilation database that returns a single compile command line.
///
/// Useful when we want a tool to behave more like a compiler invocation.
+/// This compilation database is not enumerable: getAllFiles() returns {}.
class FixedCompilationDatabase : public CompilationDatabase {
public:
/// \brief Creates a FixedCompilationDatabase from the arguments after "--".
@@ -182,6 +191,11 @@ public:
int &Argc, const char *const *Argv, std::string &ErrorMsg,
Twine Directory = ".");
+ /// Reads flags from the given file, one-per line.
+ /// Returns nullptr and sets ErrorMessage if we can't read the file.
+ static std::unique_ptr<FixedCompilationDatabase>
+ loadFromFile(StringRef Path, std::string &ErrorMsg);
+
/// \brief Constructs a compilation data base from a specified directory
/// and command line.
FixedCompilationDatabase(Twine Directory, ArrayRef<std::string> CommandLine);
@@ -194,17 +208,6 @@ public:
std::vector<CompileCommand>
getCompileCommands(StringRef FilePath) const override;
- /// \brief Returns the list of all files available in the compilation database.
- ///
- /// Note: This is always an empty list for the fixed compilation database.
- std::vector<std::string> getAllFiles() const override;
-
- /// \brief Returns all compile commands for all the files in the compilation
- /// database.
- ///
- /// Note: This is always an empty list for the fixed compilation database.
- std::vector<CompileCommand> getAllCompileCommands() const override;
-
private:
/// This is built up to contain a single entry vector to be returned from
/// getCompileCommands after adding the positional argument.
diff --git a/include/clang/Tooling/Core/Replacement.h b/include/clang/Tooling/Core/Replacement.h
index 8d4a22adf368..3fea9aee604c 100644
--- a/include/clang/Tooling/Core/Replacement.h
+++ b/include/clang/Tooling/Core/Replacement.h
@@ -255,7 +255,7 @@ class Replacements {
/// \brief Merges \p Replaces into the current replacements. \p Replaces
/// refers to code after applying the current replacements.
- Replacements merge(const Replacements &Replaces) const;
+ LLVM_NODISCARD Replacements merge(const Replacements &Replaces) const;
// Returns the affected ranges in the changed code.
std::vector<Range> getAffectedRanges() const;
diff --git a/include/clang/Tooling/Execution.h b/include/clang/Tooling/Execution.h
new file mode 100644
index 000000000000..1a44c4788c49
--- /dev/null
+++ b/include/clang/Tooling/Execution.h
@@ -0,0 +1,175 @@
+//===--- Execution.h - Executing clang frontend actions -*- 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 framework for executing clang frontend actions.
+//
+// The framework can be extended to support different execution plans including
+// standalone execution on the given TUs or parallel execution on all TUs in
+// the codebase.
+//
+// In order to enable multiprocessing execution, tool actions are expected to
+// output result into the ToolResults provided by the executor. The
+// `ToolResults` is an interface that abstracts how results are stored e.g.
+// in-memory for standalone execution or on-disk for large-scale execution.
+//
+// New executors can be registered as ToolExecutorPlugins via the
+// `ToolExecutorPluginRegistry`. CLI tools can use
+// `createExecutorFromCommandLineArgs` to create a specific registered executor
+// according to the command-line arguments.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_EXECUTION_H
+#define LLVM_CLANG_TOOLING_EXECUTION_H
+
+#include "clang/Tooling/CommonOptionsParser.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/Registry.h"
+
+namespace clang {
+namespace tooling {
+
+/// \brief An abstraction for the result of a tool execution. For example, the
+/// underlying result can be in-memory or on-disk.
+///
+/// Results should be string key-value pairs. For example, a refactoring tool
+/// can use source location as key and a replacement in YAML format as value.
+class ToolResults {
+public:
+ virtual ~ToolResults() = default;
+ virtual void addResult(StringRef Key, StringRef Value) = 0;
+ virtual std::vector<std::pair<std::string, std::string>> AllKVResults() = 0;
+ virtual void forEachResult(
+ llvm::function_ref<void(StringRef Key, StringRef Value)> Callback) = 0;
+};
+
+class InMemoryToolResults : public ToolResults {
+public:
+ void addResult(StringRef Key, StringRef Value) override;
+ std::vector<std::pair<std::string, std::string>> AllKVResults() override;
+ void forEachResult(llvm::function_ref<void(StringRef Key, StringRef Value)>
+ Callback) override;
+
+private:
+ std::vector<std::pair<std::string, std::string>> KVResults;
+};
+
+/// \brief The context of an execution, including the information about
+/// compilation and results.
+class ExecutionContext {
+public:
+ virtual ~ExecutionContext() {}
+
+ /// \brief Initializes a context. This does not take ownership of `Results`.
+ explicit ExecutionContext(ToolResults *Results) : Results(Results) {}
+
+ /// \brief Adds a KV pair to the result container of this execution.
+ void reportResult(StringRef Key, StringRef Value);
+
+ // Returns the source control system's revision number if applicable.
+ // Otherwise returns an empty string.
+ virtual std::string getRevision() { return ""; }
+
+ // Returns the corpus being analyzed, e.g. "llvm" for the LLVM codebase, if
+ // applicable.
+ virtual std::string getCorpus() { return ""; }
+
+ // Returns the currently processed compilation unit if available.
+ virtual std::string getCurrentCompilationUnit() { return ""; }
+
+private:
+ ToolResults *Results;
+};
+
+/// \brief Interface for executing clang frontend actions.
+///
+/// This can be extended to support running tool actions in different
+/// execution mode, e.g. on a specific set of TUs or many TUs in parallel.
+///
+/// New executors can be registered as ToolExecutorPlugins via the
+/// `ToolExecutorPluginRegistry`. CLI tools can use
+/// `createExecutorFromCommandLineArgs` to create a specific registered
+/// executor according to the command-line arguments.
+class ToolExecutor {
+public:
+ virtual ~ToolExecutor() {}
+
+ /// \brief Returns the name of a specific executor.
+ virtual StringRef getExecutorName() const = 0;
+
+ /// \brief Executes each action with a corresponding arguments adjuster.
+ virtual llvm::Error
+ execute(llvm::ArrayRef<
+ std::pair<std::unique_ptr<FrontendActionFactory>, ArgumentsAdjuster>>
+ Actions) = 0;
+
+ /// \brief Convenient functions for the above `execute`.
+ llvm::Error execute(std::unique_ptr<FrontendActionFactory> Action);
+ /// Executes an action with an argument adjuster.
+ llvm::Error execute(std::unique_ptr<FrontendActionFactory> Action,
+ ArgumentsAdjuster Adjuster);
+
+ /// \brief Returns a reference to the execution context.
+ ///
+ /// This should be passed to tool callbacks, and tool callbacks should report
+ /// results via the returned context.
+ virtual ExecutionContext *getExecutionContext() = 0;
+
+ /// \brief Returns a reference to the result container.
+ ///
+ /// NOTE: This should only be used after the execution finishes. Tool
+ /// callbacks should report results via `ExecutionContext` instead.
+ virtual ToolResults *getToolResults() = 0;
+
+ /// \brief Map a virtual file to be used while running the tool.
+ ///
+ /// \param FilePath The path at which the content will be mapped.
+ /// \param Content A buffer of the file's content.
+ virtual void mapVirtualFile(StringRef FilePath, StringRef Content) = 0;
+};
+
+/// \brief Interface for factories that create specific executors. This is also
+/// used as a plugin to be registered into ToolExecutorPluginRegistry.
+class ToolExecutorPlugin {
+public:
+ virtual ~ToolExecutorPlugin() {}
+
+ /// \brief Create an `ToolExecutor`.
+ ///
+ /// `OptionsParser` can be consumed (e.g. moved) if the creation succeeds.
+ virtual llvm::Expected<std::unique_ptr<ToolExecutor>>
+ create(CommonOptionsParser &OptionsParser) = 0;
+};
+
+/// \brief This creates a ToolExecutor that is in the global registry based on
+/// commandline arguments.
+///
+/// This picks the right executor based on the `--executor` option. This parses
+/// the commandline arguments with `CommonOptionsParser`, so caller does not
+/// need to parse again.
+///
+/// By default, this creates a `StandaloneToolExecutor` ("standalone") if
+/// `--executor` is not provided.
+llvm::Expected<std::unique_ptr<ToolExecutor>>
+createExecutorFromCommandLineArgs(int &argc, const char **argv,
+ llvm::cl::OptionCategory &Category,
+ const char *Overview = nullptr);
+
+namespace internal {
+llvm::Expected<std::unique_ptr<ToolExecutor>>
+createExecutorFromCommandLineArgsImpl(int &argc, const char **argv,
+ llvm::cl::OptionCategory &Category,
+ const char *Overview = nullptr);
+} // end namespace internal
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_EXECUTION_H
diff --git a/include/clang/Tooling/Refactoring/ASTSelection.h b/include/clang/Tooling/Refactoring/ASTSelection.h
new file mode 100644
index 000000000000..aa02a6899e8f
--- /dev/null
+++ b/include/clang/Tooling/Refactoring/ASTSelection.h
@@ -0,0 +1,155 @@
+//===--- ASTSelection.h - Clang refactoring library -----------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_REFACTOR_AST_SELECTION_H
+#define LLVM_CLANG_TOOLING_REFACTOR_AST_SELECTION_H
+
+#include "clang/AST/ASTTypeTraits.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
+#include <vector>
+
+namespace clang {
+
+class ASTContext;
+
+namespace tooling {
+
+enum class SourceSelectionKind {
+ /// A node that's not selected.
+ None,
+
+ /// A node that's considered to be selected because the whole selection range
+ /// is inside of its source range.
+ ContainsSelection,
+ /// A node that's considered to be selected because the start of the selection
+ /// range is inside its source range.
+ ContainsSelectionStart,
+ /// A node that's considered to be selected because the end of the selection
+ /// range is inside its source range.
+ ContainsSelectionEnd,
+
+ /// A node that's considered to be selected because the node is entirely in
+ /// the selection range.
+ InsideSelection,
+};
+
+/// Represents a selected AST node.
+///
+/// AST selection is represented using a tree of \c SelectedASTNode. The tree
+/// follows the top-down shape of the actual AST. Each selected node has
+/// a selection kind. The kind might be none as the node itself might not
+/// actually be selected, e.g. a statement in macro whose child is in a macro
+/// argument.
+struct SelectedASTNode {
+ ast_type_traits::DynTypedNode Node;
+ SourceSelectionKind SelectionKind;
+ std::vector<SelectedASTNode> Children;
+
+ SelectedASTNode(const ast_type_traits::DynTypedNode &Node,
+ SourceSelectionKind SelectionKind)
+ : Node(Node), SelectionKind(SelectionKind) {}
+ SelectedASTNode(SelectedASTNode &&) = default;
+ SelectedASTNode &operator=(SelectedASTNode &&) = default;
+
+ void dump(llvm::raw_ostream &OS = llvm::errs()) const;
+
+ using ReferenceType = std::reference_wrapper<const SelectedASTNode>;
+};
+
+/// Traverses the given ASTContext and creates a tree of selected AST nodes.
+///
+/// \returns None if no nodes are selected in the AST, or a selected AST node
+/// that corresponds to the TranslationUnitDecl otherwise.
+Optional<SelectedASTNode> findSelectedASTNodes(const ASTContext &Context,
+ SourceRange SelectionRange);
+
+/// An AST selection value that corresponds to a selection of a set of
+/// statements that belong to one body of code (like one function).
+///
+/// For example, the following selection in the source.
+///
+/// \code
+/// void function() {
+/// // selection begin:
+/// int x = 0;
+/// {
+/// // selection end
+/// x = 1;
+/// }
+/// x = 2;
+/// }
+/// \endcode
+///
+/// Would correspond to a code range selection of statements "int x = 0"
+/// and the entire compound statement that follows it.
+///
+/// A \c CodeRangeASTSelection value stores references to the full
+/// \c SelectedASTNode tree and should not outlive it.
+class CodeRangeASTSelection {
+public:
+ CodeRangeASTSelection(CodeRangeASTSelection &&) = default;
+ CodeRangeASTSelection &operator=(CodeRangeASTSelection &&) = default;
+
+ /// Returns the parent hierarchy (top to bottom) for the selected nodes.
+ ArrayRef<SelectedASTNode::ReferenceType> getParents() { return Parents; }
+
+ /// Returns the number of selected statements.
+ size_t size() const {
+ if (!AreChildrenSelected)
+ return 1;
+ return SelectedNode.get().Children.size();
+ }
+
+ const Stmt *operator[](size_t I) const {
+ if (!AreChildrenSelected) {
+ assert(I == 0 && "Invalid index");
+ return SelectedNode.get().Node.get<Stmt>();
+ }
+ return SelectedNode.get().Children[I].Node.get<Stmt>();
+ }
+
+ /// Returns true when a selected code range is in a function-like body
+ /// of code, like a function, method or a block.
+ ///
+ /// This function can be used to test against selected expressions that are
+ /// located outside of a function, e.g. global variable initializers, default
+ /// argument values, or even template arguments.
+ ///
+ /// Use the \c getFunctionLikeNearestParent to get the function-like parent
+ /// declaration.
+ bool isInFunctionLikeBodyOfCode() const;
+
+ /// Returns the nearest function-like parent declaration or null if such
+ /// declaration doesn't exist.
+ const Decl *getFunctionLikeNearestParent() const;
+
+ static Optional<CodeRangeASTSelection>
+ create(SourceRange SelectionRange, const SelectedASTNode &ASTSelection);
+
+private:
+ CodeRangeASTSelection(SelectedASTNode::ReferenceType SelectedNode,
+ ArrayRef<SelectedASTNode::ReferenceType> Parents,
+ bool AreChildrenSelected)
+ : SelectedNode(SelectedNode), Parents(Parents.begin(), Parents.end()),
+ AreChildrenSelected(AreChildrenSelected) {}
+
+ /// The reference to the selected node (or reference to the selected
+ /// child nodes).
+ SelectedASTNode::ReferenceType SelectedNode;
+ /// The parent hierarchy (top to bottom) for the selected noe.
+ llvm::SmallVector<SelectedASTNode::ReferenceType, 8> Parents;
+ /// True only when the children of the selected node are actually selected.
+ bool AreChildrenSelected;
+};
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_REFACTOR_AST_SELECTION_H
diff --git a/include/clang/Tooling/Refactoring/AtomicChange.h b/include/clang/Tooling/Refactoring/AtomicChange.h
index 9cccd78677b1..8a468a6de84e 100644
--- a/include/clang/Tooling/Refactoring/AtomicChange.h
+++ b/include/clang/Tooling/Refactoring/AtomicChange.h
@@ -16,6 +16,7 @@
#define LLVM_CLANG_TOOLING_REFACTOR_ATOMICCHANGE_H
#include "clang/Basic/SourceManager.h"
+#include "clang/Format/Format.h"
#include "clang/Tooling/Core/Replacement.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Error.h"
@@ -45,6 +46,14 @@ public:
AtomicChange(llvm::StringRef FilePath, llvm::StringRef Key)
: Key(Key), FilePath(FilePath) {}
+ AtomicChange(AtomicChange &&) = default;
+ AtomicChange(const AtomicChange &) = default;
+
+ AtomicChange &operator=(AtomicChange &&) = default;
+ AtomicChange &operator=(const AtomicChange &) = default;
+
+ bool operator==(const AtomicChange &Other) const;
+
/// \brief Returns the atomic change as a YAML string.
std::string toYAMLString();
@@ -129,6 +138,41 @@ private:
tooling::Replacements Replaces;
};
+using AtomicChanges = std::vector<AtomicChange>;
+
+// Defines specs for applying changes.
+struct ApplyChangesSpec {
+ // If true, cleans up redundant/erroneous code around changed code with
+ // clang-format's cleanup functionality, e.g. redundant commas around deleted
+ // parameter or empty namespaces introduced by deletions.
+ bool Cleanup = true;
+
+ format::FormatStyle Style = format::getNoStyle();
+
+ // Options for selectively formatting changes with clang-format:
+ // kAll: Format all changed lines.
+ // kNone: Don't format anything.
+ // kViolations: Format lines exceeding the `ColumnLimit` in `Style`.
+ enum FormatOption { kAll, kNone, kViolations };
+
+ FormatOption Format = kNone;
+};
+
+/// \brief Applies all AtomicChanges in \p Changes to the \p Code.
+///
+/// This completely ignores the file path in each change and replaces them with
+/// \p FilePath, i.e. callers are responsible for ensuring all changes are for
+/// the same file.
+///
+/// \returns The changed code if all changes are applied successfully;
+/// otherwise, an llvm::Error carrying llvm::StringError is returned (the Error
+/// message can be converted to string with `llvm::toString()` and the
+/// error_code should be ignored).
+llvm::Expected<std::string>
+applyAtomicChanges(llvm::StringRef FilePath, llvm::StringRef Code,
+ llvm::ArrayRef<AtomicChange> Changes,
+ const ApplyChangesSpec &Spec);
+
} // end namespace tooling
} // end namespace clang
diff --git a/include/clang/Tooling/Refactoring/Extract/Extract.h b/include/clang/Tooling/Refactoring/Extract/Extract.h
new file mode 100644
index 000000000000..2fd76d252c62
--- /dev/null
+++ b/include/clang/Tooling/Refactoring/Extract/Extract.h
@@ -0,0 +1,53 @@
+//===--- Extract.h - Clang refactoring library ----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_REFACTOR_EXTRACT_EXTRACT_H
+#define LLVM_CLANG_TOOLING_REFACTOR_EXTRACT_EXTRACT_H
+
+#include "clang/Tooling/Refactoring/ASTSelection.h"
+#include "clang/Tooling/Refactoring/RefactoringActionRules.h"
+
+namespace clang {
+namespace tooling {
+
+/// An "Extract Function" refactoring moves code into a new function that's
+/// then called from the place where the original code was.
+class ExtractFunction final : public SourceChangeRefactoringRule {
+public:
+ /// Initiates the extract function refactoring operation.
+ ///
+ /// \param Code The selected set of statements.
+ /// \param DeclName The name name of the extract function. If None,
+ /// "extracted" is used.
+ static Expected<ExtractFunction> initiate(RefactoringRuleContext &Context,
+ CodeRangeASTSelection Code,
+ Optional<std::string> DeclName);
+
+ static const RefactoringDescriptor &describe();
+
+private:
+ ExtractFunction(CodeRangeASTSelection Code, Optional<std::string> DeclName)
+ : Code(std::move(Code)),
+ DeclName(DeclName ? std::move(*DeclName) : "extracted") {}
+
+ Expected<AtomicChanges>
+ createSourceReplacements(RefactoringRuleContext &Context) override;
+
+ CodeRangeASTSelection Code;
+
+ // FIXME: Account for naming collisions:
+ // - error when name is specified by user.
+ // - rename to "extractedN" when name is implicit.
+ std::string DeclName;
+};
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_REFACTOR_EXTRACT_EXTRACT_H
diff --git a/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h b/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h
index 8b01a61256f6..d96ad78ad876 100644
--- a/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h
+++ b/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h
@@ -70,6 +70,18 @@ public:
return visit(Expr->getFoundDecl().getDecl(), Expr->getMemberLoc());
}
+ bool VisitOffsetOfExpr(const OffsetOfExpr *S) {
+ 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()))
+ return false;
+ }
+ // FIXME: Try to resolve dependent field references.
+ }
+ return true;
+ }
+
// Other visitors:
bool VisitTypeLoc(const TypeLoc Loc) {
diff --git a/include/clang/Tooling/Refactoring/RefactoringAction.h b/include/clang/Tooling/Refactoring/RefactoringAction.h
new file mode 100644
index 000000000000..c4080237f1c3
--- /dev/null
+++ b/include/clang/Tooling/Refactoring/RefactoringAction.h
@@ -0,0 +1,64 @@
+//===--- RefactoringAction.h - Clang refactoring library ------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTION_H
+#define LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTION_H
+
+#include "clang/Basic/LLVM.h"
+#include "clang/Tooling/Refactoring/RefactoringActionRules.h"
+#include <vector>
+
+namespace clang {
+namespace tooling {
+
+/// A refactoring action is a class that defines a set of related refactoring
+/// action rules. These rules get grouped under a common umbrella - a single
+/// clang-refactor subcommand.
+///
+/// A subclass of \c RefactoringAction is responsible for creating the set of
+/// grouped refactoring action rules that represent one refactoring operation.
+/// Although the rules in one action may have a number of different
+/// implementations, they should strive to produce a similar result. It should
+/// be easy for users to identify which refactoring action produced the result
+/// regardless of which refactoring action rule was used.
+///
+/// The distinction between actions and rules enables the creation of action
+/// that uses very different rules, for example:
+/// - local vs global: a refactoring operation like
+/// "add missing switch cases" can be applied to one switch when it's
+/// selected in an editor, or to all switches in a project when an enum
+/// constant is added to an enum.
+/// - tool vs editor: some refactoring operation can be initiated in the
+/// editor when a declaration is selected, or in a tool when the name of
+/// the declaration is passed using a command-line argument.
+class RefactoringAction {
+public:
+ virtual ~RefactoringAction() {}
+
+ /// Returns the name of the subcommand that's used by clang-refactor for this
+ /// action.
+ virtual StringRef getCommand() const = 0;
+
+ virtual StringRef getDescription() const = 0;
+
+ RefactoringActionRules createActiveActionRules();
+
+protected:
+ /// Returns a set of refactoring actions rules that are defined by this
+ /// action.
+ virtual RefactoringActionRules createActionRules() const = 0;
+};
+
+/// Returns the list of all the available refactoring actions.
+std::vector<std::unique_ptr<RefactoringAction>> createRefactoringActions();
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTION_H
diff --git a/include/clang/Tooling/Refactoring/RefactoringActionRule.h b/include/clang/Tooling/Refactoring/RefactoringActionRule.h
new file mode 100644
index 000000000000..4130e29d8dea
--- /dev/null
+++ b/include/clang/Tooling/Refactoring/RefactoringActionRule.h
@@ -0,0 +1,74 @@
+//===--- RefactoringActionRule.h - Clang refactoring library -------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTION_RULE_H
+#define LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTION_RULE_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
+#include <vector>
+
+namespace clang {
+namespace tooling {
+
+class RefactoringOptionVisitor;
+class RefactoringResultConsumer;
+class RefactoringRuleContext;
+
+struct RefactoringDescriptor {
+ /// A unique identifier for the specific refactoring.
+ StringRef Name;
+ /// A human readable title for the refactoring.
+ StringRef Title;
+ /// A human readable description of what the refactoring does.
+ StringRef Description;
+};
+
+/// A common refactoring action rule interface that defines the 'invoke'
+/// function that performs the refactoring operation (either fully or
+/// partially).
+class RefactoringActionRuleBase {
+public:
+ virtual ~RefactoringActionRuleBase() {}
+
+ /// Initiates and performs a specific refactoring action.
+ ///
+ /// The specific rule will invoke an appropriate \c handle method on a
+ /// consumer to propagate the result of the refactoring action.
+ virtual void invoke(RefactoringResultConsumer &Consumer,
+ RefactoringRuleContext &Context) = 0;
+
+ /// Returns the structure that describes the refactoring.
+ // static const RefactoringDescriptor &describe() = 0;
+};
+
+/// A refactoring action rule is a wrapper class around a specific refactoring
+/// action rule (SourceChangeRefactoringRule, etc) that, in addition to invoking
+/// the action, describes the requirements that determine when the action can be
+/// initiated.
+class RefactoringActionRule : public RefactoringActionRuleBase {
+public:
+ /// Returns true when the rule has a source selection requirement that has
+ /// to be fullfilled before refactoring can be performed.
+ virtual bool hasSelectionRequirement() = 0;
+
+ /// Traverses each refactoring option used by the rule and invokes the
+ /// \c visit callback in the consumer for each option.
+ ///
+ /// Options are visited in the order of use, e.g. if a rule has two
+ /// requirements that use options, the options from the first requirement
+ /// are visited before the options in the second requirement.
+ virtual void visitRefactoringOptions(RefactoringOptionVisitor &Visitor) = 0;
+};
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTION_RULE_H
diff --git a/include/clang/Tooling/Refactoring/RefactoringActionRuleRequirements.h b/include/clang/Tooling/Refactoring/RefactoringActionRuleRequirements.h
new file mode 100644
index 000000000000..355a6a55f22f
--- /dev/null
+++ b/include/clang/Tooling/Refactoring/RefactoringActionRuleRequirements.h
@@ -0,0 +1,123 @@
+//===--- RefactoringActionRuleRequirements.h - Clang refactoring library --===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTION_RULE_REQUIREMENTS_H
+#define LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTION_RULE_REQUIREMENTS_H
+
+#include "clang/Basic/LLVM.h"
+#include "clang/Tooling/Refactoring/ASTSelection.h"
+#include "clang/Tooling/Refactoring/RefactoringDiagnostic.h"
+#include "clang/Tooling/Refactoring/RefactoringOption.h"
+#include "clang/Tooling/Refactoring/RefactoringRuleContext.h"
+#include "llvm/Support/Error.h"
+#include <type_traits>
+
+namespace clang {
+namespace tooling {
+
+/// A refactoring action rule requirement determines when a refactoring action
+/// rule can be invoked. The rule can be invoked only when all of the
+/// requirements are satisfied.
+///
+/// Subclasses must implement the
+/// 'Expected<T> evaluate(RefactoringRuleContext &) const' member function.
+/// \c T is used to determine the return type that is passed to the
+/// refactoring rule's constructor.
+/// For example, the \c SourceRangeSelectionRequirement subclass defines
+/// 'Expected<SourceRange> evaluate(RefactoringRuleContext &Context) const'
+/// function. When this function returns a non-error value, the resulting
+/// source range is passed to the specific refactoring action rule
+/// constructor (provided all other requirements are satisfied).
+class RefactoringActionRuleRequirement {
+ // Expected<T> evaluate(RefactoringRuleContext &Context) const;
+};
+
+/// A base class for any requirement that expects some part of the source to be
+/// selected in an editor (or the refactoring tool with the -selection option).
+class SourceSelectionRequirement : public RefactoringActionRuleRequirement {};
+
+/// A selection requirement that is satisfied when any portion of the source
+/// text is selected.
+class SourceRangeSelectionRequirement : public SourceSelectionRequirement {
+public:
+ Expected<SourceRange> evaluate(RefactoringRuleContext &Context) const {
+ if (Context.getSelectionRange().isValid())
+ return Context.getSelectionRange();
+ return Context.createDiagnosticError(diag::err_refactor_no_selection);
+ }
+};
+
+/// An AST selection requirement is satisfied when any portion of the AST
+/// overlaps with the selection range.
+///
+/// The requirement will be evaluated only once during the initiation and
+/// search of matching refactoring action rules.
+class ASTSelectionRequirement : public SourceRangeSelectionRequirement {
+public:
+ Expected<SelectedASTNode> evaluate(RefactoringRuleContext &Context) const;
+};
+
+/// A selection requirement that is satisfied when the selection range overlaps
+/// with a number of neighbouring statements in the AST. The statemenst must be
+/// contained in declaration like a function. The selection range must be a
+/// non-empty source selection (i.e. cursors won't be accepted).
+///
+/// The requirement will be evaluated only once during the initiation and search
+/// of matching refactoring action rules.
+///
+/// \see CodeRangeASTSelection
+class CodeRangeASTSelectionRequirement : public ASTSelectionRequirement {
+public:
+ Expected<CodeRangeASTSelection>
+ evaluate(RefactoringRuleContext &Context) const;
+};
+
+/// A base class for any requirement that requires some refactoring options.
+class RefactoringOptionsRequirement : public RefactoringActionRuleRequirement {
+public:
+ virtual ~RefactoringOptionsRequirement() {}
+
+ /// Returns the set of refactoring options that are used when evaluating this
+ /// requirement.
+ virtual ArrayRef<std::shared_ptr<RefactoringOption>>
+ getRefactoringOptions() const = 0;
+};
+
+/// A requirement that evaluates to the value of the given \c OptionType when
+/// the \c OptionType is a required option. When the \c OptionType is an
+/// optional option, the requirement will evaluate to \c None if the option is
+/// not specified or to an appropriate value otherwise.
+template <typename OptionType>
+class OptionRequirement : public RefactoringOptionsRequirement {
+public:
+ OptionRequirement() : Opt(createRefactoringOption<OptionType>()) {}
+
+ ArrayRef<std::shared_ptr<RefactoringOption>>
+ getRefactoringOptions() const final override {
+ return Opt;
+ }
+
+ Expected<typename OptionType::ValueType>
+ evaluate(RefactoringRuleContext &) const {
+ return static_cast<OptionType *>(Opt.get())->getValue();
+ }
+
+private:
+ /// The partially-owned option.
+ ///
+ /// The ownership of the option is shared among the different requirements
+ /// because the same option can be used by multiple rules in one refactoring
+ /// action.
+ std::shared_ptr<RefactoringOption> Opt;
+};
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTION_RULE_REQUIREMENTS_H
diff --git a/include/clang/Tooling/Refactoring/RefactoringActionRules.h b/include/clang/Tooling/Refactoring/RefactoringActionRules.h
new file mode 100644
index 000000000000..33206d9a5dd1
--- /dev/null
+++ b/include/clang/Tooling/Refactoring/RefactoringActionRules.h
@@ -0,0 +1,94 @@
+//===--- RefactoringActionRules.h - Clang refactoring library -------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTION_RULES_H
+#define LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTION_RULES_H
+
+#include "clang/Tooling/Refactoring/RefactoringActionRule.h"
+#include "clang/Tooling/Refactoring/RefactoringActionRulesInternal.h"
+
+namespace clang {
+namespace tooling {
+
+/// Creates a new refactoring action rule that constructs and invokes the
+/// \c RuleType rule when all of the requirements are satisfied.
+///
+/// This function takes in a list of values whose type derives from
+/// \c RefactoringActionRuleRequirement. These values describe the initiation
+/// requirements that have to be satisfied by the refactoring engine before
+/// the provided action rule can be constructed and invoked. The engine
+/// verifies that the requirements are satisfied by evaluating them (using the
+/// 'evaluate' member function) and checking that the results don't contain
+/// any errors. Once all requirements are satisfied, the provided refactoring
+/// rule is constructed by passing in the values returned by the requirements'
+/// evaluate functions as arguments to the constructor. The rule is then invoked
+/// immediately after construction.
+///
+/// The separation of requirements, their evaluation and the invocation of the
+/// refactoring action rule allows the refactoring clients to:
+/// - Disable refactoring action rules whose requirements are not supported.
+/// - Gather the set of options and define a command-line / visual interface
+/// that allows users to input these options without ever invoking the
+/// action.
+template <typename RuleType, typename... RequirementTypes>
+std::unique_ptr<RefactoringActionRule>
+createRefactoringActionRule(const RequirementTypes &... Requirements);
+
+/// A set of refactoring action rules that should have unique initiation
+/// requirements.
+using RefactoringActionRules =
+ std::vector<std::unique_ptr<RefactoringActionRule>>;
+
+/// A type of refactoring action rule that produces source replacements in the
+/// form of atomic changes.
+///
+/// This action rule is typically used for local refactorings that replace
+/// source in a single AST unit.
+class SourceChangeRefactoringRule : public RefactoringActionRuleBase {
+public:
+ void invoke(RefactoringResultConsumer &Consumer,
+ RefactoringRuleContext &Context) final override {
+ Expected<AtomicChanges> Changes = createSourceReplacements(Context);
+ if (!Changes)
+ Consumer.handleError(Changes.takeError());
+ else
+ Consumer.handle(std::move(*Changes));
+ }
+
+private:
+ virtual Expected<AtomicChanges>
+ createSourceReplacements(RefactoringRuleContext &Context) = 0;
+};
+
+/// A type of refactoring action rule that finds a set of symbol occurrences
+/// that reference a particular symbol.
+///
+/// This action rule is typically used for an interactive rename that allows
+/// users to specify the new name and the set of selected occurrences during
+/// the refactoring.
+class FindSymbolOccurrencesRefactoringRule : public RefactoringActionRuleBase {
+public:
+ void invoke(RefactoringResultConsumer &Consumer,
+ RefactoringRuleContext &Context) final override {
+ Expected<SymbolOccurrences> Occurrences = findSymbolOccurrences(Context);
+ if (!Occurrences)
+ Consumer.handleError(Occurrences.takeError());
+ else
+ Consumer.handle(std::move(*Occurrences));
+ }
+
+private:
+ virtual Expected<SymbolOccurrences>
+ findSymbolOccurrences(RefactoringRuleContext &Context) = 0;
+};
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTION_RULES_H
diff --git a/include/clang/Tooling/Refactoring/RefactoringActionRulesInternal.h b/include/clang/Tooling/Refactoring/RefactoringActionRulesInternal.h
new file mode 100644
index 000000000000..75b6c8f70d17
--- /dev/null
+++ b/include/clang/Tooling/Refactoring/RefactoringActionRulesInternal.h
@@ -0,0 +1,158 @@
+//===--- RefactoringActionRulesInternal.h - Clang refactoring library -----===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTION_RULES_INTERNAL_H
+#define LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTION_RULES_INTERNAL_H
+
+#include "clang/Basic/LLVM.h"
+#include "clang/Tooling/Refactoring/RefactoringActionRule.h"
+#include "clang/Tooling/Refactoring/RefactoringActionRuleRequirements.h"
+#include "clang/Tooling/Refactoring/RefactoringResultConsumer.h"
+#include "clang/Tooling/Refactoring/RefactoringRuleContext.h"
+#include "llvm/Support/Error.h"
+#include <type_traits>
+
+namespace clang {
+namespace tooling {
+namespace internal {
+
+inline llvm::Error findError() { return llvm::Error::success(); }
+
+inline void ignoreError() {}
+
+template <typename FirstT, typename... RestT>
+void ignoreError(Expected<FirstT> &First, Expected<RestT> &... Rest) {
+ if (!First)
+ llvm::consumeError(First.takeError());
+ ignoreError(Rest...);
+}
+
+/// Scans the tuple and returns a valid \c Error if any of the values are
+/// invalid.
+template <typename FirstT, typename... RestT>
+llvm::Error findError(Expected<FirstT> &First, Expected<RestT> &... Rest) {
+ if (!First) {
+ ignoreError(Rest...);
+ return First.takeError();
+ }
+ return findError(Rest...);
+}
+
+template <typename RuleType, typename... RequirementTypes, size_t... Is>
+void invokeRuleAfterValidatingRequirements(
+ RefactoringResultConsumer &Consumer, RefactoringRuleContext &Context,
+ const std::tuple<RequirementTypes...> &Requirements,
+ llvm::index_sequence<Is...>) {
+ // Check if the requirements we're interested in can be evaluated.
+ auto Values =
+ std::make_tuple(std::get<Is>(Requirements).evaluate(Context)...);
+ auto Err = findError(std::get<Is>(Values)...);
+ if (Err)
+ return Consumer.handleError(std::move(Err));
+ // Construct the target action rule by extracting the evaluated
+ // requirements from Expected<> wrappers and then run it.
+ auto Rule =
+ RuleType::initiate(Context, std::move((*std::get<Is>(Values)))...);
+ if (!Rule)
+ return Consumer.handleError(Rule.takeError());
+ Rule->invoke(Consumer, Context);
+}
+
+inline void visitRefactoringOptionsImpl(RefactoringOptionVisitor &) {}
+
+/// Scans the list of requirements in a rule and visits all the refactoring
+/// options that are used by all the requirements.
+template <typename FirstT, typename... RestT>
+void visitRefactoringOptionsImpl(RefactoringOptionVisitor &Visitor,
+ const FirstT &First, const RestT &... Rest) {
+ struct OptionGatherer {
+ RefactoringOptionVisitor &Visitor;
+
+ void operator()(const RefactoringOptionsRequirement &Requirement) {
+ for (const auto &Option : Requirement.getRefactoringOptions())
+ Option->passToVisitor(Visitor);
+ }
+ void operator()(const RefactoringActionRuleRequirement &) {}
+ };
+ (OptionGatherer{Visitor})(First);
+ return visitRefactoringOptionsImpl(Visitor, Rest...);
+}
+
+template <typename... RequirementTypes, size_t... Is>
+void visitRefactoringOptions(
+ RefactoringOptionVisitor &Visitor,
+ const std::tuple<RequirementTypes...> &Requirements,
+ llvm::index_sequence<Is...>) {
+ visitRefactoringOptionsImpl(Visitor, std::get<Is>(Requirements)...);
+}
+
+/// A type trait that returns true when the given type list has at least one
+/// type whose base is the given base type.
+template <typename Base, typename First, typename... Rest>
+struct HasBaseOf : std::conditional<HasBaseOf<Base, First>::value ||
+ HasBaseOf<Base, Rest...>::value,
+ std::true_type, std::false_type>::type {};
+
+template <typename Base, typename T>
+struct HasBaseOf<Base, T> : std::is_base_of<Base, T> {};
+
+/// A type trait that returns true when the given type list contains types that
+/// derive from Base.
+template <typename Base, typename First, typename... Rest>
+struct AreBaseOf : std::conditional<AreBaseOf<Base, First>::value &&
+ AreBaseOf<Base, Rest...>::value,
+ std::true_type, std::false_type>::type {};
+
+template <typename Base, typename T>
+struct AreBaseOf<Base, T> : std::is_base_of<Base, T> {};
+
+} // end namespace internal
+
+template <typename RuleType, typename... RequirementTypes>
+std::unique_ptr<RefactoringActionRule>
+createRefactoringActionRule(const RequirementTypes &... Requirements) {
+ static_assert(std::is_base_of<RefactoringActionRuleBase, RuleType>::value,
+ "Expected a refactoring action rule type");
+ static_assert(internal::AreBaseOf<RefactoringActionRuleRequirement,
+ RequirementTypes...>::value,
+ "Expected a list of refactoring action rules");
+
+ class Rule final : public RefactoringActionRule {
+ public:
+ Rule(std::tuple<RequirementTypes...> Requirements)
+ : Requirements(Requirements) {}
+
+ void invoke(RefactoringResultConsumer &Consumer,
+ RefactoringRuleContext &Context) override {
+ internal::invokeRuleAfterValidatingRequirements<RuleType>(
+ Consumer, Context, Requirements,
+ llvm::index_sequence_for<RequirementTypes...>());
+ }
+
+ bool hasSelectionRequirement() override {
+ return internal::HasBaseOf<SourceSelectionRequirement,
+ RequirementTypes...>::value;
+ }
+
+ void visitRefactoringOptions(RefactoringOptionVisitor &Visitor) override {
+ internal::visitRefactoringOptions(
+ Visitor, Requirements,
+ llvm::index_sequence_for<RequirementTypes...>());
+ }
+ private:
+ std::tuple<RequirementTypes...> Requirements;
+ };
+
+ return llvm::make_unique<Rule>(std::make_tuple(Requirements...));
+}
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTION_RULES_INTERNAL_H
diff --git a/include/clang/Tooling/Refactoring/RefactoringDiagnostic.h b/include/clang/Tooling/Refactoring/RefactoringDiagnostic.h
new file mode 100644
index 000000000000..6767dc708e01
--- /dev/null
+++ b/include/clang/Tooling/Refactoring/RefactoringDiagnostic.h
@@ -0,0 +1,30 @@
+//===--- RefactoringDiagnostic.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_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
+
+#endif // LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGDIAGNOSTIC_H
diff --git a/include/clang/Tooling/Refactoring/RefactoringOption.h b/include/clang/Tooling/Refactoring/RefactoringOption.h
new file mode 100644
index 000000000000..5011223cce69
--- /dev/null
+++ b/include/clang/Tooling/Refactoring/RefactoringOption.h
@@ -0,0 +1,64 @@
+//===--- RefactoringOption.h - Clang refactoring library ------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_OPTION_H
+#define LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_OPTION_H
+
+#include "clang/Basic/LLVM.h"
+#include <memory>
+#include <type_traits>
+
+namespace clang {
+namespace tooling {
+
+class RefactoringOptionVisitor;
+
+/// A refactoring option is an interface that describes a value that
+/// has an impact on the outcome of a refactoring.
+///
+/// Refactoring options can be specified using command-line arguments when
+/// the clang-refactor tool is used.
+class RefactoringOption {
+public:
+ virtual ~RefactoringOption() {}
+
+ /// Returns the name of the refactoring option.
+ ///
+ /// Each refactoring option must have a unique name.
+ virtual StringRef getName() const = 0;
+
+ virtual StringRef getDescription() const = 0;
+
+ /// True when this option must be specified before invoking the refactoring
+ /// action.
+ virtual bool isRequired() const = 0;
+
+ /// Invokes the \c visit method in the option consumer that's appropriate
+ /// for the option's value type.
+ ///
+ /// For example, if the option stores a string value, this method will
+ /// invoke the \c visit method with a reference to an std::string value.
+ virtual void passToVisitor(RefactoringOptionVisitor &Visitor) = 0;
+};
+
+/// Constructs a refactoring option of the given type.
+///
+/// The ownership of options is shared among requirements that use it because
+/// one option can be used by multiple rules in a refactoring action.
+template <typename OptionType>
+std::shared_ptr<OptionType> createRefactoringOption() {
+ static_assert(std::is_base_of<RefactoringOption, OptionType>::value,
+ "invalid option type");
+ return std::make_shared<OptionType>();
+}
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_OPTION_H
diff --git a/include/clang/Tooling/Refactoring/RefactoringOptionVisitor.h b/include/clang/Tooling/Refactoring/RefactoringOptionVisitor.h
new file mode 100644
index 000000000000..aea8fa549392
--- /dev/null
+++ b/include/clang/Tooling/Refactoring/RefactoringOptionVisitor.h
@@ -0,0 +1,62 @@
+//===--- RefactoringOptionVisitor.h - Clang refactoring library -----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_OPTION_VISITOR_H
+#define LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_OPTION_VISITOR_H
+
+#include "clang/Basic/LLVM.h"
+#include <type_traits>
+
+namespace clang {
+namespace tooling {
+
+class RefactoringOption;
+
+/// An interface that declares functions that handle different refactoring
+/// option types.
+///
+/// A valid refactoring option type must have a corresponding \c visit
+/// declaration in this interface.
+class RefactoringOptionVisitor {
+public:
+ virtual ~RefactoringOptionVisitor() {}
+
+ virtual void visit(const RefactoringOption &Opt,
+ Optional<std::string> &Value) = 0;
+};
+
+namespace traits {
+namespace internal {
+
+template <typename T> struct HasHandle {
+private:
+ template <typename ClassT>
+ static auto check(ClassT *) -> typename std::is_same<
+ decltype(std::declval<RefactoringOptionVisitor>().visit(
+ std::declval<RefactoringOption>(), *std::declval<Optional<T> *>())),
+ void>::type;
+
+ template <typename> static std::false_type check(...);
+
+public:
+ using Type = decltype(check<RefactoringOptionVisitor>(nullptr));
+};
+
+} // end namespace internal
+
+/// A type trait that returns true iff the given type is a type that can be
+/// stored in a refactoring option.
+template <typename T>
+struct IsValidOptionType : internal::HasHandle<T>::Type {};
+
+} // end namespace traits
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_OPTION_VISITOR_H
diff --git a/include/clang/Tooling/Refactoring/RefactoringOptions.h b/include/clang/Tooling/Refactoring/RefactoringOptions.h
new file mode 100644
index 000000000000..e45c0a09fd67
--- /dev/null
+++ b/include/clang/Tooling/Refactoring/RefactoringOptions.h
@@ -0,0 +1,58 @@
+//===--- RefactoringOptions.h - Clang refactoring library -----------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_OPTIONS_H
+#define LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_OPTIONS_H
+
+#include "clang/Basic/LLVM.h"
+#include "clang/Tooling/Refactoring/RefactoringActionRuleRequirements.h"
+#include "clang/Tooling/Refactoring/RefactoringOption.h"
+#include "clang/Tooling/Refactoring/RefactoringOptionVisitor.h"
+#include "llvm/Support/Error.h"
+#include <type_traits>
+
+namespace clang {
+namespace tooling {
+
+/// A refactoring option that stores a value of type \c T.
+template <typename T, typename = typename std::enable_if<
+ traits::IsValidOptionType<T>::value>::type>
+class OptionalRefactoringOption : public RefactoringOption {
+public:
+ void passToVisitor(RefactoringOptionVisitor &Visitor) final override {
+ Visitor.visit(*this, Value);
+ }
+
+ bool isRequired() const override { return false; }
+
+ using ValueType = Optional<T>;
+
+ const ValueType &getValue() const { return Value; }
+
+protected:
+ Optional<T> Value;
+};
+
+/// A required refactoring option that stores a value of type \c T.
+template <typename T, typename = typename std::enable_if<
+ traits::IsValidOptionType<T>::value>::type>
+class RequiredRefactoringOption : public OptionalRefactoringOption<T> {
+public:
+ using ValueType = T;
+
+ const ValueType &getValue() const {
+ return *OptionalRefactoringOption<T>::Value;
+ }
+ bool isRequired() const final override { return true; }
+};
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_OPTIONS_H
diff --git a/include/clang/Tooling/Refactoring/RefactoringResultConsumer.h b/include/clang/Tooling/Refactoring/RefactoringResultConsumer.h
new file mode 100644
index 000000000000..fe7738e73499
--- /dev/null
+++ b/include/clang/Tooling/Refactoring/RefactoringResultConsumer.h
@@ -0,0 +1,52 @@
+//===--- RefactoringResultConsumer.h - Clang refactoring library ----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_RESULT_CONSUMER_H
+#define LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_RESULT_CONSUMER_H
+
+#include "clang/Basic/LLVM.h"
+#include "clang/Tooling/Refactoring/AtomicChange.h"
+#include "clang/Tooling/Refactoring/Rename/SymbolOccurrences.h"
+#include "llvm/Support/Error.h"
+
+namespace clang {
+namespace tooling {
+
+/// An abstract interface that consumes the various refactoring results that can
+/// be produced by refactoring actions.
+///
+/// A valid refactoring result must be handled by a \c handle method.
+class RefactoringResultConsumer {
+public:
+ virtual ~RefactoringResultConsumer() {}
+
+ /// Handles an initation or an invication error. An initiation error typically
+ /// has a \c DiagnosticError payload that describes why initation failed.
+ virtual void handleError(llvm::Error Err) = 0;
+
+ /// Handles the source replacements that are produced by a refactoring action.
+ virtual void handle(AtomicChanges SourceReplacements) {
+ defaultResultHandler();
+ }
+
+ /// Handles the symbol occurrences that are found by an interactive
+ /// refactoring action.
+ virtual void handle(SymbolOccurrences Occurrences) { defaultResultHandler(); }
+
+private:
+ void defaultResultHandler() {
+ handleError(llvm::make_error<llvm::StringError>(
+ "unsupported refactoring result", llvm::inconvertibleErrorCode()));
+ }
+};
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_RESULT_CONSUMER_H
diff --git a/include/clang/Tooling/Refactoring/RefactoringRuleContext.h b/include/clang/Tooling/Refactoring/RefactoringRuleContext.h
new file mode 100644
index 000000000000..882ab824b639
--- /dev/null
+++ b/include/clang/Tooling/Refactoring/RefactoringRuleContext.h
@@ -0,0 +1,90 @@
+//===--- RefactoringRuleContext.h - Clang refactoring library -------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_RULE_CONTEXT_H
+#define LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_RULE_CONTEXT_H
+
+#include "clang/Basic/DiagnosticError.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Tooling/Refactoring/ASTSelection.h"
+
+namespace clang {
+
+class ASTContext;
+
+namespace tooling {
+
+/// The refactoring rule context stores all of the inputs that might be needed
+/// by a refactoring action rule. It can create the specialized
+/// \c ASTRefactoringOperation or \c PreprocessorRefactoringOperation values
+/// that can be used by the refactoring action rules.
+///
+/// The following inputs are stored by the operation:
+///
+/// - SourceManager: a reference to a valid source manager.
+///
+/// - SelectionRange: an optional source selection ranges that can be used
+/// to represent a selection in an editor.
+class RefactoringRuleContext {
+public:
+ RefactoringRuleContext(const SourceManager &SM) : SM(SM) {}
+
+ const SourceManager &getSources() const { return SM; }
+
+ /// Returns the current source selection range as set by the
+ /// refactoring engine. Can be invalid.
+ SourceRange getSelectionRange() const { return SelectionRange; }
+
+ void setSelectionRange(SourceRange R) { SelectionRange = R; }
+
+ bool hasASTContext() const { return AST; }
+
+ ASTContext &getASTContext() const {
+ assert(AST && "no AST!");
+ return *AST;
+ }
+
+ void setASTContext(ASTContext &Context) { AST = &Context; }
+
+ /// Creates an llvm::Error value that contains a diagnostic.
+ ///
+ /// The errors should not outlive the context.
+ llvm::Error createDiagnosticError(SourceLocation Loc, unsigned DiagID) {
+ return DiagnosticError::create(Loc, PartialDiagnostic(DiagID, DiagStorage));
+ }
+
+ llvm::Error createDiagnosticError(unsigned DiagID) {
+ return createDiagnosticError(SourceLocation(), DiagID);
+ }
+
+ void setASTSelection(std::unique_ptr<SelectedASTNode> Node) {
+ ASTNodeSelection = std::move(Node);
+ }
+
+private:
+ /// The source manager for the translation unit / file on which a refactoring
+ /// action might operate on.
+ const SourceManager &SM;
+ /// An optional source selection range that's commonly used to represent
+ /// a selection in an editor.
+ SourceRange SelectionRange;
+ /// An optional AST for the translation unit on which a refactoring action
+ /// might operate on.
+ ASTContext *AST = nullptr;
+ /// The allocator for diagnostics.
+ PartialDiagnostic::StorageAllocator DiagStorage;
+
+ // FIXME: Remove when memoized.
+ std::unique_ptr<SelectedASTNode> ASTNodeSelection;
+};
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_RULE_CONTEXT_H
diff --git a/include/clang/Tooling/Refactoring/Rename/RenamingAction.h b/include/clang/Tooling/Refactoring/Rename/RenamingAction.h
index 099eaca6c42a..734b624d777b 100644
--- a/include/clang/Tooling/Refactoring/Rename/RenamingAction.h
+++ b/include/clang/Tooling/Refactoring/Rename/RenamingAction.h
@@ -16,6 +16,11 @@
#define LLVM_CLANG_TOOLING_REFACTOR_RENAME_RENAMING_ACTION_H
#include "clang/Tooling/Refactoring.h"
+#include "clang/Tooling/Refactoring/AtomicChange.h"
+#include "clang/Tooling/Refactoring/RefactoringActionRules.h"
+#include "clang/Tooling/Refactoring/RefactoringOptions.h"
+#include "clang/Tooling/Refactoring/Rename/SymbolOccurrences.h"
+#include "llvm/Support/Error.h"
namespace clang {
class ASTConsumer;
@@ -42,6 +47,53 @@ private:
bool PrintLocations;
};
+class RenameOccurrences final : public SourceChangeRefactoringRule {
+public:
+ static Expected<RenameOccurrences> initiate(RefactoringRuleContext &Context,
+ SourceRange SelectionRange,
+ std::string NewName);
+
+ static const RefactoringDescriptor &describe();
+
+private:
+ RenameOccurrences(const NamedDecl *ND, std::string NewName)
+ : ND(ND), NewName(std::move(NewName)) {}
+
+ Expected<AtomicChanges>
+ createSourceReplacements(RefactoringRuleContext &Context) override;
+
+ const NamedDecl *ND;
+ std::string NewName;
+};
+
+class QualifiedRenameRule final : public SourceChangeRefactoringRule {
+public:
+ static Expected<QualifiedRenameRule> initiate(RefactoringRuleContext &Context,
+ std::string OldQualifiedName,
+ std::string NewQualifiedName);
+
+ static const RefactoringDescriptor &describe();
+
+private:
+ QualifiedRenameRule(const NamedDecl *ND,
+ std::string NewQualifiedName)
+ : ND(ND), NewQualifiedName(std::move(NewQualifiedName)) {}
+
+ Expected<AtomicChanges>
+ createSourceReplacements(RefactoringRuleContext &Context) override;
+
+ // A NamedDecl which indentifies the the symbol being renamed.
+ const NamedDecl *ND;
+ // The new qualified name to change the symbol to.
+ std::string NewQualifiedName;
+};
+
+/// Returns source replacements that correspond to the rename of the given
+/// symbol occurrences.
+llvm::Expected<std::vector<AtomicChange>>
+createRenameReplacements(const SymbolOccurrences &Occurrences,
+ const SourceManager &SM, const SymbolName &NewName);
+
/// Rename all symbols identified by the given USRs.
class QualifiedRenamingAction {
public:
diff --git a/include/clang/Tooling/Refactoring/Rename/SymbolName.h b/include/clang/Tooling/Refactoring/Rename/SymbolName.h
new file mode 100644
index 000000000000..e69d2908b5d3
--- /dev/null
+++ b/include/clang/Tooling/Refactoring/Rename/SymbolName.h
@@ -0,0 +1,49 @@
+//===--- SymbolName.h - Clang refactoring library -------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_REFACTOR_RENAME_SYMBOL_NAME_H
+#define LLVM_CLANG_TOOLING_REFACTOR_RENAME_SYMBOL_NAME_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace clang {
+namespace tooling {
+
+/// A name of a symbol.
+///
+/// Symbol's name can be composed of multiple strings. For example, Objective-C
+/// methods can contain multiple argument lables:
+///
+/// \code
+/// - (void) myMethodNamePiece: (int)x anotherNamePieces:(int)y;
+/// // ^~ string 0 ~~~~~ ^~ string 1 ~~~~~
+/// \endcode
+class SymbolName {
+public:
+ explicit SymbolName(StringRef Name) {
+ // While empty symbol names are valid (Objective-C selectors can have empty
+ // name pieces), occurrences Objective-C selectors are created using an
+ // array of strings instead of just one string.
+ assert(!Name.empty() && "Invalid symbol name!");
+ this->Name.push_back(Name.str());
+ }
+
+ ArrayRef<std::string> getNamePieces() const { return Name; }
+
+private:
+ llvm::SmallVector<std::string, 1> Name;
+};
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_REFACTOR_RENAME_SYMBOL_NAME_H
diff --git a/include/clang/Tooling/Refactoring/Rename/SymbolOccurrences.h b/include/clang/Tooling/Refactoring/Rename/SymbolOccurrences.h
new file mode 100644
index 000000000000..0f853011978f
--- /dev/null
+++ b/include/clang/Tooling/Refactoring/Rename/SymbolOccurrences.h
@@ -0,0 +1,91 @@
+//===--- SymbolOccurrences.h - Clang refactoring library ------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_REFACTOR_RENAME_SYMBOL_OCCURRENCES_H
+#define LLVM_CLANG_TOOLING_REFACTOR_RENAME_SYMBOL_OCCURRENCES_H
+
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include <vector>
+
+namespace clang {
+namespace tooling {
+
+class SymbolName;
+
+/// An occurrence of a symbol in the source.
+///
+/// Occurrences can have difference kinds, that describe whether this occurrence
+/// is an exact semantic match, or whether this is a weaker textual match that's
+/// not guaranteed to represent the exact declaration.
+///
+/// A single occurrence of a symbol can span more than one source range. For
+/// example, Objective-C selectors can contain multiple argument labels:
+///
+/// \code
+/// [object selectorPiece1: ... selectorPiece2: ...];
+/// // ^~~ range 0 ~~ ^~~ range 1 ~~
+/// \endcode
+///
+/// We have to replace the text in both range 0 and range 1 when renaming the
+/// Objective-C method 'selectorPiece1:selectorPiece2'.
+class SymbolOccurrence {
+public:
+ enum OccurrenceKind {
+ /// This occurrence is an exact match and can be renamed automatically.
+ ///
+ /// Note:
+ /// Symbol occurrences in macro arguments that expand to different
+ /// declarations get marked as exact matches, and thus the renaming engine
+ /// will rename them e.g.:
+ ///
+ /// \code
+ /// #define MACRO(x) x + ns::x
+ /// int foo(int var) {
+ /// return MACRO(var); // var is renamed automatically here when
+ /// // either var or ns::var is renamed.
+ /// };
+ /// \endcode
+ ///
+ /// The user will have to fix their code manually after performing such a
+ /// rename.
+ /// FIXME: The rename verifier should notify user about this issue.
+ MatchingSymbol
+ };
+
+ SymbolOccurrence(const SymbolName &Name, OccurrenceKind Kind,
+ ArrayRef<SourceLocation> Locations);
+
+ SymbolOccurrence(SymbolOccurrence &&) = default;
+ SymbolOccurrence &operator=(SymbolOccurrence &&) = default;
+
+ OccurrenceKind getKind() const { return Kind; }
+
+ ArrayRef<SourceRange> getNameRanges() const {
+ if (MultipleRanges) {
+ return llvm::makeArrayRef(MultipleRanges.get(),
+ RangeOrNumRanges.getBegin().getRawEncoding());
+ }
+ return RangeOrNumRanges;
+ }
+
+private:
+ OccurrenceKind Kind;
+ std::unique_ptr<SourceRange[]> MultipleRanges;
+ SourceRange RangeOrNumRanges;
+};
+
+using SymbolOccurrences = std::vector<SymbolOccurrence>;
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_REFACTOR_RENAME_SYMBOL_OCCURRENCES_H
diff --git a/include/clang/Tooling/Refactoring/Rename/USRFindingAction.h b/include/clang/Tooling/Refactoring/Rename/USRFindingAction.h
index 8aafee95bc09..f1c5ae60f875 100644
--- a/include/clang/Tooling/Refactoring/Rename/USRFindingAction.h
+++ b/include/clang/Tooling/Refactoring/Rename/USRFindingAction.h
@@ -23,11 +23,25 @@
namespace clang {
class ASTConsumer;
+class ASTContext;
class CompilerInstance;
class NamedDecl;
namespace tooling {
+/// Returns the canonical declaration that best represents a symbol that can be
+/// renamed.
+///
+/// The following canonicalization rules are currently used:
+///
+/// - A constructor is canonicalized to its class.
+/// - A destructor is canonicalized to its class.
+const NamedDecl *getCanonicalSymbolDeclaration(const NamedDecl *FoundDecl);
+
+/// Returns the set of USRs that correspond to the given declaration.
+std::vector<std::string> getUSRsForDeclaration(const NamedDecl *ND,
+ ASTContext &Context);
+
struct USRFindingAction {
USRFindingAction(ArrayRef<unsigned> SymbolOffsets,
ArrayRef<std::string> QualifiedNames, bool Force)
diff --git a/include/clang/Tooling/Refactoring/Rename/USRLocFinder.h b/include/clang/Tooling/Refactoring/Rename/USRLocFinder.h
index 733ea1a6ac9e..801a8ad9e99c 100644
--- a/include/clang/Tooling/Refactoring/Rename/USRLocFinder.h
+++ b/include/clang/Tooling/Refactoring/Rename/USRLocFinder.h
@@ -19,6 +19,7 @@
#include "clang/AST/AST.h"
#include "clang/Tooling/Core/Replacement.h"
#include "clang/Tooling/Refactoring/AtomicChange.h"
+#include "clang/Tooling/Refactoring/Rename/SymbolOccurrences.h"
#include "llvm/ADT/StringRef.h"
#include <string>
#include <vector>
@@ -38,10 +39,13 @@ std::vector<tooling::AtomicChange>
createRenameAtomicChanges(llvm::ArrayRef<std::string> USRs,
llvm::StringRef NewName, Decl *TranslationUnitDecl);
-// FIXME: make this an AST matcher. Wouldn't that be awesome??? I agree!
-std::vector<SourceLocation>
-getLocationsOfUSRs(const std::vector<std::string> &USRs,
- llvm::StringRef PrevName, Decl *Decl);
+/// Finds the symbol occurrences for the symbol that's identified by the given
+/// USR set.
+///
+/// \return SymbolOccurrences that can be converted to AtomicChanges when
+/// renaming.
+SymbolOccurrences getOccurrencesOfUSRs(ArrayRef<std::string> USRs,
+ StringRef PrevName, Decl *Decl);
} // end namespace tooling
} // end namespace clang
diff --git a/include/clang/Tooling/StandaloneExecution.h b/include/clang/Tooling/StandaloneExecution.h
new file mode 100644
index 000000000000..f5f32d737a45
--- /dev/null
+++ b/include/clang/Tooling/StandaloneExecution.h
@@ -0,0 +1,97 @@
+//===--- StandaloneExecution.h - Standalone execution. -*- 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 standalone execution of clang tools.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_STANDALONEEXECUTION_H
+#define LLVM_CLANG_TOOLING_STANDALONEEXECUTION_H
+
+#include "clang/Tooling/ArgumentsAdjusters.h"
+#include "clang/Tooling/Execution.h"
+
+namespace clang {
+namespace tooling {
+
+/// \brief A standalone executor that runs FrontendActions on a given set of
+/// TUs in sequence.
+///
+/// By default, this executor uses the following arguments adjusters (as defined
+/// in `clang/Tooling/ArgumentsAdjusters.h`):
+/// - `getClangStripOutputAdjuster()`
+/// - `getClangSyntaxOnlyAdjuster()`
+/// - `getClangStripDependencyFileAdjuster()`
+class StandaloneToolExecutor : public ToolExecutor {
+public:
+ static const char *ExecutorName;
+
+ /// \brief Init with \p CompilationDatabase and the paths of all files to be
+ /// proccessed.
+ StandaloneToolExecutor(
+ const CompilationDatabase &Compilations,
+ llvm::ArrayRef<std::string> SourcePaths,
+ std::shared_ptr<PCHContainerOperations> PCHContainerOps =
+ std::make_shared<PCHContainerOperations>());
+
+ /// \brief Init with \p CommonOptionsParser. This is expected to be used by
+ /// `createExecutorFromCommandLineArgs` based on commandline options.
+ ///
+ /// The executor takes ownership of \p Options.
+ StandaloneToolExecutor(
+ CommonOptionsParser Options,
+ std::shared_ptr<PCHContainerOperations> PCHContainerOps =
+ std::make_shared<PCHContainerOperations>());
+
+ StringRef getExecutorName() const override { return ExecutorName; }
+
+ using ToolExecutor::execute;
+
+ llvm::Error
+ execute(llvm::ArrayRef<
+ std::pair<std::unique_ptr<FrontendActionFactory>, ArgumentsAdjuster>>
+ Actions) override;
+
+ /// \brief Set a \c DiagnosticConsumer to use during parsing.
+ void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer) {
+ Tool.setDiagnosticConsumer(DiagConsumer);
+ }
+
+ ExecutionContext *getExecutionContext() override { return &Context; };
+
+ ToolResults *getToolResults() override { return &Results; }
+
+ llvm::ArrayRef<std::string> getSourcePaths() const {
+ return Tool.getSourcePaths();
+ }
+
+ void mapVirtualFile(StringRef FilePath, StringRef Content) override {
+ Tool.mapVirtualFile(FilePath, Content);
+ }
+
+ /// \brief Returns the file manager used in the tool.
+ ///
+ /// The file manager is shared between all translation units.
+ FileManager &getFiles() { return Tool.getFiles(); }
+
+private:
+ // Used to store the parser when the executor is initialized with parser.
+ llvm::Optional<CommonOptionsParser> OptionsParser;
+ // FIXME: The standalone executor is currently just a wrapper of `ClangTool`.
+ // Merge `ClangTool` implementation into the this.
+ ClangTool Tool;
+ ExecutionContext Context;
+ InMemoryToolResults Results;
+ ArgumentsAdjuster ArgsAdjuster;
+};
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_STANDALONEEXECUTION_H
diff --git a/include/clang/Tooling/ToolExecutorPluginRegistry.h b/include/clang/Tooling/ToolExecutorPluginRegistry.h
new file mode 100644
index 000000000000..11ba89546e9e
--- /dev/null
+++ b/include/clang/Tooling/ToolExecutorPluginRegistry.h
@@ -0,0 +1,24 @@
+//===--- ToolExecutorPluginRegistry.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_TOOLING_TOOLEXECUTORPLUGINREGISTRY_H
+#define LLVM_CLANG_TOOLING_TOOLEXECUTORPLUGINREGISTRY_H
+
+#include "clang/Tooling/Execution.h"
+#include "llvm/Support/Registry.h"
+
+namespace clang {
+namespace tooling {
+
+typedef llvm::Registry<ToolExecutorPlugin> ToolExecutorPluginRegistry;
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_TOOLEXECUTORPLUGINREGISTRY_H
diff --git a/include/clang/Tooling/Tooling.h b/include/clang/Tooling/Tooling.h
index 6f9bc9e1a150..e64be07d9ab4 100644
--- a/include/clang/Tooling/Tooling.h
+++ b/include/clang/Tooling/Tooling.h
@@ -31,12 +31,12 @@
#define LLVM_CLANG_TOOLING_TOOLING_H
#include "clang/AST/ASTConsumer.h"
-#include "clang/Frontend/PCHContainerOperations.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/LLVM.h"
#include "clang/Driver/Util.h"
#include "clang/Frontend/FrontendAction.h"
+#include "clang/Frontend/PCHContainerOperations.h"
#include "clang/Lex/ModuleLoader.h"
#include "clang/Tooling/ArgumentsAdjusters.h"
#include "clang/Tooling/CompilationDatabase.h"
@@ -337,7 +337,9 @@ class ClangTool {
/// The file manager is shared between all translation units.
FileManager &getFiles() { return *Files; }
- private:
+ llvm::ArrayRef<std::string> getSourcePaths() const { return SourcePaths; }
+
+private:
const CompilationDatabase &Compilations;
std::vector<std::string> SourcePaths;
std::shared_ptr<PCHContainerOperations> PCHContainerOps;
diff --git a/include/clang/module.modulemap b/include/clang/module.modulemap
index d850bd552e1f..4097ad2dc716 100644
--- a/include/clang/module.modulemap
+++ b/include/clang/module.modulemap
@@ -49,6 +49,7 @@ module Clang_Basic {
textual header "Basic/OperatorKinds.def"
textual header "Basic/Sanitizers.def"
textual header "Basic/TokenKinds.def"
+ textual header "Basic/X86Target.def"
module * { export * }
}
@@ -69,9 +70,9 @@ module Clang_Diagnostics {
module Frontend { header "Frontend/FrontendDiagnostic.h" export * }
module Lex { header "Lex/LexDiagnostic.h" export * }
module Parse { header "Parse/ParseDiagnostic.h" export * }
- // FIXME: This breaks the build of Clang_Sema, for unknown reasons.
- //module Sema { header "Sema/SemaDiagnostic.h" export * }
+ module Sema { header "Sema/SemaDiagnostic.h" export * }
module Serialization { header "Serialization/SerializationDiagnostic.h" export * }
+ module Refactoring { header "Tooling/Refactoring/RefactoringDiagnostic.h" export * }
}
module Clang_Driver {
@@ -90,7 +91,6 @@ module Clang_Frontend {
requires cplusplus
umbrella "Frontend"
- textual header "Frontend/CodeGenOptions.def"
textual header "Frontend/LangStandards.def"
module * { export * }
@@ -99,11 +99,20 @@ module Clang_Frontend {
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 * } }
module Clang_Index { requires cplusplus umbrella "Index" module * { export * } }
module Clang_Lex { requires cplusplus umbrella "Lex" module * { export * } }
module Clang_Parse { requires cplusplus umbrella "Parse" module * { export * } }
-module Clang_Rewrite { requires cplusplus umbrella "Rewrite" module * { export * } }
+module Clang_Rewrite { requires cplusplus umbrella "Rewrite/Core" module * { export * } }
+module Clang_RewriteFrontend { requires cplusplus umbrella "Rewrite/Frontend" module * { export * } }
module Clang_Sema { requires cplusplus umbrella "Sema" module * { export * } }
module Clang_Serialization { requires cplusplus umbrella "Serialization" module * { export * } }
@@ -139,3 +148,8 @@ module Clang_Tooling {
// matchers (and thus the AST), which clang-format should not have.
exclude header "Tooling/RefactoringCallbacks.h"
}
+
+module Clang_ToolingCore {
+ requires cplusplus
+ umbrella "Tooling/Core" module * { export * }
+}