diff options
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/Sema.h | 5 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 46 |
4 files changed, 57 insertions, 1 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 317cd6587eb..03099956b07 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -615,6 +615,11 @@ public: IdentifierInfo &II, bool HasTrailingLParen, const CXXScopeSpec *SS = 0); + virtual ExprResult ActOnOperatorFunctionIdExpr(Scope *S, + SourceLocation OperatorLoc, + OverloadedOperatorKind Op, + bool HasTrailingLParen, + const CXXScopeSpec *SS = 0); virtual ExprResult ActOnConversionFunctionExpr(Scope *S, SourceLocation OperatorLoc, TypeTy *Ty, diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index fdc4aff031c..5ad1429c35d 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -783,6 +783,11 @@ DeclarationName Sema::GetNameForDeclarator(Declarator &D) { Ty = Context.getCanonicalType(Ty); return Context.DeclarationNames.getCXXConversionFunctionName(Ty); } + + case Declarator::DK_Operator: + assert(D.getIdentifier() == 0 && "operator names have no identifier"); + return Context.DeclarationNames.getCXXOperatorName( + D.getOverloadedOperator()); } assert(false && "Unknown name kind"); diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index d113d6b6db9..accdc32d45b 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -2839,7 +2839,7 @@ Action::ExprResult Sema::ActOnBinOp(Scope *S, SourceLocation TokLoc, OverloadedOperatorKind OverOp = OverOps[Opc]; // Lookup this operator. - Decl *D = LookupDecl(&PP.getIdentifierTable().getOverloadedOperator(OverOp), + Decl *D = LookupDecl(Context.DeclarationNames.getCXXOperatorName(OverOp), Decl::IDNS_Ordinary, S); // Add any overloaded operators we find to the overload set. diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index e49ef27af77..f2c6c3b35b1 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -70,6 +70,52 @@ Sema::ExprResult Sema::ActOnConversionFunctionExpr(Scope *S, return new DeclRefExpr(Conversion, Conversion->getType(), OperatorLoc); } +/// ActOnOperatorFunctionIdExpr - Parse a C++ overloaded operator +/// name (e.g., @c operator+ ) as an expression. This is very +/// similar to ActOnIdentifierExpr, except that instead of providing +/// an identifier the parser provides the kind of overloaded +/// operator that was parsed. +Sema::ExprResult Sema::ActOnOperatorFunctionIdExpr(Scope *S, + SourceLocation OperatorLoc, + OverloadedOperatorKind Op, + bool HasTrailingLParen, + const CXXScopeSpec *SS) { + DeclarationName Name = Context.DeclarationNames.getCXXOperatorName(Op); + + Decl *D; + if (SS && !SS->isEmpty()) { + DeclContext *DC = static_cast<DeclContext*>(SS->getScopeRep()); + if (DC == 0) + return true; + D = LookupDecl(Name, Decl::IDNS_Ordinary, S, DC); + } else + D = LookupDecl(Name, Decl::IDNS_Ordinary, S); + + if (D == 0) { + // If there is no conversion function that converts to this type, + // diagnose the problem. + if (SS && !SS->isEmpty()) + return Diag(OperatorLoc, diag::err_typecheck_no_member, + Name.getAsString(), SS->getRange()); + else + return Diag(OperatorLoc, diag::err_undeclared_var_use, + Name.getAsString()); + } + + ValueDecl *VD = cast<ValueDecl>(D); + + // check if referencing a declaration with __attribute__((deprecated)). + if (VD->getAttr<DeprecatedAttr>()) + Diag(OperatorLoc, diag::warn_deprecated, Name.getAsString()); + + // Only create DeclRefExpr's for valid Decl's. + if (VD->isInvalidDecl()) + return true; + + // Create a normal DeclRefExpr. + return new DeclRefExpr(VD, VD->getType(), OperatorLoc); +} + /// ActOnCXXTypeidOfType - Parse typeid( type-id ). Action::ExprResult Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc, |