2006-11-10 12:58:55 +08:00
|
|
|
//===--- Sema.cpp - AST Builder and Semantic Analysis Implementation ------===//
|
2006-08-17 13:51:27 +08:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
2007-12-30 03:59:25 +08:00
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
2006-08-17 13:51:27 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
2006-11-10 12:58:55 +08:00
|
|
|
// This file implements the actions class which performs semantic analysis and
|
|
|
|
// builds an AST out of a parse stream.
|
2006-08-17 13:51:27 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2010-08-13 04:07:10 +08:00
|
|
|
#include "clang/Sema/Sema.h"
|
2010-01-10 20:58:08 +08:00
|
|
|
#include "TargetAttributesSema.h"
|
2009-07-30 11:15:39 +08:00
|
|
|
#include "llvm/ADT/DenseMap.h"
|
2010-02-01 06:27:38 +08:00
|
|
|
#include "llvm/ADT/SmallSet.h"
|
2009-11-07 11:30:10 +08:00
|
|
|
#include "llvm/ADT/APFloat.h"
|
2010-06-01 17:23:16 +08:00
|
|
|
#include "clang/Sema/ExternalSemaSource.h"
|
2010-08-13 06:51:45 +08:00
|
|
|
#include "clang/Sema/SemaConsumer.h"
|
2006-11-10 14:20:45 +08:00
|
|
|
#include "clang/AST/ASTContext.h"
|
2010-02-10 06:26:47 +08:00
|
|
|
#include "clang/AST/ASTDiagnostic.h"
|
2008-08-11 13:35:13 +08:00
|
|
|
#include "clang/AST/DeclObjC.h"
|
2008-08-11 12:54:23 +08:00
|
|
|
#include "clang/AST/Expr.h"
|
2006-10-06 13:22:26 +08:00
|
|
|
#include "clang/Lex/Preprocessor.h"
|
2009-08-27 06:33:56 +08:00
|
|
|
#include "clang/Basic/PartialDiagnostic.h"
|
2009-04-30 14:18:40 +08:00
|
|
|
#include "clang/Basic/TargetInfo.h"
|
2006-08-18 13:17:52 +08:00
|
|
|
using namespace clang;
|
Keep an explicit stack of function and block scopes, each element of
which has the label map, switch statement stack, etc. Previously, we
had a single set of maps in Sema (for the function) along with a stack
of block scopes. However, this lead to funky behavior with nested
functions, e.g., in the member functions of local classes.
The explicit-stack approach is far cleaner, and we retain a 1-element
cache so that we're not malloc/free'ing every time we enter a
function. Fixes PR6382.
Also, tweaked the unused-variable warning suppression logic to look at
errors within a given Scope rather than within a given function. The
prior code wasn't looking at the right number-of-errors count when
dealing with blocks, since the block's count would be deallocated
before we got to ActOnPopScope. This approach works with nested
blocks/functions, and gives tighter error recovery.
llvm-svn: 97518
2010-03-02 07:15:13 +08:00
|
|
|
|
|
|
|
FunctionScopeInfo::~FunctionScopeInfo() { }
|
|
|
|
|
|
|
|
void FunctionScopeInfo::Clear(unsigned NumErrors) {
|
2010-08-01 08:26:45 +08:00
|
|
|
HasBranchProtectedScope = false;
|
|
|
|
HasBranchIntoScope = false;
|
|
|
|
HasIndirectGoto = false;
|
|
|
|
|
Keep an explicit stack of function and block scopes, each element of
which has the label map, switch statement stack, etc. Previously, we
had a single set of maps in Sema (for the function) along with a stack
of block scopes. However, this lead to funky behavior with nested
functions, e.g., in the member functions of local classes.
The explicit-stack approach is far cleaner, and we retain a 1-element
cache so that we're not malloc/free'ing every time we enter a
function. Fixes PR6382.
Also, tweaked the unused-variable warning suppression logic to look at
errors within a given Scope rather than within a given function. The
prior code wasn't looking at the right number-of-errors count when
dealing with blocks, since the block's count would be deallocated
before we got to ActOnPopScope. This approach works with nested
blocks/functions, and gives tighter error recovery.
llvm-svn: 97518
2010-03-02 07:15:13 +08:00
|
|
|
LabelMap.clear();
|
|
|
|
SwitchStack.clear();
|
2010-05-15 14:01:05 +08:00
|
|
|
Returns.clear();
|
Keep an explicit stack of function and block scopes, each element of
which has the label map, switch statement stack, etc. Previously, we
had a single set of maps in Sema (for the function) along with a stack
of block scopes. However, this lead to funky behavior with nested
functions, e.g., in the member functions of local classes.
The explicit-stack approach is far cleaner, and we retain a 1-element
cache so that we're not malloc/free'ing every time we enter a
function. Fixes PR6382.
Also, tweaked the unused-variable warning suppression logic to look at
errors within a given Scope rather than within a given function. The
prior code wasn't looking at the right number-of-errors count when
dealing with blocks, since the block's count would be deallocated
before we got to ActOnPopScope. This approach works with nested
blocks/functions, and gives tighter error recovery.
llvm-svn: 97518
2010-03-02 07:15:13 +08:00
|
|
|
NumErrorsAtStartOfFunction = NumErrors;
|
|
|
|
}
|
|
|
|
|
|
|
|
BlockScopeInfo::~BlockScopeInfo() { }
|
|
|
|
|
2007-11-01 02:42:27 +08:00
|
|
|
void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
|
|
|
|
TUScope = S;
|
2008-12-12 00:49:14 +08:00
|
|
|
PushDeclContext(S, Context.getTranslationUnitDecl());
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2010-05-29 02:45:08 +08:00
|
|
|
VAListTagName = PP.getIdentifierInfo("__va_list_tag");
|
|
|
|
|
2010-07-05 05:44:19 +08:00
|
|
|
if (!Context.isInt128Installed() && // May be set by PCHReader.
|
|
|
|
PP.getTargetInfo().getPointerWidth(0) >= 64) {
|
2009-12-07 10:54:59 +08:00
|
|
|
TypeSourceInfo *TInfo;
|
2009-10-24 16:00:42 +08:00
|
|
|
|
2009-04-30 14:18:40 +08:00
|
|
|
// Install [u]int128_t for 64-bit targets.
|
2009-12-07 10:54:59 +08:00
|
|
|
TInfo = Context.getTrivialTypeSourceInfo(Context.Int128Ty);
|
2009-04-30 14:18:40 +08:00
|
|
|
PushOnScopeChains(TypedefDecl::Create(Context, CurContext,
|
|
|
|
SourceLocation(),
|
|
|
|
&Context.Idents.get("__int128_t"),
|
2009-12-07 10:54:59 +08:00
|
|
|
TInfo), TUScope);
|
2009-10-24 16:00:42 +08:00
|
|
|
|
2009-12-07 10:54:59 +08:00
|
|
|
TInfo = Context.getTrivialTypeSourceInfo(Context.UnsignedInt128Ty);
|
2009-04-30 14:18:40 +08:00
|
|
|
PushOnScopeChains(TypedefDecl::Create(Context, CurContext,
|
|
|
|
SourceLocation(),
|
|
|
|
&Context.Idents.get("__uint128_t"),
|
2009-12-07 10:54:59 +08:00
|
|
|
TInfo), TUScope);
|
2010-07-05 05:44:19 +08:00
|
|
|
Context.setInt128Installed();
|
2009-04-30 14:18:40 +08:00
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
|
|
|
|
2008-02-06 08:46:58 +08:00
|
|
|
if (!PP.getLangOptions().ObjC1) return;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-06-16 08:20:10 +08:00
|
|
|
// Built-in ObjC types may already be set by PCHReader (hence isNull checks).
|
2009-04-24 06:29:11 +08:00
|
|
|
if (Context.getObjCSelType().isNull()) {
|
2009-11-22 03:53:08 +08:00
|
|
|
// Create the built-in typedef for 'SEL'.
|
2009-11-24 02:04:25 +08:00
|
|
|
QualType SelT = Context.getPointerType(Context.ObjCBuiltinSelTy);
|
2009-12-07 10:54:59 +08:00
|
|
|
TypeSourceInfo *SelInfo = Context.getTrivialTypeSourceInfo(SelT);
|
2009-10-24 16:00:42 +08:00
|
|
|
TypedefDecl *SelTypedef
|
|
|
|
= TypedefDecl::Create(Context, CurContext, SourceLocation(),
|
|
|
|
&Context.Idents.get("SEL"), SelInfo);
|
2009-04-24 06:29:11 +08:00
|
|
|
PushOnScopeChains(SelTypedef, TUScope);
|
|
|
|
Context.setObjCSelType(Context.getTypeDeclType(SelTypedef));
|
2009-11-26 07:07:42 +08:00
|
|
|
Context.ObjCSelRedefinitionType = Context.getObjCSelType();
|
2009-04-24 06:29:11 +08:00
|
|
|
}
|
|
|
|
|
2008-06-22 04:20:39 +08:00
|
|
|
// Synthesize "@class Protocol;
|
2009-04-24 06:29:11 +08:00
|
|
|
if (Context.getObjCProtoType().isNull()) {
|
|
|
|
ObjCInterfaceDecl *ProtocolDecl =
|
|
|
|
ObjCInterfaceDecl::Create(Context, CurContext, SourceLocation(),
|
2009-09-09 23:08:12 +08:00
|
|
|
&Context.Idents.get("Protocol"),
|
2010-08-11 20:19:30 +08:00
|
|
|
SourceLocation(), true);
|
2009-04-24 06:29:11 +08:00
|
|
|
Context.setObjCProtoType(Context.getObjCInterfaceType(ProtocolDecl));
|
2009-11-19 07:15:37 +08:00
|
|
|
PushOnScopeChains(ProtocolDecl, TUScope, false);
|
2009-04-24 06:29:11 +08:00
|
|
|
}
|
2009-07-16 02:40:39 +08:00
|
|
|
// Create the built-in typedef for 'id'.
|
2009-04-24 06:29:11 +08:00
|
|
|
if (Context.getObjCIdType().isNull()) {
|
2010-05-15 19:32:37 +08:00
|
|
|
QualType T = Context.getObjCObjectType(Context.ObjCBuiltinIdTy, 0, 0);
|
|
|
|
T = Context.getObjCObjectPointerType(T);
|
|
|
|
TypeSourceInfo *IdInfo = Context.getTrivialTypeSourceInfo(T);
|
2009-10-24 16:00:42 +08:00
|
|
|
TypedefDecl *IdTypedef
|
|
|
|
= TypedefDecl::Create(Context, CurContext, SourceLocation(),
|
|
|
|
&Context.Idents.get("id"), IdInfo);
|
2009-04-24 06:29:11 +08:00
|
|
|
PushOnScopeChains(IdTypedef, TUScope);
|
|
|
|
Context.setObjCIdType(Context.getTypeDeclType(IdTypedef));
|
2009-08-18 00:35:33 +08:00
|
|
|
Context.ObjCIdRedefinitionType = Context.getObjCIdType();
|
2009-04-24 06:29:11 +08:00
|
|
|
}
|
2009-07-16 02:40:39 +08:00
|
|
|
// Create the built-in typedef for 'Class'.
|
2009-07-11 07:34:53 +08:00
|
|
|
if (Context.getObjCClassType().isNull()) {
|
2010-05-15 19:32:37 +08:00
|
|
|
QualType T = Context.getObjCObjectType(Context.ObjCBuiltinClassTy, 0, 0);
|
|
|
|
T = Context.getObjCObjectPointerType(T);
|
|
|
|
TypeSourceInfo *ClassInfo = Context.getTrivialTypeSourceInfo(T);
|
2009-10-24 16:00:42 +08:00
|
|
|
TypedefDecl *ClassTypedef
|
|
|
|
= TypedefDecl::Create(Context, CurContext, SourceLocation(),
|
|
|
|
&Context.Idents.get("Class"), ClassInfo);
|
2009-07-11 07:34:53 +08:00
|
|
|
PushOnScopeChains(ClassTypedef, TUScope);
|
|
|
|
Context.setObjCClassType(Context.getTypeDeclType(ClassTypedef));
|
2009-08-18 00:35:33 +08:00
|
|
|
Context.ObjCClassRedefinitionType = Context.getObjCClassType();
|
2010-08-13 06:51:45 +08:00
|
|
|
}
|
2007-10-17 04:40:23 +08:00
|
|
|
}
|
2007-10-11 05:53:07 +08:00
|
|
|
|
2009-04-15 00:27:31 +08:00
|
|
|
Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
|
2009-11-13 16:58:20 +08:00
|
|
|
bool CompleteTranslationUnit,
|
|
|
|
CodeCompleteConsumer *CodeCompleter)
|
2010-01-10 20:58:08 +08:00
|
|
|
: TheTargetAttributesSema(0),
|
|
|
|
LangOpts(pp.getLangOptions()), PP(pp), Context(ctxt), Consumer(consumer),
|
2009-09-09 23:08:12 +08:00
|
|
|
Diags(PP.getDiagnostics()), SourceMgr(PP.getSourceManager()),
|
2009-11-13 16:58:20 +08:00
|
|
|
ExternalSource(0), CodeCompleter(CodeCompleter), CurContext(0),
|
2010-08-05 14:57:20 +08:00
|
|
|
PackContext(0), VisContext(0), TopFunctionScope(0), ParsingDeclDepth(0),
|
2010-08-02 15:14:54 +08:00
|
|
|
IdResolver(pp.getLangOptions()), GlobalNewDeleteDeclared(false),
|
2009-05-15 05:44:34 +08:00
|
|
|
CompleteTranslationUnit(CompleteTranslationUnit),
|
2010-06-28 16:39:25 +08:00
|
|
|
NumSFINAEErrors(0), SuppressAccessChecking(false),
|
|
|
|
NonInstantiationEntries(0), CurrentInstantiationScope(0), TyposCorrected(0),
|
2010-03-23 08:13:23 +08:00
|
|
|
AnalysisWarnings(*this)
|
2009-11-12 05:54:23 +08:00
|
|
|
{
|
2007-10-11 05:53:07 +08:00
|
|
|
TUScope = 0;
|
2008-07-01 18:37:29 +08:00
|
|
|
if (getLangOptions().CPlusPlus)
|
|
|
|
FieldCollector.reset(new CXXFieldCollector());
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2008-11-23 17:13:29 +08:00
|
|
|
// Tell diagnostics how to render things from the AST library.
|
2010-02-10 06:26:47 +08:00
|
|
|
PP.getDiagnostics().SetArgToStringFn(&FormatASTNodeDiagnosticArgument,
|
|
|
|
&Context);
|
2009-11-26 08:44:06 +08:00
|
|
|
|
|
|
|
ExprEvalContexts.push_back(
|
2010-08-13 06:51:45 +08:00
|
|
|
ExpressionEvaluationContextRecord(PotentiallyEvaluated, 0));
|
|
|
|
}
|
|
|
|
|
|
|
|
void Sema::Initialize() {
|
|
|
|
// Tell the AST consumer about this Sema object.
|
|
|
|
Consumer.Initialize(Context);
|
|
|
|
|
|
|
|
// FIXME: Isn't this redundant with the initialization above?
|
|
|
|
if (SemaConsumer *SC = dyn_cast<SemaConsumer>(&Consumer))
|
|
|
|
SC->InitializeSema(*this);
|
|
|
|
|
|
|
|
// Tell the external Sema source about this Sema object.
|
|
|
|
if (ExternalSemaSource *ExternalSema
|
|
|
|
= dyn_cast_or_null<ExternalSemaSource>(Context.getExternalSource()))
|
|
|
|
ExternalSema->InitializeSema(*this);
|
2007-02-28 09:22:02 +08:00
|
|
|
}
|
2006-11-10 14:20:45 +08:00
|
|
|
|
2010-01-10 20:58:08 +08:00
|
|
|
Sema::~Sema() {
|
|
|
|
if (PackContext) FreePackedContext();
|
2010-08-05 14:57:20 +08:00
|
|
|
if (VisContext) FreeVisContext();
|
2010-01-10 20:58:08 +08:00
|
|
|
delete TheTargetAttributesSema;
|
Keep an explicit stack of function and block scopes, each element of
which has the label map, switch statement stack, etc. Previously, we
had a single set of maps in Sema (for the function) along with a stack
of block scopes. However, this lead to funky behavior with nested
functions, e.g., in the member functions of local classes.
The explicit-stack approach is far cleaner, and we retain a 1-element
cache so that we're not malloc/free'ing every time we enter a
function. Fixes PR6382.
Also, tweaked the unused-variable warning suppression logic to look at
errors within a given Scope rather than within a given function. The
prior code wasn't looking at the right number-of-errors count when
dealing with blocks, since the block's count would be deallocated
before we got to ActOnPopScope. This approach works with nested
blocks/functions, and gives tighter error recovery.
llvm-svn: 97518
2010-03-02 07:15:13 +08:00
|
|
|
while (!FunctionScopes.empty())
|
|
|
|
PopFunctionOrBlockScope();
|
2010-08-13 06:51:45 +08:00
|
|
|
|
|
|
|
// Tell the SemaConsumer to forget about us; we're going out of scope.
|
|
|
|
if (SemaConsumer *SC = dyn_cast<SemaConsumer>(&Consumer))
|
|
|
|
SC->ForgetSema();
|
|
|
|
|
|
|
|
// Detach from the external Sema source.
|
|
|
|
if (ExternalSemaSource *ExternalSema
|
2010-08-13 11:15:25 +08:00
|
|
|
= dyn_cast_or_null<ExternalSemaSource>(Context.getExternalSource()))
|
2010-08-13 06:51:45 +08:00
|
|
|
ExternalSema->ForgetSema();
|
2010-01-10 20:58:08 +08:00
|
|
|
}
|
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
/// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
|
2008-01-17 03:17:22 +08:00
|
|
|
/// If there is already an implicit cast, merge into the existing one.
|
2010-07-20 12:20:21 +08:00
|
|
|
/// The result is of the given category.
|
2009-09-09 23:08:12 +08:00
|
|
|
void Sema::ImpCastExprToType(Expr *&Expr, QualType Ty,
|
2010-04-24 06:18:37 +08:00
|
|
|
CastExpr::CastKind Kind,
|
2010-07-20 12:20:21 +08:00
|
|
|
ImplicitCastExpr::ResultCategory Category,
|
2010-08-07 14:22:56 +08:00
|
|
|
const CXXCastPath *BasePath) {
|
2008-09-04 16:38:01 +08:00
|
|
|
QualType ExprTy = Context.getCanonicalType(Expr->getType());
|
|
|
|
QualType TypeTy = Context.getCanonicalType(Ty);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2008-09-04 16:38:01 +08:00
|
|
|
if (ExprTy == TypeTy)
|
|
|
|
return;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-11-07 11:30:10 +08:00
|
|
|
if (Expr->getType()->isPointerType() && Ty->isPointerType()) {
|
|
|
|
QualType ExprBaseType = cast<PointerType>(ExprTy)->getPointeeType();
|
|
|
|
QualType BaseType = cast<PointerType>(TypeTy)->getPointeeType();
|
2008-09-04 16:38:01 +08:00
|
|
|
if (ExprBaseType.getAddressSpace() != BaseType.getAddressSpace()) {
|
2008-11-19 13:27:50 +08:00
|
|
|
Diag(Expr->getExprLoc(), diag::err_implicit_pointer_address_space_cast)
|
|
|
|
<< Expr->getSourceRange();
|
2008-09-04 16:38:01 +08:00
|
|
|
}
|
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// If this is a derived-to-base cast to a through a virtual base, we
|
|
|
|
// need a vtable.
|
|
|
|
if (Kind == CastExpr::CK_DerivedToBase &&
|
2010-08-07 14:22:56 +08:00
|
|
|
BasePathInvolvesVirtualBase(*BasePath)) {
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
QualType T = Expr->getType();
|
|
|
|
if (const PointerType *Pointer = T->getAs<PointerType>())
|
|
|
|
T = Pointer->getPointeeType();
|
|
|
|
if (const RecordType *RecordTy = T->getAs<RecordType>())
|
|
|
|
MarkVTableUsed(Expr->getLocStart(),
|
|
|
|
cast<CXXRecordDecl>(RecordTy->getDecl()));
|
|
|
|
}
|
|
|
|
|
Implement support for operator overloading using candidate operator
functions for built-in operators, e.g., the builtin
bool operator==(int const*, int const*)
can be used for the expression "x1 == x2" given:
struct X {
operator int const*();
} x1, x2;
The scheme for handling these built-in operators is relatively simple:
for each candidate required by the standard, create a special kind of
candidate function for the built-in. If overload resolution picks the
built-in operator, we perform the appropriate conversions on the
arguments and then let the normal built-in operator take care of it.
There may be some optimization opportunity left: if we can reduce the
number of built-in operator overloads we generate, overload resolution
for these cases will go faster. However, one must be careful when
doing this: GCC generates too few operator overloads in our little
test program, and fails to compile it because none of the overloads it
generates match.
Note that we only support operator overload for non-member binary
operators at the moment. The other operators will follow.
As part of this change, ImplicitCastExpr can now be an lvalue.
llvm-svn: 59148
2008-11-13 01:17:38 +08:00
|
|
|
if (ImplicitCastExpr *ImpCast = dyn_cast<ImplicitCastExpr>(Expr)) {
|
2010-08-07 14:22:56 +08:00
|
|
|
if (ImpCast->getCastKind() == Kind && (!BasePath || BasePath->empty())) {
|
2009-09-15 13:28:24 +08:00
|
|
|
ImpCast->setType(Ty);
|
2010-07-20 12:20:21 +08:00
|
|
|
ImpCast->setCategory(Category);
|
2009-09-15 13:28:24 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-07 14:22:56 +08:00
|
|
|
Expr = ImplicitCastExpr::Create(Context, Ty, Kind, Expr, BasePath, Category);
|
2010-07-20 12:20:21 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
ImplicitCastExpr::ResultCategory Sema::CastCategory(Expr *E) {
|
|
|
|
Expr::Classification Classification = E->Classify(Context);
|
|
|
|
return Classification.isRValue() ?
|
|
|
|
ImplicitCastExpr::RValue :
|
|
|
|
(Classification.isLValue() ?
|
|
|
|
ImplicitCastExpr::LValue :
|
|
|
|
ImplicitCastExpr::XValue);
|
2008-01-17 03:17:22 +08:00
|
|
|
}
|
|
|
|
|
2007-08-31 12:53:24 +08:00
|
|
|
void Sema::DeleteExpr(ExprTy *E) {
|
|
|
|
}
|
|
|
|
void Sema::DeleteStmt(StmtTy *S) {
|
|
|
|
}
|
|
|
|
|
2008-08-23 11:19:52 +08:00
|
|
|
/// ActOnEndOfTranslationUnit - This is called at the very end of the
|
|
|
|
/// translation unit when EOF is reached and all but the top-level scope is
|
|
|
|
/// popped.
|
2010-08-05 17:48:16 +08:00
|
|
|
void Sema::ActOnEndOfTranslationUnit() {
|
|
|
|
// At PCH writing, implicit instantiations and VTable handling info are
|
|
|
|
// stored and performed when the PCH is included.
|
|
|
|
if (CompleteTranslationUnit)
|
|
|
|
while (1) {
|
|
|
|
// C++: Perform implicit template instantiations.
|
|
|
|
//
|
|
|
|
// FIXME: When we perform these implicit instantiations, we do not
|
|
|
|
// carefully keep track of the point of instantiation (C++ [temp.point]).
|
|
|
|
// This means that name lookup that occurs within the template
|
|
|
|
// instantiation will always happen at the end of the translation unit,
|
|
|
|
// so it will find some names that should not be found. Although this is
|
|
|
|
// common behavior for C++ compilers, it is technically wrong. In the
|
|
|
|
// future, we either need to be able to filter the results of name lookup
|
|
|
|
// or we need to perform template instantiations earlier.
|
|
|
|
PerformPendingImplicitInstantiations();
|
|
|
|
|
|
|
|
/// If DefinedUsedVTables ends up marking any virtual member
|
|
|
|
/// functions it might lead to more pending template
|
|
|
|
/// instantiations, which is why we need to loop here.
|
|
|
|
if (!DefineUsedVTables())
|
|
|
|
break;
|
|
|
|
}
|
2009-12-07 16:24:59 +08:00
|
|
|
|
2010-08-14 02:42:17 +08:00
|
|
|
// Remove file scoped decls that turned out to be used.
|
2010-08-14 04:13:06 +08:00
|
|
|
UnusedFileScopedDecls.erase(std::remove_if(UnusedFileScopedDecls.begin(),
|
|
|
|
UnusedFileScopedDecls.end(),
|
|
|
|
std::bind2nd(std::mem_fun(&DeclaratorDecl::isUsed),
|
|
|
|
true)),
|
2010-08-14 02:42:17 +08:00
|
|
|
UnusedFileScopedDecls.end());
|
2010-04-10 01:41:13 +08:00
|
|
|
|
2010-08-14 06:48:40 +08:00
|
|
|
if (!CompleteTranslationUnit) {
|
|
|
|
TUScope = 0;
|
2010-08-05 17:48:08 +08:00
|
|
|
return;
|
2010-08-14 06:48:40 +08:00
|
|
|
}
|
2010-08-05 17:48:08 +08:00
|
|
|
|
2009-09-09 02:19:27 +08:00
|
|
|
// Check for #pragma weak identifiers that were never declared
|
|
|
|
// FIXME: This will cause diagnostics to be emitted in a non-determinstic
|
|
|
|
// order! Iterating over a densemap like this is bad.
|
2009-07-30 11:15:39 +08:00
|
|
|
for (llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator
|
2009-09-09 02:19:27 +08:00
|
|
|
I = WeakUndeclaredIdentifiers.begin(),
|
|
|
|
E = WeakUndeclaredIdentifiers.end(); I != E; ++I) {
|
|
|
|
if (I->second.getUsed()) continue;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-09-09 02:19:27 +08:00
|
|
|
Diag(I->second.getLocation(), diag::warn_weak_identifier_undeclared)
|
|
|
|
<< I->first;
|
2009-07-30 11:15:39 +08:00
|
|
|
}
|
|
|
|
|
2009-03-11 07:43:53 +08:00
|
|
|
// C99 6.9.2p2:
|
|
|
|
// A declaration of an identifier for an object that has file
|
|
|
|
// scope without an initializer, and without a storage-class
|
|
|
|
// specifier or with the storage-class specifier static,
|
|
|
|
// constitutes a tentative definition. If a translation unit
|
|
|
|
// contains one or more tentative definitions for an identifier,
|
|
|
|
// and the translation unit contains no external definition for
|
|
|
|
// that identifier, then the behavior is exactly as if the
|
|
|
|
// translation unit contains a file scope declaration of that
|
|
|
|
// identifier, with the composite type as of the end of the
|
|
|
|
// translation unit, with an initializer equal to 0.
|
2010-02-01 06:27:38 +08:00
|
|
|
llvm::SmallSet<VarDecl *, 32> Seen;
|
|
|
|
for (unsigned i = 0, e = TentativeDefinitions.size(); i != e; ++i) {
|
|
|
|
VarDecl *VD = TentativeDefinitions[i]->getActingDefinition();
|
|
|
|
|
|
|
|
// If the tentative definition was completed, getActingDefinition() returns
|
|
|
|
// null. If we've already seen this variable before, insert()'s second
|
|
|
|
// return value is false.
|
|
|
|
if (VD == 0 || VD->isInvalidDecl() || !Seen.insert(VD))
|
2009-04-22 01:11:58 +08:00
|
|
|
continue;
|
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
if (const IncompleteArrayType *ArrayT
|
2009-04-22 01:11:58 +08:00
|
|
|
= Context.getAsIncompleteArrayType(VD->getType())) {
|
2009-09-09 23:08:12 +08:00
|
|
|
if (RequireCompleteType(VD->getLocation(),
|
2009-04-22 01:11:58 +08:00
|
|
|
ArrayT->getElementType(),
|
2009-09-09 02:19:27 +08:00
|
|
|
diag::err_tentative_def_incomplete_type_arr)) {
|
2009-04-22 01:11:58 +08:00
|
|
|
VD->setInvalidDecl();
|
2009-09-09 02:19:27 +08:00
|
|
|
continue;
|
2009-03-11 07:43:53 +08:00
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-09-09 02:19:27 +08:00
|
|
|
// Set the length of the array to 1 (C99 6.9.2p5).
|
|
|
|
Diag(VD->getLocation(), diag::warn_tentative_incomplete_array);
|
|
|
|
llvm::APInt One(Context.getTypeSize(Context.getSizeType()), true);
|
2009-10-16 08:14:28 +08:00
|
|
|
QualType T = Context.getConstantArrayType(ArrayT->getElementType(),
|
|
|
|
One, ArrayType::Normal, 0);
|
2009-09-09 02:19:27 +08:00
|
|
|
VD->setType(T);
|
2009-09-09 23:08:12 +08:00
|
|
|
} else if (RequireCompleteType(VD->getLocation(), VD->getType(),
|
2009-04-22 01:11:58 +08:00
|
|
|
diag::err_tentative_def_incomplete_type))
|
|
|
|
VD->setInvalidDecl();
|
|
|
|
|
|
|
|
// Notify the consumer that we've completed a tentative definition.
|
|
|
|
if (!VD->isInvalidDecl())
|
|
|
|
Consumer.CompleteTentativeDefinition(VD);
|
|
|
|
|
2009-03-11 07:43:53 +08:00
|
|
|
}
|
2010-02-12 08:07:30 +08:00
|
|
|
|
2010-08-14 02:42:17 +08:00
|
|
|
// Output warning for unused file scoped decls.
|
|
|
|
for (std::vector<const DeclaratorDecl*>::iterator
|
|
|
|
I = UnusedFileScopedDecls.begin(),
|
|
|
|
E = UnusedFileScopedDecls.end(); I != E; ++I) {
|
2010-08-14 04:13:06 +08:00
|
|
|
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*I))
|
|
|
|
Diag(FD->getLocation(), diag::warn_unused_function) << FD->getDeclName();
|
|
|
|
else
|
|
|
|
Diag((*I)->getLocation(), diag::warn_unused_variable)
|
|
|
|
<< cast<VarDecl>(*I)->getDeclName();
|
2010-08-14 02:42:17 +08:00
|
|
|
}
|
2010-08-14 06:48:40 +08:00
|
|
|
|
|
|
|
TUScope = 0;
|
2008-08-23 11:19:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-11-10 13:17:58 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Helper functions.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2009-08-09 01:45:02 +08:00
|
|
|
DeclContext *Sema::getFunctionLevelDeclContext() {
|
2009-12-19 18:53:49 +08:00
|
|
|
DeclContext *DC = CurContext;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2010-05-23 00:25:05 +08:00
|
|
|
while (isa<BlockDecl>(DC) || isa<EnumDecl>(DC))
|
2009-08-09 01:45:02 +08:00
|
|
|
DC = DC->getParent();
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-08-09 01:45:02 +08:00
|
|
|
return DC;
|
|
|
|
}
|
|
|
|
|
2008-12-05 07:50:19 +08:00
|
|
|
/// getCurFunctionDecl - If inside of a function body, this returns a pointer
|
|
|
|
/// to the function decl for the function being parsed. If we're currently
|
|
|
|
/// in a 'block', this returns the containing context.
|
|
|
|
FunctionDecl *Sema::getCurFunctionDecl() {
|
2009-08-09 01:45:02 +08:00
|
|
|
DeclContext *DC = getFunctionLevelDeclContext();
|
2008-12-05 07:50:19 +08:00
|
|
|
return dyn_cast<FunctionDecl>(DC);
|
|
|
|
}
|
|
|
|
|
2008-08-11 13:35:13 +08:00
|
|
|
ObjCMethodDecl *Sema::getCurMethodDecl() {
|
2009-08-09 01:45:02 +08:00
|
|
|
DeclContext *DC = getFunctionLevelDeclContext();
|
2008-11-18 00:28:52 +08:00
|
|
|
return dyn_cast<ObjCMethodDecl>(DC);
|
2008-08-11 13:35:13 +08:00
|
|
|
}
|
2008-12-05 07:50:19 +08:00
|
|
|
|
|
|
|
NamedDecl *Sema::getCurFunctionOrMethodDecl() {
|
2009-08-09 01:45:02 +08:00
|
|
|
DeclContext *DC = getFunctionLevelDeclContext();
|
2008-12-05 07:50:19 +08:00
|
|
|
if (isa<ObjCMethodDecl>(DC) || isa<FunctionDecl>(DC))
|
2009-01-20 09:17:11 +08:00
|
|
|
return cast<NamedDecl>(DC);
|
2008-12-05 07:50:19 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-03-21 06:48:49 +08:00
|
|
|
Sema::SemaDiagnosticBuilder::~SemaDiagnosticBuilder() {
|
2009-06-14 15:33:30 +08:00
|
|
|
if (!this->Emit())
|
|
|
|
return;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-03-21 06:48:49 +08:00
|
|
|
// If this is not a note, and we're in a template instantiation
|
|
|
|
// that is different from the last template instantiation where
|
|
|
|
// we emitted an error, print a template instantiation
|
|
|
|
// backtrace.
|
|
|
|
if (!SemaRef.Diags.isBuiltinNote(DiagID) &&
|
|
|
|
!SemaRef.ActiveTemplateInstantiations.empty() &&
|
2009-09-09 23:08:12 +08:00
|
|
|
SemaRef.ActiveTemplateInstantiations.back()
|
2009-03-21 06:48:49 +08:00
|
|
|
!= SemaRef.LastTemplateInstantiationErrorContext) {
|
|
|
|
SemaRef.PrintInstantiationStack();
|
2009-09-09 23:08:12 +08:00
|
|
|
SemaRef.LastTemplateInstantiationErrorContext
|
2009-03-21 06:48:49 +08:00
|
|
|
= SemaRef.ActiveTemplateInstantiations.back();
|
|
|
|
}
|
|
|
|
}
|
Add support for retrieving the Doxygen comment associated with a given
declaration in the AST.
The new ASTContext::getCommentForDecl function searches for a comment
that is attached to the given declaration, and returns that comment,
which may be composed of several comment blocks.
Comments are always available in an AST. However, to avoid harming
performance, we don't actually parse the comments. Rather, we keep the
source ranges of all of the comments within a large, sorted vector,
then lazily extract comments via a binary search in that vector only
when needed (which never occurs in a "normal" compile).
Comments are written to a precompiled header/AST file as a blob of
source ranges. That blob is only lazily loaded when one requests a
comment for a declaration (this never occurs in a "normal" compile).
The indexer testbed now supports comment extraction. When the
-point-at location points to a declaration with a Doxygen-style
comment, the indexer testbed prints the associated comment
block(s). See test/Index/comments.c for an example.
Some notes:
- We don't actually attempt to parse the comment blocks themselves,
beyond identifying them as Doxygen comment blocks to associate them
with a declaration.
- We won't find comment blocks that aren't adjacent to the
declaration, because we start our search based on the location of
the declaration.
- We don't go through the necessary hops to find, for example,
whether some redeclaration of a declaration has comments when our
current declaration does not. Similarly, we don't attempt to
associate a \param Foo marker in a function body comment with the
parameter named Foo (although that is certainly possible).
- Verification of my "no performance impact" claims is still "to be
done".
llvm-svn: 74704
2009-07-03 01:08:52 +08:00
|
|
|
|
2010-03-26 06:17:48 +08:00
|
|
|
Sema::SemaDiagnosticBuilder Sema::Diag(SourceLocation Loc, unsigned DiagID) {
|
|
|
|
if (isSFINAEContext()) {
|
|
|
|
switch (Diagnostic::getDiagnosticSFINAEResponse(DiagID)) {
|
|
|
|
case Diagnostic::SFINAE_Report:
|
|
|
|
// Fall through; we'll report the diagnostic below.
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Diagnostic::SFINAE_SubstitutionFailure:
|
|
|
|
// Count this failure so that we know that template argument deduction
|
|
|
|
// has failed.
|
|
|
|
++NumSFINAEErrors;
|
|
|
|
// Fall through
|
|
|
|
|
|
|
|
case Diagnostic::SFINAE_Suppress:
|
|
|
|
// Suppress this diagnostic.
|
|
|
|
Diags.setLastDiagnosticIgnored();
|
|
|
|
return SemaDiagnosticBuilder(*this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
DiagnosticBuilder DB = Diags.Report(FullSourceLoc(Loc, SourceMgr), DiagID);
|
|
|
|
return SemaDiagnosticBuilder(DB, *this, DiagID);
|
|
|
|
}
|
|
|
|
|
2009-08-27 06:33:56 +08:00
|
|
|
Sema::SemaDiagnosticBuilder
|
|
|
|
Sema::Diag(SourceLocation Loc, const PartialDiagnostic& PD) {
|
|
|
|
SemaDiagnosticBuilder Builder(Diag(Loc, PD.getDiagID()));
|
|
|
|
PD.Emit(Builder);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-08-27 06:33:56 +08:00
|
|
|
return Builder;
|
|
|
|
}
|
|
|
|
|
2010-07-03 01:43:08 +08:00
|
|
|
/// \brief Determines the active Scope associated with the given declaration
|
|
|
|
/// context.
|
|
|
|
///
|
|
|
|
/// This routine maps a declaration context to the active Scope object that
|
|
|
|
/// represents that declaration context in the parser. It is typically used
|
|
|
|
/// from "scope-less" code (e.g., template instantiation, lazy creation of
|
|
|
|
/// declarations) that injects a name for name-lookup purposes and, therefore,
|
|
|
|
/// must update the Scope.
|
|
|
|
///
|
|
|
|
/// \returns The scope corresponding to the given declaraion context, or NULL
|
|
|
|
/// if no such scope is open.
|
|
|
|
Scope *Sema::getScopeForContext(DeclContext *Ctx) {
|
|
|
|
|
|
|
|
if (!Ctx)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
Ctx = Ctx->getPrimaryContext();
|
|
|
|
for (Scope *S = getCurScope(); S; S = S->getParent()) {
|
2010-07-09 07:07:34 +08:00
|
|
|
// Ignore scopes that cannot have declarations. This is important for
|
|
|
|
// out-of-line definitions of static class members.
|
|
|
|
if (S->getFlags() & (Scope::DeclScope | Scope::TemplateParamScope))
|
|
|
|
if (DeclContext *Entity = static_cast<DeclContext *> (S->getEntity()))
|
|
|
|
if (Ctx == Entity->getPrimaryContext())
|
|
|
|
return S;
|
2010-07-03 01:43:08 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
Keep an explicit stack of function and block scopes, each element of
which has the label map, switch statement stack, etc. Previously, we
had a single set of maps in Sema (for the function) along with a stack
of block scopes. However, this lead to funky behavior with nested
functions, e.g., in the member functions of local classes.
The explicit-stack approach is far cleaner, and we retain a 1-element
cache so that we're not malloc/free'ing every time we enter a
function. Fixes PR6382.
Also, tweaked the unused-variable warning suppression logic to look at
errors within a given Scope rather than within a given function. The
prior code wasn't looking at the right number-of-errors count when
dealing with blocks, since the block's count would be deallocated
before we got to ActOnPopScope. This approach works with nested
blocks/functions, and gives tighter error recovery.
llvm-svn: 97518
2010-03-02 07:15:13 +08:00
|
|
|
|
|
|
|
/// \brief Enter a new function scope
|
|
|
|
void Sema::PushFunctionScope() {
|
|
|
|
if (FunctionScopes.empty()) {
|
|
|
|
// Use the "top" function scope rather than having to allocate memory for
|
|
|
|
// a new scope.
|
|
|
|
TopFunctionScope.Clear(getDiagnostics().getNumErrors());
|
|
|
|
FunctionScopes.push_back(&TopFunctionScope);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
FunctionScopes.push_back(
|
|
|
|
new FunctionScopeInfo(getDiagnostics().getNumErrors()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void Sema::PushBlockScope(Scope *BlockScope, BlockDecl *Block) {
|
|
|
|
FunctionScopes.push_back(new BlockScopeInfo(getDiagnostics().getNumErrors(),
|
|
|
|
BlockScope, Block));
|
|
|
|
}
|
|
|
|
|
|
|
|
void Sema::PopFunctionOrBlockScope() {
|
|
|
|
if (FunctionScopes.back() != &TopFunctionScope)
|
|
|
|
delete FunctionScopes.back();
|
|
|
|
else
|
|
|
|
TopFunctionScope.Clear(getDiagnostics().getNumErrors());
|
|
|
|
|
|
|
|
FunctionScopes.pop_back();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Determine whether any errors occurred within this function/method/
|
|
|
|
/// block.
|
|
|
|
bool Sema::hasAnyErrorsInThisFunction() const {
|
|
|
|
unsigned NumErrors = TopFunctionScope.NumErrorsAtStartOfFunction;
|
|
|
|
if (!FunctionScopes.empty())
|
|
|
|
NumErrors = FunctionScopes.back()->NumErrorsAtStartOfFunction;
|
|
|
|
return NumErrors != getDiagnostics().getNumErrors();
|
|
|
|
}
|
|
|
|
|
|
|
|
BlockScopeInfo *Sema::getCurBlock() {
|
|
|
|
if (FunctionScopes.empty())
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return dyn_cast<BlockScopeInfo>(FunctionScopes.back());
|
|
|
|
}
|
2010-06-01 17:23:16 +08:00
|
|
|
|
|
|
|
// Pin this vtable to this file.
|
|
|
|
ExternalSemaSource::~ExternalSemaSource() {}
|