summaryrefslogtreecommitdiffstats
path: root/lib/Sema/Sema.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/Sema.h')
-rw-r--r--lib/Sema/Sema.h183
1 files changed, 133 insertions, 50 deletions
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 3c7492a..efd04e8 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -95,6 +95,7 @@ namespace clang {
class ObjCMethodDecl;
class ObjCPropertyDecl;
class ObjCContainerDecl;
+ class PseudoDestructorTypeStorage;
class FunctionProtoType;
class CXXBasePath;
class CXXBasePaths;
@@ -107,9 +108,47 @@ namespace clang {
class TargetAttributesSema;
class ADLResult;
-/// BlockSemaInfo - When a block is being parsed, this contains information
-/// about the block. It is pointed to from Sema::CurBlock.
-struct BlockSemaInfo {
+/// \brief Retains information about a function, method, or block that is
+/// currently being parsed.
+struct FunctionScopeInfo {
+ /// \brief Whether this scope information structure defined information for
+ /// a block.
+ bool IsBlockInfo;
+
+ /// \brief Set true when a function, method contains a VLA or ObjC try block,
+ /// which introduce scopes that need to be checked for goto conditions. If a
+ /// function does not contain this, then it need not have the jump checker run on it.
+ bool NeedsScopeChecking;
+
+ /// \brief The number of errors that had occurred before starting this
+ /// function or block.
+ unsigned NumErrorsAtStartOfFunction;
+
+ /// LabelMap - This is a mapping from label identifiers to the LabelStmt for
+ /// it (which acts like the label decl in some ways). Forward referenced
+ /// labels have a LabelStmt created for them with a null location & SubStmt.
+ llvm::DenseMap<IdentifierInfo*, LabelStmt*> LabelMap;
+
+ /// SwitchStack - This is the current set of active switch statements in the
+ /// block.
+ llvm::SmallVector<SwitchStmt*, 8> SwitchStack;
+
+ FunctionScopeInfo(unsigned NumErrors)
+ : IsBlockInfo(false), NeedsScopeChecking(false),
+ NumErrorsAtStartOfFunction(NumErrors) { }
+
+ virtual ~FunctionScopeInfo();
+
+ /// \brief Clear out the information in this function scope, making it
+ /// suitable for reuse.
+ void Clear(unsigned NumErrors);
+
+ static bool classof(const FunctionScopeInfo *FSI) { return true; }
+};
+
+
+/// \brief Retains information about a block that is currently being parsed.
+struct BlockScopeInfo : FunctionScopeInfo {
llvm::SmallVector<ParmVarDecl*, 8> Params;
bool hasPrototype;
bool isVariadic;
@@ -125,22 +164,17 @@ struct BlockSemaInfo {
/// return types, if any, in the block body.
QualType ReturnType;
- /// LabelMap - This is a mapping from label identifiers to the LabelStmt for
- /// it (which acts like the label decl in some ways). Forward referenced
- /// labels have a LabelStmt created for them with a null location & SubStmt.
- llvm::DenseMap<IdentifierInfo*, LabelStmt*> LabelMap;
-
- /// SwitchStack - This is the current set of active switch statements in the
- /// block.
- llvm::SmallVector<SwitchStmt*, 8> SwitchStack;
+ BlockScopeInfo(unsigned NumErrors, Scope *BlockScope, BlockDecl *Block)
+ : FunctionScopeInfo(NumErrors), hasPrototype(false), isVariadic(false),
+ hasBlockDeclRefExprs(false), TheDecl(Block), TheScope(BlockScope)
+ {
+ IsBlockInfo = true;
+ }
- /// SavedFunctionNeedsScopeChecking - This is the value of
- /// CurFunctionNeedsScopeChecking at the point when the block started.
- bool SavedFunctionNeedsScopeChecking;
+ virtual ~BlockScopeInfo();
- /// PrevBlockInfo - If this is nested inside another block, this points
- /// to the outer block.
- BlockSemaInfo *PrevBlockInfo;
+ static bool classof(const FunctionScopeInfo *FSI) { return FSI->IsBlockInfo; }
+ static bool classof(const BlockScopeInfo *BSI) { return true; }
};
/// \brief Holds a QualType and a TypeSourceInfo* that came out of a declarator
@@ -199,38 +233,25 @@ public:
/// CurContext - This is the current declaration context of parsing.
DeclContext *CurContext;
- /// CurBlock - If inside of a block definition, this contains a pointer to
- /// the active block object that represents it.
- BlockSemaInfo *CurBlock;
-
/// PackContext - Manages the stack for #pragma pack. An alignment
/// of 0 indicates default alignment.
void *PackContext; // Really a "PragmaPackStack*"
- /// FunctionLabelMap - This is a mapping from label identifiers to the
- /// LabelStmt for it (which acts like the label decl in some ways). Forward
- /// referenced labels have a LabelStmt created for them with a null location &
- /// SubStmt.
+ /// \brief Stack containing information about each of the nested function,
+ /// block, and method scopes that are currently active.
+ llvm::SmallVector<FunctionScopeInfo *, 4> FunctionScopes;
+
+ /// \brief Cached function scope object used for the top function scope
+ /// and when there is no function scope (in error cases).
///
- /// Note that this should always be accessed through getLabelMap() in order
- /// to handle blocks properly.
- llvm::DenseMap<IdentifierInfo*, LabelStmt*> FunctionLabelMap;
-
- /// FunctionSwitchStack - This is the current set of active switch statements
- /// in the top level function. Clients should always use getSwitchStack() to
- /// handle the case when they are in a block.
- llvm::SmallVector<SwitchStmt*, 8> FunctionSwitchStack;
-
+ /// This should never be accessed directly; rather, it's address will be
+ /// pushed into \c FunctionScopes when we want to re-use it.
+ FunctionScopeInfo TopFunctionScope;
+
/// ExprTemporaries - This is the stack of temporaries that are created by
/// the current full expression.
llvm::SmallVector<CXXTemporary*, 8> ExprTemporaries;
- /// CurFunctionNeedsScopeChecking - This is set to true when a function or
- /// ObjC method body contains a VLA or an ObjC try block, which introduce
- /// scopes that need to be checked for goto conditions. If a function does
- /// not contain this, then it need not have the jump checker run on it.
- bool CurFunctionNeedsScopeChecking;
-
/// ExtVectorDecls - This is a list all the extended vector types. This allows
/// us to associate a raw vector type with one of the ext_vector type names.
/// This is only necessary for issuing pretty diagnostics.
@@ -606,18 +627,42 @@ public:
virtual void ActOnEndOfTranslationUnit();
+ void PushFunctionScope();
+ void PushBlockScope(Scope *BlockScope, BlockDecl *Block);
+ void PopFunctionOrBlockScope();
+
/// getLabelMap() - Return the current label map. If we're in a block, we
/// return it.
llvm::DenseMap<IdentifierInfo*, LabelStmt*> &getLabelMap() {
- return CurBlock ? CurBlock->LabelMap : FunctionLabelMap;
+ if (FunctionScopes.empty())
+ return TopFunctionScope.LabelMap;
+
+ return FunctionScopes.back()->LabelMap;
}
/// getSwitchStack - This is returns the switch stack for the current block or
/// function.
llvm::SmallVector<SwitchStmt*,8> &getSwitchStack() {
- return CurBlock ? CurBlock->SwitchStack : FunctionSwitchStack;
+ if (FunctionScopes.empty())
+ return TopFunctionScope.SwitchStack;
+
+ return FunctionScopes.back()->SwitchStack;
}
+ /// \brief Determine whether the current function or block needs scope
+ /// checking.
+ bool &FunctionNeedsScopeChecking() {
+ if (FunctionScopes.empty())
+ return TopFunctionScope.NeedsScopeChecking;
+
+ return FunctionScopes.back()->NeedsScopeChecking;
+ }
+
+ bool hasAnyErrorsInThisFunction() const;
+
+ /// \brief Retrieve the current block, if any.
+ BlockScopeInfo *getCurBlock();
+
/// WeakTopLevelDeclDecls - access to #pragma weak-generated Decls
llvm::SmallVector<Decl*,2> &WeakTopLevelDecls() { return WeakTopLevelDecl; }
@@ -1440,6 +1485,8 @@ public:
void AtomicPropertySetterGetterRules(ObjCImplDecl* IMPDecl,
ObjCContainerDecl* IDecl);
+ void DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID, ObjCInterfaceDecl *SID);
+
/// MatchTwoMethodDeclarations - Checks if two methods' type match and returns
/// true, or false, accordingly.
bool MatchTwoMethodDeclarations(const ObjCMethodDecl *Method,
@@ -2056,6 +2103,12 @@ public:
SourceLocation Loc,
ASTOwningVector<&ActionBase::DeleteExpr> &ConvertedArgs);
+ virtual TypeTy *getDestructorName(SourceLocation TildeLoc,
+ IdentifierInfo &II, SourceLocation NameLoc,
+ Scope *S, const CXXScopeSpec &SS,
+ TypeTy *ObjectType,
+ bool EnteringContext);
+
/// ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const}_cast's.
virtual OwningExprResult ActOnCXXNamedCast(SourceLocation OpLoc,
tok::TokenKind Kind,
@@ -2167,8 +2220,32 @@ public:
ExprArg Base,
SourceLocation OpLoc,
tok::TokenKind OpKind,
- TypeTy *&ObjectType);
+ TypeTy *&ObjectType,
+ bool &MayBePseudoDestructor);
+ OwningExprResult DiagnoseDtorReference(SourceLocation NameLoc,
+ ExprArg MemExpr);
+
+ OwningExprResult BuildPseudoDestructorExpr(ExprArg Base,
+ SourceLocation OpLoc,
+ tok::TokenKind OpKind,
+ const CXXScopeSpec &SS,
+ TypeSourceInfo *ScopeType,
+ SourceLocation CCLoc,
+ SourceLocation TildeLoc,
+ PseudoDestructorTypeStorage DestroyedType,
+ bool HasTrailingLParen);
+
+ virtual OwningExprResult ActOnPseudoDestructorExpr(Scope *S, ExprArg Base,
+ SourceLocation OpLoc,
+ tok::TokenKind OpKind,
+ const CXXScopeSpec &SS,
+ UnqualifiedId &FirstTypeName,
+ SourceLocation CCLoc,
+ SourceLocation TildeLoc,
+ UnqualifiedId &SecondTypeName,
+ bool HasTrailingLParen);
+
/// MaybeCreateCXXExprWithTemporaries - If the list of temporaries is
/// non-empty, will create a new CXXExprWithTemporaries expression.
/// Otherwise, just returs the passed in expression.
@@ -2195,7 +2272,11 @@ public:
bool isAcceptableNestedNameSpecifier(NamedDecl *SD);
NamedDecl *FindFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS);
-
+ virtual bool isNonTypeNestedNameSpecifier(Scope *S, const CXXScopeSpec &SS,
+ SourceLocation IdLoc,
+ IdentifierInfo &II,
+ TypeTy *ObjectType);
+
CXXScopeTy *BuildCXXNestedNameSpecifier(Scope *S,
const CXXScopeSpec &SS,
SourceLocation IdLoc,
@@ -3376,7 +3457,8 @@ public:
Decl *getInstantiationOf(const Decl *D) {
Decl *Result = LocalDecls[D];
- assert(Result && "declaration was not instantiated in this scope!");
+ assert((Result || D->isInvalidDecl()) &&
+ "declaration was not instantiated in this scope!");
return Result;
}
@@ -3395,7 +3477,7 @@ public:
void InstantiatedLocal(const Decl *D, Decl *Inst) {
Decl *&Stored = LocalDecls[D];
- assert(!Stored && "Already instantiated this local");
+ assert((!Stored || Stored == Inst) && "Already instantiated this local");
Stored = Inst;
}
};
@@ -3502,9 +3584,9 @@ public:
const CXXConstructorDecl *Tmpl,
const MultiLevelTemplateArgumentList &TemplateArgs);
- NamedDecl *FindInstantiatedDecl(NamedDecl *D,
+ NamedDecl *FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
const MultiLevelTemplateArgumentList &TemplateArgs);
- DeclContext *FindInstantiatedContext(DeclContext *DC,
+ DeclContext *FindInstantiatedContext(SourceLocation Loc, DeclContext *DC,
const MultiLevelTemplateArgumentList &TemplateArgs);
// Objective-C declarations.
@@ -3910,7 +3992,8 @@ public:
Expr *&cond, Expr *&lhs, Expr *&rhs, SourceLocation questionLoc);
QualType CXXCheckConditionalOperands( // C++ 5.16
Expr *&cond, Expr *&lhs, Expr *&rhs, SourceLocation questionLoc);
- QualType FindCompositePointerType(Expr *&E1, Expr *&E2); // C++ 5.9
+ QualType FindCompositePointerType(Expr *&E1, Expr *&E2,
+ bool *NonStandardCompositeType = 0);
QualType FindCompositeObjCPointerType(Expr *&LHS, Expr *&RHS,
SourceLocation questionLoc);
@@ -4129,7 +4212,7 @@ private:
CallExpr *TheCall);
bool SemaBuiltinVAStart(CallExpr *TheCall);
bool SemaBuiltinUnorderedCompare(CallExpr *TheCall);
- bool SemaBuiltinFPClassification(CallExpr *TheCall, unsigned LastArg=1);
+ bool SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs);
bool SemaBuiltinStackAddress(CallExpr *TheCall);
public:
OpenPOWER on IntegriCloud