aboutsummaryrefslogtreecommitdiffstats
path: root/include/clang
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2012-12-02 13:20:44 +0000
committerDimitry Andric <dim@FreeBSD.org>2012-12-02 13:20:44 +0000
commit13cc256e404620c1de0cbcc4e43ce1e2dbbc4898 (patch)
tree2732d02d7d51218d6eed98ac7fcfc5b8794896b5 /include/clang
parent657bc3d9848e3be92029b2416031340988cd0111 (diff)
downloadsrc-13cc256e404620c1de0cbcc4e43ce1e2dbbc4898.tar.gz
src-13cc256e404620c1de0cbcc4e43ce1e2dbbc4898.zip
Vendor import of clang release_32 branch r168974 (effectively, 3.2 RC2):vendor/clang/clang-release_32-r168974
Notes
Notes: svn path=/vendor/clang/dist/; revision=243791 svn path=/vendor/clang/clang-release_32-r168974/; revision=243792; tag=vendor/clang/clang-release_32-r168974
Diffstat (limited to 'include/clang')
-rw-r--r--include/clang/ARCMigrate/ARCMT.h5
-rw-r--r--include/clang/AST/ASTConsumer.h15
-rw-r--r--include/clang/AST/ASTContext.h616
-rw-r--r--include/clang/AST/ASTMutationListener.h2
-rw-r--r--include/clang/AST/Attr.h5
-rw-r--r--include/clang/AST/BuiltinTypes.def2
-rw-r--r--include/clang/AST/CMakeLists.txt12
-rw-r--r--include/clang/AST/CXXInheritance.h17
-rw-r--r--include/clang/AST/CanonicalType.h1
-rw-r--r--include/clang/AST/CharUnits.h4
-rw-r--r--include/clang/AST/Comment.h189
-rw-r--r--include/clang/AST/CommentBriefParser.h3
-rw-r--r--include/clang/AST/CommentCommandTraits.h186
-rw-r--r--include/clang/AST/CommentCommands.td156
-rw-r--r--include/clang/AST/CommentHTMLTags.td54
-rw-r--r--include/clang/AST/CommentLexer.h116
-rw-r--r--include/clang/AST/CommentParser.h4
-rw-r--r--include/clang/AST/CommentSema.h48
-rw-r--r--include/clang/AST/Decl.h52
-rw-r--r--include/clang/AST/DeclBase.h27
-rw-r--r--include/clang/AST/DeclCXX.h46
-rw-r--r--include/clang/AST/DeclFriend.h12
-rw-r--r--include/clang/AST/DeclObjC.h106
-rw-r--r--include/clang/AST/DeclTemplate.h130
-rw-r--r--include/clang/AST/DeclarationName.h4
-rw-r--r--include/clang/AST/Expr.h249
-rw-r--r--include/clang/AST/ExprCXX.h214
-rw-r--r--include/clang/AST/ExprObjC.h33
-rw-r--r--include/clang/AST/ExternalASTSource.h2
-rw-r--r--include/clang/AST/Makefile19
-rw-r--r--include/clang/AST/NSAPI.h6
-rw-r--r--include/clang/AST/NestedNameSpecifier.h3
-rw-r--r--include/clang/AST/OperationKinds.h6
-rw-r--r--include/clang/AST/PrettyPrinter.h12
-rw-r--r--include/clang/AST/RawCommentList.h6
-rw-r--r--include/clang/AST/RecordLayout.h4
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h13
-rw-r--r--include/clang/AST/SelectorLocationsKind.h4
-rw-r--r--include/clang/AST/Stmt.h377
-rw-r--r--include/clang/AST/StmtCXX.h5
-rw-r--r--include/clang/AST/StmtObjC.h7
-rw-r--r--include/clang/AST/TemplateBase.h92
-rw-r--r--include/clang/AST/Type.h163
-rw-r--r--include/clang/AST/TypeLoc.h42
-rw-r--r--include/clang/AST/UnresolvedSet.h2
-rw-r--r--include/clang/AST/VTableBuilder.h5
-rw-r--r--include/clang/ASTMatchers/ASTMatchFinder.h29
-rw-r--r--include/clang/ASTMatchers/ASTMatchers.h1445
-rw-r--r--include/clang/ASTMatchers/ASTMatchersInternal.h621
-rw-r--r--include/clang/ASTMatchers/ASTMatchersMacros.h65
-rw-r--r--include/clang/ASTMatchers/ASTTypeTraits.h209
-rw-r--r--include/clang/Analysis/Analyses/FormatString.h24
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafety.h3
-rw-r--r--include/clang/Analysis/AnalysisContext.h35
-rw-r--r--include/clang/Analysis/CFG.h6
-rw-r--r--include/clang/Analysis/DomainSpecific/ObjCNoReturn.h46
-rw-r--r--include/clang/Analysis/ProgramPoint.h7
-rw-r--r--include/clang/Basic/Attr.td16
-rw-r--r--include/clang/Basic/Builtins.def65
-rw-r--r--include/clang/Basic/BuiltinsMips.def63
-rw-r--r--include/clang/Basic/BuiltinsNVPTX.def246
-rw-r--r--include/clang/Basic/BuiltinsX86.def9
-rw-r--r--include/clang/Basic/ConvertUTF.h12
-rw-r--r--include/clang/Basic/Diagnostic.h27
-rw-r--r--include/clang/Basic/DiagnosticASTKinds.td2
-rw-r--r--include/clang/Basic/DiagnosticCommentKinds.td16
-rw-r--r--include/clang/Basic/DiagnosticCommonKinds.td5
-rw-r--r--include/clang/Basic/DiagnosticDriverKinds.td24
-rw-r--r--include/clang/Basic/DiagnosticFrontendKinds.td7
-rw-r--r--include/clang/Basic/DiagnosticGroups.td83
-rw-r--r--include/clang/Basic/DiagnosticLexKinds.td35
-rw-r--r--include/clang/Basic/DiagnosticOptions.def93
-rw-r--r--include/clang/Basic/DiagnosticOptions.h85
-rw-r--r--include/clang/Basic/DiagnosticParseKinds.td50
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td361
-rw-r--r--include/clang/Basic/DiagnosticSerializationKinds.td43
-rw-r--r--include/clang/Basic/FileManager.h4
-rw-r--r--include/clang/Basic/IdentifierTable.h33
-rw-r--r--include/clang/Basic/LangOptions.def22
-rw-r--r--include/clang/Basic/Module.h30
-rw-r--r--include/clang/Basic/ObjCRuntime.h45
-rw-r--r--include/clang/Basic/OnDiskHashTable.h5
-rw-r--r--include/clang/Basic/Sanitizers.def69
-rw-r--r--include/clang/Basic/SourceLocation.h2
-rw-r--r--include/clang/Basic/SourceManager.h21
-rw-r--r--include/clang/Basic/Specifiers.h15
-rw-r--r--include/clang/Basic/StmtNodes.td10
-rw-r--r--include/clang/Basic/TargetInfo.h59
-rw-r--r--include/clang/Basic/TargetOptions.h6
-rw-r--r--include/clang/Basic/TokenKinds.def41
-rw-r--r--include/clang/Basic/TokenKinds.h25
-rw-r--r--include/clang/Basic/TypeTraits.h1
-rw-r--r--include/clang/Basic/arm_neon.td8
-rw-r--r--include/clang/CodeGen/CodeGenAction.h2
-rw-r--r--include/clang/Driver/Action.h15
-rw-r--r--include/clang/Driver/Arg.h26
-rw-r--r--include/clang/Driver/ArgList.h72
-rw-r--r--include/clang/Driver/CC1AsOptions.h4
-rw-r--r--include/clang/Driver/CC1AsOptions.td43
-rw-r--r--include/clang/Driver/CC1Options.td419
-rw-r--r--include/clang/Driver/Compilation.h11
-rw-r--r--include/clang/Driver/Driver.h43
-rw-r--r--include/clang/Driver/Job.h4
-rw-r--r--include/clang/Driver/OptParser.td31
-rw-r--r--include/clang/Driver/OptTable.h61
-rw-r--r--include/clang/Driver/Option.h324
-rw-r--r--include/clang/Driver/Options.h4
-rw-r--r--include/clang/Driver/Options.td1645
-rw-r--r--include/clang/Driver/Tool.h4
-rw-r--r--include/clang/Driver/ToolChain.h40
-rw-r--r--include/clang/Driver/Types.h4
-rw-r--r--include/clang/Frontend/ASTUnit.h86
-rw-r--r--include/clang/Frontend/AnalyzerOptions.h135
-rw-r--r--include/clang/Frontend/CodeGenOptions.def132
-rw-r--r--include/clang/Frontend/CodeGenOptions.h182
-rw-r--r--include/clang/Frontend/CompilerInstance.h44
-rw-r--r--include/clang/Frontend/CompilerInvocation.h79
-rw-r--r--include/clang/Frontend/DiagnosticOptions.h111
-rw-r--r--include/clang/Frontend/DiagnosticRenderer.h8
-rw-r--r--include/clang/Frontend/FrontendAction.h16
-rw-r--r--include/clang/Frontend/FrontendOptions.h34
-rw-r--r--include/clang/Frontend/LangStandard.h18
-rw-r--r--include/clang/Frontend/LangStandards.def58
-rw-r--r--include/clang/Frontend/LogDiagnosticPrinter.h4
-rw-r--r--include/clang/Frontend/MultiplexConsumer.h1
-rw-r--r--include/clang/Frontend/SerializedDiagnosticPrinter.h2
-rw-r--r--include/clang/Frontend/TextDiagnostic.h2
-rw-r--r--include/clang/Frontend/TextDiagnosticPrinter.h5
-rw-r--r--include/clang/Frontend/VerifyDiagnosticConsumer.h86
-rw-r--r--include/clang/Lex/ExternalPreprocessorSource.h3
-rw-r--r--include/clang/Lex/HeaderMap.h5
-rw-r--r--include/clang/Lex/HeaderSearch.h25
-rw-r--r--include/clang/Lex/HeaderSearchOptions.h (renamed from include/clang/Frontend/HeaderSearchOptions.h)11
-rw-r--r--include/clang/Lex/Lexer.h91
-rw-r--r--include/clang/Lex/LiteralSupport.h10
-rw-r--r--include/clang/Lex/MacroInfo.h60
-rw-r--r--include/clang/Lex/ModuleMap.h74
-rw-r--r--include/clang/Lex/PPCallbacks.h53
-rw-r--r--include/clang/Lex/PPMutationListener.h43
-rw-r--r--include/clang/Lex/PTHLexer.h4
-rw-r--r--include/clang/Lex/PTHManager.h5
-rw-r--r--include/clang/Lex/PreprocessingRecord.h84
-rw-r--r--include/clang/Lex/Preprocessor.h128
-rw-r--r--include/clang/Lex/PreprocessorLexer.h4
-rw-r--r--include/clang/Lex/PreprocessorOptions.h (renamed from include/clang/Frontend/PreprocessorOptions.h)13
-rw-r--r--include/clang/Lex/Token.h18
-rw-r--r--include/clang/Lex/TokenLexer.h17
-rw-r--r--include/clang/Parse/Parser.h197
-rw-r--r--include/clang/Rewrite/Core/DeltaTree.h (renamed from include/clang/Rewrite/DeltaTree.h)4
-rw-r--r--include/clang/Rewrite/Core/HTMLRewrite.h (renamed from include/clang/Rewrite/HTMLRewrite.h)0
-rw-r--r--include/clang/Rewrite/Core/RewriteRope.h (renamed from include/clang/Rewrite/RewriteRope.h)26
-rw-r--r--include/clang/Rewrite/Core/Rewriter.h (renamed from include/clang/Rewrite/Rewriter.h)6
-rw-r--r--include/clang/Rewrite/Core/TokenRewriter.h (renamed from include/clang/Rewrite/TokenRewriter.h)4
-rw-r--r--include/clang/Rewrite/Frontend/ASTConsumers.h (renamed from include/clang/Rewrite/ASTConsumers.h)0
-rw-r--r--include/clang/Rewrite/Frontend/FixItRewriter.h (renamed from include/clang/Rewrite/FixItRewriter.h)2
-rw-r--r--include/clang/Rewrite/Frontend/FrontendActions.h (renamed from include/clang/Rewrite/FrontendActions.h)0
-rw-r--r--include/clang/Rewrite/Frontend/Rewriters.h (renamed from include/clang/Rewrite/Rewriters.h)0
-rw-r--r--include/clang/Sema/AttributeList.h8
-rw-r--r--include/clang/Sema/CodeCompleteConsumer.h20
-rw-r--r--include/clang/Sema/DeclSpec.h54
-rw-r--r--include/clang/Sema/DelayedDiagnostic.h11
-rw-r--r--include/clang/Sema/ExternalSemaSource.h1
-rw-r--r--include/clang/Sema/Initialization.h4
-rw-r--r--include/clang/Sema/LocInfoType.h1
-rw-r--r--include/clang/Sema/MultiplexExternalSemaSource.h367
-rw-r--r--include/clang/Sema/Overload.h12
-rw-r--r--include/clang/Sema/Ownership.h216
-rw-r--r--include/clang/Sema/ParsedTemplate.h5
-rw-r--r--include/clang/Sema/Scope.h8
-rw-r--r--include/clang/Sema/ScopeInfo.h226
-rw-r--r--include/clang/Sema/Sema.h249
-rw-r--r--include/clang/Sema/SemaConsumer.h1
-rw-r--r--include/clang/Sema/Template.h5
-rw-r--r--include/clang/Sema/TemplateDeduction.h18
-rw-r--r--include/clang/Sema/TypoCorrection.h12
-rw-r--r--include/clang/Serialization/ASTBitCodes.h234
-rw-r--r--include/clang/Serialization/ASTDeserializationListener.h6
-rw-r--r--include/clang/Serialization/ASTReader.h476
-rw-r--r--include/clang/Serialization/ASTWriter.h72
-rw-r--r--include/clang/Serialization/ContinuousRangeMap.h4
-rw-r--r--include/clang/Serialization/Module.h66
-rw-r--r--include/clang/Serialization/ModuleManager.h9
-rw-r--r--include/clang/StaticAnalyzer/Checkers/DereferenceChecker.h35
-rw-r--r--include/clang/StaticAnalyzer/Core/Analyses.def (renamed from include/clang/Frontend/Analyses.def)2
-rw-r--r--include/clang/StaticAnalyzer/Core/AnalyzerOptions.h308
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h89
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h58
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h129
-rw-r--r--include/clang/StaticAnalyzer/Core/Checker.h17
-rw-r--r--include/clang/StaticAnalyzer/Core/CheckerManager.h12
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h4
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h80
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h5
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h167
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h130
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h111
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h70
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h52
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h11
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h74
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h76
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h43
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h95
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h31
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h57
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h5
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/Store.h45
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h6
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h52
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h2
-rw-r--r--include/clang/Tooling/CommandLineClangTool.h80
-rw-r--r--include/clang/Tooling/CommonOptionsParser.h89
-rw-r--r--include/clang/Tooling/CompilationDatabase.h95
-rw-r--r--include/clang/Tooling/CompilationDatabasePluginRegistry.h27
-rw-r--r--include/clang/Tooling/FileMatchTrie.h90
-rw-r--r--include/clang/Tooling/JSONCompilationDatabase.h107
-rw-r--r--include/clang/Tooling/Refactoring.h1
-rw-r--r--include/clang/Tooling/Tooling.h48
218 files changed, 10678 insertions, 5556 deletions
diff --git a/include/clang/ARCMigrate/ARCMT.h b/include/clang/ARCMigrate/ARCMT.h
index 86a6cbb22aae..cce866165210 100644
--- a/include/clang/ARCMigrate/ARCMT.h
+++ b/include/clang/ARCMigrate/ARCMT.h
@@ -12,6 +12,7 @@
#include "clang/ARCMigrate/FileRemapper.h"
#include "clang/Frontend/CompilerInvocation.h"
+#include "clang/Basic/SourceLocation.h"
namespace clang {
class ASTContext;
@@ -51,7 +52,7 @@ bool applyTransformations(CompilerInvocation &origCI,
DiagnosticConsumer *DiagClient);
/// \brief Applies automatic modifications and produces temporary files
-/// and metadata into the \arg outputDir path.
+/// and metadata into the \p outputDir path.
///
/// \param emitPremigrationARCErrors if true all ARC errors will get emitted
/// even if the migrator can fix them, but the function will still return false
@@ -68,7 +69,7 @@ bool migrateWithTemporaryFiles(CompilerInvocation &origCI,
bool emitPremigrationARCErrors,
StringRef plistOut);
-/// \brief Get the set of file remappings from the \arg outputDir path that
+/// \brief Get the set of file remappings from the \p outputDir path that
/// migrateWithTemporaryFiles produced.
///
/// \returns false if no error is produced, true otherwise.
diff --git a/include/clang/AST/ASTConsumer.h b/include/clang/AST/ASTConsumer.h
index 69a3866969d2..37b0740cb98b 100644
--- a/include/clang/AST/ASTConsumer.h
+++ b/include/clang/AST/ASTConsumer.h
@@ -19,12 +19,14 @@ namespace clang {
class CXXRecordDecl;
class DeclGroupRef;
class HandleTagDeclDefinition;
+ class PPMutationListener;
class ASTMutationListener;
class ASTDeserializationListener; // layering violation because void* is ugly
class SemaConsumer; // layering violation required for safe SemaConsumer
class TagDecl;
class VarDecl;
class FunctionDecl;
+ class ImportDecl;
/// ASTConsumer - This is an abstract interface that should be implemented by
/// clients that read ASTs. This abstraction layer allows the client to be
@@ -79,6 +81,11 @@ public:
/// The default implementation ignored them.
virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef D);
+ /// \brief Handle an ImportDecl that was implicitly created due to an
+ /// inclusion directive.
+ /// The default implementation passes it to HandleTopLevelDecl.
+ virtual void HandleImplicitImportDecl(ImportDecl *D);
+
/// CompleteTentativeDefinition - Callback invoked at the end of a translation
/// unit to notify the consumer that the given tentative definition should be
/// completed.
@@ -105,6 +112,11 @@ public:
/// it was actually used.
virtual void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) {}
+ /// \brief If the consumer is interested in preprocessor entities getting
+ /// modified after their initial creation, it should return a pointer to
+ /// a PPMutationListener here.
+ virtual PPMutationListener *GetPPMutationListener() { return 0; }
+
/// \brief If the consumer is interested in entities getting modified after
/// their initial creation, it should return a pointer to
/// an ASTMutationListener here.
@@ -118,9 +130,6 @@ public:
/// PrintStats - If desired, print any statistics.
virtual void PrintStats() {}
-
- // Support isa/cast/dyn_cast
- static bool classof(const ASTConsumer *) { return true; }
};
} // end namespace clang.
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index cad3ad2b5f9c..f0934b77961b 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -6,9 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file defines the ASTContext interface.
-//
+///
+/// \file
+/// \brief Defines the clang::ASTContext interface.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_ASTCONTEXT_H
@@ -28,6 +29,7 @@
#include "clang/AST/Type.h"
#include "clang/AST/CanonicalType.h"
#include "clang/AST/RawCommentList.h"
+#include "clang/AST/CommentCommandTraits.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
@@ -84,8 +86,8 @@ namespace clang {
class FullComment;
}
-/// ASTContext - This class holds long-lived AST nodes (such as types and
-/// decls) that can be referred to throughout the semantic analysis of a file.
+/// \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; }
@@ -144,19 +146,20 @@ class ASTContext : public RefCountedBase<ASTContext> {
mutable NestedNameSpecifier *GlobalNestedNameSpecifier;
friend class NestedNameSpecifier;
- /// ASTRecordLayouts - A cache mapping from RecordDecls to ASTRecordLayouts.
- /// This is lazily created. This is intentionally not serialized.
+ /// \brief A cache mapping from RecordDecls to ASTRecordLayouts.
+ ///
+ /// This is lazily created. This is intentionally not serialized.
mutable llvm::DenseMap<const RecordDecl*, const ASTRecordLayout*>
ASTRecordLayouts;
mutable llvm::DenseMap<const ObjCContainerDecl*, const ASTRecordLayout*>
ObjCLayouts;
- /// TypeInfoMap - A cache from types to size and alignment information.
+ /// \brief A cache from types to size and alignment information.
typedef llvm::DenseMap<const Type*,
std::pair<uint64_t, unsigned> > TypeInfoMap;
mutable TypeInfoMap MemoizedTypeInfo;
- /// KeyFunctions - A cache mapping from CXXRecordDecls to key functions.
+ /// \brief A cache mapping from CXXRecordDecls to key functions.
llvm::DenseMap<const CXXRecordDecl*, const CXXMethodDecl*> KeyFunctions;
/// \brief Mapping from ObjCContainers to their ObjCImplementations.
@@ -170,7 +173,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
llvm::DenseMap<const VarDecl*, Expr*> BlockVarCopyInits;
/// \brief Mapping from class scope functions specialization to their
- /// template patterns.
+ /// template patterns.
llvm::DenseMap<const FunctionDecl*, FunctionDecl*>
ClassScopeSpecializationPattern;
@@ -206,17 +209,20 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// __builtin_va_list type.
mutable TypedefDecl *BuiltinVaListDecl;
- /// \brief The typedef for the predefined 'id' type.
+ /// \brief The typedef for the predefined \c id type.
mutable TypedefDecl *ObjCIdDecl;
- /// \brief The typedef for the predefined 'SEL' type.
+ /// \brief The typedef for the predefined \c SEL type.
mutable TypedefDecl *ObjCSelDecl;
- /// \brief The typedef for the predefined 'Class' type.
+ /// \brief The typedef for the predefined \c Class type.
mutable TypedefDecl *ObjCClassDecl;
- /// \brief The typedef for the predefined 'Protocol' class in Objective-C.
+ /// \brief The typedef for the predefined \c Protocol class in Objective-C.
mutable ObjCInterfaceDecl *ObjCProtocolClassDecl;
+
+ /// \brief The typedef for the predefined 'BOOL' type.
+ mutable TypedefDecl *BOOLDecl;
// Typedefs which may be provided defining the structure of Objective-C
// pseudo-builtins
@@ -296,9 +302,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
InstantiatedFromStaticDataMember;
/// \brief Keeps track of the declaration from which a UsingDecl was
- /// created during instantiation. The source declaration is always
- /// a UsingDecl, an UnresolvedUsingValueDecl, or an
- /// UnresolvedUsingTypenameDecl.
+ /// created during instantiation.
+ ///
+ /// The source declaration is always a UsingDecl, an UnresolvedUsingValueDecl,
+ /// or an UnresolvedUsingTypenameDecl.
///
/// For example:
/// \code
@@ -337,9 +344,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// mangling context.
llvm::DenseMap<const DeclContext *, LambdaMangleContext> LambdaMangleContexts;
- /// \brief Mapping that stores parameterIndex values for ParmVarDecls
- /// when that value exceeds the bitfield size of
- /// ParmVarDeclBits.ParameterIndex.
+ /// \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;
ParameterIndexTable ParamIndices;
@@ -348,10 +354,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
TranslationUnitDecl *TUDecl;
- /// SourceMgr - The associated SourceManager object.
+ /// \brief The associated SourceManager object.a
SourceManager &SourceMgr;
- /// LangOpts - The language options used to create the AST associated with
+ /// \brief The language options used to create the AST associated with
/// this ASTContext object.
LangOptions &LangOpts;
@@ -387,9 +393,11 @@ public:
OwningPtr<ExternalASTSource> ExternalSource;
ASTMutationListener *Listener;
- clang::PrintingPolicy getPrintingPolicy() const { return PrintingPolicy; }
+ const clang::PrintingPolicy &getPrintingPolicy() const {
+ return PrintingPolicy;
+ }
- void setPrintingPolicy(clang::PrintingPolicy Policy) {
+ void setPrintingPolicy(const clang::PrintingPolicy &Policy) {
PrintingPolicy = Policy;
}
@@ -508,6 +516,8 @@ public:
}
void addComment(const RawComment &RC) {
+ assert(LangOpts.RetainCommentsFromSystemHeaders ||
+ !SourceMgr.isInSystemHeader(RC.getSourceRange().getBegin()));
Comments.addComment(RC, BumpAlloc);
}
@@ -522,7 +532,22 @@ public:
/// Return parsed documentation comment attached to a given declaration.
/// Returns NULL if no comment is attached.
- comments::FullComment *getCommentForDecl(const Decl *D) const;
+ ///
+ /// \param PP the Preprocessor used with this TU. Could be NULL if
+ /// preprocessor is not available.
+ comments::FullComment *getCommentForDecl(const Decl *D,
+ const Preprocessor *PP) const;
+
+ comments::FullComment *cloneFullComment(comments::FullComment *FC,
+ const Decl *D) const;
+
+private:
+ mutable comments::CommandTraits CommentCommandTraits;
+
+public:
+ comments::CommandTraits &getCommentCommandTraits() const {
+ return CommentCommandTraits;
+ }
/// \brief Retrieve the attributes for the given declaration.
AttrVec& getDeclAttrs(const Decl *D);
@@ -547,7 +572,7 @@ public:
TemplateSpecializationKind TSK,
SourceLocation PointOfInstantiation = SourceLocation());
- /// \brief If the given using decl is an instantiation of a
+ /// \brief If the given using decl \p Inst is an instantiation of a
/// (possibly unresolved) using decl from a template instantiation,
/// return it.
NamedDecl *getInstantiatedFromUsingDecl(UsingDecl *Inst);
@@ -564,28 +589,28 @@ public:
void setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst, FieldDecl *Tmpl);
- /// ZeroBitfieldFollowsNonBitfield - return 'true" if 'FD' is a zero-length
- /// bitfield which follows the non-bitfield 'LastFD'.
+ /// \brief Return \c true if \p FD is a zero-length bitfield which follows
+ /// the non-bitfield \p LastFD.
bool ZeroBitfieldFollowsNonBitfield(const FieldDecl *FD,
const FieldDecl *LastFD) const;
- /// ZeroBitfieldFollowsBitfield - return 'true" if 'FD' is a zero-length
- /// bitfield which follows the bitfield 'LastFD'.
+ /// \brief Return \c true if \p FD is a zero-length bitfield which follows
+ /// the bitfield \p LastFD.
bool ZeroBitfieldFollowsBitfield(const FieldDecl *FD,
const FieldDecl *LastFD) const;
- /// BitfieldFollowsBitfield - return 'true" if 'FD' is a
- /// bitfield which follows the bitfield 'LastFD'.
+ /// \brief Return \c true if \p FD is a bitfield which follows the bitfield
+ /// \p LastFD.
bool BitfieldFollowsBitfield(const FieldDecl *FD,
const FieldDecl *LastFD) const;
- /// NonBitfieldFollowsBitfield - return 'true" if 'FD' is not a
- /// bitfield which follows the bitfield 'LastFD'.
+ /// \brief Return \c true if \p FD is not a bitfield which follows the
+ /// bitfield \p LastFD.
bool NonBitfieldFollowsBitfield(const FieldDecl *FD,
const FieldDecl *LastFD) const;
- /// BitfieldFollowsNonBitfield - return 'true" if 'FD' is a
- /// bitfield which follows the none bitfield 'LastFD'.
+ /// \brief Return \c true if \p FD is a bitfield which follows the
+ /// non-bitfield \p LastFD.
bool BitfieldFollowsNonBitfield(const FieldDecl *FD,
const FieldDecl *LastFD) const;
@@ -603,6 +628,17 @@ public:
/// Overridden method.
void addOverriddenMethod(const CXXMethodDecl *Method,
const CXXMethodDecl *Overridden);
+
+ /// \brief Return C++ or ObjC overridden methods for the given \p Method.
+ ///
+ /// An ObjC method is considered to override any method in the class's
+ /// base classes, its protocols, or its categories' protocols, that has
+ /// the same selector and is of the same kind (class or instance).
+ /// A method in an implementation is not considered as overriding the same
+ /// method in the interface or its categories.
+ void getOverriddenMethods(
+ const NamedDecl *Method,
+ SmallVectorImpl<const NamedDecl *> &Overridden) const;
/// \brief Notify the AST context that a new import declaration has been
/// parsed or implicitly created within this translation unit.
@@ -673,6 +709,7 @@ public:
CanQualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy;
CanQualType VoidPtrTy, NullPtrTy;
CanQualType DependentTy, OverloadTy, BoundMemberTy, UnknownAnyTy;
+ CanQualType BuiltinFnTy;
CanQualType PseudoObjectTy, ARCUnbridgedCastTy;
CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy;
CanQualType ObjCBuiltinBoolTy;
@@ -731,77 +768,85 @@ public:
//===--------------------------------------------------------------------===//
private:
- /// getExtQualType - Return a type with extended qualifiers.
+ /// \brief Return a type with extended qualifiers.
QualType getExtQualType(const Type *Base, Qualifiers Quals) const;
QualType getTypeDeclTypeSlow(const TypeDecl *Decl) const;
public:
- /// getAddSpaceQualType - Return the uniqued reference to the type for an
- /// address space qualified type with the specified type and address space.
+ /// \brief Return the uniqued reference to the type for an address space
+ /// qualified type with the specified type and address space.
+ ///
/// 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;
- /// getObjCGCQualType - Returns the uniqued reference to the type for an
- /// objc gc qualified type. The retulting type has a union of the qualifiers
- /// from T and the gc attribute.
+ /// \brief Return the uniqued reference to the type for an Objective-C
+ /// gc-qualified type.
+ ///
+ /// The retulting type has a union of the qualifiers from T and the gc
+ /// attribute.
QualType getObjCGCQualType(QualType T, Qualifiers::GC gcAttr) const;
- /// getRestrictType - Returns the uniqued reference to the type for a
- /// 'restrict' qualified type. The resulting type has a union of the
- /// qualifiers from T and 'restrict'.
+ /// \brief Return the uniqued reference to the type for a \c restrict
+ /// qualified type.
+ ///
+ /// The resulting type has a union of the qualifiers from \p T and
+ /// \c restrict.
QualType getRestrictType(QualType T) const {
return T.withFastQualifiers(Qualifiers::Restrict);
}
- /// getVolatileType - Returns the uniqued reference to the type for a
- /// 'volatile' qualified type. The resulting type has a union of the
- /// qualifiers from T and 'volatile'.
+ /// \brief Return the uniqued reference to the type for a \c volatile
+ /// qualified type.
+ ///
+ /// The resulting type has a union of the qualifiers from \p T and
+ /// \c volatile.
QualType getVolatileType(QualType T) const {
return T.withFastQualifiers(Qualifiers::Volatile);
}
- /// getConstType - Returns the uniqued reference to the type for a
- /// 'const' qualified type. The resulting type has a union of the
- /// qualifiers from T and 'const'.
+ /// \brief Return the uniqued reference to the type for a \c const
+ /// qualified type.
///
- /// It can be reasonably expected that this will always be
- /// equivalent to calling T.withConst().
+ /// The resulting type has a union of the qualifiers from \p T and \c const.
+ ///
+ /// It can be reasonably expected that this will always be equivalent to
+ /// calling T.withConst().
QualType getConstType(QualType T) const { return T.withConst(); }
- /// adjustFunctionType - Change the ExtInfo on a function type.
+ /// \brief Change the ExtInfo on a function type.
const FunctionType *adjustFunctionType(const FunctionType *Fn,
FunctionType::ExtInfo EInfo);
- /// getComplexType - Return the uniqued reference to the type for a complex
+ /// \brief Return the uniqued reference to the type for a complex
/// number with the specified element type.
QualType getComplexType(QualType T) const;
CanQualType getComplexType(CanQualType T) const {
return CanQualType::CreateUnsafe(getComplexType((QualType) T));
}
- /// getPointerType - Return the uniqued reference to the type for a pointer to
+ /// \brief Return the uniqued reference to the type for a pointer to
/// the specified type.
QualType getPointerType(QualType T) const;
CanQualType getPointerType(CanQualType T) const {
return CanQualType::CreateUnsafe(getPointerType((QualType) T));
}
- /// getAtomicType - Return the uniqued reference to the atomic type for
- /// the specified type.
+ /// \brief Return the uniqued reference to the atomic type for the specified
+ /// type.
QualType getAtomicType(QualType T) const;
- /// getBlockPointerType - Return the uniqued reference to the type for a block
- /// of the specified type.
+ /// \brief Return the uniqued reference to the type for a block of the
+ /// specified type.
QualType getBlockPointerType(QualType T) const;
- /// This gets the struct used to keep track of the descriptor for pointer to
+ /// Gets the struct used to keep track of the descriptor for pointer to
/// blocks.
QualType getBlockDescriptorType() const;
- /// This gets the struct used to keep track of the extended descriptor for
+ /// Gets the struct used to keep track of the extended descriptor for
/// pointer to blocks.
QualType getBlockDescriptorExtendedType() const;
@@ -812,78 +857,82 @@ public:
return cudaConfigureCallDecl;
}
- /// This builds the struct used for __block variables.
+ /// Builds the struct used for __block variables.
QualType BuildByRefType(StringRef DeclName, QualType Ty) const;
/// Returns true iff we need copy/dispose helpers for the given type.
bool BlockRequiresCopying(QualType Ty) const;
- /// getLValueReferenceType - Return the uniqued reference to the type for an
- /// lvalue reference to the specified type.
+ /// \brief Return the uniqued reference to the type for an lvalue reference
+ /// to the specified type.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue = true)
const;
- /// getRValueReferenceType - Return the uniqued reference to the type for an
- /// rvalue reference to the specified type.
+ /// \brief Return the uniqued reference to the type for an rvalue reference
+ /// to the specified type.
QualType getRValueReferenceType(QualType T) const;
- /// getMemberPointerType - Return the uniqued reference to the type for a
- /// member pointer to the specified type in the specified class. The class
- /// is a Type because it could be a dependent name.
+ /// \brief Return the uniqued reference to the type for a member pointer to
+ /// the specified type in the specified class.
+ ///
+ /// The class \p Cls is a \c Type because it could be a dependent name.
QualType getMemberPointerType(QualType T, const Type *Cls) const;
- /// getVariableArrayType - Returns a non-unique reference to the type for a
- /// variable array of the specified element type.
+ /// \brief Return a non-unique reference to the type for a variable array of
+ /// the specified element type.
QualType getVariableArrayType(QualType EltTy, Expr *NumElts,
ArrayType::ArraySizeModifier ASM,
unsigned IndexTypeQuals,
SourceRange Brackets) const;
- /// getDependentSizedArrayType - Returns a non-unique reference to
- /// the type for a dependently-sized array of the specified element
- /// type. FIXME: We will need these to be uniqued, or at least
- /// comparable, at some point.
+ /// \brief Return a non-unique reference to the type for a dependently-sized
+ /// array of the specified element type.
+ ///
+ /// FIXME: We will need these to be uniqued, or at least comparable, at some
+ /// point.
QualType getDependentSizedArrayType(QualType EltTy, Expr *NumElts,
ArrayType::ArraySizeModifier ASM,
unsigned IndexTypeQuals,
SourceRange Brackets) const;
- /// getIncompleteArrayType - Returns a unique reference to the type for a
- /// incomplete array of the specified element type.
+ /// \brief Return a unique reference to the type for an incomplete array of
+ /// the specified element type.
QualType getIncompleteArrayType(QualType EltTy,
ArrayType::ArraySizeModifier ASM,
unsigned IndexTypeQuals) const;
- /// getConstantArrayType - Return the unique reference to the type for a
- /// constant array of the specified element type.
+ /// \brief Return the unique reference to the type for a constant array of
+ /// the specified element type.
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize,
ArrayType::ArraySizeModifier ASM,
unsigned IndexTypeQuals) const;
- /// getVariableArrayDecayedType - Returns a vla type where known sizes
- /// are replaced with [*].
+ /// \brief Returns a vla type where known sizes are replaced with [*].
QualType getVariableArrayDecayedType(QualType Ty) const;
- /// getVectorType - Return the unique reference to a vector type of
- /// the specified element type and size. VectorType must be a built-in type.
+ /// \brief Return the unique reference to a vector type of the specified
+ /// element type and size.
+ ///
+ /// \pre \p VectorType must be a built-in type.
QualType getVectorType(QualType VectorType, unsigned NumElts,
VectorType::VectorKind VecKind) const;
- /// getExtVectorType - Return the unique reference to an extended vector type
- /// of the specified element type and size. VectorType must be a built-in
- /// type.
+ /// \brief Return the unique reference to an extended vector type
+ /// of the specified element type and size.
+ ///
+ /// \pre \p VectorType must be a built-in type.
QualType getExtVectorType(QualType VectorType, unsigned NumElts) const;
- /// getDependentSizedExtVectorType - Returns a non-unique reference to
- /// the type for a dependently-sized vector of the specified element
- /// type. FIXME: We will need these to be uniqued, or at least
- /// comparable, at some point.
+ /// \pre Return a non-unique reference to the type for a dependently-sized
+ /// vector of the specified element type.
+ ///
+ /// FIXME: We will need these to be uniqued, or at least comparable, at some
+ /// point.
QualType getDependentSizedExtVectorType(QualType VectorType,
Expr *SizeExpr,
SourceLocation AttrLoc) const;
- /// getFunctionNoProtoType - Return a K&R style C function type like 'int()'.
- ///
+ /// \brief Return a K&R style C function type like 'int()'.
QualType getFunctionNoProtoType(QualType ResultTy,
const FunctionType::ExtInfo &Info) const;
@@ -891,14 +940,13 @@ public:
return getFunctionNoProtoType(ResultTy, FunctionType::ExtInfo());
}
- /// getFunctionType - Return a normal function type with a typed
- /// argument list.
+ /// \brief Return a normal function type with a typed argument list.
QualType getFunctionType(QualType ResultTy,
const QualType *Args, unsigned NumArgs,
const FunctionProtoType::ExtProtoInfo &EPI) const;
- /// getTypeDeclType - Return the unique reference to the type for
- /// the specified type declaration.
+ /// \brief Return the unique reference to the type for the specified type
+ /// declaration.
QualType getTypeDeclType(const TypeDecl *Decl,
const TypeDecl *PrevDecl = 0) const {
assert(Decl && "Passed null for Decl param");
@@ -913,8 +961,8 @@ public:
return getTypeDeclTypeSlow(Decl);
}
- /// getTypedefType - Return the unique reference to the type for the
- /// specified typedef-name decl.
+ /// \brief Return the unique reference to the type for the specified
+ /// typedef-name decl.
QualType getTypedefType(const TypedefNameDecl *Decl,
QualType Canon = QualType()) const;
@@ -986,69 +1034,75 @@ public:
ObjCProtocolDecl * const *Protocols,
unsigned NumProtocols) const;
- /// getObjCObjectPointerType - Return a ObjCObjectPointerType type
- /// for the given ObjCObjectType.
+ /// \brief Return a ObjCObjectPointerType type for the given ObjCObjectType.
QualType getObjCObjectPointerType(QualType OIT) const;
- /// getTypeOfType - GCC extension.
+ /// \brief GCC extension.
QualType getTypeOfExprType(Expr *e) const;
QualType getTypeOfType(QualType t) const;
- /// getDecltypeType - C++0x decltype.
+ /// \brief C++11 decltype.
QualType getDecltypeType(Expr *e, QualType UnderlyingType) const;
- /// getUnaryTransformType - unary type transforms
+ /// \brief Unary type transforms
QualType getUnaryTransformType(QualType BaseType, QualType UnderlyingType,
UnaryTransformType::UTTKind UKind) const;
- /// getAutoType - C++0x deduced auto type.
+ /// \brief C++11 deduced auto type.
QualType getAutoType(QualType DeducedType) const;
- /// getAutoDeductType - C++0x deduction pattern for 'auto' type.
+ /// \brief C++11 deduction pattern for 'auto' type.
QualType getAutoDeductType() const;
- /// getAutoRRefDeductType - C++0x deduction pattern for 'auto &&' type.
+ /// \brief C++11 deduction pattern for 'auto &&' type.
QualType getAutoRRefDeductType() const;
- /// getTagDeclType - Return the unique reference to the type for the
- /// specified TagDecl (struct/union/class/enum) decl.
+ /// \brief Return the unique reference to the type for the specified TagDecl
+ /// (struct/union/class/enum) decl.
QualType getTagDeclType(const TagDecl *Decl) const;
- /// getSizeType - Return the unique type for "size_t" (C99 7.17), defined
- /// in <stddef.h>. The sizeof operator requires this (C99 6.5.3.4p4).
+ /// \brief Return the unique type for "size_t" (C99 7.17), defined in
+ /// <stddef.h>.
+ ///
+ /// The sizeof operator requires this (C99 6.5.3.4p4).
CanQualType getSizeType() const;
- /// getIntMaxType - Return the unique type for "intmax_t" (C99 7.18.1.5),
- /// defined in <stdint.h>.
+ /// \brief Return the unique type for "intmax_t" (C99 7.18.1.5), defined in
+ /// <stdint.h>.
CanQualType getIntMaxType() const;
- /// getUIntMaxType - Return the unique type for "uintmax_t" (C99 7.18.1.5),
- /// defined in <stdint.h>.
+ /// \brief Return the unique type for "uintmax_t" (C99 7.18.1.5), defined in
+ /// <stdint.h>.
CanQualType getUIntMaxType() const;
- /// getWCharType - In C++, this returns the unique wchar_t type. In C99, this
+ /// \brief In C++, this returns the unique wchar_t type. In C99, this
/// returns a type compatible with the type defined in <stddef.h> as defined
/// by the target.
QualType getWCharType() const { return WCharTy; }
- /// getSignedWCharType - Return the type of "signed wchar_t".
+ /// \brief Return the type of "signed wchar_t".
+ ///
/// Used when in C++, as a GCC extension.
QualType getSignedWCharType() const;
- /// getUnsignedWCharType - Return the type of "unsigned wchar_t".
+ /// \brief Return the type of "unsigned wchar_t".
+ ///
/// Used when in C++, as a GCC extension.
QualType getUnsignedWCharType() const;
- /// getWIntType - In C99, this returns a type compatible with the type
+ /// \brief In C99, this returns a type compatible with the type
/// defined in <stddef.h> as defined by the target.
QualType getWIntType() const { return WIntTy; }
- /// getPointerDiffType - Return the unique type for "ptrdiff_t" (C99 7.17)
- /// defined in <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9).
+ /// \brief Return the unique type for "ptrdiff_t" (C99 7.17) defined in
+ /// <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9).
QualType getPointerDiffType() const;
- // getCFConstantStringType - Return the C structure type used to represent
- // constant CFStrings.
+ /// \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;
+
+ /// \brief Return the C structure type used to represent constant CFStrings.
QualType getCFConstantStringType() const;
/// Get the structure type used to representation CFStrings, or NULL
@@ -1074,21 +1128,21 @@ public:
ObjCNSStringType = T;
}
- /// \brief Retrieve the type that 'id' has been defined to, which may be
- /// different from the built-in 'id' if 'id' has been typedef'd.
+ /// \brief Retrieve the type that \c id has been defined to, which may be
+ /// different from the built-in \c id if \c id has been typedef'd.
QualType getObjCIdRedefinitionType() const {
if (ObjCIdRedefinitionType.isNull())
return getObjCIdType();
return ObjCIdRedefinitionType;
}
- /// \brief Set the user-written type that redefines 'id'.
+ /// \brief Set the user-written type that redefines \c id.
void setObjCIdRedefinitionType(QualType RedefType) {
ObjCIdRedefinitionType = RedefType;
}
- /// \brief Retrieve the type that 'Class' has been defined to, which may be
- /// different from the built-in 'Class' if 'Class' has been typedef'd.
+ /// \brief Retrieve the type that \c Class has been defined to, which may be
+ /// different from the built-in \c Class if \c Class has been typedef'd.
QualType getObjCClassRedefinitionType() const {
if (ObjCClassRedefinitionType.isNull())
return getObjCClassType();
@@ -1175,27 +1229,29 @@ public:
return getLangOpts().CPlusPlus ? BoolTy : IntTy;
}
- /// getObjCEncodingForType - Emit the ObjC type encoding for the
- /// given type into \arg S. If \arg NameFields is specified then
- /// record field names are also encoded.
- void getObjCEncodingForType(QualType t, std::string &S,
+ /// \brief Emit the Objective-CC type encoding for the given type \p T into
+ /// \p S.
+ ///
+ /// If \p Field is specified then record field names are also encoded.
+ void getObjCEncodingForType(QualType T, std::string &S,
const FieldDecl *Field=0) const;
void getLegacyIntegralTypeEncoding(QualType &t) const;
- // Put the string version of type qualifiers into S.
+ /// \brief Put the string version of the type qualifiers \p QT into \p S.
void getObjCEncodingForTypeQualifier(Decl::ObjCDeclQualifier QT,
std::string &S) const;
- /// getObjCEncodingForFunctionDecl - Returns the encoded type for this
- /// function. This is in the same format as Objective-C method encodings.
+ /// \brief Emit the encoded type for the function \p Decl into \p S.
+ ///
+ /// This is in the same format as Objective-C method encodings.
///
/// \returns true if an error occurred (e.g., because one of the parameter
/// types is incomplete), false otherwise.
bool getObjCEncodingForFunctionDecl(const FunctionDecl *Decl, std::string& S);
- /// getObjCEncodingForMethodDecl - Return the encoded type for this method
- /// declaration.
+ /// \brief Emit the encoded type for the method declaration \p Decl into
+ /// \p S.
///
/// \returns true if an error occurred (e.g., because one of the parameter
/// types is incomplete), false otherwise.
@@ -1203,8 +1259,7 @@ public:
bool Extended = false)
const;
- /// getObjCEncodingForBlock - Return the encoded type for this block
- /// declaration.
+ /// \brief Return the encoded type for this block declaration.
std::string getObjCEncodingForBlock(const BlockExpr *blockExpr) const;
/// getObjCEncodingForPropertyDecl - Return the encoded type for
@@ -1218,16 +1273,18 @@ public:
bool ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto,
ObjCProtocolDecl *rProto) const;
- /// getObjCEncodingTypeSize returns size of type for objective-c encoding
- /// purpose in characters.
- CharUnits getObjCEncodingTypeSize(QualType t) const;
+ /// \brief Return the size of type \p T for Objective-C encoding purpose,
+ /// in characters.
+ CharUnits getObjCEncodingTypeSize(QualType T) const;
- /// \brief Retrieve the typedef corresponding to the predefined 'id' type
+ /// \brief Retrieve the typedef corresponding to the predefined \c id type
/// in Objective-C.
TypedefDecl *getObjCIdDecl() const;
- /// This setter/getter represents the ObjC 'id' type. It is setup lazily, by
- /// Sema. id is always a (typedef for a) pointer type, a pointer to a struct.
+ /// \brief Represents the Objective-CC \c id type.
+ ///
+ /// This is set up lazily, by Sema. \c id is always a (typedef for a)
+ /// pointer type, a pointer to a struct.
QualType getObjCIdType() const {
return getTypeDeclType(getObjCIdDecl());
}
@@ -1246,48 +1303,64 @@ public:
/// Objective-C 'Class' type.
TypedefDecl *getObjCClassDecl() const;
- /// This setter/getter repreents the ObjC 'Class' type. It is setup lazily, by
- /// Sema. 'Class' is always a (typedef for a) pointer type, a pointer to a
- /// struct.
+ /// \brief Represents the Objective-C \c Class type.
+ ///
+ /// This is set up lazily, by Sema. \c Class is always a (typedef for a)
+ /// pointer type, a pointer to a struct.
QualType getObjCClassType() const {
return getTypeDeclType(getObjCClassDecl());
}
/// \brief Retrieve the Objective-C class declaration corresponding to
- /// the predefined 'Protocol' class.
+ /// the predefined \c Protocol class.
ObjCInterfaceDecl *getObjCProtocolDecl() const;
+
+ /// \brief Retrieve declaration of 'BOOL' typedef
+ TypedefDecl *getBOOLDecl() const {
+ return BOOLDecl;
+ }
+
+ /// \brief Save declaration of 'BOOL' typedef
+ void setBOOLDecl(TypedefDecl *TD) {
+ BOOLDecl = TD;
+ }
+
+ /// \brief type of 'BOOL' type.
+ QualType getBOOLType() const {
+ return getTypeDeclType(getBOOLDecl());
+ }
- /// \brief Retrieve the type of the Objective-C "Protocol" class.
+ /// \brief Retrieve the type of the Objective-C \c Protocol class.
QualType getObjCProtoType() const {
return getObjCInterfaceType(getObjCProtocolDecl());
}
/// \brief Retrieve the C type declaration corresponding to the predefined
- /// __builtin_va_list type.
+ /// \c __builtin_va_list type.
TypedefDecl *getBuiltinVaListDecl() const;
- /// \brief Retrieve the type of the __builtin_va_list type.
+ /// \brief Retrieve the type of the \c __builtin_va_list type.
QualType getBuiltinVaListType() const {
return getTypeDeclType(getBuiltinVaListDecl());
}
/// \brief Retrieve the C type declaration corresponding to the predefined
- /// __va_list_tag type used to help define the __builtin_va_list type for
- /// some targets.
+ /// \c __va_list_tag type used to help define the \c __builtin_va_list type
+ /// for some targets.
QualType getVaListTagType() const;
- /// getCVRQualifiedType - Returns a type with additional const,
- /// volatile, or restrict qualifiers.
+ /// \brief Return a type with additional \c const, \c volatile, or
+ /// \c restrict qualifiers.
QualType getCVRQualifiedType(QualType T, unsigned CVR) const {
return getQualifiedType(T, Qualifiers::fromCVRMask(CVR));
}
- /// getQualifiedType - Un-split a SplitQualType.
+ /// \brief Un-split a SplitQualType.
QualType getQualifiedType(SplitQualType split) const {
return getQualifiedType(split.Ty, split.Quals);
}
- /// getQualifiedType - Returns a type with additional qualifiers.
+ /// \brief Return a type with additional qualifiers.
QualType getQualifiedType(QualType T, Qualifiers Qs) const {
if (!Qs.hasNonFastQualifiers())
return T.withFastQualifiers(Qs.getFastQualifiers());
@@ -1296,15 +1369,16 @@ public:
return getExtQualType(Ptr, Qc);
}
- /// getQualifiedType - Returns a type with additional qualifiers.
+ /// \brief Return a type with additional qualifiers.
QualType getQualifiedType(const Type *T, Qualifiers Qs) const {
if (!Qs.hasNonFastQualifiers())
return QualType(T, Qs.getFastQualifiers());
return getExtQualType(T, Qs);
}
- /// getLifetimeQualifiedType - Returns a type with the given
- /// lifetime qualifier.
+ /// \brief Return a type with the given lifetime qualifier.
+ ///
+ /// \pre Neither type.ObjCLifetime() nor \p lifetime may be \c OCL_None.
QualType getLifetimeQualifiedType(QualType type,
Qualifiers::ObjCLifetime lifetime) {
assert(type.getObjCLifetime() == Qualifiers::OCL_None);
@@ -1341,8 +1415,9 @@ public:
GE_Missing_ucontext ///< Missing a type from <ucontext.h>
};
- /// GetBuiltinType - Return the type for the specified builtin. If
- /// IntegerConstantArgs is non-null, it is filled in with a bitmask of
+ /// \brief Return the type for the specified builtin.
+ ///
+ /// If \p IntegerConstantArgs is non-null, it is filled in with a bitmask of
/// arguments to the builtin that are required to be integer constant
/// expressions.
QualType GetBuiltinType(unsigned ID, GetBuiltinTypeError &Error,
@@ -1357,19 +1432,19 @@ private:
//===--------------------------------------------------------------------===//
public:
- /// getObjCGCAttr - Returns one of GCNone, Weak or Strong objc's
- /// garbage collection attribute.
- ///
+ /// \brief Return one of the GCNone, Weak or Strong Objective-C garbage
+ /// collection attributes.
Qualifiers::GC getObjCGCAttrKind(QualType Ty) const;
- /// areCompatibleVectorTypes - Return true if the given vector types
- /// are of the same unqualified type or if they are equivalent to the same
- /// GCC vector type, ignoring whether they are target-specific (AltiVec or
- /// Neon) types.
+ /// \brief Return true if the given vector types are of the same unqualified
+ /// type or if they are equivalent to the same GCC vector type.
+ ///
+ /// \note This ignores whether they are target-specific (AltiVec or Neon)
+ /// types.
bool areCompatibleVectorTypes(QualType FirstVec, QualType SecondVec);
- /// isObjCNSObjectType - Return true if this is an NSObject object with
- /// its NSObject attribute set.
+ /// \brief Return true if this is an \c NSObject object with its \c NSObject
+ /// attribute set.
static bool isObjCNSObjectType(QualType Ty) {
return Ty->isObjCNSObjectType();
}
@@ -1378,19 +1453,17 @@ public:
// Type Sizing and Analysis
//===--------------------------------------------------------------------===//
- /// getFloatTypeSemantics - Return the APFloat 'semantics' for the specified
- /// scalar floating point type.
+ /// \brief Return the APFloat 'semantics' for the specified scalar floating
+ /// point type.
const llvm::fltSemantics &getFloatTypeSemantics(QualType T) const;
- /// getTypeInfo - Get the size and alignment of the specified complete type in
- /// bits.
+ /// \brief Get the size and alignment of the specified complete type in bits.
std::pair<uint64_t, unsigned> getTypeInfo(const Type *T) const;
std::pair<uint64_t, unsigned> getTypeInfo(QualType T) const {
return getTypeInfo(T.getTypePtr());
}
- /// getTypeSize - Return the size of the specified type, in bits. This method
- /// does not work on incomplete types.
+ /// \brief Return the size of the specified (complete) type \p T, in bits.
uint64_t getTypeSize(QualType T) const {
return getTypeInfo(T).first;
}
@@ -1398,24 +1471,24 @@ public:
return getTypeInfo(T).first;
}
- /// getCharWidth - Return the size of the character type, in bits
+ /// \brief Return the size of the character type, in bits.
uint64_t getCharWidth() const {
return getTypeSize(CharTy);
}
- /// toCharUnitsFromBits - Convert a size in bits to a size in characters.
+ /// \brief Convert a size in bits to a size in characters.
CharUnits toCharUnitsFromBits(int64_t BitSize) const;
- /// toBits - Convert a size in characters to a size in bits.
+ /// \brief Convert a size in characters to a size in bits.
int64_t toBits(CharUnits CharSize) const;
- /// getTypeSizeInChars - Return the size of the specified type, in characters.
- /// This method does not work on incomplete types.
+ /// \brief Return the size of the specified (complete) type \p T, in
+ /// characters.
CharUnits getTypeSizeInChars(QualType T) const;
CharUnits getTypeSizeInChars(const Type *T) const;
- /// getTypeAlign - Return the ABI-specified alignment of a type, in bits.
- /// This method does not work on incomplete types.
+ /// \brief Return the ABI-specified alignment of a (complete) type \p T, in
+ /// bits.
unsigned getTypeAlign(QualType T) const {
return getTypeInfo(T).second;
}
@@ -1423,49 +1496,59 @@ public:
return getTypeInfo(T).second;
}
- /// getTypeAlignInChars - Return the ABI-specified alignment of a type, in
- /// characters. This method does not work on incomplete types.
+ /// \brief Return the ABI-specified alignment of a (complete) type \p T, in
+ /// characters.
CharUnits getTypeAlignInChars(QualType T) const;
CharUnits getTypeAlignInChars(const Type *T) const;
+
+ // getTypeInfoDataSizeInChars - Return the size of a type, in chars. If the
+ // type is a record, its data size is returned.
+ std::pair<CharUnits, CharUnits> getTypeInfoDataSizeInChars(QualType T) const;
std::pair<CharUnits, CharUnits> getTypeInfoInChars(const Type *T) const;
std::pair<CharUnits, CharUnits> getTypeInfoInChars(QualType T) const;
- /// getPreferredTypeAlign - Return the "preferred" alignment of the specified
- /// type for the current target in bits. This can be different than the ABI
- /// alignment in cases where it is beneficial for performance to overalign
- /// a data type.
+ /// \brief Return the "preferred" alignment of the specified type \p T for
+ /// the current target, in bits.
+ ///
+ /// This can be different than the ABI alignment in cases where it is
+ /// beneficial for performance to overalign a data type.
unsigned getPreferredTypeAlign(const Type *T) const;
- /// getDeclAlign - Return a conservative estimate of the alignment of
- /// the specified decl. Note that bitfields do not have a valid alignment, so
- /// this method will assert on them.
- /// If @p RefAsPointee, references are treated like their underlying type
+ /// \brief Return a conservative estimate of the alignment of the specified
+ /// decl \p D.
+ ///
+ /// \pre \p D must not be a bitfield type, as bitfields do not have a valid
+ /// alignment.
+ ///
+ /// If \p RefAsPointee, references are treated like their underlying type
/// (for alignof), else they're treated like pointers (for CodeGen).
CharUnits getDeclAlign(const Decl *D, bool RefAsPointee = false) const;
- /// getASTRecordLayout - Get or compute information about the layout of the
- /// specified record (struct/union/class), which indicates its size and field
+ /// \brief Get or compute information about the layout of the specified
+ /// record (struct/union/class) \p D, which indicates its size and field
/// position information.
const ASTRecordLayout &getASTRecordLayout(const RecordDecl *D) const;
- /// getASTObjCInterfaceLayout - Get or compute information about the
- /// layout of the specified Objective-C interface.
+ /// \brief Get or compute information about the layout of the specified
+ /// Objective-C interface.
const ASTRecordLayout &getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D)
const;
void DumpRecordLayout(const RecordDecl *RD, raw_ostream &OS,
bool Simple = false) const;
- /// getASTObjCImplementationLayout - Get or compute information about
- /// the layout of the specified Objective-C implementation. This may
- /// differ from the interface if synthesized ivars are present.
+ /// \brief Get or compute information about the layout of the specified
+ /// Objective-C implementation.
+ ///
+ /// This may differ from the interface if synthesized ivars are present.
const ASTRecordLayout &
getASTObjCImplementationLayout(const ObjCImplementationDecl *D) const;
- /// getKeyFunction - Get the key function for the given record decl, or NULL
- /// if there isn't one. The key function is, according to the Itanium C++ ABI
- /// section 5.2.3:
+ /// \brief Get the key function for the given record decl, or NULL 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 point
/// of class definition.
@@ -1489,12 +1572,14 @@ public:
// Type Operators
//===--------------------------------------------------------------------===//
- /// getCanonicalType - Return the canonical (structural) type corresponding to
- /// the specified potentially non-canonical type. The non-canonical version
- /// of a type may have many "decorated" versions of types. Decorators can
- /// include typedefs, 'typeof' operators, etc. The returned type is guaranteed
- /// to be free of any of these, allowing two canonical types to be compared
- /// for exact equality with a simple pointer comparison.
+ /// \brief Return the canonical (structural) type corresponding to the
+ /// specified potentially non-canonical type \p T.
+ ///
+ /// The non-canonical version of a type may have many "decorated" versions of
+ /// types. Decorators can include typedefs, 'typeof' operators, etc. The
+ /// returned type is guaranteed to be free of any of these, allowing two
+ /// canonical types to be compared for exact equality with a simple pointer
+ /// comparison.
CanQualType getCanonicalType(QualType T) const {
return CanQualType::CreateUnsafe(T.getCanonicalType());
}
@@ -1503,21 +1588,23 @@ public:
return T->getCanonicalTypeInternal().getTypePtr();
}
- /// getCanonicalParamType - Return the canonical parameter type
- /// corresponding to the specific potentially non-canonical one.
+ /// \brief Return the canonical parameter type corresponding to the specific
+ /// potentially non-canonical one.
+ ///
/// Qualifiers are stripped off, functions are turned into function
/// pointers, and arrays decay one level into pointers.
CanQualType getCanonicalParamType(QualType T) const;
- /// \brief Determine whether the given types are equivalent.
+ /// \brief Determine whether the given types \p T1 and \p T2 are equivalent.
bool hasSameType(QualType T1, QualType T2) const {
return getCanonicalType(T1) == getCanonicalType(T2);
}
- /// \brief Returns this type as a completely-unqualified array type,
- /// capturing the qualifiers in Quals. This will remove the minimal amount of
- /// sugaring from the types, similar to the behavior of
- /// QualType::getUnqualifiedType().
+ /// \brief Return this type as a completely-unqualified array type,
+ /// capturing the qualifiers in \p Quals.
+ ///
+ /// This will remove the minimal amount of sugaring from the types, similar
+ /// to the behavior of QualType::getUnqualifiedType().
///
/// \param T is the qualified type, which may be an ArrayType
///
@@ -1628,15 +1715,16 @@ public:
return dyn_cast_or_null<DependentSizedArrayType>(getAsArrayType(T));
}
- /// getBaseElementType - Returns the innermost element type of an array type.
+ /// \brief Return the innermost element type of an array type.
+ ///
/// For example, will return "int" for int[m][n]
QualType getBaseElementType(const ArrayType *VAT) const;
- /// getBaseElementType - Returns the innermost element type of a type
- /// (which needn't actually be an array type).
+ /// \brief Return the innermost element type of a type (which needn't
+ /// actually be an array type).
QualType getBaseElementType(QualType QT) const;
- /// getConstantArrayElementCount - Returns number of constant array elements.
+ /// \brief Return number of constant array elements.
uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const;
/// \brief Perform adjustment on the parameter type of a function.
@@ -1651,21 +1739,22 @@ public:
/// cv-qualifiers.
QualType getSignatureParameterType(QualType T) const;
- /// getArrayDecayedType - Return the properly qualified result of decaying the
- /// specified array type to a pointer. This operation is non-trivial when
- /// handling typedefs etc. The canonical type of "T" must be an array type,
- /// this returns a pointer to a properly qualified element of the array.
+ /// \brief Return the properly qualified result of decaying the specified
+ /// array type to a pointer.
+ ///
+ /// This operation is non-trivial when handling typedefs etc. The canonical
+ /// type of \p T must be an array type, this returns a pointer to a properly
+ /// qualified element of the array.
///
/// See C99 6.7.5.3p7 and C99 6.3.2.1p3.
QualType getArrayDecayedType(QualType T) const;
- /// getPromotedIntegerType - Returns the type that Promotable will
- /// promote to: C99 6.3.1.1p2, assuming that Promotable is a promotable
- /// integer type.
+ /// \brief Return the type that \p PromotableType will promote to: C99
+ /// 6.3.1.1p2, assuming that \p PromotableType is a promotable integer type.
QualType getPromotedIntegerType(QualType PromotableType) const;
- /// \brief Recurses in pointer/array types until it finds an objc retainable
- /// type and returns its ownership.
+ /// \brief Recurses in pointer/array types until it finds an Objective-C
+ /// retainable type and returns its ownership.
Qualifiers::ObjCLifetime getInnerObjCOwnership(QualType T) const;
/// \brief Whether this is a promotable bitfield reference according
@@ -1675,21 +1764,24 @@ public:
/// promotion occurs.
QualType isPromotableBitField(Expr *E) const;
- /// getIntegerTypeOrder - Returns the highest ranked integer type:
- /// C99 6.3.1.8p1. If LHS > RHS, return 1. If LHS == RHS, return 0. If
- /// LHS < RHS, return -1.
+ /// \brief Return the highest ranked integer type, see C99 6.3.1.8p1.
+ ///
+ /// If \p LHS > \p RHS, returns 1. If \p LHS == \p RHS, returns 0. If
+ /// \p LHS < \p RHS, return -1.
int getIntegerTypeOrder(QualType LHS, QualType RHS) const;
- /// getFloatingTypeOrder - Compare the rank of the two specified floating
- /// point types, ignoring the domain of the type (i.e. 'double' ==
- /// '_Complex double'). If LHS > RHS, return 1. If LHS == RHS, return 0. If
- /// LHS < RHS, return -1.
+ /// \brief Compare the rank of the two specified floating point types,
+ /// ignoring the domain of the type (i.e. 'double' == '_Complex double').
+ ///
+ /// If \p LHS > \p RHS, returns 1. If \p LHS == \p RHS, returns 0. If
+ /// \p LHS < \p RHS, return -1.
int getFloatingTypeOrder(QualType LHS, QualType RHS) const;
- /// getFloatingTypeOfSizeWithinDomain - Returns a real floating
- /// point or a complex type (based on typeDomain/typeSize).
- /// 'typeDomain' is a real floating point or complex type.
- /// 'typeSize' is a real floating point or complex type.
+ /// \brief Return a real floating point or a complex type (based on
+ /// \p typeDomain/\p typeSize).
+ ///
+ /// \param typeDomain a real floating point or complex type.
+ /// \param typeSize a real floating point or complex type.
QualType getFloatingTypeOfSizeWithinDomain(QualType typeSize,
QualType typeDomain) const;
@@ -1787,7 +1879,7 @@ public:
// Per C99 6.2.5p6, for every signed integer type, there is a corresponding
// unsigned integer type. This method takes a signed type, and returns the
// corresponding unsigned integer type.
- QualType getCorrespondingUnsignedType(QualType T);
+ QualType getCorrespondingUnsignedType(QualType T) const;
//===--------------------------------------------------------------------===//
// Type Iterators.
@@ -1805,8 +1897,8 @@ public:
// Integer Values
//===--------------------------------------------------------------------===//
- /// MakeIntValue - Make an APSInt of the appropriate width and
- /// signedness for the given \arg Value and integer \arg Type.
+ /// \brief Make an APSInt of the appropriate width and signedness for the
+ /// given \p Value and integer \p Type.
llvm::APSInt MakeIntValue(uint64_t Value, QualType Type) const {
llvm::APSInt Res(getIntWidth(Type),
!Type->isSignedIntegerOrEnumerationType());
@@ -1816,12 +1908,14 @@ public:
bool isSentinelNullExpr(const Expr *E);
- /// \brief Get the implementation of ObjCInterfaceDecl,or NULL if none exists.
+ /// \brief Get the implementation of the ObjCInterfaceDecl \p D, or NULL if
+ /// none exists.
ObjCImplementationDecl *getObjCImplementation(ObjCInterfaceDecl *D);
- /// \brief Get the implementation of ObjCCategoryDecl, or NULL if none exists.
+ /// \brief Get the implementation of the ObjCCategoryDecl \p D, or NULL if
+ /// none exists.
ObjCCategoryImplDecl *getObjCImplementation(ObjCCategoryDecl *D);
- /// \brief returns true if there is at least one \@implementation in TU.
+ /// \brief Return true if there is at least one \@implementation in the TU.
bool AnyObjCImplementation() {
return !ObjCImpls.empty();
}
@@ -1834,7 +1928,7 @@ public:
ObjCCategoryImplDecl *ImplD);
/// \brief Get the duplicate declaration of a ObjCMethod in the same
- /// interface, or null if non exists.
+ /// interface, or null if none exists.
const ObjCMethodDecl *getObjCMethodRedeclaration(
const ObjCMethodDecl *MD) const {
return ObjCMethodRedecls.lookup(MD);
@@ -1846,16 +1940,16 @@ public:
ObjCMethodRedecls[MD] = Redecl;
}
- /// \brief Returns the objc interface that \arg ND belongs to if it is a
- /// objc method/property/ivar etc. that is part of an interface,
+ /// \brief Returns the Objective-C interface that \p ND belongs to if it is
+ /// an Objective-C method/property/ivar etc. that is part of an interface,
/// otherwise returns null.
ObjCInterfaceDecl *getObjContainingInterface(NamedDecl *ND) const;
/// \brief Set the copy inialization expression of a block var decl.
void setBlockVarCopyInits(VarDecl*VD, Expr* Init);
- /// \brief Get the copy initialization expression of VarDecl,or NULL if
- /// none exists.
- Expr *getBlockVarCopyInits(const VarDecl*VD);
+ /// \brief Get the copy initialization expression of the VarDecl \p VD, or
+ /// NULL if none exists.
+ Expr *getBlockVarCopyInits(const VarDecl* VD);
/// \brief Allocate an uninitialized TypeSourceInfo.
///
@@ -1882,9 +1976,9 @@ public:
/// \brief Add a deallocation callback that will be invoked when the
/// ASTContext is destroyed.
///
- /// \brief Callback A callback function that will be invoked on destruction.
+ /// \param Callback A callback function that will be invoked on destruction.
///
- /// \brief Data Pointer data that will be provided to the callback function
+ /// \param Data Pointer data that will be provided to the callback function
/// when it is called.
void AddDeallocation(void (*Callback)(void*), void *Data);
@@ -1957,8 +2051,8 @@ public:
static unsigned NumImplicitDestructorsDeclared;
private:
- ASTContext(const ASTContext&); // DO NOT IMPLEMENT
- void operator=(const ASTContext&); // DO NOT IMPLEMENT
+ ASTContext(const ASTContext &) LLVM_DELETED_FUNCTION;
+ void operator=(const ASTContext &) LLVM_DELETED_FUNCTION;
public:
/// \brief Initialize built-in types.
@@ -1974,7 +2068,7 @@ public:
private:
void InitBuiltinType(CanQualType &R, BuiltinType::Kind K);
- // Return the ObjC type encoding for a given type.
+ // Return the Objective-C type encoding for a given type.
void getObjCEncodingForTypeImpl(QualType t, std::string &S,
bool ExpandPointedToStructures,
bool ExpandStructures,
@@ -2017,13 +2111,13 @@ private:
void ReleaseDeclContextMaps();
};
-/// @brief Utility function for constructing a nullary selector.
+/// \brief Utility function for constructing a nullary selector.
static 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.
+/// \brief Utility function for constructing an unary selector.
static inline Selector GetUnarySelector(StringRef name, ASTContext& Ctx) {
IdentifierInfo* II = &Ctx.Idents.get(name);
return Ctx.Selectors.getSelector(1, &II);
diff --git a/include/clang/AST/ASTMutationListener.h b/include/clang/AST/ASTMutationListener.h
index cb038a0a5826..56d15260a581 100644
--- a/include/clang/AST/ASTMutationListener.h
+++ b/include/clang/AST/ASTMutationListener.h
@@ -13,6 +13,8 @@
#ifndef LLVM_CLANG_AST_ASTMUTATIONLISTENER_H
#define LLVM_CLANG_AST_ASTMUTATIONLISTENER_H
+#include "clang/Basic/SourceLocation.h"
+
namespace clang {
class Decl;
class DeclContext;
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index b17bd48b7d03..12a9855617c0 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -107,9 +107,6 @@ public:
// Pretty print this attribute.
virtual void printPretty(llvm::raw_ostream &OS,
const PrintingPolicy &Policy) const = 0;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *) { return true; }
};
class InheritableAttr : public Attr {
@@ -125,7 +122,6 @@ public:
static bool classof(const Attr *A) {
return A->getKind() <= attr::LAST_INHERITABLE;
}
- static bool classof(const InheritableAttr *) { return true; }
};
class InheritableParamAttr : public InheritableAttr {
@@ -139,7 +135,6 @@ public:
static bool classof(const Attr *A) {
return A->getKind() <= attr::LAST_INHERITABLE_PARAM;
}
- static bool classof(const InheritableParamAttr *) { return true; }
};
#include "clang/AST/Attrs.inc"
diff --git a/include/clang/AST/BuiltinTypes.def b/include/clang/AST/BuiltinTypes.def
index 34e6fc5cd826..ba322fb32655 100644
--- a/include/clang/AST/BuiltinTypes.def
+++ b/include/clang/AST/BuiltinTypes.def
@@ -206,6 +206,8 @@ PLACEHOLDER_TYPE(PseudoObject, PseudoObjectTy)
// unknown type, most notably explicit casts.
PLACEHOLDER_TYPE(UnknownAny, UnknownAnyTy)
+PLACEHOLDER_TYPE(BuiltinFn, BuiltinFnTy)
+
// The type of a cast which, in ARC, would normally require a
// __bridge, but which might be okay depending on the immediate
// context.
diff --git a/include/clang/AST/CMakeLists.txt b/include/clang/AST/CMakeLists.txt
index d7458aa7900e..4c4c0fb0a08b 100644
--- a/include/clang/AST/CMakeLists.txt
+++ b/include/clang/AST/CMakeLists.txt
@@ -20,3 +20,15 @@ clang_tablegen(CommentNodes.inc -gen-clang-comment-nodes
SOURCE ../Basic/CommentNodes.td
TARGET ClangCommentNodes)
+clang_tablegen(CommentHTMLTags.inc -gen-clang-comment-html-tags
+ SOURCE CommentHTMLTags.td
+ TARGET ClangCommentHTMLTags)
+
+clang_tablegen(CommentHTMLTagsProperties.inc -gen-clang-comment-html-tags-properties
+ SOURCE CommentHTMLTags.td
+ TARGET ClangCommentHTMLTagsProperties)
+
+clang_tablegen(CommentCommandInfo.inc -gen-clang-comment-command-info
+ SOURCE CommentCommands.td
+ TARGET ClangCommentCommandInfo)
+
diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h
index ee6eba78e415..87bdbe04f3df 100644
--- a/include/clang/AST/CXXInheritance.h
+++ b/include/clang/AST/CXXInheritance.h
@@ -19,7 +19,7 @@
#include "clang/AST/DeclCXX.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeOrdering.h"
-#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include <list>
@@ -271,15 +271,14 @@ struct UniqueVirtualMethod {
/// pair is the virtual method that overrides it (including the
/// subobject in which that virtual function occurs).
class OverridingMethods {
- llvm::DenseMap<unsigned, SmallVector<UniqueVirtualMethod, 4> >
- Overrides;
+ typedef SmallVector<UniqueVirtualMethod, 4> ValuesT;
+ typedef llvm::MapVector<unsigned, ValuesT> MapType;
+ MapType Overrides;
public:
// Iterate over the set of subobjects that have overriding methods.
- typedef llvm::DenseMap<unsigned, SmallVector<UniqueVirtualMethod, 4> >
- ::iterator iterator;
- typedef llvm::DenseMap<unsigned, SmallVector<UniqueVirtualMethod, 4> >
- ::const_iterator const_iterator;
+ typedef MapType::iterator iterator;
+ typedef MapType::const_iterator const_iterator;
iterator begin() { return Overrides.begin(); }
const_iterator begin() const { return Overrides.begin(); }
iterator end() { return Overrides.end(); }
@@ -357,8 +356,8 @@ public:
/// 0 represents the virtua base class subobject of that type, while
/// subobject numbers greater than 0 refer to non-virtual base class
/// subobjects of that type.
-class CXXFinalOverriderMap
- : public llvm::DenseMap<const CXXMethodDecl *, OverridingMethods> { };
+class CXXFinalOverriderMap
+ : public llvm::MapVector<const CXXMethodDecl *, OverridingMethods> { };
/// \brief A set of all the primary bases for a class.
class CXXIndirectPrimaryBaseSet
diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h
index 6cce88868db8..ea307bf307cb 100644
--- a/include/clang/AST/CanonicalType.h
+++ b/include/clang/AST/CanonicalType.h
@@ -276,6 +276,7 @@ public:
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isMemberFunctionPointerType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isClassType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureType)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isInterfaceType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureOrClassType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnionType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexIntegerType)
diff --git a/include/clang/AST/CharUnits.h b/include/clang/AST/CharUnits.h
index 5be35826a964..12e74b32be8a 100644
--- a/include/clang/AST/CharUnits.h
+++ b/include/clang/AST/CharUnits.h
@@ -164,8 +164,8 @@ namespace clang {
QuantityType getQuantity() const { return Quantity; }
/// RoundUpToAlignment - Returns the next integer (mod 2**64) that is
- /// greater than or equal to this quantity and is a multiple of \arg
- /// Align. Align must be non-zero.
+ /// greater than or equal to this quantity and is a multiple of \p Align.
+ /// Align must be non-zero.
CharUnits RoundUpToAlignment(const CharUnits &Align) {
return CharUnits(llvm::RoundUpToAlignment(Quantity,
Align.Quantity));
diff --git a/include/clang/AST/Comment.h b/include/clang/AST/Comment.h
index 01aaac3f77ad..316a1801bd46 100644
--- a/include/clang/AST/Comment.h
+++ b/include/clang/AST/Comment.h
@@ -16,6 +16,8 @@
#include "clang/Basic/SourceLocation.h"
#include "clang/AST/Type.h"
+#include "clang/AST/CommentCommandTraits.h"
+#include "clang/AST/DeclObjC.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
@@ -25,7 +27,7 @@ class ParmVarDecl;
class TemplateParameterList;
namespace comments {
-
+class FullComment;
/// Any part of the comment.
/// Abstract class.
class Comment {
@@ -74,8 +76,9 @@ protected:
unsigned : NumInlineContentCommentBits;
unsigned RenderKind : 2;
+ unsigned CommandID : 8;
};
- enum { NumInlineCommandCommentBits = NumInlineContentCommentBits + 1 };
+ enum { NumInlineCommandCommentBits = NumInlineContentCommentBits + 10 };
class HTMLStartTagCommentBitfields {
friend class HTMLStartTagComment;
@@ -101,10 +104,19 @@ protected:
};
enum { NumParagraphCommentBits = NumCommentBits + 2 };
+ class BlockCommandCommentBitfields {
+ friend class BlockCommandComment;
+
+ unsigned : NumCommentBits;
+
+ unsigned CommandID : 8;
+ };
+ enum { NumBlockCommandCommentBits = NumCommentBits + 8 };
+
class ParamCommandCommentBitfields {
friend class ParamCommandComment;
- unsigned : NumCommentBits;
+ unsigned : NumBlockCommandCommentBits;
/// Parameter passing direction, see ParamCommandComment::PassDirection.
unsigned Direction : 2;
@@ -112,7 +124,7 @@ protected:
/// True if direction was specified explicitly in the comment.
unsigned IsDirectionExplicit : 1;
};
- enum { NumParamCommandCommentBits = 11 };
+ enum { NumParamCommandCommentBits = NumBlockCommandCommentBits + 3 };
union {
CommentBitfields CommentBits;
@@ -121,6 +133,7 @@ protected:
InlineCommandCommentBitfields InlineCommandCommentBits;
HTMLStartTagCommentBitfields HTMLStartTagCommentBits;
ParagraphCommentBitfields ParagraphCommentBits;
+ BlockCommandCommentBitfields BlockCommandCommentBits;
ParamCommandCommentBitfields ParamCommandCommentBits;
};
@@ -158,10 +171,9 @@ public:
const char *getCommentKindName() const;
LLVM_ATTRIBUTE_USED void dump() const;
- LLVM_ATTRIBUTE_USED void dump(SourceManager &SM) const;
- void dump(llvm::raw_ostream &OS, SourceManager *SM) const;
-
- static bool classof(const Comment *) { return true; }
+ LLVM_ATTRIBUTE_USED void dump(const ASTContext &Context) const;
+ void dump(llvm::raw_ostream &OS, const CommandTraits *Traits,
+ const SourceManager *SM) const;
SourceRange getSourceRange() const LLVM_READONLY { return Range; }
@@ -204,8 +216,6 @@ public:
C->getCommentKind() <= LastInlineContentCommentConstant;
}
- static bool classof(const InlineContentComment *) { return true; }
-
void addTrailingNewline() {
InlineContentCommentBits.HasTrailingNewline = 1;
}
@@ -232,8 +242,6 @@ public:
return C->getCommentKind() == TextCommentKind;
}
- static bool classof(const TextComment *) { return true; }
-
child_iterator child_begin() const { return NULL; }
child_iterator child_end() const { return NULL; }
@@ -273,35 +281,35 @@ public:
};
protected:
- /// Command name.
- StringRef Name;
-
/// Command arguments.
llvm::ArrayRef<Argument> Args;
public:
InlineCommandComment(SourceLocation LocBegin,
SourceLocation LocEnd,
- StringRef Name,
+ unsigned CommandID,
RenderKind RK,
llvm::ArrayRef<Argument> Args) :
InlineContentComment(InlineCommandCommentKind, LocBegin, LocEnd),
- Name(Name), Args(Args) {
+ Args(Args) {
InlineCommandCommentBits.RenderKind = RK;
+ InlineCommandCommentBits.CommandID = CommandID;
}
static bool classof(const Comment *C) {
return C->getCommentKind() == InlineCommandCommentKind;
}
- static bool classof(const InlineCommandComment *) { return true; }
-
child_iterator child_begin() const { return NULL; }
child_iterator child_end() const { return NULL; }
- StringRef getCommandName() const {
- return Name;
+ unsigned getCommandID() const {
+ return InlineCommandCommentBits.CommandID;
+ }
+
+ StringRef getCommandName(const CommandTraits &Traits) const {
+ return Traits.getCommandInfo(getCommandID())->Name;
}
SourceRange getCommandNameRange() const {
@@ -352,8 +360,6 @@ public:
C->getCommentKind() <= LastHTMLTagCommentConstant;
}
- static bool classof(const HTMLTagComment *) { return true; }
-
StringRef getTagName() const LLVM_READONLY { return TagName; }
SourceRange getTagNameSourceRange() const LLVM_READONLY {
@@ -419,8 +425,6 @@ public:
return C->getCommentKind() == HTMLStartTagCommentKind;
}
- static bool classof(const HTMLStartTagComment *) { return true; }
-
child_iterator child_begin() const { return NULL; }
child_iterator child_end() const { return NULL; }
@@ -476,8 +480,6 @@ public:
return C->getCommentKind() == HTMLEndTagCommentKind;
}
- static bool classof(const HTMLEndTagComment *) { return true; }
-
child_iterator child_begin() const { return NULL; }
child_iterator child_end() const { return NULL; }
@@ -498,8 +500,6 @@ public:
return C->getCommentKind() >= FirstBlockContentCommentConstant &&
C->getCommentKind() <= LastBlockContentCommentConstant;
}
-
- static bool classof(const BlockContentComment *) { return true; }
};
/// A single paragraph that contains inline content.
@@ -529,8 +529,6 @@ public:
return C->getCommentKind() == ParagraphCommentKind;
}
- static bool classof(const ParagraphComment *) { return true; }
-
child_iterator child_begin() const {
return reinterpret_cast<child_iterator>(Content.begin());
}
@@ -566,9 +564,6 @@ public:
};
protected:
- /// Command name.
- StringRef Name;
-
/// Word-like arguments.
llvm::ArrayRef<Argument> Args;
@@ -578,21 +573,21 @@ protected:
BlockCommandComment(CommentKind K,
SourceLocation LocBegin,
SourceLocation LocEnd,
- StringRef Name) :
+ unsigned CommandID) :
BlockContentComment(K, LocBegin, LocEnd),
- Name(Name),
Paragraph(NULL) {
- setLocation(getCommandNameRange().getBegin());
+ setLocation(getCommandNameBeginLoc());
+ BlockCommandCommentBits.CommandID = CommandID;
}
public:
BlockCommandComment(SourceLocation LocBegin,
SourceLocation LocEnd,
- StringRef Name) :
+ unsigned CommandID) :
BlockContentComment(BlockCommandCommentKind, LocBegin, LocEnd),
- Name(Name),
Paragraph(NULL) {
- setLocation(getCommandNameRange().getBegin());
+ setLocation(getCommandNameBeginLoc());
+ BlockCommandCommentBits.CommandID = CommandID;
}
static bool classof(const Comment *C) {
@@ -600,8 +595,6 @@ public:
C->getCommentKind() <= LastBlockCommandCommentConstant;
}
- static bool classof(const BlockCommandComment *) { return true; }
-
child_iterator child_begin() const {
return reinterpret_cast<child_iterator>(&Paragraph);
}
@@ -610,12 +603,21 @@ public:
return reinterpret_cast<child_iterator>(&Paragraph + 1);
}
- StringRef getCommandName() const {
- return Name;
+ unsigned getCommandID() const {
+ return BlockCommandCommentBits.CommandID;
}
- SourceRange getCommandNameRange() const {
- return SourceRange(getLocStart().getLocWithOffset(1),
+ StringRef getCommandName(const CommandTraits &Traits) const {
+ return Traits.getCommandInfo(getCommandID())->Name;
+ }
+
+ SourceLocation getCommandNameBeginLoc() const {
+ return getLocStart().getLocWithOffset(1);
+ }
+
+ SourceRange getCommandNameRange(const CommandTraits &Traits) const {
+ StringRef Name = getCommandName(Traits);
+ return SourceRange(getCommandNameBeginLoc(),
getLocStart().getLocWithOffset(1 + Name.size()));
}
@@ -667,8 +669,9 @@ public:
ParamCommandComment(SourceLocation LocBegin,
SourceLocation LocEnd,
- StringRef Name) :
- BlockCommandComment(ParamCommandCommentKind, LocBegin, LocEnd, Name),
+ unsigned CommandID) :
+ BlockCommandComment(ParamCommandCommentKind, LocBegin, LocEnd,
+ CommandID),
ParamIndex(InvalidParamIndex) {
ParamCommandCommentBits.Direction = In;
ParamCommandCommentBits.IsDirectionExplicit = false;
@@ -678,8 +681,6 @@ public:
return C->getCommentKind() == ParamCommandCommentKind;
}
- static bool classof(const ParamCommandComment *) { return true; }
-
enum PassDirection {
In,
Out,
@@ -705,7 +706,9 @@ public:
return getNumArgs() > 0;
}
- StringRef getParamName() const {
+ StringRef getParamName(const FullComment *FC) const;
+
+ StringRef getParamNameAsWritten() const {
return Args[0].Text;
}
@@ -748,21 +751,21 @@ private:
public:
TParamCommandComment(SourceLocation LocBegin,
SourceLocation LocEnd,
- StringRef Name) :
- BlockCommandComment(TParamCommandCommentKind, LocBegin, LocEnd, Name)
+ unsigned CommandID) :
+ BlockCommandComment(TParamCommandCommentKind, LocBegin, LocEnd, CommandID)
{ }
static bool classof(const Comment *C) {
return C->getCommentKind() == TParamCommandCommentKind;
}
- static bool classof(const TParamCommandComment *) { return true; }
-
bool hasParamName() const {
return getNumArgs() > 0;
}
- StringRef getParamName() const {
+ StringRef getParamName(const FullComment *FC) const;
+
+ StringRef getParamNameAsWritten() const {
return Args[0].Text;
}
@@ -807,8 +810,6 @@ public:
return C->getCommentKind() == VerbatimBlockLineCommentKind;
}
- static bool classof(const VerbatimBlockLineComment *) { return true; }
-
child_iterator child_begin() const { return NULL; }
child_iterator child_end() const { return NULL; }
@@ -830,17 +831,15 @@ protected:
public:
VerbatimBlockComment(SourceLocation LocBegin,
SourceLocation LocEnd,
- StringRef Name) :
+ unsigned CommandID) :
BlockCommandComment(VerbatimBlockCommentKind,
- LocBegin, LocEnd, Name)
+ LocBegin, LocEnd, CommandID)
{ }
static bool classof(const Comment *C) {
return C->getCommentKind() == VerbatimBlockCommentKind;
}
- static bool classof(const VerbatimBlockComment *) { return true; }
-
child_iterator child_begin() const {
return reinterpret_cast<child_iterator>(Lines.begin());
}
@@ -882,12 +881,12 @@ protected:
public:
VerbatimLineComment(SourceLocation LocBegin,
SourceLocation LocEnd,
- StringRef Name,
+ unsigned CommandID,
SourceLocation TextBegin,
StringRef Text) :
BlockCommandComment(VerbatimLineCommentKind,
LocBegin, LocEnd,
- Name),
+ CommandID),
Text(Text),
TextBegin(TextBegin)
{ }
@@ -896,8 +895,6 @@ public:
return C->getCommentKind() == VerbatimLineCommentKind;
}
- static bool classof(const VerbatimLineComment *) { return true; }
-
child_iterator child_begin() const { return NULL; }
child_iterator child_end() const { return NULL; }
@@ -913,23 +910,34 @@ public:
/// Information about the declaration, useful to clients of FullComment.
struct DeclInfo {
- /// Declaration the comment is attached to. Should not be NULL.
- const Decl *ThisDecl;
-
- /// Parameters that can be referenced by \\param if \c ThisDecl is something
+ /// Declaration the comment is actually attached to (in the source).
+ /// Should not be NULL.
+ const Decl *CommentDecl;
+
+ /// CurrentDecl is the declaration with which the FullComment is associated.
+ ///
+ /// It can be different from \c CommentDecl. It happens when we we decide
+ /// that the comment originally attached to \c CommentDecl is fine for
+ /// \c CurrentDecl too (for example, for a redeclaration or an overrider of
+ /// \c CommentDecl).
+ ///
+ /// The information in the DeclInfo corresponds to CurrentDecl.
+ const Decl *CurrentDecl;
+
+ /// Parameters that can be referenced by \\param if \c CommentDecl is something
/// that we consider a "function".
ArrayRef<const ParmVarDecl *> ParamVars;
- /// Function result type if \c ThisDecl is something that we consider
+ /// Function result type if \c CommentDecl is something that we consider
/// a "function".
QualType ResultType;
- /// Template parameters that can be referenced by \\tparam if \c ThisDecl is
+ /// Template parameters that can be referenced by \\tparam if \c CommentDecl is
/// a template (\c IsTemplateDecl or \c IsTemplatePartialSpecialization is
/// true).
const TemplateParameterList *TemplateParameters;
- /// A simplified description of \c ThisDecl kind that should be good enough
+ /// A simplified description of \c CommentDecl kind that should be good enough
/// for documentation rendering purposes.
enum DeclKind {
/// Everything else not explicitly mentioned below.
@@ -942,7 +950,9 @@ struct DeclInfo {
/// \li member function,
/// \li member function template,
/// \li member function template specialization,
- /// \li ObjC method.
+ /// \li ObjC method,
+ /// \li a typedef for a function pointer, member function pointer,
+ /// ObjC block.
FunctionKind,
/// Something that we consider a "class":
@@ -968,7 +978,7 @@ struct DeclInfo {
EnumKind
};
- /// What kind of template specialization \c ThisDecl is.
+ /// What kind of template specialization \c CommentDecl is.
enum TemplateDeclKind {
NotTemplate,
Template,
@@ -976,24 +986,24 @@ struct DeclInfo {
TemplatePartialSpecialization
};
- /// If false, only \c ThisDecl is valid.
+ /// If false, only \c CommentDecl is valid.
unsigned IsFilled : 1;
- /// Simplified kind of \c ThisDecl, see\c DeclKind enum.
+ /// Simplified kind of \c CommentDecl, see \c DeclKind enum.
unsigned Kind : 3;
- /// Is \c ThisDecl a template declaration.
+ /// Is \c CommentDecl a template declaration.
unsigned TemplateKind : 2;
- /// Is \c ThisDecl an ObjCMethodDecl.
+ /// Is \c CommentDecl an ObjCMethodDecl.
unsigned IsObjCMethod : 1;
- /// Is \c ThisDecl a non-static member function of C++ class or
+ /// Is \c CommentDecl a non-static member function of C++ class or
/// instance method of ObjC class.
/// Can be true only if \c IsFunctionDecl is true.
unsigned IsInstanceMethod : 1;
- /// Is \c ThisDecl a static member function of C++ class or
+ /// Is \c CommentDecl a static member function of C++ class or
/// class method of ObjC class.
/// Can be true only if \c IsFunctionDecl is true.
unsigned IsClassMethod : 1;
@@ -1012,7 +1022,6 @@ struct DeclInfo {
/// A full comment attached to a declaration, contains block content.
class FullComment : public Comment {
llvm::ArrayRef<BlockContentComment *> Blocks;
-
DeclInfo *ThisDeclInfo;
public:
@@ -1031,27 +1040,31 @@ public:
return C->getCommentKind() == FullCommentKind;
}
- static bool classof(const FullComment *) { return true; }
-
child_iterator child_begin() const {
return reinterpret_cast<child_iterator>(Blocks.begin());
}
child_iterator child_end() const {
- return reinterpret_cast<child_iterator>(Blocks.end());
+ return reinterpret_cast<child_iterator>(Blocks.end());
}
const Decl *getDecl() const LLVM_READONLY {
- return ThisDeclInfo->ThisDecl;
+ return ThisDeclInfo->CommentDecl;
}
-
+
const DeclInfo *getDeclInfo() const LLVM_READONLY {
if (!ThisDeclInfo->IsFilled)
ThisDeclInfo->fill();
return ThisDeclInfo;
}
+
+ DeclInfo *getThisDeclInfo() const LLVM_READONLY {
+ return ThisDeclInfo;
+ }
+
+ llvm::ArrayRef<BlockContentComment *> getBlocks() const { return Blocks; }
+
};
-
} // end namespace comments
} // end namespace clang
diff --git a/include/clang/AST/CommentBriefParser.h b/include/clang/AST/CommentBriefParser.h
index 003c33727e35..5d508860635d 100644
--- a/include/clang/AST/CommentBriefParser.h
+++ b/include/clang/AST/CommentBriefParser.h
@@ -44,8 +44,7 @@ class BriefParser {
public:
BriefParser(Lexer &L, const CommandTraits &Traits);
- /// Return \\brief paragraph, if it exists; otherwise return the first
- /// paragraph.
+ /// Return the best "brief description" we can find.
std::string Parse();
};
diff --git a/include/clang/AST/CommentCommandTraits.h b/include/clang/AST/CommentCommandTraits.h
index 5f0269a4650b..6d44c706c3dc 100644
--- a/include/clang/AST/CommentCommandTraits.h
+++ b/include/clang/AST/CommentCommandTraits.h
@@ -19,136 +19,132 @@
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/ErrorHandling.h"
namespace clang {
namespace comments {
-/// This class provides informaiton about commands that can be used
-/// in comments.
-class CommandTraits {
-public:
- CommandTraits() { }
+/// \brief Information about a single command.
+///
+/// When reordering, adding or removing members please update the corresponding
+/// TableGen backend.
+struct CommandInfo {
+ unsigned getID() const {
+ return ID;
+ }
+
+ const char *Name;
+
+ /// Name of the command that ends the verbatim block.
+ const char *EndCommandName;
+
+ unsigned ID : 8;
+
+ /// Number of word-like arguments for a given block command, except for
+ /// \\param and \\tparam commands -- these have special argument parsers.
+ unsigned NumArgs : 4;
- /// \brief Check if a given command is a verbatim-like block command.
+ /// True if this command is a inline command (of any kind).
+ unsigned IsInlineCommand : 1;
+
+ /// True if this command is a block command (of any kind).
+ unsigned IsBlockCommand : 1;
+
+ /// True if this command is introducing a brief documentation
+ /// paragraph (\\brief or an alias).
+ unsigned IsBriefCommand : 1;
+
+ /// True if this command is \\returns or an alias.
+ unsigned IsReturnsCommand : 1;
+
+ /// True if this command is introducing documentation for a function
+ /// parameter (\\param or an alias).
+ unsigned IsParamCommand : 1;
+
+ /// True if this command is introducing documentation for
+ /// a template parameter (\\tparam or an alias).
+ unsigned IsTParamCommand : 1;
+
+ /// True if this command is \\deprecated or an alias.
+ unsigned IsDeprecatedCommand : 1;
+
+ /// True if we don't want to warn about this command being passed an empty
+ /// paragraph. Meaningful only for block commands.
+ unsigned IsEmptyParagraphAllowed : 1;
+
+ /// \brief True if this command is a verbatim-like block command.
///
/// A verbatim-like block command eats every character (except line starting
/// decorations) until matching end command is seen or comment end is hit.
- ///
- /// \param StartName name of the command that starts the verbatim block.
- /// \param [out] EndName name of the command that ends the verbatim block.
- ///
- /// \returns true if a given command is a verbatim block command.
- bool isVerbatimBlockCommand(StringRef StartName, StringRef &EndName) const;
+ unsigned IsVerbatimBlockCommand : 1;
- /// \brief Register a new verbatim block command.
- void addVerbatimBlockCommand(StringRef StartName, StringRef EndName);
+ /// \brief True if this command is an end command for a verbatim-like block.
+ unsigned IsVerbatimBlockEndCommand : 1;
- /// \brief Check if a given command is a verbatim line command.
+ /// \brief True if this command is a verbatim line command.
///
/// A verbatim-like line command eats everything until a newline is seen or
/// comment end is hit.
- bool isVerbatimLineCommand(StringRef Name) const;
+ unsigned IsVerbatimLineCommand : 1;
- /// \brief Check if a given command is a command that contains a declaration
- /// for the entity being documented.
+ /// \brief True if this command contains a declaration for the entity being
+ /// documented.
///
/// For example:
/// \code
/// \fn void f(int a);
/// \endcode
- bool isDeclarationCommand(StringRef Name) const;
+ unsigned IsDeclarationCommand : 1;
- /// \brief Register a new verbatim line command.
- void addVerbatimLineCommand(StringRef Name);
+ /// \brief True if this command is unknown. This \c CommandInfo object was
+ /// created during parsing.
+ unsigned IsUnknownCommand : 1;
+};
- /// \brief Check if a given command is a block command (of any kind).
- bool isBlockCommand(StringRef Name) const;
+/// This class provides information about commands that can be used
+/// in comments.
+class CommandTraits {
+public:
+ CommandTraits(llvm::BumpPtrAllocator &Allocator);
- /// \brief Check if a given command is introducing documentation for
- /// a function parameter (\\param or an alias).
- bool isParamCommand(StringRef Name) const;
+ /// \returns a CommandInfo object for a given command name or
+ /// NULL if no CommandInfo object exists for this command.
+ const CommandInfo *getCommandInfoOrNULL(StringRef Name) const;
- /// \brief Check if a given command is introducing documentation for
- /// a template parameter (\\tparam or an alias).
- bool isTParamCommand(StringRef Name) const;
+ const CommandInfo *getCommandInfo(StringRef Name) const {
+ if (const CommandInfo *Info = getCommandInfoOrNULL(Name))
+ return Info;
+ llvm_unreachable("the command should be known");
+ }
- /// \brief Check if a given command is introducing a brief documentation
- /// paragraph (\\brief or an alias).
- bool isBriefCommand(StringRef Name) const;
+ const CommandInfo *getCommandInfo(unsigned CommandID) const;
- /// \brief Check if a given command is \\brief or an alias.
- bool isReturnsCommand(StringRef Name) const;
+ const CommandInfo *registerUnknownCommand(StringRef CommandName);
- /// \returns the number of word-like arguments for a given block command,
- /// except for \\param and \\tparam commands -- these have special argument
- /// parsers.
- unsigned getBlockCommandNumArgs(StringRef Name) const;
+ /// \returns a CommandInfo object for a given command name or
+ /// NULL if \c Name is not a builtin command.
+ static const CommandInfo *getBuiltinCommandInfo(StringRef Name);
- /// \brief Check if a given command is a inline command (of any kind).
- bool isInlineCommand(StringRef Name) const;
+ /// \returns a CommandInfo object for a given command ID or
+ /// NULL if \c CommandID is not a builtin command.
+ static const CommandInfo *getBuiltinCommandInfo(unsigned CommandID);
private:
- struct VerbatimBlockCommand {
- StringRef StartName;
- StringRef EndName;
- };
-
- typedef SmallVector<VerbatimBlockCommand, 4> VerbatimBlockCommandVector;
+ CommandTraits(const CommandTraits &) LLVM_DELETED_FUNCTION;
+ void operator=(const CommandTraits &) LLVM_DELETED_FUNCTION;
- /// Registered additional verbatim-like block commands.
- VerbatimBlockCommandVector VerbatimBlockCommands;
+ const CommandInfo *getRegisteredCommandInfo(StringRef Name) const;
+ const CommandInfo *getRegisteredCommandInfo(unsigned CommandID) const;
- struct VerbatimLineCommand {
- StringRef Name;
- };
+ unsigned NextID;
- typedef SmallVector<VerbatimLineCommand, 4> VerbatimLineCommandVector;
+ /// Allocator for CommandInfo objects.
+ llvm::BumpPtrAllocator &Allocator;
- /// Registered verbatim-like line commands.
- VerbatimLineCommandVector VerbatimLineCommands;
+ SmallVector<CommandInfo *, 4> RegisteredCommands;
};
-inline bool CommandTraits::isBlockCommand(StringRef Name) const {
- return isBriefCommand(Name) || isReturnsCommand(Name) ||
- isParamCommand(Name) || isTParamCommand(Name) ||
- llvm::StringSwitch<bool>(Name)
- .Case("author", true)
- .Case("authors", true)
- .Case("pre", true)
- .Case("post", true)
- .Default(false);
-}
-
-inline bool CommandTraits::isParamCommand(StringRef Name) const {
- return Name == "param";
-}
-
-inline bool CommandTraits::isTParamCommand(StringRef Name) const {
- return Name == "tparam" || // Doxygen
- Name == "templatefield"; // HeaderDoc
-}
-
-inline bool CommandTraits::isBriefCommand(StringRef Name) const {
- return Name == "brief" || Name == "short";
-}
-
-inline bool CommandTraits::isReturnsCommand(StringRef Name) const {
- return Name == "returns" || Name == "return" || Name == "result";
-}
-
-inline unsigned CommandTraits::getBlockCommandNumArgs(StringRef Name) const {
- return 0;
-}
-
-inline bool CommandTraits::isInlineCommand(StringRef Name) const {
- return llvm::StringSwitch<bool>(Name)
- .Case("b", true)
- .Cases("c", "p", true)
- .Cases("a", "e", "em", true)
- .Default(false);
-}
-
} // end namespace comments
} // end namespace clang
diff --git a/include/clang/AST/CommentCommands.td b/include/clang/AST/CommentCommands.td
new file mode 100644
index 000000000000..3d8bad89c26b
--- /dev/null
+++ b/include/clang/AST/CommentCommands.td
@@ -0,0 +1,156 @@
+class Command<string name> {
+ string Name = name;
+ string EndCommandName = "";
+
+ int NumArgs = 0;
+
+ bit IsInlineCommand = 0;
+
+ bit IsBlockCommand = 0;
+ bit IsBriefCommand = 0;
+ bit IsReturnsCommand = 0;
+ bit IsParamCommand = 0;
+ bit IsTParamCommand = 0;
+ bit IsDeprecatedCommand = 0;
+
+ bit IsEmptyParagraphAllowed = 0;
+
+ bit IsVerbatimBlockCommand = 0;
+ bit IsVerbatimBlockEndCommand = 0;
+ bit IsVerbatimLineCommand = 0;
+ bit IsDeclarationCommand = 0;
+}
+
+class InlineCommand<string name> : Command<name> {
+ let IsInlineCommand = 1;
+}
+
+class BlockCommand<string name> : Command<name> {
+ let IsBlockCommand = 1;
+}
+
+class VerbatimBlockCommand<string name> : Command<name> {
+ let EndCommandName = name;
+ let IsVerbatimBlockCommand = 1;
+}
+
+multiclass VerbatimBlockCommand<string name, string endCommandName> {
+ def Begin : Command<name> {
+ let EndCommandName = endCommandName;
+ let IsVerbatimBlockCommand = 1;
+ }
+
+ def End : Command<endCommandName> {
+ let IsVerbatimBlockEndCommand = 1;
+ }
+}
+
+class VerbatimLineCommand<string name> : Command<name> {
+ let IsVerbatimLineCommand = 1;
+}
+
+class DeclarationVerbatimLineCommand<string name> :
+ VerbatimLineCommand<name> {
+ let IsDeclarationCommand = 1;
+}
+
+def B : InlineCommand<"b">;
+def C : InlineCommand<"c">;
+def P : InlineCommand<"p">;
+def A : InlineCommand<"a">;
+def E : InlineCommand<"e">;
+def Em : InlineCommand<"em">;
+
+def Brief : BlockCommand<"brief"> { let IsBriefCommand = 1; }
+def Short : BlockCommand<"short"> { let IsBriefCommand = 1; }
+
+def Returns : BlockCommand<"returns"> { let IsReturnsCommand = 1; }
+def Return : BlockCommand<"return"> { let IsReturnsCommand = 1; }
+def Result : BlockCommand<"result"> { let IsReturnsCommand = 1; }
+
+def Param : BlockCommand<"param"> { let IsParamCommand = 1; }
+
+// Doxygen
+def Tparam : BlockCommand<"tparam"> { let IsTParamCommand = 1; }
+
+// HeaderDoc
+def Templatefield : BlockCommand<"templatefield"> { let IsTParamCommand = 1; }
+
+def Deprecated : BlockCommand<"deprecated"> {
+ let IsEmptyParagraphAllowed = 1;
+ let IsDeprecatedCommand = 1;
+}
+
+def Author : BlockCommand<"author">;
+def Authors : BlockCommand<"authors">;
+def Bug : BlockCommand<"bug">;
+def Copyright : BlockCommand<"copyright">;
+def Date : BlockCommand<"date">;
+def Details : BlockCommand<"details">;
+def Invariant : BlockCommand<"invariant">;
+def Note : BlockCommand<"note">;
+def Post : BlockCommand<"post">;
+def Pre : BlockCommand<"pre">;
+def Remark : BlockCommand<"remark">;
+def Remarks : BlockCommand<"remarks">;
+def Sa : BlockCommand<"sa">;
+def See : BlockCommand<"see">;
+def Since : BlockCommand<"since">;
+def Todo : BlockCommand<"todo">;
+def Version : BlockCommand<"version">;
+def Warning : BlockCommand<"warning">;
+
+defm Code : VerbatimBlockCommand<"code", "endcode">;
+defm Verbatim : VerbatimBlockCommand<"verbatim", "endverbatim">;
+defm Htmlonly : VerbatimBlockCommand<"htmlonly", "endhtmlonly">;
+defm Latexonly : VerbatimBlockCommand<"latexonly", "endlatexonly">;
+defm Xmlonly : VerbatimBlockCommand<"xmlonly", "endxmlonly">;
+defm Manonly : VerbatimBlockCommand<"manonly", "endmanonly">;
+defm Rtfonly : VerbatimBlockCommand<"rtfonly", "endrtfonly">;
+
+defm Dot : VerbatimBlockCommand<"dot", "enddot">;
+defm Msc : VerbatimBlockCommand<"msc", "endmsc">;
+
+// These commands have special support in lexer.
+def FDollar : VerbatimBlockCommand<"f$">; // Inline LaTeX formula
+defm FBracket : VerbatimBlockCommand<"f[", "f]">; // Displayed LaTeX formula
+defm FBrace : VerbatimBlockCommand<"f{", "f}">; // LaTeX environment
+
+def Defgroup : VerbatimLineCommand<"defgroup">;
+def Ingroup : VerbatimLineCommand<"ingroup">;
+def Addtogroup : VerbatimLineCommand<"addtogroup">;
+def Weakgroup : VerbatimLineCommand<"weakgroup">;
+def Name : VerbatimLineCommand<"name">;
+
+def Section : VerbatimLineCommand<"section">;
+def Subsection : VerbatimLineCommand<"subsection">;
+def Subsubsection : VerbatimLineCommand<"subsubsection">;
+def Paragraph : VerbatimLineCommand<"paragraph">;
+
+def Mainpage : VerbatimLineCommand<"mainpage">;
+def Subpage : VerbatimLineCommand<"subpage">;
+def Ref : VerbatimLineCommand<"ref">;
+
+// Doxygen commands.
+def Fn : DeclarationVerbatimLineCommand<"fn">;
+def Namespace : DeclarationVerbatimLineCommand<"namespace">;
+def Overload : DeclarationVerbatimLineCommand<"overload">;
+def Property : DeclarationVerbatimLineCommand<"property">;
+def Typedef : DeclarationVerbatimLineCommand<"typedef">;
+def Var : DeclarationVerbatimLineCommand<"var">;
+
+// HeaderDoc commands.
+def Class : DeclarationVerbatimLineCommand<"class">;
+def Interface : DeclarationVerbatimLineCommand<"interface">;
+def Protocol : DeclarationVerbatimLineCommand<"protocol">;
+def Category : DeclarationVerbatimLineCommand<"category">;
+def Template : DeclarationVerbatimLineCommand<"template">;
+def Function : DeclarationVerbatimLineCommand<"function">;
+def Method : DeclarationVerbatimLineCommand<"method">;
+def Callback : DeclarationVerbatimLineCommand<"callback">;
+def Const : DeclarationVerbatimLineCommand<"const">;
+def Constant : DeclarationVerbatimLineCommand<"constant">;
+def Struct : DeclarationVerbatimLineCommand<"struct">;
+def Union : DeclarationVerbatimLineCommand<"union">;
+def Enum : DeclarationVerbatimLineCommand<"enum">;
+
diff --git a/include/clang/AST/CommentHTMLTags.td b/include/clang/AST/CommentHTMLTags.td
new file mode 100644
index 000000000000..f98e32ddca4f
--- /dev/null
+++ b/include/clang/AST/CommentHTMLTags.td
@@ -0,0 +1,54 @@
+class Tag<string spelling> {
+ string Spelling = spelling;
+ bit EndTagOptional = 0;
+ bit EndTagForbidden = 0;
+}
+
+def Em : Tag<"em">;
+def Strong : Tag<"strong">;
+def Tt : Tag<"tt">;
+def I : Tag<"i">;
+def B : Tag<"b">;
+def Big : Tag<"big">;
+def Small : Tag<"small">;
+def Strike : Tag<"strike">;
+def S : Tag<"s">;
+def U : Tag<"u">;
+def Font : Tag<"font">;
+def A : Tag<"a">;
+def Hr : Tag<"hr"> { let EndTagForbidden = 1; }
+def Div : Tag<"div">;
+def Span : Tag<"span">;
+def H1 : Tag<"h1">;
+def H2 : Tag<"h2">;
+def H3 : Tag<"h3">;
+def H4 : Tag<"h4">;
+def H5 : Tag<"h5">;
+def H6 : Tag<"h6">;
+def Code : Tag<"code">;
+def Blockquote : Tag<"blockquote">;
+def Sub : Tag<"sub">;
+def Sup : Tag<"sup">;
+def Img : Tag<"img"> { let EndTagForbidden = 1; }
+def P : Tag<"p"> { let EndTagOptional = 1; }
+def Br : Tag<"br"> { let EndTagForbidden = 1; }
+def Pre : Tag<"pre">;
+def Ins : Tag<"ins">;
+def Del : Tag<"del">;
+def Ul : Tag<"ul">;
+def Ol : Tag<"ol">;
+def Li : Tag<"li"> { let EndTagOptional = 1; }
+def Dl : Tag<"dl">;
+def Dt : Tag<"dt"> { let EndTagOptional = 1; }
+def Dd : Tag<"dd"> { let EndTagOptional = 1; }
+def Table : Tag<"table">;
+def Caption : Tag<"caption">;
+def Thead : Tag<"thead"> { let EndTagOptional = 1; }
+def Tfoot : Tag<"tfoot"> { let EndTagOptional = 1; }
+def Tbody : Tag<"tbody"> { let EndTagOptional = 1; }
+def Colgroup : Tag<"colgroup"> { let EndTagOptional = 1; }
+def Col : Tag<"col"> { let EndTagForbidden = 1; }
+def Tr : Tag<"tr"> { let EndTagOptional = 1; }
+def Th : Tag<"th"> { let EndTagOptional = 1; }
+def Td : Tag<"td"> { let EndTagOptional = 1; }
+
diff --git a/include/clang/AST/CommentLexer.h b/include/clang/AST/CommentLexer.h
index 7a24b1163178..f2636973ff27 100644
--- a/include/clang/AST/CommentLexer.h
+++ b/include/clang/AST/CommentLexer.h
@@ -26,6 +26,7 @@ namespace comments {
class Lexer;
class TextTokenRetokenizer;
+struct CommandInfo;
class CommandTraits;
namespace tok {
@@ -33,7 +34,8 @@ enum TokenKind {
eof,
newline,
text,
- command,
+ unknown_command, // Command that does not have an ID.
+ command, // Command with an ID.
verbatim_block_begin,
verbatim_block_line,
verbatim_block_end,
@@ -49,11 +51,6 @@ enum TokenKind {
};
} // end namespace tok
-class CommentOptions {
-public:
- bool Markdown;
-};
-
/// \brief Comment token.
class Token {
friend class Lexer;
@@ -70,8 +67,14 @@ class Token {
unsigned Length;
/// Contains text value associated with a token.
- const char *TextPtr1;
- unsigned TextLen1;
+ const char *TextPtr;
+
+ /// Integer value associated with a token.
+ ///
+ /// If the token is a konwn command, contains command ID and TextPtr is
+ /// unused (command spelling can be found with CommandTraits). Otherwise,
+ /// contains the length of the string that starts at TextPtr.
+ unsigned IntVal;
public:
SourceLocation getLocation() const LLVM_READONLY { return Loc; }
@@ -94,113 +97,120 @@ public:
StringRef getText() const LLVM_READONLY {
assert(is(tok::text));
- return StringRef(TextPtr1, TextLen1);
+ return StringRef(TextPtr, IntVal);
}
void setText(StringRef Text) {
assert(is(tok::text));
- TextPtr1 = Text.data();
- TextLen1 = Text.size();
+ TextPtr = Text.data();
+ IntVal = Text.size();
+ }
+
+ StringRef getUnknownCommandName() const LLVM_READONLY {
+ assert(is(tok::unknown_command));
+ return StringRef(TextPtr, IntVal);
+ }
+
+ void setUnknownCommandName(StringRef Name) {
+ assert(is(tok::unknown_command));
+ TextPtr = Name.data();
+ IntVal = Name.size();
}
- StringRef getCommandName() const LLVM_READONLY {
+ unsigned getCommandID() const LLVM_READONLY {
assert(is(tok::command));
- return StringRef(TextPtr1, TextLen1);
+ return IntVal;
}
- void setCommandName(StringRef Name) {
+ void setCommandID(unsigned ID) {
assert(is(tok::command));
- TextPtr1 = Name.data();
- TextLen1 = Name.size();
+ IntVal = ID;
}
- StringRef getVerbatimBlockName() const LLVM_READONLY {
+ unsigned getVerbatimBlockID() const LLVM_READONLY {
assert(is(tok::verbatim_block_begin) || is(tok::verbatim_block_end));
- return StringRef(TextPtr1, TextLen1);
+ return IntVal;
}
- void setVerbatimBlockName(StringRef Name) {
+ void setVerbatimBlockID(unsigned ID) {
assert(is(tok::verbatim_block_begin) || is(tok::verbatim_block_end));
- TextPtr1 = Name.data();
- TextLen1 = Name.size();
+ IntVal = ID;
}
StringRef getVerbatimBlockText() const LLVM_READONLY {
assert(is(tok::verbatim_block_line));
- return StringRef(TextPtr1, TextLen1);
+ return StringRef(TextPtr, IntVal);
}
void setVerbatimBlockText(StringRef Text) {
assert(is(tok::verbatim_block_line));
- TextPtr1 = Text.data();
- TextLen1 = Text.size();
+ TextPtr = Text.data();
+ IntVal = Text.size();
}
- /// Returns the name of verbatim line command.
- StringRef getVerbatimLineName() const LLVM_READONLY {
+ unsigned getVerbatimLineID() const LLVM_READONLY {
assert(is(tok::verbatim_line_name));
- return StringRef(TextPtr1, TextLen1);
+ return IntVal;
}
- void setVerbatimLineName(StringRef Name) {
+ void setVerbatimLineID(unsigned ID) {
assert(is(tok::verbatim_line_name));
- TextPtr1 = Name.data();
- TextLen1 = Name.size();
+ IntVal = ID;
}
StringRef getVerbatimLineText() const LLVM_READONLY {
assert(is(tok::verbatim_line_text));
- return StringRef(TextPtr1, TextLen1);
+ return StringRef(TextPtr, IntVal);
}
void setVerbatimLineText(StringRef Text) {
assert(is(tok::verbatim_line_text));
- TextPtr1 = Text.data();
- TextLen1 = Text.size();
+ TextPtr = Text.data();
+ IntVal = Text.size();
}
StringRef getHTMLTagStartName() const LLVM_READONLY {
assert(is(tok::html_start_tag));
- return StringRef(TextPtr1, TextLen1);
+ return StringRef(TextPtr, IntVal);
}
void setHTMLTagStartName(StringRef Name) {
assert(is(tok::html_start_tag));
- TextPtr1 = Name.data();
- TextLen1 = Name.size();
+ TextPtr = Name.data();
+ IntVal = Name.size();
}
StringRef getHTMLIdent() const LLVM_READONLY {
assert(is(tok::html_ident));
- return StringRef(TextPtr1, TextLen1);
+ return StringRef(TextPtr, IntVal);
}
void setHTMLIdent(StringRef Name) {
assert(is(tok::html_ident));
- TextPtr1 = Name.data();
- TextLen1 = Name.size();
+ TextPtr = Name.data();
+ IntVal = Name.size();
}
StringRef getHTMLQuotedString() const LLVM_READONLY {
assert(is(tok::html_quoted_string));
- return StringRef(TextPtr1, TextLen1);
+ return StringRef(TextPtr, IntVal);
}
void setHTMLQuotedString(StringRef Str) {
assert(is(tok::html_quoted_string));
- TextPtr1 = Str.data();
- TextLen1 = Str.size();
+ TextPtr = Str.data();
+ IntVal = Str.size();
}
StringRef getHTMLTagEndName() const LLVM_READONLY {
assert(is(tok::html_end_tag));
- return StringRef(TextPtr1, TextLen1);
+ return StringRef(TextPtr, IntVal);
}
void setHTMLTagEndName(StringRef Name) {
assert(is(tok::html_end_tag));
- TextPtr1 = Name.data();
- TextLen1 = Name.size();
+ TextPtr = Name.data();
+ IntVal = Name.size();
}
void dump(const Lexer &L, const SourceManager &SM) const;
@@ -209,8 +219,8 @@ public:
/// \brief Comment lexer.
class Lexer {
private:
- Lexer(const Lexer&); // DO NOT IMPLEMENT
- void operator=(const Lexer&); // DO NOT IMPLEMENT
+ Lexer(const Lexer &) LLVM_DELETED_FUNCTION;
+ void operator=(const Lexer &) LLVM_DELETED_FUNCTION;
/// Allocator for strings that are semantic values of tokens and have to be
/// computed (for example, resolved decimal character references).
@@ -221,7 +231,6 @@ private:
const char *const BufferStart;
const char *const BufferEnd;
SourceLocation FileLoc;
- CommentOptions CommOpts;
const char *BufferPtr;
@@ -286,8 +295,8 @@ private:
Result.setKind(Kind);
Result.setLength(TokLen);
#ifndef NDEBUG
- Result.TextPtr1 = "<UNSET>";
- Result.TextLen1 = 7;
+ Result.TextPtr = "<UNSET>";
+ Result.IntVal = 7;
#endif
BufferPtr = TokEnd;
}
@@ -314,13 +323,14 @@ private:
void setupAndLexVerbatimBlock(Token &T,
const char *TextBegin,
- char Marker, StringRef EndName);
+ char Marker, const CommandInfo *Info);
void lexVerbatimBlockFirstLine(Token &T);
void lexVerbatimBlockBody(Token &T);
- void setupAndLexVerbatimLine(Token &T, const char *TextBegin);
+ void setupAndLexVerbatimLine(Token &T, const char *TextBegin,
+ const CommandInfo *Info);
void lexVerbatimLineText(Token &T);
@@ -336,7 +346,7 @@ private:
public:
Lexer(llvm::BumpPtrAllocator &Allocator, const CommandTraits &Traits,
- SourceLocation FileLoc, const CommentOptions &CommOpts,
+ SourceLocation FileLoc,
const char *BufferStart, const char *BufferEnd);
void lex(Token &T);
diff --git a/include/clang/AST/CommentParser.h b/include/clang/AST/CommentParser.h
index 039079931c58..19e1d57fc3f5 100644
--- a/include/clang/AST/CommentParser.h
+++ b/include/clang/AST/CommentParser.h
@@ -28,8 +28,8 @@ class CommandTraits;
/// Doxygen comment parser.
class Parser {
- Parser(const Parser&); // DO NOT IMPLEMENT
- void operator=(const Parser&); // DO NOT IMPLEMENT
+ Parser(const Parser &) LLVM_DELETED_FUNCTION;
+ void operator=(const Parser &) LLVM_DELETED_FUNCTION;
friend class TextTokenRetokenizer;
diff --git a/include/clang/AST/CommentSema.h b/include/clang/AST/CommentSema.h
index e1756ca3e2f1..0340b3cfd52d 100644
--- a/include/clang/AST/CommentSema.h
+++ b/include/clang/AST/CommentSema.h
@@ -25,13 +25,14 @@
namespace clang {
class Decl;
class SourceMgr;
+class Preprocessor;
namespace comments {
class CommandTraits;
class Sema {
- Sema(const Sema&); // DO NOT IMPLEMENT
- void operator=(const Sema&); // DO NOT IMPLEMENT
+ Sema(const Sema &) LLVM_DELETED_FUNCTION;
+ void operator=(const Sema &) LLVM_DELETED_FUNCTION;
/// Allocator for AST nodes.
llvm::BumpPtrAllocator &Allocator;
@@ -41,18 +42,13 @@ class Sema {
DiagnosticsEngine &Diags;
- const CommandTraits &Traits;
+ CommandTraits &Traits;
+
+ const Preprocessor *PP;
/// Information about the declaration this comment is attached to.
DeclInfo *ThisDeclInfo;
- /// Comment AST nodes that correspond to \c ParamVars for which we have
- /// found a \\param command or NULL if no documentation was found so far.
- ///
- /// Has correct size and contains valid values if \c DeclInfo->IsFilled is
- /// true.
- llvm::SmallVector<ParamCommandComment *, 8> ParamVarDocs;
-
/// Comment AST nodes that correspond to parameter names in
/// \c TemplateParameters.
///
@@ -75,7 +71,8 @@ class Sema {
public:
Sema(llvm::BumpPtrAllocator &Allocator, const SourceManager &SourceMgr,
- DiagnosticsEngine &Diags, const CommandTraits &Traits);
+ DiagnosticsEngine &Diags, CommandTraits &Traits,
+ const Preprocessor *PP);
void setDecl(const Decl *D);
@@ -96,7 +93,7 @@ public:
BlockCommandComment *actOnBlockCommandStart(SourceLocation LocBegin,
SourceLocation LocEnd,
- StringRef Name);
+ unsigned CommandID);
void actOnBlockCommandArgs(BlockCommandComment *Command,
ArrayRef<BlockCommandComment::Argument> Args);
@@ -106,7 +103,7 @@ public:
ParamCommandComment *actOnParamCommandStart(SourceLocation LocBegin,
SourceLocation LocEnd,
- StringRef Name);
+ unsigned CommandID);
void actOnParamCommandDirectionArg(ParamCommandComment *Command,
SourceLocation ArgLocBegin,
@@ -123,7 +120,7 @@ public:
TParamCommandComment *actOnTParamCommandStart(SourceLocation LocBegin,
SourceLocation LocEnd,
- StringRef Name);
+ unsigned CommandID);
void actOnTParamCommandParamNameArg(TParamCommandComment *Command,
SourceLocation ArgLocBegin,
@@ -135,25 +132,29 @@ public:
InlineCommandComment *actOnInlineCommand(SourceLocation CommandLocBegin,
SourceLocation CommandLocEnd,
- StringRef CommandName);
+ unsigned CommandID);
InlineCommandComment *actOnInlineCommand(SourceLocation CommandLocBegin,
SourceLocation CommandLocEnd,
- StringRef CommandName,
+ unsigned CommandID,
SourceLocation ArgLocBegin,
SourceLocation ArgLocEnd,
StringRef Arg);
InlineContentComment *actOnUnknownCommand(SourceLocation LocBegin,
SourceLocation LocEnd,
- StringRef Name);
+ StringRef CommandName);
+
+ InlineContentComment *actOnUnknownCommand(SourceLocation LocBegin,
+ SourceLocation LocEnd,
+ unsigned CommandID);
TextComment *actOnText(SourceLocation LocBegin,
SourceLocation LocEnd,
StringRef Text);
VerbatimBlockComment *actOnVerbatimBlockStart(SourceLocation Loc,
- StringRef Name);
+ unsigned CommandID);
VerbatimBlockLineComment *actOnVerbatimBlockLine(SourceLocation Loc,
StringRef Text);
@@ -164,7 +165,7 @@ public:
ArrayRef<VerbatimBlockLineComment *> Lines);
VerbatimLineComment *actOnVerbatimLine(SourceLocation LocBegin,
- StringRef Name,
+ unsigned CommandID,
SourceLocation TextBegin,
StringRef Text);
@@ -190,6 +191,12 @@ public:
/// used only once per comment, e.g., \\brief and \\returns.
void checkBlockCommandDuplicate(const BlockCommandComment *Command);
+ void checkDeprecatedCommand(const BlockCommandComment *Comment);
+
+ /// Resolve parameter names to parameter indexes in function declaration.
+ /// Emit diagnostics about unknown parametrs.
+ void resolveParamCommandIndexes(const FullComment *FC);
+
bool isFunctionDecl();
bool isTemplateOrSpecialization();
@@ -218,9 +225,6 @@ public:
InlineCommandComment::RenderKind
getInlineCommandRenderKind(StringRef Name) const;
-
- bool isHTMLEndTagOptional(StringRef Name);
- bool isHTMLEndTagForbidden(StringRef Name);
};
} // end namespace comments
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index e9f25b368aad..087a58587471 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -88,7 +88,6 @@ public:
static TranslationUnitDecl *Create(ASTContext &C);
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const TranslationUnitDecl *D) { return true; }
static bool classofKind(Kind K) { return K == TranslationUnit; }
static DeclContext *castToDeclContext(const TranslationUnitDecl *D) {
return static_cast<DeclContext *>(const_cast<TranslationUnitDecl*>(D));
@@ -214,16 +213,19 @@ public:
bool isCXXInstanceMember() const;
class LinkageInfo {
- Linkage linkage_;
- Visibility visibility_;
- bool explicit_;
+ uint8_t linkage_ : 2;
+ uint8_t visibility_ : 2;
+ uint8_t explicit_ : 1;
void setVisibility(Visibility V, bool E) { visibility_ = V; explicit_ = E; }
public:
LinkageInfo() : linkage_(ExternalLinkage), visibility_(DefaultVisibility),
explicit_(false) {}
LinkageInfo(Linkage L, Visibility V, bool E)
- : linkage_(L), visibility_(V), explicit_(E) {}
+ : linkage_(L), visibility_(V), explicit_(E) {
+ assert(linkage() == L && visibility() == V && visibilityExplicit() == E &&
+ "Enum truncated!");
+ }
static LinkageInfo external() {
return LinkageInfo();
@@ -238,8 +240,8 @@ public:
return LinkageInfo(NoLinkage, DefaultVisibility, false);
}
- Linkage linkage() const { return linkage_; }
- Visibility visibility() const { return visibility_; }
+ Linkage linkage() const { return (Linkage)linkage_; }
+ Visibility visibility() const { return (Visibility)visibility_; }
bool visibilityExplicit() const { return explicit_; }
void setLinkage(Linkage L) { linkage_ = L; }
@@ -337,7 +339,6 @@ public:
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const NamedDecl *D) { return true; }
static bool classofKind(Kind K) { return K >= firstNamed && K <= lastNamed; }
};
@@ -383,7 +384,6 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const LabelDecl *D) { return true; }
static bool classofKind(Kind K) { return K == Label; }
};
@@ -509,7 +509,6 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const NamespaceDecl *D) { return true; }
static bool classofKind(Kind K) { return K == Namespace; }
static DeclContext *castToDeclContext(const NamespaceDecl *D) {
return static_cast<DeclContext *>(const_cast<NamespaceDecl*>(D));
@@ -545,7 +544,6 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const ValueDecl *D) { return true; }
static bool classofKind(Kind K) { return K >= firstValue && K <= lastValue; }
};
@@ -578,8 +576,8 @@ struct QualifierInfo {
private:
// Copy constructor and copy assignment are disabled.
- QualifierInfo(const QualifierInfo&);
- QualifierInfo& operator=(const QualifierInfo&);
+ QualifierInfo(const QualifierInfo&) LLVM_DELETED_FUNCTION;
+ QualifierInfo& operator=(const QualifierInfo&) LLVM_DELETED_FUNCTION;
};
/// \brief Represents a ValueDecl that came out of a declarator.
@@ -666,7 +664,6 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const DeclaratorDecl *D) { return true; }
static bool classofKind(Kind K) {
return K >= firstDeclarator && K <= lastDeclarator;
}
@@ -712,7 +709,7 @@ public:
typedef clang::StorageClass StorageClass;
/// getStorageClassSpecifierString - Return the string used to
- /// specify the storage class \arg SC.
+ /// specify the storage class \p SC.
///
/// It is illegal to call this function with SC == None.
static const char *getStorageClassSpecifierString(StorageClass SC);
@@ -1208,7 +1205,6 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const VarDecl *D) { return true; }
static bool classofKind(Kind K) { return K >= firstVar && K <= lastVar; }
};
@@ -1229,7 +1225,6 @@ public:
}
// Implement isa/cast/dyncast/etc.
- static bool classof(const ImplicitParamDecl *D) { return true; }
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == ImplicitParam; }
};
@@ -1399,7 +1394,6 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const ParmVarDecl *D) { return true; }
static bool classofKind(Kind K) { return K == ParmVar; }
private:
@@ -2070,7 +2064,6 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const FunctionDecl *D) { return true; }
static bool classofKind(Kind K) {
return K >= firstFunction && K <= lastFunction;
}
@@ -2204,7 +2197,6 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const FieldDecl *D) { return true; }
static bool classofKind(Kind K) { return K >= firstField && K <= lastField; }
friend class ASTDeclReader;
@@ -2243,7 +2235,6 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const EnumConstantDecl *D) { return true; }
static bool classofKind(Kind K) { return K == EnumConstant; }
friend class StmtIteratorBase;
@@ -2287,7 +2278,6 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const IndirectFieldDecl *D) { return true; }
static bool classofKind(Kind K) { return K == IndirectField; }
friend class ASTDeclReader;
};
@@ -2334,7 +2324,6 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const TypeDecl *D) { return true; }
static bool classofKind(Kind K) { return K >= firstType && K <= lastType; }
};
@@ -2390,7 +2379,6 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const TypedefNameDecl *D) { return true; }
static bool classofKind(Kind K) {
return K >= firstTypedefName && K <= lastTypedefName;
}
@@ -2413,7 +2401,6 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const TypedefDecl *D) { return true; }
static bool classofKind(Kind K) { return K == Typedef; }
};
@@ -2434,7 +2421,6 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const TypeAliasDecl *D) { return true; }
static bool classofKind(Kind K) { return K == TypeAlias; }
};
@@ -2448,7 +2434,7 @@ public:
private:
// FIXME: This can be packed into the bitfields in Decl.
/// TagDeclKind - The TagKind enum.
- unsigned TagDeclKind : 2;
+ unsigned TagDeclKind : 3;
/// IsCompleteDefinition - True if this is a definition ("struct foo
/// {};"), false if it is a declaration ("struct foo;"). It is not
@@ -2625,6 +2611,7 @@ public:
void setTagKind(TagKind TK) { TagDeclKind = TK; }
bool isStruct() const { return getTagKind() == TTK_Struct; }
+ bool isInterface() const { return getTagKind() == TTK_Interface; }
bool isClass() const { return getTagKind() == TTK_Class; }
bool isUnion() const { return getTagKind() == TTK_Union; }
bool isEnum() const { return getTagKind() == TTK_Enum; }
@@ -2665,7 +2652,6 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const TagDecl *D) { return true; }
static bool classofKind(Kind K) { return K >= firstTag && K <= lastTag; }
static DeclContext *castToDeclContext(const TagDecl *D) {
@@ -2895,7 +2881,6 @@ public:
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const EnumDecl *D) { return true; }
static bool classofKind(Kind K) { return K == Enum; }
friend class ASTDeclReader;
@@ -3026,11 +3011,15 @@ public:
virtual void completeDefinition();
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const RecordDecl *D) { return true; }
static bool classofKind(Kind K) {
return K >= firstRecord && K <= lastRecord;
}
+ /// isMsStrust - 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;
+
private:
/// \brief Deserialize just the fields.
void LoadFieldsFromExternalStorage() const;
@@ -3062,7 +3051,6 @@ public:
void setAsmString(StringLiteral *Asm) { AsmString = Asm; }
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const FileScopeAsmDecl *D) { return true; }
static bool classofKind(Kind K) { return K == FileScopeAsm; }
};
@@ -3208,7 +3196,6 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const BlockDecl *D) { return true; }
static bool classofKind(Kind K) { return K == Block; }
static DeclContext *castToDeclContext(const BlockDecl *D) {
return static_cast<DeclContext *>(const_cast<BlockDecl*>(D));
@@ -3282,7 +3269,6 @@ public:
virtual SourceRange getSourceRange() const LLVM_READONLY;
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const ImportDecl *D) { return true; }
static bool classofKind(Kind K) { return K == Import; }
};
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index 0f596095f74a..50e202738dd4 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -430,16 +430,10 @@ public:
void dropAttr() {
if (!HasAttrs) return;
- AttrVec &Attrs = getAttrs();
- for (unsigned i = 0, e = Attrs.size(); i != e; /* in loop */) {
- if (isa<T>(Attrs[i])) {
- Attrs.erase(Attrs.begin() + i);
- --e;
- }
- else
- ++i;
- }
- if (Attrs.empty())
+ AttrVec &Vec = getAttrs();
+ Vec.erase(std::remove_if(Vec.begin(), Vec.end(), isa<T, Attr*>), Vec.end());
+
+ if (Vec.empty())
HasAttrs = false;
}
@@ -844,8 +838,6 @@ public:
IdentifierNamespace |= IDNS_NonMemberOperator;
}
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *) { return true; }
static bool classofKind(Kind K) { return true; }
static DeclContext *castToDeclContext(const Decl *);
static Decl *castFromDeclContext(const DeclContext *);
@@ -1479,6 +1471,13 @@ public:
inline ddiag_iterator ddiag_end() const;
// Low-level accessors
+
+ /// \brief Mark the lookup table as needing to be built. This should be
+ /// used only if setHasExternalLexicalStorage() has been called.
+ void setMustBuildLookupTable() {
+ assert(ExternalLexicalStorage && "Requires external lexical storage");
+ LookupPtr.setInt(true);
+ }
/// \brief Retrieve the internal representation of the lookup structure.
/// This may omit some names if we are lazily building the structure.
@@ -1516,10 +1515,6 @@ public:
static bool classof(const Decl *D);
static bool classof(const DeclContext *D) { return true; }
-#define DECL(NAME, BASE)
-#define DECL_CONTEXT(NAME) \
- static bool classof(const NAME##Decl *D) { return true; }
-#include "clang/AST/DeclNodes.inc"
LLVM_ATTRIBUTE_USED void dumpDeclContext() const;
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 2d95f038dfd4..9cb56e2b3ccc 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -145,7 +145,6 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const AccessSpecDecl *D) { return true; }
static bool classofKind(Kind K) { return K == AccessSpec; }
};
@@ -563,9 +562,10 @@ class CXXRecordDecl : public RecordDecl {
struct LambdaDefinitionData : public DefinitionData {
typedef LambdaExpr::Capture Capture;
- LambdaDefinitionData(CXXRecordDecl *D, bool Dependent)
+ LambdaDefinitionData(CXXRecordDecl *D, TypeSourceInfo *Info, bool Dependent)
: DefinitionData(D), Dependent(Dependent), NumCaptures(0),
- NumExplicitCaptures(0), ManglingNumber(0), ContextDecl(0), Captures(0)
+ NumExplicitCaptures(0), ManglingNumber(0), ContextDecl(0), Captures(0),
+ MethodTyInfo(Info)
{
IsLambda = true;
}
@@ -598,7 +598,10 @@ class CXXRecordDecl : public RecordDecl {
/// \brief The list of captures, both explicit and implicit, for this
/// lambda.
- Capture *Captures;
+ Capture *Captures;
+
+ /// \brief The type of the call method.
+ TypeSourceInfo *MethodTyInfo;
};
struct DefinitionData &data() {
@@ -705,7 +708,8 @@ public:
IdentifierInfo *Id, CXXRecordDecl* PrevDecl=0,
bool DelayTypeCreation = false);
static CXXRecordDecl *CreateLambda(const ASTContext &C, DeclContext *DC,
- SourceLocation Loc, bool DependentLambda);
+ TypeSourceInfo *Info, SourceLocation Loc,
+ bool DependentLambda);
static CXXRecordDecl *CreateDeserialized(const ASTContext &C, unsigned ID);
bool isDynamicClass() const {
@@ -1303,7 +1307,7 @@ public:
/// \brief Function type used by forallBases() as a callback.
///
- /// \param Base the definition of the base class
+ /// \param BaseDefinition the definition of the base class
///
/// \returns true if this base matched the search criteria
typedef bool ForallBasesCallback(const CXXRecordDecl *BaseDefinition,
@@ -1500,15 +1504,15 @@ public:
bool isDependentLambda() const {
return isLambda() && getLambdaData().Dependent;
}
-
+
+ TypeSourceInfo *getLambdaTypeInfo() const {
+ return getLambdaData().MethodTyInfo;
+ }
+
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) {
return K >= firstCXXRecord && K <= lastCXXRecord;
}
- static bool classof(const CXXRecordDecl *D) { return true; }
- static bool classof(const ClassTemplateSpecializationDecl *D) {
- return true;
- }
friend class ASTDeclReader;
friend class ASTDeclWriter;
@@ -1549,14 +1553,16 @@ public:
bool isStatic() const { return getStorageClass() == SC_Static; }
bool isInstance() const { return !isStatic(); }
- bool isConst() { return getType()->castAs<FunctionType>()->isConst(); }
- bool isVolatile() { return getType()->castAs<FunctionType>()->isVolatile(); }
+ bool isConst() const { return getType()->castAs<FunctionType>()->isConst(); }
+ bool isVolatile() const { return getType()->castAs<FunctionType>()->isVolatile(); }
bool isVirtual() const {
CXXMethodDecl *CD =
cast<CXXMethodDecl>(const_cast<CXXMethodDecl*>(this)->getCanonicalDecl());
- if (CD->isVirtualAsWritten())
+ // Methods declared in interfaces are automatically (pure) virtual.
+ if (CD->isVirtualAsWritten() ||
+ (CD->getParent()->isInterface() && CD->isUserProvided()))
return true;
return (CD->begin_overridden_methods() != CD->end_overridden_methods());
@@ -1661,7 +1667,6 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const CXXMethodDecl *D) { return true; }
static bool classofKind(Kind K) {
return K >= firstCXXMethod && K <= lastCXXMethod;
}
@@ -2141,7 +2146,6 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const CXXConstructorDecl *D) { return true; }
static bool classofKind(Kind K) { return K == CXXConstructor; }
friend class ASTDeclReader;
@@ -2213,7 +2217,6 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const CXXDestructorDecl *D) { return true; }
static bool classofKind(Kind K) { return K == CXXDestructor; }
friend class ASTDeclReader;
@@ -2280,7 +2283,6 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const CXXConversionDecl *D) { return true; }
static bool classofKind(Kind K) { return K == CXXConversion; }
friend class ASTDeclReader;
@@ -2350,7 +2352,6 @@ public:
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const LinkageSpecDecl *D) { return true; }
static bool classofKind(Kind K) { return K == LinkageSpec; }
static DeclContext *castToDeclContext(const LinkageSpecDecl *D) {
return static_cast<DeclContext *>(const_cast<LinkageSpecDecl*>(D));
@@ -2454,7 +2455,6 @@ public:
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const UsingDirectiveDecl *D) { return true; }
static bool classofKind(Kind K) { return K == UsingDirective; }
// Friend for getUsingDirectiveName.
@@ -2548,7 +2548,6 @@ public:
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const NamespaceAliasDecl *D) { return true; }
static bool classofKind(Kind K) { return K == NamespaceAlias; }
};
@@ -2619,7 +2618,6 @@ public:
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const UsingShadowDecl *D) { return true; }
static bool classofKind(Kind K) { return K == Decl::UsingShadow; }
friend class ASTDeclReader;
@@ -2751,7 +2749,6 @@ public:
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const UsingDecl *D) { return true; }
static bool classofKind(Kind K) { return K == Using; }
friend class ASTDeclReader;
@@ -2825,7 +2822,6 @@ public:
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const UnresolvedUsingValueDecl *D) { return true; }
static bool classofKind(Kind K) { return K == UnresolvedUsingValue; }
friend class ASTDeclReader;
@@ -2891,7 +2887,6 @@ public:
CreateDeserialized(ASTContext &C, unsigned ID);
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const UnresolvedUsingTypenameDecl *D) { return true; }
static bool classofKind(Kind K) { return K == UnresolvedUsingTypename; }
};
@@ -2931,7 +2926,6 @@ public:
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(StaticAssertDecl *D) { return true; }
static bool classofKind(Kind K) { return K == StaticAssert; }
friend class ASTDeclReader;
diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h
index 9a64f08dee50..37e45868b57c 100644
--- a/include/clang/AST/DeclFriend.h
+++ b/include/clang/AST/DeclFriend.h
@@ -16,6 +16,7 @@
#define LLVM_CLANG_AST_DECLFRIEND_H
#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclTemplate.h"
#include "llvm/Support/Compiler.h"
namespace clang {
@@ -104,9 +105,15 @@ public:
/// Retrieves the source range for the friend declaration.
SourceRange getSourceRange() const LLVM_READONLY {
- /* FIXME: consider the case of templates wrt start of range. */
- if (NamedDecl *ND = getFriendDecl())
+ if (NamedDecl *ND = getFriendDecl()) {
+ if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(ND))
+ return FTD->getSourceRange();
+ if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(ND)) {
+ if (DD->getOuterLocStart() != DD->getInnerLocStart())
+ return DD->getSourceRange();
+ }
return SourceRange(getFriendLoc(), ND->getLocEnd());
+ }
else if (TypeSourceInfo *TInfo = getFriendType())
return SourceRange(getFriendLoc(), TInfo->getTypeLoc().getEndLoc());
else
@@ -123,7 +130,6 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const FriendDecl *D) { return true; }
static bool classofKind(Kind K) { return K == Decl::Friend; }
friend class ASTDeclReader;
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index 6c39f2c3abe1..8b27dd8e9e16 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -33,8 +33,8 @@ class ObjCPropertyImplDecl;
class CXXCtorInitializer;
class ObjCListBase {
- void operator=(const ObjCListBase &); // DO NOT IMPLEMENT
- ObjCListBase(const ObjCListBase&); // DO NOT IMPLEMENT
+ ObjCListBase(const ObjCListBase &) LLVM_DELETED_FUNCTION;
+ void operator=(const ObjCListBase &) LLVM_DELETED_FUNCTION;
protected:
/// List is an array of pointers to objects that are not owned by this object.
void **List;
@@ -123,8 +123,8 @@ private:
unsigned IsInstance : 1;
unsigned IsVariadic : 1;
- // Synthesized declaration method for a property setter/getter
- unsigned IsSynthesized : 1;
+ /// True if this method is the getter or setter for an explicit property.
+ unsigned IsPropertyAccessor : 1;
// Method has a definition.
unsigned IsDefined : 1;
@@ -174,8 +174,7 @@ private:
SourceLocation DeclEndLoc; // the location of the ';' or '{'.
// The following are only used for method definitions, null otherwise.
- // FIXME: space savings opportunity, consider a sub-class.
- Stmt *Body;
+ LazyDeclStmtPtr Body;
/// SelfDecl - Decl for the implicit self parameter. This is lazily
/// constructed by createImplicitParams.
@@ -227,7 +226,7 @@ private:
DeclContext *contextDecl,
bool isInstance = true,
bool isVariadic = false,
- bool isSynthesized = false,
+ bool isPropertyAccessor = false,
bool isImplicitlyDeclared = false,
bool isDefined = false,
ImplementationControl impControl = None,
@@ -235,14 +234,14 @@ private:
: NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo),
DeclContext(ObjCMethod), Family(InvalidObjCMethodFamily),
IsInstance(isInstance), IsVariadic(isVariadic),
- IsSynthesized(isSynthesized),
+ IsPropertyAccessor(isPropertyAccessor),
IsDefined(isDefined), IsRedeclaration(0), HasRedeclaration(0),
DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None),
RelatedResultType(HasRelatedResultType),
SelLocsKind(SelLoc_StandardNoSpace), IsOverriding(0),
MethodDeclType(T), ResultTInfo(ResultTInfo),
ParamsAndSelLocs(0), NumParams(0),
- DeclEndLoc(endLoc), Body(0), SelfDecl(0), CmdDecl(0) {
+ DeclEndLoc(endLoc), Body(), SelfDecl(0), CmdDecl(0) {
setImplicit(isImplicitlyDeclared);
}
@@ -261,7 +260,7 @@ public:
DeclContext *contextDecl,
bool isInstance = true,
bool isVariadic = false,
- bool isSynthesized = false,
+ bool isPropertyAccessor = false,
bool isImplicitlyDeclared = false,
bool isDefined = false,
ImplementationControl impControl = None,
@@ -363,7 +362,7 @@ public:
}
/// \brief Sets the method's parameters and selector source locations.
- /// If the method is implicit (not coming from source) \arg SelLocs is
+ /// If the method is implicit (not coming from source) \p SelLocs is
/// ignored.
void setMethodParams(ASTContext &C,
ArrayRef<ParmVarDecl*> Params,
@@ -403,8 +402,8 @@ public:
bool isClassMethod() const { return !IsInstance; }
- bool isSynthesized() const { return IsSynthesized; }
- void setSynthesized(bool isSynth) { IsSynthesized = isSynth; }
+ bool isPropertyAccessor() const { return IsPropertyAccessor; }
+ void setPropertyAccessor(bool isAccessor) { IsPropertyAccessor = isAccessor; }
bool isDefined() const { return IsDefined; }
void setDefined(bool isDefined) { IsDefined = isDefined; }
@@ -418,7 +417,25 @@ public:
/// method in the interface or its categories.
bool isOverriding() const { return IsOverriding; }
void setOverriding(bool isOverriding) { IsOverriding = isOverriding; }
-
+
+ /// \brief Return overridden methods for the given \p Method.
+ ///
+ /// An ObjC method is considered to override any method in the class's
+ /// base classes (and base's categories), its protocols, or its categories'
+ /// protocols, that has
+ /// the same selector and is of the same kind (class or instance).
+ /// A method in an implementation is not considered as overriding the same
+ /// method in the interface or its categories.
+ void getOverriddenMethods(
+ SmallVectorImpl<const ObjCMethodDecl *> &Overridden) const;
+
+ /// \brief Returns the property associated with this method's selector.
+ ///
+ /// Note that even if this particular method is not marked as a property
+ /// accessor, it is still possible for it to match a property declared in a
+ /// superclass. Pass \c false if you only want to check the current class.
+ const ObjCPropertyDecl *findPropertyDecl(bool CheckOverrides = true) const;
+
// Related to protocols declared in \@protocol
void setDeclImplementation(ImplementationControl ic) {
DeclImplementation = ic;
@@ -427,10 +444,15 @@ public:
return ImplementationControl(DeclImplementation);
}
- virtual Stmt *getBody() const {
- return (Stmt*) Body;
- }
- CompoundStmt *getCompoundBody() { return (CompoundStmt*)Body; }
+ /// \brief Determine whether this method has a body.
+ virtual bool hasBody() const { return Body; }
+
+ /// \brief Retrieve the body of this method, if it has one.
+ virtual Stmt *getBody() const;
+
+ void setLazyBody(uint64_t Offset) { Body = Offset; }
+
+ CompoundStmt *getCompoundBody() { return (CompoundStmt*)getBody(); }
void setBody(Stmt *B) { Body = B; }
/// \brief Returns whether this specific method is a definition.
@@ -438,7 +460,6 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const ObjCMethodDecl *D) { return true; }
static bool classofKind(Kind K) { return K == ObjCMethod; }
static DeclContext *castToDeclContext(const ObjCMethodDecl *D) {
return static_cast<DeclContext *>(const_cast<ObjCMethodDecl*>(D));
@@ -520,6 +541,13 @@ public:
ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const;
+ typedef llvm::DenseMap<IdentifierInfo*, ObjCPropertyDecl*> PropertyMap;
+
+ /// This routine collects list of properties to be implemented in the class.
+ /// This includes, class's and its conforming protocols' properties.
+ /// Note, the superclass's properties are not included in the list.
+ virtual void collectPropertiesToImplement(PropertyMap &PM) const {}
+
SourceLocation getAtStartLoc() const { return AtStart; }
void setAtStartLoc(SourceLocation Loc) { AtStart = Loc; }
@@ -537,7 +565,6 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const ObjCContainerDecl *D) { return true; }
static bool classofKind(Kind K) {
return K >= firstObjCContainer &&
K <= lastObjCContainer;
@@ -880,6 +907,8 @@ public:
ObjCPropertyDecl
*FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId) const;
+ virtual void collectPropertiesToImplement(PropertyMap &PM) const;
+
/// isSuperClassOf - Return true if this class is the specified class or is a
/// super class of the specified interface class.
bool isSuperClassOf(const ObjCInterfaceDecl *I) const {
@@ -992,7 +1021,6 @@ public:
void setTypeForDecl(const Type *TD) const { TypeForDecl = TD; }
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const ObjCInterfaceDecl *D) { return true; }
static bool classofKind(Kind K) { return K == ObjCInterface; }
friend class ASTReader;
@@ -1065,7 +1093,6 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const ObjCIvarDecl *D) { return true; }
static bool classofKind(Kind K) { return K == ObjCIvar; }
private:
/// NextIvar - Next Ivar in the list of ivars declared in class; class's
@@ -1098,7 +1125,6 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const ObjCAtDefsFieldDecl *D) { return true; }
static bool classofKind(Kind K) { return K == ObjCAtDefsField; }
};
@@ -1277,8 +1303,9 @@ public:
return getFirstDeclaration();
}
+ virtual void collectPropertiesToImplement(PropertyMap &PM) const;
+
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const ObjCProtocolDecl *D) { return true; }
static bool classofKind(Kind K) { return K == ObjCProtocol; }
friend class ASTReader;
@@ -1402,7 +1429,6 @@ public:
SourceLocation getIvarRBraceLoc() const { return IvarRBraceLoc; }
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const ObjCCategoryDecl *D) { return true; }
static bool classofKind(Kind K) { return K == ObjCCategory; }
friend class ASTDeclReader;
@@ -1455,7 +1481,6 @@ public:
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const ObjCImplDecl *D) { return true; }
static bool classofKind(Kind K) {
return K >= firstObjCImpl && K <= lastObjCImpl;
}
@@ -1532,7 +1557,6 @@ public:
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const ObjCCategoryImplDecl *D) { return true; }
static bool classofKind(Kind K) { return K == ObjCCategoryImpl;}
friend class ASTDeclReader;
@@ -1568,8 +1592,12 @@ class ObjCImplementationDecl : public ObjCImplDecl {
CXXCtorInitializer **IvarInitializers;
unsigned NumIvarInitializers;
- /// true if class has a .cxx_[construct,destruct] method.
- bool HasCXXStructors : 1;
+ /// Do the ivars of this class require initialization other than
+ /// zero-initialization?
+ bool HasNonZeroConstructors : 1;
+
+ /// Do the ivars of this class require non-trivial destruction?
+ bool HasDestructors : 1;
ObjCImplementationDecl(DeclContext *DC,
ObjCInterfaceDecl *classInterface,
@@ -1581,7 +1609,7 @@ class ObjCImplementationDecl : public ObjCImplDecl {
SuperClass(superDecl), IvarLBraceLoc(IvarLBraceLoc),
IvarRBraceLoc(IvarRBraceLoc),
IvarInitializers(0), NumIvarInitializers(0),
- HasCXXStructors(false) {}
+ HasNonZeroConstructors(false), HasDestructors(false) {}
public:
static ObjCImplementationDecl *Create(ASTContext &C, DeclContext *DC,
ObjCInterfaceDecl *classInterface,
@@ -1625,8 +1653,15 @@ public:
CXXCtorInitializer ** initializers,
unsigned numInitializers);
- bool hasCXXStructors() const { return HasCXXStructors; }
- void setHasCXXStructors(bool val) { HasCXXStructors = val; }
+ /// Do any of the ivars of this class (not counting its base classes)
+ /// require construction other than zero-initialization?
+ bool hasNonZeroConstructors() const { return HasNonZeroConstructors; }
+ void setHasNonZeroConstructors(bool val) { HasNonZeroConstructors = val; }
+
+ /// Do any of the ivars of this class (not counting its base classes)
+ /// require non-trivial destruction?
+ bool hasDestructors() const { return HasDestructors; }
+ void setHasDestructors(bool val) { HasDestructors = val; }
/// getIdentifier - Get the identifier that names the class
/// interface associated with this implementation.
@@ -1676,7 +1711,6 @@ public:
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const ObjCImplementationDecl *D) { return true; }
static bool classofKind(Kind K) { return K == ObjCImplementation; }
friend class ASTDeclReader;
@@ -1708,7 +1742,6 @@ public:
void setClassInterface(ObjCInterfaceDecl *D) { AliasedClass = D; }
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const ObjCCompatibleAliasDecl *D) { return true; }
static bool classofKind(Kind K) { return K == ObjCCompatibleAlias; }
};
@@ -1882,13 +1915,15 @@ public:
virtual SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(AtLoc, getLocation());
}
+
+ /// Get the default name of the synthesized ivar.
+ IdentifierInfo *getDefaultSynthIvarName(ASTContext &Ctx) const;
/// Lookup a property by name in the specified DeclContext.
static ObjCPropertyDecl *findPropertyDecl(const DeclContext *DC,
IdentifierInfo *propertyID);
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const ObjCPropertyDecl *D) { return true; }
static bool classofKind(Kind K) { return K == ObjCProperty; }
};
@@ -1999,7 +2034,6 @@ public:
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const ObjCPropertyImplDecl *D) { return true; }
static bool classofKind(Decl::Kind K) { return K == ObjCPropertyImpl; }
friend class ASTDeclReader;
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index 7affc7e15f27..862011666205 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -50,7 +50,11 @@ class TemplateParameterList {
/// The number of template parameters in this template
/// parameter list.
- unsigned NumParams;
+ unsigned NumParams : 31;
+
+ /// Whether this template parameter list contains an unexpanded parameter
+ /// pack.
+ unsigned ContainsUnexpandedParameterPack : 1;
protected:
TemplateParameterList(SourceLocation TemplateLoc, SourceLocation LAngleLoc,
@@ -104,6 +108,12 @@ public:
/// the second template parameter list will have depth 1, etc.
unsigned getDepth() const;
+ /// \brief Determine whether this template parameter list contains an
+ /// unexpanded parameter pack.
+ bool containsUnexpandedParameterPack() const {
+ return ContainsUnexpandedParameterPack;
+ }
+
SourceLocation getTemplateLoc() const { return TemplateLoc; }
SourceLocation getLAngleLoc() const { return LAngleLoc; }
SourceLocation getRAngleLoc() const { return RAngleLoc; }
@@ -139,8 +149,8 @@ class TemplateArgumentList {
/// argument list.
unsigned NumArguments;
- TemplateArgumentList(const TemplateArgumentList &Other); // DO NOT IMPL
- void operator=(const TemplateArgumentList &Other); // DO NOT IMPL
+ TemplateArgumentList(const TemplateArgumentList &Other) LLVM_DELETED_FUNCTION;
+ void operator=(const TemplateArgumentList &Other) LLVM_DELETED_FUNCTION;
TemplateArgumentList(const TemplateArgument *Args, unsigned NumArgs,
bool Owned)
@@ -233,12 +243,6 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const TemplateDecl *D) { return true; }
- static bool classof(const RedeclarableTemplateDecl *D) { return true; }
- static bool classof(const FunctionTemplateDecl *D) { return true; }
- static bool classof(const ClassTemplateDecl *D) { return true; }
- static bool classof(const TemplateTemplateParmDecl *D) { return true; }
- static bool classof(const TypeAliasTemplateDecl *D) { return true; }
static bool classofKind(Kind K) {
return K >= firstTemplate && K <= lastTemplate;
}
@@ -678,10 +682,6 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const RedeclarableTemplateDecl *D) { return true; }
- static bool classof(const FunctionTemplateDecl *D) { return true; }
- static bool classof(const ClassTemplateDecl *D) { return true; }
- static bool classof(const TypeAliasTemplateDecl *D) { return true; }
static bool classofKind(Kind K) {
return K >= firstRedeclarableTemplate && K <= lastRedeclarableTemplate;
}
@@ -827,7 +827,6 @@ public:
// Implement isa/cast/dyncast support
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const FunctionTemplateDecl *D) { return true; }
static bool classofKind(Kind K) { return K == FunctionTemplate; }
friend class ASTDeclReader;
@@ -969,7 +968,6 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const TemplateTypeParmDecl *D) { return true; }
static bool classofKind(Kind K) { return K == TemplateTypeParm; }
};
@@ -1090,8 +1088,17 @@ public:
/// \endcode
bool isParameterPack() const { return ParameterPack; }
+ /// \brief Whether this parameter pack is a pack expansion.
+ ///
+ /// A non-type template parameter pack is a pack expansion if its type
+ /// contains an unexpanded parameter pack. In this case, we will have
+ /// built a PackExpansionType wrapping the type.
+ bool isPackExpansion() const {
+ return ParameterPack && getType()->getAs<PackExpansionType>();
+ }
+
/// \brief Whether this parameter is a non-type template parameter pack
- /// that has different types at different positions.
+ /// that has a known list of different types at different positions.
///
/// A parameter pack is an expanded parameter pack when the original
/// parameter pack's type was itself a pack expansion, and that expansion
@@ -1141,7 +1148,6 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const NonTypeTemplateParmDecl *D) { return true; }
static bool classofKind(Kind K) { return K == NonTypeTemplateParm; }
};
@@ -1165,23 +1171,47 @@ class TemplateTemplateParmDecl : public TemplateDecl,
/// \brief Whether this parameter is a parameter pack.
bool ParameterPack;
+ /// \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;
+
+ /// \brief The number of parameters in an expanded parameter pack.
+ unsigned NumExpandedParams;
+
TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
unsigned D, unsigned P, bool ParameterPack,
IdentifierInfo *Id, TemplateParameterList *Params)
: TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
TemplateParmPosition(D, P), DefaultArgument(),
- DefaultArgumentWasInherited(false), ParameterPack(ParameterPack)
+ DefaultArgumentWasInherited(false), ParameterPack(ParameterPack),
+ ExpandedParameterPack(false), NumExpandedParams(0)
{ }
+ TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
+ unsigned D, unsigned P,
+ IdentifierInfo *Id, TemplateParameterList *Params,
+ unsigned NumExpansions,
+ TemplateParameterList * const *Expansions);
+
public:
static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC,
SourceLocation L, unsigned D,
unsigned P, bool ParameterPack,
IdentifierInfo *Id,
TemplateParameterList *Params);
+ static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC,
+ SourceLocation L, unsigned D,
+ unsigned P,
+ IdentifierInfo *Id,
+ TemplateParameterList *Params,
+ llvm::ArrayRef<TemplateParameterList*> Expansions);
- static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C,
+ static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C,
unsigned ID);
+ static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C,
+ unsigned ID,
+ unsigned NumExpansions);
using TemplateParmPosition::getDepth;
using TemplateParmPosition::getPosition;
@@ -1195,6 +1225,49 @@ public:
/// \endcode
bool isParameterPack() const { return ParameterPack; }
+ /// \brief Whether this parameter pack is a pack expansion.
+ ///
+ /// A template template parameter pack is a pack expansion if its template
+ /// parameter list contains an unexpanded parameter pack.
+ bool isPackExpansion() const {
+ return ParameterPack &&
+ getTemplateParameters()->containsUnexpandedParameterPack();
+ }
+
+ /// \brief Whether this parameter is a template template parameter pack that
+ /// has a known list of different template parameter lists at different
+ /// positions.
+ ///
+ /// A parameter pack is an expanded parameter pack when the original parameter
+ /// pack's template parameter list was itself a pack expansion, and that
+ /// expansion has already been expanded. For exampe, given:
+ ///
+ /// \code
+ /// template<typename...Types> struct Outer {
+ /// template<template<Types> class...Templates> struct Inner;
+ /// };
+ /// \endcode
+ ///
+ /// The parameter pack \c Templates is a pack expansion, which expands the
+ /// pack \c Types. When \c Types is supplied with template arguments by
+ /// instantiating \c Outer, the instantiation of \c Templates is an expanded
+ /// parameter pack.
+ bool isExpandedParameterPack() const { return ExpandedParameterPack; }
+
+ /// \brief Retrieves the number of expansion template parameters in
+ /// an expanded parameter pack.
+ unsigned getNumExpansionTemplateParameters() const {
+ assert(ExpandedParameterPack && "Not an expansion parameter pack");
+ return NumExpandedParams;
+ }
+
+ /// \brief Retrieve a particular expansion type within an expanded parameter
+ /// pack.
+ TemplateParameterList *getExpansionTemplateParameters(unsigned I) const {
+ assert(I < NumExpandedParams && "Out-of-range expansion type index");
+ return reinterpret_cast<TemplateParameterList *const *>(this + 1)[I];
+ }
+
/// \brief Determine whether this template parameter has a default
/// argument.
bool hasDefaultArgument() const {
@@ -1238,7 +1311,6 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const TemplateTemplateParmDecl *D) { return true; }
static bool classofKind(Kind K) { return K == TemplateTemplateParm; }
friend class ASTDeclReader;
@@ -1505,14 +1577,6 @@ public:
K <= lastClassTemplateSpecialization;
}
- static bool classof(const ClassTemplateSpecializationDecl *) {
- return true;
- }
-
- static bool classof(const ClassTemplatePartialSpecializationDecl *) {
- return true;
- }
-
friend class ASTDeclReader;
friend class ASTDeclWriter;
};
@@ -1681,10 +1745,6 @@ public:
return K == ClassTemplatePartialSpecialization;
}
- static bool classof(const ClassTemplatePartialSpecializationDecl *) {
- return true;
- }
-
friend class ASTDeclReader;
friend class ASTDeclWriter;
};
@@ -1886,7 +1946,6 @@ public:
// Implement isa/cast/dyncast support
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const ClassTemplateDecl *D) { return true; }
static bool classofKind(Kind K) { return K == ClassTemplate; }
friend class ASTDeclReader;
@@ -1984,7 +2043,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; }
- static bool classof(const FriendTemplateDecl *D) { return true; }
friend class ASTDeclReader;
};
@@ -2059,7 +2117,6 @@ public:
// Implement isa/cast/dyncast support
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classof(const TypeAliasTemplateDecl *D) { return true; }
static bool classofKind(Kind K) { return K == TypeAliasTemplate; }
friend class ASTDeclReader;
@@ -2123,9 +2180,6 @@ public:
static bool classofKind(Kind K) {
return K == Decl::ClassScopeFunctionSpecialization;
}
- static bool classof(const ClassScopeFunctionSpecializationDecl *D) {
- return true;
- }
friend class ASTDeclReader;
friend class ASTDeclWriter;
diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h
index 614652540679..d991c73612c2 100644
--- a/include/clang/AST/DeclarationName.h
+++ b/include/clang/AST/DeclarationName.h
@@ -334,8 +334,8 @@ class DeclarationNameTable {
CXXOperatorIdName *CXXOperatorNames; // Operator names
void *CXXLiteralOperatorNames; // Actually a CXXOperatorIdName*
- DeclarationNameTable(const DeclarationNameTable&); // NONCOPYABLE
- DeclarationNameTable& operator=(const DeclarationNameTable&); // NONCOPYABLE
+ DeclarationNameTable(const DeclarationNameTable&) LLVM_DELETED_FUNCTION;
+ void operator=(const DeclarationNameTable&) LLVM_DELETED_FUNCTION;
public:
DeclarationNameTable(const ASTContext &C);
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 89c003c8f664..dc83654bd948 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -34,6 +34,7 @@
namespace clang {
class ASTContext;
class APValue;
+ class CastExpr;
class Decl;
class IdentifierInfo;
class ParmVarDecl;
@@ -42,6 +43,7 @@ namespace clang {
class BlockDecl;
class CXXBaseSpecifier;
class CXXOperatorCallExpr;
+ class MaterializeTemporaryExpr;
class CXXMemberCallExpr;
class ObjCPropertyRefExpr;
class OpaqueValueExpr;
@@ -49,6 +51,48 @@ namespace clang {
/// \brief A simple array of base specifiers.
typedef SmallVector<CXXBaseSpecifier*, 4> CXXCastPath;
+/// \brief An adjustment to be made to the temporary created when emitting a
+/// reference binding, which accesses a particular subobject of that temporary.
+struct SubobjectAdjustment {
+ enum {
+ DerivedToBaseAdjustment,
+ FieldAdjustment,
+ MemberPointerAdjustment
+ } Kind;
+
+ union {
+ struct {
+ const CastExpr *BasePath;
+ const CXXRecordDecl *DerivedClass;
+ } DerivedToBase;
+
+ FieldDecl *Field;
+
+ struct {
+ const MemberPointerType *MPT;
+ Expr *RHS;
+ } Ptr;
+ };
+
+ SubobjectAdjustment(const CastExpr *BasePath,
+ const CXXRecordDecl *DerivedClass)
+ : Kind(DerivedToBaseAdjustment) {
+ DerivedToBase.BasePath = BasePath;
+ DerivedToBase.DerivedClass = DerivedClass;
+ }
+
+ SubobjectAdjustment(FieldDecl *Field)
+ : Kind(FieldAdjustment) {
+ this->Field = Field;
+ }
+
+ SubobjectAdjustment(const MemberPointerType *MPT, Expr *RHS)
+ : Kind(MemberPointerAdjustment) {
+ this->Ptr.MPT = MPT;
+ this->Ptr.RHS = RHS;
+ }
+};
+
/// Expr - This represents one expression. Note that Expr's are subclasses of
/// Stmt. This allows an expression to be transparently used any place a Stmt
/// is required.
@@ -220,15 +264,6 @@ public:
/// Reasons why an expression might not be an l-value.
LValueClassification ClassifyLValue(ASTContext &Ctx) const;
- /// isModifiableLvalue - C99 6.3.2.1: an lvalue that does not have array type,
- /// does not have an incomplete type, does not have a const-qualified type,
- /// and if it is a structure or union, does not have any member (including,
- /// recursively, any member or element of all contained aggregates or unions)
- /// with a const-qualified type.
- ///
- /// \param Loc [in,out] - A source location which *may* be filled
- /// in with the location of the expression making this a
- /// non-modifiable lvalue, if specified.
enum isModifiableLvalueResult {
MLV_Valid,
MLV_NotObjectType,
@@ -247,6 +282,15 @@ public:
MLV_ClassTemporary,
MLV_ArrayTemporary
};
+ /// isModifiableLvalue - C99 6.3.2.1: an lvalue that does not have array type,
+ /// does not have an incomplete type, does not have a const-qualified type,
+ /// and if it is a structure or union, does not have any member (including,
+ /// recursively, any member or element of all contained aggregates or unions)
+ /// with a const-qualified type.
+ ///
+ /// \param Loc [in,out] - A source location which *may* be filled
+ /// in with the location of the expression making this a
+ /// non-modifiable lvalue, if specified.
isModifiableLvalueResult isModifiableLvalue(ASTContext &Ctx,
SourceLocation *Loc = 0) const;
@@ -392,6 +436,9 @@ public:
/// property, find the underlying property reference expression.
const ObjCPropertyRefExpr *getObjCProperty() const;
+ /// \brief Check if this expression is the ObjC 'self' implicit parameter.
+ bool isObjCSelfExpr() const;
+
/// \brief Returns whether this expression refers to a vector element.
bool refersToVectorElement() const;
@@ -692,11 +739,22 @@ public:
/// behavior if the object isn't dynamically of the derived type.
const CXXRecordDecl *getBestDynamicClassType() const;
+ /// Walk outwards from an expression we want to bind a reference to and
+ /// find the expression whose lifetime needs to be extended. Record
+ /// the adjustments needed along the path.
+ const Expr *
+ skipRValueSubobjectAdjustments(
+ SmallVectorImpl<SubobjectAdjustment> &Adjustments) const;
+
+ /// Skip irrelevant expressions to find what should be materialize for
+ /// binding with a reference.
+ const Expr *
+ findMaterializedTemporary(const MaterializeTemporaryExpr *&MTE) const;
+
static bool classof(const Stmt *T) {
return T->getStmtClass() >= firstExprConstant &&
T->getStmtClass() <= lastExprConstant;
}
- static bool classof(const Expr *) { return true; }
};
@@ -762,7 +820,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == OpaqueValueExprClass;
}
- static bool classof(const OpaqueValueExpr *) { return true; }
};
/// \brief A reference to a declared variable, function, enum, etc.
@@ -1059,7 +1116,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == DeclRefExprClass;
}
- static bool classof(const DeclRefExpr *) { return true; }
// Iterators
child_range children() { return child_range(); }
@@ -1109,7 +1165,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == PredefinedExprClass;
}
- static bool classof(const PredefinedExpr *) { return true; }
// Iterators
child_range children() { return child_range(); }
@@ -1132,8 +1187,8 @@ class APNumericStorage {
bool hasAllocation() const { return llvm::APInt::getNumWords(BitWidth) > 1; }
- APNumericStorage(const APNumericStorage&); // do not implement
- APNumericStorage& operator=(const APNumericStorage&); // do not implement
+ APNumericStorage(const APNumericStorage &) LLVM_DELETED_FUNCTION;
+ void operator=(const APNumericStorage &) LLVM_DELETED_FUNCTION;
protected:
APNumericStorage() : VAL(0), BitWidth(0) { }
@@ -1196,7 +1251,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == IntegerLiteralClass;
}
- static bool classof(const IntegerLiteral *) { return true; }
// Iterators
child_range children() { return child_range(); }
@@ -1243,7 +1297,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CharacterLiteralClass;
}
- static bool classof(const CharacterLiteral *) { return true; }
// Iterators
child_range children() { return child_range(); }
@@ -1286,7 +1339,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == FloatingLiteralClass;
}
- static bool classof(const FloatingLiteral *) { return true; }
// Iterators
child_range children() { return child_range(); }
@@ -1317,7 +1369,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == ImaginaryLiteralClass;
}
- static bool classof(const ImaginaryLiteral *) { return true; }
// Iterators
child_range children() { return child_range(&Val, &Val+1); }
@@ -1479,7 +1530,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == StringLiteralClass;
}
- static bool classof(const StringLiteral *) { return true; }
// Iterators
child_range children() { return child_range(); }
@@ -1520,7 +1570,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == ParenExprClass;
}
- static bool classof(const ParenExpr *) { return true; }
// Iterators
child_range children() { return child_range(&Val, &Val+1); }
@@ -1610,7 +1659,7 @@ public:
/// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
/// corresponds to, e.g. "sizeof" or "[pre]++"
- static const char *getOpcodeStr(Opcode Op);
+ static StringRef getOpcodeStr(Opcode Op);
/// \brief Retrieve the unary opcode that corresponds to the given
/// overloaded operator.
@@ -1631,7 +1680,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == UnaryOperatorClass;
}
- static bool classof(const UnaryOperator *) { return true; }
// Iterators
child_range children() { return child_range(&Val, &Val+1); }
@@ -1757,8 +1805,7 @@ private:
OffsetOfExpr(ASTContext &C, QualType type,
SourceLocation OperatorLoc, TypeSourceInfo *tsi,
- OffsetOfNode* compsPtr, unsigned numComps,
- Expr** exprsPtr, unsigned numExprs,
+ ArrayRef<OffsetOfNode> comps, ArrayRef<Expr*> exprs,
SourceLocation RParenLoc);
explicit OffsetOfExpr(unsigned numComps, unsigned numExprs)
@@ -1769,9 +1816,8 @@ public:
static OffsetOfExpr *Create(ASTContext &C, QualType type,
SourceLocation OperatorLoc, TypeSourceInfo *tsi,
- OffsetOfNode* compsPtr, unsigned numComps,
- Expr** exprsPtr, unsigned numExprs,
- SourceLocation RParenLoc);
+ ArrayRef<OffsetOfNode> comps,
+ ArrayRef<Expr*> exprs, SourceLocation RParenLoc);
static OffsetOfExpr *CreateEmpty(ASTContext &C,
unsigned NumComps, unsigned NumExprs);
@@ -1832,8 +1878,6 @@ public:
return T->getStmtClass() == OffsetOfExprClass;
}
- static bool classof(const OffsetOfExpr *) { return true; }
-
// Iterators
child_range children() {
Stmt **begin =
@@ -1937,7 +1981,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == UnaryExprOrTypeTraitExprClass;
}
- static bool classof(const UnaryExprOrTypeTraitExpr *) { return true; }
// Iterators
child_range children();
@@ -2017,7 +2060,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == ArraySubscriptExprClass;
}
- static bool classof(const ArraySubscriptExpr *) { return true; }
// Iterators
child_range children() {
@@ -2041,7 +2083,7 @@ class CallExpr : public Expr {
protected:
// These versions of the constructor are for derived classes.
CallExpr(ASTContext& C, StmtClass SC, Expr *fn, unsigned NumPreArgs,
- Expr **args, unsigned numargs, QualType t, ExprValueKind VK,
+ ArrayRef<Expr*> args, QualType t, ExprValueKind VK,
SourceLocation rparenloc);
CallExpr(ASTContext &C, StmtClass SC, unsigned NumPreArgs, EmptyShell Empty);
@@ -2061,7 +2103,7 @@ protected:
unsigned getNumPreArgs() const { return CallExprBits.NumPreArgs; }
public:
- CallExpr(ASTContext& C, Expr *fn, Expr **args, unsigned numargs, QualType t,
+ CallExpr(ASTContext& C, Expr *fn, ArrayRef<Expr*> args, QualType t,
ExprValueKind VK, SourceLocation rparenloc);
/// \brief Build an empty call expression.
@@ -2153,7 +2195,6 @@ public:
return T->getStmtClass() >= firstCallExprConstant &&
T->getStmtClass() <= lastCallExprConstant;
}
- static bool classof(const CallExpr *) { return true; }
// Iterators
child_range children() {
@@ -2440,7 +2481,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == MemberExprClass;
}
- static bool classof(const MemberExpr *) { return true; }
// Iterators
child_range children() { return child_range(&Base, &Base+1); }
@@ -2506,7 +2546,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CompoundLiteralExprClass;
}
- static bool classof(const CompoundLiteralExpr *) { return true; }
// Iterators
child_range children() { return child_range(&Init, &Init+1); }
@@ -2597,7 +2636,6 @@ public:
return T->getStmtClass() >= firstCastExprConstant &&
T->getStmtClass() <= lastCastExprConstant;
}
- static bool classof(const CastExpr *) { return true; }
// Iterators
child_range children() { return child_range(&Op, &Op+1); }
@@ -2661,7 +2699,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == ImplicitCastExprClass;
}
- static bool classof(const ImplicitCastExpr *) { return true; }
};
inline Expr *Expr::IgnoreImpCasts() {
@@ -2716,7 +2753,6 @@ public:
return T->getStmtClass() >= firstExplicitCastExprConstant &&
T->getStmtClass() <= lastExplicitCastExprConstant;
}
- static bool classof(const ExplicitCastExpr *) { return true; }
};
/// CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style
@@ -2757,7 +2793,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CStyleCastExprClass;
}
- static bool classof(const CStyleCastExpr *) { return true; }
};
/// \brief A builtin binary operation expression such as "x + y" or "x <= y".
@@ -2784,6 +2819,12 @@ public:
private:
unsigned Opc : 6;
+
+ // Records the FP_CONTRACT pragma status at the point that this binary
+ // operator was parsed. This bit is only meaningful for operations on
+ // floating point types. For all other types it should default to
+ // false.
+ unsigned FPContractable : 1;
SourceLocation OpLoc;
enum { LHS, RHS, END_EXPR };
@@ -2792,7 +2833,7 @@ public:
BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
ExprValueKind VK, ExprObjectKind OK,
- SourceLocation opLoc)
+ SourceLocation opLoc, bool fpContractable)
: Expr(BinaryOperatorClass, ResTy, VK, OK,
lhs->isTypeDependent() || rhs->isTypeDependent(),
lhs->isValueDependent() || rhs->isValueDependent(),
@@ -2800,7 +2841,7 @@ public:
rhs->isInstantiationDependent()),
(lhs->containsUnexpandedParameterPack() ||
rhs->containsUnexpandedParameterPack())),
- Opc(opc), OpLoc(opLoc) {
+ Opc(opc), FPContractable(fpContractable), OpLoc(opLoc) {
SubExprs[LHS] = lhs;
SubExprs[RHS] = rhs;
assert(!isCompoundAssignmentOp() &&
@@ -2829,9 +2870,9 @@ public:
/// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
/// corresponds to, e.g. "<<=".
- static const char *getOpcodeStr(Opcode Op);
+ static StringRef getOpcodeStr(Opcode Op);
- const char *getOpcodeStr() const { return getOpcodeStr(getOpcode()); }
+ StringRef getOpcodeStr() const { return getOpcodeStr(getOpcode()); }
/// \brief Retrieve the binary opcode that corresponds to the given
/// overloaded operator.
@@ -2894,17 +2935,24 @@ public:
return S->getStmtClass() >= firstBinaryOperatorConstant &&
S->getStmtClass() <= lastBinaryOperatorConstant;
}
- static bool classof(const BinaryOperator *) { return true; }
// Iterators
child_range children() {
return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
}
+ // Set the FP contractability status of this operator. Only meaningful for
+ // operations on floating point types.
+ void setFPContractable(bool FPC) { FPContractable = FPC; }
+
+ // Get the FP contractability status of this operator. Only meaningful for
+ // operations on floating point types.
+ bool isFPContractable() const { return FPContractable; }
+
protected:
BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
ExprValueKind VK, ExprObjectKind OK,
- SourceLocation opLoc, bool dead)
+ SourceLocation opLoc, bool fpContractable, bool dead2)
: Expr(CompoundAssignOperatorClass, ResTy, VK, OK,
lhs->isTypeDependent() || rhs->isTypeDependent(),
lhs->isValueDependent() || rhs->isValueDependent(),
@@ -2912,7 +2960,7 @@ protected:
rhs->isInstantiationDependent()),
(lhs->containsUnexpandedParameterPack() ||
rhs->containsUnexpandedParameterPack())),
- Opc(opc), OpLoc(opLoc) {
+ Opc(opc), FPContractable(fpContractable), OpLoc(opLoc) {
SubExprs[LHS] = lhs;
SubExprs[RHS] = rhs;
}
@@ -2934,8 +2982,9 @@ public:
CompoundAssignOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResType,
ExprValueKind VK, ExprObjectKind OK,
QualType CompLHSType, QualType CompResultType,
- SourceLocation OpLoc)
- : BinaryOperator(lhs, rhs, opc, ResType, VK, OK, OpLoc, true),
+ SourceLocation OpLoc, bool fpContractable)
+ : BinaryOperator(lhs, rhs, opc, ResType, VK, OK, OpLoc, fpContractable,
+ true),
ComputationLHSType(CompLHSType),
ComputationResultType(CompResultType) {
assert(isCompoundAssignmentOp() &&
@@ -2955,7 +3004,6 @@ public:
QualType getComputationResultType() const { return ComputationResultType; }
void setComputationResultType(QualType T) { ComputationResultType = T; }
- static bool classof(const CompoundAssignOperator *) { return true; }
static bool classof(const Stmt *S) {
return S->getStmtClass() == CompoundAssignOperatorClass;
}
@@ -3001,7 +3049,6 @@ public:
return T->getStmtClass() == ConditionalOperatorClass ||
T->getStmtClass() == BinaryConditionalOperatorClass;
}
- static bool classof(const AbstractConditionalOperator *) { return true; }
};
/// ConditionalOperator - The ?: ternary operator. The GNU "missing
@@ -3060,7 +3107,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == ConditionalOperatorClass;
}
- static bool classof(const ConditionalOperator *) { return true; }
// Iterators
child_range children() {
@@ -3142,7 +3188,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == BinaryConditionalOperatorClass;
}
- static bool classof(const BinaryConditionalOperator *) { return true; }
// Iterators
child_range children() {
@@ -3198,7 +3243,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == AddrLabelExprClass;
}
- static bool classof(const AddrLabelExpr *) { return true; }
// Iterators
child_range children() { return child_range(); }
@@ -3242,7 +3286,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == StmtExprClass;
}
- static bool classof(const StmtExpr *) { return true; }
// Iterators
child_range children() { return child_range(&SubStmt, &SubStmt+1); }
@@ -3266,9 +3309,8 @@ class ShuffleVectorExpr : public Expr {
unsigned NumExprs;
public:
- ShuffleVectorExpr(ASTContext &C, Expr **args, unsigned nexpr,
- QualType Type, SourceLocation BLoc,
- SourceLocation RP);
+ ShuffleVectorExpr(ASTContext &C, ArrayRef<Expr*> args, QualType Type,
+ SourceLocation BLoc, SourceLocation RP);
/// \brief Build an empty vector-shuffle expression.
explicit ShuffleVectorExpr(EmptyShell Empty)
@@ -3286,7 +3328,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == ShuffleVectorExprClass;
}
- static bool classof(const ShuffleVectorExpr *) { return true; }
/// getNumSubExprs - Return the size of the SubExprs array. This includes the
/// constant expression, the actual arguments passed in, and the function
@@ -3308,7 +3349,7 @@ public:
void setExprs(ASTContext &C, Expr ** Exprs, unsigned NumExprs);
- unsigned getShuffleMaskIdx(ASTContext &Ctx, unsigned N) {
+ unsigned getShuffleMaskIdx(ASTContext &Ctx, unsigned N) const {
assert((N < NumExprs - 2) && "Shuffle idx out of range!");
return getExpr(N+2)->EvaluateKnownConstInt(Ctx).getZExtValue();
}
@@ -3381,7 +3422,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == ChooseExprClass;
}
- static bool classof(const ChooseExpr *) { return true; }
// Iterators
child_range children() {
@@ -3418,7 +3458,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == GNUNullExprClass;
}
- static bool classof(const GNUNullExpr *) { return true; }
// Iterators
child_range children() { return child_range(); }
@@ -3464,7 +3503,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == VAArgExprClass;
}
- static bool classof(const VAArgExpr *) { return true; }
// Iterators
child_range children() { return child_range(&Val, &Val+1); }
@@ -3501,21 +3539,32 @@ public:
/// initializer lists may still have fewer initializers than there are
/// elements to initialize within the object.
///
+/// After semantic analysis has completed, given an initializer list,
+/// method isSemanticForm() returns true if and only if this is the
+/// semantic form of the initializer list (note: the same AST node
+/// may at the same time be the syntactic form).
/// Given the semantic form of the initializer list, one can retrieve
-/// the original syntactic form of that initializer list (if it
-/// exists) using getSyntacticForm(). Since many initializer lists
-/// have the same syntactic and semantic forms, getSyntacticForm() may
-/// return NULL, indicating that the current initializer list also
-/// serves as its syntactic form.
+/// the syntactic form of that initializer list (when different)
+/// using method getSyntacticForm(); the method returns null if applied
+/// to a initializer list which is already in syntactic form.
+/// Similarly, given the syntactic form (i.e., an initializer list such
+/// that isSemanticForm() returns false), one can retrieve the semantic
+/// form using method getSemanticForm().
+/// Since many initializer lists have the same syntactic and semantic forms,
+/// getSyntacticForm() may return NULL, indicating that the current
+/// semantic initializer list also serves as its syntactic form.
class InitListExpr : public Expr {
// FIXME: Eliminate this vector in favor of ASTContext allocation
typedef ASTVector<Stmt *> InitExprsTy;
InitExprsTy InitExprs;
SourceLocation LBraceLoc, RBraceLoc;
- /// Contains the initializer list that describes the syntactic form
- /// written in the source code.
- InitListExpr *SyntacticForm;
+ /// The alternative form of the initializer list (if it exists).
+ /// The int part of the pair stores whether this initalizer list is
+ /// in semantic form. If not null, the pointer points to:
+ /// - the syntactic form, if this is in semantic form;
+ /// - the semantic form, if this is in syntactic form.
+ llvm::PointerIntPair<InitListExpr *, 1, bool> AltForm;
/// \brief Either:
/// If this initializer list initializes an array with more elements than
@@ -3528,8 +3577,7 @@ class InitListExpr : public Expr {
public:
InitListExpr(ASTContext &C, SourceLocation lbraceloc,
- Expr **initexprs, unsigned numinits,
- SourceLocation rbraceloc);
+ ArrayRef<Expr*> initExprs, SourceLocation rbraceloc);
/// \brief Build an empty initializer list.
explicit InitListExpr(ASTContext &C, EmptyShell Empty)
@@ -3621,12 +3669,20 @@ public:
SourceLocation getRBraceLoc() const { return RBraceLoc; }
void setRBraceLoc(SourceLocation Loc) { RBraceLoc = Loc; }
- /// @brief Retrieve the initializer list that describes the
- /// syntactic form of the initializer.
- ///
- ///
- InitListExpr *getSyntacticForm() const { return SyntacticForm; }
- void setSyntacticForm(InitListExpr *Init) { SyntacticForm = Init; }
+ bool isSemanticForm() const { return AltForm.getInt(); }
+ InitListExpr *getSemanticForm() const {
+ return isSemanticForm() ? 0 : AltForm.getPointer();
+ }
+ InitListExpr *getSyntacticForm() const {
+ return isSemanticForm() ? AltForm.getPointer() : 0;
+ }
+
+ void setSyntacticForm(InitListExpr *Init) {
+ AltForm.setPointer(Init);
+ AltForm.setInt(true);
+ Init->AltForm.setPointer(this);
+ Init->AltForm.setInt(false);
+ }
bool hadArrayRangeDesignator() const {
return InitListExprBits.HadArrayRangeDesignator != 0;
@@ -3647,7 +3703,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == InitListExprClass;
}
- static bool classof(const InitListExpr *) { return true; }
// Iterators
child_range children() {
@@ -3723,8 +3778,7 @@ private:
DesignatedInitExpr(ASTContext &C, QualType Ty, unsigned NumDesignators,
const Designator *Designators,
SourceLocation EqualOrColonLoc, bool GNUSyntax,
- Expr **IndexExprs, unsigned NumIndexExprs,
- Expr *Init);
+ ArrayRef<Expr*> IndexExprs, Expr *Init);
explicit DesignatedInitExpr(unsigned NumSubExprs)
: Expr(DesignatedInitExprClass, EmptyShell()),
@@ -3885,7 +3939,7 @@ public:
static DesignatedInitExpr *Create(ASTContext &C, Designator *Designators,
unsigned NumDesignators,
- Expr **IndexExprs, unsigned NumIndexExprs,
+ ArrayRef<Expr*> IndexExprs,
SourceLocation EqualOrColonLoc,
bool GNUSyntax, Expr *Init);
@@ -3985,7 +4039,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == DesignatedInitExprClass;
}
- static bool classof(const DesignatedInitExpr *) { return true; }
// Iterators
child_range children() {
@@ -4015,7 +4068,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == ImplicitValueInitExprClass;
}
- static bool classof(const ImplicitValueInitExpr *) { return true; }
SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange();
@@ -4032,8 +4084,8 @@ class ParenListExpr : public Expr {
SourceLocation LParenLoc, RParenLoc;
public:
- ParenListExpr(ASTContext& C, SourceLocation lparenloc, Expr **exprs,
- unsigned numexprs, SourceLocation rparenloc);
+ ParenListExpr(ASTContext& C, SourceLocation lparenloc, ArrayRef<Expr*> exprs,
+ SourceLocation rparenloc);
/// \brief Build an empty paren list.
explicit ParenListExpr(EmptyShell Empty) : Expr(ParenListExprClass, Empty) { }
@@ -4061,7 +4113,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == ParenListExprClass;
}
- static bool classof(const ParenListExpr *) { return true; }
// Iterators
child_range children() {
@@ -4109,18 +4160,18 @@ class GenericSelectionExpr : public Expr {
public:
GenericSelectionExpr(ASTContext &Context,
SourceLocation GenericLoc, Expr *ControllingExpr,
- TypeSourceInfo **AssocTypes, Expr **AssocExprs,
- unsigned NumAssocs, SourceLocation DefaultLoc,
- SourceLocation RParenLoc,
+ ArrayRef<TypeSourceInfo*> AssocTypes,
+ ArrayRef<Expr*> AssocExprs,
+ SourceLocation DefaultLoc, SourceLocation RParenLoc,
bool ContainsUnexpandedParameterPack,
unsigned ResultIndex);
/// This constructor is used in the result-dependent case.
GenericSelectionExpr(ASTContext &Context,
SourceLocation GenericLoc, Expr *ControllingExpr,
- TypeSourceInfo **AssocTypes, Expr **AssocExprs,
- unsigned NumAssocs, SourceLocation DefaultLoc,
- SourceLocation RParenLoc,
+ ArrayRef<TypeSourceInfo*> AssocTypes,
+ ArrayRef<Expr*> AssocExprs,
+ SourceLocation DefaultLoc, SourceLocation RParenLoc,
bool ContainsUnexpandedParameterPack);
explicit GenericSelectionExpr(EmptyShell Empty)
@@ -4176,7 +4227,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == GenericSelectionExprClass;
}
- static bool classof(const GenericSelectionExpr *) { return true; }
child_range children() {
return child_range(SubExprs, SubExprs+END_EXPR+NumAssocs);
@@ -4247,7 +4297,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == ExtVectorElementExprClass;
}
- static bool classof(const ExtVectorElementExpr *) { return true; }
// Iterators
child_range children() { return child_range(&Base, &Base+1); }
@@ -4289,7 +4338,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == BlockExprClass;
}
- static bool classof(const BlockExpr *) { return true; }
// Iterators
child_range children() { return child_range(); }
@@ -4336,7 +4384,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == AsTypeExprClass;
}
- static bool classof(const AsTypeExpr *) { return true; }
// Iterators
child_range children() { return child_range(&SrcExpr, &SrcExpr+1); }
@@ -4473,7 +4520,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == PseudoObjectExprClass;
}
- static bool classof(const PseudoObjectExpr *) { return true; }
};
/// AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*,
@@ -4501,7 +4547,7 @@ private:
friend class ASTStmtReader;
public:
- AtomicExpr(SourceLocation BLoc, Expr **args, unsigned nexpr, QualType t,
+ AtomicExpr(SourceLocation BLoc, ArrayRef<Expr*> args, QualType t,
AtomicOp op, SourceLocation RP);
/// \brief Determine the number of arguments the specified atomic builtin
@@ -4563,7 +4609,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == AtomicExprClass;
}
- static bool classof(const AtomicExpr *) { return true; }
// Iterators
child_range children() {
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index ecfa9e213637..9c759db1f97a 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -53,14 +53,19 @@ class CXXOperatorCallExpr : public CallExpr {
OverloadedOperatorKind Operator;
SourceRange Range;
+ // Record the FP_CONTRACT state that applies to this operator call. Only
+ // meaningful for floating point types. For other types this value can be
+ // set to false.
+ unsigned FPContractable : 1;
+
SourceRange getSourceRangeImpl() const LLVM_READONLY;
public:
CXXOperatorCallExpr(ASTContext& C, OverloadedOperatorKind Op, Expr *fn,
- Expr **args, unsigned numargs, QualType t,
- ExprValueKind VK, SourceLocation operatorloc)
- : CallExpr(C, CXXOperatorCallExprClass, fn, 0, args, numargs, t, VK,
+ ArrayRef<Expr*> args, QualType t, ExprValueKind VK,
+ SourceLocation operatorloc, bool fpContractable)
+ : CallExpr(C, CXXOperatorCallExprClass, fn, 0, args, t, VK,
operatorloc),
- Operator(Op) {
+ Operator(Op), FPContractable(fpContractable) {
Range = getSourceRangeImpl();
}
explicit CXXOperatorCallExpr(ASTContext& C, EmptyShell Empty) :
@@ -83,7 +88,14 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXOperatorCallExprClass;
}
- static bool classof(const CXXOperatorCallExpr *) { return true; }
+
+ // Set the FP contractability status of this operator. Only meaningful for
+ // operations on floating point types.
+ void setFPContractable(bool FPC) { FPContractable = FPC; }
+
+ // Get the FP contractability status of this operator. Only meaningful for
+ // operations on floating point types.
+ bool isFPContractable() const { return FPContractable; }
friend class ASTStmtReader;
friend class ASTStmtWriter;
@@ -99,9 +111,9 @@ public:
/// the object argument).
class CXXMemberCallExpr : public CallExpr {
public:
- CXXMemberCallExpr(ASTContext &C, Expr *fn, Expr **args, unsigned numargs,
+ CXXMemberCallExpr(ASTContext &C, Expr *fn, ArrayRef<Expr*> args,
QualType t, ExprValueKind VK, SourceLocation RP)
- : CallExpr(C, CXXMemberCallExprClass, fn, 0, args, numargs, t, VK, RP) {}
+ : CallExpr(C, CXXMemberCallExprClass, fn, 0, args, t, VK, RP) {}
CXXMemberCallExpr(ASTContext &C, EmptyShell Empty)
: CallExpr(C, CXXMemberCallExprClass, Empty) { }
@@ -124,7 +136,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXMemberCallExprClass;
}
- static bool classof(const CXXMemberCallExpr *) { return true; }
};
/// CUDAKernelCallExpr - Represents a call to a CUDA kernel function.
@@ -134,10 +145,9 @@ private:
public:
CUDAKernelCallExpr(ASTContext &C, Expr *fn, CallExpr *Config,
- Expr **args, unsigned numargs, QualType t,
- ExprValueKind VK, SourceLocation RP)
- : CallExpr(C, CUDAKernelCallExprClass, fn, END_PREARG, args, numargs, t, VK,
- RP) {
+ ArrayRef<Expr*> args, QualType t, ExprValueKind VK,
+ SourceLocation RP)
+ : CallExpr(C, CUDAKernelCallExprClass, fn, END_PREARG, args, t, VK, RP) {
setConfig(Config);
}
@@ -153,7 +163,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CUDAKernelCallExprClass;
}
- static bool classof(const CUDAKernelCallExpr *) { return true; }
};
/// CXXNamedCastExpr - Abstract class common to all of the C++ "named"
@@ -205,7 +214,6 @@ public:
return false;
}
}
- static bool classof(const CXXNamedCastExpr *) { return true; }
};
/// CXXStaticCastExpr - A C++ @c static_cast expression
@@ -235,7 +243,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXStaticCastExprClass;
}
- static bool classof(const CXXStaticCastExpr *) { return true; }
};
/// CXXDynamicCastExpr - A C++ @c dynamic_cast expression
@@ -269,7 +276,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXDynamicCastExprClass;
}
- static bool classof(const CXXDynamicCastExpr *) { return true; }
};
/// CXXReinterpretCastExpr - A C++ @c reinterpret_cast expression (C++
@@ -301,7 +307,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXReinterpretCastExprClass;
}
- static bool classof(const CXXReinterpretCastExpr *) { return true; }
};
/// CXXConstCastExpr - A C++ @c const_cast expression (C++ [expr.const.cast]),
@@ -329,7 +334,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXConstCastExprClass;
}
- static bool classof(const CXXConstCastExpr *) { return true; }
};
/// UserDefinedLiteral - A call to a literal operator (C++11 [over.literal])
@@ -346,11 +350,11 @@ class UserDefinedLiteral : public CallExpr {
SourceLocation UDSuffixLoc;
public:
- UserDefinedLiteral(ASTContext &C, Expr *Fn, Expr **Args, unsigned NumArgs,
+ UserDefinedLiteral(ASTContext &C, Expr *Fn, ArrayRef<Expr*> Args,
QualType T, ExprValueKind VK, SourceLocation LitEndLoc,
SourceLocation SuffixLoc)
- : CallExpr(C, UserDefinedLiteralClass, Fn, 0, Args, NumArgs, T, VK,
- LitEndLoc), UDSuffixLoc(SuffixLoc) {}
+ : CallExpr(C, UserDefinedLiteralClass, Fn, 0, Args, T, VK, LitEndLoc),
+ UDSuffixLoc(SuffixLoc) {}
explicit UserDefinedLiteral(ASTContext &C, EmptyShell Empty)
: CallExpr(C, UserDefinedLiteralClass, Empty) {}
@@ -398,7 +402,6 @@ public:
static bool classof(const Stmt *S) {
return S->getStmtClass() == UserDefinedLiteralClass;
}
- static bool classof(const UserDefinedLiteral *) { return true; }
friend class ASTStmtReader;
friend class ASTStmtWriter;
@@ -429,7 +432,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXBoolLiteralExprClass;
}
- static bool classof(const CXXBoolLiteralExpr *) { return true; }
// Iterators
child_range children() { return child_range(); }
@@ -455,7 +457,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXNullPtrLiteralExprClass;
}
- static bool classof(const CXXNullPtrLiteralExpr *) { return true; }
child_range children() { return child_range(); }
};
@@ -536,7 +537,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXTypeidExprClass;
}
- static bool classof(const CXXTypeidExpr *) { return true; }
// Iterators
child_range children() {
@@ -611,7 +611,9 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXUuidofExprClass;
}
- static bool classof(const CXXUuidofExpr *) { return true; }
+
+ /// Grabs __declspec(uuid()) off a type, or returns 0 if there is none.
+ static UuidAttr *GetUuidAttrOfType(QualType QT);
// Iterators
child_range children() {
@@ -659,7 +661,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXThisExprClass;
}
- static bool classof(const CXXThisExpr *) { return true; }
// Iterators
child_range children() { return child_range(); }
@@ -710,7 +711,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXThrowExprClass;
}
- static bool classof(const CXXThrowExpr *) { return true; }
// Iterators
child_range children() {
@@ -798,7 +798,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXDefaultArgExprClass;
}
- static bool classof(const CXXDefaultArgExpr *) { return true; }
// Iterators
child_range children() { return child_range(); }
@@ -875,7 +874,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXBindTemporaryExprClass;
}
- static bool classof(const CXXBindTemporaryExpr *) { return true; }
// Iterators
child_range children() { return child_range(&SubExpr, &SubExpr + 1); }
@@ -908,7 +906,7 @@ protected:
CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T,
SourceLocation Loc,
CXXConstructorDecl *d, bool elidable,
- Expr **args, unsigned numargs,
+ ArrayRef<Expr *> Args,
bool HadMultipleCandidates,
bool ListInitialization,
bool ZeroInitialization,
@@ -934,7 +932,7 @@ public:
static CXXConstructExpr *Create(ASTContext &C, QualType T,
SourceLocation Loc,
CXXConstructorDecl *D, bool Elidable,
- Expr **Args, unsigned NumArgs,
+ ArrayRef<Expr *> Args,
bool HadMultipleCandidates,
bool ListInitialization,
bool ZeroInitialization,
@@ -1011,7 +1009,6 @@ public:
return T->getStmtClass() == CXXConstructExprClass ||
T->getStmtClass() == CXXTemporaryObjectExprClass;
}
- static bool classof(const CXXConstructExpr *) { return true; }
// Iterators
child_range children() {
@@ -1066,7 +1063,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXFunctionalCastExprClass;
}
- static bool classof(const CXXFunctionalCastExpr *) { return true; }
};
/// @brief Represents a C++ functional cast expression that builds a
@@ -1090,7 +1086,7 @@ class CXXTemporaryObjectExpr : public CXXConstructExpr {
public:
CXXTemporaryObjectExpr(ASTContext &C, CXXConstructorDecl *Cons,
TypeSourceInfo *Type,
- Expr **Args,unsigned NumArgs,
+ ArrayRef<Expr *> Args,
SourceRange parenRange,
bool HadMultipleCandidates,
bool ZeroInitialization = false);
@@ -1104,7 +1100,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXTemporaryObjectExprClass;
}
- static bool classof(const CXXTemporaryObjectExpr *) { return true; }
friend class ASTStmtReader;
};
@@ -1281,8 +1276,11 @@ private:
/// \brief Retrieve the complete set of array-index variables.
VarDecl **getArrayIndexVars() const {
+ unsigned ArrayIndexSize =
+ llvm::RoundUpToAlignment(sizeof(unsigned) * (NumCaptures + 1),
+ llvm::alignOf<VarDecl*>());
return reinterpret_cast<VarDecl **>(
- getArrayIndexStarts() + NumCaptures + 1);
+ reinterpret_cast<char*>(getArrayIndexStarts()) + ArrayIndexSize);
}
public:
@@ -1394,7 +1392,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == LambdaExprClass;
}
- static bool classof(const LambdaExpr *) { return true; }
SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(IntroducerRange.getBegin(), ClosingBrace);
@@ -1442,7 +1439,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXScalarValueInitExprClass;
}
- static bool classof(const CXXScalarValueInitExpr *) { return true; }
// Iterators
child_range children() { return child_range(); }
@@ -1467,8 +1463,8 @@ class CXXNewExpr : public Expr {
/// the source range covering the parenthesized type-id.
SourceRange TypeIdParens;
- /// \brief Location of the first token.
- SourceLocation StartLoc;
+ /// \brief Range of the entire new expression.
+ SourceRange Range;
/// \brief Source-range of a paren-delimited initializer.
SourceRange DirectInitRange;
@@ -1498,11 +1494,11 @@ public:
CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
FunctionDecl *operatorDelete, bool usualArrayDeleteWantsSize,
- Expr **placementArgs, unsigned numPlaceArgs,
+ ArrayRef<Expr*> placementArgs,
SourceRange typeIdParens, Expr *arraySize,
InitializationStyle initializationStyle, Expr *initializer,
QualType ty, TypeSourceInfo *AllocatedTypeInfo,
- SourceLocation startLoc, SourceRange directInitRange);
+ SourceRange Range, SourceRange directInitRange);
explicit CXXNewExpr(EmptyShell Shell)
: Expr(CXXNewExprClass, Shell), SubExprs(0) { }
@@ -1580,7 +1576,7 @@ public:
}
/// \brief Returns the CXXConstructExpr from this new-expression, or NULL.
- const CXXConstructExpr* getConstructExpr() {
+ const CXXConstructExpr* getConstructExpr() const {
return dyn_cast_or_null<CXXConstructExpr>(getInitializer());
}
@@ -1617,19 +1613,18 @@ public:
return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
}
- SourceLocation getStartLoc() const { return StartLoc; }
- SourceLocation getEndLoc() const;
+ SourceLocation getStartLoc() const { return Range.getBegin(); }
+ SourceLocation getEndLoc() const { return Range.getEnd(); }
SourceRange getDirectInitRange() const { return DirectInitRange; }
SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(getStartLoc(), getEndLoc());
+ return Range;
}
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXNewExprClass;
}
- static bool classof(const CXXNewExpr *) { return true; }
// Iterators
child_range children() {
@@ -1700,7 +1695,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXDeleteExprClass;
}
- static bool classof(const CXXDeleteExpr *) { return true; }
// Iterators
child_range children() { return child_range(&Argument, &Argument+1); }
@@ -1889,7 +1883,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXPseudoDestructorExprClass;
}
- static bool classof(const CXXPseudoDestructorExpr *) { return true; }
// Iterators
child_range children() { return child_range(&Base, &Base + 1); }
@@ -1945,7 +1938,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == UnaryTypeTraitExprClass;
}
- static bool classof(const UnaryTypeTraitExpr *) { return true; }
// Iterators
child_range children() { return child_range(); }
@@ -2017,7 +2009,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == BinaryTypeTraitExprClass;
}
- static bool classof(const BinaryTypeTraitExpr *) { return true; }
// Iterators
child_range children() { return child_range(); }
@@ -2111,7 +2102,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == TypeTraitExprClass;
}
- static bool classof(const TypeTraitExpr *) { return true; }
// Iterators
child_range children() { return child_range(); }
@@ -2186,7 +2176,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == ArrayTypeTraitExprClass;
}
- static bool classof(const ArrayTypeTraitExpr *) { return true; }
// Iterators
child_range children() { return child_range(); }
@@ -2245,7 +2234,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == ExpressionTraitExprClass;
}
- static bool classof(const ExpressionTraitExpr *) { return true; }
// Iterators
child_range children() { return child_range(); }
@@ -2432,7 +2420,6 @@ public:
return T->getStmtClass() == UnresolvedLookupExprClass ||
T->getStmtClass() == UnresolvedMemberExprClass;
}
- static bool classof(const OverloadExpr *) { return true; }
friend class ASTStmtReader;
friend class ASTStmtWriter;
@@ -2454,10 +2441,6 @@ class UnresolvedLookupExpr : public OverloadExpr {
/// call.
bool RequiresADL;
- /// True if namespace ::std should be considered an associated namespace
- /// for the purposes of argument-dependent lookup. See C++0x [stmt.ranged]p1.
- bool StdIsAssociatedNamespace;
-
/// True if these lookup results are overloaded. This is pretty
/// trivially rederivable if we urgently need to kill this field.
bool Overloaded;
@@ -2476,19 +2459,16 @@ class UnresolvedLookupExpr : public OverloadExpr {
const DeclarationNameInfo &NameInfo,
bool RequiresADL, bool Overloaded,
const TemplateArgumentListInfo *TemplateArgs,
- UnresolvedSetIterator Begin, UnresolvedSetIterator End,
- bool StdIsAssociatedNamespace)
+ UnresolvedSetIterator Begin, UnresolvedSetIterator End)
: OverloadExpr(UnresolvedLookupExprClass, C, QualifierLoc, TemplateKWLoc,
NameInfo, TemplateArgs, Begin, End, false, false, false),
RequiresADL(RequiresADL),
- StdIsAssociatedNamespace(StdIsAssociatedNamespace),
Overloaded(Overloaded), NamingClass(NamingClass)
{}
UnresolvedLookupExpr(EmptyShell Empty)
: OverloadExpr(UnresolvedLookupExprClass, Empty),
- RequiresADL(false), StdIsAssociatedNamespace(false), Overloaded(false),
- NamingClass(0)
+ RequiresADL(false), Overloaded(false), NamingClass(0)
{}
friend class ASTStmtReader;
@@ -2500,14 +2480,10 @@ public:
const DeclarationNameInfo &NameInfo,
bool ADL, bool Overloaded,
UnresolvedSetIterator Begin,
- UnresolvedSetIterator End,
- bool StdIsAssociatedNamespace = false) {
- assert((ADL || !StdIsAssociatedNamespace) &&
- "std considered associated namespace when not performing ADL");
+ UnresolvedSetIterator End) {
return new(C) UnresolvedLookupExpr(C, NamingClass, QualifierLoc,
SourceLocation(), NameInfo,
- ADL, Overloaded, 0, Begin, End,
- StdIsAssociatedNamespace);
+ ADL, Overloaded, 0, Begin, End);
}
static UnresolvedLookupExpr *Create(ASTContext &C,
@@ -2528,10 +2504,6 @@ public:
/// argument-dependent lookup.
bool requiresADL() const { return RequiresADL; }
- /// True if namespace \::std should be artificially added to the set of
- /// associated namespaces for argument-dependent lookup purposes.
- bool isStdAssociatedNamespace() const { return StdIsAssociatedNamespace; }
-
/// True if this lookup is overloaded.
bool isOverloaded() const { return Overloaded; }
@@ -2554,7 +2526,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == UnresolvedLookupExprClass;
}
- static bool classof(const UnresolvedLookupExpr *) { return true; }
};
/// \brief A qualified reference to a name whose declaration cannot
@@ -2705,7 +2676,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == DependentScopeDeclRefExprClass;
}
- static bool classof(const DependentScopeDeclRefExpr *) { return true; }
child_range children() { return child_range(); }
@@ -2778,7 +2748,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == ExprWithCleanupsClass;
}
- static bool classof(const ExprWithCleanups *) { return true; }
// Iterators
child_range children() { return child_range(&SubExpr, &SubExpr + 1); }
@@ -2820,8 +2789,7 @@ class CXXUnresolvedConstructExpr : public Expr {
CXXUnresolvedConstructExpr(TypeSourceInfo *Type,
SourceLocation LParenLoc,
- Expr **Args,
- unsigned NumArgs,
+ ArrayRef<Expr*> Args,
SourceLocation RParenLoc);
CXXUnresolvedConstructExpr(EmptyShell Empty, unsigned NumArgs)
@@ -2833,8 +2801,7 @@ public:
static CXXUnresolvedConstructExpr *Create(ASTContext &C,
TypeSourceInfo *Type,
SourceLocation LParenLoc,
- Expr **Args,
- unsigned NumArgs,
+ ArrayRef<Expr*> Args,
SourceLocation RParenLoc);
static CXXUnresolvedConstructExpr *CreateEmpty(ASTContext &C,
@@ -2893,7 +2860,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXUnresolvedConstructExprClass;
}
- static bool classof(const CXXUnresolvedConstructExpr *) { return true; }
// Iterators
child_range children() {
@@ -3142,7 +3108,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXDependentScopeMemberExprClass;
}
- static bool classof(const CXXDependentScopeMemberExpr *) { return true; }
// Iterators
child_range children() {
@@ -3276,7 +3241,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == UnresolvedMemberExprClass;
}
- static bool classof(const UnresolvedMemberExpr *) { return true; }
// Iterators
child_range children() {
@@ -3320,7 +3284,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXNoexceptExprClass;
}
- static bool classof(const CXXNoexceptExpr *) { return true; }
// Iterators
child_range children() { return child_range(&Operand, &Operand + 1); }
@@ -3397,7 +3360,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == PackExpansionExprClass;
}
- static bool classof(const PackExpansionExpr *) { return true; }
// Iterators
child_range children() {
@@ -3503,7 +3465,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == SizeOfPackExprClass;
}
- static bool classof(const SizeOfPackExpr *) { return true; }
// Iterators
child_range children() { return child_range(); }
@@ -3548,9 +3509,6 @@ public:
static bool classof(const Stmt *s) {
return s->getStmtClass() == SubstNonTypeTemplateParmExprClass;
}
- static bool classof(const SubstNonTypeTemplateParmExpr *) {
- return true;
- }
// Iterators
child_range children() { return child_range(&Replacement, &Replacement+1); }
@@ -3561,7 +3519,7 @@ public:
///
/// When a pack expansion in the source code contains multiple parameter packs
/// and those parameter packs correspond to different levels of template
-/// parameter lists, this node node is used to represent a non-type template
+/// parameter lists, this node is used to represent a non-type template
/// parameter pack from an outer level, which has already had its argument pack
/// substituted but that still lives within a pack expansion that itself
/// could not be instantiated. When actually performing a substitution into
@@ -3608,14 +3566,77 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == SubstNonTypeTemplateParmPackExprClass;
}
- static bool classof(const SubstNonTypeTemplateParmPackExpr *) {
- return true;
- }
// Iterators
child_range children() { return child_range(); }
};
+/// \brief Represents a reference to a function parameter pack that has been
+/// substituted but not yet expanded.
+///
+/// When a pack expansion contains multiple parameter packs at different levels,
+/// this node is used to represent a function parameter pack at an outer level
+/// which we have already substituted to refer to expanded parameters, but where
+/// the containing pack expansion cannot yet be expanded.
+///
+/// \code
+/// template<typename...Ts> struct S {
+/// template<typename...Us> auto f(Ts ...ts) -> decltype(g(Us(ts)...));
+/// };
+/// template struct S<int, int>;
+/// \endcode
+class FunctionParmPackExpr : public Expr {
+ /// \brief The function parameter pack which was referenced.
+ ParmVarDecl *ParamPack;
+
+ /// \brief The location of the function parameter pack reference.
+ SourceLocation NameLoc;
+
+ /// \brief The number of expansions of this pack.
+ unsigned NumParameters;
+
+ FunctionParmPackExpr(QualType T, ParmVarDecl *ParamPack,
+ SourceLocation NameLoc, unsigned NumParams,
+ Decl * const *Params);
+
+ friend class ASTReader;
+ friend class ASTStmtReader;
+
+public:
+ static FunctionParmPackExpr *Create(ASTContext &Context, QualType T,
+ ParmVarDecl *ParamPack,
+ SourceLocation NameLoc,
+ llvm::ArrayRef<Decl*> Params);
+ static FunctionParmPackExpr *CreateEmpty(ASTContext &Context,
+ unsigned NumParams);
+
+ /// \brief Get the parameter pack which this expression refers to.
+ ParmVarDecl *getParameterPack() const { return ParamPack; }
+
+ /// \brief Get the location of the parameter pack.
+ SourceLocation getParameterPackLocation() const { return NameLoc; }
+
+ /// \brief Iterators over the parameters which the parameter pack expanded
+ /// into.
+ typedef ParmVarDecl * const *iterator;
+ iterator begin() const { return reinterpret_cast<iterator>(this+1); }
+ iterator end() const { return begin() + NumParameters; }
+
+ /// \brief Get the number of parameters in this parameter pack.
+ unsigned getNumExpansions() const { return NumParameters; }
+
+ /// \brief Get an expansion of the parameter pack by index.
+ ParmVarDecl *getExpansion(unsigned I) const { return begin()[I]; }
+
+ SourceRange getSourceRange() const LLVM_READONLY { return NameLoc; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == FunctionParmPackExprClass;
+ }
+
+ child_range children() { return child_range(); }
+};
+
/// \brief Represents a prvalue temporary that written into memory so that
/// a reference can bind to it.
///
@@ -3670,9 +3691,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == MaterializeTemporaryExprClass;
}
- static bool classof(const MaterializeTemporaryExpr *) {
- return true;
- }
// Iterators
child_range children() { return child_range(&Temporary, &Temporary + 1); }
diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h
index 93a5ada27915..27f5da0ce707 100644
--- a/include/clang/AST/ExprObjC.h
+++ b/include/clang/AST/ExprObjC.h
@@ -51,7 +51,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCStringLiteralClass;
}
- static bool classof(const ObjCStringLiteral *) { return true; }
// Iterators
child_range children() { return child_range(&String, &String+1); }
@@ -81,7 +80,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCBoolLiteralExprClass;
}
- static bool classof(const ObjCBoolLiteralExpr *) { return true; }
// Iterators
child_range children() { return child_range(); }
@@ -121,7 +119,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCBoxedExprClass;
}
- static bool classof(const ObjCBoxedExpr *) { return true; }
// Iterators
child_range children() { return child_range(&SubExpr, &SubExpr+1); }
@@ -156,7 +153,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCArrayLiteralClass;
}
- static bool classof(const ObjCArrayLiteral *) { return true; }
/// \brief Retrieve elements of array of literals.
Expr **getElements() { return reinterpret_cast<Expr **>(this + 1); }
@@ -319,7 +315,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCDictionaryLiteralClass;
}
- static bool classof(const ObjCDictionaryLiteral *) { return true; }
// Iterators
child_range children() {
@@ -372,7 +367,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCEncodeExprClass;
}
- static bool classof(const ObjCEncodeExpr *) { return true; }
// Iterators
child_range children() { return child_range(); }
@@ -409,7 +403,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCSelectorExprClass;
}
- static bool classof(const ObjCSelectorExpr *) { return true; }
// Iterators
child_range children() { return child_range(); }
@@ -447,7 +440,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCProtocolExprClass;
}
- static bool classof(const ObjCProtocolExpr *) { return true; }
// Iterators
child_range children() { return child_range(); }
@@ -501,7 +493,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCIvarRefExprClass;
}
- static bool classof(const ObjCIvarRefExpr *) { return true; }
// Iterators
child_range children() { return child_range(&Base, &Base+1); }
@@ -715,7 +706,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCPropertyRefExprClass;
}
- static bool classof(const ObjCPropertyRefExpr *) { return true; }
// Iterators
child_range children() {
@@ -813,7 +803,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCSubscriptRefExprClass;
}
- static bool classof(const ObjCSubscriptRefExpr *) { return true; }
Expr *getBaseExpr() const { return cast<Expr>(SubExprs[BASE]); }
void setBaseExpr(Stmt *S) { SubExprs[BASE] = S; }
@@ -1156,10 +1145,8 @@ public:
return getReceiverKind() == Class || getReceiverKind() == SuperClass;
}
- /// \brief Returns the receiver of an instance message.
- ///
- /// \brief Returns the object expression for an instance message, or
- /// NULL for a message that is not an instance message.
+ /// \brief Returns the object expression (receiver) for an instance message,
+ /// or null for a message that is not an instance message.
Expr *getInstanceReceiver() {
if (getReceiverKind() == Instance)
return static_cast<Expr *>(getReceiverPointer());
@@ -1208,6 +1195,17 @@ public:
return SourceLocation();
}
+ /// \brief Retrieve the receiver type to which this message is being directed.
+ ///
+ /// This routine cross-cuts all of the different kinds of message
+ /// sends to determine what the underlying (statically known) type
+ /// of the receiver will be; use \c getReceiverKind() to determine
+ /// whether the message is a class or an instance method, whether it
+ /// is a send to super or not, etc.
+ ///
+ /// \returns The type of the receiver.
+ QualType getReceiverType() const;
+
/// \brief Retrieve the Objective-C interface to which this message
/// is being directed, if known.
///
@@ -1344,7 +1342,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCMessageExprClass;
}
- static bool classof(const ObjCMessageExpr *) { return true; }
// Iterators
child_range children();
@@ -1409,7 +1406,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCIsaExprClass;
}
- static bool classof(const ObjCIsaExpr *) { return true; }
// Iterators
child_range children() { return child_range(&Base, &Base+1); }
@@ -1483,7 +1479,6 @@ public:
static bool classof(const Stmt *s) {
return s->getStmtClass() == ObjCIndirectCopyRestoreExprClass;
}
- static bool classof(const ObjCIndirectCopyRestoreExpr *) { return true; }
};
/// \brief An Objective-C "bridged" cast expression, which casts between
@@ -1532,8 +1527,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCBridgedCastExprClass;
}
- static bool classof(const ObjCBridgedCastExpr *) { return true; }
-
};
} // end namespace clang
diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h
index 7aedfe2ef600..db2bddb4bfca 100644
--- a/include/clang/AST/ExternalASTSource.h
+++ b/include/clang/AST/ExternalASTSource.h
@@ -162,7 +162,7 @@ public:
}
/// \brief Get the decls that are contained in a file in the Offset/Length
- /// range. \arg Length can be 0 to indicate a point at \arg Offset instead of
+ /// range. \p Length can be 0 to indicate a point at \p Offset instead of
/// a range.
virtual void FindFileRegionDecls(FileID File, unsigned Offset,unsigned Length,
SmallVectorImpl<Decl *> &Decls) {}
diff --git a/include/clang/AST/Makefile b/include/clang/AST/Makefile
index f6dd4ce6e69a..7fb33f27741a 100644
--- a/include/clang/AST/Makefile
+++ b/include/clang/AST/Makefile
@@ -1,6 +1,8 @@
CLANG_LEVEL := ../../..
TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic
-BUILT_SOURCES = Attrs.inc AttrImpl.inc StmtNodes.inc DeclNodes.inc CommentNodes.inc
+BUILT_SOURCES = Attrs.inc AttrImpl.inc StmtNodes.inc DeclNodes.inc \
+ CommentNodes.inc CommentHTMLTags.inc \
+ CommentHTMLTagsProperties.inc CommentCommandInfo.inc
TABLEGEN_INC_FILES_COMMON = 1
@@ -33,3 +35,18 @@ $(ObjDir)/CommentNodes.inc.tmp : $(TD_SRC_DIR)/CommentNodes.td $(CLANG_TBLGEN) \
$(Echo) "Building Clang comment node tables with tblgen"
$(Verb) $(ClangTableGen) -gen-clang-comment-nodes -o $(call SYSPATH, $@) $<
+$(ObjDir)/CommentHTMLTags.inc.tmp : $(PROJ_SRC_DIR)/CommentHTMLTags.td $(CLANG_TBLGEN) \
+ $(ObjDir)/.dir
+ $(Echo) "Building Clang comment HTML tag matchers with tblgen"
+ $(Verb) $(ClangTableGen) -gen-clang-comment-html-tags -o $(call SYSPATH, $@) $<
+
+$(ObjDir)/CommentHTMLTagsProperties.inc.tmp : $(PROJ_SRC_DIR)/CommentHTMLTags.td \
+ $(CLANG_TBLGEN) $(ObjDir)/.dir
+ $(Echo) "Building Clang comment HTML tag properties with tblgen"
+ $(Verb) $(ClangTableGen) -gen-clang-comment-html-tags-properties -o $(call SYSPATH, $@) $<
+
+$(ObjDir)/CommentCommandInfo.inc.tmp : $(PROJ_SRC_DIR)/CommentCommands.td \
+ $(CLANG_TBLGEN) $(ObjDir)/.dir
+ $(Echo) "Building Clang comment command info with tblgen"
+ $(Verb) $(ClangTableGen) -gen-clang-comment-command-info -o $(call SYSPATH, $@) $<
+
diff --git a/include/clang/AST/NSAPI.h b/include/clang/AST/NSAPI.h
index 51ae1daf14f3..f9fd1f906b55 100644
--- a/include/clang/AST/NSAPI.h
+++ b/include/clang/AST/NSAPI.h
@@ -83,7 +83,7 @@ public:
/// \brief The Objective-C NSArray selectors.
Selector getNSArraySelector(NSArrayMethodKind MK) const;
- /// \brief Return NSArrayMethodKind if \arg Sel is such a selector.
+ /// \brief Return NSArrayMethodKind if \p Sel is such a selector.
llvm::Optional<NSArrayMethodKind> getNSArrayMethodKind(Selector Sel);
/// \brief Enumerates the NSDictionary methods used to generate literals.
@@ -104,7 +104,7 @@ public:
/// \brief The Objective-C NSDictionary selectors.
Selector getNSDictionarySelector(NSDictionaryMethodKind MK) const;
- /// \brief Return NSDictionaryMethodKind if \arg Sel is such a selector.
+ /// \brief Return NSDictionaryMethodKind if \p Sel is such a selector.
llvm::Optional<NSDictionaryMethodKind>
getNSDictionaryMethodKind(Selector Sel);
@@ -169,7 +169,7 @@ public:
Sel == getNSNumberLiteralSelector(MK, true);
}
- /// \brief Return NSNumberLiteralMethodKind if \arg Sel is such a selector.
+ /// \brief Return NSNumberLiteralMethodKind if \p Sel is such a selector.
llvm::Optional<NSNumberLiteralMethodKind>
getNSNumberLiteralMethodKind(Selector Sel) const;
diff --git a/include/clang/AST/NestedNameSpecifier.h b/include/clang/AST/NestedNameSpecifier.h
index a5aec1fdda6b..bf9e1cbc764b 100644
--- a/include/clang/AST/NestedNameSpecifier.h
+++ b/include/clang/AST/NestedNameSpecifier.h
@@ -97,8 +97,7 @@ private:
Specifier(Other.Specifier) {
}
- NestedNameSpecifier &operator=(const NestedNameSpecifier &); // do not
- // implement
+ void operator=(const NestedNameSpecifier &) LLVM_DELETED_FUNCTION;
/// \brief Either find or insert the given nested name specifier
/// mockup in the given context.
diff --git a/include/clang/AST/OperationKinds.h b/include/clang/AST/OperationKinds.h
index 63594141ac66..18169fd60c83 100644
--- a/include/clang/AST/OperationKinds.h
+++ b/include/clang/AST/OperationKinds.h
@@ -288,7 +288,11 @@ enum CastKind {
///
/// This particular cast kind is used for the conversion from a C++11
/// lambda expression to a block pointer.
- CK_CopyAndAutoreleaseBlockObject
+ CK_CopyAndAutoreleaseBlockObject,
+
+ // Convert a builtin function to a function pointer; only allowed in the
+ // callee of a call expression.
+ CK_BuiltinFnToFnPtr
};
static const CastKind CK_Invalid = static_cast<CastKind>(-1);
diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h
index f2c015fffe94..7babc1b24a13 100644
--- a/include/clang/AST/PrettyPrinter.h
+++ b/include/clang/AST/PrettyPrinter.h
@@ -39,6 +39,7 @@ struct PrintingPolicy {
SuppressUnwrittenScope(false), SuppressInitializers(false),
ConstantArraySizeAsWritten(false), AnonymousTagLocations(true),
SuppressStrongLifetime(false), Bool(LO.Bool),
+ TerseOutput(false), SuppressAttributes(false),
DumpSourceManager(0) { }
/// \brief What language we're printing.
@@ -134,6 +135,17 @@ struct PrintingPolicy {
/// doesn't actually have 'bool' (because, e.g., it is defined as a macro).
unsigned Bool : 1;
+ /// \brief 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 not print attributes attached to the declaration.
+ ///
+ unsigned SuppressAttributes : 1;
+
/// \brief If we are "dumping" rather than "pretty-printing", this points to
/// a SourceManager which will be used to dump SourceLocations. Dumping
/// involves printing the internal details of the AST and pretty-printing
diff --git a/include/clang/AST/RawCommentList.h b/include/clang/AST/RawCommentList.h
index 630626b438ee..3a8b2183a557 100644
--- a/include/clang/AST/RawCommentList.h
+++ b/include/clang/AST/RawCommentList.h
@@ -18,6 +18,7 @@ namespace clang {
class ASTContext;
class ASTReader;
class Decl;
+class Preprocessor;
namespace comments {
class FullComment;
@@ -114,7 +115,8 @@ public:
}
/// Parse the comment, assuming it is attached to decl \c D.
- comments::FullComment *parse(const ASTContext &Context, const Decl *D) const;
+ comments::FullComment *parse(const ASTContext &Context,
+ const Preprocessor *PP, const Decl *D) const;
private:
SourceRange Range;
@@ -188,7 +190,7 @@ public:
private:
SourceManager &SourceMgr;
std::vector<RawComment *> Comments;
- RawComment LastComment;
+ SourceLocation PrevCommentEndLoc;
bool OnlyWhitespaceSeen;
void addCommentsToFront(const std::vector<RawComment *> &C) {
diff --git a/include/clang/AST/RecordLayout.h b/include/clang/AST/RecordLayout.h
index 3a870d057bad..36556469eaf8 100644
--- a/include/clang/AST/RecordLayout.h
+++ b/include/clang/AST/RecordLayout.h
@@ -136,8 +136,8 @@ private:
void Destroy(ASTContext &Ctx);
- ASTRecordLayout(const ASTRecordLayout&); // DO NOT IMPLEMENT
- void operator=(const ASTRecordLayout&); // DO NOT IMPLEMENT
+ ASTRecordLayout(const ASTRecordLayout &) LLVM_DELETED_FUNCTION;
+ void operator=(const ASTRecordLayout &) LLVM_DELETED_FUNCTION;
public:
/// getAlignment - Get the record alignment in characters.
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index 2e56a486f3d0..f96e06797855 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -721,6 +721,7 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgument(
case TemplateArgument::Null:
case TemplateArgument::Declaration:
case TemplateArgument::Integral:
+ case TemplateArgument::NullPtr:
return true;
case TemplateArgument::Type:
@@ -753,6 +754,7 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc(
case TemplateArgument::Null:
case TemplateArgument::Declaration:
case TemplateArgument::Integral:
+ case TemplateArgument::NullPtr:
return true;
case TemplateArgument::Type: {
@@ -799,7 +801,7 @@ bool RecursiveASTVisitor<Derived>::TraverseConstructorInitializer(
if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo())
TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
- if (Init->isWritten())
+ if (Init->isWritten() || getDerived().shouldVisitImplicitCode())
TRY_TO(TraverseStmt(Init->getInit()));
return true;
}
@@ -1827,7 +1829,7 @@ bool RecursiveASTVisitor<Derived>::Traverse##STMT (STMT *S) { \
return true; \
}
-DEF_TRAVERSE_STMT(AsmStmt, {
+DEF_TRAVERSE_STMT(GCCAsmStmt, {
TRY_TO(TraverseStmt(S->getAsmString()));
for (unsigned I = 0, E = S->getNumInputs(); I < E; ++I) {
TRY_TO(TraverseStmt(S->getInputConstraintLiteral(I)));
@@ -1836,7 +1838,7 @@ DEF_TRAVERSE_STMT(AsmStmt, {
TRY_TO(TraverseStmt(S->getOutputConstraintLiteral(I)));
}
for (unsigned I = 0, E = S->getNumClobbers(); I < E; ++I) {
- TRY_TO(TraverseStmt(S->getClobber(I)));
+ TRY_TO(TraverseStmt(S->getClobberStringLiteral(I)));
}
// children() iterates over inputExpr and outputExpr.
})
@@ -2141,7 +2143,9 @@ DEF_TRAVERSE_STMT(BlockExpr, {
return true; // no child statements to loop through.
})
DEF_TRAVERSE_STMT(ChooseExpr, { })
-DEF_TRAVERSE_STMT(CompoundLiteralExpr, { })
+DEF_TRAVERSE_STMT(CompoundLiteralExpr, {
+ TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
+})
DEF_TRAVERSE_STMT(CXXBindTemporaryExpr, { })
DEF_TRAVERSE_STMT(CXXBoolLiteralExpr, { })
DEF_TRAVERSE_STMT(CXXDefaultArgExpr, { })
@@ -2219,6 +2223,7 @@ DEF_TRAVERSE_STMT(PackExpansionExpr, { })
DEF_TRAVERSE_STMT(SizeOfPackExpr, { })
DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmPackExpr, { })
DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, { })
+DEF_TRAVERSE_STMT(FunctionParmPackExpr, { })
DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, { })
DEF_TRAVERSE_STMT(AtomicExpr, { })
diff --git a/include/clang/AST/SelectorLocationsKind.h b/include/clang/AST/SelectorLocationsKind.h
index cd43a5c49c55..6d903f820cd4 100644
--- a/include/clang/AST/SelectorLocationsKind.h
+++ b/include/clang/AST/SelectorLocationsKind.h
@@ -42,7 +42,7 @@ enum SelectorLocationsKind {
SelLoc_StandardWithSpace = 2
};
-/// \brief Returns true if all \arg SelLocs are in a "standard" location.
+/// \brief Returns true if all \p SelLocs are in a "standard" location.
SelectorLocationsKind hasStandardSelectorLocs(Selector Sel,
ArrayRef<SourceLocation> SelLocs,
ArrayRef<Expr *> Args,
@@ -60,7 +60,7 @@ SourceLocation getStandardSelectorLoc(unsigned Index,
ArrayRef<Expr *> Args,
SourceLocation EndLoc);
-/// \brief Returns true if all \arg SelLocs are in a "standard" location.
+/// \brief Returns true if all \p SelLocs are in a "standard" location.
SelectorLocationsKind hasStandardSelectorLocs(Selector Sel,
ArrayRef<SourceLocation> SelLocs,
ArrayRef<ParmVarDecl *> Args,
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index 35fb69312b6e..a9bbb48f0368 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -392,9 +392,6 @@ public:
const_cast<const Stmt*>(this)->stripLabelLikeStatements());
}
- // Implement isa<T> support.
- static bool classof(const Stmt *) { return true; }
-
/// hasImplicitControlFlow - Some statements (e.g. short circuited operations)
/// contain implicit control-flow in the order their subexpressions
/// are evaluated. This predicate returns true if this statement has
@@ -424,12 +421,12 @@ public:
/// \brief Produce a unique representation of the given statement.
///
- /// \brief ID once the profiling operation is complete, will contain
+ /// \param ID once the profiling operation is complete, will contain
/// the unique representation of the given statement.
///
- /// \brief Context the AST context in which the statement resides
+ /// \param Context the AST context in which the statement resides
///
- /// \brief Canonical whether the profile should be based on the canonical
+ /// \param Canonical whether the profile should be based on the canonical
/// representation of this statement (e.g., where non-type template
/// parameters are identified by index/level rather than their
/// declaration pointers) or the exact representation of the statement as
@@ -480,7 +477,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == DeclStmtClass;
}
- static bool classof(const DeclStmt *) { return true; }
// Iterators over subexpressions.
child_range children() {
@@ -535,7 +531,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == NullStmtClass;
}
- static bool classof(const NullStmt *) { return true; }
child_range children() { return child_range(); }
@@ -615,7 +610,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CompoundStmtClass;
}
- static bool classof(const CompoundStmt *) { return true; }
// Iterators
child_range children() {
@@ -654,7 +648,6 @@ public:
return T->getStmtClass() == CaseStmtClass ||
T->getStmtClass() == DefaultStmtClass;
}
- static bool classof(const SwitchCase *) { return true; }
};
class CaseStmt : public SwitchCase {
@@ -714,7 +707,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CaseStmtClass;
}
- static bool classof(const CaseStmt *) { return true; }
// Iterators
child_range children() {
@@ -749,7 +741,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == DefaultStmtClass;
}
- static bool classof(const DefaultStmt *) { return true; }
// Iterators
child_range children() { return child_range(&SubStmt, &SubStmt+1); }
@@ -788,7 +779,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == LabelStmtClass;
}
- static bool classof(const LabelStmt *) { return true; }
};
@@ -837,7 +827,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == AttributedStmtClass;
}
- static bool classof(const AttributedStmt *) { return true; }
};
@@ -906,7 +895,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == IfStmtClass;
}
- static bool classof(const IfStmt *) { return true; }
};
/// SwitchStmt - This represents a 'switch' stmt.
@@ -1000,7 +988,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == SwitchStmtClass;
}
- static bool classof(const SwitchStmt *) { return true; }
};
@@ -1050,7 +1037,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == WhileStmtClass;
}
- static bool classof(const WhileStmt *) { return true; }
// Iterators
child_range children() {
@@ -1099,7 +1085,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == DoStmtClass;
}
- static bool classof(const DoStmt *) { return true; }
// Iterators
child_range children() {
@@ -1171,7 +1156,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == ForStmtClass;
}
- static bool classof(const ForStmt *) { return true; }
// Iterators
child_range children() {
@@ -1206,7 +1190,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == GotoStmtClass;
}
- static bool classof(const GotoStmt *) { return true; }
// Iterators
child_range children() { return child_range(); }
@@ -1251,7 +1234,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == IndirectGotoStmtClass;
}
- static bool classof(const IndirectGotoStmt *) { return true; }
// Iterators
child_range children() { return child_range(&Target, &Target+1); }
@@ -1278,7 +1260,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == ContinueStmtClass;
}
- static bool classof(const ContinueStmt *) { return true; }
// Iterators
child_range children() { return child_range(); }
@@ -1302,7 +1283,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == BreakStmtClass;
}
- static bool classof(const BreakStmt *) { return true; }
// Iterators
child_range children() { return child_range(); }
@@ -1354,7 +1334,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == ReturnStmtClass;
}
- static bool classof(const ReturnStmt *) { return true; }
// Iterators
child_range children() {
@@ -1363,48 +1342,184 @@ public:
}
};
-/// AsmStmt - This represents a GNU inline-assembly statement extension.
+/// AsmStmt is the base class for GCCAsmStmt and MSAsmStmt.
///
class AsmStmt : public Stmt {
- SourceLocation AsmLoc, RParenLoc;
- StringLiteral *AsmStr;
-
+protected:
+ SourceLocation AsmLoc;
+ /// \brief True if the assembly statement does not have any input or output
+ /// operands.
bool IsSimple;
+
+ /// \brief If true, treat this inline assembly as having side effects.
+ /// This assembly statement should not be optimized, deleted or moved.
bool IsVolatile;
- bool MSAsm;
unsigned NumOutputs;
unsigned NumInputs;
unsigned NumClobbers;
- // FIXME: If we wanted to, we could allocate all of these in one big array.
IdentifierInfo **Names;
- StringLiteral **Constraints;
Stmt **Exprs;
- StringLiteral **Clobbers;
-public:
- AsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple, bool isvolatile,
- bool msasm, unsigned numoutputs, unsigned numinputs,
- IdentifierInfo **names, StringLiteral **constraints,
- Expr **exprs, StringLiteral *asmstr, unsigned numclobbers,
- StringLiteral **clobbers, SourceLocation rparenloc);
+ 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) { }
+public:
/// \brief Build an empty inline-assembly statement.
- explicit AsmStmt(EmptyShell Empty) : Stmt(AsmStmtClass, Empty),
- Names(0), Constraints(0), Exprs(0), Clobbers(0) { }
+ explicit AsmStmt(StmtClass SC, EmptyShell Empty) :
+ Stmt(SC, Empty), Names(0), Exprs(0) { }
SourceLocation getAsmLoc() const { return AsmLoc; }
void setAsmLoc(SourceLocation L) { AsmLoc = L; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- bool isVolatile() const { return IsVolatile; }
- void setVolatile(bool V) { IsVolatile = V; }
bool isSimple() const { return IsSimple; }
void setSimple(bool V) { IsSimple = V; }
- bool isMSAsm() const { return MSAsm; }
- void setMSAsm(bool V) { MSAsm = V; }
+
+ bool isVolatile() const { return IsVolatile; }
+ void setVolatile(bool V) { IsVolatile = V; }
+
+ SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(); }
+
+ //===--- Asm String Analysis ---===//
+
+ /// Assemble final IR asm string.
+ std::string generateAsmString(ASTContext &C) const;
+
+ //===--- Output operands ---===//
+
+ unsigned getNumOutputs() const { return NumOutputs; }
+
+ IdentifierInfo *getOutputIdentifier(unsigned i) const {
+ return Names[i];
+ }
+
+ StringRef getOutputName(unsigned i) const {
+ if (IdentifierInfo *II = getOutputIdentifier(i))
+ return II->getName();
+
+ return StringRef();
+ }
+
+ /// getOutputConstraint - Return the constraint string for the specified
+ /// output operand. All output constraints are known to be non-empty (either
+ /// '=' or '+').
+ StringRef getOutputConstraint(unsigned i) const;
+
+ /// isOutputPlusConstraint - Return true if the specified output constraint
+ /// is a "+" constraint (which is both an input and an output) or false if it
+ /// is an "=" constraint (just an output).
+ bool isOutputPlusConstraint(unsigned i) const {
+ return getOutputConstraint(i)[0] == '+';
+ }
+
+ const Expr *getOutputExpr(unsigned i) const;
+
+ /// getNumPlusOperands - Return the number of output operands that have a "+"
+ /// constraint.
+ unsigned getNumPlusOperands() const;
+
+ //===--- Input operands ---===//
+
+ unsigned getNumInputs() const { return NumInputs; }
+
+ IdentifierInfo *getInputIdentifier(unsigned i) const {
+ return Names[i + NumOutputs];
+ }
+
+ StringRef getInputName(unsigned i) const {
+ if (IdentifierInfo *II = getInputIdentifier(i))
+ return II->getName();
+
+ return StringRef();
+ }
+
+ /// getInputConstraint - Return the specified input constraint. Unlike output
+ /// constraints, these can be empty.
+ StringRef getInputConstraint(unsigned i) const;
+
+ const Expr *getInputExpr(unsigned i) const;
+
+ //===--- Other ---===//
+
+ unsigned getNumClobbers() const { return NumClobbers; }
+ StringRef getClobber(unsigned i) const;
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == GCCAsmStmtClass ||
+ T->getStmtClass() == MSAsmStmtClass;
+ }
+
+ // Input expr iterators.
+
+ typedef ExprIterator inputs_iterator;
+ typedef ConstExprIterator const_inputs_iterator;
+
+ inputs_iterator begin_inputs() {
+ return &Exprs[0] + NumOutputs;
+ }
+
+ inputs_iterator end_inputs() {
+ return &Exprs[0] + NumOutputs + NumInputs;
+ }
+
+ const_inputs_iterator begin_inputs() const {
+ return &Exprs[0] + NumOutputs;
+ }
+
+ const_inputs_iterator end_inputs() const {
+ return &Exprs[0] + NumOutputs + NumInputs;
+ }
+
+ // Output expr iterators.
+
+ typedef ExprIterator outputs_iterator;
+ typedef ConstExprIterator const_outputs_iterator;
+
+ outputs_iterator begin_outputs() {
+ return &Exprs[0];
+ }
+ outputs_iterator end_outputs() {
+ return &Exprs[0] + NumOutputs;
+ }
+
+ const_outputs_iterator begin_outputs() const {
+ return &Exprs[0];
+ }
+ const_outputs_iterator end_outputs() const {
+ return &Exprs[0] + NumOutputs;
+ }
+
+ child_range children() {
+ return child_range(&Exprs[0], &Exprs[0] + NumOutputs + NumInputs);
+ }
+};
+
+/// This represents a GCC inline-assembly statement extension.
+///
+class GCCAsmStmt : public AsmStmt {
+ SourceLocation RParenLoc;
+ StringLiteral *AsmStr;
+
+ // FIXME: If we wanted to, we could allocate all of these in one big array.
+ StringLiteral **Constraints;
+ StringLiteral **Clobbers;
+
+public:
+ GCCAsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple,
+ bool isvolatile, unsigned numoutputs, unsigned numinputs,
+ IdentifierInfo **names, StringLiteral **constraints, Expr **exprs,
+ StringLiteral *asmstr, unsigned numclobbers,
+ StringLiteral **clobbers, SourceLocation rparenloc);
+
+ /// \brief Build an empty inline-assembly statement.
+ explicit GCCAsmStmt(EmptyShell Empty) : AsmStmt(GCCAsmStmtClass, Empty),
+ Constraints(0), Clobbers(0) { }
+
+ SourceLocation getRParenLoc() const { return RParenLoc; }
+ void setRParenLoc(SourceLocation L) { RParenLoc = L; }
//===--- Asm String Analysis ---===//
@@ -1461,25 +1576,11 @@ public:
unsigned AnalyzeAsmString(SmallVectorImpl<AsmStringPiece> &Pieces,
ASTContext &C, unsigned &DiagOffs) const;
+ /// Assemble final IR asm string.
+ std::string generateAsmString(ASTContext &C) const;
//===--- Output operands ---===//
- unsigned getNumOutputs() const { return NumOutputs; }
-
- IdentifierInfo *getOutputIdentifier(unsigned i) const {
- return Names[i];
- }
-
- StringRef getOutputName(unsigned i) const {
- if (IdentifierInfo *II = getOutputIdentifier(i))
- return II->getName();
-
- return StringRef();
- }
-
- /// getOutputConstraint - Return the constraint string for the specified
- /// output operand. All output constraints are known to be non-empty (either
- /// '=' or '+').
StringRef getOutputConstraint(unsigned i) const;
const StringLiteral *getOutputConstraintLiteral(unsigned i) const {
@@ -1492,37 +1593,11 @@ public:
Expr *getOutputExpr(unsigned i);
const Expr *getOutputExpr(unsigned i) const {
- return const_cast<AsmStmt*>(this)->getOutputExpr(i);
+ return const_cast<GCCAsmStmt*>(this)->getOutputExpr(i);
}
- /// isOutputPlusConstraint - Return true if the specified output constraint
- /// is a "+" constraint (which is both an input and an output) or false if it
- /// is an "=" constraint (just an output).
- bool isOutputPlusConstraint(unsigned i) const {
- return getOutputConstraint(i)[0] == '+';
- }
-
- /// getNumPlusOperands - Return the number of output operands that have a "+"
- /// constraint.
- unsigned getNumPlusOperands() const;
-
//===--- Input operands ---===//
- unsigned getNumInputs() const { return NumInputs; }
-
- IdentifierInfo *getInputIdentifier(unsigned i) const {
- return Names[i + NumOutputs];
- }
-
- StringRef getInputName(unsigned i) const {
- if (IdentifierInfo *II = getInputIdentifier(i))
- return II->getName();
-
- return StringRef();
- }
-
- /// getInputConstraint - Return the specified input constraint. Unlike output
- /// constraints, these can be empty.
StringRef getInputConstraint(unsigned i) const;
const StringLiteral *getInputConstraintLiteral(unsigned i) const {
@@ -1536,7 +1611,7 @@ public:
void setInputExpr(unsigned i, Expr *E);
const Expr *getInputExpr(unsigned i) const {
- return const_cast<AsmStmt*>(this)->getInputExpr(i);
+ return const_cast<GCCAsmStmt*>(this)->getInputExpr(i);
}
void setOutputsAndInputsAndClobbers(ASTContext &C,
@@ -1555,90 +1630,45 @@ public:
/// This returns -1 if the operand name is invalid.
int getNamedOperand(StringRef SymbolicName) const;
- unsigned getNumClobbers() const { return NumClobbers; }
- StringLiteral *getClobber(unsigned i) { return Clobbers[i]; }
- const StringLiteral *getClobber(unsigned i) const { return Clobbers[i]; }
+ StringRef getClobber(unsigned i) const;
+ StringLiteral *getClobberStringLiteral(unsigned i) { return Clobbers[i]; }
+ const StringLiteral *getClobberStringLiteral(unsigned i) const {
+ return Clobbers[i];
+ }
SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(AsmLoc, RParenLoc);
}
- static bool classof(const Stmt *T) {return T->getStmtClass() == AsmStmtClass;}
- static bool classof(const AsmStmt *) { return true; }
-
- // Input expr iterators.
-
- typedef ExprIterator inputs_iterator;
- typedef ConstExprIterator const_inputs_iterator;
-
- inputs_iterator begin_inputs() {
- return &Exprs[0] + NumOutputs;
- }
-
- inputs_iterator end_inputs() {
- return &Exprs[0] + NumOutputs + NumInputs;
- }
-
- const_inputs_iterator begin_inputs() const {
- return &Exprs[0] + NumOutputs;
- }
-
- const_inputs_iterator end_inputs() const {
- return &Exprs[0] + NumOutputs + NumInputs;
- }
-
- // Output expr iterators.
-
- typedef ExprIterator outputs_iterator;
- typedef ConstExprIterator const_outputs_iterator;
-
- outputs_iterator begin_outputs() {
- return &Exprs[0];
- }
- outputs_iterator end_outputs() {
- return &Exprs[0] + NumOutputs;
- }
-
- const_outputs_iterator begin_outputs() const {
- return &Exprs[0];
- }
- const_outputs_iterator end_outputs() const {
- return &Exprs[0] + NumOutputs;
- }
-
- child_range children() {
- return child_range(&Exprs[0], &Exprs[0] + NumOutputs + NumInputs);
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == GCCAsmStmtClass;
}
};
-/// MSAsmStmt - This represents a MS inline-assembly statement extension.
+/// This represents a Microsoft inline-assembly statement extension.
///
-class MSAsmStmt : public Stmt {
+class MSAsmStmt : public AsmStmt {
SourceLocation AsmLoc, LBraceLoc, EndLoc;
std::string AsmStr;
- bool IsSimple;
- bool IsVolatile;
-
unsigned NumAsmToks;
- unsigned NumInputs;
- unsigned NumOutputs;
- unsigned NumClobbers;
Token *AsmToks;
- IdentifierInfo **Names;
- Stmt **Exprs;
+ StringRef *Constraints;
StringRef *Clobbers;
public:
MSAsmStmt(ASTContext &C, SourceLocation asmloc, SourceLocation lbraceloc,
bool issimple, bool isvolatile, ArrayRef<Token> asmtoks,
- ArrayRef<IdentifierInfo*> inputs, ArrayRef<IdentifierInfo*> outputs,
- StringRef asmstr, ArrayRef<StringRef> clobbers,
- SourceLocation endloc);
+ unsigned numoutputs, unsigned numinputs,
+ ArrayRef<IdentifierInfo*> names, ArrayRef<StringRef> constraints,
+ ArrayRef<Expr*> exprs, StringRef asmstr,
+ ArrayRef<StringRef> clobbers, SourceLocation endloc);
+
+ /// \brief Build an empty MS-style inline-assembly statement.
+ explicit MSAsmStmt(EmptyShell Empty) : AsmStmt(MSAsmStmtClass, Empty),
+ NumAsmToks(0), AsmToks(0), Constraints(0), Clobbers(0) { }
- SourceLocation getAsmLoc() const { return AsmLoc; }
- void setAsmLoc(SourceLocation L) { AsmLoc = L; }
SourceLocation getLBraceLoc() const { return LBraceLoc; }
void setLBraceLoc(SourceLocation L) { LBraceLoc = L; }
SourceLocation getEndLoc() const { return EndLoc; }
@@ -1649,20 +1679,42 @@ public:
unsigned getNumAsmToks() { return NumAsmToks; }
Token *getAsmToks() { return AsmToks; }
- bool isVolatile() const { return IsVolatile; }
- void setVolatile(bool V) { IsVolatile = V; }
- bool isSimple() const { return IsSimple; }
- void setSimple(bool V) { IsSimple = V; }
-
//===--- Asm String Analysis ---===//
const std::string *getAsmString() const { return &AsmStr; }
std::string *getAsmString() { return &AsmStr; }
void setAsmString(StringRef &E) { AsmStr = E.str(); }
+ /// Assemble final IR asm string.
+ std::string generateAsmString(ASTContext &C) const;
+
+ //===--- Output operands ---===//
+
+ StringRef getOutputConstraint(unsigned i) const {
+ return Constraints[i];
+ }
+
+ Expr *getOutputExpr(unsigned i);
+
+ const Expr *getOutputExpr(unsigned i) const {
+ return const_cast<MSAsmStmt*>(this)->getOutputExpr(i);
+ }
+
+ //===--- Input operands ---===//
+
+ StringRef getInputConstraint(unsigned i) const {
+ return Constraints[i + NumOutputs];
+ }
+
+ Expr *getInputExpr(unsigned i);
+ void setInputExpr(unsigned i, Expr *E);
+
+ const Expr *getInputExpr(unsigned i) const {
+ return const_cast<MSAsmStmt*>(this)->getInputExpr(i);
+ }
+
//===--- Other ---===//
- unsigned getNumClobbers() const { return NumClobbers; }
StringRef getClobber(unsigned i) const { return Clobbers[i]; }
SourceRange getSourceRange() const LLVM_READONLY {
@@ -1671,7 +1723,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == MSAsmStmtClass;
}
- static bool classof(const MSAsmStmt *) { return true; }
child_range children() {
return child_range(&Exprs[0], &Exprs[0]);
@@ -1720,8 +1771,6 @@ public:
return T->getStmtClass() == SEHExceptStmtClass;
}
- static bool classof(SEHExceptStmt *) { return true; }
-
};
class SEHFinallyStmt : public Stmt {
@@ -1757,8 +1806,6 @@ public:
return T->getStmtClass() == SEHFinallyStmtClass;
}
- static bool classof(SEHFinallyStmt *) { return true; }
-
};
class SEHTryStmt : public Stmt {
@@ -1810,8 +1857,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == SEHTryStmtClass;
}
-
- static bool classof(SEHTryStmt *) { return true; }
};
} // end namespace clang
diff --git a/include/clang/AST/StmtCXX.h b/include/clang/AST/StmtCXX.h
index a948722cc1d5..f4e4dcdd4a5e 100644
--- a/include/clang/AST/StmtCXX.h
+++ b/include/clang/AST/StmtCXX.h
@@ -50,7 +50,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXCatchStmtClass;
}
- static bool classof(const CXXCatchStmt *) { return true; }
child_range children() { return child_range(&HandlerBlock, &HandlerBlock+1); }
@@ -111,7 +110,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXTryStmtClass;
}
- static bool classof(const CXXTryStmt *) { return true; }
child_range children() {
return child_range(getStmts(), getStmts() + getNumHandlers() + 1);
@@ -196,7 +194,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXForRangeStmtClass;
}
- static bool classof(const CXXForRangeStmt *) { return true; }
// Iterators
child_range children() {
@@ -286,8 +283,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == MSDependentExistsStmtClass;
}
-
- static bool classof(MSDependentExistsStmt *) { return true; }
};
} // end namespace clang
diff --git a/include/clang/AST/StmtObjC.h b/include/clang/AST/StmtObjC.h
index e7e1232989e3..d7a73a70bd54 100644
--- a/include/clang/AST/StmtObjC.h
+++ b/include/clang/AST/StmtObjC.h
@@ -61,7 +61,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCForCollectionStmtClass;
}
- static bool classof(const ObjCForCollectionStmt *) { return true; }
// Iterators
child_range children() {
@@ -112,7 +111,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCAtCatchStmtClass;
}
- static bool classof(const ObjCAtCatchStmt *) { return true; }
child_range children() { return child_range(&Body, &Body + 1); }
};
@@ -143,7 +141,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCAtFinallyStmtClass;
}
- static bool classof(const ObjCAtFinallyStmt *) { return true; }
child_range children() {
return child_range(&AtFinallyStmt, &AtFinallyStmt+1);
@@ -244,7 +241,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCAtTryStmtClass;
}
- static bool classof(const ObjCAtTryStmt *) { return true; }
child_range children() {
return child_range(getStmts(),
@@ -303,7 +299,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCAtSynchronizedStmtClass;
}
- static bool classof(const ObjCAtSynchronizedStmt *) { return true; }
child_range children() {
return child_range(&SubStmts[0], &SubStmts[0]+END_EXPR);
@@ -339,7 +334,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCAtThrowStmtClass;
}
- static bool classof(const ObjCAtThrowStmt *) { return true; }
child_range children() { return child_range(&Throw, &Throw+1); }
};
@@ -371,7 +365,6 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCAutoreleasePoolStmtClass;
}
- static bool classof(const ObjCAutoreleasePoolStmt *) { return true; }
child_range children() { return child_range(&SubStmt, &SubStmt + 1); }
};
diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h
index 5047028e5eac..1c0abde5b761 100644
--- a/include/clang/AST/TemplateBase.h
+++ b/include/clang/AST/TemplateBase.h
@@ -28,11 +28,11 @@ namespace llvm {
namespace clang {
-class Decl;
class DiagnosticBuilder;
class Expr;
struct PrintingPolicy;
class TypeSourceInfo;
+class ValueDecl;
/// \brief Represents a template argument within a class template
/// specialization.
@@ -43,12 +43,14 @@ public:
/// \brief Represents an empty template argument, e.g., one that has not
/// been deduced.
Null = 0,
- /// The template argument is a type. Its value is stored in the
- /// TypeOrValue field.
+ /// The template argument is a type.
Type,
- /// The template argument is a declaration that was provided for a pointer
- /// or reference non-type template parameter.
+ /// 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,
@@ -73,6 +75,10 @@ private:
union {
uintptr_t TypeOrValue;
struct {
+ ValueDecl *D;
+ bool ForRefParam;
+ } DeclArg;
+ struct {
// We store a decomposed APSInt with the data allocated by ASTContext if
// BitWidth > 64. The memory may be shared between multiple
// TemplateArgument instances.
@@ -101,15 +107,18 @@ public:
TemplateArgument() : Kind(Null), TypeOrValue(0) { }
/// \brief Construct a template type argument.
- TemplateArgument(QualType T) : Kind(Type) {
+ TemplateArgument(QualType T, bool isNullPtr = false)
+ : Kind(isNullPtr ? NullPtr : Type) {
TypeOrValue = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
}
/// \brief Construct a template argument that refers to a
/// declaration, which is either an external declaration or a
/// template declaration.
- TemplateArgument(Decl *D) : Kind(Declaration) {
- TypeOrValue = reinterpret_cast<uintptr_t>(D);
+ TemplateArgument(ValueDecl *D, bool ForRefParam) : Kind(Declaration) {
+ assert(D && "Expected decl");
+ DeclArg.D = D;
+ DeclArg.ForRefParam = ForRefParam;
}
/// \brief Construct an integral constant template argument. The memory to
@@ -177,6 +186,10 @@ public:
this->Args.NumArgs = NumArgs;
}
+ static TemplateArgument getEmptyPack() {
+ return TemplateArgument((TemplateArgument*)0, 0);
+ }
+
/// \brief Create a new template argument pack by copying the given set of
/// template arguments.
static TemplateArgument CreatePackCopy(ASTContext &Context,
@@ -205,34 +218,43 @@ public:
/// \brief Determine whether this template argument is a pack expansion.
bool isPackExpansion() const;
- /// \brief Retrieve the template argument as a type.
+ /// \brief Retrieve the type for a type template argument.
QualType getAsType() const {
- if (Kind != Type)
- return QualType();
-
+ assert(Kind == Type && "Unexpected kind");
return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue));
}
- /// \brief Retrieve the template argument as a declaration.
- Decl *getAsDecl() const {
- if (Kind != Declaration)
- return 0;
- return reinterpret_cast<Decl *>(TypeOrValue);
+ /// \brief Retrieve the declaration for a declaration non-type
+ /// template argument.
+ ValueDecl *getAsDecl() const {
+ assert(Kind == Declaration && "Unexpected kind");
+ return DeclArg.D;
+ }
+
+ /// \brief Retrieve whether a declaration is binding to a
+ /// reference parameter in a declaration non-type template argument.
+ bool isDeclForReferenceParam() const {
+ assert(Kind == Declaration && "Unexpected kind");
+ return DeclArg.ForRefParam;
}
- /// \brief Retrieve the template argument as a template name.
+ /// \brief Retrieve the type for null non-type template argument.
+ QualType getNullPtrType() const {
+ assert(Kind == NullPtr && "Unexpected kind");
+ return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue));
+ }
+
+ /// \brief Retrieve the template name for a template name argument.
TemplateName getAsTemplate() const {
- if (Kind != Template)
- return TemplateName();
-
+ assert(Kind == Template && "Unexpected kind");
return TemplateName::getFromVoidPointer(TemplateArg.Name);
}
/// \brief Retrieve the template argument as a template name; if the argument
/// is a pack expansion, return the pattern as a template name.
TemplateName getAsTemplateOrTemplatePattern() const {
- if (Kind != Template && Kind != TemplateExpansion)
- return TemplateName();
+ assert((Kind == Template || Kind == TemplateExpansion) &&
+ "Unexpected kind");
return TemplateName::getFromVoidPointer(TemplateArg.Name);
}
@@ -244,6 +266,7 @@ public:
/// \brief Retrieve the template argument as an integral value.
// FIXME: Provide a way to read the integral data without copying the value.
llvm::APSInt getAsIntegral() const {
+ assert(Kind == Integral && "Unexpected kind");
using namespace llvm;
if (Integer.BitWidth <= 64)
return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned);
@@ -255,23 +278,18 @@ public:
/// \brief Retrieve the type of the integral value.
QualType getIntegralType() const {
- if (Kind != Integral)
- return QualType();
-
+ assert(Kind == Integral && "Unexpected kind");
return QualType::getFromOpaquePtr(Integer.Type);
}
void setIntegralType(QualType T) {
- assert(Kind == Integral &&
- "Cannot set the integral type of a non-integral template argument");
+ assert(Kind == Integral && "Unexpected kind");
Integer.Type = T.getAsOpaquePtr();
}
/// \brief Retrieve the template argument as an expression.
Expr *getAsExpr() const {
- if (Kind != Expression)
- return 0;
-
+ assert(Kind == Expression && "Unexpected kind");
return reinterpret_cast<Expr *>(TypeOrValue);
}
@@ -436,7 +454,17 @@ public:
assert(Argument.getKind() == TemplateArgument::Declaration);
return LocInfo.getAsExpr();
}
-
+
+ Expr *getSourceNullPtrExpression() const {
+ assert(Argument.getKind() == TemplateArgument::NullPtr);
+ return LocInfo.getAsExpr();
+ }
+
+ Expr *getSourceIntegralExpression() const {
+ assert(Argument.getKind() == TemplateArgument::Integral);
+ return LocInfo.getAsExpr();
+ }
+
NestedNameSpecifierLoc getTemplateQualifierLoc() const {
assert(Argument.getKind() == TemplateArgument::Template ||
Argument.getKind() == TemplateArgument::TemplateExpansion);
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index 6564b66548a4..6900a7d40af9 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -20,6 +20,7 @@
#include "clang/Basic/Linkage.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/Visibility.h"
+#include "clang/Basic/Specifiers.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/TemplateName.h"
#include "llvm/Support/type_traits.h"
@@ -160,6 +161,44 @@ public:
Qualifiers() : Mask(0) {}
+ /// \brief Returns the common set of qualifiers while removing them from
+ /// the given sets.
+ static Qualifiers removeCommonQualifiers(Qualifiers &L, Qualifiers &R) {
+ // If both are only CVR-qualified, bit operations are sufficient.
+ if (!(L.Mask & ~CVRMask) && !(R.Mask & ~CVRMask)) {
+ Qualifiers Q;
+ Q.Mask = L.Mask & R.Mask;
+ L.Mask &= ~Q.Mask;
+ R.Mask &= ~Q.Mask;
+ return Q;
+ }
+
+ Qualifiers Q;
+ unsigned CommonCRV = L.getCVRQualifiers() & R.getCVRQualifiers();
+ Q.addCVRQualifiers(CommonCRV);
+ L.removeCVRQualifiers(CommonCRV);
+ R.removeCVRQualifiers(CommonCRV);
+
+ if (L.getObjCGCAttr() == R.getObjCGCAttr()) {
+ Q.setObjCGCAttr(L.getObjCGCAttr());
+ L.removeObjCGCAttr();
+ R.removeObjCGCAttr();
+ }
+
+ if (L.getObjCLifetime() == R.getObjCLifetime()) {
+ Q.setObjCLifetime(L.getObjCLifetime());
+ L.removeObjCLifetime();
+ R.removeObjCLifetime();
+ }
+
+ if (L.getAddressSpace() == R.getAddressSpace()) {
+ Q.setAddressSpace(L.getAddressSpace());
+ L.removeAddressSpace();
+ R.removeAddressSpace();
+ }
+ return Q;
+ }
+
static Qualifiers fromFastMask(unsigned Mask) {
Qualifiers Qs;
Qs.addFastQualifiers(Mask);
@@ -333,6 +372,23 @@ public:
}
}
+ /// \brief Remove the qualifiers from the given set from this set.
+ void removeQualifiers(Qualifiers Q) {
+ // If the other set doesn't have any non-boolean qualifiers, just
+ // bit-and the inverse in.
+ if (!(Q.Mask & ~CVRMask))
+ Mask &= ~Q.Mask;
+ else {
+ Mask &= ~(Q.Mask & CVRMask);
+ if (getObjCGCAttr() == Q.getObjCGCAttr())
+ removeObjCGCAttr();
+ if (getObjCLifetime() == Q.getObjCLifetime())
+ removeObjCLifetime();
+ if (getAddressSpace() == Q.getAddressSpace())
+ removeAddressSpace();
+ }
+ }
+
/// \brief Add the qualifiers from the given set to this set, given that
/// they don't conflict.
void addConsistentQualifiers(Qualifiers qs) {
@@ -400,7 +456,7 @@ public:
}
Qualifiers &operator-=(Qualifiers R) {
- Mask = Mask & ~(R.Mask);
+ removeQualifiers(R);
return *this;
}
@@ -435,18 +491,6 @@ private:
static const uint32_t AddressSpaceShift = 8;
};
-/// CallingConv - Specifies the calling convention that a function uses.
-enum CallingConv {
- CC_Default,
- CC_C, // __attribute__((cdecl))
- CC_X86StdCall, // __attribute__((stdcall))
- CC_X86FastCall, // __attribute__((fastcall))
- CC_X86ThisCall, // __attribute__((thiscall))
- CC_X86Pascal, // __attribute__((pascal))
- CC_AAPCS, // __attribute__((pcs("aapcs")))
- CC_AAPCS_VFP // __attribute__((pcs("aapcs-vfp")))
-};
-
/// A std::pair-like structure for storing a qualified type split
/// into its local qualifiers and its locally-unqualified type.
struct SplitQualType {
@@ -1126,8 +1170,8 @@ public:
};
private:
- Type(const Type&); // DO NOT IMPLEMENT.
- void operator=(const Type&); // DO NOT IMPLEMENT.
+ Type(const Type &) LLVM_DELETED_FUNCTION;
+ void operator=(const Type &) LLVM_DELETED_FUNCTION;
/// Bitfields required by the Type class.
class TypeBitfields {
@@ -1225,7 +1269,7 @@ protected:
/// Extra information which affects how the function is called, like
/// regparm and the calling convention.
- unsigned ExtInfo : 8;
+ unsigned ExtInfo : 9;
/// TypeQuals - Used only by FunctionProtoType, put here to pack with the
/// other bitfields.
@@ -1512,6 +1556,7 @@ public:
bool isRecordType() const;
bool isClassType() const;
bool isStructureType() const;
+ bool isInterfaceType() const;
bool isStructureOrClassType() const;
bool isUnionType() const;
bool isComplexIntegerType() const; // GCC _Complex integer type.
@@ -1630,13 +1675,19 @@ public:
const ObjCObjectPointerType *getAsObjCQualifiedIdType() const;
const ObjCObjectPointerType *getAsObjCQualifiedClassType() const;
const ObjCObjectType *getAsObjCQualifiedInterfaceType() const;
- const CXXRecordDecl *getCXXRecordDeclForPointerType() const;
/// \brief Retrieves the CXXRecordDecl that this type refers to, either
/// because the type is a RecordType or because it is the injected-class-name
/// type of a class template or class template partial specialization.
CXXRecordDecl *getAsCXXRecordDecl() const;
+ /// If this is a pointer or reference to a RecordType, return the
+ /// CXXRecordDecl that that type refers to.
+ ///
+ /// If this is not a pointer or reference, or the type being pointed to does
+ /// not refer to a CXXRecordDecl, returns NULL.
+ const CXXRecordDecl *getPointeeCXXRecordDecl() const;
+
/// \brief Get the AutoType whose type will be deduced for a variable with
/// an initializer of this type. This looks through declarators like pointer
/// types, but not through decltype or typedefs.
@@ -1738,8 +1789,6 @@ public:
CanQualType getCanonicalTypeUnqualified() const; // in CanonicalType.h
LLVM_ATTRIBUTE_USED void dump() const;
- static bool classof(const Type *) { return true; }
-
friend class ASTReader;
friend class ASTWriter;
};
@@ -1748,6 +1797,11 @@ public:
/// until it reaches a TypedefType or a non-sugared type.
template <> const TypedefType *Type::getAs() const;
+/// \brief This will check for a TemplateSpecializationType by removing any
+/// existing sugar until it reaches a TemplateSpecializationType or a
+/// non-sugared type.
+template <> const TemplateSpecializationType *Type::getAs() const;
+
// We can do canonical leaf types faster, because we don't have to
// worry about preserving child type decoration.
#define TYPE(Class, Base)
@@ -1834,7 +1888,6 @@ public:
}
static bool classof(const Type *T) { return T->getTypeClass() == Builtin; }
- static bool classof(const BuiltinType *) { return true; }
};
/// ComplexType - C99 6.2.5p11 - Complex values. This supports the C99 complex
@@ -1865,7 +1918,6 @@ public:
}
static bool classof(const Type *T) { return T->getTypeClass() == Complex; }
- static bool classof(const ComplexType *) { return true; }
};
/// ParenType - Sugar for parentheses used when specifying types.
@@ -1897,7 +1949,6 @@ public:
}
static bool classof(const Type *T) { return T->getTypeClass() == Paren; }
- static bool classof(const ParenType *) { return true; }
};
/// PointerType - C99 6.7.5.1 - Pointer Declarators.
@@ -1929,7 +1980,6 @@ public:
}
static bool classof(const Type *T) { return T->getTypeClass() == Pointer; }
- static bool classof(const PointerType *) { return true; }
};
/// BlockPointerType - pointer to a block type.
@@ -1965,7 +2015,6 @@ public:
static bool classof(const Type *T) {
return T->getTypeClass() == BlockPointer;
}
- static bool classof(const BlockPointerType *) { return true; }
};
/// ReferenceType - Base for LValueReferenceType and RValueReferenceType
@@ -2013,7 +2062,6 @@ public:
return T->getTypeClass() == LValueReference ||
T->getTypeClass() == RValueReference;
}
- static bool classof(const ReferenceType *) { return true; }
};
/// LValueReferenceType - C++ [dcl.ref] - Lvalue reference
@@ -2031,7 +2079,6 @@ public:
static bool classof(const Type *T) {
return T->getTypeClass() == LValueReference;
}
- static bool classof(const LValueReferenceType *) { return true; }
};
/// RValueReferenceType - C++0x [dcl.ref] - Rvalue reference
@@ -2048,7 +2095,6 @@ public:
static bool classof(const Type *T) {
return T->getTypeClass() == RValueReference;
}
- static bool classof(const RValueReferenceType *) { return true; }
};
/// MemberPointerType - C++ 8.3.3 - Pointers to members
@@ -2103,7 +2149,6 @@ public:
static bool classof(const Type *T) {
return T->getTypeClass() == MemberPointer;
}
- static bool classof(const MemberPointerType *) { return true; }
};
/// ArrayType - C99 6.7.5.2 - Array Declarators.
@@ -2159,7 +2204,6 @@ public:
T->getTypeClass() == IncompleteArray ||
T->getTypeClass() == DependentSizedArray;
}
- static bool classof(const ArrayType *) { return true; }
};
/// ConstantArrayType - This class represents the canonical version of
@@ -2211,7 +2255,6 @@ public:
static bool classof(const Type *T) {
return T->getTypeClass() == ConstantArray;
}
- static bool classof(const ConstantArrayType *) { return true; }
};
/// IncompleteArrayType - This class represents C arrays with an unspecified
@@ -2231,7 +2274,6 @@ public:
static bool classof(const Type *T) {
return T->getTypeClass() == IncompleteArray;
}
- static bool classof(const IncompleteArrayType *) { return true; }
friend class StmtIteratorBase;
@@ -2294,7 +2336,6 @@ public:
static bool classof(const Type *T) {
return T->getTypeClass() == VariableArray;
}
- static bool classof(const VariableArrayType *) { return true; }
friend class StmtIteratorBase;
@@ -2351,7 +2392,6 @@ public:
static bool classof(const Type *T) {
return T->getTypeClass() == DependentSizedArray;
}
- static bool classof(const DependentSizedArrayType *) { return true; }
friend class StmtIteratorBase;
@@ -2397,7 +2437,6 @@ public:
static bool classof(const Type *T) {
return T->getTypeClass() == DependentSizedExtVector;
}
- static bool classof(const DependentSizedExtVectorType *) { return true; }
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, Context, getElementType(), getSizeExpr());
@@ -2463,7 +2502,6 @@ public:
static bool classof(const Type *T) {
return T->getTypeClass() == Vector || T->getTypeClass() == ExtVector;
}
- static bool classof(const VectorType *) { return true; }
};
/// ExtVectorType - Extended vector type. This type is created using
@@ -2529,7 +2567,6 @@ public:
static bool classof(const Type *T) {
return T->getTypeClass() == ExtVector;
}
- static bool classof(const ExtVectorType *) { return true; }
};
/// FunctionType - C99 6.7.5.3 - Function Declarators. This is the common base
@@ -2561,19 +2598,19 @@ class FunctionType : public Type {
// * AST read and write
// * Codegen
class ExtInfo {
- // Feel free to rearrange or add bits, but if you go over 8,
+ // Feel free to rearrange or add bits, but if you go over 9,
// you'll need to adjust both the Bits field below and
// Type::FunctionTypeBitfields.
// | CC |noreturn|produces|regparm|
- // |0 .. 2| 3 | 4 | 5 .. 7|
+ // |0 .. 3| 4 | 5 | 6 .. 8|
//
// regparm is either 0 (no regparm attribute) or the regparm value+1.
- enum { CallConvMask = 0x7 };
- enum { NoReturnMask = 0x8 };
- enum { ProducesResultMask = 0x10 };
+ enum { CallConvMask = 0xF };
+ enum { NoReturnMask = 0x10 };
+ enum { ProducesResultMask = 0x20 };
enum { RegParmMask = ~(CallConvMask | NoReturnMask | ProducesResultMask),
- RegParmOffset = 5 }; // Assumed to be the last field
+ RegParmOffset = 6 }; // Assumed to be the last field
uint16_t Bits;
@@ -2692,7 +2729,6 @@ public:
return T->getTypeClass() == FunctionNoProto ||
T->getTypeClass() == FunctionProto;
}
- static bool classof(const FunctionType *) { return true; }
};
/// FunctionNoProtoType - Represents a K&R-style 'int foo()' function, which has
@@ -2724,7 +2760,6 @@ public:
static bool classof(const Type *T) {
return T->getTypeClass() == FunctionNoProto;
}
- static bool classof(const FunctionNoProtoType *) { return true; }
};
/// FunctionProtoType - Represents a prototype with argument type info, e.g.
@@ -2972,14 +3007,13 @@ public:
// FIXME: Remove the string version.
void printExceptionSpecification(std::string &S,
- PrintingPolicy Policy) const;
+ const PrintingPolicy &Policy) const;
void printExceptionSpecification(raw_ostream &OS,
- PrintingPolicy Policy) const;
+ const PrintingPolicy &Policy) const;
static bool classof(const Type *T) {
return T->getTypeClass() == FunctionProto;
}
- static bool classof(const FunctionProtoType *) { return true; }
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx);
static void Profile(llvm::FoldingSetNodeID &ID, QualType Result,
@@ -3010,7 +3044,6 @@ public:
static bool classof(const Type *T) {
return T->getTypeClass() == UnresolvedUsing;
}
- static bool classof(const UnresolvedUsingType *) { return true; }
void Profile(llvm::FoldingSetNodeID &ID) {
return Profile(ID, Decl);
@@ -3042,7 +3075,6 @@ public:
QualType desugar() const;
static bool classof(const Type *T) { return T->getTypeClass() == Typedef; }
- static bool classof(const TypedefType *) { return true; }
};
/// TypeOfExprType (GCC extension).
@@ -3062,7 +3094,6 @@ public:
bool isSugared() const;
static bool classof(const Type *T) { return T->getTypeClass() == TypeOfExpr; }
- static bool classof(const TypeOfExprType *) { return true; }
};
/// \brief Internal representation of canonical, dependent
@@ -3109,7 +3140,6 @@ public:
bool isSugared() const { return true; }
static bool classof(const Type *T) { return T->getTypeClass() == TypeOf; }
- static bool classof(const TypeOfType *) { return true; }
};
/// DecltypeType (C++0x)
@@ -3131,7 +3161,6 @@ public:
bool isSugared() const;
static bool classof(const Type *T) { return T->getTypeClass() == Decltype; }
- static bool classof(const DecltypeType *) { return true; }
};
/// \brief Internal representation of canonical, dependent
@@ -3184,7 +3213,6 @@ public:
static bool classof(const Type *T) {
return T->getTypeClass() == UnaryTransform;
}
- static bool classof(const UnaryTransformType *) { return true; }
};
class TagType : public Type {
@@ -3207,7 +3235,6 @@ public:
static bool classof(const Type *T) {
return T->getTypeClass() >= TagFirst && T->getTypeClass() <= TagLast;
}
- static bool classof(const TagType *) { return true; }
};
/// RecordType - This is a helper class that allows the use of isa/cast/dyncast
@@ -3234,7 +3261,6 @@ public:
QualType desugar() const { return QualType(this, 0); }
static bool classof(const Type *T) { return T->getTypeClass() == Record; }
- static bool classof(const RecordType *) { return true; }
};
/// EnumType - This is a helper class that allows the use of isa/cast/dyncast
@@ -3253,7 +3279,6 @@ public:
QualType desugar() const { return QualType(this, 0); }
static bool classof(const Type *T) { return T->getTypeClass() == Enum; }
- static bool classof(const EnumType *) { return true; }
};
/// AttributedType - An attributed type is a type to which a type
@@ -3297,7 +3322,8 @@ public:
attr_fastcall,
attr_stdcall,
attr_thiscall,
- attr_pascal
+ attr_pascal,
+ attr_pnaclcall
};
private:
@@ -3341,7 +3367,6 @@ public:
static bool classof(const Type *T) {
return T->getTypeClass() == Attributed;
}
- static bool classof(const AttributedType *T) { return true; }
};
class TemplateTypeParmType : public Type, public llvm::FoldingSetNode {
@@ -3415,7 +3440,6 @@ public:
static bool classof(const Type *T) {
return T->getTypeClass() == TemplateTypeParm;
}
- static bool classof(const TemplateTypeParmType *T) { return true; }
};
/// \brief Represents the result of substituting a type for a template
@@ -3466,7 +3490,6 @@ public:
static bool classof(const Type *T) {
return T->getTypeClass() == SubstTemplateTypeParm;
}
- static bool classof(const SubstTemplateTypeParmType *T) { return true; }
};
/// \brief Represents the result of substituting a set of types for a template
@@ -3519,7 +3542,6 @@ public:
static bool classof(const Type *T) {
return T->getTypeClass() == SubstTemplateTypeParmPack;
}
- static bool classof(const SubstTemplateTypeParmPackType *T) { return true; }
};
/// \brief Represents a C++0x auto type.
@@ -3562,7 +3584,6 @@ public:
static bool classof(const Type *T) {
return T->getTypeClass() == Auto;
}
- static bool classof(const AutoType *T) { return true; }
};
/// \brief Represents a type template specialization; the template
@@ -3726,7 +3747,6 @@ public:
static bool classof(const Type *T) {
return T->getTypeClass() == TemplateSpecialization;
}
- static bool classof(const TemplateSpecializationType *T) { return true; }
};
/// \brief The injected class name of a C++ class template or class
@@ -3789,13 +3809,14 @@ public:
static bool classof(const Type *T) {
return T->getTypeClass() == InjectedClassName;
}
- static bool classof(const InjectedClassNameType *T) { return true; }
};
/// \brief The kind of a tag type.
enum TagTypeKind {
/// \brief The "struct" keyword.
TTK_Struct,
+ /// \brief The "__interface" keyword.
+ TTK_Interface,
/// \brief The "union" keyword.
TTK_Union,
/// \brief The "class" keyword.
@@ -3809,6 +3830,8 @@ 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.
@@ -3932,7 +3955,6 @@ public:
static bool classof(const Type *T) {
return T->getTypeClass() == Elaborated;
}
- static bool classof(const ElaboratedType *T) { return true; }
};
/// \brief Represents a qualified type name for which the type name is
@@ -3996,7 +4018,6 @@ public:
static bool classof(const Type *T) {
return T->getTypeClass() == DependentName;
}
- static bool classof(const DependentNameType *T) { return true; }
};
/// DependentTemplateSpecializationType - Represents a template
@@ -4067,9 +4088,6 @@ public:
static bool classof(const Type *T) {
return T->getTypeClass() == DependentTemplateSpecialization;
}
- static bool classof(const DependentTemplateSpecializationType *T) {
- return true;
- }
};
/// \brief Represents a pack expansion of types.
@@ -4150,9 +4168,6 @@ public:
static bool classof(const Type *T) {
return T->getTypeClass() == PackExpansion;
}
- static bool classof(const PackExpansionType *T) {
- return true;
- }
};
/// ObjCObjectType - Represents a class type in Objective C.
@@ -4263,7 +4278,6 @@ public:
return T->getTypeClass() == ObjCObject ||
T->getTypeClass() == ObjCInterface;
}
- static bool classof(const ObjCObjectType *) { return true; }
};
/// ObjCObjectTypeImpl - A class providing a concrete implementation
@@ -4327,7 +4341,6 @@ public:
static bool classof(const Type *T) {
return T->getTypeClass() == ObjCInterface;
}
- static bool classof(const ObjCInterfaceType *) { return true; }
// Nonsense to "hide" certain members of ObjCObjectType within this
// class. People asking for protocols on an ObjCInterfaceType are
@@ -4477,7 +4490,6 @@ public:
static bool classof(const Type *T) {
return T->getTypeClass() == ObjCObjectPointer;
}
- static bool classof(const ObjCObjectPointerType *) { return true; }
};
class AtomicType : public Type, public llvm::FoldingSetNode {
@@ -4508,7 +4520,6 @@ class AtomicType : public Type, public llvm::FoldingSetNode {
static bool classof(const Type *T) {
return T->getTypeClass() == Atomic;
}
- static bool classof(const AtomicType *) { return true; }
};
/// A qualifier set is used to build a set of qualifiers.
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
index 11a878d6b0f3..8a04bd8d5ee0 100644
--- a/include/clang/AST/TypeLoc.h
+++ b/include/clang/AST/TypeLoc.h
@@ -159,8 +159,6 @@ public:
return !(LHS == RHS);
}
- static bool classof(const TypeLoc *TL) { return true; }
-
private:
static void initializeImpl(ASTContext &Context, TypeLoc TL,
SourceLocation Loc);
@@ -192,7 +190,6 @@ public:
static bool classof(const TypeLoc *TL) {
return !TL->getType().hasLocalQualifiers();
}
- static bool classof(const UnqualTypeLoc *TL) { return true; }
};
/// \brief Wrapper of type source information for a type with
@@ -237,7 +234,6 @@ public:
static bool classof(const TypeLoc *TL) {
return TL->getType().hasLocalQualifiers();
}
- static bool classof(const QualifiedTypeLoc *TL) { return true; }
};
inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const {
@@ -250,11 +246,11 @@ inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const {
/// to a particular Type subclass. It is accepted for a single
/// TypeLoc class to correspond to multiple Type classes.
///
-/// \param Base a class from which to derive
-/// \param Derived the class deriving from this one
-/// \param TypeClass the concrete Type subclass associated with this
+/// \tparam Base a class from which to derive
+/// \tparam Derived the class deriving from this one
+/// \tparam TypeClass the concrete Type subclass associated with this
/// location type
-/// \param LocalData the structure type of local location data for
+/// \tparam LocalData the structure type of local location data for
/// this type
///
/// sizeof(LocalData) needs to be a multiple of sizeof(void*) or
@@ -303,9 +299,6 @@ public:
static bool classof(const UnqualTypeLoc *TL) {
return Derived::classofType(TL->getTypePtr());
}
- static bool classof(const Derived *TL) {
- return true;
- }
TypeLoc getNextTypeLoc() const {
return getNextTypeLoc(asDerived()->getInnerType());
@@ -380,9 +373,6 @@ public:
static bool classof(const UnqualTypeLoc *TL) {
return Derived::classofType(TL->getTypePtr());
}
- static bool classof(const Derived *TL) {
- return true;
- }
const TypeClass *getTypePtr() const {
return cast<TypeClass>(Base::getTypePtr());
@@ -417,7 +407,6 @@ public:
}
static bool classof(const TypeLoc *TL);
- static bool classof(const TypeSpecTypeLoc *TL) { return true; }
};
@@ -866,6 +855,7 @@ public:
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setNameLoc(Loc);
+ setNameEndLoc(Loc);
}
};
@@ -1060,6 +1050,8 @@ public:
struct FunctionLocInfo {
SourceLocation LocalRangeBegin;
+ SourceLocation LParenLoc;
+ SourceLocation RParenLoc;
SourceLocation LocalRangeEnd;
};
@@ -1083,6 +1075,24 @@ public:
getLocalData()->LocalRangeEnd = L;
}
+ SourceLocation getLParenLoc() const {
+ return this->getLocalData()->LParenLoc;
+ }
+ void setLParenLoc(SourceLocation Loc) {
+ this->getLocalData()->LParenLoc = Loc;
+ }
+
+ SourceLocation getRParenLoc() const {
+ return this->getLocalData()->RParenLoc;
+ }
+ void setRParenLoc(SourceLocation Loc) {
+ this->getLocalData()->RParenLoc = Loc;
+ }
+
+ SourceRange getParensRange() const {
+ return SourceRange(getLParenLoc(), getRParenLoc());
+ }
+
ArrayRef<ParmVarDecl *> getParams() const {
return ArrayRef<ParmVarDecl *>(getParmArray(), getNumArgs());
}
@@ -1110,6 +1120,8 @@ public:
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setLocalRangeBegin(Loc);
+ setLParenLoc(Loc);
+ setRParenLoc(Loc);
setLocalRangeEnd(Loc);
for (unsigned i = 0, e = getNumArgs(); i != e; ++i)
setArg(i, NULL);
diff --git a/include/clang/AST/UnresolvedSet.h b/include/clang/AST/UnresolvedSet.h
index 0918dc44aa73..9f11ee5fe3e2 100644
--- a/include/clang/AST/UnresolvedSet.h
+++ b/include/clang/AST/UnresolvedSet.h
@@ -94,7 +94,7 @@ class UnresolvedSetImpl {
private:
template <unsigned N> friend class UnresolvedSet;
UnresolvedSetImpl() {}
- UnresolvedSetImpl(const UnresolvedSetImpl &) {}
+ UnresolvedSetImpl(const UnresolvedSetImpl &) LLVM_DELETED_FUNCTION;
public:
// We don't currently support assignment through this iterator, so we might
diff --git a/include/clang/AST/VTableBuilder.h b/include/clang/AST/VTableBuilder.h
index 392dad94a4a3..a6aa40b9d68b 100644
--- a/include/clang/AST/VTableBuilder.h
+++ b/include/clang/AST/VTableBuilder.h
@@ -147,9 +147,10 @@ private:
assert((ComponentKind == CK_VCallOffset ||
ComponentKind == CK_VBaseOffset ||
ComponentKind == CK_OffsetToTop) && "Invalid component kind!");
- assert(Offset.getQuantity() <= ((1LL << 56) - 1) && "Offset is too big!");
+ assert(Offset.getQuantity() < (1LL << 56) && "Offset is too big!");
+ assert(Offset.getQuantity() >= -(1LL << 56) && "Offset is too small!");
- Value = ((Offset.getQuantity() << 3) | ComponentKind);
+ Value = (uint64_t(Offset.getQuantity()) << 3) | ComponentKind;
}
VTableComponent(Kind ComponentKind, uintptr_t Ptr) {
diff --git a/include/clang/ASTMatchers/ASTMatchFinder.h b/include/clang/ASTMatchers/ASTMatchFinder.h
index dd237eece3e4..30b4050e1c81 100644
--- a/include/clang/ASTMatchers/ASTMatchFinder.h
+++ b/include/clang/ASTMatchers/ASTMatchFinder.h
@@ -85,7 +85,14 @@ public:
class MatchCallback {
public:
virtual ~MatchCallback();
+
+ /// \brief Called on every match by the \c MatchFinder.
virtual void run(const MatchResult &Result) = 0;
+
+ /// \brief Called at the start of each translation unit.
+ ///
+ /// Optionally override to do per translation unit tasks.
+ virtual void onStartOfTranslationUnit() {}
};
/// \brief Called when parsing is finished. Intended for testing only.
@@ -112,11 +119,24 @@ public:
MatchCallback *Action);
void addMatcher(const StatementMatcher &NodeMatch,
MatchCallback *Action);
+ void addMatcher(const NestedNameSpecifierMatcher &NodeMatch,
+ MatchCallback *Action);
+ void addMatcher(const NestedNameSpecifierLocMatcher &NodeMatch,
+ MatchCallback *Action);
+ void addMatcher(const TypeLocMatcher &NodeMatch,
+ MatchCallback *Action);
/// @}
/// \brief Creates a clang ASTConsumer that finds all matches.
clang::ASTConsumer *newASTConsumer();
+ /// \brief Finds all matches on the given \c Node.
+ ///
+ /// @{
+ void findAll(const Decl &Node, ASTContext &Context);
+ void findAll(const Stmt &Node, ASTContext &Context);
+ /// @}
+
/// \brief Registers a callback to notify the end of parsing.
///
/// The provided closure is called after parsing is done, before the AST is
@@ -125,11 +145,10 @@ public:
void registerTestCallbackAfterParsing(ParsingDoneTestCallback *ParsingDone);
private:
- /// \brief The MatchCallback*'s will be called every time the
- /// UntypedBaseMatcher matches on the AST.
- std::vector< std::pair<
- const internal::UntypedBaseMatcher*,
- MatchCallback*> > Triggers;
+ /// \brief For each \c DynTypedMatcher a \c MatchCallback that will be called
+ /// when it matches.
+ std::vector<std::pair<const internal::DynTypedMatcher*, MatchCallback*> >
+ MatcherCallbackPairs;
/// \brief Called when parsing is done.
ParsingDoneTestCallback *ParsingDone;
diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h
index 33ef3dc8d6e0..a70dd5c378bd 100644
--- a/include/clang/ASTMatchers/ASTMatchers.h
+++ b/include/clang/ASTMatchers/ASTMatchers.h
@@ -14,7 +14,7 @@
// a functional in-language DSL to express queries over the C++ AST.
//
// For example, to match a class with a certain name, one would call:
-// record(hasName("MyClass"))
+// recordDecl(hasName("MyClass"))
// which returns a matcher that can be used to find all AST nodes that declare
// a class named 'MyClass'.
//
@@ -25,7 +25,7 @@
//
// For example, when we're interested in child classes of a certain class, we
// would write:
-// record(hasName("MyClass"), hasChild(id("child", record())))
+// recordDecl(hasName("MyClass"), hasChild(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
@@ -57,52 +57,47 @@ namespace ast_matchers {
/// \brief Maps string IDs to AST nodes matched by parts of a matcher.
///
-/// The bound nodes are generated by adding id(...) matchers into the
-/// match expression around the matchers for the nodes we want to access later.
+/// The bound nodes are generated by calling \c bind("id") on the node matchers
+/// of the nodes we want to access later.
///
-/// The instances of BoundNodes are created by MatchFinder when the user's
+/// The instances of BoundNodes are created by \c MatchFinder when the user's
/// callbacks are executed every time a match is found.
class BoundNodes {
public:
- /// \brief Returns the AST node bound to 'ID'.
- /// Returns NULL if there was no node bound to 'ID' or if there is a node but
+ /// \brief Returns the AST node bound to \c ID.
+ ///
+ /// Returns NULL if there was no node bound to \c ID or if there is a node but
/// it cannot be converted to the specified type.
- /// FIXME: We'll need one of those for every base type.
+ template <typename T>
+ const T *getNodeAs(StringRef ID) const {
+ return MyBoundNodes.getNodeAs<T>(ID);
+ }
+
+ /// \brief Deprecated. Please use \c getNodeAs instead.
/// @{
template <typename T>
const T *getDeclAs(StringRef ID) const {
- return getNodeAs<T>(DeclBindings, ID);
+ return getNodeAs<T>(ID);
}
template <typename T>
const T *getStmtAs(StringRef ID) const {
- return getNodeAs<T>(StmtBindings, ID);
+ return getNodeAs<T>(ID);
}
/// @}
private:
/// \brief Create BoundNodes from a pre-filled map of bindings.
- BoundNodes(const std::map<std::string, const Decl*> &DeclBindings,
- const std::map<std::string, const Stmt*> &StmtBindings)
- : DeclBindings(DeclBindings), StmtBindings(StmtBindings) {}
-
- template <typename T, typename MapT>
- const T *getNodeAs(const MapT &Bindings, StringRef ID) const {
- typename MapT::const_iterator It = Bindings.find(ID);
- if (It == Bindings.end()) {
- return NULL;
- }
- return llvm::dyn_cast<T>(It->second);
- }
+ BoundNodes(internal::BoundNodesMap &MyBoundNodes)
+ : MyBoundNodes(MyBoundNodes) {}
- std::map<std::string, const Decl*> DeclBindings;
- std::map<std::string, const Stmt*> StmtBindings;
+ internal::BoundNodesMap MyBoundNodes;
friend class internal::BoundNodesTree;
};
-/// \brief If the provided matcher matches a node, binds the node to 'ID'.
+/// \brief If the provided matcher matches a node, binds the node to \c ID.
///
-/// FIXME: Add example for accessing it.
+/// FIXME: Do we want to support this now that we have bind()?
template <typename T>
internal::Matcher<T> id(const std::string &ID,
const internal::BindableMatcher<T> &InnerMatcher) {
@@ -113,20 +108,27 @@ internal::Matcher<T> id(const std::string &ID,
/// hierarchy.
/// @{
typedef internal::Matcher<Decl> DeclarationMatcher;
-typedef internal::Matcher<QualType> TypeMatcher;
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;
/// @}
/// \brief Matches any node.
///
/// Useful when another matcher requires a child matcher, but there's no
/// additional constraint. This will often be used with an explicit conversion
-/// to a internal::Matcher<> type such as TypeMatcher.
+/// to an \c internal::Matcher<> type such as \c TypeMatcher.
///
-/// Example: DeclarationMatcher(anything()) matches all declarations, e.g.,
+/// Example: \c DeclarationMatcher(anything()) matches all declarations, e.g.,
+/// \code
/// "int* p" and "void f()" in
/// int* p;
/// void f();
+/// \endcode
+///
+/// Usable as: Any Matcher
inline internal::PolymorphicMatcherWithParam0<internal::TrueMatcher> anything() {
return internal::PolymorphicMatcherWithParam0<internal::TrueMatcher>();
}
@@ -144,53 +146,69 @@ const internal::VariadicDynCastAllOfMatcher<Decl, Decl> decl;
/// \brief Matches a declaration of anything that could have a name.
///
-/// Example matches X, S, the anonymous union type, i, and U;
+/// Example matches \c X, \c S, the anonymous union type, \c i, and \c U;
+/// \code
/// typedef int X;
/// struct S {
/// union {
/// int i;
/// } U;
/// };
-const internal::VariadicDynCastAllOfMatcher<
- Decl,
- NamedDecl> nameableDeclaration;
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<Decl, NamedDecl> namedDecl;
/// \brief Matches C++ class declarations.
///
-/// Example matches X, Z
+/// Example matches \c X, \c Z
+/// \code
/// class X;
/// template<class T> class Z {};
+/// \endcode
const internal::VariadicDynCastAllOfMatcher<
Decl,
- CXXRecordDecl> record;
+ CXXRecordDecl> recordDecl;
+
+/// \brief Matches C++ class template declarations.
+///
+/// Example matches \c Z
+/// \code
+/// template<class T> class Z {};
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+ Decl,
+ ClassTemplateDecl> classTemplateDecl;
/// \brief Matches C++ class template specializations.
///
/// Given
+/// \code
/// template<typename T> class A {};
/// template<> class A<double> {};
/// A<int> a;
-/// classTemplateSpecialization()
+/// \endcode
+/// classTemplateSpecializationDecl()
/// matches the specializations \c A<int> and \c A<double>
const internal::VariadicDynCastAllOfMatcher<
Decl,
- ClassTemplateSpecializationDecl> classTemplateSpecialization;
+ ClassTemplateSpecializationDecl> classTemplateSpecializationDecl;
/// \brief Matches classTemplateSpecializations that have at least one
-/// TemplateArgument matching the given Matcher.
+/// TemplateArgument matching the given InnerMatcher.
///
/// Given
+/// \code
/// template<typename T> class A {};
/// template<> class A<double> {};
/// A<int> a;
-/// classTemplateSpecialization(hasAnyTemplateArgument(
+/// \endcode
+/// classTemplateSpecializationDecl(hasAnyTemplateArgument(
/// refersToType(asString("int"))))
/// matches the specialization \c A<int>
AST_MATCHER_P(ClassTemplateSpecializationDecl, hasAnyTemplateArgument,
- internal::Matcher<TemplateArgument>, Matcher) {
+ internal::Matcher<TemplateArgument>, InnerMatcher) {
const TemplateArgumentList &List = Node.getTemplateArgs();
for (unsigned i = 0; i < List.size(); ++i) {
- if (Matcher.matches(List.get(i), Finder, Builder))
+ if (InnerMatcher.matches(List.get(i), Finder, Builder))
return true;
}
return false;
@@ -201,19 +219,25 @@ AST_MATCHER_P(ClassTemplateSpecializationDecl, hasAnyTemplateArgument,
///
/// Parentheses and explicit casts are not discarded.
/// Given
+/// \code
/// int arr[5];
/// int a = 0;
/// char b = 0;
/// const int c = a;
/// int *d = arr;
/// long e = (long) 0l;
+/// \endcode
/// The matchers
-/// variable(hasInitializer(ignoringImpCasts(integerLiteral())))
-/// variable(hasInitializer(ignoringImpCasts(declarationReference())))
+/// \code
+/// varDecl(hasInitializer(ignoringImpCasts(integerLiteral())))
+/// varDecl(hasInitializer(ignoringImpCasts(declRefExpr())))
+/// \endcode
/// would match the declarations for a, b, c, and d, but not e.
-/// while
-/// variable(hasInitializer(integerLiteral()))
-/// variable(hasInitializer(declarationReference()))
+/// While
+/// \code
+/// varDecl(hasInitializer(integerLiteral()))
+/// varDecl(hasInitializer(declRefExpr()))
+/// \endcode
/// only match the declarations for b, c, and d.
AST_MATCHER_P(Expr, ignoringImpCasts,
internal::Matcher<Expr>, InnerMatcher) {
@@ -225,15 +249,17 @@ AST_MATCHER_P(Expr, ignoringImpCasts,
///
/// Implicit and non-C Style casts are also discarded.
/// Given
+/// \code
/// int a = 0;
/// char b = (0);
/// void* c = reinterpret_cast<char*>(0);
/// char d = char(0);
+/// \endcode
/// The matcher
-/// variable(hasInitializer(ignoringParenCasts(integerLiteral())))
+/// varDecl(hasInitializer(ignoringParenCasts(integerLiteral())))
/// would match the declarations for a, b, c, and d.
/// while
-/// variable(hasInitializer(integerLiteral()))
+/// varDecl(hasInitializer(integerLiteral()))
/// only match the declaration for a.
AST_MATCHER_P(Expr, ignoringParenCasts, internal::Matcher<Expr>, InnerMatcher) {
return InnerMatcher.matches(*Node.IgnoreParenCasts(), Finder, Builder);
@@ -244,21 +270,21 @@ AST_MATCHER_P(Expr, ignoringParenCasts, internal::Matcher<Expr>, InnerMatcher) {
///
/// Explicit casts are not discarded.
/// Given
+/// \code
/// int arr[5];
/// int a = 0;
/// char b = (0);
/// const int c = a;
/// int *d = (arr);
/// long e = ((long) 0l);
+/// \endcode
/// The matchers
-/// variable(hasInitializer(ignoringParenImpCasts(
-/// integerLiteral())))
-/// variable(hasInitializer(ignoringParenImpCasts(
-/// declarationReference())))
+/// varDecl(hasInitializer(ignoringParenImpCasts(integerLiteral())))
+/// varDecl(hasInitializer(ignoringParenImpCasts(declRefExpr())))
/// would match the declarations for a, b, c, and d, but not e.
/// while
-/// variable(hasInitializer(integerLiteral()))
-/// variable(hasInitializer(declarationReference()))
+/// varDecl(hasInitializer(integerLiteral()))
+/// varDecl(hasInitializer(declRefExpr()))
/// would only match the declaration for a.
AST_MATCHER_P(Expr, ignoringParenImpCasts,
internal::Matcher<Expr>, InnerMatcher) {
@@ -266,101 +292,119 @@ AST_MATCHER_P(Expr, ignoringParenImpCasts,
}
/// \brief Matches classTemplateSpecializations where the n'th TemplateArgument
-/// matches the given Matcher.
+/// matches the given InnerMatcher.
///
/// Given
+/// \code
/// template<typename T, typename U> class A {};
/// A<bool, int> b;
/// A<int, bool> c;
-/// classTemplateSpecialization(hasTemplateArgument(
+/// \endcode
+/// classTemplateSpecializationDecl(hasTemplateArgument(
/// 1, refersToType(asString("int"))))
/// matches the specialization \c A<bool, int>
AST_MATCHER_P2(ClassTemplateSpecializationDecl, hasTemplateArgument,
- unsigned, N, internal::Matcher<TemplateArgument>, Matcher) {
+ unsigned, N, internal::Matcher<TemplateArgument>, InnerMatcher) {
const TemplateArgumentList &List = Node.getTemplateArgs();
if (List.size() <= N)
return false;
- return Matcher.matches(List.get(N), Finder, Builder);
+ return InnerMatcher.matches(List.get(N), Finder, Builder);
}
/// \brief Matches a TemplateArgument that refers to a certain type.
///
/// Given
+/// \code
/// struct X {};
/// template<typename T> struct A {};
/// A<X> a;
-/// classTemplateSpecialization(hasAnyTemplateArgument(
+/// \endcode
+/// classTemplateSpecializationDecl(hasAnyTemplateArgument(
/// refersToType(class(hasName("X")))))
/// matches the specialization \c A<X>
AST_MATCHER_P(TemplateArgument, refersToType,
- internal::Matcher<QualType>, Matcher) {
+ internal::Matcher<QualType>, InnerMatcher) {
if (Node.getKind() != TemplateArgument::Type)
return false;
- return Matcher.matches(Node.getAsType(), Finder, Builder);
+ return InnerMatcher.matches(Node.getAsType(), Finder, Builder);
}
/// \brief Matches a TemplateArgument that refers to a certain declaration.
///
/// Given
+/// \code
/// template<typename T> struct A {};
/// struct B { B* next; };
/// A<&B::next> a;
-/// classTemplateSpecialization(hasAnyTemplateArgument(
-/// refersToDeclaration(field(hasName("next"))))
-/// matches the specialization \c A<&B::next> with \c field(...) matching
+/// \endcode
+/// classTemplateSpecializationDecl(hasAnyTemplateArgument(
+/// refersToDeclaration(fieldDecl(hasName("next"))))
+/// matches the specialization \c A<&B::next> with \c fieldDecl(...) matching
/// \c B::next
AST_MATCHER_P(TemplateArgument, refersToDeclaration,
- internal::Matcher<Decl>, Matcher) {
- if (const Decl *Declaration = Node.getAsDecl())
- return Matcher.matches(*Declaration, Finder, Builder);
+ internal::Matcher<Decl>, InnerMatcher) {
+ if (Node.getKind() == TemplateArgument::Declaration)
+ return InnerMatcher.matches(*Node.getAsDecl(), Finder, Builder);
return false;
}
/// \brief Matches C++ constructor declarations.
///
/// Example matches Foo::Foo() and Foo::Foo(int)
+/// \code
/// class Foo {
/// public:
/// Foo();
/// Foo(int);
/// int DoSomething();
/// };
+/// \endcode
const internal::VariadicDynCastAllOfMatcher<
Decl,
- CXXConstructorDecl> constructor;
+ CXXConstructorDecl> constructorDecl;
/// \brief Matches explicit C++ destructor declarations.
///
/// Example matches Foo::~Foo()
+/// \code
/// class Foo {
/// public:
/// virtual ~Foo();
/// };
-const internal::VariadicDynCastAllOfMatcher<Decl, CXXDestructorDecl> destructor;
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+ Decl,
+ CXXDestructorDecl> destructorDecl;
/// \brief Matches enum declarations.
///
/// Example matches X
+/// \code
/// enum X {
/// A, B, C
/// };
+/// \endcode
const internal::VariadicDynCastAllOfMatcher<Decl, EnumDecl> enumDecl;
/// \brief Matches enum constants.
///
/// Example matches A, B, C
+/// \code
/// enum X {
/// A, B, C
/// };
+/// \endcode
const internal::VariadicDynCastAllOfMatcher<
Decl,
- EnumConstantDecl> enumConstant;
+ EnumConstantDecl> enumConstantDecl;
/// \brief Matches method declarations.
///
/// Example matches y
+/// \code
/// class X { void y() };
-const internal::VariadicDynCastAllOfMatcher<Decl, CXXMethodDecl> method;
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<Decl, CXXMethodDecl> methodDecl;
/// \brief Matches variable declarations.
///
@@ -368,76 +412,111 @@ const internal::VariadicDynCastAllOfMatcher<Decl, CXXMethodDecl> method;
/// "field" declarations in Clang parlance.
///
/// Example matches a
+/// \code
/// int a;
-const internal::VariadicDynCastAllOfMatcher<Decl, VarDecl> variable;
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<Decl, VarDecl> varDecl;
/// \brief Matches field declarations.
///
/// Given
+/// \code
/// class X { int m; };
-/// field()
+/// \endcode
+/// fieldDecl()
/// matches 'm'.
-const internal::VariadicDynCastAllOfMatcher<Decl, FieldDecl> field;
+const internal::VariadicDynCastAllOfMatcher<Decl, FieldDecl> fieldDecl;
/// \brief Matches function declarations.
///
/// Example matches f
+/// \code
/// void f();
-const internal::VariadicDynCastAllOfMatcher<Decl, FunctionDecl> function;
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<Decl, FunctionDecl> functionDecl;
+/// \brief Matches C++ function template declarations.
+///
+/// Example matches f
+/// \code
+/// template<class T> void f(T t) {}
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+ Decl,
+ FunctionTemplateDecl> functionTemplateDecl;
/// \brief Matches statements.
///
/// Given
+/// \code
/// { ++a; }
-/// statement()
+/// \endcode
+/// stmt()
/// matches both the compound statement '{ ++a; }' and '++a'.
-const internal::VariadicDynCastAllOfMatcher<Stmt, Stmt> statement;
+const internal::VariadicDynCastAllOfMatcher<Stmt, Stmt> stmt;
/// \brief Matches declaration statements.
///
/// Given
+/// \code
/// int a;
-/// declarationStatement()
+/// \endcode
+/// declStmt()
/// matches 'int a'.
const internal::VariadicDynCastAllOfMatcher<
Stmt,
- DeclStmt> declarationStatement;
+ DeclStmt> declStmt;
/// \brief Matches member expressions.
///
/// Given
+/// \code
/// class Y {
/// void x() { this->x(); x(); Y y; y.x(); a; this->b; Y::b; }
/// int a; static int b;
/// };
-/// memberExpression()
+/// \endcode
+/// memberExpr()
/// matches this->x, x, y.x, a, this->b
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- MemberExpr> memberExpression;
+const internal::VariadicDynCastAllOfMatcher<Stmt, MemberExpr> memberExpr;
/// \brief Matches call expressions.
///
/// Example matches x.y() and y()
+/// \code
/// X x;
/// x.y();
/// y();
-const internal::VariadicDynCastAllOfMatcher<Stmt, CallExpr> call;
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<Stmt, CallExpr> callExpr;
+
+/// \brief Matches lambda expressions.
+///
+/// Example matches [&](){return 5;}
+/// \code
+/// [&](){return 5;}
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<Stmt, LambdaExpr> lambdaExpr;
/// \brief Matches member call expressions.
///
/// Example matches x.y()
+/// \code
/// X x;
/// x.y();
-const internal::VariadicDynCastAllOfMatcher<Stmt, CXXMemberCallExpr> memberCall;
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+ Stmt,
+ CXXMemberCallExpr> memberCallExpr;
/// \brief Matches init list expressions.
///
/// Given
+/// \code
/// int a[] = { 1, 2 };
/// struct B { int x, y; };
/// B b = { 5, 6 };
+/// \endcode
/// initList()
/// matches "{ 1, 2 }" and "{ 5, 6 }"
const internal::VariadicDynCastAllOfMatcher<Stmt, InitListExpr> initListExpr;
@@ -445,8 +524,10 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, InitListExpr> initListExpr;
/// \brief Matches using declarations.
///
/// Given
+/// \code
/// namespace X { int x; }
/// using X::x;
+/// \endcode
/// usingDecl()
/// matches \code using X::x \endcode
const internal::VariadicDynCastAllOfMatcher<Decl, UsingDecl> usingDecl;
@@ -454,49 +535,89 @@ const internal::VariadicDynCastAllOfMatcher<Decl, UsingDecl> usingDecl;
/// \brief Matches constructor call expressions (including implicit ones).
///
/// Example matches string(ptr, n) and ptr within arguments of f
-/// (matcher = constructorCall())
+/// (matcher = constructExpr())
+/// \code
/// void f(const string &a, const string &b);
/// char *ptr;
/// int n;
/// f(string(ptr, n), ptr);
+/// \endcode
const internal::VariadicDynCastAllOfMatcher<
Stmt,
- CXXConstructExpr> constructorCall;
+ CXXConstructExpr> constructExpr;
+
+/// \brief Matches implicit and explicit this expressions.
+///
+/// Example matches the implicit this expression in "return i".
+/// (matcher = thisExpr())
+/// \code
+/// struct foo {
+/// int i;
+/// int f() { return i; }
+/// };
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThisExpr> thisExpr;
/// \brief Matches nodes where temporaries are created.
///
/// Example matches FunctionTakesString(GetStringByValue())
-/// (matcher = bindTemporaryExpression())
+/// (matcher = bindTemporaryExpr())
+/// \code
/// FunctionTakesString(GetStringByValue());
/// FunctionTakesStringByPointer(GetStringPointer());
+/// \endcode
const internal::VariadicDynCastAllOfMatcher<
Stmt,
- CXXBindTemporaryExpr> bindTemporaryExpression;
+ CXXBindTemporaryExpr> bindTemporaryExpr;
+
+/// \brief Matches nodes where temporaries are materialized.
+///
+/// Example: Given
+/// \code
+/// struct T {void func()};
+/// T f();
+/// void g(T);
+/// \endcode
+/// materializeTemporaryExpr() matches 'f()' in these statements
+/// \code
+/// T u(f());
+/// g(f());
+/// \endcode
+/// but does not match
+/// \code
+/// f();
+/// f().func();
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+ Stmt,
+ MaterializeTemporaryExpr> materializeTemporaryExpr;
/// \brief Matches new expressions.
///
/// Given
+/// \code
/// new X;
-/// newExpression()
+/// \endcode
+/// newExpr()
/// matches 'new X'.
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CXXNewExpr> newExpression;
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNewExpr> newExpr;
/// \brief Matches delete expressions.
///
/// Given
+/// \code
/// delete X;
-/// deleteExpression()
+/// \endcode
+/// deleteExpr()
/// matches 'delete X'.
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CXXDeleteExpr> deleteExpression;
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDeleteExpr> deleteExpr;
/// \brief Matches array subscript expressions.
///
/// Given
+/// \code
/// int i = a[1];
+/// \endcode
/// arraySubscriptExpr()
/// matches "a[1]"
const internal::VariadicDynCastAllOfMatcher<
@@ -507,12 +628,14 @@ const internal::VariadicDynCastAllOfMatcher<
///
/// Example matches the CXXDefaultArgExpr placeholder inserted for the
/// default value of the second parameter in the call expression f(42)
-/// (matcher = defaultArgument())
+/// (matcher = defaultArgExpr())
+/// \code
/// void f(int x, int y = 0);
/// f(42);
+/// \endcode
const internal::VariadicDynCastAllOfMatcher<
Stmt,
- CXXDefaultArgExpr> defaultArgument;
+ CXXDefaultArgExpr> defaultArgExpr;
/// \brief Matches overloaded operator calls.
///
@@ -522,50 +645,67 @@ const internal::VariadicDynCastAllOfMatcher<
/// FIXME: figure out why these do not match?
///
/// Example matches both operator<<((o << b), c) and operator<<(o, b)
-/// (matcher = overloadedOperatorCall())
+/// (matcher = operatorCallExpr())
+/// \code
/// ostream &operator<< (ostream &out, int i) { };
/// ostream &o; int b = 1, c = 1;
/// o << b << c;
+/// \endcode
const internal::VariadicDynCastAllOfMatcher<
Stmt,
- CXXOperatorCallExpr> overloadedOperatorCall;
+ CXXOperatorCallExpr> operatorCallExpr;
/// \brief Matches expressions.
///
/// Example matches x()
+/// \code
/// void f() { x(); }
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- Expr> expression;
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<Stmt, Expr> expr;
/// \brief Matches expressions that refer to declarations.
///
/// Example matches x in if (x)
+/// \code
/// bool x;
/// if (x) {}
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- DeclRefExpr> declarationReference;
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<Stmt, DeclRefExpr> declRefExpr;
/// \brief Matches if statements.
///
/// Example matches 'if (x) {}'
+/// \code
/// if (x) {}
+/// \endcode
const internal::VariadicDynCastAllOfMatcher<Stmt, IfStmt> ifStmt;
/// \brief Matches for statements.
///
/// Example matches 'for (;;) {}'
+/// \code
/// for (;;) {}
-const internal::VariadicDynCastAllOfMatcher<
- Stmt, ForStmt> forStmt;
+/// int i[] = {1, 2, 3}; for (auto a : i);
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<Stmt, ForStmt> forStmt;
+
+/// \brief Matches range-based for statements.
+///
+/// forRangeStmt() matches 'for (auto a : i)'
+/// \code
+/// int i[] = {1, 2, 3}; for (auto a : i);
+/// for(int j = 0; j < 5; ++j);
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXForRangeStmt> forRangeStmt;
/// \brief Matches the increment statement of a for loop.
///
/// Example:
/// forStmt(hasIncrement(unaryOperator(hasOperatorName("++"))))
/// matches '++x' in
+/// \code
/// for (x; x < N; ++x) { }
+/// \endcode
AST_MATCHER_P(ForStmt, hasIncrement, internal::Matcher<Stmt>,
InnerMatcher) {
const Stmt *const Increment = Node.getInc();
@@ -576,9 +716,11 @@ AST_MATCHER_P(ForStmt, hasIncrement, internal::Matcher<Stmt>,
/// \brief Matches the initialization statement of a for loop.
///
/// Example:
-/// forStmt(hasLoopInit(declarationStatement()))
+/// forStmt(hasLoopInit(declStmt()))
/// matches 'int x = 0' in
+/// \code
/// for (int x = 0; x < N; ++x) { }
+/// \endcode
AST_MATCHER_P(ForStmt, hasLoopInit, internal::Matcher<Stmt>,
InnerMatcher) {
const Stmt *const Init = Node.getInit();
@@ -588,53 +730,167 @@ AST_MATCHER_P(ForStmt, hasLoopInit, internal::Matcher<Stmt>,
/// \brief Matches while statements.
///
/// Given
+/// \code
/// while (true) {}
+/// \endcode
/// whileStmt()
/// matches 'while (true) {}'.
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- WhileStmt> whileStmt;
+const internal::VariadicDynCastAllOfMatcher<Stmt, WhileStmt> whileStmt;
/// \brief Matches do statements.
///
/// Given
+/// \code
/// do {} while (true);
+/// \endcode
/// doStmt()
/// matches 'do {} while(true)'
const internal::VariadicDynCastAllOfMatcher<Stmt, DoStmt> doStmt;
+/// \brief Matches break statements.
+///
+/// Given
+/// \code
+/// while (true) { break; }
+/// \endcode
+/// breakStmt()
+/// matches 'break'
+const internal::VariadicDynCastAllOfMatcher<Stmt, BreakStmt> breakStmt;
+
+/// \brief Matches continue statements.
+///
+/// Given
+/// \code
+/// while (true) { continue; }
+/// \endcode
+/// continueStmt()
+/// matches 'continue'
+const internal::VariadicDynCastAllOfMatcher<Stmt, ContinueStmt> continueStmt;
+
+/// \brief Matches return statements.
+///
+/// Given
+/// \code
+/// return 1;
+/// \endcode
+/// returnStmt()
+/// matches 'return 1'
+const internal::VariadicDynCastAllOfMatcher<Stmt, ReturnStmt> returnStmt;
+
+/// \brief Matches goto statements.
+///
+/// Given
+/// \code
+/// goto FOO;
+/// FOO: bar();
+/// \endcode
+/// gotoStmt()
+/// matches 'goto FOO'
+const internal::VariadicDynCastAllOfMatcher<Stmt, GotoStmt> gotoStmt;
+
+/// \brief Matches label statements.
+///
+/// Given
+/// \code
+/// goto FOO;
+/// FOO: bar();
+/// \endcode
+/// labelStmt()
+/// matches 'FOO:'
+const internal::VariadicDynCastAllOfMatcher<Stmt, LabelStmt> labelStmt;
+
+/// \brief Matches switch statements.
+///
+/// Given
+/// \code
+/// switch(a) { case 42: break; default: break; }
+/// \endcode
+/// switchStmt()
+/// matches 'switch(a)'.
+const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchStmt> switchStmt;
+
/// \brief Matches case and default statements inside switch statements.
///
/// Given
+/// \code
/// switch(a) { case 42: break; default: break; }
+/// \endcode
/// switchCase()
/// matches 'case 42: break;' and 'default: break;'.
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- SwitchCase> switchCase;
+const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchCase> switchCase;
/// \brief Matches compound statements.
///
/// Example matches '{}' and '{{}}'in 'for (;;) {{}}'
+/// \code
/// for (;;) {{}}
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- CompoundStmt> compoundStatement;
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundStmt> compoundStmt;
+
+/// \brief Matches catch statements.
+///
+/// \code
+/// try {} catch(int i) {}
+/// \endcode
+/// catchStmt()
+/// matches 'catch(int i)'
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXCatchStmt> catchStmt;
+
+/// \brief Matches try statements.
+///
+/// \code
+/// try {} catch(int i) {}
+/// \endcode
+/// tryStmt()
+/// matches 'try {}'
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTryStmt> tryStmt;
+
+/// \brief Matches throw expressions.
+///
+/// \code
+/// try { throw 5; } catch(int i) {}
+/// \endcode
+/// throwExpr()
+/// matches 'throw 5'
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThrowExpr> throwExpr;
+
+/// \brief Matches null statements.
+///
+/// \code
+/// foo();;
+/// \endcode
+/// nullStmt()
+/// matches the second ';'
+const internal::VariadicDynCastAllOfMatcher<Stmt, NullStmt> nullStmt;
+
+/// \brief Matches asm statements.
+///
+/// \code
+/// int i = 100;
+/// __asm("mov al, 2");
+/// \endcode
+/// asmStmt()
+/// matches '__asm("mov al, 2")'
+const internal::VariadicDynCastAllOfMatcher<Stmt, AsmStmt> asmStmt;
/// \brief Matches bool literals.
///
/// Example matches true
+/// \code
/// true
+/// \endcode
const internal::VariadicDynCastAllOfMatcher<
- Expr,
+ Stmt,
CXXBoolLiteralExpr> boolLiteral;
/// \brief Matches string literals (also matches wide string literals).
///
/// Example matches "abcd", L"abcd"
+/// \code
/// char *s = "abcd"; wchar_t *ws = L"abcd"
+/// \endcode
const internal::VariadicDynCastAllOfMatcher<
- Expr,
+ Stmt,
StringLiteral> stringLiteral;
/// \brief Matches character literals (also matches wchar_t).
@@ -643,9 +899,11 @@ const internal::VariadicDynCastAllOfMatcher<
/// though.
///
/// Example matches 'a', L'a'
+/// \code
/// char ch = 'a'; wchar_t chw = L'a';
+/// \endcode
const internal::VariadicDynCastAllOfMatcher<
- Expr,
+ Stmt,
CharacterLiteral> characterLiteral;
/// \brief Matches integer literals of all sizes / encodings.
@@ -654,13 +912,27 @@ const internal::VariadicDynCastAllOfMatcher<
///
/// Example matches 1, 1L, 0x1, 1U
const internal::VariadicDynCastAllOfMatcher<
- Expr,
+ Stmt,
IntegerLiteral> integerLiteral;
+/// \brief Matches user defined literal operator call.
+///
+/// Example match: "foo"_suffix
+const internal::VariadicDynCastAllOfMatcher<
+ Stmt,
+ UserDefinedLiteral> userDefinedLiteral;
+
+/// \brief Matches nullptr literal.
+const internal::VariadicDynCastAllOfMatcher<
+ Stmt,
+ CXXNullPtrLiteralExpr> nullPtrLiteralExpr;
+
/// \brief Matches binary operator expressions.
///
/// Example matches a || b
+/// \code
/// !(a || b)
+/// \endcode
const internal::VariadicDynCastAllOfMatcher<
Stmt,
BinaryOperator> binaryOperator;
@@ -668,7 +940,9 @@ const internal::VariadicDynCastAllOfMatcher<
/// \brief Matches unary operator expressions.
///
/// Example matches !a
+/// \code
/// !a || b
+/// \endcode
const internal::VariadicDynCastAllOfMatcher<
Stmt,
UnaryOperator> unaryOperator;
@@ -676,7 +950,9 @@ const internal::VariadicDynCastAllOfMatcher<
/// \brief Matches conditional operator expressions.
///
/// Example matches a ? b : c
+/// \code
/// (a ? b : c) + 42
+/// \endcode
const internal::VariadicDynCastAllOfMatcher<
Stmt,
ConditionalOperator> conditionalOperator;
@@ -688,10 +964,12 @@ const internal::VariadicDynCastAllOfMatcher<
/// more readable.
///
/// Example matches reinterpret_cast<char*>(&p) in
+/// \code
/// void* p = reinterpret_cast<char*>(&p);
+/// \endcode
const internal::VariadicDynCastAllOfMatcher<
- Expr,
- CXXReinterpretCastExpr> reinterpretCast;
+ Stmt,
+ CXXReinterpretCastExpr> reinterpretCastExpr;
/// \brief Matches a C++ static_cast expression.
///
@@ -699,38 +977,54 @@ const internal::VariadicDynCastAllOfMatcher<
/// \see reinterpretCast
///
/// Example:
-/// staticCast()
+/// staticCastExpr()
/// matches
/// static_cast<long>(8)
/// in
+/// \code
/// long eight(static_cast<long>(8));
+/// \endcode
const internal::VariadicDynCastAllOfMatcher<
- Expr,
- CXXStaticCastExpr> staticCast;
+ Stmt,
+ CXXStaticCastExpr> staticCastExpr;
/// \brief Matches a dynamic_cast expression.
///
/// Example:
-/// dynamicCast()
+/// dynamicCastExpr()
/// matches
/// dynamic_cast<D*>(&b);
/// in
+/// \code
/// struct B { virtual ~B() {} }; struct D : B {};
/// B b;
/// D* p = dynamic_cast<D*>(&b);
+/// \endcode
const internal::VariadicDynCastAllOfMatcher<
- Expr,
- CXXDynamicCastExpr> dynamicCast;
+ Stmt,
+ CXXDynamicCastExpr> dynamicCastExpr;
/// \brief Matches a const_cast expression.
///
/// Example: Matches const_cast<int*>(&r) in
+/// \code
/// int n = 42;
-/// const int& r(n);
+/// const int &r(n);
/// int* p = const_cast<int*>(&r);
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+ Stmt,
+ CXXConstCastExpr> constCastExpr;
+
+/// \brief Matches a C-style cast expression.
+///
+/// Example: Matches (int*) 2.2f in
+/// \code
+/// int i = (int) 2.2f;
+/// \endcode
const internal::VariadicDynCastAllOfMatcher<
- Expr,
- CXXConstCastExpr> constCast;
+ Stmt,
+ CStyleCastExpr> cStyleCastExpr;
/// \brief Matches explicit cast expressions.
///
@@ -746,98 +1040,127 @@ const internal::VariadicDynCastAllOfMatcher<
/// \see hasDestinationType.
///
/// Example: matches all five of the casts in
+/// \code
/// int((int)(reinterpret_cast<int>(static_cast<int>(const_cast<int>(42)))))
+/// \endcode
/// but does not match the implicit conversion in
+/// \code
/// long ell = 42;
+/// \endcode
const internal::VariadicDynCastAllOfMatcher<
- Expr,
- ExplicitCastExpr> explicitCast;
+ 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<
- Expr,
- ImplicitCastExpr> implicitCast;
+ Stmt,
+ ImplicitCastExpr> implicitCastExpr;
/// \brief Matches any cast nodes of Clang's AST.
///
/// Example: castExpr() matches each of the following:
+/// \code
/// (int) 3;
/// const_cast<Expr *>(SubExpr);
/// char c = 0;
+/// \endcode
/// but does not match
+/// \code
/// int i = (0);
/// int k = 0;
-const internal::VariadicDynCastAllOfMatcher<
- Expr,
- CastExpr> castExpr;
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<Stmt, CastExpr> castExpr;
/// \brief Matches functional cast expressions
///
/// Example: Matches Foo(bar);
+/// \code
/// Foo f = bar;
/// Foo g = (Foo) bar;
/// Foo h = Foo(bar);
+/// \endcode
const internal::VariadicDynCastAllOfMatcher<
- Expr,
- CXXFunctionalCastExpr> functionalCast;
+ Stmt,
+ CXXFunctionalCastExpr> functionalCastExpr;
+
+/// \brief Matches \c QualTypes in the clang AST.
+const internal::VariadicAllOfMatcher<QualType> qualType;
+
+/// \brief Matches \c Types in the clang AST.
+const internal::VariadicDynCastAllOfMatcher<Type, Type> type;
+
+/// \brief Matches \c TypeLocs in the clang AST.
+const internal::VariadicDynCastAllOfMatcher<TypeLoc, TypeLoc> typeLoc;
/// \brief Various overloads for the anyOf matcher.
/// @{
-template<typename C1, typename C2>
-internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C1, C2>
-anyOf(const C1 &P1, const C2 &P2) {
+
+/// \brief Matches if any of the given matchers matches.
+///
+/// Usable as: Any Matcher
+template<typename M1, typename M2>
+internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, M1, M2>
+anyOf(const M1 &P1, const M2 &P2) {
return internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher,
- C1, C2 >(P1, P2);
+ M1, M2 >(P1, P2);
}
-template<typename C1, typename C2, typename C3>
-internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C1,
- internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C2, C3> >
-anyOf(const C1 &P1, const C2 &P2, const C3 &P3) {
+template<typename M1, typename M2, typename M3>
+internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, M1,
+ internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, M2, M3> >
+anyOf(const M1 &P1, const M2 &P2, const M3 &P3) {
return anyOf(P1, anyOf(P2, P3));
}
-template<typename C1, typename C2, typename C3, typename C4>
-internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C1,
- internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C2,
+template<typename M1, typename M2, typename M3, typename M4>
+internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, M1,
+ internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, M2,
internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher,
- C3, C4> > >
-anyOf(const C1 &P1, const C2 &P2, const C3 &P3, const C4 &P4) {
+ M3, M4> > >
+anyOf(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4) {
return anyOf(P1, anyOf(P2, anyOf(P3, P4)));
}
-template<typename C1, typename C2, typename C3, typename C4, typename C5>
-internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C1,
- internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C2,
- internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C3,
+template<typename M1, typename M2, typename M3, typename M4, typename M5>
+internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, M1,
+ internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, M2,
+ internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, M3,
internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher,
- C4, C5> > > >
-anyOf(const C1& P1, const C2& P2, const C3& P3, const C4& P4, const C5& P5) {
+ M4, M5> > > >
+anyOf(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4, const M5 &P5) {
return anyOf(P1, anyOf(P2, anyOf(P3, anyOf(P4, P5))));
}
+
/// @}
/// \brief Various overloads for the allOf matcher.
/// @{
-template<typename C1, typename C2>
-internal::PolymorphicMatcherWithParam2<internal::AllOfMatcher, C1, C2>
-allOf(const C1 &P1, const C2 &P2) {
+
+/// \brief Matches if all given matchers match.
+///
+/// Usable as: Any Matcher
+template<typename M1, typename M2>
+internal::PolymorphicMatcherWithParam2<internal::AllOfMatcher, M1, M2>
+allOf(const M1 &P1, const M2 &P2) {
return internal::PolymorphicMatcherWithParam2<internal::AllOfMatcher,
- C1, C2>(P1, P2);
+ M1, M2>(P1, P2);
}
-template<typename C1, typename C2, typename C3>
-internal::PolymorphicMatcherWithParam2<internal::AllOfMatcher, C1,
- internal::PolymorphicMatcherWithParam2<internal::AllOfMatcher, C2, C3> >
-allOf(const C1& P1, const C2& P2, const C3& P3) {
+template<typename M1, typename M2, typename M3>
+internal::PolymorphicMatcherWithParam2<internal::AllOfMatcher, M1,
+ internal::PolymorphicMatcherWithParam2<internal::AllOfMatcher, M2, M3> >
+allOf(const M1 &P1, const M2 &P2, const M3 &P3) {
return allOf(P1, allOf(P2, P3));
}
+
/// @}
/// \brief Matches sizeof (C99), alignof (C++11) and vec_step (OpenCL)
///
/// Given
+/// \code
/// Foo x = bar;
/// int y = sizeof(x) + alignof(x);
+/// \endcode
/// unaryExprOrTypeTraitExpr()
/// matches \c sizeof(x) and \c alignof(x)
const internal::VariadicDynCastAllOfMatcher<
@@ -847,20 +1170,24 @@ const internal::VariadicDynCastAllOfMatcher<
/// \brief Matches unary expressions that have a specific type of argument.
///
/// Given
+/// \code
/// int a, c; float b; int s = sizeof(a) + sizeof(b) + alignof(c);
+/// \endcode
/// unaryExprOrTypeTraitExpr(hasArgumentOfType(asString("int"))
/// matches \c sizeof(a) and \c alignof(c)
AST_MATCHER_P(UnaryExprOrTypeTraitExpr, hasArgumentOfType,
- internal::Matcher<QualType>, Matcher) {
+ internal::Matcher<QualType>, InnerMatcher) {
const QualType ArgumentType = Node.getTypeOfArgument();
- return Matcher.matches(ArgumentType, Finder, Builder);
+ return InnerMatcher.matches(ArgumentType, Finder, Builder);
}
/// \brief Matches unary expressions of a certain kind.
///
/// Given
+/// \code
/// int x;
/// int s = sizeof(x) + alignof(x)
+/// \endcode
/// unaryExprOrTypeTraitExpr(ofKind(UETT_SizeOf))
/// matches \c sizeof(x)
AST_MATCHER_P(UnaryExprOrTypeTraitExpr, ofKind, UnaryExprOrTypeTrait, Kind) {
@@ -870,17 +1197,17 @@ AST_MATCHER_P(UnaryExprOrTypeTraitExpr, ofKind, UnaryExprOrTypeTrait, Kind) {
/// \brief Same as unaryExprOrTypeTraitExpr, but only matching
/// alignof.
inline internal::Matcher<Stmt> alignOfExpr(
- const internal::Matcher<UnaryExprOrTypeTraitExpr> &Matcher) {
+ const internal::Matcher<UnaryExprOrTypeTraitExpr> &InnerMatcher) {
return internal::Matcher<Stmt>(unaryExprOrTypeTraitExpr(allOf(
- ofKind(UETT_AlignOf), Matcher)));
+ ofKind(UETT_AlignOf), InnerMatcher)));
}
/// \brief Same as unaryExprOrTypeTraitExpr, but only matching
/// sizeof.
inline internal::Matcher<Stmt> sizeOfExpr(
- const internal::Matcher<UnaryExprOrTypeTraitExpr> &Matcher) {
+ const internal::Matcher<UnaryExprOrTypeTraitExpr> &InnerMatcher) {
return internal::Matcher<Stmt>(unaryExprOrTypeTraitExpr(allOf(
- ofKind(UETT_SizeOf), Matcher)));
+ ofKind(UETT_SizeOf), InnerMatcher)));
}
/// \brief Matches NamedDecl nodes that have the specified name.
@@ -890,10 +1217,14 @@ inline internal::Matcher<Stmt> sizeOfExpr(
/// Does not match typedefs of an underlying type with the given name.
///
/// Example matches X (Name == "X")
+/// \code
/// class X;
+/// \endcode
///
/// Example matches X (Name is one of "::a::b::X", "a::b::X", "b::X", "X")
-/// namespace a { namespace b { class X; } }
+/// \code
+/// namespace a { namespace b { class X; } }
+/// \endcode
AST_MATCHER_P(NamedDecl, hasName, std::string, Name) {
assert(!Name.empty());
const std::string FullNameString = "::" + Node.getQualifiedNameAsString();
@@ -914,10 +1245,14 @@ AST_MATCHER_P(NamedDecl, hasName, std::string, Name) {
/// of an underlying type with the given name.
///
/// Example matches X (regexp == "::X")
+/// \code
/// class X;
+/// \endcode
///
/// Example matches X (regexp is one of "::X", "^foo::.*X", among others)
-/// namespace foo { namespace bar { class X; } }
+/// \code
+/// namespace foo { namespace bar { class X; } }
+/// \endcode
AST_MATCHER_P(NamedDecl, matchesName, std::string, RegExp) {
assert(!RegExp.empty());
std::string FullNameString = "::" + Node.getQualifiedNameAsString();
@@ -931,10 +1266,12 @@ AST_MATCHER_P(NamedDecl, matchesName, std::string, RegExp) {
/// "operator" prefix, such as "<<", for OverloadedOperatorCall's.
///
/// Example matches a << b
-/// (matcher == overloadedOperatorCall(hasOverloadedOperatorName("<<")))
+/// (matcher == operatorCallExpr(hasOverloadedOperatorName("<<")))
+/// \code
/// a << b;
/// c && d; // assuming both operator<<
/// // and operator&& are overloaded somewhere.
+/// \endcode
AST_MATCHER_P(CXXOperatorCallExpr,
hasOverloadedOperatorName, std::string, Name) {
return getOperatorSpelling(Node.getOperator()) == Name;
@@ -943,20 +1280,24 @@ AST_MATCHER_P(CXXOperatorCallExpr,
/// \brief Matches C++ classes that are directly or indirectly derived from
/// a class matching \c Base.
///
-/// Note that a class is considered to be also derived from itself.
+/// Note that a class is not considered to be derived from itself.
///
-/// Example matches X, Y, Z, C (Base == hasName("X"))
-/// class X; // A class is considered to be derived from itself
+/// Example matches Y, Z, C (Base == hasName("X"))
+/// \code
+/// class X;
/// class Y : public X {}; // directly derived
/// class Z : public Y {}; // indirectly derived
/// typedef X A;
/// typedef A B;
/// class C : public B {}; // derived from a typedef of X
+/// \endcode
///
/// In the following example, Bar matches isDerivedFrom(hasName("X")):
+/// \code
/// class Foo;
/// typedef Foo X;
/// class Bar : public Foo {}; // derived from a type that X is a typedef of
+/// \endcode
AST_MATCHER_P(CXXRecordDecl, isDerivedFrom,
internal::Matcher<NamedDecl>, Base) {
return Finder->classIsDerivedFrom(&Node, Base, Builder);
@@ -968,15 +1309,34 @@ inline internal::Matcher<CXXRecordDecl> isDerivedFrom(StringRef BaseName) {
return isDerivedFrom(hasName(BaseName));
}
+/// \brief Similar to \c isDerivedFrom(), but also matches classes that directly
+/// match \c Base.
+inline internal::Matcher<CXXRecordDecl> isSameOrDerivedFrom(
+ internal::Matcher<NamedDecl> Base) {
+ return anyOf(Base, isDerivedFrom(Base));
+}
+
+/// \brief Overloaded method as shortcut for
+/// \c isSameOrDerivedFrom(hasName(...)).
+inline internal::Matcher<CXXRecordDecl> isSameOrDerivedFrom(
+ StringRef BaseName) {
+ assert(!BaseName.empty());
+ return isSameOrDerivedFrom(hasName(BaseName));
+}
+
/// \brief Matches AST nodes that have child AST nodes that match the
/// provided matcher.
///
-/// Example matches X, Y (matcher = record(has(record(hasName("X")))
+/// Example matches X, Y (matcher = recordDecl(has(recordDecl(hasName("X")))
+/// \code
/// class X {}; // Matches X, because X::X is a class of name X inside X.
/// class Y { class X {}; };
/// class Z { class Y { class X {}; }; }; // Does not match Z.
+/// \endcode
///
/// ChildT must be an AST base type.
+///
+/// Usable as: Any Matcher
template <typename ChildT>
internal::ArgumentAdaptingMatcher<internal::HasMatcher, ChildT> has(
const internal::Matcher<ChildT> &ChildMatcher) {
@@ -988,12 +1348,16 @@ internal::ArgumentAdaptingMatcher<internal::HasMatcher, ChildT> has(
/// provided matcher.
///
/// Example matches X, Y, Z
-/// (matcher = record(hasDescendant(record(hasName("X")))))
+/// (matcher = recordDecl(hasDescendant(recordDecl(hasName("X")))))
+/// \code
/// class X {}; // Matches X, because X::X is a class of name X inside X.
/// class Y { class X {}; };
/// class Z { class Y { class X {}; }; };
+/// \endcode
///
/// DescendantT must be an AST base type.
+///
+/// Usable as: Any Matcher
template <typename DescendantT>
internal::ArgumentAdaptingMatcher<internal::HasDescendantMatcher, DescendantT>
hasDescendant(const internal::Matcher<DescendantT> &DescendantMatcher) {
@@ -1002,22 +1366,25 @@ hasDescendant(const internal::Matcher<DescendantT> &DescendantMatcher) {
DescendantT>(DescendantMatcher);
}
-
/// \brief Matches AST nodes that have child AST nodes that match the
/// provided matcher.
///
-/// Example matches X, Y (matcher = record(forEach(record(hasName("X")))
+/// Example matches X, Y (matcher = recordDecl(forEach(recordDecl(hasName("X")))
+/// \code
/// class X {}; // Matches X, because X::X is a class of name X inside X.
/// class Y { class X {}; };
/// class Z { class Y { class X {}; }; }; // Does not match Z.
+/// \endcode
///
/// ChildT must be an AST base type.
///
/// As opposed to 'has', 'forEach' will cause a match for each result that
/// matches instead of only on the first one.
+///
+/// Usable as: Any Matcher
template <typename ChildT>
internal::ArgumentAdaptingMatcher<internal::ForEachMatcher, ChildT> forEach(
- const internal::Matcher<ChildT>& ChildMatcher) {
+ const internal::Matcher<ChildT> &ChildMatcher) {
return internal::ArgumentAdaptingMatcher<
internal::ForEachMatcher,
ChildT>(ChildMatcher);
@@ -1027,10 +1394,12 @@ internal::ArgumentAdaptingMatcher<internal::ForEachMatcher, ChildT> forEach(
/// provided matcher.
///
/// Example matches X, A, B, C
-/// (matcher = record(forEachDescendant(record(hasName("X")))))
+/// (matcher = recordDecl(forEachDescendant(recordDecl(hasName("X")))))
+/// \code
/// class X {}; // Matches X, because X::X is a class of name X inside X.
/// class A { class X {}; };
/// class B { class C { class X {}; }; };
+/// \endcode
///
/// DescendantT must be an AST base type.
///
@@ -1038,25 +1407,72 @@ internal::ArgumentAdaptingMatcher<internal::ForEachMatcher, ChildT> forEach(
/// each result that matches instead of only on the first one.
///
/// Note: Recursively combined ForEachDescendant can cause many matches:
-/// record(forEachDescendant(record(forEachDescendant(record()))))
+/// recordDecl(forEachDescendant(recordDecl(forEachDescendant(recordDecl()))))
/// will match 10 times (plus injected class name matches) on:
+/// \code
/// class A { class B { class C { class D { class E {}; }; }; }; };
+/// \endcode
+///
+/// Usable as: Any Matcher
template <typename DescendantT>
-internal::ArgumentAdaptingMatcher<internal::ForEachDescendantMatcher, DescendantT>
+internal::ArgumentAdaptingMatcher<internal::ForEachDescendantMatcher,
+ DescendantT>
forEachDescendant(
- const internal::Matcher<DescendantT>& DescendantMatcher) {
+ const internal::Matcher<DescendantT> &DescendantMatcher) {
return internal::ArgumentAdaptingMatcher<
internal::ForEachDescendantMatcher,
DescendantT>(DescendantMatcher);
}
+/// \brief Matches AST nodes that have a parent that matches the provided
+/// matcher.
+///
+/// Given
+/// \code
+/// void f() { for (;;) { int x = 42; if (true) { int x = 43; } } }
+/// \endcode
+/// \c compoundStmt(hasParent(ifStmt())) matches "{ int x = 43; }".
+///
+/// Usable as: Any Matcher
+template <typename ParentT>
+internal::ArgumentAdaptingMatcher<internal::HasParentMatcher, ParentT>
+hasParent(const internal::Matcher<ParentT> &ParentMatcher) {
+ return internal::ArgumentAdaptingMatcher<
+ internal::HasParentMatcher,
+ ParentT>(ParentMatcher);
+}
+
+/// \brief Matches AST nodes that have an ancestor that matches the provided
+/// matcher.
+///
+/// Given
+/// \code
+/// void f() { if (true) { int x = 42; } }
+/// void g() { for (;;) { int x = 43; } }
+/// \endcode
+/// \c expr(integerLiteral(hasAncestor(ifStmt()))) matches \c 42, but not 43.
+///
+/// Usable as: Any Matcher
+template <typename AncestorT>
+internal::ArgumentAdaptingMatcher<internal::HasAncestorMatcher, AncestorT>
+hasAncestor(const internal::Matcher<AncestorT> &AncestorMatcher) {
+ return internal::ArgumentAdaptingMatcher<
+ internal::HasAncestorMatcher,
+ AncestorT>(AncestorMatcher);
+}
+
/// \brief Matches if the provided matcher does not match.
///
-/// Example matches Y (matcher = record(unless(hasName("X"))))
+/// Example matches Y (matcher = recordDecl(unless(hasName("X"))))
+/// \code
/// class X {};
/// class Y {};
+/// \endcode
+///
+/// Usable as: Any Matcher
template <typename M>
-internal::PolymorphicMatcherWithParam1<internal::NotMatcher, M> unless(const M &InnerMatcher) {
+internal::PolymorphicMatcherWithParam1<internal::NotMatcher, M>
+unless(const M &InnerMatcher) {
return internal::PolymorphicMatcherWithParam1<
internal::NotMatcher, M>(InnerMatcher);
}
@@ -1064,7 +1480,8 @@ internal::PolymorphicMatcherWithParam1<internal::NotMatcher, M> unless(const M &
/// \brief Matches a type if the declaration of the type matches the given
/// matcher.
///
-/// Usable as: Matcher<QualType>, Matcher<CallExpr>, Matcher<CXXConstructExpr>
+/// Usable as: Matcher<QualType>, Matcher<CallExpr>, Matcher<CXXConstructExpr>,
+/// Matcher<MemberExpr>
inline internal::PolymorphicMatcherWithParam1< internal::HasDeclarationMatcher,
internal::Matcher<Decl> >
hasDeclaration(const internal::Matcher<Decl> &InnerMatcher) {
@@ -1075,9 +1492,11 @@ inline internal::PolymorphicMatcherWithParam1< internal::HasDeclarationMatcher,
/// \brief Matches on the implicit object argument of a member call expression.
///
-/// Example matches y.x() (matcher = call(on(hasType(record(hasName("Y"))))))
+/// Example matches y.x() (matcher = callExpr(on(hasType(recordDecl(hasName("Y"))))))
+/// \code
/// class Y { public: void x(); };
/// void z() { Y y; y.x(); }",
+/// \endcode
///
/// FIXME: Overload to allow directly matching types?
AST_MATCHER_P(CXXMemberCallExpr, on, internal::Matcher<Expr>,
@@ -1092,9 +1511,11 @@ AST_MATCHER_P(CXXMemberCallExpr, on, internal::Matcher<Expr>,
/// \brief Matches if the call expression's callee expression matches.
///
/// Given
+/// \code
/// class Y { void x() { this->x(); x(); Y y; y.x(); } };
/// void f() { f(); }
-/// call(callee(expression()))
+/// \endcode
+/// callExpr(callee(expr()))
/// matches this->x(), x(), y.x(), f()
/// with callee(...)
/// matching this->x, x, y.x, f respectively
@@ -1113,9 +1534,11 @@ AST_MATCHER_P(CallExpr, callee, internal::Matcher<Stmt>,
/// \brief Matches if the call expression's callee's declaration matches the
/// given matcher.
///
-/// Example matches y.x() (matcher = call(callee(method(hasName("x")))))
+/// Example matches y.x() (matcher = callExpr(callee(methodDecl(hasName("x")))))
+/// \code
/// class Y { public: void x(); };
/// void z() { Y y; y.x();
+/// \endcode
inline internal::Matcher<CallExpr> callee(
const internal::Matcher<Decl> &InnerMatcher) {
return internal::Matcher<CallExpr>(hasDeclaration(InnerMatcher));
@@ -1124,12 +1547,12 @@ inline internal::Matcher<CallExpr> callee(
/// \brief Matches if the expression's or declaration's type matches a type
/// matcher.
///
-/// Example matches x (matcher = expression(hasType(
-/// hasDeclaration(record(hasName("X"))))))
-/// and z (matcher = variable(hasType(
-/// hasDeclaration(record(hasName("X"))))))
+/// Example matches x (matcher = expr(hasType(recordDecl(hasName("X")))))
+/// and z (matcher = varDecl(hasType(recordDecl(hasName("X")))))
+/// \code
/// class X {};
/// void y(X &x) { x; X z; }
+/// \endcode
AST_POLYMORPHIC_MATCHER_P(hasType, internal::Matcher<QualType>,
InnerMatcher) {
TOOLING_COMPILE_ASSERT((llvm::is_base_of<Expr, NodeType>::value ||
@@ -1143,14 +1566,16 @@ AST_POLYMORPHIC_MATCHER_P(hasType, internal::Matcher<QualType>,
///
/// In case of a value declaration (for example a variable declaration),
/// this resolves one layer of indirection. For example, in the value
-/// declaration "X x;", record(hasName("X")) matches the declaration of X,
-/// while variable(hasType(record(hasName("X")))) matches the declaration
+/// declaration "X x;", recordDecl(hasName("X")) matches the declaration of X,
+/// while varDecl(hasType(recordDecl(hasName("X")))) matches the declaration
/// of x."
///
-/// Example matches x (matcher = expression(hasType(record(hasName("X")))))
-/// and z (matcher = variable(hasType(record(hasName("X")))))
+/// Example matches x (matcher = expr(hasType(recordDecl(hasName("X")))))
+/// and z (matcher = varDecl(hasType(recordDecl(hasName("X")))))
+/// \code
/// class X {};
/// void y(X &x) { x; X z; }
+/// \endcode
///
/// Usable as: Matcher<Expr>, Matcher<ValueDecl>
inline internal::PolymorphicMatcherWithParam1<
@@ -1164,9 +1589,11 @@ hasType(const internal::Matcher<Decl> &InnerMatcher) {
/// \brief Matches if the matched type is represented by the given string.
///
/// Given
+/// \code
/// class Y { public: void x(); };
/// void z() { Y* y; y->x(); }
-/// call(on(hasType(asString("class Y *"))))
+/// \endcode
+/// callExpr(on(hasType(asString("class Y *"))))
/// matches y->x()
AST_MATCHER_P(QualType, asString, std::string, Name) {
return Name == Node.getAsString();
@@ -1176,9 +1603,11 @@ AST_MATCHER_P(QualType, asString, std::string, Name) {
/// matches the specified matcher.
///
/// Example matches y->x()
-/// (matcher = call(on(hasType(pointsTo(record(hasName("Y")))))))
+/// (matcher = callExpr(on(hasType(pointsTo(recordDecl(hasName("Y")))))))
+/// \code
/// class Y { public: void x(); };
/// void z() { Y *y; y->x(); }
+/// \endcode
AST_MATCHER_P(
QualType, pointsTo, internal::Matcher<QualType>,
InnerMatcher) {
@@ -1197,12 +1626,14 @@ inline internal::Matcher<QualType> pointsTo(
/// type matches the specified matcher.
///
/// Example matches X &x and const X &y
-/// (matcher = variable(hasType(references(record(hasName("X"))))))
+/// (matcher = varDecl(hasType(references(recordDecl(hasName("X"))))))
+/// \code
/// class X {
/// void a(X b) {
/// X &x = b;
/// const X &y = b;
/// };
+/// \endcode
AST_MATCHER_P(QualType, references, internal::Matcher<QualType>,
InnerMatcher) {
return (!Node.isNull() && Node->isReferenceType() &&
@@ -1243,9 +1674,11 @@ inline internal::Matcher<CXXMemberCallExpr> thisPointerType(
/// specified matcher.
///
/// Example matches x in if(x)
-/// (matcher = declarationReference(to(variable(hasName("x")))))
+/// (matcher = declRefExpr(to(varDecl(hasName("x")))))
+/// \code
/// bool x;
/// if (x) {}
+/// \endcode
AST_MATCHER_P(DeclRefExpr, to, internal::Matcher<Decl>,
InnerMatcher) {
const Decl *DeclNode = Node.getDecl();
@@ -1259,29 +1692,33 @@ AST_MATCHER_P(DeclRefExpr, to, internal::Matcher<Decl>,
/// FIXME: This currently only works for functions. Fix.
///
/// Given
+/// \code
/// namespace a { void f() {} }
/// using a::f;
/// void g() {
/// f(); // Matches this ..
/// a::f(); // .. but not this.
/// }
-/// declarationReference(throughUsingDeclaration(anything()))
+/// \endcode
+/// declRefExpr(throughUsingDeclaration(anything()))
/// matches \c f()
AST_MATCHER_P(DeclRefExpr, throughUsingDecl,
- internal::Matcher<UsingShadowDecl>, Matcher) {
+ internal::Matcher<UsingShadowDecl>, InnerMatcher) {
const NamedDecl *FoundDecl = Node.getFoundDecl();
if (const UsingShadowDecl *UsingDecl =
llvm::dyn_cast<UsingShadowDecl>(FoundDecl))
- return Matcher.matches(*UsingDecl, Finder, Builder);
+ return InnerMatcher.matches(*UsingDecl, Finder, Builder);
return false;
}
/// \brief Matches the Decl of a DeclStmt which has a single declaration.
///
/// Given
+/// \code
/// int a, b;
/// int c;
-/// declarationStatement(hasSingleDecl(anything()))
+/// \endcode
+/// declStmt(hasSingleDecl(anything()))
/// matches 'int c;' but not 'int a, b;'.
AST_MATCHER_P(DeclStmt, hasSingleDecl, internal::Matcher<Decl>, InnerMatcher) {
if (Node.isSingleDecl()) {
@@ -1294,9 +1731,11 @@ AST_MATCHER_P(DeclStmt, hasSingleDecl, internal::Matcher<Decl>, InnerMatcher) {
/// \brief Matches a variable declaration that has an initializer expression
/// that matches the given matcher.
///
-/// Example matches x (matcher = variable(hasInitializer(call())))
+/// Example matches x (matcher = varDecl(hasInitializer(callExpr())))
+/// \code
/// bool y() { return true; }
/// bool x = y();
+/// \endcode
AST_MATCHER_P(
VarDecl, hasInitializer, internal::Matcher<Expr>,
InnerMatcher) {
@@ -1308,9 +1747,11 @@ AST_MATCHER_P(
/// \brief Checks that a call expression or a constructor call expression has
/// a specific number of arguments (including absent default arguments).
///
-/// Example matches f(0, 0) (matcher = call(argumentCountIs(2)))
+/// Example matches f(0, 0) (matcher = callExpr(argumentCountIs(2)))
+/// \code
/// void f(int x, int y);
/// f(0, 0);
+/// \endcode
AST_POLYMORPHIC_MATCHER_P(argumentCountIs, unsigned, N) {
TOOLING_COMPILE_ASSERT((llvm::is_base_of<CallExpr, NodeType>::value ||
llvm::is_base_of<CXXConstructExpr,
@@ -1323,8 +1764,10 @@ AST_POLYMORPHIC_MATCHER_P(argumentCountIs, unsigned, N) {
/// call expression.
///
/// Example matches y in x(y)
-/// (matcher = call(hasArgument(0, declarationReference())))
+/// (matcher = callExpr(hasArgument(0, declRefExpr())))
+/// \code
/// void x(int) { int y; x(y); }
+/// \endcode
AST_POLYMORPHIC_MATCHER_P2(
hasArgument, unsigned, N, internal::Matcher<Expr>, InnerMatcher) {
TOOLING_COMPILE_ASSERT((llvm::is_base_of<CallExpr, NodeType>::value ||
@@ -1340,13 +1783,15 @@ AST_POLYMORPHIC_MATCHER_P2(
/// declarations.
///
/// Example: Given
+/// \code
/// int a, b;
/// int c;
/// int d = 2, e;
+/// \endcode
/// declCountIs(2)
/// matches 'int a, b;' and 'int d = 2, e;', but not 'int c;'.
AST_MATCHER_P(DeclStmt, declCountIs, unsigned, N) {
- return std::distance(Node.decl_begin(), Node.decl_end()) == N;
+ return std::distance(Node.decl_begin(), Node.decl_end()) == (ptrdiff_t)N;
}
/// \brief Matches the n'th declaration of a declaration statement.
@@ -1355,15 +1800,19 @@ AST_MATCHER_P(DeclStmt, declCountIs, unsigned, N) {
/// breaks up multiple-declaration DeclStmt's into multiple single-declaration
/// DeclStmt's.
/// Example: Given non-global declarations
+/// \code
/// int a, b = 0;
/// int c;
/// int d = 2, e;
-/// declarationStatement(containsDeclaration(
-/// 0, variable(hasInitializer(anything()))))
+/// \endcode
+/// declStmt(containsDeclaration(
+/// 0, varDecl(hasInitializer(anything()))))
/// matches only 'int d = 2, e;', and
-/// declarationStatement(containsDeclaration(1, variable()))
+/// declStmt(containsDeclaration(1, varDecl()))
+/// \code
/// matches 'int a, b = 0' as well as 'int d = 2, e;'
/// but 'int c;' is not matched.
+/// \endcode
AST_MATCHER_P2(DeclStmt, containsDeclaration, unsigned, N,
internal::Matcher<Decl>, InnerMatcher) {
const unsigned NumDecls = std::distance(Node.decl_begin(), Node.decl_end());
@@ -1377,11 +1826,13 @@ AST_MATCHER_P2(DeclStmt, containsDeclaration, unsigned, N,
/// \brief Matches a constructor initializer.
///
/// Given
+/// \code
/// struct Foo {
/// Foo() : foo_(1) { }
/// int foo_;
/// };
-/// record(has(constructor(hasAnyConstructorInitializer(anything()))))
+/// \endcode
+/// recordDecl(has(constructorDecl(hasAnyConstructorInitializer(anything()))))
/// record matches Foo, hasAnyConstructorInitializer matches foo_(1)
AST_MATCHER_P(CXXConstructorDecl, hasAnyConstructorInitializer,
internal::Matcher<CXXCtorInitializer>, InnerMatcher) {
@@ -1397,11 +1848,13 @@ AST_MATCHER_P(CXXConstructorDecl, hasAnyConstructorInitializer,
/// \brief Matches the field declaration of a constructor initializer.
///
/// Given
+/// \code
/// struct Foo {
/// Foo() : foo_(1) { }
/// int foo_;
/// };
-/// record(has(constructor(hasAnyConstructorInitializer(
+/// \endcode
+/// recordDecl(has(constructorDecl(hasAnyConstructorInitializer(
/// forField(hasName("foo_"))))))
/// matches Foo
/// with forField matching foo_
@@ -1415,11 +1868,13 @@ AST_MATCHER_P(CXXCtorInitializer, forField,
/// \brief Matches the initializer expression of a constructor initializer.
///
/// Given
+/// \code
/// struct Foo {
/// Foo() : foo_(1) { }
/// int foo_;
/// };
-/// record(has(constructor(hasAnyConstructorInitializer(
+/// \endcode
+/// recordDecl(has(constructorDecl(hasAnyConstructorInitializer(
/// withInitializer(integerLiteral(equals(1)))))))
/// matches Foo
/// with withInitializer matching (1)
@@ -1434,12 +1889,14 @@ AST_MATCHER_P(CXXCtorInitializer, withInitializer,
/// code (as opposed to implicitly added by the compiler).
///
/// Given
+/// \code
/// struct Foo {
/// Foo() { }
/// Foo(int) : foo_("A") { }
/// string foo_;
/// };
-/// constructor(hasAnyConstructorInitializer(isWritten()))
+/// \endcode
+/// constructorDecl(hasAnyConstructorInitializer(isWritten()))
/// will match Foo(int), but not Foo()
AST_MATCHER(CXXCtorInitializer, isWritten) {
return Node.isWritten();
@@ -1455,8 +1912,10 @@ AST_MATCHER(CXXConstructorDecl, isImplicit) {
/// expression.
///
/// Given
+/// \code
/// void x(int, int, int) { int y; x(1, y, 42); }
-/// call(hasAnyArgument(declarationReference()))
+/// \endcode
+/// callExpr(hasAnyArgument(declRefExpr()))
/// matches x(1, y, 42)
/// with hasAnyArgument(...)
/// matching y
@@ -1478,8 +1937,10 @@ AST_POLYMORPHIC_MATCHER_P(hasAnyArgument, internal::Matcher<Expr>,
/// \brief Matches the n'th parameter of a function declaration.
///
/// Given
+/// \code
/// class X { void f(int x) {} };
-/// method(hasParameter(0, hasType(variable())))
+/// \endcode
+/// methodDecl(hasParameter(0, hasType(varDecl())))
/// matches f(int x) {}
/// with hasParameter(...)
/// matching int x
@@ -1496,8 +1957,10 @@ AST_MATCHER_P2(FunctionDecl, hasParameter,
/// Does not match the 'this' parameter of a method.
///
/// Given
+/// \code
/// class X { void f(int x, int y, int z) {} };
-/// method(hasAnyParameter(hasName("y")))
+/// \endcode
+/// methodDecl(hasAnyParameter(hasName("y")))
/// matches f(int x, int y, int z) {}
/// with hasAnyParameter(...)
/// matching int y
@@ -1514,20 +1977,25 @@ AST_MATCHER_P(FunctionDecl, hasAnyParameter,
/// \brief Matches the return type of a function declaration.
///
/// Given:
+/// \code
/// class X { int f() { return 1; } };
-/// method(returns(asString("int")))
+/// \endcode
+/// methodDecl(returns(asString("int")))
/// matches int f() { return 1; }
-AST_MATCHER_P(FunctionDecl, returns, internal::Matcher<QualType>, Matcher) {
- return Matcher.matches(Node.getResultType(), Finder, Builder);
+AST_MATCHER_P(FunctionDecl, returns,
+ internal::Matcher<QualType>, InnerMatcher) {
+ return InnerMatcher.matches(Node.getResultType(), Finder, Builder);
}
/// \brief Matches extern "C" function declarations.
///
/// Given:
+/// \code
/// extern "C" void f() {}
/// extern "C" { void g() {} }
/// void h() {}
-/// function(isExternC())
+/// \endcode
+/// functionDecl(isExternC())
/// matches the declaration of f and g, but not the declaration h
AST_MATCHER(FunctionDecl, isExternC) {
return Node.isExternC();
@@ -1537,7 +2005,9 @@ AST_MATCHER(FunctionDecl, isExternC) {
/// or conditional operator.
///
/// Example matches true (matcher = hasCondition(boolLiteral(equals(true))))
+/// \code
/// if (true) {}
+/// \endcode
AST_POLYMORPHIC_MATCHER_P(hasCondition, internal::Matcher<Expr>,
InnerMatcher) {
TOOLING_COMPILE_ASSERT(
@@ -1555,7 +2025,9 @@ AST_POLYMORPHIC_MATCHER_P(hasCondition, internal::Matcher<Expr>,
/// \brief Matches the condition variable statement in an if statement.
///
/// Given
+/// \code
/// if (A* a = GetAPointer()) {}
+/// \endcode
/// hasConditionVariableStatment(...)
/// matches 'A* a = GetAPointer()'.
AST_MATCHER_P(IfStmt, hasConditionVariableStatement,
@@ -1569,29 +2041,33 @@ AST_MATCHER_P(IfStmt, hasConditionVariableStatement,
/// \brief Matches the index expression of an array subscript expression.
///
/// Given
+/// \code
/// int i[5];
/// void f() { i[1] = 42; }
+/// \endcode
/// arraySubscriptExpression(hasIndex(integerLiteral()))
/// matches \c i[1] with the \c integerLiteral() matching \c 1
AST_MATCHER_P(ArraySubscriptExpr, hasIndex,
- internal::Matcher<Expr>, matcher) {
+ internal::Matcher<Expr>, InnerMatcher) {
if (const Expr* Expression = Node.getIdx())
- return matcher.matches(*Expression, Finder, Builder);
+ return InnerMatcher.matches(*Expression, Finder, Builder);
return false;
}
/// \brief Matches the base expression of an array subscript expression.
///
/// Given
+/// \code
/// int i[5];
/// void f() { i[1] = 42; }
-/// arraySubscriptExpression(hasBase(implicitCast(
-/// hasSourceExpression(declarationReference()))))
-/// matches \c i[1] with the \c declarationReference() matching \c i
+/// \endcode
+/// arraySubscriptExpression(hasBase(implicitCastExpr(
+/// hasSourceExpression(declRefExpr()))))
+/// matches \c i[1] with the \c declRefExpr() matching \c i
AST_MATCHER_P(ArraySubscriptExpr, hasBase,
- internal::Matcher<Expr>, matcher) {
+ internal::Matcher<Expr>, InnerMatcher) {
if (const Expr* Expression = Node.getBase())
- return matcher.matches(*Expression, Finder, Builder);
+ return InnerMatcher.matches(*Expression, Finder, Builder);
return false;
}
@@ -1599,10 +2075,12 @@ AST_MATCHER_P(ArraySubscriptExpr, hasBase,
/// a given body.
///
/// Given
+/// \code
/// for (;;) {}
-/// hasBody(compoundStatement())
+/// \endcode
+/// hasBody(compoundStmt())
/// matches 'for (;;) {}'
-/// with compoundStatement()
+/// with compoundStmt()
/// matching '{}'
AST_POLYMORPHIC_MATCHER_P(hasBody, internal::Matcher<Stmt>,
InnerMatcher) {
@@ -1620,10 +2098,12 @@ AST_POLYMORPHIC_MATCHER_P(hasBody, internal::Matcher<Stmt>,
/// a given matcher.
///
/// Given
+/// \code
/// { {}; 1+2; }
-/// hasAnySubstatement(compoundStatement())
+/// \endcode
+/// hasAnySubstatement(compoundStmt())
/// matches '{ {}; 1+2; }'
-/// with compoundStatement()
+/// with compoundStmt()
/// matching '{}'
AST_MATCHER_P(CompoundStmt, hasAnySubstatement,
internal::Matcher<Stmt>, InnerMatcher) {
@@ -1639,8 +2119,10 @@ AST_MATCHER_P(CompoundStmt, hasAnySubstatement,
/// child statements.
///
/// Example: Given
+/// \code
/// { for (;;) {} }
-/// compoundStatement(statementCountIs(0)))
+/// \endcode
+/// compoundStmt(statementCountIs(0)))
/// matches '{}'
/// but does not match the outer compound statement.
AST_MATCHER_P(CompoundStmt, statementCountIs, unsigned, N) {
@@ -1650,7 +2132,9 @@ AST_MATCHER_P(CompoundStmt, statementCountIs, unsigned, N) {
/// \brief Matches literals that are equal to the given value.
///
/// Example matches true (matcher = boolLiteral(equals(true)))
+/// \code
/// true
+/// \endcode
///
/// Usable as: Matcher<CharacterLiteral>, Matcher<CXXBoolLiteral>,
/// Matcher<FloatingLiteral>, Matcher<IntegerLiteral>
@@ -1666,7 +2150,9 @@ equals(const ValueT &Value) {
/// unary).
///
/// Example matches a || b (matcher = binaryOperator(hasOperatorName("||")))
+/// \code
/// !(a || b)
+/// \endcode
AST_POLYMORPHIC_MATCHER_P(hasOperatorName, std::string, Name) {
TOOLING_COMPILE_ASSERT(
(llvm::is_base_of<BinaryOperator, NodeType>::value) ||
@@ -1678,7 +2164,9 @@ AST_POLYMORPHIC_MATCHER_P(hasOperatorName, std::string, Name) {
/// \brief Matches the left hand side of binary operator expressions.
///
/// Example matches a (matcher = binaryOperator(hasLHS()))
+/// \code
/// a || b
+/// \endcode
AST_MATCHER_P(BinaryOperator, hasLHS,
internal::Matcher<Expr>, InnerMatcher) {
Expr *LeftHandSide = Node.getLHS();
@@ -1689,7 +2177,9 @@ AST_MATCHER_P(BinaryOperator, hasLHS,
/// \brief Matches the right hand side of binary operator expressions.
///
/// Example matches b (matcher = binaryOperator(hasRHS()))
+/// \code
/// a || b
+/// \endcode
AST_MATCHER_P(BinaryOperator, hasRHS,
internal::Matcher<Expr>, InnerMatcher) {
Expr *RightHandSide = Node.getRHS();
@@ -1706,8 +2196,10 @@ inline internal::Matcher<BinaryOperator> hasEitherOperand(
/// \brief Matches if the operand of a unary operator matches.
///
-/// Example matches true (matcher = hasOperand(boolLiteral(equals(true))))
+/// Example matches true (matcher = hasUnaryOperand(boolLiteral(equals(true))))
+/// \code
/// !true
+/// \endcode
AST_MATCHER_P(UnaryOperator, hasUnaryOperand,
internal::Matcher<Expr>, InnerMatcher) {
const Expr * const Operand = Node.getSubExpr();
@@ -1718,8 +2210,8 @@ AST_MATCHER_P(UnaryOperator, hasUnaryOperand,
/// \brief Matches if the cast's source expression matches the given matcher.
///
/// Example: matches "a string" (matcher =
-/// hasSourceExpression(constructorCall()))
-///
+/// hasSourceExpression(constructExpr()))
+/// \code
/// class URL { URL(string); };
/// URL url = "a string";
AST_MATCHER_P(CastExpr, hasSourceExpression,
@@ -1751,7 +2243,9 @@ AST_MATCHER_P(ImplicitCastExpr, hasImplicitDestinationType,
/// \brief Matches the true branch expression of a conditional operator.
///
/// Example matches a
+/// \code
/// condition ? a : b
+/// \endcode
AST_MATCHER_P(ConditionalOperator, hasTrueExpression,
internal::Matcher<Expr>, InnerMatcher) {
Expr *Expression = Node.getTrueExpr();
@@ -1762,7 +2256,9 @@ AST_MATCHER_P(ConditionalOperator, hasTrueExpression,
/// \brief Matches the false branch expression of a conditional operator.
///
/// Example matches b
+/// \code
/// condition ? a : b
+/// \endcode
AST_MATCHER_P(ConditionalOperator, hasFalseExpression,
internal::Matcher<Expr>, InnerMatcher) {
Expr *Expression = Node.getFalseExpr();
@@ -1773,12 +2269,14 @@ AST_MATCHER_P(ConditionalOperator, hasFalseExpression,
/// \brief Matches if a declaration has a body attached.
///
/// Example matches A, va, fa
+/// \code
/// class A {};
/// class B; // Doesn't match, as it has no body.
/// int va;
/// 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.
+/// \endcode
///
/// Usable as: Matcher<TagDecl>, Matcher<VarDecl>, Matcher<FunctionDecl>
inline internal::PolymorphicMatcherWithParam0<internal::IsDefinitionMatcher>
@@ -1795,13 +2293,15 @@ isDefinition() {
/// this to?
///
/// Example matches A() in the last line
-/// (matcher = constructorCall(hasDeclaration(method(
+/// (matcher = constructExpr(hasDeclaration(methodDecl(
/// ofClass(hasName("A"))))))
+/// \code
/// class A {
/// public:
/// A();
/// };
/// A a = A();
+/// \endcode
AST_MATCHER_P(CXXMethodDecl, ofClass,
internal::Matcher<CXXRecordDecl>, InnerMatcher) {
const CXXRecordDecl *Parent = Node.getParent();
@@ -1815,12 +2315,14 @@ AST_MATCHER_P(CXXMethodDecl, ofClass,
/// Member calls on the implicit this pointer match as called with '->'.
///
/// Given
+/// \code
/// class Y {
/// void x() { this->x(); x(); Y y; y.x(); a; this->b; Y::b; }
/// int a;
/// static int b;
/// };
-/// memberExpression(isArrow())
+/// \endcode
+/// memberExpr(isArrow())
/// matches this->x, x, y.x, a, this->b
inline internal::Matcher<MemberExpr> isArrow() {
return makeMatcher(new internal::IsArrowMatcher());
@@ -1829,10 +2331,12 @@ inline internal::Matcher<MemberExpr> isArrow() {
/// \brief Matches QualType nodes that are of integer type.
///
/// Given
+/// \code
/// void a(int);
/// void b(long);
/// void c(double);
-/// function(hasAnyParameter(hasType(isInteger())))
+/// \endcode
+/// functionDecl(hasAnyParameter(hasType(isInteger())))
/// matches "a(int)", "b(long)", but not "c(double)".
AST_MATCHER(QualType, isInteger) {
return Node->isIntegerType();
@@ -1842,12 +2346,14 @@ AST_MATCHER(QualType, isInteger) {
/// include "top-level" const.
///
/// Given
+/// \code
/// void a(int);
/// void b(int const);
/// void c(const int);
/// void d(const int*);
/// void e(int const) {};
-/// function(hasAnyParameter(hasType(isConstQualified())))
+/// \endcode
+/// functionDecl(hasAnyParameter(hasType(isConstQualified())))
/// matches "void b(int const)", "void c(const int)" and
/// "void e(int const) {}". It does not match d as there
/// is no top-level const on the parameter type "const int *".
@@ -1859,10 +2365,12 @@ inline internal::Matcher<QualType> isConstQualified() {
/// given matcher.
///
/// Given
+/// \code
/// struct { int first, second; } first, second;
/// int i(second.first);
/// int j(first.second);
-/// memberExpression(member(hasName("first")))
+/// \endcode
+/// memberExpr(member(hasName("first")))
/// matches second.first
/// but not first.second (because the member name there is "second").
AST_MATCHER_P(MemberExpr, member,
@@ -1874,9 +2382,11 @@ AST_MATCHER_P(MemberExpr, member,
/// matched by a given matcher.
///
/// Given
+/// \code
/// struct X { int m; };
/// void f(X x) { x.m; m; }
-/// memberExpression(hasObjectExpression(hasType(record(hasName("X")))))))
+/// \endcode
+/// memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))))
/// matches "x.m" and "m"
/// with hasObjectExpression(...)
/// matching "x" and the implicit object expression of "m" which has type X*.
@@ -1888,15 +2398,17 @@ AST_MATCHER_P(MemberExpr, hasObjectExpression,
/// \brief Matches any using shadow declaration.
///
/// Given
+/// \code
/// namespace X { void b(); }
/// using X::b;
+/// \endcode
/// usingDecl(hasAnyUsingShadowDecl(hasName("b"))))
/// matches \code using X::b \endcode
AST_MATCHER_P(UsingDecl, hasAnyUsingShadowDecl,
- internal::Matcher<UsingShadowDecl>, Matcher) {
+ internal::Matcher<UsingShadowDecl>, InnerMatcher) {
for (UsingDecl::shadow_iterator II = Node.shadow_begin();
II != Node.shadow_end(); ++II) {
- if (Matcher.matches(**II, Finder, Builder))
+ if (InnerMatcher.matches(**II, Finder, Builder))
return true;
}
return false;
@@ -1906,31 +2418,39 @@ AST_MATCHER_P(UsingDecl, hasAnyUsingShadowDecl,
/// matched by the given matcher.
///
/// Given
+/// \code
/// namespace X { int a; void b(); }
/// using X::a;
/// using X::b;
-/// usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(function())))
+/// \endcode
+/// usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(functionDecl())))
/// matches \code using X::b \endcode
/// but not \code using X::a \endcode
AST_MATCHER_P(UsingShadowDecl, hasTargetDecl,
- internal::Matcher<NamedDecl>, Matcher) {
- return Matcher.matches(*Node.getTargetDecl(), Finder, Builder);
+ internal::Matcher<NamedDecl>, InnerMatcher) {
+ return InnerMatcher.matches(*Node.getTargetDecl(), Finder, Builder);
}
/// \brief Matches template instantiations of function, class, or static
/// member variable template instantiations.
///
/// Given
+/// \code
/// template <typename T> class X {}; class A {}; X<A> x;
+/// \endcode
/// or
+/// \code
/// template <typename T> class X {}; class A {}; template class X<A>;
-/// record(hasName("::X"), isTemplateInstantiation())
+/// \endcode
+/// recordDecl(hasName("::X"), isTemplateInstantiation())
/// matches the template instantiation of X<A>.
///
/// But given
-/// template <typename T> class X {}; class A {};
+/// \code
+/// template <typename T> class X {}; class A {};
/// template <> class X<A> {}; X<A> x;
-/// record(hasName("::X"), isTemplateInstantiation())
+/// \endcode
+/// recordDecl(hasName("::X"), isTemplateInstantiation())
/// does not match, as X<A> is an explicit template specialization.
///
/// Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl>
@@ -1941,6 +2461,411 @@ isTemplateInstantiation() {
internal::IsTemplateInstantiationMatcher>();
}
+/// \brief Matches explicit template specializations of function, class, or
+/// static member variable template instantiations.
+///
+/// Given
+/// \code
+/// template<typename T> void A(T t) { }
+/// template<> void A(int N) { }
+/// \endcode
+/// functionDecl(isExplicitTemplateSpecialization())
+/// matches the specialization A<int>().
+///
+/// Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl>
+inline internal::PolymorphicMatcherWithParam0<
+ internal::IsExplicitTemplateSpecializationMatcher>
+isExplicitTemplateSpecialization() {
+ return internal::PolymorphicMatcherWithParam0<
+ internal::IsExplicitTemplateSpecializationMatcher>();
+}
+
+/// \brief Matches \c TypeLocs for which the given inner
+/// QualType-matcher matches.
+inline internal::BindableMatcher<TypeLoc> loc(
+ const internal::Matcher<QualType> &InnerMatcher) {
+ return internal::BindableMatcher<TypeLoc>(
+ new internal::TypeLocTypeMatcher(InnerMatcher));
+}
+
+/// \brief Matches builtin Types.
+///
+/// Given
+/// \code
+/// struct A {};
+/// A a;
+/// int b;
+/// float c;
+/// bool d;
+/// \endcode
+/// builtinType()
+/// matches "int b", "float c" and "bool d"
+AST_TYPE_MATCHER(BuiltinType, builtinType);
+
+/// \brief Matches all kinds of arrays.
+///
+/// Given
+/// \code
+/// int a[] = { 2, 3 };
+/// int b[4];
+/// void f() { int c[a[0]]; }
+/// \endcode
+/// arrayType()
+/// matches "int a[]", "int b[4]" and "int c[a[0]]";
+AST_TYPE_MATCHER(ArrayType, arrayType);
+
+/// \brief Matches C99 complex types.
+///
+/// Given
+/// \code
+/// _Complex float f;
+/// \endcode
+/// complexType()
+/// matches "_Complex float f"
+AST_TYPE_MATCHER(ComplexType, complexType);
+
+/// \brief Matches arrays and C99 complex types that have a specific element
+/// type.
+///
+/// Given
+/// \code
+/// struct A {};
+/// A a[7];
+/// int b[7];
+/// \endcode
+/// arrayType(hasElementType(builtinType()))
+/// matches "int b[7]"
+///
+/// Usable as: Matcher<ArrayType>, Matcher<ComplexType>
+AST_TYPELOC_TRAVERSE_MATCHER(hasElementType, getElement);
+
+/// \brief Matches C arrays with a specified constant size.
+///
+/// Given
+/// \code
+/// void() {
+/// int a[2];
+/// int b[] = { 2, 3 };
+/// int c[b[0]];
+/// }
+/// \endcode
+/// constantArrayType()
+/// matches "int a[2]"
+AST_TYPE_MATCHER(ConstantArrayType, constantArrayType);
+
+/// \brief Matches \c ConstantArrayType nodes that have the specified size.
+///
+/// Given
+/// \code
+/// int a[42];
+/// int b[2 * 21];
+/// int c[41], d[43];
+/// \endcode
+/// constantArrayType(hasSize(42))
+/// matches "int a[42]" and "int b[2 * 21]"
+AST_MATCHER_P(ConstantArrayType, hasSize, unsigned, N) {
+ return Node.getSize() == N;
+}
+
+/// \brief Matches C++ arrays whose size is a value-dependent expression.
+///
+/// Given
+/// \code
+/// template<typename T, int Size>
+/// class array {
+/// T data[Size];
+/// };
+/// \endcode
+/// dependentSizedArrayType
+/// matches "T data[Size]"
+AST_TYPE_MATCHER(DependentSizedArrayType, dependentSizedArrayType);
+
+/// \brief Matches C arrays with unspecified size.
+///
+/// Given
+/// \code
+/// int a[] = { 2, 3 };
+/// int b[42];
+/// void f(int c[]) { int d[a[0]]; };
+/// \endcode
+/// incompleteArrayType()
+/// matches "int a[]" and "int c[]"
+AST_TYPE_MATCHER(IncompleteArrayType, incompleteArrayType);
+
+/// \brief Matches C arrays with a specified size that is not an
+/// integer-constant-expression.
+///
+/// Given
+/// \code
+/// void f() {
+/// int a[] = { 2, 3 }
+/// int b[42];
+/// int c[a[0]];
+/// \endcode
+/// variableArrayType()
+/// matches "int c[a[0]]"
+AST_TYPE_MATCHER(VariableArrayType, variableArrayType);
+
+/// \brief Matches \c VariableArrayType nodes that have a specific size
+/// expression.
+///
+/// Given
+/// \code
+/// void f(int b) {
+/// int a[b];
+/// }
+/// \endcode
+/// variableArrayType(hasSizeExpr(ignoringImpCasts(declRefExpr(to(
+/// varDecl(hasName("b")))))))
+/// matches "int a[b]"
+AST_MATCHER_P(VariableArrayType, hasSizeExpr,
+ internal::Matcher<Expr>, InnerMatcher) {
+ return InnerMatcher.matches(*Node.getSizeExpr(), Finder, Builder);
+}
+
+/// \brief Matches atomic types.
+///
+/// Given
+/// \code
+/// _Atomic(int) i;
+/// \endcode
+/// atomicType()
+/// matches "_Atomic(int) i"
+AST_TYPE_MATCHER(AtomicType, atomicType);
+
+/// \brief Matches atomic types with a specific value type.
+///
+/// Given
+/// \code
+/// _Atomic(int) i;
+/// _Atomic(float) f;
+/// \endcode
+/// atomicType(hasValueType(isInteger()))
+/// matches "_Atomic(int) i"
+///
+/// Usable as: Matcher<AtomicType>
+AST_TYPELOC_TRAVERSE_MATCHER(hasValueType, getValue);
+
+/// \brief Matches types nodes representing C++11 auto types.
+///
+/// Given:
+/// \code
+/// auto n = 4;
+/// int v[] = { 2, 3 }
+/// for (auto i : v) { }
+/// \endcode
+/// autoType()
+/// matches "auto n" and "auto i"
+AST_TYPE_MATCHER(AutoType, autoType);
+
+/// \brief Matches \c AutoType nodes where the deduced type is a specific type.
+///
+/// Note: There is no \c TypeLoc for the deduced type and thus no
+/// \c getDeducedLoc() matcher.
+///
+/// Given
+/// \code
+/// auto a = 1;
+/// auto b = 2.0;
+/// \endcode
+/// autoType(hasDeducedType(isInteger()))
+/// matches "auto a"
+///
+/// Usable as: Matcher<AutoType>
+AST_TYPE_TRAVERSE_MATCHER(hasDeducedType, getDeducedType);
+
+/// \brief Matches \c FunctionType nodes.
+///
+/// Given
+/// \code
+/// int (*f)(int);
+/// void g();
+/// \endcode
+/// functionType()
+/// matches "int (*f)(int)" and the type of "g".
+AST_TYPE_MATCHER(FunctionType, functionType);
+
+/// \brief Matches block pointer types, i.e. types syntactically represented as
+/// "void (^)(int)".
+///
+/// The \c pointee is always required to be a \c FunctionType.
+AST_TYPE_MATCHER(BlockPointerType, blockPointerType);
+
+/// \brief Matches member pointer types.
+/// Given
+/// \code
+/// struct A { int i; }
+/// A::* ptr = A::i;
+/// \endcode
+/// memberPointerType()
+/// matches "A::* ptr"
+AST_TYPE_MATCHER(MemberPointerType, memberPointerType);
+
+/// \brief Matches pointer types.
+///
+/// Given
+/// \code
+/// int *a;
+/// int &b = *a;
+/// int c = 5;
+/// \endcode
+/// pointerType()
+/// matches "int *a"
+AST_TYPE_MATCHER(PointerType, pointerType);
+
+/// \brief Matches reference types.
+///
+/// Given
+/// \code
+/// int *a;
+/// int &b = *a;
+/// int c = 5;
+/// \endcode
+/// pointerType()
+/// matches "int &b"
+AST_TYPE_MATCHER(ReferenceType, referenceType);
+
+/// \brief Narrows PointerType (and similar) matchers to those where the
+/// \c pointee matches a given matcher.
+///
+/// Given
+/// \code
+/// int *a;
+/// int const *b;
+/// float const *f;
+/// \endcode
+/// pointerType(pointee(isConstQualified(), isInteger()))
+/// matches "int const *b"
+///
+/// Usable as: Matcher<BlockPointerType>, Matcher<MemberPointerType>,
+/// Matcher<PointerType>, Matcher<ReferenceType>
+AST_TYPELOC_TRAVERSE_MATCHER(pointee, getPointee);
+
+/// \brief Matches typedef types.
+///
+/// Given
+/// \code
+/// typedef int X;
+/// \endcode
+/// typedefType()
+/// matches "typedef int X"
+AST_TYPE_MATCHER(TypedefType, typedefType);
+
+/// \brief Matches \c TypedefTypes referring to a specific
+/// \c TypedefNameDecl.
+AST_MATCHER_P(TypedefType, hasDecl,
+ internal::Matcher<TypedefNameDecl>, InnerMatcher) {
+ return InnerMatcher.matches(*Node.getDecl(), Finder, Builder);
+}
+
+/// \brief Matches nested name specifiers.
+///
+/// Given
+/// \code
+/// namespace ns {
+/// struct A { static void f(); };
+/// void A::f() {}
+/// void g() { A::f(); }
+/// }
+/// ns::A a;
+/// \endcode
+/// nestedNameSpecifier()
+/// matches "ns::" and both "A::"
+const internal::VariadicAllOfMatcher<NestedNameSpecifier> nestedNameSpecifier;
+
+/// \brief Same as \c nestedNameSpecifier but matches \c NestedNameSpecifierLoc.
+const internal::VariadicAllOfMatcher<
+ NestedNameSpecifierLoc> nestedNameSpecifierLoc;
+
+/// \brief Matches \c NestedNameSpecifierLocs for which the given inner
+/// NestedNameSpecifier-matcher matches.
+inline internal::BindableMatcher<NestedNameSpecifierLoc> loc(
+ const internal::Matcher<NestedNameSpecifier> &InnerMatcher) {
+ return internal::BindableMatcher<NestedNameSpecifierLoc>(
+ new internal::LocMatcher<NestedNameSpecifierLoc, NestedNameSpecifier>(
+ InnerMatcher));
+}
+
+/// \brief Matches nested name specifiers that specify a type matching the
+/// given \c QualType matcher without qualifiers.
+///
+/// Given
+/// \code
+/// struct A { struct B { struct C {}; }; };
+/// A::B::C c;
+/// \endcode
+/// nestedNameSpecifier(specifiesType(hasDeclaration(recordDecl(hasName("A")))))
+/// matches "A::"
+AST_MATCHER_P(NestedNameSpecifier, specifiesType,
+ internal::Matcher<QualType>, InnerMatcher) {
+ if (Node.getAsType() == NULL)
+ return false;
+ return InnerMatcher.matches(QualType(Node.getAsType(), 0), Finder, Builder);
+}
+
+/// \brief Matches nested name specifier locs that specify a type matching the
+/// given \c TypeLoc.
+///
+/// Given
+/// \code
+/// struct A { struct B { struct C {}; }; };
+/// A::B::C c;
+/// \endcode
+/// nestedNameSpecifierLoc(specifiesTypeLoc(loc(type(
+/// hasDeclaration(recordDecl(hasName("A")))))))
+/// matches "A::"
+AST_MATCHER_P(NestedNameSpecifierLoc, specifiesTypeLoc,
+ internal::Matcher<TypeLoc>, InnerMatcher) {
+ return InnerMatcher.matches(Node.getTypeLoc(), Finder, Builder);
+}
+
+/// \brief Matches on the prefix of a \c NestedNameSpecifier.
+///
+/// Given
+/// \code
+/// struct A { struct B { struct C {}; }; };
+/// A::B::C c;
+/// \endcode
+/// nestedNameSpecifier(hasPrefix(specifiesType(asString("struct A")))) and
+/// matches "A::"
+inline internal::Matcher<NestedNameSpecifier> hasPrefix(
+ const internal::Matcher<NestedNameSpecifier> &InnerMatcher) {
+ return internal::makeMatcher(
+ new internal::NestedNameSpecifierPrefixMatcher(InnerMatcher));
+}
+
+/// \brief Matches on the prefix of a \c NestedNameSpecifierLoc.
+///
+/// Given
+/// \code
+/// struct A { struct B { struct C {}; }; };
+/// A::B::C c;
+/// \endcode
+/// nestedNameSpecifierLoc(hasPrefix(loc(specifiesType(asString("struct A")))))
+/// matches "A::"
+inline internal::Matcher<NestedNameSpecifierLoc> hasPrefix(
+ const internal::Matcher<NestedNameSpecifierLoc> &InnerMatcher) {
+ return internal::makeMatcher(
+ new internal::NestedNameSpecifierLocPrefixMatcher(InnerMatcher));
+}
+
+/// \brief Matches nested name specifiers that specify a namespace matching the
+/// given namespace matcher.
+///
+/// Given
+/// \code
+/// namespace ns { struct A {}; }
+/// ns::A a;
+/// \endcode
+/// nestedNameSpecifier(specifiesNamespace(hasName("ns")))
+/// matches "ns::"
+AST_MATCHER_P(NestedNameSpecifier, specifiesNamespace,
+ internal::Matcher<NamespaceDecl>, InnerMatcher) {
+ if (Node.getAsNamespace() == NULL)
+ return false;
+ return InnerMatcher.matches(*Node.getAsNamespace(), Finder, Builder);
+}
+
} // end namespace ast_matchers
} // end namespace clang
diff --git a/include/clang/ASTMatchers/ASTMatchersInternal.h b/include/clang/ASTMatchers/ASTMatchersInternal.h
index 3f5568521c0e..e5365ff89d72 100644
--- a/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ b/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -39,7 +39,11 @@
#include "clang/AST/DeclCXX.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtCXX.h"
+#include "clang/AST/Type.h"
+#include "clang/ASTMatchers/ASTTypeTraits.h"
#include "llvm/ADT/VariadicFunction.h"
+#include "llvm/Support/type_traits.h"
#include <map>
#include <string>
#include <vector>
@@ -57,6 +61,45 @@ class BoundNodes;
namespace internal {
class BoundNodesTreeBuilder;
+/// \brief Internal version of BoundNodes. Holds all the bound nodes.
+class BoundNodesMap {
+public:
+ /// \brief Adds \c Node to the map with key \c ID.
+ ///
+ /// The node's base type should be in NodeBaseType or it will be unaccessible.
+ template <typename T>
+ void addNode(StringRef ID, const T* Node) {
+ NodeMap[ID] = ast_type_traits::DynTypedNode::create(*Node);
+ }
+ void addNode(StringRef ID, ast_type_traits::DynTypedNode Node) {
+ NodeMap[ID] = Node;
+ }
+
+ /// \brief Returns the AST node bound to \c ID.
+ ///
+ /// Returns NULL if there was no node bound to \c ID or if there is a node but
+ /// it cannot be converted to the specified type.
+ template <typename T>
+ const T *getNodeAs(StringRef ID) const {
+ IDToNodeMap::const_iterator It = NodeMap.find(ID);
+ if (It == NodeMap.end()) {
+ return NULL;
+ }
+ return It->second.get<T>();
+ }
+
+ /// \brief Copies all ID/Node pairs to BoundNodesTreeBuilder \c Builder.
+ void copyTo(BoundNodesTreeBuilder *Builder) const;
+
+ /// \brief Copies all ID/Node pairs to BoundNodesMap \c Other.
+ void copyTo(BoundNodesMap *Other) const;
+
+private:
+ /// \brief A map from IDs to the bound nodes.
+ typedef std::map<std::string, ast_type_traits::DynTypedNode> IDToNodeMap;
+
+ IDToNodeMap NodeMap;
+};
/// \brief A tree of bound nodes in match results.
///
@@ -84,11 +127,10 @@ public:
BoundNodesTree();
/// \brief Create a BoundNodesTree from pre-filled maps of bindings.
- BoundNodesTree(const std::map<std::string, const Decl*>& DeclBindings,
- const std::map<std::string, const Stmt*>& StmtBindings,
+ BoundNodesTree(const BoundNodesMap& Bindings,
const std::vector<BoundNodesTree> RecursiveBindings);
- /// \brief Adds all bound nodes to bound_nodes_builder.
+ /// \brief Adds all bound nodes to \c Builder.
void copyTo(BoundNodesTreeBuilder* Builder) const;
/// \brief Visits all matches that this BoundNodesTree represents.
@@ -99,17 +141,12 @@ public:
private:
void visitMatchesRecursively(
Visitor* ResultVistior,
- std::map<std::string, const Decl*> DeclBindings,
- std::map<std::string, const Stmt*> StmtBindings);
-
- template <typename T>
- void copyBindingsTo(const T& bindings, BoundNodesTreeBuilder* Builder) const;
+ const BoundNodesMap& AggregatedBindings);
// FIXME: Find out whether we want to use different data structures here -
// first benchmarks indicate that it doesn't matter though.
- std::map<std::string, const Decl*> DeclBindings;
- std::map<std::string, const Stmt*> StmtBindings;
+ BoundNodesMap Bindings;
std::vector<BoundNodesTree> RecursiveBindings;
};
@@ -123,12 +160,13 @@ public:
BoundNodesTreeBuilder();
/// \brief Add a binding from an id to a node.
- ///
- /// FIXME: Add overloads for all AST base types.
- /// @{
- void setBinding(const std::string &Id, const Decl *Node);
- void setBinding(const std::string &Id, const Stmt *Node);
- /// @}
+ template <typename T>
+ void setBinding(const std::string &Id, const T *Node) {
+ Bindings.addNode(Id, Node);
+ }
+ void setBinding(const std::string &Id, ast_type_traits::DynTypedNode Node) {
+ Bindings.addNode(Id, Node);
+ }
/// \brief Adds a branch in the tree.
void addMatch(const BoundNodesTree& Bindings);
@@ -137,11 +175,10 @@ public:
BoundNodesTree build() const;
private:
- BoundNodesTreeBuilder(const BoundNodesTreeBuilder&); // DO NOT IMPLEMENT
- void operator=(const BoundNodesTreeBuilder&); // DO NOT IMPLEMENT
+ BoundNodesTreeBuilder(const BoundNodesTreeBuilder &) LLVM_DELETED_FUNCTION;
+ void operator=(const BoundNodesTreeBuilder &) LLVM_DELETED_FUNCTION;
- std::map<std::string, const Decl*> DeclBindings;
- std::map<std::string, const Stmt*> StmtBindings;
+ BoundNodesMap Bindings;
std::vector<BoundNodesTree> RecursiveBindings;
};
@@ -169,7 +206,8 @@ public:
BoundNodesTreeBuilder *Builder) const = 0;
};
-/// \brief Interface for matchers that only evaluate properties on a single node.
+/// \brief Interface for matchers that only evaluate properties on a single
+/// node.
template <typename T>
class SingleNodeMatcherInterface : public MatcherInterface<T> {
public:
@@ -187,6 +225,24 @@ private:
}
};
+/// \brief Base class for all matchers that works on a \c DynTypedNode.
+///
+/// Matcher implementations will check whether the \c DynTypedNode is
+/// convertible into the respecitve types and then do the actual match
+/// on the actual node, or return false if it is not convertible.
+class DynTypedMatcher {
+public:
+ virtual ~DynTypedMatcher() {}
+
+ /// \brief Returns true if the matcher matches the given \c DynNode.
+ virtual bool matches(const ast_type_traits::DynTypedNode DynNode,
+ ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const = 0;
+
+ /// \brief Returns a unique ID for the matcher.
+ virtual uint64_t getID() const = 0;
+};
+
/// \brief Wrapper of a MatcherInterface<T> *that allows copying.
///
/// A Matcher<Base> can be used anywhere a Matcher<Derived> is
@@ -196,12 +252,32 @@ private:
/// operator rather than a type hierarchy to be able to templatize the
/// type hierarchy instead of spelling it out.
template <typename T>
-class Matcher {
+class Matcher : public DynTypedMatcher {
public:
/// \brief Takes ownership of the provided implementation pointer.
explicit Matcher(MatcherInterface<T> *Implementation)
: Implementation(Implementation) {}
+ /// \brief Implicitly converts \c Other to a Matcher<T>.
+ ///
+ /// Requires \c T to be derived from \c From.
+ template <typename From>
+ Matcher(const Matcher<From> &Other,
+ typename llvm::enable_if_c<
+ llvm::is_base_of<From, T>::value &&
+ !llvm::is_same<From, T>::value >::type* = 0)
+ : Implementation(new ImplicitCastMatcher<From>(Other)) {}
+
+ /// \brief Implicitly converts \c Matcher<Type> to \c Matcher<QualType>.
+ ///
+ /// The resulting matcher is not strict, i.e. ignores qualifiers.
+ template <typename TypeT>
+ Matcher(const Matcher<TypeT> &Other,
+ typename llvm::enable_if_c<
+ llvm::is_same<T, QualType>::value &&
+ llvm::is_same<TypeT, Type>::value >::type* = 0)
+ : Implementation(new TypeToQualType<TypeT>(Other)) {}
+
/// \brief Forwards the call to the underlying MatcherInterface<T> pointer.
bool matches(const T &Node,
ASTMatchFinder *Finder,
@@ -209,14 +285,6 @@ public:
return Implementation->matches(Node, Finder, Builder);
}
- /// \brief Implicitly converts this object to a Matcher<Derived>.
- ///
- /// Requires Derived to be derived from T.
- template <typename Derived>
- operator Matcher<Derived>() const {
- return Matcher<Derived>(new ImplicitCastMatcher<Derived>(*this));
- }
-
/// \brief Returns an ID that uniquely identifies the matcher.
uint64_t getID() const {
/// FIXME: Document the requirements this imposes on matcher
@@ -224,23 +292,55 @@ public:
return reinterpret_cast<uint64_t>(Implementation.getPtr());
}
+ /// \brief Returns whether the matcher matches on the given \c DynNode.
+ virtual bool matches(const ast_type_traits::DynTypedNode DynNode,
+ ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const {
+ const T *Node = DynNode.get<T>();
+ if (!Node) return false;
+ return matches(*Node, Finder, Builder);
+ }
+
+ /// \brief Allows the conversion of a \c Matcher<Type> to a \c
+ /// Matcher<QualType>.
+ ///
+ /// Depending on the constructor argument, the matcher is either strict, i.e.
+ /// does only matches in the absence of qualifiers, or not, i.e. simply
+ /// ignores any qualifiers.
+ template <typename TypeT>
+ class TypeToQualType : public MatcherInterface<QualType> {
+ public:
+ TypeToQualType(const Matcher<TypeT> &InnerMatcher)
+ : InnerMatcher(InnerMatcher) {}
+
+ virtual bool matches(const QualType &Node,
+ ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const {
+ if (Node.isNull())
+ return false;
+ return InnerMatcher.matches(*Node, Finder, Builder);
+ }
+ private:
+ const Matcher<TypeT> InnerMatcher;
+ };
+
private:
- /// \brief Allows conversion from Matcher<T> to Matcher<Derived> if Derived
- /// is derived from T.
- template <typename Derived>
- class ImplicitCastMatcher : public MatcherInterface<Derived> {
+ /// \brief Allows conversion from Matcher<Base> to Matcher<T> if T
+ /// is derived from Base.
+ template <typename Base>
+ class ImplicitCastMatcher : public MatcherInterface<T> {
public:
- explicit ImplicitCastMatcher(const Matcher<T> &From)
+ explicit ImplicitCastMatcher(const Matcher<Base> &From)
: From(From) {}
- virtual bool matches(const Derived &Node,
+ virtual bool matches(const T &Node,
ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const {
return From.matches(Node, Finder, Builder);
}
private:
- const Matcher<T> From;
+ const Matcher<Base> From;
};
llvm::IntrusiveRefCntPtr< MatcherInterface<T> > Implementation;
@@ -280,18 +380,14 @@ private:
/// FIXME: Add other ways to convert...
if (Node.isNull())
return false;
- CXXRecordDecl *NodeAsRecordDecl = Node->getAsCXXRecordDecl();
- return NodeAsRecordDecl != NULL &&
- InnerMatcher.matches(*NodeAsRecordDecl, Finder, Builder);
+ return matchesDecl(Node->getAsCXXRecordDecl(), Finder, Builder);
}
/// \brief Extracts the Decl of the callee of a CallExpr and returns whether
/// the inner matcher matches on it.
bool matchesSpecialized(const CallExpr &Node, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const {
- const Decl *NodeAsDecl = Node.getCalleeDecl();
- return NodeAsDecl != NULL &&
- InnerMatcher.matches(*NodeAsDecl, Finder, Builder);
+ return matchesDecl(Node.getCalleeDecl(), Finder, Builder);
}
/// \brief Extracts the Decl of the constructor call and returns whether the
@@ -299,96 +395,63 @@ private:
bool matchesSpecialized(const CXXConstructExpr &Node,
ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const {
- const Decl *NodeAsDecl = Node.getConstructor();
- return NodeAsDecl != NULL &&
- InnerMatcher.matches(*NodeAsDecl, Finder, Builder);
+ return matchesDecl(Node.getConstructor(), Finder, Builder);
+ }
+
+ /// \brief Extracts the \c ValueDecl a \c MemberExpr refers to and returns
+ /// whether the inner matcher matches on it.
+ bool matchesSpecialized(const MemberExpr &Node,
+ ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const {
+ return matchesDecl(Node.getMemberDecl(), 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,
+ BoundNodesTreeBuilder *Builder) const {
+ return Node != NULL && InnerMatcher.matches(*Node, Finder, Builder);
}
const Matcher<Decl> InnerMatcher;
};
/// \brief IsBaseType<T>::value is true if T is a "base" type in the AST
-/// node class hierarchies (i.e. if T is Decl, Stmt, or QualType).
+/// node class hierarchies.
template <typename T>
struct IsBaseType {
static const bool value =
(llvm::is_same<T, Decl>::value ||
llvm::is_same<T, Stmt>::value ||
llvm::is_same<T, QualType>::value ||
+ llvm::is_same<T, Type>::value ||
+ llvm::is_same<T, TypeLoc>::value ||
+ llvm::is_same<T, NestedNameSpecifier>::value ||
+ llvm::is_same<T, NestedNameSpecifierLoc>::value ||
llvm::is_same<T, CXXCtorInitializer>::value);
};
template <typename T>
const bool IsBaseType<T>::value;
-/// \brief Interface that can match any AST base node type and contains default
-/// implementations returning false.
-class UntypedBaseMatcher : public llvm::RefCountedBaseVPTR {
-public:
- virtual ~UntypedBaseMatcher() {}
-
- virtual bool matches(const Decl &DeclNode, ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
- return false;
- }
- virtual bool matches(const QualType &TypeNode, ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
- return false;
- }
- virtual bool matches(const Stmt &StmtNode, ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
- return false;
- }
- virtual bool matches(const CXXCtorInitializer &CtorInitNode,
- ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
- return false;
- }
-
- /// \brief Returns a unique ID for the matcher.
- virtual uint64_t getID() const = 0;
-};
-
-/// \brief An UntypedBaseMatcher that overwrites the Matches(...) method for
-/// node type T. T must be an AST base type.
-template <typename T>
-class TypedBaseMatcher : public UntypedBaseMatcher {
- TOOLING_COMPILE_ASSERT(IsBaseType<T>::value,
- typed_base_matcher_can_only_be_used_with_base_type);
-public:
- explicit TypedBaseMatcher(const Matcher<T> &InnerMatcher)
- : InnerMatcher(InnerMatcher) {}
-
- using UntypedBaseMatcher::matches;
- /// \brief Implements UntypedBaseMatcher::Matches.
- ///
- /// Since T is guaranteed to be a "base" AST node type, this method is
- /// guaranteed to override one of the matches() methods from
- /// UntypedBaseMatcher.
- virtual bool matches(const T &Node,
- ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
- return InnerMatcher.matches(Node, Finder, Builder);
- }
-
- /// \brief Implements UntypedBaseMatcher::getID.
- virtual uint64_t getID() const {
- return InnerMatcher.getID();
- }
-
-private:
- Matcher<T> InnerMatcher;
-};
-
/// \brief Interface that allows matchers to traverse the AST.
/// FIXME: Find a better name.
///
-/// This provides two entry methods for each base node type in the AST:
-/// - matchesChildOf:
+/// This provides three entry methods for each base node type in the AST:
+/// - \c matchesChildOf:
/// Matches a matcher on every child node of the given node. Returns true
/// if at least one child node could be matched.
-/// - matchesDescendantOf:
+/// - \c matchesDescendantOf:
/// Matches a matcher on all descendant nodes of the given node. Returns true
/// if at least one descendant matched.
+/// - \c matchesAncestorOf:
+/// Matches a matcher on all ancestors of the given node. Returns true if
+/// at least one ancestor matched.
+///
+/// FIXME: Currently we only allow Stmt and Decl nodes to start a traversal.
+/// In the future, we wan to implement this for all nodes for which it makes
+/// sense. In the case of matchesAncestorOf, we'll want to implement it for
+/// all nodes, as all nodes have ancestors.
class ASTMatchFinder {
public:
/// \brief Defines how we descend a level in the AST when we pass
@@ -408,6 +471,14 @@ public:
BK_All
};
+ /// \brief Defines which ancestors are considered for a match.
+ enum AncestorMatchMode {
+ /// All ancestors.
+ AMM_All,
+ /// Direct parent only.
+ AMM_ParentOnly
+ };
+
virtual ~ASTMatchFinder() {}
/// \brief Returns true if the given class is directly or indirectly derived
@@ -418,26 +489,70 @@ public:
const Matcher<NamedDecl> &Base,
BoundNodesTreeBuilder *Builder) = 0;
- // FIXME: Implement for other base nodes.
- virtual bool matchesChildOf(const Decl &DeclNode,
- const UntypedBaseMatcher &BaseMatcher,
- BoundNodesTreeBuilder *Builder,
- TraversalKind Traverse,
- BindKind Bind) = 0;
- virtual bool matchesChildOf(const Stmt &StmtNode,
- const UntypedBaseMatcher &BaseMatcher,
+ template <typename T>
+ bool matchesChildOf(const T &Node,
+ const DynTypedMatcher &Matcher,
+ BoundNodesTreeBuilder *Builder,
+ TraversalKind Traverse,
+ BindKind Bind) {
+ TOOLING_COMPILE_ASSERT(
+ (llvm::is_base_of<Decl, T>::value ||
+ llvm::is_base_of<Stmt, T>::value ||
+ llvm::is_base_of<NestedNameSpecifier, T>::value ||
+ llvm::is_base_of<NestedNameSpecifierLoc, T>::value ||
+ llvm::is_base_of<TypeLoc, T>::value ||
+ llvm::is_base_of<QualType, T>::value),
+ unsupported_type_for_recursive_matching);
+ return matchesChildOf(ast_type_traits::DynTypedNode::create(Node),
+ Matcher, Builder, Traverse, Bind);
+ }
+
+ template <typename T>
+ bool matchesDescendantOf(const T &Node,
+ const DynTypedMatcher &Matcher,
+ BoundNodesTreeBuilder *Builder,
+ BindKind Bind) {
+ TOOLING_COMPILE_ASSERT(
+ (llvm::is_base_of<Decl, T>::value ||
+ llvm::is_base_of<Stmt, T>::value ||
+ llvm::is_base_of<NestedNameSpecifier, T>::value ||
+ llvm::is_base_of<NestedNameSpecifierLoc, T>::value ||
+ llvm::is_base_of<TypeLoc, T>::value ||
+ llvm::is_base_of<QualType, T>::value),
+ unsupported_type_for_recursive_matching);
+ return matchesDescendantOf(ast_type_traits::DynTypedNode::create(Node),
+ Matcher, Builder, Bind);
+ }
+
+ // FIXME: Implement support for BindKind.
+ template <typename T>
+ bool matchesAncestorOf(const T &Node,
+ const DynTypedMatcher &Matcher,
+ BoundNodesTreeBuilder *Builder,
+ AncestorMatchMode MatchMode) {
+ TOOLING_COMPILE_ASSERT((llvm::is_base_of<Decl, T>::value ||
+ llvm::is_base_of<Stmt, T>::value),
+ only_Decl_or_Stmt_allowed_for_recursive_matching);
+ return matchesAncestorOf(ast_type_traits::DynTypedNode::create(Node),
+ Matcher, Builder, MatchMode);
+ }
+
+protected:
+ virtual bool matchesChildOf(const ast_type_traits::DynTypedNode &Node,
+ const DynTypedMatcher &Matcher,
BoundNodesTreeBuilder *Builder,
TraversalKind Traverse,
BindKind Bind) = 0;
- virtual bool matchesDescendantOf(const Decl &DeclNode,
- const UntypedBaseMatcher &BaseMatcher,
- BoundNodesTreeBuilder *Builder,
- BindKind Bind) = 0;
- virtual bool matchesDescendantOf(const Stmt &StmtNode,
- const UntypedBaseMatcher &BaseMatcher,
+ virtual bool matchesDescendantOf(const ast_type_traits::DynTypedNode &Node,
+ const DynTypedMatcher &Matcher,
BoundNodesTreeBuilder *Builder,
BindKind Bind) = 0;
+
+ virtual bool matchesAncestorOf(const ast_type_traits::DynTypedNode &Node,
+ const DynTypedMatcher &Matcher,
+ BoundNodesTreeBuilder *Builder,
+ AncestorMatchMode MatchMode) = 0;
};
/// \brief Converts a \c Matcher<T> to a matcher of desired type \c To by
@@ -606,9 +721,6 @@ public:
/// The returned matcher is equivalent to this matcher, but will
/// bind the matched node on a match.
Matcher<T> bind(StringRef ID) const {
- TOOLING_COMPILE_ASSERT((llvm::is_base_of<Stmt, T>::value ||
- llvm::is_base_of<Decl, T>::value),
- trying_to_bind_unsupported_node_type__only_decl_and_stmt_supported);
return Matcher<T>(new IdMatcher<T>(ID, *this));
}
};
@@ -635,7 +747,7 @@ public:
}
private:
- const TypedBaseMatcher<ChildT> ChildMatcher;
+ const Matcher<ChildT> ChildMatcher;
};
/// \brief Matches nodes of type T that have child nodes of type ChildT for
@@ -661,7 +773,7 @@ class ForEachMatcher : public MatcherInterface<T> {
}
private:
- const TypedBaseMatcher<ChildT> ChildMatcher;
+ const Matcher<ChildT> ChildMatcher;
};
/// \brief Matches nodes of type T if the given Matcher<T> does not match.
@@ -733,6 +845,20 @@ private:
const Matcher<T> InnertMatcher2;
};
+/// \brief Creates a Matcher<T> that matches if all inner matchers match.
+template<typename T>
+BindableMatcher<T> makeAllOfComposite(
+ ArrayRef<const Matcher<T> *> InnerMatchers) {
+ if (InnerMatchers.empty())
+ return BindableMatcher<T>(new TrueMatcher<T>);
+ MatcherInterface<T> *InnerMatcher = new TrueMatcher<T>;
+ for (int i = InnerMatchers.size() - 1; i >= 0; --i) {
+ InnerMatcher = new AllOfMatcher<T, Matcher<T>, Matcher<T> >(
+ *InnerMatchers[i], makeMatcher(InnerMatcher));
+ }
+ return BindableMatcher<T>(InnerMatcher);
+}
+
/// \brief Creates a Matcher<T> that matches if
/// T is dyn_cast'able into InnerT and all inner matchers match.
///
@@ -742,17 +868,8 @@ private:
template<typename T, typename InnerT>
BindableMatcher<T> makeDynCastAllOfComposite(
ArrayRef<const Matcher<InnerT> *> InnerMatchers) {
- if (InnerMatchers.empty()) {
- Matcher<InnerT> InnerMatcher = makeMatcher(new TrueMatcher<InnerT>);
- return BindableMatcher<T>(new DynCastMatcher<T, InnerT>(InnerMatcher));
- }
- Matcher<InnerT> InnerMatcher = *InnerMatchers.back();
- for (int i = InnerMatchers.size() - 2; i >= 0; --i) {
- InnerMatcher = makeMatcher(
- new AllOfMatcher<InnerT, Matcher<InnerT>, Matcher<InnerT> >(
- *InnerMatchers[i], InnerMatcher));
- }
- return BindableMatcher<T>(new DynCastMatcher<T, InnerT>(InnerMatcher));
+ return BindableMatcher<T>(new DynCastMatcher<T, InnerT>(
+ makeAllOfComposite(InnerMatchers)));
}
/// \brief Matches nodes of type T that have at least one descendant node of
@@ -775,7 +892,53 @@ public:
}
private:
- const TypedBaseMatcher<DescendantT> DescendantMatcher;
+ const Matcher<DescendantT> DescendantMatcher;
+};
+
+/// \brief Matches nodes of type \c T that have a parent node of type \c ParentT
+/// for which the given inner matcher matches.
+///
+/// \c ParentT must be an AST base type.
+template <typename T, typename ParentT>
+class HasParentMatcher : public MatcherInterface<T> {
+ TOOLING_COMPILE_ASSERT(IsBaseType<ParentT>::value,
+ has_parent_only_accepts_base_type_matcher);
+public:
+ explicit HasParentMatcher(const Matcher<ParentT> &ParentMatcher)
+ : ParentMatcher(ParentMatcher) {}
+
+ virtual bool matches(const T &Node,
+ ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const {
+ return Finder->matchesAncestorOf(
+ Node, ParentMatcher, Builder, ASTMatchFinder::AMM_ParentOnly);
+ }
+
+ private:
+ const Matcher<ParentT> ParentMatcher;
+};
+
+/// \brief Matches nodes of type \c T that have at least one ancestor node of
+/// type \c AncestorT for which the given inner matcher matches.
+///
+/// \c AncestorT must be an AST base type.
+template <typename T, typename AncestorT>
+class HasAncestorMatcher : public MatcherInterface<T> {
+ TOOLING_COMPILE_ASSERT(IsBaseType<AncestorT>::value,
+ has_ancestor_only_accepts_base_type_matcher);
+public:
+ explicit HasAncestorMatcher(const Matcher<AncestorT> &AncestorMatcher)
+ : AncestorMatcher(AncestorMatcher) {}
+
+ virtual bool matches(const T &Node,
+ ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const {
+ return Finder->matchesAncestorOf(
+ Node, AncestorMatcher, Builder, ASTMatchFinder::AMM_All);
+ }
+
+ private:
+ const Matcher<AncestorT> AncestorMatcher;
};
/// \brief Matches nodes of type T that have at least one descendant node of
@@ -801,7 +964,7 @@ class ForEachDescendantMatcher : public MatcherInterface<T> {
}
private:
- const TypedBaseMatcher<DescendantT> DescendantMatcher;
+ const Matcher<DescendantT> DescendantMatcher;
};
/// \brief Matches on nodes that have a getValue() method if getValue() equals
@@ -858,6 +1021,22 @@ class IsTemplateInstantiationMatcher : public MatcherInterface<T> {
}
};
+/// \brief Matches on explicit template specializations for FunctionDecl,
+/// VarDecl or CXXRecordDecl nodes.
+template <typename T>
+class IsExplicitTemplateSpecializationMatcher : public MatcherInterface<T> {
+ TOOLING_COMPILE_ASSERT((llvm::is_base_of<FunctionDecl, T>::value) ||
+ (llvm::is_base_of<VarDecl, T>::value) ||
+ (llvm::is_base_of<CXXRecordDecl, T>::value),
+ requires_getTemplateSpecializationKind_method);
+ public:
+ virtual bool matches(const T& Node,
+ ASTMatchFinder* Finder,
+ BoundNodesTreeBuilder* Builder) const {
+ return (Node.getTemplateSpecializationKind() == TSK_ExplicitSpecialization);
+ }
+};
+
class IsArrowMatcher : public SingleNodeMatcherInterface<MemberExpr> {
public:
virtual bool matchesNode(const MemberExpr &Node) const {
@@ -894,6 +1073,166 @@ public:
VariadicDynCastAllOfMatcher() {}
};
+/// \brief A \c VariadicAllOfMatcher<T> object is a variadic functor that takes
+/// a number of \c Matcher<T> and returns a \c Matcher<T> that matches \c T
+/// nodes that are matched by all of the given matchers.
+///
+/// For example:
+/// const VariadicAllOfMatcher<NestedNameSpecifier> nestedNameSpecifier;
+/// Creates a functor nestedNameSpecifier(...) that creates a
+/// \c Matcher<NestedNameSpecifier> given a variable number of arguments of type
+/// \c Matcher<NestedNameSpecifier>.
+/// The returned matcher matches if all given matchers match.
+template <typename T>
+class VariadicAllOfMatcher : public llvm::VariadicFunction<
+ BindableMatcher<T>, Matcher<T>,
+ makeAllOfComposite<T> > {
+public:
+ VariadicAllOfMatcher() {}
+};
+
+/// \brief Matches nodes of type \c TLoc for which the inner
+/// \c Matcher<T> matches.
+template <typename TLoc, typename T>
+class LocMatcher : public MatcherInterface<TLoc> {
+public:
+ explicit LocMatcher(const Matcher<T> &InnerMatcher)
+ : InnerMatcher(InnerMatcher) {}
+
+ virtual bool matches(const TLoc &Node,
+ ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const {
+ if (!Node)
+ return false;
+ return InnerMatcher.matches(*extract(Node), Finder, Builder);
+ }
+
+private:
+ const NestedNameSpecifier *extract(const NestedNameSpecifierLoc &Loc) const {
+ return Loc.getNestedNameSpecifier();
+ }
+
+ const Matcher<T> InnerMatcher;
+};
+
+/// \brief Matches \c NestedNameSpecifiers with a prefix matching another
+/// \c Matcher<NestedNameSpecifier>.
+class NestedNameSpecifierPrefixMatcher
+ : public MatcherInterface<NestedNameSpecifier> {
+public:
+ explicit NestedNameSpecifierPrefixMatcher(
+ const Matcher<NestedNameSpecifier> &InnerMatcher)
+ : InnerMatcher(InnerMatcher) {}
+
+ virtual bool matches(const NestedNameSpecifier &Node,
+ ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const {
+ NestedNameSpecifier *NextNode = Node.getPrefix();
+ if (NextNode == NULL)
+ return false;
+ return InnerMatcher.matches(*NextNode, Finder, Builder);
+ }
+
+private:
+ const Matcher<NestedNameSpecifier> InnerMatcher;
+};
+
+/// \brief Matches \c NestedNameSpecifierLocs with a prefix matching another
+/// \c Matcher<NestedNameSpecifierLoc>.
+class NestedNameSpecifierLocPrefixMatcher
+ : public MatcherInterface<NestedNameSpecifierLoc> {
+public:
+ explicit NestedNameSpecifierLocPrefixMatcher(
+ const Matcher<NestedNameSpecifierLoc> &InnerMatcher)
+ : InnerMatcher(InnerMatcher) {}
+
+ virtual bool matches(const NestedNameSpecifierLoc &Node,
+ ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const {
+ NestedNameSpecifierLoc NextNode = Node.getPrefix();
+ if (!NextNode)
+ return false;
+ return InnerMatcher.matches(NextNode, Finder, Builder);
+ }
+
+private:
+ const Matcher<NestedNameSpecifierLoc> InnerMatcher;
+};
+
+/// \brief Matches \c TypeLocs based on an inner matcher matching a certain
+/// \c QualType.
+///
+/// Used to implement the \c loc() matcher.
+class TypeLocTypeMatcher : public MatcherInterface<TypeLoc> {
+public:
+ explicit TypeLocTypeMatcher(const Matcher<QualType> &InnerMatcher)
+ : InnerMatcher(InnerMatcher) {}
+
+ virtual bool matches(const TypeLoc &Node,
+ ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const {
+ if (!Node)
+ return false;
+ return InnerMatcher.matches(Node.getType(), Finder, Builder);
+ }
+
+private:
+ const Matcher<QualType> InnerMatcher;
+};
+
+/// \brief Matches nodes of type \c T for which the inner matcher matches on a
+/// another node of type \c T that can be reached using a given traverse
+/// function.
+template <typename T>
+class TypeTraverseMatcher : public MatcherInterface<T> {
+public:
+ explicit TypeTraverseMatcher(const Matcher<QualType> &InnerMatcher,
+ QualType (T::*TraverseFunction)() const)
+ : InnerMatcher(InnerMatcher), TraverseFunction(TraverseFunction) {}
+
+ virtual bool matches(const T &Node,
+ ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const {
+ QualType NextNode = (Node.*TraverseFunction)();
+ if (NextNode.isNull())
+ return false;
+ return InnerMatcher.matches(NextNode, Finder, Builder);
+ }
+
+private:
+ const Matcher<QualType> InnerMatcher;
+ QualType (T::*TraverseFunction)() const;
+};
+
+/// \brief Matches nodes of type \c T in a ..Loc hierarchy, for which the inner
+/// matcher matches on a another node of type \c T that can be reached using a
+/// given traverse function.
+template <typename T>
+class TypeLocTraverseMatcher : public MatcherInterface<T> {
+public:
+ explicit TypeLocTraverseMatcher(const Matcher<TypeLoc> &InnerMatcher,
+ TypeLoc (T::*TraverseFunction)() const)
+ : InnerMatcher(InnerMatcher), TraverseFunction(TraverseFunction) {}
+
+ virtual bool matches(const T &Node,
+ ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const {
+ TypeLoc NextNode = (Node.*TraverseFunction)();
+ if (!NextNode)
+ return false;
+ return InnerMatcher.matches(NextNode, Finder, Builder);
+ }
+
+private:
+ const Matcher<TypeLoc> InnerMatcher;
+ TypeLoc (T::*TraverseFunction)() const;
+};
+
+template <typename T, typename InnerT>
+T makeTypeAllOfComposite(ArrayRef<const Matcher<InnerT> *> InnerMatchers) {
+ return T(makeAllOfComposite<InnerT>(InnerMatchers));
+}
+
} // end namespace internal
} // end namespace ast_matchers
} // end namespace clang
diff --git a/include/clang/ASTMatchers/ASTMatchersMacros.h b/include/clang/ASTMatchers/ASTMatchersMacros.h
index c68534acae35..953abc2a2ec9 100644
--- a/include/clang/ASTMatchers/ASTMatchersMacros.h
+++ b/include/clang/ASTMatchers/ASTMatchersMacros.h
@@ -221,4 +221,69 @@
const NodeType &Node, ASTMatchFinder *Finder, \
BoundNodesTreeBuilder *Builder) const
+/// \brief Creates a variadic matcher for both a specific \c Type as well as
+/// the corresponding \c TypeLoc.
+#define AST_TYPE_MATCHER(NodeType, MatcherName) \
+ const internal::VariadicDynCastAllOfMatcher<Type, NodeType> MatcherName; \
+ const internal::VariadicDynCastAllOfMatcher<TypeLoc, \
+ NodeType##Loc> MatcherName##Loc
+
+/// \brief AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) defines
+/// the matcher \c MatcherName that can be used to traverse from one \c Type
+/// to another.
+///
+/// For a specific \c SpecificType, the traversal is done using
+/// \c SpecificType::FunctionName. The existance of such a function determines
+/// whether a corresponding matcher can be used on \c SpecificType.
+#define AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) \
+class Polymorphic##MatcherName##TypeMatcher { \
+public: \
+ Polymorphic##MatcherName##TypeMatcher( \
+ const internal::Matcher<QualType> &InnerMatcher) \
+ : InnerMatcher(InnerMatcher) {} \
+ template <typename T> operator internal::Matcher<T>() { \
+ return internal::Matcher<T>(new internal::TypeTraverseMatcher<T>( \
+ InnerMatcher, &T::FunctionName)); \
+ } \
+private: \
+ const internal::Matcher<QualType> InnerMatcher; \
+}; \
+class Variadic##MatcherName##TypeTraverseMatcher \
+ : public llvm::VariadicFunction< \
+ Polymorphic##MatcherName##TypeMatcher, \
+ internal::Matcher<QualType>, \
+ internal::makeTypeAllOfComposite< \
+ Polymorphic##MatcherName##TypeMatcher, QualType> > { \
+public: \
+ Variadic##MatcherName##TypeTraverseMatcher() {} \
+}; \
+const Variadic##MatcherName##TypeTraverseMatcher MatcherName
+
+/// \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) \
+class Polymorphic##MatcherName##TypeLocMatcher { \
+public: \
+ Polymorphic##MatcherName##TypeLocMatcher( \
+ const internal::Matcher<TypeLoc> &InnerMatcher) \
+ : InnerMatcher(InnerMatcher) {} \
+ template <typename T> operator internal::Matcher<T>() { \
+ return internal::Matcher<T>(new internal::TypeLocTraverseMatcher<T>( \
+ InnerMatcher, &T::FunctionName##Loc)); \
+ } \
+private: \
+ const internal::Matcher<TypeLoc> InnerMatcher; \
+}; \
+class Variadic##MatcherName##TypeLocTraverseMatcher \
+ : public llvm::VariadicFunction< \
+ Polymorphic##MatcherName##TypeLocMatcher, \
+ internal::Matcher<TypeLoc>, \
+ internal::makeTypeAllOfComposite< \
+ Polymorphic##MatcherName##TypeLocMatcher, TypeLoc> > { \
+public: \
+ Variadic##MatcherName##TypeLocTraverseMatcher() {} \
+}; \
+const Variadic##MatcherName##TypeLocTraverseMatcher MatcherName##Loc; \
+AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName##Type)
+
#endif // LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_MACROS_H
diff --git a/include/clang/ASTMatchers/ASTTypeTraits.h b/include/clang/ASTMatchers/ASTTypeTraits.h
new file mode 100644
index 000000000000..bda53eaf70f6
--- /dev/null
+++ b/include/clang/ASTMatchers/ASTTypeTraits.h
@@ -0,0 +1,209 @@
+//===--- ASTMatchersTypeTraits.h --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Provides a dynamically typed node container that can be used to store
+// an AST base node at runtime in the same storage in a type safe way.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_MATCHERS_AST_TYPE_TRAITS_H
+#define LLVM_CLANG_AST_MATCHERS_AST_TYPE_TRAITS_H
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/Stmt.h"
+#include "llvm/Support/AlignOf.h"
+
+namespace clang {
+namespace ast_type_traits {
+
+/// \brief A dynamically typed AST node container.
+///
+/// Stores an AST node in a type safe way. This allows writing code that
+/// works with different kinds of AST nodes, despite the fact that they don't
+/// have a common base class.
+///
+/// Use \c create(Node) to create a \c DynTypedNode from an AST node,
+/// and \c get<T>() to retrieve the node as type T if the types match.
+///
+/// See \c NodeTypeTag for which node base types are currently supported;
+/// You can create DynTypedNodes for all nodes in the inheritance hierarchy of
+/// the supported base types.
+class DynTypedNode {
+public:
+ /// \brief Creates a \c DynTypedNode from \c Node.
+ template <typename T>
+ static DynTypedNode create(const T &Node) {
+ return BaseConverter<T>::create(Node);
+ }
+
+ /// \brief Retrieve the stored node as type \c T.
+ ///
+ /// Returns NULL if the stored node does not have a type that is
+ /// convertible to \c T.
+ ///
+ /// For types that have identity via their pointer in the AST
+ /// (like \c Stmt and \c Decl) the returned pointer points to the
+ /// referenced AST node.
+ /// For other types (like \c QualType) the value is stored directly
+ /// in the \c DynTypedNode, and the returned pointer points at
+ /// the storage inside DynTypedNode. For those nodes, do not
+ /// use the pointer outside the scope of the DynTypedNode.
+ template <typename T>
+ const T *get() const {
+ return BaseConverter<T>::get(Tag, Storage.buffer);
+ }
+
+ /// \brief Returns a pointer that identifies the stored AST node.
+ ///
+ /// Note that this is not supported by all AST nodes. For AST nodes
+ /// that don't have a pointer-defined identity inside the AST, this
+ /// method returns NULL.
+ const void *getMemoizationData() const;
+
+private:
+ /// \brief Takes care of converting from and to \c T.
+ template <typename T, typename EnablerT = void> struct BaseConverter;
+
+ /// \brief Supported base node types.
+ enum NodeTypeTag {
+ NT_Decl,
+ NT_Stmt,
+ NT_NestedNameSpecifier,
+ NT_NestedNameSpecifierLoc,
+ NT_QualType,
+ NT_Type,
+ NT_TypeLoc
+ } Tag;
+
+ /// \brief Stores the data of the node.
+ ///
+ /// Note that we can store \c Decls and \c Stmts by pointer as they are
+ /// guaranteed to be unique pointers pointing to dedicated storage in the
+ /// AST. \c QualTypes on the other hand do not have storage or unique
+ /// pointers and thus need to be stored by value.
+ llvm::AlignedCharArrayUnion<Decl*, QualType, TypeLoc, NestedNameSpecifierLoc>
+ Storage;
+};
+
+// FIXME: Pull out abstraction for the following.
+template<typename T> struct DynTypedNode::BaseConverter<T,
+ typename llvm::enable_if<llvm::is_base_of<Decl, T> >::type> {
+ static const T *get(NodeTypeTag Tag, const char Storage[]) {
+ if (Tag == NT_Decl)
+ return dyn_cast<T>(*reinterpret_cast<Decl*const*>(Storage));
+ return NULL;
+ }
+ static DynTypedNode create(const Decl &Node) {
+ DynTypedNode Result;
+ Result.Tag = NT_Decl;
+ new (Result.Storage.buffer) const Decl*(&Node);
+ return Result;
+ }
+};
+template<typename T> struct DynTypedNode::BaseConverter<T,
+ typename llvm::enable_if<llvm::is_base_of<Stmt, T> >::type> {
+ static const T *get(NodeTypeTag Tag, const char Storage[]) {
+ if (Tag == NT_Stmt)
+ return dyn_cast<T>(*reinterpret_cast<Stmt*const*>(Storage));
+ return NULL;
+ }
+ static DynTypedNode create(const Stmt &Node) {
+ DynTypedNode Result;
+ Result.Tag = NT_Stmt;
+ new (Result.Storage.buffer) const Stmt*(&Node);
+ return Result;
+ }
+};
+template<typename T> struct DynTypedNode::BaseConverter<T,
+ typename llvm::enable_if<llvm::is_base_of<Type, T> >::type> {
+ static const T *get(NodeTypeTag Tag, const char Storage[]) {
+ if (Tag == NT_Type)
+ return dyn_cast<T>(*reinterpret_cast<Type*const*>(Storage));
+ return NULL;
+ }
+ static DynTypedNode create(const Type &Node) {
+ DynTypedNode Result;
+ Result.Tag = NT_Type;
+ new (Result.Storage.buffer) const Type*(&Node);
+ return Result;
+ }
+};
+template<> struct DynTypedNode::BaseConverter<NestedNameSpecifier, void> {
+ static const NestedNameSpecifier *get(NodeTypeTag Tag, const char Storage[]) {
+ if (Tag == NT_NestedNameSpecifier)
+ return *reinterpret_cast<NestedNameSpecifier*const*>(Storage);
+ return NULL;
+ }
+ static DynTypedNode create(const NestedNameSpecifier &Node) {
+ DynTypedNode Result;
+ Result.Tag = NT_NestedNameSpecifier;
+ new (Result.Storage.buffer) const NestedNameSpecifier*(&Node);
+ return Result;
+ }
+};
+template<> struct DynTypedNode::BaseConverter<NestedNameSpecifierLoc, void> {
+ static const NestedNameSpecifierLoc *get(NodeTypeTag Tag,
+ const char Storage[]) {
+ if (Tag == NT_NestedNameSpecifierLoc)
+ return reinterpret_cast<const NestedNameSpecifierLoc*>(Storage);
+ return NULL;
+ }
+ static DynTypedNode create(const NestedNameSpecifierLoc &Node) {
+ DynTypedNode Result;
+ Result.Tag = NT_NestedNameSpecifierLoc;
+ new (Result.Storage.buffer) NestedNameSpecifierLoc(Node);
+ return Result;
+ }
+};
+template<> struct DynTypedNode::BaseConverter<QualType, void> {
+ static const QualType *get(NodeTypeTag Tag, const char Storage[]) {
+ if (Tag == NT_QualType)
+ return reinterpret_cast<const QualType*>(Storage);
+ return NULL;
+ }
+ static DynTypedNode create(const QualType &Node) {
+ DynTypedNode Result;
+ Result.Tag = NT_QualType;
+ new (Result.Storage.buffer) QualType(Node);
+ return Result;
+ }
+};
+template<> struct DynTypedNode::BaseConverter<TypeLoc, void> {
+ static const TypeLoc *get(NodeTypeTag Tag, const char Storage[]) {
+ if (Tag == NT_TypeLoc)
+ return reinterpret_cast<const TypeLoc*>(Storage);
+ return NULL;
+ }
+ static DynTypedNode create(const TypeLoc &Node) {
+ DynTypedNode Result;
+ Result.Tag = NT_TypeLoc;
+ new (Result.Storage.buffer) TypeLoc(Node);
+ return Result;
+ }
+};
+// The only operation we allow on unsupported types is \c get.
+// This allows to conveniently use \c DynTypedNode when having an arbitrary
+// AST node that is not supported, but prevents misuse - a user cannot create
+// a DynTypedNode from arbitrary types.
+template <typename T, typename EnablerT> struct DynTypedNode::BaseConverter {
+ static const T *get(NodeTypeTag Tag, const char Storage[]) { return NULL; }
+};
+
+inline const void *DynTypedNode::getMemoizationData() const {
+ switch (Tag) {
+ case NT_Decl: return BaseConverter<Decl>::get(Tag, Storage.buffer);
+ case NT_Stmt: return BaseConverter<Stmt>::get(Tag, Storage.buffer);
+ default: return NULL;
+ };
+}
+
+} // end namespace ast_type_traits
+} // end namespace clang
+
+#endif // LLVM_CLANG_AST_MATCHERS_AST_TYPE_TRAITS_H
diff --git a/include/clang/Analysis/Analyses/FormatString.h b/include/clang/Analysis/Analyses/FormatString.h
index 7f50ee392be6..5cb973122d72 100644
--- a/include/clang/Analysis/Analyses/FormatString.h
+++ b/include/clang/Analysis/Analyses/FormatString.h
@@ -23,6 +23,8 @@
namespace clang {
+class TargetInfo;
+
//===----------------------------------------------------------------------===//
/// Common components of both fprintf and fscanf format strings.
namespace analyze_format_string {
@@ -115,11 +117,14 @@ public:
// C99 conversion specifiers.
cArg,
dArg,
+ DArg, // Apple extension
iArg,
- IntArgBeg = cArg, IntArgEnd = iArg,
+ IntArgBeg = dArg, IntArgEnd = iArg,
oArg,
+ OArg, // Apple extension
uArg,
+ UArg, // Apple extension
xArg,
XArg,
UIntArgBeg = oArg, UIntArgEnd = XArg,
@@ -157,7 +162,7 @@ public:
ScanfConvBeg = ScanListArg, ScanfConvEnd = ScanListArg
};
- ConversionSpecifier(bool isPrintf)
+ ConversionSpecifier(bool isPrintf = true)
: IsPrintf(isPrintf), Position(0), EndScanList(0), kind(InvalidSpecifier) {}
ConversionSpecifier(bool isPrintf, const char *pos, Kind k)
@@ -189,10 +194,14 @@ public:
return EndScanList ? EndScanList - Position : 1;
}
+ bool isIntArg() const { return kind >= IntArgBeg && kind <= IntArgEnd; }
bool isUIntArg() const { return kind >= UIntArgBeg && kind <= UIntArgEnd; }
+ bool isAnyIntArg() const { return kind >= IntArgBeg && kind <= UIntArgEnd; }
const char *toString() const;
bool isPrintfKind() const { return IsPrintf; }
+
+ llvm::Optional<ConversionSpecifier> getStandardSpecifier() const;
protected:
bool IsPrintf;
@@ -348,10 +357,12 @@ public:
bool usesPositionalArg() const { return UsesPositionalArg; }
- bool hasValidLengthModifier() const;
+ bool hasValidLengthModifier(const TargetInfo &Target) const;
bool hasStandardLengthModifier() const;
+ llvm::Optional<LengthModifier> getCorrectedLengthModifier() const;
+
bool hasStandardConversionSpecifier(const LangOptions &LangOpt) const;
bool hasStandardLengthConversionCombination() const;
@@ -378,7 +389,6 @@ public:
: ConversionSpecifier(true, pos, k) {}
bool isObjCArg() const { return kind >= ObjCBeg && kind <= ObjCEnd; }
- bool isIntArg() const { return kind >= IntArgBeg && kind <= IntArgEnd; }
bool isDoubleArg() const { return kind >= DoubleArgBeg &&
kind <= DoubleArgEnd; }
unsigned getLength() const {
@@ -623,10 +633,12 @@ public:
};
bool ParsePrintfString(FormatStringHandler &H,
- const char *beg, const char *end, const LangOptions &LO);
+ const char *beg, const char *end, const LangOptions &LO,
+ const TargetInfo &Target);
bool ParseScanfString(FormatStringHandler &H,
- const char *beg, const char *end, const LangOptions &LO);
+ const char *beg, const char *end, const LangOptions &LO,
+ const TargetInfo &Target);
} // end analyze_format_string namespace
} // end clang namespace
diff --git a/include/clang/Analysis/Analyses/ThreadSafety.h b/include/clang/Analysis/Analyses/ThreadSafety.h
index 742cc0434456..ef6b821e390b 100644
--- a/include/clang/Analysis/Analyses/ThreadSafety.h
+++ b/include/clang/Analysis/Analyses/ThreadSafety.h
@@ -132,7 +132,8 @@ public:
/// \param Loc -- The location of the protected operation.
virtual void handleMutexNotHeld(const NamedDecl *D,
ProtectedOperationKind POK, Name LockName,
- LockKind LK, SourceLocation Loc) {}
+ LockKind LK, SourceLocation Loc,
+ Name *PossibleMatch=0) {}
/// Warn when a function is called while an excluded mutex is locked. For
/// example, the mutex may be locked inside the function.
diff --git a/include/clang/Analysis/AnalysisContext.h b/include/clang/Analysis/AnalysisContext.h
index 46b4e93bb7d4..52466786b341 100644
--- a/include/clang/Analysis/AnalysisContext.h
+++ b/include/clang/Analysis/AnalysisContext.h
@@ -72,7 +72,7 @@ class AnalysisDeclContext {
/// AnalysisDeclContext. This may be null.
AnalysisDeclContextManager *Manager;
- const Decl *D;
+ const Decl * const D;
OwningPtr<CFG> cfg, completeCFG;
OwningPtr<CFGStmtMap> cfgStmtMap;
@@ -81,9 +81,6 @@ class AnalysisDeclContext {
CFG::BuildOptions::ForcedBlkExprs *forcedBlkExprs;
bool builtCFG, builtCompleteCFG;
-
- OwningPtr<LiveVariables> liveness;
- OwningPtr<LiveVariables> relaxedLiveness;
OwningPtr<ParentMap> PM;
OwningPtr<PseudoConstantAnalysis> PCA;
OwningPtr<CFGReverseBlockReachabilityAnalysis> CFA;
@@ -104,9 +101,15 @@ public:
~AnalysisDeclContext();
- ASTContext &getASTContext() { return D->getASTContext(); }
+ ASTContext &getASTContext() const { return D->getASTContext(); }
const Decl *getDecl() const { return D; }
+ /// Return the AnalysisDeclContextManager (if any) that created
+ /// this AnalysisDeclContext.
+ AnalysisDeclContextManager *getManager() const {
+ return Manager;
+ }
+
/// Return the build options used to construct the CFG.
CFG::BuildOptions &getCFGBuildOptions() {
return cfgBuildOptions;
@@ -234,9 +237,10 @@ public:
const StackFrameContext *getCurrentStackFrame() const;
- virtual void Profile(llvm::FoldingSetNodeID &ID) = 0;
+ /// Return true if the current LocationContext has no caller context.
+ virtual bool inTopFrame() const;
- static bool classof(const LocationContext*) { return true; }
+ virtual void Profile(llvm::FoldingSetNodeID &ID) = 0;
public:
static void ProfileCommon(llvm::FoldingSetNodeID &ID,
@@ -270,6 +274,9 @@ public:
const CFGBlock *getCallSiteBlock() const { return Block; }
+ /// Return true if the current LocationContext has no caller context.
+ virtual bool inTopFrame() const { return getParent() == 0; }
+
unsigned getIndex() const { return Index; }
void Profile(llvm::FoldingSetNodeID &ID);
@@ -379,11 +386,17 @@ class AnalysisDeclContextManager {
ContextMap Contexts;
LocationContextManager LocContexts;
CFG::BuildOptions cfgBuildOptions;
+
+ /// Flag to indicate whether or not bodies should be synthesized
+ /// for well-known functions.
+ bool SynthesizeBodies;
public:
AnalysisDeclContextManager(bool useUnoptimizedCFG = false,
- bool addImplicitDtors = false,
- bool addInitializers = false);
+ bool addImplicitDtors = false,
+ bool addInitializers = false,
+ bool addTemporaryDtors = false,
+ bool synthesizeBodies = false);
~AnalysisDeclContextManager();
@@ -396,6 +409,10 @@ public:
CFG::BuildOptions &getCFGBuildOptions() {
return cfgBuildOptions;
}
+
+ /// Return true if faux bodies should be synthesized for well-known
+ /// functions.
+ bool synthesizeBodies() const { return SynthesizeBodies; }
const StackFrameContext *getStackFrame(AnalysisDeclContext *Ctx,
LocationContext const *Parent,
diff --git a/include/clang/Analysis/CFG.h b/include/clang/Analysis/CFG.h
index 4d087e749830..8cc5d814e822 100644
--- a/include/clang/Analysis/CFG.h
+++ b/include/clang/Analysis/CFG.h
@@ -88,8 +88,6 @@ public:
return static_cast<const ElemTy*>(this);
return 0;
}
-
- static bool classof(const CFGElement *E) { return true; }
};
class CFGStmt : public CFGElement {
@@ -568,6 +566,7 @@ public:
bool AddEHEdges;
bool AddInitializers;
bool AddImplicitDtors;
+ bool AddTemporaryDtors;
bool alwaysAdd(const Stmt *stmt) const {
return alwaysAddMask[stmt->getStmtClass()];
@@ -587,7 +586,8 @@ public:
: forcedBlkExprs(0), PruneTriviallyFalseEdges(true)
,AddEHEdges(false)
,AddInitializers(false)
- ,AddImplicitDtors(false) {}
+ ,AddImplicitDtors(false)
+ ,AddTemporaryDtors(false) {}
};
/// \brief Provides a custom implementation of the iterator class to have the
diff --git a/include/clang/Analysis/DomainSpecific/ObjCNoReturn.h b/include/clang/Analysis/DomainSpecific/ObjCNoReturn.h
new file mode 100644
index 000000000000..930c2bd0925b
--- /dev/null
+++ b/include/clang/Analysis/DomainSpecific/ObjCNoReturn.h
@@ -0,0 +1,46 @@
+//= ObjCNoReturn.h - Handling of Cocoa APIs known not to return --*- C++ -*---//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements special handling of recognizing ObjC API hooks that
+// do not return but aren't marked as such in API headers.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_DS_OBJCNORETURN
+#define LLVM_CLANG_ANALYSIS_DS_OBJCNORETURN
+
+#include "clang/Basic/IdentifierTable.h"
+
+namespace clang {
+
+class ASTContext;
+class ObjCMessageExpr;
+
+class ObjCNoReturn {
+ /// Cached "raise" selector.
+ Selector RaiseSel;
+
+ /// Cached identifier for "NSException".
+ IdentifierInfo *NSExceptionII;
+
+ enum { NUM_RAISE_SELECTORS = 2 };
+
+ /// Cached set of selectors in NSException that are 'noreturn'.
+ Selector NSExceptionInstanceRaiseSelectors[NUM_RAISE_SELECTORS];
+
+public:
+ ObjCNoReturn(ASTContext &C);
+
+ /// Return true if the given message expression is known to never
+ /// return.
+ bool isImplicitNoReturn(const ObjCMessageExpr *ME);
+};
+}
+
+#endif
diff --git a/include/clang/Analysis/ProgramPoint.h b/include/clang/Analysis/ProgramPoint.h
index 5de06cd3a54d..947997804388 100644
--- a/include/clang/Analysis/ProgramPoint.h
+++ b/include/clang/Analysis/ProgramPoint.h
@@ -140,8 +140,6 @@ public:
return ID.ComputeHash();
}
- static bool classof(const ProgramPoint*) { return true; }
-
bool operator==(const ProgramPoint & RHS) const {
return Data1 == RHS.Data1 &&
Data2 == RHS.Data2 &&
@@ -213,7 +211,9 @@ class StmtPoint : public ProgramPoint {
public:
StmtPoint(const Stmt *S, const void *p2, Kind k, const LocationContext *L,
const ProgramPointTag *tag)
- : ProgramPoint(S, p2, k, L, tag) {}
+ : ProgramPoint(S, p2, k, L, tag) {
+ assert(S);
+ }
const Stmt *getStmt() const { return (const Stmt*) getData1(); }
@@ -461,6 +461,7 @@ public:
};
/// Represents a point when we begin processing an inlined call.
+/// CallEnter uses the caller's location context.
class CallEnter : public ProgramPoint {
public:
CallEnter(const Stmt *stmt, const StackFrameContext *calleeCtx,
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
index fade83ef9361..bfe8093079b7 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -190,7 +190,7 @@ def Availability : InheritableAttr {
[{static llvm::StringRef getPrettyPlatformName(llvm::StringRef Platform) {
return llvm::StringSwitch<llvm::StringRef>(Platform)
.Case("ios", "iOS")
- .Case("macosx", "Mac OS X")
+ .Case("macosx", "OS X")
.Default(llvm::StringRef());
} }];
}
@@ -341,6 +341,11 @@ def Final : InheritableAttr {
let SemaHandler = 0;
}
+def MinSize : InheritableAttr {
+ let Spellings = [GNU<"minsize">];
+ let Subjects = [Function];
+}
+
def Format : InheritableAttr {
let Spellings = [GNU<"format">];
let Args = [StringArgument<"Type">, IntArgument<"FormatIdx">,
@@ -528,6 +533,11 @@ def ObjCReturnsInnerPointer : Attr {
let Subjects = [ObjCMethod];
}
+def ObjCRequiresSuper : InheritableAttr {
+ let Spellings = [GNU<"objc_requires_super">];
+ let Subjects = [ObjCMethod];
+}
+
def ObjCRootClass : Attr {
let Spellings = [GNU<"objc_root_class">];
let Subjects = [ObjCInterface];
@@ -556,6 +566,10 @@ def Packed : InheritableAttr {
let Spellings = [GNU<"packed">];
}
+def PnaclCall : InheritableAttr {
+ let Spellings = [GNU<"pnaclcall">];
+}
+
def Pcs : InheritableAttr {
let Spellings = [GNU<"pcs">];
let Args = [EnumArgument<"PCS", "PCSType",
diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def
index 84b28811728e..d48eadcd6b61 100644
--- a/include/clang/Basic/Builtins.def
+++ b/include/clang/Basic/Builtins.def
@@ -41,6 +41,7 @@
// J -> jmp_buf
// SJ -> sigjmp_buf
// K -> ucontext_t
+// p -> pid_t
// . -> "...". This may only occur at the end of the function list.
//
// Types may be prefixed with the following modifiers:
@@ -388,6 +389,7 @@ BUILTIN(__builtin_popcountll, "iULLi", "nc")
// FIXME: These type signatures are not correct for targets with int != 32-bits
// or with ULL != 64-bits.
+BUILTIN(__builtin_bswap16, "UsUs", "nc")
BUILTIN(__builtin_bswap32, "UiUi", "nc")
BUILTIN(__builtin_bswap64, "ULLiULLi", "nc")
@@ -478,6 +480,7 @@ BUILTIN(__builtin_expect, "LiLiLi" , "nc")
BUILTIN(__builtin_prefetch, "vvC*.", "nc")
BUILTIN(__builtin_readcyclecounter, "ULLi", "n")
BUILTIN(__builtin_trap, "v", "nr")
+BUILTIN(__builtin_debugtrap, "v", "n")
BUILTIN(__builtin_unreachable, "v", "nr")
BUILTIN(__builtin_shufflevector, "v." , "nc")
BUILTIN(__builtin_alloca, "v*z" , "n")
@@ -735,7 +738,7 @@ LIBBUILTIN(strcasecmp, "icC*cC*", "f", "strings.h", ALL_LANGUAGES)
LIBBUILTIN(strncasecmp, "icC*cC*z", "f", "strings.h", ALL_LANGUAGES)
// POSIX unistd.h
LIBBUILTIN(_exit, "vi", "fr", "unistd.h", ALL_LANGUAGES)
-LIBBUILTIN(vfork, "i", "fj", "unistd.h", ALL_LANGUAGES)
+LIBBUILTIN(vfork, "p", "fj", "unistd.h", ALL_LANGUAGES)
// POSIX setjmp.h
// In some systems setjmp is a macro that expands to _setjmp. We undefine
@@ -826,9 +829,13 @@ LIBBUILTIN(atan2, "ddd", "fe", "math.h", ALL_LANGUAGES)
LIBBUILTIN(atan2l, "LdLdLd", "fe", "math.h", ALL_LANGUAGES)
LIBBUILTIN(atan2f, "fff", "fe", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(ceil, "dd", "fe", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(ceill, "LdLd", "fe", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(ceilf, "ff", "fe", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(ceil, "dd", "fc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(ceill, "LdLd", "fc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(ceilf, "ff", "fc", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(copysign, "ddd", "fc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(copysignl, "LdLdLd", "fc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(copysignf, "fff", "fc", "math.h", ALL_LANGUAGES)
LIBBUILTIN(cos, "dd", "fe", "math.h", ALL_LANGUAGES)
LIBBUILTIN(cosl, "LdLd", "fe", "math.h", ALL_LANGUAGES)
@@ -838,37 +845,53 @@ LIBBUILTIN(exp, "dd", "fe", "math.h", ALL_LANGUAGES)
LIBBUILTIN(expl, "LdLd", "fe", "math.h", ALL_LANGUAGES)
LIBBUILTIN(expf, "ff", "fe", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(fabs, "dd", "fe", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(fabsl, "LdLd", "fe", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(fabsf, "ff", "fe", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(exp2, "dd", "fe", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(exp2l, "LdLd", "fe", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(exp2f, "ff", "fe", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(fabs, "dd", "fc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(fabsl, "LdLd", "fc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(fabsf, "ff", "fc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(floor, "dd", "fe", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(floorl, "LdLd", "fe", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(floorf, "ff", "fe", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(floor, "dd", "fc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(floorl, "LdLd", "fc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(floorf, "ff", "fc", "math.h", ALL_LANGUAGES)
LIBBUILTIN(fma, "dddd", "fc", "math.h", ALL_LANGUAGES)
LIBBUILTIN(fmal, "LdLdLdLd", "fc", "math.h", ALL_LANGUAGES)
LIBBUILTIN(fmaf, "ffff", "fc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(fmax, "ddd", "fe", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(fmaxl, "LdLdLd", "fe", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(fmaxf, "fff", "fe", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(fmax, "ddd", "fc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(fmaxl, "LdLdLd", "fc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(fmaxf, "fff", "fc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(fmin, "ddd", "fe", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(fminl, "LdLdLd", "fe", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(fminf, "fff", "fe", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(fmin, "ddd", "fc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(fminl, "LdLdLd", "fc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(fminf, "fff", "fc", "math.h", ALL_LANGUAGES)
LIBBUILTIN(log, "dd", "fe", "math.h", ALL_LANGUAGES)
LIBBUILTIN(logl, "LdLd", "fe", "math.h", ALL_LANGUAGES)
LIBBUILTIN(logf, "ff", "fe", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(log2, "dd", "fe", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(log2l, "LdLd", "fe", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(log2f, "ff", "fe", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(nearbyint, "dd", "fc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(nearbyintl, "LdLd", "fc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(nearbyintf, "ff", "fc", "math.h", ALL_LANGUAGES)
+
LIBBUILTIN(pow, "ddd", "fe", "math.h", ALL_LANGUAGES)
LIBBUILTIN(powl, "LdLdLd", "fe", "math.h", ALL_LANGUAGES)
LIBBUILTIN(powf, "fff", "fe", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(round, "dd", "fe", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(roundl, "LdLd", "fe", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(roundf, "ff", "fe", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(rint, "dd", "fc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(rintl, "LdLd", "fc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(rintf, "ff", "fc", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(round, "dd", "fc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(roundl, "LdLd", "fc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(roundf, "ff", "fc", "math.h", ALL_LANGUAGES)
LIBBUILTIN(sin, "dd", "fe", "math.h", ALL_LANGUAGES)
LIBBUILTIN(sinl, "LdLd", "fe", "math.h", ALL_LANGUAGES)
@@ -882,6 +905,10 @@ LIBBUILTIN(tan, "dd", "fe", "math.h", ALL_LANGUAGES)
LIBBUILTIN(tanl, "LdLd", "fe", "math.h", ALL_LANGUAGES)
LIBBUILTIN(tanf, "ff", "fe", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(trunc, "dd", "fc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(truncl, "LdLd", "fc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(truncf, "ff", "fc", "math.h", ALL_LANGUAGES)
+
// Blocks runtime Builtin math library functions
LIBBUILTIN(_Block_object_assign, "vv*vC*iC", "f", "Blocks.h", ALL_LANGUAGES)
LIBBUILTIN(_Block_object_dispose, "vvC*iC", "f", "Blocks.h", ALL_LANGUAGES)
diff --git a/include/clang/Basic/BuiltinsMips.def b/include/clang/Basic/BuiltinsMips.def
index d0137155a2d0..43fb90756efb 100644
--- a/include/clang/Basic/BuiltinsMips.def
+++ b/include/clang/Basic/BuiltinsMips.def
@@ -14,6 +14,8 @@
// The format of this database matches clang/Basic/Builtins.def.
+// MIPS DSP Rev 1
+
// Add/subtract with optional saturation
BUILTIN(__builtin_mips_addu_qb, "V4ScV4ScV4Sc", "n")
BUILTIN(__builtin_mips_addu_s_qb, "V4ScV4ScV4Sc", "n")
@@ -122,4 +124,65 @@ BUILTIN(__builtin_mips_lbux, "iv*i", "n")
BUILTIN(__builtin_mips_lhx, "iv*i", "n")
BUILTIN(__builtin_mips_lwx, "iv*i", "n")
+// MIPS DSP Rev 2
+
+BUILTIN(__builtin_mips_absq_s_qb, "V4ScV4Sc", "n")
+
+BUILTIN(__builtin_mips_addqh_ph, "V2sV2sV2s", "nc")
+BUILTIN(__builtin_mips_addqh_r_ph, "V2sV2sV2s", "nc")
+BUILTIN(__builtin_mips_addqh_w, "iii", "nc")
+BUILTIN(__builtin_mips_addqh_r_w, "iii", "nc")
+
+BUILTIN(__builtin_mips_addu_ph, "V2sV2sV2s", "n")
+BUILTIN(__builtin_mips_addu_s_ph, "V2sV2sV2s", "n")
+
+BUILTIN(__builtin_mips_adduh_qb, "V4ScV4ScV4Sc", "nc")
+BUILTIN(__builtin_mips_adduh_r_qb, "V4ScV4ScV4Sc", "nc")
+
+BUILTIN(__builtin_mips_append, "iiiIi", "nc")
+BUILTIN(__builtin_mips_balign, "iiiIi", "nc")
+
+BUILTIN(__builtin_mips_cmpgdu_eq_qb, "iV4ScV4Sc", "n")
+BUILTIN(__builtin_mips_cmpgdu_lt_qb, "iV4ScV4Sc", "n")
+BUILTIN(__builtin_mips_cmpgdu_le_qb, "iV4ScV4Sc", "n")
+
+BUILTIN(__builtin_mips_dpa_w_ph, "LLiLLiV2sV2s", "nc")
+BUILTIN(__builtin_mips_dps_w_ph, "LLiLLiV2sV2s", "nc")
+
+BUILTIN(__builtin_mips_dpaqx_s_w_ph, "LLiLLiV2sV2s", "n")
+BUILTIN(__builtin_mips_dpaqx_sa_w_ph, "LLiLLiV2sV2s", "n")
+BUILTIN(__builtin_mips_dpax_w_ph, "LLiLLiV2sV2s", "nc")
+BUILTIN(__builtin_mips_dpsx_w_ph, "LLiLLiV2sV2s", "nc")
+BUILTIN(__builtin_mips_dpsqx_s_w_ph, "LLiLLiV2sV2s", "n")
+BUILTIN(__builtin_mips_dpsqx_sa_w_ph, "LLiLLiV2sV2s", "n")
+
+BUILTIN(__builtin_mips_mul_ph, "V2sV2sV2s", "n")
+BUILTIN(__builtin_mips_mul_s_ph, "V2sV2sV2s", "n")
+
+BUILTIN(__builtin_mips_mulq_rs_w, "iii", "n")
+BUILTIN(__builtin_mips_mulq_s_ph, "V2sV2sV2s", "n")
+BUILTIN(__builtin_mips_mulq_s_w, "iii", "n")
+BUILTIN(__builtin_mips_mulsa_w_ph, "LLiLLiV2sV2s", "nc")
+
+BUILTIN(__builtin_mips_precr_qb_ph, "V4ScV2sV2s", "n")
+BUILTIN(__builtin_mips_precr_sra_ph_w, "V2siiIi", "nc")
+BUILTIN(__builtin_mips_precr_sra_r_ph_w, "V2siiIi", "nc")
+
+BUILTIN(__builtin_mips_prepend, "iiiIi", "nc")
+
+BUILTIN(__builtin_mips_shra_qb, "V4ScV4Sci", "nc")
+BUILTIN(__builtin_mips_shra_r_qb, "V4ScV4Sci", "nc")
+BUILTIN(__builtin_mips_shrl_ph, "V2sV2si", "nc")
+
+BUILTIN(__builtin_mips_subqh_ph, "V2sV2sV2s", "nc")
+BUILTIN(__builtin_mips_subqh_r_ph, "V2sV2sV2s", "nc")
+BUILTIN(__builtin_mips_subqh_w, "iii", "nc")
+BUILTIN(__builtin_mips_subqh_r_w, "iii", "nc")
+
+BUILTIN(__builtin_mips_subu_ph, "V2sV2sV2s", "n")
+BUILTIN(__builtin_mips_subu_s_ph, "V2sV2sV2s", "n")
+
+BUILTIN(__builtin_mips_subuh_qb, "V4ScV4ScV4Sc", "nc")
+BUILTIN(__builtin_mips_subuh_r_qb, "V4ScV4ScV4Sc", "nc")
+
#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsNVPTX.def b/include/clang/Basic/BuiltinsNVPTX.def
index f90a43f7f404..3c3f06c5ea3a 100644
--- a/include/clang/Basic/BuiltinsNVPTX.def
+++ b/include/clang/Basic/BuiltinsNVPTX.def
@@ -14,6 +14,7 @@
// The format of this database matches clang/Basic/Builtins.def.
+// Builtins retained from previous PTX back-end
BUILTIN(__builtin_ptx_read_tid_x, "i", "nc")
BUILTIN(__builtin_ptx_read_tid_y, "i", "nc")
BUILTIN(__builtin_ptx_read_tid_z, "i", "nc")
@@ -59,4 +60,249 @@ BUILTIN(__builtin_ptx_read_pm3, "i", "n")
BUILTIN(__builtin_ptx_bar_sync, "vi", "n")
+// Builtins exposed as part of NVVM
+BUILTIN(__syncthreads, "v", "n")
+BUILTIN(__nvvm_bar0, "v", "n")
+BUILTIN(__nvvm_bar0_popc, "ii", "n")
+BUILTIN(__nvvm_bar0_and, "ii", "n")
+BUILTIN(__nvvm_bar0_or, "ii", "n")
+BUILTIN(__nvvm_membar_cta, "v", "n")
+BUILTIN(__nvvm_membar_gl, "v", "n")
+BUILTIN(__nvvm_membar_sys, "v", "n")
+BUILTIN(__nvvm_popc_i, "ii", "nc")
+BUILTIN(__nvvm_popc_ll, "LiLi", "nc")
+BUILTIN(__nvvm_prmt, "UiUiUiUi", "nc")
+BUILTIN(__nvvm_min_i, "iii", "nc")
+BUILTIN(__nvvm_min_ui, "UiUiUi", "nc")
+BUILTIN(__nvvm_min_ll, "LLiLLiLLi", "nc")
+BUILTIN(__nvvm_min_ull, "ULLiULLiULLi", "nc")
+BUILTIN(__nvvm_max_i, "iii", "nc")
+BUILTIN(__nvvm_max_ui, "UiUiUi", "nc")
+BUILTIN(__nvvm_max_ll, "LLiLLiLLi", "nc")
+BUILTIN(__nvvm_max_ull, "ULLiULLiULLi", "nc")
+BUILTIN(__nvvm_mulhi_i, "iii", "nc")
+BUILTIN(__nvvm_mulhi_ui, "UiUiUi", "nc")
+BUILTIN(__nvvm_mulhi_ll, "LLiLLiLLi", "nc")
+BUILTIN(__nvvm_mulhi_ull, "ULLiULLiULLi", "nc")
+BUILTIN(__nvvm_mul24_i, "iii", "nc")
+BUILTIN(__nvvm_mul24_ui, "UiUiUi", "nc")
+BUILTIN(__nvvm_brev32, "UiUi", "nc")
+BUILTIN(__nvvm_brev64, "ULLiULLi", "nc")
+BUILTIN(__nvvm_sad_i, "iiii", "nc")
+BUILTIN(__nvvm_sad_ui, "UiUiUiUi", "nc")
+BUILTIN(__nvvm_abs_i, "ii", "nc")
+BUILTIN(__nvvm_abs_ll, "LiLi", "nc")
+BUILTIN(__nvvm_floor_ftz_f, "ff", "nc")
+BUILTIN(__nvvm_floor_f, "ff", "nc")
+BUILTIN(__nvvm_floor_d, "dd", "nc")
+BUILTIN(__nvvm_fabs_ftz_f, "ff", "nc")
+BUILTIN(__nvvm_fabs_f, "ff", "nc")
+BUILTIN(__nvvm_fabs_d, "dd", "nc")
+BUILTIN(__nvvm_rcp_approx_ftz_d, "dd", "nc")
+BUILTIN(__nvvm_fmin_ftz_f, "fff", "nc")
+BUILTIN(__nvvm_fmin_f, "fff", "nc")
+BUILTIN(__nvvm_fmax_ftz_f, "fff", "nc")
+BUILTIN(__nvvm_fmax_f, "fff", "nc")
+BUILTIN(__nvvm_rsqrt_approx_ftz_f, "ff", "nc")
+BUILTIN(__nvvm_rsqrt_approx_f, "ff", "nc")
+BUILTIN(__nvvm_fmin_d, "ddd", "nc")
+BUILTIN(__nvvm_fmax_d, "ddd", "nc")
+BUILTIN(__nvvm_rsqrt_approx_d, "dd", "nc")
+BUILTIN(__nvvm_ceil_d, "dd", "nc")
+BUILTIN(__nvvm_trunc_d, "dd", "nc")
+BUILTIN(__nvvm_round_d, "dd", "nc")
+BUILTIN(__nvvm_ex2_approx_d, "dd", "nc")
+BUILTIN(__nvvm_lg2_approx_d, "dd", "nc")
+BUILTIN(__nvvm_round_ftz_f, "ff", "nc")
+BUILTIN(__nvvm_round_f, "ff", "nc")
+BUILTIN(__nvvm_ex2_approx_ftz_f, "ff", "nc")
+BUILTIN(__nvvm_ex2_approx_f, "ff", "nc")
+BUILTIN(__nvvm_lg2_approx_ftz_f, "ff", "nc")
+BUILTIN(__nvvm_lg2_approx_f, "ff", "nc")
+BUILTIN(__nvvm_sin_approx_ftz_f, "ff", "nc")
+BUILTIN(__nvvm_sin_approx_f, "ff", "nc")
+BUILTIN(__nvvm_cos_approx_ftz_f, "ff", "nc")
+BUILTIN(__nvvm_cos_approx_f, "ff", "nc")
+BUILTIN(__nvvm_trunc_ftz_f, "ff", "nc")
+BUILTIN(__nvvm_trunc_f, "ff", "nc")
+BUILTIN(__nvvm_ceil_ftz_f, "ff", "nc")
+BUILTIN(__nvvm_ceil_f, "ff", "nc")
+BUILTIN(__nvvm_saturate_d, "dd", "nc")
+BUILTIN(__nvvm_saturate_ftz_f, "ff", "nc")
+BUILTIN(__nvvm_saturate_f, "ff", "nc")
+BUILTIN(__nvvm_fma_rn_ftz_f, "ffff", "nc")
+BUILTIN(__nvvm_fma_rn_f, "ffff", "nc")
+BUILTIN(__nvvm_fma_rz_ftz_f, "ffff", "nc")
+BUILTIN(__nvvm_fma_rz_f, "ffff", "nc")
+BUILTIN(__nvvm_fma_rm_ftz_f, "ffff", "nc")
+BUILTIN(__nvvm_fma_rm_f, "ffff", "nc")
+BUILTIN(__nvvm_fma_rp_ftz_f, "ffff", "nc")
+BUILTIN(__nvvm_fma_rp_f, "ffff", "nc")
+BUILTIN(__nvvm_fma_rn_d, "dddd", "nc")
+BUILTIN(__nvvm_fma_rz_d, "dddd", "nc")
+BUILTIN(__nvvm_fma_rm_d, "dddd", "nc")
+BUILTIN(__nvvm_fma_rp_d, "dddd", "nc")
+BUILTIN(__nvvm_div_approx_ftz_f, "fff", "nc")
+BUILTIN(__nvvm_div_approx_f, "fff", "nc")
+BUILTIN(__nvvm_div_rn_ftz_f, "fff", "nc")
+BUILTIN(__nvvm_div_rn_f, "fff", "nc")
+BUILTIN(__nvvm_div_rz_ftz_f, "fff", "nc")
+BUILTIN(__nvvm_div_rz_f, "fff", "nc")
+BUILTIN(__nvvm_div_rm_ftz_f, "fff", "nc")
+BUILTIN(__nvvm_div_rm_f, "fff", "nc")
+BUILTIN(__nvvm_div_rp_ftz_f, "fff", "nc")
+BUILTIN(__nvvm_div_rp_f, "fff", "nc")
+BUILTIN(__nvvm_rcp_rn_ftz_f, "ff", "nc")
+BUILTIN(__nvvm_rcp_rn_f, "ff", "nc")
+BUILTIN(__nvvm_rcp_rz_ftz_f, "ff", "nc")
+BUILTIN(__nvvm_rcp_rz_f, "ff", "nc")
+BUILTIN(__nvvm_rcp_rm_ftz_f, "ff", "nc")
+BUILTIN(__nvvm_rcp_rm_f, "ff", "nc")
+BUILTIN(__nvvm_rcp_rp_ftz_f, "ff", "nc")
+BUILTIN(__nvvm_rcp_rp_f, "ff", "nc")
+BUILTIN(__nvvm_sqrt_rn_ftz_f, "ff", "nc")
+BUILTIN(__nvvm_sqrt_rn_f, "ff", "nc")
+BUILTIN(__nvvm_sqrt_rz_ftz_f, "ff", "nc")
+BUILTIN(__nvvm_sqrt_rz_f, "ff", "nc")
+BUILTIN(__nvvm_sqrt_rm_ftz_f, "ff", "nc")
+BUILTIN(__nvvm_sqrt_rm_f, "ff", "nc")
+BUILTIN(__nvvm_sqrt_rp_ftz_f, "ff", "nc")
+BUILTIN(__nvvm_sqrt_rp_f, "ff", "nc")
+BUILTIN(__nvvm_div_rn_d, "ddd", "nc")
+BUILTIN(__nvvm_div_rz_d, "ddd", "nc")
+BUILTIN(__nvvm_div_rm_d, "ddd", "nc")
+BUILTIN(__nvvm_div_rp_d, "ddd", "nc")
+BUILTIN(__nvvm_rcp_rn_d, "dd", "nc")
+BUILTIN(__nvvm_rcp_rz_d, "dd", "nc")
+BUILTIN(__nvvm_rcp_rm_d, "dd", "nc")
+BUILTIN(__nvvm_rcp_rp_d, "dd", "nc")
+BUILTIN(__nvvm_sqrt_rn_d, "dd", "nc")
+BUILTIN(__nvvm_sqrt_rz_d, "dd", "nc")
+BUILTIN(__nvvm_sqrt_rm_d, "dd", "nc")
+BUILTIN(__nvvm_sqrt_rp_d, "dd", "nc")
+BUILTIN(__nvvm_sqrt_approx_ftz_f, "ff", "nc")
+BUILTIN(__nvvm_sqrt_approx_f, "ff", "nc")
+BUILTIN(__nvvm_add_rn_d, "ddd", "nc")
+BUILTIN(__nvvm_add_rz_d, "ddd", "nc")
+BUILTIN(__nvvm_add_rm_d, "ddd", "nc")
+BUILTIN(__nvvm_add_rp_d, "ddd", "nc")
+BUILTIN(__nvvm_mul_rn_d, "ddd", "nc")
+BUILTIN(__nvvm_mul_rz_d, "ddd", "nc")
+BUILTIN(__nvvm_mul_rm_d, "ddd", "nc")
+BUILTIN(__nvvm_mul_rp_d, "ddd", "nc")
+BUILTIN(__nvvm_add_rm_ftz_f, "fff", "nc")
+BUILTIN(__nvvm_add_rm_f, "fff", "nc")
+BUILTIN(__nvvm_add_rp_ftz_f, "fff", "nc")
+BUILTIN(__nvvm_add_rp_f, "fff", "nc")
+BUILTIN(__nvvm_mul_rm_ftz_f, "fff", "nc")
+BUILTIN(__nvvm_mul_rm_f, "fff", "nc")
+BUILTIN(__nvvm_mul_rp_ftz_f, "fff", "nc")
+BUILTIN(__nvvm_mul_rp_f, "fff", "nc")
+BUILTIN(__nvvm_add_rn_ftz_f, "fff", "nc")
+BUILTIN(__nvvm_add_rn_f, "fff", "nc")
+BUILTIN(__nvvm_add_rz_ftz_f, "fff", "nc")
+BUILTIN(__nvvm_add_rz_f, "fff", "nc")
+BUILTIN(__nvvm_mul_rn_ftz_f, "fff", "nc")
+BUILTIN(__nvvm_mul_rn_f, "fff", "nc")
+BUILTIN(__nvvm_mul_rz_ftz_f, "fff", "nc")
+BUILTIN(__nvvm_mul_rz_f, "fff", "nc")
+BUILTIN(__nvvm_d2f_rn_ftz, "fd", "nc")
+BUILTIN(__nvvm_d2f_rn, "fd", "nc")
+BUILTIN(__nvvm_d2f_rz_ftz, "fd", "nc")
+BUILTIN(__nvvm_d2f_rz, "fd", "nc")
+BUILTIN(__nvvm_d2f_rm_ftz, "fd", "nc")
+BUILTIN(__nvvm_d2f_rm, "fd", "nc")
+BUILTIN(__nvvm_d2f_rp_ftz, "fd", "nc")
+BUILTIN(__nvvm_d2f_rp, "fd", "nc")
+BUILTIN(__nvvm_d2i_rn, "id", "nc")
+BUILTIN(__nvvm_d2i_rz, "id", "nc")
+BUILTIN(__nvvm_d2i_rm, "id", "nc")
+BUILTIN(__nvvm_d2i_rp, "id", "nc")
+BUILTIN(__nvvm_d2ui_rn, "Uid", "nc")
+BUILTIN(__nvvm_d2ui_rz, "Uid", "nc")
+BUILTIN(__nvvm_d2ui_rm, "Uid", "nc")
+BUILTIN(__nvvm_d2ui_rp, "Uid", "nc")
+BUILTIN(__nvvm_i2d_rn, "di", "nc")
+BUILTIN(__nvvm_i2d_rz, "di", "nc")
+BUILTIN(__nvvm_i2d_rm, "di", "nc")
+BUILTIN(__nvvm_i2d_rp, "di", "nc")
+BUILTIN(__nvvm_ui2d_rn, "dUi", "nc")
+BUILTIN(__nvvm_ui2d_rz, "dUi", "nc")
+BUILTIN(__nvvm_ui2d_rm, "dUi", "nc")
+BUILTIN(__nvvm_ui2d_rp, "dUi", "nc")
+BUILTIN(__nvvm_f2i_rn_ftz, "if", "nc")
+BUILTIN(__nvvm_f2i_rn, "if", "nc")
+BUILTIN(__nvvm_f2i_rz_ftz, "if", "nc")
+BUILTIN(__nvvm_f2i_rz, "if", "nc")
+BUILTIN(__nvvm_f2i_rm_ftz, "if", "nc")
+BUILTIN(__nvvm_f2i_rm, "if", "nc")
+BUILTIN(__nvvm_f2i_rp_ftz, "if", "nc")
+BUILTIN(__nvvm_f2i_rp, "if", "nc")
+BUILTIN(__nvvm_f2ui_rn_ftz, "Uif", "nc")
+BUILTIN(__nvvm_f2ui_rn, "Uif", "nc")
+BUILTIN(__nvvm_f2ui_rz_ftz, "Uif", "nc")
+BUILTIN(__nvvm_f2ui_rz, "Uif", "nc")
+BUILTIN(__nvvm_f2ui_rm_ftz, "Uif", "nc")
+BUILTIN(__nvvm_f2ui_rm, "Uif", "nc")
+BUILTIN(__nvvm_f2ui_rp_ftz, "Uif", "nc")
+BUILTIN(__nvvm_f2ui_rp, "Uif", "nc")
+BUILTIN(__nvvm_i2f_rn, "fi", "nc")
+BUILTIN(__nvvm_i2f_rz, "fi", "nc")
+BUILTIN(__nvvm_i2f_rm, "fi", "nc")
+BUILTIN(__nvvm_i2f_rp, "fi", "nc")
+BUILTIN(__nvvm_ui2f_rn, "fUi", "nc")
+BUILTIN(__nvvm_ui2f_rz, "fUi", "nc")
+BUILTIN(__nvvm_ui2f_rm, "fUi", "nc")
+BUILTIN(__nvvm_ui2f_rp, "fUi", "nc")
+BUILTIN(__nvvm_lohi_i2d, "dii", "nc")
+BUILTIN(__nvvm_d2i_lo, "id", "nc")
+BUILTIN(__nvvm_d2i_hi, "id", "nc")
+BUILTIN(__nvvm_f2ll_rn_ftz, "LLif", "nc")
+BUILTIN(__nvvm_f2ll_rn, "LLif", "nc")
+BUILTIN(__nvvm_f2ll_rz_ftz, "LLif", "nc")
+BUILTIN(__nvvm_f2ll_rz, "LLif", "nc")
+BUILTIN(__nvvm_f2ll_rm_ftz, "LLif", "nc")
+BUILTIN(__nvvm_f2ll_rm, "LLif", "nc")
+BUILTIN(__nvvm_f2ll_rp_ftz, "LLif", "nc")
+BUILTIN(__nvvm_f2ll_rp, "LLif", "nc")
+BUILTIN(__nvvm_f2ull_rn_ftz, "ULLif", "nc")
+BUILTIN(__nvvm_f2ull_rn, "ULLif", "nc")
+BUILTIN(__nvvm_f2ull_rz_ftz, "ULLif", "nc")
+BUILTIN(__nvvm_f2ull_rz, "ULLif", "nc")
+BUILTIN(__nvvm_f2ull_rm_ftz, "ULLif", "nc")
+BUILTIN(__nvvm_f2ull_rm, "ULLif", "nc")
+BUILTIN(__nvvm_f2ull_rp_ftz, "ULLif", "nc")
+BUILTIN(__nvvm_f2ull_rp, "ULLif", "nc")
+BUILTIN(__nvvm_d2ll_rn, "LLid", "nc")
+BUILTIN(__nvvm_d2ll_rz, "LLid", "nc")
+BUILTIN(__nvvm_d2ll_rm, "LLid", "nc")
+BUILTIN(__nvvm_d2ll_rp, "LLid", "nc")
+BUILTIN(__nvvm_d2ull_rn, "ULLid", "nc")
+BUILTIN(__nvvm_d2ull_rz, "ULLid", "nc")
+BUILTIN(__nvvm_d2ull_rm, "ULLid", "nc")
+BUILTIN(__nvvm_d2ull_rp, "ULLid", "nc")
+BUILTIN(__nvvm_ll2f_rn, "fLLi", "nc")
+BUILTIN(__nvvm_ll2f_rz, "fLLi", "nc")
+BUILTIN(__nvvm_ll2f_rm, "fLLi", "nc")
+BUILTIN(__nvvm_ll2f_rp, "fLLi", "nc")
+BUILTIN(__nvvm_ull2f_rn, "fULLi", "nc")
+BUILTIN(__nvvm_ull2f_rz, "fULLi", "nc")
+BUILTIN(__nvvm_ull2f_rm, "fULLi", "nc")
+BUILTIN(__nvvm_ull2f_rp, "fULLi", "nc")
+BUILTIN(__nvvm_ll2d_rn, "dLLi", "nc")
+BUILTIN(__nvvm_ll2d_rz, "dLLi", "nc")
+BUILTIN(__nvvm_ll2d_rm, "dLLi", "nc")
+BUILTIN(__nvvm_ll2d_rp, "dLLi", "nc")
+BUILTIN(__nvvm_ull2d_rn, "dULLi", "nc")
+BUILTIN(__nvvm_ull2d_rz, "dULLi", "nc")
+BUILTIN(__nvvm_ull2d_rm, "dULLi", "nc")
+BUILTIN(__nvvm_ull2d_rp, "dULLi", "nc")
+BUILTIN(__nvvm_f2h_rn_ftz, "Usf", "nc")
+BUILTIN(__nvvm_f2h_rn, "Usf", "nc")
+BUILTIN(__nvvm_h2f, "fUs", "nc")
+BUILTIN(__nvvm_bitcast_i2f, "fi", "nc")
+BUILTIN(__nvvm_bitcast_f2i, "if", "nc")
+BUILTIN(__nvvm_bitcast_ll2d, "dLLi", "nc")
+BUILTIN(__nvvm_bitcast_d2ll, "LLid", "nc")
+
#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def
index 75e60742148d..5b46f8e6ad11 100644
--- a/include/clang/Basic/BuiltinsX86.def
+++ b/include/clang/Basic/BuiltinsX86.def
@@ -613,6 +613,12 @@ BUILTIN(__builtin_ia32_gatherd_d256, "V8iV8iV8iC*V8iV8iIc", "")
BUILTIN(__builtin_ia32_gatherq_d, "V4iV4iV4iC*V2LLiV4iIc", "")
BUILTIN(__builtin_ia32_gatherq_d256, "V4iV4iV4iC*V4LLiV4iIc", "")
+// F16C
+BUILTIN(__builtin_ia32_vcvtps2ph, "V8sV4fIi", "")
+BUILTIN(__builtin_ia32_vcvtps2ph256, "V8sV8fIi", "")
+BUILTIN(__builtin_ia32_vcvtph2ps, "V4fV8s", "")
+BUILTIN(__builtin_ia32_vcvtph2ps256, "V8fV8s", "")
+
// RDRAND
BUILTIN(__builtin_ia32_rdrand16_step, "UiUs*", "")
BUILTIN(__builtin_ia32_rdrand32_step, "UiUi*", "")
@@ -730,5 +736,8 @@ BUILTIN(__builtin_ia32_vfrczps, "V4fV4f", "")
BUILTIN(__builtin_ia32_vfrczpd, "V2dV2d", "")
BUILTIN(__builtin_ia32_vfrczps256, "V8fV8f", "")
BUILTIN(__builtin_ia32_vfrczpd256, "V4dV4d", "")
+BUILTIN(__builtin_ia32_xbegin, "i", "")
+BUILTIN(__builtin_ia32_xend, "v", "")
+BUILTIN(__builtin_ia32_xabort, "vIc", "")
#undef BUILTIN
diff --git a/include/clang/Basic/ConvertUTF.h b/include/clang/Basic/ConvertUTF.h
index e7cfa8a7677c..cdc42699e3eb 100644
--- a/include/clang/Basic/ConvertUTF.h
+++ b/include/clang/Basic/ConvertUTF.h
@@ -147,7 +147,6 @@ ConversionResult ConvertUTF32toUTF8 (
const UTF32** sourceStart, const UTF32* sourceEnd,
UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
-#ifdef CLANG_NEEDS_THESE_ONE_DAY
ConversionResult ConvertUTF16toUTF32 (
const UTF16** sourceStart, const UTF16* sourceEnd,
UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
@@ -159,7 +158,9 @@ ConversionResult ConvertUTF32toUTF16 (
Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd);
-Boolean isLegalUTF8String(const UTF8 *source, const UTF8 *sourceEnd);
+Boolean isLegalUTF8String(const UTF8 **source, const UTF8 *sourceEnd);
+
+unsigned getNumBytesForUTF8(UTF8 firstByte);
#ifdef __cplusplus
}
@@ -175,11 +176,13 @@ namespace clang {
* Convert an UTF8 StringRef to UTF8, UTF16, or UTF32 depending on
* WideCharWidth. The converted data is written to ResultPtr, which needs to
* point to at least WideCharWidth * (Source.Size() + 1) bytes. On success,
- * ResultPtr will point one after the end of the copied string.
+ * ResultPtr will point one after the end of the copied string. On failure,
+ * ResultPtr will not be changed, and ErrorPtr will be set to the location of
+ * the first character which could not be converted.
* \return true on success.
*/
bool ConvertUTF8toWide(unsigned WideCharWidth, llvm::StringRef Source,
- char *&ResultPtr);
+ char *&ResultPtr, const UTF8 *&ErrorPtr);
/**
* Convert an Unicode code point to UTF8 sequence.
@@ -194,7 +197,6 @@ bool ConvertUTF8toWide(unsigned WideCharWidth, llvm::StringRef Source,
bool ConvertCodePointToUTF8(unsigned Source, char *&ResultPtr);
}
-#endif
#endif
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h
index 3997fb89ba82..e47f3e185741 100644
--- a/include/clang/Basic/Diagnostic.h
+++ b/include/clang/Basic/Diagnostic.h
@@ -16,6 +16,7 @@
#define LLVM_CLANG_DIAGNOSTIC_H
#include "clang/Basic/DiagnosticIDs.h"
+#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
@@ -29,6 +30,7 @@
namespace clang {
class DiagnosticConsumer;
class DiagnosticBuilder;
+ class DiagnosticOptions;
class IdentifierInfo;
class DeclContext;
class LangOptions;
@@ -160,13 +162,6 @@ public:
ak_qualtype_pair ///< pair<QualType, QualType>
};
- /// \brief Specifies which overload candidates to display when overload
- /// resolution fails.
- enum OverloadsShown {
- Ovl_All, ///< Show all overloads.
- Ovl_Best ///< Show just the "best" overload candidates.
- };
-
/// \brief Represents on argument value, which is a union discriminated
/// by ArgumentKind, with a value.
typedef std::pair<ArgumentKind, intptr_t> ArgumentValue;
@@ -190,6 +185,7 @@ private:
// backtrace stack, 0 -> no limit.
ExtensionHandling ExtBehavior; // Map extensions onto warnings or errors?
IntrusiveRefCntPtr<DiagnosticIDs> Diags;
+ IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
DiagnosticConsumer *Client;
bool OwnsDiagClient;
SourceManager *SourceMgr;
@@ -341,6 +337,7 @@ private:
public:
explicit DiagnosticsEngine(
const IntrusiveRefCntPtr<DiagnosticIDs> &Diags,
+ DiagnosticOptions *DiagOpts,
DiagnosticConsumer *client = 0,
bool ShouldOwnClient = true);
~DiagnosticsEngine();
@@ -349,6 +346,9 @@ public:
return Diags;
}
+ /// \brief Retrieve the diagnostic options.
+ DiagnosticOptions &getDiagnosticOptions() const { return *DiagOpts; }
+
DiagnosticConsumer *getClient() { return Client; }
const DiagnosticConsumer *getClient() const { return Client; }
@@ -478,10 +478,13 @@ public:
}
OverloadsShown getShowOverloads() const { return ShowOverloads; }
- /// \brief Pretend that the last diagnostic issued was ignored.
+ /// \brief Pretend that the last diagnostic issued was ignored, so any
+ /// subsequent notes will be suppressed.
///
/// This can be used by clients who suppress diagnostics themselves.
void setLastDiagnosticIgnored() {
+ if (LastDiagLevel == DiagnosticIDs::Fatal)
+ FatalErrorOccurred = true;
LastDiagLevel = DiagnosticIDs::Ignored;
}
@@ -584,7 +587,7 @@ public:
const char *Argument, unsigned ArgLen,
const ArgumentValue *PrevArgs, unsigned NumPrevArgs,
SmallVectorImpl<char> &Output,
- SmallVectorImpl<intptr_t> &QualTypeVals) const {
+ ArrayRef<intptr_t> QualTypeVals) const {
ArgToStringFn(Kind, Val, Modifier, ModLen, Argument, ArgLen,
PrevArgs, NumPrevArgs, Output, ArgToStringCookie,
QualTypeVals);
@@ -837,7 +840,7 @@ class DiagnosticBuilder {
/// call to ForceEmit.
mutable bool IsForceEmit;
- void operator=(const DiagnosticBuilder&); // DO NOT IMPLEMENT
+ void operator=(const DiagnosticBuilder &) LLVM_DELETED_FUNCTION;
friend class DiagnosticsEngine;
DiagnosticBuilder()
@@ -961,6 +964,10 @@ public:
"Too many arguments to diagnostic!");
DiagObj->DiagFixItHints[NumFixits++] = Hint;
}
+
+ bool hasMaxRanges() const {
+ return NumRanges == DiagnosticsEngine::MaxRanges;
+ }
};
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
diff --git a/include/clang/Basic/DiagnosticASTKinds.td b/include/clang/Basic/DiagnosticASTKinds.td
index 9cfe5efae259..d869c9983bd7 100644
--- a/include/clang/Basic/DiagnosticASTKinds.td
+++ b/include/clang/Basic/DiagnosticASTKinds.td
@@ -137,7 +137,7 @@ def err_odr_function_type_inconsistent : Error<
def warn_odr_tag_type_inconsistent : Warning<
"type %0 has incompatible definitions in different translation units">;
def note_odr_tag_kind_here: Note<
- "%0 is a %select{struct|union|class|enum}1 here">;
+ "%0 is a %select{struct|interface|union|class|enum}1 here">;
def note_odr_field : Note<"field %0 has type %1 here">;
def note_odr_missing_field : Note<"no corresponding field here">;
def note_odr_bit_field : Note<"bit-field %0 with type %1 and length %2 here">;
diff --git a/include/clang/Basic/DiagnosticCommentKinds.td b/include/clang/Basic/DiagnosticCommentKinds.td
index 235ca79564d3..e6dfe5b6387c 100644
--- a/include/clang/Basic/DiagnosticCommentKinds.td
+++ b/include/clang/Basic/DiagnosticCommentKinds.td
@@ -121,5 +121,21 @@ def warn_doc_returns_attached_to_a_void_function : Warning<
"method returning void}1">,
InGroup<Documentation>, DefaultIgnore;
+// \deprecated command
+
+def warn_doc_deprecated_not_sync : Warning<
+ "declaration is marked with '\\deprecated' command but does not have "
+ "a deprecation attribute">,
+ InGroup<DocumentationDeprecatedSync>, DefaultIgnore;
+
+def note_add_deprecation_attr : Note<
+ "add a deprecation attribute to the declaration to silence this warning">;
+
+// verbatim block commands
+
+def warn_verbatim_block_end_without_start : Warning<
+ "'\\%0' command does not terminate a verbatim text block">,
+ InGroup<Documentation>, DefaultIgnore;
+
} // end of documentation issue category
} // end of AST component
diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td
index f85928740b4c..a6ce9d4a2d21 100644
--- a/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/include/clang/Basic/DiagnosticCommonKinds.td
@@ -78,9 +78,12 @@ def note_decl_hiding_tag_type : Note<
"%1 %0 is hidden by a non-type declaration of %0 here">;
// Sema && Lex
-def ext_longlong : Extension<
+def ext_c99_longlong : Extension<
"'long long' is an extension when C99 mode is not enabled">,
InGroup<LongLong>;
+def ext_cxx11_longlong : Extension<
+ "'long long' is a C++11 extension">,
+ InGroup<CXX11LongLong>;
def warn_cxx98_compat_longlong : Warning<
"'long long' is incompatible with C++98">,
InGroup<CXX98CompatPedantic>, DefaultIgnore;
diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td
index 583b2345c935..4b430351756a 100644
--- a/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/include/clang/Basic/DiagnosticDriverKinds.td
@@ -11,6 +11,8 @@ let Component = "Driver" in {
def err_drv_no_such_file : Error<"no such file or directory: '%0'">;
def err_drv_unsupported_opt : Error<"unsupported option '%0'">;
+def err_drv_unsupported_opt_for_target : Error<
+ "unsupported option '%0' for target '%1'">;
def err_drv_unsupported_option_argument : Error<
"unsupported argument '%1' to option '%0'">;
def err_drv_unknown_stdin_type : Error<
@@ -91,10 +93,10 @@ def err_drv_invalid_arch_for_deployment_target : Error<
"invalid architecture '%0' for deployment target '%1'">;
def err_drv_objc_gc_arr : Error<
"cannot specify both '-fobjc-arc' and '%0'">;
-def err_arc_nonfragile_abi : Error<
- "-fobjc-arc is not supported with legacy abi">;
-def err_arc_unsupported : Error<
- "-fobjc-arc is not supported on current deployment target">;
+def err_arc_unsupported_on_runtime : Error<
+ "-fobjc-arc is not supported on platforms using the legacy runtime">;
+def err_arc_unsupported_on_toolchain : Error< // feel free to generalize this
+ "-fobjc-arc is not supported on versions of OS X prior to 10.6">;
def err_drv_mg_requires_m_or_mm : Error<
"option '-MG' requires '-M' or '-MM'">;
def err_drv_asan_android_requires_pie : Error<
@@ -119,14 +121,10 @@ def warn_drv_unused_argument : Warning<
def warn_drv_empty_joined_argument : Warning<
"joined argument expects additional value: '%0'">,
InGroup<DiagGroup<"unused-command-line-argument">>;
-def warn_drv_not_using_clang_cpp : Warning<
- "not using the clang preprocessor due to user override">;
-def warn_drv_not_using_clang_cxx : Warning<
- "not using the clang compiler for C++ inputs">;
-def warn_drv_not_using_clang_arch : Warning<
- "not using the clang compiler for the '%0' architecture">;
def warn_drv_clang_unsupported : Warning<
"the clang compiler does not support '%0'">;
+def warn_drv_deprecated_arg : Warning<
+ "argument '%0' is deprecated, use '%1' instead">, InGroup<Deprecated>;
def warn_drv_assuming_mfloat_abi_is : Warning<
"unknown platform, assuming -mfloat-abi=%0">;
def warn_ignoring_ftabstop_value : Warning<
@@ -141,5 +139,9 @@ def warn_drv_pch_not_first_include : Warning<
def note_drv_command_failed_diag_msg : Note<
"diagnostic msg: %0">;
-
+
+def err_analyzer_config_no_value : Error<
+ "analyzer-config option '%0' has a key but no value">;
+def err_analyzer_config_multiple_values : Error<
+ "analyzer-config option '%0' should contain only one '='">;
}
diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td
index 417a22c96df5..b7a84764391b 100644
--- a/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -58,6 +58,8 @@ def warn_fe_cc_print_header_failure : Warning<
"unable to open CC_PRINT_HEADERS file: %0 (using stderr)">;
def warn_fe_cc_log_diagnostics_failure : Warning<
"unable to open CC_LOG_DIAGNOSTICS file: %0 (using stderr)">;
+def err_fe_no_pch_in_dir : Error<
+ "no suitable precompiled header file found in directory '%0'">;
def warn_fe_serialized_diag_failure : Warning<
"unable to open file %0 for serializing diagnostics (%1)">,
@@ -76,6 +78,11 @@ def err_verify_invalid_content : Error<
def err_verify_inconsistent_diags : Error<
"'%0' diagnostics %select{expected|seen}1 but not %select{seen|expected}1: "
"%2">;
+def err_verify_invalid_no_diags : Error<
+ "%select{expected|'expected-no-diagnostics'}0 directive cannot follow "
+ "%select{'expected-no-diagnostics' directive|other expected directives}0">;
+def err_verify_no_directives : Error<
+ "no expected directives found: consider use of 'expected-no-diagnostics'">;
def note_fixit_applied : Note<"FIX-IT applied suggested code changes">;
def note_fixit_in_macro : Note<
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index d8632dd8c39d..f9f9ec78309a 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -22,8 +22,6 @@ def : DiagGroup<"address">;
def AddressOfTemporary : DiagGroup<"address-of-temporary">;
def : DiagGroup<"aggregate-return">;
def AmbigMemberTemplate : DiagGroup<"ambiguous-member-template">;
-def : DiagGroup<"attributes">;
-def : DiagGroup<"bad-function-cast">;
def Availability : DiagGroup<"availability">;
def Section : DiagGroup<"section">;
def AutoImport : DiagGroup<"auto-import">;
@@ -33,8 +31,11 @@ def StringConversion : DiagGroup<"string-conversion">;
def SignConversion : DiagGroup<"sign-conversion">;
def BoolConversion : DiagGroup<"bool-conversion">;
def IntConversion : DiagGroup<"int-conversion">;
+def EnumConversion : DiagGroup<"enum-conversion">;
def NonLiteralNullConversion : DiagGroup<"non-literal-null-conversion">;
def NullConversion : DiagGroup<"null-conversion">;
+def ImplicitConversionFloatingPointToBool :
+ DiagGroup<"implicit-conversion-floating-point-to-bool">;
def BuiltinRequiresHeader : DiagGroup<"builtin-requires-header">;
def CXXCompat: DiagGroup<"c++-compat">;
def CastAlign : DiagGroup<"cast-align">;
@@ -42,11 +43,11 @@ def : DiagGroup<"cast-qual">;
def : DiagGroup<"char-align">;
def Comment : DiagGroup<"comment">;
def : DiagGroup<"ctor-dtor-privacy">;
-def : DiagGroup<"declaration-after-statement">;
def DefaultArgSpecialMember : DiagGroup<"default-arg-special-member">;
def GNUDesignator : DiagGroup<"gnu-designator">;
def DeleteNonVirtualDtor : DiagGroup<"delete-non-virtual-dtor">;
+def AbstractFinalClass : DiagGroup<"abstract-final-class">;
def DeprecatedDeclarations : DiagGroup<"deprecated-declarations">;
def DeprecatedWritableStr : DiagGroup<"deprecated-writable-strings">;
@@ -58,9 +59,14 @@ def DeprecatedImplementations :DiagGroup<"deprecated-implementations">;
def : DiagGroup<"disabled-optimization">;
def : DiagGroup<"discard-qual">;
def : DiagGroup<"div-by-zero">;
+
def DocumentationHTML : DiagGroup<"documentation-html">;
def DocumentationPedantic : DiagGroup<"documentation-pedantic">;
-def Documentation : DiagGroup<"documentation", [DocumentationHTML]>;
+def DocumentationDeprecatedSync : DiagGroup<"documentation-deprecated-sync">;
+def Documentation : DiagGroup<"documentation",
+ [DocumentationHTML,
+ DocumentationDeprecatedSync]>;
+
def EmptyBody : DiagGroup<"empty-body">;
def ExtraTokens : DiagGroup<"extra-tokens">;
def CXX11ExtraSemi : DiagGroup<"c++11-extra-semi">;
@@ -108,9 +114,9 @@ def ExitTimeDestructors : DiagGroup<"exit-time-destructors">;
def FlexibleArrayExtensions : DiagGroup<"flexible-array-extensions">;
def FourByteMultiChar : DiagGroup<"four-char-constants">;
def GlobalConstructors : DiagGroup<"global-constructors">;
-def : DiagGroup<"idiomatic-parentheses">;
def BitwiseOpParentheses: DiagGroup<"bitwise-op-parentheses">;
def LogicalOpParentheses: DiagGroup<"logical-op-parentheses">;
+def ShiftOpParentheses: DiagGroup<"shift-op-parentheses">;
def DanglingElse: DiagGroup<"dangling-else">;
def IgnoredQualifiers : DiagGroup<"ignored-qualifiers">;
def : DiagGroup<"import">;
@@ -119,7 +125,6 @@ def IncompleteUmbrella : DiagGroup<"incomplete-umbrella">;
def KNRPromotedParameter : DiagGroup<"knr-promoted-parameter">;
def : DiagGroup<"init-self">;
def : DiagGroup<"inline">;
-def : DiagGroup<"int-to-pointer-cast">;
def : DiagGroup<"invalid-pch">;
def LiteralRange : DiagGroup<"literal-range">;
def LocalTypeTemplateArgs : DiagGroup<"local-type-template-args",
@@ -131,11 +136,12 @@ def MissingBraces : DiagGroup<"missing-braces">;
def MissingDeclarations: DiagGroup<"missing-declarations">;
def : DiagGroup<"missing-format-attribute">;
def : DiagGroup<"missing-include-dirs">;
-def : DiagGroup<"missing-noreturn">;
def MultiChar : DiagGroup<"multichar">;
def : DiagGroup<"nested-externs">;
-def : DiagGroup<"newline-eof">;
-def LongLong : DiagGroup<"long-long">;
+def CXX11LongLong : DiagGroup<"c++11-long-long">;
+def LongLong : DiagGroup<"long-long", [CXX11LongLong]>;
+def MismatchedParameterTypes : DiagGroup<"mismatched-parameter-types">;
+def MismatchedReturnTypes : DiagGroup<"mismatched-return-types">;
def MismatchedTags : DiagGroup<"mismatched-tags">;
def MissingFieldInitializers : DiagGroup<"missing-field-initializers">;
def ModuleBuild : DiagGroup<"module-build">;
@@ -157,6 +163,7 @@ def OverlengthStrings : DiagGroup<"overlength-strings">;
def OverloadedVirtual : DiagGroup<"overloaded-virtual">;
def PrivateExtern : DiagGroup<"private-extern">;
def SelTypeCast : DiagGroup<"cast-of-sel-type">;
+def BadFunctionCast : DiagGroup<"bad-function-cast">;
def ObjCPropertyImpl : DiagGroup<"objc-property-implementation">;
def ObjCPropertyNoAttribute : DiagGroup<"objc-property-no-attribute">;
def ObjCMissingSuperCalls : DiagGroup<"objc-missing-super-calls">;
@@ -183,7 +190,7 @@ def Sentinel : DiagGroup<"sentinel">;
def MissingMethodReturnType : DiagGroup<"missing-method-return-type">;
def : DiagGroup<"sequence-point">;
def Shadow : DiagGroup<"shadow">;
-def : DiagGroup<"shorten-64-to-32">;
+def Shorten64To32 : DiagGroup<"shorten-64-to-32">;
def : DiagGroup<"sign-promo">;
def SignCompare : DiagGroup<"sign-compare">;
def : DiagGroup<"stack-protector">;
@@ -192,11 +199,15 @@ def : DiagGroup<"synth">;
def SizeofArrayArgument : DiagGroup<"sizeof-array-argument">;
def StringPlusInt : DiagGroup<"string-plus-int">;
def StrncatSize : DiagGroup<"strncat-size">;
-def TautologicalCompare : DiagGroup<"tautological-compare">;
+def TautologicalOutOfRangeCompare : DiagGroup<"tautological-constant-out-of-range-compare">;
+def TautologicalCompare : DiagGroup<"tautological-compare",
+ [TautologicalOutOfRangeCompare]>;
def HeaderHygiene : DiagGroup<"header-hygiene">;
+def DuplicateDeclSpecifier : DiagGroup<"duplicate-decl-specifier">;
+def CompareDistinctPointerType : DiagGroup<"compare-distinct-pointer-types">;
// Preprocessor warnings.
-def : DiagGroup<"builtin-macro-redefined">;
+def AmbiguousMacro : DiagGroup<"ambiguous-macro">;
// Just silence warnings about -Wstrict-aliasing for now.
def : DiagGroup<"strict-aliasing=0">;
@@ -262,26 +273,29 @@ def ImplicitAtomic : DiagGroup<"implicit-atomic-properties">;
def CustomAtomic : DiagGroup<"custom-atomic-properties">;
def AtomicProperties : DiagGroup<"atomic-properties",
[ImplicitAtomic, CustomAtomic]>;
-def AutomaticReferenceCountingABI : DiagGroup<"arc-abi">;
+// FIXME: Remove arc-abi once an Xcode is released that doesn't pass this flag.
+def : DiagGroup<"arc-abi">;
def ARCUnsafeRetainedAssign : DiagGroup<"arc-unsafe-retained-assign">;
def ARCRetainCycles : DiagGroup<"arc-retain-cycles">;
def ARCNonPodMemAccess : DiagGroup<"arc-non-pod-memaccess">;
def AutomaticReferenceCounting : DiagGroup<"arc",
- [AutomaticReferenceCountingABI,
- ARCUnsafeRetainedAssign,
+ [ARCUnsafeRetainedAssign,
ARCRetainCycles,
ARCNonPodMemAccess]>;
+def ARCRepeatedUseOfWeakMaybe : DiagGroup<"arc-maybe-repeated-use-of-weak">;
+def ARCRepeatedUseOfWeak : DiagGroup<"arc-repeated-use-of-weak",
+ [ARCRepeatedUseOfWeakMaybe]>;
def Selector : DiagGroup<"selector">;
def Protocol : DiagGroup<"protocol">;
def SuperSubClassMismatch : DiagGroup<"super-class-method-mismatch">;
def OverridingMethodMismatch : DiagGroup<"overriding-method-mismatch">;
-def : DiagGroup<"variadic-macros">;
def VariadicMacros : DiagGroup<"variadic-macros">;
def VectorConversion : DiagGroup<"vector-conversion">; // clang specific
def VexingParse : DiagGroup<"vexing-parse">;
def VLA : DiagGroup<"vla">;
def VolatileRegisterVar : DiagGroup<"volatile-register-var">;
def Visibility : DiagGroup<"visibility">;
+def ZeroLengthArray : DiagGroup<"zero-length-array">;
// GCC calls -Wdeprecated-writable-strings -Wwrite-strings.
def GCCWriteStrings : DiagGroup<"write-strings" , [DeprecatedWritableStr]>;
@@ -300,6 +314,7 @@ def ParenthesesOnEquality : DiagGroup<"parentheses-equality">;
def Parentheses : DiagGroup<"parentheses",
[LogicalOpParentheses,
BitwiseOpParentheses,
+ ShiftOpParentheses,
ParenthesesOnEquality,
DanglingElse]>;
@@ -311,15 +326,16 @@ def Parentheses : DiagGroup<"parentheses",
// - bool-to-pointer conversion warnings are on by default
// - __null-to-integer conversion warnings are on by default
def Conversion : DiagGroup<"conversion",
- [DiagGroup<"shorten-64-to-32">,
+ [BoolConversion,
ConstantConversion,
+ EnumConversion,
+ Shorten64To32,
+ IntConversion,
LiteralConversion,
- StringConversion,
- SignConversion,
- BoolConversion,
- NullConversion, // NULL->non-pointer
NonLiteralNullConversion, // (1-1)->pointer (etc)
- IntConversion]>,
+ NullConversion, // NULL->non-pointer
+ SignConversion,
+ StringConversion]>,
DiagCategory<"Value Conversion Issue">;
def Unused : DiagGroup<"unused",
@@ -345,6 +361,8 @@ def Format2 : DiagGroup<"format=2",
def TypeSafety : DiagGroup<"type-safety">;
+def IntToPointerCast : DiagGroup<"int-to-pointer-cast">;
+
def Extra : DiagGroup<"extra", [
MissingFieldInitializers,
IgnoredQualifiers,
@@ -361,6 +379,7 @@ def Most : DiagGroup<"most", [
DeleteNonVirtualDtor,
Format,
Implicit,
+ IntToPointerCast,
MismatchedTags,
MissingBraces,
MultiChar,
@@ -382,9 +401,12 @@ def Most : DiagGroup<"most", [
// Thread Safety warnings
def ThreadSafetyAttributes : DiagGroup<"thread-safety-attributes">;
-def ThreadSafetyAnalysis : DiagGroup<"thread-safety-analysis">;
-def ThreadSafety : DiagGroup<"thread-safety",
- [ThreadSafetyAttributes, ThreadSafetyAnalysis]>;
+def ThreadSafetyAnalysis : DiagGroup<"thread-safety-analysis">;
+def ThreadSafetyPrecise : DiagGroup<"thread-safety-precise">;
+def ThreadSafety : DiagGroup<"thread-safety",
+ [ThreadSafetyAttributes,
+ ThreadSafetyAnalysis,
+ ThreadSafetyPrecise]>;
// Note that putting warnings in -Wall will not disable them by default. If a
// warning should be active _only_ when -Wall is passed in, mark it as
@@ -414,7 +436,8 @@ def NonGCC : DiagGroup<"non-gcc",
// A warning group for warnings about using C++11 features as extensions in
// earlier C++ versions.
-def CXX11 : DiagGroup<"c++11-extensions", [CXX11ExtraSemi]>;
+def CXX11 : DiagGroup<"c++11-extensions", [CXX11ExtraSemi, CXX11LongLong]>;
+
def : DiagGroup<"c++0x-extensions", [CXX11]>;
def DelegatingCtorCycles :
DiagGroup<"delegating-ctor-cycles">;
@@ -426,7 +449,7 @@ def C11 : DiagGroup<"c11-extensions">;
def C99 : DiagGroup<"c99-extensions">;
// A warning group for warnings about GCC extensions.
-def GNU : DiagGroup<"gnu", [GNUDesignator, VLA]>;
+def GNU : DiagGroup<"gnu", [GNUDesignator, VLA, ZeroLengthArray]>;
// A warning group for warnings about code that clang accepts but gcc doesn't.
def GccCompat : DiagGroup<"gcc-compat">;
@@ -451,3 +474,9 @@ def ObjCStringComparison : DiagGroup<"objc-string-compare">;
def ObjCLiteralComparison : DiagGroup<"objc-literal-compare", [
ObjCStringComparison
]>;
+
+// Inline ASM warnings.
+def ASMOperandWidths : DiagGroup<"asm-operand-widths">;
+def ASM : DiagGroup<"asm", [
+ ASMOperandWidths
+ ]>;
diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td
index cc958dbdfea2..c6c50ab37b87 100644
--- a/include/clang/Basic/DiagnosticLexKinds.td
+++ b/include/clang/Basic/DiagnosticLexKinds.td
@@ -41,9 +41,9 @@ def trigraph_ends_block_comment : Warning<"trigraph ends block comment">,
def trigraph_converted : Warning<"trigraph converted to '%0' character">,
InGroup<Trigraphs>;
-def ext_multi_line_bcpl_comment : Extension<"multi-line // comment">,
+def ext_multi_line_line_comment : Extension<"multi-line // comment">,
InGroup<Comment>;
-def ext_bcpl_comment : Extension<
+def ext_line_comment : Extension<
"// comments are not allowed in this language">,
InGroup<Comment>;
def ext_no_newline_eof : Extension<"no newline at end of file">,
@@ -55,7 +55,7 @@ def warn_cxx98_compat_no_newline_eof : Warning<
def ext_dollar_in_identifier : Extension<"'$' in identifier">,
InGroup<DiagGroup<"dollar-in-identifier-extension">>;
-def ext_charize_microsoft : Extension<"@# is a microsoft extension">,
+def ext_charize_microsoft : Extension<"charizing operator #@ is a Microsoft extension">,
InGroup<Microsoft>;
def ext_token_used : Extension<"extension used">,
@@ -127,15 +127,16 @@ 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 an extension">;
+def ext_imaginary_constant : Extension<
+ "imaginary constants are a GNU extension">, InGroup<GNU>;
def err_hexconstant_requires_exponent : Error<
"hexadecimal floating constants require an exponent">;
def err_hexconstant_requires_digits : Error<
"hexadecimal floating constants require a significand">;
def ext_hexconstant_invalid : Extension<
- "hexadecimal floating constants are a C99 feature">;
+ "hexadecimal floating constants are a C99 feature">, InGroup<C99>;
def ext_binary_literal : Extension<
- "binary integer literals are an extension">;
+ "binary integer literals are a GNU extension">, InGroup<GNU>;
def err_pascal_string_too_long : Error<"Pascal string is too long">;
def warn_octal_escape_too_large : ExtWarn<"octal escape sequence out of range">;
def warn_hex_escape_too_large : ExtWarn<"hex escape sequence out of range">;
@@ -228,6 +229,12 @@ def pp_macro_not_used : Warning<"macro is not used">, DefaultIgnore,
def warn_pp_undef_identifier : Warning<
"%0 is not defined, evaluates to 0">,
InGroup<DiagGroup<"undef">>, DefaultIgnore;
+def warn_pp_ambiguous_macro : Warning<
+ "ambiguous expansion of macro %0">, InGroup<AmbiguousMacro>;
+def note_pp_ambiguous_macro_chosen : Note<
+ "expanding this definition of %0">;
+def note_pp_ambiguous_macro_other : Note<
+ "other definition of %0">;
def pp_invalid_string_literal : Warning<
"invalid string literal, ignoring final '\\'">;
@@ -484,15 +491,21 @@ def err_mmap_missing_module_unqualified : Error<
def err_mmap_missing_module_qualified : Error<
"no module named '%0' in '%1'">;
def err_mmap_top_level_inferred_submodule : Error<
- "only submodules may be inferred with wildcard syntax">;
+ "only submodules and framework modules may be inferred with wildcard syntax">;
def err_mmap_inferred_no_umbrella : Error<
"inferred submodules require a module with an umbrella">;
+def err_mmap_inferred_framework_submodule : Error<
+ "inferred submodule cannot be a framework submodule">;
+def err_mmap_explicit_inferred_framework : Error<
+ "inferred framework modules cannot be 'explicit'">;
+def err_mmap_missing_exclude_name : Error<
+ "expected excluded module name">;
def err_mmap_inferred_redef : Error<
"redefinition of inferred submodule">;
def err_mmap_expected_lbrace_wildcard : Error<
"expected '{' to start inferred submodule">;
-def err_mmap_expected_wildcard_member : Error<
- "expected module export wildcard">;
+def err_mmap_expected_inferred_member : Error<
+ "expected %select{module exclusion with 'exclude'|'export *'}0">;
def err_mmap_expected_export_wildcard : Error<
"only '*' can be exported from an inferred submodule">;
def err_mmap_explicit_top_level : Error<
@@ -509,5 +522,7 @@ def warn_auto_module_import : Warning<
"import of module '%1'">, InGroup<AutoImport>, DefaultIgnore;
def warn_uncovered_module_header : Warning<
"umbrella header does not include header '%0'">, InGroup<IncompleteUmbrella>;
-
+def err_expected_id_building_module : Error<
+ "expected a module name in '__building_module' expression">;
+
}
diff --git a/include/clang/Basic/DiagnosticOptions.def b/include/clang/Basic/DiagnosticOptions.def
new file mode 100644
index 000000000000..476ac1e373f0
--- /dev/null
+++ b/include/clang/Basic/DiagnosticOptions.def
@@ -0,0 +1,93 @@
+//===--- DiagOptions.def - Diagnostic option 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 diagnostic options. Users of this file
+// must define the DIAGOPT macro to make use of this information.
+// Optionally, the user may also define ENUM_DIAGOPT (for options
+// that have enumeration type and VALUE_DIAGOPT (for options that
+// describe a value rather than a flag). The SEMANTIC_* variants of these macros
+// indicate options that affect the processing of the program, rather than
+// simply the output.
+//
+//===----------------------------------------------------------------------===//
+#ifndef DIAGOPT
+# error Define the DIAGOPT macro to handle language options
+#endif
+
+#ifndef VALUE_DIAGOPT
+# define VALUE_DIAGOPT(Name, Bits, Default) \
+DIAGOPT(Name, Bits, Default)
+#endif
+
+#ifndef ENUM_DIAGOPT
+# define ENUM_DIAGOPT(Name, Type, Bits, Default) \
+DIAGOPT(Name, Bits, Default)
+#endif
+
+#ifndef SEMANTIC_DIAGOPT
+# define SEMANTIC_DIAGOPT(Name, Bits, Default) DIAGOPT(Name, Bits, Default)
+#endif
+
+#ifndef SEMANTIC_VALUE_DIAGOPT
+# define SEMANTIC_VALUE_DIAGOPT(Name, Bits, Default) \
+ VALUE_DIAGOPT(Name, Bits, Default)
+#endif
+
+#ifndef SEMANTIC_ENUM_DIAGOPT
+# define SEMANTIC_ENUM_DIAGOPT(Name, Type, Bits, Default) \
+ ENUM_DIAGOPT(Name, Type, Bits, Default)
+#endif
+
+SEMANTIC_DIAGOPT(IgnoreWarnings, 1, 0) /// -w
+DIAGOPT(NoRewriteMacros, 1, 0) /// -Wno-rewrite-macros
+DIAGOPT(Pedantic, 1, 0) /// -pedantic
+DIAGOPT(PedanticErrors, 1, 0) /// -pedantic-errors
+DIAGOPT(ShowColumn, 1, 1) /// Show column number on diagnostics.
+DIAGOPT(ShowLocation, 1, 1) /// Show source location information.
+DIAGOPT(ShowCarets, 1, 1) /// Show carets in diagnostics.
+DIAGOPT(ShowFixits, 1, 1) /// Show fixit information.
+DIAGOPT(ShowSourceRanges, 1, 0) /// Show source ranges in numeric form.
+DIAGOPT(ShowParseableFixits, 1, 0) /// Show machine parseable fix-its.
+DIAGOPT(ShowOptionNames, 1, 0) /// Show the option name for mappable
+ /// diagnostics.
+DIAGOPT(ShowNoteIncludeStack, 1, 0) /// Show include stacks for notes.
+VALUE_DIAGOPT(ShowCategories, 2, 0) /// Show categories: 0 -> none, 1 -> Number,
+ /// 2 -> Full Name.
+
+ENUM_DIAGOPT(Format, TextDiagnosticFormat, 2, Clang) /// Format for diagnostics:
+
+DIAGOPT(ShowColors, 1, 0) /// Show diagnostics with ANSI color sequences.
+ENUM_DIAGOPT(ShowOverloads, OverloadsShown, 1,
+ Ovl_All) /// Overload candidates to show.
+DIAGOPT(VerifyDiagnostics, 1, 0) /// Check that diagnostics match the expected
+ /// diagnostics, indicated by markers in the
+ /// input source file.
+
+DIAGOPT(ElideType, 1, 0) /// Elide identical types in template diffing
+DIAGOPT(ShowTemplateTree, 1, 0) /// Print a template tree when diffing
+
+VALUE_DIAGOPT(ErrorLimit, 32, 0) /// Limit # errors emitted.
+/// Limit depth of macro expansion backtrace.
+VALUE_DIAGOPT(MacroBacktraceLimit, 32, DefaultMacroBacktraceLimit)
+/// Limit depth of instantiation backtrace.
+VALUE_DIAGOPT(TemplateBacktraceLimit, 32, DefaultTemplateBacktraceLimit)
+/// Limit depth of constexpr backtrace.
+VALUE_DIAGOPT(ConstexprBacktraceLimit, 32, DefaultConstexprBacktraceLimit)
+
+VALUE_DIAGOPT(TabStop, 32, DefaultTabStop) /// The distance between tab stops.
+/// Column limit for formatting message diagnostics, or 0 if unused.
+VALUE_DIAGOPT(MessageLength, 32, 0)
+
+#undef DIAGOPT
+#undef ENUM_DIAGOPT
+#undef VALUE_DIAGOPT
+#undef SEMANTIC_DIAGOPT
+#undef SEMANTIC_ENUM_DIAGOPT
+#undef SEMANTIC_VALUE_DIAGOPT
+
diff --git a/include/clang/Basic/DiagnosticOptions.h b/include/clang/Basic/DiagnosticOptions.h
new file mode 100644
index 000000000000..b75cb0c24da3
--- /dev/null
+++ b/include/clang/Basic/DiagnosticOptions.h
@@ -0,0 +1,85 @@
+//===--- DiagnosticOptions.h ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_DIAGNOSTICOPTIONS_H
+#define LLVM_CLANG_BASIC_DIAGNOSTICOPTIONS_H
+
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+
+#include <string>
+#include <vector>
+
+namespace clang {
+
+/// \brief Specifies which overload candidates to display when overload
+/// resolution fails.
+enum OverloadsShown {
+ Ovl_All, ///< Show all overloads.
+ Ovl_Best ///< Show just the "best" overload candidates.
+};
+
+/// DiagnosticOptions - Options for controlling the compiler diagnostics
+/// engine.
+class DiagnosticOptions : public llvm::RefCountedBase<DiagnosticOptions>{
+public:
+ enum TextDiagnosticFormat { Clang, Msvc, Vi };
+
+ // Default values.
+ enum { DefaultTabStop = 8, MaxTabStop = 100,
+ DefaultMacroBacktraceLimit = 6,
+ DefaultTemplateBacktraceLimit = 10,
+ DefaultConstexprBacktraceLimit = 10 };
+
+ // Define simple diagnostic options (with no accessors).
+#define DIAGOPT(Name, Bits, Default) unsigned Name : Bits;
+#define ENUM_DIAGOPT(Name, Type, Bits, Default)
+#include "clang/Basic/DiagnosticOptions.def"
+
+protected:
+ // Define diagnostic options of enumeration type. These are private, and will
+ // have accessors (below).
+#define DIAGOPT(Name, Bits, Default)
+#define ENUM_DIAGOPT(Name, Type, Bits, Default) unsigned Name : Bits;
+#include "clang/Basic/DiagnosticOptions.def"
+
+public:
+ /// If non-empty, a file to log extended build information to, for development
+ /// testing and analysis.
+ std::string DumpBuildInformation;
+
+ /// The file to log diagnostic output to.
+ std::string DiagnosticLogFile;
+
+ /// The file to serialize diagnostics to (non-appending).
+ std::string DiagnosticSerializationFile;
+
+ /// The list of -W... options used to alter the diagnostic mappings, with the
+ /// prefixes removed.
+ std::vector<std::string> Warnings;
+
+public:
+ // Define accessors/mutators for diagnostic options of enumeration type.
+#define DIAGOPT(Name, Bits, Default)
+#define ENUM_DIAGOPT(Name, Type, Bits, Default) \
+ Type get##Name() const { return static_cast<Type>(Name); } \
+ void set##Name(Type Value) { Name = static_cast<unsigned>(Value); }
+#include "clang/Basic/DiagnosticOptions.def"
+
+ DiagnosticOptions() {
+#define DIAGOPT(Name, Bits, Default) Name = Default;
+#define ENUM_DIAGOPT(Name, Type, Bits, Default) set##Name(Default);
+#include "clang/Basic/DiagnosticOptions.def"
+ }
+};
+
+typedef DiagnosticOptions::TextDiagnosticFormat TextDiagnosticFormat;
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index b1c16fa8529f..21eeccb5a3e4 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -18,10 +18,13 @@ def w_asm_qualifier_ignored : Warning<"ignored %0 qualifier on asm">,
def warn_file_asm_volatile : Warning<
"meaningless 'volatile' on asm outside function">, CatInlineAsm;
+def warn_unsupported_msasm : Warning<
+ "MS-style inline assembly is not supported">, InGroup<Microsoft>;
+
let CategoryName = "Parse Issue" in {
def ext_empty_translation_unit : Extension<
- "ISO C requires a translation unit to contain at least one declaration.">,
+ "ISO C requires a translation unit to contain at least one declaration">,
InGroup<DiagGroup<"empty-translation-unit">>;
def warn_cxx98_compat_top_level_semi : Warning<
"extra ';' outside of a function is incompatible with C++98">,
@@ -40,11 +43,14 @@ def warn_extra_semi_after_mem_fn_def : Warning<
"extra ';' after member function definition">,
InGroup<ExtraSemi>, DefaultIgnore;
-def ext_duplicate_declspec : Extension<"duplicate '%0' declaration specifier">;
+def ext_duplicate_declspec : ExtWarn<"duplicate '%0' declaration specifier">,
+ InGroup<DuplicateDeclSpecifier>;
+def warn_duplicate_declspec : Warning<"duplicate '%0' declaration specifier">,
+ InGroup<DuplicateDeclSpecifier>;
def ext_plain_complex : ExtWarn<
"plain '_Complex' requires a type specifier; assuming '_Complex double'">;
def ext_integer_complex : Extension<
- "complex integer types are an extension">;
+ "complex integer types are a GNU extension">, InGroup<GNU>;
def ext_thread_before : Extension<"'__thread' before '%0'">;
def ext_empty_struct_union : Extension<
@@ -80,8 +86,11 @@ def err_enumerator_list_missing_comma : Error<
"missing ',' between enumerators">;
def err_enumerator_unnamed_no_def : Error<
"unnamed enumeration must be a definition">;
-def ext_ms_enum_fixed_underlying_type : Extension<
- "enumeration types with a fixed underlying type are a Microsoft extension">,
+def ext_cxx11_enum_fixed_underlying_type : Extension<
+ "enumeration types with a fixed underlying type are a C++11 extension">,
+ InGroup<CXX11>;
+def ext_c_enum_fixed_underlying_type : Extension<
+ "enumeration types with a fixed underlying type are a Microsoft extension">,
InGroup<Microsoft>;
def warn_cxx98_compat_enum_fixed_underlying_type : Warning<
"enumeration types with a fixed underlying type are incompatible with C++98">,
@@ -207,6 +216,17 @@ def err_expected_semi_after_static_assert : Error<
"expected ';' after static_assert">;
def err_expected_semi_for : Error<"expected ';' in 'for' statement specifier">;
def err_expected_colon_after : Error<"expected ':' after %0">;
+def warn_missing_selector_name : Warning<
+ "%0 used as the name of the previous parameter rather than as part "
+ "of the selector">,
+ InGroup<DiagGroup<"missing-selector-name">>;
+def note_missing_selector_name : Note<
+ "introduce a parameter name to make %0 part of the selector">;
+def note_force_empty_selector_name : Note<
+ "or insert whitespace before ':' to use %0 as parameter name "
+ "and have an empty entry in the selector">;
+def note_missing_argument_name : Note<
+ "did you mean to use %0 as the selector name instead of %1">;
def err_label_end_of_compound_statement : Error<
"label at end of compound statement: expected statement">;
def err_address_of_label_outside_fn : Error<
@@ -331,6 +351,8 @@ def ext_c11_static_assert : Extension<
def warn_cxx98_compat_static_assert : Warning<
"static_assert declarations are incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
+def err_paren_after_colon_colon : Error<
+ "unexpected parenthesis after '::'">;
/// Objective-C parser diagnostics
def err_expected_minus_or_plus : Error<
@@ -423,7 +445,8 @@ def err_expected_member_or_base_name : Error<
def err_expected_lbrace_after_base_specifiers : Error<
"expected '{' after base class list">;
def ext_ellipsis_exception_spec : Extension<
- "exception specification of '...' is a Microsoft extension">;
+ "exception specification of '...' is a Microsoft extension">,
+ InGroup<Microsoft>;
def err_dynamic_and_noexcept_specification : Error<
"cannot have both throw() and noexcept() clause on the same function">;
def warn_cxx98_compat_noexcept_decl : Warning<
@@ -455,9 +478,6 @@ def err_literal_operator_string_prefix : Error<
"string literal after 'operator' cannot have an encoding prefix">;
def err_literal_operator_string_not_empty : Error<
"string literal after 'operator' must be '\"\"'">;
-def err_literal_operator_missing_space : Error<
- "C++11 requires a space between the \"\" and the user-defined suffix in a "
- "literal operator">;
def warn_cxx98_compat_literal_operator : Warning<
"literal operators are incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
@@ -570,7 +590,7 @@ def err_expected_type_name_after_typename : Error<
"expected an identifier or template-id after '::'">;
def err_explicit_spec_non_template : Error<
"explicit %select{specialization|instantiation}0 of non-template "
- "%select{class|struct|union}1 %2">;
+ "%select{class|struct|union|interface}1 %2">;
def err_default_template_template_parameter_not_template : Error<
"default template argument for a template template parameter must be a class "
@@ -627,6 +647,11 @@ def ext_override_control_keyword : ExtWarn<
def warn_cxx98_compat_override_control_keyword : Warning<
"'%0' keyword is incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
+def err_override_control_interface : Error<
+ "'%0' keyword not permitted with interface types">;
+
+def err_access_specifier_interface : Error<
+ "interface types cannot specify '%select{private|protected}0' access">;
def err_duplicate_virt_specifier : Error<
"class member already marked '%0'">;
@@ -710,6 +735,11 @@ def warn_pragma_unused_expected_var : Warning<
"expected '#pragma unused' argument to be a variable name">;
def warn_pragma_unused_expected_punc : Warning<
"expected ')' or ',' in '#pragma unused'">;
+// - #pragma fp_contract
+def err_pragma_fp_contract_scope : Error<
+ "'#pragma fp_contract' should only appear at file scope or at the start of a "
+ "compound expression">;
+
// OpenCL Section 6.8.g
def err_not_opencl_storage_class_specifier : Error<
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 2d63dc42fd94..0d64bf38ad7c 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -20,13 +20,6 @@ def warn_variables_not_in_loop_body : Warning<
"used in loop condition not modified in loop body">,
InGroup<DiagGroup<"loop-analysis">>, DefaultIgnore;
-def warn_identical_enum_values : Warning<
- "all elements of %0 are initialized with literals to value %1">,
- InGroup<DiagGroup<"unique-enum">>;
-def note_identical_enum_values : Note<
- "initialize the last element with the previous element to silence "
- "this warning">;
-
// Constant expressions
def err_expr_not_ice : Error<
"expression is not an %select{integer|integral}0 constant expression">;
@@ -102,7 +95,7 @@ def err_variably_modified_new_type : Error<
// C99 Designated Initializers
def ext_designated_init : Extension<
- "designated initializers are a C99 feature">;
+ "designated initializers are a C99 feature">, InGroup<C99>;
def err_array_designator_negative : Error<
"array designator value '%0' is negative">;
def err_array_designator_empty_range : Error<
@@ -410,12 +403,10 @@ def err_statically_allocated_object : Error<
"interface type cannot be statically allocated">;
def err_object_cannot_be_passed_returned_by_value : Error<
"interface type %1 cannot be %select{returned|passed}0 by value"
- "; did you forget * in %1">;
+ "; did you forget * in %1?">;
def err_parameters_retval_cannot_have_fp16_type : Error<
"%select{parameters|function return value}0 cannot have __fp16 type; did you forget * ?">;
def warn_enum_value_overflow : Warning<"overflow in enumeration value">;
-def warn_pragma_options_align_unsupported_option : Warning<
- "unsupported alignment option in '#pragma options align'">;
def warn_pragma_options_align_reset_failed : Warning<
"#pragma options align=reset failed: %0">;
def err_pragma_options_align_mac68k_target_unsupported : Error<
@@ -521,7 +512,8 @@ def warn_conflicting_overriding_ret_types : Warning<
def warn_conflicting_ret_types : Warning<
"conflicting return type in "
- "implementation of %0%diff{: $ vs $|}1,2">;
+ "implementation of %0%diff{: $ vs $|}1,2">,
+ InGroup<MismatchedReturnTypes>;
def warn_conflicting_overriding_ret_type_modifiers : Warning<
"conflicting distributed object modifiers on return type "
@@ -550,7 +542,9 @@ def warn_conflicting_overriding_param_types : Warning<
def warn_conflicting_param_types : Warning<
"conflicting parameter types in "
- "implementation of %0%diff{: $ vs $|}1,2">;
+ "implementation of %0%diff{: $ vs $|}1,2">,
+ InGroup<MismatchedParameterTypes>;
+
def warn_conflicting_param_modifiers : Warning<
"conflicting distributed object modifiers on parameter type "
"in implementation of %0">,
@@ -595,6 +589,8 @@ def warn_accessor_property_type_mismatch : Warning<
"type of property %0 does not match type of accessor %1">;
def not_conv_function_declared_at : Note<"type conversion function declared here">;
def note_method_declared_at : Note<"method %0 declared here">;
+def note_property_attribute : Note<"property %0 is declared "
+ "%select{deprecated|unavailable}1 here">;
def err_setter_type_void : Error<"type of setter must be void">;
def err_duplicate_method_decl : Error<"duplicate declaration of method %0">;
def warn_duplicate_method_decl :
@@ -700,7 +696,7 @@ def error_bad_property_context : Error<
"property implementation must be in a class or category implementation">;
def error_missing_property_ivar_decl : Error<
"synthesized property %0 must either be named the same as a compatible"
- " ivar or must explicitly name an ivar">;
+ " instance variable or must explicitly name an instance variable">;
def error_synthesize_weak_non_arc_or_gc : Error<
"@synthesize of 'weak' property is only allowed in ARC or GC mode">;
def err_arc_perform_selector_retains : Error<
@@ -712,38 +708,55 @@ def err_gc_weak_property_strong_type : Error<
"weak attribute declared on a __strong type property in GC mode">;
def warn_receiver_is_weak : Warning <
"weak %select{receiver|property|implicit property}0 may be "
- "unpredictably null in ARC mode">,
+ "unpredictably set to nil">,
InGroup<DiagGroup<"receiver-is-weak">>, DefaultIgnore;
+def note_arc_assign_to_strong : Note<
+ "assign the value to a strong variable to keep the object alive during use">;
+def warn_arc_repeated_use_of_weak : Warning <
+ "weak %select{variable|property|implicit property|instance variable}0 %1 is "
+ "accessed multiple times in this %select{function|method|block|lambda}2 "
+ "but may be unpredictably set to nil; assign to a strong variable to keep "
+ "the object alive">,
+ InGroup<ARCRepeatedUseOfWeak>, DefaultIgnore;
+def warn_implicitly_retains_self : Warning <
+ "block implicitly retains 'self'; explicitly mention 'self' to indicate "
+ "this is intended behavior">,
+ InGroup<DiagGroup<"implicit-retain-self">>, DefaultIgnore;
+def warn_arc_possible_repeated_use_of_weak : Warning <
+ "weak %select{variable|property|implicit property|instance variable}0 %1 may "
+ "be accessed multiple times in this %select{function|method|block|lambda}2 "
+ "and may be unpredictably set to nil; assign to a strong variable to keep "
+ "the object alive">,
+ InGroup<ARCRepeatedUseOfWeakMaybe>, DefaultIgnore;
+def note_arc_weak_also_accessed_here : Note<
+ "also accessed here">;
def err_incomplete_synthesized_property : Error<
"cannot synthesize property %0 with incomplete type %1">;
def error_property_ivar_type : Error<
- "type of property %0 (%1) does not match type of ivar %2 (%3)">;
+ "type of property %0 (%1) does not match type of instance variable %2 (%3)">;
def error_property_accessor_type : Error<
"type of property %0 (%1) does not match type of accessor %2 (%3)">;
def error_ivar_in_superclass_use : Error<
- "property %0 attempting to use ivar %1 declared in super class %2">;
+ "property %0 attempting to use instance variable %1 declared in super class %2">;
def error_weak_property : Error<
- "existing ivar %1 for __weak property %0 must be __weak">;
+ "existing instance variable %1 for __weak property %0 must be __weak">;
def error_strong_property : Error<
- "existing ivar %1 for strong property %0 may not be __weak">;
+ "existing instance variable %1 for strong property %0 may not be __weak">;
def error_dynamic_property_ivar_decl : Error<
- "dynamic property can not have ivar specification">;
+ "dynamic property can not have instance variable specification">;
def error_duplicate_ivar_use : Error<
- "synthesized properties %0 and %1 both claim ivar %2">;
+ "synthesized properties %0 and %1 both claim instance variable %2">;
def error_property_implemented : Error<"property %0 is already implemented">;
def warn_objc_property_attr_mutually_exclusive : Warning<
"property attributes '%0' and '%1' are mutually exclusive">,
InGroup<ReadOnlySetterAttrs>, DefaultIgnore;
-def warn_objc_missing_super_dealloc : Warning<
- "method possibly missing a [super dealloc] call">,
+def warn_objc_missing_super_call : Warning<
+ "method possibly missing a [super %0] call">,
InGroup<ObjCMissingSuperCalls>;
def error_dealloc_bad_result_type : Error<
"dealloc return type must be correctly specified as 'void' under ARC, "
"instead of %0">;
-def warn_objc_missing_super_finalize : Warning<
- "method possibly missing a [super finalize] call">,
- InGroup<ObjCMissingSuperCalls>;
def warn_undeclared_selector : Warning<
"undeclared selector %0">, InGroup<UndeclaredSelector>, DefaultIgnore;
def warn_implicit_atomic_property : Warning<
@@ -768,7 +781,7 @@ def err_static_assert_expression_is_not_constant : Error<
def err_static_assert_failed : Error<"static_assert failed %0">;
def warn_inline_namespace_reopened_noninline : Warning<
- "inline namespace cannot be re-opened as a non-inline namespace">;
+ "inline namespace cannot be reopened as a non-inline namespace">;
def err_inline_namespace_mismatch : Error<
"%select{|non-}0inline namespace "
"cannot be reopened as %select{non-|}0inline">;
@@ -792,10 +805,11 @@ def warn_cxx98_compat_friend_is_member : Warning<
"with C++98">, InGroup<CXX98Compat>, DefaultIgnore;
def ext_unelaborated_friend_type : ExtWarn<
"unelaborated friend declaration is a C++11 extension; specify "
- "'%select{struct|union|class|enum}0' to befriend %1">, InGroup<CXX11>;
+ "'%select{struct|interface|union|class|enum}0' to befriend %1">,
+ InGroup<CXX11>;
def warn_cxx98_compat_unelaborated_friend_type : Warning<
- "befriending %1 without '%select{struct|union|class|enum}0' keyword is "
- "incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore;
+ "befriending %1 without '%select{struct|interface|union|class|enum}0' "
+ "keyword is incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore;
def err_qualified_friend_not_found : Error<
"no function named %0 with type %1 was found in the specified scope">;
def err_introducing_special_friend : Error<
@@ -806,16 +820,26 @@ def err_tagless_friend_type_template : Error<
def err_no_matching_local_friend : Error<
"no matching function found in local scope">;
def err_no_matching_local_friend_suggest : Error<
- "no matching function %0 found in local scope; did you mean %2">;
+ "no matching function %0 found in local scope; did you mean %2?">;
def err_partial_specialization_friend : Error<
"partial specialization cannot be declared as a friend">;
def err_qualified_friend_def : Error<
"friend function definition cannot be qualified with '%0'">;
def err_friend_def_in_local_class : Error<
"friend function cannot be defined in a local class">;
+def err_friend_not_first_in_declaration : Error<
+ "'friend' must appear first in a non-function declaration">;
+def err_invalid_member_in_interface : Error<
+ "%select{data member |non-public member function |static member function |"
+ "user-declared constructor|user-declared destructor|operator |"
+ "nested class }0%1 is not permitted within an interface type">;
+def err_invalid_base_in_interface : Error<
+ "interface type cannot inherit from "
+ "%select{'struct|non-public 'interface|'class}0 %1'">;
+
def err_abstract_type_in_decl : Error<
- "%select{return|parameter|variable|field|ivar}0 type %1 is an abstract class">;
+ "%select{return|parameter|variable|field|instance variable}0 type %1 is an abstract class">;
def err_allocation_of_abstract_type : Error<
"allocating an object of abstract class type %0">;
def err_throw_abstract_type : Error<
@@ -841,6 +865,12 @@ def note_pure_virtual_function : Note<
def err_deleted_decl_not_first : Error<
"deleted definition must be first declaration">;
+def err_deleted_override : Error<
+ "deleted function %0 cannot override a non-deleted function">;
+
+def err_non_deleted_override : Error<
+ "non-deleted function %0 cannot override a deleted function">;
+
def warn_weak_vtable : Warning<
"%0 has no out-of-line virtual method definitions; its vtable will be "
"emitted in every translation unit">,
@@ -1030,7 +1060,7 @@ def warn_call_to_pure_virtual_member_function_from_ctor_dtor : Warning<
"not available in the %select{constructor|destructor}1 of %2">;
def note_field_decl : Note<"member is declared here">;
-def note_ivar_decl : Note<"ivar is declared here">;
+def note_ivar_decl : Note<"instance variable is declared here">;
def note_bitfield_decl : Note<"bit-field is declared here">;
def note_previous_decl : Note<"%0 declared here">;
def note_member_synthesized_at : Note<
@@ -1113,8 +1143,8 @@ def err_constructor_redeclared : Error<"constructor cannot be redeclared">;
def err_constructor_byvalue_arg : Error<
"copy constructor must pass its first argument by reference">;
def warn_no_constructor_for_refconst : Warning<
- "%select{struct|union|class|enum}0 %1 does not declare any constructor to "
- "initialize its non-modifiable members">;
+ "%select{struct|interface|union|class|enum}0 %1 does not declare any "
+ "constructor to initialize its non-modifiable members">;
def note_refconst_member_not_initialized : Note<
"%select{const|reference}0 member %1 will never be initialized">;
def ext_ms_explicit_constructor_call : ExtWarn<
@@ -1214,11 +1244,18 @@ def err_init_reference_member_uninitialized : Error<
"reference member of type %0 uninitialized">;
def note_uninit_reference_member : Note<
"uninitialized reference member is here">;
-def warn_field_is_uninit : Warning<"field is uninitialized when used here">,
+def warn_field_is_uninit : Warning<"field %0 is uninitialized when used here">,
+ InGroup<Uninitialized>;
+def warn_reference_field_is_uninit : Warning<
+ "reference %0 is not yet bound to a value when used here">,
InGroup<Uninitialized>;
def warn_uninit_self_reference_in_init : Warning<
"variable %0 is uninitialized when used within its own initialization">,
InGroup<Uninitialized>;
+def warn_uninit_self_reference_in_reference_init : Warning<
+ "reference %0 is not yet bound to a value when used within its own"
+ " initialization">,
+ InGroup<Uninitialized>;
def warn_uninit_var : Warning<
"variable %0 is uninitialized when %select{used here|captured by block}1">,
InGroup<Uninitialized>, DefaultIgnore;
@@ -1300,9 +1337,10 @@ def err_new_array_of_auto : Error<
"cannot allocate array of 'auto'">;
def err_auto_not_allowed : Error<
"'auto' not allowed %select{in function prototype|in non-static struct member"
- "|in non-static union member|in non-static class member|in exception declaration"
- "|in template parameter|in block literal|in template argument"
- "|in typedef|in type alias|in function return type|here}0">;
+ "|in non-static union member|in non-static class member|in interface member"
+ "|in exception declaration|in template parameter|in block literal"
+ "|in template argument|in typedef|in type alias|in function return type"
+ "|here}0">;
def err_auto_var_requires_init : Error<
"declaration of variable %0 with type %1 requires an initializer">;
def err_auto_new_requires_ctor_arg : Error<
@@ -1346,6 +1384,8 @@ def err_function_marked_override_not_overriding : Error<
"%0 marked 'override' but does not override any member functions">;
def err_class_marked_final_used_as_base : Error<
"base %0 is marked 'final'">;
+def warn_abstract_final_class : Warning<
+ "abstract class is marked 'final'">, InGroup<AbstractFinalClass>;
// C++11 attributes
def err_repeat_attribute : Error<"'%0' attribute cannot be repeated">;
@@ -1408,7 +1448,17 @@ def err_for_range_member_begin_end_mismatch : Error<
"range type %0 has '%select{begin|end}1' member but no '%select{end|begin}1' member">;
def err_for_range_begin_end_types_differ : Error<
"'begin' and 'end' must return the same type (got %0 and %1)">;
-def note_for_range_type : Note<"range has type %0">;
+def note_in_for_range: Note<
+ "when looking up '%select{begin|end}0' function for range expression "
+ "of type %1">;
+def err_for_range_invalid: Error<
+ "invalid range expression of type %0; no viable '%select{begin|end}1' "
+ "function available">;
+def err_for_range_dereference : Error<
+ "invalid range expression of type %0; did you mean to dereference it "
+ "with '*'?">;
+def note_for_range_invalid_iterator : Note <
+ "in implicit call to 'operator%select{!=|*|++}0' for iterator of type %1">;
def note_for_range_begin_end : Note<
"selected '%select{begin|end}0' %select{function|template }1%2 with iterator type %3">;
@@ -1420,7 +1470,7 @@ def err_invalid_constexpr : Error<
"%select{function parameter|typedef|non-static data member}0 "
"cannot be constexpr">;
def err_constexpr_tag : Error<
- "%select{class|struct|union|enum}0 cannot be marked constexpr">;
+ "%select{class|struct|interface|union|enum}0 cannot be marked constexpr">;
def err_constexpr_dtor : Error<"destructor cannot be marked constexpr">;
def err_constexpr_no_declarators : Error<
"constexpr can only be used in variable and function declarations">;
@@ -1438,11 +1488,12 @@ def err_constexpr_redecl_mismatch : Error<
def err_constexpr_virtual : Error<"virtual function cannot be constexpr">;
def err_constexpr_virtual_base : Error<
"constexpr %select{member function|constructor}0 not allowed in "
- "%select{class|struct}1 with virtual base %plural{1:class|:classes}2">;
+ "%select{struct|interface|class}1 with virtual base "
+ "%plural{1:class|:classes}2">;
def note_non_literal_incomplete : Note<
"incomplete type %0 is not a literal type">;
-def note_non_literal_virtual_base : Note<"%select{class|struct}0 with virtual "
- "base %plural{1:class|:classes}1 is not a literal type">;
+def note_non_literal_virtual_base : Note<"%select{struct|interface|class}0 "
+ "with virtual base %plural{1:class|:classes}1 is not a literal type">;
def note_constexpr_virtual_base_here : Note<"virtual base class declared here">;
def err_constexpr_non_literal_return : Error<
"constexpr function's return type %0 is not a literal type">;
@@ -1490,10 +1541,10 @@ def note_non_literal_user_provided_dtor : Note<
def note_non_literal_nontrivial_dtor : Note<
"%0 is not literal because it has a non-trivial destructor">;
def warn_private_extern : Warning<
- "Use of __private_extern__ on tentative definition has unexpected"
- " behaviour - use __attribute__((visibility(\"hidden\"))) on extern"
- " declaration or definition instead">,
- InGroup<PrivateExtern>, DefaultIgnore;
+ "use of __private_extern__ on a declaration may not produce external symbol "
+ "private to the linkage unit and is deprecated">, InGroup<PrivateExtern>;
+def note_private_extern : Note<
+ "use __attribute__((visibility(\"hidden\"))) attribute instead">;
// C++11 char16_t/char32_t
def warn_cxx98_compat_unicode_type : Warning<
@@ -1681,7 +1732,9 @@ def warn_attribute_invalid_on_stmt : Warning<
"attribute %0 cannot be specified on a statement">,
InGroup<IgnoredAttributes>;
def warn_declspec_attribute_ignored : Warning<
- "attribute %0 is ignored, place it after \"%select{class|struct|union|enum}1\" to apply attribute to type declaration">, InGroup<IgnoredAttributes>;
+ "attribute %0 is ignored, place it after "
+ "\"%select{class|struct|union|interface|enum}1\" to apply attribute to "
+ "type declaration">, InGroup<IgnoredAttributes>;
def warn_attribute_precede_definition : Warning<
"attribute declaration must precede definition">,
InGroup<IgnoredAttributes>;
@@ -1699,7 +1752,8 @@ def warn_nsobject_attribute : Warning<
"__attribute ((NSObject)) may be put on a typedef only, "
"attribute is ignored">, InGroup<NSobjectAttribute>;
def warn_attribute_weak_on_local : Warning<
- "__weak attribute cannot be specified on an automatic variable">,
+ "__weak attribute cannot be specified on an automatic variable when ARC "
+ "is not enabled">,
InGroup<IgnoredAttributes>;
def warn_weak_identifier_undeclared : Warning<
"weak identifier %0 never declared">;
@@ -1753,6 +1807,8 @@ def err_attribute_vecreturn_only_pod_record : Error<
def err_cconv_change : Error<
"function declared '%0' here was previously declared "
"%select{'%2'|without calling convention}1">;
+def warn_cconv_ignored : Warning<
+ "calling convention %0 ignored for this target">, InGroup<IgnoredAttributes>;
def err_cconv_knr : Error<
"function with no prototype cannot use %0 calling convention">;
def err_cconv_varargs : Error<
@@ -1840,14 +1896,6 @@ def warn_lock_exclusive_and_shared : Warning<
InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
def note_lock_exclusive_and_shared : Note<
"the other lock of mutex '%0' is here">;
-def warn_variable_requires_lock : Warning<
- "%select{reading|writing}2 variable '%0' requires locking "
- "%select{'%1'|'%1' exclusively}2">,
- InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
-def warn_var_deref_requires_lock : Warning<
- "%select{reading|writing}2 the value pointed to by '%0' requires locking "
- "%select{'%1'|'%1' exclusively}2">,
- InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
def warn_variable_requires_any_lock : Warning<
"%select{reading|writing}1 variable '%0' requires locking "
"%select{any mutex|any mutex exclusively}1">,
@@ -1856,9 +1904,6 @@ def warn_var_deref_requires_any_lock : Warning<
"%select{reading|writing}1 the value pointed to by '%0' requires locking "
"%select{any mutex|any mutex exclusively}1">,
InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
-def warn_fun_requires_lock : Warning<
- "calling function '%0' requires %select{shared|exclusive}2 lock on '%1'">,
- InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
def warn_fun_excludes_mutex : Warning<
"cannot call function '%0' while mutex '%1' is locked">,
InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
@@ -1866,6 +1911,32 @@ def warn_cannot_resolve_lock : Warning<
"cannot resolve lock expression">,
InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
+// Imprecise thread safety warnings
+def warn_variable_requires_lock : Warning<
+ "%select{reading|writing}2 variable '%0' requires locking "
+ "%select{'%1'|'%1' exclusively}2">,
+ InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
+def warn_var_deref_requires_lock : Warning<
+ "%select{reading|writing}2 the value pointed to by '%0' requires locking "
+ "%select{'%1'|'%1' exclusively}2">,
+ InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
+def warn_fun_requires_lock : Warning<
+ "calling function '%0' requires %select{shared|exclusive}2 lock on '%1'">,
+ InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
+
+// Precise thread safety warnings
+def warn_variable_requires_lock_precise : Warning<
+ "%select{reading|writing}2 variable '%0' requires locking "
+ "%select{'%1'|'%1' exclusively}2">,
+ InGroup<ThreadSafetyPrecise>, DefaultIgnore;
+def warn_var_deref_requires_lock_precise : Warning<
+ "%select{reading|writing}2 the value pointed to by '%0' requires locking "
+ "%select{'%1'|'%1' exclusively}2">,
+ InGroup<ThreadSafetyPrecise>, DefaultIgnore;
+def warn_fun_requires_lock_precise : Warning<
+ "calling function '%0' requires %select{shared|exclusive}2 lock on '%1'">,
+ InGroup<ThreadSafetyPrecise>, DefaultIgnore;
+def note_found_mutex_near_match : Note<"found near match '%0'">;
def warn_impcast_vector_scalar : Warning<
"implicit conversion turns vector to scalar: %0 to %1">,
@@ -1890,7 +1961,7 @@ def warn_impcast_integer_precision : Warning<
InGroup<DiagGroup<"conversion">>, DefaultIgnore;
def warn_impcast_integer_64_32 : Warning<
"implicit conversion loses integer precision: %0 to %1">,
- InGroup<DiagGroup<"shorten-64-to-32">>, DefaultIgnore;
+ InGroup<Shorten64To32>, DefaultIgnore;
def warn_impcast_integer_precision_constant : Warning<
"implicit conversion from %2 to %3 changes value from %0 to %1">,
InGroup<ConstantConversion>;
@@ -1905,7 +1976,7 @@ def warn_impcast_string_literal_to_bool : Warning<
InGroup<StringConversion>, DefaultIgnore;
def warn_impcast_different_enum_types : Warning<
"implicit conversion from enumeration type %0 to different enumeration type "
- "%1">, InGroup<DiagGroup<"conversion">>;
+ "%1">, InGroup<EnumConversion>;
def warn_impcast_bool_to_null_pointer : Warning<
"initialization of pointer of type %0 to null from a constant boolean "
"expression">, InGroup<BoolConversion>;
@@ -1915,6 +1986,9 @@ def warn_non_literal_null_pointer : Warning<
def warn_impcast_null_pointer_to_integer : Warning<
"implicit conversion of NULL constant to %0">,
InGroup<NullConversion>;
+def warn_impcast_floating_point_to_bool : Warning<
+ "implicit conversion turns floating-point number into bool: %0 to %1">,
+ InGroup<ImplicitConversionFloatingPointToBool>;
def warn_impcast_function_to_bool : Warning<
"address of function %q0 will always evaluate to 'true'">,
InGroup<BoolConversion>;
@@ -1927,6 +2001,10 @@ def warn_cast_align : Warning<
"cast from %0 to %1 increases required alignment from %2 to %3">,
InGroup<CastAlign>, DefaultIgnore;
+def warn_int_to_pointer_cast : Warning<
+ "cast to %1 from smaller integer type %0">,
+ InGroup<IntToPointerCast>;
+
def warn_attribute_ignored_for_field_of_type : Warning<
"%0 attribute ignored for field of type %1">,
InGroup<IgnoredAttributes>;
@@ -2008,7 +2086,7 @@ def warn_attribute_ibaction: Warning<
def err_iboutletcollection_type : Error<
"invalid type %0 as argument of iboutletcollection attribute">;
def warn_iboutlet_object_type : Warning<
- "%select{ivar|property}2 with %0 attribute must "
+ "%select{instance variable|property}2 with %0 attribute must "
"be an object type (invalid %1)">,
InGroup<DiagGroup<"invalid-iboutlet">>;
def err_attribute_overloadable_not_function : Error<
@@ -2028,6 +2106,12 @@ def warn_ns_attribute_wrong_parameter_type : Warning<
"%0 attribute only applies to %select{Objective-C object|pointer}1 "
"parameters">,
InGroup<IgnoredAttributes>;
+def warn_objc_requires_super_protocol : Warning<
+ "%0 attribute cannot be applied to %select{methods in protocols|dealloc}1">,
+ InGroup<DiagGroup<"requires-super-attribute">>;
+def note_protocol_decl : Note<
+ "protocol is declared here">;
+
def err_ns_bridged_not_interface : Error<
"parameter of 'ns_bridged' attribute does not name an Objective-C class">;
@@ -3058,6 +3142,9 @@ def note_sentinel_here : Note<
def warn_missing_prototype : Warning<
"no previous prototype for function %0">,
InGroup<DiagGroup<"missing-prototypes">>, DefaultIgnore;
+def warn_missing_variable_declarations : Warning<
+ "no previous extern declaration for non-static variable %0">,
+ InGroup<DiagGroup<"missing-variable-declarations">>, DefaultIgnore;
def err_redefinition : Error<"redefinition of %0">;
def err_definition_of_implicitly_declared_member : Error<
"definition of implicitly declared %select{default constructor|copy "
@@ -3144,7 +3231,7 @@ def err_non_thread_thread : Error<
def err_thread_non_thread : Error<
"thread-local declaration of %0 follows non-thread-local declaration">;
def err_redefinition_different_type : Error<
- "redefinition of %0 with a different type">;
+ "redefinition of %0 with a different type%diff{: $ vs $|}1,2">;
def err_redefinition_different_kind : Error<
"redefinition of %0 as different kind of symbol">;
def warn_forward_class_redefinition : Warning<
@@ -3159,8 +3246,8 @@ def err_tag_reference_conflict : Error<
"implicit declaration introduced by elaborated type conflicts with "
"%select{a declaration|a typedef|a type alias|a template}0 of the same name">;
def err_dependent_tag_decl : Error<
- "%select{declaration|definition}0 of %select{struct|union|class|enum}1 "
- "in a dependent scope">;
+ "%select{declaration|definition}0 of "
+ "%select{struct|interface|union|class|enum}1 in a dependent scope">;
def err_tag_definition_of_typedef : Error<
"definition of type %0 conflicts with %select{typedef|type alias}1 of the same name">;
def err_conflicting_types : Error<"conflicting types for %0">;
@@ -3168,15 +3255,16 @@ def err_nested_redefinition : Error<"nested redefinition of %0">;
def err_use_with_wrong_tag : Error<
"use of %0 with tag type that does not match previous declaration">;
def warn_struct_class_tag_mismatch : Warning<
- "%select{struct|class}0%select{| template}1 %2 was previously declared "
- "as a %select{class|struct}0%select{| template}1">,
+ "%select{struct|interface|class}0%select{| template}1 %2 was previously "
+ "declared as a %select{struct|interface|class}3%select{| template}1">,
InGroup<MismatchedTags>, DefaultIgnore;
def warn_struct_class_previous_tag_mismatch : Warning<
- "%2 defined as a %select{struct|class}0%select{| template}1 here but "
- "previously declared as a %select{class|struct}0%select{| template}1">,
+ "%2 defined as %select{a struct|an interface|a class}0%select{| template}1 "
+ "here but previously declared as "
+ "%select{a struct|an interface|a class}3%select{| template}1">,
InGroup<MismatchedTags>, DefaultIgnore;
def note_struct_class_suggestion : Note<
- "did you mean %select{struct|class}0 here?">;
+ "did you mean %select{struct|interface|class}0 here?">;
def ext_forward_ref_enum : Extension<
"ISO C forbids forward references to 'enum' types">;
def err_forward_ref_enum : Error<
@@ -3189,9 +3277,9 @@ def ext_forward_ref_enum_def : Extension<
def err_redefinition_of_enumerator : Error<"redefinition of enumerator %0">;
def err_duplicate_member : Error<"duplicate member %0">;
def err_misplaced_ivar : Error<
- "ivars may not be placed in %select{categories|class extension}0">;
+ "instance variables may not be placed in %select{categories|class extension}0">;
def warn_ivars_in_interface : Warning<
- "declaration of ivars in the interface is deprecated">,
+ "declaration of instance variables in the interface is deprecated">,
InGroup<DiagGroup<"objc-interface-ivars">>, DefaultIgnore;
def ext_enum_value_not_int : Extension<
"ISO C restricts enumerator values to range of 'int' (%0 is too "
@@ -3220,11 +3308,13 @@ def warn_array_new_too_large : Warning<"array is too large (%0 elements)">,
// -Wpadded, -Wpacked
def warn_padded_struct_field : Warning<
- "padding %select{struct|class}0 %1 with %2 %select{byte|bit}3%select{|s}4 "
- "to align %5">, InGroup<Padded>, DefaultIgnore;
+ "padding %select{struct|interface|class}0 %1 with %2 "
+ "%select{byte|bit}3%select{|s}4 to align %5">,
+ InGroup<Padded>, DefaultIgnore;
def warn_padded_struct_anon_field : Warning<
- "padding %select{struct|class}0 %1 with %2 %select{byte|bit}3%select{|s}4 "
- "to align anonymous bit-field">, InGroup<Padded>, DefaultIgnore;
+ "padding %select{struct|interface|class}0 %1 with %2 "
+ "%select{byte|bit}3%select{|s}4 to align anonymous bit-field">,
+ InGroup<Padded>, DefaultIgnore;
def warn_padded_struct_size : Warning<
"padding size of %0 with %1 %select{byte|bit}2%select{|s}3 "
"to alignment boundary">, InGroup<Padded>, DefaultIgnore;
@@ -3244,7 +3334,7 @@ def err_typecheck_invalid_restrict_not_pointer_noarg : Error<
def err_typecheck_invalid_restrict_invalid_pointee : Error<
"pointer to function type %0 may not be 'restrict' qualified">;
def ext_typecheck_zero_array_size : Extension<
- "zero size arrays are an extension">;
+ "zero size arrays are an extension">, InGroup<ZeroLengthArray>;
def err_typecheck_zero_array_size : Error<
"zero-length arrays are not permitted in C++">;
def warn_typecheck_zero_static_array_size : Warning<
@@ -3354,7 +3444,7 @@ def warn_anon_bitfield_width_exceeds_type_size : Warning<
def warn_missing_braces : Warning<
"suggest braces around initialization of subobject">,
- InGroup<DiagGroup<"missing-braces">>, DefaultIgnore;
+ InGroup<MissingBraces>, DefaultIgnore;
def err_missing_braces : Error<
"cannot omit braces around initialization of subobject when using direct "
"list-initialization">;
@@ -3472,14 +3562,16 @@ def ext_flexible_array_in_array : Extension<
def err_flexible_array_init : Error<
"initialization of flexible array member is not allowed">;
def ext_flexible_array_empty_aggregate_ms : Extension<
- "flexible array member %0 in otherwise empty %select{struct|class}1 "
- "is a Microsoft extension">, InGroup<Microsoft>;
+ "flexible array member %0 in otherwise empty "
+ "%select{struct|interface|union|class|enum}1 is a Microsoft extension">,
+ InGroup<Microsoft>;
def ext_flexible_array_union_ms : Extension<
"flexible array member %0 in a union is a Microsoft extension">,
InGroup<Microsoft>;
def ext_flexible_array_empty_aggregate_gnu : Extension<
- "flexible array member %0 in otherwise empty %select{struct|class}1 "
- "is a GNU extension">, InGroup<GNU>;
+ "flexible array member %0 in otherwise empty "
+ "%select{struct|interface|union|class|enum}1 is a GNU extension">,
+ InGroup<GNU>;
def ext_flexible_array_union_gnu : Extension<
"flexible array member %0 in a union is a GNU extension">, InGroup<GNU>;
@@ -3497,7 +3589,7 @@ def err_arc_weak_unavailable_assign : Error<
"assignment of a weak-unavailable object to a __weak object">;
def err_arc_weak_unavailable_property : Error<
"synthesis of a weak-unavailable property is disallowed "
- "because it requires synthesis of an ivar of the __weak object">;
+ "because it requires synthesis of an instance variable of the __weak object">;
def err_arc_convesion_of_weak_unavailable : Error<
"%select{implicit conversion|cast}0 of weak-unavailable object of type %1 to"
" a __weak object of type %2">;
@@ -3527,6 +3619,9 @@ def err_arc_illegal_selector : Error<
"ARC forbids use of %0 in a @selector">;
def err_arc_illegal_method_def : Error<
"ARC forbids implementation of %0">;
+def warn_arc_strong_pointer_objc_pointer : Warning<
+ "method parameter of type %0 with no explicit ownership">,
+ InGroup<DiagGroup<"explicit-ownership-type">>, DefaultIgnore;
} // end "ARC Restrictions" category
@@ -3549,11 +3644,6 @@ def err_typecheck_arc_assign_self_class_method : Error<
def err_typecheck_arr_assign_enumeration : Error<
"fast enumeration variables can't be modified in ARC by default; "
"declare the variable __strong to allow this">;
-def warn_arc_non_pod_class_with_object_member : Warning<
- "%0 cannot be shared between ARC and non-ARC "
- "code; add a copy constructor, a copy assignment operator, and a destructor "
- "to make it ABI-compatible">, InGroup<AutomaticReferenceCountingABI>,
- DefaultIgnore;
def warn_arc_retained_assign : Warning<
"assigning retained object to %select{weak|unsafe_unretained}0 "
"%select{property|variable}1"
@@ -3563,19 +3653,10 @@ def warn_arc_retained_property_assign : Warning<
"assigning retained object to unsafe property"
"; object will be released after assignment">,
InGroup<ARCUnsafeRetainedAssign>;
-def warn_arc_trivial_member_function_with_object_member : Warning<
- "%0 cannot be shared between ARC and non-ARC "
- "code; add a non-trivial %select{copy constructor|copy assignment operator|"
- "destructor}1 to make it ABI-compatible">,
- InGroup<AutomaticReferenceCountingABI>, DefaultIgnore;
def err_arc_new_array_without_ownership : Error<
"'new' cannot allocate an array of %0 with no explicit ownership">;
-def warn_err_new_delete_object_array : Warning<
- "%select{allocating|destroying}0 an array of %1; this array must not "
- "%select{be deleted in|have been allocated from}0 non-ARC code">,
- InGroup<AutomaticReferenceCountingABI>, DefaultIgnore;
def err_arc_autoreleasing_var : Error<
- "%select{__block variables|global variables|fields|ivars}0 cannot have "
+ "%select{__block variables|global variables|fields|instance variables}0 cannot have "
"__autoreleasing ownership">;
def err_arc_autoreleasing_capture : Error<
"cannot capture __autoreleasing variable in a "
@@ -3632,10 +3713,10 @@ def warn_arc_object_memaccess : Warning<
let CategoryName = "ARC and @properties" in {
def err_arc_strong_property_ownership : Error<
- "existing ivar %1 for strong property %0 may not be "
+ "existing instance variable %1 for strong property %0 may not be "
"%select{|__unsafe_unretained||__weak}2">;
def err_arc_assign_property_ownership : Error<
- "existing ivar %1 for property %0 with %select{unsafe_unretained| assign}2 "
+ "existing instance variable %1 for property %0 with %select{unsafe_unretained| assign}2 "
"attribute must be __unsafe_unretained">;
def err_arc_inconsistent_property_ownership : Error<
"%select{|unsafe_unretained|strong|weak}1 property %0 may not also be "
@@ -3766,16 +3847,14 @@ def warn_precedence_bitwise_rel : Warning<
InGroup<Parentheses>;
def note_precedence_bitwise_first : Note<
"place parentheses around the %0 expression to evaluate it first">;
-def note_precedence_bitwise_silence : Note<
- "place parentheses around the %0 expression to silence this warning">;
+def note_precedence_silence : Note<
+ "place parentheses around the '%0' expression to silence this warning">;
def warn_precedence_conditional : Warning<
"operator '?:' has lower precedence than '%0'; '%0' will be evaluated first">,
InGroup<Parentheses>;
def note_precedence_conditional_first : Note<
"place parentheses around the '?:' expression to evaluate it first">;
-def note_precedence_conditional_silence : Note<
- "place parentheses around the '%0' expression to silence this warning">;
def warn_logical_instead_of_bitwise : Warning<
"use of logical '%0' with constant operand">,
@@ -3787,13 +3866,13 @@ def note_logical_instead_of_bitwise_remove_constant : Note<
def warn_bitwise_and_in_bitwise_or : Warning<
"'&' within '|'">, InGroup<BitwiseOpParentheses>;
-def note_bitwise_and_in_bitwise_or_silence : Note<
- "place parentheses around the '&' expression to silence this warning">;
def warn_logical_and_in_logical_or : Warning<
"'&&' within '||'">, InGroup<LogicalOpParentheses>;
-def note_logical_and_in_logical_or_silence : Note<
- "place parentheses around the '&&' expression to silence this warning">;
+
+def warn_addition_in_bitshift : Warning<
+ "operator '%0' has lower precedence than '%1'; "
+ "'%1' will be evaluated first">, InGroup<ShiftOpParentheses>;
def warn_self_assignment : Warning<
"explicitly assigning a variable of type %0 to itself">,
@@ -3896,6 +3975,8 @@ def ext_out_of_line_declaration : ExtWarn<
"out-of-line declaration of a member must be a definition">,
InGroup<OutOfLineDeclaration>, DefaultError;
def warn_member_extra_qualification : Warning<
+ "extra qualification on member %0">, InGroup<Microsoft>;
+def err_member_extra_qualification : Error<
"extra qualification on member %0">;
def err_member_qualification : Error<
"non-friend class member %0 cannot have a qualified name">;
@@ -4013,7 +4094,8 @@ def ext_typecheck_comparison_of_pointer_integer : ExtWarn<
def err_typecheck_comparison_of_pointer_integer : Error<
"comparison between pointer and integer (%0 and %1)">;
def ext_typecheck_comparison_of_distinct_pointers : ExtWarn<
- "comparison of distinct pointer types%diff{ ($ and $)|}0,1">;
+ "comparison of distinct pointer types%diff{ ($ and $)|}0,1">,
+ InGroup<CompareDistinctPointerType>;
def ext_typecheck_cond_incompatible_operands : ExtWarn<
"incompatible operand types (%0 and %1)">;
def err_cond_voidptr_arc : Error <
@@ -4023,7 +4105,7 @@ def err_typecheck_comparison_of_distinct_pointers : Error<
"comparison of distinct pointer types%diff{ ($ and $)|}0,1">;
def ext_typecheck_comparison_of_distinct_pointers_nonstandard : ExtWarn<
"comparison of distinct pointer types (%0 and %1) uses non-standard "
- "composite pointer type %2">;
+ "composite pointer type %2">, InGroup<CompareDistinctPointerType>;
def err_typecheck_assign_const : Error<"read-only variable is not assignable">;
def err_stmtexpr_file_scope : Error<
"statement expression not allowed at file scope">;
@@ -4033,6 +4115,9 @@ def warn_mixed_sign_comparison : Warning<
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 constant %0 with expression of type %1 is always "
+ "%select{false|true}2">, InGroup<TautologicalOutOfRangeCompare>;
def warn_runsigned_always_true_comparison : Warning<
"comparison of %0 unsigned%select{| enum}2 expression is always %1">,
InGroup<TautologicalCompare>;
@@ -4166,7 +4251,7 @@ def err_nogetter_property_incdec : Error<
def error_no_subobject_property_setting : Error<
"expression is not assignable">;
def err_qualified_objc_access : Error<
- "%select{property|ivar}0 access cannot be qualified with '%1'">;
+ "%select{property|instance variable}0 access cannot be qualified with '%1'">;
def ext_freestanding_complex : Extension<
"complex numbers are an extension in a freestanding C99 implementation">;
@@ -4562,7 +4647,7 @@ def err_invalid_declarator_global_scope : Error<
def err_invalid_declarator_in_function : Error<
"definition or redeclaration of %0 not allowed inside a function">;
def err_not_tag_in_scope : Error<
- "no %select{struct|union|class|enum}0 named %1 in %2">;
+ "no %select{struct|interface|union|class|enum}0 named %1 in %2">;
def err_no_typeid_with_fno_rtti : Error<
"cannot use typeid with -fno-rtti">;
@@ -4885,6 +4970,8 @@ def note_callee_decl : Note<
"%0 declared here">;
def note_defined_here : Note<"%0 defined here">;
+def err_builtin_fn_use : Error<"builtin functions must be directly called">;
+
def warn_call_wrong_number_of_arguments : Warning<
"too %select{few|many}0 arguments in call to %1">;
def err_atomic_builtin_must_be_pointer : Error<
@@ -4898,6 +4985,9 @@ def err_atomic_builtin_pointer_size : Error<
def err_atomic_op_needs_atomic : Error<
"first argument to atomic operation must be a pointer to _Atomic "
"type (%0 invalid)">;
+def err_atomic_op_needs_non_const_atomic : Error<
+ "first argument to atomic operation must be a pointer to non-const _Atomic "
+ "type (%0 invalid)">;
def err_atomic_op_needs_trivial_copy : Error<
"first argument to atomic operation must be a pointer to a trivially-copyable"
" type (%0 invalid)">;
@@ -4960,7 +5050,9 @@ def err_typecheck_cast_to_incomplete : Error<
"cast to incomplete type %0">;
def ext_typecheck_cast_nonscalar : Extension<
"C99 forbids casting nonscalar type %0 to the same type">;
-def ext_typecheck_cast_to_union : Extension<"C99 forbids casts to union type">;
+def ext_typecheck_cast_to_union : Extension<
+ "cast to union type is a GNU extension">,
+ InGroup<GNU>;
def err_typecheck_cast_to_union_no_type : Error<
"cast to union type from type %0 not present in union">;
def err_cast_pointer_from_non_pointer_int : Error<
@@ -4968,6 +5060,9 @@ def err_cast_pointer_from_non_pointer_int : Error<
def warn_cast_pointer_from_sel : Warning<
"cast of type %0 to %1 is deprecated; use sel_getName instead">,
InGroup<SelTypeCast>;
+def warn_bad_function_cast : Warning<
+ "cast from function call of type %0 to non-matching type %1">,
+ InGroup<BadFunctionCast>, DefaultIgnore;
def err_cast_pointer_to_non_pointer_int : Error<
"pointer cannot be cast to type %0">;
def err_typecheck_expect_scalar_operand : Error<
@@ -5045,19 +5140,21 @@ let CategoryName = "Inline Assembly Issue" in {
"unsupported inline asm: input with type "
"%diff{$ matching output with type $|}0,1">;
def err_asm_unknown_register_name : Error<"unknown register name '%0' in asm">;
- def warn_asm_label_on_auto_decl : Warning<
- "ignored asm label '%0' on automatic variable">;
+ def err_asm_empty : Error<"__asm used with no assembly instructions">;
def err_invalid_asm_cast_lvalue : Error<
"invalid use of a cast in a inline asm context requiring an l-value: "
"remove the cast or build with -fheinous-gnu-extensions">;
+ def err_inline_ms_asm_parsing : Error<"%0">;
+ def warn_asm_label_on_auto_decl : Warning<
+ "ignored asm label '%0' on automatic variable">;
def warn_invalid_asm_cast_lvalue : Warning<
- "invalid use of a cast in a inline asm context requiring an l-value: "
+ "invalid use of a cast in an inline asm context requiring an l-value: "
"accepted due to -fheinous-gnu-extensions, but clang may remove support "
"for this in the future">;
-
- def warn_unsupported_msasm : ExtWarn<
- "MS-style inline assembly is not supported">, InGroup<Microsoft>;
+ def warn_asm_mismatched_size_modifier : Warning<
+ "the size being stored is truncated, use a modifier to specify the size">,
+ InGroup<ASMOperandWidths>;
}
let CategoryName = "Semantic Issue" in {
@@ -5122,7 +5219,7 @@ def err_in_class_initializer_references_def_ctor : Error<
def ext_in_class_initializer_non_constant : Extension<
"in-class initializer for static data member is not a constant expression; "
- "folding it to a constant is a GNU extension">;
+ "folding it to a constant is a GNU extension">, InGroup<GNU>;
// C++ anonymous unions and GNU anonymous structs/unions
def ext_anonymous_union : Extension<
@@ -5178,6 +5275,8 @@ def err_static_data_member_not_allowed_in_local_class : Error<
def err_base_clause_on_union : Error<"unions cannot have base classes">;
def err_base_must_be_class : Error<"base specifier must name a class">;
def err_union_as_base_class : Error<"unions cannot be base classes">;
+def err_circular_inheritance : Error<
+ "circular inheritance between %0 and %1">;
def err_incomplete_base_class : Error<"base class has incomplete type">;
def err_duplicate_base_class : Error<
"base class %0 specified more than once as a direct base class">;
@@ -5340,6 +5439,10 @@ def err_out_of_line_default_deletes : Error<
"defaulting this %select{default constructor|copy constructor|move "
"constructor|copy assignment operator|move assignment operator|destructor}0 "
"would delete it after its first declaration">;
+def ext_implicit_exception_spec_mismatch : ExtWarn<
+ "function previously declared with an %select{explicit|implicit}0 exception "
+ "specification redeclared with an %select{implicit|explicit}0 exception "
+ "specification">, InGroup<DiagGroup<"implicit-exception-spec-mismatch">>;
def warn_ptr_arith_precedes_bounds : Warning<
"the pointer decremented by %0 refers before the beginning of the array">,
@@ -5373,6 +5476,10 @@ def warn_scanf_nonzero_width : Warning<
def warn_printf_conversion_argument_type_mismatch : Warning<
"format specifies type %0 but the argument has type %1">,
InGroup<Format>;
+def warn_format_argument_needs_cast : Warning<
+ "values of type '%0' should not be used as format arguments; add an explicit "
+ "cast to %1 instead">,
+ InGroup<Format>;
def warn_printf_positional_arg_exceeds_data_args : Warning <
"data argument position '%0' exceeds the number of data arguments (%1)">,
InGroup<Format>;
@@ -5397,7 +5504,8 @@ def warn_format_string_is_wide_literal : Warning<
def warn_printf_format_string_contains_null_char : Warning<
"format string contains '\\0' within the string body">, InGroup<Format>;
def warn_printf_asterisk_missing_arg : Warning<
- "'%select{*|.*}0' specified field %select{width|precision}0 is missing a matching 'int' argument">;
+ "'%select{*|.*}0' specified field %select{width|precision}0 is missing a matching 'int' argument">,
+ InGroup<Format>;
def warn_printf_asterisk_wrong_type : Warning<
"field %select{width|precision}0 should have type %1, but argument has type %2">,
InGroup<Format>;
@@ -5425,6 +5533,7 @@ def warn_scanf_scanlist_incomplete : Warning<
"no closing ']' for '%%[' in scanf format string">,
InGroup<Format>;
def note_format_string_defined : Note<"format string is defined here">;
+def note_format_fix_specifier : Note<"did you mean to use '%0'?">;
def note_printf_c_str: Note<"did you mean to call the %0 method?">;
def warn_null_arg : Warning<
@@ -5588,7 +5697,7 @@ def warn_unannotated_fallthrough_per_function : Warning<
"unannotated fall-through between switch labels in partly-annotated "
"function">, InGroup<ImplicitFallthroughPerFunction>, DefaultIgnore;
def note_insert_fallthrough_fixit : Note<
- "insert '[[clang::fallthrough]];' to silence this warning">;
+ "insert '%0;' to silence this warning">;
def note_insert_break_fixit : Note<
"insert 'break;' to avoid fall-through">;
def err_fallthrough_attr_wrong_target : Error<
@@ -5824,7 +5933,7 @@ def err_typecheck_member_reference_ivar_suggest : Error<
def err_property_not_found_suggest : Error<
"property %0 not found on object of type %1; did you mean %2?">;
def err_ivar_access_using_property_syntax_suggest : Error<
- "property %0 not found on object of type %1; did you mean to access ivar %2?">;
+ "property %0 not found on object of type %1; did you mean to access instance variable %2?">;
def err_property_found_suggest : Error<
"property %0 found on object of type %1; did you mean to access "
"it with the \".\" operator?">;
@@ -5911,7 +6020,7 @@ def err_module_private_local : Error<
"%select{local variable|parameter|typedef}0 %1 cannot be declared "
"__module_private__">;
def err_module_private_local_class : Error<
- "local %select{struct|union|class|enum}0 cannot be declared "
+ "local %select{struct|interface|union|class|enum}0 cannot be declared "
"__module_private__">;
def err_module_private_definition : Error<
"definition of %0 must be imported before it is required">;
diff --git a/include/clang/Basic/DiagnosticSerializationKinds.td b/include/clang/Basic/DiagnosticSerializationKinds.td
index a440e806d735..e9df09d114db 100644
--- a/include/clang/Basic/DiagnosticSerializationKinds.td
+++ b/include/clang/Basic/DiagnosticSerializationKinds.td
@@ -25,9 +25,13 @@ def err_fe_pch_file_modified : Error<
def err_fe_pch_file_overridden : Error<
"file '%0' from the precompiled header has been overridden">;
-def warn_pch_target_triple : Error<
- "PCH file was compiled for the target '%0' but the current translation "
- "unit is being compiled for target '%1'">;
+def err_pch_targetopt_mismatch : Error<
+ "PCH file was compiled for the %0 '%1' but the current translation "
+ "unit is being compiled for target '%2'">;
+def err_pch_targetopt_feature_mismatch : Error<
+ "%select{AST file|current translation unit}0 was compiled with the target "
+ "feature'%1' but the %select{current translation unit is|AST file was}0 "
+ "not">;
def err_pch_langopt_mismatch : Error<"%0 was %select{disabled|enabled}1 in "
"PCH file but is currently %select{disabled|enabled}2">;
def err_pch_langopt_value_mismatch : Error<
@@ -41,21 +45,24 @@ def warn_pch_different_branch : Error<
"PCH file built from a different branch (%0) than the compiler (%1)">;
def err_pch_with_compiler_errors : Error<
"PCH file contains compiler errors">;
-def warn_cmdline_conflicting_macro_def : Error<
- "definition of the macro '%0' conflicts with the definition used to "
- "build the precompiled header">;
-def note_pch_macro_defined_as : Note<
- "definition of macro '%0' in the precompiled header">;
-def warn_cmdline_missing_macro_defs : Warning<
- "macro definitions used to build the precompiled header are missing">;
-def note_using_macro_def_from_pch : Note<
- "using this macro definition from precompiled header">;
-def warn_macro_name_used_in_pch : Error<
- "definition of macro %0 conflicts with an identifier used in the "
- "precompiled header">;
-def warn_pch_compiler_options_mismatch : Error<
- "compiler options used when building the precompiled header differ from "
- "the options used when using the precompiled header">;
+
+
+def err_pch_macro_def_undef : Error<
+ "macro '%0' was %select{defined|undef'd}1 in the precompiled header but "
+ "%select{undef'd|defined}1 on the command line">;
+def err_pch_macro_def_conflict : Error<
+ "definition of macro '%0' differs between the precompiled header ('%1') "
+ "and the command line ('%2')">;
+def err_pch_include_opt_missing : Error<
+ "precompiled header depends on '%select{-include|-imacros}0 %1' option "
+ "that is missing from the command line">;
+def err_pch_include_opt_conflict : Error<
+ "precompiled header option '%select{-include|-imacros}0 %1' conflicts with "
+ "corresponding option '%select{-include|-imacros}0 %2' on command line">;
+def err_pch_undef : Error<
+ "%select{command line contains|precompiled header was built with}0 "
+ "'-undef' but %select{precompiled header was not built with it|"
+ "it is not present on the command line}0">;
def err_not_a_pch_file : Error<
"'%0' does not appear to be a precompiled header file">, DefaultFatal;
diff --git a/include/clang/Basic/FileManager.h b/include/clang/Basic/FileManager.h
index b00f2b782709..b2f578da7b49 100644
--- a/include/clang/Basic/FileManager.h
+++ b/include/clang/Basic/FileManager.h
@@ -103,6 +103,10 @@ public:
bool operator<(const FileEntry &RHS) const {
return Device < RHS.Device || (Device == RHS.Device && Inode < RHS.Inode);
}
+
+ /// \brief Check whether the file is a named pipe (and thus can't be opened by
+ /// the native FileManager methods).
+ bool isNamedPipe() const;
};
/// \brief Implements support for file system lookup, file system caching,
diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h
index dc6acdaa91ae..76242ec0a56d 100644
--- a/include/clang/Basic/IdentifierTable.h
+++ b/include/clang/Basic/IdentifierTable.h
@@ -21,7 +21,6 @@
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
#include <cassert>
#include <string>
@@ -54,6 +53,7 @@ class IdentifierInfo {
// are for builtins.
unsigned ObjCOrBuiltinID :11;
bool HasMacro : 1; // True if there is a #define for this.
+ bool HadMacro : 1; // True if there was a #define for this.
bool IsExtension : 1; // True if identifier is a lang extension.
bool IsCXX11CompatKeyword : 1; // True if identifier is a keyword in C++11.
bool IsPoisoned : 1; // True if identifier is poisoned.
@@ -70,13 +70,13 @@ class IdentifierInfo {
// stored externally.
bool IsModulesImport : 1; // True if this is the 'import' contextual
// keyword.
- // 1 bit left in 32-bit word.
-
+ // 32-bit word is filled.
+
void *FETokenInfo; // Managed by the language front-end.
llvm::StringMapEntry<IdentifierInfo*> *Entry;
- IdentifierInfo(const IdentifierInfo&); // NONCOPYABLE.
- void operator=(const IdentifierInfo&); // NONASSIGNABLE.
+ IdentifierInfo(const IdentifierInfo&) LLVM_DELETED_FUNCTION;
+ void operator=(const IdentifierInfo&) LLVM_DELETED_FUNCTION;
friend class IdentifierTable;
@@ -133,10 +133,21 @@ public:
if (HasMacro == Val) return;
HasMacro = Val;
- if (Val)
+ if (Val) {
NeedsHandleIdentifier = 1;
- else
+ HadMacro = true;
+ } else {
RecomputeNeedsHandleIdentifier();
+ }
+ }
+ /// \brief Returns true if this identifier was \#defined to some value at any
+ /// moment. In this case there should be an entry for the identifier in the
+ /// macro history table in Preprocessor.
+ bool hadMacroDefinition() const {
+ return HadMacro;
+ }
+ void setHadMacroDefinition(bool Val) {
+ HadMacro = Val;
}
/// getTokenID - If this is a source-language token (e.g. 'for'), this API
@@ -346,8 +357,8 @@ public:
/// actual functionality.
class IdentifierIterator {
private:
- IdentifierIterator(const IdentifierIterator&); // Do not implement
- IdentifierIterator &operator=(const IdentifierIterator&); // Do not implement
+ IdentifierIterator(const IdentifierIterator &) LLVM_DELETED_FUNCTION;
+ void operator=(const IdentifierIterator &) LLVM_DELETED_FUNCTION;
protected:
IdentifierIterator() { }
@@ -695,8 +706,8 @@ public:
/// multi-keyword caching.
class SelectorTable {
void *Impl; // Actually a SelectorTableImpl
- SelectorTable(const SelectorTable&); // DISABLED: DO NOT IMPLEMENT
- void operator=(const SelectorTable&); // DISABLED: DO NOT IMPLEMENT
+ SelectorTable(const SelectorTable &) LLVM_DELETED_FUNCTION;
+ void operator=(const SelectorTable &) LLVM_DELETED_FUNCTION;
public:
SelectorTable();
~SelectorTable();
diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def
index fab17a2fe56e..dbc08c7dca1f 100644
--- a/include/clang/Basic/LangOptions.def
+++ b/include/clang/Basic/LangOptions.def
@@ -48,15 +48,19 @@ LANGOPT(MicrosoftMode , 1, 0, "Microsoft compatibility mode")
LANGOPT(Borland , 1, 0, "Borland extensions")
LANGOPT(CPlusPlus , 1, 0, "C++")
LANGOPT(CPlusPlus0x , 1, 0, "C++0x")
+LANGOPT(CPlusPlus1y , 1, 0, "C++1y")
LANGOPT(ObjC1 , 1, 0, "Objective-C 1")
LANGOPT(ObjC2 , 1, 0, "Objective-C 2")
BENIGN_LANGOPT(ObjCDefaultSynthProperties , 1, 0,
"Objective-C auto-synthesized properties")
+BENIGN_LANGOPT(EncodeExtendedBlockSig , 1, 0,
+ "Encoding extended block type signature")
BENIGN_LANGOPT(ObjCInferRelatedResultType , 1, 1,
"Objective-C related result type inference")
LANGOPT(Trigraphs , 1, 0,"trigraphs")
-LANGOPT(BCPLComment , 1, 0, "BCPL-style '//' comments")
+LANGOPT(LineComment , 1, 0, "'//' comments")
LANGOPT(Bool , 1, 0, "bool, true, and false keywords")
+LANGOPT(WChar , 1, CPlusPlus, "wchar_t keyword")
BENIGN_LANGOPT(DollarIdents , 1, 1, "'$' in identifiers")
BENIGN_LANGOPT(AsmPreprocessor, 1, 0, "preprocessor in asm mode")
BENIGN_LANGOPT(GNUMode , 1, 1, "GNU extensions")
@@ -115,7 +119,6 @@ LANGOPT(CUDA , 1, 0, "CUDA")
LANGOPT(AssumeSaneOperatorNew , 1, 1, "implicit __attribute__((malloc)) for C++'s new operators")
BENIGN_LANGOPT(ElideConstructors , 1, 1, "C++ copy constructor elision")
-BENIGN_LANGOPT(CatchUndefined , 1, 0, "catching undefined behavior at run time")
BENIGN_LANGOPT(DumpRecordLayouts , 1, 0, "dumping the layout of IRgen'd records")
BENIGN_LANGOPT(DumpRecordLayoutsSimple , 1, 0, "dumping the layout of IRgen'd records in a simple form")
BENIGN_LANGOPT(DumpVTableLayouts , 1, 0, "dumping the layouts of emitted vtables")
@@ -125,8 +128,6 @@ BENIGN_LANGOPT(ParseUnknownAnytype, 1, 0, "__unknown_anytype")
BENIGN_LANGOPT(DebuggerSupport , 1, 0, "debugger support")
BENIGN_LANGOPT(DebuggerCastResultToId, 1, 0, "for 'po' in the debugger, cast the result to id if it is of unknown type")
BENIGN_LANGOPT(DebuggerObjCLiteral , 1, 0, "debugger Objective-C literals and subscripting support")
-BENIGN_LANGOPT(AddressSanitizer , 1, 0, "AddressSanitizer enabled")
-BENIGN_LANGOPT(ThreadSanitizer , 1, 0, "ThreadSanitizer enabled")
BENIGN_LANGOPT(SpellChecking , 1, 1, "spell-checking")
LANGOPT(SinglePrecisionConstants , 1, 0, "treating double-precision floating point constants as single precision constants")
@@ -135,7 +136,7 @@ LANGOPT(DefaultFPContract , 1, 0, "FP_CONTRACT")
LANGOPT(NoBitFieldTypeAlign , 1, 0, "bit-field type alignment")
LANGOPT(HexagonQdsp6Compat , 1, 0, "hexagon-qdsp6 backward compatibility")
LANGOPT(ObjCAutoRefCount , 1, 0, "Objective-C automated reference counting")
-LANGOPT(ObjCRuntimeHasWeak , 1, 0, "__weak support in the ARC runtime")
+LANGOPT(ObjCARCWeak , 1, 0, "__weak support in the ARC runtime")
LANGOPT(FakeAddressSpaceMap , 1, 0, "OpenCL fake address space map")
LANGOPT(MRTD , 1, 0, "-mrtd calling convention")
@@ -162,6 +163,17 @@ VALUE_LANGOPT(MSCVersion, 32, 0,
LANGOPT(ApplePragmaPack, 1, 0, "Apple gcc-compatible #pragma pack handling")
+BENIGN_LANGOPT(EmitMicrosoftInlineAsm , 1, 0,
+ "Enable emission of MS-style inline assembly.")
+
+
+BENIGN_LANGOPT(RetainCommentsFromSystemHeaders, 1, 0, "retain documentation comments from system headers in the AST")
+
+/// Runtime sanitizers.
+#define SANITIZER(NAME, ID) \
+BENIGN_LANGOPT(Sanitize##ID, 1, 0, NAME " sanitizer")
+#include "clang/Basic/Sanitizers.def"
+
#undef LANGOPT
#undef VALUE_LANGOPT
#undef BENIGN_LANGOPT
diff --git a/include/clang/Basic/Module.h b/include/clang/Basic/Module.h
index c8027f47028f..b6b088c1f701 100644
--- a/include/clang/Basic/Module.h
+++ b/include/clang/Basic/Module.h
@@ -21,6 +21,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/SetVector.h"
#include <string>
#include <utility>
#include <vector>
@@ -63,11 +64,21 @@ private:
/// \brief A mapping from the submodule name to the index into the
/// \c SubModules vector at which that submodule resides.
llvm::StringMap<unsigned> SubModuleIndex;
+
+ /// \brief The AST file if this is a top-level module which has a
+ /// corresponding serialized AST file, or null otherwise.
+ const FileEntry *ASTFile;
public:
/// \brief The headers that are part of this module.
llvm::SmallVector<const FileEntry *, 2> Headers;
+ /// \brief The headers that are explicitly excluded from this module.
+ llvm::SmallVector<const FileEntry *, 2> ExcludedHeaders;
+
+ /// \brief The top-level headers associated with this module.
+ llvm::SmallSetVector<const FileEntry *, 2> TopHeaders;
+
/// \brief The set of language features required to use this module.
///
/// If any of these features is not present, the \c IsAvailable bit
@@ -158,7 +169,7 @@ public:
/// \brief Construct a top-level module.
explicit Module(StringRef Name, SourceLocation DefinitionLoc,
bool IsFramework)
- : Name(Name), DefinitionLoc(DefinitionLoc), Parent(0), Umbrella(),
+ : Name(Name), DefinitionLoc(DefinitionLoc), Parent(0),Umbrella(),ASTFile(0),
IsAvailable(true), IsFromModuleFile(false), IsFramework(IsFramework),
IsExplicit(false), IsSystem(false),
InferSubmodules(false), InferExplicitSubmodules(false),
@@ -227,7 +238,18 @@ public:
StringRef getTopLevelModuleName() const {
return getTopLevelModule()->Name;
}
-
+
+ /// \brief The serialized AST file for this module, if one was created.
+ const FileEntry *getASTFile() const {
+ return getTopLevelModule()->ASTFile;
+ }
+
+ /// \brief Set the serialized AST file for the top-level module of this module.
+ void setASTFile(const FileEntry *File) {
+ assert((getASTFile() == 0 || getASTFile() == File) && "file path changed");
+ getTopLevelModule()->ASTFile = File;
+ }
+
/// \brief Retrieve the directory for which this module serves as the
/// umbrella.
const DirectoryEntry *getUmbrellaDir() const;
@@ -271,6 +293,10 @@ public:
submodule_iterator submodule_end() { return SubModules.end(); }
submodule_const_iterator submodule_end() const { return SubModules.end(); }
+ static StringRef getModuleInputBufferName() {
+ return "<module-includes>";
+ }
+
/// \brief Print the module map for this module to the given stream.
///
void print(llvm::raw_ostream &OS, unsigned Indent = 0) const;
diff --git a/include/clang/Basic/ObjCRuntime.h b/include/clang/Basic/ObjCRuntime.h
index b24fe7cd9159..d543b7671549 100644
--- a/include/clang/Basic/ObjCRuntime.h
+++ b/include/clang/Basic/ObjCRuntime.h
@@ -126,12 +126,25 @@ public:
return !isGNUFamily();
}
+ /// \brief Does this runtime allow ARC at all?
+ bool allowsARC() const {
+ switch (getKind()) {
+ case FragileMacOSX: return false;
+ case MacOSX: return true;
+ case iOS: return true;
+ case GCC: return false;
+ case GNUstep: return true;
+ case ObjFW: return true;
+ }
+ llvm_unreachable("bad kind");
+ }
+
/// \brief Does this runtime natively provide the ARC entrypoints?
///
/// ARC cannot be directly supported on a platform that does not provide
/// these entrypoints, although it may be supportable via a stub
/// library.
- bool hasARC() const {
+ bool hasNativeARC() const {
switch (getKind()) {
case FragileMacOSX: return false;
case MacOSX: return getVersion() >= VersionTuple(10, 7);
@@ -139,16 +152,35 @@ public:
case GCC: return false;
case GNUstep: return getVersion() >= VersionTuple(1, 6);
- case ObjFW: return false; // XXX: this will change soon
+ case ObjFW: return true;
}
llvm_unreachable("bad kind");
}
+ /// \brief Does this runtime supports optimized setter entrypoints?
+ bool hasOptimizedSetter() const {
+ switch (getKind()) {
+ case MacOSX:
+ return getVersion() >= VersionTuple(10, 8);
+ case iOS:
+ return (getVersion() >= VersionTuple(6));
+
+ default:
+ return false;
+ }
+ }
+
+ /// Does this runtime allow the use of __weak?
+ bool allowsWeak() const {
+ return hasNativeWeak();
+ }
+
/// \brief Does this runtime natively provide ARC-compliant 'weak'
/// entrypoints?
- bool hasWeak() const {
- // Right now, this is always equivalent to the ARC decision.
- return hasARC();
+ bool hasNativeWeak() const {
+ // Right now, this is always equivalent to whether the runtime
+ // natively supports ARC decision.
+ return hasNativeARC();
}
/// \brief Does this runtime directly support the subscripting methods?
@@ -158,7 +190,7 @@ public:
switch (getKind()) {
case FragileMacOSX: return false;
case MacOSX: return getVersion() >= VersionTuple(10, 8);
- case iOS: return false;
+ case iOS: return getVersion() >= VersionTuple(6);
// This is really a lie, because some implementations and versions
// of the runtime do not support ARC. Probably -fgnu-runtime
@@ -226,6 +258,7 @@ public:
}
llvm_unreachable("bad kind");
}
+
/// \brief Does this runtime use zero-cost exceptions?
bool hasUnwindExceptions() const {
switch (getKind()) {
diff --git a/include/clang/Basic/OnDiskHashTable.h b/include/clang/Basic/OnDiskHashTable.h
index 79273fcc798d..cc9ca9f2ec37 100644
--- a/include/clang/Basic/OnDiskHashTable.h
+++ b/include/clang/Basic/OnDiskHashTable.h
@@ -65,8 +65,7 @@ inline void Emit64(raw_ostream& Out, uint64_t V) {
inline void Pad(raw_ostream& Out, unsigned A) {
Offset off = (Offset) Out.tell();
- uint32_t n = ((uintptr_t)(off+A-1) & ~(uintptr_t)(A-1)) - off;
- for (; n ; --n)
+ for (uint32_t n = llvm::OffsetToAlignment(off, A); n; --n)
Emit8(Out, 0);
}
@@ -102,7 +101,7 @@ inline uint64_t ReadUnalignedLE64(const unsigned char *&Data) {
inline uint32_t ReadLE32(const unsigned char *&Data) {
// Hosts that directly support little-endian 32-bit loads can just
// use them. Big-endian hosts need a bswap.
- uint32_t V = *((uint32_t*)Data);
+ uint32_t V = *((const uint32_t*)Data);
if (llvm::sys::isBigEndianHost())
V = llvm::ByteSwap_32(V);
Data += 4;
diff --git a/include/clang/Basic/Sanitizers.def b/include/clang/Basic/Sanitizers.def
new file mode 100644
index 000000000000..085ca16eae1a
--- /dev/null
+++ b/include/clang/Basic/Sanitizers.def
@@ -0,0 +1,69 @@
+//===--- Sanitizers.def - Runtime sanitizer options -------------*- 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 options for specifying which runtime sanitizers to
+// enable. Users of this file must define the SANITIZER macro to make use of
+// this information. Users of this file can also define the SANITIZER_GROUP
+// macro to get information on options which refer to sets of sanitizers.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SANITIZER
+#error "Define SANITIZER prior to including this file!"
+#endif
+
+// SANITIZER(NAME, ID)
+
+// The first value is the name of the sanitizer as a string. The sani