Initial step toward supporting qualification conversions (C++ 4.4).
Changes:
- Sema::IsQualificationConversion determines whether we have a qualification
conversion.
- Sema::CheckSingleAssignment constraints now follows the C++ rules in C++,
performing an implicit conversion from the right-hand side to the type of
the left-hand side rather than checking based on the C notion of
"compatibility". We now rely on the implicit-conversion code to
determine whether the conversion can happen or
not. Sema::TryCopyInitialization has an ugly reference-related
hack to cope with the initialization of references, for now.
- When building DeclRefExprs, strip away the reference type, since
there are no expressions whose type is a reference. We'll need to
do this throughout Sema.
- Expr::isLvalue now permits functions to be lvalues in C++ (but not
in C).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57935 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 943cd9a..d957e33 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -15,6 +15,7 @@
#include "clang/AST/APValue.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclCXX.h"
#include "clang/AST/RecordLayout.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/Basic/TargetInfo.h"
@@ -334,14 +335,17 @@
/// - reference type [C++ [expr]]
///
Expr::isLvalueResult Expr::isLvalue(ASTContext &Ctx) const {
- // first, check the type (C99 6.3.2.1)
- if (TR->isFunctionType()) // from isObjectType()
+ // first, check the type (C99 6.3.2.1). Expressions with function
+ // type in C are not lvalues, but they can be lvalues in C++.
+ if (!Ctx.getLangOptions().CPlusPlus && TR->isFunctionType())
return LV_NotObjectType;
// Allow qualified void which is an incomplete type other than void (yuck).
if (TR->isVoidType() && !Ctx.getCanonicalType(TR).getCVRQualifiers())
return LV_IncompleteVoidType;
+ /// FIXME: Expressions can't have reference type, so the following
+ /// isn't needed.
if (TR->isReferenceType()) // C++ [expr]
return LV_Valid;
@@ -356,7 +360,11 @@
return LV_Valid;
case DeclRefExprClass: { // C99 6.5.1p2
const Decl *RefdDecl = cast<DeclRefExpr>(this)->getDecl();
- if (isa<VarDecl>(RefdDecl) || isa<ImplicitParamDecl>(RefdDecl))
+ if (isa<VarDecl>(RefdDecl) ||
+ isa<ImplicitParamDecl>(RefdDecl) ||
+ // C++ 3.10p2: An lvalue refers to an object or function.
+ isa<FunctionDecl>(RefdDecl) ||
+ isa<OverloadedFunctionDecl>(RefdDecl))
return LV_Valid;
break;
}