[cfe-commits] [PATCH][MS] - operator __uuidof implementation part 1
Douglas Gregor
dgregor at apple.com
Fri Sep 3 08:56:32 PDT 2010
On Sep 1, 2010, at 8:49 PM, Francois Pichet wrote:
> Hi,
>
> This patch is part 1 of X of my implementation of the Microsoft
> __uuidof operator.
> I want to go incrementally for this one because I don't want to submit
> a huge patch.
> The basic parsing is completed but some sema and all the code gen are missing.
>
> __uuidof is similar to the typeid operator so I used that operator as
> template of what to do.
Index: include/clang/AST/ExprCXX.h
===================================================================
--- include/clang/AST/ExprCXX.h (revision 112800)
+++ include/clang/AST/ExprCXX.h (working copy)
@@ -396,6 +396,82 @@
virtual child_iterator child_end();
};
+/// CXXUuidofExpr - A microsoft C++ @c __uuidof expression, which gets
+/// the _GUID that corresponds to the supplied type or expression.
+///
+/// This represents code like @c __uuidof(COMTYPE) or @c __uuidof(*comPtr)
+class CXXUuidofExpr : public Expr {
Is __uuidof only available in C++ mode, or does MSVC also allow it in C mode?
+private:
+ llvm::PointerUnion<Stmt *, TypeSourceInfo *> Operand;
+ SourceRange Range;
+
+public:
+ CXXUuidofExpr(QualType Ty, TypeSourceInfo *Operand, SourceRange R)
+ : Expr(CXXUuidofExprClass, Ty,
+ // FIXME: is __uuidof really never type-dependent?
+ false,
+ // FIXME: is __uuidof really value-dependent if the type or
+ // expression are dependent?
+ Operand->getType()->isDependentType()),
+ Operand(Operand), Range(R) { }
+
+ CXXUuidofExpr(QualType Ty, Expr *Operand, SourceRange R)
+ : Expr(CXXUuidofExprClass, Ty,
+ // FIXME: is __uuidof really never type-dependent?
+ false,
+ // FIXME: is __uuidof really value-dependent if the type or
+ // expression are dependent?
+ Operand->isTypeDependent() || Operand->isValueDependent()),
+ Operand(Operand), Range(R) { }
Yes, it makes sense that __uuidof is never type-dependent and is only value-dependent if the argument is type- or value-dependent.
Index: lib/Parse/ParseExprCXX.cpp
===================================================================
--- lib/Parse/ParseExprCXX.cpp (revision 112800)
+++ lib/Parse/ParseExprCXX.cpp (working copy)
@@ -534,6 +534,55 @@
return move(Result);
}
+/// ParseCXXUuidof - This handles the Microsoft C++ __uuidof expression.
+///
+/// '__uuidof' '(' expression ')'
+/// '__uuidof' '(' type-id ')'
+///
+ExprResult Parser::ParseCXXUuidof() {
+ assert(Tok.is(tok::kw___uuidof) && "Not '__uuidof'!");
+
+ SourceLocation OpLoc = ConsumeToken();
+ SourceLocation LParenLoc = Tok.getLocation();
+ SourceLocation RParenLoc;
+
+ // __uuidof expressions are always parenthesized.
+ if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
+ "__uuidof"))
+ return ExprError();
+
+ ExprResult Result;
+
+ if (isTypeIdInParens()) {
+ TypeResult Ty = ParseTypeName();
+
+ // Match the ')'.
+ MatchRHSPunctuation(tok::r_paren, LParenLoc);
+
+ if (Ty.isInvalid())
+ return ExprError();
+
+ Result = Actions.ActOnCXXUuidof(OpLoc, LParenLoc, /*isType=*/true,
+ Ty.get().getAsOpaquePtr(), RParenLoc);
+ } else {
+ EnterExpressionEvaluationContext Unevaluated(Actions,
+ Sema::PotentiallyPotentiallyEvaluated);
Is there anything dynamci about __uuidof? In other words, is the result of __uuidof always a constant, or can it involve run-time computation? If it does not involve run-time computation, then you can use the Unevaluated context rather than the PotentiallyPotentiallyEvaluated context.
+/// ActOnCXXUuidof - Parse __uuidof( type-id ) or __uuidof (expression);
+ExprResult
+Sema::ActOnCXXUuidof(SourceLocation OpLoc, SourceLocation LParenLoc,
+ bool isType, void *TyOrExpr, SourceLocation RParenLoc) {
+
+ // Check that _GUID is defined.
+ IdentifierInfo *TypeInfoII = &PP.getIdentifierTable().get("_GUID");
+ LookupResult R(*this, TypeInfoII, SourceLocation(), LookupTagName);
+ LookupQualifiedName(R, Context.getTranslationUnitDecl());
+ RecordDecl *TypeInfoRecordDecl = R.getAsSingle<RecordDecl>();
+ if (!TypeInfoRecordDecl)
+ return ExprError(Diag(OpLoc, diag::err_need_header_before_ms_uuidof));
+
+ QualType TypeInfoType = Context.getTypeDeclType(TypeInfoRecordDecl);
You shouldn't do this lookup every time. Instead, you should perform the lookup for _GUID lazily and cache the result in Sema.
@@ -5165,6 +5190,45 @@
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::PotentiallyPotentiallyEvaluated);
Same comment as before about Unevaluated vs. PotentiallyPotentiallyEvaluated.
Otherwise, things are looking good! Don't forget to add AST reading/writing support for this new expression kind.
- Doug
More information about the cfe-commits
mailing list