aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/clang-c/CXCompilationDatabase.h6
-rw-r--r--include/clang-c/CXString.h2
-rw-r--r--include/clang-c/Index.h165
-rw-r--r--include/clang/ARCMigrate/ARCMT.h2
-rw-r--r--include/clang/ARCMigrate/ARCMTActions.h2
-rw-r--r--include/clang/ARCMigrate/FileRemapper.h2
-rw-r--r--include/clang/AST/APValue.h2
-rw-r--r--include/clang/AST/AST.h2
-rw-r--r--include/clang/AST/ASTConsumer.h15
-rw-r--r--include/clang/AST/ASTContext.h253
-rw-r--r--include/clang/AST/ASTImporter.h3
-rw-r--r--include/clang/AST/ASTMutationListener.h9
-rw-r--r--include/clang/AST/ASTTypeTraits.h (renamed from include/clang/ASTMatchers/ASTTypeTraits.h)14
-rw-r--r--include/clang/AST/ASTUnresolvedSet.h86
-rw-r--r--include/clang/AST/ASTVector.h12
-rw-r--r--include/clang/AST/Attr.h171
-rw-r--r--include/clang/AST/AttrIterator.h142
-rw-r--r--include/clang/AST/BuiltinTypes.def14
-rw-r--r--include/clang/AST/CMakeLists.txt13
-rw-r--r--include/clang/AST/CXXInheritance.h4
-rw-r--r--include/clang/AST/CanonicalType.h69
-rw-r--r--include/clang/AST/CharUnits.h11
-rw-r--r--include/clang/AST/Comment.h87
-rw-r--r--include/clang/AST/CommentCommandTraits.h34
-rw-r--r--include/clang/AST/CommentCommands.td92
-rw-r--r--include/clang/AST/CommentHTMLNamedCharacterReferences.td177
-rw-r--r--include/clang/AST/CommentLexer.h13
-rw-r--r--include/clang/AST/CommentParser.h9
-rw-r--r--include/clang/AST/CommentSema.h31
-rw-r--r--include/clang/AST/CommentVisitor.h4
-rw-r--r--include/clang/AST/Decl.h327
-rw-r--r--include/clang/AST/DeclAccessPair.h1
-rw-r--r--include/clang/AST/DeclBase.h129
-rw-r--r--include/clang/AST/DeclCXX.h587
-rw-r--r--include/clang/AST/DeclContextInternals.h24
-rw-r--r--include/clang/AST/DeclFriend.h50
-rw-r--r--include/clang/AST/DeclLookups.h1
-rw-r--r--include/clang/AST/DeclObjC.h339
-rw-r--r--include/clang/AST/DeclOpenMP.h83
-rw-r--r--include/clang/AST/DeclTemplate.h114
-rw-r--r--include/clang/AST/DeclVisitor.h43
-rw-r--r--include/clang/AST/DeclarationName.h85
-rw-r--r--include/clang/AST/DependentDiagnostic.h22
-rw-r--r--include/clang/AST/EvaluatedExprVisitor.h23
-rw-r--r--include/clang/AST/Expr.h367
-rw-r--r--include/clang/AST/ExprCXX.h257
-rw-r--r--include/clang/AST/ExprObjC.h126
-rw-r--r--include/clang/AST/ExternalASTSource.h28
-rw-r--r--include/clang/AST/LambdaMangleContext.h4
-rw-r--r--include/clang/AST/Makefile25
-rw-r--r--include/clang/AST/Mangle.h2
-rw-r--r--include/clang/AST/NSAPI.h14
-rw-r--r--include/clang/AST/NestedNameSpecifier.h2
-rw-r--r--include/clang/AST/OperationKinds.h5
-rw-r--r--include/clang/AST/PrettyPrinter.h19
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h36
-rw-r--r--include/clang/AST/Stmt.h229
-rw-r--r--include/clang/AST/StmtCXX.h38
-rw-r--r--include/clang/AST/StmtGraphTraits.h2
-rw-r--r--include/clang/AST/StmtObjC.h37
-rw-r--r--include/clang/AST/TemplateBase.h87
-rw-r--r--include/clang/AST/TemplateName.h24
-rw-r--r--include/clang/AST/Type.h200
-rw-r--r--include/clang/AST/TypeLoc.h93
-rw-r--r--include/clang/AST/TypeLocVisitor.h2
-rw-r--r--include/clang/AST/TypeOrdering.h2
-rw-r--r--include/clang/AST/UnresolvedSet.h11
-rw-r--r--include/clang/AST/VTTBuilder.h9
-rw-r--r--include/clang/AST/VTableBuilder.h23
-rw-r--r--include/clang/ASTMatchers/ASTMatchFinder.h85
-rw-r--r--include/clang/ASTMatchers/ASTMatchers.h573
-rw-r--r--include/clang/ASTMatchers/ASTMatchersInternal.h241
-rw-r--r--include/clang/ASTMatchers/ASTMatchersMacros.h284
-rw-r--r--include/clang/Analysis/Analyses/Dominators.h7
-rw-r--r--include/clang/Analysis/Analyses/FormatString.h4
-rw-r--r--include/clang/Analysis/Analyses/LiveVariables.h2
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafety.h23
-rw-r--r--include/clang/Analysis/Analyses/UninitializedValues.h5
-rw-r--r--include/clang/Analysis/AnalysisContext.h25
-rw-r--r--include/clang/Analysis/CFG.h117
-rw-r--r--include/clang/Analysis/CallGraph.h40
-rw-r--r--include/clang/Analysis/FlowSensitive/DataflowSolver.h4
-rw-r--r--include/clang/Analysis/ProgramPoint.h230
-rw-r--r--include/clang/Analysis/Support/BlkExprDeclBitVector.h2
-rw-r--r--include/clang/Analysis/Support/BumpVector.h4
-rw-r--r--include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h6
-rw-r--r--include/clang/Basic/Attr.td243
-rw-r--r--include/clang/Basic/AttrKinds.h1
-rw-r--r--include/clang/Basic/Builtins.def41
-rw-r--r--include/clang/Basic/Builtins.h6
-rw-r--r--include/clang/Basic/BuiltinsX86.def6
-rw-r--r--include/clang/Basic/CharInfo.h198
-rw-r--r--include/clang/Basic/CommentOptions.h34
-rw-r--r--include/clang/Basic/ConvertUTF.h203
-rw-r--r--include/clang/Basic/DeclNodes.td2
-rw-r--r--include/clang/Basic/Diagnostic.h34
-rw-r--r--include/clang/Basic/DiagnosticASTKinds.td6
-rw-r--r--include/clang/Basic/DiagnosticCommentKinds.td41
-rw-r--r--include/clang/Basic/DiagnosticCommonKinds.td14
-rw-r--r--include/clang/Basic/DiagnosticDriverKinds.td20
-rw-r--r--include/clang/Basic/DiagnosticFrontendKinds.td24
-rw-r--r--include/clang/Basic/DiagnosticGroups.td58
-rw-r--r--include/clang/Basic/DiagnosticIDs.h14
-rw-r--r--include/clang/Basic/DiagnosticLexKinds.td89
-rw-r--r--include/clang/Basic/DiagnosticOptions.def2
-rw-r--r--include/clang/Basic/DiagnosticOptions.h15
-rw-r--r--include/clang/Basic/DiagnosticParseKinds.td51
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td519
-rw-r--r--include/clang/Basic/DiagnosticSerializationKinds.td15
-rw-r--r--include/clang/Basic/FileManager.h18
-rw-r--r--include/clang/Basic/FileSystemStatCache.h21
-rw-r--r--include/clang/Basic/IdentifierTable.h9
-rw-r--r--include/clang/Basic/LLVM.h13
-rw-r--r--include/clang/Basic/LangOptions.def23
-rw-r--r--include/clang/Basic/LangOptions.h21
-rw-r--r--include/clang/Basic/Linkage.h8
-rw-r--r--include/clang/Basic/MacroBuilder.h1
-rw-r--r--include/clang/Basic/Module.h124
-rw-r--r--include/clang/Basic/ObjCRuntime.h16
-rw-r--r--include/clang/Basic/OnDiskHashTable.h3
-rw-r--r--include/clang/Basic/OpenMPKinds.def23
-rw-r--r--include/clang/Basic/OpenMPKinds.h37
-rw-r--r--include/clang/Basic/OperatorPrecedence.h52
-rw-r--r--include/clang/Basic/PartialDiagnostic.h24
-rw-r--r--include/clang/Basic/Sanitizers.def57
-rw-r--r--include/clang/Basic/SourceLocation.h22
-rw-r--r--include/clang/Basic/SourceManager.h158
-rw-r--r--include/clang/Basic/Specifiers.h13
-rw-r--r--include/clang/Basic/TargetCXXABI.h261
-rw-r--r--include/clang/Basic/TargetInfo.h80
-rw-r--r--include/clang/Basic/TargetOptions.h1
-rw-r--r--include/clang/Basic/TokenKinds.def92
-rw-r--r--include/clang/Basic/TokenKinds.h18
-rw-r--r--include/clang/Basic/TypeTraits.h3
-rw-r--r--include/clang/Basic/Version.h3
-rw-r--r--include/clang/Basic/VersionTuple.h8
-rw-r--r--include/clang/Basic/Visibility.h76
-rw-r--r--include/clang/CodeGen/ModuleBuilder.h2
-rw-r--r--include/clang/Driver/Arg.h7
-rw-r--r--include/clang/Driver/ArgList.h5
-rw-r--r--include/clang/Driver/CC1AsOptions.td8
-rw-r--r--include/clang/Driver/CC1Options.td47
-rw-r--r--include/clang/Driver/Compilation.h43
-rw-r--r--include/clang/Driver/Driver.h14
-rw-r--r--include/clang/Driver/Job.h2
-rw-r--r--include/clang/Driver/OptSpecifier.h4
-rw-r--r--include/clang/Driver/Option.h2
-rw-r--r--include/clang/Driver/Options.td107
-rw-r--r--include/clang/Driver/Phases.h4
-rw-r--r--include/clang/Driver/Tool.h1
-rw-r--r--include/clang/Driver/ToolChain.h36
-rw-r--r--include/clang/Driver/Types.def3
-rw-r--r--include/clang/Driver/Types.h13
-rw-r--r--include/clang/Driver/Util.h5
-rw-r--r--include/clang/Edit/Commit.h8
-rw-r--r--include/clang/Edit/EditedSource.h12
-rw-r--r--include/clang/Edit/Rewriters.h4
-rw-r--r--include/clang/Format/Format.h131
-rw-r--r--include/clang/Frontend/ASTUnit.h42
-rw-r--r--include/clang/Frontend/ChainedIncludesSource.h4
-rw-r--r--include/clang/Frontend/CodeGenOptions.def21
-rw-r--r--include/clang/Frontend/CodeGenOptions.h17
-rw-r--r--include/clang/Frontend/CompilerInstance.h52
-rw-r--r--include/clang/Frontend/CompilerInvocation.h14
-rw-r--r--include/clang/Frontend/DiagnosticRenderer.h49
-rw-r--r--include/clang/Frontend/FrontendAction.h102
-rw-r--r--include/clang/Frontend/FrontendActions.h17
-rw-r--r--include/clang/Frontend/FrontendOptions.h29
-rw-r--r--include/clang/Frontend/LangStandard.h6
-rw-r--r--include/clang/Frontend/LangStandards.def12
-rw-r--r--include/clang/Frontend/LayoutOverrideSource.h5
-rw-r--r--include/clang/Frontend/LogDiagnosticPrinter.h4
-rw-r--r--include/clang/Frontend/MultiplexConsumer.h1
-rw-r--r--include/clang/Frontend/PreprocessorOutputOptions.h2
-rw-r--r--include/clang/Frontend/SerializedDiagnosticPrinter.h3
-rw-r--r--include/clang/Frontend/TextDiagnostic.h20
-rw-r--r--include/clang/Frontend/TextDiagnosticPrinter.h4
-rw-r--r--include/clang/Frontend/Utils.h3
-rw-r--r--include/clang/Lex/DirectoryLookup.h34
-rw-r--r--include/clang/Lex/ExternalPreprocessorSource.h4
-rw-r--r--include/clang/Lex/HeaderSearch.h30
-rw-r--r--include/clang/Lex/HeaderSearchOptions.h67
-rw-r--r--include/clang/Lex/Lexer.h50
-rw-r--r--include/clang/Lex/LiteralSupport.h8
-rw-r--r--include/clang/Lex/MacroInfo.h471
-rw-r--r--include/clang/Lex/ModuleLoader.h41
-rw-r--r--include/clang/Lex/ModuleMap.h55
-rw-r--r--include/clang/Lex/PPCallbacks.h66
-rw-r--r--include/clang/Lex/PPConditionalDirectiveRecord.h102
-rw-r--r--include/clang/Lex/PPMutationListener.h43
-rw-r--r--include/clang/Lex/PTHManager.h6
-rw-r--r--include/clang/Lex/PreprocessingRecord.h97
-rw-r--r--include/clang/Lex/Preprocessor.h184
-rw-r--r--include/clang/Lex/PreprocessorOptions.h52
-rw-r--r--include/clang/Lex/Token.h12
-rw-r--r--include/clang/Parse/Parser.h147
-rw-r--r--include/clang/Rewrite/Core/RewriteRope.h3
-rw-r--r--include/clang/Rewrite/Core/Rewriter.h8
-rw-r--r--include/clang/Rewrite/Frontend/ASTConsumers.h3
-rw-r--r--include/clang/Rewrite/Frontend/FixItRewriter.h2
-rw-r--r--include/clang/Sema/AttributeList.h123
-rw-r--r--include/clang/Sema/CMakeLists.txt7
-rw-r--r--include/clang/Sema/CXXFieldCollector.h1
-rw-r--r--include/clang/Sema/CodeCompleteConsumer.h37
-rw-r--r--include/clang/Sema/CodeCompleteOptions.h8
-rw-r--r--include/clang/Sema/DeclSpec.h216
-rw-r--r--include/clang/Sema/DelayedDiagnostic.h39
-rw-r--r--include/clang/Sema/ExternalSemaSource.h10
-rw-r--r--include/clang/Sema/IdentifierResolver.h3
-rw-r--r--include/clang/Sema/Initialization.h93
-rw-r--r--include/clang/Sema/Lookup.h25
-rw-r--r--include/clang/Sema/Makefile9
-rw-r--r--include/clang/Sema/MultiplexExternalSemaSource.h59
-rw-r--r--include/clang/Sema/Overload.h9
-rw-r--r--include/clang/Sema/Ownership.h3
-rw-r--r--include/clang/Sema/Scope.h64
-rw-r--r--include/clang/Sema/ScopeInfo.h17
-rw-r--r--include/clang/Sema/Sema.h551
-rw-r--r--include/clang/Sema/SemaInternal.h2
-rw-r--r--include/clang/Sema/Template.h13
-rw-r--r--include/clang/Sema/TemplateDeduction.h18
-rw-r--r--include/clang/Sema/TypoCorrection.h15
-rw-r--r--include/clang/Serialization/ASTBitCodes.h103
-rw-r--r--include/clang/Serialization/ASTReader.h347
-rw-r--r--include/clang/Serialization/ASTWriter.h62
-rw-r--r--include/clang/Serialization/ContinuousRangeMap.h1
-rw-r--r--include/clang/Serialization/GlobalModuleIndex.h194
-rw-r--r--include/clang/Serialization/Module.h53
-rw-r--r--include/clang/Serialization/ModuleManager.h148
-rw-r--r--include/clang/StaticAnalyzer/Core/Analyses.def14
-rw-r--r--include/clang/StaticAnalyzer/Core/AnalyzerOptions.h215
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h28
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h125
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/BugType.h1
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h32
-rw-r--r--include/clang/StaticAnalyzer/Core/Checker.h87
-rw-r--r--include/clang/StaticAnalyzer/Core/CheckerManager.h81
-rw-r--r--include/clang/StaticAnalyzer/Core/CheckerOptInfo.h1
-rw-r--r--include/clang/StaticAnalyzer/Core/CheckerRegistry.h2
-rw-r--r--include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h24
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h9
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h2
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h3
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h38
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h12
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h14
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h12
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h10
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h64
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h143
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h96
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h61
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h105
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h19
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h5
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h242
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/Store.h40
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h22
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h8
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h4
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h6
-rw-r--r--include/clang/Tooling/CommonOptionsParser.h10
-rw-r--r--include/clang/Tooling/CompilationDatabase.h13
-rw-r--r--include/clang/Tooling/FileMatchTrie.h3
-rw-r--r--include/clang/Tooling/JSONCompilationDatabase.h10
-rw-r--r--include/clang/Tooling/Refactoring.h62
-rw-r--r--include/clang/Tooling/Tooling.h17
267 files changed, 10728 insertions, 4881 deletions
diff --git a/include/clang-c/CXCompilationDatabase.h b/include/clang-c/CXCompilationDatabase.h
index d11133cf9328..ff1ec63db057 100644
--- a/include/clang-c/CXCompilationDatabase.h
+++ b/include/clang-c/CXCompilationDatabase.h
@@ -95,6 +95,12 @@ clang_CompilationDatabase_getCompileCommands(CXCompilationDatabase,
const char *CompleteFileName);
/**
+ * \brief Get all the compile commands in the given compilation database.
+ */
+CINDEX_LINKAGE CXCompileCommands
+clang_CompilationDatabase_getAllCompileCommands(CXCompilationDatabase);
+
+/**
* \brief Free the given CompileCommands
*/
CINDEX_LINKAGE void clang_CompileCommands_dispose(CXCompileCommands);
diff --git a/include/clang-c/CXString.h b/include/clang-c/CXString.h
index 74c31660ef10..34cab5e7bd8c 100644
--- a/include/clang-c/CXString.h
+++ b/include/clang-c/CXString.h
@@ -36,7 +36,7 @@ extern "C" {
* with the string data, call \c clang_disposeString() to free the string.
*/
typedef struct {
- void *data;
+ const void *data;
unsigned private_flags;
} CXString;
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
index aa3403cc80c4..787c44a2e4fa 100644
--- a/include/clang-c/Index.h
+++ b/include/clang-c/Index.h
@@ -32,7 +32,7 @@
* compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable.
*/
#define CINDEX_VERSION_MAJOR 0
-#define CINDEX_VERSION_MINOR 6
+#define CINDEX_VERSION_MINOR 15
#define CINDEX_VERSION_ENCODE(major, minor) ( \
((major) * 10000) \
@@ -297,6 +297,24 @@ CINDEX_LINKAGE CXString clang_getFileName(CXFile SFile);
CINDEX_LINKAGE time_t clang_getFileTime(CXFile SFile);
/**
+ * \brief Uniquely identifies a CXFile, that refers to the same underlying file,
+ * across an indexing session.
+ */
+typedef struct {
+ unsigned long long data[3];
+} CXFileUniqueID;
+
+/**
+ * \brief Retrieve the unique ID for the given \c file.
+ *
+ * \param file the file to get the ID for.
+ * \param outID stores the returned CXFileUniqueID.
+ * \returns If there was a failure getting the unique ID, returns non-zero,
+ * otherwise returns 0.
+*/
+CINDEX_LINKAGE int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID);
+
+/**
* \brief Determine whether the given header is guarded against
* multiple inclusions, either with the conventional
* \#ifndef/\#define/\#endif macro guards or with \#pragma once.
@@ -342,7 +360,7 @@ CINDEX_LINKAGE CXFile clang_getFile(CXTranslationUnit tu,
* to map a source location to a particular file, line, and column.
*/
typedef struct {
- void *ptr_data[2];
+ const void *ptr_data[2];
unsigned int_data;
} CXSourceLocation;
@@ -353,7 +371,7 @@ typedef struct {
* starting and end locations from a source range, respectively.
*/
typedef struct {
- void *ptr_data[2];
+ const void *ptr_data[2];
unsigned begin_int_data;
unsigned end_int_data;
} CXSourceRange;
@@ -361,7 +379,7 @@ typedef struct {
/**
* \brief Retrieve a NULL (invalid) source location.
*/
-CINDEX_LINKAGE CXSourceLocation clang_getNullLocation();
+CINDEX_LINKAGE CXSourceLocation clang_getNullLocation(void);
/**
* \brief Determine whether two source locations, which must refer into
@@ -393,7 +411,7 @@ CINDEX_LINKAGE CXSourceLocation clang_getLocationForOffset(CXTranslationUnit tu,
/**
* \brief Retrieve a NULL (invalid) source range.
*/
-CINDEX_LINKAGE CXSourceRange clang_getNullRange();
+CINDEX_LINKAGE CXSourceRange clang_getNullRange(void);
/**
* \brief Retrieve a source range given the beginning and ending source
@@ -531,6 +549,35 @@ CINDEX_LINKAGE void clang_getSpellingLocation(CXSourceLocation location,
unsigned *offset);
/**
+ * \brief Retrieve the file, line, column, and offset represented by
+ * the given source location.
+ *
+ * If the location refers into a macro expansion, return where the macro was
+ * expanded or where the macro argument was written, if the location points at
+ * a macro argument.
+ *
+ * \param location the location within a source file that will be decomposed
+ * into its parts.
+ *
+ * \param file [out] if non-NULL, will be set to the file to which the given
+ * source location points.
+ *
+ * \param line [out] if non-NULL, will be set to the line to which the given
+ * source location points.
+ *
+ * \param column [out] if non-NULL, will be set to the column to which the given
+ * source location points.
+ *
+ * \param offset [out] if non-NULL, will be set to the offset into the
+ * buffer to which the given source location points.
+ */
+CINDEX_LINKAGE void clang_getFileLocation(CXSourceLocation location,
+ CXFile *file,
+ unsigned *line,
+ unsigned *column,
+ unsigned *offset);
+
+/**
* \brief Retrieve a source location representing the first character within a
* source range.
*/
@@ -2072,7 +2119,7 @@ enum CXCursorKind {
typedef struct {
enum CXCursorKind kind;
int xdata;
- void *data[3];
+ const void *data[3];
} CXCursor;
/**
@@ -2330,7 +2377,7 @@ typedef struct CXCursorSetImpl *CXCursorSet;
/**
* \brief Creates an empty CXCursorSet.
*/
-CINDEX_LINKAGE CXCursorSet clang_createCXCursorSet();
+CINDEX_LINKAGE CXCursorSet clang_createCXCursorSet(void);
/**
* \brief Disposes a CXCursorSet and releases its associated memory.
@@ -2626,6 +2673,7 @@ enum CXCallingConv {
CXCallingConv_AAPCS = 6,
CXCallingConv_AAPCS_VFP = 7,
CXCallingConv_PnaclCall = 8,
+ CXCallingConv_IntelOclBicc = 9,
CXCallingConv_Invalid = 100,
CXCallingConv_Unexposed = 200
@@ -2647,6 +2695,14 @@ typedef struct {
CINDEX_LINKAGE CXType clang_getCursorType(CXCursor C);
/**
+ * \brief Pretty-print the underlying type using the rules of the
+ * language of the translation unit from which it came.
+ *
+ * If the type is invalid, an empty string is returned.
+ */
+CINDEX_LINKAGE CXString clang_getTypeSpelling(CXType CT);
+
+/**
* \brief Retrieve the underlying type of a typedef declaration.
*
* If the cursor does not reference a typedef declaration, an invalid type is
@@ -2683,18 +2739,27 @@ CINDEX_LINKAGE long long clang_getEnumConstantDeclValue(CXCursor C);
CINDEX_LINKAGE unsigned long long clang_getEnumConstantDeclUnsignedValue(CXCursor C);
/**
+ * \brief Retrieve the bit width of a bit field declaration as an integer.
+ *
+ * If a cursor that is not a bit field declaration is passed in, -1 is returned.
+ */
+CINDEX_LINKAGE int clang_getFieldDeclBitWidth(CXCursor C);
+
+/**
* \brief Retrieve the number of non-variadic arguments associated with a given
* cursor.
*
- * If a cursor that is not a function or method is passed in, -1 is returned.
+ * The number of arguments can be determined for calls as well as for
+ * declarations of functions or methods. For other cursors -1 is returned.
*/
CINDEX_LINKAGE int clang_Cursor_getNumArguments(CXCursor C);
/**
* \brief Retrieve the argument cursor of a function or method.
*
- * If a cursor that is not a function or method is passed in or the index
- * exceeds the number of arguments, an invalid cursor is returned.
+ * The argument cursor can be determined for calls as well as for declarations
+ * of functions or methods. For other cursors and for invalid indices, an
+ * invalid cursor is returned.
*/
CINDEX_LINKAGE CXCursor clang_Cursor_getArgument(CXCursor C, unsigned i);
@@ -3284,7 +3349,8 @@ CINDEX_LINKAGE CXString clang_Module_getFullName(CXModule Module);
*
* \returns the number of top level headers associated with this module.
*/
-CINDEX_LINKAGE unsigned clang_Module_getNumTopLevelHeaders(CXModule Module);
+CINDEX_LINKAGE unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit,
+ CXModule Module);
/**
* \param Module a module object.
@@ -3294,7 +3360,8 @@ CINDEX_LINKAGE unsigned clang_Module_getNumTopLevelHeaders(CXModule Module);
* \returns the specified top level header associated with the module.
*/
CINDEX_LINKAGE
-CXFile clang_Module_getTopLevelHeader(CXModule Module, unsigned Index);
+CXFile clang_Module_getTopLevelHeader(CXTranslationUnit,
+ CXModule Module, unsigned Index);
/**
* @}
@@ -4828,7 +4895,7 @@ CXString clang_codeCompleteGetObjCSelector(CXCodeCompleteResults *Results);
* \brief Return a version string, suitable for showing to a user, but not
* intended to be parsed (the format is not guaranteed to be stable).
*/
-CINDEX_LINKAGE CXString clang_getClangVersion();
+CINDEX_LINKAGE CXString clang_getClangVersion(void);
/**
@@ -4943,6 +5010,23 @@ typedef struct {
enum CXVisitorResult (*visit)(void *context, CXCursor, CXSourceRange);
} CXCursorAndRangeVisitor;
+typedef enum {
+ /**
+ * \brief Function returned successfully.
+ */
+ CXResult_Success = 0,
+ /**
+ * \brief One of the parameters was invalid for the function.
+ */
+ CXResult_Invalid = 1,
+ /**
+ * \brief The function was terminated by a callback (e.g. it returned
+ * CXVisit_Break)
+ */
+ CXResult_VisitBreak = 2
+
+} CXResult;
+
/**
* \brief Find references of a declaration in a specific file.
*
@@ -4954,10 +5038,28 @@ typedef struct {
* each reference found.
* The CXSourceRange will point inside the file; if the reference is inside
* a macro (and not a macro argument) the CXSourceRange will be invalid.
+ *
+ * \returns one of the CXResult enumerators.
*/
-CINDEX_LINKAGE void clang_findReferencesInFile(CXCursor cursor, CXFile file,
+CINDEX_LINKAGE CXResult clang_findReferencesInFile(CXCursor cursor, CXFile file,
CXCursorAndRangeVisitor visitor);
+/**
+ * \brief Find #import/#include directives in a specific file.
+ *
+ * \param TU translation unit containing the file to query.
+ *
+ * \param file to search for #import/#include directives.
+ *
+ * \param visitor callback that will receive pairs of CXCursor/CXSourceRange for
+ * each directive found.
+ *
+ * \returns one of the CXResult enumerators.
+ */
+CINDEX_LINKAGE CXResult clang_findIncludesInFile(CXTranslationUnit TU,
+ CXFile file,
+ CXCursorAndRangeVisitor visitor);
+
#ifdef __has_feature
# if __has_feature(blocks)
@@ -4965,8 +5067,12 @@ typedef enum CXVisitorResult
(^CXCursorAndRangeVisitorBlock)(CXCursor, CXSourceRange);
CINDEX_LINKAGE
-void clang_findReferencesInFileWithBlock(CXCursor, CXFile,
- CXCursorAndRangeVisitorBlock);
+CXResult clang_findReferencesInFileWithBlock(CXCursor, CXFile,
+ CXCursorAndRangeVisitorBlock);
+
+CINDEX_LINKAGE
+CXResult clang_findIncludesInFileWithBlock(CXTranslationUnit, CXFile,
+ CXCursorAndRangeVisitorBlock);
# endif
#endif
@@ -5144,6 +5250,10 @@ typedef struct {
CXIdxLoc classLoc;
} CXIdxIBOutletCollectionAttrInfo;
+typedef enum {
+ CXIdxDeclFlag_Skipped = 0x1
+} CXIdxDeclInfoFlags;
+
typedef struct {
const CXIdxEntityInfo *entityInfo;
CXCursor cursor;
@@ -5165,6 +5275,9 @@ typedef struct {
int isImplicit;
const CXIdxAttrInfo *const *attributes;
unsigned numAttributes;
+
+ unsigned flags;
+
} CXIdxDeclInfo;
typedef enum {
@@ -5372,16 +5485,14 @@ CINDEX_LINKAGE void
clang_index_setClientEntity(const CXIdxEntityInfo *, CXIdxClientEntity);
/**
- * \brief An indexing action, to be applied to one or multiple translation units
- * but not on concurrent threads. If there are threads doing indexing
- * concurrently, they should use different CXIndexAction objects.
+ * \brief An indexing action/session, to be applied to one or multiple
+ * translation units.
*/
typedef void *CXIndexAction;
/**
- * \brief An indexing action, to be applied to one or multiple translation units
- * but not on concurrent threads. If there are threads doing indexing
- * concurrently, they should use different CXIndexAction objects.
+ * \brief An indexing action/session, to be applied to one or multiple
+ * translation units.
*
* \param CIdx The index object with which the index action will be associated.
*/
@@ -5423,7 +5534,15 @@ typedef enum {
/**
* \brief Suppress all compiler warnings when parsing for indexing.
*/
- CXIndexOpt_SuppressWarnings = 0x8
+ CXIndexOpt_SuppressWarnings = 0x8,
+
+ /**
+ * \brief Skip a function/method body that was already parsed during an
+ * indexing session assosiated with a \c CXIndexAction object.
+ * Bodies in system headers are always skipped.
+ */
+ CXIndexOpt_SkipParsedBodiesInSession = 0x10
+
} CXIndexOptFlags;
/**
diff --git a/include/clang/ARCMigrate/ARCMT.h b/include/clang/ARCMigrate/ARCMT.h
index cce866165210..c167d3c3192b 100644
--- a/include/clang/ARCMigrate/ARCMT.h
+++ b/include/clang/ARCMigrate/ARCMT.h
@@ -11,8 +11,8 @@
#define LLVM_CLANG_ARCMIGRATE_ARCMT_H
#include "clang/ARCMigrate/FileRemapper.h"
-#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Basic/SourceLocation.h"
+#include "clang/Frontend/CompilerInvocation.h"
namespace clang {
class ASTContext;
diff --git a/include/clang/ARCMigrate/ARCMTActions.h b/include/clang/ARCMigrate/ARCMTActions.h
index e0752521378b..2daaf73065c2 100644
--- a/include/clang/ARCMigrate/ARCMTActions.h
+++ b/include/clang/ARCMigrate/ARCMTActions.h
@@ -10,8 +10,8 @@
#ifndef LLVM_CLANG_ARCMIGRATE_ARCMT_ACTION_H
#define LLVM_CLANG_ARCMIGRATE_ARCMT_ACTION_H
-#include "clang/Frontend/FrontendAction.h"
#include "clang/ARCMigrate/FileRemapper.h"
+#include "clang/Frontend/FrontendAction.h"
#include "llvm/ADT/OwningPtr.h"
namespace clang {
diff --git a/include/clang/ARCMigrate/FileRemapper.h b/include/clang/ARCMigrate/FileRemapper.h
index fe7cfadb4973..94c9e8f31acb 100644
--- a/include/clang/ARCMigrate/FileRemapper.h
+++ b/include/clang/ARCMigrate/FileRemapper.h
@@ -11,9 +11,9 @@
#define LLVM_CLANG_ARCMIGRATE_FILEREMAPPER_H
#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/PointerUnion.h"
-#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringRef.h"
namespace llvm {
diff --git a/include/clang/AST/APValue.h b/include/clang/AST/APValue.h
index 1b6e90cf4a83..ec8faa4e3524 100644
--- a/include/clang/AST/APValue.h
+++ b/include/clang/AST/APValue.h
@@ -15,8 +15,8 @@
#define LLVM_CLANG_AST_APVALUE_H
#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h"
diff --git a/include/clang/AST/AST.h b/include/clang/AST/AST.h
index 164c5fbbb6e2..6db351d1064b 100644
--- a/include/clang/AST/AST.h
+++ b/include/clang/AST/AST.h
@@ -22,7 +22,7 @@
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprObjC.h"
-#include "clang/AST/Type.h"
#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/Type.h"
#endif
diff --git a/include/clang/AST/ASTConsumer.h b/include/clang/AST/ASTConsumer.h
index 37b0740cb98b..ae779436a9da 100644
--- a/include/clang/AST/ASTConsumer.h
+++ b/include/clang/AST/ASTConsumer.h
@@ -17,9 +17,9 @@
namespace clang {
class ASTContext;
class CXXRecordDecl;
+ class Decl;
class DeclGroupRef;
class HandleTagDeclDefinition;
- class PPMutationListener;
class ASTMutationListener;
class ASTDeserializationListener; // layering violation because void* is ugly
class SemaConsumer; // layering violation required for safe SemaConsumer
@@ -112,11 +112,6 @@ 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.
@@ -130,6 +125,14 @@ public:
/// PrintStats - If desired, print any statistics.
virtual void PrintStats() {}
+
+ /// \brief This callback is called for each function if the Parser was
+ /// initialized with \c SkipFunctionBodies set to \c true.
+ ///
+ /// \return \c true if the function's body should be skipped. The function
+ /// body may be parsed anyway if it is needed (for instance, if it contains
+ /// the code completion point or is constexpr).
+ virtual bool shouldSkipFunctionBody(Decl *D) { return true; }
};
} // end namespace clang.
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index f0934b77961b..d4878a99a6fe 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -15,21 +15,23 @@
#ifndef LLVM_CLANG_AST_ASTCONTEXT_H
#define LLVM_CLANG_AST_ASTCONTEXT_H
-#include "clang/Basic/AddressSpaces.h"
-#include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/OperatorKinds.h"
-#include "clang/Basic/PartialDiagnostic.h"
-#include "clang/Basic/VersionTuple.h"
+#include "clang/AST/ASTTypeTraits.h"
+#include "clang/AST/CanonicalType.h"
+#include "clang/AST/CommentCommandTraits.h"
#include "clang/AST/Decl.h"
#include "clang/AST/LambdaMangleContext.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/PrettyPrinter.h"
+#include "clang/AST/RawCommentList.h"
+#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
-#include "clang/AST/CanonicalType.h"
-#include "clang/AST/RawCommentList.h"
-#include "clang/AST/CommentCommandTraits.h"
+#include "clang/Basic/AddressSpaces.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/OperatorKinds.h"
+#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/VersionTuple.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
@@ -57,28 +59,12 @@ namespace clang {
class TargetInfo;
class CXXABI;
// Decls
- class DeclContext;
- class CXXConversionDecl;
- class CXXMethodDecl;
- class CXXRecordDecl;
- class Decl;
- class FieldDecl;
class MangleContext;
class ObjCIvarDecl;
- class ObjCIvarRefExpr;
class ObjCPropertyDecl;
- class ParmVarDecl;
- class RecordDecl;
- class StoredDeclsMap;
- class TagDecl;
- class TemplateTemplateParmDecl;
- class TemplateTypeParmDecl;
- class TranslationUnitDecl;
- class TypeDecl;
- class TypedefNameDecl;
+ class UnresolvedSetIterator;
class UsingDecl;
class UsingShadowDecl;
- class UnresolvedSetIterator;
namespace Builtin { class Context; }
@@ -91,7 +77,7 @@ namespace clang {
class ASTContext : public RefCountedBase<ASTContext> {
ASTContext &this_() { return *this; }
- mutable std::vector<Type*> Types;
+ mutable SmallVector<Type *, 0> Types;
mutable llvm::FoldingSet<ExtQuals> ExtQualNodes;
mutable llvm::FoldingSet<ComplexType> ComplexTypes;
mutable llvm::FoldingSet<PointerType> PointerTypes;
@@ -233,6 +219,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
QualType ObjCConstantStringType;
mutable RecordDecl *CFConstantStringTypeDecl;
+ mutable QualType ObjCSuperType;
+
QualType ObjCNSStringType;
/// \brief The typedef declaration for the Objective-C "instancetype" type.
@@ -343,7 +331,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// \brief Mapping from each declaration context to its corresponding lambda
/// mangling context.
llvm::DenseMap<const DeclContext *, LambdaMangleContext> LambdaMangleContexts;
-
+
+ llvm::DenseMap<const DeclContext *, unsigned> UnnamedMangleContexts;
+ llvm::DenseMap<const TagDecl *, unsigned> UnnamedMangleNumbers;
+
/// \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;
@@ -393,6 +384,58 @@ public:
OwningPtr<ExternalASTSource> ExternalSource;
ASTMutationListener *Listener;
+ /// \brief Contains parents of a node.
+ typedef llvm::SmallVector<ast_type_traits::DynTypedNode, 1> ParentVector;
+
+ /// \brief Maps from a node to its parents.
+ typedef llvm::DenseMap<const void *, ParentVector> ParentMap;
+
+ /// \brief Returns the parents of the given node.
+ ///
+ /// Note that this will lazily compute the parents of all nodes
+ /// and store them for later retrieval. Thus, the first call is O(n)
+ /// in the number of AST nodes.
+ ///
+ /// Caveats and FIXMEs:
+ /// Calculating the parent map over all AST nodes will need to load the
+ /// full AST. This can be undesirable in the case where the full AST is
+ /// expensive to create (for example, when using precompiled header
+ /// preambles). Thus, there are good opportunities for optimization here.
+ /// One idea is to walk the given node downwards, looking for references
+ /// to declaration contexts - once a declaration context is found, compute
+ /// the parent map for the declaration context; if that can satisfy the
+ /// request, loading the whole AST can be avoided. Note that this is made
+ /// more complex by statements in templates having multiple parents - those
+ /// problems can be solved by building closure over the templated parts of
+ /// the AST, which also avoids touching large parts of the AST.
+ /// Additionally, we will want to add an interface to already give a hint
+ /// where to search for the parents, for example when looking at a statement
+ /// inside a certain function.
+ ///
+ /// 'NodeT' can be one of Decl, Stmt, Type, TypeLoc,
+ /// NestedNameSpecifier or NestedNameSpecifierLoc.
+ template <typename NodeT>
+ ParentVector getParents(const NodeT &Node) {
+ return getParents(ast_type_traits::DynTypedNode::create(Node));
+ }
+
+ ParentVector getParents(const ast_type_traits::DynTypedNode &Node) {
+ assert(Node.getMemoizationData() &&
+ "Invariant broken: only nodes that support memoization may be "
+ "used in the parent map.");
+ if (!AllParents) {
+ // We always need to run over the whole translation unit, as
+ // hasAncestor can escape any subtree.
+ AllParents.reset(
+ ParentMapASTVisitor::buildMap(*getTranslationUnitDecl()));
+ }
+ ParentMap::const_iterator I = AllParents->find(Node.getMemoizationData());
+ if (I == AllParents->end()) {
+ return ParentVector();
+ }
+ return I->second;
+ }
+
const clang::PrintingPolicy &getPrintingPolicy() const {
return PrintingPolicy;
}
@@ -713,6 +756,10 @@ public:
CanQualType PseudoObjectTy, ARCUnbridgedCastTy;
CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy;
CanQualType ObjCBuiltinBoolTy;
+ CanQualType OCLImage1dTy, OCLImage1dArrayTy, OCLImage1dBufferTy;
+ CanQualType OCLImage2dTy, OCLImage2dArrayTy;
+ CanQualType OCLImage3dTy;
+ CanQualType OCLSamplerTy, OCLEventTy;
// Types for deductions in C++0x [stmt.ranged]'s desugaring. Built on demand.
mutable QualType AutoDeductTy; // Deduction against 'auto'.
@@ -755,7 +802,7 @@ public:
ASTMutationListener *getASTMutationListener() const { return Listener; }
void PrintStats() const;
- const std::vector<Type*>& getTypes() const { return Types; }
+ const SmallVectorImpl<Type *>& getTypes() const { return Types; }
/// \brief Retrieve the declaration for the 128-bit signed integer type.
TypedefDecl *getInt128Decl() const;
@@ -857,12 +904,17 @@ public:
return cudaConfigureCallDecl;
}
- /// 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;
-
+ bool BlockRequiresCopying(QualType Ty, const VarDecl *D);
+
+
+ /// Returns true, if given type has a known lifetime. HasByrefExtendedLayout is set
+ /// to false in this case. If HasByrefExtendedLayout returns true, byref variable
+ /// has extended lifetime.
+ bool getByrefLifetime(QualType Ty,
+ Qualifiers::ObjCLifetime &Lifetime,
+ bool &HasByrefExtendedLayout) const;
+
/// \brief Return the uniqued reference to the type for an lvalue reference
/// to the specified type.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue = true)
@@ -941,8 +993,7 @@ public:
}
/// \brief Return a normal function type with a typed argument list.
- QualType getFunctionType(QualType ResultTy,
- const QualType *Args, unsigned NumArgs,
+ QualType getFunctionType(QualType ResultTy, ArrayRef<QualType> Args,
const FunctionProtoType::ExtProtoInfo &EPI) const;
/// \brief Return the unique reference to the type for the specified type
@@ -1025,7 +1076,7 @@ public:
const TemplateArgument *Args) const;
QualType getPackExpansionType(QualType Pattern,
- llvm::Optional<unsigned> NumExpansions);
+ Optional<unsigned> NumExpansions);
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl,
ObjCInterfaceDecl *PrevDecl = 0) const;
@@ -1094,6 +1145,14 @@ public:
/// defined in <stddef.h> as defined by the target.
QualType getWIntType() const { return WIntTy; }
+ /// \brief Return a type compatible with "intptr_t" (C99 7.18.1.4),
+ /// as defined by the target.
+ QualType getIntPtrType() const;
+
+ /// \brief Return a type compatible with "uintptr_t" (C99 7.18.1.4),
+ /// as defined by the target.
+ QualType getUIntPtrType() const;
+
/// \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;
@@ -1104,7 +1163,11 @@ public:
/// \brief Return the C structure type used to represent constant CFStrings.
QualType getCFConstantStringType() const;
-
+
+ /// \brief Returns the C struct type for objc_super
+ QualType getObjCSuperType() const;
+ void setObjCSuperType(QualType ST) { ObjCSuperType = ST; }
+
/// Get the structure type used to representation CFStrings, or NULL
/// if it hasn't yet been built.
QualType getRawCFConstantStringType() const {
@@ -1545,14 +1608,27 @@ public:
const ASTRecordLayout &
getASTObjCImplementationLayout(const ObjCImplementationDecl *D) const;
- /// \brief Get the key function for the given record decl, or NULL if there
- /// isn't one.
+ /// \brief Get our current best idea for the key function of 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.
///
- /// ...the first non-pure virtual function that is not inline at the point
- /// of class definition.
- const CXXMethodDecl *getKeyFunction(const CXXRecordDecl *RD);
+ /// Other ABIs use the same idea. However, the ARM C++ ABI ignores
+ /// virtual functions that are defined 'inline', which means that
+ /// the result of this computation can change.
+ const CXXMethodDecl *getCurrentKeyFunction(const CXXRecordDecl *RD);
+
+ /// \brief Observe that the given method cannot be a key function.
+ /// Checks the key-function cache for the method's class and clears it
+ /// if matches the given declaration.
+ ///
+ /// This is used in ABIs where out-of-line definitions marked
+ /// inline are not considered to be key functions.
+ ///
+ /// \param method should be the declaration from the class definition
+ void setNonKeyFunction(const CXXMethodDecl *method);
/// Get the offset of a FieldDecl or IndirectFieldDecl, in bits.
uint64_t getFieldOffset(const ValueDecl *FD) const;
@@ -1885,8 +1961,8 @@ public:
// Type Iterators.
//===--------------------------------------------------------------------===//
- typedef std::vector<Type*>::iterator type_iterator;
- typedef std::vector<Type*>::const_iterator const_type_iterator;
+ typedef SmallVectorImpl<Type *>::iterator type_iterator;
+ typedef SmallVectorImpl<Type *>::const_iterator const_type_iterator;
type_iterator types_begin() { return Types.begin(); }
type_iterator types_end() { return Types.end(); }
@@ -1943,7 +2019,7 @@ public:
/// \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;
+ const ObjCInterfaceDecl *getObjContainingInterface(const NamedDecl *ND) const;
/// \brief Set the copy inialization expression of a block var decl.
void setBlockVarCopyInits(VarDecl*VD, Expr* Init);
@@ -1993,6 +2069,9 @@ public:
/// it is not used.
bool DeclMustBeEmitted(const Decl *D);
+ void addUnnamedTag(const TagDecl *Tag);
+ int getUnnamedTagManglingNumber(const TagDecl *Tag) const;
+
/// \brief Retrieve the lambda mangling number for a lambda expression.
unsigned getLambdaManglingNumber(CXXMethodDecl *CallOperator);
@@ -2077,7 +2156,8 @@ private:
bool EncodingProperty = false,
bool StructField = false,
bool EncodeBlockParameters = false,
- bool EncodeClassNames = false) const;
+ bool EncodeClassNames = false,
+ bool EncodePointerToObjCTypedef = false) const;
// Adds the encoding of the structure's members.
void getObjCEncodingForStructureImpl(RecordDecl *RD, std::string &S,
@@ -2109,8 +2189,81 @@ private:
friend class DeclContext;
friend class DeclarationNameTable;
void ReleaseDeclContextMaps();
+
+ /// \brief A \c RecursiveASTVisitor that builds a map from nodes to their
+ /// parents as defined by the \c RecursiveASTVisitor.
+ ///
+ /// Note that the relationship described here is purely in terms of AST
+ /// traversal - there are other relationships (for example declaration context)
+ /// in the AST that are better modeled by special matchers.
+ ///
+ /// FIXME: Currently only builds up the map using \c Stmt and \c Decl nodes.
+ class ParentMapASTVisitor : public RecursiveASTVisitor<ParentMapASTVisitor> {
+ public:
+ /// \brief Builds and returns the translation unit's parent map.
+ ///
+ /// The caller takes ownership of the returned \c ParentMap.
+ static ParentMap *buildMap(TranslationUnitDecl &TU) {
+ ParentMapASTVisitor Visitor(new ParentMap);
+ Visitor.TraverseDecl(&TU);
+ return Visitor.Parents;
+ }
+
+ private:
+ typedef RecursiveASTVisitor<ParentMapASTVisitor> VisitorBase;
+
+ ParentMapASTVisitor(ParentMap *Parents) : Parents(Parents) {
+ }
+
+ bool shouldVisitTemplateInstantiations() const {
+ return true;
+ }
+ bool shouldVisitImplicitCode() const {
+ return true;
+ }
+ // Disables data recursion. We intercept Traverse* methods in the RAV, which
+ // are not triggered during data recursion.
+ bool shouldUseDataRecursionFor(clang::Stmt *S) const {
+ return false;
+ }
+
+ template <typename T>
+ bool TraverseNode(T *Node, bool(VisitorBase:: *traverse) (T *)) {
+ if (Node == NULL)
+ return true;
+ if (ParentStack.size() > 0)
+ // FIXME: Currently we add the same parent multiple times, for example
+ // when we visit all subexpressions of template instantiations; this is
+ // suboptimal, bug benign: the only way to visit those is with
+ // hasAncestor / hasParent, and those do not create new matches.
+ // The plan is to enable DynTypedNode to be storable in a map or hash
+ // map. The main problem there is to implement hash functions /
+ // comparison operators for all types that DynTypedNode supports that
+ // do not have pointer identity.
+ (*Parents)[Node].push_back(ParentStack.back());
+ ParentStack.push_back(ast_type_traits::DynTypedNode::create(*Node));
+ bool Result = (this ->* traverse) (Node);
+ ParentStack.pop_back();
+ return Result;
+ }
+
+ bool TraverseDecl(Decl *DeclNode) {
+ return TraverseNode(DeclNode, &VisitorBase::TraverseDecl);
+ }
+
+ bool TraverseStmt(Stmt *StmtNode) {
+ return TraverseNode(StmtNode, &VisitorBase::TraverseStmt);
+ }
+
+ ParentMap *Parents;
+ llvm::SmallVector<ast_type_traits::DynTypedNode, 16> ParentStack;
+
+ friend class RecursiveASTVisitor<ParentMapASTVisitor>;
+ };
+
+ llvm::OwningPtr<ParentMap> AllParents;
};
-
+
/// \brief Utility function for constructing a nullary selector.
static inline Selector GetNullarySelector(StringRef name, ASTContext& Ctx) {
IdentifierInfo* II = &Ctx.Idents.get(name);
@@ -2132,8 +2285,8 @@ static inline Selector GetUnarySelector(StringRef name, ASTContext& Ctx) {
/// This placement form of operator new uses the ASTContext's allocator for
/// obtaining memory.
///
-/// IMPORTANT: These are also declared in clang/AST/Attr.h! Any changes here
-/// need to also be made there.
+/// IMPORTANT: These are also declared in clang/AST/AttrIterator.h! Any changes
+/// here need to also be made there.
///
/// We intentionally avoid using a nothrow specification here so that the calls
/// to this operator will not perform a null check on the result -- the
diff --git a/include/clang/AST/ASTImporter.h b/include/clang/AST/ASTImporter.h
index 46a9881039c7..1672ab22a3de 100644
--- a/include/clang/AST/ASTImporter.h
+++ b/include/clang/AST/ASTImporter.h
@@ -48,6 +48,9 @@ namespace clang {
/// \brief Whether to perform a minimal import.
bool Minimal;
+
+ /// \brief Whether the last diagnostic came from the "from" context.
+ bool LastDiagFromFrom;
/// \brief Mapping from the already-imported types in the "from" context
/// to the corresponding types in the "to" context.
diff --git a/include/clang/AST/ASTMutationListener.h b/include/clang/AST/ASTMutationListener.h
index 56d15260a581..6b70285e3ad8 100644
--- a/include/clang/AST/ASTMutationListener.h
+++ b/include/clang/AST/ASTMutationListener.h
@@ -16,18 +16,19 @@
#include "clang/Basic/SourceLocation.h"
namespace clang {
- class Decl;
- class DeclContext;
- class TagDecl;
class CXXRecordDecl;
class ClassTemplateDecl;
class ClassTemplateSpecializationDecl;
+ class Decl;
+ class DeclContext;
class FunctionDecl;
class FunctionTemplateDecl;
class ObjCCategoryDecl;
- class ObjCInterfaceDecl;
class ObjCContainerDecl;
+ class ObjCInterfaceDecl;
class ObjCPropertyDecl;
+ class TagDecl;
+ class VarDecl;
/// \brief An abstract interface that should be implemented by listeners
/// that want to be notified when an AST entity gets modified after its
diff --git a/include/clang/ASTMatchers/ASTTypeTraits.h b/include/clang/AST/ASTTypeTraits.h
index bda53eaf70f6..4688b12de701 100644
--- a/include/clang/ASTMatchers/ASTTypeTraits.h
+++ b/include/clang/AST/ASTTypeTraits.h
@@ -1,4 +1,4 @@
-//===--- ASTMatchersTypeTraits.h --------------------------------*- C++ -*-===//
+//===--- ASTTypeTraits.h ----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,11 +12,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_MATCHERS_AST_TYPE_TRAITS_H
-#define LLVM_CLANG_AST_MATCHERS_AST_TYPE_TRAITS_H
+#ifndef LLVM_CLANG_AST_AST_TYPE_TRAITS_H
+#define LLVM_CLANG_AST_AST_TYPE_TRAITS_H
#include "clang/AST/Decl.h"
#include "clang/AST/Stmt.h"
+#include "clang/AST/TypeLoc.h"
#include "llvm/Support/AlignOf.h"
namespace clang {
@@ -87,8 +88,9 @@ private:
/// 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;
+ llvm::AlignedCharArrayUnion<Decl *, Stmt *, NestedNameSpecifier,
+ NestedNameSpecifierLoc, QualType, Type,
+ TypeLoc> Storage;
};
// FIXME: Pull out abstraction for the following.
@@ -206,4 +208,4 @@ inline const void *DynTypedNode::getMemoizationData() const {
} // end namespace ast_type_traits
} // end namespace clang
-#endif // LLVM_CLANG_AST_MATCHERS_AST_TYPE_TRAITS_H
+#endif // LLVM_CLANG_AST_AST_TYPE_TRAITS_H
diff --git a/include/clang/AST/ASTUnresolvedSet.h b/include/clang/AST/ASTUnresolvedSet.h
new file mode 100644
index 000000000000..c709895fc0f4
--- /dev/null
+++ b/include/clang/AST/ASTUnresolvedSet.h
@@ -0,0 +1,86 @@
+//===-- ASTUnresolvedSet.h - Unresolved sets of declarations ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides an UnresolvedSet-like class, whose contents are
+// allocated using the allocator associated with an ASTContext.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_ASTUNRESOLVEDSET_H
+#define LLVM_CLANG_AST_ASTUNRESOLVEDSET_H
+
+#include "clang/AST/ASTVector.h"
+#include "clang/AST/UnresolvedSet.h"
+
+namespace clang {
+
+/// \brief An UnresolvedSet-like class which uses the ASTContext's allocator.
+class ASTUnresolvedSet {
+ typedef ASTVector<DeclAccessPair> DeclsTy;
+ DeclsTy Decls;
+
+ ASTUnresolvedSet(const ASTUnresolvedSet &) LLVM_DELETED_FUNCTION;
+ void operator=(const ASTUnresolvedSet &) LLVM_DELETED_FUNCTION;
+
+public:
+ ASTUnresolvedSet() {}
+ ASTUnresolvedSet(ASTContext &C, unsigned N) : Decls(C, N) {}
+
+ typedef UnresolvedSetIterator iterator;
+ typedef UnresolvedSetIterator const_iterator;
+
+ iterator begin() { return iterator(Decls.begin()); }
+ iterator end() { return iterator(Decls.end()); }
+
+ const_iterator begin() const { return const_iterator(Decls.begin()); }
+ const_iterator end() const { return const_iterator(Decls.end()); }
+
+ void addDecl(ASTContext &C, NamedDecl *D) {
+ addDecl(C, D, AS_none);
+ }
+
+ void addDecl(ASTContext &C, NamedDecl *D, AccessSpecifier AS) {
+ Decls.push_back(DeclAccessPair::make(D, AS), C);
+ }
+
+ /// Replaces the given declaration with the new one, once.
+ ///
+ /// \return true if the set changed
+ bool replace(const NamedDecl* Old, NamedDecl *New) {
+ for (DeclsTy::iterator I = Decls.begin(), E = Decls.end(); I != E; ++I)
+ if (I->getDecl() == Old)
+ return (I->setDecl(New), true);
+ return false;
+ }
+
+ void erase(unsigned I) {
+ Decls[I] = Decls.back();
+ Decls.pop_back();
+ }
+
+ void clear() { Decls.clear(); }
+
+ bool empty() const { return Decls.empty(); }
+ unsigned size() const { return Decls.size(); }
+
+ void reserve(ASTContext &C, unsigned N) {
+ Decls.reserve(C, N);
+ }
+
+ void append(ASTContext &C, iterator I, iterator E) {
+ Decls.append(C, I.ir, E.ir);
+ }
+
+ DeclAccessPair &operator[](unsigned I) { return Decls[I]; }
+ const DeclAccessPair &operator[](unsigned I) const { return Decls[I]; }
+};
+
+} // namespace clang
+
+#endif
diff --git a/include/clang/AST/ASTVector.h b/include/clang/AST/ASTVector.h
index 4ff5ea37b882..669e50dbeb87 100644
--- a/include/clang/AST/ASTVector.h
+++ b/include/clang/AST/ASTVector.h
@@ -18,12 +18,13 @@
#ifndef LLVM_CLANG_AST_VECTOR
#define LLVM_CLANG_AST_VECTOR
-#include "llvm/Support/type_traits.h"
-#include "llvm/Support/Allocator.h"
+#include "clang/AST/AttrIterator.h"
#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/type_traits.h"
#include <algorithm>
-#include <memory>
#include <cstring>
+#include <memory>
#ifdef _MSC_VER
namespace std {
@@ -50,6 +51,7 @@ namespace std {
#endif
namespace clang {
+ class ASTContext;
template<typename T>
class ASTVector {
@@ -59,7 +61,9 @@ class ASTVector {
public:
// Default ctor - Initialize to empty.
- explicit ASTVector(ASTContext &C, unsigned N = 0)
+ ASTVector() : Begin(NULL), End(NULL), Capacity(NULL) { }
+
+ ASTVector(ASTContext &C, unsigned N)
: Begin(NULL), End(NULL), Capacity(NULL) {
reserve(C, N);
}
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index 12a9855617c0..27dcef2a1e98 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -14,9 +14,10 @@
#ifndef LLVM_CLANG_AST_ATTR_H
#define LLVM_CLANG_AST_ATTR_H
-#include "clang/Basic/LLVM.h"
-#include "clang/Basic/AttrKinds.h"
+#include "clang/AST/AttrIterator.h"
#include "clang/AST/Type.h"
+#include "clang/Basic/AttrKinds.h"
+#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/VersionTuple.h"
#include "llvm/ADT/SmallVector.h"
@@ -26,7 +27,6 @@
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <cstring>
-#include <algorithm>
namespace clang {
class ASTContext;
@@ -36,23 +36,6 @@ namespace clang {
class QualType;
class FunctionDecl;
class TypeSourceInfo;
-}
-
-// Defined in ASTContext.h
-void *operator new(size_t Bytes, const clang::ASTContext &C,
- size_t Alignment = 16);
-// FIXME: Being forced to not have a default argument here due to redeclaration
-// rules on default arguments sucks
-void *operator new[](size_t Bytes, const clang::ASTContext &C,
- size_t Alignment);
-
-// It is good practice to pair new/delete operators. Also, MSVC gives many
-// warnings if a matching delete overload is not declared, even though the
-// throw() spec guarantees it will not be implicitly called.
-void operator delete(void *Ptr, const clang::ASTContext &C, size_t);
-void operator delete[](void *Ptr, const clang::ASTContext &C, size_t);
-
-namespace clang {
/// Attr - This represents one attribute.
class Attr {
@@ -61,10 +44,16 @@ private:
unsigned AttrKind : 16;
protected:
+ /// An index into the spelling list of an
+ /// attribute defined in Attr.td file.
+ unsigned SpellingListIndex : 4;
+
bool Inherited : 1;
+ bool IsPackExpansion : 1;
+
virtual ~Attr();
-
+
void* operator new(size_t bytes) throw() {
llvm_unreachable("Attrs cannot be allocated with regular 'new'.");
}
@@ -84,14 +73,17 @@ public:
}
protected:
- Attr(attr::Kind AK, SourceRange R)
- : Range(R), AttrKind(AK), Inherited(false) {}
+ Attr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex = 0)
+ : Range(R), AttrKind(AK), SpellingListIndex(SpellingListIndex),
+ Inherited(false), IsPackExpansion(false) {}
public:
attr::Kind getKind() const {
return static_cast<attr::Kind>(AttrKind);
}
+
+ unsigned getSpellingListIndex() const { return SpellingListIndex; }
SourceLocation getLocation() const { return Range.getBegin(); }
SourceRange getRange() const { return Range; }
@@ -99,21 +91,24 @@ public:
bool isInherited() const { return Inherited; }
+ void setPackExpansion(bool PE) { IsPackExpansion = PE; }
+ bool isPackExpansion() const { return IsPackExpansion; }
+
// Clone this attribute.
- virtual Attr* clone(ASTContext &C) const = 0;
+ virtual Attr *clone(ASTContext &C) const = 0;
virtual bool isLateParsed() const { return false; }
// Pretty print this attribute.
- virtual void printPretty(llvm::raw_ostream &OS,
+ virtual void printPretty(raw_ostream &OS,
const PrintingPolicy &Policy) const = 0;
};
class InheritableAttr : public Attr {
virtual void anchor();
protected:
- InheritableAttr(attr::Kind AK, SourceRange R)
- : Attr(AK, R) {}
+ InheritableAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex = 0)
+ : Attr(AK, R, SpellingListIndex) {}
public:
void setInherited(bool I) { Inherited = I; }
@@ -127,125 +122,35 @@ public:
class InheritableParamAttr : public InheritableAttr {
virtual void anchor();
protected:
- InheritableParamAttr(attr::Kind AK, SourceRange R)
- : InheritableAttr(AK, R) {}
+ InheritableParamAttr(attr::Kind AK, SourceRange R,
+ unsigned SpellingListIndex = 0)
+ : InheritableAttr(AK, R, SpellingListIndex) {}
public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Attr *A) {
+ // Relies on relative order of enum emission with respect to MS inheritance
+ // attrs.
return A->getKind() <= attr::LAST_INHERITABLE_PARAM;
}
};
-#include "clang/AST/Attrs.inc"
-
-/// AttrVec - A vector of Attr, which is how they are stored on the AST.
-typedef SmallVector<Attr*, 2> AttrVec;
-typedef SmallVector<const Attr*, 2> ConstAttrVec;
-
-/// specific_attr_iterator - Iterates over a subrange of an AttrVec, only
-/// providing attributes that are of a specifc type.
-template <typename SpecificAttr, typename Container = AttrVec>
-class specific_attr_iterator {
- typedef typename Container::const_iterator Iterator;
-
- /// Current - The current, underlying iterator.
- /// In order to ensure we don't dereference an invalid iterator unless
- /// specifically requested, we don't necessarily advance this all the
- /// way. Instead, we advance it when an operation is requested; if the
- /// operation is acting on what should be a past-the-end iterator,
- /// then we offer no guarantees, but this way we do not dererence a
- /// past-the-end iterator when we move to a past-the-end position.
- mutable Iterator Current;
-
- void AdvanceToNext() const {
- while (!isa<SpecificAttr>(*Current))
- ++Current;
- }
-
- void AdvanceToNext(Iterator I) const {
- while (Current != I && !isa<SpecificAttr>(*Current))
- ++Current;
- }
+class MSInheritanceAttr : public InheritableAttr {
+ virtual void anchor();
+protected:
+ MSInheritanceAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex = 0)
+ : InheritableAttr(AK, R, SpellingListIndex) {}
public:
- typedef SpecificAttr* value_type;
- typedef SpecificAttr* reference;
- typedef SpecificAttr* pointer;
- typedef std::forward_iterator_tag iterator_category;
- typedef std::ptrdiff_t difference_type;
-
- specific_attr_iterator() : Current() { }
- explicit specific_attr_iterator(Iterator i) : Current(i) { }
-
- reference operator*() const {
- AdvanceToNext();
- return cast<SpecificAttr>(*Current);
- }
- pointer operator->() const {
- AdvanceToNext();
- return cast<SpecificAttr>(*Current);
- }
-
- specific_attr_iterator& operator++() {
- ++Current;
- return *this;
- }
- specific_attr_iterator operator++(int) {
- specific_attr_iterator Tmp(*this);
- ++(*this);
- return Tmp;
- }
-
- friend bool operator==(specific_attr_iterator Left,
- specific_attr_iterator Right) {
- if (Left.Current < Right.Current)
- Left.AdvanceToNext(Right.Current);
- else
- Right.AdvanceToNext(Left.Current);
- return Left.Current == Right.Current;
- }
- friend bool operator!=(specific_attr_iterator Left,
- specific_attr_iterator Right) {
- return !(Left == Right);
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Attr *A) {
+ // Relies on relative order of enum emission with respect to param attrs.
+ return (A->getKind() <= attr::LAST_MS_INHERITABLE &&
+ A->getKind() > attr::LAST_INHERITABLE_PARAM);
}
};
-template <typename SpecificAttr, typename Container>
-inline specific_attr_iterator<SpecificAttr, Container>
- specific_attr_begin(const Container& container) {
- return specific_attr_iterator<SpecificAttr, Container>(container.begin());
-}
-template <typename SpecificAttr, typename Container>
-inline specific_attr_iterator<SpecificAttr, Container>
- specific_attr_end(const Container& container) {
- return specific_attr_iterator<SpecificAttr, Container>(container.end());
-}
-
-template <typename SpecificAttr, typename Container>
-inline bool hasSpecificAttr(const Container& container) {
- return specific_attr_begin<SpecificAttr>(container) !=
- specific_attr_end<SpecificAttr>(container);
-}
-template <typename SpecificAttr, typename Container>
-inline SpecificAttr *getSpecificAttr(const Container& container) {
- specific_attr_iterator<SpecificAttr, Container> i =
- specific_attr_begin<SpecificAttr>(container);
- if (i != specific_attr_end<SpecificAttr>(container))
- return *i;
- else
- return 0;
-}
-
-/// getMaxAlignment - Returns the highest alignment value found among
-/// AlignedAttrs in an AttrVec, or 0 if there are none.
-inline unsigned getMaxAttrAlignment(const AttrVec& V, ASTContext &Ctx) {
- unsigned Align = 0;
- specific_attr_iterator<AlignedAttr> i(V.begin()), e(V.end());
- for(; i != e; ++i)
- Align = std::max(Align, i->getAlignment(Ctx));
- return Align;
-}
+#include "clang/AST/Attrs.inc"
} // end namespace clang
diff --git a/include/clang/AST/AttrIterator.h b/include/clang/AST/AttrIterator.h
new file mode 100644
index 000000000000..8bd8fbec895d
--- /dev/null
+++ b/include/clang/AST/AttrIterator.h
@@ -0,0 +1,142 @@
+//===--- AttrIterator.h - Classes for attribute iteration -------*- 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 Attr vector and specific_attr_iterator interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_ATTRITERATOR_H
+#define LLVM_CLANG_AST_ATTRITERATOR_H
+
+#include "clang/Basic/LLVM.h"
+#include <iterator>
+
+namespace clang {
+ class ASTContext;
+ class Attr;
+}
+
+// Defined in ASTContext.h
+void *operator new(size_t Bytes, const clang::ASTContext &C,
+ size_t Alignment = 16);
+// FIXME: Being forced to not have a default argument here due to redeclaration
+// rules on default arguments sucks
+void *operator new[](size_t Bytes, const clang::ASTContext &C,
+ size_t Alignment);
+
+// It is good practice to pair new/delete operators. Also, MSVC gives many
+// warnings if a matching delete overload is not declared, even though the
+// throw() spec guarantees it will not be implicitly called.
+void operator delete(void *Ptr, const clang::ASTContext &C, size_t);
+void operator delete[](void *Ptr, const clang::ASTContext &C, size_t);
+
+namespace clang {
+
+/// AttrVec - A vector of Attr, which is how they are stored on the AST.
+typedef SmallVector<Attr*, 2> AttrVec;
+typedef SmallVector<const Attr*, 2> ConstAttrVec;
+
+/// specific_attr_iterator - Iterates over a subrange of an AttrVec, only
+/// providing attributes that are of a specifc type.
+template <typename SpecificAttr, typename Container = AttrVec>
+class specific_attr_iterator {
+ typedef typename Container::const_iterator Iterator;
+
+ /// Current - The current, underlying iterator.
+ /// In order to ensure we don't dereference an invalid iterator unless
+ /// specifically requested, we don't necessarily advance this all the
+ /// way. Instead, we advance it when an operation is requested; if the
+ /// operation is acting on what should be a past-the-end iterator,
+ /// then we offer no guarantees, but this way we do not dererence a
+ /// past-the-end iterator when we move to a past-the-end position.
+ mutable Iterator Current;
+
+ void AdvanceToNext() const {
+ while (!isa<SpecificAttr>(*Current))
+ ++Current;
+ }
+
+ void AdvanceToNext(Iterator I) const {
+ while (Current != I && !isa<SpecificAttr>(*Current))
+ ++Current;
+ }
+
+public:
+ typedef SpecificAttr* value_type;
+ typedef SpecificAttr* reference;
+ typedef SpecificAttr* pointer;
+ typedef std::forward_iterator_tag iterator_category;
+ typedef std::ptrdiff_t difference_type;
+
+ specific_attr_iterator() : Current() { }
+ explicit specific_attr_iterator(Iterator i) : Current(i) { }
+
+ reference operator*() const {
+ AdvanceToNext();
+ return cast<SpecificAttr>(*Current);
+ }
+ pointer operator->() const {
+ AdvanceToNext();
+ return cast<SpecificAttr>(*Current);
+ }
+
+ specific_attr_iterator& operator++() {
+ ++Current;
+ return *this;
+ }
+ specific_attr_iterator operator++(int) {
+ specific_attr_iterator Tmp(*this);
+ ++(*this);
+ return Tmp;
+ }
+
+ friend bool operator==(specific_attr_iterator Left,
+ specific_attr_iterator Right) {
+ assert((Left.Current == 0) == (Right.Current == 0));
+ if (Left.Current < Right.Current)
+ Left.AdvanceToNext(Right.Current);
+ else
+ Right.AdvanceToNext(Left.Current);
+ return Left.Current == Right.Current;
+ }
+ friend bool operator!=(specific_attr_iterator Left,
+ specific_attr_iterator Right) {
+ return !(Left == Right);
+ }
+};
+
+template <typename SpecificAttr, typename Container>
+inline specific_attr_iterator<SpecificAttr, Container>
+ specific_attr_begin(const Container& container) {
+ return specific_attr_iterator<SpecificAttr, Container>(container.begin());
+}
+template <typename SpecificAttr, typename Container>
+inline specific_attr_iterator<SpecificAttr, Container>
+ specific_attr_end(const Container& container) {
+ return specific_attr_iterator<SpecificAttr, Container>(container.end());
+}
+
+template <typename SpecificAttr, typename Container>
+inline bool hasSpecificAttr(const Container& container) {
+ return specific_attr_begin<SpecificAttr>(container) !=
+ specific_attr_end<SpecificAttr>(container);
+}
+template <typename SpecificAttr, typename Container>
+inline SpecificAttr *getSpecificAttr(const Container& container) {
+ specific_attr_iterator<SpecificAttr, Container> i =
+ specific_attr_begin<SpecificAttr>(container);
+ if (i != specific_attr_end<SpecificAttr>(container))
+ return *i;
+ else
+ return 0;
+}
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/AST/BuiltinTypes.def b/include/clang/AST/BuiltinTypes.def
index ba322fb32655..488cacef0af3 100644
--- a/include/clang/AST/BuiltinTypes.def
+++ b/include/clang/AST/BuiltinTypes.def
@@ -154,6 +154,20 @@ BUILTIN_TYPE(ObjCClass, ObjCBuiltinClassTy)
// type is a typedef of a PointerType to this.
BUILTIN_TYPE(ObjCSel, ObjCBuiltinSelTy)
+// OpenCL image types.
+BUILTIN_TYPE(OCLImage1d, OCLImage1dTy)
+BUILTIN_TYPE(OCLImage1dArray, OCLImage1dArrayTy)
+BUILTIN_TYPE(OCLImage1dBuffer, OCLImage1dBufferTy)
+BUILTIN_TYPE(OCLImage2d, OCLImage2dTy)
+BUILTIN_TYPE(OCLImage2dArray, OCLImage2dArrayTy)
+BUILTIN_TYPE(OCLImage3d, OCLImage3dTy)
+
+// OpenCL sampler_t.
+BUILTIN_TYPE(OCLSampler, OCLSamplerTy)
+
+// OpenCL event_t.
+BUILTIN_TYPE(OCLEvent, OCLEventTy)
+
// This represents the type of an expression whose type is
// totally unknown, e.g. 'T::foo'. It is permitted for this to
// appear in situations where the structure of the type is
diff --git a/include/clang/AST/CMakeLists.txt b/include/clang/AST/CMakeLists.txt
index 4c4c0fb0a08b..ba54fa2aa92b 100644
--- a/include/clang/AST/CMakeLists.txt
+++ b/include/clang/AST/CMakeLists.txt
@@ -8,6 +8,11 @@ clang_tablegen(AttrImpl.inc -gen-clang-attr-impl
SOURCE ../Basic/Attr.td
TARGET ClangAttrImpl)
+clang_tablegen(AttrDump.inc -gen-clang-attr-dump
+ -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
+ SOURCE ../Basic/Attr.td
+ TARGET ClangAttrDump)
+
clang_tablegen(StmtNodes.inc -gen-clang-stmt-nodes
SOURCE ../Basic/StmtNodes.td
TARGET ClangStmtNodes)
@@ -28,7 +33,15 @@ clang_tablegen(CommentHTMLTagsProperties.inc -gen-clang-comment-html-tags-proper
SOURCE CommentHTMLTags.td
TARGET ClangCommentHTMLTagsProperties)
+clang_tablegen(CommentHTMLNamedCharacterReferences.inc -gen-clang-comment-html-named-character-references
+ SOURCE CommentHTMLNamedCharacterReferences.td
+ TARGET ClangCommentHTMLNamedCharacterReferences)
+
clang_tablegen(CommentCommandInfo.inc -gen-clang-comment-command-info
SOURCE CommentCommands.td
TARGET ClangCommentCommandInfo)
+clang_tablegen(CommentCommandList.inc -gen-clang-comment-command-list
+ SOURCE CommentCommands.td
+ TARGET ClangCommentCommandList)
+
diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h
index 87bdbe04f3df..2983e04cda34 100644
--- a/include/clang/AST/CXXInheritance.h
+++ b/include/clang/AST/CXXInheritance.h
@@ -14,17 +14,17 @@
#ifndef LLVM_CLANG_AST_CXXINHERITANCE_H
#define LLVM_CLANG_AST_CXXINHERITANCE_H
-#include "clang/AST/DeclarationName.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclarationName.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeOrdering.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
+#include <cassert>
#include <list>
#include <map>
-#include <cassert>
namespace clang {
diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h
index ea307bf307cb..946075739d06 100644
--- a/include/clang/AST/CanonicalType.h
+++ b/include/clang/AST/CanonicalType.h
@@ -351,15 +351,12 @@ namespace llvm {
/// CanQual<T> to a specific Type class. We're prefer isa/dyn_cast/cast/etc.
/// to return smart pointer (proxies?).
template<typename T>
-struct simplify_type<const ::clang::CanQual<T> > {
+struct simplify_type< ::clang::CanQual<T> > {
typedef const T *SimpleType;
- static SimpleType getSimplifiedValue(const ::clang::CanQual<T> &Val) {
+ static SimpleType getSimplifiedValue(::clang::CanQual<T> Val) {
return Val.getTypePtr();
}
};
-template<typename T>
-struct simplify_type< ::clang::CanQual<T> >
-: public simplify_type<const ::clang::CanQual<T> > {};
// Teach SmallPtrSet that CanQual<T> is "basically a pointer".
template<typename T>
@@ -514,55 +511,13 @@ struct CanProxyAdaptor<MemberPointerType>
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Type *, getClass)
};
-template<>
-struct CanProxyAdaptor<ArrayType> : public CanProxyBase<ArrayType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
- getSizeModifier)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
-};
-
-template<>
-struct CanProxyAdaptor<ConstantArrayType>
- : public CanProxyBase<ConstantArrayType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
- getSizeModifier)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const llvm::APInt &, getSize)
-};
-
-template<>
-struct CanProxyAdaptor<IncompleteArrayType>
- : public CanProxyBase<IncompleteArrayType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
- getSizeModifier)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
-};
-
-template<>
-struct CanProxyAdaptor<VariableArrayType>
- : public CanProxyBase<VariableArrayType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
- getSizeModifier)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getSizeExpr)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceRange, getBracketsRange)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getLBracketLoc)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getRBracketLoc)
-};
-
-template<>
-struct CanProxyAdaptor<DependentSizedArrayType>
- : public CanProxyBase<DependentSizedArrayType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getSizeExpr)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceRange, getBracketsRange)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getLBracketLoc)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getRBracketLoc)
-};
+// CanProxyAdaptors for arrays are intentionally unimplemented because
+// they are not safe.
+template<> struct CanProxyAdaptor<ArrayType>;
+template<> struct CanProxyAdaptor<ConstantArrayType>;
+template<> struct CanProxyAdaptor<IncompleteArrayType>;
+template<> struct CanProxyAdaptor<VariableArrayType>;
+template<> struct CanProxyAdaptor<DependentSizedArrayType>;
template<>
struct CanProxyAdaptor<DependentSizedExtVectorType>
@@ -746,6 +701,9 @@ CanQual<T> CanQual<T>::CreateUnsafe(QualType Other) {
template<typename T>
template<typename U>
CanProxy<U> CanQual<T>::getAs() const {
+ ArrayType_cannot_be_used_with_getAs<U> at;
+ (void)at;
+
if (Stored.isNull())
return CanProxy<U>();
@@ -758,6 +716,9 @@ CanProxy<U> CanQual<T>::getAs() const {
template<typename T>
template<typename U>
CanProxy<U> CanQual<T>::castAs() const {
+ ArrayType_cannot_be_used_with_getAs<U> at;
+ (void)at;
+
assert(!Stored.isNull() && isa<U>(Stored.getTypePtr()));
return CanQual<U>::CreateUnsafe(Stored);
}
diff --git a/include/clang/AST/CharUnits.h b/include/clang/AST/CharUnits.h
index 12e74b32be8a..082c672c2191 100644
--- a/include/clang/AST/CharUnits.h
+++ b/include/clang/AST/CharUnits.h
@@ -171,6 +171,17 @@ namespace clang {
Align.Quantity));
}
+ /// Given that this is a non-zero alignment value, what is the
+ /// alignment at the given offset?
+ CharUnits alignmentAtOffset(CharUnits offset) {
+ // alignment: 0010000
+ // offset: 1011100
+ // lowBits: 0001011
+ // result: 0000100
+ QuantityType lowBits = (Quantity-1) & (offset.Quantity-1);
+ return CharUnits((lowBits + 1) & ~lowBits);
+ }
+
}; // class CharUnit
} // namespace clang
diff --git a/include/clang/AST/Comment.h b/include/clang/AST/Comment.h
index 316a1801bd46..c02a82f0fa55 100644
--- a/include/clang/AST/Comment.h
+++ b/include/clang/AST/Comment.h
@@ -14,10 +14,10 @@
#ifndef LLVM_CLANG_AST_COMMENT_H
#define LLVM_CLANG_AST_COMMENT_H
-#include "clang/Basic/SourceLocation.h"
-#include "clang/AST/Type.h"
#include "clang/AST/CommentCommandTraits.h"
#include "clang/AST/DeclObjC.h"
+#include "clang/AST/Type.h"
+#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
@@ -28,6 +28,26 @@ class TemplateParameterList;
namespace comments {
class FullComment;
+
+/// Describes the syntax that was used in a documentation command.
+///
+/// Exact values of this enumeration are important because they used to select
+/// parts of diagnostic messages. Audit diagnostics before changing or adding
+/// a new value.
+enum CommandMarkerKind {
+ /// Command started with a backslash character:
+ /// \code
+ /// \foo
+ /// \endcode
+ CMK_Backslash = 0,
+
+ /// Command started with an 'at' character:
+ /// \code
+ /// @foo
+ /// \endcode
+ CMK_At = 1
+};
+
/// Any part of the comment.
/// Abstract class.
class Comment {
@@ -110,8 +130,12 @@ protected:
unsigned : NumCommentBits;
unsigned CommandID : 8;
+
+ /// Describes the syntax that was used in a documentation command.
+ /// Contains values from CommandMarkerKind enum.
+ unsigned CommandMarker : 1;
};
- enum { NumBlockCommandCommentBits = NumCommentBits + 8 };
+ enum { NumBlockCommandCommentBits = NumCommentBits + 9 };
class ParamCommandCommentBitfields {
friend class ParamCommandComment;
@@ -171,8 +195,9 @@ public:
const char *getCommentKindName() const;
LLVM_ATTRIBUTE_USED void dump() const;
+ LLVM_ATTRIBUTE_USED void dumpColor() const;
LLVM_ATTRIBUTE_USED void dump(const ASTContext &Context) const;
- void dump(llvm::raw_ostream &OS, const CommandTraits *Traits,
+ void dump(raw_ostream &OS, const CommandTraits *Traits,
const SourceManager *SM) const;
SourceRange getSourceRange() const LLVM_READONLY { return Range; }
@@ -282,14 +307,14 @@ public:
protected:
/// Command arguments.
- llvm::ArrayRef<Argument> Args;
+ ArrayRef<Argument> Args;
public:
InlineCommandComment(SourceLocation LocBegin,
SourceLocation LocEnd,
unsigned CommandID,
RenderKind RK,
- llvm::ArrayRef<Argument> Args) :
+ ArrayRef<Argument> Args) :
InlineContentComment(InlineCommandCommentKind, LocBegin, LocEnd),
Args(Args) {
InlineCommandCommentBits.RenderKind = RK;
@@ -504,10 +529,10 @@ public:
/// A single paragraph that contains inline content.
class ParagraphComment : public BlockContentComment {
- llvm::ArrayRef<InlineContentComment *> Content;
+ ArrayRef<InlineContentComment *> Content;
public:
- ParagraphComment(llvm::ArrayRef<InlineContentComment *> Content) :
+ ParagraphComment(ArrayRef<InlineContentComment *> Content) :
BlockContentComment(ParagraphCommentKind,
SourceLocation(),
SourceLocation()),
@@ -565,7 +590,7 @@ public:
protected:
/// Word-like arguments.
- llvm::ArrayRef<Argument> Args;
+ ArrayRef<Argument> Args;
/// Paragraph argument.
ParagraphComment *Paragraph;
@@ -573,21 +598,25 @@ protected:
BlockCommandComment(CommentKind K,
SourceLocation LocBegin,
SourceLocation LocEnd,
- unsigned CommandID) :
+ unsigned CommandID,
+ CommandMarkerKind CommandMarker) :
BlockContentComment(K, LocBegin, LocEnd),
Paragraph(NULL) {
setLocation(getCommandNameBeginLoc());
BlockCommandCommentBits.CommandID = CommandID;
+ BlockCommandCommentBits.CommandMarker = CommandMarker;
}
public:
BlockCommandComment(SourceLocation LocBegin,
SourceLocation LocEnd,
- unsigned CommandID) :
+ unsigned CommandID,
+ CommandMarkerKind CommandMarker) :
BlockContentComment(BlockCommandCommentKind, LocBegin, LocEnd),
Paragraph(NULL) {
setLocation(getCommandNameBeginLoc());
BlockCommandCommentBits.CommandID = CommandID;
+ BlockCommandCommentBits.CommandMarker = CommandMarker;
}
static bool classof(const Comment *C) {
@@ -633,7 +662,7 @@ public:
return Args[Idx].Range;
}
- void setArgs(llvm::ArrayRef<Argument> A) {
+ void setArgs(ArrayRef<Argument> A) {
Args = A;
if (Args.size() > 0) {
SourceLocation NewLocEnd = Args.back().Range.getEnd();
@@ -656,6 +685,11 @@ public:
if (NewLocEnd.isValid())
setSourceRange(SourceRange(getLocStart(), NewLocEnd));
}
+
+ CommandMarkerKind getCommandMarker() const LLVM_READONLY {
+ return static_cast<CommandMarkerKind>(
+ BlockCommandCommentBits.CommandMarker);
+ }
};
/// Doxygen \\param command.
@@ -669,9 +703,10 @@ public:
ParamCommandComment(SourceLocation LocBegin,
SourceLocation LocEnd,
- unsigned CommandID) :
+ unsigned CommandID,
+ CommandMarkerKind CommandMarker) :
BlockCommandComment(ParamCommandCommentKind, LocBegin, LocEnd,
- CommandID),
+ CommandID, CommandMarker),
ParamIndex(InvalidParamIndex) {
ParamCommandCommentBits.Direction = In;
ParamCommandCommentBits.IsDirectionExplicit = false;
@@ -746,13 +781,15 @@ private:
/// For C: Position = { 0 }
/// For TT: Position = { 1 }
/// For T: Position = { 1, 0 }
- llvm::ArrayRef<unsigned> Position;
+ ArrayRef<unsigned> Position;
public:
TParamCommandComment(SourceLocation LocBegin,
SourceLocation LocEnd,
- unsigned CommandID) :
- BlockCommandComment(TParamCommandCommentKind, LocBegin, LocEnd, CommandID)
+ unsigned CommandID,
+ CommandMarkerKind CommandMarker) :
+ BlockCommandComment(TParamCommandCommentKind, LocBegin, LocEnd, CommandID,
+ CommandMarker)
{ }
static bool classof(const Comment *C) {
@@ -826,14 +863,15 @@ class VerbatimBlockComment : public BlockCommandComment {
protected:
StringRef CloseName;
SourceLocation CloseNameLocBegin;
- llvm::ArrayRef<VerbatimBlockLineComment *> Lines;
+ ArrayRef<VerbatimBlockLineComment *> Lines;
public:
VerbatimBlockComment(SourceLocation LocBegin,
SourceLocation LocEnd,
unsigned CommandID) :
BlockCommandComment(VerbatimBlockCommentKind,
- LocBegin, LocEnd, CommandID)
+ LocBegin, LocEnd, CommandID,
+ CMK_At) // FIXME: improve source fidelity.
{ }
static bool classof(const Comment *C) {
@@ -853,7 +891,7 @@ public:
CloseNameLocBegin = LocBegin;
}
- void setLines(llvm::ArrayRef<VerbatimBlockLineComment *> L) {
+ void setLines(ArrayRef<VerbatimBlockLineComment *> L) {
Lines = L;
}
@@ -886,7 +924,8 @@ public:
StringRef Text) :
BlockCommandComment(VerbatimLineCommentKind,
LocBegin, LocEnd,
- CommandID),
+ CommandID,
+ CMK_At), // FIXME: improve source fidelity.
Text(Text),
TextBegin(TextBegin)
{ }
@@ -1021,11 +1060,11 @@ struct DeclInfo {
/// A full comment attached to a declaration, contains block content.
class FullComment : public Comment {
- llvm::ArrayRef<BlockContentComment *> Blocks;
+ ArrayRef<BlockContentComment *> Blocks;
DeclInfo *ThisDeclInfo;
public:
- FullComment(llvm::ArrayRef<BlockContentComment *> Blocks, DeclInfo *D) :
+ FullComment(ArrayRef<BlockContentComment *> Blocks, DeclInfo *D) :
Comment(FullCommentKind, SourceLocation(), SourceLocation()),
Blocks(Blocks), ThisDeclInfo(D) {
if (Blocks.empty())
@@ -1062,7 +1101,7 @@ public:
return ThisDeclInfo;
}
- llvm::ArrayRef<BlockContentComment *> getBlocks() const { return Blocks; }
+ ArrayRef<BlockContentComment *> getBlocks() const { return Blocks; }
};
} // end namespace comments
diff --git a/include/clang/AST/CommentCommandTraits.h b/include/clang/AST/CommentCommandTraits.h
index 6d44c706c3dc..d1f5209d1eef 100644
--- a/include/clang/AST/CommentCommandTraits.h
+++ b/include/clang/AST/CommentCommandTraits.h
@@ -16,9 +16,10 @@
#ifndef LLVM_CLANG_AST_COMMENT_COMMAND_TRAITS_H
#define LLVM_CLANG_AST_COMMENT_COMMAND_TRAITS_H
+#include "clang/Basic/CommentOptions.h"
#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/ErrorHandling.h"
@@ -69,6 +70,9 @@ struct CommandInfo {
/// True if this command is \\deprecated or an alias.
unsigned IsDeprecatedCommand : 1;
+ /// \brief True if this is a \\headerfile-like command.
+ unsigned IsHeaderfileCommand : 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;
@@ -96,7 +100,17 @@ struct CommandInfo {
/// \fn void f(int a);
/// \endcode
unsigned IsDeclarationCommand : 1;
-
+
+ /// \brief True if verbatim-like line command is a function declaration.
+ unsigned IsFunctionDeclarationCommand : 1;
+
+ /// \brief True if block command is further describing a container API; such
+ /// as \@coclass, \@classdesign, etc.
+ unsigned IsRecordLikeDetailCommand : 1;
+
+ /// \brief True if block command is a container API; such as \@interface.
+ unsigned IsRecordLikeDeclarationCommand : 1;
+
/// \brief True if this command is unknown. This \c CommandInfo object was
/// created during parsing.
unsigned IsUnknownCommand : 1;
@@ -106,7 +120,17 @@ struct CommandInfo {
/// in comments.
class CommandTraits {
public:
- CommandTraits(llvm::BumpPtrAllocator &Allocator);
+ enum KnownCommandIDs {
+#define COMMENT_COMMAND(NAME) KCI_##NAME,
+#include "clang/AST/CommentCommandList.inc"
+#undef COMMENT_COMMAND
+ KCI_Last
+ };
+
+ CommandTraits(llvm::BumpPtrAllocator &Allocator,
+ const CommentOptions &CommentOptions);
+
+ void registerCommentOptions(const CommentOptions &CommentOptions);
/// \returns a CommandInfo object for a given command name or
/// NULL if no CommandInfo object exists for this command.
@@ -122,6 +146,8 @@ public:
const CommandInfo *registerUnknownCommand(StringRef CommandName);
+ const CommandInfo *registerBlockCommand(StringRef CommandName);
+
/// \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);
@@ -137,6 +163,8 @@ private:
const CommandInfo *getRegisteredCommandInfo(StringRef Name) const;
const CommandInfo *getRegisteredCommandInfo(unsigned CommandID) const;
+ CommandInfo *createCommandInfoWithName(StringRef CommandName);
+
unsigned NextID;
/// Allocator for CommandInfo objects.
diff --git a/include/clang/AST/CommentCommands.td b/include/clang/AST/CommentCommands.td
index 3d8bad89c26b..9587ace87caf 100644
--- a/include/clang/AST/CommentCommands.td
+++ b/include/clang/AST/CommentCommands.td
@@ -1,3 +1,7 @@
+//===----------------------------------------------------------------------===//
+// Define command classes.
+//===----------------------------------------------------------------------===//
+
class Command<string name> {
string Name = name;
string EndCommandName = "";
@@ -12,6 +16,7 @@ class Command<string name> {
bit IsParamCommand = 0;
bit IsTParamCommand = 0;
bit IsDeprecatedCommand = 0;
+ bit IsHeaderfileCommand = 0;
bit IsEmptyParagraphAllowed = 0;
@@ -19,6 +24,9 @@ class Command<string name> {
bit IsVerbatimBlockEndCommand = 0;
bit IsVerbatimLineCommand = 0;
bit IsDeclarationCommand = 0;
+ bit IsFunctionDeclarationCommand = 0;
+ bit IsRecordLikeDetailCommand = 0;
+ bit IsRecordLikeDeclarationCommand = 0;
}
class InlineCommand<string name> : Command<name> {
@@ -29,6 +37,10 @@ class BlockCommand<string name> : Command<name> {
let IsBlockCommand = 1;
}
+class RecordLikeDetailCommand<string name> : BlockCommand<name> {
+ let IsRecordLikeDetailCommand = 1;
+}
+
class VerbatimBlockCommand<string name> : Command<name> {
let EndCommandName = name;
let IsVerbatimBlockCommand = 1;
@@ -54,6 +66,22 @@ class DeclarationVerbatimLineCommand<string name> :
let IsDeclarationCommand = 1;
}
+class FunctionDeclarationVerbatimLineCommand<string name> :
+ VerbatimLineCommand<name> {
+ let IsDeclarationCommand = 1;
+ let IsFunctionDeclarationCommand = 1;
+}
+
+class RecordLikeDeclarationVerbatimLineCommand<string name> :
+ VerbatimLineCommand<name> {
+ let IsDeclarationCommand = 1;
+ let IsRecordLikeDeclarationCommand = 1;
+}
+
+//===----------------------------------------------------------------------===//
+// InlineCommand
+//===----------------------------------------------------------------------===//
+
def B : InlineCommand<"b">;
def C : InlineCommand<"c">;
def P : InlineCommand<"p">;
@@ -61,19 +89,26 @@ def A : InlineCommand<"a">;
def E : InlineCommand<"e">;
def Em : InlineCommand<"em">;
+//===----------------------------------------------------------------------===//
+// BlockCommand
+//===----------------------------------------------------------------------===//
+
def Brief : BlockCommand<"brief"> { let IsBriefCommand = 1; }
def Short : BlockCommand<"short"> { let IsBriefCommand = 1; }
+// Opposite of \brief, it is the default in our implementation.
+def Details : BlockCommand<"details">;
+
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
+// Doxygen command for template parameter documentation.
def Tparam : BlockCommand<"tparam"> { let IsTParamCommand = 1; }
-// HeaderDoc
+// HeaderDoc command for template parameter documentation.
def Templatefield : BlockCommand<"templatefield"> { let IsTParamCommand = 1; }
def Deprecated : BlockCommand<"deprecated"> {
@@ -81,12 +116,17 @@ def Deprecated : BlockCommand<"deprecated"> {
let IsDeprecatedCommand = 1;
}
+def Headerfile : BlockCommand<"headerfile"> { let IsHeaderfileCommand = 1; }
+
+// We don't do any additional semantic analysis for the following
+// BlockCommands. It might be a good idea to do something extra for them, but
+// for now we model them as plain BlockCommands.
+def Attention : BlockCommand<"attention">;
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">;
@@ -99,6 +139,22 @@ def Since : BlockCommand<"since">;
def Todo : BlockCommand<"todo">;
def Version : BlockCommand<"version">;
def Warning : BlockCommand<"warning">;
+// HeaderDoc commands
+def ClassDesign : RecordLikeDetailCommand<"classdesign">;
+def CoClass : RecordLikeDetailCommand<"coclass">;
+def Dependency : RecordLikeDetailCommand<"dependency">;
+def Helper : RecordLikeDetailCommand<"helper">;
+def HelperClass : RecordLikeDetailCommand<"helperclass">;
+def Helps : RecordLikeDetailCommand<"helps">;
+def InstanceSize : RecordLikeDetailCommand<"instancesize">;
+def Ownership : RecordLikeDetailCommand<"ownership">;
+def Performance : RecordLikeDetailCommand<"performance">;
+def Security : RecordLikeDetailCommand<"security">;
+def SuperClass : RecordLikeDetailCommand<"superclass">;
+
+//===----------------------------------------------------------------------===//
+// VerbatimBlockCommand
+//===----------------------------------------------------------------------===//
defm Code : VerbatimBlockCommand<"code", "endcode">;
defm Verbatim : VerbatimBlockCommand<"verbatim", "endverbatim">;
@@ -111,11 +167,16 @@ defm Rtfonly : VerbatimBlockCommand<"rtfonly", "endrtfonly">;
defm Dot : VerbatimBlockCommand<"dot", "enddot">;
defm Msc : VerbatimBlockCommand<"msc", "endmsc">;
-// These commands have special support in lexer.
+// These three commands have special support in CommentLexer to recognize their
+// names.
def FDollar : VerbatimBlockCommand<"f$">; // Inline LaTeX formula
defm FBracket : VerbatimBlockCommand<"f[", "f]">; // Displayed LaTeX formula
defm FBrace : VerbatimBlockCommand<"f{", "f}">; // LaTeX environment
+//===----------------------------------------------------------------------===//
+// VerbatimLineCommand
+//===----------------------------------------------------------------------===//
+
def Defgroup : VerbatimLineCommand<"defgroup">;
def Ingroup : VerbatimLineCommand<"ingroup">;
def Addtogroup : VerbatimLineCommand<"addtogroup">;
@@ -131,6 +192,10 @@ def Mainpage : VerbatimLineCommand<"mainpage">;
def Subpage : VerbatimLineCommand<"subpage">;
def Ref : VerbatimLineCommand<"ref">;
+//===----------------------------------------------------------------------===//
+// DeclarationVerbatimLineCommand
+//===----------------------------------------------------------------------===//
+
// Doxygen commands.
def Fn : DeclarationVerbatimLineCommand<"fn">;
def Namespace : DeclarationVerbatimLineCommand<"namespace">;
@@ -140,17 +205,18 @@ def Typedef : DeclarationVerbatimLineCommand<"typedef">;
def Var : DeclarationVerbatimLineCommand<"var">;
// HeaderDoc commands.
-def Class : DeclarationVerbatimLineCommand<"class">;
-def Interface : DeclarationVerbatimLineCommand<"interface">;
-def Protocol : DeclarationVerbatimLineCommand<"protocol">;
+def Class : RecordLikeDeclarationVerbatimLineCommand<"class">;
+def Interface : RecordLikeDeclarationVerbatimLineCommand<"interface">;
+def Protocol : RecordLikeDeclarationVerbatimLineCommand<"protocol">;
+def Struct : RecordLikeDeclarationVerbatimLineCommand<"struct">;
+def Union : RecordLikeDeclarationVerbatimLineCommand<"union">;
def Category : DeclarationVerbatimLineCommand<"category">;
def Template : DeclarationVerbatimLineCommand<"template">;
-def Function : DeclarationVerbatimLineCommand<"function">;
-def Method : DeclarationVerbatimLineCommand<"method">;
-def Callback : DeclarationVerbatimLineCommand<"callback">;
+def Function : FunctionDeclarationVerbatimLineCommand<"function">;
+def FunctionGroup : FunctionDeclarationVerbatimLineCommand<"functiongroup">;
+def Method : FunctionDeclarationVerbatimLineCommand<"method">;
+def MethodGroup : FunctionDeclarationVerbatimLineCommand<"methodgroup">;
+def Callback : FunctionDeclarationVerbatimLineCommand<"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/CommentHTMLNamedCharacterReferences.td b/include/clang/AST/CommentHTMLNamedCharacterReferences.td
new file mode 100644
index 000000000000..449310871229
--- /dev/null
+++ b/include/clang/AST/CommentHTMLNamedCharacterReferences.td
@@ -0,0 +1,177 @@
+// HTML Named Character Reference
+class NCR<string spelling, int codePoint> {
+ string Spelling = spelling;
+ int CodePoint = codePoint;
+}
+
+// The list below includes named character references supported by Doxygen:
+// http://www.stack.nl/~dimitri/doxygen/manual/htmlcmds.html
+//
+// It does not include all HTML 5 named character references.
+//
+// Corresponding code point values can be found here:
+// http://www.w3.org/TR/2011/WD-html5-20110113/named-character-references.html
+
+def : NCR<"copy", 0x000A9>;
+def : NCR<"COPY", 0x000A9>;
+def : NCR<"trade", 0x02122>;
+def : NCR<"TRADE", 0x02122>;
+def : NCR<"reg", 0x000AE>;
+def : NCR<"REG", 0x000AE>;
+def : NCR<"lt", 0x0003C>;
+def : NCR<"Lt", 0x0003C>;
+def : NCR<"LT", 0x0003C>;
+def : NCR<"gt", 0x0003E>;
+def : NCR<"Gt", 0x0003E>;
+def : NCR<"GT", 0x0003E>;
+def : NCR<"amp", 0x00026>;
+def : NCR<"AMP", 0x00026>;
+def : NCR<"apos", 0x00027>;
+def : NCR<"quot", 0x00022>;
+def : NCR<"QUOT", 0x00022>;
+def : NCR<"lsquo", 0x02018>;
+def : NCR<"rsquo", 0x02019>;
+def : NCR<"ldquo", 0x0201C>;
+def : NCR<"rdquo", 0x0201D>;
+def : NCR<"ndash", 0x02013>;
+def : NCR<"mdash", 0x02014>;
+
+def : NCR<"Auml", 0x000C4>;
+def : NCR<"Euml", 0x000CB>;
+def : NCR<"Iuml", 0x000CF>;
+def : NCR<"Ouml", 0x000D6>;
+def : NCR<"Uuml", 0x000DC>;
+def : NCR<"Yuml", 0x00178>;
+def : NCR<"auml", 0x000E4>;
+def : NCR<"euml", 0x000EB>;
+def : NCR<"iuml", 0x000EF>;
+def : NCR<"ouml", 0x000F6>;
+def : NCR<"uuml", 0x000FC>;
+def : NCR<"yuml", 0x000FF>;
+
+def : NCR<"Aacute", 0x000C1>;
+def : NCR<"Eacute", 0x000C9>;
+def : NCR<"Iacute", 0x000CD>;
+def : NCR<"Oacute", 0x000D3>;
+def : NCR<"Uacute", 0x000DA>;
+def : NCR<"Yacute", 0x000DD>;
+def : NCR<"aacute", 0x000E1>;
+def : NCR<"eacute", 0x000E9>;
+def : NCR<"iacute", 0x000ED>;
+def : NCR<"oacute", 0x000F3>;
+def : NCR<"uacute", 0x000FA>;
+def : NCR<"yacute", 0x000FD>;
+
+def : NCR<"Agrave", 0x000C0>;
+def : NCR<"Egrave", 0x000C8>;
+def : NCR<"Igrave", 0x000CC>;
+def : NCR<"Ograve", 0x000D2>;
+def : NCR<"Ugrave", 0x000D9>;
+// def : NCR<"Ygrave", 0x01EF2>; // Defined neither in Doxygen, nor in HTML5.
+def : NCR<"agrave", 0x000E0>;
+def : NCR<"egrave", 0x000E8>;
+def : NCR<"igrave", 0x000EC>;
+def : NCR<"ograve", 0x000F2>;
+def : NCR<"ugrave", 0x000F9>;
+def : NCR<"ygrave", 0x01EF3>; // Defined in Doxygen, not defined in HTML5.
+
+def : NCR<"Acirc", 0x000C2>;
+def : NCR<"Ecirc", 0x000CA>;
+def : NCR<"Icirc", 0x000CE>;
+def : NCR<"Ocirc", 0x000D4>;
+def : NCR<"Ucirc", 0x000DB>;
+def : NCR<"Ycirc", 0x00176>; // Not defined in Doxygen, defined in HTML5.
+def : NCR<"acirc", 0x000E2>;
+def : NCR<"ecirc", 0x000EA>;
+def : NCR<"icirc", 0x000EE>;
+def : NCR<"ocirc", 0x000F4>;
+def : NCR<"ucirc", 0x000FB>;
+def : NCR<"ycirc", 0x00177>;
+
+def : NCR<"Atilde", 0x000C3>;
+def : NCR<"Ntilde", 0x000D1>;
+def : NCR<"Otilde", 0x000D5>;
+def : NCR<"atilde", 0x000E3>;
+def : NCR<"ntilde", 0x000F1>;
+def : NCR<"otilde", 0x000F5>;
+
+def : NCR<"szlig", 0x000DF>;
+
+def : NCR<"ccedil", 0x000E7>;
+def : NCR<"Ccedil", 0x000C7>;
+
+def : NCR<"aring", 0x000E5>;
+def : NCR<"Aring", 0x000C5>;
+
+def : NCR<"nbsp", 0x000A0>;
+
+def : NCR<"Gamma", 0x00393>;
+def : NCR<"Delta", 0x00394>;
+def : NCR<"Theta", 0x00398>;
+def : NCR<"Lambda", 0x0039B>;
+def : NCR<"Xi", 0x0039E>;
+def : NCR<"Pi", 0x003A0>;
+def : NCR<"Sigma", 0x003A3>;
+def : NCR<"Upsilon", 0x003A5>;
+def : NCR<"Phi", 0x003A6>;
+def : NCR<"Psi", 0x003A8>;
+def : NCR<"Omega", 0x003A9>;
+
+def : NCR<"alpha", 0x003B1>;
+def : NCR<"beta", 0x003B2>;
+def : NCR<"gamma", 0x003B3>;
+def : NCR<"delta", 0x003B4>;
+def : NCR<"epsilon", 0x003B5>;
+def : NCR<"zeta", 0x003B6>;
+def : NCR<"eta", 0x003B7>;
+def : NCR<"theta", 0x003B8>;
+def : NCR<"iota", 0x003B9>;
+def : NCR<"kappa", 0x003BA>;
+def : NCR<"lambda", 0x003BB>;
+def : NCR<"mu", 0x003BC>;
+def : NCR<"nu", 0x003BD>;
+def : NCR<"xi", 0x003BE>;
+def : NCR<"pi", 0x003C0>;
+def : NCR<"rho", 0x003C1>;
+def : NCR<"sigma", 0x003C3>;
+def : NCR<"tau", 0x003C4>;
+def : NCR<"upsilon", 0x003C5>;
+def : NCR<"phi", 0x003C6>;
+def : NCR<"chi", 0x003C7>;
+def : NCR<"psi", 0x003C8>;
+def : NCR<"omega", 0x003C9>;
+def : NCR<"sigmaf", 0x003C2>;
+
+def : NCR<"sect", 0x000A7>;
+def : NCR<"deg", 0x000B0>;
+def : NCR<"prime", 0x02032>;
+def : NCR<"Prime", 0x02033>;
+def : NCR<"infin", 0x0221E>;
+def : NCR<"empty", 0x02205>;
+def : NCR<"plusmn", 0x000B1>;
+def : NCR<"times", 0x000D7>;
+def : NCR<"minus", 0x02212>;
+def : NCR<"sdot", 0x022C5>;
+def : NCR<"part", 0x02202>;
+def : NCR<"nabla", 0x02207>;
+def : NCR<"radic", 0x0221A>;
+def : NCR<"perp", 0x022A5>;
+def : NCR<"sum", 0x02211>;
+def : NCR<"int", 0x0222B>;
+def : NCR<"prod", 0x0220F>;
+def : NCR<"sim", 0x0223C>;
+def : NCR<"asymp", 0x02248>;
+def : NCR<"ne", 0x02260>;
+def : NCR<"equiv", 0x02261>;
+def : NCR<"prop", 0x0221D>;
+def : NCR<"le", 0x02264>;
+def : NCR<"ge", 0x02265>;
+def : NCR<"larr", 0x02190>;
+def : NCR<"rarr", 0x02192>;
+def : NCR<"isin", 0x02208>;
+def : NCR<"notin", 0x02209>;
+def : NCR<"lceil", 0x02308>;
+def : NCR<"rceil", 0x02309>;
+def : NCR<"lfloor", 0x0230A>;
+def : NCR<"rfloor", 0x0230B>;
+
diff --git a/include/clang/AST/CommentLexer.h b/include/clang/AST/CommentLexer.h
index f2636973ff27..4179f45e80ee 100644
--- a/include/clang/AST/CommentLexer.h
+++ b/include/clang/AST/CommentLexer.h
@@ -15,9 +15,9 @@
#define LLVM_CLANG_AST_COMMENT_LEXER_H
#include "clang/Basic/SourceManager.h"
-#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/raw_ostream.h"
@@ -34,8 +34,9 @@ enum TokenKind {
eof,
newline,
text,
- unknown_command, // Command that does not have an ID.
- command, // Command with an ID.
+ unknown_command, // Command that does not have an ID.
+ backslash_command, // Command with an ID, that used backslash marker.
+ at_command, // Command with an ID, that used 'at' marker.
verbatim_block_begin,
verbatim_block_line,
verbatim_block_end,
@@ -75,7 +76,7 @@ class Token {
/// 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; }
void setLocation(SourceLocation SL) { Loc = SL; }
@@ -118,12 +119,12 @@ public:
}
unsigned getCommandID() const LLVM_READONLY {
- assert(is(tok::command));
+ assert(is(tok::backslash_command) || is(tok::at_command));
return IntVal;
}
void setCommandID(unsigned ID) {
- assert(is(tok::command));
+ assert(is(tok::backslash_command) || is(tok::at_command));
IntVal = ID;
}
diff --git a/include/clang/AST/CommentParser.h b/include/clang/AST/CommentParser.h
index 19e1d57fc3f5..d6a1072786ed 100644
--- a/include/clang/AST/CommentParser.h
+++ b/include/clang/AST/CommentParser.h
@@ -14,10 +14,10 @@
#ifndef LLVM_CLANG_AST_COMMENT_PARSER_H
#define LLVM_CLANG_AST_COMMENT_PARSER_H
-#include "clang/Basic/Diagnostic.h"
-#include "clang/AST/CommentLexer.h"
#include "clang/AST/Comment.h"
+#include "clang/AST/CommentLexer.h"
#include "clang/AST/CommentSema.h"
+#include "clang/Basic/Diagnostic.h"
#include "llvm/Support/Allocator.h"
namespace clang {
@@ -86,6 +86,11 @@ class Parser {
Tok = Toks[0];
}
+ bool isTokBlockCommand() {
+ return (Tok.is(tok::backslash_command) || Tok.is(tok::at_command)) &&
+ Traits.getCommandInfo(Tok.getCommandID())->IsBlockCommand;
+ }
+
public:
Parser(Lexer &L, Sema &S, llvm::BumpPtrAllocator &Allocator,
const SourceManager &SourceMgr, DiagnosticsEngine &Diags,
diff --git a/include/clang/AST/CommentSema.h b/include/clang/AST/CommentSema.h
index 0340b3cfd52d..15e454dcc389 100644
--- a/include/clang/AST/CommentSema.h
+++ b/include/clang/AST/CommentSema.h
@@ -14,12 +14,12 @@
#ifndef LLVM_CLANG_AST_COMMENT_SEMA_H
#define LLVM_CLANG_AST_COMMENT_SEMA_H
+#include "clang/AST/Comment.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceLocation.h"
-#include "clang/AST/Comment.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
namespace clang {
@@ -60,6 +60,9 @@ class Sema {
/// AST node for the \\returns command and its aliases.
const BlockCommandComment *ReturnsCommand;
+
+ /// AST node for the \\headerfile command.
+ const BlockCommandComment *HeaderfileCommand;
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) {
return Diags.Report(Loc, DiagID);
@@ -93,7 +96,8 @@ public:
BlockCommandComment *actOnBlockCommandStart(SourceLocation LocBegin,
SourceLocation LocEnd,
- unsigned CommandID);
+ unsigned CommandID,
+ CommandMarkerKind CommandMarker);
void actOnBlockCommandArgs(BlockCommandComment *Command,
ArrayRef<BlockCommandComment::Argument> Args);
@@ -103,7 +107,8 @@ public:
ParamCommandComment *actOnParamCommandStart(SourceLocation LocBegin,
SourceLocation LocEnd,
- unsigned CommandID);
+ unsigned CommandID,
+ CommandMarkerKind CommandMarker);
void actOnParamCommandDirectionArg(ParamCommandComment *Command,
SourceLocation ArgLocBegin,
@@ -120,7 +125,8 @@ public:
TParamCommandComment *actOnTParamCommandStart(SourceLocation LocBegin,
SourceLocation LocEnd,
- unsigned CommandID);
+ unsigned CommandID,
+ CommandMarkerKind CommandMarker);
void actOnTParamCommandParamNameArg(TParamCommandComment *Command,
SourceLocation ArgLocBegin,
@@ -192,13 +198,28 @@ public:
void checkBlockCommandDuplicate(const BlockCommandComment *Command);
void checkDeprecatedCommand(const BlockCommandComment *Comment);
+
+ void checkFunctionDeclVerbatimLine(const BlockCommandComment *Comment);
+
+ void checkContainerDeclVerbatimLine(const BlockCommandComment *Comment);
+
+ void checkContainerDecl(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 isAnyFunctionDecl();
+ bool isFunctionPointerVarDecl();
+ bool isObjCMethodDecl();
+ bool isObjCPropertyDecl();
bool isTemplateOrSpecialization();
+ bool isRecordLikeDecl();
+ bool isClassOrStructDecl();
+ bool isUnionDecl();
+ bool isObjCInterfaceDecl();
+ bool isObjCProtocolDecl();
ArrayRef<const ParmVarDecl *> getParamVars();
diff --git a/include/clang/AST/CommentVisitor.h b/include/clang/AST/CommentVisitor.h
index 47867a634fcc..21641bfeb89f 100644
--- a/include/clang/AST/CommentVisitor.h
+++ b/include/clang/AST/CommentVisitor.h
@@ -7,6 +7,9 @@
//
//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_AST_COMMENTVISITOR_H
+#define LLVM_CLANG_AST_COMMENTVISITOR_H
+
#include "clang/AST/Comment.h"
#include "llvm/Support/ErrorHandling.h"
@@ -64,3 +67,4 @@ class ConstCommentVisitor :
} // end namespace comments
} // end namespace clang
+#endif
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 087a58587471..7927279ddd6d 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -16,33 +16,34 @@
#include "clang/AST/APValue.h"
#include "clang/AST/DeclBase.h"
-#include "clang/AST/Redeclarable.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/ExternalASTSource.h"
+#include "clang/AST/Redeclarable.h"
+#include "clang/AST/Type.h"
#include "clang/Basic/Linkage.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
#include "llvm/Support/Compiler.h"
namespace clang {
+struct ASTTemplateArgumentListInfo;
class CXXTemporary;
+class CompoundStmt;
+class DependentFunctionTemplateSpecializationInfo;
class Expr;
class FunctionTemplateDecl;
+class FunctionTemplateSpecializationInfo;
+class LabelStmt;
+class MemberSpecializationInfo;
+class Module;
+class NestedNameSpecifier;
class Stmt;
-class CompoundStmt;
class StringLiteral;
-class NestedNameSpecifier;
-class TemplateParameterList;
class TemplateArgumentList;
-struct ASTTemplateArgumentListInfo;
-class MemberSpecializationInfo;
-class FunctionTemplateSpecializationInfo;
-class DependentFunctionTemplateSpecializationInfo;
+class TemplateParameterList;
class TypeLoc;
class UnresolvedSetImpl;
-class LabelStmt;
-class Module;
-
+
/// \brief A container of type source information.
///
/// A client can read the relevant info using TypeLoc wrappers, e.g:
@@ -108,6 +109,7 @@ class NamedDecl : public Decl {
private:
NamedDecl *getUnderlyingDeclImpl();
+ void verifyLinkage() const;
protected:
NamedDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N)
@@ -149,32 +151,29 @@ public:
/// \brief Set the name of this declaration.
void setDeclName(DeclarationName N) { Name = N; }
- /// getQualifiedNameAsString - Returns human-readable qualified name for
+ /// printQualifiedName - Returns human-readable qualified name for
/// declaration, like A::B::i, for i being member of namespace A::B.
/// If declaration is not member of context which can be named (record,
- /// namespace), it will return same result as getNameAsString().
+ /// namespace), it will return same result as printName().
/// Creating this name is expensive, so it should be called only when
/// performance doesn't matter.
+ void printQualifiedName(raw_ostream &OS) const;
+ void printQualifiedName(raw_ostream &OS, const PrintingPolicy &Policy) const;
+
+ // FIXME: Remove string versions.
std::string getQualifiedNameAsString() const;
std::string getQualifiedNameAsString(const PrintingPolicy &Policy) const;
/// getNameForDiagnostic - Appends a human-readable name for this
- /// declaration into the given string.
+ /// declaration into the given stream.
///
/// This is the method invoked by Sema when displaying a NamedDecl
/// in a diagnostic. It does not necessarily produce the same
- /// result as getNameAsString(); for example, class template
+ /// result as printName(); for example, class template
/// specializations are printed with their template arguments.
- ///
- /// TODO: use an API that doesn't require so many temporary strings
- virtual void getNameForDiagnostic(std::string &S,
+ virtual void getNameForDiagnostic(raw_ostream &OS,
const PrintingPolicy &Policy,
- bool Qualified) const {
- if (Qualified)
- S += getQualifiedNameAsString(Policy);
- else
- S += getNameAsString();
- }
+ bool Qualified) const;
/// declarationReplaces - Determine whether this declaration, if
/// known to be well-formed within its context, will replace the
@@ -212,117 +211,40 @@ public:
/// a C++ class.
bool isCXXInstanceMember() const;
- class LinkageInfo {
- 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) {
- assert(linkage() == L && visibility() == V && visibilityExplicit() == E &&
- "Enum truncated!");
- }
-
- static LinkageInfo external() {
- return LinkageInfo();
- }
- static LinkageInfo internal() {
- return LinkageInfo(InternalLinkage, DefaultVisibility, false);
- }
- static LinkageInfo uniqueExternal() {
- return LinkageInfo(UniqueExternalLinkage, DefaultVisibility, false);
- }
- static LinkageInfo none() {
- return LinkageInfo(NoLinkage, DefaultVisibility, false);
- }
-
- Linkage linkage() const { return (Linkage)linkage_; }
- Visibility visibility() const { return (Visibility)visibility_; }
- bool visibilityExplicit() const { return explicit_; }
-
- void setLinkage(Linkage L) { linkage_ = L; }
- void mergeLinkage(Linkage L) {
- setLinkage(minLinkage(linkage(), L));
- }
- void mergeLinkage(LinkageInfo Other) {
- mergeLinkage(Other.linkage());
- }
-
- // Merge the visibility V giving preference to explicit ones.
- // This is used, for example, when merging the visibility of a class
- // down to one of its members. If the member has no explicit visibility,
- // the class visibility wins.
- void mergeVisibility(Visibility V, bool E = false) {
- // Never increase the visibility
- if (visibility() < V)
- return;
-
- // If we have an explicit visibility, keep it
- if (visibilityExplicit())
- return;
-
- setVisibility(V, E);
- }
- // Merge the visibility V, keeping the most restrictive one.
- // This is used for cases like merging the visibility of a template
- // argument to an instantiation. If we already have a hidden class,
- // no argument should give it default visibility.
- void mergeVisibilityWithMin(Visibility V, bool E = false) {
- // Never increase the visibility
- if (visibility() < V)
- return;
-
- // FIXME: this
- // If this visibility is explicit, keep it.
- if (visibilityExplicit() && !E)
- return;
-
- // should be replaced with this
- // Don't lose the explicit bit for nothing
- // if (visibility() == V && visibilityExplicit())
- // return;
-
- setVisibility(V, E);
- }
- void mergeVisibility(LinkageInfo Other) {
- mergeVisibility(Other.visibility(), Other.visibilityExplicit());
- }
- void mergeVisibilityWithMin(LinkageInfo Other) {
- mergeVisibilityWithMin(Other.visibility(), Other.visibilityExplicit());
- }
-
- void merge(LinkageInfo Other) {
- mergeLinkage(Other);
- mergeVisibility(Other);
- }
- void mergeWithMin(LinkageInfo Other) {
- mergeLinkage(Other);
- mergeVisibilityWithMin(Other);
- }
- };
-
/// \brief Determine what kind of linkage this entity has.
Linkage getLinkage() const;
+ /// \brief True if this decl has external linkage.
+ bool hasExternalLinkage() const {
+ return getLinkage() == ExternalLinkage;
+ }
+
+ /// \brief True if this decl has external linkage. Don't cache the linkage,
+ /// because we are not finished setting up the redecl chain for the decl.
+ bool hasExternalLinkageUncached() const;
+
/// \brief Determines the visibility of this entity.
Visibility getVisibility() const {
- return getLinkageAndVisibility().visibility();
+ return getLinkageAndVisibility().getVisibility();
}
/// \brief Determines the linkage and visibility of this entity.
LinkageInfo getLinkageAndVisibility() const;
+ /// Kinds of explicit visibility.
+ enum ExplicitVisibilityKind {
+ VisibilityForType,
+ VisibilityForValue
+ };
+
/// \brief If visibility was explicitly specified for this
/// declaration, return that visibility.
- llvm::Optional<Visibility> getExplicitVisibility() const;
+ Optional<Visibility>
+ getExplicitVisibility(ExplicitVisibilityKind kind) const;
- /// \brief Clear the linkage cache in response to a change
- /// to the declaration.
- void ClearLinkageCache();
+ /// \brief True if the computed linkage is valid. Used for consistency
+ /// checking. Should always return true.
+ bool isLinkageValid() const;
/// \brief Looks through UsingDecls and ObjCCompatibleAliasDecls for
/// the underlying named decl.
@@ -538,9 +460,7 @@ public:
/// \brief Determine whether this symbol is weakly-imported,
/// or declared with the weak or weak-ref attr.
- bool isWeak() const {
- return hasAttr<WeakAttr>() || hasAttr<WeakRefAttr>() || isWeakImported();
- }
+ bool isWeak() const;
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -744,7 +664,6 @@ private:
friend class ASTDeclReader;
unsigned SClass : 3;
- unsigned SClassAsWritten : 3;
unsigned ThreadSpecified : 1;
unsigned InitStyle : 2;
@@ -811,14 +730,12 @@ protected:
VarDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
- QualType T, TypeSourceInfo *TInfo, StorageClass SC,
- StorageClass SCAsWritten)
+ QualType T, TypeSourceInfo *TInfo, StorageClass SC)
: DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc), Init() {
assert(sizeof(VarDeclBitfields) <= sizeof(unsigned));
assert(sizeof(ParmVarDeclBitfields) <= sizeof(unsigned));
AllBits = 0;
VarDeclBits.SClass = SC;
- VarDeclBits.SClassAsWritten = SCAsWritten;
// Everything else is implicitly initialized to false.
}
@@ -841,23 +758,18 @@ public:
static VarDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
- StorageClass S, StorageClass SCAsWritten);
+ StorageClass S);
static VarDecl *CreateDeserialized(ASTContext &C, unsigned ID);
virtual SourceRange getSourceRange() const LLVM_READONLY;
+ /// \brief Returns the storage class as written in the source. For the
+ /// computed linkage of symbol, see getLinkage.
StorageClass getStorageClass() const {
return (StorageClass) VarDeclBits.SClass;
}
- StorageClass getStorageClassAsWritten() const {
- return (StorageClass) VarDeclBits.SClassAsWritten;
- }
void setStorageClass(StorageClass SC);
- void setStorageClassAsWritten(StorageClass SC) {
- assert(isLegalForVariable(SC));
- VarDeclBits.SClassAsWritten = SC;
- }
void setThreadSpecified(bool T) { VarDeclBits.ThreadSpecified = T; }
bool isThreadSpecified() const {
@@ -882,8 +794,8 @@ public:
return getStorageClass() == SC_Static && !isFileVarDecl();
}
- /// hasExternStorage - Returns true if a variable has extern or
- /// __private_extern__ storage.
+ /// \brief Returns true if a variable has extern or __private_extern__
+ /// storage.
bool hasExternalStorage() const {
return getStorageClass() == SC_Extern ||
getStorageClass() == SC_PrivateExtern;
@@ -894,6 +806,9 @@ public:
/// as static variables declared within a function.
bool hasGlobalStorage() const { return !hasLocalStorage(); }
+ /// Compute the language linkage.
+ LanguageLinkage getLanguageLinkage() const;
+
/// \brief Determines whether this variable is a variable with
/// external, C linkage.
bool isExternC() const;
@@ -1087,8 +1002,7 @@ public:
/// not a constant expression. Returns a pointer to the value if evaluation
/// succeeded, 0 otherwise.
APValue *evaluateValue() const;
- APValue *evaluateValue(
- llvm::SmallVectorImpl<PartialDiagnosticAt> &Notes) const;
+ APValue *evaluateValue(SmallVectorImpl<PartialDiagnosticAt> &Notes) const;
/// \brief Return the already-evaluated value of this variable's
/// initializer, or NULL if the value is not yet known. Returns pointer
@@ -1220,7 +1134,7 @@ public:
ImplicitParamDecl(DeclContext *DC, SourceLocation IdLoc,
IdentifierInfo *Id, QualType Type)
: VarDecl(ImplicitParam, DC, IdLoc, IdLoc, Id, Type,
- /*tinfo*/ 0, SC_None, SC_None) {
+ /*tinfo*/ 0, SC_None) {
setImplicit();
}
@@ -1239,8 +1153,8 @@ protected:
ParmVarDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
QualType T, TypeSourceInfo *TInfo,
- StorageClass S, StorageClass SCAsWritten, Expr *DefArg)
- : VarDecl(DK, DC, StartLoc, IdLoc, Id, T, TInfo, S, SCAsWritten) {
+ StorageClass S, Expr *DefArg)
+ : VarDecl(DK, DC, StartLoc, IdLoc, Id, T, TInfo, S) {
assert(ParmVarDeclBits.HasInheritedDefaultArg == false);
assert(ParmVarDeclBits.IsKNRPromoted == false);
assert(ParmVarDeclBits.IsObjCMethodParam == false);
@@ -1252,8 +1166,7 @@ public:
SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
QualType T, TypeSourceInfo *TInfo,
- StorageClass S, StorageClass SCAsWritten,
- Expr *DefArg);
+ StorageClass S, Expr *DefArg);
static ParmVarDecl *CreateDeserialized(ASTContext &C, unsigned ID);
@@ -1451,14 +1364,13 @@ private:
/// DeclsInPrototypeScope - Array of pointers to NamedDecls for
/// decls defined in the function prototype that are not parameters. E.g.
/// 'enum Y' in 'void f(enum Y {AA} x) {}'.
- llvm::ArrayRef<NamedDecl*> DeclsInPrototypeScope;
+ ArrayRef<NamedDecl *> DeclsInPrototypeScope;
LazyDeclStmtPtr Body;
// FIXME: This can be packed into the bitfields in Decl.
// NOTE: VC++ treats enums as signed, avoid using the StorageClass enum
unsigned SClass : 2;
- unsigned SClassAsWritten : 2;
bool IsInline : 1;
bool IsInlineSpecified : 1;
bool IsVirtualAsWritten : 1;
@@ -1473,6 +1385,10 @@ private:
bool IsLateTemplateParsed : 1;
bool IsConstexpr : 1;
+ /// \brief Indicates if the function was a definition but its body was
+ /// skipped.
+ unsigned HasSkippedBody : 1;
+
/// \brief End part of this FunctionDecl's source range.
///
/// We could compute the full range in getSourceRange(). However, when we're
@@ -1538,25 +1454,26 @@ private:
void setInstantiationOfMemberFunction(ASTContext &C, FunctionDecl *FD,
TemplateSpecializationKind TSK);
- void setParams(ASTContext &C, llvm::ArrayRef<ParmVarDecl *> NewParamInfo);
+ void setParams(ASTContext &C, ArrayRef<ParmVarDecl *> NewParamInfo);
protected:
FunctionDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
- StorageClass S, StorageClass SCAsWritten, bool isInlineSpecified,
+ StorageClass S, bool isInlineSpecified,
bool isConstexprSpecified)
: DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo,
StartLoc),
DeclContext(DK),
ParamInfo(0), Body(),
- SClass(S), SClassAsWritten(SCAsWritten),
+ SClass(S),
IsInline(isInlineSpecified), IsInlineSpecified(isInlineSpecified),
IsVirtualAsWritten(false), IsPure(false), HasInheritedPrototype(false),
HasWrittenPrototype(true), IsDeleted(false), IsTrivial(false),
IsDefaulted(false), IsExplicitlyDefaulted(false),
HasImplicitReturnZero(false), IsLateTemplateParsed(false),
- IsConstexpr(isConstexprSpecified), EndRangeLoc(NameInfo.getEndLoc()),
+ IsConstexpr(isConstexprSpecified), HasSkippedBody(false),
+ EndRangeLoc(NameInfo.getEndLoc()),
TemplateOrSpecialization(),
DNLoc(NameInfo.getInfo()) {}
@@ -1580,14 +1497,13 @@ public:
SourceLocation StartLoc, SourceLocation NLoc,
DeclarationName N, QualType T,
TypeSourceInfo *TInfo,
- StorageClass SC = SC_None,
- StorageClass SCAsWritten = SC_None,
+ StorageClass SC,
bool isInlineSpecified = false,
bool hasWrittenPrototype = true,
bool isConstexprSpecified = false) {
DeclarationNameInfo NameInfo(N, NLoc);
return FunctionDecl::Create(C, DC, StartLoc, NameInfo, T, TInfo,
- SC, SCAsWritten,
+ SC,
isInlineSpecified, hasWrittenPrototype,
isConstexprSpecified);
}
@@ -1596,10 +1512,9 @@ public:
SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
- StorageClass SC = SC_None,
- StorageClass SCAsWritten = SC_None,
- bool isInlineSpecified = false,
- bool hasWrittenPrototype = true,
+ StorageClass SC,
+ bool isInlineSpecified,
+ bool hasWrittenPrototype,
bool isConstexprSpecified = false);
static FunctionDecl *CreateDeserialized(ASTContext &C, unsigned ID);
@@ -1608,7 +1523,7 @@ public:
return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc);
}
- virtual void getNameForDiagnostic(std::string &S,
+ virtual void getNameForDiagnostic(raw_ostream &OS,
const PrintingPolicy &Policy,
bool Qualified) const;
@@ -1732,7 +1647,7 @@ public:
/// Whether this is a (C++11) constexpr function or constexpr constructor.
bool isConstexpr() const { return IsConstexpr; }
- void setConstexpr(bool IC);
+ void setConstexpr(bool IC) { IsConstexpr = IC; }
/// \brief Whether this function has been deleted.
///
@@ -1776,6 +1691,9 @@ public:
/// This function must be an allocation or deallocation function.
bool isReservedGlobalPlacementOperator() const;
+ /// Compute the language linkage.
+ LanguageLinkage getLanguageLinkage() const;
+
/// \brief Determines whether this function is a function with
/// external, C linkage.
bool isExternC() const;
@@ -1783,6 +1701,14 @@ public:
/// \brief Determines whether this is a global function.
bool isGlobal() const;
+ /// \brief Determines whether this function is known to be 'noreturn', through
+ /// an attribute on its declaration or its type.
+ bool isNoReturn() const;
+
+ /// \brief True if the function was a definition but its body was skipped.
+ bool hasSkippedBody() const { return HasSkippedBody; }
+ void setHasSkippedBody(bool Skipped = true) { HasSkippedBody = Skipped; }
+
void setPreviousDeclaration(FunctionDecl * PrevDecl);
virtual const FunctionDecl *getCanonicalDecl() const;
@@ -1814,14 +1740,14 @@ public:
assert(i < getNumParams() && "Illegal param #");
return ParamInfo[i];
}
- void setParams(llvm::ArrayRef<ParmVarDecl *> NewParamInfo) {
+ void setParams(ArrayRef<ParmVarDecl *> NewParamInfo) {
setParams(getASTContext(), NewParamInfo);
}
- const llvm::ArrayRef<NamedDecl*> &getDeclsInPrototypeScope() const {
+ const ArrayRef<NamedDecl *> &getDeclsInPrototypeScope() const {
return DeclsInPrototypeScope;
}
- void setDeclsInPrototypeScope(llvm::ArrayRef<NamedDecl *> NewDecls);
+ void setDeclsInPrototypeScope(ArrayRef<NamedDecl *> NewDecls);
/// getMinRequiredArguments - Returns the minimum number of arguments
/// needed to call this function. This may be fewer than the number of
@@ -1838,12 +1764,9 @@ public:
return getType()->getAs<FunctionType>()->getCallResultType(getASTContext());
}
+ /// \brief Returns the storage class as written in the source. For the
+ /// computed linkage of symbol, see getLinkage.
StorageClass getStorageClass() const { return StorageClass(SClass); }
- void setStorageClass(StorageClass SC);
-
- StorageClass getStorageClassAsWritten() const {
- return StorageClass(SClassAsWritten);
- }
/// \brief Determine whether the "inline" keyword was specified for this
/// function.
@@ -1863,7 +1786,7 @@ public:
/// \brief Determine whether this function should be inlined, because it is
/// either marked "inline" or "constexpr" or is a member function of a class
/// that was defined in the class body.
- bool isInlined() const;
+ bool isInlined() const { return IsInline; }
bool isInlineDefinitionExternallyVisible() const;
@@ -1908,7 +1831,9 @@ public:
/// \brief If this function is an instantiation of a member function of a
/// class template specialization, retrieves the member specialization
/// information.
- MemberSpecializationInfo *getMemberSpecializationInfo() const;
+ MemberSpecializationInfo *getMemberSpecializationInfo() const {
+ return TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>();
+ }
/// \brief Specify that this record is an instantiation of the
/// member function FD.
@@ -2472,6 +2397,12 @@ protected:
/// possible in C++11 or Microsoft extensions mode.
bool IsFixed : 1;
+ /// \brief Indicates whether it is possible for declarations of this kind
+ /// to have an out-of-date definition.
+ ///
+ /// This option is only enabled when modules are enabled.
+ bool MayHaveOutOfDateDef : 1;
+
private:
SourceLocation RBraceLoc;
@@ -2616,6 +2547,25 @@ public:
bool isUnion() const { return getTagKind() == TTK_Union; }
bool isEnum() const { return getTagKind() == TTK_Enum; }
+ /// Is this tag type named, either directly or via being defined in
+ /// a typedef of this type?
+ ///
+ /// C++11 [basic.link]p8:
+ /// A type is said to have linkage if and only if:
+ /// - it is a class or enumeration type that is named (or has a
+ /// name for linkage purposes) and the name has linkage; ...
+ /// C++11 [dcl.typedef]p9:
+ /// If the typedef declaration defines an unnamed class (or enum),
+ /// the first typedef-name declared by the declaration to be that
+ /// class type (or enum type) is used to denote the class type (or
+ /// enum type) for linkage purposes only.
+ ///
+ /// C does not have an analogous rule, but the same concept is
+ /// nonetheless useful in some places.
+ bool hasNameForLinkage() const {
+ return (getDeclName() || getTypedefNameForAnonDecl());
+ }
+
TypedefNameDecl *getTypedefNameForAnonDecl() const {
return hasExtInfo() ? 0 :
TypedefNameDeclOrQualifier.get<TypedefNameDecl*>();
@@ -2906,6 +2856,10 @@ class RecordDecl : public TagDecl {
/// HasObjectMember - This is true if this struct has at least one member
/// containing an Objective-C object pointer type.
bool HasObjectMember : 1;
+
+ /// HasVolatileMember - This is true if struct has at least one member of
+ /// 'volatile' type.
+ bool HasVolatileMember : 1;
/// \brief Whether the field declarations of this record have been loaded
/// from external storage. To avoid unnecessary deserialization of
@@ -2962,6 +2916,9 @@ public:
bool hasObjectMember() const { return HasObjectMember; }
void setHasObjectMember (bool val) { HasObjectMember = val; }
+ bool hasVolatileMember() const { return HasVolatileMember; }
+ void setHasVolatileMember (bool val) { HasVolatileMember = val; }
+
/// \brief Determines whether this declaration represents the
/// injected class name.
///
@@ -3161,7 +3118,7 @@ public:
assert(i < getNumParams() && "Illegal param #");
return ParamInfo[i];
}
- void setParams(llvm::ArrayRef<ParmVarDecl *> NewParamInfo);
+ void setParams(ArrayRef<ParmVarDecl *> NewParamInfo);
/// hasCaptures - True if this block (or its nested blocks) captures
/// anything of local storage from its enclosing scopes.
@@ -3210,7 +3167,7 @@ public:
///
/// An import declaration imports the named module (or submodule). For example:
/// \code
-/// @__experimental_modules_import std.vector;
+/// @import std.vector;
/// \endcode
///
/// Import declarations can also be implicitly generated from
@@ -3271,7 +3228,21 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == Import; }
};
-
+
+/// \brief Represents an empty-declaration.
+class EmptyDecl : public Decl {
+ virtual void anchor();
+ EmptyDecl(DeclContext *DC, SourceLocation L)
+ : Decl(Empty, DC, L) { }
+
+public:
+ static EmptyDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L);
+ static EmptyDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classofKind(Kind K) { return K == Empty; }
+};
/// Insertion operator for diagnostics. This allows sending NamedDecl's
/// into a diagnostic with <<.
@@ -3299,10 +3270,10 @@ void Redeclarable<decl_type>::setPreviousDeclaration(decl_type *PrevDecl) {
// Point to previous. Make sure that this is actually the most recent
// redeclaration, or we can build invalid chains. If the most recent
// redeclaration is invalid, it won't be PrevDecl, but we want it anyway.
- RedeclLink = PreviousDeclLink(
- llvm::cast<decl_type>(PrevDecl->getMostRecentDecl()));
First = PrevDecl->getFirstDeclaration();
assert(First->RedeclLink.NextIsLatest() && "Expected first");
+ decl_type *MostRecent = First->RedeclLink.getNext();
+ RedeclLink = PreviousDeclLink(cast<decl_type>(MostRecent));
} else {
// Make this first.
First = static_cast<decl_type*>(this);
@@ -3310,8 +3281,8 @@ void Redeclarable<decl_type>::setPreviousDeclaration(decl_type *PrevDecl) {
// First one will point to this one as latest.
First->RedeclLink = LatestDeclLink(static_cast<decl_type*>(this));
- if (NamedDecl *ND = dyn_cast<NamedDecl>(static_cast<decl_type*>(this)))
- ND->ClearLinkageCache();
+ assert(!isa<NamedDecl>(static_cast<decl_type*>(this)) ||
+ cast<NamedDecl>(static_cast<decl_type*>(this))->isLinkageValid());
}
// Inline function definitions.
diff --git a/include/clang/AST/DeclAccessPair.h b/include/clang/AST/DeclAccessPair.h
index 7ecd8f8bcd78..5731308f55e6 100644
--- a/include/clang/AST/DeclAccessPair.h
+++ b/include/clang/AST/DeclAccessPair.h
@@ -19,6 +19,7 @@
#define LLVM_CLANG_AST_DECLACCESSPAIR_H
#include "clang/Basic/Specifiers.h"
+#include "llvm/Support/DataTypes.h"
namespace clang {
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index 50e202738dd4..852bb9ab0400 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -14,38 +14,40 @@
#ifndef LLVM_CLANG_AST_DECLBASE_H
#define LLVM_CLANG_AST_DECLBASE_H
-#include "clang/AST/Attr.h"
+#include "clang/AST/AttrIterator.h"
#include "clang/AST/DeclarationName.h"
-#include "clang/AST/Type.h"
#include "clang/Basic/Specifiers.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/PrettyStackTrace.h"
namespace clang {
-class DeclContext;
-class TranslationUnitDecl;
-class NamespaceDecl;
-class UsingDirectiveDecl;
-class NamedDecl;
-class FunctionDecl;
+class ASTMutationListener;
+class BlockDecl;
class CXXRecordDecl;
+class CompoundStmt;
+class DeclContext;
+class DeclarationName;
+class DependentDiagnostic;
class EnumDecl;
-class ObjCMethodDecl;
-class ObjCContainerDecl;
-class ObjCInterfaceDecl;
+class FunctionDecl;
+class LinkageSpecDecl;
+class Module;
+class NamedDecl;
+class NamespaceDecl;
class ObjCCategoryDecl;
-class ObjCProtocolDecl;
-class ObjCImplementationDecl;
class ObjCCategoryImplDecl;
+class ObjCContainerDecl;
class ObjCImplDecl;
-class LinkageSpecDecl;
-class BlockDecl;
-class DeclarationName;
-class CompoundStmt;
+class ObjCImplementationDecl;
+class ObjCInterfaceDecl;
+class ObjCMethodDecl;
+class ObjCProtocolDecl;
+struct PrintingPolicy;
+class Stmt;
class StoredDeclsMap;
-class DependentDiagnostic;
-class ASTMutationListener;
+class TranslationUnitDecl;
+class UsingDirectiveDecl;
}
namespace llvm {
@@ -133,7 +135,7 @@ public:
/// or member ends up here.
IDNS_Ordinary = 0x0020,
- /// Objective C @protocol.
+ /// Objective C \@protocol.
IDNS_ObjCProtocol = 0x0040,
/// This declaration is a friend function. A friend function
@@ -335,7 +337,10 @@ protected:
static void *AllocateDeserializedDecl(const ASTContext &Context,
unsigned ID,
unsigned Size);
-
+
+ /// \brief Update a potentially out-of-date declaration.
+ void updateOutOfDate(IdentifierInfo &II) const;
+
public:
/// \brief Source range that this declaration covers.
@@ -455,9 +460,7 @@ public:
/// getMaxAlignment - return the maximum alignment specified by attributes
/// on this decl, 0 if there are none.
- unsigned getMaxAlignment() const {
- return hasAttrs() ? getMaxAttrAlignment(getAttrs(), getASTContext()) : 0;
- }
+ unsigned getMaxAlignment() const;
/// setInvalidDecl - Indicates the Decl had a semantic error. This
/// allows for graceful error recovery.
@@ -593,7 +596,18 @@ public:
return 0;
}
-
+
+private:
+ Module *getOwningModuleSlow() const;
+
+public:
+ Module *getOwningModule() const {
+ if (!isFromASTFile())
+ return 0;
+
+ return getOwningModuleSlow();
+ }
+
unsigned getIdentifierNamespace() const {
return IdentifierNamespace;
}
@@ -851,6 +865,8 @@ public:
unsigned Indentation = 0);
// Debuggers don't usually respect default arguments.
LLVM_ATTRIBUTE_USED void dump() const;
+ // Same as dump(), but forces color printing.
+ LLVM_ATTRIBUTE_USED void dumpColor() const;
void dump(raw_ostream &Out) const;
// Debuggers don't usually respect default arguments.
LLVM_ATTRIBUTE_USED void dumpXML() const;
@@ -891,29 +907,9 @@ public:
virtual void print(raw_ostream &OS) const;
};
-class DeclContextLookupResult
- : public std::pair<NamedDecl**,NamedDecl**> {
-public:
- DeclContextLookupResult(NamedDecl **I, NamedDecl **E)
- : std::pair<NamedDecl**,NamedDecl**>(I, E) {}
- DeclContextLookupResult()
- : std::pair<NamedDecl**,NamedDecl**>() {}
+typedef llvm::MutableArrayRef<NamedDecl*> DeclContextLookupResult;
- using std::pair<NamedDecl**,NamedDecl**>::operator=;
-};
-
-class DeclContextLookupConstResult
- : public std::pair<NamedDecl*const*, NamedDecl*const*> {
-public:
- DeclContextLookupConstResult(std::pair<NamedDecl**,NamedDecl**> R)
- : std::pair<NamedDecl*const*, NamedDecl*const*>(R) {}
- DeclContextLookupConstResult(NamedDecl * const *I, NamedDecl * const *E)
- : std::pair<NamedDecl*const*, NamedDecl*const*>(I, E) {}
- DeclContextLookupConstResult()
- : std::pair<NamedDecl*const*, NamedDecl*const*>() {}
-
- using std::pair<NamedDecl*const*,NamedDecl*const*>::operator=;
-};
+typedef ArrayRef<NamedDecl *> DeclContextLookupConstResult;
/// DeclContext - This is used only as base class of specific decl types that
/// can act as declaration contexts. These decls are (only the top classes
@@ -935,19 +931,26 @@ class DeclContext {
/// \brief Whether this declaration context also has some external
/// storage that contains additional declarations that are lexically
/// part of this context.
- mutable unsigned ExternalLexicalStorage : 1;
+ mutable bool ExternalLexicalStorage : 1;
/// \brief Whether this declaration context also has some external
/// storage that contains additional declarations that are visible
/// in this context.
- mutable unsigned ExternalVisibleStorage : 1;
+ mutable bool ExternalVisibleStorage : 1;
+
+ /// \brief Whether this declaration context has had external visible
+ /// storage added since the last lookup. In this case, \c LookupPtr's
+ /// invariant may not hold and needs to be fixed before we perform
+ /// another lookup.
+ mutable bool NeedToReconcileExternalVisibleStorage : 1;
/// \brief Pointer to the data structure used to lookup declarations
/// within this context (or a DependentStoredDeclsMap if this is a
/// dependent context), and a bool indicating whether we have lazily
/// omitted any declarations from the map. We maintain the invariant
- /// that, if the map contains an entry for a DeclarationName, then it
- /// contains all relevant entries for that name.
+ /// that, if the map contains an entry for a DeclarationName (and we
+ /// haven't lazily omitted anything), then it contains all relevant
+ /// entries for that name.
mutable llvm::PointerIntPair<StoredDeclsMap*, 1, bool> LookupPtr;
protected:
@@ -970,10 +973,11 @@ protected:
static std::pair<Decl *, Decl *>
BuildDeclChain(ArrayRef<Decl*> Decls, bool FieldsAlreadyLoaded);
- DeclContext(Decl::Kind K)
- : DeclKind(K), ExternalLexicalStorage(false),
- ExternalVisibleStorage(false), LookupPtr(0, false), FirstDecl(0),
- LastDecl(0) { }
+ DeclContext(Decl::Kind K)
+ : DeclKind(K), ExternalLexicalStorage(false),
+ ExternalVisibleStorage(false),
+ NeedToReconcileExternalVisibleStorage(false), LookupPtr(0, false),
+ FirstDecl(0), LastDecl(0) {}
public:
~DeclContext();
@@ -1086,6 +1090,10 @@ public:
/// a C++ extern "C" linkage spec.
bool isExternCContext() const;
+ /// \brief Determines whether this context is, or is nested within,
+ /// a C++ extern "C++" linkage spec.
+ bool isExternCXXContext() const;
+
/// \brief Determine whether this declaration context is equivalent
/// to the declaration context DC.
bool Equals(const DeclContext *DC) const {
@@ -1160,7 +1168,7 @@ public:
/// contexts that are semanticaly connected to this declaration context,
/// in source order, including this context (which may be the only result,
/// for non-namespace contexts).
- void collectAllContexts(llvm::SmallVectorImpl<DeclContext *> &Contexts);
+ void collectAllContexts(SmallVectorImpl<DeclContext *> &Contexts);
/// decl_iterator - Iterates through the declarations stored
/// within this context.
@@ -1423,7 +1431,7 @@ public:
/// usual relationship between a DeclContext and the external source.
/// See the ASTImporter for the (few, but important) use cases.
void localUncachedLookup(DeclarationName Name,
- llvm::SmallVectorImpl<NamedDecl *> &Results);
+ SmallVectorImpl<NamedDecl *> &Results);
/// @brief Makes a declaration visible within this context.
///
@@ -1473,9 +1481,9 @@ public:
// Low-level accessors
/// \brief Mark the lookup table as needing to be built. This should be
- /// used only if setHasExternalLexicalStorage() has been called.
+ /// used only if setHasExternalLexicalStorage() has been called on any
+ /// decl context for which this is the primary context.
void setMustBuildLookupTable() {
- assert(ExternalLexicalStorage && "Requires external lexical storage");
LookupPtr.setInt(true);
}
@@ -1504,6 +1512,8 @@ public:
/// declarations visible in this context.
void setHasExternalVisibleStorage(bool ES = true) {
ExternalVisibleStorage = ES;
+ if (ES && LookupPtr.getPointer())
+ NeedToReconcileExternalVisibleStorage = true;
}
/// \brief Determine whether the given declaration is stored in the list of
@@ -1519,6 +1529,7 @@ public:
LLVM_ATTRIBUTE_USED void dumpDeclContext() const;
private:
+ void reconcileExternalVisibleStorage();
void LoadLexicalDeclsFromExternalStorage() const;
/// @brief Makes a declaration visible within this context, but
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 9cb56e2b3ccc..05ff49c64cea 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -15,11 +15,11 @@
#ifndef LLVM_CLANG_AST_DECLCXX_H
#define LLVM_CLANG_AST_DECLCXX_H
+#include "clang/AST/ASTUnresolvedSet.h"
+#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
-#include "clang/AST/Decl.h"
#include "clang/AST/TypeLoc.h"
-#include "clang/AST/UnresolvedSet.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallPtrSet.h"
@@ -69,17 +69,6 @@ public:
} // end namespace clang
namespace llvm {
- /// Implement simplify_type for AnyFunctionDecl, so that we can dyn_cast from
- /// AnyFunctionDecl to any function or function template declaration.
- template<> struct simplify_type<const ::clang::AnyFunctionDecl> {
- typedef ::clang::NamedDecl* SimpleType;
- static SimpleType getSimplifiedValue(const ::clang::AnyFunctionDecl &Val) {
- return Val;
- }
- };
- template<> struct simplify_type< ::clang::AnyFunctionDecl>
- : public simplify_type<const ::clang::AnyFunctionDecl> {};
-
// Provide PointerLikeTypeTraits for non-cvr pointers.
template<>
class PointerLikeTypeTraits< ::clang::AnyFunctionDecl> {
@@ -272,32 +261,25 @@ class CXXRecordDecl : public RecordDecl {
friend void TagDecl::startDefinition();
+ /// Values used in DefinitionData fields to represent special members.
+ enum SpecialMemberFlags {
+ SMF_DefaultConstructor = 0x1,
+ SMF_CopyConstructor = 0x2,
+ SMF_MoveConstructor = 0x4,
+ SMF_CopyAssignment = 0x8,
+ SMF_MoveAssignment = 0x10,
+ SMF_Destructor = 0x20,
+ SMF_All = 0x3f
+ };
+
struct DefinitionData {
DefinitionData(CXXRecordDecl *D);
- /// UserDeclaredConstructor - True when this class has a
- /// user-declared constructor.
+ /// \brief True if this class has any user-declared constructors.
bool UserDeclaredConstructor : 1;
- /// UserDeclaredCopyConstructor - True when this class has a
- /// user-declared copy constructor.
- bool UserDeclaredCopyConstructor : 1;
-
- /// UserDeclareMoveConstructor - True when this class has a
- /// user-declared move constructor.
- bool UserDeclaredMoveConstructor : 1;
-
- /// UserDeclaredCopyAssignment - True when this class has a
- /// user-declared copy assignment operator.
- bool UserDeclaredCopyAssignment : 1;
-
- /// UserDeclareMoveAssignment - True when this class has a
- /// user-declared move assignment.
- bool UserDeclaredMoveAssignment : 1;
-
- /// UserDeclaredDestructor - True when this class has a
- /// user-declared destructor.
- bool UserDeclaredDestructor : 1;
+ /// The user-declared special members which this class has.
+ unsigned UserDeclaredSpecialMembers : 6;
/// Aggregate - True when this class is an aggregate.
bool Aggregate : 1;
@@ -360,21 +342,46 @@ class CXXRecordDecl : public RecordDecl {
/// \brief True if any field has an in-class initializer.
bool HasInClassInitializer : 1;
- /// HasTrivialDefaultConstructor - True when, if this class has a default
- /// constructor, this default constructor is trivial.
+ /// \brief True if any field is of reference type, and does not have an
+ /// in-class initializer. In this case, value-initialization of this class
+ /// is illegal in C++98 even if the class has a trivial default constructor.
+ bool HasUninitializedReferenceMember : 1;
+
+ /// \brief These flags are \c true if a defaulted corresponding special
+ /// member can't be fully analyzed without performing overload resolution.
+ /// @{
+ bool NeedOverloadResolutionForMoveConstructor : 1;
+ bool NeedOverloadResolutionForMoveAssignment : 1;
+ bool NeedOverloadResolutionForDestructor : 1;
+ /// @}
+
+ /// \brief These flags are \c true if an implicit defaulted corresponding
+ /// special member would be defined as deleted.
+ /// @{
+ bool DefaultedMoveConstructorIsDeleted : 1;
+ bool DefaultedMoveAssignmentIsDeleted : 1;
+ bool DefaultedDestructorIsDeleted : 1;
+ /// @}
+
+ /// \brief The trivial special members which this class has, per
+ /// C++11 [class.ctor]p5, C++11 [class.copy]p12, C++11 [class.copy]p25,
+ /// C++11 [class.dtor]p5, or would have if the member were not suppressed.
+ ///
+ /// This excludes any user-declared but not user-provided special members
+ /// which have been declared but not yet defined.
+ unsigned HasTrivialSpecialMembers : 6;
+
+ /// \brief The declared special members of this class which are known to be
+ /// non-trivial.
///
- /// C++0x [class.ctor]p5
- /// A default constructor is trivial if it is not user-provided and if
- /// -- its class has no virtual functions and no virtual base classes,
- /// and
- /// -- no non-static data member of its class has a
- /// brace-or-equal-initializer, and
- /// -- all the direct base classes of its class have trivial
- /// default constructors, and
- /// -- for all the nonstatic data members of its class that are of class
- /// type (or array thereof), each such class has a trivial
- /// default constructor.
- bool HasTrivialDefaultConstructor : 1;
+ /// This excludes any user-declared but not user-provided special members
+ /// which have been declared but not yet defined, and any implicit special
+ /// members which have not yet been declared.
+ unsigned DeclaredNonTrivialSpecialMembers : 6;
+
+ /// HasIrrelevantDestructor - True when this class has a destructor with no
+ /// semantic effect.
+ bool HasIrrelevantDestructor : 1;
/// HasConstexprNonCopyMoveConstructor - True when this class has at least
/// one user-declared constexpr constructor which is neither the copy nor
@@ -389,80 +396,6 @@ class CXXRecordDecl : public RecordDecl {
/// default constructor (either user-declared or implicitly declared).
bool HasConstexprDefaultConstructor : 1;
- /// HasTrivialCopyConstructor - True when this class has a trivial copy
- /// constructor.
- ///
- /// C++0x [class.copy]p13:
- /// A copy/move constructor for class X is trivial if it is neither
- /// user-provided and if
- /// -- class X has no virtual functions and no virtual base classes, and
- /// -- the constructor selected to copy/move each direct base class
- /// subobject is trivial, and
- /// -- for each non-static data member of X that is of class type (or an
- /// array thereof), the constructor selected to copy/move that member
- /// is trivial;
- /// otherwise the copy/move constructor is non-trivial.
- bool HasTrivialCopyConstructor : 1;
-
- /// HasTrivialMoveConstructor - True when this class has a trivial move
- /// constructor.
- ///
- /// C++0x [class.copy]p13:
- /// A copy/move constructor for class X is trivial if it is neither
- /// user-provided and if
- /// -- class X has no virtual functions and no virtual base classes, and
- /// -- the constructor selected to copy/move each direct base class
- /// subobject is trivial, and
- /// -- for each non-static data member of X that is of class type (or an
- /// array thereof), the constructor selected to copy/move that member
- /// is trivial;
- /// otherwise the copy/move constructor is non-trivial.
- bool HasTrivialMoveConstructor : 1;
-
- /// HasTrivialCopyAssignment - True when this class has a trivial copy
- /// assignment operator.
- ///
- /// C++0x [class.copy]p27:
- /// A copy/move assignment operator for class X is trivial if it is
- /// neither user-provided nor deleted and if
- /// -- class X has no virtual functions and no virtual base classes, and
- /// -- the assignment operator selected to copy/move each direct base
- /// class subobject is trivial, and
- /// -- for each non-static data member of X that is of class type (or an
- /// array thereof), the assignment operator selected to copy/move
- /// that member is trivial;
- /// otherwise the copy/move assignment operator is non-trivial.
- bool HasTrivialCopyAssignment : 1;
-
- /// HasTrivialMoveAssignment - True when this class has a trivial move
- /// assignment operator.
- ///
- /// C++0x [class.copy]p27:
- /// A copy/move assignment operator for class X is trivial if it is
- /// neither user-provided nor deleted and if
- /// -- class X has no virtual functions and no virtual base classes, and
- /// -- the assignment operator selected to copy/move each direct base
- /// class subobject is trivial, and
- /// -- for each non-static data member of X that is of class type (or an
- /// array thereof), the assignment operator selected to copy/move
- /// that member is trivial;
- /// otherwise the copy/move assignment operator is non-trivial.
- bool HasTrivialMoveAssignment : 1;
-
- /// HasTrivialDestructor - True when this class has a trivial destructor.
- ///
- /// C++ [class.dtor]p3. A destructor is trivial if it is an
- /// implicitly-declared destructor and if:
- /// * all of the direct base classes of its class have trivial destructors
- /// and
- /// * for all of the non-static data members of its class that are of class
- /// type (or array thereof), each such class has a trivial destructor.
- bool HasTrivialDestructor : 1;
-
- /// HasIrrelevantDestructor - True when this class has a destructor with no
- /// semantic effect.
- bool HasIrrelevantDestructor : 1;
-
/// HasNonLiteralTypeFieldsOrBases - True when this class contains at least
/// one non-static data member or base class of non-literal or volatile
/// type.
@@ -472,27 +405,29 @@ class CXXRecordDecl : public RecordDecl {
/// already computed and are available.
bool ComputedVisibleConversions : 1;
- /// \brief Whether we have a C++0x user-provided default constructor (not
+ /// \brief Whether we have a C++11 user-provided default constructor (not
/// explicitly deleted or defaulted).
bool UserProvidedDefaultConstructor : 1;
- /// \brief Whether we have already declared the default constructor.
- bool DeclaredDefaultConstructor : 1;
+ /// \brief The special members which have been declared for this class,
+ /// either by the user or implicitly.
+ unsigned DeclaredSpecialMembers : 6;
- /// \brief Whether we have already declared the copy constructor.
- bool DeclaredCopyConstructor : 1;
+ /// \brief Whether an implicit copy constructor would have a const-qualified
+ /// parameter.
+ bool ImplicitCopyConstructorHasConstParam : 1;
- /// \brief Whether we have already declared the move constructor.
- bool DeclaredMoveConstructor : 1;
+ /// \brief Whether an implicit copy assignment operator would have a
+ /// const-qualified parameter.
+ bool ImplicitCopyAssignmentHasConstParam : 1;
- /// \brief Whether we have already declared the copy-assignment operator.
- bool DeclaredCopyAssignment : 1;
+ /// \brief Whether any declared copy constructor has a const-qualified
+ /// parameter.
+ bool HasDeclaredCopyConstructorWithConstParam : 1;
- /// \brief Whether we have already declared the move-assignment operator.
- bool DeclaredMoveAssignment : 1;
-
- /// \brief Whether we have already declared a destructor within the class.
- bool DeclaredDestructor : 1;
+ /// \brief Whether any declared copy assignment operator has either a
+ /// const-qualified reference parameter or a non-reference parameter.
+ bool HasDeclaredCopyAssignmentWithConstParam : 1;
/// \brief Whether an implicit move constructor was attempted to be declared
/// but would have been deleted.
@@ -522,14 +457,14 @@ class CXXRecordDecl : public RecordDecl {
/// of this C++ class (but not its inherited conversion
/// functions). Each of the entries in this overload set is a
/// CXXConversionDecl.
- UnresolvedSet<4> Conversions;
+ ASTUnresolvedSet Conversions;
/// VisibleConversions - Overload set containing the conversion
/// functions of this C++ class and all those inherited conversion
/// functions that are visible in this class. Each of the entries
/// in this overload set is a CXXConversionDecl or a
/// FunctionTemplateDecl.
- UnresolvedSet<4> VisibleConversions;
+ ASTUnresolvedSet VisibleConversions;
/// Definition - The declaration which defines this record.
CXXRecordDecl *Definition;
@@ -636,6 +571,10 @@ class CXXRecordDecl : public RecordDecl {
friend class DeclContext;
friend class LambdaExpr;
+ /// \brief Called from setBases and addedMember to notify the class that a
+ /// direct or virtual base class or a member of class type has been added.
+ void addedClassSubobject(CXXRecordDecl *Base);
+
/// \brief Notify the class that member has been added.
///
/// This routine helps maintain information about the class based on which
@@ -646,9 +585,6 @@ class CXXRecordDecl : public RecordDecl {
void markedVirtualFunctionPure();
friend void FunctionDecl::setPure(bool);
- void markedConstructorConstexpr(CXXConstructorDecl *CD);
- friend void FunctionDecl::setConstexpr(bool);
-
friend class ASTNodeImporter;
protected:
@@ -765,7 +701,8 @@ public:
return reverse_base_class_const_iterator(vbases_begin());
}
- /// \brief Determine whether this class has any dependent base classes.
+ /// \brief Determine whether this class has any dependent base classes which
+ /// are not the current instantiation.
bool hasAnyDependentBases() const;
/// Iterator access to method members. The method iterator visits
@@ -805,47 +742,38 @@ public:
return data().FirstFriend != 0;
}
+ /// \brief \c true if we know for sure that this class has a single,
+ /// accessible, unambiguous move constructor that is not deleted.
+ bool hasSimpleMoveConstructor() const {
+ return !hasUserDeclaredMoveConstructor() && hasMoveConstructor();
+ }
+ /// \brief \c true if we know for sure that this class has a single,
+ /// accessible, unambiguous move assignment operator that is not deleted.
+ bool hasSimpleMoveAssignment() const {
+ return !hasUserDeclaredMoveAssignment() && hasMoveAssignment();
+ }
+ /// \brief \c true if we know for sure that this class has an accessible
+ /// destructor that is not deleted.
+ bool hasSimpleDestructor() const {
+ return !hasUserDeclaredDestructor() &&
+ !data().DefaultedDestructorIsDeleted;
+ }
+
+ /// \brief Determine whether this class has any default constructors.
+ bool hasDefaultConstructor() const {
+ return (data().DeclaredSpecialMembers & SMF_DefaultConstructor) ||
+ needsImplicitDefaultConstructor();
+ }
+
/// \brief Determine if we need to declare a default constructor for
/// this class.
///
/// This value is used for lazy creation of default constructors.
bool needsImplicitDefaultConstructor() const {
return !data().UserDeclaredConstructor &&
- !data().DeclaredDefaultConstructor;
- }
-
- /// hasDeclaredDefaultConstructor - Whether this class's default constructor
- /// has been declared (either explicitly or implicitly).
- bool hasDeclaredDefaultConstructor() const {
- return data().DeclaredDefaultConstructor;
+ !(data().DeclaredSpecialMembers & SMF_DefaultConstructor);
}
- /// hasConstCopyConstructor - Determines whether this class has a
- /// copy constructor that accepts a const-qualified argument.
- bool hasConstCopyConstructor() const;
-
- /// getCopyConstructor - Returns the copy constructor for this class
- CXXConstructorDecl *getCopyConstructor(unsigned TypeQuals) const;
-
- /// getMoveConstructor - Returns the move constructor for this class
- CXXConstructorDecl *getMoveConstructor() const;
-
- /// \brief Retrieve the copy-assignment operator for this class, if available.
- ///
- /// This routine attempts to find the copy-assignment operator for this
- /// class, using a simplistic form of overload resolution.
- ///
- /// \param ArgIsConst Whether the argument to the copy-assignment operator
- /// is const-qualified.
- ///
- /// \returns The copy-assignment operator that can be invoked, or NULL if
- /// a unique copy-assignment operator could not be found.
- CXXMethodDecl *getCopyAssignmentOperator(bool ArgIsConst) const;
-
- /// getMoveAssignmentOperator - Returns the move assignment operator for this
- /// class
- CXXMethodDecl *getMoveAssignmentOperator() const;
-
/// hasUserDeclaredConstructor - Whether this class has any
/// user-declared constructors. When true, a default constructor
/// will not be implicitly declared.
@@ -863,35 +791,53 @@ public:
/// user-declared copy constructor. When false, a copy constructor
/// will be implicitly declared.
bool hasUserDeclaredCopyConstructor() const {
- return data().UserDeclaredCopyConstructor;
+ return data().UserDeclaredSpecialMembers & SMF_CopyConstructor;
}
- /// \brief Determine whether this class has had its copy constructor
- /// declared, either via the user or via an implicit declaration.
- ///
- /// This value is used for lazy creation of copy constructors.
- bool hasDeclaredCopyConstructor() const {
- return data().DeclaredCopyConstructor;
+ /// \brief Determine whether this class needs an implicit copy
+ /// constructor to be lazily declared.
+ bool needsImplicitCopyConstructor() const {
+ return !(data().DeclaredSpecialMembers & SMF_CopyConstructor);
+ }
+
+ /// \brief Determine whether we need to eagerly declare a defaulted copy
+ /// constructor for this class.
+ bool needsOverloadResolutionForCopyConstructor() const {
+ return data().HasMutableFields;
+ }
+
+ /// \brief Determine whether an implicit copy constructor for this type
+ /// would have a parameter with a const-qualified reference type.
+ bool implicitCopyConstructorHasConstParam() const {
+ return data().ImplicitCopyConstructorHasConstParam;
+ }
+
+ /// \brief Determine whether this class has a copy constructor with
+ /// a parameter type which is a reference to a const-qualified type.
+ bool hasCopyConstructorWithConstParam() const {
+ return data().HasDeclaredCopyConstructorWithConstParam ||
+ (needsImplicitCopyConstructor() &&
+ implicitCopyConstructorHasConstParam());
}
/// hasUserDeclaredMoveOperation - Whether this class has a user-
/// declared move constructor or assignment operator. When false, a
/// move constructor and assignment operator may be implicitly declared.
bool hasUserDeclaredMoveOperation() const {
- return data().UserDeclaredMoveConstructor ||
- data().UserDeclaredMoveAssignment;
+ return data().UserDeclaredSpecialMembers &
+ (SMF_MoveConstructor | SMF_MoveAssignment);
}
/// \brief Determine whether this class has had a move constructor
/// declared by the user.
bool hasUserDeclaredMoveConstructor() const {
- return data().UserDeclaredMoveConstructor;
+ return data().UserDeclaredSpecialMembers & SMF_MoveConstructor;
}
- /// \brief Determine whether this class has had a move constructor
- /// declared.
- bool hasDeclaredMoveConstructor() const {
- return data().DeclaredMoveConstructor;
+ /// \brief Determine whether this class has a move constructor.
+ bool hasMoveConstructor() const {
+ return (data().DeclaredSpecialMembers & SMF_MoveConstructor) ||
+ needsImplicitMoveConstructor();
}
/// \brief Determine whether implicit move constructor generation for this
@@ -908,44 +854,66 @@ public:
/// \brief Determine whether this class should get an implicit move
/// constructor or if any existing special member function inhibits this.
- ///
- /// Covers all bullets of C++0x [class.copy]p9 except the last, that the
- /// constructor wouldn't be deleted, which is only looked up from a cached
- /// result.
bool needsImplicitMoveConstructor() const {
return !hasFailedImplicitMoveConstructor() &&
- !hasDeclaredMoveConstructor() &&
+ !(data().DeclaredSpecialMembers & SMF_MoveConstructor) &&
!hasUserDeclaredCopyConstructor() &&
!hasUserDeclaredCopyAssignment() &&
!hasUserDeclaredMoveAssignment() &&
- !hasUserDeclaredDestructor();
+ !hasUserDeclaredDestructor() &&
+ !data().DefaultedMoveConstructorIsDeleted;
+ }
+
+ /// \brief Determine whether we need to eagerly declare a defaulted move
+ /// constructor for this class.
+ bool needsOverloadResolutionForMoveConstructor() const {
+ return data().NeedOverloadResolutionForMoveConstructor;
}
/// hasUserDeclaredCopyAssignment - Whether this class has a
/// user-declared copy assignment operator. When false, a copy
/// assigment operator will be implicitly declared.
bool hasUserDeclaredCopyAssignment() const {
- return data().UserDeclaredCopyAssignment;
+ return data().UserDeclaredSpecialMembers & SMF_CopyAssignment;
}
- /// \brief Determine whether this class has had its copy assignment operator
- /// declared, either via the user or via an implicit declaration.
- ///
- /// This value is used for lazy creation of copy assignment operators.
- bool hasDeclaredCopyAssignment() const {
- return data().DeclaredCopyAssignment;
+ /// \brief Determine whether this class needs an implicit copy
+ /// assignment operator to be lazily declared.
+ bool needsImplicitCopyAssignment() const {
+ return !(data().DeclaredSpecialMembers & SMF_CopyAssignment);
+ }
+
+ /// \brief Determine whether we need to eagerly declare a defaulted copy
+ /// assignment operator for this class.
+ bool needsOverloadResolutionForCopyAssignment() const {
+ return data().HasMutableFields;
+ }
+
+ /// \brief Determine whether an implicit copy assignment operator for this
+ /// type would have a parameter with a const-qualified reference type.
+ bool implicitCopyAssignmentHasConstParam() const {
+ return data().ImplicitCopyAssignmentHasConstParam;
+ }
+
+ /// \brief Determine whether this class has a copy assignment operator with
+ /// a parameter type which is a reference to a const-qualified type or is not
+ /// a reference..
+ bool hasCopyAssignmentWithConstParam() const {
+ return data().HasDeclaredCopyAssignmentWithConstParam ||
+ (needsImplicitCopyAssignment() &&
+ implicitCopyAssignmentHasConstParam());
}
/// \brief Determine whether this class has had a move assignment
/// declared by the user.
bool hasUserDeclaredMoveAssignment() const {
- return data().UserDeclaredMoveAssignment;
+ return data().UserDeclaredSpecialMembers & SMF_MoveAssignment;
}
- /// hasDeclaredMoveAssignment - Whether this class has a
- /// declared move assignment operator.
- bool hasDeclaredMoveAssignment() const {
- return data().DeclaredMoveAssignment;
+ /// \brief Determine whether this class has a move assignment operator.
+ bool hasMoveAssignment() const {
+ return (data().DeclaredSpecialMembers & SMF_MoveAssignment) ||
+ needsImplicitMoveAssignment();
}
/// \brief Determine whether implicit move assignment generation for this
@@ -963,34 +931,44 @@ public:
/// \brief Determine whether this class should get an implicit move
/// assignment operator or if any existing special member function inhibits
/// this.
- ///
- /// Covers all bullets of C++0x [class.copy]p20 except the last, that the
- /// constructor wouldn't be deleted.
bool needsImplicitMoveAssignment() const {
return !hasFailedImplicitMoveAssignment() &&
- !hasDeclaredMoveAssignment() &&
+ !(data().DeclaredSpecialMembers & SMF_MoveAssignment) &&
!hasUserDeclaredCopyConstructor() &&
!hasUserDeclaredCopyAssignment() &&
!hasUserDeclaredMoveConstructor() &&
- !hasUserDeclaredDestructor();
+ !hasUserDeclaredDestructor() &&
+ !data().DefaultedMoveAssignmentIsDeleted;
+ }
+
+ /// \brief Determine whether we need to eagerly declare a move assignment
+ /// operator for this class.
+ bool needsOverloadResolutionForMoveAssignment() const {
+ return data().NeedOverloadResolutionForMoveAssignment;
}
/// hasUserDeclaredDestructor - Whether this class has a
/// user-declared destructor. When false, a destructor will be
/// implicitly declared.
bool hasUserDeclaredDestructor() const {
- return data().UserDeclaredDestructor;
+ return data().UserDeclaredSpecialMembers & SMF_Destructor;
}
- /// \brief Determine whether this class has had its destructor declared,
- /// either via the user or via an implicit declaration.
- ///
- /// This value is used for lazy creation of destructors.
- bool hasDeclaredDestructor() const { return data().DeclaredDestructor; }
+ /// \brief Determine whether this class needs an implicit destructor to
+ /// be lazily declared.
+ bool needsImplicitDestructor() const {
+ return !(data().DeclaredSpecialMembers & SMF_Destructor);
+ }
+
+ /// \brief Determine whether we need to eagerly declare a destructor for this
+ /// class.
+ bool needsOverloadResolutionForDestructor() const {
+ return data().NeedOverloadResolutionForDestructor;
+ }
/// \brief Determine whether this class describes a lambda function object.
bool isLambda() const { return hasDefinition() && data().IsLambda; }
-
+
/// \brief For a closure type, retrieve the mapping from captured
/// variables and this to the non-static data members that store the
/// values or references of the captures.
@@ -1011,21 +989,12 @@ public:
return isLambda() ? captures_begin() + getLambdaData().NumCaptures : NULL;
}
- /// getConversions - Retrieve the overload set containing all of the
- /// conversion functions in this class.
- UnresolvedSetImpl *getConversionFunctions() {
- return &data().Conversions;
- }
- const UnresolvedSetImpl *getConversionFunctions() const {
- return &data().Conversions;
- }
-
- typedef UnresolvedSetImpl::iterator conversion_iterator;
+ typedef UnresolvedSetIterator conversion_iterator;
conversion_iterator conversion_begin() const {
- return getConversionFunctions()->begin();
+ return data().Conversions.begin();
}
conversion_iterator conversion_end() const {
- return getConversionFunctions()->end();
+ return data().Conversions.end();
}
/// Removes a conversion function from this class. The conversion
@@ -1035,7 +1004,8 @@ public:
/// getVisibleConversionFunctions - get all conversion functions visible
/// in current class; including conversion function templates.
- const UnresolvedSetImpl *getVisibleConversionFunctions();
+ std::pair<conversion_iterator, conversion_iterator>
+ getVisibleConversionFunctions();
/// isAggregate - Whether this class is an aggregate (C++
/// [dcl.init.aggr]), which is a class with no user-declared
@@ -1047,10 +1017,26 @@ public:
/// for non-static data members.
bool hasInClassInitializer() const { return data().HasInClassInitializer; }
+ /// \brief Whether this class or any of its subobjects has any members of
+ /// reference type which would make value-initialization ill-formed, per
+ /// C++03 [dcl.init]p5:
+ /// -- if T is a non-union class type without a user-declared constructor,
+ /// then every non-static data member and base-class component of T is
+ /// value-initialized
+ /// [...]
+ /// A program that calls for [...] value-initialization of an entity of
+ /// reference type is ill-formed.
+ bool hasUninitializedReferenceMember() const {
+ return !isUnion() && !hasUserDeclaredConstructor() &&
+ data().HasUninitializedReferenceMember;
+ }
+
/// isPOD - Whether this class is a POD-type (C++ [class]p4), which is a class
/// that is an aggregate that has no non-static non-POD data members, no
/// reference data members, no user-defined copy assignment operator and no
/// user-defined destructor.
+ ///
+ /// Note that this is the C++ TR1 definition of POD.
bool isPOD() const { return data().PlainOldData; }
/// \brief True if this class is C-like, without C++-specific features, e.g.
@@ -1079,64 +1065,110 @@ public:
/// mutable field.
bool hasMutableFields() const { return data().HasMutableFields; }
- /// hasTrivialDefaultConstructor - Whether this class has a trivial default
- /// constructor (C++11 [class.ctor]p5).
+ /// \brief Determine whether this class has a trivial default constructor
+ /// (C++11 [class.ctor]p5).
bool hasTrivialDefaultConstructor() const {
- return data().HasTrivialDefaultConstructor &&
- (!data().UserDeclaredConstructor ||
- data().DeclaredDefaultConstructor);
+ return hasDefaultConstructor() &&
+ (data().HasTrivialSpecialMembers & SMF_DefaultConstructor);
+ }
+
+ /// \brief Determine whether this class has a non-trivial default constructor
+ /// (C++11 [class.ctor]p5).
+ bool hasNonTrivialDefaultConstructor() const {
+ return (data().DeclaredNonTrivialSpecialMembers & SMF_DefaultConstructor) ||
+ (needsImplicitDefaultConstructor() &&
+ !(data().HasTrivialSpecialMembers & SMF_DefaultConstructor));
}
- /// hasConstexprNonCopyMoveConstructor - Whether this class has at least one
- /// constexpr constructor other than the copy or move constructors.
+ /// \brief Determine whether this class has at least one constexpr constructor
+ /// other than the copy or move constructors.
bool hasConstexprNonCopyMoveConstructor() const {
return data().HasConstexprNonCopyMoveConstructor ||
- (!hasUserDeclaredConstructor() &&
+ (needsImplicitDefaultConstructor() &&
defaultedDefaultConstructorIsConstexpr());
}
- /// defaultedDefaultConstructorIsConstexpr - Whether a defaulted default
- /// constructor for this class would be constexpr.
+ /// \brief Determine whether a defaulted default constructor for this class
+ /// would be constexpr.
bool defaultedDefaultConstructorIsConstexpr() const {
return data().DefaultedDefaultConstructorIsConstexpr &&
(!isUnion() || hasInClassInitializer());
}
- /// hasConstexprDefaultConstructor - Whether this class has a constexpr
- /// default constructor.
+ /// \brief Determine whether this class has a constexpr default constructor.
bool hasConstexprDefaultConstructor() const {
return data().HasConstexprDefaultConstructor ||
- (!data().UserDeclaredConstructor &&
+ (needsImplicitDefaultConstructor() &&
defaultedDefaultConstructorIsConstexpr());
}
- // hasTrivialCopyConstructor - Whether this class has a trivial copy
- // constructor (C++ [class.copy]p6, C++0x [class.copy]p13)
+ /// \brief Determine whether this class has a trivial copy constructor
+ /// (C++ [class.copy]p6, C++11 [class.copy]p12)
bool hasTrivialCopyConstructor() const {
- return data().HasTrivialCopyConstructor;
+ return data().HasTrivialSpecialMembers & SMF_CopyConstructor;
+ }
+
+ /// \brief Determine whether this class has a non-trivial copy constructor
+ /// (C++ [class.copy]p6, C++11 [class.copy]p12)
+ bool hasNonTrivialCopyConstructor() const {
+ return data().DeclaredNonTrivialSpecialMembers & SMF_CopyConstructor ||
+ !hasTrivialCopyConstructor();
}
- // hasTrivialMoveConstructor - Whether this class has a trivial move
- // constructor (C++0x [class.copy]p13)
+ /// \brief Determine whether this class has a trivial move constructor
+ /// (C++11 [class.copy]p12)
bool hasTrivialMoveConstructor() const {
- return data().HasTrivialMoveConstructor;
+ return hasMoveConstructor() &&
+ (data().HasTrivialSpecialMembers & SMF_MoveConstructor);
}
- // hasTrivialCopyAssignment - Whether this class has a trivial copy
- // assignment operator (C++ [class.copy]p11, C++0x [class.copy]p27)
+ /// \brief Determine whether this class has a non-trivial move constructor
+ /// (C++11 [class.copy]p12)
+ bool hasNonTrivialMoveConstructor() const {
+ return (data().DeclaredNonTrivialSpecialMembers & SMF_MoveConstructor) ||
+ (needsImplicitMoveConstructor() &&
+ !(data().HasTrivialSpecialMembers & SMF_MoveConstructor));
+ }
+
+ /// \brief Determine whether this class has a trivial copy assignment operator
+ /// (C++ [class.copy]p11, C++11 [class.copy]p25)
bool hasTrivialCopyAssignment() const {
- return data().HasTrivialCopyAssignment;
+ return data().HasTrivialSpecialMembers & SMF_CopyAssignment;
+ }
+
+ /// \brief Determine whether this class has a non-trivial copy assignment
+ /// operator (C++ [class.copy]p11, C++11 [class.copy]p25)
+ bool hasNonTrivialCopyAssignment() const {
+ return data().DeclaredNonTrivialSpecialMembers & SMF_CopyAssignment ||
+ !hasTrivialCopyAssignment();
}
- // hasTrivialMoveAssignment - Whether this class has a trivial move
- // assignment operator (C++0x [class.copy]p27)
+ /// \brief Determine whether this class has a trivial move assignment operator
+ /// (C++11 [class.copy]p25)
bool hasTrivialMoveAssignment() const {
- return data().HasTrivialMoveAssignment;
+ return hasMoveAssignment() &&
+ (data().HasTrivialSpecialMembers & SMF_MoveAssignment);
+ }
+
+ /// \brief Determine whether this class has a non-trivial move assignment
+ /// operator (C++11 [class.copy]p25)
+ bool hasNonTrivialMoveAssignment() const {
+ return (data().DeclaredNonTrivialSpecialMembers & SMF_MoveAssignment) ||
+ (needsImplicitMoveAssignment() &&
+ !(data().HasTrivialSpecialMembers & SMF_MoveAssignment));
}
- // hasTrivialDestructor - Whether this class has a trivial destructor
- // (C++ [class.dtor]p3)
- bool hasTrivialDestructor() const { return data().HasTrivialDestructor; }
+ /// \brief Determine whether this class has a trivial destructor
+ /// (C++ [class.dtor]p3)
+ bool hasTrivialDestructor() const {
+ return data().HasTrivialSpecialMembers & SMF_Destructor;
+ }
+
+ /// \brief Determine whether this class has a non-trivial destructor
+ /// (C++ [class.dtor]p3)
+ bool hasNonTrivialDestructor() const {
+ return !(data().HasTrivialSpecialMembers & SMF_Destructor);
+ }
// hasIrrelevantDestructor - Whether this class has a destructor which has no
// semantic effect. Any such destructor will be trivial, public, defaulted
@@ -1210,7 +1242,9 @@ public:
/// \brief If this class is an instantiation of a member class of a
/// class template specialization, retrieves the member specialization
/// information.
- MemberSpecializationInfo *getMemberSpecializationInfo() const;
+ MemberSpecializationInfo *getMemberSpecializationInfo() const {
+ return TemplateOrInstantiation.dyn_cast<MemberSpecializationInfo *>();
+ }
/// \brief Specify that this record is an instantiation of the
/// member class RD.
@@ -1256,6 +1290,10 @@ public:
return dyn_cast<FunctionDecl>(getDeclContext());
}
+ /// \brief Determine whether this dependent class is a current instantiation,
+ /// when viewed from within the given context.
+ bool isCurrentInstantiation(const DeclContext *CurContext) const;
+
/// \brief Determine whether this class is derived from the class \p Base.
///
/// This routine only determines whether this class is derived from \p Base,
@@ -1437,6 +1475,10 @@ public:
return (PathAccess > DeclAccess ? PathAccess : DeclAccess);
}
+ /// \brief Indicates that the declaration of a defaulted or deleted special
+ /// member function is now complete.
+ void finishedDefaultedOrDeletedMember(CXXMethodDecl *MD);
+
/// \brief Indicates that the definition of this class is now complete.
virtual void completeDefinition();
@@ -1490,6 +1532,9 @@ public:
getLambdaData().ContextDecl = ContextDecl;
}
+ /// \brief Returns the inheritance model used for this record.
+ MSInheritanceModel getMSInheritanceModel() const;
+
/// \brief Determine whether this lambda expression was known to be dependent
/// at the time it was created, even if its context does not appear to be
/// dependent.
@@ -1528,11 +1573,10 @@ protected:
CXXMethodDecl(Kind DK, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
- bool isStatic, StorageClass SCAsWritten, bool isInline,
+ StorageClass SC, bool isInline,
bool isConstexpr, SourceLocation EndLocation)
: FunctionDecl(DK, RD, StartLoc, NameInfo, T, TInfo,
- (isStatic ? SC_Static : SC_None),
- SCAsWritten, isInline, isConstexpr) {
+ SC, isInline, isConstexpr) {
if (EndLocation.isValid())
setRangeEnd(EndLocation);
}
@@ -1542,15 +1586,14 @@ public:
SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
- bool isStatic,
- StorageClass SCAsWritten,
+ StorageClass SC,
bool isInline,
bool isConstexpr,
SourceLocation EndLocation);
static CXXMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- bool isStatic() const { return getStorageClass() == SC_Static; }
+
+ bool isStatic() const;
bool isInstance() const { return !isStatic(); }
bool isConst() const { return getType()->castAs<FunctionType>()->isConst(); }
@@ -1958,7 +2001,7 @@ class CXXConstructorDecl : public CXXMethodDecl {
QualType T, TypeSourceInfo *TInfo,
bool isExplicitSpecified, bool isInline,
bool isImplicitlyDeclared, bool isConstexpr)
- : CXXMethodDecl(CXXConstructor, RD, StartLoc, NameInfo, T, TInfo, false,
+ : CXXMethodDecl(CXXConstructor, RD, StartLoc, NameInfo, T, TInfo,
SC_None, isInline, isConstexpr, SourceLocation()),
IsExplicitSpecified(isExplicitSpecified), ImplicitlyDefined(false),
CtorInitializers(0), NumCtorInitializers(0) {
@@ -2077,7 +2120,7 @@ public:
/// constructor (C++ [class.copy]p2, which can be used to copy the
/// class. @p TypeQuals will be set to the qualifiers on the
/// argument type. For example, @p TypeQuals would be set to @c
- /// QualType::Const for the following copy constructor:
+ /// Qualifiers::Const for the following copy constructor:
///
/// @code
/// class X {
@@ -2177,7 +2220,7 @@ class CXXDestructorDecl : public CXXMethodDecl {
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
bool isInline, bool isImplicitlyDeclared)
- : CXXMethodDecl(CXXDestructor, RD, StartLoc, NameInfo, T, TInfo, false,
+ : CXXMethodDecl(CXXDestructor, RD, StartLoc, NameInfo, T, TInfo,
SC_None, isInline, /*isConstexpr=*/false, SourceLocation()),
ImplicitlyDefined(false), OperatorDelete(0) {
setImplicit(isImplicitlyDeclared);
@@ -2244,7 +2287,7 @@ class CXXConversionDecl : public CXXMethodDecl {
QualType T, TypeSourceInfo *TInfo,
bool isInline, bool isExplicitSpecified,
bool isConstexpr, SourceLocation EndLocation)
- : CXXMethodDecl(CXXConversion, RD, StartLoc, NameInfo, T, TInfo, false,
+ : CXXMethodDecl(CXXConversion, RD, StartLoc, NameInfo, T, TInfo,
SC_None, isInline, isConstexpr, EndLocation),
IsExplicitSpecified(isExplicitSpecified) { }
diff --git a/include/clang/AST/DeclContextInternals.h b/include/clang/AST/DeclContextInternals.h
index 39f04c68a3c7..84f3698d6b58 100644
--- a/include/clang/AST/DeclContextInternals.h
+++ b/include/clang/AST/DeclContextInternals.h
@@ -15,10 +15,10 @@
#define LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H
#include "clang/AST/Decl.h"
-#include "clang/AST/DeclarationName.h"
#include "clang/AST/DeclCXX.h"
-#include "llvm/ADT/PointerUnion.h"
+#include "clang/AST/DeclarationName.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallVector.h"
#include <algorithm>
@@ -97,6 +97,22 @@ public:
== Vec.end() && "list still contains decl");
}
+ /// \brief Remove any declarations which were imported from an external
+ /// AST source.
+ void removeExternalDecls() {
+ if (isNull()) {
+ // Nothing to do.
+ } else if (NamedDecl *Singleton = getAsDecl()) {
+ if (Singleton->isFromASTFile())
+ *this = StoredDeclsList();
+ } else {
+ DeclsTy &Vec = *getAsVector();
+ Vec.erase(std::remove_if(Vec.begin(), Vec.end(),
+ std::mem_fun(&Decl::isFromASTFile)),
+ Vec.end());
+ }
+ }
+
/// getLookupResult - Return an array of all the decls that this list
/// represents.
DeclContext::lookup_result getLookupResult() {
@@ -117,7 +133,7 @@ public:
DeclsTy &Vector = *getAsVector();
// Otherwise, we have a range result.
- return DeclContext::lookup_result(&Vector[0], &Vector[0]+Vector.size());
+ return DeclContext::lookup_result(Vector.begin(), Vector.end());
}
/// HandleRedeclaration - If this is a redeclaration of an existing decl,
@@ -186,7 +202,7 @@ public:
// All other declarations go at the end of the list, but before any
// tag declarations. But we can be clever about tag declarations
// because there can only ever be one in a scope.
- } else if (Vec.back()->hasTagIdentifierNamespace()) {
+ } else if (!Vec.empty() && Vec.back()->hasTagIdentifierNamespace()) {
NamedDecl *TagD = Vec.back();
Vec.back() = D;
Vec.push_back(TagD);
diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h
index 37e45868b57c..253c23c199af 100644
--- a/include/clang/AST/DeclFriend.h
+++ b/include/clang/AST/DeclFriend.h
@@ -54,22 +54,40 @@ private:
/// True if this 'friend' declaration is unsupported. Eventually we
/// will support every possible friend declaration, but for now we
/// silently ignore some and set this flag to authorize all access.
- bool UnsupportedFriend;
+ bool UnsupportedFriend : 1;
+
+ // The number of "outer" template parameter lists in non-templatic
+ // (currently unsupported) friend type declarations, such as
+ // template <class T> friend class A<T>::B;
+ unsigned NumTPLists : 31;
+
+ // The tail-allocated friend type template parameter lists (if any).
+ TemplateParameterList* const *getTPLists() const {
+ return reinterpret_cast<TemplateParameterList* const *>(this + 1);
+ }
+ TemplateParameterList **getTPLists() {
+ return reinterpret_cast<TemplateParameterList**>(this + 1);
+ }
friend class CXXRecordDecl::friend_iterator;
friend class CXXRecordDecl;
FriendDecl(DeclContext *DC, SourceLocation L, FriendUnion Friend,
- SourceLocation FriendL)
+ SourceLocation FriendL,
+ ArrayRef<TemplateParameterList*> FriendTypeTPLists)
: Decl(Decl::Friend, DC, L),
Friend(Friend),
NextFriend(),
FriendLoc(FriendL),
- UnsupportedFriend(false) {
+ UnsupportedFriend(false),
+ NumTPLists(FriendTypeTPLists.size()) {
+ for (unsigned i = 0; i < NumTPLists; ++i)
+ getTPLists()[i] = FriendTypeTPLists[i];
}
- explicit FriendDecl(EmptyShell Empty)
- : Decl(Decl::Friend, Empty), NextFriend() { }
+ FriendDecl(EmptyShell Empty, unsigned NumFriendTypeTPLists)
+ : Decl(Decl::Friend, Empty), NextFriend(),
+ NumTPLists(NumFriendTypeTPLists) { }
FriendDecl *getNextFriend() {
if (!NextFriend.isOffset())
@@ -81,8 +99,11 @@ private:
public:
static FriendDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, FriendUnion Friend_,
- SourceLocation FriendL);
- static FriendDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+ SourceLocation FriendL,
+ ArrayRef<TemplateParameterList*> FriendTypeTPLists
+ = ArrayRef<TemplateParameterList*>());
+ static FriendDecl *CreateDeserialized(ASTContext &C, unsigned ID,
+ unsigned FriendTypeNumTPLists);
/// If this friend declaration names an (untemplated but possibly
/// dependent) type, return the type; otherwise return null. This
@@ -91,6 +112,13 @@ public:
TypeSourceInfo *getFriendType() const {
return Friend.dyn_cast<TypeSourceInfo*>();
}
+ unsigned getFriendTypeNumTemplateParameterLists() const {
+ return NumTPLists;
+ }
+ TemplateParameterList *getFriendTypeTemplateParameterList(unsigned N) const {
+ assert(N < NumTPLists);
+ return getTPLists()[N];
+ }
/// If this friend declaration doesn't name a type, return the inner
/// declaration.
@@ -114,8 +142,12 @@ public:
}
return SourceRange(getFriendLoc(), ND->getLocEnd());
}
- else if (TypeSourceInfo *TInfo = getFriendType())
- return SourceRange(getFriendLoc(), TInfo->getTypeLoc().getEndLoc());
+ else if (TypeSourceInfo *TInfo = getFriendType()) {
+ SourceLocation StartL = (NumTPLists == 0)
+ ? getFriendLoc()
+ : getTPLists()[0]->getTemplateLoc();
+ return SourceRange(StartL, TInfo->getTypeLoc().getEndLoc());
+ }
else
return SourceRange(getFriendLoc(), getLocation());
}
diff --git a/include/clang/AST/DeclLookups.h b/include/clang/AST/DeclLookups.h
index 867b46525753..4477c25a9135 100644
--- a/include/clang/AST/DeclLookups.h
+++ b/include/clang/AST/DeclLookups.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_AST_DECLLOOKUPS_H
#define LLVM_CLANG_AST_DECLLOOKUPS_H
+#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclContextInternals.h"
#include "clang/AST/DeclarationName.h"
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index 8b27dd8e9e16..c29492298bfc 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -159,6 +159,9 @@ private:
/// method in the interface or its categories.
unsigned IsOverriding : 1;
+ /// \brief Indicates if the method was a definition but its body was skipped.
+ unsigned HasSkippedBody : 1;
+
// Result type of this method.
QualType MethodDeclType;
@@ -238,7 +241,7 @@ private:
IsDefined(isDefined), IsRedeclaration(0), HasRedeclaration(0),
DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None),
RelatedResultType(HasRelatedResultType),
- SelLocsKind(SelLoc_StandardNoSpace), IsOverriding(0),
+ SelLocsKind(SelLoc_StandardNoSpace), IsOverriding(0), HasSkippedBody(0),
MethodDeclType(T), ResultTInfo(ResultTInfo),
ParamsAndSelLocs(0), NumParams(0),
DeclEndLoc(endLoc), Body(), SelfDecl(0), CmdDecl(0) {
@@ -429,6 +432,10 @@ public:
void getOverriddenMethods(
SmallVectorImpl<const ObjCMethodDecl *> &Overridden) const;
+ /// \brief True if the method was a definition but its body was skipped.
+ bool hasSkippedBody() const { return HasSkippedBody; }
+ void setHasSkippedBody(bool Skipped = true) { HasSkippedBody = Skipped; }
+
/// \brief Returns the property associated with this method's selector.
///
/// Note that even if this particular method is not marked as a property
@@ -530,23 +537,29 @@ public:
}
// Get the local instance/class method declared in this interface.
- ObjCMethodDecl *getMethod(Selector Sel, bool isInstance) const;
- ObjCMethodDecl *getInstanceMethod(Selector Sel) const {
- return getMethod(Sel, true/*isInstance*/);
+ ObjCMethodDecl *getMethod(Selector Sel, bool isInstance,
+ bool AllowHidden = false) const;
+ ObjCMethodDecl *getInstanceMethod(Selector Sel,
+ bool AllowHidden = false) const {
+ return getMethod(Sel, true/*isInstance*/, AllowHidden);
}
- ObjCMethodDecl *getClassMethod(Selector Sel) const {
- return getMethod(Sel, false/*isInstance*/);
+ ObjCMethodDecl *getClassMethod(Selector Sel, bool AllowHidden = false) const {
+ return getMethod(Sel, false/*isInstance*/, AllowHidden);
}
+ bool HasUserDeclaredSetterMethod(const ObjCPropertyDecl *P) const;
ObjCIvarDecl *getIvarDecl(IdentifierInfo *Id) const;
ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const;
typedef llvm::DenseMap<IdentifierInfo*, ObjCPropertyDecl*> PropertyMap;
-
+
+ typedef llvm::SmallVector<ObjCPropertyDecl*, 8> PropertyDeclOrder;
+
/// 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 {}
+ virtual void collectPropertiesToImplement(PropertyMap &PM,
+ PropertyDeclOrder &PO) const {}
SourceLocation getAtStartLoc() const { return AtStart; }
void setAtStartLoc(SourceLocation Loc) { AtStart = Loc; }
@@ -641,6 +654,10 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
/// completed by the external AST source when required.
mutable bool ExternallyCompleted : 1;
+ /// \brief Indicates that the ivar cache does not yet include ivars
+ /// declared in the implementation.
+ mutable bool IvarListMissingImplementation : 1;
+
/// \brief The location of the superclass, if any.
SourceLocation SuperClassLoc;
@@ -650,7 +667,8 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
SourceLocation EndLoc;
DefinitionData() : Definition(), SuperClass(), CategoryList(), IvarList(),
- ExternallyCompleted() { }
+ ExternallyCompleted(),
+ IvarListMissingImplementation(true) { }
};
ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
@@ -661,11 +679,14 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
/// \brief Contains a pointer to the data associated with this class,
/// which will be NULL if this class has not yet been defined.
- DefinitionData *Data;
+ ///
+ /// The bit indicates when we don't need to check for out-of-date
+ /// declarations. It will be set unless modules are enabled.
+ llvm::PointerIntPair<DefinitionData *, 1, bool> Data;
DefinitionData &data() const {
- assert(Data != 0 && "Declaration has no definition!");
- return *Data;
+ assert(Data.getPointer() && "Declaration has no definition!");
+ return *Data.getPointer();
}
/// \brief Allocate the definition data for this class.
@@ -673,7 +694,7 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
typedef Redeclarable<ObjCInterfaceDecl> redeclarable_base;
virtual ObjCInterfaceDecl *getNextRedeclaration() {
- return RedeclLink.getNext();
+ return RedeclLink.getNext();
}
virtual ObjCInterfaceDecl *getPreviousDeclImpl() {
return getPreviousDecl();
@@ -846,24 +867,38 @@ public:
/// \brief Determine whether this particular declaration of this class is
/// actually also a definition.
bool isThisDeclarationADefinition() const {
- return Data && Data->Definition == this;
+ return getDefinition() == this;
}
/// \brief Determine whether this class has been defined.
- bool hasDefinition() const { return Data; }
+ bool hasDefinition() const {
+ // If the name of this class is out-of-date, bring it up-to-date, which
+ // might bring in a definition.
+ // Note: a null value indicates that we don't have a definition and that
+ // modules are enabled.
+ if (!Data.getOpaqueValue()) {
+ if (IdentifierInfo *II = getIdentifier()) {
+ if (II->isOutOfDate()) {
+ updateOutOfDate(*II);
+ }
+ }
+ }
+
+ return Data.getPointer();
+ }
/// \brief Retrieve the definition of this class, or NULL if this class
/// has been forward-declared (with \@class) but not yet defined (with
/// \@interface).
ObjCInterfaceDecl *getDefinition() {
- return hasDefinition()? Data->Definition : 0;
+ return hasDefinition()? Data.getPointer()->Definition : 0;
}
/// \brief Retrieve the definition of this class, or NULL if this class
/// has been forward-declared (with \@class) but not yet defined (with
/// \@interface).
const ObjCInterfaceDecl *getDefinition() const {
- return hasDefinition()? Data->Definition : 0;
+ return hasDefinition()? Data.getPointer()->Definition : 0;
}
/// \brief Starts the definition of this Objective-C class, taking it from
@@ -887,7 +922,166 @@ public:
: superCls;
}
- ObjCCategoryDecl* getCategoryList() const {
+ /// \brief Iterator that walks over the list of categories, filtering out
+ /// those that do not meet specific criteria.
+ ///
+ /// This class template is used for the various permutations of category
+ /// and extension iterators.
+ template<bool (*Filter)(ObjCCategoryDecl *)>
+ class filtered_category_iterator {
+ ObjCCategoryDecl *Current;
+
+ void findAcceptableCategory();
+
+ public:
+ typedef ObjCCategoryDecl * value_type;
+ typedef value_type reference;
+ typedef value_type pointer;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::input_iterator_tag iterator_category;
+
+ filtered_category_iterator() : Current(0) { }
+ explicit filtered_category_iterator(ObjCCategoryDecl *Current)
+ : Current(Current)
+ {
+ findAcceptableCategory();
+ }
+
+ reference operator*() const { return Current; }
+ pointer operator->() const { return Current; }
+
+ filtered_category_iterator &operator++();
+
+ filtered_category_iterator operator++(int) {
+ filtered_category_iterator Tmp = *this;
+ ++(*this);
+ return Tmp;
+ }
+
+ friend bool operator==(filtered_category_iterator X,
+ filtered_category_iterator Y) {
+ return X.Current == Y.Current;
+ }
+
+ friend bool operator!=(filtered_category_iterator X,
+ filtered_category_iterator Y) {
+ return X.Current != Y.Current;
+ }
+ };
+
+private:
+ /// \brief Test whether the given category is visible.
+ ///
+ /// Used in the \c visible_categories_iterator.
+ static bool isVisibleCategory(ObjCCategoryDecl *Cat);
+
+public:
+ /// \brief Iterator that walks over the list of categories and extensions
+ /// that are visible, i.e., not hidden in a non-imported submodule.
+ typedef filtered_category_iterator<isVisibleCategory>
+ visible_categories_iterator;
+
+ /// \brief Retrieve an iterator to the beginning of the visible-categories
+ /// list.
+ visible_categories_iterator visible_categories_begin() const {
+ return visible_categories_iterator(getCategoryListRaw());
+ }
+
+ /// \brief Retrieve an iterator to the end of the visible-categories list.
+ visible_categories_iterator visible_categories_end() const {
+ return visible_categories_iterator();
+ }
+
+ /// \brief Determine whether the visible-categories list is empty.
+ bool visible_categories_empty() const {
+ return visible_categories_begin() == visible_categories_end();
+ }
+
+private:
+ /// \brief Test whether the given category... is a category.
+ ///
+ /// Used in the \c known_categories_iterator.
+ static bool isKnownCategory(ObjCCategoryDecl *) { return true; }
+
+public:
+ /// \brief Iterator that walks over all of the known categories and
+ /// extensions, including those that are hidden.
+ typedef filtered_category_iterator<isKnownCategory> known_categories_iterator;
+
+ /// \brief Retrieve an iterator to the beginning of the known-categories
+ /// list.
+ known_categories_iterator known_categories_begin() const {
+ return known_categories_iterator(getCategoryListRaw());
+ }
+
+ /// \brief Retrieve an iterator to the end of the known-categories list.
+ known_categories_iterator known_categories_end() const {
+ return known_categories_iterator();
+ }
+
+ /// \brief Determine whether the known-categories list is empty.
+ bool known_categories_empty() const {
+ return known_categories_begin() == known_categories_end();
+ }
+
+private:
+ /// \brief Test whether the given category is a visible extension.
+ ///
+ /// Used in the \c visible_extensions_iterator.
+ static bool isVisibleExtension(ObjCCategoryDecl *Cat);
+
+public:
+ /// \brief Iterator that walks over all of the visible extensions, skipping
+ /// any that are known but hidden.
+ typedef filtered_category_iterator<isVisibleExtension>
+ visible_extensions_iterator;
+
+ /// \brief Retrieve an iterator to the beginning of the visible-extensions
+ /// list.
+ visible_extensions_iterator visible_extensions_begin() const {
+ return visible_extensions_iterator(getCategoryListRaw());
+ }
+
+ /// \brief Retrieve an iterator to the end of the visible-extensions list.
+ visible_extensions_iterator visible_extensions_end() const {
+ return visible_extensions_iterator();
+ }
+
+ /// \brief Determine whether the visible-extensions list is empty.
+ bool visible_extensions_empty() const {
+ return visible_extensions_begin() == visible_extensions_end();
+ }
+
+private:
+ /// \brief Test whether the given category is an extension.
+ ///
+ /// Used in the \c known_extensions_iterator.
+ static bool isKnownExtension(ObjCCategoryDecl *Cat);
+
+public:
+ /// \brief Iterator that walks over all of the known extensions.
+ typedef filtered_category_iterator<isKnownExtension>
+ known_extensions_iterator;
+
+ /// \brief Retrieve an iterator to the beginning of the known-extensions
+ /// list.
+ known_extensions_iterator known_extensions_begin() const {
+ return known_extensions_iterator(getCategoryListRaw());
+ }
+
+ /// \brief Retrieve an iterator to the end of the known-extensions list.
+ known_extensions_iterator known_extensions_end() const {
+ return known_extensions_iterator();
+ }
+
+ /// \brief Determine whether the known-extensions list is empty.
+ bool known_extensions_empty() const {
+ return known_extensions_begin() == known_extensions_end();
+ }
+
+ /// \brief Retrieve the raw pointer to the start of the category/extension
+ /// list.
+ ObjCCategoryDecl* getCategoryListRaw() const {
// FIXME: Should make sure no callers ever do this.
if (!hasDefinition())
return 0;
@@ -898,16 +1092,17 @@ public:
return data().CategoryList;
}
- void setCategoryList(ObjCCategoryDecl *category) {
+ /// \brief Set the raw pointer to the start of the category/extension
+ /// list.
+ void setCategoryListRaw(ObjCCategoryDecl *category) {
data().CategoryList = category;
}
- ObjCCategoryDecl* getFirstClassExtension() const;
-
ObjCPropertyDecl
*FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId) const;
- virtual void collectPropertiesToImplement(PropertyMap &PM) const;
+ virtual void collectPropertiesToImplement(PropertyMap &PM,
+ PropertyDeclOrder &PO) const;
/// isSuperClassOf - Return true if this class is the specified class or is a
/// super class of the specified interface class.
@@ -924,28 +1119,12 @@ public:
/// isArcWeakrefUnavailable - Checks for a class or one of its super classes
/// to be incompatible with __weak references. Returns true if it is.
- bool isArcWeakrefUnavailable() const {
- const ObjCInterfaceDecl *Class = this;
- while (Class) {
- if (Class->hasAttr<ArcWeakrefUnavailableAttr>())
- return true;
- Class = Class->getSuperClass();
- }
- return false;
- }
+ bool isArcWeakrefUnavailable() const;
/// isObjCRequiresPropertyDefs - Checks that a class or one of its super
/// classes must not be auto-synthesized. Returns class decl. if it must not
/// be; 0, otherwise.
- const ObjCInterfaceDecl *isObjCRequiresPropertyDefs() const {
- const ObjCInterfaceDecl *Class = this;
- while (Class) {
- if (Class->hasAttr<ObjCRequiresPropertyDefsAttr>())
- return Class;
- Class = Class->getSuperClass();
- }
- return 0;
- }
+ const ObjCInterfaceDecl *isObjCRequiresPropertyDefs() const;
ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName,
ObjCInterfaceDecl *&ClassDeclared);
@@ -992,7 +1171,7 @@ public:
/// ObjCInterfaceDecl node. This is for legacy objective-c \@implementation
/// declaration without an \@interface declaration.
bool isImplicitInterfaceDecl() const {
- return hasDefinition() ? Data->Definition->isImplicit() : isImplicit();
+ return hasDefinition() ? data().Definition->isImplicit() : isImplicit();
}
/// ClassImplementsProtocol - Checks that 'lProto' protocol
@@ -1169,12 +1348,17 @@ class ObjCProtocolDecl : public ObjCContainerDecl,
/// \brief Referenced protocols
ObjCProtocolList ReferencedProtocols;
};
-
- DefinitionData *Data;
+
+ /// \brief Contains a pointer to the data associated with this class,
+ /// which will be NULL if this class has not yet been defined.
+ ///
+ /// The bit indicates when we don't need to check for out-of-date
+ /// declarations. It will be set unless modules are enabled.
+ llvm::PointerIntPair<DefinitionData *, 1, bool> Data;
DefinitionData &data() const {
- assert(Data && "Objective-C protocol has no definition!");
- return *Data;
+ assert(Data.getPointer() && "Objective-C protocol has no definition!");
+ return *Data.getPointer();
}
ObjCProtocolDecl(DeclContext *DC, IdentifierInfo *Id,
@@ -1193,7 +1377,7 @@ class ObjCProtocolDecl : public ObjCContainerDecl,
virtual ObjCProtocolDecl *getMostRecentDeclImpl() {
return getMostRecentDecl();
}
-
+
public:
static ObjCProtocolDecl *Create(ASTContext &C, DeclContext *DC,
IdentifierInfo *Id,
@@ -1244,7 +1428,7 @@ public:
/// implements.
void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num,
const SourceLocation *Locs, ASTContext &C) {
- assert(Data && "Protocol is not defined");
+ assert(hasDefinition() && "Protocol is not defined");
data().ReferencedProtocols.set(List, Num, Locs, C);
}
@@ -1261,16 +1445,30 @@ public:
}
/// \brief Determine whether this protocol has a definition.
- bool hasDefinition() const { return Data != 0; }
+ bool hasDefinition() const {
+ // If the name of this protocol is out-of-date, bring it up-to-date, which
+ // might bring in a definition.
+ // Note: a null value indicates that we don't have a definition and that
+ // modules are enabled.
+ if (!Data.getOpaqueValue()) {
+ if (IdentifierInfo *II = getIdentifier()) {
+ if (II->isOutOfDate()) {
+ updateOutOfDate(*II);
+ }
+ }
+ }
+
+ return Data.getPointer();
+ }
/// \brief Retrieve the definition of this protocol, if any.
ObjCProtocolDecl *getDefinition() {
- return Data? Data->Definition : 0;
+ return hasDefinition()? Data.getPointer()->Definition : 0;
}
/// \brief Retrieve the definition of this protocol, if any.
const ObjCProtocolDecl *getDefinition() const {
- return Data? Data->Definition : 0;
+ return hasDefinition()? Data.getPointer()->Definition : 0;
}
/// \brief Determine whether this particular declaration is also the
@@ -1303,7 +1501,8 @@ public:
return getFirstDeclaration();
}
- virtual void collectPropertiesToImplement(PropertyMap &PM) const;
+ virtual void collectPropertiesToImplement(PropertyMap &PM,
+ PropertyDeclOrder &PO) const;
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == ObjCProtocol; }
@@ -1360,6 +1559,7 @@ class ObjCCategoryDecl : public ObjCContainerDecl {
CategoryNameLoc(CategoryNameLoc),
IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc) {
}
+
public:
static ObjCCategoryDecl *Create(ASTContext &C, DeclContext *DC,
@@ -1403,8 +1603,13 @@ public:
ObjCCategoryDecl *getNextClassCategory() const { return NextClassCategory; }
+ /// \brief Retrieve the pointer to the next stored category (or extension),
+ /// which may be hidden.
+ ObjCCategoryDecl *getNextClassCategoryRaw() const {
+ return NextClassCategory;
+ }
+
bool IsClassExtension() const { return getIdentifier() == 0; }
- const ObjCCategoryDecl *getNextClassExtension() const;
typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
ivar_iterator ivar_begin() const {
@@ -1847,7 +2052,7 @@ public:
PropertyAttributesAsWritten = PRVal;
}
- void makeitReadWriteAttribute(void) {
+ void makeitReadWriteAttribute() {
PropertyAttributes &= ~OBJC_PR_readonly;
PropertyAttributes |= OBJC_PR_readwrite;
}
@@ -2039,5 +2244,33 @@ public:
friend class ASTDeclReader;
};
+template<bool (*Filter)(ObjCCategoryDecl *)>
+void
+ObjCInterfaceDecl::filtered_category_iterator<Filter>::
+findAcceptableCategory() {
+ while (Current && !Filter(Current))
+ Current = Current->getNextClassCategoryRaw();
+}
+
+template<bool (*Filter)(ObjCCategoryDecl *)>
+inline ObjCInterfaceDecl::filtered_category_iterator<Filter> &
+ObjCInterfaceDecl::filtered_category_iterator<Filter>::operator++() {
+ Current = Current->getNextClassCategoryRaw();
+ findAcceptableCategory();
+ return *this;
+}
+
+inline bool ObjCInterfaceDecl::isVisibleCategory(ObjCCategoryDecl *Cat) {
+ return !Cat->isHidden();
+}
+
+inline bool ObjCInterfaceDecl::isVisibleExtension(ObjCCategoryDecl *Cat) {
+ return Cat->IsClassExtension() && !Cat->isHidden();
+}
+
+inline bool ObjCInterfaceDecl::isKnownExtension(ObjCCategoryDecl *Cat) {
+ return Cat->IsClassExtension();
+}
+
} // end namespace clang
#endif
diff --git a/include/clang/AST/DeclOpenMP.h b/include/clang/AST/DeclOpenMP.h
new file mode 100644
index 000000000000..ca92040c3286
--- /dev/null
+++ b/include/clang/AST/DeclOpenMP.h
@@ -0,0 +1,83 @@
+//===--- OpenMP.h - Classes for representing OpenMP directives ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This file defines OpenMP nodes.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_OPENMP_H
+#define LLVM_CLANG_AST_OPENMP_H
+
+#include "clang/AST/DeclBase.h"
+#include "llvm/ADT/ArrayRef.h"
+
+namespace clang {
+
+class DeclRefExpr;
+
+/// \brief This represents '#pragma omp threadprivate ...' directive.
+/// For example, in the following, both 'a' and 'A::b' are threadprivate:
+///
+/// \code
+/// int a;
+/// #pragma omp threadprivate(a)
+/// struct A {
+/// static int b;
+/// #pragma omp threadprivate(b)
+/// };
+/// \endcode
+///
+class OMPThreadPrivateDecl : public Decl {
+ friend class ASTDeclReader;
+ unsigned NumVars;
+
+ virtual void anchor();
+
+ OMPThreadPrivateDecl(Kind DK, DeclContext *DC, SourceLocation L) :
+ Decl(DK, DC, L), NumVars(0) { }
+
+ ArrayRef<const DeclRefExpr *> getVars() const {
+ return ArrayRef<const DeclRefExpr *>(
+ reinterpret_cast<const DeclRefExpr * const *>(this + 1),
+ NumVars);
+ }
+
+ llvm::MutableArrayRef<DeclRefExpr *> getVars() {
+ return llvm::MutableArrayRef<DeclRefExpr *>(
+ reinterpret_cast<DeclRefExpr **>(this + 1),
+ NumVars);
+ }
+
+ void setVars(ArrayRef<DeclRefExpr *> VL);
+
+public:
+ static OMPThreadPrivateDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L,
+ ArrayRef<DeclRefExpr *> VL);
+ static OMPThreadPrivateDecl *CreateDeserialized(ASTContext &C,
+ unsigned ID, unsigned N);
+
+ typedef llvm::MutableArrayRef<DeclRefExpr *>::iterator varlist_iterator;
+ typedef ArrayRef<const DeclRefExpr *>::iterator varlist_const_iterator;
+
+ unsigned varlist_size() const { return NumVars; }
+ bool varlist_empty() const { return NumVars == 0; }
+ varlist_iterator varlist_begin() { return getVars().begin(); }
+ varlist_iterator varlist_end() { return getVars().end(); }
+ varlist_const_iterator varlist_begin() const { return getVars().begin(); }
+ varlist_const_iterator varlist_end() const { return getVars().end(); }
+
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classofKind(Kind K) { return K == OMPThreadPrivate; }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index 862011666205..425a617738b0 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -84,6 +84,13 @@ public:
unsigned size() const { return NumParams; }
+ llvm::ArrayRef<NamedDecl*> asArray() {
+ return llvm::ArrayRef<NamedDecl*>(begin(), size());
+ }
+ llvm::ArrayRef<const NamedDecl*> asArray() const {
+ return llvm::ArrayRef<const NamedDecl*>(begin(), size());
+ }
+
NamedDecl* getParam(unsigned Idx) {
assert(Idx < size() && "Template parameter index out-of-range");
return begin()[Idx];
@@ -193,6 +200,11 @@ public:
/// \brief Retrieve the template argument at a given index.
const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); }
+ /// \brief Produce this as an array ref.
+ llvm::ArrayRef<TemplateArgument> asArray() const {
+ return llvm::ArrayRef<TemplateArgument>(data(), size());
+ }
+
/// \brief Retrieve the number of template arguments in this
/// template argument list.
unsigned size() const { return NumArguments; }
@@ -324,6 +336,23 @@ public:
return getTemplateSpecializationKind() == TSK_ExplicitSpecialization;
}
+ /// \brief True if this declaration is an explicit specialization,
+ /// explicit instantiation declaration, or explicit instantiation
+ /// definition.
+ bool isExplicitInstantiationOrSpecialization() const {
+ switch (getTemplateSpecializationKind()) {
+ case TSK_ExplicitSpecialization:
+ case TSK_ExplicitInstantiationDeclaration:
+ case TSK_ExplicitInstantiationDefinition:
+ return true;
+
+ case TSK_Undeclared:
+ case TSK_ImplicitInstantiation:
+ return false;
+ }
+ llvm_unreachable("bad template specialization kind");
+ }
+
/// \brief Set the template specialization kind.
void setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
assert(TSK != TSK_Undeclared &&
@@ -390,6 +419,10 @@ public:
return (TemplateSpecializationKind)(MemberAndTSK.getInt() + 1);
}
+ bool isExplicitSpecialization() const {
+ return getTemplateSpecializationKind() == TSK_ExplicitSpecialization;
+ }
+
/// \brief Set the template specialization kind.
void setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
assert(TSK != TSK_Undeclared &&
@@ -425,18 +458,19 @@ public:
/// };
/// \endcode
class DependentFunctionTemplateSpecializationInfo {
+ struct CA {
+ /// The number of potential template candidates.
+ unsigned NumTemplates;
+
+ /// The number of template arguments.
+ unsigned NumArgs;
+ };
+
union {
// Force sizeof to be a multiple of sizeof(void*) so that the
// trailing data is aligned.
void *Aligner;
-
- struct {
- /// The number of potential template candidates.
- unsigned NumTemplates;
-
- /// The number of template arguments.
- unsigned NumArgs;
- } d;
+ struct CA d;
};
/// The locations of the left and right angle brackets.
@@ -552,7 +586,7 @@ protected:
};
template <typename EntryType>
- SpecIterator<EntryType>
+ static SpecIterator<EntryType>
makeSpecIterator(llvm::FoldingSetVector<EntryType> &Specs, bool isEnd) {
return SpecIterator<EntryType>(isEnd ? Specs.end() : Specs.begin());
}
@@ -576,14 +610,14 @@ protected:
/// \brief Pointer to the common data shared by all declarations of this
/// template.
- CommonBase *Common;
+ mutable CommonBase *Common;
/// \brief Retrieves the "common" pointer shared by all (re-)declarations of
/// the same template. Calling this routine may implicitly allocate memory
/// for the common pointer.
- CommonBase *getCommonPtr();
+ CommonBase *getCommonPtr() const;
- virtual CommonBase *newCommon(ASTContext &C) = 0;
+ virtual CommonBase *newCommon(ASTContext &C) const = 0;
// Construct a template decl with name, parameters, and templated element.
RedeclarableTemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
@@ -618,7 +652,7 @@ public:
/// template<> template<typename T>
/// struct X<int>::Inner { /* ... */ };
/// \endcode
- bool isMemberSpecialization() {
+ bool isMemberSpecialization() const {
return getCommonPtr()->InstantiatedFromMember.getInt();
}
@@ -665,7 +699,7 @@ public:
/// template<typename U>
/// void X<T>::f(T, U);
/// \endcode
- RedeclarableTemplateDecl *getInstantiatedFromMemberTemplate() {
+ RedeclarableTemplateDecl *getInstantiatedFromMemberTemplate() const {
return getCommonPtr()->InstantiatedFromMember.getPointer();
}
@@ -729,9 +763,9 @@ protected:
TemplateParameterList *Params, NamedDecl *Decl)
: RedeclarableTemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl) { }
- CommonBase *newCommon(ASTContext &C);
+ CommonBase *newCommon(ASTContext &C) const;
- Common *getCommonPtr() {
+ Common *getCommonPtr() const {
return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
}
@@ -740,7 +774,7 @@ protected:
/// \brief Retrieve the set of function template specializations of this
/// function template.
llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
- getSpecializations() {
+ getSpecializations() const {
return getCommonPtr()->Specializations;
}
@@ -798,11 +832,11 @@ public:
typedef SpecIterator<FunctionTemplateSpecializationInfo> spec_iterator;
- spec_iterator spec_begin() {
+ spec_iterator spec_begin() const {
return makeSpecIterator(getSpecializations(), false);
}
- spec_iterator spec_end() {
+ spec_iterator spec_end() const {
return makeSpecIterator(getSpecializations(), true);
}
@@ -1205,7 +1239,7 @@ public:
unsigned P,
IdentifierInfo *Id,
TemplateParameterList *Params,
- llvm::ArrayRef<TemplateParameterList*> Expansions);
+ ArrayRef<TemplateParameterList *> Expansions);
static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C,
unsigned ID);
@@ -1399,7 +1433,7 @@ public:
static ClassTemplateSpecializationDecl *
CreateDeserialized(ASTContext &C, unsigned ID);
- virtual void getNameForDiagnostic(std::string &S,
+ virtual void getNameForDiagnostic(raw_ostream &OS,
const PrintingPolicy &Policy,
bool Qualified) const;
@@ -1433,6 +1467,23 @@ public:
return getSpecializationKind() == TSK_ExplicitSpecialization;
}
+ /// \brief True if this declaration is an explicit specialization,
+ /// explicit instantiation declaration, or explicit instantiation
+ /// definition.
+ bool isExplicitInstantiationOrSpecialization() const {
+ switch (getTemplateSpecializationKind()) {
+ case TSK_ExplicitSpecialization:
+ case TSK_ExplicitInstantiationDeclaration:
+ case TSK_ExplicitInstantiationDefinition:
+ return true;
+
+ case TSK_Undeclared:
+ case TSK_ImplicitInstantiation:
+ return false;
+ }
+ llvm_unreachable("bad template specialization kind");
+ }
+
void setSpecializationKind(TemplateSpecializationKind TSK) {
SpecializationKind = TSK;
}
@@ -1464,8 +1515,7 @@ public:
= SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
return PartialSpec->PartialSpecialization;
- return const_cast<ClassTemplateDecl*>(
- SpecializedTemplate.get<ClassTemplateDecl*>());
+ return SpecializedTemplate.get<ClassTemplateDecl*>();
}
/// \brief Retrieve the class template or class template partial
@@ -1477,8 +1527,7 @@ public:
= SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
return PartialSpec->PartialSpecialization;
- return const_cast<ClassTemplateDecl*>(
- SpecializedTemplate.get<ClassTemplateDecl*>());
+ return SpecializedTemplate.get<ClassTemplateDecl*>();
}
/// \brief Retrieve the set of template arguments that should be used
@@ -1780,10 +1829,11 @@ protected:
};
/// \brief Load any lazily-loaded specializations from the external source.
- void LoadLazySpecializations();
+ void LoadLazySpecializations() const;
/// \brief Retrieve the set of specializations of this class template.
- llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &getSpecializations();
+ llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
+ getSpecializations() const;
/// \brief Retrieve the set of partial specializations of this class
/// template.
@@ -1798,9 +1848,9 @@ protected:
: RedeclarableTemplateDecl(ClassTemplate, 0, SourceLocation(),
DeclarationName(), 0, 0) { }
- CommonBase *newCommon(ASTContext &C);
+ CommonBase *newCommon(ASTContext &C) const;
- Common *getCommonPtr() {
+ Common *getCommonPtr() const {
return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
}
@@ -1925,11 +1975,11 @@ public:
typedef SpecIterator<ClassTemplateSpecializationDecl> spec_iterator;
- spec_iterator spec_begin() {
+ spec_iterator spec_begin() const {
return makeSpecIterator(getSpecializations(), false);
}
- spec_iterator spec_end() {
+ spec_iterator spec_end() const {
return makeSpecIterator(getSpecializations(), true);
}
@@ -2063,7 +2113,7 @@ protected:
TemplateParameterList *Params, NamedDecl *Decl)
: RedeclarableTemplateDecl(TypeAliasTemplate, DC, L, Name, Params, Decl) { }
- CommonBase *newCommon(ASTContext &C);
+ CommonBase *newCommon(ASTContext &C) const;
Common *getCommonPtr() {
return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
diff --git a/include/clang/AST/DeclVisitor.h b/include/clang/AST/DeclVisitor.h
index 62654b8115fc..4eaae35778b9 100644
--- a/include/clang/AST/DeclVisitor.h
+++ b/include/clang/AST/DeclVisitor.h
@@ -14,21 +14,28 @@
#define LLVM_CLANG_AST_DECLVISITOR_H
#include "clang/AST/Decl.h"
-#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclFriend.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclOpenMP.h"
#include "clang/AST/DeclTemplate.h"
namespace clang {
+namespace declvisitor {
-#define DISPATCH(NAME, CLASS) \
- return static_cast<ImplClass*>(this)-> Visit##NAME(static_cast<CLASS*>(D))
+template <typename T> struct make_ptr { typedef T *type; };
+template <typename T> struct make_const_ptr { typedef const T *type; };
/// \brief A simple visitor class that helps create declaration visitors.
-template<typename ImplClass, typename RetTy=void>
-class DeclVisitor {
+template<template <typename> class Ptr, typename ImplClass, typename RetTy=void>
+class Base {
public:
- RetTy Visit(Decl *D) {
+
+#define PTR(CLASS) typename Ptr<CLASS>::type
+#define DISPATCH(NAME, CLASS) \
+ return static_cast<ImplClass*>(this)->Visit##NAME(static_cast<PTR(CLASS)>(D))
+
+ RetTy Visit(PTR(Decl) D) {
switch (D->getKind()) {
#define DECL(DERIVED, BASE) \
case Decl::DERIVED: DISPATCH(DERIVED##Decl, DERIVED##Decl);
@@ -41,13 +48,31 @@ public:
// If the implementation chooses not to implement a certain visit
// method, fall back to the parent.
#define DECL(DERIVED, BASE) \
- RetTy Visit##DERIVED##Decl(DERIVED##Decl *D) { DISPATCH(BASE, BASE); }
+ RetTy Visit##DERIVED##Decl(PTR(DERIVED##Decl) D) { DISPATCH(BASE, BASE); }
#include "clang/AST/DeclNodes.inc"
- RetTy VisitDecl(Decl *D) { return RetTy(); }
-};
+ RetTy VisitDecl(PTR(Decl) D) { return RetTy(); }
+#undef PTR
#undef DISPATCH
+};
+
+} // end namespace declvisitor
+
+/// \brief A simple visitor class that helps create declaration visitors.
+///
+/// This class does not preserve constness of Decl pointers (see also
+/// ConstDeclVisitor).
+template<typename ImplClass, typename RetTy=void>
+class DeclVisitor
+ : public declvisitor::Base<declvisitor::make_ptr, ImplClass, RetTy> {};
+
+/// \brief A simple visitor class that helps create declaration visitors.
+///
+/// This class preserves constness of Decl pointers (see also DeclVisitor).
+template<typename ImplClass, typename RetTy=void>
+class ConstDeclVisitor
+ : public declvisitor::Base<declvisitor::make_const_ptr, ImplClass, RetTy> {};
} // end namespace clang
diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h
index d991c73612c2..f28882b3bf94 100644
--- a/include/clang/AST/DeclarationName.h
+++ b/include/clang/AST/DeclarationName.h
@@ -14,8 +14,6 @@
#define LLVM_CLANG_AST_DECLARATIONNAME_H
#include "clang/Basic/IdentifierTable.h"
-#include "clang/AST/Type.h"
-#include "clang/AST/CanonicalType.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "llvm/Support/Compiler.h"
@@ -24,14 +22,20 @@ namespace llvm {
}
namespace clang {
- class CXXSpecialName;
- class CXXOperatorIdName;
+ class ASTContext;
class CXXLiteralOperatorIdName;
+ class CXXOperatorIdName;
+ class CXXSpecialName;
class DeclarationNameExtra;
class IdentifierInfo;
class MultiKeywordSelector;
- class UsingDirectiveDecl;
+ class QualType;
+ class Type;
class TypeSourceInfo;
+ class UsingDirectiveDecl;
+
+ template <typename> class CanQual;
+ typedef CanQual<Type> CanQualType;
/// DeclarationName - The name of a declaration. In the common case,
/// this just stores an IdentifierInfo pointer to a normal
@@ -349,23 +353,15 @@ public:
/// getCXXConstructorName - Returns the name of a C++ constructor
/// for the given Type.
- DeclarationName getCXXConstructorName(CanQualType Ty) {
- return getCXXSpecialName(DeclarationName::CXXConstructorName,
- Ty.getUnqualifiedType());
- }
+ DeclarationName getCXXConstructorName(CanQualType Ty);
/// getCXXDestructorName - Returns the name of a C++ destructor
/// for the given Type.
- DeclarationName getCXXDestructorName(CanQualType Ty) {
- return getCXXSpecialName(DeclarationName::CXXDestructorName,
- Ty.getUnqualifiedType());
- }
+ DeclarationName getCXXDestructorName(CanQualType Ty);
/// getCXXConversionFunctionName - Returns the name of a C++
/// conversion function for the given Type.
- DeclarationName getCXXConversionFunctionName(CanQualType Ty) {
- return getCXXSpecialName(DeclarationName::CXXConversionFunctionName, Ty);
- }
+ DeclarationName getCXXConversionFunctionName(CanQualType Ty);
/// getCXXSpecialName - Returns a declaration name for special kind
/// of C++ name, e.g., for a constructor, destructor, or conversion
@@ -386,32 +382,35 @@ public:
/// for a declaration name. Needs a DeclarationName in order
/// to be interpreted correctly.
struct DeclarationNameLoc {
+ // The source location for identifier stored elsewhere.
+ // struct {} Identifier;
+
+ // Type info for constructors, destructors and conversion functions.
+ // Locations (if any) for the tilde (destructor) or operator keyword
+ // (conversion) are stored elsewhere.
+ struct NT {
+ TypeSourceInfo* TInfo;
+ };
+
+ // The location (if any) of the operator keyword is stored elsewhere.
+ struct CXXOpName {
+ unsigned BeginOpNameLoc;
+ unsigned EndOpNameLoc;
+ };
+
+ // The location (if any) of the operator keyword is stored elsewhere.
+ struct CXXLitOpName {
+ unsigned OpNameLoc;
+ };
+
+ // struct {} CXXUsingDirective;
+ // struct {} ObjCZeroArgSelector;
+ // struct {} ObjCOneArgSelector;
+ // struct {} ObjCMultiArgSelector;
union {
- // The source location for identifier stored elsewhere.
- // struct {} Identifier;
-
- // Type info for constructors, destructors and conversion functions.
- // Locations (if any) for the tilde (destructor) or operator keyword
- // (conversion) are stored elsewhere.
- struct {
- TypeSourceInfo* TInfo;
- } NamedType;
-
- // The location (if any) of the operator keyword is stored elsewhere.
- struct {
- unsigned BeginOpNameLoc;
- unsigned EndOpNameLoc;
- } CXXOperatorName;
-
- // The location (if any) of the operator keyword is stored elsewhere.
- struct {
- unsigned OpNameLoc;
- } CXXLiteralOperatorName;
-
- // struct {} CXXUsingDirective;
- // struct {} ObjCZeroArgSelector;
- // struct {} ObjCOneArgSelector;
- // struct {} ObjCMultiArgSelector;
+ struct NT NamedType;
+ struct CXXOpName CXXOperatorName;
+ struct CXXLitOpName CXXLiteralOperatorName;
};
DeclarationNameLoc(DeclarationName Name);
@@ -525,9 +524,7 @@ public:
SourceLocation getEndLoc() const;
/// getSourceRange - The range of the declaration name.
SourceRange getSourceRange() const LLVM_READONLY {
- SourceLocation BeginLoc = getBeginLoc();
- SourceLocation EndLoc = getEndLoc();
- return SourceRange(BeginLoc, EndLoc.isValid() ? EndLoc : BeginLoc);
+ return SourceRange(getLocStart(), getLocEnd());
}
SourceLocation getLocStart() const LLVM_READONLY {
return getBeginLoc();
diff --git a/include/clang/AST/DependentDiagnostic.h b/include/clang/AST/DependentDiagnostic.h
index 948dcb461a5a..004b45da0f34 100644
--- a/include/clang/AST/DependentDiagnostic.h
+++ b/include/clang/AST/DependentDiagnostic.h
@@ -18,11 +18,11 @@
#ifndef LLVM_CLANG_AST_DEPENDENT_DIAGNOSTIC_H
#define LLVM_CLANG_AST_DEPENDENT_DIAGNOSTIC_H
-#include "clang/Basic/PartialDiagnostic.h"
-#include "clang/Basic/SourceLocation.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclContextInternals.h"
#include "clang/AST/Type.h"
+#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/SourceLocation.h"
namespace clang {
@@ -108,16 +108,14 @@ private:
PartialDiagnostic Diag;
- union {
- struct {
- unsigned Loc;
- unsigned Access : 2;
- unsigned IsMember : 1;
- NamedDecl *TargetDecl;
- CXXRecordDecl *NamingClass;
- void *BaseObjectType;
- } AccessData;
- };
+ struct {
+ unsigned Loc;
+ unsigned Access : 2;
+ unsigned IsMember : 1;
+ NamedDecl *TargetDecl;
+ CXXRecordDecl *NamingClass;
+ void *BaseObjectType;
+ } AccessData;
};
///
diff --git a/include/clang/AST/EvaluatedExprVisitor.h b/include/clang/AST/EvaluatedExprVisitor.h
index d5e9c8c678fe..eb186c217e35 100644
--- a/include/clang/AST/EvaluatedExprVisitor.h
+++ b/include/clang/AST/EvaluatedExprVisitor.h
@@ -15,10 +15,10 @@
#ifndef LLVM_CLANG_AST_EVALUATEDEXPRVISITOR_H
#define LLVM_CLANG_AST_EVALUATEDEXPRVISITOR_H
-#include "clang/AST/StmtVisitor.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
+#include "clang/AST/StmtVisitor.h"
namespace clang {
@@ -49,6 +49,9 @@ public:
}
void VisitChooseExpr(ChooseExpr *E) {
+ // Don't visit either child expression if the condition is dependent.
+ if (E->getCond()->isValueDependent())
+ return;
// Only the selected subexpression matters; the other one is not evaluated.
return this->Visit(E->getChosenSubExpr(Context));
}
@@ -58,17 +61,17 @@ public:
// expressions.
return this->Visit(E->getInit());
}
-
+
void VisitCXXTypeidExpr(CXXTypeidExpr *E) {
- // typeid(expression) is potentially evaluated when the argument is
- // a glvalue of polymorphic type. (C++ 5.2.8p2-3)
- if (!E->isTypeOperand() && E->Classify(Context).isGLValue())
- if (const RecordType *Record
- = E->getExprOperand()->getType()->template getAs<RecordType>())
- if (cast<CXXRecordDecl>(Record->getDecl())->isPolymorphic())
- return this->Visit(E->getExprOperand());
+ if (E->isPotentiallyEvaluated())
+ return this->Visit(E->getExprOperand());
}
-
+
+ void VisitCallExpr(CallExpr *CE) {
+ if (!CE->isUnevaluatedBuiltinCall(Context))
+ return static_cast<ImplClass*>(this)->VisitExpr(CE);
+ }
+
/// \brief The basis case walks all of the children of the statement or
/// expression, assuming they are all potentially evaluated.
void VisitStmt(Stmt *S) {
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index dc83654bd948..36d70d8b0b71 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -15,38 +15,38 @@
#define LLVM_CLANG_AST_EXPR_H
#include "clang/AST/APValue.h"
+#include "clang/AST/ASTVector.h"
#include "clang/AST/Decl.h"
-#include "clang/AST/Stmt.h"
-#include "clang/AST/Type.h"
#include "clang/AST/DeclAccessPair.h"
#include "clang/AST/OperationKinds.h"
-#include "clang/AST/ASTVector.h"
+#include "clang/AST/Stmt.h"
#include "clang/AST/TemplateBase.h"
-#include "clang/Basic/TargetInfo.h"
+#include "clang/AST/Type.h"
+#include "clang/Basic/CharInfo.h"
#include "clang/Basic/TypeTraits.h"
-#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
-#include <cctype>
namespace clang {
- class ASTContext;
class APValue;
- class CastExpr;
- class Decl;
- class IdentifierInfo;
- class ParmVarDecl;
- class NamedDecl;
- class ValueDecl;
+ class ASTContext;
class BlockDecl;
class CXXBaseSpecifier;
+ class CXXMemberCallExpr;
class CXXOperatorCallExpr;
+ class CastExpr;
+ class Decl;
+ class IdentifierInfo;
class MaterializeTemporaryExpr;
- class CXXMemberCallExpr;
+ class NamedDecl;
class ObjCPropertyRefExpr;
class OpaqueValueExpr;
+ class ParmVarDecl;
+ class TargetInfo;
+ class ValueDecl;
/// \brief A simple array of base specifiers.
typedef SmallVector<CXXBaseSpecifier*, 4> CXXCastPath;
@@ -60,18 +60,21 @@ struct SubobjectAdjustment {
MemberPointerAdjustment
} Kind;
- union {
- struct {
- const CastExpr *BasePath;
- const CXXRecordDecl *DerivedClass;
- } DerivedToBase;
- FieldDecl *Field;
+ struct DTB {
+ const CastExpr *BasePath;
+ const CXXRecordDecl *DerivedClass;
+ };
- struct {
- const MemberPointerType *MPT;
- Expr *RHS;
- } Ptr;
+ struct P {
+ const MemberPointerType *MPT;
+ Expr *RHS;
+ };
+
+ union {
+ struct DTB DerivedToBase;
+ FieldDecl *Field;
+ struct P Ptr;
};
SubobjectAdjustment(const CastExpr *BasePath,
@@ -196,7 +199,7 @@ public:
}
/// \brief Whether this expression contains an unexpanded parameter
- /// pack (for C++0x variadic templates).
+ /// pack (for C++11 variadic templates).
///
/// Given the following function template:
///
@@ -238,7 +241,7 @@ public:
/// result of an r-value expression is a value detached from any
/// specific storage.
///
- /// C++0x divides the concept of "r-value" into pure r-values
+ /// C++11 divides the concept of "r-value" into pure r-values
/// ("pr-values") and so-called expiring values ("x-values"), which
/// identify specific objects that can be safely cannibalized for
/// their resources. This is an unfortunate abuse of terminology on
@@ -294,7 +297,7 @@ public:
isModifiableLvalueResult isModifiableLvalue(ASTContext &Ctx,
SourceLocation *Loc = 0) const;
- /// \brief The return type of classify(). Represents the C++0x expression
+ /// \brief The return type of classify(). Represents the C++11 expression
/// taxonomy.
class Classification {
public:
@@ -357,10 +360,10 @@ public:
}
};
- /// \brief Classify - Classify this expression according to the C++0x
+ /// \brief Classify - Classify this expression according to the C++11
/// expression taxonomy.
///
- /// C++0x defines ([basic.lval]) a new taxonomy of expressions to replace the
+ /// C++11 defines ([basic.lval]) a new taxonomy of expressions to replace the
/// old lvalue vs rvalue. This function determines the type of expression this
/// is. There are three expression types:
/// - lvalues are classical lvalues as in C++03.
@@ -374,7 +377,7 @@ public:
}
/// \brief ClassifyModifiable - Classify this expression according to the
- /// C++0x expression taxonomy, and see if it is valid on the left side
+ /// C++11 expression taxonomy, and see if it is valid on the left side
/// of an assignment.
///
/// This function extends classify in that it also tests whether the
@@ -490,7 +493,7 @@ public:
/// constexpr. Return false if the function can never produce a constant
/// expression, along with diagnostics describing why not.
static bool isPotentialConstantExpr(const FunctionDecl *FD,
- llvm::SmallVectorImpl<
+ SmallVectorImpl<
PartialDiagnosticAt> &Diags);
/// isConstantInitializer - Returns true if this expression can be emitted to
@@ -510,7 +513,7 @@ public:
/// foldable. If the expression is foldable, but not a constant expression,
/// the notes will describes why it isn't a constant expression. If the
/// expression *is* a constant expression, no notes will be produced.
- llvm::SmallVectorImpl<PartialDiagnosticAt> *Diag;
+ SmallVectorImpl<PartialDiagnosticAt> *Diag;
EvalStatus() : HasSideEffects(false), Diag(0) {}
@@ -568,7 +571,11 @@ public:
/// EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded
/// integer. This must be called on an expression that constant folds to an
/// integer.
- llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const;
+ llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx,
+ SmallVectorImpl<PartialDiagnosticAt> *Diag=0) const;
+
+ void EvaluateForOverflow(const ASTContext &Ctx,
+ SmallVectorImpl<PartialDiagnosticAt> *Diag) const;
/// EvaluateAsLValue - Evaluate an expression to see if we can fold it to an
/// lvalue with link time known address, with no side-effects.
@@ -580,7 +587,7 @@ public:
/// notes will be produced if the expression is not a constant expression.
bool EvaluateAsInitializer(APValue &Result, const ASTContext &Ctx,
const VarDecl *VD,
- llvm::SmallVectorImpl<PartialDiagnosticAt> &Notes) const;
+ SmallVectorImpl<PartialDiagnosticAt> &Notes) const;
/// \brief Enumeration used to describe the kind of Null pointer constant
/// returned from \c isNullPointerConstant().
@@ -598,8 +605,8 @@ public:
/// \brief Expression is a Null pointer constant built from a literal zero.
NPCK_ZeroLiteral,
- /// \brief Expression is a C++0X nullptr.
- NPCK_CXX0X_nullptr,
+ /// \brief Expression is a C++11 nullptr.
+ NPCK_CXX11_nullptr,
/// \brief Expression is a GNU-style __null constant.
NPCK_GNUNull
@@ -728,7 +735,7 @@ public:
return const_cast<Expr*>(this)->IgnoreParenNoopCasts(Ctx);
}
- static bool hasAnyTypeDependentArguments(llvm::ArrayRef<Expr *> Exprs);
+ static bool hasAnyTypeDependentArguments(ArrayRef<Expr *> Exprs);
/// \brief For an expression of class type or pointer to class type,
/// return the most derived class decl the expression is known to refer to.
@@ -796,9 +803,11 @@ public:
/// \brief Retrieve the location of this expression.
SourceLocation getLocation() const { return Loc; }
- SourceRange getSourceRange() const LLVM_READONLY {
- if (SourceExpr) return SourceExpr->getSourceRange();
- return Loc;
+ SourceLocation getLocStart() const LLVM_READONLY {
+ return SourceExpr ? SourceExpr->getLocStart() : Loc;
+ }
+ SourceLocation getLocEnd() const LLVM_READONLY {
+ return SourceExpr ? SourceExpr->getLocEnd() : Loc;
}
SourceLocation getExprLoc() const LLVM_READONLY {
if (SourceExpr) return SourceExpr->getExprLoc();
@@ -954,7 +963,6 @@ public:
SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }
- SourceRange getSourceRange() const LLVM_READONLY;
SourceLocation getLocStart() const LLVM_READONLY;
SourceLocation getLocEnd() const LLVM_READONLY;
@@ -1160,7 +1168,8 @@ public:
static std::string ComputeName(IdentType IT, const Decl *CurrentDecl);
- SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(Loc); }
+ SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == PredefinedExprClass;
@@ -1211,8 +1220,8 @@ public:
class APFloatStorage : private APNumericStorage {
public:
- llvm::APFloat getValue(bool IsIEEE) const {
- return llvm::APFloat(getIntValue(), IsIEEE);
+ llvm::APFloat getValue(const llvm::fltSemantics &Semantics) const {
+ return llvm::APFloat(Semantics, getIntValue());
}
void setValue(ASTContext &C, const llvm::APFloat &Val) {
setIntValue(C, Val.bitcastToAPInt());
@@ -1241,7 +1250,8 @@ public:
/// \brief Returns a new empty integer literal.
static IntegerLiteral *Create(ASTContext &C, EmptyShell Empty);
- SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(Loc); }
+ SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
/// \brief Retrieve the location of the literal.
SourceLocation getLocation() const { return Loc; }
@@ -1286,7 +1296,8 @@ public:
return static_cast<CharacterKind>(CharacterLiteralBits.Kind);
}
- SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(Loc); }
+ SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
unsigned getValue() const { return Value; }
@@ -1317,12 +1328,31 @@ public:
static FloatingLiteral *Create(ASTContext &C, EmptyShell Empty);
llvm::APFloat getValue() const {
- return APFloatStorage::getValue(FloatingLiteralBits.IsIEEE);
+ return APFloatStorage::getValue(getSemantics());
}
void setValue(ASTContext &C, const llvm::APFloat &Val) {
+ assert(&getSemantics() == &Val.getSemantics() && "Inconsistent semantics");
APFloatStorage::setValue(C, Val);
}
+ /// Get a raw enumeration value representing the floating-point semantics of
+ /// this literal (32-bit IEEE, x87, ...), suitable for serialisation.
+ APFloatSemantics getRawSemantics() const {
+ return static_cast<APFloatSemantics>(FloatingLiteralBits.Semantics);
+ }
+
+ /// Set the raw enumeration value representing the floating-point semantics of
+ /// this literal (32-bit IEEE, x87, ...), suitable for serialisation.
+ void setRawSemantics(APFloatSemantics Sem) {
+ FloatingLiteralBits.Semantics = Sem;
+ }
+
+ /// Return the APFloat semantics this literal uses.
+ const llvm::fltSemantics &getSemantics() const;
+
+ /// Set the APFloat semantics this literal uses.
+ void setSemantics(const llvm::fltSemantics &Sem);
+
bool isExact() const { return FloatingLiteralBits.IsExact; }
void setExact(bool E) { FloatingLiteralBits.IsExact = E; }
@@ -1334,7 +1364,8 @@ public:
SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }
- SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(Loc); }
+ SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == FloatingLiteralClass;
@@ -1365,7 +1396,9 @@ public:
Expr *getSubExpr() { return cast<Expr>(Val); }
void setSubExpr(Expr *E) { Val = E; }
- SourceRange getSourceRange() const LLVM_READONLY { return Val->getSourceRange(); }
+ SourceLocation getLocStart() const LLVM_READONLY { return Val->getLocStart(); }
+ SourceLocation getLocEnd() const LLVM_READONLY { return Val->getLocEnd(); }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == ImaginaryLiteralClass;
}
@@ -1458,7 +1491,7 @@ public:
getByteLength());
}
- void outputString(raw_ostream &OS);
+ void outputString(raw_ostream &OS) const;
uint32_t getCodeUnit(size_t i) const {
assert(i < Length && "out of bounds access");
@@ -1491,7 +1524,7 @@ public:
bool containsNonAsciiOrNull() const {
StringRef Str = getString();
for (unsigned i = 0, e = Str.size(); i != e; ++i)
- if (!isascii(Str[i]) || !Str[i])
+ if (!isASCII(Str[i]) || !Str[i])
return true;
return false;
}
@@ -1524,9 +1557,11 @@ public:
tokloc_iterator tokloc_begin() const { return TokLocs; }
tokloc_iterator tokloc_end() const { return TokLocs+NumConcatenated; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(TokLocs[0], TokLocs[NumConcatenated-1]);
+ SourceLocation getLocStart() const LLVM_READONLY { return TokLocs[0]; }
+ SourceLocation getLocEnd() const LLVM_READONLY {
+ return TokLocs[NumConcatenated - 1];
}
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == StringLiteralClass;
}
@@ -1557,7 +1592,8 @@ public:
Expr *getSubExpr() { return cast<Expr>(Val); }
void setSubExpr(Expr *E) { Val = E; }
- SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(L, R); }
+ SourceLocation getLocStart() const LLVM_READONLY { return L; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return R; }
/// \brief Get the location of the left parentheses '('.
SourceLocation getLParen() const { return L; }
@@ -1669,11 +1705,11 @@ public:
/// the given unary opcode.
static OverloadedOperatorKind getOverloadedOperator(Opcode Opc);
- SourceRange getSourceRange() const LLVM_READONLY {
- if (isPostfix())
- return SourceRange(Val->getLocStart(), Loc);
- else
- return SourceRange(Loc, Val->getLocEnd());
+ SourceLocation getLocStart() const LLVM_READONLY {
+ return isPostfix() ? Val->getLocStart() : Loc;
+ }
+ SourceLocation getLocEnd() const LLVM_READONLY {
+ return isPostfix() ? Loc : Val->getLocEnd();
}
SourceLocation getExprLoc() const LLVM_READONLY { return Loc; }
@@ -1791,6 +1827,8 @@ public:
/// contains the location of the period (if there is one) and the
/// identifier.
SourceRange getSourceRange() const LLVM_READONLY { return Range; }
+ SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
+ SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
};
private:
@@ -1870,9 +1908,8 @@ public:
return NumExprs;
}
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(OperatorLoc, RParenLoc);
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return OperatorLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == OffsetOfExprClass;
@@ -1974,9 +2011,8 @@ public:
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(OpLoc, RParenLoc);
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return OpLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == UnaryExprOrTypeTraitExprClass;
@@ -2048,14 +2084,17 @@ public:
return cast<Expr>(getRHS()->getType()->isIntegerType() ? getRHS():getLHS());
}
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(getLHS()->getLocStart(), RBracketLoc);
+ SourceLocation getLocStart() const LLVM_READONLY {
+ return getLHS()->getLocStart();
}
+ SourceLocation getLocEnd() const LLVM_READONLY { return RBracketLoc; }
SourceLocation getRBracketLoc() const { return RBracketLoc; }
void setRBracketLoc(SourceLocation L) { RBracketLoc = L; }
- SourceLocation getExprLoc() const LLVM_READONLY { return getBase()->getExprLoc(); }
+ SourceLocation getExprLoc() const LLVM_READONLY {
+ return getBase()->getExprLoc();
+ }
static bool classof(const Stmt *T) {
return T->getStmtClass() == ArraySubscriptExprClass;
@@ -2171,6 +2210,15 @@ public:
return SubExprs+PREARGS_START+getNumPreArgs()+getNumArgs();
}
+ /// This method provides fast access to all the subexpressions of
+ /// a CallExpr without going through the slower virtual child_iterator
+ /// interface. This provides efficient reverse iteration of the
+ /// subexpressions. This is currently used for CFG construction.
+ ArrayRef<Stmt*> getRawSubExprs() {
+ return ArrayRef<Stmt*>(SubExprs,
+ getNumPreArgs() + PREARGS_START + getNumArgs());
+ }
+
/// getNumCommas - Return the number of commas that must have been present in
/// this function call.
unsigned getNumCommas() const { return NumArgs ? NumArgs - 1 : 0; }
@@ -2179,6 +2227,10 @@ public:
/// not, return 0.
unsigned isBuiltinCall() const;
+ /// \brief Returns \c true if this is a call to a builtin which does not
+ /// evaluate side-effects within its arguments.
+ bool isUnevaluatedBuiltinCall(ASTContext &Ctx) const;
+
/// getCallReturnType - Get the return type of the call expr. This is not
/// always the type of the expr itself, if the return type is a reference
/// type.
@@ -2187,7 +2239,6 @@ public:
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceRange getSourceRange() const LLVM_READONLY;
SourceLocation getLocStart() const LLVM_READONLY;
SourceLocation getLocEnd() const LLVM_READONLY;
@@ -2455,7 +2506,6 @@ public:
SourceLocation getMemberLoc() const { return MemberLoc; }
void setMemberLoc(SourceLocation L) { MemberLoc = L; }
- SourceRange getSourceRange() const LLVM_READONLY;
SourceLocation getLocStart() const LLVM_READONLY;
SourceLocation getLocEnd() const LLVM_READONLY;
@@ -2534,13 +2584,19 @@ public:
TInfoAndScope.setPointer(tinfo);
}
- SourceRange getSourceRange() const LLVM_READONLY {
+ SourceLocation getLocStart() const LLVM_READONLY {
// FIXME: Init should never be null.
if (!Init)
- return SourceRange();
+ return SourceLocation();
if (LParenLoc.isInvalid())
- return Init->getSourceRange();
- return SourceRange(LParenLoc, Init->getLocEnd());
+ return Init->getLocStart();
+ return LParenLoc;
+ }
+ SourceLocation getLocEnd() const LLVM_READONLY {
+ // FIXME: Init should never be null.
+ if (!Init)
+ return SourceLocation();
+ return Init->getLocEnd();
}
static bool classof(const Stmt *T) {
@@ -2686,9 +2742,6 @@ public:
static ImplicitCastExpr *CreateEmpty(ASTContext &Context, unsigned PathSize);
- SourceRange getSourceRange() const LLVM_READONLY {
- return getSubExpr()->getSourceRange();
- }
SourceLocation getLocStart() const LLVM_READONLY {
return getSubExpr()->getLocStart();
}
@@ -2787,9 +2840,11 @@ public:
SourceLocation getRParenLoc() const { return RPLoc; }
void setRParenLoc(SourceLocation L) { RPLoc = L; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(LPLoc, getSubExpr()->getSourceRange().getEnd());
+ SourceLocation getLocStart() const LLVM_READONLY { return LPLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY {
+ return getSubExpr()->getLocEnd();
}
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == CStyleCastExprClass;
}
@@ -2845,7 +2900,7 @@ public:
SubExprs[LHS] = lhs;
SubExprs[RHS] = rhs;
assert(!isCompoundAssignmentOp() &&
- "Use ArithAssignBinaryOperator for compound assignments");
+ "Use CompoundAssignOperator for compound assignments");
}
/// \brief Construct an empty binary operator.
@@ -2864,8 +2919,11 @@ public:
Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); }
void setRHS(Expr *E) { SubExprs[RHS] = E; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(getLHS()->getLocStart(), getRHS()->getLocEnd());
+ SourceLocation getLocStart() const LLVM_READONLY {
+ return getLHS()->getLocStart();
+ }
+ SourceLocation getLocEnd() const LLVM_READONLY {
+ return getRHS()->getLocEnd();
}
/// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
@@ -2902,6 +2960,33 @@ public:
static bool isComparisonOp(Opcode Opc) { return Opc >= BO_LT && Opc<=BO_NE; }
bool isComparisonOp() const { return isComparisonOp(getOpcode()); }
+ static Opcode negateComparisonOp(Opcode Opc) {
+ switch (Opc) {
+ default:
+ llvm_unreachable("Not a comparsion operator.");
+ case BO_LT: return BO_GE;
+ case BO_GT: return BO_LE;
+ case BO_LE: return BO_GT;
+ case BO_GE: return BO_LT;
+ case BO_EQ: return BO_NE;
+ case BO_NE: return BO_EQ;
+ }
+ }
+
+ static Opcode reverseComparisonOp(Opcode Opc) {
+ switch (Opc) {
+ default:
+ llvm_unreachable("Not a comparsion operator.");
+ case BO_LT: return BO_GT;
+ case BO_GT: return BO_LT;
+ case BO_LE: return BO_GE;
+ case BO_GE: return BO_LE;
+ case BO_EQ:
+ case BO_NE:
+ return Opc;
+ }
+ }
+
static bool isLogicalOp(Opcode Opc) { return Opc == BO_LAnd || Opc==BO_LOr; }
bool isLogicalOp() const { return isLogicalOp(getOpcode()); }
@@ -3101,9 +3186,13 @@ public:
Expr *getLHS() const { return cast<Expr>(SubExprs[LHS]); }
Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(getCond()->getLocStart(), getRHS()->getLocEnd());
+ SourceLocation getLocStart() const LLVM_READONLY {
+ return getCond()->getLocStart();
+ }
+ SourceLocation getLocEnd() const LLVM_READONLY {
+ return getRHS()->getLocEnd();
}
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == ConditionalOperatorClass;
}
@@ -3182,9 +3271,13 @@ public:
return cast<Expr>(SubExprs[RHS]);
}
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(getCommon()->getLocStart(), getFalseExpr()->getLocEnd());
+ SourceLocation getLocStart() const LLVM_READONLY {
+ return getCommon()->getLocStart();
}
+ SourceLocation getLocEnd() const LLVM_READONLY {
+ return getFalseExpr()->getLocEnd();
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == BinaryConditionalOperatorClass;
}
@@ -3233,9 +3326,8 @@ public:
SourceLocation getLabelLoc() const { return LabelLoc; }
void setLabelLoc(SourceLocation L) { LabelLoc = L; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(AmpAmpLoc, LabelLoc);
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return AmpAmpLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return LabelLoc; }
LabelDecl *getLabel() const { return Label; }
void setLabel(LabelDecl *L) { Label = L; }
@@ -3274,9 +3366,8 @@ public:
const CompoundStmt *getSubStmt() const { return cast<CompoundStmt>(SubStmt); }
void setSubStmt(CompoundStmt *S) { SubStmt = S; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(LParenLoc, RParenLoc);
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return LParenLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
SourceLocation getLParenLoc() const { return LParenLoc; }
void setLParenLoc(SourceLocation L) { LParenLoc = L; }
@@ -3322,9 +3413,9 @@ public:
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(BuiltinLoc, RParenLoc);
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == ShuffleVectorExprClass;
}
@@ -3416,9 +3507,9 @@ public:
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(BuiltinLoc, RParenLoc);
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == ChooseExprClass;
}
@@ -3452,9 +3543,9 @@ public:
SourceLocation getTokenLocation() const { return TokenLoc; }
void setTokenLocation(SourceLocation L) { TokenLoc = L; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(TokenLoc);
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return TokenLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return TokenLoc; }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == GNUNullExprClass;
}
@@ -3497,9 +3588,9 @@ public:
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(BuiltinLoc, RParenLoc);
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == VAArgExprClass;
}
@@ -3580,8 +3671,8 @@ public:
ArrayRef<Expr*> initExprs, SourceLocation rbraceloc);
/// \brief Build an empty initializer list.
- explicit InitListExpr(ASTContext &C, EmptyShell Empty)
- : Expr(InitListExprClass, Empty), InitExprs(C) { }
+ explicit InitListExpr(EmptyShell Empty)
+ : Expr(InitListExprClass, Empty) { }
unsigned getNumInits() const { return InitExprs.size(); }
@@ -3698,7 +3789,8 @@ public:
InitListExprBits.InitializesStdInitializerList = ISIL;
}
- SourceRange getSourceRange() const LLVM_READONLY;
+ SourceLocation getLocStart() const LLVM_READONLY;
+ SourceLocation getLocEnd() const LLVM_READONLY;
static bool classof(const Stmt *T) {
return T->getStmtClass() == InitListExprClass;
@@ -3923,17 +4015,17 @@ public:
return ArrayOrRange.Index;
}
- SourceLocation getStartLocation() const {
+ SourceLocation getLocStart() const LLVM_READONLY {
if (Kind == FieldDesignator)
return getDotLoc().isInvalid()? getFieldLoc() : getDotLoc();
else
return getLBracketLoc();
}
- SourceLocation getEndLocation() const {
+ SourceLocation getLocEnd() const LLVM_READONLY {
return Kind == FieldDesignator ? getFieldLoc() : getRBracketLoc();
}
SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(getStartLocation(), getEndLocation());
+ return SourceRange(getLocStart(), getLocEnd());
}
};
@@ -3984,9 +4076,9 @@ public:
void setDesignators(ASTContext &C, const Designator *Desigs,
unsigned NumDesigs);
- Expr *getArrayIndex(const Designator& D);
- Expr *getArrayRangeStart(const Designator& D);
- Expr *getArrayRangeEnd(const Designator& D);
+ Expr *getArrayIndex(const Designator &D) const;
+ Expr *getArrayRangeStart(const Designator &D) const;
+ Expr *getArrayRangeEnd(const Designator &D) const;
/// @brief Retrieve the location of the '=' that precedes the
/// initializer value itself, if present.
@@ -4034,7 +4126,8 @@ public:
SourceRange getDesignatorsSourceRange() const;
- SourceRange getSourceRange() const LLVM_READONLY;
+ SourceLocation getLocStart() const LLVM_READONLY;
+ SourceLocation getLocEnd() const LLVM_READONLY;
static bool classof(const Stmt *T) {
return T->getStmtClass() == DesignatedInitExprClass;
@@ -4069,9 +4162,8 @@ public:
return T->getStmtClass() == ImplicitValueInitExprClass;
}
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange();
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
+ SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }
// Iterators
child_range children() { return child_range(); }
@@ -4107,9 +4199,9 @@ public:
SourceLocation getLParenLoc() const { return LParenLoc; }
SourceLocation getRParenLoc() const { return RParenLoc; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(LParenLoc, RParenLoc);
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return LParenLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == ParenListExprClass;
}
@@ -4221,9 +4313,9 @@ public:
const Expr *getResultExpr() const { return getAssocExpr(getResultIndex()); }
Expr *getResultExpr() { return getAssocExpr(getResultIndex()); }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(GenericLoc, RParenLoc);
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return GenericLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == GenericSelectionExprClass;
}
@@ -4286,9 +4378,10 @@ public:
/// aggregate Constant of ConstantInt(s).
void getEncodedElementAccess(SmallVectorImpl<unsigned> &Elts) const;
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(getBase()->getLocStart(), AccessorLoc);
+ SourceLocation getLocStart() const LLVM_READONLY {
+ return getBase()->getLocStart();
}
+ SourceLocation getLocEnd() const LLVM_READONLY { return AccessorLoc; }
/// isArrow - Return true if the base expression is a pointer to vector,
/// return false if the base expression is a vector.
@@ -4328,9 +4421,8 @@ public:
const Stmt *getBody() const;
Stmt *getBody();
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(getCaretLocation(), getBody()->getLocEnd());
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return getCaretLocation(); }
+ SourceLocation getLocEnd() const LLVM_READONLY { return getBody()->getLocEnd(); }
/// getFunctionType - Return the underlying function type for this block.
const FunctionProtoType *getFunctionType() const;
@@ -4377,9 +4469,8 @@ public:
/// getRParenLoc - Return the location of final right parenthesis.
SourceLocation getRParenLoc() const { return RParenLoc; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(BuiltinLoc, RParenLoc);
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == AsTypeExprClass;
@@ -4508,8 +4599,12 @@ public:
SourceLocation getExprLoc() const LLVM_READONLY {
return getSyntacticForm()->getExprLoc();
}
- SourceRange getSourceRange() const LLVM_READONLY {
- return getSyntacticForm()->getSourceRange();
+
+ SourceLocation getLocStart() const LLVM_READONLY {
+ return getSyntacticForm()->getLocStart();
+ }
+ SourceLocation getLocEnd() const LLVM_READONLY {
+ return getSyntacticForm()->getLocEnd();
}
child_range children() {
@@ -4603,9 +4698,9 @@ public:
SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
SourceLocation getRParenLoc() const { return RParenLoc; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(BuiltinLoc, RParenLoc);
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == AtomicExprClass;
}
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 9c759db1f97a..04f6fb64cfd2 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -16,8 +16,8 @@
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
-#include "clang/AST/UnresolvedSet.h"
#include "clang/AST/TemplateBase.h"
+#include "clang/AST/UnresolvedSet.h"
#include "clang/Basic/ExpressionTraits.h"
#include "clang/Basic/Lambda.h"
#include "clang/Basic/TypeTraits.h"
@@ -30,6 +30,7 @@ class CXXDestructorDecl;
class CXXMethodDecl;
class CXXTemporary;
class TemplateArgumentListInfo;
+class UuidAttr;
//===--------------------------------------------------------------------===//
// C++ Expressions.
@@ -83,6 +84,8 @@ public:
/// bracket.
SourceLocation getOperatorLoc() const { return getRParenLoc(); }
+ SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
+ SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
SourceRange getSourceRange() const { return Range; }
static bool classof(const Stmt *T) {
@@ -176,14 +179,16 @@ class CXXNamedCastExpr : public ExplicitCastExpr {
private:
SourceLocation Loc; // the location of the casting op
SourceLocation RParenLoc; // the location of the right parenthesis
+ SourceRange AngleBrackets; // range for '<' '>'
protected:
CXXNamedCastExpr(StmtClass SC, QualType ty, ExprValueKind VK,
CastKind kind, Expr *op, unsigned PathSize,
TypeSourceInfo *writtenTy, SourceLocation l,
- SourceLocation RParenLoc)
+ SourceLocation RParenLoc,
+ SourceRange AngleBrackets)
: ExplicitCastExpr(SC, ty, VK, kind, op, PathSize, writtenTy), Loc(l),
- RParenLoc(RParenLoc) {}
+ RParenLoc(RParenLoc), AngleBrackets(AngleBrackets) {}
explicit CXXNamedCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize)
: ExplicitCastExpr(SC, Shell, PathSize) { }
@@ -200,9 +205,10 @@ public:
/// \brief Retrieve the location of the closing parenthesis.
SourceLocation getRParenLoc() const { return RParenLoc; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(Loc, RParenLoc);
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+ SourceRange getAngleBrackets() const LLVM_READONLY { return AngleBrackets; }
+
static bool classof(const Stmt *T) {
switch (T->getStmtClass()) {
case CXXStaticCastExprClass:
@@ -224,9 +230,10 @@ public:
class CXXStaticCastExpr : public CXXNamedCastExpr {
CXXStaticCastExpr(QualType ty, ExprValueKind vk, CastKind kind, Expr *op,
unsigned pathSize, TypeSourceInfo *writtenTy,
- SourceLocation l, SourceLocation RParenLoc)
+ SourceLocation l, SourceLocation RParenLoc,
+ SourceRange AngleBrackets)
: CXXNamedCastExpr(CXXStaticCastExprClass, ty, vk, kind, op, pathSize,
- writtenTy, l, RParenLoc) {}
+ writtenTy, l, RParenLoc, AngleBrackets) {}
explicit CXXStaticCastExpr(EmptyShell Empty, unsigned PathSize)
: CXXNamedCastExpr(CXXStaticCastExprClass, Empty, PathSize) { }
@@ -236,7 +243,8 @@ public:
ExprValueKind VK, CastKind K, Expr *Op,
const CXXCastPath *Path,
TypeSourceInfo *Written, SourceLocation L,
- SourceLocation RParenLoc);
+ SourceLocation RParenLoc,
+ SourceRange AngleBrackets);
static CXXStaticCastExpr *CreateEmpty(ASTContext &Context,
unsigned PathSize);
@@ -254,9 +262,10 @@ public:
class CXXDynamicCastExpr : public CXXNamedCastExpr {
CXXDynamicCastExpr(QualType ty, ExprValueKind VK, CastKind kind,
Expr *op, unsigned pathSize, TypeSourceInfo *writtenTy,
- SourceLocation l, SourceLocation RParenLoc)
+ SourceLocation l, SourceLocation RParenLoc,
+ SourceRange AngleBrackets)
: CXXNamedCastExpr(CXXDynamicCastExprClass, ty, VK, kind, op, pathSize,
- writtenTy, l, RParenLoc) {}
+ writtenTy, l, RParenLoc, AngleBrackets) {}
explicit CXXDynamicCastExpr(EmptyShell Empty, unsigned pathSize)
: CXXNamedCastExpr(CXXDynamicCastExprClass, Empty, pathSize) { }
@@ -266,7 +275,8 @@ public:
ExprValueKind VK, CastKind Kind, Expr *Op,
const CXXCastPath *Path,
TypeSourceInfo *Written, SourceLocation L,
- SourceLocation RParenLoc);
+ SourceLocation RParenLoc,
+ SourceRange AngleBrackets);
static CXXDynamicCastExpr *CreateEmpty(ASTContext &Context,
unsigned pathSize);
@@ -288,9 +298,10 @@ class CXXReinterpretCastExpr : public CXXNamedCastExpr {
CXXReinterpretCastExpr(QualType ty, ExprValueKind vk, CastKind kind,
Expr *op, unsigned pathSize,
TypeSourceInfo *writtenTy, SourceLocation l,
- SourceLocation RParenLoc)
+ SourceLocation RParenLoc,
+ SourceRange AngleBrackets)
: CXXNamedCastExpr(CXXReinterpretCastExprClass, ty, vk, kind, op,
- pathSize, writtenTy, l, RParenLoc) {}
+ pathSize, writtenTy, l, RParenLoc, AngleBrackets) {}
CXXReinterpretCastExpr(EmptyShell Empty, unsigned pathSize)
: CXXNamedCastExpr(CXXReinterpretCastExprClass, Empty, pathSize) { }
@@ -300,7 +311,8 @@ public:
ExprValueKind VK, CastKind Kind,
Expr *Op, const CXXCastPath *Path,
TypeSourceInfo *WrittenTy, SourceLocation L,
- SourceLocation RParenLoc);
+ SourceLocation RParenLoc,
+ SourceRange AngleBrackets);
static CXXReinterpretCastExpr *CreateEmpty(ASTContext &Context,
unsigned pathSize);
@@ -317,9 +329,9 @@ public:
class CXXConstCastExpr : public CXXNamedCastExpr {
CXXConstCastExpr(QualType ty, ExprValueKind VK, Expr *op,
TypeSourceInfo *writtenTy, SourceLocation l,
- SourceLocation RParenLoc)
+ SourceLocation RParenLoc, SourceRange AngleBrackets)
: CXXNamedCastExpr(CXXConstCastExprClass, ty, VK, CK_NoOp, op,
- 0, writtenTy, l, RParenLoc) {}
+ 0, writtenTy, l, RParenLoc, AngleBrackets) {}
explicit CXXConstCastExpr(EmptyShell Empty)
: CXXNamedCastExpr(CXXConstCastExprClass, Empty, 0) { }
@@ -328,7 +340,8 @@ public:
static CXXConstCastExpr *Create(ASTContext &Context, QualType T,
ExprValueKind VK, Expr *Op,
TypeSourceInfo *WrittenTy, SourceLocation L,
- SourceLocation RParenLoc);
+ SourceLocation RParenLoc,
+ SourceRange AngleBrackets);
static CXXConstCastExpr *CreateEmpty(ASTContext &Context);
static bool classof(const Stmt *T) {
@@ -386,9 +399,6 @@ public:
return getArg(0)->getLocStart();
}
SourceLocation getLocEnd() const { return getRParenLoc(); }
- SourceRange getSourceRange() const {
- return SourceRange(getLocStart(), getLocEnd());
- }
/// getUDSuffixLoc - Returns the location of a ud-suffix in the expression.
@@ -424,7 +434,8 @@ public:
bool getValue() const { return Value; }
void setValue(bool V) { Value = V; }
- SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(Loc); }
+ SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }
@@ -449,7 +460,8 @@ public:
explicit CXXNullPtrLiteralExpr(EmptyShell Empty)
: Expr(CXXNullPtrLiteralExprClass, Empty) { }
- SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(Loc); }
+ SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }
@@ -531,6 +543,8 @@ public:
Operand = E;
}
+ SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
+ SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
SourceRange getSourceRange() const LLVM_READONLY { return Range; }
void setSourceRange(SourceRange R) { Range = R; }
@@ -605,6 +619,8 @@ public:
Operand = E;
}
+ SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
+ SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
SourceRange getSourceRange() const LLVM_READONLY { return Range; }
void setSourceRange(SourceRange R) { Range = R; }
@@ -653,7 +669,8 @@ public:
SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }
- SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(Loc); }
+ SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
bool isImplicit() const { return Implicit; }
void setImplicit(bool I) { Implicit = I; }
@@ -702,10 +719,11 @@ public:
/// this variable.
bool isThrownVariableInScope() const { return IsThrownVariableInScope; }
- SourceRange getSourceRange() const LLVM_READONLY {
+ SourceLocation getLocStart() const LLVM_READONLY { return ThrowLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY {
if (getSubExpr() == 0)
- return SourceRange(ThrowLoc, ThrowLoc);
- return SourceRange(ThrowLoc, getSubExpr()->getSourceRange().getEnd());
+ return ThrowLoc;
+ return getSubExpr()->getLocEnd();
}
static bool classof(const Stmt *T) {
@@ -789,11 +807,12 @@ public:
/// used.
SourceLocation getUsedLocation() const { return Loc; }
- SourceRange getSourceRange() const LLVM_READONLY {
- // Default argument expressions have no representation in the
- // source, so they have an empty source range.
- return SourceRange();
- }
+ // Default argument expressions have no representation in the
+ // source, so they have an empty source range.
+ SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
+ SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }
+
+ SourceLocation getExprLoc() const LLVM_READONLY { return Loc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXDefaultArgExprClass;
@@ -866,9 +885,10 @@ public:
Expr *getSubExpr() { return cast<Expr>(SubExpr); }
void setSubExpr(Expr *E) { SubExpr = E; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SubExpr->getSourceRange();
+ SourceLocation getLocStart() const LLVM_READONLY {
+ return SubExpr->getLocStart();
}
+ SourceLocation getLocEnd() const LLVM_READONLY { return SubExpr->getLocEnd();}
// Implement isa/cast/dyncast/etc.
static bool classof(const Stmt *T) {
@@ -1001,7 +1021,8 @@ public:
Args[Arg] = ArgExpr;
}
- SourceRange getSourceRange() const LLVM_READONLY;
+ SourceLocation getLocStart() const LLVM_READONLY;
+ SourceLocation getLocEnd() const LLVM_READONLY;
SourceRange getParenRange() const { return ParenRange; }
void setParenRange(SourceRange Range) { ParenRange = Range; }
@@ -1057,9 +1078,9 @@ public:
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(TyBeginLoc, RParenLoc);
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return TyBeginLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXFunctionalCastExprClass;
}
@@ -1089,13 +1110,15 @@ public:
ArrayRef<Expr *> Args,
SourceRange parenRange,
bool HadMultipleCandidates,
- bool ZeroInitialization = false);
+ bool ListInitialization,
+ bool ZeroInitialization);
explicit CXXTemporaryObjectExpr(EmptyShell Empty)
: CXXConstructExpr(CXXTemporaryObjectExprClass, Empty), Type() { }
TypeSourceInfo *getTypeSourceInfo() const { return Type; }
- SourceRange getSourceRange() const LLVM_READONLY;
+ SourceLocation getLocStart() const LLVM_READONLY;
+ SourceLocation getLocEnd() const LLVM_READONLY;
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXTemporaryObjectExprClass;
@@ -1111,7 +1134,7 @@ public:
/// \code
/// void low_pass_filter(std::vector<double> &values, double cutoff) {
/// values.erase(std::remove_if(values.begin(), values.end(),
-// [=](double value) { return value > cutoff; });
+/// [=](double value) { return value > cutoff; });
/// }
/// \endcode
///
@@ -1393,9 +1416,10 @@ public:
return T->getStmtClass() == LambdaExprClass;
}
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(IntroducerRange.getBegin(), ClosingBrace);
+ SourceLocation getLocStart() const LLVM_READONLY {
+ return IntroducerRange.getBegin();
}
+ SourceLocation getLocEnd() const LLVM_READONLY { return ClosingBrace; }
child_range children() {
return child_range(getStoredStmts(), getStoredStmts() + NumCaptures + 1);
@@ -1434,7 +1458,8 @@ public:
SourceLocation getRParenLoc() const { return RParenLoc; }
- SourceRange getSourceRange() const LLVM_READONLY;
+ SourceLocation getLocStart() const LLVM_READONLY;
+ SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXScalarValueInitExprClass;
@@ -1621,6 +1646,8 @@ public:
SourceRange getSourceRange() const LLVM_READONLY {
return Range;
}
+ SourceLocation getLocStart() const LLVM_READONLY { return getStartLoc(); }
+ SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXNewExprClass;
@@ -1688,9 +1715,8 @@ public:
/// return an invalid type.
QualType getDestroyedType() const;
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(Loc, Argument->getLocEnd());
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
+ SourceLocation getLocEnd() const LLVM_READONLY {return Argument->getLocEnd();}
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXDeleteExprClass;
@@ -1878,7 +1904,8 @@ public:
DestroyedType = PseudoDestructorTypeStorage(Info);
}
- SourceRange getSourceRange() const LLVM_READONLY;
+ SourceLocation getLocStart() const LLVM_READONLY {return Base->getLocStart();}
+ SourceLocation getLocEnd() const LLVM_READONLY;
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXPseudoDestructorExprClass;
@@ -1925,7 +1952,8 @@ public:
: Expr(UnaryTypeTraitExprClass, Empty), UTT(0), Value(false),
QueriedType() { }
- SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(Loc, RParen);}
+ SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return RParen; }
UnaryTypeTrait getTrait() const { return static_cast<UnaryTypeTrait>(UTT); }
@@ -1990,9 +2018,8 @@ public:
: Expr(BinaryTypeTraitExprClass, Empty), BTT(0), Value(false),
LhsType(), RhsType() { }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(Loc, RParen);
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return RParen; }
BinaryTypeTrait getTrait() const {
return static_cast<BinaryTypeTrait>(BTT);
@@ -2097,8 +2124,9 @@ public:
return getTypeSourceInfos() + getNumArgs();
}
- SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(Loc, RParenLoc); }
-
+ SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == TypeTraitExprClass;
}
@@ -2159,9 +2187,8 @@ public:
virtual ~ArrayTypeTraitExpr() { }
- virtual SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(Loc, RParen);
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return RParen; }
ArrayTypeTrait getTrait() const { return static_cast<ArrayTypeTrait>(ATT); }
@@ -2221,9 +2248,8 @@ public:
: Expr(ExpressionTraitExprClass, Empty), ET(0), Value(false),
QueriedExpression() { }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(Loc, RParen);
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return RParen; }
ExpressionTrait getTrait() const { return static_cast<ExpressionTrait>(ET); }
@@ -2411,7 +2437,7 @@ public:
///
/// This points to the same data as getExplicitTemplateArgs(), but
/// returns null if there are no explicit template arguments.
- const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() {
+ const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const {
if (!hasExplicitTemplateArgs()) return 0;
return &getExplicitTemplateArgs();
}
@@ -2512,13 +2538,15 @@ public:
/// that was looked in to find these results.
CXXRecordDecl *getNamingClass() const { return NamingClass; }
- SourceRange getSourceRange() const LLVM_READONLY {
- SourceRange Range(getNameInfo().getSourceRange());
- if (getQualifierLoc())
- Range.setBegin(getQualifierLoc().getBeginLoc());
+ SourceLocation getLocStart() const LLVM_READONLY {
+ if (NestedNameSpecifierLoc l = getQualifierLoc())
+ return l.getBeginLoc();
+ return getNameInfo().getLocStart();
+ }
+ SourceLocation getLocEnd() const LLVM_READONLY {
if (hasExplicitTemplateArgs())
- Range.setEnd(getRAngleLoc());
- return Range;
+ return getRAngleLoc();
+ return getNameInfo().getLocEnd();
}
child_range children() { return child_range(); }
@@ -2647,7 +2675,7 @@ public:
/// \brief Retrieves the optional explicit template arguments.
/// This points to the same data as getExplicitTemplateArgs(), but
/// returns null if there are no explicit template arguments.
- const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() {
+ const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const {
if (!hasExplicitTemplateArgs()) return 0;
return &getExplicitTemplateArgs();
}
@@ -2666,11 +2694,13 @@ public:
return getExplicitTemplateArgs().NumTemplateArgs;
}
- SourceRange getSourceRange() const LLVM_READONLY {
- SourceRange Range(QualifierLoc.getBeginLoc(), getLocation());
+ SourceLocation getLocStart() const LLVM_READONLY {
+ return QualifierLoc.getBeginLoc();
+ }
+ SourceLocation getLocEnd() const LLVM_READONLY {
if (hasExplicitTemplateArgs())
- Range.setEnd(getRAngleLoc());
- return Range;
+ return getRAngleLoc();
+ return getLocation();
}
static bool classof(const Stmt *T) {
@@ -2740,9 +2770,10 @@ public:
/// when modifying an existing AST to preserve its invariants.
void setSubExpr(Expr *E) { SubExpr = E; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SubExpr->getSourceRange();
+ SourceLocation getLocStart() const LLVM_READONLY {
+ return SubExpr->getLocStart();
}
+ SourceLocation getLocEnd() const LLVM_READONLY { return SubExpr->getLocEnd();}
// Implement isa/cast/dyncast/etc.
static bool classof(const Stmt *T) {
@@ -2855,7 +2886,8 @@ public:
*(arg_begin() + I) = E;
}
- SourceRange getSourceRange() const LLVM_READONLY;
+ SourceLocation getLocStart() const LLVM_READONLY;
+ SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXUnresolvedConstructExprClass;
@@ -3061,7 +3093,7 @@ public:
/// \brief Retrieves the optional explicit template arguments.
/// This points to the same data as getExplicitTemplateArgs(), but
/// returns null if there are no explicit template arguments.
- const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() {
+ const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const {
if (!hasExplicitTemplateArgs()) return 0;
return &getExplicitTemplateArgs();
}
@@ -3089,20 +3121,18 @@ public:
return getExplicitTemplateArgs().NumTemplateArgs;
}
- SourceRange getSourceRange() const LLVM_READONLY {
- SourceRange Range;
+ SourceLocation getLocStart() const LLVM_READONLY {
if (!isImplicitAccess())
- Range.setBegin(Base->getSourceRange().getBegin());
- else if (getQualifier())
- Range.setBegin(getQualifierLoc().getBeginLoc());
- else
- Range.setBegin(MemberNameInfo.getBeginLoc());
+ return Base->getLocStart();
+ if (getQualifier())
+ return getQualifierLoc().getBeginLoc();
+ return MemberNameInfo.getBeginLoc();
+ }
+ SourceLocation getLocEnd() const LLVM_READONLY {
if (hasExplicitTemplateArgs())
- Range.setEnd(getRAngleLoc());
- else
- Range.setEnd(MemberNameInfo.getEndLoc());
- return Range;
+ return getRAngleLoc();
+ return MemberNameInfo.getEndLoc();
}
static bool classof(const Stmt *T) {
@@ -3226,16 +3256,17 @@ public:
// expression refers to.
SourceLocation getMemberLoc() const { return getNameLoc(); }
- SourceRange getSourceRange() const LLVM_READONLY {
- SourceRange Range = getMemberNameInfo().getSourceRange();
+ SourceLocation getLocStart() const LLVM_READONLY {
if (!isImplicitAccess())
- Range.setBegin(Base->getSourceRange().getBegin());
- else if (getQualifierLoc())
- Range.setBegin(getQualifierLoc().getBeginLoc());
-
+ return Base->getLocStart();
+ if (NestedNameSpecifierLoc l = getQualifierLoc())
+ return l.getBeginLoc();
+ return getMemberNameInfo().getLocStart();
+ }
+ SourceLocation getLocEnd() const LLVM_READONLY {
if (hasExplicitTemplateArgs())
- Range.setEnd(getRAngleLoc());
- return Range;
+ return getRAngleLoc();
+ return getMemberNameInfo().getLocEnd();
}
static bool classof(const Stmt *T) {
@@ -3277,6 +3308,8 @@ public:
Expr *getOperand() const { return static_cast<Expr*>(Operand); }
+ SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
+ SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
SourceRange getSourceRange() const LLVM_READONLY { return Range; }
bool getValue() const { return Value; }
@@ -3323,7 +3356,7 @@ class PackExpansionExpr : public Expr {
public:
PackExpansionExpr(QualType T, Expr *Pattern, SourceLocation EllipsisLoc,
- llvm::Optional<unsigned> NumExpansions)
+ Optional<unsigned> NumExpansions)
: Expr(PackExpansionExprClass, T, Pattern->getValueKind(),
Pattern->getObjectKind(), /*TypeDependent=*/true,
/*ValueDependent=*/true, /*InstantiationDependent=*/true,
@@ -3346,16 +3379,17 @@ public:
/// \brief Determine the number of expansions that will be produced when
/// this pack expansion is instantiated, if already known.
- llvm::Optional<unsigned> getNumExpansions() const {
+ Optional<unsigned> getNumExpansions() const {
if (NumExpansions)
return NumExpansions - 1;
- return llvm::Optional<unsigned>();
+ return None;
}
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(Pattern->getLocStart(), EllipsisLoc);
+ SourceLocation getLocStart() const LLVM_READONLY {
+ return Pattern->getLocStart();
}
+ SourceLocation getLocEnd() const LLVM_READONLY { return EllipsisLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == PackExpansionExprClass;
@@ -3458,9 +3492,8 @@ public:
return Length;
}
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(OperatorLoc, RParenLoc);
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return OperatorLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == SizeOfPackExprClass;
@@ -3500,7 +3533,8 @@ public:
Param(param), Replacement(replacement), NameLoc(loc) {}
SourceLocation getNameLoc() const { return NameLoc; }
- SourceRange getSourceRange() const LLVM_READONLY { return NameLoc; }
+ SourceLocation getLocStart() const LLVM_READONLY { return NameLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return NameLoc; }
Expr *getReplacement() const { return cast<Expr>(Replacement); }
@@ -3561,7 +3595,8 @@ public:
/// template arguments.
TemplateArgument getArgumentPack() const;
- SourceRange getSourceRange() const LLVM_READONLY { return NameLoc; }
+ SourceLocation getLocStart() const LLVM_READONLY { return NameLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return NameLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == SubstNonTypeTemplateParmPackExprClass;
@@ -3606,7 +3641,7 @@ public:
static FunctionParmPackExpr *Create(ASTContext &Context, QualType T,
ParmVarDecl *ParamPack,
SourceLocation NameLoc,
- llvm::ArrayRef<Decl*> Params);
+ ArrayRef<Decl *> Params);
static FunctionParmPackExpr *CreateEmpty(ASTContext &Context,
unsigned NumParams);
@@ -3628,7 +3663,8 @@ public:
/// \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; }
+ SourceLocation getLocStart() const LLVM_READONLY { return NameLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return NameLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == FunctionParmPackExprClass;
@@ -3684,8 +3720,11 @@ public:
return getValueKind() == VK_LValue;
}
- SourceRange getSourceRange() const LLVM_READONLY {
- return Temporary->getSourceRange();
+ SourceLocation getLocStart() const LLVM_READONLY {
+ return Temporary->getLocStart();
+ }
+ SourceLocation getLocEnd() const LLVM_READONLY {
+ return Temporary->getLocEnd();
}
static bool classof(const Stmt *T) {
diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h
index 27f5da0ce707..dfd45279dd15 100644
--- a/include/clang/AST/ExprObjC.h
+++ b/include/clang/AST/ExprObjC.h
@@ -44,9 +44,8 @@ public:
SourceLocation getAtLoc() const { return AtLoc; }
void setAtLoc(SourceLocation L) { AtLoc = L; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(AtLoc, String->getLocEnd());
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return String->getLocEnd(); }
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCStringLiteralClass;
@@ -72,8 +71,9 @@ public:
bool getValue() const { return Value; }
void setValue(bool V) { Value = V; }
- SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(Loc); }
-
+ SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
+
SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }
@@ -112,6 +112,8 @@ public:
SourceLocation getAtLoc() const { return Range.getBegin(); }
+ SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
+ SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
SourceRange getSourceRange() const LLVM_READONLY {
return Range;
}
@@ -133,7 +135,7 @@ class ObjCArrayLiteral : public Expr {
SourceRange Range;
ObjCMethodDecl *ArrayWithObjectsMethod;
- ObjCArrayLiteral(llvm::ArrayRef<Expr *> Elements,
+ ObjCArrayLiteral(ArrayRef<Expr *> Elements,
QualType T, ObjCMethodDecl * Method,
SourceRange SR);
@@ -142,12 +144,14 @@ class ObjCArrayLiteral : public Expr {
public:
static ObjCArrayLiteral *Create(ASTContext &C,
- llvm::ArrayRef<Expr *> Elements,
+ ArrayRef<Expr *> Elements,
QualType T, ObjCMethodDecl * Method,
SourceRange SR);
static ObjCArrayLiteral *CreateEmpty(ASTContext &C, unsigned NumElements);
+ SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
+ SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
SourceRange getSourceRange() const LLVM_READONLY { return Range; }
static bool classof(const Stmt *T) {
@@ -202,12 +206,18 @@ struct ObjCDictionaryElement {
/// \brief The number of elements this pack expansion will expand to, if
/// this is a pack expansion and is known.
- llvm::Optional<unsigned> NumExpansions;
+ Optional<unsigned> NumExpansions;
/// \brief Determines whether this dictionary element is a pack expansion.
bool isPackExpansion() const { return EllipsisLoc.isValid(); }
};
+} // end namespace clang
+
+namespace llvm {
+template <> struct isPodLike<clang::ObjCDictionaryElement> : llvm::true_type {};
+}
+namespace clang {
/// ObjCDictionaryLiteral - AST node to represent objective-c dictionary
/// literals; as in: @{@"name" : NSUserName(), @"date" : [NSDate date] };
class ObjCDictionaryLiteral : public Expr {
@@ -296,8 +306,7 @@ public:
ObjCDictionaryElement getKeyValueElement(unsigned Index) const {
assert((Index < NumElements) && "Arg access out of range!");
const KeyValuePair &KV = getKeyValues()[Index];
- ObjCDictionaryElement Result = { KV.Key, KV.Value, SourceLocation(),
- llvm::Optional<unsigned>() };
+ ObjCDictionaryElement Result = { KV.Key, KV.Value, SourceLocation(), None };
if (HasPackExpansions) {
const ExpansionData &Expansion = getExpansionData()[Index];
Result.EllipsisLoc = Expansion.EllipsisLoc;
@@ -310,6 +319,8 @@ public:
ObjCMethodDecl *getDictWithObjectsMethod() const
{ return DictWithObjectsMethod; }
+ SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
+ SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
SourceRange getSourceRange() const LLVM_READONLY { return Range; }
static bool classof(const Stmt *T) {
@@ -360,9 +371,8 @@ public:
EncodedType = EncType;
}
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(AtLoc, RParenLoc);
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCEncodeExprClass;
@@ -393,9 +403,8 @@ public:
void setAtLoc(SourceLocation L) { AtLoc = L; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(AtLoc, RParenLoc);
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
/// getNumArgs - Return the number of actual arguments to this call.
unsigned getNumArgs() const { return SelName.getNumArgs(); }
@@ -408,9 +417,13 @@ public:
child_range children() { return child_range(); }
};
-/// ObjCProtocolExpr used for protocol expression in Objective-C. This is used
-/// as: @protocol(foo), as in:
-/// obj conformsToProtocol:@protocol(foo)]
+/// ObjCProtocolExpr used for protocol expression in Objective-C.
+///
+/// This is used as: \@protocol(foo), as in:
+/// \code
+/// [obj conformsToProtocol:@protocol(foo)]
+/// \endcode
+///
/// The return type is "Protocol*".
class ObjCProtocolExpr : public Expr {
ObjCProtocolDecl *TheProtocol;
@@ -433,9 +446,8 @@ public:
void setAtLoc(SourceLocation L) { AtLoc = L; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(AtLoc, RParenLoc);
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCProtocolExprClass;
@@ -453,18 +465,23 @@ class ObjCIvarRefExpr : public Expr {
ObjCIvarDecl *D;
Stmt *Base;
SourceLocation Loc;
+ /// OpLoc - This is the location of '.' or '->'
+ SourceLocation OpLoc;
+
bool IsArrow:1; // True if this is "X->F", false if this is "X.F".
bool IsFreeIvar:1; // True if ivar reference has no base (self assumed).
public:
ObjCIvarRefExpr(ObjCIvarDecl *d, QualType t,
- SourceLocation l, Expr *base,
+ SourceLocation l, SourceLocation oploc,
+ Expr *base,
bool arrow = false, bool freeIvar = false) :
Expr(ObjCIvarRefExprClass, t, VK_LValue, OK_Ordinary,
/*TypeDependent=*/false, base->isValueDependent(),
base->isInstantiationDependent(),
base->containsUnexpandedParameterPack()),
- D(d), Base(base), Loc(l), IsArrow(arrow), IsFreeIvar(freeIvar) {}
+ D(d), Base(base), Loc(l), OpLoc(oploc),
+ IsArrow(arrow), IsFreeIvar(freeIvar) {}
explicit ObjCIvarRefExpr(EmptyShell Empty)
: Expr(ObjCIvarRefExprClass, Empty) {}
@@ -485,10 +502,13 @@ public:
SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return isFreeIvar() ? SourceRange(Loc)
- : SourceRange(getBase()->getLocStart(), Loc);
+ SourceLocation getLocStart() const LLVM_READONLY {
+ return isFreeIvar() ? Loc : getBase()->getLocStart();
}
+ SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
+
+ SourceLocation getOpLoc() const { return OpLoc; }
+ void setOpLoc(SourceLocation L) { OpLoc = L; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCIvarRefExprClass;
@@ -697,11 +717,10 @@ public:
bool isSuperReceiver() const { return Receiver.is<const Type*>(); }
bool isClassReceiver() const { return Receiver.is<ObjCInterfaceDecl*>(); }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange((isObjectReceiver() ? getBase()->getLocStart()
- : getReceiverLocation()),
- IdLoc);
+ SourceLocation getLocStart() const LLVM_READONLY {
+ return isObjectReceiver() ? getBase()->getLocStart() :getReceiverLocation();
}
+ SourceLocation getLocEnd() const LLVM_READONLY { return IdLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCPropertyRefExprClass;
@@ -796,10 +815,12 @@ public:
SourceLocation getRBracket() const { return RBracket; }
void setRBracket(SourceLocation RB) { RBracket = RB; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(SubExprs[BASE]->getLocStart(), RBracket);
+
+ SourceLocation getLocStart() const LLVM_READONLY {
+ return SubExprs[BASE]->getLocStart();
}
-
+ SourceLocation getLocEnd() const LLVM_READONLY { return RBracket; }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCSubscriptRefExprClass;
}
@@ -1335,9 +1356,8 @@ public:
LBracLoc = R.getBegin();
RBracLoc = R.getEnd();
}
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(LBracLoc, RBracLoc);
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return LBracLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return RBracLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCMessageExprClass;
@@ -1372,16 +1392,20 @@ class ObjCIsaExpr : public Expr {
/// IsaMemberLoc - This is the location of the 'isa'.
SourceLocation IsaMemberLoc;
+
+ /// OpLoc - This is the location of '.' or '->'
+ SourceLocation OpLoc;
/// IsArrow - True if this is "X->F", false if this is "X.F".
bool IsArrow;
public:
- ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, QualType ty)
+ ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, SourceLocation oploc,
+ QualType ty)
: Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary,
/*TypeDependent=*/false, base->isValueDependent(),
base->isInstantiationDependent(),
/*ContainsUnexpandedParameterPack=*/false),
- Base(base), IsaMemberLoc(l), IsArrow(isarrow) {}
+ Base(base), IsaMemberLoc(l), OpLoc(oploc), IsArrow(isarrow) {}
/// \brief Build an empty expression.
explicit ObjCIsaExpr(EmptyShell Empty) : Expr(ObjCIsaExprClass, Empty) { }
@@ -1396,10 +1420,19 @@ public:
/// location of 'F'.
SourceLocation getIsaMemberLoc() const { return IsaMemberLoc; }
void setIsaMemberLoc(SourceLocation L) { IsaMemberLoc = L; }
+
+ SourceLocation getOpLoc() const { return OpLoc; }
+ void setOpLoc(SourceLocation L) { OpLoc = L; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(getBase()->getLocStart(), IsaMemberLoc);
+ SourceLocation getLocStart() const LLVM_READONLY {
+ return getBase()->getLocStart();
+ }
+
+ SourceLocation getBaseLocEnd() const LLVM_READONLY {
+ return getBase()->getLocEnd();
}
+
+ SourceLocation getLocEnd() const LLVM_READONLY { return IsaMemberLoc; }
SourceLocation getExprLoc() const LLVM_READONLY { return IsaMemberLoc; }
@@ -1469,9 +1502,11 @@ public:
child_range children() { return child_range(&Operand, &Operand+1); }
// Source locations are determined by the subexpression.
- SourceRange getSourceRange() const LLVM_READONLY {
- return Operand->getSourceRange();
+ SourceLocation getLocStart() const LLVM_READONLY {
+ return Operand->getLocStart();
}
+ SourceLocation getLocEnd() const LLVM_READONLY { return Operand->getLocEnd();}
+
SourceLocation getExprLoc() const LLVM_READONLY {
return getSubExpr()->getExprLoc();
}
@@ -1520,8 +1555,9 @@ public:
/// \brief The location of the bridge keyword.
SourceLocation getBridgeKeywordLoc() const { return BridgeKeywordLoc; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(LParenLoc, getSubExpr()->getLocEnd());
+ SourceLocation getLocStart() const LLVM_READONLY { return LParenLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY {
+ return getSubExpr()->getLocEnd();
}
static bool classof(const Stmt *T) {
diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h
index db2bddb4bfca..81fcf242b65e 100644
--- a/include/clang/AST/ExternalASTSource.h
+++ b/include/clang/AST/ExternalASTSource.h
@@ -14,8 +14,8 @@
#ifndef LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H
#define LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H
-#include "clang/AST/DeclBase.h"
#include "clang/AST/CharUnits.h"
+#include "clang/AST/DeclBase.h"
#include "llvm/ADT/DenseMap.h"
namespace clang {
@@ -24,7 +24,10 @@ class ASTConsumer;
class CXXBaseSpecifier;
class DeclarationName;
class ExternalSemaSource; // layering violation required for downcasting
+class FieldDecl;
+class Module;
class NamedDecl;
+class RecordDecl;
class Selector;
class Stmt;
class TagDecl;
@@ -115,23 +118,28 @@ public:
/// The default implementation of this method is a no-op.
virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset);
- /// \brief Finds all declarations with the given name in the
- /// given context.
- ///
- /// Generally the final step of this method is either to call
- /// SetExternalVisibleDeclsForName or to recursively call lookup on
- /// the DeclContext after calling SetExternalVisibleDecls.
+ /// \brief Update an out-of-date identifier.
+ virtual void updateOutOfDateIdentifier(IdentifierInfo &II) { }
+
+ /// \brief Find all declarations with the given name in the given context,
+ /// and add them to the context by calling SetExternalVisibleDeclsForName
+ /// or SetNoExternalVisibleDeclsForName.
+ /// \return \c true if any declarations might have been found, \c false if
+ /// we definitely have no declarations with tbis name.
///
- /// The default implementation of this method is a no-op.
- virtual DeclContextLookupResult
+ /// The default implementation of this method is a no-op returning \c false.
+ virtual bool
FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name);
/// \brief Ensures that the table of all visible declarations inside this
/// context is up to date.
///
- /// The default implementation of this functino is a no-op.
+ /// The default implementation of this function is a no-op.
virtual void completeVisibleDeclsMap(const DeclContext *DC);
+ /// \brief Retrieve the module that corresponds to the given module ID.
+ virtual Module *getModule(unsigned ID) { return 0; }
+
/// \brief Finds all declarations lexically contained within the given
/// DeclContext, after applying an optional filter predicate.
///
diff --git a/include/clang/AST/LambdaMangleContext.h b/include/clang/AST/LambdaMangleContext.h
index 3e2fbad2f8e6..bbaee26494a9 100644
--- a/include/clang/AST/LambdaMangleContext.h
+++ b/include/clang/AST/LambdaMangleContext.h
@@ -14,7 +14,9 @@
#ifndef LLVM_CLANG_LAMBDAMANGLECONTEXT_H
#define LLVM_CLANG_LAMBDAMANGLECONTEXT_H
+#include "clang/Basic/LLVM.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
namespace clang {
@@ -23,7 +25,7 @@ class FunctionProtoType;
/// \brief Keeps track of the mangled names of lambda expressions within a
/// particular context.
-class LambdaMangleContext {
+class LambdaMangleContext : public RefCountedBase<LambdaMangleContext> {
llvm::DenseMap<const FunctionProtoType *, unsigned> ManglingNumbers;
public:
diff --git a/include/clang/AST/Makefile b/include/clang/AST/Makefile
index 7fb33f27741a..ae84bcfd5817 100644
--- a/include/clang/AST/Makefile
+++ b/include/clang/AST/Makefile
@@ -1,8 +1,12 @@
CLANG_LEVEL := ../../..
TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic
-BUILT_SOURCES = Attrs.inc AttrImpl.inc StmtNodes.inc DeclNodes.inc \
+BUILT_SOURCES = Attrs.inc AttrImpl.inc AttrDump.inc \
+ StmtNodes.inc DeclNodes.inc \
CommentNodes.inc CommentHTMLTags.inc \
- CommentHTMLTagsProperties.inc CommentCommandInfo.inc
+ CommentHTMLTagsProperties.inc \
+ CommentHTMLNamedCharacterReferences.inc \
+ CommentCommandInfo.inc \
+ CommentCommandList.inc
TABLEGEN_INC_FILES_COMMON = 1
@@ -20,6 +24,12 @@ $(ObjDir)/AttrImpl.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
$(Verb) $(ClangTableGen) -gen-clang-attr-impl -o $(call SYSPATH, $@) \
-I $(PROJ_SRC_DIR)/../../ $<
+$(ObjDir)/AttrDump.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
+ $(ObjDir)/.dir
+ $(Echo) "Building Clang attribute dumper with tblgen"
+ $(Verb) $(ClangTableGen) -gen-clang-attr-dump -o $(call SYSPATH, $@) \
+ -I $(PROJ_SRC_DIR)/../../ $<
+
$(ObjDir)/StmtNodes.inc.tmp : $(TD_SRC_DIR)/StmtNodes.td $(CLANG_TBLGEN) \
$(ObjDir)/.dir
$(Echo) "Building Clang statement node tables with tblgen"
@@ -45,8 +55,19 @@ $(ObjDir)/CommentHTMLTagsProperties.inc.tmp : $(PROJ_SRC_DIR)/CommentHTMLTags.td
$(Echo) "Building Clang comment HTML tag properties with tblgen"
$(Verb) $(ClangTableGen) -gen-clang-comment-html-tags-properties -o $(call SYSPATH, $@) $<
+$(ObjDir)/CommentHTMLNamedCharacterReferences.inc.tmp : \
+ $(PROJ_SRC_DIR)/CommentHTMLNamedCharacterReferences.td \
+ $(CLANG_TBLGEN) $(ObjDir)/.dir
+ $(Echo) "Building Clang named character reference translation function with tblgen"
+ $(Verb) $(ClangTableGen) -gen-clang-comment-html-named-character-references -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, $@) $<
+$(ObjDir)/CommentCommandList.inc.tmp : $(PROJ_SRC_DIR)/CommentCommands.td \
+ $(CLANG_TBLGEN) $(ObjDir)/.dir
+ $(Echo) "Building Clang list of comment commands with tblgen"
+ $(Verb) $(ClangTableGen) -gen-clang-comment-command-list -o $(call SYSPATH, $@) $<
+
diff --git a/include/clang/AST/Mangle.h b/include/clang/AST/Mangle.h
index a0dffb93088b..94faa19f1b33 100644
--- a/include/clang/AST/Mangle.h
+++ b/include/clang/AST/Mangle.h
@@ -17,8 +17,8 @@
#include "clang/AST/Type.h"
#include "clang/Basic/ABI.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/raw_ostream.h"
namespace clang {
diff --git a/include/clang/AST/NSAPI.h b/include/clang/AST/NSAPI.h
index f9fd1f906b55..0b21b0334812 100644
--- a/include/clang/AST/NSAPI.h
+++ b/include/clang/AST/NSAPI.h
@@ -52,7 +52,7 @@ public:
Selector getNSStringSelector(NSStringMethodKind MK) const;
/// \brief Return NSStringMethodKind if \param Sel is such a selector.
- llvm::Optional<NSStringMethodKind> getNSStringMethodKind(Selector Sel) const;
+ Optional<NSStringMethodKind> getNSStringMethodKind(Selector Sel) const;
/// \brief Returns true if the expression \param E is a reference of
/// "NSUTF8StringEncoding" enum constant.
@@ -84,7 +84,7 @@ public:
Selector getNSArraySelector(NSArrayMethodKind MK) const;
/// \brief Return NSArrayMethodKind if \p Sel is such a selector.
- llvm::Optional<NSArrayMethodKind> getNSArrayMethodKind(Selector Sel);
+ Optional<NSArrayMethodKind> getNSArrayMethodKind(Selector Sel);
/// \brief Enumerates the NSDictionary methods used to generate literals.
enum NSDictionaryMethodKind {
@@ -96,17 +96,17 @@ public:
NSDict_dictionaryWithObjectsAndKeys,
NSDict_initWithDictionary,
NSDict_initWithObjectsAndKeys,
+ NSDict_initWithObjectsForKeys,
NSDict_objectForKey,
NSMutableDict_setObjectForKey
};
- static const unsigned NumNSDictionaryMethods = 10;
+ static const unsigned NumNSDictionaryMethods = 11;
/// \brief The Objective-C NSDictionary selectors.
Selector getNSDictionarySelector(NSDictionaryMethodKind MK) const;
/// \brief Return NSDictionaryMethodKind if \p Sel is such a selector.
- llvm::Optional<NSDictionaryMethodKind>
- getNSDictionaryMethodKind(Selector Sel);
+ Optional<NSDictionaryMethodKind> getNSDictionaryMethodKind(Selector Sel);
/// \brief Returns selector for "objectForKeyedSubscript:".
Selector getObjectForKeyedSubscriptSelector() const {
@@ -170,12 +170,12 @@ public:
}
/// \brief Return NSNumberLiteralMethodKind if \p Sel is such a selector.
- llvm::Optional<NSNumberLiteralMethodKind>
+ Optional<NSNumberLiteralMethodKind>
getNSNumberLiteralMethodKind(Selector Sel) const;
/// \brief Determine the appropriate NSNumber factory method kind for a
/// literal of the given type.
- llvm::Optional<NSNumberLiteralMethodKind>
+ Optional<NSNumberLiteralMethodKind>
getNSNumberFactoryMethodKind(QualType T) const;
/// \brief Returns true if \param T is a typedef of "BOOL" in objective-c.
diff --git a/include/clang/AST/NestedNameSpecifier.h b/include/clang/AST/NestedNameSpecifier.h
index bf9e1cbc764b..58f39862b102 100644
--- a/include/clang/AST/NestedNameSpecifier.h
+++ b/include/clang/AST/NestedNameSpecifier.h
@@ -117,7 +117,7 @@ public:
/// \brief Builds a nested name specifier that names a namespace.
static NestedNameSpecifier *Create(const ASTContext &Context,
NestedNameSpecifier *Prefix,
- NamespaceDecl *NS);
+ const NamespaceDecl *NS);
/// \brief Builds a nested name specifier that names a namespace alias.
static NestedNameSpecifier *Create(const ASTContext &Context,
diff --git a/include/clang/AST/OperationKinds.h b/include/clang/AST/OperationKinds.h
index 18169fd60c83..5e41d955cfd7 100644
--- a/include/clang/AST/OperationKinds.h
+++ b/include/clang/AST/OperationKinds.h
@@ -292,7 +292,10 @@ enum CastKind {
// Convert a builtin function to a function pointer; only allowed in the
// callee of a call expression.
- CK_BuiltinFnToFnPtr
+ CK_BuiltinFnToFnPtr,
+
+ // Convert a zero value for OpenCL event_t initialization.
+ CK_ZeroToOCLEvent
};
static const CastKind CK_Invalid = static_cast<CastKind>(-1);
diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h
index 7babc1b24a13..e3c09e7b418f 100644
--- a/include/clang/AST/PrettyPrinter.h
+++ b/include/clang/AST/PrettyPrinter.h
@@ -14,14 +14,15 @@
#ifndef LLVM_CLANG_AST_PRETTY_PRINTER_H
#define LLVM_CLANG_AST_PRETTY_PRINTER_H
-#include "clang/Basic/LangOptions.h"
#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
namespace clang {
+class LangOptions;
+class SourceManager;
class Stmt;
class TagDecl;
-class LangOptions;
class PrinterHelper {
public:
@@ -39,8 +40,7 @@ struct PrintingPolicy {
SuppressUnwrittenScope(false), SuppressInitializers(false),
ConstantArraySizeAsWritten(false), AnonymousTagLocations(true),
SuppressStrongLifetime(false), Bool(LO.Bool),
- TerseOutput(false), SuppressAttributes(false),
- DumpSourceManager(0) { }
+ TerseOutput(false), PolishForDeclaration(false) { }
/// \brief What language we're printing.
LangOptions LangOpts;
@@ -142,15 +142,10 @@ struct PrintingPolicy {
/// only the requested declaration.
unsigned TerseOutput : 1;
- /// \brief When true, do not print attributes attached to the declaration.
+ /// \brief When true, do certain refinement needed for producing proper
+ /// declaration tag; such as, 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
- /// involves printing something similar to source code.
- SourceManager *DumpSourceManager;
+ unsigned PolishForDeclaration : 1;
};
} // end namespace clang
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index f96e06797855..0191964bbfe7 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -18,6 +18,7 @@
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclFriend.h"
#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclOpenMP.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
@@ -464,20 +465,15 @@ template<typename Derived>
bool RecursiveASTVisitor<Derived>::dataTraverseNode(Stmt *S,
bool &EnqueueChildren) {
-// The cast for DISPATCH_WALK is needed for older versions of g++, but causes
-// problems for MSVC. So we'll skip the cast entirely for MSVC.
-#if defined(_MSC_VER)
- #define GCC_CAST(CLASS)
-#else
- #define GCC_CAST(CLASS) (bool (RecursiveASTVisitor::*)(CLASS*))
-#endif
-
// Dispatch to the corresponding WalkUpFrom* function only if the derived
// class didn't override Traverse* (and thus the traversal is trivial).
#define DISPATCH_WALK(NAME, CLASS, VAR) \
- if (&RecursiveASTVisitor::Traverse##NAME == \
- GCC_CAST(CLASS)&Derived::Traverse##NAME) \
- return getDerived().WalkUpFrom##NAME(static_cast<CLASS*>(VAR)); \
+ { \
+ bool (Derived::*DerivedFn)(CLASS*) = &Derived::Traverse##NAME; \
+ bool (Derived::*BaseFn)(CLASS*) = &RecursiveASTVisitor::Traverse##NAME; \
+ if (DerivedFn == BaseFn) \
+ return getDerived().WalkUpFrom##NAME(static_cast<CLASS*>(VAR)); \
+ } \
EnqueueChildren = false; \
return getDerived().Traverse##NAME(static_cast<CLASS*>(VAR));
@@ -516,7 +512,6 @@ bool RecursiveASTVisitor<Derived>::dataTraverseNode(Stmt *S,
}
#undef DISPATCH_WALK
-#undef GCC_CAST
return true;
}
@@ -600,7 +595,7 @@ bool RecursiveASTVisitor<Derived>::TraverseTypeLoc(TypeLoc TL) {
#define ABSTRACT_TYPELOC(CLASS, BASE)
#define TYPELOC(CLASS, BASE) \
case TypeLoc::CLASS: \
- return getDerived().Traverse##CLASS##TypeLoc(*cast<CLASS##TypeLoc>(&TL));
+ return getDerived().Traverse##CLASS##TypeLoc(TL.castAs<CLASS##TypeLoc>());
#include "clang/AST/TypeLocNodes.def"
}
@@ -1263,6 +1258,8 @@ DEF_TRAVERSE_DECL(BlockDecl, {
return true;
})
+DEF_TRAVERSE_DECL(EmptyDecl, { })
+
DEF_TRAVERSE_DECL(FileScopeAsmDecl, {
TRY_TO(TraverseStmt(D->getAsmString()));
})
@@ -1393,6 +1390,14 @@ DEF_TRAVERSE_DECL(UsingDirectiveDecl, {
DEF_TRAVERSE_DECL(UsingShadowDecl, { })
+DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, {
+ for (OMPThreadPrivateDecl::varlist_iterator I = D->varlist_begin(),
+ E = D->varlist_end();
+ I != E; ++I) {
+ TRY_TO(TraverseStmt(*I));
+ }
+ })
+
// A helper method for TemplateDecl's children.
template<typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper(
@@ -1716,7 +1721,7 @@ bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
// FunctionNoProtoType or FunctionProtoType, or a typedef. This
// also covers the return type and the function parameters,
// including exception specifications.
- if (clang::TypeSourceInfo *TSI = D->getTypeSourceInfo()) {
+ if (TypeSourceInfo *TSI = D->getTypeSourceInfo()) {
TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
}
@@ -2106,8 +2111,7 @@ bool RecursiveASTVisitor<Derived>::TraverseLambdaExpr(LambdaExpr *S) {
if (S->hasExplicitParameters() && S->hasExplicitResultType()) {
// Visit the whole type.
TRY_TO(TraverseTypeLoc(TL));
- } else if (isa<FunctionProtoTypeLoc>(TL)) {
- FunctionProtoTypeLoc Proto = cast<FunctionProtoTypeLoc>(TL);
+ } else if (FunctionProtoTypeLoc Proto = TL.getAs<FunctionProtoTypeLoc>()) {
if (S->hasExplicitParameters()) {
// Visit parameters.
for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I) {
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index a9bbb48f0368..cf8fc249c590 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -14,16 +14,14 @@
#ifndef LLVM_CLANG_AST_STMT_H
#define LLVM_CLANG_AST_STMT_H
+#include "clang/AST/DeclGroup.h"
+#include "clang/AST/StmtIterator.h"
+#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
-#include "clang/AST/PrettyPrinter.h"
-#include "clang/AST/StmtIterator.h"
-#include "clang/AST/DeclGroup.h"
-#include "clang/AST/Attr.h"
-#include "clang/Lex/Token.h"
-#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/Compiler.h"
-#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/ErrorHandling.h"
#include <string>
namespace llvm {
@@ -32,15 +30,19 @@ namespace llvm {
namespace clang {
class ASTContext;
- class Expr;
+ class Attr;
class Decl;
- class ParmVarDecl;
- class QualType;
+ class Expr;
class IdentifierInfo;
class LabelDecl;
+ class ParmVarDecl;
+ class PrinterHelper;
+ struct PrintingPolicy;
+ class QualType;
class SourceManager;
class StringLiteral;
class SwitchStmt;
+ class Token;
class VarDecl;
//===--------------------------------------------------------------------===//
@@ -172,11 +174,20 @@ protected:
unsigned Kind : 2;
};
+ enum APFloatSemantics {
+ IEEEhalf,
+ IEEEsingle,
+ IEEEdouble,
+ x87DoubleExtended,
+ IEEEquad,
+ PPCDoubleDouble
+ };
+
class FloatingLiteralBitfields {
friend class FloatingLiteral;
unsigned : NumExprBits;
- unsigned IsIEEE : 1; // Distinguishes between PPC128 and IEEE128.
+ unsigned Semantics : 3; // Provides semantics for APFloat construction
unsigned IsExact : 1;
};
@@ -302,14 +313,10 @@ public:
// Only allow allocation of Stmts using the allocator in ASTContext
// or by doing a placement new.
void* operator new(size_t bytes, ASTContext& C,
- unsigned alignment = 8) throw() {
- return ::operator new(bytes, C, alignment);
- }
+ unsigned alignment = 8) throw();
void* operator new(size_t bytes, ASTContext* C,
- unsigned alignment = 8) throw() {
- return ::operator new(bytes, *C, alignment);
- }
+ unsigned alignment = 8) throw();
void* operator new(size_t bytes, void* mem) throw() {
return mem;
@@ -360,16 +367,14 @@ public:
static void EnableStatistics();
static void PrintStats();
- /// dump - This does a local dump of the specified AST fragment. It dumps the
- /// specified node and a few nodes underneath it, but not the whole subtree.
- /// This is useful in a debugger.
+ /// \brief Dumps the specified AST fragment and all subtrees to
+ /// \c llvm::errs().
LLVM_ATTRIBUTE_USED void dump() const;
LLVM_ATTRIBUTE_USED void dump(SourceManager &SM) const;
void dump(raw_ostream &OS, SourceManager &SM) const;
- /// dumpAll - This does a dump of the specified AST fragment and all subtrees.
- void dumpAll() const;
- void dumpAll(SourceManager &SM) const;
+ /// dumpColor - same as dump(), but forces color highlighting.
+ LLVM_ATTRIBUTE_USED void dumpColor() const;
/// dumpPretty/printPretty - These two methods do a "pretty print" of the AST
/// back to its original source language syntax.
@@ -470,9 +475,8 @@ public:
SourceLocation getEndLoc() const { return EndLoc; }
void setEndLoc(SourceLocation L) { EndLoc = L; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(StartLoc, EndLoc);
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return StartLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return EndLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == DeclStmtClass;
@@ -526,7 +530,8 @@ public:
bool hasLeadingEmptyMacro() const { return HasLeadingEmptyMacro; }
- SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(SemiLoc); }
+ SourceLocation getLocStart() const LLVM_READONLY { return SemiLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return SemiLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == NullStmtClass;
@@ -544,7 +549,7 @@ class CompoundStmt : public Stmt {
Stmt** Body;
SourceLocation LBracLoc, RBracLoc;
public:
- CompoundStmt(ASTContext &C, Stmt **StmtStart, unsigned NumStmts,
+ CompoundStmt(ASTContext &C, ArrayRef<Stmt*> Stmts,
SourceLocation LB, SourceLocation RB);
// \brief Build an empty compound statment with a location.
@@ -598,9 +603,8 @@ public:
return const_reverse_body_iterator(body_begin());
}
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(LBracLoc, RBracLoc);
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return LBracLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return RBracLoc; }
SourceLocation getLBracLoc() const { return LBracLoc; }
void setLBracLoc(SourceLocation L) { LBracLoc = L; }
@@ -627,8 +631,14 @@ protected:
// A pointer to the following CaseStmt or DefaultStmt class,
// used by SwitchStmt.
SwitchCase *NextSwitchCase;
+ SourceLocation KeywordLoc;
+ SourceLocation ColonLoc;
- SwitchCase(StmtClass SC) : Stmt(SC), NextSwitchCase(0) {}
+ SwitchCase(StmtClass SC, SourceLocation KWLoc, SourceLocation ColonLoc)
+ : Stmt(SC), NextSwitchCase(0), KeywordLoc(KWLoc), ColonLoc(ColonLoc) {}
+
+ SwitchCase(StmtClass SC, EmptyShell)
+ : Stmt(SC), NextSwitchCase(0) {}
public:
const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; }
@@ -637,12 +647,18 @@ public:
void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; }
+ SourceLocation getKeywordLoc() const { return KeywordLoc; }
+ void setKeywordLoc(SourceLocation L) { KeywordLoc = L; }
+ SourceLocation getColonLoc() const { return ColonLoc; }
+ void setColonLoc(SourceLocation L) { ColonLoc = L; }
+
Stmt *getSubStmt();
const Stmt *getSubStmt() const {
return const_cast<SwitchCase*>(this)->getSubStmt();
}
- SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(); }
+ SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY;
static bool classof(const Stmt *T) {
return T->getStmtClass() == CaseStmtClass ||
@@ -654,26 +670,22 @@ class CaseStmt : public SwitchCase {
enum { LHS, RHS, SUBSTMT, END_EXPR };
Stmt* SubExprs[END_EXPR]; // The expression for the RHS is Non-null for
// GNU "case 1 ... 4" extension
- SourceLocation CaseLoc;
SourceLocation EllipsisLoc;
- SourceLocation ColonLoc;
public:
CaseStmt(Expr *lhs, Expr *rhs, SourceLocation caseLoc,
SourceLocation ellipsisLoc, SourceLocation colonLoc)
- : SwitchCase(CaseStmtClass) {
+ : SwitchCase(CaseStmtClass, caseLoc, colonLoc) {
SubExprs[SUBSTMT] = 0;
SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs);
SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs);
- CaseLoc = caseLoc;
EllipsisLoc = ellipsisLoc;
- ColonLoc = colonLoc;
}
/// \brief Build an empty switch case statement.
- explicit CaseStmt(EmptyShell Empty) : SwitchCase(CaseStmtClass) { }
+ explicit CaseStmt(EmptyShell Empty) : SwitchCase(CaseStmtClass, Empty) { }
- SourceLocation getCaseLoc() const { return CaseLoc; }
- void setCaseLoc(SourceLocation L) { CaseLoc = L; }
+ SourceLocation getCaseLoc() const { return KeywordLoc; }
+ void setCaseLoc(SourceLocation L) { KeywordLoc = L; }
SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
void setEllipsisLoc(SourceLocation L) { EllipsisLoc = L; }
SourceLocation getColonLoc() const { return ColonLoc; }
@@ -695,15 +707,16 @@ public:
void setLHS(Expr *Val) { SubExprs[LHS] = reinterpret_cast<Stmt*>(Val); }
void setRHS(Expr *Val) { SubExprs[RHS] = reinterpret_cast<Stmt*>(Val); }
-
- SourceRange getSourceRange() const LLVM_READONLY {
+ SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY {
// Handle deeply nested case statements with iteration instead of recursion.
const CaseStmt *CS = this;
while (const CaseStmt *CS2 = dyn_cast<CaseStmt>(CS->getSubStmt()))
CS = CS2;
- return SourceRange(CaseLoc, CS->getSubStmt()->getLocEnd());
+ return CS->getSubStmt()->getLocEnd();
}
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == CaseStmtClass;
}
@@ -716,28 +729,26 @@ public:
class DefaultStmt : public SwitchCase {
Stmt* SubStmt;
- SourceLocation DefaultLoc;
- SourceLocation ColonLoc;
public:
DefaultStmt(SourceLocation DL, SourceLocation CL, Stmt *substmt) :
- SwitchCase(DefaultStmtClass), SubStmt(substmt), DefaultLoc(DL),
- ColonLoc(CL) {}
+ SwitchCase(DefaultStmtClass, DL, CL), SubStmt(substmt) {}
/// \brief Build an empty default statement.
- explicit DefaultStmt(EmptyShell) : SwitchCase(DefaultStmtClass) { }
+ explicit DefaultStmt(EmptyShell Empty)
+ : SwitchCase(DefaultStmtClass, Empty) { }
Stmt *getSubStmt() { return SubStmt; }
const Stmt *getSubStmt() const { return SubStmt; }
void setSubStmt(Stmt *S) { SubStmt = S; }
- SourceLocation getDefaultLoc() const { return DefaultLoc; }
- void setDefaultLoc(SourceLocation L) { DefaultLoc = L; }
+ SourceLocation getDefaultLoc() const { return KeywordLoc; }
+ void setDefaultLoc(SourceLocation L) { KeywordLoc = L; }
SourceLocation getColonLoc() const { return ColonLoc; }
void setColonLoc(SourceLocation L) { ColonLoc = L; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(DefaultLoc, SubStmt->getLocEnd());
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();}
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == DefaultStmtClass;
}
@@ -746,6 +757,11 @@ public:
child_range children() { return child_range(&SubStmt, &SubStmt+1); }
};
+inline SourceLocation SwitchCase::getLocEnd() const {
+ if (const CaseStmt *CS = dyn_cast<CaseStmt>(this))
+ return CS->getLocEnd();
+ return cast<DefaultStmt>(this)->getLocEnd();
+}
/// LabelStmt - Represents a label, which has a substatement. For example:
/// foo: return;
@@ -771,9 +787,9 @@ public:
void setIdentLoc(SourceLocation L) { IdentLoc = L; }
void setSubStmt(Stmt *SS) { SubStmt = SS; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(IdentLoc, SubStmt->getLocEnd());
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return IdentLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();}
+
child_range children() { return child_range(&SubStmt, &SubStmt+1); }
static bool classof(const Stmt *T) {
@@ -819,9 +835,9 @@ public:
Stmt *getSubStmt() { return SubStmt; }
const Stmt *getSubStmt() const { return SubStmt; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(AttrLoc, SubStmt->getLocEnd());
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return AttrLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();}
+
child_range children() { return child_range(&SubStmt, &SubStmt + 1); }
static bool classof(const Stmt *T) {
@@ -879,11 +895,12 @@ public:
SourceLocation getElseLoc() const { return ElseLoc; }
void setElseLoc(SourceLocation L) { ElseLoc = L; }
- SourceRange getSourceRange() const LLVM_READONLY {
+ SourceLocation getLocStart() const LLVM_READONLY { return IfLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY {
if (SubExprs[ELSE])
- return SourceRange(IfLoc, SubExprs[ELSE]->getLocEnd());
+ return SubExprs[ELSE]->getLocEnd();
else
- return SourceRange(IfLoc, SubExprs[THEN]->getLocEnd());
+ return SubExprs[THEN]->getLocEnd();
}
// Iterators over subexpressions. The iterators will include iterating
@@ -977,9 +994,11 @@ public:
return (bool) AllEnumCasesCovered;
}
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(SwitchLoc, SubExprs[BODY]->getLocEnd());
+ SourceLocation getLocStart() const LLVM_READONLY { return SwitchLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY {
+ return SubExprs[BODY]->getLocEnd();
}
+
// Iterators
child_range children() {
return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
@@ -1031,9 +1050,11 @@ public:
SourceLocation getWhileLoc() const { return WhileLoc; }
void setWhileLoc(SourceLocation L) { WhileLoc = L; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(WhileLoc, SubExprs[BODY]->getLocEnd());
+ SourceLocation getLocStart() const LLVM_READONLY { return WhileLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY {
+ return SubExprs[BODY]->getLocEnd();
}
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == WhileStmtClass;
}
@@ -1079,9 +1100,9 @@ public:
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(DoLoc, RParenLoc);
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return DoLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == DoStmtClass;
}
@@ -1150,9 +1171,11 @@ public:
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd());
+ SourceLocation getLocStart() const LLVM_READONLY { return ForLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY {
+ return SubExprs[BODY]->getLocEnd();
}
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == ForStmtClass;
}
@@ -1184,9 +1207,9 @@ public:
SourceLocation getLabelLoc() const { return LabelLoc; }
void setLabelLoc(SourceLocation L) { LabelLoc = L; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(GotoLoc, LabelLoc);
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return GotoLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return LabelLoc; }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == GotoStmtClass;
}
@@ -1227,9 +1250,8 @@ public:
return const_cast<IndirectGotoStmt*>(this)->getConstantTarget();
}
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(GotoLoc, Target->getLocEnd());
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return GotoLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return Target->getLocEnd(); }
static bool classof(const Stmt *T) {
return T->getStmtClass() == IndirectGotoStmtClass;
@@ -1253,9 +1275,8 @@ public:
SourceLocation getContinueLoc() const { return ContinueLoc; }
void setContinueLoc(SourceLocation L) { ContinueLoc = L; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(ContinueLoc);
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return ContinueLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return ContinueLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == ContinueStmtClass;
@@ -1278,7 +1299,8 @@ public:
SourceLocation getBreakLoc() const { return BreakLoc; }
void setBreakLoc(SourceLocation L) { BreakLoc = L; }
- SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(BreakLoc); }
+ SourceLocation getLocStart() const LLVM_READONLY { return BreakLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return BreakLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == BreakStmtClass;
@@ -1329,7 +1351,10 @@ public:
const VarDecl *getNRVOCandidate() const { return NRVOCandidate; }
void setNRVOCandidate(const VarDecl *Var) { NRVOCandidate = Var; }
- SourceRange getSourceRange() const LLVM_READONLY;
+ SourceLocation getLocStart() const LLVM_READONLY { return RetLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY {
+ return RetExpr ? RetExpr->getLocEnd() : RetLoc;
+ }
static bool classof(const Stmt *T) {
return T->getStmtClass() == ReturnStmtClass;
@@ -1381,7 +1406,8 @@ public:
bool isVolatile() const { return IsVolatile; }
void setVolatile(bool V) { IsVolatile = V; }
- SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(); }
+ SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
+ SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }
//===--- Asm String Analysis ---===//
@@ -1636,9 +1662,8 @@ public:
return Clobbers[i];
}
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(AsmLoc, RParenLoc);
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return AsmLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == GCCAsmStmtClass;
@@ -1648,7 +1673,7 @@ public:
/// This represents a Microsoft inline-assembly statement extension.
///
class MSAsmStmt : public AsmStmt {
- SourceLocation AsmLoc, LBraceLoc, EndLoc;
+ SourceLocation LBraceLoc, EndLoc;
std::string AsmStr;
unsigned NumAsmToks;
@@ -1717,9 +1742,9 @@ public:
StringRef getClobber(unsigned i) const { return Clobbers[i]; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(AsmLoc, EndLoc);
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return AsmLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return EndLoc; }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == MSAsmStmtClass;
}
@@ -1748,9 +1773,9 @@ public:
SourceLocation ExceptLoc,
Expr *FilterExpr,
Stmt *Block);
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(getExceptLoc(), getEndLoc());
- }
+
+ SourceLocation getLocStart() const LLVM_READONLY { return getExceptLoc(); }
+ SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
SourceLocation getExceptLoc() const { return Loc; }
SourceLocation getEndLoc() const { return getBlock()->getLocEnd(); }
@@ -1760,7 +1785,7 @@ public:
}
CompoundStmt *getBlock() const {
- return llvm::cast<CompoundStmt>(Children[BLOCK]);
+ return cast<CompoundStmt>(Children[BLOCK]);
}
child_range children() {
@@ -1789,14 +1814,13 @@ public:
SourceLocation FinallyLoc,
Stmt *Block);
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(getFinallyLoc(), getEndLoc());
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return getFinallyLoc(); }
+ SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
SourceLocation getFinallyLoc() const { return Loc; }
SourceLocation getEndLoc() const { return Block->getLocEnd(); }
- CompoundStmt *getBlock() const { return llvm::cast<CompoundStmt>(Block); }
+ CompoundStmt *getBlock() const { return cast<CompoundStmt>(Block); }
child_range children() {
return child_range(&Block,&Block+1);
@@ -1831,9 +1855,8 @@ public:
Stmt *TryBlock,
Stmt *Handler);
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(getTryLoc(), getEndLoc());
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return getTryLoc(); }
+ SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
SourceLocation getTryLoc() const { return TryLoc; }
SourceLocation getEndLoc() const { return Children[HANDLER]->getLocEnd(); }
@@ -1841,7 +1864,7 @@ public:
bool getIsCXXTry() const { return IsCXXTry; }
CompoundStmt* getTryBlock() const {
- return llvm::cast<CompoundStmt>(Children[TRY]);
+ return cast<CompoundStmt>(Children[TRY]);
}
Stmt *getHandler() const { return Children[HANDLER]; }
diff --git a/include/clang/AST/StmtCXX.h b/include/clang/AST/StmtCXX.h
index f4e4dcdd4a5e..0112befb293f 100644
--- a/include/clang/AST/StmtCXX.h
+++ b/include/clang/AST/StmtCXX.h
@@ -14,6 +14,9 @@
#ifndef LLVM_CLANG_AST_STMTCXX_H
#define LLVM_CLANG_AST_STMTCXX_H
+#include "clang/AST/DeclarationName.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/Stmt.h"
#include "llvm/Support/Compiler.h"
@@ -38,8 +41,9 @@ public:
CXXCatchStmt(EmptyShell Empty)
: Stmt(CXXCatchStmtClass), ExceptionDecl(0), HandlerBlock(0) {}
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(CatchLoc, HandlerBlock->getLocEnd());
+ SourceLocation getLocStart() const LLVM_READONLY { return CatchLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY {
+ return HandlerBlock->getLocEnd();
}
SourceLocation getCatchLoc() const { return CatchLoc; }
@@ -62,8 +66,7 @@ class CXXTryStmt : public Stmt {
SourceLocation TryLoc;
unsigned NumHandlers;
- CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock, Stmt **handlers,
- unsigned numHandlers);
+ CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock, ArrayRef<Stmt*> handlers);
CXXTryStmt(EmptyShell Empty, unsigned numHandlers)
: Stmt(CXXTryStmtClass), NumHandlers(numHandlers) { }
@@ -77,15 +80,13 @@ class CXXTryStmt : public Stmt {
public:
static CXXTryStmt *Create(ASTContext &C, SourceLocation tryLoc,
- Stmt *tryBlock, Stmt **handlers,
- unsigned numHandlers);
+ Stmt *tryBlock, ArrayRef<Stmt*> handlers);
static CXXTryStmt *Create(ASTContext &C, EmptyShell Empty,
unsigned numHandlers);
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(getTryLoc(), getEndLoc());
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return getTryLoc(); }
+ SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
SourceLocation getTryLoc() const { return TryLoc; }
SourceLocation getEndLoc() const {
@@ -93,18 +94,18 @@ public:
}
CompoundStmt *getTryBlock() {
- return llvm::cast<CompoundStmt>(getStmts()[0]);
+ return cast<CompoundStmt>(getStmts()[0]);
}
const CompoundStmt *getTryBlock() const {
- return llvm::cast<CompoundStmt>(getStmts()[0]);
+ return cast<CompoundStmt>(getStmts()[0]);
}
unsigned getNumHandlers() const { return NumHandlers; }
CXXCatchStmt *getHandler(unsigned i) {
- return llvm::cast<CXXCatchStmt>(getStmts()[i + 1]);
+ return cast<CXXCatchStmt>(getStmts()[i + 1]);
}
const CXXCatchStmt *getHandler(unsigned i) const {
- return llvm::cast<CXXCatchStmt>(getStmts()[i + 1]);
+ return cast<CXXCatchStmt>(getStmts()[i + 1]);
}
static bool classof(const Stmt *T) {
@@ -188,9 +189,11 @@ public:
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd());
+ SourceLocation getLocStart() const LLVM_READONLY { return ForLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY {
+ return SubExprs[BODY]->getLocEnd();
}
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXForRangeStmtClass;
}
@@ -272,9 +275,8 @@ public:
return reinterpret_cast<CompoundStmt *>(SubStmt);
}
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(KeywordLoc, SubStmt->getLocEnd());
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();}
child_range children() {
return child_range(&SubStmt, &SubStmt+1);
diff --git a/include/clang/AST/StmtGraphTraits.h b/include/clang/AST/StmtGraphTraits.h
index 25d015287b75..a3e9e1e093f6 100644
--- a/include/clang/AST/StmtGraphTraits.h
+++ b/include/clang/AST/StmtGraphTraits.h
@@ -16,8 +16,8 @@
#define LLVM_CLANG_AST_STMT_GRAPHTRAITS_H
#include "clang/AST/Stmt.h"
-#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/DepthFirstIterator.h"
+#include "llvm/ADT/GraphTraits.h"
namespace llvm {
diff --git a/include/clang/AST/StmtObjC.h b/include/clang/AST/StmtObjC.h
index d7a73a70bd54..e97c1a5a319f 100644
--- a/include/clang/AST/StmtObjC.h
+++ b/include/clang/AST/StmtObjC.h
@@ -55,9 +55,11 @@ public:
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd());
+ SourceLocation getLocStart() const LLVM_READONLY { return ForLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY {
+ return SubExprs[BODY]->getLocEnd();
}
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCForCollectionStmtClass;
}
@@ -102,9 +104,8 @@ public:
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(AtCatchLoc, Body->getLocEnd());
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return AtCatchLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return Body->getLocEnd(); }
bool hasEllipsis() const { return getCatchParamDecl() == 0; }
@@ -131,8 +132,9 @@ public:
Stmt *getFinallyBody() { return AtFinallyStmt; }
void setFinallyBody(Stmt *S) { AtFinallyStmt = S; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(AtFinallyLoc, AtFinallyStmt->getLocEnd());
+ SourceLocation getLocStart() const LLVM_READONLY { return AtFinallyLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY {
+ return AtFinallyStmt->getLocEnd();
}
SourceLocation getAtFinallyLoc() const { return AtFinallyLoc; }
@@ -236,7 +238,8 @@ public:
getStmts()[1 + NumCatchStmts] = S;
}
- SourceRange getSourceRange() const LLVM_READONLY;
+ SourceLocation getLocStart() const LLVM_READONLY { return AtTryLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY;
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCAtTryStmtClass;
@@ -292,8 +295,9 @@ public:
}
void setSynchExpr(Stmt *S) { SubStmts[SYNC_EXPR] = S; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(AtSynchronizedLoc, getSynchBody()->getLocEnd());
+ SourceLocation getLocStart() const LLVM_READONLY { return AtSynchronizedLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY {
+ return getSynchBody()->getLocEnd();
}
static bool classof(const Stmt *T) {
@@ -324,11 +328,9 @@ public:
SourceLocation getThrowLoc() { return AtThrowLoc; }
void setThrowLoc(SourceLocation Loc) { AtThrowLoc = Loc; }
- SourceRange getSourceRange() const LLVM_READONLY {
- if (Throw)
- return SourceRange(AtThrowLoc, Throw->getLocEnd());
- else
- return SourceRange(AtThrowLoc);
+ SourceLocation getLocStart() const LLVM_READONLY { return AtThrowLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY {
+ return Throw ? Throw->getLocEnd() : AtThrowLoc;
}
static bool classof(const Stmt *T) {
@@ -355,9 +357,8 @@ public:
Stmt *getSubStmt() { return SubStmt; }
void setSubStmt(Stmt *S) { SubStmt = S; }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(AtLoc, SubStmt->getLocEnd());
- }
+ SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();}
SourceLocation getAtLoc() const { return AtLoc; }
void setAtLoc(SourceLocation Loc) { AtLoc = Loc; }
diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h
index 1c0abde5b761..70b934f36c2c 100644
--- a/include/clang/AST/TemplateBase.h
+++ b/include/clang/AST/TemplateBase.h
@@ -15,8 +15,8 @@
#ifndef LLVM_CLANG_AST_TEMPLATEBASE_H
#define LLVM_CLANG_AST_TEMPLATEBASE_H
-#include "clang/AST/Type.h"
#include "clang/AST/TemplateName.h"
+#include "clang/AST/Type.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Compiler.h"
@@ -72,35 +72,39 @@ private:
/// \brief The kind of template argument we're storing.
unsigned Kind;
+ struct DA {
+ ValueDecl *D;
+ bool ForRefParam;
+ };
+ struct I {
+ // We store a decomposed APSInt with the data allocated by ASTContext if
+ // BitWidth > 64. The memory may be shared between multiple
+ // TemplateArgument instances.
+ union {
+ uint64_t VAL; ///< Used to store the <= 64 bits integer value.
+ const uint64_t *pVal; ///< Used to store the >64 bits integer value.
+ };
+ unsigned BitWidth : 31;
+ unsigned IsUnsigned : 1;
+ void *Type;
+ };
+ struct A {
+ const TemplateArgument *Args;
+ unsigned NumArgs;
+ };
+ struct TA {
+ void *Name;
+ unsigned NumExpansions;
+ };
union {
+ struct DA DeclArg;
+ struct I Integer;
+ struct A Args;
+ struct TA TemplateArg;
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.
- union {
- uint64_t VAL; ///< Used to store the <= 64 bits integer value.
- const uint64_t *pVal; ///< Used to store the >64 bits integer value.
- };
- unsigned BitWidth : 31;
- unsigned IsUnsigned : 1;
- void *Type;
- } Integer;
- struct {
- const TemplateArgument *Args;
- unsigned NumArgs;
- } Args;
- struct {
- void *Name;
- unsigned NumExpansions;
- } TemplateArg;
};
- TemplateArgument(TemplateName, bool); // DO NOT USE
+ TemplateArgument(TemplateName, bool) LLVM_DELETED_FUNCTION;
public:
/// \brief Construct an empty, invalid template argument.
@@ -158,7 +162,7 @@ public:
///
/// \param NumExpansions The number of expansions that will be generated by
/// instantiating
- TemplateArgument(TemplateName Name, llvm::Optional<unsigned> NumExpansions)
+ TemplateArgument(TemplateName Name, Optional<unsigned> NumExpansions)
: Kind(TemplateExpansion)
{
TemplateArg.Name = Name.getAsVoidPointer();
@@ -261,7 +265,7 @@ public:
/// \brief Retrieve the number of expansions that a template template argument
/// expansion will produce, if known.
- llvm::Optional<unsigned> getNumTemplateExpansions() const;
+ Optional<unsigned> getNumTemplateExpansions() const;
/// \brief Retrieve the template argument as an integral value.
// FIXME: Provide a way to read the integral data without copying the value.
@@ -317,6 +321,12 @@ public:
return Args.NumArgs;
}
+ /// \brief Return the array of arguments in this template argument pack.
+ llvm::ArrayRef<TemplateArgument> getPackAsArray() const {
+ assert(Kind == Pack);
+ return llvm::ArrayRef<TemplateArgument>(Args.Args, Args.NumArgs);
+ }
+
/// \brief Determines whether two template arguments are superficially the
/// same.
bool structurallyEquals(const TemplateArgument &Other) const;
@@ -335,17 +345,20 @@ public:
/// Location information for a TemplateArgument.
struct TemplateArgumentLocInfo {
private:
+
+ struct T {
+ // FIXME: We'd like to just use the qualifier in the TemplateName,
+ // but template arguments get canonicalized too quickly.
+ NestedNameSpecifier *Qualifier;
+ void *QualifierLocData;
+ unsigned TemplateNameLoc;
+ unsigned EllipsisLoc;
+ };
+
union {
+ struct T Template;
Expr *Expression;
TypeSourceInfo *Declarator;
- struct {
- // FIXME: We'd like to just use the qualifier in the TemplateName,
- // but template arguments get canonicalized too quickly.
- NestedNameSpecifier *Qualifier;
- void *QualifierLocData;
- unsigned TemplateNameLoc;
- unsigned EllipsisLoc;
- } Template;
};
public:
@@ -490,7 +503,7 @@ public:
/// \param NumExpansions Will be set to the number of expansions that will
/// be generated from this pack expansion, if known a priori.
TemplateArgumentLoc getPackExpansionPattern(SourceLocation &Ellipsis,
- llvm::Optional<unsigned> &NumExpansions,
+ Optional<unsigned> &NumExpansions,
ASTContext &Context) const;
};
diff --git a/include/clang/AST/TemplateName.h b/include/clang/AST/TemplateName.h
index 7dc75b19257c..0b9d4c85473c 100644
--- a/include/clang/AST/TemplateName.h
+++ b/include/clang/AST/TemplateName.h
@@ -15,9 +15,9 @@
#define LLVM_CLANG_AST_TEMPLATENAME_H
#include "clang/Basic/LLVM.h"
+#include "clang/Basic/OperatorKinds.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/PointerUnion.h"
-#include "clang/Basic/OperatorKinds.h"
namespace clang {
@@ -46,16 +46,17 @@ protected:
SubstTemplateTemplateParmPack
};
- union {
- struct {
- /// \brief A Kind.
- unsigned Kind : 2;
-
- /// \brief The number of stored templates or template arguments,
- /// depending on which subclass we have.
- unsigned Size : 30;
- } Bits;
+ struct BitsTag {
+ /// \brief A Kind.
+ unsigned Kind : 2;
+ /// \brief The number of stored templates or template arguments,
+ /// depending on which subclass we have.
+ unsigned Size : 30;
+ };
+
+ union {
+ struct BitsTag Bits;
void *PointerAlignment;
};
@@ -308,6 +309,9 @@ public:
void print(raw_ostream &OS, const PrintingPolicy &Policy,
bool SuppressNNS = false) const;
+ /// \brief Debugging aid that dumps the template name.
+ void dump(raw_ostream &OS) const;
+
/// \brief Debugging aid that dumps the template name to standard
/// error.
void dump() const;
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index 6900a7d40af9..23fa3e876566 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -14,24 +14,24 @@
#ifndef LLVM_CLANG_AST_TYPE_H
#define LLVM_CLANG_AST_TYPE_H
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/TemplateName.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/ExceptionSpecificationType.h"
#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LLVM.h"
#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"
-#include "llvm/Support/ErrorHandling.h"
+#include "clang/Basic/Visibility.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/Twine.h"
-#include "clang/Basic/LLVM.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/type_traits.h"
namespace clang {
enum {
@@ -784,8 +784,8 @@ public:
/// Executing \c getUnqualifiedType() on the type \c DifferenceType will
/// desugar until we hit the type \c Integer, which has no qualifiers on it.
///
- /// The resulting type might still be qualified if it's an array
- /// type. To strip qualifiers even from within an array type, use
+ /// The resulting type might still be qualified if it's sugar for an array
+ /// type. To strip qualifiers even from within a sugared array type, use
/// ASTContext::getUnqualifiedArrayType.
inline QualType getUnqualifiedType() const;
@@ -795,8 +795,8 @@ public:
/// Like getUnqualifiedType(), but also returns the set of
/// qualifiers that were built up.
///
- /// The resulting type might still be qualified if it's an array
- /// type. To strip qualifiers even from within an array type, use
+ /// The resulting type might still be qualified if it's sugar for an array
+ /// type. To strip qualifiers even from within a sugared array type, use
/// ASTContext::getUnqualifiedArrayType.
inline SplitQualType getSplitUnqualifiedType() const;
@@ -979,10 +979,6 @@ public:
/// type other than void.
bool isCForbiddenLValueType() const;
- /// \brief Determine whether this type has trivial copy/move-assignment
- /// semantics.
- bool hasTrivialAssignment(ASTContext &Context, bool Copying) const;
-
private:
// These methods are implemented in a separate translation unit;
// "static"-ize them to avoid creating temporary QualTypes in the
@@ -1002,14 +998,12 @@ private:
namespace llvm {
/// Implement simplify_type for QualType, so that we can dyn_cast from QualType
/// to a specific Type class.
-template<> struct simplify_type<const ::clang::QualType> {
+template<> struct simplify_type< ::clang::QualType> {
typedef const ::clang::Type *SimpleType;
- static SimpleType getSimplifiedValue(const ::clang::QualType &Val) {
+ static SimpleType getSimplifiedValue(::clang::QualType Val) {
return Val.getTypePtr();
}
};
-template<> struct simplify_type< ::clang::QualType>
- : public simplify_type<const ::clang::QualType> {};
// Teach SmallPtrSet that QualType is "basically a pointer".
template<>
@@ -1195,13 +1189,9 @@ private:
/// (for C++0x variadic templates).
unsigned ContainsUnexpandedParameterPack : 1;
- /// \brief Nonzero if the cache (i.e. the bitfields here starting
- /// with 'Cache') is valid. If so, then this is a
- /// LangOptions::VisibilityMode+1.
- mutable unsigned CacheValidAndVisibility : 2;
-
- /// \brief True if the visibility was set explicitly in the source code.
- mutable unsigned CachedExplicitVisibility : 1;
+ /// \brief True if the cache (i.e. the bitfields here starting with
+ /// 'Cache') is valid.
+ mutable unsigned CacheValid : 1;
/// \brief Linkage of this type.
mutable unsigned CachedLinkage : 2;
@@ -1213,15 +1203,7 @@ private:
mutable unsigned FromAST : 1;
bool isCacheValid() const {
- return (CacheValidAndVisibility != 0);
- }
- Visibility getVisibility() const {
- assert(isCacheValid() && "getting linkage from invalid cache");
- return static_cast<Visibility>(CacheValidAndVisibility-1);
- }
- bool isVisibilityExplicit() const {
- assert(isCacheValid() && "getting linkage from invalid cache");
- return CachedExplicitVisibility;
+ return CacheValid;
}
Linkage getLinkage() const {
assert(isCacheValid() && "getting linkage from invalid cache");
@@ -1278,11 +1260,6 @@ protected:
/// C++ 8.3.5p4: The return type, the parameter type list and the
/// cv-qualifier-seq, [...], are part of the function type.
unsigned TypeQuals : 3;
-
- /// \brief The ref-qualifier associated with a \c FunctionProtoType.
- ///
- /// This is a value of type \c RefQualifierKind.
- unsigned RefQualifier : 2;
};
class ObjCObjectTypeBitfields {
@@ -1382,8 +1359,7 @@ protected:
TypeBits.InstantiationDependent = Dependent || InstantiationDependent;
TypeBits.VariablyModified = VariablyModified;
TypeBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack;
- TypeBits.CacheValidAndVisibility = 0;
- TypeBits.CachedExplicitVisibility = false;
+ TypeBits.CacheValid = false;
TypeBits.CachedLocalOrUnnamed = false;
TypeBits.CachedLinkage = NoLinkage;
TypeBits.FromAST = false;
@@ -1584,6 +1560,20 @@ public:
bool isNullPtrType() const; // C++0x nullptr_t
bool isAtomicType() const; // C11 _Atomic()
+ bool isImage1dT() const; // OpenCL image1d_t
+ bool isImage1dArrayT() const; // OpenCL image1d_array_t
+ bool isImage1dBufferT() const; // OpenCL image1d_buffer_t
+ bool isImage2dT() const; // OpenCL image2d_t
+ bool isImage2dArrayT() const; // OpenCL image2d_array_t
+ bool isImage3dT() const; // OpenCL image3d_t
+
+ bool isImageType() const; // Any OpenCL image type
+
+ bool isSamplerT() const; // OpenCL sampler_t
+ bool isEventT() const; // OpenCL event_t
+
+ bool isOpenCLSpecificType() const; // Any OpenCL specific type
+
/// Determines if this type, which must satisfy
/// isObjCLifetimeType(), is implicitly __unsafe_unretained rather
/// than implicitly __strong.
@@ -1770,16 +1760,21 @@ public:
Linkage getLinkage() const;
/// \brief Determine the visibility of this type.
- Visibility getVisibility() const;
+ Visibility getVisibility() const {
+ return getLinkageAndVisibility().getVisibility();
+ }
/// \brief Return true if the visibility was explicitly set is the code.
- bool isVisibilityExplicit() const;
+ bool isVisibilityExplicit() const {
+ return getLinkageAndVisibility().isVisibilityExplicit();
+ }
/// \brief Determine the linkage and visibility of this type.
- std::pair<Linkage,Visibility> getLinkageAndVisibility() const;
+ LinkageInfo getLinkageAndVisibility() const;
- /// \brief Note that the linkage is no longer known.
- void ClearLinkageCache();
+ /// \brief True if the computed linkage is valid. Used for consistency
+ /// checking. Should always return true.
+ bool isLinkageValid() const;
const char *getTypeClassName() const;
@@ -2097,6 +2092,14 @@ public:
}
};
+/// The inheritance model to use for this member pointer.
+enum MSInheritanceModel {
+ MSIM_Single,
+ MSIM_Multiple,
+ MSIM_Virtual,
+ MSIM_Unspecified
+};
+
/// MemberPointerType - C++ 8.3.3 - Pointers to members
///
class MemberPointerType : public Type, public llvm::FoldingSetNode {
@@ -2132,6 +2135,10 @@ public:
return !PointeeType->isFunctionProtoType();
}
+ /// Returns the number of pointer and integer slots used to represent this
+ /// member pointer in the MS C++ ABI.
+ std::pair<unsigned, unsigned> getMSMemberPointerSlots() const;
+
const Type *getClass() const { return Class; }
bool isSugared() const { return false; }
@@ -2686,8 +2693,7 @@ class FunctionType : public Type {
protected:
FunctionType(TypeClass tc, QualType res,
- unsigned typeQuals, RefQualifierKind RefQualifier,
- QualType Canonical, bool Dependent,
+ unsigned typeQuals, QualType Canonical, bool Dependent,
bool InstantiationDependent,
bool VariablyModified, bool ContainsUnexpandedParameterPack,
ExtInfo Info)
@@ -2696,20 +2702,18 @@ protected:
ResultType(res) {
FunctionTypeBits.ExtInfo = Info.Bits;
FunctionTypeBits.TypeQuals = typeQuals;
- FunctionTypeBits.RefQualifier = static_cast<unsigned>(RefQualifier);
}
unsigned getTypeQuals() const { return FunctionTypeBits.TypeQuals; }
- RefQualifierKind getRefQualifier() const {
- return static_cast<RefQualifierKind>(FunctionTypeBits.RefQualifier);
- }
-
public:
QualType getResultType() const { return ResultType; }
bool getHasRegParm() const { return getExtInfo().getHasRegParm(); }
unsigned getRegParmType() const { return getExtInfo().getRegParm(); }
+ /// \brief Determine whether this function type includes the GNU noreturn
+ /// attribute. The C++11 [[noreturn]] attribute does not affect the function
+ /// type.
bool getNoReturnAttr() const { return getExtInfo().getNoReturn(); }
CallingConv getCallConv() const { return getExtInfo().getCC(); }
ExtInfo getExtInfo() const { return ExtInfo(FunctionTypeBits.ExtInfo); }
@@ -2735,7 +2739,7 @@ public:
/// no information available about its arguments.
class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode {
FunctionNoProtoType(QualType Result, QualType Canonical, ExtInfo Info)
- : FunctionType(FunctionNoProto, Result, 0, RQ_None, Canonical,
+ : FunctionType(FunctionNoProto, Result, 0, Canonical,
/*Dependent=*/false, /*InstantiationDependent=*/false,
Result->isVariablyModifiedType(),
/*ContainsUnexpandedParameterPack=*/false, Info) {}
@@ -2804,11 +2808,11 @@ private:
return false;
}
- FunctionProtoType(QualType result, const QualType *args, unsigned numArgs,
+ FunctionProtoType(QualType result, ArrayRef<QualType> args,
QualType canonical, const ExtProtoInfo &epi);
/// NumArgs - The number of arguments this function has, not counting '...'.
- unsigned NumArgs : 17;
+ unsigned NumArgs : 15;
/// NumExceptions - The number of types in the exception spec, if any.
unsigned NumExceptions : 9;
@@ -2825,6 +2829,11 @@ private:
/// HasTrailingReturn - Whether this function has a trailing return type.
unsigned HasTrailingReturn : 1;
+ /// \brief The ref-qualifier associated with a \c FunctionProtoType.
+ ///
+ /// This is a value of type \c RefQualifierKind.
+ unsigned RefQualifier : 2;
+
// ArgInfo - There is an variable size array after the class in memory that
// holds the argument types.
@@ -2864,6 +2873,9 @@ public:
assert(i < NumArgs && "Invalid argument number!");
return arg_type_begin()[i];
}
+ ArrayRef<QualType> getArgTypes() const {
+ return ArrayRef<QualType>(arg_type_begin(), arg_type_end());
+ }
ExtProtoInfo getExtProtoInfo() const {
ExtProtoInfo EPI;
@@ -2972,7 +2984,7 @@ public:
/// \brief Retrieve the ref-qualifier associated with this function type.
RefQualifierKind getRefQualifier() const {
- return FunctionType::getRefQualifier();
+ return static_cast<RefQualifierKind>(RefQualifier);
}
typedef const QualType *arg_type_iterator;
@@ -3005,9 +3017,6 @@ public:
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
- // FIXME: Remove the string version.
- void printExceptionSpecification(std::string &S,
- const PrintingPolicy &Policy) const;
void printExceptionSpecification(raw_ostream &OS,
const PrintingPolicy &Policy) const;
@@ -3323,7 +3332,8 @@ public:
attr_stdcall,
attr_thiscall,
attr_pascal,
- attr_pnaclcall
+ attr_pnaclcall,
+ attr_inteloclbicc
};
private:
@@ -3648,21 +3658,6 @@ public:
/// \brief Print a template argument list, including the '<' and '>'
/// enclosing the template arguments.
- // FIXME: remove the string ones.
- static std::string PrintTemplateArgumentList(const TemplateArgument *Args,
- unsigned NumArgs,
- const PrintingPolicy &Policy,
- bool SkipBrackets = false);
-
- static std::string PrintTemplateArgumentList(const TemplateArgumentLoc *Args,
- unsigned NumArgs,
- const PrintingPolicy &Policy);
-
- static std::string PrintTemplateArgumentList(const TemplateArgumentListInfo &,
- const PrintingPolicy &Policy);
-
- /// \brief Print a template argument list, including the '<' and '>'
- /// enclosing the template arguments.
static void PrintTemplateArgumentList(raw_ostream &OS,
const TemplateArgument *Args,
unsigned NumArgs,
@@ -4125,7 +4120,7 @@ class PackExpansionType : public Type, public llvm::FoldingSetNode {
unsigned NumExpansions;
PackExpansionType(QualType Pattern, QualType Canon,
- llvm::Optional<unsigned> NumExpansions)
+ Optional<unsigned> NumExpansions)
: Type(PackExpansion, Canon, /*Dependent=*/Pattern->isDependentType(),
/*InstantiationDependent=*/true,
/*VariableModified=*/Pattern->isVariablyModifiedType(),
@@ -4143,11 +4138,11 @@ public:
/// \brief Retrieve the number of expansions that this pack expansion will
/// generate, if known.
- llvm::Optional<unsigned> getNumExpansions() const {
+ Optional<unsigned> getNumExpansions() const {
if (NumExpansions)
return NumExpansions - 1;
- return llvm::Optional<unsigned>();
+ return None;
}
bool isSugared() const { return false; }
@@ -4158,9 +4153,9 @@ public:
}
static void Profile(llvm::FoldingSetNodeID &ID, QualType Pattern,
- llvm::Optional<unsigned> NumExpansions) {
+ Optional<unsigned> NumExpansions) {
ID.AddPointer(Pattern.getAsOpaquePtr());
- ID.AddBoolean(NumExpansions);
+ ID.AddBoolean(NumExpansions.hasValue());
if (NumExpansions)
ID.AddInteger(*NumExpansions);
}
@@ -4887,6 +4882,49 @@ inline bool Type::isObjCSelType() const {
inline bool Type::isObjCBuiltinType() const {
return isObjCIdType() || isObjCClassType() || isObjCSelType();
}
+
+inline bool Type::isImage1dT() const {
+ return isSpecificBuiltinType(BuiltinType::OCLImage1d);
+}
+
+inline bool Type::isImage1dArrayT() const {
+ return isSpecificBuiltinType(BuiltinType::OCLImage1dArray);
+}
+
+inline bool Type::isImage1dBufferT() const {
+ return isSpecificBuiltinType(BuiltinType::OCLImage1dBuffer);
+}
+
+inline bool Type::isImage2dT() const {
+ return isSpecificBuiltinType(BuiltinType::OCLImage2d);
+}
+
+inline bool Type::isImage2dArrayT() const {
+ return isSpecificBuiltinType(BuiltinType::OCLImage2dArray);
+}
+
+inline bool Type::isImage3dT() const {
+ return isSpecificBuiltinType(BuiltinType::OCLImage3d);
+}
+
+inline bool Type::isSamplerT() const {
+ return isSpecificBuiltinType(BuiltinType::OCLSampler);
+}
+
+inline bool Type::isEventT() const {
+ return isSpecificBuiltinType(BuiltinType::OCLEvent);
+}
+
+inline bool Type::isImageType() const {
+ return isImage3dT() ||
+ isImage2dT() || isImage2dArrayT() ||
+ isImage1dT() || isImage1dArrayT() || isImage1dBufferT();
+}
+
+inline bool Type::isOpenCLSpecificType() const {
+ return isSamplerT() || isEventT() || isImageType();
+}
+
inline bool Type::isTemplateTypeParmType() const {
return isa<TemplateTypeParmType>(CanonicalType);
}
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
index 8a04bd8d5ee0..11cad9bb9dd9 100644
--- a/include/clang/AST/TypeLoc.h
+++ b/include/clang/AST/TypeLoc.h
@@ -14,9 +14,9 @@
#ifndef LLVM_CLANG_AST_TYPELOC_H
#define LLVM_CLANG_AST_TYPELOC_H
-#include "clang/AST/Type.h"
#include "clang/AST/Decl.h"
#include "clang/AST/TemplateBase.h"
+#include "clang/AST/Type.h"
#include "clang/Basic/Specifiers.h"
#include "llvm/Support/Compiler.h"
@@ -44,6 +44,29 @@ protected:
void *Data;
public:
+ /// \brief Convert to the specified TypeLoc type, asserting that this TypeLoc
+ /// is of the desired type.
+ template<typename T>
+ T castAs() const {
+ assert(T::isKind(*this));
+ T t;
+ TypeLoc& tl = t;
+ tl = *this;
+ return t;
+ }
+
+ /// \brief Convert to the specified TypeLoc type, returning a null TypeLoc if
+ /// this TypeLoc is not of the desired type.
+ template<typename T>
+ T getAs() const {
+ if (!T::isKind(*this))
+ return T();
+ T t;
+ TypeLoc& tl = t;
+ tl = *this;
+ return t;
+ }
+
/// The kinds of TypeLocs. Equivalent to the Type::TypeClass enum,
/// except it also defines a Qualified enum that corresponds to the
/// QualifiedLoc class.
@@ -119,11 +142,7 @@ public:
/// \brief Skips past any qualifiers, if this is qualified.
UnqualTypeLoc getUnqualifiedLoc() const; // implemented in this header
- TypeLoc IgnoreParens() const {
- if (isa<ParenTypeLoc>(this))
- return IgnoreParensImpl(*this);
- return *this;
- }
+ TypeLoc IgnoreParens() const;
/// \brief Initializes this to state that every location in this
/// type is the given location.
@@ -160,6 +179,10 @@ public:
}
private:
+ static bool isKind(const TypeLoc&) {
+ return true;
+ }
+
static void initializeImpl(ASTContext &Context, TypeLoc TL,
SourceLocation Loc);
static TypeLoc getNextTypeLocImpl(TypeLoc TL);
@@ -187,8 +210,10 @@ public:
return (TypeLocClass) getTypePtr()->getTypeClass();
}
- static bool classof(const TypeLoc *TL) {
- return !TL->getType().hasLocalQualifiers();
+private:
+ friend class TypeLoc;
+ static bool isKind(const TypeLoc &TL) {
+ return !TL.getType().hasLocalQualifiers();
}
};
@@ -231,15 +256,17 @@ public:
getFullDataSizeForType(getType().getLocalUnqualifiedType());
}
- static bool classof(const TypeLoc *TL) {
- return TL->getType().hasLocalQualifiers();
+private:
+ friend class TypeLoc;
+ static bool isKind(const TypeLoc &TL) {
+ return TL.getType().hasLocalQualifiers();
}
};
inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const {
- if (isa<QualifiedTypeLoc>(this))
- return cast<QualifiedTypeLoc>(this)->getUnqualifiedLoc();
- return cast<UnqualTypeLoc>(*this);
+ if (QualifiedTypeLoc Loc = getAs<QualifiedTypeLoc>())
+ return Loc.getUnqualifiedLoc();
+ return castAs<UnqualTypeLoc>();
}
/// A metaprogramming base class for TypeLoc classes which correspond
@@ -280,24 +307,22 @@ class ConcreteTypeLoc : public Base {
return static_cast<const Derived*>(this);
}
-public:
- unsigned getLocalDataSize() const {
- return sizeof(LocalData) + asDerived()->getExtraLocalDataSize();
- }
- // Give a default implementation that's useful for leaf types.
- unsigned getFullDataSize() const {
- return asDerived()->getLocalDataSize() + getInnerTypeSize();
+ friend class TypeLoc;
+ static bool isKind(const TypeLoc &TL) {
+ return Derived::classofType(TL.getTypePtr());
}
static bool classofType(const Type *Ty) {
return TypeClass::classof(Ty);
}
- static bool classof(const TypeLoc *TL) {
- return Derived::classofType(TL->getTypePtr());
+public:
+ unsigned getLocalDataSize() const {
+ return sizeof(LocalData) + asDerived()->getExtraLocalDataSize();
}
- static bool classof(const UnqualTypeLoc *TL) {
- return Derived::classofType(TL->getTypePtr());
+ // Give a default implementation that's useful for leaf types.
+ unsigned getFullDataSize() const {
+ return asDerived()->getLocalDataSize() + getInnerTypeSize();
}
TypeLoc getNextTypeLoc() const {
@@ -362,18 +387,19 @@ private:
/// information. See the note on ConcreteTypeLoc.
template <class Base, class Derived, class TypeClass>
class InheritingConcreteTypeLoc : public Base {
-public:
+ friend class TypeLoc;
static bool classofType(const Type *Ty) {
return TypeClass::classof(Ty);
}
- static bool classof(const TypeLoc *TL) {
- return Derived::classofType(TL->getTypePtr());
+ static bool isKind(const TypeLoc &TL) {
+ return Derived::classofType(TL.getTypePtr());
}
- static bool classof(const UnqualTypeLoc *TL) {
- return Derived::classofType(TL->getTypePtr());
+ static bool isKind(const UnqualTypeLoc &TL) {
+ return Derived::classofType(TL.getTypePtr());
}
+public:
const TypeClass *getTypePtr() const {
return cast<TypeClass>(Base::getTypePtr());
}
@@ -406,7 +432,9 @@ public:
setNameLoc(Loc);
}
- static bool classof(const TypeLoc *TL);
+private:
+ friend class TypeLoc;
+ static bool isKind(const TypeLoc &TL);
};
@@ -899,6 +927,11 @@ public:
}
};
+inline TypeLoc TypeLoc::IgnoreParens() const {
+ if (ParenTypeLoc::isKind(*this))
+ return IgnoreParensImpl(*this);
+ return *this;
+}
struct PointerLikeLocInfo {
SourceLocation StarLoc;
diff --git a/include/clang/AST/TypeLocVisitor.h b/include/clang/AST/TypeLocVisitor.h
index 50fc43913f4c..db5775aa146e 100644
--- a/include/clang/AST/TypeLocVisitor.h
+++ b/include/clang/AST/TypeLocVisitor.h
@@ -21,7 +21,7 @@ namespace clang {
#define DISPATCH(CLASSNAME) \
return static_cast<ImplClass*>(this)-> \
- Visit##CLASSNAME(cast<CLASSNAME>(TyLoc))
+ Visit##CLASSNAME(TyLoc.castAs<CLASSNAME>())
template<typename ImplClass, typename RetTy=void>
class TypeLocVisitor {
diff --git a/include/clang/AST/TypeOrdering.h b/include/clang/AST/TypeOrdering.h
index 7cf0d5e999b6..59b59f517168 100644
--- a/include/clang/AST/TypeOrdering.h
+++ b/include/clang/AST/TypeOrdering.h
@@ -16,8 +16,8 @@
#ifndef LLVM_CLANG_TYPE_ORDERING_H
#define LLVM_CLANG_TYPE_ORDERING_H
-#include "clang/AST/Type.h"
#include "clang/AST/CanonicalType.h"
+#include "clang/AST/Type.h"
#include <functional>
namespace clang {
diff --git a/include/clang/AST/UnresolvedSet.h b/include/clang/AST/UnresolvedSet.h
index 9f11ee5fe3e2..d26065e3745b 100644
--- a/include/clang/AST/UnresolvedSet.h
+++ b/include/clang/AST/UnresolvedSet.h
@@ -15,9 +15,11 @@
#ifndef LLVM_CLANG_AST_UNRESOLVEDSET_H
#define LLVM_CLANG_AST_UNRESOLVEDSET_H
-#include <iterator>
-#include "llvm/ADT/SmallVector.h"
#include "clang/AST/DeclAccessPair.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
+#include <iterator>
namespace clang {
@@ -25,12 +27,13 @@ namespace clang {
/// non-const iterator.
class UnresolvedSetIterator {
private:
- typedef SmallVectorImpl<DeclAccessPair> DeclsTy;
+ typedef llvm::MutableArrayRef<DeclAccessPair> DeclsTy;
typedef DeclsTy::iterator IteratorTy;
IteratorTy ir;
friend class UnresolvedSetImpl;
+ friend class ASTUnresolvedSet;
friend class OverloadExpr;
explicit UnresolvedSetIterator(DeclsTy::iterator ir) : ir(ir) {}
explicit UnresolvedSetIterator(DeclsTy::const_iterator ir) :
@@ -87,7 +90,7 @@ public:
/// UnresolvedSet - A set of unresolved declarations.
class UnresolvedSetImpl {
- typedef UnresolvedSetIterator::DeclsTy DeclsTy;
+ typedef SmallVectorImpl<DeclAccessPair> DeclsTy;
// Don't allow direct construction, and only permit subclassing by
// UnresolvedSet.
diff --git a/include/clang/AST/VTTBuilder.h b/include/clang/AST/VTTBuilder.h
index 6756dd1e993b..f24bb3f16b86 100644
--- a/include/clang/AST/VTTBuilder.h
+++ b/include/clang/AST/VTTBuilder.h
@@ -102,9 +102,6 @@ class VTTBuilder {
bool GenerateDefinition;
/// AddVTablePointer - Add a vtable pointer to the VTT currently being built.
- ///
- /// \param AddressPoints - If the vtable is a construction vtable, this has
- /// the address points for it.
void AddVTablePointer(BaseSubobject Base, uint64_t VTableIndex,
const CXXRecordDecl *VTableClass);
@@ -117,9 +114,6 @@ class VTTBuilder {
///
/// \param BaseIsMorallyVirtual whether the base subobject is a virtual base
/// or a direct or indirect base of a virtual base.
- ///
- /// \param AddressPoints - If the vtable is a construction vtable, this has
- /// the address points for it.
void LayoutSecondaryVirtualPointers(BaseSubobject Base,
bool BaseIsMorallyVirtual,
uint64_t VTableIndex,
@@ -128,9 +122,6 @@ class VTTBuilder {
/// LayoutSecondaryVirtualPointers - Lay out the secondary virtual pointers
/// for the given base subobject.
- ///
- /// \param AddressPoints - If the vtable is a construction vtable, this has
- /// the address points for it.
void LayoutSecondaryVirtualPointers(BaseSubobject Base,
uint64_t VTableIndex);
diff --git a/include/clang/AST/VTableBuilder.h b/include/clang/AST/VTableBuilder.h
index a6aa40b9d68b..bcbe8754ea4a 100644
--- a/include/clang/AST/VTableBuilder.h
+++ b/include/clang/AST/VTableBuilder.h
@@ -215,12 +215,15 @@ private:
/// Address points - Address points for all vtables.
AddressPointsMapTy AddressPoints;
+ bool IsMicrosoftABI;
+
public:
VTableLayout(uint64_t NumVTableComponents,
const VTableComponent *VTableComponents,
uint64_t NumVTableThunks,
const VTableThunkTy *VTableThunks,
- const AddressPointsMapTy &AddressPoints);
+ const AddressPointsMapTy &AddressPoints,
+ bool IsMicrosoftABI);
~VTableLayout();
uint64_t getNumVTableComponents() const {
@@ -252,7 +255,8 @@ public:
"Did not find address point!");
uint64_t AddressPoint = AddressPoints.lookup(Base);
- assert(AddressPoint && "Address point must not be zero!");
+ assert(AddressPoint != 0 || IsMicrosoftABI);
+ (void)IsMicrosoftABI;
return AddressPoint;
}
@@ -271,6 +275,8 @@ public:
typedef SmallVector<ThunkInfo, 1> ThunkInfoVectorTy;
private:
+ bool IsMicrosoftABI;
+
/// MethodVTableIndices - Contains the index (relative to the vtable address
/// point) where the function pointer for a virtual function is stored.
typedef llvm::DenseMap<GlobalDecl, int64_t> MethodVTableIndicesTy;
@@ -306,10 +312,21 @@ private:
/// given record decl.
void ComputeVTableRelatedInformation(const CXXRecordDecl *RD);
+ /// ErrorUnsupported - Print out an error that the v-table layout code
+ /// doesn't support the particular C++ feature yet.
+ void ErrorUnsupported(StringRef Feature, SourceLocation Location);
+
public:
- VTableContext(ASTContext &Context) : Context(Context) {}
+ VTableContext(ASTContext &Context);
~VTableContext();
+ bool isMicrosoftABI() const {
+ // FIXME: Currently, this method is only used in the VTableContext and
+ // VTableBuilder code which is ABI-specific. Probably we can remove it
+ // when we add a layer of abstraction for vtable generation.
+ return IsMicrosoftABI;
+ }
+
const VTableLayout &getVTableLayout(const CXXRecordDecl *RD) {
ComputeVTableRelatedInformation(RD);
assert(VTableLayouts.count(RD) && "No layout for this record decl!");
diff --git a/include/clang/ASTMatchers/ASTMatchFinder.h b/include/clang/ASTMatchers/ASTMatchFinder.h
index 30b4050e1c81..870a39b39111 100644
--- a/include/clang/ASTMatchers/ASTMatchFinder.h
+++ b/include/clang/ASTMatchers/ASTMatchFinder.h
@@ -56,6 +56,10 @@ namespace ast_matchers {
/// that will trigger the callbacks specified via addMatcher(...) when a match
/// is found.
///
+/// The order of matches is guaranteed to be equivalent to doing a pre-order
+/// traversal on the AST, and applying the matchers in the order in which they
+/// were added to the MatchFinder.
+///
/// See ASTMatchers.h for more information about how to create matchers.
///
/// Not intended to be subclassed.
@@ -130,11 +134,17 @@ public:
/// \brief Creates a clang ASTConsumer that finds all matches.
clang::ASTConsumer *newASTConsumer();
- /// \brief Finds all matches on the given \c Node.
+ /// \brief Calls the registered callbacks on all matches on the given \p Node.
+ ///
+ /// Note that there can be multiple matches on a single node, for
+ /// example when using decl(forEachDescendant(stmt())).
///
/// @{
- void findAll(const Decl &Node, ASTContext &Context);
- void findAll(const Stmt &Node, ASTContext &Context);
+ template <typename T> void match(const T &Node, ASTContext &Context) {
+ match(clang::ast_type_traits::DynTypedNode::create(Node), Context);
+ }
+ void match(const clang::ast_type_traits::DynTypedNode &Node,
+ ASTContext &Context);
/// @}
/// \brief Registers a callback to notify the end of parsing.
@@ -154,6 +164,75 @@ private:
ParsingDoneTestCallback *ParsingDone;
};
+/// \brief Returns the results of matching \p Matcher on \p Node.
+///
+/// Collects the \c BoundNodes of all callback invocations when matching
+/// \p Matcher on \p Node and returns the collected results.
+///
+/// Multiple results occur when using matchers like \c forEachDescendant,
+/// which generate a result for each sub-match.
+///
+/// \see selectFirst
+/// @{
+template <typename MatcherT, typename NodeT>
+SmallVector<BoundNodes, 1>
+match(MatcherT Matcher, const NodeT &Node, ASTContext &Context);
+
+template <typename MatcherT>
+SmallVector<BoundNodes, 1>
+match(MatcherT Matcher, const ast_type_traits::DynTypedNode &Node,
+ ASTContext &Context);
+/// @}
+
+/// \brief Returns the first result of type \c NodeT bound to \p BoundTo.
+///
+/// Returns \c NULL if there is no match, or if the matching node cannot be
+/// casted to \c NodeT.
+///
+/// This is useful in combanation with \c match():
+/// \code
+/// Decl *D = selectFirst<Decl>("id", match(Matcher.bind("id"),
+/// Node, Context));
+/// \endcode
+template <typename NodeT>
+NodeT *
+selectFirst(StringRef BoundTo, const SmallVectorImpl<BoundNodes> &Results) {
+ for (SmallVectorImpl<BoundNodes>::const_iterator I = Results.begin(),
+ E = Results.end();
+ I != E; ++I) {
+ if (NodeT *Node = I->getNodeAs<NodeT>(BoundTo))
+ return Node;
+ }
+ return NULL;
+}
+
+namespace internal {
+class CollectMatchesCallback : public MatchFinder::MatchCallback {
+public:
+ virtual void run(const MatchFinder::MatchResult &Result) {
+ Nodes.push_back(Result.Nodes);
+ }
+ SmallVector<BoundNodes, 1> Nodes;
+};
+}
+
+template <typename MatcherT>
+SmallVector<BoundNodes, 1>
+match(MatcherT Matcher, const ast_type_traits::DynTypedNode &Node,
+ ASTContext &Context) {
+ internal::CollectMatchesCallback Callback;
+ MatchFinder Finder;
+ Finder.addMatcher(Matcher, &Callback);
+ Finder.match(Node, Context);
+ return Callback.Nodes;
+}
+
+template <typename MatcherT, typename NodeT>
+SmallVector<BoundNodes, 1>
+match(MatcherT Matcher, const NodeT &Node, ASTContext &Context) {
+ return match(Matcher, ast_type_traits::DynTypedNode::create(Node), Context);
+}
+
} // end namespace ast_matchers
} // end namespace clang
diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h
index a70dd5c378bd..f10addcb7af6 100644
--- a/include/clang/ASTMatchers/ASTMatchers.h
+++ b/include/clang/ASTMatchers/ASTMatchers.h
@@ -142,7 +142,7 @@ inline internal::PolymorphicMatcherWithParam0<internal::TrueMatcher> anything()
/// friend X;
/// };
/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Decl, Decl> decl;
+const internal::VariadicAllOfMatcher<Decl> decl;
/// \brief Matches a declaration of anything that could have a name.
///
@@ -192,6 +192,69 @@ const internal::VariadicDynCastAllOfMatcher<
Decl,
ClassTemplateSpecializationDecl> classTemplateSpecializationDecl;
+/// \brief Matches C++ access specifier declarations.
+///
+/// Given
+/// \code
+/// class C {
+/// public:
+/// int a;
+/// };
+/// \endcode
+/// accessSpecDecl()
+/// matches 'public:'
+const internal::VariadicDynCastAllOfMatcher<
+ Decl,
+ AccessSpecDecl> accessSpecDecl;
+
+/// \brief Matches public C++ declarations.
+///
+/// Given
+/// \code
+/// class C {
+/// public: int a;
+/// protected: int b;
+/// private: int c;
+/// };
+/// \endcode
+/// fieldDecl(isPublic())
+/// matches 'int a;'
+AST_MATCHER(Decl, isPublic) {
+ return Node.getAccess() == AS_public;
+}
+
+/// \brief Matches protected C++ declarations.
+///
+/// Given
+/// \code
+/// class C {
+/// public: int a;
+/// protected: int b;
+/// private: int c;
+/// };
+/// \endcode
+/// fieldDecl(isProtected())
+/// matches 'int b;'
+AST_MATCHER(Decl, isProtected) {
+ return Node.getAccess() == AS_protected;
+}
+
+/// \brief Matches private C++ declarations.
+///
+/// Given
+/// \code
+/// class C {
+/// public: int a;
+/// protected: int b;
+/// private: int c;
+/// };
+/// \endcode
+/// fieldDecl(isPrivate())
+/// matches 'int c;'
+AST_MATCHER(Decl, isPrivate) {
+ return Node.getAccess() == AS_private;
+}
+
/// \brief Matches classTemplateSpecializations that have at least one
/// TemplateArgument matching the given InnerMatcher.
///
@@ -453,7 +516,7 @@ const internal::VariadicDynCastAllOfMatcher<
/// \endcode
/// stmt()
/// matches both the compound statement '{ ++a; }' and '++a'.
-const internal::VariadicDynCastAllOfMatcher<Stmt, Stmt> stmt;
+const internal::VariadicAllOfMatcher<Stmt> stmt;
/// \brief Matches declaration statements.
///
@@ -922,6 +985,16 @@ const internal::VariadicDynCastAllOfMatcher<
Stmt,
UserDefinedLiteral> userDefinedLiteral;
+/// \brief Matches compound (i.e. non-scalar) literals
+///
+/// Example match: {1}, (1, 2)
+/// \code
+/// int array[4] = {1}; vector int myvec = (vector int)(1, 2);
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+ Stmt,
+ CompoundLiteralExpr> compoundLiteralExpr;
+
/// \brief Matches nullptr literal.
const internal::VariadicDynCastAllOfMatcher<
Stmt,
@@ -1090,10 +1163,36 @@ const internal::VariadicDynCastAllOfMatcher<
const internal::VariadicAllOfMatcher<QualType> qualType;
/// \brief Matches \c Types in the clang AST.
-const internal::VariadicDynCastAllOfMatcher<Type, Type> type;
+const internal::VariadicAllOfMatcher<Type> type;
/// \brief Matches \c TypeLocs in the clang AST.
-const internal::VariadicDynCastAllOfMatcher<TypeLoc, TypeLoc> typeLoc;
+const internal::VariadicAllOfMatcher<TypeLoc> typeLoc;
+
+/// \brief Matches if any of the given matchers matches.
+///
+/// Unlike \c anyOf, \c eachOf will generate a match result for each
+/// matching submatcher.
+///
+/// For example, in:
+/// \code
+/// class A { int a; int b; };
+/// \endcode
+/// The matcher:
+/// \code
+/// recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
+/// has(fieldDecl(hasName("b")).bind("v"))))
+/// \endcode
+/// will generate two results binding "v", the first of which binds
+/// the field declaration of \c a, the second the field declaration of
+/// \c b.
+///
+/// Usable as: Any Matcher
+template <typename M1, typename M2>
+internal::PolymorphicMatcherWithParam2<internal::EachOfMatcher, M1, M2>
+eachOf(const M1 &P1, const M2 &P2) {
+ return internal::PolymorphicMatcherWithParam2<internal::EachOfMatcher, M1,
+ M2>(P1, P2);
+}
/// \brief Various overloads for the anyOf matcher.
/// @{
@@ -1139,18 +1238,40 @@ anyOf(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4, const M5 &P5) {
/// \brief Matches if all given matchers match.
///
/// Usable as: Any Matcher
-template<typename M1, typename M2>
+template <typename M1, typename M2>
internal::PolymorphicMatcherWithParam2<internal::AllOfMatcher, M1, M2>
allOf(const M1 &P1, const M2 &P2) {
- return internal::PolymorphicMatcherWithParam2<internal::AllOfMatcher,
- M1, M2>(P1, P2);
+ return internal::PolymorphicMatcherWithParam2<internal::AllOfMatcher, M1, M2>(
+ P1, P2);
}
-template<typename M1, typename M2, typename M3>
-internal::PolymorphicMatcherWithParam2<internal::AllOfMatcher, M1,
+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));
}
+template <typename M1, typename M2, typename M3, typename M4>
+internal::PolymorphicMatcherWithParam2<
+ internal::AllOfMatcher, M1,
+ internal::PolymorphicMatcherWithParam2<
+ internal::AllOfMatcher, M2, internal::PolymorphicMatcherWithParam2<
+ internal::AllOfMatcher, M3, M4> > >
+allOf(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4) {
+ return allOf(P1, allOf(P2, P3, P4));
+}
+template <typename M1, typename M2, typename M3, typename M4, typename M5>
+internal::PolymorphicMatcherWithParam2<
+ internal::AllOfMatcher, M1,
+ internal::PolymorphicMatcherWithParam2<
+ internal::AllOfMatcher, M2,
+ internal::PolymorphicMatcherWithParam2<
+ internal::AllOfMatcher, M3,
+ internal::PolymorphicMatcherWithParam2<internal::AllOfMatcher, M4,
+ M5> > > >
+allOf(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4, const M5 &P5) {
+ return allOf(P1, allOf(P2, P3, P4, P5));
+}
/// @}
@@ -1198,7 +1319,7 @@ AST_MATCHER_P(UnaryExprOrTypeTraitExpr, ofKind, UnaryExprOrTypeTrait, Kind) {
/// alignof.
inline internal::Matcher<Stmt> alignOfExpr(
const internal::Matcher<UnaryExprOrTypeTraitExpr> &InnerMatcher) {
- return internal::Matcher<Stmt>(unaryExprOrTypeTraitExpr(allOf(
+ return stmt(unaryExprOrTypeTraitExpr(allOf(
ofKind(UETT_AlignOf), InnerMatcher)));
}
@@ -1206,8 +1327,8 @@ inline internal::Matcher<Stmt> alignOfExpr(
/// sizeof.
inline internal::Matcher<Stmt> sizeOfExpr(
const internal::Matcher<UnaryExprOrTypeTraitExpr> &InnerMatcher) {
- return internal::Matcher<Stmt>(unaryExprOrTypeTraitExpr(allOf(
- ofKind(UETT_SizeOf), InnerMatcher)));
+ return stmt(unaryExprOrTypeTraitExpr(
+ allOf(ofKind(UETT_SizeOf), InnerMatcher)));
}
/// \brief Matches NamedDecl nodes that have the specified name.
@@ -1228,8 +1349,8 @@ inline internal::Matcher<Stmt> sizeOfExpr(
AST_MATCHER_P(NamedDecl, hasName, std::string, Name) {
assert(!Name.empty());
const std::string FullNameString = "::" + Node.getQualifiedNameAsString();
- const llvm::StringRef FullName = FullNameString;
- const llvm::StringRef Pattern = Name;
+ const StringRef FullName = FullNameString;
+ const StringRef Pattern = Name;
if (Pattern.startswith("::")) {
return FullName == Pattern;
} else {
@@ -1237,8 +1358,8 @@ AST_MATCHER_P(NamedDecl, hasName, std::string, Name) {
}
}
-/// \brief Matches NamedDecl nodes whose full names partially match the
-/// given RegExp.
+/// \brief Matches NamedDecl nodes whose fully qualified names contain
+/// a substring matched by the given RegExp.
///
/// Supports specifying enclosing namespaces or classes by
/// prefixing the name with '<enclosing>::'. Does not match typedefs
@@ -1263,18 +1384,26 @@ AST_MATCHER_P(NamedDecl, matchesName, std::string, RegExp) {
/// \brief Matches overloaded operator names.
///
/// Matches overloaded operator names specified in strings without the
-/// "operator" prefix, such as "<<", for OverloadedOperatorCall's.
+/// "operator" prefix: e.g. "<<".
///
-/// Example matches a << b
-/// (matcher == operatorCallExpr(hasOverloadedOperatorName("<<")))
+/// Given:
/// \code
-/// a << b;
-/// c && d; // assuming both operator<<
-/// // and operator&& are overloaded somewhere.
+/// class A { int operator*(); };
+/// const A &operator<<(const A &a, const A &b);
+/// A a;
+/// a << a; // <-- This matches
/// \endcode
-AST_MATCHER_P(CXXOperatorCallExpr,
- hasOverloadedOperatorName, std::string, Name) {
- return getOperatorSpelling(Node.getOperator()) == Name;
+///
+/// \c operatorCallExpr(hasOverloadedOperatorName("<<"))) matches the specified
+/// line and \c recordDecl(hasMethod(hasOverloadedOperatorName("*"))) matches
+/// the declaration of \c A.
+///
+/// Usable as: Matcher<CXXOperatorCallExpr>, Matcher<CXXMethodDecl>
+inline internal::PolymorphicMatcherWithParam1<
+ internal::HasOverloadedOperatorNameMatcher, StringRef>
+hasOverloadedOperatorName(const StringRef Name) {
+ return internal::PolymorphicMatcherWithParam1<
+ internal::HasOverloadedOperatorNameMatcher, StringRef>(Name);
}
/// \brief Matches C++ classes that are directly or indirectly derived from
@@ -1324,6 +1453,27 @@ inline internal::Matcher<CXXRecordDecl> isSameOrDerivedFrom(
return isSameOrDerivedFrom(hasName(BaseName));
}
+/// \brief Matches the first method of a class or struct that satisfies \c
+/// InnerMatcher.
+///
+/// Given:
+/// \code
+/// class A { void func(); };
+/// class B { void member(); };
+/// \code
+///
+/// \c recordDecl(hasMethod(hasName("func"))) matches the declaration of \c A
+/// but not \c B.
+AST_MATCHER_P(CXXRecordDecl, hasMethod, internal::Matcher<CXXMethodDecl>,
+ InnerMatcher) {
+ for (CXXRecordDecl::method_iterator I = Node.method_begin(),
+ E = Node.method_end();
+ I != E; ++I)
+ if (InnerMatcher.matches(**I, Finder, Builder))
+ return true;
+ return false;
+}
+
/// \brief Matches AST nodes that have child AST nodes that match the
/// provided matcher.
///
@@ -1424,6 +1574,29 @@ forEachDescendant(
DescendantT>(DescendantMatcher);
}
+/// \brief Matches if the node or any descendant matches.
+///
+/// Generates results for each match.
+///
+/// For example, in:
+/// \code
+/// class A { class B {}; class C {}; };
+/// \endcode
+/// The matcher:
+/// \code
+/// recordDecl(hasName("::A"), findAll(recordDecl(isDefinition()).bind("m")))
+/// \endcode
+/// will generate results for \c A, \c B and \c C.
+///
+/// Usable as: Any Matcher
+template <typename T>
+internal::PolymorphicMatcherWithParam2<
+ internal::EachOfMatcher, internal::Matcher<T>,
+ internal::ArgumentAdaptingMatcher<internal::ForEachDescendantMatcher, T> >
+findAll(const internal::Matcher<T> &Matcher) {
+ return eachOf(Matcher, forEachDescendant(Matcher));
+}
+
/// \brief Matches AST nodes that have a parent that matches the provided
/// matcher.
///
@@ -1480,8 +1653,13 @@ unless(const M &InnerMatcher) {
/// \brief Matches a type if the declaration of the type matches the given
/// matcher.
///
+/// In addition to being usable as Matcher<TypedefType>, also usable as
+/// Matcher<T> for any T supporting the getDecl() member function. e.g. various
+/// subtypes of clang::Type.
+///
/// Usable as: Matcher<QualType>, Matcher<CallExpr>, Matcher<CXXConstructExpr>,
-/// Matcher<MemberExpr>
+/// Matcher<MemberExpr>, Matcher<TypedefType>,
+/// Matcher<TemplateSpecializationType>
inline internal::PolymorphicMatcherWithParam1< internal::HasDeclarationMatcher,
internal::Matcher<Decl> >
hasDeclaration(const internal::Matcher<Decl> &InnerMatcher) {
@@ -1501,9 +1679,8 @@ inline internal::PolymorphicMatcherWithParam1< internal::HasDeclarationMatcher,
/// FIXME: Overload to allow directly matching types?
AST_MATCHER_P(CXXMemberCallExpr, on, internal::Matcher<Expr>,
InnerMatcher) {
- const Expr *ExprNode = const_cast<CXXMemberCallExpr&>(Node)
- .getImplicitObjectArgument()
- ->IgnoreParenImpCasts();
+ const Expr *ExprNode = Node.getImplicitObjectArgument()
+ ->IgnoreParenImpCasts();
return (ExprNode != NULL &&
InnerMatcher.matches(*ExprNode, Finder, Builder));
}
@@ -1541,7 +1718,7 @@ AST_MATCHER_P(CallExpr, callee, internal::Matcher<Stmt>,
/// \endcode
inline internal::Matcher<CallExpr> callee(
const internal::Matcher<Decl> &InnerMatcher) {
- return internal::Matcher<CallExpr>(hasDeclaration(InnerMatcher));
+ return callExpr(hasDeclaration(InnerMatcher));
}
/// \brief Matches if the expression's or declaration's type matches a type
@@ -1579,11 +1756,10 @@ AST_POLYMORPHIC_MATCHER_P(hasType, internal::Matcher<QualType>,
///
/// Usable as: Matcher<Expr>, Matcher<ValueDecl>
inline internal::PolymorphicMatcherWithParam1<
- internal::matcher_hasTypeMatcher,
+ internal::matcher_hasType0Matcher,
internal::Matcher<QualType> >
hasType(const internal::Matcher<Decl> &InnerMatcher) {
- return hasType(internal::Matcher<QualType>(
- hasDeclaration(InnerMatcher)));
+ return hasType(qualType(hasDeclaration(InnerMatcher)));
}
/// \brief Matches if the matched type is represented by the given string.
@@ -1618,8 +1794,7 @@ AST_MATCHER_P(
/// \brief Overloaded to match the pointee type's declaration.
inline internal::Matcher<QualType> pointsTo(
const internal::Matcher<Decl> &InnerMatcher) {
- return pointsTo(internal::Matcher<QualType>(
- hasDeclaration(InnerMatcher)));
+ return pointsTo(qualType(hasDeclaration(InnerMatcher)));
}
/// \brief Matches if the matched type is a reference type and the referenced
@@ -1640,17 +1815,32 @@ AST_MATCHER_P(QualType, references, internal::Matcher<QualType>,
InnerMatcher.matches(Node->getPointeeType(), Finder, Builder));
}
+/// \brief Matches QualTypes whose canonical type matches InnerMatcher.
+///
+/// Given:
+/// \code
+/// typedef int &int_ref;
+/// int a;
+/// int_ref b = a;
+/// \code
+///
+/// \c varDecl(hasType(qualType(referenceType()))))) will not match the
+/// declaration of b but \c
+/// varDecl(hasType(qualType(hasCanonicalType(referenceType())))))) does.
+AST_MATCHER_P(QualType, hasCanonicalType, internal::Matcher<QualType>,
+ InnerMatcher) {
+ return InnerMatcher.matches(Node.getCanonicalType(), Finder, Builder);
+}
+
/// \brief Overloaded to match the referenced type's declaration.
inline internal::Matcher<QualType> references(
const internal::Matcher<Decl> &InnerMatcher) {
- return references(internal::Matcher<QualType>(
- hasDeclaration(InnerMatcher)));
+ return references(qualType(hasDeclaration(InnerMatcher)));
}
AST_MATCHER_P(CXXMemberCallExpr, onImplicitObjectArgument,
internal::Matcher<Expr>, InnerMatcher) {
- const Expr *ExprNode =
- const_cast<CXXMemberCallExpr&>(Node).getImplicitObjectArgument();
+ const Expr *ExprNode = Node.getImplicitObjectArgument();
return (ExprNode != NULL &&
InnerMatcher.matches(*ExprNode, Finder, Builder));
}
@@ -1705,8 +1895,7 @@ AST_MATCHER_P(DeclRefExpr, to, internal::Matcher<Decl>,
AST_MATCHER_P(DeclRefExpr, throughUsingDecl,
internal::Matcher<UsingShadowDecl>, InnerMatcher) {
const NamedDecl *FoundDecl = Node.getFoundDecl();
- if (const UsingShadowDecl *UsingDecl =
- llvm::dyn_cast<UsingShadowDecl>(FoundDecl))
+ if (const UsingShadowDecl *UsingDecl = dyn_cast<UsingShadowDecl>(FoundDecl))
return InnerMatcher.matches(*UsingDecl, Finder, Builder);
return false;
}
@@ -1974,6 +2163,19 @@ AST_MATCHER_P(FunctionDecl, hasAnyParameter,
return false;
}
+/// \brief Matches \c FunctionDecls that have a specific parameter count.
+///
+/// Given
+/// \code
+/// void f(int i) {}
+/// void g(int i, int j) {}
+/// \endcode
+/// functionDecl(parameterCountIs(2))
+/// matches g(int i, int j) {}
+AST_MATCHER_P(FunctionDecl, parameterCountIs, unsigned, N) {
+ return Node.getNumParams() == N;
+}
+
/// \brief Matches the return type of a function declaration.
///
/// Given:
@@ -2279,10 +2481,13 @@ AST_MATCHER_P(ConditionalOperator, hasFalseExpression,
/// \endcode
///
/// Usable as: Matcher<TagDecl>, Matcher<VarDecl>, Matcher<FunctionDecl>
-inline internal::PolymorphicMatcherWithParam0<internal::IsDefinitionMatcher>
-isDefinition() {
- return internal::PolymorphicMatcherWithParam0<
- internal::IsDefinitionMatcher>();
+AST_POLYMORPHIC_MATCHER(isDefinition) {
+ TOOLING_COMPILE_ASSERT(
+ (llvm::is_base_of<TagDecl, NodeType>::value) ||
+ (llvm::is_base_of<VarDecl, NodeType>::value) ||
+ (llvm::is_base_of<FunctionDecl, NodeType>::value),
+ is_definition_requires_isThisDeclarationADefinition_method);
+ return Node.isThisDeclarationADefinition();
}
/// \brief Matches the class declaration that the given method declaration
@@ -2324,8 +2529,8 @@ AST_MATCHER_P(CXXMethodDecl, ofClass,
/// \endcode
/// memberExpr(isArrow())
/// matches this->x, x, y.x, a, this->b
-inline internal::Matcher<MemberExpr> isArrow() {
- return makeMatcher(new internal::IsArrowMatcher());
+AST_MATCHER(MemberExpr, isArrow) {
+ return Node.isArrow();
}
/// \brief Matches QualType nodes that are of integer type.
@@ -2357,8 +2562,25 @@ AST_MATCHER(QualType, isInteger) {
/// 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 *".
-inline internal::Matcher<QualType> isConstQualified() {
- return makeMatcher(new internal::IsConstQualifiedMatcher());
+AST_MATCHER(QualType, isConstQualified) {
+ return Node.isConstQualified();
+}
+
+/// \brief Matches QualType nodes that have local CV-qualifiers attached to
+/// the node, not hidden within a typedef.
+///
+/// Given
+/// \code
+/// typedef const int const_int;
+/// const_int i;
+/// int *const j;
+/// int *volatile k;
+/// int m;
+/// \endcode
+/// \c varDecl(hasType(hasLocalQualifiers())) matches only \c j and \c k.
+/// \c i is const-qualified but the qualifier is not local.
+AST_MATCHER(QualType, hasLocalQualifiers) {
+ return Node.hasLocalQualifiers();
}
/// \brief Matches a member expression where the member is matched by a
@@ -2454,11 +2676,14 @@ AST_MATCHER_P(UsingShadowDecl, hasTargetDecl,
/// does not match, as X<A> is an explicit template specialization.
///
/// Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl>
-inline internal::PolymorphicMatcherWithParam0<
- internal::IsTemplateInstantiationMatcher>
-isTemplateInstantiation() {
- return internal::PolymorphicMatcherWithParam0<
- internal::IsTemplateInstantiationMatcher>();
+AST_POLYMORPHIC_MATCHER(isTemplateInstantiation) {
+ TOOLING_COMPILE_ASSERT((llvm::is_base_of<FunctionDecl, NodeType>::value) ||
+ (llvm::is_base_of<VarDecl, NodeType>::value) ||
+ (llvm::is_base_of<CXXRecordDecl, NodeType>::value),
+ requires_getTemplateSpecializationKind_method);
+ return (Node.getTemplateSpecializationKind() == TSK_ImplicitInstantiation ||
+ Node.getTemplateSpecializationKind() ==
+ TSK_ExplicitInstantiationDefinition);
}
/// \brief Matches explicit template specializations of function, class, or
@@ -2473,11 +2698,12 @@ isTemplateInstantiation() {
/// matches the specialization A<int>().
///
/// Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl>
-inline internal::PolymorphicMatcherWithParam0<
- internal::IsExplicitTemplateSpecializationMatcher>
-isExplicitTemplateSpecialization() {
- return internal::PolymorphicMatcherWithParam0<
- internal::IsExplicitTemplateSpecializationMatcher>();
+AST_POLYMORPHIC_MATCHER(isExplicitTemplateSpecialization) {
+ TOOLING_COMPILE_ASSERT((llvm::is_base_of<FunctionDecl, NodeType>::value) ||
+ (llvm::is_base_of<VarDecl, NodeType>::value) ||
+ (llvm::is_base_of<CXXRecordDecl, NodeType>::value),
+ requires_getTemplateSpecializationKind_method);
+ return (Node.getTemplateSpecializationKind() == TSK_ExplicitSpecialization);
}
/// \brief Matches \c TypeLocs for which the given inner
@@ -2685,6 +2911,32 @@ AST_TYPE_TRAVERSE_MATCHER(hasDeducedType, getDeducedType);
/// matches "int (*f)(int)" and the type of "g".
AST_TYPE_MATCHER(FunctionType, functionType);
+/// \brief Matches \c ParenType nodes.
+///
+/// Given
+/// \code
+/// int (*ptr_to_array)[4];
+/// int *array_of_ptrs[4];
+/// \endcode
+///
+/// \c varDecl(hasType(pointsTo(parenType()))) matches \c ptr_to_array but not
+/// \c array_of_ptrs.
+AST_TYPE_MATCHER(ParenType, parenType);
+
+/// \brief Matches \c ParenType nodes where the inner type is a specific type.
+///
+/// Given
+/// \code
+/// int (*ptr_to_array)[4];
+/// int (*ptr_to_func)(int);
+/// \endcode
+///
+/// \c varDecl(hasType(pointsTo(parenType(innerType(functionType()))))) matches
+/// \c ptr_to_func but not \c ptr_to_array.
+///
+/// Usable as: Matcher<ParenType>
+AST_TYPE_TRAVERSE_MATCHER(innerType, getInnerType);
+
/// \brief Matches block pointer types, i.e. types syntactically represented as
/// "void (^)(int)".
///
@@ -2713,18 +2965,56 @@ AST_TYPE_MATCHER(MemberPointerType, memberPointerType);
/// matches "int *a"
AST_TYPE_MATCHER(PointerType, pointerType);
-/// \brief Matches reference types.
+/// \brief Matches both lvalue and rvalue reference types.
///
/// Given
/// \code
/// int *a;
/// int &b = *a;
-/// int c = 5;
+/// int &&c = 1;
+/// auto &d = b;
+/// auto &&e = c;
+/// auto &&f = 2;
+/// int g = 5;
/// \endcode
-/// pointerType()
-/// matches "int &b"
+///
+/// \c referenceType() matches the types of \c b, \c c, \c d, \c e, and \c f.
AST_TYPE_MATCHER(ReferenceType, referenceType);
+/// \brief Matches lvalue reference types.
+///
+/// Given:
+/// \code
+/// int *a;
+/// int &b = *a;
+/// int &&c = 1;
+/// auto &d = b;
+/// auto &&e = c;
+/// auto &&f = 2;
+/// int g = 5;
+/// \endcode
+///
+/// \c lValueReferenceType() matches the types of \c b, \c d, and \c e. \c e is
+/// matched since the type is deduced as int& by reference collapsing rules.
+AST_TYPE_MATCHER(LValueReferenceType, lValueReferenceType);
+
+/// \brief Matches rvalue reference types.
+///
+/// Given:
+/// \code
+/// int *a;
+/// int &b = *a;
+/// int &&c = 1;
+/// auto &d = b;
+/// auto &&e = c;
+/// auto &&f = 2;
+/// int g = 5;
+/// \endcode
+///
+/// \c rValueReferenceType() matches the types of \c c and \c f. \c e is not
+/// matched as it is deduced to int& by reference collapsing rules.
+AST_TYPE_MATCHER(RValueReferenceType, rValueReferenceType);
+
/// \brief Narrows PointerType (and similar) matchers to those where the
/// \c pointee matches a given matcher.
///
@@ -2751,11 +3041,116 @@ AST_TYPELOC_TRAVERSE_MATCHER(pointee, getPointee);
/// 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 template specialization types.
+///
+/// Given
+/// \code
+/// template <typename T>
+/// class C { };
+///
+/// template class C<int>; // A
+/// C<char> var; // B
+/// \code
+///
+/// \c templateSpecializationType() matches the type of the explicit
+/// instantiation in \c A and the type of the variable declaration in \c B.
+AST_TYPE_MATCHER(TemplateSpecializationType, templateSpecializationType);
+
+/// \brief Matches record types (e.g. structs, classes).
+///
+/// Given
+/// \code
+/// class C {};
+/// struct S {};
+///
+/// C c;
+/// S s;
+/// \code
+///
+/// \c recordType() matches the type of the variable declarations of both \c c
+/// and \c s.
+AST_TYPE_MATCHER(RecordType, recordType);
+
+/// \brief Matches types specified with an elaborated type keyword or with a
+/// qualified name.
+///
+/// Given
+/// \code
+/// namespace N {
+/// namespace M {
+/// class D {};
+/// }
+/// }
+/// class C {};
+///
+/// class C c;
+/// N::M::D d;
+/// \code
+///
+/// \c elaboratedType() matches the type of the variable declarations of both
+/// \c c and \c d.
+AST_TYPE_MATCHER(ElaboratedType, elaboratedType);
+
+/// \brief Matches ElaboratedTypes whose qualifier, a NestedNameSpecifier,
+/// matches \c InnerMatcher if the qualifier exists.
+///
+/// Given
+/// \code
+/// namespace N {
+/// namespace M {
+/// class D {};
+/// }
+/// }
+/// N::M::D d;
+/// \code
+///
+/// \c elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N"))))
+/// matches the type of the variable declaration of \c d.
+AST_MATCHER_P(ElaboratedType, hasQualifier,
+ internal::Matcher<NestedNameSpecifier>, InnerMatcher) {
+ if (const NestedNameSpecifier *Qualifier = Node.getQualifier())
+ return InnerMatcher.matches(*Qualifier, Finder, Builder);
+
+ return false;
+}
+
+/// \brief Matches ElaboratedTypes whose named type matches \c InnerMatcher.
+///
+/// Given
+/// \code
+/// namespace N {
+/// namespace M {
+/// class D {};
+/// }
+/// }
+/// N::M::D d;
+/// \code
+///
+/// \c elaboratedType(namesType(recordType(
+/// hasDeclaration(namedDecl(hasName("D")))))) matches the type of the variable
+/// declaration of \c d.
+AST_MATCHER_P(ElaboratedType, namesType, internal::Matcher<QualType>,
+ InnerMatcher) {
+ return InnerMatcher.matches(Node.getNamedType(), Finder, Builder);
+}
+
+/// \brief Matches declarations whose declaration context, interpreted as a
+/// Decl, matches \c InnerMatcher.
+///
+/// Given
+/// \code
+/// namespace N {
+/// namespace M {
+/// class D {};
+/// }
+/// }
+/// \code
+///
+/// \c recordDecl(hasDeclContext(namedDecl(hasName("M")))) matches the
+/// declaration of \c class \c D.
+AST_MATCHER_P(Decl, hasDeclContext, internal::Matcher<Decl>, InnerMatcher) {
+ return InnerMatcher.matches(*Decl::castFromDeclContext(Node.getDeclContext()),
+ Finder, Builder);
}
/// \brief Matches nested name specifiers.
@@ -2828,10 +3223,13 @@ AST_MATCHER_P(NestedNameSpecifierLoc, specifiesTypeLoc,
/// \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));
+AST_MATCHER_P_OVERLOAD(NestedNameSpecifier, hasPrefix,
+ internal::Matcher<NestedNameSpecifier>, InnerMatcher,
+ 0) {
+ NestedNameSpecifier *NextNode = Node.getPrefix();
+ if (NextNode == NULL)
+ return false;
+ return InnerMatcher.matches(*NextNode, Finder, Builder);
}
/// \brief Matches on the prefix of a \c NestedNameSpecifierLoc.
@@ -2843,10 +3241,13 @@ inline internal::Matcher<NestedNameSpecifier> hasPrefix(
/// \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));
+AST_MATCHER_P_OVERLOAD(NestedNameSpecifierLoc, hasPrefix,
+ internal::Matcher<NestedNameSpecifierLoc>, InnerMatcher,
+ 1) {
+ NestedNameSpecifierLoc NextNode = Node.getPrefix();
+ if (!NextNode)
+ return false;
+ return InnerMatcher.matches(NextNode, Finder, Builder);
}
/// \brief Matches nested name specifiers that specify a namespace matching the
@@ -2866,6 +3267,26 @@ AST_MATCHER_P(NestedNameSpecifier, specifiesNamespace,
return InnerMatcher.matches(*Node.getAsNamespace(), Finder, Builder);
}
+/// \brief Overloads for the \c equalsNode matcher.
+/// FIXME: Implement for other node types.
+/// @{
+
+/// \brief Matches if a node equals another node.
+///
+/// \c Decl has pointer identity in the AST.
+AST_MATCHER_P_OVERLOAD(Decl, equalsNode, Decl*, Other, 0) {
+ return &Node == Other;
+}
+/// \brief Matches if a node equals another node.
+///
+/// \c Stmt has pointer identity in the AST.
+///
+AST_MATCHER_P_OVERLOAD(Stmt, equalsNode, Stmt*, Other, 1) {
+ return &Node == Other;
+}
+
+/// @}
+
} // end namespace ast_matchers
} // end namespace clang
diff --git a/include/clang/ASTMatchers/ASTMatchersInternal.h b/include/clang/ASTMatchers/ASTMatchersInternal.h
index e5365ff89d72..30691ad8f912 100644
--- a/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ b/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -35,13 +35,13 @@
#ifndef LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_INTERNAL_H
#define LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_INTERNAL_H
-#include "clang/AST/Decl.h"
+#include "clang/AST/ASTTypeTraits.h"
#include "clang/AST/DeclCXX.h"
+#include "clang/AST/Decl.h"
#include "clang/AST/ExprCXX.h"
-#include "clang/AST/Stmt.h"
#include "clang/AST/StmtCXX.h"
+#include "clang/AST/Stmt.h"
#include "clang/AST/Type.h"
-#include "clang/ASTMatchers/ASTTypeTraits.h"
#include "llvm/ADT/VariadicFunction.h"
#include "llvm/Support/type_traits.h"
#include <map>
@@ -193,7 +193,7 @@ class ASTMatchFinder;
/// current node and doesn't care about its children or descendants,
/// implement SingleNodeMatcherInterface instead.
template <typename T>
-class MatcherInterface : public llvm::RefCountedBaseVPTR {
+class MatcherInterface : public RefCountedBaseVPTR {
public:
virtual ~MatcherInterface() {}
@@ -343,7 +343,7 @@ private:
const Matcher<Base> From;
};
- llvm::IntrusiveRefCntPtr< MatcherInterface<T> > Implementation;
+ IntrusiveRefCntPtr< MatcherInterface<T> > Implementation;
}; // class Matcher
/// \brief A convenient helper for creating a Matcher<T> without specifying
@@ -353,6 +353,61 @@ inline Matcher<T> makeMatcher(MatcherInterface<T> *Implementation) {
return Matcher<T>(Implementation);
}
+/// \brief Metafunction to determine if type T has a member called getDecl.
+template <typename T> struct has_getDecl {
+ struct Default { int getDecl; };
+ struct Derived : T, Default { };
+
+ template<typename C, C> struct CheckT;
+
+ // If T::getDecl exists, an ambiguity arises and CheckT will
+ // not be instantiable. This makes f(...) the only available
+ // overload.
+ template<typename C>
+ static char (&f(CheckT<int Default::*, &C::getDecl>*))[1];
+ template<typename C> static char (&f(...))[2];
+
+ static bool const value = sizeof(f<Derived>(0)) == 2;
+};
+
+/// \brief Matches overloaded operators with a specific name.
+///
+/// The type argument ArgT is not used by this matcher but is used by
+/// PolymorphicMatcherWithParam1 and should be StringRef.
+template <typename T, typename ArgT>
+class HasOverloadedOperatorNameMatcher : public SingleNodeMatcherInterface<T> {
+ TOOLING_COMPILE_ASSERT((llvm::is_same<T, CXXOperatorCallExpr>::value ||
+ llvm::is_same<T, CXXMethodDecl>::value),
+ unsupported_class_for_matcher);
+ TOOLING_COMPILE_ASSERT((llvm::is_same<ArgT, StringRef>::value),
+ argument_type_must_be_StringRef);
+public:
+ explicit HasOverloadedOperatorNameMatcher(const StringRef Name)
+ : SingleNodeMatcherInterface<T>(), Name(Name) {}
+
+ virtual bool matchesNode(const T &Node) const LLVM_OVERRIDE {
+ return matchesSpecialized(Node);
+ }
+
+private:
+
+ /// \brief CXXOperatorCallExpr exist only for calls to overloaded operators
+ /// so this function returns true if the call is to an operator of the given
+ /// name.
+ bool matchesSpecialized(const CXXOperatorCallExpr &Node) const {
+ return getOperatorSpelling(Node.getOperator()) == Name;
+ }
+
+ /// \brief Returns true only if CXXMethodDecl represents an overloaded
+ /// operator and has the given operator name.
+ bool matchesSpecialized(const CXXMethodDecl &Node) const {
+ return Node.isOverloadedOperator() &&
+ getOperatorSpelling(Node.getOverloadedOperator()) == Name;
+ }
+
+ std::string Name;
+};
+
/// \brief Matches declarations for QualType and CallExpr.
///
/// Type argument DeclMatcherT is required by PolymorphicMatcherWithParam1 but
@@ -373,16 +428,36 @@ public:
}
private:
- /// \brief Extracts the CXXRecordDecl of a QualType and returns whether the
- /// inner matcher matches on it.
+ /// \brief If getDecl exists as a member of U, returns whether the inner
+ /// matcher matches Node.getDecl().
+ template <typename U>
+ bool matchesSpecialized(
+ const U &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
+ typename llvm::enable_if<has_getDecl<U>, int>::type = 0) const {
+ return matchesDecl(Node.getDecl(), Finder, Builder);
+ }
+
+ /// \brief Extracts the CXXRecordDecl or EnumDecl of a QualType and returns
+ /// whether the inner matcher matches on it.
bool matchesSpecialized(const QualType &Node, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const {
/// FIXME: Add other ways to convert...
if (Node.isNull())
return false;
+ if (const EnumType *AsEnum = dyn_cast<EnumType>(Node.getTypePtr()))
+ return matchesDecl(AsEnum->getDecl(), Finder, Builder);
return matchesDecl(Node->getAsCXXRecordDecl(), Finder, Builder);
}
+ /// \brief Gets the TemplateDecl from a TemplateSpecializationType
+ /// and returns whether the inner matches on it.
+ bool matchesSpecialized(const TemplateSpecializationType &Node,
+ ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const {
+ return matchesDecl(Node.getTemplateName().getAsTemplateDecl(),
+ 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,
@@ -537,6 +612,8 @@ public:
Matcher, Builder, MatchMode);
}
+ virtual ASTContext &getASTContext() const = 0;
+
protected:
virtual bool matchesChildOf(const ast_type_traits::DynTypedNode &Node,
const DynTypedMatcher &Matcher,
@@ -672,7 +749,7 @@ public:
virtual bool matches(const T &Node,
ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const {
- const To *InnerMatchValue = llvm::dyn_cast<To>(&Node);
+ const To *InnerMatchValue = dyn_cast<To>(&Node);
return InnerMatchValue != NULL &&
InnerMatcher.matches(*InnerMatchValue, Finder, Builder);
}
@@ -828,21 +905,56 @@ private:
/// used. They will always be instantiated with types convertible to
/// Matcher<T>.
template <typename T, typename MatcherT1, typename MatcherT2>
+class EachOfMatcher : public MatcherInterface<T> {
+public:
+ EachOfMatcher(const Matcher<T> &InnerMatcher1,
+ const Matcher<T> &InnerMatcher2)
+ : InnerMatcher1(InnerMatcher1), InnerMatcher2(InnerMatcher2) {
+ }
+
+ virtual bool matches(const T &Node, ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const {
+ BoundNodesTreeBuilder Builder1;
+ bool Matched1 = InnerMatcher1.matches(Node, Finder, &Builder1);
+ if (Matched1)
+ Builder->addMatch(Builder1.build());
+
+ BoundNodesTreeBuilder Builder2;
+ bool Matched2 = InnerMatcher2.matches(Node, Finder, &Builder2);
+ if (Matched2)
+ Builder->addMatch(Builder2.build());
+
+ return Matched1 || Matched2;
+ }
+
+private:
+ const Matcher<T> InnerMatcher1;
+ const Matcher<T> InnerMatcher2;
+};
+
+/// \brief Matches nodes of type T for which at least one of the two provided
+/// matchers matches.
+///
+/// Type arguments MatcherT1 and MatcherT2 are
+/// required by PolymorphicMatcherWithParam2 but not actually
+/// used. They will always be instantiated with types convertible to
+/// Matcher<T>.
+template <typename T, typename MatcherT1, typename MatcherT2>
class AnyOfMatcher : public MatcherInterface<T> {
public:
AnyOfMatcher(const Matcher<T> &InnerMatcher1, const Matcher<T> &InnerMatcher2)
- : InnerMatcher1(InnerMatcher1), InnertMatcher2(InnerMatcher2) {}
+ : InnerMatcher1(InnerMatcher1), InnerMatcher2(InnerMatcher2) {}
virtual bool matches(const T &Node,
ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const {
return InnerMatcher1.matches(Node, Finder, Builder) ||
- InnertMatcher2.matches(Node, Finder, Builder);
+ InnerMatcher2.matches(Node, Finder, Builder);
}
private:
const Matcher<T> InnerMatcher1;
- const Matcher<T> InnertMatcher2;
+ const Matcher<T> InnerMatcher2;
};
/// \brief Creates a Matcher<T> that matches if all inner matchers match.
@@ -989,69 +1101,6 @@ private:
const ValueT ExpectedValue;
};
-template <typename T>
-class IsDefinitionMatcher : public SingleNodeMatcherInterface<T> {
- TOOLING_COMPILE_ASSERT(
- (llvm::is_base_of<TagDecl, T>::value) ||
- (llvm::is_base_of<VarDecl, T>::value) ||
- (llvm::is_base_of<FunctionDecl, T>::value),
- is_definition_requires_isThisDeclarationADefinition_method);
-public:
- virtual bool matchesNode(const T &Node) const {
- return Node.isThisDeclarationADefinition();
- }
-};
-
-/// \brief Matches on template instantiations for FunctionDecl, VarDecl or
-/// CXXRecordDecl nodes.
-template <typename T>
-class IsTemplateInstantiationMatcher : 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_ImplicitInstantiation ||
- Node.getTemplateSpecializationKind() ==
- TSK_ExplicitInstantiationDefinition);
- }
-};
-
-/// \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 {
- return Node.isArrow();
- }
-};
-
-class IsConstQualifiedMatcher
- : public SingleNodeMatcherInterface<QualType> {
- public:
- virtual bool matchesNode(const QualType& Node) const {
- return Node.isConstQualified();
- }
-};
-
/// \brief A VariadicDynCastAllOfMatcher<SourceT, TargetT> object is a
/// variadic functor that takes a number of Matcher<TargetT> and returns a
/// Matcher<SourceT> that matches TargetT nodes that are matched by all of the
@@ -1115,50 +1164,6 @@ private:
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.
///
diff --git a/include/clang/ASTMatchers/ASTMatchersMacros.h b/include/clang/ASTMatchers/ASTMatchersMacros.h
index 953abc2a2ec9..f5ca26bca73c 100644
--- a/include/clang/ASTMatchers/ASTMatchersMacros.h
+++ b/include/clang/ASTMatchers/ASTMatchersMacros.h
@@ -49,21 +49,23 @@
///
/// The code should return true if 'Node' matches.
#define AST_MATCHER(Type, DefineMatcher) \
+ AST_MATCHER_OVERLOAD(Type, DefineMatcher, 0)
+
+#define AST_MATCHER_OVERLOAD(Type, DefineMatcher, OverloadId) \
namespace internal { \
- class matcher_##DefineMatcher##Matcher \
+ class matcher_##DefineMatcher##OverloadId##Matcher \
: public MatcherInterface<Type> { \
- public: \
- explicit matcher_##DefineMatcher##Matcher() {} \
- virtual bool matches( \
- const Type &Node, ASTMatchFinder *Finder, \
- BoundNodesTreeBuilder *Builder) const; \
+ public: \
+ explicit matcher_##DefineMatcher##OverloadId##Matcher() {} \
+ virtual bool matches(const Type &Node, ASTMatchFinder *Finder, \
+ BoundNodesTreeBuilder *Builder) const; \
}; \
} \
inline internal::Matcher<Type> DefineMatcher() { \
return internal::makeMatcher( \
- new internal::matcher_##DefineMatcher##Matcher()); \
+ new internal::matcher_##DefineMatcher##OverloadId##Matcher()); \
} \
- inline bool internal::matcher_##DefineMatcher##Matcher::matches( \
+ inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
const Type &Node, ASTMatchFinder *Finder, \
BoundNodesTreeBuilder *Builder) const
@@ -81,24 +83,29 @@
///
/// The code should return true if 'Node' matches.
#define AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) \
+ AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param, 0)
+
+#define AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param, \
+ OverloadId) \
namespace internal { \
- class matcher_##DefineMatcher##Matcher \
+ class matcher_##DefineMatcher##OverloadId##Matcher \
: public MatcherInterface<Type> { \
- public: \
- explicit matcher_##DefineMatcher##Matcher( \
- const ParamType &A##Param) : Param(A##Param) {} \
- virtual bool matches( \
- const Type &Node, ASTMatchFinder *Finder, \
- BoundNodesTreeBuilder *Builder) const; \
- private: \
+ public: \
+ explicit matcher_##DefineMatcher##OverloadId##Matcher( \
+ const ParamType &A##Param) \
+ : Param(A##Param) { \
+ } \
+ virtual bool matches(const Type &Node, ASTMatchFinder *Finder, \
+ BoundNodesTreeBuilder *Builder) const; \
+ private: \
const ParamType Param; \
}; \
} \
inline internal::Matcher<Type> DefineMatcher(const ParamType &Param) { \
return internal::makeMatcher( \
- new internal::matcher_##DefineMatcher##Matcher(Param)); \
+ new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param)); \
} \
- inline bool internal::matcher_##DefineMatcher##Matcher::matches( \
+ inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
const Type &Node, ASTMatchFinder *Finder, \
BoundNodesTreeBuilder *Builder) const
@@ -116,33 +123,67 @@
/// Builder: a BoundNodesTreeBuilder*.
///
/// The code should return true if 'Node' matches.
-#define AST_MATCHER_P2( \
- Type, DefineMatcher, ParamType1, Param1, ParamType2, Param2) \
+#define AST_MATCHER_P2(Type, DefineMatcher, ParamType1, Param1, ParamType2, \
+ Param2) \
+ AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1, ParamType2, \
+ Param2, 0)
+
+#define AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1, \
+ ParamType2, Param2, OverloadId) \
namespace internal { \
- class matcher_##DefineMatcher##Matcher \
+ class matcher_##DefineMatcher##OverloadId##Matcher \
: public MatcherInterface<Type> { \
- public: \
- matcher_##DefineMatcher##Matcher( \
- const ParamType1 &A##Param1, const ParamType2 &A##Param2) \
- : Param1(A##Param1), Param2(A##Param2) {} \
- virtual bool matches( \
- const Type &Node, ASTMatchFinder *Finder, \
- BoundNodesTreeBuilder *Builder) const; \
- private: \
+ public: \
+ matcher_##DefineMatcher##OverloadId##Matcher(const ParamType1 &A##Param1, \
+ const ParamType2 &A##Param2) \
+ : Param1(A##Param1), Param2(A##Param2) { \
+ } \
+ virtual bool matches(const Type &Node, ASTMatchFinder *Finder, \
+ BoundNodesTreeBuilder *Builder) const; \
+ private: \
const ParamType1 Param1; \
const ParamType2 Param2; \
}; \
} \
- inline internal::Matcher<Type> DefineMatcher( \
- const ParamType1 &Param1, const ParamType2 &Param2) { \
+ inline internal::Matcher<Type> \
+ DefineMatcher(const ParamType1 &Param1, const ParamType2 &Param2) { \
return internal::makeMatcher( \
- new internal::matcher_##DefineMatcher##Matcher( \
- Param1, Param2)); \
+ new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param1, \
+ Param2)); \
} \
- inline bool internal::matcher_##DefineMatcher##Matcher::matches( \
+ inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
const Type &Node, ASTMatchFinder *Finder, \
BoundNodesTreeBuilder *Builder) const
+/// \brief AST_POLYMORPHIC_MATCHER(DefineMatcher) { ... }
+/// defines a single-parameter function named DefineMatcher() that is
+/// polymorphic in the return type.
+///
+/// The variables are the same as for AST_MATCHER, but NodeType will be deduced
+/// from the calling context.
+#define AST_POLYMORPHIC_MATCHER(DefineMatcher) \
+ AST_POLYMORPHIC_MATCHER_OVERLOAD(DefineMatcher, 0)
+
+#define AST_POLYMORPHIC_MATCHER_OVERLOAD(DefineMatcher, OverloadId) \
+ namespace internal { \
+ template <typename NodeType> \
+ class matcher_##DefineMatcher##OverloadId##Matcher \
+ : public MatcherInterface<NodeType> { \
+ public: \
+ virtual bool matches(const NodeType &Node, ASTMatchFinder *Finder, \
+ BoundNodesTreeBuilder *Builder) const; \
+ }; \
+ } \
+ inline internal::PolymorphicMatcherWithParam0< \
+ internal::matcher_##DefineMatcher##OverloadId##Matcher> DefineMatcher() {\
+ return internal::PolymorphicMatcherWithParam0< \
+ internal::matcher_##DefineMatcher##OverloadId##Matcher>(); \
+ } \
+ template <typename NodeType> \
+ bool internal::matcher_##DefineMatcher##OverloadId##Matcher< \
+ NodeType>::matches(const NodeType &Node, ASTMatchFinder *Finder, \
+ BoundNodesTreeBuilder *Builder) const
+
/// \brief AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ParamType, Param) { ... }
/// defines a single-parameter function named DefineMatcher() that is
/// polymorphic in the return type.
@@ -153,32 +194,36 @@
///
/// FIXME: Pull out common code with above macro?
#define AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ParamType, Param) \
+ AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ParamType, Param, 0)
+
+#define AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ParamType, Param, \
+ OverloadId) \
namespace internal { \
template <typename NodeType, typename ParamT> \
- class matcher_##DefineMatcher##Matcher \
+ class matcher_##DefineMatcher##OverloadId##Matcher \
: public MatcherInterface<NodeType> { \
- public: \
- explicit matcher_##DefineMatcher##Matcher( \
- const ParamType &A##Param) : Param(A##Param) {} \
- virtual bool matches( \
- const NodeType &Node, ASTMatchFinder *Finder, \
- BoundNodesTreeBuilder *Builder) const; \
- private: \
+ public: \
+ explicit matcher_##DefineMatcher##OverloadId##Matcher( \
+ const ParamType &A##Param) \
+ : Param(A##Param) { \
+ } \
+ virtual bool matches(const NodeType &Node, ASTMatchFinder *Finder, \
+ BoundNodesTreeBuilder *Builder) const; \
+ private: \
const ParamType Param; \
}; \
} \
inline internal::PolymorphicMatcherWithParam1< \
- internal::matcher_##DefineMatcher##Matcher, \
- ParamType > \
- DefineMatcher(const ParamType &Param) { \
+ internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType> \
+ DefineMatcher(const ParamType &Param) { \
return internal::PolymorphicMatcherWithParam1< \
- internal::matcher_##DefineMatcher##Matcher, \
- ParamType >(Param); \
+ internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType>( \
+ Param); \
} \
template <typename NodeType, typename ParamT> \
- bool internal::matcher_##DefineMatcher##Matcher<NodeType, ParamT>::matches( \
- const NodeType &Node, ASTMatchFinder *Finder, \
- BoundNodesTreeBuilder *Builder) const
+ bool internal::matcher_##DefineMatcher##OverloadId##Matcher< \
+ NodeType, ParamT>::matches(const NodeType &Node, ASTMatchFinder *Finder, \
+ BoundNodesTreeBuilder *Builder) const
/// \brief AST_POLYMORPHIC_MATCHER_P2(
/// DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... }
@@ -188,35 +233,39 @@
/// The variables are the same as for AST_MATCHER_P2, with the
/// addition of NodeType, which specifies the node type of the matcher
/// Matcher<NodeType> returned by the function DefineMatcher().
-#define AST_POLYMORPHIC_MATCHER_P2( \
- DefineMatcher, ParamType1, Param1, ParamType2, Param2) \
+#define AST_POLYMORPHIC_MATCHER_P2(DefineMatcher, ParamType1, Param1, \
+ ParamType2, Param2) \
+ AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ParamType1, Param1, \
+ ParamType2, Param2, 0)
+
+#define AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ParamType1, Param1, \
+ ParamType2, Param2, OverloadId) \
namespace internal { \
template <typename NodeType, typename ParamT1, typename ParamT2> \
- class matcher_##DefineMatcher##Matcher \
+ class matcher_##DefineMatcher##OverloadId##Matcher \
: public MatcherInterface<NodeType> { \
- public: \
- matcher_##DefineMatcher##Matcher( \
- const ParamType1 &A##Param1, const ParamType2 &A##Param2) \
- : Param1(A##Param1), Param2(A##Param2) {} \
- virtual bool matches( \
- const NodeType &Node, ASTMatchFinder *Finder, \
- BoundNodesTreeBuilder *Builder) const; \
- private: \
+ public: \
+ matcher_##DefineMatcher##OverloadId##Matcher(const ParamType1 &A##Param1, \
+ const ParamType2 &A##Param2) \
+ : Param1(A##Param1), Param2(A##Param2) { \
+ } \
+ virtual bool matches(const NodeType &Node, ASTMatchFinder *Finder, \
+ BoundNodesTreeBuilder *Builder) const; \
+ private: \
const ParamType1 Param1; \
const ParamType2 Param2; \
}; \
} \
inline internal::PolymorphicMatcherWithParam2< \
- internal::matcher_##DefineMatcher##Matcher, \
- ParamType1, ParamType2 > \
- DefineMatcher(const ParamType1 &Param1, const ParamType2 &Param2) { \
+ internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \
+ ParamType2> \
+ DefineMatcher(const ParamType1 &Param1, const ParamType2 &Param2) { \
return internal::PolymorphicMatcherWithParam2< \
- internal::matcher_##DefineMatcher##Matcher, \
- ParamType1, ParamType2 >( \
- Param1, Param2); \
+ internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \
+ ParamType2>(Param1, Param2); \
} \
template <typename NodeType, typename ParamT1, typename ParamT2> \
- bool internal::matcher_##DefineMatcher##Matcher< \
+ bool internal::matcher_##DefineMatcher##OverloadId##Matcher< \
NodeType, ParamT1, ParamT2>::matches( \
const NodeType &Node, ASTMatchFinder *Finder, \
BoundNodesTreeBuilder *Builder) const
@@ -224,9 +273,9 @@
/// \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
+ const internal::VariadicDynCastAllOfMatcher<Type, NodeType> MatcherName
+// FIXME: add a matcher for TypeLoc derived classes using its custom casting
+// API (no longer dyn_cast) if/when we need such matching
/// \brief AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) defines
/// the matcher \c MatcherName that can be used to traverse from one \c Type
@@ -236,54 +285,61 @@
/// \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)); \
+ 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; \
} \
-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
+ ; \
+ 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)); \
+ 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() { \
+ } \
} \
-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)
+ ; \
+ 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/Analysis/Analyses/Dominators.h b/include/clang/Analysis/Analyses/Dominators.h
index e9a431a991a1..2a806c8befda 100644
--- a/include/clang/Analysis/Analyses/Dominators.h
+++ b/include/clang/Analysis/Analyses/Dominators.h
@@ -15,12 +15,11 @@
#define LLVM_CLANG_DOMINATORS_H
#include "clang/Analysis/AnalysisContext.h"
-
-#include "llvm/Module.h"
-#include "llvm/ADT/GraphTraits.h"
#include "clang/Analysis/CFG.h"
-#include "llvm/Analysis/Dominators.h"
+#include "llvm/ADT/GraphTraits.h"
#include "llvm/Analysis/DominatorInternals.h"
+#include "llvm/Analysis/Dominators.h"
+#include "llvm/IR/Module.h"
namespace clang {
diff --git a/include/clang/Analysis/Analyses/FormatString.h b/include/clang/Analysis/Analyses/FormatString.h
index 5cb973122d72..4bd989cf4ef3 100644
--- a/include/clang/Analysis/Analyses/FormatString.h
+++ b/include/clang/Analysis/Analyses/FormatString.h
@@ -201,7 +201,7 @@ public:
bool isPrintfKind() const { return IsPrintf; }
- llvm::Optional<ConversionSpecifier> getStandardSpecifier() const;
+ Optional<ConversionSpecifier> getStandardSpecifier() const;
protected:
bool IsPrintf;
@@ -361,7 +361,7 @@ public:
bool hasStandardLengthModifier() const;
- llvm::Optional<LengthModifier> getCorrectedLengthModifier() const;
+ Optional<LengthModifier> getCorrectedLengthModifier() const;
bool hasStandardConversionSpecifier(const LangOptions &LangOpt) const;
diff --git a/include/clang/Analysis/Analyses/LiveVariables.h b/include/clang/Analysis/Analyses/LiveVariables.h
index c9f39b46b98e..bbd2b02e8256 100644
--- a/include/clang/Analysis/Analyses/LiveVariables.h
+++ b/include/clang/Analysis/Analyses/LiveVariables.h
@@ -14,8 +14,8 @@
#ifndef LLVM_CLANG_LIVEVARIABLES_H
#define LLVM_CLANG_LIVEVARIABLES_H
-#include "clang/Analysis/AnalysisContext.h"
#include "clang/AST/Decl.h"
+#include "clang/Analysis/AnalysisContext.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/ImmutableSet.h"
diff --git a/include/clang/Analysis/Analyses/ThreadSafety.h b/include/clang/Analysis/Analyses/ThreadSafety.h
index ef6b821e390b..8a888e633322 100644
--- a/include/clang/Analysis/Analyses/ThreadSafety.h
+++ b/include/clang/Analysis/Analyses/ThreadSafety.h
@@ -29,24 +29,24 @@ namespace thread_safety {
/// This enum distinguishes between different kinds of operations that may
/// need to be protected by locks. We use this enum in error handling.
enum ProtectedOperationKind {
- POK_VarDereference, /// Dereferencing a variable (e.g. p in *p = 5;)
- POK_VarAccess, /// Reading or writing a variable (e.g. x in x = 5;)
- POK_FunctionCall /// Making a function call (e.g. fool())
+ POK_VarDereference, ///< Dereferencing a variable (e.g. p in *p = 5;)
+ POK_VarAccess, ///< Reading or writing a variable (e.g. x in x = 5;)
+ POK_FunctionCall ///< Making a function call (e.g. fool())
};
/// This enum distinguishes between different kinds of lock actions. For
/// example, it is an error to write a variable protected by shared version of a
/// mutex.
enum LockKind {
- LK_Shared, /// Shared/reader lock of a mutex
- LK_Exclusive /// Exclusive/writer lock of a mutex
+ LK_Shared, ///< Shared/reader lock of a mutex.
+ LK_Exclusive ///< Exclusive/writer lock of a mutex.
};
/// This enum distinguishes between different ways to access (read or write) a
/// variable.
enum AccessKind {
- AK_Read, /// Reading a variable
- AK_Written /// Writing a variable
+ AK_Read, ///< Reading a variable.
+ AK_Written ///< Writing a variable.
};
/// This enum distinguishes between different situations where we warn due to
@@ -67,7 +67,8 @@ enum LockErrorKind {
/// Handler class for thread safety warnings.
class ThreadSafetyHandler {
public:
- typedef llvm::StringRef Name;
+ typedef StringRef Name;
+ ThreadSafetyHandler() : IssueBetaWarnings(false) { }
virtual ~ThreadSafetyHandler();
/// Warn about lock expressions which fail to resolve to lockable objects.
@@ -143,6 +144,12 @@ public:
/// \param Loc -- The location of the function call.
virtual void handleFunExcludesLock(Name FunName, Name LockName,
SourceLocation Loc) {}
+
+ bool issueBetaWarnings() { return IssueBetaWarnings; }
+ void setIssueBetaWarnings(bool b) { IssueBetaWarnings = b; }
+
+private:
+ bool IssueBetaWarnings;
};
/// \brief Check a function's CFG for thread-safety violations.
diff --git a/include/clang/Analysis/Analyses/UninitializedValues.h b/include/clang/Analysis/Analyses/UninitializedValues.h
index 45ce4de1f8dd..e8810c32a140 100644
--- a/include/clang/Analysis/Analyses/UninitializedValues.h
+++ b/include/clang/Analysis/Analyses/UninitializedValues.h
@@ -15,6 +15,7 @@
#ifndef LLVM_CLANG_UNINIT_VALS_H
#define LLVM_CLANG_UNINIT_VALS_H
+#include "clang/AST/Stmt.h"
#include "llvm/ADT/SmallVector.h"
namespace clang {
@@ -42,7 +43,7 @@ private:
/// This use is always uninitialized if it occurs after any of these branches
/// is taken.
- llvm::SmallVector<Branch, 2> UninitBranches;
+ SmallVector<Branch, 2> UninitBranches;
public:
UninitUse(const Expr *User, bool AlwaysUninit) :
@@ -71,7 +72,7 @@ public:
!branch_empty() ? Sometimes : Maybe;
}
- typedef llvm::SmallVectorImpl<Branch>::const_iterator branch_iterator;
+ typedef SmallVectorImpl<Branch>::const_iterator branch_iterator;
/// Branches which inevitably result in the variable being used uninitialized.
branch_iterator branch_begin() const { return UninitBranches.begin(); }
branch_iterator branch_end() const { return UninitBranches.end(); }
diff --git a/include/clang/Analysis/AnalysisContext.h b/include/clang/Analysis/AnalysisContext.h
index 52466786b341..46d7d07e0907 100644
--- a/include/clang/Analysis/AnalysisContext.h
+++ b/include/clang/Analysis/AnalysisContext.h
@@ -18,11 +18,11 @@
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
#include "clang/Analysis/CFG.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/PointerUnion.h"
-#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/Allocator.h"
namespace clang {
@@ -133,7 +133,21 @@ public:
void registerForcedBlockExpression(const Stmt *stmt);
const CFGBlock *getBlockForRegisteredExpression(const Stmt *stmt);
+ /// \brief Get the body of the Declaration.
Stmt *getBody() const;
+
+ /// \brief Get the body of the Declaration.
+ /// \param[out] IsAutosynthesized Specifies if the body is auto-generated
+ /// by the BodyFarm.
+ Stmt *getBody(bool &IsAutosynthesized) const;
+
+ /// \brief Checks if the body of the Decl is generated by the BodyFarm.
+ ///
+ /// Note, the lookup is not free. We are going to call getBody behind
+ /// the scenes.
+ /// \sa getBody
+ bool isBodyAutosynthesized() const;
+
CFG *getCFG();
CFGStmtMap *getCFGStmtMap();
@@ -242,6 +256,8 @@ public:
virtual void Profile(llvm::FoldingSetNodeID &ID) = 0;
+ LLVM_ATTRIBUTE_USED void dumpStack() const;
+
public:
static void ProfileCommon(llvm::FoldingSetNodeID &ID,
ContextKind ck,
@@ -396,7 +412,8 @@ public:
bool addImplicitDtors = false,
bool addInitializers = false,
bool addTemporaryDtors = false,
- bool synthesizeBodies = false);
+ bool synthesizeBodies = false,
+ bool addStaticInitBranches = false);
~AnalysisDeclContextManager();
diff --git a/include/clang/Analysis/CFG.h b/include/clang/Analysis/CFG.h
index 8cc5d814e822..ee0be736dd5e 100644
--- a/include/clang/Analysis/CFG.h
+++ b/include/clang/Analysis/CFG.h
@@ -15,15 +15,16 @@
#ifndef LLVM_CLANG_CFG_H
#define LLVM_CLANG_CFG_H
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/ADT/GraphTraits.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/ADT/DenseMap.h"
#include "clang/AST/Stmt.h"
#include "clang/Analysis/Support/BumpVector.h"
#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Casting.h"
#include <bitset>
#include <cassert>
#include <iterator>
@@ -48,7 +49,6 @@ class CFGElement {
public:
enum Kind {
// main kind
- Invalid,
Statement,
Initializer,
// dtor kind
@@ -69,8 +69,31 @@ protected:
: Data1(const_cast<void*>(Ptr1), ((unsigned) kind) & 0x3),
Data2(const_cast<void*>(Ptr2), (((unsigned) kind) >> 2) & 0x3) {}
-public:
CFGElement() {}
+public:
+
+ /// \brief Convert to the specified CFGElement type, asserting that this
+ /// CFGElement is of the desired type.
+ template<typename T>
+ T castAs() const {
+ assert(T::isKind(*this));
+ T t;
+ CFGElement& e = t;
+ e = *this;
+ return t;
+ }
+
+ /// \brief Convert to the specified CFGElement type, returning None if this
+ /// CFGElement is not of the desired type.
+ template<typename T>
+ Optional<T> getAs() const {
+ if (!T::isKind(*this))
+ return None;
+ T t;
+ CFGElement& e = t;
+ e = *this;
+ return t;
+ }
Kind getKind() const {
unsigned x = Data2.getInt();
@@ -78,16 +101,6 @@ public:
x |= Data1.getInt();
return (Kind) x;
}
-
- bool isValid() const { return getKind() != Invalid; }
-
- operator bool() const { return isValid(); }
-
- template<class ElemTy> const ElemTy *getAs() const {
- if (llvm::isa<ElemTy>(this))
- return static_cast<const ElemTy*>(this);
- return 0;
- }
};
class CFGStmt : public CFGElement {
@@ -98,8 +111,11 @@ public:
return static_cast<const Stmt *>(Data1.getPointer());
}
- static bool classof(const CFGElement *E) {
- return E->getKind() == Statement;
+private:
+ friend class CFGElement;
+ CFGStmt() {}
+ static bool isKind(const CFGElement &E) {
+ return E.getKind() == Statement;
}
};
@@ -114,8 +130,11 @@ public:
return static_cast<CXXCtorInitializer*>(Data1.getPointer());
}
- static bool classof(const CFGElement *E) {
- return E->getKind() == Initializer;
+private:
+ friend class CFGElement;
+ CFGInitializer() {}
+ static bool isKind(const CFGElement &E) {
+ return E.getKind() == Initializer;
}
};
@@ -123,6 +142,7 @@ public:
/// by compiler on various occasions.
class CFGImplicitDtor : public CFGElement {
protected:
+ CFGImplicitDtor() {}
CFGImplicitDtor(Kind kind, const void *data1, const void *data2 = 0)
: CFGElement(kind, data1, data2) {
assert(kind >= DTOR_BEGIN && kind <= DTOR_END);
@@ -132,8 +152,10 @@ public:
const CXXDestructorDecl *getDestructorDecl(ASTContext &astContext) const;
bool isNoReturn(ASTContext &astContext) const;
- static bool classof(const CFGElement *E) {
- Kind kind = E->getKind();
+private:
+ friend class CFGElement;
+ static bool isKind(const CFGElement &E) {
+ Kind kind = E.getKind();
return kind >= DTOR_BEGIN && kind <= DTOR_END;
}
};
@@ -155,8 +177,11 @@ public:
return static_cast<Stmt*>(Data2.getPointer());
}
- static bool classof(const CFGElement *elem) {
- return elem->getKind() == AutomaticObjectDtor;
+private:
+ friend class CFGElement;
+ CFGAutomaticObjDtor() {}
+ static bool isKind(const CFGElement &elem) {
+ return elem.getKind() == AutomaticObjectDtor;
}
};
@@ -171,8 +196,11 @@ public:
return static_cast<const CXXBaseSpecifier*>(Data1.getPointer());
}
- static bool classof(const CFGElement *E) {
- return E->getKind() == BaseDtor;
+private:
+ friend class CFGElement;
+ CFGBaseDtor() {}
+ static bool isKind(const CFGElement &E) {
+ return E.getKind() == BaseDtor;
}
};
@@ -187,8 +215,11 @@ public:
return static_cast<const FieldDecl*>(Data1.getPointer());
}
- static bool classof(const CFGElement *E) {
- return E->getKind() == MemberDtor;
+private:
+ friend class CFGElement;
+ CFGMemberDtor() {}
+ static bool isKind(const CFGElement &E) {
+ return E.getKind() == MemberDtor;
}
};
@@ -203,8 +234,11 @@ public:
return static_cast<const CXXBindTemporaryExpr *>(Data1.getPointer());
}
- static bool classof(const CFGElement *E) {
- return E->getKind() == TemporaryDtor;
+private:
+ friend class CFGElement;
+ CFGTemporaryDtor() {}
+ static bool isKind(const CFGElement &E) {
+ return E.getKind() == TemporaryDtor;
}
};
@@ -535,7 +569,7 @@ public:
// the elements beginning at the last position in prepared space.
iterator beginAutomaticObjDtorsInsert(iterator I, size_t Cnt,
BumpVectorContext &C) {
- return iterator(Elements.insert(I.base(), Cnt, CFGElement(), C));
+ return iterator(Elements.insert(I.base(), Cnt, CFGAutomaticObjDtor(0, 0), C));
}
iterator insertAutomaticObjDtor(iterator I, VarDecl *VD, Stmt *S) {
*I = CFGAutomaticObjDtor(VD, S);
@@ -567,6 +601,7 @@ public:
bool AddInitializers;
bool AddImplicitDtors;
bool AddTemporaryDtors;
+ bool AddStaticInitBranches;
bool alwaysAdd(const Stmt *stmt) const {
return alwaysAddMask[stmt->getStmtClass()];
@@ -587,7 +622,8 @@ public:
,AddEHEdges(false)
,AddInitializers(false)
,AddImplicitDtors(false)
- ,AddTemporaryDtors(false) {}
+ ,AddTemporaryDtors(false)
+ ,AddStaticInitBranches(false) {}
};
/// \brief Provides a custom implementation of the iterator class to have the
@@ -718,7 +754,7 @@ public:
for (const_iterator I=begin(), E=end(); I != E; ++I)
for (CFGBlock::const_iterator BI=(*I)->begin(), BE=(*I)->end();
BI != BE; ++BI) {
- if (const CFGStmt *stmt = BI->getAs<CFGStmt>())
+ if (Optional<CFGStmt> stmt = BI->getAs<CFGStmt>())
O(const_cast<Stmt*>(stmt->getStmt()));
}
}
@@ -807,17 +843,10 @@ namespace llvm {
/// Implement simplify_type for CFGTerminator, so that we can dyn_cast from
/// CFGTerminator to a specific Stmt class.
-template <> struct simplify_type<const ::clang::CFGTerminator> {
- typedef const ::clang::Stmt *SimpleType;
- static SimpleType getSimplifiedValue(const ::clang::CFGTerminator &Val) {
- return Val.getStmt();
- }
-};
-
template <> struct simplify_type< ::clang::CFGTerminator> {
typedef ::clang::Stmt *SimpleType;
- static SimpleType getSimplifiedValue(const ::clang::CFGTerminator &Val) {
- return const_cast<SimpleType>(Val.getStmt());
+ static SimpleType getSimplifiedValue(::clang::CFGTerminator Val) {
+ return Val.getStmt();
}
};
diff --git a/include/clang/Analysis/CallGraph.h b/include/clang/Analysis/CallGraph.h
index 509de7bc2178..5015eb61497e 100644
--- a/include/clang/Analysis/CallGraph.h
+++ b/include/clang/Analysis/CallGraph.h
@@ -39,15 +39,9 @@ class CallGraph : public RecursiveASTVisitor<CallGraph> {
/// FunctionMap owns all CallGraphNodes.
FunctionMapTy FunctionMap;
- /// This is a virtual root node that has edges to all the global functions -
- /// 'main' or functions accessible from other translation units.
+ /// This is a virtual root node that has edges to all the functions.
CallGraphNode *Root;
- /// The list of nodes that have no parent. These are unreachable from Root.
- /// Declarations can get to this list due to impressions in the graph, for
- /// example, we do not track functions whose addresses were taken.
- llvm::SetVector<CallGraphNode *> ParentlessNodes;
-
public:
CallGraph();
~CallGraph();
@@ -91,34 +85,35 @@ public:
/// failing to add a call edge due to the analysis imprecision.
typedef llvm::SetVector<CallGraphNode *>::iterator nodes_iterator;
typedef llvm::SetVector<CallGraphNode *>::const_iterator const_nodes_iterator;
- nodes_iterator parentless_begin() { return ParentlessNodes.begin(); }
- nodes_iterator parentless_end() { return ParentlessNodes.end(); }
- const_nodes_iterator
- parentless_begin() const { return ParentlessNodes.begin(); }
- const_nodes_iterator
- parentless_end() const { return ParentlessNodes.end(); }
void print(raw_ostream &os) const;
void dump() const;
void viewGraph() const;
+ void addNodesForBlocks(DeclContext *D);
+
/// Part of recursive declaration visitation. We recursively visit all the
- /// Declarations to collect the root functions.
+ /// declarations to collect the root functions.
bool VisitFunctionDecl(FunctionDecl *FD) {
// We skip function template definitions, as their semantics is
// only determined when they are instantiated.
- if (includeInGraph(FD))
+ if (includeInGraph(FD)) {
+ // Add all blocks declared inside this function to the graph.
+ addNodesForBlocks(FD);
// If this function has external linkage, anything could call it.
// Note, we are not precise here. For example, the function could have
// its address taken.
addNodeForDecl(FD, FD->isGlobal());
+ }
return true;
}
/// Part of recursive declaration visitation.
bool VisitObjCMethodDecl(ObjCMethodDecl *MD) {
- if (includeInGraph(MD))
+ if (includeInGraph(MD)) {
+ addNodesForBlocks(MD);
addNodeForDecl(MD, true);
+ }
return true;
}
@@ -144,15 +139,13 @@ private:
Decl *FD;
/// \brief The list of functions called from this node.
- // Small vector might be more efficient since we are only tracking functions
- // whose definition is in the current TU.
- llvm::SmallVector<CallRecord, 5> CalledFunctions;
+ SmallVector<CallRecord, 5> CalledFunctions;
public:
CallGraphNode(Decl *D) : FD(D) {}
- typedef llvm::SmallVector<CallRecord, 5>::iterator iterator;
- typedef llvm::SmallVector<CallRecord, 5>::const_iterator const_iterator;
+ typedef SmallVector<CallRecord, 5>::iterator iterator;
+ typedef SmallVector<CallRecord, 5>::const_iterator const_iterator;
/// Iterators through all the callees/children of the node.
inline iterator begin() { return CalledFunctions.begin(); }
@@ -165,13 +158,10 @@ public:
void addCallee(CallGraphNode *N, CallGraph *CG) {
CalledFunctions.push_back(N);
- CG->ParentlessNodes.remove(N);
}
Decl *getDecl() const { return FD; }
- StringRef getName() const;
-
void print(raw_ostream &os) const;
void dump() const;
};
@@ -203,7 +193,7 @@ template <> struct GraphTraits<const clang::CallGraphNode*> {
typedef NodeType::const_iterator ChildIteratorType;
static NodeType *getEntryNode(const clang::CallGraphNode *CGN) { return CGN; }
static inline ChildIteratorType child_begin(NodeType *N) { return N->begin();}
- static inline ChildIteratorType child_end (NodeType *N) { return N->end(); }
+ static inline ChildIteratorType child_end(NodeType *N) { return N->end(); }
};
template <> struct GraphTraits<clang::CallGraph*>
diff --git a/include/clang/Analysis/FlowSensitive/DataflowSolver.h b/include/clang/Analysis/FlowSensitive/DataflowSolver.h
index 017da636ebf6..0f5e7bf246e8 100644
--- a/include/clang/Analysis/FlowSensitive/DataflowSolver.h
+++ b/include/clang/Analysis/FlowSensitive/DataflowSolver.h
@@ -14,12 +14,12 @@
#ifndef LLVM_CLANG_ANALYSES_DATAFLOW_SOLVER
#define LLVM_CLANG_ANALYSES_DATAFLOW_SOLVER
+#include "functional" // STL
#include "clang/Analysis/CFG.h"
-#include "clang/Analysis/ProgramPoint.h"
#include "clang/Analysis/FlowSensitive/DataflowValues.h"
+#include "clang/Analysis/ProgramPoint.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
-#include "functional" // STL
namespace clang {
diff --git a/include/clang/Analysis/ProgramPoint.h b/include/clang/Analysis/ProgramPoint.h
index 947997804388..333329d8c30b 100644
--- a/include/clang/Analysis/ProgramPoint.h
+++ b/include/clang/Analysis/ProgramPoint.h
@@ -17,15 +17,16 @@
#include "clang/Analysis/AnalysisContext.h"
#include "clang/Analysis/CFG.h"
-#include "llvm/Support/DataTypes.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/FoldingSet.h"
-#include "llvm/Support/Casting.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/DataTypes.h"
#include <cassert>
-#include <utility>
#include <string>
+#include <utility>
namespace clang {
@@ -71,9 +72,8 @@ private:
llvm::PointerIntPair<const ProgramPointTag *, 2, unsigned> Tag;
- ProgramPoint();
-
protected:
+ ProgramPoint() {}
ProgramPoint(const void *P,
Kind k,
const LocationContext *l,
@@ -110,6 +110,29 @@ public:
getLocationContext(), tag);
}
+ /// \brief Convert to the specified ProgramPoint type, asserting that this
+ /// ProgramPoint is of the desired type.
+ template<typename T>
+ T castAs() const {
+ assert(T::isKind(*this));
+ T t;
+ ProgramPoint& PP = t;
+ PP = *this;
+ return t;
+ }
+
+ /// \brief Convert to the specified ProgramPoint type, returning None if this
+ /// ProgramPoint is not of the desired type.
+ template<typename T>
+ Optional<T> getAs() const {
+ if (!T::isKind(*this))
+ return None;
+ T t;
+ ProgramPoint& PP = t;
+ PP = *this;
+ return t;
+ }
+
Kind getKind() const {
unsigned x = Tag.getInt();
x <<= 2;
@@ -179,13 +202,16 @@ public:
return reinterpret_cast<const CFGBlock*>(getData1());
}
- const CFGElement getFirstElement() const {
+ Optional<CFGElement> getFirstElement() const {
const CFGBlock *B = getBlock();
- return B->empty() ? CFGElement() : B->front();
+ return B->empty() ? Optional<CFGElement>() : B->front();
}
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == BlockEntranceKind;
+private:
+ friend class ProgramPoint;
+ BlockEntrance() {}
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() == BlockEntranceKind;
}
};
@@ -202,8 +228,11 @@ public:
return getBlock()->getTerminator();
}
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == BlockExitKind;
+private:
+ friend class ProgramPoint;
+ BlockExit() {}
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() == BlockExitKind;
}
};
@@ -218,10 +247,14 @@ public:
const Stmt *getStmt() const { return (const Stmt*) getData1(); }
template <typename T>
- const T* getStmtAs() const { return llvm::dyn_cast<T>(getStmt()); }
+ const T* getStmtAs() const { return dyn_cast<T>(getStmt()); }
- static bool classof(const ProgramPoint* Location) {
- unsigned k = Location->getKind();
+protected:
+ StmtPoint() {}
+private:
+ friend class ProgramPoint;
+ static bool isKind(const ProgramPoint &Location) {
+ unsigned k = Location.getKind();
return k >= PreStmtKind && k <= MaxPostStmtKind;
}
};
@@ -235,13 +268,17 @@ public:
const Stmt *getSubStmt() const { return (const Stmt*) getData2(); }
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == PreStmtKind;
+private:
+ friend class ProgramPoint;
+ PreStmt() {}
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() == PreStmtKind;
}
};
class PostStmt : public StmtPoint {
protected:
+ PostStmt() {}
PostStmt(const Stmt *S, const void *data, Kind k, const LocationContext *L,
const ProgramPointTag *tag = 0)
: StmtPoint(S, data, k, L, tag) {}
@@ -255,8 +292,10 @@ public:
const ProgramPointTag *tag = 0)
: StmtPoint(S, NULL, PostStmtKind, L, tag) {}
- static bool classof(const ProgramPoint* Location) {
- unsigned k = Location->getKind();
+private:
+ friend class ProgramPoint;
+ static bool isKind(const ProgramPoint &Location) {
+ unsigned k = Location.getKind();
return k >= MinPostStmtKind && k <= MaxPostStmtKind;
}
};
@@ -268,19 +307,25 @@ public:
const ProgramPointTag *tag = 0)
: PostStmt(S, PostConditionKind, L, tag) {}
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == PostConditionKind;
+private:
+ friend class ProgramPoint;
+ PostCondition() {}
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() == PostConditionKind;
}
};
class LocationCheck : public StmtPoint {
protected:
+ LocationCheck() {}
LocationCheck(const Stmt *S, const LocationContext *L,
ProgramPoint::Kind K, const ProgramPointTag *tag)
: StmtPoint(S, NULL, K, L, tag) {}
- static bool classof(const ProgramPoint *location) {
- unsigned k = location->getKind();
+private:
+ friend class ProgramPoint;
+ static bool isKind(const ProgramPoint &location) {
+ unsigned k = location.getKind();
return k == PreLoadKind || k == PreStoreKind;
}
};
@@ -291,8 +336,11 @@ public:
const ProgramPointTag *tag = 0)
: LocationCheck(S, L, PreLoadKind, tag) {}
- static bool classof(const ProgramPoint *location) {
- return location->getKind() == PreLoadKind;
+private:
+ friend class ProgramPoint;
+ PreLoad() {}
+ static bool isKind(const ProgramPoint &location) {
+ return location.getKind() == PreLoadKind;
}
};
@@ -302,8 +350,11 @@ public:
const ProgramPointTag *tag = 0)
: LocationCheck(S, L, PreStoreKind, tag) {}
- static bool classof(const ProgramPoint *location) {
- return location->getKind() == PreStoreKind;
+private:
+ friend class ProgramPoint;
+ PreStore() {}
+ static bool isKind(const ProgramPoint &location) {
+ return location.getKind() == PreStoreKind;
}
};
@@ -313,8 +364,11 @@ public:
const ProgramPointTag *tag = 0)
: PostStmt(S, PostLoadKind, L, tag) {}
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == PostLoadKind;
+private:
+ friend class ProgramPoint;
+ PostLoad() {}
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() == PostLoadKind;
}
};
@@ -331,16 +385,18 @@ public:
setData2(Loc);
}
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == PostStoreKind;
- }
-
/// \brief Returns the information about the location used in the store,
/// how it was uttered in the code.
const void *getLocationValue() const {
return getData2();
}
+private:
+ friend class ProgramPoint;
+ PostStore() {}
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() == PostStoreKind;
+ }
};
class PostLValue : public PostStmt {
@@ -349,8 +405,11 @@ public:
const ProgramPointTag *tag = 0)
: PostStmt(S, PostLValueKind, L, tag) {}
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == PostLValueKind;
+private:
+ friend class ProgramPoint;
+ PostLValue() {}
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() == PostLValueKind;
}
};
@@ -362,8 +421,11 @@ public:
const ProgramPointTag *tag = 0)
: StmtPoint(S, 0, PreStmtPurgeDeadSymbolsKind, L, tag) { }
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == PreStmtPurgeDeadSymbolsKind;
+private:
+ friend class ProgramPoint;
+ PreStmtPurgeDeadSymbols() {}
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() == PreStmtPurgeDeadSymbolsKind;
}
};
@@ -375,8 +437,11 @@ public:
const ProgramPointTag *tag = 0)
: StmtPoint(S, 0, PostStmtPurgeDeadSymbolsKind, L, tag) { }
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == PostStmtPurgeDeadSymbolsKind;
+private:
+ friend class ProgramPoint;
+ PostStmtPurgeDeadSymbols() {}
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() == PostStmtPurgeDeadSymbolsKind;
}
};
@@ -396,19 +461,40 @@ public:
return static_cast<const CFGBlock*>(getData2());
}
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == BlockEdgeKind;
+private:
+ friend class ProgramPoint;
+ BlockEdge() {}
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() == BlockEdgeKind;
}
};
class PostInitializer : public ProgramPoint {
public:
- PostInitializer(const CXXCtorInitializer *I,
+ /// \brief Construct a PostInitializer point that represents a location after
+ /// CXXCtorInitializer expression evaluation.
+ ///
+ /// \param I The initializer.
+ /// \param Loc The location of the field being initialized.
+ PostInitializer(const CXXCtorInitializer *I,
+ const void *Loc,
const LocationContext *L)
- : ProgramPoint(I, PostInitializerKind, L) {}
+ : ProgramPoint(I, Loc, PostInitializerKind, L) {}
+
+ const CXXCtorInitializer *getInitializer() const {
+ return static_cast<const CXXCtorInitializer *>(getData1());
+ }
- static bool classof(const ProgramPoint *Location) {
- return Location->getKind() == PostInitializerKind;
+ /// \brief Returns the location of the field.
+ const void *getLocationValue() const {
+ return getData2();
+ }
+
+private:
+ friend class ProgramPoint;
+ PostInitializer() {}
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() == PostInitializerKind;
}
};
@@ -426,9 +512,13 @@ public:
return SourceLocation::getFromPtrEncoding(getData1());
}
- static bool classof(const ProgramPoint *Location) {
- return Location->getKind() >= MinImplicitCallKind &&
- Location->getKind() <= MaxImplicitCallKind;
+protected:
+ ImplicitCallPoint() {}
+private:
+ friend class ProgramPoint;
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() >= MinImplicitCallKind &&
+ Location.getKind() <= MaxImplicitCallKind;
}
};
@@ -441,8 +531,11 @@ public:
const LocationContext *L, const ProgramPointTag *Tag = 0)
: ImplicitCallPoint(D, Loc, PreImplicitCallKind, L, Tag) {}
- static bool classof(const ProgramPoint *Location) {
- return Location->getKind() == PreImplicitCallKind;
+private:
+ friend class ProgramPoint;
+ PreImplicitCall() {}
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() == PreImplicitCallKind;
}
};
@@ -455,8 +548,11 @@ public:
const LocationContext *L, const ProgramPointTag *Tag = 0)
: ImplicitCallPoint(D, Loc, PostImplicitCallKind, L, Tag) {}
- static bool classof(const ProgramPoint *Location) {
- return Location->getKind() == PostImplicitCallKind;
+private:
+ friend class ProgramPoint;
+ PostImplicitCall() {}
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() == PostImplicitCallKind;
}
};
@@ -476,8 +572,11 @@ public:
return static_cast<const StackFrameContext *>(getData2());
}
- static bool classof(const ProgramPoint *Location) {
- return Location->getKind() == CallEnterKind;
+private:
+ friend class ProgramPoint;
+ CallEnter() {}
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() == CallEnterKind;
}
};
@@ -496,8 +595,11 @@ public:
CallExitBegin(const StackFrameContext *L)
: ProgramPoint(0, CallExitBeginKind, L, 0) {}
- static bool classof(const ProgramPoint *Location) {
- return Location->getKind() == CallExitBeginKind;
+private:
+ friend class ProgramPoint;
+ CallExitBegin() {}
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() == CallExitBeginKind;
}
};
@@ -514,8 +616,11 @@ public:
return static_cast<const StackFrameContext *>(getData1());
}
- static bool classof(const ProgramPoint *Location) {
- return Location->getKind() == CallExitEndKind;
+private:
+ friend class ProgramPoint;
+ CallExitEnd() {}
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() == CallExitEndKind;
}
};
@@ -529,8 +634,11 @@ public:
const void *getData() const { return getData1(); }
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == EpsilonKind;
+private:
+ friend class ProgramPoint;
+ EpsilonPoint() {}
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() == EpsilonKind;
}
};
@@ -544,7 +652,7 @@ public:
virtual StringRef getTagDescription() const = 0;
protected:
- /// Used to implement 'classof' in subclasses.
+ /// Used to implement 'isKind' in subclasses.
const void *getTagKind() { return TagKind; }
private:
diff --git a/include/clang/Analysis/Support/BlkExprDeclBitVector.h b/include/clang/Analysis/Support/BlkExprDeclBitVector.h
index d25b84833c54..35cc799b13bc 100644
--- a/include/clang/Analysis/Support/BlkExprDeclBitVector.h
+++ b/include/clang/Analysis/Support/BlkExprDeclBitVector.h
@@ -17,8 +17,8 @@
#ifndef LLVM_CLANG_STMTDECLBVDVAL_H
#define LLVM_CLANG_STMTDECLBVDVAL_H
-#include "clang/Analysis/CFG.h"
#include "clang/AST/Decl.h" // for Decl* -> NamedDecl* conversion
+#include "clang/Analysis/CFG.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
diff --git a/include/clang/Analysis/Support/BumpVector.h b/include/clang/Analysis/Support/BumpVector.h
index 83532e62babe..387e7792bd38 100644
--- a/include/clang/Analysis/Support/BumpVector.h
+++ b/include/clang/Analysis/Support/BumpVector.h
@@ -19,9 +19,9 @@
#ifndef LLVM_CLANG_BUMP_VECTOR
#define LLVM_CLANG_BUMP_VECTOR
-#include "llvm/Support/type_traits.h"
-#include "llvm/Support/Allocator.h"
#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/type_traits.h"
#include <algorithm>
#include <cstring>
#include <iterator>
diff --git a/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h b/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h
index c510e202f93f..2bf3eda070b9 100644
--- a/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h
+++ b/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h
@@ -17,10 +17,10 @@
#ifndef LLVM_CLANG_ANALYSIS_CFG_REC_STMT_DECL_VISITOR_H
#define LLVM_CLANG_ANALYSIS_CFG_REC_STMT_DECL_VISITOR_H
-#include "clang/Analysis/Visitors/CFGRecStmtVisitor.h"
#include "clang/AST/Decl.h"
-#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/Analysis/Visitors/CFGRecStmtVisitor.h"
#define DISPATCH_CASE(CLASS) \
case Decl::CLASS: \
@@ -63,6 +63,7 @@ public:
DISPATCH_CASE(ImplicitParam)
DISPATCH_CASE(EnumConstant)
DISPATCH_CASE(Typedef)
+ DISPATCH_CASE(TypeAlias)
DISPATCH_CASE(Record) // FIXME: Refine. VisitStructDecl?
DISPATCH_CASE(CXXRecord)
DISPATCH_CASE(Enum)
@@ -82,6 +83,7 @@ public:
DEFAULT_DISPATCH(ImplicitParam)
DEFAULT_DISPATCH(EnumConstant)
DEFAULT_DISPATCH(Typedef)
+ DEFAULT_DISPATCH(TypeAlias)
DEFAULT_DISPATCH(Record)
DEFAULT_DISPATCH(Enum)
DEFAULT_DISPATCH(Field)
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
index bfe8093079b7..37aa332b812f 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -29,8 +29,8 @@ class SubsetSubject<AttrSubject base, string description, code check>
code CheckCode = check;
}
-// This is the type of a variable which C++0x defines [[aligned()]] as being
-// a possible subject.
+// This is the type of a variable which C++11 allows alignas(...) to appertain
+// to.
def NormalVar : SubsetSubject<Var, "non-register, non-parameter variable",
[{S->getStorageClass() != VarDecl::Register &&
S->getKind() != Decl::ImplicitParam &&
@@ -91,6 +91,12 @@ class Declspec<string name> : Spelling<name, "Declspec">;
class CXX11<string namespace, string name> : Spelling<name, "CXX11"> {
string Namespace = namespace;
}
+class Keyword<string name> : Spelling<name, "Keyword">;
+
+class Accessor<string name, list<Spelling> spellings> {
+ string Name = name;
+ list<Spelling> Spellings = spellings;
+}
class Attr {
// The various ways in which an attribute can be spelled in source
@@ -99,8 +105,10 @@ class Attr {
list<AttrSubject> Subjects;
// The arguments allowed on an attribute
list<Argument> Args = [];
- // Set to true for attributes with arguments which require delayed parsing.
- bit LateParsed = 0;
+ // Accessors which should be generated for the attribute.
+ list<Accessor> Accessors = [];
+ // Set to true for attributes with arguments which require delayed parsing.
+ bit LateParsed = 0;
// Set to false to prevent an attribute from being propagated from a template
// to the instantiation.
bit Clone = 1;
@@ -114,7 +122,7 @@ class Attr {
bit Ignored = 0;
// Set to true if each of the spellings is a distinct attribute.
bit DistinctSpellings = 0;
- // Any additional text that should be included verbatim in the class.
+ // Any additional text that should be included verbatim in the class.
code AdditionalMembers = [{}];
}
@@ -125,6 +133,13 @@ class InheritableAttr : Attr;
/// redeclarations, even when it's written on a parameter.
class InheritableParamAttr : InheritableAttr;
+/// An ignored attribute, which we parse but discard with no checking.
+class IgnoredAttr : Attr {
+ let Ignored = 1;
+ let ASTNode = 0;
+ let SemaHandler = 0;
+}
+
//
// Attributes begin here
//
@@ -132,18 +147,24 @@ class InheritableParamAttr : InheritableAttr;
def AddressSpace : Attr {
let Spellings = [GNU<"address_space">];
let Args = [IntArgument<"AddressSpace">];
- let ASTNode = 0;
+ let ASTNode = 0;
}
def Alias : InheritableAttr {
- let Spellings = [GNU<"alias">];
+ let Spellings = [GNU<"alias">, CXX11<"gnu", "alias">];
let Args = [StringArgument<"Aliasee">];
}
def Aligned : InheritableAttr {
- let Spellings = [GNU<"aligned">, GNU<"align">];
+ let Spellings = [GNU<"aligned">, Declspec<"align">, CXX11<"gnu", "aligned">,
+ Keyword<"alignas">, Keyword<"_Alignas">];
let Subjects = [NonBitField, NormalVar, Tag];
- let Args = [AlignedArgument<"Alignment">, BoolArgument<"IsMSDeclSpec">];
+ let Args = [AlignedArgument<"Alignment">];
+ let Accessors = [Accessor<"isGNU", [GNU<"aligned">, CXX11<"gnu","aligned">]>,
+ Accessor<"isC11", [Keyword<"_Alignas">]>,
+ Accessor<"isAlignas", [Keyword<"alignas">,
+ Keyword<"_Alignas">]>,
+ Accessor<"isDeclspec",[Declspec<"align">]>];
}
def AlignMac68k : InheritableAttr {
@@ -152,16 +173,16 @@ def AlignMac68k : InheritableAttr {
}
def AllocSize : Attr {
- let Spellings = [GNU<"alloc_size">];
+ let Spellings = [GNU<"alloc_size">, CXX11<"gnu", "alloc_size">];
let Args = [VariadicUnsignedArgument<"Args">];
}
def AlwaysInline : InheritableAttr {
- let Spellings = [GNU<"always_inline">];
+ let Spellings = [GNU<"always_inline">, CXX11<"gnu", "always_inline">];
}
def TLSModel : InheritableAttr {
- let Spellings = [GNU<"tls_model">];
+ let Spellings = [GNU<"tls_model">, CXX11<"gnu", "tls_model">];
let Subjects = [Var];
let Args = [StringArgument<"Model">];
}
@@ -200,11 +221,8 @@ def Blocks : InheritableAttr {
let Args = [EnumArgument<"Type", "BlockType", ["byref"], ["ByRef"]>];
}
-def Bounded : Attr {
+def Bounded : IgnoredAttr {
let Spellings = [GNU<"bounded">];
- let ASTNode = 0;
- let SemaHandler = 0;
- let Ignored = 1;
}
def CarriesDependency : InheritableParamAttr {
@@ -214,7 +232,8 @@ def CarriesDependency : InheritableParamAttr {
}
def CDecl : InheritableAttr {
- let Spellings = [GNU<"cdecl">, GNU<"__cdecl">];
+ let Spellings = [GNU<"cdecl">, CXX11<"gnu", "cdecl">, Keyword<"__cdecl">,
+ Keyword<"_cdecl">];
}
// cf_audited_transfer indicates that the given function has been
@@ -234,11 +253,6 @@ def CFUnknownTransfer : InheritableAttr {
let Subjects = [Function];
}
-def CFReturnsAutoreleased : Attr {
- let Spellings = [GNU<"cf_returns_autoreleased">];
- let ASTNode = 0;
-}
-
def CFReturnsRetained : InheritableAttr {
let Spellings = [GNU<"cf_returns_retained">];
let Subjects = [ObjCMethod, Function];
@@ -255,24 +269,24 @@ def CFConsumed : InheritableParamAttr {
}
def Cleanup : InheritableAttr {
- let Spellings = [GNU<"cleanup">];
+ let Spellings = [GNU<"cleanup">, CXX11<"gnu", "cleanup">];
let Args = [FunctionArgument<"FunctionDecl">];
}
def Cold : InheritableAttr {
- let Spellings = [GNU<"cold">];
+ let Spellings = [GNU<"cold">, CXX11<"gnu", "cold">];
}
def Common : InheritableAttr {
- let Spellings = [GNU<"common">];
+ let Spellings = [GNU<"common">, CXX11<"gnu", "common">];
}
def Const : InheritableAttr {
- let Spellings = [GNU<"const">, GNU<"__const">];
+ let Spellings = [GNU<"const">, GNU<"__const">, CXX11<"gnu", "const">];
}
def Constructor : InheritableAttr {
- let Spellings = [GNU<"constructor">];
+ let Spellings = [GNU<"constructor">, CXX11<"gnu", "constructor">];
let Args = [IntArgument<"Priority">];
}
@@ -301,23 +315,33 @@ def CUDAShared : InheritableAttr {
let Spellings = [GNU<"shared">];
}
+def C11NoReturn : InheritableAttr {
+ let Spellings = [Keyword<"_Noreturn">];
+ let Subjects = [Function];
+ let SemaHandler = 0;
+}
+
+def CXX11NoReturn : InheritableAttr {
+ let Spellings = [CXX11<"","noreturn">, CXX11<"std","noreturn">];
+ let Subjects = [Function];
+}
+
def OpenCLKernel : Attr {
- let Spellings = [GNU<"opencl_kernel_function">];
+ let Spellings = [Keyword<"__kernel">, Keyword<"kernel">];
}
def OpenCLImageAccess : Attr {
let Spellings = [GNU<"opencl_image_access">];
let Args = [IntArgument<"Access">];
- let ASTNode = 0;
}
def Deprecated : InheritableAttr {
- let Spellings = [GNU<"deprecated">];
+ let Spellings = [GNU<"deprecated">, CXX11<"gnu", "deprecated">];
let Args = [StringArgument<"Message">];
}
def Destructor : InheritableAttr {
- let Spellings = [GNU<"destructor">];
+ let Spellings = [GNU<"destructor">, CXX11<"gnu", "destructor">];
let Args = [IntArgument<"Priority">];
}
@@ -328,12 +352,13 @@ def ExtVectorType : Attr {
}
def FallThrough : Attr {
- let Spellings = [CXX11<"clang","fallthrough">];
+ let Spellings = [CXX11<"clang", "fallthrough">];
let Subjects = [NullStmt];
}
def FastCall : InheritableAttr {
- let Spellings = [GNU<"fastcall">, GNU<"__fastcall">];
+ let Spellings = [GNU<"fastcall">, CXX11<"gnu", "fastcall">,
+ Keyword<"__fastcall">, Keyword<"_fastcall">];
}
def Final : InheritableAttr {
@@ -347,22 +372,22 @@ def MinSize : InheritableAttr {
}
def Format : InheritableAttr {
- let Spellings = [GNU<"format">];
+ let Spellings = [GNU<"format">, CXX11<"gnu", "format">];
let Args = [StringArgument<"Type">, IntArgument<"FormatIdx">,
IntArgument<"FirstArg">];
}
def FormatArg : InheritableAttr {
- let Spellings = [GNU<"format_arg">];
+ let Spellings = [GNU<"format_arg">, CXX11<"gnu", "format_arg">];
let Args = [IntArgument<"FormatIdx">];
}
def GNUInline : InheritableAttr {
- let Spellings = [GNU<"gnu_inline">];
+ let Spellings = [GNU<"gnu_inline">, CXX11<"gnu", "gnu_inline">];
}
def Hot : InheritableAttr {
- let Spellings = [GNU<"hot">];
+ let Spellings = [GNU<"hot">, CXX11<"gnu", "hot">];
}
def IBAction : InheritableAttr {
@@ -379,7 +404,7 @@ def IBOutletCollection : InheritableAttr {
}
def Malloc : InheritableAttr {
- let Spellings = [GNU<"malloc">];
+ let Spellings = [GNU<"malloc">, CXX11<"gnu", "malloc">];
}
def MaxFieldAlignment : InheritableAttr {
@@ -389,7 +414,7 @@ def MaxFieldAlignment : InheritableAttr {
}
def MayAlias : InheritableAttr {
- let Spellings = [GNU<"may_alias">];
+ let Spellings = [GNU<"may_alias">, CXX11<"gnu", "may_alias">];
}
def MSP430Interrupt : InheritableAttr {
@@ -408,14 +433,19 @@ def MBlazeSaveVolatiles : InheritableAttr {
let SemaHandler = 0;
}
+def Mips16 : InheritableAttr {
+ let Spellings = [GNU<"mips16">, CXX11<"gnu", "mips16">];
+ let Subjects = [Function];
+}
+
def Mode : Attr {
- let Spellings = [GNU<"mode">];
+ let Spellings = [GNU<"mode">, CXX11<"gnu", "mode">];
let Args = [IdentifierArgument<"Mode">];
let ASTNode = 0;
}
def Naked : InheritableAttr {
- let Spellings = [GNU<"naked">];
+ let Spellings = [GNU<"naked">, CXX11<"gnu", "naked">];
}
def NeonPolyVectorType : Attr {
@@ -431,11 +461,11 @@ def NeonVectorType : Attr {
}
def ReturnsTwice : InheritableAttr {
- let Spellings = [GNU<"returns_twice">];
+ let Spellings = [GNU<"returns_twice">, CXX11<"gnu", "returns_twice">];
}
def NoCommon : InheritableAttr {
- let Spellings = [GNU<"nocommon">];
+ let Spellings = [GNU<"nocommon">, CXX11<"gnu", "nocommon">];
}
def NoDebug : InheritableAttr {
@@ -443,11 +473,16 @@ def NoDebug : InheritableAttr {
}
def NoInline : InheritableAttr {
- let Spellings = [GNU<"noinline">];
+ let Spellings = [GNU<"noinline">, CXX11<"gnu", "noinline">];
+}
+
+def NoMips16 : InheritableAttr {
+ let Spellings = [GNU<"nomips16">, CXX11<"gnu", "nomips16">];
+ let Subjects = [Function];
}
def NonNull : InheritableAttr {
- let Spellings = [GNU<"nonnull">];
+ let Spellings = [GNU<"nonnull">, CXX11<"gnu", "nonnull">];
let Args = [VariadicUnsignedArgument<"Args">];
let AdditionalMembers =
[{bool isNonNull(unsigned idx) const {
@@ -460,19 +495,19 @@ def NonNull : InheritableAttr {
}
def NoReturn : InheritableAttr {
- let Spellings = [GNU<"noreturn">, CXX11<"","noreturn">,
- CXX11<"std","noreturn">];
+ let Spellings = [GNU<"noreturn">, CXX11<"gnu", "noreturn">];
// FIXME: Does GCC allow this on the function instead?
let Subjects = [Function];
}
def NoInstrumentFunction : InheritableAttr {
- let Spellings = [GNU<"no_instrument_function">];
+ let Spellings = [GNU<"no_instrument_function">,
+ CXX11<"gnu", "no_instrument_function">];
let Subjects = [Function];
}
def NoThrow : InheritableAttr {
- let Spellings = [GNU<"nothrow">];
+ let Spellings = [GNU<"nothrow">, CXX11<"gnu", "nothrow">];
}
def NSBridged : InheritableAttr {
@@ -563,26 +598,30 @@ def Ownership : InheritableAttr {
}
def Packed : InheritableAttr {
- let Spellings = [GNU<"packed">];
+ let Spellings = [GNU<"packed">, CXX11<"gnu", "packed">];
}
def PnaclCall : InheritableAttr {
let Spellings = [GNU<"pnaclcall">];
}
+def IntelOclBicc : InheritableAttr {
+ let Spellings = [GNU<"intel_ocl_bicc">];
+}
+
def Pcs : InheritableAttr {
- let Spellings = [GNU<"pcs">];
+ let Spellings = [GNU<"pcs">, CXX11<"gnu", "pcs">];
let Args = [EnumArgument<"PCS", "PCSType",
["aapcs", "aapcs-vfp"],
["AAPCS", "AAPCS_VFP"]>];
}
def Pure : InheritableAttr {
- let Spellings = [GNU<"pure">];
+ let Spellings = [GNU<"pure">, CXX11<"gnu", "pure">];
}
def Regparm : InheritableAttr {
- let Spellings = [GNU<"regparm">];
+ let Spellings = [GNU<"regparm">, CXX11<"gnu", "regparm">];
let Args = [UnsignedArgument<"NumParams">];
}
@@ -592,6 +631,11 @@ def ReqdWorkGroupSize : InheritableAttr {
UnsignedArgument<"ZDim">];
}
+def Endian : InheritableAttr {
+ let Spellings = [GNU<"endian">];
+ let Args = [IdentifierArgument<"platform">];
+}
+
def WorkGroupSizeHint : InheritableAttr {
let Spellings = [GNU<"work_group_size_hint">];
let Args = [UnsignedArgument<"XDim">,
@@ -605,30 +649,32 @@ def InitPriority : InheritableAttr {
}
def Section : InheritableAttr {
- let Spellings = [GNU<"section">];
+ let Spellings = [GNU<"section">, CXX11<"gnu", "section">];
let Args = [StringArgument<"Name">];
}
def Sentinel : InheritableAttr {
- let Spellings = [GNU<"sentinel">];
+ let Spellings = [GNU<"sentinel">, CXX11<"gnu", "sentinel">];
let Args = [DefaultIntArgument<"Sentinel", 0>,
DefaultIntArgument<"NullPos", 0>];
}
def StdCall : InheritableAttr {
- let Spellings = [GNU<"stdcall">, GNU<"__stdcall">];
+ let Spellings = [GNU<"stdcall">, CXX11<"gnu", "stdcall">,
+ Keyword<"__stdcall">, Keyword<"_stdcall">];
}
def ThisCall : InheritableAttr {
- let Spellings = [GNU<"thiscall">, GNU<"__thiscall">];
+ let Spellings = [GNU<"thiscall">, CXX11<"gnu", "thiscall">,
+ Keyword<"__thiscall">, Keyword<"_thiscall">];
}
def Pascal : InheritableAttr {
- let Spellings = [GNU<"pascal">];
+ let Spellings = [GNU<"pascal">, Keyword<"__pascal">, Keyword<"_pascal">];
}
def TransparentUnion : InheritableAttr {
- let Spellings = [GNU<"transparent_union">];
+ let Spellings = [GNU<"transparent_union">, CXX11<"gnu", "transparent_union">];
}
def Unavailable : InheritableAttr {
@@ -659,11 +705,11 @@ def ObjCRequiresPropertyDefs : InheritableAttr {
}
def Unused : InheritableAttr {
- let Spellings = [GNU<"unused">];
+ let Spellings = [GNU<"unused">, CXX11<"gnu", "unused">];
}
def Used : InheritableAttr {
- let Spellings = [GNU<"used">];
+ let Spellings = [GNU<"used">, CXX11<"gnu", "used">];
}
def Uuid : InheritableAttr {
@@ -673,21 +719,27 @@ def Uuid : InheritableAttr {
}
def VectorSize : Attr {
- let Spellings = [GNU<"vector_size">];
+ let Spellings = [GNU<"vector_size">, CXX11<"gnu", "vector_size">];
let Args = [ExprArgument<"NumBytes">];
let ASTNode = 0;
}
-def VecTypeHint : Attr {
+def VecTypeHint : InheritableAttr {
let Spellings = [GNU<"vec_type_hint">];
- let ASTNode = 0;
- let SemaHandler = 0;
- let Ignored = 1;
+ let Args = [TypeArgument<"TypeHint">, SourceLocArgument<"TypeLoc">];
}
def Visibility : InheritableAttr {
let Clone = 0;
- let Spellings = [GNU<"visibility">];
+ let Spellings = [GNU<"visibility">, CXX11<"gnu", "visibility">];
+ let Args = [EnumArgument<"Visibility", "VisibilityType",
+ ["default", "hidden", "internal", "protected"],
+ ["Default", "Hidden", "Hidden", "Protected"]>];
+}
+
+def TypeVisibility : InheritableAttr {
+ let Clone = 0;
+ let Spellings = [GNU<"type_visibility">, CXX11<"clang", "type_visibility">];
let Args = [EnumArgument<"Visibility", "VisibilityType",
["default", "hidden", "internal", "protected"],
["Default", "Hidden", "Hidden", "Protected"]>];
@@ -699,11 +751,13 @@ def VecReturn : InheritableAttr {
}
def WarnUnusedResult : InheritableAttr {
- let Spellings = [GNU<"warn_unused_result">];
+ let Spellings = [GNU<"warn_unused_result">,
+ CXX11<"clang", "warn_unused_result">,
+ CXX11<"gnu", "warn_unused_result">];
}
def Weak : InheritableAttr {
- let Spellings = [GNU<"weak">];
+ let Spellings = [GNU<"weak">, CXX11<"gnu", "weak">];
}
def WeakImport : InheritableAttr {
@@ -711,16 +765,27 @@ def WeakImport : InheritableAttr {
}
def WeakRef : InheritableAttr {
- let Spellings = [GNU<"weakref">];
+ let Spellings = [GNU<"weakref">, CXX11<"gnu", "weakref">];
}
def X86ForceAlignArgPointer : InheritableAttr {
let Spellings = [];
}
-// AddressSafety attribute (e.g. for AddressSanitizer)
-def NoAddressSafetyAnalysis : InheritableAttr {
- let Spellings = [GNU<"no_address_safety_analysis">];
+// Attribute to disable AddressSanitizer (or equivalent) checks.
+def NoSanitizeAddress : InheritableAttr {
+ let Spellings = [GNU<"no_address_safety_analysis">,
+ GNU<"no_sanitize_address">];
+}
+
+// Attribute to disable ThreadSanitizer checks.
+def NoSanitizeThread : InheritableAttr {
+ let Spellings = [GNU<"no_sanitize_thread">];
+}
+
+// Attribute to disable MemorySanitizer checks.
+def NoSanitizeMemory : InheritableAttr {
+ let Spellings = [GNU<"no_sanitize_memory">];
}
// C/C++ Thread safety attributes (e.g. for deadlock, data race checking)
@@ -876,29 +941,41 @@ def DLLImport : InheritableAttr {
}
def ForceInline : InheritableAttr {
- let Spellings = [Declspec<"__forceinline">];
+ let Spellings = [Keyword<"__forceinline">];
}
def Win64 : InheritableAttr {
- let Spellings = [Declspec<"w64">];
+ let Spellings = [Keyword<"__w64">];
}
def Ptr32 : InheritableAttr {
- let Spellings = [Declspec<"__ptr32">];
+ let Spellings = [Keyword<"__ptr32">];
}
def Ptr64 : InheritableAttr {
- let Spellings = [Declspec<"__ptr64">];
+ let Spellings = [Keyword<"__ptr64">];
}
-def SingleInheritance : InheritableAttr {
- let Spellings = [Declspec<"__single_inheritance">];
+class MSInheritanceAttr : InheritableAttr;
+
+def SingleInheritance : MSInheritanceAttr {
+ let Spellings = [Keyword<"__single_inheritance">];
+}
+
+def MultipleInheritance : MSInheritanceAttr {
+ let Spellings = [Keyword<"__multiple_inheritance">];
}
-def MultipleInheritance : InheritableAttr {
- let Spellings = [Declspec<"__multiple_inheritance">];
+def VirtualInheritance : MSInheritanceAttr {
+ let Spellings = [Keyword<"__virtual_inheritance">];
+}
+
+// This attribute doesn't have any spellings, but we can apply it implicitly to
+// incomplete types that lack any of the other attributes.
+def UnspecifiedInheritance : MSInheritanceAttr {
+ let Spellings = [];
}
-def VirtualInheritance : InheritableAttr {
- let Spellings = [Declspec<"__virtual_inheritance">];
+def Unaligned : IgnoredAttr {
+ let Spellings = [Keyword<"__unaligned">];
}
diff --git a/include/clang/Basic/AttrKinds.h b/include/clang/Basic/AttrKinds.h
index 150a30e73d3f..bd090ecc0d1b 100644
--- a/include/clang/Basic/AttrKinds.h
+++ b/include/clang/Basic/AttrKinds.h
@@ -24,6 +24,7 @@ enum Kind {
#define ATTR(X) X,
#define LAST_INHERITABLE_ATTR(X) X, LAST_INHERITABLE = X,
#define LAST_INHERITABLE_PARAM_ATTR(X) X, LAST_INHERITABLE_PARAM = X,
+#define LAST_MS_INHERITABLE_ATTR(X) X, LAST_MS_INHERITABLE = X,
#include "clang/Basic/AttrList.inc"
NUM_ATTRS
};
diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def
index d48eadcd6b61..0a513efdbc16 100644
--- a/include/clang/Basic/Builtins.def
+++ b/include/clang/Basic/Builtins.def
@@ -31,6 +31,7 @@
// F -> constant CFString
// G -> id
// H -> SEL
+// M -> struct objc_super
// a -> __builtin_va_list
// A -> "reference" to __builtin_va_list
// V -> Vector, followed by the number of elements and the base type.
@@ -81,6 +82,7 @@
// through an ellipsis
// e -> const, but only when -fmath-errno=0
// j -> returns_twice (like setjmp)
+// u -> arguments are not evaluated for their side-effects
// FIXME: gcc has nonnull
#if defined(BUILTIN) && !defined(LIBBUILTIN)
@@ -394,8 +396,8 @@ BUILTIN(__builtin_bswap32, "UiUi", "nc")
BUILTIN(__builtin_bswap64, "ULLiULLi", "nc")
// Random GCC builtins
-BUILTIN(__builtin_constant_p, "i.", "nct")
-BUILTIN(__builtin_classify_type, "i.", "nct")
+BUILTIN(__builtin_constant_p, "i.", "nctu")
+BUILTIN(__builtin_classify_type, "i.", "nctu")
BUILTIN(__builtin___CFStringMakeConstantString, "FC*cC*", "nc")
BUILTIN(__builtin___NSStringMakeConstantString, "FC*cC*", "nc")
BUILTIN(__builtin_va_start, "vA.", "nt")
@@ -453,17 +455,17 @@ BUILTIN(__builtin_dwarf_sp_column, "Ui", "n")
BUILTIN(__builtin_extend_pointer, "ULLiv*", "n") // _Unwind_Word == uint64_t
// GCC Object size checking builtins
-BUILTIN(__builtin_object_size, "zvC*i", "n")
+BUILTIN(__builtin_object_size, "zvC*i", "nu")
BUILTIN(__builtin___memcpy_chk, "v*v*vC*zz", "nF")
-BUILTIN(__builtin___memccpy_chk, "v*v*vC*iz", "nF")
+BUILTIN(__builtin___memccpy_chk, "v*v*vC*izz", "nF")
BUILTIN(__builtin___memmove_chk, "v*v*vC*zz", "nF")
BUILTIN(__builtin___mempcpy_chk, "v*v*vC*zz", "nF")
BUILTIN(__builtin___memset_chk, "v*v*izz", "nF")
BUILTIN(__builtin___stpcpy_chk, "c*c*cC*z", "nF")
BUILTIN(__builtin___strcat_chk, "c*c*cC*z", "nF")
BUILTIN(__builtin___strcpy_chk, "c*c*cC*z", "nF")
-BUILTIN(__builtin___strlcat_chk, "c*c*cC*zz", "nF")
-BUILTIN(__builtin___strlcpy_chk, "c*c*cC*zz", "nF")
+BUILTIN(__builtin___strlcat_chk, "zc*cC*zz", "nF")
+BUILTIN(__builtin___strlcpy_chk, "zc*cC*zz", "nF")
BUILTIN(__builtin___strncat_chk, "c*c*cC*zz", "nF")
BUILTIN(__builtin___strncpy_chk, "c*c*cC*zz", "nF")
BUILTIN(__builtin___stpncpy_chk, "c*c*cC*zz", "nF")
@@ -760,17 +762,16 @@ LIBBUILTIN(strlcpy, "zc*cC*z", "f", "string.h", ALL_LANGUAGES)
LIBBUILTIN(strlcat, "zc*cC*z", "f", "string.h", ALL_LANGUAGES)
// id objc_msgSend(id, SEL, ...)
LIBBUILTIN(objc_msgSend, "GGH.", "f", "objc/message.h", OBJC_LANG)
-
// long double objc_msgSend_fpret(id self, SEL op, ...)
LIBBUILTIN(objc_msgSend_fpret, "LdGH.", "f", "objc/message.h", OBJC_LANG)
// _Complex long double objc_msgSend_fp2ret(id self, SEL op, ...)
LIBBUILTIN(objc_msgSend_fp2ret, "XLdGH.", "f", "objc/message.h", OBJC_LANG)
-// id objc_msgSend_stret (id, SEL, ...)
-LIBBUILTIN(objc_msgSend_stret, "GGH.", "f", "objc/message.h", OBJC_LANG)
+// void objc_msgSend_stret (id, SEL, ...)
+LIBBUILTIN(objc_msgSend_stret, "vGH.", "f", "objc/message.h", OBJC_LANG)
// id objc_msgSendSuper(struct objc_super *super, SEL op, ...)
-LIBBUILTIN(objc_msgSendSuper, "Gv*H.", "f", "objc/message.h", OBJC_LANG)
+LIBBUILTIN(objc_msgSendSuper, "GM*H.", "f", "objc/message.h", OBJC_LANG)
// void objc_msgSendSuper_stret(struct objc_super *super, SEL op, ...)
-LIBBUILTIN(objc_msgSendSuper_stret, "vv*H.", "f", "objc/message.h", OBJC_LANG)
+LIBBUILTIN(objc_msgSendSuper_stret, "vM*H.", "f", "objc/message.h", OBJC_LANG)
// id objc_getClass(const char *name)
LIBBUILTIN(objc_getClass, "GcC*", "f", "objc/runtime.h", OBJC_LANG)
// id objc_getMetaClass(const char *name)
@@ -833,6 +834,14 @@ 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(cimag, "dXd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cimagf, "fXf", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cimagl, "LdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+
+LIBBUILTIN(creal, "dXd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(crealf, "fXf", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(creall, "LdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+
LIBBUILTIN(copysign, "ddd", "fc", "math.h", ALL_LANGUAGES)
LIBBUILTIN(copysignl, "LdLdLd", "fc", "math.h", ALL_LANGUAGES)
LIBBUILTIN(copysignf, "fff", "fc", "math.h", ALL_LANGUAGES)
@@ -917,5 +926,15 @@ LIBBUILTIN(_Block_object_dispose, "vvC*iC", "f", "Blocks.h", ALL_LANGUAGES)
// Annotation function
BUILTIN(__builtin_annotation, "v.", "tn")
+// Multiprecision Arithmetic Builtins.
+BUILTIN(__builtin_addcs, "UsUsCUsCUsCUs*", "n")
+BUILTIN(__builtin_addc, "UiUiCUiCUiCUi*", "n")
+BUILTIN(__builtin_addcl, "ULiULiCULiCULiCULi*", "n")
+BUILTIN(__builtin_addcll, "ULLiULLiCULLiCULLiCULLi*", "n")
+BUILTIN(__builtin_subcs, "UsUsCUsCUsCUs*", "n")
+BUILTIN(__builtin_subc, "UiUiCUiCUiCUi*", "n")
+BUILTIN(__builtin_subcl, "ULiULiCULiCULiCULi*", "n")
+BUILTIN(__builtin_subcll, "ULLiULLiCULLiCULLiCULLi*", "n")
+
#undef BUILTIN
#undef LIBBUILTIN
diff --git a/include/clang/Basic/Builtins.h b/include/clang/Basic/Builtins.h
index 257daf10ecee..3b88e1550cba 100644
--- a/include/clang/Basic/Builtins.h
+++ b/include/clang/Basic/Builtins.h
@@ -109,6 +109,12 @@ public:
return strchr(GetRecord(ID).Attributes, 'j') != 0;
}
+ /// \brief Returns true if this builtin does not perform the side-effects
+ /// of its arguments.
+ bool isUnevaluated(unsigned ID) const {
+ return strchr(GetRecord(ID).Attributes, 'u') != 0;
+ }
+
/// \brief Return true if this is a builtin for a libc/libm function,
/// with a "__builtin_" prefix (e.g. __builtin_abs).
bool isLibFunction(unsigned ID) const {
diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def
index 5b46f8e6ad11..d536821d55d9 100644
--- a/include/clang/Basic/BuiltinsX86.def
+++ b/include/clang/Basic/BuiltinsX86.def
@@ -624,6 +624,11 @@ BUILTIN(__builtin_ia32_rdrand16_step, "UiUs*", "")
BUILTIN(__builtin_ia32_rdrand32_step, "UiUi*", "")
BUILTIN(__builtin_ia32_rdrand64_step, "UiULLi*", "")
+// RDSEED
+BUILTIN(__builtin_ia32_rdseed16_step, "UiUs*", "")
+BUILTIN(__builtin_ia32_rdseed32_step, "UiUi*", "")
+BUILTIN(__builtin_ia32_rdseed64_step, "UiULLi*", "")
+
// BMI
BUILTIN(__builtin_ia32_bextr_u32, "UiUiUi", "")
BUILTIN(__builtin_ia32_bextr_u64, "ULLiULLiULLi", "")
@@ -739,5 +744,6 @@ BUILTIN(__builtin_ia32_vfrczpd256, "V4dV4d", "")
BUILTIN(__builtin_ia32_xbegin, "i", "")
BUILTIN(__builtin_ia32_xend, "v", "")
BUILTIN(__builtin_ia32_xabort, "vIc", "")
+BUILTIN(__builtin_ia32_xtest, "i", "")
#undef BUILTIN
diff --git a/include/clang/Basic/CharInfo.h b/include/clang/Basic/CharInfo.h
new file mode 100644
index 000000000000..d0afda43709a
--- /dev/null
+++ b/include/clang/Basic/CharInfo.h
@@ -0,0 +1,198 @@
+//===--- clang/Basic/CharInfo.h - Classifying ASCII Characters ------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_BASIC_CHARINFO_H
+#define CLANG_BASIC_CHARINFO_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace clang {
+namespace charinfo {
+ extern const uint16_t InfoTable[256];
+
+ enum {
+ CHAR_HORZ_WS = 0x0001, // '\t', '\f', '\v'. Note, no '\0'
+ CHAR_VERT_WS = 0x0002, // '\r', '\n'
+ CHAR_SPACE = 0x0004, // ' '
+ CHAR_DIGIT = 0x0008, // 0-9
+ CHAR_XLETTER = 0x0010, // a-f,A-F
+ CHAR_UPPER = 0x0020, // A-Z
+ CHAR_LOWER = 0x0040, // a-z
+ CHAR_UNDER = 0x0080, // _
+ CHAR_PERIOD = 0x0100, // .
+ CHAR_RAWDEL = 0x0200, // {}[]#<>%:;?*+-/^&|~!=,"'
+ CHAR_PUNCT = 0x0400 // `$@()
+ };
+
+ enum {
+ CHAR_XUPPER = CHAR_XLETTER | CHAR_UPPER,
+ CHAR_XLOWER = CHAR_XLETTER | CHAR_LOWER
+ };
+} // end namespace charinfo
+
+/// Returns true if this is an ASCII character.
+LLVM_READNONE static inline bool isASCII(char c) {
+ return static_cast<unsigned char>(c) <= 127;
+}
+
+/// Returns true if this is a valid first character of a C identifier,
+/// which is [a-zA-Z_].
+LLVM_READONLY static inline bool isIdentifierHead(unsigned char c,
+ bool AllowDollar = false) {
+ using namespace charinfo;
+ if (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER|CHAR_UNDER))
+ return true;
+ return AllowDollar && c == '$';
+}
+
+/// Returns true if this is a body character of a C identifier,
+/// which is [a-zA-Z0-9_].
+LLVM_READONLY static inline bool isIdentifierBody(unsigned char c,
+ bool AllowDollar = false) {
+ using namespace charinfo;
+ if (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER|CHAR_DIGIT|CHAR_UNDER))
+ return true;
+ return AllowDollar && c == '$';
+}
+
+/// Returns true if this character is horizontal ASCII whitespace:
+/// ' ', '\\t', '\\f', '\\v'.
+///
+/// Note that this returns false for '\\0'.
+LLVM_READONLY static inline bool isHorizontalWhitespace(unsigned char c) {
+ using namespace charinfo;
+ return (InfoTable[c] & (CHAR_HORZ_WS|CHAR_SPACE)) != 0;
+}
+
+/// Returns true if this character is vertical ASCII whitespace: '\\n', '\\r'.
+///
+/// Note that this returns false for '\\0'.
+LLVM_READONLY static inline bool isVerticalWhitespace(unsigned char c) {
+ using namespace charinfo;
+ return (InfoTable[c] & CHAR_VERT_WS) != 0;
+}
+
+/// Return true if this character is horizontal or vertical ASCII whitespace:
+/// ' ', '\\t', '\\f', '\\v', '\\n', '\\r'.
+///
+/// Note that this returns false for '\\0'.
+LLVM_READONLY static inline bool isWhitespace(unsigned char c) {
+ using namespace charinfo;
+ return (InfoTable[c] & (CHAR_HORZ_WS|CHAR_VERT_WS|CHAR_SPACE)) != 0;
+}
+
+/// Return true if this character is an ASCII digit: [0-9]
+LLVM_READONLY static inline bool isDigit(unsigned char c) {
+ using namespace charinfo;
+ return (InfoTable[c] & CHAR_DIGIT) != 0;
+}
+
+/// Return true if this character is a lowercase ASCII letter: [a-z]
+LLVM_READONLY static inline bool isLowercase(unsigned char c) {
+ using namespace charinfo;
+ return (InfoTable[c] & CHAR_LOWER) != 0;
+}
+
+/// Return true if this character is an uppercase ASCII letter: [A-Z]
+LLVM_READONLY static inline bool isUppercase(unsigned char c) {
+ using namespace charinfo;
+ return (InfoTable[c] & CHAR_UPPER) != 0;
+}
+
+/// Return true if this character is an ASCII letter: [a-zA-Z]
+LLVM_READONLY static inline bool isLetter(unsigned char c) {
+ using namespace charinfo;
+ return (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER)) != 0;
+}
+
+/// Return true if this character is an ASCII letter or digit: [a-zA-Z0-9]
+LLVM_READONLY static inline bool isAlphanumeric(unsigned char c) {
+ using namespace charinfo;
+ return (InfoTable[c] & (CHAR_DIGIT|CHAR_UPPER|CHAR_LOWER)) != 0;
+}
+
+/// Return true if this character is an ASCII hex digit: [0-9a-fA-F]
+LLVM_READONLY static inline bool isHexDigit(unsigned char c) {
+ using namespace charinfo;
+ return (InfoTable[c] & (CHAR_DIGIT|CHAR_XLETTER)) != 0;
+}
+
+/// Return true if this character is an ASCII punctuation character.
+///
+/// Note that '_' is both a punctuation character and an identifier character!
+LLVM_READONLY static inline bool isPunctuation(unsigned char c) {
+ using namespace charinfo;
+ return (InfoTable[c] & (CHAR_UNDER|CHAR_PERIOD|CHAR_RAWDEL|CHAR_PUNCT)) != 0;
+}
+
+/// Return true if this character is an ASCII printable character; that is, a
+/// character that should take exactly one column to print in a fixed-width
+/// terminal.
+LLVM_READONLY static inline bool isPrintable(unsigned char c) {
+ using namespace charinfo;
+ return (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER|CHAR_PERIOD|CHAR_PUNCT|
+ CHAR_DIGIT|CHAR_UNDER|CHAR_RAWDEL|CHAR_SPACE)) != 0;
+}
+
+/// Return true if this is the body character of a C preprocessing number,
+/// which is [a-zA-Z0-9_.].
+LLVM_READONLY static inline bool isPreprocessingNumberBody(unsigned char c) {
+ using namespace charinfo;
+ return (InfoTable[c] &
+ (CHAR_UPPER|CHAR_LOWER|CHAR_DIGIT|CHAR_UNDER|CHAR_PERIOD)) != 0;
+}
+
+/// Return true if this is the body character of a C++ raw string delimiter.
+LLVM_READONLY static inline bool isRawStringDelimBody(unsigned char c) {
+ using namespace charinfo;
+ return (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER|CHAR_PERIOD|
+ CHAR_DIGIT|CHAR_UNDER|CHAR_RAWDEL)) != 0;
+}
+
+
+/// Converts the given ASCII character to its lowercase equivalent.
+///
+/// If the character is not an uppercase character, it is returned as is.
+LLVM_READONLY static inline char toLowercase(char c) {
+ if (isUppercase(c))
+ return c + 'a' - 'A';
+ return c;
+}
+
+/// Converts the given ASCII character to its uppercase equivalent.
+///
+/// If the character is not a lowercase character, it is returned as is.
+LLVM_READONLY static inline char toUppercase(char c) {
+ if (isLowercase(c))
+ return c + 'A' - 'a';
+ return c;
+}
+
+
+/// Return true if this is a valid ASCII identifier.
+///
+/// Note that this is a very simple check; it does not accept '$' or UCNs as
+/// valid identifier characters.
+LLVM_READONLY static inline bool isValidIdentifier(StringRef S) {
+ if (S.empty() || !isIdentifierHead(S[0]))
+ return false;
+
+ for (StringRef::iterator I = S.begin(), E = S.end(); I != E; ++I)
+ if (!isIdentifierBody(*I))
+ return false;
+
+ return true;
+}
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/CommentOptions.h b/include/clang/Basic/CommentOptions.h
new file mode 100644
index 000000000000..79b9a6b88350
--- /dev/null
+++ b/include/clang/Basic/CommentOptions.h
@@ -0,0 +1,34 @@
+//===--- CommentOptions.h - Options for parsing comments -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the clang::CommentOptions interface.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_COMMENTOPTIONS_H
+#define LLVM_CLANG_COMMENTOPTIONS_H
+
+#include <string>
+#include <vector>
+
+namespace clang {
+
+/// \brief Options for controlling comment parsing.
+struct CommentOptions {
+ typedef std::vector<std::string> BlockCommandNamesTy;
+
+ /// \brief Command names to treat as block commands in comments.
+ /// Should not include the leading backslash.
+ BlockCommandNamesTy BlockCommandNames;
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/ConvertUTF.h b/include/clang/Basic/ConvertUTF.h
deleted file mode 100644
index cdc42699e3eb..000000000000
--- a/include/clang/Basic/ConvertUTF.h
+++ /dev/null
@@ -1,203 +0,0 @@
-/*===--- ConvertUTF.h - Universal Character Names conversions ---------------===
- *
- * The LLVM Compiler Infrastructure
- *
- * This file is distributed under the University of Illinois Open Source
- * License. See LICENSE.TXT for details.
- *
- *==------------------------------------------------------------------------==*/
-/*
- * Copyright 2001-2004 Unicode, Inc.
- *
- * Disclaimer
- *
- * This source code is provided as is by Unicode, Inc. No claims are
- * made as to fitness for any particular purpose. No warranties of any
- * kind are expressed or implied. The recipient agrees to determine
- * applicability of information provided. If this file has been
- * purchased on magnetic or optical media from Unicode, Inc., the
- * sole remedy for any claim will be exchange of defective media
- * within 90 days of receipt.
- *
- * Limitations on Rights to Redistribute This Code
- *
- * Unicode, Inc. hereby grants the right to freely use the information
- * supplied in this file in the creation of products supporting the
- * Unicode Standard, and to make copies of this file in any form
- * for internal or external distribution as long as this notice
- * remains attached.
- */
-
-/* ---------------------------------------------------------------------
-
- Conversions between UTF32, UTF-16, and UTF-8. Header file.
-
- Several funtions are included here, forming a complete set of
- conversions between the three formats. UTF-7 is not included
- here, but is handled in a separate source file.
-
- Each of these routines takes pointers to input buffers and output
- buffers. The input buffers are const.
-
- Each routine converts the text between *sourceStart and sourceEnd,
- putting the result into the buffer between *targetStart and
- targetEnd. Note: the end pointers are *after* the last item: e.g.
- *(sourceEnd - 1) is the last item.
-
- The return result indicates whether the conversion was successful,
- and if not, whether the problem was in the source or target buffers.
- (Only the first encountered problem is indicated.)
-
- After the conversion, *sourceStart and *targetStart are both
- updated to point to the end of last text successfully converted in
- the respective buffers.
-
- Input parameters:
- sourceStart - pointer to a pointer to the source buffer.
- The contents of this are modified on return so that
- it points at the next thing to be converted.
- targetStart - similarly, pointer to pointer to the target buffer.
- sourceEnd, targetEnd - respectively pointers to the ends of the
- two buffers, for overflow checking only.
-
- These conversion functions take a ConversionFlags argument. When this
- flag is set to strict, both irregular sequences and isolated surrogates
- will cause an error. When the flag is set to lenient, both irregular
- sequences and isolated surrogates are converted.
-
- Whether the flag is strict or lenient, all illegal sequences will cause
- an error return. This includes sequences such as: <F4 90 80 80>, <C0 80>,
- or <A0> in UTF-8, and values above 0x10FFFF in UTF-32. Conformant code
- must check for illegal sequences.
-
- When the flag is set to lenient, characters over 0x10FFFF are converted
- to the replacement character; otherwise (when the flag is set to strict)
- they constitute an error.
-
- Output parameters:
- The value "sourceIllegal" is returned from some routines if the input
- sequence is malformed. When "sourceIllegal" is returned, the source
- value will point to the illegal value that caused the problem. E.g.,
- in UTF-8 when a sequence is malformed, it points to the start of the
- malformed sequence.
-
- Author: Mark E. Davis, 1994.
- Rev History: Rick McGowan, fixes & updates May 2001.
- Fixes & updates, Sept 2001.
-
------------------------------------------------------------------------- */
-
-#ifndef CLANG_BASIC_CONVERTUTF_H
-#define CLANG_BASIC_CONVERTUTF_H
-
-/* ---------------------------------------------------------------------
- The following 4 definitions are compiler-specific.
- The C standard does not guarantee that wchar_t has at least
- 16 bits, so wchar_t is no less portable than unsigned short!
- All should be unsigned values to avoid sign extension during
- bit mask & shift operations.
------------------------------------------------------------------------- */
-
-typedef unsigned int UTF32; /* at least 32 bits */
-typedef unsigned short UTF16; /* at least 16 bits */
-typedef unsigned char UTF8; /* typically 8 bits */
-typedef unsigned char Boolean; /* 0 or 1 */
-
-/* Some fundamental constants */
-#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD
-#define UNI_MAX_BMP (UTF32)0x0000FFFF
-#define UNI_MAX_UTF16 (UTF32)0x0010FFFF
-#define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF
-#define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF
-
-#define UNI_MAX_UTF8_BYTES_PER_CODE_POINT 4
-
-typedef enum {
- conversionOK, /* conversion successful */
- sourceExhausted, /* partial character in source, but hit end */
- targetExhausted, /* insuff. room in target for conversion */
- sourceIllegal /* source sequence is illegal/malformed */
-} ConversionResult;
-
-typedef enum {
- strictConversion = 0,
- lenientConversion
-} ConversionFlags;
-
-/* This is for C++ and does no harm in C */
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-ConversionResult ConvertUTF8toUTF16 (
- const UTF8** sourceStart, const UTF8* sourceEnd,
- UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
-
-ConversionResult ConvertUTF8toUTF32 (
- const UTF8** sourceStart, const UTF8* sourceEnd,
- UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
-
-#ifdef CLANG_NEEDS_THESE_ONE_DAY
-ConversionResult ConvertUTF16toUTF8 (
- const UTF16** sourceStart, const UTF16* sourceEnd,
- UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
-#endif
-
-ConversionResult ConvertUTF32toUTF8 (
- const UTF32** sourceStart, const UTF32* sourceEnd,
- UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
-
-ConversionResult ConvertUTF16toUTF32 (
- const UTF16** sourceStart, const UTF16* sourceEnd,
- UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
-
-ConversionResult ConvertUTF32toUTF16 (
- const UTF32** sourceStart, const UTF32* sourceEnd,
- UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
-#endif
-
-Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd);
-
-Boolean isLegalUTF8String(const UTF8 **source, const UTF8 *sourceEnd);
-
-unsigned getNumBytesForUTF8(UTF8 firstByte);
-
-#ifdef __cplusplus
-}
-
-/*************************************************************************/
-/* Below are LLVM-specific wrappers of the functions above. */
-
-#include "llvm/ADT/StringRef.h"
-
-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. 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, const UTF8 *&ErrorPtr);
-
-/**
- * Convert an Unicode code point to UTF8 sequence.
- *
- * \param Source a Unicode code point.
- * \param [in,out] ResultPtr pointer to the output buffer, needs to be at least
- * \c UNI_MAX_UTF8_BYTES_PER_CODE_POINT bytes. On success \c ResultPtr is
- * updated one past end of the converted sequence.
- *
- * \returns true on success.
- */
-bool ConvertCodePointToUTF8(unsigned Source, char *&ResultPtr);
-
-}
-
-#endif
-
-/* --------------------------------------------------------------------- */
diff --git a/include/clang/Basic/DeclNodes.td b/include/clang/Basic/DeclNodes.td
index 6f2bb3572519..45742bc6655a 100644
--- a/include/clang/Basic/DeclNodes.td
+++ b/include/clang/Basic/DeclNodes.td
@@ -74,4 +74,6 @@ def StaticAssert : Decl;
def Block : Decl, DeclContext;
def ClassScopeFunctionSpecialization : Decl;
def Import : Decl;
+def OMPThreadPrivate : Decl;
+def Empty : Decl;
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h
index e47f3e185741..032763672b47 100644
--- a/include/clang/Basic/Diagnostic.h
+++ b/include/clang/Basic/Diagnostic.h
@@ -23,9 +23,8 @@
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/type_traits.h"
-
-#include <vector>
#include <list>
+#include <vector>
namespace clang {
class DiagnosticConsumer;
@@ -78,7 +77,7 @@ public:
bool BeforePreviousInsertions = false) {
FixItHint Hint;
Hint.RemoveRange =
- CharSourceRange(SourceRange(InsertionLoc, InsertionLoc), false);
+ CharSourceRange::getCharRange(InsertionLoc, InsertionLoc);
Hint.CodeToInsert = Code;
Hint.BeforePreviousInsertions = BeforePreviousInsertions;
return Hint;
@@ -91,7 +90,7 @@ public:
bool BeforePreviousInsertions = false) {
FixItHint Hint;
Hint.RemoveRange =
- CharSourceRange(SourceRange(InsertionLoc, InsertionLoc), false);
+ CharSourceRange::getCharRange(InsertionLoc, InsertionLoc);
Hint.InsertFromRange = FromRange;
Hint.BeforePreviousInsertions = BeforePreviousInsertions;
return Hint;
@@ -176,6 +175,7 @@ private:
bool SuppressAllDiagnostics; // Suppress all diagnostics.
bool ElideType; // Elide common types of templates.
bool PrintTemplateTree; // Print a tree when comparing templates.
+ bool WarnOnSpellCheck; // Emit warning when spellcheck is initiated.
bool ShowColors; // Color printing is enabled.
OverloadsShown ShowOverloads; // Which overload candidates to show.
unsigned ErrorLimit; // Cap of # errors emitted, 0 -> no limit.
@@ -280,6 +280,10 @@ private:
/// \brief Sticky flag set to \c true when an error is emitted.
bool ErrorOccurred;
+ /// \brief Sticky flag set to \c true when an "uncompilable error" occurs.
+ /// I.e. an error that was not upgraded from a warning by -Werror.
+ bool UncompilableErrorOccurred;
+
/// \brief Sticky flag set to \c true when a fatal error is emitted.
bool FatalErrorOccurred;
@@ -432,8 +436,8 @@ public:
///
/// If this and IgnoreAllWarnings are both set, then that one wins.
void setEnableAllWarnings(bool Val) { EnableAllWarnings = Val; }
- bool getEnableAllWarnngs() const { return EnableAllWarnings; }
-
+ bool getEnableAllWarnings() const { return EnableAllWarnings; }
+
/// \brief When set to true, any warnings reported are issued as errors.
void setWarningsAsErrors(bool Val) { WarningsAsErrors = Val; }
bool getWarningsAsErrors() const { return WarningsAsErrors; }
@@ -463,6 +467,10 @@ public:
/// tree format.
void setPrintTemplateTree(bool Val = false) { PrintTemplateTree = Val; }
bool getPrintTemplateTree() { return PrintTemplateTree; }
+
+ /// \brief Warn when spellchecking is initated, for testing.
+ void setWarnOnSpellCheck(bool Val = false) { WarnOnSpellCheck = Val; }
+ bool getWarnOnSpellCheck() { return WarnOnSpellCheck; }
/// \brief Set color printing, so the type diffing will inject color markers
/// into the output.
@@ -559,6 +567,12 @@ public:
SourceLocation Loc = SourceLocation());
bool hasErrorOccurred() const { return ErrorOccurred; }
+
+ /// \brief Errors that actually prevent compilation, not those that are
+ /// upgraded from a warning by -Werror.
+ bool hasUncompilableErrorOccurred() const {
+ return UncompilableErrorOccurred;
+ }
bool hasFatalErrorOccurred() const { return FatalErrorOccurred; }
/// \brief Determine whether any kind of unrecoverable error has occurred.
@@ -574,7 +588,7 @@ public:
/// \brief Return an ID for a diagnostic with the specified message and level.
///
- /// If this is the first request for this diagnosic, it is registered and
+ /// If this is the first request for this diagnostic, it is registered and
/// created, otherwise the existing ID is returned.
unsigned getCustomDiagID(Level L, StringRef Message) {
return Diags->getCustomDiagID((DiagnosticIDs::Level)L, Message);
@@ -598,6 +612,12 @@ public:
ArgToStringCookie = Cookie;
}
+ /// \brief Note that the prior diagnostic was emitted by some other
+ /// \c DiagnosticsEngine, and we may be attaching a note to that diagnostic.
+ void notePriorDiagnosticFrom(const DiagnosticsEngine &Other) {
+ LastDiagLevel = Other.LastDiagLevel;
+ }
+
/// \brief Reset the state of the diagnostic object to its initial
/// configuration.
void Reset();
diff --git a/include/clang/Basic/DiagnosticASTKinds.td b/include/clang/Basic/DiagnosticASTKinds.td
index d869c9983bd7..9be32af9ecc1 100644
--- a/include/clang/Basic/DiagnosticASTKinds.td
+++ b/include/clang/Basic/DiagnosticASTKinds.td
@@ -106,6 +106,9 @@ def note_constexpr_calls_suppressed : Note<
"(skipping %0 call%s0 in backtrace; use -fconstexpr-backtrace-limit=0 to "
"see all)">;
def note_constexpr_call_here : Note<"in call to '%0'">;
+def warn_integer_constant_overflow : Warning<
+ "overflow in expression; result is %0 with type %1">,
+ InGroup<DiagGroup<"integer-overflow">>;
// inline asm related.
let CategoryName = "Inline Assembly Issue" in {
@@ -135,7 +138,8 @@ def err_odr_function_type_inconsistent : Error<
"external function %0 declared with incompatible types in different "
"translation units (%1 vs. %2)">;
def warn_odr_tag_type_inconsistent : Warning<
- "type %0 has incompatible definitions in different translation units">;
+ "type %0 has incompatible definitions in different translation units">,
+ InGroup<DiagGroup<"odr">>;
def note_odr_tag_kind_here: Note<
"%0 is a %select{struct|interface|union|class|enum}1 here">;
def note_odr_field : Note<"field %0 has type %1 here">;
diff --git a/include/clang/Basic/DiagnosticCommentKinds.td b/include/clang/Basic/DiagnosticCommentKinds.td
index e6dfe5b6387c..3880e0e5b4fa 100644
--- a/include/clang/Basic/DiagnosticCommentKinds.td
+++ b/include/clang/Basic/DiagnosticCommentKinds.td
@@ -44,18 +44,18 @@ def note_doc_html_end_tag : Note<
// Commands
def warn_doc_block_command_empty_paragraph : Warning<
- "empty paragraph passed to '\\%0' command">,
+ "empty paragraph passed to '%select{\\|@}0%1' command">,
InGroup<Documentation>, DefaultIgnore;
def warn_doc_block_command_duplicate : Warning<
- "duplicated command '\\%0'">,
+ "duplicated command '%select{\\|@}0%1'">,
InGroup<Documentation>, DefaultIgnore;
def note_doc_block_command_previous : Note<
- "previous command '\\%0' here">;
+ "previous command '%select{\\|@}0%1' here">;
def note_doc_block_command_previous_alias : Note<
- "previous command '\\%0' (an alias of '\\%1') here">;
+ "previous command '%select{\\|@}0%1' (an alias of '\\%2') here">;
// \param command
@@ -69,10 +69,29 @@ def warn_doc_param_spaces_in_direction : Warning<
InGroup<DocumentationPedantic>, DefaultIgnore;
def warn_doc_param_not_attached_to_a_function_decl : Warning<
- "'\\param' command used in a comment that is not attached to "
+ "'%select{\\|@}0param' command used in a comment that is not attached to "
"a function declaration">,
InGroup<Documentation>, DefaultIgnore;
+def warn_doc_function_method_decl_mismatch : Warning<
+ "'%select{\\|@}0%select{function|functiongroup|method|methodgroup|callback}1' "
+ "command should be used in a comment attached to "
+ "%select{a function|a function|an Objective-C method|an Objective-C method|"
+ "a pointer to function}2 declaration">,
+ InGroup<Documentation>, DefaultIgnore;
+
+def warn_doc_api_container_decl_mismatch : Warning<
+ "'%select{\\|@}0%select{class|interface|protocol|struct|union}1' "
+ "command should not be used in a comment attached to a "
+ "non-%select{class|interface|protocol|struct|union}2 declaration">,
+ InGroup<Documentation>, DefaultIgnore;
+
+def warn_doc_container_decl_mismatch : Warning<
+ "'%select{\\|@}0%select{classdesign|coclass|dependency|helper"
+ "|helperclass|helps|instancesize|ownership|performance|security|superclass}1' "
+ "command should not be used in a comment attached to a non-container declaration">,
+ InGroup<Documentation>, DefaultIgnore;
+
def warn_doc_param_duplicate : Warning<
"parameter '%0' is already documented">,
InGroup<Documentation>, DefaultIgnore;
@@ -87,10 +106,10 @@ def warn_doc_param_not_found : Warning<
def note_doc_param_name_suggestion : Note<
"did you mean '%0'?">;
-// \tparam command
+// tparam command
def warn_doc_tparam_not_attached_to_a_template_decl : Warning<
- "'\\tparam' command used in a comment that is not attached to "
+ "'%select{\\|@}0tparam' command used in a comment that is not attached to "
"a template declaration">,
InGroup<Documentation>, DefaultIgnore;
@@ -111,14 +130,14 @@ def note_doc_tparam_name_suggestion : Note<
// \returns command
def warn_doc_returns_not_attached_to_a_function_decl : Warning<
- "'\\%0' command used in a comment that is not attached to "
+ "'%select{\\|@}0%1' command used in a comment that is not attached to "
"a function or method declaration">,
InGroup<Documentation>, DefaultIgnore;
def warn_doc_returns_attached_to_a_void_function : Warning<
- "'\\%0' command used in a comment that is attached to a "
+ "'%select{\\|@}0%1' command used in a comment that is attached to a "
"%select{function returning void|constructor|destructor|"
- "method returning void}1">,
+ "method returning void}2">,
InGroup<Documentation>, DefaultIgnore;
// \deprecated command
@@ -134,7 +153,7 @@ def note_add_deprecation_attr : Note<
// verbatim block commands
def warn_verbatim_block_end_without_start : Warning<
- "'\\%0' command does not terminate a verbatim text block">,
+ "'%select{\\|@}0%1' command does not terminate a verbatim text block">,
InGroup<Documentation>, DefaultIgnore;
} // end of documentation issue category
diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td
index a6ce9d4a2d21..7ff6ae13b4ef 100644
--- a/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/include/clang/Basic/DiagnosticCommonKinds.td
@@ -41,6 +41,9 @@ def err_expected_colon : Error<"expected ':'">;
def err_expected_colon_after_setter_name : Error<
"method name referenced in property setter attribute "
"must end with ':'">;
+def err_expected_string_literal : Error<"expected string literal "
+ "%select{in %1|for diagnostic message in static_assert|"
+ "for optional message in 'availability' attribute}0">;
def err_invalid_string_udl : Error<
"string literal with user-defined suffix cannot be used here">;
def err_invalid_character_udl : Error<
@@ -49,8 +52,6 @@ def err_invalid_numeric_udl : Error<
"numeric literal with user-defined suffix cannot be used here">;
// Parse && Sema
-def ext_no_declarators : ExtWarn<"declaration does not declare anything">,
- InGroup<MissingDeclarations>;
def err_param_redefinition : Error<"redefinition of parameter %0">;
def warn_method_param_redefinition : Warning<"redefinition of method parameter %0">;
def warn_method_param_declaration : Warning<"redeclaration of method parameter %0">,
@@ -71,11 +72,12 @@ def err_module_not_found : Error<"module '%0' not found">, DefaultFatal;
def err_module_not_built : Error<"could not build module '%0'">, DefaultFatal;
def err_module_cycle : Error<"cyclic dependency in module '%0': %1">,
DefaultFatal;
-def warn_module_build : Warning<"building module '%0' from source">,
- InGroup<ModuleBuild>, DefaultIgnore;
def note_pragma_entered_here : Note<"#pragma entered here">;
def note_decl_hiding_tag_type : Note<
"%1 %0 is hidden by a non-type declaration of %0 here">;
+def err_attribute_not_type_attr : Error<
+ "%0 attribute cannot be applied to types">;
+def err_enum_template : Error<"enumeration cannot be a template">;
// Sema && Lex
def ext_c99_longlong : Extension<
@@ -115,4 +117,8 @@ def err_unable_to_rename_temp : Error<
"unable to rename temporary '%0' to output file '%1': '%2'">;
def err_unable_to_make_temp : Error<
"unable to make temporary file: %0">;
+
+// Modules
+def err_module_file_conflict : Error<"module '%0' found in both '%1' and '%2'">;
+
}
diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td
index 4b430351756a..15b894866066 100644
--- a/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/include/clang/Basic/DiagnosticDriverKinds.td
@@ -35,6 +35,8 @@ def err_drv_use_of_Z_option : Error<
"unsupported use of internal gcc -Z option '%0'">;
def err_drv_output_argument_with_multiple_files : Error<
"cannot specify -o when generating multiple output files">;
+def err_no_external_windows_assembler : Error<
+ "there is no external assembler we can use on windows">;
def err_drv_unable_to_remove_file : Error<
"unable to remove file: %0">;
def err_drv_command_failure : Error<
@@ -57,6 +59,8 @@ def err_drv_no_linker_llvm_support : Error<
"'%0': unable to pass LLVM bit-code files to linker">;
def err_drv_no_ast_support : Error<
"'%0': unable to use AST files with this tool">;
+def err_drv_no_module_support : Error<
+ "'%0': unable to use module files with this tool">;
def err_drv_clang_unsupported : Error<
"the clang compiler does not support '%0'">;
def err_drv_clang_unsupported_per_platform : Error<
@@ -67,6 +71,8 @@ def err_drv_command_failed : Error<
"%0 command failed with exit code %1 (use -v to see invocation)">;
def err_drv_command_signalled : Error<
"%0 command failed due to signal (use -v to see invocation)">;
+def err_drv_force_crash : Error<
+ "failing because environment variable '%0' is set">;
def err_drv_invalid_mfloat_abi : Error<
"invalid float ABI '%0'">;
def err_drv_invalid_libcxx_deployment : Error<
@@ -108,19 +114,21 @@ def warn_c_kext : Warning<
"ignoring -fapple-kext which is valid for C++ and Objective-C++ only">;
def warn_drv_input_file_unused : Warning<
"%0: '%1' input unused%select{ when '%3' is present|}2">,
- InGroup<DiagGroup<"unused-command-line-argument">>;
+ InGroup<UnusedCommandLineArgument>;
def warn_drv_input_file_unused_by_cpp : Warning<
"%0: '%1' input unused in cpp mode">,
- InGroup<DiagGroup<"unused-command-line-argument">>;
+ InGroup<UnusedCommandLineArgument>;
def warn_drv_preprocessed_input_file_unused : Warning<
"%0: previously preprocessed input%select{ unused when '%2' is present|}1">,
- InGroup<DiagGroup<"unused-command-line-argument">>;
+ InGroup<UnusedCommandLineArgument>;
def warn_drv_unused_argument : Warning<
"argument unused during compilation: '%0'">,
- InGroup<DiagGroup<"unused-command-line-argument">>;
+ InGroup<UnusedCommandLineArgument>;
def warn_drv_empty_joined_argument : Warning<
"joined argument expects additional value: '%0'">,
- InGroup<DiagGroup<"unused-command-line-argument">>;
+ InGroup<UnusedCommandLineArgument>;
+def warn_drv_unused_sanitizer : Warning<"'%0' is ignored in absence of '%1'">,
+ InGroup<UnusedSanitizeArgument>;
def warn_drv_clang_unsupported : Warning<
"the clang compiler does not support '%0'">;
def warn_drv_deprecated_arg : Warning<
@@ -136,6 +144,8 @@ def warn_drv_objc_gc_unsupported : Warning<
"Objective-C garbage collection is not supported on this platform, ignoring '%0'">;
def warn_drv_pch_not_first_include : Warning<
"precompiled header '%0' was ignored because '%1' is not first '-include'">;
+def warn_missing_sysroot : Warning<"no such sysroot directory: '%0'">,
+ InGroup<DiagGroup<"missing-sysroot">>;
def note_drv_command_failed_diag_msg : Note<
"diagnostic msg: %0">;
diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td
index b7a84764391b..111622e0fe9e 100644
--- a/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -48,8 +48,6 @@ def err_fe_unable_to_interface_with_target : Error<
"unable to interface with target machine">;
def err_fe_unable_to_open_output : Error<
"unable to open output file '%0': '%1'">;
-def err_fe_unable_to_open_logfile : Error<
- "unable to open logfile file '%0': '%1'">;
def err_fe_pth_file_has_no_source_header : Error<
"PTH file '%0' does not designate an original source header file for -include-pth">;
def warn_fe_macro_contains_embedded_newline : Warning<
@@ -60,6 +58,8 @@ 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 err_fe_action_not_available : Error<
+ "action %0 not compiled in">;
def warn_fe_serialized_diag_failure : Warning<
"unable to open file %0 for serializing diagnostics (%1)">,
@@ -100,19 +100,19 @@ def err_relocatable_without_isysroot : Error<
def warn_unknown_warning_option : Warning<
"unknown warning option '%0'">,
- InGroup<DiagGroup<"unknown-warning-option"> >;
+ InGroup<UnknownWarningOption>;
def warn_unknown_negative_warning_option : Warning<
"unknown warning option '%0'">,
- InGroup<DiagGroup<"unknown-warning-option"> >;
+ InGroup<UnknownWarningOption>;
def warn_unknown_warning_option_suggest : Warning<
"unknown warning option '%0'; did you mean '%1'?">,
- InGroup<DiagGroup<"unknown-warning-option"> >;
+ InGroup<UnknownWarningOption>;
def warn_unknown_negative_warning_option_suggest : Warning<
"unknown warning option '%0'; did you mean '%1'?">,
- InGroup<DiagGroup<"unknown-warning-option"> >;
+ InGroup<UnknownWarningOption>;
def warn_unknown_warning_specifier : Warning<
"unknown %0 warning specifier: '%1'">,
- InGroup<DiagGroup<"unknown-warning-option"> >;
+ InGroup<UnknownWarningOption>;
def err_unknown_analyzer_checker : Error<
"no analyzer checkers are associated with '%0'">;
@@ -129,8 +129,6 @@ def err_missing_module_name : Error<
DefaultFatal;
def err_missing_module : Error<
"no module named '%0' declared in module map file '%1'">, DefaultFatal;
-def err_missing_umbrella_header : Error<
- "cannot open umbrella header '%0': %1">, DefaultFatal;
def err_no_submodule : Error<"no submodule named %0 in module '%1'">;
def err_no_submodule_suggest : Error<
"no submodule named %0 in module '%1'; did you mean '%2'?">;
@@ -139,5 +137,11 @@ def warn_missing_submodule : Warning<"missing submodule '%0'">,
def err_module_map_temp_file : Error<
"unable to write temporary module map file '%0'">, DefaultFatal;
def err_module_unavailable : Error<"module '%0' requires feature '%1'">;
-
+def warn_module_config_macro_undef : Warning<
+ "%select{definition|#undef}0 of configuration macro '%1' has no effect on "
+ "the import of '%2'; pass '%select{-D%1=...|-U%1}0' on the command line "
+ "to configure the module">,
+ InGroup<ConfigMacros>;
+def note_module_def_undef_here : Note<
+ "macro was %select{defined|#undef'd}0 here">;
}
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index f9f9ec78309a..a12a4f974eff 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -22,6 +22,8 @@ def : DiagGroup<"address">;
def AddressOfTemporary : DiagGroup<"address-of-temporary">;
def : DiagGroup<"aggregate-return">;
def AmbigMemberTemplate : DiagGroup<"ambiguous-member-template">;
+def ArrayBounds : DiagGroup<"array-bounds">;
+def ArrayBoundsPointerArithmetic : DiagGroup<"array-bounds-pointer-arithmetic">;
def Availability : DiagGroup<"availability">;
def Section : DiagGroup<"section">;
def AutoImport : DiagGroup<"auto-import">;
@@ -36,14 +38,17 @@ def NonLiteralNullConversion : DiagGroup<"non-literal-null-conversion">;
def NullConversion : DiagGroup<"null-conversion">;
def ImplicitConversionFloatingPointToBool :
DiagGroup<"implicit-conversion-floating-point-to-bool">;
+def BadArrayNewLength : DiagGroup<"bad-array-new-length">;
+def BuiltinMacroRedefined : DiagGroup<"builtin-macro-redefined">;
def BuiltinRequiresHeader : DiagGroup<"builtin-requires-header">;
+def C99Compat : DiagGroup<"c99-compat">;
def CXXCompat: DiagGroup<"c++-compat">;
def CastAlign : DiagGroup<"cast-align">;
def : DiagGroup<"cast-qual">;
def : DiagGroup<"char-align">;
def Comment : DiagGroup<"comment">;
+def ConfigMacros : DiagGroup<"config-macros">;
def : DiagGroup<"ctor-dtor-privacy">;
-def DefaultArgSpecialMember : DiagGroup<"default-arg-special-member">;
def GNUDesignator : DiagGroup<"gnu-designator">;
def DeleteNonVirtualDtor : DiagGroup<"delete-non-virtual-dtor">;
@@ -118,10 +123,18 @@ def BitwiseOpParentheses: DiagGroup<"bitwise-op-parentheses">;
def LogicalOpParentheses: DiagGroup<"logical-op-parentheses">;
def ShiftOpParentheses: DiagGroup<"shift-op-parentheses">;
def DanglingElse: DiagGroup<"dangling-else">;
+def DanglingField : DiagGroup<"dangling-field">;
+def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">;
def IgnoredQualifiers : DiagGroup<"ignored-qualifiers">;
def : DiagGroup<"import">;
-def IncompatiblePointerTypes : DiagGroup<"incompatible-pointer-types">;
+def IncompatiblePointerTypesDiscardsQualifiers
+ : DiagGroup<"incompatible-pointer-types-discards-qualifiers">;
+def IncompatiblePointerTypes
+ : DiagGroup<"incompatible-pointer-types",
+ [IncompatiblePointerTypesDiscardsQualifiers]>;
def IncompleteUmbrella : DiagGroup<"incomplete-umbrella">;
+def InvalidNoreturn : DiagGroup<"invalid-noreturn">;
+def InvalidSourceEncoding : DiagGroup<"invalid-source-encoding">;
def KNRPromotedParameter : DiagGroup<"knr-promoted-parameter">;
def : DiagGroup<"init-self">;
def : DiagGroup<"inline">;
@@ -136,19 +149,23 @@ def MissingBraces : DiagGroup<"missing-braces">;
def MissingDeclarations: DiagGroup<"missing-declarations">;
def : DiagGroup<"missing-format-attribute">;
def : DiagGroup<"missing-include-dirs">;
+def MissingNoreturn : DiagGroup<"missing-noreturn">;
def MultiChar : DiagGroup<"multichar">;
def : DiagGroup<"nested-externs">;
def CXX11LongLong : DiagGroup<"c++11-long-long">;
def LongLong : DiagGroup<"long-long", [CXX11LongLong]>;
+def MethodSignatures : DiagGroup<"method-signatures">;
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">;
+def ModuleConflict : DiagGroup<"module-conflict">;
+def NullArithmetic : DiagGroup<"null-arithmetic">;
def NullCharacter : DiagGroup<"null-character">;
def NullDereference : DiagGroup<"null-dereference">;
def InitializerOverrides : DiagGroup<"initializer-overrides">;
def NonNull : DiagGroup<"nonnull">;
+def NonPODVarargs : DiagGroup<"non-pod-varargs">;
def : DiagGroup<"nonportable-cfstrings">;
def NonVirtualDtor : DiagGroup<"non-virtual-dtor">;
def OveralignedType : DiagGroup<"over-aligned">;
@@ -170,6 +187,7 @@ def ObjCMissingSuperCalls : DiagGroup<"objc-missing-super-calls">;
def ObjCRetainBlockProperty : DiagGroup<"objc-noncopy-retain-block-property">;
def ObjCReadonlyPropertyHasSetter : DiagGroup<"objc-readonly-with-setter-property">;
def ObjCRootClass : DiagGroup<"objc-root-class">;
+def DeprecatedObjCIsaUsage : DiagGroup<"deprecated-objc-isa-usage">;
def Packed : DiagGroup<"packed">;
def Padded : DiagGroup<"padded">;
def PointerArith : DiagGroup<"pointer-arith">;
@@ -179,6 +197,7 @@ def PoundPragmaMessage : DiagGroup<"#pragma-messages">,
DiagCategory<"#pragma message Directive">;
def : DiagGroup<"pointer-to-int-cast">;
def : DiagGroup<"redundant-decls">;
+def ReturnStackAddress : DiagGroup<"return-stack-address">;
def ReturnTypeCLinkage : DiagGroup<"return-type-c-linkage">;
def ReturnType : DiagGroup<"return-type", [ReturnTypeCLinkage]>;
def BindToTemporaryCopy : DiagGroup<"bind-to-temporary-copy",
@@ -188,7 +207,6 @@ def SelfAssignment : DiagGroup<"self-assign", [SelfAssignmentField]>;
def SemiBeforeMethodBody : DiagGroup<"semicolon-before-method-body">;
def Sentinel : DiagGroup<"sentinel">;
def MissingMethodReturnType : DiagGroup<"missing-method-return-type">;
-def : DiagGroup<"sequence-point">;
def Shadow : DiagGroup<"shadow">;
def Shorten64To32 : DiagGroup<"shorten-64-to-32">;
def : DiagGroup<"sign-promo">;
@@ -197,6 +215,12 @@ def : DiagGroup<"stack-protector">;
def : DiagGroup<"switch-default">;
def : DiagGroup<"synth">;
def SizeofArrayArgument : DiagGroup<"sizeof-array-argument">;
+def SizeofArrayDecay : DiagGroup<"sizeof-array-decay">;
+def SizeofPointerMemaccess : DiagGroup<"sizeof-pointer-memaccess">;
+def StaticInInline : DiagGroup<"static-in-inline">;
+def StaticLocalInInline : DiagGroup<"static-local-in-inline">;
+def GNUStaticFloatInit : DiagGroup<"gnu-static-float-init">;
+def StaticFloatInit : DiagGroup<"static-float-init", [GNUStaticFloatInit]>;
def StringPlusInt : DiagGroup<"string-plus-int">;
def StrncatSize : DiagGroup<"strncat-size">;
def TautologicalOutOfRangeCompare : DiagGroup<"tautological-constant-out-of-range-compare">;
@@ -206,6 +230,10 @@ def HeaderHygiene : DiagGroup<"header-hygiene">;
def DuplicateDeclSpecifier : DiagGroup<"duplicate-decl-specifier">;
def CompareDistinctPointerType : DiagGroup<"compare-distinct-pointer-types">;
+def Unsequenced : DiagGroup<"unsequenced">;
+// GCC name for -Wunsequenced
+def : DiagGroup<"sequence-point", [Unsequenced]>;
+
// Preprocessor warnings.
def AmbiguousMacro : DiagGroup<"ambiguous-macro">;
@@ -240,17 +268,25 @@ def InvalidPPToken : DiagGroup<"invalid-pp-token">;
def Trigraphs : DiagGroup<"trigraphs">;
def : DiagGroup<"type-limits">;
+def UndefinedReinterpretCast : DiagGroup<"undefined-reinterpret-cast">;
+def ReinterpretBaseClass : DiagGroup<"reinterpret-base-class">;
def Unicode : DiagGroup<"unicode">;
def UninitializedMaybe : DiagGroup<"conditional-uninitialized">;
def UninitializedSometimes : DiagGroup<"sometimes-uninitialized">;
-def Uninitialized : DiagGroup<"uninitialized", [UninitializedSometimes]>;
+def UninitializedStaticSelfInit : DiagGroup<"static-self-init">;
+def Uninitialized : DiagGroup<"uninitialized", [UninitializedSometimes,
+ UninitializedStaticSelfInit]>;
def UnknownPragmas : DiagGroup<"unknown-pragmas">;
+def UnknownWarningOption : DiagGroup<"unknown-warning-option">;
def NSobjectAttribute : DiagGroup<"NSObject-attribute">;
def UnknownAttributes : DiagGroup<"attributes">;
def IgnoredAttributes : DiagGroup<"ignored-attributes">;
def UnnamedTypeTemplateArgs : DiagGroup<"unnamed-type-template-args",
[CXX98CompatUnnamedTypeTemplateArgs]>;
def UnusedArgument : DiagGroup<"unused-argument">;
+def UnusedSanitizeArgument : DiagGroup<"unused-sanitize-argument">;
+def UnusedCommandLineArgument : DiagGroup<"unused-command-line-argument",
+ [UnusedSanitizeArgument]>;
def UnusedComparison : DiagGroup<"unused-comparison">;
def UnusedExceptionParameter : DiagGroup<"unused-exception-parameter">;
def UnneededInternalDecl : DiagGroup<"unneeded-internal-declaration">;
@@ -293,6 +329,7 @@ def VariadicMacros : DiagGroup<"variadic-macros">;
def VectorConversion : DiagGroup<"vector-conversion">; // clang specific
def VexingParse : DiagGroup<"vexing-parse">;
def VLA : DiagGroup<"vla">;
+def VLAExtension : DiagGroup<"vla-extension">;
def VolatileRegisterVar : DiagGroup<"volatile-register-var">;
def Visibility : DiagGroup<"visibility">;
def ZeroLengthArray : DiagGroup<"zero-length-array">;
@@ -379,7 +416,6 @@ def Most : DiagGroup<"most", [
DeleteNonVirtualDtor,
Format,
Implicit,
- IntToPointerCast,
MismatchedTags,
MissingBraces,
MultiChar,
@@ -387,6 +423,7 @@ def Most : DiagGroup<"most", [
ReturnType,
SelfAssignment,
SizeofArrayArgument,
+ SizeofArrayDecay,
StringPlusInt,
Trigraphs,
Uninitialized,
@@ -407,6 +444,7 @@ def ThreadSafety : DiagGroup<"thread-safety",
[ThreadSafetyAttributes,
ThreadSafetyAnalysis,
ThreadSafetyPrecise]>;
+def ThreadSafetyBeta : DiagGroup<"thread-safety-beta">;
// 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
@@ -449,7 +487,8 @@ def C11 : DiagGroup<"c11-extensions">;
def C99 : DiagGroup<"c99-extensions">;
// A warning group for warnings about GCC extensions.
-def GNU : DiagGroup<"gnu", [GNUDesignator, VLA, ZeroLengthArray]>;
+def GNU : DiagGroup<"gnu", [GNUDesignator, VLAExtension,
+ ZeroLengthArray, GNUStaticFloatInit]>;
// A warning group for warnings about code that clang accepts but gcc doesn't.
def GccCompat : DiagGroup<"gcc-compat">;
@@ -460,6 +499,8 @@ def ObjCNonUnifiedException : DiagGroup<"objc-nonunified-exceptions">;
def ObjCProtocolMethodImpl : DiagGroup<"objc-protocol-method-implementation">;
+def ObjCNoPropertyAutoSynthesis : DiagGroup<"objc-property-synthesis">;
+
// ObjC API warning groups.
def ObjCRedundantLiteralUse : DiagGroup<"objc-redundant-literal-use">;
def ObjCRedundantAPIUse : DiagGroup<"objc-redundant-api-use", [
@@ -480,3 +521,6 @@ def ASMOperandWidths : DiagGroup<"asm-operand-widths">;
def ASM : DiagGroup<"asm", [
ASMOperandWidths
]>;
+
+// OpenMP warnings.
+def SourceUsesOpenMP : DiagGroup<"source-uses-openmp">;
diff --git a/include/clang/Basic/DiagnosticIDs.h b/include/clang/Basic/DiagnosticIDs.h
index 11552af8f0af..d35b90742496 100644
--- a/include/clang/Basic/DiagnosticIDs.h
+++ b/include/clang/Basic/DiagnosticIDs.h
@@ -15,13 +15,9 @@
#ifndef LLVM_CLANG_DIAGNOSTICIDS_H
#define LLVM_CLANG_DIAGNOSTICIDS_H
+#include "clang/Basic/LLVM.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/StringRef.h"
-#include "clang/Basic/LLVM.h"
-
-namespace llvm {
- template<typename T, unsigned> class SmallVector;
-}
namespace clang {
class DiagnosticsEngine;
@@ -128,7 +124,7 @@ public:
/// \brief Return an ID for a diagnostic with the specified message and level.
///
- /// If this is the first request for this diagnosic, it is registered and
+ /// If this is the first request for this diagnostic, it is registered and
/// created, otherwise the existing ID is returned.
unsigned getCustomDiagID(Level L, StringRef Message);
@@ -231,10 +227,10 @@ public:
/// \param Diags [out] - On return, the diagnostics in the group.
/// \returns True if the given group is unknown, false otherwise.
bool getDiagnosticsInGroup(StringRef Group,
- llvm::SmallVectorImpl<diag::kind> &Diags) const;
+ SmallVectorImpl<diag::kind> &Diags) const;
/// \brief Get the set of all diagnostic IDs.
- void getAllDiagnostics(llvm::SmallVectorImpl<diag::kind> &Diags) const;
+ void getAllDiagnostics(SmallVectorImpl<diag::kind> &Diags) const;
/// \brief Get the warning option with the closest edit distance to the given
/// group name.
@@ -245,7 +241,7 @@ private:
///
/// \param Diags [out] - On return, the diagnostics in the group.
void getDiagnosticsInGroup(const WarningOption *Group,
- llvm::SmallVectorImpl<diag::kind> &Diags) const;
+ SmallVectorImpl<diag::kind> &Diags) const;
/// \brief Based on the way the client configured the DiagnosticsEngine
/// object, classify the specified diagnostic ID into a Level, consumable by
diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td
index c6c50ab37b87..339788b75da8 100644
--- a/include/clang/Basic/DiagnosticLexKinds.td
+++ b/include/clang/Basic/DiagnosticLexKinds.td
@@ -93,26 +93,63 @@ def ext_multichar_character_literal : ExtWarn<
"multi-character character constant">, InGroup<MultiChar>;
def ext_four_char_character_literal : Extension<
"multi-character character constant">, InGroup<FourByteMultiChar>;
-
-// Literal
-def ext_nonstandard_escape : Extension<
- "use of non-standard escape character '\\%0'">;
-def ext_unknown_escape : ExtWarn<"unknown escape sequence '\\%0'">;
-def err_hex_escape_no_digits : Error<"\\x used with no following hex digits">;
-def err_ucn_escape_no_digits : Error<"\\u used with no following hex digits">;
-def err_ucn_escape_invalid : Error<"invalid universal character">;
-def err_ucn_escape_incomplete : Error<"incomplete universal character name">;
+
+// Unicode and UCNs
+def err_invalid_utf8 : Error<
+ "source file is not valid UTF-8">;
+def err_non_ascii : Error<
+ "non-ASCII characters are not allowed outside of literals and identifiers">;
+def ext_unicode_whitespace : ExtWarn<
+ "treating Unicode character as whitespace">,
+ InGroup<DiagGroup<"unicode-whitespace">>;
+
+def err_hex_escape_no_digits : Error<
+ "\\%0 used with no following hex digits">;
+def warn_ucn_escape_no_digits : Warning<
+ "\\%0 used with no following hex digits; "
+ "treating as '\\' followed by identifier">, InGroup<Unicode>;
+def err_ucn_escape_incomplete : Error<
+ "incomplete universal character name">;
+def warn_ucn_escape_incomplete : Warning<
+ "incomplete universal character name; "
+ "treating as '\\' followed by identifier">, InGroup<Unicode>;
+def note_ucn_four_not_eight : Note<"did you mean to use '\\u'?">;
+
def err_ucn_escape_basic_scs : Error<
"character '%0' cannot be specified by a universal character name">;
def err_ucn_control_character : Error<
"universal character name refers to a control character">;
+def err_ucn_escape_invalid : Error<"invalid universal character">;
+def warn_ucn_escape_surrogate : Warning<
+ "universal character name refers to a surrogate character">,
+ InGroup<Unicode>;
+
+def warn_c99_compat_unicode_id : Warning<
+ "%select{using this character in an identifier|starting an identifier with "
+ "this character}0 is incompatible with C99">,
+ InGroup<C99Compat>, DefaultIgnore;
+def warn_cxx98_compat_unicode_id : Warning<
+ "using this character in an identifier is incompatible with C++98">,
+ InGroup<CXX98Compat>, DefaultIgnore;
+
def warn_cxx98_compat_literal_ucn_escape_basic_scs : Warning<
"specifying character '%0' with a universal character name "
"is incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore;
def warn_cxx98_compat_literal_ucn_control_character : Warning<
"universal character name referring to a control character "
"is incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore;
+def warn_ucn_not_valid_in_c89 : Warning<
+ "universal character names are only valid in C99 or C++; "
+ "treating as '\\' followed by identifier">, InGroup<Unicode>;
+def warn_ucn_not_valid_in_c89_literal : ExtWarn<
+ "universal character names are only valid in C99 or C++">, InGroup<Unicode>;
+
+
+// Literal
+def ext_nonstandard_escape : Extension<
+ "use of non-standard escape character '\\%0'">;
+def ext_unknown_escape : ExtWarn<"unknown escape sequence '\\%0'">;
def err_invalid_decimal_digit : Error<"invalid digit '%0' in decimal constant">;
def err_invalid_binary_digit : Error<"invalid digit '%0' in binary constant">;
def err_invalid_octal_digit : Error<"invalid digit '%0' in octal constant">;
@@ -145,8 +182,9 @@ def ext_string_too_long : Extension<"string literal of length %0 exceeds "
"support">, InGroup<OverlengthStrings>;
def err_character_too_large : Error<
"character too large for enclosing character literal type">;
-def warn_ucn_not_valid_in_c89 : ExtWarn<
- "unicode escape sequences are only valid in C99 or C++">, InGroup<Unicode>;
+def warn_c99_compat_unicode_literal : Warning<
+ "unicode literals are incompatible with C99">,
+ InGroup<C99Compat>, DefaultIgnore;
def warn_cxx98_compat_unicode_literal : Warning<
"unicode literals are incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
@@ -175,12 +213,12 @@ def err_bad_string_encoding : Error<
"illegal character encoding in string literal">;
def warn_bad_string_encoding : ExtWarn<
"illegal character encoding in string literal">,
- InGroup<DiagGroup<"invalid-source-encoding">>;
+ InGroup<InvalidSourceEncoding>;
def err_bad_character_encoding : Error<
"illegal character encoding in character literal">;
def warn_bad_character_encoding : ExtWarn<
"illegal character encoding in character literal">,
- InGroup<DiagGroup<"invalid-source-encoding">>;
+ InGroup<InvalidSourceEncoding>;
def err_lexing_string : Error<"failure when lexing a string">;
@@ -218,9 +256,10 @@ def pp_pragma_sysheader_in_main_file : Warning<
def pp_poisoning_existing_macro : Warning<"poisoning existing macro">;
def pp_out_of_date_dependency : Warning<
"current file is older than dependency %0">;
-def pp_undef_builtin_macro : Warning<"undefining builtin macro">;
-def pp_redef_builtin_macro : Warning<"redefining builtin macro">,
- InGroup<DiagGroup<"builtin-macro-redefined">>;
+def ext_pp_undef_builtin_macro : ExtWarn<"undefining builtin macro">,
+ InGroup<BuiltinMacroRedefined>;
+def ext_pp_redef_builtin_macro : ExtWarn<"redefining builtin macro">,
+ InGroup<BuiltinMacroRedefined>;
def pp_disabled_macro_expansion : Warning<
"disabled expansion of recursive macro">, DefaultIgnore,
InGroup<DiagGroup<"disabled-macro-expansion">>;
@@ -284,7 +323,12 @@ def warn_cxx98_compat_empty_fnmacro_arg : Warning<
InGroup<CXX98CompatPedantic>, DefaultIgnore;
def note_macro_here : Note<"macro %0 defined here">;
+def err_pp_opencl_variadic_macros :
+ Error<"variadic macros not supported in OpenCL">;
+
def err_pp_invalid_directive : Error<"invalid preprocessing directive">;
+def err_pp_directive_required : Error<
+ "%0 must be used within a preprocessing directive">;
def err_pp_file_not_found : Error<"'%0' file not found">, DefaultFatal;
def err_pp_file_not_found_not_fatal : Error<
"'%0' file not found with <angled> include; use \"quotes\" instead">;
@@ -486,6 +530,16 @@ def err_mmap_umbrella_clash : Error<
"umbrella for module '%0' already covers this directory">;
def err_mmap_export_module_id : Error<
"expected an exported module name or '*'">;
+def err_mmap_expected_library_name : Error<
+ "expected %select{library|framework}0 name as a string">;
+def err_mmap_config_macro_submodule : Error<
+ "configuration macros are only allowed on top-level modules">;
+def err_mmap_expected_config_macro : Error<
+ "expected configuration macro name after ','">;
+def err_mmap_expected_conflicts_comma : Error<
+ "expected ',' after conflicting module name">;
+def err_mmap_expected_conflicts_message : Error<
+ "expected a message describing the conflict with '%0'">;
def err_mmap_missing_module_unqualified : Error<
"no module named '%0' visible from '%1'">;
def err_mmap_missing_module_qualified : Error<
@@ -521,7 +575,8 @@ def warn_auto_module_import : Warning<
"treating #%select{include|import|include_next|__include_macros}0 as an "
"import of module '%1'">, InGroup<AutoImport>, DefaultIgnore;
def warn_uncovered_module_header : Warning<
- "umbrella header does not include header '%0'">, InGroup<IncompleteUmbrella>;
+ "umbrella header for module '%0' does not include header '%1'">,
+ 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
index 476ac1e373f0..8e5562c86305 100644
--- a/include/clang/Basic/DiagnosticOptions.def
+++ b/include/clang/Basic/DiagnosticOptions.def
@@ -54,6 +54,7 @@ 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(ShowPresumedLoc, 1, 0) /// Show presumed location for diagnostics.
DIAGOPT(ShowOptionNames, 1, 0) /// Show the option name for mappable
/// diagnostics.
DIAGOPT(ShowNoteIncludeStack, 1, 0) /// Show include stacks for notes.
@@ -71,6 +72,7 @@ DIAGOPT(VerifyDiagnostics, 1, 0) /// Check that diagnostics match the expected
DIAGOPT(ElideType, 1, 0) /// Elide identical types in template diffing
DIAGOPT(ShowTemplateTree, 1, 0) /// Print a template tree when diffing
+DIAGOPT(WarnOnSpellCheck, 1, 0) /// -fwarn-on-spellcheck
VALUE_DIAGOPT(ErrorLimit, 32, 0) /// Limit # errors emitted.
/// Limit depth of macro expansion backtrace.
diff --git a/include/clang/Basic/DiagnosticOptions.h b/include/clang/Basic/DiagnosticOptions.h
index b75cb0c24da3..2fba3844a09c 100644
--- a/include/clang/Basic/DiagnosticOptions.h
+++ b/include/clang/Basic/DiagnosticOptions.h
@@ -10,8 +10,8 @@
#ifndef LLVM_CLANG_BASIC_DIAGNOSTICOPTIONS_H
#define LLVM_CLANG_BASIC_DIAGNOSTICOPTIONS_H
+#include "clang/Basic/LLVM.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
-
#include <string>
#include <vector>
@@ -24,9 +24,8 @@ enum OverloadsShown {
Ovl_Best ///< Show just the "best" overload candidates.
};
-/// DiagnosticOptions - Options for controlling the compiler diagnostics
-/// engine.
-class DiagnosticOptions : public llvm::RefCountedBase<DiagnosticOptions>{
+/// \brief Options for controlling the compiler diagnostics engine.
+class DiagnosticOptions : public RefCountedBase<DiagnosticOptions>{
public:
enum TextDiagnosticFormat { Clang, Msvc, Vi };
@@ -49,14 +48,10 @@ protected:
#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.
+ /// \brief The file to log diagnostic output to.
std::string DiagnosticLogFile;
- /// The file to serialize diagnostics to (non-appending).
+ /// \brief The file to serialize diagnostics to (non-appending).
std::string DiagnosticSerializationFile;
/// The list of -W... options used to alter the diagnostic mappings, with the
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index 21eeccb5a3e4..04a433c0a6a2 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -18,9 +18,6 @@ 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<
@@ -98,6 +95,8 @@ def warn_cxx98_compat_enum_fixed_underlying_type : Warning<
def warn_cxx98_compat_alignof : Warning<
"alignof expressions are incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
+def ext_alignof_expr : ExtWarn<
+ "%0 applied to an expression is a GNU extension">, InGroup<GNU>;
def warn_microsoft_dependent_exists : Warning<
"dependent %select{__if_not_exists|__if_exists}0 declarations are ignored">,
@@ -113,6 +112,9 @@ def note_previous_default_assoc : Note<
def ext_c11_alignment : Extension<
"%0 is a C11-specific feature">, InGroup<C11>;
+def ext_c11_noreturn : Extension<
+ "_Noreturn functions are a C11-specific feature">, InGroup<C11>;
+
def ext_gnu_indirect_goto : Extension<
"use of GNU indirect-goto extension">, InGroup<GNU>;
def ext_gnu_address_of_label : Extension<
@@ -225,13 +227,10 @@ def note_missing_selector_name : Note<
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<
"use of address-of-label extension outside of a function body">;
-def err_expected_string_literal : Error<"expected string literal">;
def err_asm_operand_wide_string_literal : Error<
"cannot use %select{unicode|wide}0 string literal in 'asm'">;
def err_expected_selector_for_method : Error<
@@ -364,7 +363,7 @@ def note_objc_container_start : Note<
"%select{class|protocol|category|class extension|implementation"
"|category implementation}0 started here">;
def warn_objc_protocol_qualifier_missing_id : Warning<
- "protocol qualifiers without 'id' is archaic">;
+ "protocol has no object type specified; defaults to qualified 'id'">;
def err_objc_unknown_at : Error<"expected an Objective-C directive after '@'">;
def err_illegal_super_cast : Error<
"cannot cast 'super' (it isn't an expression)">;
@@ -400,6 +399,11 @@ def err_objc_properties_require_objc2 : Error<
"properties are an Objective-C 2 feature">;
def err_objc_unexpected_attr : Error<
"prefix attribute must be followed by an interface or protocol">;
+def err_objc_postfix_attribute : Error <
+ "postfix attributes are not allowed on Objective-C directives">;
+def err_objc_postfix_attribute_hint : Error <
+ "postfix attributes are not allowed on Objective-C directives, place"
+ " them in front of '%select{@interface|@protocol}0'">;
def err_objc_directive_only_in_protocol : Error<
"directive may only be specified in protocols only">;
def err_missing_catch_finally : Error<
@@ -407,6 +411,8 @@ def err_missing_catch_finally : Error<
def err_objc_concat_string : Error<"unexpected token after Objective-C string">;
def err_expected_objc_container : Error<
"'@end' must appear in an Objective-C context">;
+def err_objc_unexpected_atend : Error<
+ "'@end' appears where closing brace '}' is expected">;
def error_property_ivar_decl : Error<
"property synthesize requires specification of an ivar">;
def err_synthesized_property_name : Error<
@@ -425,6 +431,8 @@ def err_declaration_does_not_declare_param : Error<
def err_no_matching_param : Error<"parameter named %0 is missing">;
/// C++ parser diagnostics
+def err_invalid_operator_on_type : Error<
+ "cannot use %select{dot|arrow}0 operator on a type">;
def err_expected_unqualified_id : Error<
"expected %select{identifier|unqualified-id}0">;
def err_func_def_no_params : Error<
@@ -464,11 +472,16 @@ def err_destructor_template_id : Error<
"destructor name %0 does not refer to a template">;
def err_default_arg_unparsed : Error<
"unexpected end of default argument expression">;
-def err_parser_impl_limit_overflow : Error<
- "parser recursion limit reached, program too complex">, DefaultFatal;
+def err_bracket_depth_exceeded : Error<
+ "bracket nesting level exceeded maximum of %0">, DefaultFatal;
+def note_bracket_depth : Note<
+ "use -fbracket-depth=N to increase maximum nesting level">;
def err_misplaced_ellipsis_in_declaration : Error<
"'...' must %select{immediately precede declared identifier|"
"be innermost component of anonymous pack declaration}0">;
+def ext_abstract_pack_declarator_parens : ExtWarn<
+ "ISO C++11 requires a parenthesized pack declaration to have a name">,
+ InGroup<DiagGroup<"anonymous-pack-parens">>;
// C++ derived classes
def err_dup_virtual : Error<"duplicate 'virtual' in base specifier">;
@@ -504,12 +517,12 @@ def err_cxx11_attribute_forbids_arguments : Error<
"attribute '%0' cannot have an argument list">;
def err_cxx11_attribute_forbids_ellipsis : Error<
"attribute '%0' cannot be used as an attribute pack">;
+def err_cxx11_attribute_repeated : Error<
+ "attribute %0 cannot appear multiple times in an attribute specifier">;
def err_attributes_not_allowed : Error<"an attribute list cannot appear here">;
def err_l_square_l_square_not_attribute : Error<
"C++11 only allows consecutive left square brackets when "
"introducing an attribute">;
-def err_alignas_pack_exp_unsupported : Error<
- "pack expansions in alignment specifiers are not supported yet">;
def err_ms_declspec_type : Error<
"__declspec attributes must be an identifier or string literal">;
def warn_ms_declspec_unknown : Warning<
@@ -548,7 +561,6 @@ def err_explicit_instantiation_with_definition : Error<
"explicit template instantiation cannot have a definition; if this "
"definition is meant to be an explicit specialization, add '<>' after the "
"'template' keyword">;
-def err_enum_template : Error<"enumeration cannot be a template">;
def err_explicit_instantiation_enum : Error<
"enumerations cannot be explicitly instantiated">;
def err_expected_template_parameter : Error<"expected template parameter">;
@@ -764,14 +776,25 @@ def err_seh___except_filter : Error<
def err_seh___finally_block : Error<
"%0 only allowed in __finally block">;
-
+
+// OpenMP support.
+def warn_pragma_omp_ignored : Warning <
+ "unexpected '#pragma omp ...' in program">, InGroup<SourceUsesOpenMP>, DefaultIgnore;
+def warn_omp_extra_tokens_at_eol : Warning <
+ "extra tokens at end of '#pragma omp %0' are ignored">,
+ InGroup<ExtraTokens>;
+def err_omp_unknown_directive : Error <
+ "expected an OpenMP directive">;
+def err_omp_unexpected_directive : Error <
+ "unexpected OpenMP directive '#pragma omp %0'">;
+
} // end of Parse Issue category.
let CategoryName = "Modules Issue" in {
def err_module_expected_ident : Error<
"expected a module name after module import">;
def err_module_expected_semi : Error<
- "expected a semicolon name after module name">;
+ "expected ';' after module name">;
}
} // end of Parser diagnostics
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 0d64bf38ad7c..c4815cd7ea6c 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -20,6 +20,11 @@ def warn_variables_not_in_loop_body : Warning<
"used in loop condition not modified in loop body">,
InGroup<DiagGroup<"loop-analysis">>, DefaultIgnore;
+def warn_duplicate_enum_values : Warning<
+ "element %0 has been implicitly assigned %1 which another element has "
+ "been assigned">, InGroup<DiagGroup<"duplicate-enum">>, DefaultIgnore;
+def note_duplicate_element : Note<"element %0 also has value %1">;
+
// Constant expressions
def err_expr_not_ice : Error<
"expression is not an %select{integer|integral}0 constant expression">;
@@ -70,7 +75,9 @@ def warn_double_const_requires_fp64 : Warning<
// C99 variable-length arrays
def ext_vla : Extension<"variable length arrays are a C99 feature">,
- InGroup<VLA>;
+ InGroup<VLAExtension>;
+def warn_vla_used : Warning<"variable length array used">,
+ InGroup<VLA>, DefaultIgnore;
def err_vla_non_pod : Error<"variable length array of non-POD element type %0">;
def err_vla_in_sfinae : Error<
"variable length array cannot be formed during template argument deduction">;
@@ -209,6 +216,8 @@ def warn_use_out_of_scope_declaration : Warning<
"use of out-of-scope declaration of %0">;
def err_inline_non_function : Error<
"'inline' can only appear on functions">;
+def err_noreturn_non_function : Error<
+ "'_Noreturn' can only appear on functions">;
def warn_qual_return_type : Warning<
"'%0' type qualifier%s1 on return type %plural{1:has|:have}1 no effect">,
InGroup<IgnoredQualifiers>, DefaultIgnore;
@@ -245,19 +254,20 @@ def note_using_decl_constructor_conflict_previous_ctor : Note<
"previous constructor">;
def note_using_decl_constructor_conflict_previous_using : Note<
"previously inherited here">;
+def warn_using_decl_constructor_ellipsis : Warning<
+ "inheriting constructor does not inherit ellipsis">,
+ InGroup<DiagGroup<"inherited-variadic-ctor">>;
+def note_using_decl_constructor_ellipsis : Note<
+ "constructor declared with ellipsis here">;
def err_using_decl_can_not_refer_to_class_member : Error<
"using declaration can not refer to class member">;
def err_using_decl_can_not_refer_to_namespace : Error<
"using declaration can not refer to namespace">;
def err_using_decl_constructor : Error<
"using declaration can not refer to a constructor">;
-def err_using_decl_constructor_unsupported : Error<
- "inheriting constructors are not supported">;
-// FIXME: Replace the above error with this warning if support for
-// inheriting constructors is implemented.
-//def warn_cxx98_compat_using_decl_constructor : Warning<
-// "inheriting constructors are incompatible with C++98">,
-// InGroup<CXX98Compat>, DefaultIgnore;
+def warn_cxx98_compat_using_decl_constructor : Warning<
+ "inheriting constructors are incompatible with C++98">,
+ InGroup<CXX98Compat>, DefaultIgnore;
def err_using_decl_destructor : Error<
"using declaration can not refer to a destructor">;
def err_using_decl_template_id : Error<
@@ -304,10 +314,10 @@ def err_falloff_nonvoid_block : Error<
"control reaches end of non-void block">;
def warn_suggest_noreturn_function : Warning<
"%select{function|method}0 %1 could be declared with attribute 'noreturn'">,
- InGroup<DiagGroup<"missing-noreturn">>, DefaultIgnore;
+ InGroup<MissingNoreturn>, DefaultIgnore;
def warn_suggest_noreturn_block : Warning<
"block could be declared with attribute 'noreturn'">,
- InGroup<DiagGroup<"missing-noreturn">>, DefaultIgnore;
+ InGroup<MissingNoreturn>, DefaultIgnore;
def warn_unreachable : Warning<"will never be executed">,
InGroup<DiagGroup<"unreachable-code">>, DefaultIgnore;
@@ -331,7 +341,8 @@ def warn_implicit_decl_requires_ucontext : Warning<
"<ucontext.h>">,
InGroup<BuiltinRequiresHeader>;
def warn_redecl_library_builtin : Warning<
- "incompatible redeclaration of library function %0">;
+ "incompatible redeclaration of library function %0">,
+ InGroup<DiagGroup<"incompatible-library-redeclaration">>;
def err_builtin_definition : Error<"definition of builtin function %0">;
def err_types_compatible_p_in_cplusplus : Error<
"__builtin_types_compatible_p is not valid in C++">;
@@ -347,7 +358,7 @@ def note_bad_memaccess_silence : Note<
def warn_sizeof_pointer_expr_memaccess : Warning<
"'%0' call operates on objects of type %1 while the size is based on a "
"different type %2">,
- InGroup<DiagGroup<"sizeof-pointer-memaccess">>;
+ InGroup<SizeofPointerMemaccess>;
def warn_sizeof_pointer_expr_memaccess_note : Note<
"did you mean to %select{dereference the argument to 'sizeof' (and multiply "
"it by the number of elements)|remove the addressof in the argument to "
@@ -356,7 +367,7 @@ def warn_sizeof_pointer_expr_memaccess_note : Note<
def warn_sizeof_pointer_type_memaccess : Warning<
"argument to 'sizeof' in %0 call is the same pointer type %1 as the "
"%select{destination|source}2; expected %3 or an explicit length">,
- InGroup<DiagGroup<"sizeof-pointer-memaccess">>;
+ InGroup<SizeofPointerMemaccess>;
def warn_strlcpycat_wrong_size : Warning<
"size argument in %0 call appears to be size of the source; expected the size of "
"the destination">,
@@ -376,17 +387,21 @@ def note_strncat_wrong_size : Note<
"the terminating null byte">;
/// main()
-// static/inline main() are not errors in C, just in C++.
+// static main() is not an error in C, just in C++.
def warn_static_main : Warning<"'main' should not be declared static">,
InGroup<Main>;
def err_static_main : Error<"'main' is not allowed to be declared static">;
def err_inline_main : Error<"'main' is not allowed to be declared inline">;
+def ext_noreturn_main : ExtWarn<
+ "'main' is not allowed to be declared _Noreturn">, InGroup<Main>;
+def note_main_remove_noreturn : Note<"remove '_Noreturn'">;
def err_constexpr_main : Error<
"'main' is not allowed to be declared constexpr">;
def err_main_template_decl : Error<"'main' cannot be a template">;
def err_main_returns_nonint : Error<"'main' must return 'int'">;
def ext_main_returns_nonint : ExtWarn<"return type of 'main' is not 'int'">,
InGroup<MainReturnType>;
+def note_main_change_return_type : Note<"change return type to 'int'">;
def err_main_surplus_args : Error<"too many parameters (%0) for 'main': "
"must be 0, 2, or 3">;
def warn_main_one_arg : Warning<"only one parameter on 'main' declaration">,
@@ -396,6 +411,8 @@ def err_main_arg_wrong : Error<"%select{first|second|third|fourth}0 "
"platform-specific data}0) must be of type %1">;
/// parser diagnostics
+def ext_no_declarators : ExtWarn<"declaration does not declare anything">,
+ InGroup<MissingDeclarations>;
def ext_typedef_without_a_name : ExtWarn<"typedef requires a name">,
InGroup<MissingDeclarations>;
def err_typedef_not_identifier : Error<"typedef name must be an identifier">;
@@ -406,6 +423,15 @@ def err_object_cannot_be_passed_returned_by_value : Error<
"; 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 err_opencl_half_load_store : Error<
+ "%select{loading directly from|assigning directly to}0 pointer to type %1 is not allowed">;
+def err_opencl_cast_to_half : Error<"casting to type %0 is not allowed">;
+def err_opencl_half_declaration : Error<
+ "declaring variable of type %0 is not allowed">;
+def err_opencl_half_argument : Error<
+ "declaring function argument of type %0 is not allowed; did you forget * ?">;
+def err_opencl_half_return : Error<
+ "declaring function return value of type %0 is not allowed; did you forget * ?">;
def warn_enum_value_overflow : Warning<"overflow in enumeration value">;
def warn_pragma_options_align_reset_failed : Warning<
"#pragma options align=reset failed: %0">;
@@ -456,7 +482,7 @@ def warn_readonly_property : Warning<
"'readwrite' of property inherited from %1">;
def warn_property_attribute : Warning<
- "property %0 '%1' attribute does not match the property inherited from %2">;
+ "'%1' attribute on property %0 does not match the property inherited from %2">;
def warn_property_types_are_incompatible : Warning<
"property type %0 is incompatible with type %1 inherited from %2">;
def err_undef_interface : Error<"cannot find interface declaration for %0">;
@@ -499,9 +525,8 @@ def err_conflicting_ivar_name : Error<
"conflicting instance variable names: %0 vs %1">;
def err_inconsistant_ivar_count : Error<
"inconsistent number of instance variables specified">;
-def warn_incomplete_impl : Warning<"incomplete implementation">,
+def warn_undef_method_impl : Warning<"method definition for %0 not found">,
InGroup<DiagGroup<"incomplete-implementation">>;
-def note_undef_method_impl : Note<"method definition for %0 not found">;
def note_required_for_protocol_at :
Note<"required for direct or indirect protocol %0">;
@@ -523,7 +548,7 @@ def warn_conflicting_overriding_ret_type_modifiers : Warning<
def warn_conflicting_ret_type_modifiers : Warning<
"conflicting distributed object modifiers on return type "
"in implementation of %0">,
- InGroup<DiagGroup<"distributed-object-modifiers">>;
+ InGroup<DistributedObjectModifiers>;
def warn_non_covariant_overriding_ret_types : Warning<
"conflicting return type in "
@@ -533,7 +558,7 @@ def warn_non_covariant_overriding_ret_types : Warning<
def warn_non_covariant_ret_types : Warning<
"conflicting return type in "
"implementation of %0: %1 vs %2">,
- InGroup<DiagGroup<"method-signatures">>, DefaultIgnore;
+ InGroup<MethodSignatures>, DefaultIgnore;
def warn_conflicting_overriding_param_types : Warning<
"conflicting parameter types in "
@@ -548,7 +573,7 @@ def warn_conflicting_param_types : Warning<
def warn_conflicting_param_modifiers : Warning<
"conflicting distributed object modifiers on parameter type "
"in implementation of %0">,
- InGroup<DiagGroup<"distributed-object-modifiers">>;
+ InGroup<DistributedObjectModifiers>;
def warn_conflicting_overriding_param_modifiers : Warning<
"conflicting distributed object modifiers on parameter type "
@@ -563,7 +588,7 @@ def warn_non_contravariant_overriding_param_types : Warning<
def warn_non_contravariant_param_types : Warning<
"conflicting parameter types in "
"implementation of %0: %1 vs %2">,
- InGroup<DiagGroup<"method-signatures">>, DefaultIgnore;
+ InGroup<MethodSignatures>, DefaultIgnore;
def warn_conflicting_overriding_variadic :Warning<
"conflicting variadic declaration of method and its "
@@ -609,9 +634,11 @@ def warn_objc_property_no_assignment_attribute : Warning<
"'assign' is assumed">,
InGroup<ObjCPropertyNoAttribute>;
def warn_objc_isa_use : Warning<
- "direct access to objective-c's isa is deprecated "
- "in favor of object_setClass() and object_getClass()">,
- InGroup<DiagGroup<"deprecated-objc-isa-usage">>;
+ "direct access to Objective-C's isa is deprecated in favor of "
+ "object_getClass()">, InGroup<DeprecatedObjCIsaUsage>;
+def warn_objc_isa_assign : Warning<
+ "assignment to Objective-C's isa is deprecated in favor of "
+ "object_setClass()">, InGroup<DeprecatedObjCIsaUsage>;
def warn_objc_property_default_assign_on_object : Warning<
"default property attribute 'assign' not appropriate for non-GC object">,
InGroup<ObjCPropertyNoAttribute>;
@@ -643,6 +670,15 @@ def warn_auto_synthesizing_protocol_property :Warning<
"auto property synthesis will not synthesize property"
" declared in a protocol">,
InGroup<DiagGroup<"objc-protocol-property-synthesis">>;
+def warn_no_autosynthesis_shared_ivar_property : Warning <
+ "auto property synthesis will not synthesize property "
+ "'%0' because it cannot share an ivar with another synthesized property">,
+ InGroup<ObjCNoPropertyAutoSynthesis>;
+def warn_no_autosynthesis_property : Warning<
+ "auto property synthesis will not synthesize property "
+ "'%0' because it is 'readwrite' but it will be synthesized 'readonly' "
+ "via another property">,
+ InGroup<ObjCNoPropertyAutoSynthesis>;
def warn_autosynthesis_property_ivar_match :Warning<
"autosynthesized property %0 will use %select{|synthesized}1 instance variable "
"%2, not existing instance variable %3">,
@@ -684,6 +720,8 @@ def error_category_property : Error<
"class implementation">;
def note_property_declare : Note<
"property declared here">;
+def note_property_synthesize : Note<
+ "property synthesized here">;
def error_synthesize_category_decl : Error<
"@synthesize not allowed in a category's implementation">;
def error_reference_property : Error<
@@ -762,9 +800,9 @@ def warn_undeclared_selector : Warning<
def warn_implicit_atomic_property : Warning<
"property is assumed atomic by default">, InGroup<ImplicitAtomic>, DefaultIgnore;
def note_auto_readonly_iboutlet_fixup_suggest : Note<
- "readonly IBOutlet property should be changed to be readwrite">;
+ "property should be changed to be readwrite">;
def warn_auto_readonly_iboutlet_property : Warning<
- "readonly IBOutlet property when auto-synthesized may "
+ "readonly IBOutlet property '%0' when auto-synthesized may "
"not work correctly with 'nib' loader">,
InGroup<DiagGroup<"readonly-iboutlet-property">>;
def warn_auto_implicit_atomic_property : Warning<
@@ -829,6 +867,8 @@ 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_using_decl_friend : Error<
+ "cannot befriend target of using declaration">;
def err_invalid_member_in_interface : Error<
"%select{data member |non-public member function |static member function |"
@@ -892,6 +932,8 @@ def err_distant_exception_spec : Error<
def err_incomplete_in_exception_spec : Error<
"%select{|pointer to |reference to }0incomplete type %1 is not allowed "
"in exception specification">;
+def err_rref_in_exception_spec : Error<
+ "rvalue reference type %0 is not allowed in exception specification">;
def err_mismatched_exception_spec : Error<
"exception specification in declaration does not match previous declaration">;
def warn_mismatched_exception_spec : ExtWarn<
@@ -1063,14 +1105,18 @@ def note_field_decl : Note<"member 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_implicit_param_decl : Note<"%0 is an implicit parameter">;
def note_member_synthesized_at : Note<
"implicit default %select{constructor|copy constructor|move constructor|copy "
"assignment operator|move assignment operator|destructor}0 for %1 first "
"required here">;
+def note_inhctor_synthesized_at : Note<
+ "inheriting constructor for %0 first required here">;
def err_missing_default_ctor : Error<
- "%select{|implicit default }0constructor for %1 must explicitly initialize "
- "the %select{base class|member}2 %3 which does not have a default "
+ "%select{|implicit default |inheriting }0constructor for %1 must explicitly "
+ "initialize the %select{base class|member}2 %3 which does not have a default "
"constructor">;
+
def err_illegal_union_or_anon_struct_member : Error<
"%select{anonymous struct|union}0 member %1 has a non-trivial "
"%select{constructor|copy constructor|move constructor|copy assignment "
@@ -1080,16 +1126,38 @@ def warn_cxx98_compat_nontrivial_union_or_anon_struct_member : Warning<
"%select{constructor|copy constructor|move constructor|copy assignment "
"operator|move assignment operator|destructor}2 is incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
+
+def note_nontrivial_virtual_dtor : Note<
+ "destructor for %0 is not trivial because it is virtual">;
def note_nontrivial_has_virtual : Note<
"because type %0 has a virtual %select{member function|base class}1">;
-def note_nontrivial_has_nontrivial : Note<
- "because type %0 has a %select{member|base class}1 with a non-trivial "
- "%select{constructor|copy constructor|move constructor|copy assignment "
- "operator|move assignment operator|destructor}2">;
-def note_nontrivial_user_defined : Note<
- "because type %0 has a user-declared %select{constructor|copy constructor|"
- "move constructor|copy assignment operator|move assignment operator|"
- "destructor}1">;
+def note_nontrivial_no_def_ctor : Note<
+ "because %select{base class of |field of |}0type %1 has no "
+ "default constructor">;
+def note_user_declared_ctor : Note<
+ "implicit default constructor suppressed by user-declared constructor">;
+def note_nontrivial_no_copy : Note<
+ "because no %select{<<ERROR>>|constructor|constructor|assignment operator|"
+ "assignment operator|<<ERROR>>}2 can be used to "
+ "%select{<<ERROR>>|copy|move|copy|move|<<ERROR>>}2 "
+ "%select{base class|field|an object}0 of type %3">;
+def note_nontrivial_user_provided : Note<
+ "because %select{base class of |field of |}0type %1 has a user-provided "
+ "%select{default constructor|copy constructor|move constructor|"
+ "copy assignment operator|move assignment operator|destructor}2">;
+def note_nontrivial_in_class_init : Note<
+ "because field %0 has an initializer">;
+def note_nontrivial_param_type : Note<
+ "because its parameter is %diff{of type $, not $|of the wrong type}2,3">;
+def note_nontrivial_default_arg : Note<"because it has a default argument">;
+def note_nontrivial_variadic : Note<"because it is a variadic function">;
+def note_nontrivial_subobject : Note<
+ "because the function selected to %select{construct|copy|move|copy|move|"
+ "destroy}2 %select{base class|field}0 of type %1 is not trivial">;
+def note_nontrivial_objc_ownership : Note<
+ "because type %0 has a member with %select{no|no|__strong|__weak|"
+ "__autoreleasing}1 ownership">;
+
def err_static_data_member_not_allowed_in_anon_struct : Error<
"static data member %0 not allowed in anonymous struct">;
def ext_static_data_member_in_union : ExtWarn<
@@ -1100,14 +1168,17 @@ def warn_cxx98_compat_static_data_member_in_union : Warning<
def err_union_member_of_reference_type : Error<
"union member %0 has reference type %1">;
def ext_anonymous_struct_union_qualified : Extension<
- "anonymous %select{struct|union}0 cannot be '%select{const|volatile|"
- "restrict}1'">;
+ "anonymous %select{struct|union}0 cannot be '%1'">;
def err_different_return_type_for_overriding_virtual_function : Error<
"virtual function %0 has a different return type "
"%diff{($) than the function it overrides (which has return type $)|"
"than the function it overrides}1,2">;
def note_overridden_virtual_function : Note<
"overridden virtual function is here">;
+def err_conflicting_overriding_cc_attributes : Error<
+ "virtual function %0 has different calling convention attributes "
+ "%diff{($) than the function it overrides (which has calling convention $)|"
+ "than the function it overrides}1,2">;
def err_covariant_return_inaccessible_base : Error<
"invalid covariant return for virtual function: %1 is a "
@@ -1236,6 +1307,8 @@ def err_reference_var_requires_init : Error<
"declaration of reference variable %0 requires an initializer">;
def err_reference_without_init : Error<
"reference to type %0 requires an initializer">;
+def note_value_initialization_here : Note<
+ "in value-initialization of type %0 here">;
def err_reference_has_multiple_inits : Error<
"reference cannot be initialized with multiple values">;
def err_init_non_aggr_init_list : Error<
@@ -1249,6 +1322,9 @@ def warn_field_is_uninit : Warning<"field %0 is uninitialized when used here">,
def warn_reference_field_is_uninit : Warning<
"reference %0 is not yet bound to a value when used here">,
InGroup<Uninitialized>;
+def warn_static_self_reference_in_init : Warning<
+ "static variable %0 is suspiciously used within its own initialization">,
+ InGroup<UninitializedStaticSelfInit>;
def warn_uninit_self_reference_in_init : Warning<
"variable %0 is uninitialized when used within its own initialization">,
InGroup<Uninitialized>;
@@ -1284,6 +1360,11 @@ def note_uninit_fixit_remove_cond : Note<
"is always %select{false|true}2">;
def err_init_incomplete_type : Error<"initialization of incomplete type %0">;
+def warn_unsequenced_mod_mod : Warning<
+ "multiple unsequenced modifications to %0">, InGroup<Unsequenced>;
+def warn_unsequenced_mod_use : Warning<
+ "unsequenced modification and access to %0">, InGroup<Unsequenced>;
+
def err_temp_copy_no_viable : Error<
"no viable constructor %select{copying variable|copying parameter|"
"returning object|throwing object|copying member subobject|copying array "
@@ -1469,6 +1550,8 @@ def warn_cxx98_compat_constexpr : Warning<
def err_invalid_constexpr : Error<
"%select{function parameter|typedef|non-static data member}0 "
"cannot be constexpr">;
+def err_invalid_constexpr_member : Error<"non-static data member cannot be "
+ "constexpr%select{; did you intend to make it %select{const|static}0?|}1">;
def err_constexpr_tag : Error<
"%select{class|struct|interface|union|enum}0 cannot be marked constexpr">;
def err_constexpr_dtor : Error<"destructor cannot be marked constexpr">;
@@ -1509,7 +1592,7 @@ def err_constexpr_vla : Error<
"%select{function|constructor}1">;
def err_constexpr_var_declaration : Error<
"variables cannot be declared in a constexpr %select{function|constructor}0">;
-def err_constexpr_function_never_constant_expr : ExtWarn<
+def ext_constexpr_function_never_constant_expr : ExtWarn<
"constexpr %select{function|constructor}0 never produces a "
"constant expression">, InGroup<DiagGroup<"invalid-constexpr">>, DefaultError;
def err_constexpr_body_no_return : Error<
@@ -1584,8 +1667,19 @@ def err_attribute_argument_not_int : Error<
"'%0' attribute requires integer constant">;
def err_aligned_attribute_argument_not_int : Error<
"'aligned' attribute requires integer constant">;
-def err_attribute_argument_not_class : Error<
- "%0 attribute requires arguments that are class type or point to class type">;
+def err_alignas_attribute_wrong_decl_type : Error<
+ "'%select{alignas|_Alignas}0' attribute cannot be applied to a %select{"
+ "function parameter|variable with 'register' storage class|"
+ "'catch' variable|bit-field}1">;
+def err_alignas_missing_on_definition : Error<
+ "'%select{alignas|_Alignas}0' must be specified on definition if it is "
+ "specified on any declaration">;
+def note_alignas_on_declaration : Note<
+ "declared with '%select{alignas|_Alignas}0' attribute here">;
+def err_alignas_mismatch : Error<
+ "redeclaration has different alignment requirement (%1 vs %0)">;
+def err_alignas_underaligned : Error<
+ "requested alignment is less than minimum alignment of %1 for type %0">;
def err_attribute_first_argument_not_int_or_bool : Error<
"%0 attribute first argument must be of int or bool type">;
def err_attribute_argument_outof_range : Error<
@@ -1594,6 +1688,8 @@ def err_attribute_argument_outof_range : Error<
def err_init_priority_object_attr : Error<
"can only use 'init_priority' attribute on file-scope definitions "
"of objects of class type">;
+def err_attribute_argument_vec_type_hint : Error<
+ "invalid attribute argument %0 - expecting a vector or vectorizable scalar type">;
def err_attribute_argument_n_not_int : Error<
"'%0' attribute requires parameter %1 to be an integer constant">;
def err_attribute_argument_n_not_string : Error<
@@ -1651,6 +1747,8 @@ def err_as_qualified_auto_decl : Error<
"automatic variable qualified with an address space">;
def err_arg_with_address_space : Error<
"parameter may not be qualified with an address space">;
+def err_field_with_address_space : Error<
+ "field may not be qualified with an address space">;
def err_attr_objc_ownership_redundant : Error<
"the type %0 is already explicitly ownership-qualified">;
def err_attribute_not_string : Error<
@@ -1725,12 +1823,14 @@ def warn_attribute_after_definition_ignored : Warning<
InGroup<IgnoredAttributes>;
def warn_unknown_attribute_ignored : Warning<
"unknown attribute %0 ignored">, InGroup<UnknownAttributes>;
+def warn_cxx11_gnu_attribute_on_type : Warning<
+ "attribute %0 ignored, because it cannot be applied to a type">,
+ InGroup<IgnoredAttributes>;
def warn_unhandled_ms_attribute_ignored : Warning<
"__declspec attribute %0 is not supported">,
InGroup<IgnoredAttributes>;
-def warn_attribute_invalid_on_stmt : Warning<
- "attribute %0 cannot be specified on a statement">,
- InGroup<IgnoredAttributes>;
+def err_attribute_invalid_on_stmt : Error<
+ "%0 attribute cannot be applied to a statement">;
def warn_declspec_attribute_ignored : Warning<
"attribute %0 is ignored, place it after "
"\"%select{class|struct|union|interface|enum}1\" to apply attribute to "
@@ -1773,17 +1873,22 @@ def err_alias_not_supported_on_darwin : Error <
def warn_attribute_wrong_decl_type : Warning<
"%0 attribute only applies to %select{functions|unions|"
"variables and functions|functions and methods|parameters|"
- "functions, methods and blocks|functions, methods, and parameters|"
- "classes|variables|methods|variables, functions and labels|"
- "fields and global variables|structs|"
- "variables, functions and tag types|thread-local variables}1">,
+ "functions, methods and blocks|functions, methods, and classes|"
+ "functions, methods, and parameters|classes|variables|methods|"
+ "variables, functions and labels|fields and global variables|structs|"
+ "variables, functions and tag types|thread-local variables|"
+ "variables and fields|variables, data members and tag types|"
+ "types and namespaces}1">,
InGroup<IgnoredAttributes>;
def err_attribute_wrong_decl_type : Error<
"%0 attribute only applies to %select{functions|unions|"
"variables and functions|functions and methods|parameters|"
- "functions, methods and blocks|functions, methods, and parameters|"
- "classes|variables|methods|variables, functions and labels|"
- "fields and global variables|structs|thread-local variables}1">;
+ "functions, methods and blocks|functions, methods, and classes|"
+ "functions, methods, and parameters|classes|variables|methods|"
+ "variables, functions and labels|fields and global variables|structs|"
+ "variables, functions and tag types|thread-local variables|"
+ "variables and fields|variables, data members and tag types|"
+ "types and namespaces}1">;
def warn_function_attribute_wrong_type : Warning<
"'%0' only applies to function types; type here is %1">,
InGroup<IgnoredAttributes>;
@@ -1813,7 +1918,7 @@ def err_cconv_knr : Error<
"function with no prototype cannot use %0 calling convention">;
def err_cconv_varargs : Error<
"variadic function cannot use %0 calling convention">;
-def err_regparm_mismatch : Error<"function declared with with regparm(%0) "
+def err_regparm_mismatch : Error<"function declared with regparm(%0) "
"attribute was previously declared "
"%plural{0:without the regparm|:with the regparm(%1)}1 attribute">;
def err_returns_retained_mismatch : Error<
@@ -1824,11 +1929,13 @@ def err_objc_precise_lifetime_bad_type : Error<
def warn_objc_precise_lifetime_meaningless : Error<
"objc_precise_lifetime is not meaningful for "
"%select{__unsafe_unretained|__autoreleasing}0 objects">;
-def err_invalid_pcs : Error<"Invalid PCS type">;
+def err_invalid_pcs : Error<"invalid PCS type">;
def err_attribute_can_be_applied_only_to_value_decl : Error<
"%0 attribute can only be applied to value declarations">;
-def warn_attribute_not_on_decl : Error<
- "%0 attribute ignored when parsing type">;
+def warn_attribute_not_on_decl : Warning<
+ "%0 attribute ignored when parsing type">, InGroup<IgnoredAttributes>;
+def err_base_specifier_attribute : Error<
+ "%0 attribute cannot be applied to a base specifier">;
// Availability attribute
def warn_availability_unknown_platform : Warning<
@@ -1839,6 +1946,16 @@ def warn_availability_version_ordering : Warning<
"attribute ignored">, InGroup<Availability>;
def warn_mismatched_availability: Warning<
"availability does not match previous declaration">, InGroup<Availability>;
+def warn_mismatched_availability_override : Warning<
+ "overriding method %select{introduced after|"
+ "deprecated before|obsoleted before}0 overridden method on %1 (%2 vs. %3)">,
+ InGroup<Availability>;
+def warn_mismatched_availability_override_unavail : Warning<
+ "overriding method cannot be unavailable on %0 when its overridden method is "
+ "available">,
+ InGroup<Availability>;
+def note_overridden_method : Note<
+ "overridden method is here">;
// Thread Safety Attributes
def warn_thread_attribute_ignored : Warning<
@@ -1938,18 +2055,22 @@ def warn_fun_requires_lock_precise : Warning<
InGroup<ThreadSafetyPrecise>, DefaultIgnore;
def note_found_mutex_near_match : Note<"found near match '%0'">;
+// Dummy warning that will trigger "beta" warnings from the analysis if enabled.
+def warn_thread_safety_beta : Warning<
+ "Thread safety beta warning.">, InGroup<ThreadSafetyBeta>, DefaultIgnore;
+
def warn_impcast_vector_scalar : Warning<
"implicit conversion turns vector to scalar: %0 to %1">,
- InGroup<DiagGroup<"conversion">>, DefaultIgnore;
+ InGroup<Conversion>, DefaultIgnore;
def warn_impcast_complex_scalar : Warning<
"implicit conversion discards imaginary component: %0 to %1">,
- InGroup<DiagGroup<"conversion">>, DefaultIgnore;
+ InGroup<Conversion>, DefaultIgnore;
def warn_impcast_float_precision : Warning<
"implicit conversion loses floating-point precision: %0 to %1">,
- InGroup<DiagGroup<"conversion">>, DefaultIgnore;
+ InGroup<Conversion>, DefaultIgnore;
def warn_impcast_float_integer : Warning<
"implicit conversion turns floating-point number into integer: %0 to %1">,
- InGroup<DiagGroup<"conversion">>, DefaultIgnore;
+ InGroup<Conversion>, DefaultIgnore;
def warn_impcast_integer_sign : Warning<
"implicit conversion changes signedness: %0 to %1">,
InGroup<SignConversion>, DefaultIgnore;
@@ -1958,7 +2079,7 @@ def warn_impcast_integer_sign_conditional : Warning<
InGroup<SignConversion>, DefaultIgnore;
def warn_impcast_integer_precision : Warning<
"implicit conversion loses integer precision: %0 to %1">,
- InGroup<DiagGroup<"conversion">>, DefaultIgnore;
+ InGroup<Conversion>, DefaultIgnore;
def warn_impcast_integer_64_32 : Warning<
"implicit conversion loses integer precision: %0 to %1">,
InGroup<Shorten64To32>, DefaultIgnore;
@@ -2036,6 +2157,8 @@ def warn_attribute_protected_visibility :
Warning<"target does not support 'protected' visibility; using 'default'">,
InGroup<DiagGroup<"unsupported-visibility">>;
def err_mismatched_visibility: Error<"visibility does not match previous declaration">;
+def warn_attribute_unknown_endian : Warning<"unknown endian '%0'">,
+ InGroup<IgnoredAttributes>;
def note_previous_attribute : Note<"previous attribute is here">;
def err_unknown_machine_mode : Error<"unknown machine mode %0">;
def err_unsupported_machine_mode : Error<"unsupported machine mode %0">;
@@ -2158,15 +2281,11 @@ def err_uninitialized_member_for_assign : Error<
"non-static %select{reference|const}1 member %2 can't use default "
"assignment operator">;
def err_uninitialized_member_in_ctor : Error<
- "%select{|implicit default }0constructor for %1 must explicitly initialize "
- "the %select{reference|const}2 member %3">;
-def warn_default_arg_makes_ctor_special : Warning<
+ "%select{|implicit default |inheriting }0constructor for %1 must explicitly "
+ "initialize the %select{reference|const}2 member %3">;
+def err_default_arg_makes_ctor_special : Error<
"addition of default argument on redeclaration makes this constructor a "
- "%select{default|copy|move}0 constructor">, InGroup<DefaultArgSpecialMember>;
-def note_previous_declaration_special : Note<
- // The ERRORs are in hopes that if they occur, they'll get reported.
- "previous declaration was %select{*ERROR*|a copy constructor|a move "
- "constructor|*ERROR*|*ERROR*|*ERROR*|not a special member function}0">;
+ "%select{default|copy|move}0 constructor">;
def err_use_of_default_argument_to_function_declared_later : Error<
"use of default argument to function %0 that is declared later in class %1">;
@@ -2246,6 +2365,11 @@ def note_ovl_candidate_substitution_failure : Note<
"candidate template ignored: substitution failure%0%1">;
def note_ovl_candidate_disabled_by_enable_if : Note<
"candidate template ignored: disabled by %0%1">;
+def note_ovl_candidate_failed_overload_resolution : Note<
+ "candidate template ignored: couldn't resolve reference to overloaded "
+ "function %0">;
+def note_ovl_candidate_non_deduced_mismatch : Note<
+ "candidate template ignored: could not match %diff{$ against $|types}0,1">;
// Note that we don't treat templates differently for this diagnostic.
def note_ovl_candidate_arity : Note<"candidate "
@@ -2473,9 +2597,10 @@ def err_ovl_no_viable_oper : Error<"no viable overloaded '%0'">;
def err_ovl_deleted_oper : Error<
"overload resolution selected %select{unavailable|deleted}0 operator '%1'%2">;
def err_ovl_deleted_special_oper : Error<
- "overload resolution selected implicitly-deleted %select{default constructor|"
- "copy constructor|move constructor|copy assignment operator|move assignment "
- "operator|destructor|'%1'}0%2">;
+ "object of type %0 cannot be %select{constructed|copied|moved|assigned|"
+ "assigned|destroyed}1 because its %select{default constructor|"
+ "copy constructor|move constructor|copy assignment operator|"
+ "move assignment operator|destructor}1 is implicitly deleted">;
def err_ovl_no_viable_subscript :
Error<"no viable overloaded operator[] for type %0">;
def err_ovl_no_oper :
@@ -2597,7 +2722,7 @@ def err_template_arg_must_be_type_suggest : Error<
def err_template_arg_must_be_expr : Error<
"template argument for non-type template parameter must be an expression">;
def err_template_arg_nontype_ambig : Error<
- "template argument for non-type template parameter is treated as type %0">;
+ "template argument for non-type template parameter is treated as function type %0">;
def err_template_arg_must_be_template : Error<
"template argument for template template parameter must be a class template%select{| or type alias template}0">;
def ext_template_arg_local_type : ExtWarn<
@@ -3021,9 +3146,9 @@ def warn_cxx98_compat_template_outside_of_template : Warning<
InGroup<CXX98Compat>, DefaultIgnore;
def err_non_type_template_in_nested_name_specifier : Error<
- "qualified name refers into a specialization of function template '%0'">;
+ "qualified name refers into a specialization of function template %0">;
def err_template_id_not_a_type : Error<
- "template name refers to non-type template '%0'">;
+ "template name refers to non-type template %0">;
def note_template_declared_here : Note<
"%select{function template|class template|type alias template|template template parameter}0 "
"%1 declared here">;
@@ -3142,6 +3267,8 @@ def note_sentinel_here : Note<
def warn_missing_prototype : Warning<
"no previous prototype for function %0">,
InGroup<DiagGroup<"missing-prototypes">>, DefaultIgnore;
+def note_declaration_not_a_prototype : Note<
+ "this declaration is not a prototype; add 'void' to make it a prototype for a zero-parameter function">;
def warn_missing_variable_declarations : Warning<
"no previous extern declaration for non-static variable %0">,
InGroup<DiagGroup<"missing-variable-declarations">>, DefaultIgnore;
@@ -3189,18 +3316,23 @@ def note_deleted_assign_field : Note<
"%select{copy|move}0 assignment operator of %1 is implicitly deleted "
"because field %2 is of %select{reference|const-qualified}4 type %3">;
-// This should eventually be an error.
+// These should be errors.
def warn_undefined_internal : Warning<
"%select{function|variable}0 %q1 has internal linkage but is not defined">,
- DiagGroup<"undefined-internal">;
+ InGroup<DiagGroup<"undefined-internal">>;
+def warn_undefined_inline : Warning<"inline function %q0 is not defined">,
+ InGroup<DiagGroup<"undefined-inline">>;
def note_used_here : Note<"used here">;
def warn_internal_in_extern_inline : ExtWarn<
"static %select{function|variable}0 %1 is used in an inline function with "
- "external linkage">, InGroup<DiagGroup<"static-in-inline"> >;
+ "external linkage">, InGroup<StaticInInline>;
def ext_internal_in_extern_inline : Extension<
"static %select{function|variable}0 %1 is used in an inline function with "
- "external linkage">, InGroup<DiagGroup<"static-in-inline"> >;
+ "external linkage">, InGroup<StaticInInline>;
+def warn_static_local_in_extern_inline : Warning<
+ "non-constant static local variable in inline function may be different "
+ "in different files">, InGroup<StaticLocalInInline>;
def note_convert_inline_to_static : Note<
"use 'static' to give inline function %0 internal linkage">;
def note_internal_decl_declared_here : Note<
@@ -3216,6 +3348,8 @@ def err_inline_declaration_block_scope : Error<
"inline declaration of %0 not allowed in block scope">;
def err_static_non_static : Error<
"static declaration of %0 follows non-static declaration">;
+def err_different_language_linkage : Error<
+ "declaration of %0 has a different language linkage">;
def warn_weak_import : Warning <
"an already-declared variable is made a weak_import declaration %0">;
def warn_static_non_static : ExtWarn<
@@ -3304,7 +3438,7 @@ def err_array_too_large : Error<
"array is too large (%0 elements)">;
def warn_array_new_too_large : Warning<"array is too large (%0 elements)">,
// FIXME PR11644: ", will throw std::bad_array_new_length at runtime"
- InGroup<DiagGroup<"bad-array-new-length">>;
+ InGroup<BadArrayNewLength>;
// -Wpadded, -Wpacked
def warn_padded_struct_field : Warning<
@@ -3324,7 +3458,7 @@ def warn_unnecessary_packed : Warning<
def err_typecheck_negative_array_size : Error<"array size is negative">;
def warn_typecheck_negative_array_new_size : Warning<"array size is negative">,
// FIXME PR11644: ", will throw std::bad_array_new_length at runtime"
- InGroup<DiagGroup<"bad-array-new-length">>;
+ InGroup<BadArrayNewLength>;
def warn_typecheck_function_qualifiers : Warning<
"qualifier on function type %0 has unspecified behavior">;
def err_typecheck_invalid_restrict_not_pointer : Error<
@@ -3339,7 +3473,7 @@ def err_typecheck_zero_array_size : Error<
"zero-length arrays are not permitted in C++">;
def warn_typecheck_zero_static_array_size : Warning<
"'static' has no effect on zero-length arrays">,
- InGroup<DiagGroup<"array-bounds">>;
+ InGroup<ArrayBounds>;
def err_array_size_non_int : Error<"size of array has non-integer type %0">;
def err_init_element_not_constant : Error<
"initializer element is not a compile-time constant">;
@@ -3610,8 +3744,9 @@ def err_arc_mismatched_cast : Error<
" to %3 is disallowed with ARC">;
def err_arc_nolifetime_behavior : Error<
"explicit ownership qualifier on cast result has no effect">;
-def err_arc_objc_object_in_struct : Error<
- "ARC forbids %select{Objective-C objects|blocks}0 in structs or unions">;
+def err_arc_objc_object_in_tag : Error<
+ "ARC forbids %select{Objective-C objects|blocks}0 in "
+ "%select{struct|interface|union|<<ERROR>>|enum}1">;
def err_arc_objc_property_default_assign_on_object : Error<
"ARC forbids synthesizing a property of an Objective-C object "
"with unspecified ownership or storage attribute">;
@@ -3653,6 +3788,11 @@ def warn_arc_retained_property_assign : Warning<
"assigning retained object to unsafe property"
"; object will be released after assignment">,
InGroup<ARCUnsafeRetainedAssign>;
+def warn_arc_literal_assign : Warning<
+ "assigning %select{array literal|dictionary literal|numeric literal|boxed expression|<should not happen>|block literal}0"
+ " to a weak %select{property|variable}1"
+ "; object will be released after assignment">,
+ InGroup<ARCUnsafeRetainedAssign>;
def err_arc_new_array_without_ownership : Error<
"'new' cannot allocate an array of %0 with no explicit ownership">;
def err_arc_autoreleasing_var : Error<
@@ -3691,6 +3831,10 @@ def err_arc_collection_forward : Error<
def err_arc_multiple_method_decl : Error<
"multiple methods named %0 found with mismatched result, "
"parameter type or attributes">;
+def warn_arc_lifetime_result_type : Warning<
+ "ARC %select{unused|__unsafe_unretained|__strong|__weak|__autoreleasing}0 "
+ "lifetime qualifier on return type is ignored">,
+ InGroup<IgnoredQualifiers>;
let CategoryName = "ARC Retain Cycle" in {
@@ -3703,9 +3847,6 @@ def note_arc_retain_cycle_owner : Note<
} // end "ARC Retain Cycle" category
-def note_nontrivial_objc_ownership : Note<
- "because type %0 has %select{no|no|__strong|__weak|__autoreleasing}1 "
- "ownership">;
def warn_arc_object_memaccess : Warning<
"%select{destination for|source of}0 this %1 call is a pointer to "
"ownership-qualified type %2">, InGroup<ARCNonPodMemAccess>;
@@ -3743,12 +3884,20 @@ def err_arc_cast_requires_bridge : Error<
"requires a bridged cast">;
def note_arc_bridge : Note<
"use __bridge to convert directly (no change in ownership)">;
+def note_arc_cstyle_bridge : Note<
+ "use __bridge with C-style cast to convert directly (no change in ownership)">;
def note_arc_bridge_transfer : Note<
"use %select{__bridge_transfer|CFBridgingRelease call}1 to transfer "
"ownership of a +1 %0 into ARC">;
+def note_arc_cstyle_bridge_transfer : Note<
+ "use __bridge_transfer with C-style cast to transfer "
+ "ownership of a +1 %0 into ARC">;
def note_arc_bridge_retained : Note<
"use %select{__bridge_retained|CFBridgingRetain call}1 to make an "
"ARC object available as a +1 %0">;
+def note_arc_cstyle_bridge_retained : Note<
+ "use __bridge_retained with C-style cast to make an "
+ "ARC object available as a +1 %0">;
} // ARC Casting category
@@ -3796,16 +3945,17 @@ def err_atomic_specifier_bad_type : Error<
"%1 %select{||||||which is not trivially copyable}0">;
// Expressions.
-def ext_sizeof_function_type : Extension<
- "invalid application of 'sizeof' to a function type">, InGroup<PointerArith>;
-def ext_sizeof_void_type : Extension<
- "invalid application of '%select{sizeof|__alignof|vec_step}0' to a void "
+def ext_sizeof_alignof_function_type : Extension<
+ "invalid application of '%select{sizeof|alignof|vec_step}0' to a "
+ "function type">, InGroup<PointerArith>;
+def ext_sizeof_alignof_void_type : Extension<
+ "invalid application of '%select{sizeof|alignof|vec_step}0' to a void "
"type">, InGroup<PointerArith>;
def err_sizeof_alignof_incomplete_type : Error<
- "invalid application of '%select{sizeof|__alignof|vec_step}0' to an "
+ "invalid application of '%select{sizeof|alignof|vec_step}0' to an "
"incomplete type %1">;
def err_sizeof_alignof_bitfield : Error<
- "invalid application of '%select{sizeof|__alignof}0' to bit-field">;
+ "invalid application of '%select{sizeof|alignof}0' to bit-field">;
def err_vecstep_non_scalar_vector_type : Error<
"'vec_step' requires built-in scalar or vector type, %0 invalid">;
def err_offsetof_incomplete_type : Error<
@@ -3888,6 +4038,10 @@ def warn_sizeof_array_param : Warning<
"sizeof on array function parameter will return size of %0 instead of %1">,
InGroup<SizeofArrayArgument>;
+def warn_sizeof_array_decay : Warning<
+ "sizeof on pointer operation will return size of %0 instead of %1">,
+ InGroup<SizeofArrayDecay>;
+
def err_sizeof_nonfragile_interface : Error<
"application of '%select{alignof|sizeof}1' to interface %0 is "
"not supported on this architecture and platform">;
@@ -3912,6 +4066,8 @@ def err_subscript_function_type : Error<
"subscript of pointer to function type %0">;
def err_subscript_incomplete_type : Error<
"subscript of pointer to incomplete type %0">;
+def err_dereference_incomplete_type : Error<
+ "dereference of pointer to incomplete type %0">;
def ext_gnu_subscript_void_type : Extension<
"subscript of a pointer to void is a GNU extension">, InGroup<PointerArith>;
def err_typecheck_member_reference_struct_union : Error<
@@ -4038,7 +4194,13 @@ def err_typecheck_sclass_fscope : Error<
"illegal storage class on file-scoped variable">;
def err_unsupported_global_register : Error<
"global register variables are not supported">;
-def warn_standalone_specifier : Warning<"'%0' ignored on this declaration">;
+def warn_standalone_specifier : Warning<"'%0' ignored on this declaration">,
+ InGroup<MissingDeclarations>;
+def ext_standalone_specifier : ExtWarn<"'%0' is not permitted on a declaration "
+ "of a type">, InGroup<MissingDeclarations>;
+def err_standalone_class_nested_name_specifier : Error<
+ "forward declaration of %select{class|struct|interface|union|enum}0 cannot "
+ "have a nested name specifier">;
def err_typecheck_sclass_func : Error<"illegal storage class on function">;
def err_static_block_func : Error<
"function declared in block scope cannot have 'static' storage class">;
@@ -4052,12 +4214,14 @@ def err_invalid_form_pointer_member_function : Error<
"cannot create a non-constant pointer to member function">;
def err_parens_pointer_member_function : Error<
"cannot parenthesize the name of a method when forming a member pointer">;
+def err_typecheck_invalid_lvalue_addrof_addrof_function : Error<
+ "extra '&' taking address of overloaded function">;
def err_typecheck_invalid_lvalue_addrof : Error<
- "address expression must be an lvalue or a function designator">;
-def ext_typecheck_addrof_class_temporary : ExtWarn<
+ "cannot take the address of an rvalue of type %0">;
+def ext_typecheck_addrof_temporary : ExtWarn<
"taking the address of a temporary object of type %0">,
InGroup<DiagGroup<"address-of-temporary">>, DefaultError;
-def err_typecheck_addrof_class_temporary : Error<
+def err_typecheck_addrof_temporary : Error<
"taking the address of a temporary object of type %0">;
def err_typecheck_unary_expr : Error<
"invalid argument type %0 to unary expression">;
@@ -4070,7 +4234,7 @@ def note_indirection_through_null : Note<
def warn_pointer_indirection_from_incompatible_type : Warning<
"dereference of type %1 that was reinterpret_cast from type %0 has undefined "
"behavior">,
- InGroup<DiagGroup<"undefined-reinterpret-cast">>, DefaultIgnore;
+ InGroup<UndefinedReinterpretCast>, DefaultIgnore;
def err_objc_object_assignment : Error<
"cannot assign to class object (%0 invalid)">;
@@ -4127,11 +4291,11 @@ def warn_comparison_of_mixed_enum_types : Warning<
InGroup<DiagGroup<"enum-compare">>;
def warn_null_in_arithmetic_operation : Warning<
"use of NULL in arithmetic operation">,
- InGroup<DiagGroup<"null-arithmetic">>;
+ InGroup<NullArithmetic>;
def warn_null_in_comparison_operation : Warning<
"comparison between NULL and non-pointer "
"%select{(%1 and NULL)|(NULL and %1)}0">,
- InGroup<DiagGroup<"null-arithmetic">>;
+ InGroup<NullArithmetic>;
def err_invalid_this_use : Error<
"invalid use of 'this' outside of a non-static member function">;
@@ -4178,6 +4342,9 @@ def err_unexpected_interface : Error<
def err_ref_non_value : Error<"%0 does not refer to a value">;
def err_ref_vm_type : Error<
"cannot refer to declaration with a variably modified type inside block">;
+def err_ref_flexarray_type : Error<
+ "cannot refer to declaration of structure variable with flexible array member "
+ "inside block">;
def err_ref_array_type : Error<
"cannot refer to declaration with an array type inside block">;
def err_property_not_found : Error<
@@ -4185,7 +4352,7 @@ def err_property_not_found : Error<
def err_invalid_property_name : Error<
"%0 is not a valid property name (accessing an object of type %1)">;
def err_getter_not_found : Error<
- "expected getter method not found on object of type %0">;
+ "no getter method for read from property">;
def err_objc_subscript_method_not_found : Error<
"expected method to %select{read|write}1 %select{dictionary|array}2 element not "
"found on object of type %0">;
@@ -4276,8 +4443,6 @@ def error_no_super_class_message : Error<
"no @interface declaration found in class messaging of %0">;
def error_root_class_cannot_use_super : Error<
"%0 cannot use 'super' because it is a root class">;
-def err_invalid_receiver_to_message : Error<
- "invalid receiver to message expression">;
def err_invalid_receiver_to_message_super : Error<
"'super' is only valid in a method body">;
def err_invalid_receiver_class_message : Error<
@@ -4337,6 +4502,14 @@ def note_parameter_here : Note<
def err_bad_reinterpret_cast_overload : Error<
"reinterpret_cast cannot resolve overloaded function %0 to type %1">;
+def warn_reinterpret_different_from_static : Warning<
+ "'reinterpret_cast' %select{from|to}3 class %0 %select{to|from}3 its "
+ "%select{virtual base|base at non-zero offset}2 %1 behaves differently from "
+ "'static_cast'">, InGroup<ReinterpretBaseClass>;
+def note_reinterpret_updowncast_use_static: Note<
+ "use 'static_cast' to adjust the pointer correctly while "
+ "%select{upcasting|downcasting}0">;
+
def err_bad_static_cast_overload : Error<
"address of overloaded function %0 cannot be static_cast to type %1">;
@@ -4386,7 +4559,7 @@ def err_bad_reinterpret_cast_reference : Error<
"reinterpret_cast of a %0 to %1 needs its address which is not allowed">;
def warn_undefined_reinterpret_cast : Warning<
"reinterpret_cast from %0 to %1 has undefined behavior">,
- InGroup<DiagGroup<"undefined-reinterpret-cast">>, DefaultIgnore;
+ InGroup<UndefinedReinterpretCast>, DefaultIgnore;
// These messages don't adhere to the pattern.
// FIXME: Display the path somehow better.
@@ -4464,7 +4637,7 @@ def ext_delete_void_ptr_operand : ExtWarn<
def err_ambiguous_delete_operand : Error<"ambiguous conversion of delete "
"expression of type %0 to a pointer">;
def warn_delete_incomplete : Warning<
- "deleting pointer to incomplete type %0 may cause undefined behaviour">,
+ "deleting pointer to incomplete type %0 may cause undefined behavior">,
InGroup<DiagGroup<"delete-incomplete">>;
def err_delete_incomplete_class_type : Error<
"deleting incomplete class type %0; no conversions to pointer type">;
@@ -4563,6 +4736,9 @@ let CategoryName = "Lambda Issue" in {
def err_lambda_capture_vm_type : Error<
"variable %0 with variably modified type cannot be captured in "
"a lambda expression">;
+ def err_lambda_capture_flexarray_type : Error<
+ "variable %0 with flexible array member cannot be captured in "
+ "a lambda expression">;
def err_lambda_impcap : Error<
"variable %0 cannot be implicitly captured in a lambda with no "
"capture-default specified">;
@@ -4573,8 +4749,6 @@ let CategoryName = "Lambda Issue" in {
"cannot deduce lambda return type from initializer list">;
def err_lambda_capture_default_arg : Error<
"lambda expression in default argument cannot capture any entity">;
- def err_lambda_unexpanded_pack : Error<
- "unexpanded function parameter pack capture is unsupported">;
def err_lambda_incomplete_result : Error<
"incomplete result type %0 in lambda expression">;
def err_lambda_objc_object_result : Error<
@@ -4823,7 +4997,7 @@ def ext_typecheck_convert_discards_qualifiers : ExtWarn<
"sending to parameter of different type}0,1"
"|%diff{casting $ to type $|casting between types}0,1}2"
" discards qualifiers">,
- InGroup<IncompatiblePointerTypes>;
+ InGroup<IncompatiblePointerTypesDiscardsQualifiers>;
def ext_nested_pointer_qualifier_mismatch : ExtWarn<
"%select{%diff{assigning to $ from $|assigning to different types}0,1"
"|%diff{passing $ to parameter of type $|"
@@ -4837,7 +5011,7 @@ def ext_nested_pointer_qualifier_mismatch : ExtWarn<
"sending to parameter of different type}0,1"
"|%diff{casting $ to type $|casting between types}0,1}2"
" discards qualifiers in nested pointer types">,
- InGroup<IncompatiblePointerTypes>;
+ InGroup<IncompatiblePointerTypesDiscardsQualifiers>;
def warn_incompatible_vectors : Warning<
"incompatible vector types "
"%select{%diff{assigning to $ from $|assigning to different types}0,1"
@@ -5015,7 +5189,7 @@ def err_ref_bad_target : Error<
def warn_non_pod_vararg_with_format_string : Warning<
"cannot pass %select{non-POD|non-trivial}0 object of type %1 to variadic "
"%select{function|block|method|constructor}2; expected type from format "
- "string was %3">, InGroup<DiagGroup<"non-pod-varargs">>, DefaultError;
+ "string was %3">, InGroup<NonPODVarargs>, DefaultError;
// The arguments to this diagnostic should match the warning above.
def err_cannot_pass_objc_interface_to_vararg_format : Error<
"cannot pass object with interface type %1 by value to variadic "
@@ -5028,7 +5202,7 @@ def err_cannot_pass_objc_interface_to_vararg : Error<
def warn_cannot_pass_non_pod_arg_to_vararg : Warning<
"cannot pass object of %select{non-POD|non-trivial}0 type %1 through variadic"
" %select{function|block|method|constructor}2; call will abort at runtime">,
- InGroup<DiagGroup<"non-pod-varargs">>, DefaultError;
+ InGroup<NonPODVarargs>, DefaultError;
def warn_cxx98_compat_pass_non_pod_arg_to_vararg : Warning<
"passing object of trivial but non-POD type %0 through variadic"
" %select{function|block|method|constructor}1 is incompatible with C++98">,
@@ -5141,10 +5315,14 @@ let CategoryName = "Inline Assembly Issue" in {
"%diff{$ matching output with type $|}0,1">;
def err_asm_unknown_register_name : Error<"unknown register name '%0' in asm">;
def err_asm_empty : Error<"__asm used with no assembly instructions">;
+ def err_asm_invalid_input_size : Error<
+ "invalid input size for constraint '%0'">;
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 err_msasm_unsupported_arch : Error<
+ "Unsupported architecture '%0' for MS-style inline assembly">;
def warn_asm_label_on_auto_decl : Warning<
"ignored asm label '%0' on automatic variable">;
@@ -5153,7 +5331,8 @@ let CategoryName = "Inline Assembly Issue" in {
"accepted due to -fheinous-gnu-extensions, but clang may remove support "
"for this in the future">;
def warn_asm_mismatched_size_modifier : Warning<
- "the size being stored is truncated, use a modifier to specify the size">,
+ "the value is truncated when put into register, "
+ "use a modifier to specify the size">,
InGroup<ASMOperandWidths>;
}
@@ -5205,9 +5384,11 @@ def err_in_class_initializer_bad_type : Error<
"static data member of type %0 must be initialized out of line">;
def ext_in_class_initializer_float_type : ExtWarn<
"in-class initializer for static data member of type %0 is a GNU extension">,
- InGroup<GNU>;
-def note_in_class_initializer_float_type_constexpr : Note<
- "use 'constexpr' specifier to silence this warning">;
+ InGroup<GNUStaticFloatInit>;
+def ext_in_class_initializer_float_type_cxx11 : ExtWarn<
+ "in-class initializer for static data member of type %0 requires "
+ "'constexpr' specifier">, InGroup<StaticFloatInit>, DefaultError;
+def note_in_class_initializer_float_type_cxx11 : Note<"add 'constexpr'">;
def err_in_class_initializer_literal_type : Error<
"in-class initializer for static data member of type %0 requires "
"'constexpr' specifier">;
@@ -5244,6 +5425,9 @@ def err_anonymous_record_with_type : Error<
def ext_anonymous_record_with_type : Extension<
"types declared in an anonymous %select{struct|union}0 are a Microsoft "
"extension">, InGroup<Microsoft>;
+def ext_anonymous_record_with_anonymous_type : Extension<
+ "anonymous types declared in an anonymous %select{struct|union}0 "
+ "are an extension">, InGroup<DiagGroup<"nested-anon-types">>;
def err_anonymous_record_with_function : Error<
"functions cannot be declared in an anonymous %select{struct|union}0">;
def err_anonymous_record_with_static : Error<
@@ -5403,6 +5587,9 @@ def warn_cxx98_compat_explicit_conversion_functions : Warning<
def err_defaulted_special_member_params : Error<
"an explicitly-defaulted %select{|copy |move }0constructor cannot "
"have default arguments">;
+def err_defaulted_special_member_variadic : Error<
+ "an explicitly-defaulted %select{|copy |move }0constructor cannot "
+ "be variadic">;
def err_defaulted_special_member_return_type : Error<
"explicitly-defaulted %select{copy|move}0 assignment operator must "
"return %1">;
@@ -5420,10 +5607,6 @@ def err_defaulted_special_member_copy_const_param : Error<
"the parameter for this explicitly-defaulted copy "
"%select{constructor|assignment operator}0 is const, but a member or base "
"requires it to be non-const">;
-def err_defaulted_special_member_copy_non_const_param : Error<
- "explicitly-defaulted copy %select{constructor|assignment operator}0 with "
- "a non-const parameter must be defaulted outside the class, unless a base or "
- "member requires the parameter to be non-const">;
def err_defaulted_copy_assign_not_ref : Error<
"the parameter for an explicitly-defaulted copy assignment operator must be an "
"lvalue reference type">;
@@ -5446,17 +5629,17 @@ def ext_implicit_exception_spec_mismatch : ExtWarn<
def warn_ptr_arith_precedes_bounds : Warning<
"the pointer decremented by %0 refers before the beginning of the array">,
- InGroup<DiagGroup<"array-bounds-pointer-arithmetic">>, DefaultIgnore;
+ InGroup<ArrayBoundsPointerArithmetic>, DefaultIgnore;
def warn_ptr_arith_exceeds_bounds : Warning<
"the pointer incremented by %0 refers past the end of the array (that "
"contains %1 element%s2)">,
- InGroup<DiagGroup<"array-bounds-pointer-arithmetic">>, DefaultIgnore;
+ InGroup<ArrayBoundsPointerArithmetic>, DefaultIgnore;
def warn_array_index_precedes_bounds : Warning<
"array index %0 is before the beginning of the array">,
- InGroup<DiagGroup<"array-bounds">>;
+ InGroup<ArrayBounds>;
def warn_array_index_exceeds_bounds : Warning<
"array index %0 is past the end of the array (which contains %1 "
- "element%s2)">, InGroup<DiagGroup<"array-bounds">>;
+ "element%s2)">, InGroup<ArrayBounds>;
def note_array_index_out_of_bounds : Note<
"array %0 declared here">;
@@ -5494,7 +5677,7 @@ def warn_format_mix_positional_nonpositional_args : Warning<
InGroup<Format>;
def warn_static_array_too_small : Warning<
"array argument is too small; contains %0 elements, callee requires at least %1">,
- InGroup<DiagGroup<"array-bounds">>;
+ InGroup<ArrayBounds>;
def note_callee_static_array : Note<
"callee declares array parameter as static here">;
def warn_empty_format_string : Warning<
@@ -5543,19 +5726,19 @@ def warn_null_arg : Warning<
// CHECK: returning address/reference of stack memory
def warn_ret_stack_addr : Warning<
"address of stack memory associated with local variable %0 returned">,
- InGroup<DiagGroup<"return-stack-address">>;
+ InGroup<ReturnStackAddress>;
def warn_ret_stack_ref : Warning<
"reference to stack memory associated with local variable %0 returned">,
- InGroup<DiagGroup<"return-stack-address">>;
+ InGroup<ReturnStackAddress>;
def warn_ret_local_temp_addr : Warning<
"returning address of local temporary object">,
- InGroup<DiagGroup<"return-stack-address">>;
+ InGroup<ReturnStackAddress>;
def warn_ret_local_temp_ref : Warning<
"returning reference to local temporary object">,
- InGroup<DiagGroup<"return-stack-address">>;
+ InGroup<ReturnStackAddress>;
def warn_ret_addr_label : Warning<
"returning address of label, which is local">,
- InGroup<DiagGroup<"return-stack-address">>;
+ InGroup<ReturnStackAddress>;
def err_ret_local_block : Error<
"returning block that lives on the local stack">;
def note_ref_var_local_bind : Note<
@@ -5565,13 +5748,13 @@ def note_ref_var_local_bind : Note<
// a constructor parameter.
def warn_bind_ref_member_to_parameter : Warning<
"binding reference member %0 to stack allocated parameter %1">,
- InGroup<DiagGroup<"dangling-field">>;
+ InGroup<DanglingField>;
def warn_init_ptr_member_to_parameter_addr : Warning<
"initializing pointer member %0 with the stack address of parameter %1">,
- InGroup<DiagGroup<"dangling-field">>;
+ InGroup<DanglingField>;
def warn_bind_ref_member_to_temporary : Warning<
"binding reference member %0 to a temporary value">,
- InGroup<DiagGroup<"dangling-field">>;
+ InGroup<DanglingField>;
def note_ref_or_ptr_member_declared_here : Note<
"%select{reference|pointer}0 member declared here">;
@@ -5657,7 +5840,7 @@ def warn_bool_switch_condition : Warning<
"switch condition has boolean value">;
def warn_case_value_overflow : Warning<
"overflow converting case value to switch condition type (%0 to %1)">,
- InGroup<DiagGroup<"switch">>;
+ InGroup<Switch>;
def err_duplicate_case : Error<"duplicate case value '%0'">;
def err_duplicate_case_differing_expr : Error<
"duplicate case value: '%0' and '%1' both equal '%2'">;
@@ -5760,10 +5943,10 @@ def err_second_parameter_to_va_arg_abstract: Error<
"second argument to 'va_arg' is of abstract type %0">;
def warn_second_parameter_to_va_arg_not_pod : Warning<
"second argument to 'va_arg' is of non-POD type %0">,
- InGroup<DiagGroup<"non-pod-varargs">>, DefaultError;
+ InGroup<NonPODVarargs>, DefaultError;
def warn_second_parameter_to_va_arg_ownership_qualified : Warning<
"second argument to 'va_arg' is of ARC ownership-qualified type %0">,
- InGroup<DiagGroup<"non-pod-varargs">>, DefaultError;
+ InGroup<NonPODVarargs>, DefaultError;
def warn_second_parameter_to_va_arg_never_compatible : Warning<
"second argument to 'va_arg' is of promotable type %0; this va_arg has "
"undefined behavior because arguments will be promoted to %1">;
@@ -5785,12 +5968,24 @@ def err_return_init_list : Error<
"must not return a value">;
def warn_noreturn_function_has_return_expr : Warning<
"function %0 declared 'noreturn' should not return">,
- InGroup<DiagGroup<"invalid-noreturn">>;
+ InGroup<InvalidNoreturn>;
def warn_falloff_noreturn_function : Warning<
"function declared 'noreturn' should not return">,
- InGroup<DiagGroup<"invalid-noreturn">>;
+ InGroup<InvalidNoreturn>;
def err_noreturn_block_has_return_expr : Error<
"block declared 'noreturn' should not return">;
+def err_noreturn_missing_on_first_decl : Error<
+ "function declared '[[noreturn]]' after its first declaration">;
+def note_noreturn_missing_first_decl : Note<
+ "declaration missing '[[noreturn]]' attribute is here">;
+def err_carries_dependency_missing_on_first_decl : Error<
+ "%select{function|parameter}0 declared '[[carries_dependency]]' "
+ "after its first declaration">;
+def note_carries_dependency_missing_first_decl : Note<
+ "declaration missing '[[carries_dependency]]' attribute is here">;
+def err_carries_dependency_param_not_function_decl : Error<
+ "'[[carries_dependency]]' attribute only allowed on parameter in a function "
+ "declaration or lambda">;
def err_block_on_nonlocal : Error<
"__block attribute not allowed, only allowed on local variables">;
def err_block_on_vm : Error<
@@ -5870,6 +6065,8 @@ def err_c99_array_usage_cxx : Error<
"feature, not permitted in C++">;
def err_double_requires_fp64 : Error<
"use of type 'double' requires cl_khr_fp64 extension to be enabled">;
+def err_int128_unsupported : Error<
+ "__int128 is not supported on this target">;
def err_nsconsumed_attribute_mismatch : Error<
"overriding method has mismatched ns_consumed attribute on its"
" parameter">;
@@ -5986,8 +6183,44 @@ def err_invalid_astype_of_different_size : Error<
"invalid reinterpretation: sizes of %0 and %1 must match">;
def err_static_kernel : Error<
"kernel functions cannot be declared static">;
+def err_opencl_ptrptr_kernel_arg : Error<
+ "kernel argument cannot be declared as a pointer to a pointer">;
def err_static_function_scope : Error<
"variables in function scope cannot be declared static">;
+def err_opencl_bitfields : Error<
+ "bitfields are not supported in OpenCL">;
+def err_opencl_vla : Error<
+ "variable length arrays are not supported in OpenCL">;
+def err_event_t_kernel_arg : Error<
+ "the event_t type cannot be used to declare a kernel function argument">;
+def err_event_t_global_var : Error<
+ "the event_t type cannot be used to declare a program scope variable">;
+def err_event_t_struct_field : Error<
+ "the event_t type cannot be used to declare a structure or union field">;
+def err_event_t_addr_space_qual : Error<
+ "the event_t type can only be used with __private address space qualifier">;
+def err_expected_kernel_void_return_type : Error<
+ "kernel must have void return type">;
+def err_sampler_argument_required : Error<
+ "sampler_t variable required - got %0">;
+def err_wrong_sampler_addressspace: Error<
+ "sampler type cannot be used with the __local and __global address space qualifiers">;
+
+// OpenMP support.
+def err_omp_expected_var_arg_suggest : Error<
+ "%0 is not a global variable, static local variable or static data member%select{|; did you mean %2?}1">;
+def err_omp_global_var_arg : Error<
+ "arguments of '#pragma omp %0' must have %select{global storage|static storage duration}1">;
+def err_omp_ref_type_arg : Error<
+ "arguments of '#pragma omp %0' cannot be of reference type %1">;
+def err_omp_var_scope : Error<
+ "'#pragma omp %0' must appear in the scope of the %1 variable declaration">;
+def err_omp_var_used : Error<
+ "'#pragma omp %0' must precede all references to variable %1">;
+def err_omp_var_thread_local : Error<
+ "variable %0 cannot be threadprivate because it is thread-local">;
+def err_omp_incomplete_type : Error<
+ "a threadprivate variable must not have incomplete type %0">;
} // end of sema category
@@ -6000,15 +6233,19 @@ def warn_related_result_type_compatibility_class : Warning<
def warn_related_result_type_compatibility_protocol : Warning<
"protocol method is expected to return an instance of the implementing "
"class, but is declared to return %0">;
-def note_related_result_type_overridden_family : Note<
- "overridden method is part of the '%select{|alloc|copy|init|mutableCopy|"
- "new|autorelease|dealloc|finalize|release|retain|retainCount|self}0' method "
- "family">;
+def note_related_result_type_family : Note<
+ "%select{overridden|current}0 method is part of the '%select{|alloc|copy|init|"
+ "mutableCopy|new|autorelease|dealloc|finalize|release|retain|retainCount|"
+ "self}1' method family%select{| and is expected to return an instance of its "
+ "class type}0">;
def note_related_result_type_overridden : Note<
"overridden method returns an instance of its class type">;
def note_related_result_type_inferred : Note<
"%select{class|instance}0 method %1 is assumed to return an instance of "
"its receiver type (%2)">;
+def note_related_result_type_explicit : Note<
+ "%select{overridden|current}0 method is explicitly declared 'instancetype'"
+ "%select{| and is expected to return an instance of its class type}0">;
}
@@ -6023,7 +6260,7 @@ def err_module_private_local_class : Error<
"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">;
+ "definition of %0 must be imported from module '%1' before it is required">;
}
let CategoryName = "Documentation Issue" in {
diff --git a/include/clang/Basic/DiagnosticSerializationKinds.td b/include/clang/Basic/DiagnosticSerializationKinds.td
index e9df09d114db..7137404a6908 100644
--- a/include/clang/Basic/DiagnosticSerializationKinds.td
+++ b/include/clang/Basic/DiagnosticSerializationKinds.td
@@ -17,10 +17,8 @@ def err_fe_pch_malformed : Error<
"malformed or corrupted PCH file: '%0'">, DefaultFatal;
def err_fe_pch_malformed_block : Error<
"malformed block record in PCH file: '%0'">, DefaultFatal;
-def err_fe_pch_error_at_end_block : Error<
- "error at end of module block in PCH file: '%0'">, DefaultFatal;
def err_fe_pch_file_modified : Error<
- "file '%0' has been modified since the precompiled header was built">,
+ "file '%0' has been modified since the precompiled header '%1' was built">,
DefaultFatal;
def err_fe_pch_file_overridden : Error<
"file '%0' from the precompiled header has been overridden">;
@@ -46,19 +44,16 @@ def warn_pch_different_branch : Error<
def err_pch_with_compiler_errors : Error<
"PCH file contains compiler errors">;
-
+def warn_module_conflict : Warning<
+ "module '%0' conflicts with already-imported module '%1': %2">,
+ InGroup<ModuleConflict>;
+
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|"
diff --git a/include/clang/Basic/FileManager.h b/include/clang/Basic/FileManager.h
index b2f578da7b49..6d9e53b7eb0d 100644
--- a/include/clang/Basic/FileManager.h
+++ b/include/clang/Basic/FileManager.h
@@ -17,11 +17,12 @@
#include "clang/Basic/FileSystemOptions.h"
#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/Allocator.h"
// FIXME: Enhance libsystem to support inode and other fields in stat.
#include <sys/types.h>
@@ -152,6 +153,12 @@ class FileManager : public RefCountedBase<FileManager> {
/// \see SeenDirEntries
llvm::StringMap<FileEntry*, llvm::BumpPtrAllocator> SeenFileEntries;
+ /// \brief The canonical names of directories.
+ llvm::DenseMap<const DirectoryEntry *, llvm::StringRef> CanonicalDirNames;
+
+ /// \brief Storage for canonical names that we have computed.
+ llvm::BumpPtrAllocator CanonicalNameStorage;
+
/// \brief Each FileEntry we create is assigned a unique ID #.
///
unsigned NextFileUID;
@@ -164,7 +171,7 @@ class FileManager : public RefCountedBase<FileManager> {
OwningPtr<FileSystemStatCache> StatCache;
bool getStatValue(const char *Path, struct stat &StatBuf,
- int *FileDescriptor);
+ bool isFile, int *FileDescriptor);
/// Add all ancestors of the given path (pointing to either a file
/// or a directory) as virtual directories.
@@ -257,6 +264,13 @@ public:
static void modifyFileEntry(FileEntry *File, off_t Size,
time_t ModificationTime);
+ /// \brief Retrieve the canonical name for a given directory.
+ ///
+ /// This is a very expensive operation, despite its results being cached,
+ /// and should only be used when the physical layout of the file system is
+ /// required, which is (almost) never.
+ StringRef getCanonicalName(const DirectoryEntry *Dir);
+
void PrintStats() const;
};
diff --git a/include/clang/Basic/FileSystemStatCache.h b/include/clang/Basic/FileSystemStatCache.h
index a802c7cc748e..ff70373ffb06 100644
--- a/include/clang/Basic/FileSystemStatCache.h
+++ b/include/clang/Basic/FileSystemStatCache.h
@@ -18,8 +18,8 @@
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringMap.h"
-#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/types.h>
namespace clang {
@@ -44,13 +44,13 @@ public:
///
/// \returns \c true if the path does not exist or \c false if it exists.
///
- /// If FileDescriptor is non-null, then this lookup should only return success
- /// for files (not directories). If it is null this lookup should only return
+ /// If isFile is true, then this lookup should only return success for files
+ /// (not directories). If it is false this lookup should only return
/// success for directories (not files). On a successful file lookup, the
/// implementation can optionally fill in FileDescriptor with a valid
/// descriptor and the client guarantees that it will close it.
- static bool get(const char *Path, struct stat &StatBuf, int *FileDescriptor,
- FileSystemStatCache *Cache);
+ static bool get(const char *Path, struct stat &StatBuf,
+ bool isFile, int *FileDescriptor, FileSystemStatCache *Cache);
/// \brief Sets the next stat call cache in the chain of stat caches.
@@ -69,16 +69,17 @@ public:
protected:
virtual LookupResult getStat(const char *Path, struct stat &StatBuf,
- int *FileDescriptor) = 0;
+ bool isFile, int *FileDescriptor) = 0;
LookupResult statChained(const char *Path, struct stat &StatBuf,
- int *FileDescriptor) {
+ bool isFile, int *FileDescriptor) {
if (FileSystemStatCache *Next = getNextStatCache())
- return Next->getStat(Path, StatBuf, FileDescriptor);
+ return Next->getStat(Path, StatBuf, isFile, FileDescriptor);
// If we hit the end of the list of stat caches to try, just compute and
// return it without a cache.
- return get(Path, StatBuf, FileDescriptor, 0) ? CacheMissing : CacheExists;
+ return get(Path, StatBuf,
+ isFile, FileDescriptor, 0) ? CacheMissing : CacheExists;
}
};
@@ -97,7 +98,7 @@ public:
iterator end() const { return StatCalls.end(); }
virtual LookupResult getStat(const char *Path, struct stat &StatBuf,
- int *FileDescriptor);
+ bool isFile, int *FileDescriptor);
};
} // end namespace clang
diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h
index 76242ec0a56d..c04a893c6f6e 100644
--- a/include/clang/Basic/IdentifierTable.h
+++ b/include/clang/Basic/IdentifierTable.h
@@ -16,9 +16,9 @@
#ifndef LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
#define LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
+#include "clang/Basic/LLVM.h"
#include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/TokenKinds.h"
-#include "clang/Basic/LLVM.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
@@ -146,9 +146,6 @@ public:
bool hadMacroDefinition() const {
return HadMacro;
}
- void setHadMacroDefinition(bool Val) {
- HadMacro = Val;
- }
/// getTokenID - If this is a source-language token (e.g. 'for'), this API
/// can be used to cause the lexer to map identifiers to source-language
@@ -297,11 +294,11 @@ public:
}
/// \brief Determine whether this is the contextual keyword
- /// '__experimental_modules_import'.
+ /// 'import'.
bool isModulesImport() const { return IsModulesImport; }
/// \brief Set whether this identifier is the contextual keyword
- /// '__experimental_modules_import'.
+ /// 'import'.
void setModulesImport(bool I) {
IsModulesImport = I;
if (I)
diff --git a/include/clang/Basic/LLVM.h b/include/clang/Basic/LLVM.h
index 13c5b445b8ee..306c75e57a9f 100644
--- a/include/clang/Basic/LLVM.h
+++ b/include/clang/Basic/LLVM.h
@@ -16,19 +16,24 @@
#ifndef CLANG_BASIC_LLVM_H
#define CLANG_BASIC_LLVM_H
-// This should be the only #include, force #includes of all the others on
-// clients.
+// Do not proliferate #includes here, require clients to #include their
+// dependencies.
+// Casting.h has complex templates that cannot be easily forward declared.
#include "llvm/Support/Casting.h"
+// None.h includes an enumerator that is desired & cannot be forward declared
+// without a definition of NoneType.
+#include "llvm/ADT/None.h"
namespace llvm {
// ADT's.
class StringRef;
class Twine;
template<typename T> class ArrayRef;
- template<class T> class OwningPtr;
+ template<typename T> class OwningPtr;
template<unsigned InternalLen> class SmallString;
template<typename T, unsigned N> class SmallVector;
template<typename T> class SmallVectorImpl;
+ template<typename T> class Optional;
template<typename T>
struct SaveAndRestore;
@@ -53,6 +58,8 @@ namespace clang {
using llvm::cast_or_null;
// ADT's.
+ using llvm::None;
+ using llvm::Optional;
using llvm::StringRef;
using llvm::Twine;
using llvm::ArrayRef;
diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def
index dbc08c7dca1f..3de0107dff6d 100644
--- a/include/clang/Basic/LangOptions.def
+++ b/include/clang/Basic/LangOptions.def
@@ -45,9 +45,10 @@ LANGOPT(C99 , 1, 0, "C99")
LANGOPT(C11 , 1, 0, "C11")
LANGOPT(MicrosoftExt , 1, 0, "Microsoft extensions")
LANGOPT(MicrosoftMode , 1, 0, "Microsoft compatibility mode")
+LANGOPT(AsmBlocks , 1, 0, "Microsoft inline asm blocks")
LANGOPT(Borland , 1, 0, "Borland extensions")
LANGOPT(CPlusPlus , 1, 0, "C++")
-LANGOPT(CPlusPlus0x , 1, 0, "C++0x")
+LANGOPT(CPlusPlus11 , 1, 0, "C++0x")
LANGOPT(CPlusPlus1y , 1, 0, "C++1y")
LANGOPT(ObjC1 , 1, 0, "Objective-C 1")
LANGOPT(ObjC2 , 1, 0, "Objective-C 2")
@@ -115,7 +116,9 @@ LANGOPT(ShortEnums , 1, 0, "short enum types")
LANGOPT(OpenCL , 1, 0, "OpenCL")
LANGOPT(OpenCLVersion , 32, 0, "OpenCL version")
+LANGOPT(NativeHalfType , 1, 0, "Native half type support")
LANGOPT(CUDA , 1, 0, "CUDA")
+LANGOPT(OpenMP , 1, 0, "OpenMP support")
LANGOPT(AssumeSaneOperatorNew , 1, 1, "implicit __attribute__((malloc)) for C++'s new operators")
BENIGN_LANGOPT(ElideConstructors , 1, 1, "C++ copy constructor elision")
@@ -144,18 +147,21 @@ BENIGN_LANGOPT(DelayedTemplateParsing , 1, 0, "delayed template parsing")
LANGOPT(BlocksRuntimeOptional , 1, 0, "optional blocks runtime")
ENUM_LANGOPT(GC, GCMode, 2, NonGC, "Objective-C Garbage Collection mode")
-ENUM_LANGOPT(VisibilityMode, Visibility, 3, DefaultVisibility,
- "symbol visibility")
+ENUM_LANGOPT(ValueVisibilityMode, Visibility, 3, DefaultVisibility,
+ "value symbol visibility")
+ENUM_LANGOPT(TypeVisibilityMode, Visibility, 3, DefaultVisibility,
+ "type symbol visibility")
ENUM_LANGOPT(StackProtector, StackProtectorMode, 2, SSPOff,
"stack protector mode")
ENUM_LANGOPT(SignedOverflowBehavior, SignedOverflowBehaviorTy, 2, SOB_Undefined,
"signed integer overflow handling")
-ENUM_LANGOPT(FPContractMode, FPContractModeKind, 2, FPC_On, "FP_CONTRACT mode")
BENIGN_LANGOPT(InstantiationDepth, 32, 512,
"maximum template instantiation depth")
BENIGN_LANGOPT(ConstexprCallDepth, 32, 512,
"maximum constexpr call depth")
+BENIGN_LANGOPT(BracketDepth, 32, 256,
+ "maximum bracket nesting depth")
BENIGN_LANGOPT(NumLargeByValueCopy, 32, 0,
"if non-zero, warn about parameter or return Warn if parameter/return value is larger in bytes than this setting. 0 is no check.")
VALUE_LANGOPT(MSCVersion, 32, 0,
@@ -163,17 +169,8 @@ 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/LangOptions.h b/include/clang/Basic/LangOptions.h
index fbb014e96707..21ca7eb201c9 100644
--- a/include/clang/Basic/LangOptions.h
+++ b/include/clang/Basic/LangOptions.h
@@ -15,14 +15,23 @@
#ifndef LLVM_CLANG_LANGOPTIONS_H
#define LLVM_CLANG_LANGOPTIONS_H
-#include <string>
+#include "clang/Basic/CommentOptions.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/ObjCRuntime.h"
#include "clang/Basic/Visibility.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include <string>
namespace clang {
+struct SanitizerOptions {
+#define SANITIZER(NAME, ID) unsigned ID : 1;
+#include "clang/Basic/Sanitizers.def"
+
+ /// \brief Cached set of sanitizer options with all sanitizers disabled.
+ static const SanitizerOptions Disabled;
+};
+
/// Bitfields of LangOptions, split out from LangOptions in order to ensure that
/// this large collection of bitfields is a trivial class type.
class LangOptionsBase {
@@ -32,6 +41,7 @@ public:
#define ENUM_LANGOPT(Name, Type, Bits, Default, Description)
#include "clang/Basic/LangOptions.def"
+ SanitizerOptions Sanitize;
protected:
// Define language options of enumeration type. These are private, and will
// have accessors (below).
@@ -56,12 +66,6 @@ public:
SOB_Trapping // -ftrapv
};
- enum FPContractModeKind {
- FPC_Off, // Form fused FP ops only where result will not be affected.
- FPC_On, // Form fused FP ops according to FP_CONTRACT rules.
- FPC_Fast // Aggressively fuse FP ops (E.g. FMA).
- };
-
public:
clang::ObjCRuntime ObjCRuntime;
@@ -75,6 +79,9 @@ public:
/// \brief The name of the current module.
std::string CurrentModule;
+
+ /// \brief Options for parsing comments.
+ CommentOptions CommentOpts;
LangOptions();
diff --git a/include/clang/Basic/Linkage.h b/include/clang/Basic/Linkage.h
index 6bc1f5d5ef1c..01b8db15f511 100644
--- a/include/clang/Basic/Linkage.h
+++ b/include/clang/Basic/Linkage.h
@@ -42,6 +42,14 @@ enum Linkage {
ExternalLinkage
};
+/// \brief Describes the different kinds of language linkage
+/// (C++ [dcl.link]) that an entity may have.
+enum LanguageLinkage {
+ CLanguageLinkage,
+ CXXLanguageLinkage,
+ NoLanguageLinkage
+};
+
/// \brief A more specific kind of linkage than enum Linkage.
///
/// This is relevant to CodeGen and AST file reading.
diff --git a/include/clang/Basic/MacroBuilder.h b/include/clang/Basic/MacroBuilder.h
index 6df3a383df9d..9a9eaa24983c 100644
--- a/include/clang/Basic/MacroBuilder.h
+++ b/include/clang/Basic/MacroBuilder.h
@@ -15,6 +15,7 @@
#ifndef LLVM_CLANG_BASIC_MACROBUILDER_H
#define LLVM_CLANG_BASIC_MACROBUILDER_H
+#include "clang/Basic/LLVM.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/raw_ostream.h"
diff --git a/include/clang/Basic/Module.h b/include/clang/Basic/Module.h
index b6b088c1f701..d2a43f0219e6 100644
--- a/include/clang/Basic/Module.h
+++ b/include/clang/Basic/Module.h
@@ -18,10 +18,10 @@
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/SetVector.h"
#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>
@@ -34,12 +34,12 @@ namespace clang {
class DirectoryEntry;
class FileEntry;
+class FileManager;
class LangOptions;
class TargetInfo;
/// \brief Describes the name of a module.
-typedef llvm::SmallVector<std::pair<std::string, SourceLocation>, 2>
- ModuleId;
+typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
/// \brief Describes a module or submodule.
class Module {
@@ -68,23 +68,26 @@ private:
/// \brief The AST file if this is a top-level module which has a
/// corresponding serialized AST file, or null otherwise.
const FileEntry *ASTFile;
-
+
+ /// \brief The top-level headers associated with this module.
+ llvm::SmallSetVector<const FileEntry *, 2> TopHeaders;
+
+ /// \brief top-level header filenames that aren't resolved to FileEntries yet.
+ std::vector<std::string> TopHeaderNames;
+
public:
/// \brief The headers that are part of this module.
- llvm::SmallVector<const FileEntry *, 2> Headers;
+ 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;
+ SmallVector<const FileEntry *, 2> ExcludedHeaders;
/// \brief The set of language features required to use this module.
///
/// If any of these features is not present, the \c IsAvailable bit
/// will be false to indicate that this (sub)module is not
/// available.
- llvm::SmallVector<std::string, 2> Requires;
+ SmallVector<std::string, 2> Requires;
/// \brief Whether this module is available in the current
/// translation unit.
@@ -116,7 +119,14 @@ public:
/// \brief Whether, when inferring submodules, the inferr submodules should
/// export all modules they import (e.g., the equivalent of "export *").
unsigned InferExportWildcard : 1;
-
+
+ /// \brief Whether the set of configuration macros is exhaustive.
+ ///
+ /// When the set of configuration macros is exhaustive, meaning
+ /// that no identifier not in this list should affect how the module is
+ /// built.
+ unsigned ConfigMacrosExhaustive : 1;
+
/// \brief Describes the visibility of the various names within a
/// particular module.
enum NameVisibilityKind {
@@ -137,7 +147,7 @@ public:
/// \brief The set of modules imported by this module, and on which this
/// module depends.
- llvm::SmallVector<Module *, 2> Imports;
+ SmallVector<Module *, 2> Imports;
/// \brief Describes an exported module.
///
@@ -146,7 +156,7 @@ public:
typedef llvm::PointerIntPair<Module *, 1, bool> ExportDecl;
/// \brief The set of export declarations.
- llvm::SmallVector<ExportDecl, 2> Exports;
+ SmallVector<ExportDecl, 2> Exports;
/// \brief Describes an exported module that has not yet been resolved
/// (perhaps because the module it refers to has not yet been loaded).
@@ -164,8 +174,58 @@ public:
};
/// \brief The set of export declarations that have yet to be resolved.
- llvm::SmallVector<UnresolvedExportDecl, 2> UnresolvedExports;
-
+ SmallVector<UnresolvedExportDecl, 2> UnresolvedExports;
+
+ /// \brief A library or framework to link against when an entity from this
+ /// module is used.
+ struct LinkLibrary {
+ LinkLibrary() : IsFramework(false) { }
+ LinkLibrary(const std::string &Library, bool IsFramework)
+ : Library(Library), IsFramework(IsFramework) { }
+
+ /// \brief The library to link against.
+ ///
+ /// This will typically be a library or framework name, but can also
+ /// be an absolute path to the library or framework.
+ std::string Library;
+
+ /// \brief Whether this is a framework rather than a library.
+ bool IsFramework;
+ };
+
+ /// \brief The set of libraries or frameworks to link against when
+ /// an entity from this module is used.
+ llvm::SmallVector<LinkLibrary, 2> LinkLibraries;
+
+ /// \brief The set of "configuration macros", which are macros that
+ /// (intentionally) change how this module is built.
+ std::vector<std::string> ConfigMacros;
+
+ /// \brief An unresolved conflict with another module.
+ struct UnresolvedConflict {
+ /// \brief The (unresolved) module id.
+ ModuleId Id;
+
+ /// \brief The message provided to the user when there is a conflict.
+ std::string Message;
+ };
+
+ /// \brief The list of conflicts for which the module-id has not yet been
+ /// resolved.
+ std::vector<UnresolvedConflict> UnresolvedConflicts;
+
+ /// \brief A conflict between two modules.
+ struct Conflict {
+ /// \brief The module that this module conflicts with.
+ Module *Other;
+
+ /// \brief The message provided to the user when there is a conflict.
+ std::string Message;
+ };
+
+ /// \brief The list of conflicts.
+ std::vector<Conflict> Conflicts;
+
/// \brief Construct a top-level module.
explicit Module(StringRef Name, SourceLocation DefinitionLoc,
bool IsFramework)
@@ -173,7 +233,8 @@ public:
IsAvailable(true), IsFromModuleFile(false), IsFramework(IsFramework),
IsExplicit(false), IsSystem(false),
InferSubmodules(false), InferExplicitSubmodules(false),
- InferExportWildcard(false), NameVisibility(Hidden) { }
+ InferExportWildcard(false), ConfigMacrosExhaustive(false),
+ NameVisibility(Hidden) { }
/// \brief Construct a new module or submodule.
Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
@@ -217,7 +278,13 @@ public:
return false;
}
-
+
+ /// \brief Determine whether this module is a subframework of another
+ /// framework.
+ bool isSubFramework() const {
+ return IsFramework && Parent && Parent->isPartOfFramework();
+ }
+
/// \brief Retrieve the full name of this module, including the path from
/// its top-level module.
std::string getFullModuleName() const;
@@ -266,6 +333,20 @@ public:
return Umbrella && Umbrella.is<const DirectoryEntry *>();
}
+ /// \brief Add a top-level header associated with this module.
+ void addTopHeader(const FileEntry *File) {
+ assert(File);
+ TopHeaders.insert(File);
+ }
+
+ /// \brief Add a top-level header filename associated with this module.
+ void addTopHeaderFilename(StringRef Filename) {
+ TopHeaderNames.push_back(Filename);
+ }
+
+ /// \brief The top-level headers associated with this module.
+ ArrayRef<const FileEntry *> getTopHeaders(FileManager &FileMgr);
+
/// \brief Add the given feature requirement to the list of features
/// required by this module.
///
@@ -284,7 +365,7 @@ public:
///
/// \returns The submodule if found, or NULL otherwise.
Module *findSubmodule(StringRef Name) const;
-
+
typedef std::vector<Module *>::iterator submodule_iterator;
typedef std::vector<Module *>::const_iterator submodule_const_iterator;
@@ -292,14 +373,17 @@ public:
submodule_const_iterator submodule_begin() const {return SubModules.begin();}
submodule_iterator submodule_end() { return SubModules.end(); }
submodule_const_iterator submodule_end() const { return SubModules.end(); }
-
+
+ /// \brief Returns the exported modules based on the wildcard restrictions.
+ void getExportedModules(SmallVectorImpl<Module *> &Exported) const;
+
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;
+ void print(raw_ostream &OS, unsigned Indent = 0) const;
/// \brief Dump the contents of this module to the given output stream.
void dump() const;
diff --git a/include/clang/Basic/ObjCRuntime.h b/include/clang/Basic/ObjCRuntime.h
index d543b7671549..18ef64a31527 100644
--- a/include/clang/Basic/ObjCRuntime.h
+++ b/include/clang/Basic/ObjCRuntime.h
@@ -104,7 +104,7 @@ public:
return true;
}
- /// \brief Is this runtime basically of the GNUstep family of runtimes?
+ /// \brief Is this runtime basically of the GNU family of runtimes?
bool isGNUFamily() const {
switch (getKind()) {
case FragileMacOSX:
@@ -164,6 +164,8 @@ public:
return getVersion() >= VersionTuple(10, 8);
case iOS:
return (getVersion() >= VersionTuple(6));
+ case GNUstep:
+ return getVersion() >= VersionTuple(1, 7);
default:
return false;
@@ -272,6 +274,18 @@ public:
llvm_unreachable("bad kind");
}
+ bool hasAtomicCopyHelper() const {
+ switch (getKind()) {
+ case FragileMacOSX:
+ case MacOSX:
+ case iOS:
+ return true;
+ case GNUstep:
+ return getVersion() >= VersionTuple(1, 7);
+ default: return false;
+ }
+ }
+
/// \brief Try to parse an Objective-C runtime specification from the given
/// string.
///
diff --git a/include/clang/Basic/OnDiskHashTable.h b/include/clang/Basic/OnDiskHashTable.h
index cc9ca9f2ec37..06cb1438e620 100644
--- a/include/clang/Basic/OnDiskHashTable.h
+++ b/include/clang/Basic/OnDiskHashTable.h
@@ -14,11 +14,12 @@
#ifndef LLVM_CLANG_BASIC_ON_DISK_HASH_TABLE_H
#define LLVM_CLANG_BASIC_ON_DISK_HASH_TABLE_H
+#include "clang/Basic/LLVM.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Host.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/Host.h"
#include <cassert>
#include <cstdlib>
diff --git a/include/clang/Basic/OpenMPKinds.def b/include/clang/Basic/OpenMPKinds.def
new file mode 100644
index 000000000000..f968977f64bc
--- /dev/null
+++ b/include/clang/Basic/OpenMPKinds.def
@@ -0,0 +1,23 @@
+//===--- OpenMPKinds.def - OpenMP directives and clauses list ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// \brief This file defines the list of supported OpenMP directives and
+/// clauses.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef OPENMP_DIRECTIVE
+# define OPENMP_DIRECTIVE(Name)
+#endif
+
+// OpenMP directives.
+OPENMP_DIRECTIVE(threadprivate)
+OPENMP_DIRECTIVE(parallel)
+
+#undef OPENMP_DIRECTIVE
diff --git a/include/clang/Basic/OpenMPKinds.h b/include/clang/Basic/OpenMPKinds.h
new file mode 100644
index 000000000000..c90e9a0a76d5
--- /dev/null
+++ b/include/clang/Basic/OpenMPKinds.h
@@ -0,0 +1,37 @@
+//===--- OpenMPKinds.h - OpenMP enums ---------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines some OpenMP-specific enums and functions.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_OPENMPKINDS_H
+#define LLVM_CLANG_BASIC_OPENMPKINDS_H
+
+#include "llvm/ADT/StringRef.h"
+
+namespace clang {
+
+/// \brief OpenMP directives.
+enum OpenMPDirectiveKind {
+ OMPD_unknown = 0,
+#define OPENMP_DIRECTIVE(Name) \
+ OMPD_##Name,
+#include "clang/Basic/OpenMPKinds.def"
+ NUM_OPENMP_DIRECTIVES
+};
+
+OpenMPDirectiveKind getOpenMPDirectiveKind(llvm::StringRef Str);
+const char *getOpenMPDirectiveName(OpenMPDirectiveKind Kind);
+
+}
+
+#endif
+
diff --git a/include/clang/Basic/OperatorPrecedence.h b/include/clang/Basic/OperatorPrecedence.h
new file mode 100644
index 000000000000..b68d577c806c
--- /dev/null
+++ b/include/clang/Basic/OperatorPrecedence.h
@@ -0,0 +1,52 @@
+//===--- OperatorPrecedence.h - Operator precedence levels ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines and computes precedence levels for binary/ternary operators.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_OPERATOR_PRECEDENCE_H
+#define LLVM_CLANG_OPERATOR_PRECEDENCE_H
+
+#include "clang/Basic/TokenKinds.h"
+
+namespace clang {
+
+/// PrecedenceLevels - These are precedences for the binary/ternary
+/// operators in the C99 grammar. These have been named to relate
+/// with the C99 grammar productions. Low precedences numbers bind
+/// more weakly than high numbers.
+namespace prec {
+ enum Level {
+ Unknown = 0, // Not binary operator.
+ Comma = 1, // ,
+ Assignment = 2, // =, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |=
+ Conditional = 3, // ?
+ LogicalOr = 4, // ||
+ LogicalAnd = 5, // &&
+ InclusiveOr = 6, // |
+ ExclusiveOr = 7, // ^
+ And = 8, // &
+ Equality = 9, // ==, !=
+ Relational = 10, // >=, <=, >, <
+ Shift = 11, // <<, >>
+ Additive = 12, // -, +
+ Multiplicative = 13, // *, /, %
+ PointerToMember = 14 // .*, ->*
+ };
+}
+
+/// \brief Return the precedence of the specified binary operator token.
+prec::Level getBinOpPrecedence(tok::TokenKind Kind, bool GreaterThanIsOperator,
+ bool CPlusPlus11);
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_OPERATOR_PRECEDENCE_H
diff --git a/include/clang/Basic/PartialDiagnostic.h b/include/clang/Basic/PartialDiagnostic.h
index 3f4626ec0a7e..3f68160f69a6 100644
--- a/include/clang/Basic/PartialDiagnostic.h
+++ b/include/clang/Basic/PartialDiagnostic.h
@@ -19,6 +19,7 @@
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
#include <cassert>
@@ -200,6 +201,14 @@ public:
}
}
+#if LLVM_HAS_RVALUE_REFERENCES
+ PartialDiagnostic(PartialDiagnostic &&Other)
+ : DiagID(Other.DiagID), DiagStorage(Other.DiagStorage),
+ Allocator(Other.Allocator) {
+ Other.DiagStorage = 0;
+ }
+#endif
+
PartialDiagnostic(const PartialDiagnostic &Other, Storage *DiagStorage)
: DiagID(Other.DiagID), DiagStorage(DiagStorage),
Allocator(reinterpret_cast<StorageAllocator *>(~uintptr_t(0)))
@@ -242,6 +251,19 @@ public:
return *this;
}
+#if LLVM_HAS_RVALUE_REFERENCES
+ PartialDiagnostic &operator=(PartialDiagnostic &&Other) {
+ freeStorage();
+
+ DiagID = Other.DiagID;
+ DiagStorage = Other.DiagStorage;
+ Allocator = Other.Allocator;
+
+ Other.DiagStorage = 0;
+ return *this;
+ }
+#endif
+
~PartialDiagnostic() {
freeStorage();
}
@@ -299,7 +321,7 @@ public:
}
void EmitToString(DiagnosticsEngine &Diags,
- llvm::SmallVectorImpl<char> &Buf) const {
+ SmallVectorImpl<char> &Buf) const {
// FIXME: It should be possible to render a diagnostic to a string without
// messing with the state of the diagnostics engine.
DiagnosticBuilder DB(Diags.Report(getDiagID()));
diff --git a/include/clang/Basic/Sanitizers.def b/include/clang/Basic/Sanitizers.def
index 085ca16eae1a..709ec8d0376f 100644
--- a/include/clang/Basic/Sanitizers.def
+++ b/include/clang/Basic/Sanitizers.def
@@ -40,30 +40,61 @@
// AddressSanitizer
SANITIZER("address", Address)
+// More features of AddressSanitizer that should be turned on explicitly.
+SANITIZER("init-order", InitOrder)
+SANITIZER("use-after-return", UseAfterReturn)
+SANITIZER("use-after-scope", UseAfterScope)
+
+SANITIZER_GROUP("address-full", AddressFull,
+ Address | InitOrder | UseAfterReturn | UseAfterScope)
+
+// MemorySanitizer
+SANITIZER("memory", Memory)
// ThreadSanitizer
SANITIZER("thread", Thread)
// UndefinedBehaviorSanitizer
-SANITIZER("signed-integer-overflow", SignedIntegerOverflow)
-SANITIZER("divide-by-zero", DivideByZero)
+SANITIZER("alignment", Alignment)
+SANITIZER("bool", Bool)
+SANITIZER("bounds", Bounds)
+SANITIZER("enum", Enum)
+SANITIZER("float-cast-overflow", FloatCastOverflow)
+SANITIZER("float-divide-by-zero", FloatDivideByZero)
+SANITIZER("integer-divide-by-zero", IntegerDivideByZero)
+SANITIZER("null", Null)
+SANITIZER("object-size", ObjectSize)
+SANITIZER("return", Return)
SANITIZER("shift", Shift)
+SANITIZER("signed-integer-overflow", SignedIntegerOverflow)
SANITIZER("unreachable", Unreachable)
-SANITIZER("return", Return)
SANITIZER("vla-bound", VLABound)
-SANITIZER("alignment", Alignment)
-SANITIZER("null", Null)
SANITIZER("vptr", Vptr)
-SANITIZER("object-size", ObjectSize)
-SANITIZER("float-cast-overflow", FloatCastOverflow)
-// -fsanitize=undefined (and its alias -fcatch-undefined-behavior). This should
-// include all the sanitizers which have low overhead, no ABI or address space
-// layout implications, and only catch undefined behavior.
+// IntegerSanitizer
+SANITIZER("unsigned-integer-overflow", UnsignedIntegerOverflow)
+
+// -fsanitize=undefined includes all the sanitizers which have low overhead, no
+// ABI or address space layout implications, and only catch undefined behavior.
SANITIZER_GROUP("undefined", Undefined,
- SignedIntegerOverflow | DivideByZero | Shift | Unreachable |
- Return | VLABound | Alignment | Null | Vptr | ObjectSize |
- FloatCastOverflow)
+ Alignment | Bool | Bounds | Enum | FloatCastOverflow |
+ FloatDivideByZero | IntegerDivideByZero | Null | ObjectSize |
+ Return | Shift | SignedIntegerOverflow | Unreachable |
+ VLABound | Vptr)
+
+// -fsanitize=undefined-trap (and its alias -fcatch-undefined-behavior) includes
+// all sanitizers included by -fsanitize=undefined, except those that require
+// runtime support. This group is generally used in conjunction with the
+// -fsanitize-undefined-trap-on-error flag.
+SANITIZER_GROUP("undefined-trap", UndefinedTrap,
+ Alignment | Bool | Bounds | Enum | FloatCastOverflow |
+ FloatDivideByZero | IntegerDivideByZero | Null | ObjectSize |
+ Return | Shift | SignedIntegerOverflow | Unreachable |
+ VLABound)
+
+SANITIZER_GROUP("integer", Integer,
+ SignedIntegerOverflow | UnsignedIntegerOverflow | Shift |
+ IntegerDivideByZero)
#undef SANITIZER
#undef SANITIZER_GROUP
diff --git a/include/clang/Basic/SourceLocation.h b/include/clang/Basic/SourceLocation.h
index cfcf468772ef..143beb67e0b7 100644
--- a/include/clang/Basic/SourceLocation.h
+++ b/include/clang/Basic/SourceLocation.h
@@ -16,12 +16,12 @@
#define LLVM_CLANG_SOURCELOCATION_H
#include "clang/Basic/LLVM.h"
-#include "llvm/Support/PointerLikeTypeTraits.h"
#include "llvm/Support/Compiler.h"
-#include <utility>
-#include <functional>
+#include "llvm/Support/PointerLikeTypeTraits.h"
#include <cassert>
+#include <functional>
#include <string>
+#include <utility>
namespace llvm {
class MemoryBuffer;
@@ -165,7 +165,7 @@ public:
return (void*)(uintptr_t)getRawEncoding();
}
- /// getFromPtrEncoding - Turn a pointer encoding of a SourceLocation object
+ /// \brief Turn a pointer encoding of a SourceLocation object back
/// into a real SourceLocation.
static SourceLocation getFromPtrEncoding(const void *Encoding) {
return getFromRawEncoding((unsigned)(uintptr_t)Encoding);
@@ -218,7 +218,7 @@ public:
/// \brief Represents a character-granular source range.
///
/// The underlying SourceRange can either specify the starting/ending character
-/// of the range, or it can specify the start or the range and the start of the
+/// of the range, or it can specify the start of the range and the start of the
/// last token of the range (a "token range"). In the token range case, the
/// size of the last token must be measured to determine the actual end of the
/// range.
@@ -227,20 +227,14 @@ class CharSourceRange {
bool IsTokenRange;
public:
CharSourceRange() : IsTokenRange(false) {}
- CharSourceRange(SourceRange R, bool ITR) : Range(R),IsTokenRange(ITR){}
+ CharSourceRange(SourceRange R, bool ITR) : Range(R), IsTokenRange(ITR) {}
static CharSourceRange getTokenRange(SourceRange R) {
- CharSourceRange Result;
- Result.Range = R;
- Result.IsTokenRange = true;
- return Result;
+ return CharSourceRange(R, true);
}
static CharSourceRange getCharRange(SourceRange R) {
- CharSourceRange Result;
- Result.Range = R;
- Result.IsTokenRange = false;
- return Result;
+ return CharSourceRange(R, false);
}
static CharSourceRange getTokenRange(SourceLocation B, SourceLocation E) {
diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h
index db6bfd2ad3dd..00c96c3da0d0 100644
--- a/include/clang/Basic/SourceManager.h
+++ b/include/clang/Basic/SourceManager.h
@@ -10,7 +10,7 @@
/// \file
/// \brief Defines the SourceManager interface.
///
-/// There are three different types of locations in a file: a spelling
+/// There are three different types of locations in a %file: a spelling
/// location, an expansion location, and a presumed location.
///
/// Given an example of:
@@ -35,21 +35,22 @@
#ifndef LLVM_CLANG_SOURCEMANAGER_H
#define LLVM_CLANG_SOURCEMANAGER_H
-#include "clang/Basic/LLVM.h"
#include "clang/Basic/FileManager.h"
+#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/DataTypes.h"
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/ADT/PointerUnion.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/Support/MemoryBuffer.h"
+#include <cassert>
#include <map>
#include <vector>
-#include <cassert>
namespace clang {
@@ -78,7 +79,7 @@ namespace SrcMgr {
};
/// \brief One instance of this struct is kept for every file loaded or used.
- ////
+ ///
/// This object owns the MemoryBuffer object.
class ContentCache {
enum CCFlags {
@@ -270,7 +271,7 @@ namespace SrcMgr {
return SourceLocation::getFromRawEncoding(IncludeLoc);
}
const ContentCache* getContentCache() const {
- return reinterpret_cast<const ContentCache*>(Data & ~7UL);
+ return reinterpret_cast<const ContentCache*>(Data & ~uintptr_t(7));
}
/// \brief Return whether this is a system header or not.
@@ -328,6 +329,11 @@ namespace SrcMgr {
SourceLocation::getFromRawEncoding(ExpansionLocEnd).isInvalid();
}
+ bool isMacroBodyExpansion() const {
+ return getExpansionLocStart().isValid() &&
+ SourceLocation::getFromRawEncoding(ExpansionLocEnd).isValid();
+ }
+
bool isFunctionMacroExpansion() const {
return getExpansionLocStart().isValid() &&
getExpansionLocStart() != getExpansionLocEnd();
@@ -429,6 +435,11 @@ public:
/// \returns true if an error occurred that prevented the source-location
/// entry from being loaded.
virtual bool ReadSLocEntry(int ID) = 0;
+
+ /// \brief Retrieve the module import location and name for the given ID, if
+ /// in fact it was loaded from a module (rather than, say, a precompiled
+ /// header).
+ virtual std::pair<SourceLocation, StringRef> getModuleImportLoc(int ID) = 0;
};
@@ -436,7 +447,7 @@ public:
///
/// The cache structure is complex enough to be worth breaking out of
/// SourceManager.
-class IsBeforeInTranslationUnitCache {
+class InBeforeInTUCacheEntry {
/// \brief The FileID's of the cached query.
///
/// If these match up with a subsequent query, the result can be reused.
@@ -458,7 +469,6 @@ class IsBeforeInTranslationUnitCache {
/// random token in the parent.
unsigned LCommonOffset, RCommonOffset;
public:
-
/// \brief Return true if the currently cached values match up with
/// the specified LHS/RHS query.
///
@@ -508,6 +518,11 @@ public:
};
+/// \brief The stack used when building modules on demand, which is used
+/// to provide a link between the source managers of the different compiler
+/// instances.
+typedef ArrayRef<std::pair<std::string, FullSourceLoc> > ModuleBuildStack;
+
/// \brief This class handles loading and caching of source files into memory.
///
/// This object owns the MemoryBuffer objects for all of the loaded
@@ -572,13 +587,13 @@ class SourceManager : public RefCountedBase<SourceManager> {
///
/// Positive FileIDs are indexes into this table. Entry 0 indicates an invalid
/// expansion.
- std::vector<SrcMgr::SLocEntry> LocalSLocEntryTable;
+ SmallVector<SrcMgr::SLocEntry, 0> LocalSLocEntryTable;
/// \brief The table of SLocEntries that are loaded from other modules.
///
/// Negative FileIDs are indexes into this table. To get from ID to an index,
/// use (-ID - 2).
- mutable std::vector<SrcMgr::SLocEntry> LoadedSLocEntryTable;
+ mutable SmallVector<SrcMgr::SLocEntry, 0> LoadedSLocEntryTable;
/// \brief The starting offset of the next local SLocEntry.
///
@@ -631,8 +646,21 @@ class SourceManager : public RefCountedBase<SourceManager> {
// Statistics for -print-stats.
mutable unsigned NumLinearScans, NumBinaryProbes;
- // Cache results for the isBeforeInTranslationUnit method.
- mutable IsBeforeInTranslationUnitCache IsBeforeInTUCache;
+ /// The key value into the IsBeforeInTUCache table.
+ typedef std::pair<FileID, FileID> IsBeforeInTUCacheKey;
+
+ /// The IsBeforeInTranslationUnitCache is a mapping from FileID pairs
+ /// to cache results.
+ typedef llvm::DenseMap<IsBeforeInTUCacheKey, InBeforeInTUCacheEntry>
+ InBeforeInTUCache;
+
+ /// Cache results for the isBeforeInTranslationUnit method.
+ mutable InBeforeInTUCache IBTUCache;
+ mutable InBeforeInTUCacheEntry IBTUCacheOverflow;
+
+ /// Return the cache entry for comparing the given file IDs
+ /// for isBeforeInTranslationUnit.
+ InBeforeInTUCacheEntry &getInBeforeInTUCache(FileID LFID, FileID RFID) const;
// Cache for the "fake" buffer used for error-recovery purposes.
mutable llvm::MemoryBuffer *FakeBufferForRecovery;
@@ -645,6 +673,15 @@ class SourceManager : public RefCountedBase<SourceManager> {
mutable llvm::DenseMap<FileID, MacroArgsMap *> MacroArgsCacheMap;
+ /// \brief The stack of modules being built, which is used to detect
+ /// cycles in the module dependency graph as modules are being built, as
+ /// well as to describe why we're rebuilding a particular module.
+ ///
+ /// There is no way to set this value from the command line. If we ever need
+ /// to do so (e.g., if on-demand module construction moves out-of-process),
+ /// we can add a cc1-level option to do so.
+ SmallVector<std::pair<std::string, FullSourceLoc>, 2> StoredModuleBuildStack;
+
// SourceManager doesn't support copy construction.
explicit SourceManager(const SourceManager&) LLVM_DELETED_FUNCTION;
void operator=(const SourceManager&) LLVM_DELETED_FUNCTION;
@@ -669,6 +706,22 @@ public:
/// (likely to change while trying to use them).
bool userFilesAreVolatile() const { return UserFilesAreVolatile; }
+ /// \brief Retrieve the module build stack.
+ ModuleBuildStack getModuleBuildStack() const {
+ return StoredModuleBuildStack;
+ }
+
+ /// \brief Set the module build stack.
+ void setModuleBuildStack(ModuleBuildStack stack) {
+ StoredModuleBuildStack.clear();
+ StoredModuleBuildStack.append(stack.begin(), stack.end());
+ }
+
+ /// \brief Push an entry to the module build stack.
+ void pushModuleBuildStack(StringRef moduleName, FullSourceLoc importLoc) {
+ StoredModuleBuildStack.push_back(std::make_pair(moduleName.str(),importLoc));
+ }
+
/// \brief Create the FileID for a memory buffer that will represent the
/// FileID for the main source.
///
@@ -959,6 +1012,21 @@ public:
return Entry.getFile().getIncludeLoc();
}
+ // \brief Returns the import location if the given source location is
+ // located within a module, or an invalid location if the source location
+ // is within the current translation unit.
+ std::pair<SourceLocation, StringRef>
+ getModuleImportLoc(SourceLocation Loc) const {
+ FileID FID = getFileID(Loc);
+
+ // Positive file IDs are in the current translation unit, and -1 is a
+ // placeholder.
+ if (FID.ID >= -1)
+ return std::make_pair(SourceLocation(), "");
+
+ return ExternalSLocEntries->getModuleImportLoc(FID.ID);
+ }
+
/// \brief Given a SourceLocation object \p Loc, return the expansion
/// location referenced by the ID.
SourceLocation getExpansionLoc(SourceLocation Loc) const {
@@ -1075,6 +1143,13 @@ public:
/// expanded.
bool isMacroArgExpansion(SourceLocation Loc) const;
+ /// \brief Tests whether the given source location represents the expansion of
+ /// a macro body.
+ ///
+ /// This is equivalent to testing whether the location is part of a macro
+ /// expansion but not the expansion of an argument to a function-like macro.
+ bool isMacroBodyExpansion(SourceLocation Loc) const;
+
/// \brief Returns true if \p Loc is inside the [\p Start, +\p Length)
/// chunk of the source location address space.
///
@@ -1187,7 +1262,8 @@ public:
/// presumed location cannot be calculate (e.g., because \p Loc is invalid
/// or the file containing \p Loc has changed on disk), returns an invalid
/// presumed location.
- PresumedLoc getPresumedLoc(SourceLocation Loc) const;
+ PresumedLoc getPresumedLoc(SourceLocation Loc,
+ bool UseLineDirectives = true) const;
/// \brief Returns true if both SourceLocations correspond to the same file.
bool isFromSameFile(SourceLocation Loc1, SourceLocation Loc2) const {
@@ -1421,40 +1497,13 @@ public:
return !isLoadedFileID(FID);
}
- /// Get a presumed location suitable for displaying in a diagnostic message,
- /// taking into account macro arguments and expansions.
- PresumedLoc getPresumedLocForDisplay(SourceLocation Loc) const {
- // This is a condensed form of the algorithm used by emitCaretDiagnostic to
- // walk to the top of the macro call stack.
- while (Loc.isMacroID()) {
- Loc = skipToMacroArgExpansion(Loc);
- Loc = getImmediateMacroCallerLoc(Loc);
- }
-
- return getPresumedLoc(Loc);
- }
-
- /// Look through spelling locations for a macro argument expansion, and if
- /// found skip to it so that we can trace the argument rather than the macros
- /// in which that argument is used. If no macro argument expansion is found,
- /// don't skip anything and return the starting location.
- SourceLocation skipToMacroArgExpansion(SourceLocation StartLoc) const {
- for (SourceLocation L = StartLoc; L.isMacroID();
- L = getImmediateSpellingLoc(L)) {
- if (isMacroArgExpansion(L))
- return L;
- }
- // Otherwise just return initial location, there's nothing to skip.
- return StartLoc;
- }
-
/// Gets the location of the immediate macro caller, one level up the stack
/// toward the initial macro typed into the source.
SourceLocation getImmediateMacroCallerLoc(SourceLocation Loc) const {
if (!Loc.isMacroID()) return Loc;
// When we have the location of (part of) an expanded parameter, its
- // spelling location points to the argument as typed into the macro call,
+ // spelling location points to the argument as expanded in the macro call,
// and therefore is used to locate the macro caller.
if (isMacroArgExpansion(Loc))
return getImmediateSpellingLoc(Loc);
@@ -1464,22 +1513,6 @@ public:
return getImmediateExpansionRange(Loc).first;
}
- /// Gets the location of the immediate macro callee, one level down the stack
- /// toward the leaf macro.
- SourceLocation getImmediateMacroCalleeLoc(SourceLocation Loc) const {
- if (!Loc.isMacroID()) return Loc;
-
- // When we have the location of (part of) an expanded parameter, its
- // expansion location points to the unexpanded parameter reference within
- // the macro definition (or callee).
- if (isMacroArgExpansion(Loc))
- return getImmediateExpansionRange(Loc).first;
-
- // Otherwise, the callee of the macro is located where this location was
- // spelled inside the macro definition.
- return getImmediateSpellingLoc(Loc);
- }
-
private:
const llvm::MemoryBuffer *getFakeBufferForRecovery() const;
const SrcMgr::ContentCache *getFakeContentCacheForRecovery() const;
@@ -1599,4 +1632,5 @@ public:
} // end namespace clang
+
#endif
diff --git a/include/clang/Basic/Specifiers.h b/include/clang/Basic/Specifiers.h
index c82b8cb91887..8706179a1713 100644
--- a/include/clang/Basic/Specifiers.h
+++ b/include/clang/Basic/Specifiers.h
@@ -62,13 +62,21 @@ namespace clang {
TST_auto, // C++0x auto
TST_unknown_anytype, // __unknown_anytype extension
TST_atomic, // C11 _Atomic
+ TST_image1d_t, // OpenCL image1d_t
+ TST_image1d_array_t, // OpenCL image1d_array_t
+ TST_image1d_buffer_t, // OpenCL image1d_buffer_t
+ TST_image2d_t, // OpenCL image2d_t
+ TST_image2d_array_t, // OpenCL image2d_array_t
+ TST_image3d_t, // OpenCL image3d_t
+ TST_sampler_t, // OpenCL sampler_t
+ TST_event_t, // OpenCL event_t
TST_error // erroneous type
};
/// \brief Structure that packs information about the type specifiers that
/// were written in a particular type specifier sequence.
struct WrittenBuiltinSpecs {
- /*DeclSpec::TST*/ unsigned Type : 5;
+ /*DeclSpec::TST*/ unsigned Type : 6;
/*DeclSpec::TSS*/ unsigned Sign : 2;
/*DeclSpec::TSW*/ unsigned Width : 2;
bool ModeAttr : 1;
@@ -186,7 +194,8 @@ namespace clang {
CC_X86Pascal, // __attribute__((pascal))
CC_AAPCS, // __attribute__((pcs("aapcs")))
CC_AAPCS_VFP, // __attribute__((pcs("aapcs-vfp")))
- CC_PnaclCall // __attribute__((pnaclcall))
+ CC_PnaclCall, // __attribute__((pnaclcall))
+ CC_IntelOclBicc // __attribute__((intel_ocl_bicc))
};
} // end namespace clang
diff --git a/include/clang/Basic/TargetCXXABI.h b/include/clang/Basic/TargetCXXABI.h
new file mode 100644
index 000000000000..c9d28f8774b6
--- /dev/null
+++ b/include/clang/Basic/TargetCXXABI.h
@@ -0,0 +1,261 @@
+//===--- TargetCXXABI.h - C++ ABI Target Configuration ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the TargetCXXABI class, which abstracts details of the
+/// C++ ABI that we're targeting.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TARGETCXXABI_H
+#define LLVM_CLANG_TARGETCXXABI_H
+
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace clang {
+
+/// \brief The basic abstraction for the target C++ ABI.
+class TargetCXXABI {
+public:
+ /// \brief The basic C++ ABI kind.
+ enum Kind {
+ /// The generic Itanium ABI is the standard ABI of most open-source
+ /// and Unix-like platforms. It is the primary ABI targeted by
+ /// many compilers, including Clang and GCC.
+ ///
+ /// It is documented here:
+ /// http://www.codesourcery.com/public/cxx-abi/
+ GenericItanium,
+
+ /// The generic ARM ABI is a modified version of the Itanium ABI
+ /// proposed by ARM for use on ARM-based platforms.
+ ///
+ /// These changes include:
+ /// - the representation of member function pointers is adjusted
+ /// to not conflict with the 'thumb' bit of ARM function pointers;
+ /// - constructors and destructors return 'this';
+ /// - guard variables are smaller;
+ /// - inline functions are never key functions;
+ /// - array cookies have a slightly different layout;
+ /// - additional convenience functions are specified;
+ /// - and more!
+ ///
+ /// It is documented here:
+ /// http://infocenter.arm.com
+ /// /help/topic/com.arm.doc.ihi0041c/IHI0041C_cppabi.pdf
+ GenericARM,
+
+ /// The iOS ABI is a partial implementation of the ARM ABI.
+ /// Several of the features of the ARM ABI were not fully implemented
+ /// in the compilers that iOS was launched with.
+ ///
+ /// Essentially, the iOS ABI includes the ARM changes to:
+ /// - member function pointers,
+ /// - guard variables,
+ /// - array cookies, and
+ /// - constructor/destructor signatures.
+ iOS,
+
+ /// The generic AArch64 ABI is also a modified version of the Itanium ABI,
+ /// but it has fewer divergences than the 32-bit ARM ABI.
+ ///
+ /// The relevant changes from the generic ABI in this case are:
+ /// - representation of member function pointers adjusted as in ARM.
+ /// - guard variables are smaller.
+ GenericAArch64,
+
+ /// The Microsoft ABI is the ABI used by Microsoft Visual Studio (and
+ /// compatible compilers).
+ ///
+ /// FIXME: should this be split into Win32 and Win64 variants?
+ ///
+ /// Only scattered and incomplete official documentation exists.
+ Microsoft
+ };
+
+private:
+ // Right now, this class is passed around as a cheap value type.
+ // If you add more members, especially non-POD members, please
+ // audit the users to pass it by reference instead.
+ Kind TheKind;
+
+public:
+ /// A bogus initialization of the platform ABI.
+ TargetCXXABI() : TheKind(GenericItanium) {}
+
+ TargetCXXABI(Kind kind) : TheKind(kind) {}
+
+ void set(Kind kind) {
+ TheKind = kind;
+ }
+
+ Kind getKind() const { return TheKind; }
+
+ /// \brief Does this ABI generally fall into the Itanium family of ABIs?
+ bool isItaniumFamily() const {
+ switch (getKind()) {
+ case GenericAArch64:
+ case GenericItanium:
+ case GenericARM:
+ case iOS:
+ return true;
+
+ case Microsoft:
+ return false;
+ }
+ llvm_unreachable("bad ABI kind");
+ }
+
+ /// \brief Is this ABI an MSVC-compatible ABI?
+ bool isMicrosoft() const {
+ switch (getKind()) {
+ case GenericAArch64:
+ case GenericItanium:
+ case GenericARM:
+ case iOS:
+ return false;
+
+ case Microsoft:
+ return true;
+ }
+ llvm_unreachable("bad ABI kind");
+ }
+
+ /// \brief Is the default C++ member function calling convention
+ /// the same as the default calling convention?
+ bool isMemberFunctionCCDefault() const {
+ // Right now, this is always true for Microsoft.
+ return !isMicrosoft();
+ }
+
+ /// \brief Does this ABI have different entrypoints for complete-object
+ /// and base-subobject constructors?
+ bool hasConstructorVariants() const {
+ return isItaniumFamily();
+ }
+
+ /// \brief Does this ABI have different entrypoints for complete-object
+ /// and base-subobject destructors?
+ bool hasDestructorVariants() const {
+ return isItaniumFamily();
+ }
+
+ /// \brief Does this ABI allow virtual bases to be primary base classes?
+ bool hasPrimaryVBases() const {
+ return isItaniumFamily();
+ }
+
+ /// \brief Can an out-of-line inline function serve as a key function?
+ ///
+ /// This flag is only useful in ABIs where type data (for example,
+ /// v-tables and type_info objects) are emitted only after processing
+ /// the definition of a special "key" virtual function. (This is safe
+ /// because the ODR requires that every virtual function be defined
+ /// somewhere in a program.) This usually permits such data to be
+ /// emitted in only a single object file, as opposed to redundantly
+ /// in every object file that requires it.
+ ///
+ /// One simple and common definition of "key function" is the first
+ /// virtual function in the class definition which is not defined there.
+ /// This rule works very well when that function has a non-inline
+ /// definition in some non-header file. Unfortunately, when that
+ /// function is defined inline, this rule requires the type data
+ /// to be emitted weakly, as if there were no key function.
+ ///
+ /// The ARM ABI observes that the ODR provides an additional guarantee:
+ /// a virtual function is always ODR-used, so if it is defined inline,
+ /// that definition must appear in every translation unit that defines
+ /// the class. Therefore, there is no reason to allow such functions
+ /// to serve as key functions.
+ ///
+ /// Because this changes the rules for emitting type data,
+ /// it can cause type data to be emitted with both weak and strong
+ /// linkage, which is not allowed on all platforms. Therefore,
+ /// exploiting this observation requires an ABI break and cannot be
+ /// done on a generic Itanium platform.
+ bool canKeyFunctionBeInline() const {
+ switch (getKind()) {
+ case GenericARM:
+ return false;
+
+ case GenericAArch64:
+ case GenericItanium:
+ case iOS: // old iOS compilers did not follow this rule
+ case Microsoft:
+ return true;
+ }
+ llvm_unreachable("bad ABI kind");
+ }
+
+ /// When is record layout allowed to allocate objects in the tail
+ /// padding of a base class?
+ ///
+ /// This decision cannot be changed without breaking platform ABI
+ /// compatibility, and yet it is tied to language guarantees which
+ /// the committee has so far seen fit to strengthen no less than
+ /// three separate times:
+ /// - originally, there were no restrictions at all;
+ /// - C++98 declared that objects could not be allocated in the
+ /// tail padding of a POD type;
+ /// - C++03 extended the definition of POD to include classes
+ /// containing member pointers; and
+ /// - C++11 greatly broadened the definition of POD to include
+ /// all trivial standard-layout classes.
+ /// Each of these changes technically took several existing
+ /// platforms and made them permanently non-conformant.
+ enum TailPaddingUseRules {
+ /// The tail-padding of a base class is always theoretically
+ /// available, even if it's POD. This is not strictly conforming
+ /// in any language mode.
+ AlwaysUseTailPadding,
+
+ /// Only allocate objects in the tail padding of a base class if
+ /// the base class is not POD according to the rules of C++ TR1.
+ /// This is non strictly conforming in C++11 mode.
+ UseTailPaddingUnlessPOD03,
+
+ /// Only allocate objects in the tail padding of a base class if
+ /// the base class is not POD according to the rules of C++11.
+ UseTailPaddingUnlessPOD11
+ };
+ TailPaddingUseRules getTailPaddingUseRules() const {
+ switch (getKind()) {
+ // To preserve binary compatibility, the generic Itanium ABI has
+ // permanently locked the definition of POD to the rules of C++ TR1,
+ // and that trickles down to all the derived ABIs.
+ case GenericItanium:
+ case GenericAArch64:
+ case GenericARM:
+ case iOS:
+ return UseTailPaddingUnlessPOD03;
+
+ // MSVC always allocates fields in the tail-padding of a base class
+ // subobject, even if they're POD.
+ case Microsoft:
+ return AlwaysUseTailPadding;
+ }
+ llvm_unreachable("bad ABI kind");
+ }
+
+ /// Try to parse an ABI name, returning false on error.
+ bool tryParse(llvm::StringRef name);
+
+ friend bool operator==(const TargetCXXABI &left, const TargetCXXABI &right) {
+ return left.getKind() == right.getKind();
+ }
+
+ friend bool operator!=(const TargetCXXABI &left, const TargetCXXABI &right) {
+ return !(left == right);
+ }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
index 2d26783e3875..c05f062aee95 100644
--- a/include/clang/Basic/TargetInfo.h
+++ b/include/clang/Basic/TargetInfo.h
@@ -15,20 +15,21 @@
#ifndef LLVM_CLANG_BASIC_TARGETINFO_H
#define LLVM_CLANG_BASIC_TARGETINFO_H
+#include "clang/Basic/AddressSpaces.h"
+#include "clang/Basic/TargetCXXABI.h"
#include "clang/Basic/LLVM.h"
+#include "clang/Basic/Specifiers.h"
+#include "clang/Basic/TargetOptions.h"
+#include "clang/Basic/VersionTuple.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/DataTypes.h"
-#include "clang/Basic/AddressSpaces.h"
-#include "clang/Basic/TargetOptions.h"
-#include "clang/Basic/VersionTuple.h"
-#include "clang/Basic/Specifiers.h"
#include <cassert>
-#include <vector>
#include <string>
+#include <vector>
namespace llvm {
struct fltSemantics;
@@ -43,26 +44,10 @@ class SourceManager;
namespace Builtin { struct Info; }
-/// \brief The types of C++ ABIs for which we can generate code.
-enum TargetCXXABI {
- /// The generic ("Itanium") C++ ABI, documented at:
- /// http://www.codesourcery.com/public/cxx-abi/
- CXXABI_Itanium,
-
- /// The ARM C++ ABI, based largely on the Itanium ABI but with
- /// significant differences.
- /// http://infocenter.arm.com
- /// /help/topic/com.arm.doc.ihi0041c/IHI0041C_cppabi.pdf
- CXXABI_ARM,
-
- /// The Visual Studio ABI. Only scattered official documentation exists.
- CXXABI_Microsoft
-};
-
/// \brief Exposes information about the current target.
///
class TargetInfo : public RefCountedBase<TargetInfo> {
- llvm::IntrusiveRefCntPtr<TargetOptions> TargetOpts;
+ IntrusiveRefCntPtr<TargetOptions> TargetOpts;
llvm::Triple Triple;
protected:
// Target values set by the ctor of the actual target implementation. Default
@@ -89,7 +74,7 @@ protected:
const llvm::fltSemantics *HalfFormat, *FloatFormat, *DoubleFormat,
*LongDoubleFormat;
unsigned char RegParmMax, SSERegParmMax;
- TargetCXXABI CXXABI;
+ TargetCXXABI TheCXXABI;
const LangAS::Map *AddrSpaceMap;
mutable StringRef PlatformName;
@@ -109,7 +94,7 @@ public:
/// modify the options to canonicalize the target feature information to match
/// what the backend expects.
static TargetInfo* CreateTargetInfo(DiagnosticsEngine &Diags,
- TargetOptions &Opts);
+ TargetOptions *Opts);
virtual ~TargetInfo();
@@ -119,8 +104,8 @@ public:
return *TargetOpts;
}
- void setTargetOpts(TargetOptions &TargetOpts) {
- this->TargetOpts = &TargetOpts;
+ void setTargetOpts(TargetOptions *TargetOpts) {
+ this->TargetOpts = TargetOpts;
}
///===---- Target Data Type Query Methods -------------------------------===//
@@ -151,6 +136,10 @@ public:
/// typedef void* __builtin_va_list;
VoidPtrBuiltinVaList,
+ /// __builtin_va_list as defind by the AArch64 ABI
+ /// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055a/IHI0055A_aapcs64.pdf
+ AArch64ABIBuiltinVaList,
+
/// __builtin_va_list as defined by the PNaCl ABI:
/// http://www.chromium.org/nativeclient/pnacl/bitcode-abi#TOC-Machine-Types
PNaClABIBuiltinVaList,
@@ -270,6 +259,9 @@ public:
unsigned getLongLongWidth() const { return LongLongWidth; }
unsigned getLongLongAlign() const { return LongLongAlign; }
+ /// \brief Determine whether the __int128 type is supported on this target.
+ bool hasInt128Type() const { return getPointerWidth(0) >= 64; } // FIXME
+
/// \brief Return the alignment that is suitable for storing any
/// object with a fundamental alignment requirement.
unsigned getSuitableAlign() const { return SuitableAlign; }
@@ -335,6 +327,9 @@ public:
return getTypeWidth(IntMaxType);
}
+ // Return the size of unwind_word for this target.
+ unsigned getUnwindWordWidth() const { return getPointerWidth(0); }
+
/// \brief Return the "preferred" register width on this target.
uint64_t getRegisterWidth() const {
// Currently we assume the register width on the target matches the pointer
@@ -518,6 +513,10 @@ public:
bool validateInputConstraint(ConstraintInfo *OutputConstraints,
unsigned NumOutputs,
ConstraintInfo &info) const;
+ virtual bool validateInputSize(StringRef /*Constraint*/,
+ unsigned /*Size*/) const {
+ return true;
+ }
virtual bool validateConstraintModifier(StringRef /*Constraint*/,
const char /*Modifier*/,
unsigned /*Size*/) const {
@@ -572,8 +571,6 @@ public:
/// either; the entire thing is pretty badly mangled.
virtual bool hasProtectedVisibility() const { return true; }
- virtual bool useGlobalsForAutomaticVariables() const { return false; }
-
/// \brief Return the section to use for CFString literals, or 0 if no
/// special section is used.
virtual const char *getCFStringSection() const {
@@ -624,8 +621,8 @@ public:
}
/// \brief Get the C++ ABI currently in use.
- virtual TargetCXXABI getCXXABI() const {
- return CXXABI;
+ TargetCXXABI getCXXABI() const {
+ return TheCXXABI;
}
/// \brief Target the specified CPU.
@@ -645,14 +642,9 @@ public:
/// \brief Use this specified C++ ABI.
///
/// \return False on error (invalid C++ ABI name).
- bool setCXXABI(const std::string &Name) {
- static const TargetCXXABI Unknown = static_cast<TargetCXXABI>(-1);
- TargetCXXABI ABI = llvm::StringSwitch<TargetCXXABI>(Name)
- .Case("arm", CXXABI_ARM)
- .Case("itanium", CXXABI_Itanium)
- .Case("microsoft", CXXABI_Microsoft)
- .Default(Unknown);
- if (ABI == Unknown) return false;
+ bool setCXXABI(llvm::StringRef name) {
+ TargetCXXABI ABI;
+ if (!ABI.tryParse(name)) return false;
return setCXXABI(ABI);
}
@@ -660,7 +652,7 @@ public:
///
/// \return False on error (ABI not valid on this target)
virtual bool setCXXABI(TargetCXXABI ABI) {
- CXXABI = ABI;
+ TheCXXABI = ABI;
return true;
}
@@ -735,13 +727,19 @@ public:
bool isBigEndian() const { return BigEndian; }
+ enum CallingConvMethodType {
+ CCMT_Unknown,
+ CCMT_Member,
+ CCMT_NonMember
+ };
+
/// \brief Gets the default calling convention for the given target and
/// declaration context.
- virtual CallingConv getDefaultCallingConv() const {
+ virtual CallingConv getDefaultCallingConv(CallingConvMethodType MT) const {
// Not all targets will specify an explicit calling convention that we can
// express. This will always do the right thing, even though it's not
// an explicit calling convention.
- return CC_Default;
+ return CC_C;
}
enum CallingConvCheckResult {
diff --git a/include/clang/Basic/TargetOptions.h b/include/clang/Basic/TargetOptions.h
index d6deb0244d9f..c2183fd29d56 100644
--- a/include/clang/Basic/TargetOptions.h
+++ b/include/clang/Basic/TargetOptions.h
@@ -15,6 +15,7 @@
#ifndef LLVM_CLANG_FRONTEND_TARGETOPTIONS_H
#define LLVM_CLANG_FRONTEND_TARGETOPTIONS_H
+#include "clang/Basic/LLVM.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include <string>
#include <vector>
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
index 25e8d5a635c7..a254faef76bb 100644
--- a/include/clang/Basic/TokenKinds.def
+++ b/include/clang/Basic/TokenKinds.def
@@ -121,7 +121,7 @@ TOK(numeric_constant) // 0x123
TOK(char_constant) // 'a'
TOK(wide_char_constant) // L'b'
-// C++0x Character Constants
+// C++11 Character Constants
TOK(utf16_char_constant) // u'a'
TOK(utf32_char_constant) // U'a'
@@ -130,7 +130,7 @@ TOK(string_literal) // "foo"
TOK(wide_string_literal) // L"foo"
TOK(angle_string_literal)// <foo>
-// C++0x String Literals.
+// C++11 String Literals.
TOK(utf8_string_literal) // u8"foo"
TOK(utf16_string_literal)// u"foo"
TOK(utf32_string_literal)// U"foo"
@@ -208,7 +208,7 @@ PUNCTUATOR(greatergreatergreater, ">>>")
// KEYCXX - This is a C++ keyword, or a C++-specific keyword in the
// implementation namespace
// KEYNOCXX - This is a keyword in every non-C++ dialect.
-// KEYCXX0X - This is a C++ keyword introduced to C++ in C++0x
+// KEYCXX11 - This is a C++ keyword introduced to C++ in C++11
// KEYGNU - This is a keyword if GNU extensions are enabled
// KEYMS - This is a keyword if Microsoft extensions are enabled
// KEYNOMS - This is a keyword that must never be enabled under
@@ -260,6 +260,7 @@ KEYWORD(_Bool , KEYNOCXX)
KEYWORD(_Complex , KEYALL)
KEYWORD(_Generic , KEYALL)
KEYWORD(_Imaginary , KEYALL)
+KEYWORD(_Noreturn , KEYALL)
KEYWORD(_Static_assert , KEYALL)
KEYWORD(__func__ , KEYALL)
KEYWORD(__objc_yes , KEYALL)
@@ -311,17 +312,17 @@ CXX_KEYWORD_OPERATOR(or_eq , pipeequal)
CXX_KEYWORD_OPERATOR(xor , caret)
CXX_KEYWORD_OPERATOR(xor_eq , caretequal)
-// C++0x keywords
-KEYWORD(alignas , KEYCXX0X)
-KEYWORD(alignof , KEYCXX0X)
-KEYWORD(char16_t , KEYCXX0X|KEYNOMS)
-KEYWORD(char32_t , KEYCXX0X|KEYNOMS)
-KEYWORD(constexpr , KEYCXX0X)
-KEYWORD(decltype , KEYCXX0X)
-KEYWORD(noexcept , KEYCXX0X)
-KEYWORD(nullptr , KEYCXX0X)
-KEYWORD(static_assert , KEYCXX0X)
-KEYWORD(thread_local , KEYCXX0X)
+// C++11 keywords
+KEYWORD(alignas , KEYCXX11)
+KEYWORD(alignof , KEYCXX11)
+KEYWORD(char16_t , KEYCXX11|KEYNOMS)
+KEYWORD(char32_t , KEYCXX11|KEYNOMS)
+KEYWORD(constexpr , KEYCXX11)
+KEYWORD(decltype , KEYCXX11)
+KEYWORD(noexcept , KEYCXX11)
+KEYWORD(nullptr , KEYCXX11)
+KEYWORD(static_assert , KEYCXX11)
+KEYWORD(thread_local , KEYCXX11)
// GNU Extensions (in impl-reserved namespace)
KEYWORD(_Decimal32 , KEYALL)
@@ -350,31 +351,34 @@ KEYWORD(typeof , KEYGNU)
KEYWORD(L__FUNCTION__ , KEYMS)
// GNU and MS Type Traits
-KEYWORD(__has_nothrow_assign , KEYCXX)
-KEYWORD(__has_nothrow_copy , KEYCXX)
-KEYWORD(__has_nothrow_constructor , KEYCXX)
-KEYWORD(__has_trivial_assign , KEYCXX)
-KEYWORD(__has_trivial_copy , KEYCXX)
-KEYWORD(__has_trivial_constructor , KEYCXX)
-KEYWORD(__has_trivial_destructor , KEYCXX)
-KEYWORD(__has_virtual_destructor , KEYCXX)
-KEYWORD(__is_abstract , KEYCXX)
-KEYWORD(__is_base_of , KEYCXX)
-KEYWORD(__is_class , KEYCXX)
-KEYWORD(__is_convertible_to , KEYCXX)
-KEYWORD(__is_empty , KEYCXX)
-KEYWORD(__is_enum , KEYCXX)
-KEYWORD(__is_final , KEYCXX)
-KEYWORD(__is_interface_class , KEYCXX)
+KEYWORD(__has_nothrow_assign , KEYCXX)
+KEYWORD(__has_nothrow_move_assign , KEYCXX)
+KEYWORD(__has_nothrow_copy , KEYCXX)
+KEYWORD(__has_nothrow_constructor , KEYCXX)
+KEYWORD(__has_trivial_assign , KEYCXX)
+KEYWORD(__has_trivial_move_assign , KEYCXX)
+KEYWORD(__has_trivial_copy , KEYCXX)
+KEYWORD(__has_trivial_constructor , KEYCXX)
+KEYWORD(__has_trivial_move_constructor, KEYCXX)
+KEYWORD(__has_trivial_destructor , KEYCXX)
+KEYWORD(__has_virtual_destructor , KEYCXX)
+KEYWORD(__is_abstract , KEYCXX)
+KEYWORD(__is_base_of , KEYCXX)
+KEYWORD(__is_class , KEYCXX)
+KEYWORD(__is_convertible_to , KEYCXX)
+KEYWORD(__is_empty , KEYCXX)
+KEYWORD(__is_enum , KEYCXX)
+KEYWORD(__is_final , KEYCXX)
+KEYWORD(__is_interface_class , KEYCXX)
// Tentative name - there's no implementation of std::is_literal_type yet.
-KEYWORD(__is_literal , KEYCXX)
+KEYWORD(__is_literal , KEYCXX)
// Name for GCC 4.6 compatibility - people have already written libraries using
// this name unfortunately.
-KEYWORD(__is_literal_type , KEYCXX)
-KEYWORD(__is_pod , KEYCXX)
-KEYWORD(__is_polymorphic , KEYCXX)
-KEYWORD(__is_trivial , KEYCXX)
-KEYWORD(__is_union , KEYCXX)
+KEYWORD(__is_literal_type , KEYCXX)
+KEYWORD(__is_pod , KEYCXX)
+KEYWORD(__is_polymorphic , KEYCXX)
+KEYWORD(__is_trivial , KEYCXX)
+KEYWORD(__is_union , KEYCXX)
// Clang-only C++ Type Traits
KEYWORD(__is_trivially_constructible, KEYCXX)
@@ -448,6 +452,14 @@ ALIAS("read_only", __read_only , KEYOPENCL)
ALIAS("write_only", __write_only , KEYOPENCL)
ALIAS("read_write", __read_write , KEYOPENCL)
KEYWORD(__builtin_astype , KEYOPENCL)
+KEYWORD(image1d_t , KEYOPENCL)
+KEYWORD(image1d_array_t , KEYOPENCL)
+KEYWORD(image1d_buffer_t , KEYOPENCL)
+KEYWORD(image2d_t , KEYOPENCL)
+KEYWORD(image2d_array_t , KEYOPENCL)
+KEYWORD(image3d_t , KEYOPENCL)
+KEYWORD(sampler_t , KEYOPENCL)
+KEYWORD(event_t , KEYOPENCL)
// Borland Extensions.
KEYWORD(__pascal , KEYALL)
@@ -566,7 +578,7 @@ OBJC2_AT_KEYWORD(required)
OBJC2_AT_KEYWORD(optional)
OBJC2_AT_KEYWORD(synthesize)
OBJC2_AT_KEYWORD(dynamic)
-OBJC2_AT_KEYWORD(__experimental_modules_import)
+OBJC2_AT_KEYWORD(import)
// TODO: What to do about context-sensitive keywords like:
// bycopy/byref/in/inout/oneway/out?
@@ -637,6 +649,12 @@ ANNOTATION(pragma_fp_contract)
// handles them.
ANNOTATION(pragma_opencl_extension)
+// Annotations for OpenMP pragma directives - #pragma omp ...
+// The lexer produces these so that they only take effect when the parser
+// handles #pragma omp ... directives.
+ANNOTATION(pragma_openmp)
+ANNOTATION(pragma_openmp_end)
+
#undef ANNOTATION
#undef TESTING_KEYWORD
#undef OBJC2_AT_KEYWORD
diff --git a/include/clang/Basic/TokenKinds.h b/include/clang/Basic/TokenKinds.h
index e850971e34fa..dcbe1da1115d 100644
--- a/include/clang/Basic/TokenKinds.h
+++ b/include/clang/Basic/TokenKinds.h
@@ -68,15 +68,21 @@ inline bool isAnyIdentifier(TokenKind K) {
return (K == tok::identifier) || (K == tok::raw_identifier);
}
+/// \brief Return true if this is a C or C++ string-literal (or
+/// C++11 user-defined-string-literal) token.
+inline bool isStringLiteral(TokenKind K) {
+ return K == tok::string_literal || K == tok::wide_string_literal ||
+ K == tok::utf8_string_literal || K == tok::utf16_string_literal ||
+ K == tok::utf32_string_literal;
+}
+
/// \brief Return true if this is a "literal" kind, like a numeric
/// constant, string, etc.
inline bool isLiteral(TokenKind K) {
- return (K == tok::numeric_constant) || (K == tok::char_constant) ||
- (K == tok::wide_char_constant) || (K == tok::utf16_char_constant) ||
- (K == tok::utf32_char_constant) || (K == tok::string_literal) ||
- (K == tok::wide_string_literal) || (K == tok::utf8_string_literal) ||
- (K == tok::utf16_string_literal) || (K == tok::utf32_string_literal) ||
- (K == tok::angle_string_literal);
+ return K == tok::numeric_constant || K == tok::char_constant ||
+ K == tok::wide_char_constant || K == tok::utf16_char_constant ||
+ K == tok::utf32_char_constant || isStringLiteral(K) ||
+ K == tok::angle_string_literal;
}
/// \brief Return true if this is any of tok::annot_* kinds.
diff --git a/include/clang/Basic/TypeTraits.h b/include/clang/Basic/TypeTraits.h
index 882b52d489ec..16457969862a 100644
--- a/include/clang/Basic/TypeTraits.h
+++ b/include/clang/Basic/TypeTraits.h
@@ -20,11 +20,14 @@ namespace clang {
/// \brief Names for the unary type traits.
enum UnaryTypeTrait {
UTT_HasNothrowAssign,
+ UTT_HasNothrowMoveAssign,
UTT_HasNothrowCopy,
UTT_HasNothrowConstructor,
UTT_HasTrivialAssign,
+ UTT_HasTrivialMoveAssign,
UTT_HasTrivialCopy,
UTT_HasTrivialDefaultConstructor,
+ UTT_HasTrivialMoveConstructor,
UTT_HasTrivialDestructor,
UTT_HasVirtualDestructor,
UTT_IsAbstract,
diff --git a/include/clang/Basic/Version.h b/include/clang/Basic/Version.h
index 3f1b4d83b95e..7db8a2ebf682 100644
--- a/include/clang/Basic/Version.h
+++ b/include/clang/Basic/Version.h
@@ -16,9 +16,8 @@
#ifndef LLVM_CLANG_BASIC_VERSION_H
#define LLVM_CLANG_BASIC_VERSION_H
-#include "llvm/ADT/StringRef.h"
-
#include "clang/Basic/Version.inc"
+#include "llvm/ADT/StringRef.h"
/// \brief Helper macro for CLANG_VERSION_STRING.
#define CLANG_MAKE_VERSION_STRING2(X) #X
diff --git a/include/clang/Basic/VersionTuple.h b/include/clang/Basic/VersionTuple.h
index a94f76c182bb..ff06a5c23d82 100644
--- a/include/clang/Basic/VersionTuple.h
+++ b/include/clang/Basic/VersionTuple.h
@@ -55,16 +55,16 @@ public:
unsigned getMajor() const { return Major; }
/// \brief Retrieve the minor version number, if provided.
- llvm::Optional<unsigned> getMinor() const {
+ Optional<unsigned> getMinor() const {
if (!HasMinor)
- return llvm::Optional<unsigned>();
+ return None;
return Minor;
}
/// \brief Retrieve the subminor version number, if provided.
- llvm::Optional<unsigned> getSubminor() const {
+ Optional<unsigned> getSubminor() const {
if (!HasSubminor)
- return llvm::Optional<unsigned>();
+ return None;
return Subminor;
}
diff --git a/include/clang/Basic/Visibility.h b/include/clang/Basic/Visibility.h
index e81ad91a06c9..b623b94a6787 100644
--- a/include/clang/Basic/Visibility.h
+++ b/include/clang/Basic/Visibility.h
@@ -15,6 +15,8 @@
#ifndef LLVM_CLANG_BASIC_VISIBILITY_H
#define LLVM_CLANG_BASIC_VISIBILITY_H
+#include "clang/Basic/Linkage.h"
+
namespace clang {
/// \brief Describes the different kinds of visibility that a declaration
@@ -46,6 +48,80 @@ inline Visibility minVisibility(Visibility L, Visibility R) {
return L < R ? L : R;
}
+class LinkageInfo {
+ 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) {
+ assert(getLinkage() == L && getVisibility() == V &&
+ isVisibilityExplicit() == E && "Enum truncated!");
+ }
+
+ static LinkageInfo external() {
+ return LinkageInfo();
+ }
+ static LinkageInfo internal() {
+ return LinkageInfo(InternalLinkage, DefaultVisibility, false);
+ }
+ static LinkageInfo uniqueExternal() {
+ return LinkageInfo(UniqueExternalLinkage, DefaultVisibility, false);
+ }
+ static LinkageInfo none() {
+ return LinkageInfo(NoLinkage, DefaultVisibility, false);
+ }
+
+ Linkage getLinkage() const { return (Linkage)linkage_; }
+ Visibility getVisibility() const { return (Visibility)visibility_; }
+ bool isVisibilityExplicit() const { return explicit_; }
+
+ void setLinkage(Linkage L) { linkage_ = L; }
+
+ void mergeLinkage(Linkage L) {
+ setLinkage(minLinkage(getLinkage(), L));
+ }
+ void mergeLinkage(LinkageInfo other) {
+ mergeLinkage(other.getLinkage());
+ }
+
+ /// Merge in the visibility 'newVis'.
+ void mergeVisibility(Visibility newVis, bool newExplicit) {
+ Visibility oldVis = getVisibility();
+
+ // Never increase visibility.
+ if (oldVis < newVis)
+ return;
+
+ // If the new visibility is the same as the old and the new
+ // visibility isn't explicit, we have nothing to add.
+ if (oldVis == newVis && !newExplicit)
+ return;
+
+ // Otherwise, we're either decreasing visibility or making our
+ // existing visibility explicit.
+ setVisibility(newVis, newExplicit);
+ }
+ void mergeVisibility(LinkageInfo other) {
+ mergeVisibility(other.getVisibility(), other.isVisibilityExplicit());
+ }
+
+ /// Merge both linkage and visibility.
+ void merge(LinkageInfo other) {
+ mergeLinkage(other);
+ mergeVisibility(other);
+ }
+
+ /// Merge linkage and conditionally merge visibility.
+ void mergeMaybeWithVisibility(LinkageInfo other, bool withVis) {
+ mergeLinkage(other);
+ if (withVis) mergeVisibility(other);
+ }
+};
}
#endif // LLVM_CLANG_BASIC_VISIBILITY_H
diff --git a/include/clang/CodeGen/ModuleBuilder.h b/include/clang/CodeGen/ModuleBuilder.h
index ba9d1f9305c3..cda7863445cf 100644
--- a/include/clang/CodeGen/ModuleBuilder.h
+++ b/include/clang/CodeGen/ModuleBuilder.h
@@ -26,6 +26,7 @@ namespace clang {
class DiagnosticsEngine;
class LangOptions;
class CodeGenOptions;
+ class TargetOptions;
class CodeGenerator : public ASTConsumer {
virtual void anchor();
@@ -40,6 +41,7 @@ namespace clang {
CodeGenerator *CreateLLVMCodeGen(DiagnosticsEngine &Diags,
const std::string &ModuleName,
const CodeGenOptions &CGO,
+ const TargetOptions &TO,
llvm::LLVMContext& C);
}
diff --git a/include/clang/Driver/Arg.h b/include/clang/Driver/Arg.h
index 3b3829a634a0..662a2e2c618b 100644
--- a/include/clang/Driver/Arg.h
+++ b/include/clang/Driver/Arg.h
@@ -15,9 +15,8 @@
#ifndef CLANG_DRIVER_ARG_H_
#define CLANG_DRIVER_ARG_H_
-#include "clang/Driver/Option.h"
-
#include "Util.h"
+#include "clang/Driver/Option.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include <string>
@@ -52,7 +51,7 @@ namespace driver {
/// ArgList.
unsigned Index;
- /// \brief Was this argument used to effect compilation?
+ /// \brief Was this argument used to affect compilation?
///
/// This is used for generating "argument unused" diagnostics.
mutable unsigned Claimed : 1;
@@ -72,7 +71,7 @@ namespace driver {
const char *Value0, const char *Value1, const Arg *BaseArg = 0);
~Arg();
- const Option getOption() const { return Opt; }
+ Option getOption() const { return Opt; }
StringRef getSpelling() const { return Spelling; }
unsigned getIndex() const { return Index; }
diff --git a/include/clang/Driver/ArgList.h b/include/clang/Driver/ArgList.h
index 72ed7bf58604..3967dcc21d13 100644
--- a/include/clang/Driver/ArgList.h
+++ b/include/clang/Driver/ArgList.h
@@ -11,12 +11,11 @@
#define CLANG_DRIVER_ARGLIST_H_
#include "clang/Basic/LLVM.h"
-#include "clang/Driver/Option.h"
#include "clang/Driver/OptSpecifier.h"
+#include "clang/Driver/Option.h"
#include "clang/Driver/Util.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
-
#include <list>
#include <string>
#include <vector>
@@ -291,6 +290,8 @@ namespace driver {
StringRef RHS) const;
/// @}
+
+ void dump();
};
class InputArgList : public ArgList {
diff --git a/include/clang/Driver/CC1AsOptions.td b/include/clang/Driver/CC1AsOptions.td
index 9fd855a9ce9f..2749bcd7779c 100644
--- a/include/clang/Driver/CC1AsOptions.td
+++ b/include/clang/Driver/CC1AsOptions.td
@@ -37,6 +37,8 @@ def L : Flag<["-"], "L">,
HelpText<"Save temporary labels in the symbol table. "
"Note this may change .s semantics, it should almost never be used "
"on compiler generated code!">;
+def main_file_name : Separate<["-"], "main-file-name">,
+ HelpText<"Main file name to use for debug info">;
//===----------------------------------------------------------------------===//
// Frontend Options
@@ -86,5 +88,11 @@ def fatal_warnings : Flag<["--"], "fatal-warnings">,
def g : Flag<["-"], "g">, HelpText<"Generate source level debug information">;
+def fdebug_compilation_dir : Separate<["-"], "fdebug-compilation-dir">,
+ HelpText<"The compilation directory to embed in the debug info.">;
+
def dwarf_debug_flags : Separate<["-"], "dwarf-debug-flags">,
HelpText<"The string to embed in the Dwarf debug flags record.">;
+
+def dwarf_debug_producer : Separate<["-"], "dwarf-debug-producer">,
+ HelpText<"The string to embed in the Dwarf debug AT_producer record.">;
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index 3ff25494ff53..e4dd34509efe 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -81,15 +81,6 @@ def analyzer_inline_max_stack_depth : Separate<["-"], "analyzer-inline-max-stack
def analyzer_inline_max_stack_depth_EQ : Joined<["-"], "analyzer-inline-max-stack-depth=">,
Alias<analyzer_inline_max_stack_depth>;
-def analyzer_inline_max_function_size : Separate<["-"], "analyzer-inline-max-function-size">,
- HelpText<"Bound on the number of basic blocks in an inlined function (200 by default)">;
-def analyzer_inline_max_function_size_EQ : Joined<["-"], "analyzer-inline-max-function-size=">,
- Alias<analyzer_inline_max_function_size>;
-
-def analyzer_ipa : Separate<["-"], "analyzer-ipa">,
- HelpText<"Specify the inter-procedural analysis mode">;
-def analyzer_ipa_EQ : Joined<["-"], "analyzer-ipa=">, Alias<analyzer_ipa>;
-
def analyzer_inlining_mode : Separate<["-"], "analyzer-inlining-mode">,
HelpText<"Specify the function selection heuristic used during inlining">;
def analyzer_inlining_mode_EQ : Joined<["-"], "analyzer-inlining-mode=">, Alias<analyzer_inlining_mode>;
@@ -97,8 +88,6 @@ def analyzer_inlining_mode_EQ : Joined<["-"], "analyzer-inlining-mode=">, Alias<
def analyzer_disable_retry_exhausted : Flag<["-"], "analyzer-disable-retry-exhausted">,
HelpText<"Do not re-analyze paths leading to exhausted nodes with a different strategy (may decrease code coverage)">;
-def analyzer_max_nodes : Separate<["-"], "analyzer-max-nodes">,
- HelpText<"The maximum number of nodes the analyzer can generate (150000 default, 0 = no limit)">;
def analyzer_max_loop : Separate<["-"], "analyzer-max-loop">,
HelpText<"The maximum number of times the analyzer will go through a loop">;
def analyzer_stats : Flag<["-"], "analyzer-stats">,
@@ -145,6 +134,8 @@ def dwarf_debug_flags : Separate<["-"], "dwarf-debug-flags">,
HelpText<"The string to embed in the Dwarf debug flags record.">;
def dwarf_column_info : Flag<["-"], "dwarf-column-info">,
HelpText<"Turn on column location information.">;
+def split_dwarf : Flag<["-"], "split-dwarf">,
+ HelpText<"Split out the dwarf .dwo sections">;
def fforbid_guard_variables : Flag<["-"], "fforbid-guard-variables">,
HelpText<"Emit an error if a C++ static local initializer would need a guard variable">;
def no_implicit_float : Flag<["-"], "no-implicit-float">,
@@ -158,10 +149,20 @@ def femit_coverage_data: Flag<["-"], "femit-coverage-data">,
def coverage_file : Separate<["-"], "coverage-file">,
HelpText<"Emit coverage data to this filename. The extension will be replaced.">;
def coverage_file_EQ : Joined<["-"], "coverage-file=">, Alias<coverage_file>;
+def coverage_cfg_checksum : Flag<["-"], "coverage-cfg-checksum">,
+ HelpText<"Emit CFG checksum for functions in .gcno files.">;
+def coverage_no_function_names_in_data : Flag<["-"], "coverage-no-function-names-in-data">,
+ HelpText<"Emit function names in .gcda files.">;
+def coverage_version_EQ : Joined<["-"], "coverage-version=">,
+ HelpText<"Four-byte version string for gcov files.">;
+def test_coverage : Flag<["-"], "test-coverage">,
+ HelpText<"Do not generate coverage files or remove coverage changes from IR">;
def fuse_register_sized_bitfield_access: Flag<["-"], "fuse-register-sized-bitfield-access">,
HelpText<"Use register sized accesses to bit-fields, when possible.">;
def relaxed_aliasing : Flag<["-"], "relaxed-aliasing">,
HelpText<"Turn off Type Based Alias Analysis">;
+def struct_path_tbaa : Flag<["-"], "struct-path-tbaa">,
+ HelpText<"Turn on struct-path aware Type Based Alias Analysis">;
def masm_verbose : Flag<["-"], "masm-verbose">,
HelpText<"Generate verbose assembly output">;
def mcode_model : Separate<["-"], "mcode-model">,
@@ -185,6 +186,8 @@ def mlimit_float_precision : Separate<["-"], "mlimit-float-precision">,
HelpText<"Limit float precision to the given value">;
def mno_exec_stack : Flag<["-"], "mnoexecstack">,
HelpText<"Mark the file as not needing an executable stack">;
+def split_stacks : Flag<["-"], "split-stacks">,
+ HelpText<"Try to use a split stack if possible.">;
def mno_zero_initialized_in_bss : Flag<["-"], "mno-zero-initialized-in-bss">,
HelpText<"Do not put zero initialized data in the BSS">;
def backend_option : Separate<["-"], "backend-option">,
@@ -197,8 +200,6 @@ def mrelocation_model : Separate<["-"], "mrelocation-model">,
HelpText<"The relocation model to use">;
def munwind_tables : Flag<["-"], "munwind-tables">,
HelpText<"Generate unwinding tables for all functions">;
-def fuse_init_array : Flag<["-"], "fuse-init-array">,
- HelpText<"Use .init_array instead of .ctors">;
def mconstructor_aliases : Flag<["-"], "mconstructor-aliases">,
HelpText<"Emit complete constructors and destructors as aliases when possible">;
def mlink_bitcode_file : Separate<["-"], "mlink-bitcode-file">,
@@ -217,9 +218,6 @@ def header_include_file : Separate<["-"], "header-include-file">,
// Diagnostic Options
//===----------------------------------------------------------------------===//
-def dump_build_information : Separate<["-"], "dump-build-information">,
- MetaVarName<"<filename>">,
- HelpText<"output a dump of some build information to a file">;
def diagnostic_log_file : Separate<["-"], "diagnostic-log-file">,
HelpText<"Filename (or -) to log diagnostics to">;
def diagnostic_serialized_file : Separate<["-"], "serialize-diagnostic-file">,
@@ -230,6 +228,8 @@ def fdiagnostics_format : Separate<["-"], "fdiagnostics-format">,
HelpText<"Change diagnostic formatting to match IDE and command line tools">;
def fdiagnostics_show_category : Separate<["-"], "fdiagnostics-show-category">,
HelpText<"Print diagnostic category">;
+def fno_diagnostics_use_presumed_location : Flag<["-"], "fno-diagnostics-use-presumed-location">,
+ HelpText<"Ignore #line directives when displaying diagnostic locations">;
def ftabstop : Separate<["-"], "ftabstop">, MetaVarName<"<N>">,
HelpText<"Set the tab stop distance.">;
def ferror_limit : Separate<["-"], "ferror-limit">, MetaVarName<"<N>">,
@@ -245,6 +245,9 @@ def fmessage_length : Separate<["-"], "fmessage-length">, MetaVarName<"<N>">,
def Wno_rewrite_macros : Flag<["-"], "Wno-rewrite-macros">,
HelpText<"Silence ObjC rewriting warnings">;
+def fwarn_on_spellcheck : Flag<["-"], "fwarn-on-spellcheck">,
+ HelpText<"Emit warning if spell-check is initiated, for testing">;
+
//===----------------------------------------------------------------------===//
// Frontend Options
//===----------------------------------------------------------------------===//
@@ -283,8 +286,6 @@ def plugin_arg : JoinedAndSeparate<["-"], "plugin-arg-">,
HelpText<"Pass <arg> to plugin <name>">;
def add_plugin : Separate<["-"], "add-plugin">, MetaVarName<"<name>">,
HelpText<"Use the named plugin action in addition to the default action">;
-def resource_dir : Separate<["-"], "resource-dir">,
- HelpText<"The directory which holds the compiler resource files">;
def version : Flag<["-"], "version">,
HelpText<"Print the compiler version">;
def ast_dump_filter : Separate<["-"], "ast-dump-filter">,
@@ -292,6 +293,8 @@ def ast_dump_filter : Separate<["-"], "ast-dump-filter">,
HelpText<"Use with -ast-dump or -ast-print to dump/print only AST declaration"
" nodes having a certain substring in a qualified name. Use"
" -ast-list to list all filterable declaration node names.">;
+def fno_modules_global_index : Flag<["-"], "fno-modules-global-index">,
+ HelpText<"Do not automatically generate or update the global module index">;
let Group = Action_Group in {
@@ -389,6 +392,8 @@ def fhidden_weak_vtables : Flag<["-"], "fhidden-weak-vtables">,
HelpText<"Generate weak vtables and RTTI with hidden visibility">;
def main_file_name : Separate<["-"], "main-file-name">,
HelpText<"Main file name to use for debug info">;
+def split_dwarf_file : Separate<["-"], "split-dwarf-file">,
+ HelpText<"File name to use for split dwarf debug info output">;
def fno_signed_char : Flag<["-"], "fno-signed-char">,
HelpText<"Char is unsigned">;
def fno_wchar : Flag<["-"], "fno-wchar">,
@@ -425,11 +430,15 @@ def stack_protector : Separate<["-"], "stack-protector">,
def stack_protector_buffer_size : Separate<["-"], "stack-protector-buffer-size">,
HelpText<"Lower bound for a buffer to be considered for stack protection">;
def fvisibility : Separate<["-"], "fvisibility">,
- HelpText<"Default symbol visibility">;
+ HelpText<"Default type and symbol visibility">;
+def ftype_visibility : Separate<["-"], "ftype-visibility">,
+ HelpText<"Default type visibility">;
def ftemplate_depth : Separate<["-"], "ftemplate-depth">,
HelpText<"Maximum depth of recursive template instantiation">;
def fconstexpr_depth : Separate<["-"], "fconstexpr-depth">,
HelpText<"Maximum depth of recursive constexpr function calls">;
+def fbracket_depth : Separate<["-"], "fbracket-depth">,
+ HelpText<"Maximum nesting level for parentheses, brackets, and braces">;
def fconst_strings : Flag<["-"], "fconst-strings">,
HelpText<"Use a const qualified type for string literals in C and ObjC">;
def fno_const_strings : Flag<["-"], "fno-const-strings">,
diff --git a/include/clang/Driver/Compilation.h b/include/clang/Driver/Compilation.h
index 5f63aa768857..15c5e40e495a 100644
--- a/include/clang/Driver/Compilation.h
+++ b/include/clang/Driver/Compilation.h
@@ -20,6 +20,7 @@ namespace driver {
class DerivedArgList;
class Driver;
class InputArgList;
+ class JobAction;
class JobList;
class ToolChain;
@@ -54,11 +55,11 @@ class Compilation {
ArgStringList TempFiles;
/// Result files which should be removed on failure.
- ArgStringList ResultFiles;
+ ArgStringMap ResultFiles;
/// Result files which are generated correctly on failure, and which should
/// only be removed if we crash.
- ArgStringList FailureResultFiles;
+ ArgStringMap FailureResultFiles;
/// Redirection for stdout, stderr, etc.
const llvm::sys::Path **Redirects;
@@ -88,9 +89,9 @@ public:
const ArgStringList &getTempFiles() const { return TempFiles; }
- const ArgStringList &getResultFiles() const { return ResultFiles; }
+ const ArgStringMap &getResultFiles() const { return ResultFiles; }
- const ArgStringList &getFailureResultFiles() const {
+ const ArgStringMap &getFailureResultFiles() const {
return FailureResultFiles;
}
@@ -113,24 +114,40 @@ public:
/// addResultFile - Add a file to remove on failure, and returns its
/// argument.
- const char *addResultFile(const char *Name) {
- ResultFiles.push_back(Name);
+ const char *addResultFile(const char *Name, const JobAction *JA) {
+ ResultFiles[JA] = Name;
return Name;
}
/// addFailureResultFile - Add a file to remove if we crash, and returns its
/// argument.
- const char *addFailureResultFile(const char *Name) {
- FailureResultFiles.push_back(Name);
+ const char *addFailureResultFile(const char *Name, const JobAction *JA) {
+ FailureResultFiles[JA] = Name;
return Name;
}
+ /// CleanupFile - Delete a given file.
+ ///
+ /// \param IssueErrors - Report failures as errors.
+ /// \return Whether the file was removed successfully.
+ bool CleanupFile(const char *File, bool IssueErrors = false) const;
+
/// CleanupFileList - Remove the files in the given list.
///
/// \param IssueErrors - Report failures as errors.
/// \return Whether all files were removed successfully.
bool CleanupFileList(const ArgStringList &Files,
- bool IssueErrors=false) const;
+ bool IssueErrors = false) const;
+
+ /// CleanupFileMap - Remove the files in the given map.
+ ///
+ /// \param JA - If specified, only delete the files associated with this
+ /// JobAction. Otherwise, delete all files in the map.
+ /// \param IssueErrors - Report failures as errors.
+ /// \return Whether all files were removed successfully.
+ bool CleanupFileMap(const ArgStringMap &Files,
+ const JobAction *JA,
+ bool IssueErrors = false) const;
/// PrintJob - Print one job in -### format.
///
@@ -158,10 +175,10 @@ public:
/// ExecuteJob - Execute a single job.
///
- /// \param FailingCommand - For non-zero results, this will be set to the
- /// Command which failed.
- /// \return The accumulated result code of the job.
- int ExecuteJob(const Job &J, const Command *&FailingCommand) const;
+ /// \param FailingCommands - For non-zero results, this will be a vector of
+ /// failing commands and their associated result code.
+ void ExecuteJob(const Job &J,
+ SmallVectorImpl< std::pair<int, const Command *> > &FailingCommands) const;
/// initCompilationForDiagnostics - Remove stale state and suppress output
/// so compilation can be reexecuted to generate additional diagnostic
diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h
index b752ce6a349a..1330e95ac957 100644
--- a/include/clang/Driver/Driver.h
+++ b/include/clang/Driver/Driver.h
@@ -11,11 +11,10 @@
#define CLANG_DRIVER_DRIVER_H_
#include "clang/Basic/Diagnostic.h"
-
+#include "clang/Basic/LLVM.h"
#include "clang/Driver/Phases.h"
#include "clang/Driver/Types.h"
#include "clang/Driver/Util.h"
-
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
@@ -25,9 +24,6 @@
#include <set>
#include <string>
-namespace llvm {
- template<typename T> class ArrayRef;
-}
namespace clang {
namespace driver {
class Action;
@@ -178,7 +174,6 @@ public:
Driver(StringRef _ClangExecutable,
StringRef _DefaultTargetTriple,
StringRef _DefaultImageName,
- bool IsProduction,
DiagnosticsEngine &_Diags);
~Driver();
@@ -277,7 +272,7 @@ public:
/// to just running the subprocesses, for example reporting errors, removing
/// temporary files, etc.
int ExecuteCompilation(const Compilation &C,
- const Command *&FailingCommand) const;
+ SmallVectorImpl< std::pair<int, const Command *> > &FailingCommands) const;
/// generateCompilationDiagnostics - Generate diagnostics information
/// including preprocessed source file(s).
@@ -363,10 +358,9 @@ public:
/// GCC goes to extra lengths here to be a bit more robust.
std::string GetTemporaryPath(StringRef Prefix, const char *Suffix) const;
- /// ShouldUseClangCompilar - Should the clang compiler be used to
+ /// ShouldUseClangCompiler - Should the clang compiler be used to
/// handle this action.
- bool ShouldUseClangCompiler(const Compilation &C, const JobAction &JA,
- const llvm::Triple &ArchName) const;
+ bool ShouldUseClangCompiler(const JobAction &JA) const;
bool IsUsingLTO(const ArgList &Args) const;
diff --git a/include/clang/Driver/Job.h b/include/clang/Driver/Job.h
index 84f5ee19173d..045b5d89ded3 100644
--- a/include/clang/Driver/Job.h
+++ b/include/clang/Driver/Job.h
@@ -10,9 +10,9 @@
#ifndef CLANG_DRIVER_JOB_H_
#define CLANG_DRIVER_JOB_H_
+#include "clang/Basic/LLVM.h"
#include "clang/Driver/Util.h"
#include "llvm/ADT/SmallVector.h"
-#include "clang/Basic/LLVM.h"
namespace clang {
namespace driver {
diff --git a/include/clang/Driver/OptSpecifier.h b/include/clang/Driver/OptSpecifier.h
index bb1cd1740bbb..e683ef325b8e 100644
--- a/include/clang/Driver/OptSpecifier.h
+++ b/include/clang/Driver/OptSpecifier.h
@@ -10,6 +10,8 @@
#ifndef CLANG_DRIVER_OPTSPECIFIER_H
#define CLANG_DRIVER_OPTSPECIFIER_H
+#include "llvm/Support/Compiler.h"
+
namespace clang {
namespace driver {
class Option;
@@ -19,7 +21,7 @@ namespace driver {
unsigned ID;
private:
- explicit OptSpecifier(bool); // DO NOT IMPLEMENT
+ explicit OptSpecifier(bool) LLVM_DELETED_FUNCTION;
public:
OptSpecifier() : ID(0) {}
diff --git a/include/clang/Driver/Option.h b/include/clang/Driver/Option.h
index c3db773cd922..764934fdf810 100644
--- a/include/clang/Driver/Option.h
+++ b/include/clang/Driver/Option.h
@@ -10,10 +10,10 @@
#ifndef CLANG_DRIVER_OPTION_H_
#define CLANG_DRIVER_OPTION_H_
+#include "clang/Basic/LLVM.h"
#include "clang/Driver/OptTable.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ErrorHandling.h"
-#include "clang/Basic/LLVM.h"
namespace clang {
namespace driver {
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index 77ba17a2b4c7..112feb77b1c9 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -152,7 +152,8 @@ def E : Flag<["-"], "E">, Flags<[DriverOption,CC1Option]>, Group<Action_Group>,
HelpText<"Only run the preprocessor">;
def F : JoinedOrSeparate<["-"], "F">, Flags<[RenderJoined,CC1Option]>,
HelpText<"Add directory to framework include search path">;
-def G : Separate<["-"], "G">, Flags<[DriverOption]>;
+def G : JoinedOrSeparate<["-"], "G">, Flags<[DriverOption]>;
+def G_EQ : Joined<["-"], "G=">, Flags<[DriverOption]>;
def H : Flag<["-"], "H">, Flags<[CC1Option]>,
HelpText<"Show header includes and nesting depth">;
def I_ : Flag<["-"], "I-">, Group<I_Group>;
@@ -290,6 +291,7 @@ def faccess_control : Flag<["-"], "faccess-control">, Group<f_Group>;
def fallow_unsupported : Flag<["-"], "fallow-unsupported">, Group<f_Group>;
def faltivec : Flag<["-"], "faltivec">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Enable AltiVec vector initializer syntax">;
+def fno_altivec : Flag<["-"], "fno-altivec">, Group<f_Group>, Flags<[CC1Option]>;
def fapple_kext : Flag<["-"], "fapple-kext">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Use Apple's kernel extensions ABI">;
def fapple_pragma_pack : Flag<["-"], "fapple-pragma-pack">, Group<f_Group>, Flags<[CC1Option]>,
@@ -300,7 +302,7 @@ def fthread_sanitizer : Flag<["-"], "fthread-sanitizer">, Group<f_Group>;
def fno_thread_sanitizer : Flag<["-"], "fno-thread-sanitizer">, Group<f_Group>;
def fasm : Flag<["-"], "fasm">, Group<f_Group>;
-def fasm_blocks : Flag<["-"], "fasm-blocks">, Group<f_Group>;
+def fasm_blocks : Flag<["-"], "fasm-blocks">, Group<f_Group>, Flags<[CC1Option]>;
def fno_asm_blocks : Flag<["-"], "fno-asm-blocks">, Group<f_Group>;
def fassume_sane_operator_new : Flag<["-"], "fassume-sane-operator-new">, Group<f_Group>;
@@ -325,6 +327,9 @@ def fcatch_undefined_behavior : Flag<["-"], "fcatch-undefined-behavior">, Group<
def fclasspath_EQ : Joined<["-"], "fclasspath=">, Group<f_Group>;
def fcolor_diagnostics : Flag<["-"], "fcolor-diagnostics">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Use colors in diagnostics">;
+def fcomment_block_commands : CommaJoined<["-"], "fcomment-block-commands=">, Group<f_clang_Group>, Flags<[CC1Option]>,
+ HelpText<"Treat each comma separated argument in <arg> as a documentation comment block command">,
+ MetaVarName<"<arg>">;
def fcommon : Flag<["-"], "fcommon">, Group<f_Group>;
def fcompile_resource_EQ : Joined<["-"], "fcompile-resource=">, Group<f_Group>;
def fconstant_cfstrings : Flag<["-"], "fconstant-cfstrings">, Group<f_Group>;
@@ -374,6 +379,10 @@ def ferror_limit_EQ : Joined<["-"], "ferror-limit=">, Group<f_Group>;
def fexceptions : Flag<["-"], "fexceptions">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Enable support for exception handling">;
def fextdirs_EQ : Joined<["-"], "fextdirs=">, Group<f_Group>;
+def fextended_identifiers : Flag<["-"], "fextended-identifiers">,
+ Group<clang_ignored_f_Group>;
+def fno_extended_identifiers : Flag<["-"], "fno-extended-identifiers">,
+ Group<f_Group>, Flags<[Unsupported]>;
def fhosted : Flag<["-"], "fhosted">, Group<f_Group>;
def ffast_math : Flag<["-"], "ffast-math">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Enable the *frontend*'s 'fast-math' mode. This has no effect on "
@@ -383,6 +392,7 @@ def fno_fast_math : Flag<["-"], "fno-fast-math">, Group<f_Group>;
def fmath_errno : Flag<["-"], "fmath-errno">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Require math functions to indicate errors by setting errno">;
def fno_math_errno : Flag<["-"], "fno-math-errno">, Group<f_Group>;
+def fbracket_depth_EQ : Joined<["-"], "fbracket-depth=">, Group<f_Group>;
def fsignaling_math : Flag<["-"], "fsignaling-math">, Group<f_Group>;
def fno_signaling_math : Flag<["-"], "fno-signaling-math">, Group<f_Group>;
def fsanitize_EQ : CommaJoined<["-"], "fsanitize=">, Group<f_clang_Group>,
@@ -391,6 +401,32 @@ def fsanitize_EQ : CommaJoined<["-"], "fsanitize=">, Group<f_clang_Group>,
"address (memory errors) | thread (race detection) | "
"undefined (miscellaneous undefined behavior)">;
def fno_sanitize_EQ : CommaJoined<["-"], "fno-sanitize=">, Group<f_clang_Group>;
+def fsanitize_address_zero_base_shadow : Flag<["-"], "fsanitize-address-zero-base-shadow">,
+ Group<f_clang_Group>, Flags<[CC1Option]>,
+ HelpText<"Make AddressSanitizer map shadow memory"
+ "at zero offset">;
+def fno_sanitize_address_zero_base_shadow : Flag<["-"], "fno-sanitize-address-zero-base-shadow">,
+ Group<f_clang_Group>;
+def fsanitize_blacklist : Joined<["-"], "fsanitize-blacklist=">,
+ Group<f_clang_Group>, Flags<[CC1Option]>,
+ HelpText<"Path to blacklist file for sanitizers">;
+def fno_sanitize_blacklist : Flag<["-"], "fno-sanitize-blacklist">,
+ Group<f_clang_Group>,
+ HelpText<"Don't use blacklist file for sanitizers">;
+def fsanitize_memory_track_origins : Flag<["-"], "fsanitize-memory-track-origins">,
+ Group<f_clang_Group>, Flags<[CC1Option]>,
+ HelpText<"Enable origins tracking in MemorySanitizer">;
+def fno_sanitize_memory_track_origins : Flag<["-"], "fno-sanitize-memory-track-origins">,
+ Group<f_clang_Group>;
+def fsanitize_recover : Flag<["-"], "fsanitize-recover">,
+ Group<f_clang_Group>;
+def fno_sanitize_recover : Flag<["-"], "fno-sanitize-recover">,
+ Group<f_clang_Group>, Flags<[CC1Option]>,
+ HelpText<"Disable sanitizer check recovery">;
+def fsanitize_undefined_trap_on_error : Flag<["-"], "fsanitize-undefined-trap-on-error">,
+ Group<f_clang_Group>, Flags<[CC1Option]>;
+def fno_sanitize_undefined_trap_on_error : Flag<["-"], "fno-sanitize-undefined-trap-on-error">,
+ Group<f_clang_Group>;
def funsafe_math_optimizations : Flag<["-"], "funsafe-math-optimizations">,
Group<f_Group>;
def fno_unsafe_math_optimizations : Flag<["-"], "fno-unsafe-math-optimizations">,
@@ -453,8 +489,6 @@ def fmerge_all_constants : Flag<["-"], "fmerge-all-constants">, Group<f_Group>;
def fmessage_length_EQ : Joined<["-"], "fmessage-length=">, Group<f_Group>;
def fms_extensions : Flag<["-"], "fms-extensions">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Accept some non-standard constructs supported by the Microsoft compiler">;
-def fenable_experimental_ms_inline_asm : Flag<["-"], "fenable-experimental-ms-inline-asm">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Enable support for Microsoft style inine assembly">;
def fms_compatibility : Flag<["-"], "fms-compatibility">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Enable Microsoft compatibility mode">;
def fmsc_version : Joined<["-"], "fmsc-version=">, Group<f_Group>, Flags<[CC1Option]>,
@@ -462,11 +496,23 @@ def fmsc_version : Joined<["-"], "fmsc-version=">, Group<f_Group>, Flags<[CC1Opt
def fdelayed_template_parsing : Flag<["-"], "fdelayed-template-parsing">, Group<f_Group>,
HelpText<"Parse templated function definitions at the end of the "
"translation unit ">, Flags<[CC1Option]>;
-def fmodule_cache_path : Separate<["-"], "fmodule-cache-path">, Group<i_Group>,
+def fmodules_cache_path : Joined<["-"], "fmodules-cache-path=">, Group<i_Group>,
Flags<[NoForward,CC1Option]>, MetaVarName<"<directory>">,
HelpText<"Specify the module cache path">;
+def fmodules_prune_interval : Joined<["-"], "fmodules-prune-interval=">, Group<i_Group>,
+ Flags<[CC1Option]>, MetaVarName<"<seconds>">,
+ HelpText<"Specify the interval (in seconds) between attempts to prune the module cache">;
+def fmodules_prune_after : Joined<["-"], "fmodules-prune-after=">, Group<i_Group>,
+ Flags<[CC1Option]>, MetaVarName<"<seconds>">,
+ HelpText<"Specify the interval (in seconds) after which a module file will be considered unused">;
def fmodules : Flag <["-"], "fmodules">, Group<f_Group>, Flags<[NoForward,CC1Option]>,
HelpText<"Enable the 'modules' language feature">;
+def fmodules_autolink : Flag <["-"], "fmodules-autolink">, Group<f_Group>, Flags<[NoForward,CC1Option]>,
+ HelpText<"Enable autolinking of the libraries for imported modules">;
+def fno_modules_autolink : Flag <["-"], "fno-modules-autolink">, Group<f_Group>,
+ HelpText<"Disable autolinking of the libraries for imported modules">;
+def fmodules_ignore_macro : Joined<["-"], "fmodules-ignore-macro=">, Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Ignore the definition of the given macro when building and loading modules">;
def fretain_comments_from_system_headers : Flag<["-"], "fretain-comments-from-system-headers">, Group<f_Group>, Flags<[CC1Option]>;
def fmudflapth : Flag<["-"], "fmudflapth">, Group<f_Group>;
@@ -541,12 +587,15 @@ def fno_spell_checking : Flag<["-"], "fno-spell-checking">, Group<f_Group>,
Flags<[CC1Option]>, HelpText<"Disable spell-checking">;
def fno_stack_protector : Flag<["-"], "fno-stack-protector">, Group<f_Group>;
def fno_strict_aliasing : Flag<["-"], "fno-strict-aliasing">, Group<f_Group>;
+def fstruct_path_tbaa : Flag<["-"], "fstruct-path-tbaa">, Group<f_Group>;
def fno_strict_enums : Flag<["-"], "fno-strict-enums">, Group<f_Group>;
def fno_strict_overflow : Flag<["-"], "fno-strict-overflow">, Group<f_Group>;
def fno_threadsafe_statics : Flag<["-"], "fno-threadsafe-statics">, Group<f_Group>,
Flags<[CC1Option]>, HelpText<"Do not emit code to make initialization of local statics thread safe">;
def fno_use_cxa_atexit : Flag<["-"], "fno-use-cxa-atexit">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Don't use __cxa_atexit for calling destructors">;
+def fno_use_init_array : Flag<["-"], "fno-use-init-array">, Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Don't use .init_array instead of .ctors">;
def fno_unit_at_a_time : Flag<["-"], "fno-unit-at-a-time">, Group<f_Group>;
def fno_unwind_tables : Flag<["-"], "fno-unwind-tables">, Group<f_Group>;
def fno_verbose_asm : Flag<["-"], "fno-verbose-asm">, Group<f_Group>;
@@ -590,7 +639,7 @@ def fno_objc_nonfragile_abi : Flag<["-"], "fno-objc-nonfragile-abi">, Group<f_Gr
def fobjc_sender_dependent_dispatch : Flag<["-"], "fobjc-sender-dependent-dispatch">, Group<f_Group>;
def fobjc : Flag<["-"], "fobjc">, Group<f_Group>;
def fomit_frame_pointer : Flag<["-"], "fomit-frame-pointer">, Group<f_Group>;
-def fopenmp : Flag<["-"], "fopenmp">, Group<f_Group>;
+def fopenmp : Flag<["-"], "fopenmp">, Group<f_Group>, Flags<[CC1Option]>;
def fno_optimize_sibling_calls : Flag<["-"], "fno-optimize-sibling-calls">, Group<f_Group>;
def foptimize_sibling_calls : Flag<["-"], "foptimize-sibling-calls">, Group<f_Group>;
def force__cpusubtype__ALL : Flag<["-"], "force_cpusubtype_ALL">;
@@ -627,6 +676,7 @@ def fshow_source_location : Flag<["-"], "fshow-source-location">, Group<f_Group>
def fspell_checking : Flag<["-"], "fspell-checking">, Group<f_Group>;
def fsigned_bitfields : Flag<["-"], "fsigned-bitfields">, Group<f_Group>;
def fsigned_char : Flag<["-"], "fsigned-char">, Group<f_Group>;
+def fsplit_stack : Flag<["-"], "fsplit-stack">, Group<f_Group>;
def fstack_protector_all : Flag<["-"], "fstack-protector-all">, Group<f_Group>;
def fstack_protector : Flag<["-"], "fstack-protector">, Group<f_Group>;
def fstrict_aliasing : Flag<["-"], "fstrict-aliasing">, Group<f_Group>;
@@ -641,6 +691,16 @@ def ftemplate_depth_ : Joined<["-"], "ftemplate-depth-">, Group<f_Group>;
def ftemplate_backtrace_limit_EQ : Joined<["-"], "ftemplate-backtrace-limit=">,
Group<f_Group>;
def ftest_coverage : Flag<["-"], "ftest-coverage">, Group<f_Group>;
+def fvectorize : Flag<["-"], "fvectorize">, Group<f_Group>,
+ HelpText<"Enable the loop vectorization passes">;
+def fno_vectorize : Flag<["-"], "fno-vectorize">, Group<f_Group>;
+def ftree_vectorize : Flag<["-"], "ftree-vectorize">, Alias<fvectorize>;
+def fno_tree_vectorize : Flag<["-"], "fno-tree-vectorize">, Alias<fno_vectorize>;
+def fslp_vectorize : Flag<["-"], "fslp-vectorize">, Group<f_Group>,
+ HelpText<"Enable the superword-level parallelism vectorization passes">;
+def fno_slp_vectorize : Flag<["-"], "fno-slp-vectorize">, Group<f_Group>;
+def ftree_slp_vectorize : Flag<["-"], "ftree-slp-vectorize">, Alias<fslp_vectorize>;
+def fno_tree_slp_vectorize : Flag<["-"], "fno-tree-slp-vectorize">, Alias<fno_slp_vectorize>;
def Wlarge_by_value_copy_def : Flag<["-"], "Wlarge-by-value-copy">,
HelpText<"Warn if a function definition returns or accepts an object larger "
"in bytes than a given value">, Flags<[HelpHidden]>;
@@ -672,11 +732,17 @@ def funsigned_bitfields : Flag<["-"], "funsigned-bitfields">, Group<f_Group>;
def funsigned_char : Flag<["-"], "funsigned-char">, Group<f_Group>;
def funwind_tables : Flag<["-"], "funwind-tables">, Group<f_Group>;
def fuse_cxa_atexit : Flag<["-"], "fuse-cxa-atexit">, Group<f_Group>;
+def fuse_init_array : Flag<["-"], "fuse-init-array">, Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Use .init_array instead of .ctors">;
def fverbose_asm : Flag<["-"], "fverbose-asm">, Group<f_Group>;
-def fvisibility_EQ : Joined<["-"], "fvisibility=">, Group<f_Group>;
+def fvisibility_EQ : Joined<["-"], "fvisibility=">, Group<f_Group>,
+ HelpText<"Set the default symbol visibility for all global declarations">;
def fvisibility_inlines_hidden : Flag<["-"], "fvisibility-inlines-hidden">, Group<f_Group>,
HelpText<"Give inline C++ member functions default visibility by default">,
Flags<[CC1Option]>;
+def fvisibility_ms_compat : Flag<["-"], "fvisibility-ms-compat">, Group<f_Group>,
+ HelpText<"Give global types 'default' visibility and global functions and "
+ "variables 'hidden' visibility by default">;
def fwrapv : Flag<["-"], "fwrapv">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Treat signed integer overflow as two's complement">;
def fwritable_strings : Flag<["-"], "fwritable-strings">, Group<f_Group>, Flags<[CC1Option]>,
@@ -716,6 +782,7 @@ def gno_record_gcc_switches : Flag<["-"], "gno-record-gcc-switches">,
def gstrict_dwarf : Flag<["-"], "gstrict-dwarf">, Group<g_flags_Group>;
def gno_strict_dwarf : Flag<["-"], "gno-strict-dwarf">, Group<g_flags_Group>;
def gcolumn_info : Flag<["-"], "gcolumn-info">, Group<g_flags_Group>;
+def gsplit_dwarf : Flag<["-"], "gsplit-dwarf">, Group<g_flags_Group>;
def headerpad__max__install__names : Joined<["-"], "headerpad_max_install_names">;
def help : Flag<["-", "--"], "help">, Flags<[CC1Option]>,
HelpText<"Display available options">;
@@ -757,6 +824,8 @@ def keep__private__externs : Flag<["-"], "keep_private_externs">;
def l : JoinedOrSeparate<["-"], "l">, Flags<[LinkerInput, RenderJoined]>;
def lazy__framework : Separate<["-"], "lazy_framework">, Flags<[LinkerInput]>;
def lazy__library : Separate<["-"], "lazy_library">, Flags<[LinkerInput]>;
+def EL : Flag<["-"], "EL">, Flags<[DriverOption]>;
+def EB : Flag<["-"], "EB">, Flags<[DriverOption]>;
def m32 : Flag<["-"], "m32">, Group<m_Group>, Flags<[DriverOption]>;
def mqdsp6_compat : Flag<["-"], "mqdsp6-compat">, Group<m_Group>, Flags<[DriverOption,CC1Option]>,
HelpText<"Enable hexagon-qdsp6 backward compatibility">;
@@ -766,6 +835,15 @@ def m64 : Flag<["-"], "m64">, Group<m_Group>, Flags<[DriverOption]>;
def mabi_EQ : Joined<["-"], "mabi=">, Group<m_Group>;
def march_EQ : Joined<["-"], "march=">, Group<m_Group>;
def maltivec : Flag<["-"], "maltivec">, Alias<faltivec>;
+def mno_altivec : Flag<["-"], "mno-altivec">, Alias<fno_altivec>;
+def mfprnd : Flag<["-"], "mfprnd">, Group<m_Group>;
+def mno_fprnd : Flag<["-"], "mno-fprnd">, Group<m_Group>;
+def mmfcrf : Flag<["-"], "mmfcrf">, Group<m_Group>;
+def mno_mfcrf : Flag<["-"], "mno-mfcrf">, Group<m_Group>;
+def mpopcntd : Flag<["-"], "mpopcntd">, Group<m_Group>;
+def mno_popcntd : Flag<["-"], "mno-popcntd">, Group<m_Group>;
+def mqpx : Flag<["-"], "mqpx">, Group<m_Group>;
+def mno_qpx : Flag<["-"], "mno-qpx">, Group<m_Group>;
def mcmodel_EQ : Joined<["-"], "mcmodel=">, Group<m_Group>;
def mconstant_cfstrings : Flag<["-"], "mconstant-cfstrings">, Group<clang_ignored_m_Group>;
def mcpu_EQ : Joined<["-"], "mcpu=">, Group<m_Group>;
@@ -827,6 +905,8 @@ def mno_fma : Flag<["-"], "mno-fma">, Group<m_x86_Features_Group>;
def mno_xop : Flag<["-"], "mno-xop">, Group<m_x86_Features_Group>;
def mno_f16c : Flag<["-"], "mno-f16c">, Group<m_x86_Features_Group>;
def mno_rtm : Flag<["-"], "mno-rtm">, Group<m_x86_Features_Group>;
+def mno_prfchw : Flag<["-"], "mno-prfchw">, Group<m_x86_Features_Group>;
+def mno_rdseed : Flag<["-"], "mno-rdseed">, Group<m_x86_Features_Group>;
def mno_thumb : Flag<["-"], "mno-thumb">, Group<m_Group>;
def marm : Flag<["-"], "marm">, Alias<mno_thumb>;
@@ -835,6 +915,7 @@ def mno_warn_nonportable_cfstrings : Flag<["-"], "mno-warn-nonportable-cfstrings
def mno_omit_leaf_frame_pointer : Flag<["-"], "mno-omit-leaf-frame-pointer">, Group<m_Group>;
def momit_leaf_frame_pointer : Flag<["-"], "momit-leaf-frame-pointer">, Group<m_Group>,
HelpText<"Omit frame pointer setup for leaf functions">, Flags<[CC1Option]>;
+def moslib_EQ : Joined<["-"], "moslib=">, Group<m_Group>;
def mpascal_strings : Flag<["-"], "mpascal-strings">, Group<m_Group>;
def mred_zone : Flag<["-"], "mred-zone">, Group<m_Group>;
def mregparm_EQ : Joined<["-"], "mregparm=">, Group<m_Group>;
@@ -869,8 +950,12 @@ def mfma : Flag<["-"], "mfma">, Group<m_x86_Features_Group>;
def mxop : Flag<["-"], "mxop">, Group<m_x86_Features_Group>;
def mf16c : Flag<["-"], "mf16c">, Group<m_x86_Features_Group>;
def mrtm : Flag<["-"], "mrtm">, Group<m_x86_Features_Group>;
+def mprfchw : Flag<["-"], "mprfchw">, Group<m_x86_Features_Group>;
+def mrdseed : Flag<["-"], "mrdseed">, Group<m_x86_Features_Group>;
def mips16 : Flag<["-"], "mips16">, Group<m_Group>;
def mno_mips16 : Flag<["-"], "mno-mips16">, Group<m_Group>;
+def mxgot : Flag<["-"], "mxgot">, Group<m_Group>;
+def mno_xgot : Flag<["-"], "mno-xgot">, Group<m_Group>;
def mdsp : Flag<["-"], "mdsp">, Group<m_Group>;
def mno_dsp : Flag<["-"], "mno-dsp">, Group<m_Group>;
def mdspr2 : Flag<["-"], "mdspr2">, Group<m_Group>;
@@ -883,6 +968,7 @@ def mips64 : Flag<["-"], "mips64">, Group<mips_CPUs_Group>,
HelpText<"Equivalent to -march=mips64">, Flags<[HelpHidden]>;
def mips64r2 : Flag<["-"], "mips64r2">, Group<mips_CPUs_Group>,
HelpText<"Equivalent to -march=mips64r2">, Flags<[HelpHidden]>;
+def module_file_info : Flag<["-"], "module-file-info">, Flags<[DriverOption,CC1Option]>, Group<Action_Group>;
def mthumb : Flag<["-"], "mthumb">, Group<m_Group>;
def mtune_EQ : Joined<["-"], "mtune=">, Group<m_Group>;
def multi__module : Flag<["-"], "multi_module">;
@@ -951,6 +1037,11 @@ def rewrite_objc : Flag<["-"], "rewrite-objc">, Flags<[DriverOption,CC1Option]>,
def rewrite_legacy_objc : Flag<["-"], "rewrite-legacy-objc">, Flags<[DriverOption]>,
HelpText<"Rewrite Legacy Objective-C source to C++">;
def rdynamic : Flag<["-"], "rdynamic">;
+def resource_dir : Separate<["-"], "resource-dir">,
+ Flags<[DriverOption, CC1Option, HelpHidden]>,
+ HelpText<"The directory which holds the compiler resource files">;
+def resource_dir_EQ : Joined<["-"], "resource-dir=">, Flags<[DriverOption]>,
+ Alias<resource_dir>;
def rpath : Separate<["-"], "rpath">, Flags<[LinkerInput]>;
def rtlib_EQ : Joined<["-", "--"], "rtlib=">;
def r : Flag<["-"], "r">;
@@ -1100,7 +1191,7 @@ def _output_class_directory_EQ : Joined<["--"], "output-class-directory=">, Alia
def _output_class_directory : Separate<["--"], "output-class-directory">, Alias<foutput_class_dir_EQ>;
def _output_EQ : Joined<["--"], "output=">, Alias<o>;
def _output : Separate<["--"], "output">, Alias<o>;
-def _param : Separate<["--"], "param">;
+def _param : Separate<["--"], "param">, Group<CompileOnly_Group>;
def _param_EQ : Joined<["--"], "param=">, Alias<_param>;
def _prefix_EQ : Joined<["--"], "prefix=">, Alias<B>;
def _prefix : Separate<["--"], "prefix">, Alias<B>;
diff --git a/include/clang/Driver/Phases.h b/include/clang/Driver/Phases.h
index a0c42ea17362..4e0f40c17dff 100644
--- a/include/clang/Driver/Phases.h
+++ b/include/clang/Driver/Phases.h
@@ -23,6 +23,10 @@ namespace phases {
Link
};
+ enum {
+ MaxNumberOfPhases = Link + 1
+ };
+
const char *getPhaseName(ID Id);
} // end namespace phases
diff --git a/include/clang/Driver/Tool.h b/include/clang/Driver/Tool.h
index c62e7567ea3e..4c05d0a743bc 100644
--- a/include/clang/Driver/Tool.h
+++ b/include/clang/Driver/Tool.h
@@ -50,6 +50,7 @@ public:
virtual bool hasIntegratedAssembler() const { return false; }
virtual bool hasIntegratedCPP() const = 0;
virtual bool isLinkJob() const { return false; }
+ virtual bool isDsymutilJob() const { return false; }
/// \brief Does this tool have "good" standardized diagnostics, or should the
/// driver add an additional "command failed" diagnostic on failures.
diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h
index 509e08d67efc..ae9e397644ef 100644
--- a/include/clang/Driver/ToolChain.h
+++ b/include/clang/Driver/ToolChain.h
@@ -10,8 +10,10 @@
#ifndef CLANG_DRIVER_TOOLCHAIN_H_
#define CLANG_DRIVER_TOOLCHAIN_H_
-#include "clang/Driver/Util.h"
+#include "clang/Driver/Action.h"
#include "clang/Driver/Types.h"
+#include "clang/Driver/Util.h"
+#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/Path.h"
@@ -47,6 +49,7 @@ public:
private:
const Driver &D;
const llvm::Triple Triple;
+ const ArgList &Args;
/// The list of toolchain specific path prefixes to search for
/// files.
@@ -56,8 +59,20 @@ private:
/// programs.
path_list ProgramPaths;
+ mutable OwningPtr<Tool> Clang;
+ mutable OwningPtr<Tool> Assemble;
+ mutable OwningPtr<Tool> Link;
+ Tool *getClang() const;
+ Tool *getAssemble() const;
+ Tool *getLink() const;
+ Tool *getClangAs() const;
+
protected:
- ToolChain(const Driver &D, const llvm::Triple &T);
+ ToolChain(const Driver &D, const llvm::Triple &T, const ArgList &Args);
+
+ virtual Tool *buildAssembler() const;
+ virtual Tool *buildLinker() const;
+ virtual Tool *getTool(Action::ActionClass AC) const;
/// \name Utilities for implementing subclasses.
///@{
@@ -111,10 +126,8 @@ public:
return 0;
}
- /// SelectTool - Choose a tool to use to handle the action \p JA with the
- /// given \p Inputs.
- virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
- const ActionList &Inputs) const = 0;
+ /// Choose a tool to use to handle the action \p JA.
+ Tool *SelectTool(const JobAction &JA) const;
// Helper methods
@@ -138,6 +151,9 @@ public:
/// by default.
virtual bool IsIntegratedAssemblerDefault() const { return false; }
+ /// \brief Check if the toolchain should use the integrated assembler.
+ bool useIntegratedAs() const;
+
/// IsStrictAliasingDefault - Does this tool chain use -fstrict-aliasing by
/// default.
virtual bool IsStrictAliasingDefault() const { return true; }
@@ -147,7 +163,7 @@ public:
/// IsObjCDefaultSynthPropertiesDefault - Does this tool chain enable
/// -fobjc-default-synthesize-properties by default.
- virtual bool IsObjCDefaultSynthPropertiesDefault() const { return false; }
+ virtual bool IsObjCDefaultSynthPropertiesDefault() const { return true; }
/// IsEncodeExtendedBlockSignatureDefault - Does this tool chain enable
/// -fencode-extended-block-signature by default.
@@ -233,9 +249,9 @@ public:
virtual void AddClangSystemIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const;
- // addClangTargetOptions - Add options that need to be passed to cc1 for
- // this target.
- virtual void addClangTargetOptions(ArgStringList &CC1Args) const;
+ /// \brief Add options that need to be passed to cc1 for this target.
+ virtual void addClangTargetOptions(const ArgList &DriverArgs,
+ ArgStringList &CC1Args) const;
// GetRuntimeLibType - Determine the runtime library type to use with the
// given compilation arguments.
diff --git a/include/clang/Driver/Types.def b/include/clang/Driver/Types.def
index 318c55ad6366..42f0709cf17a 100644
--- a/include/clang/Driver/Types.def
+++ b/include/clang/Driver/Types.def
@@ -30,7 +30,7 @@
// The fourth value is the suffix to use when creating temporary files
// of this type, or null if unspecified.
-// The fifth value is a string containt option flags. Valid values:
+// The fifth value is a string containing option flags. Valid values:
// a - The type should only be assembled.
// p - The type should only be precompiled.
// u - The type can be user specified (with -x).
@@ -80,6 +80,7 @@ TYPE("lto-bc", LTO_BC, INVALID, "o", "")
// Misc.
TYPE("ast", AST, INVALID, "ast", "u")
+TYPE("pcm", ModuleFile, INVALID, "pcm", "u")
TYPE("plist", Plist, INVALID, "plist", "")
TYPE("rewritten-objc", RewrittenObjC,INVALID, "cpp", "")
TYPE("rewritten-legacy-objc", RewrittenLegacyObjC,INVALID, "cpp", "")
diff --git a/include/clang/Driver/Types.h b/include/clang/Driver/Types.h
index d28ca888d302..18cd2d5102cf 100644
--- a/include/clang/Driver/Types.h
+++ b/include/clang/Driver/Types.h
@@ -11,6 +11,7 @@
#define CLANG_DRIVER_TYPES_H_
#include "clang/Driver/Phases.h"
+#include "llvm/ADT/SmallVector.h"
namespace clang {
namespace driver {
@@ -73,14 +74,12 @@ namespace types {
/// specified type name.
ID lookupTypeForTypeSpecifier(const char *Name);
- /// getNumCompilationPhases - Return the complete number of phases
- /// to be done for this type.
- unsigned getNumCompilationPhases(ID Id);
+ /// getCompilationPhases - Get the list of compilation phases ('Phases') to be
+ /// done for type 'Id'.
+ void getCompilationPhases(
+ ID Id,
+ llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> &Phases);
- /// getCompilationPhase - Return the \p N th compilation phase to
- /// be done for this type.
- phases::ID getCompilationPhase(ID Id, unsigned N);
-
/// lookupCXXTypeForCType - Lookup CXX input type that corresponds to given
/// C type (used for clang++ emulation of g++ behaviour)
ID lookupCXXTypeForCType(ID Id);
diff --git a/include/clang/Driver/Util.h b/include/clang/Driver/Util.h
index 65aef4b31025..06b82b977fe0 100644
--- a/include/clang/Driver/Util.h
+++ b/include/clang/Driver/Util.h
@@ -11,14 +11,19 @@
#define CLANG_DRIVER_UTIL_H_
#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/DenseMap.h"
namespace clang {
namespace driver {
class Action;
+ class JobAction;
/// ArgStringList - Type used for constructing argv lists for subprocesses.
typedef SmallVector<const char*, 16> ArgStringList;
+ /// ArgStringMap - Type used to map a JobAction to its result file.
+ typedef llvm::DenseMap<const JobAction*, const char*> ArgStringMap;
+
/// ActionList - Type used for lists of actions.
typedef SmallVector<Action*, 3> ActionList;
diff --git a/include/clang/Edit/Commit.h b/include/clang/Edit/Commit.h
index aaf6b1838476..48e3d593aa54 100644
--- a/include/clang/Edit/Commit.h
+++ b/include/clang/Edit/Commit.h
@@ -11,12 +11,12 @@
#define LLVM_CLANG_EDIT_COMMIT_H
#include "clang/Edit/FileOffset.h"
-#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
namespace clang {
class LangOptions;
- class PreprocessingRecord;
+ class PPConditionalDirectiveRecord;
namespace edit {
class EditedSource;
@@ -46,7 +46,7 @@ public:
private:
const SourceManager &SourceMgr;
const LangOptions &LangOpts;
- const PreprocessingRecord *PPRec;
+ const PPConditionalDirectiveRecord *PPRec;
EditedSource *Editor;
bool IsCommitable;
@@ -55,7 +55,7 @@ private:
public:
explicit Commit(EditedSource &Editor);
Commit(const SourceManager &SM, const LangOptions &LangOpts,
- const PreprocessingRecord *PPRec = 0)
+ const PPConditionalDirectiveRecord *PPRec = 0)
: SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec), Editor(0),
IsCommitable(true) { }
diff --git a/include/clang/Edit/EditedSource.h b/include/clang/Edit/EditedSource.h
index c685753e4b65..733ad400c934 100644
--- a/include/clang/Edit/EditedSource.h
+++ b/include/clang/Edit/EditedSource.h
@@ -11,14 +11,14 @@
#define LLVM_CLANG_EDIT_EDITEDSOURCE_H
#include "clang/Edit/FileOffset.h"
-#include "llvm/Support/Allocator.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Allocator.h"
#include <map>
namespace clang {
class LangOptions;
- class PreprocessingRecord;
+ class PPConditionalDirectiveRecord;
namespace edit {
class Commit;
@@ -27,7 +27,7 @@ namespace edit {
class EditedSource {
const SourceManager &SourceMgr;
const LangOptions &LangOpts;
- const PreprocessingRecord *PPRec;
+ const PPConditionalDirectiveRecord *PPRec;
struct FileEdit {
StringRef Text;
@@ -45,13 +45,15 @@ class EditedSource {
public:
EditedSource(const SourceManager &SM, const LangOptions &LangOpts,
- const PreprocessingRecord *PPRec = 0)
+ const PPConditionalDirectiveRecord *PPRec = 0)
: SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec),
StrAlloc(/*size=*/512) { }
const SourceManager &getSourceManager() const { return SourceMgr; }
const LangOptions &getLangOpts() const { return LangOpts; }
- const PreprocessingRecord *getPreprocessingRecord() const { return PPRec; }
+ const PPConditionalDirectiveRecord *getPPCondDirectiveRecord() const {
+ return PPRec;
+ }
bool canInsertInOffset(SourceLocation OrigLoc, FileOffset Offs);
diff --git a/include/clang/Edit/Rewriters.h b/include/clang/Edit/Rewriters.h
index aa7a5b232025..292878e75695 100644
--- a/include/clang/Edit/Rewriters.h
+++ b/include/clang/Edit/Rewriters.h
@@ -13,6 +13,7 @@
namespace clang {
class ObjCMessageExpr;
class NSAPI;
+ class ParentMap;
namespace edit {
class Commit;
@@ -21,7 +22,8 @@ bool rewriteObjCRedundantCallWithLiteral(const ObjCMessageExpr *Msg,
const NSAPI &NS, Commit &commit);
bool rewriteToObjCLiteralSyntax(const ObjCMessageExpr *Msg,
- const NSAPI &NS, Commit &commit);
+ const NSAPI &NS, Commit &commit,
+ const ParentMap *PMap);
bool rewriteToObjCSubscriptSyntax(const ObjCMessageExpr *Msg,
const NSAPI &NS, Commit &commit);
diff --git a/include/clang/Format/Format.h b/include/clang/Format/Format.h
new file mode 100644
index 000000000000..d6cc114e3cd1
--- /dev/null
+++ b/include/clang/Format/Format.h
@@ -0,0 +1,131 @@
+//===--- Format.h - Format C++ code -----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Various functions to configurably format source code.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FORMAT_FORMAT_H
+#define LLVM_CLANG_FORMAT_FORMAT_H
+
+#include "clang/Frontend/FrontendAction.h"
+#include "clang/Tooling/Refactoring.h"
+
+namespace clang {
+
+class Lexer;
+class SourceManager;
+class DiagnosticConsumer;
+
+namespace format {
+
+/// \brief The \c FormatStyle is used to configure the formatting to follow
+/// specific guidelines.
+struct FormatStyle {
+ /// \brief The column limit.
+ unsigned ColumnLimit;
+
+ /// \brief The penalty for each character outside of the column limit.
+ unsigned PenaltyExcessCharacter;
+
+ /// \brief The maximum number of consecutive empty lines to keep.
+ unsigned MaxEmptyLinesToKeep;
+
+ /// \brief Set whether & and * bind to the type as opposed to the variable.
+ bool PointerBindsToType;
+
+ /// \brief If \c true, analyze the formatted file for the most common binding.
+ bool DerivePointerBinding;
+
+ /// \brief The extra indent or outdent of access modifiers (e.g.: public:).
+ int AccessModifierOffset;
+
+ enum LanguageStandard {
+ LS_Cpp03,
+ LS_Cpp11,
+ LS_Auto
+ };
+
+ /// \brief Format compatible with this standard, e.g. use \c A<A<int> >
+ /// instead of \c A<A<int>> for LS_Cpp03.
+ LanguageStandard Standard;
+
+ /// \brief If \c true, analyze the formatted file for C++03 compatibility.
+ bool DeriveBackwardsCompatibility;
+
+ /// \brief Indent case labels one level from the switch statement.
+ ///
+ /// When false, use the same indentation level as for the switch statement.
+ /// Switch statement body is always indented one level more than case labels.
+ bool IndentCaseLabels;
+
+ /// \brief The number of spaces to before trailing line comments.
+ unsigned SpacesBeforeTrailingComments;
+
+ /// \brief If false, a function call's or function definition's parameters
+ /// will either all be on the same line or will have one line each.
+ bool BinPackParameters;
+
+ /// \brief Allow putting all parameters of a function declaration onto
+ /// the next line even if \c BinPackParameters is \c false.
+ bool AllowAllParametersOfDeclarationOnNextLine;
+
+ /// \brief Penalty for putting the return type of a function onto its own
+ /// line.
+ unsigned PenaltyReturnTypeOnItsOwnLine;
+
+ /// \brief If the constructor initializers don't fit on a line, put each
+ /// initializer on its own line.
+ bool ConstructorInitializerAllOnOneLineOrOnePerLine;
+
+ /// \brief If true, "if (a) return;" can be put on a single line.
+ bool AllowShortIfStatementsOnASingleLine;
+
+ /// \brief Add a space in front of an Objective-C protocol list, i.e. use
+ /// Foo <Protocol> instead of Foo<Protocol>.
+ bool ObjCSpaceBeforeProtocolList;
+};
+
+/// \brief Returns a format style complying with the LLVM coding standards:
+/// http://llvm.org/docs/CodingStandards.html.
+FormatStyle getLLVMStyle();
+
+/// \brief Returns a format style complying with Google's C++ style guide:
+/// http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml.
+FormatStyle getGoogleStyle();
+
+/// \brief Returns a format style complying with Chromium's style guide:
+/// http://www.chromium.org/developers/coding-style.
+FormatStyle getChromiumStyle();
+
+/// \brief Reformats the given \p Ranges in the token stream coming out of
+/// \c Lex.
+///
+/// Each range is extended on either end to its next bigger logic unit, i.e.
+/// everything that might influence its formatting or might be influenced by its
+/// formatting.
+///
+/// \param DiagClient A custom DiagnosticConsumer. Can be 0, in this case
+/// diagnostic is output to llvm::errs().
+///
+/// Returns the \c Replacements necessary to make all \p Ranges comply with
+/// \p Style.
+tooling::Replacements reformat(const FormatStyle &Style, Lexer &Lex,
+ SourceManager &SourceMgr,
+ std::vector<CharSourceRange> Ranges,
+ DiagnosticConsumer *DiagClient = 0);
+
+/// \brief Returns the \c LangOpts that the formatter expects you to set.
+LangOptions getFormattingLangOpts();
+
+} // end namespace format
+} // end namespace clang
+
+#endif // LLVM_CLANG_FORMAT_FORMAT_H
diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h
index 5e409bd7ed83..02c57d7472a5 100644
--- a/include/clang/Frontend/ASTUnit.h
+++ b/include/clang/Frontend/ASTUnit.h
@@ -14,30 +14,30 @@
#ifndef LLVM_CLANG_FRONTEND_ASTUNIT_H
#define LLVM_CLANG_FRONTEND_ASTUNIT_H
-#include "clang/Serialization/ASTBitCodes.h"
-#include "clang/Sema/Sema.h"
-#include "clang/Sema/CodeCompleteConsumer.h"
-#include "clang/Lex/ModuleLoader.h"
-#include "clang/Lex/PreprocessingRecord.h"
-#include "clang/Lex/HeaderSearchOptions.h"
+#include "clang-c/Index.h"
#include "clang/AST/ASTContext.h"
-#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/SourceManager.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/FileSystemOptions.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetOptions.h"
-#include "clang-c/Index.h"
+#include "clang/Lex/HeaderSearchOptions.h"
+#include "clang/Lex/ModuleLoader.h"
+#include "clang/Lex/PreprocessingRecord.h"
+#include "clang/Sema/CodeCompleteConsumer.h"
+#include "clang/Sema/Sema.h"
+#include "clang/Serialization/ASTBitCodes.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/Path.h"
+#include <cassert>
#include <map>
#include <string>
-#include <vector>
-#include <cassert>
-#include <utility>
#include <sys/types.h>
+#include <utility>
+#include <vector>
namespace llvm {
class MemoryBuffer;
@@ -485,6 +485,9 @@ public:
StringRef getMainFileName() const;
+ /// \brief If this ASTUnit came from an AST file, returns the filename for it.
+ StringRef getASTFileName() const;
+
typedef std::vector<Decl *>::iterator top_level_iterator;
top_level_iterator top_level_begin() {
@@ -830,12 +833,19 @@ public:
/// \returns True if an error occurred, false otherwise.
bool serialize(raw_ostream &OS);
- virtual Module *loadModule(SourceLocation ImportLoc, ModuleIdPath Path,
- Module::NameVisibilityKind Visibility,
- bool IsInclusionDirective) {
+ virtual ModuleLoadResult loadModule(SourceLocation ImportLoc,
+ ModuleIdPath Path,
+ Module::NameVisibilityKind Visibility,
+ bool IsInclusionDirective) {
// ASTUnit doesn't know how to load modules (not that this matters).
- return 0;
+ return ModuleLoadResult();
}
+
+ virtual void makeModuleVisible(Module *Mod,
+ Module::NameVisibilityKind Visibility,
+ SourceLocation ImportLoc,
+ bool Complain) { }
+
};
} // namespace clang
diff --git a/include/clang/Frontend/ChainedIncludesSource.h b/include/clang/Frontend/ChainedIncludesSource.h
index d7119e96536f..e14580ed69b7 100644
--- a/include/clang/Frontend/ChainedIncludesSource.h
+++ b/include/clang/Frontend/ChainedIncludesSource.h
@@ -44,8 +44,8 @@ protected:
virtual uint32_t GetNumExternalSelectors();
virtual Stmt *GetExternalDeclStmt(uint64_t Offset);
virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset);
- virtual DeclContextLookupResult
- FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name);
+ virtual bool FindExternalVisibleDeclsByName(const DeclContext *DC,
+ DeclarationName Name);
virtual ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
bool (*isKindWeWant)(Decl::Kind),
SmallVectorImpl<Decl*> &Result);
diff --git a/include/clang/Frontend/CodeGenOptions.def b/include/clang/Frontend/CodeGenOptions.def
index 558e6f11113b..1c0b9fa99e79 100644
--- a/include/clang/Frontend/CodeGenOptions.def
+++ b/include/clang/Frontend/CodeGenOptions.def
@@ -30,6 +30,8 @@ CODEGENOPT(Name, Bits, Default)
CODEGENOPT(AsmVerbose , 1, 0) ///< -dA, -fverbose-asm.
CODEGENOPT(ObjCAutoRefCountExceptions , 1, 0) ///< Whether ARC should be EH-safe.
+CODEGENOPT(CoverageExtraChecksum, 1, 0) ///< Whether we need a second checksum for functions in GCNO files.
+CODEGENOPT(CoverageNoFunctionNamesInData, 1, 0) ///< Do not include function names in GCDA files.
CODEGENOPT(CUDAIsDevice , 1, 0) ///< Set when compiling for CUDA device.
CODEGENOPT(CXAAtExit , 1, 1) ///< Use __cxa_atexit for calling destructors.
CODEGENOPT(CXXCtorDtorAliases, 1, 0) ///< Emit complete ctors/dtors as linker
@@ -40,6 +42,7 @@ CODEGENOPT(DisableLLVMOpts , 1, 0) ///< Don't run any optimizations, for use i
///< getting .bc files that correspond to the
///< internal state before optimizations are
///< done.
+CODEGENOPT(DisableGCov , 1, 0) ///< Don't run the GCov pass, for testing.
CODEGENOPT(DisableRedZone , 1, 0) ///< Set when -mno-red-zone is enabled.
CODEGENOPT(DisableTailCalls , 1, 0) ///< Do not emit tail calls.
CODEGENOPT(EmitDeclMetadata , 1, 0) ///< Emit special metadata indicating what
@@ -49,6 +52,8 @@ CODEGENOPT(EmitDeclMetadata , 1, 0) ///< Emit special metadata indicating what
CODEGENOPT(EmitGcovArcs , 1, 0) ///< Emit coverage data files, aka. GCDA.
CODEGENOPT(EmitGcovNotes , 1, 0) ///< Emit coverage "notes" files, aka GCNO.
CODEGENOPT(EmitOpenCLArgMetadata , 1, 0) ///< Emit OpenCL kernel arg metadata.
+/// \brief FP_CONTRACT mode (on/off/fast).
+ENUM_CODEGENOPT(FPContractMode, FPContractModeKind, 2, FPC_On)
CODEGENOPT(ForbidGuardVariables , 1, 0) ///< Issue errors if C++ guard variables
///< are required.
CODEGENOPT(FunctionSections , 1, 0) ///< Set when -ffunction-sections is enabled.
@@ -65,6 +70,7 @@ CODEGENOPT(NoDwarf2CFIAsm , 1, 0) ///< Set when -fno-dwarf2-cfi-asm is enable
CODEGENOPT(NoDwarfDirectoryAsm , 1, 0) ///< Set when -fno-dwarf-directory-asm is
///< enabled.
CODEGENOPT(NoExecStack , 1, 0) ///< Set when -Wa,--noexecstack is enabled.
+CODEGENOPT(EnableSegmentedStacks , 1, 0) ///< Set when -fsplit-stack is enabled.
CODEGENOPT(NoGlobalMerge , 1, 0) ///< Set when -mno-global-merge is enabled.
CODEGENOPT(NoImplicitFloat , 1, 0) ///< Set when -mno-implicit-float is enabled.
CODEGENOPT(NoInfsFPMath , 1, 0) ///< Assume FP arguments, results not +-Inf.
@@ -80,7 +86,14 @@ VALUE_CODEGENOPT(OptimizationLevel, 3, 0) ///< The -O[0-4] option specified.
VALUE_CODEGENOPT(OptimizeSize, 2, 0) ///< If -Os (==1) or -Oz (==2) is specified.
CODEGENOPT(RelaxAll , 1, 0) ///< Relax all machine code instructions.
CODEGENOPT(RelaxedAliasing , 1, 0) ///< Set when -fno-strict-aliasing is enabled.
+CODEGENOPT(StructPathTBAA , 1, 0) ///< Whether or not to use struct-path TBAA.
CODEGENOPT(SaveTempLabels , 1, 0) ///< Save temporary labels.
+CODEGENOPT(SanitizeAddressZeroBaseShadow , 1, 0) ///< Map shadow memory at zero
+ ///< offset in AddressSanitizer.
+CODEGENOPT(SanitizeMemoryTrackOrigins, 1, 0) ///< Enable tracking origins in
+ ///< MemorySanitizer
+CODEGENOPT(SanitizeUndefinedTrapOnError, 1, 0) ///< Set on
+ /// -fsanitize-undefined-trap-on-error
CODEGENOPT(SimplifyLibCalls , 1, 1) ///< Set when -fbuiltin is enabled.
CODEGENOPT(SoftFloat , 1, 0) ///< -soft-float.
CODEGENOPT(StrictEnums , 1, 0) ///< Optimize based on strict enum definition.
@@ -107,13 +120,12 @@ VALUE_CODEGENOPT(StackAlignment , 32, 0) ///< Overrides default stack
CODEGENOPT(DebugColumnInfo, 1, 0) ///< Whether or not to use column information
///< in debug info.
+CODEGENOPT(ModulesAutolink, 1, 0) ///< Whether to auto-link imported modules
+
/// The user specified number of registers to be used for integral arguments,
/// or 0 if unspecified.
VALUE_CODEGENOPT(NumRegisterParameters, 32, 0)
-/// The run-time penalty for bounds checking, or 0 to disable.
-VALUE_CODEGENOPT(BoundsChecking, 8, 0)
-
/// The lower bound for a buffer to be considered for stack protection.
VALUE_CODEGENOPT(SSPBufferSize, 32, 0)
@@ -126,6 +138,9 @@ ENUM_CODEGENOPT(Inlining, InliningMethod, 2, NoInlining)
/// The default TLS model to use.
ENUM_CODEGENOPT(DefaultTLSModel, TLSModel, 2, GeneralDynamicTLSModel)
+CODEGENOPT(SanitizeRecover, 1, 1) ///< Attempt to recover from sanitizer checks
+ ///< by continuing execution when possible
+
#undef CODEGENOPT
#undef ENUM_CODEGENOPT
#undef VALUE_CODEGENOPT
diff --git a/include/clang/Frontend/CodeGenOptions.h b/include/clang/Frontend/CodeGenOptions.h
index 35671870f441..d0bbf30918c5 100644
--- a/include/clang/Frontend/CodeGenOptions.h
+++ b/include/clang/Frontend/CodeGenOptions.h
@@ -65,6 +65,12 @@ public:
LocalExecTLSModel
};
+ enum FPContractModeKind {
+ FPC_Off, // Form fused FP ops only where result will not be affected.
+ FPC_On, // Form fused FP ops according to FP_CONTRACT rules.
+ FPC_Fast // Aggressively fuse FP ops (E.g. FMA).
+ };
+
/// The code model to use (-mcmodel).
std::string CodeModel;
@@ -72,6 +78,9 @@ public:
/// replaced.
std::string CoverageFile;
+ /// The version string to put into coverage files.
+ char CoverageVersion[4];
+
/// Enable additional debugging information.
std::string DebugPass;
@@ -96,9 +105,16 @@ public:
/// file, for example with -save-temps.
std::string MainFileName;
+ /// The name for the split debug info file that we'll break out. This is used
+ /// in the backend for setting the name in the skeleton cu.
+ std::string SplitDwarfFile;
+
/// The name of the relocation model to use.
std::string RelocationModel;
+ /// Path to blacklist file for sanitizers.
+ std::string SanitizerBlacklistFile;
+
/// If not an empty string, trap intrinsics are lowered to calls to this
/// function instead of to trap instructions.
std::string TrapFuncName;
@@ -121,6 +137,7 @@ public:
#include "clang/Frontend/CodeGenOptions.def"
RelocationModel = "pic";
+ memcpy(CoverageVersion, "*204", 4);
}
};
diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h
index 2f3dc3f80847..0d674629fd48 100644
--- a/include/clang/Frontend/CompilerInstance.h
+++ b/include/clang/Frontend/CompilerInstance.h
@@ -10,15 +10,15 @@
#ifndef LLVM_CLANG_FRONTEND_COMPILERINSTANCE_H_
#define LLVM_CLANG_FRONTEND_COMPILERINSTANCE_H_
-#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceManager.h"
+#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Lex/ModuleLoader.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/StringRef.h"
#include <cassert>
#include <list>
#include <string>
@@ -94,7 +94,7 @@ class CompilerInstance : public ModuleLoader {
/// \brief The semantic analysis object.
OwningPtr<Sema> TheSema;
-
+
/// \brief The frontend timer
OwningPtr<llvm::Timer> FrontendTimer;
@@ -111,8 +111,15 @@ class CompilerInstance : public ModuleLoader {
/// \brief The result of the last module import.
///
- Module *LastModuleImportResult;
-
+ ModuleLoadResult LastModuleImportResult;
+
+ /// \brief Whether we should (re)build the global module index once we
+ /// have finished with this translation unit.
+ bool BuildGlobalModuleIndex;
+
+ /// \brief One or more modules failed to build.
+ bool ModuleBuildFailed;
+
/// \brief Holds information about the output file.
///
/// If TempFilename is not empty we must rename it to Filename at the end.
@@ -186,6 +193,15 @@ public:
/// setInvocation - Replace the current invocation.
void setInvocation(CompilerInvocation *Value);
+ /// \brief Indicates whether we should (re)build the global module index.
+ bool shouldBuildGlobalModuleIndex() const;
+
+ /// \brief Set the flag indicating whether we should (re)build the global
+ /// module index.
+ void setBuildGlobalModuleIndex(bool Build) {
+ BuildGlobalModuleIndex = Build;
+ }
+
/// }
/// @name Forwarding Methods
/// {
@@ -479,17 +495,12 @@ public:
///
/// \param ShouldCloneClient If Client is non-NULL, specifies whether that
/// client should be cloned.
- void createDiagnostics(int Argc, const char* const *Argv,
- DiagnosticConsumer *Client = 0,
+ void createDiagnostics(DiagnosticConsumer *Client = 0,
bool ShouldOwnClient = true,
bool ShouldCloneClient = true);
/// Create a DiagnosticsEngine object with a the TextDiagnosticPrinter.
///
- /// The \p Argc and \p Argv arguments are used only for logging purposes,
- /// when the diagnostic options indicate that the compiler should output
- /// logging information.
- ///
/// If no diagnostic client is provided, this creates a
/// DiagnosticConsumer that is owned by the returned diagnostic
/// object, if using directly the caller is responsible for
@@ -507,8 +518,7 @@ public:
///
/// \return The new object on success, or null on failure.
static IntrusiveRefCntPtr<DiagnosticsEngine>
- createDiagnostics(DiagnosticOptions *Opts, int Argc,
- const char* const *Argv,
+ createDiagnostics(DiagnosticOptions *Opts,
DiagnosticConsumer *Client = 0,
bool ShouldOwnClient = true,
bool ShouldCloneClient = true,
@@ -542,7 +552,8 @@ public:
bool DisablePCHValidation,
bool AllowPCHWithCompilerErrors,
Preprocessor &PP, ASTContext &Context,
- void *DeserializationListener, bool Preamble);
+ void *DeserializationListener, bool Preamble,
+ bool UseGlobalModuleIndex);
/// Create a code completion consumer using the invocation; note that this
/// will cause the source manager to truncate the input source file at the
@@ -645,9 +656,16 @@ public:
/// }
- virtual Module *loadModule(SourceLocation ImportLoc, ModuleIdPath Path,
- Module::NameVisibilityKind Visibility,
- bool IsInclusionDirective);
+ virtual ModuleLoadResult loadModule(SourceLocation ImportLoc,
+ ModuleIdPath Path,
+ Module::NameVisibilityKind Visibility,
+ bool IsInclusionDirective);
+
+ virtual void makeModuleVisible(Module *Mod,
+ Module::NameVisibilityKind Visibility,
+ SourceLocation ImportLoc,
+ bool Complain);
+
};
} // end namespace clang
diff --git a/include/clang/Frontend/CompilerInvocation.h b/include/clang/Frontend/CompilerInvocation.h
index 1314956c3f47..fac05c55fbb1 100644
--- a/include/clang/Frontend/CompilerInvocation.h
+++ b/include/clang/Frontend/CompilerInvocation.h
@@ -10,22 +10,22 @@
#ifndef LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H_
#define LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H_
+#include "clang/Basic/DiagnosticOptions.h"
+#include "clang/Basic/FileSystemOptions.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/TargetOptions.h"
-#include "clang/Basic/FileSystemOptions.h"
-#include "clang/Basic/DiagnosticOptions.h"
-#include "clang/Lex/HeaderSearchOptions.h"
-#include "clang/Lex/PreprocessorOptions.h"
-#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
-#include "clang/Frontend/MigratorOptions.h"
#include "clang/Frontend/CodeGenOptions.h"
#include "clang/Frontend/DependencyOutputOptions.h"
#include "clang/Frontend/FrontendOptions.h"
#include "clang/Frontend/LangStandard.h"
+#include "clang/Frontend/MigratorOptions.h"
#include "clang/Frontend/PreprocessorOutputOptions.h"
+#include "clang/Lex/HeaderSearchOptions.h"
+#include "clang/Lex/PreprocessorOptions.h"
+#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
#include <string>
#include <vector>
diff --git a/include/clang/Frontend/DiagnosticRenderer.h b/include/clang/Frontend/DiagnosticRenderer.h
index 086bb137d46f..f3cd054045e3 100644
--- a/include/clang/Frontend/DiagnosticRenderer.h
+++ b/include/clang/Frontend/DiagnosticRenderer.h
@@ -19,6 +19,7 @@
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerUnion.h"
namespace clang {
@@ -31,7 +32,8 @@ typedef llvm::PointerUnion<const Diagnostic *,
const StoredDiagnostic *> DiagOrStoredDiag;
/// \brief Class to encapsulate the logic for formatting a diagnostic message.
-/// Actual "printing" logic is implemented by subclasses.
+///
+/// Actual "printing" logic is implemented by subclasses.
///
/// This class provides an interface for building and emitting
/// diagnostic, including all of the macro backtraces, caret diagnostics, FixIt
@@ -55,7 +57,7 @@ protected:
/// \brief The location of the last include whose stack was printed if known.
///
- /// Same restriction as \see LastLoc essentially, but tracking include stack
+ /// Same restriction as LastLoc essentially, but tracking include stack
/// root locations rather than diagnostic locations.
SourceLocation LastIncludeLoc;
@@ -92,7 +94,13 @@ protected:
virtual void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc,
const SourceManager &SM) = 0;
-
+ virtual void emitImportLocation(SourceLocation Loc, PresumedLoc PLoc,
+ StringRef ModuleName,
+ const SourceManager &SM) = 0;
+ virtual void emitBuildingModuleLocation(SourceLocation Loc, PresumedLoc PLoc,
+ StringRef ModuleName,
+ const SourceManager &SM) = 0;
+
virtual void beginDiagnostic(DiagOrStoredDiag D,
DiagnosticsEngine::Level Level) {}
virtual void endDiagnostic(DiagOrStoredDiag D,
@@ -100,16 +108,23 @@ protected:
private:
- void emitIncludeStack(SourceLocation Loc, DiagnosticsEngine::Level Level,
- const SourceManager &SM);
+ void emitIncludeStack(SourceLocation Loc, PresumedLoc PLoc,
+ DiagnosticsEngine::Level Level, const SourceManager &SM);
void emitIncludeStackRecursively(SourceLocation Loc, const SourceManager &SM);
- void emitMacroExpansionsAndCarets(SourceLocation Loc,
- DiagnosticsEngine::Level Level,
- SmallVectorImpl<CharSourceRange>& Ranges,
- ArrayRef<FixItHint> Hints,
- const SourceManager &SM,
- unsigned &MacroDepth,
- unsigned OnMacroInst = 0);
+ void emitImportStack(SourceLocation Loc, const SourceManager &SM);
+ void emitImportStackRecursively(SourceLocation Loc, StringRef ModuleName,
+ const SourceManager &SM);
+ void emitModuleBuildStack(const SourceManager &SM);
+ void emitCaret(SourceLocation Loc, DiagnosticsEngine::Level Level,
+ ArrayRef<CharSourceRange> Ranges, ArrayRef<FixItHint> Hints,
+ const SourceManager &SM);
+ void emitMacroExpansions(SourceLocation Loc,
+ DiagnosticsEngine::Level Level,
+ ArrayRef<CharSourceRange> Ranges,
+ ArrayRef<FixItHint> Hints,
+ const SourceManager &SM,
+ unsigned &MacroDepth,
+ unsigned OnMacroInst = 0);
public:
/// \brief Emit a diagnostic.
///
@@ -149,7 +164,15 @@ public:
virtual void emitIncludeLocation(SourceLocation Loc,
PresumedLoc PLoc,
const SourceManager &SM);
-
+
+ virtual void emitImportLocation(SourceLocation Loc, PresumedLoc PLoc,
+ StringRef ModuleName,
+ const SourceManager &SM);
+
+ virtual void emitBuildingModuleLocation(SourceLocation Loc, PresumedLoc PLoc,
+ StringRef ModuleName,
+ const SourceManager &SM);
+
virtual void emitNote(SourceLocation Loc, StringRef Message,
const SourceManager *SM) = 0;
};
diff --git a/include/clang/Frontend/FrontendAction.h b/include/clang/Frontend/FrontendAction.h
index 328344425c38..c67be924720c 100644
--- a/include/clang/Frontend/FrontendAction.h
+++ b/include/clang/Frontend/FrontendAction.h
@@ -6,6 +6,14 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the clang::FrontendAction interface and various convenience
+/// abstract classes (clang::ASTFrontendAction, clang::PluginASTAction,
+/// clang::PreprocessorFrontendAction, and clang::WrapperFrontendAction)
+/// derived from it.
+///
+//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_FRONTEND_FRONTENDACTION_H
#define LLVM_CLANG_FRONTEND_FRONTENDACTION_H
@@ -13,8 +21,8 @@
#include "clang/Basic/LLVM.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Frontend/FrontendOptions.h"
-#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/StringRef.h"
#include <string>
#include <vector>
@@ -24,8 +32,7 @@ class ASTMergeAction;
class ASTUnit;
class CompilerInstance;
-/// FrontendAction - Abstract base class for actions which can be performed by
-/// the frontend.
+/// Abstract base class for actions which can be performed by the frontend.
class FrontendAction {
FrontendInputFile CurrentInput;
OwningPtr<ASTUnit> CurrentASTUnit;
@@ -41,20 +48,19 @@ protected:
/// @name Implementation Action Interface
/// @{
- /// CreateASTConsumer - Create the AST consumer object for this action, if
- /// supported.
+ /// \brief Create the AST consumer object for this action, if supported.
///
- /// This routine is called as part of \see BeginSourceAction(), which will
+ /// This routine is called as part of BeginSourceFile(), which will
/// fail if the AST consumer cannot be created. This will not be called if the
/// action has indicated that it only uses the preprocessor.
///
- /// \param CI - The current compiler instance, provided as a convenience, \see
+ /// \param CI - The current compiler instance, provided as a convenience, see
/// getCompilerInstance().
///
- /// \param InFile - The current input file, provided as a convenience, \see
+ /// \param InFile - The current input file, provided as a convenience, see
/// getCurrentFile().
///
- /// \return The new AST consumer, or 0 on failure.
+ /// \return The new AST consumer, or null on failure.
virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
StringRef InFile) = 0;
@@ -62,29 +68,29 @@ protected:
/// opportunity to modify the CompilerInvocation or do some other action
/// before BeginSourceFileAction is called.
///
- /// \return True on success; on failure \see BeginSourceFileAction() and
- /// ExecutionAction() and EndSourceFileAction() will not be called.
+ /// \return True on success; on failure BeginSourceFileAction(),
+ /// ExecuteAction() and EndSourceFileAction() will not be called.
virtual bool BeginInvocation(CompilerInstance &CI) { return true; }
- /// BeginSourceFileAction - Callback at the start of processing a single
- /// input.
+ /// \brief Callback at the start of processing a single input.
///
- /// \return True on success; on failure \see ExecutionAction() and
+ /// \return True on success; on failure ExecutionAction() and
/// EndSourceFileAction() will not be called.
virtual bool BeginSourceFileAction(CompilerInstance &CI,
StringRef Filename) {
return true;
}
- /// ExecuteAction - Callback to run the program action, using the initialized
+ /// \brief Callback to run the program action, using the initialized
/// compiler instance.
///
- /// This routine is guaranteed to only be called between \see
- /// BeginSourceFileAction() and \see EndSourceFileAction().
+ /// This is guaranteed to only be called between BeginSourceFileAction()
+ /// and EndSourceFileAction().
virtual void ExecuteAction() = 0;
- /// EndSourceFileAction - Callback at the end of processing a single input;
- /// this is guaranteed to only be called following a successful call to
+ /// \brief Callback at the end of processing a single input.
+ ///
+ /// This is guaranteed to only be called following a successful call to
/// BeginSourceFileAction (and BeginSourceFile).
virtual void EndSourceFileAction() {}
@@ -142,34 +148,35 @@ public:
/// @name Supported Modes
/// @{
- /// usesPreprocessorOnly - Does this action only use the preprocessor? If so
- /// no AST context will be created and this action will be invalid with AST
- /// file inputs.
+ /// \brief Does this action only use the preprocessor?
+ ///
+ /// If so no AST context will be created and this action will be invalid
+ /// with AST file inputs.
virtual bool usesPreprocessorOnly() const = 0;
/// \brief For AST-based actions, the kind of translation unit we're handling.
virtual TranslationUnitKind getTranslationUnitKind() { return TU_Complete; }
- /// hasPCHSupport - Does this action support use with PCH?
+ /// \brief Does this action support use with PCH?
virtual bool hasPCHSupport() const { return !usesPreprocessorOnly(); }
- /// hasASTFileSupport - Does this action support use with AST files?
+ /// \brief Does this action support use with AST files?
virtual bool hasASTFileSupport() const { return !usesPreprocessorOnly(); }
- /// hasIRSupport - Does this action support use with IR files?
+ /// \brief Does this action support use with IR files?
virtual bool hasIRSupport() const { return false; }
- /// hasCodeCompletionSupport - Does this action support use with code
- /// completion?
+ /// \brief Does this action support use with code completion?
virtual bool hasCodeCompletionSupport() const { return false; }
/// @}
/// @name Public Action Interface
/// @{
- /// BeginSourceFile - Prepare the action for processing the input file
- /// \p Input; this is run after the options and frontend have been
- /// initialized, but prior to executing any per-file processing.
+ /// \brief Prepare the action for processing the input file \p Input.
+ ///
+ /// This is run after the options and frontend have been initialized,
+ /// but prior to executing any per-file processing.
///
/// \param CI - The compiler instance this action is being run from. The
/// action may store and use this object up until the matching EndSourceFile
@@ -180,29 +187,28 @@ public:
/// several objects which would normally be owned by the
/// CompilerInstance. When processing AST input files, these objects should
/// generally not be initialized in the CompilerInstance -- they will
- /// automatically be shared with the AST file in between \see
- /// BeginSourceFile() and \see EndSourceFile().
+ /// automatically be shared with the AST file in between
+ /// BeginSourceFile() and EndSourceFile().
///
/// \return True on success; on failure the compilation of this file should
- /// be aborted and neither Execute nor EndSourceFile should be called.
+ /// be aborted and neither Execute() nor EndSourceFile() should be called.
bool BeginSourceFile(CompilerInstance &CI, const FrontendInputFile &Input);
- /// Execute - Set the source managers main input file, and run the action.
+ /// \brief Set the source manager's main input file, and run the action.
bool Execute();
- /// EndSourceFile - Perform any per-file post processing, deallocate per-file
+ /// \brief Perform any per-file post processing, deallocate per-file
/// objects, and run statistics and output file cleanup code.
void EndSourceFile();
/// @}
};
-/// ASTFrontendAction - Abstract base class to use for AST consumer based
-/// frontend actions.
+/// \brief Abstract base class to use for AST consumer-based frontend actions.
class ASTFrontendAction : public FrontendAction {
protected:
- /// ExecuteAction - Implement the ExecuteAction interface by running Sema on
- /// the already initialized AST consumer.
+ /// \brief Implement the ExecuteAction interface by running Sema on
+ /// the already-initialized AST consumer.
///
/// This will also take care of instantiating a code completion consumer if
/// the user requested it and the action supports it.
@@ -219,7 +225,7 @@ protected:
StringRef InFile) = 0;
public:
- /// ParseArgs - Parse the given plugin command line arguments.
+ /// \brief Parse the given plugin command line arguments.
///
/// \param CI - The compiler instance, for use in reporting diagnostics.
/// \return True if the parsing succeeded; otherwise the plugin will be
@@ -229,11 +235,10 @@ public:
const std::vector<std::string> &arg) = 0;
};
-/// PreprocessorFrontendAction - Abstract base class to use for preprocessor
-/// based frontend actions.
+/// \brief Abstract base class to use for preprocessor-based frontend actions.
class PreprocessorFrontendAction : public FrontendAction {
protected:
- /// CreateASTConsumer - Provide a default implementation which returns aborts,
+ /// \brief Provide a default implementation which returns aborts;
/// this method should never be called by FrontendAction clients.
virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
StringRef InFile);
@@ -242,11 +247,12 @@ public:
virtual bool usesPreprocessorOnly() const { return true; }
};
-/// WrapperFrontendAction - A frontend action which simply wraps some other
-/// runtime specified frontend action. Deriving from this class allows an
-/// action to inject custom logic around some existing action's behavior. It
-/// implements every virtual method in the FrontendAction interface by
-/// forwarding to the wrapped action.
+/// \brief A frontend action which simply wraps some other runtime-specified
+/// frontend action.
+///
+/// Deriving from this class allows an action to inject custom logic around
+/// some existing action's behavior. It implements every virtual method in
+/// the FrontendAction interface by forwarding to the wrapped action.
class WrapperFrontendAction : public FrontendAction {
OwningPtr<FrontendAction> WrappedAction;
diff --git a/include/clang/Frontend/FrontendActions.h b/include/clang/Frontend/FrontendActions.h
index 477ac45a9570..178619047a38 100644
--- a/include/clang/Frontend/FrontendActions.h
+++ b/include/clang/Frontend/FrontendActions.h
@@ -123,7 +123,7 @@ public:
std::string &OutputFile,
raw_ostream *&OS);
};
-
+
class SyntaxOnlyAction : public ASTFrontendAction {
protected:
virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
@@ -133,6 +133,21 @@ public:
virtual bool hasCodeCompletionSupport() const { return true; }
};
+/// \brief Dump information about the given module file, to be used for
+/// basic debugging and discovery.
+class DumpModuleInfoAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile);
+ virtual void ExecuteAction();
+
+public:
+ virtual bool hasPCHSupport() const { return false; }
+ virtual bool hasASTFileSupport() const { return true; }
+ virtual bool hasIRSupport() const { return false; }
+ virtual bool hasCodeCompletionSupport() const { return false; }
+};
+
/**
* \brief Frontend action adaptor that merges ASTs together.
*
diff --git a/include/clang/Frontend/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h
index db2f5a5e7159..234e3446c809 100644
--- a/include/clang/Frontend/FrontendOptions.h
+++ b/include/clang/Frontend/FrontendOptions.h
@@ -43,6 +43,7 @@ namespace frontend {
GeneratePCH, ///< Generate pre-compiled header.
GeneratePTH, ///< Generate pre-tokenized header.
InitOnly, ///< Only execute frontend initialization.
+ ModuleFileInfo, ///< Dump information about a module file.
ParseSyntaxOnly, ///< Parse and perform semantic analysis.
PluginAction, ///< Run a plugin action, \see ActionName.
PrintDeclContext, ///< Print DeclContext and their Decls.
@@ -137,6 +138,10 @@ public:
/// speed up parsing in cases you do
/// not need them (e.g. with code
/// completion).
+ unsigned UseGlobalModuleIndex : 1; ///< Whether we can use the
+ ///< global module index if available.
+ unsigned GenerateGlobalModuleIndex : 1; ///< Whether we can generate the
+ ///< global module index if needed.
CodeCompleteOptions CodeCompleteOpts;
@@ -204,20 +209,16 @@ public:
std::string OverrideRecordLayoutsFile;
public:
- FrontendOptions() {
- DisableFree = 0;
- ProgramAction = frontend::ParseSyntaxOnly;
- ActionName = "";
- RelocatablePCH = 0;
- ShowHelp = 0;
- ShowStats = 0;
- ShowTimers = 0;
- ShowVersion = 0;
- ARCMTAction = ARCMT_None;
- ARCMTMigrateEmitARCErrors = 0;
- SkipFunctionBodies = 0;
- ObjCMTAction = ObjCMT_None;
- }
+ FrontendOptions() :
+ DisableFree(false), RelocatablePCH(false), ShowHelp(false),
+ ShowStats(false), ShowTimers(false), ShowVersion(false),
+ FixWhatYouCan(false), FixOnlyWarnings(false), FixAndRecompile(false),
+ FixToTemporaries(false), ARCMTMigrateEmitARCErrors(false),
+ SkipFunctionBodies(false), UseGlobalModuleIndex(true),
+ GenerateGlobalModuleIndex(true),
+ ARCMTAction(ARCMT_None), ObjCMTAction(ObjCMT_None),
+ ProgramAction(frontend::ParseSyntaxOnly)
+ {}
/// getInputKindForExtension - Return the appropriate input kind for a file
/// extension. For example, "c" would return IK_C.
diff --git a/include/clang/Frontend/LangStandard.h b/include/clang/Frontend/LangStandard.h
index f07cb0234bdb..1124d53eafd5 100644
--- a/include/clang/Frontend/LangStandard.h
+++ b/include/clang/Frontend/LangStandard.h
@@ -23,7 +23,7 @@ enum LangFeatures {
C99 = (1 << 2),
C11 = (1 << 3),
CPlusPlus = (1 << 4),
- CPlusPlus0x = (1 << 5),
+ CPlusPlus11 = (1 << 5),
CPlusPlus1y = (1 << 6),
Digraphs = (1 << 7),
GNUMode = (1 << 8),
@@ -69,8 +69,8 @@ public:
/// isCPlusPlus - Language is a C++ variant.
bool isCPlusPlus() const { return Flags & frontend::CPlusPlus; }
- /// isCPlusPlus0x - Language is a C++0x variant.
- bool isCPlusPlus0x() const { return Flags & frontend::CPlusPlus0x; }
+ /// isCPlusPlus11 - Language is a C++0x variant.
+ bool isCPlusPlus11() const { return Flags & frontend::CPlusPlus11; }
/// isCPlusPlus1y - Language is a C++1y variant.
bool isCPlusPlus1y() const { return Flags & frontend::CPlusPlus1y; }
diff --git a/include/clang/Frontend/LangStandards.def b/include/clang/Frontend/LangStandards.def
index 10807b7804b3..7b2516b0e3ef 100644
--- a/include/clang/Frontend/LangStandards.def
+++ b/include/clang/Frontend/LangStandards.def
@@ -96,23 +96,23 @@ LANGSTANDARD(gnucxx98, "gnu++98",
LANGSTANDARD(cxx0x, "c++0x",
"ISO C++ 2011 with amendments",
- LineComment | CPlusPlus | CPlusPlus0x | Digraphs)
+ LineComment | CPlusPlus | CPlusPlus11 | Digraphs)
LANGSTANDARD(cxx11, "c++11",
"ISO C++ 2011 with amendments",
- LineComment | CPlusPlus | CPlusPlus0x | Digraphs)
+ LineComment | CPlusPlus | CPlusPlus11 | Digraphs)
LANGSTANDARD(gnucxx0x, "gnu++0x",
"ISO C++ 2011 with amendments and GNU extensions",
- LineComment | CPlusPlus | CPlusPlus0x | Digraphs | GNUMode)
+ LineComment | CPlusPlus | CPlusPlus11 | Digraphs | GNUMode)
LANGSTANDARD(gnucxx11, "gnu++11",
"ISO C++ 2011 with amendments and GNU extensions",
- LineComment | CPlusPlus | CPlusPlus0x | Digraphs | GNUMode)
+ LineComment | CPlusPlus | CPlusPlus11 | Digraphs | GNUMode)
LANGSTANDARD(cxx1y, "c++1y",
"Working draft for ISO C++ 2014",
- LineComment | CPlusPlus | CPlusPlus0x | CPlusPlus1y | Digraphs)
+ LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus1y | Digraphs)
LANGSTANDARD(gnucxx1y, "gnu++1y",
"Working draft for ISO C++ 2014 with GNU extensions",
- LineComment | CPlusPlus | CPlusPlus0x | CPlusPlus1y | Digraphs |
+ LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus1y | Digraphs |
GNUMode)
// OpenCL
diff --git a/include/clang/Frontend/LayoutOverrideSource.h b/include/clang/Frontend/LayoutOverrideSource.h
index 225efe690bd2..ec34e147650e 100644
--- a/include/clang/Frontend/LayoutOverrideSource.h
+++ b/include/clang/Frontend/LayoutOverrideSource.h
@@ -11,6 +11,7 @@
#define LLVM_CLANG_FRONTEND_LAYOUTOVERRIDESOURCE_H
#include "clang/AST/ExternalASTSource.h"
+#include "clang/Basic/LLVM.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
@@ -31,7 +32,7 @@ namespace clang {
uint64_t Align;
/// \brief The offsets of the fields, in source order.
- llvm::SmallVector<uint64_t, 8> FieldOffsets;
+ SmallVector<uint64_t, 8> FieldOffsets;
};
/// \brief The set of layouts that will be overridden.
@@ -42,7 +43,7 @@ namespace clang {
/// set of record types.
///
/// The file is the result of passing -fdump-record-layouts to a file.
- explicit LayoutOverrideSource(llvm::StringRef Filename);
+ explicit LayoutOverrideSource(StringRef Filename);
/// \brief If this particular record type has an overridden layout,
/// return that layout.
diff --git a/include/clang/Frontend/LogDiagnosticPrinter.h b/include/clang/Frontend/LogDiagnosticPrinter.h
index f4fa876ae392..0c700a7671b6 100644
--- a/include/clang/Frontend/LogDiagnosticPrinter.h
+++ b/include/clang/Frontend/LogDiagnosticPrinter.h
@@ -12,8 +12,8 @@
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
namespace clang {
class DiagnosticOptions;
@@ -42,7 +42,7 @@ class LogDiagnosticPrinter : public DiagnosticConsumer {
raw_ostream &OS;
const LangOptions *LangOpts;
- llvm::IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
+ IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
SourceLocation LastWarningLoc;
FullSourceLoc LastLoc;
diff --git a/include/clang/Frontend/MultiplexConsumer.h b/include/clang/Frontend/MultiplexConsumer.h
index 539f2c5c4df8..6ea7547c7140 100644
--- a/include/clang/Frontend/MultiplexConsumer.h
+++ b/include/clang/Frontend/MultiplexConsumer.h
@@ -17,7 +17,6 @@
#include "clang/Basic/LLVM.h"
#include "clang/Sema/SemaConsumer.h"
-#include "clang/Basic/LLVM.h"
#include "llvm/ADT/OwningPtr.h"
#include <vector>
diff --git a/include/clang/Frontend/PreprocessorOutputOptions.h b/include/clang/Frontend/PreprocessorOutputOptions.h
index 9793aa6fa7ae..e273dd613def 100644
--- a/include/clang/Frontend/PreprocessorOutputOptions.h
+++ b/include/clang/Frontend/PreprocessorOutputOptions.h
@@ -25,7 +25,7 @@ public:
public:
PreprocessorOutputOptions() {
- ShowCPP = 1;
+ ShowCPP = 0;
ShowComments = 0;
ShowLineMarkers = 1;
ShowMacroComments = 0;
diff --git a/include/clang/Frontend/SerializedDiagnosticPrinter.h b/include/clang/Frontend/SerializedDiagnosticPrinter.h
index ab70afd21fc6..117771d15791 100644
--- a/include/clang/Frontend/SerializedDiagnosticPrinter.h
+++ b/include/clang/Frontend/SerializedDiagnosticPrinter.h
@@ -10,6 +10,7 @@
#ifndef LLVM_CLANG_FRONTEND_SERIALIZE_DIAGNOSTIC_PRINTER_H_
#define LLVM_CLANG_FRONTEND_SERIALIZE_DIAGNOSTIC_PRINTER_H_
+#include "clang/Basic/LLVM.h"
#include "llvm/Bitcode/BitstreamWriter.h"
namespace llvm {
@@ -53,7 +54,7 @@ enum RecordIDs {
/// This allows wrapper tools for Clang to get diagnostics from Clang
/// (via libclang) without needing to parse Clang's command line output.
///
-DiagnosticConsumer *create(llvm::raw_ostream *OS,
+DiagnosticConsumer *create(raw_ostream *OS,
DiagnosticOptions *diags);
} // end serialized_diags namespace
diff --git a/include/clang/Frontend/TextDiagnostic.h b/include/clang/Frontend/TextDiagnostic.h
index 51f841ddd3c5..656aa57e6e5a 100644
--- a/include/clang/Frontend/TextDiagnostic.h
+++ b/include/clang/Frontend/TextDiagnostic.h
@@ -18,8 +18,6 @@
#include "clang/Frontend/DiagnosticRenderer.h"
-struct SourceColumnMap;
-
namespace clang {
/// \brief Class to encapsulate the logic for formatting and printing a textual
@@ -103,6 +101,14 @@ protected:
virtual void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc,
const SourceManager &SM);
+ virtual void emitImportLocation(SourceLocation Loc, PresumedLoc PLoc,
+ StringRef ModuleName,
+ const SourceManager &SM);
+
+ virtual void emitBuildingModuleLocation(SourceLocation Loc, PresumedLoc PLoc,
+ StringRef ModuleName,
+ const SourceManager &SM);
+
private:
void emitSnippetAndCaret(SourceLocation Loc, DiagnosticsEngine::Level Level,
SmallVectorImpl<CharSourceRange>& Ranges,
@@ -111,16 +117,6 @@ private:
void emitSnippet(StringRef SourceLine);
- void highlightRange(const CharSourceRange &R,
- unsigned LineNo, FileID FID,
- const SourceColumnMap &map,
- std::string &CaretLine,
- const SourceManager &SM);
-
- std::string buildFixItInsertionLine(unsigned LineNo,
- const SourceColumnMap &map,
- ArrayRef<FixItHint> Hints,
- const SourceManager &SM);
void emitParseableFixits(ArrayRef<FixItHint> Hints, const SourceManager &SM);
};
diff --git a/include/clang/Frontend/TextDiagnosticPrinter.h b/include/clang/Frontend/TextDiagnosticPrinter.h
index 91ac3c833942..470438e7bd9a 100644
--- a/include/clang/Frontend/TextDiagnosticPrinter.h
+++ b/include/clang/Frontend/TextDiagnosticPrinter.h
@@ -17,8 +17,8 @@
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/OwningPtr.h"
namespace clang {
class DiagnosticOptions;
@@ -27,7 +27,7 @@ class TextDiagnostic;
class TextDiagnosticPrinter : public DiagnosticConsumer {
raw_ostream &OS;
- llvm::IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
+ IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
/// \brief Handle to the currently active text diagnostic emitter.
OwningPtr<TextDiagnostic> TextDiag;
diff --git a/include/clang/Frontend/Utils.h b/include/clang/Frontend/Utils.h
index 6b1fc630e234..8830dced3cc2 100644
--- a/include/clang/Frontend/Utils.h
+++ b/include/clang/Frontend/Utils.h
@@ -60,7 +60,8 @@ void InitializePreprocessor(Preprocessor &PP,
/// ProcessWarningOptions - Initialize the diagnostic client and process the
/// warning options specified on the command line.
void ProcessWarningOptions(DiagnosticsEngine &Diags,
- const DiagnosticOptions &Opts);
+ const DiagnosticOptions &Opts,
+ bool ReportDiags = true);
/// DoPrintPreprocessedInput - Implement -E mode.
void DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream* OS,
diff --git a/include/clang/Lex/DirectoryLookup.h b/include/clang/Lex/DirectoryLookup.h
index d773fc6fb15f..261dfabc0fd2 100644
--- a/include/clang/Lex/DirectoryLookup.h
+++ b/include/clang/Lex/DirectoryLookup.h
@@ -50,34 +50,34 @@ private:
/// SrcMgr::CharacteristicKind.
unsigned DirCharacteristic : 2;
- /// UserSupplied - True if this is a user-supplied directory.
- ///
- bool UserSupplied : 1;
-
/// LookupType - This indicates whether this DirectoryLookup object is a
/// normal directory, a framework, or a headermap.
unsigned LookupType : 2;
/// \brief Whether this is a header map used when building a framework.
unsigned IsIndexHeaderMap : 1;
+
+ /// \brief Whether we've performed an exhaustive search for module maps
+ /// within the subdirectories of this directory.
+ unsigned SearchedAllModuleMaps : 1;
public:
/// DirectoryLookup ctor - Note that this ctor *does not take ownership* of
/// 'dir'.
DirectoryLookup(const DirectoryEntry *dir, SrcMgr::CharacteristicKind DT,
- bool isUser, bool isFramework)
- : DirCharacteristic(DT), UserSupplied(isUser),
+ bool isFramework)
+ : DirCharacteristic(DT),
LookupType(isFramework ? LT_Framework : LT_NormalDir),
- IsIndexHeaderMap(false) {
+ IsIndexHeaderMap(false), SearchedAllModuleMaps(false) {
u.Dir = dir;
}
/// DirectoryLookup ctor - Note that this ctor *does not take ownership* of
/// 'map'.
DirectoryLookup(const HeaderMap *map, SrcMgr::CharacteristicKind DT,
- bool isUser, bool isIndexHeaderMap)
- : DirCharacteristic(DT), UserSupplied(isUser), LookupType(LT_HeaderMap),
- IsIndexHeaderMap(isIndexHeaderMap) {
+ bool isIndexHeaderMap)
+ : DirCharacteristic(DT), LookupType(LT_HeaderMap),
+ IsIndexHeaderMap(isIndexHeaderMap), SearchedAllModuleMaps(false) {
u.Map = map;
}
@@ -113,16 +113,22 @@ public:
/// isHeaderMap - Return true if this is a header map, not a normal directory.
bool isHeaderMap() const { return getLookupType() == LT_HeaderMap; }
+ /// \brief Determine whether we have already searched this entire
+ /// directory for module maps.
+ bool haveSearchedAllModuleMaps() const { return SearchedAllModuleMaps; }
+
+ /// \brief Specify whether we have already searched all of the subdirectories
+ /// for module maps.
+ void setSearchedAllModuleMaps(bool SAMM) {
+ SearchedAllModuleMaps = SAMM;
+ }
+
/// DirCharacteristic - The type of directory this is, one of the DirType enum
/// values.
SrcMgr::CharacteristicKind getDirCharacteristic() const {
return (SrcMgr::CharacteristicKind)DirCharacteristic;
}
- /// isUserSupplied - True if this is a user-supplied directory.
- ///
- bool isUserSupplied() const { return UserSupplied; }
-
/// \brief Whether this header map is building a framework or not.
bool isIndexHeaderMap() const {
return isHeaderMap() && IsIndexHeaderMap;
diff --git a/include/clang/Lex/ExternalPreprocessorSource.h b/include/clang/Lex/ExternalPreprocessorSource.h
index d2e2412192ed..d9a4de4d9981 100644
--- a/include/clang/Lex/ExternalPreprocessorSource.h
+++ b/include/clang/Lex/ExternalPreprocessorSource.h
@@ -15,7 +15,9 @@
#define LLVM_CLANG_LEX_EXTERNAL_PREPROCESSOR_SOURCE_H
namespace clang {
-
+
+class IdentifierInfo;
+
/// \brief Abstract interface for external sources of preprocessor
/// information.
///
diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h
index 4334db771c85..8a5a798560de 100644
--- a/include/clang/Lex/HeaderSearch.h
+++ b/include/clang/Lex/HeaderSearch.h
@@ -18,10 +18,10 @@
#include "clang/Lex/ModuleMap.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/Allocator.h"
-#include "llvm/ADT/OwningPtr.h"
#include <vector>
namespace clang {
@@ -50,6 +50,9 @@ struct HeaderFileInfo {
/// \brief Whether this header file info was supplied by an external source.
unsigned External : 1;
+
+ /// \brief Whether this header is part of a module.
+ unsigned isModuleHeader : 1;
/// \brief Whether this structure is considered to already have been
/// "resolved", meaning that it was loaded from the external source.
@@ -90,7 +93,8 @@ struct HeaderFileInfo {
HeaderFileInfo()
: isImport(false), isPragmaOnce(false), DirInfo(SrcMgr::C_User),
- External(false), Resolved(false), IndexHeaderMapHeader(false),
+ External(false), isModuleHeader(false), Resolved(false),
+ IndexHeaderMapHeader(false),
NumIncludes(0), ControllingMacroID(0), ControllingMacro(0) {}
/// \brief Retrieve the controlling macro for this header file, if
@@ -134,7 +138,7 @@ class HeaderSearch {
};
/// \brief Header-search options used to initialize this header search.
- llvm::IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts;
+ IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts;
FileManager &FileMgr;
/// \#include search path information. Requests for \#include "x" search the
@@ -189,7 +193,7 @@ class HeaderSearch {
std::vector<std::pair<const FileEntry*, const HeaderMap*> > HeaderMaps;
/// \brief The mapping between modules and headers.
- ModuleMap ModMap;
+ mutable ModuleMap ModMap;
/// \brief Describes whether a given directory has a module map in it.
llvm::DenseMap<const DirectoryEntry *, bool> DirectoryHasModuleMap;
@@ -217,7 +221,7 @@ class HeaderSearch {
friend class DirectoryLookup;
public:
- HeaderSearch(llvm::IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts,
+ HeaderSearch(IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts,
FileManager &FM, DiagnosticsEngine &Diags,
const LangOptions &LangOpts, const TargetInfo *Target);
~HeaderSearch();
@@ -363,7 +367,8 @@ public:
StringRef Filename,
const FileEntry *RelativeFileEnt,
SmallVectorImpl<char> *SearchPath,
- SmallVectorImpl<char> *RelativePath);
+ SmallVectorImpl<char> *RelativePath,
+ Module **SuggestedModule);
/// \brief Look up the specified framework name in our framework cache.
/// \returns The DirectoryEntry it is in if we know, null otherwise.
@@ -399,6 +404,9 @@ public:
getFileInfo(File).DirInfo = SrcMgr::C_System;
}
+ /// \brief Mark the specified file as part of a module.
+ void MarkFileModuleHeader(const FileEntry *File);
+
/// \brief Increment the count for the number of times the specified
/// FileEntry has been entered.
void IncrementIncludeCount(const FileEntry *File) {
@@ -468,7 +476,7 @@ public:
/// \brief Retrieve the module that corresponds to the given file, if any.
///
/// \param File The header that we wish to map to a module.
- Module *findModuleForHeader(const FileEntry *File);
+ Module *findModuleForHeader(const FileEntry *File) const;
/// \brief Read the contents of the given module map file.
///
@@ -480,7 +488,7 @@ public:
/// \brief Collect the set of all known, top-level modules.
///
/// \param Modules Will be filled with the set of known, top-level modules.
- void collectAllModules(llvm::SmallVectorImpl<Module *> &Modules);
+ void collectAllModules(SmallVectorImpl<Module *> &Modules);
private:
/// \brief Retrieve a module with the given name, which may be part of the
@@ -497,7 +505,11 @@ private:
Module *loadFrameworkModule(StringRef Name,
const DirectoryEntry *Dir,
bool IsSystem);
-
+
+ /// \brief Load all of the module maps within the immediate subdirectories
+ /// of the given search directory.
+ void loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir);
+
public:
/// \brief Retrieve the module map.
ModuleMap &getModuleMap() { return ModMap; }
diff --git a/include/clang/Lex/HeaderSearchOptions.h b/include/clang/Lex/HeaderSearchOptions.h
index 468fefa4aba3..afce5ba18b3b 100644
--- a/include/clang/Lex/HeaderSearchOptions.h
+++ b/include/clang/Lex/HeaderSearchOptions.h
@@ -10,8 +10,11 @@
#ifndef LLVM_CLANG_LEX_HEADERSEARCHOPTIONS_H
#define LLVM_CLANG_LEX_HEADERSEARCHOPTIONS_H
+#include "clang/Basic/LLVM.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/StringRef.h"
+#include <string>
#include <vector>
namespace clang {
@@ -27,6 +30,8 @@ namespace frontend {
IndexHeaderMap, ///< Like Angled, but marks header maps used when
/// building frameworks.
System, ///< Like Angled, but marks system directories.
+ ExternCSystem, ///< Like System, but headers are implicitly wrapped in
+ /// extern "C".
CSystem, ///< Like System, but only used for C.
CXXSystem, ///< Like System, but only used for C++.
ObjCSystem, ///< Like System, but only used for ObjC.
@@ -37,12 +42,11 @@ namespace frontend {
/// HeaderSearchOptions - Helper class for storing options related to the
/// initialization of the HeaderSearch object.
-class HeaderSearchOptions : public llvm::RefCountedBase<HeaderSearchOptions> {
+class HeaderSearchOptions : public RefCountedBase<HeaderSearchOptions> {
public:
struct Entry {
std::string Path;
frontend::IncludeDirGroup Group;
- unsigned IsUserSupplied : 1;
unsigned IsFramework : 1;
/// IgnoreSysRoot - This is false if an absolute path should be treated
@@ -50,24 +54,10 @@ public:
/// path.
unsigned IgnoreSysRoot : 1;
- /// \brief True if this entry is an internal search path.
- ///
- /// This typically indicates that users didn't directly provide it, but
- /// instead it was provided by a compatibility layer for a particular
- /// system. This isn't redundant with IsUserSupplied (even though perhaps
- /// it should be) because that is false for user provided '-iwithprefix'
- /// header search entries.
- unsigned IsInternal : 1;
-
- /// \brief True if this entry's headers should be wrapped in extern "C".
- unsigned ImplicitExternC : 1;
-
- Entry(StringRef path, frontend::IncludeDirGroup group,
- bool isUserSupplied, bool isFramework, bool ignoreSysRoot,
- bool isInternal, bool implicitExternC)
- : Path(path), Group(group), IsUserSupplied(isUserSupplied),
- IsFramework(isFramework), IgnoreSysRoot(ignoreSysRoot),
- IsInternal(isInternal), ImplicitExternC(implicitExternC) {}
+ Entry(StringRef path, frontend::IncludeDirGroup group, bool isFramework,
+ bool ignoreSysRoot)
+ : Path(path), Group(group), IsFramework(isFramework),
+ IgnoreSysRoot(ignoreSysRoot) {}
};
struct SystemHeaderPrefix {
@@ -98,13 +88,35 @@ public:
/// \brief The directory used for the module cache.
std::string ModuleCachePath;
-
+
/// \brief Whether we should disable the use of the hash string within the
/// module cache.
///
/// Note: Only used for testing!
unsigned DisableModuleHash : 1;
-
+
+ /// \brief The interval (in seconds) between pruning operations.
+ ///
+ /// This operation is expensive, because it requires Clang to walk through
+ /// the directory structure of the module cache, stat()'ing and removing
+ /// files.
+ ///
+ /// The default value is large, e.g., the operation runs once a week.
+ unsigned ModuleCachePruneInterval;
+
+ /// \brief The time (in seconds) after which an unused module file will be
+ /// considered unused and will, therefore, be pruned.
+ ///
+ /// When the module cache is pruned, any module file that has not been
+ /// accessed in this many seconds will be removed. The default value is
+ /// large, e.g., a month, to avoid forcing infrequently-used modules to be
+ /// regenerated often.
+ unsigned ModuleCachePruneAfter;
+
+ /// \brief The set of macro names that should be ignored for the purposes
+ /// of computing the module hash.
+ llvm::SetVector<std::string> ModulesIgnoreMacros;
+
/// Include the compiler builtin includes.
unsigned UseBuiltinIncludes : 1;
@@ -122,16 +134,17 @@ public:
public:
HeaderSearchOptions(StringRef _Sysroot = "/")
- : Sysroot(_Sysroot), DisableModuleHash(0), UseBuiltinIncludes(true),
+ : Sysroot(_Sysroot), DisableModuleHash(0),
+ ModuleCachePruneInterval(7*24*60*60),
+ ModuleCachePruneAfter(31*24*60*60),
+ UseBuiltinIncludes(true),
UseStandardSystemIncludes(true), UseStandardCXXIncludes(true),
UseLibcxx(false), Verbose(false) {}
/// AddPath - Add the \p Path path to the specified \p Group list.
void AddPath(StringRef Path, frontend::IncludeDirGroup Group,
- bool IsUserSupplied, bool IsFramework, bool IgnoreSysRoot,
- bool IsInternal = false, bool ImplicitExternC = false) {
- UserEntries.push_back(Entry(Path, Group, IsUserSupplied, IsFramework,
- IgnoreSysRoot, IsInternal, ImplicitExternC));
+ bool IsFramework, bool IgnoreSysRoot) {
+ UserEntries.push_back(Entry(Path, Group, IsFramework, IgnoreSysRoot));
}
/// AddSystemHeaderPrefix - Override whether \#include directives naming a
diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h
index 407b644fd74c..cb4f57fb9cf4 100644
--- a/include/clang/Lex/Lexer.h
+++ b/include/clang/Lex/Lexer.h
@@ -14,11 +14,11 @@
#ifndef LLVM_CLANG_LEXER_H
#define LLVM_CLANG_LEXER_H
-#include "clang/Lex/PreprocessorLexer.h"
#include "clang/Basic/LangOptions.h"
+#include "clang/Lex/PreprocessorLexer.h"
#include "llvm/ADT/SmallVector.h"
-#include <string>
#include <cassert>
+#include <string>
namespace clang {
class DiagnosticsEngine;
@@ -174,8 +174,8 @@ public:
/// SetKeepWhitespaceMode - This method lets clients enable or disable
/// whitespace retention mode.
void SetKeepWhitespaceMode(bool Val) {
- assert((!Val || LexingRawMode) &&
- "Can only enable whitespace retention in raw mode");
+ assert((!Val || LexingRawMode || LangOpts.TraditionalCPP) &&
+ "Can only retain whitespace in raw mode or -traditional-cpp");
ExtendedTokenMode = Val ? 2 : 0;
}
@@ -194,6 +194,14 @@ public:
ExtendedTokenMode = Mode ? 1 : 0;
}
+ /// Sets the extended token mode back to its initial value, according to the
+ /// language options and preprocessor. This controls whether the lexer
+ /// produces comment and whitespace tokens.
+ ///
+ /// This requires the lexer to have an associated preprocessor. A standalone
+ /// lexer has nothing to reset to.
+ void resetExtendedTokenMode();
+
const char *getBufferStart() const { return BufferStart; }
/// ReadToEndOfLine - Read the rest of the current preprocessor line as an
@@ -260,10 +268,10 @@ public:
/// location and does not jump to the expansion or spelling
/// location.
static StringRef getSpelling(SourceLocation loc,
- SmallVectorImpl<char> &buffer,
- const SourceManager &SourceMgr,
- const LangOptions &LangOpts,
- bool *invalid = 0);
+ SmallVectorImpl<char> &buffer,
+ const SourceManager &SourceMgr,
+ const LangOptions &LangOpts,
+ bool *invalid = 0);
/// MeasureTokenLength - Relex the token at the specified location and return
/// its length in bytes in the input file. If the token needs cleaning (e.g.
@@ -273,6 +281,12 @@ public:
const SourceManager &SM,
const LangOptions &LangOpts);
+ /// \brief Relex the token at the specified location.
+ /// \returns true if there was a failure, false on success.
+ static bool getRawToken(SourceLocation Loc, Token &Result,
+ const SourceManager &SM,
+ const LangOptions &LangOpts);
+
/// \brief Given a location any where in a source buffer, find the location
/// that corresponds to the beginning of the token in which the original
/// source location lands.
@@ -431,6 +445,11 @@ private:
///
void LexTokenInternal(Token &Result);
+ /// Given that a token begins with the Unicode character \p C, figure out
+ /// what kind of token it is and dispatch to the appropriate lexing helper
+ /// function.
+ void LexUnicode(Token &Result, uint32_t C, const char *CurPtr);
+
/// FormTokenWithChars - When we lex a token, we have identified a span
/// starting at BufferPtr, going to TokEnd that forms the token. This method
/// takes that range and assigns it to the token as its location and size. In
@@ -573,6 +592,21 @@ private:
void cutOffLexing() { BufferPtr = BufferEnd; }
bool isHexaLiteral(const char *Start, const LangOptions &LangOpts);
+
+
+ /// Read a universal character name.
+ ///
+ /// \param CurPtr The position in the source buffer after the initial '\'.
+ /// If the UCN is syntactically well-formed (but not necessarily
+ /// valid), this parameter will be updated to point to the
+ /// character after the UCN.
+ /// \param SlashLoc The position in the source buffer of the '\'.
+ /// \param Tok The token being formed. Pass \c NULL to suppress diagnostics
+ /// and handle token formation in the caller.
+ ///
+ /// \return The Unicode codepoint specified by the UCN, or 0 if the UCN is
+ /// invalid.
+ uint32_t tryReadUCN(const char *&CurPtr, const char *SlashLoc, Token *Tok);
};
diff --git a/include/clang/Lex/LiteralSupport.h b/include/clang/Lex/LiteralSupport.h
index 3b68d1b570f4..b1430cc80519 100644
--- a/include/clang/Lex/LiteralSupport.h
+++ b/include/clang/Lex/LiteralSupport.h
@@ -15,13 +15,13 @@
#ifndef CLANG_LITERALSUPPORT_H
#define CLANG_LITERALSUPPORT_H
+#include "clang/Basic/CharInfo.h"
#include "clang/Basic/LLVM.h"
+#include "clang/Basic/TokenKinds.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataTypes.h"
-#include "clang/Basic/TokenKinds.h"
-#include <cctype>
namespace clang {
@@ -101,7 +101,7 @@ private:
/// SkipHexDigits - Read and skip over any hex digits, up to End.
/// Return a pointer to the first non-hex digit or End.
const char *SkipHexDigits(const char *ptr) {
- while (ptr != ThisTokEnd && isxdigit(*ptr))
+ while (ptr != ThisTokEnd && isHexDigit(*ptr))
ptr++;
return ptr;
}
@@ -117,7 +117,7 @@ private:
/// SkipDigits - Read and skip over any digits, up to End.
/// Return a pointer to the first non-hex digit or End.
const char *SkipDigits(const char *ptr) {
- while (ptr != ThisTokEnd && isdigit(*ptr))
+ while (ptr != ThisTokEnd && isDigit(*ptr))
ptr++;
return ptr;
}
diff --git a/include/clang/Lex/MacroInfo.h b/include/clang/Lex/MacroInfo.h
index aba77d580d9b..64323b7c765f 100644
--- a/include/clang/Lex/MacroInfo.h
+++ b/include/clang/Lex/MacroInfo.h
@@ -6,9 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file defines the MacroInfo interface.
-//
+///
+/// \file
+/// \brief Defines the clang::MacroInfo and clang::MacroDirective classes.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_MACROINFO_H
@@ -22,34 +23,28 @@
namespace clang {
class Preprocessor;
-/// MacroInfo - Each identifier that is \#define'd has an instance of this class
-/// associated with it, used to implement macro expansion.
+/// \brief Encapsulates the data about a macro definition (e.g. its tokens).
+///
+/// There's an instance of this class for every #define.
class MacroInfo {
//===--------------------------------------------------------------------===//
// State set when the macro is defined.
- /// Location - This is the place the macro is defined.
+ /// \brief The location the macro is defined.
SourceLocation Location;
- /// EndLocation - The location of the last token in the macro.
+ /// \brief The location of the last token in the macro.
SourceLocation EndLocation;
- /// \brief The location where the macro was #undef'd, or an invalid location
- /// for macros that haven't been undefined.
- SourceLocation UndefLocation;
- /// \brief Previous definition, the identifier of this macro was defined to,
- /// or NULL.
- MacroInfo *PreviousDefinition;
- /// Arguments - The list of arguments for a function-like macro. This can be
- /// empty, for, e.g. "#define X()". In a C99-style variadic macro, this
+ /// \brief The list of arguments for a function-like macro.
+ ///
+ /// ArgumentList points to the first of NumArguments pointers.
+ ///
+ /// This can be empty, for, e.g. "#define X()". In a C99-style variadic macro, this
/// includes the \c __VA_ARGS__ identifier on the list.
IdentifierInfo **ArgumentList;
- unsigned NumArguments;
- /// \brief The location at which this macro was either explicitly exported
- /// from its module or marked as private.
- ///
- /// If invalid, this macro has not been explicitly given any visibility.
- SourceLocation VisibilityLocation;
+ /// \see ArgumentList
+ unsigned NumArguments;
/// \brief This is the list of tokens that the macro is defined to.
SmallVector<Token, 8> ReplacementTokens;
@@ -58,119 +53,88 @@ class MacroInfo {
mutable unsigned DefinitionLength;
mutable bool IsDefinitionLengthCached : 1;
- /// \brief True if this macro is a function-like macro, false if it
- /// is an object-like macro.
+ /// \brief True if this macro is function-like, false if it is object-like.
bool IsFunctionLike : 1;
- /// IsC99Varargs - True if this macro is of the form "#define X(...)" or
- /// "#define X(Y,Z,...)". The __VA_ARGS__ token should be replaced with the
- /// contents of "..." in an invocation.
+ /// \brief True if this macro is of the form "#define X(...)" or
+ /// "#define X(Y,Z,...)".
+ ///
+ /// The __VA_ARGS__ token should be replaced with the contents of "..." in an
+ /// invocation.
bool IsC99Varargs : 1;
- /// IsGNUVarargs - True if this macro is of the form "#define X(a...)". The
- /// "a" identifier in the replacement list will be replaced with all arguments
+ /// \brief True if this macro is of the form "#define X(a...)".
+ ///
+ /// The "a" identifier in the replacement list will be replaced with all arguments
/// of the macro starting with the specified one.
bool IsGNUVarargs : 1;
- /// IsBuiltinMacro - True if this is a builtin macro, such as __LINE__, and if
- /// it has not yet been redefined or undefined.
+ /// \brief True if this macro requires processing before expansion.
+ ///
+ /// This is the case for builtin macros such as __LINE__, so long as they have
+ /// not been redefined, but not for regular predefined macros from the "<built-in>"
+ /// memory buffer (see Preprocessing::getPredefinesFileID).
bool IsBuiltinMacro : 1;
- /// \brief True if this macro was loaded from an AST file.
- bool IsFromAST : 1;
-
- /// \brief Whether this macro changed after it was loaded from an AST file.
- bool ChangedAfterLoad : 1;
+ /// \brief Whether this macro contains the sequence ", ## __VA_ARGS__"
+ bool HasCommaPasting : 1;
private:
//===--------------------------------------------------------------------===//
// State that changes as the macro is used.
- /// IsDisabled - True if we have started an expansion of this macro already.
+ /// \brief True if we have started an expansion of this macro already.
+ ///
/// This disables recursive expansion, which would be quite bad for things
/// like \#define A A.
bool IsDisabled : 1;
- /// IsUsed - True if this macro is either defined in the main file and has
- /// been used, or if it is not defined in the main file. This is used to
- /// emit -Wunused-macros diagnostics.
+ /// \brief True if this macro is either defined in the main file and has
+ /// been used, or if it is not defined in the main file.
+ ///
+ /// This is used to emit -Wunused-macros diagnostics.
bool IsUsed : 1;
- /// AllowRedefinitionsWithoutWarning - True if this macro can be redefined
- /// without emitting a warning.
+ /// \brief True if this macro can be redefined without emitting a warning.
bool IsAllowRedefinitionsWithoutWarning : 1;
/// \brief Must warn if the macro is unused at the end of translation unit.
bool IsWarnIfUnused : 1;
-
- /// \brief Whether the macro has public (when described in a module).
- bool IsPublic : 1;
- /// \brief Whether the macro definition is currently "hidden".
- /// Note that this is transient state that is never serialized to the AST
- /// file.
- bool IsHidden : 1;
+ /// \brief Whether this macro info was loaded from an AST file.
+ unsigned FromASTFile : 1;
- /// \brief Whether the definition of this macro is ambiguous, due to
- /// multiple definitions coming in from multiple modules.
- bool IsAmbiguous : 1;
-
- ~MacroInfo() {
+ ~MacroInfo() {
assert(ArgumentList == 0 && "Didn't call destroy before dtor!");
}
public:
MacroInfo(SourceLocation DefLoc);
- MacroInfo(const MacroInfo &MI, llvm::BumpPtrAllocator &PPAllocator);
- /// FreeArgumentList - Free the argument list of the macro, restoring it to a
- /// state where it can be reused for other devious purposes.
+ /// \brief Free the argument list of the macro.
+ ///
+ /// This restores this MacroInfo to a state where it can be reused for other
+ /// devious purposes.
void FreeArgumentList() {
ArgumentList = 0;
NumArguments = 0;
}
- /// Destroy - destroy this MacroInfo object.
+ /// \brief Destroy this MacroInfo object.
void Destroy() {
FreeArgumentList();
this->~MacroInfo();
}
- /// getDefinitionLoc - Return the location that the macro was defined at.
- ///
+ /// \brief Return the location that the macro was defined at.
SourceLocation getDefinitionLoc() const { return Location; }
- /// setDefinitionEndLoc - Set the location of the last token in the macro.
- ///
+ /// \brief Set the location of the last token in the macro.
void setDefinitionEndLoc(SourceLocation EndLoc) { EndLocation = EndLoc; }
- /// getDefinitionEndLoc - Return the location of the last token in the macro.
- ///
+ /// \brief Return the location of the last token in the macro.
SourceLocation getDefinitionEndLoc() const { return EndLocation; }
- /// \brief Set the location where macro was undefined. Can only be set once.
- void setUndefLoc(SourceLocation UndefLoc) {
- assert(UndefLocation.isInvalid() && "UndefLocation is already set!");
- assert(UndefLoc.isValid() && "Invalid UndefLoc!");
- UndefLocation = UndefLoc;
- }
-
- /// \brief Get the location where macro was undefined.
- SourceLocation getUndefLoc() const { return UndefLocation; }
-
- /// \brief Set previous definition of the macro with the same name.
- void setPreviousDefinition(MacroInfo *PreviousDef) {
- PreviousDefinition = PreviousDef;
- }
-
- /// \brief Get previous definition of the macro with the same name.
- MacroInfo *getPreviousDefinition() { return PreviousDefinition; }
-
- /// \brief Find macro definition active in the specified source location. If
- /// this macro was not defined there, return NULL.
- const MacroInfo *findDefinitionAtLoc(SourceLocation L,
- SourceManager &SM) const;
-
/// \brief Get length in characters of the macro definition.
unsigned getDefinitionLength(SourceManager &SM) const {
if (IsDefinitionLengthCached)
@@ -178,25 +142,27 @@ public:
return getDefinitionLengthSlow(SM);
}
- /// isIdenticalTo - Return true if the specified macro definition is equal to
- /// this macro in spelling, arguments, and whitespace. This is used to emit
- /// duplicate definition warnings. This implements the rules in C99 6.10.3.
- bool isIdenticalTo(const MacroInfo &Other, Preprocessor &PP) const;
-
- /// setIsBuiltinMacro - Set or clear the isBuiltinMacro flag.
+ /// \brief Return true if the specified macro definition is equal to
+ /// this macro in spelling, arguments, and whitespace.
///
+ /// \param Syntactically if true, the macro definitions can be identical even
+ /// if they use different identifiers for the function macro parameters.
+ /// Otherwise the comparison is lexical and this implements the rules in
+ /// C99 6.10.3.
+ bool isIdenticalTo(const MacroInfo &Other, Preprocessor &PP,
+ bool Syntactically) const;
+
+ /// \brief Set or clear the isBuiltinMacro flag.
void setIsBuiltinMacro(bool Val = true) {
IsBuiltinMacro = Val;
}
- /// setIsUsed - Set the value of the IsUsed flag.
- ///
+ /// \brief Set the value of the IsUsed flag.
void setIsUsed(bool Val) {
IsUsed = Val;
}
- /// setIsAllowRedefinitionsWithoutWarning - Set the value of the
- /// IsAllowRedefinitionsWithoutWarning flag.
+ /// \brief Set the value of the IsAllowRedefinitionsWithoutWarning flag.
void setIsAllowRedefinitionsWithoutWarning(bool Val) {
IsAllowRedefinitionsWithoutWarning = Val;
}
@@ -206,8 +172,8 @@ public:
IsWarnIfUnused = val;
}
- /// setArgumentList - Set the specified list of identifiers as the argument
- /// list for this macro.
+ /// \brief Set the specified list of identifiers as the argument list for
+ /// this macro.
void setArgumentList(IdentifierInfo* const *List, unsigned NumArgs,
llvm::BumpPtrAllocator &PPAllocator) {
assert(ArgumentList == 0 && NumArguments == 0 &&
@@ -228,7 +194,7 @@ public:
arg_iterator arg_end() const { return ArgumentList+NumArguments; }
unsigned getNumArgs() const { return NumArguments; }
- /// getArgumentNum - Return the argument number of the specified identifier,
+ /// \brief Return the argument number of the specified identifier,
/// or -1 if the identifier is not a formal argument identifier.
int getArgumentNum(IdentifierInfo *Arg) const {
for (arg_iterator I = arg_begin(), E = arg_end(); I != E; ++I)
@@ -249,30 +215,22 @@ public:
bool isGNUVarargs() const { return IsGNUVarargs; }
bool isVariadic() const { return IsC99Varargs | IsGNUVarargs; }
- /// isBuiltinMacro - Return true if this macro is a builtin macro, such as
- /// __LINE__, which requires processing before expansion.
+ /// \brief Return true if this macro requires processing before expansion.
+ ///
+ /// This is true only for builtin macro, such as \__LINE__, whose values
+ /// are not given by fixed textual expansions. Regular predefined macros
+ /// from the "<built-in>" buffer are not reported as builtins by this
+ /// function.
bool isBuiltinMacro() const { return IsBuiltinMacro; }
- /// isFromAST - Return true if this macro was loaded from an AST file.
- bool isFromAST() const { return IsFromAST; }
-
- /// setIsFromAST - Set whether this macro was loaded from an AST file.
- void setIsFromAST(bool FromAST = true) { IsFromAST = FromAST; }
+ bool hasCommaPasting() const { return HasCommaPasting; }
+ void setHasCommaPasting() { HasCommaPasting = true; }
- /// \brief Determine whether this macro has changed since it was loaded from
- /// an AST file.
- bool hasChangedAfterLoad() const { return ChangedAfterLoad; }
-
- /// \brief Note whether this macro has changed after it was loaded from an
- /// AST file.
- void setChangedAfterLoad(bool CAL = true) { ChangedAfterLoad = CAL; }
-
- /// isUsed - Return false if this macro is defined in the main file and has
+ /// \brief Return false if this macro is defined in the main file and has
/// not yet been used.
bool isUsed() const { return IsUsed; }
- /// isAllowRedefinitionsWithoutWarning - Return true if this macro can be
- /// redefined without warning.
+ /// \brief Return true if this macro can be redefined without warning.
bool isAllowRedefinitionsWithoutWarning() const {
return IsAllowRedefinitionsWithoutWarning;
}
@@ -282,7 +240,7 @@ public:
return IsWarnIfUnused;
}
- /// getNumTokens - Return the number of tokens that this macro expands to.
+ /// \brief Return the number of tokens that this macro expands to.
///
unsigned getNumTokens() const {
return ReplacementTokens.size();
@@ -298,16 +256,16 @@ public:
tokens_iterator tokens_end() const { return ReplacementTokens.end(); }
bool tokens_empty() const { return ReplacementTokens.empty(); }
- /// AddTokenToBody - Add the specified token to the replacement text for the
- /// macro.
+ /// \brief Add the specified token to the replacement text for the macro.
void AddTokenToBody(const Token &Tok) {
assert(!IsDefinitionLengthCached &&
"Changing replacement tokens after definition length got calculated");
ReplacementTokens.push_back(Tok);
}
- /// isEnabled - Return true if this macro is enabled: in other words, that we
- /// are not currently in an expansion of this macro.
+ /// \brief Return true if this macro is enabled.
+ ///
+ /// In other words, that we are not currently in an expansion of this macro.
bool isEnabled() const { return !IsDisabled; }
void EnableMacro() {
@@ -320,41 +278,272 @@ public:
IsDisabled = true;
}
- /// \brief Set the export location for this macro.
- void setVisibility(bool Public, SourceLocation Loc) {
- VisibilityLocation = Loc;
- IsPublic = Public;
+ /// \brief Determine whether this macro info came from an AST file (such as
+ /// a precompiled header or module) rather than having been parsed.
+ bool isFromASTFile() const { return FromASTFile; }
+
+ /// \brief Retrieve the global ID of the module that owns this particular
+ /// macro info.
+ unsigned getOwningModuleID() const {
+ if (isFromASTFile())
+ return *(const unsigned*)(this+1);
+
+ return 0;
}
- /// \brief Determine whether this macro is part of the public API of its
- /// module.
- bool isPublic() const { return IsPublic; }
-
- /// \brief Determine the location where this macro was explicitly made
- /// public or private within its module.
- SourceLocation getVisibilityLocation() { return VisibilityLocation; }
+private:
+ unsigned getDefinitionLengthSlow(SourceManager &SM) const;
+
+ void setOwningModuleID(unsigned ID) {
+ assert(isFromASTFile());
+ *(unsigned*)(this+1) = ID;
+ }
+
+ friend class Preprocessor;
+};
+
+class DefMacroDirective;
+
+/// \brief Encapsulates changes to the "macros namespace" (the location where
+/// the macro name became active, the location where it was undefined, etc.).
+///
+/// MacroDirectives, associated with an identifier, are used to model the macro
+/// history. Usually a macro definition (MacroInfo) is where a macro name
+/// becomes active (MacroDirective) but modules can have their own macro
+/// history, separate from the local (current translation unit) macro history.
+///
+/// For example, if "@import A;" imports macro FOO, there will be a new local
+/// MacroDirective created to indicate that "FOO" became active at the import
+/// location. Module "A" itself will contain another MacroDirective in its macro
+/// history (at the point of the definition of FOO) and both MacroDirectives
+/// will point to the same MacroInfo object.
+///
+class MacroDirective {
+public:
+ enum Kind {
+ MD_Define,
+ MD_Undefine,
+ MD_Visibility
+ };
+
+protected:
+ /// \brief Previous macro directive for the same identifier, or NULL.
+ MacroDirective *Previous;
+
+ SourceLocation Loc;
+
+ /// \brief MacroDirective kind.
+ unsigned MDKind : 2;
+
+ /// \brief True if the macro directive was loaded from a PCH file.
+ bool IsFromPCH : 1;
- /// \brief Determine whether this macro is currently defined (and has not
- /// been #undef'd) or has been hidden.
- bool isDefined() const { return UndefLocation.isInvalid() && !IsHidden; }
+ /// \brief Whether the macro directive is currently "hidden".
+ ///
+ /// Note that this is transient state that is never serialized to the AST
+ /// file.
+ bool IsHidden : 1;
+
+ // Used by DefMacroDirective -----------------------------------------------//
- /// \brief Determine whether this macro definition is hidden.
+ /// \brief True if this macro was imported from a module.
+ bool IsImported : 1;
+
+ /// \brief Whether the definition of this macro is ambiguous, due to
+ /// multiple definitions coming in from multiple modules.
+ bool IsAmbiguous : 1;
+
+ // Used by VisibilityMacroDirective ----------------------------------------//
+
+ /// \brief Whether the macro has public visibility (when described in a
+ /// module).
+ bool IsPublic : 1;
+
+ MacroDirective(Kind K, SourceLocation Loc)
+ : Previous(0), Loc(Loc), MDKind(K), IsFromPCH(false), IsHidden(false),
+ IsImported(false), IsAmbiguous(false),
+ IsPublic(true) {
+ }
+
+public:
+ Kind getKind() const { return Kind(MDKind); }
+
+ SourceLocation getLocation() const { return Loc; }
+
+ /// \brief Set previous definition of the macro with the same name.
+ void setPrevious(MacroDirective *Prev) {
+ Previous = Prev;
+ }
+
+ /// \brief Get previous definition of the macro with the same name.
+ const MacroDirective *getPrevious() const { return Previous; }
+
+ /// \brief Get previous definition of the macro with the same name.
+ MacroDirective *getPrevious() { return Previous; }
+
+ /// \brief Return true if the macro directive was loaded from a PCH file.
+ bool isFromPCH() const { return IsFromPCH; }
+
+ void setIsFromPCH() { IsFromPCH = true; }
+
+ /// \brief Determine whether this macro directive is hidden.
bool isHidden() const { return IsHidden; }
- /// \brief Set whether this macro definition is hidden.
+ /// \brief Set whether this macro directive is hidden.
void setHidden(bool Val) { IsHidden = Val; }
+ class DefInfo {
+ DefMacroDirective *DefDirective;
+ SourceLocation UndefLoc;
+ bool IsPublic;
+
+ public:
+ DefInfo() : DefDirective(0) { }
+
+ DefInfo(DefMacroDirective *DefDirective, SourceLocation UndefLoc,
+ bool isPublic)
+ : DefDirective(DefDirective), UndefLoc(UndefLoc), IsPublic(isPublic) { }
+
+ const DefMacroDirective *getDirective() const { return DefDirective; }
+ DefMacroDirective *getDirective() { return DefDirective; }
+
+ inline SourceLocation getLocation() const;
+ inline MacroInfo *getMacroInfo();
+ const MacroInfo *getMacroInfo() const {
+ return const_cast<DefInfo*>(this)->getMacroInfo();
+ }
+
+ SourceLocation getUndefLocation() const { return UndefLoc; }
+ bool isUndefined() const { return UndefLoc.isValid(); }
+
+ bool isPublic() const { return IsPublic; }
+
+ bool isValid() const { return DefDirective != 0; }
+ bool isInvalid() const { return !isValid(); }
+
+ operator bool() const { return isValid(); }
+
+ inline DefInfo getPreviousDefinition(bool AllowHidden = false);
+ const DefInfo getPreviousDefinition(bool AllowHidden = false) const {
+ return const_cast<DefInfo*>(this)->getPreviousDefinition(AllowHidden);
+ }
+ };
+
+ /// \brief Traverses the macro directives history and returns the next
+ /// macro definition directive along with info about its undefined location
+ /// (if there is one) and if it is public or private.
+ DefInfo getDefinition(bool AllowHidden = false);
+ const DefInfo getDefinition(bool AllowHidden = false) const {
+ return const_cast<MacroDirective*>(this)->getDefinition(AllowHidden);
+ }
+
+ bool isDefined(bool AllowHidden = false) const {
+ if (const DefInfo Def = getDefinition(AllowHidden))
+ return !Def.isUndefined();
+ return false;
+ }
+
+ const MacroInfo *getMacroInfo(bool AllowHidden = false) const {
+ return getDefinition(AllowHidden).getMacroInfo();
+ }
+ MacroInfo *getMacroInfo(bool AllowHidden = false) {
+ return getDefinition(AllowHidden).getMacroInfo();
+ }
+
+ /// \brief Find macro definition active in the specified source location. If
+ /// this macro was not defined there, return NULL.
+ const DefInfo findDirectiveAtLoc(SourceLocation L, SourceManager &SM) const;
+
+ static bool classof(const MacroDirective *) { return true; }
+};
+
+/// \brief A directive for a defined macro or a macro imported from a module.
+class DefMacroDirective : public MacroDirective {
+ MacroInfo *Info;
+
+public:
+ explicit DefMacroDirective(MacroInfo *MI)
+ : MacroDirective(MD_Define, MI->getDefinitionLoc()), Info(MI) {
+ assert(MI && "MacroInfo is null");
+ }
+
+ DefMacroDirective(MacroInfo *MI, SourceLocation Loc, bool isImported)
+ : MacroDirective(MD_Define, Loc), Info(MI) {
+ assert(MI && "MacroInfo is null");
+ IsImported = isImported;
+ }
+
+ /// \brief The data for the macro definition.
+ const MacroInfo *getInfo() const { return Info; }
+ MacroInfo *getInfo() { return Info; }
+
+ /// \brief True if this macro was imported from a module.
+ bool isImported() const { return IsImported; }
+
/// \brief Determine whether this macro definition is ambiguous with
/// other macro definitions.
bool isAmbiguous() const { return IsAmbiguous; }
/// \brief Set whether this macro definition is ambiguous.
void setAmbiguous(bool Val) { IsAmbiguous = Val; }
-
-private:
- unsigned getDefinitionLengthSlow(SourceManager &SM) const;
+
+ static bool classof(const MacroDirective *MD) {
+ return MD->getKind() == MD_Define;
+ }
+ static bool classof(const DefMacroDirective *) { return true; }
+};
+
+/// \brief A directive for an undefined macro.
+class UndefMacroDirective : public MacroDirective {
+public:
+ explicit UndefMacroDirective(SourceLocation UndefLoc)
+ : MacroDirective(MD_Undefine, UndefLoc) {
+ assert(UndefLoc.isValid() && "Invalid UndefLoc!");
+ }
+
+ static bool classof(const MacroDirective *MD) {
+ return MD->getKind() == MD_Undefine;
+ }
+ static bool classof(const UndefMacroDirective *) { return true; }
+};
+
+/// \brief A directive for setting the module visibility of a macro.
+class VisibilityMacroDirective : public MacroDirective {
+public:
+ explicit VisibilityMacroDirective(SourceLocation Loc, bool Public)
+ : MacroDirective(MD_Visibility, Loc) {
+ IsPublic = Public;
+ }
+
+ /// \brief Determine whether this macro is part of the public API of its
+ /// module.
+ bool isPublic() const { return IsPublic; }
+
+ static bool classof(const MacroDirective *MD) {
+ return MD->getKind() == MD_Visibility;
+ }
+ static bool classof(const VisibilityMacroDirective *) { return true; }
};
+inline SourceLocation MacroDirective::DefInfo::getLocation() const {
+ if (isInvalid())
+ return SourceLocation();
+ return DefDirective->getLocation();
+}
+
+inline MacroInfo *MacroDirective::DefInfo::getMacroInfo() {
+ if (isInvalid())
+ return 0;
+ return DefDirective->getInfo();
+}
+
+inline MacroDirective::DefInfo
+MacroDirective::DefInfo::getPreviousDefinition(bool AllowHidden) {
+ if (isInvalid() || DefDirective->getPrevious() == 0)
+ return DefInfo();
+ return DefDirective->getPrevious()->getDefinition(AllowHidden);
+}
+
} // end namespace clang
#endif
diff --git a/include/clang/Lex/ModuleLoader.h b/include/clang/Lex/ModuleLoader.h
index 36d03c0aa2a3..3acf9151bc52 100644
--- a/include/clang/Lex/ModuleLoader.h
+++ b/include/clang/Lex/ModuleLoader.h
@@ -17,16 +17,36 @@
#include "clang/Basic/Module.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/PointerIntPair.h"
namespace clang {
class IdentifierInfo;
-
+class Module;
+
/// \brief A sequence of identifier/location pairs used to describe a particular
/// module or submodule, e.g., std.vector.
-typedef llvm::ArrayRef<std::pair<IdentifierInfo*, SourceLocation> >
- ModuleIdPath;
-
+typedef ArrayRef<std::pair<IdentifierInfo *, SourceLocation> > ModuleIdPath;
+
+/// \brief Describes the result of attempting to load a module.
+class ModuleLoadResult {
+ llvm::PointerIntPair<Module *, 1, bool> Storage;
+
+public:
+ ModuleLoadResult() : Storage() { }
+
+ ModuleLoadResult(Module *module, bool missingExpected)
+ : Storage(module, missingExpected) { }
+
+ operator Module *() const { return Storage.getPointer(); }
+
+ /// \brief Determines whether the module, which failed to load, was
+ /// actually a submodule that we expected to see (based on implying the
+ /// submodule from header structure), but didn't materialize in the actual
+ /// module.
+ bool isMissingExpected() const { return Storage.getInt(); }
+};
+
/// \brief Abstract interface for a module loader.
///
/// This abstract interface describes a module loader, which is responsible
@@ -55,9 +75,16 @@ public:
///
/// \returns If successful, returns the loaded module. Otherwise, returns
/// NULL to indicate that the module could not be loaded.
- virtual Module *loadModule(SourceLocation ImportLoc, ModuleIdPath Path,
- Module::NameVisibilityKind Visibility,
- bool IsInclusionDirective) = 0;
+ virtual ModuleLoadResult loadModule(SourceLocation ImportLoc,
+ ModuleIdPath Path,
+ Module::NameVisibilityKind Visibility,
+ bool IsInclusionDirective) = 0;
+
+ /// \brief Make the given module visible.
+ virtual void makeModuleVisible(Module *Mod,
+ Module::NameVisibilityKind Visibility,
+ SourceLocation ImportLoc,
+ bool Complain) = 0;
};
}
diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h
index 082408d83ce3..1c9c67314ae0 100644
--- a/include/clang/Lex/ModuleMap.h
+++ b/include/clang/Lex/ModuleMap.h
@@ -22,8 +22,8 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
#include <string>
namespace clang {
@@ -33,6 +33,7 @@ class FileEntry;
class FileManager;
class DiagnosticConsumer;
class DiagnosticsEngine;
+class HeaderSearch;
class ModuleMapParser;
class ModuleMap {
@@ -40,6 +41,7 @@ class ModuleMap {
IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
const LangOptions &LangOpts;
const TargetInfo *Target;
+ HeaderSearch &HeaderInfo;
/// \brief The directory used for Clang-supplied, builtin include headers,
/// such as "stdint.h".
@@ -104,13 +106,17 @@ class ModuleMap {
/// \brief The names of modules that cannot be inferred within this
/// directory.
- llvm::SmallVector<std::string, 2> ExcludedModules;
+ SmallVector<std::string, 2> ExcludedModules;
};
/// \brief A mapping from directories to information about inferring
/// framework modules from within those directories.
llvm::DenseMap<const DirectoryEntry *, InferredDirectory> InferredDirectories;
+ /// \brief Describes whether we haved parsed a particular file as a module
+ /// map.
+ llvm::DenseMap<const FileEntry *, bool> ParsedModuleMap;
+
friend class ModuleMapParser;
/// \brief Resolve the given export declaration into an actual export
@@ -127,8 +133,21 @@ class ModuleMap {
/// if the export could not be resolved.
Module::ExportDecl
resolveExport(Module *Mod, const Module::UnresolvedExportDecl &Unresolved,
- bool Complain);
-
+ bool Complain) const;
+
+ /// \brief Resolve the given module id to an actual module.
+ ///
+ /// \param Id The module-id to resolve.
+ ///
+ /// \param Mod The module in which we're resolving the module-id.
+ ///
+ /// \param Complain Whether this routine should complain about unresolvable
+ /// module-ids.
+ ///
+ /// \returns The resolved module, or null if the module-id could not be
+ /// resolved.
+ Module *resolveModuleId(const ModuleId &Id, Module *Mod, bool Complain) const;
+
public:
/// \brief Construct a new module map.
///
@@ -143,7 +162,8 @@ public:
///
/// \param Target The target for this translation unit.
ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC,
- const LangOptions &LangOpts, const TargetInfo *Target);
+ const LangOptions &LangOpts, const TargetInfo *Target,
+ HeaderSearch &HeaderInfo);
/// \brief Destroy the module map.
///
@@ -157,6 +177,7 @@ public:
void setBuiltinIncludeDir(const DirectoryEntry *Dir) {
BuiltinIncludeDir = Dir;
}
+ const DirectoryEntry *getBuiltinIncludeDir() { return BuiltinIncludeDir; }
/// \brief Retrieve the module that owns the given header file, if any.
///
@@ -168,14 +189,14 @@ public:
/// \brief Determine whether the given header is part of a module
/// marked 'unavailable'.
- bool isHeaderInUnavailableModule(const FileEntry *Header);
+ bool isHeaderInUnavailableModule(const FileEntry *Header) const;
/// \brief Retrieve a module with the given name.
///
/// \param Name The name of the module to look up.
///
/// \returns The named module, if known; otherwise, returns null.
- Module *findModule(StringRef Name);
+ Module *findModule(StringRef Name) const;
/// \brief Retrieve a module with the given name using lexical name lookup,
/// starting at the given context.
@@ -186,7 +207,7 @@ public:
/// name lookup.
///
/// \returns The named module, if known; otherwise, returns null.
- Module *lookupModuleUnqualified(StringRef Name, Module *Context);
+ Module *lookupModuleUnqualified(StringRef Name, Module *Context) const;
/// \brief Retrieve a module with the given name within the given context,
/// using direct (qualified) name lookup.
@@ -197,7 +218,7 @@ public:
/// null, we will look for a top-level module.
///
/// \returns The named submodule, if known; otherwose, returns null.
- Module *lookupModuleQualified(StringRef Name, Module *Context);
+ Module *lookupModuleQualified(StringRef Name, Module *Context) const;
/// \brief Find a new module or submodule, or create it if it does not already
/// exist.
@@ -231,7 +252,7 @@ public:
/// \returns true if we are allowed to infer a framework module, and false
/// otherwise.
bool canInferFrameworkModule(const DirectoryEntry *ParentDir,
- StringRef Name, bool &IsSystem);
+ StringRef Name, bool &IsSystem) const;
/// \brief Infer the contents of a framework module map from the given
/// framework directory.
@@ -246,7 +267,7 @@ public:
///
/// \returns The file entry for the module map file containing the given
/// module, or NULL if the module definition was inferred.
- const FileEntry *getContainingModuleMapFile(Module *Module);
+ const FileEntry *getContainingModuleMapFile(Module *Module) const;
/// \brief Resolve all of the unresolved exports in the given module.
///
@@ -258,7 +279,17 @@ public:
/// false otherwise.
bool resolveExports(Module *Mod, bool Complain);
- /// \brief Infers the (sub)module based on the given source location and
+ /// \brief Resolve all of the unresolved conflicts in the given module.
+ ///
+ /// \param Mod The module whose conflicts should be resolved.
+ ///
+ /// \param Complain Whether to emit diagnostics for failures.
+ ///
+ /// \returns true if any errors were encountered while resolving conflicts,
+ /// false otherwise.
+ bool resolveConflicts(Module *Mod, bool Complain);
+
+ /// \brief Infers the (sub)module based on the given source location and
/// source manager.
///
/// \param Loc The location within the source that we are querying, along
diff --git a/include/clang/Lex/PPCallbacks.h b/include/clang/Lex/PPCallbacks.h
index 8ba02cc4ea23..96359a2aa3a4 100644
--- a/include/clang/Lex/PPCallbacks.h
+++ b/include/clang/Lex/PPCallbacks.h
@@ -15,10 +15,10 @@
#ifndef LLVM_CLANG_LEX_PPCALLBACKS_H
#define LLVM_CLANG_LEX_PPCALLBACKS_H
+#include "clang/Basic/DiagnosticIDs.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Lex/DirectoryLookup.h"
#include "clang/Lex/ModuleLoader.h"
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/DiagnosticIDs.h"
#include "llvm/ADT/StringRef.h"
#include <string>
@@ -26,7 +26,7 @@ namespace clang {
class SourceLocation;
class Token;
class IdentifierInfo;
- class MacroInfo;
+ class MacroDirective;
/// \brief This interface provides a way to observe the actions of the
/// preprocessor as it does its thing.
@@ -184,22 +184,25 @@ public:
/// \brief Called by Preprocessor::HandleMacroExpandedIdentifier when a
/// macro invocation is found.
- virtual void MacroExpands(const Token &MacroNameTok, const MacroInfo* MI,
+ virtual void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD,
SourceRange Range) {
}
/// \brief Hook called whenever a macro definition is seen.
- virtual void MacroDefined(const Token &MacroNameTok, const MacroInfo *MI) {
+ virtual void MacroDefined(const Token &MacroNameTok,
+ const MacroDirective *MD) {
}
/// \brief Hook called whenever a macro \#undef is seen.
///
- /// MI is released immediately following this callback.
- virtual void MacroUndefined(const Token &MacroNameTok, const MacroInfo *MI) {
+ /// MD is released immediately following this callback.
+ virtual void MacroUndefined(const Token &MacroNameTok,
+ const MacroDirective *MD) {
}
/// \brief Hook called whenever the 'defined' operator is seen.
- virtual void Defined(const Token &MacroNameTok) {
+ /// \param MD The MacroDirective if the name was a macro, null otherwise.
+ virtual void Defined(const Token &MacroNameTok, const MacroDirective *MD) {
}
/// \brief Hook called when a source range is skipped.
@@ -228,13 +231,17 @@ public:
/// \brief Hook called whenever an \#ifdef is seen.
/// \param Loc the source location of the directive.
/// \param MacroNameTok Information on the token being tested.
- virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok) {
+ /// \param MD The MacroDirective if the name was a macro, null otherwise.
+ virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
+ const MacroDirective *MD) {
}
/// \brief Hook called whenever an \#ifndef is seen.
/// \param Loc the source location of the directive.
/// \param MacroNameTok Information on the token being tested.
- virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok) {
+ /// \param MD The MacroDirective if the name was a macro, null otherwise.
+ virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
+ const MacroDirective *MD) {
}
/// \brief Hook called whenever an \#else is seen.
@@ -346,25 +353,26 @@ public:
Second->PragmaDiagnostic(Loc, Namespace, mapping, Str);
}
- virtual void MacroExpands(const Token &MacroNameTok, const MacroInfo* MI,
+ virtual void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD,
SourceRange Range) {
- First->MacroExpands(MacroNameTok, MI, Range);
- Second->MacroExpands(MacroNameTok, MI, Range);
+ First->MacroExpands(MacroNameTok, MD, Range);
+ Second->MacroExpands(MacroNameTok, MD, Range);
}
- virtual void MacroDefined(const Token &MacroNameTok, const MacroInfo *MI) {
- First->MacroDefined(MacroNameTok, MI);
- Second->MacroDefined(MacroNameTok, MI);
+ virtual void MacroDefined(const Token &MacroNameTok, const MacroDirective *MD) {
+ First->MacroDefined(MacroNameTok, MD);
+ Second->MacroDefined(MacroNameTok, MD);
}
- virtual void MacroUndefined(const Token &MacroNameTok, const MacroInfo *MI) {
- First->MacroUndefined(MacroNameTok, MI);
- Second->MacroUndefined(MacroNameTok, MI);
+ virtual void MacroUndefined(const Token &MacroNameTok,
+ const MacroDirective *MD) {
+ First->MacroUndefined(MacroNameTok, MD);
+ Second->MacroUndefined(MacroNameTok, MD);
}
- virtual void Defined(const Token &MacroNameTok) {
- First->Defined(MacroNameTok);
- Second->Defined(MacroNameTok);
+ virtual void Defined(const Token &MacroNameTok, const MacroDirective *MD) {
+ First->Defined(MacroNameTok, MD);
+ Second->Defined(MacroNameTok, MD);
}
virtual void SourceRangeSkipped(SourceRange Range) {
@@ -386,15 +394,17 @@ public:
}
/// \brief Hook called whenever an \#ifdef is seen.
- virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok) {
- First->Ifdef(Loc, MacroNameTok);
- Second->Ifdef(Loc, MacroNameTok);
+ virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
+ const MacroDirective *MD) {
+ First->Ifdef(Loc, MacroNameTok, MD);
+ Second->Ifdef(Loc, MacroNameTok, MD);
}
/// \brief Hook called whenever an \#ifndef is seen.
- virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok) {
- First->Ifndef(Loc, MacroNameTok);
- Second->Ifndef(Loc, MacroNameTok);
+ virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
+ const MacroDirective *MD) {
+ First->Ifndef(Loc, MacroNameTok, MD);
+ Second->Ifndef(Loc, MacroNameTok, MD);
}
/// \brief Hook called whenever an \#else is seen.
diff --git a/include/clang/Lex/PPConditionalDirectiveRecord.h b/include/clang/Lex/PPConditionalDirectiveRecord.h
new file mode 100644
index 000000000000..b9a22529e205
--- /dev/null
+++ b/include/clang/Lex/PPConditionalDirectiveRecord.h
@@ -0,0 +1,102 @@
+//===--- PPConditionalDirectiveRecord.h - Preprocessing Directives-*- 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 PPConditionalDirectiveRecord class, which maintains
+// a record of conditional directive regions.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H
+#define LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Lex/PPCallbacks.h"
+#include "llvm/ADT/SmallVector.h"
+#include <vector>
+
+namespace clang {
+
+/// \brief Records preprocessor conditional directive regions and allows
+/// querying in which region source locations belong to.
+class PPConditionalDirectiveRecord : public PPCallbacks {
+ SourceManager &SourceMgr;
+
+ SmallVector<SourceLocation, 6> CondDirectiveStack;
+
+ class CondDirectiveLoc {
+ SourceLocation Loc;
+ SourceLocation RegionLoc;
+
+ public:
+ CondDirectiveLoc(SourceLocation Loc, SourceLocation RegionLoc)
+ : Loc(Loc), RegionLoc(RegionLoc) {}
+
+ SourceLocation getLoc() const { return Loc; }
+ SourceLocation getRegionLoc() const { return RegionLoc; }
+
+ class Comp {
+ SourceManager &SM;
+ public:
+ explicit Comp(SourceManager &SM) : SM(SM) {}
+ bool operator()(const CondDirectiveLoc &LHS,
+ const CondDirectiveLoc &RHS) {
+ return SM.isBeforeInTranslationUnit(LHS.getLoc(), RHS.getLoc());
+ }
+ bool operator()(const CondDirectiveLoc &LHS, SourceLocation RHS) {
+ return SM.isBeforeInTranslationUnit(LHS.getLoc(), RHS);
+ }
+ bool operator()(SourceLocation LHS, const CondDirectiveLoc &RHS) {
+ return SM.isBeforeInTranslationUnit(LHS, RHS.getLoc());
+ }
+ };
+ };
+
+ typedef std::vector<CondDirectiveLoc> CondDirectiveLocsTy;
+ /// \brief The locations of conditional directives in source order.
+ CondDirectiveLocsTy CondDirectiveLocs;
+
+ void addCondDirectiveLoc(CondDirectiveLoc DirLoc);
+
+public:
+ /// \brief Construct a new preprocessing record.
+ explicit PPConditionalDirectiveRecord(SourceManager &SM);
+
+ size_t getTotalMemory() const;
+
+ SourceManager &getSourceManager() const { return SourceMgr; }
+
+ /// \brief Returns true if the given range intersects with a conditional
+ /// directive. if a \#if/\#endif block is fully contained within the range,
+ /// this function will return false.
+ bool rangeIntersectsConditionalDirective(SourceRange Range) const;
+
+ /// \brief Returns true if the given locations are in different regions,
+ /// separated by conditional directive blocks.
+ bool areInDifferentConditionalDirectiveRegion(SourceLocation LHS,
+ SourceLocation RHS) const {
+ return findConditionalDirectiveRegionLoc(LHS) !=
+ findConditionalDirectiveRegionLoc(RHS);
+ }
+
+ SourceLocation findConditionalDirectiveRegionLoc(SourceLocation Loc) const;
+
+private:
+ virtual void If(SourceLocation Loc, SourceRange ConditionRange);
+ virtual void Elif(SourceLocation Loc, SourceRange ConditionRange,
+ SourceLocation IfLoc);
+ virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
+ const MacroDirective *MD);
+ virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
+ const MacroDirective *MD);
+ virtual void Else(SourceLocation Loc, SourceLocation IfLoc);
+ virtual void Endif(SourceLocation Loc, SourceLocation IfLoc);
+};
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H
diff --git a/include/clang/Lex/PPMutationListener.h b/include/clang/Lex/PPMutationListener.h
deleted file mode 100644
index 5319c66fa27d..000000000000
--- a/include/clang/Lex/PPMutationListener.h
+++ /dev/null
@@ -1,43 +0,0 @@
-//===--- PPMutationListener.h - Preprocessor Mutation Interface -*- 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 PPMutationListener interface.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_LEX_PPTMUTATIONLISTENER_H
-#define LLVM_CLANG_LEX_PPTMUTATIONLISTENER_H
-
-#include "clang/Basic/SourceLocation.h"
-
-namespace clang {
-
-class MacroInfo;
-
-/// \brief A record that describes an update to a macro that was
-/// originally loaded to an AST file and has been modified within the
-/// current translation unit.
-struct MacroUpdate {
- /// \brief The source location at which this macro was #undef'd.
- SourceLocation UndefLoc;
-};
-
-/// \brief An abstract interface that should be implemented by
-/// listeners that want to be notified when a preprocessor entity gets
-/// modified after its initial creation.
-class PPMutationListener {
-public:
- virtual ~PPMutationListener();
-
- /// \brief A macro has been #undef'd.
- virtual void UndefinedMacro(MacroInfo *MI) { }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Lex/PTHManager.h b/include/clang/Lex/PTHManager.h
index e64dbd8bbcb0..fad0806ca347 100644
--- a/include/clang/Lex/PTHManager.h
+++ b/include/clang/Lex/PTHManager.h
@@ -14,10 +14,10 @@
#ifndef LLVM_CLANG_PTHMANAGER_H
#define LLVM_CLANG_PTHMANAGER_H
-#include "clang/Lex/PTHLexer.h"
-#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Lex/PTHLexer.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/Allocator.h"
#include <string>
diff --git a/include/clang/Lex/PreprocessingRecord.h b/include/clang/Lex/PreprocessingRecord.h
index 57e51b754e42..b13b2be7f317 100644
--- a/include/clang/Lex/PreprocessingRecord.h
+++ b/include/clang/Lex/PreprocessingRecord.h
@@ -14,18 +14,19 @@
#ifndef LLVM_CLANG_LEX_PREPROCESSINGRECORD_H
#define LLVM_CLANG_LEX_PREPROCESSINGRECORD_H
-#include "clang/Lex/PPCallbacks.h"
-#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/IdentifierTable.h"
-#include "llvm/ADT/SmallVector.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Lex/PPCallbacks.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Compiler.h"
#include <vector>
namespace clang {
class IdentifierInfo;
+ class MacroInfo;
class PreprocessingRecord;
}
@@ -277,9 +278,9 @@ namespace clang {
/// \brief Optionally returns true or false if the preallocated preprocessed
/// entity with index \p Index came from file \p FID.
- virtual llvm::Optional<bool> isPreprocessedEntityInFileID(unsigned Index,
- FileID FID) {
- return llvm::Optional<bool>();
+ virtual Optional<bool> isPreprocessedEntityInFileID(unsigned Index,
+ FileID FID) {
+ return None;
}
};
@@ -303,44 +304,6 @@ namespace clang {
/// and are referenced by the iterator using negative indices.
std::vector<PreprocessedEntity *> LoadedPreprocessedEntities;
- bool RecordCondDirectives;
- unsigned CondDirectiveNextIdx;
- SmallVector<unsigned, 6> CondDirectiveStack;
-
- class CondDirectiveLoc {
- SourceLocation Loc;
- unsigned Idx;
-
- public:
- CondDirectiveLoc(SourceLocation Loc, unsigned Idx) : Loc(Loc), Idx(Idx) {}
-
- SourceLocation getLoc() const { return Loc; }
- unsigned getIdx() const { return Idx; }
-
- class Comp {
- SourceManager &SM;
- public:
- explicit Comp(SourceManager &SM) : SM(SM) {}
- bool operator()(const CondDirectiveLoc &LHS,
- const CondDirectiveLoc &RHS) {
- return SM.isBeforeInTranslationUnit(LHS.getLoc(), RHS.getLoc());
- }
- bool operator()(const CondDirectiveLoc &LHS, SourceLocation RHS) {
- return SM.isBeforeInTranslationUnit(LHS.getLoc(), RHS);
- }
- bool operator()(SourceLocation LHS, const CondDirectiveLoc &RHS) {
- return SM.isBeforeInTranslationUnit(LHS, RHS.getLoc());
- }
- };
- };
-
- typedef std::vector<CondDirectiveLoc> CondDirectiveLocsTy;
- /// \brief The locations of conditional directives in source order.
- CondDirectiveLocsTy CondDirectiveLocs;
-
- void addCondDirectiveLoc(CondDirectiveLoc DirLoc);
- unsigned findCondDirectiveIdx(SourceLocation Loc) const;
-
/// \brief Global (loaded or local) ID for a preprocessed entity.
/// Negative values are used to indicate preprocessed entities
/// loaded from the external source while non-negative values are used to
@@ -363,7 +326,7 @@ namespace clang {
}
/// \brief Mapping from MacroInfo structures to their definitions.
- llvm::DenseMap<const MacroInfo *, PPEntityID> MacroDefinitions;
+ llvm::DenseMap<const MacroInfo *, MacroDefinition *> MacroDefinitions;
/// \brief External source of preprocessed entities.
ExternalPreprocessingRecordSource *ExternalSource;
@@ -394,11 +357,11 @@ namespace clang {
unsigned allocateLoadedEntities(unsigned NumEntities);
/// \brief Register a new macro definition.
- void RegisterMacroDefinition(MacroInfo *Macro, PPEntityID PPID);
+ void RegisterMacroDefinition(MacroInfo *Macro, MacroDefinition *Def);
public:
/// \brief Construct a new preprocessing record.
- PreprocessingRecord(SourceManager &SM, bool RecordConditionalDirectives);
+ explicit PreprocessingRecord(SourceManager &SM);
/// \brief Allocate memory in the preprocessing record.
void *Allocate(unsigned Size, unsigned Align = 8) {
@@ -582,24 +545,6 @@ namespace clang {
/// \brief Add a new preprocessed entity to this record.
PPEntityID addPreprocessedEntity(PreprocessedEntity *Entity);
- /// \brief Returns true if this PreprocessingRecord is keeping track of
- /// conditional directives locations.
- bool isRecordingConditionalDirectives() const {
- return RecordCondDirectives;
- }
-
- /// \brief Returns true if the given range intersects with a conditional
- /// directive. if a \#if/\#endif block is fully contained within the range,
- /// this function will return false.
- bool rangeIntersectsConditionalDirective(SourceRange Range) const;
-
- /// \brief Returns true if the given locations are in different regions,
- /// separated by conditional directive blocks.
- bool areInDifferentConditionalDirectiveRegion(SourceLocation LHS,
- SourceLocation RHS) const {
- return findCondDirectiveIdx(LHS) != findCondDirectiveIdx(RHS);
- }
-
/// \brief Set the external source for preprocessed entities.
void SetExternalSource(ExternalPreprocessingRecordSource &Source);
@@ -613,10 +558,10 @@ namespace clang {
MacroDefinition *findMacroDefinition(const MacroInfo *MI);
private:
- virtual void MacroExpands(const Token &Id, const MacroInfo* MI,
+ virtual void MacroExpands(const Token &Id, const MacroDirective *MD,
SourceRange Range);
- virtual void MacroDefined(const Token &Id, const MacroInfo *MI);
- virtual void MacroUndefined(const Token &Id, const MacroInfo *MI);
+ virtual void MacroDefined(const Token &Id, const MacroDirective *MD);
+ virtual void MacroUndefined(const Token &Id, const MacroDirective *MD);
virtual void InclusionDirective(SourceLocation HashLoc,
const Token &IncludeTok,
StringRef FileName,
@@ -626,13 +571,15 @@ namespace clang {
StringRef SearchPath,
StringRef RelativePath,
const Module *Imported);
- virtual void If(SourceLocation Loc, SourceRange ConditionRange);
- virtual void Elif(SourceLocation Loc, SourceRange ConditionRange,
- SourceLocation IfLoc);
- virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok);
- virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok);
- virtual void Else(SourceLocation Loc, SourceLocation IfLoc);
- virtual void Endif(SourceLocation Loc, SourceLocation IfLoc);
+ virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
+ const MacroDirective *MD);
+ virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
+ const MacroDirective *MD);
+ /// \brief Hook called whenever the 'defined' operator is seen.
+ virtual void Defined(const Token &MacroNameTok, const MacroDirective *MD);
+
+ void addMacroExpansion(const Token &Id, const MacroInfo *MI,
+ SourceRange Range);
/// \brief Cached result of the last \see getPreprocessedEntitiesInRange
/// query.
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index e9095fbf44a9..7a912ec0f817 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -14,23 +14,22 @@
#ifndef LLVM_CLANG_LEX_PREPROCESSOR_H
#define LLVM_CLANG_LEX_PREPROCESSOR_H
-#include "clang/Lex/MacroInfo.h"
-#include "clang/Lex/Lexer.h"
-#include "clang/Lex/PTHLexer.h"
-#include "clang/Lex/PPCallbacks.h"
-#include "clang/Lex/PPMutationListener.h"
-#include "clang/Lex/TokenLexer.h"
-#include "clang/Lex/PTHManager.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/SourceLocation.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Lex/MacroInfo.h"
+#include "clang/Lex/PPCallbacks.h"
+#include "clang/Lex/PTHLexer.h"
+#include "clang/Lex/PTHManager.h"
+#include "clang/Lex/TokenLexer.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/Allocator.h"
#include <vector>
@@ -84,7 +83,7 @@ public:
/// like the \#include stack, token expansion, etc.
///
class Preprocessor : public RefCountedBase<Preprocessor> {
- llvm::IntrusiveRefCntPtr<PreprocessorOptions> PPOpts;
+ IntrusiveRefCntPtr<PreprocessorOptions> PPOpts;
DiagnosticsEngine *Diags;
LangOptions &LangOpts;
const TargetInfo *Target;
@@ -160,6 +159,12 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
/// \brief True if pragmas are enabled.
bool PragmasEnabled : 1;
+ /// \brief True if the current build action is a preprocessing action.
+ bool PreprocessedOutput : 1;
+
+ /// \brief True if we are currently preprocessing a #if or #elif directive
+ bool ParsingIfOrElifDirective;
+
/// \brief True if we are pre-expanding macro arguments.
bool InMacroArgPreExpansion;
@@ -215,8 +220,7 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
SourceLocation ModuleImportLoc;
/// \brief The module import path that we're currently processing.
- llvm::SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2>
- ModuleImportPath;
+ SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> ModuleImportPath;
/// \brief Whether the module import expectes an identifier next. Otherwise,
/// it expects a '.' or ';'.
@@ -291,24 +295,19 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
/// encountered (e.g. a file is \#included, etc).
PPCallbacks *Callbacks;
- /// \brief Listener whose actions are invoked when an entity in the
- /// preprocessor (e.g., a macro) that was loaded from an AST file is
- /// later mutated.
- PPMutationListener *Listener;
-
struct MacroExpandsInfo {
Token Tok;
- MacroInfo *MI;
+ MacroDirective *MD;
SourceRange Range;
- MacroExpandsInfo(Token Tok, MacroInfo *MI, SourceRange Range)
- : Tok(Tok), MI(MI), Range(Range) { }
+ MacroExpandsInfo(Token Tok, MacroDirective *MD, SourceRange Range)
+ : Tok(Tok), MD(MD), Range(Range) { }
};
SmallVector<MacroExpandsInfo, 2> DelayedMacroExpandsCallbacks;
/// Macros - For each IdentifierInfo that was associated with a macro, we
/// keep a mapping to the history of all macro definitions and #undefs in
/// the reverse order (the latest one is in the head of the list).
- llvm::DenseMap<IdentifierInfo*, MacroInfo*> Macros;
+ llvm::DenseMap<const IdentifierInfo*, MacroDirective*> Macros;
friend class ASTReader;
/// \brief Macros that we want to warn because they are not used at the end
@@ -343,6 +342,9 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
/// should use from the command line etc.
std::string Predefines;
+ /// \brief The file ID for the preprocessor predefines.
+ FileID PredefinesFileID;
+
/// TokenLexerCache - Cache macro expanders to reduce malloc traffic.
enum { TokenLexerCacheSize = 8 };
unsigned NumCachedTokenLexers;
@@ -396,7 +398,7 @@ private: // Cached tokens state.
MacroInfoChain *MICache;
public:
- Preprocessor(llvm::IntrusiveRefCntPtr<PreprocessorOptions> PPOpts,
+ Preprocessor(IntrusiveRefCntPtr<PreprocessorOptions> PPOpts,
DiagnosticsEngine &diags, LangOptions &opts,
const TargetInfo *target,
SourceManager &SM, HeaderSearch &Headers,
@@ -447,6 +449,11 @@ public:
/// \brief Retrieve the module loader associated with this preprocessor.
ModuleLoader &getModuleLoader() const { return TheModuleLoader; }
+ /// \brief True if we are currently preprocessing a #if or #elif directive
+ bool isParsingIfOrElifDirective() const {
+ return ParsingIfOrElifDirective;
+ }
+
/// SetCommentRetentionState - Control whether or not the preprocessor retains
/// comments in output.
void SetCommentRetentionState(bool KeepComments, bool KeepMacroComments) {
@@ -467,6 +474,16 @@ public:
return SuppressIncludeNotFoundError;
}
+ /// Sets whether the preprocessor is responsible for producing output or if
+ /// it is producing tokens to be consumed by Parse and Sema.
+ void setPreprocessedOutput(bool IsPreprocessedOutput) {
+ PreprocessedOutput = IsPreprocessedOutput;
+ }
+
+ /// Returns true if the preprocessor is responsible for generating output,
+ /// false if it is producing tokens to be consumed by Parse and Sema.
+ bool isPreprocessedOutput() const { return PreprocessedOutput; }
+
/// isCurrentLexer - Return true if we are lexing directly from the specified
/// lexer.
bool isCurrentLexer(const PreprocessorLexer *L) const {
@@ -483,6 +500,9 @@ public:
/// expansions going on at the time.
PreprocessorLexer *getCurrentFileLexer() const;
+ /// \brief Returns the file ID for the preprocessor predefines.
+ FileID getPredefinesFileID() const { return PredefinesFileID; }
+
/// getPPCallbacks/addPPCallbacks - Accessors for preprocessor callbacks.
/// Note that this class takes ownership of any PPCallbacks object given to
/// it.
@@ -493,53 +513,54 @@ public:
Callbacks = C;
}
- /// \brief Attach an preprocessor mutation listener to the preprocessor.
- ///
- /// The preprocessor mutation listener provides the ability to track
- /// modifications to the preprocessor entities committed after they were
- /// initially created.
- void setPPMutationListener(PPMutationListener *Listener) {
- this->Listener = Listener;
- }
-
- /// \brief Retrieve a pointer to the preprocessor mutation listener
- /// associated with this preprocessor, if any.
- PPMutationListener *getPPMutationListener() const { return Listener; }
-
- /// \brief Given an identifier, return the MacroInfo it is \#defined to
- /// or null if it isn't \#define'd.
- MacroInfo *getMacroInfo(IdentifierInfo *II) const {
+ /// \brief Given an identifier, return its latest MacroDirective if it is
+ // \#defined or null if it isn't \#define'd.
+ MacroDirective *getMacroDirective(IdentifierInfo *II) const {
if (!II->hasMacroDefinition())
return 0;
- MacroInfo *MI = getMacroInfoHistory(II);
- assert(MI->getUndefLoc().isInvalid() && "Macro is undefined!");
- return MI;
+ MacroDirective *MD = getMacroDirectiveHistory(II);
+ assert(MD->isDefined() && "Macro is undefined!");
+ return MD;
+ }
+
+ const MacroInfo *getMacroInfo(IdentifierInfo *II) const {
+ return const_cast<Preprocessor*>(this)->getMacroInfo(II);
+ }
+
+ MacroInfo *getMacroInfo(IdentifierInfo *II) {
+ if (MacroDirective *MD = getMacroDirective(II))
+ return MD->getMacroInfo();
+ return 0;
}
/// \brief Given an identifier, return the (probably #undef'd) MacroInfo
/// representing the most recent macro definition. One can iterate over all
/// previous macro definitions from it. This method should only be called for
/// identifiers that hadMacroDefinition().
- MacroInfo *getMacroInfoHistory(IdentifierInfo *II) const;
-
- /// \brief Specify a macro for this identifier.
- void setMacroInfo(IdentifierInfo *II, MacroInfo *MI);
- /// \brief Add a MacroInfo that was loaded from an AST file.
- void addLoadedMacroInfo(IdentifierInfo *II, MacroInfo *MI,
- MacroInfo *Hint = 0);
- /// \brief Make the given MacroInfo, that was loaded from an AST file and
- /// previously hidden, visible.
- void makeLoadedMacroInfoVisible(IdentifierInfo *II, MacroInfo *MI);
- /// \brief Undefine a macro for this identifier.
- void clearMacroInfo(IdentifierInfo *II);
+ MacroDirective *getMacroDirectiveHistory(const IdentifierInfo *II) const;
+
+ /// \brief Add a directive to the macro directive history for this identifier.
+ void appendMacroDirective(IdentifierInfo *II, MacroDirective *MD);
+ DefMacroDirective *appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI,
+ SourceLocation Loc,
+ bool isImported) {
+ DefMacroDirective *MD = AllocateDefMacroDirective(MI, Loc, isImported);
+ appendMacroDirective(II, MD);
+ return MD;
+ }
+ DefMacroDirective *appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI){
+ return appendDefMacroDirective(II, MI, MI->getDefinitionLoc(), false);
+ }
+ /// \brief Set a MacroDirective that was loaded from a PCH file.
+ void setLoadedMacroDirective(IdentifierInfo *II, MacroDirective *MD);
/// macro_iterator/macro_begin/macro_end - This allows you to walk the macro
/// history table. Currently defined macros have
/// IdentifierInfo::hasMacroDefinition() set and an empty
/// MacroInfo::getUndefLoc() at the head of the list.
- typedef llvm::DenseMap<IdentifierInfo*,
- MacroInfo*>::const_iterator macro_iterator;
+ typedef llvm::DenseMap<const IdentifierInfo *,
+ MacroDirective*>::const_iterator macro_iterator;
macro_iterator macro_begin(bool IncludeExternalMacros = true) const;
macro_iterator macro_end(bool IncludeExternalMacros = true) const;
@@ -611,7 +632,7 @@ public:
/// \brief Create a new preprocessing record, which will keep track of
/// all macro expansions, macro definitions, etc.
- void createPreprocessingRecord(bool RecordConditionalDirectives);
+ void createPreprocessingRecord();
/// EnterMainSourceFile - Enter the specified FileID as the main source file,
/// which implicitly adds the builtin defines etc.
@@ -696,6 +717,25 @@ public:
void LexAfterModuleImport(Token &Result);
+ /// \brief Lex a string literal, which may be the concatenation of multiple
+ /// string literals and may even come from macro expansion.
+ /// \returns true on success, false if a error diagnostic has been generated.
+ bool LexStringLiteral(Token &Result, std::string &String,
+ const char *DiagnosticTag, bool AllowMacroExpansion) {
+ if (AllowMacroExpansion)
+ Lex(Result);
+ else
+ LexUnexpandedToken(Result);
+ return FinishLexStringLiteral(Result, String, DiagnosticTag,
+ AllowMacroExpansion);
+ }
+
+ /// \brief Complete the lexing of a string literal where the first token has
+ /// already been lexed (see LexStringLiteral).
+ bool FinishLexStringLiteral(Token &Result, std::string &String,
+ const char *DiagnosticTag,
+ bool AllowMacroExpansion);
+
/// LexNonComment - Lex a token. If it's a comment, keep lexing until we get
/// something not a comment. This is useful in -E -C mode where comments
/// would foul up preprocessor directive handling.
@@ -901,8 +941,8 @@ public:
/// "cleaning", e.g. if it contains trigraphs or escaped newlines
/// \param invalid If non-null, will be set \c true if an error occurs.
StringRef getSpelling(SourceLocation loc,
- SmallVectorImpl<char> &buffer,
- bool *invalid = 0) const {
+ SmallVectorImpl<char> &buffer,
+ bool *invalid = 0) const {
return Lexer::getSpelling(loc, buffer, SourceMgr, LangOpts, invalid);
}
@@ -939,6 +979,12 @@ public:
SmallVectorImpl<char> &Buffer,
bool *Invalid = 0) const;
+ /// \brief Relex the token at the specified location.
+ /// \returns true if there was a failure, false on success.
+ bool getRawToken(SourceLocation Loc, Token &Result) {
+ return Lexer::getRawToken(Loc, Result, SourceMgr, LangOpts);
+ }
+
/// getSpellingOfSingleCharacterNumericConstant - Tok is a numeric constant
/// with length 1, return the character.
char getSpellingOfSingleCharacterNumericConstant(const Token &Tok,
@@ -1143,8 +1189,9 @@ public:
/// \brief Allocate a new MacroInfo object with the provided SourceLocation.
MacroInfo *AllocateMacroInfo(SourceLocation L);
- /// \brief Allocate a new MacroInfo object which is clone of \p MI.
- MacroInfo *CloneMacroInfo(const MacroInfo &MI);
+ /// \brief Allocate a new MacroInfo object loaded from an AST file.
+ MacroInfo *AllocateDeserializedMacroInfo(SourceLocation L,
+ unsigned SubModuleID);
/// \brief Turn the specified lexer token into a fully checked and spelled
/// filename, e.g. as an operand of \#include.
@@ -1221,6 +1268,13 @@ private:
/// \brief Allocate a new MacroInfo object.
MacroInfo *AllocateMacroInfo();
+ DefMacroDirective *AllocateDefMacroDirective(MacroInfo *MI,
+ SourceLocation Loc,
+ bool isImported);
+ UndefMacroDirective *AllocateUndefMacroDirective(SourceLocation UndefLoc);
+ VisibilityMacroDirective *AllocateVisibilityMacroDirective(SourceLocation Loc,
+ bool isPublic);
+
/// \brief Release the specified MacroInfo for re-use.
///
/// This memory will be reused for allocating new MacroInfo objects.
@@ -1268,7 +1322,7 @@ private:
/// HandleMacroExpandedIdentifier - If an identifier token is read that is to
/// be expanded as a macro, handle it and return the next token as 'Tok'. If
/// the macro should not be expanded return true, otherwise return false.
- bool HandleMacroExpandedIdentifier(Token &Tok, MacroInfo *MI);
+ bool HandleMacroExpandedIdentifier(Token &Tok, MacroDirective *MD);
/// \brief Cache macro expanded tokens for TokenLexers.
//
@@ -1312,6 +1366,12 @@ private:
/// start getting tokens from it using the PTH cache.
void EnterSourceFileWithPTH(PTHLexer *PL, const DirectoryLookup *Dir);
+ /// \brief Set the file ID for the preprocessor predefines.
+ void setPredefinesFileID(FileID FID) {
+ assert(PredefinesFileID.isInvalid() && "PredefinesFileID already set!");
+ PredefinesFileID = FID;
+ }
+
/// IsFileLexer - Returns true if we are lexing from a file and not a
/// pragma or a macro.
static bool IsFileLexer(const Lexer* L, const PreprocessorLexer* P) {
@@ -1367,8 +1427,6 @@ private:
// Macro handling.
void HandleDefineDirective(Token &Tok);
void HandleUndefDirective(Token &Tok);
- void UndefineMacro(IdentifierInfo *II, MacroInfo *MI,
- SourceLocation UndefLoc);
// Conditional Inclusion.
void HandleIfdefDirective(Token &Tok, bool isIfndef,
diff --git a/include/clang/Lex/PreprocessorOptions.h b/include/clang/Lex/PreprocessorOptions.h
index e5fe37379355..eba2a13342f5 100644
--- a/include/clang/Lex/PreprocessorOptions.h
+++ b/include/clang/Lex/PreprocessorOptions.h
@@ -10,14 +10,16 @@
#ifndef LLVM_CLANG_LEX_PREPROCESSOROPTIONS_H_
#define LLVM_CLANG_LEX_PREPROCESSOROPTIONS_H_
+#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSet.h"
#include <cassert>
+#include <set>
#include <string>
#include <utility>
#include <vector>
-#include <set>
namespace llvm {
class MemoryBuffer;
@@ -39,23 +41,20 @@ enum ObjCXXARCStandardLibraryKind {
/// PreprocessorOptions - This class is used for passing the various options
/// used in preprocessor initialization to InitializePreprocessor().
-class PreprocessorOptions : public llvm::RefCountedBase<PreprocessorOptions> {
+class PreprocessorOptions : public RefCountedBase<PreprocessorOptions> {
public:
std::vector<std::pair<std::string, bool/*isUndef*/> > Macros;
std::vector<std::string> Includes;
std::vector<std::string> MacroIncludes;
- unsigned UsePredefines : 1; /// Initialize the preprocessor with the compiler
- /// and target specific predefines.
+ /// \brief Initialize the preprocessor with the compiler and target specific
+ /// predefines.
+ unsigned UsePredefines : 1;
+
+ /// \brief Whether we should maintain a detailed record of all macro
+ /// definitions and expansions.
+ unsigned DetailedRecord : 1;
- unsigned DetailedRecord : 1; /// Whether we should maintain a detailed
- /// record of all macro definitions and
- /// expansions.
- unsigned DetailedRecordConditionalDirectives : 1; /// Whether in the
- /// preprocessing record we should also keep
- /// track of locations of conditional directives
- /// in non-system files.
-
/// The implicit PCH included at the start of the translation unit, or empty.
std::string ImplicitPCHInclude;
@@ -119,14 +118,28 @@ public:
/// with support for lifetime-qualified pointers.
ObjCXXARCStandardLibraryKind ObjCXXARCStandardLibrary;
- /// \brief The path of modules being build, which is used to detect
- /// cycles in the module dependency graph as modules are being built.
- ///
- /// There is no way to set this value from the command line. If we ever need
- /// to do so (e.g., if on-demand module construction moves out-of-process),
- /// we can add a cc1-level option to do so.
- SmallVector<std::string, 2> ModuleBuildPath;
+ /// \brief Records the set of modules
+ class FailedModulesSet : public RefCountedBase<FailedModulesSet> {
+ llvm::StringSet<> Failed;
+
+ public:
+ bool hasAlreadyFailed(StringRef module) {
+ return Failed.count(module) > 0;
+ }
+
+ void addFailed(StringRef module) {
+ Failed.insert(module);
+ }
+ };
+ /// \brief The set of modules that failed to build.
+ ///
+ /// This pointer will be shared among all of the compiler instances created
+ /// to (re)build modules, so that once a module fails to build anywhere,
+ /// other instances will see that the module has failed and won't try to
+ /// build it again.
+ IntrusiveRefCntPtr<FailedModulesSet> FailedModules;
+
typedef std::vector<std::pair<std::string, std::string> >::iterator
remapped_file_iterator;
typedef std::vector<std::pair<std::string, std::string> >::const_iterator
@@ -163,7 +176,6 @@ public:
public:
PreprocessorOptions() : UsePredefines(true), DetailedRecord(false),
- DetailedRecordConditionalDirectives(false),
DisablePCHValidation(false),
AllowPCHWithCompilerErrors(false),
DumpDeserializedPCHDecls(false),
diff --git a/include/clang/Lex/Token.h b/include/clang/Lex/Token.h
index 50b86c84e571..bcbe9c913be1 100644
--- a/include/clang/Lex/Token.h
+++ b/include/clang/Lex/Token.h
@@ -14,10 +14,10 @@
#ifndef LLVM_CLANG_TOKEN_H
#define LLVM_CLANG_TOKEN_H
+#include "clang/Basic/OperatorKinds.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/TemplateKinds.h"
#include "clang/Basic/TokenKinds.h"
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/OperatorKinds.h"
#include <cstdlib>
namespace clang {
@@ -74,9 +74,10 @@ public:
StartOfLine = 0x01, // At start of line or only after whitespace.
LeadingSpace = 0x02, // Whitespace exists before this token.
DisableExpand = 0x04, // This identifier may never be macro expanded.
- NeedsCleaning = 0x08, // Contained an escaped newline or trigraph.
+ NeedsCleaning = 0x08, // Contained an escaped newline or trigraph.
LeadingEmptyMacro = 0x10, // Empty macro exists before this token.
- HasUDSuffix = 0x20 // This string or character literal has a ud-suffix.
+ HasUDSuffix = 0x20, // This string or character literal has a ud-suffix.
+ HasUCN = 0x40 // This identifier contains a UCN.
};
tok::TokenKind getKind() const { return (tok::TokenKind)Kind; }
@@ -257,6 +258,9 @@ public:
/// \brief Return true if this token is a string or character literal which
/// has a ud-suffix.
bool hasUDSuffix() const { return (Flags & HasUDSuffix) ? true : false; }
+
+ /// Returns true if this token contains a universal character name.
+ bool hasUCN() const { return (Flags & HasUCN) ? true : false; }
};
/// \brief Information about the conditional stack (\#if directives)
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index c433344602c6..8cc60a29dfa3 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -14,11 +14,13 @@
#ifndef LLVM_CLANG_PARSE_PARSER_H
#define LLVM_CLANG_PARSE_PARSER_H
+#include "clang/Basic/OpenMPKinds.h"
+#include "clang/Basic/OperatorPrecedence.h"
#include "clang/Basic/Specifiers.h"
-#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/CodeCompletionHandler.h"
-#include "clang/Sema/Sema.h"
+#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/Sema.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Compiler.h"
@@ -44,39 +46,6 @@ namespace clang {
class PoisonSEHIdentifiersRAIIObject;
class VersionTuple;
-/// PrettyStackTraceParserEntry - If a crash happens while the parser is active,
-/// an entry is printed for it.
-class PrettyStackTraceParserEntry : public llvm::PrettyStackTraceEntry {
- const Parser &P;
-public:
- PrettyStackTraceParserEntry(const Parser &p) : P(p) {}
- virtual void print(raw_ostream &OS) const;
-};
-
-/// PrecedenceLevels - These are precedences for the binary/ternary
-/// operators in the C99 grammar. These have been named to relate
-/// with the C99 grammar productions. Low precedences numbers bind
-/// more weakly than high numbers.
-namespace prec {
- enum Level {
- Unknown = 0, // Not binary operator.
- Comma = 1, // ,
- Assignment = 2, // =, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |=
- Conditional = 3, // ?
- LogicalOr = 4, // ||
- LogicalAnd = 5, // &&
- InclusiveOr = 6, // |
- ExclusiveOr = 7, // ^
- And = 8, // &
- Equality = 9, // ==, !=
- Relational = 10, // >=, <=, >, <
- Shift = 11, // <<, >>
- Additive = 12, // -, +
- Multiplicative = 13, // *, /, %
- PointerToMember = 14 // .*, ->*
- };
-}
-
/// Parser - This implements a parser for the C family of languages. After
/// parsing units of the grammar, productions are invoked to handle whatever has
/// been read.
@@ -179,6 +148,7 @@ class Parser : public CodeCompletionHandler {
OwningPtr<PragmaHandler> FPContractHandler;
OwningPtr<PragmaHandler> OpenCLExtensionHandler;
OwningPtr<CommentHandler> CommentSemaHandler;
+ OwningPtr<PragmaHandler> OpenMPHandler;
/// Whether the '>' token acts as an operator or not. This will be
/// true except when we are parsing an expression within a C++
@@ -255,15 +225,6 @@ public:
typedef llvm::MutableArrayRef<Stmt*> MultiStmtArg;
typedef Sema::FullExprArg FullExprArg;
- /// Adorns a ExprResult with Actions to make it an ExprResult
- ExprResult Owned(ExprResult res) {
- return ExprResult(res);
- }
- /// Adorns a StmtResult with Actions to make it an StmtResult
- StmtResult Owned(StmtResult res) {
- return StmtResult(res);
- }
-
ExprResult ExprError() { return ExprResult(true); }
StmtResult StmtError() { return StmtResult(true); }
@@ -274,10 +235,6 @@ public:
// Parsing methods.
- /// ParseTranslationUnit - All in one method that initializes parses, and
- /// shuts down the parser.
- void ParseTranslationUnit();
-
/// Initialize - Warm up the parser.
///
void Initialize();
@@ -290,12 +247,12 @@ public:
/// This does not work with all kinds of tokens: strings and specific other
/// tokens must be consumed with custom methods below. This returns the
/// location of the consumed token.
- SourceLocation ConsumeToken() {
+ SourceLocation ConsumeToken(bool ConsumeCodeCompletionTok = false) {
assert(!isTokenStringLiteral() && !isTokenParen() && !isTokenBracket() &&
!isTokenBrace() &&
"Should consume special tokens with Consume*Token");
- if (Tok.is(tok::code_completion))
+ if (!ConsumeCodeCompletionTok && Tok.is(tok::code_completion))
return handleUnexpectedCodeCompletionToken();
PrevTokLocation = Tok.getLocation();
@@ -324,11 +281,7 @@ private:
/// isTokenStringLiteral - True if this token is a string-literal.
///
bool isTokenStringLiteral() const {
- return Tok.getKind() == tok::string_literal ||
- Tok.getKind() == tok::wide_string_literal ||
- Tok.getKind() == tok::utf8_string_literal ||
- Tok.getKind() == tok::utf16_string_literal ||
- Tok.getKind() == tok::utf32_string_literal;
+ return tok::isStringLiteral(Tok.getKind());
}
/// \brief Returns true if the current token is '=' or is a type of '='.
@@ -338,7 +291,7 @@ private:
/// ConsumeAnyToken - Dispatch to the right Consume* method based on the
/// current token type. This should only be used in cases where the type of
/// the token really isn't known, e.g. in error recovery.
- SourceLocation ConsumeAnyToken() {
+ SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok = false) {
if (isTokenParen())
return ConsumeParen();
else if (isTokenBracket())
@@ -348,7 +301,7 @@ private:
else if (isTokenStringLiteral())
return ConsumeStringToken();
else
- return ConsumeToken();
+ return ConsumeToken(ConsumeCodeCompletionTok);
}
/// ConsumeParen - This consume method keeps the paren count up-to-date.
@@ -849,7 +802,7 @@ private:
};
// A list of late-parsed attributes. Used by ParseGNUAttributes.
- class LateParsedAttrList: public llvm::SmallVector<LateParsedAttribute*, 2> {
+ class LateParsedAttrList: public SmallVector<LateParsedAttribute *, 2> {
public:
LateParsedAttrList(bool PSoon = false) : ParseSoon(PSoon) { }
@@ -869,7 +822,7 @@ private:
/// \brief Whether this member function had an associated template
/// scope. When true, D is a template declaration.
- /// othewise, it is a member function declaration.
+ /// otherwise, it is a member function declaration.
bool TemplateScope;
explicit LexedMethod(Parser* P, Decl *MD)
@@ -1097,7 +1050,8 @@ private:
void DeallocateParsedClasses(ParsingClass *Class);
void PopParsingClass(Sema::ParsingClassState);
- Decl *ParseCXXInlineMethodDef(AccessSpecifier AS, AttributeList *AccessAttrs,
+ NamedDecl *ParseCXXInlineMethodDef(AccessSpecifier AS,
+ AttributeList *AccessAttrs,
ParsingDeclarator &D,
const ParsedTemplateInfo &TemplateInfo,
const VirtSpecifiers& VS,
@@ -1159,10 +1113,15 @@ private:
ExprResult ParseAsmStringLiteral();
// Objective-C External Declarations
+ void MaybeSkipAttributes(tok::ObjCKeywordKind Kind);
DeclGroupPtrTy ParseObjCAtDirectives();
DeclGroupPtrTy ParseObjCAtClassDeclaration(SourceLocation atLoc);
Decl *ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
ParsedAttributes &prefixAttrs);
+ void HelperActionsForIvarDeclarations(Decl *interfaceDecl, SourceLocation atLoc,
+ BalancedDelimiterTracker &T,
+ SmallVectorImpl<Decl *> &AllIvarDecls,
+ bool RBraceMissing);
void ParseObjCClassInstanceVariables(Decl *interfaceDecl,
tok::ObjCKeywordKind visibility,
SourceLocation atLoc);
@@ -1289,7 +1248,7 @@ private:
SmallVectorImpl<SourceLocation> &CommaLocs,
void (Sema::*Completer)(Scope *S,
Expr *Data,
- llvm::ArrayRef<Expr *> Args) = 0,
+ ArrayRef<Expr *> Args) = 0,
Expr *Data = 0);
/// ParenParseOption - Control what ParseParenExpression will parse.
@@ -1332,7 +1291,8 @@ private:
ParsedType ObjectType,
bool EnteringContext,
bool *MayBePseudoDestructor = 0,
- bool IsTypename = false);
+ bool IsTypename = false,
+ IdentifierInfo **LastII = 0);
void CheckForLParenAfterColonColon();
@@ -1342,7 +1302,7 @@ private:
// [...] () -> type {...}
ExprResult ParseLambdaExpression();
ExprResult TryParseLambdaExpression();
- llvm::Optional<unsigned> ParseLambdaIntroducer(LambdaIntroducer &Intro);
+ Optional<unsigned> ParseLambdaIntroducer(LambdaIntroducer &Intro);
bool TryParseLambdaIntroducer(LambdaIntroducer &Intro);
ExprResult ParseLambdaExpressionAfterIntroducer(
LambdaIntroducer &Intro);
@@ -1637,7 +1597,8 @@ private:
bool ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
const ParsedTemplateInfo &TemplateInfo,
- AccessSpecifier AS, DeclSpecContext DSC);
+ AccessSpecifier AS, DeclSpecContext DSC,
+ ParsedAttributesWithRange &Attrs);
DeclSpecContext getDeclSpecContextFromDeclaratorContext(unsigned Context);
void ParseDeclarationSpecifiers(DeclSpec &DS,
const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
@@ -1843,7 +1804,8 @@ public:
Declarator::TheContext Context
= Declarator::TypeNameContext,
AccessSpecifier AS = AS_none,
- Decl **OwnedType = 0);
+ Decl **OwnedType = 0,
+ ParsedAttributes *Attrs = 0);
private:
void ParseBlockId(SourceLocation CaretLoc);
@@ -1852,11 +1814,22 @@ private:
// an attribute is not allowed.
bool CheckProhibitedCXX11Attribute() {
assert(Tok.is(tok::l_square));
- if (!getLangOpts().CPlusPlus0x || NextToken().isNot(tok::l_square))
+ if (!getLangOpts().CPlusPlus11 || NextToken().isNot(tok::l_square))
return false;
return DiagnoseProhibitedCXX11Attribute();
}
bool DiagnoseProhibitedCXX11Attribute();
+ void CheckMisplacedCXX11Attribute(ParsedAttributesWithRange &Attrs,
+ SourceLocation CorrectLocation) {
+ if (!getLangOpts().CPlusPlus11)
+ return;
+ if ((Tok.isNot(tok::l_square) || NextToken().isNot(tok::l_square)) &&
+ Tok.isNot(tok::kw_alignas))
+ return;
+ DiagnoseMisplacedCXX11Attribute(Attrs, CorrectLocation);
+ }
+ void DiagnoseMisplacedCXX11Attribute(ParsedAttributesWithRange &Attrs,
+ SourceLocation CorrectLocation);
void ProhibitAttributes(ParsedAttributesWithRange &attrs) {
if (!attrs.Range.isValid()) return;
@@ -1896,26 +1869,26 @@ private:
SourceLocation ScopeLoc,
AttributeList::Syntax Syntax);
- void MaybeParseCXX0XAttributes(Declarator &D) {
- if (getLangOpts().CPlusPlus0x && isCXX11AttributeSpecifier()) {
+ void MaybeParseCXX11Attributes(Declarator &D) {
+ if (getLangOpts().CPlusPlus11 && isCXX11AttributeSpecifier()) {
ParsedAttributesWithRange attrs(AttrFactory);
SourceLocation endLoc;
ParseCXX11Attributes(attrs, &endLoc);
D.takeAttributes(attrs, endLoc);
}
}
- void MaybeParseCXX0XAttributes(ParsedAttributes &attrs,
+ void MaybeParseCXX11Attributes(ParsedAttributes &attrs,
SourceLocation *endLoc = 0) {
- if (getLangOpts().CPlusPlus0x && isCXX11AttributeSpecifier()) {
+ if (getLangOpts().CPlusPlus11 && isCXX11AttributeSpecifier()) {
ParsedAttributesWithRange attrsWithRange(AttrFactory);
ParseCXX11Attributes(attrsWithRange, endLoc);
attrs.takeAllFrom(attrsWithRange);
}
}
- void MaybeParseCXX0XAttributes(ParsedAttributesWithRange &attrs,
+ void MaybeParseCXX11Attributes(ParsedAttributesWithRange &attrs,
SourceLocation *endLoc = 0,
bool OuterMightBeMessageSend = false) {
- if (getLangOpts().CPlusPlus0x &&
+ if (getLangOpts().CPlusPlus11 &&
isCXX11AttributeSpecifier(false, OuterMightBeMessageSend))
ParseCXX11Attributes(attrs, endLoc);
}
@@ -1954,7 +1927,7 @@ private:
ParsedAttributes &attrs,
SourceLocation *endLoc);
- bool IsThreadSafetyAttribute(llvm::StringRef AttrName);
+ bool IsThreadSafetyAttribute(StringRef AttrName);
void ParseThreadSafetyAttribute(IdentifierInfo &AttrName,
SourceLocation AttrNameLoc,
ParsedAttributes &Attrs,
@@ -1978,13 +1951,13 @@ private:
void ParseAlignmentSpecifier(ParsedAttributes &Attrs,
SourceLocation *endLoc = 0);
- VirtSpecifiers::Specifier isCXX0XVirtSpecifier(const Token &Tok) const;
- VirtSpecifiers::Specifier isCXX0XVirtSpecifier() const {
- return isCXX0XVirtSpecifier(Tok);
+ VirtSpecifiers::Specifier isCXX11VirtSpecifier(const Token &Tok) const;
+ VirtSpecifiers::Specifier isCXX11VirtSpecifier() const {
+ return isCXX11VirtSpecifier(Tok);
}
- void ParseOptionalCXX0XVirtSpecifierSeq(VirtSpecifiers &VS, bool IsInterface);
+ void ParseOptionalCXX11VirtSpecifierSeq(VirtSpecifiers &VS, bool IsInterface);
- bool isCXX0XFinalKeyword() const;
+ bool isCXX11FinalKeyword() const;
/// DeclaratorScopeObj - RAII object used in Parser::ParseDirectDeclarator to
/// enter a new C++ declarator scope and exit it when the function is
@@ -2027,7 +2000,8 @@ private:
DirectDeclParseFunction DirectDeclParser);
void ParseTypeQualifierListOpt(DeclSpec &DS, bool GNUAttributesAllowed = true,
- bool CXX0XAttributesAllowed = true);
+ bool CXX11AttributesAllowed = true,
+ bool AtomicAllowed = true);
void ParseDirectDeclarator(Declarator &D);
void ParseParenDeclarator(Declarator &D);
void ParseFunctionDeclarator(Declarator &D,
@@ -2098,8 +2072,12 @@ private:
void ParseClassSpecifier(tok::TokenKind TagTokKind, SourceLocation TagLoc,
DeclSpec &DS, const ParsedTemplateInfo &TemplateInfo,
AccessSpecifier AS, bool EnteringContext,
- DeclSpecContext DSC);
- void ParseCXXMemberSpecification(SourceLocation StartLoc, unsigned TagType,
+ DeclSpecContext DSC,
+ ParsedAttributesWithRange &Attributes);
+ void ParseCXXMemberSpecification(SourceLocation StartLoc,
+ SourceLocation AttrFixitLoc,
+ ParsedAttributesWithRange &Attrs,
+ unsigned TagType,
Decl *TagDecl);
ExprResult ParseCXXMemberInitializer(Decl *D, bool IsFunction,
SourceLocation &EqualLoc);
@@ -2131,6 +2109,11 @@ private:
ParsedType ObjectType,
UnqualifiedId &Result);
+ //===--------------------------------------------------------------------===//
+ // OpenMP: Directives and clauses.
+ DeclGroupPtrTy ParseOpenMPDeclarativeDirective();
+ bool ParseOpenMPSimpleVarList(OpenMPDirectiveKind Kind,
+ SmallVectorImpl<DeclarationNameInfo> &IdList);
public:
bool ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
bool AllowDestructorName,
@@ -2173,6 +2156,8 @@ private:
// C++ 14.3: Template arguments [temp.arg]
typedef SmallVector<ParsedTemplateArgument, 16> TemplateArgList;
+ bool ParseGreaterThanInTemplateList(SourceLocation &RAngleLoc,
+ bool ConsumeLastToken);
bool ParseTemplateIdAfterTemplateName(TemplateTy Template,
SourceLocation TemplateNameLoc,
const CXXScopeSpec &SS,
diff --git a/include/clang/Rewrite/Core/RewriteRope.h b/include/clang/Rewrite/Core/RewriteRope.h
index 9f1bbe501318..a5192ef1ea1c 100644
--- a/include/clang/Rewrite/Core/RewriteRope.h
+++ b/include/clang/Rewrite/Core/RewriteRope.h
@@ -15,10 +15,9 @@
#define LLVM_CLANG_REWRITEROPE_H
#include "llvm/Support/Compiler.h"
-
-#include <cstring>
#include <cassert>
#include <cstddef>
+#include <cstring>
#include <iterator>
namespace clang {
diff --git a/include/clang/Rewrite/Core/Rewriter.h b/include/clang/Rewrite/Core/Rewriter.h
index a33ea134a7ac..cb044aef23fe 100644
--- a/include/clang/Rewrite/Core/Rewriter.h
+++ b/include/clang/Rewrite/Core/Rewriter.h
@@ -52,7 +52,11 @@ public:
iterator end() const { return Buffer.end(); }
unsigned size() const { return Buffer.size(); }
- raw_ostream &write(raw_ostream &) const;
+ /// \brief Write to \p Stream the result of applying all changes to the
+ /// original buffer.
+ ///
+ /// The original buffer is not actually changed.
+ raw_ostream &write(raw_ostream &Stream) const;
/// RemoveText - Remove the specified text.
void RemoveText(unsigned OrigOffset, unsigned Size,
@@ -279,7 +283,7 @@ public:
buffer_iterator buffer_begin() { return RewriteBuffers.begin(); }
buffer_iterator buffer_end() { return RewriteBuffers.end(); }
- /// SaveFiles - Save all changed files to disk.
+ /// overwriteChangedFiles - Save all changed files to disk.
///
/// Returns whether not all changes were saved successfully.
/// Outputs diagnostics via the source manager's diagnostic engine
diff --git a/include/clang/Rewrite/Frontend/ASTConsumers.h b/include/clang/Rewrite/Frontend/ASTConsumers.h
index c9c92e3a0188..584af3fa18b0 100644
--- a/include/clang/Rewrite/Frontend/ASTConsumers.h
+++ b/include/clang/Rewrite/Frontend/ASTConsumers.h
@@ -35,7 +35,8 @@ ASTConsumer *CreateModernObjCRewriter(const std::string &InFile,
raw_ostream *OS,
DiagnosticsEngine &Diags,
const LangOptions &LOpts,
- bool SilenceRewriteMacroWarning);
+ bool SilenceRewriteMacroWarning,
+ bool LineInfo);
/// CreateHTMLPrinter - Create an AST consumer which rewrites source code to
/// HTML with syntax highlighting suitable for viewing in a web-browser.
diff --git a/include/clang/Rewrite/Frontend/FixItRewriter.h b/include/clang/Rewrite/Frontend/FixItRewriter.h
index f12a034bd716..04c04a25f549 100644
--- a/include/clang/Rewrite/Frontend/FixItRewriter.h
+++ b/include/clang/Rewrite/Frontend/FixItRewriter.h
@@ -17,8 +17,8 @@
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceLocation.h"
-#include "clang/Rewrite/Core/Rewriter.h"
#include "clang/Edit/EditedSource.h"
+#include "clang/Rewrite/Core/Rewriter.h"
namespace clang {
diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h
index 2e8b0c03f770..0f0d2185b0c6 100644
--- a/include/clang/Sema/AttributeList.h
+++ b/include/clang/Sema/AttributeList.h
@@ -15,11 +15,11 @@
#ifndef LLVM_CLANG_SEMA_ATTRLIST_H
#define LLVM_CLANG_SEMA_ATTRLIST_H
-#include "llvm/Support/Allocator.h"
-#include "llvm/ADT/SmallVector.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/VersionTuple.h"
#include "clang/Sema/Ownership.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Allocator.h"
#include <cassert>
namespace clang {
@@ -44,8 +44,9 @@ struct AvailabilityChange {
bool isValid() const { return !Version.empty(); }
};
-/// AttributeList - Represents GCC's __attribute__ declaration. There are
-/// 4 forms of this construct...they are:
+/// AttributeList - Represents a syntactic attribute.
+///
+/// For a GNU attribute, there are four forms of this construct:
///
/// 1: __attribute__(( const )). ParmName/Args/NumArgs will all be unused.
/// 2: __attribute__(( mode(byte) )). ParmName used, Args/NumArgs unused.
@@ -56,12 +57,14 @@ class AttributeList { // TODO: This should really be called ParsedAttribute
public:
/// The style used to specify an attribute.
enum Syntax {
+ /// __attribute__((...))
AS_GNU,
+ /// [[...]]
AS_CXX11,
+ /// __declspec(...)
AS_Declspec,
- // eg) __w64, __ptr32, etc. It is implied that an MSTypespec is also
- // a declspec.
- AS_MSTypespec
+ /// __ptr16, alignas(...), etc.
+ AS_Keyword
};
private:
IdentifierInfo *AttrName;
@@ -70,6 +73,7 @@ private:
SourceRange AttrRange;
SourceLocation ScopeLoc;
SourceLocation ParmLoc;
+ SourceLocation EllipsisLoc;
/// The number of expression arguments this attribute has.
/// The expressions themselves are stored after the object.
@@ -140,6 +144,14 @@ private:
return *reinterpret_cast<const TypeTagForDatatypeData *>(this + 1);
}
+ ParsedType &getTypeBuffer() {
+ return *reinterpret_cast<ParsedType *>(this + 1);
+ }
+
+ const ParsedType &getTypeBuffer() const {
+ return *reinterpret_cast<const ParsedType *>(this + 1);
+ }
+
AttributeList(const AttributeList &) LLVM_DELETED_FUNCTION;
void operator=(const AttributeList &) LLVM_DELETED_FUNCTION;
void operator delete(void *) LLVM_DELETED_FUNCTION;
@@ -152,11 +164,11 @@ private:
IdentifierInfo *scopeName, SourceLocation scopeLoc,
IdentifierInfo *parmName, SourceLocation parmLoc,
Expr **args, unsigned numArgs,
- Syntax syntaxUsed)
+ Syntax syntaxUsed, SourceLocation ellipsisLoc)
: AttrName(attrName), ScopeName(scopeName), ParmName(parmName),
AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc),
- NumArgs(numArgs), SyntaxUsed(syntaxUsed), Invalid(false),
- UsedAsTypeAttr(false), IsAvailability(false),
+ EllipsisLoc(ellipsisLoc), NumArgs(numArgs), SyntaxUsed(syntaxUsed),
+ Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
IsTypeTagForDatatype(false), NextInPosition(0), NextInPool(0) {
if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(Expr*));
AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
@@ -173,7 +185,7 @@ private:
const Expr *messageExpr,
Syntax syntaxUsed)
: AttrName(attrName), ScopeName(scopeName), ParmName(parmName),
- AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc),
+ AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc), EllipsisLoc(),
NumArgs(0), SyntaxUsed(syntaxUsed),
Invalid(false), UsedAsTypeAttr(false), IsAvailability(true),
IsTypeTagForDatatype(false),
@@ -194,7 +206,7 @@ private:
bool mustBeNull, Syntax syntaxUsed)
: AttrName(attrName), ScopeName(scopeName), ParmName(argumentKindName),
AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(argumentKindLoc),
- NumArgs(0), SyntaxUsed(syntaxUsed),
+ EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed),
Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
IsTypeTagForDatatype(true), NextInPosition(NULL), NextInPool(NULL) {
TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot();
@@ -204,6 +216,20 @@ private:
AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
}
+ /// Constructor for attributes with a single type argument.
+ AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ IdentifierInfo *parmName, SourceLocation parmLoc,
+ ParsedType typeArg, Syntax syntaxUsed)
+ : AttrName(attrName), ScopeName(scopeName), ParmName(parmName),
+ AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc),
+ EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(false),
+ UsedAsTypeAttr(false), IsAvailability(false),
+ IsTypeTagForDatatype(false), NextInPosition(0), NextInPool(0) {
+ new (&getTypeBuffer()) ParsedType(typeArg);
+ AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
+ }
+
friend class AttributePool;
friend class AttributeFactory;
@@ -227,12 +253,16 @@ public:
IdentifierInfo *getParameterName() const { return ParmName; }
SourceLocation getParameterLoc() const { return ParmLoc; }
- /// Returns true if the attribute is a pure __declspec or a synthesized
- /// declspec representing a type specification (like __w64 or __ptr32).
- bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec ||
- SyntaxUsed == AS_MSTypespec; }
- bool isCXX0XAttribute() const { return SyntaxUsed == AS_CXX11; }
- bool isMSTypespecAttribute() const { return SyntaxUsed == AS_MSTypespec; }
+ bool isAlignasAttribute() const {
+ // FIXME: Use a better mechanism to determine this.
+ return getKind() == AT_Aligned && SyntaxUsed == AS_Keyword;
+ }
+
+ bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; }
+ bool isCXX11Attribute() const {
+ return SyntaxUsed == AS_CXX11 || isAlignasAttribute();
+ }
+ bool isKeywordAttribute() const { return SyntaxUsed == AS_Keyword; }
bool isInvalid() const { return Invalid; }
void setInvalid(bool b = true) const { Invalid = b; }
@@ -240,6 +270,9 @@ public:
bool isUsedAsTypeAttr() const { return UsedAsTypeAttr; }
void setUsedAsTypeAttr() { UsedAsTypeAttr = true; }
+ bool isPackExpansion() const { return EllipsisLoc.isValid(); }
+ SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
+
Kind getKind() const { return Kind(AttrKind); }
static Kind getKind(const IdentifierInfo *Name, const IdentifierInfo *Scope,
Syntax SyntaxUsed);
@@ -340,6 +373,16 @@ public:
"Not a type_tag_for_datatype attribute");
return getTypeTagForDatatypeDataSlot().MustBeNull;
}
+
+ const ParsedType &getTypeArg() const {
+ assert(getKind() == AT_VecTypeHint && "Not a type attribute");
+ return getTypeBuffer();
+ }
+
+ /// \brief Get an index into the attribute spelling list
+ /// defined in Attr.td. This index is used by an attribute
+ /// to pretty print itself.
+ unsigned getAttributeSpellingListIndex() const;
};
/// A factory, from which one makes pools, from which one creates
@@ -448,13 +491,15 @@ public:
IdentifierInfo *scopeName, SourceLocation scopeLoc,
IdentifierInfo *parmName, SourceLocation parmLoc,
Expr **args, unsigned numArgs,
- AttributeList::Syntax syntax) {
+ AttributeList::Syntax syntax,
+ SourceLocation ellipsisLoc = SourceLocation()) {
void *memory = allocate(sizeof(AttributeList)
+ numArgs * sizeof(Expr*));
return add(new (memory) AttributeList(attrName, attrRange,
scopeName, scopeLoc,
parmName, parmLoc,
- args, numArgs, syntax));
+ args, numArgs, syntax,
+ ellipsisLoc));
}
AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
@@ -491,6 +536,18 @@ public:
matchingCType, layoutCompatible,
mustBeNull, syntax));
}
+
+ AttributeList *createTypeAttribute(
+ IdentifierInfo *attrName, SourceRange attrRange,
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ IdentifierInfo *parmName, SourceLocation parmLoc,
+ ParsedType typeArg, AttributeList::Syntax syntaxUsed) {
+ void *memory = allocate(sizeof(AttributeList) + sizeof(void *));
+ return add(new (memory) AttributeList(attrName, attrRange,
+ scopeName, scopeLoc,
+ parmName, parmLoc,
+ typeArg, syntaxUsed));
+ }
};
/// addAttributeLists - Add two AttributeLists together
@@ -511,18 +568,18 @@ inline AttributeList *addAttributeLists(AttributeList *Left,
return Left;
}
-/// CXX0XAttributeList - A wrapper around a C++0x attribute list.
+/// CXX11AttributeList - A wrapper around a C++11 attribute list.
/// Stores, in addition to the list proper, whether or not an actual list was
/// (as opposed to an empty list, which may be ill-formed in some places) and
/// the source range of the list.
-struct CXX0XAttributeList {
+struct CXX11AttributeList {
AttributeList *AttrList;
SourceRange Range;
bool HasAttr;
- CXX0XAttributeList (AttributeList *attrList, SourceRange range, bool hasAttr)
+ CXX11AttributeList (AttributeList *attrList, SourceRange range, bool hasAttr)
: AttrList(attrList), Range(range), HasAttr (hasAttr) {
}
- CXX0XAttributeList ()
+ CXX11AttributeList ()
: AttrList(0), Range(), HasAttr(false) {
}
};
@@ -588,10 +645,11 @@ public:
IdentifierInfo *scopeName, SourceLocation scopeLoc,
IdentifierInfo *parmName, SourceLocation parmLoc,
Expr **args, unsigned numArgs,
- AttributeList::Syntax syntax) {
+ AttributeList::Syntax syntax,
+ SourceLocation ellipsisLoc = SourceLocation()) {
AttributeList *attr =
pool.create(attrName, attrRange, scopeName, scopeLoc, parmName, parmLoc,
- args, numArgs, syntax);
+ args, numArgs, syntax, ellipsisLoc);
add(attr);
return attr;
}
@@ -632,6 +690,19 @@ public:
return attr;
}
+ /// Add an attribute with a single type argument.
+ AttributeList *
+ addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange,
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ IdentifierInfo *parmName, SourceLocation parmLoc,
+ ParsedType typeArg, AttributeList::Syntax syntaxUsed) {
+ AttributeList *attr =
+ pool.createTypeAttribute(attrName, attrRange, scopeName, scopeLoc,
+ parmName, parmLoc, typeArg, syntaxUsed);
+ add(attr);
+ return attr;
+ }
+
AttributeList *addNewInteger(ASTContext &C, IdentifierInfo *name,
SourceLocation loc, int arg) {
AttributeList *attr =
diff --git a/include/clang/Sema/CMakeLists.txt b/include/clang/Sema/CMakeLists.txt
index 03f99a363035..6b5d222b5d56 100644
--- a/include/clang/Sema/CMakeLists.txt
+++ b/include/clang/Sema/CMakeLists.txt
@@ -11,4 +11,9 @@ clang_tablegen(AttrParsedAttrList.inc -gen-clang-attr-parsed-attr-list
clang_tablegen(AttrParsedAttrKinds.inc -gen-clang-attr-parsed-attr-kinds
-I ${CMAKE_CURRENT_SOURCE_DIR}/../../
SOURCE ../Basic/Attr.td
- TARGET ClangAttrParsedAttrKinds) \ No newline at end of file
+ TARGET ClangAttrParsedAttrKinds)
+
+clang_tablegen(AttrSpellingListIndex.inc -gen-clang-attr-spelling-index
+ -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
+ SOURCE ../Basic/Attr.td
+ TARGET ClangAttrSpellingListIndex)
diff --git a/include/clang/Sema/CXXFieldCollector.h b/include/clang/Sema/CXXFieldCollector.h
index 6f3c0b44b148..6685751d1e61 100644
--- a/include/clang/Sema/CXXFieldCollector.h
+++ b/include/clang/Sema/CXXFieldCollector.h
@@ -15,6 +15,7 @@
#ifndef LLVM_CLANG_SEMA_CXXFIELDCOLLECTOR_H
#define LLVM_CLANG_SEMA_CXXFIELDCOLLECTOR_H
+#include "clang/Basic/LLVM.h"
#include "llvm/ADT/SmallVector.h"
namespace clang {
diff --git a/include/clang/Sema/CodeCompleteConsumer.h b/include/clang/Sema/CodeCompleteConsumer.h
index b128bd866903..a1ddec7520ad 100644
--- a/include/clang/Sema/CodeCompleteConsumer.h
+++ b/include/clang/Sema/CodeCompleteConsumer.h
@@ -13,13 +13,13 @@
#ifndef LLVM_CLANG_SEMA_CODECOMPLETECONSUMER_H
#define LLVM_CLANG_SEMA_CODECOMPLETECONSUMER_H
-#include "clang/AST/Type.h"
+#include "clang-c/Index.h"
#include "clang/AST/CanonicalType.h"
+#include "clang/AST/Type.h"
#include "clang/Sema/CodeCompleteOptions.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
-#include "clang-c/Index.h"
#include <string>
namespace clang {
@@ -121,7 +121,7 @@ SimplifiedTypeClass getSimplifiedTypeClass(CanQualType T);
/// \brief Determine the type that this declaration will have if it is used
/// as a type or in an expression.
-QualType getDeclUsageType(ASTContext &C, NamedDecl *ND);
+QualType getDeclUsageType(ASTContext &C, const NamedDecl *ND);
/// \brief Determine the priority to be given to a macro code completion result
/// with the given name.
@@ -138,7 +138,7 @@ unsigned getMacroUsagePriority(StringRef MacroName,
/// \brief Determine the libclang cursor kind associated with the given
/// declaration.
-CXCursorKind getCursorKindForDecl(Decl *D);
+CXCursorKind getCursorKindForDecl(const Decl *D);
class FunctionDecl;
class FunctionType;
@@ -245,7 +245,8 @@ public:
/// \brief Code completion in a parenthesized expression, which means that
/// we may also have types here in C and Objective-C (as well as in C++).
CCC_ParenthesizedExpression,
- /// \brief Code completion where an Objective-C instance message is expcted.
+ /// \brief Code completion where an Objective-C instance message is
+ /// expected.
CCC_ObjCInstanceMessage,
/// \brief Code completion where an Objective-C class message is expected.
CCC_ObjCClassMessage,
@@ -530,7 +531,7 @@ class GlobalCodeCompletionAllocator
};
class CodeCompletionTUInfo {
- llvm::DenseMap<DeclContext *, StringRef> ParentNames;
+ llvm::DenseMap<const DeclContext *, StringRef> ParentNames;
IntrusiveRefCntPtr<GlobalCodeCompletionAllocator> AllocatorRef;
public:
@@ -546,7 +547,7 @@ public:
return *AllocatorRef;
}
- StringRef getParentName(DeclContext *DC);
+ StringRef getParentName(const DeclContext *DC);
};
} // end namespace clang
@@ -629,8 +630,9 @@ public:
void AddAnnotation(const char *A) { Annotations.push_back(A); }
/// \brief Add the parent context information to this code completion.
- void addParentContext(DeclContext *DC);
+ void addParentContext(const DeclContext *DC);
+ const char *getBriefComment() const { return BriefComment; }
void addBriefComment(StringRef Comment);
StringRef getParentName() const { return ParentName; }
@@ -649,7 +651,7 @@ public:
/// \brief When Kind == RK_Declaration or RK_Pattern, the declaration we are
/// referring to. In the latter case, the declaration might be NULL.
- NamedDecl *Declaration;
+ const NamedDecl *Declaration;
union {
/// \brief When Kind == RK_Keyword, the string representing the keyword
@@ -661,7 +663,7 @@ public:
CodeCompletionString *Pattern;
/// \brief When Kind == RK_Macro, the identifier that refers to a macro.
- IdentifierInfo *Macro;
+ const IdentifierInfo *Macro;
};
/// \brief The priority of this particular code-completion result.
@@ -704,11 +706,12 @@ public:
NestedNameSpecifier *Qualifier;
/// \brief Build a result that refers to a declaration.
- CodeCompletionResult(NamedDecl *Declaration,
+ CodeCompletionResult(const NamedDecl *Declaration,
+ unsigned Priority,
NestedNameSpecifier *Qualifier = 0,
bool QualifierIsInformative = false,
bool Accessible = true)
- : Declaration(Declaration), Priority(getPriorityFromDecl(Declaration)),
+ : Declaration(Declaration), Priority(Priority),
StartParameter(0), Kind(RK_Declaration),
Availability(CXAvailability_Available), Hidden(false),
QualifierIsInformative(QualifierIsInformative),
@@ -728,7 +731,8 @@ public:
}
/// \brief Build a result that refers to a macro.
- CodeCompletionResult(IdentifierInfo *Macro, unsigned Priority = CCP_Macro)
+ CodeCompletionResult(const IdentifierInfo *Macro,
+ unsigned Priority = CCP_Macro)
: Declaration(0), Macro(Macro), Priority(Priority), StartParameter(0),
Kind(RK_Macro), CursorKind(CXCursor_MacroDefinition),
Availability(CXAvailability_Available), Hidden(false),
@@ -742,7 +746,7 @@ public:
unsigned Priority = CCP_CodePattern,
CXCursorKind CursorKind = CXCursor_NotImplemented,
CXAvailabilityKind Availability = CXAvailability_Available,
- NamedDecl *D = 0)
+ const NamedDecl *D = 0)
: Declaration(D), Pattern(Pattern), Priority(Priority), StartParameter(0),
Kind(RK_Pattern), CursorKind(CursorKind), Availability(Availability),
Hidden(false), QualifierIsInformative(0),
@@ -763,7 +767,7 @@ public:
}
/// \brief Retrieve the declaration stored in this result.
- NamedDecl *getDeclaration() const {
+ const NamedDecl *getDeclaration() const {
assert(Kind == RK_Declaration && "Not a declaration result");
return Declaration;
}
@@ -791,9 +795,6 @@ public:
CodeCompletionTUInfo &CCTUInfo,
bool IncludeBriefComments);
- /// \brief Determine a base priority for the given declaration.
- static unsigned getPriorityFromDecl(NamedDecl *ND);
-
private:
void computeCursorKindAndAvailability(bool Accessible = true);
};
diff --git a/include/clang/Sema/CodeCompleteOptions.h b/include/clang/Sema/CodeCompleteOptions.h
index 30712dbad116..e43496f55bdb 100644
--- a/include/clang/Sema/CodeCompleteOptions.h
+++ b/include/clang/Sema/CodeCompleteOptions.h
@@ -13,16 +13,16 @@
/// Options controlling the behavior of code completion.
class CodeCompleteOptions {
public:
- ///< Show macros in code completion results.
+ /// Show macros in code completion results.
unsigned IncludeMacros : 1;
- ///< Show code patterns in code completion results.
+ /// Show code patterns in code completion results.
unsigned IncludeCodePatterns : 1;
- ///< Show top-level decls in code completion results.
+ /// Show top-level decls in code completion results.
unsigned IncludeGlobals : 1;
- ///< Show brief documentation comments in code completion results.
+ /// Show brief documentation comments in code completion results.
unsigned IncludeBriefComments : 1;
CodeCompleteOptions() :
diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h
index 0728e8737638..5b90784dcf0f 100644
--- a/include/clang/Sema/DeclSpec.h
+++ b/include/clang/Sema/DeclSpec.h
@@ -23,14 +23,14 @@
#ifndef LLVM_CLANG_SEMA_DECLSPEC_H
#define LLVM_CLANG_SEMA_DECLSPEC_H
-#include "clang/Sema/AttributeList.h"
-#include "clang/Sema/Ownership.h"
#include "clang/AST/NestedNameSpecifier.h"
-#include "clang/Lex/Token.h"
#include "clang/Basic/ExceptionSpecificationType.h"
#include "clang/Basic/Lambda.h"
#include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/Specifiers.h"
+#include "clang/Lex/Token.h"
+#include "clang/Sema/AttributeList.h"
+#include "clang/Sema/Ownership.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
@@ -276,6 +276,14 @@ public:
static const TST TST_auto = clang::TST_auto;
static const TST TST_unknown_anytype = clang::TST_unknown_anytype;
static const TST TST_atomic = clang::TST_atomic;
+ static const TST TST_image1d_t = clang::TST_image1d_t;
+ static const TST TST_image1d_array_t = clang::TST_image1d_array_t;
+ static const TST TST_image1d_buffer_t = clang::TST_image1d_buffer_t;
+ static const TST TST_image2d_t = clang::TST_image2d_t;
+ static const TST TST_image2d_array_t = clang::TST_image2d_array_t;
+ static const TST TST_image3d_t = clang::TST_image3d_t;
+ static const TST TST_sampler_t = clang::TST_sampler_t;
+ static const TST TST_event_t = clang::TST_event_t;
static const TST TST_error = clang::TST_error;
// type-qualifiers
@@ -283,7 +291,10 @@ public:
TQ_unspecified = 0,
TQ_const = 1,
TQ_restrict = 2,
- TQ_volatile = 4
+ TQ_volatile = 4,
+ // This has no corresponding Qualifiers::TQ value, because it's not treated
+ // as a qualifier in our type system.
+ TQ_atomic = 8
};
/// ParsedSpecifiers - Flags to query which specifiers were applied. This is
@@ -306,19 +317,20 @@ private:
/*TSW*/unsigned TypeSpecWidth : 2;
/*TSC*/unsigned TypeSpecComplex : 2;
/*TSS*/unsigned TypeSpecSign : 2;
- /*TST*/unsigned TypeSpecType : 5;
+ /*TST*/unsigned TypeSpecType : 6;
unsigned TypeAltiVecVector : 1;
unsigned TypeAltiVecPixel : 1;
unsigned TypeAltiVecBool : 1;
unsigned TypeSpecOwned : 1;
// type-qualifiers
- unsigned TypeQualifiers : 3; // Bitwise OR of TQ.
+ unsigned TypeQualifiers : 4; // Bitwise OR of TQ.
// function-specifier
unsigned FS_inline_specified : 1;
unsigned FS_virtual_specified : 1;
unsigned FS_explicit_specified : 1;
+ unsigned FS_noreturn_specified : 1;
// friend-specifier
unsigned Friend_specified : 1;
@@ -326,8 +338,6 @@ private:
// constexpr-specifier
unsigned Constexpr_specified : 1;
- /*SCS*/unsigned StorageClassSpecAsWritten : 3;
-
union {
UnionParsedType TypeRep;
Decl *DeclRep;
@@ -360,13 +370,12 @@ private:
/// TSTNameLoc provides source range info for tag types.
SourceLocation TSTNameLoc;
SourceRange TypeofParensRange;
- SourceLocation TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc;
- SourceLocation FS_inlineLoc, FS_virtualLoc, FS_explicitLoc;
+ SourceLocation TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc, TQ_atomicLoc;
+ SourceLocation FS_inlineLoc, FS_virtualLoc, FS_explicitLoc, FS_noreturnLoc;
SourceLocation FriendLoc, ModulePrivateLoc, ConstexprLoc;
WrittenBuiltinSpecs writtenBS;
void SaveWrittenBuiltinSpecs();
- void SaveStorageSpecifierAsWritten();
ObjCDeclSpec *ObjCQualifiers;
@@ -377,16 +386,16 @@ private:
static bool isExprRep(TST T) {
return (T == TST_typeofExpr || T == TST_decltype);
}
+
+ DeclSpec(const DeclSpec &) LLVM_DELETED_FUNCTION;
+ void operator=(const DeclSpec &) LLVM_DELETED_FUNCTION;
+public:
static bool isDeclRep(TST T) {
return (T == TST_enum || T == TST_struct ||
T == TST_interface || T == TST_union ||
T == TST_class);
}
- DeclSpec(const DeclSpec &) LLVM_DELETED_FUNCTION;
- void operator=(const DeclSpec &) LLVM_DELETED_FUNCTION;
-public:
-
DeclSpec(AttributeFactory &attrFactory)
: StorageClassSpec(SCS_unspecified),
SCS_thread_specified(false),
@@ -403,9 +412,9 @@ public:
FS_inline_specified(false),
FS_virtual_specified(false),
FS_explicit_specified(false),
+ FS_noreturn_specified(false),
Friend_specified(false),
Constexpr_specified(false),
- StorageClassSpecAsWritten(SCS_unspecified),
Attrs(attrFactory),
ProtocolQualifiers(0),
NumProtocolQualifiers(0),
@@ -493,6 +502,7 @@ public:
SourceLocation getConstSpecLoc() const { return TQ_constLoc; }
SourceLocation getRestrictSpecLoc() const { return TQ_restrictLoc; }
SourceLocation getVolatileSpecLoc() const { return TQ_volatileLoc; }
+ SourceLocation getAtomicSpecLoc() const { return TQ_atomicLoc; }
/// \brief Clear out all of the type qualifiers.
void ClearTypeQualifiers() {
@@ -500,6 +510,7 @@ public:
TQ_constLoc = SourceLocation();
TQ_restrictLoc = SourceLocation();
TQ_volatileLoc = SourceLocation();
+ TQ_atomicLoc = SourceLocation();
}
// function-specifier
@@ -512,6 +523,9 @@ public:
bool isExplicitSpecified() const { return FS_explicit_specified; }
SourceLocation getExplicitSpecLoc() const { return FS_explicitLoc; }
+ bool isNoreturnSpecified() const { return FS_noreturn_specified; }
+ SourceLocation getNoreturnSpecLoc() const { return FS_noreturnLoc; }
+
void ClearFunctionSpecs() {
FS_inline_specified = false;
FS_inlineLoc = SourceLocation();
@@ -519,6 +533,8 @@ public:
FS_virtualLoc = SourceLocation();
FS_explicit_specified = false;
FS_explicitLoc = SourceLocation();
+ FS_noreturn_specified = false;
+ FS_noreturnLoc = SourceLocation();
}
/// \brief Return true if any type-specifier has been found.
@@ -533,10 +549,6 @@ public:
/// DeclSpec includes.
unsigned getParsedSpecifiers() const;
- SCS getStorageClassSpecAsWritten() const {
- return (SCS)StorageClassSpecAsWritten;
- }
-
/// isEmpty - Return true if this declaration specifier is completely empty:
/// no tokens were parsed in the production of it.
bool isEmpty() const {
@@ -602,12 +614,10 @@ public:
bool SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec,
unsigned &DiagID, const LangOptions &Lang);
- bool SetFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec,
- unsigned &DiagID);
- bool SetFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec,
- unsigned &DiagID);
- bool SetFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec,
- unsigned &DiagID);
+ bool setFunctionSpecInline(SourceLocation Loc);
+ bool setFunctionSpecVirtual(SourceLocation Loc);
+ bool setFunctionSpecExplicit(SourceLocation Loc);
+ bool setFunctionSpecNoreturn(SourceLocation Loc);
bool SetFriendSpec(SourceLocation Loc, const char *&PrevSpec,
unsigned &DiagID);
@@ -808,6 +818,20 @@ public:
IK_ImplicitSelfParam
} Kind;
+ struct OFI {
+ /// \brief The kind of overloaded operator.
+ OverloadedOperatorKind Operator;
+
+ /// \brief The source locations of the individual tokens that name
+ /// the operator, e.g., the "new", "[", and "]" tokens in
+ /// operator new [].
+ ///
+ /// Different operators have different numbers of tokens in their name,
+ /// up to three. Any remaining source locations in this array will be
+ /// set to an invalid value for operators with fewer than three tokens.
+ unsigned SymbolLocations[3];
+ };
+
/// \brief Anonymous union that holds extra data associated with the
/// parsed unqualified-id.
union {
@@ -817,19 +841,7 @@ public:
/// \brief When Kind == IK_OperatorFunctionId, the overloaded operator
/// that we parsed.
- struct {
- /// \brief The kind of overloaded operator.
- OverloadedOperatorKind Operator;
-
- /// \brief The source locations of the individual tokens that name
- /// the operator, e.g., the "new", "[", and "]" tokens in
- /// operator new [].
- ///
- /// Different operators have different numbers of tokens in their name,
- /// up to three. Any remaining source locations in this array will be
- /// set to an invalid value for operators with fewer than three tokens.
- unsigned SymbolLocations[3];
- } OperatorFunctionId;
+ struct OFI OperatorFunctionId;
/// \brief When Kind == IK_ConversionFunctionId, the type that the
/// conversion function names.
@@ -1010,8 +1022,8 @@ struct DeclaratorChunk {
};
struct PointerTypeInfo : TypeInfoCommon {
- /// The type qualifiers: const/volatile/restrict.
- unsigned TypeQuals : 3;
+ /// The type qualifiers: const/volatile/restrict/atomic.
+ unsigned TypeQuals : 4;
/// The location of the const-qualifier, if any.
unsigned ConstQualLoc;
@@ -1022,6 +1034,9 @@ struct DeclaratorChunk {
/// The location of the restrict-qualifier, if any.
unsigned RestrictQualLoc;
+ /// The location of the _Atomic-qualifier, if any.
+ unsigned AtomicQualLoc;
+
void destroy() {
}
};
@@ -1036,8 +1051,8 @@ struct DeclaratorChunk {
};
struct ArrayTypeInfo : TypeInfoCommon {
- /// The type qualifiers for the array: const/volatile/restrict.
- unsigned TypeQuals : 3;
+ /// The type qualifiers for the array: const/volatile/restrict/_Atomic.
+ unsigned TypeQuals : 4;
/// True if this dimension included the 'static' keyword.
bool hasStatic : 1;
@@ -1259,16 +1274,16 @@ struct DeclaratorChunk {
struct BlockPointerTypeInfo : TypeInfoCommon {
/// For now, sema will catch these as invalid.
- /// The type qualifiers: const/volatile/restrict.
- unsigned TypeQuals : 3;
+ /// The type qualifiers: const/volatile/restrict/_Atomic.
+ unsigned TypeQuals : 4;
void destroy() {
}
};
struct MemberPointerTypeInfo : TypeInfoCommon {
- /// The type qualifiers: const/volatile/restrict.
- unsigned TypeQuals : 3;
+ /// The type qualifiers: const/volatile/restrict/_Atomic.
+ unsigned TypeQuals : 4;
// CXXScopeSpec has a constructor, so it can't be a direct member.
// So we need some pointer-aligned storage and a bit of trickery.
union {
@@ -1422,6 +1437,9 @@ struct DeclaratorChunk {
return I;
}
+ bool isParen() const {
+ return Kind == Paren;
+ }
};
/// \brief Described the kind of function definition (if any) provided for
@@ -1783,33 +1801,41 @@ public:
return DeclTypeInfo[i];
}
- void DropFirstTypeObject()
- {
+ void DropFirstTypeObject() {
assert(!DeclTypeInfo.empty() && "No type chunks to drop.");
DeclTypeInfo.front().destroy();
DeclTypeInfo.erase(DeclTypeInfo.begin());
}
+ /// Return the innermost (closest to the declarator) chunk of this
+ /// declarator that is not a parens chunk, or null if there are no
+ /// non-parens chunks.
+ const DeclaratorChunk *getInnermostNonParenChunk() const {
+ for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i) {
+ if (!DeclTypeInfo[i].isParen())
+ return &DeclTypeInfo[i];
+ }
+ return 0;
+ }
+
+ /// Return the outermost (furthest from the declarator) chunk of
+ /// this declarator that is not a parens chunk, or null if there are
+ /// no non-parens chunks.
+ const DeclaratorChunk *getOutermostNonParenChunk() const {
+ for (unsigned i = DeclTypeInfo.size(), i_end = 0; i != i_end; --i) {
+ if (!DeclTypeInfo[i-1].isParen())
+ return &DeclTypeInfo[i-1];
+ }
+ return 0;
+ }
+
/// isArrayOfUnknownBound - This method returns true if the declarator
/// is a declarator for an array of unknown bound (looking through
/// parentheses).
bool isArrayOfUnknownBound() const {
- for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i) {
- switch (DeclTypeInfo[i].Kind) {
- case DeclaratorChunk::Paren:
- continue;
- case DeclaratorChunk::Function:
- case DeclaratorChunk::Pointer:
- case DeclaratorChunk::Reference:
- case DeclaratorChunk::BlockPointer:
- case DeclaratorChunk::MemberPointer:
- return false;
- case DeclaratorChunk::Array:
- return !DeclTypeInfo[i].Arr.NumElts;
- }
- llvm_unreachable("Invalid type chunk");
- }
- return false;
+ const DeclaratorChunk *chunk = getInnermostNonParenChunk();
+ return (chunk && chunk->Kind == DeclaratorChunk::Array &&
+ !chunk->Arr.NumElts);
}
/// isFunctionDeclarator - This method returns true if the declarator
@@ -1866,7 +1892,54 @@ public:
/// isn't a function declarator, if the type specifier refers to a function
/// type. This routine checks for both cases.
bool isDeclarationOfFunction() const;
+
+ /// \brief Return true if this declaration appears in a context where a
+ /// function declarator would be a function declaration.
+ bool isFunctionDeclarationContext() const {
+ if (getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef)
+ return false;
+
+ switch (Context) {
+ case FileContext:
+ case MemberContext:
+ case BlockContext:
+ return true;
+
+ case ForContext:
+ case ConditionContext:
+ case KNRTypeListContext:
+ case TypeNameContext:
+ case AliasDeclContext:
+ case AliasTemplateContext:
+ case PrototypeContext:
+ case ObjCParameterContext:
+ case ObjCResultContext:
+ case TemplateParamContext:
+ case CXXNewContext:
+ case CXXCatchContext:
+ case ObjCCatchContext:
+ case BlockLiteralContext:
+ case LambdaExprContext:
+ case TemplateTypeArgContext:
+ case TrailingReturnContext:
+ return false;
+ }
+ llvm_unreachable("unknown context kind!");
+ }
+ /// \brief Return true if a function declarator at this position would be a
+ /// function declaration.
+ bool isFunctionDeclaratorAFunctionDeclaration() const {
+ if (!isFunctionDeclarationContext())
+ return false;
+
+ for (unsigned I = 0, N = getNumTypeObjects(); I != N; ++I)
+ if (getTypeObject(I).Kind != DeclaratorChunk::Paren)
+ return false;
+
+ return true;
+ }
+
/// takeAttributes - Takes attributes from the given parsed-attributes
/// set and add them to this declarator.
///
@@ -1897,6 +1970,17 @@ public:
return false;
}
+ /// \brief Return a source range list of C++11 attributes associated
+ /// with the declarator.
+ void getCXX11AttributeRanges(SmallVector<SourceRange, 4> &Ranges) {
+ AttributeList *AttrList = Attrs.getList();
+ while (AttrList) {
+ if (AttrList->isCXX11Attribute())
+ Ranges.push_back(AttrList->getRange());
+ AttrList = AttrList->getNext();
+ }
+ }
+
void setAsmLabel(Expr *E) { AsmLabel = E; }
Expr *getAsmLabel() const { return AsmLabel; }
@@ -1996,7 +2080,7 @@ struct LambdaIntroducer {
SourceRange Range;
SourceLocation DefaultLoc;
LambdaCaptureDefault Default;
- llvm::SmallVector<LambdaCapture, 4> Captures;
+ SmallVector<LambdaCapture, 4> Captures;
LambdaIntroducer()
: Default(LCD_None) {}
diff --git a/include/clang/Sema/DelayedDiagnostic.h b/include/clang/Sema/DelayedDiagnostic.h
index a20480c7e44b..3704e095c74f 100644
--- a/include/clang/Sema/DelayedDiagnostic.h
+++ b/include/clang/Sema/DelayedDiagnostic.h
@@ -199,21 +199,25 @@ public:
}
private:
+
+ struct DD {
+ const NamedDecl *Decl;
+ const ObjCInterfaceDecl *UnknownObjCClass;
+ const ObjCPropertyDecl *ObjCProperty;
+ const char *Message;
+ size_t MessageLen;
+ };
+
+ struct FTD {
+ unsigned Diagnostic;
+ unsigned Argument;
+ void *OperandType;
+ };
+
union {
- /// Deprecation.
- struct {
- const NamedDecl *Decl;
- const ObjCInterfaceDecl *UnknownObjCClass;
- const ObjCPropertyDecl *ObjCProperty;
- const char *Message;
- size_t MessageLen;
- } DeprecationData;
-
- struct {
- unsigned Diagnostic;
- unsigned Argument;
- void *OperandType;
- } ForbiddenTypeData;
+ /// Deprecation
+ struct DD DeprecationData;
+ struct FTD ForbiddenTypeData;
/// Access control.
char AccessData[sizeof(AccessedEntity)];
@@ -224,14 +228,14 @@ private:
/// delayed.
class DelayedDiagnosticPool {
const DelayedDiagnosticPool *Parent;
- llvm::SmallVector<DelayedDiagnostic, 4> Diagnostics;
+ SmallVector<DelayedDiagnostic, 4> Diagnostics;
DelayedDiagnosticPool(const DelayedDiagnosticPool &) LLVM_DELETED_FUNCTION;
void operator=(const DelayedDiagnosticPool &) LLVM_DELETED_FUNCTION;
public:
DelayedDiagnosticPool(const DelayedDiagnosticPool *parent) : Parent(parent) {}
~DelayedDiagnosticPool() {
- for (llvm::SmallVectorImpl<DelayedDiagnostic>::iterator
+ for (SmallVectorImpl<DelayedDiagnostic>::iterator
i = Diagnostics.begin(), e = Diagnostics.end(); i != e; ++i)
i->Destroy();
}
@@ -260,8 +264,7 @@ public:
pool.Diagnostics.clear();
}
- typedef llvm::SmallVectorImpl<DelayedDiagnostic>::const_iterator
- pool_iterator;
+ typedef SmallVectorImpl<DelayedDiagnostic>::const_iterator pool_iterator;
pool_iterator pool_begin() const { return Diagnostics.begin(); }
pool_iterator pool_end() const { return Diagnostics.end(); }
bool pool_empty() const { return Diagnostics.empty(); }
diff --git a/include/clang/Sema/ExternalSemaSource.h b/include/clang/Sema/ExternalSemaSource.h
index 7a598498ff31..cbce757ea7d0 100644
--- a/include/clang/Sema/ExternalSemaSource.h
+++ b/include/clang/Sema/ExternalSemaSource.h
@@ -15,6 +15,7 @@
#include "clang/AST/ExternalASTSource.h"
#include "clang/Sema/Weak.h"
+#include "llvm/ADT/MapVector.h"
#include <utility>
namespace clang {
@@ -65,7 +66,12 @@ public:
/// which will be used during typo correction.
virtual void ReadKnownNamespaces(
SmallVectorImpl<NamespaceDecl *> &Namespaces);
-
+
+ /// \brief Load the set of used but not defined functions or variables with
+ /// internal linkage, or used but not defined internal functions.
+ virtual void ReadUndefinedButUsed(
+ llvm::DenseMap<NamedDecl*, SourceLocation> &Undefined);
+
/// \brief Do last resort, unqualified lookup on a LookupResult that
/// Sema cannot find.
///
@@ -130,7 +136,7 @@ public:
/// declarations to the given vector of declarations. Note that this routine
/// may be invoked multiple times; the external source should take care not
/// to introduce the same declarations repeatedly.
- virtual void ReadLocallyScopedExternalDecls(
+ virtual void ReadLocallyScopedExternCDecls(
SmallVectorImpl<NamedDecl *> &Decls) {}
/// \brief Read the set of referenced selectors known to the
diff --git a/include/clang/Sema/IdentifierResolver.h b/include/clang/Sema/IdentifierResolver.h
index dff013423aa9..0b1b74a0d8cc 100644
--- a/include/clang/Sema/IdentifierResolver.h
+++ b/include/clang/Sema/IdentifierResolver.h
@@ -158,8 +158,7 @@ public:
/// \param ExplicitInstantiationOrSpecialization When true, we are checking
/// whether the declaration is in scope for the purposes of explicit template
/// instantiation or specialization. The default is false.
- bool isDeclInScope(Decl *D, DeclContext *Ctx, ASTContext &Context,
- Scope *S = 0,
+ bool isDeclInScope(Decl *D, DeclContext *Ctx, Scope *S = 0,
bool ExplicitInstantiationOrSpecialization = false) const;
/// AddDecl - Link the decl to its shadowed decl chain.
diff --git a/include/clang/Sema/Initialization.h b/include/clang/Sema/Initialization.h
index 0b0af0cff6ef..8459be16f4cf 100644
--- a/include/clang/Sema/Initialization.h
+++ b/include/clang/Sema/Initialization.h
@@ -13,12 +13,13 @@
#ifndef LLVM_CLANG_SEMA_INITIALIZATION_H
#define LLVM_CLANG_SEMA_INITIALIZATION_H
-#include "clang/Sema/Ownership.h"
-#include "clang/Sema/Overload.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/Attr.h"
#include "clang/AST/Type.h"
#include "clang/AST/UnresolvedSet.h"
#include "clang/Basic/SourceLocation.h"
+#include "clang/Sema/Overload.h"
+#include "clang/Sema/Ownership.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallVector.h"
#include <cassert>
@@ -87,7 +88,27 @@ private:
/// \brief The type of the object or reference being initialized.
QualType Type;
-
+
+ struct LN {
+ /// \brief When Kind == EK_Result, EK_Exception, EK_New, the
+ /// location of the 'return', 'throw', or 'new' keyword,
+ /// respectively. When Kind == EK_Temporary, the location where
+ /// the temporary is being created.
+ unsigned Location;
+
+ /// \brief Whether the entity being initialized may end up using the
+ /// named return value optimization (NRVO).
+ bool NRVO;
+ };
+
+ struct C {
+ /// \brief The variable being captured by an EK_LambdaCapture.
+ VarDecl *Var;
+
+ /// \brief The source location at which the capture occurs.
+ unsigned Location;
+ };
+
union {
/// \brief When Kind == EK_Variable, or EK_Member, the VarDecl or
/// FieldDecl, respectively.
@@ -100,18 +121,8 @@ private:
/// \brief When Kind == EK_Temporary, the type source information for
/// the temporary.
TypeSourceInfo *TypeInfo;
-
- struct {
- /// \brief When Kind == EK_Result, EK_Exception, EK_New, the
- /// location of the 'return', 'throw', or 'new' keyword,
- /// respectively. When Kind == EK_Temporary, the location where
- /// the temporary is being created.
- unsigned Location;
-
- /// \brief Whether the entity being initialized may end up using the
- /// named return value optimization (NRVO).
- bool NRVO;
- } LocAndNRVO;
+
+ struct LN LocAndNRVO;
/// \brief When Kind == EK_Base, the base specifier that provides the
/// base class. The lower bit specifies whether the base is an inherited
@@ -122,14 +133,8 @@ private:
/// EK_ComplexElement, the index of the array or vector element being
/// initialized.
unsigned Index;
-
- struct {
- /// \brief The variable being captured by an EK_LambdaCapture.
- VarDecl *Var;
-
- /// \brief The source location at which the capture occurs.
- unsigned Location;
- } Capture;
+
+ struct C Capture;
};
InitializedEntity() { }
@@ -172,17 +177,25 @@ public:
static InitializedEntity InitializeVariable(VarDecl *Var) {
return InitializedEntity(Var);
}
-
+
/// \brief Create the initialization entity for a parameter.
static InitializedEntity InitializeParameter(ASTContext &Context,
ParmVarDecl *Parm) {
+ return InitializeParameter(Context, Parm, Parm->getType());
+ }
+
+ /// \brief Create the initialization entity for a parameter, but use
+ /// another type.
+ static InitializedEntity InitializeParameter(ASTContext &Context,
+ ParmVarDecl *Parm,
+ QualType Type) {
bool Consumed = (Context.getLangOpts().ObjCAutoRefCount &&
Parm->hasAttr<NSConsumedAttr>());
InitializedEntity Entity;
Entity.Kind = EK_Parameter;
- Entity.Type = Context.getVariableArrayDecayedType(
- Parm->getType().getUnqualifiedType());
+ Entity.Type =
+ Context.getVariableArrayDecayedType(Type.getUnqualifiedType());
Entity.Parent = 0;
Entity.Parameter
= (static_cast<uintptr_t>(Consumed) | reinterpret_cast<uintptr_t>(Parm));
@@ -615,7 +628,11 @@ public:
/// \brief Produce an Objective-C object pointer.
SK_ProduceObjCObject,
/// \brief Construct a std::initializer_list from an initializer list.
- SK_StdInitializerList
+ SK_StdInitializerList,
+ /// \brief Initialize an OpenCL sampler from an integer.
+ SK_OCLSamplerInit,
+ /// \brief Passing zero to a function where OpenCL event_t is expected.
+ SK_OCLZeroEvent
};
/// \brief A single step in the initialization sequence.
@@ -626,7 +643,13 @@ public:
// \brief The type that results from this initialization.
QualType Type;
-
+
+ struct F {
+ bool HadMultipleCandidates;
+ FunctionDecl *Function;
+ DeclAccessPair FoundDecl;
+ };
+
union {
/// \brief When Kind == SK_ResolvedOverloadedFunction or Kind ==
/// SK_UserConversion, the function that the expression should be
@@ -638,11 +661,7 @@ public:
/// selected from an overloaded set having size greater than 1.
/// For conversion decls, the naming class is the source type.
/// For construct decls, the naming class is the target type.
- struct {
- bool HadMultipleCandidates;
- FunctionDecl *Function;
- DeclAccessPair FoundDecl;
- } Function;
+ struct F Function;
/// \brief When Kind = SK_ConversionSequence, the implicit conversion
/// sequence.
@@ -944,6 +963,14 @@ public:
/// initializer list.
void AddStdInitializerListConstructionStep(QualType T);
+ /// \brief Add a step to initialize an OpenCL sampler from an integer
+ /// constant.
+ void AddOCLSamplerInitStep(QualType T);
+
+ /// \brief Add a step to initialize an OpenCL event_t from a NULL
+ /// constant.
+ void AddOCLZeroEventStep(QualType T);
+
/// \brief Add steps to unwrap a initializer list for a reference around a
/// single element and rewrap it at the end.
void RewrapReferenceInitList(QualType T, InitListExpr *Syntactic);
diff --git a/include/clang/Sema/Lookup.h b/include/clang/Sema/Lookup.h
index fe5d2627335a..3e7e3a16ebc8 100644
--- a/include/clang/Sema/Lookup.h
+++ b/include/clang/Sema/Lookup.h
@@ -15,8 +15,8 @@
#ifndef LLVM_CLANG_SEMA_LOOKUP_H
#define LLVM_CLANG_SEMA_LOOKUP_H
-#include "clang/Sema/Sema.h"
#include "clang/AST/DeclCXX.h"
+#include "clang/Sema/Sema.h"
namespace clang {
@@ -138,7 +138,8 @@ public:
IDNS(0),
Redecl(Redecl != Sema::NotForRedeclaration),
HideTags(true),
- Diagnose(Redecl == Sema::NotForRedeclaration)
+ Diagnose(Redecl == Sema::NotForRedeclaration),
+ AllowHidden(Redecl == Sema::ForRedeclaration)
{
configure();
}
@@ -158,7 +159,8 @@ public:
IDNS(0),
Redecl(Redecl != Sema::NotForRedeclaration),
HideTags(true),
- Diagnose(Redecl == Sema::NotForRedeclaration)
+ Diagnose(Redecl == Sema::NotForRedeclaration),
+ AllowHidden(Redecl == Sema::ForRedeclaration)
{
configure();
}
@@ -176,7 +178,8 @@ public:
IDNS(Other.IDNS),
Redecl(Other.Redecl),
HideTags(Other.HideTags),
- Diagnose(false)
+ Diagnose(false),
+ AllowHidden(Other.AllowHidden)
{}
~LookupResult() {
@@ -214,10 +217,16 @@ public:
return Redecl;
}
+ /// \brief Specify whether hidden declarations are visible, e.g.,
+ /// for recovery reasons.
+ void setAllowHidden(bool AH) {
+ AllowHidden = AH;
+ }
+
/// \brief Determine whether this lookup is permitted to see hidden
/// declarations, such as those in modules that have not yet been imported.
bool isHiddenDeclarationVisible() const {
- return Redecl || LookupKind == Sema::LookupTagName;
+ return AllowHidden || LookupKind == Sema::LookupTagName;
}
/// Sets whether tag declarations should be hidden by non-tag
@@ -483,6 +492,7 @@ public:
/// \brief Change this lookup's redeclaration kind.
void setRedeclarationKind(Sema::RedeclarationKind RK) {
Redecl = RK;
+ AllowHidden = (RK == Sema::ForRedeclaration);
configure();
}
@@ -615,7 +625,7 @@ private:
bool sanityCheckUnresolved() const {
for (iterator I = begin(), E = end(); I != E; ++I)
- if (isa<UnresolvedUsingValueDecl>(*I))
+ if (isa<UnresolvedUsingValueDecl>((*I)->getUnderlyingDecl()))
return true;
return false;
}
@@ -644,6 +654,9 @@ private:
bool HideTags;
bool Diagnose;
+
+ /// \brief True if we should allow hidden declarations to be 'visible'.
+ bool AllowHidden;
};
/// \brief Consumes visible declarations found when searching for
diff --git a/include/clang/Sema/Makefile b/include/clang/Sema/Makefile
index f6662d6b08eb..7d658a7c11ef 100644
--- a/include/clang/Sema/Makefile
+++ b/include/clang/Sema/Makefile
@@ -1,6 +1,7 @@
CLANG_LEVEL := ../../..
TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic
-BUILT_SOURCES = AttrTemplateInstantiate.inc AttrParsedAttrList.inc AttrParsedAttrKinds.inc
+BUILT_SOURCES = AttrTemplateInstantiate.inc AttrParsedAttrList.inc AttrParsedAttrKinds.inc \
+ AttrSpellingListIndex.inc
TABLEGEN_INC_FILES_COMMON = 1
@@ -24,4 +25,10 @@ $(ObjDir)/AttrParsedAttrKinds.inc.tmp : $(TD_SRC_DIR)/Attr.td \
$(Verb) $(ClangTableGen) -gen-clang-attr-parsed-attr-kinds -o \
$(call SYSPATH, $@) -I $(PROJ_SRC_DIR)/../../ $<
+$(ObjDir)/AttrSpellingListIndex.inc.tmp : $(TD_SRC_DIR)/Attr.td \
+ $(CLANG_TBLGEN) $(ObjDir)/.dir
+ $(Echo) "Building Clang attribute spelling list index with tablegen"
+ $(Verb) $(ClangTableGen) -gen-clang-attr-spelling-index -o \
+ $(call SYSPATH, $@) -I $(PROJ_SRC_DIR)/../../ $<
+
diff --git a/include/clang/Sema/MultiplexExternalSemaSource.h b/include/clang/Sema/MultiplexExternalSemaSource.h
index 1513aebb3e1e..ff87d05c0404 100644
--- a/include/clang/Sema/MultiplexExternalSemaSource.h
+++ b/include/clang/Sema/MultiplexExternalSemaSource.h
@@ -15,9 +15,7 @@
#include "clang/Sema/ExternalSemaSource.h"
#include "clang/Sema/Weak.h"
-
#include "llvm/ADT/SmallVector.h"
-
#include <utility>
namespace clang {
@@ -41,7 +39,7 @@ namespace clang {
class MultiplexExternalSemaSource : public ExternalSemaSource {
private:
- llvm::SmallVector<ExternalSemaSource*, 2> Sources; // doesn't own them.
+ SmallVector<ExternalSemaSource *, 2> Sources; // doesn't own them.
public:
@@ -67,58 +65,30 @@ public:
/// \brief Resolve a declaration ID into a declaration, potentially
/// building a new declaration.
- ///
- /// This method only needs to be implemented if the AST source ever
- /// passes back decl sets as VisibleDeclaration objects.
- ///
- /// The default implementation of this method is a no-op.
virtual Decl *GetExternalDecl(uint32_t ID);
/// \brief Resolve a selector ID into a selector.
- ///
- /// This operation only needs to be implemented if the AST source
- /// returns non-zero for GetNumKnownSelectors().
- ///
- /// The default implementation of this method is a no-op.
virtual Selector GetExternalSelector(uint32_t ID);
/// \brief Returns the number of selectors known to the external AST
/// source.
- ///
- /// The default implementation of this method is a no-op.
virtual uint32_t GetNumExternalSelectors();
/// \brief Resolve the offset of a statement in the decl stream into
/// a statement.
- ///
- /// This operation is meant to be used via a LazyOffsetPtr. It only
- /// needs to be implemented if the AST source uses methods like
- /// FunctionDecl::setLazyBody when building decls.
- ///
- /// The default implementation of this method is a no-op.
virtual Stmt *GetExternalDeclStmt(uint64_t Offset);
/// \brief Resolve the offset of a set of C++ base specifiers in the decl
/// stream into an array of specifiers.
- ///
- /// The default implementation of this method is a no-op.
virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset);
- /// \brief Finds all declarations with the given name in the
+ /// \brief Find all declarations with the given name in the
/// given context.
- ///
- /// Generally the final step of this method is either to call
- /// SetExternalVisibleDeclsForName or to recursively call lookup on
- /// the DeclContext after calling SetExternalVisibleDecls.
- ///
- /// The default implementation of this method is a no-op.
- virtual DeclContextLookupResult
+ virtual bool
FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name);
/// \brief Ensures that the table of all visible declarations inside this
/// context is up to date.
- ///
- /// The default implementation of this functino is a no-op.
virtual void completeVisibleDeclsMap(const DeclContext *DC);
/// \brief Finds all declarations lexically contained within the given
@@ -129,8 +99,6 @@ public:
/// are returned.
///
/// \return an indication of whether the load succeeded or failed.
- ///
- /// The default implementation of this method is a no-op.
virtual ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
bool (*isKindWeWant)(Decl::Kind),
SmallVectorImpl<Decl*> &Result);
@@ -174,26 +142,18 @@ public:
/// \brief Notify ExternalASTSource that we started deserialization of
/// a decl or type so until FinishedDeserializing is called there may be
/// decls that are initializing. Must be paired with FinishedDeserializing.
- ///
- /// The default implementation of this method is a no-op.
virtual void StartedDeserializing();
/// \brief Notify ExternalASTSource that we finished the deserialization of
/// a decl or type. Must be paired with StartedDeserializing.
- ///
- /// The default implementation of this method is a no-op.
virtual void FinishedDeserializing();
/// \brief Function that will be invoked when we begin parsing a new
/// translation unit involving this external AST source.
- ///
- /// The default implementation of this method is a no-op.
virtual void StartTranslationUnit(ASTConsumer *Consumer);
/// \brief Print any statistics that have been gathered regarding
/// the external AST source.
- ///
- /// The default implementation of this method is a no-op.
virtual void PrintStats();
@@ -254,6 +214,11 @@ public:
/// \brief Load the set of namespaces that are known to the external source,
/// which will be used during typo correction.
virtual void ReadKnownNamespaces(SmallVectorImpl<NamespaceDecl*> &Namespaces);
+
+ /// \brief Load the set of used but not defined functions or variables with
+ /// internal linkage, or used but not defined inline functions.
+ virtual void ReadUndefinedButUsed(
+ llvm::DenseMap<NamedDecl*, SourceLocation> &Undefined);
/// \brief Do last resort, unqualified lookup on a LookupResult that
/// Sema cannot find.
@@ -311,14 +276,14 @@ public:
/// introduce the same declarations repeatedly.
virtual void ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl*> &Decls);
- /// \brief Read the set of locally-scoped external declarations known to the
+ /// \brief Read the set of locally-scoped extern "C" declarations known to the
/// external Sema source.
///
/// The external source should append its own locally-scoped external
- /// declarations to the given vector of declarations. Note that this routine
- /// may be invoked multiple times; the external source should take care not
+ /// declarations to the given vector of declarations. Note that this routine
+ /// may be invoked multiple times; the external source should take care not
/// to introduce the same declarations repeatedly.
- virtual void ReadLocallyScopedExternalDecls(SmallVectorImpl<NamedDecl*>&Decls);
+ virtual void ReadLocallyScopedExternCDecls(SmallVectorImpl<NamedDecl*>&Decls);
/// \brief Read the set of referenced selectors known to the
/// external Sema source.
diff --git a/include/clang/Sema/Overload.h b/include/clang/Sema/Overload.h
index 65ed781f743c..c685843f18cd 100644
--- a/include/clang/Sema/Overload.h
+++ b/include/clang/Sema/Overload.h
@@ -78,8 +78,9 @@ namespace clang {
ICK_Vector_Splat, ///< A vector splat from an arithmetic type
ICK_Complex_Real, ///< Complex-real conversions (C99 6.3.1.7)
ICK_Block_Pointer_Conversion, ///< Block Pointer conversions
- ICK_TransparentUnionConversion, /// Transparent Union Conversions
+ ICK_TransparentUnionConversion, ///< Transparent Union Conversions
ICK_Writeback_Conversion, ///< Objective-C ARC writeback conversion
+ ICK_Zero_Event_Conversion, ///< Zero constant to event (OpenCL1.2 6.12.10)
ICK_Num_Conversion_Kinds ///< The number of conversion kinds
};
@@ -694,6 +695,10 @@ namespace clang {
/// \brief Return the second template argument this deduction failure
/// refers to, if any.
const TemplateArgument *getSecondArg();
+
+ /// \brief Return the expression this deduction failure refers to,
+ /// if any.
+ Expr *getExpr();
/// \brief Free any memory associated with this deduction failure.
void Destroy();
@@ -809,7 +814,7 @@ namespace clang {
void NoteCandidates(Sema &S,
OverloadCandidateDisplayKind OCD,
- llvm::ArrayRef<Expr *> Args,
+ ArrayRef<Expr *> Args,
StringRef Opc = "",
SourceLocation Loc = SourceLocation());
};
diff --git a/include/clang/Sema/Ownership.h b/include/clang/Sema/Ownership.h
index e59fb3f46ba3..e064b91f78fb 100644
--- a/include/clang/Sema/Ownership.h
+++ b/include/clang/Sema/Ownership.h
@@ -23,13 +23,10 @@
//===----------------------------------------------------------------------===//
namespace clang {
- class Attr;
class CXXCtorInitializer;
class CXXBaseSpecifier;
class Decl;
- class DeclGroupRef;
class Expr;
- class NestedNameSpecifier;
class ParsedTemplateArgument;
class QualType;
class Stmt;
diff --git a/include/clang/Sema/Scope.h b/include/clang/Sema/Scope.h
index 1329f97c2bcf..d016b9b887c5 100644
--- a/include/clang/Sema/Scope.h
+++ b/include/clang/Sema/Scope.h
@@ -32,70 +32,66 @@ public:
/// ScopeFlags - These are bitfields that are or'd together when creating a
/// scope, which defines the sorts of things the scope contains.
enum ScopeFlags {
- /// FnScope - This indicates that the scope corresponds to a function, which
+ /// \brief This indicates that the scope corresponds to a function, which
/// means that labels are set here.
FnScope = 0x01,
- /// BreakScope - This is a while,do,switch,for, etc that can have break
- /// stmts embedded into it.
+ /// \brief This is a while, do, switch, for, etc that can have break
+ /// statements embedded into it.
BreakScope = 0x02,
- /// ContinueScope - This is a while,do,for, which can have continue
- /// stmt embedded into it.
+ /// \brief This is a while, do, for, which can have continue statements
+ /// embedded into it.
ContinueScope = 0x04,
- /// DeclScope - This is a scope that can contain a declaration. Some scopes
+ /// \brief This is a scope that can contain a declaration. Some scopes
/// just contain loop constructs but don't contain decls.
DeclScope = 0x08,
- /// ControlScope - The controlling scope in a if/switch/while/for statement.
+ /// \brief The controlling scope in a if/switch/while/for statement.
ControlScope = 0x10,
- /// ClassScope - The scope of a struct/union/class definition.
+ /// \brief The scope of a struct/union/class definition.
ClassScope = 0x20,
- /// BlockScope - This is a scope that corresponds to a block/closure object.
+ /// \brief This is a scope that corresponds to a block/closure object.
/// Blocks serve as top-level scopes for some objects like labels, they
/// also prevent things like break and continue. BlockScopes always have
/// the FnScope and DeclScope flags set as well.
BlockScope = 0x40,
- /// TemplateParamScope - This is a scope that corresponds to the
+ /// \brief This is a scope that corresponds to the
/// template parameters of a C++ template. Template parameter
/// scope starts at the 'template' keyword and ends when the
/// template declaration ends.
TemplateParamScope = 0x80,
- /// FunctionPrototypeScope - This is a scope that corresponds to the
+ /// \brief This is a scope that corresponds to the
/// parameters within a function prototype.
FunctionPrototypeScope = 0x100,
- /// AtCatchScope - This is a scope that corresponds to the Objective-C
+ /// \brief This is a scope that corresponds to the parameters within
+ /// a function prototype for a function declaration (as opposed to any
+ /// other kind of function declarator). Always has FunctionPrototypeScope
+ /// set as well.
+ FunctionDeclarationScope = 0x200,
+
+ /// \brief This is a scope that corresponds to the Objective-C
/// \@catch statement.
- AtCatchScope = 0x200,
+ AtCatchScope = 0x400,
- /// ObjCMethodScope - This scope corresponds to an Objective-C method body.
+ /// \brief This scope corresponds to an Objective-C method body.
/// It always has FnScope and DeclScope set as well.
- ObjCMethodScope = 0x400,
-
- /// SwitchScope - This is a scope that corresponds to a switch statement.
- SwitchScope = 0x800,
-
- /// TryScope - This is the scope of a C++ try statement.
- TryScope = 0x1000,
-
- /// CatchScope - This is the scope of a C++ catch statement.
- CatchScope = 0x2000,
+ ObjCMethodScope = 0x800,
- /// FnTryCatchScope - This is the scope for a function-level C++ try or
- /// catch scope.
- FnTryCatchScope = 0x4000,
+ /// \brief This is a scope that corresponds to a switch statement.
+ SwitchScope = 0x1000,
- /// FnTryScope - This is the scope of a function-level C++ try scope.
- FnTryScope = TryScope | FnTryCatchScope,
+ /// \brief This is the scope of a C++ try statement.
+ TryScope = 0x2000,
- /// FnCatchScope - This is the scope of a function-level C++ catch scope.
- FnCatchScope = CatchScope | FnTryCatchScope
+ /// \brief This is the scope for a function-level C++ try or catch scope.
+ FnTryCatchScope = 0x4000
};
private:
/// The parent scope for this scope. This is null for the translation-unit
@@ -244,7 +240,11 @@ public:
void setEntity(void *E) { Entity = E; }
bool hasErrorOccurred() const { return ErrorTrap.hasErrorOccurred(); }
-
+
+ bool hasUnrecoverableErrorOccurred() const {
+ return ErrorTrap.hasUnrecoverableErrorOccurred();
+ }
+
/// isClassScope - Return true if this scope is a class/struct/union scope.
bool isClassScope() const {
return (getFlags() & Scope::ClassScope);
diff --git a/include/clang/Sema/ScopeInfo.h b/include/clang/Sema/ScopeInfo.h
index feda9c96b857..2295bf437cb3 100644
--- a/include/clang/Sema/ScopeInfo.h
+++ b/include/clang/Sema/ScopeInfo.h
@@ -91,6 +91,9 @@ public:
/// \brief Whether this function contains any indirect gotos.
bool HasIndirectGoto;
+ /// \brief Whether a statement was dropped because it was invalid.
+ bool HasDroppedStmt;
+
/// A flag that is set when parsing a method that must call super's
/// implementation, such as \c -dealloc, \c -finalize, or any method marked
/// with \c __attribute__((objc_requires_super)).
@@ -287,9 +290,14 @@ public:
HasIndirectGoto = true;
}
+ void setHasDroppedStmt() {
+ HasDroppedStmt = true;
+ }
+
bool NeedsScopeChecking() const {
- return HasIndirectGoto ||
- (HasBranchProtectedScope && HasBranchIntoScope);
+ return !HasDroppedStmt &&
+ (HasIndirectGoto ||
+ (HasBranchProtectedScope && HasBranchIntoScope));
}
FunctionScopeInfo(DiagnosticsEngine &Diag)
@@ -297,6 +305,7 @@ public:
HasBranchProtectedScope(false),
HasBranchIntoScope(false),
HasIndirectGoto(false),
+ HasDroppedStmt(false),
ObjCShouldCallSuper(false),
ErrorTrap(Diag) { }
@@ -511,11 +520,11 @@ public:
bool ContainsUnexpandedParameterPack;
/// \brief Variables used to index into by-copy array captures.
- llvm::SmallVector<VarDecl *, 4> ArrayIndexVars;
+ SmallVector<VarDecl *, 4> ArrayIndexVars;
/// \brief Offsets into the ArrayIndexVars array at which each capture starts
/// its list of array index variables.
- llvm::SmallVector<unsigned, 4> ArrayIndexStarts;
+ SmallVector<unsigned, 4> ArrayIndexStarts;
LambdaScopeInfo(DiagnosticsEngine &Diag, CXXRecordDecl *Lambda,
CXXMethodDecl *CallOperator)
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 9b572d8b4d70..5b93e513eafe 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -15,27 +15,30 @@
#ifndef LLVM_CLANG_SEMA_SEMA_H
#define LLVM_CLANG_SEMA_SEMA_H
-#include "clang/Sema/Ownership.h"
-#include "clang/Sema/AnalysisBasedWarnings.h"
-#include "clang/Sema/IdentifierResolver.h"
-#include "clang/Sema/ObjCMethodList.h"
-#include "clang/Sema/DeclSpec.h"
-#include "clang/Sema/ExternalSemaSource.h"
-#include "clang/Sema/LocInfoType.h"
-#include "clang/Sema/TypoCorrection.h"
-#include "clang/Sema/Weak.h"
+#include "clang/AST/Attr.h"
+#include "clang/AST/DeclarationName.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprObjC.h"
-#include "clang/AST/DeclarationName.h"
#include "clang/AST/ExternalASTSource.h"
#include "clang/AST/LambdaMangleContext.h"
-#include "clang/AST/TypeLoc.h"
#include "clang/AST/NSAPI.h"
-#include "clang/Lex/ModuleLoader.h"
+#include "clang/AST/PrettyPrinter.h"
+#include "clang/AST/TypeLoc.h"
+#include "clang/Basic/ExpressionTraits.h"
+#include "clang/Basic/LangOptions.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Basic/TemplateKinds.h"
#include "clang/Basic/TypeTraits.h"
-#include "clang/Basic/ExpressionTraits.h"
+#include "clang/Lex/ModuleLoader.h"
+#include "clang/Sema/AnalysisBasedWarnings.h"
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/ExternalSemaSource.h"
+#include "clang/Sema/IdentifierResolver.h"
+#include "clang/Sema/LocInfoType.h"
+#include "clang/Sema/ObjCMethodList.h"
+#include "clang/Sema/Ownership.h"
+#include "clang/Sema/TypoCorrection.h"
+#include "clang/Sema/Weak.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/OwningPtr.h"
@@ -129,6 +132,7 @@ namespace clang {
class ObjCMethodDecl;
class ObjCPropertyDecl;
class ObjCProtocolDecl;
+ class OMPThreadPrivateDecl;
class OverloadCandidateSet;
class OverloadExpr;
class ParenListExpr;
@@ -197,6 +201,8 @@ class Sema {
///\brief Whether Sema has generated a multiplexer and has to delete it.
bool isMultiplexExternalSource;
+ static bool mightHaveNonExternalLinkage(const DeclaratorDecl *FD);
+
public:
typedef OpaquePtr<DeclGroupRef> DeclGroupPtrTy;
typedef OpaquePtr<TemplateName> TemplateTy;
@@ -253,7 +259,7 @@ public:
/// element type here is ExprWithCleanups::Object.
SmallVector<BlockDecl*, 8> ExprCleanupObjects;
- llvm::SmallPtrSet<Expr*, 8> MaybeODRUseExprs;
+ llvm::SmallPtrSet<Expr*, 2> MaybeODRUseExprs;
/// \brief Stack containing information about each of the nested
/// function, block, and method scopes that are currently active.
@@ -272,12 +278,6 @@ public:
/// This is only necessary for issuing pretty diagnostics.
ExtVectorDeclsType ExtVectorDecls;
- /// \brief The set of types for which we have already complained about the
- /// definitions being hidden.
- ///
- /// This set is used to suppress redundant diagnostics.
- llvm::SmallPtrSet<NamedDecl *, 4> HiddenDefinitions;
-
/// FieldCollector - Collects CXXFieldDecls during parsing of C++ classes.
OwningPtr<CXXFieldCollector> FieldCollector;
@@ -298,35 +298,35 @@ public:
llvm::SmallPtrSet<const Decl*, 4> ParsingInitForAutoVars;
/// \brief A mapping from external names to the most recent
- /// locally-scoped external declaration with that name.
+ /// locally-scoped extern "C" declaration with that name.
///
/// This map contains external declarations introduced in local
- /// scoped, e.g.,
+ /// scopes, e.g.,
///
/// \code
- /// void f() {
+ /// extern "C" void f() {
/// void foo(int, int);
/// }
/// \endcode
///
- /// Here, the name "foo" will be associated with the declaration on
+ /// Here, the name "foo" will be associated with the declaration of
/// "foo" within f. This name is not visible outside of
/// "f". However, we still find it in two cases:
///
- /// - If we are declaring another external with the name "foo", we
- /// can find "foo" as a previous declaration, so that the types
- /// of this external declaration can be checked for
- /// compatibility.
+ /// - If we are declaring another global or extern "C" entity with
+ /// the name "foo", we can find "foo" as a previous declaration,
+ /// so that the types of this external declaration can be checked
+ /// for compatibility.
///
/// - If we would implicitly declare "foo" (e.g., due to a call to
/// "foo" in C when no prototype or definition is visible), then
/// we find this declaration of "foo" and complain that it is
/// not visible.
- llvm::DenseMap<DeclarationName, NamedDecl *> LocallyScopedExternalDecls;
+ llvm::DenseMap<DeclarationName, NamedDecl *> LocallyScopedExternCDecls;
- /// \brief Look for a locally scoped external declaration by the given name.
+ /// \brief Look for a locally scoped extern "C" declaration by the given name.
llvm::DenseMap<DeclarationName, NamedDecl *>::iterator
- findLocallyScopedExternalDecl(DeclarationName Name);
+ findLocallyScopedExternCDecl(DeclarationName Name);
typedef LazyVector<VarDecl *, ExternalSemaSource,
&ExternalSemaSource::ReadTentativeDefinitions, 2, 2>
@@ -363,6 +363,16 @@ public:
const CXXDestructorDecl*>, 2>
DelayedDestructorExceptionSpecChecks;
+ /// \brief All the members seen during a class definition which were both
+ /// explicitly defaulted and had explicitly-specified exception
+ /// specifications, along with the function type containing their
+ /// user-specified exception specification. Those exception specifications
+ /// were overridden with the default specifications, but we still need to
+ /// check whether they are compatible with the default specification, and
+ /// we can't do that until the nesting set of class definitions is complete.
+ SmallVector<std::pair<CXXMethodDecl*, const FunctionProtoType*>, 2>
+ DelayedDefaultedMemberExceptionSpecs;
+
/// \brief Callback to the parser to parse templated functions when needed.
typedef void LateTemplateParserCB(void *P, const FunctionDecl *FD);
LateTemplateParserCB *LateTemplateParser;
@@ -533,7 +543,7 @@ public:
RecordDecl *MSVCGuidDecl;
/// \brief Caches identifiers/selectors for NSFoundation APIs.
- llvm::OwningPtr<NSAPI> NSAPIObj;
+ OwningPtr<NSAPI> NSAPIObj;
/// \brief The declaration of the Objective-C NSNumber class.
ObjCInterfaceDecl *NSNumberDecl;
@@ -568,6 +578,9 @@ public:
/// \brief id<NSCopying> type.
QualType QIDNSCopying;
+ /// \brief will hold 'respondsToSelector:'
+ Selector RespondsToSelectorSel;
+
/// A flag to remember whether the implicit forms of operator new and delete
/// have been declared.
bool GlobalNewDeleteDeclared;
@@ -619,11 +632,11 @@ public:
/// this expression evaluation context.
unsigned NumCleanupObjects;
- llvm::SmallPtrSet<Expr*, 8> SavedMaybeODRUseExprs;
+ llvm::SmallPtrSet<Expr*, 2> SavedMaybeODRUseExprs;
/// \brief The lambdas that are present within this context, if it
/// is indeed an unevaluated context.
- llvm::SmallVector<LambdaExpr *, 2> Lambdas;
+ SmallVector<LambdaExpr *, 2> Lambdas;
/// \brief The declaration that provides context for the lambda expression
/// if the normal declaration context does not suffice, e.g., in a
@@ -635,15 +648,15 @@ public:
///
/// This mangling information is allocated lazily, since most contexts
/// do not have lambda expressions.
- LambdaMangleContext *LambdaMangle;
+ IntrusiveRefCntPtr<LambdaMangleContext> LambdaMangle;
/// \brief If we are processing a decltype type, a set of call expressions
/// for which we have deferred checking the completeness of the return type.
- llvm::SmallVector<CallExpr*, 8> DelayedDecltypeCalls;
+ SmallVector<CallExpr *, 8> DelayedDecltypeCalls;
/// \brief If we are processing a decltype type, a set of temporary binding
/// expressions for which we have deferred checking the destructor.
- llvm::SmallVector<CXXBindTemporaryExpr*, 8> DelayedDecltypeBinds;
+ SmallVector<CXXBindTemporaryExpr *, 8> DelayedDecltypeBinds;
ExpressionEvaluationContextRecord(ExpressionEvaluationContext Context,
unsigned NumCleanupObjects,
@@ -654,10 +667,6 @@ public:
IsDecltype(IsDecltype), NumCleanupObjects(NumCleanupObjects),
LambdaContextDecl(LambdaContextDecl), LambdaMangle() { }
- ~ExpressionEvaluationContextRecord() {
- delete LambdaMangle;
- }
-
/// \brief Retrieve the mangling context for lambdas.
LambdaMangleContext &getLambdaMangleContext() {
assert(LambdaContextDecl && "Need to have a lambda context declaration");
@@ -730,11 +739,15 @@ public:
// Contains the locations of the beginning of unparsed default
// argument locations.
- llvm::DenseMap<ParmVarDecl *,SourceLocation> UnparsedDefaultArgLocs;
+ llvm::DenseMap<ParmVarDecl *, SourceLocation> UnparsedDefaultArgLocs;
+
+ /// UndefinedInternals - all the used, undefined objects which require a
+ /// definition in this translation unit.
+ llvm::DenseMap<NamedDecl *, SourceLocation> UndefinedButUsed;
- /// UndefinedInternals - all the used, undefined objects with
- /// internal linkage in this translation unit.
- llvm::DenseMap<NamedDecl*, SourceLocation> UndefinedInternals;
+ /// Obtain a sorted list of functions that are undefined but ODR-used.
+ void getUndefinedButUsed(
+ llvm::SmallVectorImpl<std::pair<NamedDecl *, SourceLocation> > &Undefined);
typedef std::pair<ObjCMethodList, ObjCMethodList> GlobalMethods;
typedef llvm::DenseMap<Selector, GlobalMethods> GlobalMethodPool;
@@ -749,6 +762,24 @@ public:
/// of -Wselector.
llvm::DenseMap<Selector, SourceLocation> ReferencedSelectors;
+ /// Kinds of C++ special members.
+ enum CXXSpecialMember {
+ CXXDefaultConstructor,
+ CXXCopyConstructor,
+ CXXMoveConstructor,
+ CXXCopyAssignment,
+ CXXMoveAssignment,
+ CXXDestructor,
+ CXXInvalid
+ };
+
+ typedef std::pair<CXXRecordDecl*, CXXSpecialMember> SpecialMemberDecl;
+
+ /// The C++ special members which we are currently in the process of
+ /// declaring. If this process recursively triggers the declaration of the
+ /// same special member, we should act as if it is not yet declared.
+ llvm::SmallSet<SpecialMemberDecl, 4> SpecialMembersBeingDeclared;
+
void ReadMethodPool(Selector Sel);
/// Private Helper predicate to check for 'self'.
@@ -903,10 +934,10 @@ public:
// Type Analysis / Processing: SemaType.cpp.
//
- QualType BuildQualifiedType(QualType T, SourceLocation Loc, Qualifiers Qs);
- QualType BuildQualifiedType(QualType T, SourceLocation Loc, unsigned CVR) {
- return BuildQualifiedType(T, Loc, Qualifiers::fromCVRMask(CVR));
- }
+ QualType BuildQualifiedType(QualType T, SourceLocation Loc, Qualifiers Qs,
+ const DeclSpec *DS = 0);
+ QualType BuildQualifiedType(QualType T, SourceLocation Loc, unsigned CVRA,
+ const DeclSpec *DS = 0);
QualType BuildPointerType(QualType T,
SourceLocation Loc, DeclarationName Entity);
QualType BuildReferenceType(QualType T, bool LValueRef,
@@ -916,12 +947,39 @@ public:
SourceRange Brackets, DeclarationName Entity);
QualType BuildExtVectorType(QualType T, Expr *ArraySize,
SourceLocation AttrLoc);
+
+ /// \brief Build a function type.
+ ///
+ /// This routine checks the function type according to C++ rules and
+ /// under the assumption that the result type and parameter types have
+ /// just been instantiated from a template. It therefore duplicates
+ /// some of the behavior of GetTypeForDeclarator, but in a much
+ /// simpler form that is only suitable for this narrow use case.
+ ///
+ /// \param T The return type of the function.
+ ///
+ /// \param ParamTypes The parameter types of the function. This array
+ /// will be modified to account for adjustments to the types of the
+ /// function parameters.
+ ///
+ /// \param Loc The location of the entity whose type involves this
+ /// function type or, if there is no such entity, the location of the
+ /// type that will have function type.
+ ///
+ /// \param Entity The name of the entity that involves the function
+ /// type, if known.
+ ///
+ /// \param EPI Extra information about the function type. Usually this will
+ /// be taken from an existing function with the same prototype.
+ ///
+ /// \returns A suitable function type, if there are no errors. The
+ /// unqualified type will always be a FunctionProtoType.
+ /// Otherwise, returns a NULL type.
QualType BuildFunctionType(QualType T,
- QualType *ParamTypes, unsigned NumParamTypes,
- bool Variadic, bool HasTrailingReturn,
- unsigned Quals, RefQualifierKind RefQualifier,
+ llvm::MutableArrayRef<QualType> ParamTypes,
SourceLocation Loc, DeclarationName Entity,
- FunctionType::ExtInfo Info);
+ const FunctionProtoType::ExtProtoInfo &EPI);
+
QualType BuildMemberPointerType(QualType T, QualType Class,
SourceLocation Loc,
DeclarationName Entity);
@@ -943,7 +1001,7 @@ public:
CanThrowResult canThrow(const Expr *E);
const FunctionProtoType *ResolveExceptionSpec(SourceLocation Loc,
const FunctionProtoType *FPT);
- bool CheckSpecifiedExceptionType(QualType T, const SourceRange &Range);
+ bool CheckSpecifiedExceptionType(QualType &T, const SourceRange &Range);
bool CheckDistantExceptionSpec(QualType T);
bool CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New);
bool CheckEquivalentExceptionSpec(
@@ -1291,8 +1349,8 @@ public:
Decl *ActOnDeclarator(Scope *S, Declarator &D);
- Decl *HandleDeclarator(Scope *S, Declarator &D,
- MultiTemplateParamsArg TemplateParameterLists);
+ NamedDecl *HandleDeclarator(Scope *S, Declarator &D,
+ MultiTemplateParamsArg TemplateParameterLists);
void RegisterLocallyScopedExternCDecl(NamedDecl *ND,
const LookupResult &Previous,
Scope *S);
@@ -1300,7 +1358,7 @@ public:
bool diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC,
DeclarationName Name,
SourceLocation Loc);
- void DiagnoseFunctionSpecifiers(Declarator& D);
+ void DiagnoseFunctionSpecifiers(const DeclSpec &DS);
void CheckShadow(Scope *S, VarDecl *D, const LookupResult& R);
void CheckShadow(Scope *S, VarDecl *D);
void CheckCastAlign(Expr *Op, QualType T, SourceRange TRange);
@@ -1317,6 +1375,7 @@ public:
// Returns true if the variable declaration is a redeclaration
bool CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous);
void CheckCompleteVariableDeclaration(VarDecl *var);
+ void MaybeSuggestAddingStaticToDecl(const FunctionDecl *D);
void ActOnStartFunctionDeclarator();
void ActOnEndFunctionDeclarator();
NamedDecl* ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
@@ -1343,7 +1402,7 @@ public:
ParmVarDecl *CheckParameter(DeclContext *DC, SourceLocation StartLoc,
SourceLocation NameLoc, IdentifierInfo *Name,
QualType T, TypeSourceInfo *TSInfo,
- StorageClass SC, StorageClass SCAsWritten);
+ StorageClass SC);
void ActOnParamDefaultArgument(Decl *param,
SourceLocation EqualLoc,
Expr *defarg);
@@ -1383,9 +1442,19 @@ public:
return D && isa<ObjCMethodDecl>(D);
}
+ /// \brief Determine whether we can skip parsing the body of a function
+ /// definition, assuming we don't care about analyzing its body or emitting
+ /// code for that function.
+ ///
+ /// This will be \c false only if we may need the body of the function in
+ /// order to parse the rest of the program (for instance, if it is
+ /// \c constexpr in C++11 or has an 'auto' return type in C++14).
+ bool canSkipFunctionBody(Decl *D);
+
void computeNRVO(Stmt *Body, sema::FunctionScopeInfo *Scope);
Decl *ActOnFinishFunctionBody(Decl *Decl, Stmt *Body);
Decl *ActOnFinishFunctionBody(Decl *Decl, Stmt *Body, bool IsInstantiation);
+ Decl *ActOnSkippedFunctionBody(Decl *Decl);
/// ActOnFinishDelayedAttribute - Invoked when we have finished parsing an
/// attribute for which parsing is delayed.
@@ -1409,6 +1478,11 @@ public:
SourceLocation AsmLoc,
SourceLocation RParenLoc);
+ /// \brief Handle a C++11 empty-declaration and attribute-declaration.
+ Decl *ActOnEmptyDeclaration(Scope *S,
+ AttributeList *AttrList,
+ SourceLocation SemiLoc);
+
/// \brief The parser has processed a module import declaration.
///
/// \param AtLoc The location of the '@' symbol, if any.
@@ -1419,6 +1493,14 @@ public:
DeclResult ActOnModuleImport(SourceLocation AtLoc, SourceLocation ImportLoc,
ModuleIdPath Path);
+ /// \brief Create an implicit import of the given module at the given
+ /// source location.
+ ///
+ /// This routine is typically used for error recovery, when the entity found
+ /// by name lookup is actually hidden within a module that we know about but
+ /// the user has forgotten to import.
+ void createImplicitModuleImport(SourceLocation Loc, Module *Mod);
+
/// \brief Retrieve a suitable printing policy.
PrintingPolicy getPrintingPolicy() const {
return getPrintingPolicy(Context, PP);
@@ -1436,7 +1518,8 @@ public:
DeclSpec &DS);
Decl *ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
DeclSpec &DS,
- MultiTemplateParamsArg TemplateParams);
+ MultiTemplateParamsArg TemplateParams,
+ bool IsExplicitInstantiation = false);
Decl *BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
AccessSpecifier AS,
@@ -1502,17 +1585,10 @@ public:
AccessSpecifier AS, NamedDecl *PrevDecl,
Declarator *D = 0);
- enum CXXSpecialMember {
- CXXDefaultConstructor,
- CXXCopyConstructor,
- CXXMoveConstructor,
- CXXCopyAssignment,
- CXXMoveAssignment,
- CXXDestructor,
- CXXInvalid
- };
bool CheckNontrivialField(FieldDecl *FD);
- void DiagnoseNontrivial(const RecordType* Record, CXXSpecialMember mem);
+ void DiagnoseNontrivial(const CXXRecordDecl *Record, CXXSpecialMember CSM);
+ bool SpecialMemberIsTrivial(CXXMethodDecl *MD, CXXSpecialMember CSM,
+ bool Diagnose = false);
CXXSpecialMember getSpecialMember(const CXXMethodDecl *MD);
void ActOnLastBitfield(SourceLocation DeclStart,
SmallVectorImpl<Decl *> &AllIvarDecls);
@@ -1522,7 +1598,7 @@ public:
// This is used for both record definitions and ObjC interface declarations.
void ActOnFields(Scope* S, SourceLocation RecLoc, Decl *TagDecl,
- llvm::ArrayRef<Decl *> Fields,
+ ArrayRef<Decl *> Fields,
SourceLocation LBrac, SourceLocation RBrac,
AttributeList *AttrList);
@@ -1639,30 +1715,54 @@ public:
bool isIncompatibleTypedef(TypeDecl *Old, TypedefNameDecl *New);
/// Attribute merging methods. Return true if a new attribute was added.
- AvailabilityAttr *mergeAvailabilityAttr(Decl *D, SourceRange Range,
+ AvailabilityAttr *mergeAvailabilityAttr(NamedDecl *D, SourceRange Range,
IdentifierInfo *Platform,
VersionTuple Introduced,
VersionTuple Deprecated,
VersionTuple Obsoleted,
bool IsUnavailable,
- StringRef Message);
+ StringRef Message,
+ bool Override,
+ unsigned AttrSpellingListIndex);
+ TypeVisibilityAttr *mergeTypeVisibilityAttr(Decl *D, SourceRange Range,
+ TypeVisibilityAttr::VisibilityType Vis,
+ unsigned AttrSpellingListIndex);
VisibilityAttr *mergeVisibilityAttr(Decl *D, SourceRange Range,
- VisibilityAttr::VisibilityType Vis);
- DLLImportAttr *mergeDLLImportAttr(Decl *D, SourceRange Range);
- DLLExportAttr *mergeDLLExportAttr(Decl *D, SourceRange Range);
+ VisibilityAttr::VisibilityType Vis,
+ unsigned AttrSpellingListIndex);
+ DLLImportAttr *mergeDLLImportAttr(Decl *D, SourceRange Range,
+ unsigned AttrSpellingListIndex);
+ DLLExportAttr *mergeDLLExportAttr(Decl *D, SourceRange Range,
+ unsigned AttrSpellingListIndex);
FormatAttr *mergeFormatAttr(Decl *D, SourceRange Range, StringRef Format,
- int FormatIdx, int FirstArg);
- SectionAttr *mergeSectionAttr(Decl *D, SourceRange Range, StringRef Name);
- bool mergeDeclAttribute(Decl *New, InheritableAttr *Attr);
+ int FormatIdx, int FirstArg,
+ unsigned AttrSpellingListIndex);
+ SectionAttr *mergeSectionAttr(Decl *D, SourceRange Range, StringRef Name,
+ unsigned AttrSpellingListIndex);
+
+ /// \brief Describes the kind of merge to perform for availability
+ /// attributes (including "deprecated", "unavailable", and "availability").
+ enum AvailabilityMergeKind {
+ /// \brief Don't merge availability attributes at all.
+ AMK_None,
+ /// \brief Merge availability attributes for a redeclaration, which requires
+ /// an exact match.
+ AMK_Redeclaration,
+ /// \brief Merge availability attributes for an override, which requires
+ /// an exact match or a weakening of constraints.
+ AMK_Override
+ };
- void mergeDeclAttributes(Decl *New, Decl *Old, bool MergeDeprecation = true);
+ void mergeDeclAttributes(NamedDecl *New, Decl *Old,
+ AvailabilityMergeKind AMK = AMK_Redeclaration);
void MergeTypedefNameDecl(TypedefNameDecl *New, LookupResult &OldDecls);
bool MergeFunctionDecl(FunctionDecl *New, Decl *Old, Scope *S);
bool MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old,
Scope *S);
void mergeObjCMethodDecls(ObjCMethodDecl *New, ObjCMethodDecl *Old);
- void MergeVarDecl(VarDecl *New, LookupResult &OldDecls);
- void MergeVarDeclTypes(VarDecl *New, VarDecl *Old);
+ void MergeVarDecl(VarDecl *New, LookupResult &OldDecls,
+ bool OldDeclsWereHidden);
+ void MergeVarDeclTypes(VarDecl *New, VarDecl *Old, bool OldIsHidden);
void MergeVarDeclExceptionSpecs(VarDecl *New, VarDecl *Old);
bool MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old, Scope *S);
@@ -1841,6 +1941,19 @@ public:
};
ObjCSubscriptKind CheckSubscriptingKind(Expr *FromE);
+ // Note that LK_String is intentionally after the other literals, as
+ // this is used for diagnostics logic.
+ enum ObjCLiteralKind {
+ LK_Array,
+ LK_Dictionary,
+ LK_Numeric,
+ LK_Boxed,
+ LK_String,
+ LK_Block,
+ LK_None
+ };
+ ObjCLiteralKind CheckLiteralKind(Expr *FromE);
+
ExprResult PerformObjectMemberConversion(Expr *From,
NestedNameSpecifier *Qualifier,
NamedDecl *FoundDecl,
@@ -1853,13 +1966,13 @@ public:
void AddOverloadCandidate(FunctionDecl *Function,
DeclAccessPair FoundDecl,
- llvm::ArrayRef<Expr *> Args,
+ ArrayRef<Expr *> Args,
OverloadCandidateSet& CandidateSet,
bool SuppressUserConversions = false,
bool PartialOverloading = false,
bool AllowExplicit = false);
void AddFunctionCandidates(const UnresolvedSetImpl &Functions,
- llvm::ArrayRef<Expr *> Args,
+ ArrayRef<Expr *> Args,
OverloadCandidateSet& CandidateSet,
bool SuppressUserConversions = false,
TemplateArgumentListInfo *ExplicitTemplateArgs = 0);
@@ -1873,7 +1986,7 @@ public:
DeclAccessPair FoundDecl,
CXXRecordDecl *ActingContext, QualType ObjectType,
Expr::Classification ObjectClassification,
- llvm::ArrayRef<Expr *> Args,
+ ArrayRef<Expr *> Args,
OverloadCandidateSet& CandidateSet,
bool SuppressUserConversions = false);
void AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,
@@ -1882,13 +1995,13 @@ public:
TemplateArgumentListInfo *ExplicitTemplateArgs,
QualType ObjectType,
Expr::Classification ObjectClassification,
- llvm::ArrayRef<Expr *> Args,
+ ArrayRef<Expr *> Args,
OverloadCandidateSet& CandidateSet,
bool SuppressUserConversions = false);
void AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
DeclAccessPair FoundDecl,
TemplateArgumentListInfo *ExplicitTemplateArgs,
- llvm::ArrayRef<Expr *> Args,
+ ArrayRef<Expr *> Args,
OverloadCandidateSet& CandidateSet,
bool SuppressUserConversions = false);
void AddConversionCandidate(CXXConversionDecl *Conversion,
@@ -1905,7 +2018,7 @@ public:
DeclAccessPair FoundDecl,
CXXRecordDecl *ActingContext,
const FunctionProtoType *Proto,
- Expr *Object, llvm::ArrayRef<Expr*> Args,
+ Expr *Object, ArrayRef<Expr *> Args,
OverloadCandidateSet& CandidateSet);
void AddMemberOperatorCandidates(OverloadedOperatorKind Op,
SourceLocation OpLoc,
@@ -1923,7 +2036,7 @@ public:
OverloadCandidateSet& CandidateSet);
void AddArgumentDependentLookupCandidates(DeclarationName Name,
bool Operator, SourceLocation Loc,
- llvm::ArrayRef<Expr *> Args,
+ ArrayRef<Expr *> Args,
TemplateArgumentListInfo *ExplicitTemplateArgs,
OverloadCandidateSet& CandidateSet,
bool PartialOverloading = false);
@@ -1971,7 +2084,7 @@ public:
FunctionDecl *Fn);
void AddOverloadedCallCandidates(UnresolvedLookupExpr *ULE,
- llvm::ArrayRef<Expr *> Args,
+ ArrayRef<Expr *> Args,
OverloadCandidateSet &CandidateSet,
bool PartialOverloading = false);
@@ -2164,7 +2277,7 @@ private:
//
// The boolean value will be true to indicate that the namespace was loaded
// from an AST/PCH file, or false otherwise.
- llvm::DenseMap<NamespaceDecl*, bool> KnownNamespaces;
+ llvm::MapVector<NamespaceDecl*, bool> KnownNamespaces;
/// \brief Whether we have already loaded known namespaces from an extenal
/// source.
@@ -2218,7 +2331,7 @@ public:
void ArgumentDependentLookup(DeclarationName Name, bool Operator,
SourceLocation Loc,
- llvm::ArrayRef<Expr *> Args,
+ ArrayRef<Expr *> Args,
ADLResult &Functions);
void LookupVisibleDecls(Scope *S, LookupNameKind Kind,
@@ -2237,7 +2350,7 @@ public:
const ObjCObjectPointerType *OPT = 0);
void FindAssociatedClassesAndNamespaces(SourceLocation InstantiationLoc,
- llvm::ArrayRef<Expr *> Args,
+ ArrayRef<Expr *> Args,
AssociatedNamespaceSet &AssociatedNamespaces,
AssociatedClassSet &AssociatedClasses);
@@ -2260,19 +2373,25 @@ public:
// More parsing and symbol table subroutines.
+ void ProcessPragmaWeak(Scope *S, Decl *D);
// Decl attributes - this routine is the top level dispatcher.
void ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD,
- bool NonInheritable = true, bool Inheritable = true);
+ bool NonInheritable = true,
+ bool Inheritable = true);
void ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AL,
- bool NonInheritable = true, bool Inheritable = true);
+ bool NonInheritable = true,
+ bool Inheritable = true,
+ bool IncludeCXX11Attributes = true);
bool ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl,
const AttributeList *AttrList);
void checkUnusedDeclAttributes(Declarator &D);
bool CheckRegparmAttr(const AttributeList &attr, unsigned &value);
- bool CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC);
+ bool CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC,
+ const FunctionDecl *FD = 0);
bool CheckNoReturnAttr(const AttributeList &attr);
+ void CheckAlignasUnderalignment(Decl *D);
/// \brief Stmt attributes - this routine is the top level dispatcher.
StmtResult ProcessStmtAttributes(Stmt *Stmt, AttributeList *Attrs,
@@ -2339,21 +2458,27 @@ public:
llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap,
llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& SuperPropMap);
+ /// IvarBacksCurrentMethodAccessor - This routine returns 'true' if 'IV' is
+ /// an ivar synthesized for 'Method' and 'Method' is a property accessor
+ /// declared in class 'IFace'.
+ bool IvarBacksCurrentMethodAccessor(ObjCInterfaceDecl *IFace,
+ ObjCMethodDecl *Method, ObjCIvarDecl *IV);
+
/// Called by ActOnProperty to handle \@property declarations in
/// class extensions.
- Decl *HandlePropertyInClassExtension(Scope *S,
- SourceLocation AtLoc,
- SourceLocation LParenLoc,
- FieldDeclarator &FD,
- Selector GetterSel,
- Selector SetterSel,
- const bool isAssign,
- const bool isReadWrite,
- const unsigned Attributes,
- const unsigned AttributesAsWritten,
- bool *isOverridingProperty,
- TypeSourceInfo *T,
- tok::ObjCKeywordKind MethodImplKind);
+ ObjCPropertyDecl *HandlePropertyInClassExtension(Scope *S,
+ SourceLocation AtLoc,
+ SourceLocation LParenLoc,
+ FieldDeclarator &FD,
+ Selector GetterSel,
+ Selector SetterSel,
+ const bool isAssign,
+ const bool isReadWrite,
+ const unsigned Attributes,
+ const unsigned AttributesAsWritten,
+ bool *isOverridingProperty,
+ TypeSourceInfo *T,
+ tok::ObjCKeywordKind MethodImplKind);
/// Called by ActOnProperty and HandlePropertyInClassExtension to
/// handle creating the ObjcPropertyDecl for a category or \@interface.
@@ -2507,8 +2632,15 @@ public:
FullExprArg MakeFullExpr(Expr *Arg, SourceLocation CC) {
return FullExprArg(ActOnFinishFullExpr(Arg, CC).release());
}
+ FullExprArg MakeFullDiscardedValueExpr(Expr *Arg) {
+ ExprResult FE =
+ ActOnFinishFullExpr(Arg, Arg ? Arg->getExprLoc() : SourceLocation(),
+ /*DiscardedValue*/ true);
+ return FullExprArg(FE.release());
+ }
- StmtResult ActOnExprStmt(FullExprArg Expr);
+ StmtResult ActOnExprStmt(ExprResult Arg);
+ StmtResult ActOnExprStmtError();
StmtResult ActOnNullStmt(SourceLocation SemiLoc,
bool HasLeadingEmptyMacro = false);
@@ -2616,7 +2748,7 @@ public:
SourceLocation StarLoc,
Expr *DestExp);
StmtResult ActOnContinueStmt(SourceLocation ContinueLoc, Scope *CurScope);
- StmtResult ActOnBreakStmt(SourceLocation GotoLoc, Scope *CurScope);
+ StmtResult ActOnBreakStmt(SourceLocation BreakLoc, Scope *CurScope);
const VarDecl *getCopyElisionCandidate(QualType ReturnType, Expr *E,
bool AllowFunctionParameters);
@@ -2632,7 +2764,8 @@ public:
SourceLocation RParenLoc);
NamedDecl *LookupInlineAsmIdentifier(StringRef Name, SourceLocation Loc,
- unsigned &Size);
+ unsigned &Length, unsigned &Size,
+ unsigned &Type, bool &IsVarDecl);
bool LookupInlineAsmField(StringRef Base, StringRef Member,
unsigned &Offset, SourceLocation AsmLoc);
StmtResult ActOnMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
@@ -2766,7 +2899,7 @@ public:
void DiscardCleanupsInEvaluationContext();
- ExprResult TranformToPotentiallyEvaluated(Expr *E);
+ ExprResult TransformToPotentiallyEvaluated(Expr *E);
ExprResult HandleExprEvaluationContextForTypeof(Expr *E);
ExprResult ActOnConstantExpression(ExprResult Res);
@@ -2777,7 +2910,7 @@ public:
// for expressions referring to a decl; these exist because odr-use marking
// needs to be delayed for some constant variables when we build one of the
// named expressions.
- void MarkAnyDeclReferenced(SourceLocation Loc, Decl *D);
+ void MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, bool OdrUse);
void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func);
void MarkVariableReferenced(SourceLocation Loc, VarDecl *Var);
void MarkDeclRefReferenced(DeclRefExpr *E);
@@ -2873,7 +3006,7 @@ public:
bool DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
CorrectionCandidateCallback &CCC,
TemplateArgumentListInfo *ExplicitTemplateArgs = 0,
- llvm::ArrayRef<Expr *> Args = llvm::ArrayRef<Expr *>());
+ ArrayRef<Expr *> Args = ArrayRef<Expr *>());
ExprResult LookupInObjCMethod(LookupResult &LookUp, Scope *S,
IdentifierInfo *II,
@@ -2892,7 +3025,8 @@ public:
ExprResult BuildDeclRefExpr(ValueDecl *D, QualType Ty,
ExprValueKind VK,
const DeclarationNameInfo &NameInfo,
- const CXXScopeSpec *SS = 0);
+ const CXXScopeSpec *SS = 0,
+ NamedDecl *FoundD = 0);
ExprResult
BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS,
SourceLocation nameLoc,
@@ -2925,7 +3059,7 @@ public:
bool NeedsADL);
ExprResult BuildDeclarationNameExpr(const CXXScopeSpec &SS,
const DeclarationNameInfo &NameInfo,
- NamedDecl *D);
+ NamedDecl *D, NamedDecl *FoundD = 0);
ExprResult BuildLiteralOperatorCall(LookupResult &R,
DeclarationNameInfo &SuffixInfo,
@@ -3334,15 +3468,9 @@ public:
MultiTemplateParamsArg TemplateParams,
SourceLocation UsingLoc,
UnqualifiedId &Name,
+ AttributeList *AttrList,
TypeResult Type);
- /// InitializeVarWithConstructor - Creates an CXXConstructExpr
- /// and sets it as the initializer for the passed in VarDecl.
- bool InitializeVarWithConstructor(VarDecl *VD,
- CXXConstructorDecl *Constructor,
- MultiExprArg Exprs,
- bool HadMultipleCandidates);
-
/// BuildCXXConstructExpr - Creates a complete call to a constructor,
/// including handling of its default argument expressions.
///
@@ -3350,8 +3478,9 @@ public:
ExprResult
BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
CXXConstructorDecl *Constructor, MultiExprArg Exprs,
- bool HadMultipleCandidates, bool RequiresZeroInit,
- unsigned ConstructKind, SourceRange ParenRange);
+ bool HadMultipleCandidates, bool IsListInitialization,
+ bool RequiresZeroInit, unsigned ConstructKind,
+ SourceRange ParenRange);
// FIXME: Can re remove this and have the above BuildCXXConstructExpr check if
// the constructor can be elidable?
@@ -3359,8 +3488,8 @@ public:
BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
CXXConstructorDecl *Constructor, bool Elidable,
MultiExprArg Exprs, bool HadMultipleCandidates,
- bool RequiresZeroInit, unsigned ConstructKind,
- SourceRange ParenRange);
+ bool IsListInitialization, bool RequiresZeroInit,
+ unsigned ConstructKind, SourceRange ParenRange);
/// BuildCXXDefaultArgExpr - Creates a CXXDefaultArgExpr, instantiating
/// the default expr if needed.
@@ -3395,7 +3524,7 @@ public:
public:
explicit ImplicitExceptionSpecification(Sema &Self)
: Self(&Self), ComputedEST(EST_BasicNoexcept) {
- if (!Self.getLangOpts().CPlusPlus0x)
+ if (!Self.getLangOpts().CPlusPlus11)
ComputedEST = EST_DynamicNone;
}
@@ -3474,6 +3603,11 @@ public:
ImplicitExceptionSpecification
ComputeDefaultedDtorExceptionSpec(CXXMethodDecl *MD);
+ /// \brief Determine what sort of exception specification an inheriting
+ /// constructor of a class will have.
+ ImplicitExceptionSpecification
+ ComputeInheritingCtorExceptionSpec(CXXMethodDecl *MD);
+
/// \brief Evaluate the implicit exception specification for a defaulted
/// special member function.
void EvaluateImplicitExceptionSpec(SourceLocation Loc, CXXMethodDecl *MD);
@@ -3484,7 +3618,7 @@ public:
ArrayRef<ParsedType> DynamicExceptions,
ArrayRef<SourceRange> DynamicExceptionRanges,
Expr *NoexceptExpr,
- llvm::SmallVectorImpl<QualType> &Exceptions,
+ SmallVectorImpl<QualType> &Exceptions,
FunctionProtoType::ExtProtoInfo &EPI);
/// \brief Determine if a special member function should have a deleted
@@ -3526,11 +3660,15 @@ public:
void AdjustDestructorExceptionSpec(CXXRecordDecl *ClassDecl,
CXXDestructorDecl *Destructor);
- /// \brief Declare all inherited constructors for the given class.
+ /// \brief Declare all inheriting constructors for the given class.
///
- /// \param ClassDecl The class declaration into which the inherited
+ /// \param ClassDecl The class declaration into which the inheriting
/// constructors will be added.
- void DeclareInheritedConstructors(CXXRecordDecl *ClassDecl);
+ void DeclareInheritingConstructors(CXXRecordDecl *ClassDecl);
+
+ /// \brief Define the specified inheriting constructor.
+ void DefineInheritingConstructor(SourceLocation UseLoc,
+ CXXConstructorDecl *Constructor);
/// \brief Declare the implicit copy constructor for the given class.
///
@@ -3617,7 +3755,12 @@ public:
MultiExprArg ArgsPtr,
SourceLocation Loc,
SmallVectorImpl<Expr*> &ConvertedArgs,
- bool AllowExplicit = false);
+ bool AllowExplicit = false,
+ bool IsListInitialization = false);
+
+ ParsedType getInheritingConstructorName(CXXScopeSpec &SS,
+ SourceLocation NameLoc,
+ IdentifierInfo &Name);
ParsedType getDestructorName(SourceLocation TildeLoc,
IdentifierInfo &II, SourceLocation NameLoc,
@@ -3917,7 +4060,9 @@ public:
return ActOnFinishFullExpr(Expr, Expr ? Expr->getExprLoc()
: SourceLocation());
}
- ExprResult ActOnFinishFullExpr(Expr *Expr, SourceLocation CC);
+ ExprResult ActOnFinishFullExpr(Expr *Expr, SourceLocation CC,
+ bool DiscardedValue = false,
+ bool IsConstexpr = false);
StmtResult ActOnFinishFullStmt(Stmt *Stmt);
// Marks SS invalid if it represents an incomplete type.
@@ -3943,7 +4088,7 @@ public:
bool ActOnCXXGlobalScopeSpecifier(Scope *S, SourceLocation CCLoc,
CXXScopeSpec &SS);
- bool isAcceptableNestedNameSpecifier(NamedDecl *SD);
+ bool isAcceptableNestedNameSpecifier(const NamedDecl *SD);
NamedDecl *FindFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS);
bool isNonTypeNestedNameSpecifier(Scope *S, CXXScopeSpec &SS,
@@ -4100,7 +4245,7 @@ public:
SourceRange IntroducerRange,
TypeSourceInfo *MethodType,
SourceLocation EndLoc,
- llvm::ArrayRef<ParmVarDecl *> Params);
+ ArrayRef<ParmVarDecl *> Params);
/// \brief Introduce the scope for a lambda expression.
sema::LambdaScopeInfo *enterLambdaScope(CXXMethodDecl *CallOperator,
@@ -4247,7 +4392,7 @@ public:
SourceLocation ColonLoc,
AttributeList *Attrs = 0);
- Decl *ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS,
+ NamedDecl *ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS,
Declarator &D,
MultiTemplateParamsArg TemplateParameterLists,
Expr *BitfieldWidth, const VirtSpecifiers &VS,
@@ -4304,9 +4449,9 @@ public:
bool SetDelegatingInitializer(CXXConstructorDecl *Constructor,
CXXCtorInitializer *Initializer);
- bool SetCtorInitializers(CXXConstructorDecl *Constructor,
- CXXCtorInitializer **Initializers,
- unsigned NumInitializers, bool AnyErrors);
+ bool SetCtorInitializers(CXXConstructorDecl *Constructor, bool AnyErrors,
+ ArrayRef<CXXCtorInitializer *> Initializers =
+ ArrayRef<CXXCtorInitializer *>());
void SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation);
@@ -4369,8 +4514,7 @@ public:
void ActOnMemInitializers(Decl *ConstructorDecl,
SourceLocation ColonLoc,
- CXXCtorInitializer **MemInits,
- unsigned NumMemInits,
+ ArrayRef<CXXCtorInitializer*> MemInits,
bool AnyErrors);
void CheckCompletedCXXClass(CXXRecordDecl *Record);
@@ -4407,8 +4551,8 @@ public:
TypeSourceInfo *TSInfo);
Decl *ActOnFriendTypeDecl(Scope *S, const DeclSpec &DS,
MultiTemplateParamsArg TemplateParams);
- Decl *ActOnFriendFunctionDecl(Scope *S, Declarator &D,
- MultiTemplateParamsArg TemplateParams);
+ NamedDecl *ActOnFriendFunctionDecl(Scope *S, Declarator &D,
+ MultiTemplateParamsArg TemplateParams);
QualType CheckConstructorDeclarator(Declarator &D, QualType R,
StorageClass& SC);
@@ -4420,8 +4564,10 @@ public:
StorageClass& SC);
Decl *ActOnConversionDeclarator(CXXConversionDecl *Conversion);
- void CheckExplicitlyDefaultedMethods(CXXRecordDecl *Record);
void CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD);
+ void CheckExplicitlyDefaultedMemberExceptionSpec(CXXMethodDecl *MD,
+ const FunctionProtoType *T);
+ void CheckDelayedExplicitlyDefaultedMemberExceptionSpecs();
//===--------------------------------------------------------------------===//
// C++ Derived Classes
@@ -4436,6 +4582,7 @@ public:
BaseResult ActOnBaseSpecifier(Decl *classdecl,
SourceRange SpecifierRange,
+ ParsedAttributes &Attrs,
bool Virtual, AccessSpecifier Access,
ParsedType basetype,
SourceLocation BaseLoc,
@@ -4467,6 +4614,9 @@ public:
std::string getAmbiguousPathsDisplayString(CXXBasePaths &Paths);
+ bool CheckOverridingFunctionAttributes(const CXXMethodDecl *New,
+ const CXXMethodDecl *Old);
+
/// CheckOverridingFunctionReturnType - Checks whether the return types are
/// covariant, according to C++ [class.virtual]p5.
bool CheckOverridingFunctionReturnType(const CXXMethodDecl *New,
@@ -5234,14 +5384,14 @@ public:
/// expansion.
TypeSourceInfo *CheckPackExpansion(TypeSourceInfo *Pattern,
SourceLocation EllipsisLoc,
- llvm::Optional<unsigned> NumExpansions);
+ Optional<unsigned> NumExpansions);
/// \brief Construct a pack expansion type from the pattern of the pack
/// expansion.
QualType CheckPackExpansion(QualType Pattern,
SourceRange PatternRange,
SourceLocation EllipsisLoc,
- llvm::Optional<unsigned> NumExpansions);
+ Optional<unsigned> NumExpansions);
/// \brief Invoked when parsing an expression followed by an ellipsis, which
/// creates a pack expansion.
@@ -5260,7 +5410,7 @@ public:
///
/// \param EllipsisLoc The location of the ellipsis.
ExprResult CheckPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
- llvm::Optional<unsigned> NumExpansions);
+ Optional<unsigned> NumExpansions);
/// \brief Determine whether we could expand a pack expansion with the
/// given set of parameter packs into separate arguments by repeatedly
@@ -5298,11 +5448,11 @@ public:
/// must be set.
bool CheckParameterPacksForExpansion(SourceLocation EllipsisLoc,
SourceRange PatternRange,
- llvm::ArrayRef<UnexpandedParameterPack> Unexpanded,
+ ArrayRef<UnexpandedParameterPack> Unexpanded,
const MultiLevelTemplateArgumentList &TemplateArgs,
bool &ShouldExpand,
bool &RetainExpansion,
- llvm::Optional<unsigned> &NumExpansions);
+ Optional<unsigned> &NumExpansions);
/// \brief Determine the number of arguments in the given pack expansion
/// type.
@@ -5311,8 +5461,8 @@ public:
/// consistent across all of the unexpanded parameter packs in its pattern.
///
/// Returns an empty Optional if the type can't be expanded.
- llvm::Optional<unsigned> getNumArgumentsInExpansion(QualType T,
- const MultiLevelTemplateArgumentList &TemplateArgs);
+ Optional<unsigned> getNumArgumentsInExpansion(QualType T,
+ const MultiLevelTemplateArgumentList &TemplateArgs);
/// \brief Determine whether the given declarator contains any unexpanded
/// parameter packs.
@@ -5366,10 +5516,8 @@ public:
/// \brief Substitution of the deduced template argument values
/// resulted in an error.
TDK_SubstitutionFailure,
- /// \brief Substitution of the deduced template argument values
- /// into a non-deduced context produced a type or value that
- /// produces a type that does not match the original template
- /// arguments provided.
+ /// \brief A non-depnedent component of the parameter did not match the
+ /// corresponding component of the argument.
TDK_NonDeducedMismatch,
/// \brief When performing template argument deduction for a function
/// template, there were too many call arguments.
@@ -5382,7 +5530,9 @@ public:
TDK_InvalidExplicitArguments,
/// \brief The arguments included an overloaded function name that could
/// not be resolved to a suitable function.
- TDK_FailedOverloadResolution
+ TDK_FailedOverloadResolution,
+ /// \brief Deduction failed; that's all we know.
+ TDK_MiscellaneousDeductionFailure
};
TemplateDeductionResult
@@ -5423,7 +5573,7 @@ public:
TemplateDeductionResult
DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
TemplateArgumentListInfo *ExplicitTemplateArgs,
- llvm::ArrayRef<Expr *> Args,
+ ArrayRef<Expr *> Args,
FunctionDecl *&Specialization,
sema::TemplateDeductionInfo &Info);
@@ -5483,13 +5633,14 @@ public:
bool OnlyDeduced,
unsigned Depth,
llvm::SmallBitVector &Used);
- void MarkDeducedTemplateParameters(FunctionTemplateDecl *FunctionTemplate,
- llvm::SmallBitVector &Deduced) {
+ void MarkDeducedTemplateParameters(
+ const FunctionTemplateDecl *FunctionTemplate,
+ llvm::SmallBitVector &Deduced) {
return MarkDeducedTemplateParameters(Context, FunctionTemplate, Deduced);
}
static void MarkDeducedTemplateParameters(ASTContext &Ctx,
- FunctionTemplateDecl *FunctionTemplate,
- llvm::SmallBitVector &Deduced);
+ const FunctionTemplateDecl *FunctionTemplate,
+ llvm::SmallBitVector &Deduced);
//===--------------------------------------------------------------------===//
// C++ Template Instantiation
@@ -5554,7 +5705,7 @@ public:
NamedDecl *Template;
/// \brief The entity that is being instantiated.
- uintptr_t Entity;
+ Decl *Entity;
/// \brief The list of template arguments we are substituting, if they
/// are not part of the entity.
@@ -5796,11 +5947,11 @@ public:
/// template argument substitution failures are not considered
/// errors.
///
- /// \returns An empty \c llvm::Optional if we're not in a SFINAE context.
+ /// \returns An empty \c Optional if we're not in a SFINAE context.
/// Otherwise, contains a pointer that, if non-NULL, contains the nearest
/// template-deduction context object, which can be used to capture
/// diagnostics that will be suppressed.
- llvm::Optional<sema::TemplateDeductionInfo *> isSFINAEContext() const;
+ Optional<sema::TemplateDeductionInfo *> isSFINAEContext() const;
/// \brief Determines whether we are currently in a context that
/// is not evaluated as per C++ [expr] p5.
@@ -5911,7 +6062,7 @@ public:
ParmVarDecl *SubstParmVarDecl(ParmVarDecl *D,
const MultiLevelTemplateArgumentList &TemplateArgs,
int indexAdjustment,
- llvm::Optional<unsigned> NumExpansions,
+ Optional<unsigned> NumExpansions,
bool ExpectParameterPack);
bool SubstParmTypes(SourceLocation Loc,
ParmVarDecl **Params, unsigned NumParams,
@@ -6141,10 +6292,6 @@ public:
void DiagnosePropertyMismatch(ObjCPropertyDecl *Property,
ObjCPropertyDecl *SuperProperty,
const IdentifierInfo *Name);
- void ComparePropertiesInBaseAndSuper(ObjCInterfaceDecl *IDecl);
-
-
- void CompareProperties(Decl *CDecl, Decl *MergeProtocols);
void DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT,
ObjCInterfaceDecl *ID);
@@ -6214,6 +6361,7 @@ public:
ObjCMethodDecl *LookupMethodInObjectType(Selector Sel, QualType Ty,
bool IsInstance);
+ bool CheckARCMethodDecl(ObjCMethodDecl *method);
bool inferObjCARCLifetime(ValueDecl *decl);
ExprResult
@@ -6324,14 +6472,13 @@ public:
ParsedType Type,
SourceLocation RParenLoc,
Expr *SubExpr);
-
+
bool checkInitMethod(ObjCMethodDecl *method, QualType receiverTypeIfCall);
/// \brief Check whether the given new method is a valid override of the
/// given overridden method, and set any properties that should be inherited.
void CheckObjCMethodOverride(ObjCMethodDecl *NewMethod,
- const ObjCMethodDecl *Overridden,
- bool IsImplementation);
+ const ObjCMethodDecl *Overridden);
/// \brief Describes the compatibility of a result type with its method.
enum ResultTypeCompatibilityKind {
@@ -6450,9 +6597,21 @@ public:
/// AddAlignedAttr - Adds an aligned attribute to a particular declaration.
void AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E,
- bool isDeclSpec);
+ unsigned SpellingListIndex, bool IsPackExpansion);
void AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *T,
- bool isDeclSpec);
+ unsigned SpellingListIndex, bool IsPackExpansion);
+
+ // OpenMP directives and clauses.
+
+ /// \brief Called on well-formed '#pragma omp threadprivate'.
+ DeclGroupPtrTy ActOnOpenMPThreadprivateDirective(
+ SourceLocation Loc,
+ Scope *CurScope,
+ ArrayRef<DeclarationNameInfo> IdList);
+ /// \brief Build a new OpenMPThreadPrivateDecl and check its correctness.
+ OMPThreadPrivateDecl *CheckOMPThreadPrivateDecl(
+ SourceLocation Loc,
+ ArrayRef<DeclRefExpr *> VarList);
/// \brief The kind of conversion being performed.
enum CheckedConversionKind {
@@ -6541,7 +6700,8 @@ public:
Expr **Args, unsigned NumArgs,
SmallVector<Expr *, 8> &AllArgs,
VariadicCallType CallType = VariadicDoesNotApply,
- bool AllowExplicit = false);
+ bool AllowExplicit = false,
+ bool IsListInitialization = false);
// DefaultVariadicArgumentPromotion - Like DefaultArgumentPromotion, but
// will create a runtime trap if the resulting type is not a POD type.
@@ -6812,6 +6972,11 @@ public:
/// given type.
ExprResult forceUnknownAnyToType(Expr *E, QualType ToType);
+ /// \brief Type-check an expression that's being passed to an
+ /// __unknown_anytype parameter.
+ ExprResult checkUnknownAnyArg(SourceLocation callLoc,
+ Expr *result, QualType &paramType);
+
// CheckVectorCast - check type constraints for vectors.
// Since vectors are an extension, there are no C standard reference for this.
// We allow casting between vectors and integer datatypes of the same size.
@@ -6883,6 +7048,11 @@ public:
/// with a related result type, emit a note describing what happened.
void EmitRelatedResultTypeNote(const Expr *E);
+ /// \brief Given that we had incompatible pointer types in a return
+ /// statement, check whether we're in a method with a related result
+ /// type, and if so, emit a note describing what happened.
+ void EmitRelatedResultTypeNoteForReturn(QualType destType);
+
/// CheckBooleanCondition - Diagnose problems involving the use of
/// the given expression as a boolean condition (e.g. in an if
/// statement). Also performs the standard function and array
@@ -7033,7 +7203,7 @@ public:
void CodeCompleteTag(Scope *S, unsigned TagSpec);
void CodeCompleteTypeQualifiers(DeclSpec &DS);
void CodeCompleteCase(Scope *S);
- void CodeCompleteCall(Scope *S, Expr *Fn, llvm::ArrayRef<Expr *> Args);
+ void CodeCompleteCall(Scope *S, Expr *Fn, ArrayRef<Expr *> Args);
void CodeCompleteInitializer(Scope *S, Decl *D);
void CodeCompleteReturn(Scope *S);
void CodeCompleteAfterIf(Scope *S);
@@ -7150,12 +7320,11 @@ private:
bool CheckBlockCall(NamedDecl *NDecl, CallExpr *TheCall,
const FunctionProtoType *Proto);
void CheckConstructorCall(FunctionDecl *FDecl,
- Expr **Args,
- unsigned NumArgs,
+ ArrayRef<const Expr *> Args,
const FunctionProtoType *Proto,
SourceLocation Loc);
- void checkCall(NamedDecl *FDecl, Expr **Args, unsigned NumArgs,
+ void checkCall(NamedDecl *FDecl, ArrayRef<const Expr *> Args,
unsigned NumProtoArgs, bool IsMemberFunction,
SourceLocation Loc, SourceRange Range,
VariadicCallType CallType);
@@ -7203,7 +7372,7 @@ private:
};
StringLiteralCheckType checkFormatStringExpr(const Expr *E,
- Expr **Args, unsigned NumArgs,
+ ArrayRef<const Expr *> Args,
bool HasVAListArg,
unsigned format_idx,
unsigned firstDataArg,
@@ -7212,16 +7381,17 @@ private:
bool inFunctionCall = true);
void CheckFormatString(const StringLiteral *FExpr, const Expr *OrigFormatExpr,
- Expr **Args, unsigned NumArgs, bool HasVAListArg,
+ ArrayRef<const Expr *> Args, bool HasVAListArg,
unsigned format_idx, unsigned firstDataArg,
FormatStringType Type, bool inFunctionCall,
VariadicCallType CallType);
- bool CheckFormatArguments(const FormatAttr *Format, Expr **Args,
- unsigned NumArgs, bool IsCXXMember,
+ bool CheckFormatArguments(const FormatAttr *Format,
+ ArrayRef<const Expr *> Args,
+ bool IsCXXMember,
VariadicCallType CallType,
SourceLocation Loc, SourceRange Range);
- bool CheckFormatArguments(Expr **Args, unsigned NumArgs,
+ bool CheckFormatArguments(ArrayRef<const Expr *> Args,
bool HasVAListArg, unsigned format_idx,
unsigned firstDataArg, FormatStringType Type,
VariadicCallType CallType,
@@ -7245,6 +7415,13 @@ private:
SourceLocation ReturnLoc);
void CheckFloatComparison(SourceLocation Loc, Expr* LHS, Expr* RHS);
void CheckImplicitConversions(Expr *E, SourceLocation CC = SourceLocation());
+ void CheckForIntOverflow(Expr *E);
+ void CheckUnsequencedOperations(Expr *E);
+
+ /// \brief Perform semantic checks on a completed expression. This will either
+ /// be a full-expression or a default argument expression.
+ void CheckCompletedExpr(Expr *E, SourceLocation CheckLoc = SourceLocation(),
+ bool IsConstexpr = false);
void CheckBitFieldInitialization(SourceLocation InitLoc, FieldDecl *Field,
Expr *Init);
@@ -7290,6 +7467,8 @@ private:
/// The parser maintains this state here.
Scope *CurScope;
+ mutable IdentifierInfo *Ident_super;
+
protected:
friend class Parser;
friend class InitializationSequence;
@@ -7307,6 +7486,8 @@ public:
/// template substitution or instantiation.
Scope *getCurScope() const { return CurScope; }
+ IdentifierInfo *getSuperIdentifier() const;
+
Decl *getObjCDeclContext() const;
DeclContext *getCurLexicalContext() const {
diff --git a/include/clang/Sema/SemaInternal.h b/include/clang/Sema/SemaInternal.h
index 64b83e3bf612..bbf42721ba6d 100644
--- a/include/clang/Sema/SemaInternal.h
+++ b/include/clang/Sema/SemaInternal.h
@@ -15,9 +15,9 @@
#ifndef LLVM_CLANG_SEMA_SEMA_INTERNAL_H
#define LLVM_CLANG_SEMA_SEMA_INTERNAL_H
+#include "clang/AST/ASTContext.h"
#include "clang/Sema/Sema.h"
#include "clang/Sema/SemaDiagnostic.h"
-#include "clang/AST/ASTContext.h"
namespace clang {
diff --git a/include/clang/Sema/Template.h b/include/clang/Sema/Template.h
index bbccd259678a..492e5800bdad 100644
--- a/include/clang/Sema/Template.h
+++ b/include/clang/Sema/Template.h
@@ -14,6 +14,7 @@
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DeclVisitor.h"
+#include "clang/Sema/Sema.h"
#include "llvm/ADT/SmallVector.h"
#include <cassert>
#include <utility>
@@ -344,7 +345,16 @@ namespace clang {
void SetPartiallySubstitutedPack(NamedDecl *Pack,
const TemplateArgument *ExplicitArgs,
unsigned NumExplicitArgs);
-
+
+ /// \brief Reset the partially-substituted pack when it is no longer of
+ /// interest.
+ void ResetPartiallySubstitutedPack() {
+ assert(PartiallySubstitutedPack && "No partially-substituted pack");
+ PartiallySubstitutedPack = 0;
+ ArgsInPartiallySubstitutedPack = 0;
+ NumArgsInPartiallySubstitutedPack = 0;
+ }
+
/// \brief Retrieve the partially-substitued template parameter pack.
///
/// If there is no partially-substituted parameter pack, returns NULL.
@@ -420,6 +430,7 @@ namespace clang {
Decl *VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
Decl *VisitClassScopeFunctionSpecializationDecl(
ClassScopeFunctionSpecializationDecl *D);
+ Decl *VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D);
// Base case. FIXME: Remove once we can instantiate everything.
Decl *VisitDecl(Decl *D) {
diff --git a/include/clang/Sema/TemplateDeduction.h b/include/clang/Sema/TemplateDeduction.h
index 251a65990b3b..3abb8f1889e9 100644
--- a/include/clang/Sema/TemplateDeduction.h
+++ b/include/clang/Sema/TemplateDeduction.h
@@ -13,8 +13,8 @@
#ifndef LLVM_CLANG_SEMA_TEMPLATE_DEDUCTION_H
#define LLVM_CLANG_SEMA_TEMPLATE_DEDUCTION_H
-#include "clang/Basic/PartialDiagnostic.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/Basic/PartialDiagnostic.h"
#include "llvm/ADT/SmallVector.h"
namespace clang {
@@ -47,7 +47,7 @@ class TemplateDeductionInfo {
public:
TemplateDeductionInfo(SourceLocation Loc)
- : Deduced(0), Loc(Loc), HasSFINAEDiagnostic(false) { }
+ : Deduced(0), Loc(Loc), HasSFINAEDiagnostic(false), Expression(0) { }
/// \brief Returns the location at which template argument is
/// occurring.
@@ -141,15 +141,25 @@ public:
/// TDK_SubstitutionFailure: this argument is the template
/// argument we were instantiating when we encountered an error.
///
- /// TDK_NonDeducedMismatch: this is the template argument
- /// provided in the source code.
+ /// TDK_NonDeducedMismatch: this is the component of the 'parameter'
+ /// of the deduction, directly provided in the source code.
TemplateArgument FirstArg;
/// \brief The second template argument to which the template
/// argument deduction failure refers.
///
+ /// TDK_NonDeducedMismatch: this is the mismatching component of the
+ /// 'argument' of the deduction, from which we are deducing arguments.
+ ///
/// FIXME: Finish documenting this.
TemplateArgument SecondArg;
+
+ /// \brief The expression which caused a deduction failure.
+ ///
+ /// TDK_FailedOverloadResolution: this argument is the reference to
+ // an overloaded function which could not be resolved to a specific
+ // function.
+ Expr *Expression;
};
}
diff --git a/include/clang/Sema/TypoCorrection.h b/include/clang/Sema/TypoCorrection.h
index 2b4a9e62167b..cdd71c8fa9aa 100644
--- a/include/clang/Sema/TypoCorrection.h
+++ b/include/clang/Sema/TypoCorrection.h
@@ -16,6 +16,7 @@
#define LLVM_CLANG_SEMA_TYPOCORRECTION_H
#include "clang/AST/DeclCXX.h"
+#include "clang/Sema/DeclSpec.h"
#include "llvm/ADT/SmallVector.h"
namespace clang {
@@ -181,12 +182,12 @@ public:
return CorrectionRange;
}
- typedef llvm::SmallVector<NamedDecl*, 1>::iterator decl_iterator;
+ typedef SmallVector<NamedDecl *, 1>::iterator decl_iterator;
decl_iterator begin() {
return isKeyword() ? CorrectionDecls.end() : CorrectionDecls.begin();
}
decl_iterator end() { return CorrectionDecls.end(); }
- typedef llvm::SmallVector<NamedDecl*, 1>::const_iterator const_decl_iterator;
+ typedef SmallVector<NamedDecl *, 1>::const_iterator const_decl_iterator;
const_decl_iterator begin() const {
return isKeyword() ? CorrectionDecls.end() : CorrectionDecls.begin();
}
@@ -200,7 +201,7 @@ private:
// Results.
DeclarationName CorrectionName;
NestedNameSpecifier *CorrectionNameSpec;
- llvm::SmallVector<NamedDecl*, 1> CorrectionDecls;
+ SmallVector<NamedDecl *, 1> CorrectionDecls;
unsigned CharDistance;
unsigned QualifierDistance;
unsigned CallbackDistance;
@@ -227,9 +228,11 @@ class CorrectionCandidateCallback {
/// candidate is viable, without ranking potentially viable candidates.
/// Only ValidateCandidate or RankCandidate need to be overriden by a
/// callback wishing to check the viability of correction candidates.
- virtual bool ValidateCandidate(const TypoCorrection &candidate) {
- return true;
- }
+ /// The default predicate always returns true if the candidate is not a type
+ /// name or keyword, true for types if WantTypeSpecifiers is true, and true
+ /// for keywords if WantTypeSpecifiers, WantExpressionKeywords,
+ /// WantCXXNamedCasts, WantRemainingKeywords, or WantObjCSuper is true.
+ virtual bool ValidateCandidate(const TypoCorrection &candidate);
/// \brief Method used by Sema::CorrectTypo to assign an "edit distance" rank
/// to a candidate (where a lower value represents a better candidate), or
diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h
index 8c58fb281662..9b685ba118f4 100644
--- a/include/clang/Serialization/ASTBitCodes.h
+++ b/include/clang/Serialization/ASTBitCodes.h
@@ -18,9 +18,9 @@
#define LLVM_CLANG_FRONTEND_PCHBITCODES_H
#include "clang/AST/Type.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/Bitcode/BitCodes.h"
#include "llvm/Support/DataTypes.h"
-#include "llvm/ADT/DenseMap.h"
namespace clang {
namespace serialization {
@@ -35,7 +35,7 @@ namespace clang {
/// Version 4 of AST files also requires that the version control branch and
/// revision match exactly, since there is no backward compatibility of
/// AST files at this time.
- const unsigned VERSION_MAJOR = 4;
+ const unsigned VERSION_MAJOR = 5;
/// \brief AST file minor version number supported by this version of
/// Clang.
@@ -129,7 +129,14 @@ namespace clang {
/// \brief An ID number that refers to a macro in an AST file.
typedef uint32_t MacroID;
-
+
+ /// \brief A global ID number that refers to a macro in an AST file.
+ typedef uint32_t GlobalMacroID;
+
+ /// \brief A local to a module ID number that refers to a macro in an
+ /// AST file.
+ typedef uint32_t LocalMacroID;
+
/// \brief The number of predefined macro IDs.
const unsigned int NUM_PREDEF_MACRO_IDS = 1;
@@ -259,21 +266,25 @@ namespace clang {
/// \brief The directory that the PCH was originally created in.
ORIGINAL_PCH_DIR = 6,
+ /// \brief Record code for file ID of the file or buffer that was used to
+ /// generate the AST file.
+ ORIGINAL_FILE_ID = 7,
+
/// \brief Offsets into the input-files block where input files
/// reside.
- INPUT_FILE_OFFSETS = 7,
+ INPUT_FILE_OFFSETS = 8,
/// \brief Record code for the diagnostic options table.
- DIAGNOSTIC_OPTIONS = 8,
+ DIAGNOSTIC_OPTIONS = 9,
/// \brief Record code for the filesystem options table.
- FILE_SYSTEM_OPTIONS = 9,
+ FILE_SYSTEM_OPTIONS = 10,
/// \brief Record code for the headers search options table.
- HEADER_SEARCH_OPTIONS = 10,
+ HEADER_SEARCH_OPTIONS = 11,
/// \brief Record code for the preprocessor options table.
- PREPROCESSOR_OPTIONS = 11
+ PREPROCESSOR_OPTIONS = 12
};
/// \brief Record types that occur within the input-files block
@@ -319,6 +330,11 @@ namespace clang {
/// NULL-terminated string that corresponds to that identifier.
IDENTIFIER_OFFSET = 3,
+ /// \brief This is so that older clang versions, before the introduction
+ /// of the control block, can read and reject the newer PCH format.
+ /// *DON"T CHANGE THIS NUMBER*.
+ METADATA_OLD_FORMAT = 4,
+
/// \brief Record code for the identifier table.
///
/// The identifier table is a simple blob that contains
@@ -331,7 +347,7 @@ namespace clang {
/// between offsets (for unresolved identifier IDs) and
/// IdentifierInfo pointers (for already-resolved identifier
/// IDs).
- IDENTIFIER_TABLE = 4,
+ IDENTIFIER_TABLE = 5,
/// \brief Record code for the array of external definitions.
///
@@ -341,7 +357,7 @@ namespace clang {
/// reported to the AST consumer after the AST file has been
/// read, since their presence can affect the semantics of the
/// program (e.g., for code generation).
- EXTERNAL_DEFINITIONS = 5,
+ EXTERNAL_DEFINITIONS = 6,
/// \brief Record code for the set of non-builtin, special
/// types.
@@ -350,33 +366,33 @@ namespace clang {
/// that are constructed during semantic analysis (e.g.,
/// __builtin_va_list). The SPECIAL_TYPE_* constants provide
/// offsets into this record.
- SPECIAL_TYPES = 6,
+ SPECIAL_TYPES = 7,
/// \brief Record code for the extra statistics we gather while
/// generating an AST file.
- STATISTICS = 7,
+ STATISTICS = 8,
/// \brief Record code for the array of tentative definitions.
- TENTATIVE_DEFINITIONS = 8,
+ TENTATIVE_DEFINITIONS = 9,
- /// \brief Record code for the array of locally-scoped external
+ /// \brief Record code for the array of locally-scoped extern "C"
/// declarations.
- LOCALLY_SCOPED_EXTERNAL_DECLS = 9,
+ LOCALLY_SCOPED_EXTERN_C_DECLS = 10,
/// \brief Record code for the table of offsets into the
/// Objective-C method pool.
- SELECTOR_OFFSETS = 10,
+ SELECTOR_OFFSETS = 11,
/// \brief Record code for the Objective-C method pool,
- METHOD_POOL = 11,
+ METHOD_POOL = 12,
/// \brief The value of the next __COUNTER__ to dispense.
/// [PP_COUNTER_VALUE, Val]
- PP_COUNTER_VALUE = 12,
+ PP_COUNTER_VALUE = 13,
/// \brief Record code for the table of offsets into the block
/// of source-location information.
- SOURCE_LOCATION_OFFSETS = 13,
+ SOURCE_LOCATION_OFFSETS = 14,
/// \brief Record code for the set of source location entries
/// that need to be preloaded by the AST reader.
@@ -384,7 +400,7 @@ namespace clang {
/// This set contains the source location entry for the
/// predefines buffer and for any file entries that need to be
/// preloaded.
- SOURCE_LOCATION_PRELOADS = 14,
+ SOURCE_LOCATION_PRELOADS = 15,
/// \brief Record code for the set of ext_vector type names.
EXT_VECTOR_DECLS = 16,
@@ -513,9 +529,13 @@ namespace clang {
/// macro definition.
MACRO_OFFSET = 47,
- /// \brief Record of updates for a macro that was modified after
- /// being deserialized.
- MACRO_UPDATES = 48
+ /// \brief Mapping table from the identifier ID to the offset of the
+ /// macro directive history for the identifier.
+ MACRO_TABLE = 48,
+
+ /// \brief Record code for undefined but used functions and variables that
+ /// need a definition in this TU.
+ UNDEFINED_BUT_USED = 49
};
/// \brief Record types used within a source manager block.
@@ -552,7 +572,10 @@ namespace clang {
/// \brief Describes one token.
/// [PP_TOKEN, SLoc, Length, IdentInfoID, Kind, Flags]
- PP_TOKEN = 3
+ PP_TOKEN = 3,
+
+ /// \brief The macro directives history for a particular identifier.
+ PP_MACRO_DIRECTIVE_HISTORY = 4
};
/// \brief Record types used within a preprocessor detail block.
@@ -594,7 +617,13 @@ namespace clang {
SUBMODULE_REQUIRES = 8,
/// \brief Specifies a header that has been explicitly excluded
/// from this submodule.
- SUBMODULE_EXCLUDED_HEADER = 9
+ SUBMODULE_EXCLUDED_HEADER = 9,
+ /// \brief Specifies a library or framework to link against.
+ SUBMODULE_LINK_LIBRARY = 10,
+ /// \brief Specifies a configuration macro for this module.
+ SUBMODULE_CONFIG_MACRO = 11,
+ /// \brief Specifies a conflict with another module.
+ SUBMODULE_CONFLICT = 12
};
/// \brief Record types used within a comments block.
@@ -692,7 +721,23 @@ namespace clang {
/// \brief The __va_list_tag placeholder type.
PREDEF_TYPE_VA_LIST_TAG = 36,
/// \brief The placeholder type for builtin functions.
- PREDEF_TYPE_BUILTIN_FN = 37
+ PREDEF_TYPE_BUILTIN_FN = 37,
+ /// \brief OpenCL 1d image type.
+ PREDEF_TYPE_IMAGE1D_ID = 38,
+ /// \brief OpenCL 1d image array type.
+ PREDEF_TYPE_IMAGE1D_ARR_ID = 39,
+ /// \brief OpenCL 1d image buffer type.
+ PREDEF_TYPE_IMAGE1D_BUFF_ID = 40,
+ /// \brief OpenCL 2d image type.
+ PREDEF_TYPE_IMAGE2D_ID = 41,
+ /// \brief OpenCL 2d image array type.
+ PREDEF_TYPE_IMAGE2D_ARR_ID = 42,
+ /// \brief OpenCL 3d image type.
+ PREDEF_TYPE_IMAGE3D_ID = 43,
+ /// \brief OpenCL event type.
+ PREDEF_TYPE_EVENT_ID = 44,
+ /// \brief OpenCL sampler type.
+ PREDEF_TYPE_SAMPLER_ID = 45
};
/// \brief The number of predefined type IDs that are reserved for
@@ -1000,7 +1045,11 @@ namespace clang {
/// function specialization. (Microsoft extension).
DECL_CLASS_SCOPE_FUNCTION_SPECIALIZATION,
/// \brief An ImportDecl recording a module import.
- DECL_IMPORT
+ DECL_IMPORT,
+ /// \brief A OMPThreadPrivateDecl record.
+ DECL_OMP_THREADPRIVATE,
+ /// \brief An EmptyDecl record.
+ DECL_EMPTY
};
/// \brief Record codes for each kind of statement or expression.
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h
index e23ea5cca7e5..925533678c15 100644
--- a/include/clang/Serialization/ASTReader.h
+++ b/include/clang/Serialization/ASTReader.h
@@ -14,33 +14,33 @@
#ifndef LLVM_CLANG_FRONTEND_AST_READER_H
#define LLVM_CLANG_FRONTEND_AST_READER_H
-#include "clang/Serialization/ASTBitCodes.h"
-#include "clang/Serialization/ContinuousRangeMap.h"
-#include "clang/Serialization/Module.h"
-#include "clang/Serialization/ModuleManager.h"
-#include "clang/Sema/ExternalSemaSource.h"
-#include "clang/AST/DeclarationName.h"
#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclarationName.h"
#include "clang/AST/TemplateBase.h"
-#include "clang/Lex/ExternalPreprocessorSource.h"
-#include "clang/Lex/HeaderSearch.h"
-#include "clang/Lex/PPMutationListener.h"
-#include "clang/Lex/PreprocessingRecord.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/FileSystemOptions.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/Version.h"
+#include "clang/Lex/ExternalPreprocessorSource.h"
+#include "clang/Lex/HeaderSearch.h"
+#include "clang/Lex/PreprocessingRecord.h"
+#include "clang/Sema/ExternalSemaSource.h"
+#include "clang/Serialization/ASTBitCodes.h"
+#include "clang/Serialization/ContinuousRangeMap.h"
+#include "clang/Serialization/Module.h"
+#include "clang/Serialization/ModuleManager.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/DenseSet.h"
#include "llvm/Bitcode/BitstreamReader.h"
#include "llvm/Support/DataTypes.h"
#include <deque>
@@ -48,6 +48,7 @@
#include <string>
#include <utility>
#include <vector>
+#include <sys/stat.h>
namespace llvm {
class MemoryBuffer;
@@ -68,8 +69,10 @@ class NestedNameSpecifier;
class CXXBaseSpecifier;
class CXXConstructorDecl;
class CXXCtorInitializer;
+class GlobalModuleIndex;
class GotoStmt;
class MacroDefinition;
+class MacroDirective;
class NamedDecl;
class OpaqueValueExpr;
class Preprocessor;
@@ -85,6 +88,7 @@ class TypeLocReader;
struct HeaderFileInfo;
class VersionTuple;
class TargetOptions;
+class ASTUnresolvedSet;
/// \brief Abstract interface for callback invocations by the ASTReader.
///
@@ -96,6 +100,14 @@ class ASTReaderListener {
public:
virtual ~ASTReaderListener();
+ /// \brief Receives the full Clang version information.
+ ///
+ /// \returns true to indicate that the version is invalid. Subclasses should
+ /// generally defer to this implementation.
+ virtual bool ReadFullVersionInformation(StringRef FullVersion) {
+ return FullVersion != getClangFullRepositoryVersion();
+ }
+
/// \brief Receives the language options.
///
/// \returns true to indicate the options are invalid or false otherwise.
@@ -233,6 +245,8 @@ public:
Success,
/// \brief The AST file itself appears corrupted.
Failure,
+ /// \brief The AST file was missing.
+ Missing,
/// \brief The AST file is out-of-date relative to its input files,
/// and needs to be regenerated.
OutOfDate,
@@ -291,6 +305,9 @@ private:
/// \brief The module manager which manages modules and their dependencies
ModuleManager ModuleMgr;
+ /// \brief The global module index, if loaded.
+ llvm::OwningPtr<GlobalModuleIndex> GlobalIndex;
+
/// \brief A map of global bit offsets to the module that stores entities
/// at those bit offsets.
ContinuousRangeMap<uint64_t, ModuleFile*, 4> GlobalBitOffsetsMap;
@@ -387,7 +404,7 @@ private:
typedef llvm::MapVector<Decl *, uint64_t,
llvm::SmallDenseMap<Decl *, unsigned, 4>,
- llvm::SmallVector<std::pair<Decl *, uint64_t>, 4> >
+ SmallVector<std::pair<Decl *, uint64_t>, 4> >
PendingBodiesMap;
/// \brief Functions or methods that have bodies that will be attached.
@@ -431,15 +448,6 @@ private:
/// global macro ID to produce a local ID.
GlobalMacroMapType GlobalMacroMap;
- typedef llvm::DenseMap<serialization::MacroID,
- llvm::SmallVector<std::pair<serialization::SubmoduleID,
- MacroUpdate>, 1> >
- MacroUpdatesMap;
-
- /// \brief Mapping from (global) macro IDs to the set of updates to be
- /// performed to the corresponding macro.
- MacroUpdatesMap MacroUpdates;
-
/// \brief A vector containing submodules that have already been loaded.
///
/// This vector is indexed by the Submodule ID (-1). NULL submodule entries
@@ -459,28 +467,22 @@ private:
public:
enum NameKind {
Declaration,
- MacroVisibility,
- MacroUndef
+ MacroVisibility
} Kind;
private:
- unsigned Loc;
-
union {
Decl *D;
- MacroInfo *MI;
+ MacroDirective *MD;
};
IdentifierInfo *Id;
public:
- HiddenName(Decl *D) : Kind(Declaration), Loc(), D(D), Id() { }
+ HiddenName(Decl *D) : Kind(Declaration), D(D), Id() { }
- HiddenName(IdentifierInfo *II, MacroInfo *MI)
- : Kind(MacroVisibility), Loc(), MI(MI), Id(II) { }
-
- HiddenName(IdentifierInfo *II, MacroInfo *MI, SourceLocation Loc)
- : Kind(MacroUndef), Loc(Loc.getRawEncoding()), MI(MI), Id(II) { }
+ HiddenName(IdentifierInfo *II, MacroDirective *MD)
+ : Kind(MacroVisibility), MD(MD), Id(II) { }
NameKind getKind() const { return Kind; }
@@ -489,21 +491,14 @@ private:
return D;
}
- std::pair<IdentifierInfo *, MacroInfo *> getMacro() const {
- assert((getKind() == MacroUndef || getKind() == MacroVisibility)
- && "Hidden name is not a macro!");
- return std::make_pair(Id, MI);
- }
-
- SourceLocation getMacroUndefLoc() const {
- assert(getKind() == MacroUndef && "Hidden name is not an undef!");
- return SourceLocation::getFromRawEncoding(Loc);
+ std::pair<IdentifierInfo *, MacroDirective *> getMacro() const {
+ assert(getKind() == MacroVisibility && "Hidden name is not a macro!");
+ return std::make_pair(Id, MD);
}
};
/// \brief A set of hidden declarations.
- typedef llvm::SmallVector<HiddenName, 2>
- HiddenNames;
+ typedef SmallVector<HiddenName, 2> HiddenNames;
typedef llvm::DenseMap<Module *, HiddenNames> HiddenNamesMapType;
@@ -512,28 +507,30 @@ private:
HiddenNamesMapType HiddenNamesMap;
- /// \brief A module import or export that hasn't yet been resolved.
- struct UnresolvedModuleImportExport {
+ /// \brief A module import, export, or conflict that hasn't yet been resolved.
+ struct UnresolvedModuleRef {
/// \brief The file in which this module resides.
ModuleFile *File;
/// \brief The module that is importing or exporting.
Module *Mod;
-
+
+ /// \brief The kind of module reference.
+ enum { Import, Export, Conflict } Kind;
+
/// \brief The local ID of the module that is being exported.
unsigned ID;
-
- /// \brief Whether this is an import (vs. an export).
- unsigned IsImport : 1;
-
+
/// \brief Whether this is a wildcard export.
unsigned IsWildcard : 1;
+
+ /// \brief String data.
+ StringRef String;
};
/// \brief The set of module imports and exports that still need to be
/// resolved.
- llvm::SmallVector<UnresolvedModuleImportExport, 2>
- UnresolvedModuleImportExports;
+ SmallVector<UnresolvedModuleRef, 2> UnresolvedModuleRefs;
/// \brief A vector containing selectors that have already been loaded.
///
@@ -546,7 +543,7 @@ private:
GlobalSelectorMapType;
/// \brief Mapping from global selector IDs to the module in which the
- /// selector resides along with the offset that should be added to the
+
/// global selector ID to produce a local ID.
GlobalSelectorMapType GlobalSelectorMap;
@@ -554,8 +551,35 @@ private:
/// global method pool for this selector.
llvm::DenseMap<Selector, unsigned> SelectorGeneration;
- typedef llvm::MapVector<IdentifierInfo *,
- llvm::SmallVector<serialization::MacroID, 2> >
+ struct PendingMacroInfo {
+ ModuleFile *M;
+
+ struct ModuleMacroDataTy {
+ serialization::GlobalMacroID GMacID;
+ unsigned ImportLoc;
+ };
+ struct PCHMacroDataTy {
+ uint64_t MacroDirectivesOffset;
+ };
+
+ union {
+ ModuleMacroDataTy ModuleMacroData;
+ PCHMacroDataTy PCHMacroData;
+ };
+
+ PendingMacroInfo(ModuleFile *M,
+ serialization::GlobalMacroID GMacID,
+ SourceLocation ImportLoc) : M(M) {
+ ModuleMacroData.GMacID = GMacID;
+ ModuleMacroData.ImportLoc = ImportLoc.getRawEncoding();
+ }
+
+ PendingMacroInfo(ModuleFile *M, uint64_t MacroDirectivesOffset) : M(M) {
+ PCHMacroData.MacroDirectivesOffset = MacroDirectivesOffset;
+ }
+ };
+
+ typedef llvm::MapVector<IdentifierInfo *, SmallVector<PendingMacroInfo, 2> >
PendingMacroIDsMap;
/// \brief Mapping from identifiers that have a macro history to the global
@@ -637,11 +661,11 @@ private:
/// \brief Fields containing data that is used for semantic analysis
//@{
- /// \brief The IDs of all locally scoped external decls in the chain.
+ /// \brief The IDs of all locally scoped extern "C" decls in the chain.
///
/// Sema tracks these to validate that the types are consistent across all
- /// local external declarations.
- SmallVector<uint64_t, 16> LocallyScopedExternalDecls;
+ /// local extern "C" declarations.
+ SmallVector<uint64_t, 16> LocallyScopedExternCDecls;
/// \brief The IDs of all dynamic class declarations in the chain.
///
@@ -674,6 +698,10 @@ private:
/// \brief A list of the namespaces we've seen.
SmallVector<uint64_t, 4> KnownNamespaces;
+ /// \brief A list of undefined decls with internal linkage followed by the
+ /// SourceLocation of a matching ODR-use.
+ SmallVector<uint64_t, 8> UndefinedButUsed;
+
/// \brief A list of modules that were imported by precompiled headers or
/// any other non-module AST file.
SmallVector<serialization::SubmoduleID, 2> ImportedModules;
@@ -693,6 +721,12 @@ private:
/// \brief Whether to accept an AST file with compiler errors.
bool AllowASTWithCompilerErrors;
+ /// \brief Whether we are allowed to use the global module index.
+ bool UseGlobalIndex;
+
+ /// \brief Whether we have tried loading the global module index yet.
+ bool TriedLoadingGlobalIndex;
+
/// \brief The current "generation" of the module file import stack, which
/// indicates how many separate module file load operations have occurred.
unsigned CurrentGeneration;
@@ -727,6 +761,12 @@ private:
/// \brief The total number of macros stored in the chain.
unsigned TotalNumMacros;
+ /// \brief The number of lookups into identifier tables.
+ unsigned NumIdentifierLookups;
+
+ /// \brief The number of lookups into identifier tables that succeed.
+ unsigned NumIdentifierLookupHits;
+
/// \brief The number of selectors that have been read.
unsigned NumSelectorsRead;
@@ -734,8 +774,20 @@ private:
unsigned NumMethodPoolEntriesRead;
/// \brief The number of times we have looked up a selector in the method
- /// pool and not found anything interesting.
- unsigned NumMethodPoolMisses;
+ /// pool.
+ unsigned NumMethodPoolLookups;
+
+ /// \brief The number of times we have looked up a selector in the method
+ /// pool and found something.
+ unsigned NumMethodPoolHits;
+
+ /// \brief The number of times we have looked up a selector in the method
+ /// pool within a specific module.
+ unsigned NumMethodPoolTableLookups;
+
+ /// \brief The number of times we have looked up a selector in the method
+ /// pool within a specific module and found something.
+ unsigned NumMethodPoolTableHits;
/// \brief The total number of method pool entries in the selector table.
unsigned TotalNumMethodPoolEntries;
@@ -761,19 +813,13 @@ private:
/// Number of CXX base specifiers currently loaded
unsigned NumCXXBaseSpecifiersLoaded;
- /// \brief An IdentifierInfo that has been loaded but whose top-level
- /// declarations of the same name have not (yet) been loaded.
- struct PendingIdentifierInfo {
- IdentifierInfo *II;
- SmallVector<uint32_t, 4> DeclIDs;
- };
-
/// \brief The set of identifiers that were read while the AST reader was
/// (recursively) loading declarations.
///
/// The declarations on the identifier chain for these identifiers will be
/// loaded once the recursive loading has completed.
- std::deque<PendingIdentifierInfo> PendingIdentifierInfos;
+ llvm::MapVector<IdentifierInfo *, SmallVector<uint32_t, 4> >
+ PendingIdentifierInfos;
/// \brief The generation number of each identifier, which keeps track of
/// the last time we loaded information about this identifier.
@@ -797,11 +843,26 @@ private:
/// Each element is the global declaration ID of the first declaration in
/// the chain. Elements in this vector should be unique; use
/// PendingDeclChainsKnown to ensure uniqueness.
- llvm::SmallVector<serialization::DeclID, 16> PendingDeclChains;
+ SmallVector<serialization::DeclID, 16> PendingDeclChains;
/// \brief Keeps track of the elements added to PendingDeclChains.
llvm::SmallSet<serialization::DeclID, 16> PendingDeclChainsKnown;
+ /// \brief The Decl IDs for the Sema/Lexical DeclContext of a Decl that has
+ /// been loaded but its DeclContext was not set yet.
+ struct PendingDeclContextInfo {
+ Decl *D;
+ serialization::GlobalDeclID SemaDC;
+ serialization::GlobalDeclID LexicalDC;
+ };
+
+ /// \brief The set of Decls that have been loaded but their DeclContexts are
+ /// not set yet.
+ ///
+ /// The DeclContexts for these Decls will be set once recursive loading has
+ /// been completed.
+ std::deque<PendingDeclContextInfo> PendingDeclContextInfos;
+
/// \brief The set of Objective-C categories that have been deserialized
/// since the last time the declaration chains were linked.
llvm::SmallPtrSet<ObjCCategoryDecl *, 16> CategoriesDeserialized;
@@ -809,9 +870,9 @@ private:
/// \brief The set of Objective-C class definitions that have already been
/// loaded, for which we will need to check for categories whenever a new
/// module is loaded.
- llvm::SmallVector<ObjCInterfaceDecl *, 16> ObjCClassesLoaded;
+ SmallVector<ObjCInterfaceDecl *, 16> ObjCClassesLoaded;
- typedef llvm::DenseMap<Decl *, llvm::SmallVector<serialization::DeclID, 2> >
+ typedef llvm::DenseMap<Decl *, SmallVector<serialization::DeclID, 2> >
MergedDeclsMap;
/// \brief A mapping from canonical declarations to the set of additional
@@ -820,7 +881,7 @@ private:
MergedDeclsMap MergedDecls;
typedef llvm::DenseMap<serialization::GlobalDeclID,
- llvm::SmallVector<serialization::DeclID, 2> >
+ SmallVector<serialization::DeclID, 2> >
StoredMergedDeclsMap;
/// \brief A mapping from canonical declaration IDs to the set of additional
@@ -883,11 +944,10 @@ private:
/// \brief Reads a statement from the specified cursor.
Stmt *ReadStmtFromStream(ModuleFile &F);
- typedef llvm::PointerIntPair<const FileEntry *, 1, bool> InputFile;
-
/// \brief Retrieve the file entry and 'overridden' bit for an input
/// file in the given module file.
- InputFile getInputFile(ModuleFile &F, unsigned ID, bool Complain = true);
+ serialization::InputFile getInputFile(ModuleFile &F, unsigned ID,
+ bool Complain = true);
/// \brief Get a FileEntry out of stored-in-PCH filename, making sure we take
/// into account all the necessary relocations.
@@ -895,12 +955,24 @@ private:
void MaybeAddSystemRootToFilename(ModuleFile &M, std::string &Filename);
+ struct ImportedModule {
+ ModuleFile *Mod;
+ ModuleFile *ImportedBy;
+ SourceLocation ImportLoc;
+
+ ImportedModule(ModuleFile *Mod,
+ ModuleFile *ImportedBy,
+ SourceLocation ImportLoc)
+ : Mod(Mod), ImportedBy(ImportedBy), ImportLoc(ImportLoc) { }
+ };
+
ASTReadResult ReadASTCore(StringRef FileName, ModuleKind Type,
- ModuleFile *ImportedBy,
- llvm::SmallVectorImpl<ModuleFile *> &Loaded,
+ SourceLocation ImportLoc, ModuleFile *ImportedBy,
+ SmallVectorImpl<ImportedModule> &Loaded,
+ off_t ExpectedSize, time_t ExpectedModTime,
unsigned ClientLoadCapabilities);
ASTReadResult ReadControlBlock(ModuleFile &F,
- llvm::SmallVectorImpl<ModuleFile *> &Loaded,
+ SmallVectorImpl<ImportedModule> &Loaded,
unsigned ClientLoadCapabilities);
bool ReadASTBlock(ModuleFile &F);
bool ParseLineTable(ModuleFile &F, SmallVectorImpl<uint64_t> &Record);
@@ -1034,6 +1106,14 @@ private:
void finishPendingActions();
+ void addPendingDeclContextInfo(Decl *D,
+ serialization::GlobalDeclID SemaDC,
+ serialization::GlobalDeclID LexicalDC) {
+ assert(D);
+ PendingDeclContextInfo Info = { D, SemaDC, LexicalDC };
+ PendingDeclContextInfos.push_back(Info);
+ }
+
/// \brief Produce an error diagnostic and return true.
///
/// This routine should only be used for fatal errors that have to
@@ -1065,13 +1145,18 @@ public:
/// \param AllowASTWithCompilerErrors If true, the AST reader will accept an
/// AST file the was created out of an AST with compiler errors,
/// otherwise it will reject it.
+ ///
+ /// \param UseGlobalIndex If true, the AST reader will try to load and use
+ /// the global module index.
ASTReader(Preprocessor &PP, ASTContext &Context, StringRef isysroot = "",
bool DisableValidation = false,
- bool AllowASTWithCompilerErrors = false);
+ bool AllowASTWithCompilerErrors = false,
+ bool UseGlobalIndex = true);
~ASTReader();
SourceManager &getSourceManager() const { return SourceMgr; }
+ FileManager &getFileManager() const { return FileMgr; }
/// \brief Flags that indicate what kind of AST loading failures the client
/// of the AST reader can directly handle.
@@ -1082,15 +1167,18 @@ public:
/// \brief The client can't handle any AST loading failures.
ARR_None = 0,
/// \brief The client can handle an AST file that cannot load because it
+ /// is missing.
+ ARR_Missing = 0x1,
+ /// \brief The client can handle an AST file that cannot load because it
/// is out-of-date relative to its input files.
- ARR_OutOfDate = 0x1,
+ ARR_OutOfDate = 0x2,
/// \brief The client can handle an AST file that cannot load because it
/// was built with a different version of Clang.
- ARR_VersionMismatch = 0x2,
+ ARR_VersionMismatch = 0x4,
/// \brief The client can handle an AST file that cannot load because it's
/// compiled configuration doesn't match that of the context it was
/// loaded into.
- ARR_ConfigurationMismatch = 0x4
+ ARR_ConfigurationMismatch = 0x8
};
/// \brief Load the AST file designated by the given file name.
@@ -1100,10 +1188,14 @@ public:
/// \param Type The kind of AST being loaded, e.g., PCH, module, main file,
/// or preamble.
///
+ /// \param ImportLoc the location where the module file will be considered as
+ /// imported from. For non-module AST types it should be invalid.
+ ///
/// \param ClientLoadCapabilities The set of client load-failure
/// capabilities, represented as a bitset of the enumerators of
/// LoadFailureCapabilities.
ASTReadResult ReadAST(const std::string &FileName, ModuleKind Type,
+ SourceLocation ImportLoc,
unsigned ClientLoadCapabilities);
/// \brief Make the entities in the given module and any of its (non-explicit)
@@ -1113,11 +1205,17 @@ public:
///
/// \param NameVisibility The level of visibility to give the names in the
/// module. Visibility can only be increased over time.
+ ///
+ /// \param ImportLoc The location at which the import occurs.
+ ///
+ /// \param Complain Whether to complain about conflicting module imports.
void makeModuleVisible(Module *Mod,
- Module::NameVisibilityKind NameVisibility);
+ Module::NameVisibilityKind NameVisibility,
+ SourceLocation ImportLoc,
+ bool Complain);
/// \brief Make the names within this set of hidden names visible.
- void makeNamesVisible(const HiddenNames &Names);
+ void makeNamesVisible(const HiddenNames &Names, Module *Owner);
/// \brief Set the AST callbacks listener.
void setListener(ASTReaderListener *listener) {
@@ -1127,6 +1225,18 @@ public:
/// \brief Set the AST deserialization listener.
void setDeserializationListener(ASTDeserializationListener *Listener);
+ /// \brief Determine whether this AST reader has a global index.
+ bool hasGlobalIndex() const { return GlobalIndex; }
+
+ /// \brief Attempts to load the global index.
+ ///
+ /// \returns true if loading the global index has failed for any reason.
+ bool loadGlobalIndex();
+
+ /// \brief Determine whether we tried to load the global index, but failed,
+ /// e.g., because it is out-of-date or does not exist.
+ bool isGlobalIndexUnavailable() const;
+
/// \brief Initializes the ASTContext
void InitializeContext();
@@ -1193,8 +1303,8 @@ public:
/// \brief Optionally returns true or false if the preallocated preprocessed
/// entity with index \p Index came from file \p FID.
- virtual llvm::Optional<bool> isPreprocessedEntityInFileID(unsigned Index,
- FileID FID);
+ virtual Optional<bool> isPreprocessedEntityInFileID(unsigned Index,
+ FileID FID);
/// \brief Read the header file information for the given file entry.
virtual HeaderFileInfo GetHeaderFileInfo(const FileEntry *FE);
@@ -1297,7 +1407,7 @@ public:
/// \brief Retrieve the module file that owns the given declaration, or NULL
/// if the declaration is not from a module file.
- ModuleFile *getOwningModuleFile(Decl *D);
+ ModuleFile *getOwningModuleFile(const Decl *D);
/// \brief Returns the source location for the decl \p ID.
SourceLocation getSourceLocationForDeclID(serialization::GlobalDeclID ID);
@@ -1374,7 +1484,7 @@ public:
/// \brief Finds all the visible declarations with a given name.
/// The current implementation of this method just loads the entire
/// lookup table as unmaterialized references.
- virtual DeclContext::lookup_result
+ virtual bool
FindExternalVisibleDeclsByName(const DeclContext *DC,
DeclarationName Name);
@@ -1459,6 +1569,9 @@ public:
virtual void ReadKnownNamespaces(
SmallVectorImpl<NamespaceDecl *> &Namespaces);
+ virtual void ReadUndefinedButUsed(
+ llvm::DenseMap<NamedDecl *, SourceLocation> &Undefined);
+
virtual void ReadTentativeDefinitions(
SmallVectorImpl<VarDecl *> &TentativeDefs);
@@ -1472,7 +1585,7 @@ public:
virtual void ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl *> &Decls);
- virtual void ReadLocallyScopedExternalDecls(
+ virtual void ReadLocallyScopedExternCDecls(
SmallVectorImpl<NamedDecl *> &Decls);
virtual void ReadReferencedSelectors(
@@ -1493,7 +1606,7 @@ public:
void SetIdentifierInfo(unsigned ID, IdentifierInfo *II);
void SetGloballyVisibleDecls(IdentifierInfo *II,
const SmallVectorImpl<uint32_t> &DeclIDs,
- bool Nonrecursive = false);
+ SmallVectorImpl<Decl *> *Decls = 0);
/// \brief Report a diagnostic.
DiagnosticBuilder Diag(unsigned DiagID);
@@ -1520,8 +1633,16 @@ public:
serialization::IdentifierID getGlobalIdentifierID(ModuleFile &M,
unsigned LocalID);
+ void resolvePendingMacro(IdentifierInfo *II, const PendingMacroInfo &PMInfo);
+
+ void installPCHMacroDirectives(IdentifierInfo *II,
+ ModuleFile &M, uint64_t Offset);
+
+ void installImportedMacro(IdentifierInfo *II, MacroDirective *MD,
+ Module *Owner);
+
/// \brief Retrieve the macro with the given ID.
- MacroInfo *getMacro(serialization::MacroID ID, MacroInfo *Hint = 0);
+ MacroInfo *getMacro(serialization::MacroID ID);
/// \brief Retrieve the global macro ID corresponding to the given local
/// ID within the given module file.
@@ -1530,6 +1651,10 @@ public:
/// \brief Read the source location entry with index ID.
virtual bool ReadSLocEntry(int ID);
+ /// \brief Retrieve the module import location and module name for the
+ /// given source manager entry ID.
+ virtual std::pair<SourceLocation, StringRef> getModuleImportLoc(int ID);
+
/// \brief Retrieve the global submodule ID given a module and its local ID
/// number.
serialization::SubmoduleID
@@ -1538,7 +1663,12 @@ public:
/// \brief Retrieve the submodule that corresponds to a global submodule ID.
///
Module *getSubmodule(serialization::SubmoduleID GlobalID);
-
+
+ /// \brief Retrieve the module that corresponds to the given module ID.
+ ///
+ /// Note: overrides method in ExternalASTSource
+ virtual Module *getModule(unsigned ID);
+
/// \brief Retrieve a selector from the given module with its local ID
/// number.
Selector getLocalSelector(ModuleFile &M, unsigned LocalID);
@@ -1597,7 +1727,7 @@ public:
unsigned &Idx);
/// \brief Read a UnresolvedSet structure.
- void ReadUnresolvedSet(ModuleFile &F, UnresolvedSetImpl &Set,
+ void ReadUnresolvedSet(ModuleFile &F, ASTUnresolvedSet &Set,
const RecordData &Record, unsigned &Idx);
/// \brief Read a C++ base specifier.
@@ -1620,13 +1750,13 @@ public:
/// \brief Read a source location.
SourceLocation ReadSourceLocation(ModuleFile &ModuleFile,
- const RecordData &Record, unsigned& Idx) {
+ const RecordData &Record, unsigned &Idx) {
return ReadSourceLocation(ModuleFile, Record[Idx++]);
}
/// \brief Read a source range.
SourceRange ReadSourceRange(ModuleFile &F,
- const RecordData &Record, unsigned& Idx);
+ const RecordData &Record, unsigned &Idx);
/// \brief Read an integral value
llvm::APInt ReadAPInt(const RecordData &Record, unsigned &Idx);
@@ -1635,7 +1765,8 @@ public:
llvm::APSInt ReadAPSInt(const RecordData &Record, unsigned &Idx);
/// \brief Read a floating-point value
- llvm::APFloat ReadAPFloat(const RecordData &Record, unsigned &Idx);
+ llvm::APFloat ReadAPFloat(const RecordData &Record,
+ const llvm::fltSemantics &Sem, unsigned &Idx);
// \brief Read a string
static std::string ReadString(const RecordData &Record, unsigned &Idx);
@@ -1670,20 +1801,32 @@ public:
Expr *ReadSubExpr();
/// \brief Reads the macro record located at the given offset.
- void ReadMacroRecord(ModuleFile &F, uint64_t Offset, MacroInfo *Hint = 0);
+ MacroInfo *ReadMacroRecord(ModuleFile &F, uint64_t Offset);
/// \brief Determine the global preprocessed entity ID that corresponds to
/// the given local ID within the given module.
serialization::PreprocessedEntityID
getGlobalPreprocessedEntityID(ModuleFile &M, unsigned LocalID) const;
- /// \brief Note that the identifier has a macro history.
+ /// \brief Add a macro to resolve imported from a module.
///
/// \param II The name of the macro.
+ /// \param M The module file.
+ /// \param GMacID The global macro ID that is associated with this identifier.
+ /// \param ImportLoc The location where the module is imported.
+ void addPendingMacroFromModule(IdentifierInfo *II,
+ ModuleFile *M,
+ serialization::GlobalMacroID GMacID,
+ SourceLocation ImportLoc);
+
+ /// \brief Add a macro to deserialize its macro directive history from a PCH.
///
- /// \param IDs The global macro IDs that are associated with this identifier.
- void setIdentifierIsMacro(IdentifierInfo *II,
- ArrayRef<serialization::MacroID> IDs);
+ /// \param II The name of the macro.
+ /// \param M The module file.
+ /// \param MacroDirectivesOffset Offset of the serialized macro directive
+ /// history.
+ void addPendingMacroFromPCH(IdentifierInfo *II,
+ ModuleFile *M, uint64_t MacroDirectivesOffset);
/// \brief Read the set of macros defined by this external macro source.
virtual void ReadDefinedMacros();
@@ -1734,7 +1877,7 @@ public:
/// then restores it when destroyed.
struct SavedStreamPosition {
explicit SavedStreamPosition(llvm::BitstreamCursor &Cursor)
- : Cursor(Cursor), Offset(Cursor.GetCurrentBitNo()) { }
+ : Cursor(Cursor), Offset(Cursor.GetCurrentBitNo()) { }
~SavedStreamPosition() {
Cursor.JumpToBit(Offset);
diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h
index ac81e2164c57..2938dc76de49 100644
--- a/include/clang/Serialization/ASTWriter.h
+++ b/include/clang/Serialization/ASTWriter.h
@@ -14,20 +14,19 @@
#ifndef LLVM_CLANG_FRONTEND_AST_WRITER_H
#define LLVM_CLANG_FRONTEND_AST_WRITER_H
+#include "clang/AST/ASTMutationListener.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/TemplateBase.h"
-#include "clang/AST/ASTMutationListener.h"
-#include "clang/Lex/PPMutationListener.h"
+#include "clang/Sema/SemaConsumer.h"
#include "clang/Serialization/ASTBitCodes.h"
#include "clang/Serialization/ASTDeserializationListener.h"
-#include "clang/Sema/SemaConsumer.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/Bitcode/BitstreamWriter.h"
#include <map>
#include <queue>
@@ -48,12 +47,14 @@ class CXXCtorInitializer;
class FileEntry;
class FPOptions;
class HeaderSearch;
+class HeaderSearchOptions;
class IdentifierResolver;
class MacroDefinition;
+class MacroDirective;
+class MacroInfo;
class OpaqueValueExpr;
class OpenCLOptions;
class ASTReader;
-class MacroInfo;
class Module;
class PreprocessedEntity;
class PreprocessingRecord;
@@ -63,6 +64,7 @@ class SourceManager;
class SwitchCase;
class TargetInfo;
class VersionTuple;
+class ASTUnresolvedSet;
namespace SrcMgr { class SLocEntry; }
@@ -73,7 +75,6 @@ namespace SrcMgr { class SLocEntry; }
/// data structures. This bitstream can be de-serialized via an
/// instance of the ASTReader class.
class ASTWriter : public ASTDeserializationListener,
- public PPMutationListener,
public ASTMutationListener {
public:
typedef SmallVector<uint64_t, 64> RecordData;
@@ -231,6 +232,16 @@ private:
/// \brief Map that provides the ID numbers of each macro.
llvm::DenseMap<MacroInfo *, serialization::MacroID> MacroIDs;
+ struct MacroInfoToEmitData {
+ const IdentifierInfo *Name;
+ MacroInfo *MI;
+ serialization::MacroID ID;
+ };
+ /// \brief The macro infos to emit.
+ std::vector<MacroInfoToEmitData> MacroInfosToEmit;
+
+ llvm::DenseMap<const IdentifierInfo *, uint64_t> IdentMacroDirectivesOffsetMap;
+
/// @name FlushStmt Caches
/// @{
@@ -266,11 +277,6 @@ private:
/// table, indexed by the Selector ID (-1).
std::vector<uint32_t> SelectorOffsets;
- typedef llvm::MapVector<MacroInfo *, MacroUpdate> MacroUpdatesMap;
-
- /// \brief Updates to macro definitions that were loaded from an AST file.
- MacroUpdatesMap MacroUpdates;
-
/// \brief Mapping from macro definitions (as they occur in the preprocessing
/// record) to the macro IDs.
llvm::DenseMap<const MacroDefinition *, serialization::PreprocessedEntityID>
@@ -343,7 +349,7 @@ private:
/// \brief The set of declarations that may have redeclaration chains that
/// need to be serialized.
- llvm::SetVector<Decl *, llvm::SmallVector<Decl *, 4>,
+ llvm::SetVector<Decl *, SmallVector<Decl *, 4>,
llvm::SmallPtrSet<Decl *, 4> > Redeclarations;
/// \brief Statements that we've encountered while serializing a
@@ -415,7 +421,9 @@ private:
void WriteBlockInfoBlock();
void WriteControlBlock(Preprocessor &PP, ASTContext &Context,
StringRef isysroot, const std::string &OutputFile);
- void WriteInputFiles(SourceManager &SourceMgr, StringRef isysroot);
+ void WriteInputFiles(SourceManager &SourceMgr,
+ HeaderSearchOptions &HSOpts,
+ StringRef isysroot);
void WriteSourceManagerBlock(SourceManager &SourceMgr,
const Preprocessor &PP,
StringRef isysroot);
@@ -424,7 +432,8 @@ private:
void WritePreprocessorDetail(PreprocessingRecord &PPRec);
void WriteSubmodules(Module *WritingModule);
- void WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag);
+ void WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag,
+ bool isModule);
void WriteCXXBaseSpecifiersOffsets();
void WriteType(QualType T);
uint64_t WriteDeclContextLexicalBlock(ASTContext &Context, DeclContext *DC);
@@ -437,7 +446,6 @@ private:
void WriteIdentifierTable(Preprocessor &PP, IdentifierResolver &IdResolver,
bool IsModule);
void WriteAttributes(ArrayRef<const Attr*> Attrs, RecordDataImpl &Record);
- void WriteMacroUpdates();
void ResolveDeclUpdatesBlocks();
void WriteDeclUpdatesBlocks();
void WriteDeclReplacementsBlock();
@@ -508,9 +516,6 @@ public:
/// \brief Emit a reference to an identifier.
void AddIdentifierRef(const IdentifierInfo *II, RecordDataImpl &Record);
- /// \brief Emit a reference to a macro.
- void addMacroRef(MacroInfo *MI, RecordDataImpl &Record);
-
/// \brief Emit a Selector (which is a smart pointer reference).
void AddSelectorRef(Selector, RecordDataImpl &Record);
@@ -529,7 +534,12 @@ public:
serialization::IdentID getIdentifierRef(const IdentifierInfo *II);
/// \brief Get the unique number used to refer to the given macro.
- serialization::MacroID getMacroRef(MacroInfo *MI);
+ serialization::MacroID getMacroRef(MacroInfo *MI, const IdentifierInfo *Name);
+
+ /// \brief Determine the ID of an already-emitted macro.
+ serialization::MacroID getMacroID(MacroInfo *MI);
+
+ uint64_t getMacroDirectivesOffset(const IdentifierInfo *Name);
/// \brief Emit a reference to a type.
void AddTypeRef(QualType T, RecordDataImpl &Record);
@@ -603,7 +613,7 @@ public:
RecordDataImpl &Record);
/// \brief Emit a UnresolvedSet structure.
- void AddUnresolvedSet(const UnresolvedSetImpl &Set, RecordDataImpl &Record);
+ void AddUnresolvedSet(const ASTUnresolvedSet &Set, RecordDataImpl &Record);
/// \brief Emit a C++ base specifier.
void AddCXXBaseSpecifier(const CXXBaseSpecifier &Base,
@@ -640,6 +650,10 @@ public:
/// source location.
serialization::SubmoduleID inferSubmoduleIDFromLocation(SourceLocation Loc);
+ /// \brief Retrieve a submodule ID for this module.
+ /// Returns 0 If no ID has been associated with the module.
+ unsigned getExistingSubmoduleID(Module *Mod) const;
+
/// \brief Note that the identifier II occurs at the given offset
/// within the identifier table.
void SetIdentifierOffset(const IdentifierInfo *II, uint32_t Offset);
@@ -699,9 +713,6 @@ public:
MacroDefinition *MD);
void ModuleRead(serialization::SubmoduleID ID, Module *Mod);
- // PPMutationListener implementation.
- virtual void UndefinedMacro(MacroInfo *MI);
-
// ASTMutationListener implementation.
virtual void CompletedTagDefinition(const TagDecl *D);
virtual void AddedVisibleDecl(const DeclContext *DC, const Decl *D);
@@ -728,7 +739,7 @@ class PCHGenerator : public SemaConsumer {
std::string isysroot;
raw_ostream *Out;
Sema *SemaPtr;
- llvm::SmallVector<char, 128> Buffer;
+ SmallVector<char, 128> Buffer;
llvm::BitstreamWriter Stream;
ASTWriter Writer;
@@ -743,7 +754,6 @@ public:
~PCHGenerator();
virtual void InitializeSema(Sema &S) { SemaPtr = &S; }
virtual void HandleTranslationUnit(ASTContext &Ctx);
- virtual PPMutationListener *GetPPMutationListener();
virtual ASTMutationListener *GetASTMutationListener();
virtual ASTDeserializationListener *GetASTDeserializationListener();
};
diff --git a/include/clang/Serialization/ContinuousRangeMap.h b/include/clang/Serialization/ContinuousRangeMap.h
index d89cd02903d6..f8ef8a1a63cf 100644
--- a/include/clang/Serialization/ContinuousRangeMap.h
+++ b/include/clang/Serialization/ContinuousRangeMap.h
@@ -15,6 +15,7 @@
#ifndef LLVM_CLANG_SERIALIZATION_CONTINUOUS_RANGE_MAP_H
#define LLVM_CLANG_SERIALIZATION_CONTINUOUS_RANGE_MAP_H
+#include "clang/Basic/LLVM.h"
#include "llvm/ADT/SmallVector.h"
#include <algorithm>
#include <utility>
diff --git a/include/clang/Serialization/GlobalModuleIndex.h b/include/clang/Serialization/GlobalModuleIndex.h
new file mode 100644
index 000000000000..eaf26d1df16f
--- /dev/null
+++ b/include/clang/Serialization/GlobalModuleIndex.h
@@ -0,0 +1,194 @@
+//===--- GlobalModuleIndex.h - Global Module Index --------------*- 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 GlobalModuleIndex class, which manages a global index
+// containing all of the identifiers known to the various modules within a given
+// subdirectory of the module cache. It is used to improve the performance of
+// queries such as "do any modules know about this identifier?"
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_SERIALIZATION_GLOBAL_MODULE_INDEX_H
+#define LLVM_CLANG_SERIALIZATION_GLOBAL_MODULE_INDEX_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include <utility>
+
+namespace llvm {
+class BitstreamCursor;
+class MemoryBuffer;
+}
+
+namespace clang {
+
+class DirectoryEntry;
+class FileEntry;
+class FileManager;
+
+namespace serialization {
+ class ModuleFile;
+}
+
+using llvm::SmallVector;
+using llvm::SmallVectorImpl;
+using llvm::StringRef;
+using serialization::ModuleFile;
+
+/// \brief A global index for a set of module files, providing information about
+/// the identifiers within those module files.
+///
+/// The global index is an aid for name lookup into modules, offering a central
+/// place where one can look for identifiers determine which
+/// module files contain any information about that identifier. This
+/// allows the client to restrict the search to only those module files known
+/// to have a information about that identifier, improving performance. Moreover,
+/// the global module index may know about module files that have not been
+/// imported, and can be queried to determine which modules the current
+/// translation could or should load to fix a problem.
+class GlobalModuleIndex {
+ /// \brief Buffer containing the index file, which is lazily accessed so long
+ /// as the global module index is live.
+ llvm::OwningPtr<llvm::MemoryBuffer> Buffer;
+
+ /// \brief The hash table.
+ ///
+ /// This pointer actually points to a IdentifierIndexTable object,
+ /// but that type is only accessible within the implementation of
+ /// GlobalModuleIndex.
+ void *IdentifierIndex;
+
+ /// \brief Information about a given module file.
+ struct ModuleInfo {
+ ModuleInfo() : File(), Size(), ModTime() { }
+
+ /// \brief The module file, once it has been resolved.
+ ModuleFile *File;
+
+ /// \brief The module file name.
+ std::string FileName;
+
+ /// \brief Size of the module file at the time the global index was built.
+ off_t Size;
+
+ /// \brief Modification time of the module file at the time the global
+ /// index was built.
+ time_t ModTime;
+
+ /// \brief The module IDs on which this module directly depends.
+ /// FIXME: We don't really need a vector here.
+ llvm::SmallVector<unsigned, 4> Dependencies;
+ };
+
+ /// \brief A mapping from module IDs to information about each module.
+ ///
+ /// This vector may have gaps, if module files have been removed or have
+ /// been updated since the index was built. A gap is indicated by an empty
+ /// file name.
+ llvm::SmallVector<ModuleInfo, 16> Modules;
+
+ /// \brief Lazily-populated mapping from module files to their
+ /// corresponding index into the \c Modules vector.
+ llvm::DenseMap<ModuleFile *, unsigned> ModulesByFile;
+
+ /// \brief The set of modules that have not yet been resolved.
+ ///
+ /// The string is just the name of the module itself, which maps to the
+ /// module ID.
+ llvm::StringMap<unsigned> UnresolvedModules;
+
+ /// \brief The number of identifier lookups we performed.
+ unsigned NumIdentifierLookups;
+
+ /// \brief The number of identifier lookup hits, where we recognize the
+ /// identifier.
+ unsigned NumIdentifierLookupHits;
+
+ /// \brief Internal constructor. Use \c readIndex() to read an index.
+ explicit GlobalModuleIndex(llvm::MemoryBuffer *Buffer,
+ llvm::BitstreamCursor Cursor);
+
+ GlobalModuleIndex(const GlobalModuleIndex &) LLVM_DELETED_FUNCTION;
+ GlobalModuleIndex &operator=(const GlobalModuleIndex &) LLVM_DELETED_FUNCTION;
+
+public:
+ ~GlobalModuleIndex();
+
+ /// \brief An error code returned when trying to read an index.
+ enum ErrorCode {
+ /// \brief No error occurred.
+ EC_None,
+ /// \brief No index was found.
+ EC_NotFound,
+ /// \brief Some other process is currently building the index; it is not
+ /// available yet.
+ EC_Building,
+ /// \brief There was an unspecified I/O error reading or writing the index.
+ EC_IOError
+ };
+
+ /// \brief Read a global index file for the given directory.
+ ///
+ /// \param Path The path to the specific module cache where the module files
+ /// for the intended configuration reside.
+ ///
+ /// \returns A pair containing the global module index (if it exists) and
+ /// the error code.
+ static std::pair<GlobalModuleIndex *, ErrorCode>
+ readIndex(StringRef Path);
+
+ /// \brief Retrieve the set of modules that have up-to-date indexes.
+ ///
+ /// \param ModuleFiles Will be populated with the set of module files that
+ /// have been indexed.
+ void getKnownModules(SmallVectorImpl<ModuleFile *> &ModuleFiles);
+
+ /// \brief Retrieve the set of module files on which the given module file
+ /// directly depends.
+ void getModuleDependencies(ModuleFile *File,
+ SmallVectorImpl<ModuleFile *> &Dependencies);
+
+ /// \brief A set of module files in which we found a result.
+ typedef llvm::SmallPtrSet<ModuleFile *, 4> HitSet;
+
+ /// \brief Look for all of the module files with information about the given
+ /// identifier, e.g., a global function, variable, or type with that name.
+ ///
+ /// \param Name The identifier to look for.
+ ///
+ /// \param Hits Will be populated with the set of module files that have
+ /// information about this name.
+ ///
+ /// \returns true if the identifier is known to the index, false otherwise.
+ bool lookupIdentifier(StringRef Name, HitSet &Hits);
+
+ /// \brief Note that the given module file has been loaded.
+ ///
+ /// \returns false if the global module index has information about this
+ /// module file, and true otherwise.
+ bool loadedModuleFile(ModuleFile *File);
+
+ /// \brief Print statistics to standard error.
+ void printStats();
+
+ /// \brief Write a global index into the given
+ ///
+ /// \param FileMgr The file manager to use to load module files.
+ ///
+ /// \param Path The path to the directory containing module files, into
+ /// which the global index will be written.
+ static ErrorCode writeIndex(FileManager &FileMgr, StringRef Path);
+};
+
+}
+
+#endif
diff --git a/include/clang/Serialization/Module.h b/include/clang/Serialization/Module.h
index 39fa3d90ced4..89c604f393ed 100644
--- a/include/clang/Serialization/Module.h
+++ b/include/clang/Serialization/Module.h
@@ -15,9 +15,9 @@
#ifndef LLVM_CLANG_SERIALIZATION_MODULE_H
#define LLVM_CLANG_SERIALIZATION_MODULE_H
+#include "clang/Basic/SourceLocation.h"
#include "clang/Serialization/ASTBitCodes.h"
#include "clang/Serialization/ContinuousRangeMap.h"
-#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/Bitcode/BitstreamReader.h"
@@ -55,6 +55,35 @@ struct DeclContextInfo {
unsigned NumLexicalDecls;
};
+/// \brief The input file that has been loaded from this AST file, along with
+/// bools indicating whether this was an overridden buffer or if it was
+/// out-of-date.
+class InputFile {
+ enum {
+ Overridden = 1,
+ OutOfDate = 2
+ };
+ llvm::PointerIntPair<const FileEntry *, 2, unsigned> Val;
+
+public:
+ InputFile() {}
+ InputFile(const FileEntry *File,
+ bool isOverridden = false, bool isOutOfDate = false) {
+ assert(!(isOverridden && isOutOfDate) &&
+ "an overridden cannot be out-of-date");
+ unsigned intVal = 0;
+ if (isOverridden)
+ intVal = Overridden;
+ else if (isOutOfDate)
+ intVal = OutOfDate;
+ Val.setPointerAndInt(File, intVal);
+ }
+
+ const FileEntry *getFile() const { return Val.getPointer(); }
+ bool isOverridden() const { return Val.getInt() == Overridden; }
+ bool isOutOfDate() const { return Val.getInt() == OutOfDate; }
+};
+
/// \brief Information about a module that has been loaded by the ASTReader.
///
/// Each instance of the Module class corresponds to a single AST file, which
@@ -69,6 +98,9 @@ public:
// === General information ===
+ /// \brief The index of this module in the list of modules.
+ unsigned Index;
+
/// \brief The type of this module.
ModuleKind Kind;
@@ -121,8 +153,15 @@ public:
/// \brief The main bitstream cursor for the main block.
llvm::BitstreamCursor Stream;
+ /// \brief The source location where the module was explicitly or implicitly
+ /// imported in the local translation unit.
+ ///
+ /// If module A depends on and imports module B, both modules will have the
+ /// same DirectImportLoc, but different ImportLoc (B's ImportLoc will be a
+ /// source location inside module A).
+ SourceLocation DirectImportLoc;
+
/// \brief The source location where this module was first imported.
- /// FIXME: This is not properly initialized yet.
SourceLocation ImportLoc;
/// \brief The first source location in this module.
@@ -135,10 +174,8 @@ public:
/// \brief Offsets for all of the input file entries in the AST file.
const uint32_t *InputFileOffsets;
- /// \brief The input files that have been loaded from this AST file, along
- /// with a bool indicating whether this was an overridden buffer.
- std::vector<llvm::PointerIntPair<const FileEntry *, 1, bool> >
- InputFilesLoaded;
+ /// \brief The input files that have been loaded from this AST file.
+ std::vector<InputFile> InputFilesLoaded;
// === Source Locations ===
@@ -252,10 +289,6 @@ public:
/// the header files.
void *HeaderFileInfoTable;
- /// \brief Actual data for the list of framework names used in the header
- /// search information.
- const char *HeaderFileFrameworkStrings;
-
// === Submodule information ===
/// \brief The number of submodules in this module.
unsigned LocalNumSubmodules;
diff --git a/include/clang/Serialization/ModuleManager.h b/include/clang/Serialization/ModuleManager.h
index 6dcaa210d2d8..b2c406346a5f 100644
--- a/include/clang/Serialization/ModuleManager.h
+++ b/include/clang/Serialization/ModuleManager.h
@@ -15,19 +15,22 @@
#ifndef LLVM_CLANG_SERIALIZATION_MODULE_MANAGER_H
#define LLVM_CLANG_SERIALIZATION_MODULE_MANAGER_H
-#include "clang/Serialization/Module.h"
#include "clang/Basic/FileManager.h"
+#include "clang/Serialization/Module.h"
#include "llvm/ADT/DenseMap.h"
namespace clang {
+class GlobalModuleIndex;
+class ModuleMap;
+
namespace serialization {
-
+
/// \brief Manages the set of modules loaded by an AST reader.
class ModuleManager {
/// \brief The chain of AST files. The first entry is the one named by the
/// user, the last one is the one that doesn't depend on anything further.
- llvm::SmallVector<ModuleFile*, 2> Chain;
+ SmallVector<ModuleFile *, 2> Chain;
/// \brief All loaded modules, indexed by name.
llvm::DenseMap<const FileEntry *, ModuleFile *> Modules;
@@ -38,7 +41,60 @@ class ModuleManager {
/// \brief A lookup of in-memory (virtual file) buffers
llvm::DenseMap<const FileEntry *, llvm::MemoryBuffer *> InMemoryBuffers;
-
+
+ /// \brief The visitation order.
+ SmallVector<ModuleFile *, 4> VisitOrder;
+
+ /// \brief The list of module files that both we and the global module index
+ /// know about.
+ ///
+ /// Either the global index or the module manager may have modules that the
+ /// other does not know about, because the global index can be out-of-date
+ /// (in which case the module manager could have modules it does not) and
+ /// this particular translation unit might not have loaded all of the modules
+ /// known to the global index.
+ SmallVector<ModuleFile *, 4> ModulesInCommonWithGlobalIndex;
+
+ /// \brief The global module index, if one is attached.
+ ///
+ /// The global module index will actually be owned by the ASTReader; this is
+ /// just an non-owning pointer.
+ GlobalModuleIndex *GlobalIndex;
+
+ /// \brief State used by the "visit" operation to avoid malloc traffic in
+ /// calls to visit().
+ struct VisitState {
+ explicit VisitState(unsigned N)
+ : VisitNumber(N, 0), NextVisitNumber(1), NextState(0)
+ {
+ Stack.reserve(N);
+ }
+
+ ~VisitState() {
+ delete NextState;
+ }
+
+ /// \brief The stack used when marking the imports of a particular module
+ /// as not-to-be-visited.
+ SmallVector<ModuleFile *, 4> Stack;
+
+ /// \brief The visit number of each module file, which indicates when
+ /// this module file was last visited.
+ SmallVector<unsigned, 4> VisitNumber;
+
+ /// \brief The next visit number to use to mark visited module files.
+ unsigned NextVisitNumber;
+
+ /// \brief The next visit state.
+ VisitState *NextState;
+ };
+
+ /// \brief The first visit() state in the chain.
+ VisitState *FirstVisitState;
+
+ VisitState *allocateVisitState();
+ void returnVisitState(VisitState *State);
+
public:
typedef SmallVector<ModuleFile*, 2>::iterator ModuleIterator;
typedef SmallVector<ModuleFile*, 2>::const_iterator ModuleConstIterator;
@@ -79,12 +135,28 @@ public:
/// \brief Returns the module associated with the given name
ModuleFile *lookup(StringRef Name);
-
+
+ /// \brief Returns the module associated with the given module file.
+ ModuleFile *lookup(const FileEntry *File);
+
/// \brief Returns the in-memory (virtual file) buffer with the given name
llvm::MemoryBuffer *lookupBuffer(StringRef Name);
/// \brief Number of modules loaded
unsigned size() const { return Chain.size(); }
+
+ /// \brief The result of attempting to add a new module.
+ enum AddModuleResult {
+ /// \brief The module file had already been loaded.
+ AlreadyLoaded,
+ /// \brief The module file was just loaded in response to this call.
+ NewlyLoaded,
+ /// \brief The module file is missing.
+ Missing,
+ /// \brief The module file is out-of-date.
+ OutOfDate
+ };
+
/// \brief Attempts to create a new module and add it to the list of known
/// modules.
///
@@ -92,26 +164,48 @@ public:
///
/// \param Type The kind of module being loaded.
///
+ /// \param ImportLoc The location at which the module is imported.
+ ///
/// \param ImportedBy The module that is importing this module, or NULL if
/// this module is imported directly by the user.
///
/// \param Generation The generation in which this module was loaded.
///
+ /// \param ExpectedSize The expected size of the module file, used for
+ /// validation. This will be zero if unknown.
+ ///
+ /// \param ExpectedModTime The expected modification time of the module
+ /// file, used for validation. This will be zero if unknown.
+ ///
+ /// \param Module A pointer to the module file if the module was successfully
+ /// loaded.
+ ///
/// \param ErrorStr Will be set to a non-empty string if any errors occurred
/// while trying to load the module.
///
/// \return A pointer to the module that corresponds to this file name,
- /// and a boolean indicating whether the module was newly added.
- std::pair<ModuleFile *, bool>
- addModule(StringRef FileName, ModuleKind Type, ModuleFile *ImportedBy,
- unsigned Generation, std::string &ErrorStr);
+ /// and a value indicating whether the module was loaded.
+ AddModuleResult addModule(StringRef FileName, ModuleKind Type,
+ SourceLocation ImportLoc,
+ ModuleFile *ImportedBy, unsigned Generation,
+ off_t ExpectedSize, time_t ExpectedModTime,
+ ModuleFile *&Module,
+ std::string &ErrorStr);
/// \brief Remove the given set of modules.
- void removeModules(ModuleIterator first, ModuleIterator last);
+ void removeModules(ModuleIterator first, ModuleIterator last,
+ ModuleMap *modMap);
/// \brief Add an in-memory buffer the list of known buffers
void addInMemoryBuffer(StringRef FileName, llvm::MemoryBuffer *Buffer);
-
+
+ /// \brief Set the global module index.
+ void setGlobalIndex(GlobalModuleIndex *Index);
+
+ /// \brief Notification from the AST reader that the given module file
+ /// has been "accepted", and will not (can not) be unloaded.
+ void moduleFileAccepted(ModuleFile *MF);
+
/// \brief Visit each of the modules.
///
/// This routine visits each of the modules, starting with the
@@ -130,7 +224,13 @@ public:
///
/// \param UserData User data associated with the visitor object, which
/// will be passed along to the visitor.
- void visit(bool (*Visitor)(ModuleFile &M, void *UserData), void *UserData);
+ ///
+ /// \param ModuleFilesHit If non-NULL, contains the set of module files
+ /// that we know we need to visit because the global module index told us to.
+ /// Any module that is known to both the global module index and the module
+ /// manager that is *not* in this set can be skipped.
+ void visit(bool (*Visitor)(ModuleFile &M, void *UserData), void *UserData,
+ llvm::SmallPtrSet<ModuleFile *, 4> *ModuleFilesHit = 0);
/// \brief Visit each of the modules with a depth-first traversal.
///
@@ -151,7 +251,29 @@ public:
void visitDepthFirst(bool (*Visitor)(ModuleFile &M, bool Preorder,
void *UserData),
void *UserData);
-
+
+ /// \brief Attempt to resolve the given module file name to a file entry.
+ ///
+ /// \param FileName The name of the module file.
+ ///
+ /// \param ExpectedSize The size that the module file is expected to have.
+ /// If the actual size differs, the resolver should return \c true.
+ ///
+ /// \param ExpectedModTime The modification time that the module file is
+ /// expected to have. If the actual modification time differs, the resolver
+ /// should return \c true.
+ ///
+ /// \param File Will be set to the file if there is one, or null
+ /// otherwise.
+ ///
+ /// \returns True if a file exists but does not meet the size/
+ /// modification time criteria, false if the file is either available and
+ /// suitable, or is missing.
+ bool lookupModuleFile(StringRef FileName,
+ off_t ExpectedSize,
+ time_t ExpectedModTime,
+ const FileEntry *&File);
+
/// \brief View the graphviz representation of the module graph.
void viewGraph();
};
diff --git a/include/clang/StaticAnalyzer/Core/Analyses.def b/include/clang/StaticAnalyzer/Core/Analyses.def
index 01a6ffd7142c..dc7945016b1a 100644
--- a/include/clang/StaticAnalyzer/Core/Analyses.def
+++ b/include/clang/StaticAnalyzer/Core/Analyses.def
@@ -41,22 +41,12 @@ ANALYSIS_PURGE(PurgeStmt, "statement", "Purge symbols, bindings, and constraint
ANALYSIS_PURGE(PurgeBlock, "block", "Purge symbols, bindings, and constraints before every basic block")
ANALYSIS_PURGE(PurgeNone, "none", "Do not purge symbols, bindings, or constraints")
-#ifndef ANALYSIS_IPA
-#define ANALYSIS_IPA(NAME, CMDFLAG, DESC)
-#endif
-
-ANALYSIS_IPA(None, "none", "Perform only intra-procedural analysis")
-ANALYSIS_IPA(BasicInlining, "basic-inlining", "Inline C functions and blocks when their definitions are available")
-ANALYSIS_IPA(Inlining, "inlining", "Inline callees when their definitions are available")
-ANALYSIS_IPA(DynamicDispatch, "dynamic", "Experimental: Enable inlining of dynamically dispatched methods")
-ANALYSIS_IPA(DynamicDispatchBifurcate, "dynamic-bifurcate", "Experimental: Enable inlining of dynamically dispatched methods, bifurcate paths when exact type info is unavailable")
-
#ifndef ANALYSIS_INLINING_MODE
#define ANALYSIS_INLINING_MODE(NAME, CMDFLAG, DESC)
#endif
-ANALYSIS_INLINING_MODE(All, "all", "Analyze all functions in the order defined in the TU")
-ANALYSIS_INLINING_MODE(NoRedundancy, "noredundancy", "Do not analyze a function which has been previously inlined, use call graph to order")
+ANALYSIS_INLINING_MODE(All, "all", "Analyze all functions as top level")
+ANALYSIS_INLINING_MODE(NoRedundancy, "noredundancy", "Do not analyze a function which has been previously inlined")
#undef ANALYSIS_STORE
#undef ANALYSIS_CONSTRAINTS
diff --git a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
index fa0754acb150..6dbdbbf89b96 100644
--- a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
+++ b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
@@ -15,12 +15,12 @@
#ifndef LLVM_CLANG_ANALYZEROPTIONS_H
#define LLVM_CLANG_ANALYZEROPTIONS_H
-#include <string>
-#include <vector>
#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringMap.h"
+#include <string>
+#include <vector>
namespace clang {
class ASTConsumer;
@@ -64,13 +64,6 @@ enum AnalysisPurgeMode {
NumPurgeModes
};
-/// AnalysisIPAMode - Set of inter-procedural modes.
-enum AnalysisIPAMode {
-#define ANALYSIS_IPA(NAME, CMDFLAG, DESC) NAME,
-#include "clang/StaticAnalyzer/Core/Analyses.def"
-NumIPAModes
-};
-
/// AnalysisInlineFunctionSelection - Set of inlining function selection heuristics.
enum AnalysisInliningMode {
#define ANALYSIS_INLINING_MODE(NAME, CMDFLAG, DESC) NAME,
@@ -102,8 +95,28 @@ enum CXXInlineableMemberKind {
CIMK_Destructors
};
+/// \brief Describes the different modes of inter-procedural analysis.
+enum IPAKind {
+ IPAK_NotSet = 0,
+
+ /// Perform only intra-procedural analysis.
+ IPAK_None = 1,
+
+ /// Inline C functions and blocks when their definitions are available.
+ IPAK_BasicInlining = 2,
-class AnalyzerOptions : public llvm::RefCountedBase<AnalyzerOptions> {
+ /// Inline callees(C, C++, ObjC) when their definitions are available.
+ IPAK_Inlining = 3,
+
+ /// Enable inlining of dynamically dispatched methods.
+ IPAK_DynamicDispatch = 4,
+
+ /// Enable inlining of dynamically dispatched methods, bifurcate paths when
+ /// exact type info is unavailable.
+ IPAK_DynamicDispatchBifurcate = 5
+};
+
+class AnalyzerOptions : public RefCountedBase<AnalyzerOptions> {
public:
typedef llvm::StringMap<std::string> ConfigTable;
@@ -117,14 +130,8 @@ public:
AnalysisDiagClients AnalysisDiagOpt;
AnalysisPurgeMode AnalysisPurgeOpt;
- // \brief The interprocedural analysis mode.
- AnalysisIPAMode IPAMode;
-
std::string AnalyzeSpecificFunction;
- /// \brief The maximum number of exploded nodes the analyzer will generate.
- unsigned MaxNodes;
-
/// \brief The maximum number of times the analyzer visits a block.
unsigned maxBlockVisitOnPath;
@@ -159,39 +166,71 @@ public:
unsigned InlineMaxStackDepth;
/// \brief The mode of function selection used during inlining.
- unsigned InlineMaxFunctionSize;
-
- /// \brief The mode of function selection used during inlining.
AnalysisInliningMode InliningMode;
private:
+ /// \brief Describes the kinds for high-level analyzer mode.
+ enum UserModeKind {
+ UMK_NotSet = 0,
+ /// Perform shallow but fast analyzes.
+ UMK_Shallow = 1,
+ /// Perform deep analyzes.
+ UMK_Deep = 2
+ };
+
+ /// Controls the high-level analyzer mode, which influences the default
+ /// settings for some of the lower-level config options (such as IPAMode).
+ /// \sa getUserMode
+ UserModeKind UserMode;
+
+ /// Controls the mode of inter-procedural analysis.
+ IPAKind IPAMode;
+
/// Controls which C++ member functions will be considered for inlining.
CXXInlineableMemberKind CXXMemberInliningMode;
/// \sa includeTemporaryDtorsInCFG
- llvm::Optional<bool> IncludeTemporaryDtorsInCFG;
+ Optional<bool> IncludeTemporaryDtorsInCFG;
/// \sa mayInlineCXXStandardLibrary
- llvm::Optional<bool> InlineCXXStandardLibrary;
+ Optional<bool> InlineCXXStandardLibrary;
/// \sa mayInlineTemplateFunctions
- llvm::Optional<bool> InlineTemplateFunctions;
+ Optional<bool> InlineTemplateFunctions;
+
+ /// \sa mayInlineCXXContainerCtorsAndDtors
+ Optional<bool> InlineCXXContainerCtorsAndDtors;
/// \sa mayInlineObjCMethod
- llvm::Optional<bool> ObjCInliningMode;
+ Optional<bool> ObjCInliningMode;
// Cache of the "ipa-always-inline-size" setting.
// \sa getAlwaysInlineSize
- llvm::Optional<unsigned> AlwaysInlineSize;
+ Optional<unsigned> AlwaysInlineSize;
- /// \sa shouldPruneNullReturnPaths
- llvm::Optional<bool> PruneNullReturnPaths;
+ /// \sa shouldSuppressNullReturnPaths
+ Optional<bool> SuppressNullReturnPaths;
+
+ // \sa getMaxInlinableSize
+ Optional<unsigned> MaxInlinableSize;
/// \sa shouldAvoidSuppressingNullArgumentPaths
- llvm::Optional<bool> AvoidSuppressingNullArgumentPaths;
-
+ Optional<bool> AvoidSuppressingNullArgumentPaths;
+
+ /// \sa shouldSuppressInlinedDefensiveChecks
+ Optional<bool> SuppressInlinedDefensiveChecks;
+
+ /// \sa shouldSuppressFromCXXStandardLibrary
+ Optional<bool> SuppressFromCXXStandardLibrary;
+
/// \sa getGraphTrimInterval
- llvm::Optional<unsigned> GraphTrimInterval;
+ Optional<unsigned> GraphTrimInterval;
+
+ /// \sa getMaxTimesInlineLarge
+ Optional<unsigned> MaxTimesInlineLarge;
+
+ /// \sa getMaxNodesPerTopLevelFunction
+ Optional<unsigned> MaxNodesPerTopLevelFunction;
/// Interprets an option's string value as a boolean.
///
@@ -200,13 +239,20 @@ private:
bool getBooleanOption(StringRef Name, bool DefaultVal);
/// Variant that accepts a Optional value to cache the result.
- bool getBooleanOption(llvm::Optional<bool> &V, StringRef Name,
- bool DefaultVal);
-
+ bool getBooleanOption(Optional<bool> &V, StringRef Name, bool DefaultVal);
+
/// Interprets an option's string value as an integer value.
- int getOptionAsInteger(llvm::StringRef Name, int DefaultVal);
+ int getOptionAsInteger(StringRef Name, int DefaultVal);
public:
+ /// \brief Retrieves and sets the UserMode. This is a high-level option,
+ /// which is used to set other low-level options. It is not accessible
+ /// outside of AnalyzerOptions.
+ UserModeKind getUserMode();
+
+ /// \brief Returns the inter-procedural analysis mode.
+ IPAKind getIPAMode();
+
/// Returns the option controlling which C++ member functions will be
/// considered for inlining.
///
@@ -238,6 +284,13 @@ public:
/// accepts the values "true" and "false".
bool mayInlineTemplateFunctions();
+ /// Returns whether or not constructors and destructors of C++ container
+ /// objects may be considered for inlining.
+ ///
+ /// This is controlled by the 'c++-container-inlining' config option, which
+ /// accepts the values "true" and "false".
+ bool mayInlineCXXContainerCtorsAndDtors();
+
/// Returns whether or not paths that go through null returns should be
/// suppressed.
///
@@ -246,12 +299,12 @@ public:
///
/// This is controlled by the 'suppress-null-return-paths' config option,
/// which accepts the values "true" and "false".
- bool shouldPruneNullReturnPaths();
+ bool shouldSuppressNullReturnPaths();
/// Returns whether a bug report should \em not be suppressed if its path
/// includes a call with a null argument, even if that call has a null return.
///
- /// This option has no effect when #shouldPruneNullReturnPaths() is false.
+ /// This option has no effect when #shouldSuppressNullReturnPaths() is false.
///
/// This is a counter-heuristic to avoid false negatives.
///
@@ -259,12 +312,43 @@ public:
/// option, which accepts the values "true" and "false".
bool shouldAvoidSuppressingNullArgumentPaths();
+ /// Returns whether or not diagnostics containing inlined defensive NULL
+ /// checks should be suppressed.
+ ///
+ /// This is controlled by the 'suppress-inlined-defensive-checks' config
+ /// option, which accepts the values "true" and "false".
+ bool shouldSuppressInlinedDefensiveChecks();
+
+ /// Returns whether or not diagnostics reported within the C++ standard
+ /// library should be suppressed.
+ ///
+ /// This is controlled by the 'suppress-c++-stdlib' config option,
+ /// which accepts the values "true" and "false".
+ bool shouldSuppressFromCXXStandardLibrary();
+
+ /// Returns whether irrelevant parts of a bug report path should be pruned
+ /// out of the final output.
+ ///
+ /// This is controlled by the 'prune-paths' config option, which accepts the
+ /// values "true" and "false".
+ bool shouldPrunePaths();
+
+ /// Returns true if 'static' initializers should be in conditional logic
+ /// in the CFG.
+ bool shouldConditionalizeStaticInitializers();
+
// Returns the size of the functions (in basic blocks), which should be
// considered to be small enough to always inline.
//
// This is controlled by "ipa-always-inline-size" analyzer-config option.
unsigned getAlwaysInlineSize();
-
+
+ // Returns the bound on the number of basic blocks in an inlined function
+ // (50 by default).
+ //
+ // This is controlled by "-analyzer-config max-inlinable-size" option.
+ unsigned getMaxInlinableSize();
+
/// Returns true if the analyzer engine should synthesize fake bodies
/// for well-known functions.
bool shouldSynthesizeBodies();
@@ -276,32 +360,45 @@ public:
/// node reclamation, set the option to "0".
unsigned getGraphTrimInterval();
+ /// Returns the maximum times a large function could be inlined.
+ ///
+ /// This is controlled by the 'max-times-inline-large' config option.
+ unsigned getMaxTimesInlineLarge();
+
+ /// Returns the maximum number of nodes the analyzer can generate while
+ /// exploring a top level function (for each exploded graph).
+ /// 150000 is default; 0 means no limit.
+ ///
+ /// This is controlled by the 'max-nodes' config option.
+ unsigned getMaxNodesPerTopLevelFunction();
+
public:
- AnalyzerOptions() : CXXMemberInliningMode() {
- AnalysisStoreOpt = RegionStoreModel;
- AnalysisConstraintsOpt = RangeConstraintsModel;
- AnalysisDiagOpt = PD_HTML;
- AnalysisPurgeOpt = PurgeStmt;
- IPAMode = DynamicDispatchBifurcate;
- ShowCheckerHelp = 0;
- AnalyzeAll = 0;
- AnalyzerDisplayProgress = 0;
- AnalyzeNestedBlocks = 0;
- eagerlyAssumeBinOpBifurcation = 0;
- TrimGraph = 0;
- visualizeExplodedGraphWithGraphViz = 0;
- visualizeExplodedGraphWithUbiGraph = 0;
- UnoptimizedCFG = 0;
- PrintStats = 0;
- NoRetryExhausted = 0;
+ AnalyzerOptions() :
+ AnalysisStoreOpt(RegionStoreModel),
+ AnalysisConstraintsOpt(RangeConstraintsModel),
+ AnalysisDiagOpt(PD_HTML),
+ AnalysisPurgeOpt(PurgeStmt),
+ ShowCheckerHelp(0),
+ AnalyzeAll(0),
+ AnalyzerDisplayProgress(0),
+ AnalyzeNestedBlocks(0),
+ eagerlyAssumeBinOpBifurcation(0),
+ TrimGraph(0),
+ visualizeExplodedGraphWithGraphViz(0),
+ visualizeExplodedGraphWithUbiGraph(0),
+ UnoptimizedCFG(0),
+ PrintStats(0),
+ NoRetryExhausted(0),
// Cap the stack depth at 4 calls (5 stack frames, base + 4 calls).
- InlineMaxStackDepth = 5;
- InlineMaxFunctionSize = 200;
- InliningMode = NoRedundancy;
- }
+ InlineMaxStackDepth(5),
+ InliningMode(NoRedundancy),
+ UserMode(UMK_NotSet),
+ IPAMode(IPAK_NotSet),
+ CXXMemberInliningMode() {}
+
};
-typedef llvm::IntrusiveRefCntPtr<AnalyzerOptions> AnalyzerOptionsRef;
+typedef IntrusiveRefCntPtr<AnalyzerOptions> AnalyzerOptionsRef;
}
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
index b5a88ba9f6c6..7a87e47f74ce 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
@@ -19,12 +19,12 @@
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h"
#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/ilist.h"
-#include "llvm/ADT/ilist_node.h"
#include "llvm/ADT/ImmutableSet.h"
-#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/ilist.h"
+#include "llvm/ADT/ilist_node.h"
namespace clang {
@@ -75,6 +75,8 @@ protected:
std::string Description;
PathDiagnosticLocation Location;
PathDiagnosticLocation UniqueingLocation;
+ const Decl *UniqueingDecl;
+
const ExplodedNode *ErrorNode;
SmallVector<SourceRange, 4> Ranges;
ExtraTextList ExtraText;
@@ -87,14 +89,14 @@ protected:
/// diagnostics to include when constructing the final path diagnostic.
/// The stack is largely used by BugReporter when generating PathDiagnostics
/// for multiple PathDiagnosticConsumers.
- llvm::SmallVector<Symbols *, 2> interestingSymbols;
+ SmallVector<Symbols *, 2> interestingSymbols;
/// A (stack of) set of regions that are registered with this report as being
/// "interesting", and thus used to help decide which diagnostics
/// to include when constructing the final path diagnostic.
/// The stack is largely used by BugReporter when generating PathDiagnostics
/// for multiple PathDiagnosticConsumers.
- llvm::SmallVector<Regions *, 2> interestingRegions;
+ SmallVector<Regions *, 2> interestingRegions;
/// A set of location contexts that correspoind to call sites which should be
/// considered "interesting".
@@ -162,9 +164,10 @@ public:
/// for uniquing reports. For example, memory leaks checker, could set this to
/// the allocation site, rather then the location where the bug is reported.
BugReport(BugType& bt, StringRef desc, const ExplodedNode *errornode,
- PathDiagnosticLocation LocationToUnique)
+ PathDiagnosticLocation LocationToUnique, const Decl *DeclToUnique)
: BT(bt), DeclWithIssue(0), Description(desc),
UniqueingLocation(LocationToUnique),
+ UniqueingDecl(DeclToUnique),
ErrorNode(errornode), ConfigurationChangeToken(0),
DoNotPrunePath(false) {}
@@ -260,6 +263,16 @@ public:
/// This location is used by clients rendering diagnostics.
virtual PathDiagnosticLocation getLocation(const SourceManager &SM) const;
+ /// \brief Get the location on which the report should be uniqued.
+ PathDiagnosticLocation getUniqueingLocation() const {
+ return UniqueingLocation;
+ }
+
+ /// \brief Get the declaration containing the uniqueing location.
+ const Decl *getUniqueingDecl() const {
+ return UniqueingDecl;
+ }
+
const Stmt *getStmt() const;
/// \brief Add a range to a bug report.
@@ -440,8 +453,7 @@ public:
return true;
}
- bool RemoveUneededCalls(PathPieces &pieces, BugReport *R,
- PathDiagnosticCallPiece *CallWithLoc = 0);
+ bool RemoveUnneededCalls(PathPieces &pieces, BugReport *R);
void Register(BugType *BT);
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
index 78e35ca82b89..2e5f207f4b4c 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
@@ -55,8 +55,8 @@ public:
///
/// The last parameter can be used to register a new visitor with the given
/// BugReport while processing a node.
- virtual PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
- const ExplodedNode *PrevN,
+ virtual PathDiagnosticPiece *VisitNode(const ExplodedNode *Succ,
+ const ExplodedNode *Pred,
BugReporterContext &BRC,
BugReport &BR) = 0;
@@ -99,26 +99,24 @@ class FindLastStoreBRVisitor
{
const MemRegion *R;
SVal V;
- bool satisfied;
+ bool Satisfied;
-public:
- /// \brief Convenience method to create a visitor given only the MemRegion.
- /// Returns NULL if the visitor cannot be created. For example, when the
- /// corresponding value is unknown.
- static BugReporterVisitor *createVisitorObject(const ExplodedNode *N,
- const MemRegion *R);
+ /// If the visitor is tracking the value directly responsible for the
+ /// bug, we are going to employ false positive suppression.
+ bool EnableNullFPSuppression;
+public:
/// Creates a visitor for every VarDecl inside a Stmt and registers it with
/// the BugReport.
- static void registerStatementVarDecls(BugReport &BR, const Stmt *S);
+ static void registerStatementVarDecls(BugReport &BR, const Stmt *S,
+ bool EnableNullFPSuppression);
- FindLastStoreBRVisitor(SVal v, const MemRegion *r)
- : R(r), V(v), satisfied(false) {
- assert (!V.isUnknown() && "Cannot track unknown value.");
-
- // TODO: Does it make sense to allow undef values here?
- // (If not, also see UndefCapturedBlockVarChecker)?
- }
+ FindLastStoreBRVisitor(KnownSVal V, const MemRegion *R,
+ bool InEnableNullFPSuppression)
+ : R(R),
+ V(V),
+ Satisfied(false),
+ EnableNullFPSuppression(InEnableNullFPSuppression) {}
void Profile(llvm::FoldingSetNodeID &ID) const;
@@ -132,12 +130,14 @@ class TrackConstraintBRVisitor
: public BugReporterVisitorImpl<TrackConstraintBRVisitor>
{
DefinedSVal Constraint;
- const bool Assumption;
- bool isSatisfied;
+ bool Assumption;
+ bool IsSatisfied;
+ bool IsZeroCheck;
public:
TrackConstraintBRVisitor(DefinedSVal constraint, bool assumption)
- : Constraint(constraint), Assumption(assumption), isSatisfied(false) {}
+ : Constraint(constraint), Assumption(assumption), IsSatisfied(false),
+ IsZeroCheck(!Assumption && Constraint.getAs<Loc>()) {}
void Profile(llvm::FoldingSetNodeID &ID) const;
@@ -149,12 +149,19 @@ public:
const ExplodedNode *PrevN,
BugReporterContext &BRC,
BugReport &BR);
+
+private:
+ /// Checks if the constraint is valid in the current state.
+ bool isUnderconstrained(const ExplodedNode *N) const;
+
};
+/// \class NilReceiverBRVisitor
+/// \brief Prints path notes when a message is sent to a nil receiver.
class NilReceiverBRVisitor
- : public BugReporterVisitorImpl<NilReceiverBRVisitor>
-{
+ : public BugReporterVisitorImpl<NilReceiverBRVisitor> {
public:
+
void Profile(llvm::FoldingSetNodeID &ID) const {
static int x = 0;
ID.AddPointer(&x);
@@ -164,6 +171,10 @@ public:
const ExplodedNode *PrevN,
BugReporterContext &BRC,
BugReport &BR);
+
+ /// If the statement is a message send expression with nil receiver, returns
+ /// the receiver expression. Returns NULL otherwise.
+ static const Expr *getNilReceiver(const Stmt *S, const ExplodedNode *N);
};
/// Visitor that tries to report interesting diagnostics from conditions.
@@ -223,11 +234,38 @@ public:
const ExplodedNode *N);
bool patternMatch(const Expr *Ex,
- llvm::raw_ostream &Out,
+ raw_ostream &Out,
BugReporterContext &BRC,
BugReport &R,
const ExplodedNode *N,
- llvm::Optional<bool> &prunable);
+ Optional<bool> &prunable);
+};
+
+/// \brief Suppress reports that might lead to known false positives.
+///
+/// Currently this suppresses reports based on locations of bugs.
+class LikelyFalsePositiveSuppressionBRVisitor
+ : public BugReporterVisitorImpl<LikelyFalsePositiveSuppressionBRVisitor> {
+public:
+ static void *getTag() {
+ static int Tag = 0;
+ return static_cast<void *>(&Tag);
+ }
+
+ void Profile(llvm::FoldingSetNodeID &ID) const {
+ ID.AddPointer(getTag());
+ }
+
+ virtual PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
+ const ExplodedNode *Prev,
+ BugReporterContext &BRC,
+ BugReport &BR) {
+ return 0;
+ }
+
+ virtual PathDiagnosticPiece *getEndPath(BugReporterContext &BRC,
+ const ExplodedNode *N,
+ BugReport &BR);
};
/// \brief When a region containing undefined value or '0' value is passed
@@ -256,6 +294,38 @@ public:
BugReport &BR);
};
+class SuppressInlineDefensiveChecksVisitor
+: public BugReporterVisitorImpl<SuppressInlineDefensiveChecksVisitor>
+{
+ /// The symbolic value for which we are tracking constraints.
+ /// This value is constrained to null in the end of path.
+ DefinedSVal V;
+
+ /// Track if we found the node where the constraint was first added.
+ bool IsSatisfied;
+
+ /// Since the visitors can be registered on nodes previous to the last
+ /// node in the BugReport, but the path traversal always starts with the last
+ /// node, the visitor invariant (that we start with a node in which V is null)
+ /// might not hold when node visitation starts. We are going to start tracking
+ /// from the last node in which the value is null.
+ bool IsTrackingTurnedOn;
+
+public:
+ SuppressInlineDefensiveChecksVisitor(DefinedSVal Val, const ExplodedNode *N);
+
+ void Profile(llvm::FoldingSetNodeID &ID) const;
+
+ /// Return the tag associated with this visitor. This tag will be used
+ /// to make all PathDiagnosticPieces created by this visitor.
+ static const char *getTag();
+
+ PathDiagnosticPiece *VisitNode(const ExplodedNode *Succ,
+ const ExplodedNode *Pred,
+ BugReporterContext &BRC,
+ BugReport &BR);
+};
+
namespace bugreporter {
/// Attempts to add visitors to trace a null or undefined value back to its
@@ -268,14 +338,17 @@ namespace bugreporter {
/// \param IsArg Whether the statement is an argument to an inlined function.
/// If this is the case, \p N \em must be the CallEnter node for
/// the function.
+/// \param EnableNullFPSuppression Whether we should employ false positive
+/// suppression (inlined defensive checks, returned null).
///
/// \return Whether or not the function was able to add visitors for this
/// statement. Note that returning \c true does not actually imply
/// that any visitors were added.
bool trackNullOrUndefValue(const ExplodedNode *N, const Stmt *S, BugReport &R,
- bool IsArg = false);
+ bool IsArg = false,
+ bool EnableNullFPSuppression = true);
-const Stmt *GetDerefExpr(const ExplodedNode *N);
+const Expr *getDerefExpr(const Stmt *S);
const Stmt *GetDenomExpr(const ExplodedNode *N);
const Stmt *GetRetValExpr(const ExplodedNode *N);
bool isDeclRefExprToReference(const Expr *E);
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
index cb49122e4a53..644aa3159301 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_ANALYSIS_BUGTYPE
#define LLVM_CLANG_ANALYSIS_BUGTYPE
+#include "clang/Basic/LLVM.h"
#include "llvm/ADT/FoldingSet.h"
#include <string>
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
index 6dc26e670344..3f0a1b1bc144 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
@@ -14,12 +14,12 @@
#ifndef LLVM_CLANG_PATH_DIAGNOSTIC_H
#define LLVM_CLANG_PATH_DIAGNOSTIC_H
-#include "clang/Basic/SourceLocation.h"
#include "clang/Analysis/ProgramPoint.h"
+#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/PointerUnion.h"
#include <deque>
#include <iterator>
#include <string>
@@ -341,7 +341,7 @@ protected:
public:
virtual ~PathDiagnosticPiece();
- llvm::StringRef getString() const { return str; }
+ StringRef getString() const { return str; }
/// Tag this PathDiagnosticPiece with the given C-string.
void setTag(const char *tag) { Tag = tag; }
@@ -461,13 +461,13 @@ public:
};
class PathDiagnosticEventPiece : public PathDiagnosticSpotPiece {
- llvm::Optional<bool> IsPrunable;
+ Optional<bool> IsPrunable;
/// If the event occurs in a different frame than the final diagnostic,
/// supply a message that will be used to construct an extra hint on the
/// returns from all the calls on the stack from this event to the final
/// diagnostic.
- llvm::OwningPtr<StackHintGenerator> CallStackHint;
+ OwningPtr<StackHintGenerator> CallStackHint;
public:
PathDiagnosticEventPiece(const PathDiagnosticLocation &pos,
@@ -670,13 +670,19 @@ class PathDiagnostic : public llvm::FoldingSetNode {
std::deque<std::string> OtherDesc;
PathDiagnosticLocation Loc;
PathPieces pathImpl;
- llvm::SmallVector<PathPieces *, 3> pathStack;
+ SmallVector<PathPieces *, 3> pathStack;
- PathDiagnostic(); // Do not implement.
+ /// \brief Important bug uniqueing location.
+ /// The location info is useful to differentiate between bugs.
+ PathDiagnosticLocation UniqueingLoc;
+ const Decl *UniqueingDecl;
+
+ PathDiagnostic() LLVM_DELETED_FUNCTION;
public:
PathDiagnostic(const Decl *DeclWithIssue, StringRef bugtype,
StringRef verboseDesc, StringRef shortDesc,
- StringRef category);
+ StringRef category, PathDiagnosticLocation LocationToUnique,
+ const Decl *DeclToUnique);
~PathDiagnostic();
@@ -738,6 +744,16 @@ public:
return Loc;
}
+ /// \brief Get the location on which the report should be uniqued.
+ PathDiagnosticLocation getUniqueingLoc() const {
+ return UniqueingLoc;
+ }
+
+ /// \brief Get the declaration containing the uniqueing location.
+ const Decl *getUniqueingDecl() const {
+ return UniqueingDecl;
+ }
+
void flattenLocations() {
Loc.flatten();
for (PathPieces::iterator I = pathImpl.begin(), E = pathImpl.end();
diff --git a/include/clang/StaticAnalyzer/Core/Checker.h b/include/clang/StaticAnalyzer/Core/Checker.h
index 9eb1248f6a71..0dbaab033d2d 100644
--- a/include/clang/StaticAnalyzer/Core/Checker.h
+++ b/include/clang/StaticAnalyzer/Core/Checker.h
@@ -34,11 +34,11 @@ class ASTDecl {
template <typename CHECKER>
static void _checkDecl(void *checker, const Decl *D, AnalysisManager& mgr,
BugReporter &BR) {
- ((const CHECKER *)checker)->checkASTDecl(llvm::cast<DECL>(D), mgr, BR);
+ ((const CHECKER *)checker)->checkASTDecl(cast<DECL>(D), mgr, BR);
}
static bool _handlesDecl(const Decl *D) {
- return llvm::isa<DECL>(D);
+ return isa<DECL>(D);
}
public:
template <typename CHECKER>
@@ -86,11 +86,11 @@ template <typename STMT>
class PreStmt {
template <typename CHECKER>
static void _checkStmt(void *checker, const Stmt *S, CheckerContext &C) {
- ((const CHECKER *)checker)->checkPreStmt(llvm::cast<STMT>(S), C);
+ ((const CHECKER *)checker)->checkPreStmt(cast<STMT>(S), C);
}
static bool _handlesStmt(const Stmt *S) {
- return llvm::isa<STMT>(S);
+ return isa<STMT>(S);
}
public:
template <typename CHECKER>
@@ -105,11 +105,11 @@ template <typename STMT>
class PostStmt {
template <typename CHECKER>
static void _checkStmt(void *checker, const Stmt *S, CheckerContext &C) {
- ((const CHECKER *)checker)->checkPostStmt(llvm::cast<STMT>(S), C);
+ ((const CHECKER *)checker)->checkPostStmt(cast<STMT>(S), C);
}
static bool _handlesStmt(const Stmt *S) {
- return llvm::isa<STMT>(S);
+ return isa<STMT>(S);
}
public:
template <typename CHECKER>
@@ -227,18 +227,18 @@ public:
}
};
-class EndPath {
+class EndFunction {
template <typename CHECKER>
- static void _checkEndPath(void *checker,
- CheckerContext &C) {
- ((const CHECKER *)checker)->checkEndPath(C);
+ static void _checkEndFunction(void *checker,
+ CheckerContext &C) {
+ ((const CHECKER *)checker)->checkEndFunction(C);
}
public:
template <typename CHECKER>
static void _register(CHECKER *checker, CheckerManager &mgr) {
- mgr._registerForEndPath(
- CheckerManager::CheckEndPathFunc(checker, _checkEndPath<CHECKER>));
+ mgr._registerForEndFunction(
+ CheckerManager::CheckEndFunctionFunc(checker, _checkEndFunction<CHECKER>));
}
};
@@ -293,7 +293,7 @@ class RegionChanges {
static ProgramStateRef
_checkRegionChanges(void *checker,
ProgramStateRef state,
- const StoreManager::InvalidatedSymbols *invalidated,
+ const InvalidatedSymbols *invalidated,
ArrayRef<const MemRegion *> Explicits,
ArrayRef<const MemRegion *> Regions,
const CallEvent *Call) {
@@ -317,6 +317,59 @@ public:
}
};
+class PointerEscape {
+ template <typename CHECKER>
+ static ProgramStateRef
+ _checkPointerEscape(void *checker,
+ ProgramStateRef State,
+ const InvalidatedSymbols &Escaped,
+ const CallEvent *Call,
+ PointerEscapeKind Kind,
+ bool IsConst) {
+ if (!IsConst)
+ return ((const CHECKER *)checker)->checkPointerEscape(State,
+ Escaped,
+ Call,
+ Kind);
+ return State;
+ }
+
+public:
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr) {
+ mgr._registerForPointerEscape(
+ CheckerManager::CheckPointerEscapeFunc(checker,
+ _checkPointerEscape<CHECKER>));
+ }
+};
+
+class ConstPointerEscape {
+ template <typename CHECKER>
+ static ProgramStateRef
+ _checkConstPointerEscape(void *checker,
+ ProgramStateRef State,
+ const InvalidatedSymbols &Escaped,
+ const CallEvent *Call,
+ PointerEscapeKind Kind,
+ bool IsConst) {
+ if (IsConst)
+ return ((const CHECKER *)checker)->checkConstPointerEscape(State,
+ Escaped,
+ Call,
+ Kind);
+ return State;
+ }
+
+public:
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr) {
+ mgr._registerForPointerEscape(
+ CheckerManager::CheckPointerEscapeFunc(checker,
+ _checkConstPointerEscape<CHECKER>));
+ }
+};
+
+
template <typename EVENT>
class Event {
template <typename CHECKER>
@@ -448,6 +501,14 @@ struct ImplicitNullDerefEvent {
BugReporter *BR;
};
+/// \brief A helper class which wraps a boolean value set to false by default.
+struct DefaultBool {
+ bool val;
+ DefaultBool() : val(false) {}
+ operator bool() const { return val; }
+ DefaultBool &operator=(bool b) { val = b; return *this; }
+};
+
} // end ento namespace
} // end clang namespace
diff --git a/include/clang/StaticAnalyzer/Core/CheckerManager.h b/include/clang/StaticAnalyzer/Core/CheckerManager.h
index 7ae8e53784bf..6f99fc14577a 100644
--- a/include/clang/StaticAnalyzer/Core/CheckerManager.h
+++ b/include/clang/StaticAnalyzer/Core/CheckerManager.h
@@ -14,12 +14,12 @@
#ifndef LLVM_CLANG_SA_CORE_CHECKERMANAGER_H
#define LLVM_CLANG_SA_CORE_CHECKERMANAGER_H
+#include "clang/Analysis/ProgramPoint.h"
#include "clang/Basic/LangOptions.h"
-#include "llvm/ADT/SmallVector.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
-#include "clang/Analysis/ProgramPoint.h"
+#include "llvm/ADT/SmallVector.h"
#include <vector>
namespace clang {
@@ -112,6 +112,26 @@ public:
RET operator()() const { return Fn(Checker); }
};
+/// \brief Describes the different reasons a pointer escapes
+/// during analysis.
+enum PointerEscapeKind {
+ /// A pointer escapes due to binding its value to a location
+ /// that the analyzer cannot track.
+ PSK_EscapeOnBind,
+
+ /// The pointer has been passed to a function call directly.
+ PSK_DirectEscapeOnCall,
+
+ /// The pointer has been passed to a function indirectly.
+ /// For example, the pointer is accessible through an
+ /// argument to a function.
+ PSK_IndirectEscapeOnCall,
+
+ /// The reason for pointer escape is unknown. For example,
+ /// a region containing this pointer is invalidated.
+ PSK_EscapeOther
+};
+
class CheckerManager {
const LangOptions LangOpts;
@@ -264,11 +284,11 @@ public:
void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR,
ExprEngine &Eng);
- /// \brief Run checkers for end of path.
- void runCheckersForEndPath(NodeBuilderContext &BC,
- ExplodedNodeSet &Dst,
- ExplodedNode *Pred,
- ExprEngine &Eng);
+ /// \brief Run checkers on end of function.
+ void runCheckersForEndFunction(NodeBuilderContext &BC,
+ ExplodedNodeSet &Dst,
+ ExplodedNode *Pred,
+ ExprEngine &Eng);
/// \brief Run checkers for branch condition.
void runCheckersForBranchCondition(const Stmt *condition,
@@ -310,14 +330,34 @@ public:
/// by a call.
ProgramStateRef
runCheckersForRegionChanges(ProgramStateRef state,
- const StoreManager::InvalidatedSymbols *invalidated,
+ const InvalidatedSymbols *invalidated,
ArrayRef<const MemRegion *> ExplicitRegions,
ArrayRef<const MemRegion *> Regions,
const CallEvent *Call);
+ /// \brief Run checkers when pointers escape.
+ ///
+ /// This notifies the checkers about pointer escape, which occurs whenever
+ /// the analyzer cannot track the symbol any more. For example, as a
+ /// result of assigning a pointer into a global or when it's passed to a
+ /// function call the analyzer cannot model.
+ ///
+ /// \param State The state at the point of escape.
+ /// \param Escaped The list of escaped symbols.
+ /// \param Call The corresponding CallEvent, if the symbols escape as
+ /// parameters to the given call.
+ /// \param IsConst Specifies if the pointer is const.
+ /// \returns Checkers can modify the state by returning a new one.
+ ProgramStateRef
+ runCheckersForPointerEscape(ProgramStateRef State,
+ const InvalidatedSymbols &Escaped,
+ const CallEvent *Call,
+ PointerEscapeKind Kind,
+ bool IsConst = false);
+
/// \brief Run checkers for handling assumptions on symbolic values.
ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state,
- SVal Cond, bool Assumption);
+ SVal Cond, bool Assumption);
/// \brief Run checkers for evaluating a call.
///
@@ -382,7 +422,7 @@ public:
CheckEndAnalysisFunc;
typedef CheckerFn<void (CheckerContext &)>
- CheckEndPathFunc;
+ CheckEndFunctionFunc;
typedef CheckerFn<void (const Stmt *, CheckerContext &)>
CheckBranchConditionFunc;
@@ -393,13 +433,20 @@ public:
typedef CheckerFn<void (ProgramStateRef,SymbolReaper &)> CheckLiveSymbolsFunc;
typedef CheckerFn<ProgramStateRef (ProgramStateRef,
- const StoreManager::InvalidatedSymbols *symbols,
+ const InvalidatedSymbols *symbols,
ArrayRef<const MemRegion *> ExplicitRegions,
ArrayRef<const MemRegion *> Regions,
const CallEvent *Call)>
CheckRegionChangesFunc;
typedef CheckerFn<bool (ProgramStateRef)> WantsRegionChangeUpdateFunc;
+
+ typedef CheckerFn<ProgramStateRef (ProgramStateRef,
+ const InvalidatedSymbols &Escaped,
+ const CallEvent *Call,
+ PointerEscapeKind Kind,
+ bool IsConst)>
+ CheckPointerEscapeFunc;
typedef CheckerFn<ProgramStateRef (ProgramStateRef,
const SVal &cond, bool assumption)>
@@ -430,7 +477,7 @@ public:
void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn);
- void _registerForEndPath(CheckEndPathFunc checkfn);
+ void _registerForEndFunction(CheckEndFunctionFunc checkfn);
void _registerForBranchCondition(CheckBranchConditionFunc checkfn);
@@ -441,6 +488,10 @@ public:
void _registerForRegionChanges(CheckRegionChangesFunc checkfn,
WantsRegionChangeUpdateFunc wantUpdateFn);
+ void _registerForPointerEscape(CheckPointerEscapeFunc checkfn);
+
+ void _registerForConstPointerEscape(CheckPointerEscapeFunc checkfn);
+
void _registerForEvalAssume(EvalAssumeFunc checkfn);
void _registerForEvalCall(EvalCallFunc checkfn);
@@ -552,7 +603,7 @@ private:
std::vector<CheckEndAnalysisFunc> EndAnalysisCheckers;
- std::vector<CheckEndPathFunc> EndPathCheckers;
+ std::vector<CheckEndFunctionFunc> EndFunctionCheckers;
std::vector<CheckBranchConditionFunc> BranchConditionCheckers;
@@ -566,6 +617,8 @@ private:
};
std::vector<RegionChangesCheckerInfo> RegionChangesCheckers;
+ std::vector<CheckPointerEscapeFunc> PointerEscapeCheckers;
+
std::vector<EvalAssumeFunc> EvalAssumeCheckers;
std::vector<EvalCallFunc> EvalCallCheckers;
diff --git a/include/clang/StaticAnalyzer/Core/CheckerOptInfo.h b/include/clang/StaticAnalyzer/Core/CheckerOptInfo.h
index 6ce5b3c5095e..e981871ae4e0 100644
--- a/include/clang/StaticAnalyzer/Core/CheckerOptInfo.h
+++ b/include/clang/StaticAnalyzer/Core/CheckerOptInfo.h
@@ -11,6 +11,7 @@
#define LLVM_CLANG_STATICANALYZER_CORE_CHECKEROPTINFO_H
#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/StringRef.h"
namespace clang {
namespace ento {
diff --git a/include/clang/StaticAnalyzer/Core/CheckerRegistry.h b/include/clang/StaticAnalyzer/Core/CheckerRegistry.h
index 1452d45073aa..4557aa40ea80 100644
--- a/include/clang/StaticAnalyzer/Core/CheckerRegistry.h
+++ b/include/clang/StaticAnalyzer/Core/CheckerRegistry.h
@@ -10,8 +10,8 @@
#ifndef LLVM_CLANG_STATICANALYZER_CORE_CHECKERREGISTRY_H
#define LLVM_CLANG_STATICANALYZER_CORE_CHECKERREGISTRY_H
-#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/Basic/LLVM.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include <vector>
// FIXME: move this information to an HTML file in docs/.
diff --git a/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h b/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h
index 3aab648dc574..b856de7dc612 100644
--- a/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h
+++ b/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h
@@ -19,6 +19,7 @@
namespace clang {
+class AnalyzerOptions;
class Preprocessor;
namespace ento {
@@ -26,21 +27,18 @@ namespace ento {
class PathDiagnosticConsumer;
typedef std::vector<PathDiagnosticConsumer*> PathDiagnosticConsumers;
-void createHTMLDiagnosticConsumer(PathDiagnosticConsumers &C,
- const std::string& prefix,
- const Preprocessor &PP);
+#define CREATE_CONSUMER(NAME)\
+void create ## NAME ## DiagnosticConsumer(AnalyzerOptions &AnalyzerOpts,\
+ PathDiagnosticConsumers &C,\
+ const std::string& prefix,\
+ const Preprocessor &PP);
-void createPlistDiagnosticConsumer(PathDiagnosticConsumers &C,
- const std::string& prefix,
- const Preprocessor &PP);
+CREATE_CONSUMER(HTML)
+CREATE_CONSUMER(Plist)
+CREATE_CONSUMER(PlistMultiFile)
+CREATE_CONSUMER(TextPath)
-void createPlistMultiFileDiagnosticConsumer(PathDiagnosticConsumers &C,
- const std::string& prefix,
- const Preprocessor &PP);
-
-void createTextPathDiagnosticConsumer(PathDiagnosticConsumers &C,
- const std::string& prefix,
- const Preprocessor &PP);
+#undef CREATE_CONSUMER
} // end 'ento' namespace
} // end 'clang' namespace
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h b/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h
index 27f3677bba22..9502900f7e35 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h
@@ -81,9 +81,12 @@ public:
/// Tests whether a given value is losslessly representable using this type.
///
- /// Note that signedness conversions will be rejected, even with the same bit
- /// pattern. For example, -1s8 is not in range for 'unsigned char' (u8).
- RangeTestResultKind testInRange(const llvm::APSInt &Val) const LLVM_READONLY;
+ /// \param Val The value to test.
+ /// \param AllowMixedSign Whether or not to allow signedness conversions.
+ /// This determines whether -1s8 is considered in range
+ /// for 'unsigned char' (u8).
+ RangeTestResultKind testInRange(const llvm::APSInt &Val,
+ bool AllowMixedSign) const LLVM_READONLY;
bool operator==(const APSIntType &Other) const {
return BitWidth == Other.BitWidth && IsUnsigned == Other.IsUnsigned;
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
index 9038ae5276a7..458c8966e79e 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
@@ -100,7 +100,7 @@ public:
}
bool shouldInlineCall() const {
- return options.IPAMode != None;
+ return options.getIPAMode() != IPAK_None;
}
CFG *getCFG(Decl const *D) {
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h b/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
index fb393548b1af..1135b511441d 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
@@ -16,9 +16,10 @@
#ifndef LLVM_CLANG_GR_BASICVALUEFACTORY_H
#define LLVM_CLANG_GR_BASICVALUEFACTORY_H
+#include "clang/AST/ASTContext.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h"
namespace clang {
namespace ento {
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
index a6a91e2b66df..f990b8dcd0ec 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
@@ -16,11 +16,11 @@
#ifndef LLVM_CLANG_STATICANALYZER_PATHSENSITIVE_CALL
#define LLVM_CLANG_STATICANALYZER_PATHSENSITIVE_CALL
-#include "clang/Basic/SourceManager.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Basic/SourceManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
#include "llvm/ADT/PointerIntPair.h"
@@ -162,11 +162,11 @@ protected:
}
- typedef SmallVectorImpl<const MemRegion *> RegionList;
+ typedef SmallVectorImpl<SVal> ValueList;
/// \brief Used to specify non-argument regions that will be invalidated as a
/// result of this call.
- virtual void getExtraInvalidatedRegions(RegionList &Regions) const {}
+ virtual void getExtraInvalidatedValues(ValueList &Values) const {}
public:
virtual ~CallEvent() {}
@@ -181,7 +181,7 @@ public:
}
/// \brief The state in which the call is being evaluated.
- ProgramStateRef getState() const {
+ const ProgramStateRef &getState() const {
return State;
}
@@ -228,6 +228,11 @@ public:
return false;
}
+ /// \brief Returns true if this is a call to a variadic function or method.
+ virtual bool isVariadic() const {
+ return false;
+ }
+
/// \brief Returns a source range for the entire call, suitable for
/// outputting in diagnostics.
virtual SourceRange getSourceRange() const {
@@ -331,7 +336,9 @@ public:
/// of some kind.
static bool isCallStmt(const Stmt *S);
- /// \brief Returns the result type of a function, method declaration.
+ /// \brief Returns the result type of a function or method declaration.
+ ///
+ /// This will return a null QualType if the result type cannot be determined.
static QualType getDeclaredResultType(const Decl *D);
// Iterator access to formal parameters and their types.
@@ -416,6 +423,10 @@ public:
return RuntimeDefinition();
}
+ virtual bool isVariadic() const {
+ return getDecl()->isVariadic();
+ }
+
virtual bool argumentsMayEscape() const;
virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
@@ -493,7 +504,7 @@ protected:
BlockCall(const BlockCall &Other) : SimpleCall(Other) {}
virtual void cloneTo(void *Dest) const { new (Dest) BlockCall(*this); }
- virtual void getExtraInvalidatedRegions(RegionList &Regions) const;
+ virtual void getExtraInvalidatedValues(ValueList &Values) const;
public:
/// \brief Returns the region associated with this instance of the block.
@@ -516,6 +527,10 @@ public:
return RuntimeDefinition(getBlockDecl());
}
+ virtual bool isVariadic() const {
+ return getBlockDecl()->isVariadic();
+ }
+
virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
BindingsTy &Bindings) const;
@@ -533,7 +548,7 @@ public:
/// it is written.
class CXXInstanceCall : public AnyFunctionCall {
protected:
- virtual void getExtraInvalidatedRegions(RegionList &Regions) const;
+ virtual void getExtraInvalidatedValues(ValueList &Values) const;
CXXInstanceCall(const CallExpr *CE, ProgramStateRef St,
const LocationContext *LCtx)
@@ -716,7 +731,7 @@ protected:
CXXConstructorCall(const CXXConstructorCall &Other) : AnyFunctionCall(Other){}
virtual void cloneTo(void *Dest) const { new (Dest) CXXConstructorCall(*this); }
- virtual void getExtraInvalidatedRegions(RegionList &Regions) const;
+ virtual void getExtraInvalidatedValues(ValueList &Values) const;
public:
virtual const CXXConstructExpr *getOriginExpr() const {
@@ -815,7 +830,7 @@ protected:
ObjCMethodCall(const ObjCMethodCall &Other) : CallEvent(Other) {}
virtual void cloneTo(void *Dest) const { new (Dest) ObjCMethodCall(*this); }
- virtual void getExtraInvalidatedRegions(RegionList &Regions) const;
+ virtual void getExtraInvalidatedValues(ValueList &Values) const;
/// Check if the selector may have multiple definitions (may have overrides).
virtual bool canBeOverridenInSubclass(ObjCInterfaceDecl *IDecl,
@@ -834,6 +849,9 @@ public:
virtual const Expr *getArgExpr(unsigned Index) const {
return getOriginExpr()->getArg(Index);
}
+ virtual bool isVariadic() const {
+ return getDecl()->isVariadic();
+ }
bool isInstanceMessage() const {
return getOriginExpr()->isInstanceMessage();
@@ -1024,7 +1042,7 @@ namespace llvm {
typedef const T *SimpleType;
static SimpleType
- getSimplifiedValue(const clang::ento::CallEventRef<T>& Val) {
+ getSimplifiedValue(clang::ento::CallEventRef<T> Val) {
return Val.getPtr();
}
};
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
index 4558cd9c9480..cda1366a4399 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
@@ -119,7 +119,7 @@ public:
/// the state of the program before the checker ran. Note, checkers should
/// not retain the node in their state since the nodes might get invalidated.
ExplodedNode *getPredecessor() { return Pred; }
- ProgramStateRef getState() const { return Pred->getState(); }
+ const ProgramStateRef &getState() const { return Pred->getState(); }
/// \brief Check if the checker changed the state of the execution; ex: added
/// a new transition or a bug report.
@@ -185,7 +185,7 @@ public:
/// example, for finding variables that the given symbol was assigned to.
static const MemRegion *getLocationRegionIfPostStore(const ExplodedNode *N) {
ProgramPoint L = N->getLocation();
- if (const PostStore *PSL = dyn_cast<PostStore>(&L))
+ if (Optional<PostStore> PSL = L.getAs<PostStore>())
return reinterpret_cast<const MemRegion*>(PSL->getLocationValue());
return 0;
}
@@ -303,14 +303,6 @@ private:
}
};
-/// \brief A helper class which wraps a boolean value set to false by default.
-struct DefaultBool {
- bool Val;
- DefaultBool() : Val(false) {}
- operator bool() const { return Val; }
- DefaultBool &operator=(bool b) { Val = b; return *this; }
-};
-
} // end GR namespace
} // end clang namespace
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
index 4a78849024ae..1e76ea6ed647 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
@@ -14,8 +14,8 @@
#ifndef LLVM_CLANG_GR_CONSTRAINT_MANAGER_H
#define LLVM_CLANG_GR_CONSTRAINT_MANAGER_H
-#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
#include "llvm/Support/SaveAndRestore.h"
namespace llvm {
@@ -28,7 +28,7 @@ namespace ento {
class SubEngine;
class ConditionTruthVal {
- llvm::Optional<bool> Val;
+ Optional<bool> Val;
public:
/// Construct a ConditionTruthVal indicating the constraint is constrained
/// to either true or false, depending on the boolean value provided.
@@ -78,9 +78,13 @@ public:
// If StTrue is infeasible, asserting the falseness of Cond is unnecessary
// because the existing constraints already establish this.
if (!StTrue) {
- // FIXME: This is fairly expensive and should be disabled even in
- // Release+Asserts builds.
+#ifndef __OPTIMIZE__
+ // This check is expensive and should be disabled even in Release+Asserts
+ // builds.
+ // FIXME: __OPTIMIZE__ is a GNU extension that Clang implements but MSVC
+ // does not. Is there a good equivalent there?
assert(assume(State, Cond, false) && "System is over constrained.");
+#endif
return ProgramStatePair((ProgramStateRef)NULL, State);
}
@@ -118,7 +122,7 @@ public:
/// Convenience method to query the state to see if a symbol is null or
/// not null, or if neither assumption can be made.
ConditionTruthVal isNull(ProgramStateRef State, SymbolRef Sym) {
- llvm::SaveAndRestore<bool> DisableNotify(NotifyAssumeClients, false);
+ SaveAndRestore<bool> DisableNotify(NotifyAssumeClients, false);
return checkNull(State, Sym);
}
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
index b6686409e5aa..a2e211edea8b 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
@@ -17,10 +17,10 @@
#include "clang/AST/Expr.h"
#include "clang/Analysis/AnalysisContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/WorkList.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h"
#include "llvm/ADT/OwningPtr.h"
namespace clang {
@@ -96,6 +96,10 @@ private:
void HandleBranch(const Stmt *Cond, const Stmt *Term, const CFGBlock *B,
ExplodedNode *Pred);
+ /// Handle conditional logic for running static initializers.
+ void HandleStaticInit(const DeclStmt *DS, const CFGBlock *B,
+ ExplodedNode *Pred);
+
private:
CoreEngine(const CoreEngine &) LLVM_DELETED_FUNCTION;
void operator=(const CoreEngine &) LLVM_DELETED_FUNCTION;
@@ -463,7 +467,7 @@ public:
bool operator!=(const iterator &X) const { return I != X.I; }
const LabelDecl *getLabel() const {
- return llvm::cast<LabelStmt>((*I)->getLabel())->getDecl();
+ return cast<LabelStmt>((*I)->getLabel())->getDecl();
}
const CFGBlock *getBlock() const {
@@ -510,7 +514,7 @@ public:
bool operator==(const iterator &X) const { return I == X.I; }
const CaseStmt *getCase() const {
- return llvm::cast<CaseStmt>((*I)->getLabel());
+ return cast<CaseStmt>((*I)->getLabel());
}
const CFGBlock *getBlock() const {
@@ -522,7 +526,7 @@ public:
iterator end() { return iterator(Src->succ_rend()); }
const SwitchStmt *getSwitch() const {
- return llvm::cast<SwitchStmt>(Src->getTerminator());
+ return cast<SwitchStmt>(Src->getTerminator());
}
ExplodedNode *generateCaseStmtNode(const iterator &I,
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
index eb9bd85fe64d..f3a582da040f 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
@@ -33,9 +33,6 @@ class SValBuilder;
/// other things.
class EnvironmentEntry : public std::pair<const Stmt*,
const StackFrameContext *> {
- friend class EnvironmentManager;
- EnvironmentEntry makeLocation() const;
-
public:
EnvironmentEntry(const Stmt *s, const LocationContext *L);
@@ -118,13 +115,6 @@ public:
/// Bind a symbolic value to the given environment entry.
Environment bindExpr(Environment Env, const EnvironmentEntry &E, SVal V,
bool Invalidate);
-
- /// Bind the location 'location' and value 'V' to the specified
- /// environment entry.
- Environment bindExprAndLocation(Environment Env,
- const EnvironmentEntry &E,
- SVal location,
- SVal V);
Environment removeDeadBindings(Environment Env,
SymbolReaper &SymReaper,
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
index b112e66d30d3..5211916407c8 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
@@ -19,19 +19,19 @@
#ifndef LLVM_CLANG_GR_EXPLODEDGRAPH
#define LLVM_CLANG_GR_EXPLODEDGRAPH
-#include "clang/Analysis/ProgramPoint.h"
-#include "clang/Analysis/AnalysisContext.h"
#include "clang/AST/Decl.h"
-#include "llvm/ADT/SmallVector.h"
+#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/ProgramPoint.h"
+#include "clang/Analysis/Support/BumpVector.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Allocator.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/ADT/GraphTraits.h"
-#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/Support/Casting.h"
-#include "clang/Analysis/Support/BumpVector.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
#include <vector>
namespace clang {
@@ -152,10 +152,12 @@ public:
return *getLocationContext()->getAnalysis<T>();
}
- ProgramStateRef getState() const { return State; }
+ const ProgramStateRef &getState() const { return State; }
template <typename T>
- const T* getLocationAs() const { return llvm::dyn_cast<T>(&Location); }
+ Optional<T> getLocationAs() const LLVM_LVALUE_FUNCTION {
+ return Location.getAs<T>();
+ }
static void Profile(llvm::FoldingSetNodeID &ID,
const ProgramPoint &Loc,
@@ -167,7 +169,8 @@ public:
}
void Profile(llvm::FoldingSetNodeID& ID) const {
- Profile(ID, getLocation(), getState(), isSink());
+ // We avoid copy constructors by not using accessors.
+ Profile(ID, Location, State, isSink());
}
/// addPredeccessor - Adds a predecessor to the current node, and
@@ -236,18 +239,8 @@ private:
void replacePredecessor(ExplodedNode *node) { Preds.replaceNode(node); }
};
-// FIXME: Is this class necessary?
-class InterExplodedGraphMap {
- virtual void anchor();
- llvm::DenseMap<const ExplodedNode*, ExplodedNode*> M;
- friend class ExplodedGraph;
-
-public:
- ExplodedNode *getMappedNode(const ExplodedNode *N) const;
-
- InterExplodedGraphMap() {}
- virtual ~InterExplodedGraphMap() {}
-};
+typedef llvm::DenseMap<const ExplodedNode *, const ExplodedNode *>
+ InterExplodedGraphMap;
class ExplodedGraph {
protected:
@@ -365,14 +358,19 @@ public:
typedef llvm::DenseMap<const ExplodedNode*, ExplodedNode*> NodeMap;
- std::pair<ExplodedGraph*, InterExplodedGraphMap*>
- Trim(const NodeTy* const* NBeg, const NodeTy* const* NEnd,
- llvm::DenseMap<const void*, const void*> *InverseMap = 0) const;
-
- ExplodedGraph* TrimInternal(const ExplodedNode* const * NBeg,
- const ExplodedNode* const * NEnd,
- InterExplodedGraphMap *M,
- llvm::DenseMap<const void*, const void*> *InverseMap) const;
+ /// Creates a trimmed version of the graph that only contains paths leading
+ /// to the given nodes.
+ ///
+ /// \param Nodes The nodes which must appear in the final graph. Presumably
+ /// these are end-of-path nodes (i.e. they have no successors).
+ /// \param[out] ForwardMap A optional map from nodes in this graph to nodes in
+ /// the returned graph.
+ /// \param[out] InverseMap An optional map from nodes in the returned graph to
+ /// nodes in this graph.
+ /// \returns The trimmed graph
+ ExplodedGraph *trim(ArrayRef<const NodeTy *> Nodes,
+ InterExplodedGraphMap *ForwardMap = 0,
+ InterExplodedGraphMap *InverseMap = 0) const;
/// Enable tracking of recently allocated nodes for potential reclamation
/// when calling reclaimRecentlyAllocatedNodes().
@@ -384,6 +382,10 @@ public:
/// was called.
void reclaimRecentlyAllocatedNodes();
+ /// \brief Returns true if nodes for the given expression kind are always
+ /// kept around.
+ static bool isInterestingLValueExpr(const Expr *Ex);
+
private:
bool shouldCollect(const ExplodedNode *node);
void collectNode(ExplodedNode *node);
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
index 78b254222e9e..33e4431eb4be 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -16,15 +16,15 @@
#ifndef LLVM_CLANG_GR_EXPRENGINE
#define LLVM_CLANG_GR_EXPRENGINE
+#include "clang/AST/Expr.h"
+#include "clang/AST/Type.h"
#include "clang/Analysis/DomainSpecific/ObjCNoReturn.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
-#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/Type.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h"
namespace clang {
@@ -44,8 +44,19 @@ namespace ento {
class AnalysisManager;
class CallEvent;
class SimpleCall;
+class CXXConstructorCall;
class ExprEngine : public SubEngine {
+public:
+ /// The modes of inlining, which override the default analysis-wide settings.
+ enum InliningModes {
+ /// Follow the default settings for inlining callees.
+ Inline_Regular = 0,
+ /// Do minimal inlining of callees.
+ Inline_Minimal = 0x1
+ };
+
+private:
AnalysisManager &AMgr;
AnalysisDeclContextManager &AnalysisDeclContexts;
@@ -64,15 +75,6 @@ class ExprEngine : public SubEngine {
/// svalBuilder - SValBuilder object that creates SVals from expressions.
SValBuilder &svalBuilder;
- /// EntryNode - The immediate predecessor node.
- ExplodedNode *EntryNode;
-
- /// CleanedState - The state for EntryNode "cleaned" of all dead
- /// variables and symbols (as determined by a liveness analysis).
- ProgramStateRef CleanedState;
-
- /// currStmt - The current block-level statement.
- const Stmt *currStmt;
unsigned int currStmtIdx;
const NodeBuilderContext *currBldrCtx;
@@ -92,10 +94,14 @@ class ExprEngine : public SubEngine {
/// AnalysisConsumer. It can be null.
SetOfConstDecls *VisitedCallees;
+ /// The flag, which specifies the mode of inlining for the engine.
+ InliningModes HowToInline;
+
public:
ExprEngine(AnalysisManager &mgr, bool gcEnabled,
SetOfConstDecls *VisitedCalleesIn,
- FunctionSummariesTy *FS);
+ FunctionSummariesTy *FS,
+ InliningModes HowToInlineIn);
~ExprEngine();
@@ -140,11 +146,12 @@ public:
void enqueueEndOfPath(ExplodedNodeSet &S);
void GenerateCallExitNode(ExplodedNode *N);
- /// ViewGraph - Visualize the ExplodedGraph created by executing the
- /// simulation.
+ /// Visualize the ExplodedGraph created by executing the simulation.
void ViewGraph(bool trim = false);
- void ViewGraph(ExplodedNode** Beg, ExplodedNode** End);
+ /// Visualize a trimmed ExplodedGraph that only contains paths to the given
+ /// nodes.
+ void ViewGraph(ArrayRef<const ExplodedNode*> Nodes);
/// getInitialState - Return the initial state used for the root vertex
/// in the ExplodedGraph.
@@ -154,26 +161,33 @@ public:
const ExplodedGraph& getGraph() const { return G; }
/// \brief Run the analyzer's garbage collection - remove dead symbols and
- /// bindings.
+ /// bindings from the state.
///
- /// \param Node - The predecessor node, from which the processing should
- /// start.
- /// \param Out - The returned set of output nodes.
- /// \param ReferenceStmt - Run garbage collection using the symbols,
- /// which are live before the given statement.
- /// \param LC - The location context of the ReferenceStmt.
- /// \param DiagnosticStmt - the statement used to associate the diagnostic
- /// message, if any warnings should occur while removing the dead (leaks
- /// are usually reported here).
- /// \param K - In some cases it is possible to use PreStmt kind. (Do
- /// not use it unless you know what you are doing.)
- /// If the ReferenceStmt is NULL, everything is this and parent contexts is
- /// considered live.
- /// If the stack frame context is NULL, everything on stack is considered
- /// dead.
+ /// Checkers can participate in this process with two callbacks:
+ /// \c checkLiveSymbols and \c checkDeadSymbols. See the CheckerDocumentation
+ /// class for more information.
+ ///
+ /// \param Node The predecessor node, from which the processing should start.
+ /// \param Out The returned set of output nodes.
+ /// \param ReferenceStmt The statement which is about to be processed.
+ /// Everything needed for this statement should be considered live.
+ /// A null statement means that everything in child LocationContexts
+ /// is dead.
+ /// \param LC The location context of the \p ReferenceStmt. A null location
+ /// context means that we have reached the end of analysis and that
+ /// all statements and local variables should be considered dead.
+ /// \param DiagnosticStmt Used as a location for any warnings that should
+ /// occur while removing the dead (e.g. leaks). By default, the
+ /// \p ReferenceStmt is used.
+ /// \param K Denotes whether this is a pre- or post-statement purge. This
+ /// must only be ProgramPoint::PostStmtPurgeDeadSymbolsKind if an
+ /// entire location context is being cleared, in which case the
+ /// \p ReferenceStmt must either be a ReturnStmt or \c NULL. Otherwise,
+ /// it must be ProgramPoint::PreStmtPurgeDeadSymbolsKind (the default)
+ /// and \p ReferenceStmt must be valid (non-null).
void removeDead(ExplodedNode *Node, ExplodedNodeSet &Out,
- const Stmt *ReferenceStmt, const StackFrameContext *LC,
- const Stmt *DiagnosticStmt,
+ const Stmt *ReferenceStmt, const LocationContext *LC,
+ const Stmt *DiagnosticStmt = 0,
ProgramPoint::Kind K = ProgramPoint::PreStmtPurgeDeadSymbolsKind);
/// processCFGElement - Called by CoreEngine. Used to generate new successor
@@ -210,6 +224,15 @@ public:
const CFGBlock *DstT,
const CFGBlock *DstF);
+ /// Called by CoreEngine. Used to processing branching behavior
+ /// at static initalizers.
+ void processStaticInitializer(const DeclStmt *DS,
+ NodeBuilderContext& BuilderCtx,
+ ExplodedNode *Pred,
+ ExplodedNodeSet &Dst,
+ const CFGBlock *DstT,
+ const CFGBlock *DstF);
+
/// processIndirectGoto - Called by CoreEngine. Used to generate successor
/// nodes by processing the 'effects' of a computed goto jump.
void processIndirectGoto(IndirectGotoNodeBuilder& builder);
@@ -218,8 +241,8 @@ public:
/// nodes by processing the 'effects' of a switch statement.
void processSwitch(SwitchNodeBuilder& builder);
- /// ProcessEndPath - Called by CoreEngine. Used to generate end-of-path
- /// nodes when the control reaches the end of a function.
+ /// Called by CoreEngine. Used to generate end-of-path
+ /// nodes when the control reaches the end of a function.
void processEndOfFunction(NodeBuilderContext& BC,
ExplodedNode *Pred);
@@ -250,7 +273,7 @@ public:
/// to the store. Used to update checkers that track region values.
ProgramStateRef
processRegionChanges(ProgramStateRef state,
- const StoreManager::InvalidatedSymbols *invalidated,
+ const InvalidatedSymbols *invalidated,
ArrayRef<const MemRegion *> ExplicitRegions,
ArrayRef<const MemRegion *> Regions,
const CallEvent *Call);
@@ -416,11 +439,11 @@ public:
geteagerlyAssumeBinOpBifurcationTags();
SVal evalMinus(SVal X) {
- return X.isValid() ? svalBuilder.evalMinus(cast<NonLoc>(X)) : X;
+ return X.isValid() ? svalBuilder.evalMinus(X.castAs<NonLoc>()) : X;
}
SVal evalComplement(SVal X) {
- return X.isValid() ? svalBuilder.evalComplement(cast<NonLoc>(X)) : X;
+ return X.isValid() ? svalBuilder.evalComplement(X.castAs<NonLoc>()) : X;
}
public:
@@ -432,7 +455,8 @@ public:
SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op,
NonLoc L, SVal R, QualType T) {
- return R.isValid() ? svalBuilder.evalBinOpNN(state,op,L, cast<NonLoc>(R), T) : R;
+ return R.isValid() ? svalBuilder.evalBinOpNN(state, op, L,
+ R.castAs<NonLoc>(), T) : R;
}
SVal evalBinOp(ProgramStateRef ST, BinaryOperator::Opcode Op,
@@ -447,6 +471,20 @@ protected:
SVal location, SVal Val, bool atDeclInit = false,
const ProgramPoint *PP = 0);
+ /// Call PointerEscape callback when a value escapes as a result of bind.
+ ProgramStateRef processPointerEscapedOnBind(ProgramStateRef State,
+ SVal Loc, SVal Val);
+ /// Call PointerEscape callback when a value escapes as a result of
+ /// region invalidation.
+ /// \param[in] IsConst Specifies that the pointer is const.
+ ProgramStateRef notifyCheckersOfPointerEscape(
+ ProgramStateRef State,
+ const InvalidatedSymbols *Invalidated,
+ ArrayRef<const MemRegion *> ExplicitRegions,
+ ArrayRef<const MemRegion *> Regions,
+ const CallEvent *Call,
+ bool IsConst);
+
public:
// FIXME: 'tag' should be removed, and a LocationContext should be used
// instead.
@@ -506,7 +544,10 @@ private:
void examineStackFrames(const Decl *D, const LocationContext *LCtx,
bool &IsRecursive, unsigned &StackDepth);
- bool shouldInlineDecl(const Decl *D, ExplodedNode *Pred);
+ /// Checks our policies and decides weither the given call should be inlined.
+ bool shouldInlineCall(const CallEvent &Call, const Decl *D,
+ const ExplodedNode *Pred);
+
bool inlineCall(const CallEvent &Call, const Decl *D, NodeBuilder &Bldr,
ExplodedNode *Pred, ProgramStateRef State);
@@ -522,6 +563,22 @@ private:
ExplodedNode *Pred);
bool replayWithoutInlining(ExplodedNode *P, const LocationContext *CalleeLC);
+
+ /// Models a trivial copy or move constructor or trivial assignment operator
+ /// call with a simple bind.
+ void performTrivialCopy(NodeBuilder &Bldr, ExplodedNode *Pred,
+ const CallEvent &Call);
+
+ /// If the value of the given expression is a NonLoc, copy it into a new
+ /// temporary object region, and replace the value of the expression with
+ /// that.
+ ///
+ /// If \p ResultE is provided, the new region will be bound to this expression
+ /// instead of \p E.
+ ProgramStateRef createTemporaryRegionIfNeeded(ProgramStateRef State,
+ const LocationContext *LC,
+ const Expr *E,
+ const Expr *ResultE = 0);
};
/// Traits for storing the call processing policy inside GDM.
@@ -531,7 +588,7 @@ private:
struct ReplayWithoutInlining{};
template <>
struct ProgramStateTrait<ReplayWithoutInlining> :
- public ProgramStatePartialTrait<void*> {
+ public ProgramStatePartialTrait<const void*> {
static void *GDMIndex() { static int index = 0; return &index; }
};
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h b/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h
index cf4a6929a3aa..169af939f08e 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h
@@ -7,94 +7,126 @@
//
//===----------------------------------------------------------------------===//
//
-// This file defines a summary of a function gathered/used by static analyzes.
+// This file defines a summary of a function gathered/used by static analysis.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_GR_FUNCTIONSUMMARY_H
#define LLVM_CLANG_GR_FUNCTIONSUMMARY_H
-#include <deque>
-#include "clang/AST/Decl.h"
+#include "clang/Basic/LLVM.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallBitVector.h"
+#include <deque>
namespace clang {
+class Decl;
+
namespace ento {
typedef std::deque<Decl*> SetOfDecls;
typedef llvm::DenseSet<const Decl*> SetOfConstDecls;
class FunctionSummariesTy {
- struct FunctionSummary {
- /// True if this function has reached a max block count while inlined from
- /// at least one call site.
- bool MayReachMaxBlockCount;
+ class FunctionSummary {
+ public:
+ /// Marks the IDs of the basic blocks visited during the analyzes.
+ llvm::SmallBitVector VisitedBasicBlocks;
/// Total number of blocks in the function.
- unsigned TotalBasicBlocks;
+ unsigned TotalBasicBlocks : 30;
- /// Marks the IDs of the basic blocks visited during the analyzes.
- llvm::BitVector VisitedBasicBlocks;
+ /// True if this function has been checked against the rules for which
+ /// functions may be inlined.
+ unsigned InlineChecked : 1;
+
+ /// True if this function may be inlined.
+ unsigned MayInline : 1;
+
+ /// The number of times the function has been inlined.
+ unsigned TimesInlined : 32;
FunctionSummary() :
- MayReachMaxBlockCount(false),
TotalBasicBlocks(0),
- VisitedBasicBlocks(0) {}
+ InlineChecked(0),
+ TimesInlined(0) {}
};
- typedef llvm::DenseMap<const Decl*, FunctionSummary*> MapTy;
+ typedef llvm::DenseMap<const Decl *, FunctionSummary> MapTy;
MapTy Map;
public:
- ~FunctionSummariesTy();
-
MapTy::iterator findOrInsertSummary(const Decl *D) {
MapTy::iterator I = Map.find(D);
if (I != Map.end())
return I;
- FunctionSummary *DS = new FunctionSummary();
- I = Map.insert(std::pair<const Decl*, FunctionSummary*>(D, DS)).first;
+
+ typedef std::pair<const Decl *, FunctionSummary> KVPair;
+ I = Map.insert(KVPair(D, FunctionSummary())).first;
assert(I != Map.end());
return I;
}
- void markReachedMaxBlockCount(const Decl* D) {
+ void markMayInline(const Decl *D) {
MapTy::iterator I = findOrInsertSummary(D);
- I->second->MayReachMaxBlockCount = true;
+ I->second.InlineChecked = 1;
+ I->second.MayInline = 1;
}
- bool hasReachedMaxBlockCount(const Decl* D) {
- MapTy::const_iterator I = Map.find(D);
- if (I != Map.end())
- return I->second->MayReachMaxBlockCount;
- return false;
+ void markShouldNotInline(const Decl *D) {
+ MapTy::iterator I = findOrInsertSummary(D);
+ I->second.InlineChecked = 1;
+ I->second.MayInline = 0;
+ }
+
+ void markReachedMaxBlockCount(const Decl *D) {
+ markShouldNotInline(D);
+ }
+
+ Optional<bool> mayInline(const Decl *D) {
+ MapTy::const_iterator I = Map.find(D);
+ if (I != Map.end() && I->second.InlineChecked)
+ return I->second.MayInline;
+ return None;
}
void markVisitedBasicBlock(unsigned ID, const Decl* D, unsigned TotalIDs) {
MapTy::iterator I = findOrInsertSummary(D);
- llvm::BitVector &Blocks = I->second->VisitedBasicBlocks;
+ llvm::SmallBitVector &Blocks = I->second.VisitedBasicBlocks;
assert(ID < TotalIDs);
if (TotalIDs > Blocks.size()) {
Blocks.resize(TotalIDs);
- I->second->TotalBasicBlocks = TotalIDs;
+ I->second.TotalBasicBlocks = TotalIDs;
}
- Blocks[ID] = true;
+ Blocks.set(ID);
}
unsigned getNumVisitedBasicBlocks(const Decl* D) {
MapTy::const_iterator I = Map.find(D);
- if (I != Map.end())
- return I->second->VisitedBasicBlocks.count();
+ if (I != Map.end())
+ return I->second.VisitedBasicBlocks.count();
return 0;
}
+ unsigned getNumTimesInlined(const Decl* D) {
+ MapTy::const_iterator I = Map.find(D);
+ if (I != Map.end())
+ return I->second.TimesInlined;
+ return 0;
+ }
+
+ void bumpNumTimesInlined(const Decl* D) {
+ MapTy::iterator I = findOrInsertSummary(D);
+ I->second.TimesInlined++;
+ }
+
/// Get the percentage of the reachable blocks.
unsigned getPercentBlocksReachable(const Decl *D) {
MapTy::const_iterator I = Map.find(D);
if (I != Map.end())
- return ((I->second->VisitedBasicBlocks.count() * 100) /
- I->second->TotalBasicBlocks);
+ return ((I->second.VisitedBasicBlocks.count() * 100) /
+ I->second.TotalBasicBlocks);
return 0;
}
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
index 34fbc3ca9e83..af2f365ead96 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
@@ -22,8 +22,8 @@
#include "clang/AST/ExprObjC.h"
#include "clang/Basic/LLVM.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
-#include "llvm/Support/ErrorHandling.h"
#include "llvm/ADT/FoldingSet.h"
+#include "llvm/Support/ErrorHandling.h"
#include <string>
namespace llvm {
@@ -642,26 +642,20 @@ public:
explicit referenced_vars_iterator(const MemRegion * const *r,
const MemRegion * const *originalR)
: R(r), OriginalR(originalR) {}
-
- operator const MemRegion * const *() const {
- return R;
- }
-
- const MemRegion *getCapturedRegion() const {
- return *R;
- }
- const MemRegion *getOriginalRegion() const {
- return *OriginalR;
- }
- const VarRegion* operator*() const {
+ const VarRegion *getCapturedRegion() const {
return cast<VarRegion>(*R);
}
-
+ const VarRegion *getOriginalRegion() const {
+ return cast<VarRegion>(*OriginalR);
+ }
+
bool operator==(const referenced_vars_iterator &I) const {
+ assert((R == 0) == (I.R == 0));
return I.R == R;
}
bool operator!=(const referenced_vars_iterator &I) const {
+ assert((R == 0) == (I.R == 0));
return I.R != R;
}
referenced_vars_iterator &operator++() {
@@ -670,6 +664,10 @@ public:
return *this;
}
};
+
+ /// Return the original region for a captured region, if
+ /// one exists.
+ const VarRegion *getOriginalRegion(const VarRegion *VR) const;
referenced_vars_iterator referenced_vars_begin() const;
referenced_vars_iterator referenced_vars_end() const;
@@ -686,6 +684,8 @@ public:
}
private:
void LazyInitializeReferencedVars();
+ std::pair<const VarRegion *, const VarRegion *>
+ getCaptureRegions(const VarDecl *VD);
};
/// SymbolicRegion - A special, "non-concrete" region. Unlike other region
@@ -952,6 +952,9 @@ public:
const ObjCIvarDecl *getDecl() const;
QualType getValueType() const;
+ bool canPrintPretty() const;
+ void printPretty(raw_ostream &os) const;
+
void dumpToStream(raw_ostream &os) const;
static bool classof(const MemRegion* R) {
@@ -993,8 +996,8 @@ class ElementRegion : public TypedValueRegion {
ElementRegion(QualType elementType, NonLoc Idx, const MemRegion* sReg)
: TypedValueRegion(sReg, ElementRegionKind),
ElementType(elementType), Index(Idx) {
- assert((!isa<nonloc::ConcreteInt>(&Idx) ||
- cast<nonloc::ConcreteInt>(&Idx)->getValue().isSigned()) &&
+ assert((!Idx.getAs<nonloc::ConcreteInt>() ||
+ Idx.castAs<nonloc::ConcreteInt>().getValue().isSigned()) &&
"The index must be signed");
}
@@ -1057,16 +1060,18 @@ public:
class CXXBaseObjectRegion : public TypedValueRegion {
friend class MemRegionManager;
- const CXXRecordDecl *decl;
+ llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> Data;
- CXXBaseObjectRegion(const CXXRecordDecl *d, const MemRegion *sReg)
- : TypedValueRegion(sReg, CXXBaseObjectRegionKind), decl(d) {}
+ CXXBaseObjectRegion(const CXXRecordDecl *RD, bool IsVirtual,
+ const MemRegion *SReg)
+ : TypedValueRegion(SReg, CXXBaseObjectRegionKind), Data(RD, IsVirtual) {}
- static void ProfileRegion(llvm::FoldingSetNodeID &ID,
- const CXXRecordDecl *decl, const MemRegion *sReg);
+ static void ProfileRegion(llvm::FoldingSetNodeID &ID, const CXXRecordDecl *RD,
+ bool IsVirtual, const MemRegion *SReg);
public:
- const CXXRecordDecl *getDecl() const { return decl; }
+ const CXXRecordDecl *getDecl() const { return Data.getPointer(); }
+ bool isVirtual() const { return Data.getInt(); }
QualType getValueType() const;
@@ -1216,15 +1221,21 @@ public:
const CXXTempObjectRegion *getCXXTempObjectRegion(Expr const *Ex,
LocationContext const *LC);
- const CXXBaseObjectRegion *getCXXBaseObjectRegion(const CXXRecordDecl *decl,
- const MemRegion *superRegion);
+ /// Create a CXXBaseObjectRegion with the given base class for region
+ /// \p Super.
+ ///
+ /// The type of \p Super is assumed be a class deriving from \p BaseClass.
+ const CXXBaseObjectRegion *
+ getCXXBaseObjectRegion(const CXXRecordDecl *BaseClass, const MemRegion *Super,
+ bool IsVirtual);
/// Create a CXXBaseObjectRegion with the same CXXRecordDecl but a different
/// super region.
const CXXBaseObjectRegion *
getCXXBaseObjectRegionWithSuper(const CXXBaseObjectRegion *baseReg,
const MemRegion *superRegion) {
- return getCXXBaseObjectRegion(baseReg->getDecl(), superRegion);
+ return getCXXBaseObjectRegion(baseReg->getDecl(), superRegion,
+ baseReg->isVirtual());
}
const FunctionTextRegion *getFunctionTextRegion(const NamedDecl *FD);
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
index 86c94deab5e8..6ea7211090ba 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
@@ -18,13 +18,13 @@
#include "clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/Environment.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h"
-#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/ImmutableMap.h"
+#include "llvm/ADT/PointerIntPair.h"
namespace llvm {
class APSInt;
@@ -170,19 +170,30 @@ public:
// If no new state is feasible, NULL is returned.
//
+ /// Assumes that the value of \p cond is zero (if \p assumption is "false")
+ /// or non-zero (if \p assumption is "true").
+ ///
+ /// This returns a new state with the added constraint on \p cond.
+ /// If no new state is feasible, NULL is returned.
ProgramStateRef assume(DefinedOrUnknownSVal cond, bool assumption) const;
- /// This method assumes both "true" and "false" for 'cond', and
- /// returns both corresponding states. It's shorthand for doing
- /// 'assume' twice.
- std::pair<ProgramStateRef , ProgramStateRef >
+ /// Assumes both "true" and "false" for \p cond, and returns both
+ /// corresponding states (respectively).
+ ///
+ /// This is more efficient than calling assume() twice. Note that one (but not
+ /// both) of the returned states may be NULL.
+ std::pair<ProgramStateRef, ProgramStateRef>
assume(DefinedOrUnknownSVal cond) const;
ProgramStateRef assumeInBound(DefinedOrUnknownSVal idx,
DefinedOrUnknownSVal upperBound,
bool assumption,
QualType IndexType = QualType()) const;
-
+
+ /// \brief Check if the given SVal is constrained to zero or is a zero
+ /// constant.
+ ConditionTruthVal isNull(SVal V) const;
+
/// Utility method for getting regions.
const VarRegion* getRegion(const VarDecl *D, const LocationContext *LC) const;
@@ -203,12 +214,6 @@ public:
ProgramStateRef BindExpr(const Stmt *S, const LocationContext *LCtx,
SVal V, bool Invalidate = true) const;
- /// Create a new state by binding the value 'V' and location 'locaton' to the
- /// statement 'S' in the state's environment.
- ProgramStateRef bindExprAndLocation(const Stmt *S,
- const LocationContext *LCtx,
- SVal location, SVal V) const;
-
ProgramStateRef bindLoc(Loc location,
SVal V,
bool notifyChanges = true) const;
@@ -219,14 +224,38 @@ public:
ProgramStateRef killBinding(Loc LV) const;
- /// invalidateRegions - Returns the state with bindings for the given regions
- /// cleared from the store. The regions are provided as a continuous array
- /// from Begin to End. Optionally invalidates global regions as well.
- ProgramStateRef invalidateRegions(ArrayRef<const MemRegion *> Regions,
- const Expr *E, unsigned BlockCount,
- const LocationContext *LCtx,
- StoreManager::InvalidatedSymbols *IS = 0,
- const CallEvent *Call = 0) const;
+ /// \brief Returns the state with bindings for the given regions
+ /// cleared from the store.
+ ///
+ /// Optionally invalidates global regions as well.
+ ///
+ /// \param Regions the set of regions to be invalidated.
+ /// \param E the expression that caused the invalidation.
+ /// \param BlockCount The number of times the current basic block has been
+ // visited.
+ /// \param CausesPointerEscape the flag is set to true when
+ /// the invalidation entails escape of a symbol (representing a
+ /// pointer). For example, due to it being passed as an argument in a
+ /// call.
+ /// \param IS the set of invalidated symbols.
+ /// \param Call if non-null, the invalidated regions represent parameters to
+ /// the call and should be considered directly invalidated.
+ /// \param ConstRegions the set of regions whose contents are accessible,
+ /// even though the regions themselves should not be invalidated.
+ ProgramStateRef
+ invalidateRegions(ArrayRef<const MemRegion *> Regions, const Expr *E,
+ unsigned BlockCount, const LocationContext *LCtx,
+ bool CausesPointerEscape, InvalidatedSymbols *IS = 0,
+ const CallEvent *Call = 0,
+ ArrayRef<const MemRegion *> ConstRegions =
+ ArrayRef<const MemRegion *>()) const;
+
+ ProgramStateRef
+ invalidateRegions(ArrayRef<SVal> Regions, const Expr *E,
+ unsigned BlockCount, const LocationContext *LCtx,
+ bool CausesPointerEscape, InvalidatedSymbols *IS = 0,
+ const CallEvent *Call = 0,
+ ArrayRef<SVal> ConstRegions = ArrayRef<SVal>()) const;
/// enterStackFrame - Returns the state for entry to the given stack frame,
/// preserving the current state.
@@ -396,13 +425,17 @@ public:
private:
friend void ProgramStateRetain(const ProgramState *state);
friend void ProgramStateRelease(const ProgramState *state);
-
- ProgramStateRef
- invalidateRegionsImpl(ArrayRef<const MemRegion *> Regions,
+
+ /// \sa invalidateValues()
+ /// \sa invalidateRegions()
+ ProgramStateRef
+ invalidateRegionsImpl(ArrayRef<SVal> Values,
const Expr *E, unsigned BlockCount,
const LocationContext *LCtx,
- StoreManager::InvalidatedSymbols &IS,
- const CallEvent *Call) const;
+ bool ResultsInSymbolEscape,
+ InvalidatedSymbols &IS,
+ const CallEvent *Call,
+ ArrayRef<SVal> ConstValues) const;
};
//===----------------------------------------------------------------------===//
@@ -611,22 +644,24 @@ inline ProgramStateRef ProgramState::assume(DefinedOrUnknownSVal Cond,
bool Assumption) const {
if (Cond.isUnknown())
return this;
-
- return getStateManager().ConstraintMgr->assume(this, cast<DefinedSVal>(Cond),
- Assumption);
+
+ return getStateManager().ConstraintMgr
+ ->assume(this, Cond.castAs<DefinedSVal>(), Assumption);
}
inline std::pair<ProgramStateRef , ProgramStateRef >
ProgramState::assume(DefinedOrUnknownSVal Cond) const {
if (Cond.isUnknown())
return std::make_pair(this, this);
-
- return getStateManager().ConstraintMgr->assumeDual(this,
- cast<DefinedSVal>(Cond));
+
+ return getStateManager().ConstraintMgr
+ ->assumeDual(this, Cond.castAs<DefinedSVal>());
}
inline ProgramStateRef ProgramState::bindLoc(SVal LV, SVal V) const {
- return !isa<Loc>(LV) ? this : bindLoc(cast<Loc>(LV), V);
+ if (Optional<Loc> L = LV.getAs<Loc>())
+ return bindLoc(*L, V);
+ return this;
}
inline Loc ProgramState::getLValue(const VarDecl *VD,
@@ -660,7 +695,7 @@ inline SVal ProgramState::getLValue(const IndirectFieldDecl *D,
}
inline SVal ProgramState::getLValue(QualType ElementType, SVal Idx, SVal Base) const{
- if (NonLoc *N = dyn_cast<NonLoc>(&Idx))
+ if (Optional<NonLoc> N = Idx.getAs<NonLoc>())
return getStateManager().StoreMgr->getLValueElement(ElementType, *N, Base);
return UnknownVal();
}
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h
index ea2a8525ba47..eb52ae47bdf2 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h
@@ -18,6 +18,8 @@
#ifndef LLVM_CLANG_GR_PROGRAMSTATETRAIT_H
#define LLVM_CLANG_GR_PROGRAMSTATETRAIT_H
+#include "llvm/Support/DataTypes.h"
+
namespace llvm {
class BumpPtrAllocator;
template <typename K, typename D, typename I> class ImmutableMap;
@@ -165,7 +167,7 @@ namespace ento {
}
static inline void *MakeVoidPtr(data_type D) {
- return (void*) D.getInternalPointer();
+ return const_cast<llvm::ImmutableListImpl<T> *>(D.getInternalPointer());
}
static inline context_type MakeContext(void *p) {
@@ -221,7 +223,20 @@ namespace ento {
}
};
-} // end GR namespace
+ // Partial specialization for const void *.
+ template <> struct ProgramStatePartialTrait<const void *> {
+ typedef const void *data_type;
+
+ static inline data_type MakeData(void * const *p) {
+ return p ? *p : data_type();
+ }
+
+ static inline void *MakeVoidPtr(data_type d) {
+ return const_cast<void *>(d);
+ }
+ };
+
+} // end ento namespace
} // end clang namespace
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
index 5d72e73a3d94..f7e49a3c7539 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
@@ -17,11 +17,10 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/Expr.h"
-#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
namespace clang {
@@ -124,7 +123,7 @@ public:
ProgramStateManager &getStateManager() { return StateMgr; }
QualType getConditionType() const {
- return getContext().IntTy;
+ return Context.getLangOpts().CPlusPlus ? Context.BoolTy : Context.IntTy;
}
QualType getArrayIndexType() const {
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
index c2134cf04826..1c5519e9e785 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
@@ -16,8 +16,8 @@
#define LLVM_CLANG_GR_RVALUE_H
#include "clang/Basic/LLVM.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
#include "llvm/ADT/ImmutableList.h"
//==------------------------------------------------------------------------==//
@@ -33,7 +33,7 @@ class LazyCompoundValData;
class ProgramState;
class BasicValueFactory;
class MemRegion;
-class TypedRegion;
+class TypedValueRegion;
class MemRegionManager;
class ProgramStateManager;
class SValBuilder;
@@ -69,6 +69,29 @@ protected:
public:
explicit SVal() : Data(0), Kind(0) {}
+ /// \brief Convert to the specified SVal type, asserting that this SVal is of
+ /// the desired type.
+ template<typename T>
+ T castAs() const {
+ assert(T::isKind(*this));
+ T t;
+ SVal& sv = t;
+ sv = *this;
+ return t;
+ }
+
+ /// \brief Convert to the specified SVal type, returning None if this SVal is
+ /// not of the desired type.
+ template<typename T>
+ Optional<T> getAs() const {
+ if (!T::isKind(*this))
+ return None;
+ T t;
+ SVal& sv = t;
+ sv = *this;
+ return t;
+ }
+
/// BufferTy - A temporary buffer to hold a set of SVals.
typedef SmallVector<SVal,5> BufferTy;
@@ -161,29 +184,32 @@ class UndefinedVal : public SVal {
public:
UndefinedVal() : SVal(UndefinedKind) {}
- static inline bool classof(const SVal* V) {
- return V->getBaseKind() == UndefinedKind;
+private:
+ friend class SVal;
+ static bool isKind(const SVal& V) {
+ return V.getBaseKind() == UndefinedKind;
}
};
class DefinedOrUnknownSVal : public SVal {
private:
- // Do not implement. We want calling these methods to be a compiler
- // error since they are tautologically false.
- bool isUndef() const;
- bool isValid() const;
+ // We want calling these methods to be a compiler error since they are
+ // tautologically false.
+ bool isUndef() const LLVM_DELETED_FUNCTION;
+ bool isValid() const LLVM_DELETED_FUNCTION;
protected:
+ DefinedOrUnknownSVal() {}
explicit DefinedOrUnknownSVal(const void *d, bool isLoc, unsigned ValKind)
: SVal(d, isLoc, ValKind) {}
explicit DefinedOrUnknownSVal(BaseKind k, void *D = NULL)
: SVal(k, D) {}
-public:
- // Implement isa<T> support.
- static inline bool classof(const SVal *V) {
- return !V->isUndef();
+private:
+ friend class SVal;
+ static bool isKind(const SVal& V) {
+ return !V.isUndef();
}
};
@@ -191,61 +217,79 @@ class UnknownVal : public DefinedOrUnknownSVal {
public:
explicit UnknownVal() : DefinedOrUnknownSVal(UnknownKind) {}
- static inline bool classof(const SVal *V) {
- return V->getBaseKind() == UnknownKind;
+private:
+ friend class SVal;
+ static bool isKind(const SVal &V) {
+ return V.getBaseKind() == UnknownKind;
}
};
class DefinedSVal : public DefinedOrUnknownSVal {
private:
- // Do not implement. We want calling these methods to be a compiler
- // error since they are tautologically true/false.
- bool isUnknown() const;
- bool isUnknownOrUndef() const;
- bool isValid() const;
+ // We want calling these methods to be a compiler error since they are
+ // tautologically true/false.
+ bool isUnknown() const LLVM_DELETED_FUNCTION;
+ bool isUnknownOrUndef() const LLVM_DELETED_FUNCTION;
+ bool isValid() const LLVM_DELETED_FUNCTION;
protected:
+ DefinedSVal() {}
explicit DefinedSVal(const void *d, bool isLoc, unsigned ValKind)
: DefinedOrUnknownSVal(d, isLoc, ValKind) {}
-public:
- // Implement isa<T> support.
- static inline bool classof(const SVal *V) {
- return !V->isUnknownOrUndef();
+private:
+ friend class SVal;
+ static bool isKind(const SVal& V) {
+ return !V.isUnknownOrUndef();
+ }
+};
+
+
+/// \brief Represents an SVal that is guaranteed to not be UnknownVal.
+class KnownSVal : public SVal {
+ KnownSVal() {}
+ friend class SVal;
+ static bool isKind(const SVal &V) {
+ return !V.isUnknown();
}
+public:
+ KnownSVal(const DefinedSVal &V) : SVal(V) {}
+ KnownSVal(const UndefinedVal &V) : SVal(V) {}
};
class NonLoc : public DefinedSVal {
protected:
+ NonLoc() {}
explicit NonLoc(unsigned SubKind, const void *d)
: DefinedSVal(d, false, SubKind) {}
public:
void dumpToStream(raw_ostream &Out) const;
- // Implement isa<T> support.
- static inline bool classof(const SVal* V) {
- return V->getBaseKind() == NonLocKind;
+private:
+ friend class SVal;
+ static bool isKind(const SVal& V) {
+ return V.getBaseKind() == NonLocKind;
}
};
class Loc : public DefinedSVal {
protected:
+ Loc() {}
explicit Loc(unsigned SubKind, const void *D)
: DefinedSVal(const_cast<void*>(D), true, SubKind) {}
public:
void dumpToStream(raw_ostream &Out) const;
- Loc(const Loc& X) : DefinedSVal(X.Data, true, X.getSubKind()) {}
-
- // Implement isa<T> support.
- static inline bool classof(const SVal* V) {
- return V->getBaseKind() == LocKind;
- }
-
static inline bool isLocType(QualType T) {
return T->isAnyPointerType() || T->isBlockPointerType() ||
T->isReferenceType();
}
+
+private:
+ friend class SVal;
+ static bool isKind(const SVal& V) {
+ return V.getBaseKind() == LocKind;
+ }
};
//==------------------------------------------------------------------------==//
@@ -266,17 +310,20 @@ public:
return (const SymExpr*) Data;
}
- bool isExpression() {
+ bool isExpression() const {
return !isa<SymbolData>(getSymbol());
}
- static inline bool classof(const SVal* V) {
- return V->getBaseKind() == NonLocKind &&
- V->getSubKind() == SymbolValKind;
+private:
+ friend class SVal;
+ SymbolVal() {}
+ static bool isKind(const SVal& V) {
+ return V.getBaseKind() == NonLocKind &&
+ V.getSubKind() == SymbolValKind;
}
- static inline bool classof(const NonLoc* V) {
- return V->getSubKind() == SymbolValKind;
+ static bool isKind(const NonLoc& V) {
+ return V.getSubKind() == SymbolValKind;
}
};
@@ -297,38 +344,40 @@ public:
ConcreteInt evalMinus(SValBuilder &svalBuilder) const;
- // Implement isa<T> support.
- static inline bool classof(const SVal* V) {
- return V->getBaseKind() == NonLocKind &&
- V->getSubKind() == ConcreteIntKind;
+private:
+ friend class SVal;
+ ConcreteInt() {}
+ static bool isKind(const SVal& V) {
+ return V.getBaseKind() == NonLocKind &&
+ V.getSubKind() == ConcreteIntKind;
}
- static inline bool classof(const NonLoc* V) {
- return V->getSubKind() == ConcreteIntKind;
+ static bool isKind(const NonLoc& V) {
+ return V.getSubKind() == ConcreteIntKind;
}
};
class LocAsInteger : public NonLoc {
friend class ento::SValBuilder;
- explicit LocAsInteger(const std::pair<SVal, uintptr_t>& data) :
- NonLoc(LocAsIntegerKind, &data) {
- assert (isa<Loc>(data.first));
- }
+ explicit LocAsInteger(const std::pair<SVal, uintptr_t> &data)
+ : NonLoc(LocAsIntegerKind, &data) {
+ assert (data.first.getAs<Loc>());
+ }
public:
Loc getLoc() const {
const std::pair<SVal, uintptr_t> *D =
static_cast<const std::pair<SVal, uintptr_t> *>(Data);
- return cast<Loc>(D->first);
+ return D->first.castAs<Loc>();
}
- const Loc& getPersistentLoc() const {
+ Loc getPersistentLoc() const {
const std::pair<SVal, uintptr_t> *D =
static_cast<const std::pair<SVal, uintptr_t> *>(Data);
const SVal& V = D->first;
- return cast<Loc>(V);
+ return V.castAs<Loc>();
}
unsigned getNumBits() const {
@@ -337,14 +386,16 @@ public:
return D->second;
}
- // Implement isa<T> support.
- static inline bool classof(const SVal* V) {
- return V->getBaseKind() == NonLocKind &&
- V->getSubKind() == LocAsIntegerKind;
+private:
+ friend class SVal;
+ LocAsInteger() {}
+ static bool isKind(const SVal& V) {
+ return V.getBaseKind() == NonLocKind &&
+ V.getSubKind() == LocAsIntegerKind;
}
- static inline bool classof(const NonLoc* V) {
- return V->getSubKind() == LocAsIntegerKind;
+ static bool isKind(const NonLoc& V) {
+ return V.getSubKind() == LocAsIntegerKind;
}
};
@@ -362,12 +413,15 @@ public:
iterator begin() const;
iterator end() const;
- static bool classof(const SVal* V) {
- return V->getBaseKind() == NonLocKind && V->getSubKind() == CompoundValKind;
+private:
+ friend class SVal;
+ CompoundVal() {}
+ static bool isKind(const SVal& V) {
+ return V.getBaseKind() == NonLocKind && V.getSubKind() == CompoundValKind;
}
- static bool classof(const NonLoc* V) {
- return V->getSubKind() == CompoundValKind;
+ static bool isKind(const NonLoc& V) {
+ return V.getSubKind() == CompoundValKind;
}
};
@@ -381,14 +435,17 @@ public:
return static_cast<const LazyCompoundValData*>(Data);
}
const void *getStore() const;
- const TypedRegion *getRegion() const;
+ const TypedValueRegion *getRegion() const;
- static bool classof(const SVal *V) {
- return V->getBaseKind() == NonLocKind &&
- V->getSubKind() == LazyCompoundValKind;
+private:
+ friend class SVal;
+ LazyCompoundVal() {}
+ static bool isKind(const SVal& V) {
+ return V.getBaseKind() == NonLocKind &&
+ V.getSubKind() == LazyCompoundValKind;
}
- static bool classof(const NonLoc *V) {
- return V->getSubKind() == LazyCompoundValKind;
+ static bool isKind(const NonLoc& V) {
+ return V.getSubKind() == LazyCompoundValKind;
}
};
@@ -410,12 +467,15 @@ public:
return static_cast<const LabelDecl*>(Data);
}
- static inline bool classof(const SVal* V) {
- return V->getBaseKind() == LocKind && V->getSubKind() == GotoLabelKind;
+private:
+ friend class SVal;
+ GotoLabel() {}
+ static bool isKind(const SVal& V) {
+ return V.getBaseKind() == LocKind && V.getSubKind() == GotoLabelKind;
}
- static inline bool classof(const Loc* V) {
- return V->getSubKind() == GotoLabelKind;
+ static bool isKind(const Loc& V) {
+ return V.getSubKind() == GotoLabelKind;
}
};
@@ -434,7 +494,7 @@ public:
template <typename REGION>
const REGION* getRegionAs() const {
- return llvm::dyn_cast<REGION>(getRegion());
+ return dyn_cast<REGION>(getRegion());
}
inline bool operator==(const MemRegionVal& R) const {
@@ -445,14 +505,16 @@ public:
return getRegion() != R.getRegion();
}
- // Implement isa<T> support.
- static inline bool classof(const SVal* V) {
- return V->getBaseKind() == LocKind &&
- V->getSubKind() == MemRegionKind;
+private:
+ friend class SVal;
+ MemRegionVal() {}
+ static bool isKind(const SVal& V) {
+ return V.getBaseKind() == LocKind &&
+ V.getSubKind() == MemRegionKind;
}
- static inline bool classof(const Loc* V) {
- return V->getSubKind() == MemRegionKind;
+ static bool isKind(const Loc& V) {
+ return V.getSubKind() == MemRegionKind;
}
};
@@ -468,19 +530,22 @@ public:
SVal evalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op,
const ConcreteInt& R) const;
- // Implement isa<T> support.
- static inline bool classof(const SVal* V) {
- return V->getBaseKind() == LocKind &&
- V->getSubKind() == ConcreteIntKind;
+private:
+ friend class SVal;
+ ConcreteInt() {}
+ static bool isKind(const SVal& V) {
+ return V.getBaseKind() == LocKind &&
+ V.getSubKind() == ConcreteIntKind;
}
- static inline bool classof(const Loc* V) {
- return V->getSubKind() == ConcreteIntKind;
+ static bool isKind(const Loc& V) {
+ return V.getSubKind() == ConcreteIntKind;
}
};
} // end ento::loc namespace
-} // end GR namespace
+
+} // end ento namespace
} // end clang namespace
@@ -491,6 +556,11 @@ static inline raw_ostream &operator<<(raw_ostream &os,
return os;
}
+template <typename T> struct isPodLike;
+template <> struct isPodLike<clang::ento::SVal> {
+ static const bool value = true;
+};
+
} // end llvm namespace
#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
index 979546b6ed47..bbfd5797fff0 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
@@ -14,9 +14,9 @@
#ifndef LLVM_CLANG_GR_STORE_H
#define LLVM_CLANG_GR_STORE_H
-#include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/Optional.h"
@@ -35,6 +35,8 @@ class ProgramState;
class ProgramStateManager;
class ScanReachableSymbols;
+typedef llvm::DenseSet<SymbolRef> InvalidatedSymbols;
+
class StoreManager {
protected:
SValBuilder &svalBuilder;
@@ -134,7 +136,8 @@ public:
SVal evalDerivedToBase(SVal Derived, const CXXBasePath &CastPath);
/// Evaluates a derived-to-base cast through a single level of derivation.
- SVal evalDerivedToBase(SVal Derived, QualType DerivedPtrType);
+ SVal evalDerivedToBase(SVal Derived, QualType DerivedPtrType,
+ bool IsVirtual);
/// \brief Evaluates C++ dynamic_cast cast.
/// The callback may result in the following 3 scenarios:
@@ -168,7 +171,6 @@ public:
/// associated with the object is recycled.
virtual void decrementReferenceCount(Store store) {}
- typedef llvm::DenseSet<SymbolRef> InvalidatedSymbols;
typedef SmallVector<const MemRegion *, 8> InvalidatedRegions;
/// invalidateRegions - Clears out the specified regions from the store,
@@ -176,26 +178,40 @@ public:
/// invalidate additional regions that may have changed based on accessing
/// the given regions. Optionally, invalidates non-static globals as well.
/// \param[in] store The initial store
- /// \param[in] Regions The regions to invalidate.
+ /// \param[in] Values The values to invalidate.
+ /// \param[in] ConstValues The values to invalidate; these are known to be
+ /// const, so only regions accesible from them should be invalidated.
/// \param[in] E The current statement being evaluated. Used to conjure
/// symbols to mark the values of invalidated regions.
/// \param[in] Count The current block count. Used to conjure
/// symbols to mark the values of invalidated regions.
- /// \param[in,out] IS A set to fill with any symbols that are no longer
- /// accessible. Pass \c NULL if this information will not be used.
/// \param[in] Call The call expression which will be used to determine which
/// globals should get invalidated.
+ /// \param[in,out] IS A set to fill with any symbols that are no longer
+ /// accessible. Pass \c NULL if this information will not be used.
+ /// \param[in,out] ConstIS A set to fill with any symbols corresponding to
+ /// the ConstValues.
+ /// \param[in,out] InvalidatedTopLevel A vector to fill with regions
+ //// explicitely being invalidated. Pass \c NULL if this
+ /// information will not be used.
+ /// \param[in,out] InvalidatedTopLevelConst A vector to fill with const
+ //// regions explicitely being invalidated. Pass \c NULL if this
+ /// information will not be used.
/// \param[in,out] Invalidated A vector to fill with any regions being
/// invalidated. This should include any regions explicitly invalidated
/// even if they do not currently have bindings. Pass \c NULL if this
/// information will not be used.
virtual StoreRef invalidateRegions(Store store,
- ArrayRef<const MemRegion *> Regions,
- const Expr *E, unsigned Count,
- const LocationContext *LCtx,
- InvalidatedSymbols &IS,
- const CallEvent *Call,
- InvalidatedRegions *Invalidated) = 0;
+ ArrayRef<SVal> Values,
+ ArrayRef<SVal> ConstValues,
+ const Expr *E, unsigned Count,
+ const LocationContext *LCtx,
+ const CallEvent *Call,
+ InvalidatedSymbols &IS,
+ InvalidatedSymbols &ConstIS,
+ InvalidatedRegions *InvalidatedTopLevel,
+ InvalidatedRegions *InvalidatedTopLevelConst,
+ InvalidatedRegions *Invalidated) = 0;
/// enterStackFrame - Let the StoreManager to do something when execution
/// engine is about to execute into a callee.
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
index 1e710778d9be..d4100634a785 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
@@ -72,6 +72,15 @@ public:
const CFGBlock *DstT,
const CFGBlock *DstF) = 0;
+ /// Called by CoreEngine. Used to processing branching behavior
+ /// at static initalizers.
+ virtual void processStaticInitializer(const DeclStmt *DS,
+ NodeBuilderContext& BuilderCtx,
+ ExplodedNode *Pred,
+ ExplodedNodeSet &Dst,
+ const CFGBlock *DstT,
+ const CFGBlock *DstF) = 0;
+
/// Called by CoreEngine. Used to generate successor
/// nodes by processing the 'effects' of a computed goto jump.
virtual void processIndirectGoto(IndirectGotoNodeBuilder& builder) = 0;
@@ -104,7 +113,7 @@ public:
/// made to the store. Used to update checkers that track region values.
virtual ProgramStateRef
processRegionChanges(ProgramStateRef state,
- const StoreManager::InvalidatedSymbols *invalidated,
+ const InvalidatedSymbols *invalidated,
ArrayRef<const MemRegion *> ExplicitRegions,
ArrayRef<const MemRegion *> Regions,
const CallEvent *Call) = 0;
@@ -116,6 +125,17 @@ public:
return processRegionChanges(state, 0, MR, MR, 0);
}
+ virtual ProgramStateRef
+ processPointerEscapedOnBind(ProgramStateRef State, SVal Loc, SVal Val) = 0;
+
+ virtual ProgramStateRef
+ notifyCheckersOfPointerEscape(ProgramStateRef State,
+ const InvalidatedSymbols *Invalidated,
+ ArrayRef<const MemRegion *> ExplicitRegions,
+ ArrayRef<const MemRegion *> Regions,
+ const CallEvent *Call,
+ bool IsConst = false) = 0;
+
/// printState - Called by ProgramStateManager to print checker-specific data.
virtual void printState(raw_ostream &Out, ProgramStateRef State,
const char *NL, const char *Sep) = 0;
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
index 873f773b459d..56afca24f6b4 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
@@ -20,10 +20,10 @@
#include "clang/Analysis/AnalysisContext.h"
#include "clang/Basic/LLVM.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h"
-#include "llvm/Support/DataTypes.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
class BumpPtrAllocator;
@@ -96,7 +96,7 @@ public:
};
typedef const SymExpr* SymbolRef;
-typedef llvm::SmallVector<SymbolRef, 2> SymbolRefSmallVectorTy;
+typedef SmallVector<SymbolRef, 2> SymbolRefSmallVectorTy;
typedef unsigned SymbolID;
/// \brief A symbol representing data which can be stored in a memory location
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h
index c274cea8413e..4c58d4b1d261 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h
@@ -14,7 +14,11 @@
#ifndef LLVM_CLANG_TAINTMANAGER_H
#define LLVM_CLANG_TAINTMANAGER_H
+#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h"
+#include "llvm/ADT/ImmutableMap.h"
namespace clang {
namespace ento {
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h b/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h
index 51aa753f11e9..d12a1514898f 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h
@@ -16,7 +16,8 @@
#define LLVM_CLANG_GR_WORKLIST
#include "clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h"
-#include <cstddef>
+#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
+#include <cassert>
namespace clang {
@@ -24,9 +25,6 @@ class CFGBlock;
namespace ento {
-class ExplodedNode;
-class ExplodedNodeImpl;
-
class WorkListUnit {
ExplodedNode *node;
BlockCounter counter;
diff --git a/include/clang/Tooling/CommonOptionsParser.h b/include/clang/Tooling/CommonOptionsParser.h
index a1bad1269d80..677593413948 100644
--- a/include/clang/Tooling/CommonOptionsParser.h
+++ b/include/clang/Tooling/CommonOptionsParser.h
@@ -53,8 +53,8 @@ namespace tooling {
///
/// int main(int argc, const char **argv) {
/// CommonOptionsParser OptionsParser(argc, argv);
-/// ClangTool Tool(OptionsParser.GetCompilations(),
-/// OptionsParser.GetSourcePathListi());
+/// ClangTool Tool(OptionsParser.getCompilations(),
+/// OptionsParser.getSourcePathListi());
/// return Tool.run(newFrontendActionFactory<clang::SyntaxOnlyAction>());
/// }
/// \endcode
@@ -67,19 +67,19 @@ public:
CommonOptionsParser(int &argc, const char **argv);
/// Returns a reference to the loaded compilations database.
- CompilationDatabase &GetCompilations() {
+ CompilationDatabase &getCompilations() {
return *Compilations;
}
/// Returns a list of source file paths to process.
- std::vector<std::string> GetSourcePathList() {
+ std::vector<std::string> getSourcePathList() {
return SourcePathList;
}
static const char *const HelpMessage;
private:
- llvm::OwningPtr<CompilationDatabase> Compilations;
+ OwningPtr<CompilationDatabase> Compilations;
std::vector<std::string> SourcePathList;
};
diff --git a/include/clang/Tooling/CompilationDatabase.h b/include/clang/Tooling/CompilationDatabase.h
index a40bffec78ba..7a8054ffc3a4 100644
--- a/include/clang/Tooling/CompilationDatabase.h
+++ b/include/clang/Tooling/CompilationDatabase.h
@@ -33,7 +33,6 @@
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
-
#include <string>
#include <vector>
@@ -106,6 +105,10 @@ public:
/// \brief Returns the list of all files available in the compilation database.
virtual std::vector<std::string> getAllFiles() const = 0;
+
+ /// \brief Returns all compile commands for all the files in the compilation
+ /// database.
+ virtual std::vector<CompileCommand> getAllCompileCommands() const = 0;
};
/// \brief Interface for compilation database plugins.
@@ -149,7 +152,7 @@ public:
/// The argument list is meant to be compatible with normal llvm command line
/// parsing in main methods.
/// int main(int argc, char **argv) {
- /// llvm::OwningPtr<FixedCompilationDatabase> Compilations(
+ /// OwningPtr<FixedCompilationDatabase> Compilations(
/// FixedCompilationDatabase::loadFromCommandLine(argc, argv));
/// cl::ParseCommandLineOptions(argc, argv);
/// ...
@@ -181,6 +184,12 @@ public:
/// Note: This is always an empty list for the fixed compilation database.
virtual std::vector<std::string> getAllFiles() const;
+ /// \brief Returns all compile commands for all the files in the compilation
+ /// database.
+ ///
+ /// Note: This is always an empty list for the fixed compilation database.
+ virtual std::vector<CompileCommand> getAllCompileCommands() const;
+
private:
/// This is built up to contain a single entry vector to be returned from
/// getCompileCommands after adding the positional argument.
diff --git a/include/clang/Tooling/FileMatchTrie.h b/include/clang/Tooling/FileMatchTrie.h
index ff988bebf2ca..e531854cca49 100644
--- a/include/clang/Tooling/FileMatchTrie.h
+++ b/include/clang/Tooling/FileMatchTrie.h
@@ -18,7 +18,6 @@
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringRef.h"
-
#include <string>
#include <vector>
@@ -77,7 +76,7 @@ public:
/// matches, an empty \c StringRef is returned and a corresponding message
/// written to 'Error'.
StringRef findEquivalent(StringRef FileName,
- llvm::raw_ostream &Error) const;
+ raw_ostream &Error) const;
private:
FileMatchTrieNode *Root;
OwningPtr<PathComparator> Comparator;
diff --git a/include/clang/Tooling/JSONCompilationDatabase.h b/include/clang/Tooling/JSONCompilationDatabase.h
index d62ab5c5036e..e3f149bebc86 100644
--- a/include/clang/Tooling/JSONCompilationDatabase.h
+++ b/include/clang/Tooling/JSONCompilationDatabase.h
@@ -75,6 +75,10 @@ public:
/// These are the 'file' entries of the JSON objects.
virtual std::vector<std::string> getAllFiles() const;
+ /// \brief Returns all compile commands for all the files in the compilation
+ /// database.
+ virtual std::vector<CompileCommand> getAllCompileCommands() const;
+
private:
/// \brief Constructs a JSON compilation database on a memory buffer.
JSONCompilationDatabase(llvm::MemoryBuffer *Database)
@@ -91,12 +95,16 @@ private:
typedef std::pair<llvm::yaml::ScalarNode*,
llvm::yaml::ScalarNode*> CompileCommandRef;
+ /// \brief Converts the given array of CompileCommandRefs to CompileCommands.
+ void getCommands(ArrayRef<CompileCommandRef> CommandsRef,
+ std::vector<CompileCommand> &Commands) const;
+
// Maps file paths to the compile command lines for that file.
llvm::StringMap< std::vector<CompileCommandRef> > IndexByFile;
FileMatchTrie MatchTrie;
- llvm::OwningPtr<llvm::MemoryBuffer> Database;
+ OwningPtr<llvm::MemoryBuffer> Database;
llvm::SourceMgr SM;
llvm::yaml::Stream YAMLStream;
};
diff --git a/include/clang/Tooling/Refactoring.h b/include/clang/Tooling/Refactoring.h
index aaffc1a29e06..079ce7420db9 100644
--- a/include/clang/Tooling/Refactoring.h
+++ b/include/clang/Tooling/Refactoring.h
@@ -19,9 +19,9 @@
#ifndef LLVM_CLANG_TOOLING_REFACTORING_H
#define LLVM_CLANG_TOOLING_REFACTORING_H
-#include "llvm/ADT/StringRef.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/StringRef.h"
#include <set>
#include <string>
@@ -47,22 +47,22 @@ public:
/// \param FilePath A source file accessible via a SourceManager.
/// \param Offset The byte offset of the start of the range in the file.
/// \param Length The length of the range in bytes.
- Replacement(llvm::StringRef FilePath, unsigned Offset,
- unsigned Length, llvm::StringRef ReplacementText);
+ Replacement(StringRef FilePath, unsigned Offset,
+ unsigned Length, StringRef ReplacementText);
/// \brief Creates a Replacement of the range [Start, Start+Length) with
/// ReplacementText.
Replacement(SourceManager &Sources, SourceLocation Start, unsigned Length,
- llvm::StringRef ReplacementText);
+ StringRef ReplacementText);
/// \brief Creates a Replacement of the given range with ReplacementText.
Replacement(SourceManager &Sources, const CharSourceRange &Range,
- llvm::StringRef ReplacementText);
+ StringRef ReplacementText);
/// \brief Creates a Replacement of the node with ReplacementText.
template <typename Node>
Replacement(SourceManager &Sources, const Node &NodeToReplace,
- llvm::StringRef ReplacementText);
+ StringRef ReplacementText);
/// \brief Returns whether this replacement can be applied to a file.
///
@@ -91,9 +91,9 @@ public:
private:
void setFromSourceLocation(SourceManager &Sources, SourceLocation Start,
- unsigned Length, llvm::StringRef ReplacementText);
+ unsigned Length, StringRef ReplacementText);
void setFromSourceRange(SourceManager &Sources, const CharSourceRange &Range,
- llvm::StringRef ReplacementText);
+ StringRef ReplacementText);
std::string FilePath;
unsigned Offset;
@@ -105,41 +105,54 @@ public:
/// FIXME: Change to a vector and deduplicate in the RefactoringTool.
typedef std::set<Replacement, Replacement::Less> Replacements;
-/// \brief Apply all replacements on the Rewriter.
+/// \brief Apply all replacements in \p Replaces to the Rewriter \p Rewrite.
+///
+/// Replacement applications happen independently of the success of
+/// other applications.
///
-/// If at least one Apply returns false, ApplyAll returns false. Every
-/// Apply will be executed independently of the result of other
-/// Apply operations.
+/// \returns true if all replacements apply. false otherwise.
bool applyAllReplacements(Replacements &Replaces, Rewriter &Rewrite);
/// \brief A tool to run refactorings.
///
-/// This is a refactoring specific version of \see ClangTool.
-/// All text replacements added to getReplacements() during the run of the
-/// tool will be applied and saved after all translation units have been
-/// processed.
-class RefactoringTool {
+/// This is a refactoring specific version of \see ClangTool. FrontendActions
+/// passed to run() and runAndSave() should add replacements to
+/// getReplacements().
+class RefactoringTool : public ClangTool {
public:
/// \see ClangTool::ClangTool.
RefactoringTool(const CompilationDatabase &Compilations,
ArrayRef<std::string> SourcePaths);
- /// \brief Returns a set of replacements. All replacements added during the
- /// run of the tool will be applied after all translation units have been
- /// processed.
+ /// \brief Returns the set of replacements to which replacements should
+ /// be added during the run of the tool.
Replacements &getReplacements();
- /// \see ClangTool::run.
- int run(FrontendActionFactory *ActionFactory);
+ /// \brief Call run(), apply all generated replacements, and immediately save
+ /// the results to disk.
+ ///
+ /// \returns 0 upon success. Non-zero upon failure.
+ int runAndSave(FrontendActionFactory *ActionFactory);
+
+ /// \brief Apply all stored replacements to the given Rewriter.
+ ///
+ /// Replacement applications happen independently of the success of other
+ /// applications.
+ ///
+ /// \returns true if all replacements apply. false otherwise.
+ bool applyAllReplacements(Rewriter &Rewrite);
+
+private:
+ /// \brief Write all refactored files to disk.
+ int saveRewrittenFiles(Rewriter &Rewrite);
private:
- ClangTool Tool;
Replacements Replace;
};
template <typename Node>
Replacement::Replacement(SourceManager &Sources, const Node &NodeToReplace,
- llvm::StringRef ReplacementText) {
+ StringRef ReplacementText) {
const CharSourceRange Range =
CharSourceRange::getTokenRange(NodeToReplace->getSourceRange());
setFromSourceRange(Sources, Range, ReplacementText);
@@ -149,4 +162,3 @@ Replacement::Replacement(SourceManager &Sources, const Node &NodeToReplace,
} // end namespace clang
#endif // end namespace LLVM_CLANG_TOOLING_REFACTORING_H
-
diff --git a/include/clang/Tooling/Tooling.h b/include/clang/Tooling/Tooling.h
index a03bcb1bbb84..27e5a0af2573 100644
--- a/include/clang/Tooling/Tooling.h
+++ b/include/clang/Tooling/Tooling.h
@@ -30,14 +30,14 @@
#ifndef LLVM_CLANG_TOOLING_TOOLING_H
#define LLVM_CLANG_TOOLING_TOOLING_H
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/Twine.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/LLVM.h"
#include "clang/Driver/Util.h"
#include "clang/Frontend/FrontendAction.h"
#include "clang/Tooling/ArgumentsAdjusters.h"
#include "clang/Tooling/CompilationDatabase.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/Twine.h"
#include <string>
#include <vector>
@@ -151,11 +151,10 @@ class ToolInvocation {
bool runInvocation(const char *BinaryName,
clang::driver::Compilation *Compilation,
- clang::CompilerInvocation *Invocation,
- const clang::driver::ArgStringList &CC1Args);
+ clang::CompilerInvocation *Invocation);
std::vector<std::string> CommandLine;
- llvm::OwningPtr<FrontendAction> ToolAction;
+ OwningPtr<FrontendAction> ToolAction;
FileManager *Files;
// Maps <file name> -> <file content>.
llvm::StringMap<StringRef> MappedFileContents;
@@ -179,6 +178,8 @@ class ClangTool {
ClangTool(const CompilationDatabase &Compilations,
ArrayRef<std::string> SourcePaths);
+ virtual ~ClangTool() {}
+
/// \brief Map a virtual file to be used while running the tool.
///
/// \param FilePath The path at which the content will be mapped.
@@ -195,7 +196,7 @@ class ClangTool {
/// \param ActionFactory Factory generating the frontend actions. The function
/// takes ownership of this parameter. A new action is generated for every
/// processed translation unit.
- int run(FrontendActionFactory *ActionFactory);
+ virtual int run(FrontendActionFactory *ActionFactory);
/// \brief Returns the file manager used in the tool.
///
@@ -210,7 +211,7 @@ class ClangTool {
// Contains a list of pairs (<file name>, <file content>).
std::vector< std::pair<StringRef, StringRef> > MappedFileContents;
- llvm::OwningPtr<ArgumentsAdjuster> ArgsAdjuster;
+ OwningPtr<ArgumentsAdjuster> ArgsAdjuster;
};
template <typename T>
@@ -244,7 +245,7 @@ inline FrontendActionFactory *newFrontendActionFactory(
: ConsumerFactory(ConsumerFactory), EndCallback(EndCallback) {}
clang::ASTConsumer *CreateASTConsumer(clang::CompilerInstance &,
- llvm::StringRef) {
+ StringRef) {
return ConsumerFactory->newASTConsumer();
}