From 39fcc9a984e2820e4ea0fa2ac4abd17d9f3a31df Mon Sep 17 00:00:00 2001 From: dim Date: Sun, 20 Feb 2011 13:06:31 +0000 Subject: Vendor import of clang trunk r126079: http://llvm.org/svn/llvm-project/cfe/trunk@126079 --- include/clang/AST/ASTConsumer.h | 8 +- include/clang/AST/ASTContext.h | 545 +++--- include/clang/AST/ASTDiagnostic.h | 2 +- include/clang/AST/ASTImporter.h | 55 +- include/clang/AST/ASTMutationListener.h | 48 + include/clang/AST/Attr.h | 31 +- include/clang/AST/CXXInheritance.h | 7 +- include/clang/AST/CanonicalType.h | 20 +- include/clang/AST/CharUnits.h | 50 +- include/clang/AST/Decl.h | 581 ++++-- include/clang/AST/DeclBase.h | 75 +- include/clang/AST/DeclCXX.h | 563 +++--- include/clang/AST/DeclFriend.h | 29 +- include/clang/AST/DeclGroup.h | 2 +- include/clang/AST/DeclObjC.h | 119 +- include/clang/AST/DeclTemplate.h | 402 ++-- include/clang/AST/DeclarationName.h | 10 +- include/clang/AST/EvaluatedExprVisitor.h | 82 + include/clang/AST/Expr.h | 1158 +++++++----- include/clang/AST/ExprCXX.h | 1061 ++++++++--- include/clang/AST/ExprObjC.h | 386 ++-- include/clang/AST/ExternalASTSource.h | 48 +- include/clang/AST/FullExpr.h | 88 - include/clang/AST/Mangle.h | 150 ++ include/clang/AST/NestedNameSpecifier.h | 23 +- include/clang/AST/OperationKinds.h | 201 +- include/clang/AST/ParentMap.h | 10 + include/clang/AST/PrettyPrinter.h | 4 +- include/clang/AST/RecordLayout.h | 169 +- include/clang/AST/RecursiveASTVisitor.h | 325 ++-- include/clang/AST/Redeclarable.h | 20 +- include/clang/AST/Stmt.h | 371 ++-- include/clang/AST/StmtCXX.h | 12 +- include/clang/AST/StmtIterator.h | 96 +- include/clang/AST/StmtObjC.h | 39 +- include/clang/AST/TemplateBase.h | 283 +-- include/clang/AST/TemplateName.h | 146 +- include/clang/AST/Type.h | 1915 +++++++++++++------- include/clang/AST/TypeLoc.h | 347 +++- include/clang/AST/TypeLocBuilder.h | 155 -- include/clang/AST/TypeNodes.def | 5 + include/clang/AST/TypeVisitor.h | 9 +- include/clang/Analysis/Analyses/FormatString.h | 13 +- include/clang/Analysis/Analyses/LiveVariables.h | 3 +- .../Analysis/Analyses/UninitializedValuesV2.h | 40 + include/clang/Analysis/AnalysisContext.h | 37 +- include/clang/Analysis/AnalysisDiagnostic.h | 2 +- include/clang/Analysis/CFG.h | 409 ++++- .../Analysis/DomainSpecific/CocoaConventions.h | 40 + .../clang/Analysis/FlowSensitive/DataflowSolver.h | 18 +- include/clang/Analysis/ProgramPoint.h | 48 +- include/clang/Analysis/Support/BumpVector.h | 29 +- .../Analysis/Visitors/CFGRecStmtDeclVisitor.h | 4 + .../clang/Analysis/Visitors/CFGRecStmtVisitor.h | 5 + include/clang/Analysis/Visitors/CFGStmtVisitor.h | 4 +- include/clang/Basic/ABI.h | 126 ++ include/clang/Basic/Attr.td | 241 ++- include/clang/Basic/AttrKinds.h | 1 + include/clang/Basic/Builtins.def | 291 ++- include/clang/Basic/Builtins.h | 23 +- include/clang/Basic/BuiltinsPPC.def | 22 +- include/clang/Basic/BuiltinsX86.def | 15 +- include/clang/Basic/DeclNodes.td | 4 +- include/clang/Basic/Diagnostic.h | 440 ++--- include/clang/Basic/Diagnostic.td | 2 + include/clang/Basic/DiagnosticASTKinds.td | 29 + include/clang/Basic/DiagnosticCommonKinds.td | 3 + include/clang/Basic/DiagnosticDriverKinds.td | 14 +- include/clang/Basic/DiagnosticFrontendKinds.td | 30 +- include/clang/Basic/DiagnosticGroups.td | 48 +- include/clang/Basic/DiagnosticIDs.h | 212 +++ include/clang/Basic/DiagnosticLexKinds.td | 14 +- include/clang/Basic/DiagnosticParseKinds.td | 87 +- include/clang/Basic/DiagnosticSemaKinds.td | 720 ++++++-- include/clang/Basic/FileManager.h | 190 +- include/clang/Basic/FileSystemOptions.h | 31 + include/clang/Basic/FileSystemStatCache.h | 101 ++ include/clang/Basic/IdentifierTable.h | 93 +- include/clang/Basic/LangOptions.h | 90 +- include/clang/Basic/OnDiskHashTable.h | 70 +- include/clang/Basic/OpenCLExtensions.def | 28 + include/clang/Basic/PartialDiagnostic.h | 55 +- include/clang/Basic/SourceLocation.h | 45 +- include/clang/Basic/SourceManager.h | 36 +- include/clang/Basic/Specifiers.h | 17 + include/clang/Basic/StmtNodes.td | 24 +- include/clang/Basic/TargetInfo.h | 35 +- include/clang/Basic/TokenKinds.def | 40 +- include/clang/Basic/TokenKinds.h | 6 + include/clang/Basic/TypeTraits.h | 6 + include/clang/Basic/Version.h | 2 +- include/clang/Basic/Visibility.h | 48 + include/clang/Basic/arm_neon.td | 386 ++-- include/clang/CMakeLists.txt | 1 + include/clang/Checker/AnalysisConsumer.h | 35 - include/clang/Checker/BugReporter/BugReporter.h | 483 ----- include/clang/Checker/BugReporter/BugType.h | 72 - include/clang/Checker/BugReporter/PathDiagnostic.h | 494 ----- .../clang/Checker/Checkers/DereferenceChecker.h | 31 - include/clang/Checker/Checkers/LocalCheckers.h | 61 - .../Checker/DomainSpecific/CocoaConventions.h | 39 - include/clang/Checker/FrontendActions.h | 29 - include/clang/Checker/ManagerRegistry.h | 53 - include/clang/Checker/PathDiagnosticClients.h | 32 - .../clang/Checker/PathSensitive/AnalysisManager.h | 202 --- .../Checker/PathSensitive/BasicValueFactory.h | 197 -- include/clang/Checker/PathSensitive/Checker.h | 308 ---- .../clang/Checker/PathSensitive/CheckerHelpers.h | 40 - .../clang/Checker/PathSensitive/CheckerVisitor.def | 37 - .../clang/Checker/PathSensitive/CheckerVisitor.h | 107 -- .../Checker/PathSensitive/ConstraintManager.h | 72 - include/clang/Checker/PathSensitive/Environment.h | 102 -- .../clang/Checker/PathSensitive/ExplodedGraph.h | 430 ----- include/clang/Checker/PathSensitive/GRAuditor.h | 35 - .../clang/Checker/PathSensitive/GRBlockCounter.h | 55 - include/clang/Checker/PathSensitive/GRCoreEngine.h | 531 ------ include/clang/Checker/PathSensitive/GRExprEngine.h | 528 ------ .../Checker/PathSensitive/GRExprEngineBuilders.h | 76 - .../clang/Checker/PathSensitive/GRSimpleAPICheck.h | 31 - include/clang/Checker/PathSensitive/GRState.h | 760 -------- include/clang/Checker/PathSensitive/GRStateTrait.h | 148 -- include/clang/Checker/PathSensitive/GRSubEngine.h | 107 -- .../clang/Checker/PathSensitive/GRTransferFuncs.h | 87 - include/clang/Checker/PathSensitive/GRWorkList.h | 79 - include/clang/Checker/PathSensitive/MemRegion.h | 1041 ----------- include/clang/Checker/PathSensitive/SVals.h | 503 ----- include/clang/Checker/PathSensitive/SValuator.h | 70 - include/clang/Checker/PathSensitive/Store.h | 245 --- .../clang/Checker/PathSensitive/SummaryManager.h | 57 - .../clang/Checker/PathSensitive/SymbolManager.h | 485 ----- include/clang/Checker/PathSensitive/ValueManager.h | 216 --- include/clang/CodeGen/CodeGenAction.h | 26 +- include/clang/Config/config.h.cmake | 17 + include/clang/Driver/ArgList.h | 2 +- include/clang/Driver/CC1AsOptions.td | 4 + include/clang/Driver/CC1Options.td | 133 +- include/clang/Driver/Driver.h | 22 +- include/clang/Driver/DriverDiagnostic.h | 2 +- include/clang/Driver/HostInfo.h | 2 + include/clang/Driver/OptTable.h | 4 +- include/clang/Driver/Options.td | 76 +- include/clang/Driver/ToolChain.h | 39 +- include/clang/Driver/Types.def | 1 + include/clang/Frontend/ASTConsumers.h | 10 +- include/clang/Frontend/ASTUnit.h | 151 +- include/clang/Frontend/Analyses.def | 40 +- include/clang/Frontend/AnalyzerOptions.h | 15 +- include/clang/Frontend/CodeGenOptions.h | 32 +- include/clang/Frontend/CommandLineSourceLoc.h | 8 +- include/clang/Frontend/CompilerInstance.h | 102 +- include/clang/Frontend/CompilerInvocation.h | 35 +- include/clang/Frontend/DeclXML.def | 5 + include/clang/Frontend/DependencyOutputOptions.h | 10 +- include/clang/Frontend/DiagnosticOptions.h | 4 - include/clang/Frontend/FrontendAction.h | 7 +- include/clang/Frontend/FrontendActions.h | 13 +- include/clang/Frontend/FrontendDiagnostic.h | 2 +- include/clang/Frontend/FrontendOptions.h | 16 +- include/clang/Frontend/HeaderSearchOptions.h | 3 + include/clang/Frontend/LangStandards.def | 5 + include/clang/Frontend/MultiplexConsumer.h | 54 + include/clang/Frontend/PreprocessorOptions.h | 17 +- include/clang/Frontend/PreprocessorOutputOptions.h | 2 - include/clang/Frontend/StmtXML.def | 7 - include/clang/Frontend/TypeXML.def | 10 +- include/clang/Frontend/Utils.h | 12 + include/clang/Frontend/VerifyDiagnosticsClient.h | 4 - include/clang/Lex/CMakeLists.txt | 6 + include/clang/Lex/ExternalPreprocessorSource.h | 3 + include/clang/Lex/HeaderMap.h | 2 +- include/clang/Lex/HeaderSearch.h | 61 +- include/clang/Lex/LexDiagnostic.h | 2 +- include/clang/Lex/Lexer.h | 53 + include/clang/Lex/LiteralSupport.h | 31 +- include/clang/Lex/MacroInfo.h | 13 + include/clang/Lex/Makefile | 13 + include/clang/Lex/PPCallbacks.h | 139 +- include/clang/Lex/PTHManager.h | 6 +- include/clang/Lex/Pragma.h | 31 +- include/clang/Lex/PreprocessingRecord.h | 93 +- include/clang/Lex/Preprocessor.h | 106 +- include/clang/Lex/PreprocessorLexer.h | 12 + include/clang/Lex/Token.h | 42 +- include/clang/Makefile | 2 +- include/clang/Parse/ParseDiagnostic.h | 2 +- include/clang/Parse/Parser.h | 358 +++- include/clang/Rewrite/ASTConsumers.h | 2 +- include/clang/Rewrite/FixItRewriter.h | 2 +- include/clang/Sema/AttributeList.h | 108 +- include/clang/Sema/CodeCompleteConsumer.h | 282 +-- include/clang/Sema/DeclSpec.h | 328 +++- include/clang/Sema/DelayedDiagnostic.h | 41 +- include/clang/Sema/ExternalSemaSource.h | 8 +- include/clang/Sema/Initialization.h | 55 +- include/clang/Sema/Lookup.h | 20 +- include/clang/Sema/Overload.h | 48 +- include/clang/Sema/Ownership.h | 9 +- include/clang/Sema/ParsedTemplate.h | 30 +- include/clang/Sema/Scope.h | 23 +- include/clang/Sema/ScopeInfo.h | 38 +- include/clang/Sema/Sema.h | 1325 ++++++++++---- include/clang/Sema/SemaDiagnostic.h | 2 +- include/clang/Sema/Template.h | 211 ++- include/clang/Sema/TemplateDeduction.h | 25 +- include/clang/Serialization/ASTBitCodes.h | 135 +- .../Serialization/ASTDeserializationListener.h | 21 +- include/clang/Serialization/ASTReader.h | 484 +++-- .../clang/Serialization/ASTSerializationListener.h | 44 + include/clang/Serialization/ASTWriter.h | 230 ++- .../clang/StaticAnalyzer/Checkers/CheckerBase.td | 38 + .../StaticAnalyzer/Checkers/DereferenceChecker.h | 35 + .../clang/StaticAnalyzer/Checkers/LocalCheckers.h | 51 + .../StaticAnalyzer/Core/BugReporter/BugReporter.h | 486 +++++ .../StaticAnalyzer/Core/BugReporter/BugType.h | 76 + .../Core/BugReporter/PathDiagnostic.h | 500 +++++ include/clang/StaticAnalyzer/Core/CheckerManager.h | 109 ++ .../clang/StaticAnalyzer/Core/CheckerProvider.h | 54 + include/clang/StaticAnalyzer/Core/CheckerV2.h | 93 + .../StaticAnalyzer/Core/PathDiagnosticClients.h | 42 + .../Core/PathSensitive/AnalysisManager.h | 220 +++ .../Core/PathSensitive/BasicValueFactory.h | 201 ++ .../Core/PathSensitive/BlockCounter.h | 59 + .../StaticAnalyzer/Core/PathSensitive/Checker.h | 324 ++++ .../Core/PathSensitive/CheckerHelpers.h | 43 + .../Core/PathSensitive/CheckerVisitor.def | 48 + .../Core/PathSensitive/CheckerVisitor.h | 103 ++ .../Core/PathSensitive/ConstraintManager.h | 76 + .../StaticAnalyzer/Core/PathSensitive/CoreEngine.h | 546 ++++++ .../Core/PathSensitive/Environment.h | 106 ++ .../Core/PathSensitive/ExplodedGraph.h | 469 +++++ .../StaticAnalyzer/Core/PathSensitive/ExprEngine.h | 550 ++++++ .../Core/PathSensitive/ExprEngineBuilders.h | 80 + .../StaticAnalyzer/Core/PathSensitive/GRState.h | 793 ++++++++ .../Core/PathSensitive/GRStateTrait.h | 165 ++ .../StaticAnalyzer/Core/PathSensitive/MemRegion.h | 1092 +++++++++++ .../Core/PathSensitive/ObjCMessage.h | 210 +++ .../Core/PathSensitive/SValBuilder.h | 258 +++ .../StaticAnalyzer/Core/PathSensitive/SVals.h | 544 ++++++ .../StaticAnalyzer/Core/PathSensitive/Store.h | 307 ++++ .../StaticAnalyzer/Core/PathSensitive/SubEngine.h | 116 ++ .../Core/PathSensitive/SummaryManager.h | 61 + .../Core/PathSensitive/SymbolManager.h | 489 +++++ .../Core/PathSensitive/TransferFuncs.h | 93 + .../StaticAnalyzer/Core/PathSensitive/WorkList.h | 101 ++ .../StaticAnalyzer/Frontend/CheckerRegistration.h | 26 + .../StaticAnalyzer/Frontend/FrontendActions.h | 33 + 246 files changed, 22351 insertions(+), 13390 deletions(-) create mode 100644 include/clang/AST/ASTMutationListener.h create mode 100644 include/clang/AST/EvaluatedExprVisitor.h delete mode 100644 include/clang/AST/FullExpr.h create mode 100644 include/clang/AST/Mangle.h delete mode 100644 include/clang/AST/TypeLocBuilder.h create mode 100644 include/clang/Analysis/Analyses/UninitializedValuesV2.h create mode 100644 include/clang/Analysis/DomainSpecific/CocoaConventions.h create mode 100644 include/clang/Basic/ABI.h create mode 100644 include/clang/Basic/DiagnosticIDs.h create mode 100644 include/clang/Basic/FileSystemOptions.h create mode 100644 include/clang/Basic/FileSystemStatCache.h create mode 100644 include/clang/Basic/OpenCLExtensions.def create mode 100644 include/clang/Basic/Visibility.h delete mode 100644 include/clang/Checker/AnalysisConsumer.h delete mode 100644 include/clang/Checker/BugReporter/BugReporter.h delete mode 100644 include/clang/Checker/BugReporter/BugType.h delete mode 100644 include/clang/Checker/BugReporter/PathDiagnostic.h delete mode 100644 include/clang/Checker/Checkers/DereferenceChecker.h delete mode 100644 include/clang/Checker/Checkers/LocalCheckers.h delete mode 100644 include/clang/Checker/DomainSpecific/CocoaConventions.h delete mode 100644 include/clang/Checker/FrontendActions.h delete mode 100644 include/clang/Checker/ManagerRegistry.h delete mode 100644 include/clang/Checker/PathDiagnosticClients.h delete mode 100644 include/clang/Checker/PathSensitive/AnalysisManager.h delete mode 100644 include/clang/Checker/PathSensitive/BasicValueFactory.h delete mode 100644 include/clang/Checker/PathSensitive/Checker.h delete mode 100644 include/clang/Checker/PathSensitive/CheckerHelpers.h delete mode 100644 include/clang/Checker/PathSensitive/CheckerVisitor.def delete mode 100644 include/clang/Checker/PathSensitive/CheckerVisitor.h delete mode 100644 include/clang/Checker/PathSensitive/ConstraintManager.h delete mode 100644 include/clang/Checker/PathSensitive/Environment.h delete mode 100644 include/clang/Checker/PathSensitive/ExplodedGraph.h delete mode 100644 include/clang/Checker/PathSensitive/GRAuditor.h delete mode 100644 include/clang/Checker/PathSensitive/GRBlockCounter.h delete mode 100644 include/clang/Checker/PathSensitive/GRCoreEngine.h delete mode 100644 include/clang/Checker/PathSensitive/GRExprEngine.h delete mode 100644 include/clang/Checker/PathSensitive/GRExprEngineBuilders.h delete mode 100644 include/clang/Checker/PathSensitive/GRSimpleAPICheck.h delete mode 100644 include/clang/Checker/PathSensitive/GRState.h delete mode 100644 include/clang/Checker/PathSensitive/GRStateTrait.h delete mode 100644 include/clang/Checker/PathSensitive/GRSubEngine.h delete mode 100644 include/clang/Checker/PathSensitive/GRTransferFuncs.h delete mode 100644 include/clang/Checker/PathSensitive/GRWorkList.h delete mode 100644 include/clang/Checker/PathSensitive/MemRegion.h delete mode 100644 include/clang/Checker/PathSensitive/SVals.h delete mode 100644 include/clang/Checker/PathSensitive/SValuator.h delete mode 100644 include/clang/Checker/PathSensitive/Store.h delete mode 100644 include/clang/Checker/PathSensitive/SummaryManager.h delete mode 100644 include/clang/Checker/PathSensitive/SymbolManager.h delete mode 100644 include/clang/Checker/PathSensitive/ValueManager.h create mode 100644 include/clang/Config/config.h.cmake create mode 100644 include/clang/Frontend/MultiplexConsumer.h create mode 100644 include/clang/Lex/CMakeLists.txt create mode 100644 include/clang/Lex/Makefile create mode 100644 include/clang/Serialization/ASTSerializationListener.h create mode 100644 include/clang/StaticAnalyzer/Checkers/CheckerBase.td create mode 100644 include/clang/StaticAnalyzer/Checkers/DereferenceChecker.h create mode 100644 include/clang/StaticAnalyzer/Checkers/LocalCheckers.h create mode 100644 include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h create mode 100644 include/clang/StaticAnalyzer/Core/BugReporter/BugType.h create mode 100644 include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h create mode 100644 include/clang/StaticAnalyzer/Core/CheckerManager.h create mode 100644 include/clang/StaticAnalyzer/Core/CheckerProvider.h create mode 100644 include/clang/StaticAnalyzer/Core/CheckerV2.h create mode 100644 include/clang/StaticAnalyzer/Core/PathDiagnosticClients.h create mode 100644 include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h create mode 100644 include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h create mode 100644 include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h create mode 100644 include/clang/StaticAnalyzer/Core/PathSensitive/Checker.h create mode 100644 include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h create mode 100644 include/clang/StaticAnalyzer/Core/PathSensitive/CheckerVisitor.def create mode 100644 include/clang/StaticAnalyzer/Core/PathSensitive/CheckerVisitor.h create mode 100644 include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h create mode 100644 include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h create mode 100644 include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h create mode 100644 include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h create mode 100644 include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h create mode 100644 include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngineBuilders.h create mode 100644 include/clang/StaticAnalyzer/Core/PathSensitive/GRState.h create mode 100644 include/clang/StaticAnalyzer/Core/PathSensitive/GRStateTrait.h create mode 100644 include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h create mode 100644 include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h create mode 100644 include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h create mode 100644 include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h create mode 100644 include/clang/StaticAnalyzer/Core/PathSensitive/Store.h create mode 100644 include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h create mode 100644 include/clang/StaticAnalyzer/Core/PathSensitive/SummaryManager.h create mode 100644 include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h create mode 100644 include/clang/StaticAnalyzer/Core/PathSensitive/TransferFuncs.h create mode 100644 include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h create mode 100644 include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h create mode 100644 include/clang/StaticAnalyzer/Frontend/FrontendActions.h (limited to 'include/clang') diff --git a/include/clang/AST/ASTConsumer.h b/include/clang/AST/ASTConsumer.h index 84833c0..08ee4ef 100644 --- a/include/clang/AST/ASTConsumer.h +++ b/include/clang/AST/ASTConsumer.h @@ -19,6 +19,7 @@ namespace clang { class CXXRecordDecl; class DeclGroupRef; class HandleTagDeclDefinition; + class ASTMutationListener; class ASTDeserializationListener; // layering violation because void* is ugly class SemaConsumer; // layering violation required for safe SemaConsumer class TagDecl; @@ -86,10 +87,13 @@ public: /// it was actually used. virtual void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) {} + /// \brief If the consumer is interested in entities getting modified after + /// their initial creation, it should return a pointer to + /// a GetASTMutationListener here. + virtual ASTMutationListener *GetASTMutationListener() { return 0; } + /// \brief If the consumer is interested in entities being deserialized from /// AST files, it should return a pointer to a ASTDeserializationListener here - /// - /// The return type is void* because ASTDS lives in Frontend. virtual ASTDeserializationListener *GetASTDeserializationListener() { return 0; } /// PrintStats - If desired, print any statistics. diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index ae4ee94..0e88713 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -45,6 +45,7 @@ namespace clang { class Diagnostic; class Expr; class ExternalASTSource; + class ASTMutationListener; class IdentifierTable; class SelectorTable; class SourceManager; @@ -56,6 +57,7 @@ namespace clang { class CXXRecordDecl; class Decl; class FieldDecl; + class MangleContext; class ObjCIvarDecl; class ObjCIvarRefExpr; class ObjCPropertyDecl; @@ -78,49 +80,61 @@ namespace clang { class ASTContext { ASTContext &this_() { return *this; } - std::vector Types; - llvm::FoldingSet ExtQualNodes; - llvm::FoldingSet ComplexTypes; - llvm::FoldingSet PointerTypes; - llvm::FoldingSet BlockPointerTypes; - llvm::FoldingSet LValueReferenceTypes; - llvm::FoldingSet RValueReferenceTypes; - llvm::FoldingSet MemberPointerTypes; - llvm::FoldingSet ConstantArrayTypes; - llvm::FoldingSet IncompleteArrayTypes; - std::vector VariableArrayTypes; - llvm::FoldingSet DependentSizedArrayTypes; - llvm::FoldingSet DependentSizedExtVectorTypes; - llvm::FoldingSet VectorTypes; - llvm::FoldingSet FunctionNoProtoTypes; - llvm::FoldingSet FunctionProtoTypes; - llvm::FoldingSet DependentTypeOfExprTypes; - llvm::FoldingSet DependentDecltypeTypes; - llvm::FoldingSet TemplateTypeParmTypes; - llvm::FoldingSet SubstTemplateTypeParmTypes; - llvm::ContextualFoldingSet + mutable std::vector Types; + mutable llvm::FoldingSet ExtQualNodes; + mutable llvm::FoldingSet ComplexTypes; + mutable llvm::FoldingSet PointerTypes; + mutable llvm::FoldingSet BlockPointerTypes; + mutable llvm::FoldingSet LValueReferenceTypes; + mutable llvm::FoldingSet RValueReferenceTypes; + mutable llvm::FoldingSet MemberPointerTypes; + mutable llvm::FoldingSet ConstantArrayTypes; + mutable llvm::FoldingSet IncompleteArrayTypes; + mutable std::vector VariableArrayTypes; + mutable llvm::FoldingSet DependentSizedArrayTypes; + mutable llvm::FoldingSet + DependentSizedExtVectorTypes; + mutable llvm::FoldingSet VectorTypes; + mutable llvm::FoldingSet FunctionNoProtoTypes; + mutable llvm::FoldingSet FunctionProtoTypes; + mutable llvm::FoldingSet DependentTypeOfExprTypes; + mutable llvm::FoldingSet DependentDecltypeTypes; + mutable llvm::FoldingSet TemplateTypeParmTypes; + mutable llvm::FoldingSet + SubstTemplateTypeParmTypes; + mutable llvm::FoldingSet + SubstTemplateTypeParmPackTypes; + mutable llvm::ContextualFoldingSet TemplateSpecializationTypes; - llvm::FoldingSet ElaboratedTypes; - llvm::FoldingSet DependentNameTypes; - llvm::ContextualFoldingSet + mutable llvm::FoldingSet ParenTypes; + mutable llvm::FoldingSet ElaboratedTypes; + mutable llvm::FoldingSet DependentNameTypes; + mutable llvm::ContextualFoldingSet DependentTemplateSpecializationTypes; - llvm::FoldingSet ObjCObjectTypes; - llvm::FoldingSet ObjCObjectPointerTypes; - - llvm::FoldingSet QualifiedTemplateNames; - llvm::FoldingSet DependentTemplateNames; - + llvm::FoldingSet PackExpansionTypes; + mutable llvm::FoldingSet ObjCObjectTypes; + mutable llvm::FoldingSet ObjCObjectPointerTypes; + llvm::FoldingSet AttributedTypes; + + mutable llvm::FoldingSet QualifiedTemplateNames; + mutable llvm::FoldingSet DependentTemplateNames; + mutable llvm::FoldingSet + SubstTemplateTemplateParmPacks; + /// \brief The set of nested name specifiers. /// /// This set is managed by the NestedNameSpecifier class. - llvm::FoldingSet NestedNameSpecifiers; - NestedNameSpecifier *GlobalNestedNameSpecifier; + mutable llvm::FoldingSet NestedNameSpecifiers; + mutable NestedNameSpecifier *GlobalNestedNameSpecifier; friend class NestedNameSpecifier; /// ASTRecordLayouts - A cache mapping from RecordDecls to ASTRecordLayouts. /// This is lazily created. This is intentionally not serialized. - llvm::DenseMap ASTRecordLayouts; - llvm::DenseMap ObjCLayouts; + mutable llvm::DenseMap + ASTRecordLayouts; + mutable llvm::DenseMap + ObjCLayouts; /// KeyFunctions - A cache mapping from CXXRecordDecls to key functions. llvm::DenseMap KeyFunctions; @@ -128,6 +142,9 @@ class ASTContext { /// \brief Mapping from ObjCContainers to their ObjCImplementations. llvm::DenseMap ObjCImpls; + /// \brief Mapping from __block VarDecls to their copy initialization expr. + llvm::DenseMap BlockVarCopyInits; + /// \brief Representation of a "canonical" template template parameter that /// is used in canonical template names. class CanonicalTemplateTemplateParm : public llvm::FoldingSetNode { @@ -144,10 +161,11 @@ class ASTContext { static void Profile(llvm::FoldingSetNodeID &ID, TemplateTemplateParmDecl *Parm); }; - llvm::FoldingSet CanonTemplateTemplateParms; + mutable llvm::FoldingSet + CanonTemplateTemplateParms; - TemplateTemplateParmDecl *getCanonicalTemplateTemplateParmDecl( - TemplateTemplateParmDecl *TTP); + TemplateTemplateParmDecl * + getCanonicalTemplateTemplateParmDecl(TemplateTemplateParmDecl *TTP) const; /// \brief Whether __[u]int128_t identifier is installed. bool IsInt128Installed; @@ -171,11 +189,11 @@ class ASTContext { QualType ObjCClassTypedefType; QualType ObjCConstantStringType; - RecordDecl *CFConstantStringTypeDecl; + mutable RecordDecl *CFConstantStringTypeDecl; - RecordDecl *NSConstantStringTypeDecl; + mutable RecordDecl *NSConstantStringTypeDecl; - RecordDecl *ObjCFastEnumerationStateTypeDecl; + mutable RecordDecl *ObjCFastEnumerationStateTypeDecl; /// \brief The type for the C FILE type. TypeDecl *FILEDecl; @@ -187,10 +205,13 @@ class ASTContext { TypeDecl *sigjmp_bufDecl; /// \brief Type for the Block descriptor for Blocks CodeGen. - RecordDecl *BlockDescriptorType; + mutable RecordDecl *BlockDescriptorType; /// \brief Type for the Block descriptor for Blocks CodeGen. - RecordDecl *BlockDescriptorExtendedType; + mutable RecordDecl *BlockDescriptorExtendedType; + + /// \brief Declaration for the CUDA cudaConfigureCall function. + FunctionDecl *cudaConfigureCallDecl; TypeSourceInfo NullTypeSourceInfo; @@ -279,7 +300,7 @@ class ASTContext { /// /// AST objects are never destructed; rather, all memory associated with the /// AST objects will be released when the ASTContext itself is destroyed. - llvm::BumpPtrAllocator BumpAlloc; + mutable llvm::BumpPtrAllocator BumpAlloc; /// \brief Allocator for partial diagnostics. PartialDiagnostic::StorageAllocator DiagAllocator; @@ -287,14 +308,17 @@ class ASTContext { /// \brief The current C++ ABI. llvm::OwningPtr ABI; CXXABI *createCXXABI(const TargetInfo &T); - + + friend class ASTDeclReader; + public: const TargetInfo &Target; IdentifierTable &Idents; SelectorTable &Selectors; Builtin::Context &BuiltinInfo; - DeclarationNameTable DeclarationNames; + mutable DeclarationNameTable DeclarationNames; llvm::OwningPtr ExternalSource; + ASTMutationListener *Listener; clang::PrintingPolicy PrintingPolicy; // Typedefs which may be provided defining the structure of Objective-C @@ -305,10 +329,10 @@ public: SourceManager& getSourceManager() { return SourceMgr; } const SourceManager& getSourceManager() const { return SourceMgr; } - void *Allocate(unsigned Size, unsigned Align = 8) { + void *Allocate(unsigned Size, unsigned Align = 8) const { return BumpAlloc.Allocate(Size, Align); } - void Deallocate(void *Ptr) { } + void Deallocate(void *Ptr) const { } PartialDiagnostic::StorageAllocator &getDiagAllocator() { return DiagAllocator; @@ -316,6 +340,8 @@ public: const LangOptions& getLangOptions() const { return LangOpts; } + Diagnostic &getDiagnostics() const; + FullSourceLoc getFullLoc(SourceLocation Loc) const { return FullSourceLoc(Loc,SourceMgr); } @@ -388,7 +414,6 @@ public: CanQualType VoidPtrTy, NullPtrTy; CanQualType OverloadTy; CanQualType DependentTy; - CanQualType UndeducedAutoTy; CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy; ASTContext(const LangOptions& LOpts, SourceManager &SM, const TargetInfo &t, @@ -409,6 +434,19 @@ public: /// with this AST context, if any. ExternalASTSource *getExternalSource() const { return ExternalSource.get(); } + /// \brief Attach an AST mutation listener to the AST context. + /// + /// The AST mutation listener provides the ability to track modifications to + /// the abstract syntax tree entities committed after they were initially + /// created. + void setASTMutationListener(ASTMutationListener *Listener) { + this->Listener = Listener; + } + + /// \brief Retrieve a pointer to the AST mutation listener associated + /// with this AST context, if any. + ASTMutationListener *getASTMutationListener() const { return Listener; } + void PrintStats() const; const std::vector& getTypes() const { return Types; } @@ -418,9 +456,9 @@ public: private: /// getExtQualType - Return a type with extended qualifiers. - QualType getExtQualType(const Type *Base, Qualifiers Quals); + QualType getExtQualType(const Type *Base, Qualifiers Quals) const; - QualType getTypeDeclTypeSlow(const TypeDecl *Decl); + QualType getTypeDeclTypeSlow(const TypeDecl *Decl) const; public: /// getAddSpaceQualType - Return the uniqued reference to the type for an @@ -428,24 +466,26 @@ public: /// The resulting type has a union of the qualifiers from T and the address /// space. If T already has an address space specifier, it is silently /// replaced. - QualType getAddrSpaceQualType(QualType T, unsigned AddressSpace); + QualType getAddrSpaceQualType(QualType T, unsigned AddressSpace) const; /// getObjCGCQualType - Returns the uniqued reference to the type for an /// objc gc qualified type. The retulting type has a union of the qualifiers /// from T and the gc attribute. - QualType getObjCGCQualType(QualType T, Qualifiers::GC gcAttr); + QualType getObjCGCQualType(QualType T, Qualifiers::GC gcAttr) const; /// getRestrictType - Returns the uniqued reference to the type for a /// 'restrict' qualified type. The resulting type has a union of the /// qualifiers from T and 'restrict'. - QualType getRestrictType(QualType T) { + QualType getRestrictType(QualType T) const { return T.withFastQualifiers(Qualifiers::Restrict); } /// getVolatileType - Returns the uniqued reference to the type for a /// 'volatile' qualified type. The resulting type has a union of the /// qualifiers from T and 'volatile'. - QualType getVolatileType(QualType T); + QualType getVolatileType(QualType T) const { + return T.withFastQualifiers(Qualifiers::Volatile); + } /// getConstType - Returns the uniqued reference to the type for a /// 'const' qualified type. The resulting type has a union of the @@ -453,44 +493,33 @@ public: /// /// It can be reasonably expected that this will always be /// equivalent to calling T.withConst(). - QualType getConstType(QualType T) { return T.withConst(); } - - /// getNoReturnType - Add or remove the noreturn attribute to the given type - /// which must be a FunctionType or a pointer to an allowable type or a - /// BlockPointer. - QualType getNoReturnType(QualType T, bool AddNoReturn = true); - - /// getCallConvType - Adds the specified calling convention attribute to - /// the given type, which must be a FunctionType or a pointer to an - /// allowable type. - QualType getCallConvType(QualType T, CallingConv CallConv); + QualType getConstType(QualType T) const { return T.withConst(); } - /// getRegParmType - Sets the specified regparm attribute to - /// the given type, which must be a FunctionType or a pointer to an - /// allowable type. - QualType getRegParmType(QualType T, unsigned RegParm); + /// adjustFunctionType - Change the ExtInfo on a function type. + const FunctionType *adjustFunctionType(const FunctionType *Fn, + FunctionType::ExtInfo EInfo); /// getComplexType - Return the uniqued reference to the type for a complex /// number with the specified element type. - QualType getComplexType(QualType T); - CanQualType getComplexType(CanQualType T) { + QualType getComplexType(QualType T) const; + CanQualType getComplexType(CanQualType T) const { return CanQualType::CreateUnsafe(getComplexType((QualType) T)); } /// getPointerType - Return the uniqued reference to the type for a pointer to /// the specified type. - QualType getPointerType(QualType T); - CanQualType getPointerType(CanQualType T) { + QualType getPointerType(QualType T) const; + CanQualType getPointerType(CanQualType T) const { return CanQualType::CreateUnsafe(getPointerType((QualType) T)); } /// getBlockPointerType - Return the uniqued reference to the type for a block /// of the specified type. - QualType getBlockPointerType(QualType T); + QualType getBlockPointerType(QualType T) const; /// This gets the struct used to keep track of the descriptor for pointer to /// blocks. - QualType getBlockDescriptorType(); + QualType getBlockDescriptorType() const; // Set the type for a Block descriptor type. void setBlockDescriptorType(QualType T); @@ -503,48 +532,56 @@ public: /// This gets the struct used to keep track of the extended descriptor for /// pointer to blocks. - QualType getBlockDescriptorExtendedType(); + QualType getBlockDescriptorExtendedType() const; // Set the type for a Block descriptor extended type. void setBlockDescriptorExtendedType(QualType T); /// Get the BlockDescriptorExtendedType type, or NULL if it hasn't yet been /// built. - QualType getRawBlockdescriptorExtendedType() { + QualType getRawBlockdescriptorExtendedType() const { if (BlockDescriptorExtendedType) return getTagDeclType(BlockDescriptorExtendedType); return QualType(); } + void setcudaConfigureCallDecl(FunctionDecl *FD) { + cudaConfigureCallDecl = FD; + } + FunctionDecl *getcudaConfigureCallDecl() { + return cudaConfigureCallDecl; + } + /// This gets the struct used to keep track of pointer to blocks, complete /// with captured variables. QualType getBlockParmType(bool BlockHasCopyDispose, - llvm::SmallVectorImpl &Layout); + llvm::SmallVectorImpl &Layout) const; /// This builds the struct used for __block variables. - QualType BuildByRefType(llvm::StringRef DeclName, QualType Ty); + QualType BuildByRefType(llvm::StringRef DeclName, QualType Ty) const; /// Returns true iff we need copy/dispose helpers for the given type. - bool BlockRequiresCopying(QualType Ty); + bool BlockRequiresCopying(QualType Ty) const; /// getLValueReferenceType - Return the uniqued reference to the type for an /// lvalue reference to the specified type. - QualType getLValueReferenceType(QualType T, bool SpelledAsLValue = true); + QualType getLValueReferenceType(QualType T, bool SpelledAsLValue = true) + const; /// getRValueReferenceType - Return the uniqued reference to the type for an /// rvalue reference to the specified type. - QualType getRValueReferenceType(QualType T); + QualType getRValueReferenceType(QualType T) const; /// getMemberPointerType - Return the uniqued reference to the type for a /// member pointer to the specified type in the specified class. The class /// is a Type because it could be a dependent name. - QualType getMemberPointerType(QualType T, const Type *Cls); + QualType getMemberPointerType(QualType T, const Type *Cls) const; /// getVariableArrayType - Returns a non-unique reference to the type for a /// variable array of the specified element type. QualType getVariableArrayType(QualType EltTy, Expr *NumElts, ArrayType::ArraySizeModifier ASM, - unsigned EltTypeQuals, - SourceRange Brackets); + unsigned IndexTypeQuals, + SourceRange Brackets) const; /// getDependentSizedArrayType - Returns a non-unique reference to /// the type for a dependently-sized array of the specified element @@ -552,30 +589,34 @@ public: /// comparable, at some point. QualType getDependentSizedArrayType(QualType EltTy, Expr *NumElts, ArrayType::ArraySizeModifier ASM, - unsigned EltTypeQuals, - SourceRange Brackets); + unsigned IndexTypeQuals, + SourceRange Brackets) const; /// getIncompleteArrayType - Returns a unique reference to the type for a /// incomplete array of the specified element type. QualType getIncompleteArrayType(QualType EltTy, ArrayType::ArraySizeModifier ASM, - unsigned EltTypeQuals); + unsigned IndexTypeQuals) const; /// getConstantArrayType - Return the unique reference to the type for a /// constant array of the specified element type. QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, ArrayType::ArraySizeModifier ASM, - unsigned EltTypeQuals); + unsigned IndexTypeQuals) const; + + /// getVariableArrayDecayedType - Returns a vla type where known sizes + /// are replaced with [*]. + QualType getVariableArrayDecayedType(QualType Ty) const; /// getVectorType - Return the unique reference to a vector type of /// the specified element type and size. VectorType must be a built-in type. QualType getVectorType(QualType VectorType, unsigned NumElts, - VectorType::AltiVecSpecific AltiVecSpec); + VectorType::VectorKind VecKind) const; /// getExtVectorType - Return the unique reference to an extended vector type /// of the specified element type and size. VectorType must be a built-in /// type. - QualType getExtVectorType(QualType VectorType, unsigned NumElts); + QualType getExtVectorType(QualType VectorType, unsigned NumElts) const; /// getDependentSizedExtVectorType - Returns a non-unique reference to /// the type for a dependently-sized vector of the specified element @@ -583,30 +624,27 @@ public: /// comparable, at some point. QualType getDependentSizedExtVectorType(QualType VectorType, Expr *SizeExpr, - SourceLocation AttrLoc); + SourceLocation AttrLoc) const; /// getFunctionNoProtoType - Return a K&R style C function type like 'int()'. /// QualType getFunctionNoProtoType(QualType ResultTy, - const FunctionType::ExtInfo &Info); + const FunctionType::ExtInfo &Info) const; - QualType getFunctionNoProtoType(QualType ResultTy) { + QualType getFunctionNoProtoType(QualType ResultTy) const { return getFunctionNoProtoType(ResultTy, FunctionType::ExtInfo()); } - /// getFunctionType - Return a normal function type with a typed argument - /// list. isVariadic indicates whether the argument list includes '...'. - QualType getFunctionType(QualType ResultTy, const QualType *ArgArray, - unsigned NumArgs, bool isVariadic, - unsigned TypeQuals, bool hasExceptionSpec, - bool hasAnyExceptionSpec, - unsigned NumExs, const QualType *ExArray, - const FunctionType::ExtInfo &Info); + /// getFunctionType - Return a normal function type with a typed + /// argument list. + QualType getFunctionType(QualType ResultTy, + const QualType *Args, unsigned NumArgs, + const FunctionProtoType::ExtProtoInfo &EPI) const; /// getTypeDeclType - Return the unique reference to the type for /// the specified type declaration. QualType getTypeDeclType(const TypeDecl *Decl, - const TypeDecl *PrevDecl = 0) { + const TypeDecl *PrevDecl = 0) const { assert(Decl && "Passed null for Decl param"); if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0); @@ -621,77 +659,93 @@ public: /// getTypedefType - Return the unique reference to the type for the /// specified typename decl. - QualType getTypedefType(const TypedefDecl *Decl, QualType Canon = QualType()); + QualType getTypedefType(const TypedefDecl *Decl, QualType Canon = QualType()) + const; + + QualType getRecordType(const RecordDecl *Decl) const; - QualType getRecordType(const RecordDecl *Decl); + QualType getEnumType(const EnumDecl *Decl) const; - QualType getEnumType(const EnumDecl *Decl); + QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType TST) const; - QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType TST); + QualType getAttributedType(AttributedType::Kind attrKind, + QualType modifiedType, + QualType equivalentType); QualType getSubstTemplateTypeParmType(const TemplateTypeParmType *Replaced, - QualType Replacement); + QualType Replacement) const; + QualType getSubstTemplateTypeParmPackType( + const TemplateTypeParmType *Replaced, + const TemplateArgument &ArgPack); QualType getTemplateTypeParmType(unsigned Depth, unsigned Index, bool ParameterPack, - IdentifierInfo *Name = 0); + IdentifierInfo *Name = 0) const; QualType getTemplateSpecializationType(TemplateName T, const TemplateArgument *Args, unsigned NumArgs, - QualType Canon = QualType()); + QualType Canon = QualType()) const; QualType getCanonicalTemplateSpecializationType(TemplateName T, const TemplateArgument *Args, - unsigned NumArgs); + unsigned NumArgs) const; QualType getTemplateSpecializationType(TemplateName T, const TemplateArgumentListInfo &Args, - QualType Canon = QualType()); + QualType Canon = QualType()) const; TypeSourceInfo * getTemplateSpecializationTypeInfo(TemplateName T, SourceLocation TLoc, const TemplateArgumentListInfo &Args, - QualType Canon = QualType()); + QualType Canon = QualType()) const; + + QualType getParenType(QualType NamedType) const; QualType getElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, - QualType NamedType); + QualType NamedType) const; QualType getDependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, const IdentifierInfo *Name, - QualType Canon = QualType()); + QualType Canon = QualType()) const; QualType getDependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, const IdentifierInfo *Name, - const TemplateArgumentListInfo &Args); + const TemplateArgumentListInfo &Args) const; QualType getDependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, const IdentifierInfo *Name, unsigned NumArgs, - const TemplateArgument *Args); + const TemplateArgument *Args) const; + + QualType getPackExpansionType(QualType Pattern, + llvm::Optional NumExpansions); - QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl); + QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl) const; QualType getObjCObjectType(QualType Base, ObjCProtocolDecl * const *Protocols, - unsigned NumProtocols); + unsigned NumProtocols) const; /// getObjCObjectPointerType - Return a ObjCObjectPointerType type /// for the given ObjCObjectType. - QualType getObjCObjectPointerType(QualType OIT); + QualType getObjCObjectPointerType(QualType OIT) const; /// getTypeOfType - GCC extension. - QualType getTypeOfExprType(Expr *e); - QualType getTypeOfType(QualType t); + QualType getTypeOfExprType(Expr *e) const; + QualType getTypeOfType(QualType t) const; /// getDecltypeType - C++0x decltype. - QualType getDecltypeType(Expr *e); + QualType getDecltypeType(Expr *e) const; + + /// getAutoType - C++0x deduced auto type. + QualType getAutoType(QualType DeducedType) const; /// getTagDeclType - Return the unique reference to the type for the /// specified TagDecl (struct/union/class/enum) decl. - QualType getTagDeclType(const TagDecl *Decl); + QualType getTagDeclType(const TagDecl *Decl) const; /// getSizeType - Return the unique type for "size_t" (C99 7.17), defined /// in . The sizeof operator requires this (C99 6.5.3.4p4). @@ -716,14 +770,14 @@ public: // getCFConstantStringType - Return the C structure type used to represent // constant CFStrings. - QualType getCFConstantStringType(); + QualType getCFConstantStringType() const; // getNSConstantStringType - Return the C structure type used to represent // constant NSStrings. - QualType getNSConstantStringType(); + QualType getNSConstantStringType() const; /// Get the structure type used to representation NSStrings, or NULL /// if it hasn't yet been built. - QualType getRawNSConstantStringType() { + QualType getRawNSConstantStringType() const { if (NSConstantStringTypeDecl) return getTagDeclType(NSConstantStringTypeDecl); return QualType(); @@ -733,7 +787,7 @@ public: /// Get the structure type used to representation CFStrings, or NULL /// if it hasn't yet been built. - QualType getRawCFConstantStringType() { + QualType getRawCFConstantStringType() const { if (CFConstantStringTypeDecl) return getTagDeclType(CFConstantStringTypeDecl); return QualType(); @@ -747,11 +801,11 @@ public: } //// This gets the struct used to keep track of fast enumerations. - QualType getObjCFastEnumerationStateType(); + QualType getObjCFastEnumerationStateType() const; /// Get the ObjCFastEnumerationState type, or NULL if it hasn't yet /// been built. - QualType getRawObjCFastEnumerationStateType() { + QualType getRawObjCFastEnumerationStateType() const { if (ObjCFastEnumerationStateTypeDecl) return getTagDeclType(ObjCFastEnumerationStateTypeDecl); return QualType(); @@ -763,7 +817,7 @@ public: void setFILEDecl(TypeDecl *FILEDecl) { this->FILEDecl = FILEDecl; } /// \brief Retrieve the C FILE type. - QualType getFILEType() { + QualType getFILEType() const { if (FILEDecl) return getTypeDeclType(FILEDecl); return QualType(); @@ -775,7 +829,7 @@ public: } /// \brief Retrieve the C jmp_buf type. - QualType getjmp_bufType() { + QualType getjmp_bufType() const { if (jmp_bufDecl) return getTypeDeclType(jmp_bufDecl); return QualType(); @@ -787,17 +841,22 @@ public: } /// \brief Retrieve the C sigjmp_buf type. - QualType getsigjmp_bufType() { + QualType getsigjmp_bufType() const { if (sigjmp_bufDecl) return getTypeDeclType(sigjmp_bufDecl); return QualType(); } + /// \brief The result type of logical operations, '<', '>', '!=', etc. + QualType getLogicalOperationType() const { + return getLangOptions().CPlusPlus ? BoolTy : IntTy; + } + /// getObjCEncodingForType - Emit the ObjC type encoding for the /// given type into \arg S. If \arg NameFields is specified then /// record field names are also encoded. void getObjCEncodingForType(QualType t, std::string &S, - const FieldDecl *Field=0); + const FieldDecl *Field=0) const; void getLegacyIntegralTypeEncoding(QualType &t) const; @@ -805,13 +864,18 @@ public: void getObjCEncodingForTypeQualifier(Decl::ObjCDeclQualifier QT, std::string &S) const; + /// getObjCEncodingForFunctionDecl - Returns the encoded type for this + //function. This is in the same format as Objective-C method encodings. + void getObjCEncodingForFunctionDecl(const FunctionDecl *Decl, std::string& S); + /// getObjCEncodingForMethodDecl - Return the encoded type for this method /// declaration. - void getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, std::string &S); + void getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, std::string &S) + const; - /// getObjCEncodingForBlockDecl - Return the encoded type for this block + /// getObjCEncodingForBlock - Return the encoded type for this block /// declaration. - void getObjCEncodingForBlock(const BlockExpr *Expr, std::string& S); + std::string getObjCEncodingForBlock(const BlockExpr *blockExpr) const; /// getObjCEncodingForPropertyDecl - Return the encoded type for /// this method declaration. If non-NULL, Container must be either @@ -819,14 +883,14 @@ public: /// only be NULL when getting encodings for protocol properties. void getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD, const Decl *Container, - std::string &S); + std::string &S) const; bool ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto, - ObjCProtocolDecl *rProto); + ObjCProtocolDecl *rProto) const; /// getObjCEncodingTypeSize returns size of type for objective-c encoding /// purpose in characters. - CharUnits getObjCEncodingTypeSize(QualType t); + CharUnits getObjCEncodingTypeSize(QualType t) const; /// \brief Whether __[u]int128_t identifier is installed. bool isInt128Installed() const { return IsInt128Installed; } @@ -854,12 +918,12 @@ public: /// getCVRQualifiedType - Returns a type with additional const, /// volatile, or restrict qualifiers. - QualType getCVRQualifiedType(QualType T, unsigned CVR) { + QualType getCVRQualifiedType(QualType T, unsigned CVR) const { return getQualifiedType(T, Qualifiers::fromCVRMask(CVR)); } /// getQualifiedType - Returns a type with additional qualifiers. - QualType getQualifiedType(QualType T, Qualifiers Qs) { + QualType getQualifiedType(QualType T, Qualifiers Qs) const { if (!Qs.hasNonFastQualifiers()) return T.withFastQualifiers(Qs.getFastQualifiers()); QualifierCollector Qc(Qs); @@ -868,35 +932,41 @@ public: } /// getQualifiedType - Returns a type with additional qualifiers. - QualType getQualifiedType(const Type *T, Qualifiers Qs) { + QualType getQualifiedType(const Type *T, Qualifiers Qs) const { if (!Qs.hasNonFastQualifiers()) return QualType(T, Qs.getFastQualifiers()); return getExtQualType(T, Qs); } DeclarationNameInfo getNameForTemplate(TemplateName Name, - SourceLocation NameLoc); + SourceLocation NameLoc) const; TemplateName getOverloadedTemplateName(UnresolvedSetIterator Begin, - UnresolvedSetIterator End); + UnresolvedSetIterator End) const; TemplateName getQualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword, - TemplateDecl *Template); + TemplateDecl *Template) const; TemplateName getDependentTemplateName(NestedNameSpecifier *NNS, - const IdentifierInfo *Name); + const IdentifierInfo *Name) const; TemplateName getDependentTemplateName(NestedNameSpecifier *NNS, - OverloadedOperatorKind Operator); - + OverloadedOperatorKind Operator) const; + TemplateName getSubstTemplateTemplateParmPack(TemplateTemplateParmDecl *Param, + const TemplateArgument &ArgPack) const; + enum GetBuiltinTypeError { GE_None, //< No error GE_Missing_stdio, //< Missing a type from GE_Missing_setjmp //< Missing a type from }; - /// GetBuiltinType - Return the type for the specified builtin. - QualType GetBuiltinType(unsigned ID, GetBuiltinTypeError &Error); + /// GetBuiltinType - Return the type for the specified builtin. If + /// IntegerConstantArgs is non-null, it is filled in with a bitmask of + /// arguments to the builtin that are required to be integer constant + /// expressions. + QualType GetBuiltinType(unsigned ID, GetBuiltinTypeError &Error, + unsigned *IntegerConstantArgs = 0) const; private: CanQualType getFromTargetType(unsigned Type) const; @@ -909,11 +979,12 @@ public: /// getObjCGCAttr - Returns one of GCNone, Weak or Strong objc's /// garbage collection attribute. /// - Qualifiers::GC getObjCGCAttrKind(const QualType &Ty) const; + Qualifiers::GC getObjCGCAttrKind(QualType Ty) const; - /// areCompatibleVectorTypes - Return true if the given vector types either - /// are of the same unqualified type or if one is GCC and other - equivalent - /// AltiVec vector type. + /// areCompatibleVectorTypes - Return true if the given vector types + /// are of the same unqualified type or if they are equivalent to the same + /// GCC vector type, ignoring whether they are target-specific (AltiVec or + /// Neon) types. bool areCompatibleVectorTypes(QualType FirstVec, QualType SecondVec); /// isObjCNSObjectType - Return true if this is an NSObject object with @@ -930,76 +1001,83 @@ public: /// getTypeInfo - Get the size and alignment of the specified complete type in /// bits. - std::pair getTypeInfo(const Type *T); - std::pair getTypeInfo(QualType T) { + std::pair getTypeInfo(const Type *T) const; + std::pair getTypeInfo(QualType T) const { return getTypeInfo(T.getTypePtr()); } /// getTypeSize - Return the size of the specified type, in bits. This method /// does not work on incomplete types. - uint64_t getTypeSize(QualType T) { + uint64_t getTypeSize(QualType T) const { return getTypeInfo(T).first; } - uint64_t getTypeSize(const Type *T) { + uint64_t getTypeSize(const Type *T) const { return getTypeInfo(T).first; } /// getCharWidth - Return the size of the character type, in bits - uint64_t getCharWidth() { + uint64_t getCharWidth() const { return getTypeSize(CharTy); } + /// toCharUnitsFromBits - Convert a size in bits to a size in characters. + CharUnits toCharUnitsFromBits(int64_t BitSize) const; + + /// toBits - Convert a size in characters to a size in bits. + int64_t toBits(CharUnits CharSize) const; + /// getTypeSizeInChars - Return the size of the specified type, in characters. /// This method does not work on incomplete types. - CharUnits getTypeSizeInChars(QualType T); - CharUnits getTypeSizeInChars(const Type *T); + CharUnits getTypeSizeInChars(QualType T) const; + CharUnits getTypeSizeInChars(const Type *T) const; /// getTypeAlign - Return the ABI-specified alignment of a type, in bits. /// This method does not work on incomplete types. - unsigned getTypeAlign(QualType T) { + unsigned getTypeAlign(QualType T) const { return getTypeInfo(T).second; } - unsigned getTypeAlign(const Type *T) { + unsigned getTypeAlign(const Type *T) const { return getTypeInfo(T).second; } /// getTypeAlignInChars - Return the ABI-specified alignment of a type, in /// characters. This method does not work on incomplete types. - CharUnits getTypeAlignInChars(QualType T); - CharUnits getTypeAlignInChars(const Type *T); + CharUnits getTypeAlignInChars(QualType T) const; + CharUnits getTypeAlignInChars(const Type *T) const; - std::pair getTypeInfoInChars(const Type *T); - std::pair getTypeInfoInChars(QualType T); + std::pair getTypeInfoInChars(const Type *T) const; + std::pair getTypeInfoInChars(QualType T) const; /// getPreferredTypeAlign - Return the "preferred" alignment of the specified /// type for the current target in bits. This can be different than the ABI /// alignment in cases where it is beneficial for performance to overalign /// a data type. - unsigned getPreferredTypeAlign(const Type *T); + unsigned getPreferredTypeAlign(const Type *T) const; /// getDeclAlign - Return a conservative estimate of the alignment of /// the specified decl. Note that bitfields do not have a valid alignment, so /// this method will assert on them. /// If @p RefAsPointee, references are treated like their underlying type /// (for alignof), else they're treated like pointers (for CodeGen). - CharUnits getDeclAlign(const Decl *D, bool RefAsPointee = false); + CharUnits getDeclAlign(const Decl *D, bool RefAsPointee = false) const; /// getASTRecordLayout - Get or compute information about the layout of the /// specified record (struct/union/class), which indicates its size and field /// position information. - const ASTRecordLayout &getASTRecordLayout(const RecordDecl *D); + const ASTRecordLayout &getASTRecordLayout(const RecordDecl *D) const; /// getASTObjCInterfaceLayout - Get or compute information about the /// layout of the specified Objective-C interface. - const ASTRecordLayout &getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D); + const ASTRecordLayout &getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) + const; - void DumpRecordLayout(const RecordDecl *RD, llvm::raw_ostream &OS); + void DumpRecordLayout(const RecordDecl *RD, llvm::raw_ostream &OS) const; /// getASTObjCImplementationLayout - Get or compute information about /// the layout of the specified Objective-C implementation. This may /// differ from the interface if synthesized ivars are present. const ASTRecordLayout & - getASTObjCImplementationLayout(const ObjCImplementationDecl *D); + getASTObjCImplementationLayout(const ObjCImplementationDecl *D) const; /// getKeyFunction - Get the key function for the given record decl, or NULL /// if there isn't one. The key function is, according to the Itanium C++ ABI @@ -1009,13 +1087,18 @@ public: /// of class definition. const CXXMethodDecl *getKeyFunction(const CXXRecordDecl *RD); + bool isNearlyEmpty(const CXXRecordDecl *RD) const; + + MangleContext *createMangleContext(); + void ShallowCollectObjCIvars(const ObjCInterfaceDecl *OI, - llvm::SmallVectorImpl &Ivars); + llvm::SmallVectorImpl &Ivars) + const; void DeepCollectObjCIvars(const ObjCInterfaceDecl *OI, bool leafClass, - llvm::SmallVectorImpl &Ivars); + llvm::SmallVectorImpl &Ivars) const; - unsigned CountNonClassIvars(const ObjCInterfaceDecl *OI); + unsigned CountNonClassIvars(const ObjCInterfaceDecl *OI) const; void CollectInheritedProtocols(const Decl *CDecl, llvm::SmallPtrSet &Protocols); @@ -1029,8 +1112,11 @@ public: /// include typedefs, 'typeof' operators, etc. The returned type is guaranteed /// to be free of any of these, allowing two canonical types to be compared /// for exact equality with a simple pointer comparison. - CanQualType getCanonicalType(QualType T); - const Type *getCanonicalType(const Type *T) { + CanQualType getCanonicalType(QualType T) const { + return CanQualType::CreateUnsafe(T.getCanonicalType()); + } + + const Type *getCanonicalType(const Type *T) const { return T->getCanonicalTypeInternal().getTypePtr(); } @@ -1038,7 +1124,7 @@ public: /// corresponding to the specific potentially non-canonical one. /// Qualifiers are stripped off, functions are turned into function /// pointers, and arrays decay one level into pointers. - CanQualType getCanonicalParamType(QualType T); + CanQualType getCanonicalParamType(QualType T) const; /// \brief Determine whether the given types are equivalent. bool hasSameType(QualType T1, QualType T2) { @@ -1062,13 +1148,8 @@ public: /// \brief Determine whether the given types are equivalent after /// cvr-qualifiers have been removed. bool hasSameUnqualifiedType(QualType T1, QualType T2) { - CanQualType CT1 = getCanonicalType(T1); - CanQualType CT2 = getCanonicalType(T2); - - Qualifiers Quals; - QualType UnqualT1 = getUnqualifiedArrayType(CT1, Quals); - QualType UnqualT2 = getUnqualifiedArrayType(CT2, Quals); - return UnqualT1 == UnqualT2; + return getCanonicalType(T1).getTypePtr() == + getCanonicalType(T2).getTypePtr(); } bool UnwrapSimilarPointerTypes(QualType &T1, QualType &T2); @@ -1097,11 +1178,15 @@ public: /// by declarations in the type system and the canonical type for /// the template type parameter 'T' is template-param-0-0. NestedNameSpecifier * - getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS); + getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const; + + /// \brief Retrieves the default calling convention to use for + /// C++ instance methods. + CallingConv getDefaultMethodCallConv(); /// \brief Retrieves the canonical representation of the given /// calling convention. - CallingConv getCanonicalCallConv(CallingConv CC) { + CallingConv getCanonicalCallConv(CallingConv CC) const { if (CC == CC_C) return CC_Default; return CC; @@ -1131,7 +1216,7 @@ public: /// template name uses the shortest form of the dependent /// nested-name-specifier, which itself contains all canonical /// types, values, and templates. - TemplateName getCanonicalTemplateName(TemplateName Name); + TemplateName getCanonicalTemplateName(TemplateName Name) const; /// \brief Determine whether the given template names refer to the same /// template. @@ -1142,33 +1227,35 @@ public: /// The canonical template argument is the simplest template argument /// (which may be a type, value, expression, or declaration) that /// expresses the value of the argument. - TemplateArgument getCanonicalTemplateArgument(const TemplateArgument &Arg); + TemplateArgument getCanonicalTemplateArgument(const TemplateArgument &Arg) + const; /// Type Query functions. If the type is an instance of the specified class, /// return the Type pointer for the underlying maximally pretty type. This /// is a member of ASTContext because this may need to do some amount of /// canonicalization, e.g. to move type qualifiers into the element type. - const ArrayType *getAsArrayType(QualType T); - const ConstantArrayType *getAsConstantArrayType(QualType T) { + const ArrayType *getAsArrayType(QualType T) const; + const ConstantArrayType *getAsConstantArrayType(QualType T) const { return dyn_cast_or_null(getAsArrayType(T)); } - const VariableArrayType *getAsVariableArrayType(QualType T) { + const VariableArrayType *getAsVariableArrayType(QualType T) const { return dyn_cast_or_null(getAsArrayType(T)); } - const IncompleteArrayType *getAsIncompleteArrayType(QualType T) { + const IncompleteArrayType *getAsIncompleteArrayType(QualType T) const { return dyn_cast_or_null(getAsArrayType(T)); } - const DependentSizedArrayType *getAsDependentSizedArrayType(QualType T) { + const DependentSizedArrayType *getAsDependentSizedArrayType(QualType T) + const { return dyn_cast_or_null(getAsArrayType(T)); } /// getBaseElementType - Returns the innermost element type of an array type. /// For example, will return "int" for int[m][n] - QualType getBaseElementType(const ArrayType *VAT); + QualType getBaseElementType(const ArrayType *VAT) const; /// getBaseElementType - Returns the innermost element type of a type /// (which needn't actually be an array type). - QualType getBaseElementType(QualType QT); + QualType getBaseElementType(QualType QT) const; /// getConstantArrayElementCount - Returns number of constant array elements. uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const; @@ -1179,30 +1266,30 @@ public: /// this returns a pointer to a properly qualified element of the array. /// /// See C99 6.7.5.3p7 and C99 6.3.2.1p3. - QualType getArrayDecayedType(QualType T); + QualType getArrayDecayedType(QualType T) const; /// getPromotedIntegerType - Returns the type that Promotable will /// promote to: C99 6.3.1.1p2, assuming that Promotable is a promotable /// integer type. - QualType getPromotedIntegerType(QualType PromotableType); + QualType getPromotedIntegerType(QualType PromotableType) const; /// \brief Whether this is a promotable bitfield reference according /// to C99 6.3.1.1p2, bullet 2 (and GCC extensions). /// /// \returns the type this bit-field will promote to, or NULL if no /// promotion occurs. - QualType isPromotableBitField(Expr *E); + QualType isPromotableBitField(Expr *E) const; /// getIntegerTypeOrder - Returns the highest ranked integer type: /// C99 6.3.1.8p1. If LHS > RHS, return 1. If LHS == RHS, return 0. If /// LHS < RHS, return -1. - int getIntegerTypeOrder(QualType LHS, QualType RHS); + int getIntegerTypeOrder(QualType LHS, QualType RHS) const; /// getFloatingTypeOrder - Compare the rank of the two specified floating /// point types, ignoring the domain of the type (i.e. 'double' == /// '_Complex double'). If LHS > RHS, return 1. If LHS == RHS, return 0. If /// LHS < RHS, return -1. - int getFloatingTypeOrder(QualType LHS, QualType RHS); + int getFloatingTypeOrder(QualType LHS, QualType RHS) const; /// getFloatingTypeOfSizeWithinDomain - Returns a real floating /// point or a complex type (based on typeDomain/typeSize). @@ -1213,7 +1300,7 @@ public: private: // Helper for integer ordering - unsigned getIntegerRank(Type* T); + unsigned getIntegerRank(const Type *T) const; public: @@ -1260,14 +1347,15 @@ public: bool Unqualified = false); QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer=false, bool Unqualified = false); + QualType mergeFunctionArgumentTypes(QualType, QualType, + bool OfBlockPointer=false, + bool Unqualified = false); + QualType mergeTransparentUnionType(QualType, QualType, + bool OfBlockPointer=false, + bool Unqualified = false); QualType mergeObjCGCQualifiers(QualType, QualType); - /// UsualArithmeticConversionsType - handles the various conversions - /// that are common to binary operators (C99 6.3.1.8, C++ [expr]p9) - /// and returns the result type of that conversion. - QualType UsualArithmeticConversionsType(QualType lhs, QualType rhs); - void ResetObjCLayout(const ObjCContainerDecl *CD) { ObjCLayouts[CD] = 0; } @@ -1278,7 +1366,7 @@ public: // The width of an integer, as defined in C99 6.2.6.2. This is the number // of bits in an integer type excluding any padding bits. - unsigned getIntWidth(QualType T); + unsigned getIntWidth(QualType T) const; // Per C99 6.2.5p6, for every signed integer type, there is a corresponding // unsigned integer type. This method takes a signed type, and returns the @@ -1303,7 +1391,7 @@ public: /// MakeIntValue - Make an APSInt of the appropriate width and /// signedness for the given \arg Value and integer \arg Type. - llvm::APSInt MakeIntValue(uint64_t Value, QualType Type) { + llvm::APSInt MakeIntValue(uint64_t Value, QualType Type) const { llvm::APSInt Res(getIntWidth(Type), !Type->isSignedIntegerType()); Res = Value; return Res; @@ -1314,12 +1402,23 @@ public: /// \brief Get the implementation of ObjCCategoryDecl, or NULL if none exists. ObjCCategoryImplDecl *getObjCImplementation(ObjCCategoryDecl *D); + /// \brief returns true if there is at lease one @implementation in TU. + bool AnyObjCImplementation() { + return !ObjCImpls.empty(); + } + /// \brief Set the implementation of ObjCInterfaceDecl. void setObjCImplementation(ObjCInterfaceDecl *IFaceD, ObjCImplementationDecl *ImplD); /// \brief Set the implementation of ObjCCategoryDecl. void setObjCImplementation(ObjCCategoryDecl *CatD, ObjCCategoryImplDecl *ImplD); + + /// \brief Set the copy inialization expression of a block var decl. + void setBlockVarCopyInits(VarDecl*VD, Expr* Init); + /// \brief Get the copy initialization expression of VarDecl,or NULL if + /// none exists. + Expr *getBlockVarCopyInits(const VarDecl*VD); /// \brief Allocate an uninitialized TypeSourceInfo. /// @@ -1332,13 +1431,14 @@ public: /// /// \param Size the size of the type info to create, or 0 if the size /// should be calculated based on the type. - TypeSourceInfo *CreateTypeSourceInfo(QualType T, unsigned Size = 0); + TypeSourceInfo *CreateTypeSourceInfo(QualType T, unsigned Size = 0) const; /// \brief Allocate a TypeSourceInfo where all locations have been /// initialized to a given location, which defaults to the empty /// location. TypeSourceInfo * - getTrivialTypeSourceInfo(QualType T, SourceLocation Loc = SourceLocation()); + getTrivialTypeSourceInfo(QualType T, + SourceLocation Loc = SourceLocation()) const; TypeSourceInfo *getNullTypeSourceInfo() { return &NullTypeSourceInfo; } @@ -1407,10 +1507,11 @@ private: bool ExpandStructures, const FieldDecl *Field, bool OutermostType = false, - bool EncodingProperty = false); + bool EncodingProperty = false) const; - const ASTRecordLayout &getObjCLayout(const ObjCInterfaceDecl *D, - const ObjCImplementationDecl *Impl); + const ASTRecordLayout & + getObjCLayout(const ObjCInterfaceDecl *D, + const ObjCImplementationDecl *Impl) const; private: /// \brief A set of deallocations that should be performed when the @@ -1423,8 +1524,8 @@ private: llvm::PointerIntPair LastSDM; /// \brief A counter used to uniquely identify "blocks". - unsigned int UniqueBlockByRefTypeID; - unsigned int UniqueBlockParmTypeID; + mutable unsigned int UniqueBlockByRefTypeID; + mutable unsigned int UniqueBlockParmTypeID; friend class DeclContext; friend class DeclarationNameTable; @@ -1469,7 +1570,7 @@ static inline Selector GetUnarySelector(const char* name, ASTContext& Ctx) { /// @param Alignment The alignment of the allocated memory (if the underlying /// allocator supports it). /// @return The allocated memory. Could be NULL. -inline void *operator new(size_t Bytes, clang::ASTContext &C, +inline void *operator new(size_t Bytes, const clang::ASTContext &C, size_t Alignment) throw () { return C.Allocate(Bytes, Alignment); } @@ -1479,7 +1580,7 @@ inline void *operator new(size_t Bytes, clang::ASTContext &C, /// invoking it directly; see the new operator for more details. This operator /// is called implicitly by the compiler if a placement new expression using /// the ASTContext throws in the object constructor. -inline void operator delete(void *Ptr, clang::ASTContext &C, size_t) +inline void operator delete(void *Ptr, const clang::ASTContext &C, size_t) throw () { C.Deallocate(Ptr); } @@ -1503,7 +1604,7 @@ inline void operator delete(void *Ptr, clang::ASTContext &C, size_t) /// @param Alignment The alignment of the allocated memory (if the underlying /// allocator supports it). /// @return The allocated memory. Could be NULL. -inline void *operator new[](size_t Bytes, clang::ASTContext& C, +inline void *operator new[](size_t Bytes, const clang::ASTContext& C, size_t Alignment = 8) throw () { return C.Allocate(Bytes, Alignment); } @@ -1514,7 +1615,7 @@ inline void *operator new[](size_t Bytes, clang::ASTContext& C, /// invoking it directly; see the new[] operator for more details. This operator /// is called implicitly by the compiler if a placement new[] expression using /// the ASTContext throws in the object constructor. -inline void operator delete[](void *Ptr, clang::ASTContext &C, size_t) +inline void operator delete[](void *Ptr, const clang::ASTContext &C, size_t) throw () { C.Deallocate(Ptr); } diff --git a/include/clang/AST/ASTDiagnostic.h b/include/clang/AST/ASTDiagnostic.h index 7cbf3a5..1ab53b3 100644 --- a/include/clang/AST/ASTDiagnostic.h +++ b/include/clang/AST/ASTDiagnostic.h @@ -15,7 +15,7 @@ namespace clang { namespace diag { enum { -#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,CATEGORY) ENUM, +#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,ACCESS,CATEGORY) ENUM, #define ASTSTART #include "clang/Basic/DiagnosticASTKinds.inc" #undef DIAG diff --git a/include/clang/AST/ASTImporter.h b/include/clang/AST/ASTImporter.h index 9380058..b659ce7 100644 --- a/include/clang/AST/ASTImporter.h +++ b/include/clang/AST/ASTImporter.h @@ -45,13 +45,13 @@ namespace clang { /// \brief The file managers we're importing to and from. FileManager &ToFileManager, &FromFileManager; - - /// \brief The diagnostics object that we should use to emit diagnostics. - Diagnostic &Diags; + + /// \brief Whether to perform a minimal import. + bool Minimal; /// \brief Mapping from the already-imported types in the "from" context /// to the corresponding types in the "to" context. - llvm::DenseMap ImportedTypes; + llvm::DenseMap ImportedTypes; /// \brief Mapping from the already-imported declarations in the "from" /// context to the corresponding declarations in the "to" context. @@ -63,7 +63,7 @@ namespace clang { /// \brief Mapping from the already-imported FileIDs in the "from" source /// manager to the corresponding FileIDs in the "to" source manager. - llvm::DenseMap ImportedFileIDs; + llvm::DenseMap ImportedFileIDs; /// \brief Imported, anonymous tag declarations that are missing their /// corresponding typedefs. @@ -74,12 +74,29 @@ namespace clang { NonEquivalentDeclSet NonEquivalentDecls; public: - ASTImporter(Diagnostic &Diags, - ASTContext &ToContext, FileManager &ToFileManager, - ASTContext &FromContext, FileManager &FromFileManager); + /// \brief Create a new AST importer. + /// + /// \param ToContext The context we'll be importing into. + /// + /// \param ToFileManager The file manager we'll be importing into. + /// + /// \param FromContext The context we'll be importing from. + /// + /// \param FromFileManager The file manager we'll be importing into. + /// + /// \param MinimalImport If true, the importer will attempt to import + /// as little as it can, e.g., by importing declarations as forward + /// declarations that can be completed at a later point. + ASTImporter(ASTContext &ToContext, FileManager &ToFileManager, + ASTContext &FromContext, FileManager &FromFileManager, + bool MinimalImport); virtual ~ASTImporter(); + /// \brief Whether the importer will perform a minimal import, creating + /// to-be-completed forward declarations when possible. + bool isMinimalImport() const { return Minimal; } + /// \brief Import the given type from the "from" context into the "to" /// context. /// @@ -129,6 +146,10 @@ namespace clang { /// context, or NULL if an error occurred. NestedNameSpecifier *Import(NestedNameSpecifier *FromNNS); + /// \brief Import the goven template name from the "from" context into the + /// "to" context. + TemplateName Import(TemplateName From); + /// \brief Import the given source location from the "from" context into /// the "to" context. /// @@ -154,7 +175,7 @@ namespace clang { /// into the "to" context. /// /// \returns the equivalent identifier in the "to" context. - IdentifierInfo *Import(IdentifierInfo *FromId); + IdentifierInfo *Import(const IdentifierInfo *FromId); /// \brief Import the given Objective-C selector from the "from" /// context into the "to" context. @@ -169,6 +190,12 @@ namespace clang { /// context. FileID Import(FileID); + /// \brief Import the definition of the given declaration, including all of + /// the declarations it contains. + /// + /// This routine is intended to be used + void ImportDefinition(Decl *From); + /// \brief Cope with a name conflict when importing a declaration into the /// given context. /// @@ -212,9 +239,6 @@ namespace clang { /// \brief Retrieve the file manager that AST nodes are being imported from. FileManager &getFromFileManager() const { return FromFileManager; } - - /// \brief Retrieve the diagnostic formatter. - Diagnostic &getDiags() const { return Diags; } /// \brief Report a diagnostic in the "to" context. DiagnosticBuilder ToDiag(SourceLocation Loc, unsigned DiagID); @@ -228,12 +252,13 @@ namespace clang { /// \brief Note that we have imported the "from" declaration by mapping it /// to the (potentially-newly-created) "to" declaration. /// - /// \returns \p To - Decl *Imported(Decl *From, Decl *To); + /// Subclasses can override this function to observe all of the \c From -> + /// \c To declaration mappings as they are imported. + virtual Decl *Imported(Decl *From, Decl *To); /// \brief Determine whether the given types are structurally /// equivalent. - bool IsStructurallyEquivalent(QualType From, QualType To); + bool IsStructurallyEquivalent(QualType From, QualType To); }; } diff --git a/include/clang/AST/ASTMutationListener.h b/include/clang/AST/ASTMutationListener.h new file mode 100644 index 0000000..01e6180 --- /dev/null +++ b/include/clang/AST/ASTMutationListener.h @@ -0,0 +1,48 @@ +//===--- ASTMutationListener.h - AST 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 ASTMutationListener interface. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_AST_ASTMUTATIONLISTENER_H +#define LLVM_CLANG_AST_ASTMUTATIONLISTENER_H + +namespace clang { + class Decl; + class DeclContext; + class TagDecl; + class CXXRecordDecl; + class ClassTemplateDecl; + class ClassTemplateSpecializationDecl; + +/// \brief An abstract interface that should be implemented by listeners +/// that want to be notified when an AST entity gets modified after its +/// initial creation. +class ASTMutationListener { +public: + virtual ~ASTMutationListener(); + + /// \brief A new TagDecl definition was completed. + virtual void CompletedTagDefinition(const TagDecl *D) { } + + /// \brief A new declaration with name has been added to a DeclContext. + virtual void AddedVisibleDecl(const DeclContext *DC, const Decl *D) {} + + /// \brief An implicit member was added after the definition was completed. + virtual void AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) {} + + /// \brief A template specialization (or partial one) was added to the + /// template declaration. + virtual void AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD, + const ClassTemplateSpecializationDecl *D) {} +}; + +} // end namespace clang + +#endif diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h index 62ca49f..67968fd 100644 --- a/include/clang/AST/Attr.h +++ b/include/clang/AST/Attr.h @@ -36,19 +36,19 @@ namespace clang { } // Defined in ASTContext.h -void *operator new(size_t Bytes, clang::ASTContext &C, +void *operator new(size_t Bytes, const clang::ASTContext &C, size_t Alignment = 16) throw (); // FIXME: Being forced to not have a default argument here due to redeclaration // rules on default arguments sucks -void *operator new[](size_t Bytes, clang::ASTContext &C, +void *operator new[](size_t Bytes, const clang::ASTContext &C, size_t Alignment) throw (); // 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, clang::ASTContext &C, size_t) +void operator delete(void *Ptr, const clang::ASTContext &C, size_t) throw (); -void operator delete[](void *Ptr, clang::ASTContext &C, size_t) +void operator delete[](void *Ptr, const clang::ASTContext &C, size_t) throw (); namespace clang { @@ -58,9 +58,10 @@ class Attr { private: SourceLocation Loc; unsigned AttrKind : 16; - bool Inherited : 1; protected: + bool Inherited : 1; + virtual ~Attr(); void* operator new(size_t bytes) throw() { @@ -88,10 +89,6 @@ protected: public: - /// \brief Whether this attribute should be merged to new - /// declarations. - virtual bool isMerged() const { return true; } - attr::Kind getKind() const { return static_cast(AttrKind); } @@ -100,7 +97,6 @@ public: void setLocation(SourceLocation L) { Loc = L; } bool isInherited() const { return Inherited; } - void setInherited(bool I) { Inherited = I; } // Clone this attribute. virtual Attr* clone(ASTContext &C) const = 0; @@ -109,6 +105,21 @@ public: static bool classof(const Attr *) { return true; } }; +class InheritableAttr : public Attr { +protected: + InheritableAttr(attr::Kind AK, SourceLocation L) + : Attr(AK, L) {} + +public: + void setInherited(bool I) { Inherited = I; } + + // Implement isa/cast/dyncast/etc. + static bool classof(const Attr *A) { + return A->getKind() <= attr::LAST_INHERITABLE; + } + static bool classof(const InheritableAttr *) { return true; } +}; + #include "clang/AST/Attrs.inc" /// AttrVec - A vector of Attr, which is how they are stored on the AST. diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h index 5a84e40..2d30cb3 100644 --- a/include/clang/AST/CXXInheritance.h +++ b/include/clang/AST/CXXInheritance.h @@ -20,6 +20,7 @@ #include "clang/AST/Type.h" #include "clang/AST/TypeOrdering.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" #include #include @@ -359,7 +360,11 @@ public: /// subobjects of that type. class CXXFinalOverriderMap : public llvm::DenseMap { }; - + +/// \brief A set of all the primary bases for a class. +class CXXIndirectPrimaryBaseSet + : public llvm::SmallSet { }; + } // end namespace clang #endif diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h index dad4dfc..4d7fcfd 100644 --- a/include/clang/AST/CanonicalType.h +++ b/include/clang/AST/CanonicalType.h @@ -66,7 +66,16 @@ public: /// \brief Retrieve the underlying type pointer, which refers to a /// canonical type. - T *getTypePtr() const { return cast_or_null(Stored.getTypePtr()); } + /// + /// The underlying pointer must not be NULL. + const T *getTypePtr() const { return cast(Stored.getTypePtr()); } + + /// \brief Retrieve the underlying type pointer, which refers to a + /// canonical type, or NULL. + /// + const T *getTypePtrOrNull() const { + return cast_or_null(Stored.getTypePtrOrNull()); + } /// \brief Implicit conversion to a qualified type. operator QualType() const { return Stored; } @@ -78,6 +87,8 @@ public: return Stored.isNull(); } + SplitQualType split() const { return Stored.split(); } + /// \brief Retrieve a canonical type pointer with a different static type, /// upcasting or downcasting as needed. /// @@ -216,7 +227,7 @@ protected: public: /// \brief Retrieve the pointer to the underlying Type - T* getTypePtr() const { return Stored.getTypePtr(); } + const T *getTypePtr() const { return Stored.getTypePtr(); } /// \brief Implicit conversion to the underlying pointer. /// @@ -225,7 +236,7 @@ public: /// @code /// if (CanQual Ptr = T->getAs()) { ... } /// @endcode - operator const T*() const { return this->Stored.getTypePtr(); } + operator const T*() const { return this->Stored.getTypePtrOrNull(); } /// \brief Try to convert the given canonical type to a specific structural /// type. @@ -336,7 +347,7 @@ namespace llvm { /// to return smart pointer (proxies?). template struct simplify_type > { - typedef T* SimpleType; + typedef const T *SimpleType; static SimpleType getSimplifiedValue(const ::clang::CanQual &Val) { return Val.getTypePtr(); } @@ -630,7 +641,6 @@ struct CanProxyAdaptor : public CanProxyBase { LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(RecordDecl *, getDecl) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasConstFields) - LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getAddressSpace) }; template<> diff --git a/include/clang/AST/CharUnits.h b/include/clang/AST/CharUnits.h index 0bb4b76..cf909e8 100644 --- a/include/clang/AST/CharUnits.h +++ b/include/clang/AST/CharUnits.h @@ -14,7 +14,9 @@ #ifndef LLVM_CLANG_AST_CHARUNITS_H #define LLVM_CLANG_AST_CHARUNITS_H -#include "llvm/System/DataTypes.h" +#include "llvm/ADT/DenseMapInfo.h" +#include "llvm/Support/DataTypes.h" +#include "llvm/Support/MathExtras.h" namespace clang { @@ -131,12 +133,24 @@ namespace clang { CharUnits operator- (const CharUnits &Other) const { return CharUnits(Quantity - Other.Quantity); } + CharUnits operator- () const { + return CharUnits(-Quantity); + } + // Conversions. /// getQuantity - Get the raw integer representation of this quantity. QuantityType getQuantity() const { return Quantity; } + /// RoundUpToAlignment - Returns the next integer (mod 2**64) that is + /// greater than or equal to this quantity and is a multiple of \arg + /// Align. Align must be non-zero. + CharUnits RoundUpToAlignment(const CharUnits &Align) { + return CharUnits(llvm::RoundUpToAlignment(Quantity, + Align.Quantity)); + } + }; // class CharUnit } // namespace clang @@ -146,4 +160,38 @@ inline clang::CharUnits operator* (clang::CharUnits::QuantityType Scale, return CU * Scale; } +namespace llvm { + +template<> struct DenseMapInfo { + static clang::CharUnits getEmptyKey() { + clang::CharUnits::QuantityType Quantity = + DenseMapInfo::getEmptyKey(); + + return clang::CharUnits::fromQuantity(Quantity); + } + + static clang::CharUnits getTombstoneKey() { + clang::CharUnits::QuantityType Quantity = + DenseMapInfo::getTombstoneKey(); + + return clang::CharUnits::fromQuantity(Quantity); + } + + static unsigned getHashValue(const clang::CharUnits &CU) { + clang::CharUnits::QuantityType Quantity = CU.getQuantity(); + return DenseMapInfo::getHashValue(Quantity); + } + + static bool isEqual(const clang::CharUnits &LHS, + const clang::CharUnits &RHS) { + return LHS == RHS; + } +}; + +template <> struct isPodLike { + static const bool value = true; +}; + +} // end namespace llvm + #endif // LLVM_CLANG_AST_CHARUNITS_H diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 6749255..ee515da 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -36,6 +36,7 @@ class FunctionTemplateSpecializationInfo; class DependentFunctionTemplateSpecializationInfo; class TypeLoc; class UnresolvedSetImpl; +class LabelStmt; /// \brief A container of type source information. /// @@ -196,9 +197,86 @@ public: /// determine whether it's an instance member of its class. bool isCXXInstanceMember() const; + class LinkageInfo { + Linkage linkage_; + Visibility visibility_; + bool explicit_; + + public: + LinkageInfo() : linkage_(ExternalLinkage), visibility_(DefaultVisibility), + explicit_(false) {} + LinkageInfo(Linkage L, Visibility V, bool E) + : linkage_(L), visibility_(V), explicit_(E) {} + + 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_; } + Visibility visibility() const { return visibility_; } + bool visibilityExplicit() const { return explicit_; } + + void setLinkage(Linkage L) { linkage_ = L; } + void setVisibility(Visibility V) { visibility_ = V; } + void setVisibility(Visibility V, bool E) { visibility_ = V; explicit_ = E; } + void setVisibility(LinkageInfo Other) { + setVisibility(Other.visibility(), Other.visibilityExplicit()); + } + + void mergeLinkage(Linkage L) { + setLinkage(minLinkage(linkage(), L)); + } + void mergeLinkage(LinkageInfo Other) { + setLinkage(minLinkage(linkage(), Other.linkage())); + } + + void mergeVisibility(Visibility V) { + setVisibility(minVisibility(visibility(), V)); + } + void mergeVisibility(Visibility V, bool E) { + setVisibility(minVisibility(visibility(), V), visibilityExplicit() || E); + } + void mergeVisibility(LinkageInfo Other) { + mergeVisibility(Other.visibility(), Other.visibilityExplicit()); + } + + void merge(LinkageInfo Other) { + mergeLinkage(Other); + mergeVisibility(Other); + } + void merge(std::pair LV) { + mergeLinkage(LV.first); + mergeVisibility(LV.second); + } + + friend LinkageInfo merge(LinkageInfo L, LinkageInfo R) { + L.merge(R); + return L; + } + }; + /// \brief Determine what kind of linkage this entity has. Linkage getLinkage() const; + /// \brief Determines the visibility of this entity. + Visibility getVisibility() const { return getLinkageAndVisibility().visibility(); } + + /// \brief Determines the linkage and visibility of this entity. + LinkageInfo getLinkageAndVisibility() const; + + /// \brief Clear the linkage cache in response to a change + /// to the declaration. + void ClearLinkageCache(); + /// \brief Looks through UsingDecls and ObjCCompatibleAliasDecls for /// the underlying named decl. NamedDecl *getUnderlyingDecl(); @@ -217,6 +295,29 @@ inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, return OS; } +/// LabelDecl - Represents the declaration of a label. Labels also have a +/// corresponding LabelStmt, which indicates the position that the label was +/// defined at. For normal labels, the location of the decl is the same as the +/// location of the statement. For GNU local labels (__label__), the decl +/// location is where the __label__ is. +class LabelDecl : public NamedDecl { + LabelStmt *TheStmt; + LabelDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *II, LabelStmt *S) + : NamedDecl(Label, DC, L, II), TheStmt(S) {} + +public: + static LabelDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation L, IdentifierInfo *II); + + LabelStmt *getStmt() const { return TheStmt; } + void setStmt(LabelStmt *T) { TheStmt = T; } + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classof(const LabelDecl *D) { return true; } + static bool classofKind(Kind K) { return K == Label; } +}; + /// NamespaceDecl - Represent a C++ namespace. class NamespaceDecl : public NamedDecl, public DeclContext { bool IsInline : 1; @@ -232,7 +333,7 @@ class NamespaceDecl : public NamedDecl, public DeclContext { // NextNamespace points to the next extended declaration. // OrigNamespace points to the original namespace declaration. // OrigNamespace of the first namespace decl points to its anonymous namespace - NamespaceDecl *NextNamespace; + LazyDeclPtr NextNamespace; /// \brief A pointer to either the original namespace definition for /// this namespace (if the boolean value is false) or the anonymous @@ -250,7 +351,7 @@ class NamespaceDecl : public NamedDecl, public DeclContext { NamespaceDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id) : NamedDecl(Namespace, DC, L, Id), DeclContext(Namespace), - IsInline(false), NextNamespace(0), OrigOrAnonNamespace(0, true) { } + IsInline(false), NextNamespace(), OrigOrAnonNamespace(0, true) { } public: static NamespaceDecl *Create(ASTContext &C, DeclContext *DC, @@ -281,8 +382,10 @@ public: /// \brief Return the next extended namespace declaration or null if there /// is none. - NamespaceDecl *getNextNamespace() { return NextNamespace; } - const NamespaceDecl *getNextNamespace() const { return NextNamespace; } + NamespaceDecl *getNextNamespace(); + const NamespaceDecl *getNextNamespace() const { + return const_cast(this)->getNextNamespace(); + } /// \brief Set the next extended namespace declaration. void setNextNamespace(NamespaceDecl *ND) { NextNamespace = ND; } @@ -331,9 +434,9 @@ public: SourceLocation getLBracLoc() const { return LBracLoc; } SourceLocation getRBracLoc() const { return RBracLoc; } - void setLBracLoc(SourceLocation LBrace) { LBracLoc = LBrace; } - void setRBracLoc(SourceLocation RBrace) { RBracLoc = RBrace; } - + void setLBracLoc(SourceLocation L) { LBracLoc = L; } + void setRBracLoc(SourceLocation R) { RBracLoc = R; } + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classof(const NamespaceDecl *D) { return true; } @@ -471,6 +574,9 @@ public: static bool classofKind(Kind K) { return K >= firstDeclarator && K <= lastDeclarator; } + + friend class ASTDeclReader; + friend class ASTDeclWriter; }; /// \brief Structure used to store a statement, the constant value to @@ -545,15 +651,21 @@ private: /// \brief Whether this local variable could be allocated in the return /// slot of its function, enabling the named return value optimization (NRVO). bool NRVOVariable : 1; + + /// \brief Whether this variable has a deduced C++0x auto type for which we're + /// currently parsing the initializer. + bool ParsingAutoInit : 1; friend class StmtIteratorBase; + friend class ASTDeclReader; + protected: VarDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass SC, StorageClass SCAsWritten) : DeclaratorDecl(DK, DC, L, Id, T, TInfo), Init(), ThreadSpecified(false), HasCXXDirectInit(false), - ExceptionVar(false), NRVOVariable(false) { + ExceptionVar(false), NRVOVariable(false), ParsingAutoInit(false) { SClass = SC; SClassAsWritten = SCAsWritten; } @@ -582,10 +694,7 @@ public: StorageClass getStorageClassAsWritten() const { return (StorageClass) SClassAsWritten; } - void setStorageClass(StorageClass SC) { - assert(isLegalForVariable(SC)); - SClass = SC; - } + void setStorageClass(StorageClass SC); void setStorageClassAsWritten(StorageClass SC) { assert(isLegalForVariable(SC)); SClassAsWritten = SC; @@ -630,13 +739,13 @@ public: /// external, C linkage. bool isExternC() const; - /// isBlockVarDecl - Returns true for local variable declarations. Note that - /// this includes static variables inside of functions. It also includes - /// variables inside blocks. + /// isLocalVarDecl - Returns true for local variable declarations + /// other than parameters. Note that this includes static variables + /// inside of functions. It also includes variables inside blocks. /// /// void foo() { int x; static int y; extern int z; } /// - bool isBlockVarDecl() const { + bool isLocalVarDecl() const { if (getKind() != Decl::Var) return false; if (const DeclContext *DC = getDeclContext()) @@ -644,8 +753,8 @@ public: return false; } - /// isFunctionOrMethodVarDecl - Similar to isBlockVarDecl, but excludes - /// variables declared in blocks. + /// isFunctionOrMethodVarDecl - Similar to isLocalVarDecl, but + /// excludes variables declared in blocks. bool isFunctionOrMethodVarDecl() const { if (getKind() != Decl::Var) return false; @@ -683,6 +792,10 @@ public: /// definition. DefinitionKind isThisDeclarationADefinition() const; + /// \brief Check whether this variable is defined in this + /// translation unit. + DefinitionKind hasDefinition() const; + /// \brief Get the tentative definition that acts as the real definition in /// a TU. Returns null if there is a proper definition available. VarDecl *getActingDefinition(); @@ -733,7 +846,7 @@ public: const Expr *getAnyInitializer(const VarDecl *&D) const; bool hasInit() const { - return !Init.isNull(); + return !Init.isNull() && (Init.is() || Init.is()); } const Expr *getInit() const { if (Init.isNull()) @@ -776,6 +889,18 @@ public: void setInit(Expr *I); + /// \brief Check whether we are in the process of parsing an initializer + /// needed to deduce the type of this variable. + bool isParsingAutoInit() const { + return ParsingAutoInit; + } + + /// \brief Note whether we are currently parsing an initializer needed to + /// deduce the type of this variable. + void setParsingAutoInit(bool P) { + ParsingAutoInit = P; + } + EvaluatedStmt *EnsureEvaluatedStmt() const { EvaluatedStmt *Eval = Init.dyn_cast(); if (!Eval) { @@ -928,7 +1053,9 @@ class ImplicitParamDecl : public VarDecl { protected: ImplicitParamDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, QualType Tw) - : VarDecl(DK, DC, L, Id, Tw, /*TInfo=*/0, SC_None, SC_None) {} + : VarDecl(DK, DC, L, Id, Tw, /*TInfo=*/0, SC_None, SC_None) { + setImplicit(); + } public: static ImplicitParamDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, @@ -1046,6 +1173,10 @@ public: return getType(); } + /// \brief Determine whether this parameter is actually a function + /// parameter pack. + bool isParameterPack() const; + /// setOwningFunction - Sets the function declaration that owns this /// ParmVarDecl. Since ParmVarDecls are often created before the /// FunctionDecls that own them, this routine is required to update @@ -1096,13 +1227,13 @@ private: unsigned SClass : 2; unsigned SClassAsWritten : 2; bool IsInline : 1; + bool IsInlineSpecified : 1; bool IsVirtualAsWritten : 1; bool IsPure : 1; bool HasInheritedPrototype : 1; bool HasWrittenPrototype : 1; bool IsDeleted : 1; bool IsTrivial : 1; // sunk from CXXMethodDecl - bool IsCopyAssignment : 1; // sunk from CXXMethodDecl bool HasImplicitReturnZero : 1; /// \brief End part of this FunctionDecl's source range. @@ -1136,19 +1267,54 @@ private: /// declaration name embedded in the DeclaratorDecl base class. DeclarationNameLoc DNLoc; + /// \brief Specify that this function declaration is actually a function + /// template specialization. + /// + /// \param C the ASTContext. + /// + /// \param Template the function template that this function template + /// specialization specializes. + /// + /// \param TemplateArgs the template arguments that produced this + /// function template specialization from the template. + /// + /// \param InsertPos If non-NULL, the position in the function template + /// specialization set where the function template specialization data will + /// be inserted. + /// + /// \param TSK the kind of template specialization this is. + /// + /// \param TemplateArgsAsWritten location info of template arguments. + /// + /// \param PointOfInstantiation point at which the function template + /// specialization was first instantiated. + void setFunctionTemplateSpecialization(ASTContext &C, + FunctionTemplateDecl *Template, + const TemplateArgumentList *TemplateArgs, + void *InsertPos, + TemplateSpecializationKind TSK, + const TemplateArgumentListInfo *TemplateArgsAsWritten, + SourceLocation PointOfInstantiation); + + /// \brief Specify that this record is an instantiation of the + /// member function FD. + void setInstantiationOfMemberFunction(ASTContext &C, FunctionDecl *FD, + TemplateSpecializationKind TSK); + + void setParams(ASTContext &C, ParmVarDecl **NewParamInfo, unsigned NumParams); + protected: FunctionDecl(Kind DK, DeclContext *DC, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, - StorageClass S, StorageClass SCAsWritten, bool isInline) + StorageClass S, StorageClass SCAsWritten, bool isInlineSpecified) : DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo), DeclContext(DK), ParamInfo(0), Body(), - SClass(S), SClassAsWritten(SCAsWritten), IsInline(isInline), + SClass(S), SClassAsWritten(SCAsWritten), + IsInline(isInlineSpecified), IsInlineSpecified(isInlineSpecified), IsVirtualAsWritten(false), IsPure(false), HasInheritedPrototype(false), HasWrittenPrototype(true), IsDeleted(false), IsTrivial(false), - IsCopyAssignment(false), - HasImplicitReturnZero(false), - EndRangeLoc(NameInfo.getEndLoc()), + HasImplicitReturnZero(false), EndRangeLoc(NameInfo.getEndLoc()), TemplateOrSpecialization(), DNLoc(NameInfo.getInfo()) {} @@ -1169,11 +1335,11 @@ public: TypeSourceInfo *TInfo, StorageClass S = SC_None, StorageClass SCAsWritten = SC_None, - bool isInline = false, + bool isInlineSpecified = false, bool hasWrittenPrototype = true) { DeclarationNameInfo NameInfo(N, L); return FunctionDecl::Create(C, DC, NameInfo, T, TInfo, S, SCAsWritten, - isInline, hasWrittenPrototype); + isInlineSpecified, hasWrittenPrototype); } static FunctionDecl *Create(ASTContext &C, DeclContext *DC, @@ -1181,7 +1347,7 @@ public: QualType T, TypeSourceInfo *TInfo, StorageClass S = SC_None, StorageClass SCAsWritten = SC_None, - bool isInline = false, + bool isInlineSpecified = false, bool hasWrittenPrototype = true); DeclarationNameInfo getNameInfo() const { @@ -1246,7 +1412,7 @@ public: /// Whether this virtual function is pure, i.e. makes the containing class /// abstract. bool isPure() const { return IsPure; } - void setPure(bool P = true) { IsPure = P; } + void setPure(bool P = true); /// Whether this function is "trivial" in some specialized C++ senses. /// Can only be true for default constructors, copy constructors, @@ -1255,9 +1421,6 @@ public: bool isTrivial() const { return IsTrivial; } void setTrivial(bool IT) { IsTrivial = IT; } - bool isCopyAssignment() const { return IsCopyAssignment; } - void setCopyAssignment(bool CA) { IsCopyAssignment = CA; } - /// Whether falling off this function implicitly returns null/zero. /// If a more specific implicit return value is required, front-ends /// should synthesize the appropriate return statements. @@ -1273,7 +1436,6 @@ public: } bool hasWrittenPrototype() const { return HasWrittenPrototype; } - void setHasWrittenPrototype(bool P) { HasWrittenPrototype = P; } /// \brief Whether this function inherited its prototype from a /// previous declaration. @@ -1343,7 +1505,9 @@ public: assert(i < getNumParams() && "Illegal param #"); return ParamInfo[i]; } - void setParams(ParmVarDecl **NewParamInfo, unsigned NumParams); + void setParams(ParmVarDecl **NewParamInfo, unsigned NumParams) { + setParams(getASTContext(), NewParamInfo, NumParams); + } /// getMinRequiredArguments - Returns the minimum number of arguments /// needed to call this function. This may be fewer than the number of @@ -1361,31 +1525,32 @@ public: } StorageClass getStorageClass() const { return StorageClass(SClass); } - void setStorageClass(StorageClass SC) { - assert(isLegalForFunction(SC)); - SClass = SC; - } + void setStorageClass(StorageClass SC); StorageClass getStorageClassAsWritten() const { return StorageClass(SClassAsWritten); } - void setStorageClassAsWritten(StorageClass SC) { - assert(isLegalForFunction(SC)); - SClassAsWritten = SC; - } /// \brief Determine whether the "inline" keyword was specified for this /// function. - bool isInlineSpecified() const { return IsInline; } + bool isInlineSpecified() const { return IsInlineSpecified; } /// Set whether the "inline" keyword was specified for this function. - void setInlineSpecified(bool I) { IsInline = I; } + void setInlineSpecified(bool I) { + IsInlineSpecified = I; + IsInline = I; + } + + /// Flag that this function is implicitly inline. + void setImplicitlyInline() { + IsInline = true; + } /// \brief Determine whether this function should be inlined, because it is /// either marked "inline" or is a member function of a C++ class that /// was defined in the class body. bool isInlined() const; - + bool isInlineDefinitionExternallyVisible() const; /// isOverloadedOperator - Whether this function declaration @@ -1432,7 +1597,9 @@ public: /// \brief Specify that this record is an instantiation of the /// member function FD. void setInstantiationOfMemberFunction(FunctionDecl *FD, - TemplateSpecializationKind TSK); + TemplateSpecializationKind TSK) { + setInstantiationOfMemberFunction(getASTContext(), FD, TSK); + } /// \brief Retrieves the function template that is described by this /// function declaration. @@ -1526,43 +1693,11 @@ public: void *InsertPos, TemplateSpecializationKind TSK = TSK_ImplicitInstantiation, const TemplateArgumentListInfo *TemplateArgsAsWritten = 0, - SourceLocation PointOfInstantiation = SourceLocation()); - - /// \brief Specify that this function declaration is actually a function - /// template specialization. - /// - /// \param Template the function template that this function template - /// specialization specializes. - /// - /// \param NumTemplateArgs number of template arguments that produced this - /// function template specialization from the template. - /// - /// \param TemplateArgs array of template arguments that produced this - /// function template specialization from the template. - /// - /// \param TSK the kind of template specialization this is. - /// - /// \param NumTemplateArgsAsWritten number of template arguments that produced - /// this function template specialization from the template. - /// - /// \param TemplateArgsAsWritten array of location info for the template - /// arguments. - /// - /// \param LAngleLoc location of left angle token. - /// - /// \param RAngleLoc location of right angle token. - /// - /// \param PointOfInstantiation point at which the function template - /// specialization was first instantiated. - void setFunctionTemplateSpecialization(FunctionTemplateDecl *Template, - unsigned NumTemplateArgs, - const TemplateArgument *TemplateArgs, - TemplateSpecializationKind TSK, - unsigned NumTemplateArgsAsWritten, - TemplateArgumentLoc *TemplateArgsAsWritten, - SourceLocation LAngleLoc, - SourceLocation RAngleLoc, - SourceLocation PointOfInstantiation); + SourceLocation PointOfInstantiation = SourceLocation()) { + setFunctionTemplateSpecialization(getASTContext(), Template, TemplateArgs, + InsertPos, TSK, TemplateArgsAsWritten, + PointOfInstantiation); + } /// \brief Specifies that this function declaration is actually a /// dependent function template specialization. @@ -1620,19 +1755,26 @@ public: class FieldDecl : public DeclaratorDecl { // FIXME: This can be packed into the bitfields in Decl. bool Mutable : 1; + mutable unsigned CachedFieldIndex : 31; + Expr *BitWidth; protected: FieldDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, Expr *BW, bool Mutable) - : DeclaratorDecl(DK, DC, L, Id, T, TInfo), Mutable(Mutable), BitWidth(BW) { + : DeclaratorDecl(DK, DC, L, Id, T, TInfo), + Mutable(Mutable), CachedFieldIndex(0), BitWidth(BW) { } public: - static FieldDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, - IdentifierInfo *Id, QualType T, + static FieldDecl *Create(const ASTContext &C, DeclContext *DC, + SourceLocation L, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, Expr *BW, bool Mutable); + /// getFieldIndex - Returns the index of this field within its record, + /// as appropriate for passing to ASTRecordLayout::getFieldOffset. + unsigned getFieldIndex() const; + /// isMutable - Determines whether this field is mutable (C++ only). bool isMutable() const { return Mutable; } @@ -1707,6 +1849,45 @@ public: friend class StmtIteratorBase; }; +/// IndirectFieldDecl - An instance of this class is created to represent a +/// field injected from an anonymous union/struct into the parent scope. +/// IndirectFieldDecl are always implicit. +class IndirectFieldDecl : public ValueDecl { + NamedDecl **Chaining; + unsigned ChainingSize; + + IndirectFieldDecl(DeclContext *DC, SourceLocation L, + DeclarationName N, QualType T, + NamedDecl **CH, unsigned CHS) + : ValueDecl(IndirectField, DC, L, N, T), Chaining(CH), ChainingSize(CHS) {} + +public: + static IndirectFieldDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation L, IdentifierInfo *Id, + QualType T, NamedDecl **CH, unsigned CHS); + + typedef NamedDecl * const *chain_iterator; + chain_iterator chain_begin() const { return Chaining; } + chain_iterator chain_end() const { return Chaining+ChainingSize; } + + unsigned getChainingSize() const { return ChainingSize; } + + FieldDecl *getAnonField() const { + assert(ChainingSize >= 2); + return cast(Chaining[ChainingSize - 1]); + } + + VarDecl *getVarDecl() const { + assert(ChainingSize >= 2); + return dyn_cast(*chain_begin()); + } + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classof(const IndirectFieldDecl *D) { return true; } + static bool classofKind(Kind K) { return K == IndirectField; } + friend class ASTDeclReader; +}; /// TypeDecl - Represents a declaration of a type. /// @@ -1715,7 +1896,7 @@ class TypeDecl : public NamedDecl { /// this TypeDecl. It is a cache maintained by /// ASTContext::getTypedefType, ASTContext::getTagDeclType, and /// ASTContext::getTemplateTypeParmType, and TemplateTypeParmDecl. - mutable Type *TypeForDecl; + mutable const Type *TypeForDecl; friend class ASTContext; friend class DeclContext; friend class TagDecl; @@ -1729,8 +1910,8 @@ protected: public: // Low-level accessor - Type *getTypeForDecl() const { return TypeForDecl; } - void setTypeForDecl(Type *TD) { TypeForDecl = TD; } + const Type *getTypeForDecl() const { return TypeForDecl; } + void setTypeForDecl(const Type *TD) { TypeForDecl = TD; } // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -1820,6 +2001,19 @@ protected: unsigned NumPositiveBits : 8; unsigned NumNegativeBits : 8; + /// IsScoped - True if this tag declaration is a scoped enumeration. Only + /// possible in C++0x mode. + bool IsScoped : 1; + /// IsScopedUsingClassTag - If this tag declaration is a scoped enum, + /// then this is true if the scoped enum was declared using the class + /// tag, false if it was declared with the struct tag. No meaning is + /// associated if this tag declaration is not a scoped enum. + bool IsScopedUsingClassTag : 1; + + /// IsFixed - True if this is an enumeration with fixed underlying type. Only + /// possible in C++0x mode. + bool IsFixed : 1; + private: SourceLocation TagKeywordLoc; SourceLocation RBraceLoc; @@ -1859,6 +2053,11 @@ protected: typedef Redeclarable redeclarable_base; virtual TagDecl *getNextRedeclaration() { return RedeclLink.getNext(); } + /// @brief Completes the definition of this tag declaration. + /// + /// This is a helper function for derived classes. + void completeDefinition(); + public: typedef redeclarable_base::redecl_iterator redecl_iterator; redecl_iterator redecls_begin() const { @@ -1923,9 +2122,6 @@ public: /// where it is in the process of being defined. void startDefinition(); - /// @brief Completes the definition of this tag declaration. - void completeDefinition(); - /// getDefinition - Returns the TagDecl that actually defines this /// struct/union/class/enum. When determining whether or not a /// struct/union/class/enum is completely defined, one should use this method @@ -2001,7 +2197,19 @@ class EnumDecl : public TagDecl { /// IntegerType - This represent the integer type that the enum corresponds /// to for code generation purposes. Note that the enumerator constants may /// have a different type than this does. - QualType IntegerType; + /// + /// If the underlying integer type was explicitly stated in the source + /// code, this is a TypeSourceInfo* for that type. Otherwise this type + /// was automatically deduced somehow, and this is a Type*. + /// + /// Normally if IsFixed(), this would contain a TypeSourceInfo*, but in + /// some cases it won't. + /// + /// The underlying type of an enumeration never has any qualifiers, so + /// we can get away with just storing a raw Type*, and thus save an + /// extra pointer when TypeSourceInfo is needed. + + llvm::PointerUnion IntegerType; /// PromotionType - The integer type that values of this type should /// promote to. In C, enumerators are generally of an integer type @@ -2022,11 +2230,16 @@ class EnumDecl : public TagDecl { }; EnumDecl(DeclContext *DC, SourceLocation L, - IdentifierInfo *Id, EnumDecl *PrevDecl, SourceLocation TKL) + IdentifierInfo *Id, EnumDecl *PrevDecl, SourceLocation TKL, + bool Scoped, bool ScopedUsingClassTag, bool Fixed) : TagDecl(Enum, TTK_Enum, DC, L, Id, PrevDecl, TKL), InstantiatedFrom(0) { - IntegerType = QualType(); + assert(Scoped || !ScopedUsingClassTag); + IntegerType = (const Type*)0; NumNegativeBits = 0; NumPositiveBits = 0; + IsScoped = Scoped; + IsScopedUsingClassTag = ScopedUsingClassTag; + IsFixed = Fixed; } public: EnumDecl *getCanonicalDecl() { @@ -2045,7 +2258,9 @@ public: static EnumDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, - SourceLocation TKL, EnumDecl *PrevDecl); + SourceLocation TKL, EnumDecl *PrevDecl, + bool IsScoped, bool IsScopedUsingClassTag, + bool IsFixed); static EnumDecl *Create(ASTContext &C, EmptyShell Empty); /// completeDefinition - When created, the EnumDecl corresponds to a @@ -2085,10 +2300,25 @@ public: /// getIntegerType - Return the integer type this enum decl corresponds to. /// This returns a null qualtype for an enum forward definition. - QualType getIntegerType() const { return IntegerType; } + QualType getIntegerType() const { + if (!IntegerType) + return QualType(); + if (const Type* T = IntegerType.dyn_cast()) + return QualType(T, 0); + return IntegerType.get()->getType(); + } /// \brief Set the underlying integer type. - void setIntegerType(QualType T) { IntegerType = T; } + void setIntegerType(QualType T) { IntegerType = T.getTypePtrOrNull(); } + + /// \brief Set the underlying integer type source info. + void setIntegerTypeSourceInfo(TypeSourceInfo* TInfo) { IntegerType = TInfo; } + + /// \brief Return the type source info for the underlying integer type, + /// if no type source info exists, return 0. + TypeSourceInfo* getIntegerTypeSourceInfo() const { + return IntegerType.dyn_cast(); + } /// \brief Returns the width in bits requred to store all the /// non-negative enumerators of this enum. @@ -2116,6 +2346,27 @@ public: NumNegativeBits = Num; } + /// \brief Returns true if this is a C++0x scoped enumeration. + bool isScoped() const { + return IsScoped; + } + + /// \brief Returns true if this is a C++0x scoped enumeration. + bool isScopedUsingClassTag() const { + return IsScopedUsingClassTag; + } + + /// \brief Returns true if this is a C++0x enumeration with fixed underlying + /// type. + bool isFixed() const { + return IsFixed; + } + + /// \brief Returns true if this can be considered a complete type. + bool isComplete() const { + return isDefinition() || isFixed(); + } + /// \brief Returns the enumeration (declared within the template) /// from which this enumeration type was instantiated, or NULL if /// this enumeration was not instantiated from any template. @@ -2128,6 +2379,8 @@ public: static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classof(const EnumDecl *D) { return true; } static bool classofKind(Kind K) { return K == Enum; } + + friend class ASTDeclReader; }; @@ -2151,17 +2404,24 @@ class RecordDecl : public TagDecl { /// containing an object. bool HasObjectMember : 1; + /// \brief Whether the field declarations of this record have been loaded + /// from external storage. To avoid unnecessary deserialization of + /// methods/nested types we allow deserialization of just the fields + /// when needed. + mutable bool LoadedFieldsFromExternalStorage : 1; + friend class DeclContext; + protected: RecordDecl(Kind DK, TagKind TK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, RecordDecl *PrevDecl, SourceLocation TKL); public: - static RecordDecl *Create(ASTContext &C, TagKind TK, DeclContext *DC, + static RecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, SourceLocation TKL = SourceLocation(), RecordDecl* PrevDecl = 0); - static RecordDecl *Create(ASTContext &C, EmptyShell Empty); + static RecordDecl *Create(const ASTContext &C, EmptyShell Empty); const RecordDecl *getPreviousDeclaration() const { return cast_or_null(TagDecl::getPreviousDeclaration()); @@ -2190,11 +2450,6 @@ public: AnonymousStructOrUnion = Anon; } - ValueDecl *getAnonymousStructOrUnionObject(); - const ValueDecl *getAnonymousStructOrUnionObject() const { - return const_cast(this)->getAnonymousStructOrUnionObject(); - } - bool hasObjectMember() const { return HasObjectMember; } void setHasObjectMember (bool val) { HasObjectMember = val; } @@ -2229,11 +2484,10 @@ public: // data members, functions, constructors, destructors, etc. typedef specific_decl_iterator field_iterator; - field_iterator field_begin() const { - return field_iterator(decls_begin()); - } + field_iterator field_begin() const; + field_iterator field_end() const { - return field_iterator(decls_end()); + return field_iterator(decl_iterator()); } // field_empty - Whether there are any fields (non-static data @@ -2244,13 +2498,17 @@ public: /// completeDefinition - Notes that the definition of this type is /// now complete. - void completeDefinition(); + virtual void completeDefinition(); static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classof(const RecordDecl *D) { return true; } static bool classofKind(Kind K) { return K >= firstRecord && K <= lastRecord; } + +private: + /// \brief Deserialize just the fields. + void LoadFieldsFromExternalStorage() const; }; class FileScopeAsmDecl : public Decl { @@ -2275,8 +2533,49 @@ public: /// ^{ statement-body } or ^(int arg1, float arg2){ statement-body } /// class BlockDecl : public Decl, public DeclContext { +public: + /// A class which contains all the information about a particular + /// captured value. + class Capture { + enum { + flag_isByRef = 0x1, + flag_isNested = 0x2 + }; + + /// The variable being captured. + llvm::PointerIntPair VariableAndFlags; + + /// The copy expression, expressed in terms of a DeclRef (or + /// BlockDeclRef) to the captured variable. Only required if the + /// variable has a C++ class type. + Expr *CopyExpr; + + public: + Capture(VarDecl *variable, bool byRef, bool nested, Expr *copy) + : VariableAndFlags(variable, + (byRef ? flag_isByRef : 0) | (nested ? flag_isNested : 0)), + CopyExpr(copy) {} + + /// The variable being captured. + VarDecl *getVariable() const { return VariableAndFlags.getPointer(); } + + /// Whether this is a "by ref" capture, i.e. a capture of a __block + /// variable. + bool isByRef() const { return VariableAndFlags.getInt() & flag_isByRef; } + + /// Whether this is a nested capture, i.e. the variable captured + /// is not from outside the immediately enclosing function/block. + bool isNested() const { return VariableAndFlags.getInt() & flag_isNested; } + + bool hasCopyExpr() const { return CopyExpr != 0; } + Expr *getCopyExpr() const { return CopyExpr; } + void setCopyExpr(Expr *e) { CopyExpr = e; } + }; + +private: // FIXME: This can be packed into the bitfields in Decl. bool IsVariadic : 1; + bool CapturesCXXThis : 1; /// ParamInfo - new[]'d array of pointers to ParmVarDecls for the formal /// parameters of this function. This is null if a prototype or if there are /// no formals. @@ -2286,11 +2585,15 @@ class BlockDecl : public Decl, public DeclContext { Stmt *Body; TypeSourceInfo *SignatureAsWritten; + Capture *Captures; + unsigned NumCaptures; + protected: BlockDecl(DeclContext *DC, SourceLocation CaretLoc) : Decl(Block, DC, CaretLoc), DeclContext(Block), - IsVariadic(false), ParamInfo(0), NumParams(0), Body(0), - SignatureAsWritten(0) {} + IsVariadic(false), CapturesCXXThis(false), + ParamInfo(0), NumParams(0), Body(0), + SignatureAsWritten(0), Captures(0), NumCaptures(0) {} public: static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L); @@ -2319,7 +2622,7 @@ public: param_const_iterator param_begin() const { return ParamInfo; } param_const_iterator param_end() const { return ParamInfo+param_size(); } - unsigned getNumParams() const; + unsigned getNumParams() const { return NumParams; } const ParmVarDecl *getParamDecl(unsigned i) const { assert(i < getNumParams() && "Illegal param #"); return ParamInfo[i]; @@ -2330,6 +2633,30 @@ public: } void setParams(ParmVarDecl **NewParamInfo, unsigned NumParams); + /// hasCaptures - True if this block (or its nested blocks) captures + /// anything of local storage from its enclosing scopes. + bool hasCaptures() const { return NumCaptures != 0 || CapturesCXXThis; } + + /// getNumCaptures - Returns the number of captured variables. + /// Does not include an entry for 'this'. + unsigned getNumCaptures() const { return NumCaptures; } + + typedef const Capture *capture_iterator; + typedef const Capture *capture_const_iterator; + capture_iterator capture_begin() { return Captures; } + capture_iterator capture_end() { return Captures + NumCaptures; } + capture_const_iterator capture_begin() const { return Captures; } + capture_const_iterator capture_end() const { return Captures + NumCaptures; } + + bool capturesCXXThis() const { return CapturesCXXThis; } + + void setCaptures(ASTContext &Context, + const Capture *begin, + const Capture *end, + bool capturesCXXThis); + + virtual SourceRange getSourceRange() const; + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classof(const BlockDecl *D) { return true; } @@ -2350,6 +2677,32 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, return DB; } +template +void Redeclarable::setPreviousDeclaration(decl_type *PrevDecl) { + // Note: This routine is implemented here because we need both NamedDecl + // and Redeclarable to be defined. + + decl_type *First; + + if (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( + PrevDecl->getMostRecentDeclaration())); + First = PrevDecl->getFirstDeclaration(); + assert(First->RedeclLink.NextIsLatest() && "Expected first"); + } else { + // Make this first. + First = static_cast(this); + } + + // First one will point to this one as latest. + First->RedeclLink = LatestDeclLink(static_cast(this)); + if (NamedDecl *ND = dyn_cast(static_cast(this))) + ND->ClearLinkageCache(); +} + } // end namespace clang #endif diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index 1369c2b..bf249ce 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -43,6 +43,7 @@ class DeclarationName; class CompoundStmt; class StoredDeclsMap; class DependentDiagnostic; +class ASTMutationListener; } namespace llvm { @@ -197,25 +198,25 @@ private: return DeclCtx.get(); } - /// Loc - The location that this decl. + /// Loc - The location of this decl. SourceLocation Loc; /// DeclKind - This indicates which class this is. - Kind DeclKind : 8; + unsigned DeclKind : 8; /// InvalidDecl - This indicates a semantic error occurred. - unsigned int InvalidDecl : 1; + unsigned InvalidDecl : 1; /// HasAttrs - This indicates whether the decl has attributes or not. - unsigned int HasAttrs : 1; + unsigned HasAttrs : 1; /// Implicit - Whether this declaration was implicitly generated by /// the implementation rather than explicitly written by the user. - bool Implicit : 1; + unsigned Implicit : 1; /// \brief Whether this declaration was "used", meaning that a definition is /// required. - bool Used : 1; + unsigned Used : 1; protected: /// Access - Used by C++ decls for the access specifier. @@ -227,17 +228,24 @@ protected: unsigned PCHLevel : 2; /// ChangedAfterLoad - if this declaration has changed since being loaded - bool ChangedAfterLoad : 1; + unsigned ChangedAfterLoad : 1; /// IdentifierNamespace - This specifies what IDNS_* namespace this lives in. - unsigned IdentifierNamespace : 15; + unsigned IdentifierNamespace : 12; + /// \brief Whether the \c CachedLinkage field is active. + /// + /// This field is only valid for NamedDecls subclasses. + mutable unsigned HasCachedLinkage : 1; + + /// \brief If \c HasCachedLinkage, the linkage of this declaration. + /// + /// This field is only valid for NamedDecls subclasses. + mutable unsigned CachedLinkage : 2; + + private: -#ifndef NDEBUG void CheckAccessDeclContext() const; -#else - void CheckAccessDeclContext() const { } -#endif protected: @@ -246,7 +254,9 @@ protected: Loc(L), DeclKind(DK), InvalidDecl(0), HasAttrs(false), Implicit(false), Used(false), Access(AS_none), PCHLevel(0), ChangedAfterLoad(false), - IdentifierNamespace(getIdentifierNamespaceForKind(DK)) { + IdentifierNamespace(getIdentifierNamespaceForKind(DK)), + HasCachedLinkage(0) + { if (Decl::CollectingStats()) add(DK); } @@ -254,7 +264,9 @@ protected: : NextDeclInContext(0), DeclKind(DK), InvalidDecl(0), HasAttrs(false), Implicit(false), Used(false), Access(AS_none), PCHLevel(0), ChangedAfterLoad(false), - IdentifierNamespace(getIdentifierNamespaceForKind(DK)) { + IdentifierNamespace(getIdentifierNamespaceForKind(DK)), + HasCachedLinkage(0) + { if (Decl::CollectingStats()) add(DK); } @@ -272,7 +284,7 @@ public: SourceLocation getLocation() const { return Loc; } void setLocation(SourceLocation L) { Loc = L; } - Kind getKind() const { return DeclKind; } + Kind getKind() const { return static_cast(DeclKind); } const char *getDeclKindName() const; Decl *getNextDeclInContext() { return NextDeclInContext; } @@ -298,17 +310,21 @@ public: void setAccess(AccessSpecifier AS) { Access = AS; +#ifndef NDEBUG CheckAccessDeclContext(); +#endif } AccessSpecifier getAccess() const { +#ifndef NDEBUG CheckAccessDeclContext(); +#endif return AccessSpecifier(Access); } bool hasAttrs() const { return HasAttrs; } void setAttrs(const AttrVec& Attrs); - AttrVec& getAttrs() { + AttrVec &getAttrs() { return const_cast(const_cast(this)->getAttrs()); } const AttrVec &getAttrs() const; @@ -551,6 +567,9 @@ public: /// template parameter pack. bool isTemplateParameterPack() const; + /// \brief Whether this declaration is a parameter pack. + bool isParameterPack() const; + /// \brief Whether this declaration is a function or function template. bool isFunctionOrFunctionTemplate() const; @@ -621,10 +640,14 @@ public: llvm::raw_ostream &Out, const PrintingPolicy &Policy, unsigned Indentation = 0); void dump() const; + void dumpXML() const; + void dumpXML(llvm::raw_ostream &OS) const; private: const Attr *getAttrsImpl() const; +protected: + ASTMutationListener *getASTMutationListener() const; }; /// PrettyStackTraceDecl - If a crash occurs, indicate that it happened when @@ -681,23 +704,24 @@ public: /// class DeclContext { /// DeclKind - This indicates which class this is. - Decl::Kind DeclKind : 8; + unsigned DeclKind : 8; /// \brief Whether this declaration context also has some external /// storage that contains additional declarations that are lexically /// part of this context. - mutable bool ExternalLexicalStorage : 1; + mutable unsigned ExternalLexicalStorage : 1; /// \brief Whether this declaration context also has some external /// storage that contains additional declarations that are visible /// in this context. - mutable bool ExternalVisibleStorage : 1; + mutable unsigned ExternalVisibleStorage : 1; /// \brief Pointer to the data structure used to lookup declarations /// within this context (or a DependentStoredDeclsMap if this is a /// dependent context). mutable StoredDeclsMap *LookupPtr; +protected: /// FirstDecl - The first declaration stored within this declaration /// context. mutable Decl *FirstDecl; @@ -710,7 +734,12 @@ class DeclContext { friend class ExternalASTSource; -protected: + /// \brief Build up a chain of declarations. + /// + /// \returns the first/last pair of declarations. + static std::pair + BuildDeclChain(const llvm::SmallVectorImpl &Decls); + DeclContext(Decl::Kind K) : DeclKind(K), ExternalLexicalStorage(false), ExternalVisibleStorage(false), LookupPtr(0), FirstDecl(0), @@ -720,7 +749,7 @@ public: ~DeclContext(); Decl::Kind getDeclKind() const { - return DeclKind; + return static_cast(DeclKind); } const char *getDeclKindName() const; @@ -807,6 +836,10 @@ public: /// C++0x scoped enums), and C++ linkage specifications. bool isTransparentContext() const; + /// \brief Determines whether this context is, or is nested within, + /// a C++ extern "C" linkage spec. + bool isExternCContext() const; + /// \brief Determine whether this declaration context is equivalent /// to the declaration context DC. bool Equals(const DeclContext *DC) const { diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index a9802bf..d11ee8f 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -35,6 +35,7 @@ class CXXMethodDecl; class CXXRecordDecl; class CXXMemberLookupCriteria; class CXXFinalOverriderMap; +class CXXIndirectPrimaryBaseSet; class FriendDecl; /// \brief Represents any kind of function declaration, whether it is a @@ -112,6 +113,8 @@ class AccessSpecDecl : public Decl { : Decl(AccessSpec, DC, ASLoc), ColonLoc(ColonLoc) { setAccess(AS); } + AccessSpecDecl(EmptyShell Empty) + : Decl(AccessSpec, Empty) { } public: /// getAccessSpecifierLoc - The location of the access specifier. SourceLocation getAccessSpecifierLoc() const { return getLocation(); } @@ -132,6 +135,9 @@ public: SourceLocation ColonLoc) { return new (C) AccessSpecDecl(AS, DC, ASLoc, ColonLoc); } + static AccessSpecDecl *Create(ASTContext &C, EmptyShell Empty) { + return new (C) AccessSpecDecl(Empty); + } // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -162,6 +168,10 @@ class CXXBaseSpecifier { /// specifier (if present). SourceRange Range; + /// \brief The source location of the ellipsis, if this is a pack + /// expansion. + SourceLocation EllipsisLoc; + /// Virtual - Whether this is a virtual base class or not. bool Virtual : 1; @@ -177,6 +187,10 @@ class CXXBaseSpecifier { /// VC++ bug. unsigned Access : 2; + /// InheritConstructors - Whether the class contains a using declaration + /// to inherit the named class's constructors. + bool InheritConstructors : 1; + /// BaseTypeInfo - The type of the base class. This will be a class or struct /// (or a typedef of such). The source code range does not include the /// "virtual" or access specifier. @@ -186,8 +200,9 @@ public: CXXBaseSpecifier() { } CXXBaseSpecifier(SourceRange R, bool V, bool BC, AccessSpecifier A, - TypeSourceInfo *TInfo) - : Range(R), Virtual(V), BaseOfClass(BC), Access(A), BaseTypeInfo(TInfo) { } + TypeSourceInfo *TInfo, SourceLocation EllipsisLoc) + : Range(R), EllipsisLoc(EllipsisLoc), Virtual(V), BaseOfClass(BC), + Access(A), InheritConstructors(false), BaseTypeInfo(TInfo) { } /// getSourceRange - Retrieves the source range that contains the /// entire base specifier. @@ -201,6 +216,22 @@ public: /// with the 'class' keyword (vs. one declared with the 'struct' keyword). bool isBaseOfClass() const { return BaseOfClass; } + /// \brief Determine whether this base specifier is a pack expansion. + bool isPackExpansion() const { return EllipsisLoc.isValid(); } + + /// \brief Determine whether this base class's constructors get inherited. + bool getInheritConstructors() const { return InheritConstructors; } + + /// \brief Set that this base class's constructors should be inherited. + void setInheritConstructors(bool Inherit = true) { + InheritConstructors = Inherit; + } + + /// \brief For a pack expansion, determine the location of the ellipsis. + SourceLocation getEllipsisLoc() const { + return EllipsisLoc; + } + /// getAccessSpecifier - Returns the access specifier for this base /// specifier. This is the actual base specifier as used for /// semantic analysis, so the result can never be AS_none. To @@ -336,20 +367,20 @@ class CXXRecordDecl : public RecordDecl { /// \brief Whether we have already declared a destructor within the class. bool DeclaredDestructor : 1; - - /// Bases - Base classes of this class. - /// FIXME: This is wasted space for a union. - CXXBaseSpecifier *Bases; /// NumBases - The number of base class specifiers in Bases. unsigned NumBases; - - /// VBases - direct and indirect virtual base classes of this class. - CXXBaseSpecifier *VBases; - + /// NumVBases - The number of virtual base class specifiers in VBases. unsigned NumVBases; + /// Bases - Base classes of this class. + /// FIXME: This is wasted space for a union. + LazyCXXBaseSpecifiersPtr Bases; + + /// VBases - direct and indirect virtual base classes of this class. + LazyCXXBaseSpecifiersPtr VBases; + /// Conversions - Overload set containing the conversion functions /// of this C++ class (but not its inherited conversion /// functions). Each of the entries in this overload set is a @@ -371,6 +402,15 @@ class CXXRecordDecl : public RecordDecl { /// in reverse order. FriendDecl *FirstFriend; + /// \brief Retrieve the set of direct base classes. + CXXBaseSpecifier *getBases() const { + return Bases.get(Definition->getASTContext().getExternalSource()); + } + + /// \brief Retrieve the set of virtual base classes. + CXXBaseSpecifier *getVBases() const { + return VBases.get(Definition->getASTContext().getExternalSource()); + } } *DefinitionData; struct DefinitionData &data() { @@ -395,9 +435,17 @@ class CXXRecordDecl : public RecordDecl { llvm::PointerUnion TemplateOrInstantiation; -#ifndef NDEBUG - void CheckConversionFunction(NamedDecl *D); -#endif + friend class DeclContext; + + /// \brief Notify the class that member has been added. + /// + /// This routine helps maintain information about the class based on which + /// members have been added. It will be invoked by DeclContext::addDecl() + /// whenever a member is added to this record. + void addedMember(Decl *D); + + void markedVirtualFunctionPure(); + friend void FunctionDecl::setPure(bool); protected: CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC, @@ -445,12 +493,12 @@ public: bool hasDefinition() const { return DefinitionData != 0; } - static CXXRecordDecl *Create(ASTContext &C, TagKind TK, DeclContext *DC, + static CXXRecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, SourceLocation TKL = SourceLocation(), CXXRecordDecl* PrevDecl=0, bool DelayTypeCreation = false); - static CXXRecordDecl *Create(ASTContext &C, EmptyShell Empty); + static CXXRecordDecl *Create(const ASTContext &C, EmptyShell Empty); bool isDynamicClass() const { return data().Polymorphic || data().NumVBases != 0; @@ -463,8 +511,8 @@ public: /// class. unsigned getNumBases() const { return data().NumBases; } - base_class_iterator bases_begin() { return data().Bases; } - base_class_const_iterator bases_begin() const { return data().Bases; } + base_class_iterator bases_begin() { return data().getBases(); } + base_class_const_iterator bases_begin() const { return data().getBases(); } base_class_iterator bases_end() { return bases_begin() + data().NumBases; } base_class_const_iterator bases_end() const { return bases_begin() + data().NumBases; @@ -486,8 +534,8 @@ public: /// class. unsigned getNumVBases() const { return data().NumVBases; } - base_class_iterator vbases_begin() { return data().VBases; } - base_class_const_iterator vbases_begin() const { return data().VBases; } + base_class_iterator vbases_begin() { return data().getVBases(); } + base_class_const_iterator vbases_begin() const { return data().getVBases(); } base_class_iterator vbases_end() { return vbases_begin() + data().NumVBases; } base_class_const_iterator vbases_end() const { return vbases_begin() + data().NumVBases; @@ -553,18 +601,12 @@ public: return data().DeclaredDefaultConstructor; } - /// \brief Note whether this class has already had its default constructor - /// implicitly declared or doesn't need one. - void setDeclaredDefaultConstructor(bool DDC) { - data().DeclaredDefaultConstructor = DDC; - } - /// hasConstCopyConstructor - Determines whether this class has a /// copy constructor that accepts a const-qualified argument. - bool hasConstCopyConstructor(ASTContext &Context) const; + bool hasConstCopyConstructor(const ASTContext &Context) const; /// getCopyConstructor - Returns the copy constructor for this class - CXXConstructorDecl *getCopyConstructor(ASTContext &Context, + CXXConstructorDecl *getCopyConstructor(const ASTContext &Context, unsigned TypeQuals) const; /// \brief Retrieve the copy-assignment operator for this class, if available. @@ -579,11 +621,6 @@ public: /// a unique copy-assignment operator could not be found. CXXMethodDecl *getCopyAssignmentOperator(bool ArgIsConst) const; - /// addedConstructor - Notify the class that another constructor has - /// been added. This routine helps maintain information about the - /// class based on which constructors have been added. - void addedConstructor(ASTContext &Context, CXXConstructorDecl *ConDecl); - /// hasUserDeclaredConstructor - Whether this class has any /// user-declared constructors. When true, a default constructor /// will not be implicitly declared. @@ -606,17 +643,6 @@ public: return data().DeclaredCopyConstructor; } - /// \brief Note whether this class has already had its copy constructor - /// declared. - void setDeclaredCopyConstructor(bool DCC) { - data().DeclaredCopyConstructor = DCC; - } - - /// addedAssignmentOperator - Notify the class that another assignment - /// operator has been added. This routine helps maintain information about the - /// class based on which operators have been added. - void addedAssignmentOperator(ASTContext &Context, CXXMethodDecl *OpDecl); - /// hasUserDeclaredCopyAssignment - Whether this class has a /// user-declared copy assignment operator. When false, a copy /// assigment operator will be implicitly declared. @@ -632,12 +658,6 @@ public: return data().DeclaredCopyAssignment; } - /// \brief Note whether this class has already had its copy assignment - /// operator declared. - void setDeclaredCopyAssignment(bool DCA) { - data().DeclaredCopyAssignment = DCA; - } - /// hasUserDeclaredDestructor - Whether this class has a /// user-declared destructor. When false, a destructor will be /// implicitly declared. @@ -645,26 +665,12 @@ public: return data().UserDeclaredDestructor; } - /// setUserDeclaredDestructor - Set whether this class has a - /// user-declared destructor. If not set by the time the class is - /// fully defined, a destructor will be implicitly declared. - void setUserDeclaredDestructor(bool UCD) { - data().UserDeclaredDestructor = UCD; - if (UCD) - data().DeclaredDestructor = true; - } - /// \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 Note whether this class has already had its destructor declared. - void setDeclaredDestructor(bool DD) { - data().DeclaredDestructor = DD; - } - + /// getConversions - Retrieve the overload set containing all of the /// conversion functions in this class. UnresolvedSetImpl *getConversionFunctions() { @@ -682,13 +688,6 @@ public: return getConversionFunctions()->end(); } - /// Replaces a conversion function with a new declaration. - /// - /// Returns true if the old conversion was found. - bool replaceConversion(const NamedDecl* Old, NamedDecl *New) { - return getConversionFunctions()->replace(Old, New); - } - /// Removes a conversion function from this class. The conversion /// function must currently be a member of this class. Furthermore, /// this class must currently be in the process of being defined. @@ -698,105 +697,52 @@ public: /// in current class; including conversion function templates. const UnresolvedSetImpl *getVisibleConversionFunctions(); - /// addConversionFunction - Registers a conversion function which - /// this class declares directly. - void addConversionFunction(NamedDecl *Decl) { -#ifndef NDEBUG - CheckConversionFunction(Decl); -#endif - - // We intentionally don't use the decl's access here because it - // hasn't been set yet. That's really just a misdesign in Sema. - data().Conversions.addDecl(Decl); - } - /// isAggregate - Whether this class is an aggregate (C++ /// [dcl.init.aggr]), which is a class with no user-declared /// constructors, no private or protected non-static data members, /// no base classes, and no virtual functions (C++ [dcl.init.aggr]p1). bool isAggregate() const { return data().Aggregate; } - /// setAggregate - Set whether this class is an aggregate (C++ - /// [dcl.init.aggr]). - void setAggregate(bool Agg) { data().Aggregate = Agg; } - - /// setMethodAsVirtual - Make input method virtual and set the necesssary - /// special function bits and other bits accordingly. - void setMethodAsVirtual(FunctionDecl *Method); - /// 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. bool isPOD() const { return data().PlainOldData; } - /// setPOD - Set whether this class is a POD-type (C++ [class]p4). - void setPOD(bool POD) { data().PlainOldData = POD; } - /// isEmpty - Whether this class is empty (C++0x [meta.unary.prop]), which /// means it has a virtual function, virtual base, data member (other than /// 0-width bit-field) or inherits from a non-empty class. Does NOT include /// a check for union-ness. bool isEmpty() const { return data().Empty; } - /// Set whether this class is empty (C++0x [meta.unary.prop]) - void setEmpty(bool Emp) { data().Empty = Emp; } - /// isPolymorphic - Whether this class is polymorphic (C++ [class.virtual]), /// which means that the class contains or inherits a virtual function. bool isPolymorphic() const { return data().Polymorphic; } - /// setPolymorphic - Set whether this class is polymorphic (C++ - /// [class.virtual]). - void setPolymorphic(bool Poly) { data().Polymorphic = Poly; } - /// isAbstract - Whether this class is abstract (C++ [class.abstract]), /// which means that the class contains or inherits a pure virtual function. bool isAbstract() const { return data().Abstract; } - /// setAbstract - Set whether this class is abstract (C++ [class.abstract]) - void setAbstract(bool Abs) { data().Abstract = Abs; } - // hasTrivialConstructor - Whether this class has a trivial constructor // (C++ [class.ctor]p5) bool hasTrivialConstructor() const { return data().HasTrivialConstructor; } - // setHasTrivialConstructor - Set whether this class has a trivial constructor - // (C++ [class.ctor]p5) - void setHasTrivialConstructor(bool TC) { data().HasTrivialConstructor = TC; } - // hasTrivialCopyConstructor - Whether this class has a trivial copy // constructor (C++ [class.copy]p6) bool hasTrivialCopyConstructor() const { return data().HasTrivialCopyConstructor; } - // setHasTrivialCopyConstructor - Set whether this class has a trivial - // copy constructor (C++ [class.copy]p6) - void setHasTrivialCopyConstructor(bool TC) { - data().HasTrivialCopyConstructor = TC; - } - // hasTrivialCopyAssignment - Whether this class has a trivial copy // assignment operator (C++ [class.copy]p11) bool hasTrivialCopyAssignment() const { return data().HasTrivialCopyAssignment; } - // setHasTrivialCopyAssignment - Set whether this class has a - // trivial copy assignment operator (C++ [class.copy]p11) - void setHasTrivialCopyAssignment(bool TC) { - data().HasTrivialCopyAssignment = TC; - } - // hasTrivialDestructor - Whether this class has a trivial destructor // (C++ [class.dtor]p3) bool hasTrivialDestructor() const { return data().HasTrivialDestructor; } - // setHasTrivialDestructor - Set whether this class has a trivial destructor - // (C++ [class.dtor]p3) - void setHasTrivialDestructor(bool TC) { data().HasTrivialDestructor = TC; } - /// \brief If this record is an instantiation of a member class, /// retrieves the member class from which it was instantiated. /// @@ -854,9 +800,6 @@ public: /// \brief Set the kind of specialization or template instantiation this is. void setTemplateSpecializationKind(TemplateSpecializationKind TSK); - - /// getDefaultConstructor - Returns the default constructor for this class - CXXConstructorDecl *getDefaultConstructor(); /// getDestructor - Returns the destructor decl for this class. CXXDestructorDecl *getDestructor() const; @@ -880,7 +823,7 @@ public: /// \param Base the base class we are searching for. /// /// \returns true if this class is derived from Base, false otherwise. - bool isDerivedFrom(CXXRecordDecl *Base) const; + bool isDerivedFrom(const CXXRecordDecl *Base) const; /// \brief Determine whether this class is derived from the type \p Base. /// @@ -898,7 +841,7 @@ public: /// /// \todo add a separate paramaeter to configure IsDerivedFrom, rather than /// tangling input and output in \p Paths - bool isDerivedFrom(CXXRecordDecl *Base, CXXBasePaths &Paths) const; + bool isDerivedFrom(const CXXRecordDecl *Base, CXXBasePaths &Paths) const; /// \brief Determine whether this class is virtually derived from /// the class \p Base. @@ -1034,6 +977,9 @@ public: /// most-derived class in the class hierarchy. void getFinalOverriders(CXXFinalOverriderMap &FinaOverriders) const; + /// \brief Get the indirect primary bases for this class. + void getIndirectPrimaryBases(CXXIndirectPrimaryBaseSet& Bases) const; + /// viewInheritance - Renders and displays an inheritance diagram /// for this C++ class and all of its base classes (transitively) using /// GraphViz. @@ -1048,6 +994,27 @@ public: return (PathAccess > DeclAccess ? PathAccess : DeclAccess); } + /// \brief Indicates that the definition of this class is now complete. + virtual void completeDefinition(); + + /// \brief Indicates that the definition of this class is now complete, + /// and provides a final overrider map to help determine + /// + /// \param FinalOverriders The final overrider map for this class, which can + /// be provided as an optimization for abstract-class checking. If NULL, + /// final overriders will be computed if they are needed to complete the + /// definition. + void completeDefinition(CXXFinalOverriderMap *FinalOverriders); + + /// \brief Determine whether this class may end up being abstract, even though + /// it is not yet known to be abstract. + /// + /// \returns true if this class is not known to be abstract but has any + /// base classes that are abstract. In this case, \c completeDefinition() + /// will need to compute final overriders to determine whether the class is + /// actually abstract. + bool mayBeAbstract() const; + static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K >= firstCXXRecord && K <= lastCXXRecord; @@ -1059,6 +1026,8 @@ public: friend class ASTDeclReader; friend class ASTDeclWriter; + friend class ASTReader; + friend class ASTWriter; }; /// CXXMethodDecl - Represents a static or instance method of a @@ -1139,6 +1108,20 @@ public: return getType()->getAs()->getTypeQuals(); } + /// \brief Retrieve the ref-qualifier associated with this method. + /// + /// In the following example, \c f() has an lvalue ref-qualifier, \c g() + /// has an rvalue ref-qualifier, and \c h() has no ref-qualifier. + /// \code + /// struct X { + /// void f() &; + /// void g() &&; + /// void h(); + /// }; + RefQualifierKind getRefQualifier() const { + return getType()->getAs()->getRefQualifier(); + } + bool hasInlineBody() const; // Implement isa/cast/dyncast/etc. @@ -1149,7 +1132,7 @@ public: } }; -/// CXXBaseOrMemberInitializer - Represents a C++ base or member +/// CXXCtorInitializer - Represents a C++ base or member /// initializer, which is part of a constructor initializer that /// initializes one non-static member variable or one base class. For /// example, in the following, both 'A(a)' and 'f(3.14159)' are member @@ -1163,37 +1146,20 @@ public: /// B(A& a) : A(a), f(3.14159) { } /// }; /// @endcode -class CXXBaseOrMemberInitializer { - /// \brief Either the base class name (stored as a TypeSourceInfo*) or the - /// field being initialized. - llvm::PointerUnion BaseOrMember; +class CXXCtorInitializer { + /// \brief Either the base class name (stored as a TypeSourceInfo*), an normal + /// field (FieldDecl) or an anonymous field (IndirectFieldDecl*) being + /// initialized. + llvm::PointerUnion3 + Initializee; - /// \brief The source location for the field name. - SourceLocation MemberLocation; + /// \brief The source location for the field name or, for a base initializer + /// pack expansion, the location of the ellipsis. + SourceLocation MemberOrEllipsisLocation; /// \brief The argument used to initialize the base or member, which may /// end up constructing an object (when multiple arguments are involved). Stmt *Init; - - /// \brief Stores either the constructor to call to initialize this base or - /// member (a CXXConstructorDecl pointer), or stores the anonymous union of - /// which the initialized value is a member. - /// - /// When the value is a FieldDecl pointer, 'BaseOrMember' is class's - /// anonymous union data member, this field holds the FieldDecl for the - /// member of the anonymous union being initialized. - /// @code - /// struct X { - /// X() : au_i1(123) {} - /// union { - /// int au_i1; - /// float au_f1; - /// }; - /// }; - /// @endcode - /// In above example, BaseOrMember holds the field decl. for anonymous union - /// and AnonUnionMember holds field decl for au_i1. - FieldDecl *AnonUnionMember; /// LParenLoc - Location of the left paren of the ctor-initializer. SourceLocation LParenLoc; @@ -1208,6 +1174,7 @@ class CXXBaseOrMemberInitializer { /// IsWritten - Whether or not the initializer is explicitly written /// in the sources. bool IsWritten : 1; + /// SourceOrderOrNumArrayIndices - If IsWritten is true, then this /// number keeps track of the textual order of this initializer in the /// original sources, counting from 0; otherwise, if IsWritten is false, @@ -1215,50 +1182,62 @@ class CXXBaseOrMemberInitializer { /// object in memory. unsigned SourceOrderOrNumArrayIndices : 14; - CXXBaseOrMemberInitializer(ASTContext &Context, - FieldDecl *Member, SourceLocation MemberLoc, - SourceLocation L, - Expr *Init, - SourceLocation R, - VarDecl **Indices, - unsigned NumIndices); + CXXCtorInitializer(ASTContext &Context, FieldDecl *Member, + SourceLocation MemberLoc, SourceLocation L, Expr *Init, + SourceLocation R, VarDecl **Indices, unsigned NumIndices); public: - /// CXXBaseOrMemberInitializer - Creates a new base-class initializer. + /// CXXCtorInitializer - Creates a new base-class initializer. explicit - CXXBaseOrMemberInitializer(ASTContext &Context, - TypeSourceInfo *TInfo, bool IsVirtual, - SourceLocation L, - Expr *Init, - SourceLocation R); + CXXCtorInitializer(ASTContext &Context, TypeSourceInfo *TInfo, bool IsVirtual, + SourceLocation L, Expr *Init, SourceLocation R, + SourceLocation EllipsisLoc); - /// CXXBaseOrMemberInitializer - Creates a new member initializer. + /// CXXCtorInitializer - Creates a new member initializer. explicit - CXXBaseOrMemberInitializer(ASTContext &Context, - FieldDecl *Member, SourceLocation MemberLoc, - SourceLocation L, - Expr *Init, - SourceLocation R); + CXXCtorInitializer(ASTContext &Context, FieldDecl *Member, + SourceLocation MemberLoc, SourceLocation L, Expr *Init, + SourceLocation R); + + explicit + CXXCtorInitializer(ASTContext &Context, IndirectFieldDecl *Member, + SourceLocation MemberLoc, SourceLocation L, Expr *Init, + SourceLocation R); /// \brief Creates a new member initializer that optionally contains /// array indices used to describe an elementwise initialization. - static CXXBaseOrMemberInitializer *Create(ASTContext &Context, - FieldDecl *Member, - SourceLocation MemberLoc, - SourceLocation L, - Expr *Init, - SourceLocation R, - VarDecl **Indices, - unsigned NumIndices); + static CXXCtorInitializer *Create(ASTContext &Context, FieldDecl *Member, + SourceLocation MemberLoc, SourceLocation L, + Expr *Init, SourceLocation R, + VarDecl **Indices, unsigned NumIndices); /// isBaseInitializer - Returns true when this initializer is /// initializing a base class. - bool isBaseInitializer() const { return BaseOrMember.is(); } + bool isBaseInitializer() const { return Initializee.is(); } /// isMemberInitializer - Returns true when this initializer is /// initializing a non-static data member. - bool isMemberInitializer() const { return BaseOrMember.is(); } + bool isMemberInitializer() const { return Initializee.is(); } + + bool isAnyMemberInitializer() const { + return isMemberInitializer() || isIndirectMemberInitializer(); + } + bool isIndirectMemberInitializer() const { + return Initializee.is(); + } + + /// \brief Determine whether this initializer is a pack expansion. + bool isPackExpansion() const { + return isBaseInitializer() && MemberOrEllipsisLocation.isValid(); + } + + // \brief For a pack expansion, returns the location of the ellipsis. + SourceLocation getEllipsisLoc() const { + assert(isPackExpansion() && "Initializer is not a pack expansion"); + return MemberOrEllipsisLocation; + } + /// If this is a base class initializer, returns the type of the /// base class with location information. Otherwise, returns an NULL /// type location. @@ -1267,7 +1246,6 @@ public: /// If this is a base class initializer, returns the type of the base class. /// Otherwise, returns NULL. const Type *getBaseClass() const; - Type *getBaseClass(); /// Returns whether the base is virtual or not. bool isBaseVirtual() const { @@ -1278,7 +1256,7 @@ public: /// \brief Returns the declarator information for a base class initializer. TypeSourceInfo *getBaseClassInfo() const { - return BaseOrMember.dyn_cast(); + return Initializee.dyn_cast(); } /// getMember - If this is a member initializer, returns the @@ -1286,18 +1264,28 @@ public: /// initialized. Otherwise, returns NULL. FieldDecl *getMember() const { if (isMemberInitializer()) - return BaseOrMember.get(); + return Initializee.get(); + else + return 0; + } + FieldDecl *getAnyMember() const { + if (isMemberInitializer()) + return Initializee.get(); + else if (isIndirectMemberInitializer()) + return Initializee.get()->getAnonField(); else return 0; } - SourceLocation getMemberLocation() const { - return MemberLocation; + IndirectFieldDecl *getIndirectMember() const { + if (isIndirectMemberInitializer()) + return Initializee.get(); + else + return 0; } - void setMember(FieldDecl *Member) { - assert(isMemberInitializer()); - BaseOrMember = Member; + SourceLocation getMemberLocation() const { + return MemberOrEllipsisLocation; } /// \brief Determine the source location of the initializer. @@ -1329,15 +1317,7 @@ public: IsWritten = true; SourceOrderOrNumArrayIndices = static_cast(pos); } - - FieldDecl *getAnonUnionMember() const { - return AnonUnionMember; - } - void setAnonUnionMember(FieldDecl *anonMember) { - AnonUnionMember = anonMember; - } - SourceLocation getLParenLoc() const { return LParenLoc; } SourceLocation getRParenLoc() const { return RParenLoc; } @@ -1388,10 +1368,10 @@ class CXXConstructorDecl : public CXXMethodDecl { bool ImplicitlyDefined : 1; /// Support for base and member initializers. - /// BaseOrMemberInitializers - The arguments used to initialize the base + /// CtorInitializers - The arguments used to initialize the base /// or member. - CXXBaseOrMemberInitializer **BaseOrMemberInitializers; - unsigned NumBaseOrMemberInitializers; + CXXCtorInitializer **CtorInitializers; + unsigned NumCtorInitializers; CXXConstructorDecl(CXXRecordDecl *RD, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, @@ -1400,7 +1380,7 @@ class CXXConstructorDecl : public CXXMethodDecl { : CXXMethodDecl(CXXConstructor, RD, NameInfo, T, TInfo, false, SC_None, isInline), IsExplicitSpecified(isExplicitSpecified), ImplicitlyDefined(false), - BaseOrMemberInitializers(0), NumBaseOrMemberInitializers(0) { + CtorInitializers(0), NumCtorInitializers(0) { setImplicit(isImplicitlyDeclared); } @@ -1443,37 +1423,54 @@ public: } /// init_iterator - Iterates through the member/base initializer list. - typedef CXXBaseOrMemberInitializer **init_iterator; + typedef CXXCtorInitializer **init_iterator; /// init_const_iterator - Iterates through the memberbase initializer list. - typedef CXXBaseOrMemberInitializer * const * init_const_iterator; + typedef CXXCtorInitializer * const * init_const_iterator; /// init_begin() - Retrieve an iterator to the first initializer. - init_iterator init_begin() { return BaseOrMemberInitializers; } + init_iterator init_begin() { return CtorInitializers; } /// begin() - Retrieve an iterator to the first initializer. - init_const_iterator init_begin() const { return BaseOrMemberInitializers; } + init_const_iterator init_begin() const { return CtorInitializers; } /// init_end() - Retrieve an iterator past the last initializer. init_iterator init_end() { - return BaseOrMemberInitializers + NumBaseOrMemberInitializers; + return CtorInitializers + NumCtorInitializers; } /// end() - Retrieve an iterator past the last initializer. init_const_iterator init_end() const { - return BaseOrMemberInitializers + NumBaseOrMemberInitializers; + return CtorInitializers + NumCtorInitializers; + } + + typedef std::reverse_iterator init_reverse_iterator; + typedef std::reverse_iterator init_const_reverse_iterator; + + init_reverse_iterator init_rbegin() { + return init_reverse_iterator(init_end()); + } + init_const_reverse_iterator init_rbegin() const { + return init_const_reverse_iterator(init_end()); + } + + init_reverse_iterator init_rend() { + return init_reverse_iterator(init_begin()); + } + init_const_reverse_iterator init_rend() const { + return init_const_reverse_iterator(init_begin()); } /// getNumArgs - Determine the number of arguments used to /// initialize the member or base. - unsigned getNumBaseOrMemberInitializers() const { - return NumBaseOrMemberInitializers; + unsigned getNumCtorInitializers() const { + return NumCtorInitializers; } - void setNumBaseOrMemberInitializers(unsigned numBaseOrMemberInitializers) { - NumBaseOrMemberInitializers = numBaseOrMemberInitializers; + void setNumCtorInitializers(unsigned numCtorInitializers) { + NumCtorInitializers = numCtorInitializers; } - void setBaseOrMemberInitializers(CXXBaseOrMemberInitializer ** initializers) { - BaseOrMemberInitializers = initializers; + void setCtorInitializers(CXXCtorInitializer ** initializers) { + CtorInitializers = initializers; } /// isDefaultConstructor - Whether this constructor is a default /// constructor (C++ [class.ctor]p5), which can be used to @@ -1502,15 +1499,44 @@ public: return isCopyConstructor(TypeQuals); } + /// \brief Determine whether this constructor is a move constructor + /// (C++0x [class.copy]p3), which can be used to move values of the class. + /// + /// \param TypeQuals If this constructor is a move constructor, will be set + /// to the type qualifiers on the referent of the first parameter's type. + bool isMoveConstructor(unsigned &TypeQuals) const; + + /// \brief Determine whether this constructor is a move constructor + /// (C++0x [class.copy]p3), which can be used to move values of the class. + bool isMoveConstructor() const; + + /// \brief Determine whether this is a copy or move constructor. + /// + /// \param TypeQuals Will be set to the type qualifiers on the reference + /// parameter, if in fact this is a copy or move constructor. + bool isCopyOrMoveConstructor(unsigned &TypeQuals) const; + + /// \brief Determine whether this a copy or move constructor. + bool isCopyOrMoveConstructor() const { + unsigned Quals; + return isCopyOrMoveConstructor(Quals); + } + /// isConvertingConstructor - Whether this constructor is a /// converting constructor (C++ [class.conv.ctor]), which can be /// used for user-defined conversions. bool isConvertingConstructor(bool AllowExplicit) const; /// \brief Determine whether this is a member template specialization that - /// looks like a copy constructor. Such constructors are never used to copy + /// would copy the object to itself. Such constructors are never used to copy /// an object. - bool isCopyConstructorLikeSpecialization() const; + bool isSpecializationCopyingObject() const; + + /// \brief Get the constructor that this inheriting constructor is based on. + const CXXConstructorDecl *getInheritedConstructor() const; + + /// \brief Set the constructor that this inheriting constructor is based on. + void setInheritedConstructor(const CXXConstructorDecl *BaseCtor); // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -1542,8 +1568,9 @@ class CXXDestructorDecl : public CXXMethodDecl { FunctionDecl *OperatorDelete; CXXDestructorDecl(CXXRecordDecl *RD, const DeclarationNameInfo &NameInfo, - QualType T, bool isInline, bool isImplicitlyDeclared) - : CXXMethodDecl(CXXDestructor, RD, NameInfo, T, /*TInfo=*/0, false, + QualType T, TypeSourceInfo *TInfo, + bool isInline, bool isImplicitlyDeclared) + : CXXMethodDecl(CXXDestructor, RD, NameInfo, T, TInfo, false, SC_None, isInline), ImplicitlyDefined(false), OperatorDelete(0) { setImplicit(isImplicitlyDeclared); @@ -1553,7 +1580,8 @@ public: static CXXDestructorDecl *Create(ASTContext& C, EmptyShell Empty); static CXXDestructorDecl *Create(ASTContext &C, CXXRecordDecl *RD, const DeclarationNameInfo &NameInfo, - QualType T, bool isInline, + QualType T, TypeSourceInfo* TInfo, + bool isInline, bool isImplicitlyDeclared); /// isImplicitlyDefined - Whether this destructor was implicitly @@ -1918,13 +1946,16 @@ class UsingShadowDecl : public NamedDecl { /// The referenced declaration. NamedDecl *Underlying; - /// The using declaration which introduced this decl. - UsingDecl *Using; + /// \brief The using declaration which introduced this decl or the next using + /// shadow declaration contained in the aforementioned using declaration. + NamedDecl *UsingOrNextShadow; + friend class UsingDecl; UsingShadowDecl(DeclContext *DC, SourceLocation Loc, UsingDecl *Using, NamedDecl *Target) : NamedDecl(UsingShadow, DC, Loc, DeclarationName()), - Underlying(Target), Using(Using) { + Underlying(Target), + UsingOrNextShadow(reinterpret_cast(Using)) { if (Target) { setDeclName(Target->getDeclName()); IdentifierNamespace = Target->getIdentifierNamespace(); @@ -1952,15 +1983,20 @@ public: } /// \brief Gets the using declaration to which this declaration is tied. - UsingDecl *getUsingDecl() const { return Using; } + UsingDecl *getUsingDecl() const; - /// \brief Sets the using declaration that introduces this target - /// declaration. - void setUsingDecl(UsingDecl* UD) { Using = UD; } + /// \brief The next using shadow declaration contained in the shadow decl + /// chain of the using declaration which introduced this decl. + UsingShadowDecl *getNextUsingShadowDecl() const { + return dyn_cast_or_null(UsingOrNextShadow); + } static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classof(const UsingShadowDecl *D) { return true; } static bool classofKind(Kind K) { return K == Decl::UsingShadow; } + + friend class ASTDeclReader; + friend class ASTDeclWriter; }; /// UsingDecl - Represents a C++ using-declaration. For example: @@ -1980,10 +2016,9 @@ class UsingDecl : public NamedDecl { /// declaration name embedded in the ValueDecl base class. DeclarationNameLoc DNLoc; - /// \brief The collection of shadow declarations associated with - /// this using declaration. This set can change as a class is - /// processed. - llvm::SmallPtrSet Shadows; + /// \brief The first shadow declaration of the shadow decl chain associated + /// with this using declaration. + UsingShadowDecl *FirstUsingShadow; // \brief Has 'typename' keyword. bool IsTypeName; @@ -1993,7 +2028,7 @@ class UsingDecl : public NamedDecl { const DeclarationNameInfo &NameInfo, bool IsTypeNameArg) : NamedDecl(Using, DC, NameInfo.getLoc(), NameInfo.getName()), NestedNameRange(NNR), UsingLocation(UL), TargetNestedName(TargetNNS), - DNLoc(NameInfo.getInfo()), IsTypeName(IsTypeNameArg) { + DNLoc(NameInfo.getInfo()), FirstUsingShadow(0),IsTypeName(IsTypeNameArg) { } public: @@ -2031,29 +2066,58 @@ public: /// \brief Sets whether the using declaration has 'typename'. void setTypeName(bool TN) { IsTypeName = TN; } - typedef llvm::SmallPtrSet::const_iterator shadow_iterator; - shadow_iterator shadow_begin() const { return Shadows.begin(); } - shadow_iterator shadow_end() const { return Shadows.end(); } + /// \brief Iterates through the using shadow declarations assosiated with + /// this using declaration. + class shadow_iterator { + /// \brief The current using shadow declaration. + UsingShadowDecl *Current; + + public: + typedef UsingShadowDecl* value_type; + typedef UsingShadowDecl* reference; + typedef UsingShadowDecl* pointer; + typedef std::forward_iterator_tag iterator_category; + typedef std::ptrdiff_t difference_type; + + shadow_iterator() : Current(0) { } + explicit shadow_iterator(UsingShadowDecl *C) : Current(C) { } - void addShadowDecl(UsingShadowDecl *S) { - assert(S->getUsingDecl() == this); - if (!Shadows.insert(S)) { - assert(false && "declaration already in set"); + reference operator*() const { return Current; } + pointer operator->() const { return Current; } + + shadow_iterator& operator++() { + Current = Current->getNextUsingShadowDecl(); + return *this; } - } - void removeShadowDecl(UsingShadowDecl *S) { - assert(S->getUsingDecl() == this); - if (!Shadows.erase(S)) { - assert(false && "declaration not in set"); + + shadow_iterator operator++(int) { + shadow_iterator tmp(*this); + ++(*this); + return tmp; } + + friend bool operator==(shadow_iterator x, shadow_iterator y) { + return x.Current == y.Current; + } + friend bool operator!=(shadow_iterator x, shadow_iterator y) { + return x.Current != y.Current; + } + }; + + shadow_iterator shadow_begin() const { + return shadow_iterator(FirstUsingShadow); } + shadow_iterator shadow_end() const { return shadow_iterator(); } /// \brief Return the number of shadowed declarations associated with this /// using declaration. - unsigned getNumShadowDecls() const { - return Shadows.size(); + unsigned shadow_size() const { + return std::distance(shadow_begin(), shadow_end()); } + void addShadowDecl(UsingShadowDecl *S); + void removeShadowDecl(UsingShadowDecl *S); + static UsingDecl *Create(ASTContext &C, DeclContext *DC, SourceRange NNR, SourceLocation UsingL, NestedNameSpecifier* TargetNNS, @@ -2145,6 +2209,9 @@ public: static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classof(const UnresolvedUsingValueDecl *D) { return true; } static bool classofKind(Kind K) { return K == UnresolvedUsingValue; } + + friend class ASTDeclReader; + friend class ASTDeclWriter; }; /// UnresolvedUsingTypenameDecl - Represents a dependent using diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h index 4b5e6fd..20d6da1 100644 --- a/include/clang/AST/DeclFriend.h +++ b/include/clang/AST/DeclFriend.h @@ -43,11 +43,16 @@ private: FriendUnion Friend; // A pointer to the next friend in the sequence. - FriendDecl *NextFriend; + LazyDeclPtr NextFriend; // Location of the 'friend' specifier. SourceLocation FriendLoc; + /// 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; + friend class CXXRecordDecl::friend_iterator; friend class CXXRecordDecl; @@ -55,13 +60,19 @@ private: SourceLocation FriendL) : Decl(Decl::Friend, DC, L), Friend(Friend), - NextFriend(0), - FriendLoc(FriendL) { + NextFriend(), + FriendLoc(FriendL), + UnsupportedFriend(false) { } explicit FriendDecl(EmptyShell Empty) - : Decl(Decl::Friend, Empty), NextFriend(0) { } + : Decl(Decl::Friend, Empty), NextFriend() { } + FriendDecl *getNextFriend() { + return cast_or_null( + NextFriend.get(getASTContext().getExternalSource())); + } + public: static FriendDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, FriendUnion Friend_, @@ -87,6 +98,14 @@ public: return FriendLoc; } + /// Determines if this friend kind is unsupported. + bool isUnsupportedFriend() const { + return UnsupportedFriend; + } + void setUnsupportedFriend(bool Unsupported) { + UnsupportedFriend = Unsupported; + } + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classof(const FriendDecl *D) { return true; } @@ -115,7 +134,7 @@ public: friend_iterator &operator++() { assert(Ptr && "attempt to increment past end of friend list"); - Ptr = Ptr->NextFriend; + Ptr = Ptr->getNextFriend(); return *this; } diff --git a/include/clang/AST/DeclGroup.h b/include/clang/AST/DeclGroup.h index 030291e..cb9e168 100644 --- a/include/clang/AST/DeclGroup.h +++ b/include/clang/AST/DeclGroup.h @@ -14,7 +14,7 @@ #ifndef LLVM_CLANG_AST_DECLGROUP_H #define LLVM_CLANG_AST_DECLGROUP_H -#include "llvm/System/DataTypes.h" +#include "llvm/Support/DataTypes.h" #include namespace clang { diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index ad26748..b3ca474 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -28,7 +28,7 @@ class ObjCProtocolDecl; class ObjCCategoryDecl; class ObjCPropertyDecl; class ObjCPropertyImplDecl; -class CXXBaseOrMemberInitializer; +class CXXCtorInitializer; class ObjCListBase { void operator=(const ObjCListBase &); // DO NOT IMPLEMENT @@ -437,7 +437,7 @@ public: class ObjCInterfaceDecl : public ObjCContainerDecl { /// TypeForDecl - This indicates the Type object that represents this /// TypeDecl. It is a cache maintained by ASTContext::getObjCInterfaceType - mutable Type *TypeForDecl; + mutable const Type *TypeForDecl; friend class ASTContext; /// Class's super class. @@ -449,8 +449,11 @@ class ObjCInterfaceDecl : public ObjCContainerDecl { /// Protocols reference in both the @interface and class extensions. ObjCList AllReferencedProtocols; - /// List of categories defined for this class. - /// FIXME: Why is this a linked list?? + /// \brief List of categories and class extensions defined for this class. + /// + /// Categories are stored as a linked list in the AST, since the categories + /// and class extensions come long after the initial interface declaration, + /// and we avoid dynamically-resized arrays in the AST whereever possible. ObjCCategoryDecl *CategoryList; /// IvarList - List of all ivars defined by this class; including class @@ -459,7 +462,11 @@ class ObjCInterfaceDecl : public ObjCContainerDecl { bool ForwardDecl:1; // declared with @class. bool InternalInterface:1; // true - no @interface for @implementation - + + /// \brief Indicates that the contents of this Objective-C class will be + /// completed by the external AST source when required. + mutable bool ExternallyCompleted : 1; + SourceLocation ClassLoc; // location of the class identifier. SourceLocation SuperClassLoc; // location of the super class identifier. SourceLocation EndLoc; // marks the '>', '}', or identifier. @@ -467,6 +474,7 @@ class ObjCInterfaceDecl : public ObjCContainerDecl { ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id, SourceLocation CLoc, bool FD, bool isInternal); + void LoadExternalDefinition() const; public: static ObjCInterfaceDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation atLoc, @@ -474,7 +482,16 @@ public: SourceLocation ClassLoc = SourceLocation(), bool ForwardDecl = false, bool isInternal = false); + + /// \brief Indicate that this Objective-C class is complete, but that + /// the external AST source will be responsible for filling in its contents + /// when a complete class is required. + void setExternallyCompleted(); + const ObjCProtocolList &getReferencedProtocols() const { + if (ExternallyCompleted) + LoadExternalDefinition(); + return ReferencedProtocols; } @@ -494,29 +511,47 @@ public: typedef ObjCProtocolList::iterator protocol_iterator; protocol_iterator protocol_begin() const { + if (ExternallyCompleted) + LoadExternalDefinition(); + return ReferencedProtocols.begin(); } protocol_iterator protocol_end() const { + if (ExternallyCompleted) + LoadExternalDefinition(); + return ReferencedProtocols.end(); } typedef ObjCProtocolList::loc_iterator protocol_loc_iterator; protocol_loc_iterator protocol_loc_begin() const { + if (ExternallyCompleted) + LoadExternalDefinition(); + return ReferencedProtocols.loc_begin(); } protocol_loc_iterator protocol_loc_end() const { + if (ExternallyCompleted) + LoadExternalDefinition(); + return ReferencedProtocols.loc_end(); } typedef ObjCList::iterator all_protocol_iterator; all_protocol_iterator all_referenced_protocol_begin() const { + if (ExternallyCompleted) + LoadExternalDefinition(); + return AllReferencedProtocols.empty() ? protocol_begin() : AllReferencedProtocols.begin(); } all_protocol_iterator all_referenced_protocol_end() const { + if (ExternallyCompleted) + LoadExternalDefinition(); + return AllReferencedProtocols.empty() ? protocol_end() : AllReferencedProtocols.end(); } @@ -551,10 +586,22 @@ public: bool isForwardDecl() const { return ForwardDecl; } void setForwardDecl(bool val) { ForwardDecl = val; } - ObjCInterfaceDecl *getSuperClass() const { return SuperClass; } + ObjCInterfaceDecl *getSuperClass() const { + if (ExternallyCompleted) + LoadExternalDefinition(); + + return SuperClass; + } + void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; } - ObjCCategoryDecl* getCategoryList() const { return CategoryList; } + ObjCCategoryDecl* getCategoryList() const { + if (ExternallyCompleted) + LoadExternalDefinition(); + + return CategoryList; + } + void setCategoryList(ObjCCategoryDecl *category) { CategoryList = category; } @@ -595,7 +642,7 @@ public: ObjCInterfaceDecl *lookupInheritedClass(const IdentifierInfo *ICName); // Lookup a method in the classes implementation hierarchy. - ObjCMethodDecl *lookupPrivateInstanceMethod(const Selector &Sel); + ObjCMethodDecl *lookupPrivateMethod(const Selector &Sel, bool Instance=true); // Location information, modeled after the Stmt API. SourceLocation getLocStart() const { return getLocation(); } // '@'interface @@ -621,8 +668,8 @@ public: bool RHSIsQualifiedID = false); // Low-level accessor - Type *getTypeForDecl() const { return TypeForDecl; } - void setTypeForDecl(Type *TD) const { TypeForDecl = TD; } + const Type *getTypeForDecl() const { return TypeForDecl; } + void setTypeForDecl(const Type *TD) const { TypeForDecl = TD; } static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classof(const ObjCInterfaceDecl *D) { return true; } @@ -991,6 +1038,7 @@ public: void insertNextClassCategory() { NextClassCategory = ClassInterface->getCategoryList(); ClassInterface->setCategoryList(this); + ClassInterface->setChangedSinceDeserialization(true); } bool IsClassExtension() const { return getIdentifier() == 0; } @@ -1168,7 +1216,7 @@ class ObjCImplementationDecl : public ObjCImplDecl { ObjCInterfaceDecl *SuperClass; /// Support for ivar initialization. /// IvarInitializers - The arguments used to initialize the ivars - CXXBaseOrMemberInitializer **IvarInitializers; + CXXCtorInitializer **IvarInitializers; unsigned NumIvarInitializers; /// true of class extension has at least one bitfield ivar. @@ -1187,10 +1235,10 @@ public: ObjCInterfaceDecl *superDecl); /// init_iterator - Iterates through the ivar initializer list. - typedef CXXBaseOrMemberInitializer **init_iterator; + typedef CXXCtorInitializer **init_iterator; /// init_const_iterator - Iterates through the ivar initializer list. - typedef CXXBaseOrMemberInitializer * const * init_const_iterator; + typedef CXXCtorInitializer * const * init_const_iterator; /// init_begin() - Retrieve an iterator to the first initializer. init_iterator init_begin() { return IvarInitializers; } @@ -1215,7 +1263,7 @@ public: } void setIvarInitializers(ASTContext &C, - CXXBaseOrMemberInitializer ** initializers, + CXXCtorInitializer ** initializers, unsigned numInitializers); bool hasSynthBitfield() const { return HasSynthBitfield; } @@ -1322,7 +1370,8 @@ public: OBJC_PR_retain = 0x10, OBJC_PR_copy = 0x20, OBJC_PR_nonatomic = 0x40, - OBJC_PR_setter = 0x80 + OBJC_PR_setter = 0x80, + OBJC_PR_atomic = 0x100 }; enum SetterKind { Assign, Retain, Copy }; @@ -1330,8 +1379,8 @@ public: private: SourceLocation AtLoc; // location of @property TypeSourceInfo *DeclType; - unsigned PropertyAttributes : 8; - unsigned PropertyAttributesAsWritten : 8; + unsigned PropertyAttributes : 9; + unsigned PropertyAttributesAsWritten : 9; // @required/@optional unsigned PropertyImplementation : 2; @@ -1429,6 +1478,10 @@ public: return PropertyIvarDecl; } + virtual SourceRange getSourceRange() const { + return SourceRange(AtLoc, getLocation()); + } + /// Lookup a property by name in the specified DeclContext. static ObjCPropertyDecl *findPropertyDecl(const DeclContext *DC, IdentifierInfo *propertyID); @@ -1450,6 +1503,15 @@ public: }; private: SourceLocation AtLoc; // location of @synthesize or @dynamic + + /// \brief For @synthesize, the location of the ivar, if it was written in + /// the source code. + /// + /// \code + /// @synthesize int a = b + /// \endcode + SourceLocation IvarLoc; + /// Property declaration being implemented ObjCPropertyDecl *PropertyDecl; @@ -1466,9 +1528,10 @@ private: ObjCPropertyImplDecl(DeclContext *DC, SourceLocation atLoc, SourceLocation L, ObjCPropertyDecl *property, Kind PK, - ObjCIvarDecl *ivarDecl) + ObjCIvarDecl *ivarDecl, + SourceLocation ivarLoc) : Decl(ObjCPropertyImpl, DC, L), AtLoc(atLoc), - PropertyDecl(property), PropertyIvarDecl(ivarDecl), + IvarLoc(ivarLoc), PropertyDecl(property), PropertyIvarDecl(ivarDecl), GetterCXXConstructor(0), SetterCXXAssignment(0) { assert (PK == Dynamic || PropertyIvarDecl); } @@ -1478,11 +1541,11 @@ public: SourceLocation atLoc, SourceLocation L, ObjCPropertyDecl *property, Kind PK, - ObjCIvarDecl *ivarDecl); + ObjCIvarDecl *ivarDecl, + SourceLocation ivarLoc); - virtual SourceRange getSourceRange() const { - return SourceRange(AtLoc, getLocation()); - } + virtual SourceRange getSourceRange() const; + SourceLocation getLocStart() const { return AtLoc; } void setAtLoc(SourceLocation Loc) { AtLoc = Loc; } @@ -1498,7 +1561,13 @@ public: ObjCIvarDecl *getPropertyIvarDecl() const { return PropertyIvarDecl; } - void setPropertyIvarDecl(ObjCIvarDecl *Ivar) { PropertyIvarDecl = Ivar; } + SourceLocation getPropertyIvarDeclLoc() const { return IvarLoc; } + + void setPropertyIvarDecl(ObjCIvarDecl *Ivar, + SourceLocation IvarLoc) { + PropertyIvarDecl = Ivar; + this->IvarLoc = IvarLoc; + } Expr *getGetterCXXConstructor() const { return GetterCXXConstructor; @@ -1517,6 +1586,8 @@ public: static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classof(const ObjCPropertyImplDecl *D) { return true; } static bool classofKind(Decl::Kind K) { return K == ObjCPropertyImpl; } + + friend class ASTDeclReader; }; } // end namespace clang diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index b532668..176c6ba 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -53,7 +53,7 @@ class TemplateParameterList { SourceLocation RAngleLoc); public: - static TemplateParameterList *Create(ASTContext &C, + static TemplateParameterList *Create(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, NamedDecl **Params, @@ -85,7 +85,7 @@ public: return begin()[Idx]; } - /// \btief Returns the minimum number of arguments needed to form a + /// \brief Returns the minimum number of arguments needed to form a /// template specialization. This may be fewer than the number of /// template parameters, if some of the parameters have default /// arguments or if there is a parameter pack. @@ -107,101 +107,57 @@ public: } }; -/// \brief A helper class for making template argument lists. -class TemplateArgumentListBuilder { - TemplateArgument *StructuredArgs; - unsigned MaxStructuredArgs; - unsigned NumStructuredArgs; - - llvm::SmallVector FlatArgs; - unsigned MaxFlatArgs; - unsigned NumFlatArgs; - - bool AddingToPack; - unsigned PackBeginIndex; - -public: - TemplateArgumentListBuilder(const TemplateParameterList *Parameters, - unsigned NumTemplateArgs) - : StructuredArgs(0), MaxStructuredArgs(Parameters->size()), - NumStructuredArgs(0), FlatArgs(0), - MaxFlatArgs(std::max(MaxStructuredArgs, NumTemplateArgs)), NumFlatArgs(0), - AddingToPack(false), PackBeginIndex(0) { } - - void Append(const TemplateArgument &Arg); - void BeginPack(); - void EndPack(); - - unsigned flatSize() const { return FlatArgs.size(); } - const TemplateArgument *getFlatArguments() const { return FlatArgs.data(); } - - unsigned structuredSize() const { - // If we don't have any structured args, just reuse the flat size. - if (!StructuredArgs) - return flatSize(); - - return NumStructuredArgs; - } - const TemplateArgument *getStructuredArguments() const { - // If we don't have any structured args, just reuse the flat args. - if (!StructuredArgs) - return getFlatArguments(); - - return StructuredArgs; - } -}; - /// \brief A template argument list. -/// -/// FIXME: In the future, this class will be extended to support -/// variadic templates and member templates, which will make some of -/// the function names below make more sense. class TemplateArgumentList { /// \brief The template argument list. /// /// The integer value will be non-zero to indicate that this /// template argument list does own the pointer. - llvm::PointerIntPair FlatArguments; + llvm::PointerIntPair Arguments; /// \brief The number of template arguments in this template /// argument list. - unsigned NumFlatArguments; - - llvm::PointerIntPair StructuredArguments; - unsigned NumStructuredArguments; + unsigned NumArguments; TemplateArgumentList(const TemplateArgumentList &Other); // DO NOT IMPL void operator=(const TemplateArgumentList &Other); // DO NOT IMPL + + TemplateArgumentList(const TemplateArgument *Args, unsigned NumArgs, + bool Owned) + : Arguments(Args, Owned), NumArguments(NumArgs) { } + public: - /// TemplateArgumentList - If this constructor is passed "true" for 'TakeArgs' - /// it copies them into a locally new[]'d array. If passed "false", then it - /// just references the array passed in. This is only safe if the builder - /// outlives it, but saves a copy. - TemplateArgumentList(ASTContext &Context, - TemplateArgumentListBuilder &Builder, - bool TakeArgs); - - /// TemplateArgumentList - It copies the template arguments into a locally - /// new[]'d array. - TemplateArgumentList(ASTContext &Context, - const TemplateArgument *Args, unsigned NumArgs); - - /// Produces a shallow copy of the given template argument list. This - /// assumes that the input argument list outlives it. This takes the list as - /// a pointer to avoid looking like a copy constructor, since this really - /// really isn't safe to use that way. - explicit TemplateArgumentList(const TemplateArgumentList *Other); - - TemplateArgumentList() : NumFlatArguments(0), NumStructuredArguments(0) { } - - /// \brief Copies the template arguments into a locally new[]'d array. - void init(ASTContext &Context, - const TemplateArgument *Args, unsigned NumArgs); + /// \brief Type used to indicate that the template argument list itself is a + /// stack object. It does not own its template arguments. + enum OnStackType { OnStack }; + + /// \brief Create a new template argument list that copies the given set of + /// template arguments. + static TemplateArgumentList *CreateCopy(ASTContext &Context, + const TemplateArgument *Args, + unsigned NumArgs); + + /// \brief Construct a new, temporary template argument list on the stack. + /// + /// The template argument list does not own the template arguments + /// provided. + explicit TemplateArgumentList(OnStackType, + const TemplateArgument *Args, unsigned NumArgs) + : Arguments(Args, false), NumArguments(NumArgs) { } + + /// \brief Produces a shallow copy of the given template argument list. + /// + /// This operation assumes that the input argument list outlives it. + /// This takes the list as a pointer to avoid looking like a copy + /// constructor, since this really really isn't safe to use that + /// way. + explicit TemplateArgumentList(const TemplateArgumentList *Other) + : Arguments(Other->data(), false), NumArguments(Other->size()) { } /// \brief Retrieve the template argument at a given index. const TemplateArgument &get(unsigned Idx) const { - assert(Idx < NumFlatArguments && "Invalid template argument index"); - return getFlatArgumentList()[Idx]; + assert(Idx < NumArguments && "Invalid template argument index"); + return data()[Idx]; } /// \brief Retrieve the template argument at a given index. @@ -209,15 +165,11 @@ public: /// \brief Retrieve the number of template arguments in this /// template argument list. - unsigned size() const { return NumFlatArguments; } - - /// \brief Retrieve the number of template arguments in the - /// flattened template argument list. - unsigned flat_size() const { return NumFlatArguments; } + unsigned size() const { return NumArguments; } - /// \brief Retrieve the flattened template argument list. - const TemplateArgument *getFlatArgumentList() const { - return FlatArguments.getPointer(); + /// \brief Retrieve a pointer to the template argument list. + const TemplateArgument *data() const { + return Arguments.getPointer(); } }; @@ -292,7 +244,31 @@ public: /// which is a FunctionDecl that has been explicitly specialization or /// instantiated from a function template. class FunctionTemplateSpecializationInfo : public llvm::FoldingSetNode { + FunctionTemplateSpecializationInfo(FunctionDecl *FD, + FunctionTemplateDecl *Template, + TemplateSpecializationKind TSK, + const TemplateArgumentList *TemplateArgs, + const TemplateArgumentListInfo *TemplateArgsAsWritten, + SourceLocation POI) + : Function(FD), + Template(Template, TSK - 1), + TemplateArguments(TemplateArgs), + TemplateArgumentsAsWritten(TemplateArgsAsWritten), + PointOfInstantiation(POI) { } + public: + static FunctionTemplateSpecializationInfo * + Create(ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template, + TemplateSpecializationKind TSK, + const TemplateArgumentList *TemplateArgs, + const TemplateArgumentListInfo *TemplateArgsAsWritten, + SourceLocation POI) { + return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK, + TemplateArgs, + TemplateArgsAsWritten, + POI); + } + /// \brief The function template specialization that this structure /// describes. FunctionDecl *Function; @@ -345,8 +321,8 @@ public: } void Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, TemplateArguments->getFlatArgumentList(), - TemplateArguments->flat_size(), + Profile(ID, TemplateArguments->data(), + TemplateArguments->size(), Function->getASTContext()); } @@ -441,11 +417,6 @@ class DependentFunctionTemplateSpecializationInfo { return reinterpret_cast(this+1); } - const TemplateArgumentLoc *getTemplateArgs() const { - return reinterpret_cast( - &getTemplates()[getNumTemplates()]); - } - public: DependentFunctionTemplateSpecializationInfo( const UnresolvedSetImpl &Templates, @@ -463,6 +434,12 @@ public: return getTemplates()[I]; } + /// \brief Returns the explicit template arguments that were given. + const TemplateArgumentLoc *getTemplateArgs() const { + return reinterpret_cast( + &getTemplates()[getNumTemplates()]); + } + /// \brief Returns the number of explicit template arguments that were given. unsigned getNumTemplateArgs() const { return d.NumArgs; @@ -584,7 +561,7 @@ protected: /// for the common pointer. CommonBase *getCommonPtr(); - virtual CommonBase *newCommon() = 0; + virtual CommonBase *newCommon(ASTContext &C) = 0; // Construct a template decl with name, parameters, and templated element. RedeclarableTemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, @@ -789,19 +766,13 @@ protected: TemplateParameterList *Params, NamedDecl *Decl) : RedeclarableTemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl) { } - CommonBase *newCommon(); + CommonBase *newCommon(ASTContext &C); Common *getCommonPtr() { return static_cast(RedeclarableTemplateDecl::getCommonPtr()); } - friend void FunctionDecl::setFunctionTemplateSpecialization( - FunctionTemplateDecl *Template, - const TemplateArgumentList *TemplateArgs, - void *InsertPos, - TemplateSpecializationKind TSK, - const TemplateArgumentListInfo *TemplateArgsAsWritten, - SourceLocation PointOfInstantiation); + friend class FunctionDecl; /// \brief Retrieve the set of function template specializations of this /// function template. @@ -940,15 +911,15 @@ class TemplateTypeParmDecl : public TypeDecl { bool Typename, QualType Type, bool ParameterPack) : TypeDecl(TemplateTypeParm, DC, L, Id), Typename(Typename), InheritedDefault(false), ParameterPack(ParameterPack), DefaultArgument() { - TypeForDecl = Type.getTypePtr(); + TypeForDecl = Type.getTypePtrOrNull(); } public: - static TemplateTypeParmDecl *Create(ASTContext &C, DeclContext *DC, + static TemplateTypeParmDecl *Create(const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D, unsigned P, IdentifierInfo *Id, bool Typename, bool ParameterPack); - static TemplateTypeParmDecl *Create(ASTContext &C, EmptyShell Empty); + static TemplateTypeParmDecl *Create(const ASTContext &C, EmptyShell Empty); /// \brief Whether this template type parameter was declared with /// the 'typename' keyword. If not, it was declared with the 'class' @@ -1014,22 +985,54 @@ public: /// template class array { }; /// @endcode class NonTypeTemplateParmDecl - : public VarDecl, protected TemplateParmPosition { + : public DeclaratorDecl, protected TemplateParmPosition { /// \brief The default template argument, if any, and whether or not /// it was inherited. llvm::PointerIntPair DefaultArgumentAndInherited; + // FIXME: Collapse this into TemplateParamPosition; or, just move depth/index + // down here to save memory. + + /// \brief Whether this non-type template parameter is a parameter pack. + bool ParameterPack; + + /// \brief Whether this non-type template parameter is an "expanded" + /// parameter pack, meaning that its type is a pack expansion and we + /// already know the set of types that expansion expands to. + bool ExpandedParameterPack; + + /// \brief The number of types in an expanded parameter pack. + unsigned NumExpandedTypes; + NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D, unsigned P, IdentifierInfo *Id, QualType T, - TypeSourceInfo *TInfo) - : VarDecl(NonTypeTemplateParm, DC, L, Id, T, TInfo, SC_None, SC_None), - TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false) + bool ParameterPack, TypeSourceInfo *TInfo) + : DeclaratorDecl(NonTypeTemplateParm, DC, L, Id, T, TInfo), + TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false), + ParameterPack(ParameterPack), ExpandedParameterPack(false), + NumExpandedTypes(0) { } + NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D, + unsigned P, IdentifierInfo *Id, QualType T, + TypeSourceInfo *TInfo, + const QualType *ExpandedTypes, + unsigned NumExpandedTypes, + TypeSourceInfo **ExpandedTInfos); + + friend class ASTDeclReader; + public: static NonTypeTemplateParmDecl * - Create(ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D, - unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo); + Create(const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D, + unsigned P, IdentifierInfo *Id, QualType T, bool ParameterPack, + TypeSourceInfo *TInfo); + + static NonTypeTemplateParmDecl * + Create(const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D, + unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, + const QualType *ExpandedTypes, unsigned NumExpandedTypes, + TypeSourceInfo **ExpandedTInfos); using TemplateParmPosition::getDepth; using TemplateParmPosition::setDepth; @@ -1037,6 +1040,9 @@ public: using TemplateParmPosition::setPosition; using TemplateParmPosition::getIndex; + SourceLocation getInnerLocStart() const; + SourceRange getSourceRange() const; + /// \brief Determine whether this template parameter has a default /// argument. bool hasDefaultArgument() const { @@ -1071,6 +1077,65 @@ public: DefaultArgumentAndInherited.setInt(false); } + /// \brief Whether this parameter is a non-type template parameter pack. + /// + /// If the parameter is a parameter pack, the type may be a + /// \c PackExpansionType. In the following example, the \c Dims parameter + /// is a parameter pack (whose type is 'unsigned'). + /// + /// \code + /// template struct multi_array; + /// \endcode + bool isParameterPack() const { return ParameterPack; } + + /// \brief Whether this parameter is a non-type template parameter pack + /// that has different types at different positions. + /// + /// A parameter pack is an expanded parameter pack when the original + /// parameter pack's type was itself a pack expansion, and that expansion + /// has already been expanded. For example, given: + /// + /// \code + /// template + /// struct X { + /// template + /// struct Y { /* ... */ }; + /// }; + /// \endcode + /// + /// The parameter pack \c Values has a \c PackExpansionType as its type, + /// which expands \c Types. When \c Types is supplied with template arguments + /// by instantiating \c X, the instantiation of \c Values becomes an + /// expanded parameter pack. For example, instantiating + /// \c X results in \c Values being an expanded parameter + /// pack with expansion types \c int and \c unsigned int. + /// + /// The \c getExpansionType() and \c getExpansionTypeSourceInfo() functions + /// return the expansion types. + bool isExpandedParameterPack() const { return ExpandedParameterPack; } + + /// \brief Retrieves the number of expansion types in an expanded parameter pack. + unsigned getNumExpansionTypes() const { + assert(ExpandedParameterPack && "Not an expansion parameter pack"); + return NumExpandedTypes; + } + + /// \brief Retrieve a particular expansion type within an expanded parameter + /// pack. + QualType getExpansionType(unsigned I) const { + assert(I < NumExpandedTypes && "Out-of-range expansion type index"); + void * const *TypesAndInfos = reinterpret_cast(this + 1); + return QualType::getFromOpaquePtr(TypesAndInfos[2*I]); + } + + /// \brief Retrieve a particular expansion type source info within an + /// expanded parameter pack. + TypeSourceInfo *getExpansionTypeSourceInfo(unsigned I) const { + assert(I < NumExpandedTypes && "Out-of-range expansion type index"); + void * const *TypesAndInfos = reinterpret_cast(this + 1); + return static_cast(TypesAndInfos[2*I+1]); + } + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classof(const NonTypeTemplateParmDecl *D) { return true; } @@ -1092,24 +1157,36 @@ class TemplateTemplateParmDecl /// Whether or not the default argument was inherited. bool DefaultArgumentWasInherited; + /// \brief Whether this parameter is a parameter pack. + bool ParameterPack; + TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, - unsigned D, unsigned P, + unsigned D, unsigned P, bool ParameterPack, IdentifierInfo *Id, TemplateParameterList *Params) : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params), TemplateParmPosition(D, P), DefaultArgument(), - DefaultArgumentWasInherited(false) + DefaultArgumentWasInherited(false), ParameterPack(ParameterPack) { } public: - static TemplateTemplateParmDecl *Create(ASTContext &C, DeclContext *DC, + static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D, - unsigned P, IdentifierInfo *Id, + unsigned P, bool ParameterPack, + IdentifierInfo *Id, TemplateParameterList *Params); using TemplateParmPosition::getDepth; using TemplateParmPosition::getPosition; using TemplateParmPosition::getIndex; + /// \brief Whether this template template parameter is a template + /// parameter pack. + /// + /// \code + /// template