summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorFrancois Pichet <pichet2000@gmail.com>2010-09-08 12:20:18 +0000
committerFrancois Pichet <pichet2000@gmail.com>2010-09-08 12:20:18 +0000
commit9f4f2078d62d5d0cab1cf0347bb02ac5d223d495 (patch)
treee7901c9ee1e5930e70d47624a19c2c88eba6cca4 /clang/lib/Sema
parente542972828ce89018a6bf3fbb06a9dc91815b243 (diff)
downloadbcm5719-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.cpp2
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp56
-rw-r--r--clang/lib/Sema/TreeTransform.h63
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());
}
OpenPOWER on IntegriCloud