summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/Sema.h5
-rw-r--r--clang/lib/Sema/SemaDecl.cpp5
-rw-r--r--clang/lib/Sema/SemaExpr.cpp2
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp46
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,
OpenPOWER on IntegriCloud