diff options
Diffstat (limited to 'clang/include/clang')
-rw-r--r-- | clang/include/clang/Lex/Token.h | 63 | ||||
-rw-r--r-- | clang/include/clang/Parse/Action.h | 3 | ||||
-rw-r--r-- | clang/include/clang/Parse/DeclSpec.h | 11 | ||||
-rw-r--r-- | clang/include/clang/Parse/Ownership.h | 35 | ||||
-rw-r--r-- | clang/include/clang/Parse/Parser.h | 14 | ||||
-rw-r--r-- | clang/include/clang/Parse/Template.h | 183 |
6 files changed, 202 insertions, 107 deletions
diff --git a/clang/include/clang/Lex/Token.h b/clang/include/clang/Lex/Token.h index 8d910959b9f..604eae1027a 100644 --- a/clang/include/clang/Lex/Token.h +++ b/clang/include/clang/Lex/Token.h @@ -248,69 +248,6 @@ struct PPConditionalInfo { bool FoundElse; }; -/// TemplateIdAnnotation - Information about a template-id annotation -/// token, which contains the template declaration, template -/// arguments, whether those template arguments were types or -/// expressions, and the source locations for important tokens. All of -/// the information about template arguments is allocated directly -/// after this structure. -struct TemplateIdAnnotation { - /// TemplateNameLoc - The location of the template name within the - /// source. - SourceLocation TemplateNameLoc; - - /// FIXME: Temporarily stores the name of a specialization - IdentifierInfo *Name; - - /// FIXME: Temporarily stores the overloaded operator kind. - OverloadedOperatorKind Operator; - - /// The declaration of the template corresponding to the - /// template-name. This is an Action::DeclTy*. - void *Template; - - /// The kind of template that Template refers to. - TemplateNameKind Kind; - - /// The location of the '<' before the template argument - /// list. - SourceLocation LAngleLoc; - - /// The location of the '>' after the template argument - /// list. - SourceLocation RAngleLoc; - - /// NumArgs - The number of template arguments. - unsigned NumArgs; - - /// \brief Retrieves a pointer to the template arguments - void **getTemplateArgs() { return (void **)(this + 1); } - - /// \brief Retrieves a pointer to the array of template argument - /// locations. - SourceLocation *getTemplateArgLocations() { - return (SourceLocation *)(getTemplateArgs() + NumArgs); - } - - /// \brief Retrieves a pointer to the array of flags that states - /// whether the template arguments are types. - bool *getTemplateArgIsType() { - return (bool *)(getTemplateArgLocations() + NumArgs); - } - - static TemplateIdAnnotation* Allocate(unsigned NumArgs) { - TemplateIdAnnotation *TemplateId - = (TemplateIdAnnotation *)std::malloc(sizeof(TemplateIdAnnotation) + - sizeof(void*) * NumArgs + - sizeof(SourceLocation) * NumArgs + - sizeof(bool) * NumArgs); - TemplateId->NumArgs = NumArgs; - return TemplateId; - } - - void Destroy() { free(this); } -}; - } // end namespace clang #endif diff --git a/clang/include/clang/Parse/Action.h b/clang/include/clang/Parse/Action.h index 929e18ba01d..4886970c741 100644 --- a/clang/include/clang/Parse/Action.h +++ b/clang/include/clang/Parse/Action.h @@ -1632,7 +1632,6 @@ public: SourceLocation TemplateLoc, SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgs, - SourceLocation *TemplateArgLocs, SourceLocation RAngleLoc) { return TypeResult(); }; @@ -1737,7 +1736,6 @@ public: SourceLocation TemplateNameLoc, SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgs, - SourceLocation *TemplateArgLocs, SourceLocation RAngleLoc, AttributeList *Attr, MultiTemplateParamsArg TemplateParameterLists) { @@ -1817,7 +1815,6 @@ public: SourceLocation TemplateNameLoc, SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgs, - SourceLocation *TemplateArgLocs, SourceLocation RAngleLoc, AttributeList *Attr) { return DeclResult(); diff --git a/clang/include/clang/Parse/DeclSpec.h b/clang/include/clang/Parse/DeclSpec.h index d539508e973..7e7d0b3f28e 100644 --- a/clang/include/clang/Parse/DeclSpec.h +++ b/clang/include/clang/Parse/DeclSpec.h @@ -25,7 +25,8 @@ namespace clang { class IdentifierInfo; class Preprocessor; class Declarator; - + struct TemplateIdAnnotation; + /// DeclSpec - This class captures information about "declaration specifiers", /// which encompasses storage-class-specifiers, type-specifiers, /// type-qualifiers, and function-specifiers. @@ -642,13 +643,7 @@ public: /// \param TemplateId the template-id annotation that describes the parsed /// template-id. This UnqualifiedId instance will take ownership of the /// \p TemplateId and will free it on destruction. - void setTemplateId(TemplateIdAnnotation *TemplateId) { - assert(TemplateId && "NULL template-id annotation?"); - Kind = IK_TemplateId; - this->TemplateId = TemplateId; - StartLocation = TemplateId->TemplateNameLoc; - EndLocation = TemplateId->RAngleLoc; - } + void setTemplateId(TemplateIdAnnotation *TemplateId); /// \brief Return the source range that covers this unqualified-id. SourceRange getSourceRange() const { diff --git a/clang/include/clang/Parse/Ownership.h b/clang/include/clang/Parse/Ownership.h index 9bd69c5fdb6..5eb9635f06a 100644 --- a/clang/include/clang/Parse/Ownership.h +++ b/clang/include/clang/Parse/Ownership.h @@ -654,41 +654,33 @@ namespace clang { #endif }; + class ParsedTemplateArgument; + class ASTTemplateArgsPtr { #if !defined(DISABLE_SMART_POINTERS) ActionBase &Actions; #endif - void **Args; - bool *ArgIsType; + ParsedTemplateArgument *Args; mutable unsigned Count; #if !defined(DISABLE_SMART_POINTERS) - void destroy() { - if (!Count) - return; - - for (unsigned i = 0; i != Count; ++i) - if (Args[i] && !ArgIsType[i]) - Actions.DeleteExpr((ActionBase::ExprTy *)Args[i]); - - Count = 0; - } + void destroy(); #endif - + public: - ASTTemplateArgsPtr(ActionBase &actions, void **args, bool *argIsType, + ASTTemplateArgsPtr(ActionBase &actions, ParsedTemplateArgument *args, unsigned count) : #if !defined(DISABLE_SMART_POINTERS) Actions(actions), #endif - Args(args), ArgIsType(argIsType), Count(count) { } + Args(args), Count(count) { } // FIXME: Lame, not-fully-type-safe emulation of 'move semantics'. ASTTemplateArgsPtr(ASTTemplateArgsPtr &Other) : #if !defined(DISABLE_SMART_POINTERS) Actions(Other.Actions), #endif - Args(Other.Args), ArgIsType(Other.ArgIsType), Count(Other.Count) { + Args(Other.Args), Count(Other.Count) { #if !defined(DISABLE_SMART_POINTERS) Other.Count = 0; #endif @@ -700,7 +692,6 @@ namespace clang { Actions = Other.Actions; #endif Args = Other.Args; - ArgIsType = Other.ArgIsType; Count = Other.Count; #if !defined(DISABLE_SMART_POINTERS) Other.Count = 0; @@ -712,22 +703,20 @@ namespace clang { ~ASTTemplateArgsPtr() { destroy(); } #endif - void **getArgs() const { return Args; } - bool *getArgIsType() const {return ArgIsType; } + ParsedTemplateArgument *getArgs() const { return Args; } unsigned size() const { return Count; } - void reset(void **args, bool *argIsType, unsigned count) { + void reset(ParsedTemplateArgument *args, unsigned count) { #if !defined(DISABLE_SMART_POINTERS) destroy(); #endif Args = args; - ArgIsType = argIsType; Count = count; } - void *operator[](unsigned Arg) const { return Args[Arg]; } + const ParsedTemplateArgument &operator[](unsigned Arg) const; - void **release() const { + ParsedTemplateArgument *release() const { #if !defined(DISABLE_SMART_POINTERS) Count = 0; #endif diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 1ca92edc9a8..b163c81e18c 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -331,7 +331,7 @@ private: /// either "commit the consumed tokens" or revert to the previously marked /// token position. Example: /// - /// TentativeParsingAction TPA; + /// TentativeParsingAction TPA(*this); /// ConsumeToken(); /// .... /// TPA.Revert(); @@ -1347,9 +1347,7 @@ private: DeclPtrTy ParseTemplateTemplateParameter(unsigned Depth, unsigned Position); DeclPtrTy ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position); // C++ 14.3: Template arguments [temp.arg] - typedef llvm::SmallVector<void *, 16> TemplateArgList; - typedef llvm::SmallVector<bool, 16> TemplateArgIsTypeList; - typedef llvm::SmallVector<SourceLocation, 16> TemplateArgLocationList; + typedef llvm::SmallVector<ParsedTemplateArgument, 16> TemplateArgList; bool ParseTemplateIdAfterTemplateName(TemplateTy Template, SourceLocation TemplateNameLoc, @@ -1357,8 +1355,6 @@ private: bool ConsumeLastToken, SourceLocation &LAngleLoc, TemplateArgList &TemplateArgs, - TemplateArgIsTypeList &TemplateArgIsType, - TemplateArgLocationList &TemplateArgLocations, SourceLocation &RAngleLoc); bool AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK, @@ -1367,10 +1363,8 @@ private: SourceLocation TemplateKWLoc = SourceLocation(), bool AllowTypeAnnotation = true); void AnnotateTemplateIdTokenAsType(const CXXScopeSpec *SS = 0); - bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs, - TemplateArgIsTypeList &TemplateArgIsType, - TemplateArgLocationList &TemplateArgLocations); - void *ParseTemplateArgument(bool &ArgIsType); + bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs); + ParsedTemplateArgument ParseTemplateArgument(); DeclPtrTy ParseExplicitInstantiation(SourceLocation ExternLoc, SourceLocation TemplateLoc, SourceLocation &DeclEnd); diff --git a/clang/include/clang/Parse/Template.h b/clang/include/clang/Parse/Template.h new file mode 100644 index 00000000000..8531bf66a80 --- /dev/null +++ b/clang/include/clang/Parse/Template.h @@ -0,0 +1,183 @@ +//===--- Template.h - Template Parsing Data Types -------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file provides data structures that store the parsed representation of +// templates. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_PARSE_TEMPLATE_H +#define LLVM_CLANG_PARSE_TEMPLATE_H + +#include "clang/Parse/DeclSpec.h" +#include "clang/Parse/Ownership.h" +#include <cassert> + +namespace clang { + /// \brief Represents the parsed form of a C++ template argument. + class ParsedTemplateArgument { + public: + /// \brief Describes the kind of template argument that was parsed. + enum KindType { + /// \brief A template type parameter, stored as a type. + Type, + /// \brief A non-type template parameter, stored as an expression. + NonType, + /// \brief A template template argument, stored as a template name. + Template + }; + + /// \brief Build an empty template argument. This template argument + ParsedTemplateArgument() : Kind(Type), Arg(0) { } + + /// \brief Create a template type argument or non-type template argument. + /// + /// \param Arg the template type argument or non-type template argument. + /// \param Loc the location of the type. + ParsedTemplateArgument(KindType Kind, void *Arg, SourceLocation Loc) + : Kind(Kind), Arg(Arg), Loc(Loc) { } + + /// \brief Create a template template argument. + /// + /// \param SS the C++ scope specifier that precedes the template name, if + /// any. + /// + /// \param Template the template to which this template template + /// argument refers. + /// + /// \param TemplateLoc the location of the template name. + ParsedTemplateArgument(const CXXScopeSpec &SS, + ActionBase::TemplateTy Template, + SourceLocation TemplateLoc) + : Kind(ParsedTemplateArgument::Template), Arg(Template.get()), + Loc(TemplateLoc), SS(SS) { } + + /// \brief Determine whether the given template argument is invalid. + bool isInvalid() { return Arg == 0; } + + /// \brief Determine what kind of template argument we have. + KindType getKind() const { return Kind; } + + /// \brief Retrieve the template type argument's type. + ActionBase::TypeTy *getAsType() const { + assert(Kind == Type && "Not a template type argument"); + return Arg; + } + + /// \brief Retrieve the non-type template argument's expression. + ActionBase::ExprTy *getAsExpr() const { + assert(Kind == NonType && "Not a non-type template argument"); + return Arg; + } + + /// \brief Retrieve the template template argument's template name. + ActionBase::TemplateTy getAsTemplate() const { + assert(Kind == Template && "Not a template template argument"); + return ActionBase::TemplateTy::make(Arg); + } + + /// \brief Retrieve the location of the template argument. + SourceLocation getLocation() const { return Loc; } + + /// \brief Retrieve the nested-name-specifier that precedes the template + /// name in a template template argument. + const CXXScopeSpec &getScopeSpec() const { + assert(Kind == Template && + "Only template template arguments can have a scope specifier"); + return SS; + } + + private: + KindType Kind; + + /// \brief The actual template argument representation, which may be + /// an \c ActionBase::TypeTy* (for a type), an ActionBase::ExprTy* (for an + /// expression), or an ActionBase::TemplateTy (for a template). + void *Arg; + + /// \brief the location of the template argument. + SourceLocation Loc; + + /// \brief The nested-name-specifier that can accompany a template template + /// argument. + CXXScopeSpec SS; + }; + + /// \brief Information about a template-id annotation + /// token. + /// + /// A template-id annotation token contains the template declaration, + /// template arguments, whether those template arguments were types, + /// expressions, or template names, and the source locations for important + /// tokens. All of the information about template arguments is allocated + /// directly after this structure. + struct TemplateIdAnnotation { + /// TemplateNameLoc - The location of the template name within the + /// source. + SourceLocation TemplateNameLoc; + + /// FIXME: Temporarily stores the name of a specialization + IdentifierInfo *Name; + + /// FIXME: Temporarily stores the overloaded operator kind. + OverloadedOperatorKind Operator; + + /// The declaration of the template corresponding to the + /// template-name. This is an Action::TemplateTy. + void *Template; + + /// The kind of template that Template refers to. + TemplateNameKind Kind; + + /// The location of the '<' before the template argument + /// list. + SourceLocation LAngleLoc; + + /// The location of the '>' after the template argument + /// list. + SourceLocation RAngleLoc; + + /// NumArgs - The number of template arguments. + unsigned NumArgs; + + /// \brief Retrieves a pointer to the template arguments + ParsedTemplateArgument *getTemplateArgs() { + return reinterpret_cast<ParsedTemplateArgument *>(this + 1); + } + + static TemplateIdAnnotation* Allocate(unsigned NumArgs) { + TemplateIdAnnotation *TemplateId + = (TemplateIdAnnotation *)std::malloc(sizeof(TemplateIdAnnotation) + + sizeof(ParsedTemplateArgument) * NumArgs); + TemplateId->NumArgs = NumArgs; + return TemplateId; + } + + void Destroy() { free(this); } + }; + +#if !defined(DISABLE_SMART_POINTERS) + inline void ASTTemplateArgsPtr::destroy() { + if (!Count) + return; + + for (unsigned I = 0; I != Count; ++I) + if (Args[I].getKind() == ParsedTemplateArgument::NonType) + Actions.DeleteExpr(Args[I].getAsExpr()); + + Count = 0; + } +#endif + + inline const ParsedTemplateArgument & + ASTTemplateArgsPtr::operator[](unsigned Arg) const { + return Args[Arg]; + } +} + +#endif
\ No newline at end of file |