diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-10-25 01:33:02 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-10-25 01:33:02 +0000 |
commit | ba0513de93d2fab6db5ab30b6927209fcc883078 (patch) | |
tree | 75067afaf5c45f10ab9a9647d6a372ddd925e4a1 /lib/Sema | |
parent | f11e923433b62efb0fbaeb2573e8457f1c4a1b1e (diff) |
Implement support for dependent Microsoft __if_exists/__if_not_exists
statements. As noted in the documentation for the AST node, the
semantics of __if_exists/__if_not_exists are somewhat different from
the way Visual C++ implements them, because our parsed-template
representation can't accommodate VC++ semantics without serious
contortions. Hopefully this implementation is "good enough".
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@142901 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 22 | ||||
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 23 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 81 |
3 files changed, 118 insertions, 8 deletions
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(); |