Store a TypeArgument on an attribute as a TypeSourceInfo*, rather than as a
QualType with a SourceLocation stashed alongside. llvm-svn: 193803
This commit is contained in:
parent
cb5bd5e508
commit
b87c465391
|
@ -15,6 +15,7 @@
|
||||||
#define LLVM_CLANG_AST_ATTR_H
|
#define LLVM_CLANG_AST_ATTR_H
|
||||||
|
|
||||||
#include "clang/AST/AttrIterator.h"
|
#include "clang/AST/AttrIterator.h"
|
||||||
|
#include "clang/AST/Decl.h"
|
||||||
#include "clang/AST/Type.h"
|
#include "clang/AST/Type.h"
|
||||||
#include "clang/Basic/AttrKinds.h"
|
#include "clang/Basic/AttrKinds.h"
|
||||||
#include "clang/Basic/LLVM.h"
|
#include "clang/Basic/LLVM.h"
|
||||||
|
|
|
@ -435,8 +435,7 @@ def IBOutlet : InheritableAttr {
|
||||||
|
|
||||||
def IBOutletCollection : InheritableAttr {
|
def IBOutletCollection : InheritableAttr {
|
||||||
let Spellings = [GNU<"iboutletcollection">];
|
let Spellings = [GNU<"iboutletcollection">];
|
||||||
let Args = [TypeArgument<"Interface", 1>, SourceLocArgument<"InterfaceLoc">];
|
let Args = [TypeArgument<"Interface", 1>];
|
||||||
let HasCustomParsing = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def Malloc : InheritableAttr {
|
def Malloc : InheritableAttr {
|
||||||
|
@ -751,8 +750,7 @@ def VectorSize : TypeAttr {
|
||||||
|
|
||||||
def VecTypeHint : InheritableAttr {
|
def VecTypeHint : InheritableAttr {
|
||||||
let Spellings = [GNU<"vec_type_hint">];
|
let Spellings = [GNU<"vec_type_hint">];
|
||||||
let Args = [TypeArgument<"TypeHint">, SourceLocArgument<"TypeLoc">];
|
let Args = [TypeArgument<"TypeHint">];
|
||||||
let HasCustomParsing = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def Visibility : InheritableAttr {
|
def Visibility : InheritableAttr {
|
||||||
|
|
|
@ -128,9 +128,6 @@ bool Sema::isSimpleTypeSpecifier(tok::TokenKind Kind) const {
|
||||||
/// determine whether the name refers to a type. If so, returns an
|
/// determine whether the name refers to a type. If so, returns an
|
||||||
/// opaque pointer (actually a QualType) corresponding to that
|
/// opaque pointer (actually a QualType) corresponding to that
|
||||||
/// type. Otherwise, returns NULL.
|
/// type. Otherwise, returns NULL.
|
||||||
///
|
|
||||||
/// If name lookup results in an ambiguity, this routine will complain
|
|
||||||
/// and then return NULL.
|
|
||||||
ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
|
ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
|
||||||
Scope *S, CXXScopeSpec *SS,
|
Scope *S, CXXScopeSpec *SS,
|
||||||
bool isClassName, bool HasTrailingDot,
|
bool isClassName, bool HasTrailingDot,
|
||||||
|
|
|
@ -207,11 +207,16 @@ static inline bool isCFStringType(QualType T, ASTContext &Ctx) {
|
||||||
return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
|
return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned getNumAttributeArgs(const AttributeList &Attr) {
|
||||||
|
// FIXME: Include the type in the argument list.
|
||||||
|
return Attr.getNumArgs() + Attr.hasParsedType();
|
||||||
|
}
|
||||||
|
|
||||||
/// \brief Check if the attribute has exactly as many args as Num. May
|
/// \brief Check if the attribute has exactly as many args as Num. May
|
||||||
/// output an error.
|
/// output an error.
|
||||||
static bool checkAttributeNumArgs(Sema &S, const AttributeList &Attr,
|
static bool checkAttributeNumArgs(Sema &S, const AttributeList &Attr,
|
||||||
unsigned int Num) {
|
unsigned Num) {
|
||||||
if (Attr.getNumArgs() != Num) {
|
if (getNumAttributeArgs(Attr) != Num) {
|
||||||
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
|
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
|
||||||
<< Attr.getName() << Num;
|
<< Attr.getName() << Num;
|
||||||
return false;
|
return false;
|
||||||
|
@ -224,8 +229,8 @@ static bool checkAttributeNumArgs(Sema &S, const AttributeList &Attr,
|
||||||
/// \brief Check if the attribute has at least as many args as Num. May
|
/// \brief Check if the attribute has at least as many args as Num. May
|
||||||
/// output an error.
|
/// output an error.
|
||||||
static bool checkAttributeAtLeastNumArgs(Sema &S, const AttributeList &Attr,
|
static bool checkAttributeAtLeastNumArgs(Sema &S, const AttributeList &Attr,
|
||||||
unsigned int Num) {
|
unsigned Num) {
|
||||||
if (Attr.getNumArgs() < Num) {
|
if (getNumAttributeArgs(Attr) < Num) {
|
||||||
S.Diag(Attr.getLoc(), diag::err_attribute_too_few_arguments) << Num;
|
S.Diag(Attr.getLoc(), diag::err_attribute_too_few_arguments) << Num;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1352,10 +1357,10 @@ static void handleIBOutletCollection(Sema &S, Decl *D,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeSourceInfo *TSI = 0;
|
TypeSourceInfo *QTLoc = 0;
|
||||||
QualType QT = S.GetTypeFromParser(PT, &TSI);
|
QualType QT = S.GetTypeFromParser(PT, &QTLoc);
|
||||||
SourceLocation QTLoc =
|
if (!QTLoc)
|
||||||
TSI ? TSI->getTypeLoc().getLocStart() : SourceLocation();
|
QTLoc = S.Context.getTrivialTypeSourceInfo(QT, Attr.getLoc());
|
||||||
|
|
||||||
// Diagnose use of non-object type in iboutletcollection attribute.
|
// Diagnose use of non-object type in iboutletcollection attribute.
|
||||||
// FIXME. Gnu attribute extension ignores use of builtin types in
|
// FIXME. Gnu attribute extension ignores use of builtin types in
|
||||||
|
@ -1369,7 +1374,7 @@ static void handleIBOutletCollection(Sema &S, Decl *D,
|
||||||
}
|
}
|
||||||
|
|
||||||
D->addAttr(::new (S.Context)
|
D->addAttr(::new (S.Context)
|
||||||
IBOutletCollectionAttr(Attr.getRange(), S.Context, QT, QTLoc,
|
IBOutletCollectionAttr(Attr.getRange(), S.Context, QTLoc,
|
||||||
Attr.getAttributeSpellingListIndex()));
|
Attr.getAttributeSpellingListIndex()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2773,16 +2778,15 @@ static void handleWorkGroupSize(Sema &S, Decl *D,
|
||||||
static void handleVecTypeHint(Sema &S, Decl *D, const AttributeList &Attr) {
|
static void handleVecTypeHint(Sema &S, Decl *D, const AttributeList &Attr) {
|
||||||
assert(Attr.getKind() == AttributeList::AT_VecTypeHint);
|
assert(Attr.getKind() == AttributeList::AT_VecTypeHint);
|
||||||
|
|
||||||
if (!checkAttributeNumArgs(S, Attr, 0))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!Attr.hasParsedType()) {
|
if (!Attr.hasParsedType()) {
|
||||||
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
|
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
|
||||||
<< Attr.getName() << 1;
|
<< Attr.getName() << 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QualType ParmType = S.GetTypeFromParser(Attr.getTypeArg());
|
TypeSourceInfo *ParmTSI = 0;
|
||||||
|
QualType ParmType = S.GetTypeFromParser(Attr.getTypeArg(), &ParmTSI);
|
||||||
|
assert(ParmTSI && "no type source info for attribute argument");
|
||||||
|
|
||||||
if (!ParmType->isExtVectorType() && !ParmType->isFloatingType() &&
|
if (!ParmType->isExtVectorType() && !ParmType->isFloatingType() &&
|
||||||
(ParmType->isBooleanType() ||
|
(ParmType->isBooleanType() ||
|
||||||
|
@ -2795,14 +2799,14 @@ static void handleVecTypeHint(Sema &S, Decl *D, const AttributeList &Attr) {
|
||||||
if (Attr.getKind() == AttributeList::AT_VecTypeHint &&
|
if (Attr.getKind() == AttributeList::AT_VecTypeHint &&
|
||||||
D->hasAttr<VecTypeHintAttr>()) {
|
D->hasAttr<VecTypeHintAttr>()) {
|
||||||
VecTypeHintAttr *A = D->getAttr<VecTypeHintAttr>();
|
VecTypeHintAttr *A = D->getAttr<VecTypeHintAttr>();
|
||||||
if (A->getTypeHint() != ParmType) {
|
if (!S.Context.hasSameType(A->getTypeHint(), ParmType)) {
|
||||||
S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute) << Attr.getName();
|
S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute) << Attr.getName();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
D->addAttr(::new (S.Context) VecTypeHintAttr(Attr.getLoc(), S.Context,
|
D->addAttr(::new (S.Context) VecTypeHintAttr(Attr.getLoc(), S.Context,
|
||||||
ParmType, Attr.getLoc()));
|
ParmTSI));
|
||||||
}
|
}
|
||||||
|
|
||||||
SectionAttr *Sema::mergeSectionAttr(Decl *D, SourceRange Range,
|
SectionAttr *Sema::mergeSectionAttr(Decl *D, SourceRange Range,
|
||||||
|
@ -4101,11 +4105,13 @@ static void handleTypeTagForDatatypeAttr(Sema &S, Decl *D,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
IdentifierInfo *PointerKind = Attr.getArgAsIdent(0)->Ident;
|
IdentifierInfo *PointerKind = Attr.getArgAsIdent(0)->Ident;
|
||||||
QualType MatchingCType = S.GetTypeFromParser(Attr.getMatchingCType(), NULL);
|
TypeSourceInfo *MatchingCTypeLoc = 0;
|
||||||
|
S.GetTypeFromParser(Attr.getMatchingCType(), &MatchingCTypeLoc);
|
||||||
|
assert(MatchingCTypeLoc && "no type source info for attribute argument");
|
||||||
|
|
||||||
D->addAttr(::new (S.Context)
|
D->addAttr(::new (S.Context)
|
||||||
TypeTagForDatatypeAttr(Attr.getRange(), S.Context, PointerKind,
|
TypeTagForDatatypeAttr(Attr.getRange(), S.Context, PointerKind,
|
||||||
MatchingCType,
|
MatchingCTypeLoc,
|
||||||
Attr.getLayoutCompatible(),
|
Attr.getLayoutCompatible(),
|
||||||
Attr.getMustBeNull(),
|
Attr.getMustBeNull(),
|
||||||
Attr.getAttributeSpellingListIndex()));
|
Attr.getAttributeSpellingListIndex()));
|
||||||
|
|
|
@ -533,8 +533,9 @@ bool CursorVisitor::VisitChildren(CXCursor Cursor) {
|
||||||
const IBOutletCollectionAttr *A =
|
const IBOutletCollectionAttr *A =
|
||||||
cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
|
cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
|
||||||
if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
|
if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
|
||||||
return Visit(cxcursor::MakeCursorObjCClassRef(ObjT->getInterface(),
|
return Visit(cxcursor::MakeCursorObjCClassRef(
|
||||||
A->getInterfaceLoc(), TU));
|
ObjT->getInterface(),
|
||||||
|
A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If pointing inside a macro definition, check if the token is an identifier
|
// If pointing inside a macro definition, check if the token is an identifier
|
||||||
|
|
|
@ -94,8 +94,10 @@ AttrListInfo::AttrListInfo(const Decl *D, IndexingContext &IdxCtx)
|
||||||
|
|
||||||
const IBOutletCollectionAttr *
|
const IBOutletCollectionAttr *
|
||||||
IBAttr = cast<IBOutletCollectionAttr>(IBInfo.A);
|
IBAttr = cast<IBOutletCollectionAttr>(IBInfo.A);
|
||||||
|
SourceLocation InterfaceLocStart =
|
||||||
|
IBAttr->getInterfaceLoc()->getTypeLoc().getLocStart();
|
||||||
IBInfo.IBCollInfo.attrInfo = &IBInfo;
|
IBInfo.IBCollInfo.attrInfo = &IBInfo;
|
||||||
IBInfo.IBCollInfo.classLoc = IdxCtx.getIndexLoc(IBAttr->getInterfaceLoc());
|
IBInfo.IBCollInfo.classLoc = IdxCtx.getIndexLoc(InterfaceLocStart);
|
||||||
IBInfo.IBCollInfo.objcClass = 0;
|
IBInfo.IBCollInfo.objcClass = 0;
|
||||||
IBInfo.IBCollInfo.classCursor = clang_getNullCursor();
|
IBInfo.IBCollInfo.classCursor = clang_getNullCursor();
|
||||||
QualType Ty = IBAttr->getInterface();
|
QualType Ty = IBAttr->getInterface();
|
||||||
|
@ -103,8 +105,8 @@ AttrListInfo::AttrListInfo(const Decl *D, IndexingContext &IdxCtx)
|
||||||
if (const ObjCInterfaceDecl *InterD = ObjectTy->getInterface()) {
|
if (const ObjCInterfaceDecl *InterD = ObjectTy->getInterface()) {
|
||||||
IdxCtx.getEntityInfo(InterD, IBInfo.ClassInfo, SA);
|
IdxCtx.getEntityInfo(InterD, IBInfo.ClassInfo, SA);
|
||||||
IBInfo.IBCollInfo.objcClass = &IBInfo.ClassInfo;
|
IBInfo.IBCollInfo.objcClass = &IBInfo.ClassInfo;
|
||||||
IBInfo.IBCollInfo.classCursor = MakeCursorObjCClassRef(InterD,
|
IBInfo.IBCollInfo.classCursor =
|
||||||
IBAttr->getInterfaceLoc(), IdxCtx.CXTU);
|
MakeCursorObjCClassRef(InterD, InterfaceLocStart, IdxCtx.CXTU);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ static std::string ReadPCHRecord(StringRef type) {
|
||||||
return StringSwitch<std::string>(type)
|
return StringSwitch<std::string>(type)
|
||||||
.EndsWith("Decl *", "GetLocalDeclAs<"
|
.EndsWith("Decl *", "GetLocalDeclAs<"
|
||||||
+ std::string(type, 0, type.size()-1) + ">(F, Record[Idx++])")
|
+ std::string(type, 0, type.size()-1) + ">(F, Record[Idx++])")
|
||||||
.Case("QualType", "getLocalType(F, Record[Idx++])")
|
.Case("TypeSourceInfo *", "GetTypeSourceInfo(F, Record, Idx)")
|
||||||
.Case("Expr *", "ReadExpr(F)")
|
.Case("Expr *", "ReadExpr(F)")
|
||||||
.Case("IdentifierInfo *", "GetIdentifierInfo(F, Record, Idx)")
|
.Case("IdentifierInfo *", "GetIdentifierInfo(F, Record, Idx)")
|
||||||
.Case("SourceLocation", "ReadSourceLocation(F, Record, Idx)")
|
.Case("SourceLocation", "ReadSourceLocation(F, Record, Idx)")
|
||||||
|
@ -59,7 +59,8 @@ static std::string WritePCHRecord(StringRef type, StringRef name) {
|
||||||
return StringSwitch<std::string>(type)
|
return StringSwitch<std::string>(type)
|
||||||
.EndsWith("Decl *", "AddDeclRef(" + std::string(name) +
|
.EndsWith("Decl *", "AddDeclRef(" + std::string(name) +
|
||||||
", Record);\n")
|
", Record);\n")
|
||||||
.Case("QualType", "AddTypeRef(" + std::string(name) + ", Record);\n")
|
.Case("TypeSourceInfo *",
|
||||||
|
"AddTypeSourceInfo(" + std::string(name) + ", Record);\n")
|
||||||
.Case("Expr *", "AddStmt(" + std::string(name) + ");\n")
|
.Case("Expr *", "AddStmt(" + std::string(name) + ");\n")
|
||||||
.Case("IdentifierInfo *",
|
.Case("IdentifierInfo *",
|
||||||
"AddIdentifierRef(" + std::string(name) + ", Record);\n")
|
"AddIdentifierRef(" + std::string(name) + ", Record);\n")
|
||||||
|
@ -185,10 +186,11 @@ namespace {
|
||||||
}
|
}
|
||||||
void writeValue(raw_ostream &OS) const {
|
void writeValue(raw_ostream &OS) const {
|
||||||
if (type == "FunctionDecl *") {
|
if (type == "FunctionDecl *") {
|
||||||
OS << "\" << get" << getUpperName() << "()->getNameInfo().getAsString() << \"";
|
OS << "\" << get" << getUpperName()
|
||||||
|
<< "()->getNameInfo().getAsString() << \"";
|
||||||
} else if (type == "IdentifierInfo *") {
|
} else if (type == "IdentifierInfo *") {
|
||||||
OS << "\" << get" << getUpperName() << "()->getName() << \"";
|
OS << "\" << get" << getUpperName() << "()->getName() << \"";
|
||||||
} else if (type == "QualType") {
|
} else if (type == "TypeSourceInfo *") {
|
||||||
OS << "\" << get" << getUpperName() << "().getAsString() << \"";
|
OS << "\" << get" << getUpperName() << "().getAsString() << \"";
|
||||||
} else if (type == "SourceLocation") {
|
} else if (type == "SourceLocation") {
|
||||||
OS << "\" << get" << getUpperName() << "().getRawEncoding() << \"";
|
OS << "\" << get" << getUpperName() << "().getRawEncoding() << \"";
|
||||||
|
@ -203,7 +205,7 @@ namespace {
|
||||||
} else if (type == "IdentifierInfo *") {
|
} else if (type == "IdentifierInfo *") {
|
||||||
OS << " OS << \" \" << SA->get" << getUpperName()
|
OS << " OS << \" \" << SA->get" << getUpperName()
|
||||||
<< "()->getName();\n";
|
<< "()->getName();\n";
|
||||||
} else if (type == "QualType") {
|
} else if (type == "TypeSourceInfo *") {
|
||||||
OS << " OS << \" \" << SA->get" << getUpperName()
|
OS << " OS << \" \" << SA->get" << getUpperName()
|
||||||
<< "().getAsString();\n";
|
<< "().getAsString();\n";
|
||||||
} else if (type == "SourceLocation") {
|
} else if (type == "SourceLocation") {
|
||||||
|
@ -827,6 +829,29 @@ namespace {
|
||||||
<< "SA->" << getLowerName() << "_end()";
|
<< "SA->" << getLowerName() << "_end()";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TypeArgument : public SimpleArgument {
|
||||||
|
public:
|
||||||
|
TypeArgument(Record &Arg, StringRef Attr)
|
||||||
|
: SimpleArgument(Arg, Attr, "TypeSourceInfo *")
|
||||||
|
{}
|
||||||
|
|
||||||
|
void writeAccessors(raw_ostream &OS) const {
|
||||||
|
OS << " QualType get" << getUpperName() << "() const {\n";
|
||||||
|
OS << " return " << getLowerName() << "->getType();\n";
|
||||||
|
OS << " }";
|
||||||
|
OS << " " << getType() << " get" << getUpperName() << "Loc() const {\n";
|
||||||
|
OS << " return " << getLowerName() << ";\n";
|
||||||
|
OS << " }";
|
||||||
|
}
|
||||||
|
void writeTemplateInstantiationArgs(raw_ostream &OS) const {
|
||||||
|
OS << "A->get" << getUpperName() << "Loc()";
|
||||||
|
}
|
||||||
|
void writePCHWrite(raw_ostream &OS) const {
|
||||||
|
OS << " " << WritePCHRecord(
|
||||||
|
getType(), "SA->get" + std::string(getUpperName()) + "Loc()");
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static Argument *createArgument(Record &Arg, StringRef Attr,
|
static Argument *createArgument(Record &Arg, StringRef Attr,
|
||||||
|
@ -848,8 +873,7 @@ static Argument *createArgument(Record &Arg, StringRef Attr,
|
||||||
"bool");
|
"bool");
|
||||||
else if (ArgName == "IntArgument") Ptr = new SimpleArgument(Arg, Attr, "int");
|
else if (ArgName == "IntArgument") Ptr = new SimpleArgument(Arg, Attr, "int");
|
||||||
else if (ArgName == "StringArgument") Ptr = new StringArgument(Arg, Attr);
|
else if (ArgName == "StringArgument") Ptr = new StringArgument(Arg, Attr);
|
||||||
else if (ArgName == "TypeArgument")
|
else if (ArgName == "TypeArgument") Ptr = new TypeArgument(Arg, Attr);
|
||||||
Ptr = new SimpleArgument(Arg, Attr, "QualType");
|
|
||||||
else if (ArgName == "UnsignedArgument")
|
else if (ArgName == "UnsignedArgument")
|
||||||
Ptr = new SimpleArgument(Arg, Attr, "unsigned");
|
Ptr = new SimpleArgument(Arg, Attr, "unsigned");
|
||||||
else if (ArgName == "SourceLocArgument")
|
else if (ArgName == "SourceLocArgument")
|
||||||
|
|
Loading…
Reference in New Issue