summaryrefslogtreecommitdiff
path: root/lib/Sema/Sema.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/Sema.h')
-rw-r--r--lib/Sema/Sema.h1874
1 files changed, 1234 insertions, 640 deletions
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 7af80c0261e4d..80f366302171b 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -18,6 +18,7 @@
#include "IdentifierResolver.h"
#include "CXXFieldCollector.h"
#include "SemaOverload.h"
+#include "SemaTemplate.h"
#include "clang/AST/Attr.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/Decl.h"
@@ -41,6 +42,7 @@ namespace llvm {
namespace clang {
class ASTContext;
class ASTConsumer;
+ class CodeCompleteConsumer;
class Preprocessor;
class Decl;
class DeclContext;
@@ -50,6 +52,7 @@ namespace clang {
class Stmt;
class Expr;
class InitListExpr;
+ class ParenListExpr;
class DesignatedInitExpr;
class CallExpr;
class DeclRefExpr;
@@ -87,8 +90,7 @@ namespace clang {
class ObjCPropertyDecl;
class ObjCContainerDecl;
class FunctionProtoType;
- class BasePaths;
- struct MemberLookupCriteria;
+ class CXXBasePaths;
class CXXTemporary;
/// BlockSemaInfo - When a block is being parsed, this contains information
@@ -98,35 +100,69 @@ struct BlockSemaInfo {
bool hasPrototype;
bool isVariadic;
bool hasBlockDeclRefExprs;
-
+
BlockDecl *TheDecl;
-
+
/// TheScope - This is the scope for the block itself, which contains
/// arguments etc.
Scope *TheScope;
-
+
/// ReturnType - This will get set to block result type, by looking at
/// 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;
-
+
/// SavedFunctionNeedsScopeChecking - This is the value of
/// CurFunctionNeedsScopeChecking at the point when the block started.
bool SavedFunctionNeedsScopeChecking;
-
+
/// PrevBlockInfo - If this is nested inside another block, this points
/// to the outer block.
BlockSemaInfo *PrevBlockInfo;
};
+/// \brief Holds a QualType and a DeclaratorInfo* that came out of a declarator
+/// parsing.
+///
+/// LocInfoType is a "transient" type, only needed for passing to/from Parser
+/// and Sema, when we want to preserve type source info for a parsed type.
+/// It will not participate in the type system semantics in any way.
+class LocInfoType : public Type {
+ enum {
+ // The last number that can fit in Type's TC.
+ // Avoids conflict with an existing Type class.
+ LocInfo = (1 << TypeClassBitSize) - 1
+ };
+
+ DeclaratorInfo *DeclInfo;
+
+ LocInfoType(QualType ty, DeclaratorInfo *DInfo)
+ : Type((TypeClass)LocInfo, ty, ty->isDependentType()), DeclInfo(DInfo) {
+ assert(getTypeClass() == (TypeClass)LocInfo && "LocInfo didn't fit in TC?");
+ }
+ friend class Sema;
+
+public:
+ QualType getType() const { return getCanonicalTypeInternal(); }
+ DeclaratorInfo *getDeclaratorInfo() const { return DeclInfo; }
+
+ virtual void getAsStringInternal(std::string &Str,
+ const PrintingPolicy &Policy) const;
+
+ static bool classof(const Type *T) {
+ return T->getTypeClass() == (TypeClass)LocInfo;
+ }
+ static bool classof(const LocInfoType *) { return true; }
+};
+
/// Sema - This implements semantic analysis and AST building for C.
class Sema : public Action {
Sema(const Sema&); // DO NOT IMPLEMENT
@@ -142,6 +178,9 @@ public:
/// \brief Source of additional semantic information.
ExternalSemaSource *ExternalSource;
+ /// \brief Code-completion consumer.
+ CodeCompleteConsumer *CodeCompleter;
+
/// CurContext - This is the current declaration context of parsing.
DeclContext *CurContext;
@@ -165,13 +204,13 @@ public:
/// 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;
- /// ExprTemporaries - This is the stack of temporaries that are created by
+ /// ExprTemporaries - This is the stack of temporaries that are created by
/// the current full expression.
llvm::SmallVector<CXXTemporary*, 8> ExprTemporaries;
@@ -180,26 +219,22 @@ public:
/// 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.
llvm::SmallVector<TypedefDecl*, 24> ExtVectorDecls;
- /// ObjCCategoryImpls - Maintain a list of category implementations so
- /// we can check for duplicates and find local method declarations.
- llvm::SmallVector<ObjCCategoryImplDecl*, 8> ObjCCategoryImpls;
-
/// FieldCollector - Collects CXXFieldDecls during parsing of C++ classes.
llvm::OwningPtr<CXXFieldCollector> FieldCollector;
typedef llvm::SmallPtrSet<const CXXRecordDecl*, 8> RecordDeclSetTy;
-
- /// PureVirtualClassDiagSet - a set of class declarations which we have
+
+ /// PureVirtualClassDiagSet - a set of class declarations which we have
/// emitted a list of pure virtual functions. Used to prevent emitting the
/// same list more than once.
llvm::OwningPtr<RecordDeclSetTy> PureVirtualClassDiagSet;
-
+
/// \brief A mapping from external names to the most recent
/// locally-scoped external declaration with that name.
///
@@ -234,6 +269,37 @@ public:
/// declaration, and only the most recent tentative declaration for
/// a given variable will be recorded here.
llvm::DenseMap<DeclarationName, VarDecl *> TentativeDefinitions;
+ std::vector<DeclarationName> TentativeDefinitionList;
+
+ /// WeakUndeclaredIdentifiers - Identifiers contained in
+ /// #pragma weak before declared. rare. may alias another
+ /// identifier, declared or undeclared
+ class WeakInfo {
+ IdentifierInfo *alias; // alias (optional)
+ SourceLocation loc; // for diagnostics
+ bool used; // identifier later declared?
+ public:
+ WeakInfo()
+ : alias(0), loc(SourceLocation()), used(false) {}
+ WeakInfo(IdentifierInfo *Alias, SourceLocation Loc)
+ : alias(Alias), loc(Loc), used(false) {}
+ inline IdentifierInfo * getAlias() const { return alias; }
+ inline SourceLocation getLocation() const { return loc; }
+ void setUsed(bool Used=true) { used = Used; }
+ inline bool getUsed() { return used; }
+ bool operator==(WeakInfo RHS) const {
+ return alias == RHS.getAlias() && loc == RHS.getLocation();
+ }
+ bool operator!=(WeakInfo RHS) const { return !(*this == RHS); }
+ };
+ llvm::DenseMap<IdentifierInfo*,WeakInfo> WeakUndeclaredIdentifiers;
+
+ /// WeakTopLevelDecl - Translation-unit scoped declarations generated by
+ /// #pragma weak during processing of other Decls.
+ /// I couldn't figure out a clean way to generate these in-line, so
+ /// we store them here and handle separately -- which is a hack.
+ /// It would be best to refactor this.
+ llvm::SmallVector<Decl*,2> WeakTopLevelDecl;
IdentifierResolver IdResolver;
@@ -242,27 +308,30 @@ public:
/// For example, user-defined classes, built-in "id" type, etc.
Scope *TUScope;
- /// The C++ "std" namespace, where the standard library resides. Cached here
- /// by GetStdNamespace
+ /// \brief The C++ "std" namespace, where the standard library resides.
NamespaceDecl *StdNamespace;
+ /// \brief The C++ "std::bad_alloc" class, which is defined by the C++
+ /// standard library.
+ CXXRecordDecl *StdBadAlloc;
+
/// A flag to remember whether the implicit forms of operator new and delete
/// have been declared.
bool GlobalNewDeleteDeclared;
/// The current expression evaluation context.
ExpressionEvaluationContext ExprEvalContext;
-
- typedef std::vector<std::pair<SourceLocation, Decl *> >
+
+ typedef std::vector<std::pair<SourceLocation, Decl *> >
PotentiallyReferencedDecls;
-
+
/// A stack of declarations, each element of which is a set of declarations
/// that will be marked as referenced if the corresponding potentially
/// potentially evaluated expression is potentially evaluated. Each element
/// in the stack corresponds to a PotentiallyPotentiallyEvaluated expression
/// evaluation context.
std::list<PotentiallyReferencedDecls> PotentiallyReferencedDeclStack;
-
+
/// \brief Whether the code handled by Sema should be considered a
/// complete translation unit or not.
///
@@ -274,6 +343,8 @@ public:
/// unit.
bool CompleteTranslationUnit;
+ llvm::BumpPtrAllocator BumpAlloc;
+
/// \brief The number of SFINAE diagnostics that have been trapped.
unsigned NumSFINAEErrors;
@@ -281,11 +352,11 @@ public:
/// Instance/Factory Method Pools - allows efficient lookup when typechecking
/// messages to "id". We need to maintain a list, since selectors can have
- /// differing signatures across classes. In Cocoa, this happens to be
+ /// differing signatures across classes. In Cocoa, this happens to be
/// extremely uncommon (only 1% of selectors are "overloaded").
MethodPool InstanceMethodPool;
MethodPool FactoryMethodPool;
-
+
MethodPool::iterator ReadMethodPool(Selector Sel, bool isInstance);
/// Private Helper predicate to check for 'self'.
@@ -296,7 +367,7 @@ public:
~Sema() {
if (PackContext) FreePackedContext();
}
-
+
const LangOptions &getLangOptions() const { return LangOpts; }
Diagnostic &getDiagnostics() const { return Diags; }
SourceManager &getSourceManager() const { return SourceMgr; }
@@ -318,7 +389,7 @@ public:
SemaDiagnosticBuilder(DiagnosticBuilder &DB, Sema &SemaRef, unsigned DiagID)
: DiagnosticBuilder(DB), SemaRef(SemaRef), DiagID(DiagID) { }
- explicit SemaDiagnosticBuilder(Sema &SemaRef)
+ explicit SemaDiagnosticBuilder(Sema &SemaRef)
: DiagnosticBuilder(DiagnosticBuilder::Suppress), SemaRef(SemaRef) { }
~SemaDiagnosticBuilder();
@@ -331,6 +402,7 @@ public:
// deduction, and that error is one of the SFINAE errors,
// suppress the diagnostic.
++NumSFINAEErrors;
+ Diags.setLastDiagnosticIgnored();
return SemaDiagnosticBuilder(*this);
}
@@ -338,6 +410,9 @@ public:
return SemaDiagnosticBuilder(DB, *this, DiagID);
}
+ /// \brief Emit a partial diagnostic.
+ SemaDiagnosticBuilder Diag(SourceLocation Loc, const PartialDiagnostic& PD);
+
virtual void DeleteExpr(ExprTy *E);
virtual void DeleteStmt(StmtTy *S);
@@ -356,13 +431,16 @@ public:
llvm::DenseMap<IdentifierInfo*, LabelStmt*> &getLabelMap() {
return CurBlock ? CurBlock->LabelMap : FunctionLabelMap;
}
-
+
/// getSwitchStack - This is returns the switch stack for the current block or
/// function.
llvm::SmallVector<SwitchStmt*,8> &getSwitchStack() {
return CurBlock ? CurBlock->SwitchStack : FunctionSwitchStack;
}
-
+
+ /// WeakTopLevelDeclDecls - access to #pragma weak-generated Decls
+ llvm::SmallVector<Decl*,2> &WeakTopLevelDecls() { return WeakTopLevelDecl; }
+
virtual void ActOnComment(SourceRange Comment);
//===--------------------------------------------------------------------===//
@@ -370,34 +448,51 @@ public:
//
QualType adjustParameterType(QualType T);
QualType ConvertDeclSpecToType(const DeclSpec &DS, SourceLocation DeclLoc,
- bool &IsInvalid);
+ bool &IsInvalid, QualType &SourceTy);
void ProcessTypeAttributeList(QualType &Result, const AttributeList *AL);
- QualType BuildPointerType(QualType T, unsigned Quals,
+ QualType BuildPointerType(QualType T, unsigned Quals,
SourceLocation Loc, DeclarationName Entity);
QualType BuildReferenceType(QualType T, bool LValueRef, unsigned Quals,
SourceLocation Loc, DeclarationName Entity);
QualType BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM,
Expr *ArraySize, unsigned Quals,
- SourceLocation Loc, DeclarationName Entity);
- QualType BuildExtVectorType(QualType T, ExprArg ArraySize,
+ SourceRange Brackets, DeclarationName Entity);
+ QualType BuildExtVectorType(QualType T, ExprArg ArraySize,
SourceLocation AttrLoc);
QualType BuildFunctionType(QualType T,
QualType *ParamTypes, unsigned NumParamTypes,
bool Variadic, unsigned Quals,
SourceLocation Loc, DeclarationName Entity);
- QualType BuildMemberPointerType(QualType T, QualType Class,
- unsigned Quals, SourceLocation Loc,
+ QualType BuildMemberPointerType(QualType T, QualType Class,
+ unsigned Quals, SourceLocation Loc,
DeclarationName Entity);
QualType BuildBlockPointerType(QualType T, unsigned Quals,
SourceLocation Loc, DeclarationName Entity);
- QualType GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip = 0,
- TagDecl **OwnedDecl = 0);
+ QualType GetTypeForDeclarator(Declarator &D, Scope *S,
+ DeclaratorInfo **DInfo = 0,
+ unsigned Skip = 0, TagDecl **OwnedDecl = 0);
+ DeclaratorInfo *GetDeclaratorInfoForDeclarator(Declarator &D, QualType T,
+ unsigned Skip);
+ /// \brief Create a LocInfoType to hold the given QualType and DeclaratorInfo.
+ QualType CreateLocInfoType(QualType T, DeclaratorInfo *DInfo);
DeclarationName GetNameForDeclarator(Declarator &D);
+ static QualType GetTypeFromParser(TypeTy *Ty, DeclaratorInfo **DInfo = 0);
bool CheckSpecifiedExceptionType(QualType T, const SourceRange &Range);
bool CheckDistantExceptionSpec(QualType T);
bool CheckEquivalentExceptionSpec(
const FunctionProtoType *Old, SourceLocation OldLoc,
const FunctionProtoType *New, SourceLocation NewLoc);
+ bool CheckEquivalentExceptionSpec(
+ const PartialDiagnostic &DiagID, const PartialDiagnostic & NoteID,
+ const FunctionProtoType *Old, SourceLocation OldLoc,
+ const FunctionProtoType *New, SourceLocation NewLoc);
+ bool CheckExceptionSpecSubset(
+ const PartialDiagnostic &DiagID, const PartialDiagnostic & NoteID,
+ const FunctionProtoType *Superset, SourceLocation SuperLoc,
+ const FunctionProtoType *Subset, SourceLocation SubLoc);
+ bool CheckParamExceptionSpec(const PartialDiagnostic & NoteID,
+ const FunctionProtoType *Target, SourceLocation TargetLoc,
+ const FunctionProtoType *Source, SourceLocation SourceLoc);
QualType ObjCGetTypeForMethodDefinition(DeclPtrTy D);
@@ -405,72 +500,87 @@ public:
virtual TypeResult ActOnTypeName(Scope *S, Declarator &D);
- bool RequireCompleteType(SourceLocation Loc, QualType T, unsigned diag,
- SourceRange Range1 = SourceRange(),
- SourceRange Range2 = SourceRange(),
- QualType PrintType = QualType());
+ bool RequireCompleteType(SourceLocation Loc, QualType T,
+ const PartialDiagnostic &PD,
+ std::pair<SourceLocation,
+ PartialDiagnostic> Note =
+ std::make_pair(SourceLocation(), PDiag()));
QualType getQualifiedNameType(const CXXScopeSpec &SS, QualType T);
QualType BuildTypeofExprType(Expr *E);
QualType BuildDecltypeType(Expr *E);
-
+
//===--------------------------------------------------------------------===//
// Symbol table / Decl tracking callbacks: SemaDecl.cpp.
//
/// getDeclName - Return a pretty name for the specified decl if possible, or
- /// an empty string if not. This is used for pretty crash reporting.
+ /// an empty string if not. This is used for pretty crash reporting.
virtual std::string getDeclName(DeclPtrTy D);
-
+
DeclGroupPtrTy ConvertDeclToDeclGroup(DeclPtrTy Ptr);
- virtual TypeTy *getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
- Scope *S, const CXXScopeSpec *SS);
+ virtual TypeTy *getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
+ Scope *S, const CXXScopeSpec *SS,
+ bool isClassName = false);
virtual DeclSpec::TST isTagName(IdentifierInfo &II, Scope *S);
+ virtual bool DiagnoseUnknownTypeName(const IdentifierInfo &II,
+ SourceLocation IILoc,
+ Scope *S,
+ const CXXScopeSpec *SS,
+ TypeTy *&SuggestedType);
virtual DeclPtrTy ActOnDeclarator(Scope *S, Declarator &D) {
return HandleDeclarator(S, D, MultiTemplateParamsArg(*this), false);
}
-
- DeclPtrTy HandleDeclarator(Scope *S, Declarator &D,
+
+ DeclPtrTy HandleDeclarator(Scope *S, Declarator &D,
MultiTemplateParamsArg TemplateParameterLists,
bool IsFunctionDefinition);
void RegisterLocallyScopedExternCDecl(NamedDecl *ND, NamedDecl *PrevDecl,
Scope *S);
void DiagnoseFunctionSpecifiers(Declarator& D);
NamedDecl* ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
- QualType R, Decl* PrevDecl,
- bool &Redeclaration);
+ QualType R, DeclaratorInfo *DInfo,
+ NamedDecl* PrevDecl, bool &Redeclaration);
NamedDecl* ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
- QualType R, NamedDecl* PrevDecl,
+ QualType R, DeclaratorInfo *DInfo,
+ NamedDecl* PrevDecl,
+ MultiTemplateParamsArg TemplateParamLists,
bool &Redeclaration);
void CheckVariableDeclaration(VarDecl *NewVD, NamedDecl *PrevDecl,
bool &Redeclaration);
NamedDecl* ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
- QualType R, NamedDecl* PrevDecl,
+ QualType R, DeclaratorInfo *DInfo,
+ NamedDecl* PrevDecl,
MultiTemplateParamsArg TemplateParamLists,
bool IsFunctionDefinition,
bool &Redeclaration);
void CheckFunctionDeclaration(FunctionDecl *NewFD, NamedDecl *&PrevDecl,
- bool &Redeclaration,
+ bool IsExplicitSpecialization,
+ bool &Redeclaration,
bool &OverloadableAttrRequired);
+ void CheckMain(FunctionDecl *FD);
virtual DeclPtrTy ActOnParamDeclarator(Scope *S, Declarator &D);
virtual void ActOnParamDefaultArgument(DeclPtrTy param,
SourceLocation EqualLoc,
ExprArg defarg);
- virtual void ActOnParamUnparsedDefaultArgument(DeclPtrTy param,
+ virtual void ActOnParamUnparsedDefaultArgument(DeclPtrTy param,
SourceLocation EqualLoc,
SourceLocation ArgLoc);
virtual void ActOnParamDefaultArgumentError(DeclPtrTy param);
-
+ bool SetParamDefaultArgument(ParmVarDecl *Param, ExprArg DefaultArg,
+ SourceLocation EqualLoc);
+
+
// Contains the locations of the beginning of unparsed default
// argument locations.
llvm::DenseMap<ParmVarDecl *,SourceLocation> UnparsedDefaultArgLocs;
- virtual void AddInitializerToDecl(DeclPtrTy dcl, FullExprArg init);
+ virtual void AddInitializerToDecl(DeclPtrTy dcl, ExprArg init);
void AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit);
- void ActOnUninitializedDecl(DeclPtrTy dcl);
+ void ActOnUninitializedDecl(DeclPtrTy dcl, bool TypeContainsUndeducedAuto);
virtual void SetDeclDeleted(DeclPtrTy dcl, SourceLocation DelLoc);
virtual DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
DeclPtrTy *Group,
@@ -484,19 +594,19 @@ public:
virtual DeclPtrTy ActOnFinishFunctionBody(DeclPtrTy Decl, StmtArg Body);
DeclPtrTy ActOnFinishFunctionBody(DeclPtrTy Decl, StmtArg Body,
bool IsInstantiation);
-
+
/// \brief Diagnose any unused parameters in the given sequence of
/// ParmVarDecl pointers.
template<typename InputIterator>
void DiagnoseUnusedParameters(InputIterator Param, InputIterator ParamEnd) {
for (; Param != ParamEnd; ++Param) {
- if (!(*Param)->isUsed() && (*Param)->getDeclName() &&
+ if (!(*Param)->isUsed() && (*Param)->getDeclName() &&
!(*Param)->template hasAttr<UnusedAttr>())
Diag((*Param)->getLocation(), diag::warn_unused_parameter)
<< (*Param)->getDeclName();
}
}
-
+
void DiagnoseInvalidJumps(Stmt *Body);
virtual DeclPtrTy ActOnFileScopeAsmDecl(SourceLocation Loc, ExprArg expr);
@@ -507,23 +617,32 @@ public:
/// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
/// no declarator (e.g. "struct foo;") is parsed.
virtual DeclPtrTy ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS);
-
+
bool InjectAnonymousStructOrUnionMembers(Scope *S, DeclContext *Owner,
RecordDecl *AnonRecord);
- virtual DeclPtrTy BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
+ virtual DeclPtrTy BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
RecordDecl *Record);
- bool isAcceptableTagRedeclaration(const TagDecl *Previous,
+ bool isAcceptableTagRedeclaration(const TagDecl *Previous,
TagDecl::TagKind NewTag,
SourceLocation NewTagLoc,
const IdentifierInfo &Name);
- virtual DeclPtrTy ActOnTag(Scope *S, unsigned TagSpec, TagKind TK,
+ virtual DeclPtrTy ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
SourceLocation KWLoc, const CXXScopeSpec &SS,
IdentifierInfo *Name, SourceLocation NameLoc,
AttributeList *Attr, AccessSpecifier AS,
- bool &OwnedDecl);
-
+ MultiTemplateParamsArg TemplateParameterLists,
+ bool &OwnedDecl, bool &IsDependent);
+
+ virtual TypeResult ActOnDependentTag(Scope *S,
+ unsigned TagSpec,
+ TagUseKind TUK,
+ const CXXScopeSpec &SS,
+ IdentifierInfo *Name,
+ SourceLocation TagLoc,
+ SourceLocation NameLoc);
+
virtual void ActOnDefs(Scope *S, DeclPtrTy TagD, SourceLocation DeclStart,
IdentifierInfo *ClassName,
llvm::SmallVectorImpl<DeclPtrTy> &Decls);
@@ -535,12 +654,22 @@ public:
Declarator &D, Expr *BitfieldWidth,
AccessSpecifier AS);
- FieldDecl *CheckFieldDecl(DeclarationName Name, QualType T,
+ FieldDecl *CheckFieldDecl(DeclarationName Name, QualType T,
+ DeclaratorInfo *DInfo,
RecordDecl *Record, SourceLocation Loc,
bool Mutable, Expr *BitfieldWidth,
+ SourceLocation TSSL,
AccessSpecifier AS, NamedDecl *PrevDecl,
Declarator *D = 0);
-
+
+ enum CXXSpecialMember {
+ CXXDefaultConstructor = 0,
+ CXXCopyConstructor = 1,
+ CXXCopyAssignment = 2,
+ CXXDestructor = 3
+ };
+ void DiagnoseNontrivial(const RecordType* Record, CXXSpecialMember mem);
+
virtual DeclPtrTy ActOnIvar(Scope *S, SourceLocation DeclStart,
DeclPtrTy IntfDecl,
Declarator &D, ExprTy *BitfieldWidth,
@@ -560,7 +689,8 @@ public:
/// ActOnTagFinishDefinition - Invoked once we have finished parsing
/// the definition of a tag (enumeration, class, struct, or union).
- virtual void ActOnTagFinishDefinition(Scope *S, DeclPtrTy TagDecl);
+ virtual void ActOnTagFinishDefinition(Scope *S, DeclPtrTy TagDecl,
+ SourceLocation RBraceLoc);
EnumConstantDecl *CheckEnumConstant(EnumDecl *Enum,
EnumConstantDecl *LastEnumConst,
@@ -574,25 +704,27 @@ public:
SourceLocation EqualLoc, ExprTy *Val);
virtual void ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
SourceLocation RBraceLoc, DeclPtrTy EnumDecl,
- DeclPtrTy *Elements, unsigned NumElements);
+ DeclPtrTy *Elements, unsigned NumElements,
+ Scope *S, AttributeList *Attr);
DeclContext *getContainingDC(DeclContext *DC);
/// Set the current declaration context until it gets popped.
void PushDeclContext(Scope *S, DeclContext *DC);
void PopDeclContext();
-
+
/// EnterDeclaratorContext - Used when we must lookup names in the context
/// of a declarator's nested name specifier.
void EnterDeclaratorContext(Scope *S, DeclContext *DC);
void ExitDeclaratorContext(Scope *S);
-
-
+
+ DeclContext *getFunctionLevelDeclContext();
+
/// 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 *getCurFunctionDecl();
-
+
/// getCurMethodDecl - If inside of a method body, this returns a pointer to
/// the method decl for the method being parsed. If we're currently
/// in a 'block', this returns the containing context.
@@ -604,15 +736,35 @@ public:
NamedDecl *getCurFunctionOrMethodDecl();
/// Add this decl to the scope shadowed decl chains.
- void PushOnScopeChains(NamedDecl *D, Scope *S);
+ void PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext = true);
/// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true
/// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
/// true if 'D' belongs to the given declaration context.
- bool isDeclInScope(Decl *D, DeclContext *Ctx, Scope *S = 0) {
- return IdResolver.isDeclInScope(D, Ctx, Context, S);
+ bool isDeclInScope(NamedDecl *&D, DeclContext *Ctx, Scope *S = 0);
+
+ /// Finds the scope corresponding to the given decl context, if it
+ /// happens to be an enclosing scope. Otherwise return NULL.
+ Scope *getScopeForDeclContext(Scope *S, DeclContext *DC) {
+ DeclContext *TargetDC = DC->getPrimaryContext();
+ do {
+ if (DeclContext *ScopeDC = (DeclContext*) S->getEntity())
+ if (ScopeDC->getPrimaryContext() == TargetDC)
+ return S;
+ } while ((S = S->getParent()));
+
+ return NULL;
}
+ /// OverloadingResult - Capture the result of performing overload
+ /// resolution.
+ enum OverloadingResult {
+ OR_Success, ///< Overload resolution succeeded.
+ OR_No_Viable_Function, ///< No viable function found.
+ OR_Ambiguous, ///< Ambiguous candidates found.
+ OR_Deleted ///< Overload resoltuion refers to a deleted function.
+ };
+
/// Subroutines of ActOnDeclarator().
TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, QualType T);
@@ -623,41 +775,52 @@ public:
bool MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old);
/// C++ Overloading.
- bool IsOverload(FunctionDecl *New, Decl* OldD,
+ bool IsOverload(FunctionDecl *New, Decl* OldD,
OverloadedFunctionDecl::function_iterator &MatchedDecl);
- ImplicitConversionSequence
+ ImplicitConversionSequence
TryImplicitConversion(Expr* From, QualType ToType,
- bool SuppressUserConversions = false,
- bool AllowExplicit = false,
- bool ForceRValue = false);
- bool IsStandardConversion(Expr *From, QualType ToType,
+ bool SuppressUserConversions,
+ bool AllowExplicit,
+ bool ForceRValue,
+ bool InOverloadResolution,
+ bool UserCast = false);
+ bool IsStandardConversion(Expr *From, QualType ToType,
+ bool InOverloadResolution,
StandardConversionSequence& SCS);
bool IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType);
bool IsFloatingPointPromotion(QualType FromType, QualType ToType);
bool IsComplexPromotion(QualType FromType, QualType ToType);
bool IsPointerConversion(Expr *From, QualType FromType, QualType ToType,
+ bool InOverloadResolution,
QualType& ConvertedType, bool &IncompatibleObjC);
bool isObjCPointerConversion(QualType FromType, QualType ToType,
QualType& ConvertedType, bool &IncompatibleObjC);
- bool CheckPointerConversion(Expr *From, QualType ToType);
+ bool CheckPointerConversion(Expr *From, QualType ToType,
+ CastExpr::CastKind &Kind);
bool IsMemberPointerConversion(Expr *From, QualType FromType, QualType ToType,
+ bool InOverloadResolution,
QualType &ConvertedType);
- bool CheckMemberPointerConversion(Expr *From, QualType ToType);
+ bool CheckMemberPointerConversion(Expr *From, QualType ToType,
+ CastExpr::CastKind &Kind);
bool IsQualificationConversion(QualType FromType, QualType ToType);
- bool IsUserDefinedConversion(Expr *From, QualType ToType,
+ OverloadingResult IsUserDefinedConversion(Expr *From, QualType ToType,
UserDefinedConversionSequence& User,
+ OverloadCandidateSet& Conversions,
bool AllowConversionFunctions,
- bool AllowExplicit, bool ForceRValue);
+ bool AllowExplicit, bool ForceRValue,
+ bool UserCast = false);
+ bool DiagnoseAmbiguousUserDefinedConversion(Expr *From, QualType ToType);
+
- ImplicitConversionSequence::CompareKind
+ ImplicitConversionSequence::CompareKind
CompareImplicitConversionSequences(const ImplicitConversionSequence& ICS1,
const ImplicitConversionSequence& ICS2);
- ImplicitConversionSequence::CompareKind
+ ImplicitConversionSequence::CompareKind
CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
const StandardConversionSequence& SCS2);
- ImplicitConversionSequence::CompareKind
+ ImplicitConversionSequence::CompareKind
CompareQualificationConversions(const StandardConversionSequence& SCS1,
const StandardConversionSequence& SCS2);
@@ -665,11 +828,11 @@ public:
CompareDerivedToBaseConversions(const StandardConversionSequence& SCS1,
const StandardConversionSequence& SCS2);
- ImplicitConversionSequence
+ ImplicitConversionSequence
TryCopyInitialization(Expr* From, QualType ToType,
- bool SuppressUserConversions = false,
- bool ForceRValue = false);
- bool PerformCopyInitialization(Expr *&From, QualType ToType,
+ bool SuppressUserConversions, bool ForceRValue,
+ bool InOverloadResolution);
+ bool PerformCopyInitialization(Expr *&From, QualType ToType,
const char *Flavor, bool Elidable = false);
ImplicitConversionSequence
@@ -679,24 +842,21 @@ public:
ImplicitConversionSequence TryContextuallyConvertToBool(Expr *From);
bool PerformContextuallyConvertToBool(Expr *&From);
- /// OverloadingResult - Capture the result of performing overload
- /// resolution.
- enum OverloadingResult {
- OR_Success, ///< Overload resolution succeeded.
- OR_No_Viable_Function, ///< No viable function found.
- OR_Ambiguous, ///< Ambiguous candidates found.
- OR_Deleted ///< Overload resoltuion refers to a deleted function.
- };
+ bool PerformObjectMemberConversion(Expr *&From, NamedDecl *Member);
+
+ // Members have to be NamespaceDecl* or TranslationUnitDecl*.
+ // TODO: make this is a typesafe union.
+ typedef llvm::SmallPtrSet<DeclContext *, 16> AssociatedNamespaceSet;
typedef llvm::SmallPtrSet<AnyFunctionDecl, 16> FunctionSet;
- typedef llvm::SmallPtrSet<NamespaceDecl *, 16> AssociatedNamespaceSet;
typedef llvm::SmallPtrSet<CXXRecordDecl *, 16> AssociatedClassSet;
- void AddOverloadCandidate(FunctionDecl *Function,
+ void AddOverloadCandidate(FunctionDecl *Function,
Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet,
bool SuppressUserConversions = false,
- bool ForceRValue = false);
+ bool ForceRValue = false,
+ bool PartialOverloading = false);
void AddFunctionCandidates(const FunctionSet &Functions,
Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet,
@@ -706,6 +866,14 @@ public:
OverloadCandidateSet& CandidateSet,
bool SuppressUserConversions = false,
bool ForceRValue = false);
+ void AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,
+ bool HasExplicitTemplateArgs,
+ const TemplateArgument *ExplicitTemplateArgs,
+ unsigned NumExplicitTemplateArgs,
+ Expr *Object, Expr **Args, unsigned NumArgs,
+ OverloadCandidateSet& CandidateSet,
+ bool SuppressUserConversions = false,
+ bool ForceRValue = false);
void AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
bool HasExplicitTemplateArgs,
const TemplateArgument *ExplicitTemplateArgs,
@@ -717,6 +885,9 @@ public:
void AddConversionCandidate(CXXConversionDecl *Conversion,
Expr *From, QualType ToType,
OverloadCandidateSet& CandidateSet);
+ void AddTemplateConversionCandidate(FunctionTemplateDecl *FunctionTemplate,
+ Expr *From, QualType ToType,
+ OverloadCandidateSet &CandidateSet);
void AddSurrogateCandidate(CXXConversionDecl *Conversion,
const FunctionProtoType *Proto,
Expr *Object, Expr **Args, unsigned NumArgs,
@@ -731,29 +902,45 @@ public:
Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet,
SourceRange OpRange = SourceRange());
- void AddBuiltinCandidate(QualType ResultTy, QualType *ParamTys,
+ void AddBuiltinCandidate(QualType ResultTy, QualType *ParamTys,
Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet,
bool IsAssignmentOperator = false,
unsigned NumContextualBoolArguments = 0);
- void AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
- Expr **Args, unsigned NumArgs,
+ void AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
+ Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet);
void AddArgumentDependentLookupCandidates(DeclarationName Name,
Expr **Args, unsigned NumArgs,
- OverloadCandidateSet& CandidateSet);
+ bool HasExplicitTemplateArgs,
+ const TemplateArgument *ExplicitTemplateArgs,
+ unsigned NumExplicitTemplateArgs,
+ OverloadCandidateSet& CandidateSet,
+ bool PartialOverloading = false);
bool isBetterOverloadCandidate(const OverloadCandidate& Cand1,
const OverloadCandidate& Cand2);
OverloadingResult BestViableFunction(OverloadCandidateSet& CandidateSet,
SourceLocation Loc,
OverloadCandidateSet::iterator& Best);
void PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
- bool OnlyViable);
-
+ bool OnlyViable,
+ const char *Opc=0,
+ SourceLocation Loc=SourceLocation());
+
FunctionDecl *ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
bool Complain);
void FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn);
+ void AddOverloadedCallCandidates(NamedDecl *Callee,
+ DeclarationName &UnqualifiedName,
+ bool &ArgumentDependentLookup,
+ bool HasExplicitTemplateArgs,
+ const TemplateArgument *ExplicitTemplateArgs,
+ unsigned NumExplicitTemplateArgs,
+ Expr **Args, unsigned NumArgs,
+ OverloadCandidateSet &CandidateSet,
+ bool PartialOverloading = false);
+
FunctionDecl *ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee,
DeclarationName UnqualifiedName,
bool HasExplicitTemplateArgs,
@@ -761,7 +948,7 @@ public:
unsigned NumExplicitTemplateArgs,
SourceLocation LParenLoc,
Expr **Args, unsigned NumArgs,
- SourceLocation *CommaLocs,
+ SourceLocation *CommaLocs,
SourceLocation RParenLoc,
bool &ArgumentDependentLookup);
@@ -777,23 +964,33 @@ public:
ExprResult
BuildCallToMemberFunction(Scope *S, Expr *MemExpr,
- SourceLocation LParenLoc, Expr **Args,
+ SourceLocation LParenLoc, Expr **Args,
unsigned NumArgs, SourceLocation *CommaLocs,
SourceLocation RParenLoc);
- ExprResult
+ ExprResult
BuildCallToObjectOfClassType(Scope *S, Expr *Object, SourceLocation LParenLoc,
Expr **Args, unsigned NumArgs,
- SourceLocation *CommaLocs,
+ SourceLocation *CommaLocs,
SourceLocation RParenLoc);
- ExprResult BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc,
- SourceLocation MemberLoc,
- IdentifierInfo &Member);
-
- /// Helpers for dealing with function parameters.
+ OwningExprResult BuildOverloadedArrowExpr(Scope *S, ExprArg Base,
+ SourceLocation OpLoc);
+
+ /// CheckCallReturnType - Checks that a call expression's return type is
+ /// complete. Returns true on failure. The location passed in is the location
+ /// that best represents the call.
+ bool CheckCallReturnType(QualType ReturnType, SourceLocation Loc,
+ CallExpr *CE, FunctionDecl *FD);
+
+ /// Helpers for dealing with blocks and functions.
+ void CheckFallThroughForFunctionDef(Decl *D, Stmt *Body);
+ void CheckFallThroughForBlock(QualType BlockTy, Stmt *Body);
bool CheckParmsForFunctionDef(FunctionDecl *FD);
void CheckCXXDefaultArguments(FunctionDecl *FD);
void CheckExtraCXXDefaultArguments(Declarator &D);
+ enum ControlFlowKind { NeverFallThrough = 0, MaybeFallThrough = 1,
+ AlwaysFallThrough = 2 };
+ ControlFlowKind CheckFallThrough(Stmt *);
Scope *getNonFieldDeclScope(Scope *S);
@@ -804,7 +1001,7 @@ public:
/// overloaded operator names, constructor names, etc.) into zero or
/// more declarations within a particular scope. The major entry
/// points are LookupName, which performs unqualified name lookup,
- /// and LookupQualifiedName, which performs qualified name lookup.
+ /// and LookupQualifiedName, which performs qualified name lookup.
///
/// All name lookup is performed based on some specific criteria,
/// which specify what names will be visible to name lookup and how
@@ -851,7 +1048,7 @@ public:
LookupNamespaceName,
/// Look up an ordinary name that is going to be redeclared as a
/// name with linkage. This lookup ignores any declarations that
- /// are outside of the current scope unless they have linkage. See
+ /// are outside of the current scope unless they have linkage. See
/// C99 6.2.2p4-5 and C++ [basic.link]p6.
LookupRedeclarationWithLinkage,
/// Look up the name of an Objective-C protocol.
@@ -868,66 +1065,16 @@ public:
/// single name lookup, which can return no result (nothing found),
/// a single declaration, a set of overloaded functions, or an
/// ambiguity. Use the getKind() method to determine which of these
- /// results occurred for a given lookup.
+ /// results occurred for a given lookup.
///
/// Any non-ambiguous lookup can be converted into a single
- /// (possibly NULL) @c NamedDecl* via a conversion function or the
- /// getAsDecl() method. This conversion permits the common-case
- /// usage in C and Objective-C where name lookup will always return
- /// a single declaration.
- struct LookupResult {
- /// The kind of entity that is actually stored within the
- /// LookupResult object.
- enum {
- /// First is a single declaration (a NamedDecl*), which may be NULL.
- SingleDecl,
-
- /// First is a single declaration (an OverloadedFunctionDecl*).
- OverloadedDeclSingleDecl,
-
- /// [First, Last) is an iterator range represented as opaque
- /// pointers used to reconstruct IdentifierResolver::iterators.
- OverloadedDeclFromIdResolver,
-
- /// [First, Last) is an iterator range represented as opaque
- /// pointers used to reconstruct DeclContext::lookup_iterators.
- OverloadedDeclFromDeclContext,
-
- /// First is a pointer to a BasePaths structure, which is owned
- /// by the LookupResult. Last is non-zero to indicate that the
- /// ambiguity is caused by two names found in base class
- /// subobjects of different types.
- AmbiguousLookupStoresBasePaths,
-
- /// [First, Last) is an iterator range represented as opaque
- /// pointers used to reconstruct new'ed Decl*[] array containing
- /// found ambiguous decls. LookupResult is owner of this array.
- AmbiguousLookupStoresDecls
- } StoredKind;
-
- /// The first lookup result, whose contents depend on the kind of
- /// lookup result. This may be a NamedDecl* (if StoredKind ==
- /// SingleDecl), OverloadedFunctionDecl* (if StoredKind ==
- /// OverloadedDeclSingleDecl), the opaque pointer from an
- /// IdentifierResolver::iterator (if StoredKind ==
- /// OverloadedDeclFromIdResolver), a DeclContext::lookup_iterator
- /// (if StoredKind == OverloadedDeclFromDeclContext), or a
- /// BasePaths pointer (if StoredKind == AmbiguousLookupStoresBasePaths).
- mutable uintptr_t First;
-
- /// The last lookup result, whose contents depend on the kind of
- /// lookup result. This may be unused (if StoredKind ==
- /// SingleDecl), it may have the same type as First (for
- /// overloaded function declarations), or is may be used as a
- /// Boolean value (if StoredKind == AmbiguousLookupStoresBasePaths).
- mutable uintptr_t Last;
-
- /// Context - The context in which we will build any
- /// OverloadedFunctionDecl nodes needed by the conversion to
- /// Decl*.
- ASTContext *Context;
-
- /// @brief The kind of entity found by name lookup.
+ /// (possibly NULL) @c NamedDecl* via the getAsSingleDecl() method.
+ /// This permits the common-case usage in C and Objective-C where
+ /// name lookup will always return a single declaration. Use of
+ /// this is largely deprecated; callers should handle the possibility
+ /// of multiple declarations.
+ class LookupResult {
+ public:
enum LookupKind {
/// @brief No entity found met the criteria.
NotFound = 0,
@@ -941,6 +1088,13 @@ public:
/// functions into an OverloadedFunctionDecl.
FoundOverloaded,
+ /// @brief Name lookup results in an ambiguity; use
+ /// getAmbiguityKind to figure out what kind of ambiguity
+ /// we have.
+ Ambiguous
+ };
+
+ enum AmbiguityKind {
/// Name lookup results in an ambiguity because multiple
/// entities that meet the lookup criteria were found in
/// subobjects of different types. For example:
@@ -948,7 +1102,7 @@ public:
/// struct A { void f(int); }
/// struct B { void f(double); }
/// struct C : A, B { };
- /// void test(C c) {
+ /// void test(C c) {
/// c.f(0); // error: A::f and B::f come from subobjects of different
/// // types. overload resolution is not performed.
/// }
@@ -982,125 +1136,178 @@ public:
/// }
/// }
/// @endcode
- AmbiguousReference
+ AmbiguousReference,
+
+ /// Name lookup results in an ambiguity because an entity with a
+ /// tag name was hidden by an entity with an ordinary name from
+ /// a different context.
+ /// @code
+ /// namespace A { struct Foo {}; }
+ /// namespace B { void Foo(); }
+ /// namespace C {
+ /// using namespace A;
+ /// using namespace B;
+ /// }
+ /// void test() {
+ /// C::Foo(); // error: tag 'A::Foo' is hidden by an object in a
+ /// // different namespace
+ /// }
+ /// @endcode
+ AmbiguousTagHiding
};
- static LookupResult CreateLookupResult(ASTContext &Context, NamedDecl *D);
+ typedef llvm::SmallVector<NamedDecl*, 4> DeclsTy;
+ typedef DeclsTy::const_iterator iterator;
- static LookupResult CreateLookupResult(ASTContext &Context,
- IdentifierResolver::iterator F,
- IdentifierResolver::iterator L);
+ LookupResult()
+ : Kind(NotFound),
+ Paths(0)
+ {}
+ ~LookupResult() {
+ if (Paths) deletePaths(Paths);
+ }
- static LookupResult CreateLookupResult(ASTContext &Context,
- DeclContext::lookup_iterator F,
- DeclContext::lookup_iterator L);
+ bool isAmbiguous() const {
+ return getKind() == Ambiguous;
+ }
- static LookupResult CreateLookupResult(ASTContext &Context, BasePaths *Paths,
- bool DifferentSubobjectTypes) {
- LookupResult Result;
- Result.StoredKind = AmbiguousLookupStoresBasePaths;
- Result.First = reinterpret_cast<uintptr_t>(Paths);
- Result.Last = DifferentSubobjectTypes? 1 : 0;
- Result.Context = &Context;
- return Result;
+ LookupKind getKind() const {
+ sanity();
+ return Kind;
}
- template <typename Iterator>
- static LookupResult CreateLookupResult(ASTContext &Context,
- Iterator B, std::size_t Len) {
- NamedDecl ** Array = new NamedDecl*[Len];
- for (std::size_t Idx = 0; Idx < Len; ++Idx, ++B)
- Array[Idx] = *B;
- LookupResult Result;
- Result.StoredKind = AmbiguousLookupStoresDecls;
- Result.First = reinterpret_cast<uintptr_t>(Array);
- Result.Last = reinterpret_cast<uintptr_t>(Array + Len);
- Result.Context = &Context;
- return Result;
+ AmbiguityKind getAmbiguityKind() const {
+ assert(isAmbiguous());
+ return Ambiguity;
}
- LookupKind getKind() const;
+ iterator begin() const { return Decls.begin(); }
+ iterator end() const { return Decls.end(); }
- /// @brief Determine whether name look found something.
- operator bool() const { return getKind() != NotFound; }
+ /// \brief Return true if no decls were found
+ bool empty() const { return Decls.empty(); }
- /// @brief Determines whether the lookup resulted in an ambiguity.
- bool isAmbiguous() const {
- return StoredKind == AmbiguousLookupStoresBasePaths ||
- StoredKind == AmbiguousLookupStoresDecls;
+ /// \brief Return the base paths structure that's associated with
+ /// these results, or null if none is.
+ CXXBasePaths *getBasePaths() const {
+ return Paths;
}
- /// @brief Allows conversion of a lookup result into a
- /// declaration, with the same behavior as getAsDecl.
- operator NamedDecl*() const { return getAsDecl(); }
+ /// \brief Add a declaration to these results.
+ void addDecl(NamedDecl *D) {
+ Decls.push_back(D->getUnderlyingDecl());
+ Kind = Found;
+ }
- NamedDecl* getAsDecl() const;
+ /// \brief Add all the declarations from another set of lookup
+ /// results.
+ void addAllDecls(const LookupResult &Other) {
+ Decls.append(Other.begin(), Other.end());
+ Kind = Found;
+ }
- BasePaths *getBasePaths() const;
+ /// \brief Hides a set of declarations.
+ template <class NamedDeclSet> void hideDecls(const NamedDeclSet &Set) {
+ unsigned I = 0, N = Decls.size();
+ while (I < N) {
+ if (Set.count(Decls[I]))
+ Decls[I] = Decls[--N];
+ else
+ I++;
+ }
+ Decls.set_size(N);
+ }
- /// \brief Iterate over the results of name lookup.
+ /// \brief Resolves the kind of the lookup, possibly hiding decls.
///
- /// The @c iterator class provides iteration over the results of a
- /// non-ambiguous name lookup.
- class iterator {
- /// The LookupResult structure we're iterating through.
- LookupResult *Result;
+ /// This should be called in any environment where lookup might
+ /// generate multiple lookup results.
+ void resolveKind();
- /// The current position of this iterator within the sequence of
- /// results. This value will have the same representation as the
- /// @c First field in the LookupResult structure.
- mutable uintptr_t Current;
-
- public:
- typedef NamedDecl * value_type;
- typedef NamedDecl * reference;
- typedef NamedDecl * pointer;
- typedef std::ptrdiff_t difference_type;
- typedef std::forward_iterator_tag iterator_category;
+ /// \brief Fetch this as an unambiguous single declaration
+ /// (possibly an overloaded one).
+ ///
+ /// This is deprecated; users should be written to handle
+ /// ambiguous and overloaded lookups.
+ NamedDecl *getAsSingleDecl(ASTContext &Context) const;
- iterator() : Result(0), Current(0) { }
+ /// \brief Fetch the unique decl found by this lookup. Asserts
+ /// that one was found.
+ ///
+ /// This is intended for users who have examined the result kind
+ /// and are certain that there is only one result.
+ NamedDecl *getFoundDecl() const {
+ assert(getKind() == Found && "getFoundDecl called on non-unique result");
+ return *Decls.begin();
+ }
- iterator(LookupResult *Res, uintptr_t Cur) : Result(Res), Current(Cur) { }
+ /// \brief Asks if the result is a single tag decl.
+ bool isSingleTagDecl() const {
+ return getKind() == Found && isa<TagDecl>(getFoundDecl());
+ }
- reference operator*() const;
+ /// \brief Make these results show that the name was found in
+ /// base classes of different types.
+ ///
+ /// The given paths object is copied and invalidated.
+ void setAmbiguousBaseSubobjectTypes(CXXBasePaths &P);
- pointer operator->() const { return **this; }
+ /// \brief Make these results show that the name was found in
+ /// distinct base classes of the same type.
+ ///
+ /// The given paths object is copied and invalidated.
+ void setAmbiguousBaseSubobjects(CXXBasePaths &P);
+
+ /// \brief Make these results show that the name was found in
+ /// different contexts and a tag decl was hidden by an ordinary
+ /// decl in a different context.
+ void setAmbiguousQualifiedTagHiding() {
+ setAmbiguous(AmbiguousTagHiding);
+ }
- iterator &operator++();
+ /// \brief Clears out any current state.
+ void clear() {
+ Kind = NotFound;
+ Decls.clear();
+ if (Paths) deletePaths(Paths);
+ Paths = NULL;
+ }
- iterator operator++(int) {
- iterator tmp(*this);
- ++(*this);
- return tmp;
- }
+ void print(llvm::raw_ostream &);
- friend inline bool operator==(iterator const& x, iterator const& y) {
- return x.Current == y.Current;
- }
+ private:
+ void setAmbiguous(AmbiguityKind AK) {
+ Kind = Ambiguous;
+ Ambiguity = AK;
+ }
- friend inline bool operator!=(iterator const& x, iterator const& y) {
- return x.Current != y.Current;
- }
- };
- friend class iterator;
+ void addDeclsFromBasePaths(const CXXBasePaths &P);
+
+ // Sanity checks.
+ void sanity() const {
+ assert(Kind != NotFound || Decls.size() == 0);
+ assert(Kind != Found || Decls.size() == 1);
+ assert(Kind == NotFound || Kind == Found ||
+ (Kind == Ambiguous && Ambiguity == AmbiguousBaseSubobjects)
+ || Decls.size() > 1);
+ assert((Paths != NULL) == (Kind == Ambiguous &&
+ (Ambiguity == AmbiguousBaseSubobjectTypes ||
+ Ambiguity == AmbiguousBaseSubobjects)));
+ }
- iterator begin();
- iterator end();
+ static void deletePaths(CXXBasePaths *);
- /// \brief Free the memory associated with this lookup.
- void Destroy();
+ LookupKind Kind;
+ AmbiguityKind Ambiguity; // ill-defined unless ambiguous
+ DeclsTy Decls;
+ CXXBasePaths *Paths;
};
private:
typedef llvm::SmallVector<LookupResult, 3> LookupResultsVecTy;
- std::pair<bool, LookupResult> CppLookupName(Scope *S, DeclarationName Name,
- LookupNameKind NameKind,
- bool RedeclarationOnly);
- ObjCMethodDecl *FindMethodInNestedImplementations(
- const ObjCInterfaceDecl *IFace,
- const Selector &Sel);
-
+ bool CppLookupName(LookupResult &R, Scope *S, DeclarationName Name,
+ LookupNameKind NameKind, bool RedeclarationOnly);
public:
/// Determines whether D is a suitable lookup result according to the
/// lookup criteria.
@@ -1115,62 +1322,75 @@ public:
case Sema::LookupObjCImplementationName:
case Sema::LookupObjCCategoryImplName:
return D->isInIdentifierNamespace(IDNS);
-
+
case Sema::LookupOperatorName:
- return D->isInIdentifierNamespace(IDNS) &&
+ return D->isInIdentifierNamespace(IDNS) &&
!D->getDeclContext()->isRecord();
case Sema::LookupNestedNameSpecifierName:
return isa<TypedefDecl>(D) || D->isInIdentifierNamespace(Decl::IDNS_Tag);
-
+
case Sema::LookupNamespaceName:
return isa<NamespaceDecl>(D) || isa<NamespaceAliasDecl>(D);
}
-
- assert(false &&
+
+ assert(false &&
"isAcceptableLookupResult always returns before this point");
return false;
}
- LookupResult LookupName(Scope *S, DeclarationName Name,
- LookupNameKind NameKind,
- bool RedeclarationOnly = false,
- bool AllowBuiltinCreation = false,
- SourceLocation Loc = SourceLocation());
- LookupResult LookupQualifiedName(DeclContext *LookupCtx, DeclarationName Name,
- LookupNameKind NameKind,
- bool RedeclarationOnly = false);
- LookupResult LookupParsedName(Scope *S, const CXXScopeSpec *SS,
- DeclarationName Name,
- LookupNameKind NameKind,
- bool RedeclarationOnly = false,
- bool AllowBuiltinCreation = false,
- SourceLocation Loc = SourceLocation());
+ /// \brief Look up a name, looking for a single declaration. Return
+ /// null if no unambiguous results were found.
+ ///
+ /// It is preferable to use the elaborated form and explicitly handle
+ /// ambiguity and overloaded.
+ NamedDecl *LookupSingleName(Scope *S, DeclarationName Name,
+ LookupNameKind NameKind,
+ bool RedeclarationOnly = false) {
+ LookupResult R;
+ LookupName(R, S, Name, NameKind, RedeclarationOnly);
+ return R.getAsSingleDecl(Context);
+ }
+ bool LookupName(LookupResult &R, Scope *S,
+ DeclarationName Name,
+ LookupNameKind NameKind,
+ bool RedeclarationOnly = false,
+ bool AllowBuiltinCreation = false,
+ SourceLocation Loc = SourceLocation());
+ bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
+ DeclarationName Name,
+ LookupNameKind NameKind,
+ bool RedeclarationOnly = false);
+ bool LookupParsedName(LookupResult &R, Scope *S, const CXXScopeSpec *SS,
+ DeclarationName Name,
+ LookupNameKind NameKind,
+ bool RedeclarationOnly = false,
+ bool AllowBuiltinCreation = false,
+ SourceLocation Loc = SourceLocation(),
+ bool EnteringContext = false);
ObjCProtocolDecl *LookupProtocol(IdentifierInfo *II);
- ObjCImplementationDecl *LookupObjCImplementation(IdentifierInfo *II);
ObjCCategoryImplDecl *LookupObjCCategoryImpl(IdentifierInfo *II);
void LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S,
- QualType T1, QualType T2,
+ QualType T1, QualType T2,
FunctionSet &Functions);
-
+
void ArgumentDependentLookup(DeclarationName Name,
Expr **Args, unsigned NumArgs,
FunctionSet &Functions);
void FindAssociatedClassesAndNamespaces(Expr **Args, unsigned NumArgs,
AssociatedNamespaceSet &AssociatedNamespaces,
- AssociatedClassSet &AssociatedClasses,
- bool &GlobalScope);
+ AssociatedClassSet &AssociatedClasses);
bool DiagnoseAmbiguousLookup(LookupResult &Result, DeclarationName Name,
- SourceLocation NameLoc,
+ SourceLocation NameLoc,
SourceRange LookupRange = SourceRange());
//@}
-
+
ObjCInterfaceDecl *getObjCInterfaceDecl(IdentifierInfo *Id);
- NamedDecl *LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID,
+ NamedDecl *LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID,
Scope *S, bool ForRedeclaration,
SourceLocation Loc);
NamedDecl *ImplicitlyDefineFunction(SourceLocation Loc, IdentifierInfo &II,
@@ -1179,7 +1399,7 @@ public:
// More parsing and symbol table subroutines.
- // Decl attributes - this routine is the top level dispatcher.
+ // Decl attributes - this routine is the top level dispatcher.
void ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD);
void ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AttrList);
@@ -1187,13 +1407,10 @@ public:
bool &IncompleteImpl);
void WarnConflictingTypedMethods(ObjCMethodDecl *ImpMethod,
ObjCMethodDecl *IntfMethod);
- bool QualifiedIdConformsQualifiedId(QualType LHS, QualType RHS);
- NamespaceDecl *GetStdNamespace();
-
bool isPropertyReadonly(ObjCPropertyDecl *PropertyDecl,
ObjCInterfaceDecl *IDecl);
-
+
/// CheckProtocolMethodDefs - This routine checks unimplemented
/// methods declared in protocol, and those referenced by it.
/// \param IDecl - Used for checking for methods which may have been
@@ -1204,24 +1421,24 @@ public:
const llvm::DenseSet<Selector> &InsMap,
const llvm::DenseSet<Selector> &ClsMap,
ObjCInterfaceDecl *IDecl);
-
+
/// CheckImplementationIvars - This routine checks if the instance variables
- /// listed in the implelementation match those listed in the interface.
+ /// listed in the implelementation match those listed in the interface.
void CheckImplementationIvars(ObjCImplementationDecl *ImpDecl,
ObjCIvarDecl **Fields, unsigned nIvars,
SourceLocation Loc);
-
+
/// ImplMethodsVsClassMethods - This is main routine to warn if any method
/// remains unimplemented in the class or category @implementation.
- void ImplMethodsVsClassMethods(ObjCImplDecl* IMPDecl,
- ObjCContainerDecl* IDecl,
+ void ImplMethodsVsClassMethods(ObjCImplDecl* IMPDecl,
+ ObjCContainerDecl* IDecl,
bool IncompleteImpl = false);
-
+
/// MatchTwoMethodDeclarations - Checks if two methods' type match and returns
/// true, or false, accordingly.
- bool MatchTwoMethodDeclarations(const ObjCMethodDecl *Method,
+ bool MatchTwoMethodDeclarations(const ObjCMethodDecl *Method,
const ObjCMethodDecl *PrevMethod,
- bool matchBasedOnSizeAndAlignment = false);
+ bool matchBasedOnSizeAndAlignment = false);
/// MatchAllMethodDeclarations - Check methods declaraed in interface or
/// or protocol against those declared in their implementations.
@@ -1239,15 +1456,16 @@ public:
/// a selector with a method declaraation for purposes of typechecking
/// messages sent to "id" (where the class of the object is unknown).
void AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method);
-
+
/// LookupInstanceMethodInGlobalPool - Returns the method and warns if
/// there are multiple signatures.
- ObjCMethodDecl *LookupInstanceMethodInGlobalPool(Selector Sel, SourceRange R);
+ ObjCMethodDecl *LookupInstanceMethodInGlobalPool(Selector Sel, SourceRange R,
+ bool warn=true);
/// LookupFactoryMethodInGlobalPool - Returns the method and warns if
/// there are multiple signatures.
ObjCMethodDecl *LookupFactoryMethodInGlobalPool(Selector Sel, SourceRange R);
-
+
/// AddFactoryMethodToGlobalPool - Same as above, but for factory methods.
void AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method);
//===--------------------------------------------------------------------===//
@@ -1266,7 +1484,7 @@ public:
SourceLocation DotDotDotLoc, ExprArg RHSVal,
SourceLocation ColonLoc);
virtual void ActOnCaseStmtBody(StmtTy *CaseStmt, StmtArg SubStmt);
-
+
virtual OwningStmtResult ActOnDefaultStmt(SourceLocation DefaultLoc,
SourceLocation ColonLoc,
StmtArg SubStmt, Scope *CurScope);
@@ -1274,13 +1492,13 @@ public:
IdentifierInfo *II,
SourceLocation ColonLoc,
StmtArg SubStmt);
- virtual OwningStmtResult ActOnIfStmt(SourceLocation IfLoc,
- FullExprArg CondVal, StmtArg ThenVal,
+ virtual OwningStmtResult ActOnIfStmt(SourceLocation IfLoc,
+ FullExprArg CondVal, StmtArg ThenVal,
SourceLocation ElseLoc, StmtArg ElseVal);
virtual OwningStmtResult ActOnStartOfSwitchStmt(ExprArg Cond);
virtual OwningStmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc,
StmtArg Switch, StmtArg Body);
- virtual OwningStmtResult ActOnWhileStmt(SourceLocation WhileLoc,
+ virtual OwningStmtResult ActOnWhileStmt(SourceLocation WhileLoc,
FullExprArg Cond, StmtArg Body);
virtual OwningStmtResult ActOnDoStmt(SourceLocation DoLoc, StmtArg Body,
SourceLocation WhileLoc,
@@ -1309,7 +1527,7 @@ public:
Scope *CurScope);
virtual OwningStmtResult ActOnReturnStmt(SourceLocation ReturnLoc,
- FullExprArg RetValExp);
+ ExprArg RetValExp);
OwningStmtResult ActOnBlockReturnStmt(SourceLocation ReturnLoc,
Expr *RetValExp);
@@ -1338,13 +1556,14 @@ public:
StmtArg Catch, StmtArg Finally);
virtual OwningStmtResult ActOnObjCAtThrowStmt(SourceLocation AtLoc,
- ExprArg Throw,
+ ExprArg Throw,
Scope *CurScope);
virtual OwningStmtResult ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc,
ExprArg SynchExpr,
StmtArg SynchBody);
VarDecl *BuildExceptionDeclaration(Scope *S, QualType ExDeclType,
+ DeclaratorInfo *DInfo,
IdentifierInfo *Name,
SourceLocation Loc,
SourceRange Range);
@@ -1358,25 +1577,29 @@ public:
MultiStmtArg Handlers);
void DiagnoseReturnInConstructorExceptionHandler(CXXTryStmt *TryBlock);
+ /// DiagnoseUnusedExprResult - If the statement passed in is an expression
+ /// whose result is unused, warn.
+ void DiagnoseUnusedExprResult(const Stmt *S);
+
//===--------------------------------------------------------------------===//
// Expression Parsing Callbacks: SemaExpr.cpp.
bool DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc);
- bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD,
+ bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD,
ObjCMethodDecl *Getter,
SourceLocation Loc);
void DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc,
Expr **Args, unsigned NumArgs);
- virtual ExpressionEvaluationContext
+ virtual ExpressionEvaluationContext
PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext);
-
- virtual void
+
+ virtual void
PopExpressionEvaluationContext(ExpressionEvaluationContext OldContext,
ExpressionEvaluationContext NewContext);
-
+
void MarkDeclarationReferenced(SourceLocation Loc, Decl *D);
-
+
// Primary Expressions.
virtual SourceRange getExprRange(ExprTy *E) const;
@@ -1397,8 +1620,8 @@ public:
bool HasTrailingLParen,
const CXXScopeSpec &SS,
bool isAddressOfOperand);
- OwningExprResult BuildDeclRefExpr(NamedDecl *D, QualType Ty,
- SourceLocation Loc, bool TypeDependent,
+ OwningExprResult BuildDeclRefExpr(NamedDecl *D, QualType Ty,
+ SourceLocation Loc, bool TypeDependent,
bool ValueDependent,
const CXXScopeSpec *SS = 0);
VarDecl *BuildAnonymousStructUnionMemberPath(FieldDecl *Field,
@@ -1415,15 +1638,18 @@ public:
bool isAddressOfOperand = false);
OwningExprResult BuildDeclarationNameExpr(SourceLocation Loc, NamedDecl *D,
bool HasTrailingLParen,
- const CXXScopeSpec *SS,
+ const CXXScopeSpec *SS,
bool isAddressOfOperand);
-
+
virtual OwningExprResult ActOnPredefinedExpr(SourceLocation Loc,
tok::TokenKind Kind);
virtual OwningExprResult ActOnNumericConstant(const Token &);
virtual OwningExprResult ActOnCharacterConstant(const Token &);
virtual OwningExprResult ActOnParenExpr(SourceLocation L, SourceLocation R,
ExprArg Val);
+ virtual OwningExprResult ActOnParenListExpr(SourceLocation L,
+ SourceLocation R,
+ MultiExprArg Val);
/// ActOnStringLiteral - The specified tokens were lexed as pasted string
/// fragments (e.g. "foo" "bar" L"baz").
@@ -1432,19 +1658,19 @@ public:
// Binary/Unary Operators. 'Tok' is the token for the operator.
OwningExprResult CreateBuiltinUnaryOp(SourceLocation OpLoc,
- unsigned OpcIn,
+ unsigned OpcIn,
ExprArg InputArg);
virtual OwningExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc,
tok::TokenKind Op, ExprArg Input);
- OwningExprResult CreateSizeOfAlignOfExpr(QualType T, SourceLocation OpLoc,
+ OwningExprResult CreateSizeOfAlignOfExpr(QualType T, SourceLocation OpLoc,
bool isSizeOf, SourceRange R);
- OwningExprResult CreateSizeOfAlignOfExpr(Expr *E, SourceLocation OpLoc,
+ OwningExprResult CreateSizeOfAlignOfExpr(Expr *E, SourceLocation OpLoc,
bool isSizeOf, SourceRange R);
virtual OwningExprResult
ActOnSizeOfAlignOfExpr(SourceLocation OpLoc, bool isSizeof, bool isType,
void *TyOrEx, const SourceRange &ArgRange);
-
+
bool CheckAlignOfExpr(Expr *E, SourceLocation OpLoc, const SourceRange &R);
bool CheckSizeOfAlignOfOperand(QualType type, SourceLocation OpLoc,
const SourceRange &R, bool isSizeof);
@@ -1457,18 +1683,67 @@ public:
SourceLocation LLoc,
ExprArg Idx,
SourceLocation RLoc);
+
+ OwningExprResult BuildMemberReferenceExpr(Scope *S, ExprArg Base,
+ SourceLocation OpLoc,
+ tok::TokenKind OpKind,
+ SourceLocation MemberLoc,
+ DeclarationName MemberName,
+ DeclPtrTy ImplDecl,
+ const CXXScopeSpec *SS = 0,
+ NamedDecl *FirstQualifierInScope = 0) {
+ // FIXME: Temporary helper while we migrate existing calls to
+ // BuildMemberReferenceExpr to support explicitly-specified template
+ // arguments.
+ return BuildMemberReferenceExpr(S, move(Base), OpLoc, OpKind, MemberLoc,
+ MemberName, false, SourceLocation(), 0, 0,
+ SourceLocation(), ImplDecl, SS,
+ FirstQualifierInScope);
+ }
+
+ OwningExprResult BuildMemberReferenceExpr(Scope *S, ExprArg Base,
+ SourceLocation OpLoc,
+ tok::TokenKind OpKind,
+ SourceLocation MemberLoc,
+ DeclarationName MemberName,
+ bool HasExplicitTemplateArgs,
+ SourceLocation LAngleLoc,
+ const TemplateArgument *ExplicitTemplateArgs,
+ unsigned NumExplicitTemplateArgs,
+ SourceLocation RAngleLoc,
+ DeclPtrTy ImplDecl,
+ const CXXScopeSpec *SS,
+ NamedDecl *FirstQualifierInScope = 0);
+
virtual OwningExprResult ActOnMemberReferenceExpr(Scope *S, ExprArg Base,
SourceLocation OpLoc,
tok::TokenKind OpKind,
SourceLocation MemberLoc,
IdentifierInfo &Member,
- DeclPtrTy ImplDecl);
+ DeclPtrTy ImplDecl,
+ const CXXScopeSpec *SS = 0);
+ virtual void ActOnDefaultCtorInitializers(DeclPtrTy CDtorDecl);
bool ConvertArgumentsForCall(CallExpr *Call, Expr *Fn,
FunctionDecl *FDecl,
const FunctionProtoType *Proto,
Expr **Args, unsigned NumArgs,
SourceLocation RParenLoc);
-
+ void BuildBaseOrMemberInitializers(ASTContext &C,
+ CXXConstructorDecl *Constructor,
+ CXXBaseOrMemberInitializer **Initializers,
+ unsigned NumInitializers
+ );
+
+ void DeconstructCallFunction(Expr *FnExpr,
+ NamedDecl *&Function,
+ DeclarationName &Name,
+ NestedNameSpecifier *&Qualifier,
+ SourceRange &QualifierRange,
+ bool &ArgumentDependentLookup,
+ bool &HasExplicitTemplateArguments,
+ const TemplateArgument *&ExplicitTemplateArgs,
+ unsigned &NumExplicitTemplateArgs);
+
/// ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
/// This provides the location of the left/right parens and a list of comma
/// locations.
@@ -1478,8 +1753,14 @@ public:
SourceLocation *CommaLocs,
SourceLocation RParenLoc);
- virtual OwningExprResult ActOnCastExpr(SourceLocation LParenLoc, TypeTy *Ty,
- SourceLocation RParenLoc, ExprArg Op);
+ virtual OwningExprResult ActOnCastExpr(Scope *S, SourceLocation LParenLoc,
+ TypeTy *Ty, SourceLocation RParenLoc,
+ ExprArg Op);
+
+ OwningExprResult MaybeConvertParenListExprToParenExpr(Scope *S, ExprArg ME);
+ OwningExprResult ActOnCastOfParenListExpr(Scope *S, SourceLocation LParenLoc,
+ SourceLocation RParenLoc, ExprArg E,
+ QualType Ty);
virtual OwningExprResult ActOnCompoundLiteral(SourceLocation LParenLoc,
TypeTy *Ty,
@@ -1577,7 +1858,7 @@ public:
SourceLocation IdentLoc,
IdentifierInfo *NamespcName,
AttributeList *AttrList);
-
+
void PushUsingDirective(Scope *S, UsingDirectiveDecl *UDir);
virtual DeclPtrTy ActOnNamespaceAliasDef(Scope *CurScope,
@@ -1588,16 +1869,24 @@ public:
SourceLocation IdentLoc,
IdentifierInfo *Ident);
+ NamedDecl *BuildUsingDeclaration(SourceLocation UsingLoc,
+ const CXXScopeSpec &SS,
+ SourceLocation IdentLoc,
+ DeclarationName Name,
+ AttributeList *AttrList,
+ bool IsTypeName);
+
virtual DeclPtrTy ActOnUsingDeclaration(Scope *CurScope,
- SourceLocation UsingLoc,
- const CXXScopeSpec &SS,
- SourceLocation IdentLoc,
- IdentifierInfo *TargetName,
- OverloadedOperatorKind Op,
- AttributeList *AttrList,
- bool IsTypeName);
-
- /// AddCXXDirectInitializerToDecl - This action is called immediately after
+ AccessSpecifier AS,
+ SourceLocation UsingLoc,
+ const CXXScopeSpec &SS,
+ SourceLocation IdentLoc,
+ IdentifierInfo *TargetName,
+ OverloadedOperatorKind Op,
+ AttributeList *AttrList,
+ bool IsTypeName);
+
+ /// AddCXXDirectInitializerToDecl - This action is called immediately after
/// ActOnDeclarator, when a C++ direct initializer is present.
/// e.g: "int x(1);"
virtual void AddCXXDirectInitializerToDecl(DeclPtrTy Dcl,
@@ -1608,57 +1897,79 @@ public:
/// InitializeVarWithConstructor - Creates an CXXConstructExpr
/// and sets it as the initializer for the the passed in VarDecl.
- void InitializeVarWithConstructor(VarDecl *VD,
+ bool InitializeVarWithConstructor(VarDecl *VD,
CXXConstructorDecl *Constructor,
- QualType DeclInitType,
- Expr **Exprs, unsigned NumExprs);
-
- /// MarkDestructorReferenced - Prepare for calling destructor on the
- /// constructed decl.
- void MarkDestructorReferenced(SourceLocation Loc, QualType DeclInitType);
-
- /// DefineImplicitDefaultConstructor - Checks for feasibility of
+ QualType DeclInitType,
+ MultiExprArg Exprs);
+
+ /// BuildCXXConstructExpr - Creates a complete call to a constructor,
+ /// including handling of its default argument expressions.
+ OwningExprResult BuildCXXConstructExpr(SourceLocation ConstructLoc,
+ QualType DeclInitType,
+ CXXConstructorDecl *Constructor,
+ MultiExprArg Exprs);
+
+ // FIXME: Can re remove this and have the above BuildCXXConstructExpr check if
+ // the constructor can be elidable?
+ OwningExprResult BuildCXXConstructExpr(SourceLocation ConstructLoc,
+ QualType DeclInitType,
+ CXXConstructorDecl *Constructor,
+ bool Elidable,
+ MultiExprArg Exprs);
+
+ OwningExprResult BuildCXXTemporaryObjectExpr(CXXConstructorDecl *Cons,
+ QualType writtenTy,
+ SourceLocation tyBeginLoc,
+ MultiExprArg Args,
+ SourceLocation rParenLoc);
+
+ OwningExprResult BuildCXXCastArgument(SourceLocation CastLoc,
+ QualType Ty,
+ CastExpr::CastKind Kind,
+ CXXMethodDecl *Method,
+ ExprArg Arg);
+
+ /// BuildCXXDefaultArgExpr - Creates a CXXDefaultArgExpr, instantiating
+ /// the default expr if needed.
+ OwningExprResult BuildCXXDefaultArgExpr(SourceLocation CallLoc,
+ FunctionDecl *FD,
+ ParmVarDecl *Param);
+
+ /// FinalizeVarWithDestructor - Prepare for calling destructor on the
+ /// constructed variable.
+ void FinalizeVarWithDestructor(VarDecl *VD, QualType DeclInitType);
+
+ /// DefineImplicitDefaultConstructor - Checks for feasibility of
/// defining this constructor as the default constructor.
void DefineImplicitDefaultConstructor(SourceLocation CurrentLocation,
CXXConstructorDecl *Constructor);
-
- /// DefineImplicitDestructor - Checks for feasibility of
+
+ /// DefineImplicitDestructor - Checks for feasibility of
/// defining this destructor as the default destructor.
void DefineImplicitDestructor(SourceLocation CurrentLocation,
CXXDestructorDecl *Destructor);
-
- /// DefineImplicitCopyConstructor - Checks for feasibility of
+
+ /// DefineImplicitCopyConstructor - Checks for feasibility of
/// defining this constructor as the copy constructor.
void DefineImplicitCopyConstructor(SourceLocation CurrentLocation,
CXXConstructorDecl *Constructor,
unsigned TypeQuals);
-
+
/// DefineImplicitOverloadedAssign - Checks for feasibility of
/// defining implicit this overloaded assignment operator.
- void DefineImplicitOverloadedAssign(SourceLocation CurrentLocation,
+ void DefineImplicitOverloadedAssign(SourceLocation CurrentLocation,
CXXMethodDecl *MethodDecl);
-
+
/// getAssignOperatorMethod - Returns the default copy assignmment operator
/// for the class.
CXXMethodDecl *getAssignOperatorMethod(ParmVarDecl *Decl,
- CXXRecordDecl *ClassDecl);
+ CXXRecordDecl *ClassDecl);
/// MaybeBindToTemporary - If the passed in expression has a record type with
/// a non-trivial destructor, this will return CXXBindTemporaryExpr. Otherwise
/// it simply returns the passed in expression.
OwningExprResult MaybeBindToTemporary(Expr *E);
- /// RemoveOutermostTemporaryBinding - Remove and destroy the outermost
- /// CXXBindToTemporaryExpr if necessary. This is used when we want to not
- /// destroy a temporary when a full expression has been evaluated.
- /// For example:
- ///
- /// const T& t = T(10, T());
- ///
- /// Here the outermost T needs to be destroyed when t goes out of scope, but
- /// the innermost T needs to be destroyed when the expr has been evaluated.
- Expr *RemoveOutermostTemporaryBinding(Expr *E);
-
/// InitializationKind - Represents which kind of C++ initialization
/// [dcl.init] a routine is to perform.
enum InitializationKind {
@@ -1669,11 +1980,17 @@ public:
CXXConstructorDecl *
PerformInitializationByConstructor(QualType ClassType,
- Expr **Args, unsigned NumArgs,
+ MultiExprArg ArgsPtr,
SourceLocation Loc, SourceRange Range,
DeclarationName InitEntity,
- InitializationKind Kind);
+ InitializationKind Kind,
+ ASTOwningVector<&ActionBase::DeleteExpr> &ConvertedArgs);
+ bool CompleteConstructorCall(CXXConstructorDecl *Constructor,
+ MultiExprArg ArgsPtr,
+ SourceLocation Loc,
+ ASTOwningVector<&ActionBase::DeleteExpr> &ConvertedArgs);
+
/// ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const}_cast's.
virtual OwningExprResult ActOnCXXNamedCast(SourceLocation OpLoc,
tok::TokenKind Kind,
@@ -1729,7 +2046,7 @@ public:
SourceLocation PlacementLParen,
MultiExprArg PlacementArgs,
SourceLocation PlacementRParen,
- bool ParenTypeId,
+ bool ParenTypeId,
QualType AllocType,
SourceLocation TypeLoc,
SourceRange TypeRange,
@@ -1737,7 +2054,7 @@ public:
SourceLocation ConstructorLParen,
MultiExprArg ConstructorArgs,
SourceLocation ConstructorRParen);
-
+
bool CheckAllocatedType(QualType AllocType, SourceLocation Loc,
SourceRange R);
bool FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
@@ -1775,17 +2092,62 @@ public:
TypeTy *Ty,
SourceLocation RParen);
- /// MaybeCreateCXXExprWithTemporaries - If the list of temporaries is
+ virtual OwningExprResult ActOnStartCXXMemberReference(Scope *S,
+ ExprArg Base,
+ SourceLocation OpLoc,
+ tok::TokenKind OpKind,
+ TypeTy *&ObjectType);
+
+ virtual OwningExprResult
+ ActOnDestructorReferenceExpr(Scope *S, ExprArg Base,
+ SourceLocation OpLoc,
+ tok::TokenKind OpKind,
+ SourceLocation ClassNameLoc,
+ IdentifierInfo *ClassName,
+ const CXXScopeSpec &SS,
+ bool HasTrailingLParen);
+
+ virtual OwningExprResult
+ ActOnOverloadedOperatorReferenceExpr(Scope *S, ExprArg Base,
+ SourceLocation OpLoc,
+ tok::TokenKind OpKind,
+ SourceLocation ClassNameLoc,
+ OverloadedOperatorKind OverOpKind,
+ const CXXScopeSpec *SS = 0);
+ virtual OwningExprResult
+ ActOnConversionOperatorReferenceExpr(Scope *S, ExprArg Base,
+ SourceLocation OpLoc,
+ tok::TokenKind OpKind,
+ SourceLocation ClassNameLoc,
+ TypeTy *Ty,
+ const CXXScopeSpec *SS = 0);
+
+ virtual OwningExprResult
+ ActOnMemberTemplateIdReferenceExpr(Scope *S, ExprArg Base,
+ SourceLocation OpLoc,
+ tok::TokenKind OpKind,
+ const CXXScopeSpec &SS,
+ // FIXME: "template" keyword?
+ TemplateTy Template,
+ SourceLocation TemplateNameLoc,
+ SourceLocation LAngleLoc,
+ ASTTemplateArgsPtr TemplateArgs,
+ SourceLocation *TemplateArgLocs,
+ SourceLocation RAngleLoc);
+
+ /// MaybeCreateCXXExprWithTemporaries - If the list of temporaries is
/// non-empty, will create a new CXXExprWithTemporaries expression.
/// Otherwise, just returs the passed in expression.
Expr *MaybeCreateCXXExprWithTemporaries(Expr *SubExpr,
bool ShouldDestroyTemporaries);
-
+
virtual OwningExprResult ActOnFinishFullExpr(ExprArg Expr);
bool RequireCompleteDeclContext(const CXXScopeSpec &SS);
-
- DeclContext *computeDeclContext(const CXXScopeSpec &SS);
+
+ DeclContext *computeDeclContext(QualType T);
+ DeclContext *computeDeclContext(const CXXScopeSpec &SS,
+ bool EnteringContext = false);
bool isDependentScopeSpecifier(const CXXScopeSpec &SS);
CXXRecordDecl *getCurrentInstantiationOf(NestedNameSpecifier *NNS);
bool isUnknownSpecialization(const CXXScopeSpec &SS);
@@ -1795,17 +2157,26 @@ public:
virtual CXXScopeTy *ActOnCXXGlobalScopeSpecifier(Scope *S,
SourceLocation CCLoc);
- /// ActOnCXXNestedNameSpecifier - Called during parsing of a
- /// nested-name-specifier. e.g. for "foo::bar::" we parsed "foo::" and now
- /// we want to resolve "bar::". 'SS' is empty or the previously parsed
- /// nested-name part ("foo::"), 'IdLoc' is the source location of 'bar',
- /// 'CCLoc' is the location of '::' and 'II' is the identifier for 'bar'.
- /// Returns a CXXScopeTy* object representing the C++ scope.
+ bool isAcceptableNestedNameSpecifier(NamedDecl *SD);
+ NamedDecl *FindFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS);
+
+
+ CXXScopeTy *BuildCXXNestedNameSpecifier(Scope *S,
+ const CXXScopeSpec &SS,
+ SourceLocation IdLoc,
+ SourceLocation CCLoc,
+ IdentifierInfo &II,
+ QualType ObjectType,
+ NamedDecl *ScopeLookupResult,
+ bool EnteringContext);
+
virtual CXXScopeTy *ActOnCXXNestedNameSpecifier(Scope *S,
const CXXScopeSpec &SS,
SourceLocation IdLoc,
SourceLocation CCLoc,
- IdentifierInfo &II);
+ IdentifierInfo &II,
+ TypeTy *ObjectType,
+ bool EnteringContext);
/// ActOnCXXNestedNameSpecifier - Called during parsing of a
/// nested-name-specifier that involves a template-id, e.g.,
@@ -1827,7 +2198,7 @@ public:
/// looked up in the declarator-id's scope, until the declarator is parsed and
/// ActOnCXXExitDeclaratorScope is called.
/// The 'SS' should be a non-empty valid CXXScopeSpec.
- virtual void ActOnCXXEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS);
+ virtual bool ActOnCXXEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS);
/// ActOnCXXExitDeclaratorScope - Called when a declarator that previously
/// invoked ActOnCXXEnterDeclaratorScope(), is finished. 'SS' is the same
@@ -1848,26 +2219,28 @@ public:
virtual void ActOnCXXExitDeclInitializer(Scope *S, DeclPtrTy Dcl);
// ParseObjCStringLiteral - Parse Objective-C string literals.
- virtual ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs,
+ virtual ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs,
ExprTy **Strings,
unsigned NumStrings);
-
- Expr *BuildObjCEncodeExpression(SourceLocation AtLoc,
+
+ Expr *BuildObjCEncodeExpression(SourceLocation AtLoc,
QualType EncodedType,
- SourceLocation RParenLoc);
+ SourceLocation RParenLoc);
+ CXXMemberCallExpr *BuildCXXMemberCallExpr(Expr *Exp, CXXMethodDecl *Method);
+
virtual ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc,
SourceLocation EncodeLoc,
SourceLocation LParenLoc,
TypeTy *Ty,
SourceLocation RParenLoc);
-
+
// ParseObjCSelectorExpression - Build selector expression for @selector
virtual ExprResult ParseObjCSelectorExpression(Selector Sel,
SourceLocation AtLoc,
SourceLocation SelLoc,
SourceLocation LParenLoc,
SourceLocation RParenLoc);
-
+
// ParseObjCProtocolExpression - Build protocol expression for @protocol
virtual ExprResult ParseObjCProtocolExpression(IdentifierInfo * ProtocolName,
SourceLocation AtLoc,
@@ -1897,6 +2270,7 @@ public:
virtual DeclPtrTy ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS,
Declarator &D,
+ MultiTemplateParamsArg TemplateParameterLists,
ExprTy *BitfieldWidth,
ExprTy *Init,
bool Deleted = false);
@@ -1912,12 +2286,33 @@ public:
SourceLocation *CommaLocs,
SourceLocation RParenLoc);
+ MemInitResult BuildMemberInitializer(FieldDecl *Member, Expr **Args,
+ unsigned NumArgs, SourceLocation IdLoc,
+ SourceLocation RParenLoc);
+
+ MemInitResult BuildBaseInitializer(QualType BaseType, Expr **Args,
+ unsigned NumArgs, SourceLocation IdLoc,
+ SourceLocation RParenLoc,
+ CXXRecordDecl *ClassDecl);
+
+ void setBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
+ CXXBaseOrMemberInitializer **Initializers,
+ unsigned NumInitializers,
+ llvm::SmallVectorImpl<CXXBaseSpecifier *>& Bases,
+ llvm::SmallVectorImpl<FieldDecl *>&Members);
+
+ /// computeBaseOrMembersToDestroy - Compute information in current
+ /// destructor decl's AST of bases and non-static data members which will be
+ /// implicitly destroyed. We are storing the destruction in the order that
+ /// they should occur (which is the reverse of construction order).
+ void computeBaseOrMembersToDestroy(CXXDestructorDecl *Destructor);
+
void AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl);
- virtual void ActOnMemInitializers(DeclPtrTy ConstructorDecl,
+ virtual void ActOnMemInitializers(DeclPtrTy ConstructorDecl,
SourceLocation ColonLoc,
MemInitTy **MemInits, unsigned NumMemInits);
-
+
virtual void ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc,
DeclPtrTy TagDecl,
SourceLocation LBrac,
@@ -1930,12 +2325,14 @@ public:
virtual void ActOnFinishDelayedCXXMethodDeclaration(Scope *S,
DeclPtrTy Method);
- virtual DeclPtrTy ActOnStaticAssertDeclaration(SourceLocation AssertLoc,
+ virtual DeclPtrTy ActOnStaticAssertDeclaration(SourceLocation AssertLoc,
ExprArg AssertExpr,
ExprArg AssertMessageExpr);
-
- virtual bool ActOnFriendDecl(Scope *S, SourceLocation FriendLoc,
- DeclPtrTy Dcl);
+
+ DeclPtrTy ActOnFriendTypeDecl(Scope *S, const DeclSpec &DS,
+ MultiTemplateParamsArg TemplateParams);
+ DeclPtrTy ActOnFriendFunctionDecl(Scope *S, Declarator &D, bool IsDefinition,
+ MultiTemplateParamsArg TemplateParams);
QualType CheckConstructorDeclarator(Declarator &D, QualType R,
FunctionDecl::StorageClass& SC);
@@ -1954,23 +2351,22 @@ public:
CXXBaseSpecifier *CheckBaseSpecifier(CXXRecordDecl *Class,
SourceRange SpecifierRange,
bool Virtual, AccessSpecifier Access,
- QualType BaseType,
+ QualType BaseType,
SourceLocation BaseLoc);
- virtual BaseResult ActOnBaseSpecifier(DeclPtrTy classdecl,
+ virtual BaseResult ActOnBaseSpecifier(DeclPtrTy classdecl,
SourceRange SpecifierRange,
bool Virtual, AccessSpecifier Access,
- TypeTy *basetype, SourceLocation
+ TypeTy *basetype, SourceLocation
BaseLoc);
bool AttachBaseSpecifiers(CXXRecordDecl *Class, CXXBaseSpecifier **Bases,
unsigned NumBases);
- virtual void ActOnBaseSpecifiers(DeclPtrTy ClassDecl, BaseTy **Bases,
+ virtual void ActOnBaseSpecifiers(DeclPtrTy ClassDecl, BaseTy **Bases,
unsigned NumBases);
bool IsDerivedFrom(QualType Derived, QualType Base);
- bool IsDerivedFrom(QualType Derived, QualType Base, BasePaths &Paths);
- bool LookupInBases(CXXRecordDecl *Class, const MemberLookupCriteria& Criteria,
- BasePaths &Paths);
+ bool IsDerivedFrom(QualType Derived, QualType Base, CXXBasePaths &Paths);
+
bool CheckDerivedToBaseConversion(QualType Derived, QualType Base,
SourceLocation Loc, SourceRange Range);
bool CheckDerivedToBaseConversion(QualType Derived, QualType Base,
@@ -1978,29 +2374,37 @@ public:
unsigned AmbigiousBaseConvID,
SourceLocation Loc, SourceRange Range,
DeclarationName Name);
-
- std::string getAmbiguousPathsDisplayString(BasePaths &Paths);
-
- /// CheckReturnTypeCovariance - Checks whether two types are covariant,
- /// according to C++ [class.virtual]p5.
- bool CheckOverridingFunctionReturnType(const CXXMethodDecl *New,
+
+ std::string getAmbiguousPathsDisplayString(CXXBasePaths &Paths);
+
+ /// CheckOverridingFunctionReturnType - Checks whether the return types are
+ /// covariant, according to C++ [class.virtual]p5.
+ bool CheckOverridingFunctionReturnType(const CXXMethodDecl *New,
const CXXMethodDecl *Old);
-
+
+ /// CheckOverridingFunctionExceptionSpec - Checks whether the exception
+ /// spec is a subset of base spec.
+ bool CheckOverridingFunctionExceptionSpec(const CXXMethodDecl *New,
+ const CXXMethodDecl *Old);
//===--------------------------------------------------------------------===//
// C++ Access Control
//
-
- bool SetMemberAccessSpecifier(NamedDecl *MemberDecl,
+
+ bool SetMemberAccessSpecifier(NamedDecl *MemberDecl,
NamedDecl *PrevMemberDecl,
AccessSpecifier LexicalAS);
-
- bool CheckBaseClassAccess(QualType Derived, QualType Base,
+
+ const CXXBaseSpecifier *FindInaccessibleBase(QualType Derived, QualType Base,
+ CXXBasePaths &Paths,
+ bool NoPrivileges = false);
+
+ bool CheckBaseClassAccess(QualType Derived, QualType Base,
unsigned InaccessibleBaseID,
- BasePaths& Paths, SourceLocation AccessLoc,
+ CXXBasePaths& Paths, SourceLocation AccessLoc,
DeclarationName Name);
-
-
+
+
enum AbstractDiagSelID {
AbstractNone = -1,
AbstractReturnType,
@@ -2008,8 +2412,12 @@ public:
AbstractVariableType,
AbstractFieldType
};
-
- bool RequireNonAbstractType(SourceLocation Loc, QualType T, unsigned DiagID,
+
+ bool RequireNonAbstractType(SourceLocation Loc, QualType T,
+ const PartialDiagnostic &PD,
+ const CXXRecordDecl *CurrentRD = 0);
+
+ bool RequireNonAbstractType(SourceLocation Loc, QualType T, unsigned DiagID,
AbstractDiagSelID SelID = AbstractNone,
const CXXRecordDecl *CurrentRD = 0);
@@ -2022,19 +2430,23 @@ public:
//===--------------------------------------------------------------------===//
// C++ Templates [C++ 14]
//
- virtual TemplateNameKind isTemplateName(const IdentifierInfo &II, Scope *S,
- TemplateTy &Template,
- const CXXScopeSpec *SS = 0);
+ virtual TemplateNameKind isTemplateName(Scope *S,
+ const IdentifierInfo &II,
+ SourceLocation IdLoc,
+ const CXXScopeSpec *SS,
+ TypeTy *ObjectType,
+ bool EnteringContext,
+ TemplateTy &Template);
bool DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl);
TemplateDecl *AdjustDeclIfTemplate(DeclPtrTy &Decl);
- virtual DeclPtrTy ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis,
+ virtual DeclPtrTy ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis,
SourceLocation EllipsisLoc,
SourceLocation KeyLoc,
IdentifierInfo *ParamName,
SourceLocation ParamNameLoc,
unsigned Depth, unsigned Position);
- virtual void ActOnTypeParameterDefault(DeclPtrTy TypeParam,
+ virtual void ActOnTypeParameterDefault(DeclPtrTy TypeParam,
SourceLocation EqualLoc,
SourceLocation DefaultLoc,
TypeTy *Default);
@@ -2060,21 +2472,30 @@ public:
virtual TemplateParamsTy *
ActOnTemplateParameterList(unsigned Depth,
SourceLocation ExportLoc,
- SourceLocation TemplateLoc,
+ SourceLocation TemplateLoc,
SourceLocation LAngleLoc,
DeclPtrTy *Params, unsigned NumParams,
SourceLocation RAngleLoc);
bool CheckTemplateParameterList(TemplateParameterList *NewParams,
TemplateParameterList *OldParams);
-
- virtual DeclResult
- ActOnClassTemplate(Scope *S, unsigned TagSpec, TagKind TK,
- SourceLocation KWLoc, const CXXScopeSpec &SS,
- IdentifierInfo *Name, SourceLocation NameLoc,
- AttributeList *Attr,
- MultiTemplateParamsArg TemplateParameterLists,
- AccessSpecifier AS);
-
+ TemplateParameterList *
+ MatchTemplateParametersToScopeSpecifier(SourceLocation DeclStartLoc,
+ const CXXScopeSpec &SS,
+ TemplateParameterList **ParamLists,
+ unsigned NumParamLists,
+ bool &IsExplicitSpecialization);
+
+ DeclResult CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
+ SourceLocation KWLoc, const CXXScopeSpec &SS,
+ IdentifierInfo *Name, SourceLocation NameLoc,
+ AttributeList *Attr,
+ TemplateParameterList *TemplateParams,
+ AccessSpecifier AS);
+
+ void translateTemplateArguments(ASTTemplateArgsPtr &TemplateArgsIn,
+ SourceLocation *TemplateArgLocs,
+ llvm::SmallVector<TemplateArgument, 16> &TemplateArgs);
+
QualType CheckTemplateIdType(TemplateName Template,
SourceLocation TemplateLoc,
SourceLocation LAngleLoc,
@@ -2088,32 +2509,31 @@ public:
ASTTemplateArgsPtr TemplateArgs,
SourceLocation *TemplateArgLocs,
SourceLocation RAngleLoc);
-
+
+ virtual TypeResult ActOnTagTemplateIdType(TypeResult Type,
+ TagUseKind TUK,
+ DeclSpec::TST TagSpec,
+ SourceLocation TagLoc);
+
OwningExprResult BuildTemplateIdExpr(TemplateName Template,
SourceLocation TemplateNameLoc,
SourceLocation LAngleLoc,
const TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc);
-
+
virtual OwningExprResult ActOnTemplateIdExpr(TemplateTy Template,
SourceLocation TemplateNameLoc,
SourceLocation LAngleLoc,
ASTTemplateArgsPtr TemplateArgs,
SourceLocation *TemplateArgLocs,
SourceLocation RAngleLoc);
-
+
virtual TemplateTy ActOnDependentTemplateName(SourceLocation TemplateKWLoc,
const IdentifierInfo &Name,
SourceLocation NameLoc,
- const CXXScopeSpec &SS);
-
- bool CheckClassTemplateSpecializationScope(ClassTemplateDecl *ClassTemplate,
- ClassTemplateSpecializationDecl *PrevDecl,
- SourceLocation TemplateNameLoc,
- SourceRange ScopeSpecifierRange,
- bool PartialSpecialization,
- bool ExplicitInstantiation);
+ const CXXScopeSpec &SS,
+ TypeTy *ObjectType);
bool CheckClassTemplatePartialSpecializationArgs(
TemplateParameterList *TemplateParams,
@@ -2121,8 +2541,8 @@ public:
bool &MirrorsPrimaryTemplate);
virtual DeclResult
- ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK,
- SourceLocation KWLoc,
+ ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagUseKind TUK,
+ SourceLocation KWLoc,
const CXXScopeSpec &SS,
TemplateTy Template,
SourceLocation TemplateNameLoc,
@@ -2133,17 +2553,28 @@ public:
AttributeList *Attr,
MultiTemplateParamsArg TemplateParameterLists);
- virtual DeclPtrTy ActOnTemplateDeclarator(Scope *S,
+ virtual DeclPtrTy ActOnTemplateDeclarator(Scope *S,
MultiTemplateParamsArg TemplateParameterLists,
Declarator &D);
-
- virtual DeclPtrTy ActOnStartOfFunctionTemplateDef(Scope *FnBodyScope,
+
+ virtual DeclPtrTy ActOnStartOfFunctionTemplateDef(Scope *FnBodyScope,
MultiTemplateParamsArg TemplateParameterLists,
Declarator &D);
-
+
+ bool CheckFunctionTemplateSpecialization(FunctionDecl *FD,
+ bool HasExplicitTemplateArgs,
+ SourceLocation LAngleLoc,
+ const TemplateArgument *ExplicitTemplateArgs,
+ unsigned NumExplicitTemplateArgs,
+ SourceLocation RAngleLoc,
+ NamedDecl *&PrevDecl);
+ bool CheckMemberSpecialization(NamedDecl *Member, NamedDecl *&PrevDecl);
+
virtual DeclResult
- ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc,
- unsigned TagSpec,
+ ActOnExplicitInstantiation(Scope *S,
+ SourceLocation ExternLoc,
+ SourceLocation TemplateLoc,
+ unsigned TagSpec,
SourceLocation KWLoc,
const CXXScopeSpec &SS,
TemplateTy Template,
@@ -2155,14 +2586,21 @@ public:
AttributeList *Attr);
virtual DeclResult
- ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc,
- unsigned TagSpec,
+ ActOnExplicitInstantiation(Scope *S,
+ SourceLocation ExternLoc,
+ SourceLocation TemplateLoc,
+ unsigned TagSpec,
SourceLocation KWLoc,
const CXXScopeSpec &SS,
IdentifierInfo *Name,
SourceLocation NameLoc,
AttributeList *Attr);
+ virtual DeclResult ActOnExplicitInstantiation(Scope *S,
+ SourceLocation ExternLoc,
+ SourceLocation TemplateLoc,
+ Declarator &D);
+
bool CheckTemplateArgumentList(TemplateDecl *Template,
SourceLocation TemplateLoc,
SourceLocation LAngleLoc,
@@ -2172,16 +2610,16 @@ public:
bool PartialTemplateArgs,
TemplateArgumentListBuilder &Converted);
- bool CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
+ bool CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
const TemplateArgument &Arg,
TemplateArgumentListBuilder &Converted);
bool CheckTemplateArgument(TemplateTypeParmDecl *Param, QualType Arg,
SourceLocation ArgLoc);
- bool CheckTemplateArgumentAddressOfObjectOrFunction(Expr *Arg,
+ bool CheckTemplateArgumentAddressOfObjectOrFunction(Expr *Arg,
NamedDecl *&Entity);
bool CheckTemplateArgumentPointerToMember(Expr *Arg, NamedDecl *&Member);
- bool CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
+ bool CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
QualType InstantiatedParamType, Expr *&Arg,
TemplateArgument &Converted);
bool CheckTemplateArgument(TemplateTemplateParmDecl *Param, DeclRefExpr *Arg);
@@ -2191,9 +2629,8 @@ public:
bool IsTemplateTemplateParm = false,
SourceLocation TemplateArgLoc
= SourceLocation());
-
- bool CheckTemplateDeclScope(Scope *S,
- MultiTemplateParamsArg &TemplateParameterLists);
+
+ bool CheckTemplateDeclScope(Scope *S, TemplateParameterList *TemplateParams);
/// \brief Called when the parser has parsed a C++ typename
/// specifier, e.g., "typename T::type".
@@ -2207,7 +2644,7 @@ public:
const IdentifierInfo &II, SourceLocation IdLoc);
/// \brief Called when the parser has parsed a C++ typename
- /// specifier that ends in a template-id, e.g.,
+ /// specifier that ends in a template-id, e.g.,
/// "typename MetaFun::template apply<T1, T2>".
///
/// \param TypenameLoc the location of the 'typename' keyword
@@ -2222,6 +2659,13 @@ public:
const IdentifierInfo &II,
SourceRange Range);
+ QualType RebuildTypeInCurrentInstantiation(QualType T, SourceLocation Loc,
+ DeclarationName Name);
+
+ std::string
+ getTemplateArgumentBindingsText(const TemplateParameterList *Params,
+ const TemplateArgumentList &Args);
+
/// \brief Describes the result of template argument deduction.
///
/// The TemplateDeductionResult enumeration describes the result of
@@ -2256,10 +2700,10 @@ public:
/// produces a type that does not match the original template
/// arguments provided.
TDK_NonDeducedMismatch,
- /// \brief When performing template argument deduction for a function
+ /// \brief When performing template argument deduction for a function
/// template, there were too many call arguments.
TDK_TooManyArguments,
- /// \brief When performing template argument deduction for a class
+ /// \brief When performing template argument deduction for a function
/// template, there were too few call arguments.
TDK_TooFewArguments,
/// \brief The explicitly-specified template arguments were not valid
@@ -2290,7 +2734,7 @@ public:
}
/// \brief Take ownership of the deduced template argument list.
- TemplateArgumentList *take() {
+ TemplateArgumentList *take() {
TemplateArgumentList *Result = Deduced;
Deduced = 0;
return Result;
@@ -2343,7 +2787,22 @@ public:
DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial,
const TemplateArgumentList &TemplateArgs,
TemplateDeductionInfo &Info);
-
+
+ TemplateDeductionResult
+ SubstituteExplicitTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
+ const TemplateArgument *ExplicitTemplateArgs,
+ unsigned NumExplicitTemplateArgs,
+ llvm::SmallVectorImpl<TemplateArgument> &Deduced,
+ llvm::SmallVectorImpl<QualType> &ParamTypes,
+ QualType *FunctionType,
+ TemplateDeductionInfo &Info);
+
+ TemplateDeductionResult
+ FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate,
+ llvm::SmallVectorImpl<TemplateArgument> &Deduced,
+ FunctionDecl *&Specialization,
+ TemplateDeductionInfo &Info);
+
TemplateDeductionResult
DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
bool HasExplicitTemplateArgs,
@@ -2352,15 +2811,50 @@ public:
Expr **Args, unsigned NumArgs,
FunctionDecl *&Specialization,
TemplateDeductionInfo &Info);
-
- void MarkDeducedTemplateParameters(const TemplateArgumentList &TemplateArgs,
+
+ TemplateDeductionResult
+ DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
+ bool HasExplicitTemplateArgs,
+ const TemplateArgument *ExplicitTemplateArgs,
+ unsigned NumExplicitTemplateArgs,
+ QualType ArgFunctionType,
+ FunctionDecl *&Specialization,
+ TemplateDeductionInfo &Info);
+
+ TemplateDeductionResult
+ DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
+ QualType ToType,
+ CXXConversionDecl *&Specialization,
+ TemplateDeductionInfo &Info);
+
+ FunctionTemplateDecl *getMoreSpecializedTemplate(FunctionTemplateDecl *FT1,
+ FunctionTemplateDecl *FT2,
+ TemplatePartialOrderingContext TPOC);
+ FunctionDecl *getMostSpecialized(FunctionDecl **Specializations,
+ unsigned NumSpecializations,
+ TemplatePartialOrderingContext TPOC,
+ SourceLocation Loc,
+ const PartialDiagnostic &NoneDiag,
+ const PartialDiagnostic &AmbigDiag,
+ const PartialDiagnostic &CandidateDiag,
+ unsigned *Index = 0);
+
+ ClassTemplatePartialSpecializationDecl *
+ getMoreSpecializedPartialSpecialization(
+ ClassTemplatePartialSpecializationDecl *PS1,
+ ClassTemplatePartialSpecializationDecl *PS2);
+
+ void MarkUsedTemplateParameters(const TemplateArgumentList &TemplateArgs,
+ bool OnlyDeduced,
+ llvm::SmallVectorImpl<bool> &Used);
+ void MarkDeducedTemplateParameters(FunctionTemplateDecl *FunctionTemplate,
llvm::SmallVectorImpl<bool> &Deduced);
-
+
//===--------------------------------------------------------------------===//
// C++ Template Instantiation
//
- const TemplateArgumentList &getTemplateInstantiationArgs(NamedDecl *D);
+ MultiLevelTemplateArgumentList getTemplateInstantiationArgs(NamedDecl *D);
/// \brief A template instantiation that is currently in progress.
struct ActiveTemplateInstantiation {
@@ -2377,10 +2871,15 @@ public:
/// FIXME: Use a TemplateArgumentList
DefaultTemplateArgumentInstantiation,
- /// We are substituting explicit template arguments provided for
+ /// We are instantiating a default argument for a function.
+ /// The Entity is the ParmVarDecl, and TemplateArgs/NumTemplateArgs
+ /// provides the template arguments as specified.
+ DefaultFunctionArgumentInstantiation,
+
+ /// We are substituting explicit template arguments provided for
/// a function template. The entity is a FunctionTemplateDecl.
ExplicitTemplateArgumentSubstitution,
-
+
/// We are substituting template argument determined as part of
/// template argument deduction for either a class template
/// partial specialization or a function template. The
@@ -2407,6 +2906,9 @@ public:
/// template instantiation.
SourceRange InstantiationRange;
+ ActiveTemplateInstantiation() : Kind(TemplateInstantiation), Entity(0),
+ TemplateArgs(0), NumTemplateArgs(0) {}
+
friend bool operator==(const ActiveTemplateInstantiation &X,
const ActiveTemplateInstantiation &Y) {
if (X.Kind != Y.Kind)
@@ -2422,7 +2924,9 @@ public:
case DefaultTemplateArgumentInstantiation:
case ExplicitTemplateArgumentSubstitution:
case DeducedTemplateArgumentSubstitution:
+ case DefaultFunctionArgumentInstantiation:
return X.TemplateArgs == Y.TemplateArgs;
+
}
return true;
@@ -2440,7 +2944,7 @@ public:
/// requires another template instantiation, additional
/// instantiations are pushed onto the stack up to a
/// user-configurable limit LangOptions::InstantiationDepth.
- llvm::SmallVector<ActiveTemplateInstantiation, 16>
+ llvm::SmallVector<ActiveTemplateInstantiation, 16>
ActiveTemplateInstantiations;
/// \brief The last template from which a template instantiation
@@ -2486,7 +2990,7 @@ public:
unsigned NumTemplateArgs,
ActiveTemplateInstantiation::InstantiationKind Kind,
SourceRange InstantiationRange = SourceRange());
-
+
/// \brief Note that we are instantiating as part of template
/// argument deduction for a class template partial
/// specialization.
@@ -2496,6 +3000,12 @@ public:
unsigned NumTemplateArgs,
SourceRange InstantiationRange = SourceRange());
+ InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
+ ParmVarDecl *Param,
+ const TemplateArgument *TemplateArgs,
+ unsigned NumTemplateArgs,
+ SourceRange InstantiationRange = SourceRange());
+
/// \brief Note that we have finished instantiating this template.
void Clear();
@@ -2514,7 +3024,7 @@ public:
InstantiatingTemplate(const InstantiatingTemplate&); // not implemented
- InstantiatingTemplate&
+ InstantiatingTemplate&
operator=(const InstantiatingTemplate&); // not implemented
};
@@ -2541,8 +3051,8 @@ public:
~SFINAETrap() { SemaRef.NumSFINAEErrors = PrevSFINAEErrors; }
/// \brief Determine whether any SFINAE errors have been trapped.
- bool hasErrorOccurred() const {
- return SemaRef.NumSFINAEErrors > PrevSFINAEErrors;
+ bool hasErrorOccurred() const {
+ return SemaRef.NumSFINAEErrors > PrevSFINAEErrors;
}
};
@@ -2584,7 +3094,7 @@ public:
public:
LocalInstantiationScope(Sema &SemaRef)
- : SemaRef(SemaRef), Outer(SemaRef.CurrentInstantiationScope) {
+ : SemaRef(SemaRef), Outer(SemaRef.CurrentInstantiationScope) {
SemaRef.CurrentInstantiationScope = this;
}
@@ -2619,85 +3129,89 @@ public:
/// \brief An entity for which implicit template instantiation is required.
///
- /// The source location associated with the declaration is the first place in
+ /// The source location associated with the declaration is the first place in
/// the source code where the declaration was "used". It is not necessarily
- /// the point of instantiation (which will be either before or after the
+ /// the point of instantiation (which will be either before or after the
/// namespace-scope declaration that triggered this implicit instantiation),
/// However, it is the location that diagnostics should generally refer to,
/// because users will need to know what code triggered the instantiation.
typedef std::pair<ValueDecl *, SourceLocation> PendingImplicitInstantiation;
-
+
/// \brief The queue of implicit template instantiations that are required
/// but have not yet been performed.
std::deque<PendingImplicitInstantiation> PendingImplicitInstantiations;
void PerformPendingImplicitInstantiations();
-
- QualType InstantiateType(QualType T, const TemplateArgumentList &TemplateArgs,
- SourceLocation Loc, DeclarationName Entity);
-
- OwningExprResult InstantiateExpr(Expr *E,
- const TemplateArgumentList &TemplateArgs);
- OwningStmtResult InstantiateStmt(Stmt *S,
- const TemplateArgumentList &TemplateArgs);
- OwningStmtResult InstantiateCompoundStmt(CompoundStmt *S,
- const TemplateArgumentList &TemplateArgs,
- bool isStmtExpr);
+ QualType SubstType(QualType T,
+ const MultiLevelTemplateArgumentList &TemplateArgs,
+ SourceLocation Loc, DeclarationName Entity);
- Decl *InstantiateDecl(Decl *D, DeclContext *Owner,
- const TemplateArgumentList &TemplateArgs);
+ OwningExprResult SubstExpr(Expr *E,
+ const MultiLevelTemplateArgumentList &TemplateArgs);
- bool
- InstantiateBaseSpecifiers(CXXRecordDecl *Instantiation,
- CXXRecordDecl *Pattern,
- const TemplateArgumentList &TemplateArgs);
+ OwningStmtResult SubstStmt(Stmt *S,
+ const MultiLevelTemplateArgumentList &TemplateArgs);
+
+ Decl *SubstDecl(Decl *D, DeclContext *Owner,
+ const MultiLevelTemplateArgumentList &TemplateArgs);
+
+ bool
+ SubstBaseSpecifiers(CXXRecordDecl *Instantiation,
+ CXXRecordDecl *Pattern,
+ const MultiLevelTemplateArgumentList &TemplateArgs);
bool
InstantiateClass(SourceLocation PointOfInstantiation,
CXXRecordDecl *Instantiation, CXXRecordDecl *Pattern,
- const TemplateArgumentList &TemplateArgs,
- bool ExplicitInstantiation);
+ const MultiLevelTemplateArgumentList &TemplateArgs,
+ TemplateSpecializationKind TSK,
+ bool Complain = true);
- bool
+ bool
InstantiateClassTemplateSpecialization(
ClassTemplateSpecializationDecl *ClassTemplateSpec,
- bool ExplicitInstantiation);
+ TemplateSpecializationKind TSK,
+ bool Complain = true);
void InstantiateClassMembers(SourceLocation PointOfInstantiation,
CXXRecordDecl *Instantiation,
- const TemplateArgumentList &TemplateArgs);
+ const MultiLevelTemplateArgumentList &TemplateArgs,
+ TemplateSpecializationKind TSK);
void InstantiateClassTemplateSpecializationMembers(
SourceLocation PointOfInstantiation,
- ClassTemplateSpecializationDecl *ClassTemplateSpec);
+ ClassTemplateSpecializationDecl *ClassTemplateSpec,
+ TemplateSpecializationKind TSK);
NestedNameSpecifier *
- InstantiateNestedNameSpecifier(NestedNameSpecifier *NNS,
- SourceRange Range,
- const TemplateArgumentList &TemplateArgs);
+ SubstNestedNameSpecifier(NestedNameSpecifier *NNS,
+ SourceRange Range,
+ const MultiLevelTemplateArgumentList &TemplateArgs);
TemplateName
- InstantiateTemplateName(TemplateName Name, SourceLocation Loc,
- const TemplateArgumentList &TemplateArgs);
- TemplateArgument Instantiate(TemplateArgument Arg,
- const TemplateArgumentList &TemplateArgs);
+ SubstTemplateName(TemplateName Name, SourceLocation Loc,
+ const MultiLevelTemplateArgumentList &TemplateArgs);
+ TemplateArgument Subst(TemplateArgument Arg,
+ const MultiLevelTemplateArgumentList &TemplateArgs);
void InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
FunctionDecl *Function,
bool Recursive = false);
- void InstantiateVariableDefinition(VarDecl *Var);
+ void InstantiateStaticDataMemberDefinition(
+ SourceLocation PointOfInstantiation,
+ VarDecl *Var,
+ bool Recursive = false);
+
+ void InstantiateMemInitializers(CXXConstructorDecl *New,
+ const CXXConstructorDecl *Tmpl,
+ const MultiLevelTemplateArgumentList &TemplateArgs);
+
+ NamedDecl *FindInstantiatedDecl(NamedDecl *D,
+ const MultiLevelTemplateArgumentList &TemplateArgs);
+ DeclContext *FindInstantiatedContext(DeclContext *DC,
+ const MultiLevelTemplateArgumentList &TemplateArgs);
- NamedDecl *InstantiateCurrentDeclRef(NamedDecl *D);
-
- // Simple function for cloning expressions.
- template<typename T>
- OwningExprResult Clone(T *E) {
- assert(!E->isValueDependent() && !E->isTypeDependent() &&
- "expression is value or type dependent!");
- return Owned(E->Clone(Context));
- }
-
// Objective-C declarations.
virtual DeclPtrTy ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
IdentifierInfo *ClassName,
@@ -2708,7 +3222,7 @@ public:
unsigned NumProtoRefs,
SourceLocation EndProtoLoc,
AttributeList *AttrList);
-
+
virtual DeclPtrTy ActOnCompatiblityAlias(
SourceLocation AtCompatibilityAliasLoc,
IdentifierInfo *AliasName, SourceLocation AliasLocation,
@@ -2718,14 +3232,14 @@ public:
IdentifierInfo *PName,
SourceLocation &PLoc, SourceLocation PrevLoc,
const ObjCList<ObjCProtocolDecl> &PList);
-
+
virtual DeclPtrTy ActOnStartProtocolInterface(
SourceLocation AtProtoInterfaceLoc,
IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc,
const DeclPtrTy *ProtoRefNames, unsigned NumProtoRefs,
SourceLocation EndProtoLoc,
AttributeList *AttrList);
-
+
virtual DeclPtrTy ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
IdentifierInfo *ClassName,
SourceLocation ClassLoc,
@@ -2734,78 +3248,82 @@ public:
const DeclPtrTy *ProtoRefs,
unsigned NumProtoRefs,
SourceLocation EndProtoLoc);
-
+
virtual DeclPtrTy ActOnStartClassImplementation(
SourceLocation AtClassImplLoc,
IdentifierInfo *ClassName, SourceLocation ClassLoc,
- IdentifierInfo *SuperClassname,
+ IdentifierInfo *SuperClassname,
SourceLocation SuperClassLoc);
-
+
virtual DeclPtrTy ActOnStartCategoryImplementation(
SourceLocation AtCatImplLoc,
- IdentifierInfo *ClassName,
+ IdentifierInfo *ClassName,
SourceLocation ClassLoc,
IdentifierInfo *CatName,
SourceLocation CatLoc);
-
+
virtual DeclPtrTy ActOnForwardClassDeclaration(SourceLocation Loc,
IdentifierInfo **IdentList,
unsigned NumElts);
-
+
virtual DeclPtrTy ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,
const IdentifierLocPair *IdentList,
unsigned NumElts,
AttributeList *attrList);
-
+
virtual void FindProtocolDeclaration(bool WarnOnDeclarations,
const IdentifierLocPair *ProtocolId,
unsigned NumProtocols,
llvm::SmallVectorImpl<DeclPtrTy> &Protocols);
-
- /// Ensure attributes are consistent with type.
+
+ /// Ensure attributes are consistent with type.
/// \param [in, out] Attributes The attributes to check; they will
/// be modified to be consistent with \arg PropertyTy.
- void CheckObjCPropertyAttributes(QualType PropertyTy,
+ void CheckObjCPropertyAttributes(QualType PropertyTy,
SourceLocation Loc,
unsigned &Attributes);
void ProcessPropertyDecl(ObjCPropertyDecl *property, ObjCContainerDecl *DC);
- void DiagnosePropertyMismatch(ObjCPropertyDecl *Property,
+ void DiagnosePropertyMismatch(ObjCPropertyDecl *Property,
ObjCPropertyDecl *SuperProperty,
const IdentifierInfo *Name);
void ComparePropertiesInBaseAndSuper(ObjCInterfaceDecl *IDecl);
-
+
+ void CompareMethodParamsInBaseAndSuper(Decl *IDecl,
+ ObjCMethodDecl *MethodDecl,
+ bool IsInstance);
+
void MergeProtocolPropertiesIntoClass(Decl *CDecl,
DeclPtrTy MergeProtocols);
-
- void DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT,
+
+ void DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT,
ObjCInterfaceDecl *ID);
-
+
void MergeOneProtocolPropertiesIntoClass(Decl *CDecl,
ObjCProtocolDecl *PDecl);
-
+
virtual void ActOnAtEnd(SourceLocation AtEndLoc, DeclPtrTy classDecl,
DeclPtrTy *allMethods = 0, unsigned allNum = 0,
DeclPtrTy *allProperties = 0, unsigned pNum = 0,
DeclGroupPtrTy *allTUVars = 0, unsigned tuvNum = 0);
-
+
virtual DeclPtrTy ActOnProperty(Scope *S, SourceLocation AtLoc,
FieldDeclarator &FD, ObjCDeclSpec &ODS,
Selector GetterSel, Selector SetterSel,
DeclPtrTy ClassCategory,
bool *OverridingProperty,
tok::ObjCKeywordKind MethodImplKind);
-
- virtual DeclPtrTy ActOnPropertyImplDecl(SourceLocation AtLoc,
+
+ virtual DeclPtrTy ActOnPropertyImplDecl(SourceLocation AtLoc,
SourceLocation PropertyLoc,
bool ImplKind,DeclPtrTy ClassImplDecl,
IdentifierInfo *PropertyId,
IdentifierInfo *PropertyIvar);
-
+
virtual DeclPtrTy ActOnMethodDeclaration(
SourceLocation BeginLoc, // location of the + or -.
SourceLocation EndLoc, // location of the ; or {.
- tok::TokenKind MethodType,
- DeclPtrTy ClassDecl, ObjCDeclSpec &ReturnQT, TypeTy *ReturnType,
+ tok::TokenKind MethodType,
+ DeclPtrTy ClassDecl, ObjCDeclSpec &ReturnQT, TypeTy *ReturnType,
Selector Sel,
// optional arguments. The number of types/arguments is obtained
// from the Sel.getNumArgs().
@@ -2818,24 +3336,24 @@ public:
// Will search "local" class/category implementations for a method decl.
// Will also search in class's root looking for instance method.
// Returns 0 if no method is found.
- ObjCMethodDecl *LookupPrivateClassMethod(Selector Sel,
+ ObjCMethodDecl *LookupPrivateClassMethod(Selector Sel,
ObjCInterfaceDecl *CDecl);
ObjCMethodDecl *LookupPrivateInstanceMethod(Selector Sel,
ObjCInterfaceDecl *ClassDecl);
-
+
virtual OwningExprResult ActOnClassPropertyRefExpr(
IdentifierInfo &receiverName,
IdentifierInfo &propertyName,
SourceLocation &receiverNameLoc,
SourceLocation &propertyNameLoc);
-
+
// ActOnClassMessage - used for both unary and keyword messages.
// ArgExprs is optional - if it is present, the number of expressions
// is obtained from NumArgs.
virtual ExprResult ActOnClassMessage(
Scope *S,
- IdentifierInfo *receivingClassName, Selector Sel, SourceLocation lbrac,
- SourceLocation receiverLoc, SourceLocation selectorLoc,SourceLocation rbrac,
+ IdentifierInfo *receivingClassName, Selector Sel, SourceLocation lbrac,
+ SourceLocation receiverLoc, SourceLocation selectorLoc,SourceLocation rbrac,
ExprTy **ArgExprs, unsigned NumArgs);
// ActOnInstanceMessage - used for both unary and keyword messages.
@@ -2843,23 +3361,27 @@ public:
// is obtained from NumArgs.
virtual ExprResult ActOnInstanceMessage(
ExprTy *receiver, Selector Sel,
- SourceLocation lbrac, SourceLocation receiverLoc, SourceLocation rbrac,
+ SourceLocation lbrac, SourceLocation receiverLoc, SourceLocation rbrac,
ExprTy **ArgExprs, unsigned NumArgs);
-
+
/// ActOnPragmaPack - Called on well formed #pragma pack(...).
virtual void ActOnPragmaPack(PragmaPackKind Kind,
IdentifierInfo *Name,
ExprTy *Alignment,
- SourceLocation PragmaLoc,
+ SourceLocation PragmaLoc,
SourceLocation LParenLoc,
SourceLocation RParenLoc);
-
+
/// ActOnPragmaUnused - Called on well-formed '#pragma unused'.
- virtual void ActOnPragmaUnused(ExprTy **Exprs, unsigned NumExprs,
- SourceLocation PragmaLoc,
+ virtual void ActOnPragmaUnused(const Token *Identifiers,
+ unsigned NumIdentifiers, Scope *curScope,
+ SourceLocation PragmaLoc,
SourceLocation LParenLoc,
SourceLocation RParenLoc);
+ NamedDecl *DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II);
+ void DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W);
+
/// ActOnPragmaWeakID - Called on well formed #pragma weak ident.
virtual void ActOnPragmaWeakID(IdentifierInfo* WeakName,
SourceLocation PragmaLoc,
@@ -2875,25 +3397,27 @@ public:
/// getPragmaPackAlignment() - Return the current alignment as specified by
/// the current #pragma pack directive, or 0 if none is currently active.
unsigned getPragmaPackAlignment() const;
-
+
/// FreePackedContext - Deallocate and null out PackContext.
void FreePackedContext();
/// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit
/// cast. If there is already an implicit cast, merge into the existing one.
/// If isLvalue, the result of the cast is an lvalue.
- void ImpCastExprToType(Expr *&Expr, QualType Type, bool isLvalue = false);
+ void ImpCastExprToType(Expr *&Expr, QualType Type,
+ CastExpr::CastKind Kind = CastExpr::CK_Unknown,
+ bool isLvalue = false);
// UsualUnaryConversions - promotes integers (C99 6.3.1.1p2) and converts
// functions and arrays to their respective pointers (C99 6.3.2.1).
- Expr *UsualUnaryConversions(Expr *&expr);
+ Expr *UsualUnaryConversions(Expr *&expr);
// DefaultFunctionArrayConversion - converts functions and arrays
- // to their respective pointers (C99 6.3.2.1).
+ // to their respective pointers (C99 6.3.2.1).
void DefaultFunctionArrayConversion(Expr *&expr);
-
+
// DefaultArgumentPromotion (C99 6.5.2.2p6). Used for function calls that
- // do not have a prototype. Integer promotions are performed on each
+ // do not have a prototype. Integer promotions are performed on each
// argument, and arguments that have type float are promoted to double.
void DefaultArgumentPromotion(Expr *&Expr);
@@ -2901,26 +3425,21 @@ public:
enum VariadicCallType {
VariadicFunction,
VariadicBlock,
- VariadicMethod
+ VariadicMethod,
+ VariadicConstructor
};
-
+
// DefaultVariadicArgumentPromotion - Like DefaultArgumentPromotion, but
// will warn if the resulting type is not a POD type.
bool DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT);
-
+
// UsualArithmeticConversions - performs the UsualUnaryConversions on it's
// operands and then handles various conversions that are common to binary
// operators (C99 6.3.1.8). If both operands aren't arithmetic, this
- // routine returns the first non-arithmetic type found. The client is
+ // routine returns the first non-arithmetic type found. The client is
// responsible for emitting appropriate error diagnostics.
QualType UsualArithmeticConversions(Expr *&lExpr, Expr *&rExpr,
bool isCompAssign = false);
-
- /// UsualArithmeticConversionsType - handles the various conversions
- /// that are common to binary operators (C99 6.3.1.8, C++ [expr]p9)
- /// and returns the result type of that conversion.
- QualType UsualArithmeticConversionsType(QualType lhs, QualType rhs);
-
/// AssignConvertType - All of the 'assignment' semantic checks return this
/// enum to indicate whether the assignment was allowed. These checks are
@@ -2930,15 +3449,15 @@ public:
enum AssignConvertType {
/// Compatible - the types are compatible according to the standard.
Compatible,
-
+
/// PointerToInt - The assignment converts a pointer to an int, which we
/// accept as an extension.
PointerToInt,
-
+
/// IntToPointer - The assignment converts an int to a pointer, which we
/// accept as an extension.
IntToPointer,
-
+
/// FunctionVoidPointer - The assignment is between a function pointer and
/// void*, which the standard doesn't allow, but we accept as an extension.
FunctionVoidPointer,
@@ -2960,25 +3479,25 @@ public:
/// IncompatibleVectors - The assignment is between two vector types that
/// have the same size, which we accept as an extension.
IncompatibleVectors,
-
- /// IntToBlockPointer - The assignment converts an int to a block
+
+ /// IntToBlockPointer - The assignment converts an int to a block
/// pointer. We disallow this.
IntToBlockPointer,
- /// IncompatibleBlockPointer - The assignment is between two block
+ /// IncompatibleBlockPointer - The assignment is between two block
/// pointers types that are not compatible.
IncompatibleBlockPointer,
-
+
/// IncompatibleObjCQualifiedId - The assignment is between a qualified
/// id type and something else (that is incompatible with it). For example,
/// "id <XXX>" = "Foo *", where "Foo *" doesn't implement the XXX protocol.
IncompatibleObjCQualifiedId,
-
+
/// Incompatible - We reject this conversion outright, it is invalid to
/// represent it in the AST.
Incompatible
};
-
+
/// DiagnoseAssignmentResult - Emit a diagnostic, if required, for the
/// assignment conversion type specified by ConvTy. This returns true if the
/// conversion was invalid or false if the conversion was accepted.
@@ -2986,39 +3505,46 @@ public:
SourceLocation Loc,
QualType DstType, QualType SrcType,
Expr *SrcExpr, const char *Flavor);
-
- /// CheckAssignmentConstraints - Perform type checking for assignment,
- /// argument passing, variable initialization, and function return values.
+
+ /// CheckAssignmentConstraints - Perform type checking for assignment,
+ /// argument passing, variable initialization, and function return values.
/// This routine is only used by the following two methods. C99 6.5.16.
AssignConvertType CheckAssignmentConstraints(QualType lhs, QualType rhs);
-
- // CheckSingleAssignmentConstraints - Currently used by
- // CheckAssignmentOperands, and ActOnReturnStmt. Prior to type checking,
+
+ // CheckSingleAssignmentConstraints - Currently used by
+ // CheckAssignmentOperands, and ActOnReturnStmt. Prior to type checking,
// this routine performs the default function/array converions.
- AssignConvertType CheckSingleAssignmentConstraints(QualType lhs,
+ AssignConvertType CheckSingleAssignmentConstraints(QualType lhs,
Expr *&rExpr);
// \brief If the lhs type is a transparent union, check whether we
// can initialize the transparent union with the given expression.
- AssignConvertType CheckTransparentUnionArgumentConstraints(QualType lhs,
+ AssignConvertType CheckTransparentUnionArgumentConstraints(QualType lhs,
Expr *&rExpr);
-
+
// Helper function for CheckAssignmentConstraints (C99 6.5.16.1p1)
- AssignConvertType CheckPointerTypesForAssignment(QualType lhsType,
+ AssignConvertType CheckPointerTypesForAssignment(QualType lhsType,
QualType rhsType);
-
+
// Helper function for CheckAssignmentConstraints involving two
// block pointer types.
- AssignConvertType CheckBlockPointerTypesForAssignment(QualType lhsType,
+ AssignConvertType CheckBlockPointerTypesForAssignment(QualType lhsType,
QualType rhsType);
bool IsStringLiteralToNonConstPointerConversion(Expr *From, QualType ToType);
- bool PerformImplicitConversion(Expr *&From, QualType ToType,
+ bool CheckExceptionSpecCompatibility(Expr *From, QualType ToType);
+
+ bool PerformImplicitConversion(Expr *&From, QualType ToType,
const char *Flavor,
bool AllowExplicit = false,
bool Elidable = false);
- bool PerformImplicitConversion(Expr *&From, QualType ToType,
+ bool PerformImplicitConversion(Expr *&From, QualType ToType,
+ const char *Flavor,
+ bool AllowExplicit,
+ bool Elidable,
+ ImplicitConversionSequence& ICS);
+ bool PerformImplicitConversion(Expr *&From, QualType ToType,
const ImplicitConversionSequence& ICS,
const char *Flavor);
bool PerformImplicitConversion(Expr *&From, QualType ToType,
@@ -3065,7 +3591,7 @@ public:
inline QualType CheckVectorOperands(SourceLocation l, Expr *&lex, Expr *&rex);
inline QualType CheckVectorCompareOperands(Expr *&lex, Expr *&rx,
SourceLocation l, bool isRel);
-
+
/// type checking unary operators (subroutines of ActOnUnaryOp).
/// C99 6.5.3.1, 6.5.3.2, 6.5.3.4
QualType CheckIncrementDecrementOperand(Expr *op, SourceLocation OpLoc,
@@ -3073,19 +3599,20 @@ public:
QualType CheckAddressOfOperand(Expr *op, SourceLocation OpLoc);
QualType CheckIndirectionOperand(Expr *op, SourceLocation OpLoc);
QualType CheckRealImagOperand(Expr *&Op, SourceLocation OpLoc, bool isReal);
-
+
/// type checking primary expressions.
QualType CheckExtVectorComponent(QualType baseType, SourceLocation OpLoc,
- IdentifierInfo &Comp, SourceLocation CmpLoc);
-
+ const IdentifierInfo *Comp,
+ SourceLocation CmpLoc);
+
/// type checking declaration initializers (C99 6.7.8)
-
+
bool CheckInitializerTypes(Expr *&simpleInit_or_initList, QualType &declType,
SourceLocation InitLoc,DeclarationName InitEntity,
bool DirectInit);
bool CheckInitList(InitListExpr *&InitList, QualType &DeclType);
bool CheckForConstantInitializer(Expr *e, QualType t);
-
+
bool CheckValueInitialization(QualType Type, SourceLocation Loc);
// type checking C++ declaration initializers (C++ [dcl.init]).
@@ -3115,48 +3642,70 @@ public:
bool& DerivedToBase);
bool CheckReferenceInit(Expr *&simpleInit_or_initList, QualType declType,
- ImplicitConversionSequence *ICS = 0,
- bool SuppressUserConversions = false,
- bool AllowExplicit = false,
- bool ForceRValue = false);
-
- /// CheckCastTypes - Check type constraints for casting between types.
- bool CheckCastTypes(SourceRange TyRange, QualType CastTy, Expr *&CastExpr);
-
- // CheckVectorCast - check type constraints for vectors.
+ SourceLocation DeclLoc,
+ bool SuppressUserConversions,
+ bool AllowExplicit,
+ bool ForceRValue,
+ ImplicitConversionSequence *ICS = 0);
+
+ /// CheckCastTypes - Check type constraints for casting between types under
+ /// C semantics, or forward to CXXCheckCStyleCast in C++.
+ bool CheckCastTypes(SourceRange TyRange, QualType CastTy, Expr *&CastExpr,
+ CastExpr::CastKind &Kind,
+ CXXMethodDecl *& ConversionDecl,
+ bool FunctionalStyle = false);
+
+ // CheckVectorCast - check type constraints for vectors.
// Since vectors are an extension, there are no C standard reference for this.
// We allow casting between vectors and integer datatypes of the same size.
// returns true if the cast is invalid
bool CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty);
-
- // CheckExtVectorCast - check type constraints for extended vectors.
+
+ // CheckExtVectorCast - check type constraints for extended vectors.
// Since vectors are an extension, there are no C standard reference for this.
// We allow casting between vectors and integer datatypes of the same size,
// or vectors and the element type of that vector.
// returns true if the cast is invalid
bool CheckExtVectorCast(SourceRange R, QualType VectorTy, QualType Ty);
-
- /// CheckMessageArgumentTypes - Check types in an Obj-C message send.
+
+ /// CXXCheckCStyleCast - Check constraints of a C-style or function-style
+ /// cast under C++ semantics.
+ bool CXXCheckCStyleCast(SourceRange R, QualType CastTy, Expr *&CastExpr,
+ CastExpr::CastKind &Kind, bool FunctionalStyle,
+ CXXMethodDecl *&ConversionDecl);
+
+ /// CheckMessageArgumentTypes - Check types in an Obj-C message send.
/// \param Method - May be null.
/// \param [out] ReturnType - The return type of the send.
/// \return true iff there were any incompatible types.
bool CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs, Selector Sel,
ObjCMethodDecl *Method, bool isClassMessage,
SourceLocation lbrac, SourceLocation rbrac,
- QualType &ReturnType);
+ QualType &ReturnType);
+
+ /// CheckBooleanCondition - Diagnose problems involving the use of
+ /// the given expression as a boolean condition (e.g. in an if
+ /// statement). Also performs the standard function and array
+ /// decays, possibly changing the input variable.
+ ///
+ /// \param Loc - A location associated with the condition, e.g. the
+ /// 'if' keyword.
+ /// \return true iff there were any errors
+ bool CheckBooleanCondition(Expr *&CondExpr, SourceLocation Loc);
+
+ /// DiagnoseAssignmentAsCondition - Given that an expression is
+ /// being used as a boolean condition, warn if it's an assignment.
+ void DiagnoseAssignmentAsCondition(Expr *E);
/// CheckCXXBooleanCondition - Returns true if conversion to bool is invalid.
bool CheckCXXBooleanCondition(Expr *&CondExpr);
-
+
/// ConvertIntegerToTypeWarnOnOverflow - Convert the specified APInt to have
/// the specified width and sign. If an overflow occurs, detect it and emit
/// the specified diagnostic.
- void ConvertIntegerToTypeWarnOnOverflow(llvm::APSInt &OldVal,
+ void ConvertIntegerToTypeWarnOnOverflow(llvm::APSInt &OldVal,
unsigned NewWidth, bool NewSign,
SourceLocation Loc, unsigned DiagID);
-
- bool ObjCQualifiedIdTypesAreCompatible(QualType LHS, QualType RHS,
- bool ForCompare);
/// Checks that the Objective-C declaration is declared in the global scope.
/// Emits an error and marks the declaration as invalid if it's not declared
@@ -3171,23 +3720,67 @@ public:
bool VerifyIntegerConstantExpression(const Expr *E, llvm::APSInt *Result = 0);
/// VerifyBitField - verifies that a bit field expression is an ICE and has
- /// the correct width, and that the field type is valid.
+ /// the correct width, and that the field type is valid.
/// Returns false on success.
- bool VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName,
- QualType FieldTy, const Expr *BitWidth);
+ /// Can optionally return whether the bit-field is of width 0
+ bool VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName,
+ QualType FieldTy, const Expr *BitWidth,
+ bool *ZeroWidth = 0);
+
+ /// adjustFunctionParamType - Converts the type of a function parameter to a
+ // type that can be passed as an argument type to
+ /// ASTContext::getFunctionType.
+ ///
+ /// C++ [dcl.fct]p3: "...Any cv-qualifier modifying a parameter type is
+ /// deleted. Such cv-qualifiers affect only the definition of the parameter
+ /// within the body of the function; they do not affect the function type.
+ QualType adjustFunctionParamType(QualType T) const {
+ if (!Context.getLangOptions().CPlusPlus)
+ return T;
+ return
+ T->isDependentType() ? T.getUnqualifiedType()
+ : T.getDesugaredType().getUnqualifiedType();
+
+ }
+ /// \name Code completion
+ //@{
+ void setCodeCompleteConsumer(CodeCompleteConsumer *CCC);
+ virtual void CodeCompleteOrdinaryName(Scope *S);
+ virtual void CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *Base,
+ SourceLocation OpLoc,
+ bool IsArrow);
+ virtual void CodeCompleteTag(Scope *S, unsigned TagSpec);
+ virtual void CodeCompleteCase(Scope *S);
+ virtual void CodeCompleteCall(Scope *S, ExprTy *Fn,
+ ExprTy **Args, unsigned NumArgs);
+ virtual void CodeCompleteQualifiedId(Scope *S, const CXXScopeSpec &SS,
+ bool EnteringContext);
+ virtual void CodeCompleteUsing(Scope *S);
+ virtual void CodeCompleteUsingDirective(Scope *S);
+ virtual void CodeCompleteNamespaceDecl(Scope *S);
+ virtual void CodeCompleteNamespaceAliasDecl(Scope *S);
+ virtual void CodeCompleteOperatorName(Scope *S);
+
+ virtual void CodeCompleteObjCProperty(Scope *S, ObjCDeclSpec &ODS);
+ //@}
+
//===--------------------------------------------------------------------===//
// Extra semantic analysis beyond the C type system
private:
- Action::OwningExprResult CheckFunctionCall(FunctionDecl *FDecl,
- CallExpr *TheCall);
-
- Action::OwningExprResult CheckBlockCall(NamedDecl *NDecl, CallExpr *TheCall);
+ bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall);
+ bool CheckBlockCall(NamedDecl *NDecl, CallExpr *TheCall);
+
SourceLocation getLocationOfStringLiteralByte(const StringLiteral *SL,
unsigned ByteNo) const;
+ bool CheckablePrintfAttr(const FormatAttr *Format, CallExpr *TheCall);
bool CheckObjCString(Expr *Arg);
+
+ Action::OwningExprResult CheckBuiltinFunctionCall(unsigned BuiltinID,
+ CallExpr *TheCall);
bool SemaBuiltinVAStart(CallExpr *TheCall);
bool SemaBuiltinUnorderedCompare(CallExpr *TheCall);
+ bool SemaBuiltinUnaryFP(CallExpr *TheCall);
bool SemaBuiltinStackAddress(CallExpr *TheCall);
public:
@@ -3195,19 +3788,20 @@ public:
Action::OwningExprResult SemaBuiltinShuffleVector(CallExpr *TheCall);
private:
- bool SemaBuiltinPrefetch(CallExpr *TheCall);
+ bool SemaBuiltinPrefetch(CallExpr *TheCall);
bool SemaBuiltinObjectSize(CallExpr *TheCall);
bool SemaBuiltinLongjmp(CallExpr *TheCall);
bool SemaBuiltinAtomicOverloaded(CallExpr *TheCall);
+ bool SemaBuiltinEHReturnDataRegNo(CallExpr *TheCall);
bool SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall,
bool HasVAListArg, unsigned format_idx,
unsigned firstDataArg);
void CheckPrintfString(const StringLiteral *FExpr, const Expr *OrigFormatExpr,
const CallExpr *TheCall, bool HasVAListArg,
unsigned format_idx, unsigned firstDataArg);
- void CheckNonNullArguments(const NonNullAttr *NonNull,
+ void CheckNonNullArguments(const NonNullAttr *NonNull,
const CallExpr *TheCall);
- void CheckPrintfArguments(const CallExpr *TheCall, bool HasVAListArg,
+ void CheckPrintfArguments(const CallExpr *TheCall, bool HasVAListArg,
unsigned format_idx, unsigned firstDataArg);
void CheckReturnStackAddr(Expr *RetValExp, QualType lhsType,
SourceLocation ReturnLoc);
@@ -3221,12 +3815,12 @@ template <typename T>
class ExprOwningPtr : public Action::ExprArg {
public:
ExprOwningPtr(Sema *S, T *expr) : Action::ExprArg(*S, expr) {}
-
+
void reset(T* p) { Action::ExprArg::operator=(p); }
T* get() const { return static_cast<T*>(Action::ExprArg::get()); }
T* take() { return static_cast<T*>(Action::ExprArg::take()); }
T* release() { return take(); }
-
+
T& operator*() const { return *get(); }
T* operator->() const { return get(); }
};