From 5362a71c02e7d448a8ce98cf00c47e353fba5d04 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Sat, 4 Jul 2009 13:58:54 +0000 Subject: Import Clang r74788. --- include/clang/AST/ASTContext.h | 22 +- include/clang/AST/CFG.h | 17 +- include/clang/AST/Decl.h | 86 +- include/clang/AST/DeclBase.h | 81 +- include/clang/AST/DeclCXX.h | 112 +- include/clang/AST/DeclObjC.h | 135 +- include/clang/AST/DeclTemplate.h | 1200 ++++++------ include/clang/AST/Expr.h | 9 +- include/clang/AST/ExprCXX.h | 94 + include/clang/AST/ExternalASTSource.h | 9 + include/clang/AST/NestedNameSpecifier.h | 3 +- include/clang/AST/PrettyPrinter.h | 10 +- include/clang/AST/Stmt.h | 10 +- include/clang/AST/StmtNodes.def | 3 +- include/clang/AST/Type.h | 6 +- include/clang/Analysis/PathSensitive/MemRegion.h | 59 +- include/clang/Analysis/PathSensitive/SVals.h | 2 + .../clang/Analysis/PathSensitive/ValueManager.h | 11 +- include/clang/Basic/DiagnosticDriverKinds.td | 4 + include/clang/Basic/DiagnosticSemaKinds.td | 26 + include/clang/Basic/LangOptions.h | 25 +- include/clang/Basic/TargetInfo.h | 4 +- include/clang/Basic/TokenKinds.def | 6 +- include/clang/CodeGen/ModuleBuilder.h | 4 +- include/clang/Driver/Action.h | 2 + include/clang/Driver/ArgList.h | 2 + include/clang/Driver/Compilation.h | 33 +- include/clang/Driver/Driver.h | 8 + include/clang/Driver/HostInfo.h | 2 + include/clang/Driver/Job.h | 10 +- include/clang/Driver/Options.def | 5 +- include/clang/Frontend/ASTConsumers.h | 4 +- include/clang/Frontend/PCHBitCodes.h | 6 +- include/clang/Frontend/PCHReader.h | 14 + include/clang/Frontend/PCHWriter.h | 1 + include/clang/Lex/Preprocessor.h | 24 + include/clang/Parse/Action.h | 24 + include/clang/Parse/Ownership.h | 19 + include/clang/Parse/Parser.h | 3 +- lib/AST/ASTContext.cpp | 277 ++- lib/AST/CFG.cpp | 61 +- lib/AST/Decl.cpp | 94 +- lib/AST/DeclBase.cpp | 114 +- lib/AST/DeclCXX.cpp | 63 +- lib/AST/DeclObjC.cpp | 103 +- lib/AST/DeclPrinter.cpp | 36 +- lib/AST/DeclTemplate.cpp | 27 +- lib/AST/Expr.cpp | 33 +- lib/AST/ExprCXX.cpp | 60 + lib/AST/ExprConstant.cpp | 69 +- lib/AST/NestedNameSpecifier.cpp | 6 +- lib/AST/StmtDumper.cpp | 4 +- lib/AST/StmtPrinter.cpp | 24 +- lib/AST/TemplateName.cpp | 8 +- lib/AST/Type.cpp | 26 +- lib/Analysis/BasicStore.cpp | 104 +- lib/Analysis/BugReporter.cpp | 7 +- lib/Analysis/CFRefCount.cpp | 57 +- lib/Analysis/CheckDeadStores.cpp | 4 +- lib/Analysis/CheckObjCDealloc.cpp | 14 +- lib/Analysis/CheckObjCInstMethSignature.cpp | 8 +- lib/Analysis/CheckObjCUnusedIVars.cpp | 15 +- lib/Analysis/Environment.cpp | 15 +- lib/Analysis/GRExprEngine.cpp | 15 +- lib/Analysis/GRExprEngineInternalChecks.cpp | 2 +- lib/Analysis/GRState.cpp | 6 +- lib/Analysis/LiveVariables.cpp | 3 +- lib/Analysis/MemRegion.cpp | 46 +- lib/Analysis/RegionStore.cpp | 135 +- lib/Analysis/SVals.cpp | 7 + lib/Analysis/Store.cpp | 6 +- lib/Basic/IdentifierTable.cpp | 2 +- lib/Basic/TargetInfo.cpp | 1 + lib/Basic/Targets.cpp | 510 ++--- lib/CodeGen/CGBuiltin.cpp | 4 +- lib/CodeGen/CGCXX.cpp | 4 +- lib/CodeGen/CGCall.cpp | 27 +- lib/CodeGen/CGDebugInfo.cpp | 9 +- lib/CodeGen/CGDecl.cpp | 12 +- lib/CodeGen/CGExpr.cpp | 4 +- lib/CodeGen/CGExprAgg.cpp | 8 +- lib/CodeGen/CGExprConstant.cpp | 8 +- lib/CodeGen/CGObjC.cpp | 6 +- lib/CodeGen/CGObjCGNU.cpp | 41 +- lib/CodeGen/CGObjCMac.cpp | 67 +- lib/CodeGen/CodeGenFunction.cpp | 4 +- lib/CodeGen/CodeGenModule.cpp | 105 +- lib/CodeGen/CodeGenModule.h | 3 +- lib/CodeGen/CodeGenTypes.cpp | 10 +- lib/CodeGen/Mangle.cpp | 34 +- lib/CodeGen/ModuleBuilder.cpp | 10 +- lib/CodeGen/TargetABIInfo.cpp | 24 +- lib/Driver/ArgList.cpp | 29 + lib/Driver/Compilation.cpp | 43 +- lib/Driver/Driver.cpp | 50 + lib/Driver/HostInfo.cpp | 57 + lib/Driver/Job.cpp | 6 +- lib/Driver/ToolChains.cpp | 30 + lib/Driver/ToolChains.h | 7 + lib/Driver/Tools.cpp | 148 +- lib/Driver/Tools.h | 34 + lib/Frontend/ASTConsumers.cpp | 15 +- lib/Frontend/AnalysisConsumer.cpp | 12 +- lib/Frontend/Backend.cpp | 11 +- lib/Frontend/DeclXML.cpp | 10 +- lib/Frontend/InitHeaderSearch.cpp | 8 + lib/Frontend/InitPreprocessor.cpp | 9 +- lib/Frontend/PCHReader.cpp | 14 +- lib/Frontend/PCHReaderDecl.cpp | 2 +- lib/Frontend/PCHReaderStmt.cpp | 1 - lib/Frontend/PCHWriter.cpp | 33 +- lib/Frontend/PCHWriterDecl.cpp | 6 +- lib/Frontend/PCHWriterStmt.cpp | 1 - lib/Frontend/ResolveLocation.cpp | 8 +- lib/Frontend/RewriteBlocks.cpp | 33 +- lib/Frontend/RewriteObjC.cpp | 131 +- lib/Lex/Lexer.cpp | 9 +- lib/Lex/Pragma.cpp | 1 + lib/Lex/Preprocessor.cpp | 23 + lib/Parse/ParseDecl.cpp | 8 +- lib/Parse/ParseDeclCXX.cpp | 25 +- lib/Parse/ParseExpr.cpp | 15 +- lib/Parse/ParseExprCXX.cpp | 29 +- lib/Parse/Parser.cpp | 17 + lib/Rewrite/Rewriter.cpp | 2 +- lib/Sema/JumpDiagnostics.cpp | 6 +- lib/Sema/Sema.cpp | 4 + lib/Sema/Sema.h | 92 +- lib/Sema/SemaAttr.cpp | 2 +- lib/Sema/SemaChecking.cpp | 55 +- lib/Sema/SemaDecl.cpp | 93 +- lib/Sema/SemaDeclAttr.cpp | 111 +- lib/Sema/SemaDeclCXX.cpp | 168 +- lib/Sema/SemaDeclObjC.cpp | 155 +- lib/Sema/SemaExpr.cpp | 575 +++--- lib/Sema/SemaExprCXX.cpp | 8 +- lib/Sema/SemaExprObjC.cpp | 34 +- lib/Sema/SemaInherit.cpp | 4 +- lib/Sema/SemaInit.cpp | 29 +- lib/Sema/SemaLookup.cpp | 42 +- lib/Sema/SemaOverload.cpp | 72 +- lib/Sema/SemaStmt.cpp | 6 +- lib/Sema/SemaTemplate.cpp | 55 +- lib/Sema/SemaTemplateDeduction.cpp | 134 +- lib/Sema/SemaTemplateInstantiate.cpp | 102 +- lib/Sema/SemaTemplateInstantiateDecl.cpp | 124 +- lib/Sema/SemaTemplateInstantiateExpr.cpp | 59 +- lib/Sema/SemaType.cpp | 79 +- test/Analysis/array-struct.c | 27 +- test/Analysis/concrete-address.c | 7 + test/Analysis/misc-ps.m | 19 +- test/Analysis/stack-addr-ps.c | 16 + test/Analysis/xfail_regionstore_wine_crash.c | 3 +- test/CMakeLists.txt | 3 +- test/CXX/basic/basic.def.odr/p2-typeid.cpp | 2 +- .../temp/temp.fct.spec/temp.arg.explicit/p1.cpp | 12 + .../temp/temp.fct.spec/temp.arg.explicit/p3.cpp | 11 + .../temp/temp.fct.spec/temp.deduct/sfinae-1.cpp | 17 + test/CodeGen/attributes.c | 2 +- test/CodeGen/stack-protector.c | 22 + test/CodeGen/unwind-attr.c | 4 +- .../function-template-specialization.cpp | 27 + test/Driver/openbsd.c | 6 + test/Index/comments.c | 30 + test/PCH/pr4489.c | 20 + test/Parser/offsetof.c | 7 + test/Sema/compare.c | 14 + test/Sema/ext_vector_casts.c | 22 + test/Sema/format-attr-pr4470.c | 11 + test/SemaCXX/class-base-member-init.cpp | 19 + test/SemaCXX/constructor-initializer.cpp | 39 + test/SemaCXX/decltype-overloaded-functions.cpp | 12 + test/SemaCXX/exception-spec.cpp | 30 +- test/SemaCXX/member-pointer.cpp | 2 +- .../class-template-ctor-initializer.cpp | 33 + test/SemaTemplate/operator-template.cpp | 6 +- .../recursive-template-instantiation.cpp | 10 + test/cxx-sections.data | 2063 ++++++++++---------- tools/clang-cc/clang-cc.cpp | 28 +- tools/driver/driver.cpp | 2 +- tools/index-test/index-test.cpp | 7 +- utils/test/TestRunner.py | 3 +- www/analyzer/latest_checker.html.incl | 2 +- www/cxx_status.html | 1 + 184 files changed, 6056 insertions(+), 3756 deletions(-) create mode 100644 test/Analysis/concrete-address.c create mode 100644 test/CXX/temp/temp.fct.spec/temp.arg.explicit/p1.cpp create mode 100644 test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp create mode 100644 test/CXX/temp/temp.fct.spec/temp.deduct/sfinae-1.cpp create mode 100644 test/CodeGen/stack-protector.c create mode 100644 test/CodeGenCXX/function-template-specialization.cpp create mode 100644 test/Driver/openbsd.c create mode 100644 test/Index/comments.c create mode 100644 test/PCH/pr4489.c create mode 100644 test/Parser/offsetof.c create mode 100644 test/Sema/format-attr-pr4470.c create mode 100644 test/SemaCXX/class-base-member-init.cpp create mode 100644 test/SemaCXX/decltype-overloaded-functions.cpp create mode 100644 test/SemaTemplate/class-template-ctor-initializer.cpp create mode 100644 test/SemaTemplate/recursive-template-instantiation.cpp diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index aa01b7fdf06f..041a0f33ad4d 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -141,10 +141,19 @@ class ASTContext { /// this ASTContext object. LangOptions LangOpts; + /// \brief Whether we have already loaded comment source ranges from an + /// external source. + bool LoadedExternalComments; + /// MallocAlloc/BumpAlloc - The allocator objects used to create AST objects. bool FreeMemory; llvm::MallocAllocator MallocAlloc; llvm::BumpPtrAllocator BumpAlloc; + + /// \brief Mapping from declarations to their comments, once we have + /// already looked up the comment associated with a given declaration. + llvm::DenseMap DeclComments; + public: TargetInfo &Target; IdentifierTable &Idents; @@ -154,6 +163,10 @@ public: llvm::OwningPtr ExternalSource; clang::PrintingPolicy PrintingPolicy; + /// \brief Source ranges for all of the comments in the source file, + /// sorted in order of appearance in the translation unit. + std::vector Comments; + SourceManager& getSourceManager() { return SourceMgr; } const SourceManager& getSourceManager() const { return SourceMgr; } void *Allocate(unsigned Size, unsigned Align = 8) { @@ -178,7 +191,8 @@ public: TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; } - + const char *getCommentForDecl(const Decl *D); + // Builtin Types. QualType VoidTy; QualType BoolTy; @@ -351,12 +365,6 @@ public: ObjCProtocolDecl **ProtocolList, unsigned NumProtocols); - /// getObjCQualifiedIdType - Return an ObjCQualifiedIdType for a - /// given 'id' and conforming protocol list. - QualType getObjCQualifiedIdType(ObjCProtocolDecl **ProtocolList, - unsigned NumProtocols); - - /// getTypeOfType - GCC extension. QualType getTypeOfExprType(Expr *e); QualType getTypeOfType(QualType t); diff --git a/include/clang/AST/CFG.h b/include/clang/AST/CFG.h index 7a9ee01d4f62..e60e58e1ac23 100644 --- a/include/clang/AST/CFG.h +++ b/include/clang/AST/CFG.h @@ -17,17 +17,20 @@ #include "llvm/ADT/GraphTraits.h" #include "llvm/Support/Allocator.h" -#include "llvm/Support/raw_ostream.h" #include #include #include +namespace llvm { + class raw_ostream; +} namespace clang { class Stmt; class Expr; class CFG; class PrinterHelper; class BlockEdge; + class LangOptions; /// CFGBlock - Represents a single basic block in a source-level CFG. /// It consists of: @@ -181,9 +184,9 @@ public: unsigned getBlockID() const { return BlockID; } - void dump(const CFG* cfg) const; - void print(llvm::raw_ostream& OS, const CFG* cfg) const; - void printTerminator(llvm::raw_ostream& OS) const; + void dump(const CFG *cfg, const LangOptions &LO) const; + void print(llvm::raw_ostream &OS, const CFG* cfg, const LangOptions &LO) const; + void printTerminator(llvm::raw_ostream &OS, const LangOptions &LO) const; }; @@ -283,9 +286,9 @@ public: // CFG Debugging: Pretty-Printing and Visualization. //===--------------------------------------------------------------------===// - void viewCFG() const; - void print(llvm::raw_ostream& OS) const; - void dump() const; + void viewCFG(const LangOptions &LO) const; + void print(llvm::raw_ostream& OS, const LangOptions &LO) const; + void dump(const LangOptions &LO) const; //===--------------------------------------------------------------------===// // Internal: constructors and data. diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 3de01f3baeb5..69a52869d818 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -26,13 +26,19 @@ class Stmt; class CompoundStmt; class StringLiteral; class TemplateArgumentList; +class FunctionTemplateSpecializationInfo; /// TranslationUnitDecl - The top declaration context. class TranslationUnitDecl : public Decl, public DeclContext { - TranslationUnitDecl() + ASTContext &Ctx; + + explicit TranslationUnitDecl(ASTContext &ctx) : Decl(TranslationUnit, 0, SourceLocation()), - DeclContext(TranslationUnit) {} + DeclContext(TranslationUnit), + Ctx(ctx) {} public: + ASTContext &getASTContext() const { return Ctx; } + static TranslationUnitDecl *Create(ASTContext &C); // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return D->getKind() == TranslationUnit; } @@ -621,15 +627,8 @@ public: enum StorageClass { None, Extern, Static, PrivateExtern }; -private: - /// \brief Provides information about a function template specialization, - /// which is a FunctionDecl that has been explicitly specialization or - /// instantiated from a function template. - struct TemplateSpecializationInfo { - FunctionTemplateDecl *Template; - const TemplateArgumentList *TemplateArguments; - }; +private: /// ParamInfo - new[]'d array of pointers to VarDecls for the formal /// parameters of this function. This is null if a prototype or if there are /// no formals. @@ -684,7 +683,8 @@ private: /// the template being specialized and the template arguments involved in /// that specialization. llvm::PointerUnion3 TemplateOrSpecialization; + FunctionTemplateSpecializationInfo*> + TemplateOrSpecialization; protected: FunctionDecl(Kind DK, DeclContext *DC, SourceLocation L, @@ -724,11 +724,11 @@ public: /// function. The variant that accepts a FunctionDecl pointer will /// set that function declaration to the actual declaration /// containing the body (if there is one). - Stmt *getBody(ASTContext &Context, const FunctionDecl *&Definition) const; + Stmt *getBody(const FunctionDecl *&Definition) const; - virtual Stmt *getBody(ASTContext &Context) const { + virtual Stmt *getBody() const { const FunctionDecl* Definition; - return getBody(Context, Definition); + return getBody(Definition); } /// \brief If the function has a body that is immediately available, @@ -809,9 +809,7 @@ public: return PreviousDeclaration; } - void setPreviousDeclaration(FunctionDecl * PrevDecl) { - PreviousDeclaration = PrevDecl; - } + void setPreviousDeclaration(FunctionDecl * PrevDecl); unsigned getBuiltinID(ASTContext &Context) const; @@ -940,27 +938,14 @@ public: /// /// If this function declaration is not a function template specialization, /// returns NULL. - FunctionTemplateDecl *getPrimaryTemplate() const { - if (TemplateSpecializationInfo *Info - = TemplateOrSpecialization.dyn_cast()) { - return Info->Template; - } - return 0; - } + FunctionTemplateDecl *getPrimaryTemplate() const; /// \brief Retrieve the template arguments used to produce this function /// template specialization from the primary template. /// /// If this function declaration is not a function template specialization, /// returns NULL. - const TemplateArgumentList *getTemplateSpecializationArgs() const { - if (TemplateSpecializationInfo *Info - = TemplateOrSpecialization.dyn_cast()) { - return Info->TemplateArguments; - } - return 0; - } - + const TemplateArgumentList *getTemplateSpecializationArgs() const; /// \brief Specify that this function declaration is actually a function /// template specialization. @@ -974,8 +959,17 @@ public: /// function template specialization from the template. void setFunctionTemplateSpecialization(ASTContext &Context, FunctionTemplateDecl *Template, - const TemplateArgumentList *TemplateArgs); - + const TemplateArgumentList *TemplateArgs, + void *InsertPos); + + /// \brief Determine whether this is an explicit specialization of a + /// function template or a member function of a class template. + bool isExplicitSpecialization() const; + + /// \brief Note that this is an explicit specialization of a function template + /// or a member function of a class template. + void setExplicitSpecialization(bool ES); + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return D->getKind() >= FunctionFirst && D->getKind() <= FunctionLast; @@ -1268,12 +1262,12 @@ public: // enumeration. typedef specific_decl_iterator enumerator_iterator; - enumerator_iterator enumerator_begin(ASTContext &Context) const { - return enumerator_iterator(this->decls_begin(Context)); + enumerator_iterator enumerator_begin() const { + return enumerator_iterator(this->decls_begin()); } - enumerator_iterator enumerator_end(ASTContext &Context) const { - return enumerator_iterator(this->decls_end(Context)); + enumerator_iterator enumerator_end() const { + return enumerator_iterator(this->decls_end()); } /// getIntegerType - Return the integer type this enum decl corresponds to. @@ -1376,17 +1370,17 @@ public: // data members, functions, constructors, destructors, etc. typedef specific_decl_iterator field_iterator; - field_iterator field_begin(ASTContext &Context) const { - return field_iterator(decls_begin(Context)); + field_iterator field_begin() const { + return field_iterator(decls_begin()); } - field_iterator field_end(ASTContext &Context) const { - return field_iterator(decls_end(Context)); + field_iterator field_end() const { + return field_iterator(decls_end()); } // field_empty - Whether there are any fields (non-static data // members) in this record. - bool field_empty(ASTContext &Context) const { - return field_begin(Context) == field_end(Context); + bool field_empty() const { + return field_begin() == field_end(); } /// completeDefinition - Notes that the definition of this type is @@ -1448,8 +1442,8 @@ public: bool IsVariadic() const { return isVariadic; } void setIsVariadic(bool value) { isVariadic = value; } - CompoundStmt *getBody() const { return (CompoundStmt*) Body; } - Stmt *getBody(ASTContext &C) const { return (Stmt*) Body; } + CompoundStmt *getCompoundBody() const { return (CompoundStmt*) Body; } + Stmt *getBody() const { return (Stmt*) Body; } void setBody(CompoundStmt *B) { Body = (Stmt*) B; } // Iterator access to formal parameters. diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index c959b05473fe..0bce2f84c7ba 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -213,6 +213,13 @@ public: const DeclContext *getDeclContext() const { return const_cast(this)->getDeclContext(); } + + TranslationUnitDecl *getTranslationUnitDecl(); + const TranslationUnitDecl *getTranslationUnitDecl() const { + return const_cast(this)->getTranslationUnitDecl(); + } + + ASTContext &getASTContext() const; void setAccess(AccessSpecifier AS) { Access = AS; @@ -225,23 +232,23 @@ public: } bool hasAttrs() const { return HasAttrs; } - void addAttr(ASTContext &Context, Attr *attr); - const Attr *getAttrs(ASTContext &Context) const { + void addAttr(Attr *attr); + const Attr *getAttrs() const { if (!HasAttrs) return 0; // common case, no attributes. - return getAttrsImpl(Context); // Uncommon case, out of line hash lookup. + return getAttrsImpl(); // Uncommon case, out of line hash lookup. } - void swapAttrs(ASTContext &Context, Decl *D); - void invalidateAttrs(ASTContext &Context); + void swapAttrs(Decl *D); + void invalidateAttrs(); - template const T *getAttr(ASTContext &Context) const { - for (const Attr *attr = getAttrs(Context); attr; attr = attr->getNext()) + template const T *getAttr() const { + for (const Attr *attr = getAttrs(); attr; attr = attr->getNext()) if (const T *V = dyn_cast(attr)) return V; return 0; } - template bool hasAttr(ASTContext &Context) const { - return getAttr(Context) != 0; + template bool hasAttr() const { + return getAttr() != 0; } /// setInvalidDecl - Indicates the Decl had a semantic error. This @@ -307,14 +314,14 @@ public: /// getBody - If this Decl represents a declaration for a body of code, /// such as a function or method definition, this method returns the /// top-level Stmt* of that body. Otherwise this method returns null. - virtual Stmt* getBody(ASTContext &Context) const { return 0; } + virtual Stmt* getBody() const { return 0; } /// getCompoundBody - Returns getBody(), dyn_casted to a CompoundStmt. - CompoundStmt* getCompoundBody(ASTContext &Context) const; + CompoundStmt* getCompoundBody() const; /// getBodyRBrace - Gets the right brace of the body, if a body exists. /// This works whether the body is a CompoundStmt or a CXXTryStmt. - SourceLocation getBodyRBrace(ASTContext &Context) const; + SourceLocation getBodyRBrace() const; // global temp stats (until we have a per-module visitor) static void addDeclKind(Kind k); @@ -340,18 +347,16 @@ public: /// Destroy - Call destructors and release memory. virtual void Destroy(ASTContext& C); - void print(llvm::raw_ostream &Out, ASTContext &Context, + void print(llvm::raw_ostream &Out, unsigned Indentation = 0); + void print(llvm::raw_ostream &Out, const PrintingPolicy &Policy, unsigned Indentation = 0); - void print(llvm::raw_ostream &Out, ASTContext &Context, - const PrintingPolicy &Policy, unsigned Indentation = 0); static void printGroup(Decl** Begin, unsigned NumDecls, - llvm::raw_ostream &Out, ASTContext &Context, - const PrintingPolicy &Policy, + llvm::raw_ostream &Out, const PrintingPolicy &Policy, unsigned Indentation = 0); - void dump(ASTContext &Context); + void dump(); private: - const Attr *getAttrsImpl(ASTContext &Context) const; + const Attr *getAttrsImpl() const; }; @@ -454,7 +459,11 @@ public: const DeclContext *getLexicalParent() const { return const_cast(this)->getLexicalParent(); } - + + ASTContext &getParentASTContext() const { + return cast(this)->getASTContext(); + } + bool isFunctionOrMethod() const { switch (DeclKind) { case Decl::Block: @@ -592,9 +601,9 @@ public: /// decls_begin/decls_end - Iterate over the declarations stored in /// this context. - decl_iterator decls_begin(ASTContext &Context) const; - decl_iterator decls_end(ASTContext &Context) const; - bool decls_empty(ASTContext &Context) const; + decl_iterator decls_begin() const; + decl_iterator decls_end() const; + bool decls_empty() const; /// specific_decl_iterator - Iterates over a subrange of /// declarations stored in a DeclContext, providing only those that @@ -750,7 +759,7 @@ public: /// /// If D is also a NamedDecl, it will be made visible within its /// semantic context via makeDeclVisibleInContext. - void addDecl(ASTContext &Context, Decl *D); + void addDecl(Decl *D); /// lookup_iterator - An iterator that provides access to the results /// of looking up a name within this context. @@ -769,8 +778,8 @@ public: /// the declarations with this name, with object, function, member, /// and enumerator names preceding any tag name. Note that this /// routine will not look into parent contexts. - lookup_result lookup(ASTContext &Context, DeclarationName Name); - lookup_const_result lookup(ASTContext &Context, DeclarationName Name) const; + lookup_result lookup(DeclarationName Name); + lookup_const_result lookup(DeclarationName Name) const; /// @brief Makes a declaration visible within this context. /// @@ -786,7 +795,7 @@ public: /// visible from this context, as determined by /// NamedDecl::declarationReplaces, the previous declaration will be /// replaced with D. - void makeDeclVisibleInContext(ASTContext &Context, NamedDecl *D); + void makeDeclVisibleInContext(NamedDecl *D); /// udir_iterator - Iterates through the using-directives stored /// within this context. @@ -794,14 +803,14 @@ public: typedef std::pair udir_iterator_range; - udir_iterator_range getUsingDirectives(ASTContext &Context) const; + udir_iterator_range getUsingDirectives() const; - udir_iterator using_directives_begin(ASTContext &Context) const { - return getUsingDirectives(Context).first; + udir_iterator using_directives_begin() const { + return getUsingDirectives().first; } - udir_iterator using_directives_end(ASTContext &Context) const { - return getUsingDirectives(Context).second; + udir_iterator using_directives_end() const { + return getUsingDirectives().second; } // Low-level accessors @@ -836,11 +845,11 @@ public: #include "clang/AST/DeclNodes.def" private: - void LoadLexicalDeclsFromExternalStorage(ASTContext &Context) const; - void LoadVisibleDeclsFromExternalStorage(ASTContext &Context) const; + void LoadLexicalDeclsFromExternalStorage() const; + void LoadVisibleDeclsFromExternalStorage() const; - void buildLookup(ASTContext &Context, DeclContext *DCtx); - void makeDeclVisibleInContextImpl(ASTContext &Context, NamedDecl *D); + void buildLookup(DeclContext *DCtx); + void makeDeclVisibleInContextImpl(NamedDecl *D); }; inline bool Decl::isTemplateParameter() const { diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index a2fe24e83105..c523e96e03b0 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -32,6 +32,8 @@ class ClassTemplateSpecializationDecl; class AnyFunctionDecl { NamedDecl *Function; + AnyFunctionDecl(NamedDecl *ND) : Function(ND) { } + public: AnyFunctionDecl(FunctionDecl *FD) : Function(FD) { } AnyFunctionDecl(FunctionTemplateDecl *FTD); @@ -42,6 +44,10 @@ public: /// \brief Retrieve the underlying function or function template. NamedDecl *get() const { return Function; } + + static AnyFunctionDecl getFromNamedDecl(NamedDecl *ND) { + return AnyFunctionDecl(ND); + } }; } // end namespace clang @@ -57,6 +63,22 @@ namespace llvm { }; template<> struct simplify_type< ::clang::AnyFunctionDecl> : public simplify_type {}; + + // Provide PointerLikeTypeTraits for non-cvr pointers. + template<> + class PointerLikeTypeTraits< ::clang::AnyFunctionDecl> { + public: + static inline void *getAsVoidPointer(::clang::AnyFunctionDecl F) { + return F.get(); + } + static inline ::clang::AnyFunctionDecl getFromVoidPointer(void *P) { + return ::clang::AnyFunctionDecl::getFromNamedDecl( + static_cast< ::clang::NamedDecl*>(P)); + } + + enum { NumLowBitsAvailable = 2 }; + }; + } // end namespace llvm namespace clang { @@ -91,24 +113,10 @@ public: static OverloadedFunctionDecl *Create(ASTContext &C, DeclContext *DC, DeclarationName N); - /// addOverload - Add an overloaded function FD to this set of - /// overloaded functions. - void addOverload(FunctionDecl *FD) { - assert((FD->getDeclName() == getDeclName() || - isa(FD) || isa(FD)) && - "Overloaded functions must have the same name"); - Functions.push_back(FD); - - // An overloaded function declaration always has the location of - // the most-recently-added function declaration. - if (FD->getLocation().isValid()) - this->setLocation(FD->getLocation()); - } + /// \brief Add a new overloaded function or function template to the set + /// of overloaded function templates. + void addOverload(AnyFunctionDecl F); - /// addOverload - Add an overloaded function template FTD to this set of - /// overloaded functions. - void addOverload(FunctionTemplateDecl *FTD); - function_iterator function_begin() { return Functions.begin(); } function_iterator function_end() { return Functions.end(); } function_const_iterator function_begin() const { return Functions.begin(); } @@ -289,8 +297,11 @@ public: CXXRecordDecl* PrevDecl=0, bool DelayTypeCreation = false); + virtual void Destroy(ASTContext& C); + /// setBases - Sets the base classes of this struct or class. - void setBases(CXXBaseSpecifier const * const *Bases, unsigned NumBases); + void setBases(ASTContext &C, + CXXBaseSpecifier const * const *Bases, unsigned NumBases); /// getNumBases - Retrieves the number of base classes of this /// class. @@ -580,15 +591,20 @@ class CXXBaseOrMemberInitializer { /// Args - The arguments used to initialize the base or member. Expr **Args; unsigned NumArgs; + + /// IdLoc - Location of the id in ctor-initializer list. + SourceLocation IdLoc; public: /// CXXBaseOrMemberInitializer - Creates a new base-class initializer. explicit - CXXBaseOrMemberInitializer(QualType BaseType, Expr **Args, unsigned NumArgs); + CXXBaseOrMemberInitializer(QualType BaseType, Expr **Args, unsigned NumArgs, + SourceLocation L); /// CXXBaseOrMemberInitializer - Creates a new member initializer. explicit - CXXBaseOrMemberInitializer(FieldDecl *Member, Expr **Args, unsigned NumArgs); + CXXBaseOrMemberInitializer(FieldDecl *Member, Expr **Args, unsigned NumArgs, + SourceLocation L); /// ~CXXBaseOrMemberInitializer - Destroy the base or member initializer. ~CXXBaseOrMemberInitializer(); @@ -601,6 +617,10 @@ public: /// arguments. typedef Expr * const * arg_const_iterator; + /// getBaseOrMember - get the generic 'member' representing either the field + /// or a base class. + void* getBaseOrMember() const { return reinterpret_cast(BaseOrMember); } + /// isBaseInitializer - Returns true when this initializer is /// initializing a base class. bool isBaseInitializer() const { return (BaseOrMember & 0x1) != 0; } @@ -641,6 +661,8 @@ public: return 0; } + SourceLocation getSourceLocation() const { return IdLoc; } + /// begin() - Retrieve an iterator to the first initializer argument. arg_iterator begin() { return Args; } /// begin() - Retrieve an iterator to the first initializer argument. @@ -677,16 +699,22 @@ class CXXConstructorDecl : public CXXMethodDecl { /// @c !Implicit && ImplicitlyDefined. bool ImplicitlyDefined : 1; - /// FIXME: Add support for base and member initializers. - + /// Support for base and member initializers. + /// BaseOrMemberInitializers - The arguments used to initialize the base + /// or member. + CXXBaseOrMemberInitializer **BaseOrMemberInitializers; + unsigned NumBaseOrMemberInitializers; + CXXConstructorDecl(CXXRecordDecl *RD, SourceLocation L, DeclarationName N, QualType T, bool isExplicit, bool isInline, bool isImplicitlyDeclared) : CXXMethodDecl(CXXConstructor, RD, L, N, T, false, isInline), - Explicit(isExplicit), ImplicitlyDefined(false) { + Explicit(isExplicit), ImplicitlyDefined(false), + BaseOrMemberInitializers(0), NumBaseOrMemberInitializers(0) { setImplicit(isImplicitlyDeclared); } - + virtual void Destroy(ASTContext& C); + public: static CXXConstructorDecl *Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation L, DeclarationName N, @@ -702,7 +730,8 @@ public: /// already been defined. bool isImplicitlyDefined(ASTContext &C) const { assert(isThisDeclarationADefinition() && - "Can only get the implicit-definition flag once the constructor has been defined"); + "Can only get the implicit-definition flag once the " + "constructor has been defined"); return ImplicitlyDefined; } @@ -710,10 +739,41 @@ public: /// implicitly defined or not. void setImplicitlyDefined(bool ID) { assert(isThisDeclarationADefinition() && - "Can only set the implicit-definition flag once the constructor has been defined"); + "Can only set the implicit-definition flag once the constructor " + "has been defined"); ImplicitlyDefined = ID; } + /// init_iterator - Iterates through the member/base initializer list. + typedef CXXBaseOrMemberInitializer **init_iterator; + + /// init_const_iterator - Iterates through the memberbase initializer list. + typedef CXXBaseOrMemberInitializer * const * init_const_iterator; + + /// begin() - Retrieve an iterator to the first initializer. + init_iterator begin() { return BaseOrMemberInitializers; } + /// begin() - Retrieve an iterator to the first initializer. + init_const_iterator begin() const { return BaseOrMemberInitializers; } + + /// end() - Retrieve an iterator past the last initializer. + init_iterator end() { + return BaseOrMemberInitializers + NumBaseOrMemberInitializers; + } + /// end() - Retrieve an iterator past the last initializer. + init_const_iterator end() const { + return BaseOrMemberInitializers + NumBaseOrMemberInitializers; + } + + /// getNumArgs - Determine the number of arguments used to + /// initialize the member or base. + unsigned getNumBaseOrMemberInitializers() const { + return NumBaseOrMemberInitializers; + } + + void setBaseOrMemberInitializers(ASTContext &C, + CXXBaseOrMemberInitializer **Initializers, + unsigned NumInitializers); + /// isDefaultConstructor - Whether this constructor is a default /// constructor (C++ [class.ctor]p5), which can be used to /// default-initialize a class of this type. diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index 3943ddc19638..2fcdaa3e2959 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -242,10 +242,10 @@ public: return ImplementationControl(DeclImplementation); } - virtual Stmt *getBody(ASTContext &C) const { + virtual Stmt *getBody() const { return (Stmt*) Body; } - CompoundStmt *getBody() { return (CompoundStmt*)Body; } + CompoundStmt *getCompoundBody() { return (CompoundStmt*)Body; } void setBody(Stmt *B) { Body = B; } // Implement isa/cast/dyncast/etc. @@ -291,55 +291,52 @@ public: // Iterator access to properties. typedef specific_decl_iterator prop_iterator; - prop_iterator prop_begin(ASTContext &Context) const { - return prop_iterator(decls_begin(Context)); + prop_iterator prop_begin() const { + return prop_iterator(decls_begin()); } - prop_iterator prop_end(ASTContext &Context) const { - return prop_iterator(decls_end(Context)); + prop_iterator prop_end() const { + return prop_iterator(decls_end()); } // Iterator access to instance/class methods. typedef specific_decl_iterator method_iterator; - method_iterator meth_begin(ASTContext &Context) const { - return method_iterator(decls_begin(Context)); + method_iterator meth_begin() const { + return method_iterator(decls_begin()); } - method_iterator meth_end(ASTContext &Context) const { - return method_iterator(decls_end(Context)); + method_iterator meth_end() const { + return method_iterator(decls_end()); } typedef filtered_decl_iterator instmeth_iterator; - instmeth_iterator instmeth_begin(ASTContext &Context) const { - return instmeth_iterator(decls_begin(Context)); + instmeth_iterator instmeth_begin() const { + return instmeth_iterator(decls_begin()); } - instmeth_iterator instmeth_end(ASTContext &Context) const { - return instmeth_iterator(decls_end(Context)); + instmeth_iterator instmeth_end() const { + return instmeth_iterator(decls_end()); } typedef filtered_decl_iterator classmeth_iterator; - classmeth_iterator classmeth_begin(ASTContext &Context) const { - return classmeth_iterator(decls_begin(Context)); + classmeth_iterator classmeth_begin() const { + return classmeth_iterator(decls_begin()); } - classmeth_iterator classmeth_end(ASTContext &Context) const { - return classmeth_iterator(decls_end(Context)); + classmeth_iterator classmeth_end() const { + return classmeth_iterator(decls_end()); } // Get the local instance/class method declared in this interface. - ObjCMethodDecl *getInstanceMethod(ASTContext &Context, Selector Sel) const; - ObjCMethodDecl *getClassMethod(ASTContext &Context, Selector Sel) const; - ObjCIvarDecl *getIvarDecl(ASTContext &Context, IdentifierInfo *Id) const; + ObjCMethodDecl *getInstanceMethod(Selector Sel) const; + ObjCMethodDecl *getClassMethod(Selector Sel) const; + ObjCIvarDecl *getIvarDecl(IdentifierInfo *Id) const; - ObjCMethodDecl * - getMethod(ASTContext &Context, Selector Sel, bool isInstance) const { - return isInstance ? getInstanceMethod(Context, Sel) - : getClassMethod(Context, Sel); + ObjCMethodDecl *getMethod(Selector Sel, bool isInstance) const { + return isInstance ? getInstanceMethod(Sel) : getClassMethod(Sel); } - ObjCPropertyDecl *FindPropertyDeclaration(ASTContext &Context, - IdentifierInfo *PropertyId) const; + ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const; // Marks the end of the container. SourceLocation getAtEndLoc() const { return AtEndLoc; } @@ -474,19 +471,17 @@ public: return false; } - ObjCIvarDecl *lookupInstanceVariable(ASTContext &Context, - IdentifierInfo *IVarName, + ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName, ObjCInterfaceDecl *&ClassDeclared); - ObjCIvarDecl *lookupInstanceVariable(ASTContext &Context, - IdentifierInfo *IVarName) { + ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName) { ObjCInterfaceDecl *ClassDeclared; - return lookupInstanceVariable(Context, IVarName, ClassDeclared); + return lookupInstanceVariable(IVarName, ClassDeclared); } // Lookup a method. First, we search locally. If a method isn't // found, we search referenced protocols and class categories. - ObjCMethodDecl *lookupInstanceMethod(ASTContext &Context, Selector Sel); - ObjCMethodDecl *lookupClassMethod(ASTContext &Context, Selector Sel); + ObjCMethodDecl *lookupInstanceMethod(Selector Sel); + ObjCMethodDecl *lookupClassMethod(Selector Sel); ObjCInterfaceDecl *lookupInheritedClass(const IdentifierInfo *ICName); // Location information, modeled after the Stmt API. @@ -648,8 +643,8 @@ public: // Lookup a method. First, we search locally. If a method isn't // found, we search referenced protocols and class categories. - ObjCMethodDecl *lookupInstanceMethod(ASTContext &Context, Selector Sel); - ObjCMethodDecl *lookupClassMethod(ASTContext &Context, Selector Sel); + ObjCMethodDecl *lookupInstanceMethod(Selector Sel); + ObjCMethodDecl *lookupClassMethod(Selector Sel); bool isForwardDecl() const { return isForwardProtoDecl; } void setForwardDecl(bool val) { isForwardProtoDecl = val; } @@ -831,61 +826,57 @@ public: ObjCInterfaceDecl *getClassInterface() { return ClassInterface; } void setClassInterface(ObjCInterfaceDecl *IFace) { ClassInterface = IFace; } - void addInstanceMethod(ASTContext &Context, ObjCMethodDecl *method) { + void addInstanceMethod(ObjCMethodDecl *method) { // FIXME: Context should be set correctly before we get here. method->setLexicalDeclContext(this); - addDecl(Context, method); + addDecl(method); } - void addClassMethod(ASTContext &Context, ObjCMethodDecl *method) { + void addClassMethod(ObjCMethodDecl *method) { // FIXME: Context should be set correctly before we get here. method->setLexicalDeclContext(this); - addDecl(Context, method); + addDecl(method); } // Get the local instance/class method declared in this interface. - ObjCMethodDecl *getInstanceMethod(ASTContext &Context, Selector Sel) const; - ObjCMethodDecl *getClassMethod(ASTContext &Context, Selector Sel) const; - ObjCMethodDecl *getMethod(ASTContext &Context, Selector Sel, - bool isInstance) const { - return isInstance ? getInstanceMethod(Context, Sel) - : getClassMethod(Context, Sel); + ObjCMethodDecl *getInstanceMethod(Selector Sel) const; + ObjCMethodDecl *getClassMethod(Selector Sel) const; + ObjCMethodDecl *getMethod(Selector Sel, bool isInstance) const { + return isInstance ? getInstanceMethod(Sel) + : getClassMethod(Sel); } - void addPropertyImplementation(ASTContext &Context, - ObjCPropertyImplDecl *property); + void addPropertyImplementation(ObjCPropertyImplDecl *property); - ObjCPropertyImplDecl *FindPropertyImplDecl(ASTContext &Context, - IdentifierInfo *propertyId) const; - ObjCPropertyImplDecl *FindPropertyImplIvarDecl(ASTContext &Context, - IdentifierInfo *ivarId) const; + ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId) const; + ObjCPropertyImplDecl *FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const; // Iterator access to properties. typedef specific_decl_iterator propimpl_iterator; - propimpl_iterator propimpl_begin(ASTContext &Context) const { - return propimpl_iterator(decls_begin(Context)); + propimpl_iterator propimpl_begin() const { + return propimpl_iterator(decls_begin()); } - propimpl_iterator propimpl_end(ASTContext &Context) const { - return propimpl_iterator(decls_end(Context)); + propimpl_iterator propimpl_end() const { + return propimpl_iterator(decls_end()); } typedef filtered_decl_iterator instmeth_iterator; - instmeth_iterator instmeth_begin(ASTContext &Context) const { - return instmeth_iterator(decls_begin(Context)); + instmeth_iterator instmeth_begin() const { + return instmeth_iterator(decls_begin()); } - instmeth_iterator instmeth_end(ASTContext &Context) const { - return instmeth_iterator(decls_end(Context)); + instmeth_iterator instmeth_end() const { + return instmeth_iterator(decls_end()); } typedef filtered_decl_iterator classmeth_iterator; - classmeth_iterator classmeth_begin(ASTContext &Context) const { - return classmeth_iterator(decls_begin(Context)); + classmeth_iterator classmeth_begin() const { + return classmeth_iterator(decls_begin()); } - classmeth_iterator classmeth_end(ASTContext &Context) const { - return classmeth_iterator(decls_end(Context)); + classmeth_iterator classmeth_end() const { + return classmeth_iterator(decls_end()); } // Location information, modeled after the Stmt API. @@ -1002,17 +993,17 @@ public: void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; } typedef specific_decl_iterator ivar_iterator; - ivar_iterator ivar_begin(ASTContext &Context) const { - return ivar_iterator(decls_begin(Context)); + ivar_iterator ivar_begin() const { + return ivar_iterator(decls_begin()); } - ivar_iterator ivar_end(ASTContext &Context) const { - return ivar_iterator(decls_end(Context)); + ivar_iterator ivar_end() const { + return ivar_iterator(decls_end()); } - unsigned ivar_size(ASTContext &Context) const { - return std::distance(ivar_begin(Context), ivar_end(Context)); + unsigned ivar_size() const { + return std::distance(ivar_begin(), ivar_end()); } - bool ivar_empty(ASTContext &Context) const { - return ivar_begin(Context) == ivar_end(Context); + bool ivar_empty() const { + return ivar_begin() == ivar_end(); } static bool classof(const Decl *D) { diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index aad19a63ef0f..5d0fe158e054 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -100,6 +100,352 @@ public: } }; +/// \brief Represents a template argument within a class template +/// specialization. +class TemplateArgument { + union { + uintptr_t TypeOrValue; + struct { + char Value[sizeof(llvm::APSInt)]; + void *Type; + } Integer; + struct { + TemplateArgument *Args; + unsigned NumArgs; + bool CopyArgs; + } Args; + }; + + /// \brief Location of the beginning of this template argument. + SourceLocation StartLoc; + +public: + /// \brief The type of template argument we're storing. + enum ArgKind { + Null = 0, + /// The template argument is a type. Its value is stored in the + /// TypeOrValue field. + Type = 1, + /// The template argument is a declaration + Declaration = 2, + /// The template argument is an integral value stored in an llvm::APSInt. + Integral = 3, + /// The template argument is a value- or type-dependent expression + /// stored in an Expr*. + Expression = 4, + + /// The template argument is actually a parameter pack. Arguments are stored + /// in the Args struct. + Pack = 5 + } Kind; + + /// \brief Construct an empty, invalid template argument. + TemplateArgument() : TypeOrValue(0), StartLoc(), Kind(Null) { } + + /// \brief Construct a template type argument. + TemplateArgument(SourceLocation Loc, QualType T) : Kind(Type) { + TypeOrValue = reinterpret_cast(T.getAsOpaquePtr()); + StartLoc = Loc; + } + + /// \brief Construct a template argument that refers to a + /// declaration, which is either an external declaration or a + /// template declaration. + TemplateArgument(SourceLocation Loc, Decl *D) : Kind(Declaration) { + // FIXME: Need to be sure we have the "canonical" declaration! + TypeOrValue = reinterpret_cast(D); + StartLoc = Loc; + } + + /// \brief Construct an integral constant template argument. + TemplateArgument(SourceLocation Loc, const llvm::APSInt &Value, + QualType Type) + : Kind(Integral) { + new (Integer.Value) llvm::APSInt(Value); + Integer.Type = Type.getAsOpaquePtr(); + StartLoc = Loc; + } + + /// \brief Construct a template argument that is an expression. + /// + /// This form of template argument only occurs in template argument + /// lists used for dependent types and for expression; it will not + /// occur in a non-dependent, canonical template argument list. + TemplateArgument(Expr *E); + + /// \brief Copy constructor for a template argument. + TemplateArgument(const TemplateArgument &Other) : Kind(Other.Kind) { + if (Kind == Integral) { + new (Integer.Value) llvm::APSInt(*Other.getAsIntegral()); + Integer.Type = Other.Integer.Type; + } else if (Kind == Pack) { + Args.NumArgs = Other.Args.NumArgs; + Args.Args = new TemplateArgument[Args.NumArgs]; + for (unsigned I = 0; I != Args.NumArgs; ++I) + Args.Args[I] = Other.Args.Args[I]; + } + else + TypeOrValue = Other.TypeOrValue; + StartLoc = Other.StartLoc; + } + + TemplateArgument& operator=(const TemplateArgument& Other) { + // FIXME: Does not provide the strong guarantee for exception + // safety. + using llvm::APSInt; + + // FIXME: Handle Packs + assert(Kind != Pack && "FIXME: Handle packs"); + assert(Other.Kind != Pack && "FIXME: Handle packs"); + + if (Kind == Other.Kind && Kind == Integral) { + // Copy integral values. + *this->getAsIntegral() = *Other.getAsIntegral(); + Integer.Type = Other.Integer.Type; + } else { + // Destroy the current integral value, if that's what we're holding. + if (Kind == Integral) + getAsIntegral()->~APSInt(); + + Kind = Other.Kind; + + if (Other.Kind == Integral) { + new (Integer.Value) llvm::APSInt(*Other.getAsIntegral()); + Integer.Type = Other.Integer.Type; + } else + TypeOrValue = Other.TypeOrValue; + } + StartLoc = Other.StartLoc; + + return *this; + } + + ~TemplateArgument() { + using llvm::APSInt; + + if (Kind == Integral) + getAsIntegral()->~APSInt(); + else if (Kind == Pack && Args.CopyArgs) + delete[] Args.Args; + } + + /// \brief Return the kind of stored template argument. + ArgKind getKind() const { return Kind; } + + /// \brief Determine whether this template argument has no value. + bool isNull() const { return Kind == Null; } + + /// \brief Retrieve the template argument as a type. + QualType getAsType() const { + if (Kind != Type) + return QualType(); + + return QualType::getFromOpaquePtr( + reinterpret_cast(TypeOrValue)); + } + + /// \brief Retrieve the template argument as a declaration. + Decl *getAsDecl() const { + if (Kind != Declaration) + return 0; + return reinterpret_cast(TypeOrValue); + } + + /// \brief Retrieve the template argument as an integral value. + llvm::APSInt *getAsIntegral() { + if (Kind != Integral) + return 0; + return reinterpret_cast(&Integer.Value[0]); + } + + const llvm::APSInt *getAsIntegral() const { + return const_cast(this)->getAsIntegral(); + } + + /// \brief Retrieve the type of the integral value. + QualType getIntegralType() const { + if (Kind != Integral) + return QualType(); + + return QualType::getFromOpaquePtr(Integer.Type); + } + + void setIntegralType(QualType T) { + assert(Kind == Integral && + "Cannot set the integral type of a non-integral template argument"); + Integer.Type = T.getAsOpaquePtr(); + }; + + /// \brief Retrieve the template argument as an expression. + Expr *getAsExpr() const { + if (Kind != Expression) + return 0; + + return reinterpret_cast(TypeOrValue); + } + + /// \brief Iterator that traverses the elements of a template argument pack. + typedef const TemplateArgument * pack_iterator; + + /// \brief Iterator referencing the first argument of a template argument + /// pack. + pack_iterator pack_begin() const { + assert(Kind == Pack); + return Args.Args; + } + + /// \brief Iterator referencing one past the last argument of a template + /// argument pack. + pack_iterator pack_end() const { + assert(Kind == Pack); + return Args.Args + Args.NumArgs; + } + + /// \brief The number of template arguments in the given template argument + /// pack. + unsigned pack_size() const { + assert(Kind == Pack); + return Args.NumArgs; + } + + /// \brief Retrieve the location where the template argument starts. + SourceLocation getLocation() const { return StartLoc; } + + /// \brief Construct a template argument pack. + void setArgumentPack(TemplateArgument *Args, unsigned NumArgs, bool CopyArgs); + + /// \brief Used to insert TemplateArguments into FoldingSets. + void Profile(llvm::FoldingSetNodeID &ID) const { + ID.AddInteger(Kind); + switch (Kind) { + case Null: + break; + + case Type: + getAsType().Profile(ID); + break; + + case Declaration: + ID.AddPointer(getAsDecl()); // FIXME: Must be canonical! + break; + + case Integral: + getAsIntegral()->Profile(ID); + getIntegralType().Profile(ID); + break; + + case Expression: + // FIXME: We need a canonical representation of expressions. + ID.AddPointer(getAsExpr()); + break; + + case Pack: + ID.AddInteger(Args.NumArgs); + for (unsigned I = 0; I != Args.NumArgs; ++I) + Args.Args[I].Profile(ID); + } + } +}; + +/// \brief A helper class for making template argument lists. +class TemplateArgumentListBuilder { + TemplateArgument *StructuredArgs; + unsigned MaxStructuredArgs; + unsigned NumStructuredArgs; + + TemplateArgument *FlatArgs; + unsigned MaxFlatArgs; + unsigned NumFlatArgs; + + bool AddingToPack; + unsigned PackBeginIndex; + +public: + TemplateArgumentListBuilder(const TemplateParameterList *Parameters, + unsigned NumTemplateArgs) + : StructuredArgs(0), MaxStructuredArgs(Parameters->size()), + NumStructuredArgs(0), FlatArgs(0), + MaxFlatArgs(std::max(MaxStructuredArgs, NumTemplateArgs)), NumFlatArgs(0), + AddingToPack(false), PackBeginIndex(0) { } + + void Append(const TemplateArgument& Arg); + void BeginPack(); + void EndPack(); + + void ReleaseArgs(); + + unsigned flatSize() const { + return NumFlatArgs; + } + const TemplateArgument *getFlatArguments() const { + return FlatArgs; + } + + unsigned structuredSize() const { + // If we don't have any structured args, just reuse the flat size. + if (!StructuredArgs) + return flatSize(); + + return NumStructuredArgs; + } + const TemplateArgument *getStructuredArguments() const { + // If we don't have any structured args, just reuse the flat args. + if (!StructuredArgs) + return getFlatArguments(); + + return StructuredArgs; + } +}; + +/// \brief A template argument list. +/// +/// FIXME: In the future, this class will be extended to support +/// variadic templates and member templates, which will make some of +/// the function names below make more sense. +class TemplateArgumentList { + /// \brief The template argument list. + /// + /// The integer value will be non-zero to indicate that this + /// template argument list does not own the pointer. + llvm::PointerIntPair FlatArguments; + + /// \brief The number of template arguments in this template + /// argument list. + unsigned NumFlatArguments; + + llvm::PointerIntPair StructuredArguments; + unsigned NumStructuredArguments; + +public: + TemplateArgumentList(ASTContext &Context, + TemplateArgumentListBuilder &Builder, + bool TakeArgs); + + ~TemplateArgumentList(); + + /// \brief Retrieve the template argument at a given index. + const TemplateArgument &get(unsigned Idx) const { + assert(Idx < NumFlatArguments && "Invalid template argument index"); + return getFlatArgumentList()[Idx]; + } + + /// \brief Retrieve the template argument at a given index. + const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); } + + /// \brief Retrieve the number of template arguments in this + /// template argument list. + unsigned size() const { return NumFlatArguments; } + + /// \brief Retrieve the number of template arguments in the + /// flattened template argument list. + unsigned flat_size() const { return NumFlatArguments; } + + /// \brief Retrieve the flattened template argument list. + const TemplateArgument *getFlatArgumentList() const { + return FlatArguments.getPointer(); + } +}; + //===----------------------------------------------------------------------===// // Kinds of Templates //===----------------------------------------------------------------------===// @@ -128,618 +474,364 @@ protected: DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl) : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl), - TemplateParams(Params) { } -public: - ~TemplateDecl(); - - /// Get the list of template parameters - TemplateParameterList *getTemplateParameters() const { - return TemplateParams; - } - - /// Get the underlying, templated declaration. - NamedDecl *getTemplatedDecl() const { return TemplatedDecl; } - - // Implement isa/cast/dyncast/etc. - static bool classof(const Decl *D) { - return D->getKind() >= TemplateFirst && D->getKind() <= TemplateLast; - } - static bool classof(const TemplateDecl *D) { return true; } - static bool classof(const FunctionTemplateDecl *D) { return true; } - static bool classof(const ClassTemplateDecl *D) { return true; } - static bool classof(const TemplateTemplateParmDecl *D) { return true; } - -protected: - NamedDecl *TemplatedDecl; - TemplateParameterList* TemplateParams; -}; - -/// Declaration of a template function. -class FunctionTemplateDecl : public TemplateDecl { -protected: - FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name, - TemplateParameterList *Params, NamedDecl *Decl) - : TemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl) { } -public: - /// Get the underling function declaration of the template. - FunctionDecl *getTemplatedDecl() const { - return static_cast(TemplatedDecl); - } - - /// Create a template function node. - static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC, - SourceLocation L, - DeclarationName Name, - TemplateParameterList *Params, - NamedDecl *Decl); - - // Implement isa/cast/dyncast support - static bool classof(const Decl *D) - { return D->getKind() == FunctionTemplate; } - static bool classof(const FunctionTemplateDecl *D) - { return true; } -}; - -//===----------------------------------------------------------------------===// -// Kinds of Template Parameters -//===----------------------------------------------------------------------===// - -/// The TemplateParmPosition class defines the position of a template parameter -/// within a template parameter list. Because template parameter can be listed -/// sequentially for out-of-line template members, each template parameter is -/// given a Depth - the nesting of template parameter scopes - and a Position - -/// the occurrence within the parameter list. -/// This class is inheritedly privately by different kinds of template -/// parameters and is not part of the Decl hierarchy. Just a facility. -class TemplateParmPosition -{ -protected: - // FIXME: This should probably never be called, but it's here as - TemplateParmPosition() - : Depth(0), Position(0) - { /* assert(0 && "Cannot create positionless template parameter"); */ } - - TemplateParmPosition(unsigned D, unsigned P) - : Depth(D), Position(P) - { } - - // FIXME: These probably don't need to be ints. int:5 for depth, int:8 for - // position? Maybe? - unsigned Depth; - unsigned Position; - -public: - /// Get the nesting depth of the template parameter. - unsigned getDepth() const { return Depth; } - - /// Get the position of the template parameter within its parameter list. - unsigned getPosition() const { return Position; } - - /// Get the index of the template parameter within its parameter list. - unsigned getIndex() const { return Position; } -}; - -/// TemplateTypeParmDecl - Declaration of a template type parameter, -/// e.g., "T" in -/// @code -/// template class vector; -/// @endcode -class TemplateTypeParmDecl : public TypeDecl { - /// \brief Whether this template type parameter was declaration with - /// the 'typename' keyword. If false, it was declared with the - /// 'class' keyword. - bool Typename : 1; - - /// \brief Whether this template type parameter inherited its - /// default argument. - bool InheritedDefault : 1; - - /// \brief Whether this is a parameter pack. - bool ParameterPack : 1; - - /// \brief The location of the default argument, if any. - SourceLocation DefaultArgumentLoc; - - /// \brief The default template argument, if any. - QualType DefaultArgument; - - TemplateTypeParmDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id, - bool Typename, QualType Type, bool ParameterPack) - : TypeDecl(TemplateTypeParm, DC, L, Id), Typename(Typename), - InheritedDefault(false), ParameterPack(ParameterPack), DefaultArgument() { - TypeForDecl = Type.getTypePtr(); - } - -public: - static TemplateTypeParmDecl *Create(ASTContext &C, DeclContext *DC, - SourceLocation L, unsigned D, unsigned P, - IdentifierInfo *Id, bool Typename, - bool ParameterPack); - - /// \brief Whether this template type parameter was declared with - /// the 'typename' keyword. If not, it was declared with the 'class' - /// keyword. - bool wasDeclaredWithTypename() const { return Typename; } - - /// \brief Determine whether this template parameter has a default - /// argument. - bool hasDefaultArgument() const { return !DefaultArgument.isNull(); } - - /// \brief Retrieve the default argument, if any. - QualType getDefaultArgument() const { return DefaultArgument; } - - /// \brief Retrieve the location of the default argument, if any. - SourceLocation getDefaultArgumentLoc() const { return DefaultArgumentLoc; } - - /// \brief Determines whether the default argument was inherited - /// from a previous declaration of this template. - bool defaultArgumentWasInherited() const { return InheritedDefault; } - - /// \brief Set the default argument for this template parameter, and - /// whether that default argument was inherited from another - /// declaration. - void setDefaultArgument(QualType DefArg, SourceLocation DefArgLoc, - bool Inherited) { - DefaultArgument = DefArg; - DefaultArgumentLoc = DefArgLoc; - InheritedDefault = Inherited; - } - - /// \brief Returns whether this is a parameter pack. - bool isParameterPack() const { return ParameterPack; } - - // Implement isa/cast/dyncast/etc. - static bool classof(const Decl *D) { - return D->getKind() == TemplateTypeParm; - } - static bool classof(const TemplateTypeParmDecl *D) { return true; } -}; - -/// NonTypeTemplateParmDecl - Declares a non-type template parameter, -/// e.g., "Size" in -/// @code -/// template class array { }; -/// @endcode -class NonTypeTemplateParmDecl - : public VarDecl, protected TemplateParmPosition { - /// \brief The default template argument, if any. - Expr *DefaultArgument; - - NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D, - unsigned P, IdentifierInfo *Id, QualType T, - SourceLocation TSSL = SourceLocation()) - : VarDecl(NonTypeTemplateParm, DC, L, Id, T, VarDecl::None, TSSL), - TemplateParmPosition(D, P), DefaultArgument(0) - { } - -public: - static NonTypeTemplateParmDecl * - Create(ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D, - unsigned P, IdentifierInfo *Id, QualType T, - SourceLocation TypeSpecStartLoc = SourceLocation()); - - using TemplateParmPosition::getDepth; - using TemplateParmPosition::getPosition; - using TemplateParmPosition::getIndex; - - /// \brief Determine whether this template parameter has a default - /// argument. - bool hasDefaultArgument() const { return DefaultArgument; } - - /// \brief Retrieve the default argument, if any. - Expr *getDefaultArgument() const { return DefaultArgument; } - - /// \brief Retrieve the location of the default argument, if any. - SourceLocation getDefaultArgumentLoc() const; - - /// \brief Set the default argument for this template parameter. - void setDefaultArgument(Expr *DefArg) { - DefaultArgument = DefArg; - } - - // Implement isa/cast/dyncast/etc. - static bool classof(const Decl *D) { - return D->getKind() == NonTypeTemplateParm; - } - static bool classof(const NonTypeTemplateParmDecl *D) { return true; } -}; - -/// TemplateTemplateParmDecl - Declares a template template parameter, -/// e.g., "T" in -/// @code -/// template