summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/Sema.h4
-rw-r--r--clang/lib/Sema/SemaChecking.cpp3
-rw-r--r--clang/lib/Sema/SemaDecl.cpp6
-rw-r--r--clang/lib/Sema/SemaExpr.cpp50
4 files changed, 44 insertions, 19 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
index e35c06dd2f3..ccc6b8c4cbd 100644
--- a/clang/lib/Sema/Sema.h
+++ b/clang/lib/Sema/Sema.h
@@ -43,6 +43,7 @@ namespace clang {
class Expr;
class InitListExpr;
class CallExpr;
+ class DeclRefExpr;
class VarDecl;
class ParmVarDecl;
class TypedefDecl;
@@ -674,6 +675,9 @@ public:
TypeTy *Ty,
bool HasTrailingLParen,
const CXXScopeSpec &SS);
+ DeclRefExpr *BuildDeclRefExpr(NamedDecl *D, QualType Ty, SourceLocation Loc,
+ bool TypeDependent, bool ValueDependent,
+ const CXXScopeSpec *SS = 0);
ExprResult ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
DeclarationName Name,
bool HasTrailingLParen,
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 14aa9968213..5bb78cd765d 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -883,7 +883,8 @@ static DeclRefExpr* EvalVal(Expr *E) {
// viewed AST node. We then recursively traverse the AST by calling
// EvalAddr and EvalVal appropriately.
switch (E->getStmtClass()) {
- case Stmt::DeclRefExprClass: {
+ case Stmt::DeclRefExprClass:
+ case Stmt::QualifiedDeclRefExprClass: {
// DeclRefExpr: the base case. When we hit a DeclRefExpr we are looking
// at code that refers to a variable's name. We check if it has local
// storage within the function, and if so, return the expression.
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 0396f520a84..dce1e129a59 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -1570,7 +1570,8 @@ bool Sema::CheckAddressConstantExpressionLValue(const Expr* Init) {
}
case Expr::CompoundLiteralExprClass:
return cast<CompoundLiteralExpr>(Init)->isFileScope();
- case Expr::DeclRefExprClass: {
+ case Expr::DeclRefExprClass:
+ case Expr::QualifiedDeclRefExprClass: {
const Decl *D = cast<DeclRefExpr>(Init)->getDecl();
if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
if (VD->hasGlobalStorage())
@@ -1829,7 +1830,8 @@ bool Sema::CheckArithmeticConstantExpression(const Expr* Init) {
InitializerElementNotConstant(Init);
return true;
}
- case Expr::DeclRefExprClass: {
+ case Expr::DeclRefExprClass:
+ case Expr::QualifiedDeclRefExprClass: {
const Decl *D = cast<DeclRefExpr>(Init)->getDecl();
if (isa<EnumConstantDecl>(D))
return false;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 5e07dfe8d88..8b2aca61ea0 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -358,6 +358,19 @@ Sema::ExprResult Sema::ActOnIdentifierExpr(Scope *S, SourceLocation Loc,
return ActOnDeclarationNameExpr(S, Loc, &II, HasTrailingLParen, SS);
}
+/// BuildDeclRefExpr - Build either a DeclRefExpr or a
+/// QualifiedDeclRefExpr based on whether or not SS is a
+/// nested-name-specifier.
+DeclRefExpr *Sema::BuildDeclRefExpr(NamedDecl *D, QualType Ty, SourceLocation Loc,
+ bool TypeDependent, bool ValueDependent,
+ const CXXScopeSpec *SS) {
+ if (SS && !SS->isEmpty())
+ return new QualifiedDeclRefExpr(D, Ty, Loc, TypeDependent, ValueDependent,
+ SS->getRange().getBegin());
+ else
+ return new DeclRefExpr(D, Ty, Loc, TypeDependent, ValueDependent);
+}
+
/// ActOnDeclarationNameExpr - The parser has read some kind of name
/// (e.g., a C++ id-expression (C++ [expr.prim]p1)). This routine
/// performs lookup on that name and returns an expression that refers
@@ -536,7 +549,7 @@ Sema::ExprResult Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
// Make the DeclRefExpr or BlockDeclRefExpr for the decl.
if (OverloadedFunctionDecl *Ovl = dyn_cast<OverloadedFunctionDecl>(D))
- return new DeclRefExpr(Ovl, Context.OverloadTy, Loc);
+ return BuildDeclRefExpr(Ovl, Context.OverloadTy, Loc, false, false, SS);
ValueDecl *VD = cast<ValueDecl>(D);
@@ -634,8 +647,8 @@ Sema::ExprResult Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
// (FIXME!).
}
- return new DeclRefExpr(VD, VD->getType().getNonReferenceType(), Loc,
- TypeDependent, ValueDependent);
+ return BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), Loc,
+ TypeDependent, ValueDependent, SS);
}
Sema::ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc,
@@ -1595,17 +1608,15 @@ Sema::ActOnCallExpr(Scope *S, ExprTy *fn, SourceLocation LParenLoc,
// If we're directly calling a function or a set of overloaded
// functions, get the appropriate declaration.
- {
- DeclRefExpr *DRExpr = NULL;
- if (ImplicitCastExpr *IcExpr = dyn_cast<ImplicitCastExpr>(Fn))
- DRExpr = dyn_cast<DeclRefExpr>(IcExpr->getSubExpr());
- else
- DRExpr = dyn_cast<DeclRefExpr>(Fn);
-
- if (DRExpr) {
- FDecl = dyn_cast<FunctionDecl>(DRExpr->getDecl());
- Ovl = dyn_cast<OverloadedFunctionDecl>(DRExpr->getDecl());
- }
+ DeclRefExpr *DRExpr = NULL;
+ if (ImplicitCastExpr *IcExpr = dyn_cast<ImplicitCastExpr>(Fn))
+ DRExpr = dyn_cast<DeclRefExpr>(IcExpr->getSubExpr());
+ else
+ DRExpr = dyn_cast<DeclRefExpr>(Fn);
+
+ if (DRExpr) {
+ FDecl = dyn_cast<FunctionDecl>(DRExpr->getDecl());
+ Ovl = dyn_cast<OverloadedFunctionDecl>(DRExpr->getDecl());
}
if (Ovl) {
@@ -1615,8 +1626,14 @@ Sema::ActOnCallExpr(Scope *S, ExprTy *fn, SourceLocation LParenLoc,
return true;
// Update Fn to refer to the actual function selected.
- Expr *NewFn = new DeclRefExpr(FDecl, FDecl->getType(),
- Fn->getSourceRange().getBegin());
+ Expr *NewFn = 0;
+ if (QualifiedDeclRefExpr *QDRExpr = dyn_cast<QualifiedDeclRefExpr>(DRExpr))
+ NewFn = new QualifiedDeclRefExpr(FDecl, FDecl->getType(),
+ QDRExpr->getLocation(), false, false,
+ QDRExpr->getSourceRange().getBegin());
+ else
+ NewFn = new DeclRefExpr(FDecl, FDecl->getType(),
+ Fn->getSourceRange().getBegin());
Fn->Destroy(Context);
Fn = NewFn;
}
@@ -2928,6 +2945,7 @@ QualType Sema::CheckIncrementDecrementOperand(Expr *Op, SourceLocation OpLoc,
static NamedDecl *getPrimaryDecl(Expr *E) {
switch (E->getStmtClass()) {
case Stmt::DeclRefExprClass:
+ case Stmt::QualifiedDeclRefExprClass:
return cast<DeclRefExpr>(E)->getDecl();
case Stmt::MemberExprClass:
// Fields cannot be declared with a 'register' storage class.
OpenPOWER on IntegriCloud