#define LLVM_CLANG_AST_ATTR_H
#include "clang/AST/AttrIterator.h"
+#include "clang/AST/Decl.h"
#include "clang/AST/Type.h"
#include "clang/Basic/AttrKinds.h"
#include "clang/Basic/LLVM.h"
def IBOutletCollection : InheritableAttr {
let Spellings = [GNU<"iboutletcollection">];
- let Args = [TypeArgument<"Interface", 1>, SourceLocArgument<"InterfaceLoc">];
- let HasCustomParsing = 1;
+ let Args = [TypeArgument<"Interface", 1>];
}
def Malloc : InheritableAttr {
def VecTypeHint : InheritableAttr {
let Spellings = [GNU<"vec_type_hint">];
- let Args = [TypeArgument<"TypeHint">, SourceLocArgument<"TypeLoc">];
- let HasCustomParsing = 1;
+ let Args = [TypeArgument<"TypeHint">];
}
def Visibility : InheritableAttr {
/// determine whether the name refers to a type. If so, returns an
/// opaque pointer (actually a QualType) corresponding to that
/// 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,
Scope *S, CXXScopeSpec *SS,
bool isClassName, bool HasTrailingDot,
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
/// output an error.
static bool checkAttributeNumArgs(Sema &S, const AttributeList &Attr,
- unsigned int Num) {
- if (Attr.getNumArgs() != Num) {
+ unsigned Num) {
+ if (getNumAttributeArgs(Attr) != Num) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
<< Attr.getName() << Num;
return false;
/// \brief Check if the attribute has at least as many args as Num. May
/// output an error.
static bool checkAttributeAtLeastNumArgs(Sema &S, const AttributeList &Attr,
- unsigned int Num) {
- if (Attr.getNumArgs() < Num) {
+ unsigned Num) {
+ if (getNumAttributeArgs(Attr) < Num) {
S.Diag(Attr.getLoc(), diag::err_attribute_too_few_arguments) << Num;
return false;
}
}
}
- TypeSourceInfo *TSI = 0;
- QualType QT = S.GetTypeFromParser(PT, &TSI);
- SourceLocation QTLoc =
- TSI ? TSI->getTypeLoc().getLocStart() : SourceLocation();
+ TypeSourceInfo *QTLoc = 0;
+ QualType QT = S.GetTypeFromParser(PT, &QTLoc);
+ if (!QTLoc)
+ QTLoc = S.Context.getTrivialTypeSourceInfo(QT, Attr.getLoc());
// Diagnose use of non-object type in iboutletcollection attribute.
// FIXME. Gnu attribute extension ignores use of builtin types in
}
D->addAttr(::new (S.Context)
- IBOutletCollectionAttr(Attr.getRange(), S.Context, QT, QTLoc,
+ IBOutletCollectionAttr(Attr.getRange(), S.Context, QTLoc,
Attr.getAttributeSpellingListIndex()));
}
static void handleVecTypeHint(Sema &S, Decl *D, const AttributeList &Attr) {
assert(Attr.getKind() == AttributeList::AT_VecTypeHint);
- if (!checkAttributeNumArgs(S, Attr, 0))
- return;
-
if (!Attr.hasParsedType()) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
<< Attr.getName() << 1;
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() &&
(ParmType->isBooleanType() ||
if (Attr.getKind() == AttributeList::AT_VecTypeHint &&
D->hasAttr<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();
return;
}
}
D->addAttr(::new (S.Context) VecTypeHintAttr(Attr.getLoc(), S.Context,
- ParmType, Attr.getLoc()));
+ ParmTSI));
}
SectionAttr *Sema::mergeSectionAttr(Decl *D, SourceRange Range,
return;
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)
TypeTagForDatatypeAttr(Attr.getRange(), S.Context, PointerKind,
- MatchingCType,
+ MatchingCTypeLoc,
Attr.getLayoutCompatible(),
Attr.getMustBeNull(),
Attr.getAttributeSpellingListIndex()));
const IBOutletCollectionAttr *A =
cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
- return Visit(cxcursor::MakeCursorObjCClassRef(ObjT->getInterface(),
- A->getInterfaceLoc(), TU));
+ return Visit(cxcursor::MakeCursorObjCClassRef(
+ ObjT->getInterface(),
+ A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
}
// If pointing inside a macro definition, check if the token is an identifier
const IBOutletCollectionAttr *
IBAttr = cast<IBOutletCollectionAttr>(IBInfo.A);
+ SourceLocation InterfaceLocStart =
+ IBAttr->getInterfaceLoc()->getTypeLoc().getLocStart();
IBInfo.IBCollInfo.attrInfo = &IBInfo;
- IBInfo.IBCollInfo.classLoc = IdxCtx.getIndexLoc(IBAttr->getInterfaceLoc());
+ IBInfo.IBCollInfo.classLoc = IdxCtx.getIndexLoc(InterfaceLocStart);
IBInfo.IBCollInfo.objcClass = 0;
IBInfo.IBCollInfo.classCursor = clang_getNullCursor();
QualType Ty = IBAttr->getInterface();
if (const ObjCInterfaceDecl *InterD = ObjectTy->getInterface()) {
IdxCtx.getEntityInfo(InterD, IBInfo.ClassInfo, SA);
IBInfo.IBCollInfo.objcClass = &IBInfo.ClassInfo;
- IBInfo.IBCollInfo.classCursor = MakeCursorObjCClassRef(InterD,
- IBAttr->getInterfaceLoc(), IdxCtx.CXTU);
+ IBInfo.IBCollInfo.classCursor =
+ MakeCursorObjCClassRef(InterD, InterfaceLocStart, IdxCtx.CXTU);
}
}
}
return StringSwitch<std::string>(type)
.EndsWith("Decl *", "GetLocalDeclAs<"
+ 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("IdentifierInfo *", "GetIdentifierInfo(F, Record, Idx)")
.Case("SourceLocation", "ReadSourceLocation(F, Record, Idx)")
return StringSwitch<std::string>(type)
.EndsWith("Decl *", "AddDeclRef(" + std::string(name) +
", 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("IdentifierInfo *",
"AddIdentifierRef(" + std::string(name) + ", Record);\n")
}
void writeValue(raw_ostream &OS) const {
if (type == "FunctionDecl *") {
- OS << "\" << get" << getUpperName() << "()->getNameInfo().getAsString() << \"";
+ OS << "\" << get" << getUpperName()
+ << "()->getNameInfo().getAsString() << \"";
} else if (type == "IdentifierInfo *") {
OS << "\" << get" << getUpperName() << "()->getName() << \"";
- } else if (type == "QualType") {
+ } else if (type == "TypeSourceInfo *") {
OS << "\" << get" << getUpperName() << "().getAsString() << \"";
} else if (type == "SourceLocation") {
OS << "\" << get" << getUpperName() << "().getRawEncoding() << \"";
} else if (type == "IdentifierInfo *") {
OS << " OS << \" \" << SA->get" << getUpperName()
<< "()->getName();\n";
- } else if (type == "QualType") {
+ } else if (type == "TypeSourceInfo *") {
OS << " OS << \" \" << SA->get" << getUpperName()
<< "().getAsString();\n";
} else if (type == "SourceLocation") {
<< "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,
"bool");
else if (ArgName == "IntArgument") Ptr = new SimpleArgument(Arg, Attr, "int");
else if (ArgName == "StringArgument") Ptr = new StringArgument(Arg, Attr);
- else if (ArgName == "TypeArgument")
- Ptr = new SimpleArgument(Arg, Attr, "QualType");
+ else if (ArgName == "TypeArgument") Ptr = new TypeArgument(Arg, Attr);
else if (ArgName == "UnsignedArgument")
Ptr = new SimpleArgument(Arg, Attr, "unsigned");
else if (ArgName == "SourceLocArgument")