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-26 10:13:20 +08:00
|
|
|
#include "clang/Sema/SemaInternal.h"
|
|
|
|
#include "clang/Sema/DelayedDiagnostic.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-08-24 16:50:51 +08:00
|
|
|
#include "clang/Sema/CXXFieldCollector.h"
|
2010-10-13 07:32:35 +08:00
|
|
|
#include "clang/Sema/TemplateDeduction.h"
|
2010-06-01 17:23:16 +08:00
|
|
|
#include "clang/Sema/ExternalSemaSource.h"
|
2010-09-29 04:23:00 +08:00
|
|
|
#include "clang/Sema/ObjCMethodList.h"
|
2010-08-27 07:41:50 +08:00
|
|
|
#include "clang/Sema/PrettyDeclStackTrace.h"
|
2010-08-24 16:50:51 +08:00
|
|
|
#include "clang/Sema/Scope.h"
|
2010-08-25 16:40:02 +08:00
|
|
|
#include "clang/Sema/ScopeInfo.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"
|
2010-08-25 15:42:41 +08:00
|
|
|
#include "clang/AST/DeclCXX.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"
|
2011-05-05 06:10:40 +08:00
|
|
|
#include "clang/AST/ExprCXX.h"
|
2011-02-17 15:39:24 +08:00
|
|
|
#include "clang/AST/StmtCXX.h"
|
2011-12-02 09:47:07 +08:00
|
|
|
#include "clang/Lex/HeaderSearch.h"
|
2006-10-06 13:22:26 +08:00
|
|
|
#include "clang/Lex/Preprocessor.h"
|
2011-09-21 02:13:03 +08:00
|
|
|
#include "clang/Basic/FileManager.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;
|
2010-08-25 16:40:02 +08:00
|
|
|
using namespace sema;
|
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() { }
|
|
|
|
|
2010-11-19 08:19:15 +08:00
|
|
|
void FunctionScopeInfo::Clear() {
|
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
|
|
|
SwitchStack.clear();
|
2010-05-15 14:01:05 +08:00
|
|
|
Returns.clear();
|
2010-11-19 08:19:15 +08:00
|
|
|
ErrorTrap.reset();
|
2011-02-23 09:52:04 +08:00
|
|
|
PossiblyUnreachableDiags.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
|
|
|
}
|
|
|
|
|
|
|
|
BlockScopeInfo::~BlockScopeInfo() { }
|
2012-01-05 11:35:19 +08:00
|
|
|
LambdaScopeInfo::~LambdaScopeInfo() { }
|
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
|
|
|
|
2012-01-17 10:15:51 +08:00
|
|
|
PrintingPolicy Sema::getPrintingPolicy(const ASTContext &Context,
|
|
|
|
const Preprocessor &PP) {
|
2011-09-28 07:30:47 +08:00
|
|
|
PrintingPolicy Policy = Context.getPrintingPolicy();
|
2012-01-17 10:15:51 +08:00
|
|
|
Policy.Bool = Context.getLangOptions().Bool;
|
2011-09-28 07:30:47 +08:00
|
|
|
if (!Policy.Bool) {
|
|
|
|
if (MacroInfo *BoolMacro = PP.getMacroInfo(&Context.Idents.get("bool"))) {
|
|
|
|
Policy.Bool = BoolMacro->isObjectLike() &&
|
|
|
|
BoolMacro->getNumTokens() == 1 &&
|
|
|
|
BoolMacro->getReplacementToken(0).is(tok::kw__Bool);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return Policy;
|
|
|
|
}
|
|
|
|
|
2010-08-26 02:07:12 +08:00
|
|
|
void Sema::ActOnTranslationUnitScope(Scope *S) {
|
2007-11-01 02:42:27 +08:00
|
|
|
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");
|
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,
|
2011-08-26 06:30:56 +08:00
|
|
|
TranslationUnitKind TUKind,
|
2009-11-13 16:58:20 +08:00
|
|
|
CodeCompleteConsumer *CodeCompleter)
|
2011-02-14 09:42:35 +08:00
|
|
|
: TheTargetAttributesSema(0), FPFeatures(pp.getLangOptions()),
|
2010-01-10 20:58:08 +08:00
|
|
|
LangOpts(pp.getLangOptions()), PP(pp), Context(ctxt), Consumer(consumer),
|
2009-09-09 23:08:12 +08:00
|
|
|
Diags(PP.getDiagnostics()), SourceMgr(PP.getSourceManager()),
|
2011-07-07 00:21:37 +08:00
|
|
|
CollectStats(false), ExternalSource(0), CodeCompleter(CodeCompleter),
|
2011-10-07 07:23:20 +08:00
|
|
|
CurContext(0), OriginalLexicalContext(0),
|
|
|
|
PackContext(0), MSStructPragmaOn(false), VisContext(0),
|
2011-11-10 13:35:25 +08:00
|
|
|
ExprNeedsCleanups(false), LateTemplateParser(0), OpaqueParser(0),
|
2012-01-18 06:49:33 +08:00
|
|
|
IdResolver(pp), StdInitializerList(0), CXXTypeInfoDecl(0), MSVCGuidDecl(0),
|
2010-09-09 05:30:16 +08:00
|
|
|
GlobalNewDeleteDeclared(false),
|
2011-08-23 01:25:57 +08:00
|
|
|
ObjCShouldCallSuperDealloc(false),
|
2011-08-29 06:35:17 +08:00
|
|
|
ObjCShouldCallSuperFinalize(false),
|
2011-08-26 06:30:56 +08:00
|
|
|
TUKind(TUKind),
|
2011-01-28 06:31:44 +08:00
|
|
|
NumSFINAEErrors(0), SuppressAccessChecking(false),
|
|
|
|
AccessCheckingSFINAE(false), InNonInstantiationSFINAEContext(false),
|
2010-12-21 06:05:00 +08:00
|
|
|
NonInstantiationEntries(0), ArgumentPackSubstitutionIndex(-1),
|
|
|
|
CurrentInstantiationScope(0), TyposCorrected(0),
|
2010-09-09 05:30:16 +08:00
|
|
|
AnalysisWarnings(*this)
|
2009-11-12 05:54:23 +08:00
|
|
|
{
|
2007-10-11 05:53:07 +08:00
|
|
|
TUScope = 0;
|
2011-06-29 00:20:02 +08:00
|
|
|
LoadedExternalKnownNamespaces = false;
|
|
|
|
|
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(
|
2011-06-16 07:02:42 +08:00
|
|
|
ExpressionEvaluationContextRecord(PotentiallyEvaluated, 0, false));
|
2010-08-25 16:40:02 +08:00
|
|
|
|
2010-11-19 08:19:15 +08:00
|
|
|
FunctionScopes.push_back(new FunctionScopeInfo(Diags));
|
2010-08-13 06:51:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
2011-08-12 13:46:01 +08:00
|
|
|
|
2011-08-12 14:49:56 +08:00
|
|
|
// Initialize predefined 128-bit integer types, if needed.
|
|
|
|
if (PP.getTargetInfo().getPointerWidth(0) >= 64) {
|
|
|
|
// If either of the 128-bit integer types are unavailable to name lookup,
|
|
|
|
// define them now.
|
|
|
|
DeclarationName Int128 = &Context.Idents.get("__int128_t");
|
Make the loading of information attached to an IdentifierInfo from an
AST file more lazy, so that we don't eagerly load that information for
all known identifiers each time a new AST file is loaded. The eager
reloading made some sense in the context of precompiled headers, since
very few identifiers were defined before PCH load time. With modules,
however, a huge amount of code can get parsed before we see an
@import, so laziness becomes important here.
The approach taken to make this information lazy is fairly simple:
when we load a new AST file, we mark all of the existing identifiers
as being out-of-date. Whenever we want to access information that may
come from an AST (e.g., whether the identifier has a macro definition,
or what top-level declarations have that name), we check the
out-of-date bit and, if it's set, ask the AST reader to update the
IdentifierInfo from the AST files. The update is a merge, and we now
take care to merge declarations before/after imports with declarations
from multiple imports.
The results of this optimization are fairly dramatic. On a small
application that brings in 14 non-trivial modules, this takes modules
from being > 3x slower than a "perfect" PCH file down to 30% slower
for a full rebuild. A partial rebuild (where the PCH file or modules
can be re-used) is down to 7% slower. Making the PCH file just a
little imperfect (e.g., adding two smallish modules used by a bunch of
.m files that aren't in the PCH file) tips the scales in favor of the
modules approach, with 24% faster partial rebuilds.
This is just a first step; the lazy scheme could possibly be improved
by adding versioning, so we don't search into modules we already
searched. Moreover, we'll need similar lazy schemes for all of the
other lookup data structures, such as DeclContexts.
llvm-svn: 143100
2011-10-27 17:33:13 +08:00
|
|
|
if (IdResolver.begin(Int128) == IdResolver.end())
|
2011-08-12 14:49:56 +08:00
|
|
|
PushOnScopeChains(Context.getInt128Decl(), TUScope);
|
|
|
|
|
|
|
|
DeclarationName UInt128 = &Context.Idents.get("__uint128_t");
|
Make the loading of information attached to an IdentifierInfo from an
AST file more lazy, so that we don't eagerly load that information for
all known identifiers each time a new AST file is loaded. The eager
reloading made some sense in the context of precompiled headers, since
very few identifiers were defined before PCH load time. With modules,
however, a huge amount of code can get parsed before we see an
@import, so laziness becomes important here.
The approach taken to make this information lazy is fairly simple:
when we load a new AST file, we mark all of the existing identifiers
as being out-of-date. Whenever we want to access information that may
come from an AST (e.g., whether the identifier has a macro definition,
or what top-level declarations have that name), we check the
out-of-date bit and, if it's set, ask the AST reader to update the
IdentifierInfo from the AST files. The update is a merge, and we now
take care to merge declarations before/after imports with declarations
from multiple imports.
The results of this optimization are fairly dramatic. On a small
application that brings in 14 non-trivial modules, this takes modules
from being > 3x slower than a "perfect" PCH file down to 30% slower
for a full rebuild. A partial rebuild (where the PCH file or modules
can be re-used) is down to 7% slower. Making the PCH file just a
little imperfect (e.g., adding two smallish modules used by a bunch of
.m files that aren't in the PCH file) tips the scales in favor of the
modules approach, with 24% faster partial rebuilds.
This is just a first step; the lazy scheme could possibly be improved
by adding versioning, so we don't search into modules we already
searched. Moreover, we'll need similar lazy schemes for all of the
other lookup data structures, such as DeclContexts.
llvm-svn: 143100
2011-10-27 17:33:13 +08:00
|
|
|
if (IdResolver.begin(UInt128) == IdResolver.end())
|
2011-08-12 14:49:56 +08:00
|
|
|
PushOnScopeChains(Context.getUInt128Decl(), TUScope);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-08-12 13:46:01 +08:00
|
|
|
// Initialize predefined Objective-C types:
|
|
|
|
if (PP.getLangOptions().ObjC1) {
|
2011-08-12 14:17:30 +08:00
|
|
|
// If 'SEL' does not yet refer to any declarations, make it refer to the
|
|
|
|
// predefined 'SEL'.
|
|
|
|
DeclarationName SEL = &Context.Idents.get("SEL");
|
Make the loading of information attached to an IdentifierInfo from an
AST file more lazy, so that we don't eagerly load that information for
all known identifiers each time a new AST file is loaded. The eager
reloading made some sense in the context of precompiled headers, since
very few identifiers were defined before PCH load time. With modules,
however, a huge amount of code can get parsed before we see an
@import, so laziness becomes important here.
The approach taken to make this information lazy is fairly simple:
when we load a new AST file, we mark all of the existing identifiers
as being out-of-date. Whenever we want to access information that may
come from an AST (e.g., whether the identifier has a macro definition,
or what top-level declarations have that name), we check the
out-of-date bit and, if it's set, ask the AST reader to update the
IdentifierInfo from the AST files. The update is a merge, and we now
take care to merge declarations before/after imports with declarations
from multiple imports.
The results of this optimization are fairly dramatic. On a small
application that brings in 14 non-trivial modules, this takes modules
from being > 3x slower than a "perfect" PCH file down to 30% slower
for a full rebuild. A partial rebuild (where the PCH file or modules
can be re-used) is down to 7% slower. Making the PCH file just a
little imperfect (e.g., adding two smallish modules used by a bunch of
.m files that aren't in the PCH file) tips the scales in favor of the
modules approach, with 24% faster partial rebuilds.
This is just a first step; the lazy scheme could possibly be improved
by adding versioning, so we don't search into modules we already
searched. Moreover, we'll need similar lazy schemes for all of the
other lookup data structures, such as DeclContexts.
llvm-svn: 143100
2011-10-27 17:33:13 +08:00
|
|
|
if (IdResolver.begin(SEL) == IdResolver.end())
|
2011-08-12 14:17:30 +08:00
|
|
|
PushOnScopeChains(Context.getObjCSelDecl(), TUScope);
|
|
|
|
|
2011-08-12 13:46:01 +08:00
|
|
|
// If 'id' does not yet refer to any declarations, make it refer to the
|
|
|
|
// predefined 'id'.
|
|
|
|
DeclarationName Id = &Context.Idents.get("id");
|
Make the loading of information attached to an IdentifierInfo from an
AST file more lazy, so that we don't eagerly load that information for
all known identifiers each time a new AST file is loaded. The eager
reloading made some sense in the context of precompiled headers, since
very few identifiers were defined before PCH load time. With modules,
however, a huge amount of code can get parsed before we see an
@import, so laziness becomes important here.
The approach taken to make this information lazy is fairly simple:
when we load a new AST file, we mark all of the existing identifiers
as being out-of-date. Whenever we want to access information that may
come from an AST (e.g., whether the identifier has a macro definition,
or what top-level declarations have that name), we check the
out-of-date bit and, if it's set, ask the AST reader to update the
IdentifierInfo from the AST files. The update is a merge, and we now
take care to merge declarations before/after imports with declarations
from multiple imports.
The results of this optimization are fairly dramatic. On a small
application that brings in 14 non-trivial modules, this takes modules
from being > 3x slower than a "perfect" PCH file down to 30% slower
for a full rebuild. A partial rebuild (where the PCH file or modules
can be re-used) is down to 7% slower. Making the PCH file just a
little imperfect (e.g., adding two smallish modules used by a bunch of
.m files that aren't in the PCH file) tips the scales in favor of the
modules approach, with 24% faster partial rebuilds.
This is just a first step; the lazy scheme could possibly be improved
by adding versioning, so we don't search into modules we already
searched. Moreover, we'll need similar lazy schemes for all of the
other lookup data structures, such as DeclContexts.
llvm-svn: 143100
2011-10-27 17:33:13 +08:00
|
|
|
if (IdResolver.begin(Id) == IdResolver.end())
|
2011-08-12 13:46:01 +08:00
|
|
|
PushOnScopeChains(Context.getObjCIdDecl(), TUScope);
|
2011-08-12 13:59:41 +08:00
|
|
|
|
|
|
|
// Create the built-in typedef for 'Class'.
|
|
|
|
DeclarationName Class = &Context.Idents.get("Class");
|
Make the loading of information attached to an IdentifierInfo from an
AST file more lazy, so that we don't eagerly load that information for
all known identifiers each time a new AST file is loaded. The eager
reloading made some sense in the context of precompiled headers, since
very few identifiers were defined before PCH load time. With modules,
however, a huge amount of code can get parsed before we see an
@import, so laziness becomes important here.
The approach taken to make this information lazy is fairly simple:
when we load a new AST file, we mark all of the existing identifiers
as being out-of-date. Whenever we want to access information that may
come from an AST (e.g., whether the identifier has a macro definition,
or what top-level declarations have that name), we check the
out-of-date bit and, if it's set, ask the AST reader to update the
IdentifierInfo from the AST files. The update is a merge, and we now
take care to merge declarations before/after imports with declarations
from multiple imports.
The results of this optimization are fairly dramatic. On a small
application that brings in 14 non-trivial modules, this takes modules
from being > 3x slower than a "perfect" PCH file down to 30% slower
for a full rebuild. A partial rebuild (where the PCH file or modules
can be re-used) is down to 7% slower. Making the PCH file just a
little imperfect (e.g., adding two smallish modules used by a bunch of
.m files that aren't in the PCH file) tips the scales in favor of the
modules approach, with 24% faster partial rebuilds.
This is just a first step; the lazy scheme could possibly be improved
by adding versioning, so we don't search into modules we already
searched. Moreover, we'll need similar lazy schemes for all of the
other lookup data structures, such as DeclContexts.
llvm-svn: 143100
2011-10-27 17:33:13 +08:00
|
|
|
if (IdResolver.begin(Class) == IdResolver.end())
|
2011-08-12 13:59:41 +08:00
|
|
|
PushOnScopeChains(Context.getObjCClassDecl(), TUScope);
|
2012-01-18 02:09:05 +08:00
|
|
|
|
|
|
|
// Create the built-in forward declaratino for 'Protocol'.
|
|
|
|
DeclarationName Protocol = &Context.Idents.get("Protocol");
|
|
|
|
if (IdResolver.begin(Protocol) == IdResolver.end())
|
|
|
|
PushOnScopeChains(Context.getObjCProtocolDecl(), TUScope);
|
2011-08-12 13:46:01 +08:00
|
|
|
}
|
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;
|
2011-04-26 02:49:15 +08:00
|
|
|
MSStructPragmaOn = false;
|
2010-08-25 16:40:02 +08:00
|
|
|
// Kill all the active scopes.
|
|
|
|
for (unsigned I = 1, E = FunctionScopes.size(); I != E; ++I)
|
|
|
|
delete FunctionScopes[I];
|
|
|
|
if (FunctionScopes.size() == 1)
|
|
|
|
delete FunctionScopes[0];
|
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
|
|
|
}
|
|
|
|
|
2011-06-16 07:02:42 +08:00
|
|
|
|
|
|
|
/// makeUnavailableInSystemHeader - There is an error in the current
|
|
|
|
/// context. If we're still in a system header, and we can plausibly
|
|
|
|
/// make the relevant declaration unavailable instead of erroring, do
|
|
|
|
/// so and return true.
|
|
|
|
bool Sema::makeUnavailableInSystemHeader(SourceLocation loc,
|
2011-07-23 18:55:15 +08:00
|
|
|
StringRef msg) {
|
2011-06-16 07:02:42 +08:00
|
|
|
// If we're not in a function, it's an error.
|
|
|
|
FunctionDecl *fn = dyn_cast<FunctionDecl>(CurContext);
|
|
|
|
if (!fn) return false;
|
|
|
|
|
|
|
|
// If we're in template instantiation, it's an error.
|
|
|
|
if (!ActiveTemplateInstantiations.empty())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// If that function's not in a system header, it's an error.
|
|
|
|
if (!Context.getSourceManager().isInSystemHeader(loc))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// If the function is already unavailable, it's not an error.
|
|
|
|
if (fn->hasAttr<UnavailableAttr>()) return true;
|
|
|
|
|
|
|
|
fn->addAttr(new (Context) UnavailableAttr(loc, Context, msg));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2011-04-25 00:28:06 +08:00
|
|
|
ASTMutationListener *Sema::getASTMutationListener() const {
|
|
|
|
return getASTConsumer().GetASTMutationListener();
|
|
|
|
}
|
|
|
|
|
2011-07-07 00:21:37 +08:00
|
|
|
/// \brief Print out statistics about the semantic analysis.
|
|
|
|
void Sema::PrintStats() const {
|
|
|
|
llvm::errs() << "\n*** Semantic Analysis Stats:\n";
|
|
|
|
llvm::errs() << NumSFINAEErrors << " SFINAE diagnostics trapped.\n";
|
|
|
|
|
|
|
|
BumpAlloc.PrintStats();
|
|
|
|
AnalysisWarnings.PrintStats();
|
|
|
|
}
|
|
|
|
|
2011-11-30 06:48:16 +08:00
|
|
|
/// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
|
|
|
|
/// If there is already an implicit cast, merge into the existing one.
|
|
|
|
/// The result is of the given category.
|
|
|
|
ExprResult Sema::ImpCastExprToType(Expr *E, QualType Ty,
|
|
|
|
CastKind Kind, ExprValueKind VK,
|
|
|
|
const CXXCastPath *BasePath,
|
|
|
|
CheckedConversionKind CCK) {
|
2011-10-28 11:31:48 +08:00
|
|
|
#ifndef NDEBUG
|
|
|
|
if (VK == VK_RValue && !E->isRValue()) {
|
|
|
|
switch (Kind) {
|
|
|
|
default:
|
|
|
|
assert(0 && "can't implicitly cast lvalue to rvalue with this cast kind");
|
|
|
|
case CK_LValueToRValue:
|
|
|
|
case CK_ArrayToPointerDecay:
|
|
|
|
case CK_FunctionToPointerDecay:
|
|
|
|
case CK_ToVoid:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2011-11-11 07:32:36 +08:00
|
|
|
assert((VK == VK_RValue || !E->isRValue()) && "can't cast rvalue to lvalue");
|
2011-10-28 11:31:48 +08:00
|
|
|
#endif
|
|
|
|
|
2011-04-09 02:41:53 +08:00
|
|
|
QualType ExprTy = Context.getCanonicalType(E->getType());
|
2008-09-04 16:38:01 +08:00
|
|
|
QualType TypeTy = Context.getCanonicalType(Ty);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2008-09-04 16:38:01 +08:00
|
|
|
if (ExprTy == TypeTy)
|
2011-04-09 02:41:53 +08:00
|
|
|
return Owned(E);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2011-06-16 07:02:42 +08:00
|
|
|
if (getLangOptions().ObjCAutoRefCount)
|
|
|
|
CheckObjCARCConversion(SourceRange(), Ty, E, CCK);
|
|
|
|
|
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.
|
2010-08-25 19:45:40 +08:00
|
|
|
if (Kind == CK_DerivedToBase &&
|
2010-08-07 14:22:56 +08:00
|
|
|
BasePathInvolvesVirtualBase(*BasePath)) {
|
2011-04-09 02:41:53 +08:00
|
|
|
QualType T = E->getType();
|
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 (const PointerType *Pointer = T->getAs<PointerType>())
|
|
|
|
T = Pointer->getPointeeType();
|
|
|
|
if (const RecordType *RecordTy = T->getAs<RecordType>())
|
2011-04-09 02:41:53 +08:00
|
|
|
MarkVTableUsed(E->getLocStart(),
|
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
|
|
|
cast<CXXRecordDecl>(RecordTy->getDecl()));
|
|
|
|
}
|
2011-11-30 06:48:16 +08:00
|
|
|
|
|
|
|
if (ImplicitCastExpr *ImpCast = dyn_cast<ImplicitCastExpr>(E)) {
|
|
|
|
if (ImpCast->getCastKind() == Kind && (!BasePath || BasePath->empty())) {
|
|
|
|
ImpCast->setType(Ty);
|
|
|
|
ImpCast->setValueKind(VK);
|
|
|
|
return Owned(E);
|
|
|
|
}
|
2009-09-15 13:28:24 +08:00
|
|
|
}
|
|
|
|
|
2011-11-30 06:48:16 +08:00
|
|
|
return Owned(ImplicitCastExpr::Create(Context, Ty, Kind, E, BasePath, VK));
|
2010-07-20 12:20:21 +08:00
|
|
|
}
|
|
|
|
|
2011-04-07 17:26:19 +08:00
|
|
|
/// ScalarTypeToBooleanCastKind - Returns the cast kind corresponding
|
|
|
|
/// to the conversion from scalar type ScalarTy to the Boolean type.
|
|
|
|
CastKind Sema::ScalarTypeToBooleanCastKind(QualType ScalarTy) {
|
|
|
|
switch (ScalarTy->getScalarTypeKind()) {
|
|
|
|
case Type::STK_Bool: return CK_NoOp;
|
2011-09-09 13:25:32 +08:00
|
|
|
case Type::STK_CPointer: return CK_PointerToBoolean;
|
|
|
|
case Type::STK_BlockPointer: return CK_PointerToBoolean;
|
|
|
|
case Type::STK_ObjCObjectPointer: return CK_PointerToBoolean;
|
2011-04-07 17:26:19 +08:00
|
|
|
case Type::STK_MemberPointer: return CK_MemberPointerToBoolean;
|
|
|
|
case Type::STK_Integral: return CK_IntegralToBoolean;
|
|
|
|
case Type::STK_Floating: return CK_FloatingToBoolean;
|
|
|
|
case Type::STK_IntegralComplex: return CK_IntegralComplexToBoolean;
|
|
|
|
case Type::STK_FloatingComplex: return CK_FloatingComplexToBoolean;
|
|
|
|
}
|
|
|
|
return CK_Invalid;
|
|
|
|
}
|
|
|
|
|
2010-08-15 09:15:20 +08:00
|
|
|
/// \brief Used to prune the decls of Sema's UnusedFileScopedDecls vector.
|
|
|
|
static bool ShouldRemoveFromUnused(Sema *SemaRef, const DeclaratorDecl *D) {
|
|
|
|
if (D->isUsed())
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
|
|
|
|
// UnusedFileScopedDecls stores the first declaration.
|
|
|
|
// The declaration may have become definition so check again.
|
|
|
|
const FunctionDecl *DeclToCheck;
|
|
|
|
if (FD->hasBody(DeclToCheck))
|
|
|
|
return !SemaRef->ShouldWarnIfUnusedFileScopedDecl(DeclToCheck);
|
|
|
|
|
|
|
|
// Later redecls may add new information resulting in not having to warn,
|
|
|
|
// so check again.
|
2012-01-15 00:38:05 +08:00
|
|
|
DeclToCheck = FD->getMostRecentDecl();
|
2010-08-15 09:15:20 +08:00
|
|
|
if (DeclToCheck != FD)
|
|
|
|
return !SemaRef->ShouldWarnIfUnusedFileScopedDecl(DeclToCheck);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
|
|
|
|
// UnusedFileScopedDecls stores the first declaration.
|
|
|
|
// The declaration may have become definition so check again.
|
|
|
|
const VarDecl *DeclToCheck = VD->getDefinition();
|
|
|
|
if (DeclToCheck)
|
|
|
|
return !SemaRef->ShouldWarnIfUnusedFileScopedDecl(DeclToCheck);
|
|
|
|
|
|
|
|
// Later redecls may add new information resulting in not having to warn,
|
|
|
|
// so check again.
|
2012-01-15 00:38:05 +08:00
|
|
|
DeclToCheck = VD->getMostRecentDecl();
|
2010-08-15 09:15:20 +08:00
|
|
|
if (DeclToCheck != VD)
|
|
|
|
return !SemaRef->ShouldWarnIfUnusedFileScopedDecl(DeclToCheck);
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-02-19 10:53:41 +08:00
|
|
|
namespace {
|
|
|
|
struct UndefinedInternal {
|
|
|
|
NamedDecl *decl;
|
|
|
|
FullSourceLoc useLoc;
|
|
|
|
|
|
|
|
UndefinedInternal(NamedDecl *decl, FullSourceLoc useLoc)
|
|
|
|
: decl(decl), useLoc(useLoc) {}
|
|
|
|
};
|
|
|
|
|
|
|
|
bool operator<(const UndefinedInternal &l, const UndefinedInternal &r) {
|
|
|
|
return l.useLoc.isBeforeInTranslationUnitThan(r.useLoc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// checkUndefinedInternals - Check for undefined objects with internal linkage.
|
|
|
|
static void checkUndefinedInternals(Sema &S) {
|
|
|
|
if (S.UndefinedInternals.empty()) return;
|
|
|
|
|
|
|
|
// Collect all the still-undefined entities with internal linkage.
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<UndefinedInternal, 16> undefined;
|
2011-02-19 10:53:41 +08:00
|
|
|
for (llvm::DenseMap<NamedDecl*,SourceLocation>::iterator
|
|
|
|
i = S.UndefinedInternals.begin(), e = S.UndefinedInternals.end();
|
|
|
|
i != e; ++i) {
|
|
|
|
NamedDecl *decl = i->first;
|
|
|
|
|
|
|
|
// Ignore attributes that have become invalid.
|
|
|
|
if (decl->isInvalidDecl()) continue;
|
|
|
|
|
|
|
|
// __attribute__((weakref)) is basically a definition.
|
|
|
|
if (decl->hasAttr<WeakRefAttr>()) continue;
|
|
|
|
|
|
|
|
if (FunctionDecl *fn = dyn_cast<FunctionDecl>(decl)) {
|
|
|
|
if (fn->isPure() || fn->hasBody())
|
|
|
|
continue;
|
|
|
|
} else {
|
|
|
|
if (cast<VarDecl>(decl)->hasDefinition() != VarDecl::DeclarationOnly)
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// We build a FullSourceLoc so that we can sort with array_pod_sort.
|
|
|
|
FullSourceLoc loc(i->second, S.Context.getSourceManager());
|
|
|
|
undefined.push_back(UndefinedInternal(decl, loc));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (undefined.empty()) return;
|
|
|
|
|
|
|
|
// Sort (in order of use site) so that we're not (as) dependent on
|
|
|
|
// the iteration order through an llvm::DenseMap.
|
|
|
|
llvm::array_pod_sort(undefined.begin(), undefined.end());
|
|
|
|
|
2011-07-23 18:55:15 +08:00
|
|
|
for (SmallVectorImpl<UndefinedInternal>::iterator
|
2011-02-19 10:53:41 +08:00
|
|
|
i = undefined.begin(), e = undefined.end(); i != e; ++i) {
|
|
|
|
NamedDecl *decl = i->decl;
|
|
|
|
S.Diag(decl->getLocation(), diag::warn_undefined_internal)
|
|
|
|
<< isa<VarDecl>(decl) << decl;
|
|
|
|
S.Diag(i->useLoc, diag::note_used_here);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-07-29 02:09:57 +08:00
|
|
|
void Sema::LoadExternalWeakUndeclaredIdentifiers() {
|
|
|
|
if (!ExternalSource)
|
|
|
|
return;
|
|
|
|
|
|
|
|
SmallVector<std::pair<IdentifierInfo *, WeakInfo>, 4> WeakIDs;
|
|
|
|
ExternalSource->ReadWeakUndeclaredIdentifiers(WeakIDs);
|
|
|
|
for (unsigned I = 0, N = WeakIDs.size(); I != N; ++I) {
|
|
|
|
llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator Pos
|
|
|
|
= WeakUndeclaredIdentifiers.find(WeakIDs[I].first);
|
|
|
|
if (Pos != WeakUndeclaredIdentifiers.end())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
WeakUndeclaredIdentifiers.insert(WeakIDs[I]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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() {
|
2011-08-26 06:30:56 +08:00
|
|
|
// Only complete translation units define vtables and perform implicit
|
|
|
|
// instantiations.
|
|
|
|
if (TUKind == TU_Complete) {
|
2012-02-08 00:50:53 +08:00
|
|
|
DiagnoseUseOfUnimplementedSelectors();
|
|
|
|
|
2010-12-13 05:36:11 +08:00
|
|
|
// If any dynamic classes have their key function defined within
|
|
|
|
// this translation unit, then those vtables are considered "used" and must
|
|
|
|
// be emitted.
|
2011-07-28 08:53:40 +08:00
|
|
|
for (DynamicClassesType::iterator I = DynamicClasses.begin(ExternalSource),
|
|
|
|
E = DynamicClasses.end();
|
|
|
|
I != E; ++I) {
|
|
|
|
assert(!(*I)->isDependentType() &&
|
2011-01-26 02:08:22 +08:00
|
|
|
"Should not see dependent types here!");
|
2011-07-28 08:53:40 +08:00
|
|
|
if (const CXXMethodDecl *KeyFunction = Context.getKeyFunction(*I)) {
|
2010-12-13 05:36:11 +08:00
|
|
|
const FunctionDecl *Definition = 0;
|
|
|
|
if (KeyFunction->hasBody(Definition))
|
2011-07-28 08:53:40 +08:00
|
|
|
MarkVTableUsed(Definition->getLocation(), *I, true);
|
2010-12-13 05:36:11 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-05-31 15:58:42 +08:00
|
|
|
// If DefinedUsedVTables ends up marking any virtual member functions it
|
|
|
|
// might lead to more pending template instantiations, which we then need
|
|
|
|
// to instantiate.
|
|
|
|
DefineUsedVTables();
|
|
|
|
|
|
|
|
// 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.
|
|
|
|
PerformPendingInstantiations();
|
2010-11-25 08:35:20 +08:00
|
|
|
}
|
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.
|
2011-07-28 05:45:57 +08:00
|
|
|
UnusedFileScopedDecls.erase(std::remove_if(UnusedFileScopedDecls.begin(0,
|
|
|
|
true),
|
2010-08-15 09:15:20 +08:00
|
|
|
UnusedFileScopedDecls.end(),
|
|
|
|
std::bind1st(std::ptr_fun(ShouldRemoveFromUnused),
|
|
|
|
this)),
|
2010-08-14 02:42:17 +08:00
|
|
|
UnusedFileScopedDecls.end());
|
2010-04-10 01:41:13 +08:00
|
|
|
|
2011-08-26 06:30:56 +08:00
|
|
|
if (TUKind == TU_Prefix) {
|
|
|
|
// Translation unit prefixes don't need any of the checking below.
|
2010-08-14 06:48:40 +08:00
|
|
|
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.
|
2011-07-29 02:09:57 +08:00
|
|
|
LoadExternalWeakUndeclaredIdentifiers();
|
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
|
|
|
}
|
|
|
|
|
2011-08-26 06:30:56 +08:00
|
|
|
if (TUKind == TU_Module) {
|
2011-12-02 09:47:07 +08:00
|
|
|
// If we are building a module, resolve all of the exported declarations
|
|
|
|
// now.
|
|
|
|
if (Module *CurrentModule = PP.getCurrentModule()) {
|
|
|
|
ModuleMap &ModMap = PP.getHeaderSearchInfo().getModuleMap();
|
|
|
|
|
|
|
|
llvm::SmallVector<Module *, 2> Stack;
|
|
|
|
Stack.push_back(CurrentModule);
|
|
|
|
while (!Stack.empty()) {
|
|
|
|
Module *Mod = Stack.back();
|
|
|
|
Stack.pop_back();
|
|
|
|
|
|
|
|
// Resolve the exported declarations.
|
|
|
|
// FIXME: Actually complain, once we figure out how to teach the
|
|
|
|
// diagnostic client to deal with complains in the module map at this
|
|
|
|
// point.
|
|
|
|
ModMap.resolveExports(Mod, /*Complain=*/false);
|
|
|
|
|
|
|
|
// Queue the submodules, so their exports will also be resolved.
|
2012-01-05 07:32:19 +08:00
|
|
|
for (Module::submodule_iterator Sub = Mod->submodule_begin(),
|
|
|
|
SubEnd = Mod->submodule_end();
|
2011-12-02 09:47:07 +08:00
|
|
|
Sub != SubEnd; ++Sub) {
|
2012-01-05 07:32:19 +08:00
|
|
|
Stack.push_back(*Sub);
|
2011-12-02 09:47:07 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-26 06:30:56 +08:00
|
|
|
// Modules don't need any of the checking below.
|
|
|
|
TUScope = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
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;
|
2011-07-28 04:58:46 +08:00
|
|
|
for (TentativeDefinitionsType::iterator
|
|
|
|
T = TentativeDefinitions.begin(ExternalSource),
|
|
|
|
TEnd = TentativeDefinitions.end();
|
|
|
|
T != TEnd; ++T)
|
|
|
|
{
|
|
|
|
VarDecl *VD = (*T)->getActingDefinition();
|
2010-02-01 06:27:38 +08:00
|
|
|
|
|
|
|
// 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
|
|
|
}
|
2011-01-31 15:04:37 +08:00
|
|
|
|
2011-05-05 08:05:47 +08:00
|
|
|
if (LangOpts.CPlusPlus0x &&
|
|
|
|
Diags.getDiagnosticLevel(diag::warn_delegating_ctor_cycle,
|
|
|
|
SourceLocation())
|
2011-09-26 07:23:43 +08:00
|
|
|
!= DiagnosticsEngine::Ignored)
|
2011-05-04 13:57:24 +08:00
|
|
|
CheckDelegatingCtorCycles();
|
|
|
|
|
2011-01-31 15:04:37 +08:00
|
|
|
// If there were errors, disable 'unused' warnings since they will mostly be
|
|
|
|
// noise.
|
|
|
|
if (!Diags.hasErrorOccurred()) {
|
|
|
|
// Output warning for unused file scoped decls.
|
2011-07-28 05:45:57 +08:00
|
|
|
for (UnusedFileScopedDeclsType::iterator
|
|
|
|
I = UnusedFileScopedDecls.begin(ExternalSource),
|
2011-01-31 15:04:37 +08:00
|
|
|
E = UnusedFileScopedDecls.end(); I != E; ++I) {
|
2011-07-28 05:45:57 +08:00
|
|
|
if (ShouldRemoveFromUnused(this, *I))
|
|
|
|
continue;
|
|
|
|
|
2011-01-31 15:04:37 +08:00
|
|
|
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*I)) {
|
|
|
|
const FunctionDecl *DiagD;
|
|
|
|
if (!FD->hasBody(DiagD))
|
|
|
|
DiagD = FD;
|
2011-03-04 01:47:42 +08:00
|
|
|
if (DiagD->isDeleted())
|
|
|
|
continue; // Deleted functions are supposed to be unused.
|
2011-04-20 03:51:10 +08:00
|
|
|
if (DiagD->isReferenced()) {
|
|
|
|
if (isa<CXXMethodDecl>(DiagD))
|
|
|
|
Diag(DiagD->getLocation(), diag::warn_unneeded_member_function)
|
|
|
|
<< DiagD->getDeclName();
|
|
|
|
else
|
|
|
|
Diag(DiagD->getLocation(), diag::warn_unneeded_internal_decl)
|
|
|
|
<< /*function*/0 << DiagD->getDeclName();
|
|
|
|
} else {
|
|
|
|
Diag(DiagD->getLocation(),
|
|
|
|
isa<CXXMethodDecl>(DiagD) ? diag::warn_unused_member_function
|
|
|
|
: diag::warn_unused_function)
|
|
|
|
<< DiagD->getDeclName();
|
|
|
|
}
|
2011-01-31 15:04:37 +08:00
|
|
|
} else {
|
|
|
|
const VarDecl *DiagD = cast<VarDecl>(*I)->getDefinition();
|
|
|
|
if (!DiagD)
|
|
|
|
DiagD = cast<VarDecl>(*I);
|
2011-04-20 03:51:10 +08:00
|
|
|
if (DiagD->isReferenced()) {
|
|
|
|
Diag(DiagD->getLocation(), diag::warn_unneeded_internal_decl)
|
|
|
|
<< /*variable*/1 << DiagD->getDeclName();
|
|
|
|
} else {
|
|
|
|
Diag(DiagD->getLocation(), diag::warn_unused_variable)
|
|
|
|
<< DiagD->getDeclName();
|
|
|
|
}
|
2011-01-31 15:04:37 +08:00
|
|
|
}
|
2010-08-15 09:15:20 +08:00
|
|
|
}
|
2011-02-19 10:53:41 +08:00
|
|
|
|
|
|
|
checkUndefinedInternals(*this);
|
2010-08-14 02:42:17 +08:00
|
|
|
}
|
2010-08-14 06:48:40 +08:00
|
|
|
|
2011-02-22 04:05:19 +08:00
|
|
|
// Check we've noticed that we're no longer parsing the initializer for every
|
|
|
|
// variable. If we miss cases, then at best we have a performance issue and
|
|
|
|
// at worst a rejects-valid bug.
|
|
|
|
assert(ParsingInitForAutoVars.empty() &&
|
|
|
|
"Didn't unmark var as having its initializer parsed");
|
|
|
|
|
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
|
|
|
|
2012-01-07 12:59:52 +08:00
|
|
|
while (true) {
|
|
|
|
if (isa<BlockDecl>(DC) || isa<EnumDecl>(DC)) {
|
|
|
|
DC = DC->getParent();
|
|
|
|
} else if (isa<CXXMethodDecl>(DC) &&
|
|
|
|
cast<CXXRecordDecl>(DC->getParent())->isLambda()) {
|
|
|
|
DC = DC->getParent()->getParent();
|
|
|
|
}
|
|
|
|
else break;
|
|
|
|
}
|
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() {
|
2010-10-13 07:32:35 +08:00
|
|
|
if (!isActive())
|
|
|
|
return;
|
|
|
|
|
2011-01-28 06:31:44 +08:00
|
|
|
if (llvm::Optional<TemplateDeductionInfo*> Info = SemaRef.isSFINAEContext()) {
|
2010-11-19 04:06:41 +08:00
|
|
|
switch (DiagnosticIDs::getDiagnosticSFINAEResponse(getDiagID())) {
|
|
|
|
case DiagnosticIDs::SFINAE_Report:
|
2011-10-19 08:07:01 +08:00
|
|
|
// We'll report the diagnostic below.
|
2010-10-13 07:32:35 +08:00
|
|
|
break;
|
|
|
|
|
2011-10-19 08:07:01 +08:00
|
|
|
case DiagnosticIDs::SFINAE_SubstitutionFailure:
|
|
|
|
// Count this failure so that we know that template argument deduction
|
|
|
|
// has failed.
|
|
|
|
++SemaRef.NumSFINAEErrors;
|
|
|
|
SemaRef.Diags.setLastDiagnosticIgnored();
|
|
|
|
SemaRef.Diags.Clear();
|
|
|
|
Clear();
|
|
|
|
return;
|
|
|
|
|
|
|
|
case DiagnosticIDs::SFINAE_AccessControl: {
|
2011-05-12 07:45:11 +08:00
|
|
|
// Per C++ Core Issue 1170, access control is part of SFINAE.
|
|
|
|
// Additionally, the AccessCheckingSFINAE flag can be used to temporary
|
|
|
|
// make access control a part of SFINAE for the purposes of checking
|
|
|
|
// type traits.
|
|
|
|
if (!SemaRef.AccessCheckingSFINAE &&
|
|
|
|
!SemaRef.getLangOptions().CPlusPlus0x)
|
2011-01-28 06:31:44 +08:00
|
|
|
break;
|
2011-10-19 08:07:01 +08:00
|
|
|
|
|
|
|
SourceLocation Loc = getLocation();
|
|
|
|
|
|
|
|
// Suppress this diagnostic.
|
2010-10-13 07:32:35 +08:00
|
|
|
++SemaRef.NumSFINAEErrors;
|
|
|
|
SemaRef.Diags.setLastDiagnosticIgnored();
|
|
|
|
SemaRef.Diags.Clear();
|
|
|
|
Clear();
|
2011-10-19 08:07:01 +08:00
|
|
|
|
|
|
|
// Now the diagnostic state is clear, produce a C++98 compatibility
|
|
|
|
// warning.
|
|
|
|
SemaRef.Diag(Loc, diag::warn_cxx98_compat_sfinae_access_control);
|
|
|
|
|
|
|
|
// The last diagnostic which Sema produced was ignored. Suppress any
|
|
|
|
// notes attached to it.
|
|
|
|
SemaRef.Diags.setLastDiagnosticIgnored();
|
2010-10-13 07:32:35 +08:00
|
|
|
return;
|
2011-10-19 08:07:01 +08:00
|
|
|
}
|
|
|
|
|
2010-11-19 04:06:41 +08:00
|
|
|
case DiagnosticIDs::SFINAE_Suppress:
|
2010-10-13 07:32:35 +08:00
|
|
|
// Make a copy of this suppressed diagnostic and store it with the
|
|
|
|
// template-deduction information;
|
2010-10-14 01:22:14 +08:00
|
|
|
FlushCounts();
|
2011-09-26 09:18:08 +08:00
|
|
|
Diagnostic DiagInfo(&SemaRef.Diags);
|
2010-10-14 01:22:14 +08:00
|
|
|
|
2011-01-28 06:31:44 +08:00
|
|
|
if (*Info)
|
|
|
|
(*Info)->addSuppressedDiagnostic(DiagInfo.getLocation(),
|
2010-10-13 07:32:35 +08:00
|
|
|
PartialDiagnostic(DiagInfo,
|
|
|
|
SemaRef.Context.getDiagAllocator()));
|
|
|
|
|
|
|
|
// Suppress this diagnostic.
|
|
|
|
SemaRef.Diags.setLastDiagnosticIgnored();
|
|
|
|
SemaRef.Diags.Clear();
|
|
|
|
Clear();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-28 07:30:47 +08:00
|
|
|
// Set up the context's printing policy based on our current state.
|
|
|
|
SemaRef.Context.setPrintingPolicy(SemaRef.getPrintingPolicy());
|
|
|
|
|
2010-10-13 07:32:35 +08:00
|
|
|
// Emit the diagnostic.
|
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.
|
2010-11-19 04:06:41 +08:00
|
|
|
if (!DiagnosticIDs::isBuiltinNote(DiagID) &&
|
2009-03-21 06:48:49 +08:00
|
|
|
!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) {
|
2010-11-19 04:06:41 +08:00
|
|
|
DiagnosticBuilder DB = Diags.Report(Loc, DiagID);
|
2010-03-26 06:17:48 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2011-07-26 13:40:03 +08:00
|
|
|
/// \brief Looks through the macro-expansion chain for the given
|
|
|
|
/// location, looking for a macro expansion with the given name.
|
2011-03-08 15:59:04 +08:00
|
|
|
/// If one is found, returns true and sets the location to that
|
2011-07-26 13:40:03 +08:00
|
|
|
/// expansion loc.
|
2011-07-23 18:55:15 +08:00
|
|
|
bool Sema::findMacroSpelling(SourceLocation &locref, StringRef name) {
|
2011-03-08 15:59:04 +08:00
|
|
|
SourceLocation loc = locref;
|
|
|
|
if (!loc.isMacroID()) return false;
|
|
|
|
|
|
|
|
// There's no good way right now to look at the intermediate
|
2011-07-26 13:40:03 +08:00
|
|
|
// expansions, so just jump to the expansion location.
|
2011-07-26 00:49:02 +08:00
|
|
|
loc = getSourceManager().getExpansionLoc(loc);
|
2011-03-08 15:59:04 +08:00
|
|
|
|
|
|
|
// If that's written with the name, stop here.
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<char, 16> buffer;
|
2011-03-08 15:59:04 +08:00
|
|
|
if (getPreprocessor().getSpelling(loc, buffer) == name) {
|
|
|
|
locref = loc;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
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() {
|
2010-08-25 16:40:02 +08:00
|
|
|
if (FunctionScopes.size() == 1) {
|
|
|
|
// Use the "top" function scope rather than having to allocate
|
|
|
|
// memory for a new scope.
|
2010-11-19 08:19:15 +08:00
|
|
|
FunctionScopes.back()->Clear();
|
2010-08-25 16:40:02 +08:00
|
|
|
FunctionScopes.push_back(FunctionScopes.back());
|
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
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2010-11-19 08:19:15 +08:00
|
|
|
FunctionScopes.push_back(new FunctionScopeInfo(getDiagnostics()));
|
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
|
|
|
}
|
|
|
|
|
|
|
|
void Sema::PushBlockScope(Scope *BlockScope, BlockDecl *Block) {
|
2010-11-19 08:19:15 +08:00
|
|
|
FunctionScopes.push_back(new BlockScopeInfo(getDiagnostics(),
|
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
|
|
|
BlockScope, Block));
|
|
|
|
}
|
|
|
|
|
2012-01-05 11:35:19 +08:00
|
|
|
void Sema::PushLambdaScope(CXXRecordDecl *Lambda) {
|
|
|
|
FunctionScopes.push_back(new LambdaScopeInfo(getDiagnostics(), Lambda));
|
|
|
|
}
|
|
|
|
|
|
|
|
void Sema::PopFunctionScopeInfo(const AnalysisBasedWarnings::Policy *WP,
|
|
|
|
const Decl *D, const BlockExpr *blkExpr) {
|
2011-02-23 09:51:48 +08:00
|
|
|
FunctionScopeInfo *Scope = FunctionScopes.pop_back_val();
|
2010-08-25 16:40:02 +08:00
|
|
|
assert(!FunctionScopes.empty() && "mismatched push/pop!");
|
2011-02-23 09:51:48 +08:00
|
|
|
|
|
|
|
// Issue any analysis-based warnings.
|
|
|
|
if (WP && D)
|
2011-02-23 09:51:53 +08:00
|
|
|
AnalysisWarnings.IssueWarnings(*WP, Scope, D, blkExpr);
|
2011-02-23 09:52:04 +08:00
|
|
|
else {
|
2011-07-23 18:55:15 +08:00
|
|
|
for (SmallVectorImpl<sema::PossiblyUnreachableDiag>::iterator
|
2011-02-23 09:52:04 +08:00
|
|
|
i = Scope->PossiblyUnreachableDiags.begin(),
|
|
|
|
e = Scope->PossiblyUnreachableDiags.end();
|
|
|
|
i != e; ++i) {
|
|
|
|
const sema::PossiblyUnreachableDiag &D = *i;
|
|
|
|
Diag(D.Loc, D.PD);
|
|
|
|
}
|
|
|
|
}
|
2011-02-23 09:51:48 +08:00
|
|
|
|
2011-02-23 09:52:04 +08:00
|
|
|
if (FunctionScopes.back() != Scope) {
|
2010-08-25 16:40:02 +08:00
|
|
|
delete Scope;
|
2011-02-23 09:52:04 +08:00
|
|
|
}
|
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 Determine whether any errors occurred within this function/method/
|
|
|
|
/// block.
|
2011-06-16 07:02:42 +08:00
|
|
|
bool Sema::hasAnyUnrecoverableErrorsInThisFunction() const {
|
|
|
|
return getCurFunction()->ErrorTrap.hasUnrecoverableErrorOccurred();
|
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
|
|
|
}
|
|
|
|
|
|
|
|
BlockScopeInfo *Sema::getCurBlock() {
|
|
|
|
if (FunctionScopes.empty())
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return dyn_cast<BlockScopeInfo>(FunctionScopes.back());
|
|
|
|
}
|
2010-06-01 17:23:16 +08:00
|
|
|
|
2012-01-06 11:05:34 +08:00
|
|
|
LambdaScopeInfo *Sema::getCurLambda() {
|
|
|
|
if (FunctionScopes.empty())
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return dyn_cast<LambdaScopeInfo>(FunctionScopes.back());
|
|
|
|
}
|
|
|
|
|
2010-06-01 17:23:16 +08:00
|
|
|
// Pin this vtable to this file.
|
|
|
|
ExternalSemaSource::~ExternalSemaSource() {}
|
2010-08-27 07:41:50 +08:00
|
|
|
|
2012-01-25 08:49:42 +08:00
|
|
|
void ExternalSemaSource::ReadMethodPool(Selector Sel) { }
|
2010-09-29 04:23:00 +08:00
|
|
|
|
2011-06-29 00:20:02 +08:00
|
|
|
void ExternalSemaSource::ReadKnownNamespaces(
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVectorImpl<NamespaceDecl *> &Namespaces) {
|
2011-06-29 00:20:02 +08:00
|
|
|
}
|
|
|
|
|
2011-07-23 18:55:15 +08:00
|
|
|
void PrettyDeclStackTraceEntry::print(raw_ostream &OS) const {
|
2010-08-27 07:41:50 +08:00
|
|
|
SourceLocation Loc = this->Loc;
|
|
|
|
if (!Loc.isValid() && TheDecl) Loc = TheDecl->getLocation();
|
|
|
|
if (Loc.isValid()) {
|
|
|
|
Loc.print(OS, S.getSourceManager());
|
|
|
|
OS << ": ";
|
|
|
|
}
|
|
|
|
OS << Message;
|
|
|
|
|
|
|
|
if (TheDecl && isa<NamedDecl>(TheDecl)) {
|
|
|
|
std::string Name = cast<NamedDecl>(TheDecl)->getNameAsString();
|
|
|
|
if (!Name.empty())
|
|
|
|
OS << " '" << Name << '\'';
|
|
|
|
}
|
|
|
|
|
|
|
|
OS << '\n';
|
|
|
|
}
|
2011-05-05 06:10:40 +08:00
|
|
|
|
|
|
|
/// \brief Figure out if an expression could be turned into a call.
|
|
|
|
///
|
|
|
|
/// Use this when trying to recover from an error where the programmer may have
|
|
|
|
/// written just the name of a function instead of actually calling it.
|
|
|
|
///
|
|
|
|
/// \param E - The expression to examine.
|
|
|
|
/// \param ZeroArgCallReturnTy - If the expression can be turned into a call
|
|
|
|
/// with no arguments, this parameter is set to the type returned by such a
|
|
|
|
/// call; otherwise, it is set to an empty QualType.
|
2011-10-12 07:14:30 +08:00
|
|
|
/// \param OverloadSet - If the expression is an overloaded function
|
2011-05-05 06:10:40 +08:00
|
|
|
/// name, this parameter is populated with the decls of the various overloads.
|
|
|
|
bool Sema::isExprCallable(const Expr &E, QualType &ZeroArgCallReturnTy,
|
2011-10-12 07:14:30 +08:00
|
|
|
UnresolvedSetImpl &OverloadSet) {
|
2011-05-05 06:10:40 +08:00
|
|
|
ZeroArgCallReturnTy = QualType();
|
2011-10-12 07:14:30 +08:00
|
|
|
OverloadSet.clear();
|
|
|
|
|
|
|
|
if (E.getType() == Context.OverloadTy) {
|
|
|
|
OverloadExpr::FindResult FR = OverloadExpr::find(const_cast<Expr*>(&E));
|
|
|
|
const OverloadExpr *Overloads = FR.Expression;
|
|
|
|
|
2011-05-05 06:10:40 +08:00
|
|
|
for (OverloadExpr::decls_iterator it = Overloads->decls_begin(),
|
|
|
|
DeclsEnd = Overloads->decls_end(); it != DeclsEnd; ++it) {
|
2011-10-12 07:14:30 +08:00
|
|
|
OverloadSet.addDecl(*it);
|
|
|
|
|
|
|
|
// Check whether the function is a non-template which takes no
|
|
|
|
// arguments.
|
|
|
|
if (const FunctionDecl *OverloadDecl
|
|
|
|
= dyn_cast<FunctionDecl>((*it)->getUnderlyingDecl())) {
|
2011-05-05 06:10:40 +08:00
|
|
|
if (OverloadDecl->getMinRequiredArguments() == 0)
|
|
|
|
ZeroArgCallReturnTy = OverloadDecl->getResultType();
|
|
|
|
}
|
|
|
|
}
|
2011-10-12 07:14:30 +08:00
|
|
|
|
2011-10-14 02:26:27 +08:00
|
|
|
// Ignore overloads that are pointer-to-member constants.
|
|
|
|
if (FR.HasFormOfMemberPointer)
|
2011-10-12 07:14:30 +08:00
|
|
|
return false;
|
|
|
|
|
2011-05-05 06:10:40 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2011-10-12 07:14:30 +08:00
|
|
|
if (const DeclRefExpr *DeclRef = dyn_cast<DeclRefExpr>(E.IgnoreParens())) {
|
2011-05-05 06:10:40 +08:00
|
|
|
if (const FunctionDecl *Fun = dyn_cast<FunctionDecl>(DeclRef->getDecl())) {
|
|
|
|
if (Fun->getMinRequiredArguments() == 0)
|
|
|
|
ZeroArgCallReturnTy = Fun->getResultType();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// We don't have an expression that's convenient to get a FunctionDecl from,
|
|
|
|
// but we can at least check if the type is "function of 0 arguments".
|
|
|
|
QualType ExprTy = E.getType();
|
|
|
|
const FunctionType *FunTy = NULL;
|
2011-05-05 08:59:35 +08:00
|
|
|
QualType PointeeTy = ExprTy->getPointeeType();
|
|
|
|
if (!PointeeTy.isNull())
|
|
|
|
FunTy = PointeeTy->getAs<FunctionType>();
|
2011-05-05 06:10:40 +08:00
|
|
|
if (!FunTy)
|
|
|
|
FunTy = ExprTy->getAs<FunctionType>();
|
|
|
|
if (!FunTy && ExprTy == Context.BoundMemberTy) {
|
|
|
|
// Look for the bound-member type. If it's still overloaded, give up,
|
|
|
|
// although we probably should have fallen into the OverloadExpr case above
|
|
|
|
// if we actually have an overloaded bound member.
|
|
|
|
QualType BoundMemberTy = Expr::findBoundMemberType(&E);
|
|
|
|
if (!BoundMemberTy.isNull())
|
|
|
|
FunTy = BoundMemberTy->castAs<FunctionType>();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (const FunctionProtoType *FPT =
|
|
|
|
dyn_cast_or_null<FunctionProtoType>(FunTy)) {
|
|
|
|
if (FPT->getNumArgs() == 0)
|
|
|
|
ZeroArgCallReturnTy = FunTy->getResultType();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Give notes for a set of overloads.
|
|
|
|
///
|
|
|
|
/// A companion to isExprCallable. In cases when the name that the programmer
|
|
|
|
/// wrote was an overloaded function, we may be able to make some guesses about
|
|
|
|
/// plausible overloads based on their return types; such guesses can be handed
|
|
|
|
/// off to this method to be emitted as notes.
|
|
|
|
///
|
|
|
|
/// \param Overloads - The overloads to note.
|
|
|
|
/// \param FinalNoteLoc - If we've suppressed printing some overloads due to
|
|
|
|
/// -fshow-overloads=best, this is the location to attach to the note about too
|
|
|
|
/// many candidates. Typically this will be the location of the original
|
|
|
|
/// ill-formed expression.
|
2011-10-12 07:14:30 +08:00
|
|
|
static void noteOverloads(Sema &S, const UnresolvedSetImpl &Overloads,
|
|
|
|
const SourceLocation FinalNoteLoc) {
|
2011-05-05 06:10:40 +08:00
|
|
|
int ShownOverloads = 0;
|
|
|
|
int SuppressedOverloads = 0;
|
|
|
|
for (UnresolvedSetImpl::iterator It = Overloads.begin(),
|
|
|
|
DeclsEnd = Overloads.end(); It != DeclsEnd; ++It) {
|
|
|
|
// FIXME: Magic number for max shown overloads stolen from
|
|
|
|
// OverloadCandidateSet::NoteCandidates.
|
|
|
|
if (ShownOverloads >= 4 &&
|
2011-10-12 07:14:30 +08:00
|
|
|
S.Diags.getShowOverloads() == DiagnosticsEngine::Ovl_Best) {
|
2011-05-05 06:10:40 +08:00
|
|
|
++SuppressedOverloads;
|
|
|
|
continue;
|
|
|
|
}
|
2011-10-12 07:14:30 +08:00
|
|
|
|
|
|
|
NamedDecl *Fn = (*It)->getUnderlyingDecl();
|
2011-11-16 05:43:28 +08:00
|
|
|
S.Diag(Fn->getLocation(), diag::note_possible_target_of_call);
|
2011-05-05 06:10:40 +08:00
|
|
|
++ShownOverloads;
|
|
|
|
}
|
2011-10-12 07:14:30 +08:00
|
|
|
|
2011-05-05 06:10:40 +08:00
|
|
|
if (SuppressedOverloads)
|
2011-10-12 07:14:30 +08:00
|
|
|
S.Diag(FinalNoteLoc, diag::note_ovl_too_many_candidates)
|
|
|
|
<< SuppressedOverloads;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void notePlausibleOverloads(Sema &S, SourceLocation Loc,
|
|
|
|
const UnresolvedSetImpl &Overloads,
|
|
|
|
bool (*IsPlausibleResult)(QualType)) {
|
|
|
|
if (!IsPlausibleResult)
|
|
|
|
return noteOverloads(S, Overloads, Loc);
|
|
|
|
|
|
|
|
UnresolvedSet<2> PlausibleOverloads;
|
|
|
|
for (OverloadExpr::decls_iterator It = Overloads.begin(),
|
|
|
|
DeclsEnd = Overloads.end(); It != DeclsEnd; ++It) {
|
|
|
|
const FunctionDecl *OverloadDecl = cast<FunctionDecl>(*It);
|
|
|
|
QualType OverloadResultTy = OverloadDecl->getResultType();
|
|
|
|
if (IsPlausibleResult(OverloadResultTy))
|
|
|
|
PlausibleOverloads.addDecl(It.getDecl());
|
|
|
|
}
|
|
|
|
noteOverloads(S, PlausibleOverloads, Loc);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Determine whether the given expression can be called by just
|
|
|
|
/// putting parentheses after it. Notably, expressions with unary
|
|
|
|
/// operators can't be because the unary operator will start parsing
|
|
|
|
/// outside the call.
|
|
|
|
static bool IsCallableWithAppend(Expr *E) {
|
|
|
|
E = E->IgnoreImplicit();
|
|
|
|
return (!isa<CStyleCastExpr>(E) &&
|
|
|
|
!isa<UnaryOperator>(E) &&
|
|
|
|
!isa<BinaryOperator>(E) &&
|
|
|
|
!isa<CXXOperatorCallExpr>(E));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Sema::tryToRecoverWithCall(ExprResult &E, const PartialDiagnostic &PD,
|
|
|
|
bool ForceComplain,
|
|
|
|
bool (*IsPlausibleResult)(QualType)) {
|
|
|
|
SourceLocation Loc = E.get()->getExprLoc();
|
|
|
|
SourceRange Range = E.get()->getSourceRange();
|
|
|
|
|
|
|
|
QualType ZeroArgCallTy;
|
|
|
|
UnresolvedSet<4> Overloads;
|
|
|
|
if (isExprCallable(*E.get(), ZeroArgCallTy, Overloads) &&
|
|
|
|
!ZeroArgCallTy.isNull() &&
|
|
|
|
(!IsPlausibleResult || IsPlausibleResult(ZeroArgCallTy))) {
|
|
|
|
// At this point, we know E is potentially callable with 0
|
|
|
|
// arguments and that it returns something of a reasonable type,
|
|
|
|
// so we can emit a fixit and carry on pretending that E was
|
|
|
|
// actually a CallExpr.
|
|
|
|
SourceLocation ParenInsertionLoc =
|
|
|
|
PP.getLocForEndOfToken(Range.getEnd());
|
|
|
|
Diag(Loc, PD)
|
|
|
|
<< /*zero-arg*/ 1 << Range
|
|
|
|
<< (IsCallableWithAppend(E.get())
|
|
|
|
? FixItHint::CreateInsertion(ParenInsertionLoc, "()")
|
|
|
|
: FixItHint());
|
|
|
|
notePlausibleOverloads(*this, Loc, Overloads, IsPlausibleResult);
|
|
|
|
|
|
|
|
// FIXME: Try this before emitting the fixit, and suppress diagnostics
|
|
|
|
// while doing so.
|
|
|
|
E = ActOnCallExpr(0, E.take(), ParenInsertionLoc,
|
|
|
|
MultiExprArg(*this, 0, 0),
|
|
|
|
ParenInsertionLoc.getLocWithOffset(1));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!ForceComplain) return false;
|
|
|
|
|
|
|
|
Diag(Loc, PD) << /*not zero-arg*/ 0 << Range;
|
|
|
|
notePlausibleOverloads(*this, Loc, Overloads, IsPlausibleResult);
|
|
|
|
E = ExprError();
|
|
|
|
return true;
|
2011-05-05 06:10:40 +08:00
|
|
|
}
|