forked from OSchip/llvm-project
Push DeclGroupRefs and TemplateNames in an opaque but type-safe way
through the parser. llvm-svn: 111800
This commit is contained in:
parent
421ad5e1e6
commit
3e56fd4d22
|
@ -27,6 +27,7 @@ namespace clang {
|
|||
struct CXX0XAttributeList;
|
||||
class PragmaHandler;
|
||||
class Scope;
|
||||
class DeclGroupRef;
|
||||
class DiagnosticBuilder;
|
||||
class Parser;
|
||||
class PragmaUnusedHandler;
|
||||
|
@ -147,13 +148,13 @@ public:
|
|||
// different actual classes based on the actions in place.
|
||||
typedef Expr ExprTy;
|
||||
typedef Stmt StmtTy;
|
||||
typedef Action::DeclGroupPtrTy DeclGroupPtrTy;
|
||||
typedef OpaquePtr<DeclGroupRef> DeclGroupPtrTy;
|
||||
typedef Action::TypeTy TypeTy;
|
||||
typedef CXXBaseSpecifier BaseTy;
|
||||
typedef CXXBaseOrMemberInitializer MemInitTy;
|
||||
typedef NestedNameSpecifier CXXScopeTy;
|
||||
typedef TemplateParameterList TemplateParamsTy;
|
||||
typedef Action::TemplateTy TemplateTy;
|
||||
typedef OpaquePtr<TemplateName> TemplateTy;
|
||||
|
||||
typedef llvm::SmallVector<TemplateParameterList *, 4> TemplateParameterLists;
|
||||
|
||||
|
|
|
@ -27,59 +27,64 @@ namespace clang {
|
|||
class CXXBaseOrMemberInitializer;
|
||||
class CXXBaseSpecifier;
|
||||
class Decl;
|
||||
class DeclGroupRef;
|
||||
class Expr;
|
||||
class NestedNameSpecifier;
|
||||
class Stmt;
|
||||
class TemplateName;
|
||||
class TemplateParameterList;
|
||||
|
||||
/// OpaquePtr - This is a very simple POD type that wraps a pointer that the
|
||||
/// Parser doesn't know about but that Sema or another client does. The UID
|
||||
/// template argument is used to make sure that "Decl" pointers are not
|
||||
/// compatible with "Type" pointers for example.
|
||||
template<int UID>
|
||||
template <class PtrTy>
|
||||
class OpaquePtr {
|
||||
void *Ptr;
|
||||
explicit OpaquePtr(void *Ptr) : Ptr(Ptr) {}
|
||||
|
||||
public:
|
||||
OpaquePtr() : Ptr(0) {}
|
||||
|
||||
template <typename T>
|
||||
T* getAs() const {
|
||||
return llvm::PointerLikeTypeTraits<T*>::getFromVoidPointer(Ptr);
|
||||
static OpaquePtr make(PtrTy P) {
|
||||
OpaquePtr OP; OP.set(P); return OP;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T getAsVal() const {
|
||||
return llvm::PointerLikeTypeTraits<T>::getFromVoidPointer(Ptr);
|
||||
template <typename T> T* getAs() const {
|
||||
return get();
|
||||
}
|
||||
|
||||
void *get() const { return Ptr; }
|
||||
|
||||
template<typename T>
|
||||
static OpaquePtr make(T P) {
|
||||
OpaquePtr R; R.set(P); return R;
|
||||
template <typename T> T getAsVal() const {
|
||||
return get();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void set(T P) {
|
||||
Ptr = llvm::PointerLikeTypeTraits<T>::getAsVoidPointer(P);
|
||||
PtrTy get() const {
|
||||
return llvm::PointerLikeTypeTraits<PtrTy>::getFromVoidPointer(Ptr);
|
||||
}
|
||||
|
||||
void set(PtrTy P) {
|
||||
Ptr = llvm::PointerLikeTypeTraits<PtrTy>::getAsVoidPointer(P);
|
||||
}
|
||||
|
||||
operator bool() const { return Ptr != 0; }
|
||||
|
||||
void *getAsOpaquePtr() const { return Ptr; }
|
||||
static OpaquePtr getFromOpaquePtr(void *P) { return OpaquePtr(P); }
|
||||
};
|
||||
}
|
||||
|
||||
namespace llvm {
|
||||
template <int UID>
|
||||
class PointerLikeTypeTraits<clang::OpaquePtr<UID> > {
|
||||
template <class T>
|
||||
class PointerLikeTypeTraits<clang::OpaquePtr<T> > {
|
||||
public:
|
||||
static inline void *getAsVoidPointer(clang::OpaquePtr<UID> P) {
|
||||
static inline void *getAsVoidPointer(clang::OpaquePtr<T> P) {
|
||||
// FIXME: Doesn't work? return P.getAs< void >();
|
||||
return P.get();
|
||||
return P.getAsOpaquePtr();
|
||||
}
|
||||
static inline clang::OpaquePtr<UID> getFromVoidPointer(void *P) {
|
||||
return clang::OpaquePtr<UID>::make(P);
|
||||
static inline clang::OpaquePtr<T> getFromVoidPointer(void *P) {
|
||||
return clang::OpaquePtr<T>::getFromOpaquePtr(P);
|
||||
}
|
||||
enum { NumLowBitsAvailable = 3 };
|
||||
enum { NumLowBitsAvailable = 0 };
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -207,8 +212,8 @@ namespace clang {
|
|||
|
||||
// Types - Though these don't actually enforce strong typing, they document
|
||||
// what types are required to be identical for the actions.
|
||||
typedef OpaquePtr<1> DeclGroupPtrTy;
|
||||
typedef OpaquePtr<2> TemplateTy;
|
||||
typedef OpaquePtr<DeclGroupRef> DeclGroupPtrTy;
|
||||
typedef OpaquePtr<TemplateName> TemplateTy;
|
||||
typedef Attr AttrTy;
|
||||
typedef CXXBaseSpecifier BaseTy;
|
||||
typedef CXXBaseOrMemberInitializer MemInitTy;
|
||||
|
@ -535,6 +540,7 @@ namespace clang {
|
|||
typedef ActionBase::ActionResult<CXXBaseOrMemberInitializer*> MemInitResult;
|
||||
|
||||
typedef ActionBase::ActionResult<Decl*> DeclResult;
|
||||
typedef OpaquePtr<TemplateName> ParsedTemplateTy;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -54,7 +54,8 @@ namespace clang {
|
|||
ParsedTemplateArgument(const CXXScopeSpec &SS,
|
||||
ActionBase::TemplateTy Template,
|
||||
SourceLocation TemplateLoc)
|
||||
: Kind(ParsedTemplateArgument::Template), Arg(Template.get()),
|
||||
: Kind(ParsedTemplateArgument::Template),
|
||||
Arg(Template.getAsOpaquePtr()),
|
||||
Loc(TemplateLoc), SS(SS) { }
|
||||
|
||||
/// \brief Determine whether the given template argument is invalid.
|
||||
|
@ -78,7 +79,7 @@ namespace clang {
|
|||
/// \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);
|
||||
return ActionBase::TemplateTy::getFromOpaquePtr(Arg);
|
||||
}
|
||||
|
||||
/// \brief Retrieve the location of the template argument.
|
||||
|
@ -128,8 +129,8 @@ namespace clang {
|
|||
OverloadedOperatorKind Operator;
|
||||
|
||||
/// The declaration of the template corresponding to the
|
||||
/// template-name. This is an Action::TemplateTy.
|
||||
void *Template;
|
||||
/// template-name.
|
||||
ParsedTemplateTy Template;
|
||||
|
||||
/// The kind of template that Template refers to.
|
||||
TemplateNameKind Kind;
|
||||
|
|
|
@ -84,11 +84,11 @@ void clang::ParseAST(Sema &S, bool PrintStats) {
|
|||
// is due to a top-level semicolon, an action override, or a parse error
|
||||
// skipping something.
|
||||
if (ADecl)
|
||||
Consumer->HandleTopLevelDecl(ADecl.getAsVal<DeclGroupRef>());
|
||||
Consumer->HandleTopLevelDecl(ADecl.get());
|
||||
};
|
||||
// Check for any pending objective-c implementation decl.
|
||||
while ((ADecl = P.FinishPendingObjCActions()))
|
||||
Consumer->HandleTopLevelDecl(ADecl.getAsVal<DeclGroupRef>());
|
||||
Consumer->HandleTopLevelDecl(ADecl.get());
|
||||
|
||||
// Process any TopLevelDecls generated by #pragma weak.
|
||||
for (llvm::SmallVector<Decl*,2>::iterator
|
||||
|
|
|
@ -842,7 +842,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
|
|||
TagType,
|
||||
StartLoc,
|
||||
SS,
|
||||
TemplateTy::make(TemplateId->Template),
|
||||
TemplateId->Template,
|
||||
TemplateId->TemplateNameLoc,
|
||||
TemplateId->LAngleLoc,
|
||||
TemplateArgsPtr,
|
||||
|
@ -857,7 +857,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
|
|||
(TUK == Action::TUK_Friend &&
|
||||
TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate)) {
|
||||
TypeResult
|
||||
= Actions.ActOnTemplateIdType(TemplateTy::make(TemplateId->Template),
|
||||
= Actions.ActOnTemplateIdType(TemplateId->Template,
|
||||
TemplateId->TemplateNameLoc,
|
||||
TemplateId->LAngleLoc,
|
||||
TemplateArgsPtr,
|
||||
|
@ -904,7 +904,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
|
|||
TagOrTempResult
|
||||
= Actions.ActOnClassTemplateSpecialization(getCurScope(), TagType, TUK,
|
||||
StartLoc, SS,
|
||||
TemplateTy::make(TemplateId->Template),
|
||||
TemplateId->Template,
|
||||
TemplateId->TemplateNameLoc,
|
||||
TemplateId->LAngleLoc,
|
||||
TemplateArgsPtr,
|
||||
|
|
|
@ -1128,7 +1128,7 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,
|
|||
TemplateId->TemplateNameLoc = Id.StartLocation;
|
||||
}
|
||||
|
||||
TemplateId->Template = Template.getAs<void*>();
|
||||
TemplateId->Template = Template;
|
||||
TemplateId->Kind = TNK;
|
||||
TemplateId->LAngleLoc = LAngleLoc;
|
||||
TemplateId->RAngleLoc = RAngleLoc;
|
||||
|
|
|
@ -806,7 +806,7 @@ bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
|
|||
TemplateId->Name = 0;
|
||||
TemplateId->Operator = TemplateName.OperatorFunctionId.Operator;
|
||||
}
|
||||
TemplateId->Template = Template.getAs<void*>();
|
||||
TemplateId->Template = Template;
|
||||
TemplateId->Kind = TNK;
|
||||
TemplateId->LAngleLoc = LAngleLoc;
|
||||
TemplateId->RAngleLoc = RAngleLoc;
|
||||
|
@ -851,7 +851,7 @@ void Parser::AnnotateTemplateIdTokenAsType(const CXXScopeSpec *SS) {
|
|||
TemplateId->NumArgs);
|
||||
|
||||
Action::TypeResult Type
|
||||
= Actions.ActOnTemplateIdType(TemplateTy::make(TemplateId->Template),
|
||||
= Actions.ActOnTemplateIdType(TemplateId->Template,
|
||||
TemplateId->TemplateNameLoc,
|
||||
TemplateId->LAngleLoc,
|
||||
TemplateArgsPtr,
|
||||
|
|
|
@ -2072,8 +2072,7 @@ Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) {
|
|||
}
|
||||
|
||||
case UnqualifiedId::IK_TemplateId: {
|
||||
TemplateName TName
|
||||
= TemplateName::getFromVoidPointer(Name.TemplateId->Template);
|
||||
TemplateName TName = Name.TemplateId->Template.get();
|
||||
SourceLocation TNameLoc = Name.TemplateId->TemplateNameLoc;
|
||||
return Context.getNameForTemplate(TName, TNameLoc);
|
||||
}
|
||||
|
|
|
@ -671,8 +671,7 @@ static void DecomposeUnqualifiedId(Sema &SemaRef,
|
|||
SemaRef.translateTemplateArguments(TemplateArgsPtr, Buffer);
|
||||
TemplateArgsPtr.release();
|
||||
|
||||
TemplateName TName =
|
||||
Sema::TemplateTy::make(Id.TemplateId->Template).getAsVal<TemplateName>();
|
||||
TemplateName TName = Id.TemplateId->Template.get();
|
||||
SourceLocation TNameLoc = Id.TemplateId->TemplateNameLoc;
|
||||
NameInfo = SemaRef.Context.getNameForTemplate(TName, TNameLoc);
|
||||
TemplateArgs = &Buffer;
|
||||
|
|
|
@ -2977,7 +2977,7 @@ Sema::OwningExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, ExprArg Base,
|
|||
ASTTemplateArgsPtr TemplateArgsPtr(*this,
|
||||
TemplateId->getTemplateArgs(),
|
||||
TemplateId->NumArgs);
|
||||
TypeResult T = ActOnTemplateIdType(TemplateTy::make(TemplateId->Template),
|
||||
TypeResult T = ActOnTemplateIdType(TemplateId->Template,
|
||||
TemplateId->TemplateNameLoc,
|
||||
TemplateId->LAngleLoc,
|
||||
TemplateArgsPtr,
|
||||
|
@ -3025,7 +3025,7 @@ Sema::OwningExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, ExprArg Base,
|
|||
ASTTemplateArgsPtr TemplateArgsPtr(*this,
|
||||
TemplateId->getTemplateArgs(),
|
||||
TemplateId->NumArgs);
|
||||
TypeResult T = ActOnTemplateIdType(TemplateTy::make(TemplateId->Template),
|
||||
TypeResult T = ActOnTemplateIdType(TemplateId->Template,
|
||||
TemplateId->TemplateNameLoc,
|
||||
TemplateId->LAngleLoc,
|
||||
TemplateArgsPtr,
|
||||
|
|
|
@ -436,8 +436,7 @@ static TemplateArgumentLoc translateTemplateArgument(Sema &SemaRef,
|
|||
}
|
||||
|
||||
case ParsedTemplateArgument::Template: {
|
||||
TemplateName Template
|
||||
= TemplateName::getFromVoidPointer(Arg.getAsTemplate().get());
|
||||
TemplateName Template = Arg.getAsTemplate().get();
|
||||
return TemplateArgumentLoc(TemplateArgument(Template),
|
||||
Arg.getScopeSpec().getRange(),
|
||||
Arg.getLocation());
|
||||
|
|
Loading…
Reference in New Issue