diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/StmtPrinter.cpp | 16 | ||||
-rw-r--r-- | lib/AST/StmtProfile.cpp | 7 | ||||
-rw-r--r-- | lib/CodeGen/CGStmt.cpp | 1 | ||||
-rw-r--r-- | lib/Parse/ParseStmt.cpp | 11 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 22 | ||||
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 23 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 81 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderStmt.cpp | 16 | ||||
-rw-r--r-- | lib/Serialization/ASTWriterStmt.cpp | 10 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/ExprEngine.cpp | 1 |
10 files changed, 179 insertions, 9 deletions
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp index daaa354ac3..5b1654c924 100644 --- a/lib/AST/StmtPrinter.cpp +++ b/lib/AST/StmtPrinter.cpp @@ -305,6 +305,22 @@ void StmtPrinter::VisitCXXForRangeStmt(CXXForRangeStmt *Node) { Indent() << "}\n"; } +void StmtPrinter::VisitMSDependentExistsStmt(MSDependentExistsStmt *Node) { + Indent(); + if (Node->isIfExists()) + OS << "__if_exists ("; + else + OS << "__if_not_exists ("; + + if (NestedNameSpecifier *Qualifier + = Node->getQualifierLoc().getNestedNameSpecifier()) + Qualifier->print(OS, Policy); + + OS << Node->getNameInfo() << ") "; + + PrintRawCompoundStmt(Node->getSubStmt()); +} + void StmtPrinter::VisitGotoStmt(GotoStmt *Node) { Indent() << "goto " << Node->getLabel()->getName() << ";\n"; } diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp index 214378a974..93b2f65818 100644 --- a/lib/AST/StmtProfile.cpp +++ b/lib/AST/StmtProfile.cpp @@ -182,6 +182,13 @@ void StmtProfiler::VisitCXXForRangeStmt(const CXXForRangeStmt *S) { VisitStmt(S); } +void StmtProfiler::VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) { + VisitStmt(S); + ID.AddBoolean(S->isIfExists()); + VisitNestedNameSpecifier(S->getQualifierLoc().getNestedNameSpecifier()); + VisitName(S->getNameInfo().getName()); +} + void StmtProfiler::VisitSEHTryStmt(const SEHTryStmt *S) { VisitStmt(S); } diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp index c56931bbc6..6f020ccab0 100644 --- a/lib/CodeGen/CGStmt.cpp +++ b/lib/CodeGen/CGStmt.cpp @@ -73,6 +73,7 @@ void CodeGenFunction::EmitStmt(const Stmt *S) { case Stmt::CXXCatchStmtClass: case Stmt::SEHExceptStmtClass: case Stmt::SEHFinallyStmtClass: + case Stmt::MSDependentExistsStmtClass: llvm_unreachable("invalid statement class to emit generically"); case Stmt::NullStmtClass: case Stmt::CompoundStmtClass: diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp index 5c2ed4e5f5..fb88434929 100644 --- a/lib/Parse/ParseStmt.cpp +++ b/lib/Parse/ParseStmt.cpp @@ -2152,7 +2152,16 @@ void Parser::ParseMicrosoftIfExistsStatement(StmtVector &Stmts) { ParsedAttributes Attrs(AttrFactory); StmtResult Compound = ParseCompoundStatement(Attrs); - // FIXME: We're dropping these statements on the floor. + if (Compound.isInvalid()) + return; + + StmtResult DepResult = Actions.ActOnMSDependentExistsStmt(Result.KeywordLoc, + Result.IsIfExists, + Result.SS, + Result.Name, + Compound.get()); + if (DepResult.isUsable()) + Stmts.push_back(DepResult.get()); return; } diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index c4571c96d0..2726906c1b 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -4665,18 +4665,18 @@ StmtResult Sema::ActOnFinishFullStmt(Stmt *FullStmt) { return MaybeCreateStmtWithCleanups(FullStmt); } -Sema::IfExistsResult Sema::CheckMicrosoftIfExistsSymbol(Scope *S, - CXXScopeSpec &SS, - UnqualifiedId &Name) { - DeclarationNameInfo TargetNameInfo = GetNameFromUnqualifiedId(Name); +Sema::IfExistsResult +Sema::CheckMicrosoftIfExistsSymbol(Scope *S, + CXXScopeSpec &SS, + const DeclarationNameInfo &TargetNameInfo) { DeclarationName TargetName = TargetNameInfo.getName(); if (!TargetName) return IER_DoesNotExist; - + // If the name itself is dependent, then the result is dependent. if (TargetName.isDependentName()) return IER_Dependent; - + // Do the redeclaration lookup in the current scope. LookupResult R(*this, TargetNameInfo, Sema::LookupAnyName, Sema::NotForRedeclaration); @@ -4697,5 +4697,13 @@ Sema::IfExistsResult Sema::CheckMicrosoftIfExistsSymbol(Scope *S, return IER_Dependent; } - return IER_DoesNotExist; + return IER_DoesNotExist; } + +Sema::IfExistsResult Sema::CheckMicrosoftIfExistsSymbol(Scope *S, + CXXScopeSpec &SS, + UnqualifiedId &Name) { + DeclarationNameInfo TargetNameInfo = GetNameFromUnqualifiedId(Name); + return CheckMicrosoftIfExistsSymbol(S, SS, TargetNameInfo); +} + diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 5351896204..3297c0641f 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -2484,3 +2484,26 @@ Sema::ActOnSEHFinallyBlock(SourceLocation Loc, assert(Block); return Owned(SEHFinallyStmt::Create(Context,Loc,Block)); } + +StmtResult Sema::BuildMSDependentExistsStmt(SourceLocation KeywordLoc, + bool IsIfExists, + NestedNameSpecifierLoc QualifierLoc, + DeclarationNameInfo NameInfo, + Stmt *Nested) +{ + return new (Context) MSDependentExistsStmt(KeywordLoc, IsIfExists, + QualifierLoc, NameInfo, + cast<CompoundStmt>(Nested)); +} + + +StmtResult Sema::ActOnMSDependentExistsStmt(SourceLocation KeywordLoc, + bool IsIfExists, + CXXScopeSpec &SS, + UnqualifiedId &Name, + Stmt *Nested) { + return BuildMSDependentExistsStmt(KeywordLoc, IsIfExists, + SS.getWithLocInContext(Context), + GetNameFromUnqualifiedId(Name), + Nested); +} diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index b4073eb650..dde8a974c9 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -1291,7 +1291,20 @@ public: return getSema().BuildCXXForRangeStmt(ForLoc, ColonLoc, Range, BeginEnd, Cond, Inc, LoopVar, RParenLoc); } - + + /// \brief Build a new C++0x range-based for statement. + /// + /// By default, performs semantic analysis to build the new statement. + /// Subclasses may override this routine to provide different behavior. + StmtResult RebuildMSDependentExistsStmt(SourceLocation KeywordLoc, + bool IsIfExists, + NestedNameSpecifierLoc QualifierLoc, + DeclarationNameInfo NameInfo, + Stmt *Nested) { + return getSema().BuildMSDependentExistsStmt(KeywordLoc, IsIfExists, + QualifierLoc, NameInfo, Nested); + } + /// \brief Attach body to a C++0x range-based for statement. /// /// By default, performs semantic analysis to finish the new statement. @@ -5747,6 +5760,72 @@ TreeTransform<Derived>::TransformCXXForRangeStmt(CXXForRangeStmt *S) { template<typename Derived> StmtResult +TreeTransform<Derived>::TransformMSDependentExistsStmt( + MSDependentExistsStmt *S) { + // Transform the nested-name-specifier, if any. + NestedNameSpecifierLoc QualifierLoc; + if (S->getQualifierLoc()) { + QualifierLoc + = getDerived().TransformNestedNameSpecifierLoc(S->getQualifierLoc()); + if (!QualifierLoc) + return StmtError(); + } + + // Transform the declaration name. + DeclarationNameInfo NameInfo = S->getNameInfo(); + if (NameInfo.getName()) { + NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo); + if (!NameInfo.getName()) + return StmtError(); + } + + // Check whether anything changed. + if (!getDerived().AlwaysRebuild() && + QualifierLoc == S->getQualifierLoc() && + NameInfo.getName() == S->getNameInfo().getName()) + return S; + + // Determine whether this name exists, if we can. + CXXScopeSpec SS; + SS.Adopt(QualifierLoc); + bool Dependent = false; + switch (getSema().CheckMicrosoftIfExistsSymbol(/*S=*/0, SS, NameInfo)) { + case Sema::IER_Exists: + if (S->isIfExists()) + break; + + return new (getSema().Context) NullStmt(S->getKeywordLoc()); + + case Sema::IER_DoesNotExist: + if (S->isIfNotExists()) + break; + + return new (getSema().Context) NullStmt(S->getKeywordLoc()); + + case Sema::IER_Dependent: + Dependent = true; + break; + } + + // We need to continue with the instantiation, so do so now. + StmtResult SubStmt = getDerived().TransformCompoundStmt(S->getSubStmt()); + if (SubStmt.isInvalid()) + return StmtError(); + + // If we have resolved the name, just transform to the substatement. + if (!Dependent) + return SubStmt; + + // The name is still dependent, so build a dependent expression again. + return getDerived().RebuildMSDependentExistsStmt(S->getKeywordLoc(), + S->isIfExists(), + QualifierLoc, + NameInfo, + SubStmt.get()); +} + +template<typename Derived> +StmtResult TreeTransform<Derived>::TransformSEHTryStmt(SEHTryStmt *S) { StmtResult TryBlock; // = getDerived().TransformCompoundStmt(S->getTryBlock()); if(TryBlock.isInvalid()) return StmtError(); diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp index 85d0f929c4..87912af461 100644 --- a/lib/Serialization/ASTReaderStmt.cpp +++ b/lib/Serialization/ASTReaderStmt.cpp @@ -992,6 +992,15 @@ void ASTStmtReader::VisitCXXForRangeStmt(CXXForRangeStmt *S) { S->setBody(Reader.ReadSubStmt()); } +void ASTStmtReader::VisitMSDependentExistsStmt(MSDependentExistsStmt *S) { + VisitStmt(S); + S->KeywordLoc = ReadSourceLocation(Record, Idx); + S->IsIfExists = Record[Idx++]; + S->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx); + ReadDeclarationNameInfo(S->NameInfo, Record, Idx); + S->SubStmt = Reader.ReadSubStmt(); +} + void ASTStmtReader::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) { VisitCallExpr(E); E->setOperator((OverloadedOperatorKind)Record[Idx++]); @@ -1847,6 +1856,13 @@ Stmt *ASTReader::ReadStmtFromStream(Module &F) { S = new (Context) CXXForRangeStmt(Empty); break; + case STMT_MS_DEPENDENT_EXISTS: + S = new (Context) MSDependentExistsStmt(SourceLocation(), true, + NestedNameSpecifierLoc(), + DeclarationNameInfo(), + 0); + break; + case EXPR_CXX_OPERATOR_CALL: S = new (Context) CXXOperatorCallExpr(Context, Empty); break; diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp index 463203b4a0..0721c299a1 100644 --- a/lib/Serialization/ASTWriterStmt.cpp +++ b/lib/Serialization/ASTWriterStmt.cpp @@ -957,6 +957,16 @@ void ASTStmtWriter::VisitCXXForRangeStmt(CXXForRangeStmt *S) { Code = serialization::STMT_CXX_FOR_RANGE; } +void ASTStmtWriter::VisitMSDependentExistsStmt(MSDependentExistsStmt *S) { + VisitStmt(S); + Writer.AddSourceLocation(S->getKeywordLoc(), Record); + Record.push_back(S->isIfExists()); + Writer.AddNestedNameSpecifierLoc(S->getQualifierLoc(), Record); + Writer.AddDeclarationNameInfo(S->getNameInfo(), Record); + Writer.AddStmt(S->getSubStmt()); + Code = serialization::STMT_MS_DEPENDENT_EXISTS; +} + void ASTStmtWriter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) { VisitCallExpr(E); Record.push_back(E->getOperator()); diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp index 923293093c..13550c793d 100644 --- a/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -556,6 +556,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::NullStmtClass: case Stmt::SwitchStmtClass: case Stmt::WhileStmtClass: + case Expr::MSDependentExistsStmtClass: llvm_unreachable("Stmt should not be in analyzer evaluation loop"); break; |