diff options
author | Francois Pichet <pichet2000@gmail.com> | 2010-09-08 12:20:18 +0000 |
---|---|---|
committer | Francois Pichet <pichet2000@gmail.com> | 2010-09-08 12:20:18 +0000 |
commit | 9f4f2078d62d5d0cab1cf0347bb02ac5d223d495 (patch) | |
tree | e7901c9ee1e5930e70d47624a19c2c88eba6cca4 /clang/lib/Sema | |
parent | e542972828ce89018a6bf3fbb06a9dc91815b243 (diff) | |
download | bcm5719-llvm-9f4f2078d62d5d0cab1cf0347bb02ac5d223d495.tar.gz bcm5719-llvm-9f4f2078d62d5d0cab1cf0347bb02ac5d223d495.zip |
Microsoft's __uuidof operator implementation part 1.
llvm-svn: 113356
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/Sema.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 56 | ||||
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 63 |
3 files changed, 120 insertions, 1 deletions
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 17817d41691..60e8c14cf92 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -138,7 +138,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, CompleteTranslationUnit(CompleteTranslationUnit), NumSFINAEErrors(0), SuppressAccessChecking(false), NonInstantiationEntries(0), CurrentInstantiationScope(0), TyposCorrected(0), - AnalysisWarnings(*this) + AnalysisWarnings(*this), MSVCGuidDecl(0) { TUScope = 0; if (getLangOptions().CPlusPlus) diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 7857ea96935..c3e2c503122 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -370,6 +370,62 @@ Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc, return BuildCXXTypeId(TypeInfoType, OpLoc, (Expr*)TyOrExpr, RParenLoc); } +/// \brief Build a Microsoft __uuidof expression with a type operand. +ExprResult Sema::BuildCXXUuidof(QualType TypeInfoType, + SourceLocation TypeidLoc, + TypeSourceInfo *Operand, + SourceLocation RParenLoc) { + // FIXME: add __uuidof semantic analysis for type operand. + return Owned(new (Context) CXXUuidofExpr(TypeInfoType.withConst(), + Operand, + SourceRange(TypeidLoc, RParenLoc))); +} + +/// \brief Build a Microsoft __uuidof expression with an expression operand. +ExprResult Sema::BuildCXXUuidof(QualType TypeInfoType, + SourceLocation TypeidLoc, + Expr *E, + SourceLocation RParenLoc) { + // FIXME: add __uuidof semantic analysis for expr operand. + return Owned(new (Context) CXXUuidofExpr(TypeInfoType.withConst(), + E, + SourceRange(TypeidLoc, RParenLoc))); +} + +/// ActOnCXXUuidof - Parse __uuidof( type-id ) or __uuidof (expression); +ExprResult +Sema::ActOnCXXUuidof(SourceLocation OpLoc, SourceLocation LParenLoc, + bool isType, void *TyOrExpr, SourceLocation RParenLoc) { + // If MSVCGuidDecl has not been cached, do the lookup. + if (!MSVCGuidDecl) { + IdentifierInfo *GuidII = &PP.getIdentifierTable().get("_GUID"); + LookupResult R(*this, GuidII, SourceLocation(), LookupTagName); + LookupQualifiedName(R, Context.getTranslationUnitDecl()); + MSVCGuidDecl = R.getAsSingle<RecordDecl>(); + if (!MSVCGuidDecl) + return ExprError(Diag(OpLoc, diag::err_need_header_before_ms_uuidof)); + } + + QualType GuidType = Context.getTypeDeclType(MSVCGuidDecl); + + if (isType) { + // The operand is a type; handle it as such. + TypeSourceInfo *TInfo = 0; + QualType T = GetTypeFromParser(ParsedType::getFromOpaquePtr(TyOrExpr), + &TInfo); + if (T.isNull()) + return ExprError(); + + if (!TInfo) + TInfo = Context.getTrivialTypeSourceInfo(T, OpLoc); + + return BuildCXXUuidof(GuidType, OpLoc, TInfo, RParenLoc); + } + + // The operand is an expression. + return BuildCXXUuidof(GuidType, OpLoc, (Expr*)TyOrExpr, RParenLoc); +} + /// ActOnCXXBoolLiteral - Parse {true,false} literals. ExprResult Sema::ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind) { diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 16114f2ca39..746d6ca04cc 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -1513,6 +1513,7 @@ public: RParenLoc); } + /// \brief Build a new C++ typeid(expr) expression. /// /// By default, performs semantic analysis to build the new expression. @@ -1525,6 +1526,30 @@ public: RParenLoc); } + /// \brief Build a new C++ __uuidof(type) expression. + /// + /// By default, performs semantic analysis to build the new expression. + /// Subclasses may override this routine to provide different behavior. + ExprResult RebuildCXXUuidofExpr(QualType TypeInfoType, + SourceLocation TypeidLoc, + TypeSourceInfo *Operand, + SourceLocation RParenLoc) { + return getSema().BuildCXXUuidof(TypeInfoType, TypeidLoc, Operand, + RParenLoc); + } + + /// \brief Build a new C++ __uuidof(expr) expression. + /// + /// By default, performs semantic analysis to build the new expression. + /// Subclasses may override this routine to provide different behavior. + ExprResult RebuildCXXUuidofExpr(QualType TypeInfoType, + SourceLocation TypeidLoc, + Expr *Operand, + SourceLocation RParenLoc) { + return getSema().BuildCXXUuidof(TypeInfoType, TypeidLoc, Operand, + RParenLoc); + } + /// \brief Build a new C++ "this" expression. /// /// By default, builds a new "this" expression without performing any @@ -5145,6 +5170,44 @@ TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) { template<typename Derived> ExprResult +TreeTransform<Derived>::TransformCXXUuidofExpr(CXXUuidofExpr *E) { + if (E->isTypeOperand()) { + TypeSourceInfo *TInfo + = getDerived().TransformType(E->getTypeOperandSourceInfo()); + if (!TInfo) + return ExprError(); + + if (!getDerived().AlwaysRebuild() && + TInfo == E->getTypeOperandSourceInfo()) + return SemaRef.Owned(E->Retain()); + + return getDerived().RebuildCXXTypeidExpr(E->getType(), + E->getLocStart(), + TInfo, + E->getLocEnd()); + } + + // We don't know whether the expression is potentially evaluated until + // after we perform semantic analysis, so the expression is potentially + // potentially evaluated. + EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated); + + ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand()); + if (SubExpr.isInvalid()) + return ExprError(); + + if (!getDerived().AlwaysRebuild() && + SubExpr.get() == E->getExprOperand()) + return SemaRef.Owned(E->Retain()); + + return getDerived().RebuildCXXUuidofExpr(E->getType(), + E->getLocStart(), + SubExpr.get(), + E->getLocEnd()); +} + +template<typename Derived> +ExprResult TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) { return SemaRef.Owned(E->Retain()); } |