diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2011-04-14 22:09:26 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2011-04-14 22:09:26 +0000 |
commit | 02e85f3bc5fcb784c44851b2d557cdeb63a7ca0b (patch) | |
tree | a1507fda2ae01672b66da3bafc407e9da2690398 /clang/lib/AST | |
parent | 55858499e21e0541423cfdb2be7eb18e52a40a2c (diff) | |
download | bcm5719-llvm-02e85f3bc5fcb784c44851b2d557cdeb63a7ca0b.tar.gz bcm5719-llvm-02e85f3bc5fcb784c44851b2d557cdeb63a7ca0b.zip |
Add support for C++0x's range-based for loops, as specified by the C++11 draft standard (N3291).
llvm-svn: 129541
Diffstat (limited to 'clang/lib/AST')
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 16 | ||||
-rw-r--r-- | clang/lib/AST/DeclPrinter.cpp | 3 | ||||
-rw-r--r-- | clang/lib/AST/ExprCXX.cpp | 2 | ||||
-rw-r--r-- | clang/lib/AST/Stmt.cpp | 34 | ||||
-rw-r--r-- | clang/lib/AST/StmtPrinter.cpp | 12 | ||||
-rw-r--r-- | clang/lib/AST/StmtProfile.cpp | 4 |
6 files changed, 69 insertions, 2 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 7317928d971..eea5394cfa5 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -2754,6 +2754,22 @@ QualType ASTContext::getAutoType(QualType DeducedType) const { return QualType(AT, 0); } +/// getAutoDeductType - Get type pattern for deducing against 'auto'. +QualType ASTContext::getAutoDeductType() const { + if (AutoDeductTy.isNull()) + AutoDeductTy = getAutoType(QualType()); + assert(!AutoDeductTy.isNull() && "can't build 'auto' pattern"); + return AutoDeductTy; +} + +/// getAutoRRefDeductType - Get type pattern for deducing against 'auto &&'. +QualType ASTContext::getAutoRRefDeductType() const { + if (AutoRRefDeductTy.isNull()) + AutoRRefDeductTy = getRValueReferenceType(getAutoDeductType()); + assert(!AutoRRefDeductTy.isNull() && "can't build 'auto &&' pattern"); + return AutoRRefDeductTy; +} + /// getTagDeclType - Return the unique reference to the type for the /// specified TagDecl (struct/union/class/enum) decl. QualType ASTContext::getTagDeclType(const TagDecl *Decl) const { diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp index 446b4d46464..37cd2af1b18 100644 --- a/clang/lib/AST/DeclPrinter.cpp +++ b/clang/lib/AST/DeclPrinter.cpp @@ -567,7 +567,8 @@ void DeclPrinter::VisitVarDecl(VarDecl *D) { T = Parm->getOriginalType(); T.getAsStringInternal(Name, Policy); Out << Name; - if (Expr *Init = D->getInit()) { + Expr *Init = D->getInit(); + if (!Policy.SuppressInitializers && Init) { if (D->hasCXXDirectInitializer()) Out << "("; else { diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp index 692c2c37607..127431ba7d6 100644 --- a/clang/lib/AST/ExprCXX.cpp +++ b/clang/lib/AST/ExprCXX.cpp @@ -189,7 +189,7 @@ UnresolvedLookupExpr::Create(ASTContext &C, ExplicitTemplateArgumentList::sizeFor(Args)); return new (Mem) UnresolvedLookupExpr(C, NamingClass, QualifierLoc, NameInfo, ADL, /*Overload*/ true, &Args, - Begin, End); + Begin, End, /*StdIsAssociated=*/false); } UnresolvedLookupExpr * diff --git a/clang/lib/AST/Stmt.cpp b/clang/lib/AST/Stmt.cpp index 6c353192785..5b0db8621a3 100644 --- a/clang/lib/AST/Stmt.cpp +++ b/clang/lib/AST/Stmt.cpp @@ -540,6 +540,40 @@ CXXTryStmt::CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock, std::copy(handlers, handlers + NumHandlers, Stmts + 1); } +CXXForRangeStmt::CXXForRangeStmt(DeclStmt *Range, DeclStmt *BeginEndStmt, + Expr *Cond, Expr *Inc, DeclStmt *LoopVar, + Stmt *Body, SourceLocation FL, + SourceLocation CL, SourceLocation RPL) + : Stmt(CXXForRangeStmtClass), ForLoc(FL), ColonLoc(CL), RParenLoc(RPL) { + SubExprs[RANGE] = Range; + SubExprs[BEGINEND] = BeginEndStmt; + SubExprs[COND] = reinterpret_cast<Stmt*>(Cond); + SubExprs[INC] = reinterpret_cast<Stmt*>(Inc); + SubExprs[LOOPVAR] = LoopVar; + SubExprs[BODY] = Body; +} + +Expr *CXXForRangeStmt::getRangeInit() { + DeclStmt *RangeStmt = getRangeStmt(); + VarDecl *RangeDecl = dyn_cast_or_null<VarDecl>(RangeStmt->getSingleDecl()); + assert(RangeDecl &&& "for-range should have a single var decl"); + return RangeDecl->getInit(); +} + +const Expr *CXXForRangeStmt::getRangeInit() const { + return const_cast<CXXForRangeStmt*>(this)->getRangeInit(); +} + +VarDecl *CXXForRangeStmt::getLoopVariable() { + Decl *LV = cast<DeclStmt>(getLoopVarStmt())->getSingleDecl(); + assert(LV && "No loop variable in CXXForRangeStmt"); + return cast<VarDecl>(LV); +} + +const VarDecl *CXXForRangeStmt::getLoopVariable() const { + return const_cast<CXXForRangeStmt*>(this)->getLoopVariable(); +} + IfStmt::IfStmt(ASTContext &C, SourceLocation IL, VarDecl *var, Expr *cond, Stmt *then, SourceLocation EL, Stmt *elsev) : Stmt(IfStmtClass), IfLoc(IL), ElseLoc(EL) diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index 4f500441166..37010a0358d 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -291,6 +291,18 @@ void StmtPrinter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *Node) { } } +void StmtPrinter::VisitCXXForRangeStmt(CXXForRangeStmt *Node) { + Indent() << "for ("; + PrintingPolicy SubPolicy(Policy); + SubPolicy.SuppressInitializers = true; + Node->getLoopVariable()->print(OS, SubPolicy, IndentLevel); + OS << " : "; + PrintExpr(Node->getRangeInit()); + OS << ") {\n"; + PrintStmt(Node->getBody()); + Indent() << "}\n"; +} + void StmtPrinter::VisitGotoStmt(GotoStmt *Node) { Indent() << "goto " << Node->getLabel()->getName() << ";\n"; } diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index a506d055b30..92292cea719 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -177,6 +177,10 @@ void StmtProfiler::VisitCXXTryStmt(CXXTryStmt *S) { VisitStmt(S); } +void StmtProfiler::VisitCXXForRangeStmt(CXXForRangeStmt *S) { + VisitStmt(S); +} + void StmtProfiler::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) { VisitStmt(S); } |