diff options
Diffstat (limited to 'lib/Sema/Sema.h')
-rw-r--r-- | lib/Sema/Sema.h | 1874 |
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(); } }; |