diff options
Diffstat (limited to 'clang/include')
-rw-r--r-- | clang/include/clang/AST/ASTContext.h | 10 | ||||
-rw-r--r-- | clang/include/clang/AST/Decl.h | 11 | ||||
-rw-r--r-- | clang/include/clang/AST/ExprCXX.h | 26 | ||||
-rw-r--r-- | clang/include/clang/AST/PrettyPrinter.h | 14 | ||||
-rw-r--r-- | clang/include/clang/AST/RecursiveASTVisitor.h | 1 | ||||
-rw-r--r-- | clang/include/clang/AST/StmtCXX.h | 82 | ||||
-rw-r--r-- | clang/include/clang/Analysis/Visitors/CFGStmtVisitor.h | 5 | ||||
-rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 22 | ||||
-rw-r--r-- | clang/include/clang/Basic/StmtNodes.td | 1 | ||||
-rw-r--r-- | clang/include/clang/Parse/Parser.h | 18 | ||||
-rw-r--r-- | clang/include/clang/Sema/Sema.h | 18 | ||||
-rw-r--r-- | clang/include/clang/Serialization/ASTBitCodes.h | 8 |
12 files changed, 205 insertions, 11 deletions
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index c330f4cda23..7a62af7eea7 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -423,6 +423,10 @@ public: CanQualType OverloadTy, DependentTy, UnknownAnyTy; CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy; + // Types for deductions in C++0x [stmt.ranged]'s desugaring. Built on demand. + mutable QualType AutoDeductTy; // Deduction against 'auto'. + mutable QualType AutoRRefDeductTy; // Deduction against 'auto &&'. + ASTContext(const LangOptions& LOpts, SourceManager &SM, const TargetInfo &t, IdentifierTable &idents, SelectorTable &sels, Builtin::Context &builtins, @@ -745,6 +749,12 @@ public: /// getAutoType - C++0x deduced auto type. QualType getAutoType(QualType DeducedType) const; + /// getAutoDeductType - C++0x deduction pattern for 'auto' type. + QualType getAutoDeductType() const; + + /// getAutoRRefDeductType - C++0x deduction pattern for 'auto &&' type. + QualType getAutoRRefDeductType() const; + /// getTagDeclType - Return the unique reference to the type for the /// specified TagDecl (struct/union/class/enum) decl. QualType getTagDeclType(const TagDecl *Decl) const; diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 4dd3db7fad9..48b7d9f1bf8 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -696,6 +696,10 @@ private: /// slot of its function, enabling the named return value optimization (NRVO). bool NRVOVariable : 1; + /// \brief Whether this variable is the for-range-declaration in a C++0x + /// for-range statement. + bool CXXForRangeDecl : 1; + friend class StmtIteratorBase; friend class ASTDeclReader; @@ -706,7 +710,7 @@ protected: StorageClass SCAsWritten) : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc), Init(), ThreadSpecified(false), HasCXXDirectInit(false), - ExceptionVar(false), NRVOVariable(false) { + ExceptionVar(false), NRVOVariable(false), CXXForRangeDecl(false) { SClass = SC; SClassAsWritten = SCAsWritten; } @@ -1051,6 +1055,11 @@ public: /// NRVO candidate. bool isNRVOVariable() const { return NRVOVariable; } void setNRVOVariable(bool NRVO) { NRVOVariable = NRVO; } + + /// \brief Determine whether this variable is the for-range-declaration in + /// a C++0x for-range statement. + bool isCXXForRangeDecl() const { return CXXForRangeDecl; } + void setCXXForRangeDecl(bool FRD) { CXXForRangeDecl = FRD; } /// \brief If this variable is an instantiated static data member of a /// class template specialization, returns the templated static data member diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index 9bb1a50be90..ed4661b3a4f 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -1738,6 +1738,10 @@ class UnresolvedLookupExpr : public OverloadExpr { /// call. bool RequiresADL; + /// True if namespace ::std should be considered an associated namespace + /// for the purposes of argument-dependent lookup. See C++0x [stmt.ranged]p1. + bool StdIsAssociatedNamespace; + /// True if these lookup results are overloaded. This is pretty /// trivially rederivable if we urgently need to kill this field. bool Overloaded; @@ -1755,15 +1759,19 @@ class UnresolvedLookupExpr : public OverloadExpr { const DeclarationNameInfo &NameInfo, bool RequiresADL, bool Overloaded, const TemplateArgumentListInfo *TemplateArgs, - UnresolvedSetIterator Begin, UnresolvedSetIterator End) + UnresolvedSetIterator Begin, UnresolvedSetIterator End, + bool StdIsAssociatedNamespace) : OverloadExpr(UnresolvedLookupExprClass, C, QualifierLoc, NameInfo, TemplateArgs, Begin, End), - RequiresADL(RequiresADL), Overloaded(Overloaded), NamingClass(NamingClass) + RequiresADL(RequiresADL), + StdIsAssociatedNamespace(StdIsAssociatedNamespace), + Overloaded(Overloaded), NamingClass(NamingClass) {} UnresolvedLookupExpr(EmptyShell Empty) : OverloadExpr(UnresolvedLookupExprClass, Empty), - RequiresADL(false), Overloaded(false), NamingClass(0) + RequiresADL(false), StdIsAssociatedNamespace(false), Overloaded(false), + NamingClass(0) {} friend class ASTStmtReader; @@ -1775,9 +1783,13 @@ public: const DeclarationNameInfo &NameInfo, bool ADL, bool Overloaded, UnresolvedSetIterator Begin, - UnresolvedSetIterator End) { + UnresolvedSetIterator End, + bool StdIsAssociatedNamespace = false) { + assert((ADL || !StdIsAssociatedNamespace) && + "std considered associated namespace when not performing ADL"); return new(C) UnresolvedLookupExpr(C, NamingClass, QualifierLoc, NameInfo, - ADL, Overloaded, 0, Begin, End); + ADL, Overloaded, 0, Begin, End, + StdIsAssociatedNamespace); } static UnresolvedLookupExpr *Create(ASTContext &C, @@ -1797,6 +1809,10 @@ public: /// argument-dependent lookup. bool requiresADL() const { return RequiresADL; } + /// True if namespace ::std should be artificially added to the set of + /// associated namespaecs for argument-dependent lookup purposes. + bool isStdAssociatedNamespace() const { return StdIsAssociatedNamespace; } + /// True if this lookup is overloaded. bool isOverloaded() const { return Overloaded; } diff --git a/clang/include/clang/AST/PrettyPrinter.h b/clang/include/clang/AST/PrettyPrinter.h index 5d52cde4b11..cf5fadbd185 100644 --- a/clang/include/clang/AST/PrettyPrinter.h +++ b/clang/include/clang/AST/PrettyPrinter.h @@ -39,6 +39,7 @@ struct PrintingPolicy { PrintingPolicy(const LangOptions &LO) : Indentation(2), LangOpts(LO), SuppressSpecifiers(false), SuppressTagKeyword(false), SuppressTag(false), SuppressScope(false), + SuppressInitializers(false), Dump(false), ConstantArraySizeAsWritten(false), AnonymousTagLocations(true) { } @@ -87,6 +88,19 @@ struct PrintingPolicy { /// \brief Suppresses printing of scope specifiers. bool SuppressScope : 1; + /// \brief Suppress printing of variable initializers. + /// + /// This flag is used when printing the loop variable in a for-range + /// statement. For example, given: + /// + /// \code + /// for (auto x : coll) + /// \endcode + /// + /// SuppressInitializers will be true when printing "auto x", so that the + /// internal initializer constructed for x will not be printed. + bool SuppressInitializers : 1; + /// \brief True when we are "dumping" rather than "pretty-printing", /// where dumping involves printing the internal details of the AST /// and pretty-printing involves printing something similar to diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index ccc327b5b67..2a4348feac3 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -1696,6 +1696,7 @@ DEF_TRAVERSE_STMT(ObjCAtSynchronizedStmt, { }) DEF_TRAVERSE_STMT(ObjCAtThrowStmt, { }) DEF_TRAVERSE_STMT(ObjCAtTryStmt, { }) DEF_TRAVERSE_STMT(ObjCForCollectionStmt, { }) +DEF_TRAVERSE_STMT(CXXForRangeStmt, { }) DEF_TRAVERSE_STMT(ReturnStmt, { }) DEF_TRAVERSE_STMT(SwitchStmt, { }) DEF_TRAVERSE_STMT(WhileStmt, { }) diff --git a/clang/include/clang/AST/StmtCXX.h b/clang/include/clang/AST/StmtCXX.h index f08815fd562..42dcf2bb7b7 100644 --- a/clang/include/clang/AST/StmtCXX.h +++ b/clang/include/clang/AST/StmtCXX.h @@ -119,6 +119,88 @@ public: friend class ASTStmtReader; }; +/// CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for +/// statement, represented as 'for (range-declarator : range-expression)'. +/// +/// This is stored in a partially-desugared form to allow full semantic +/// analysis of the constituent components. The original syntactic components +/// can be extracted using getLoopVariable and getRangeInit. +class CXXForRangeStmt : public Stmt { + enum { RANGE, BEGINEND, COND, INC, LOOPVAR, BODY, END }; + // SubExprs[RANGE] is an expression or declstmt. + // SubExprs[COND] and SubExprs[INC] are expressions. + Stmt *SubExprs[END]; + SourceLocation ForLoc; + SourceLocation ColonLoc; + SourceLocation RParenLoc; +public: + CXXForRangeStmt(DeclStmt *Range, DeclStmt *BeginEnd, + Expr *Cond, Expr *Inc, DeclStmt *LoopVar, Stmt *Body, + SourceLocation FL, SourceLocation CL, SourceLocation RPL); + CXXForRangeStmt(EmptyShell Empty) : Stmt(CXXForRangeStmtClass, Empty) { } + + + VarDecl *getLoopVariable(); + Expr *getRangeInit(); + + const VarDecl *getLoopVariable() const; + const Expr *getRangeInit() const; + + + DeclStmt *getRangeStmt() { return cast<DeclStmt>(SubExprs[RANGE]); } + DeclStmt *getBeginEndStmt() { return cast_or_null<DeclStmt>(SubExprs[BEGINEND]); } + Expr *getCond() { return cast_or_null<Expr>(SubExprs[COND]); } + Expr *getInc() { return cast_or_null<Expr>(SubExprs[INC]); } + DeclStmt *getLoopVarStmt() { return cast<DeclStmt>(SubExprs[LOOPVAR]); } + Stmt *getBody() { return SubExprs[BODY]; } + + const DeclStmt *getRangeStmt() const { + return cast<DeclStmt>(SubExprs[RANGE]); + } + const DeclStmt *getBeginEndStmt() const { + return cast_or_null<DeclStmt>(SubExprs[BEGINEND]); + } + const Expr *getCond() const { + return cast_or_null<Expr>(SubExprs[COND]); + } + const Expr *getInc() const { + return cast_or_null<Expr>(SubExprs[INC]); + } + const DeclStmt *getLoopVarStmt() const { + return cast<DeclStmt>(SubExprs[LOOPVAR]); + } + const Stmt *getBody() const { return SubExprs[BODY]; } + + void setRangeInit(Expr *E) { SubExprs[RANGE] = reinterpret_cast<Stmt*>(E); } + void setRangeStmt(Stmt *S) { SubExprs[RANGE] = S; } + void setBeginEndStmt(Stmt *S) { SubExprs[BEGINEND] = S; } + void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); } + void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast<Stmt*>(E); } + void setLoopVarStmt(Stmt *S) { SubExprs[LOOPVAR] = S; } + void setBody(Stmt *S) { SubExprs[BODY] = S; } + + + SourceLocation getForLoc() const { return ForLoc; } + void setForLoc(SourceLocation Loc) { ForLoc = Loc; } + SourceLocation getColonLoc() const { return ColonLoc; } + void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; } + SourceLocation getRParenLoc() const { return RParenLoc; } + void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; } + + SourceRange getSourceRange() const { + return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd()); + } + static bool classof(const Stmt *T) { + return T->getStmtClass() == CXXForRangeStmtClass; + } + static bool classof(const CXXForRangeStmt *) { return true; } + + // Iterators + child_range children() { + return child_range(&SubExprs[0], &SubExprs[END]); + } +}; + } // end namespace clang diff --git a/clang/include/clang/Analysis/Visitors/CFGStmtVisitor.h b/clang/include/clang/Analysis/Visitors/CFGStmtVisitor.h index d197e69babd..7fb4ab3ebad 100644 --- a/clang/include/clang/Analysis/Visitors/CFGStmtVisitor.h +++ b/clang/include/clang/Analysis/Visitors/CFGStmtVisitor.h @@ -82,6 +82,7 @@ public: DISPATCH_CASE(ConditionalOperator) DISPATCH_CASE(BinaryConditionalOperator) DISPATCH_CASE(ObjCForCollectionStmt) + DISPATCH_CASE(CXXForRangeStmt) case Stmt::BinaryOperatorClass: { BinaryOperator* B = cast<BinaryOperator>(S); @@ -109,6 +110,10 @@ public: return static_cast<ImplClass*>(this)->BlockStmt_VisitStmt(S); } + RetTy BlockStmt_VisitCXXForRangeStmt(CXXForRangeStmt* S) { + return static_cast<ImplClass*>(this)->BlockStmt_VisitStmt(S); + } + RetTy BlockStmt_VisitImplicitControlFlowExpr(Expr* E) { return static_cast<ImplClass*>(this)->BlockStmt_VisitExpr(E); } diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 90945d7bd40..b96c461c6c2 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -995,6 +995,28 @@ def err_delegation_unimplemented : Error< "delegating constructors are not fully implemented">; def err_delegating_initializer_alone : Error< "an initializer for a delegating constructor must appear alone">; + +// C++0x range-based for loop +def err_for_range_decl_must_be_var : Error< + "for range declaration must declare a variable">; +def err_for_range_storage_class : Error< + "loop variable %0 may not be declared %select{'extern'|'static'|" + "'__private_extern__'|'auto'|'register'|'constexpr'}1">; +def err_type_defined_in_for_range : Error< + "types may not be defined in a for range declaration">; +def err_for_range_deduction_failure : Error< + "cannot use type %0 as a range">; +def err_for_range_incomplete_type : Error< + "cannot use incomplete type %0 as a range">; +def err_for_range_iter_deduction_failure : Error< + "cannot use type %0 as an iterator">; +def err_for_range_member_begin_end_mismatch : Error< + "range type %0 has '%select{begin|end}1' member but no '%select{end|begin}1' member">; +def err_for_range_begin_end_types_differ : Error< + "'begin' and 'end' must return the same type (got %0 and %1)">; +def note_for_range_type : Note<"range has type %0">; +def note_for_range_begin_end : Note< + "selected '%select{begin|end}0' %select{function|template }1%2 with iterator type %3">; // Objective-C++ def err_objc_decls_may_only_appear_in_global_scope : Error< diff --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td index 44f6f539398..a25af44790c 100644 --- a/clang/include/clang/Basic/StmtNodes.td +++ b/clang/include/clang/Basic/StmtNodes.td @@ -41,6 +41,7 @@ def ObjCForCollectionStmt : Stmt; // C++ statments def CXXCatchStmt : Stmt; def CXXTryStmt : Stmt; +def CXXForRangeStmt : Stmt; // Expressions def Expr : Stmt<1>; diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 4c422cc4b64..f10003fcd2b 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -1288,6 +1288,15 @@ private: DSC_top_level // top-level/namespace declaration context }; + /// Information on a C++0x for-range-initializer found while parsing a + /// declaration which turns out to be a for-range-declaration. + struct ForRangeInit { + SourceLocation ColonLoc; + ExprResult RangeExpr; + + bool ParsedForRangeDecl() { return !ColonLoc.isInvalid(); } + }; + DeclGroupPtrTy ParseDeclaration(StmtVector &Stmts, unsigned Context, SourceLocation &DeclEnd, ParsedAttributesWithRange &attrs); @@ -1295,12 +1304,17 @@ private: unsigned Context, SourceLocation &DeclEnd, ParsedAttributes &attrs, - bool RequireSemi); + bool RequireSemi, + ForRangeInit *FRI = 0); DeclGroupPtrTy ParseDeclGroup(ParsingDeclSpec &DS, unsigned Context, bool AllowFunctionDefinitions, - SourceLocation *DeclEnd = 0); + SourceLocation *DeclEnd = 0, + ForRangeInit *FRI = 0); Decl *ParseDeclarationAfterDeclarator(Declarator &D, const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo()); + bool ParseAttributesAfterDeclarator(Declarator &D); + Decl *ParseDeclarationAfterDeclaratorAndAttributes(Declarator &D, + const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo()); Decl *ParseFunctionStatementBody(Decl *Decl, ParseScope &BodyScope); Decl *ParseFunctionTryBlock(Decl *Decl, ParseScope &BodyScope); diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 1169b50f852..f03bfe49b41 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -864,6 +864,7 @@ public: bool TypeMayContainAuto); void ActOnUninitializedDecl(Decl *dcl, bool TypeMayContainAuto); void ActOnInitializerError(Decl *Dcl); + void ActOnCXXForRangeDecl(Decl *D); void SetDeclDeleted(Decl *dcl, SourceLocation DelLoc); void FinalizeDeclaration(Decl *D); DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS, @@ -1268,7 +1269,8 @@ public: Expr **Args, unsigned NumArgs, TemplateArgumentListInfo *ExplicitTemplateArgs, OverloadCandidateSet& CandidateSet, - bool PartialOverloading = false); + bool PartialOverloading = false, + bool StdNamespaceIsAssociated = false); // Emit as a 'note' the specific overload candidate void NoteOverloadCandidate(FunctionDecl *Fn); @@ -1473,7 +1475,8 @@ public: void ArgumentDependentLookup(DeclarationName Name, bool Operator, Expr **Args, unsigned NumArgs, - ADLResult &Functions); + ADLResult &Functions, + bool StdNamespaceIsAssociated = false); void LookupVisibleDecls(Scope *S, LookupNameKind Kind, VisibleDeclConsumer &Consumer, @@ -1804,6 +1807,17 @@ public: SourceLocation LParenLoc, Stmt *First, Expr *Second, SourceLocation RParenLoc, Stmt *Body); + StmtResult ActOnCXXForRangeStmt(SourceLocation ForLoc, + SourceLocation LParenLoc, Stmt *LoopVar, + SourceLocation ColonLoc, Expr *Collection, + SourceLocation RParenLoc); + StmtResult BuildCXXForRangeStmt(SourceLocation ForLoc, + SourceLocation ColonLoc, + Stmt *RangeDecl, Stmt *BeginEndDecl, + Expr *Cond, Expr *Inc, + Stmt *LoopVarDecl, + SourceLocation RParenLoc); + StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body); StmtResult ActOnGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc, diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index 17cb9efcea1..35d6fe7f3b1 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -624,7 +624,11 @@ namespace clang { /// \brief NSConstantString type SPECIAL_TYPE_NS_CONSTANT_STRING = 15, /// \brief Whether __[u]int128_t identifier is installed. - SPECIAL_TYPE_INT128_INSTALLED = 16 + SPECIAL_TYPE_INT128_INSTALLED = 16, + /// \brief Cached "auto" deduction type. + SPECIAL_TYPE_AUTO_DEDUCT = 17, + /// \brief Cached "auto &&" deduction type. + SPECIAL_TYPE_AUTO_RREF_DEDUCT = 18 }; /// \brief Record codes for each kind of declaration. @@ -915,6 +919,8 @@ namespace clang { STMT_CXX_CATCH, /// \brief A CXXTryStmt record. STMT_CXX_TRY, + /// \brief A CXXForRangeStmt record. + STMT_CXX_FOR_RANGE, /// \brief A CXXOperatorCallExpr record. EXPR_CXX_OPERATOR_CALL, |